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.

399 lines
8.1KB

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