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.

186 lines
4.3KB

  1. #include <algorithm>
  2. #include <plugin/Model.hpp>
  3. #include <plugin.hpp>
  4. #include <asset.hpp>
  5. #include <system.hpp>
  6. #include <string.hpp>
  7. #include <tag.hpp>
  8. #include <ui/Menu.hpp>
  9. #include <ui/MenuSeparator.hpp>
  10. #include <helpers.hpp>
  11. namespace rack {
  12. namespace plugin {
  13. void Model::fromJson(json_t* rootJ) {
  14. assert(plugin);
  15. json_t* nameJ = json_object_get(rootJ, "name");
  16. if (nameJ)
  17. name = json_string_value(nameJ);
  18. if (name == "")
  19. throw Exception("No module name for slug %s", slug.c_str());
  20. json_t* descriptionJ = json_object_get(rootJ, "description");
  21. if (descriptionJ)
  22. description = json_string_value(descriptionJ);
  23. // Tags
  24. tagIds.clear();
  25. json_t* tagsJ = json_object_get(rootJ, "tags");
  26. if (tagsJ) {
  27. size_t i;
  28. json_t* tagJ;
  29. json_array_foreach(tagsJ, i, tagJ) {
  30. std::string tag = json_string_value(tagJ);
  31. int tagId = tag::findId(tag);
  32. // Omit duplicates
  33. auto it = std::find(tagIds.begin(), tagIds.end(), tagId);
  34. if (it != tagIds.end())
  35. continue;
  36. if (tagId >= 0)
  37. tagIds.push_back(tagId);
  38. }
  39. }
  40. // manualUrl
  41. json_t* manualUrlJ = json_object_get(rootJ, "manualUrl");
  42. if (manualUrlJ)
  43. manualUrl = json_string_value(manualUrlJ);
  44. // modularGridUrl
  45. json_t* modularGridUrlJ = json_object_get(rootJ, "modularGridUrl");
  46. if (modularGridUrlJ)
  47. modularGridUrl = json_string_value(modularGridUrlJ);
  48. // hidden
  49. json_t* hiddenJ = json_object_get(rootJ, "hidden");
  50. // Use `disabled` as an alias which was deprecated in Rack 2.0
  51. if (!hiddenJ)
  52. hiddenJ = json_object_get(rootJ, "disabled");
  53. if (hiddenJ) {
  54. // Don't un-hide Model if already hidden by C++
  55. if (json_boolean_value(hiddenJ))
  56. hidden = true;
  57. }
  58. }
  59. std::string Model::getFullName() {
  60. assert(plugin);
  61. return plugin->getBrand() + " " + name;
  62. }
  63. std::string Model::getFactoryPresetDirectory() {
  64. return asset::plugin(plugin, system::join("presets", slug));
  65. }
  66. std::string Model::getUserPresetDirectory() {
  67. return asset::user(system::join("presets", plugin->slug, slug));
  68. }
  69. std::string Model::getManualUrl() {
  70. if (!manualUrl.empty())
  71. return manualUrl;
  72. return plugin->manualUrl;
  73. }
  74. void Model::appendContextMenu(ui::Menu* menu) {
  75. // plugin
  76. menu->addChild(createMenuItem("Plugin: " + plugin->name, "", [=]() {
  77. system::openBrowser(plugin->pluginUrl);
  78. }, plugin->pluginUrl == ""));
  79. // version
  80. menu->addChild(createMenuLabel("Version: " + plugin->version));
  81. // author
  82. if (plugin->author != "") {
  83. menu->addChild(createMenuItem("Author: " + plugin->author, "", [=]() {
  84. system::openBrowser(plugin->authorUrl);
  85. }, plugin->authorUrl.empty()));
  86. }
  87. // license
  88. std::string license = plugin->license;
  89. if (string::startsWith(license, "https://") || string::startsWith(license, "http://")) {
  90. menu->addChild(createMenuItem("License: Open in browser", "", [=]() {
  91. system::openBrowser(license);
  92. }));
  93. }
  94. else if (license != "") {
  95. menu->addChild(createMenuLabel("License: " + license));
  96. }
  97. // tags
  98. if (!tagIds.empty()) {
  99. menu->addChild(createMenuLabel("Tags:"));
  100. for (int tagId : tagIds) {
  101. menu->addChild(createMenuLabel("• " + tag::getTag(tagId)));
  102. }
  103. }
  104. menu->addChild(new ui::MenuSeparator);
  105. // VCV Library page
  106. menu->addChild(createMenuItem("VCV Library page", "", [=]() {
  107. system::openBrowser("https://library.vcvrack.com/" + plugin->slug + "/" + slug);
  108. }));
  109. // modularGridUrl
  110. if (modularGridUrl != "") {
  111. menu->addChild(createMenuItem("ModularGrid page", "", [=]() {
  112. system::openBrowser(modularGridUrl);
  113. }));
  114. }
  115. // manual
  116. std::string manualUrl = getManualUrl();
  117. if (manualUrl != "") {
  118. menu->addChild(createMenuItem("User manual", RACK_MOD_CTRL_NAME "+F1", [=]() {
  119. system::openBrowser(manualUrl);
  120. }));
  121. }
  122. // donate
  123. if (plugin->donateUrl != "") {
  124. menu->addChild(createMenuItem("Donate", "", [=]() {
  125. system::openBrowser(plugin->donateUrl);
  126. }));
  127. }
  128. // source code
  129. if (plugin->sourceUrl != "") {
  130. menu->addChild(createMenuItem("Source code", "", [=]() {
  131. system::openBrowser(plugin->sourceUrl);
  132. }));
  133. }
  134. // changelog
  135. if (plugin->changelogUrl != "") {
  136. menu->addChild(createMenuItem("Changelog", "", [=]() {
  137. system::openBrowser(plugin->changelogUrl);
  138. }));
  139. }
  140. // plugin folder
  141. if (plugin->path != "") {
  142. menu->addChild(createMenuItem("Open plugin folder", "", [=]() {
  143. system::openDirectory(plugin->path);
  144. }));
  145. }
  146. }
  147. } // namespace plugin
  148. } // namespace rack