Skip to content

Commit

Permalink
feat: adds keyboard shortcuts
Browse files Browse the repository at this point in the history
Signed-off-by: Pedro Lamas <[email protected]>
  • Loading branch information
pedrolamas committed Apr 2, 2024
1 parent 63d0da3 commit 5223968
Show file tree
Hide file tree
Showing 11 changed files with 282 additions and 4 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
27 changes: 25 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,7 @@ 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'
@Component<App>({
metaInfo () {
Expand All @@ -122,13 +124,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 +319,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 +361,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 +433,21 @@ export default class App extends Mixins(StateMixin, FilesMixin, BrowserMixin) {
}
}
}
handleKeyDown (event: KeyboardEvent) {
const { key, shiftKey, ctrlKey } = event
if (
this.enableKeyboardShortcuts &&
key === 'F12' &&
shiftKey &&
ctrlKey
) {
event.preventDefault()
this.emergencyStop()
}
}
}
</script>

Expand Down
125 changes: 125 additions & 0 deletions src/components/common/KeyboardShortcutsDialog.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
<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>
<th>{{ $t('app.general.title.history') }}</th>
<td><kbd>{{ keyboardShortcuts.history }}</kbd></td>
</tr>
<tr>
<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>
<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.actions') }}</v-card-title>

<v-simple-table dense>
<tbody>
<tr>
<th>{{ $t('app.general.tooltip.estop') }}</th>
<td><kbd>Ctrl</kbd> + <kbd>Shift</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 from '@/util/event-target-is-content-editable'
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
}
handleKeyDown (event: KeyboardEvent) {
if (!this.enableKeyboardShortcuts) {
return
}
const { key, ctrlKey } = event
if (
key === '?' &&
!ctrlKey &&
!eventTargetIsContentEditable(event)
) {
event.preventDefault()
this.open = true
}
}
created () {
window.addEventListener('keydown', this.handleKeyDown, false)
}
beforeDestroy () {
window.removeEventListener('keydown', this.handleKeyDown)
}
}
</script>
23 changes: 23 additions & 0 deletions src/components/settings/GeneralSettings.vue
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,17 @@

<v-divider />

<app-setting :title="$t('app.setting.label.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 +313,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
58 changes: 56 additions & 2 deletions src/components/ui/AppNavItem.vue
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,11 @@
</v-list-item-content>
</v-list-item>
</template>
<span><slot /></span>
<span><slot /><span
v-if="accelerator"
class="ml-2"
v-html="`<kbd>${accelerator}</kbd>`"
/></span>
</v-tooltip>

<!-- <v-tooltip right :disabled="isMobileViewport">
Expand Down Expand Up @@ -52,20 +56,70 @@ import { Component, Mixins, Prop } from 'vue-property-decorator'
import StateMixin from '@/mixins/state'
import BrowserMixin from '@/mixins/browser'
import eventTargetIsContentEditable from '@/util/event-target-is-content-editable'
import { Globals } from '@/globals'
import isKeyOf from '@/util/is-key-of'
@Component({})
export default class AppNavItem extends Mixins(StateMixin, BrowserMixin) {
@Prop({ type: String })
readonly title!: string
@Prop({ type: String })
readonly to?: string
readonly to!: string
@Prop({ type: Boolean })
readonly exact?: boolean
@Prop({ type: String })
readonly icon?: string
get accelerator (): string | undefined {
if (this.to) {
const destination = this.to === '/'
? 'home'
: this.to.substring(1)
return isKeyOf(destination, Globals.KEYBOARD_SHORTCUTS)
? Globals.KEYBOARD_SHORTCUTS[destination]
: undefined
}
}
get enableKeyboardShortcuts (): boolean {
return this.$store.state.config.uiSettings.general.enableKeyboardShortcuts
}
handleKeyDown (event: KeyboardEvent) {
if (
!this.enableKeyboardShortcuts ||
!this.accelerator
) {
return
}
const { key, shiftKey, ctrlKey } = event
if (
key === this.accelerator &&
!shiftKey &&
!ctrlKey &&
!eventTargetIsContentEditable(event) &&
this.$router.currentRoute.path !== this.to
) {
event.preventDefault()
this.$router.push(this.to)
}
}
mounted () {
window.addEventListener('keydown', this.handleKeyDown, false)
}
beforeDestroy () {
window.removeEventListener('keydown', this.handleKeyDown)
}
}
</script>
Expand Down
13 changes: 13 additions & 0 deletions src/globals.ts
Original file line number Diff line number Diff line change
Expand Up @@ -236,6 +236,19 @@ export const Globals = Object.freeze({
FILTERED_FOLDER_NAMES: ['.git'],
FILTERED_FILES_PREFIX: ['.thumbs', 'thumbs'],
FILTERED_FILES_EXTENSION: ['.ignoreme'],
KEYBOARD_SHORTCUTS: {
home: 'h',
console: 'c',
preview: 'p',
jobs: 'j',
history: 'i',
timelapse: 'l',
tune: 't',
diagnostics: 'g',
configure: 'x',
system: 'q',
settings: 's'
},
DOCS_ROOT: 'https://docs.fluidd.xyz',
DOCS_REQUIRED_CONFIGURATION: 'https://docs.fluidd.xyz/configuration/initial_setup',
DOCS_MULTIPLE_INSTANCES: 'https://docs.fluidd.xyz/configuration/multiple_printers',
Expand Down
8 changes: 8 additions & 0 deletions src/locales/en.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -574,6 +574,7 @@ app:
invert_x_control: Invert X control
invert_y_control: Invert Y control
invert_z_control: Invert Z control
keyboard_shortcuts: Keyboard Shortcuts
language: Display Language
last_result: Last result
left_y: Left Y-Axis
Expand Down Expand Up @@ -898,3 +899,10 @@ app:
sensors:
title:
sensors: Sensors
keyboard_shortcuts:
title:
keyboard_shortcuts: Keyboard Shortcuts
label:
actions: Actions
navigation: Navigation
open_keyboard_shortcut_help: Open keyboard shortcut help
4 changes: 4 additions & 0 deletions src/scss/misc.scss
Original file line number Diff line number Diff line change
Expand Up @@ -75,3 +75,7 @@ input[type=number] {
.theme--dark .spool-icon {
stroke: rgba(0,0,0, 0.5);
}

.theme--dark.v-application kbd {
background: #4A4A4F !important;
}
1 change: 1 addition & 0 deletions src/store/config/state.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ export const defaultState = (): ConfigState => {
sectionsToIgnorePendingConfigurationChanges: [],
dateFormat: 'iso',
timeFormat: 'iso',
enableKeyboardShortcuts: true,
textSortOrder: 'default',
showRateOfChange: false,
showRelativeHumidity: true,
Expand Down
1 change: 1 addition & 0 deletions src/store/config/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ export interface GeneralConfig {
sectionsToIgnorePendingConfigurationChanges: string[];
dateFormat: string;
timeFormat: string;
enableKeyboardShortcuts: boolean;
textSortOrder: TextSortOrder;
showRateOfChange: boolean;
showRelativeHumidity: boolean;
Expand Down
Loading

0 comments on commit 5223968

Please sign in to comment.