241 lines
8.6 KiB
C++
241 lines
8.6 KiB
C++
#include "joypadw.h"
|
|
|
|
JoyPadWidget::JoyPadWidget( JoyPad* jp, int i, QWidget* parent )
|
|
: QWidget(parent) {
|
|
//initialize things, build the accessible dialog
|
|
joypad = jp;
|
|
index = i;
|
|
flashcount = 0;
|
|
quickset = NULL;
|
|
|
|
// Create main vertical layout
|
|
layoutMain = new QVBoxLayout(this);
|
|
layoutMain->setSpacing(10);
|
|
layoutMain->setMargin(10);
|
|
|
|
// Create horizontal layout for axes and buttons groups
|
|
topLayout = new QHBoxLayout();
|
|
|
|
// Create axes group
|
|
axesGroup = new QGroupBox("Axes", this);
|
|
QVBoxLayout *axesLayout = new QVBoxLayout(axesGroup);
|
|
|
|
axesList = new QListWidget(axesGroup);
|
|
axesList->setAccessibleName("Axes List");
|
|
axesList->setAccessibleDescription("List of joystick axes for configuration");
|
|
axesLayout->addWidget(axesList);
|
|
|
|
btnConfigureAxis = new QPushButton("Configure Selected Axis", axesGroup);
|
|
btnConfigureAxis->setEnabled(false);
|
|
btnConfigureAxis->setAccessibleDescription("Configure the currently selected axis");
|
|
btnConfigureAxis->setFocusPolicy(Qt::TabFocus);
|
|
connect(btnConfigureAxis, SIGNAL(clicked()), this, SLOT(configureSelectedAxis()));
|
|
axesLayout->addWidget(btnConfigureAxis);
|
|
|
|
axisStatusLabel = new QLabel("Select an axis to configure", axesGroup);
|
|
axisStatusLabel->setWordWrap(true);
|
|
axesLayout->addWidget(axisStatusLabel);
|
|
|
|
// Create buttons group
|
|
buttonsGroup = new QGroupBox("Buttons", this);
|
|
QVBoxLayout *buttonsLayout = new QVBoxLayout(buttonsGroup);
|
|
|
|
buttonsList = new QListWidget(buttonsGroup);
|
|
buttonsList->setAccessibleName("Buttons List");
|
|
buttonsList->setAccessibleDescription("List of joystick buttons for configuration");
|
|
buttonsLayout->addWidget(buttonsList);
|
|
|
|
btnConfigureButton = new QPushButton("Configure Selected Button", buttonsGroup);
|
|
btnConfigureButton->setEnabled(false);
|
|
btnConfigureButton->setAccessibleDescription("Configure the currently selected button");
|
|
btnConfigureButton->setFocusPolicy(Qt::TabFocus);
|
|
connect(btnConfigureButton, SIGNAL(clicked()), this, SLOT(configureSelectedButton()));
|
|
buttonsLayout->addWidget(btnConfigureButton);
|
|
|
|
buttonStatusLabel = new QLabel("Select a button to configure", buttonsGroup);
|
|
buttonStatusLabel->setWordWrap(true);
|
|
buttonsLayout->addWidget(buttonStatusLabel);
|
|
|
|
// Add groups to horizontal layout
|
|
topLayout->addWidget(axesGroup);
|
|
topLayout->addWidget(buttonsGroup);
|
|
layoutMain->addLayout(topLayout);
|
|
|
|
// Create the underlying widgets for compatibility
|
|
foreach (Axis *axis, joypad->axes) {
|
|
AxisWidget *aw = new AxisWidget(axis, this);
|
|
aw->setVisible(false); // Hide the old widgets
|
|
axes.append(aw);
|
|
connect( aw, SIGNAL( flashed( bool ) ), this, SLOT( flash( bool )));
|
|
}
|
|
|
|
foreach (Button *button, joypad->buttons) {
|
|
ButtonWidget *bw = new ButtonWidget(button, this);
|
|
bw->setVisible(false); // Hide the old widgets
|
|
buttons.append(bw);
|
|
connect( bw, SIGNAL( flashed( bool ) ), this, SLOT( flash( bool )));
|
|
}
|
|
|
|
// Control buttons
|
|
QHBoxLayout *controlLayout = new QHBoxLayout();
|
|
btnClear = new QPushButton(QIcon::fromTheme("edit-clear"), "Clear All", this);
|
|
btnClear->setAccessibleDescription("Clear all axis and button configurations");
|
|
btnClear->setFocusPolicy(Qt::StrongFocus);
|
|
btnClear->setAccessibleName("Clear All Button");
|
|
connect(btnClear, SIGNAL(clicked()), this, SLOT(clear()));
|
|
controlLayout->addWidget(btnClear);
|
|
|
|
btnAll = new QPushButton("Quick Set", this);
|
|
btnAll->setAccessibleDescription("Quick configuration mode for all controls");
|
|
btnAll->setFocusPolicy(Qt::StrongFocus); // Try StrongFocus instead of TabFocus
|
|
btnAll->setAccessibleName("Quick Set Button");
|
|
connect(btnAll, SIGNAL(clicked()), this, SLOT(setAll()));
|
|
controlLayout->addWidget(btnAll);
|
|
|
|
controlLayout->addStretch();
|
|
layoutMain->addLayout(controlLayout);
|
|
|
|
// Connect selection change signals
|
|
connect(axesList, SIGNAL(itemSelectionChanged()), this, SLOT(onAxisSelectionChanged()));
|
|
connect(buttonsList, SIGNAL(itemSelectionChanged()), this, SLOT(onButtonSelectionChanged()));
|
|
|
|
// Set explicit tab order to ensure all widgets are accessible
|
|
setTabOrder(axesList, btnConfigureAxis);
|
|
setTabOrder(btnConfigureAxis, buttonsList);
|
|
setTabOrder(buttonsList, btnConfigureButton);
|
|
setTabOrder(btnConfigureButton, btnClear);
|
|
setTabOrder(btnClear, btnAll);
|
|
|
|
// Populate the lists
|
|
update();
|
|
}
|
|
|
|
JoyPadWidget::~JoyPadWidget() {
|
|
//so the joypad knows that we're done.
|
|
joypad->releaseWidget();
|
|
}
|
|
|
|
void JoyPadWidget::flash( bool on ) {
|
|
//true iff this entire widget was considered "flashed" before
|
|
bool wasOn = (flashcount != 0);
|
|
|
|
//adjust the count based on this new flash
|
|
flashcount += (on?1:-1);
|
|
|
|
//if we were on and should now be off, or visa versa, flash the whole widget
|
|
if (wasOn != (flashcount != 0)) {
|
|
emit flashed(index);
|
|
}
|
|
}
|
|
|
|
void JoyPadWidget::update() {
|
|
// Update underlying widgets
|
|
foreach (AxisWidget *axis, axes) {
|
|
axis->update();
|
|
}
|
|
foreach (ButtonWidget *button, buttons) {
|
|
button->update();
|
|
}
|
|
|
|
// Update accessible lists
|
|
axesList->clear();
|
|
for (int i = 0; i < axes.size(); i++) {
|
|
QString axisName = QString("Axis %1").arg(i + 1);
|
|
QString axisDesc = axes[i]->text(); // Get current configuration description
|
|
axesList->addItem(QString("%1: %2").arg(axisName, axisDesc));
|
|
}
|
|
|
|
buttonsList->clear();
|
|
for (int i = 0; i < buttons.size(); i++) {
|
|
QString buttonName = QString("Button %1").arg(i + 1);
|
|
QString buttonDesc = buttons[i]->text(); // Get current configuration description
|
|
buttonsList->addItem(QString("%1: %2").arg(buttonName, buttonDesc));
|
|
}
|
|
}
|
|
|
|
void JoyPadWidget::clear() {
|
|
joypad->toDefault();
|
|
update();
|
|
}
|
|
|
|
void JoyPadWidget::setAll() {
|
|
//quickset is NULL if there is no quickset dialog, and a pointer to the
|
|
//dialog otherwise. This is so we can forward jsevents properly.
|
|
quickset = new QuickSet(joypad, this);
|
|
quickset->exec();
|
|
update();
|
|
delete quickset;
|
|
quickset = NULL;
|
|
}
|
|
|
|
void JoyPadWidget::jsevent( const js_event& msg ) {
|
|
//notify the component this event applies to. this cannot generate anything
|
|
//other than a flash :)
|
|
unsigned int type = msg.type & ~JS_EVENT_INIT;
|
|
if (type == JS_EVENT_AXIS) {
|
|
if (msg.number < axes.size()) axes[msg.number]->jsevent(msg.value);
|
|
else debug_mesg("DEBUG: axis index out of range: %d\n", msg.value);
|
|
}
|
|
else if (type == JS_EVENT_BUTTON) {
|
|
if (msg.number < buttons.size()) buttons[msg.number]->jsevent(msg.value);
|
|
else debug_mesg("DEBUG: button index out of range: %d\n", msg.value);
|
|
}
|
|
//if we're doing quickset, it needs to know when we do something.
|
|
if (quickset != NULL) {
|
|
quickset->jsevent(msg);
|
|
}
|
|
}
|
|
|
|
void JoyPadWidget::updateButtonLayoutLists(const QStringList layoutNames) {
|
|
foreach (ButtonWidget *bw, buttons) {
|
|
bw->layoutNames = layoutNames;
|
|
}
|
|
}
|
|
|
|
void JoyPadWidget::configureSelectedAxis() {
|
|
int selectedRow = axesList->currentRow();
|
|
if (selectedRow >= 0 && selectedRow < axes.size()) {
|
|
// Use the public configure method for accessibility
|
|
axes[selectedRow]->configure();
|
|
// Update the display after configuration
|
|
update();
|
|
}
|
|
}
|
|
|
|
void JoyPadWidget::configureSelectedButton() {
|
|
int selectedRow = buttonsList->currentRow();
|
|
if (selectedRow >= 0 && selectedRow < buttons.size()) {
|
|
// Use the public configure method for accessibility
|
|
buttons[selectedRow]->configure();
|
|
// Update the display after configuration
|
|
update();
|
|
}
|
|
}
|
|
|
|
void JoyPadWidget::onAxisSelectionChanged() {
|
|
bool hasSelection = axesList->currentRow() >= 0;
|
|
btnConfigureAxis->setEnabled(hasSelection);
|
|
|
|
if (hasSelection) {
|
|
int selectedRow = axesList->currentRow();
|
|
if (selectedRow < axes.size()) {
|
|
axisStatusLabel->setText(QString("Selected: %1").arg(axesList->currentItem()->text()));
|
|
}
|
|
} else {
|
|
axisStatusLabel->setText("Select an axis to configure");
|
|
}
|
|
}
|
|
|
|
void JoyPadWidget::onButtonSelectionChanged() {
|
|
bool hasSelection = buttonsList->currentRow() >= 0;
|
|
btnConfigureButton->setEnabled(hasSelection);
|
|
|
|
if (hasSelection) {
|
|
int selectedRow = buttonsList->currentRow();
|
|
if (selectedRow < buttons.size()) {
|
|
buttonStatusLabel->setText(QString("Selected: %1").arg(buttonsList->currentItem()->text()));
|
|
}
|
|
} else {
|
|
buttonStatusLabel->setText("Select a button to configure");
|
|
}
|
|
} |