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 disconnectSelectedModulesAction();
void bypassSelectedModulesAction(); void bypassSelectedModulesAction();
void deleteSelectedModulesAction(); void deleteSelectedModulesAction();
bool requestSelectedModulePos(math::Vec delta);


// Cable methods // Cable methods




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

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


history::ComplexAction* h = APP->scene->rack->getModuleDragAction(); 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; math::Vec pos = mousePos;
pos.x -= internal->dragOffset.x; pos.x -= internal->dragOffset.x;
pos.y -= RACK_GRID_HEIGHT / 2; 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. // This isn't required because removing all ModuleWidgets should remove all cables, but do it just in case.
clearCables(); clearCables();
// Remove ModuleWidgets // 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 // Don't intersect with self
if (mw == w2) if (mw == w2)
continue; continue;
// Don't intersect with invisible modules
if (!w2->visible)
continue;
// Check intersection // Check intersection
math::Rect w2Box = w2->box; math::Rect w2Box = w2->box;
if (mwBox.intersects(w2Box)) if (mwBox.intersects(w2Box))
@@ -628,9 +622,7 @@ bool RackWidget::hasModules() {


void RackWidget::updateModuleOldPositions() { void RackWidget::updateModuleOldPositions() {
// Set all modules' oldPos field from their current position. // 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; mw->oldPos() = mw->box.pos;
} }
} }
@@ -638,9 +630,7 @@ void RackWidget::updateModuleOldPositions() {
history::ComplexAction* RackWidget::getModuleDragAction() { history::ComplexAction* RackWidget::getModuleDragAction() {
history::ComplexAction* h = new history::ComplexAction; 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. // Create ModuleMove action if the module was moved.
math::Vec oldPos = mw->oldPos(); math::Vec oldPos = mw->oldPos();
if (!oldPos.equals(mw->box.pos)) { if (!oldPos.equals(mw->box.pos)) {
@@ -652,18 +642,12 @@ history::ComplexAction* RackWidget::getModuleDragAction() {
} }
} }


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


void RackWidget::updateModuleSelections() { void RackWidget::updateModuleSelections() {
math::Rect selectionBox = math::Rect::fromCorners(internal->selectionStart, internal->selectionEnd); 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); bool selected = internal->selecting && selectionBox.intersects(mw->box);
mw->selected() = selected; mw->selected() = selected;
} }
@@ -770,6 +754,36 @@ void RackWidget::deleteSelectedModulesAction() {
APP->history->push(complexAction); 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() { void RackWidget::clearCables() {
incompleteCable = NULL; incompleteCable = NULL;
internal->cableContainer->clearChildren(); internal->cableContainer->clearChildren();


Loading…
Cancel
Save