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.

233 lines
5.6KB

  1. #include "app/ParamWidget.hpp"
  2. #include "ui/MenuOverlay.hpp"
  3. #include "ui/TextField.hpp"
  4. #include "app/Scene.hpp"
  5. #include "app/ParamQuantity.hpp"
  6. #include "app.hpp"
  7. #include "settings.hpp"
  8. #include "random.hpp"
  9. #include "history.hpp"
  10. #include "helpers.hpp"
  11. namespace rack {
  12. namespace app {
  13. struct ParamField : ui::TextField {
  14. ParamWidget *paramWidget;
  15. void step() override {
  16. // Keep selected
  17. APP->event->setSelected(this);
  18. ui::TextField::step();
  19. }
  20. void setParamWidget(ParamWidget *paramWidget) {
  21. this->paramWidget = paramWidget;
  22. if (paramWidget->paramQuantity)
  23. text = paramWidget->paramQuantity->getDisplayValueString();
  24. selectAll();
  25. }
  26. void onSelectKey(const event::SelectKey &e) override {
  27. if (e.action == GLFW_PRESS && (e.key == GLFW_KEY_ENTER || e.key == GLFW_KEY_KP_ENTER)) {
  28. float oldValue = paramWidget->paramQuantity->getValue();
  29. if (paramWidget->paramQuantity)
  30. paramWidget->paramQuantity->setDisplayValueString(text);
  31. float newValue = paramWidget->paramQuantity->getValue();
  32. if (oldValue != newValue) {
  33. // Push ParamChange history action
  34. history::ParamChange *h = new history::ParamChange;
  35. h->moduleId = paramWidget->paramQuantity->module->id;
  36. h->paramId = paramWidget->paramQuantity->paramId;
  37. h->oldValue = oldValue;
  38. h->newValue = newValue;
  39. APP->history->push(h);
  40. }
  41. ui::MenuOverlay *overlay = getAncestorOfType<ui::MenuOverlay>();
  42. overlay->requestedDelete = true;
  43. e.consume(this);
  44. }
  45. if (!e.getConsumed())
  46. ui::TextField::onSelectKey(e);
  47. }
  48. };
  49. struct ParamTooltip : ui::Tooltip {
  50. ParamWidget *paramWidget;
  51. void step() override {
  52. if (paramWidget->paramQuantity) {
  53. // ui::Quantity string
  54. text = paramWidget->paramQuantity->getString();
  55. // Param description
  56. std::string description = paramWidget->paramQuantity->getParam()->description;
  57. if (!description.empty())
  58. text += "\n" + description;
  59. }
  60. // Position at bottom-right of parameter
  61. box.pos = paramWidget->getAbsoluteOffset(paramWidget->box.size).round();
  62. ui::Tooltip::step();
  63. }
  64. };
  65. struct ParamLabel : ui::MenuLabel {
  66. ParamWidget *paramWidget;
  67. void step() override {
  68. text = paramWidget->paramQuantity->getString();
  69. ui::MenuLabel::step();
  70. }
  71. };
  72. struct ParamResetItem : ui::MenuItem {
  73. ParamWidget *paramWidget;
  74. ParamResetItem() {
  75. text = "Initialize";
  76. rightText = WINDOW_MOD_SHIFT_NAME "+Click";
  77. }
  78. void onAction(const event::Action &e) override {
  79. paramWidget->resetAction();
  80. }
  81. };
  82. struct ParamFineItem : ui::MenuItem {
  83. ParamFineItem() {
  84. text = "Fine adjust";
  85. rightText = WINDOW_MOD_CTRL_NAME "+Drag";
  86. disabled = true;
  87. }
  88. };
  89. ParamWidget::~ParamWidget() {
  90. if (paramQuantity)
  91. delete paramQuantity;
  92. }
  93. void ParamWidget::step() {
  94. if (paramQuantity) {
  95. float value = paramQuantity->getValue();
  96. // Trigger change event when paramQuantity value changes
  97. if (value != dirtyValue) {
  98. dirtyValue = value;
  99. event::Change eChange;
  100. onChange(eChange);
  101. }
  102. }
  103. widget::OpaqueWidget::step();
  104. }
  105. void ParamWidget::draw(const widget::DrawContext &ctx) {
  106. widget::Widget::draw(ctx);
  107. // if (paramQuantity) {
  108. // nvgBeginPath(ctx.vg);
  109. // nvgRect(ctx.vg,
  110. // box.size.x - 12, box.size.y - 12,
  111. // 12, 12);
  112. // nvgFillColor(ctx.vg, nvgRGBAf(1, 0, 1, 0.9));
  113. // nvgFill(ctx.vg);
  114. // std::string mapText = string::f("%d", paramQuantity->paramId);
  115. // bndLabel(ctx.vg, box.size.x - 17.0, box.size.y - 16.0, INFINITY, INFINITY, -1, mapText.c_str());
  116. // }
  117. }
  118. void ParamWidget::onButton(const event::Button &e) {
  119. // Right click to open context menu
  120. if (e.action == GLFW_PRESS && e.button == GLFW_MOUSE_BUTTON_RIGHT && (e.mods & WINDOW_MOD_MASK) == 0) {
  121. createContextMenu();
  122. e.consume(this);
  123. }
  124. // Shift-click to reset
  125. if (e.action == GLFW_PRESS && e.button == GLFW_MOUSE_BUTTON_LEFT && (e.mods & WINDOW_MOD_MASK) == GLFW_MOD_SHIFT) {
  126. resetAction();
  127. // HACK so that dragging won't occur
  128. e.consume(NULL);
  129. return;
  130. }
  131. if (!e.getConsumed())
  132. widget::OpaqueWidget::onButton(e);
  133. }
  134. void ParamWidget::onEnter(const event::Enter &e) {
  135. if (settings::paramTooltip && !tooltip && paramQuantity) {
  136. ParamTooltip *paramTooltip = new ParamTooltip;
  137. paramTooltip->paramWidget = this;
  138. APP->scene->addChild(paramTooltip);
  139. tooltip = paramTooltip;
  140. }
  141. }
  142. void ParamWidget::onLeave(const event::Leave &e) {
  143. if (tooltip) {
  144. APP->scene->removeChild(tooltip);
  145. delete tooltip;
  146. tooltip = NULL;
  147. }
  148. }
  149. void ParamWidget::fromJson(json_t *rootJ) {
  150. json_t *valueJ = json_object_get(rootJ, "value");
  151. if (valueJ) {
  152. if (paramQuantity)
  153. paramQuantity->setValue(json_number_value(valueJ));
  154. }
  155. }
  156. void ParamWidget::createContextMenu() {
  157. ui::Menu *menu = createMenu();
  158. ParamLabel *paramLabel = new ParamLabel;
  159. paramLabel->paramWidget = this;
  160. menu->addChild(paramLabel);
  161. ParamField *paramField = new ParamField;
  162. paramField->box.size.x = 100;
  163. paramField->setParamWidget(this);
  164. menu->addChild(paramField);
  165. ParamResetItem *resetItem = new ParamResetItem;
  166. resetItem->paramWidget = this;
  167. menu->addChild(resetItem);
  168. // ParamFineItem *fineItem = new ParamFineItem;
  169. // menu->addChild(fineItem);
  170. }
  171. void ParamWidget::resetAction() {
  172. if (paramQuantity && paramQuantity->isBounded()) {
  173. float oldValue = paramQuantity->getValue();
  174. paramQuantity->reset();
  175. float newValue = paramQuantity->getValue();
  176. if (oldValue != newValue) {
  177. // Push ParamChange history action
  178. history::ParamChange *h = new history::ParamChange;
  179. h->moduleId = paramQuantity->module->id;
  180. h->paramId = paramQuantity->paramId;
  181. h->oldValue = oldValue;
  182. h->newValue = newValue;
  183. APP->history->push(h);
  184. }
  185. // Here's another way of doing it, but either works.
  186. // paramQuantity->getParam()->reset();
  187. }
  188. }
  189. } // namespace app
  190. } // namespace rack