Thu, 09 Feb 2017 19:57:43 +0200
Moved more business logic out of GLRenderer into Canvas. GLRenderer::pick(const QRange&) now returns a set of LDObjects without modifying them. Replaced the GLRenderer::pick(int, int) overload with GLRenderer::pickOneObject.
--- a/src/canvas.cpp Thu Feb 09 19:32:41 2017 +0200 +++ b/src/canvas.cpp Thu Feb 09 19:57:43 2017 +0200 @@ -309,4 +309,15 @@ int ry = (((position3d[axisY] * signY) - virtualHeight() + panning(Y)) * height()) / (2 * virtualHeight()); return {rx, -ry}; } -} \ No newline at end of file +} + +void Canvas::contextMenuEvent(QContextMenuEvent* event) +{ + m_window->spawnContextMenu(event->globalPos()); +} + +void Canvas::dragEnterEvent(QDragEnterEvent* event) +{ + if (m_window and event->source() == m_window->getPrimitivesTree() and m_window->getPrimitivesTree()->currentItem()) + event->acceptProposedAction(); +}
--- a/src/canvas.h Thu Feb 09 19:32:41 2017 +0200 +++ b/src/canvas.h Thu Feb 09 19:57:43 2017 +0200 @@ -43,6 +43,8 @@ void setEditMode(EditModeType type); protected: + void contextMenuEvent(QContextMenuEvent* event) override; + void dragEnterEvent(QDragEnterEvent* event) override; void dropEvent(QDropEvent* event) override; bool freeCameraAllowed() const override; void keyReleaseEvent(QKeyEvent* event) override;
--- a/src/editmodes/magicWandMode.cpp Thu Feb 09 19:32:41 2017 +0200 +++ b/src/editmodes/magicWandMode.cpp Thu Feb 09 19:57:43 2017 +0200 @@ -210,7 +210,7 @@ else if (data.keymods & Qt::ControlModifier) wandtype = MagicWandMode::Subtractive; - doMagic (renderer()->pickOneObject (data.ev->x(), data.ev->y()), wandtype); + doMagic (renderer()->pick (data.ev->x(), data.ev->y()), wandtype); return true; }
--- a/src/editmodes/selectMode.cpp Thu Feb 09 19:32:41 2017 +0200 +++ b/src/editmodes/selectMode.cpp Thu Feb 09 19:57:43 2017 +0200 @@ -66,23 +66,23 @@ if (not data.mouseMoved or m_rangepick) { QRect area; - int const mx = data.ev->x(); - int const my = data.ev->y(); + int mx = data.ev->x(); + int my = data.ev->y(); if (not m_rangepick) { - area = QRect (mx, my, 1, 1); + area = {mx, my, 1, 1}; } else { - int const x = qMin (m_rangeStart.x(), mx); - int const y = qMin (m_rangeStart.y(), my); - int const width = qAbs (m_rangeStart.x() - mx); - int const height = qAbs (m_rangeStart.y() - my); - area = QRect (x, y, width, height); + int x = qMin(m_rangeStart.x(), mx); + int y = qMin(m_rangeStart.y(), my); + int width = qAbs(m_rangeStart.x() - mx); + int height = qAbs(m_rangeStart.y() - my); + area = {x, y, width, height}; } - renderer()->pick (area, m_addpick); + doSelection(area); } m_rangepick = false; @@ -92,6 +92,29 @@ return false; } +void SelectMode::doSelection(const QRect& area) +{ + QSet<LDObject*> priorSelection = selectedObjects(); + QSet<LDObject*> newSelection = renderer()->pick(area); + + // If we're doing an additive pick, use a symmetric difference to keep the existing ones, and filter out objects that were selected + // once over again. + if (m_addpick) + newSelection = (newSelection - priorSelection) | (priorSelection - newSelection); + + newSelection.unite(renderer()->pick(area)); + + // Select all objects that we now have selected that were not selected before. + for (LDObject* object : newSelection - priorSelection) + currentDocument()->addToSelection(object); + + // Likewise, deselect whatever was selected that isn't anymore. + for (LDObject* object : priorSelection - newSelection) + currentDocument()->removeFromSelection(object); + + m_window->updateSelection(); +} + bool SelectMode::mousePressed (QMouseEvent* ev) { if (Super::mousePressed (ev)) @@ -117,7 +140,7 @@ if (ev->buttons() & Qt::LeftButton) { currentDocument()->clearSelection(); - LDObject* obj = renderer()->pickOneObject (ev->x(), ev->y()); + LDObject* obj = renderer()->pick (ev->x(), ev->y()); if (obj) {
--- a/src/editmodes/selectMode.h Thu Feb 09 19:32:41 2017 +0200 +++ b/src/editmodes/selectMode.h Thu Feb 09 19:57:43 2017 +0200 @@ -30,6 +30,7 @@ public: SelectMode (Canvas* canvas); + void doSelection(const QRect& area); void render (QPainter& painter) const override; bool mousePressed (QMouseEvent* ev) override; bool mouseReleased (MouseEventData const& data) override;
--- a/src/glRenderer.cpp Thu Feb 09 19:32:41 2017 +0200 +++ b/src/glRenderer.cpp Thu Feb 09 19:57:43 2017 +0200 @@ -675,13 +675,6 @@ // ============================================================================= // -void GLRenderer::contextMenuEvent(QContextMenuEvent* event) -{ - m_window->spawnContextMenu(event->globalPos()); -} - -// ============================================================================= -// void GLRenderer::setCamera(Camera camera) { // The edit mode may forbid the free camera. @@ -692,26 +685,14 @@ } } -// ============================================================================= -// -void GLRenderer::pick (int mouseX, int mouseY, bool additive) -{ - pick (QRect (mouseX, mouseY, mouseX + 1, mouseY + 1), additive); -} - -// ============================================================================= -// -void GLRenderer::pick(const QRect& range, bool additive) +/* + * Returns the set of objects found in the specified pixel area. + */ +QSet<LDObject*> GLRenderer::pick(const QRect& range) { makeCurrent(); - QSet<LDObject*> priorSelection = selectedObjects(); QSet<LDObject*> newSelection; - // If we're doing an additive selection, we start off with the existing selection. - // Otherwise we start selecting from scratch. - if (additive) - newSelection = priorSelection; - // Paint the picking scene setPicking(true); drawGLScene(); @@ -757,48 +738,25 @@ LDObject* object = LDObject::fromID(index); if (object != nullptr) - { - // If this is an additive single pick and the object is currently selected, - // we remove it from selection instead. - if (additive and newSelection.contains(object)) - newSelection.remove(object); - else - newSelection.insert(object); - } - } - - // Select all objects that we now have selected that were not selected before. - for (LDObject* object : newSelection - priorSelection) - { - currentDocument()->addToSelection(object); - compileObject(object); + newSelection.insert(object); } - // Likewise, deselect whatever was selected that isn't anymore. - for (LDObject* object : priorSelection - newSelection) - { - currentDocument()->removeFromSelection(object); - compileObject(object); - } - - m_window->updateSelection(); setPicking(false); repaint(); + return newSelection; } -// -// Simpler version of GLRenderer::pick which simply picks whatever object on the cursor -// -LDObject* GLRenderer::pickOneObject (int mouseX, int mouseY) +/* + * Simpler version of GLRenderer::pick which simply picks whatever object on the cursor + */ +LDObject* GLRenderer::pick(int mouseX, int mouseY) { unsigned char pixel[4]; makeCurrent(); setPicking(true); drawGLScene(); glReadPixels(mouseX, m_height - mouseY, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, pixel); - LDObject* object = LDObject::fromID(pixel[0] * 0x10000 + - pixel[1] * 0x100 + - pixel[2] * 0x1); + LDObject* object = LDObject::fromID(pixel[0] * 0x10000 + pixel[1] * 0x100 + pixel[2]); setPicking(false); repaint(); return object; @@ -1055,12 +1013,6 @@ update(); } -void GLRenderer::dragEnterEvent (QDragEnterEvent* ev) -{ - if (m_window and ev->source() == m_window->getPrimitivesTree() and m_window->getPrimitivesTree()->currentItem()) - ev->acceptProposedAction(); -} - const CameraInfo& GLRenderer::cameraInfo (Camera camera) const { if (valueInEnum<Camera>(camera))
--- a/src/glRenderer.h Thu Feb 09 19:32:41 2017 +0200 +++ b/src/glRenderer.h Thu Feb 09 19:57:43 2017 +0200 @@ -97,9 +97,8 @@ QPointF const& mousePositionF() const; void needZoomToFit(); LDObject* objectAtCursor() const; - void pick(int mouseX, int mouseY, bool additive); - void pick(const QRect& range, bool additive); - LDObject* pickOneObject(int mouseX, int mouseY); + QSet<LDObject*> pick(const QRect& range); + LDObject* pick(int mouseX, int mouseY); void refresh(); void resetAllAngles(); void resetAngles(); @@ -115,8 +114,6 @@ static const QPen thinBorderPen; protected: - void contextMenuEvent(QContextMenuEvent* event); - void dragEnterEvent(QDragEnterEvent* event); void initializeGL(); void keyPressEvent(QKeyEvent* event); void keyReleaseEvent(QKeyEvent* event);