aboutsummaryrefslogtreecommitdiff
path: root/src/client/views/collections/CollectionMenu.tsx
diff options
context:
space:
mode:
authorbobzel <zzzman@gmail.com>2023-11-29 10:02:34 -0500
committerbobzel <zzzman@gmail.com>2023-11-29 10:02:34 -0500
commitba3b3f6f261074bd3f35012bde8730f5d4a36905 (patch)
tree6f6c7b141f8bc5881113378801d4b2940cfde36a /src/client/views/collections/CollectionMenu.tsx
parentac360607bee82f0fef769eada99dc0b3f85ae70a (diff)
numerous changes to fix bugs and to fix/remove old or hacky code. fixed doc dec resizing. moving this.rootDoc => this.Document . fixing template artifacts.
Diffstat (limited to 'src/client/views/collections/CollectionMenu.tsx')
-rw-r--r--src/client/views/collections/CollectionMenu.tsx824
1 files changed, 16 insertions, 808 deletions
diff --git a/src/client/views/collections/CollectionMenu.tsx b/src/client/views/collections/CollectionMenu.tsx
index b190eb23d..3c555e731 100644
--- a/src/client/views/collections/CollectionMenu.tsx
+++ b/src/client/views/collections/CollectionMenu.tsx
@@ -1,43 +1,26 @@
import React = require('react');
-import { IconProp } from '@fortawesome/fontawesome-svg-core';
-import { FontAwesomeIcon, FontAwesomeIconProps } from '@fortawesome/react-fontawesome';
+import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { Tooltip } from '@material-ui/core';
import { Toggle, ToggleType, Type } from 'browndash-components';
import { action, computed, Lambda, observable, reaction, runInAction } from 'mobx';
import { observer } from 'mobx-react';
-import { ColorState } from 'react-color';
import { Doc, DocListCast, Opt } from '../../../fields/Doc';
-import { Document } from '../../../fields/documentSchemas';
-import { Id } from '../../../fields/FieldSymbols';
-import { InkTool } from '../../../fields/InkField';
import { List } from '../../../fields/List';
import { ObjectField } from '../../../fields/ObjectField';
import { RichTextField } from '../../../fields/RichTextField';
-import { listSpec } from '../../../fields/Schema';
import { BoolCast, Cast, DocCast, NumCast, StrCast } from '../../../fields/Types';
-import { GestureUtils } from '../../../pen-gestures/GestureUtils';
import { emptyFunction, returnEmptyDoclist, returnEmptyFilter, returnFalse, returnTrue, setupMoveUpEvents, Utils } from '../../../Utils';
-import { Docs } from '../../documents/Documents';
import { CollectionViewType, DocumentType } from '../../documents/DocumentTypes';
import { DragManager } from '../../util/DragManager';
-import { ScriptingGlobals } from '../../util/ScriptingGlobals';
import { SelectionManager } from '../../util/SelectionManager';
import { SettingsManager } from '../../util/SettingsManager';
import { Transform } from '../../util/Transform';
import { undoBatch } from '../../util/UndoManager';
import { AntimodeMenu } from '../AntimodeMenu';
import { EditableView } from '../EditableView';
-import { GestureOverlay } from '../GestureOverlay';
-import { ActiveFillColor, ActiveInkColor, SetActiveArrowEnd, SetActiveArrowStart, SetActiveBezierApprox, SetActiveFillColor, SetActiveInkColor, SetActiveInkWidth } from '../InkingStroke';
-import { LightboxView } from '../LightboxView';
import { MainView } from '../MainView';
-import { media_state } from '../nodes/AudioBox';
-import { CollectionFreeFormDocumentView } from '../nodes/CollectionFreeFormDocumentView';
-import { DocumentView, DocumentViewInternal, OpenWhereMod } from '../nodes/DocumentView';
-import { RichTextMenu } from '../nodes/formattedText/RichTextMenu';
+import { DocumentView, DocumentViewInternal } from '../nodes/DocumentView';
import { DefaultStyleProvider } from '../StyleProvider';
-import { CollectionDockingView } from './CollectionDockingView';
-import { CollectionFreeFormView } from './collectionFreeForm';
import { CollectionLinearView } from './collectionLinear';
import './CollectionMenu.scss';
@@ -66,7 +49,7 @@ export class CollectionMenu extends AntimodeMenu<CollectionMenuProps> {
componentDidMount() {
reaction(
- () => SelectionManager.Views().length && SelectionManager.Views()[0],
+ () => SelectionManager.Views().lastElement(),
view => view && this.SetSelection(view)
);
}
@@ -174,7 +157,6 @@ export class CollectionMenu extends AntimodeMenu<CollectionMenuProps> {
</div>
);
- // NEW BUTTONS
//dash col linear view buttons
const contMenuButtons = (
<div
@@ -189,21 +171,6 @@ export class CollectionMenu extends AntimodeMenu<CollectionMenuProps> {
);
return contMenuButtons;
-
- // const button = <Tooltip title={<div className="dash-tooltip">Pin Menu</div>} key="pin menu" placement="bottom">
- // <button className="antimodeMenu-button" onClick={this.toggleMenuPin} style={{ backgroundColor: "#121721" }}>
- // <FontAwesomeIcon icon="thumbtack" size="lg" style={{ transitionProperty: "transform", transitionDuration: "0.1s", transform: `rotate(${this.Pinned ? 45 : 0}deg)` }} />
- // </button>
- // </Tooltip>;
-
- // //OLD BUTTONS
- // return this.getElement(!this.SelectedCollection ? [/*button*/] :
- // [<CollectionViewBaseChrome key="chrome"
- // docView={this.SelectedCollection}
- // fieldKey={this.SelectedCollection.LayoutFieldKey}
- // type={StrCast(this.SelectedCollection?.props.Document._type_collection, CollectionViewType.Invalid) as CollectionViewType} />,
- // prop,
- // /*button*/]);
}
}
@@ -228,7 +195,7 @@ export class CollectionViewBaseChrome extends React.Component<CollectionViewMenu
_templateCommand = {
params: ['target', 'source'],
title: 'item view',
- script: 'self.target.childLayoutTemplate = getDocTemplate(self.source?.[0])',
+ script: 'this.target.childLayoutTemplate = getDocTemplate(this.source?.[0])',
immediate: undoBatch((source: Doc[]) => {
let formatStr = source.length && Cast(source[0].text, RichTextField, null)?.Text;
try {
@@ -250,24 +217,24 @@ export class CollectionViewBaseChrome extends React.Component<CollectionViewMenu
_narrativeCommand = {
params: ['target', 'source'],
title: 'child click view',
- script: 'self.target.childClickedOpenTemplateView = getDocTemplate(self.source?.[0])',
+ 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: 'set content',
- script: 'getProto(self.target).data = copyField(self.source);',
+ script: 'getProto(this.target).data = copyField(this.source);',
immediate: undoBatch((source: Doc[]) => (Doc.GetProto(this.target).data = new List<Doc>(source))),
initialize: emptyFunction,
};
_onClickCommand = {
params: ['target', 'proxy'],
title: 'copy onClick',
- script: `{ if (self.proxy?.[0]) {
- getProto(self.proxy[0]).onClick = copyField(self.target.onClick);
- getProto(self.proxy[0]).target = self.target.target;
- getProto(self.proxy[0]).source = copyField(self.target.source);
+ script: `{ if (this.proxy?.[0]) {
+ getProto(this.proxy[0]).onClick = copyField(this.target.onClick);
+ getProto(this.proxy[0]).target = this.target.target;
+ getProto(this.proxy[0]).source = copyField(this.target.source);
}}`,
immediate: undoBatch((source: Doc[]) => {}),
initialize: emptyFunction,
@@ -275,7 +242,7 @@ export class CollectionViewBaseChrome extends React.Component<CollectionViewMenu
_viewCommand = {
params: ['target'],
title: 'bookmark view',
- script: "self.target._freeform_panX = self['target-freeform_panX']; self.target._freeform_panY = self['target-freeform_panY']; self.target._freeform_scale = self['target_freeform_scale']; gotoFrame(self.target, self['target-currentFrame']);",
+ script: "this.target._freeform_panX = self['target-freeform_panX']; this.target._freeform_panY = this['target-freeform_panY']; this.target._freeform_scale = this['target_freeform_scale']; gotoFrame(this.target, this['target-currentFrame']);",
immediate: undoBatch((source: Doc[]) => {
this.target._freeform_panX = 0;
this.target._freeform_panY = 0;
@@ -292,22 +259,22 @@ export class CollectionViewBaseChrome extends React.Component<CollectionViewMenu
_clusterCommand = {
params: ['target'],
title: 'fit content',
- script: 'self.target._freeform_fitContentsToBox = !self.target._freeform_fitContentsToBox;',
+ script: 'this.target._freeform_fitContentsToBox = !this.target._freeform_fitContentsToBox;',
immediate: undoBatch((source: Doc[]) => (this.target._freeform_fitContentsToBox = !this.target._freeform_fitContentsToBox)),
initialize: emptyFunction,
};
_fitContentCommand = {
params: ['target'],
title: 'toggle clusters',
- script: 'self.target._freeform_useClusters = !self.target._freeform_useClusters;',
+ script: 'this.target._freeform_useClusters = !this.target._freeform_useClusters;',
immediate: undoBatch((source: Doc[]) => (this.target._freeform_useClusters = !this.target._freeform_useClusters)),
initialize: emptyFunction,
};
_saveFilterCommand = {
params: ['target'],
title: 'save filter',
- script: `self.target._childFilters = compareLists(self['target-childFilters'],self.target._childFilters) ? undefined : copyField(self['target-childFilters']);
- self.target._searchFilterDocs = compareLists(self['target-searchFilterDocs'],self.target._searchFilterDocs) ? undefined: copyField(self['target-searchFilterDocs']);`,
+ script: `this.target._childFilters = compareLists(this['target-childFilters'],this.target._childFilters) ? undefined : copyField(this['target-childFilters']);
+ this.target._searchFilterDocs = compareLists(this['target-searchFilterDocs'],this.target._searchFilterDocs) ? undefined: copyField(this['target-searchFilterDocs']);`,
immediate: undoBatch((source: Doc[]) => {
this.target._childFilters = undefined;
this.target._searchFilterDocs = undefined;
@@ -390,57 +357,6 @@ export class CollectionViewBaseChrome extends React.Component<CollectionViewMenu
this.document._facetWidth = 0;
};
- @computed get subChrome() {
- switch (
- this.props.docView.props.LayoutTemplateString ? CollectionViewType.Freeform : this.props.type // bcz: ARgh! hack to get menu for tree view outline items
- ) {
- default:
- return this.otherSubChrome;
- case CollectionViewType.Invalid:
- case CollectionViewType.Freeform:
- return <CollectionFreeFormViewChrome key="collchrome" {...this.props} isOverlay={this.props.type === CollectionViewType.Invalid} />;
- case CollectionViewType.Stacking:
- return <CollectionStackingViewChrome key="collchrome" {...this.props} />;
- case CollectionViewType.NoteTaking:
- return <CollectionNoteTakingViewChrome key="collchrome" {...this.props} />;
- case CollectionViewType.Schema:
- return <CollectionSchemaViewChrome key="collchrome" {...this.props} />;
- case CollectionViewType.Tree:
- return <CollectionTreeViewChrome key="collchrome" {...this.props} />;
- case CollectionViewType.Masonry:
- return <CollectionStackingViewChrome key="collchrome" {...this.props} />;
- case CollectionViewType.Carousel:
- case CollectionViewType.Carousel3D:
- return <Collection3DCarouselViewChrome key="collchrome" {...this.props} />;
- case CollectionViewType.Grid:
- return <CollectionGridViewChrome key="collchrome" {...this.props} />;
- case CollectionViewType.Docking:
- return <CollectionDockingChrome key="collchrome" {...this.props} />;
- }
- }
-
- @computed get otherSubChrome() {
- const docType = this.props.docView.Document.type;
- switch (docType) {
- default:
- return null;
- case DocumentType.IMG:
- return <CollectionFreeFormViewChrome key="collchrome" {...this.props} isOverlay={false} isDoc={true} />;
- case DocumentType.PDF:
- return <CollectionFreeFormViewChrome key="collchrome" {...this.props} isOverlay={false} isDoc={true} />;
- case DocumentType.INK:
- return <CollectionFreeFormViewChrome key="collchrome" {...this.props} isOverlay={false} isDoc={true} />;
- case DocumentType.WEB:
- return <CollectionFreeFormViewChrome key="collchrome" {...this.props} isOverlay={false} isDoc={true} />;
- case DocumentType.VID:
- return <CollectionFreeFormViewChrome key="collchrome" {...this.props} isOverlay={false} isDoc={true} />;
- case DocumentType.RTF:
- return <CollectionFreeFormViewChrome key="collchrome" {...this.props} isOverlay={this.props.type === CollectionViewType.Invalid} isDoc={true} />;
- case DocumentType.MAP:
- return <CollectionFreeFormViewChrome key="collchrome" {...this.props} isOverlay={false} isDoc={true} />;
- }
- }
-
private dropDisposer?: DragManager.DragDropDisposer;
protected createDropTarget = (ele: HTMLDivElement) => {
this.dropDisposer?.();
@@ -517,593 +433,11 @@ export class CollectionViewBaseChrome extends React.Component<CollectionViewMenu
</div>
);
}
-
- @computed get viewModes() {
- const excludedViewTypes = [CollectionViewType.Invalid, CollectionViewType.Docking, CollectionViewType.Pile, CollectionViewType.StackedTimeline, CollectionViewType.Linear];
- const isPres: boolean = this.document && this.document.type === DocumentType.PRES;
- return isPres ? null : (
- <div className="collectionViewBaseChrome-viewModes">
- <Tooltip title={<div className="dash-tooltip">drop document to apply or drag to create button</div>} placement="bottom">
- <div className="commandEntry-outerDiv" ref={this._viewRef} onPointerDown={this.dragViewDown}>
- <button className={'antimodeMenu-button'}>
- <FontAwesomeIcon icon="bullseye" size="lg" />
- </button>
- <select className="collectionViewBaseChrome-viewPicker" onPointerDown={stopPropagation} onChange={this.viewChanged} value={StrCast(this.props.type)}>
- {Object.values(CollectionViewType)
- .filter(type => !excludedViewTypes.includes(type))
- .map(type => (
- <option key={Utils.GenerateGuid()} className="collectionViewBaseChrome-viewOption" onPointerDown={stopPropagation} value={type}>
- {type[0].toUpperCase() + type.substring(1)}
- </option>
- ))}
- </select>
- </div>
- </Tooltip>
- </div>
- );
- }
-
- @computed get selectedDocumentView() {
- return SelectionManager.Views().lastElement();
- }
- @computed get selectedDoc() {
- return SelectionManager.Docs().lastElement();
- }
- @computed get notACollection() {
- if (this.selectedDoc) {
- const layoutField = Doc.LayoutField(this.selectedDoc);
- return this.props.type === CollectionViewType.Docking || (typeof layoutField === 'string' && !layoutField?.includes('CollectionView'));
- } else return false;
- }
-
- @undoBatch
- @action
- startRecording = () => {
- const doc = Docs.Create.ScreenshotDocument({ title: 'screen recording', _layout_fitWidth: true, _width: 400, _height: 200, mediaState: media_state.PendingRecording });
- CollectionDockingView.AddSplit(doc, OpenWhereMod.right);
- };
-
- @computed
- get recordButton() {
- const targetDoc = this.selectedDoc;
- return (
- <Tooltip key="record" title={<div className="dash-tooltip">{'Capture screen'}</div>} placement="top">
- <button className="antimodeMenu-button" onClick={e => this.startRecording()}>
- <div className="recordButtonOutline" style={{}}>
- <div className="recordButtonInner" style={{}}></div>
- </div>
- </button>
- </Tooltip>
- );
- }
-
- @undoBatch
- onEmbed = () => {
- if (this.selectedDoc && this.selectedDocumentView) {
- // const copy = Doc.MakeCopy(this.selectedDocumentView.props.Document, true);
- // copy.x = NumCast(this.selectedDoc.x) + NumCast(this.selectedDoc._width);
- // copy.y = NumCast(this.selectedDoc.y) + 30;
- // this.selectedDocumentView.props.addDocument?.(copy);
- const embedding = Doc.MakeEmbedding(this.selectedDoc);
- embedding.x = NumCast(this.selectedDoc.x) + NumCast(this.selectedDoc._width);
- embedding.y = NumCast(this.selectedDoc.y) + 30;
- this.selectedDocumentView.props.addDocument?.(embedding);
- }
- };
- onEmbedButtonDown = (e: React.PointerEvent): void => {
- setupMoveUpEvents(this, e, this.onEmbedButtonMoved, emptyFunction, emptyFunction);
- };
-
- @undoBatch
- onEmbedButtonMoved = (e: PointerEvent) => {
- const contentDiv = this.selectedDocumentView?.ContentDiv;
- if (contentDiv && this.selectedDoc) {
- const dragData = new DragManager.DocumentDragData([this.selectedDoc]);
- const offset = [e.clientX - contentDiv.getBoundingClientRect().x, e.clientY - contentDiv.getBoundingClientRect().y];
- dragData.defaultDropAction = 'embed';
- dragData.canEmbed = true;
- DragManager.StartDocumentDrag([contentDiv], dragData, e.clientX, e.clientY, {
- offsetX: offset[0],
- offsetY: offset[1],
- hideSource: false,
- });
- return true;
- }
- return false;
- };
-
- @computed
- get embedButton() {
- const targetDoc = this.selectedDoc;
- return !targetDoc || targetDoc.type === DocumentType.PRES ? null : (
- <Tooltip title={<div className="dash-tooltip">{'Tap or Drag to create an embedding'}</div>} placement="top">
- <button className="antimodeMenu-button" onPointerDown={this.onEmbedButtonDown} onClick={this.onEmbed} style={{ cursor: 'drag' }}>
- <FontAwesomeIcon className="colMenu-icon" icon="copy" size="lg" />
- </button>
- </Tooltip>
- );
- }
-
- @computed get lightboxButton() {
- const targetDoc = this.selectedDoc;
- return !targetDoc ? null : (
- <Tooltip title={<div className="dash-tooltip">{'View in Lightbox'}</div>} placement="top">
- <button
- className="antimodeMenu-button"
- onPointerDown={() => {
- const docs = DocListCast(targetDoc[Doc.LayoutFieldKey(targetDoc)]);
- LightboxView.Instance.SetLightboxDoc(targetDoc, undefined, docs);
- }}>
- <FontAwesomeIcon className="colMenu-icon" icon="desktop" size="lg" />
- </button>
- </Tooltip>
- );
- }
-
- @computed get toggleOverlayButton() {
- return (
- <>
- <Tooltip title={<div className="dash-tooltip">Toggle Overlay Layer</div>} placement="bottom">
- <button
- className={'antimodeMenu-button'}
- key="float"
- style={{
- backgroundColor: this.props.docView.layoutDoc.z ? '121212' : undefined,
- pointerEvents: this.props.docView.props.docViewPath().lastElement()?.rootDoc?._type_collection !== CollectionViewType.Freeform ? 'none' : undefined,
- color: this.props.docView.props.docViewPath().lastElement()?.rootDoc?._type_collection !== CollectionViewType.Freeform ? 'dimgrey' : undefined,
- }}
- onClick={undoBatch(() => this.props.docView.CollectionFreeFormDocumentView?.float())}>
- <FontAwesomeIcon icon={['fab', 'buffer']} size={'lg'} />
- </button>
- </Tooltip>
- </>
- );
- }
-
render() {
return (
<div className="collectionMenu-cont">
<div className="collectionMenu">
- <div className="collectionViewBaseChrome">
- {this.notACollection || this.props.type === CollectionViewType.Invalid ? null : this.viewModes}
- <div className="collectionMenu-divider" key="divider1"></div>
- {this.embedButton}
- {/* {this.pinButton} */}
- {this.toggleOverlayButton}
- <div className="collectionMenu-divider" key="divider2"></div>
- {this.subChrome}
- <div className="collectionMenu-divider" key="divider3"></div>
- {this.lightboxButton}
- {this.recordButton}
- {!this._buttonizableCommands ? null : this.templateChrome}
- </div>
- </div>
- </div>
- );
- }
-}
-
-@observer
-export class CollectionDockingChrome extends React.Component<CollectionViewMenuProps> {
- render() {
- return null;
- }
-}
-
-@observer
-export class CollectionFreeFormViewChrome extends React.Component<CollectionViewMenuProps & { isOverlay: boolean; isDoc?: boolean }> {
- public static Instance: CollectionFreeFormViewChrome;
- constructor(props: any) {
- super(props);
- CollectionFreeFormViewChrome.Instance = this;
- }
- get document() {
- return this.props.docView.props.Document;
- }
- @computed get dataField() {
- return this.document[this.props.docView.LayoutFieldKey + (this.props.isOverlay ? '_annotations' : '')];
- }
- @computed get childDocs() {
- return DocListCast(this.dataField);
- }
- @computed get selectedDocumentView() {
- return SelectionManager.Views().lastElement();
- }
- @computed get selectedDoc() {
- return SelectionManager.Docs().lastElement();
- }
- @computed get isText() {
- return this.selectedDoc?.type === DocumentType.RTF || (RichTextMenu.Instance?.view as any) ? true : false;
- }
-
- public static gotoKeyFrame(doc: Doc, newFrame: number) {
- if (doc) {
- const childDocs = DocListCast(doc[Doc.LayoutFieldKey(doc)]);
- const currentFrame = Cast(doc._currentFrame, 'number', null);
- if (currentFrame === undefined) {
- doc._currentFrame = 0;
- CollectionFreeFormDocumentView.setupKeyframes(childDocs, 0);
- }
- CollectionFreeFormView.updateKeyframe(undefined, [...childDocs, doc], currentFrame || 0);
- doc._currentFrame = newFrame === undefined ? 0 : Math.max(0, newFrame);
- }
- }
-
- _keyTimer: NodeJS.Timeout | undefined;
- @undoBatch
- @action
- nextKeyframe = (): void => {
- const currentFrame = Cast(this.document._currentFrame, 'number', null);
- if (currentFrame === undefined) {
- this.document._currentFrame = 0;
- CollectionFreeFormDocumentView.setupKeyframes(this.childDocs, 0);
- }
- this._keyTimer = CollectionFreeFormView.updateKeyframe(this._keyTimer, [...this.childDocs, this.document], 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 = Cast(this.document._currentFrame, 'number', null);
- if (currentFrame === undefined) {
- this.document._currentFrame = 0;
- CollectionFreeFormDocumentView.setupKeyframes(this.childDocs, 0);
- }
- this._keyTimer = CollectionFreeFormView.gotoKeyframe(this._keyTimer, [...this.childDocs, this.document], 1000);
- this.document._currentFrame = Math.max(0, (currentFrame || 0) - 1);
- };
-
- private _palette = ['#D0021B', '#F5A623', '#F8E71C', '#8B572A', '#7ED321', '#417505', '#9013FE', '#4A90E2', '#50E3C2', '#B8E986', '#000000', '#4A4A4A', '#9B9B9B', '#FFFFFF', ''];
- private _width = ['1', '5', '10', '100'];
- private _dotsize = [10, 20, 30, 40];
- private _draw = ['∿', '=', '⎯', '→', '↔︎', 'ロ', 'O'];
- private _head = ['', '', '', '', 'arrow', '', ''];
- private _end = ['', '', '', 'arrow', 'arrow', '', ''];
- private _shapePrims = ['', '', 'line', 'line', 'line', 'rectangle', 'circle'] as GestureUtils.Gestures[];
- private _title = ['pen', 'highlighter', 'line', 'line with arrow', 'line with double arrows', 'square', 'circle'];
- private _faName = ['pen-fancy', 'highlighter', 'minus', 'long-arrow-alt-right', 'arrows-alt-h', 'square', 'circle'];
- @observable _selectedPrimitive = this._shapePrims.length;
- @observable _keepPrimitiveMode = false; // for whether primitive selection enters a one-shot or persistent mode
- @observable _colorBtn = false;
- @observable _widthBtn = false;
- @observable _fillBtn = false;
-
- @action clearKeepPrimitiveMode() {
- this._selectedPrimitive = this._shapePrims.length;
- }
- @action primCreated() {
- if (!this._keepPrimitiveMode) {
- //get out of ink mode after each stroke=
- if (Doc.ActiveTool === InkTool.Highlighter && GestureOverlay.Instance.SavedColor) SetActiveInkColor(GestureOverlay.Instance.SavedColor);
- Doc.ActiveTool = InkTool.None;
- this._selectedPrimitive = this._shapePrims.length;
- SetActiveArrowStart('none');
- SetActiveArrowEnd('none');
- }
- }
-
- @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.Views().forEach(
- action((element: DocumentView) => {
- const doc = Document(element.rootDoc);
- if (doc.type === DocumentType.INK) {
- switch (field) {
- case 'width':
- doc.stroke_width = Number(value);
- break;
- case 'color':
- doc.color = String(value);
- break;
- case 'fill':
- doc.fillColor = String(value);
- break;
- case 'dash':
- doc.stroke_dash = value;
- }
- }
- })
- );
- };
-
- @computed get drawButtons() {
- const func = action((e: React.MouseEvent | React.PointerEvent, i: number, keep: boolean) => {
- this._keepPrimitiveMode = keep;
- // these are for shapes
- if (this._selectedPrimitive !== i) {
- this._selectedPrimitive = i;
- if (this._title[i] === 'highlighter') {
- Doc.ActiveTool = InkTool.Highlighter;
- GestureOverlay.Instance.SavedColor = ActiveInkColor();
- SetActiveInkColor('rgba(245, 230, 95, 0.75)');
- } else {
- Doc.ActiveTool = InkTool.Pen;
- }
- SetActiveArrowStart(this._head[i]);
- SetActiveArrowEnd(this._end[i]);
- SetActiveBezierApprox('300');
-
- if (GestureOverlay.Instance) GestureOverlay.Instance.InkShape = this._shapePrims[i];
- } else {
- this._selectedPrimitive = this._shapePrims.length;
- Doc.ActiveTool = InkTool.None;
- SetActiveArrowStart('');
- SetActiveArrowEnd('');
- if (GestureOverlay.Instance) GestureOverlay.Instance.InkShape = undefined;
- SetActiveBezierApprox('0');
- }
- e.stopPropagation();
- });
- return (
- <div className="btn-draw" key="draw">
- {this._draw.map((icon, i) => (
- <Tooltip key={icon} title={<div className="dash-tooltip">{this._title[i]}</div>} placement="bottom">
- <button className="antimodeMenu-button" onPointerDown={e => func(e, i, false)} onDoubleClick={e => func(e, i, true)} style={{ backgroundColor: i === this._selectedPrimitive ? '525252' : '', fontSize: '20' }}>
- <FontAwesomeIcon icon={this._faName[i] as IconProp} size="sm" />
- </button>
- </Tooltip>
- ))}
- </div>
- );
- }
-
- toggleButton = (key: string, value: boolean, setter: () => {}, icon: FontAwesomeIconProps['icon'], ele: JSX.Element | null) => {
- return (
- <Tooltip title={<div className="dash-tooltip">{key}</div>} placement="bottom">
- <button className="antimodeMenu-button" key={key} onPointerDown={action(e => setter())} style={{ backgroundColor: value ? '121212' : '' }}>
- <FontAwesomeIcon icon={icon} size="lg" />
- {ele}
- </button>
- </Tooltip>
- );
- };
-
- @computed get widthPicker() {
- const widthPicker = this.toggleButton('stroke width', this._widthBtn, () => (this._widthBtn = !this._widthBtn), 'bars', null);
- return !this._widthBtn ? (
- widthPicker
- ) : (
- <div className="btn2-group" key="width">
- {widthPicker}
- {this._width.map((wid, i) => (
- <Tooltip title={<div className="dash-tooltip">change width</div>} placement="bottom">
- <button
- className="antimodeMenu-button"
- key={wid}
- onPointerDown={action(() => {
- SetActiveInkWidth(wid);
- this._widthBtn = false;
- this.editProperties(wid, 'width');
- })}
- style={{ backgroundColor: this._widthBtn ? '121212' : '', zIndex: 1001, fontSize: this._dotsize[i], padding: 0, textAlign: 'center' }}>
- •
- </button>
- </Tooltip>
- ))}
- </div>
- );
- }
-
- @computed get colorPicker() {
- const colorPicker = this.toggleButton('stroke color', this._colorBtn, () => (this._colorBtn = !this._colorBtn), 'pen-nib', <div className="color-previewI" style={{ backgroundColor: ActiveInkColor() ?? '121212' }} />);
- return !this._colorBtn ? (
- colorPicker
- ) : (
- <div className="btn-group" key="color">
- {colorPicker}
- {this._palette.map(color => (
- <button
- className="antimodeMenu-button"
- key={color}
- onPointerDown={action(() => {
- this.changeColor(color, 'color');
- this._colorBtn = false;
- this.editProperties(color, 'color');
- })}
- style={{ backgroundColor: this._colorBtn ? '121212' : '', zIndex: 1001 }}>
- {/* <FontAwesomeIcon icon="pen-nib" size="lg" /> */}
- <div className="color-previewII" style={{ backgroundColor: color }}>
- {color === '' ? <p style={{ fontSize: 40, color: 'red', marginTop: -10, marginLeft: -5, position: 'fixed' }}>☒</p> : ''}
- </div>
- </button>
- ))}
- </div>
- );
- }
- @computed get fillPicker() {
- const fillPicker = this.toggleButton('shape fill color', this._fillBtn, () => (this._fillBtn = !this._fillBtn), 'fill-drip', <div className="color-previewI" style={{ backgroundColor: ActiveFillColor() ?? '121212' }} />);
- return !this._fillBtn ? (
- fillPicker
- ) : (
- <div className="btn-group" key="fill">
- {fillPicker}
- {this._palette.map(color => (
- <button
- className="antimodeMenu-button"
- key={color}
- onPointerDown={action(() => {
- this.changeColor(color, 'fill');
- this._fillBtn = false;
- this.editProperties(color, 'fill');
- })}
- style={{ backgroundColor: this._fillBtn ? '121212' : '', zIndex: 1001 }}>
- <div className="color-previewII" style={{ backgroundColor: color }}>
- {color === '' ? <p style={{ fontSize: 40, color: 'red', marginTop: -10, marginLeft: -5, position: 'fixed' }}>☒</p> : ''}
- </div>
- </button>
- ))}
- </div>
- );
- }
-
- render() {
- return !this.props.docView.layoutDoc ? null : (
- <div className="collectionFreeFormMenu-cont">
- <RichTextMenu key="rich" />
- {!this.isText ? (
- <>
- {this.drawButtons}
- {this.widthPicker}
- {this.colorPicker}
- {this.fillPicker}
- {Doc.noviceMode || this.props.isDoc ? null : (
- <>
- <Tooltip key="back" title={<div className="dash-tooltip">Back Frame</div>} placement="bottom">
- <div className="backKeyframe" onClick={this.prevKeyframe}>
- <FontAwesomeIcon icon={'caret-left'} size={'lg'} />
- </div>
- </Tooltip>
- <Tooltip key="num" title={<div className="dash-tooltip">Frame number</div>} placement="bottom">
- <div
- className="numKeyframe"
- style={{ color: this.props.docView.ComponentView?.getKeyFrameEditing?.() ? 'white' : 'black', backgroundColor: this.props.docView.ComponentView?.getKeyFrameEditing?.() ? '#5B9FDD' : '#AEDDF8' }}
- onClick={action(() => this.props.docView.ComponentView?.setKeyFrameEditing?.(!this.props.docView.ComponentView?.getKeyFrameEditing?.()))}>
- {NumCast(this.document._currentFrame)}
- </div>
- </Tooltip>
- <Tooltip key="fwd" title={<div className="dash-tooltip">Forward Frame</div>} placement="bottom">
- <div className="fwdKeyframe" onClick={this.nextKeyframe}>
- <FontAwesomeIcon icon={'caret-right'} size={'lg'} />
- </div>
- </Tooltip>
- </>
- )}
- </>
- ) : null}
- {!this.selectedDocumentView?.ComponentView?.menuControls ? null : this.selectedDocumentView?.ComponentView?.menuControls?.()}
- </div>
- );
- }
-}
-@observer
-export class CollectionStackingViewChrome extends React.Component<CollectionViewMenuProps> {
- @observable private _currentKey: string = '';
- @observable private suggestions: string[] = [];
-
- get document() {
- return this.props.docView.props.Document;
- }
-
- @computed private get descending() {
- return StrCast(this.document._columnsSort) === 'descending';
- }
- @computed get pivotField() {
- return StrCast(this.document._pivotField);
- }
-
- getKeySuggestions = async (value: string): Promise<string[]> => {
- const val = value.toLowerCase();
- const docs = DocListCast(this.document[this.props.fieldKey]);
-
- if (Doc.noviceMode) {
- if (docs instanceof Doc) {
- const keys = Object.keys(docs).filter(key => key.indexOf('title') >= 0 || key.indexOf('author') >= 0 || key.indexOf('author_date') >= 0 || key.indexOf('modificationDate') >= 0 || (key[0].toUpperCase() === key[0] && key[0] !== '_'));
- return keys.filter(key => key.toLowerCase().indexOf(val) > -1);
- }
- const keys = new Set<string>();
- docs.forEach(doc => Doc.allKeys(doc).forEach(key => keys.add(key)));
- const noviceKeys = Array.from(keys).filter(key => key.indexOf('title') >= 0 || key.indexOf('author') >= 0 || key.indexOf('author_date') >= 0 || key.indexOf('modificationDate') >= 0 || (key[0]?.toUpperCase() === key[0] && key[0] !== '_'));
- return noviceKeys.filter(key => key.toLowerCase().indexOf(val) > -1);
- }
-
- if (docs instanceof Doc) {
- return Object.keys(docs).filter(key => key.toLowerCase().indexOf(val) > -1);
- } else {
- const keys = new Set<string>();
- docs.forEach(doc => Doc.allKeys(doc).forEach(key => keys.add(key)));
- return Array.from(keys).filter(key => key.toLowerCase().indexOf(val) > -1);
- }
- };
-
- @action
- onKeyChange = (e: React.ChangeEvent, { newValue }: { newValue: string }) => {
- this._currentKey = newValue;
- };
-
- getSuggestionValue = (suggestion: string) => suggestion;
-
- renderSuggestion = (suggestion: string) => {
- return <p>{suggestion}</p>;
- };
-
- onSuggestionFetch = async ({ value }: { value: string }) => {
- const sugg = await this.getKeySuggestions(value);
- runInAction(() => {
- this.suggestions = sugg;
- });
- };
-
- @action
- onSuggestionClear = () => {
- this.suggestions = [];
- };
-
- @action
- setValue = (value: string) => {
- this.document._pivotField = value;
- return true;
- };
-
- @action toggleSort = () => {
- this.document._columnsSort = this.document._columnsSort === 'descending' ? 'ascending' : this.document._columnsSort === 'ascending' ? undefined : 'descending';
- };
- @action resetValue = () => {
- this._currentKey = this.pivotField;
- };
-
- render() {
- const doctype = this.props.docView.Document.type;
- const isPres: boolean = doctype === DocumentType.PRES;
- return isPres ? null : (
- <div className="collectionStackingViewChrome-cont">
- <div className="collectionStackingViewChrome-pivotField-cont">
- <div className="collectionStackingViewChrome-pivotField-label">GROUP BY:</div>
- <div className="collectionStackingViewChrome-sortIcon" onClick={this.toggleSort} style={{ transform: `rotate(${this.descending ? '180' : '0'}deg)` }}>
- <FontAwesomeIcon icon="caret-up" size="2x" color="white" />
- </div>
- <div className="collectionStackingViewChrome-pivotField">
- <EditableView
- GetValue={() => 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'}
- />
- </div>
+ <div className="collectionViewBaseChrome">{!this._buttonizableCommands ? null : this.templateChrome}</div>
</div>
</div>
);
@@ -1230,123 +564,6 @@ export class CollectionNoteTakingViewChrome extends React.Component<CollectionVi
}
}
-@observer
-export class CollectionSchemaViewChrome extends React.Component<CollectionViewMenuProps> {
- // private _textwrapAllRows: boolean = Cast(this.document.textwrappedSchemaRows, listSpec("string"), []).length > 0;
- get document() {
- return this.props.docView.props.Document;
- }
-
- @undoBatch
- togglePreview = () => {
- const dividerWidth = 4;
- const borderWidth = 0;
- const panelWidth = this.props.docView.props.PanelWidth();
- const previewWidth = NumCast(this.document.schema_previewWidth);
- const tableWidth = panelWidth - 2 * borderWidth - dividerWidth - previewWidth;
- this.document.schema_previewWidth = previewWidth === 0 ? Math.min(tableWidth / 3, 200) : 0;
- };
-
- @undoBatch
- @action
- toggleTextwrap = async () => {
- const textwrappedRows = Cast(this.document.textwrappedSchemaRows, listSpec('string'), []);
- if (textwrappedRows.length) {
- this.document.textwrappedSchemaRows = new List<string>([]);
- } else {
- const docs = DocListCast(this.document[this.props.fieldKey]);
- const allRows = docs instanceof Doc ? [docs[Id]] : docs.map(doc => doc[Id]);
- this.document.textwrappedSchemaRows = new List<string>(allRows);
- }
- };
-
- render() {
- const previewWidth = NumCast(this.document.schema_previewWidth);
- const textWrapped = Cast(this.document.textwrappedSchemaRows, listSpec('string'), []).length > 0;
-
- return (
- <div className="collectionSchemaViewChrome-cont">
- <div className="collectionSchemaViewChrome-toggle">
- <div className="collectionSchemaViewChrome-label">Show Preview: </div>
- <div className="collectionSchemaViewChrome-toggler" onClick={this.togglePreview}>
- <div className={'collectionSchemaViewChrome-togglerButton' + (previewWidth !== 0 ? ' on' : ' off')}>{previewWidth !== 0 ? 'on' : 'off'}</div>
- </div>
- </div>
- </div>
- );
- }
-}
-
-@observer
-export class CollectionTreeViewChrome extends React.Component<CollectionViewMenuProps> {
- get document() {
- return this.props.docView.props.Document;
- }
- get sortAscending() {
- return this.document[this.props.fieldKey + '-sortAscending'];
- }
- set sortAscending(value) {
- this.document[this.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 (
- <div className="collectionTreeViewChrome-cont">
- <button className="collectionTreeViewChrome-sort" onClick={this.toggleSort}>
- <div className="collectionTreeViewChrome-sortLabel">Sort</div>
- <div className="collectionTreeViewChrome-sortIcon" style={{ transform: `rotate(${this.ascending === undefined ? '90' : this.ascending ? '180' : '0'}deg)` }}>
- <FontAwesomeIcon icon="caret-up" size="2x" color="white" />
- </div>
- </button>
- </div>
- );
- }
-}
-
-// Enter scroll speed for 3D Carousel
-@observer
-export class Collection3DCarouselViewChrome extends React.Component<CollectionViewMenuProps> {
- get document() {
- return this.props.docView.props.Document;
- }
- @computed get scrollSpeed() {
- return this.document._autoScrollSpeed;
- }
-
- @action
- setValue = (value: string) => {
- const numValue = Number(StrCast(value));
- if (numValue > 0) {
- this.document._autoScrollSpeed = numValue;
- return true;
- }
- return false;
- };
-
- render() {
- return (
- <div className="collection3DCarouselViewChrome-cont">
- <div className="collection3DCarouselViewChrome-scrollSpeed-cont">
- {/* {FormattedTextBox.Focused ? <RichTextMenu /> : null} */}
- <div className="collectionStackingViewChrome-scrollSpeed-label">AUTOSCROLL SPEED:</div>
- <div className="collection3DCarouselViewChrome-scrollSpeed">
- <EditableView GetValue={() => StrCast(this.scrollSpeed)} oneLine SetValue={this.setValue} contents={this.scrollSpeed ? this.scrollSpeed : 1000} />
- </div>
- </div>
- </div>
- );
- }
-}
-
/**
* Chrome for grid view.
*/
@@ -1492,12 +709,6 @@ export class CollectionGridViewChrome extends React.Component<CollectionViewMenu
<input className="collectionGridViewChrome-columnButton" onClick={this.onIncrementButtonClick} onMouseEnter={this.incrementValue} onMouseLeave={this.decrementValue} type="button" value="↑" />
<input className="collectionGridViewChrome-columnButton" style={{ marginRight: 5 }} onClick={this.onDecrementButtonClick} onMouseEnter={this.decrementValue} onMouseLeave={this.incrementValue} type="button" value="↓" />
</span>
- {/* <span className="grid-control">
- <span className="grid-icon">
- <FontAwesomeIcon icon="text-height" size="1x" />
- </span>
- <input className="collectionGridViewChrome-entryBox" type="number" placeholder={this.document.rowHeight as string} onKeyDown={this.onRowHeightEnter} onClick={(e: React.MouseEvent<HTMLInputElement, MouseEvent>) => { e.stopPropagation(); e.preventDefault(); e.currentTarget.focus(); }} />
- </span> */}
<span className="grid-control" style={{ width: this.resize ? '12%' : '20%' }}>
<input type="checkbox" style={{ marginRight: 5 }} onChange={this.toggleCollisions} checked={!this.document.gridPreventCollision} />
<label className="flexLabel">{this.resize ? 'Coll' : 'Collisions'}</label>
@@ -1526,6 +737,3 @@ export class CollectionGridViewChrome extends React.Component<CollectionViewMenu
);
}
}
-ScriptingGlobals.add(function gotoFrame(doc: any, newFrame: any) {
- CollectionFreeFormViewChrome.gotoKeyFrame(doc, newFrame);
-});