Merge pull request #21813 from maxwxyz/siemens-nx-navigation
Navigation: Add Siemens NX style
This commit is contained in:
@@ -932,12 +932,14 @@ SET(View3D_SRCS
|
||||
SOURCE_GROUP("View3D" FILES ${View3D_SRCS})
|
||||
|
||||
SET(Navigation_CPP_SRCS
|
||||
Navigation/NavigationStateChart.cpp
|
||||
Navigation/NavigationStyle.cpp
|
||||
Navigation/NavigationStylePyImp.cpp
|
||||
Navigation/InventorNavigationStyle.cpp
|
||||
Navigation/CADNavigationStyle.cpp
|
||||
Navigation/RevitNavigationStyle.cpp
|
||||
Navigation/BlenderNavigationStyle.cpp
|
||||
Navigation/SiemensNXNavigationStyle.cpp
|
||||
Navigation/SolidWorksNavigationStyle.cpp
|
||||
Navigation/MayaGestureNavigationStyle.cpp
|
||||
Navigation/OpenCascadeNavigationStyle.cpp
|
||||
@@ -950,11 +952,13 @@ SET(Navigation_CPP_SRCS
|
||||
)
|
||||
SET(Navigation_SRCS
|
||||
${Navigation_CPP_SRCS}
|
||||
Navigation/NavigationStateChart.h
|
||||
Navigation/NavigationStyle.h
|
||||
Navigation/NavigationStyle.pyi
|
||||
Navigation/GestureNavigationStyle.h
|
||||
Navigation/NavigationAnimator.h
|
||||
Navigation/NavigationAnimation.h
|
||||
Navigation/SiemensNXNavigationStyle.h
|
||||
)
|
||||
SOURCE_GROUP("Navigation" FILES ${Navigation_SRCS})
|
||||
|
||||
|
||||
231
src/Gui/Navigation/NavigationStateChart.cpp
Normal file
231
src/Gui/Navigation/NavigationStateChart.cpp
Normal file
@@ -0,0 +1,231 @@
|
||||
// SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
|
||||
/***************************************************************************
|
||||
* Copyright (c) 2025 Werner Mayer <wmayer[at]users.sourceforge.net> *
|
||||
* *
|
||||
* 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 *
|
||||
* <https://www.gnu.org/licenses/>. *
|
||||
* *
|
||||
**************************************************************************/
|
||||
|
||||
|
||||
#include "PreCompiled.h"
|
||||
#include <boost/statechart/custom_reaction.hpp>
|
||||
#include <boost/statechart/state_machine.hpp>
|
||||
#include <boost/statechart/state.hpp>
|
||||
|
||||
#include "Camera.h"
|
||||
#include "NavigationStateChart.h"
|
||||
#include "View3DInventorViewer.h"
|
||||
|
||||
|
||||
using namespace Gui;
|
||||
namespace sc = boost::statechart;
|
||||
using NS = NavigationStateChart;
|
||||
|
||||
NS::Event::Event() : flags(new Flags)
|
||||
{}
|
||||
|
||||
bool NS::Event::isMouseButtonEvent() const
|
||||
{
|
||||
return this->inventor_event->isOfType(SoMouseButtonEvent::getClassTypeId());
|
||||
}
|
||||
|
||||
const SoMouseButtonEvent* NS::Event::asMouseButtonEvent() const
|
||||
{
|
||||
return static_cast<const SoMouseButtonEvent*>(this->inventor_event);
|
||||
}
|
||||
|
||||
bool NS::Event::isPress(Button button) const
|
||||
{
|
||||
return SoMouseButtonEvent::isButtonPressEvent(this->inventor_event, button);
|
||||
}
|
||||
|
||||
bool NS::Event::isRelease(Button button) const
|
||||
{
|
||||
return SoMouseButtonEvent::isButtonReleaseEvent(this->inventor_event, button);
|
||||
}
|
||||
|
||||
bool NS::Event::isKeyPress(Key key) const
|
||||
{
|
||||
return SoKeyboardEvent::isKeyPressEvent(this->inventor_event, key);
|
||||
}
|
||||
|
||||
bool NS::Event::isKeyRelease(Key key) const
|
||||
{
|
||||
return SoKeyboardEvent::isKeyReleaseEvent(this->inventor_event, key);
|
||||
}
|
||||
|
||||
bool NS::Event::isKeyboardEvent() const
|
||||
{
|
||||
return this->inventor_event->isOfType(SoKeyboardEvent::getClassTypeId());
|
||||
}
|
||||
|
||||
const SoKeyboardEvent* NS::Event::asKeyboardEvent() const
|
||||
{
|
||||
return static_cast<const SoKeyboardEvent*>(this->inventor_event);
|
||||
}
|
||||
|
||||
bool NS::Event::isLocation2Event() const
|
||||
{
|
||||
return this->inventor_event->isOfType(SoLocation2Event::getClassTypeId());
|
||||
}
|
||||
|
||||
const SoLocation2Event* NS::Event::asLocation2Event() const
|
||||
{
|
||||
return static_cast<const SoLocation2Event*>(this->inventor_event);
|
||||
}
|
||||
|
||||
bool NS::Event::isMotion3Event() const
|
||||
{
|
||||
return this->inventor_event->isOfType(SoMotion3Event::getClassTypeId());
|
||||
}
|
||||
|
||||
const SoMotion3Event* NS::Event::asMotion3Event() const
|
||||
{
|
||||
return static_cast<const SoMotion3Event*>(this->inventor_event);
|
||||
}
|
||||
|
||||
bool NS::Event::isDownButton(unsigned int state) const
|
||||
{
|
||||
return mbstate() == state;
|
||||
}
|
||||
|
||||
bool NS::Event::isDownNoButton() const
|
||||
{
|
||||
return mbstate() == 0;
|
||||
}
|
||||
|
||||
bool NS::Event::isDownButton1() const
|
||||
{
|
||||
return (mbstate() & BUTTON1DOWN) == BUTTON1DOWN;
|
||||
}
|
||||
|
||||
bool NS::Event::isDownButton2() const
|
||||
{
|
||||
return (mbstate() & BUTTON2DOWN) == BUTTON2DOWN;
|
||||
}
|
||||
|
||||
bool NS::Event::isDownButton3() const
|
||||
{
|
||||
return (mbstate() & BUTTON3DOWN) == BUTTON3DOWN;
|
||||
}
|
||||
|
||||
bool NS::Event::isDownControl() const
|
||||
{
|
||||
return (kbstate() & CTRLDOWN) == CTRLDOWN;
|
||||
}
|
||||
|
||||
bool NS::Event::isDownShift() const
|
||||
{
|
||||
return (kbstate() & SHIFTDOWN) == SHIFTDOWN;
|
||||
}
|
||||
|
||||
bool NS::Event::isDownAlt() const
|
||||
{
|
||||
return (kbstate() & ALTDOWN) == ALTDOWN;
|
||||
}
|
||||
|
||||
|
||||
/* TRANSLATOR Gui::NavigationStateChart */
|
||||
|
||||
TYPESYSTEM_SOURCE_ABSTRACT(Gui::NavigationStateChart, Gui::UserNavigationStyle)
|
||||
|
||||
NavigationStateChart::NavigationStateChart()
|
||||
{}
|
||||
|
||||
NavigationStateChart::~NavigationStateChart()
|
||||
{
|
||||
naviMachine.reset();
|
||||
}
|
||||
|
||||
SbBool NavigationStateChart::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<const SoMotion3Event*>(ev));
|
||||
return true;
|
||||
}
|
||||
|
||||
// Keyboard handling
|
||||
if (ev->isOfType(SoKeyboardEvent::getClassTypeId())) {
|
||||
const auto event = static_cast<const SoKeyboardEvent *>(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;
|
||||
}
|
||||
142
src/Gui/Navigation/NavigationStateChart.h
Normal file
142
src/Gui/Navigation/NavigationStateChart.h
Normal file
@@ -0,0 +1,142 @@
|
||||
// SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
|
||||
/***************************************************************************
|
||||
* Copyright (c) 2025 Werner Mayer <wmayer[at]users.sourceforge.net> *
|
||||
* *
|
||||
* 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 *
|
||||
* <https://www.gnu.org/licenses/>. *
|
||||
* *
|
||||
**************************************************************************/
|
||||
|
||||
|
||||
#ifndef GUI_NAVIGATIONSTATECHART_H
|
||||
#define GUI_NAVIGATIONSTATECHART_H
|
||||
|
||||
#include <boost/statechart/event.hpp>
|
||||
#include <Gui/Navigation/NavigationStyle.h>
|
||||
|
||||
// NOLINTBEGIN(cppcoreguidelines-avoid*, readability-avoid-const-params-in-decls)
|
||||
namespace Gui
|
||||
{
|
||||
|
||||
class NaviStateMachine;
|
||||
|
||||
class GuiExport NavigationStateChart : public UserNavigationStyle {
|
||||
using inherited = UserNavigationStyle;
|
||||
|
||||
TYPESYSTEM_HEADER_WITH_OVERRIDE();
|
||||
|
||||
public:
|
||||
struct Event: public boost::statechart::event<Event>
|
||||
{
|
||||
using Button = SoMouseButtonEvent::Button;
|
||||
using Key = SoKeyboardEvent::Key;
|
||||
|
||||
Event();
|
||||
bool isMouseButtonEvent() const;
|
||||
const SoMouseButtonEvent* asMouseButtonEvent() const;
|
||||
bool isPress(Button button) const;
|
||||
bool isRelease(Button button) const;
|
||||
bool isKeyPress(Key key) const;
|
||||
bool isKeyRelease(Key key) const;
|
||||
bool isKeyboardEvent() const;
|
||||
const SoKeyboardEvent* asKeyboardEvent() const;
|
||||
bool isLocation2Event() const;
|
||||
const SoLocation2Event* asLocation2Event() const;
|
||||
bool isMotion3Event() const;
|
||||
const SoMotion3Event* asMotion3Event() const;
|
||||
bool isDownButton(unsigned int state) const;
|
||||
bool isDownNoButton() const;
|
||||
bool isDownButton1() const;
|
||||
bool isDownButton2() const;
|
||||
bool isDownButton3() const;
|
||||
bool isDownControl() const;
|
||||
bool isDownShift() const;
|
||||
bool isDownAlt() const;
|
||||
|
||||
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> flags;
|
||||
};
|
||||
|
||||
NavigationStateChart();
|
||||
~NavigationStateChart() override;
|
||||
|
||||
protected:
|
||||
SbBool processSoEvent(const SoEvent * const ev) override;
|
||||
std::unique_ptr<NaviStateMachine> naviMachine; // NOLINT
|
||||
};
|
||||
|
||||
class GuiExport NaviStateMachine
|
||||
{
|
||||
public:
|
||||
NaviStateMachine(const NaviStateMachine&) = delete;
|
||||
NaviStateMachine(NaviStateMachine&&) = delete;
|
||||
NaviStateMachine& operator= (const NaviStateMachine&) = delete;
|
||||
NaviStateMachine& operator= (NaviStateMachine&&) = delete;
|
||||
|
||||
NaviStateMachine() = default;
|
||||
virtual ~NaviStateMachine() = default;
|
||||
|
||||
virtual void process_event(const NavigationStateChart::Event&) = 0;
|
||||
};
|
||||
|
||||
template< typename T >
|
||||
class NaviStateMachineT : public NaviStateMachine
|
||||
{
|
||||
public:
|
||||
explicit NaviStateMachineT(T* t) : object(t)
|
||||
{
|
||||
object->initiate();
|
||||
}
|
||||
|
||||
~NaviStateMachineT() override
|
||||
{
|
||||
object.reset();
|
||||
}
|
||||
|
||||
void process_event(const NavigationStateChart::Event& ev) override
|
||||
{
|
||||
object->process_event(ev);
|
||||
}
|
||||
|
||||
private:
|
||||
std::unique_ptr<T> object;
|
||||
};
|
||||
|
||||
} // namespace Gui
|
||||
// NOLINTEND(cppcoreguidelines-avoid*, readability-avoid-const-params-in-decls)
|
||||
|
||||
#endif // GUI_NAVIGATIONSTATECHART_H
|
||||
@@ -51,6 +51,7 @@ class SoCamera;
|
||||
class SoSensor;
|
||||
class SbSphereSheetProjector;
|
||||
|
||||
// NOLINTBEGIN(cppcoreguidelines-avoid*, readability-avoid-const-params-in-decls)
|
||||
namespace Gui {
|
||||
|
||||
class View3DInventorViewer;
|
||||
@@ -490,6 +491,7 @@ protected:
|
||||
};
|
||||
|
||||
} // namespace Gui
|
||||
// NOLINTEND(cppcoreguidelines-avoid*, readability-avoid-const-params-in-decls)
|
||||
|
||||
Q_DECLARE_OPERATORS_FOR_FLAGS(Gui::NavigationStyle::RotationCenterModes)
|
||||
|
||||
|
||||
471
src/Gui/Navigation/SiemensNXNavigationStyle.cpp
Normal file
471
src/Gui/Navigation/SiemensNXNavigationStyle.cpp
Normal file
@@ -0,0 +1,471 @@
|
||||
// SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
|
||||
/***************************************************************************
|
||||
* Copyright (c) 2025 Werner Mayer <wmayer[at]users.sourceforge.net> *
|
||||
* *
|
||||
* 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 *
|
||||
* <https://www.gnu.org/licenses/>. *
|
||||
* *
|
||||
**************************************************************************/
|
||||
|
||||
|
||||
#include "PreCompiled.h"
|
||||
#ifndef _PreComp_
|
||||
#include <QApplication>
|
||||
#endif
|
||||
|
||||
#include <boost/statechart/custom_reaction.hpp>
|
||||
#include <boost/statechart/state_machine.hpp>
|
||||
#include <boost/statechart/state.hpp>
|
||||
|
||||
#include "Camera.h"
|
||||
#include "SiemensNXNavigationStyle.h"
|
||||
#include "View3DInventorViewer.h"
|
||||
|
||||
// NOLINTBEGIN(cppcoreguidelines-pro-type-static-cast-downcast,
|
||||
// cppcoreguidelines-avoid*,
|
||||
// readability-avoid-const-params-in-decls)
|
||||
using namespace Gui;
|
||||
namespace sc = boost::statechart;
|
||||
using SC = NavigationStateChart;
|
||||
using NS = SiemensNXNavigationStyle;
|
||||
|
||||
struct NS::NaviMachine: public sc::state_machine<NS::NaviMachine, NS::IdleState>
|
||||
{
|
||||
using superclass = sc::state_machine<NS::NaviMachine, NS::IdleState>;
|
||||
explicit NaviMachine(NS& ns) : ns(ns) {}
|
||||
NS& ns;
|
||||
};
|
||||
|
||||
struct NS::IdleState: public sc::state<NS::IdleState, NS::NaviMachine>
|
||||
{
|
||||
using reactions = sc::custom_reaction<SC::Event>;
|
||||
explicit IdleState(my_context ctx) : my_base(ctx)
|
||||
{
|
||||
auto &ns = this->outermost_context().ns;
|
||||
ns.setViewingMode(NavigationStyle::IDLE);
|
||||
}
|
||||
sc::result react(const SC::Event& ev)
|
||||
{
|
||||
auto &ns = this->outermost_context().ns;
|
||||
switch (ns.getViewingMode()) {
|
||||
case NavigationStyle::SEEK_WAIT_MODE:
|
||||
{
|
||||
if (ev.isPress(SoMouseButtonEvent::BUTTON1)) {
|
||||
ns.seekToPoint(ev.inventor_event->getPosition());
|
||||
ns.setViewingMode(NavigationStyle::SEEK_MODE);
|
||||
ev.flags->processed = true;
|
||||
return transit<NS::AwaitingReleaseState>();
|
||||
}
|
||||
break;
|
||||
}
|
||||
case NavigationStyle::SPINNING:
|
||||
case NavigationStyle::SEEK_MODE:
|
||||
{
|
||||
if (!ev.flags->processed) {
|
||||
if (ev.isMouseButtonEvent()) {
|
||||
ev.flags->processed = true;
|
||||
return transit<NS::AwaitingReleaseState>();
|
||||
}
|
||||
else if (ev.isKeyboardEvent() || ev.isMotion3Event()) {
|
||||
ns.setViewingMode(NavigationStyle::IDLE);
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case NavigationStyle::BOXZOOM:
|
||||
return forward_event();
|
||||
}
|
||||
|
||||
// right-click
|
||||
if (ev.isRelease(SoMouseButtonEvent::BUTTON2)
|
||||
&& ev.mbstate() == 0
|
||||
&& !ns.viewer->isEditing()
|
||||
&& ns.isPopupMenuEnabled()){
|
||||
ns.openPopupMenu(ev.inventor_event->getPosition());
|
||||
}
|
||||
|
||||
if (ev.isPress(SoMouseButtonEvent::BUTTON3)) {
|
||||
if (ev.isDownShift()) {
|
||||
ev.flags->processed = true;
|
||||
return transit<NS::PanState>();
|
||||
}
|
||||
|
||||
if (ev.isDownButton(SC::Event::BUTTON3DOWN)) {
|
||||
ev.flags->processed = true;
|
||||
return transit<NS::AwaitingMoveState>();
|
||||
}
|
||||
}
|
||||
|
||||
// Use processClickEvent()
|
||||
|
||||
// Implement selection callback
|
||||
//if (ev.isLocation2Event() && ev.isDownButton1()) {
|
||||
// ev.flags->processed = true;
|
||||
// return transit<NS::SelectionState>();
|
||||
//}
|
||||
|
||||
return forward_event();
|
||||
}
|
||||
};
|
||||
|
||||
struct NS::AwaitingReleaseState : public sc::state<NS::AwaitingReleaseState, NS::NaviMachine>
|
||||
{
|
||||
using reactions = sc::custom_reaction<NS::Event>;
|
||||
explicit AwaitingReleaseState(my_context ctx) : my_base(ctx)
|
||||
{}
|
||||
|
||||
sc::result react(const NS::Event& /*ev*/)
|
||||
{
|
||||
return forward_event();
|
||||
}
|
||||
};
|
||||
|
||||
struct NS::InteractState: public sc::state<NS::InteractState, NS::NaviMachine>
|
||||
{
|
||||
using reactions = sc::custom_reaction<NS::Event>;
|
||||
explicit InteractState(my_context ctx):my_base(ctx)
|
||||
{
|
||||
auto &ns = this->outermost_context().ns;
|
||||
ns.setViewingMode(NavigationStyle::INTERACT);
|
||||
}
|
||||
|
||||
sc::result react(const NS::Event& /*ev*/) {
|
||||
return forward_event();
|
||||
}
|
||||
};
|
||||
|
||||
struct NS::AwaitingMoveState: public sc::state<NS::AwaitingMoveState, NS::NaviMachine>
|
||||
{
|
||||
using reactions = sc::custom_reaction<NS::Event>;
|
||||
|
||||
private:
|
||||
SbVec2s base_pos;
|
||||
SbTime since;
|
||||
|
||||
public:
|
||||
explicit AwaitingMoveState(my_context ctx):my_base(ctx)
|
||||
{
|
||||
auto &ns = this->outermost_context().ns;
|
||||
ns.setViewingMode(NavigationStyle::DRAGGING);
|
||||
this->base_pos = static_cast<const NS::Event*>(this->triggering_event())->inventor_event->getPosition();
|
||||
this->since = static_cast<const NS::Event*>(this->triggering_event())->inventor_event->getTime();
|
||||
}
|
||||
sc::result react(const NS::Event& ev){
|
||||
//this state consumes all mouse events.
|
||||
ev.flags->processed = ev.isMouseButtonEvent() || ev.isLocation2Event();
|
||||
|
||||
if (ev.isLocation2Event()) {
|
||||
return transit<NS::RotateState>();
|
||||
}
|
||||
|
||||
// right-click
|
||||
if (ev.isPress(SoMouseButtonEvent::BUTTON2) && ev.isDownButton3()) {
|
||||
return transit<NS::PanState>();
|
||||
}
|
||||
|
||||
if (ev.isKeyPress(SoKeyboardEvent::LEFT_SHIFT)) {
|
||||
ev.flags->processed = true;
|
||||
return transit<NS::PanState>();
|
||||
}
|
||||
|
||||
// left-click
|
||||
if (ev.isPress(SoMouseButtonEvent::BUTTON1) && ev.isDownButton3()) {
|
||||
return transit<NS::ZoomState>();
|
||||
}
|
||||
|
||||
if (ev.isKeyPress(SoKeyboardEvent::LEFT_CONTROL)) {
|
||||
ev.flags->processed = true;
|
||||
return transit<NS::ZoomState>();
|
||||
}
|
||||
|
||||
// middle-click
|
||||
if (ev.isRelease(SoMouseButtonEvent::BUTTON3) && ev.isDownNoButton()) {
|
||||
auto &ns = this->outermost_context().ns;
|
||||
SbTime tmp = (ev.inventor_event->getTime() - this->since);
|
||||
double dci = QApplication::doubleClickInterval() / 1000.0;
|
||||
|
||||
// is this a simple middle click?
|
||||
if (tmp.getValue() < dci) {
|
||||
ev.flags->processed = true;
|
||||
SbVec2s pos = ev.inventor_event->getPosition();
|
||||
ns.lookAtPoint(pos);
|
||||
}
|
||||
return transit<NS::IdleState>();
|
||||
}
|
||||
|
||||
return forward_event();
|
||||
}
|
||||
};
|
||||
|
||||
struct NS::RotateState: public sc::state<NS::RotateState, NS::NaviMachine>
|
||||
{
|
||||
using reactions = sc::custom_reaction<NS::Event>;
|
||||
explicit RotateState(my_context ctx) : my_base(ctx)
|
||||
{
|
||||
auto &ns = this->outermost_context().ns;
|
||||
const auto inventorEvent = static_cast<const NS::Event*>(this->triggering_event())->inventor_event;
|
||||
ns.saveCursorPosition(inventorEvent);
|
||||
ns.setViewingMode(NavigationStyle::DRAGGING);
|
||||
this->base_pos = inventorEvent->getPosition();
|
||||
}
|
||||
|
||||
sc::result react(const NS::Event& ev)
|
||||
{
|
||||
if (ev.isLocation2Event()) {
|
||||
auto &ns = this->outermost_context().ns;
|
||||
ns.addToLog(ev.inventor_event->getPosition(), ev.inventor_event->getTime());
|
||||
const SbVec2s pos = ev.inventor_event->getPosition();
|
||||
const SbVec2f posn = ns.normalizePixelPos(pos);
|
||||
ns.spin(posn);
|
||||
ns.moveCursorPosition();
|
||||
ev.flags->processed = true;
|
||||
}
|
||||
|
||||
// right-click
|
||||
if (ev.isPress(SoMouseButtonEvent::BUTTON2) && ev.isDownButton3()) {
|
||||
ev.flags->processed = true;
|
||||
return transit<NS::PanState>();
|
||||
}
|
||||
|
||||
if (ev.isKeyPress(SoKeyboardEvent::LEFT_SHIFT)) {
|
||||
ev.flags->processed = true;
|
||||
return transit<NS::PanState>();
|
||||
}
|
||||
|
||||
// left-click
|
||||
if (ev.isPress(SoMouseButtonEvent::BUTTON1) && ev.isDownButton3()) {
|
||||
ev.flags->processed = true;
|
||||
return transit<NS::ZoomState>();
|
||||
}
|
||||
|
||||
if (ev.isKeyPress(SoKeyboardEvent::LEFT_CONTROL)) {
|
||||
ev.flags->processed = true;
|
||||
return transit<NS::ZoomState>();
|
||||
}
|
||||
|
||||
if (ev.isRelease(SoMouseButtonEvent::BUTTON3) && ev.isDownNoButton()) {
|
||||
ev.flags->processed = true;
|
||||
return transit<NS::IdleState>();
|
||||
}
|
||||
return forward_event();
|
||||
}
|
||||
|
||||
private:
|
||||
SbVec2s base_pos;
|
||||
};
|
||||
|
||||
struct NS::PanState: public sc::state<NS::PanState, NS::NaviMachine>
|
||||
{
|
||||
using reactions = sc::custom_reaction<NS::Event>;
|
||||
explicit PanState(my_context ctx):my_base(ctx)
|
||||
{
|
||||
auto &ns = this->outermost_context().ns;
|
||||
const NS::Event* ev = static_cast<const NS::Event*>(this->triggering_event());
|
||||
ns.setViewingMode(NavigationStyle::PANNING);
|
||||
this->base_pos = ev->inventor_event->getPosition();
|
||||
this->ratio = ns.viewer->getSoRenderManager()->getViewportRegion().getViewportAspectRatio();
|
||||
ns.centerTime = ev->inventor_event->getTime();
|
||||
ns.setupPanningPlane(ns.getCamera());
|
||||
}
|
||||
sc::result react(const NS::Event& ev)
|
||||
{
|
||||
if (ev.isLocation2Event()){
|
||||
ev.flags->processed = true;
|
||||
SbVec2s pos = ev.inventor_event->getPosition();
|
||||
auto &ns = this->outermost_context().ns;
|
||||
ns.panCamera(ns.viewer->getSoRenderManager()->getCamera(),
|
||||
this->ratio,
|
||||
ns.panningplane,
|
||||
ns.normalizePixelPos(pos),
|
||||
ns.normalizePixelPos(this->base_pos));
|
||||
this->base_pos = pos;
|
||||
}
|
||||
|
||||
if (ev.isRelease(SoMouseButtonEvent::BUTTON2) && ev.isDownButton3()) {
|
||||
ev.flags->processed = true;
|
||||
return transit<NS::RotateState>();
|
||||
}
|
||||
|
||||
if (ev.isKeyRelease(SoKeyboardEvent::LEFT_SHIFT) && ev.isDownButton3()) {
|
||||
ev.flags->processed = true;
|
||||
return transit<NS::RotateState>();
|
||||
}
|
||||
|
||||
if (ev.isRelease(SoMouseButtonEvent::BUTTON3)) {
|
||||
ev.flags->processed = true;
|
||||
return transit<NS::IdleState>();
|
||||
}
|
||||
|
||||
return forward_event();
|
||||
}
|
||||
|
||||
private:
|
||||
SbVec2s base_pos;
|
||||
float ratio {1.0F};
|
||||
};
|
||||
|
||||
struct NS::ZoomState: public sc::state<NS::ZoomState, NS::NaviMachine>
|
||||
{
|
||||
using reactions = sc::custom_reaction<NS::Event>;
|
||||
explicit ZoomState(my_context ctx) : my_base(ctx)
|
||||
{
|
||||
auto &ns = this->outermost_context().ns;
|
||||
const NS::Event* ev = static_cast<const NS::Event*>(this->triggering_event());
|
||||
ns.setViewingMode(NavigationStyle::ZOOMING);
|
||||
this->base_pos = ev->inventor_event->getPosition();
|
||||
}
|
||||
|
||||
sc::result react(const NS::Event& ev)
|
||||
{
|
||||
if (ev.isLocation2Event()){
|
||||
ev.flags->processed = true;
|
||||
SbVec2s pos = ev.inventor_event->getPosition();
|
||||
auto &ns = this->outermost_context().ns;
|
||||
ns.zoomByCursor(ns.normalizePixelPos(pos),
|
||||
ns.normalizePixelPos(this->base_pos));
|
||||
this->base_pos = pos;
|
||||
}
|
||||
|
||||
if (ev.isRelease(SoMouseButtonEvent::BUTTON1) && ev.isDownButton3()) {
|
||||
ev.flags->processed = true;
|
||||
return transit<NS::RotateState>();
|
||||
}
|
||||
|
||||
if (ev.isKeyRelease(SoKeyboardEvent::LEFT_CONTROL) && ev.isDownButton3()) {
|
||||
ev.flags->processed = true;
|
||||
return transit<NS::RotateState>();
|
||||
}
|
||||
|
||||
if (ev.isRelease(SoMouseButtonEvent::BUTTON3)) {
|
||||
ev.flags->processed = true;
|
||||
return transit<NS::IdleState>();
|
||||
}
|
||||
|
||||
return forward_event();
|
||||
}
|
||||
|
||||
private:
|
||||
SbVec2s base_pos;
|
||||
};
|
||||
|
||||
struct NS::SelectionState: public sc::state<NS::SelectionState, NS::NaviMachine>
|
||||
{
|
||||
using reactions = sc::custom_reaction<NS::Event>;
|
||||
explicit SelectionState(my_context ctx) : my_base(ctx)
|
||||
{
|
||||
auto &ns = this->outermost_context().ns;
|
||||
const NS::Event* ev = static_cast<const NS::Event*>(this->triggering_event());
|
||||
|
||||
ns.setViewingMode(NavigationStyle::BOXZOOM);
|
||||
ns.startSelection(NavigationStyle::Rubberband);
|
||||
fakeLeftButtonDown(ev->inventor_event->getPosition());
|
||||
}
|
||||
|
||||
void fakeLeftButtonDown(const SbVec2s& pos)
|
||||
{
|
||||
SoMouseButtonEvent mbe;
|
||||
mbe.setButton(SoMouseButtonEvent::BUTTON1);
|
||||
mbe.setState(SoMouseButtonEvent::DOWN);
|
||||
mbe.setPosition(pos);
|
||||
|
||||
auto &ns = this->outermost_context().ns;
|
||||
ns.processEvent(&mbe);
|
||||
}
|
||||
|
||||
sc::result react(const NS::Event& /*ev*/)
|
||||
{
|
||||
// This isn't called while selection mode is active
|
||||
return transit<NS::IdleState>();
|
||||
}
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------------------
|
||||
|
||||
/* TRANSLATOR Gui::SiemensNXNavigationStyle */
|
||||
|
||||
TYPESYSTEM_SOURCE(Gui::SiemensNXNavigationStyle, Gui::UserNavigationStyle)
|
||||
|
||||
SiemensNXNavigationStyle::SiemensNXNavigationStyle()
|
||||
{
|
||||
naviMachine.reset(new NaviStateMachineT(new NaviMachine(*this)));
|
||||
}
|
||||
|
||||
SiemensNXNavigationStyle::~SiemensNXNavigationStyle()
|
||||
{
|
||||
}
|
||||
|
||||
const char* SiemensNXNavigationStyle::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+right click");
|
||||
case NavigationStyle::DRAGGING:
|
||||
return QT_TR_NOOP("Press middle mouse button");
|
||||
case NavigationStyle::ZOOMING:
|
||||
return QT_TR_NOOP("Scroll mouse wheel");
|
||||
default:
|
||||
return "No description";
|
||||
}
|
||||
}
|
||||
|
||||
std::string SiemensNXNavigationStyle::userFriendlyName() const
|
||||
{
|
||||
return {"Siemens NX"};
|
||||
}
|
||||
|
||||
SbBool SiemensNXNavigationStyle::processKeyboardEvent(const SoKeyboardEvent* const event)
|
||||
{
|
||||
// See https://forum.freecad.org/viewtopic.php?t=96459
|
||||
// Isometric view: Home key button
|
||||
// Trimetric view: End key button
|
||||
// Fit all: CTRL+F
|
||||
// Normal view: F8
|
||||
switch (event->getKey()) {
|
||||
case SoKeyboardEvent::F:
|
||||
if (event->wasCtrlDown()) {
|
||||
viewer->viewAll();
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
case SoKeyboardEvent::HOME:
|
||||
{
|
||||
viewer->setCameraOrientation(Camera::rotation(Camera::Isometric));
|
||||
return true;
|
||||
}
|
||||
case SoKeyboardEvent::END:
|
||||
{
|
||||
viewer->setCameraOrientation(Camera::rotation(Camera::Trimetric));
|
||||
return true;
|
||||
}
|
||||
case SoKeyboardEvent::F8:
|
||||
{
|
||||
viewer->setCameraOrientation(Camera::rotation(Camera::Top));
|
||||
return true;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return inherited::processKeyboardEvent(event);
|
||||
}
|
||||
|
||||
// NOLINTEND(cppcoreguidelines-pro-type-static-cast-downcast,
|
||||
// cppcoreguidelines-avoid*,
|
||||
// readability-avoid-const-params-in-decls)
|
||||
63
src/Gui/Navigation/SiemensNXNavigationStyle.h
Normal file
63
src/Gui/Navigation/SiemensNXNavigationStyle.h
Normal file
@@ -0,0 +1,63 @@
|
||||
// SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
|
||||
/***************************************************************************
|
||||
* Copyright (c) 2025 Werner Mayer <wmayer[at]users.sourceforge.net> *
|
||||
* *
|
||||
* 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 *
|
||||
* <https://www.gnu.org/licenses/>. *
|
||||
* *
|
||||
**************************************************************************/
|
||||
|
||||
|
||||
#ifndef GUI_SIEMENSNXNAVIGATIONSTYLE_H
|
||||
#define GUI_SIEMENSNXNAVIGATIONSTYLE_H
|
||||
|
||||
#include <Gui/Navigation/NavigationStateChart.h>
|
||||
|
||||
// NOLINTBEGIN(cppcoreguidelines-avoid*, readability-avoid-const-params-in-decls)
|
||||
namespace Gui
|
||||
{
|
||||
|
||||
class GuiExport SiemensNXNavigationStyle : public NavigationStateChart {
|
||||
using inherited = NavigationStateChart;
|
||||
|
||||
TYPESYSTEM_HEADER_WITH_OVERRIDE();
|
||||
|
||||
public:
|
||||
SiemensNXNavigationStyle();
|
||||
~SiemensNXNavigationStyle() 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_SIEMENSNXNAVIGATIONSTYLE_H
|
||||
@@ -53,6 +53,7 @@
|
||||
#include "Inventor/Draggers/SoTransformDragger.h"
|
||||
#include "Navigation/GestureNavigationStyle.h"
|
||||
#include "Navigation/NavigationStyle.h"
|
||||
#include "Navigation/SiemensNXNavigationStyle.h"
|
||||
#include "SelectionObject.h"
|
||||
#include "SoDevicePixelRatioElement.h"
|
||||
#include "SoFCColorBar.h"
|
||||
@@ -188,17 +189,19 @@ void Gui::SoFCDB::init()
|
||||
|
||||
NavigationStyle ::init();
|
||||
UserNavigationStyle ::init();
|
||||
InventorNavigationStyle ::init();
|
||||
CADNavigationStyle ::init();
|
||||
RevitNavigationStyle ::init();
|
||||
NavigationStateChart ::init();
|
||||
BlenderNavigationStyle ::init();
|
||||
SolidWorksNavigationStyle ::init();
|
||||
MayaGestureNavigationStyle ::init();
|
||||
TouchpadNavigationStyle ::init();
|
||||
CADNavigationStyle ::init();
|
||||
GestureNavigationStyle ::init();
|
||||
MayaGestureNavigationStyle ::init();
|
||||
OpenCascadeNavigationStyle ::init();
|
||||
InventorNavigationStyle ::init();
|
||||
OpenSCADNavigationStyle ::init();
|
||||
RevitNavigationStyle ::init();
|
||||
SiemensNXNavigationStyle ::init();
|
||||
SolidWorksNavigationStyle ::init();
|
||||
TinkerCADNavigationStyle ::init();
|
||||
TouchpadNavigationStyle ::init();
|
||||
|
||||
GLGraphicsItem ::init();
|
||||
GLFlagWindow ::init();
|
||||
|
||||
@@ -74,9 +74,10 @@ def RePopulateIcons():
|
||||
a6.setIcon(QtGui.QIcon(":/icons/NavigationOpenInventor_" + StyleSheetType + ".svg"))
|
||||
a7.setIcon(QtGui.QIcon(":/icons/NavigationOpenSCAD_" + StyleSheetType + ".svg"))
|
||||
a8.setIcon(QtGui.QIcon(":/icons/NavigationRevit_" + StyleSheetType + ".svg"))
|
||||
a9.setIcon(QtGui.QIcon(":/icons/NavigationSolidWorks_" + StyleSheetType + ".svg"))
|
||||
a10.setIcon(QtGui.QIcon(":/icons/NavigationTinkerCAD_" + StyleSheetType + ".svg"))
|
||||
a11.setIcon(QtGui.QIcon(":/icons/NavigationTouchpad_" + StyleSheetType + ".svg"))
|
||||
a9.setIcon(QtGui.QIcon(":/icons/NavigationSiemensNX_" + StyleSheetType + ".svg"))
|
||||
a10.setIcon(QtGui.QIcon(":/icons/NavigationSolidWorks_" + StyleSheetType + ".svg"))
|
||||
a11.setIcon(QtGui.QIcon(":/icons/NavigationTinkerCAD_" + StyleSheetType + ".svg"))
|
||||
a12.setIcon(QtGui.QIcon(":/icons/NavigationTouchpad_" + StyleSheetType + ".svg"))
|
||||
|
||||
|
||||
def retranslateUi():
|
||||
@@ -474,6 +475,48 @@ def retranslateUi():
|
||||
|
||||
global t9
|
||||
t9 = (
|
||||
"<p align='center'><b>Siemens NX</b> "
|
||||
+ text06
|
||||
+ """</p>
|
||||
<table>
|
||||
<tr>
|
||||
<th><small>"""
|
||||
+ text01
|
||||
+ """</small></th>
|
||||
<th><small>"""
|
||||
+ text02
|
||||
+ """</small></th>
|
||||
<th><small>"""
|
||||
+ text02
|
||||
+ """</small></th>
|
||||
<th><small>"""
|
||||
+ text03
|
||||
+ """</small></th>
|
||||
<th><small>"""
|
||||
+ text04
|
||||
+ """</small></th>
|
||||
<th><small>"""
|
||||
+ text04
|
||||
+ """</small></th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align='center'><img src=':/icons/Navigation_Mouse_Left.svg'></td>
|
||||
<td align='center'><img src=':/icons/Navigation_Mouse_Scroll.svg'></td>
|
||||
<td align='center'><img src=':/icons/Navigation_Mouse_MiddleLeft.svg'></td>
|
||||
<td align='center'><img src=':/icons/Navigation_Mouse_Middle.svg'></td>
|
||||
<td align='center'><img src=':/icons/Navigation_Mouse_MiddleRight.svg'></td>
|
||||
<td align='center'><img src=':/icons/Navigation_Mouse_ShiftMiddle.svg'></td>
|
||||
</tr>
|
||||
</table>
|
||||
<b>"""
|
||||
+ text08
|
||||
+ ":</b> "
|
||||
+ text10
|
||||
+ "</small></p>"
|
||||
)
|
||||
|
||||
global t10
|
||||
t10 = (
|
||||
"<p align='center'><b>SolidWorks</b> "
|
||||
+ text06
|
||||
+ """</p>
|
||||
@@ -510,8 +553,8 @@ def retranslateUi():
|
||||
+ "</small></p>"
|
||||
)
|
||||
|
||||
global t10
|
||||
t10 = (
|
||||
global t11
|
||||
t11 = (
|
||||
"<p align='center'><b>TinkerCAD</b> "
|
||||
+ text06
|
||||
+ """</p>
|
||||
@@ -539,8 +582,8 @@ def retranslateUi():
|
||||
</table>"""
|
||||
)
|
||||
|
||||
global t11
|
||||
t11 = (
|
||||
global t12
|
||||
t12 = (
|
||||
"<p align='center'><b>Touchpad</b> "
|
||||
+ text06
|
||||
+ """</p>
|
||||
@@ -716,19 +759,24 @@ a8.setData("Gui::RevitNavigationStyle")
|
||||
a8.setObjectName("Indicator_NavigationRevit")
|
||||
|
||||
a9 = QtGui.QAction(gStyle)
|
||||
a9.setText("SolidWorks ")
|
||||
a9.setData("Gui::SolidWorksNavigationStyle")
|
||||
a9.setObjectName("Indicator_NavigationSolidWorks")
|
||||
a9.setText("Siemens NX ")
|
||||
a9.setData("Gui::SiemensNXNavigationStyle")
|
||||
a9.setObjectName("Indicator_NavigationSiemensNX")
|
||||
|
||||
a10 = QtGui.QAction(gStyle)
|
||||
a10.setText("TinkerCAD ")
|
||||
a10.setData("Gui::TinkerCADNavigationStyle")
|
||||
a10.setObjectName("Indicator_NavigationTinkerCAD")
|
||||
a10.setText("SolidWorks ")
|
||||
a10.setData("Gui::SolidWorksNavigationStyle")
|
||||
a10.setObjectName("Indicator_NavigationSolidWorks")
|
||||
|
||||
a11 = QtGui.QAction(gStyle)
|
||||
a11.setText("Touchpad ")
|
||||
a11.setData("Gui::TouchpadNavigationStyle")
|
||||
a11.setObjectName("Indicator_NavigationTouchpad")
|
||||
a11.setText("TinkerCAD ")
|
||||
a11.setData("Gui::TinkerCADNavigationStyle")
|
||||
a11.setObjectName("Indicator_NavigationTinkerCAD")
|
||||
|
||||
a12 = QtGui.QAction(gStyle)
|
||||
a12.setText("Touchpad ")
|
||||
a12.setData("Gui::TouchpadNavigationStyle")
|
||||
a12.setObjectName("Indicator_NavigationTouchpad")
|
||||
|
||||
RePopulateIcons()
|
||||
|
||||
@@ -746,6 +794,7 @@ menu.addAction(a8)
|
||||
menu.addAction(a9)
|
||||
menu.addAction(a10)
|
||||
menu.addAction(a11)
|
||||
menu.addAction(a12)
|
||||
|
||||
pView.Attach(indicator)
|
||||
|
||||
@@ -787,6 +836,7 @@ def onTooltip():
|
||||
a9.setToolTip(t9)
|
||||
a10.setToolTip(t10)
|
||||
a11.setToolTip(t11)
|
||||
a12.setToolTip(t12)
|
||||
p.SetBool("Tooltip", 1)
|
||||
else:
|
||||
for i in gStyle.actions():
|
||||
|
||||
@@ -47,6 +47,8 @@
|
||||
<file>icons/NavigationOpenSCAD_dark.svg</file>
|
||||
<file>icons/NavigationRevit_light.svg</file>
|
||||
<file>icons/NavigationRevit_dark.svg</file>
|
||||
<file>icons/NavigationSiemensNX_light.svg</file>
|
||||
<file>icons/NavigationSiemensNX_dark.svg</file>
|
||||
<file>icons/NavigationSolidWorks_light.svg</file>
|
||||
<file>icons/NavigationSolidWorks_dark.svg</file>
|
||||
<file>icons/NavigationTinkerCAD_light.svg</file>
|
||||
|
||||
50
src/Mod/Tux/Resources/icons/NavigationSiemensNX_dark.svg
Normal file
50
src/Mod/Tux/Resources/icons/NavigationSiemensNX_dark.svg
Normal file
@@ -0,0 +1,50 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
id="svg2"
|
||||
height="64"
|
||||
width="64"
|
||||
version="1.1"
|
||||
viewBox="0 0 63.999999 63.999999"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/">
|
||||
<defs
|
||||
id="defs1" />
|
||||
<metadata
|
||||
id="metadata7">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
id="layer1"
|
||||
transform="translate(0 -988.36)"
|
||||
stroke="#2e3436"
|
||||
stroke-width="6"
|
||||
fill="none">
|
||||
<path
|
||||
id="path4144"
|
||||
d="m16 1028.4v-20c0-8 4-12 16-12s16 4 16 12v20c0 8-4 17-16 17s-16-9-16-17z" />
|
||||
<path
|
||||
id="path4209"
|
||||
d="m32 1004.4v12" />
|
||||
</g>
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="fill:#2e3436;stroke:#2e3436;stroke-width:1.249;stroke-dasharray:none"
|
||||
x="20.548067"
|
||||
y="42.288612"
|
||||
id="text1"><tspan
|
||||
x="20.548067"
|
||||
y="42.288612"
|
||||
id="tspan2">NX</tspan></text>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.3 KiB |
50
src/Mod/Tux/Resources/icons/NavigationSiemensNX_light.svg
Normal file
50
src/Mod/Tux/Resources/icons/NavigationSiemensNX_light.svg
Normal file
@@ -0,0 +1,50 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
id="svg2"
|
||||
height="64"
|
||||
width="64"
|
||||
version="1.1"
|
||||
viewBox="0 0 63.999999 63.999999"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/">
|
||||
<defs
|
||||
id="defs1" />
|
||||
<metadata
|
||||
id="metadata7">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
id="layer1"
|
||||
transform="translate(0 -988.36)"
|
||||
stroke="#d1cbc9"
|
||||
stroke-width="6"
|
||||
fill="none">
|
||||
<path
|
||||
id="path4144"
|
||||
d="m16 1028.4v-20c0-8 4-12 16-12s16 4 16 12v20c0 8-4 17-16 17s-16-9-16-17z" />
|
||||
<path
|
||||
id="path4209"
|
||||
d="m32 1004.4v12" />
|
||||
</g>
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="fill:#d1cbc9;stroke:#d1cbc9;stroke-width:1.249;stroke-dasharray:none"
|
||||
x="20.548067"
|
||||
y="42.288612"
|
||||
id="text1"><tspan
|
||||
x="20.548067"
|
||||
y="42.288612"
|
||||
id="tspan2">NX</tspan></text>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.3 KiB |
Reference in New Issue
Block a user