From f6411f822109a2d78eae4554e9904577ae8ab6d0 Mon Sep 17 00:00:00 2001 From: Christopher Coley Date: Tue, 18 Aug 2020 00:54:27 -0700 Subject: [PATCH] 3DConnexion SpaceBall and configuration dialog improvements --- src/Gui/3Dconnexion/3DConnexion.xml | 60 +++++++++++++- src/Gui/3Dconnexion/GuiNativeEventMac.cpp | 6 +- src/Gui/3Dconnexion/GuiNativeEventMac.h | 13 ++++ src/Gui/DlgCustomizeSpaceball.cpp | 95 +++++++++++++++++++++-- src/Gui/DlgCustomizeSpaceball.h | 4 + 5 files changed, 168 insertions(+), 10 deletions(-) diff --git a/src/Gui/3Dconnexion/3DConnexion.xml b/src/Gui/3Dconnexion/3DConnexion.xml index 9b495dd7f1..55e3279201 100644 --- a/src/Gui/3Dconnexion/3DConnexion.xml +++ b/src/Gui/3Dconnexion/3DConnexion.xml @@ -1,9 +1,63 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - + + + + + + + + + + + + + + + + + + + + + diff --git a/src/Gui/3Dconnexion/GuiNativeEventMac.cpp b/src/Gui/3Dconnexion/GuiNativeEventMac.cpp index 63cc93e2ac..5b6196f363 100644 --- a/src/Gui/3Dconnexion/GuiNativeEventMac.cpp +++ b/src/Gui/3Dconnexion/GuiNativeEventMac.cpp @@ -166,7 +166,11 @@ void Gui::GuiNativeEvent::initSpaceball(QMainWindow *window) Base::Console().Log("Couldn't connect to 3Dconnexion driver\n"); return; } - + + // Turn on all features and buttons + SetConnexionClientMask(tdxClientID, kConnexionMaskAll); + SetConnexionClientButtonMask(tdxClientID, kConnexionMaskAllButtons); + Base::Console().Log("3Dconnexion driver initialized. Client ID: %d\n", tdxClientID); mainApp->setSpaceballPresent(true); } diff --git a/src/Gui/3Dconnexion/GuiNativeEventMac.h b/src/Gui/3Dconnexion/GuiNativeEventMac.h index ffd7e49508..809e668088 100644 --- a/src/Gui/3Dconnexion/GuiNativeEventMac.h +++ b/src/Gui/3Dconnexion/GuiNativeEventMac.h @@ -29,6 +29,10 @@ class QMainWindow; #include #include +extern int16_t SetConnexionHandlers(ConnexionMessageHandlerProc messageHandler, + ConnexionAddedHandlerProc addedHandler, + ConnexionRemovedHandlerProc removedHandler, + bool useSeparateThread) __attribute__((weak_import)); // Note that InstallConnexionHandlers will be replaced with // SetConnexionHandlers "in the future". extern OSErr InstallConnexionHandlers(ConnexionMessageHandlerProc messageHandler, @@ -37,9 +41,18 @@ extern OSErr InstallConnexionHandlers(ConnexionMessageHandlerProc messageHandler __attribute__((weak_import)); extern UInt16 RegisterConnexionClient(UInt32 signature, UInt8 *name, UInt16 mode, UInt32 mask) __attribute__((weak_import)); +extern void SetConnexionClientMask(uint16_t clientID, uint32_t mask) + __attribute__((weak_import)); +extern void SetConnexionClientButtonMask(uint16_t clientID, uint32_t buttonMask) + __attribute__((weak_import)); extern void UnregisterConnexionClient(UInt16 clientID) __attribute__((weak_import)); extern void CleanupConnexionHandlers(void) __attribute__((weak_import)); +extern int16_t ConnexionControl(uint32_t message, int32_t param, int32_t *result); +extern int16_t ConnexionClientControl(uint16_t clientID, uint32_t message, int32_t param, int32_t *result); +extern int16_t ConnexionGetCurrentDevicePrefs(uint32_t deviceID, ConnexionDevicePrefs *prefs); +extern int16_t ConnexionSetButtonLabels(uint8_t *labels, uint16_t size); + namespace Gui { class GUIApplicationNativeEventAware; diff --git a/src/Gui/DlgCustomizeSpaceball.cpp b/src/Gui/DlgCustomizeSpaceball.cpp index 721a7e620b..3beb244414 100644 --- a/src/Gui/DlgCustomizeSpaceball.cpp +++ b/src/Gui/DlgCustomizeSpaceball.cpp @@ -33,6 +33,7 @@ #include #include #include +#include #endif #include "Base/Console.h" @@ -55,6 +56,7 @@ ButtonView::ButtonView(QWidget *parent) : QListView(parent) void ButtonView::selectButton(int number) { this->selectionModel()->select(this->model()->index(number, 0), QItemSelectionModel::ClearAndSelect); + this->scrollTo(this->model()->index(number, 0), QAbstractItemView::EnsureVisible); } void ButtonView::goSelectionChanged(const QItemSelection &selected, const QItemSelection &deselected) @@ -78,7 +80,7 @@ void ButtonView::goChangedCommand(const QString& commandName) ButtonModel::ButtonModel(QObject *parent) : QAbstractListModel(parent) { - load3DConnexionButtons("SpacePilot Pro"); + //load3DConnexionButtons("SpacePilot Pro"); } // Process the given Mapping tree to load in the Button mappings. @@ -129,6 +131,7 @@ void ButtonModel::load3DConnexionButtonMapping(boost::property_tree::ptree Butto newGroup = spaceballButtonGroup()->GetGroup(ButtonCode.c_str()); newGroup->SetASCII("Command", ButtonCommand.c_str()); + newGroup->SetASCII("Description", ButtonDescription.c_str()); } } } @@ -224,6 +227,7 @@ void ButtonModel::insertButtonRows(int number) groupName.setNum(index); Base::Reference newGroup = spaceballButtonGroup()->GetGroup(groupName.toLatin1());//builds the group. newGroup->SetASCII("Command", ""); + newGroup->SetASCII("Description", ""); } endInsertRows(); return; @@ -269,12 +273,28 @@ ParameterGrp::handle ButtonModel::spaceballButtonGroup() const QString ButtonModel::getLabel(const int &number) const { - if (number > -1 && number < 20) - return tr("Button %1").arg(number+1); - else + if (number > -1 && number < 32) { + QString numberString; + numberString.setNum(number); + QString desc = QString::fromStdString(spaceballButtonGroup()-> + GetGroup(numberString.toLatin1())-> + GetASCII("Description","")); + if (desc.length()) + desc = tr(" \"") + desc + tr("\""); + return tr("Button %1").arg(number + 1) + desc; + } else return tr("Out Of Range"); } +void ButtonModel::loadConfig(const char *RequiredDeviceName) +{ + goClear(); + if (!RequiredDeviceName) { + return; + } + load3DConnexionButtons(RequiredDeviceName); +} + ////////////////////////////////////////////////////////////////////////////////////////// CommandView::CommandView(QWidget *parent) : QTreeView(parent) @@ -693,11 +713,26 @@ void DlgCustomizeSpaceball::setupCommandModelView() void DlgCustomizeSpaceball::setupLayout() { QLabel *buttonLabel = new QLabel(tr("Buttons"), this); - clearButton = new QPushButton(tr("Clear"), this); + clearButton = new QPushButton(tr("Reset"), this); + devModel = new QComboBox(this); + + // Load the devModel(s) from the config xml file + devModel->addItems(getModels()); + + // Select the current preference or the first entry + QString model = QString::fromStdString(App::GetApplication().GetUserParameter().GetGroup("BaseApp")-> + GetGroup("Spaceball")->GetASCII("Model","")); + if (model.length() > 0) { + devModel->setCurrentIndex(devModel->findText(model)); + } else { + devModel->setCurrentIndex(0); + } + QVBoxLayout *buttonGroup = new QVBoxLayout(); buttonGroup->addWidget(buttonLabel); buttonGroup->addWidget(buttonView); QHBoxLayout *clearLayout = new QHBoxLayout(); + clearLayout->addWidget(devModel); clearLayout->addWidget(clearButton); clearLayout->addStretch(); buttonGroup->addLayout(clearLayout); @@ -730,7 +765,12 @@ void DlgCustomizeSpaceball::goClear() commandView->clearSelection(); commandView->collapseAll(); commandView->setDisabled(true); - buttonModel->goClear(); + //buttonModel->goClear(); + + QByteArray currentDevice = devModel->currentText().toLocal8Bit(); + App::GetApplication().GetUserParameter().GetGroup("BaseApp")-> + GetGroup("Spaceball")->SetASCII("Model", currentDevice.data()); + buttonModel->loadConfig(currentDevice.data()); } void DlgCustomizeSpaceball::goPrint() @@ -828,4 +868,47 @@ void DlgCustomizeSpaceball::onModifyMacroAction(const QByteArray ¯oName) Q_UNUSED(macroName); } +QStringList DlgCustomizeSpaceball::getModels() +{ + QStringList modelList; + try + { + boost::property_tree::ptree tree; + boost::property_tree::ptree DeviceTree; + + // exception thrown if no file found + std::string path = App::Application::getResourceDir(); + path += "3Dconnexion/3DConnexion.xml"; + read_xml(path.c_str(), tree); + + BOOST_FOREACH(const boost::property_tree::ptree::value_type &ButtonMap, tree.get_child("")) + { + if ("ButtonMap" == ButtonMap.first) + { + // Inspect ButtonMap attributes for DeviceName + BOOST_FOREACH(const boost::property_tree::ptree::value_type &kv, ButtonMap.second.get_child("")) + { + std::string Attribute; + std::string Value; + + Attribute = kv.first.data(); + Value = kv.second.data(); + + if (0 == Attribute.compare("DeviceName")) + { + modelList << QString::fromStdString(Value); + } + } + } + } + } + catch (const std::exception& e) + { + // We don't mind not finding the file to be opened + Base::Console().Warning("%s\n", e.what()); + } + + return modelList; +} + #include "moc_DlgCustomizeSpaceball.cpp" diff --git a/src/Gui/DlgCustomizeSpaceball.h b/src/Gui/DlgCustomizeSpaceball.h index 234fb9012e..1215933005 100644 --- a/src/Gui/DlgCustomizeSpaceball.h +++ b/src/Gui/DlgCustomizeSpaceball.h @@ -25,6 +25,7 @@ #include #include +#include #include #include "PropertyPage.h" @@ -66,6 +67,7 @@ namespace Gui void goButtonPress(int number); void goMacroRemoved(const QByteArray& macroName); void goClear(); + void loadConfig(const char *RequiredDeviceName); private: void load3DConnexionButtonMapping(boost::property_tree::ptree ButtonMapTree); void load3DConnexionButtons(const char *RequiredDeviceName); @@ -164,6 +166,7 @@ namespace Gui void setupCommandModelView(); void setupLayout(); void setMessage(const QString& message); + QStringList getModels(); ButtonView *buttonView; ButtonModel *buttonModel; @@ -171,6 +174,7 @@ namespace Gui CommandModel *commandModel; QPushButton *clearButton; QPushButton *printReference; + QComboBox *devModel; }; } }