Browse Source

adding push function with shift key

pull/1066/head
Frank Buss 6 years ago
parent
commit
7c17ad3f77
3 changed files with 63 additions and 2 deletions
  1. +2
    -0
      include/app.hpp
  2. +17
    -2
      src/app/ModuleWidget.cpp
  3. +44
    -0
      src/app/RackWidget.cpp

+ 2
- 0
include/app.hpp View File

@@ -185,6 +185,8 @@ struct RackWidget : OpaqueWidget {
bool requestModuleBox(ModuleWidget *m, Rect box);
/** Moves a module to the closest non-colliding position */
bool requestModuleBoxNearest(ModuleWidget *m, Rect box);
/** Moves a module by one grid unit, pushing other modules recursively. If pushLeft is true, the push direction is left, otherwise right */
bool pushModule(ModuleWidget *m, bool pushLeft);

void step() override;
void draw(NVGcontext *vg) override;


+ 17
- 2
src/app/ModuleWidget.cpp View File

@@ -424,7 +424,22 @@ void ModuleWidget::onDragMove(EventDragMove &e) {
if (!gRackWidget->lockModules) {
Rect newBox = box;
newBox.pos = gRackWidget->lastMousePos.minus(dragPos);
gRackWidget->requestModuleBoxNearest(this, newBox);
if (windowIsShiftPressed()) {
// push left or right in grid steps
float dx = newBox.pos.x - box.pos.x;
int steps = int(dx / RACK_GRID_WIDTH);
while (steps) {
if (steps < 0) {
gRackWidget->pushModule(this, true);
steps++;
} else {
gRackWidget->pushModule(this, false);
steps--;
}
}
} else {
gRackWidget->requestModuleBoxNearest(this, newBox);
}
}
}

@@ -559,4 +574,4 @@ Menu *ModuleWidget::createContextMenu() {
}


} // namespace rack
} // namespace rack

+ 44
- 0
src/app/RackWidget.cpp View File

@@ -470,6 +470,50 @@ bool RackWidget::requestModuleBoxNearest(ModuleWidget *m, Rect box) {
return false;
}

bool RackWidget::pushModule(ModuleWidget *m, bool pushLeft) {
// calculate desired position
Rect newBox = m->box;
if (pushLeft) {
newBox.pos.x -= RACK_GRID_WIDTH;
} else {
newBox.pos.x += RACK_GRID_WIDTH;
}
// can't be pushed over the left border
if (newBox.pos.x < 0.0f) return false;
// get intersection widget after moving
Widget *iw = NULL;
int count = 0;
for (Widget *child2 : moduleContainer->children) {
if (m == child2) continue;
if (newBox.intersects(child2->box)) {
iw = child2;
count++;
}
}
// if a module is higher than one grid unit, it can push only one module, otherwise we would need a rollback,
// if e.g. one of two modules can't be pushed
if (count > 1) return false;
// if there is any intersected widget, try to push it recursively
if (iw) {
ModuleWidget *w2 = dynamic_cast<ModuleWidget*>(iw);
if (pushModule(w2, pushLeft)) {
// if successful, set new position for this widget
m->box = newBox;
return true;
} else {
return false;
}
} else {
// no intersection, just set the new position
m->box = newBox;
return true;
}
}

void RackWidget::step() {
// Expand size to fit modules
Vec moduleSize = moduleContainer->getChildrenBoundingBox().getBottomRight();


Loading…
Cancel
Save