diff --git a/include/ui/MenuItem.hpp b/include/ui/MenuItem.hpp index e248372a..1d75488a 100644 --- a/include/ui/MenuItem.hpp +++ b/include/ui/MenuItem.hpp @@ -15,6 +15,7 @@ struct MenuItem : MenuEntry { bool disabled = false; void draw(const DrawArgs& args) override; + PRIVATE void drawOffset(NVGcontext* vg, float offset = 0); void step() override; void onEnter(const EnterEvent& e) override; void onDragDrop(const DragDropEvent& e) override; @@ -30,5 +31,13 @@ struct MenuItem : MenuEntry { }; +struct ColorDotMenuItem : MenuItem { + NVGcolor color; + + void draw(const DrawArgs& args) override; + void step() override; +}; + + } // namespace ui } // namespace rack diff --git a/src/app/PortWidget.cpp b/src/app/PortWidget.cpp index 9bd9802a..f87de97e 100644 --- a/src/app/PortWidget.cpp +++ b/src/app/PortWidget.cpp @@ -78,25 +78,6 @@ struct PortTooltip : ui::Tooltip { }; -struct ColorMenuItem : ui::MenuItem { - NVGcolor color; - - void draw(const DrawArgs& args) override { - MenuItem::draw(args); - - // Color circle - nvgBeginPath(args.vg); - float radius = 6.0; - nvgCircle(args.vg, 8.0 + radius, box.size.y / 2, radius); - nvgFillColor(args.vg, color); - nvgFill(args.vg); - nvgStrokeWidth(args.vg, 1.0); - nvgStrokeColor(args.vg, color::mult(color, 0.5)); - nvgStroke(args.vg); - } -}; - - struct PortCloneCableItem : ui::MenuItem { PortWidget* pw; CableWidget* cw; @@ -118,7 +99,7 @@ struct PortCloneCableItem : ui::MenuItem { }; -struct CableColorItem : ColorMenuItem { +struct CableColorItem : ui::ColorDotMenuItem { CableWidget* cw; void onAction(const ActionEvent& e) override { @@ -134,7 +115,7 @@ struct CableColorItem : ColorMenuItem { }; -struct PortCableItem : ColorMenuItem { +struct PortCableItem : ui::ColorDotMenuItem { PortWidget* pw; CableWidget* cw; @@ -158,7 +139,7 @@ struct PortCableItem : ColorMenuItem { for (NVGcolor color : settings::cableColors) { // Include extra leading spaces for the color circle - CableColorItem* item = createMenuItem(" Set color"); + CableColorItem* item = createMenuItem("Set color"); item->disabled = color::isEqual(color, cw->color); item->cw = cw; item->color = color; @@ -170,7 +151,7 @@ struct PortCableItem : ColorMenuItem { }; -struct PortCreateCableItem : ColorMenuItem { +struct PortCreateCableItem : ui::ColorDotMenuItem { PortWidget* pw; void onButton(const ButtonEvent& e) override { @@ -283,7 +264,7 @@ void PortWidget::createContextMenu() { bool createCableDisabled = (type == engine::Port::INPUT) && topCw; for (NVGcolor color : settings::cableColors) { // Include extra leading spaces for the color circle - PortCreateCableItem* item = createMenuItem(" New cable", "Click+drag"); + PortCreateCableItem* item = createMenuItem("New cable", "Click+drag"); item->disabled = createCableDisabled; item->pw = this; item->color = color; @@ -300,7 +281,7 @@ void PortWidget::createContextMenu() { PortWidget* pw = (type == engine::Port::INPUT) ? cw->outputPort : cw->inputPort; engine::PortInfo* portInfo = pw->getPortInfo(); - PortCableItem* item = createMenuItem(" " + portInfo->module->model->name + ": " + portInfo->getName(), RIGHT_ARROW); + PortCableItem* item = createMenuItem(portInfo->module->model->name + ": " + portInfo->getName(), RIGHT_ARROW); item->color = cw->color; item->pw = this; item->cw = cw; diff --git a/src/ui/MenuItem.cpp b/src/ui/MenuItem.cpp index f9909ff9..eb753cd4 100644 --- a/src/ui/MenuItem.cpp +++ b/src/ui/MenuItem.cpp @@ -7,36 +7,56 @@ namespace ui { void MenuItem::draw(const DrawArgs& args) { + drawOffset(args.vg, 0); +} + +void MenuItem::drawOffset(NVGcontext* vg, float offset) { BNDwidgetState state = BND_DEFAULT; if (APP->event->hoveredWidget == this) state = BND_HOVER; - // Set active state if this MenuItem + // Set active state if this MenuItem is the Menu's active entry Menu* parentMenu = dynamic_cast(parent); if (parentMenu && parentMenu->activeEntry == this) state = BND_ACTIVE; // Main text and background - if (!disabled) - bndMenuItem(args.vg, 0.0, 0.0, box.size.x, box.size.y, state, -1, text.c_str()); - else - bndMenuLabel(args.vg, 0.0, 0.0, box.size.x, box.size.y, -1, text.c_str()); + const BNDtheme* theme = bndGetTheme(); + if (!disabled) { + // bndMenuItem(vg, 0.0, 0.0, box.size.x, box.size.y, state, -1, text.c_str()); + // From bndMenuItem() implementation + if (state != BND_DEFAULT) { + bndInnerBox(vg, 0.0, 0.0, box.size.x, box.size.y, 0, 0, 0, 0, + bndOffsetColor(theme->menuItemTheme.innerSelectedColor, theme->menuItemTheme.shadeTop), + bndOffsetColor(theme->menuItemTheme.innerSelectedColor, theme->menuItemTheme.shadeDown)); + state = BND_ACTIVE; + } + bndIconLabelValue(vg, offset + 0.0, 0.0, box.size.x - offset, box.size.y, -1, + bndTextColor(&theme->menuItemTheme, state), BND_LEFT, + BND_LABEL_FONT_SIZE, text.c_str(), NULL); + } + else { + // bndMenuLabel(vg, 0.0, 0.0, box.size.x, box.size.y, -1, text.c_str()); + // From bndMenuLabel() implementation + 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); + } // Right text - float x = box.size.x - bndLabelWidth(args.vg, -1, rightText.c_str()); + float x = box.size.x - bndLabelWidth(vg, -1, rightText.c_str()); NVGcolor rightColor = (state == BND_DEFAULT && !disabled) ? bndGetTheme()->menuTheme.textColor : bndGetTheme()->menuTheme.textSelectedColor; - bndIconLabelValue(args.vg, x, 0.0, box.size.x, box.size.y, -1, rightColor, BND_LEFT, BND_LABEL_FONT_SIZE, rightText.c_str(), NULL); + bndIconLabelValue(vg, x, 0.0, box.size.x, box.size.y, -1, rightColor, BND_LEFT, BND_LABEL_FONT_SIZE, rightText.c_str(), NULL); } void MenuItem::step() { - // Add 10 more pixels because measurements on high-DPI screens are sometimes too small for some reason - const float rightPadding = 10.0; // HACK use APP->window->vg from the window. // 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. - box.size.x = bndLabelWidth(APP->window->vg, -1, text.c_str()) + rightPadding; + box.size.x = bndLabelWidth(APP->window->vg, -1, text.c_str()); if (!rightText.empty()) box.size.x += bndLabelWidth(APP->window->vg, -1, rightText.c_str()) - 10.0; + // Add 10 more pixels because measurements on high-DPI screens are sometimes too small for some reason + box.size.x += 10.0; + Widget::step(); } @@ -86,5 +106,25 @@ void MenuItem::onAction(const ActionEvent& e) { } +void ColorDotMenuItem::draw(const DrawArgs& args) { + drawOffset(args.vg, 20.0); + + // Color dot + nvgBeginPath(args.vg); + float radius = 6.0; + nvgCircle(args.vg, 8.0 + radius, box.size.y / 2, radius); + nvgFillColor(args.vg, color); + nvgFill(args.vg); + nvgStrokeWidth(args.vg, 1.0); + nvgStrokeColor(args.vg, color::mult(color, 0.5)); + nvgStroke(args.vg); +} + +void ColorDotMenuItem::step() { + MenuItem::step(); + box.size.x += 20.0; +} + + } // namespace ui } // namespace rack