From 00e05045df0dc9315cf6ee214db9dbaaac82a781 Mon Sep 17 00:00:00 2001 From: wmayer Date: Wed, 23 Apr 2025 13:49:23 +0200 Subject: [PATCH] Gui: Refactor navigation styles Derive SiemensNXStyle from NavigationStateChart --- src/Gui/CMakeLists.txt | 1 + src/Gui/Navigation/NavigationStyle.h | 30 ----- src/Gui/Navigation/SiemensNXStyle.cpp | 180 +------------------------- src/Gui/Navigation/SiemensNXStyle.h | 63 +++++++++ src/Gui/SoFCDB.cpp | 2 +- 5 files changed, 71 insertions(+), 205 deletions(-) create mode 100644 src/Gui/Navigation/SiemensNXStyle.h diff --git a/src/Gui/CMakeLists.txt b/src/Gui/CMakeLists.txt index f793a48ebd..49391e1c2b 100644 --- a/src/Gui/CMakeLists.txt +++ b/src/Gui/CMakeLists.txt @@ -958,6 +958,7 @@ SET(Navigation_SRCS Navigation/GestureNavigationStyle.h Navigation/NavigationAnimator.h Navigation/NavigationAnimation.h + Navigation/SiemensNXStyle.h ) SOURCE_GROUP("Navigation" FILES ${Navigation_SRCS}) diff --git a/src/Gui/Navigation/NavigationStyle.h b/src/Gui/Navigation/NavigationStyle.h index e606b179b9..152b6f030a 100644 --- a/src/Gui/Navigation/NavigationStyle.h +++ b/src/Gui/Navigation/NavigationStyle.h @@ -490,36 +490,6 @@ protected: SbBool processSoEvent(const SoEvent * const ev) override; }; -class GuiExport SiemensNXStyle : public UserNavigationStyle { - using inherited = UserNavigationStyle; - - TYPESYSTEM_HEADER_WITH_OVERRIDE(); - -public: - SiemensNXStyle(); - ~SiemensNXStyle() override; - const char* mouseButtons(ViewerMode mode) override; - std::string userFriendlyName() const override; - -protected: - SbBool processSoEvent(const SoEvent * const ev) override; - SbBool processKeyboardEvent(const SoKeyboardEvent * const event) override; - -private: - struct Event; - struct NaviMachine; - struct IdleState; - struct AwaitingReleaseState; - struct AwaitingMoveState; - struct InteractState; - struct RotateState; - struct PanState; - struct ZoomState; - struct SelectionState; - - std::unique_ptr naviMachine; -}; - } // namespace Gui // NOLINTEND(cppcoreguidelines-avoid*, readability-avoid-const-params-in-decls) diff --git a/src/Gui/Navigation/SiemensNXStyle.cpp b/src/Gui/Navigation/SiemensNXStyle.cpp index 4420321e26..98721dee98 100644 --- a/src/Gui/Navigation/SiemensNXStyle.cpp +++ b/src/Gui/Navigation/SiemensNXStyle.cpp @@ -32,7 +32,7 @@ #include #include "Camera.h" -#include "NavigationStyle.h" +#include "SiemensNXStyle.h" #include "View3DInventorViewer.h" // NOLINTBEGIN(cppcoreguidelines-pro-type-static-cast-downcast, @@ -40,98 +40,9 @@ // readability-avoid-const-params-in-decls) using namespace Gui; namespace sc = boost::statechart; +using SC = NavigationStateChart; using NS = SiemensNXStyle; -struct NS::Event: public sc::event -{ - Event() : flags(new Flags){} - using Button = SoMouseButtonEvent::Button; - using Key = SoKeyboardEvent::Key; - bool isMouseButtonEvent() const { - return this->inventor_event->isOfType(SoMouseButtonEvent::getClassTypeId()); - } - const SoMouseButtonEvent* asMouseButtonEvent() const { - return static_cast(this->inventor_event); - } - bool isPress(Button button) const { - return SoMouseButtonEvent::isButtonPressEvent(this->inventor_event, button); - } - bool isRelease(Button button) const { - return SoMouseButtonEvent::isButtonReleaseEvent(this->inventor_event, button); - } - bool isKeyPress(Key key) const { - return SoKeyboardEvent::isKeyPressEvent(this->inventor_event, key); - } - bool isKeyRelease(Key key) const { - return SoKeyboardEvent::isKeyReleaseEvent(this->inventor_event, key); - } - bool isKeyboardEvent() const { - return this->inventor_event->isOfType(SoKeyboardEvent::getClassTypeId()); - } - const SoKeyboardEvent* asKeyboardEvent() const { - return static_cast(this->inventor_event); - } - bool isLocation2Event() const { - return this->inventor_event->isOfType(SoLocation2Event::getClassTypeId()); - } - const SoLocation2Event* asLocation2Event() const { - return static_cast(this->inventor_event); - } - bool isMotion3Event() const { - return this->inventor_event->isOfType(SoMotion3Event::getClassTypeId()); - } - const SoMotion3Event* asMotion3Event() const { - return static_cast(this->inventor_event); - } - bool isDownButton(unsigned int state) const { - return mbstate() == state; - } - bool isDownNoButton() const { - return mbstate() == 0; - } - bool isDownButton1() const { - return (mbstate() & BUTTON1DOWN) == BUTTON1DOWN; - } - bool isDownButton2() const { - return (mbstate() & BUTTON2DOWN) == BUTTON2DOWN; - } - bool isDownButton3() const { - return (mbstate() & BUTTON3DOWN) == BUTTON3DOWN; - } - bool isDownControl() const { - return (kbstate() & CTRLDOWN) == CTRLDOWN; - } - bool isDownShift() const { - return (kbstate() & SHIFTDOWN) == SHIFTDOWN; - } - bool isDownAlt() const { - return (kbstate() & ALTDOWN) == ALTDOWN; - } - - enum { - // bits: 0-shift-ctrl-alt-0-lmb-mmb-rmb - BUTTON1DOWN = 0x00000100, - BUTTON2DOWN = 0x00000001, - BUTTON3DOWN = 0x00000010, - CTRLDOWN = 0x00100000, - SHIFTDOWN = 0x01000000, - ALTDOWN = 0x00010000, - MASKBUTTONS = BUTTON1DOWN | BUTTON2DOWN | BUTTON3DOWN, - MASKMODIFIERS = CTRLDOWN | SHIFTDOWN | ALTDOWN - }; - - const SoEvent* inventor_event{nullptr}; - unsigned int modifiers{0}; - unsigned int mbstate() const {return modifiers & MASKBUTTONS;} - unsigned int kbstate() const {return modifiers & MASKMODIFIERS;} - - struct Flags{ - bool processed = false; - bool propagated = false; - }; - std::shared_ptr flags; -}; - struct NS::NaviMachine: public sc::state_machine { using superclass = sc::state_machine; @@ -141,13 +52,13 @@ struct NS::NaviMachine: public sc::state_machine struct NS::IdleState: public sc::state { - using reactions = sc::custom_reaction; + using reactions = sc::custom_reaction; explicit IdleState(my_context ctx) : my_base(ctx) { auto &ns = this->outermost_context().ns; ns.setViewingMode(NavigationStyle::IDLE); } - sc::result react(const NS::Event& ev) + sc::result react(const SC::Event& ev) { auto &ns = this->outermost_context().ns; switch (ns.getViewingMode()) { @@ -194,7 +105,7 @@ struct NS::IdleState: public sc::state return transit(); } - if (ev.isDownButton(NS::Event::BUTTON3DOWN)) { + if (ev.isDownButton(SC::Event::BUTTON3DOWN)) { ev.flags->processed = true; return transit(); } @@ -490,14 +401,12 @@ struct NS::SelectionState: public sc::state TYPESYSTEM_SOURCE(Gui::SiemensNXStyle, Gui::UserNavigationStyle) SiemensNXStyle::SiemensNXStyle() - : naviMachine(new NS::NaviMachine(*this)) { - naviMachine->initiate(); + naviMachine->make_object(new NS::NaviMachine(*this)); } SiemensNXStyle::~SiemensNXStyle() { - naviMachine.reset(); } const char* SiemensNXStyle::mouseButtons(ViewerMode mode) @@ -557,83 +466,6 @@ SbBool SiemensNXStyle::processKeyboardEvent(const SoKeyboardEvent * const event) return inherited::processKeyboardEvent(event); } -SbBool SiemensNXStyle::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 - } - - // 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()) { - if (handleEventInForeground(ev)) { - return true; - } - } - - NS::Event smev; - smev.inventor_event = ev; - - // Spaceball/joystick handling - if (ev->isOfType(SoMotion3Event::getClassTypeId())){ - smev.flags->processed = true; - this->processMotionEvent(static_cast(ev)); - return true; - } - - // Keyboard handling - if (ev->isOfType(SoKeyboardEvent::getClassTypeId())) { - const auto event = static_cast(ev); - smev.flags->processed = processKeyboardEvent(event); - } - - if (smev.isMouseButtonEvent()) { - const auto button = smev.asMouseButtonEvent()->getButton(); - const SbBool press = smev.asMouseButtonEvent()->getState() == SoButtonEvent::DOWN; - switch (button) { - case SoMouseButtonEvent::BUTTON1: - this->button1down = press; - break; - case SoMouseButtonEvent::BUTTON2: - this->button2down = press; - break; - case SoMouseButtonEvent::BUTTON3: - this->button3down = press; - break; - default: - break; - } - } - - smev.modifiers = - (this->button1down ? NS::Event::BUTTON1DOWN : 0) | - (this->button2down ? NS::Event::BUTTON2DOWN : 0) | - (this->button3down ? NS::Event::BUTTON3DOWN : 0) | - (this->ctrldown ? NS::Event::CTRLDOWN : 0) | - (this->shiftdown ? NS::Event::SHIFTDOWN : 0) | - (this->altdown ? NS::Event::ALTDOWN : 0); - - if (!smev.flags->processed) { - this->naviMachine->process_event(smev); - } - - if (!smev.flags->propagated && !smev.flags->processed) { - return inherited::processSoEvent(ev); - } - - return smev.flags->processed; -} // NOLINTEND(cppcoreguidelines-pro-type-static-cast-downcast, // cppcoreguidelines-avoid*, // readability-avoid-const-params-in-decls) diff --git a/src/Gui/Navigation/SiemensNXStyle.h b/src/Gui/Navigation/SiemensNXStyle.h new file mode 100644 index 0000000000..efd36afadc --- /dev/null +++ b/src/Gui/Navigation/SiemensNXStyle.h @@ -0,0 +1,63 @@ +// SPDX-License-Identifier: LGPL-2.1-or-later + +/*************************************************************************** + * Copyright (c) 2025 Werner Mayer * + * * + * This file is part of FreeCAD. * + * * + * FreeCAD is free software: you can redistribute it and/or modify it * + * under the terms of the GNU Lesser General Public License as * + * published by the Free Software Foundation, either version 2.1 of the * + * License, or (at your option) any later version. * + * * + * FreeCAD 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 * + * Lesser General Public License for more details. * + * * + * You should have received a copy of the GNU Lesser General Public * + * License along with FreeCAD. If not, see * + * . * + * * + **************************************************************************/ + + +#ifndef GUI_SIEMENSNXSTYLE_H +#define GUI_SIEMENSNXSTYLE_H + +#include + +// NOLINTBEGIN(cppcoreguidelines-avoid*, readability-avoid-const-params-in-decls) +namespace Gui +{ + +class GuiExport SiemensNXStyle : public NavigationStateChart { + using inherited = NavigationStateChart; + + TYPESYSTEM_HEADER_WITH_OVERRIDE(); + +public: + SiemensNXStyle(); + ~SiemensNXStyle() override; + const char* mouseButtons(ViewerMode mode) override; + std::string userFriendlyName() const override; + +protected: + SbBool processKeyboardEvent(const SoKeyboardEvent * const event) override; + +private: + struct NaviMachine; + struct IdleState; + struct AwaitingReleaseState; + struct AwaitingMoveState; + struct InteractState; + struct RotateState; + struct PanState; + struct ZoomState; + struct SelectionState; +}; + +} // namespace Gui +// NOLINTEND(cppcoreguidelines-avoid*, readability-avoid-const-params-in-decls) + +#endif // GUI_SIEMENSNXSTYLE_H diff --git a/src/Gui/SoFCDB.cpp b/src/Gui/SoFCDB.cpp index 1e9e927075..ab6f365df4 100644 --- a/src/Gui/SoFCDB.cpp +++ b/src/Gui/SoFCDB.cpp @@ -53,7 +53,7 @@ #include "Inventor/Draggers/SoTransformDragger.h" #include "Navigation/GestureNavigationStyle.h" #include "Navigation/NavigationStyle.h" -#include "Navigation/NavigationStateChart.h" +#include "Navigation/SiemensNXStyle.h" #include "SelectionObject.h" #include "SoDevicePixelRatioElement.h" #include "SoFCColorBar.h"