import { action, makeObservable, observable } from 'mobx'; import { Doc, Opt } from '../../fields/Doc'; import { DocViews } from '../../fields/DocSymbols'; import { List } from '../../fields/List'; import { listSpec } from '../../fields/Schema'; import { Cast, DocCast } from '../../fields/Types'; import { CollectionViewType, DocumentType } from '../documents/DocumentTypes'; import { DocumentView } from '../views/nodes/DocumentView'; import { LinkManager } from './LinkManager'; import { ScriptingGlobals } from './ScriptingGlobals'; import { UndoManager } from './UndoManager'; export namespace SelectionManager { class Manager { @observable.shallow SelectedViews: DocumentView[] = []; @observable IsDragging: boolean = false; @observable SelectedSchemaDocument: Doc | undefined = undefined; constructor() { makeObservable(this); } @action SelectSchemaViewDoc(doc: Opt) { manager.SelectedSchemaDocument = doc; } @action SelectView(docView: DocumentView, extendSelection: boolean): void { if (!docView.SELECTED) { if (!extendSelection) this.DeselectAll(); manager.SelectedViews.push(docView); docView.SELECTED = true; docView._props.whenChildContentsActiveChanged(true); } } @action DeselectView(docView?: DocumentView): void { if (docView && manager.SelectedViews.includes(docView)) { docView.SELECTED = false; manager.SelectedViews.splice(manager.SelectedViews.indexOf(docView), 1); docView._props.whenChildContentsActiveChanged(false); } } @action DeselectAll(): void { LinkManager.currentLink = undefined; LinkManager.currentLinkAnchor = undefined; manager.SelectedSchemaDocument = undefined; manager.SelectedViews.forEach(dv => { dv.SELECTED = false; dv._props.whenChildContentsActiveChanged(false); }); manager.SelectedViews.length = 0; } } const manager = new Manager(); export function DeselectView(docView?: DocumentView): void { manager.DeselectView(docView); } export function SelectView(docView: DocumentView | undefined, ctrlPressed: boolean): void { if (!docView) DeselectAll(); else manager.SelectView(docView, ctrlPressed); } export function SelectSchemaViewDoc(document: Opt, deselectAllFirst?: boolean): void { if (deselectAllFirst) manager.DeselectAll(); manager.SelectSchemaViewDoc(document); } export function IsSelected(doc?: Doc): boolean { return Array.from(doc?.[DocViews] ?? []).some(dv => dv?.SELECTED); } export function DeselectAll(except?: Doc): void { const found = manager.SelectedViews.find(dv => dv.Document === except); manager.DeselectAll(); if (found) manager.SelectView(found, false); } export function Views(): Array { return manager.SelectedViews; } export function SelectedSchemaDoc(): Doc | undefined { return manager.SelectedSchemaDocument; } export function Docs(): Doc[] { return manager.SelectedViews.map(dv => dv.Document).filter(doc => doc?._type_collection !== CollectionViewType.Docking); } } ScriptingGlobals.add(function SelectionManager_selectedDocType(type: string, expertMode: boolean, checkContext?: boolean) { if (Doc.noviceMode && expertMode) return false; if (type === 'tab') { return SelectionManager.Views().lastElement()?._props.renderDepth === 0; } let selected = (sel => (checkContext ? DocCast(sel?.embedContainer) : sel))(SelectionManager.SelectedSchemaDoc() ?? SelectionManager.Docs().lastElement()); return selected?.type === type || selected?.type_collection === type || !type; }); ScriptingGlobals.add(function deselectAll() { SelectionManager.DeselectAll(); }); ScriptingGlobals.add(function undo() { SelectionManager.DeselectAll(); return UndoManager.Undo(); }); export function ShowUndoStack() { SelectionManager.DeselectAll(); var buffer = ''; UndoManager.undoStack.forEach((batch, i) => { buffer += 'Batch => ' + UndoManager.undoStackNames[i] + '\n'; ///batch.forEach(undo => (buffer += ' ' + undo.prop + '\n')); }); alert(buffer); } ScriptingGlobals.add(function redo() { SelectionManager.DeselectAll(); return UndoManager.Redo(); }); ScriptingGlobals.add(function selectedDocs(container: Doc, excludeCollections: boolean, prevValue: any) { const docs = SelectionManager.Views() .map(dv => dv.Document) .filter(d => !Doc.AreProtosEqual(d, container) && !d.annotationOn && d.type !== DocumentType.KVP && (!excludeCollections || d.type !== DocumentType.COL || !Cast(d.data, listSpec(Doc), null))); return docs.length ? new List(docs) : prevValue; });