From 6c96bd6c8ef06e1ecb75ca39a575155dafcc26f1 Mon Sep 17 00:00:00 2001 From: Bob Zeleznik Date: Tue, 14 Jul 2020 21:56:48 -0400 Subject: moving collectionViewChrome to CollectionMenu --- src/client/views/collections/CollectionMenu.tsx | 331 ++++++++++++++++++++++++ 1 file changed, 331 insertions(+) create mode 100644 src/client/views/collections/CollectionMenu.tsx (limited to 'src/client/views/collections/CollectionMenu.tsx') diff --git a/src/client/views/collections/CollectionMenu.tsx b/src/client/views/collections/CollectionMenu.tsx new file mode 100644 index 000000000..d79ffffa1 --- /dev/null +++ b/src/client/views/collections/CollectionMenu.tsx @@ -0,0 +1,331 @@ +import React = require("react"); +import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; +import { action, computed, observable, reaction, runInAction } from "mobx"; +import { observer } from "mobx-react"; +import { Doc, DocListCast } from "../../../fields/Doc"; +import { BoolCast, Cast, StrCast, NumCast } from "../../../fields/Types"; +import AntimodeMenu from "../AntimodeMenu"; +import "./CollectionMenu.scss"; +import { undoBatch } from "../../util/UndoManager"; +import { CollectionViewType, CollectionView } from "./CollectionView"; +import { emptyFunction, setupMoveUpEvents, Utils } from "../../../Utils"; +import { CollectionGridViewChrome } from "./CollectionViewChromes"; +import { DragManager } from "../../util/DragManager"; +import { CollectionFreeFormDocumentView } from "../nodes/CollectionFreeFormDocumentView"; +import { List } from "../../../fields/List"; +import { SelectionManager } from "../../util/SelectionManager"; + +@observer +export default class CollectionMenu extends AntimodeMenu { + static Instance: CollectionMenu; + + @observable SelectedCollection: CollectionView | undefined; + + constructor(props: Readonly<{}>) { + super(props); + CollectionMenu.Instance = this; + this._canFade = false; // don't let the inking menu fade away + this.Pinned = Cast(Doc.UserDoc()["menuCollections-pinned"], "boolean", true); + } + + @action + toggleMenuPin = (e: React.MouseEvent) => { + Doc.UserDoc()["menuCollections-pinned"] = this.Pinned = !this.Pinned; + } + + @computed get aButton() { + return
+ +
; + } + + render() { + return this.getElement([ + this.aButton, + !this.SelectedCollection ? <> : , + + ]); + } +} + +interface CollectionViewChromeProps { + CollectionView: CollectionView; + type: CollectionViewType; + collapse?: (value: boolean) => any; +} + +const stopPropagation = (e: React.SyntheticEvent) => e.stopPropagation(); + +@observer +export class CollectionViewBaseChrome extends React.Component { + //(!)?\(\(\(doc.(\w+) && \(doc.\w+ as \w+\).includes\(\"(\w+)\"\) + + get target() { return this.props.CollectionView.props.Document; } + _templateCommand = { + params: ["target", "source"], title: "=> item view", + script: "this.target.childLayout = getDocTemplate(this.source?.[0])", + immediate: undoBatch((source: Doc[]) => source.length && (this.target.childLayout = Doc.getDocTemplate(source?.[0]))), + initialize: emptyFunction, + }; + _narrativeCommand = { + params: ["target", "source"], title: "=> child click view", + script: "this.target.childClickedOpenTemplateView = getDocTemplate(this.source?.[0])", + immediate: undoBatch((source: Doc[]) => source.length && (this.target.childClickedOpenTemplateView = Doc.getDocTemplate(source?.[0]))), + initialize: emptyFunction, + }; + _contentCommand = { + params: ["target", "source"], title: "=> clear content", + script: "getProto(this.target).data = copyField(this.source);", + immediate: undoBatch((source: Doc[]) => Doc.GetProto(this.target).data = new List(source)), // Doc.aliasDocs(source), + initialize: emptyFunction, + }; + _viewCommand = { + params: ["target"], title: "=> reset view", + script: "this.target._panX = this.restoredPanX; this.target._panY = this.restoredPanY; this.target.scale = this.restoredScale;", + immediate: undoBatch((source: Doc[]) => { this.target._panX = 0; this.target._panY = 0; this.target.scale = 1; }), + initialize: (button: Doc) => { button.restoredPanX = this.target._panX; button.restoredPanY = this.target._panY; button.restoredScale = this.target.scale; }, + }; + _clusterCommand = { + params: ["target"], title: "=> fit content", + script: "this.target._fitToBox = !this.target._fitToBox;", + immediate: undoBatch((source: Doc[]) => this.target._fitToBox = !this.target._fitToBox), + initialize: emptyFunction + }; + _fitContentCommand = { + params: ["target"], title: "=> toggle clusters", + script: "this.target.useClusters = !this.target.useClusters;", + immediate: undoBatch((source: Doc[]) => this.target.useClusters = !this.target.useClusters), + initialize: emptyFunction + }; + + _freeform_commands = [this._viewCommand, this._fitContentCommand, this._clusterCommand, this._contentCommand, this._templateCommand, this._narrativeCommand]; + _stacking_commands = [this._contentCommand, this._templateCommand]; + _masonry_commands = [this._contentCommand, this._templateCommand]; + _schema_commands = [this._templateCommand, this._narrativeCommand]; + _tree_commands = []; + private get _buttonizableCommands() { + switch (this.props.type) { + case CollectionViewType.Tree: return this._tree_commands; + case CollectionViewType.Schema: return this._schema_commands; + case CollectionViewType.Stacking: return this._stacking_commands; + case CollectionViewType.Masonry: return this._stacking_commands; + case CollectionViewType.Freeform: return this._freeform_commands; + case CollectionViewType.Time: return this._freeform_commands; + case CollectionViewType.Carousel: return this._freeform_commands; + case CollectionViewType.Carousel3D: return this._freeform_commands; + } + return []; + } + private _picker: any; + private _commandRef = React.createRef(); + private _viewRef = React.createRef(); + @observable private _currentKey: string = ""; + + componentDidMount = action(() => { + this._currentKey = this._currentKey || (this._buttonizableCommands.length ? this._buttonizableCommands[0]?.title : ""); + }); + + @undoBatch + viewChanged = (e: React.ChangeEvent) => { + //@ts-ignore + this.document._viewType = e.target.selectedOptions[0].value; + } + + commandChanged = (e: React.ChangeEvent) => { + //@ts-ignore + runInAction(() => this._currentKey = e.target.selectedOptions[0].value); + } + + @action + toggleViewSpecs = (e: React.SyntheticEvent) => { + this.document._facetWidth = this.document._facetWidth ? 0 : 200; + e.stopPropagation(); + } + + @action closeViewSpecs = () => { + this.document._facetWidth = 0; + } + + + @computed get subChrome() { + switch (this.props.type) { + case CollectionViewType.Freeform: return (); + // case CollectionViewType.Stacking: return (); + // case CollectionViewType.Schema: return (); + // case CollectionViewType.Tree: return (); + // case CollectionViewType.Masonry: return (); + // case CollectionViewType.Carousel3D: return (); + // case CollectionViewType.Grid: return (); + default: return null; + } + } + + private get document() { + return this.props.CollectionView.props.Document; + } + + private dropDisposer?: DragManager.DragDropDisposer; + protected createDropTarget = (ele: HTMLDivElement) => { + this.dropDisposer?.(); + if (ele) { + this.dropDisposer = DragManager.MakeDropTarget(ele, this.drop.bind(this), this.document); + } + } + + @undoBatch + @action + protected drop(e: Event, de: DragManager.DropEvent): boolean { + const docDragData = de.complete.docDragData; + if (docDragData?.draggedDocuments.length) { + this._buttonizableCommands.filter(c => c.title === this._currentKey).map(c => c.immediate(docDragData.draggedDocuments || [])); + e.stopPropagation(); + } + return true; + } + + dragViewDown = (e: React.PointerEvent) => { + setupMoveUpEvents(this, e, (e, down, delta) => { + const vtype = this.props.CollectionView.collectionViewType; + const c = { + params: ["target"], title: vtype, + script: `this.target._viewType = '${StrCast(this.props.CollectionView.props.Document._viewType)}'`, + immediate: (source: Doc[]) => this.props.CollectionView.props.Document._viewType = Doc.getDocTemplate(source?.[0]), + initialize: emptyFunction, + }; + DragManager.StartButtonDrag([this._viewRef.current!], c.script, StrCast(c.title), + { target: this.props.CollectionView.props.Document }, c.params, c.initialize, e.clientX, e.clientY); + return true; + }, emptyFunction, emptyFunction); + } + dragCommandDown = (e: React.PointerEvent) => { + setupMoveUpEvents(this, e, (e, down, delta) => { + this._buttonizableCommands.filter(c => c.title === this._currentKey).map(c => + DragManager.StartButtonDrag([this._commandRef.current!], c.script, c.title, + { target: this.props.CollectionView.props.Document }, c.params, c.initialize, e.clientX, e.clientY)); + return true; + }, emptyFunction, () => { + this._buttonizableCommands.filter(c => c.title === this._currentKey).map(c => c.immediate([])); + }); + } + + @computed get templateChrome() { + return
+
+
+ +
+ +
+
; + } + + @computed get viewModes() { + const collapsed = this.props.CollectionView.props.Document._chromeStatus !== "enabled"; + return
+
+
+ +
+ +
+
; + } + + render() { + const scale = Math.min(1, this.props.CollectionView.props.ScreenToLocalTransform()?.Scale); + return ( +
+
+
+ {this.viewModes} +
+
+ +
+
+ {this.templateChrome} +
+ {this.subChrome} +
+
+ ); + } +} + +@observer +export class CollectionFreeFormViewChrome extends React.Component { + + get Document() { return this.props.CollectionView.props.Document; } + @computed get dataField() { + return this.props.CollectionView.props.Document[Doc.LayoutFieldKey(this.props.CollectionView.props.Document)]; + } + @computed get childDocs() { + return DocListCast(this.dataField); + } + @undoBatch + @action + nextKeyframe = (): void => { + const currentFrame = NumCast(this.Document.currentFrame); + if (currentFrame === undefined) { + this.Document.currentFrame = 0; + CollectionFreeFormDocumentView.setupKeyframes(this.childDocs, 0); + } + CollectionFreeFormDocumentView.updateKeyframe(this.childDocs, currentFrame || 0); + this.Document.currentFrame = Math.max(0, (currentFrame || 0) + 1); + this.Document.lastFrame = Math.max(NumCast(this.Document.currentFrame), NumCast(this.Document.lastFrame)); + } + @undoBatch + @action + prevKeyframe = (): void => { + const currentFrame = NumCast(this.Document.currentFrame); + if (currentFrame === undefined) { + this.Document.currentFrame = 0; + CollectionFreeFormDocumentView.setupKeyframes(this.childDocs, 0); + } + CollectionFreeFormDocumentView.gotoKeyframe(this.childDocs.slice()); + this.Document.currentFrame = Math.max(0, (currentFrame || 0) - 1); + } + render() { + return this.Document.isAnnotationOverlay ? (null) : +
+
+ +
+
this.Document.editing = !this.Document.editing)} > + {NumCast(this.Document.currentFrame)} +
+
+ +
+
; + } +} -- cgit v1.2.3-70-g09d2 From 95429adb77402ce2a218c5585ceef4db0c8494db Mon Sep 17 00:00:00 2001 From: Bob Zeleznik Date: Tue, 14 Jul 2020 23:55:59 -0400 Subject: converted collectionChrome into a menu bar --- src/client/views/MainView.tsx | 6 +- .../views/collections/CollectionDockingView.tsx | 2 +- src/client/views/collections/CollectionMenu.scss | 475 ++++++++++++++++++++- src/client/views/collections/CollectionMenu.tsx | 443 +++++++++++++++++-- src/client/views/collections/CollectionView.tsx | 11 +- 5 files changed, 888 insertions(+), 49 deletions(-) (limited to 'src/client/views/collections/CollectionMenu.tsx') diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx index 428fb835b..95b2dfcdb 100644 --- a/src/client/views/MainView.tsx +++ b/src/client/views/MainView.tsx @@ -392,7 +392,7 @@ export class MainView extends React.Component { doc.dockingConfig ? this.openWorkspace(doc) : CollectionDockingView.AddRightSplit(doc, libraryPath); } - sidebarScreenToLocal = () => new Transform(0, RichTextMenu.Instance.Pinned ? -35 : 0, 1); + sidebarScreenToLocal = () => new Transform(0, (RichTextMenu.Instance.Pinned ? -35 : 0) + (InkOptionsMenu.Instance.Pinned ? -35 : 0) + (CollectionMenu.Instance.Pinned ? -35 : 0), 1); mainContainerXf = () => this.sidebarScreenToLocal().translate(0, -this._buttonBarHeight); @computed get flyout() { @@ -469,11 +469,13 @@ export class MainView extends React.Component { @computed get mainContent() { const sidebar = this.userDoc?.["tabs-panelContainer"]; + const n = (RichTextMenu.Instance?.Pinned ? 1 : 0) + (InkOptionsMenu.Instance?.Pinned ? 1 : 0) + (CollectionMenu.Instance?.Pinned ? 1 : 0); + const height = `calc(100% - ${n * Number(ANTIMODEMENU_HEIGHT.replace("px", ""))}px)`; return !this.userDoc || !(sidebar instanceof Doc) ? (null) : (
diff --git a/src/client/views/collections/CollectionDockingView.tsx b/src/client/views/collections/CollectionDockingView.tsx index f408e24a8..657296566 100644 --- a/src/client/views/collections/CollectionDockingView.tsx +++ b/src/client/views/collections/CollectionDockingView.tsx @@ -436,7 +436,7 @@ export class CollectionDockingView extends React.Component - -
; - } - render() { return this.getElement([ - this.aButton, !this.SelectedCollection ? <> : , - ]); @@ -55,7 +47,6 @@ export default class CollectionMenu extends AntimodeMenu { interface CollectionViewChromeProps { CollectionView: CollectionView; type: CollectionViewType; - collapse?: (value: boolean) => any; } const stopPropagation = (e: React.SyntheticEvent) => e.stopPropagation(); @@ -154,12 +145,12 @@ export class CollectionViewBaseChrome extends React.Component); - // case CollectionViewType.Stacking: return (); - // case CollectionViewType.Schema: return (); - // case CollectionViewType.Tree: return (); - // case CollectionViewType.Masonry: return (); - // case CollectionViewType.Carousel3D: return (); - // case CollectionViewType.Grid: return (); + case CollectionViewType.Stacking: return (); + case CollectionViewType.Schema: return (); + case CollectionViewType.Tree: return (); + case CollectionViewType.Masonry: return (); + case CollectionViewType.Carousel3D: return (); + case CollectionViewType.Grid: return (); default: return null; } } @@ -230,8 +221,7 @@ export class CollectionViewBaseChrome extends React.Component + return
@@ -258,7 +248,7 @@ export class CollectionViewBaseChrome extends React.Component { - const currentFrame = NumCast(this.Document.currentFrame); + const currentFrame = Cast(this.Document.currentFrame, "number", null); if (currentFrame === undefined) { this.Document.currentFrame = 0; CollectionFreeFormDocumentView.setupKeyframes(this.childDocs, 0); @@ -305,7 +295,7 @@ export class CollectionFreeFormViewChrome extends React.Component { - const currentFrame = NumCast(this.Document.currentFrame); + const currentFrame = Cast(this.Document.currentFrame, "number", null); if (currentFrame === undefined) { this.Document.currentFrame = 0; CollectionFreeFormDocumentView.setupKeyframes(this.childDocs, 0); @@ -315,7 +305,7 @@ export class CollectionFreeFormViewChrome extends React.Component +
@@ -329,3 +319,400 @@ export class CollectionFreeFormViewChrome extends React.Component; } } +@observer +export class CollectionStackingViewChrome extends React.Component { + @observable private _currentKey: string = ""; + @observable private suggestions: string[] = []; + + @computed private get descending() { return StrCast(this.props.CollectionView.props.Document._columnsSort) === "descending"; } + @computed get pivotField() { return StrCast(this.props.CollectionView.props.Document._pivotField); } + + getKeySuggestions = async (value: string): Promise => { + value = value.toLowerCase(); + const docs = DocListCast(this.props.CollectionView.props.Document[this.props.CollectionView.props.fieldKey]); + if (docs instanceof Doc) { + return Object.keys(docs).filter(key => key.toLowerCase().startsWith(value)); + } else { + const keys = new Set(); + docs.forEach(doc => Doc.allKeys(doc).forEach(key => keys.add(key))); + return Array.from(keys).filter(key => key.toLowerCase().startsWith(value)); + } + } + + @action + onKeyChange = (e: React.ChangeEvent, { newValue }: { newValue: string }) => { + this._currentKey = newValue; + } + + getSuggestionValue = (suggestion: string) => suggestion; + + renderSuggestion = (suggestion: string) => { + return

{suggestion}

; + } + + onSuggestionFetch = async ({ value }: { value: string }) => { + const sugg = await this.getKeySuggestions(value); + runInAction(() => { + this.suggestions = sugg; + }); + } + + @action + onSuggestionClear = () => { + this.suggestions = []; + } + + @action + setValue = (value: string) => { + this.props.CollectionView.props.Document._pivotField = value; + return true; + } + + @action toggleSort = () => { + this.props.CollectionView.props.Document._columnsSort = + this.props.CollectionView.props.Document._columnsSort === "descending" ? "ascending" : + this.props.CollectionView.props.Document._columnsSort === "ascending" ? undefined : "descending"; + } + @action resetValue = () => { this._currentKey = this.pivotField; }; + + render() { + return ( +
+
+
+ GROUP BY: +
+
+ +
+
+ this.pivotField} + autosuggestProps={ + { + resetValue: this.resetValue, + value: this._currentKey, + onChange: this.onKeyChange, + autosuggestProps: { + inputProps: + { + value: this._currentKey, + onChange: this.onKeyChange + }, + getSuggestionValue: this.getSuggestionValue, + suggestions: this.suggestions, + alwaysRenderSuggestions: true, + renderSuggestion: this.renderSuggestion, + onSuggestionsFetchRequested: this.onSuggestionFetch, + onSuggestionsClearRequested: this.onSuggestionClear + } + }} + oneLine + SetValue={this.setValue} + contents={this.pivotField ? this.pivotField : "N/A"} + /> +
+
+
+ ); + } +} + + +@observer +export class CollectionSchemaViewChrome extends React.Component { + // private _textwrapAllRows: boolean = Cast(this.props.CollectionView.props.Document.textwrappedSchemaRows, listSpec("string"), []).length > 0; + + @undoBatch + togglePreview = () => { + const dividerWidth = 4; + const borderWidth = Number(COLLECTION_BORDER_WIDTH); + const panelWidth = this.props.CollectionView.props.PanelWidth(); + const previewWidth = NumCast(this.props.CollectionView.props.Document.schemaPreviewWidth); + const tableWidth = panelWidth - 2 * borderWidth - dividerWidth - previewWidth; + this.props.CollectionView.props.Document.schemaPreviewWidth = previewWidth === 0 ? Math.min(tableWidth / 3, 200) : 0; + } + + @undoBatch + @action + toggleTextwrap = async () => { + const textwrappedRows = Cast(this.props.CollectionView.props.Document.textwrappedSchemaRows, listSpec("string"), []); + if (textwrappedRows.length) { + this.props.CollectionView.props.Document.textwrappedSchemaRows = new List([]); + } else { + const docs = DocListCast(this.props.CollectionView.props.Document[this.props.CollectionView.props.fieldKey]); + const allRows = docs instanceof Doc ? [docs[Id]] : docs.map(doc => doc[Id]); + this.props.CollectionView.props.Document.textwrappedSchemaRows = new List(allRows); + } + } + + + render() { + const previewWidth = NumCast(this.props.CollectionView.props.Document.schemaPreviewWidth); + const textWrapped = Cast(this.props.CollectionView.props.Document.textwrappedSchemaRows, listSpec("string"), []).length > 0; + + return ( +
+
+
Show Preview:
+
+
+ {previewWidth !== 0 ? "on" : "off"} +
+
+
+
+ ); + } +} + +@observer +export class CollectionTreeViewChrome extends React.Component { + + get sortAscending() { + return this.props.CollectionView.props.Document[this.props.CollectionView.props.fieldKey + "-sortAscending"]; + } + set sortAscending(value) { + this.props.CollectionView.props.Document[this.props.CollectionView.props.fieldKey + "-sortAscending"] = value; + } + @computed private get ascending() { + return Cast(this.sortAscending, "boolean", null); + } + + @action toggleSort = () => { + if (this.sortAscending) this.sortAscending = undefined; + else if (this.sortAscending === undefined) this.sortAscending = false; + else this.sortAscending = true; + } + + render() { + return ( +
+ +
+ ); + } +} + +// Enter scroll speed for 3D Carousel +@observer +export class Collection3DCarouselViewChrome extends React.Component { + @computed get scrollSpeed() { + return this.props.CollectionView.props.Document._autoScrollSpeed; + } + + @action + setValue = (value: string) => { + const numValue = Number(StrCast(value)); + if (numValue > 0) { + this.props.CollectionView.props.Document._autoScrollSpeed = numValue; + return true; + } + return false; + } + + render() { + return ( +
+
+
+ AUTOSCROLL SPEED: +
+
+ StrCast(this.scrollSpeed)} + oneLine + SetValue={this.setValue} + contents={this.scrollSpeed ? this.scrollSpeed : 1000} /> +
+
+
+ ); + } +} + +/** + * Chrome for grid view. + */ +@observer +export class CollectionGridViewChrome extends React.Component { + + private clicked: boolean = false; + private entered: boolean = false; + private decrementLimitReached: boolean = false; + @observable private resize = false; + private resizeListenerDisposer: Opt; + + componentDidMount() { + + runInAction(() => this.resize = this.props.CollectionView.props.PanelWidth() < 700); + + // listener to reduce text on chrome resize (panel resize) + this.resizeListenerDisposer = computed(() => this.props.CollectionView.props.PanelWidth()).observe(({ newValue }) => { + runInAction(() => this.resize = newValue < 700); + }); + } + + componentWillUnmount() { + this.resizeListenerDisposer?.(); + } + + get numCols() { return NumCast(this.props.CollectionView.props.Document.gridNumCols, 10); } + + /** + * Sets the value of `numCols` on the grid's Document to the value entered. + */ + @undoBatch + onNumColsEnter = (e: React.KeyboardEvent) => { + if (e.key === "Enter" || e.key === "Tab") { + if (e.currentTarget.valueAsNumber > 0) { + this.props.CollectionView.props.Document.gridNumCols = e.currentTarget.valueAsNumber; + } + + } + } + + /** + * Sets the value of `rowHeight` on the grid's Document to the value entered. + */ + // @undoBatch + // onRowHeightEnter = (e: React.KeyboardEvent) => { + // if (e.key === "Enter" || e.key === "Tab") { + // if (e.currentTarget.valueAsNumber > 0 && this.props.CollectionView.props.Document.rowHeight as number !== e.currentTarget.valueAsNumber) { + // this.props.CollectionView.props.Document.rowHeight = e.currentTarget.valueAsNumber; + // } + // } + // } + + /** + * Sets whether the grid is flexible or not on the grid's Document. + */ + @undoBatch + toggleFlex = () => { + this.props.CollectionView.props.Document.gridFlex = !BoolCast(this.props.CollectionView.props.Document.gridFlex, true); + } + + /** + * Increments the value of numCols on button click + */ + onIncrementButtonClick = () => { + this.clicked = true; + this.entered && (this.props.CollectionView.props.Document.gridNumCols as number)--; + undoBatch(() => this.props.CollectionView.props.Document.gridNumCols = this.numCols + 1)(); + this.entered = false; + } + + /** + * Decrements the value of numCols on button click + */ + onDecrementButtonClick = () => { + this.clicked = true; + if (!this.decrementLimitReached) { + this.entered && (this.props.CollectionView.props.Document.gridNumCols as number)++; + undoBatch(() => this.props.CollectionView.props.Document.gridNumCols = this.numCols - 1)(); + } + this.entered = false; + } + + /** + * Increments the value of numCols on button hover + */ + incrementValue = () => { + this.entered = true; + if (!this.clicked && !this.decrementLimitReached) { + this.props.CollectionView.props.Document.gridNumCols = this.numCols + 1; + } + this.decrementLimitReached = false; + this.clicked = false; + } + + /** + * Decrements the value of numCols on button hover + */ + decrementValue = () => { + this.entered = true; + if (!this.clicked) { + if (this.numCols !== 1) { + this.props.CollectionView.props.Document.gridNumCols = this.numCols - 1; + } + else { + this.decrementLimitReached = true; + } + } + + this.clicked = false; + } + + /** + * Toggles the value of preventCollision + */ + toggleCollisions = () => { + this.props.CollectionView.props.Document.gridPreventCollision = !this.props.CollectionView.props.Document.gridPreventCollision; + } + + /** + * Changes the value of the compactType + */ + changeCompactType = (e: React.ChangeEvent) => { + // need to change startCompaction so that this operation will be undoable. + this.props.CollectionView.props.Document.gridStartCompaction = e.target.selectedOptions[0].value; + } + + render() { + return ( +
+ + + + + ) => { e.stopPropagation(); e.preventDefault(); e.currentTarget.focus(); }} /> + + + + {/* + + + + ) => { e.stopPropagation(); e.preventDefault(); e.currentTarget.focus(); }} /> + */} + + + + + + + + + + + + + + +
+ ); + } +} \ No newline at end of file diff --git a/src/client/views/collections/CollectionView.tsx b/src/client/views/collections/CollectionView.tsx index e18fe319e..6cd6a827f 100644 --- a/src/client/views/collections/CollectionView.tsx +++ b/src/client/views/collections/CollectionView.tsx @@ -47,7 +47,6 @@ import { SubCollectionViewProps } from './CollectionSubView'; import { CollectionTimeView } from './CollectionTimeView'; import { CollectionTreeView } from "./CollectionTreeView"; import './CollectionView.scss'; -import { CollectionViewBaseChrome } from './CollectionViewChromes'; import CollectionMenu from './CollectionMenu'; const higflyout = require("@hig/flyout"); export const { anchorPoints } = higflyout; @@ -235,16 +234,8 @@ export class CollectionView extends Touchable { - this.props.Document._chromeStatus = value ? "collapsed" : "enabled"; - } - private SubView = (type: CollectionViewType, renderProps: CollectionRenderProps) => { - // currently cant think of a reason for collection docking view to have a chrome. mind may change if we ever have nested docking views -syip - const chrome = this.props.Document._chromeStatus === "disabled" || this.props.Document._chromeStatus === "replaced" || type === CollectionViewType.Docking ? (null) : - ; - return <>{chrome} {this.SubViewHelper(type, renderProps)}; + return this.SubViewHelper(type, renderProps); } -- cgit v1.2.3-70-g09d2 From 162aea736a27a3058b49d5bc3218f75d41a38b68 Mon Sep 17 00:00:00 2001 From: Bob Zeleznik Date: Wed, 15 Jul 2020 11:27:28 -0400 Subject: make collectionMenu unpinnable --- src/client/views/collections/CollectionMenu.tsx | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src/client/views/collections/CollectionMenu.tsx') diff --git a/src/client/views/collections/CollectionMenu.tsx b/src/client/views/collections/CollectionMenu.tsx index 1644bc726..d7e2baca8 100644 --- a/src/client/views/collections/CollectionMenu.tsx +++ b/src/client/views/collections/CollectionMenu.tsx @@ -32,6 +32,9 @@ export default class CollectionMenu extends AntimodeMenu { @action toggleMenuPin = (e: React.MouseEvent) => { Doc.UserDoc()["menuCollections-pinned"] = this.Pinned = !this.Pinned; + if (!this.Pinned && this._left < 0) { + this.jumpTo(300, 300); + } } render() { -- cgit v1.2.3-70-g09d2 From ba86637704663e4791b0bccd2762f15a55fc188d Mon Sep 17 00:00:00 2001 From: Bob Zeleznik Date: Wed, 15 Jul 2020 11:32:25 -0400 Subject: moved all of collectionViewChrome permanently into CollectionMenu --- src/client/views/DocumentDecorations.tsx | 2 +- src/client/views/collections/CollectionMenu.scss | 5 +- src/client/views/collections/CollectionMenu.tsx | 25 +- .../views/collections/CollectionViewChromes.scss | 466 ------------ .../views/collections/CollectionViewChromes.tsx | 800 --------------------- 5 files changed, 15 insertions(+), 1283 deletions(-) delete mode 100644 src/client/views/collections/CollectionViewChromes.scss delete mode 100644 src/client/views/collections/CollectionViewChromes.tsx (limited to 'src/client/views/collections/CollectionMenu.tsx') diff --git a/src/client/views/DocumentDecorations.tsx b/src/client/views/DocumentDecorations.tsx index 444d2fe50..bf3037e91 100644 --- a/src/client/views/DocumentDecorations.tsx +++ b/src/client/views/DocumentDecorations.tsx @@ -150,7 +150,7 @@ export class DocumentDecorations extends React.Component<{}, { value: string }> if (e.button === 0 && !e.altKey && !e.ctrlKey) { let child = SelectionManager.SelectedDocuments()[0].ContentDiv!.children[0]; while (child.children.length) { - const next = Array.from(child.children).find(c => typeof (c.className) !== "string" || !c.className.includes("collectionViewChrome")); + const next = Array.from(child.children).find(c => typeof (c.className) !== "string"); if (typeof (next?.className) === "string" && next?.className.includes("documentView-node")) break; if (next) child = next; else break; diff --git a/src/client/views/collections/CollectionMenu.scss b/src/client/views/collections/CollectionMenu.scss index c1a3f9c09..348b9e6ea 100644 --- a/src/client/views/collections/CollectionMenu.scss +++ b/src/client/views/collections/CollectionMenu.scss @@ -11,6 +11,8 @@ background: #121721; color: white; transform-origin: top left; + top: 0; + width:100%; .antimodeMenu-button { padding:0; @@ -21,13 +23,14 @@ } } - .collectionViewChrome { + .collectionMenu { display: flex; padding-bottom: 1px; height: 32px; border-bottom: .5px solid rgb(180, 180, 180); overflow: visible; z-index: 9001; + border: unset; .collectionViewBaseChrome { display: flex; diff --git a/src/client/views/collections/CollectionMenu.tsx b/src/client/views/collections/CollectionMenu.tsx index d7e2baca8..827c3e299 100644 --- a/src/client/views/collections/CollectionMenu.tsx +++ b/src/client/views/collections/CollectionMenu.tsx @@ -47,7 +47,7 @@ export default class CollectionMenu extends AntimodeMenu { } } -interface CollectionViewChromeProps { +interface CollectionMenuProps { CollectionView: CollectionView; type: CollectionViewType; } @@ -55,7 +55,7 @@ interface CollectionViewChromeProps { const stopPropagation = (e: React.SyntheticEvent) => e.stopPropagation(); @observer -export class CollectionViewBaseChrome extends React.Component { +export class CollectionViewBaseChrome extends React.Component { //(!)?\(\(\(doc.(\w+) && \(doc.\w+ as \w+\).includes\(\"(\w+)\"\) get target() { return this.props.CollectionView.props.Document; } @@ -249,14 +249,9 @@ export class CollectionViewBaseChrome extends React.Component -
+
+
{this.viewModes}
@@ -274,7 +269,7 @@ export class CollectionViewBaseChrome extends React.Component { +export class CollectionFreeFormViewChrome extends React.Component { get Document() { return this.props.CollectionView.props.Document; } @computed get dataField() { @@ -323,7 +318,7 @@ export class CollectionFreeFormViewChrome extends React.Component { +export class CollectionStackingViewChrome extends React.Component { @observable private _currentKey: string = ""; @observable private suggestions: string[] = []; @@ -423,7 +418,7 @@ export class CollectionStackingViewChrome extends React.Component { +export class CollectionSchemaViewChrome extends React.Component { // private _textwrapAllRows: boolean = Cast(this.props.CollectionView.props.Document.textwrappedSchemaRows, listSpec("string"), []).length > 0; @undoBatch @@ -470,7 +465,7 @@ export class CollectionSchemaViewChrome extends React.Component { +export class CollectionTreeViewChrome extends React.Component { get sortAscending() { return this.props.CollectionView.props.Document[this.props.CollectionView.props.fieldKey + "-sortAscending"]; @@ -506,7 +501,7 @@ export class CollectionTreeViewChrome extends React.Component { +export class Collection3DCarouselViewChrome extends React.Component { @computed get scrollSpeed() { return this.props.CollectionView.props.Document._autoScrollSpeed; } @@ -545,7 +540,7 @@ export class Collection3DCarouselViewChrome extends React.Component { +export class CollectionGridViewChrome extends React.Component { private clicked: boolean = false; private entered: boolean = false; diff --git a/src/client/views/collections/CollectionViewChromes.scss b/src/client/views/collections/CollectionViewChromes.scss deleted file mode 100644 index b1e8d20ad..000000000 --- a/src/client/views/collections/CollectionViewChromes.scss +++ /dev/null @@ -1,466 +0,0 @@ -@import "../globalCssVariables"; -@import '~js-datepicker/dist/datepicker.min.css'; - -.collectionViewChrome-cont { - position: absolute; - width: 100%; - opacity: 0.9; - z-index: 9001; - transition: top .5s; - background: lightgrey; - transform-origin: top left; - - .collectionViewChrome { - display: flex; - padding-bottom: 1px; - height: 32px; - border-bottom: .5px solid rgb(180, 180, 180); - overflow: visible; - z-index: 9001; - - .collectionViewBaseChrome { - display: flex; - - .collectionViewBaseChrome-viewPicker { - font-size: 75%; - //text-transform: uppercase; - //letter-spacing: 2px; - background: rgb(238, 238, 238); - color: grey; - outline-color: black; - border: none; - //padding: 12px 10px 11px 10px; - } - - .collectionViewBaseChrome-viewPicker:active { - outline-color: black; - } - - .collectionViewBaseChrome-button { - font-size: 75%; - text-transform: uppercase; - letter-spacing: 2px; - background: rgb(238, 238, 238); - color: purple; - outline-color: black; - border: none; - padding: 12px 10px 11px 10px; - margin-left: 10px; - } - - .collectionViewBaseChrome-cmdPicker { - margin-left: 3px; - margin-right: 0px; - font-size: 75%; - background: rgb(238, 238, 238); - border: none; - color: grey; - } - - .commandEntry-outerDiv { - pointer-events: all; - background-color: gray; - display: flex; - flex-direction: row; - height: 30px; - - .commandEntry-drop { - color: white; - width: 25px; - margin-top: auto; - margin-bottom: auto; - } - } - - .collectionViewBaseChrome-collapse { - transition: all .5s, opacity 0.3s; - position: absolute; - width: 40px; - 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 { - display: grid; - background: rgb(238, 238, 238); - color: grey; - margin-top: auto; - margin-bottom: auto; - margin-left: 5px; - } - - .collectionViewBaseChrome-viewModes { - margin-left: 25px; - } - - .collectionViewBaseChrome-viewSpecs { - margin-left: 5px; - display: grid; - - .collectionViewBaseChrome-filterIcon { - position: relative; - display: flex; - margin: auto; - background: gray; - color: white; - width: 30px; - height: 30px; - align-items: center; - justify-content: center; - } - - .collectionViewBaseChrome-viewSpecsInput { - padding: 12px 10px 11px 10px; - border: 0px; - color: grey; - text-align: center; - letter-spacing: 2px; - outline-color: black; - font-size: 75%; - background: rgb(238, 238, 238); - 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: rgb(238, 238, 238); - box-shadow: grey 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: 75%; - letter-spacing: 2px; - color: grey; - 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: 75%; - //text-transform: uppercase; - //letter-spacing: 2px; - background: rgb(238, 238, 238); - color: grey; - outline-color: black; - border: none; - //padding: 12px 10px 11px 10px; - } - - .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%; - } - } - - - .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; - display: flex; - font-size: 75%; - letter-spacing: 2px; - - .collectionStackingViewChrome-pivotField-label, - .collectionTreeViewChrome-pivotField-label, - .collection3DCarouselViewChrome-scrollSpeed-label { - vertical-align: center; - padding-left: 10px; - margin: auto; - } - - .collectionStackingViewChrome-pivotField, - .collectionTreeViewChrome-pivotField, - .collection3DCarouselViewChrome-scrollSpeed { - color: white; - width: 100%; - min-width: 100px; - display: flex; - align-items: center; - background: rgb(238, 238, 238); - - .editable-view-input, - input, - .editableView-container-editing-oneLine, - .editableView-container-editing { - margin: auto; - border: 0px; - color: grey !important; - text-align: center; - letter-spacing: 2px; - outline-color: black; - height: 100%; - } - - .react-autosuggest__container { - margin: 0; - color: grey; - padding: 0px; - } - } - } - - .collectionStackingViewChrome-pivotField:hover, - .collectionTreeViewChrome-pivotField:hover, - .collection3DCarouselViewChrome-scrollSpeed:hover { - cursor: text; - } - - } -} - -.collectionFreeFormViewChrome-cont { - width: 60px; - display: flex; - position: relative; - align-items: center; - - .fwdKeyframe, - .numKeyframe, - .backKeyframe { - cursor: pointer; - position: absolute; - width: 20; - height: 30; - bottom: 0; - background: gray; - display: flex; - align-items: center; - color: white; - } - - .backKeyframe { - left: 0; - - svg { - display: block; - margin: auto; - } - } - - .numKeyframe { - left: 20; - display: flex; - flex-direction: column; - padding: 5px; - } - - .fwdKeyframe { - left: 40; - - svg { - display: block; - margin: auto; - } - } -} - -.collectionSchemaViewChrome-cont { - display: flex; - font-size: 10.5px; - - .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: 41px; - background-color: black; - position: relative; - } - - .collectionSchemaViewChrome-togglerButton { - width: 47px; - height: 35px; - background-color: $light-color-secondary; - // position: absolute; - transition: all 0.5s ease; - // top: 3px; - margin-top: 3px; - color: 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 #aaa; - 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 #aaa; - background-color: #fff; - font-family: Helvetica, sans-serif; - font-weight: 300; - font-size: 16px; - 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: #ddd; -} \ No newline at end of file diff --git a/src/client/views/collections/CollectionViewChromes.tsx b/src/client/views/collections/CollectionViewChromes.tsx deleted file mode 100644 index 7f1fe7649..000000000 --- a/src/client/views/collections/CollectionViewChromes.tsx +++ /dev/null @@ -1,800 +0,0 @@ -import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; -import { action, computed, observable, runInAction, Lambda } from "mobx"; -import { observer } from "mobx-react"; -import * as React from "react"; -import { Doc, DocListCast, Opt } from "../../../fields/Doc"; -import { Id } from "../../../fields/FieldSymbols"; -import { List } from "../../../fields/List"; -import { listSpec } from "../../../fields/Schema"; -import { BoolCast, Cast, NumCast, StrCast } from "../../../fields/Types"; -import { Utils, emptyFunction, setupMoveUpEvents } from "../../../Utils"; -import { DragManager } from "../../util/DragManager"; -import { undoBatch } from "../../util/UndoManager"; -import { EditableView } from "../EditableView"; -import { COLLECTION_BORDER_WIDTH } from "../globalCssVariables.scss"; -import { CollectionViewType } from "./CollectionView"; -import { CollectionView } from "./CollectionView"; -import "./CollectionViewChromes.scss"; -import { CollectionFreeFormDocumentView } from "../nodes/CollectionFreeFormDocumentView"; - -interface CollectionViewChromeProps { - CollectionView: CollectionView; - type: CollectionViewType; - collapse?: (value: boolean) => any; - PanelWidth: () => number; -} - -interface Filter { - key: string; - value: string; - contains: boolean; -} - -const stopPropagation = (e: React.SyntheticEvent) => e.stopPropagation(); - -@observer -export class CollectionViewBaseChrome extends React.Component { - //(!)?\(\(\(doc.(\w+) && \(doc.\w+ as \w+\).includes\(\"(\w+)\"\) - - get target() { return this.props.CollectionView.props.Document; } - _templateCommand = { - params: ["target", "source"], title: "=> item view", - script: "this.target.childLayout = getDocTemplate(this.source?.[0])", - immediate: undoBatch((source: Doc[]) => source.length && (this.target.childLayout = Doc.getDocTemplate(source?.[0]))), - initialize: emptyFunction, - }; - _narrativeCommand = { - params: ["target", "source"], title: "=> child click view", - script: "this.target.childClickedOpenTemplateView = getDocTemplate(this.source?.[0])", - immediate: undoBatch((source: Doc[]) => source.length && (this.target.childClickedOpenTemplateView = Doc.getDocTemplate(source?.[0]))), - initialize: emptyFunction, - }; - _contentCommand = { - params: ["target", "source"], title: "=> clear content", - script: "getProto(this.target).data = copyField(this.source);", - immediate: undoBatch((source: Doc[]) => Doc.GetProto(this.target).data = new List(source)), // Doc.aliasDocs(source), - initialize: emptyFunction, - }; - _viewCommand = { - params: ["target"], title: "=> reset view", - script: "this.target._panX = this.restoredPanX; this.target._panY = this.restoredPanY; this.target.scale = this.restoredScale;", - immediate: undoBatch((source: Doc[]) => { this.target._panX = 0; this.target._panY = 0; this.target.scale = 1; }), - initialize: (button: Doc) => { button.restoredPanX = this.target._panX; button.restoredPanY = this.target._panY; button.restoredScale = this.target.scale; }, - }; - _clusterCommand = { - params: ["target"], title: "=> fit content", - script: "this.target._fitToBox = !this.target._fitToBox;", - immediate: undoBatch((source: Doc[]) => this.target._fitToBox = !this.target._fitToBox), - initialize: emptyFunction - }; - _fitContentCommand = { - params: ["target"], title: "=> toggle clusters", - script: "this.target.useClusters = !this.target.useClusters;", - immediate: undoBatch((source: Doc[]) => this.target.useClusters = !this.target.useClusters), - initialize: emptyFunction - }; - - _freeform_commands = [this._viewCommand, this._fitContentCommand, this._clusterCommand, this._contentCommand, this._templateCommand, this._narrativeCommand]; - _stacking_commands = [this._contentCommand, this._templateCommand]; - _masonry_commands = [this._contentCommand, this._templateCommand]; - _schema_commands = [this._templateCommand, this._narrativeCommand]; - _tree_commands = []; - private get _buttonizableCommands() { - switch (this.props.type) { - case CollectionViewType.Tree: return this._tree_commands; - case CollectionViewType.Schema: return this._schema_commands; - case CollectionViewType.Stacking: return this._stacking_commands; - case CollectionViewType.Masonry: return this._stacking_commands; - case CollectionViewType.Freeform: return this._freeform_commands; - case CollectionViewType.Time: return this._freeform_commands; - case CollectionViewType.Carousel: return this._freeform_commands; - case CollectionViewType.Carousel3D: return this._freeform_commands; - } - return []; - } - private _picker: any; - private _commandRef = React.createRef(); - private _viewRef = React.createRef(); - @observable private _currentKey: string = ""; - - componentDidMount = action(() => { - this._currentKey = this._currentKey || (this._buttonizableCommands.length ? this._buttonizableCommands[0]?.title : ""); - // chrome status is one of disabled, collapsed, or visible. this determines initial state from document - switch (this.props.CollectionView.props.Document._chromeStatus) { - case "disabled": - throw new Error("how did you get here, if chrome status is 'disabled' on a collection, a chrome shouldn't even be instantiated!"); - case "collapsed": - this.props.collapse?.(true); - break; - } - }); - - @undoBatch - viewChanged = (e: React.ChangeEvent) => { - //@ts-ignore - this.document._viewType = e.target.selectedOptions[0].value; - } - - commandChanged = (e: React.ChangeEvent) => { - //@ts-ignore - runInAction(() => this._currentKey = e.target.selectedOptions[0].value); - } - - @action - toggleViewSpecs = (e: React.SyntheticEvent) => { - this.document._facetWidth = this.document._facetWidth ? 0 : 200; - e.stopPropagation(); - } - - @action closeViewSpecs = () => { - this.document._facetWidth = 0; - } - - // @action - // openDatePicker = (e: React.PointerEvent) => { - // if (this._picker) { - // this._picker.alwaysShow = true; - // this._picker.show(); - // // TODO: calendar is offset when zoomed in/out - // // this._picker.calendar.style.position = "absolute"; - // // let transform = this.props.CollectionView.props.ScreenToLocalTransform(); - // // let x = parseInt(this._picker.calendar.style.left) / transform.Scale; - // // let y = parseInt(this._picker.calendar.style.top) / transform.Scale; - // // this._picker.calendar.style.left = x; - // // this._picker.calendar.style.top = y; - - // e.stopPropagation(); - // } - // } - - // runInAction(() => this._dateValue = e.target.value)} - // onPointerDown={this.openDatePicker} - // placeholder="Value" /> - // @action.bound - // applyFilter = (e: React.MouseEvent) => { - // const keyRestrictionScript = "(" + this._keyRestrictions.map(i => i[1]).filter(i => i.length > 0).join(" && ") + ")"; - // const yearOffset = this._dateWithinValue[1] === 'y' ? 1 : 0; - // const monthOffset = this._dateWithinValue[1] === 'm' ? parseInt(this._dateWithinValue[0]) : 0; - // const weekOffset = this._dateWithinValue[1] === 'w' ? parseInt(this._dateWithinValue[0]) : 0; - // const dayOffset = (this._dateWithinValue[1] === 'd' ? parseInt(this._dateWithinValue[0]) : 0) + weekOffset * 7; - // let dateRestrictionScript = ""; - // if (this._dateValue instanceof Date) { - // const lowerBound = new Date(this._dateValue.getFullYear() - yearOffset, this._dateValue.getMonth() - monthOffset, this._dateValue.getDate() - dayOffset); - // const upperBound = new Date(this._dateValue.getFullYear() + yearOffset, this._dateValue.getMonth() + monthOffset, this._dateValue.getDate() + dayOffset + 1); - // dateRestrictionScript = `((doc.creationDate as any).date >= ${lowerBound.valueOf()} && (doc.creationDate as any).date <= ${upperBound.valueOf()})`; - // } - // else { - // const createdDate = new Date(this._dateValue); - // if (!isNaN(createdDate.getTime())) { - // const lowerBound = new Date(createdDate.getFullYear() - yearOffset, createdDate.getMonth() - monthOffset, createdDate.getDate() - dayOffset); - // const upperBound = new Date(createdDate.getFullYear() + yearOffset, createdDate.getMonth() + monthOffset, createdDate.getDate() + dayOffset + 1); - // dateRestrictionScript = `((doc.creationDate as any).date >= ${lowerBound.valueOf()} && (doc.creationDate as any).date <= ${upperBound.valueOf()})`; - // } - // } - // const fullScript = dateRestrictionScript.length || keyRestrictionScript.length ? dateRestrictionScript.length ? - // `${dateRestrictionScript} ${keyRestrictionScript.length ? "&&" : ""} (${keyRestrictionScript})` : - // `(${keyRestrictionScript}) ${dateRestrictionScript.length ? "&&" : ""} ${dateRestrictionScript}` : - // "true"; - - // this.props.CollectionView.props.Document.viewSpecScript = ScriptField.MakeFunction(fullScript, { doc: Doc.name }); - // } - - // datePickerRef = (node: HTMLInputElement) => { - // if (node) { - // try { - // this._picker = datepicker("#" + node.id, { - // disabler: (date: Date) => date > new Date(), - // onSelect: (instance: any, date: Date) => runInAction(() => {}), // this._dateValue = date), - // dateSelected: new Date() - // }); - // } catch (e) { - // console.log("date picker exception:" + e); - // } - // } - // } - - - @action - toggleCollapse = () => { - this.document._chromeStatus = this.document._chromeStatus === "enabled" ? "collapsed" : "enabled"; - if (this.props.collapse) { - this.props.collapse(this.props.CollectionView.props.Document._chromeStatus !== "enabled"); - } - } - - @computed get subChrome() { - const collapsed = this.document._chromeStatus !== "enabled"; - if (collapsed) return null; - switch (this.props.type) { - case CollectionViewType.Freeform: return (); - case CollectionViewType.Stacking: return (); - case CollectionViewType.Schema: return (); - case CollectionViewType.Tree: return (); - case CollectionViewType.Masonry: return (); - case CollectionViewType.Carousel3D: return (); - case CollectionViewType.Grid: return (); - default: return null; - } - } - - private get document() { - return this.props.CollectionView.props.Document; - } - - private dropDisposer?: DragManager.DragDropDisposer; - protected createDropTarget = (ele: HTMLDivElement) => { - this.dropDisposer?.(); - if (ele) { - this.dropDisposer = DragManager.MakeDropTarget(ele, this.drop.bind(this), this.document); - } - } - - @undoBatch - @action - protected drop(e: Event, de: DragManager.DropEvent): boolean { - const docDragData = de.complete.docDragData; - if (docDragData?.draggedDocuments.length) { - this._buttonizableCommands.filter(c => c.title === this._currentKey).map(c => c.immediate(docDragData.draggedDocuments || [])); - e.stopPropagation(); - } - return true; - } - - dragViewDown = (e: React.PointerEvent) => { - setupMoveUpEvents(this, e, (e, down, delta) => { - const vtype = this.props.CollectionView.collectionViewType; - const c = { - params: ["target"], title: vtype, - script: `this.target._viewType = '${StrCast(this.props.CollectionView.props.Document._viewType)}'`, - immediate: (source: Doc[]) => this.props.CollectionView.props.Document._viewType = Doc.getDocTemplate(source?.[0]), - initialize: emptyFunction, - }; - DragManager.StartButtonDrag([this._viewRef.current!], c.script, StrCast(c.title), - { target: this.props.CollectionView.props.Document }, c.params, c.initialize, e.clientX, e.clientY); - return true; - }, emptyFunction, emptyFunction); - } - dragCommandDown = (e: React.PointerEvent) => { - setupMoveUpEvents(this, e, (e, down, delta) => { - this._buttonizableCommands.filter(c => c.title === this._currentKey).map(c => - DragManager.StartButtonDrag([this._commandRef.current!], c.script, c.title, - { target: this.props.CollectionView.props.Document }, c.params, c.initialize, e.clientX, e.clientY)); - return true; - }, emptyFunction, () => { - this._buttonizableCommands.filter(c => c.title === this._currentKey).map(c => c.immediate([])); - }); - } - - @computed get templateChrome() { - const collapsed = this.props.CollectionView.props.Document._chromeStatus !== "enabled"; - return
-
-
- -
- -
-
; - } - - @computed get viewModes() { - const collapsed = this.props.CollectionView.props.Document._chromeStatus !== "enabled"; - return
-
-
- -
- -
-
; - } - - render() { - const collapsed = this.props.CollectionView.props.Document._chromeStatus !== "enabled"; - const scale = Math.min(1, this.props.CollectionView.props.ScreenToLocalTransform()?.Scale); - return ( -
-
-
- - {this.viewModes} -
-
- -
-
- {this.templateChrome} -
- {this.subChrome} -
-
- ); - } -} - -@observer -export class CollectionFreeFormViewChrome extends React.Component { - - get Document() { return this.props.CollectionView.props.Document; } - @computed get dataField() { - return this.props.CollectionView.props.Document[Doc.LayoutFieldKey(this.props.CollectionView.props.Document)]; - } - @computed get childDocs() { - return DocListCast(this.dataField); - } - @undoBatch - @action - nextKeyframe = (): void => { - const currentFrame = NumCast(this.Document.currentFrame); - if (currentFrame === undefined) { - this.Document.currentFrame = 0; - CollectionFreeFormDocumentView.setupKeyframes(this.childDocs, 0); - } - CollectionFreeFormDocumentView.updateKeyframe(this.childDocs, currentFrame || 0); - this.Document.currentFrame = Math.max(0, (currentFrame || 0) + 1); - this.Document.lastFrame = Math.max(NumCast(this.Document.currentFrame), NumCast(this.Document.lastFrame)); - } - @undoBatch - @action - prevKeyframe = (): void => { - const currentFrame = NumCast(this.Document.currentFrame); - if (currentFrame === undefined) { - this.Document.currentFrame = 0; - CollectionFreeFormDocumentView.setupKeyframes(this.childDocs, 0); - } - CollectionFreeFormDocumentView.gotoKeyframe(this.childDocs.slice()); - this.Document.currentFrame = Math.max(0, (currentFrame || 0) - 1); - } - render() { - return this.Document.isAnnotationOverlay ? (null) : -
-
- -
-
this.Document.editing = !this.Document.editing)} > - {NumCast(this.Document.currentFrame)} -
-
- -
-
; - } -} - -@observer -export class CollectionStackingViewChrome extends React.Component { - @observable private _currentKey: string = ""; - @observable private suggestions: string[] = []; - - @computed private get descending() { return StrCast(this.props.CollectionView.props.Document._columnsSort) === "descending"; } - @computed get pivotField() { return StrCast(this.props.CollectionView.props.Document._pivotField); } - - getKeySuggestions = async (value: string): Promise => { - value = value.toLowerCase(); - const docs = DocListCast(this.props.CollectionView.props.Document[this.props.CollectionView.props.fieldKey]); - if (docs instanceof Doc) { - return Object.keys(docs).filter(key => key.toLowerCase().startsWith(value)); - } else { - const keys = new Set(); - docs.forEach(doc => Doc.allKeys(doc).forEach(key => keys.add(key))); - return Array.from(keys).filter(key => key.toLowerCase().startsWith(value)); - } - } - - @action - onKeyChange = (e: React.ChangeEvent, { newValue }: { newValue: string }) => { - this._currentKey = newValue; - } - - getSuggestionValue = (suggestion: string) => suggestion; - - renderSuggestion = (suggestion: string) => { - return

{suggestion}

; - } - - onSuggestionFetch = async ({ value }: { value: string }) => { - const sugg = await this.getKeySuggestions(value); - runInAction(() => { - this.suggestions = sugg; - }); - } - - @action - onSuggestionClear = () => { - this.suggestions = []; - } - - @action - setValue = (value: string) => { - this.props.CollectionView.props.Document._pivotField = value; - return true; - } - - @action toggleSort = () => { - this.props.CollectionView.props.Document._columnsSort = - this.props.CollectionView.props.Document._columnsSort === "descending" ? "ascending" : - this.props.CollectionView.props.Document._columnsSort === "ascending" ? undefined : "descending"; - } - @action resetValue = () => { this._currentKey = this.pivotField; }; - - render() { - return ( -
-
-
- GROUP BY: -
-
- -
-
- this.pivotField} - autosuggestProps={ - { - resetValue: this.resetValue, - value: this._currentKey, - onChange: this.onKeyChange, - autosuggestProps: { - inputProps: - { - value: this._currentKey, - onChange: this.onKeyChange - }, - getSuggestionValue: this.getSuggestionValue, - suggestions: this.suggestions, - alwaysRenderSuggestions: true, - renderSuggestion: this.renderSuggestion, - onSuggestionsFetchRequested: this.onSuggestionFetch, - onSuggestionsClearRequested: this.onSuggestionClear - } - }} - oneLine - SetValue={this.setValue} - contents={this.pivotField ? this.pivotField : "N/A"} - /> -
-
-
- ); - } -} - - -@observer -export class CollectionSchemaViewChrome extends React.Component { - // private _textwrapAllRows: boolean = Cast(this.props.CollectionView.props.Document.textwrappedSchemaRows, listSpec("string"), []).length > 0; - - @undoBatch - togglePreview = () => { - const dividerWidth = 4; - const borderWidth = Number(COLLECTION_BORDER_WIDTH); - const panelWidth = this.props.CollectionView.props.PanelWidth(); - const previewWidth = NumCast(this.props.CollectionView.props.Document.schemaPreviewWidth); - const tableWidth = panelWidth - 2 * borderWidth - dividerWidth - previewWidth; - this.props.CollectionView.props.Document.schemaPreviewWidth = previewWidth === 0 ? Math.min(tableWidth / 3, 200) : 0; - } - - @undoBatch - @action - toggleTextwrap = async () => { - const textwrappedRows = Cast(this.props.CollectionView.props.Document.textwrappedSchemaRows, listSpec("string"), []); - if (textwrappedRows.length) { - this.props.CollectionView.props.Document.textwrappedSchemaRows = new List([]); - } else { - const docs = DocListCast(this.props.CollectionView.props.Document[this.props.CollectionView.props.fieldKey]); - const allRows = docs instanceof Doc ? [docs[Id]] : docs.map(doc => doc[Id]); - this.props.CollectionView.props.Document.textwrappedSchemaRows = new List(allRows); - } - } - - - render() { - const previewWidth = NumCast(this.props.CollectionView.props.Document.schemaPreviewWidth); - const textWrapped = Cast(this.props.CollectionView.props.Document.textwrappedSchemaRows, listSpec("string"), []).length > 0; - - return ( -
-
-
Show Preview:
-
-
- {previewWidth !== 0 ? "on" : "off"} -
-
-
-
- ); - } -} - -@observer -export class CollectionTreeViewChrome extends React.Component { - - get sortAscending() { - return this.props.CollectionView.props.Document[this.props.CollectionView.props.fieldKey + "-sortAscending"]; - } - set sortAscending(value) { - this.props.CollectionView.props.Document[this.props.CollectionView.props.fieldKey + "-sortAscending"] = value; - } - @computed private get ascending() { - return Cast(this.sortAscending, "boolean", null); - } - - @action toggleSort = () => { - if (this.sortAscending) this.sortAscending = undefined; - else if (this.sortAscending === undefined) this.sortAscending = false; - else this.sortAscending = true; - } - - render() { - return ( -
- -
- ); - } -} - -// Enter scroll speed for 3D Carousel -@observer -export class Collection3DCarouselViewChrome extends React.Component { - @computed get scrollSpeed() { - return this.props.CollectionView.props.Document._autoScrollSpeed; - } - - @action - setValue = (value: string) => { - const numValue = Number(StrCast(value)); - if (numValue > 0) { - this.props.CollectionView.props.Document._autoScrollSpeed = numValue; - return true; - } - return false; - } - - render() { - return ( -
-
-
- AUTOSCROLL SPEED: -
-
- StrCast(this.scrollSpeed)} - oneLine - SetValue={this.setValue} - contents={this.scrollSpeed ? this.scrollSpeed : 1000} /> -
-
-
- ); - } -} - -/** - * Chrome for grid view. - */ -@observer -export class CollectionGridViewChrome extends React.Component { - - private clicked: boolean = false; - private entered: boolean = false; - private decrementLimitReached: boolean = false; - @observable private resize = false; - private resizeListenerDisposer: Opt; - - componentDidMount() { - - runInAction(() => this.resize = this.props.CollectionView.props.PanelWidth() < 700); - - // listener to reduce text on chrome resize (panel resize) - this.resizeListenerDisposer = computed(() => this.props.CollectionView.props.PanelWidth()).observe(({ newValue }) => { - runInAction(() => this.resize = newValue < 700); - }); - } - - componentWillUnmount() { - this.resizeListenerDisposer?.(); - } - - get numCols() { return NumCast(this.props.CollectionView.props.Document.gridNumCols, 10); } - - /** - * Sets the value of `numCols` on the grid's Document to the value entered. - */ - @undoBatch - onNumColsEnter = (e: React.KeyboardEvent) => { - if (e.key === "Enter" || e.key === "Tab") { - if (e.currentTarget.valueAsNumber > 0) { - this.props.CollectionView.props.Document.gridNumCols = e.currentTarget.valueAsNumber; - } - - } - } - - /** - * Sets the value of `rowHeight` on the grid's Document to the value entered. - */ - // @undoBatch - // onRowHeightEnter = (e: React.KeyboardEvent) => { - // if (e.key === "Enter" || e.key === "Tab") { - // if (e.currentTarget.valueAsNumber > 0 && this.props.CollectionView.props.Document.rowHeight as number !== e.currentTarget.valueAsNumber) { - // this.props.CollectionView.props.Document.rowHeight = e.currentTarget.valueAsNumber; - // } - // } - // } - - /** - * Sets whether the grid is flexible or not on the grid's Document. - */ - @undoBatch - toggleFlex = () => { - this.props.CollectionView.props.Document.gridFlex = !BoolCast(this.props.CollectionView.props.Document.gridFlex, true); - } - - /** - * Increments the value of numCols on button click - */ - onIncrementButtonClick = () => { - this.clicked = true; - this.entered && (this.props.CollectionView.props.Document.gridNumCols as number)--; - undoBatch(() => this.props.CollectionView.props.Document.gridNumCols = this.numCols + 1)(); - this.entered = false; - } - - /** - * Decrements the value of numCols on button click - */ - onDecrementButtonClick = () => { - this.clicked = true; - if (!this.decrementLimitReached) { - this.entered && (this.props.CollectionView.props.Document.gridNumCols as number)++; - undoBatch(() => this.props.CollectionView.props.Document.gridNumCols = this.numCols - 1)(); - } - this.entered = false; - } - - /** - * Increments the value of numCols on button hover - */ - incrementValue = () => { - this.entered = true; - if (!this.clicked && !this.decrementLimitReached) { - this.props.CollectionView.props.Document.gridNumCols = this.numCols + 1; - } - this.decrementLimitReached = false; - this.clicked = false; - } - - /** - * Decrements the value of numCols on button hover - */ - decrementValue = () => { - this.entered = true; - if (!this.clicked) { - if (this.numCols !== 1) { - this.props.CollectionView.props.Document.gridNumCols = this.numCols - 1; - } - else { - this.decrementLimitReached = true; - } - } - - this.clicked = false; - } - - /** - * Toggles the value of preventCollision - */ - toggleCollisions = () => { - this.props.CollectionView.props.Document.gridPreventCollision = !this.props.CollectionView.props.Document.gridPreventCollision; - } - - /** - * Changes the value of the compactType - */ - changeCompactType = (e: React.ChangeEvent) => { - // need to change startCompaction so that this operation will be undoable. - this.props.CollectionView.props.Document.gridStartCompaction = e.target.selectedOptions[0].value; - } - - render() { - return ( -
- - - - - ) => { e.stopPropagation(); e.preventDefault(); e.currentTarget.focus(); }} /> - - - - {/* - - - - ) => { e.stopPropagation(); e.preventDefault(); e.currentTarget.focus(); }} /> - */} - - - - - - - - - - - - - - -
- ); - } -} -- cgit v1.2.3-70-g09d2 From 3fdee81100954e66f54c73661cb11967993ff467 Mon Sep 17 00:00:00 2001 From: Bob Zeleznik Date: Wed, 15 Jul 2020 15:24:53 -0400 Subject: fixed tooltips to share a csss style. added tooltips for richtext. --- src/client/documents/Documents.ts | 2 +- src/client/views/DocumentButtonBar.tsx | 10 ++--- src/client/views/DocumentDecorations.tsx | 15 +++---- src/client/views/MainView.scss | 4 ++ .../views/collections/CollectionLinearView.tsx | 20 +++++---- src/client/views/collections/CollectionMenu.tsx | 13 +++--- src/client/views/collections/CollectionView.tsx | 3 +- .../CollectionFreeFormLinkView.tsx | 12 +++--- src/client/views/linking/LinkEditor.tsx | 14 +++---- src/client/views/linking/LinkMenuItem.tsx | 19 +++------ src/client/views/nodes/DocumentLinksButton.tsx | 5 +-- src/client/views/nodes/DocumentView.tsx | 25 +++-------- .../formattedText/FormattedTextBoxComment.tsx | 4 +- .../views/nodes/formattedText/RichTextMenu.tsx | 49 +++++++++++++--------- src/client/views/pdf/PDFViewer.tsx | 2 +- 15 files changed, 94 insertions(+), 103 deletions(-) (limited to 'src/client/views/collections/CollectionMenu.tsx') diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts index 1fd533b62..b57f4c6c7 100644 --- a/src/client/documents/Documents.ts +++ b/src/client/documents/Documents.ts @@ -915,7 +915,7 @@ export namespace DocUtils { const linkDoc = Docs.Create.LinkDocument(source, target, { linkRelationship, layoutKey: "layout_linkView", description }, id); linkDoc.linkDisplay = true; - linkDoc.hideAnhors = true; + linkDoc.hidden = true; linkDoc.layout_linkView = Cast(Cast(Doc.UserDoc()["template-button-link"], Doc, null).dragFactory, Doc, null); Doc.GetProto(linkDoc).title = ComputedField.MakeFunction('self.anchor1?.title +" (" + (self.linkRelationship||"to") +") " + self.anchor2?.title'); diff --git a/src/client/views/DocumentButtonBar.tsx b/src/client/views/DocumentButtonBar.tsx index 05538a28e..45f4c7393 100644 --- a/src/client/views/DocumentButtonBar.tsx +++ b/src/client/views/DocumentButtonBar.tsx @@ -118,7 +118,7 @@ export class DocumentButtonBar extends React.Component<{ views: () => (DocumentV const targetDoc = this.view0?.props.Document; const published = targetDoc && Doc.GetProto(targetDoc)[GoogleRef] !== undefined; const animation = this.isAnimatingPulse ? "shadow-pulse 1s linear infinite" : "none"; - return !targetDoc ? (null) :
{`${published ? "Push" : "Publish"} to Google Docs`}
}> + return !targetDoc ? (null) :
{`${published ? "Push" : "Publish"} to Google Docs`}
}>
(DocumentV })(); return !targetDoc || !dataDoc || !dataDoc[GoogleRef] ? (null) :
{title}
}> + title={<>
{title}
}>
{ @@ -197,7 +197,7 @@ export class DocumentButtonBar extends React.Component<{ views: () => (DocumentV get pinButton() { const targetDoc = this.view0?.props.Document; const isPinned = targetDoc && Doc.isDocPinned(targetDoc); - return !targetDoc ? (null) :
{Doc.isDocPinned(targetDoc) ? "Unpin from presentation" : "Pin to presentation"}
}> + return !targetDoc ? (null) :
{Doc.isDocPinned(targetDoc) ? "Unpin from presentation" : "Pin to presentation"}
}>
DockedFrameRenderer.PinDoc(targetDoc, isPinned)}> @@ -209,7 +209,7 @@ export class DocumentButtonBar extends React.Component<{ views: () => (DocumentV @computed get metadataButton() { const view0 = this.view0; - return !view0 ? (null) :
Show metadata panel
}> + return !view0 ? (null) :
Show metadata panel
}>
dv).map(dv => dv!.props.Document)} suggestWithFunction /> /* tfs: @bcz This might need to be the data document? */}> @@ -258,7 +258,7 @@ export class DocumentButtonBar extends React.Component<{ views: () => (DocumentV Array.from(Object.values(Templates.TemplateList)).map(template => templates.set(template, views.reduce((checked, doc) => checked || doc?.props.Document["_show" + template.Name] ? true : false, false as boolean))); return !view0 ? (null) : -
Tap: Customize layout. Drag: Create alias
}> +
Tap: Customize layout. Drag: Create alias
}>
this._aliasDown = true)} onClose={action(() => this._aliasDown = false)} content={!this._aliasDown ? (null) : v).map(v => v as DocumentView)} templates={templates} />}> diff --git a/src/client/views/DocumentDecorations.tsx b/src/client/views/DocumentDecorations.tsx index 2fd017f7b..376b1d46b 100644 --- a/src/client/views/DocumentDecorations.tsx +++ b/src/client/views/DocumentDecorations.tsx @@ -81,6 +81,7 @@ export class DocumentDecorations extends React.Component<{}, { value: string }> return SelectionManager.SelectedDocuments().reduce((bounds, documentView) => { if (documentView.props.renderDepth === 0 || documentView.props.treeViewDoc || + !documentView.ContentDiv || Doc.AreProtosEqual(documentView.props.Document, Doc.UserDoc())) { return bounds; } @@ -88,7 +89,7 @@ export class DocumentDecorations extends React.Component<{}, { value: string }> var [sptX, sptY] = transform.transformPoint(0, 0); let [bptX, bptY] = transform.transformPoint(documentView.props.PanelWidth(), documentView.props.PanelHeight()); if (documentView.props.Document.type === DocumentType.LINK) { - const docuBox = documentView.ContentDiv!.getElementsByClassName("linkAnchorBox-cont"); + const docuBox = documentView.ContentDiv.getElementsByClassName("linkAnchorBox-cont"); if (docuBox.length) { const rect = docuBox[0].getBoundingClientRect(); sptX = rect.left; @@ -544,11 +545,11 @@ export class DocumentDecorations extends React.Component<{}, { value: string }> } const minimal = bounds.r - bounds.x < 100 ? true : false; const maximizeIcon = minimal ? ( -
Show context menu
} placement="top"> +
Show context menu
} placement="top">
) : ( -
Iconify
} placement="top"> +
Iconify
} placement="top">
{/* Currently, this is set to be enabled if there is no ink selected. It might be interesting to think about minimizing ink if it's useful? -syip2*/} @@ -572,7 +573,7 @@ export class DocumentDecorations extends React.Component<{}, { value: string }>
} : <> - {minimal ? (null) :
Show context menu
} placement="top">
+ {minimal ? (null) :
Show context menu
} placement="top">
}
@@ -611,11 +612,11 @@ export class DocumentDecorations extends React.Component<{}, { value: string }> {maximizeIcon} {titleArea} {SelectionManager.SelectedDocuments().length !== 1 || seldoc.Document.type === DocumentType.INK ? (null) : -
{`${seldoc.finalLayoutKey.includes("icon") ? "De" : ""}Iconify Document`}
} placement="top"> +
{`${seldoc.finalLayoutKey.includes("icon") ? "De" : ""}Iconify Document`}
} placement="top">
{"_"}
} -
Open Document In Tab
} placement="top">
+
Open Document In Tab
} placement="top">
{SelectionManager.SelectedDocuments().length === 1 ? DocumentDecorations.DocumentIcon(StrCast(seldoc.props.Document.layout, "...")) : "..."}
e.preventDefault()}>
{seldoc.props.renderDepth <= 1 || !seldoc.props.ContainingCollectionView ? (null) : -
tap to select containing document
} placement="top"> +
tap to select containing document
} placement="top">
e.preventDefault()}> diff --git a/src/client/views/MainView.scss b/src/client/views/MainView.scss index 5b142ffda..e1ddbc533 100644 --- a/src/client/views/MainView.scss +++ b/src/client/views/MainView.scss @@ -1,6 +1,10 @@ @import "globalCssVariables"; @import "nodeModuleOverrides"; +.dash-tooltip { + font-size: 11px; + padding: 2px; +} .mainView-tabButtons { position: relative; diff --git a/src/client/views/collections/CollectionLinearView.tsx b/src/client/views/collections/CollectionLinearView.tsx index 319cca70f..407524353 100644 --- a/src/client/views/collections/CollectionLinearView.tsx +++ b/src/client/views/collections/CollectionLinearView.tsx @@ -124,7 +124,7 @@ export class CollectionLinearView extends CollectionSubView(LinearDocument) { return
-
{BoolCast(this.props.Document.linearViewIsExpanded) ? "Close menu" : "Open menu"}
} placement="top"> +
{BoolCast(this.props.Document.linearViewIsExpanded) ? "Close menu" : "Open menu"}
} placement="top"> {menuOpener}
e.stopPropagation()} > - Creating link from: {DocumentLinksButton.StartLink.title} + Creating link from: {DocumentLinksButton.StartLink.title} + -
{LinkDescriptionPopup.showDescriptions ? "Turn off description pop-up" : - "Turn on description pop-up"}
} placement="top"> - Labels: {LinkDescriptionPopup.showDescriptions ? LinkDescriptionPopup.showDescriptions : "ON"} +
{LinkDescriptionPopup.showDescriptions ? "Turn off description pop-up" : + "Turn on description pop-up"}
} placement="top"> + + Labels: {LinkDescriptionPopup.showDescriptions ? LinkDescriptionPopup.showDescriptions : "ON"}
-
Exit link clicking mode
} placement="top"> - Clear +
Exit link clicking mode
} placement="top"> + + Clear +
{/* : , - - ]); + const button = ; + + return this.getElement(!this.SelectedCollection ? [button] : + [, + button]); } } diff --git a/src/client/views/collections/CollectionView.tsx b/src/client/views/collections/CollectionView.tsx index c1a6b5b0d..c1da23470 100644 --- a/src/client/views/collections/CollectionView.tsx +++ b/src/client/views/collections/CollectionView.tsx @@ -142,6 +142,7 @@ export class CollectionView extends Touchable d instanceof Doc); - first && (first.hidden = true); doc.displayTimecode = undefined; } doc.context = this.props.Document; diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx index dea936113..0933d525a 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx @@ -29,13 +29,13 @@ export class CollectionFreeFormLinkView extends React.Component [this.props.A.props.ScreenToLocalTransform(), this.props.B.props.ScreenToLocalTransform(), this.props.A.isSelected() || Doc.IsBrushed(this.props.A.props.Document), this.props.A.isSelected() || Doc.IsBrushed(this.props.A.props.Document)], action(() => { - if (SnappingManager.GetIsDragging()) return; + if (SnappingManager.GetIsDragging() || !this.props.A.ContentDiv || !this.props.B.ContentDiv) return; setTimeout(action(() => this._opacity = 1), 0); // since the render code depends on querying the Dom through getBoudndingClientRect, we need to delay triggering render() setTimeout(action(() => (!this.props.LinkDocs.length || !this.props.LinkDocs[0].linkDisplay) && (this._opacity = 0.05)), 750); // this will unhighlight the link line. - const acont = this.props.A.props.Document.type === DocumentType.LINK ? this.props.A.ContentDiv!.getElementsByClassName("linkAnchorBox-cont") : []; - const bcont = this.props.B.props.Document.type === DocumentType.LINK ? this.props.B.ContentDiv!.getElementsByClassName("linkAnchorBox-cont") : []; - const adiv = (acont.length ? acont[0] : this.props.A.ContentDiv!); - const bdiv = (bcont.length ? bcont[0] : this.props.B.ContentDiv!); + const acont = this.props.A.props.Document.type === DocumentType.LINK ? this.props.A.ContentDiv.getElementsByClassName("linkAnchorBox-cont") : []; + const bcont = this.props.B.props.Document.type === DocumentType.LINK ? this.props.B.ContentDiv.getElementsByClassName("linkAnchorBox-cont") : []; + const adiv = (acont.length ? acont[0] : this.props.A.ContentDiv); + const bdiv = (bcont.length ? bcont[0] : this.props.B.ContentDiv); const a = adiv.getBoundingClientRect(); const b = bdiv.getBoundingClientRect(); const abounds = adiv.parentElement!.getBoundingClientRect(); @@ -103,7 +103,7 @@ export class CollectionFreeFormLinkView extends React.Component { @observable description = StrCast(LinkManager.currentLink?.description); @observable openDropdown: boolean = false; - @observable followBehavior = this.props.linkDoc.follow ? this.props.linkDoc.follow : "Default"; @observable showInfo: boolean = false; @computed get infoIcon() { if (this.showInfo) { return "chevron-up"; } return "chevron-down"; } @observable private buttonColor: string = "black"; @@ -364,8 +363,7 @@ export class LinkEditor extends React.Component { @action changeFollowBehavior = (follow: string) => { this.openDropdown = false; - this.followBehavior = follow; - this.props.linkDoc.follow = follow; + Doc.GetProto(this.props.linkDoc).followLinkLocation = follow; } @computed @@ -376,7 +374,7 @@ export class LinkEditor extends React.Component {
- {this.followBehavior} + {StrCast(this.props.linkDoc.followLinkLocation, "Default")} @@ -388,11 +386,11 @@ export class LinkEditor extends React.Component { Default
this.changeFollowBehavior("Always open in right tab")}> + onPointerDown={() => this.changeFollowBehavior("onRight")}> Always open in right tab
this.changeFollowBehavior("Always open in new tab")}> + onPointerDown={() => this.changeFollowBehavior("inTab")}> Always open in new tab
@@ -416,7 +414,7 @@ export class LinkEditor extends React.Component { return !destination ? (null) : (
-
Return to link menu
} placement="top"> +
Return to link menu
} placement="top"> */} -
Show more link information
} placement="top"> +
Show more link information
} placement="top">
diff --git a/src/client/views/linking/LinkMenuItem.tsx b/src/client/views/linking/LinkMenuItem.tsx index 6782f625b..0e847632b 100644 --- a/src/client/views/linking/LinkMenuItem.tsx +++ b/src/client/views/linking/LinkMenuItem.tsx @@ -16,7 +16,6 @@ import { DocumentView } from '../nodes/DocumentView'; import { DocumentLinksButton } from '../nodes/DocumentLinksButton'; import { LinkDocPreview } from '../nodes/LinkDocPreview'; import { Tooltip } from '@material-ui/core'; -import { RichTextField } from '../../../fields/RichTextField'; import { DocumentType } from '../../documents/DocumentTypes'; library.add(faEye, faEdit, faTimes, faArrowRight, faChevronDown, faChevronUp, faPencilAlt, faEyeSlash); @@ -157,14 +156,8 @@ export class LinkMenuItem extends React.Component { DocumentLinksButton.EditLink = undefined; LinkDocPreview.LinkInfo = undefined; - if (this.props.linkDoc.follow) { - if (this.props.linkDoc.follow === "Default") { - DocumentManager.Instance.FollowLink(this.props.linkDoc, this.props.sourceDoc, doc => this.props.addDocTab(doc, "onRight"), false); - } else if (this.props.linkDoc.follow === "Always open in right tab") { - this.props.addDocTab(this.props.destinationDoc, "onRight"); - } else if (this.props.linkDoc.follow === "Always open in new tab") { - this.props.addDocTab(this.props.destinationDoc, "inTab"); - } + if (this.props.linkDoc.followLinkLocation && this.props.linkDoc.followLinkLocation !== "Default") { + this.props.addDocTab(this.props.destinationDoc, StrCast(this.props.linkDoc.followLinkLocation)); } else { DocumentManager.Instance.FollowLink(this.props.linkDoc, this.props.sourceDoc, doc => this.props.addDocTab(doc, "onRight"), false); } @@ -221,8 +214,6 @@ export class LinkMenuItem extends React.Component { StrCast(this.props.linkDoc.storedText).substr(0, 18) : this.props.linkDoc.storedText : undefined : undefined; - const showTitle = this.props.linkDoc.hidden ? "Show link" : "Hide link"; - return (
@@ -255,16 +246,16 @@ export class LinkMenuItem extends React.Component { {canExpand ?
this.toggleShowMore(e)}>
: <>} -
{showTitle}
}> +
{this.props.linkDoc.hidden ? "Show link" : "Hide link"}
}>
-
Edit Link
}> +
Edit Link
}>
-
Delete Link
}> +
Delete Link
}>
diff --git a/src/client/views/nodes/DocumentLinksButton.tsx b/src/client/views/nodes/DocumentLinksButton.tsx index 01c068966..bbef48e44 100644 --- a/src/client/views/nodes/DocumentLinksButton.tsx +++ b/src/client/views/nodes/DocumentLinksButton.tsx @@ -134,7 +134,6 @@ export class DocumentLinksButton extends React.Component { if (linkDoc) { @@ -213,10 +212,10 @@ export class DocumentLinksButton extends React.Component
{title}
}> +
{title}
}> {linkButton}
: !!!DocumentLinksButton.EditLink ? -
{title}
}> +
{title}
}> {linkButton}
: linkButton; diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx index a6771443a..c0a8b3a59 100644 --- a/src/client/views/nodes/DocumentView.tsx +++ b/src/client/views/nodes/DocumentView.tsx @@ -589,16 +589,12 @@ export class DocumentView extends DocComponent(Docu @undoBatch toggleLinkButtonBehavior = (): void => { + this.Document.ignoreClick = false; if (this.Document.isLinkButton || this.onClickHandler || this.Document.ignoreClick) { this.Document.isLinkButton = false; - const first = DocListCast(this.Document.links).find(d => d instanceof Doc); - first && (first.hidden = false); - this.Document.ignoreClick = false; this.Document.onClick = this.layoutDoc.onClick = undefined; } else { this.Document.isLinkButton = true; - const first = DocListCast(this.Document.links).find(d => d instanceof Doc); - first && (first.hidden = true); this.Document.followLinkZoom = false; this.Document.followLinkLocation = undefined; } @@ -606,14 +602,9 @@ export class DocumentView extends DocComponent(Docu @undoBatch toggleFollowInPlace = (): void => { + this.Document.ignoreClick = false; + this.Document.isLinkButton = !this.Document.isLinkButton; if (this.Document.isLinkButton) { - this.Document.isLinkButton = false; - const first = DocListCast(this.Document.links).find(d => d instanceof Doc); - first && (first.hidden = false); - } else { - this.Document.isLinkButton = true; - const first = DocListCast(this.Document.links).find(d => d instanceof Doc); - first && (first.hidden = true); this.Document.followLinkZoom = true; this.Document.followLinkLocation = "inPlace"; } @@ -621,15 +612,10 @@ export class DocumentView extends DocComponent(Docu @undoBatch toggleFollowOnRight = (): void => { + this.Document.ignoreClick = false; + this.Document.isLinkButton = !this.Document.isLinkButton; if (this.Document.isLinkButton) { - this.Document.isLinkButton = false; - const first = DocListCast(this.Document.links).find(d => d instanceof Doc); - first && (first.hidden = false); - } else { - this.Document.isLinkButton = true; this.Document.followLinkZoom = false; - const first = DocListCast(this.Document.links).find(d => d instanceof Doc); - first && (first.hidden = true); this.Document.followLinkLocation = "onRight"; } } @@ -643,7 +629,6 @@ export class DocumentView extends DocComponent(Docu } const makeLink = action((linkDoc: Doc) => { LinkManager.currentLink = linkDoc; - linkDoc.hidden = true; LinkCreatedBox.popupX = de.x; LinkCreatedBox.popupY = de.y - 33; diff --git a/src/client/views/nodes/formattedText/FormattedTextBoxComment.tsx b/src/client/views/nodes/formattedText/FormattedTextBoxComment.tsx index c98b5eac1..3687d5513 100644 --- a/src/client/views/nodes/formattedText/FormattedTextBoxComment.tsx +++ b/src/client/views/nodes/formattedText/FormattedTextBoxComment.tsx @@ -270,14 +270,14 @@ export class FormattedTextBoxComment {
-
Delete Link
} placement="top"> +
Delete Link
} placement="top">
this._deleteRef = r}>
-
Follow Link
} placement="top"> +
Follow Link
} placement="top">
this._followRef = r}> - - + {title}
} key={title} placement="bottom"> + +
); } @@ -388,7 +391,9 @@ export default class RichTextMenu extends AntimodeMenu { } }); } - return ; + return {key}
} placement="bottom"> + + ; } createNodesDropdown(activeMap: string, options: { node: NodeType | any | null, title: string, label: string, command: (node: NodeType | any) => void, hidden?: boolean, style?: {} }[], key: string, setter: (val: string) => {}): JSX.Element { @@ -412,7 +417,10 @@ export default class RichTextMenu extends AntimodeMenu { } }); } - return ; + + return {key}
} placement="bottom"> + + ; } changeFontSize = (mark: Mark, view: EditorView) => { @@ -595,10 +603,11 @@ export default class RichTextMenu extends AntimodeMenu { label = "No marks are currently stored"; } - const button = -
} placement="bottom"> + ; + +
; const dropdownContent =
@@ -667,11 +676,12 @@ export default class RichTextMenu extends AntimodeMenu { self.TextView.EditorView!.focus(); } - const button = -
} placement="bottom"> + ; + +
; const dropdownContent =
@@ -720,11 +730,12 @@ export default class RichTextMenu extends AntimodeMenu { UndoManager.RunInBatch(() => self.view && self.insertHighlight(self.activeHighlightColor, self.view.state, self.view.dispatch), "rt highlighter"); } - const button = -
} placement="bottom"> + ; + +
; const dropdownContent =
@@ -763,7 +774,9 @@ export default class RichTextMenu extends AntimodeMenu { const link = this.currentLink ? this.currentLink : ""; - const button = ; + const button = set hyperlink
} placement="bottom"> +
+ ; const dropdownContent =
@@ -774,9 +787,7 @@ export default class RichTextMenu extends AntimodeMenu {
; - return ( - - ); + return ; } async getTextLinkTargetTitle() { @@ -935,7 +946,7 @@ export default class RichTextMenu extends AntimodeMenu { {[this.createMarksDropdown(this.activeFontSize, this.fontSizeOptions, "font size", action((val: string) => this.activeFontSize = val)), this.createMarksDropdown(this.activeFontFamily, this.fontFamilyOptions, "font family", action((val: string) => this.activeFontFamily = val)),
, - this.createNodesDropdown(this.activeListType, this.listTypeOptions, "nodes", action((val: string) => this.activeListType = val)), + this.createNodesDropdown(this.activeListType, this.listTypeOptions, "list type", action((val: string) => this.activeListType = val)), this.createButton("sort-amount-down", "Summarize", undefined, this.insertSummarizer), this.createButton("quote-left", "Blockquote", undefined, this.insertBlockquote), this.createButton("minus", "Horizontal Rule", undefined, this.insertHorizontalRule), diff --git a/src/client/views/pdf/PDFViewer.tsx b/src/client/views/pdf/PDFViewer.tsx index 4e5fdbfbb..56212a773 100644 --- a/src/client/views/pdf/PDFViewer.tsx +++ b/src/client/views/pdf/PDFViewer.tsx @@ -637,7 +637,7 @@ export class PDFViewer extends ViewBoxAnnotatableComponent { - if (this.active()) { + if (this.active(true)) { e.stopPropagation(); if (e.ctrlKey) { const curScale = Number(this._pdfViewer.currentScaleValue); -- cgit v1.2.3-70-g09d2 From 21284a84b6d9930b5ddfddaa600b6916613748c4 Mon Sep 17 00:00:00 2001 From: Bob Zeleznik Date: Wed, 15 Jul 2020 16:13:50 -0400 Subject: adjusted startup location of unpinned CollectionMenu --- src/client/views/collections/CollectionMenu.tsx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src/client/views/collections/CollectionMenu.tsx') diff --git a/src/client/views/collections/CollectionMenu.tsx b/src/client/views/collections/CollectionMenu.tsx index 0696b93db..cdd653823 100644 --- a/src/client/views/collections/CollectionMenu.tsx +++ b/src/client/views/collections/CollectionMenu.tsx @@ -27,6 +27,7 @@ export default class CollectionMenu extends AntimodeMenu { CollectionMenu.Instance = this; this._canFade = false; // don't let the inking menu fade away this.Pinned = Cast(Doc.UserDoc()["menuCollections-pinned"], "boolean", true); + this.jumpTo(300, 300); } @action @@ -44,7 +45,7 @@ export default class CollectionMenu extends AntimodeMenu { return this.getElement(!this.SelectedCollection ? [button] : [, - button]); + button]); } } -- cgit v1.2.3-70-g09d2 From 934fd41b249533ced87b5869c116f628f4a013b9 Mon Sep 17 00:00:00 2001 From: Bob Zeleznik Date: Fri, 17 Jul 2020 11:19:03 -0400 Subject: changed dropping menu items from collectionMenu to create fonticonbuttons if all parameters are filled in. . and buttons are placed in overlay layer. added labels to all fonticons usin title + added a tooltip field. turned off autoscroll of freeform view when dragign buttons (which will be in the overlay) --- src/client/documents/Documents.ts | 2 +- src/client/util/CurrentUserUtils.ts | 44 +++++++++++----------- src/client/util/DragManager.ts | 8 +++- src/client/views/collections/CollectionMenu.tsx | 22 +++++------ .../collectionFreeForm/CollectionFreeFormView.tsx | 4 +- src/client/views/nodes/FontIconBox.tsx | 21 ++++++----- .../views/nodes/formattedText/RichTextMenu.tsx | 4 +- src/fields/Doc.ts | 9 +++-- 8 files changed, 62 insertions(+), 52 deletions(-) (limited to 'src/client/views/collections/CollectionMenu.tsx') diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts index 5b58aa2e3..8e7d125b0 100644 --- a/src/client/documents/Documents.ts +++ b/src/client/documents/Documents.ts @@ -91,7 +91,7 @@ export interface DocumentOptions { layoutKey?: string; type?: string; title?: string; - label?: string; // short form of title for use as an icon label + toolTip?: string; // tooltip to display on hover style?: string; page?: number; description?: string; // added for links diff --git a/src/client/util/CurrentUserUtils.ts b/src/client/util/CurrentUserUtils.ts index e0cb90b46..892d0ca1d 100644 --- a/src/client/util/CurrentUserUtils.ts +++ b/src/client/util/CurrentUserUtils.ts @@ -373,7 +373,7 @@ export class CurrentUserUtils { } static creatorBtnDescriptors(doc: Doc): { - title: string, label: string, icon: string, drag?: string, ignoreClick?: boolean, + title: string, toolTip: string, icon: string, drag?: string, ignoreClick?: boolean, click?: string, ischecked?: string, activeInkPen?: Doc, backgroundColor?: string, dragFactory?: Doc }[] { if (doc.emptyPresentation === undefined) { @@ -402,27 +402,27 @@ export class CurrentUserUtils { this.setupActiveMobileMenu(doc); } return [ - { title: "Drag a collection", label: "Col", icon: "folder", click: 'openOnRight(getCopy(this.dragFactory, true))', drag: 'getCopy(this.dragFactory, true)', dragFactory: doc.emptyCollection as Doc }, - { title: "Drag a web page", label: "Web", icon: "globe-asia", click: 'openOnRight(getCopy(this.dragFactory, true))', drag: 'getCopy(this.dragFactory, true)', dragFactory: doc.emptyWebpage as Doc }, - { title: "Drag a cat image", label: "Image", icon: "cat", ignoreClick: true, drag: 'Docs.Create.ImageDocument("https://upload.wikimedia.org/wikipedia/commons/thumb/3/3a/Cat03.jpg/1200px-Cat03.jpg", { _width: 250, _nativeWidth:250, title: "an image of a cat" })' }, - { title: "Drag a comparison box", label: "Comp", icon: "columns", click: 'openOnRight(getCopy(this.dragFactory, true))', drag: 'getCopy(this.dragFactory, true)', dragFactory: doc.emptyComparison as Doc }, - { title: "Drag a screengrabber", label: "Grab", icon: "photo-video", ignoreClick: true, drag: 'Docs.Create.ScreenshotDocument("", { _width: 400, _height: 200, title: "screen snapshot" })' }, - // { title: "Drag a webcam", label: "Cam", icon: "video", ignoreClick: true, drag: 'Docs.Create.WebCamDocument("", { _width: 400, _height: 400, title: "a test cam" })' }, - { title: "Drag a audio recorder", label: "Audio", icon: "microphone", ignoreClick: true, drag: `Docs.Create.AudioDocument("${nullAudio}", { _width: 200, title: "ready to record audio" })` }, - { title: "Drag a button", label: "Button", icon: "bolt", ignoreClick: true, drag: 'Docs.Create.ButtonDocument({ _width: 150, _height: 50, _xPadding:10, _yPadding: 10, title: "Button" })' }, - { title: "Drag a presentation view", label: "Prezi", icon: "tv", click: 'openOnRight(Doc.UserDoc().activePresentation = getCopy(this.dragFactory, true))', drag: `Doc.UserDoc().activePresentation = getCopy(this.dragFactory,true)`, dragFactory: doc.emptyPresentation as Doc }, - { title: "Drag a search box", label: "Query", icon: "search", ignoreClick: true, drag: 'Docs.Create.QueryDocument({ _width: 200, title: "an image of a cat" })' }, - { title: "Drag a scripting box", label: "Script", icon: "terminal", click: 'openOnRight(getCopy(this.dragFactory, true))', drag: 'getCopy(this.dragFactory, true)', dragFactory: doc.emptyScript as Doc }, - // { title: "Drag an import folder", label: "Load", icon: "cloud-upload-alt", ignoreClick: true, drag: 'Docs.Create.DirectoryImportDocument({ title: "Directory Import", _width: 400, _height: 400 })' }, - { title: "Drag a mobile view", label: "Phone", icon: "mobile", click: 'openOnRight(Doc.UserDoc().activeMobileMenu)', drag: 'this.dragFactory', dragFactory: doc.activeMobileMenu as Doc }, - // { title: "Drag an instance of the device collection", label: "Buxton", icon: "globe-asia", ignoreClick: true, drag: 'Docs.Create.Buxton()' }, + { toolTip: "Drag a collection", title: "Col", icon: "folder", click: 'openOnRight(getCopy(this.dragFactory, true))', drag: 'getCopy(this.dragFactory, true)', dragFactory: doc.emptyCollection as Doc }, + { toolTip: "Drag a web page", title: "Web", icon: "globe-asia", click: 'openOnRight(getCopy(this.dragFactory, true))', drag: 'getCopy(this.dragFactory, true)', dragFactory: doc.emptyWebpage as Doc }, + { toolTip: "Drag a cat image", title: "Image", icon: "cat", ignoreClick: true, drag: 'Docs.Create.ImageDocument("https://upload.wikimedia.org/wikipedia/commons/thumb/3/3a/Cat03.jpg/1200px-Cat03.jpg", { _width: 250, _nativeWidth:250, title: "an image of a cat" })' }, + { toolTip: "Drag a comparison box", title: "Comp", icon: "columns", click: 'openOnRight(getCopy(this.dragFactory, true))', drag: 'getCopy(this.dragFactory, true)', dragFactory: doc.emptyComparison as Doc }, + { toolTip: "Drag a screengrabber", title: "Grab", icon: "photo-video", ignoreClick: true, drag: 'Docs.Create.ScreenshotDocument("", { _width: 400, _height: 200, title: "screen snapshot" })' }, + // { title: "Drag a webcam", title: "Cam", icon: "video", ignoreClick: true, drag: 'Docs.Create.WebCamDocument("", { _width: 400, _height: 400, title: "a test cam" })' }, + { toolTip: "Drag a audio recorder", title: "Audio", icon: "microphone", ignoreClick: true, drag: `Docs.Create.AudioDocument("${nullAudio}", { _width: 200, title: "ready to record audio" })` }, + { toolTip: "Drag a button", title: "Button", icon: "bolt", ignoreClick: true, drag: 'Docs.Create.ButtonDocument({ _width: 150, _height: 50, _xPadding:10, _yPadding: 10, title: "Button" })' }, + { toolTip: "Drag a presentation view", title: "Prezi", icon: "tv", click: 'openOnRight(Doc.UserDoc().activePresentation = getCopy(this.dragFactory, true))', drag: `Doc.UserDoc().activePresentation = getCopy(this.dragFactory,true)`, dragFactory: doc.emptyPresentation as Doc }, + { toolTip: "Drag a search box", title: "Query", icon: "search", ignoreClick: true, drag: 'Docs.Create.QueryDocument({ _width: 200, title: "an image of a cat" })' }, + { toolTip: "Drag a scripting box", title: "Script", icon: "terminal", click: 'openOnRight(getCopy(this.dragFactory, true))', drag: 'getCopy(this.dragFactory, true)', dragFactory: doc.emptyScript as Doc }, + // { title: "Drag an import folder", title: "Load", icon: "cloud-upload-alt", ignoreClick: true, drag: 'Docs.Create.DirectoryImportDocument({ title: "Directory Import", _width: 400, _height: 400 })' }, + { toolTip: "Drag a mobile view", title: "Phone", icon: "mobile", click: 'openOnRight(Doc.UserDoc().activeMobileMenu)', drag: 'this.dragFactory', dragFactory: doc.activeMobileMenu as Doc }, + // { title: "Drag an instance of the device collection", title: "Buxton", icon: "globe-asia", ignoreClick: true, drag: 'Docs.Create.Buxton()' }, // { title: "use pen", icon: "pen-nib", click: 'activatePen(this.activeInkPen = sameDocs(this.activeInkPen, this) ? undefined : this)', backgroundColor: "blue", ischecked: `sameDocs(this.activeInkPen, this)`, activeInkPen: doc }, // { title: "use highlighter", icon: "highlighter", click: 'activateBrush(this.activeInkPen = sameDocs(this.activeInkPen, this) ? undefined : this,20,this.backgroundColor)', backgroundColor: "yellow", ischecked: `sameDocs(this.activeInkPen, this)`, activeInkPen: doc }, // { title: "use stamp", icon: "stamp", click: 'activateStamp(this.activeInkPen = sameDocs(this.activeInkPen, this) ? undefined : this)', backgroundColor: "orange", ischecked: `sameDocs(this.activeInkPen, this)`, activeInkPen: doc }, // { title: "use eraser", icon: "eraser", click: 'activateEraser(this.activeInkPen = sameDocs(this.activeInkPen, this) ? undefined : this);', ischecked: `sameDocs(this.activeInkPen, this)`, backgroundColor: "pink", activeInkPen: doc }, // { title: "use drag", icon: "mouse-pointer", click: 'deactivateInk();this.activeInkPen = this;', ischecked: `sameDocs(this.activeInkPen, this)`, backgroundColor: "white", activeInkPen: doc }, - { title: "Drag a document previewer", label: "Prev", icon: "expand", click: 'openOnRight(getCopy(this.dragFactory, true))', drag: 'getCopy(this.dragFactory,true)', dragFactory: doc.emptyDocHolder as Doc }, - { title: "Toggle a Calculator REPL", label: "repl", icon: "calculator", click: 'addOverlayWindow("ScriptingRepl", { x: 300, y: 100, width: 200, height: 200, title: "Scripting REPL" })' }, + { toolTip: "Drag a document previewer", title: "Prev", icon: "expand", click: 'openOnRight(getCopy(this.dragFactory, true))', drag: 'getCopy(this.dragFactory,true)', dragFactory: doc.emptyDocHolder as Doc }, + { toolTip: "Toggle a Calculator REPL", title: "repl", icon: "calculator", click: 'addOverlayWindow("ScriptingRepl", { x: 300, y: 100, width: 200, height: 200, title: "Scripting REPL" })' }, ]; } @@ -439,11 +439,11 @@ export class CurrentUserUtils { } } const buttons = CurrentUserUtils.creatorBtnDescriptors(doc).filter(d => !alreadyCreatedButtons?.includes(d.title)); - const creatorBtns = buttons.map(({ title, label, icon, ignoreClick, drag, click, ischecked, activeInkPen, backgroundColor, dragFactory }) => Docs.Create.FontIconDocument({ + const creatorBtns = buttons.map(({ title, toolTip, icon, ignoreClick, drag, click, ischecked, activeInkPen, backgroundColor, dragFactory }) => Docs.Create.FontIconDocument({ _nativeWidth: 100, _nativeHeight: 100, _width: 100, _height: 100, icon, title, - label, + toolTip, ignoreClick, dropAction: "copy", onDragStart: drag ? ScriptField.MakeFunction(drag) : undefined, @@ -735,14 +735,14 @@ export class CurrentUserUtils { if (doc["dockedBtn-pen"] === undefined) { doc["dockedBtn-pen"] = CurrentUserUtils.ficon({ onClick: ScriptField.MakeScript("activatePen(this.activeInkPen = sameDocs(this.activeInkPen, this) ? undefined : this)"), - author: "systemTemplates", title: "ink mode", icon: "pen-nib", ischecked: ComputedField.MakeFunction(`sameDocs(this.activeInkPen, this)`), activeInkPen: doc + author: "systemTemplates", toolTip: "open drawing tools", title: "draw", icon: "pen-nib", ischecked: ComputedField.MakeFunction(`sameDocs(this.activeInkPen, this)`), activeInkPen: doc }); } if (doc["dockedBtn-undo"] === undefined) { - doc["dockedBtn-undo"] = CurrentUserUtils.ficon({ onClick: ScriptField.MakeScript("undo()"), title: "undo button", icon: "undo-alt" }); + doc["dockedBtn-undo"] = CurrentUserUtils.ficon({ onClick: ScriptField.MakeScript("undo()"), toolTip: "click to undo", title: "undo", icon: "undo-alt" }); } if (doc["dockedBtn-redo"] === undefined) { - doc["dockedBtn-redo"] = CurrentUserUtils.ficon({ onClick: ScriptField.MakeScript("redo()"), title: "redo button", icon: "redo-alt" }); + doc["dockedBtn-redo"] = CurrentUserUtils.ficon({ onClick: ScriptField.MakeScript("redo()"), toolTip: "click to redo", title: "redo", icon: "redo-alt" }); } if (doc.dockedBtns === undefined) { doc.dockedBtns = CurrentUserUtils.blist({ title: "docked buttons", ignoreClick: true }, [doc["dockedBtn-undo"] as Doc, doc["dockedBtn-redo"] as Doc, doc["dockedBtn-pen"] as Doc]); diff --git a/src/client/util/DragManager.ts b/src/client/util/DragManager.ts index 5f34509a1..6a3108157 100644 --- a/src/client/util/DragManager.ts +++ b/src/client/util/DragManager.ts @@ -83,6 +83,7 @@ export namespace DragManager { hideSource?: boolean; // hide source document during drag offsetX?: number; // offset of top left of source drag visual from cursor offsetY?: number; + noAutoscroll?: boolean; } // event called when the drag operation results in a drop action @@ -225,13 +226,16 @@ export namespace DragManager { // drag a button template and drop a new button export function StartButtonDrag(eles: HTMLElement[], script: string, title: string, vars: { [name: string]: Field }, params: string[], initialize: (button: Doc) => void, downX: number, downY: number, options?: DragOptions) { const finishDrag = (e: DragCompleteEvent) => { - const bd = Docs.Create.ButtonDocument({ _width: 150, _height: 50, title, onClick: ScriptField.MakeScript(script) }); + const bd = params.length > Object.keys(vars).length ? + Docs.Create.ButtonDocument({ toolTip: title, z: 1, _width: 150, _height: 50, title, onClick: ScriptField.MakeScript(script) }) : + Docs.Create.FontIconDocument({ toolTip: title, z: 1, _nativeWidth: 30, _nativeHeight: 30, _width: 30, _height: 30, title, onClick: ScriptField.MakeScript(script) }); params.map(p => Object.keys(vars).indexOf(p) !== -1 && (Doc.GetProto(bd)[p] = new PrefetchProxy(vars[p] as Doc))); // copy all "captured" arguments into document parameterfields initialize?.(bd); Doc.GetProto(bd)["onClick-paramFieldKeys"] = new List(params); e.docDragData && (e.docDragData.droppedDocuments = [bd]); return e; }; + options && (options.noAutoscroll = true); StartDrag(eles, new DragManager.DocumentDragData([]), downX, downY, options, finishDrag); } @@ -431,7 +435,7 @@ export namespace DragManager { const complete = new DragCompleteEvent(false, dragData); - if (target) { + if (target && !options?.noAutoscroll) { target.dispatchEvent( new CustomEvent("dashDragging", { bubbles: true, diff --git a/src/client/views/collections/CollectionMenu.tsx b/src/client/views/collections/CollectionMenu.tsx index cdd653823..84e5d56cb 100644 --- a/src/client/views/collections/CollectionMenu.tsx +++ b/src/client/views/collections/CollectionMenu.tsx @@ -62,37 +62,37 @@ export class CollectionViewBaseChrome extends React.Component item view", - script: "this.target.childLayout = getDocTemplate(this.source?.[0])", - immediate: undoBatch((source: Doc[]) => source.length && (this.target.childLayout = Doc.getDocTemplate(source?.[0]))), + params: ["target", "source"], title: "item view", + script: "this.target.childLayoutTemplate = getDocTemplate(this.source?.[0])", + immediate: undoBatch((source: Doc[]) => source.length && (this.target.childLayoutTemplate = Doc.getDocTemplate(source?.[0]))), initialize: emptyFunction, }; _narrativeCommand = { - params: ["target", "source"], title: "=> child click view", + params: ["target", "source"], title: "child click view", script: "this.target.childClickedOpenTemplateView = getDocTemplate(this.source?.[0])", immediate: undoBatch((source: Doc[]) => source.length && (this.target.childClickedOpenTemplateView = Doc.getDocTemplate(source?.[0]))), initialize: emptyFunction, }; _contentCommand = { - params: ["target", "source"], title: "=> clear content", + params: ["target", "source"], title: "clear content", script: "getProto(this.target).data = copyField(this.source);", immediate: undoBatch((source: Doc[]) => Doc.GetProto(this.target).data = new List(source)), // Doc.aliasDocs(source), initialize: emptyFunction, }; _viewCommand = { - params: ["target"], title: "=> reset view", - script: "this.target._panX = this.restoredPanX; this.target._panY = this.restoredPanY; this.target.scale = this.restoredScale;", - immediate: undoBatch((source: Doc[]) => { this.target._panX = 0; this.target._panY = 0; this.target.scale = 1; }), - initialize: (button: Doc) => { button.restoredPanX = this.target._panX; button.restoredPanY = this.target._panY; button.restoredScale = this.target.scale; }, + params: ["target"], title: "bookmark view", + script: "this.target._panX = this['target-panX']; this.target._panY = this['target-panY']; this.target._viewScale = this['target-viewScale'];", + immediate: undoBatch((source: Doc[]) => { this.target._panX = 0; this.target._panY = 0; this.target._viewScale = 1; }), + initialize: (button: Doc) => { button['target-panX'] = this.target._panX; button['target-panY'] = this.target._panY; button['target-viewScale'] = this.target._viewScale; }, }; _clusterCommand = { - params: ["target"], title: "=> fit content", + params: ["target"], title: "fit content", script: "this.target._fitToBox = !this.target._fitToBox;", immediate: undoBatch((source: Doc[]) => this.target._fitToBox = !this.target._fitToBox), initialize: emptyFunction }; _fitContentCommand = { - params: ["target"], title: "=> toggle clusters", + params: ["target"], title: "toggle clusters", script: "this.target.useClusters = !this.target.useClusters;", immediate: undoBatch((source: Doc[]) => this.target.useClusters = !this.target.useClusters), initialize: emptyFunction diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx index 922cb17fe..e119910bd 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx @@ -953,8 +953,8 @@ export class CollectionFreeFormView extends CollectionSubView( render() { const referenceDoc = (this.layoutDoc.dragFactory instanceof Doc ? this.layoutDoc.dragFactory : this.layoutDoc); const refLayout = Doc.Layout(referenceDoc); - return ; + return {StrCast(this.layoutDoc.toolTip)}
}> + + ; } } \ 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 9890ef2c1..3c7c58126 100644 --- a/src/client/views/nodes/formattedText/RichTextMenu.tsx +++ b/src/client/views/nodes/formattedText/RichTextMenu.tsx @@ -319,7 +319,7 @@ export default class RichTextMenu extends AntimodeMenu { } destroy() { - !this.TextView.props.isSelected(false) && this.fadeOut(true); + !this.TextView?.props.isSelected(false) && this.fadeOut(true); } @action @@ -657,7 +657,7 @@ export default class RichTextMenu extends AntimodeMenu { @action toggleColorDropdown() { this.showColorDropdown = !this.showColorDropdown; } @action setActiveColor(color: string) { this.activeFontColor = color; } - get TextView() { return (this.view as any).TextView as FormattedTextBox; } + get TextView() { return (this.view as any)?.TextView as FormattedTextBox; } createColorButton() { const self = this; diff --git a/src/fields/Doc.ts b/src/fields/Doc.ts index 7aa1d528d..3ad9f4e41 100644 --- a/src/fields/Doc.ts +++ b/src/fields/Doc.ts @@ -899,9 +899,12 @@ export namespace Doc { } export function getDocTemplate(doc?: Doc) { - return doc?.isTemplateDoc ? doc : - Cast(doc?.dragFactory, Doc, null)?.isTemplateDoc ? doc?.dragFactory : - Cast(doc?.layout, Doc, null)?.isTemplateDoc ? doc?.layout : undefined; + return !doc ? undefined : + doc.isTemplateDoc ? doc : + Cast(doc.dragFactory, Doc, null)?.isTemplateDoc ? doc.dragFactory : + Cast(Doc.Layout(doc), Doc, null)?.isTemplateDoc ? + (Cast(Doc.Layout(doc), Doc, null).resolvedDataDoc ? Doc.Layout(doc).proto : Doc.Layout(doc)) : + undefined; } export function matchFieldValue(doc: Doc, key: string, value: any): boolean { -- cgit v1.2.3-70-g09d2 From 635bfbc9e79965f94eb925221e58445ecddb39d8 Mon Sep 17 00:00:00 2001 From: Bob Zeleznik Date: Fri, 17 Jul 2020 14:40:01 -0400 Subject: fixes for collectionMenu button sizes. --- src/client/views/collections/CollectionMenu.scss | 20 ++++++++++++-------- src/client/views/collections/CollectionMenu.tsx | 20 ++++++++++---------- 2 files changed, 22 insertions(+), 18 deletions(-) (limited to 'src/client/views/collections/CollectionMenu.tsx') diff --git a/src/client/views/collections/CollectionMenu.scss b/src/client/views/collections/CollectionMenu.scss index 348b9e6ea..0da78df9f 100644 --- a/src/client/views/collections/CollectionMenu.scss +++ b/src/client/views/collections/CollectionMenu.scss @@ -16,7 +16,7 @@ .antimodeMenu-button { padding:0; - width:40px; + width:30px; display: flex; svg { margin:auto; @@ -37,13 +37,11 @@ .collectionViewBaseChrome-viewPicker { font-size: 75%; - //text-transform: uppercase; - //letter-spacing: 2px; background: #121721; - color: white; outline-color: black; + color: white; border: none; - //padding: 12px 10px 11px 10px; + border-right: solid gray 1px; } .collectionViewBaseChrome-viewPicker:active { @@ -67,8 +65,9 @@ margin-right: 0px; font-size: 75%; background: #121721; - border: none; color: white; + border: none; + border-right: solid gray 1px; } .commandEntry-outerDiv { @@ -89,7 +88,7 @@ .collectionViewBaseChrome-collapse { transition: all .5s, opacity 0.3s; position: absolute; - width: 40px; + width: 30px; transform-origin: top left; pointer-events: all; // margin-top: 10px; @@ -112,6 +111,8 @@ .collectionViewBaseChrome-viewSpecs { margin-left: 5px; display: grid; + border: none; + border-right: solid gray 1px; .collectionViewBaseChrome-filterIcon { position: relative; @@ -123,6 +124,8 @@ height: 30px; align-items: center; justify-content: center; + border: none; + border-right: solid gray 1px; } .collectionViewBaseChrome-viewSpecsInput { @@ -201,8 +204,9 @@ background: #121721; color: white; outline-color: black; + color: white; border: none; - //padding: 12px 10px 11px 10px; + border-right: solid gray 1px; } .collectionGridViewChrome-viewPicker:active { diff --git a/src/client/views/collections/CollectionMenu.tsx b/src/client/views/collections/CollectionMenu.tsx index 84e5d56cb..f3ad21949 100644 --- a/src/client/views/collections/CollectionMenu.tsx +++ b/src/client/views/collections/CollectionMenu.tsx @@ -211,9 +211,9 @@ export class CollectionViewBaseChrome extends React.Component
-
- -
+
{this.viewModes} + {this.templateChrome}
-
- -
+
- {this.templateChrome}
{this.subChrome}
-- cgit v1.2.3-70-g09d2 From 2df5e1fb9c249ab29c0d8fc56d0a2ce394ae6643 Mon Sep 17 00:00:00 2001 From: Bob Zeleznik Date: Fri, 17 Jul 2020 17:10:43 -0400 Subject: got rid of InkOptionsMenu. Merged into CollectionFreeFormViewChrome. --- src/client/util/CurrentUserUtils.ts | 8 +- src/client/views/GestureOverlay.tsx | 10 +- src/client/views/GlobalKeyHandler.ts | 2 + src/client/views/MainView.tsx | 6 +- src/client/views/collections/CollectionMenu.scss | 61 +++++-- src/client/views/collections/CollectionMenu.tsx | 161 ++++++++++++++++- .../collectionFreeForm/InkOptionsMenu.scss | 83 --------- .../collectionFreeForm/InkOptionsMenu.tsx | 194 --------------------- src/mobile/MobileInterface.tsx | 4 +- 9 files changed, 213 insertions(+), 316 deletions(-) delete mode 100644 src/client/views/collections/collectionFreeForm/InkOptionsMenu.scss delete mode 100644 src/client/views/collections/collectionFreeForm/InkOptionsMenu.tsx (limited to 'src/client/views/collections/CollectionMenu.tsx') diff --git a/src/client/util/CurrentUserUtils.ts b/src/client/util/CurrentUserUtils.ts index 892d0ca1d..58d3848a3 100644 --- a/src/client/util/CurrentUserUtils.ts +++ b/src/client/util/CurrentUserUtils.ts @@ -732,12 +732,6 @@ 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-pen"] === undefined) { - doc["dockedBtn-pen"] = CurrentUserUtils.ficon({ - onClick: ScriptField.MakeScript("activatePen(this.activeInkPen = sameDocs(this.activeInkPen, this) ? undefined : this)"), - author: "systemTemplates", toolTip: "open drawing tools", title: "draw", icon: "pen-nib", ischecked: ComputedField.MakeFunction(`sameDocs(this.activeInkPen, this)`), activeInkPen: doc - }); - } if (doc["dockedBtn-undo"] === undefined) { doc["dockedBtn-undo"] = CurrentUserUtils.ficon({ onClick: ScriptField.MakeScript("undo()"), toolTip: "click to undo", title: "undo", icon: "undo-alt" }); } @@ -745,7 +739,7 @@ export class CurrentUserUtils { doc["dockedBtn-redo"] = CurrentUserUtils.ficon({ onClick: ScriptField.MakeScript("redo()"), toolTip: "click to redo", title: "redo", icon: "redo-alt" }); } if (doc.dockedBtns === undefined) { - doc.dockedBtns = CurrentUserUtils.blist({ title: "docked buttons", ignoreClick: true }, [doc["dockedBtn-undo"] as Doc, doc["dockedBtn-redo"] as Doc, doc["dockedBtn-pen"] as Doc]); + doc.dockedBtns = CurrentUserUtils.blist({ title: "docked buttons", ignoreClick: true }, [doc["dockedBtn-undo"] as Doc, doc["dockedBtn-redo"] as Doc]); } } // sets up the default set of documents to be shown in the Overlay layer diff --git a/src/client/views/GestureOverlay.tsx b/src/client/views/GestureOverlay.tsx index 2f34cbc05..b0b0d72b1 100644 --- a/src/client/views/GestureOverlay.tsx +++ b/src/client/views/GestureOverlay.tsx @@ -22,7 +22,7 @@ import { RadialMenu } from "./nodes/RadialMenu"; import HorizontalPalette from "./Palette"; import { Touchable } from "./Touchable"; import TouchScrollableMenu, { TouchScrollableMenuItem } from "./TouchScrollableMenu"; -import InkOptionsMenu from "./collections/collectionFreeForm/InkOptionsMenu"; +import { CollectionFreeFormViewChrome } from "./collections/CollectionMenu"; @observer export default class GestureOverlay extends Touchable { @@ -603,12 +603,12 @@ export default class GestureOverlay extends Touchable { break; } } - //if any of the shape is activated in the InkOptionsMenu + //if any of the shape is activated in the CollectionFreeFormViewChrome else if (this.InkShape) { this.makePolygon(this.InkShape, false); this.dispatchGesture(GestureUtils.Gestures.Stroke); this._points = []; - if (!InkOptionsMenu.Instance._keepMode) { + if (!CollectionFreeFormViewChrome.Instance._keepMode) { this.InkShape = ""; } } @@ -639,9 +639,9 @@ export default class GestureOverlay extends Touchable { this._points = []; } //get out of ink mode after each stroke= - if (!InkOptionsMenu.Instance._keepMode) { + if (!CollectionFreeFormViewChrome.Instance._keepMode) { Doc.SetSelectedTool(InkTool.None); - InkOptionsMenu.Instance._selected = InkOptionsMenu.Instance._shapesNum; + CollectionFreeFormViewChrome.Instance._selected = CollectionFreeFormViewChrome.Instance._shapesNum; SetActiveArrowStart("none"); GestureOverlay.Instance.SavedArrowStart = ActiveArrowStart(); SetActiveArrowEnd("none"); diff --git a/src/client/views/GlobalKeyHandler.ts b/src/client/views/GlobalKeyHandler.ts index a3a023164..8c233489e 100644 --- a/src/client/views/GlobalKeyHandler.ts +++ b/src/client/views/GlobalKeyHandler.ts @@ -22,6 +22,7 @@ import { DocumentView } from "./nodes/DocumentView"; import { DocumentLinksButton } from "./nodes/DocumentLinksButton"; import PDFMenu from "./pdf/PDFMenu"; import { ContextMenu } from "./ContextMenu"; +import { CollectionFreeFormViewChrome } from "./collections/CollectionMenu"; const modifiers = ["control", "meta", "shift", "alt"]; type KeyHandler = (keycode: string, e: KeyboardEvent) => KeyControlInfo | Promise; @@ -107,6 +108,7 @@ export default class KeyManager { GoogleAuthenticationManager.Instance.cancel(); HypothesisAuthenticationManager.Instance.cancel(); SharingManager.Instance.close(); + CollectionFreeFormViewChrome.Instance.clearKeep(); break; case "delete": case "backspace": diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx index e50ff342c..46eeac77a 100644 --- a/src/client/views/MainView.tsx +++ b/src/client/views/MainView.tsx @@ -38,7 +38,6 @@ import SharingManager from '../util/SharingManager'; import { Transform } from '../util/Transform'; import { CollectionDockingView } from './collections/CollectionDockingView'; import MarqueeOptionsMenu from './collections/collectionFreeForm/MarqueeOptionsMenu'; -import InkOptionsMenu from './collections/collectionFreeForm/InkOptionsMenu'; import { CollectionLinearView } from './collections/CollectionLinearView'; import { CollectionView, CollectionViewType } from './collections/CollectionView'; import { ContextMenu } from './ContextMenu'; @@ -392,7 +391,7 @@ export class MainView extends React.Component { doc.dockingConfig ? this.openWorkspace(doc) : CollectionDockingView.AddRightSplit(doc, libraryPath); } - sidebarScreenToLocal = () => new Transform(0, (RichTextMenu.Instance.Pinned ? -35 : 0) + (InkOptionsMenu.Instance.Pinned ? -35 : 0) + (CollectionMenu.Instance.Pinned ? -35 : 0), 1); + sidebarScreenToLocal = () => new Transform(0, (RichTextMenu.Instance.Pinned ? -35 : 0) + (CollectionMenu.Instance.Pinned ? -35 : 0), 1); mainContainerXf = () => this.sidebarScreenToLocal().translate(0, -this._buttonBarHeight); @computed get flyout() { @@ -469,7 +468,7 @@ export class MainView extends React.Component { @computed get mainContent() { const sidebar = this.userDoc?.["tabs-panelContainer"]; - const n = (RichTextMenu.Instance?.Pinned ? 1 : 0) + (InkOptionsMenu.Instance?.Pinned ? 1 : 0) + (CollectionMenu.Instance?.Pinned ? 1 : 0); + const n = (RichTextMenu.Instance?.Pinned ? 1 : 0) + (CollectionMenu.Instance?.Pinned ? 1 : 0); const height = `calc(100% - ${n * Number(ANTIMODEMENU_HEIGHT.replace("px", ""))}px)`; return !this.userDoc || !(sidebar instanceof Doc) ? (null) : (
- {LinkDescriptionPopup.descriptionPopup ? : null} diff --git a/src/client/views/collections/CollectionMenu.scss b/src/client/views/collections/CollectionMenu.scss index 0da78df9f..9da204787 100644 --- a/src/client/views/collections/CollectionMenu.scss +++ b/src/client/views/collections/CollectionMenu.scss @@ -8,15 +8,15 @@ opacity: 0.9; z-index: 9001; transition: top .5s; - background: #121721; + background: #323232; color: white; transform-origin: top left; top: 0; width:100%; .antimodeMenu-button { - padding:0; - width:30px; + padding: 0; + width: 30px; display: flex; svg { margin:auto; @@ -37,7 +37,7 @@ .collectionViewBaseChrome-viewPicker { font-size: 75%; - background: #121721; + background: #323232; outline-color: black; color: white; border: none; @@ -64,7 +64,7 @@ margin-left: 3px; margin-right: 0px; font-size: 75%; - background: #121721; + background: #323232; color: white; border: none; border-right: solid gray 1px; @@ -72,7 +72,7 @@ .commandEntry-outerDiv { pointer-events: all; - background-color: #121721; + background-color: #323232; display: flex; flex-direction: row; height: 30px; @@ -118,7 +118,7 @@ position: relative; display: flex; margin: auto; - background: #121721; + background: #323232; color: white; width: 30px; height: 30px; @@ -310,28 +310,54 @@ } .collectionFreeFormMenu-cont { - width: 60px; - display: flex; + display: inline-flex; position: relative; align-items: center; + .antimodeMenu-button { + text-align: center; + display: block; + } + .color-previewI { + width: 80%; + height: 20%; + bottom: 0; + position: absolute; + } + .color-previewII { + width: 80%; + height: 80%; + margin-left: 10%; + } + + .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: absolute; + position: relative; width: 20; height: 30; bottom: 0; - background: #121721; - display: flex; + background: #323232; + display: inline-flex; align-items: center; color: white; } .backKeyframe { - left: 0; - svg { display: block; margin: auto; @@ -339,19 +365,16 @@ } .numKeyframe { - left: 20; - display: flex; flex-direction: column; - padding: 5px; + padding-top: 5px; } .fwdKeyframe { - left: 40; - svg { display: block; margin: auto; } + border-right: solid gray 1px; } } diff --git a/src/client/views/collections/CollectionMenu.tsx b/src/client/views/collections/CollectionMenu.tsx index f3ad21949..2be57b6d2 100644 --- a/src/client/views/collections/CollectionMenu.tsx +++ b/src/client/views/collections/CollectionMenu.tsx @@ -1,5 +1,5 @@ import React = require("react"); -import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; +import { FontAwesomeIcon, FontAwesomeIconProps } from "@fortawesome/react-fontawesome"; import { action, computed, observable, reaction, runInAction, Lambda } from "mobx"; import { observer } from "mobx-react"; import { Doc, DocListCast, Opt } from "../../../fields/Doc"; @@ -15,6 +15,15 @@ import { List } from "../../../fields/List"; import { EditableView } from "../EditableView"; import { Id } from "../../../fields/FieldSymbols"; import { listSpec } from "../../../fields/Schema"; +import FormatShapePane from "./collectionFreeForm/FormatShapePane"; +import { ActiveFillColor, SetActiveInkWidth, ActiveInkColor, SetActiveBezierApprox, SetActiveArrowEnd, SetActiveArrowStart, SetActiveFillColor, SetActiveInkColor } from "../InkingStroke"; +import GestureOverlay from "../GestureOverlay"; +import { InkTool } from "../../../fields/InkField"; +import { DocumentType } from "../../documents/DocumentTypes"; +import { Document } from "../../../fields/documentSchemas"; +import { SelectionManager } from "../../util/SelectionManager"; +import { DocumentView } from "../nodes/DocumentView"; +import { ColorState } from "react-color"; @observer export default class CollectionMenu extends AntimodeMenu { @@ -272,7 +281,11 @@ export class CollectionViewBaseChrome extends React.Component { - + public static Instance: CollectionFreeFormViewChrome; + constructor(props: any) { + super(props); + CollectionFreeFormViewChrome.Instance = this; + } get Document() { return this.props.CollectionView.props.Document; } @computed get dataField() { return this.props.CollectionView.props.Document[Doc.LayoutFieldKey(this.props.CollectionView.props.Document)]; @@ -303,6 +316,144 @@ export class CollectionFreeFormViewChrome extends React.Component { + const col: ColorState = { + hex: color, hsl: { a: 0, h: 0, s: 0, l: 0, source: "" }, hsv: { a: 0, h: 0, s: 0, v: 0, source: "" }, + rgb: { a: 0, r: 0, b: 0, g: 0, source: "" }, oldHue: 0, source: "", + }; + if (type === "color") { + SetActiveInkColor(Utils.colorString(col)); + } else if (type === "fill") { + SetActiveFillColor(Utils.colorString(col)); + } + } + + @action + editProperties = (value: any, field: string) => { + SelectionManager.SelectedDocuments().forEach(action((element: DocumentView) => { + const doc = Document(element.rootDoc); + if (doc.type === DocumentType.INK) { + switch (field) { + case "width": doc.strokeWidth = Number(value); break; + case "color": doc.color = String(value); break; + case "fill": doc.fillColor = String(value); break; + case "dash": doc.strokeDash = value; + } + } + })); + } + + @computed get drawButtons() { + const func = action((i: number, keep: boolean) => { + this._keepMode = keep; + if (this._selected !== i) { + this._selected = i; + Doc.SetSelectedTool(InkTool.Pen); + SetActiveArrowStart(this._head[i]); + SetActiveArrowEnd(this._end[i]); + SetActiveBezierApprox("300"); + + GestureOverlay.Instance.InkShape = this._shape[i]; + } else { + this._selected = this._shapesNum; + Doc.SetSelectedTool(InkTool.None); + SetActiveArrowStart(""); + SetActiveArrowEnd(""); + GestureOverlay.Instance.InkShape = ""; + SetActiveBezierApprox("0"); + } + }); + return
+ {this._draw.map((icon, i) => + )} +
; + } + + toggleButton = (key: string, value: boolean, setter: () => {}, icon: FontAwesomeIconProps["icon"], ele: JSX.Element | null) => { + return ; + } + + @computed get widthPicker() { + var widthPicker = this.toggleButton("stroke width", this._widthBtn, () => this._widthBtn = !this._widthBtn, "bars", null); + return !this._widthBtn ? widthPicker : +
+ {widthPicker} + {this._width.map(wid => + )} +
; + } + + @computed get colorPicker() { + var colorPicker = this.toggleButton("stroke color", this._colorBtn, () => this._colorBtn = !this._colorBtn, "pen-nib", +
); + return !this._colorBtn ? colorPicker : +
+ {colorPicker} + {this._palette.map(color => + )} +
; + } + @computed get fillPicker() { + var fillPicker = this.toggleButton("shape fill color", this._fillBtn, () => this._fillBtn = !this._fillBtn, "fill-drip", +
); + return !this._fillBtn ? fillPicker : +
+ {fillPicker} + {this._palette.map(color => + )} + +
; + } + + @computed get formatPane() { + return ; + } + render() { return this.Document.isAnnotationOverlay ? (null) :
@@ -316,6 +467,12 @@ export class CollectionFreeFormViewChrome extends React.Component
+ + {this.widthPicker} + {this.colorPicker} + {this.fillPicker} + {this.drawButtons} + {this.formatPane}
; } } diff --git a/src/client/views/collections/collectionFreeForm/InkOptionsMenu.scss b/src/client/views/collections/collectionFreeForm/InkOptionsMenu.scss deleted file mode 100644 index 03c6c97ab..000000000 --- a/src/client/views/collections/collectionFreeForm/InkOptionsMenu.scss +++ /dev/null @@ -1,83 +0,0 @@ -.antimodeMenu-button { - .color-previewI { - width: 100%; - height: 40%; - } - - .color-previewII { - width: 100%; - height: 100%; - } - -} - -.sketch-picker { - background: #323232; - - .flexbox-fit { - background: #323232; - } -} - -.btn-group { - display: grid; - grid-template-columns: auto auto auto auto; - /* Make the buttons appear below each other */ -} - -.btn-draw { - display: inline; - /* Make the buttons appear below each other */ -} - -.btn2-group { - display: grid; - background: #323232; - grid-template-columns: auto; - - /* Make the buttons appear below each other */ - .antimodeMenu-button { - background: #323232; - display: block; - - } -} - -@media only screen and (max-device-width: 480px) { - .antimodeMenu-button { - font-size: 50%; - - .color-preview { - width: 100%; - height: 100%; - } - - } - - .sketch-picker { - background: #323232; - - .flexbox-fit { - background: #323232; - } - } - - .btn-group { - display: grid; - grid-template-columns: auto auto; - /* Make the buttons appear below each other */ - } - - .btn2-group { - display: block; - background: #323232; - grid-template-columns: auto; - - /* Make the buttons appear below each other */ - .antimodeMenu-button { - background: #323232; - display: block; - font-size: 50%; - } - } -} \ No newline at end of file diff --git a/src/client/views/collections/collectionFreeForm/InkOptionsMenu.tsx b/src/client/views/collections/collectionFreeForm/InkOptionsMenu.tsx deleted file mode 100644 index 23e1c194a..000000000 --- a/src/client/views/collections/collectionFreeForm/InkOptionsMenu.tsx +++ /dev/null @@ -1,194 +0,0 @@ -import React = require("react"); -import AntimodeMenu from "../../AntimodeMenu"; -import { observer } from "mobx-react"; -import { observable, action, computed } from "mobx"; -import "./InkOptionsMenu.scss"; -import { ActiveInkColor, ActiveFillColor, SetActiveInkWidth, SetActiveInkColor, SetActiveBezierApprox, SetActiveFillColor, SetActiveArrowStart, SetActiveArrowEnd, ActiveDash, SetActiveDash } from "../../InkingStroke"; -import { Scripting } from "../../../util/Scripting"; -import { InkTool } from "../../../../fields/InkField"; -import { ColorState } from "react-color"; -import { Utils } from "../../../../Utils"; -import GestureOverlay from "../../GestureOverlay"; -import { Doc } from "../../../../fields/Doc"; -import { SelectionManager } from "../../../util/SelectionManager"; -import { DocumentView } from "../../../views/nodes/DocumentView"; -import { Document } from "../../../../fields/documentSchemas"; -import { DocumentType } from "../../../documents/DocumentTypes"; -import { FontAwesomeIcon, FontAwesomeIconProps } from "@fortawesome/react-fontawesome"; -import { BoolCast } from "../../../../fields/Types"; -import FormatShapePane from "./FormatShapePane"; - -@observer -export default class InkOptionsMenu extends AntimodeMenu { - static Instance: InkOptionsMenu; - - private _palette = ["#D0021B", "#F5A623", "#F8E71C", "#8B572A", "#7ED321", "#417505", "#9013FE", "#4A90E2", "#50E3C2", "#B8E986", "#000000", "#4A4A4A", "#9B9B9B", "#FFFFFF", ""]; - private _width = ["1", "5", "10", "100"]; - private _draw = ["⎯", "→", "↔︎", "∿", "↝", "↭", "ロ", "O", "∆"]; - private _head = ["", "", "arrow", "", "", "arrow", "", "", ""]; - private _end = ["", "arrow", "arrow", "", "arrow", "arrow", "", "", ""]; - private _shape = ["line", "line", "line", "", "", "", "rectangle", "circle", "triangle"]; - - @observable _shapesNum = this._shape.length; - @observable _selected = this._shapesNum; - - @observable _collapsed = false; - @observable _keepMode = false; - - @observable _colorBtn = false; - @observable _widthBtn = false; - @observable _fillBtn = false; - - constructor(props: Readonly<{}>) { - super(props); - InkOptionsMenu.Instance = this; - this._canFade = false; // don't let the inking menu fade away - this.Pinned = BoolCast(Doc.UserDoc()["menuInkOptions-pinned"]); - } - - @action - toggleMenuPin = (e: React.MouseEvent) => { - Doc.UserDoc()["menuInkOptions-pinned"] = this.Pinned = !this.Pinned; - } - - @action - changeColor = (color: string, type: string) => { - const col: ColorState = { - hex: color, hsl: { a: 0, h: 0, s: 0, l: 0, source: "" }, hsv: { a: 0, h: 0, s: 0, v: 0, source: "" }, - rgb: { a: 0, r: 0, b: 0, g: 0, source: "" }, oldHue: 0, source: "", - }; - if (type === "color") { - SetActiveInkColor(Utils.colorString(col)); - } else if (type === "fill") { - SetActiveFillColor(Utils.colorString(col)); - } - } - - @action - editProperties = (value: any, field: string) => { - SelectionManager.SelectedDocuments().forEach(action((element: DocumentView) => { - const doc = Document(element.rootDoc); - if (doc.type === DocumentType.INK) { - switch (field) { - case "width": doc.strokeWidth = Number(value); break; - case "color": doc.color = String(value); break; - case "fill": doc.fillColor = String(value); break; - case "dash": doc.strokeDash = value; - } - } - })); - } - - @computed get drawButtons() { - const func = action((i: number, keep: boolean) => { - this._keepMode = keep; - if (this._selected !== i) { - this._selected = i; - Doc.SetSelectedTool(InkTool.Pen); - SetActiveArrowStart(this._head[i]); - SetActiveArrowEnd(this._end[i]); - SetActiveBezierApprox("300"); - - GestureOverlay.Instance.InkShape = this._shape[i]; - } else { - this._selected = this._shapesNum; - Doc.SetSelectedTool(InkTool.None); - SetActiveArrowStart(""); - SetActiveArrowEnd(""); - GestureOverlay.Instance.InkShape = ""; - SetActiveBezierApprox("0"); - } - }); - return
- {this._draw.map((icon, i) => - )} -
; - } - - toggleButton = (key: string, value: boolean, setter: () => {}, icon: FontAwesomeIconProps["icon"], ele: JSX.Element | null) => { - return ; - } - - @computed get widthPicker() { - var widthPicker = this.toggleButton("stroke width", this._widthBtn, () => this._widthBtn = !this._widthBtn, "bars", null); - return !this._widthBtn ? widthPicker : -
- {widthPicker} - {this._width.map(wid => - )} -
; - } - - @computed get colorPicker() { - var colorPicker = this.toggleButton("stroke color", this._colorBtn, () => this._colorBtn = !this._colorBtn, "pen-nib", -
); - return !this._colorBtn ? colorPicker : -
- {colorPicker} - {this._palette.map(color => - )} -
; - } - @computed get fillPicker() { - var fillPicker = this.toggleButton("shape fill color", this._fillBtn, () => this._fillBtn = !this._fillBtn, "fill-drip", -
); - return !this._fillBtn ? fillPicker : -
- {fillPicker} - {this._palette.map(color => - )} - -
; - } - - @computed get formatPane() { - return ; - } - - render() { - return this.getElement([ - this.widthPicker, - this.colorPicker, - this.fillPicker, - this.drawButtons, - this.formatPane, - - ]); - } -} -Scripting.addGlobal(function activatePen(penBtn: any) { - if (penBtn) { - InkOptionsMenu.Instance.jumpTo(300, 300); - InkOptionsMenu.Instance.Pinned = true; - } else { - InkOptionsMenu.Instance.Pinned = false; - InkOptionsMenu.Instance.fadeOut(true); - } -}); diff --git a/src/mobile/MobileInterface.tsx b/src/mobile/MobileInterface.tsx index fafa94a11..3a889b0db 100644 --- a/src/mobile/MobileInterface.tsx +++ b/src/mobile/MobileInterface.tsx @@ -28,7 +28,6 @@ import { DockedFrameRenderer } from '../client/views/collections/CollectionDocki import { InkTool } from '../fields/InkField'; import GestureOverlay from "../client/views/GestureOverlay"; import { ScriptField } from "../fields/ScriptField"; -import InkOptionsMenu from "../client/views/collections/collectionFreeForm/InkOptionsMenu"; import { RadialMenu } from "../client/views/nodes/RadialMenu"; import { UndoManager } from "../client/util/UndoManager"; import { List } from "../fields/List"; @@ -38,6 +37,7 @@ import RichTextMenu from "../client/views/nodes/formattedText/RichTextMenu"; import { AudioBox } from "../client/views/nodes/AudioBox"; import { CollectionViewType } from "../client/views/collections/CollectionView"; import { DocumentType } from "../client/documents/DocumentTypes"; +import { CollectionFreeFormViewChrome } from "../client/views/collections/CollectionMenu"; library.add(faTasks, faReply, faQuoteLeft, faHandPointLeft, faFolderOpen, faAngleDoubleLeft, faExternalLinkSquareAlt, faMobile, faThLarge, faWindowClose, faEdit, faTrashAlt, faPalette, faAngleRight, faBell, faTrash, faCamera, faExpand, faCaretDown, faCaretLeft, faCaretRight, faCaretSquareDown, faCaretSquareRight, faArrowsAltH, faPlus, faMinus, faTerminal, faToggleOn, fileSolid, faExternalLinkAlt, faLocationArrow, faSearch, faFileDownload, faStop, faCalculator, faWindowMaximize, faAddressCard, @@ -429,7 +429,7 @@ export class MobileInterface extends React.Component { @computed get inkMenu() { return this._activeDoc._viewType !== CollectionViewType.Docking || !this._ink ? (null) :
- + {/* */}
; } -- cgit v1.2.3-70-g09d2