diff --git a/source/Component/HeaderBar/HeaderBar.tsx b/source/Component/HeaderBar/HeaderBar.tsx index 36e884f..b287681 100644 --- a/source/Component/HeaderBar/HeaderBar.tsx +++ b/source/Component/HeaderBar/HeaderBar.tsx @@ -4,7 +4,7 @@ import { useStatusWithEvent, useStatus, IMixinStatusProps } from "@Context/Statu import { useSettingWithEvent, IMixinSettingProps, Platform } from "@Context/Setting"; import { Theme, BackgroundLevel, FontLevel } from "@Component/Theme/Theme"; import { LocalizationTooltipHost } from "@Component/Localization/LocalizationTooltipHost"; -import { useElectron, IMixinElectronProps } from "@Context/Electron"; +import { useElectronWithEvent, IMixinElectronProps } from "@Context/Electron"; import { I18N } from "@Component/Localization/Localization"; import "./HeaderBar.scss"; @@ -79,22 +79,41 @@ class HeaderFpsView extends Component { public render() { + + const isMaxSize = this.props.electron?.isMaximized(); + return -
- +
{ + this.props.electron?.minimize(); + }} + > +
-
- +
{ + if (isMaxSize) { + this.props.electron?.unMaximize(); + } else { + this.props.electron?.maximize(); + } + }} + > +
this.props.electron?.close()} + onClick={() => { + this.props.electron?.close() + }} > - +
} diff --git a/source/Context/Electron.ts b/source/Context/Electron.ts index 63518df..ad7787a 100644 --- a/source/Context/Electron.ts +++ b/source/Context/Electron.ts @@ -1,12 +1,12 @@ import { createContext } from "react"; -import { superConnect } from "@Context/Context"; -import { ISimulatorAPI } from "@Electron/SimulatorAPI"; +import { superConnect, superConnectWithEvent } from "@Context/Context"; +import { ISimulatorAPI, IApiEmitterEvent } from "@Electron/SimulatorAPI"; interface IMixinElectronProps { electron?: ISimulatorAPI; } -const ElectronContext = createContext({} as ISimulatorAPI); +const ElectronContext = createContext((window as any).API ?? {} as ISimulatorAPI); ElectronContext.displayName = "Electron"; const ElectronProvider = ElectronContext.Provider; @@ -17,4 +17,6 @@ const ElectronConsumer = ElectronContext.Consumer; */ const useElectron = superConnect(ElectronConsumer, "electron"); -export { useElectron, ElectronProvider, IMixinElectronProps, ISimulatorAPI }; \ No newline at end of file +const useElectronWithEvent = superConnectWithEvent(ElectronConsumer, "electron"); + +export { useElectron, ElectronProvider, IMixinElectronProps, ISimulatorAPI, useElectronWithEvent }; \ No newline at end of file diff --git a/source/Electron/Electron.ts b/source/Electron/Electron.ts index 3f54936..719eb0d 100644 --- a/source/Electron/Electron.ts +++ b/source/Electron/Electron.ts @@ -63,9 +63,32 @@ class ElectronApp { private handelSimulatorWindowBehavior() { - ipcMain.on("close", () => { + ipcMain.on("windows.close", () => { this.simulatorWindow?.close(); }); + + ipcMain.on("windows.maximize", () => { + this.simulatorWindow?.maximize(); + }); + + ipcMain.on("windows.unMaximize", () => { + this.simulatorWindow?.unmaximize(); + }); + + ipcMain.on("windows.isMaximized", (event) => { + event.returnValue = this.simulatorWindow?.isMaximized(); + }); + + ipcMain.on("windows.minimize", (event) => { + this.simulatorWindow?.minimize(); + }); + + const sendWindowsChangeMessage = () => { + this.simulatorWindow?.webContents.send("windows.windowsSizeStateChange"); + } + + this.simulatorWindow?.on("maximize", sendWindowsChangeMessage); + this.simulatorWindow?.on("unmaximize", sendWindowsChangeMessage); } } diff --git a/source/Electron/SimulatorAPI.ts b/source/Electron/SimulatorAPI.ts index bce5984..6581821 100644 --- a/source/Electron/SimulatorAPI.ts +++ b/source/Electron/SimulatorAPI.ts @@ -1,5 +1,10 @@ +import { Emitter } from "@Model/Emitter"; -interface ISimulatorAPI { +type IApiEmitterEvent = { + windowsSizeStateChange: void; +} + +interface ISimulatorAPI extends Emitter { /** * 关闭窗口 @@ -20,6 +25,11 @@ interface ISimulatorAPI { * 是否处于最大化状态 */ isMaximized: () => boolean; + + /** + * 是否处于最大化状态 + */ + minimize: () => void; } -export { ISimulatorAPI } \ No newline at end of file +export { ISimulatorAPI, IApiEmitterEvent } \ No newline at end of file diff --git a/source/Electron/SimulatorWindow.ts b/source/Electron/SimulatorWindow.ts index 9035380..4012366 100644 --- a/source/Electron/SimulatorWindow.ts +++ b/source/Electron/SimulatorWindow.ts @@ -1,19 +1,64 @@ import { contextBridge, ipcRenderer } from "electron"; import { ISimulatorAPI } from "@Electron/SimulatorAPI" -const API: ISimulatorAPI = { +const emitterMap: Array<[key: string, value: Function[]]> = []; +const queryEmitter = (key: string) => { + let res: (typeof emitterMap)[0] | undefined; + emitterMap.forEach((item) => { + if (item[0] === key) res = item; + }); - close() { - ipcRenderer.send("close"); - }, + if (res) { + if (Array.isArray(res[1])) return res[1]; + res[1] = []; + return res[1]; + } - maximize(){}, - - unMaximize(){}, - - isMaximized(){ - return false + else { + res = [key, []]; + emitterMap.push(res); + return res[1]; } } +const API: ISimulatorAPI = { + + close() { + ipcRenderer.send("windows.close"); + }, + + maximize() { + ipcRenderer.send("windows.maximize"); + }, + + unMaximize() { + ipcRenderer.send("windows.unMaximize"); + }, + + isMaximized() { + return ipcRenderer.sendSync("windows.isMaximized"); + }, + + minimize() { + ipcRenderer.send("windows.minimize"); + }, + + all: new Map() as any, + + resetAll: () => emitterMap.splice(0), + reset: (type) => queryEmitter(type).splice(0), + on: (type, handler) => queryEmitter(type).push(handler), + off: (type, handler) => { + const handlers = queryEmitter(type); + handlers.splice(handlers.indexOf(handler!) >>> 0, 1); + }, + emit: ((type: string, evt: any) => { + queryEmitter(type).slice().map((handler: any) => { handler(evt) }); + }) as any, +} + +ipcRenderer.on("windows.windowsSizeStateChange", () => { + API.emit("windowsSizeStateChange"); +}); + contextBridge.exposeInMainWorld("API", API); \ No newline at end of file