import { Box, Text } from "../../../../ui"; import type { DockGeometryOptions, DockLeafLayout, FloatingRect, LayoutBounds, ResolvedPane, } from "../../../../plugins/pane-manager"; import { colors } from "../../../../theme/colors"; import { constrainFloatingRectToBounds } from "../drag"; import { getFloatingResizeCornerPosition, type WindowEditDockMovePreview, windowEditHelpText, windowEditStatusLine, } from "../../window-edit/presentation"; import { windowEditHasPendingCommit, type WindowEditState } from "../../window-edit/mode"; import { NativeWindowEditStatus, resolveNativeFloatingResizeCornerRect, } from "../../window-edit/status"; import { MENU_Z_INDEX, truncateMenuText } from "../menu"; interface ShellWindowModeOverlaysProps { bounds: LayoutBounds; contentHeight: number; dockGeometryOptions: DockGeometryOptions; dockLeafLayouts: DockLeafLayout[]; dragFloatingRect: { paneId: string; rect: FloatingRect } | null; focusedPaneId: string | null; getPaneTitle: (pane: ResolvedPane) => string; menuOpen: boolean; nativePaneChrome: boolean; nativeWindowModePanelRect: LayoutBounds | null; overlayOpen: boolean; paneMap: Map; visibleFloatingPanes: Array<{ pane: ResolvedPane; rect: FloatingRect }>; width: number; windowMode: WindowEditState | null; windowModeDockMovePreview: WindowEditDockMovePreview | null; } function getHighlightedPaneId(windowMode: WindowEditState | null, focusedPaneId: string | null): string | null { if (windowMode?.mode === "move" && windowMode.focus.kind === "dock-move") { return windowMode.focus.targetId; } return windowMode?.paneId ?? focusedPaneId; } function windowModeBannerKey(windowMode: WindowEditState): string { const focusKey = windowMode.focus.kind === "dock-move" ? `${windowMode.focus.targetId}:${windowMode.focus.position}` : windowMode.focus.kind === "dock-resize" ? windowMode.focus.pathKey : windowMode.focus.kind === "floating-resize" ? windowMode.focus.corner : "move"; return `window-mode-banner:${windowMode.paneId}:${windowMode.mode}:${windowMode.focus.kind}:${focusKey}:${windowMode.notice ?? ""}`; } export function ShellWindowModeOverlays({ bounds, contentHeight, dockGeometryOptions, dockLeafLayouts, dragFloatingRect, focusedPaneId, getPaneTitle, menuOpen, nativePaneChrome, nativeWindowModePanelRect, overlayOpen, paneMap, visibleFloatingPanes, width, windowMode, windowModeDockMovePreview, }: ShellWindowModeOverlaysProps) { const highlightedPaneId = getHighlightedPaneId(windowMode, focusedPaneId); const highlightedFloatingPane = highlightedPaneId ? visibleFloatingPanes.find((entry) => entry.pane.instance.instanceId === highlightedPaneId) : null; const highlightedDockedLeaf = highlightedPaneId && !highlightedFloatingPane ? dockLeafLayouts.find((leaf) => leaf.instanceId === highlightedPaneId) : null; const highlightedRect = highlightedFloatingPane ? dragFloatingRect?.paneId === highlightedFloatingPane.pane.instance.instanceId ? constrainFloatingRectToBounds(dragFloatingRect.rect, width, contentHeight) : highlightedFloatingPane.rect : highlightedDockedLeaf?.rect ?? null; const highlightedZIndex = highlightedFloatingPane ? (highlightedFloatingPane.pane.floating?.zIndex ?? 50) + 1 : 3; return ( <> {windowModeDockMovePreview && ( )} {highlightedPaneId && !nativePaneChrome && highlightedRect && highlightedRect.height >= 2 && (!overlayOpen || menuOpen) && (() => { const selectedInWindowMode = !!windowMode; const borderColor = selectedInWindowMode ? colors.borderFocused : colors.border; const bodyTop = highlightedRect.y + 1; const bodyHeight = selectedInWindowMode ? highlightedRect.height - 1 : highlightedRect.height - 2; const bottomWidth = Math.max(0, highlightedRect.width - 2); return ( <> {bodyHeight > 0 && ( )} {bodyHeight > 0 && ( )} {selectedInWindowMode && bottomWidth > 0 && ( {"─".repeat(bottomWidth)} )} ); })()} {windowMode && !nativePaneChrome && windowMode.focus.kind === "floating-resize" && highlightedFloatingPane && (() => { const position = getFloatingResizeCornerPosition(highlightedFloatingPane.rect, windowMode.focus.corner); return ( {position.marker} ); })()} {windowMode && !nativePaneChrome && (() => { const pane = paneMap.get(windowMode.paneId); const title = pane ? getPaneTitle(pane) : "Window"; const targetPane = windowMode.focus.kind === "dock-move" ? paneMap.get(windowMode.focus.targetId) : undefined; const targetTitle = targetPane ? getPaneTitle(targetPane) : undefined; const pending = windowEditHasPendingCommit(windowMode, bounds, dockGeometryOptions); const text = `${windowEditStatusLine(windowMode, title, bounds, dockGeometryOptions, targetTitle)} · ${windowEditHelpText(windowMode, pending)}`; const bannerWidth = Math.max(1, width); const bannerText = truncateMenuText(text, bannerWidth).padEnd(bannerWidth, " "); return ( {bannerText} ); })()} {windowMode && nativePaneChrome && windowMode.focus.kind === "floating-resize" && highlightedFloatingPane && (() => { const cornerRect = resolveNativeFloatingResizeCornerRect(highlightedFloatingPane.rect, windowMode.focus.corner); return ( ); })()} {windowMode && nativePaneChrome && nativeWindowModePanelRect && (() => { const pane = paneMap.get(windowMode.paneId); const targetPane = windowMode.focus.kind === "dock-move" ? paneMap.get(windowMode.focus.targetId) : undefined; return ( ); })()} ); }