Browse Source

Add ui::ColorDotMenuItem.

tags/v2.5.0
Andrew Belt 9 months ago
parent
commit
b95897c7da
3 changed files with 65 additions and 35 deletions
  1. +9
    -0
      include/ui/MenuItem.hpp
  2. +6
    -25
      src/app/PortWidget.cpp
  3. +50
    -10
      src/ui/MenuItem.cpp

+ 9
- 0
include/ui/MenuItem.hpp View File

@@ -15,6 +15,7 @@ struct MenuItem : MenuEntry {
bool disabled = false; bool disabled = false;


void draw(const DrawArgs& args) override; void draw(const DrawArgs& args) override;
PRIVATE void drawOffset(NVGcontext* vg, float offset = 0);
void step() override; void step() override;
void onEnter(const EnterEvent& e) override; void onEnter(const EnterEvent& e) override;
void onDragDrop(const DragDropEvent& 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 ui
} // namespace rack } // namespace rack

+ 6
- 25
src/app/PortWidget.cpp View File

@@ -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 { struct PortCloneCableItem : ui::MenuItem {
PortWidget* pw; PortWidget* pw;
CableWidget* cw; CableWidget* cw;
@@ -118,7 +99,7 @@ struct PortCloneCableItem : ui::MenuItem {
}; };




struct CableColorItem : ColorMenuItem {
struct CableColorItem : ui::ColorDotMenuItem {
CableWidget* cw; CableWidget* cw;


void onAction(const ActionEvent& e) override { void onAction(const ActionEvent& e) override {
@@ -134,7 +115,7 @@ struct CableColorItem : ColorMenuItem {
}; };




struct PortCableItem : ColorMenuItem {
struct PortCableItem : ui::ColorDotMenuItem {
PortWidget* pw; PortWidget* pw;
CableWidget* cw; CableWidget* cw;


@@ -158,7 +139,7 @@ struct PortCableItem : ColorMenuItem {


for (NVGcolor color : settings::cableColors) { for (NVGcolor color : settings::cableColors) {
// Include extra leading spaces for the color circle // Include extra leading spaces for the color circle
CableColorItem* item = createMenuItem<CableColorItem>(" Set color");
CableColorItem* item = createMenuItem<CableColorItem>("Set color");
item->disabled = color::isEqual(color, cw->color); item->disabled = color::isEqual(color, cw->color);
item->cw = cw; item->cw = cw;
item->color = color; item->color = color;
@@ -170,7 +151,7 @@ struct PortCableItem : ColorMenuItem {
}; };




struct PortCreateCableItem : ColorMenuItem {
struct PortCreateCableItem : ui::ColorDotMenuItem {
PortWidget* pw; PortWidget* pw;


void onButton(const ButtonEvent& e) override { void onButton(const ButtonEvent& e) override {
@@ -283,7 +264,7 @@ void PortWidget::createContextMenu() {
bool createCableDisabled = (type == engine::Port::INPUT) && topCw; bool createCableDisabled = (type == engine::Port::INPUT) && topCw;
for (NVGcolor color : settings::cableColors) { for (NVGcolor color : settings::cableColors) {
// Include extra leading spaces for the color circle // Include extra leading spaces for the color circle
PortCreateCableItem* item = createMenuItem<PortCreateCableItem>(" New cable", "Click+drag");
PortCreateCableItem* item = createMenuItem<PortCreateCableItem>("New cable", "Click+drag");
item->disabled = createCableDisabled; item->disabled = createCableDisabled;
item->pw = this; item->pw = this;
item->color = color; item->color = color;
@@ -300,7 +281,7 @@ void PortWidget::createContextMenu() {
PortWidget* pw = (type == engine::Port::INPUT) ? cw->outputPort : cw->inputPort; PortWidget* pw = (type == engine::Port::INPUT) ? cw->outputPort : cw->inputPort;
engine::PortInfo* portInfo = pw->getPortInfo(); engine::PortInfo* portInfo = pw->getPortInfo();


PortCableItem* item = createMenuItem<PortCableItem>(" " + portInfo->module->model->name + ": " + portInfo->getName(), RIGHT_ARROW);
PortCableItem* item = createMenuItem<PortCableItem>(portInfo->module->model->name + ": " + portInfo->getName(), RIGHT_ARROW);
item->color = cw->color; item->color = cw->color;
item->pw = this; item->pw = this;
item->cw = cw; item->cw = cw;


+ 50
- 10
src/ui/MenuItem.cpp View File

@@ -7,36 +7,56 @@ namespace ui {




void MenuItem::draw(const DrawArgs& args) { void MenuItem::draw(const DrawArgs& args) {
drawOffset(args.vg, 0);
}

void MenuItem::drawOffset(NVGcontext* vg, float offset) {
BNDwidgetState state = BND_DEFAULT; BNDwidgetState state = BND_DEFAULT;


if (APP->event->hoveredWidget == this) if (APP->event->hoveredWidget == this)
state = BND_HOVER; 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<Menu*>(parent); Menu* parentMenu = dynamic_cast<Menu*>(parent);
if (parentMenu && parentMenu->activeEntry == this) if (parentMenu && parentMenu->activeEntry == this)
state = BND_ACTIVE; state = BND_ACTIVE;


// Main text and background // 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 // 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; 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() { 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. // 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. // 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()) if (!rightText.empty())
box.size.x += bndLabelWidth(APP->window->vg, -1, rightText.c_str()) - 10.0; 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(); 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 ui
} // namespace rack } // namespace rack

Loading…
Cancel
Save