UNPKG

rc-dock

Version:

dock layout for react component

175 lines (158 loc) 4.97 kB
import { BoxData, LayoutData, PanelData, BoxBase, LayoutBase, PanelBase, TabBase, TabData, maximePlaceHolderId } from "./DockData"; interface DefaultLayoutCache { panels: Map<string, PanelData>; tabs: Map<string, TabData>; } function addPanelToCache(panelData: PanelData, cache: DefaultLayoutCache) { cache.panels.set(panelData.id, panelData); for (let tab of panelData.tabs) { cache.tabs.set(tab.id, tab); } } function addBoxToCache(boxData: BoxData, cache: DefaultLayoutCache) { for (let child of boxData.children) { if ('tabs' in child) { addPanelToCache(child, cache); } else if ('children' in child) { addBoxToCache(child, cache); } } } export function createLayoutCache(defaultLayout: LayoutData | BoxData): DefaultLayoutCache { let cache: DefaultLayoutCache = { panels: new Map(), tabs: new Map(), }; if (defaultLayout) { if ('children' in defaultLayout) { // BoxData addBoxToCache(defaultLayout, cache); } else { // LayoutData if ('dockbox' in defaultLayout) { addBoxToCache(defaultLayout.dockbox, cache); } if ('floatbox' in defaultLayout) { addBoxToCache(defaultLayout.floatbox, cache); } } } return cache; } export function saveLayoutData( layout: LayoutData, saveTab?: (tab: TabData) => TabBase, afterPanelSaved?: (savedPanel: PanelBase, panel: PanelData) => void ): LayoutBase { function saveTabData(tabData: TabData): TabBase { return saveTab ? saveTab(tabData) : {id: tabData.id}; } function savePanelData(panelData: PanelData): PanelBase { let tabs: TabBase[] = []; for (let tab of panelData.tabs) { let savedTab = saveTabData(tab); if (savedTab) { tabs.push(savedTab); } } let {id, size, activeId, group, panelLock} = panelData; let savedPanel: PanelBase; if (panelData.parent.mode === 'float' || panelData.parent.mode === 'window') { let {x, y, z, w, h} = panelData; savedPanel = {id, size, tabs, group, activeId, panelLock, x, y, z, w, h}; } else { savedPanel = {id, size, tabs, group, activeId, panelLock}; } if (afterPanelSaved) { afterPanelSaved(savedPanel, panelData); } return savedPanel; } function saveBoxData(boxData: BoxData): BoxBase { let children: (BoxBase | PanelBase)[] = []; for (let child of boxData.children) { if ('tabs' in child) { children.push(savePanelData(child)); } else if ('children' in child) { children.push(saveBoxData(child)); } } let {id, size, mode} = boxData; return {id, size, mode, children}; } return { dockbox: saveBoxData(layout.dockbox), floatbox: saveBoxData(layout.floatbox), windowbox: saveBoxData(layout.windowbox), maxbox: saveBoxData(layout.maxbox), }; } export function loadLayoutData( savedLayout: LayoutBase, defaultLayout: LayoutData, loadTab?: (savedTab: TabBase) => TabData, afterPanelLoaded?: (savedPanel: PanelBase, panel: PanelData) => void ): LayoutData { let cache = createLayoutCache(defaultLayout); function loadTabData(savedTab: TabBase): TabData { if (loadTab) { return loadTab(savedTab); } let {id} = savedTab; if (cache.tabs.has(id)) { return cache.tabs.get(id); } return null; } function loadPanelData(savedPanel: PanelBase): PanelData { let {id, size, activeId, x, y, z, w, h, group, panelLock} = savedPanel; let tabs: TabData[] = []; for (let savedTab of savedPanel.tabs) { let tabData = loadTabData(savedTab); if (tabData) { tabs.push(tabData); } } let panelData: PanelData; if (w || h || x || y || z) { panelData = {id, size, activeId, group, x, y, z, w, h, tabs, panelLock}; } else { panelData = {id, size, activeId, group, tabs, panelLock}; } if (savedPanel.id === maximePlaceHolderId) { panelData.panelLock = {}; } else if (afterPanelLoaded) { afterPanelLoaded(savedPanel, panelData); } else if (cache.panels.has(id)) { panelData = {...cache.panels.get(id), ...panelData}; } return panelData; } function loadBoxData(savedBox: BoxBase): BoxData { if (!savedBox) { return null; } let children: (BoxData | PanelData)[] = []; for (let child of savedBox.children) { if ('tabs' in child) { children.push(loadPanelData(child)); } else if ('children' in child) { children.push(loadBoxData(child)); } } let {id, size, mode} = savedBox; return {id, size, mode, children}; } return { dockbox: loadBoxData(savedLayout.dockbox), floatbox: loadBoxData(savedLayout.floatbox ?? {mode: 'float', children: [], size: 0}), windowbox: loadBoxData(savedLayout.windowbox ?? {mode: 'window', children: [], size: 0}), maxbox: loadBoxData(savedLayout.maxbox ?? {mode: 'maximize', children: [], size: 1}), }; }