diff --git a/include/ui/ScrollWidget.hpp b/include/ui/ScrollWidget.hpp index 63c3c4c9..2f7ed2a2 100644 --- a/include/ui/ScrollWidget.hpp +++ b/include/ui/ScrollWidget.hpp @@ -23,6 +23,9 @@ struct ScrollWidget : widget::OpaqueWidget { ScrollWidget(); ~ScrollWidget(); + math::Vec getScrollOffset() { + return offset; + } void scrollTo(math::Rect r); /** Returns the bound of allowed `offset` values in pixels. */ math::Rect getContainerOffsetBound(); diff --git a/include/widget/Widget.hpp b/include/widget/Widget.hpp index 68c93fcf..0e9ef0f2 100644 --- a/include/widget/Widget.hpp +++ b/include/widget/Widget.hpp @@ -85,7 +85,7 @@ struct Widget : WeakBase { } /** Returns a subset of the given Rect bounded by the box of this widget and all ancestors. */ - virtual math::Rect getViewport(math::Rect r); + virtual math::Rect getViewport(math::Rect r = math::Rect::inf()); template T* getAncestorOfType() { diff --git a/src/app/RackWidget.cpp b/src/app/RackWidget.cpp index 2fb361ad..5075fe19 100644 --- a/src/app/RackWidget.cpp +++ b/src/app/RackWidget.cpp @@ -401,6 +401,8 @@ static PasteJsonResult RackWidget_pasteJson(RackWidget* that, json_t* rootJ, his that->deselectAll(); std::map newModules; + math::Vec posMin(INFINITY, INFINITY); + math::Vec posMax(-INFINITY, -INFINITY); // modules json_t* modulesJ = json_object_get(rootJ, "modules"); @@ -435,8 +437,9 @@ static PasteJsonResult RackWidget_pasteJson(RackWidget* that, json_t* rootJ, his double x = 0.0, y = 0.0; json_unpack(posJ, "[F, F]", &x, &y); math::Vec pos = math::Vec(x, y); - pos = pos.mult(RACK_GRID_SIZE); - mw->box.pos = pos.plus(RACK_OFFSET); + mw->box.pos = pos * RACK_GRID_SIZE + RACK_OFFSET; + posMin = posMin.min(mw->box.getTopLeft()); + posMax = posMax.max(mw->box.getBottomRight()); that->internal->moduleContainer->addChild(mw); that->select(mw); @@ -444,6 +447,16 @@ static PasteJsonResult RackWidget_pasteJson(RackWidget* that, json_t* rootJ, his newModules[id] = mw; } + // Adjust center of selection to appear at center of rack view + math::Vec posCenter = (posMin + posMax) / 2; + math::Vec rackCenter = APP->scene->rack->getViewport().getCenter(); + math::Vec posDelta = ((rackCenter - posCenter) / RACK_GRID_SIZE).round() * RACK_GRID_SIZE; + + for (auto pair : newModules) { + ModuleWidget* mw = pair.second; + mw->box.pos += posDelta; + } + // This calls updateExpanders() that->setSelectionPosNearest(math::Vec(0, 0));