UNPKG

smoosic

Version:

<sub>[Github site](https://github.com/Smoosic/smoosic) | [source documentation](https://smoosic.github.io/Smoosic/release/docs/modules.html) | [change notes](https://aarondavidnewman.github.io/Smoosic/changes.html) | [application](https://smoosic.github.i

244 lines (220 loc) 6.81 kB
// [Smoosic](https://github.com/AaronDavidNewman/Smoosic) // Copyright (c) Aaron David Newman 2021. import { SuiTempoDialog } from '../ui/dialogs/tempo'; import { createAndDisplayDialog } from '../ui/dialogs/dialog'; import { SuiAudioPlayer } from '../render/audio/player'; import { SmoArticulation } from '../smo/data/noteModifiers'; import { SuiScoreViewOperations } from '../render/sui/scoreViewOperations'; import { BrowserEventSource } from '../ui/eventSource'; import { SuiTracker } from '../render/sui/tracker'; import { KeyCommandParams } from './common'; import { CompleteNotifier } from '../ui/common'; import { PitchLetter, IsPitchLetter, KeyEvent, keyHandler, defaultKeyEvent } from '../smo/data/common'; export interface EditorKeyHandler { transposeUp: keyHandler, transposeDown: keyHandler, upOctave: keyHandler, toggleCourtesyAccidental: keyHandler, toggleEnharmonic: keyHandler, doubleDuration: keyHandler, halveDuration: keyHandler, dotDuration: keyHandler, undotDuration: keyHandler, setPitch: keyHandler, slashGraceNotes: keyHandler, addGraceNote: keyHandler, removeGraceNote: keyHandler, playScore: keyHandler, stopPlayer: keyHandler, makeTuplet: keyHandler, interval: keyHandler, unmakeTuplet: keyHandler, addMeasure: keyHandler, deleteNote: keyHandler, unbeamSelections: keyHandler, beamSelections: keyHandler, addRemoveAccent: keyHandler, addRemoveTenuto: keyHandler, addRemoveStaccato: keyHandler } /** * KeyCommands object handles key events and converts them into commands: keyHandler, updating the score and * display * @category SuiApplication * */ export class SuiKeyCommands implements EditorKeyHandler { view: SuiScoreViewOperations; slashMode: boolean = false; completeNotifier: CompleteNotifier; tracker: SuiTracker; eventSource: BrowserEventSource; constructor(params: KeyCommandParams) { this.slashMode = false; this.view = params.view; this.tracker = params.view.tracker; this.completeNotifier = params.completeNotifier; this.eventSource = params.eventSource; } tempoDialog() { const tempo = this.tracker.selections[0].measure.getTempo(); createAndDisplayDialog(SuiTempoDialog, { id: 'tempoDialog', ctor: 'SuiTempoDialog', completeNotifier: this.completeNotifier, view: this.view, eventSource: this.eventSource, tracker: this.tracker, startPromise: null, modifier: tempo } ); } get score() { return this.view.score; } undo() { this.view.undo(); } async copy() { await this.view.copy(); } async paste() { await this.view.paste(); } async unbeamSelections() { await this.view.unbeamSelections(); } async beamSelections() { await this.view.beamSelections(); } async toggleBeamDirection() { await this.view.toggleBeamDirection(); } async collapseChord() { await this.view.collapseChord(); } togglePlayer() { if (SuiAudioPlayer.playing) { this.stopPlayer(); } else { this.playScore(); } } playScore() { this.view.playFromSelection(); } stopPlayer() { this.view.stopPlayer(); } pausePlayer() { SuiAudioPlayer.pausePlayer(); } async intervalAdd(interval: number, direction: number) { await this.view.setInterval(direction * interval); } async interval(ev?: KeyEvent) { // code='Digit3' const keyEvent = ev ?? defaultKeyEvent(); var interval = parseInt(keyEvent.keyCode.toString(), 10) - 49; // 48 === '0', 0 indexed if (isNaN(interval) || interval < 1 || interval > 7) { return; } await this.intervalAdd(interval, keyEvent.shiftKey ? -1 : 1); } async transpose(offset: number) { await this.view.transposeSelections(offset); } async transposeDown() { await this.transpose(-1); } async transposeUp() { await this.transpose(1); } async upOctave() { await this.transpose(12); } async downOctave() { await this.transpose(-12); } async makeRest() { await this.view.makeRest(); } async setPitchCommand(letter: PitchLetter) { await this.view.setPitch(letter); } async setPitch(ev?: KeyEvent) { const keyEvent = ev ?? defaultKeyEvent(); const letter = keyEvent.key.toLowerCase(); if (IsPitchLetter(letter)) { await this.setPitchCommand(letter); } } async dotDuration() { await this.view.batchDurationOperation('dotDuration'); } async undotDuration() { await this.view.batchDurationOperation('undotDuration'); } async doubleDuration() { await this.view.batchDurationOperation('doubleDuration'); } async halveDuration() { await this.view.batchDurationOperation('halveDuration'); } async addMeasure(keyEvent?: KeyEvent) { await this.view.addMeasure(false); } async deleteNote() { await this.view.deleteNote(); } async toggleCourtesyAccidental() { await this.view.toggleCourtesyAccidentals(); } async toggleEnharmonic() { await this.view.toggleEnharmonic(); } async makeTupletCommand(numNotes: number) { await this.view.makeTuplet({ numNotes: numNotes, notesOccupied: 2, bracketed: true, ratioed: false }); } async makeTuplet(keyEvent?: KeyEvent) { if (!keyEvent) { return; } const numNotes = parseInt(keyEvent.key, 10); await this.makeTupletCommand(numNotes); } async unmakeTuplet() { await this.view.unmakeTuplet(); } async setNoteHead() { await this.view.setNoteHead('x2'); } async removeGraceNote() { await this.view.removeGraceNote(); } async addGraceNote() { await this.view.addGraceNote(); } async slashGraceNotes() { await this.view.slashGraceNotes(); } async toggleArticulationCommand(articulation: string, ctor: string) { await this.view.toggleArticulation(articulation, ctor); } async addRemoveAccent() { await this.toggleArticulationCommand(SmoArticulation.articulations.accent, 'SmoArticulation'); } async addRemoveTenuto() { await this.toggleArticulationCommand(SmoArticulation.articulations.tenuto, 'SmoArticulation'); } async addRemoveStaccato() { await this.toggleArticulationCommand(SmoArticulation.articulations.staccato, 'SmoArticulation'); } async addRemoveMarcato() { await this.toggleArticulationCommand(SmoArticulation.articulations.marcato, 'SmoArticulation'); } async addRemovePizzicato() { await this.toggleArticulationCommand(SmoArticulation.articulations.pizzicato, 'SmoArticulation'); } }