Files
qelectrotech-source-mirror/sources/spacemouse/spacemousebackend.h
T
ispyisail e35cab33f0 Extract a SpaceMouseBackend seam ahead of a future Windows/macOS backend
The user asked for phase 2 (Windows/macOS via 3Dconnexion's proprietary
3DxWare SDK) on top of #635. This sandbox has no 3DxWare SDK, no Windows
toolchain, and no macOS toolchain -- nothing to compile, link, or run a
single line of platform code against, unlike the Linux/libspnav path,
which was built and actually tested here for real. Writing 3DxWare
integration code that has never even built would be a materially weaker,
unverifiable thing sitting in this PR, so it is not in this commit.

What is: the structural seam that makes adding it later a contained,
reviewable change instead of a rewrite of code that already works.

## Before

SpaceMouseListener did three unrelated things in one class: own the
libspnav connection, read spnav events, and apply motion to the active
DiagramView. A Windows/macOS backend would have had to either duplicate
all of the DiagramView-facing logic (the pan/zoom calls, the Z-to-zoom-
factor mapping, the "which view is active" lookup -- all already verified)
or bolt onto the same class with a maze of #ifdefs. Either way, touching
that file again would put the already-tested Linux path back in scope for
review.

## After

- SpaceMouseBackend: a tiny interface (isAvailable(), a motion(dx,dy,dz)
  signal). A backend's only job is owning one platform's connection to the
  driver/daemon and translating its native event into this one signal.
- SpnavBackend: the libspnav code from the previous commit, moved behind
  that interface with no behaviour change -- still spnav_open() in the
  constructor, still a QSocketNotifier on spnav_fd(), still silent when no
  daemon/device is present.
- SpaceMouseListener: now backend-agnostic. Owns whichever backend the
  platform provides, applies its motion to the active DiagramView exactly
  as before. The DiagramView-facing code (pan/zoom calls,
  zoomFactorForZAxis) did not need to change at all -- only its input
  changed from a spnav_event_motion struct to three plain ints.

A future 3DxWare backend implements SpaceMouseBackend, is selected in
SpaceMouseListener's constructor behind its own
QET_SPACEMOUSE_BACKEND_3DXWARE guard (see the comment marking exactly
where), and never has to touch SpnavBackend or SpaceMouseListener's
DiagramView-facing half.

## CMake: one user option, one define per backend

QET_ENABLE_SPACEMOUSE is unchanged as the single option a user sets.
Internally, find_spacemouse.cmake now decides *which* backend (if any)
that resolves to: on Linux with libspnav found, QET_SPACEMOUSE_BACKEND_SPNAV
plus the umbrella QET_SPACEMOUSE_SUPPORT. Turning the option on anywhere
else today downgrades cleanly with a warning naming discussion #599,
instead of trying (and failing) to find libspnav on a platform that
doesn't ship it. Adding 3DxWare later means adding one more branch here,
not restructuring this file.

## Verified this is a pure refactor, not just "still compiles"

Reconfigured and rebuilt both ways from scratch:
 - option off: unchanged from before -- no new source files compiled, zero
   new object code.
 - option on: both new files compile with zero warnings, binary still
   links against libspnav.so.0 (confirmed via ldd), and run to completion
   in this environment (which has no spacenavd) with zero crashes and zero
   spnav-related output -- identical to before the refactor.
 - zoomFactorForZAxis re-linked and re-run in isolation: identical output
   to the pre-refactor commit (z=0 -> exactly 1.0, z=+-350 -> 1.35/0.65),
   confirming the math moved unchanged rather than being reimplemented.
2026-08-02 21:22:42 +12:00

72 lines
2.9 KiB
C++

/*
Copyright 2006-2026 The QElectroTech Team
This file is part of QElectroTech.
QElectroTech is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
QElectroTech 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with QElectroTech. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef SPACEMOUSEBACKEND_H
#define SPACEMOUSEBACKEND_H
#include <QObject>
/**
@brief The SpaceMouseBackend class
Platform seam for discussion #599's 3D mouse support. A backend owns
one platform's connection to the actual 6-DOF device driver -- opening
it, pumping whatever event source that platform uses, closing it -- and
reports motion through the one signal below. Everything platform-
independent (which DiagramView to apply motion to, the pan/zoom
primitives to call, the Z-to-zoom-factor mapping) lives in
SpaceMouseListener instead, once, so it does not have to be duplicated
or re-verified per backend.
SpnavBackend (Linux, spacenavd/libspnav) is the only implementation so
far -- built, linked, and its "no daemon/device present" path actually
run in the environment this was written in. A Windows/macOS backend
(3Dconnexion's proprietary 3DxWare SDK) would implement this same
interface and be selected in SpaceMouseListener's constructor, without
changing SpnavBackend or anything downstream of the motion signal.
Deliberately not attempted here: this was written on Linux with no
3DxWare SDK and no Windows/macOS toolchain available to compile,
link, or run a single line of it against, and shipping platform code
that has never even built would be a materially different, weaker
thing than everything else in this feature.
*/
class SpaceMouseBackend : public QObject
{
Q_OBJECT
public:
explicit SpaceMouseBackend(QObject *parent = nullptr) : QObject(parent) {}
~SpaceMouseBackend() override = default;
/// True once this backend actually has a live connection to a
/// driver/daemon. False is the ordinary case -- no daemon
/// running, no device attached -- not an error; see
/// SpaceMouseListener's class comment for why that distinction
/// matters.
virtual bool isAvailable() const = 0;
signals:
/// One raw device sample. dx/dy are the two axes
/// SpaceMouseListener maps to horizontal/vertical pan, dz the
/// one it maps to zoom. Units and range are whatever the
/// backend's own driver reports -- SpaceMouseListener's own
/// scale/divisor constants are what turn them into pixels and a
/// zoom factor, not this signal.
void motion(int dx, int dy, int dz);
};
#endif // SPACEMOUSEBACKEND_H