diff --git a/src/Gui/BlenderNavigationStyle.cpp b/src/Gui/BlenderNavigationStyle.cpp index b9f209ba88..7b9a04c2bb 100644 --- a/src/Gui/BlenderNavigationStyle.cpp +++ b/src/Gui/BlenderNavigationStyle.cpp @@ -142,16 +142,17 @@ SbBool BlenderNavigationStyle::processSoEvent(const SoEvent * const ev) // If we are in edit mode then simply ignore the RMB events // to pass the event to the base class. this->lockrecenter = true; - if (!viewer->isEditing()) { - // If we are in zoom or pan mode ignore RMB events otherwise - // the canvas doesn't get any release events + + // Don't show the context menu after dragging, panning or zooming + if (!press && (hasDragged || hasPanned || hasZoomed)) { + processed = true; + } + else if (!press && !viewer->isEditing()) { if (this->currentmode != NavigationStyle::ZOOMING && this->currentmode != NavigationStyle::PANNING && this->currentmode != NavigationStyle::DRAGGING) { if (this->isPopupMenuEnabled()) { - if (!press) { // release right mouse button - this->openPopupMenu(event->getPosition()); - } + this->openPopupMenu(event->getPosition()); } } } @@ -241,17 +242,15 @@ SbBool BlenderNavigationStyle::processSoEvent(const SoEvent * const ev) case 0: if (curmode == NavigationStyle::SPINNING) { break; } newmode = NavigationStyle::IDLE; - // The left mouse button has been released right now but - // we want to avoid that the event is processed elsewhere + // The left mouse button has been released right now if (this->lockButton1) { this->lockButton1 = false; - processed = true; } break; case BUTTON1DOWN: case CTRLDOWN|BUTTON1DOWN: // make sure not to change the selection when stopping spinning - if (curmode == NavigationStyle::SPINNING || this->lockButton1) + if (!viewer->isEditing() && (curmode == NavigationStyle::SPINNING || this->lockButton1)) newmode = NavigationStyle::IDLE; else newmode = NavigationStyle::SELECTION; @@ -277,16 +276,24 @@ SbBool BlenderNavigationStyle::processSoEvent(const SoEvent * const ev) break; } + // If the selection button is pressed together with another button + // and the other button is released, don't switch to selection mode. + // Process when selection button is pressed together with other buttons that could trigger different actions. + if (this->button1down && (this->button2down || this->button3down)) { + this->lockButton1 = true; + processed = true; + } + + // Prevent interrupting rubber-band selection in sketcher + if (viewer->isEditing() && curmode == NavigationStyle::SELECTION && newmode != NavigationStyle::IDLE) { + newmode = NavigationStyle::SELECTION; + processed = false; + } + if (newmode != curmode) { this->setViewingMode(newmode); } - // If for dragging the buttons 1 and 3 are pressed - // but then button 3 is released we shouldn't switch - // into selection mode. - if (this->button1down && this->button3down) - this->lockButton1 = true; - // If not handled in this class, pass on upwards in the inheritance // hierarchy. if (!processed) diff --git a/src/Gui/CADNavigationStyle.cpp b/src/Gui/CADNavigationStyle.cpp index e0dd117231..0ba8e0fae7 100644 --- a/src/Gui/CADNavigationStyle.cpp +++ b/src/Gui/CADNavigationStyle.cpp @@ -144,16 +144,17 @@ SbBool CADNavigationStyle::processSoEvent(const SoEvent * const ev) // If we are in edit mode then simply ignore the RMB events // to pass the event to the base class. this->lockrecenter = true; - if (!viewer->isEditing()) { - // If we are in zoom or pan mode ignore RMB events otherwise - // the canvas doesn't get any release events + + // Don't show the context menu after dragging, panning or zooming + if (!press && (hasDragged || hasPanned || hasZoomed)) { + processed = true; + } + if (!press && !viewer->isEditing()) { if (this->currentmode != NavigationStyle::ZOOMING && this->currentmode != NavigationStyle::PANNING && this->currentmode != NavigationStyle::DRAGGING) { if (this->isPopupMenuEnabled()) { - if (!press) { // release right mouse button - this->openPopupMenu(event->getPosition()); - } + this->openPopupMenu(event->getPosition()); } } } @@ -249,16 +250,14 @@ SbBool CADNavigationStyle::processSoEvent(const SoEvent * const ev) case 0: if (curmode == NavigationStyle::SPINNING) { break; } newmode = NavigationStyle::IDLE; - // The left mouse button has been released right now but - // we want to avoid that the event is processed elsewhere + // The left mouse button has been released right now if (this->lockButton1) { this->lockButton1 = false; - processed = true; } break; case BUTTON1DOWN: // make sure not to change the selection when stopping spinning - if (curmode == NavigationStyle::SPINNING || this->lockButton1) + if (!viewer->isEditing() && (curmode == NavigationStyle::SPINNING || this->lockButton1)) newmode = NavigationStyle::IDLE; else newmode = NavigationStyle::SELECTION; @@ -301,16 +300,24 @@ SbBool CADNavigationStyle::processSoEvent(const SoEvent * const ev) break; } + // If the selection button is pressed together with another button + // and the other button is released, don't switch to selection mode. + // Process when selection button is pressed together with other buttons that could trigger different actions. + if (this->button1down && (this->button2down || this->button3down)) { + this->lockButton1 = true; + processed = true; + } + + // Prevent interrupting rubber-band selection in sketcher + if (viewer->isEditing() && curmode == NavigationStyle::SELECTION && newmode != NavigationStyle::IDLE) { + newmode = NavigationStyle::SELECTION; + processed = false; + } + if (newmode != curmode) { this->setViewingMode(newmode); } - // If for dragging the buttons 1 and 3 are pressed - // but then button 3 is released we shouldn't switch - // into selection mode. - if (this->button1down && this->button3down) - this->lockButton1 = true; - // If not handled in this class, pass on upwards in the inheritance // hierarchy. if (!processed) diff --git a/src/Gui/InventorNavigationStyle.cpp b/src/Gui/InventorNavigationStyle.cpp index f4db29b1a2..3d553f78ff 100644 --- a/src/Gui/InventorNavigationStyle.cpp +++ b/src/Gui/InventorNavigationStyle.cpp @@ -172,15 +172,17 @@ SbBool InventorNavigationStyle::processSoEvent(const SoEvent * const ev) // If we are in edit mode then simply ignore the RMB events // to pass the event to the base class. this->lockrecenter = true; - if (!viewer->isEditing()) { - // If we are in zoom or pan mode ignore RMB events otherwise - // the canvas doesn't get any release events + + // Don't show the context menu after dragging, panning or zooming + if (!press && (hasDragged || hasPanned || hasZoomed)) { + processed = true; + } + else if (!press && !viewer->isEditing()) { if (this->currentmode != NavigationStyle::ZOOMING && - this->currentmode != NavigationStyle::PANNING) { + this->currentmode != NavigationStyle::PANNING && + this->currentmode != NavigationStyle::DRAGGING) { if (this->isPopupMenuEnabled()) { - if (!press) { // release right mouse button - this->openPopupMenu(event->getPosition()); - } + this->openPopupMenu(event->getPosition()); } } } @@ -267,6 +269,7 @@ SbBool InventorNavigationStyle::processSoEvent(const SoEvent * const ev) } break; case BUTTON1DOWN: + if (curmode == NavigationStyle::SELECTION) { break; } if (newmode != NavigationStyle::DRAGGING) { saveCursorPosition(ev); } @@ -289,23 +292,21 @@ SbBool InventorNavigationStyle::processSoEvent(const SoEvent * const ev) newmode = NavigationStyle::ZOOMING; break; - // There are many cases we don't handle that just falls through to - // the default case, like SHIFTDOWN, CTRLDOWN, CTRLDOWN|SHIFTDOWN, - // SHIFTDOWN|BUTTON3DOWN, SHIFTDOWN|CTRLDOWN|BUTTON3DOWN, etc. - // This is a feature, not a bug. :-) - // - // mortene. - default: - // The default will make a spin stop and otherwise not do - // anything. - if ((curmode != NavigationStyle::SEEK_WAIT_MODE) && - (curmode != NavigationStyle::SEEK_MODE)) { - newmode = NavigationStyle::IDLE; - } break; } + // Process when selection button is pressed together with other buttons that could trigger different actions. + if (this->button1down && (this->button2down || this->button3down)) { + processed = true; + } + + // Prevent interrupting rubber-band selection in sketcher + if (viewer->isEditing() && curmode == NavigationStyle::SELECTION && newmode != NavigationStyle::IDLE) { + newmode = NavigationStyle::SELECTION; + processed = false; + } + if (newmode != curmode) { this->setViewingMode(newmode); } diff --git a/src/Gui/MayaGestureNavigationStyle.cpp b/src/Gui/MayaGestureNavigationStyle.cpp index 2b3b652043..1f58d2972d 100644 --- a/src/Gui/MayaGestureNavigationStyle.cpp +++ b/src/Gui/MayaGestureNavigationStyle.cpp @@ -308,8 +308,40 @@ SbBool MayaGestureNavigationStyle::processSoEvent(const SoEvent * const ev) //all mode-dependent stuff is within this switch. switch(curmode){ - case NavigationStyle::IDLE: case NavigationStyle::SELECTION: + // Prevent interrupting rubber-band selection in sketcher + if (viewer->isEditing()) { + if (evIsButton) { + auto const event = (const SoMouseButtonEvent*)ev; + const SbBool press = event->getState() == SoButtonEvent::DOWN; + const int button = event->getButton(); + + if (!press && button == SoMouseButtonEvent::BUTTON1) { + setViewingMode(NavigationStyle::IDLE); + break; + } + } + + if (this->button1down) { + break; + } + } + [[fallthrough]]; + case NavigationStyle::IDLE: + // Prevent interrupting rubber-band selection in sketcher + if (viewer->isEditing()) { + if (evIsButton) { + auto const event = (const SoMouseButtonEvent*)ev; + const SbBool press = event->getState() == SoButtonEvent::DOWN; + const int button = event->getButton(); + + if (press && button == SoMouseButtonEvent::BUTTON1 && !this->altdown) { + setViewingMode(NavigationStyle::SELECTION); + break; + } + } + } + [[fallthrough]]; case NavigationStyle::INTERACT: { //idle and interaction diff --git a/src/Gui/NavigationStyle.cpp b/src/Gui/NavigationStyle.cpp index 01337e05b4..218711c993 100644 --- a/src/Gui/NavigationStyle.cpp +++ b/src/Gui/NavigationStyle.cpp @@ -260,6 +260,7 @@ void NavigationStyle::initialize() this->hasDragged = false; this->hasPanned = false; + this->hasZoomed = false; } void NavigationStyle::finalize() @@ -586,7 +587,10 @@ void NavigationStyle::panCamera(SoCamera * cam, float aspectratio, const SbPlane // Reposition camera according to the vector difference between the // projected points. cam->position = cam->position.getValue() - (current_planept - old_planept); - hasPanned = true; + + if (this->currentmode != NavigationStyle::IDLE) { + hasPanned = true; + } } void NavigationStyle::pan(SoCamera* camera) @@ -695,6 +699,10 @@ void NavigationStyle::zoom(SoCamera * cam, float diffvalue) cam->focalDistance = newfocaldist; } } + + if (this->currentmode != NavigationStyle::IDLE) { + hasZoomed = true; + } } // Calculate a zoom/dolly factor from the difference of the current @@ -900,7 +908,9 @@ void NavigationStyle::spin(const SbVec2f & pointerpos) // animation. if (this->spinsamplecounter > 3) this->spinsamplecounter = 3; - hasDragged = true; + if (this->currentmode != NavigationStyle::IDLE) { + hasDragged = true; + } } /*! @@ -1352,9 +1362,10 @@ void NavigationStyle::setViewingMode(const ViewerMode newmode) return; } - if (newmode != NavigationStyle::IDLE) { + if (newmode == NavigationStyle::IDLE) { hasPanned = false; hasDragged = false; + hasZoomed = false; } switch (newmode) { diff --git a/src/Gui/NavigationStyle.h b/src/Gui/NavigationStyle.h index 8e17166781..c5a0d4f5ef 100644 --- a/src/Gui/NavigationStyle.h +++ b/src/Gui/NavigationStyle.h @@ -261,6 +261,7 @@ protected: float zoomStep; SbBool hasDragged; SbBool hasPanned; + SbBool hasZoomed; /** @name Mouse model */ //@{ diff --git a/src/Gui/OpenCascadeNavigationStyle.cpp b/src/Gui/OpenCascadeNavigationStyle.cpp index 63838e6645..fe14812048 100644 --- a/src/Gui/OpenCascadeNavigationStyle.cpp +++ b/src/Gui/OpenCascadeNavigationStyle.cpp @@ -139,16 +139,17 @@ SbBool OpenCascadeNavigationStyle::processSoEvent(const SoEvent * const ev) // If we are in edit mode then simply ignore the RMB events // to pass the event to the base class. this->lockrecenter = true; - if (!viewer->isEditing()) { - // If we are in zoom or pan mode ignore RMB events otherwise - // the canvas doesn't get any release events + + // Don't show the context menu after dragging, panning or zooming + if (!press && (hasDragged || hasPanned || hasZoomed)) { + processed = true; + } + else if (!press && !viewer->isEditing()) { if (this->currentmode != NavigationStyle::ZOOMING && this->currentmode != NavigationStyle::PANNING && this->currentmode != NavigationStyle::DRAGGING) { if (this->isPopupMenuEnabled()) { - if (!press) { // release right mouse button - this->openPopupMenu(event->getPosition()); - } + this->openPopupMenu(event->getPosition()); } } } @@ -263,6 +264,17 @@ SbBool OpenCascadeNavigationStyle::processSoEvent(const SoEvent * const ev) break; } + // Process when selection button is pressed together with other buttons that could trigger different actions. + if (this->button1down && (this->button2down || this->button3down || this->ctrldown)) { + processed = true; + } + + // Prevent interrupting rubber-band selection in sketcher + if (viewer->isEditing() && curmode == NavigationStyle::SELECTION && newmode != NavigationStyle::IDLE) { + newmode = NavigationStyle::SELECTION; + processed = false; + } + if (newmode != curmode) { this->setViewingMode(newmode); } diff --git a/src/Gui/OpenSCADNavigationStyle.cpp b/src/Gui/OpenSCADNavigationStyle.cpp index c9b6b74c02..a37b6ef21f 100644 --- a/src/Gui/OpenSCADNavigationStyle.cpp +++ b/src/Gui/OpenSCADNavigationStyle.cpp @@ -140,17 +140,16 @@ SbBool OpenSCADNavigationStyle::processSoEvent(const SoEvent * const ev) // to pass the event to the base class. this->lockrecenter = true; this->button2down = press; - if (!viewer->isEditing()) { - // If we are in zoom or pan mode ignore RMB events otherwise - // the canvas doesn't get any release events - if ((curmode != NavigationStyle::ZOOMING && - curmode != NavigationStyle::PANNING && - curmode != NavigationStyle::DRAGGING) || - (curmode == NavigationStyle::PANNING && !hasPanned)) { + + // Don't show the context menu after dragging, panning or zooming + if (!press && (hasDragged || hasPanned || hasZoomed)) { + processed = true; + } + else if (!press && !viewer->isEditing()) { + if (this->currentmode != NavigationStyle::ZOOMING && + this->currentmode != NavigationStyle::DRAGGING) { if (this->isPopupMenuEnabled()) { - if (!press) { // release right mouse button - this->openPopupMenu(event->getPosition()); - } + this->openPopupMenu(event->getPosition()); } } } @@ -166,9 +165,6 @@ SbBool OpenSCADNavigationStyle::processSoEvent(const SoEvent * const ev) newmode = NavigationStyle::IDLE; processed = true; } - else if (!press && curmode == NavigationStyle::PANNING && hasPanned) { - processed = true; - } break; case SoMouseButtonEvent::BUTTON3: this->button3down = press; @@ -263,6 +259,17 @@ SbBool OpenSCADNavigationStyle::processSoEvent(const SoEvent * const ev) break; } + // Process when selection button is pressed together with other buttons that could trigger different actions. + if (this->button1down && (this->button2down || this->button3down)) { + processed = true; + } + + // Prevent interrupting rubber-band selection in sketcher + if (viewer->isEditing() && curmode == NavigationStyle::SELECTION && newmode != NavigationStyle::IDLE) { + newmode = NavigationStyle::SELECTION; + processed = false; + } + if (newmode != curmode) { this->setViewingMode(newmode); } diff --git a/src/Gui/RevitNavigationStyle.cpp b/src/Gui/RevitNavigationStyle.cpp index b1c96ad714..78535462ab 100644 --- a/src/Gui/RevitNavigationStyle.cpp +++ b/src/Gui/RevitNavigationStyle.cpp @@ -141,16 +141,17 @@ SbBool RevitNavigationStyle::processSoEvent(const SoEvent * const ev) // If we are in edit mode then simply ignore the RMB events // to pass the event to the base class. this->lockrecenter = true; - if (!viewer->isEditing()) { - // If we are in zoom or pan mode ignore RMB events otherwise - // the canvas doesn't get any release events + + // Don't show the context menu after dragging, panning or zooming + if (!press && (hasDragged || hasPanned || hasZoomed)) { + processed = true; + } + else if (!press && !viewer->isEditing()) { if (this->currentmode != NavigationStyle::ZOOMING && this->currentmode != NavigationStyle::PANNING && this->currentmode != NavigationStyle::DRAGGING) { if (this->isPopupMenuEnabled()) { - if (!press) { // release right mouse button - this->openPopupMenu(event->getPosition()); - } + this->openPopupMenu(event->getPosition()); } } } @@ -238,17 +239,15 @@ SbBool RevitNavigationStyle::processSoEvent(const SoEvent * const ev) case 0: if (curmode == NavigationStyle::SPINNING) { break; } newmode = NavigationStyle::IDLE; - // The left mouse button has been released right now but - // we want to avoid that the event is processed elsewhere + // The left mouse button has been released right now if (this->lockButton1) { this->lockButton1 = false; - processed = true; } break; case BUTTON1DOWN: case CTRLDOWN|BUTTON1DOWN: // make sure not to change the selection when stopping spinning - if (curmode == NavigationStyle::SPINNING || this->lockButton1) + if (!viewer->isEditing() && (curmode == NavigationStyle::SPINNING || this->lockButton1)) newmode = NavigationStyle::IDLE; else newmode = NavigationStyle::SELECTION; @@ -279,16 +278,24 @@ SbBool RevitNavigationStyle::processSoEvent(const SoEvent * const ev) break; } + // If the selection button is pressed together with another button + // and the other button is released, don't switch to selection mode. + // Process when selection button is pressed together with other buttons that could trigger different actions. + if (this->button1down && (this->button2down || this->button3down)) { + this->lockButton1 = true; + processed = true; + } + + // Prevent interrupting rubber-band selection in sketcher + if (viewer->isEditing() && curmode == NavigationStyle::SELECTION && newmode != NavigationStyle::IDLE) { + newmode = NavigationStyle::SELECTION; + processed = false; + } + if (newmode != curmode) { this->setViewingMode(newmode); } - // If for dragging the buttons 1 and 3 are pressed - // but then button 3 is released we shouldn't switch - // into selection mode. - if (this->button1down && this->button3down) - this->lockButton1 = true; - // If not handled in this class, pass on upwards in the inheritance // hierarchy. if (!processed) diff --git a/src/Gui/TinkerCADNavigationStyle.cpp b/src/Gui/TinkerCADNavigationStyle.cpp index e229a61f52..a35632f7bd 100644 --- a/src/Gui/TinkerCADNavigationStyle.cpp +++ b/src/Gui/TinkerCADNavigationStyle.cpp @@ -142,15 +142,18 @@ SbBool TinkerCADNavigationStyle::processSoEvent(const SoEvent * const ev) this->centerTime = ev->getTime(); processed = true; } - else if (!press && curmode == NavigationStyle::DRAGGING && hasDragged) { + // Don't show the context menu after dragging, panning or zooming + else if (!press && (hasDragged || hasPanned || hasZoomed)) { processed = true; } - else if (!press && curmode == NavigationStyle::DRAGGING && !hasDragged) { + else if (!press) { newmode = NavigationStyle::IDLE; if (!viewer->isEditing()) { - // If we are in drag mode but mouse hasn't been moved open the context-menu - if (this->isPopupMenuEnabled()) { - this->openPopupMenu(event->getPosition()); + if (this->currentmode != NavigationStyle::ZOOMING && + this->currentmode != NavigationStyle::PANNING) { + if (this->isPopupMenuEnabled()) { + this->openPopupMenu(event->getPosition()); + } } processed = true; } @@ -230,6 +233,17 @@ SbBool TinkerCADNavigationStyle::processSoEvent(const SoEvent * const ev) break; } + // Process when selection button is pressed together with other buttons that could trigger different actions. + if (this->button1down && (this->button2down || this->button3down)) { + processed = true; + } + + // Prevent interrupting rubber-band selection in sketcher + if (viewer->isEditing() && curmode == NavigationStyle::SELECTION && newmode != NavigationStyle::IDLE) { + newmode = NavigationStyle::SELECTION; + processed = false; + } + if (newmode != curmode) { this->setViewingMode(newmode); } diff --git a/src/Gui/TouchpadNavigationStyle.cpp b/src/Gui/TouchpadNavigationStyle.cpp index 172a0f7ede..5400440ae5 100644 --- a/src/Gui/TouchpadNavigationStyle.cpp +++ b/src/Gui/TouchpadNavigationStyle.cpp @@ -138,16 +138,17 @@ SbBool TouchpadNavigationStyle::processSoEvent(const SoEvent * const ev) // If we are in edit mode then simply ignore the RMB events // to pass the event to the base class. this->lockrecenter = true; - if (!viewer->isEditing()) { - // If we are in zoom or pan mode ignore RMB events otherwise - // the canvas doesn't get any release events + + // Don't show the context menu after dragging, panning or zooming + if (!press && (hasDragged || hasPanned || hasZoomed)) { + processed = true; + } + else if (!press && !viewer->isEditing()) { if (this->currentmode != NavigationStyle::ZOOMING && this->currentmode != NavigationStyle::PANNING && this->currentmode != NavigationStyle::DRAGGING) { if (this->isPopupMenuEnabled()) { - if (!press) { // release right mouse button - this->openPopupMenu(event->getPosition()); - } + this->openPopupMenu(event->getPosition()); } } } @@ -253,6 +254,17 @@ SbBool TouchpadNavigationStyle::processSoEvent(const SoEvent * const ev) break; } + // Process when selection button is pressed together with other buttons that could trigger different actions. + if (this->button1down && (this->button2down || this->button3down || this->altdown)) { + processed = true; + } + + // Prevent interrupting rubber-band selection in sketcher + if (viewer->isEditing() && curmode == NavigationStyle::SELECTION && newmode != NavigationStyle::IDLE) { + newmode = NavigationStyle::SELECTION; + processed = false; + } + if (newmode != curmode) { this->setViewingMode(newmode); }