Download src/Gui/Navigation/RevitNavigationStyle.cpp from AbdulElahGwaith/FreeCAD: direct link, hf CLI and curl.
- Browser
- Download file 13.3 kB
-
https://huggingface.co/AbdulElahGwaith/FreeCAD/resolve/main/src/Gui/Navigation/RevitNavigationStyle.cpp
- Command line
-
hf download hf://AbdulElahGwaith/FreeCAD/src/Gui/Navigation/RevitNavigationStyle.cpp
-
curl -L -o RevitNavigationStyle.cpp https://huggingface.co/AbdulElahGwaith/FreeCAD/resolve/main/src/Gui/Navigation/RevitNavigationStyle.cpp
13.3 kB
| // SPDX-License-Identifier: LGPL-2.1-or-later | |
| /*************************************************************************** | |
| * Copyright (c) 2011 Werner Mayer <wmayer[at]users.sourceforge.net> * | |
| * * | |
| * This file is part of the FreeCAD CAx development system. * | |
| * * | |
| * This library is free software; you can redistribute it and/or * | |
| * modify it under the terms of the GNU Library General Public * | |
| * License as published by the Free Software Foundation; either * | |
| * version 2 of the License, or (at your option) any later version. * | |
| * * | |
| * This library is distributed in the hope that it will be useful, * | |
| * but WITHOUT ANY WARRANTY; without even the implied warranty of * | |
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * | |
| * GNU Library General Public License for more details. * | |
| * * | |
| * You should have received a copy of the GNU Library General Public * | |
| * License along with this library; see the file COPYING.LIB. If not, * | |
| * write to the Free Software Foundation, Inc., 59 Temple Place, * | |
| * Suite 330, Boston, MA 02111-1307, USA * | |
| * * | |
| ***************************************************************************/ | |
| using namespace Gui; | |
| // ---------------------------------------------------------------------------------- | |
| /* TRANSLATOR Gui::RevitNavigationStyle */ | |
| TYPESYSTEM_SOURCE(Gui::RevitNavigationStyle, Gui::UserNavigationStyle) | |
| RevitNavigationStyle::RevitNavigationStyle() | |
| : lockButton1(false) | |
| {} | |
| RevitNavigationStyle::~RevitNavigationStyle() = default; | |
| const char* RevitNavigationStyle::mouseButtons(ViewerMode mode) | |
| { | |
| switch (mode) { | |
| case NavigationStyle::SELECTION: | |
| return QT_TR_NOOP("Press left mouse button"); | |
| case NavigationStyle::PANNING: | |
| return QT_TR_NOOP("Press middle mouse button"); | |
| case NavigationStyle::DRAGGING: | |
| return QT_TR_NOOP("Press Shift and middle mouse button"); | |
| case NavigationStyle::ZOOMING: | |
| return QT_TR_NOOP("Scroll middle mouse button"); | |
| default: | |
| return "No description"; | |
| } | |
| } | |
| SbBool RevitNavigationStyle::processSoEvent(const SoEvent* const ev) | |
| { | |
| // Events when in "ready-to-seek" mode are ignored, except those | |
| // which influence the seek mode itself -- these are handled further | |
| // up the inheritance hierarchy. | |
| if (this->isSeekMode()) { | |
| return inherited::processSoEvent(ev); | |
| } | |
| // Switch off viewing mode (Bug #0000911) | |
| if (!this->isSeekMode() && !this->isAnimating() && this->isViewing()) { | |
| this->setViewing(false); // by default disable viewing mode to render the scene | |
| } | |
| const SoType type(ev->getTypeId()); | |
| const SbViewportRegion& vp = viewer->getSoRenderManager()->getViewportRegion(); | |
| const SbVec2s pos(ev->getPosition()); | |
| const SbVec2f posn = normalizePixelPos(pos); | |
| const SbVec2f prevnormalized = this->lastmouseposition; | |
| this->lastmouseposition = posn; | |
| // Set to true if any event processing happened. Note that it is not | |
| // necessary to restrict ourselves to only do one "action" for an | |
| // event, we only need this flag to see if any processing happened | |
| // at all. | |
| SbBool processed = false; | |
| const ViewerMode curmode = this->currentmode; | |
| ViewerMode newmode = curmode; | |
| // Mismatches in state of the modifier keys happens if the user | |
| // presses or releases them outside the viewer window. | |
| syncModifierKeys(ev); | |
| // give the nodes in the foreground root the chance to handle events (e.g color bar) | |
| if (!viewer->isEditing()) { | |
| processed = handleEventInForeground(ev); | |
| if (processed) { | |
| return true; | |
| } | |
| } | |
| // Keyboard handling | |
| if (type.isDerivedFrom(SoKeyboardEvent::getClassTypeId())) { | |
| const auto event = static_cast<const SoKeyboardEvent*>(ev); | |
| processed = processKeyboardEvent(event); | |
| } | |
| // Mouse Button / Spaceball Button handling | |
| if (type.isDerivedFrom(SoMouseButtonEvent::getClassTypeId())) { | |
| const auto event = (const SoMouseButtonEvent*)ev; | |
| const int button = event->getButton(); | |
| const SbBool press = event->getState() == SoButtonEvent::DOWN ? true : false; | |
| // SoDebugError::postInfo("processSoEvent", "button = %d", button); | |
| switch (button) { | |
| case SoMouseButtonEvent::BUTTON1: | |
| this->lockrecenter = true; | |
| this->button1down = press; | |
| if (press && (this->currentmode == NavigationStyle::SEEK_WAIT_MODE)) { | |
| newmode = NavigationStyle::SEEK_MODE; | |
| this->seekToPoint(pos); // implicitly calls interactiveCountInc() | |
| processed = true; | |
| } | |
| else if (press | |
| && (this->currentmode == NavigationStyle::PANNING | |
| || this->currentmode == NavigationStyle::ZOOMING)) { | |
| newmode = NavigationStyle::DRAGGING; | |
| saveCursorPosition(ev); | |
| this->centerTime = ev->getTime(); | |
| processed = true; | |
| } | |
| else if (!press && (this->currentmode == NavigationStyle::DRAGGING)) { | |
| processed = true; | |
| } | |
| else if (viewer->isEditing() && (this->currentmode == NavigationStyle::SPINNING)) { | |
| processed = true; | |
| } | |
| else { | |
| processed = processClickEvent(event); | |
| } | |
| break; | |
| case SoMouseButtonEvent::BUTTON2: | |
| // If we are in edit mode then simply ignore the RMB events | |
| // to pass the event to the base class. | |
| this->lockrecenter = true; | |
| // 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()) { | |
| this->openPopupMenu(event->getPosition()); | |
| } | |
| } | |
| } | |
| // Alternative way of rotating & zooming | |
| if (press | |
| && (this->currentmode == NavigationStyle::PANNING | |
| || this->currentmode == NavigationStyle::ZOOMING)) { | |
| newmode = NavigationStyle::DRAGGING; | |
| saveCursorPosition(ev); | |
| this->centerTime = ev->getTime(); | |
| processed = true; | |
| } | |
| this->button2down = press; | |
| break; | |
| case SoMouseButtonEvent::BUTTON3: | |
| if (press) { | |
| this->centerTime = ev->getTime(); | |
| setupPanningPlane(getCamera()); | |
| this->lockrecenter = false; | |
| } | |
| else { | |
| SbTime tmp = (ev->getTime() - this->centerTime); | |
| float dci = (float)QApplication::doubleClickInterval() / 1000.0f; | |
| // is it just a middle click? | |
| if (tmp.getValue() < dci && !this->lockrecenter) { | |
| lookAtPoint(pos); | |
| processed = true; | |
| } | |
| } | |
| this->button3down = press; | |
| break; | |
| default: | |
| break; | |
| } | |
| } | |
| // Mouse Movement handling | |
| if (type.isDerivedFrom(SoLocation2Event::getClassTypeId())) { | |
| this->lockrecenter = true; | |
| const auto event = (const SoLocation2Event*)ev; | |
| if (this->currentmode == NavigationStyle::ZOOMING) { | |
| this->zoomByCursor(posn, prevnormalized); | |
| processed = true; | |
| } | |
| else if (this->currentmode == NavigationStyle::PANNING) { | |
| float ratio = vp.getViewportAspectRatio(); | |
| panCamera( | |
| viewer->getSoRenderManager()->getCamera(), | |
| ratio, | |
| this->panningplane, | |
| posn, | |
| prevnormalized | |
| ); | |
| processed = true; | |
| } | |
| else if (this->currentmode == NavigationStyle::DRAGGING) { | |
| this->addToLog(event->getPosition(), event->getTime()); | |
| this->spin(posn); | |
| moveCursorPosition(); | |
| processed = true; | |
| } | |
| } | |
| // Spaceball & Joystick handling | |
| if (type.isDerivedFrom(SoMotion3Event::getClassTypeId())) { | |
| const auto event = static_cast<const SoMotion3Event*>(ev); | |
| if (event) { | |
| this->processMotionEvent(event); | |
| } | |
| processed = true; | |
| } | |
| enum | |
| { | |
| BUTTON1DOWN = 1 << 0, | |
| BUTTON3DOWN = 1 << 1, | |
| CTRLDOWN = 1 << 2, | |
| SHIFTDOWN = 1 << 3, | |
| BUTTON2DOWN = 1 << 4 | |
| }; | |
| unsigned int combo = (this->button1down ? BUTTON1DOWN : 0) | |
| | (this->button2down ? BUTTON2DOWN : 0) | (this->button3down ? BUTTON3DOWN : 0) | |
| | (this->ctrldown ? CTRLDOWN : 0) | (this->shiftdown ? SHIFTDOWN : 0); | |
| switch (combo) { | |
| case 0: | |
| if (curmode == NavigationStyle::SPINNING) { | |
| break; | |
| } | |
| newmode = NavigationStyle::IDLE; | |
| // The left mouse button has been released right now | |
| if (this->lockButton1) { | |
| this->lockButton1 = false; | |
| if (curmode != NavigationStyle::SELECTION) { | |
| processed = true; | |
| } | |
| } | |
| break; | |
| case BUTTON1DOWN: | |
| case CTRLDOWN | BUTTON1DOWN: | |
| // make sure not to change the selection when stopping spinning | |
| if (curmode == NavigationStyle::SPINNING | |
| || (this->lockButton1 && curmode != NavigationStyle::SELECTION)) { | |
| newmode = NavigationStyle::IDLE; | |
| } | |
| else { | |
| newmode = NavigationStyle::SELECTION; | |
| } | |
| break; | |
| case BUTTON1DOWN | BUTTON2DOWN: | |
| case BUTTON3DOWN: | |
| newmode = NavigationStyle::PANNING; | |
| break; | |
| case SHIFTDOWN | BUTTON3DOWN: | |
| if (newmode != NavigationStyle::DRAGGING) { | |
| saveCursorPosition(ev); | |
| } | |
| newmode = NavigationStyle::DRAGGING; | |
| break; | |
| case CTRLDOWN | SHIFTDOWN | BUTTON2DOWN: | |
| case CTRLDOWN | BUTTON3DOWN: | |
| newmode = NavigationStyle::ZOOMING; | |
| break; | |
| default: | |
| // Reset mode to IDLE when button 3 is released | |
| // This stops the DRAGGING when button 3 is released but SHIFT is still pressed | |
| // This stops the ZOOMING when button 3 is released but CTRL is still pressed | |
| if ((curmode == NavigationStyle::DRAGGING || curmode == NavigationStyle::ZOOMING) | |
| && !this->button3down) { | |
| newmode = NavigationStyle::IDLE; | |
| } | |
| 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) { | |
| if (!button1down || !button2down) { // Allow canceling rubber-band in sketcher if both | |
| // button 1 and button 2 are pressed | |
| newmode = NavigationStyle::SELECTION; | |
| } | |
| processed = false; | |
| } | |
| // Reset flags when newmode is IDLE and the buttons are released | |
| if (newmode == IDLE && !button1down && !button2down && !button3down) { | |
| hasPanned = false; | |
| hasDragged = false; | |
| hasZoomed = false; | |
| } | |
| if (newmode != curmode) { | |
| this->setViewingMode(newmode); | |
| } | |
| // If not handled in this class, pass on upwards in the inheritance | |
| // hierarchy. | |
| if (!processed) { | |
| processed = inherited::processSoEvent(ev); | |
| } | |
| return processed; | |
| } | |