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.

131 lines
3.7KB

  1. #include <ui/MenuItem.hpp>
  2. #include <ui/MenuOverlay.hpp>
  3. namespace rack {
  4. namespace ui {
  5. void MenuItem::draw(const DrawArgs& args) {
  6. drawOffset(args.vg, 0);
  7. }
  8. void MenuItem::drawOffset(NVGcontext* vg, float offset) {
  9. BNDwidgetState state = BND_DEFAULT;
  10. if (APP->event->hoveredWidget == this)
  11. state = BND_HOVER;
  12. // Set active state if this MenuItem is the Menu's active entry
  13. Menu* parentMenu = dynamic_cast<Menu*>(parent);
  14. if (parentMenu && parentMenu->activeEntry == this)
  15. state = BND_ACTIVE;
  16. // Main text and background
  17. const BNDtheme* theme = bndGetTheme();
  18. if (!disabled) {
  19. // bndMenuItem(vg, 0.0, 0.0, box.size.x, box.size.y, state, -1, text.c_str());
  20. // From bndMenuItem() implementation
  21. if (state != BND_DEFAULT) {
  22. bndInnerBox(vg, 0.0, 0.0, box.size.x, box.size.y, 0, 0, 0, 0,
  23. bndOffsetColor(theme->menuItemTheme.innerSelectedColor, theme->menuItemTheme.shadeTop),
  24. bndOffsetColor(theme->menuItemTheme.innerSelectedColor, theme->menuItemTheme.shadeDown));
  25. state = BND_ACTIVE;
  26. }
  27. bndIconLabelValue(vg, offset + 0.0, 0.0, box.size.x - offset, box.size.y, -1,
  28. bndTextColor(&theme->menuItemTheme, state), BND_LEFT,
  29. BND_LABEL_FONT_SIZE, text.c_str(), NULL);
  30. }
  31. else {
  32. // bndMenuLabel(vg, 0.0, 0.0, box.size.x, box.size.y, -1, text.c_str());
  33. // From bndMenuLabel() implementation
  34. bndIconLabelValue(vg, offset + 0.0, 0.0, box.size.x, box.size.y, -1, theme->menuTheme.textColor, BND_LEFT, BND_LABEL_FONT_SIZE, text.c_str(), NULL);
  35. }
  36. // Right text
  37. float x = box.size.x - bndLabelWidth(vg, -1, rightText.c_str());
  38. NVGcolor rightColor = (state == BND_DEFAULT && !disabled) ? bndGetTheme()->menuTheme.textColor : bndGetTheme()->menuTheme.textSelectedColor;
  39. bndIconLabelValue(vg, x, 0.0, box.size.x, box.size.y, -1, rightColor, BND_LEFT, BND_LABEL_FONT_SIZE, rightText.c_str(), NULL);
  40. }
  41. void MenuItem::step() {
  42. // HACK use APP->window->vg from the window.
  43. // All this does is inspect the font, so it shouldn't modify APP->window->vg and should work when called from a widget::FramebufferWidget for example.
  44. box.size.x = bndLabelWidth(APP->window->vg, -1, text.c_str());
  45. if (!rightText.empty())
  46. box.size.x += bndLabelWidth(APP->window->vg, -1, rightText.c_str()) - 10.0;
  47. // Add 10 more pixels because measurements on high-DPI screens are sometimes too small for some reason
  48. box.size.x += 10.0;
  49. Widget::step();
  50. }
  51. void MenuItem::onEnter(const EnterEvent& e) {
  52. Menu* parentMenu = dynamic_cast<Menu*>(parent);
  53. if (!parentMenu)
  54. return;
  55. parentMenu->activeEntry = NULL;
  56. // Try to create child menu
  57. Menu* childMenu = createChildMenu();
  58. if (childMenu) {
  59. parentMenu->activeEntry = this;
  60. childMenu->box.pos = parent->box.pos.plus(box.getTopRight());
  61. }
  62. parentMenu->setChildMenu(childMenu);
  63. }
  64. void MenuItem::onDragDrop(const DragDropEvent& e) {
  65. if (e.origin == this && !disabled) {
  66. int mods = APP->window->getMods();
  67. doAction((mods & RACK_MOD_MASK) != RACK_MOD_CTRL);
  68. }
  69. }
  70. void MenuItem::doAction(bool consume) {
  71. widget::EventContext cAction;
  72. ActionEvent eAction;
  73. eAction.context = &cAction;
  74. if (consume) {
  75. eAction.consume(this);
  76. }
  77. onAction(eAction);
  78. if (!cAction.consumed)
  79. return;
  80. // Close menu
  81. MenuOverlay* overlay = getAncestorOfType<MenuOverlay>();
  82. if (overlay) {
  83. overlay->requestDelete();
  84. }
  85. }
  86. void MenuItem::onAction(const ActionEvent& e) {
  87. }
  88. void ColorDotMenuItem::draw(const DrawArgs& args) {
  89. drawOffset(args.vg, 20.0);
  90. // Color dot
  91. nvgBeginPath(args.vg);
  92. float radius = 6.0;
  93. nvgCircle(args.vg, 8.0 + radius, box.size.y / 2, radius);
  94. nvgFillColor(args.vg, color);
  95. nvgFill(args.vg);
  96. nvgStrokeWidth(args.vg, 1.0);
  97. nvgStrokeColor(args.vg, color::mult(color, 0.5));
  98. nvgStroke(args.vg);
  99. }
  100. void ColorDotMenuItem::step() {
  101. MenuItem::step();
  102. box.size.x += 20.0;
  103. }
  104. } // namespace ui
  105. } // namespace rack