Refactor hotkey definitions to be more generic (#655)

This commit is contained in:
toasted-nutbread 2020-07-08 20:02:20 -04:00 committed by GitHub
parent 6f49f426b5
commit f76a6ff1e3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 76 additions and 115 deletions

View File

@ -40,14 +40,11 @@ class DisplayFloat extends Display {
['setContentScale', {handler: this._onMessageSetContentScale.bind(this)}] ['setContentScale', {handler: this._onMessageSetContentScale.bind(this)}]
]); ]);
this.setOnKeyDownHandlers([ this.registerActions([
['C', (e) => { ['copy-host-selection', () => this._copySelection()]
if (e.ctrlKey && !window.getSelection().toString()) { ]);
this._copySelection(); this.registerHotkeys([
return true; {key: 'C', modifiers: ['ctrl'], action: 'copy-host-selection'}
}
return false;
}]
]); ]);
} }
@ -168,7 +165,9 @@ class DisplayFloat extends Display {
// Private // Private
_copySelection() { _copySelection() {
if (window.getSelection().toString()) { return false; }
this._invoke('copySelection'); this._invoke('copySelection');
return true;
} }
_clearAutoPlayTimer() { _clearAutoPlayTimer() {

View File

@ -56,108 +56,40 @@ class Display {
this._mediaLoader = new MediaLoader(); this._mediaLoader = new MediaLoader();
this._displayGenerator = new DisplayGenerator({mediaLoader: this._mediaLoader}); this._displayGenerator = new DisplayGenerator({mediaLoader: this._mediaLoader});
this._windowScroll = new WindowScroll(); this._windowScroll = new WindowScroll();
this._onKeyDownHandlers = new Map([ this._hotkeys = new Map();
['Escape', () => { this._actions = new Map();
this.onEscape();
return true;
}],
['PageUp', (e) => {
if (e.altKey) {
this._entryScrollIntoView(this._index - 3, null, true);
return true;
}
return false;
}],
['PageDown', (e) => {
if (e.altKey) {
this._entryScrollIntoView(this._index + 3, null, true);
return true;
}
return false;
}],
['End', (e) => {
if (e.altKey) {
this._entryScrollIntoView(this._definitions.length - 1, null, true);
return true;
}
return false;
}],
['Home', (e) => {
if (e.altKey) {
this._entryScrollIntoView(0, null, true);
return true;
}
return false;
}],
['ArrowUp', (e) => {
if (e.altKey) {
this._entryScrollIntoView(this._index - 1, null, true);
return true;
}
return false;
}],
['ArrowDown', (e) => {
if (e.altKey) {
this._entryScrollIntoView(this._index + 1, null, true);
return true;
}
return false;
}],
['B', (e) => {
if (e.altKey) {
this._sourceTermView();
return true;
}
return false;
}],
['F', (e) => {
if (e.altKey) {
this._nextTermView();
return true;
}
return false;
}],
['E', (e) => {
if (e.altKey) {
this._noteTryAdd('term-kanji');
return true;
}
return false;
}],
['K', (e) => {
if (e.altKey) {
this._noteTryAdd('kanji');
return true;
}
return false;
}],
['R', (e) => {
if (e.altKey) {
this._noteTryAdd('term-kana');
return true;
}
return false;
}],
['P', (e) => {
if (e.altKey) {
const index = this._index;
if (index < 0 || index >= this._definitions.length) { return; }
const entry = this._getEntry(index); this.registerActions([
if (entry !== null && entry.dataset.type === 'term') { ['close', () => { this.onEscape(); }],
this._audioPlay(this._definitions[index], this._getFirstExpressionIndex(), index); ['next-entry', () => { this._entryScrollIntoView(this._index + 1, null, true); }],
} ['next-entry-x3', () => { this._entryScrollIntoView(this._index + 3, null, true); }],
return true; ['previous-entry', () => { this._entryScrollIntoView(this._index - 1, null, true); }],
} ['previous-entry-x3', () => { this._entryScrollIntoView(this._index - 3, null, true); }],
return false; ['last-entry', () => { this._entryScrollIntoView(this._definitions.length - 1, null, true); }],
}], ['first-entry', () => { this._entryScrollIntoView(0, null, true); }],
['V', (e) => { ['history-backward', () => { this._sourceTermView(); }],
if (e.altKey) { ['history-forward', () => { this._nextTermView(); }],
this._noteTryView(); ['add-note-kanji', () => { this._noteTryAdd('kanji'); }],
return true; ['add-note-term-kanji', () => { this._noteTryAdd('term-kanji'); }],
} ['add-note-term-kana', () => { this._noteTryAdd('term-kana'); }],
return false; ['view-note', () => { this._noteTryView(); }],
}] ['play-audio', () => { this._playAudioCurrent(); }]
]);
this.registerHotkeys([
{key: 'Escape', modifiers: [], action: 'close'},
{key: 'PageUp', modifiers: ['alt'], action: 'previous-entry-x3'},
{key: 'PageDown', modifiers: ['alt'], action: 'next-entry-x3'},
{key: 'End', modifiers: ['alt'], action: 'last-entry'},
{key: 'Home', modifiers: ['alt'], action: 'first-entry'},
{key: 'ArrowUp', modifiers: ['alt'], action: 'previous-entry'},
{key: 'ArrowDown', modifiers: ['alt'], action: 'next-entry'},
{key: 'B', modifiers: ['alt'], action: 'history-backward'},
{key: 'F', modifiers: ['alt'], action: 'history-forward'},
{key: 'K', modifiers: ['alt'], action: 'add-note-kanji'},
{key: 'E', modifiers: ['alt'], action: 'add-note-term-kanji'},
{key: 'R', modifiers: ['alt'], action: 'add-note-term-kana'},
{key: 'P', modifiers: ['alt'], action: 'play-audio'},
{key: 'V', modifiers: ['alt'], action: 'view-note'}
]); ]);
} }
@ -181,9 +113,18 @@ class Display {
onKeyDown(e) { onKeyDown(e) {
const key = DOM.getKeyFromEvent(e); const key = DOM.getKeyFromEvent(e);
const handler = this._onKeyDownHandlers.get(key); const handlers = this._hotkeys.get(key);
if (typeof handler === 'function') { if (typeof handlers === 'undefined') { return false; }
if (handler(e)) {
const eventModifiers = DOM.getActiveModifiers(e);
for (const {modifiers, action} of handlers) {
if (getSetDifference(modifiers, eventModifiers).size !== 0) { continue; }
const actionHandler = this._actions.get(action);
if (typeof actionHandler === 'undefined') { continue; }
const result = actionHandler(e);
if (result !== false) {
e.preventDefault(); e.preventDefault();
return true; return true;
} }
@ -276,9 +217,20 @@ class Display {
} }
} }
setOnKeyDownHandlers(handlers) { registerActions(actions) {
for (const [key, handler] of handlers) { for (const [name, handler] of actions) {
this._onKeyDownHandlers.set(key, handler); this._actions.set(name, handler);
}
}
registerHotkeys(hotkeys) {
for (const {key, modifiers, action} of hotkeys) {
let handlers = this._hotkeys.get(key);
if (typeof handlers === 'undefined') {
handlers = [];
this._hotkeys.set(key, handlers);
}
handlers.push({modifiers: new Set(modifiers), action});
} }
} }
@ -982,4 +934,14 @@ class Display {
} }
}; };
} }
_playAudioCurrent() {
const index = this._index;
if (index < 0 || index >= this._definitions.length) { return; }
const entry = this._getEntry(index);
if (entry !== null && entry.dataset.type === 'term') {
this._audioPlay(this._definitions[index], this._getFirstExpressionIndex(), index);
}
}
} }