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