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.

230 lines
5.5KB

  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 = "Double-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. if (!e.getConsumed())
  125. widget::OpaqueWidget::onButton(e);
  126. }
  127. void ParamWidget::onDoubleClick(const event::DoubleClick &e) {
  128. resetAction();
  129. }
  130. void ParamWidget::onEnter(const event::Enter &e) {
  131. if (settings.paramTooltip && !tooltip && paramQuantity) {
  132. ParamTooltip *paramTooltip = new ParamTooltip;
  133. paramTooltip->paramWidget = this;
  134. APP->scene->addChild(paramTooltip);
  135. tooltip = paramTooltip;
  136. e.consume(this);
  137. }
  138. }
  139. void ParamWidget::onLeave(const event::Leave &e) {
  140. if (tooltip) {
  141. APP->scene->removeChild(tooltip);
  142. delete tooltip;
  143. tooltip = NULL;
  144. }
  145. }
  146. void ParamWidget::fromJson(json_t *rootJ) {
  147. json_t *valueJ = json_object_get(rootJ, "value");
  148. if (valueJ) {
  149. if (paramQuantity)
  150. paramQuantity->setValue(json_number_value(valueJ));
  151. }
  152. }
  153. void ParamWidget::createContextMenu() {
  154. ui::Menu *menu = createMenu();
  155. ParamLabel *paramLabel = new ParamLabel;
  156. paramLabel->paramWidget = this;
  157. menu->addChild(paramLabel);
  158. ParamField *paramField = new ParamField;
  159. paramField->box.size.x = 100;
  160. paramField->setParamWidget(this);
  161. menu->addChild(paramField);
  162. ParamResetItem *resetItem = new ParamResetItem;
  163. resetItem->paramWidget = this;
  164. menu->addChild(resetItem);
  165. // ParamFineItem *fineItem = new ParamFineItem;
  166. // menu->addChild(fineItem);
  167. }
  168. void ParamWidget::resetAction() {
  169. if (paramQuantity && paramQuantity->isBounded()) {
  170. float oldValue = paramQuantity->getValue();
  171. paramQuantity->reset();
  172. float newValue = paramQuantity->getValue();
  173. if (oldValue != newValue) {
  174. // Push ParamChange history action
  175. history::ParamChange *h = new history::ParamChange;
  176. h->moduleId = paramQuantity->module->id;
  177. h->paramId = paramQuantity->paramId;
  178. h->oldValue = oldValue;
  179. h->newValue = newValue;
  180. APP->history->push(h);
  181. }
  182. // Here's another way of doing it, but either works.
  183. // paramQuantity->getParam()->reset();
  184. }
  185. }
  186. } // namespace app
  187. } // namespace rack