1
/***************************************************************************
2
* Copyright (c) 2010 Thomas Anderson <ta@nextgenengineering> *
4
* This file is part of the FreeCAD CAx development system. *
6
* This library is free software; you can redistribute it and/or *
7
* modify it under the terms of the GNU Library General Public *
8
* License as published by the Free Software Foundation; either *
9
* version 2 of the License, or (at your option) any later version. *
11
* This library is distributed in the hope that it will be useful, *
12
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
13
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
14
* GNU Library General Public License for more details. *
16
* You should have received a copy of the GNU Library General Public *
17
* License along with this library; see the file COPYING.LIB. If not, *
18
* write to the Free Software Foundation, Inc., 59 Temple Place, *
19
* Suite 330, Boston, MA 02111-1307, USA *
21
***************************************************************************/
23
#include "PreCompiled.h"
30
#include "Application.h"
31
#include "GuiApplicationNativeEventAware.h"
32
#include "SpaceballEvent.h"
35
#if defined(_USE_3DCONNEXION_SDK) || defined(SPNAV_FOUND)
36
#if defined(Q_OS_LINUX)
37
#if defined(SPNAV_USE_X11)
38
#include "3Dconnexion/GuiNativeEventLinuxX11.h"
40
#include "3Dconnexion/GuiNativeEventLinux.h"
42
#elif defined(Q_OS_WIN)
43
#include "3Dconnexion/GuiNativeEventWin32.h"
44
#elif defined(Q_OS_MACOS)
45
#include "3Dconnexion/GuiNativeEventMac.h"
46
#endif // Platform switch
49
Gui::GUIApplicationNativeEventAware::GUIApplicationNativeEventAware(int &argc, char *argv[]) :
50
QApplication (argc, argv), spaceballPresent(false)
52
#if defined(_USE_3DCONNEXION_SDK) || defined(SPNAV_FOUND)
53
nativeEvent = new Gui::GuiNativeEvent(this);
57
Gui::GUIApplicationNativeEventAware::~GUIApplicationNativeEventAware() = default;
59
void Gui::GUIApplicationNativeEventAware::initSpaceball(QMainWindow *window)
61
#if defined(_USE_3DCONNEXION_SDK) || defined(SPNAV_FOUND)
62
nativeEvent->initSpaceball(window);
66
Spaceball::MotionEvent::MotionEventType = QEvent::registerEventType();
67
Spaceball::ButtonEvent::ButtonEventType = QEvent::registerEventType();
70
bool Gui::GUIApplicationNativeEventAware::processSpaceballEvent(QObject *object, QEvent *event)
72
if (!activeWindow()) {
73
qDebug("No active window\n");
77
QApplication::notify(object, event);
78
if (event->type() == Spaceball::MotionEvent::MotionEventType)
80
auto motionEvent = dynamic_cast<Spaceball::MotionEvent*>(event);
83
if (!motionEvent->isHandled())
85
//make a new event and post to parent.
86
auto newEvent = new Spaceball::MotionEvent(*motionEvent);
87
postEvent(object->parent(), newEvent);
91
if (event->type() == Spaceball::ButtonEvent::ButtonEventType)
93
auto buttonEvent = dynamic_cast<Spaceball::ButtonEvent*>(event);
96
if (!buttonEvent->isHandled())
98
//make a new event and post to parent.
99
auto newEvent = new Spaceball::ButtonEvent(*buttonEvent);
100
postEvent(object->parent(), newEvent);
106
void Gui::GUIApplicationNativeEventAware::postMotionEvent(std::vector<int> motionDataArray)
108
auto currentWidget(focusWidget());
109
if (!currentWidget) {
112
importSettings(motionDataArray);
114
auto motionEvent = new Spaceball::MotionEvent();
115
motionEvent->setTranslations(motionDataArray[0], motionDataArray[1], motionDataArray[2]);
116
motionEvent->setRotations(motionDataArray[3], motionDataArray[4], motionDataArray[5]);
117
this->postEvent(currentWidget, motionEvent);
120
void Gui::GUIApplicationNativeEventAware::postButtonEvent(int buttonNumber, int buttonPress)
122
auto currentWidget(focusWidget());
123
if (!currentWidget) {
127
auto buttonEvent = new Spaceball::ButtonEvent();
128
buttonEvent->setButtonNumber(buttonNumber);
131
buttonEvent->setButtonStatus(Spaceball::BUTTON_PRESSED);
135
buttonEvent->setButtonStatus(Spaceball::BUTTON_RELEASED);
137
this->postEvent(currentWidget, buttonEvent);
140
float Gui::GUIApplicationNativeEventAware::convertPrefToSensitivity(int value)
144
return ((0.9/50)*float(value) + 1);
148
return ((2.5/50)*float(value) + 1);
152
void Gui::GUIApplicationNativeEventAware::importSettings(std::vector<int>& motionDataArray)
154
ParameterGrp::handle group = App::GetApplication().GetUserParameter().GetGroup("BaseApp")->GetGroup("Spaceball")->GetGroup("Motion");
156
// Remapping of motion data
157
long remap = group->GetInt("Remapping", 12345);
158
if (remap != 12345) {
160
s << std::setfill('0') << std::setw(6) << remap;
165
// the string must have a length of 6 and it must contain all digits 0,...,5
166
std::string::size_type pos1 = str.find_first_not_of("012345");
167
std::string::size_type pos2 = std::string("012345").find_first_not_of(str);
168
if (pos1 == std::string::npos && pos2 == std::string::npos) {
169
std::vector<int> vec(str.size());
170
std::transform(str.begin(), str.end(), vec.begin(), [](char c) -> int { return c - '0';});
172
std::vector<int> copy = motionDataArray;
173
for (int i=0; i<6; i++) {
174
motionDataArray[i] = copy[vec[i]];
179
// here I import settings from a dialog. For now they are set as is
180
bool dominant = group->GetBool("Dominant"); // Is dominant checked
181
bool flipXY = group->GetBool("FlipYZ");; // Is Flip X/Y checked
182
float generalSensitivity = convertPrefToSensitivity(group->GetInt("GlobalSensitivity"));
184
// array that has stored info about "Enabled" checkboxes of all axes
186
enabled[0] = group->GetBool("Translations", true) && group->GetBool("PanLREnable", true);
187
enabled[1] = group->GetBool("Translations", true) && group->GetBool("PanUDEnable", true);
188
enabled[2] = group->GetBool("Translations", true) && group->GetBool("ZoomEnable", true);
189
enabled[3] = group->GetBool("Rotations", true) && group->GetBool("TiltEnable", true);
190
enabled[4] = group->GetBool("Rotations", true) && group->GetBool("RollEnable", true);
191
enabled[5] = group->GetBool("Rotations", true) && group->GetBool("SpinEnable", true);
193
// array that has stored info about "Reversed" checkboxes of all axes
195
reversed[0] = group->GetBool("PanLRReverse");
196
reversed[1] = group->GetBool("PanUDReverse");
197
reversed[2] = group->GetBool("ZoomReverse");
198
reversed[3] = group->GetBool("TiltReverse");
199
reversed[4] = group->GetBool("RollReverse");
200
reversed[5] = group->GetBool("SpinReverse");
202
// array that has stored info about sliders - on each slider you need to use method DlgSpaceballSettings::GetValuefromSlider
203
// which will convert <-50, 50> linear integers from slider to <0.1, 10> exponential floating values
204
float sensitivity[6];
205
sensitivity[0] = convertPrefToSensitivity(group->GetInt("PanLRSensitivity"));
206
sensitivity[1] = convertPrefToSensitivity(group->GetInt("PanUDSensitivity"));
207
sensitivity[2] = convertPrefToSensitivity(group->GetInt("ZoomSensitivity"));
208
sensitivity[3] = convertPrefToSensitivity(group->GetInt("TiltSensitivity"));
209
sensitivity[4] = convertPrefToSensitivity(group->GetInt("RollSensitivity"));
210
sensitivity[5] = convertPrefToSensitivity(group->GetInt("SpinSensitivity"));
212
if (group->GetBool("Calibrate"))
214
group->SetInt("CalibrationX",motionDataArray[0]);
215
group->SetInt("CalibrationY",motionDataArray[1]);
216
group->SetInt("CalibrationZ",motionDataArray[2]);
217
group->SetInt("CalibrationXr",motionDataArray[3]);
218
group->SetInt("CalibrationYr",motionDataArray[4]);
219
group->SetInt("CalibrationZr",motionDataArray[5]);
221
group->RemoveBool("Calibrate");
227
motionDataArray[0] = motionDataArray[0] - group->GetInt("CalibrationX");
228
motionDataArray[1] = motionDataArray[1] - group->GetInt("CalibrationY");
229
motionDataArray[2] = motionDataArray[2] - group->GetInt("CalibrationZ");
230
motionDataArray[3] = motionDataArray[3] - group->GetInt("CalibrationXr");
231
motionDataArray[4] = motionDataArray[4] - group->GetInt("CalibrationYr");
232
motionDataArray[5] = motionDataArray[5] - group->GetInt("CalibrationZr");
241
tempBool = enabled[1];
242
enabled[1] = enabled[2];
243
enabled[2] = tempBool;
245
tempBool = enabled[4];
246
enabled[4] = enabled[5];
247
enabled[5] = tempBool;
250
tempBool = reversed[1];
251
reversed[1] = reversed[2];
252
reversed[2] = tempBool;
254
tempBool = reversed[4];
255
reversed[4] = reversed[5];
256
reversed[5] = tempBool;
259
tempFloat = sensitivity[1];
260
sensitivity[1] = sensitivity[2];
261
sensitivity[2] = tempFloat;
263
tempFloat = sensitivity[4];
264
sensitivity[4] = sensitivity[5];
265
sensitivity[5] = tempFloat;
268
i = motionDataArray[1];
269
motionDataArray[1] = motionDataArray[2];
270
motionDataArray[2] = - i;
272
i = motionDataArray[4];
273
motionDataArray[4] = motionDataArray[5];
274
motionDataArray[5] = - i;
277
if (dominant) { // if dominant is checked
280
for (i = 0; i < 6; ++i) {
281
if (abs(motionDataArray[i]) > abs(max)) max = motionDataArray[i];
283
for (i = 0; i < 6; ++i) {
284
if ((motionDataArray[i] != max) || (flag)) {
285
motionDataArray[i] = 0;
286
} else if (motionDataArray[i] == max) {
292
for (i = 0; i < 6; ++i) {
293
if (motionDataArray[i] != 0) {
295
motionDataArray[i] = 0;
298
motionDataArray[i] = - motionDataArray[i];
299
motionDataArray[i] = (int)((float)(motionDataArray[i]) * sensitivity[i] * generalSensitivity);
305
#include "moc_GuiApplicationNativeEventAware.cpp"