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.

159 lines
3.8KB

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