Typescript - Handle popup menu on alt key press

This commit is contained in:
Kiran Niranjan 2018-12-04 15:57:23 +05:30
parent 1803469ea0
commit c468e581ad
4 changed files with 61 additions and 8 deletions

View File

@ -91,11 +91,11 @@ export class AppMenu {
/** /**
* Displays popup application at the x,y coordinates * Displays popup application at the x,y coordinates
* *
* @param window {Electron.BrowserWindow} * @param opts {Electron.PopupOptions}
*/ */
public popupMenu(window: Electron.BrowserWindow): void { public popupMenu(opts: Electron.PopupOptions): void {
if (this.menu) { if (this.menu) {
this.menu.popup({ window, x: 20, y: 15 }); this.menu.popup(opts);
} else { } else {
logger.error(`app-menu: tried popup menu, but failed menu not defined`); logger.error(`app-menu: tried popup menu, but failed menu not defined`);
} }

View File

@ -3,8 +3,13 @@ import { BrowserWindow, ipcMain } from 'electron';
import { apiCmds, apiName, IApiArgs } from '../common/api-interface'; import { apiCmds, apiName, IApiArgs } from '../common/api-interface';
import { LocaleType } from '../common/i18n'; import { LocaleType } from '../common/i18n';
import { logger } from '../common/logger'; import { logger } from '../common/logger';
import { windowHandler } from './window-handler'; import {
import { isValidWindow, setDataUrl, showBadgeCount, updateLocale } from './window-utils'; isValidWindow,
setDataUrl,
showBadgeCount,
showPopupMenu,
updateLocale,
} from './window-utils';
/** /**
* Handle API related ipc messages from renderers. Only messages from windows * Handle API related ipc messages from renderers. Only messages from windows
@ -82,8 +87,7 @@ ipcMain.on(apiName.symphonyApi, (event: Electron.Event, arg: IApiArgs) => {
case apiCmds.popupMenu: { case apiCmds.popupMenu: {
const browserWin = BrowserWindow.fromWebContents(event.sender); const browserWin = BrowserWindow.fromWebContents(event.sender);
if (browserWin && !browserWin.isDestroyed()) { if (browserWin && !browserWin.isDestroyed()) {
const appMenu = windowHandler.appMenu; showPopupMenu({ window: browserWin });
if (appMenu) appMenu.popupMenu(browserWin);
} }
break; break;
} }

View File

@ -205,3 +205,16 @@ export const updateLocale = (locale: LocaleType): void => {
const appMenu = windowHandler.appMenu; const appMenu = windowHandler.appMenu;
if (appMenu) appMenu.update(locale); if (appMenu) appMenu.update(locale);
}; };
/**
* Displays a popup menu
*/
export const showPopupMenu = (opts: Electron.PopupOptions): void => {
const mainWindow = windowHandler.getMainWindow();
if (mainWindow && !mainWindow.isDestroyed() && isValidWindow(mainWindow)) {
const { x, y } = mainWindow.isFullScreen() ? { x: 0, y: 0 } : { x: 10, y: -20 };
const popupOpts = { window: mainWindow, x, y };
const appMenu = windowHandler.appMenu;
if (appMenu) appMenu.popupMenu({ ...popupOpts, ...opts });
}
};

View File

@ -3,6 +3,7 @@ import * as React from 'react';
import { apiCmds, apiName } from '../common/api-interface'; import { apiCmds, apiName } from '../common/api-interface';
import { i18n } from '../common/i18n'; import { i18n } from '../common/i18n';
import { throttle } from '../common/utils';
interface IState { interface IState {
isMaximized: boolean; isMaximized: boolean;
@ -10,8 +11,13 @@ interface IState {
titleBarHeight: string; titleBarHeight: string;
} }
const enum KeyCodes {
Esc = 27,
Alt = 18,
}
export default class WindowsTitleBar extends React.Component<{}, IState> { export default class WindowsTitleBar extends React.Component<{}, IState> {
private window: Electron.BrowserWindow; private readonly window: Electron.BrowserWindow;
private readonly eventHandlers = { private readonly eventHandlers = {
onClose: () => this.close(), onClose: () => this.close(),
onMaximize: () => this.maximize(), onMaximize: () => this.maximize(),
@ -19,10 +25,14 @@ export default class WindowsTitleBar extends React.Component<{}, IState> {
onShowMenu: () => this.showMenu(), onShowMenu: () => this.showMenu(),
onUnmaximize: () => this.unmaximize(), onUnmaximize: () => this.unmaximize(),
}; };
private isAltKey: boolean;
private isMenuOpen: boolean;
constructor(props) { constructor(props) {
super(props); super(props);
this.window = remote.getCurrentWindow(); this.window = remote.getCurrentWindow();
this.isAltKey = false;
this.isMenuOpen = false;
this.state = { this.state = {
isFullScreen: this.window.isFullScreen(), isFullScreen: this.window.isFullScreen(),
isMaximized: this.window.isMaximized(), isMaximized: this.window.isMaximized(),
@ -37,6 +47,32 @@ export default class WindowsTitleBar extends React.Component<{}, IState> {
this.window.on('unmaximize', () => this.updateState({ isMaximized: false })); this.window.on('unmaximize', () => this.updateState({ isMaximized: false }));
this.window.on('enter-full-screen', () => this.updateState({ isFullScreen: true })); this.window.on('enter-full-screen', () => this.updateState({ isFullScreen: true }));
this.window.on('leave-full-screen', () => this.updateState({ isFullScreen: false })); this.window.on('leave-full-screen', () => this.updateState({ isFullScreen: false }));
// Handle key down events
const throttledKeyDown = throttle( (event) => {
this.isAltKey = event.keyCode === KeyCodes.Alt;
}, 500);
// Handle key up events
const throttledKeyUp = throttle( (event) => {
if (this.isAltKey && (event.keyCode === KeyCodes.Alt || KeyCodes.Esc)) {
this.isMenuOpen = !this.isMenuOpen;
}
if (this.isAltKey && this.isMenuOpen && event.keyCode === KeyCodes.Alt) {
this.showMenu();
}
}, 500);
// Handle mouse down event
const throttleMouseDown = throttle(() => {
if (this.isAltKey && this.isMenuOpen) {
this.isMenuOpen = !this.isMenuOpen;
}
}, 500);
window.addEventListener('keyup', throttledKeyUp, true);
window.addEventListener('keydown', throttledKeyDown, true);
window.addEventListener('mousedown', throttleMouseDown, { capture: true });
} }
public componentDidMount() { public componentDidMount() {