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.

471 lines
12KB

  1. #pragma once
  2. #include <list>
  3. #include <memory>
  4. #include "../ext/nanovg/src/nanovg.h"
  5. #include "../ext/oui-blendish/blendish.h"
  6. #include "../ext/nanosvg/src/nanosvg.h"
  7. #include "util/common.hpp"
  8. #include "events.hpp"
  9. namespace rack {
  10. ////////////////////
  11. // resources
  12. ////////////////////
  13. // Constructing these directly will load from the disk each time. Use the load() functions to load from disk and cache them as long as the shared_ptr is held.
  14. // Implemented in gui.cpp
  15. struct Font {
  16. int handle;
  17. Font(const std::string &filename);
  18. ~Font();
  19. static std::shared_ptr<Font> load(const std::string &filename);
  20. };
  21. struct Image {
  22. int handle;
  23. Image(const std::string &filename);
  24. ~Image();
  25. static std::shared_ptr<Image> load(const std::string &filename);
  26. };
  27. struct SVG {
  28. NSVGimage *handle;
  29. SVG(const std::string &filename);
  30. ~SVG();
  31. static std::shared_ptr<SVG> load(const std::string &filename);
  32. };
  33. ////////////////////
  34. // Base widget
  35. ////////////////////
  36. /** A node in the 2D scene graph */
  37. struct Widget {
  38. /** Stores position and size */
  39. Rect box = Rect(Vec(), Vec(INFINITY, INFINITY));
  40. Widget *parent = NULL;
  41. std::list<Widget*> children;
  42. bool visible = true;
  43. virtual ~Widget();
  44. virtual Rect getChildrenBoundingBox();
  45. /** Returns `v` transformed into the coordinate system of `relative` */
  46. virtual Vec getRelativeOffset(Vec v, Widget *relative);
  47. /** Returns `v` transformed into world coordinates */
  48. Vec getAbsoluteOffset(Vec v) {
  49. return getRelativeOffset(v, NULL);
  50. }
  51. /** Returns a subset of the given Rect bounded by the box of this widget and all ancestors */
  52. virtual Rect getViewport(Rect r);
  53. template <class T>
  54. T *getAncestorOfType() {
  55. if (!parent) return NULL;
  56. T *p = dynamic_cast<T*>(parent);
  57. if (p) return p;
  58. return parent->getAncestorOfType<T>();
  59. }
  60. template <class T>
  61. T *getFirstDescendantOfType() {
  62. for (Widget *child : children) {
  63. T *c = dynamic_cast<T*>(child);
  64. if (c) return c;
  65. c = child->getFirstDescendantOfType<T>();
  66. if (c) return c;
  67. }
  68. return NULL;
  69. }
  70. /** Adds widget to list of children.
  71. Gives ownership of widget to this widget instance.
  72. */
  73. void addChild(Widget *widget);
  74. /** Removes widget from list of children if it exists.
  75. Does not delete widget but transfers ownership to caller
  76. Silently fails if widget is not a child
  77. */
  78. void removeChild(Widget *widget);
  79. void clearChildren();
  80. /** Recursively finalizes event start/end pairs as needed */
  81. void finalizeEvents();
  82. /** Advances the module by one frame */
  83. virtual void step();
  84. /** Draws to NanoVG context */
  85. virtual void draw(NVGcontext *vg);
  86. // Events
  87. /** Called when a mouse button is pressed over this widget
  88. 0 for left, 1 for right, 2 for middle.
  89. Return `this` to accept the event.
  90. Return NULL to reject the event and pass it to the widget behind this one.
  91. */
  92. virtual void onMouseDown(EventMouseDown &e);
  93. virtual void onMouseUp(EventMouseUp &e);
  94. /** Called on every frame, even if mouseRel = Vec(0, 0) */
  95. virtual void onMouseMove(EventMouseMove &e);
  96. virtual void onHoverKey(EventHoverKey &e);
  97. /** Called when this widget begins responding to `onMouseMove` events */
  98. virtual void onMouseEnter(EventMouseEnter &e) {}
  99. /** Called when another widget begins responding to `onMouseMove` events */
  100. virtual void onMouseLeave(EventMouseLeave &e) {}
  101. virtual void onFocus(EventFocus &e) {}
  102. virtual void onDefocus(EventDefocus &e) {}
  103. virtual void onText(EventText &e) {}
  104. virtual void onKey(EventKey &e) {}
  105. virtual void onScroll(EventScroll &e);
  106. /** Called when a widget responds to `onMouseDown` for a left button press */
  107. virtual void onDragStart(EventDragStart &e) {}
  108. /** Called when the left button is released and this widget is being dragged */
  109. virtual void onDragEnd(EventDragEnd &e) {}
  110. /** Called when a widget responds to `onMouseMove` and is being dragged */
  111. virtual void onDragMove(EventDragMove &e) {}
  112. /** Called when a widget responds to `onMouseUp` for a left button release and a widget is being dragged */
  113. virtual void onDragEnter(EventDragEnter &e) {}
  114. virtual void onDragLeave(EventDragEnter &e) {}
  115. virtual void onDragDrop(EventDragDrop &e) {}
  116. virtual void onPathDrop(EventPathDrop &e);
  117. virtual void onAction(EventAction &e) {}
  118. virtual void onChange(EventChange &e) {}
  119. virtual void onZoom(EventZoom &e);
  120. };
  121. struct TransformWidget : Widget {
  122. /** The transformation matrix */
  123. float transform[6];
  124. TransformWidget();
  125. Rect getChildrenBoundingBox() override;
  126. void identity();
  127. void translate(Vec delta);
  128. void rotate(float angle);
  129. void scale(Vec s);
  130. void draw(NVGcontext *vg) override;
  131. };
  132. struct ZoomWidget : Widget {
  133. float zoom = 1.0;
  134. Vec getRelativeOffset(Vec v, Widget *relative) override;
  135. Rect getViewport(Rect r) override;
  136. void setZoom(float zoom);
  137. void draw(NVGcontext *vg) override;
  138. void onMouseDown(EventMouseDown &e) override;
  139. void onMouseUp(EventMouseUp &e) override;
  140. void onMouseMove(EventMouseMove &e) override;
  141. void onHoverKey(EventHoverKey &e) override;
  142. void onScroll(EventScroll &e) override;
  143. void onPathDrop(EventPathDrop &e) override;
  144. };
  145. ////////////////////
  146. // Trait widgets
  147. ////////////////////
  148. /** Widget that does not respond to events */
  149. struct TransparentWidget : virtual Widget {
  150. void onMouseDown(EventMouseDown &e) override {}
  151. void onMouseUp(EventMouseUp &e) override {}
  152. void onMouseMove(EventMouseMove &e) override {}
  153. void onScroll(EventScroll &e) override {}
  154. };
  155. /** Widget that automatically responds to all mouse events but gives a chance for children to respond instead */
  156. struct OpaqueWidget : virtual Widget {
  157. void onMouseDown(EventMouseDown &e) override {
  158. Widget::onMouseDown(e);
  159. if (!e.target)
  160. e.target = this;
  161. e.consumed = true;
  162. }
  163. void onMouseUp(EventMouseUp &e) override {
  164. Widget::onMouseUp(e);
  165. if (!e.target)
  166. e.target = this;
  167. e.consumed = true;
  168. }
  169. void onMouseMove(EventMouseMove &e) override {
  170. Widget::onMouseMove(e);
  171. if (!e.target)
  172. e.target = this;
  173. e.consumed = true;
  174. }
  175. void onScroll(EventScroll &e) override {
  176. Widget::onScroll(e);
  177. e.consumed = true;
  178. }
  179. };
  180. struct SpriteWidget : virtual Widget {
  181. Vec spriteOffset;
  182. Vec spriteSize;
  183. std::shared_ptr<Image> spriteImage;
  184. int index = 0;
  185. void draw(NVGcontext *vg) override;
  186. };
  187. struct SVGWidget : virtual Widget {
  188. std::shared_ptr<SVG> svg;
  189. /** Sets the box size to the svg image size */
  190. void wrap();
  191. /** Sets and wraps the SVG */
  192. void setSVG(std::shared_ptr<SVG> svg);
  193. void draw(NVGcontext *vg) override;
  194. };
  195. /** Caches a widget's draw() result to a framebuffer so it is called less frequently
  196. When `dirty` is true, its children will be re-rendered on the next call to step() override.
  197. Events are not passed to the underlying scene.
  198. */
  199. struct FramebufferWidget : virtual Widget {
  200. /** Set this to true to re-render the children to the framebuffer the next time it is drawn */
  201. bool dirty = true;
  202. /** A margin in pixels around the children in the framebuffer
  203. This prevents cutting the rendered SVG off on the box edges.
  204. */
  205. float oversample;
  206. /** The root object in the framebuffer scene
  207. The FramebufferWidget owns the pointer
  208. */
  209. struct Internal;
  210. Internal *internal;
  211. FramebufferWidget();
  212. ~FramebufferWidget();
  213. void draw(NVGcontext *vg) override;
  214. int getImageHandle();
  215. void onZoom(EventZoom &e) override;
  216. };
  217. struct QuantityWidget : virtual Widget {
  218. float value = 0.0;
  219. float minValue = 0.0;
  220. float maxValue = 1.0;
  221. float defaultValue = 0.0;
  222. std::string label;
  223. /** Include a space character if you want a space after the number, e.g. " Hz" */
  224. std::string unit;
  225. /** The decimal place to round for displaying values.
  226. A precision of 2 will display as "1.00" for example.
  227. */
  228. int precision = 2;
  229. QuantityWidget();
  230. void setValue(float value);
  231. void setLimits(float minValue, float maxValue);
  232. void setDefaultValue(float defaultValue);
  233. /** Generates the display value */
  234. std::string getText();
  235. };
  236. ////////////////////
  237. // GUI widgets
  238. ////////////////////
  239. struct Label : Widget {
  240. std::string text;
  241. Label() {
  242. box.size.y = BND_WIDGET_HEIGHT;
  243. }
  244. void draw(NVGcontext *vg) override;
  245. };
  246. /** Deletes itself from parent when clicked */
  247. struct MenuOverlay : OpaqueWidget {
  248. void step() override;
  249. void onMouseDown(EventMouseDown &e) override;
  250. void onHoverKey(EventHoverKey &e) override;
  251. };
  252. struct MenuEntry;
  253. struct Menu : OpaqueWidget {
  254. Menu *parentMenu = NULL;
  255. Menu *childMenu = NULL;
  256. /** The entry which created the child menu */
  257. MenuEntry *activeEntry = NULL;
  258. Menu() {
  259. box.size = Vec(0, 0);
  260. }
  261. ~Menu();
  262. // Resizes menu and calls addChild()
  263. void pushChild(Widget *child) DEPRECATED {
  264. addChild(child);
  265. }
  266. void setChildMenu(Menu *menu);
  267. void step() override;
  268. void draw(NVGcontext *vg) override;
  269. void onScroll(EventScroll &e) override;
  270. };
  271. struct MenuEntry : OpaqueWidget {
  272. std::string text;
  273. MenuEntry() {
  274. box.size = Vec(0, BND_WIDGET_HEIGHT);
  275. }
  276. };
  277. struct MenuLabel : MenuEntry {
  278. void draw(NVGcontext *vg) override;
  279. void step() override;
  280. };
  281. struct MenuItem : MenuEntry {
  282. std::string rightText;
  283. void draw(NVGcontext *vg) override;
  284. void step() override;
  285. virtual Menu *createChildMenu() {return NULL;}
  286. void onMouseEnter(EventMouseEnter &e) override;
  287. void onDragDrop(EventDragDrop &e) override;
  288. };
  289. struct WindowOverlay : OpaqueWidget {
  290. };
  291. struct Window : OpaqueWidget {
  292. std::string title;
  293. void draw(NVGcontext *vg) override;
  294. void onDragMove(EventDragMove &e) override;
  295. };
  296. struct Button : OpaqueWidget {
  297. std::string text;
  298. BNDwidgetState state = BND_DEFAULT;
  299. Button() {
  300. box.size.y = BND_WIDGET_HEIGHT;
  301. }
  302. void draw(NVGcontext *vg) override;
  303. void onMouseEnter(EventMouseEnter &e) override;
  304. void onMouseLeave(EventMouseLeave &e) override;
  305. void onDragStart(EventDragStart &e) override;
  306. void onDragEnd(EventDragEnd &e) override;
  307. void onDragDrop(EventDragDrop &e) override;
  308. };
  309. struct ChoiceButton : Button {
  310. void draw(NVGcontext *vg) override;
  311. };
  312. struct RadioButton : OpaqueWidget, QuantityWidget {
  313. BNDwidgetState state = BND_DEFAULT;
  314. RadioButton() {
  315. box.size.y = BND_WIDGET_HEIGHT;
  316. }
  317. void draw(NVGcontext *vg) override;
  318. void onMouseEnter(EventMouseEnter &e) override;
  319. void onMouseLeave(EventMouseLeave &e) override;
  320. void onDragDrop(EventDragDrop &e) override;
  321. };
  322. struct Slider : OpaqueWidget, QuantityWidget {
  323. BNDwidgetState state = BND_DEFAULT;
  324. Slider() {
  325. box.size.y = BND_WIDGET_HEIGHT;
  326. }
  327. void draw(NVGcontext *vg) override;
  328. void onDragStart(EventDragStart &e) override;
  329. void onDragMove(EventDragMove &e) override;
  330. void onDragEnd(EventDragEnd &e) override;
  331. void onMouseDown(EventMouseDown &e) override;
  332. };
  333. /** Parent must be a ScrollWidget */
  334. struct ScrollBar : OpaqueWidget {
  335. enum { VERTICAL, HORIZONTAL } orientation;
  336. BNDwidgetState state = BND_DEFAULT;
  337. float offset = 0.0;
  338. float size = 0.0;
  339. ScrollBar() {
  340. box.size = Vec(BND_SCROLLBAR_WIDTH, BND_SCROLLBAR_HEIGHT);
  341. }
  342. void draw(NVGcontext *vg) override;
  343. void onDragStart(EventDragStart &e) override;
  344. void onDragMove(EventDragMove &e) override;
  345. void onDragEnd(EventDragEnd &e) override;
  346. };
  347. /** Handles a container with ScrollBar */
  348. struct ScrollWidget : OpaqueWidget {
  349. Widget *container;
  350. ScrollBar *horizontalScrollBar;
  351. ScrollBar *verticalScrollBar;
  352. Vec offset;
  353. ScrollWidget();
  354. void draw(NVGcontext *vg) override;
  355. void step() override;
  356. void onMouseMove(EventMouseMove &e) override;
  357. void onScroll(EventScroll &e) override;
  358. };
  359. struct TextField : OpaqueWidget {
  360. std::string text;
  361. std::string placeholder;
  362. bool multiline = false;
  363. int begin = 0;
  364. int end = 0;
  365. TextField() {
  366. box.size.y = BND_WIDGET_HEIGHT;
  367. }
  368. void draw(NVGcontext *vg) override;
  369. void onMouseDown(EventMouseDown &e) override;
  370. void onFocus(EventFocus &e) override;
  371. void onText(EventText &e) override;
  372. void onKey(EventKey &e) override;
  373. void insertText(std::string newText);
  374. virtual void onTextChange() {}
  375. };
  376. struct PasswordField : TextField {
  377. void draw(NVGcontext *vg) override;
  378. };
  379. struct ProgressBar : TransparentWidget, QuantityWidget {
  380. ProgressBar() {
  381. box.size.y = BND_WIDGET_HEIGHT;
  382. }
  383. void draw(NVGcontext *vg) override;
  384. };
  385. struct Tooltip : Widget {
  386. void step() override;
  387. void draw(NVGcontext *vg) override;
  388. };
  389. struct Scene : OpaqueWidget {
  390. Widget *overlay = NULL;
  391. void setOverlay(Widget *w);
  392. Menu *createMenu();
  393. void step() override;
  394. };
  395. ////////////////////
  396. // globals
  397. ////////////////////
  398. extern Widget *gHoveredWidget;
  399. extern Widget *gDraggedWidget;
  400. extern Widget *gDragHoveredWidget;
  401. extern Widget *gFocusedWidget;
  402. extern Scene *gScene;
  403. } // namespace rack