From 96b2f5f5334fb475180a095905e19e45a0414233 Mon Sep 17 00:00:00 2001 From: Bob Zeleznik Date: Sun, 9 Feb 2020 17:02:43 -0500 Subject: from added range sliders --- src/client/views/nodes/SliderBox.tsx | 128 +++++++++++++++++++++++++++++++++++ 1 file changed, 128 insertions(+) create mode 100644 src/client/views/nodes/SliderBox.tsx (limited to 'src/client/views/nodes/SliderBox.tsx') diff --git a/src/client/views/nodes/SliderBox.tsx b/src/client/views/nodes/SliderBox.tsx new file mode 100644 index 000000000..00d3baf7c --- /dev/null +++ b/src/client/views/nodes/SliderBox.tsx @@ -0,0 +1,128 @@ +import { library } from '@fortawesome/fontawesome-svg-core'; +import { faEdit } from '@fortawesome/free-regular-svg-icons'; +import { computed } from 'mobx'; +import { observer } from 'mobx-react'; +import * as React from 'react'; +import { Handles, Rail, Slider, Tracks, Ticks } from 'react-compound-slider'; +import { Doc } from '../../../new_fields/Doc'; +import { documentSchema } from '../../../new_fields/documentSchemas'; +import { createSchema, listSpec, makeInterface } from '../../../new_fields/Schema'; +import { ScriptField } from '../../../new_fields/ScriptField'; +import { BoolCast, FieldValue, StrCast, NumCast, Cast } from '../../../new_fields/Types'; +import { DragManager } from '../../util/DragManager'; +import { ContextMenu } from '../ContextMenu'; +import { ContextMenuProps } from '../ContextMenuItem'; +import { DocComponent } from '../DocComponent'; +import './SliderBox.scss'; +import { Handle, TooltipRail, Track, Tick } from './SliderBox-components'; +import { FieldView, FieldViewProps } from './FieldView'; + + +library.add(faEdit as any); + +const ButtonSchema = createSchema({ + onClick: ScriptField, + buttonParams: listSpec("string"), + text: "string" +}); + +type SliderDocument = makeInterface<[typeof ButtonSchema, typeof documentSchema]>; +const SliderDocument = makeInterface(ButtonSchema, documentSchema); + +@observer +export class SliderBox extends DocComponent(SliderDocument) { + public static LayoutString(fieldKey: string) { return FieldView.LayoutString(SliderBox, fieldKey); } + private dropDisposer?: DragManager.DragDropDisposer; + + @computed get dataDoc() { + return this.props.DataDoc && + (this.Document.isTemplateForField || BoolCast(this.props.DataDoc.isTemplateForField) || + this.props.DataDoc.layout === this.props.Document) ? this.props.DataDoc : Doc.GetProto(this.props.Document); + } + + specificContextMenu = (e: React.MouseEvent): void => { + const funcs: ContextMenuProps[] = []; + funcs.push({ + description: "Clear Script Params", event: () => { + const params = FieldValue(this.Document.buttonParams); + params && params.map(p => this.props.Document[p] = undefined); + }, icon: "trash" + }); + + ContextMenu.Instance.addItem({ description: "OnClick...", subitems: funcs, icon: "asterisk" }); + } + onChange = (values: readonly number[]) => { + Cast(this.props.Document.onThumbChanged, ScriptField, null)?.script.run({ range: values, this: this.props.Document }) + } + + render() { + const domain = [NumCast(this.props.Document._sliderMin), NumCast(this.props.Document._sliderMax)] + const defaultValues = [NumCast(this.props.Document._sliderMinThumb), NumCast(this.props.Document._sliderMaxThumb)]; + return ( +
e.stopPropagation()} + style={{ boxShadow: this.Document.opacity === 0 ? undefined : StrCast(this.Document.boxShadow, "") }}> +
+ + + {railProps => } + + {({ handles, activeHandleID, getHandleProps }) => ( +
+ {handles.map(handle => ( + + ))} +
+ )} +
+ + {({ tracks, getTrackProps }) => ( +
+ {tracks.map(({ id, source, target }) => ( + + ))} +
+ )} +
+ + {({ ticks }) => ( +
+ {ticks.map((tick) => ( + val.toString()} + /> + ))} +
+ )} +
+
+
+
+ ); + } +} \ No newline at end of file -- cgit v1.2.3-70-g09d2 From 07e595fa4e542830b7731efc6b7116d8c01e2f75 Mon Sep 17 00:00:00 2001 From: Bob Zeleznik Date: Mon, 10 Feb 2020 00:25:09 -0500 Subject: made slider range filters persistent. --- .../views/collections/CollectionTimeView.tsx | 8 ++--- src/client/views/nodes/DocumentView.tsx | 31 ++++++++--------- src/client/views/nodes/SliderBox.tsx | 39 ++++++++++------------ src/new_fields/Doc.ts | 28 ++++++++++------ 4 files changed, 52 insertions(+), 54 deletions(-) (limited to 'src/client/views/nodes/SliderBox.tsx') diff --git a/src/client/views/collections/CollectionTimeView.tsx b/src/client/views/collections/CollectionTimeView.tsx index 861ee0dbb..487e98b33 100644 --- a/src/client/views/collections/CollectionTimeView.tsx +++ b/src/client/views/collections/CollectionTimeView.tsx @@ -97,21 +97,19 @@ export class CollectionTimeView extends CollectionSubView(doc => doc) { } }); if (nonNumbers / allCollectionDocs.length < .1) { + const ranged = Doc.readDocRangeFilter(this.props.Document, facetHeader); const newFacet = Docs.Create.SliderDocument({ title: facetHeader }); Doc.GetProto(newFacet).type = DocumentType.COL; // forces item to show an open/close button instead ofa checkbox newFacet.treeViewExpandedView = "layout"; newFacet.treeViewOpen = true; - newFacet._sliderMin = minVal; - newFacet._sliderMax = maxVal; + newFacet._sliderMin = ranged === undefined ? minVal : ranged[0]; + newFacet._sliderMax = ranged === undefined ? maxVal : ranged[1]; newFacet._sliderMinThumb = minVal; newFacet._sliderMaxThumb = maxVal; newFacet.target = this.props.Document; const scriptText = `setDocFilterRange(this.target, "${facetHeader}", range)`; newFacet.onThumbChanged = ScriptField.MakeScript(scriptText, { this: Doc.name, range: "number" }); - // const capturedVariables = { layoutDoc: this.props.Document, dataDoc: this.dataDoc }; - // const params = { layoutDoc: Doc.name, dataDoc: Doc.name, }; - // newFacet.data = ComputedField.MakeFunction(`readFacetData(layoutDoc, dataDoc, "${this.props.fieldKey}", "${facetHeader}")`, params, capturedVariables); Doc.AddDocToList(facetCollection, "data", newFacet); } else { const newFacet = Docs.Create.TreeDocument([], { title: facetHeader, treeViewOpen: true, isFacetFilter: true }); diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx index 787f6b79b..dfc56c642 100644 --- a/src/client/views/nodes/DocumentView.tsx +++ b/src/client/views/nodes/DocumentView.tsx @@ -1,56 +1,51 @@ import { library } from '@fortawesome/fontawesome-svg-core'; import * as fa from '@fortawesome/free-solid-svg-icons'; -import { action, computed, runInAction, trace } from "mobx"; +import { action, computed, runInAction } from "mobx"; import { observer } from "mobx-react"; import * as rp from "request-promise"; import { Doc, DocListCast, DocListCastAsync, Opt } from "../../../new_fields/Doc"; import { Document, PositionDocument } from '../../../new_fields/documentSchemas'; import { Id } from '../../../new_fields/FieldSymbols'; +import { InkTool } from '../../../new_fields/InkField'; +import { List } from '../../../new_fields/List'; +import { RichTextField } from '../../../new_fields/RichTextField'; import { listSpec } from "../../../new_fields/Schema"; import { ScriptField } from '../../../new_fields/ScriptField'; import { BoolCast, Cast, NumCast, StrCast } from "../../../new_fields/Types"; -import { ImageField, PdfField, VideoField, AudioField } from '../../../new_fields/URLField'; +import { AudioField, ImageField, PdfField, VideoField } from '../../../new_fields/URLField'; +import { TraceMobx } from '../../../new_fields/util'; +import { GestureUtils } from '../../../pen-gestures/GestureUtils'; import { CurrentUserUtils } from "../../../server/authentication/models/current_user_utils"; -import { emptyFunction, returnTransparent, returnTrue, Utils, returnOne } from "../../../Utils"; +import { emptyFunction, returnOne, returnTransparent, returnTrue, Utils } from "../../../Utils"; import { GooglePhotos } from '../../apis/google_docs/GooglePhotosClientUtils'; import { DocServer } from "../../DocServer"; -import { Docs, DocUtils, DocumentOptions } from "../../documents/Documents"; +import { Docs, DocumentOptions, DocUtils } from "../../documents/Documents"; import { DocumentType } from '../../documents/DocumentTypes'; import { ClientUtils } from '../../util/ClientUtils'; import { DocumentManager } from "../../util/DocumentManager"; import { DragManager, dropActionType } from "../../util/DragManager"; +import { InteractionUtils } from '../../util/InteractionUtils'; import { Scripting } from '../../util/Scripting'; import { SelectionManager } from "../../util/SelectionManager"; import SharingManager from '../../util/SharingManager'; import { Transform } from "../../util/Transform"; import { undoBatch, UndoManager } from "../../util/UndoManager"; -import { CollectionViewType } from '../collections/CollectionView'; import { CollectionDockingView } from "../collections/CollectionDockingView"; -import { CollectionView } from "../collections/CollectionView"; +import { CollectionView, CollectionViewType } from '../collections/CollectionView'; import { ContextMenu } from "../ContextMenu"; import { ContextMenuProps } from '../ContextMenuItem'; import { DocComponent } from "../DocComponent"; import { EditableView } from '../EditableView'; +import { InkingControl } from '../InkingControl'; import { OverlayView } from '../OverlayView'; import { ScriptBox } from '../ScriptBox'; import { ScriptingRepl } from '../ScriptingRepl'; import { DocumentContentsView } from "./DocumentContentsView"; import "./DocumentView.scss"; import { FormattedTextBox } from './FormattedTextBox'; -import React = require("react"); -import { InteractionUtils } from '../../util/InteractionUtils'; -import { InkingControl } from '../InkingControl'; -import { InkTool } from '../../../new_fields/InkField'; -import { TraceMobx } from '../../../new_fields/util'; -import { List } from '../../../new_fields/List'; import { FormattedTextBoxComment } from './FormattedTextBoxComment'; -import { GestureUtils } from '../../../pen-gestures/GestureUtils'; -import { RadialMenu } from './RadialMenu'; -import { RadialMenuProps } from './RadialMenuItem'; +import React = require("react"); -import { CollectionStackingView } from '../collections/CollectionStackingView'; -import { RichTextField } from '../../../new_fields/RichTextField'; -import { HistoryUtil } from '../../util/History'; library.add(fa.faEdit, fa.faTrash, fa.faShare, fa.faDownload, fa.faExpandArrowsAlt, fa.faCompressArrowsAlt, fa.faLayerGroup, fa.faExternalLinkAlt, fa.faAlignCenter, fa.faCaretSquareRight, fa.faSquare, fa.faConciergeBell, fa.faWindowRestore, fa.faFolder, fa.faMapPin, fa.faLink, fa.faFingerprint, fa.faCrosshairs, fa.faDesktop, fa.faUnlock, fa.faLock, fa.faLaptopCode, fa.faMale, diff --git a/src/client/views/nodes/SliderBox.tsx b/src/client/views/nodes/SliderBox.tsx index 00d3baf7c..2c9effe24 100644 --- a/src/client/views/nodes/SliderBox.tsx +++ b/src/client/views/nodes/SliderBox.tsx @@ -1,6 +1,6 @@ import { library } from '@fortawesome/fontawesome-svg-core'; import { faEdit } from '@fortawesome/free-regular-svg-icons'; -import { computed } from 'mobx'; +import { computed, runInAction } from 'mobx'; import { observer } from 'mobx-react'; import * as React from 'react'; import { Handles, Rail, Slider, Tracks, Ticks } from 'react-compound-slider'; @@ -16,18 +16,20 @@ import { DocComponent } from '../DocComponent'; import './SliderBox.scss'; import { Handle, TooltipRail, Track, Tick } from './SliderBox-components'; import { FieldView, FieldViewProps } from './FieldView'; +import { ScriptBox } from '../ScriptBox'; library.add(faEdit as any); -const ButtonSchema = createSchema({ - onClick: ScriptField, - buttonParams: listSpec("string"), - text: "string" +const SliderSchema = createSchema({ + _sliderMin: "number", + _sliderMax: "number", + _sliderMinThumb: "number", + _sliderMaxThumb: "number", }); -type SliderDocument = makeInterface<[typeof ButtonSchema, typeof documentSchema]>; -const SliderDocument = makeInterface(ButtonSchema, documentSchema); +type SliderDocument = makeInterface<[typeof SliderSchema, typeof documentSchema]>; +const SliderDocument = makeInterface(SliderSchema, documentSchema); @observer export class SliderBox extends DocComponent(SliderDocument) { @@ -37,23 +39,19 @@ export class SliderBox extends DocComponent(Slid @computed get dataDoc() { return this.props.DataDoc && (this.Document.isTemplateForField || BoolCast(this.props.DataDoc.isTemplateForField) || - this.props.DataDoc.layout === this.props.Document) ? this.props.DataDoc : Doc.GetProto(this.props.Document); + this.props.DataDoc.layout === this.Document) ? this.props.DataDoc : Doc.GetProto(this.Document); } specificContextMenu = (e: React.MouseEvent): void => { const funcs: ContextMenuProps[] = []; - funcs.push({ - description: "Clear Script Params", event: () => { - const params = FieldValue(this.Document.buttonParams); - params && params.map(p => this.props.Document[p] = undefined); - }, icon: "trash" - }); - - ContextMenu.Instance.addItem({ description: "OnClick...", subitems: funcs, icon: "asterisk" }); - } - onChange = (values: readonly number[]) => { - Cast(this.props.Document.onThumbChanged, ScriptField, null)?.script.run({ range: values, this: this.props.Document }) + funcs.push({ description: "Edit Thumb Change Script", icon: "edit", event: (obj: any) => ScriptBox.EditButtonScript("On Thumb Change ...", this.props.Document, "onThumbChange", obj.x, obj.y) }); + ContextMenu.Instance.addItem({ description: "Slider Funcs...", subitems: funcs, icon: "asterisk" }); } + onChange = (values: readonly number[]) => runInAction(() => { + this.Document._sliderMinThumb = values[0]; + this.Document._sliderMaxThumb = values[1]; + Cast(this.Document.onThumbChanged, ScriptField, null)?.script.run({ range: values, this: this.props.Document }) + }) render() { const domain = [NumCast(this.props.Document._sliderMin), NumCast(this.props.Document._sliderMax)] @@ -61,7 +59,7 @@ export class SliderBox extends DocComponent(Slid return (
e.stopPropagation()} style={{ boxShadow: this.Document.opacity === 0 ? undefined : StrCast(this.Document.boxShadow, "") }}> -
@@ -70,7 +68,6 @@ export class SliderBox extends DocComponent(Slid step={1} domain={domain} rootStyle={{ position: "relative", width: "100%" }} - // onUpdate={this.onUpdate} onChange={this.onChange} values={defaultValues} > diff --git a/src/new_fields/Doc.ts b/src/new_fields/Doc.ts index 3ccf4c49b..80553f334 100644 --- a/src/new_fields/Doc.ts +++ b/src/new_fields/Doc.ts @@ -804,19 +804,19 @@ export namespace Doc { if (StrCast(doc.title).endsWith("_" + prevLayout)) doc.title = StrCast(doc.title).replace("_" + prevLayout, ""); doc.layoutKey = deiconify || "layout"; } - export function setDocFilterRange(container: Doc, key: string, range?: number[]) { - const docFilters = Cast(container._docRangeFilters, listSpec("string"), []); - for (let i = 0; i < docFilters.length; i += 3) { - if (docFilters[i] === key) { - docFilters.splice(i, 3); + export function setDocFilterRange(target: Doc, key: string, range?: number[]) { + const docRangeFilters = Cast(target._docRangeFilters, listSpec("string"), []); + for (let i = 0; i < docRangeFilters.length; i += 3) { + if (docRangeFilters[i] === key) { + docRangeFilters.splice(i, 3); break; } } if (range !== undefined) { - docFilters.push(key); - docFilters.push(range[0].toString()); - docFilters.push(range[1].toString()); - container._docRangeFilters = new List(docFilters); + docRangeFilters.push(key); + docRangeFilters.push(range[0].toString()); + docRangeFilters.push(range[1].toString()); + target._docRangeFilters = new List(docRangeFilters); } } export function setDocFilter(container: Doc, key: string, value: any, modifiers?: string | number) { @@ -834,6 +834,14 @@ export namespace Doc { container._docFilter = new List(docFilters); } } + export function readDocRangeFilter(doc: Doc, key: string) { + const docRangeFilters = Cast(doc._docRangeFilters, listSpec("string"), []); + for (let i = 0; i < docRangeFilters.length; i += 3) { + if (docRangeFilters[i] === key) { + return [Number(docRangeFilters[i + 1]), Number(docRangeFilters[i + 2])]; + } + } + } } Scripting.addGlobal(function renameAlias(doc: any, n: any) { return StrCast(Doc.GetProto(doc).title).replace(/\([0-9]*\)/, "") + `(${n})`; }); @@ -859,4 +867,4 @@ Scripting.addGlobal(function selectedDocs(container: Doc, excludeCollections: bo return docs.length ? new List(docs) : prevValue; }); Scripting.addGlobal(function setDocFilter(container: Doc, key: string, value: any, modifiers?: string) { Doc.setDocFilter(container, key, value, modifiers); }); -Scripting.addGlobal(function setDocFilterRange(container: Doc, key: string, min: number, max: number) { Doc.setDocFilterRange(container, key, min, max); }); \ No newline at end of file +Scripting.addGlobal(function setDocFilterRange(container: Doc, key: string, range: number) { Doc.setDocFilterRange(container, key, range); }); \ No newline at end of file -- cgit v1.2.3-70-g09d2 From 4af6916f1f68b879e11e38b4d2a3f9a0708ac979 Mon Sep 17 00:00:00 2001 From: Sam Wilkins Date: Tue, 11 Feb 2020 06:21:39 -0500 Subject: factored out image resizing, fixed back button, importer script, tooltips on range sliders --- src/client/documents/Documents.ts | 21 +- src/client/util/SettingsManager.scss | 2 +- .../views/collections/CollectionTimeView.scss | 17 +- .../views/collections/CollectionTimeView.tsx | 12 +- src/client/views/nodes/ImageBox.tsx | 2 +- src/client/views/nodes/SliderBox-components.tsx | 10 +- src/client/views/nodes/SliderBox.tsx | 27 +- src/scraping/buxton/final/BuxtonImporter.ts | 180 ++++---- src/scraping/buxton/final/json/buxton.json | 490 ++++++++++----------- src/server/DashUploadUtils.ts | 108 +++-- 10 files changed, 447 insertions(+), 422 deletions(-) (limited to 'src/client/views/nodes/SliderBox.tsx') diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts index 027d7129e..49d1820f5 100644 --- a/src/client/documents/Documents.ts +++ b/src/client/documents/Documents.ts @@ -355,13 +355,18 @@ export namespace Docs { _LODdisable: true }); Networking.FetchFromServer("/buxton").then(response => { - const parentProto = Doc.GetProto(parent); - parentProto.data = new List(); const devices = JSON.parse(response); if (!Array.isArray(devices)) { - alert("Improper Buxton import formatting!"); + if ("error" in devices) { + loading.title = devices.error; + } else { + console.log(devices); + alert("The importer returned an unexpected import format. Check the console."); + } return; } + const parentProto = Doc.GetProto(parent); + parentProto.data = new List(); devices.forEach(device => { const { __images } = device; delete device.__images; @@ -370,9 +375,9 @@ export namespace Docs { const constructed = __images.map(relative => Utils.prepend(relative)); const deviceImages = constructed.map((url, i) => ImageDocument(url, { title: `image${i}.${extname(url)}` })); const doc = StackingDocument(deviceImages, { title: device.title, _LODdisable: true }); - const protoDoc = Doc.GetProto(doc); - protoDoc.hero = new ImageField(constructed[0]); - Docs.Get.DocumentHierarchyFromJson(device, undefined, protoDoc); + const deviceProto = Doc.GetProto(doc); + deviceProto.hero = new ImageField(constructed[0]); + Docs.Get.DocumentHierarchyFromJson(device, undefined, deviceProto); Doc.AddDocToList(parentProto, "data", doc); } }); @@ -507,10 +512,6 @@ export namespace Docs { return doc; } - export function IconDocument(icon: string, options: DocumentOptions = {}) { - return InstanceFromProto(Prototypes.get(DocumentType.ICON), new IconField(icon), options); - } - export function PdfDocument(url: string, options: DocumentOptions = {}) { return InstanceFromProto(Prototypes.get(DocumentType.PDF), new PdfField(new URL(url)), options); } diff --git a/src/client/util/SettingsManager.scss b/src/client/util/SettingsManager.scss index 7a0fb0741..6513cb223 100644 --- a/src/client/util/SettingsManager.scss +++ b/src/client/util/SettingsManager.scss @@ -1,6 +1,6 @@ @import "../views/globalCssVariables"; -.dialogue-box { +.settings-interface { background-color: whitesmoke !important; color: grey; width: 450px; diff --git a/src/client/views/collections/CollectionTimeView.scss b/src/client/views/collections/CollectionTimeView.scss index 02ef4e2d2..2dffb3ea0 100644 --- a/src/client/views/collections/CollectionTimeView.scss +++ b/src/client/views/collections/CollectionTimeView.scss @@ -1,21 +1,26 @@ -.collectionTimeView, .collectionTimeView-pivot { +.collectionTimeView, +.collectionTimeView-pivot { display: flex; flex-direction: row; position: absolute; height: 100%; width: 100%; overflow: hidden; + .collectionTimeView-backBtn { background: green; display: inline; margin-right: 20px; } + .collectionFreeform-customText { text-align: left; } + .collectionFreeform-customDiv { position: absolute; } + .collectionTimeView-thumb { position: absolute; width: 30px; @@ -28,14 +33,17 @@ border-radius: 9px; opacity: 0.25; } + .collectionTimeView-thumb-min { - margin-left:25%; + margin-left: 25%; } + .collectionTimeView-thumb-max { - margin-left:75%; + margin-left: 75%; } + .collectionTimeView-thumb-mid { - margin-left:50%; + margin-left: 50%; } .collectionTimeView-flyout { @@ -118,6 +126,7 @@ left: -10px; } } + .collectionTimeView-pivot { .collectionFreeform-customText { text-align: center; diff --git a/src/client/views/collections/CollectionTimeView.tsx b/src/client/views/collections/CollectionTimeView.tsx index db176d0bc..808144c18 100644 --- a/src/client/views/collections/CollectionTimeView.tsx +++ b/src/client/views/collections/CollectionTimeView.tsx @@ -46,7 +46,7 @@ export class CollectionTimeView extends CollectionSubView(doc => doc) { this.props.Document._fitToBox = true; } if (!this.props.Document.onViewDefClick) { - this.props.Document.onViewDefDivClick = ScriptField.MakeScript("pivotColumnClick(this,payload)", { payload: "any" }) + this.props.Document.onViewDefDivClick = ScriptField.MakeScript("pivotColumnClick(this,payload)", { payload: "any" }); } } @@ -164,7 +164,7 @@ export class CollectionTimeView extends CollectionSubView(doc => doc) { typeof (pair.layout[fieldKey]) === "string").map(fieldKey => keySet.add(fieldKey))); Array.from(keySet).map(fieldKey => docItems.push({ description: ":" + fieldKey, event: () => this.props.Document._pivotField = fieldKey, icon: "compress-arrows-alt" })); - docItems.push({ description: ":(null)", event: () => this.props.Document._pivotField = undefined, icon: "compress-arrows-alt" }) + docItems.push({ description: ":(null)", event: () => this.props.Document._pivotField = undefined, icon: "compress-arrows-alt" }); ContextMenu.Instance.addItem({ description: "Pivot Fields ...", subitems: docItems, icon: "eye" }); const pt = this.props.ScreenToLocalTransform().inverse().transformPoint(x, y); ContextMenu.Instance.displayMenu(x, y, ":"); @@ -282,9 +282,9 @@ export class CollectionTimeView extends CollectionSubView(doc => doc) { const layoutItems: ContextMenuProps[] = []; const doc = this.props.Document; - layoutItems.push({ description: "Force Timeline", event: () => { doc._forceRenderEngine = "timeline" }, icon: "compress-arrows-alt" }); - layoutItems.push({ description: "Force Pivot", event: () => { doc._forceRenderEngine = "pivot" }, icon: "compress-arrows-alt" }); - layoutItems.push({ description: "Auto Time/Pivot layout", event: () => { doc._forceRenderEngine = undefined }, icon: "compress-arrows-alt" }); + layoutItems.push({ description: "Force Timeline", event: () => { doc._forceRenderEngine = "timeline"; }, icon: "compress-arrows-alt" }); + layoutItems.push({ description: "Force Pivot", event: () => { doc._forceRenderEngine = "pivot"; }, icon: "compress-arrows-alt" }); + layoutItems.push({ description: "Auto Time/Pivot layout", event: () => { doc._forceRenderEngine = undefined; }, icon: "compress-arrows-alt" }); layoutItems.push({ description: "Sync with presentation", event: () => CollectionTimeView.SyncTimelineToPresentation(doc), icon: "compress-arrows-alt" }); ContextMenu.Instance.addItem({ description: "Pivot/Time Options ...", subitems: layoutItems, icon: "eye" }); @@ -331,7 +331,7 @@ export class CollectionTimeView extends CollectionSubView(doc => doc) {
-