diff options
author | bobzel <zzzman@gmail.com> | 2021-02-16 23:58:54 -0500 |
---|---|---|
committer | bobzel <zzzman@gmail.com> | 2021-02-16 23:58:54 -0500 |
commit | 1a31f3ae5d1b90deb9888bb4df863079f4837f53 (patch) | |
tree | 3af8e0ce5a68b3ef4e46ee2e6b49d88f5b208a49 /src | |
parent | 05b87c394731fbed21f9b358967c337ce294272d (diff) |
added a file system mode for tree View. ctrl-f to create file system.
Diffstat (limited to 'src')
-rw-r--r-- | src/client/documents/Documents.ts | 3 | ||||
-rw-r--r-- | src/client/util/CurrentUserUtils.ts | 2 | ||||
-rw-r--r-- | src/client/views/collections/CollectionTreeView.tsx | 9 | ||||
-rw-r--r-- | src/client/views/collections/TreeView.tsx | 34 | ||||
-rw-r--r-- | src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx | 2 | ||||
-rw-r--r-- | src/client/views/collections/collectionFreeForm/MarqueeView.tsx | 12 | ||||
-rw-r--r-- | src/client/views/nodes/formattedText/ProsemirrorExampleTransfer.ts | 2 | ||||
-rw-r--r-- | src/fields/Doc.ts | 2 | ||||
-rw-r--r-- | src/fields/documentSchemas.ts | 2 |
9 files changed, 50 insertions, 18 deletions
diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts index 7502aa685..2d8601dfe 100644 --- a/src/client/documents/Documents.ts +++ b/src/client/documents/Documents.ts @@ -144,6 +144,7 @@ export interface DocumentOptions { _layers?: List<string>; _raiseWhenDragged?: boolean; // whether a document is brought to front when dragged. isLinkButton?: boolean; + isFolder?: boolean; _columnWidth?: number; _fontSize?: string; _fontWeight?: number; @@ -211,7 +212,7 @@ export interface DocumentOptions { treeViewExpandedView?: string; // which field/thing is displayed when this item is opened in tree view treeViewChecked?: ScriptField; // script to call when a tree view checkbox is checked treeViewTruncateTitleWidth?: number; - treeViewOutlineMode?: boolean; // whether slide should function as a text outline + treeViewType?: string; // whether treeview is a Slide, file system, or (default) collection hierarchy treeViewLockExpandedView?: boolean; // whether the expanded view can be changed treeViewDefaultExpandedView?: string; // default expanded view sidebarColor?: string; // background color of text sidebar diff --git a/src/client/util/CurrentUserUtils.ts b/src/client/util/CurrentUserUtils.ts index 053b16d76..509f08e9d 100644 --- a/src/client/util/CurrentUserUtils.ts +++ b/src/client/util/CurrentUserUtils.ts @@ -378,7 +378,7 @@ export class CurrentUserUtils { ((doc.emptyPane as Doc).proto as Doc)["dragFactory-count"] = 0; } if (doc.emptySlide === undefined) { - const textDoc = Docs.Create.TreeDocument([], { title: "Slide", _viewType: CollectionViewType.Tree, _fontSize: "20px", treeViewOutlineMode: true, _xMargin: 0, _yMargin: 0, _width: 300, _height: 200, _singleLine: true, _backgroundColor: "transparent", system: true, cloneFieldFilter: new List<string>(["system"]) }); + const textDoc = Docs.Create.TreeDocument([], { title: "Slide", _viewType: CollectionViewType.Tree, _fontSize: "20px", treeViewType: "outline", _xMargin: 0, _yMargin: 0, _width: 300, _height: 200, _singleLine: true, _backgroundColor: "transparent", system: true, cloneFieldFilter: new List<string>(["system"]) }); Doc.GetProto(textDoc).title = ComputedField.MakeFunction('self.text?.Text'); FormattedTextBox.SelectOnLoad = textDoc[Id]; doc.emptySlide = textDoc; diff --git a/src/client/views/collections/CollectionTreeView.tsx b/src/client/views/collections/CollectionTreeView.tsx index bbe6cfdcb..092606fdf 100644 --- a/src/client/views/collections/CollectionTreeView.tsx +++ b/src/client/views/collections/CollectionTreeView.tsx @@ -140,8 +140,11 @@ export class CollectionTreeView extends CollectionSubView<Document, Partial<coll height={"auto"} GetValue={() => StrCast(this.dataDoc.title)} SetValue={undoBatch((value: string, shift: boolean, enter: boolean) => { - if (this.props.Document.treeViewOutlineMode && enter) { - this.makeTextCollection(childDocs); + if (enter) { + switch (this.props.Document.treeViewType) { + case "outline": this.makeTextCollection(childDocs); break; + case "fileSystem": break; + } } return Doc.SetInPlace(this.dataDoc, "title", value, false); })} />; @@ -209,7 +212,7 @@ export class CollectionTreeView extends CollectionSubView<Document, Partial<coll } @computed get titleBar() { const hideTitle = this.props.treeViewHideTitle || this.doc.treeViewHideTitle; - return hideTitle ? (null) : (this.doc.treeViewOutlineMode ? this.documentTitle : this.editableTitle)(this.treeChildren); + return hideTitle ? (null) : (this.doc.treeViewType === "outline" ? this.documentTitle : this.editableTitle)(this.treeChildren); } render() { TraceMobx(); diff --git a/src/client/views/collections/TreeView.tsx b/src/client/views/collections/TreeView.tsx index d7198ee7c..770623fcf 100644 --- a/src/client/views/collections/TreeView.tsx +++ b/src/client/views/collections/TreeView.tsx @@ -100,14 +100,16 @@ export class TreeView extends React.Component<TreeViewProps> { if (this.props.treeViewPreventOpen) this._overrideTreeViewOpen = c; else this.doc.treeViewOpen = this._overrideTreeViewOpen = c; } - @computed get outlineMode() { return this.props.treeView.doc.treeViewOutlineMode; } + @computed get outlineMode() { return this.props.treeView.doc.treeViewType === "outline"; } + @computed get fileSysMode() { return this.props.treeView.doc.treeViewType === "fileSystem"; } @computed get treeViewOpen() { return (!this.props.treeViewPreventOpen && !this.doc.treeViewPreventOpen && BoolCast(this.doc.treeViewOpen)) || this._overrideTreeViewOpen; } - @computed get treeViewExpandedView() { return StrCast(this.doc.treeViewExpandedView, this.treeViewDefaultExpandedView); } + @computed get treeViewExpandedView() { return this.fileSysMode ? this.fieldKey : StrCast(this.doc.treeViewExpandedView, this.treeViewDefaultExpandedView); } @computed get MAX_EMBED_HEIGHT() { return NumCast(this.props.containingCollection.maxEmbedHeight, 200); } @computed get dataDoc() { return this.doc[DataSym]; } @computed get layoutDoc() { return Doc.Layout(this.doc); } @computed get fieldKey() { TraceMobx(); const splits = StrCast(Doc.LayoutField(this.doc)).split("fieldKey={\'"); return splits.length > 1 ? splits[1].split("\'")[0] : "data"; } childDocList(field: string) { + if (this.fileSysMode && !this.doc.isFolder) return [] as Doc[]; const layout = Doc.LayoutField(this.doc) instanceof Doc ? Doc.LayoutField(this.doc) as Doc : undefined; return ((this.props.dataDoc ? DocListCastOrNull(this.props.dataDoc[field]) : undefined) || // if there's a data doc for an expanded template, use it's data field (layout ? DocListCastOrNull(layout[field]) : undefined) || // else if there's a layout doc, display it's fields @@ -138,8 +140,8 @@ export class TreeView extends React.Component<TreeViewProps> { const titleScript = ScriptField.MakeScript(`{setInPlace(self, 'editTitle', '${this._uniqueId}'); documentView.select();} `, { documentView: "any" }); const openScript = ScriptField.MakeScript(`openOnRight(self)`); const treeOpenScript = ScriptField.MakeScript(`self.treeViewOpen = !self.treeViewOpen`); - this._editTitleScript = !Doc.IsSystem(this.props.document) ? titleScript && (() => titleScript) : treeOpenScript && (() => treeOpenScript); - this._openScript = !Doc.IsSystem(this.props.document) ? openScript && (() => openScript) : undefined; + this._editTitleScript = !Doc.IsSystem(this.props.document) || props.document.isFolder ? titleScript && (() => titleScript) : treeOpenScript && (() => treeOpenScript); + this._openScript = !Doc.IsSystem(this.props.document) || props.document.isFolder ? openScript && (() => openScript) : undefined; if (Doc.GetT(this.props.document, "editTitle", "string", true) === "*") Doc.SetInPlace(this.props.document, "editTitle", this._uniqueId, false); } @@ -192,7 +194,7 @@ export class TreeView extends React.Component<TreeViewProps> { const bullet = Docs.Create.TextDocument("-text-", { layout: CollectionView.LayoutString("data"), title: "-title-", "sidebarColor": "transparent", "sidebarViewType": CollectionViewType.Freeform, - _viewType: CollectionViewType.Tree, hideLinkButton: true, _showSidebar: true, treeViewOutlineMode: true, + _viewType: CollectionViewType.Tree, hideLinkButton: true, _showSidebar: true, treeViewType: "outline", x: 0, y: 0, _xMargin: 0, _yMargin: 0, _autoHeight: true, _singleLine: true, _backgroundColor: "transparent", _width: 1000, _height: 10 }); Doc.GetProto(bullet).title = ComputedField.MakeFunction('self.text?.Text'); @@ -209,6 +211,13 @@ export class TreeView extends React.Component<TreeViewProps> { bullet.context = this.props.treeView.Document; return added; } + makeFolder = () => { + Doc.SetInPlace(this.doc, "editTitle", undefined, false); + const folder = Docs.Create.FreeformDocument([], { title: "-folder-", _stayInCollection: true, isFolder: true, system: true }); + const added = this.props.addDocument(folder); + folder.context = this.props.treeView.Document; + return added; + } editableView = (key: string, style?: string) => (<EditableView oneLine={true} @@ -220,10 +229,17 @@ export class TreeView extends React.Component<TreeViewProps> { fontStyle={style} fontSize={12} GetValue={() => StrCast(this.doc[key])} + OnFillDown={(value) => { + if (this.fileSysMode) { + this.makeFolder(); + } + }} SetValue={undoBatch((value: string, shiftKey: boolean, enterKey: boolean) => { Doc.SetInPlace(this.doc, key, value, false); if (this.outlineMode && enterKey) { this.makeTextCollection(); + } else if (this.fileSysMode && enterKey) { + // add folder } else { Doc.SetInPlace(this.doc, "editTitle", undefined, false); } @@ -232,7 +248,7 @@ export class TreeView extends React.Component<TreeViewProps> { SelectionManager.DeselectAll(); return false; }} - OnEmpty={undoBatch(() => this.props.treeView.doc.treeViewOutlineMode && this.props.removeDoc?.(this.doc))} + OnEmpty={undoBatch(() => this.outlineMode && this.props.removeDoc?.(this.doc))} OnTab={undoBatch((shift?: boolean) => { shift ? this.props.outdentDocument?.() : this.props.indentDocument?.(); setTimeout(() => Doc.SetInPlace(this.doc, "editTitle", `${this.props.treeView._uniqueId}`, false), 0); @@ -249,7 +265,7 @@ export class TreeView extends React.Component<TreeViewProps> { const pt = [de.x, de.y]; const rect = this._header!.current!.getBoundingClientRect(); const before = pt[1] < rect.top + rect.height / 2; - const inside = pt[0] > Math.min(rect.left + 75, rect.left + rect.width * .75) || (!before && this.treeViewOpen && this.childDocList.length); + const inside = this.fileSysMode && !this.doc.isFolder ? false : pt[0] > Math.min(rect.left + 75, rect.left + rect.width * .75) || (!before && this.treeViewOpen && this.childDocList.length); if (de.complete.linkDragData) { const sourceDoc = de.complete.linkDragData.linkSourceDocument; const destDoc = this.doc; @@ -435,7 +451,7 @@ export class TreeView extends React.Component<TreeViewProps> { checked: this.doc.treeViewChecked === "check" ? "x" : this.doc.treeViewChecked === "x" ? undefined : "check", containingTreeView: this.props.treeView.props.Document, }, console.log); - } else { + } else if (!this.fileSysMode || this.doc.isFolder) { this.treeViewOpen = !this.treeViewOpen; } e.stopPropagation(); @@ -495,7 +511,7 @@ export class TreeView extends React.Component<TreeViewProps> { contextMenuItems = () => Doc.IsSystem(this.doc) ? [] : [{ script: ScriptField.MakeFunction(`openOnRight(self)`)!, label: "Open" }, { script: ScriptField.MakeFunction(`DocFocus(self)`)!, label: "Focus" }]; truncateTitleWidth = () => NumCast(this.props.treeView.props.Document.treeViewTruncateTitleWidth, this.props.panelWidth()); onChildClick = () => this.props.onChildClick?.() ?? (this._editTitleScript?.() || ScriptCast(this.doc.treeChildClick)); - onChildDoubleClick = () => (!this.outlineMode && this._openScript?.()) || ScriptCast(this.doc.treeChildDoubleClick); + onChildDoubleClick = () => (!this.props.treeView.doc.treeViewType && this._openScript?.()) || ScriptCast(this.doc.treeChildDoubleClick); refocus = () => this.props.treeView.props.focus(this.props.treeView.props.Document); ignoreEvent = (e: any) => { diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx index a5d7489bd..3ca2258ee 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx @@ -817,7 +817,7 @@ export class CollectionFreeFormView extends CollectionSubView<PanZoomDocument, P @action onPointerWheel = (e: React.WheelEvent): void => { - if (this.layoutDoc._lockedTransform || CurrentUserUtils.OverlayDocs.includes(this.props.Document) || this.props.Document.treeViewOutlineMode) return; + if (this.layoutDoc._lockedTransform || CurrentUserUtils.OverlayDocs.includes(this.props.Document) || this.props.Document.treeViewOutlineMode === "outline") return; if (!e.ctrlKey && this.props.Document.scrollHeight !== undefined) { // things that can scroll vertically should do that instead of zooming e.stopPropagation(); } diff --git a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx index f7fb2b83d..21c9711b3 100644 --- a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx +++ b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx @@ -132,6 +132,18 @@ export class MarqueeView extends React.Component<SubCollectionViewProps & Marque }); })(); e.stopPropagation(); + } else if (e.key === "f" && e.ctrlKey) { + e.preventDefault(); + const root = Docs.Create.FreeformDocument([], { title: "folder", _stayInCollection: true, system: true, isFolder: true }); + const folder = Docs.Create.TreeDocument([root], { title: "root", isFolder: true, treeViewType: "fileSystem" }); + Doc.GetProto(folder).isFolder = true; + folder.x = x; + folder.y = y; + folder._width = 200; + folder._height = 300; + this.props.addDocument?.(folder); + //setTimeout(() => SelectionManager.SelectDoc(DocumentManager.Instance.getDocumentView(slide)!, false)); + e.stopPropagation(); } else if (e.key === "b" && e.ctrlKey) { // e.preventDefault(); // navigator.clipboard.readText().then(text => { diff --git a/src/client/views/nodes/formattedText/ProsemirrorExampleTransfer.ts b/src/client/views/nodes/formattedText/ProsemirrorExampleTransfer.ts index 8d9d36580..243cfc6de 100644 --- a/src/client/views/nodes/formattedText/ProsemirrorExampleTransfer.ts +++ b/src/client/views/nodes/formattedText/ProsemirrorExampleTransfer.ts @@ -49,7 +49,7 @@ export function buildKeymap<S extends Schema<any>>(schema: S, props: any, mapKey /// bcz; Argh!! replace with an onEnter func that conditionally handles Enter const addTextBox = (below: boolean, force?: boolean) => { - if (props.Document.treeViewOutlineMode) return true; // bcz: Arghh .. need to determine if this is an treeViewOutlineBox in which case Enter's are ignored.. + if (props.Document.treeViewType === "outline") return true; // bcz: Arghh .. need to determine if this is an treeViewOutlineBox in which case Enter's are ignored.. const layoutDoc = props.Document; const originalDoc = layoutDoc.rootDocument || layoutDoc; if (force || props.Document._singleLine) { diff --git a/src/fields/Doc.ts b/src/fields/Doc.ts index 56b2db48e..da95c3605 100644 --- a/src/fields/Doc.ts +++ b/src/fields/Doc.ts @@ -1147,7 +1147,7 @@ export namespace Doc { case DocumentType.IMG: return "image"; case DocumentType.COMPARISON: return "columns"; case DocumentType.RTF: return "sticky-note"; - case DocumentType.COL: return "folder"; + case DocumentType.COL: return !doc.isFolder ? "folder" : "chevron-right"; case DocumentType.WEB: return "globe-asia"; case DocumentType.SCREENSHOT: return "photo-video"; case DocumentType.WEBCAM: return "video"; diff --git a/src/fields/documentSchemas.ts b/src/fields/documentSchemas.ts index df3dd1eb4..6973079b0 100644 --- a/src/fields/documentSchemas.ts +++ b/src/fields/documentSchemas.ts @@ -81,7 +81,7 @@ export const documentSchema = createSchema({ treeViewLockExpandedView: "boolean", // whether the expanded view can be changed treeViewDefaultExpandedView: "string", // name of field whose contents are displayed by default treeViewPreventOpen: "boolean", // ignores the treeViewOpen flag (for allowing a view to not be slaved to other views of the document) - treeViewOutlineMode: "boolean", // whether tree view is an outline and clicks edit document titles immediately since double-click opening is turned off + treeViewType: "string", // whether tree view is an outline, file syste or (default) hierarchy. For outline, clicks edit document titles immediately since double-click opening is turned off // interaction and linking properties ignoreClick: "boolean", // whether documents ignores input clicks (but does not ignore manipulation and other events) |