From 6e65bae57966339ef36cb114966fd36e19d0e113 Mon Sep 17 00:00:00 2001 From: dreamer Date: Sun, 12 Jul 2026 11:40:37 +0200 Subject: [PATCH 1/5] start working on popmenu --- pdvg.hpp | 1 + src/Common.hpp | 34 +++++++++- src/ExtraEventHandlers.cpp | 124 ++++++++++++++++++++++++++++++++++++- src/ExtraEventHandlers.hpp | 32 ++++++++++ src/Popmenu.cpp | 74 ++++++++++++++++++++++ src/Popmenu.hpp | 40 ++++++++++++ 6 files changed, 300 insertions(+), 5 deletions(-) create mode 100644 src/Popmenu.cpp create mode 100644 src/Popmenu.hpp diff --git a/pdvg.hpp b/pdvg.hpp index cba7805..01871fc 100644 --- a/pdvg.hpp +++ b/pdvg.hpp @@ -19,3 +19,4 @@ #include "src/Slider.hpp" #include "src/Subpatch.hpp" #include "src/Knob.hpp" +#include "src/Popmenu.hpp" diff --git a/src/Common.hpp b/src/Common.hpp index 78b3279..750b724 100644 --- a/src/Common.hpp +++ b/src/Common.hpp @@ -64,14 +64,12 @@ static Rectangle reduceRectangle(Rectangle r, float amount) { // (x + delta, y + delta, w - delta * 2, h - delta * 2) - Rectangle nR( + return Rectangle( r.getX() + amount, r.getY() + amount, r.getWidth() - amount * 2, r.getHeight() - amount * 2 ); - - return nR; } static Rectangle subtractBorder(Rectangle r, Border border) @@ -84,6 +82,36 @@ static Rectangle subtractBorder(Rectangle r, Border border) ); } +static Rectangle removeFromRight(Rectangle r, float amount) +{ + return Rectangle( + r.getX(), + r.getY(), + r.getWidth() - amount, + r.getHeight() + ); +} + +static Rectangle resizeCentered(Rectangle r, float width, float height) +{ + return Rectangle( + r.getX() + (r.getWidth() - width) / 2.0f, + r.getY() + (r.getHeight() - height) / 2.0f, + width, + height + ); +} + +static Rectangle translateRectangle(Rectangle r, float x, float y) +{ + return Rectangle( + r.getX() + x, + r.getY() + y, + r.getWidth(), + r.getHeight() + ); +} + static float valToPropOfLen(float const value, float const length) { return value / length; diff --git a/src/ExtraEventHandlers.cpp b/src/ExtraEventHandlers.cpp index 8ef9bce..73446d1 100644 --- a/src/ExtraEventHandlers.cpp +++ b/src/ExtraEventHandlers.cpp @@ -36,7 +36,6 @@ struct PDToggleEventHandler::PrivateData widget(w), callback(other->callback), isDown(other->isDown) - { } @@ -682,7 +681,6 @@ struct PDRadioEventHandler::PrivateData bool mouseEvent(const Widget::MouseEvent &ev) { - if (ev.button != 1) return false; @@ -1655,5 +1653,127 @@ bool PDKnobEventHandler::scrollEvent(const Widget::ScrollEvent &ev) return pData->scrollEvent(ev); } // end knob +// -------------------------------------------------------------------------------------------------------------------- + +// begin popmenu +struct PDPopmenuEventHandler::PrivateData +{ + PDPopmenuEventHandler *const self; + SubWidget *const widget; + PDPopmenuEventHandler::Callback *callback; + + uint length; + uint value; + + PrivateData(PDPopmenuEventHandler *const s, SubWidget *const w) + : self(s), + widget(w), + callback(nullptr), + length(0), + value(0) + { + } + + PrivateData(PDPopmenuEventHandler *const s, SubWidget *const w, PrivateData *const other) + : self(s), + widget(w), + callback(other->callback), + length(other->length), + value(other->value) + { + } + + void assignFrom(PrivateData *const other) + { + callback = other->callback; + length = other->length; + value = other->value; + } + + bool mouseEvent(const Widget::MouseEvent &ev) + { + if (ev.button != 1) + return false; + + PDWidget* pdWidget = dynamic_cast(widget); + if (ev.press && pdWidget->contains(ev.pos)) + { + // if (callback != nullptr) + // { + // try + // { + // callback->popmenuClicked(widget, value); + // } + // DISTRHO_SAFE_EXCEPTION("PDPopmenuEventHandler::mouseEvent"); + // } + return true; + } + return false; + } + + bool setValue(const uint value2, const bool sendCallback) + { + if (value != value2) + { + value = value2; + if (sendCallback && callback != nullptr) + { + try + { + callback->popmenuClicked(widget, value); + } + DISTRHO_SAFE_EXCEPTION("PDPopmenuEventHandler::setValue"); + } + return true; + } + return false; + } +}; + +// -------------------------------------------------------------------------------------------------------------------- + +PDPopmenuEventHandler::PDPopmenuEventHandler(SubWidget *const self) + : pData(new PrivateData(this, self)) {} + +PDPopmenuEventHandler::PDPopmenuEventHandler(SubWidget *const self, const PDPopmenuEventHandler &other) + : pData(new PrivateData(this, self, other.pData)) {} + +PDPopmenuEventHandler &PDPopmenuEventHandler::operator=(const PDPopmenuEventHandler &other) +{ + pData->assignFrom(other.pData); + return *this; +} + +PDPopmenuEventHandler::~PDPopmenuEventHandler() +{ + delete pData; +} + +uint PDPopmenuEventHandler::getValue() const noexcept +{ + return pData->value; +} + +bool PDPopmenuEventHandler::setValue(const int value, const bool sendCallback) noexcept +{ + return pData->setValue(static_cast(value), sendCallback); +} + +void PDPopmenuEventHandler::setLength(int length) noexcept +{ + pData->length = length; +} + +void PDPopmenuEventHandler::setCallback(Callback *const callback) noexcept +{ + pData->callback = callback; +} + +bool PDPopmenuEventHandler::mouseEvent(const Widget::MouseEvent &ev) +{ + return pData->mouseEvent(ev); +} + +// end popmenu END_NAMESPACE_DGL diff --git a/src/ExtraEventHandlers.hpp b/src/ExtraEventHandlers.hpp index aa70070..a3045aa 100644 --- a/src/ExtraEventHandlers.hpp +++ b/src/ExtraEventHandlers.hpp @@ -315,6 +315,38 @@ class PDKnobEventHandler DISTRHO_LEAK_DETECTOR(PDKnobEventHandler) }; +class PDPopmenuEventHandler +{ +public: + class Callback + { + public: + virtual ~Callback() {} + virtual void popmenuClicked(SubWidget *widget, uint index) = 0; + }; + + explicit PDPopmenuEventHandler(SubWidget *self); + explicit PDPopmenuEventHandler(SubWidget *self, const PDPopmenuEventHandler &other); + PDPopmenuEventHandler &operator=(const PDPopmenuEventHandler &other); + ~PDPopmenuEventHandler(); + + uint getValue() const noexcept; + + virtual bool setValue(int value, bool sendCallback = false) noexcept; + + void setLength(int length) noexcept; + void setCallback(Callback *callback) noexcept; + + bool mouseEvent(const Widget::MouseEvent &ev); + +protected: +private: + struct PrivateData; + PrivateData *const pData; + + DISTRHO_LEAK_DETECTOR(PDPopmenuEventHandler) +}; + // -------------------------------------------------------------------------------------------------------------------- END_NAMESPACE_DGL diff --git a/src/Popmenu.cpp b/src/Popmenu.cpp new file mode 100644 index 0000000..ab98487 --- /dev/null +++ b/src/Popmenu.cpp @@ -0,0 +1,74 @@ +/* + * Copyright (C) 2026 Wasted Audio + * SPDX-License-Identifier: ISC +*/ + +#include "nanovg.h" + +#include "Common.hpp" +#include "Popmenu.hpp" + + +START_NAMESPACE_DISTRHO + +PDPopmenu::PDPopmenu(NanoSubWidget* parent, PDPopmenuEventHandler::Callback* cb) + : PDWidget(parent), + PDPopmenuEventHandler(this) +{ + PDPopmenuEventHandler::setCallback(cb); +} + +void PDPopmenu::onNanoDisplay() +{ + const float scaleFactor = getTopLevelWidget()->getScaleFactor(); + const Rectangle b(0.0f, 0.0f, getWidth(), getHeight()); + + NVGcontext* nvg = getContext(); + + drawRoundedRect(nvg, b.getX(), b.getY(), b.getWidth(), b.getHeight(), bgColor, Colors::outColor, Corners::objectCornerRadius); + + // auto textBounds = getLocalBounds().reduced(2).translated(2, 0); + auto textBounds = translateRectangle(reduceRectangle(b, 2), 2, 0); + // if (!textBounds.isEmpty()) { + // textRenderer.renderText(nvg, textBounds.toFloat(), getImageScale()); + // } + + // auto const triangleBounds = b.removeFromRight(20).withSizeKeepingCentre(20, std::min(getHeight(), 12)); + auto const triangleBounds = resizeCentered(removeFromRight(b, 20), 20, std::min((int)b.getHeight(), 12)); + + nvgStrokeColor(nvg, fgColor); + nvgBeginPath(nvg); + nvgMoveTo(nvg, (triangleBounds.getX() - triangleBounds.getWidth() / 2.0f) - 3 * scaleFactor, triangleBounds.getY() + 3 * scaleFactor); + nvgLineTo(nvg, (triangleBounds.getX() - triangleBounds.getWidth() / 2.0f), triangleBounds.getY()); + nvgLineTo(nvg, (triangleBounds.getX() - triangleBounds.getWidth() / 2.0f) + 3 * scaleFactor, triangleBounds.getY() + 3 * scaleFactor); + nvgStroke(nvg); + + nvgBeginPath(nvg); + nvgMoveTo(nvg, (triangleBounds.getX() - triangleBounds.getWidth() / 2.0f) - 3 * scaleFactor, triangleBounds.getY() - triangleBounds.getHeight() - 3 * scaleFactor); + nvgLineTo(nvg, (triangleBounds.getX() - triangleBounds.getWidth() / 2.0f), triangleBounds.getY() - triangleBounds.getHeight()); + nvgLineTo(nvg, (triangleBounds.getX() - triangleBounds.getWidth() / 2.0f) + 3 * scaleFactor, triangleBounds.getY() - triangleBounds.getHeight() - 3 * scaleFactor); + nvgStroke(nvg); +} + +bool PDPopmenu::onMouse(const MouseEvent &ev) +{ + return PDPopmenuEventHandler::mouseEvent(ev); +} + +void PDPopmenu::setColors(NVGcolor bgColor, NVGcolor fgColor) +{ + this->bgColor = bgColor; + this->fgColor = fgColor; +} + +void PDPopmenu::setOptions(std::vector options) +{ + this->options = options; +} + +void PDPopmenu::setFontSize(float fontSize) +{ + this->fontSize = fontSize; +} + +END_NAMESPACE_DISTRHO diff --git a/src/Popmenu.hpp b/src/Popmenu.hpp new file mode 100644 index 0000000..a61619b --- /dev/null +++ b/src/Popmenu.hpp @@ -0,0 +1,40 @@ +/* + * Copyright (C) 2026 Wasted Audio + * SPDX-License-Identifier: ISC +*/ + +#pragma once + +#include "NanoVG.hpp" +#include "nanovg.h" + +#include "ExtraEventHandlers.hpp" +#include "Label.hpp" +#include "PDWidget.hpp" + +START_NAMESPACE_DISTRHO + +class PDPopmenu : public PDWidget, + public PDPopmenuEventHandler +{ +public: + explicit PDPopmenu(NanoSubWidget* parent, PDPopmenuEventHandler::Callback* cb); + + void setColors(NVGcolor bgColor, NVGcolor fgColor); + void setOptions(std::vector options); + void setFontSize(float size); + +protected: + bool onMouse(const MouseEvent &ev) override; + void onNanoDisplay() override; + +private: + NVGcolor fgColor; + NVGcolor bgColor; + float fontSize; + std::vector options; + + DISTRHO_LEAK_DETECTOR(PDPopmenu) +}; + +END_NAMESPACE_DISTRHO From cbf7e07b82121f7f87761c8792733a16f1b00128 Mon Sep 17 00:00:00 2001 From: dreamer Date: Sun, 12 Jul 2026 12:01:47 +0200 Subject: [PATCH 2/5] attribute JUCE utils as separate module --- pdvg.hpp | 1 + src/Common.hpp | 48 ++++++----------------------------------------- src/Jutils.hpp | 50 +++++++++++++++++++++++++++++++++++++++++++++++++ src/Popmenu.cpp | 17 +++++++++-------- 4 files changed, 66 insertions(+), 50 deletions(-) create mode 100644 src/Jutils.hpp diff --git a/pdvg.hpp b/pdvg.hpp index 01871fc..b93f158 100644 --- a/pdvg.hpp +++ b/pdvg.hpp @@ -5,6 +5,7 @@ #include "src/Bang.hpp" #include "src/Canvas.hpp" +#include "src/Jutils.hpp" #include "src/Common.hpp" #include "src/Comment.hpp" #include "src/DragNum.hpp" diff --git a/src/Common.hpp b/src/Common.hpp index 750b724..1b1c50e 100644 --- a/src/Common.hpp +++ b/src/Common.hpp @@ -9,6 +9,7 @@ #include #include "nanovg.h" #include "Widget.hpp" +#include "Jutils.hpp" START_NAMESPACE_DISTRHO @@ -84,10 +85,13 @@ static Rectangle subtractBorder(Rectangle r, Border border) static Rectangle removeFromRight(Rectangle r, float amount) { + float amountRemove = jmin(amount, r.getWidth()); + r.setWidth(r.getWidth() - amountRemove); + return Rectangle( - r.getX(), + r.getX() + r.getWidth() - amountRemove, r.getY(), - r.getWidth() - amount, + amountRemove, r.getHeight() ); } @@ -117,46 +121,6 @@ static float valToPropOfLen(float const value, float const length) return value / length; } - -/** Some utility functions taken from JUCE ISC code */ - -/** Returns the smaller of two values. */ -template -constexpr Type jmin (Type a, Type b) { return b < a ? b : a; } - -/** Returns the larger of two values. */ -template -constexpr Type jmax (Type a, Type b) { return a < b ? b : a; } - -/** Returns the larger of three values. */ -template -constexpr Type jmax (Type a, Type b, Type c) { return a < b ? (b < c ? c : b) : (a < c ? c : a); } - -/** Remaps a normalised value (between 0 and 1) to a target range. - This effectively returns (targetRangeMin + value0To1 * (targetRangeMax - targetRangeMin)). -*/ -template -constexpr Type jmap (Type value0To1, Type targetRangeMin, Type targetRangeMax) -{ - return targetRangeMin + value0To1 * (targetRangeMax - targetRangeMin); -} - -/** Remaps a value from a source range to a target range. */ -template -Type jmap (Type sourceValue, Type sourceRangeMin, Type sourceRangeMax, Type targetRangeMin, Type targetRangeMax) -{ - return targetRangeMin + ((targetRangeMax - targetRangeMin) * (sourceValue - sourceRangeMin)) / (sourceRangeMax - sourceRangeMin); -} - -/** Converts an angle in degrees to radians. */ -template -constexpr FloatType degreesToRadians (FloatType degrees) noexcept { return degrees * (NVG_PI / FloatType (180)); } - -/** Converts an angle in radians to degrees. */ -template -constexpr FloatType radiansToDegrees (FloatType radians) noexcept { return radians * (FloatType (180) / NVG_PI); } - - static float getColorBrightness(NVGcolor c) { float brightness = 0.0f; diff --git a/src/Jutils.hpp b/src/Jutils.hpp new file mode 100644 index 0000000..6f380dd --- /dev/null +++ b/src/Jutils.hpp @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2022 - Raw Material Software Limited + * SPDX-License-Identifier: ISC +*/ + +#pragma once + +#include "nanovg.h" + +START_NAMESPACE_DISTRHO + +/** Some utility functions taken from JUCE ISC code */ + +/** Returns the smaller of two values. */ +template +constexpr Type jmin (Type a, Type b) { return b < a ? b : a; } + +/** Returns the larger of two values. */ +template +constexpr Type jmax (Type a, Type b) { return a < b ? b : a; } + +/** Returns the larger of three values. */ +template +constexpr Type jmax (Type a, Type b, Type c) { return a < b ? (b < c ? c : b) : (a < c ? c : a); } + +/** Remaps a normalised value (between 0 and 1) to a target range. + This effectively returns (targetRangeMin + value0To1 * (targetRangeMax - targetRangeMin)). +*/ +template +constexpr Type jmap (Type value0To1, Type targetRangeMin, Type targetRangeMax) +{ + return targetRangeMin + value0To1 * (targetRangeMax - targetRangeMin); +} + +/** Remaps a value from a source range to a target range. */ +template +Type jmap (Type sourceValue, Type sourceRangeMin, Type sourceRangeMax, Type targetRangeMin, Type targetRangeMax) +{ + return targetRangeMin + ((targetRangeMax - targetRangeMin) * (sourceValue - sourceRangeMin)) / (sourceRangeMax - sourceRangeMin); +} + +/** Converts an angle in degrees to radians. */ +template +constexpr FloatType degreesToRadians (FloatType degrees) noexcept { return degrees * (NVG_PI / FloatType (180)); } + +/** Converts an angle in radians to degrees. */ +template +constexpr FloatType radiansToDegrees (FloatType radians) noexcept { return radians * (FloatType (180) / NVG_PI); } + +END_NAMESPACE_DISTRHO diff --git a/src/Popmenu.cpp b/src/Popmenu.cpp index ab98487..1e33425 100644 --- a/src/Popmenu.cpp +++ b/src/Popmenu.cpp @@ -27,26 +27,27 @@ void PDPopmenu::onNanoDisplay() drawRoundedRect(nvg, b.getX(), b.getY(), b.getWidth(), b.getHeight(), bgColor, Colors::outColor, Corners::objectCornerRadius); - // auto textBounds = getLocalBounds().reduced(2).translated(2, 0); auto textBounds = translateRectangle(reduceRectangle(b, 2), 2, 0); // if (!textBounds.isEmpty()) { // textRenderer.renderText(nvg, textBounds.toFloat(), getImageScale()); // } - // auto const triangleBounds = b.removeFromRight(20).withSizeKeepingCentre(20, std::min(getHeight(), 12)); auto const triangleBounds = resizeCentered(removeFromRight(b, 20), 20, std::min((int)b.getHeight(), 12)); + auto const triangleBoundsCenterX = triangleBounds.getX() + triangleBounds.getWidth() / 2.0f; + auto const triangleBoundsBottom = triangleBounds.getY() + triangleBounds.getHeight(); + nvgStrokeColor(nvg, fgColor); nvgBeginPath(nvg); - nvgMoveTo(nvg, (triangleBounds.getX() - triangleBounds.getWidth() / 2.0f) - 3 * scaleFactor, triangleBounds.getY() + 3 * scaleFactor); - nvgLineTo(nvg, (triangleBounds.getX() - triangleBounds.getWidth() / 2.0f), triangleBounds.getY()); - nvgLineTo(nvg, (triangleBounds.getX() - triangleBounds.getWidth() / 2.0f) + 3 * scaleFactor, triangleBounds.getY() + 3 * scaleFactor); + nvgMoveTo(nvg, triangleBoundsCenterX - 3 * scaleFactor, triangleBounds.getY() + 3 * scaleFactor); + nvgLineTo(nvg, triangleBoundsCenterX, triangleBounds.getY()); + nvgLineTo(nvg, triangleBoundsCenterX + 3 * scaleFactor, triangleBounds.getY() + 3 * scaleFactor); nvgStroke(nvg); nvgBeginPath(nvg); - nvgMoveTo(nvg, (triangleBounds.getX() - triangleBounds.getWidth() / 2.0f) - 3 * scaleFactor, triangleBounds.getY() - triangleBounds.getHeight() - 3 * scaleFactor); - nvgLineTo(nvg, (triangleBounds.getX() - triangleBounds.getWidth() / 2.0f), triangleBounds.getY() - triangleBounds.getHeight()); - nvgLineTo(nvg, (triangleBounds.getX() - triangleBounds.getWidth() / 2.0f) + 3 * scaleFactor, triangleBounds.getY() - triangleBounds.getHeight() - 3 * scaleFactor); + nvgMoveTo(nvg, triangleBoundsCenterX - 3 * scaleFactor, triangleBoundsBottom - 3 * scaleFactor); + nvgLineTo(nvg, triangleBoundsCenterX, triangleBoundsBottom); + nvgLineTo(nvg, triangleBoundsCenterX + 3 * scaleFactor, triangleBoundsBottom - 3 * scaleFactor); nvgStroke(nvg); } From 319ad9f08582c1c1a4d22a9f3d9569fb649943d9 Mon Sep 17 00:00:00 2001 From: dreamer Date: Sun, 12 Jul 2026 12:20:33 +0200 Subject: [PATCH 3/5] add noSelectLabel --- src/Popmenu.cpp | 5 +++++ src/Popmenu.hpp | 2 ++ 2 files changed, 7 insertions(+) diff --git a/src/Popmenu.cpp b/src/Popmenu.cpp index 1e33425..92f8b19 100644 --- a/src/Popmenu.cpp +++ b/src/Popmenu.cpp @@ -62,6 +62,11 @@ void PDPopmenu::setColors(NVGcolor bgColor, NVGcolor fgColor) this->fgColor = fgColor; } +void PDPopmenu::setNoSelectLabel(std::string label) +{ + this->noSelectLabel = label; +} + void PDPopmenu::setOptions(std::vector options) { this->options = options; diff --git a/src/Popmenu.hpp b/src/Popmenu.hpp index a61619b..2dac998 100644 --- a/src/Popmenu.hpp +++ b/src/Popmenu.hpp @@ -21,6 +21,7 @@ class PDPopmenu : public PDWidget, explicit PDPopmenu(NanoSubWidget* parent, PDPopmenuEventHandler::Callback* cb); void setColors(NVGcolor bgColor, NVGcolor fgColor); + void setNoSelectLabel(std::string label); void setOptions(std::vector options); void setFontSize(float size); @@ -32,6 +33,7 @@ class PDPopmenu : public PDWidget, NVGcolor fgColor; NVGcolor bgColor; float fontSize; + std::string noSelectLabel; std::vector options; DISTRHO_LEAK_DETECTOR(PDPopmenu) From d279eae635eb24c88455f7e1f4296b6497c1777d Mon Sep 17 00:00:00 2001 From: dreamer Date: Sun, 12 Jul 2026 14:27:24 +0200 Subject: [PATCH 4/5] render text in object --- src/Popmenu.cpp | 32 +++++++++++++++++++++++++------- src/Popmenu.hpp | 7 +++++-- 2 files changed, 30 insertions(+), 9 deletions(-) diff --git a/src/Popmenu.cpp b/src/Popmenu.cpp index 4e62ccc..19490c1 100644 --- a/src/Popmenu.cpp +++ b/src/Popmenu.cpp @@ -7,7 +7,7 @@ #include "Common.hpp" #include "Popmenu.hpp" - +#include "Fonts/InterRegular.hpp" START_NAMESPACE_DISTRHO @@ -16,6 +16,26 @@ PDPopmenu::PDPopmenu(NanoSubWidget* parent, PDPopmenuEventHandler::Callback* cb) PDPopmenuEventHandler(this) { PDPopmenuEventHandler::setCallback(cb); + + using namespace InterRegular; + NanoVG:FontId interId = createFontFromMemory("inter", (const uchar *)InterRegularData, InterRegularDataSize, 0); + fFontId = interId; +} + +void PDPopmenu::renderText(NVGcontext* nvg, DGL::Rectangle bounds) +{ + beginPath(); + + auto fAlign = NVG_ALIGN_TOP; + auto value = (int) getValue(); + auto fText = options[value].c_str(); + + fontFaceId(fFontId); + fontSize(fFontSize * 1.5f); + fillColor(Colors::cnvTextColor); + textAlign(fAlign); + text(bounds.getX(), bounds.getY(), fText, NULL); + closePath(); } void PDPopmenu::onNanoDisplay() @@ -27,10 +47,8 @@ void PDPopmenu::onNanoDisplay() drawRoundedRect(nvg, b.getX(), b.getY(), b.getWidth(), b.getHeight(), bgColor, Colors::outColor, Corners::objectCornerRadius); - auto textBounds = translateRectangle(reduceRectangle(b, 2), 2, 0); - // if (!textBounds.isEmpty()) { - // textRenderer.renderText(nvg, textBounds.toFloat(), getImageScale()); - // } + auto textBounds = translateRectangle(reduceRectangle(b, 2 * scaleFactor), 2 * scaleFactor, 0); + renderText(nvg, textBounds); auto const triangleBounds = resizeCentered(removeFromRight(b, 20), 20, std::min((int)b.getHeight(), 12)); @@ -72,9 +90,9 @@ void PDPopmenu::setOptions(std::vector options) this->options = options; } -void PDPopmenu::setFontSize(float fontSize) +void PDPopmenu::setFontSize(int fontSize) { - this->fontSize = fontSize; + this->fFontSize = fontSize; } END_NAMESPACE_DISTRHO diff --git a/src/Popmenu.hpp b/src/Popmenu.hpp index 2dac998..4d8089d 100644 --- a/src/Popmenu.hpp +++ b/src/Popmenu.hpp @@ -23,19 +23,22 @@ class PDPopmenu : public PDWidget, void setColors(NVGcolor bgColor, NVGcolor fgColor); void setNoSelectLabel(std::string label); void setOptions(std::vector options); - void setFontSize(float size); + void setFontSize(int size); protected: bool onMouse(const MouseEvent &ev) override; + void renderText(NVGcontext* nvg, DGL::Rectangle bounds); void onNanoDisplay() override; private: NVGcolor fgColor; NVGcolor bgColor; - float fontSize; + int fFontSize; std::string noSelectLabel; std::vector options; + NanoVG::FontId fFontId; + DISTRHO_LEAK_DETECTOR(PDPopmenu) }; From d6b3d5d92f948fb996786caed3b7864f5704ebc5 Mon Sep 17 00:00:00 2001 From: dreamer Date: Sun, 12 Jul 2026 14:31:26 +0200 Subject: [PATCH 5/5] add motion handler --- src/ExtraEventHandlers.cpp | 18 ++++++++++-------- src/ExtraEventHandlers.hpp | 1 + src/Popmenu.cpp | 5 +++++ src/Popmenu.hpp | 1 + 4 files changed, 17 insertions(+), 8 deletions(-) diff --git a/src/ExtraEventHandlers.cpp b/src/ExtraEventHandlers.cpp index 7694f65..7249c68 100644 --- a/src/ExtraEventHandlers.cpp +++ b/src/ExtraEventHandlers.cpp @@ -1698,19 +1698,16 @@ struct PDPopmenuEventHandler::PrivateData PDWidget* pdWidget = dynamic_cast(widget); if (ev.press && pdWidget->contains(ev.pos)) { - // if (callback != nullptr) - // { - // try - // { - // callback->popmenuClicked(widget, value); - // } - // DISTRHO_SAFE_EXCEPTION("PDPopmenuEventHandler::mouseEvent"); - // } return true; } return false; } + bool motionEvent(const Widget::MotionEvent &ev) + { + return false; + } + bool setValue(const uint value2, const bool sendCallback) { if (value != value2) @@ -1774,6 +1771,11 @@ bool PDPopmenuEventHandler::mouseEvent(const Widget::MouseEvent &ev) return pData->mouseEvent(ev); } +bool PDPopmenuEventHandler::motionEvent(const Widget::MotionEvent &ev) +{ + return pData->motionEvent(ev); +} + // end popmenu END_NAMESPACE_DGL diff --git a/src/ExtraEventHandlers.hpp b/src/ExtraEventHandlers.hpp index 2e7c664..35e1b3d 100644 --- a/src/ExtraEventHandlers.hpp +++ b/src/ExtraEventHandlers.hpp @@ -338,6 +338,7 @@ class PDPopmenuEventHandler void setCallback(Callback *callback) noexcept; bool mouseEvent(const Widget::MouseEvent &ev); + bool motionEvent(const Widget::MotionEvent &ev); protected: private: diff --git a/src/Popmenu.cpp b/src/Popmenu.cpp index 19490c1..ac03bc0 100644 --- a/src/Popmenu.cpp +++ b/src/Popmenu.cpp @@ -74,6 +74,11 @@ bool PDPopmenu::onMouse(const MouseEvent &ev) return PDPopmenuEventHandler::mouseEvent(ev); } +bool PDPopmenu::onMotion(const MotionEvent &ev) +{ + return PDPopmenuEventHandler::motionEvent(ev); +} + void PDPopmenu::setColors(NVGcolor bgColor, NVGcolor fgColor) { this->bgColor = bgColor; diff --git a/src/Popmenu.hpp b/src/Popmenu.hpp index 4d8089d..a030b70 100644 --- a/src/Popmenu.hpp +++ b/src/Popmenu.hpp @@ -27,6 +27,7 @@ class PDPopmenu : public PDWidget, protected: bool onMouse(const MouseEvent &ev) override; + bool onMotion(const MotionEvent &ev) override; void renderText(NVGcontext* nvg, DGL::Rectangle bounds); void onNanoDisplay() override;