You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

169 lines
5.0KB

  1. #include "MidiKeyboardHandler.h"
  2. #include "MidiSequencer.h"
  3. #include <GLFW/glfw3.h>
  4. #include <assert.h>
  5. void MidiKeyboardHandler::handleNoteEditorChange(
  6. MidiSequencer* sequencer,
  7. ChangeType type,
  8. bool increase)
  9. {
  10. assert(type != ChangeType::lessThan); // can't handle
  11. switch(sequencer->context->noteAttribute) {
  12. case MidiEditorContext::NoteAttribute::Pitch:
  13. {
  14. int semitones = (type == ChangeType::bracket) ? 12 : 1;
  15. if (!increase) {
  16. semitones = -semitones;
  17. }
  18. sequencer->editor->changePitch(semitones);
  19. }
  20. break;
  21. case MidiEditorContext::NoteAttribute::Duration:
  22. {
  23. int units = (type == ChangeType::bracket) ? 4 : 1;
  24. if (!increase) {
  25. units = -units;
  26. }
  27. sequencer->editor->changeDuration(false, units);
  28. }
  29. break;
  30. case MidiEditorContext::NoteAttribute::StartTime:
  31. {
  32. int units = (type == ChangeType::bracket) ? 4 : 1;
  33. if (!increase) {
  34. units = -units;
  35. }
  36. sequencer->editor->changeStartTime(false, units);
  37. }
  38. break;
  39. }
  40. }
  41. bool MidiKeyboardHandler::handle(
  42. MidiSequencer* sequencer,
  43. unsigned key,
  44. unsigned mods)
  45. {
  46. bool handled = false;
  47. const bool shift = (mods & GLFW_MOD_SHIFT);
  48. const bool ctrl = (mods & GLFW_MOD_CONTROL);
  49. switch(key) {
  50. case GLFW_KEY_TAB:
  51. if (shift) {
  52. sequencer->editor->selectPrevNote();
  53. } else {
  54. sequencer->editor->selectNextNote();
  55. }
  56. handled = true;
  57. break;
  58. case GLFW_KEY_KP_ADD:
  59. handleNoteEditorChange(sequencer, ChangeType::plus, true);
  60. handled = true;
  61. break;
  62. case GLFW_KEY_EQUAL:
  63. if (shift) {
  64. handleNoteEditorChange(sequencer, ChangeType::plus, true);
  65. handled = true;
  66. }
  67. break;
  68. case GLFW_KEY_KP_SUBTRACT:
  69. handleNoteEditorChange(sequencer, ChangeType::plus, false);
  70. handled = true;
  71. break;
  72. case GLFW_KEY_LEFT_BRACKET:
  73. handleNoteEditorChange(sequencer, ChangeType::bracket, false);
  74. handled = true;
  75. break;
  76. case GLFW_KEY_RIGHT_BRACKET:
  77. handleNoteEditorChange(sequencer, ChangeType::bracket, true);
  78. handled = true;
  79. break;
  80. case GLFW_KEY_MINUS:
  81. if (!shift) {
  82. handleNoteEditorChange(sequencer, ChangeType::plus, false);
  83. handled = true;
  84. }
  85. break;
  86. case GLFW_KEY_RIGHT:
  87. {
  88. int units = ctrl ? 4 : 1;
  89. sequencer->editor->advanceCursor(false, units);
  90. handled = true;
  91. }
  92. break;
  93. case GLFW_KEY_LEFT:
  94. {
  95. int units = ctrl ? -4 : -1;
  96. sequencer->editor->advanceCursor(false, units);
  97. handled = true;
  98. }
  99. break;
  100. case GLFW_KEY_UP:
  101. {
  102. sequencer->editor->changeCursorPitch(1);
  103. handled = true;
  104. }
  105. break;
  106. case GLFW_KEY_DOWN:
  107. {
  108. sequencer->editor->changeCursorPitch(-1);
  109. handled = true;
  110. }
  111. break;
  112. case GLFW_KEY_P:
  113. {
  114. sequencer->editor->setNoteEditorAttribute(MidiEditorContext::NoteAttribute::Pitch);
  115. handled = true;
  116. }
  117. break;
  118. case GLFW_KEY_D:
  119. {
  120. sequencer->editor->setNoteEditorAttribute(MidiEditorContext::NoteAttribute::Duration);
  121. handled = true;
  122. }
  123. break;
  124. case GLFW_KEY_S:
  125. {
  126. sequencer->editor->setNoteEditorAttribute(MidiEditorContext::NoteAttribute::StartTime);
  127. }
  128. break;
  129. case GLFW_KEY_KP_0:
  130. case GLFW_KEY_INSERT:
  131. sequencer->editor->insertNote();
  132. handled = true;
  133. break;
  134. case GLFW_KEY_KP_DECIMAL:
  135. case GLFW_KEY_DELETE:
  136. sequencer->editor->deleteNote();
  137. handled = true;
  138. break;
  139. case GLFW_KEY_Z:
  140. if (ctrl & !shift) {
  141. handled = true;
  142. if (sequencer->undo->canUndo()) {
  143. sequencer->undo->undo();
  144. }
  145. } else if (ctrl & shift) {
  146. if (sequencer->undo->canRedo()) {
  147. sequencer->undo->redo();
  148. }
  149. }
  150. break;
  151. case GLFW_KEY_Y:
  152. if (ctrl) {
  153. handled = true;
  154. if (sequencer->undo->canRedo()) {
  155. sequencer->undo->redo();
  156. }
  157. }
  158. break;
  159. }
  160. return handled;
  161. }