diff --git a/src/button.cpp b/src/button.cpp index 26b2eb9..167aca2 100644 --- a/src/button.cpp +++ b/src/button.cpp @@ -6,6 +6,7 @@ Button::Button( int i, QObject *parent ) : QObject(parent) { isButtonPressed = false; isDown = false; rapidfire = false; + hasLayout = false; toDefault(); tick = 0; } @@ -18,7 +19,7 @@ bool Button::read( QTextStream &stream ) { // at this point, toDefault() has just been called. //read in a line of text and break it into words - QString input = stream.readLine().toLower(); + QString input = stream.readLine(); QRegExp regex("[\\s,]+"); QStringList words = input.split(regex); @@ -29,7 +30,7 @@ bool Button::read( QTextStream &stream ) { //go through every word on the line describing this button. for ( QStringList::Iterator it = words.begin(); it != words.end(); ++it ) { - if (*it == "mouse") { + if (QString::compare(*it, "mouse", Qt::CaseInsensitive) == 0) { ++it; if (it == words.end()) return false; val = (*it).toInt(&ok); @@ -39,7 +40,7 @@ bool Button::read( QTextStream &stream ) { } else return false; } - else if (*it == "key") { + else if (QString::compare(*it, "key", Qt::CaseInsensitive) == 0) { ++it; if (it == words.end()) return false; val = (*it).toInt(&ok); @@ -49,10 +50,16 @@ bool Button::read( QTextStream &stream ) { } else return false; } - else if (*it == "rapidfire") { + else if (QString::compare(*it, "layout", Qt::CaseInsensitive) == 0) { + ++it; + if (it == words.end()) return false; + layout = (*it).replace("\\s", " "); + hasLayout = true; + } + else if (QString::compare(*it, "rapidfire", Qt::CaseInsensitive) == 0) { rapidfire = true; } - else if (*it == "sticky") { + else if (QString::compare(*it, "sticky", Qt::CaseInsensitive) == 0) { sticky = true; } } @@ -63,7 +70,9 @@ void Button::write( QTextStream &stream ) { stream << "\tButton " << (index+1) << ": "; if (rapidfire) stream << "rapidfire, "; if (sticky) stream << "sticky, "; - stream << (useMouse ? "mouse " : "key ") << keycode << "\n"; + stream << (useMouse ? "mouse " : "key ") << keycode; + if (hasLayout) stream << " layout " << layout.replace(" ", "\\s"); + stream << "\n"; } void Button::release() { @@ -74,6 +83,18 @@ void Button::release() { } void Button::jsevent( int value ) { + if (hasLayout) { + if (value == 1 && !isButtonPressed) { + isButtonPressed = 1; + //Change layout + emit loadLayout(layout); + } + else if (value == 0) { + isButtonPressed = 0; + } + return; + } + bool newval = (value == 1); if (sticky) { //the state of a sticky key only changes on button press, not button release. @@ -113,6 +134,7 @@ void Button::toDefault() { sticky = false; useMouse = false; keycode = 0; + hasLayout = false; timer.stop(); } @@ -120,7 +142,8 @@ bool Button::isDefault() { return (rapidfire == false) && (sticky == false) && (useMouse == false) && - (keycode == 0); + (keycode == 0) && + (hasLayout == false); } QString Button::getName() { @@ -128,7 +151,10 @@ QString Button::getName() { } QString Button::status() { - if (useMouse) { + if (hasLayout) { + return tr("%1 : %2").arg(getName(), layout); + } + else if (useMouse) { return tr("%1 : Mouse %2").arg(getName()).arg(keycode); } else { diff --git a/src/button.h b/src/button.h index 1f1f7e3..ef597e1 100644 --- a/src/button.h +++ b/src/button.h @@ -53,8 +53,13 @@ class Button : public QObject { bool useMouse; int keycode; QTimer timer; + //Layout settings + bool hasLayout; + QString layout; public slots: void timerCalled(); + signals: + void loadLayout(QString name); }; #endif diff --git a/src/button_edit.cpp b/src/button_edit.cpp index 0d37cb8..6fa53c0 100644 --- a/src/button_edit.cpp +++ b/src/button_edit.cpp @@ -4,7 +4,7 @@ #include #include -ButtonEdit::ButtonEdit(Button* butt) +ButtonEdit::ButtonEdit(Button* butt, const QStringList *layoutNames) : QDialog(0) { setModal(true); //build the dialog! @@ -28,6 +28,20 @@ ButtonEdit::ButtonEdit(Button* butt) h->addWidget(chkRapid); v->addLayout(h); + cmbLayout = new QComboBox(this); + cmbLayout->addItem(tr("[UNSET]"), QVariant(QString())); + foreach (const QString& layout, *layoutNames) { + cmbLayout->addItem(layout, layout); + } + //Keep selected layout (if any) + if (button->hasLayout) { + cmbLayout->setCurrentIndex(layoutNames->indexOf(button->layout) + 1); + } + else { + cmbLayout->setCurrentIndex(0); + } + v->addWidget(cmbLayout); + QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel, Qt::Horizontal, this); connect(buttonBox, SIGNAL(accepted()), this, SLOT(accept())); connect(buttonBox, SIGNAL(rejected()), this, SLOT(reject())); @@ -52,6 +66,13 @@ void ButtonEdit::accept() { //if the user chose a mouse button... button->useMouse = btnKey->choseMouse(); button->keycode = btnKey->getValue(); + if (cmbLayout->currentIndex() != 0) { + button->hasLayout = true; + button->layout = cmbLayout->currentText(); + } + else { + button->hasLayout = false; + } QDialog::accept(); } diff --git a/src/button_edit.h b/src/button_edit.h index b886a94..79ca72b 100644 --- a/src/button_edit.h +++ b/src/button_edit.h @@ -4,6 +4,7 @@ #include #include #include +#include //we need to edit a Button #include "button.h" @@ -15,7 +16,7 @@ class ButtonEdit : public QDialog { Q_OBJECT public: - ButtonEdit(Button* butt); + ButtonEdit(Button* butt, const QStringList *layoutNames); void show(); protected slots: void accept(); @@ -23,6 +24,7 @@ class ButtonEdit : public QDialog { Button *button; KeyButton *btnKey; QCheckBox *chkSticky, *chkRapid; + QComboBox *cmbLayout; }; diff --git a/src/buttonw.cpp b/src/buttonw.cpp index bdcba28..ef9b0af 100644 --- a/src/buttonw.cpp +++ b/src/buttonw.cpp @@ -19,7 +19,7 @@ void ButtonWidget::update() { } void ButtonWidget::mouseReleaseEvent( QMouseEvent* e ) { - ButtonEdit* be = new ButtonEdit(button); + ButtonEdit* be = new ButtonEdit(button, &layoutNames); be->exec(); delete be; diff --git a/src/buttonw.h b/src/buttonw.h index a3ddac8..b83e72d 100644 --- a/src/buttonw.h +++ b/src/buttonw.h @@ -17,10 +17,11 @@ class ButtonWidget : public FlashButton { Q_OBJECT public: - ButtonWidget( Button* b, QWidget* parent); + ButtonWidget( Button* b, QWidget* parent ); void jsevent( int val ); //reset the label to match the respective Button's current state. void update(); + QStringList layoutNames; private: void mouseReleaseEvent( QMouseEvent* e ); bool on; diff --git a/src/joypad.h b/src/joypad.h index 4a28aea..731bbf8 100644 --- a/src/joypad.h +++ b/src/joypad.h @@ -58,13 +58,14 @@ class JoyPad : public QObject { JoyPadWidget* widget(QWidget* parent, int i); //called when the joypad is no longer being edited. void releaseWidget(); - protected: + //lookup axes and buttons. These are dictionaries to support //layouts with different numbers of axes/buttons than the current //devices. Note that with the current layout settings, the defined //buttons that don't actually exist on the device may not be contiguous. - QList axes; QList buttons; + protected: + QList axes; //the index of this device (devicenum) int index; diff --git a/src/joypadw.cpp b/src/joypadw.cpp index d1d89c7..86f85d5 100644 --- a/src/joypadw.cpp +++ b/src/joypadw.cpp @@ -103,3 +103,9 @@ void JoyPadWidget::jsevent( const js_event& msg ) { quickset->jsevent(msg); } } + +void JoyPadWidget::updateButtonLayoutLists(const QStringList layoutNames) { + foreach (ButtonWidget *bw, buttons) { + bw->layoutNames = layoutNames; + } +} \ No newline at end of file diff --git a/src/joypadw.h b/src/joypadw.h index 4581693..56c9772 100644 --- a/src/joypadw.h +++ b/src/joypadw.h @@ -26,6 +26,8 @@ class JoyPadWidget : public QWidget { ~JoyPadWidget(); //takes in an event and decides whether or not to flash anything void jsevent(const js_event &msg ); + //Propagate changes in layout list + void updateButtonLayoutLists(const QStringList layoutNames); public slots: //called whenever one of the subwidgets flashes... used to determine //when to emit the flashed() signal. diff --git a/src/layout.cpp b/src/layout.cpp index b7111ca..f705c9d 100644 --- a/src/layout.cpp +++ b/src/layout.cpp @@ -161,6 +161,10 @@ QString LayoutManager::getFileName(const QString& layoutname ) { return QString("%1%2.lyt").arg(settingsDir, layoutname); } +void LayoutManager::loadLayoutFromButton(QString name) { + load(name); +} + bool LayoutManager::load(const QString& name) { //it's VERY easy to load NL :) if (name.isNull()) { @@ -707,6 +711,9 @@ void LayoutManager::addJoyPad(int index, const QString& devpath) { //if we've never seen this device before, make a new one! if (joypad == 0) { joypad = new JoyPad( index, joydev, this ); + foreach (Button *button, joypad->buttons) { + connect(button, &Button::loadLayout, this, &LayoutManager::loadLayoutFromButton); + } joypads.insert(index,joypad); } else { diff --git a/src/layout.h b/src/layout.h index e17fa6a..f1cc0f5 100644 --- a/src/layout.h +++ b/src/layout.h @@ -43,6 +43,8 @@ class LayoutManager : public QObject { //produces a list of the names of all the available layout. QStringList getLayoutNames() const; public slots: + //This is necessary to prevent issues with the overloaded load() function + void loadLayoutFromButton(QString name); //load a layout with a given name bool load(const QString& name); //look for the last loaded layout and try to load that. diff --git a/src/layout_edit.cpp b/src/layout_edit.cpp index 0011270..222b805 100644 --- a/src/layout_edit.cpp +++ b/src/layout_edit.cpp @@ -168,6 +168,11 @@ void LayoutEdit::updateLayoutList() { cmbLayouts->setCurrentIndex(cmbLayouts->count() - 1); } } + //Update layout list for all button edit widgets + for (int i = 0, n = lm->available.count(); i < n; i++) { + const QStringList layoutNames = lm->getLayoutNames(); + ((JoyPadWidget*)padStack->widget(i))->updateButtonLayoutLists(layoutNames); + } } void LayoutEdit::updateJoypadWidgets() {