diff --git a/src/constants.ts b/src/constants.ts index 1aac189..75e63ea 100644 --- a/src/constants.ts +++ b/src/constants.ts @@ -13,6 +13,9 @@ export const CONSTANTS = { export const IPC_COMMANDS = { TOGGLE_INFO: 'TOGGLE_INFO', SHOW_DISK_IMAGE: 'SHOW_DISK_IMAGE', + ZOOM_IN: 'ZOOM_IN', + ZOOM_OUT: 'ZOOM_OUT', + ZOOM_RESET: 'ZOOM_RESET', // Machine instructions MACHINE_START: 'MACHINE_START', MACHINE_RESTART: 'MACHINE_RESTART', diff --git a/src/main/main.ts b/src/main/main.ts index 409de82..da79325 100644 --- a/src/main/main.ts +++ b/src/main/main.ts @@ -4,7 +4,7 @@ import { isDevMode } from "../utils/devmode"; import { setupAboutPanel } from "./about-panel"; import { shouldQuit } from "./squirrel"; import { setupUpdates } from "./update"; -import { createWindow } from "./windows"; +import { getOrCreateWindow } from "./windows"; import { setupMenu } from "./menu"; /** @@ -14,7 +14,7 @@ import { setupMenu } from "./menu"; export async function onReady() { if (!isDevMode()) process.env.NODE_ENV = "production"; - createWindow(); + getOrCreateWindow(); setupAboutPanel(); setupMenu(); setupUpdates(); diff --git a/src/main/menu.ts b/src/main/menu.ts index be7a1f4..ca86c62 100644 --- a/src/main/menu.ts +++ b/src/main/menu.ts @@ -1,8 +1,9 @@ -import { app, shell, Menu, BrowserWindow, ipcMain } from "electron"; +import { app, shell, Menu, BrowserWindow, ipcMain, webFrame } from "electron"; import { clearCaches } from "../cache"; import { IPC_COMMANDS } from "../constants"; import { isDevMode } from "../utils/devmode"; +import { getOrCreateWindow } from "./windows"; const LINKS = { homepage: "https://www.twitter.com/felixrieseberg", @@ -100,6 +101,24 @@ async function createMenu({ isRunning } = { isRunning: false }) { label: "Close", accelerator: "CmdOrCtrl+W", role: "close" + }, + { + type: "separator" + }, + { + label: "Zoom in", + click: () => send(IPC_COMMANDS.ZOOM_IN), + enabled: isRunning + }, + { + label: "Zoom out", + click: () => send(IPC_COMMANDS.ZOOM_OUT), + enabled: isRunning + }, + { + label: "Reset zoom", + click: () => send(IPC_COMMANDS.ZOOM_RESET), + enabled: isRunning } ] }, diff --git a/src/main/windows.ts b/src/main/windows.ts index 81f7ea5..641a5e7 100644 --- a/src/main/windows.ts +++ b/src/main/windows.ts @@ -1,8 +1,10 @@ import { BrowserWindow } from "electron"; -let mainWindow; +let mainWindow: BrowserWindow | null = null; + +export function getOrCreateWindow(): BrowserWindow { + if (mainWindow) return mainWindow; -export function createWindow() { // Create the browser window. mainWindow = new BrowserWindow({ width: 1024, @@ -18,4 +20,6 @@ export function createWindow() { mainWindow.on("closed", () => { mainWindow = null; }); + + return mainWindow; } diff --git a/src/renderer/emulator.tsx b/src/renderer/emulator.tsx index 779a250..d33c6b6 100644 --- a/src/renderer/emulator.tsx +++ b/src/renderer/emulator.tsx @@ -1,7 +1,7 @@ import * as React from "react"; import * as fs from "fs-extra"; import * as path from "path"; -import { ipcRenderer, remote, shell } from "electron"; +import { ipcRenderer, remote, shell, webFrame } from "electron"; import { CONSTANTS, IPC_COMMANDS } from "../constants"; import { getDiskImageSize } from "../utils/disk-image-size"; @@ -14,6 +14,7 @@ import { EmulatorInfo } from "./emulator-info"; export interface EmulatorState { currentUiCard: string; emulator?: any; + scale: number; floppyFile?: string; isBootingFresh: boolean; isCursorCaptured: boolean; @@ -38,7 +39,8 @@ export class Emulator extends React.Component<{}, EmulatorState> { isCursorCaptured: false, isRunning: false, currentUiCard: "start", - isInfoDisplayed: true + isInfoDisplayed: true, + scale: 1 }; this.setupInputListeners(); @@ -123,11 +125,11 @@ export class Emulator extends React.Component<{}, EmulatorState> { if (this.state.emulator && this.state.isRunning) { this.state.emulator.keyboard_send_scancodes([ 0x38, // alt - 0x3E, // f4 + 0x3e, // f4 // break codes 0x38 | 0x80, - 0x3E | 0x80 + 0x3e | 0x80 ]); } }); @@ -157,6 +159,14 @@ export class Emulator extends React.Component<{}, EmulatorState> { ipcRenderer.on(IPC_COMMANDS.SHOW_DISK_IMAGE, () => { this.showDiskImage(); }); + + ipcRenderer.on(IPC_COMMANDS.ZOOM_IN, () => { + this.setScale(this.state.scale * 1.2); + }); + + ipcRenderer.on(IPC_COMMANDS.ZOOM_OUT, () => { + this.setScale(this.state.scale * 0.8); + }); } /** @@ -428,4 +438,18 @@ export class Emulator extends React.Component<{}, EmulatorState> { ); } } + + /** + * Set the emulator's scale + * + * @param target + */ + private setScale(target: number) { + const { emulator, isRunning } = this.state; + + if (emulator && isRunning) { + emulator.screen_set_scale(target); + this.setState({ scale: target }); + } + } }