diff --git a/include/app/ModuleWidget.hpp b/include/app/ModuleWidget.hpp index 371793ee..7cab70ac 100644 --- a/include/app/ModuleWidget.hpp +++ b/include/app/ModuleWidget.hpp @@ -18,7 +18,7 @@ struct ModuleWidget : widget::OpaqueWidget { Internal* internal; plugin::Model* model = NULL; - /** Owned. */ + /** Owned */ engine::Module* module = NULL; ModuleWidget(); @@ -27,17 +27,15 @@ struct ModuleWidget : widget::OpaqueWidget { } ~ModuleWidget(); - plugin::Model* getModel() { - return model; - } - engine::Module* getModule() { - return module; - } + plugin::Model* getModel(); + void setModel(plugin::Model* model); + engine::Module* getModule(); /** Associates this ModuleWidget with the Module. Transfers ownership. */ void setModule(engine::Module* module); + /** Sets the panel and sets the size of the ModuleWidget from the panel. Transfers ownership. */ diff --git a/include/app/RackWidget.hpp b/include/app/RackWidget.hpp index 1e692c4b..9698c416 100644 --- a/include/app/RackWidget.hpp +++ b/include/app/RackWidget.hpp @@ -21,12 +21,7 @@ struct RackWidget : widget::OpaqueWidget { struct Internal; Internal* internal; - RailWidget* rail; - widget::Widget* moduleContainer; - widget::Widget* cableContainer; CableWidget* incompleteCable = NULL; - /** The last mouse position in the RackWidget */ - math::Vec mousePos; ParamWidget* touchedParam = NULL; int nextCableColorId = 0; @@ -45,6 +40,10 @@ struct RackWidget : widget::OpaqueWidget { // Rack methods + widget::Widget* getModuleContainer(); + widget::Widget* getCableContainer(); + math::Vec getMousePos(); + /** Completely clear the rack's modules and cables */ void clear(); void mergeJson(json_t* rootJ); diff --git a/include/helpers.hpp b/include/helpers.hpp index 3e5cdb32..9c45833a 100644 --- a/include/helpers.hpp +++ b/include/helpers.hpp @@ -34,7 +34,7 @@ plugin::Model* createModel(const std::string& slug) { tm = dynamic_cast(m); } app::ModuleWidget* mw = new TModuleWidget(tm); - mw->model = this; + mw->setModel(this); return mw; } }; diff --git a/src/app/CableWidget.cpp b/src/app/CableWidget.cpp index afbcdcb4..7efbe39d 100644 --- a/src/app/CableWidget.cpp +++ b/src/app/CableWidget.cpp @@ -193,7 +193,7 @@ math::Vec CableWidget::getInputPos() { return hoveredInputPort->getRelativeOffset(hoveredInputPort->box.zeroPos().getCenter(), APP->scene->rack); } else { - return APP->scene->rack->mousePos; + return APP->scene->rack->getMousePos(); } } @@ -205,7 +205,7 @@ math::Vec CableWidget::getOutputPos() { return hoveredOutputPort->getRelativeOffset(hoveredOutputPort->box.zeroPos().getCenter(), APP->scene->rack); } else { - return APP->scene->rack->mousePos; + return APP->scene->rack->getMousePos(); } } diff --git a/src/app/ModuleWidget.cpp b/src/app/ModuleWidget.cpp index 7fbb9f37..e6b7ac2d 100644 --- a/src/app/ModuleWidget.cpp +++ b/src/app/ModuleWidget.cpp @@ -434,6 +434,19 @@ ModuleWidget::~ModuleWidget() { delete internal; } +plugin::Model* ModuleWidget::getModel() { + return model; +} + +void ModuleWidget::setModel(plugin::Model* model) { + assert(!this->model); + this->model = model; +} + +engine::Module* ModuleWidget::getModule() { + return module; +} + void ModuleWidget::setModule(engine::Module* module) { if (this->module) { APP->engine->removeModule(this->module); @@ -720,7 +733,7 @@ void ModuleWidget::onDragEnd(const DragEndEvent& e) { void ModuleWidget::onDragMove(const DragMoveEvent& e) { if (e.button == GLFW_MOUSE_BUTTON_LEFT) { if (!settings::lockModules) { - math::Vec mousePos = APP->scene->rack->mousePos; + math::Vec mousePos = APP->scene->rack->getMousePos(); if (!internal->dragEnabled) { // Set dragRackPos on the first time after dragging @@ -1200,29 +1213,24 @@ void ModuleWidget::createContextMenu() { appendContextMenu(menu); } - math::Vec& ModuleWidget::dragOffset() { return internal->dragOffset; } - bool& ModuleWidget::dragEnabled() { return internal->dragEnabled; } - math::Vec& ModuleWidget::oldPos() { return internal->oldPos; } - engine::Module* ModuleWidget::releaseModule() { engine::Module* module = this->module; this->module = NULL; return module; } - bool& ModuleWidget::selected() { return internal->selected; } diff --git a/src/app/RackScrollWidget.cpp b/src/app/RackScrollWidget.cpp index 86b51998..aecc0cf4 100644 --- a/src/app/RackScrollWidget.cpp +++ b/src/app/RackScrollWidget.cpp @@ -56,7 +56,7 @@ void RackScrollWidget::step() { internal->zoomPos = box.size.div(2); // Compute module bounding box - math::Rect moduleBox = rackWidget->moduleContainer->getChildrenBoundingBox(); + math::Rect moduleBox = rackWidget->getModuleContainer()->getChildrenBoundingBox(); if (!moduleBox.size.isFinite()) moduleBox = math::Rect(RACK_OFFSET, math::Vec(0, 0)); diff --git a/src/app/RackWidget.cpp b/src/app/RackWidget.cpp index 08da83fc..8ae57f0a 100644 --- a/src/app/RackWidget.cpp +++ b/src/app/RackWidget.cpp @@ -73,6 +73,12 @@ struct CableContainer : widget::TransparentWidget { struct RackWidget::Internal { + RailWidget* rail = NULL; + widget::Widget* moduleContainer = NULL; + widget::Widget* cableContainer = NULL; + /** The last mouse position in the RackWidget */ + math::Vec mousePos; + bool selecting = false; math::Vec selectionStart; math::Vec selectionEnd; @@ -82,14 +88,14 @@ struct RackWidget::Internal { RackWidget::RackWidget() { internal = new Internal; - rail = new RailWidget; - addChild(rail); + internal->rail = new RailWidget; + addChild(internal->rail); - moduleContainer = new ModuleContainer; - addChild(moduleContainer); + internal->moduleContainer = new ModuleContainer; + addChild(internal->moduleContainer); - cableContainer = new CableContainer; - addChild(cableContainer); + internal->cableContainer = new CableContainer; + addChild(internal->cableContainer); } RackWidget::~RackWidget() { @@ -123,7 +129,7 @@ void RackWidget::draw(const DrawArgs& args) { void RackWidget::onHover(const HoverEvent& e) { // Set before calling children's onHover() - mousePos = e.pos; + internal->mousePos = e.pos; OpaqueWidget::onHover(e); } @@ -161,8 +167,8 @@ void RackWidget::onDragStart(const DragStartEvent& e) { // Deselect all modules updateModuleSelections(); internal->selecting = true; - internal->selectionStart = mousePos; - internal->selectionEnd = mousePos; + internal->selectionStart = internal->mousePos; + internal->selectionEnd = internal->mousePos; } } @@ -174,21 +180,33 @@ void RackWidget::onDragEnd(const DragEndEvent& e) { void RackWidget::onDragHover(const DragHoverEvent& e) { // Set before calling children's onDragHover() - mousePos = e.pos; + internal->mousePos = e.pos; if (internal->selecting) { - internal->selectionEnd = mousePos; + internal->selectionEnd = internal->mousePos; updateModuleSelections(); } OpaqueWidget::onDragHover(e); } +widget::Widget* RackWidget::getModuleContainer() { + return internal->moduleContainer; +} + +widget::Widget* RackWidget::getCableContainer() { + return internal->cableContainer; +} + +math::Vec RackWidget::getMousePos() { + return internal->mousePos; +} + void RackWidget::clear() { // This isn't required because removing all ModuleWidgets should remove all cables, but do it just in case. clearCables(); // Remove ModuleWidgets - std::list widgets = moduleContainer->children; + std::list widgets = internal->moduleContainer->children; for (widget::Widget* w : widgets) { ModuleWidget* moduleWidget = dynamic_cast(w); assert(moduleWidget); @@ -200,10 +218,10 @@ void RackWidget::clear() { void RackWidget::mergeJson(json_t* rootJ) { // Get module offset so modules are aligned to (0, 0) when the patch is loaded. math::Vec moduleOffset = math::Vec(INFINITY, INFINITY); - for (widget::Widget* w : moduleContainer->children) { + for (widget::Widget* w : internal->moduleContainer->children) { moduleOffset = moduleOffset.min(w->box.pos); } - if (moduleContainer->children.empty()) { + if (internal->moduleContainer->children.empty()) { moduleOffset = RACK_OFFSET; } @@ -392,14 +410,14 @@ void RackWidget::pastePresetClipboardAction() { } static void RackWidget_updateExpanders(RackWidget* that) { - for (widget::Widget* w : that->moduleContainer->children) { + for (widget::Widget* w : that->internal->moduleContainer->children) { math::Vec pLeft = w->box.pos.div(RACK_GRID_SIZE).round(); math::Vec pRight = w->box.getTopRight().div(RACK_GRID_SIZE).round(); ModuleWidget* mwLeft = NULL; ModuleWidget* mwRight = NULL; // Find adjacent modules - for (widget::Widget* w2 : that->moduleContainer->children) { + for (widget::Widget* w2 : that->internal->moduleContainer->children) { if (w2 == w) continue; @@ -433,7 +451,7 @@ void RackWidget::addModule(ModuleWidget* m) { if (m->box.size.y != RACK_GRID_HEIGHT) throw Exception("Module %s height is %g px, must be %g px", m->model->getFullName().c_str(), m->box.size.y, RACK_GRID_HEIGHT); - moduleContainer->addChild(m); + internal->moduleContainer->addChild(m); RackWidget_updateExpanders(this); } @@ -441,7 +459,7 @@ void RackWidget::addModule(ModuleWidget* m) { void RackWidget::addModuleAtMouse(ModuleWidget* mw) { assert(mw); // Move module nearest to the mouse position - math::Vec pos = mousePos.minus(mw->box.size.div(2)); + math::Vec pos = internal->mousePos.minus(mw->box.size.div(2)); setModulePosNearest(mw, pos); addModule(mw); } @@ -458,13 +476,13 @@ void RackWidget::removeModule(ModuleWidget* m) { m->disconnect(); // Remove module from ModuleContainer - moduleContainer->removeChild(m); + internal->moduleContainer->removeChild(m); } bool RackWidget::requestModulePos(ModuleWidget* mw, math::Vec pos) { // Check intersection with other modules math::Rect mwBox = math::Rect(pos, mw->box.size); - for (widget::Widget* w2 : moduleContainer->children) { + for (widget::Widget* w2 : internal->moduleContainer->children) { // Don't intersect with self if (mw == w2) continue; @@ -543,7 +561,7 @@ void RackWidget::setModulePosForce(ModuleWidget* mw, math::Vec pos) { // Collect modules to the left and right of `mw` std::set leftModules(cmp); std::set rightModules(cmp); - for (widget::Widget* w2 : moduleContainer->children) { + for (widget::Widget* w2 : internal->moduleContainer->children) { if (w2 == mw) continue; // Modules must be on the same row as `mw` @@ -585,7 +603,7 @@ void RackWidget::setModulePosForce(ModuleWidget* mw, math::Vec pos) { } ModuleWidget* RackWidget::getModule(int64_t moduleId) { - for (widget::Widget* w : moduleContainer->children) { + for (widget::Widget* w : internal->moduleContainer->children) { ModuleWidget* mw = dynamic_cast(w); assert(mw); if (mw->module->id == moduleId) @@ -595,12 +613,12 @@ ModuleWidget* RackWidget::getModule(int64_t moduleId) { } bool RackWidget::isEmpty() { - return moduleContainer->children.empty(); + return internal->moduleContainer->children.empty(); } void RackWidget::updateModuleOldPositions() { // Set all modules' oldPos field from their current position. - for (widget::Widget* w : moduleContainer->children) { + for (widget::Widget* w : internal->moduleContainer->children) { ModuleWidget* mw = dynamic_cast(w); assert(mw); mw->oldPos() = mw->box.pos; @@ -610,7 +628,7 @@ void RackWidget::updateModuleOldPositions() { history::ComplexAction* RackWidget::getModuleDragAction() { history::ComplexAction* h = new history::ComplexAction; - for (widget::Widget* w : moduleContainer->children) { + for (widget::Widget* w : internal->moduleContainer->children) { ModuleWidget* mw = dynamic_cast(w); assert(mw); // Create ModuleMove action if the module was moved. @@ -633,7 +651,7 @@ history::ComplexAction* RackWidget::getModuleDragAction() { void RackWidget::updateModuleSelections() { math::Rect selectionBox = math::Rect::fromCorners(internal->selectionStart, internal->selectionEnd); - for (widget::Widget* w : moduleContainer->children) { + for (widget::Widget* w : internal->moduleContainer->children) { ModuleWidget* mw = dynamic_cast(w); assert(mw); bool selected = internal->selecting && selectionBox.intersects(mw->box); @@ -643,7 +661,7 @@ void RackWidget::updateModuleSelections() { void RackWidget::clearCables() { incompleteCable = NULL; - cableContainer->clearChildren(); + internal->cableContainer->clearChildren(); } void RackWidget::clearCablesAction() { @@ -651,7 +669,7 @@ void RackWidget::clearCablesAction() { history::ComplexAction* complexAction = new history::ComplexAction; complexAction->name = "clear cables"; - for (widget::Widget* w : cableContainer->children) { + for (widget::Widget* w : internal->cableContainer->children) { CableWidget* cw = dynamic_cast(w); assert(cw); if (!cw->isComplete()) @@ -675,7 +693,7 @@ void RackWidget::clearCablesOnPort(PortWidget* port) { // Check if cable is connected to port if (cw == incompleteCable) { incompleteCable = NULL; - cableContainer->removeChild(cw); + internal->cableContainer->removeChild(cw); } else { removeCable(cw); @@ -686,22 +704,22 @@ void RackWidget::clearCablesOnPort(PortWidget* port) { void RackWidget::addCable(CableWidget* cw) { assert(cw->isComplete()); - cableContainer->addChild(cw); + internal->cableContainer->addChild(cw); } void RackWidget::removeCable(CableWidget* cw) { assert(cw->isComplete()); - cableContainer->removeChild(cw); + internal->cableContainer->removeChild(cw); } void RackWidget::setIncompleteCable(CableWidget* cw) { if (incompleteCable) { - cableContainer->removeChild(incompleteCable); + internal->cableContainer->removeChild(incompleteCable); delete incompleteCable; incompleteCable = NULL; } if (cw) { - cableContainer->addChild(cw); + internal->cableContainer->addChild(cw); incompleteCable = cw; } } @@ -711,13 +729,13 @@ CableWidget* RackWidget::releaseIncompleteCable() { return NULL; CableWidget* cw = incompleteCable; - cableContainer->removeChild(incompleteCable); + internal->cableContainer->removeChild(incompleteCable); incompleteCable = NULL; return cw; } CableWidget* RackWidget::getTopCable(PortWidget* port) { - for (auto it = cableContainer->children.rbegin(); it != cableContainer->children.rend(); it++) { + for (auto it = internal->cableContainer->children.rbegin(); it != internal->cableContainer->children.rend(); it++) { CableWidget* cw = dynamic_cast(*it); assert(cw); if (cw->inputPort == port || cw->outputPort == port) @@ -727,7 +745,7 @@ CableWidget* RackWidget::getTopCable(PortWidget* port) { } CableWidget* RackWidget::getCable(int64_t cableId) { - for (widget::Widget* w : cableContainer->children) { + for (widget::Widget* w : internal->cableContainer->children) { CableWidget* cw = dynamic_cast(w); assert(cw); if (!cw->cable) @@ -741,7 +759,7 @@ CableWidget* RackWidget::getCable(int64_t cableId) { std::list RackWidget::getCablesOnPort(PortWidget* port) { assert(port); std::list cws; - for (widget::Widget* w : cableContainer->children) { + for (widget::Widget* w : internal->cableContainer->children) { CableWidget* cw = dynamic_cast(w); assert(cw); if (cw->inputPort == port || cw->outputPort == port) { diff --git a/src/core/Blank.cpp b/src/core/Blank.cpp index c0d8fe92..a06ea074 100644 --- a/src/core/Blank.cpp +++ b/src/core/Blank.cpp @@ -68,7 +68,7 @@ struct ModuleResizeHandle : OpaqueWidget { if (e.button != GLFW_MOUSE_BUTTON_LEFT) return; - dragPos = APP->scene->rack->mousePos; + dragPos = APP->scene->rack->getMousePos(); ModuleWidget* mw = getAncestorOfType(); assert(mw); originalBox = mw->box; @@ -78,7 +78,7 @@ struct ModuleResizeHandle : OpaqueWidget { ModuleWidget* mw = getAncestorOfType(); assert(mw); - Vec newDragPos = APP->scene->rack->mousePos; + Vec newDragPos = APP->scene->rack->getMousePos(); float deltaX = newDragPos.x - dragPos.x; Rect newBox = originalBox; diff --git a/src/history.cpp b/src/history.cpp index 4510a330..89810270 100644 --- a/src/history.cpp +++ b/src/history.cpp @@ -43,13 +43,13 @@ ModuleAdd::~ModuleAdd() { void ModuleAdd::setModule(app::ModuleWidget* mw) { assert(mw); - model = mw->model; - assert(mw->module); - moduleId = mw->module->id; + model = mw->getModel(); + assert(mw->getModule()); + moduleId = mw->getModule()->id; pos = mw->box.pos; // ModuleAdd doesn't *really* need the state to be serialized, although ModuleRemove certainly does. // However, creating a module may give it a nondeterministic initial state for whatever reason, so serialize anyway. - moduleJ = APP->engine->moduleToJson(mw->module); + moduleJ = APP->engine->moduleToJson(mw->getModule()); } void ModuleAdd::undo() {