--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/QTfrontend/ui/widget/keybinder.cpp Sat Dec 29 22:50:10 2012 +0100
@@ -0,0 +1,301 @@
+/*
+ * Hedgewars, a free turn based strategy game
+ * Copyright (c) 2004-2012 Andrey Korotaev <unC0Rr@gmail.com>
+ *
+ * This program 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; version 2 of the License
+ *
+ * This program 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 this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include "keybinder.h"
+#include "HWApplication.h"
+#include "DataManager.h"
+#include <QHBoxLayout>
+#include <QScrollArea>
+#include <QTableWidget>
+#include <QTableWidgetItem>
+#include <QStandardItemModel>
+#include <QAbstractItemModel>
+#include <QListWidget>
+#include <QListWidgetItem>
+#include <QPushButton>
+#include <QHeaderView>
+#include <QComboBox>
+#include <QLabel>
+#include <QFrame>
+#include <QDebug>
+
+KeyBinder::KeyBinder(QWidget * parent, const QString & helpText, const QString & defaultText, const QString & resetButtonText) : QWidget(parent)
+{
+ this->defaultText = defaultText;
+ enableSignal = false;
+
+ // Two-column tab layout
+ QHBoxLayout * pageKeysLayout = new QHBoxLayout(this);
+ pageKeysLayout->setSpacing(0);
+ pageKeysLayout->setContentsMargins(0, 0, 0, 0);
+
+ // Table for category list
+ QVBoxLayout * catListContainer = new QVBoxLayout();
+ catListContainer->setContentsMargins(10, 10, 10, 10);
+ catList = new QListWidget();
+ catList->setFixedWidth(180);
+ catList->setStyleSheet("QListWidget::item { font-size: 14px; } QListWidget:hover { border-color: #F6CB1C; } QListWidget::item:selected { background: #150A61; color: yellow; }");
+ catList->setFocusPolicy(Qt::NoFocus);
+ connect(catList, SIGNAL(currentRowChanged(int)), this, SLOT(changeBindingsPage(int)));
+ catListContainer->addWidget(catList);
+ pageKeysLayout->addLayout(catListContainer);
+
+ // Reset all binds button
+ if (!resetButtonText.isEmpty())
+ {
+ QPushButton * btnResetAll = new QPushButton(resetButtonText);
+ catListContainer->addWidget(btnResetAll);
+ btnResetAll->setFixedHeight(40);
+ catListContainer->setStretch(1, 0);
+ catListContainer->setSpacing(10);
+ connect(btnResetAll, SIGNAL(clicked()), this, SIGNAL(resetAllBinds()));
+ }
+
+ // Container for pages of key bindings
+ QWidget * bindingsPagesContainer = new QWidget();
+ QVBoxLayout * rightLayout = new QVBoxLayout(bindingsPagesContainer);
+
+ // Scroll area for key bindings
+ QScrollArea * scrollArea = new QScrollArea();
+ scrollArea->setContentsMargins(0, 0, 0, 0);
+ scrollArea->setWidget(bindingsPagesContainer);
+ scrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);
+ scrollArea->setWidgetResizable(true);
+ scrollArea->setFrameShape(QFrame::NoFrame);
+ scrollArea->setStyleSheet("background: #130F2A;");
+
+ // Add key binding pages to bindings tab
+ pageKeysLayout->addWidget(scrollArea);
+ pageKeysLayout->setStretch(1, 1);
+
+ // Custom help text
+ QLabel * helpLabel = new QLabel();
+ helpLabel->setText(helpText);
+ helpLabel->setStyleSheet("color: #130F2A; background: #F6CB1C; border: solid 4px #F6CB1C; border-radius: 10px; padding: auto 20px;");
+ helpLabel->setFixedHeight(24);
+ rightLayout->addWidget(helpLabel, 0, Qt::AlignCenter);
+
+ // Category list and bind table row heights
+ const int rowHeight = 20;
+ QSize catSize, headerSize;
+ catSize.setHeight(36);
+ headerSize.setHeight(24);
+
+ // Category list header
+ QListWidgetItem * catListHeader = new QListWidgetItem(tr("Category"));
+ catListHeader->setSizeHint(headerSize);
+ catListHeader->setFlags(Qt::NoItemFlags);
+ catListHeader->setForeground(QBrush(QColor("#130F2A")));
+ catListHeader->setBackground(QBrush(QColor("#F6CB1C")));
+ catListHeader->setTextAlignment(Qt::AlignCenter);
+ catList->addItem(catListHeader);
+
+ // Populate
+ bindingsPages = new QHBoxLayout();
+ bindingsPages->setContentsMargins(0, 0, 0, 0);
+ rightLayout->addLayout(bindingsPages);
+ QWidget * curPage = NULL;
+ QVBoxLayout * curLayout = NULL;
+ QTableWidget * curTable = NULL;
+ bool bFirstPage = true;
+ selectedBindTable = NULL;
+ bindComboBoxCellMappings = new QHash<QObject *, QTableWidgetItem *>();
+ bindCellComboBoxMappings = new QHash<QTableWidgetItem *, QComboBox *>();
+ for (int i = 0; i < BINDS_NUMBER; i++)
+ {
+ if (cbinds[i].category != NULL)
+ {
+ // Add stretch at end of previous layout
+ if (curLayout != NULL) curLayout->insertStretch(-1, 1);
+
+ // Category list item
+ QListWidgetItem * catItem = new QListWidgetItem(HWApplication::translate("binds (categories)", cbinds[i].category));
+ catItem->setSizeHint(catSize);
+ catList->addItem(catItem);
+
+ // Create new page
+ curPage = new QWidget();
+ curLayout = new QVBoxLayout(curPage);
+ curLayout->setSpacing(2);
+ bindingsPages->addWidget(curPage);
+ if (!bFirstPage) curPage->setVisible(false);
+ }
+
+ // Description
+ if (cbinds[i].description != NULL)
+ {
+ QLabel * desc = new QLabel(HWApplication::translate("binds (descriptions)", cbinds[i].description));
+ curLayout->addWidget(desc, 0);
+ QFrame * divider = new QFrame();
+ divider->setFrameShape(QFrame::HLine);
+ divider->setFrameShadow(QFrame::Plain);
+ curLayout->addWidget(divider, 0);
+ }
+
+ // New table
+ if (cbinds[i].category != NULL || cbinds[i].description != NULL)
+ {
+ curTable = new QTableWidget(0, 2);
+ curTable->verticalHeader()->setVisible(false);
+ curTable->horizontalHeader()->setVisible(false);
+ curTable->horizontalHeader()->setResizeMode(QHeaderView::Stretch);
+ curTable->verticalHeader()->setDefaultSectionSize(rowHeight);
+ curTable->setShowGrid(false);
+ curTable->setStyleSheet("QTableWidget { border: none; } ");
+ curTable->setSelectionBehavior(QAbstractItemView::SelectRows);
+ curTable->setSelectionMode(QAbstractItemView::SingleSelection);
+ curTable->setFocusPolicy(Qt::NoFocus);
+ connect(curTable, SIGNAL(itemSelectionChanged()), this, SLOT(bindSelectionChanged()));
+ connect(curTable, SIGNAL(itemClicked(QTableWidgetItem *)), this, SLOT(bindCellClicked(QTableWidgetItem *)));
+ curLayout->addWidget(curTable, 0);
+ }
+
+ // Hidden combo box
+ QComboBox * comboBox = CBBind[i] = new QComboBox(curTable);
+ comboBox->setModel((QAbstractItemModel*)DataManager::instance().bindsModel());
+ comboBox->setVisible(false);
+ comboBox->setFixedWidth(200);
+
+ // Table row
+ int row = curTable->rowCount();
+ QTableWidgetItem * nameCell = new QTableWidgetItem(HWApplication::translate("binds", cbinds[i].name));
+ nameCell->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled);
+ curTable->insertRow(row);
+ curTable->setItem(row, 0, nameCell);
+ QTableWidgetItem * bindCell = new QTableWidgetItem(comboBox->currentText());
+ bindCell->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled);
+ curTable->setItem(row, 1, bindCell);
+ curTable->resizeColumnsToContents();
+ curTable->setFixedHeight(curTable->verticalHeader()->length() + 10);
+
+ // Updates the text in the table cell
+ connect(comboBox, SIGNAL(currentIndexChanged(const QString &)), this, SLOT(bindChanged(const QString &)));
+
+ // Map combo box and that row's cells to each other
+ bindComboBoxCellMappings->insert(comboBox, bindCell);
+ bindCellComboBoxMappings->insert(nameCell, comboBox);
+ bindCellComboBoxMappings->insert(bindCell, comboBox);
+ }
+
+ // Add stretch at end of last layout
+ if (curLayout != NULL) curLayout->insertStretch(-1, 1);
+
+ // Go to first page
+ catList->setCurrentItem(catList->item(1));
+
+ enableSignal = true;
+}
+
+KeyBinder::~KeyBinder()
+{
+ delete bindComboBoxCellMappings;
+ delete bindCellComboBoxMappings;
+}
+
+// Switches between different pages of key binds
+void KeyBinder::changeBindingsPage(int page)
+{
+ page--; // Disregard first item (the list header)
+ int pages = bindingsPages->count();
+ for (int i = 0; i < pages; i++)
+ bindingsPages->itemAt(i)->widget()->setVisible(false);
+ bindingsPages->itemAt(page)->widget()->setVisible(true);
+}
+
+// When a key bind combobox value is changed, updates the table cell text
+void KeyBinder::bindChanged(const QString & text)
+{
+ bindComboBoxCellMappings->value(sender())->setText(text);
+
+ if (enableSignal)
+ {
+ for (int i = 0; i < BINDS_NUMBER; i++)
+ {
+ if (CBBind[i] == sender())
+ {
+ emit bindUpdate(i);
+ break;
+ }
+ }
+ }
+}
+
+// When a row in a key bind table is clicked, this shows the popup
+void KeyBinder::bindCellClicked(QTableWidgetItem * item)
+{
+ QComboBox * box = bindCellComboBoxMappings->value(item);
+ QTableWidget * table = item->tableWidget();
+ QFrame * frame = box->findChild<QFrame*>();
+
+ box->showPopup();
+ frame->move(
+ frame->x() + table->horizontalHeader()->sectionSize(0),
+ frame->y() + (table->verticalHeader()->defaultSectionSize() * item->row())
+ );
+}
+
+// When a new row in a bind table is *selected*, this clears selection in any other table
+void KeyBinder::bindSelectionChanged()
+{
+ QTableWidget * theSender = (QTableWidget*)sender();
+ if (theSender != selectedBindTable)
+ {
+ if (selectedBindTable != NULL)
+ selectedBindTable->clearSelection();
+ selectedBindTable = theSender;
+ }
+}
+
+// Set a combobox's index
+void KeyBinder::setBindIndex(int keyIndex, int bindIndex)
+{
+ enableSignal = false;
+ CBBind[keyIndex]->setCurrentIndex(bindIndex);
+ enableSignal = true;
+}
+
+// Return a combobox's selected index
+int KeyBinder::bindIndex(int keyIndex)
+{
+ return CBBind[keyIndex]->currentIndex();
+}
+
+// Clears selection and goes to first category
+void KeyBinder::resetInterface()
+{
+ enableSignal = false;
+
+ catList->setCurrentItem(catList->item(1));
+ changeBindingsPage(1);
+ if (selectedBindTable != NULL)
+ {
+ selectedBindTable->clearSelection();
+ selectedBindTable = NULL;
+ }
+
+ // Default bind text
+ DataManager::instance().bindsModel()->item(0)->setData(defaultText, Qt::DisplayRole);
+ for (int i = 0; i < BINDS_NUMBER; i++)
+ {
+ CBBind[i]->setModel(DataManager::instance().bindsModel());
+ CBBind[i]->setCurrentIndex(0);
+ bindComboBoxCellMappings->value(CBBind[i])->setText(defaultText);
+ }
+
+ enableSignal = true;
+}