дзеркало
https://github.com/l0ng-ai/openidea.git
синхронізовано 2026-11-09 03:05:40 +02:00
The main toolbar and status bar could not be hidden, Tool Window Bars was a Settings row only, and widgets could be switched only from the status bar's context menu. View > Appearance now has Toolbar, Tool Window Bars, Status Bar and Status Bar Widgets, with check marks in the macOS and in-app menus, plus Settings toggles. Both new settings default to shown. With the toolbar hidden, the window keeps a compact header with the title, which Distraction Free now shares. Controls stay reachable with a bar hidden: the Git branches popup and background tasks have their own hosts, and background tasks has an action. Co-authored-by: lleviathe <[email protected]>
111 рядки
4.5 KiB
TypeScript
111 рядки
4.5 KiB
TypeScript
/**
|
||
* The IDEA-style shell (Islands): title bar, tool window stripes and island
|
||
* panels around the editor area on the frame background, status bar, and the
|
||
* overlay layer. Without an open project the welcome view replaces the frame,
|
||
* or, editing loose files (LightEdit), a frame with the editor only.
|
||
*/
|
||
import { useEditorRegistry } from "@/editor/api";
|
||
import { basename, useProject } from "@/platform/project";
|
||
import { useT } from "@/platform/i18n";
|
||
import { ProgressBar } from "@/ui";
|
||
import projectMark from "../../src-tauri/icons/source/openidea-mark.svg";
|
||
import { useDistractionFree } from "./distractionFree";
|
||
import { EditorArea } from "./EditorArea";
|
||
import { OverlayHost } from "./OverlayHost";
|
||
import { projectColorVars } from "./projectColor";
|
||
import { StatusBar } from "./StatusBar";
|
||
import { TitleBar } from "./TitleBar";
|
||
import { WindowGroupTabs } from "./WindowGroupTabs";
|
||
import { useApplyTheme } from "./theme";
|
||
import { ToolWindowLayout } from "./toolwindows/ToolWindows";
|
||
import { Welcome } from "./Welcome";
|
||
import { WindowResizeHandles } from "./WindowResizeHandles";
|
||
import { useContributions, useStandaloneEditor } from "./contributions";
|
||
import styles from "./Workbench.module.css";
|
||
|
||
/** View › Appearance switches (`appearance.showMainToolbar`, `appearance.showStatusBar`), shown by default. */
|
||
function useAppearanceFlag(key: "showMainToolbar" | "showStatusBar"): boolean {
|
||
return useProject((s) => s.settings?.appearance?.[key] !== false);
|
||
}
|
||
|
||
/** LightEdit: editor tabs only; no tool windows, toolbar widgets or project status items. */
|
||
function LightEditFrame({ title }: { title?: string }) {
|
||
const path = useEditorRegistry((s) => s.active?.ctx.path);
|
||
const distractionFree = useDistractionFree((s) => s.active);
|
||
const statusBar = useAppearanceFlag("showStatusBar");
|
||
return (
|
||
<>
|
||
<TitleBar lightEdit compact={distractionFree} title={title ?? (path ? basename(path) : "LightEdit")} />
|
||
<main className={styles.lightEdit} data-light-edit>
|
||
<div className={styles.lightEditIsland}>
|
||
<EditorArea />
|
||
</div>
|
||
</main>
|
||
{!distractionFree && statusBar && <StatusBar lightEdit />}
|
||
</>
|
||
);
|
||
}
|
||
|
||
function ProjectOpening({ path }: { path: string }) {
|
||
const t = useT();
|
||
const label = t("app.project.opening", { name: basename(path) });
|
||
return (
|
||
<div className={styles.opening} data-project-opening>
|
||
<TitleBar bare />
|
||
<div className={styles.openingBody} role="status" aria-label={label}>
|
||
<div className={styles.openingBrand} aria-hidden="true">
|
||
<img className={styles.openingLogo} src={projectMark} alt="" draggable={false} />
|
||
<span>OpenIDEA</span>
|
||
</div>
|
||
<ProgressBar className={styles.openingProgress} aria-label={label} />
|
||
<div className={styles.openingTitle}>{label}</div>
|
||
<div className={styles.openingPath} title={path}>
|
||
{path}
|
||
</div>
|
||
</div>
|
||
</div>
|
||
);
|
||
}
|
||
|
||
export function Workbench() {
|
||
useApplyTheme();
|
||
const banners = useContributions((s) => s.workbenchBanners);
|
||
const project = useProject((s) => s.project);
|
||
const lightEdit = useProject((s) => s.lightEdit);
|
||
const standaloneTitle = useStandaloneEditor((s) => s.title);
|
||
const openingPath = useProject((s) => s.openingPath);
|
||
const root = project?.root ?? null;
|
||
const distractionFree = useDistractionFree((s) => s.active);
|
||
const mainToolbar = useAppearanceFlag("showMainToolbar");
|
||
const statusBar = useAppearanceFlag("showStatusBar");
|
||
const frame = project ? styles.framed : lightEdit || standaloneTitle ? styles.lightEditFrame : undefined;
|
||
|
||
return (
|
||
<div
|
||
className={frame ? `${styles.workbench} ${frame}` : styles.workbench}
|
||
style={project ? projectColorVars(project.name) : undefined}
|
||
>
|
||
<div className={styles.content} inert={openingPath !== null} aria-hidden={openingPath ? true : undefined}>
|
||
{project ? (
|
||
<>
|
||
<TitleBar compact={distractionFree || !mainToolbar} />
|
||
{!distractionFree && <WindowGroupTabs />}
|
||
{[...banners.values()].map(({ id, component: Banner }) => (
|
||
<Banner key={id} />
|
||
))}
|
||
<ToolWindowLayout key={root} editor={<EditorArea />} />
|
||
{!distractionFree && statusBar && <StatusBar />}
|
||
</>
|
||
) : lightEdit || standaloneTitle ? (
|
||
<LightEditFrame title={standaloneTitle ?? undefined} />
|
||
) : (
|
||
<Welcome />
|
||
)}
|
||
</div>
|
||
{openingPath && <ProjectOpening path={openingPath} />}
|
||
<OverlayHost />
|
||
<WindowResizeHandles />
|
||
</div>
|
||
);
|
||
}
|