Skip to content

Commit

Permalink
feat: adds keyboard shortcuts (#1404)
Browse files Browse the repository at this point in the history
Signed-off-by: Pedro Lamas <pedrolamas@gmail.com>
  • Loading branch information
pedrolamas committed Apr 7, 2024
1 parent 5cf9a49 commit 79a6bcc
Show file tree
Hide file tree
Showing 21 changed files with 442 additions and 60 deletions.
1 change: 1 addition & 0 deletions components.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ declare module 'vue' {
BedScrewsAdjustDialog: typeof import('./src/components/common/BedScrewsAdjustDialog.vue')['default']
CollapsableCard: typeof import('./src/components/common/CollapsableCard.vue')['default']
FlashMessage: typeof import('./src/components/common/FlashMessage.vue')['default']
KeyboardShortcutsDialog: typeof import('./src/components/common/KeyboardShortcutsDialog.vue')['default']
KlippyStatusCard: typeof import('./src/components/common/KlippyStatusCard.vue')['default']
ManualProbeDialog: typeof import('./src/components/common/ManualProbeDialog.vue')['default']
PeripheralsDialog: typeof import('./src/components/common/PeripheralsDialog.vue')['default']
Expand Down
65 changes: 63 additions & 2 deletions src/App.vue
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@
<updating-dialog />
<spool-selection-dialog />
<action-command-prompt-dialog />
<keyboard-shortcuts-dialog />
</v-main>
<app-footer />
Expand All @@ -110,6 +111,8 @@ import type { FlashMessage } from '@/types'
import { getFilesFromDataTransfer, hasFilesInDataTransfer } from './util/file-system-entry'
import type { ThemeConfig } from '@/store/config/types'
import ActionCommandPromptDialog from './components/common/ActionCommandPromptDialog.vue'
import KeyboardShortcutsDialog from './components/common/KeyboardShortcutsDialog.vue'
import { eventTargetIsContentEditable, keyboardEventToKeyboardShortcut } from './util/event-helpers'
@Component<App>({
metaInfo () {
Expand All @@ -122,13 +125,13 @@ import ActionCommandPromptDialog from './components/common/ActionCommandPromptDi
components: {
SpoolSelectionDialog,
FileSystemDownloadDialog,
ActionCommandPromptDialog
ActionCommandPromptDialog,
KeyboardShortcutsDialog
}
})
export default class App extends Mixins(StateMixin, FilesMixin, BrowserMixin) {
toolsdrawer: boolean | null = null
navdrawer: boolean | null = null
showUpdateUI = false
dragState = false
customBackgroundImageStyle: Record<string, string> = {}
Expand Down Expand Up @@ -317,11 +320,16 @@ export default class App extends Mixins(StateMixin, FilesMixin, BrowserMixin) {
}
}
get enableKeyboardShortcuts (): boolean {
return this.$store.state.config.uiSettings.general.enableKeyboardShortcuts
}
mounted () {
window.addEventListener('dragover', this.handleDragOver)
window.addEventListener('dragenter', this.handleDragEnter)
window.addEventListener('dragleave', this.handleDragLeave)
window.addEventListener('drop', this.handleDrop)
window.addEventListener('keydown', this.handleKeyDown, false)
// this.onLoadLocale(this.$i18n.locale)
EventBus.bus.$on('flashMessage', (payload: FlashMessage) => {
Expand Down Expand Up @@ -354,6 +362,7 @@ export default class App extends Mixins(StateMixin, FilesMixin, BrowserMixin) {
window.removeEventListener('dragenter', this.handleDragEnter)
window.removeEventListener('dragleave', this.handleDragLeave)
window.removeEventListener('drop', this.handleDrop)
window.removeEventListener('keydown', this.handleKeyDown)
}
handleToolsDrawerChange () {
Expand Down Expand Up @@ -425,6 +434,58 @@ export default class App extends Mixins(StateMixin, FilesMixin, BrowserMixin) {
}
}
}
handleKeyDown (event: KeyboardEvent) {
if (!this.enableKeyboardShortcuts) {
return
}
const shortcut = keyboardEventToKeyboardShortcut(event)
if (shortcut === 'Ctrl+Alt+F12') {
event.preventDefault()
this.emergencyStop()
return
}
if (
!this.klippyReady ||
eventTargetIsContentEditable(event)
) {
return
}
switch (shortcut) {
case 'Shift+C':
if (
this.printerPrinting ||
this.printerPaused
) {
event.preventDefault()
this.cancelPrint()
}
break
case 'Shift+P':
if (this.printerPrinting) {
event.preventDefault()
this.pausePrint()
}
break
case 'Shift+H':
if (!this.printerPrinting) {
event.preventDefault()
this.homeAll()
}
break
}
}
}
</script>
Expand Down
166 changes: 166 additions & 0 deletions src/components/common/KeyboardShortcutsDialog.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,166 @@
<template>
<app-dialog
v-model="open"
:title="$t('app.keyboard_shortcuts.title.keyboard_shortcuts')"
max-width="400"
no-actions
>
<v-card-text class="pa-0">
<v-card flat>
<v-card-title>{{ $t('app.keyboard_shortcuts.label.navigation') }}</v-card-title>

<v-simple-table dense>
<tbody>
<tr>
<th>{{ $t('app.general.title.home') }}</th>
<td><kbd>{{ keyboardShortcuts.home }}</kbd></td>
</tr>
<tr>
<th>{{ $t('app.general.title.console') }}</th>
<td><kbd>{{ keyboardShortcuts.console }}</kbd></td>
</tr>
<tr>
<th>{{ $t('app.general.title.gcode_preview') }}</th>
<td><kbd>{{ keyboardShortcuts.preview }}</kbd></td>
</tr>
<tr>
<th>{{ $t('app.general.title.jobs') }}</th>
<td><kbd>{{ keyboardShortcuts.jobs }}</kbd></td>
</tr>
<tr v-if="supportsHistory">
<th>{{ $t('app.general.title.history') }}</th>
<td><kbd>{{ keyboardShortcuts.history }}</kbd></td>
</tr>
<tr v-if="supportsTimelapse">
<th>{{ $t('app.general.title.timelapse') }}</th>
<td><kbd>{{ keyboardShortcuts.timelapse }}</kbd></td>
</tr>
<tr>
<th>{{ $t('app.general.title.tune') }}</th>
<td><kbd>{{ keyboardShortcuts.tune }}</kbd></td>
</tr>
<tr v-if="enableDiagnostics">
<th>{{ $t('app.general.title.diagnostics') }}</th>
<td><kbd>{{ keyboardShortcuts.diagnostics }}</kbd></td>
</tr>
<tr>
<th>{{ $t('app.general.title.configure') }}</th>
<td><kbd>{{ keyboardShortcuts.configure }}</kbd></td>
</tr>
<tr>
<th>{{ $t('app.general.title.system') }}</th>
<td><kbd>{{ keyboardShortcuts.system }}</kbd></td>
</tr>
<tr>
<th>{{ $t('app.general.title.settings') }}</th>
<td><kbd>{{ keyboardShortcuts.settings }}</kbd></td>
</tr>
</tbody>
</v-simple-table>
</v-card>

<v-card flat>
<v-card-title>{{ $t('app.keyboard_shortcuts.label.tool') }}</v-card-title>

<v-simple-table dense>
<tbody>
<tr>
<th>{{ $t('app.keyboard_shortcuts.label.home_all') }}</th>
<td><kbd>Shift</kbd> + <kbd>h</kbd></td>
</tr>
</tbody>
</v-simple-table>
</v-card>

<v-card flat>
<v-card-title>{{ $t('app.keyboard_shortcuts.label.printing') }}</v-card-title>

<v-simple-table dense>
<tbody>
<tr>
<th>{{ $t('app.keyboard_shortcuts.label.pause') }}</th>
<td><kbd>Shift</kbd> + <kbd>p</kbd></td>
</tr>
<tr>
<th>{{ $t('app.keyboard_shortcuts.label.cancel') }}</th>
<td><kbd>Shift</kbd> + <kbd>c</kbd></td>
</tr>
</tbody>
</v-simple-table>
</v-card>

<v-card flat>
<v-card-title>{{ $t('app.keyboard_shortcuts.label.actions') }}</v-card-title>

<v-simple-table dense>
<tbody>
<tr>
<th>{{ $t('app.keyboard_shortcuts.label.emergency_stop') }}</th>
<td><kbd>Ctrl</kbd> + <kbd>Alt</kbd> + <kbd>F12</kbd></td>
</tr>
<tr>
<th>{{ $t('app.keyboard_shortcuts.label.open_keyboard_shortcut_help') }}</th>
<td><kbd>?</kbd></td>
</tr>
</tbody>
</v-simple-table>
</v-card>
</v-card-text>
</app-dialog>
</template>

<script lang="ts">
import { Globals } from '@/globals'
import { eventTargetIsContentEditable, keyboardEventToKeyboardShortcut } from '@/util/event-helpers'
import { Component, Vue } from 'vue-property-decorator'
@Component({})
export default class KeyboardShortcutsDialog extends Vue {
open = false
get keyboardShortcuts () {
return Globals.KEYBOARD_SHORTCUTS
}
get enableKeyboardShortcuts (): boolean {
return this.$store.state.config.uiSettings.general.enableKeyboardShortcuts
}
get supportsHistory (): boolean {
return this.$store.getters['server/componentSupport']('history')
}
get supportsTimelapse (): boolean {
return this.$store.getters['server/componentSupport']('timelapse')
}
get enableDiagnostics (): boolean {
return this.$store.state.config.uiSettings.general.enableDiagnostics
}
handleKeyDown (event: KeyboardEvent) {
if (!this.enableKeyboardShortcuts) {
return
}
const shortcut = keyboardEventToKeyboardShortcut(event)
if (
['?', 'Shift+?'].includes(shortcut) &&
!eventTargetIsContentEditable(event)
) {
event.preventDefault()
this.open = true
}
}
created () {
window.addEventListener('keydown', this.handleKeyDown, false)
}
beforeDestroy () {
window.removeEventListener('keydown', this.handleKeyDown)
}
}
</script>
12 changes: 11 additions & 1 deletion src/components/layout/AppBar.vue
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,13 @@
</v-icon>
</app-btn>
</template>
<span>{{ $t('app.general.tooltip.estop') }}</span>
<span>
{{ $t('app.general.tooltip.estop') }}
<template v-if="enableKeyboardShortcuts">
<br>
<kbd>Ctrl</kbd> + <kbd>Alt</kbd> + <kbd>F12</kbd>
</template>
</span>
</v-tooltip>
</div>

Expand Down Expand Up @@ -335,6 +341,10 @@ export default class AppBar extends Mixins(StateMixin, ServicesMixin, FilesMixin
return true
}
get enableKeyboardShortcuts (): boolean {
return this.$store.state.config.uiSettings.general.enableKeyboardShortcuts
}
handleExitLayout () {
this.$store.commit('config/setLayoutMode', false)
}
Expand Down
4 changes: 0 additions & 4 deletions src/components/layout/AppNavDrawer.vue
Original file line number Diff line number Diff line change
Expand Up @@ -141,10 +141,6 @@ export default class AppNavDrawer extends Mixins(StateMixin, BrowserMixin) {
return this.$store.getters['server/componentSupport']('timelapse')
}
get supportsVersions () {
return this.$store.getters['server/componentSupport']('update_manager')
}
get enableDiagnostics () {
return this.$store.state.config.uiSettings.general.enableDiagnostics
}
Expand Down
26 changes: 26 additions & 0 deletions src/components/settings/GeneralSettings.vue
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,20 @@

<v-divider />

<app-setting
:title="$t('app.setting.label.keyboard_shortcuts')"
:sub-title="$t('app.setting.tooltip.keyboard_shortcuts')"
>
<v-switch
v-model="enableKeyboardShortcuts"
hide-details
class="mb-5"
@click.native.stop
/>
</app-setting>

<v-divider />

<app-setting :title="$t('app.setting.label.confirm_on_estop')">
<v-switch
v-model="confirmOnEstop"
Expand Down Expand Up @@ -302,6 +316,18 @@ export default class GeneralSettings extends Mixins(StateMixin) {
}))
}
get enableKeyboardShortcuts (): boolean {
return this.$store.state.config.uiSettings.general.enableKeyboardShortcuts
}
set enableKeyboardShortcuts (value: boolean) {
this.$store.dispatch('config/saveByPath', {
path: 'uiSettings.general.enableKeyboardShortcuts',
value,
server: true
})
}
get confirmOnEstop () {
return this.$store.state.config.uiSettings.general.confirmOnEstop
}
Expand Down

0 comments on commit 79a6bcc

Please sign in to comment.