fix pane split/join menu

This commit is contained in:
Skyler Lehmkuhl 2025-10-24 00:28:24 -04:00
parent 4b1d9dc851
commit 6b8679fa87
1 changed files with 107 additions and 4 deletions

View File

@ -4638,6 +4638,35 @@ function splitPane(div, percent, horiz, newPane = undefined) {
} }
// TODO: use icon menu items // TODO: use icon menu items
// See https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/menu/iconMenuItem.ts // See https://github.com/tauri-apps/tauri/blob/dev/packages/api/src/menu/iconMenuItem.ts
// Check if children contain nested splits to determine which joins are unambiguous
const leftUpChild = div.children[0];
const rightDownChild = div.children[1];
// A child is a leaf if it's a panecontainer that directly contains another panecontainer
// A child has nested splits if it's a panecontainer that contains a grid
const leftUpHasSplit = leftUpChild &&
leftUpChild.classList.contains("panecontainer") &&
leftUpChild.firstElementChild &&
(leftUpChild.firstElementChild.classList.contains("horizontal-grid") ||
leftUpChild.firstElementChild.classList.contains("vertical-grid")) &&
leftUpChild.firstElementChild.hasAttribute("lb-percent");
const rightDownHasSplit = rightDownChild &&
rightDownChild.classList.contains("panecontainer") &&
rightDownChild.firstElementChild &&
(rightDownChild.firstElementChild.classList.contains("horizontal-grid") ||
rightDownChild.firstElementChild.classList.contains("vertical-grid")) &&
rightDownChild.firstElementChild.hasAttribute("lb-percent");
// Join Left/Up is unambiguous if we're keeping the left/up side (which may have splits)
// and removing the right/down side (which should be a simple pane)
const canJoinLeftUp = !rightDownHasSplit;
// Join Right/Down is unambiguous if we're keeping the right/down side (which may have splits)
// and removing the left/up side (which should be a simple pane)
const canJoinRightDown = !leftUpHasSplit;
const menu = await Menu.new({ const menu = await Menu.new({
items: [ items: [
{ id: "ctx_option0", text: "Area options", enabled: false }, { id: "ctx_option0", text: "Area options", enabled: false },
@ -4652,11 +4681,83 @@ function splitPane(div, percent, horiz, newPane = undefined) {
action: () => createSplit("horizontal"), action: () => createSplit("horizontal"),
}, },
new PredefinedMenuItem("Separator"), new PredefinedMenuItem("Separator"),
{ id: "ctx_option3", text: horiz ? "Join Left" : "Join Up" }, {
{ id: "ctx_option4", text: horiz ? "Join Right" : "Join Down" }, id: "ctx_option3",
text: horiz ? "Join Left" : "Join Up",
enabled: canJoinLeftUp,
action: () => {
// Join left/up: remove the left/up pane, keep the right/down pane
const keepChild = div.children[1];
// Move all children from the kept panecontainer to the parent
const children = Array.from(keepChild.children);
// Replace the split div with just the kept child's contents
div.className = "panecontainer";
div.innerHTML = "";
children.forEach(child => {
// Recursively clear explicit sizing on grid and panecontainer elements only
function clearSizes(el) {
if (el.classList.contains("horizontal-grid") ||
el.classList.contains("vertical-grid") ||
el.classList.contains("panecontainer")) {
el.style.width = "";
el.style.height = "";
Array.from(el.children).forEach(clearSizes);
}
}
clearSizes(child);
div.appendChild(child);
});
div.removeAttribute("lb-percent");
setTimeout(() => {
updateAll();
updateUI();
updateLayers();
}, 20);
}
},
{
id: "ctx_option4",
text: horiz ? "Join Right" : "Join Down",
enabled: canJoinRightDown,
action: () => {
// Join right/down: remove the right/down pane, keep the left/up pane
const keepChild = div.children[0];
// Move all children from the kept panecontainer to the parent
const children = Array.from(keepChild.children);
// Replace the split div with just the kept child's contents
div.className = "panecontainer";
div.innerHTML = "";
children.forEach(child => {
// Recursively clear explicit sizing on grid and panecontainer elements only
function clearSizes(el) {
if (el.classList.contains("horizontal-grid") ||
el.classList.contains("vertical-grid") ||
el.classList.contains("panecontainer")) {
el.style.width = "";
el.style.height = "";
Array.from(el.children).forEach(clearSizes);
}
}
clearSizes(child);
div.appendChild(child);
});
div.removeAttribute("lb-percent");
setTimeout(() => {
updateAll();
updateUI();
updateLayers();
}, 20);
}
},
], ],
}); });
await menu.popup(); await menu.popup(new PhysicalPosition(event.clientX, event.clientY));
} }
console.log("Right-click on the element"); console.log("Right-click on the element");
@ -5865,8 +5966,9 @@ async function renderMenu() {
// Add individual layouts // Add individual layouts
for (const layoutKey of getLayoutNames()) { for (const layoutKey of getLayoutNames()) {
const layout = getLayout(layoutKey); const layout = getLayout(layoutKey);
const isCurrentLayout = config.currentLayout === layoutKey;
layoutMenuItems.push({ layoutMenuItems.push({
text: layout.name, text: isCurrentLayout ? `${layout.name}` : layout.name,
enabled: true, enabled: true,
action: () => switchLayout(layoutKey), action: () => switchLayout(layoutKey),
}); });
@ -6171,6 +6273,7 @@ function switchLayout(layoutKey) {
updateAll(); updateAll();
updateUI(); updateUI();
updateLayers(); updateLayers();
updateMenu();
console.log(`Layout switched to: ${layoutDef.name}`); console.log(`Layout switched to: ${layoutDef.name}`);
} catch (error) { } catch (error) {