diff options
author | geireann <geireann.lindfield@gmail.com> | 2021-08-27 14:19:25 -0400 |
---|---|---|
committer | geireann <geireann.lindfield@gmail.com> | 2021-08-27 14:19:25 -0400 |
commit | be4fd2492ad706f30af28f33133a4df0e8049e12 (patch) | |
tree | e33b32f54be50122ed16c07d2b6f6b2e79239cb4 /src/client/views/collections/CollectionTreeView.tsx | |
parent | c5e96c72fcf149b9bcfe5f7f7a9c714de1d5fd9a (diff) | |
parent | 7c83bc30b3a6ed6061ef68bcef6a0e8941668b3c (diff) |
Merge branch 'master' into schema-view-En-Hua
Diffstat (limited to 'src/client/views/collections/CollectionTreeView.tsx')
-rw-r--r-- | src/client/views/collections/CollectionTreeView.tsx | 61 |
1 files changed, 42 insertions, 19 deletions
diff --git a/src/client/views/collections/CollectionTreeView.tsx b/src/client/views/collections/CollectionTreeView.tsx index 82c8a9114..89d42439e 100644 --- a/src/client/views/collections/CollectionTreeView.tsx +++ b/src/client/views/collections/CollectionTreeView.tsx @@ -1,15 +1,16 @@ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; -import { action, computed, reaction, IReactionDisposer, observable } from "mobx"; +import { action, computed, IReactionDisposer, observable, reaction } from "mobx"; import { observer } from "mobx-react"; -import { DataSym, Doc, DocListCast, HeightSym, Opt, WidthSym } from '../../../fields/Doc'; +import { DataSym, Doc, DocListCast, HeightSym, Opt, StrListCast, WidthSym } from '../../../fields/Doc'; import { Id } from '../../../fields/FieldSymbols'; -import { List } from '../../../fields/List'; -import { Document } from '../../../fields/Schema'; +import { InkTool } from '../../../fields/InkField'; +import { Document, listSpec } from '../../../fields/Schema'; import { ScriptField } from '../../../fields/ScriptField'; import { BoolCast, Cast, NumCast, ScriptCast, StrCast } from '../../../fields/Types'; import { TraceMobx } from '../../../fields/util'; import { returnEmptyDoclist, returnEmptyFilter, returnFalse, returnTrue } from '../../../Utils'; import { DocUtils } from '../../documents/Documents'; +import { CurrentUserUtils } from '../../util/CurrentUserUtils'; import { DocumentManager } from '../../util/DocumentManager'; import { DragManager, dropActionType } from "../../util/DragManager"; import { SelectionManager } from '../../util/SelectionManager'; @@ -25,8 +26,6 @@ import { CollectionSubView } from "./CollectionSubView"; import "./CollectionTreeView.scss"; import { TreeView } from "./TreeView"; import React = require("react"); -import { InkTool } from '../../../fields/InkField'; -import { CurrentUserUtils } from '../../util/CurrentUserUtils'; const _global = (window /* browser */ || global /* node */) as any; export type collectionTreeViewProps = { @@ -52,6 +51,7 @@ export class CollectionTreeView extends CollectionSubView<Document, Partial<coll @computed get treeChildren() { TraceMobx(); return this.props.childDocuments || this.childDocs; } @computed get outlineMode() { return this.doc.treeViewType === "outline"; } @computed get fileSysMode() { return this.doc.treeViewType === "fileSystem"; } + @computed get dashboardMode() { return this.doc === Doc.UserDoc().myDashboards; } // these should stay in synch with counterparts in DocComponent.ts ViewBoxAnnotatableComponent @observable _isAnyChildContentActive = false; @@ -61,7 +61,9 @@ export class CollectionTreeView extends CollectionSubView<Document, Partial<coll this.props.isSelected(outsideReaction) || this._isAnyChildContentActive || this.props.rootSelected(outsideReaction)) ? true : false) + isDisposing = false; componentWillUnmount() { + this.isDisposing = true; super.componentWillUnmount(); this.treedropDisposer?.(); Object.values(this._disposers).forEach(disposer => disposer?.()); @@ -76,15 +78,16 @@ export class CollectionTreeView extends CollectionSubView<Document, Partial<coll refList: Set<any> = new Set(); observer: any; computeHeight = () => { - const hgt = this.paddingTop() + 26/* bcz: ugh: title bar height hack ... get ref and compute instead */ + - Array.from(this.refList).reduce((p, r) => p + Number(getComputedStyle(r).height.replace("px", "")), 0); - this.props.setHeight(hgt); + if (this.isDisposing) return; + const bodyHeight = Array.from(this.refList).reduce((p, r) => p + Number(getComputedStyle(r).height.replace("px", "")), this.paddingTop() + this.paddingBot()); + this.layoutDoc._autoHeightMargins = bodyHeight; + this.props.setHeight(this.documentTitleHeight() + bodyHeight); } unobserveHeight = (ref: any) => { this.refList.delete(ref); this.rootDoc.autoHeight && this.computeHeight(); } - observerHeight = (ref: any) => { + observeHeight = (ref: any) => { if (ref) { this.refList.add(ref); this.observer = new _global.ResizeObserver(action((entries: any) => { @@ -154,7 +157,7 @@ export class CollectionTreeView extends CollectionSubView<Document, Partial<coll !existingOnClick && ContextMenu.Instance.addItem({ description: "OnClick...", noexpand: true, subitems: onClicks, icon: "mouse-pointer" }); } } - onTreeDrop = (e: React.DragEvent) => this.onExternalDrop(e, {}); + onTreeDrop = (e: React.DragEvent, addDocs?: (docs: Doc[]) => void) => this.onExternalDrop(e, {}, addDocs); @undoBatch makeTextCollection = (childDocs: Doc[]) => { @@ -199,6 +202,7 @@ export class CollectionTreeView extends CollectionSubView<Document, Partial<coll NativeWidth={this.documentTitleWidth} NativeHeight={this.documentTitleHeight} focus={this.props.focus} + treeViewDoc={this.props.Document} ScreenToLocalTransform={this.titleTransform} docFilters={returnEmptyFilter} docRangeFilters={returnEmptyFilter} @@ -215,6 +219,11 @@ export class CollectionTreeView extends CollectionSubView<Document, Partial<coll /> </div>; } + childContextMenuItems = () => { + const customScripts = Cast(this.doc.childContextMenuScripts, listSpec(ScriptField), []); + const filterScripts = Cast(this.doc.childContextMenuFilters, listSpec(ScriptField), []); + return StrListCast(this.doc.childContextMenuLabels).map((label, i) => ({ script: customScripts[i], filter: filterScripts[i], label })); + } @computed get treeViewElements() { TraceMobx(); const dropAction = StrCast(this.doc.childDropAction) as dropActionType; @@ -246,12 +255,14 @@ export class CollectionTreeView extends CollectionSubView<Document, Partial<coll true, this.whenChildContentsActiveChanged, this.props.dontRegisterView || Cast(this.props.Document.childDontRegisterViews, "boolean", null), - this.observerHeight, - this.unobserveHeight); + this.observeHeight, + this.unobserveHeight, + this.childContextMenuItems() + ); } @computed get titleBar() { const hideTitle = this.props.treeViewHideTitle || this.doc.treeViewHideTitle; - return hideTitle ? (null) : (this.doc.treeViewType === "outline" ? this.documentTitle : this.editableTitle)(this.treeChildren); + return hideTitle ? (null) : (this.outlineMode ? this.documentTitle : this.editableTitle)(this.treeChildren); } @computed get renderClearButton() { @@ -261,30 +272,42 @@ export class CollectionTreeView extends CollectionSubView<Document, Partial<coll </button> </div >; } + @computed get nativeWidth() { return Doc.NativeWidth(this.Document, undefined, true); } + @computed get nativeHeight() { return Doc.NativeHeight(this.Document, undefined, true); } + @computed get contentScaling() { + const nw = this.nativeWidth; + const nh = this.nativeHeight; + const hscale = nh ? this.props.PanelHeight() / nh : 1; + const wscale = nw ? this.props.PanelWidth() / nw : 1; + return wscale < hscale ? wscale : hscale; + } paddingX = () => NumCast(this.doc._xPadding, 15); paddingTop = () => NumCast(this.doc._yPadding, 20); + paddingBot = () => NumCast(this.doc._yPadding, 20); documentTitleWidth = () => Math.min(this.layoutDoc?.[WidthSym](), this.panelWidth()); - documentTitleHeight = () => Math.min(this.layoutDoc?.[HeightSym](), (StrCast(this.layoutDoc?._fontSize) ? Number(StrCast(this.layoutDoc?._fontSize, "32px").replace("px", "")) : NumCast(this.layoutDoc?._fontSize)) * 2); + documentTitleHeight = () => (this.layoutDoc?.[HeightSym]() || 0) - NumCast(this.layoutDoc.autoHeightMargins); titleTransform = () => this.props.ScreenToLocalTransform().translate(-NumCast(this.doc._xPadding, 10), -NumCast(this.doc._yPadding, 20)); truncateTitleWidth = () => this.treeViewtruncateTitleWidth; onChildClick = () => this.props.onChildClick?.() || ScriptCast(this.doc.onChildClick); - panelWidth = () => this.props.PanelWidth() - 2 * this.paddingX(); + panelWidth = () => (this.props.PanelWidth() - 2 * this.paddingX()) * (this.props.scaling?.() || 1); render() { TraceMobx(); const background = () => this.props.styleProvider?.(this.doc, this.props, StyleProp.BackgroundColor); const pointerEvents = () => !this.props.isContentActive() && !SnappingManager.GetIsDragging() ? "none" : undefined; return !(this.doc instanceof Doc) || !this.treeChildren ? (null) : - <div className="collectionTreeView-container" onContextMenu={this.onContextMenu}> + <div className="collectionTreeView-container" + style={this.outlineMode ? { transform: `scale(${this.contentScaling})`, width: `calc(${100 / this.contentScaling}%)` } : {}} + onContextMenu={this.onContextMenu}> <div className="collectionTreeView-dropTarget" - style={{ background: background(), paddingLeft: `${this.paddingX()}px`, paddingRight: `${this.paddingX()}px`, paddingTop: `${this.paddingTop()}px`, pointerEvents: pointerEvents() }} + style={{ background: background(), paddingLeft: `${this.paddingX()}px`, paddingRight: `${this.paddingX()}px`, paddingBottom: `${this.paddingBot()}px`, paddingTop: `${this.paddingTop()}px`, pointerEvents: pointerEvents() }} onWheel={e => e.stopPropagation()} onDrop={this.onTreeDrop} ref={this.createTreeDropTarget}> {this.titleBar} {this.renderClearButton} - <ul className="no-indent"> + <ul className={`no-indent${this.outlineMode ? "-outline" : ""}`} > {this.treeViewElements} </ul> </div > |