Browse Source

In RackWidget::setModulePosForce(), if module old position is to the left of the new position, shove other modules to the left instead of the right.

tags/v2.1.0
Andrew Belt 2 years ago
parent
commit
957350c9ff
1 changed files with 45 additions and 27 deletions
  1. +45
    -27
      src/app/RackWidget.cpp

+ 45
- 27
src/app/RackWidget.cpp View File

@@ -696,30 +696,31 @@ void RackWidget::setModulePosNearest(ModuleWidget* mw, math::Vec pos) {
}

void RackWidget::setModulePosForce(ModuleWidget* mw, math::Vec pos) {
mw->setPosition(pos.div(RACK_GRID_SIZE).round().mult(RACK_GRID_SIZE));
math::Rect newBox = mw->box;
newBox.pos = (pos / RACK_GRID_SIZE).round() * RACK_GRID_SIZE;

// Comparison of X coordinates
auto cmp = [&](const widget::Widget* a, const widget::Widget* b) {
return a->box.pos.x < b->box.pos.x;
};

// Collect modules to the left and right of `mw`
// Collect modules to the left and right of pos
std::set<widget::Widget*, decltype(cmp)> leftModules(cmp);
std::set<widget::Widget*, decltype(cmp)> rightModules(cmp);
for (widget::Widget* w2 : internal->moduleContainer->children) {
// Skip this module
if (w2 == mw)
continue;
// Reset position to old position
// Reset position to old position, including this module
auto it = internal->moduleOldPositions.find(w2);
if (it != internal->moduleOldPositions.end()) {
w2->box.pos = it->second;
}
// Modules must be on the same row as `mw`
if (w2->box.getTop() != mw->box.getTop())
// Skip this module
if (w2 == mw)
continue;
// Modules must be on the same row as pos
if (w2->box.getTop() != newBox.getTop())
continue;
// Insert into leftModules or rightModules
if (w2->box.getCenter().x < mw->box.getCenter().x)
if (w2->box.getCenter().x < newBox.getCenter().x)
leftModules.insert(w2);
else
rightModules.insert(w2);
@@ -729,35 +730,52 @@ void RackWidget::setModulePosForce(ModuleWidget* mw, math::Vec pos) {
widget::Widget* rightModule = rightModules.empty() ? NULL : *rightModules.begin();

if (leftModule) {
if (leftModule->box.getRight() > mw->box.getLeft()) {
mw->box.pos.x = leftModule->box.getRight();
// Place right of leftModule
if (leftModule->box.getRight() > newBox.getLeft()) {
newBox.pos.x = leftModule->box.getRight();
}
}
if (rightModule) {
if (mw->box.getRight() > rightModule->box.getLeft()) {
mw->box.pos.x = rightModule->box.getLeft() - mw->box.size.x;
// Place left of rightModule
if (newBox.getRight() > rightModule->box.getLeft()) {
newBox.pos.x = rightModule->box.getLeft() - newBox.size.x;
}
}
if (leftModule && rightModule) {
// If there isn't enough space between the last leftModule and first rightModule, place module to the right of the leftModule.
if (leftModule->box.getRight() + mw->box.getWidth() > rightModule->box.getLeft()) {
mw->box.pos.x = leftModule->box.getRight();

// Shove right modules
float xLimit = mw->box.getRight();
for (auto it = rightModules.begin(); it != rightModules.end(); it++) {
widget::Widget* w2 = *it;
math::Vec newPos = w2->box.pos;
newPos.x = xLimit;
newPos.x = std::round(newPos.x / RACK_GRID_WIDTH) * RACK_GRID_WIDTH;
if (w2->box.pos.x > newPos.x)
break;
w2->box.pos = newPos;
xLimit = w2->box.getRight();
if (leftModule->box.getRight() + newBox.getWidth() > rightModule->box.getLeft()) {
// If module old position is to the left of the new position, shove other modules to the left instead of the right.
if (mw->box.getTop() == newBox.getTop() && mw->box.getLeft() < newBox.getLeft()) {
newBox.pos.x = rightModule->box.getLeft() - newBox.size.x;

// Shove left modules
float xLeft = newBox.getLeft();
for (auto it = leftModules.rbegin(); it != leftModules.rend(); it++) {
widget::Widget* w2 = *it;
if (w2->box.getRight() <= xLeft)
break;
w2->box.pos.x = std::round((xLeft - w2->box.size.x) / RACK_GRID_WIDTH) * RACK_GRID_WIDTH;
xLeft = w2->box.getLeft();
}
}
else {
newBox.pos.x = leftModule->box.getRight();

// Shove right modules
float xRight = newBox.getRight();
for (auto it = rightModules.begin(); it != rightModules.end(); it++) {
widget::Widget* w2 = *it;
if (w2->box.getLeft() >= xRight)
break;
w2->box.pos.x = std::round(xRight / RACK_GRID_WIDTH) * RACK_GRID_WIDTH;
xRight = w2->box.getRight();
}
}
}
}

mw->box.pos = (newBox.pos / RACK_GRID_SIZE).round() * RACK_GRID_SIZE;

updateExpanders();
}



Loading…
Cancel
Save