mirror of
https://github.com/wavetermdev/waveterm.git
synced 2025-01-02 18:39:05 +01:00
Fix Cmd-W to close focused node (#273)
Fixes the in-memory focused node stack so it can be used to find the currently-focused node. This is necessary for `closeFocusedNode` to work. Also fixes `validateFocusedNode` so it will set the first node to be focused if no focused node is available. Also cleans up leafOrder update pattern.
This commit is contained in:
parent
164afeeb66
commit
eea57af80b
@ -101,7 +101,7 @@ export class LayoutModel {
|
||||
/**
|
||||
* An ordered list of node ids starting from the top left corner to the bottom right corner.
|
||||
*/
|
||||
leafOrder: Atom<string[]>;
|
||||
leafOrder: PrimitiveAtom<string[]>;
|
||||
/**
|
||||
* A map of node models for currently-active leafs.
|
||||
*/
|
||||
@ -210,18 +210,7 @@ export class LayoutModel {
|
||||
this.resizeHandleSizePx = 2 * this.halfResizeHandleSizePx;
|
||||
|
||||
this.leafs = atom([]);
|
||||
this.leafOrder = atom((get) => {
|
||||
const leafs = get(this.leafs);
|
||||
const additionalProps = get(this.additionalProps);
|
||||
return leafs
|
||||
.map((node) => node.id)
|
||||
.sort((a, b) => {
|
||||
const treeKeyA = additionalProps[a]?.treeKey;
|
||||
const treeKeyB = additionalProps[b]?.treeKey;
|
||||
if (!treeKeyA || !treeKeyB) return;
|
||||
return treeKeyA.localeCompare(treeKeyB);
|
||||
});
|
||||
});
|
||||
this.leafOrder = atom([]);
|
||||
|
||||
this.nodeModels = new Map();
|
||||
this.additionalProps = atom({});
|
||||
@ -406,7 +395,9 @@ export class LayoutModel {
|
||||
this.leafs,
|
||||
newLeafs.sort((a, b) => a.id.localeCompare(b.id))
|
||||
);
|
||||
this.validateFocusedNode(newLeafs);
|
||||
const newLeafOrder = getLeafOrder(newLeafs, newAdditionalProps);
|
||||
this.setter(this.leafOrder, newLeafOrder);
|
||||
this.validateFocusedNode(newLeafOrder);
|
||||
this.cleanupNodeModels();
|
||||
}
|
||||
};
|
||||
@ -523,25 +514,28 @@ export class LayoutModel {
|
||||
|
||||
/**
|
||||
* Checks whether the focused node id has changed and, if so, whether to update the focused node stack. If the focused node was deleted, will pop the latest value from the stack.
|
||||
* @param newLeafs The new leafs array to use when searching for stale nodes in the stack.
|
||||
* @param leafOrder The new leaf order array to use when searching for stale nodes in the stack.
|
||||
*/
|
||||
private validateFocusedNode(newLeafs: LayoutNode[]) {
|
||||
private validateFocusedNode(leafOrder: string[]) {
|
||||
if (this.treeState.focusedNodeId !== this.focusedNodeId) {
|
||||
// Remove duplicates and stale entries from focus stack.
|
||||
const leafIds = newLeafs.map((leaf) => leaf.id);
|
||||
const newFocusedNodeIdStack: string[] = [];
|
||||
for (const id of this.focusedNodeIdStack) {
|
||||
if (leafIds.includes(id) && !newFocusedNodeIdStack.includes(id)) newFocusedNodeIdStack.push(id);
|
||||
if (leafOrder.includes(id) && !newFocusedNodeIdStack.includes(id)) newFocusedNodeIdStack.push(id);
|
||||
}
|
||||
this.focusedNodeIdStack = newFocusedNodeIdStack;
|
||||
|
||||
// Update the focused node and stack based on the changes in the tree state.
|
||||
if (this.treeState.focusedNodeId) {
|
||||
this.focusedNodeIdStack.unshift(this.treeState.focusedNodeId);
|
||||
} else {
|
||||
if (!this.treeState.focusedNodeId) {
|
||||
if (this.focusedNodeIdStack.length > 0) {
|
||||
this.treeState.focusedNodeId = this.focusedNodeIdStack.shift();
|
||||
} else {
|
||||
this.treeState.focusedNodeId = leafOrder[0];
|
||||
console.log("next insert loc", this.treeState.focusedNodeId);
|
||||
}
|
||||
}
|
||||
this.focusedNodeIdStack.unshift(this.treeState.focusedNodeId);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -992,3 +986,14 @@ export class LayoutModel {
|
||||
return this.getNodeRectById(node.id);
|
||||
}
|
||||
}
|
||||
|
||||
function getLeafOrder(leafs: LayoutNode[], additionalProps: Record<string, LayoutNodeAdditionalProps>): string[] {
|
||||
return leafs
|
||||
.map((node) => node.id)
|
||||
.sort((a, b) => {
|
||||
const treeKeyA = additionalProps[a]?.treeKey;
|
||||
const treeKeyB = additionalProps[b]?.treeKey;
|
||||
if (!treeKeyA || !treeKeyB) return;
|
||||
return treeKeyA.localeCompare(treeKeyB);
|
||||
});
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
// Copyright 2024, Command Line Inc.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import { DEFAULT_MAX_CHILDREN } from "./layoutTree";
|
||||
import { DefaultNodeSize, FlexDirection, LayoutNode } from "./types";
|
||||
import { reverseFlexDirection } from "./utils";
|
||||
|
||||
@ -222,7 +223,10 @@ export function balanceNode(
|
||||
* @param maxChildren The maximum number of children a node can have.
|
||||
* @returns The node to insert into and the index at which to insert.
|
||||
*/
|
||||
export function findNextInsertLocation(node: LayoutNode, maxChildren: number): { node: LayoutNode; index: number } {
|
||||
export function findNextInsertLocation(
|
||||
node: LayoutNode,
|
||||
maxChildren = DEFAULT_MAX_CHILDREN
|
||||
): { node: LayoutNode; index: number } {
|
||||
const insertLoc = findNextInsertLocationHelper(node, maxChildren, 1);
|
||||
return { node: insertLoc?.node, index: insertLoc?.index };
|
||||
}
|
||||
|
@ -29,6 +29,8 @@ import {
|
||||
MoveOperation,
|
||||
} from "./types";
|
||||
|
||||
export const DEFAULT_MAX_CHILDREN = 5;
|
||||
|
||||
/**
|
||||
* Computes an operation for inserting a new node into the tree in the given direction relative to the specified node.
|
||||
*
|
||||
@ -262,7 +264,7 @@ export function insertNode(layoutState: LayoutTreeState, action: LayoutTreeInser
|
||||
if (!layoutState.rootNode) {
|
||||
layoutState.rootNode = action.node;
|
||||
} else {
|
||||
const insertLoc = findNextInsertLocation(layoutState.rootNode, 5);
|
||||
const insertLoc = findNextInsertLocation(layoutState.rootNode, DEFAULT_MAX_CHILDREN);
|
||||
addChildAt(insertLoc.node, insertLoc.index, action.node);
|
||||
if (action.magnified) {
|
||||
layoutState.magnifiedNodeId = action.node.id;
|
||||
|
Loading…
Reference in New Issue
Block a user