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.

171 lines
4.5KB

  1. #include <app/Scene.hpp>
  2. #include <app/ModuleBrowser.hpp>
  3. #include <app.hpp>
  4. #include <system.hpp>
  5. #include <network.hpp>
  6. #include <history.hpp>
  7. #include <settings.hpp>
  8. #include <patch.hpp>
  9. #include <asset.hpp>
  10. #include <osdialog.h>
  11. #include <thread>
  12. namespace rack {
  13. namespace app {
  14. struct FrameRateWidget : widget::TransparentWidget {
  15. void draw(const DrawArgs& args) override {
  16. std::string text = string::f("%.2f Hz", APP->window->getLastFrameRate());
  17. bndLabel(args.vg, 0.0, 0.0, INFINITY, INFINITY, -1, text.c_str());
  18. }
  19. };
  20. Scene::Scene() {
  21. rackScroll = new RackScrollWidget;
  22. addChild(rackScroll);
  23. rack = rackScroll->rackWidget;
  24. menuBar = createMenuBar();
  25. addChild(menuBar);
  26. moduleBrowser = moduleBrowserCreate();
  27. moduleBrowser->hide();
  28. addChild(moduleBrowser);
  29. frameRateWidget = new FrameRateWidget;
  30. frameRateWidget->box.size = math::Vec(80.0, 30.0);
  31. frameRateWidget->hide();
  32. addChild(frameRateWidget);
  33. }
  34. Scene::~Scene() {
  35. }
  36. void Scene::step() {
  37. bool fullscreen = APP->window->isFullScreen();
  38. menuBar->visible = !fullscreen;
  39. rackScroll->box.pos.y = menuBar->visible ? menuBar->box.size.y : 0;
  40. frameRateWidget->box.pos.x = box.size.x - frameRateWidget->box.size.x;
  41. // Resize owned descendants
  42. menuBar->box.size.x = box.size.x;
  43. rackScroll->box.size = box.size.minus(rackScroll->box.pos);
  44. // Autosave every 15 seconds
  45. if (settings::autosavePeriod > 0.0) {
  46. double time = glfwGetTime();
  47. if (time - lastAutosaveTime >= settings::autosavePeriod) {
  48. lastAutosaveTime = time;
  49. APP->patch->save(asset::autosavePath);
  50. settings::save(asset::settingsPath);
  51. }
  52. }
  53. Widget::step();
  54. }
  55. void Scene::draw(const DrawArgs& args) {
  56. Widget::draw(args);
  57. }
  58. void Scene::onHoverKey(const event::HoverKey& e) {
  59. OpaqueWidget::onHoverKey(e);
  60. if (e.isConsumed())
  61. return;
  62. if (e.action == GLFW_PRESS || e.action == GLFW_REPEAT) {
  63. if (e.key == GLFW_KEY_N && (e.mods & RACK_MOD_MASK) == RACK_MOD_CTRL) {
  64. APP->patch->resetDialog();
  65. e.consume(this);
  66. }
  67. else if (e.key == GLFW_KEY_Q && (e.mods & RACK_MOD_MASK) == RACK_MOD_CTRL) {
  68. APP->window->close();
  69. e.consume(this);
  70. }
  71. else if (e.key == GLFW_KEY_O && (e.mods & RACK_MOD_MASK) == RACK_MOD_CTRL) {
  72. APP->patch->loadDialog();
  73. e.consume(this);
  74. }
  75. else if (e.key == GLFW_KEY_O && (e.mods & RACK_MOD_MASK) == (RACK_MOD_CTRL | GLFW_MOD_SHIFT)) {
  76. APP->patch->revertDialog();
  77. e.consume(this);
  78. }
  79. else if (e.key == GLFW_KEY_S && (e.mods & RACK_MOD_MASK) == RACK_MOD_CTRL) {
  80. APP->patch->saveDialog();
  81. e.consume(this);
  82. }
  83. else if (e.key == GLFW_KEY_S && (e.mods & RACK_MOD_MASK) == (RACK_MOD_CTRL | GLFW_MOD_SHIFT)) {
  84. APP->patch->saveAsDialog();
  85. e.consume(this);
  86. }
  87. else if (e.key == GLFW_KEY_Z && (e.mods & RACK_MOD_MASK) == RACK_MOD_CTRL) {
  88. APP->history->undo();
  89. e.consume(this);
  90. }
  91. else if (e.key == GLFW_KEY_Z && (e.mods & RACK_MOD_MASK) == (RACK_MOD_CTRL | GLFW_MOD_SHIFT)) {
  92. APP->history->redo();
  93. e.consume(this);
  94. }
  95. else if ((e.key == GLFW_KEY_MINUS || e.key == GLFW_KEY_KP_SUBTRACT) && (e.mods & RACK_MOD_MASK) == RACK_MOD_CTRL) {
  96. float zoom = settings::zoom;
  97. zoom *= 2;
  98. zoom = std::ceil(zoom - 0.01f) - 1;
  99. zoom /= 2;
  100. settings::zoom = zoom;
  101. e.consume(this);
  102. }
  103. else if ((e.key == GLFW_KEY_EQUAL || e.key == GLFW_KEY_KP_ADD) && (e.mods & RACK_MOD_MASK) == RACK_MOD_CTRL) {
  104. float zoom = settings::zoom;
  105. zoom *= 2;
  106. zoom = std::floor(zoom + 0.01f) + 1;
  107. zoom /= 2;
  108. settings::zoom = zoom;
  109. e.consume(this);
  110. }
  111. else if ((e.key == GLFW_KEY_0 || e.key == GLFW_KEY_KP_0) && (e.mods & RACK_MOD_MASK) == RACK_MOD_CTRL) {
  112. settings::zoom = 0.f;
  113. e.consume(this);
  114. }
  115. else if ((e.key == GLFW_KEY_ENTER || e.key == GLFW_KEY_KP_ENTER) && (e.mods & RACK_MOD_MASK) == 0) {
  116. moduleBrowser->show();
  117. e.consume(this);
  118. }
  119. else if (e.key == GLFW_KEY_F1 && (e.mods & RACK_MOD_MASK) == 0) {
  120. std::thread t([] {
  121. system::openBrowser("https://vcvrack.com/manual/");
  122. });
  123. t.detach();
  124. e.consume(this);
  125. }
  126. else if (e.key == GLFW_KEY_F3 && (e.mods & RACK_MOD_MASK) == 0) {
  127. settings::cpuMeter ^= true;
  128. e.consume(this);
  129. }
  130. else if (e.key == GLFW_KEY_F11 && (e.mods & RACK_MOD_MASK) == 0) {
  131. APP->window->setFullScreen(!APP->window->isFullScreen());
  132. e.consume(this);
  133. }
  134. }
  135. }
  136. void Scene::onPathDrop(const event::PathDrop& e) {
  137. if (e.paths.size() >= 1) {
  138. const std::string& path = e.paths[0];
  139. if (string::filenameExtension(string::filename(path)) == "vcv") {
  140. APP->patch->loadPathDialog(path);
  141. e.consume(this);
  142. return;
  143. }
  144. }
  145. OpaqueWidget::onPathDrop(e);
  146. }
  147. } // namespace app
  148. } // namespace rack