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.

175 lines
4.2KB

  1. #include "osdialog.h"
  2. #include "system.hpp"
  3. #include "network.hpp"
  4. #include "app/Scene.hpp"
  5. #include "app/ModuleBrowser.hpp"
  6. #include "app/RackScrollWidget.hpp"
  7. #include "app.hpp"
  8. #include "history.hpp"
  9. #include <thread>
  10. namespace rack {
  11. Scene::Scene() {
  12. scrollWidget = new RackScrollWidget;
  13. {
  14. zoomWidget = new ZoomWidget;
  15. {
  16. rackWidget = new RackWidget;
  17. zoomWidget->addChild(rackWidget);
  18. }
  19. scrollWidget->container->addChild(zoomWidget);
  20. }
  21. addChild(scrollWidget);
  22. toolbar = new Toolbar;
  23. addChild(toolbar);
  24. scrollWidget->box.pos.y = toolbar->box.size.y;
  25. moduleBrowser = new ModuleBrowser;
  26. moduleBrowser->visible = false;
  27. addChild(moduleBrowser);
  28. }
  29. Scene::~Scene() {
  30. }
  31. void Scene::step() {
  32. // Resize owned descendants
  33. toolbar->box.size.x = box.size.x;
  34. scrollWidget->box.size = box.size.minus(scrollWidget->box.pos);
  35. // Resize to be a bit larger than the ScrollWidget viewport
  36. rackWidget->box.size = scrollWidget->box.size
  37. .minus(scrollWidget->container->box.pos)
  38. .plus(math::Vec(500, 500))
  39. .div(zoomWidget->zoom);
  40. OpaqueWidget::step();
  41. zoomWidget->box.size = rackWidget->box.size.mult(zoomWidget->zoom);
  42. moduleBrowser->box.size = box.size;
  43. // Request latest version from server
  44. if (!devMode && checkVersion && !checkedVersion) {
  45. std::thread t(&Scene::runCheckVersion, this);
  46. t.detach();
  47. checkedVersion = true;
  48. }
  49. // Version popup message
  50. if (!latestVersion.empty()) {
  51. std::string versionMessage = string::f("Rack %s is available.\n\nYou have Rack %s.\n\nClose Rack and download new version on the website?", latestVersion.c_str(), APP_VERSION.c_str());
  52. if (osdialog_message(OSDIALOG_INFO, OSDIALOG_OK_CANCEL, versionMessage.c_str())) {
  53. std::thread t(system::openBrowser, "https://vcvrack.com/");
  54. t.detach();
  55. app()->window->close();
  56. }
  57. latestVersion = "";
  58. }
  59. }
  60. void Scene::draw(NVGcontext *vg) {
  61. OpaqueWidget::draw(vg);
  62. }
  63. void Scene::onHoverKey(const event::HoverKey &e) {
  64. if (e.action == GLFW_PRESS) {
  65. switch (e.key) {
  66. case GLFW_KEY_N: {
  67. if ((e.mods & WINDOW_MOD) && !(e.mods & GLFW_MOD_SHIFT)) {
  68. rackWidget->reset();
  69. e.consume(this);
  70. }
  71. } break;
  72. case GLFW_KEY_Q: {
  73. if ((e.mods & WINDOW_MOD) && !(e.mods & GLFW_MOD_SHIFT)) {
  74. app()->window->close();
  75. e.consume(this);
  76. }
  77. } break;
  78. case GLFW_KEY_O: {
  79. if ((e.mods & WINDOW_MOD) && !(e.mods & GLFW_MOD_SHIFT)) {
  80. rackWidget->loadDialog();
  81. e.consume(this);
  82. }
  83. if ((e.mods & WINDOW_MOD) && (e.mods & GLFW_MOD_SHIFT)) {
  84. rackWidget->revert();
  85. e.consume(this);
  86. }
  87. } break;
  88. case GLFW_KEY_S: {
  89. if ((e.mods & WINDOW_MOD) && !(e.mods & GLFW_MOD_SHIFT)) {
  90. rackWidget->saveDialog();
  91. e.consume(this);
  92. }
  93. if ((e.mods & WINDOW_MOD) && (e.mods & GLFW_MOD_SHIFT)) {
  94. rackWidget->saveAsDialog();
  95. e.consume(this);
  96. }
  97. } break;
  98. case GLFW_KEY_V: {
  99. if ((e.mods & WINDOW_MOD) && !(e.mods & GLFW_MOD_SHIFT)) {
  100. rackWidget->pastePresetClipboard();
  101. e.consume(this);
  102. }
  103. } break;
  104. case GLFW_KEY_Z: {
  105. if ((e.mods & WINDOW_MOD) && !(e.mods & GLFW_MOD_SHIFT)) {
  106. app()->history->undo();
  107. e.consume(this);
  108. }
  109. if ((e.mods & WINDOW_MOD) && (e.mods & GLFW_MOD_SHIFT)) {
  110. app()->history->redo();
  111. e.consume(this);
  112. }
  113. } break;
  114. case GLFW_KEY_ENTER:
  115. case GLFW_KEY_KP_ENTER: {
  116. moduleBrowser->visible = true;
  117. e.consume(this);
  118. } break;
  119. case GLFW_KEY_F11: {
  120. app()->window->setFullScreen(!app()->window->isFullScreen());
  121. e.consume(this);
  122. }
  123. }
  124. }
  125. if (!e.getConsumed())
  126. OpaqueWidget::onHoverKey(e);
  127. }
  128. void Scene::onPathDrop(const event::PathDrop &e) {
  129. if (e.paths.size() >= 1) {
  130. const std::string &path = e.paths[0];
  131. if (string::extension(path) == "vcv") {
  132. rackWidget->load(path);
  133. e.consume(this);
  134. }
  135. }
  136. if (!e.getConsumed())
  137. OpaqueWidget::onPathDrop(e);
  138. }
  139. void Scene::runCheckVersion() {
  140. json_t *resJ = network::requestJson(network::METHOD_GET, API_HOST + "/version", NULL);
  141. if (resJ) {
  142. json_t *versionJ = json_object_get(resJ, "version");
  143. if (versionJ) {
  144. std::string version = json_string_value(versionJ);
  145. if (version != APP_VERSION) {
  146. latestVersion = version;
  147. }
  148. }
  149. json_decref(resJ);
  150. }
  151. }
  152. } // namespace rack