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.

415 lines
8.4KB

  1. #pragma once
  2. #include <assert.h>
  3. #include <stdio.h>
  4. #include <math.h>
  5. #include <vector>
  6. #include <list>
  7. #include <map>
  8. #include <GL/glew.h>
  9. #include <GLFW/glfw3.h>
  10. #include <jansson.h>
  11. #include "../lib/nanovg/src/nanovg.h"
  12. #include "../lib/oui/blendish.h"
  13. #include "util.hpp"
  14. namespace rack {
  15. struct Module;
  16. struct Wire;
  17. struct RackWidget;
  18. struct ParamWidget;
  19. struct InputPort;
  20. struct OutputPort;
  21. ////////////////////
  22. // base class and traits
  23. ////////////////////
  24. // A node in the 2D scene graph
  25. struct Widget {
  26. // Stores position and size
  27. Rect box = Rect(Vec(0, 0), Vec(INFINITY, INFINITY));
  28. Widget *parent = NULL;
  29. std::list<Widget*> children;
  30. virtual ~Widget();
  31. Vec getAbsolutePos();
  32. Rect getChildrenBoundingBox();
  33. // Gives ownership of widget to this widget instance
  34. void addChild(Widget *widget);
  35. // Does not delete widget but transfers ownership to caller
  36. // Silenty fails if widget is not a child
  37. void removeChild(Widget *widget);
  38. void clearChildren();
  39. // Advances the module by one frame
  40. virtual void step();
  41. // Draws to NanoVG context
  42. virtual void draw(NVGcontext *vg);
  43. // Override this to return NULL if the widget is to be "invisible" to mouse events.
  44. // Override this to return `this` if the widget is to override events of its children.
  45. virtual Widget *pick(Vec pos);
  46. // Events
  47. virtual void onMouseDown(int button) {}
  48. virtual void onMouseUp(int button) {}
  49. virtual void onMouseMove(Vec mouseRel) {}
  50. virtual void onMouseEnter() {}
  51. virtual void onMouseLeave() {}
  52. virtual void onScroll(Vec scrollRel) {}
  53. virtual void onDragStart() {}
  54. virtual void onDragDrop(Widget *origin) {}
  55. virtual void onDragHover(Widget *origin) {}
  56. virtual void onDragMove(Vec mouseRel) {}
  57. virtual void onDragEnd() {}
  58. virtual void onResize() {}
  59. virtual void onAction() {}
  60. virtual void onChange() {}
  61. };
  62. // Widget that does not respond to events
  63. struct TransparentWidget : virtual Widget {
  64. Widget *pick(Vec pos) { return NULL; }
  65. };
  66. // Widget that does not respond to events, but allows its children to
  67. struct TranslucentWidget : virtual Widget {
  68. Widget *pick(Vec pos) {
  69. Widget *picked = Widget::pick(pos);
  70. if (picked == this) {
  71. return NULL;
  72. }
  73. return picked;
  74. }
  75. };
  76. struct SpriteWidget : virtual Widget {
  77. Vec spriteOffset;
  78. Vec spriteSize;
  79. std::string spriteFilename;
  80. int index = 0;
  81. void draw(NVGcontext *vg);
  82. };
  83. struct QuantityWidget : virtual Widget {
  84. float value = 0.0;
  85. float minValue = 0.0;
  86. float maxValue = 1.0;
  87. float defaultValue = 0.0;
  88. std::string label;
  89. // Include a space character if you want a space after the number, e.g. " Hz"
  90. std::string unit;
  91. void setValue(float value);
  92. void setLimits(float minValue, float maxValue);
  93. void setDefaultValue(float defaultValue);
  94. };
  95. ////////////////////
  96. // gui elements
  97. ////////////////////
  98. struct Label : TransparentWidget {
  99. std::string text;
  100. void draw(NVGcontext *vg);
  101. };
  102. // Deletes itself from parent when clicked
  103. struct MenuOverlay : Widget {
  104. void onMouseDown(int button);
  105. };
  106. struct Menu : Widget {
  107. Menu() {
  108. box.size = Vec(0, 0);
  109. }
  110. // Transfers ownership, like addChild()
  111. void pushChild(Widget *child);
  112. void draw(NVGcontext *vg);
  113. };
  114. struct MenuEntry : Widget {
  115. std::string text;
  116. MenuEntry() {
  117. box.size = Vec(0, BND_WIDGET_HEIGHT);
  118. }
  119. float computeMinWidth(NVGcontext *vg);
  120. };
  121. struct MenuLabel : MenuEntry {
  122. void draw(NVGcontext *vg);
  123. };
  124. struct MenuItem : MenuEntry {
  125. BNDwidgetState state = BND_DEFAULT;
  126. void draw(NVGcontext *vg);
  127. void onMouseUp(int button);
  128. void onMouseEnter();
  129. void onMouseLeave() ;
  130. };
  131. struct Button : Widget {
  132. std::string text;
  133. BNDwidgetState state = BND_DEFAULT;
  134. Button();
  135. void draw(NVGcontext *vg);
  136. void onMouseEnter();
  137. void onMouseLeave() ;
  138. void onDragDrop(Widget *origin);
  139. };
  140. struct ChoiceButton : Button {
  141. void draw(NVGcontext *vg);
  142. };
  143. struct Slider : QuantityWidget {
  144. BNDwidgetState state = BND_DEFAULT;
  145. Slider();
  146. void draw(NVGcontext *vg);
  147. void onDragStart();
  148. void onDragMove(Vec mouseRel);
  149. void onDragEnd();
  150. };
  151. struct ScrollBar : Widget {
  152. enum { VERTICAL, HORIZONTAL } orientation;
  153. float containerOffset = 0.0;
  154. float containerSize = 0.0;
  155. BNDwidgetState state = BND_DEFAULT;
  156. ScrollBar();
  157. void draw(NVGcontext *vg);
  158. void move(float delta);
  159. void onDragStart();
  160. void onDragMove(Vec mouseRel);
  161. void onDragEnd();
  162. };
  163. // Handles a container with scrollbars
  164. struct ScrollWidget : Widget {
  165. Widget *container;
  166. ScrollBar *hScrollBar;
  167. ScrollBar *vScrollBar;
  168. ScrollWidget();
  169. void draw(NVGcontext *vg);
  170. void onResize();
  171. void onScroll(Vec scrollRel);
  172. };
  173. struct Tooltip : TransparentWidget {
  174. void step();
  175. void draw(NVGcontext *vg);
  176. };
  177. ////////////////////
  178. // module
  179. ////////////////////
  180. // A 1U module should be 15x380. Thus the width of a module should be a factor of 15.
  181. struct Model;
  182. struct ModuleWidget : Widget {
  183. Model *model = NULL;
  184. // Eventually this should be replaced with a `moduleId` which will be used for inter-process communication between the gui world and the audio world.
  185. Module *module = NULL;
  186. // int moduleId;
  187. std::vector<InputPort*> inputs;
  188. std::vector<OutputPort*> outputs;
  189. std::vector<ParamWidget*> params;
  190. ModuleWidget(Module *module);
  191. ~ModuleWidget();
  192. // Convenience functions for adding special widgets (calls addChild())
  193. void addInput(InputPort *input);
  194. void addOutput(OutputPort *output);
  195. void addParam(ParamWidget *param);
  196. json_t *toJson();
  197. void fromJson(json_t *root);
  198. void disconnectPorts();
  199. void resetParams();
  200. void cloneParams(ModuleWidget *source);
  201. void draw(NVGcontext *vg);
  202. bool requested = false;
  203. Vec requestedPos;
  204. Vec dragPos;
  205. void onDragStart();
  206. void onDragMove(Vec mouseRel);
  207. void onDragEnd();
  208. void onMouseDown(int button);
  209. };
  210. struct WireWidget : Widget {
  211. OutputPort *outputPort = NULL;
  212. InputPort *inputPort = NULL;
  213. Wire *wire = NULL;
  214. NVGcolor color;
  215. WireWidget();
  216. ~WireWidget();
  217. void updateWire();
  218. void draw(NVGcontext *vg);
  219. void drawOutputPlug(NVGcontext *vg);
  220. void drawInputPlug(NVGcontext *vg);
  221. };
  222. struct RackWidget : Widget {
  223. // Only put ModuleWidgets in here
  224. Widget *moduleContainer;
  225. // Only put WireWidgets in here
  226. Widget *wireContainer;
  227. // An unowned reference to the currently dragged wire
  228. WireWidget *activeWire = NULL;
  229. RackWidget();
  230. ~RackWidget();
  231. void clear();
  232. void savePatch(std::string filename);
  233. void loadPatch(std::string filename);
  234. json_t *toJson();
  235. void fromJson(json_t *root);
  236. int frame = 0;
  237. void repositionModule(ModuleWidget *module);
  238. void step();
  239. void draw(NVGcontext *vg);
  240. void onMouseDown(int button);
  241. };
  242. ////////////////////
  243. // params
  244. ////////////////////
  245. struct Light : TransparentWidget, SpriteWidget {
  246. NVGcolor color;
  247. void draw(NVGcontext *vg);
  248. };
  249. // If you don't add these to your ModuleWidget, it will fall out of the RackWidget
  250. struct Screw : TransparentWidget, SpriteWidget {
  251. Screw();
  252. };
  253. struct ParamWidget : QuantityWidget {
  254. Module *module = NULL;
  255. int paramId;
  256. json_t *toJson();
  257. void fromJson(json_t *root);
  258. void onMouseDown(int button);
  259. void onChange();
  260. };
  261. struct Knob : ParamWidget, SpriteWidget {
  262. int minIndex, maxIndex, spriteCount;
  263. void step();
  264. void onDragStart();
  265. void onDragMove(Vec mouseRel);
  266. void onDragEnd();
  267. };
  268. struct Switch : ParamWidget, SpriteWidget {
  269. };
  270. struct ToggleSwitch : virtual Switch {
  271. void onDragStart() {
  272. index = 1;
  273. }
  274. void onDragEnd() {
  275. index = 0;
  276. }
  277. void onDragDrop(Widget *origin) {
  278. if (origin != this)
  279. return;
  280. // Cycle through modes
  281. // e.g. a range of [0.0, 3.0] would have modes 0, 1, 2, and 3.
  282. float v = value + 1.0;
  283. setValue(v > maxValue ? minValue : v);
  284. }
  285. };
  286. struct MomentarySwitch : virtual Switch {
  287. void onDragStart() {
  288. setValue(maxValue);
  289. index = 1;
  290. }
  291. void onDragEnd() {
  292. setValue(minValue);
  293. index = 0;
  294. }
  295. };
  296. ////////////////////
  297. // ports
  298. ////////////////////
  299. struct Port : Widget {
  300. Module *module = NULL;
  301. WireWidget *connectedWire = NULL;
  302. Port();
  303. ~Port();
  304. void disconnect();
  305. int type;
  306. void draw(NVGcontext *vg);
  307. void drawGlow(NVGcontext *vg);
  308. void onMouseDown(int button);
  309. void onDragEnd();
  310. };
  311. struct InputPort : Port {
  312. int inputId;
  313. void draw(NVGcontext *vg);
  314. void onDragStart();
  315. void onDragDrop(Widget *origin);
  316. };
  317. struct OutputPort : Port {
  318. int outputId;
  319. void draw(NVGcontext *vg);
  320. void onDragStart();
  321. void onDragDrop(Widget *origin);
  322. };
  323. ////////////////////
  324. // scene
  325. ////////////////////
  326. struct Toolbar : Widget {
  327. Slider *wireOpacitySlider;
  328. Toolbar();
  329. void draw(NVGcontext *vg);
  330. };
  331. struct Scene : Widget {
  332. Toolbar *toolbar;
  333. ScrollWidget *scrollWidget;
  334. Scene();
  335. void onResize();
  336. };
  337. } // namespace rack