diff options
5 files changed, 43 insertions, 6 deletions
diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts index 5039be2f6..c4014a752 100644 --- a/src/client/documents/Documents.ts +++ b/src/client/documents/Documents.ts @@ -315,6 +315,7 @@ export class DocumentOptions { linearViewExpandable?: boolean; // can linear view be expanded linearViewToggleButton?: string; // button to open close linear view group linearViewSubMenu?: boolean; + linearBtnWidth?: number; flexGap?: number; // Linear view flex gap flexDirection?: 'unset' | 'row' | 'column' | 'row-reverse' | 'column-reverse'; diff --git a/src/client/util/CurrentUserUtils.ts b/src/client/util/CurrentUserUtils.ts index 9571209b0..9aceed366 100644 --- a/src/client/util/CurrentUserUtils.ts +++ b/src/client/util/CurrentUserUtils.ts @@ -41,6 +41,7 @@ interface Button { numBtnMax?: number; switchToggle?: boolean; width?: number; + linearBtnWidth?: number; toolType?: string; // type of pen tool expertMode?: boolean;// available only in expert mode btnList?: List<string>; @@ -621,6 +622,7 @@ export class CurrentUserUtils { { title: "Snap\xA0Lines",icon: "th", toolTip: "Show Snap Lines", btnType: ButtonType.ToggleButton, expertMode: false, toolType:"snap lines", funcs: {}, scripts: { onClick: 'showFreeform(self.toolType, _readOnly_)'}}, // Only when floating document is selected in freeform { title: "View\xA0All", icon: "object-group",toolTip: "Fit all Docs to View",btnType: ButtonType.ToggleButton, expertMode: false, toolType:"viewAll", funcs: {}, scripts: { onClick: 'showFreeform(self.toolType, _readOnly_)'}}, // Only when floating document is selected in freeform { title: "Clusters", icon: "braille", toolTip: "Show Doc Clusters", btnType: ButtonType.ToggleButton, expertMode: false, toolType:"clusters", funcs: {}, scripts: { onClick: 'showFreeform(self.toolType, _readOnly_)'}}, // Only when floating document is selected in freeform + { title: "Arrange", icon: "window", toolTip: "Toggle Auto Arrange", btnType: ButtonType.ToggleButton, expertMode: false, toolType:"arrange", funcs: {}, scripts: { onClick: 'showFreeform(self.toolType, _readOnly_)'}}, // Only when floating document is selected in freeform { title: "Reset", icon: "check", toolTip: "Reset View", btnType: ButtonType.ClickButton, expertMode: false, backgroundColor:"transparent", scripts: { onClick: 'resetView()'}}, // Only when floating document is selected in freeform ] } @@ -695,7 +697,7 @@ export class CurrentUserUtils { { title: "Doc", icon: "Doc", toolTip: "Freeform Doc tools", subMenu: CurrentUserUtils.freeTools(), expertMode: false, toolType:CollectionViewType.Freeform, funcs: {hidden: `!SelectionManager_selectedDocType(self.toolType, self.expertMode, true)`, linearViewIsExpanded: `SelectionManager_selectedDocType(self.toolType, self.expertMode)`} }, // Always available { title: "View", icon: "View", toolTip: "View tools", subMenu: CurrentUserUtils.viewTools(), expertMode: false, toolType:CollectionViewType.Freeform, funcs: {hidden: `!SelectionManager_selectedDocType(self.toolType, self.expertMode)`, linearViewIsExpanded: `SelectionManager_selectedDocType(self.toolType, self.expertMode)`} }, // Always available { title: "Web", icon: "Web", toolTip: "Web functions", subMenu: CurrentUserUtils.webTools(), expertMode: false, toolType:DocumentType.WEB, funcs: {hidden: `!SelectionManager_selectedDocType(self.toolType, self.expertMode)`, linearViewIsExpanded: `SelectionManager_selectedDocType(self.toolType, self.expertMode)`} }, // Only when Web is selected - { title: "Schema", icon: "Schema", toolTip: "Schema functions", subMenu: CurrentUserUtils.schemaTools(), expertMode: false, toolType:CollectionViewType.Schema, funcs: {hidden: `!SelectionManager_selectedDocType(self.toolType, self.expertMode)`, linearViewIsExpanded: `SelectionManager_selectedDocType(self.toolType, self.expertMode)`} } // Only when Schema is selected + { title: "Schema", icon: "Schema",linearBtnWidth:58,toolTip: "Schema functions", subMenu: CurrentUserUtils.schemaTools(), expertMode: false, toolType:CollectionViewType.Schema, funcs: {hidden: `!SelectionManager_selectedDocType(self.toolType, self.expertMode)`, linearViewIsExpanded: `SelectionManager_selectedDocType(self.toolType, self.expertMode)`} } // Only when Schema is selected ]; } @@ -706,7 +708,7 @@ export class CurrentUserUtils { backgroundColor: params.backgroundColor ??"transparent", /// a bit hacky. if an onClick is specified, then assume a toggle uses onClick to get the backgroundColor (see below). Otherwise, assume a transparent background color: Colors.WHITE, system: true, dontUndo: true, _nativeWidth: params.width ?? 30, _width: params.width ?? 30, - _height: 30, _nativeHeight: 30, + _height: 30, _nativeHeight: 30, linearBtnWidth: params.linearBtnWidth, toolType: params.toolType, expertMode: params.expertMode, _stayInCollection: true, _hideContextMenu: true, _lockedPosition: true, _removeDropProperties: new List<string>([ "_stayInCollection"]), diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx index 22a2a429f..9fe8f5f49 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx @@ -1408,6 +1408,24 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection } doFreeformLayout(poolData: Map<string, PoolData>) { + if (this.layoutDoc._autoArrange) { + const sorted = this.childLayoutPairs.slice().sort((a, b) => (NumCast(a.layout.y) < NumCast(b.layout.y) ? -1 : 1)); + if (sorted.length > 1) { + const deltay = sorted.length > 1 ? NumCast(sorted[1].layout.y) - (NumCast(sorted[0].layout.y) + NumCast(sorted[0].layout._height)) : 0; + const deltax = sorted.length > 1 ? NumCast(sorted[1].layout.x) - NumCast(sorted[0].layout.x) : 0; + + let lastx = NumCast(sorted[0].layout.x); + let lasty = NumCast(sorted[0].layout.y) + NumCast(sorted[0].layout._height); + setTimeout( + action(() => + sorted.slice(1).forEach((pair, i) => { + lastx = pair.layout.x = lastx + deltax; + lasty = (pair.layout.y = lasty + deltay) + NumCast(pair.layout._height); + }) + ) + ); + } + } this.childLayoutPairs.filter(pair => this.isCurrent(pair.layout)).map((pair, i) => poolData.set(pair.layout[Id], this.getCalculatedPositions({ pair, index: i, collection: this.Document }))); return [] as ViewDefResult[]; } @@ -1693,6 +1711,11 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection }, icon: 'compress-arrows-alt', }); + appearanceItems.push({ + description: 'Toggle auto arrange', + event: () => (this.layoutDoc._autoArrange = !this.layoutDoc._autoArrange), + icon: 'compress-arrows-alt', + }); if (this.props.setContentView === emptyFunction) { !appearance && ContextMenu.Instance.addItem({ description: 'Appearance...', subitems: appearanceItems, icon: 'eye' }); return; diff --git a/src/client/views/collections/collectionLinear/CollectionLinearView.tsx b/src/client/views/collections/collectionLinear/CollectionLinearView.tsx index a062c65fc..c7d9b6619 100644 --- a/src/client/views/collections/collectionLinear/CollectionLinearView.tsx +++ b/src/client/views/collections/collectionLinear/CollectionLinearView.tsx @@ -44,7 +44,7 @@ export class CollectionLinearView extends CollectionSubView() { componentDidMount() { this._widthDisposer = reaction( - () => 5 + this.dimension() + (this.layoutDoc.linearViewIsExpanded ? this.childDocs.filter(doc => !doc.hidden).reduce((tot, doc) => (doc[WidthSym]() || this.dimension()) + tot + 4, 0) : 0), + () => 5 + NumCast(this.rootDoc.linearBtnWidth, this.dimension()) + (this.layoutDoc.linearViewIsExpanded ? this.childDocs.filter(doc => !doc.hidden).reduce((tot, doc) => (doc[WidthSym]() || this.dimension()) + tot + 4, 0) : 0), width => this.childDocs.length && (this.layoutDoc._width = width), { fireImmediately: true } ); @@ -78,7 +78,7 @@ export class CollectionLinearView extends CollectionSubView() { } }; - dimension = () => NumCast(this.rootDoc._height); // 2 * the padding + dimension = () => NumCast(this.rootDoc._height); getTransform = (ele: Opt<HTMLDivElement>) => { if (!ele) return Transform.Identity(); const { scale, translateX, translateY } = Utils.GetScreenTransform(ele); diff --git a/src/client/views/nodes/button/FontIconBox.tsx b/src/client/views/nodes/button/FontIconBox.tsx index 28e6eaf1c..8410fda18 100644 --- a/src/client/views/nodes/button/FontIconBox.tsx +++ b/src/client/views/nodes/button/FontIconBox.tsx @@ -587,32 +587,43 @@ ScriptingGlobals.add(function toggleOverlay(checkResult?: boolean) { selected ? selected.props.CollectionFreeFormDocumentView?.().float() : console.log('[FontIconBox.tsx] toggleOverlay failed'); }); -ScriptingGlobals.add(function showFreeform(attr: 'grid' | 'snap lines' | 'clusters' | 'viewAll', checkResult?: boolean) { +ScriptingGlobals.add(function showFreeform(attr: 'grid' | 'snap lines' | 'clusters' | 'arrange' | 'viewAll', checkResult?: boolean) { const selected = SelectionManager.Docs().lastElement(); // prettier-ignore - const map: Map<'grid' | 'snap lines' | 'clusters' | 'viewAll', { checkResult: (doc:Doc) => any; setDoc: (doc:Doc) => void;}> = new Map([ + const map: Map<'grid' | 'snap lines' | 'clusters' | 'arrange'| 'viewAll', { undo: boolean, checkResult: (doc:Doc) => any; setDoc: (doc:Doc) => void;}> = new Map([ ['grid', { + undo: false, checkResult: (doc:Doc) => doc._backgroundGridShow, setDoc: (doc:Doc) => doc._backgroundGridShow = !doc._backgroundGridShow, }], ['snap lines', { + undo: false, checkResult: (doc:Doc) => doc.showSnapLines, setDoc: (doc:Doc) => doc._showSnapLines = !doc._showSnapLines, }], ['viewAll', { + undo: false, checkResult: (doc:Doc) => doc._fitContentsToBox, setDoc: (doc:Doc) => doc._fitContentsToBox = !doc._fitContentsToBox, }], ['clusters', { + undo: false, checkResult: (doc:Doc) => doc._useClusters, setDoc: (doc:Doc) => doc._useClusters = !doc._useClusters, }], + ['arrange', { + undo: true, + checkResult: (doc:Doc) => doc._autoArrange, + setDoc: (doc:Doc) => doc._autoArrange = !doc._autoArrange, + }], ]); if (checkResult) { return map.get(attr)?.checkResult(selected) ? Colors.MEDIUM_BLUE : 'transparent'; } + const batch = map.get(attr)?.undo ? UndoManager.StartBatch('set feature') : { end: () => {} }; SelectionManager.Docs().map(dv => map.get(attr)?.setDoc(dv)); + setTimeout(() => batch.end(), 100); }); ScriptingGlobals.add(function setFontAttr(attr: 'font' | 'fontColor' | 'highlight' | 'fontSize', value: any, checkResult?: boolean) { const editorView = RichTextMenu.Instance?.TextView?.EditorView; |