@@ -21,7 +21,6 @@ struct ModuleWidget : widget::OpaqueWidget { | |||||
/** Owned. */ | /** Owned. */ | ||||
engine::Module* module = NULL; | 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. | /** Note that the indexes of these vectors do not necessarily correspond with the indexes of `Module::params` etc. | ||||
*/ | */ | ||||
std::vector<ParamWidget*> params; | std::vector<ParamWidget*> params; | ||||
@@ -43,11 +42,16 @@ struct ModuleWidget : widget::OpaqueWidget { | |||||
void onDragEnd(const event::DragEnd& e) override; | void onDragEnd(const event::DragEnd& e) override; | ||||
void onDragMove(const event::DragMove& 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 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()) */ | /** Convenience functions for adding special widgets (calls addChild()) */ | ||||
void addParam(ParamWidget* param); | 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 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/ParamWidget.hpp> | ||||
#include <app/ModuleLightWidget.hpp> | #include <app/ModuleLightWidget.hpp> | ||||
#include <app/Scene.hpp> | #include <app/Scene.hpp> | ||||
#include <app/SvgPanel.hpp> | |||||
#include <engine/Module.hpp> | #include <engine/Module.hpp> | ||||
#include <engine/ParamQuantity.hpp> | #include <engine/ParamQuantity.hpp> | ||||
#include <app.hpp> | #include <app.hpp> | ||||
@@ -55,6 +56,16 @@ TWidget* createWidgetCentered(math::Vec pos) { | |||||
return o; | 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> | template <class TParamWidget> | ||||
TParamWidget* createParam(math::Vec pos, engine::Module* module, int paramId) { | TParamWidget* createParam(math::Vec pos, engine::Module* module, int paramId) { | ||||
TParamWidget* o = new TParamWidget; | 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. | Set by RackWidget::updateModuleOldPositions() when *any* module begins dragging, since force-dragging can move other modules around. | ||||
*/ | */ | ||||
math::Vec oldPos; | math::Vec oldPos; | ||||
widget::Widget* panel = NULL; | |||||
}; | }; | ||||
@@ -472,22 +474,26 @@ void ModuleWidget::setModule(engine::Module* module) { | |||||
this->module = module; | this->module = module; | ||||
} | } | ||||
void ModuleWidget::setPanel(std::shared_ptr<Svg> svg) { | |||||
void ModuleWidget::setPanel(widget::Widget* panel) { | |||||
// Remove existing panel | // Remove existing panel | ||||
if (internal->panel) { | |||||
removeChild(internal->panel); | |||||
delete internal->panel; | |||||
internal->panel = NULL; | |||||
} | |||||
if (panel) { | 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 | // 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) { | void ModuleWidget::addParam(ParamWidget* param) { | ||||
@@ -1,4 +1,5 @@ | |||||
#include <app/SvgPanel.hpp> | #include <app/SvgPanel.hpp> | ||||
#include <settings.hpp> | |||||
namespace rack { | 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() { | 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 | // 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; | |||||
} | } | ||||