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.

86 lines
2.2KB

  1. #pragma once
  2. #include <list>
  3. #include "common.hpp"
  4. #include "math.hpp"
  5. #include "window.hpp"
  6. #include "color.hpp"
  7. namespace rack {
  8. namespace event {
  9. struct Event;
  10. } // namespace event
  11. /** A node in the 2D scene graph */
  12. struct Widget {
  13. /** Stores position and size */
  14. math::Rect box = math::Rect(math::Vec(), math::Vec(INFINITY, INFINITY));
  15. /** Automatically set when Widget is added as a child to another Widget */
  16. Widget *parent = NULL;
  17. std::list<Widget*> children;
  18. /** Disables rendering but allow stepping */
  19. bool visible = true;
  20. /** If set to true, parent will delete Widget in the next step() */
  21. bool requestedDelete = false;
  22. virtual ~Widget();
  23. virtual math::Rect getChildrenBoundingBox();
  24. /** Returns `v` transformed into the coordinate system of `relative` */
  25. virtual math::Vec getRelativeOffset(math::Vec v, Widget *relative);
  26. /** Returns `v` transformed into world coordinates */
  27. math::Vec getAbsoluteOffset(math::Vec v) {
  28. return getRelativeOffset(v, NULL);
  29. }
  30. /** Returns a subset of the given math::Rect bounded by the box of this widget and all ancestors */
  31. virtual math::Rect getViewport(math::Rect r);
  32. template <class T>
  33. T *getAncestorOfType() {
  34. if (!parent) return NULL;
  35. T *p = dynamic_cast<T*>(parent);
  36. if (p) return p;
  37. return parent->getAncestorOfType<T>();
  38. }
  39. template <class T>
  40. T *getFirstDescendantOfType() {
  41. for (Widget *child : children) {
  42. T *c = dynamic_cast<T*>(child);
  43. if (c) return c;
  44. c = child->getFirstDescendantOfType<T>();
  45. if (c) return c;
  46. }
  47. return NULL;
  48. }
  49. /** Adds widget to list of children.
  50. Gives ownership of widget to this widget instance.
  51. */
  52. void addChild(Widget *widget);
  53. /** Removes widget from list of children if it exists.
  54. Does not delete widget but transfers ownership to caller
  55. */
  56. void removeChild(Widget *widget);
  57. /** Removes and deletes all children */
  58. void clearChildren();
  59. /** Advances the module by one frame */
  60. virtual void step();
  61. /** Draws to NanoVG context */
  62. virtual void draw(NVGcontext *vg);
  63. /** Trigger an event on this Widget. */
  64. virtual void handleEvent(event::Event &e) {
  65. // Basic widgets do not handle events, but the EventWidget subclass does.
  66. }
  67. };
  68. } // namespace rack