| @@ -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; | |||
| } | |||