@@ -21,7 +21,6 @@ struct ModuleWidget : widget::OpaqueWidget { | |||
/** Owned. */ | |||
engine::Module* module = NULL; | |||
widget::Widget* panel = NULL; | |||
/** Note that the indexes of these vectors do not necessarily correspond with the indexes of `Module::params` etc. | |||
*/ | |||
std::vector<ParamWidget*> params; | |||
@@ -43,11 +42,16 @@ struct ModuleWidget : widget::OpaqueWidget { | |||
void onDragEnd(const event::DragEnd& e) override; | |||
void onDragMove(const event::DragMove& e) override; | |||
/** Associates this ModuleWidget with the Module | |||
Transfers ownership | |||
/** Associates this ModuleWidget with the Module. | |||
Transfers ownership. | |||
*/ | |||
void setModule(engine::Module* module); | |||
void setPanel(std::shared_ptr<Svg> svg); | |||
/** Sets the panel and sets the size of the ModuleWidget from the panel. | |||
Transfers ownership. | |||
*/ | |||
void setPanel(widget::Widget* panel); | |||
/** Use `setPanel(createPanel(svg))` instead. */ | |||
DEPRECATED void setPanel(std::shared_ptr<Svg> svg); | |||
/** Convenience functions for adding special widgets (calls addChild()) */ | |||
void addParam(ParamWidget* param); | |||
@@ -15,9 +15,16 @@ struct PanelBorder : widget::TransparentWidget { | |||
}; | |||
struct SvgPanel : widget::FramebufferWidget { | |||
struct SvgPanel : widget::Widget { | |||
widget::FramebufferWidget* fb; | |||
widget::SvgWidget* sw; | |||
PanelBorder* panelBorder; | |||
std::shared_ptr<Svg> svg; | |||
std::shared_ptr<Svg> darkSvg; | |||
SvgPanel(); | |||
void step() override; | |||
void setBackground(std::shared_ptr<Svg> svg); | |||
void setBackground(std::shared_ptr<Svg> svg, std::shared_ptr<Svg> darkSvg = NULL); | |||
}; | |||
@@ -8,6 +8,7 @@ | |||
#include <app/ParamWidget.hpp> | |||
#include <app/ModuleLightWidget.hpp> | |||
#include <app/Scene.hpp> | |||
#include <app/SvgPanel.hpp> | |||
#include <engine/Module.hpp> | |||
#include <engine/ParamQuantity.hpp> | |||
#include <app.hpp> | |||
@@ -55,6 +56,16 @@ TWidget* createWidgetCentered(math::Vec pos) { | |||
return o; | |||
} | |||
inline app::SvgPanel* createPanel(std::string svgPath, std::string darkSvgPath = "") { | |||
app::SvgPanel* panel = new app::SvgPanel; | |||
std::shared_ptr<Svg> svg = APP->window->loadSvg(svgPath); | |||
std::shared_ptr<Svg> darkSvg; | |||
if (darkSvgPath != "") | |||
darkSvg = APP->window->loadSvg(darkSvgPath); | |||
panel->setBackground(svg, darkSvg); | |||
return panel; | |||
} | |||
template <class TParamWidget> | |||
TParamWidget* createParam(math::Vec pos, engine::Module* module, int paramId) { | |||
TParamWidget* o = new TParamWidget; | |||
@@ -283,6 +283,8 @@ struct ModuleWidget::Internal { | |||
Set by RackWidget::updateModuleOldPositions() when *any* module begins dragging, since force-dragging can move other modules around. | |||
*/ | |||
math::Vec oldPos; | |||
widget::Widget* panel = NULL; | |||
}; | |||
@@ -472,22 +474,26 @@ void ModuleWidget::setModule(engine::Module* module) { | |||
this->module = module; | |||
} | |||
void ModuleWidget::setPanel(std::shared_ptr<Svg> svg) { | |||
void ModuleWidget::setPanel(widget::Widget* panel) { | |||
// Remove existing panel | |||
if (internal->panel) { | |||
removeChild(internal->panel); | |||
delete internal->panel; | |||
internal->panel = NULL; | |||
} | |||
if (panel) { | |||
removeChild(panel); | |||
delete panel; | |||
panel = NULL; | |||
addChildBottom(panel); | |||
internal->panel = panel; | |||
box.size.x = std::round(panel->box.size.x / RACK_GRID_WIDTH) * RACK_GRID_WIDTH; | |||
} | |||
} | |||
void ModuleWidget::setPanel(std::shared_ptr<Svg> svg) { | |||
// Create SvgPanel | |||
SvgPanel* svgPanel = new SvgPanel; | |||
svgPanel->setBackground(svg); | |||
panel = svgPanel; | |||
addChildBottom(panel); | |||
// Set ModuleWidget size based on panel | |||
box.size.x = std::round(panel->box.size.x / RACK_GRID_WIDTH) * RACK_GRID_WIDTH; | |||
SvgPanel* panel = new SvgPanel; | |||
panel->setBackground(svg); | |||
setPanel(panel); | |||
} | |||
void ModuleWidget::addParam(ParamWidget* param) { | |||
@@ -1,4 +1,5 @@ | |||
#include <app/SvgPanel.hpp> | |||
#include <settings.hpp> | |||
namespace rack { | |||
@@ -15,25 +16,43 @@ void PanelBorder::draw(const DrawArgs& args) { | |||
} | |||
SvgPanel::SvgPanel() { | |||
fb = new widget::FramebufferWidget; | |||
addChild(fb); | |||
sw = new widget::SvgWidget; | |||
fb->addChild(sw); | |||
panelBorder = new PanelBorder; | |||
fb->addChild(panelBorder); | |||
} | |||
void SvgPanel::step() { | |||
if (math::isNear(APP->window->pixelRatio, 1.0)) { | |||
if (APP->window->pixelRatio < 2.0) { | |||
// Small details draw poorly at low DPI, so oversample when drawing to the framebuffer | |||
oversample = 2.0; | |||
fb->oversample = 2.0; | |||
} | |||
FramebufferWidget::step(); | |||
} | |||
void SvgPanel::setBackground(std::shared_ptr<Svg> svg) { | |||
widget::SvgWidget* sw = new widget::SvgWidget; | |||
sw->setSvg(svg); | |||
addChild(sw); | |||
std::shared_ptr<Svg> svg = this->svg; | |||
if (settings::isDarkMode() && this->darkSvg) | |||
svg = this->darkSvg; | |||
if (sw->svg != svg) { | |||
sw->setSvg(svg); | |||
fb->dirty = true; | |||
} | |||
// Set size | |||
box.size = sw->box.size.div(RACK_GRID_SIZE).round().mult(RACK_GRID_SIZE); | |||
Widget::step(); | |||
} | |||
PanelBorder* pb = new PanelBorder; | |||
pb->box.size = box.size; | |||
addChild(pb); | |||
void SvgPanel::setBackground(std::shared_ptr<Svg> svg, std::shared_ptr<Svg> darkSvg) { | |||
this->svg = svg; | |||
this->darkSvg = darkSvg; | |||
sw->setSvg(svg); | |||
fb->box.size = sw->box.size.div(RACK_GRID_SIZE).round().mult(RACK_GRID_SIZE); | |||
panelBorder->box.size = fb->box.size; | |||
box.size = fb->box.size; | |||
} | |||