mirror of
https://github.com/WowUp/WowUp.git
synced 2026-04-23 15:27:03 -04:00
Custom keyboard shortcuts
This commit is contained in:
@@ -299,9 +299,9 @@ function getAppMenu(): Array<MenuItemConstructorOptions | MenuItem> {
|
||||
{ role: "forceReload" },
|
||||
{ role: "toggleDevTools", accelerator: "CommandOrControl+Shift+I" },
|
||||
{ type: "separator" },
|
||||
{ role: "resetZoom" },
|
||||
{ role: "zoomIn", accelerator: "CommandOrControl+=" },
|
||||
{ role: "zoomOut" },
|
||||
// { role: "resetZoom" },
|
||||
// { role: "zoomIn", accelerator: "CommandOrControl+=" },
|
||||
// { role: "zoomOut" },
|
||||
{ type: "separator" },
|
||||
{ role: "togglefullscreen" },
|
||||
],
|
||||
@@ -312,10 +312,10 @@ function getAppMenu(): Array<MenuItemConstructorOptions | MenuItem> {
|
||||
{
|
||||
label: "View",
|
||||
submenu: [
|
||||
{ role: "resetZoom" },
|
||||
// { role: "resetZoom" },
|
||||
{ role: "toggleDevTools" },
|
||||
{ role: "zoomIn", accelerator: "CommandOrControl+=" },
|
||||
{ role: "zoomOut" },
|
||||
// { role: "zoomIn", accelerator: "CommandOrControl+=" },
|
||||
// { role: "zoomOut" },
|
||||
{ type: "separator" },
|
||||
{ role: "togglefullscreen" },
|
||||
],
|
||||
@@ -346,9 +346,9 @@ function getAppMenu(): Array<MenuItemConstructorOptions | MenuItem> {
|
||||
{ role: "forceReload" },
|
||||
{ role: "toggleDevTools" },
|
||||
{ type: "separator" },
|
||||
{ role: "resetZoom" },
|
||||
{ role: "zoomIn", accelerator: "CommandOrControl+=" },
|
||||
{ role: "zoomOut" },
|
||||
// { role: "resetZoom" },
|
||||
// { role: "zoomIn", accelerator: "CommandOrControl+=" },
|
||||
// { role: "zoomOut" },
|
||||
{ type: "separator" },
|
||||
{ role: "togglefullscreen" },
|
||||
],
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
import { AfterViewInit, ChangeDetectionStrategy, Component, OnInit } from "@angular/core";
|
||||
import { AfterViewInit, ChangeDetectionStrategy, Component, HostListener, OnInit } from "@angular/core";
|
||||
import { MatDialog } from "@angular/material/dialog";
|
||||
import { TranslateService } from "@ngx-translate/core";
|
||||
import { OverlayContainer } from "@angular/cdk/overlay";
|
||||
import { filter } from "rxjs/operators";
|
||||
import {
|
||||
ALLIANCE_LIGHT_THEME,
|
||||
ALLIANCE_THEME,
|
||||
@@ -21,7 +22,7 @@ import { FileService } from "./services/files/file.service";
|
||||
import { WowUpService } from "./services/wowup/wowup.service";
|
||||
import { IconService } from "./services/icons/icon.service";
|
||||
import { SessionService } from "./services/session/session.service";
|
||||
import { filter } from "rxjs/operators";
|
||||
import { getZoomDirection, ZoomDirection } from "./utils/zoom.utils";
|
||||
|
||||
const AUTO_UPDATE_PERIOD_MS = 60 * 60 * 1000; // 1 hour
|
||||
|
||||
@@ -34,6 +35,12 @@ const AUTO_UPDATE_PERIOD_MS = 60 * 60 * 1000; // 1 hour
|
||||
export class AppComponent implements OnInit, AfterViewInit {
|
||||
private _autoUpdateInterval?: number;
|
||||
|
||||
@HostListener("document:keydown", ["$event"])
|
||||
handleKeyboardEvent(event: KeyboardEvent) {
|
||||
const zoomDirection = getZoomDirection(event);
|
||||
this._electronService.applyZoom(zoomDirection);
|
||||
}
|
||||
|
||||
public get quitEnabled() {
|
||||
return this._electronService.appOptions.quit;
|
||||
}
|
||||
|
||||
@@ -76,10 +76,8 @@
|
||||
{{ "PAGES.OPTIONS.APPLICATION.ENABLE_SYSTEM_NOTIFICATIONS_LABEL" | translate }}
|
||||
</div>
|
||||
</div>
|
||||
<mat-slide-toggle
|
||||
[checked]="wowupService.enableSystemNotifications"
|
||||
(change)="onEnableSystemNotifications($event)"
|
||||
>
|
||||
<mat-slide-toggle [checked]="wowupService.enableSystemNotifications"
|
||||
(change)="onEnableSystemNotifications($event)">
|
||||
</mat-slide-toggle>
|
||||
</div>
|
||||
<small class="text-2">
|
||||
@@ -108,11 +106,8 @@
|
||||
</div>
|
||||
<small class="text-2">{{ "PAGES.OPTIONS.APPLICATION.START_WITH_SYSTEM_DESCRIPTION" | translate }}</small>
|
||||
</div>
|
||||
<mat-slide-toggle
|
||||
[(ngModel)]="startWithSystem"
|
||||
[(checked)]="startWithSystem"
|
||||
(change)="onStartWithSystemChange($event)"
|
||||
>
|
||||
<mat-slide-toggle [(ngModel)]="startWithSystem" [(checked)]="startWithSystem"
|
||||
(change)="onStartWithSystemChange($event)">
|
||||
</mat-slide-toggle>
|
||||
</div>
|
||||
</div>
|
||||
@@ -125,12 +120,8 @@
|
||||
</div>
|
||||
<small class="text-2">{{ "PAGES.OPTIONS.APPLICATION.START_MINIMIZED_DESCRIPTION" | translate }}</small>
|
||||
</div>
|
||||
<mat-slide-toggle
|
||||
[(ngModel)]="startMinimized"
|
||||
[(disabled)]="!startWithSystem"
|
||||
[(checked)]="startMinimized"
|
||||
(change)="onStartMinimizedChange($event)"
|
||||
>
|
||||
<mat-slide-toggle [(ngModel)]="startMinimized" [(disabled)]="!startWithSystem" [(checked)]="startMinimized"
|
||||
(change)="onStartMinimizedChange($event)">
|
||||
</mat-slide-toggle>
|
||||
</div>
|
||||
</div>
|
||||
@@ -141,14 +132,11 @@
|
||||
<small class="text-2">{{ "PAGES.OPTIONS.APPLICATION.SCALE_DESCRIPTION" | translate }}</small>
|
||||
</div>
|
||||
<mat-form-field class="light-select">
|
||||
<mat-select
|
||||
[(value)]="currentScale"
|
||||
(selectionChange)="onScaleChange($event)"
|
||||
>
|
||||
<mat-option *ngFor="let value of allowedScales" [value]="value">
|
||||
<mat-select [(value)]="currentScale" (selectionChange)="onScaleChange($event)">
|
||||
<mat-option *ngFor="let value of zoomScale" [value]="value">
|
||||
{{ value * 100 | number:'1.0-0' }} %
|
||||
</mat-option>
|
||||
</mat-select>
|
||||
</mat-form-field>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Component, OnInit } from "@angular/core";
|
||||
import { ChangeDetectorRef, Component, OnInit } from "@angular/core";
|
||||
import { MatDialog } from "@angular/material/dialog";
|
||||
import { MatSelectChange } from "@angular/material/select";
|
||||
import { MatSlideToggleChange } from "@angular/material/slide-toggle";
|
||||
@@ -17,6 +17,7 @@ import {
|
||||
HORDE_LIGHT_THEME,
|
||||
HORDE_THEME,
|
||||
} from "../../../common/constants";
|
||||
import { ZOOM_SCALE } from "../../utils/zoom.utils";
|
||||
|
||||
interface LocaleListItem {
|
||||
localeId: string;
|
||||
@@ -36,6 +37,8 @@ export class OptionsAppSectionComponent implements OnInit {
|
||||
public telemetryEnabled = false;
|
||||
public useHardwareAcceleration = true;
|
||||
public currentLanguage: string = "";
|
||||
public zoomScale = ZOOM_SCALE;
|
||||
public currentScale = 1;
|
||||
public languages: LocaleListItem[] = [
|
||||
{ localeId: "en", label: "English" },
|
||||
{ localeId: "de", label: "Deutsch" },
|
||||
@@ -52,31 +55,29 @@ export class OptionsAppSectionComponent implements OnInit {
|
||||
|
||||
public themeGroups: ThemeGroup[] = [
|
||||
{
|
||||
name: 'APP.THEME.GROUP_DARK', themes: [
|
||||
name: "APP.THEME.GROUP_DARK",
|
||||
themes: [
|
||||
{ display: "APP.THEME.DEFAULT", class: DEFAULT_THEME },
|
||||
{ display: "APP.THEME.ALLIANCE", class: ALLIANCE_THEME },
|
||||
{ display: "APP.THEME.HORDE", class: HORDE_THEME },
|
||||
]
|
||||
],
|
||||
},
|
||||
{
|
||||
name: 'APP.THEME.GROUP_LIGHT', themes: [
|
||||
name: "APP.THEME.GROUP_LIGHT",
|
||||
themes: [
|
||||
{ display: "APP.THEME.DEFAULT", class: DEFAULT_LIGHT_THEME },
|
||||
{ display: "APP.THEME.ALLIANCE", class: ALLIANCE_LIGHT_THEME },
|
||||
{ display: "APP.THEME.HORDE", class: HORDE_LIGHT_THEME },
|
||||
]
|
||||
],
|
||||
},
|
||||
]
|
||||
|
||||
public allowedScales = [-2.5, -2, -1.5, -1, -0.5, 0, 0.5, 1, 1.5, 2, 2.5, 3, 3.5, 4, 4.5, 5, 5.5, 6].map(
|
||||
(x) => Math.pow(1.2, x)
|
||||
);
|
||||
public currentScale = 1;
|
||||
];
|
||||
|
||||
constructor(
|
||||
private _analyticsService: AnalyticsService,
|
||||
private _dialog: MatDialog,
|
||||
private _electronService: ElectronService,
|
||||
private _translateService: TranslateService,
|
||||
private _cdRef: ChangeDetectorRef,
|
||||
public electronService: ElectronService,
|
||||
public sessionService: SessionService,
|
||||
public wowupService: WowUpService
|
||||
) {}
|
||||
@@ -86,7 +87,7 @@ export class OptionsAppSectionComponent implements OnInit {
|
||||
this.telemetryEnabled = enabled;
|
||||
});
|
||||
|
||||
const minimizeOnCloseKey = this._electronService.isWin
|
||||
const minimizeOnCloseKey = this.electronService.isWin
|
||||
? "PAGES.OPTIONS.APPLICATION.MINIMIZE_ON_CLOSE_DESCRIPTION_WINDOWS"
|
||||
: "PAGES.OPTIONS.APPLICATION.MINIMIZE_ON_CLOSE_DESCRIPTION_MAC";
|
||||
|
||||
@@ -101,13 +102,18 @@ export class OptionsAppSectionComponent implements OnInit {
|
||||
this.startMinimized = this.wowupService.startMinimized;
|
||||
this.currentLanguage = this.wowupService.currentLanguage;
|
||||
|
||||
if (window.require("electron").remote) {
|
||||
if (this.electronService.remote) {
|
||||
this.updateScale();
|
||||
const currentWindow = window.require("electron").remote.getCurrentWindow();
|
||||
currentWindow.webContents.on('zoom-changed', (event, arg) => {
|
||||
this.updateScale()
|
||||
const currentWindow = this.electronService.remote.getCurrentWindow();
|
||||
currentWindow.webContents.on("zoom-changed", (event, arg) => {
|
||||
this.updateScale();
|
||||
});
|
||||
}
|
||||
|
||||
this.electronService.zoomFactor$.subscribe((zoomFactor) => {
|
||||
this.currentScale = zoomFactor;
|
||||
this._cdRef.detectChanges();
|
||||
});
|
||||
}
|
||||
|
||||
onEnableSystemNotifications = (evt: MatSlideToggleChange) => {
|
||||
@@ -154,7 +160,7 @@ export class OptionsAppSectionComponent implements OnInit {
|
||||
}
|
||||
|
||||
this.wowupService.useHardwareAcceleration = evt.checked;
|
||||
this._electronService.restartApplication();
|
||||
this.electronService.restartApplication();
|
||||
});
|
||||
};
|
||||
|
||||
@@ -173,19 +179,17 @@ export class OptionsAppSectionComponent implements OnInit {
|
||||
}
|
||||
|
||||
this.wowupService.currentLanguage = evt.value;
|
||||
this._electronService.restartApplication();
|
||||
this.electronService.restartApplication();
|
||||
});
|
||||
};
|
||||
|
||||
onScaleChange = (evt: MatSelectChange) => {
|
||||
let newScale = evt.value;
|
||||
const currentWindow = window.require("electron").remote.getCurrentWindow();
|
||||
currentWindow.webContents.zoomFactor = newScale;
|
||||
public onScaleChange = (evt: MatSelectChange) => {
|
||||
const newScale = evt.value;
|
||||
this.electronService.setZoomFactor(newScale);
|
||||
this.currentScale = newScale;
|
||||
};
|
||||
|
||||
updateScale() {
|
||||
const currentWindow = window.require("electron").remote.getCurrentWindow();
|
||||
this.currentScale = currentWindow.webContents.zoomFactor;
|
||||
};
|
||||
private updateScale() {
|
||||
this.currentScale = this.electronService.getZoomFactor();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@ import {
|
||||
APP_UPDATE_DOWNLOADED,
|
||||
APP_UPDATE_START_DOWNLOAD,
|
||||
} from "../../../common/constants";
|
||||
import * as minimist from "minimist";
|
||||
// If you import a module but never use any of the imported values other than as TypeScript types,
|
||||
// the resulting javascript file will look as if you never imported the module at all.
|
||||
import { ipcRenderer, remote, Settings, shell, webFrame } from "electron";
|
||||
@@ -17,7 +18,7 @@ import { IpcResponse } from "../../../common/models/ipc-response";
|
||||
import { ValueRequest } from "../../../common/models/value-request";
|
||||
import { ValueResponse } from "../../../common/models/value-response";
|
||||
import { AppOptions } from "../../../common/wowup/app-options";
|
||||
import * as minimist from "minimist";
|
||||
import { ZoomDirection, ZOOM_MAX, ZOOM_MIN, ZOOM_STEP } from "../../utils/zoom.utils";
|
||||
|
||||
@Injectable({
|
||||
providedIn: "root",
|
||||
@@ -26,6 +27,7 @@ export class ElectronService {
|
||||
private readonly _windowMaximizedSrc = new BehaviorSubject(false);
|
||||
private readonly _windowMinimizedSrc = new BehaviorSubject(false);
|
||||
private readonly _ipcEventReceivedSrc = new BehaviorSubject("");
|
||||
private readonly _zoomFactorChangeSrc = new BehaviorSubject(1.0);
|
||||
|
||||
ipcRenderer: typeof ipcRenderer;
|
||||
webFrame: typeof webFrame;
|
||||
@@ -37,6 +39,7 @@ export class ElectronService {
|
||||
public readonly windowMaximized$ = this._windowMaximizedSrc.asObservable();
|
||||
public readonly windowMinimized$ = this._windowMinimizedSrc.asObservable();
|
||||
public readonly ipcEventReceived$ = this._ipcEventReceivedSrc.asObservable();
|
||||
public readonly zoomFactor$ = this._zoomFactorChangeSrc.asObservable();
|
||||
public readonly isWin = process.platform === "win32";
|
||||
public readonly isMac = process.platform === "darwin";
|
||||
public readonly isLinux = process.platform === "linux";
|
||||
@@ -128,6 +131,8 @@ export class ElectronService {
|
||||
}
|
||||
});
|
||||
|
||||
this._zoomFactorChangeSrc.next(this.getZoomFactor());
|
||||
|
||||
this.appOptions = (<any>minimist(this.remote.process.argv.slice(1), {
|
||||
boolean: ["hidden", "quit"],
|
||||
})) as AppOptions;
|
||||
@@ -214,4 +219,36 @@ export class ElectronService {
|
||||
public async invoke(channel: string, ...args: any[]): Promise<any> {
|
||||
return await this.ipcRenderer.invoke(channel, ...args);
|
||||
}
|
||||
|
||||
public applyZoom = (zoomDirection: ZoomDirection) => {
|
||||
const zoomFactor = this.getZoomFactor();
|
||||
const zoomInFactor = Math.min(ZOOM_MAX, zoomFactor + ZOOM_STEP);
|
||||
const zoomOutFactor = Math.max(ZOOM_MIN, zoomFactor - ZOOM_STEP);
|
||||
|
||||
switch (zoomDirection) {
|
||||
case ZoomDirection.ZoomIn:
|
||||
this.setZoomFactor(zoomInFactor);
|
||||
break;
|
||||
case ZoomDirection.ZoomOut:
|
||||
this.setZoomFactor(zoomOutFactor);
|
||||
break;
|
||||
case ZoomDirection.ZoomReset:
|
||||
this.setZoomFactor(1.0);
|
||||
break;
|
||||
case ZoomDirection.ZoomUnknown:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
public setZoomFactor = (zoomFactor: number) => {
|
||||
const currentWindow = this.remote.getCurrentWindow();
|
||||
currentWindow.webContents.zoomFactor = zoomFactor;
|
||||
this._zoomFactorChangeSrc.next(zoomFactor);
|
||||
};
|
||||
|
||||
public getZoomFactor(): number {
|
||||
const currentWindow = this.remote.getCurrentWindow();
|
||||
return currentWindow.webContents.zoomFactor;
|
||||
}
|
||||
}
|
||||
|
||||
40
wowup-electron/src/app/utils/zoom.utils.ts
Normal file
40
wowup-electron/src/app/utils/zoom.utils.ts
Normal file
@@ -0,0 +1,40 @@
|
||||
// See https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/code/code_values
|
||||
const ZOOM_IN_CODE = "Equal";
|
||||
const ZOOM_OUT_CODE = "Minus";
|
||||
const ZOOM_RESET_CODE = "Digit0";
|
||||
|
||||
export const ZOOM_SCALE = [0.5, 0.75, 1.0, 1.25, 1.5, 1.75, 2.0, 2.25, 2.5, 2.75, 3.0];
|
||||
export const ZOOM_MIN = ZOOM_SCALE[0];
|
||||
export const ZOOM_MAX = ZOOM_SCALE[ZOOM_SCALE.length - 1];
|
||||
export const ZOOM_STEP = 0.25;
|
||||
|
||||
export enum ZoomDirection {
|
||||
ZoomIn,
|
||||
ZoomOut,
|
||||
ZoomReset,
|
||||
ZoomUnknown,
|
||||
}
|
||||
|
||||
export function isZoomInShortcut(event: KeyboardEvent) {
|
||||
return event.ctrlKey && event.code === ZOOM_IN_CODE;
|
||||
}
|
||||
|
||||
export function isZoomOutShortcut(event: KeyboardEvent) {
|
||||
return event.ctrlKey && event.code === ZOOM_OUT_CODE;
|
||||
}
|
||||
|
||||
export function isZoomResetShortcut(event: KeyboardEvent) {
|
||||
return event.ctrlKey && event.code === ZOOM_RESET_CODE;
|
||||
}
|
||||
|
||||
export function getZoomDirection(event: KeyboardEvent): ZoomDirection {
|
||||
if (isZoomInShortcut(event)) {
|
||||
return ZoomDirection.ZoomIn;
|
||||
} else if (isZoomOutShortcut(event)) {
|
||||
return ZoomDirection.ZoomOut;
|
||||
} else if (isZoomResetShortcut(event)) {
|
||||
return ZoomDirection.ZoomReset;
|
||||
}
|
||||
|
||||
return ZoomDirection.ZoomUnknown;
|
||||
}
|
||||
Reference in New Issue
Block a user