Browse Source

Add basic module selection dragging.

tags/v2.0.0
Andrew Belt 3 years ago
parent
commit
5995391ef9
3 changed files with 52 additions and 29 deletions
  1. +1
    -0
      include/app/RackWidget.hpp
  2. +15
    -7
      src/app/ModuleWidget.cpp
  3. +36
    -22
      src/app/RackWidget.cpp

+ 1
- 0
include/app/RackWidget.hpp View File

@@ -78,6 +78,7 @@ struct RackWidget : widget::OpaqueWidget {
void disconnectSelectedModulesAction();
void bypassSelectedModulesAction();
void deleteSelectedModulesAction();
bool requestSelectedModulePos(math::Vec delta);

// Cable methods



+ 15
- 7
src/app/ModuleWidget.cpp View File

@@ -402,9 +402,10 @@ void ModuleWidget::onDragEnd(const DragEndEvent& e) {
internal->dragEnabled = true;

history::ComplexAction* h = APP->scene->rack->getModuleDragAction();
if (!h)
return;
APP->history->push(h);
if (!h->isEmpty())
APP->history->push(h);
else
delete h;
}
}

@@ -429,10 +430,17 @@ void ModuleWidget::onDragMove(const DragMoveEvent& e) {
math::Vec pos = mousePos;
pos.x -= internal->dragOffset.x;
pos.y -= RACK_GRID_HEIGHT / 2;
if ((APP->window->getMods() & RACK_MOD_MASK) == RACK_MOD_CTRL)
APP->scene->rack->setModulePosForce(this, pos);
else
APP->scene->rack->setModulePosNearest(this, pos);
if (internal->selected) {
pos = (pos / RACK_GRID_SIZE).round() * RACK_GRID_SIZE;
math::Vec delta = pos.minus(box.pos);
APP->scene->rack->requestSelectedModulePos(delta);
}
else {
if ((APP->window->getMods() & RACK_MOD_MASK) == RACK_MOD_CTRL)
APP->scene->rack->setModulePosForce(this, pos);
else
APP->scene->rack->setModulePosNearest(this, pos);
}
}
}
}


+ 36
- 22
src/app/RackWidget.cpp View File

@@ -206,12 +206,9 @@ 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<widget::Widget*> widgets = internal->moduleContainer->children;
for (widget::Widget* w : widgets) {
ModuleWidget* moduleWidget = dynamic_cast<ModuleWidget*>(w);
assert(moduleWidget);
removeModule(moduleWidget);
delete moduleWidget;
for (ModuleWidget* mw : getModules()) {
removeModule(mw);
delete mw;
}
}

@@ -486,9 +483,6 @@ bool RackWidget::requestModulePos(ModuleWidget* mw, math::Vec pos) {
// Don't intersect with self
if (mw == w2)
continue;
// Don't intersect with invisible modules
if (!w2->visible)
continue;
// Check intersection
math::Rect w2Box = w2->box;
if (mwBox.intersects(w2Box))
@@ -628,9 +622,7 @@ bool RackWidget::hasModules() {

void RackWidget::updateModuleOldPositions() {
// Set all modules' oldPos field from their current position.
for (widget::Widget* w : internal->moduleContainer->children) {
ModuleWidget* mw = dynamic_cast<ModuleWidget*>(w);
assert(mw);
for (ModuleWidget* mw : getModules()) {
mw->oldPos() = mw->box.pos;
}
}
@@ -638,9 +630,7 @@ void RackWidget::updateModuleOldPositions() {
history::ComplexAction* RackWidget::getModuleDragAction() {
history::ComplexAction* h = new history::ComplexAction;

for (widget::Widget* w : internal->moduleContainer->children) {
ModuleWidget* mw = dynamic_cast<ModuleWidget*>(w);
assert(mw);
for (ModuleWidget* mw : getModules()) {
// Create ModuleMove action if the module was moved.
math::Vec oldPos = mw->oldPos();
if (!oldPos.equals(mw->box.pos)) {
@@ -652,18 +642,12 @@ history::ComplexAction* RackWidget::getModuleDragAction() {
}
}

if (h->isEmpty()) {
delete h;
return NULL;
}
return h;
}

void RackWidget::updateModuleSelections() {
math::Rect selectionBox = math::Rect::fromCorners(internal->selectionStart, internal->selectionEnd);
for (widget::Widget* w : internal->moduleContainer->children) {
ModuleWidget* mw = dynamic_cast<ModuleWidget*>(w);
assert(mw);
for (ModuleWidget* mw : getModules()) {
bool selected = internal->selecting && selectionBox.intersects(mw->box);
mw->selected() = selected;
}
@@ -770,6 +754,36 @@ void RackWidget::deleteSelectedModulesAction() {
APP->history->push(complexAction);
}

bool RackWidget::requestSelectedModulePos(math::Vec delta) {
// Check intersection with other modules
std::map<widget::Widget*, math::Rect> mwBoxes;
for (ModuleWidget* mw : getSelectedModules()) {
math::Rect mwBox = mw->box;
mwBox.pos += delta;
mwBoxes[mw] = mwBox;
}

for (widget::Widget* w2 : internal->moduleContainer->children) {
// Don't intersect with selected modules
auto it = mwBoxes.find(w2);
if (it != mwBoxes.end())
continue;
math::Rect w2Box = w2->box;
// Check intersection with all selected modules
for (const auto& pair : mwBoxes) {
if (pair.second.intersects(w2Box))
return false;
}
}

// Accept requested position
for (const auto& pair : mwBoxes) {
pair.first->setPosition(pair.second.pos);
}
RackWidget_updateExpanders(this);
return true;
}

void RackWidget::clearCables() {
incompleteCable = NULL;
internal->cableContainer->clearChildren();


Loading…
Cancel
Save