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.

153 lines
4.0KB

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