Hello,
I’m in over my head a little bit and could use some guidance. Here’s a piece of code that creates a knob overlay (SVG), then layers a red square beneath it:
template <typename TBase = VoxglitchKnob>
struct TLargeKnob : TBase
{
TLargeKnob() {
this->svgFile = "large_knob_overlay.svg";
this->setSvg(APP->window->loadSvg(asset::plugin(pluginInstance, "res/components/" + this->svgFile)));
// Draw big red square behind svg layer
widget::SvgWidget* bg = new widget::SvgWidget;
bg->setSvg(APP->window->loadSvg(asset::plugin(pluginInstance, "res/components/redsquare.svg")));
this->fb->addChildBelow(bg, this->tw);
}
};
typedef TLargeKnob<> VoxglitchLargeKnob;
And here’s what it looks like:
So far, so good.
What I’m trying to achieve is to draw a PNG file behind the SVG, but I’m having no luck so far. I have created a widget for displaying PNG files that, by itself, works. It looks like this:
struct PNGPanel : TransparentWidget
{
std::string png_file_path;
float width;
float height;
float alpha = 1.0;
PNGPanel(std::string png_file_path, float width, float height, float alpha = 1.0)
{
this->png_file_path = png_file_path;
this->width = width;
this->height = height;
this->alpha = alpha;
}
void draw(const DrawArgs &args) override
{
std::shared_ptr<Image> img = APP->window->loadImage(asset::plugin(pluginInstance, this->png_file_path));
int temp_width, temp_height;
// Get the image size and store it in the width and height variables
nvgImageSize(args.vg, img->handle, &temp_width, &temp_height);
// Set the bounding box of the widget
box.size = mm2px(Vec(width, height));
// Paint the .png background
NVGpaint paint = nvgImagePattern(args.vg, 0.0, 0.0, box.size.x, box.size.y, 0.0, img->handle, this->alpha);
nvgBeginPath(args.vg);
nvgRect(args.vg, 0.0, 0.0, box.size.x, box.size.y);
nvgFillPaint(args.vg, paint);
nvgFill(args.vg);
Widget::draw(args);
}
};
I thought… OK, maybe I can simply use that as my bottom layer? So I tried this:
template <typename TBase = VoxglitchKnob>
struct TLargeKnob : TBase
{
TLargeKnob() {
// Same as before, set the SVG overlay for the knob
this->svgFile = "large_knob_overlay.svg";
this->setSvg(APP->window->loadSvg(asset::plugin(pluginInstance, "res/components/" + this->svgFile)));
// Try adding the PNGPanel to the background
PNGPanel* bg = new PNGPanel(asset::plugin(pluginInstance, "res/components/png/Big-Knob.png"), 4.0, 4.0);
this->fb->addChildBelow(bg, this->tw);
}
};
typedef TLargeKnob<> VoxglitchLargeKnob;
This doesn’t work. In fact, when I try this, neither the SVG nor the PNG are displayed.
Any suggestions?
-=-=-=-
Let me provide a bit of background. Here’s an example front panel:
I’m using a PNG file for the background of the module. The PNG file looks like this:
Each knob has an SVG overlay which gives the appearance of the knob being turned. For the large knob, this looks like:
However, having the background part of the knob “baked in” to the background means that each module needs their own a custom PNG background. That’s pretty inefficient, considering that the background texture is 90% similar across all modules.
Instead of that strategy, I’d like to have one, single, larger background PNG that all of the modules use. This would
- Reduce the size of the distribution file and
- Make it trivial to swap in a new background texture.
- Maybe be more efficient for VCV Rack? (I’m not 100% sure of that.)
I’m working on a new theme system, so I’m spending some extra time to make things flexible.
(Panel design by Chris Corrado.)