mirror of
https://github.com/wavetermdev/waveterm.git
synced 2024-12-22 16:48:23 +01:00
164afeeb66
This adds a new NodeModel, which can be passed from the TileLayout to contained blocks. It contains all the layout data that the block should care about, including focus status, whether a drag operation is underway, whether the node is magnified, etc. This also adds a focus stack for the layout, which will let the focus switch to the last-focused node when the currently-focused one is closed. This also addresses a regression in the resize handles that caused them to be offset from the cursor when dragged. --------- Co-authored-by: sawka <mike.sawka@gmail.com>
62 lines
2.4 KiB
TypeScript
62 lines
2.4 KiB
TypeScript
// Copyright 2024, Command Line Inc.
|
|
// SPDX-License-Identifier: Apache-2.0
|
|
|
|
import { atoms, globalStore, WOS } from "@/app/store/global";
|
|
import useResizeObserver from "@react-hook/resize-observer";
|
|
import { Atom, useAtomValue } from "jotai";
|
|
import { useEffect } from "react";
|
|
import { withLayoutTreeStateAtomFromTab } from "./layoutAtom";
|
|
import { LayoutModel } from "./layoutModel";
|
|
import { LayoutNode, NodeModel, TileLayoutContents } from "./types";
|
|
|
|
const layoutModelMap: Map<string, LayoutModel> = new Map();
|
|
|
|
export function getLayoutModelForTab(tabAtom: Atom<Tab>): LayoutModel {
|
|
const tabData = globalStore.get(tabAtom);
|
|
if (!tabData) return;
|
|
const tabId = tabData.oid;
|
|
if (layoutModelMap.has(tabId)) {
|
|
const layoutModel = layoutModelMap.get(tabData.oid);
|
|
if (layoutModel) {
|
|
return layoutModel;
|
|
}
|
|
}
|
|
const layoutTreeStateAtom = withLayoutTreeStateAtomFromTab(tabAtom);
|
|
const layoutModel = new LayoutModel(layoutTreeStateAtom, globalStore.get, globalStore.set);
|
|
globalStore.sub(layoutTreeStateAtom, () => layoutModel.updateTreeState());
|
|
layoutModelMap.set(tabId, layoutModel);
|
|
return layoutModel;
|
|
}
|
|
|
|
export function getLayoutModelForTabById(tabId: string) {
|
|
const tabOref = WOS.makeORef("tab", tabId);
|
|
const tabAtom = WOS.getWaveObjectAtom<Tab>(tabOref);
|
|
return getLayoutModelForTab(tabAtom);
|
|
}
|
|
|
|
export function getLayoutModelForActiveTab() {
|
|
const tabId = globalStore.get(atoms.activeTabId);
|
|
return getLayoutModelForTabById(tabId);
|
|
}
|
|
|
|
export function deleteLayoutModelForTab(tabId: string) {
|
|
if (layoutModelMap.has(tabId)) layoutModelMap.delete(tabId);
|
|
}
|
|
|
|
export function useLayoutModel(tabAtom: Atom<Tab>): LayoutModel {
|
|
return getLayoutModelForTab(tabAtom);
|
|
}
|
|
|
|
export function useTileLayout(tabAtom: Atom<Tab>, tileContent: TileLayoutContents): LayoutModel {
|
|
// Use tab data to ensure we can reload if the tab is disposed and remade (such as during Hot Module Reloading)
|
|
useAtomValue(tabAtom);
|
|
const layoutModel = useLayoutModel(tabAtom);
|
|
useResizeObserver(layoutModel?.displayContainerRef, layoutModel?.onContainerResize);
|
|
useEffect(() => layoutModel.registerTileLayout(tileContent), [tileContent]);
|
|
return layoutModel;
|
|
}
|
|
|
|
export function useNodeModel(layoutModel: LayoutModel, layoutNode: LayoutNode): NodeModel {
|
|
return layoutModel.getNodeModel(layoutNode);
|
|
}
|