diff --git a/src/controller/activityBar.ts b/src/controller/activityBar.ts index a5a61e054..36c9c5939 100644 --- a/src/controller/activityBar.ts +++ b/src/controller/activityBar.ts @@ -1,4 +1,7 @@ import 'reflect-metadata'; +import { Controller } from 'mo/react/controller'; +import { container, singleton } from 'tsyringe'; +import { MenuBarController, IMenuBarController } from 'mo/controller'; import { IMenuItemProps } from 'mo/components/menu'; import { ActivityBarEvent, @@ -11,15 +14,11 @@ import { CONTEXT_MENU_SETTINGS, IActivityBarItem, } from 'mo/model'; -import { Controller } from 'mo/react/controller'; -import { container, singleton } from 'tsyringe'; import { SelectColorThemeAction } from 'mo/monaco/selectColorThemeAction'; import { ActivityBarService, - MenuBarService, IActivityBarService, - IMenuBarService, ISettingsService, SettingsService, } from 'mo/services'; @@ -39,16 +38,16 @@ export class ActivityBarController extends Controller implements IActivityBarController { private readonly activityBarService: IActivityBarService; - private readonly menuBarService: IMenuBarService; private readonly settingsService: ISettingsService; private readonly monacoService: IMonacoService; + private readonly menuBarController: IMenuBarController; constructor() { super(); this.activityBarService = container.resolve(ActivityBarService); - this.menuBarService = container.resolve(MenuBarService); this.settingsService = container.resolve(SettingsService); this.monacoService = container.resolve(MonacoService); + this.menuBarController = container.resolve(MenuBarController); } public readonly onSelect = ( @@ -91,7 +90,7 @@ export class ActivityBarController switch (contextMenuId) { // activityBar contextMenu case CONTEXT_MENU_MENU: { - this.menuBarService.showHide(); + this.menuBarController.updateMenuBar!(); break; } case CONTEXT_MENU_EXPLORER: { @@ -103,7 +102,7 @@ export class ActivityBarController break; } case CONTEXT_MENU_HIDE: { - this.activityBarService.showHide(); + this.menuBarController.updateActivityBar!(); break; } // manage button contextMenu diff --git a/src/controller/explorer/explorer.tsx b/src/controller/explorer/explorer.tsx index 317f785b5..7a41df3ea 100644 --- a/src/controller/explorer/explorer.tsx +++ b/src/controller/explorer/explorer.tsx @@ -1,6 +1,7 @@ import 'reflect-metadata'; import * as React from 'react'; import { Controller } from 'mo/react/controller'; +import { MenuBarController, IMenuBarController } from 'mo/controller'; import { container, singleton } from 'tsyringe'; import { connect } from 'mo/react'; import { Explorer, FolderTreeView } from 'mo/workbench/sidebar/explore'; @@ -53,6 +54,7 @@ export class ExplorerController private readonly folderTreeService: IFolderTreeService; private readonly menuBarService: IMenuBarService; private readonly folderTreeController: IFolderTreeController; + private readonly menuBarController: IMenuBarController; constructor() { super(); @@ -62,6 +64,7 @@ export class ExplorerController this.folderTreeService = container.resolve(FolderTreeService); this.menuBarService = container.resolve(MenuBarService); this.folderTreeController = container.resolve(FolderTreeController); + this.menuBarController = container.resolve(MenuBarController); this.initView(); } @@ -94,13 +97,11 @@ export class ExplorerController }; this.activityBarService.onSelect((e, item: IActivityBarItem) => { - const { hidden } = this.sidebarService.getState(); if (item.id === EXPLORER_ACTIVITY_ITEM) { - const isShow = hidden ? !hidden : hidden; this.sidebarService.setState({ current: explorePane.id, - hidden: isShow, }); + this.menuBarController.updateSideBar!(); this.menuBarService.update(MENU_VIEW_SIDEBAR, { icon: 'check', }); diff --git a/src/controller/index.ts b/src/controller/index.ts index 9a93442a0..6ee5ce8ad 100644 --- a/src/controller/index.ts +++ b/src/controller/index.ts @@ -7,7 +7,7 @@ export * from './problems'; export * from './settings'; export * from './sidebar'; export * from './statusBar'; -export * from './workbench'; +export * from './layout'; export * from './explorer/explorer'; export * from './explorer/folderTree'; export * from './explorer/outline'; diff --git a/src/controller/layout.ts b/src/controller/layout.ts new file mode 100644 index 000000000..2e3a32ea0 --- /dev/null +++ b/src/controller/layout.ts @@ -0,0 +1,27 @@ +import 'reflect-metadata'; +import { container, singleton } from 'tsyringe'; +import { Controller } from 'mo/react/controller'; +import { ILayoutService, LayoutService } from 'mo/services'; + +export interface ILayoutController { + onPaneSizeChange: (splitPanePos: string[]) => void; + onHorizontalPaneSizeChange: (horizontalSplitPanePos: string[]) => void; +} + +@singleton() +export class LayoutController extends Controller implements ILayoutController { + private readonly layoutService: ILayoutService; + + constructor() { + super(); + this.layoutService = container.resolve(LayoutService); + } + + public onPaneSizeChange = (splitPanePos: string[]) => { + this.layoutService.setPaneSize(splitPanePos); + }; + + public onHorizontalPaneSizeChange = (horizontalSplitPanePos: string[]) => { + this.layoutService.setHorizontalPaneSize(horizontalSplitPanePos); + }; +} diff --git a/src/controller/menuBar.ts b/src/controller/menuBar.ts index 34feb6b07..11666394f 100644 --- a/src/controller/menuBar.ts +++ b/src/controller/menuBar.ts @@ -11,40 +11,36 @@ import { } from 'mo/model/workbench/menuBar'; import { Controller } from 'mo/react/controller'; import { - ActivityBarService, EditorService, - IActivityBarService, IEditorService, IMenuBarService, - ISidebarService, - IStatusBarService, + ILayoutService, MenuBarService, - SidebarService, - StatusBarService, + LayoutService, } from 'mo/services'; export interface IMenuBarController { onSelect?: (key: string, item?: IActivityBarItem) => void; onClick: (event: React.MouseEvent, item: IMenuBarItem) => void; + updateStatusBar?: () => void; + updateMenuBar?: () => void; + updateActivityBar?: () => void; + updateSideBar?: () => void; } @singleton() export class MenuBarController extends Controller implements IMenuBarController { - private readonly activityBarService: IActivityBarService; private readonly editorService: IEditorService; private readonly menuBarService: IMenuBarService; - private readonly statusBarService: IStatusBarService; - private readonly sidebarService: ISidebarService; + private readonly layoutService: ILayoutService; constructor() { super(); - this.activityBarService = container.resolve(ActivityBarService); this.editorService = container.resolve(EditorService); this.menuBarService = container.resolve(MenuBarService); - this.statusBarService = container.resolve(StatusBarService); - this.sidebarService = container.resolve(SidebarService); + this.layoutService = container.resolve(LayoutService); } public readonly onClick = (event: React.MouseEvent, item: IMenuBarItem) => { @@ -80,32 +76,40 @@ export class MenuBarController }; public updateActivityBar = () => { - this.activityBarService.showHide(); - const { hidden } = this.activityBarService.getState(); + this.layoutService.setActivityBarHidden(); + const { + activityBar: { hidden }, + } = this.layoutService.getState(); this.menuBarService.update(MENU_VIEW_ACTIVITYBAR, { icon: hidden ? '' : 'check', }); }; public updateMenuBar = () => { - this.menuBarService.showHide(); - const { hidden } = this.menuBarService.getState(); + this.layoutService.setMenuBarHidden(); + const { + menuBar: { hidden }, + } = this.layoutService.getState(); this.menuBarService.update(MENU_VIEW_MENUBAR, { icon: hidden ? '' : 'check', }); }; public updateStatusBar = () => { - this.statusBarService.showHide(); - const { hidden } = this.statusBarService.getState(); + this.layoutService.setStatusBarHidden(); + const { + statusBar: { hidden }, + } = this.layoutService.getState(); this.menuBarService.update(MENU_VIEW_STATUSBAR, { icon: hidden ? '' : 'check', }); }; public updateSideBar = () => { - this.sidebarService.showHide(); - const { hidden } = this.sidebarService.getState(); + this.layoutService.setSideBarHidden(); + const { + sideBar: { hidden }, + } = this.layoutService.getState(); this.menuBarService.update(MENU_VIEW_SIDEBAR, { icon: hidden ? '' : 'check', }); diff --git a/src/controller/panel.tsx b/src/controller/panel.tsx index db90550ce..44c30d30a 100644 --- a/src/controller/panel.tsx +++ b/src/controller/panel.tsx @@ -8,7 +8,12 @@ import { PANEL_TOOLBOX_CLOSE, PANEL_TOOLBOX_RESIZE, } from 'mo/model/workbench/panel'; -import { IPanelService, PanelService } from 'mo/services'; +import { + IPanelService, + PanelService, + ILayoutService, + LayoutService, +} from 'mo/services'; export interface IPanelController { onTabChange(key: string | undefined): void; @@ -18,10 +23,12 @@ export interface IPanelController { @singleton() export class PanelController extends Controller implements IPanelController { private readonly panelService: IPanelService; + private readonly layoutService: ILayoutService; constructor() { super(); this.panelService = container.resolve(PanelService); + this.layoutService = container.resolve(LayoutService); } public readonly onTabChange = (key: string | undefined): void => { @@ -39,7 +46,7 @@ export class PanelController extends Controller implements IPanelController { item: IActionBarItemProps ): void => { if (item.id === PANEL_TOOLBOX_CLOSE) { - this.panelService.showHide(); + this.layoutService.setPanelHidden(); } else if (item.id === PANEL_TOOLBOX_RESIZE) { this.panelService.maximizeRestore(); } diff --git a/src/controller/problems.tsx b/src/controller/problems.tsx index 176a6b12d..53326cfb4 100644 --- a/src/controller/problems.tsx +++ b/src/controller/problems.tsx @@ -7,6 +7,8 @@ import { PanelService, IStatusBarService, StatusBarService, + ILayoutService, + LayoutService, } from 'mo/services'; import { singleton, container } from 'tsyringe'; import { builtInPanelProblems, builtInStatusProblems } from 'mo/model/problems'; @@ -19,24 +21,29 @@ export class ProblemsController implements IProblemsController { private readonly panelService: IPanelService; private readonly statusBarService: IStatusBarService; + private readonly layoutService: ILayoutService; constructor() { super(); this.panelService = container.resolve(PanelService); this.statusBarService = container.resolve(StatusBarService); + this.layoutService = container.resolve(LayoutService); this.init(); } private showHideProblems() { - const { current, hidden } = this.panelService.getState(); + const { current } = this.panelService.getState(); + const { + panel: { hidden }, + } = this.layoutService.getState(); if (hidden) { - this.panelService.showHide(); + this.layoutService.setPanelHidden(); this.panelService.open(builtInPanelProblems()); } else { if (current?.id !== builtInPanelProblems().id) { this.panelService.open(builtInPanelProblems()); } else { - this.panelService.showHide(); + this.layoutService.setPanelHidden(); } } } diff --git a/src/controller/workbench.ts b/src/controller/workbench.ts deleted file mode 100644 index 6e1f6609c..000000000 --- a/src/controller/workbench.ts +++ /dev/null @@ -1,28 +0,0 @@ -import { Controller } from 'mo/react/controller'; -import { singleton } from 'tsyringe'; - -export interface IWorkbenchController { - readonly splitPanePos: string[]; - readonly horizontalSplitPanePos: string[]; - onPaneSizeChange?: (newSize: number) => void; - onHorizontalPaneSizeChange?: (newSize: number) => void; -} -@singleton() -export class WorkbenchController - extends Controller - implements IWorkbenchController { - // Group Pos locate here temporary, we can move it to state or localStorage in future. - public splitPanePos: string[] = ['300px', 'auto']; - public horizontalSplitPanePos: string[] = ['70%', 'auto']; - - constructor() { - super(); - } - - public onPaneSizeChange = (newSize) => { - this.splitPanePos = newSize; - }; - - public onHorizontalPaneSizeChange = (newSize) => - (this.horizontalSplitPanePos = newSize); -} diff --git a/src/model/workbench/activityBar.ts b/src/model/workbench/activityBar.ts index 2ec5a81e9..f2d5d9367 100644 --- a/src/model/workbench/activityBar.ts +++ b/src/model/workbench/activityBar.ts @@ -36,7 +36,6 @@ export interface IActivityBar { data?: IActivityBarItem[]; contextMenu?: IMenuItemProps[]; selected?: string; - hidden?: boolean; } export const ACTIVITY_BAR_GLOBAL_SETTINGS = 'global.menu.settings'; @@ -113,16 +112,13 @@ export class ActivityBarModel implements IActivityBar { public data: IActivityBarItem[]; public contextMenu: IMenuItemProps[]; public selected: string; - public hidden = false; constructor( data: IActivityBarItem[] = [], contextMenu: IMenuItemProps[] = [], - selected: string = '', - hidden = false + selected: string = '' ) { this.data = data; this.contextMenu = contextMenu; this.selected = selected; - this.hidden = hidden; } } diff --git a/src/model/workbench/layout.ts b/src/model/workbench/layout.ts new file mode 100644 index 000000000..977bdb74f --- /dev/null +++ b/src/model/workbench/layout.ts @@ -0,0 +1,75 @@ +export enum Position { + LEFT, + RIGHT, + BOTTOM, +} +export interface ViewVisibility { + hidden?: boolean; +} + +export interface IPanelViewState extends ViewVisibility { + panelMaximized?: boolean; +} + +export interface ISideBarViewState extends ViewVisibility { + position?: Position; +} + +export function positionToString(position: Position): string { + switch (position) { + case Position.LEFT: + return 'left'; + case Position.RIGHT: + return 'right'; + case Position.BOTTOM: + return 'bottom'; + default: + return 'bottom'; + } +} + +const positionsByString: { [key: string]: Position } = { + [positionToString(Position.LEFT)]: Position.LEFT, + [positionToString(Position.RIGHT)]: Position.RIGHT, + [positionToString(Position.BOTTOM)]: Position.BOTTOM, +}; + +export function positionFromString(str: string): Position { + return positionsByString[str]; +} +export interface ILayout { + splitPanePos: string[]; + horizontalSplitPanePos: string[]; + activityBar: ViewVisibility; + panel: IPanelViewState; + statusBar: ViewVisibility; + sideBar: ISideBarViewState; + menuBar: ViewVisibility; +} + +export class LayoutModel implements ILayout { + public splitPanePos: string[]; + public horizontalSplitPanePos: string[]; + public activityBar: ViewVisibility; + public panel: IPanelViewState; + public statusBar: ViewVisibility; + public sideBar: ISideBarViewState; + public menuBar: ViewVisibility; + constructor( + splitPanePos: string[] = ['300px', 'auto'], + horizontalSplitPanePos = ['70%', 'auto'], + activityBar = { hidden: false }, + panel = { hidden: false, panelMaximized: false }, + statusBar = { hidden: false }, + sideBar = { hidden: false, position: Position.LEFT }, + menuBar = { hidden: false } + ) { + this.splitPanePos = splitPanePos; + this.horizontalSplitPanePos = horizontalSplitPanePos; + this.activityBar = activityBar; + this.panel = panel; + this.statusBar = statusBar; + this.sideBar = sideBar; + this.menuBar = menuBar; + } +} diff --git a/src/model/workbench/menuBar.ts b/src/model/workbench/menuBar.ts index 0aee4d295..b8b2ff3db 100644 --- a/src/model/workbench/menuBar.ts +++ b/src/model/workbench/menuBar.ts @@ -21,7 +21,6 @@ export interface IMenuBarItem { } export interface IMenuBar { data?: IMenuBarItem[]; - hidden?: boolean; } export const MENU_FILE_UNDO = 'undo'; @@ -156,10 +155,8 @@ export const undoRedoMenu = [ ]; export class MenuBarModel implements IMenuBar { public data: IMenuBarItem[]; - public hidden = false; constructor(data: IMenuBarItem[] = [], hidden = false) { this.data = data; - this.hidden = hidden; } } diff --git a/src/model/workbench/panel.tsx b/src/model/workbench/panel.tsx index 5958da301..728fb9d40 100644 --- a/src/model/workbench/panel.tsx +++ b/src/model/workbench/panel.tsx @@ -25,8 +25,6 @@ export interface IPanel { current?: IPanelItem; data?: IPanelItem[]; toolbox?: IActionBarItemProps[]; - hidden?: boolean; - maximize?: boolean; } export function builtInOutputPanel() { @@ -67,14 +65,10 @@ export class PanelModel implements IPanel { constructor( current: IPanelItem | undefined = undefined, data: IPanelItem[] = [], - hidden = false, - maximize = false, toolbox: IActionBarItemProps[] = [] ) { this.current = current; this.data = data; - this.hidden = hidden; - this.maximize = maximize; this.toolbox = toolbox; } } diff --git a/src/model/workbench/sidebar.ts b/src/model/workbench/sidebar.ts index e1371aeb1..f4867530c 100644 --- a/src/model/workbench/sidebar.ts +++ b/src/model/workbench/sidebar.ts @@ -16,21 +16,14 @@ export enum SideBarEvent { export interface ISidebar { current?: string; panes?: ISidebarPane[]; - hidden?: boolean; } export class SidebarModel implements ISidebar { public current: string; public panes: ISidebarPane[]; - public hidden = false; - constructor( - panes: ISidebarPane[] = [], - selected: string = '', - hidden = false - ) { + constructor(panes: ISidebarPane[] = [], selected: string = '') { this.panes = panes; this.current = selected; - this.hidden = hidden; } } diff --git a/src/model/workbench/statusBar.tsx b/src/model/workbench/statusBar.tsx index e5c1abacf..c9a935808 100644 --- a/src/model/workbench/statusBar.tsx +++ b/src/model/workbench/statusBar.tsx @@ -14,7 +14,6 @@ export interface IStatusBar { rightItems: IStatusBarItem[]; leftItems: IStatusBarItem[]; contextMenu?: IMenuItemProps[]; - hidden?: boolean; } export const STATUS_EDITOR_INFO: IStatusBarItem = { @@ -50,17 +49,14 @@ export class StatusBarModel implements IStatusBar { public leftItems: IStatusBarItem[] = []; public rightItems: IStatusBarItem[] = []; public contextMenu: IMenuItemProps[]; - public hidden = false; constructor( leftItems: IStatusBarItem[] = [], rightItems: IStatusBarItem[] = [STATUS_EDITOR_INFO], - contextMenu: IMenuItemProps[] = [CONTEXT_MENU_HIDE_STATUS_BAR], - hidden = false + contextMenu: IMenuItemProps[] = [CONTEXT_MENU_HIDE_STATUS_BAR] ) { this.leftItems = leftItems; this.rightItems = rightItems; this.contextMenu = contextMenu; - this.hidden = hidden; } } diff --git a/src/molecule.api.ts b/src/molecule.api.ts index 41150d643..1cb49e4e3 100644 --- a/src/molecule.api.ts +++ b/src/molecule.api.ts @@ -18,6 +18,8 @@ export { } from 'mo/model'; import { + ILayoutService, + LayoutService, ActivityBarService, IActivityBarService, ExplorerService, @@ -49,6 +51,10 @@ import { } from 'mo/services'; import { ILocaleService, LocaleService } from './i18n/localeService'; +/** + * layout service + */ +export const layout = container.resolve(LayoutService); /** * Register the Locales service first diff --git a/src/monaco/monacoService.ts b/src/monaco/monacoService.ts index d29287f74..4de7021b1 100644 --- a/src/monaco/monacoService.ts +++ b/src/monaco/monacoService.ts @@ -47,15 +47,14 @@ export interface IMonacoService { ): IStandaloneCodeEditor; /** * Initial the Workspace, like Services and editor config. - * @param container The Container element of Molecule */ initWorkspace(container: HTMLElement): void; } @singleton() export class MonacoService implements IMonacoService { private _services: ServiceCollection; - private _container!: HTMLElement | null; private simpleEditorModelResolverService: SimpleEditorModelResolverService | null = null; + private _container!: HTMLElement | null; constructor() {} @@ -64,6 +63,10 @@ export class MonacoService implements IMonacoService { this._services = this.createStandaloneServices(); } + get container() { + return this._container; + } + get services() { return this._services; } @@ -72,10 +75,6 @@ export class MonacoService implements IMonacoService { return this.services.get(ICommandService); } - get container() { - return this._container; - } - private mergeEditorServices(overrides?: IEditorOverrideServices) { if (overrides) { const services = this.services; diff --git a/src/provider/molecule.tsx b/src/provider/molecule.tsx index 5d33114e0..45b97b124 100644 --- a/src/provider/molecule.tsx +++ b/src/provider/molecule.tsx @@ -10,13 +10,13 @@ import { ExtensionService, IExtensionService, } from 'mo/services/extensionService'; -import { ID_APP } from 'mo/common/id'; import { IMonacoService, MonacoService } from 'mo/monaco/monacoService'; import { CommandQuickAccessViewAction } from 'mo/monaco/quickAccessViewAction'; import { registerAction2 } from 'mo/monaco/common'; import { QuickAccessSettings } from 'mo/monaco/quickAccessSettingsAction'; import { SelectColorThemeAction } from 'mo/monaco/selectColorThemeAction'; import { ILocaleService, LocaleService } from 'mo/i18n/localeService'; +import { ILayoutService, LayoutService } from 'mo/services'; import { SelectLocaleAction } from 'mo/i18n/selectLocaleAction'; export interface IMoleculeProps { extensions?: IExtension[]; @@ -34,13 +34,14 @@ export class MoleculeProvider extends React.Component { private readonly extensionService!: IExtensionService; private readonly monacoService!: IMonacoService; private readonly localeService!: ILocaleService; + private readonly layoutService!: ILayoutService; constructor(props: IMoleculeProps) { super(props); this.localeService = container.resolve(LocaleService); this.monacoService = container.resolve(MonacoService); this.extensionService = container.resolve(ExtensionService); - + this.layoutService = container.resolve(LayoutService); this.preloadLocales(); } @@ -48,19 +49,19 @@ export class MoleculeProvider extends React.Component { this.initialize(); } - public get container() { - return document.getElementById(ID_APP) || document.body; - } - preloadLocales() { const { locales = [], locale } = this.props; this.localeService.initialize(locales, locale); } + public get container() { + return this.layoutService.container; + } + initialize() { const { extensions = [] } = this.props; - this.monacoService.initWorkspace(this.container); + this.monacoService.initWorkspace(this.container!); this.extensionService.load(defaultExtensions); this.extensionService.load(extensions); diff --git a/src/services/workbench/activityBarService.ts b/src/services/workbench/activityBarService.ts index 3f05c0066..8096c40c0 100644 --- a/src/services/workbench/activityBarService.ts +++ b/src/services/workbench/activityBarService.ts @@ -13,7 +13,6 @@ import { searchById } from '../helper'; import { IMenuItemProps } from 'mo/components/menu'; export interface IActivityBarService extends Component { - showHide(): void; reset(): void; addBar(data: IActivityBarItem | IActivityBarItem[]): void; remove(id: string): void; @@ -44,13 +43,6 @@ export class ActivityBarService this.setState({ data: [], selected: '', - hidden: false, - }); - } - - public showHide(): void { - this.setState({ - hidden: !this.state.hidden, }); } diff --git a/src/services/workbench/index.ts b/src/services/workbench/index.ts index dbf4ee74f..1b8a52c9b 100644 --- a/src/services/workbench/index.ts +++ b/src/services/workbench/index.ts @@ -7,3 +7,4 @@ export * from './explorer/explorerService'; export * from './explorer/folderTreeService'; export * from './searchService'; export * from './panelService'; +export * from './layoutService'; diff --git a/src/services/workbench/layoutService.ts b/src/services/workbench/layoutService.ts new file mode 100644 index 000000000..54fd1692a --- /dev/null +++ b/src/services/workbench/layoutService.ts @@ -0,0 +1,118 @@ +import { container, singleton } from 'tsyringe'; +import { Component } from 'mo/react'; +import { ID_APP } from 'mo/common/id'; +import { ILayout, Position, LayoutModel } from 'mo/model/workbench/layout'; + +export interface ILayoutService extends Component { + setMenuBarHidden(): void; + setSideBarHidden(): void; + setPanelHidden(): void; + setActivityBarHidden(): void; + setStatusBarHidden(): void; + setPaneSize(splitPanePos: string[]): void; + setHorizontalPaneSize(horizontalSplitPanePos: string[]): void; + setSideBarPosition(position: Position): void; + getSideBarPosition(): Position; + togglePanelMaximized(): void; + isPanelMaximized(): boolean | undefined; + container: HTMLElement | null; +} + +@singleton() +export class LayoutService extends Component implements ILayoutService { + protected state: ILayout; + private _container!: HTMLElement | null; + constructor() { + super(); + this.state = container.resolve(LayoutModel); + } + + public get container() { + if (!this._container) { + this._container = document.getElementById(ID_APP) || document.body; + } + return this._container; + } + /** + * Set menubar hidden or not + */ + public setMenuBarHidden(): void { + const { menuBar } = this.state; + const wasHidden = menuBar?.hidden; + this.setState({ menuBar: { ...menuBar, hidden: !wasHidden } }); + } + /** + * Set panel hidden or not + */ + public setPanelHidden(): void { + const { panel } = this.state; + const wasHidden = panel?.hidden; + this.setState({ panel: { ...panel, hidden: !wasHidden } }); + } + /** + * Set sidebar hidden or not + */ + public setSideBarHidden(): void { + const { sideBar } = this.state; + const wasHidden = sideBar.hidden; + this.setState({ sideBar: { ...sideBar, hidden: !wasHidden } }); + } + /** + * Set activity bar hidden or not + */ + public setActivityBarHidden(): void { + const { activityBar } = this.state; + const wasHidden = activityBar.hidden; + this.setState({ activityBar: { ...activityBar, hidden: !wasHidden } }); + } + /** + * Set status bar hidden or not + */ + public setStatusBarHidden(): void { + const { statusBar } = this.state; + const wasHidden = statusBar.hidden; + this.setState({ statusBar: { ...statusBar, hidden: !wasHidden } }); + } + + public setSideBarPosition(newPosition: Position): void { + const { sideBar } = this.state; + const position = sideBar?.position; + const wasHidden = sideBar.hidden; + const newPositionValue = + newPosition === Position.LEFT ? 'left' : 'right'; + const oldPositionValue = position === Position.LEFT ? 'left' : 'right'; + if (newPositionValue !== oldPositionValue && !wasHidden) { + this.setState({ + sidebar: { ...sideBar, hidden: !wasHidden }, + }); + } + } + + public getSideBarPosition(): Position { + return this.state.sideBar.position!; + } + /** + * Toggle Panel Maximized + */ + public togglePanelMaximized(): void { + const panelViewState = this.state.panel; + this.setState({ + panel: { + ...panelViewState, + panelMaximized: !panelViewState.panelMaximized, + }, + }); + } + /** + * Returns true if the panel is maximized. + */ + public isPanelMaximized(): boolean { + return this.state.panel?.panelMaximized!; + } + public setPaneSize(splitPanePos: string[]): void { + this.setState({ splitPanePos }); + } + public setHorizontalPaneSize(horizontalSplitPanePos: string[]): void { + this.setState({ horizontalSplitPanePos }); + } +} diff --git a/src/services/workbench/menuBarService.ts b/src/services/workbench/menuBarService.ts index aa1fa56c3..a51b4c56b 100644 --- a/src/services/workbench/menuBarService.ts +++ b/src/services/workbench/menuBarService.ts @@ -10,7 +10,6 @@ import { Component } from 'mo/react'; import { singleton, container } from 'tsyringe'; export interface IMenuBarService extends Component { - showHide(): void; initMenu(data: IMenuBarItem[]): void; addRootMenu(menu: IMenuBarItem | IMenuBarItem[]): void; add(menuItem: IMenuBarItem, parentId: string): void; @@ -30,12 +29,6 @@ export class MenuBarService this.state = container.resolve(MenuBarModel); } - public showHide(): void { - this.setState({ - hidden: !this.state.hidden, - }); - } - public initMenu = (menuData: IMenuBarItem[]) => { this.setState({ data: menuData, diff --git a/src/services/workbench/panelService.ts b/src/services/workbench/panelService.ts index 8cd7e510f..a67808360 100644 --- a/src/services/workbench/panelService.ts +++ b/src/services/workbench/panelService.ts @@ -16,6 +16,8 @@ import { import { searchById } from '../helper'; import { IActionBarItemProps } from 'mo/components/actionBar'; import { localize } from 'mo/i18n/localize'; +import { LayoutService } from 'mo/services'; + export interface IPanelService extends Component { open(data: IPanelItem): void; getById(id: string): IPanelItem | undefined; @@ -25,7 +27,6 @@ export interface IPanelService extends Component { appendOutput(content: string): void; updateOutput(data: IPanelItem): IPanelItem | undefined; clearOutput(): void; - showHide(): void; maximizeRestore(): void; onTabChange(callback: (key: string) => void): void; onToolbarClick( @@ -36,27 +37,23 @@ export interface IPanelService extends Component { @singleton() export class PanelService extends Component implements IPanelService { protected state: IPanel; + private readonly layoutService: LayoutService; constructor() { super(); this.state = container.resolve(PanelModel); - } - - public showHide(): void { - this.setState({ - hidden: !this.state.hidden, - }); + this.layoutService = container.resolve(LayoutService); } public maximizeRestore(): void { - const maximize = !this.state.maximize; + const panelMaximized = this.layoutService.isPanelMaximized(); const { toolbox = [] } = this.state; const resizeBtnIndex = toolbox?.findIndex( searchById(PANEL_TOOLBOX_RESIZE) ); const resizeBtn = toolbox[resizeBtnIndex]; if (resizeBtn) { - if (maximize) { + if (panelMaximized) { toolbox[resizeBtnIndex] = Object.assign({}, resizeBtn, { title: localize( PANEL_TOOLBOX_RESTORE_SIZE, @@ -67,9 +64,7 @@ export class PanelService extends Component implements IPanelService { } else { toolbox[resizeBtnIndex] = builtInPanelToolboxResize(); } - this.setState({ - maximize: !this.state.maximize, - }); + this.layoutService.togglePanelMaximized(); } } diff --git a/src/services/workbench/sidebarService.ts b/src/services/workbench/sidebarService.ts index c399a4ffa..7ddb72926 100644 --- a/src/services/workbench/sidebarService.ts +++ b/src/services/workbench/sidebarService.ts @@ -8,7 +8,6 @@ import { } from 'mo/model/workbench/sidebar'; export interface ISidebarService extends Component { - showHide(): void; push(data: ISidebarPane): void; } @@ -27,10 +26,4 @@ export class SidebarService const original = this.state.panes; original?.push(data); } - - public showHide(): void { - this.setState({ - hidden: !this.state.hidden, - }); - } } diff --git a/src/services/workbench/statusBarService.ts b/src/services/workbench/statusBarService.ts index 02c0a5d7a..a6281fe9f 100644 --- a/src/services/workbench/statusBarService.ts +++ b/src/services/workbench/statusBarService.ts @@ -9,7 +9,6 @@ import { Component } from 'mo/react'; import { container, singleton } from 'tsyringe'; export interface IStatusBarService extends Component { - showHide(): void; appendLeftItem(item: IStatusBarItem): void; appendRightItem(item: IStatusBarItem): void; updateItem(item: IStatusBarItem): void; @@ -51,13 +50,6 @@ export class StatusBarService this.subscribe(StatusBarEvent.onClick, callback); } - public showHide(): void { - this.setState({ - ...this.state, - hidden: !this.state.hidden, - }); - } - private remove(id: string, arr: IStatusBarItem[]): IStatusBarItem { const index = arr.findIndex(searchById(id)); const result = arr.splice(index, 1); diff --git a/src/workbench/index.tsx b/src/workbench/index.tsx index 325ccffb7..2fd592de1 100644 --- a/src/workbench/index.tsx +++ b/src/workbench/index.tsx @@ -27,7 +27,7 @@ export type { export type { IActivityBarController, - IWorkbenchController, + ILayoutController, IEditorController, ISideBarController, IMenuBarController, diff --git a/src/workbench/workbench.tsx b/src/workbench/workbench.tsx index e53b5f6e3..2f233ce1f 100644 --- a/src/workbench/workbench.tsx +++ b/src/workbench/workbench.tsx @@ -18,22 +18,10 @@ import { APP_PREFIX } from 'mo/common/const'; import { connect } from 'mo/react'; -import { - IWorkbenchController, - WorkbenchController, -} from 'mo/controller/workbench'; -import { - ActivityBarService, - IActivityBarService, - IMenuBarService, - IPanelService, - ISidebarService, - IStatusBarService, - MenuBarService, - PanelService, - SidebarService, - StatusBarService, -} from 'mo/services'; +import { ILayoutController, LayoutController } from 'mo/controller/layout'; +import { LayoutService } from 'mo/services'; +import { ILayout } from 'mo/model/workbench/layout'; + import { IWorkbench } from 'mo/model'; const mainBenchClassName = prefixClaName('mainBench'); @@ -41,16 +29,10 @@ const workbenchClassName = prefixClaName('workbench'); const compositeBarClassName = prefixClaName('compositeBar'); const appClassName = classNames(APP_PREFIX, Utils.isMacOs() ? 'mac' : ''); -const panelService = container.resolve(PanelService); -const sidebarService = container.resolve(SidebarService); -const menuBarService = container.resolve(MenuBarService); -const activityBarService = container.resolve( - ActivityBarService -); -const workbenchController = container.resolve(WorkbenchController); -const statusBarService = container.resolve(StatusBarService); +const layoutController = container.resolve(LayoutController); +const layoutService = container.resolve(LayoutService); -export function WorkbenchView(props: IWorkbench & IWorkbenchController) { +export function WorkbenchView(props: IWorkbench & ILayout & ILayoutController) { const { activityBar, menuBar, @@ -75,7 +57,7 @@ export function WorkbenchView(props: IWorkbench & IWorkbenchController) { split="vertical" primary="first" allowResize={true} - onChange={onPaneSizeChange} + onChange={onPaneSizeChange as any} > {!sideBar.hidden && ( void; + onChange={onHorizontalPaneSizeChange as any} > - {!panel.maximize ? ( + {!panel.panelMaximized ? (