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.

173 lines
4.3KB

  1. #include "app/MidiWidget.hpp"
  2. #include "midi.hpp"
  3. #include "helpers.hpp"
  4. namespace rack {
  5. struct MidiDriverItem : MenuItem {
  6. midi::IO *midiIO;
  7. int driverId;
  8. void onAction(const event::Action &e) override {
  9. midiIO->setDriverId(driverId);
  10. }
  11. };
  12. struct MidiDriverChoice : LedDisplayChoice {
  13. MidiWidget *midiWidget;
  14. void onAction(const event::Action &e) override {
  15. if (!midiWidget->midiIO)
  16. return;
  17. Menu *menu = createMenu();
  18. menu->addChild(createMenuLabel("MIDI driver"));
  19. for (int driverId : midiWidget->midiIO->getDriverIds()) {
  20. MidiDriverItem *item = new MidiDriverItem;
  21. item->midiIO = midiWidget->midiIO;
  22. item->driverId = driverId;
  23. item->text = midiWidget->midiIO->getDriverName(driverId);
  24. item->rightText = CHECKMARK(item->driverId == midiWidget->midiIO->driverId);
  25. menu->addChild(item);
  26. }
  27. }
  28. void step() override {
  29. if (!midiWidget->midiIO) {
  30. text = "";
  31. return;
  32. }
  33. text = midiWidget->midiIO->getDriverName(midiWidget->midiIO->driverId);
  34. if (text.empty()) {
  35. text = "(No driver)";
  36. color.a = 0.5f;
  37. }
  38. else {
  39. color.a = 1.f;
  40. }
  41. }
  42. };
  43. struct MidiDeviceItem : MenuItem {
  44. midi::IO *midiIO;
  45. int deviceId;
  46. void onAction(const event::Action &e) override {
  47. midiIO->setDeviceId(deviceId);
  48. }
  49. };
  50. struct MidiDeviceChoice : LedDisplayChoice {
  51. MidiWidget *midiWidget;
  52. void onAction(const event::Action &e) override {
  53. if (!midiWidget->midiIO)
  54. return;
  55. Menu *menu = createMenu();
  56. menu->addChild(createMenuLabel("MIDI device"));
  57. {
  58. MidiDeviceItem *item = new MidiDeviceItem;
  59. item->midiIO = midiWidget->midiIO;
  60. item->deviceId = -1;
  61. item->text = "(No device)";
  62. item->rightText = CHECKMARK(item->deviceId == midiWidget->midiIO->deviceId);
  63. menu->addChild(item);
  64. }
  65. for (int deviceId : midiWidget->midiIO->getDeviceIds()) {
  66. MidiDeviceItem *item = new MidiDeviceItem;
  67. item->midiIO = midiWidget->midiIO;
  68. item->deviceId = deviceId;
  69. item->text = midiWidget->midiIO->getDeviceName(deviceId);
  70. item->rightText = CHECKMARK(item->deviceId == midiWidget->midiIO->deviceId);
  71. menu->addChild(item);
  72. }
  73. }
  74. void step() override {
  75. if (!midiWidget->midiIO) {
  76. text = "";
  77. return;
  78. }
  79. text = midiWidget->midiIO->getDeviceName(midiWidget->midiIO->deviceId);
  80. if (text.empty()) {
  81. text = "(No device)";
  82. color.a = 0.5f;
  83. }
  84. else {
  85. color.a = 1.f;
  86. }
  87. }
  88. };
  89. struct MidiChannelItem : MenuItem {
  90. midi::IO *midiIO;
  91. int channel;
  92. void onAction(const event::Action &e) override {
  93. midiIO->channel = channel;
  94. }
  95. };
  96. struct MidiChannelChoice : LedDisplayChoice {
  97. MidiWidget *midiWidget;
  98. void onAction(const event::Action &e) override {
  99. if (!midiWidget->midiIO)
  100. return;
  101. Menu *menu = createMenu();
  102. menu->addChild(createMenuLabel("MIDI channel"));
  103. for (int channel : midiWidget->midiIO->getChannels()) {
  104. MidiChannelItem *item = new MidiChannelItem;
  105. item->midiIO = midiWidget->midiIO;
  106. item->channel = channel;
  107. item->text = midiWidget->midiIO->getChannelName(channel);
  108. item->rightText = CHECKMARK(item->channel == midiWidget->midiIO->channel);
  109. menu->addChild(item);
  110. }
  111. }
  112. void step() override {
  113. if (midiWidget->midiIO)
  114. text = midiWidget->midiIO->getChannelName(midiWidget->midiIO->channel);
  115. else
  116. text = "";
  117. }
  118. };
  119. MidiWidget::MidiWidget() {
  120. box.size = mm2px(math::Vec(44, 28));
  121. math::Vec pos = math::Vec();
  122. MidiDriverChoice *driverChoice = createWidget<MidiDriverChoice>(pos);
  123. driverChoice->midiWidget = this;
  124. addChild(driverChoice);
  125. pos = driverChoice->box.getBottomLeft();
  126. this->driverChoice = driverChoice;
  127. this->driverSeparator = createWidget<LedDisplaySeparator>(pos);
  128. addChild(this->driverSeparator);
  129. MidiDeviceChoice *deviceChoice = createWidget<MidiDeviceChoice>(pos);
  130. deviceChoice->midiWidget = this;
  131. addChild(deviceChoice);
  132. pos = deviceChoice->box.getBottomLeft();
  133. this->deviceChoice = deviceChoice;
  134. this->deviceSeparator = createWidget<LedDisplaySeparator>(pos);
  135. addChild(this->deviceSeparator);
  136. MidiChannelChoice *channelChoice = createWidget<MidiChannelChoice>(pos);
  137. channelChoice->midiWidget = this;
  138. addChild(channelChoice);
  139. this->channelChoice = channelChoice;
  140. }
  141. void MidiWidget::step() {
  142. this->driverChoice->box.size.x = box.size.x;
  143. this->driverSeparator->box.size.x = box.size.x;
  144. this->deviceChoice->box.size.x = box.size.x;
  145. this->deviceSeparator->box.size.x = box.size.x;
  146. this->channelChoice->box.size.x = box.size.x;
  147. LedDisplay::step();
  148. }
  149. } // namespace rack