diff options
author | bobzel <zzzman@gmail.com> | 2021-04-05 12:22:20 -0400 |
---|---|---|
committer | bobzel <zzzman@gmail.com> | 2021-04-05 12:22:20 -0400 |
commit | b8ffb911300ea8b7bf589bcafd15e84a8f7f4db9 (patch) | |
tree | b359af8daaf7c53a3a5ba76cede0b9fcc1d856ac | |
parent | ee17752109ba1238d645a4df7cee1cf60855f8df (diff) |
added autoHeight for tree views.
-rw-r--r-- | src/client/views/PropertiesButtons.tsx | 3 | ||||
-rw-r--r-- | src/client/views/collections/CollectionStackingView.tsx | 2 | ||||
-rw-r--r-- | src/client/views/collections/CollectionTreeView.tsx | 40 | ||||
-rw-r--r-- | src/client/views/collections/TreeView.tsx | 19 |
4 files changed, 53 insertions, 11 deletions
diff --git a/src/client/views/PropertiesButtons.tsx b/src/client/views/PropertiesButtons.tsx index e1c0b96c0..5c41a96d0 100644 --- a/src/client/views/PropertiesButtons.tsx +++ b/src/client/views/PropertiesButtons.tsx @@ -188,6 +188,7 @@ export class PropertiesButtons extends React.Component<{}, {}> { const isCollection = this.selectedDoc?.type === DocumentType.COL; const isStacking = this.selectedDoc?._viewType === CollectionViewType.Stacking; const isFreeForm = this.selectedDoc?._viewType === CollectionViewType.Freeform; + const isTree = this.selectedDoc?._viewType === CollectionViewType.Tree; const toggle = (ele: JSX.Element | null, style?: React.CSSProperties) => <div className="propertiesButtons-button" style={style}> {ele} </div>; return !this.selectedDoc ? (null) : @@ -199,7 +200,7 @@ export class PropertiesButtons extends React.Component<{}, {}> { {toggle(this.onClickButton)} {toggle(this.fitWidthButton)} {toggle(this.fitContentButton, { display: !isFreeForm ? "none" : "" })} - {toggle(this.autoHeightButton, { display: !isText && !isStacking ? "none" : "" })} + {toggle(this.autoHeightButton, { display: !isText && !isStacking && !isTree ? "none" : "" })} {toggle(this.maskButton, { display: !isInk ? "none" : "" })} {toggle(this.chromeButton, { display: isCollection ? "" : "none" })} {toggle(this.gridButton, { display: isCollection ? "" : "none" })} diff --git a/src/client/views/collections/CollectionStackingView.tsx b/src/client/views/collections/CollectionStackingView.tsx index cc5a41c72..8d8c69fd5 100644 --- a/src/client/views/collections/CollectionStackingView.tsx +++ b/src/client/views/collections/CollectionStackingView.tsx @@ -23,7 +23,6 @@ import { EditableView } from "../EditableView"; import { LightboxView } from "../LightboxView"; import { CollectionFreeFormDocumentView } from "../nodes/CollectionFreeFormDocumentView"; import { DocFocusOptions, DocumentView, DocumentViewProps, ViewAdjustment } from "../nodes/DocumentView"; -import { FieldViewProps } from "../nodes/FieldView"; import { StyleProp } from "../StyleProvider"; import { CollectionMasonryViewFieldRow } from "./CollectionMasonryViewFieldRow"; import "./CollectionStackingView.scss"; @@ -400,7 +399,6 @@ export class CollectionStackingView extends CollectionSubView<StackingDocument, observeHeight={ref => { if (ref) { this.refList.push(ref); - const doc = this.props.DataDoc && this.props.DataDoc.layout === this.layoutDoc ? this.props.DataDoc : this.layoutDoc; this.observer = new _global.ResizeObserver(action((entries: any) => { if (this.layoutDoc._autoHeight && ref && this.refList.length && !SnappingManager.GetIsDragging()) { const height = this.headerMargin + diff --git a/src/client/views/collections/CollectionTreeView.tsx b/src/client/views/collections/CollectionTreeView.tsx index ed0ed63b3..b97d11629 100644 --- a/src/client/views/collections/CollectionTreeView.tsx +++ b/src/client/views/collections/CollectionTreeView.tsx @@ -1,5 +1,5 @@ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; -import { action, computed } from "mobx"; +import { action, computed, reaction, IReactionDisposer } from "mobx"; import { observer } from "mobx-react"; import { DataSym, Doc, DocListCast, HeightSym, Opt, WidthSym } from '../../../fields/Doc'; import { Id } from '../../../fields/FieldSymbols'; @@ -8,7 +8,7 @@ import { Document } 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, Utils } from '../../../Utils'; +import { returnEmptyDoclist, returnEmptyFilter, returnFalse, returnTrue } from '../../../Utils'; import { DocUtils } from '../../documents/Documents'; import { DocumentManager } from '../../util/DocumentManager'; import { DragManager, dropActionType } from "../../util/DragManager"; @@ -25,6 +25,7 @@ import { CollectionSubView } from "./CollectionSubView"; import "./CollectionTreeView.scss"; import { TreeView } from "./TreeView"; import React = require("react"); +const _global = (window /* browser */ || global /* node */) as any; export type collectionTreeViewProps = { treeViewExpandedView?: "fields" | "layout" | "links" | "data"; @@ -40,6 +41,7 @@ export type collectionTreeViewProps = { export class CollectionTreeView extends CollectionSubView<Document, Partial<collectionTreeViewProps>>(Document) { private treedropDisposer?: DragManager.DragDropDisposer; private _mainEle?: HTMLDivElement; + private _disposers: { [name: string]: IReactionDisposer } = {}; MainEle = () => this._mainEle; @computed get doc() { return this.props.Document; } @computed get dataDoc() { return this.props.DataDoc || this.doc; } @@ -51,8 +53,34 @@ export class CollectionTreeView extends CollectionSubView<Document, Partial<coll componentWillUnmount() { super.componentWillUnmount(); this.treedropDisposer?.(); + Object.values(this._disposers).forEach(disposer => disposer?.()); } + componentWillMount() { + this._disposers.autoheight = reaction(() => this.rootDoc.autoHeight, + auto => auto && this.computeHeight(), + { fireImmediately: true }) + } + + refList: Set<any> = new Set(); + observer: any; + computeHeight = () => { + this.rootDoc._height = 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); + } + unobserveHeight = (ref: any) => this.refList.delete(ref); + observerHeight = (ref: any) => { + if (ref) { + this.refList.add(ref); + this.observer = new _global.ResizeObserver(action((entries: any) => { + if (this.rootDoc.autoHeight && ref && this.refList.size && !SnappingManager.GetIsDragging()) { + this.computeHeight(); + } + })); + this.rootDoc.autoHeight && this.computeHeight(); + this.observer.observe(ref); + } + } protected createTreeDropTarget = (ele: HTMLDivElement) => { this.treedropDisposer?.(); if (this._mainEle = ele) this.treedropDisposer = DragManager.MakeDropTarget(ele, this.onInternalDrop.bind(this), this.doc, this.onInternalPreDrop.bind(this)); @@ -201,7 +229,9 @@ export class CollectionTreeView extends CollectionSubView<Document, Partial<coll this.props.treeViewSkipFields, true, this.props.whenChildContentsActiveChanged, - this.props.dontRegisterView || Cast(this.props.Document.childDontRegisterViews, "boolean", null)); + this.props.dontRegisterView || Cast(this.props.Document.childDontRegisterViews, "boolean", null), + this.observerHeight, + this.unobserveHeight); } @computed get titleBar() { const hideTitle = this.props.treeViewHideTitle || this.doc.treeViewHideTitle; @@ -217,6 +247,7 @@ export class CollectionTreeView extends CollectionSubView<Document, Partial<coll } paddingX = () => NumCast(this.doc._xPadding, 15); + paddingTop = () => 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); titleTransform = () => this.props.ScreenToLocalTransform().translate(-NumCast(this.doc._xPadding, 10), -NumCast(this.doc._yPadding, 20)); @@ -227,13 +258,12 @@ export class CollectionTreeView extends CollectionSubView<Document, Partial<coll render() { TraceMobx(); const background = () => this.props.styleProvider?.(this.doc, this.props, StyleProp.BackgroundColor); - const paddingTop = () => `${NumCast(this.doc._yPadding, 20)}px`; 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-dropTarget" - style={{ background: background(), paddingLeft: `${this.paddingX()}px`, paddingRight: `${this.paddingX()}px`, paddingTop: paddingTop(), pointerEvents: pointerEvents() }} + style={{ background: background(), paddingLeft: `${this.paddingX()}px`, paddingRight: `${this.paddingX()}px`, paddingTop: `${this.paddingTop()}px`, pointerEvents: pointerEvents() }} onWheel={e => e.stopPropagation()} onDrop={this.onTreeDrop} ref={this.createTreeDropTarget}> diff --git a/src/client/views/collections/TreeView.tsx b/src/client/views/collections/TreeView.tsx index 94a19a673..2c3a6c0d7 100644 --- a/src/client/views/collections/TreeView.tsx +++ b/src/client/views/collections/TreeView.tsx @@ -35,6 +35,8 @@ import React = require("react"); export interface TreeViewProps { treeView: CollectionTreeView; parentTreeView: TreeView | CollectionTreeView | undefined; + observeHeight: (ref: any) => void; + unobserveHeight: (ref: any) => void; prevSibling?: Doc; document: Doc; dataDoc?: Doc; @@ -162,13 +164,17 @@ export class TreeView extends React.Component<TreeViewProps> { this._editTitleScript = Doc.IsSystem(this.props.document) ? () => TreeView._openLevelScript! : () => TreeView._openTitleScript!; } + _treeEle: any; protected createTreeDropTarget = (ele: HTMLDivElement) => { this._treedropDisposer?.(); ele && (this._treedropDisposer = DragManager.MakeDropTarget(ele, this.treeDrop.bind(this), undefined, this.preTreeDrop.bind(this)), this.doc); + if (this._treeEle) this.props.unobserveHeight(this._treeEle); + this.props.observeHeight(this._treeEle = ele); } componentWillUnmount() { this._selDisposer?.(); + this._treeEle && this.props.unobserveHeight(this._treeEle) document.removeEventListener("pointermove", this.onDragMove, true); document.removeEventListener("pointermove", this.onDragUp, true); } @@ -322,7 +328,8 @@ export class TreeView extends React.Component<TreeViewProps> { this.props.treeView, this, doc, undefined, this.props.containerCollection, this.props.prevSibling, addDoc, remDoc, this.move, this.props.dropAction, this.props.addDocTab, this.titleStyleProvider, this.props.ScreenToLocalTransform, this.props.isContentActive, this.props.panelWidth, this.props.renderDepth, this.props.treeViewHideHeaderFields, - [...this.props.renderedIds, doc[Id]], this.props.onCheckedClick, this.props.onChildClick, this.props.skipFields, false, this.props.whenChildContentsActiveChanged, this.props.dontRegisterView); + [...this.props.renderedIds, doc[Id]], this.props.onCheckedClick, this.props.onChildClick, this.props.skipFields, false, this.props.whenChildContentsActiveChanged, + this.props.dontRegisterView, emptyFunction, emptyFunction); } else { contentElement = <EditableView key="editableView" contents={contents !== undefined ? Field.toString(contents as Field) : "null"} @@ -403,7 +410,8 @@ export class TreeView extends React.Component<TreeViewProps> { this.dataDoc, this.props.containerCollection, this.props.prevSibling, addDoc, remDoc, this.move, StrCast(this.doc.childDropAction, this.props.dropAction) as dropActionType, this.props.addDocTab, this.titleStyleProvider, this.props.ScreenToLocalTransform, this.props.isContentActive, this.props.panelWidth, this.props.renderDepth, this.props.treeViewHideHeaderFields, - [...this.props.renderedIds, this.doc[Id]], this.props.onCheckedClick, this.props.onChildClick, this.props.skipFields, false, this.props.whenChildContentsActiveChanged, this.props.dontRegisterView)} + [...this.props.renderedIds, this.doc[Id]], this.props.onCheckedClick, this.props.onChildClick, this.props.skipFields, false, this.props.whenChildContentsActiveChanged, + this.props.dontRegisterView, emptyFunction, emptyFunction)} </ul >; } else if (this.treeViewExpandedView === "fields") { return <ul key={this.doc[Id] + this.doc.title}> @@ -782,6 +790,8 @@ export class TreeView extends React.Component<TreeViewProps> { firstLevel: boolean, whenChildContentsActiveChanged: (isActive: boolean) => void, dontRegisterView: boolean | undefined, + observerHeight: (ref: any) => void, + unobserveHeight: (ref: any) => void ) { const viewSpecScript = Cast(conainerCollection.viewSpecScript, ScriptField); if (viewSpecScript) { @@ -843,7 +853,10 @@ export class TreeView extends React.Component<TreeViewProps> { skipFields={skipFields} firstLevel={firstLevel} whenChildContentsActiveChanged={whenChildContentsActiveChanged} - parentTreeView={parentTreeView} />; + parentTreeView={parentTreeView} + observeHeight={observerHeight} + unobserveHeight={unobserveHeight} + />; }); } }
\ No newline at end of file |