Add SolidWorks navigation style (#19568)

This commit is contained in:
theepicviolin
2025-02-24 08:57:00 -08:00
committed by GitHub
parent 8ea4046685
commit 38797d1fa4
12 changed files with 709 additions and 0 deletions

View File

@@ -938,6 +938,7 @@ SET(Navigation_CPP_SRCS
Navigation/CADNavigationStyle.cpp
Navigation/RevitNavigationStyle.cpp
Navigation/BlenderNavigationStyle.cpp
Navigation/SolidWorksNavigationStyle.cpp
Navigation/MayaGestureNavigationStyle.cpp
Navigation/OpenCascadeNavigationStyle.cpp
Navigation/OpenSCADNavigationStyle.cpp

View File

@@ -384,6 +384,23 @@ private:
SbBool lockButton1{false};
};
class GuiExport SolidWorksNavigationStyle : public UserNavigationStyle {
using inherited = UserNavigationStyle;
TYPESYSTEM_HEADER_WITH_OVERRIDE();
public:
SolidWorksNavigationStyle();
~SolidWorksNavigationStyle() override;
const char* mouseButtons(ViewerMode) override;
protected:
SbBool processSoEvent(const SoEvent * const ev) override;
private:
SbBool lockButton1{false};
};
class GuiExport MayaGestureNavigationStyle : public UserNavigationStyle {
using inherited = UserNavigationStyle;

View File

@@ -0,0 +1,308 @@
/***************************************************************************
* 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 *
* *
***************************************************************************/
#include "PreCompiled.h"
#ifndef _PreComp_
# include <Inventor/nodes/SoCamera.h>
# include <QApplication>
#endif
#include "Navigation/NavigationStyle.h"
#include "View3DInventorViewer.h"
using namespace Gui;
// ----------------------------------------------------------------------------------
/* TRANSLATOR Gui::SolidWorksNavigationStyle */
TYPESYSTEM_SOURCE(Gui::SolidWorksNavigationStyle, Gui::UserNavigationStyle)
SolidWorksNavigationStyle::SolidWorksNavigationStyle() : lockButton1(false)
{
}
SolidWorksNavigationStyle::~SolidWorksNavigationStyle() = default;
const char* SolidWorksNavigationStyle::mouseButtons(ViewerMode mode)
{
switch (mode) {
case NavigationStyle::SELECTION:
return QT_TR_NOOP("Press left mouse button");
case NavigationStyle::PANNING:
return QT_TR_NOOP("Press CTRL and middle mouse button");
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";
}
}
SbBool SolidWorksNavigationStyle::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 * const 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 * const 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 * const 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 SHIFTDOWN|BUTTON3DOWN:
newmode = NavigationStyle::ZOOMING;
break;
case BUTTON3DOWN:
if (newmode != NavigationStyle::DRAGGING) {
saveCursorPosition(ev);
}
newmode = NavigationStyle::DRAGGING;
break;
case CTRLDOWN|BUTTON3DOWN:
newmode = NavigationStyle::PANNING;
break;
default:
// Reset mode to IDLE when button 3 is released
// This stops the PANNING when button 3 is released but CTRL is still pressed
// This stops the ZOOMING when button 3 is released but SHIFT is still pressed
if ((curmode == NavigationStyle::PANNING || 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) {
newmode = NavigationStyle::SELECTION;
processed = 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;
}

View File

@@ -189,6 +189,7 @@ void Gui::SoFCDB::init()
CADNavigationStyle ::init();
RevitNavigationStyle ::init();
BlenderNavigationStyle ::init();
SolidWorksNavigationStyle ::init();
MayaGestureNavigationStyle ::init();
TouchpadNavigationStyle ::init();
GestureNavigationStyle ::init();

View File

@@ -366,6 +366,8 @@ SET(TechDrawGuiNav_SRCS
QGVNavStyleOpenSCAD.h
QGVNavStyleRevit.cpp
QGVNavStyleRevit.h
QGVNavStyleSolidWorks.cpp
QGVNavStyleSolidWorks.h
QGVNavStyleTinkerCAD.cpp
QGVNavStyleTinkerCAD.h
QGVNavStyleTouchpad.cpp

View File

@@ -0,0 +1,127 @@
/***************************************************************************
* Copyright (c) 2022 Wanderer Fan <wandererfan@gmail.com> *
* *
* 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 *
* *
***************************************************************************/
#include "PreCompiled.h"
#ifndef _PreComp_
# include <QGuiApplication>
# include <QMouseEvent>
#endif
#include "QGVNavStyleSolidWorks.h"
#include "QGVPage.h"
using namespace TechDrawGui;
namespace TechDrawGui {
QGVNavStyleSolidWorks::QGVNavStyleSolidWorks(QGVPage* qgvp) :
QGVNavStyle(qgvp)
{
}
QGVNavStyleSolidWorks::~QGVNavStyleSolidWorks()
{
}
void QGVNavStyleSolidWorks::handleKeyReleaseEvent(QKeyEvent *event)
{
// zoom mode 2
if ((event->key() == Qt::Key_Shift) && zoomingActive) {
stopZoom();
event->accept();
}
}
void QGVNavStyleSolidWorks::handleMousePressEvent(QMouseEvent *event)
{
Q_UNUSED(event)
// Base::Console().Message("QGVNSSolidWorks::handleMousePressEvent() - button: %d buttons: %d\n", event->button(), event->buttons());
}
void QGVNavStyleSolidWorks::handleMouseMoveEvent(QMouseEvent *event)
{
if (getViewer()->isBalloonPlacing()) {
balloonCursorMovement(event);
return;
}
if ((QGuiApplication::mouseButtons() & Qt::MiddleButton) &&
QGuiApplication::keyboardModifiers().testFlag(Qt::ShiftModifier) ) {
//zoom mode 2 Shift + MMB
if (zoomingActive) {
zoom(mouseZoomFactor(event->pos()));
} else {
startZoom(event->pos());
}
event->accept();
} else if ((QGuiApplication::mouseButtons() & Qt::MiddleButton) &&
QGuiApplication::keyboardModifiers().testFlag(Qt::ControlModifier) ) {
// pan mode 1 - Ctrl + MMB
// I think this block may be unnecessary since pan mode 2 MMB also captures pan mode 1
// Ctrl + MMB, but I'll leave it in to make it clear that this is what's intended
// also nav style OCC has a similar block
if (panningActive) {
pan(event->pos());
} else {
startPan(event->pos());
}
event->accept();
} else if (QGuiApplication::mouseButtons() & Qt::MiddleButton) {
// pan mode 2 - MMB
if (panningActive) {
pan(event->pos());
} else {
startPan(event->pos());
}
event->accept();
}
}
void QGVNavStyleSolidWorks::handleMouseReleaseEvent(QMouseEvent *event)
{
// Base::Console().Message("QGVNSSolidWorks::handleMouseReleaseEvent() - button: %d buttons: %d\n", event->button(), event->buttons());
if (getViewer()->isBalloonPlacing()) {
placeBalloon(event->pos());
}
if (panningActive) {
if (event->button() == Qt::MiddleButton) {
//pan mode 1 or 2 - [Control] + MMB
//stop panning if MMB released
if (panningActive) {
stopPan();
event->accept();
}
//zoom mode 2 Shift + MMB
//stop zooming if MMB released
if (zoomingActive) {
stopZoom();
event->accept();
}
}
}
}
} // namespace TechDrawGui

View File

@@ -0,0 +1,52 @@
/***************************************************************************
* Copyright (c) 2022 Wanderer Fan <wandererfan@gmail.com> *
* *
* 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 *
* *
***************************************************************************/
#ifndef TECHDRAW_SOLIDWORKSNAVSTYLE_H
#define TECHDRAW_SOLIDWORKSNAVSTYLE_H
#include <Mod/TechDraw/TechDrawGlobal.h>
#include "QGVNavStyle.h"
namespace TechDrawGui {
class QGVPage;
class TechDrawGuiExport QGVNavStyleSolidWorks : public QGVNavStyle
{
public:
explicit QGVNavStyleSolidWorks(QGVPage* qgvp);
~QGVNavStyleSolidWorks() override;
void handleKeyReleaseEvent(QKeyEvent *event) override;
void handleMousePressEvent(QMouseEvent *event) override;
void handleMouseMoveEvent(QMouseEvent *event) override;
void handleMouseReleaseEvent(QMouseEvent *event) override;
protected:
private:
};
}
#endif // TECHDRAW_SOLIDWORKSNAVSTYLE_H

View File

@@ -59,6 +59,7 @@
#include "QGVNavStyleOCC.h"
#include "QGVNavStyleOpenSCAD.h"
#include "QGVNavStyleRevit.h"
#include "QGVNavStyleSolidWorks.h"
#include "QGVNavStyleTinkerCAD.h"
#include "QGVNavStyleTouchpad.h"
#include "QGVPage.h"
@@ -246,6 +247,7 @@ void QGVPage::setNavigationStyle(std::string navParm)
std::size_t foundOCC = navParm.find("OpenCascade");
std::size_t foundOpenSCAD = navParm.find("OpenSCAD");
std::size_t foundRevit = navParm.find("Revit");
std::size_t foundSolidWorks = navParm.find("SolidWorks");
if (foundBlender != std::string::npos) {
m_navStyle = static_cast<QGVNavStyle*>(new QGVNavStyleBlender(this));
@@ -277,6 +279,9 @@ void QGVPage::setNavigationStyle(std::string navParm)
else if (foundRevit != std::string::npos) {
m_navStyle = static_cast<QGVNavStyle*>(new QGVNavStyleRevit(this));
}
else if (foundSolidWorks != std::string::npos) {
m_navStyle = static_cast<QGVNavStyle*>(new QGVNavStyleSolidWorks(this));
}
else {
m_navStyle = new QGVNavStyle(this);
}

View File

@@ -76,6 +76,7 @@ def RePopulateIcons():
a8.setIcon(QtGui.QIcon(":/icons/NavigationRevit_" + StyleSheetType + ".svg"))
a9.setIcon(QtGui.QIcon(":/icons/NavigationTinkerCAD_" + StyleSheetType + ".svg"))
a10.setIcon(QtGui.QIcon(":/icons/NavigationTouchpad_" + StyleSheetType + ".svg"))
a11.setIcon(QtGui.QIcon(":/icons/NavigationSolidWorks_" + StyleSheetType + ".svg"))
def retranslateUi():
@@ -566,6 +567,44 @@ def retranslateUi():
+ "</p>"
)
global t11
t11 = (
"<p align='center'><b>SolidWorks</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>
</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_ShiftMiddle.svg'></td>
<td align='center'><img src=':/icons/Navigation_Mouse_Middle.svg'></td>
<td align='center'><img src=':/icons/Navigation_Mouse_CtrlMiddle.svg'></td>
</tr>
</table>
<b>"""
+ text08
+ ":</b> "
+ text10
+ "</small></p>"
)
menuSettings.setTitle(translate("NavigationIndicator", "Settings"))
menuOrbit.setTitle(translate("NavigationIndicator", "Orbit style"))
aCompact.setText(translate("NavigationIndicator", "Compact"))
@@ -670,6 +709,11 @@ a10.setText("Touchpad ")
a10.setData("Gui::TouchpadNavigationStyle")
a10.setObjectName("Indicator_NavigationTouchpad")
a11 = QtGui.QAction(gStyle)
a11.setText("SolidWorks ")
a11.setData("Gui::SolidWorksNavigationStyle")
a11.setObjectName("Indicator_NavigationSolidWorks")
RePopulateIcons()
menu.addMenu(menuSettings)
@@ -685,6 +729,7 @@ menu.addAction(a7)
menu.addAction(a8)
menu.addAction(a9)
menu.addAction(a10)
menu.addAction(a11)
pView.Attach(indicator)
@@ -725,6 +770,7 @@ def onTooltip():
a8.setToolTip(t8)
a9.setToolTip(t9)
a10.setToolTip(t10)
a11.setToolTip(t11)
p.SetBool("Tooltip", 1)
else:
for i in gStyle.actions():

View File

@@ -47,6 +47,8 @@
<file>icons/NavigationOpenSCAD_dark.svg</file>
<file>icons/NavigationRevit_light.svg</file>
<file>icons/NavigationRevit_dark.svg</file>
<file>icons/NavigationSolidWorks_light.svg</file>
<file>icons/NavigationSolidWorks_dark.svg</file>
<file>icons/NavigationTinkerCAD_light.svg</file>
<file>icons/NavigationTinkerCAD_dark.svg</file>
<file>icons/NavigationTouchpad_light.svg</file>

View File

@@ -0,0 +1,76 @@
<?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"
sodipodi:docname="NavigationSW_dark.svg"
inkscape:version="1.4 (e7c3feb100, 2024-10-09)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
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/">
<sodipodi:namedview
id="namedview1"
pagecolor="#ffffff"
bordercolor="#999999"
borderopacity="1"
inkscape:showpageshadow="2"
inkscape:pageopacity="0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
inkscape:zoom="12.546875"
inkscape:cx="31.960149"
inkscape:cy="32.039851"
inkscape:window-width="1290"
inkscape:window-height="991"
inkscape:window-x="26"
inkscape:window-y="23"
inkscape:window-maximized="0"
inkscape:current-layer="svg2" />
<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"
style="stroke:#2e3436;stroke-opacity:1">
<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"
style="stroke:#2e3436;stroke-opacity:1" />
<path
id="path4209"
d="m32 1004.4v12"
style="stroke:#2e3436;stroke-opacity:1" />
</g>
<text
xml:space="preserve"
style="fill:#d1cbc9;stroke:#2e3436;stroke-width:1.249;stroke-dasharray:none;stroke-opacity:1"
x="22.540596"
y="42.368313"
id="text1"><tspan
x="22.540596"
y="42.368313"
id="tspan2"
style="stroke:#2e3436;stroke-opacity:1">SW</tspan></text>
</svg>

After

Width:  |  Height:  |  Size: 2.2 KiB

View File

@@ -0,0 +1,72 @@
<?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"
sodipodi:docname="NavigationSW_light.svg"
inkscape:version="1.4 (e7c3feb100, 2024-10-09)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
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/">
<sodipodi:namedview
id="namedview1"
pagecolor="#ffffff"
bordercolor="#999999"
borderopacity="1"
inkscape:showpageshadow="2"
inkscape:pageopacity="0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
inkscape:zoom="12.546875"
inkscape:cx="31.960149"
inkscape:cy="32"
inkscape:window-width="1920"
inkscape:window-height="1014"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1"
inkscape:current-layer="svg2" />
<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="22.540596"
y="42.368313"
id="text1"><tspan
x="22.540596"
y="42.368313"
id="tspan2">SW</tspan></text>
</svg>

After

Width:  |  Height:  |  Size: 2.0 KiB