15 * along with this program; if not, write to the Free Software |
15 * along with this program; if not, write to the Free Software |
16 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA |
16 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA |
17 */ |
17 */ |
18 |
18 |
19 #include <QDialog> |
19 #include <QDialog> |
20 #include <QVBoxLayout> |
20 #include <QGridLayout> |
|
21 #include <QHBoxLayout> |
21 #include <QScrollArea> |
22 #include <QScrollArea> |
22 #include <QPushButton> |
23 #include <QPushButton> |
23 #include <QToolButton> |
24 #include <QToolButton> |
24 #include <QWidgetItem> |
25 #include <QWidgetItem> |
25 #include <QModelIndex> |
26 #include <QModelIndex> |
|
27 #include <QListView> |
|
28 #include <QLineEdit> |
26 #include <QLabel> |
29 #include <QLabel> |
|
30 #include <QSortFilterProxyModel> |
|
31 #include <QFontMetrics> |
|
32 #include <QDebug> |
27 |
33 |
28 #include "flowlayout.h" |
|
29 #include "DataManager.h" |
34 #include "DataManager.h" |
|
35 #include "lineeditcursor.h" |
30 #include "ThemeModel.h" |
36 #include "ThemeModel.h" |
31 #include "themeprompt.h" |
37 #include "themeprompt.h" |
32 |
38 |
33 ThemePrompt::ThemePrompt(QWidget* parent) : QDialog(parent) |
39 ThemePrompt::ThemePrompt(int currentIndex, QWidget* parent) : QDialog(parent) |
34 { |
40 { |
35 setModal(true); |
41 setModal(true); |
36 setWindowFlags(Qt::Sheet); |
42 setWindowFlags(Qt::Sheet); |
37 setWindowModality(Qt::WindowModal); |
43 setWindowModality(Qt::WindowModal); |
38 setMinimumSize(550, 430); |
44 setMinimumSize(550, 430); |
39 resize(550, 430); |
45 resize(550, 430); |
40 setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum); |
46 setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum); |
41 |
47 |
|
48 setStyleSheet("QPushButton { padding: 5px; margin-top: 10px; }"); |
|
49 |
|
50 // Theme model, and a model for setting a filter |
|
51 ThemeModel * themeModel = DataManager::instance().themeModel(); |
|
52 filterModel = new QSortFilterProxyModel(); |
|
53 filterModel->setSourceModel(themeModel); |
|
54 filterModel->setFilterCaseSensitivity(Qt::CaseInsensitive); |
|
55 |
42 // Grid |
56 // Grid |
43 QVBoxLayout * dialogLayout = new QVBoxLayout(this); |
57 QGridLayout * dialogLayout = new QGridLayout(this); |
44 dialogLayout->setSpacing(0); |
58 dialogLayout->setSpacing(0); |
|
59 dialogLayout->setColumnStretch(1, 1); |
|
60 |
|
61 QHBoxLayout * topLayout = new QHBoxLayout(); |
45 |
62 |
46 // Help/prompt message at top |
63 // Help/prompt message at top |
47 QLabel * lblDesc = new QLabel(tr("Select a theme for this map")); |
64 QLabel * lblDesc = new QLabel(tr("Select a theme")); |
48 lblDesc->setStyleSheet("color: #130F2A; background: #F6CB1C; border: solid 4px #F6CB1C; border-top-left-radius: 10px; border-top-right-radius: 10px; padding: auto 20px;"); |
65 lblDesc->setObjectName("lblDesc"); |
|
66 lblDesc->setStyleSheet("#lblDesc { color: #130F2A; background: #F6CB1C; border: solid 4px #F6CB1C; border-top-left-radius: 10px; padding: 4px 10px;}"); |
49 lblDesc->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed); |
67 lblDesc->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed); |
50 lblDesc->setFixedHeight(24); |
68 lblDesc->setFixedHeight(24); |
51 lblDesc->setMinimumWidth(0); |
69 lblDesc->setMinimumWidth(0); |
52 |
70 |
53 // Scroll area and container for theme icons |
71 // Filter text box |
54 QWidget * themesContainer = new QWidget(); |
72 QWidget * filterContainer = new QWidget(); |
55 FlowLayout * themesGrid = new FlowLayout(); |
73 filterContainer->setFixedHeight(24); |
56 themesContainer->setLayout(themesGrid); |
74 filterContainer->setObjectName("filterContainer"); |
57 QScrollArea * scrollArea = new QScrollArea(); |
75 filterContainer->setStyleSheet("#filterContainer { background: #F6CB1C; border-top-right-radius: 10px; padding: 3px; }"); |
58 scrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded); |
76 filterContainer->setFixedWidth(250); |
59 scrollArea->setObjectName("scrollArea"); |
77 txtFilter = new LineEditCursor(filterContainer); |
60 scrollArea->setStyleSheet("QScrollBar, #scrollArea { background-color: #130F2A; } #scrollArea { border-color: #F6CB1C; border-width: 3px; border-top-width: 0; border-style: solid; border-bottom-left-radius: 10px; border-bottom-right-radius: 10px; }"); |
78 txtFilter->setFixedWidth(250); |
61 scrollArea->setWidgetResizable(true); |
79 txtFilter->setFocus(); |
62 scrollArea->setFrameShape(QFrame::NoFrame); |
80 txtFilter->setFixedHeight(22); |
63 scrollArea->setWidget(themesContainer); |
81 connect(txtFilter, SIGNAL(textChanged(const QString &)), this, SLOT(filterChanged(const QString &))); |
|
82 connect(txtFilter, SIGNAL(moveUp()), this, SLOT(moveUp())); |
|
83 connect(txtFilter, SIGNAL(moveDown()), this, SLOT(moveDown())); |
|
84 connect(txtFilter, SIGNAL(moveLeft()), this, SLOT(moveLeft())); |
|
85 connect(txtFilter, SIGNAL(moveRight()), this, SLOT(moveRight())); |
|
86 |
|
87 // Filter label |
|
88 QLabel * lblFilter = new QLabel(tr("Filter: "), txtFilter); |
|
89 QFontMetrics lblMetrics(lblFilter->font()); |
|
90 int lblFilterWidth = lblMetrics.width(lblFilter->text()); |
|
91 lblFilter->setStyleSheet(QString("background: none; margin-left: -%1px; margin-top: 4px;").arg(lblFilterWidth + 5)); |
|
92 txtFilter->setStyleSheet(QString("LineEditCursor, QLabel { border-width: 0px; border-radius: 6px; margin-top: 3px; margin-right: 3px; padding-left: %1px; padding-bottom: 2px; background-color: rgb(23, 11, 54); } LineEditCursor:hover, LineEditCursor:focus { background-color: rgb(13, 5, 68); }").arg(lblFilterWidth + 5)); |
|
93 |
|
94 // Corner widget |
|
95 QLabel * corner = new QLabel(); |
|
96 corner->setPixmap(QPixmap(QString::fromUtf8(":/res/inverse-corner-bl.png"))); |
|
97 corner->setFixedSize(10, 10); |
|
98 |
|
99 // Add widgets to top layout |
|
100 topLayout->addWidget(lblDesc); |
|
101 topLayout->addWidget(filterContainer); |
|
102 topLayout->addWidget(corner, 0, Qt::AlignBottom); |
|
103 topLayout->addStretch(1); |
64 |
104 |
65 // Cancel button (closes dialog) |
105 // Cancel button (closes dialog) |
66 QPushButton * btnCancel = new QPushButton(tr("Cancel")); |
106 QPushButton * btnCancel = new QPushButton(tr("Cancel")); |
67 btnCancel->setStyleSheet("padding: 5px; margin-top: 10px;"); |
|
68 connect(btnCancel, SIGNAL(clicked()), this, SLOT(reject())); |
107 connect(btnCancel, SIGNAL(clicked()), this, SLOT(reject())); |
69 |
108 |
|
109 // Select button |
|
110 QPushButton * btnSelect = new QPushButton(tr("Use selected theme")); |
|
111 btnSelect->setDefault(true); |
|
112 connect(btnSelect, SIGNAL(clicked()), this, SLOT(onAccepted())); |
|
113 |
|
114 // Add themes |
|
115 list = new ThemeListView(); |
|
116 list->setModel(filterModel); |
|
117 list->setViewMode(QListView::IconMode); |
|
118 list->setResizeMode(QListView::Adjust); |
|
119 list->setMovement(QListView::Static); |
|
120 list->setEditTriggers(QAbstractItemView::NoEditTriggers); |
|
121 list->setSpacing(8); |
|
122 list->setWordWrap(true); |
|
123 list->setSelectionMode(QAbstractItemView::SingleSelection); |
|
124 list->setObjectName("themeList"); |
|
125 list->setCurrentIndex(filterModel->index(currentIndex, 0)); |
|
126 connect(list, SIGNAL(activated(const QModelIndex &)), this, SLOT(themeChosen(const QModelIndex &))); |
|
127 connect(list, SIGNAL(clicked(const QModelIndex &)), this, SLOT(themeChosen(const QModelIndex &))); |
|
128 |
70 // Add elements to layouts |
129 // Add elements to layouts |
71 dialogLayout->addWidget(lblDesc, 0); |
130 dialogLayout->addLayout(topLayout, 0, 0, 1, 3); |
72 dialogLayout->addWidget(scrollArea, 1); |
131 dialogLayout->addWidget(list, 1, 0, 1, 3); |
73 dialogLayout->addWidget(btnCancel, 0, Qt::AlignLeft); |
132 dialogLayout->addWidget(btnCancel, 2, 0, 1, 1, Qt::AlignLeft); |
|
133 dialogLayout->addWidget(btnSelect, 2, 2, 1, 1, Qt::AlignRight); |
|
134 } |
74 |
135 |
75 // Tooltip label for theme name |
136 void ThemePrompt::moveUp() |
76 lblToolTip = new QLabel(this); |
137 { |
|
138 list->setCurrentIndex(list->moveCursor(QAbstractItemView::MoveUp, Qt::NoModifier)); |
|
139 } |
77 |
140 |
78 // Add theme buttons |
141 void ThemePrompt::moveDown() |
79 ThemeModel * themes = DataManager::instance().themeModel(); |
142 { |
80 for (int i = 0; i < themes->rowCount(); i++) |
143 list->setCurrentIndex(list->moveCursor(QAbstractItemView::MoveDown, Qt::NoModifier)); |
81 { |
144 } |
82 QModelIndex index = themes->index(i, 0); |
145 |
83 QToolButton * btn = new QToolButton(); |
146 void ThemePrompt::moveLeft() |
84 bool dlc = themes->data(index, Qt::UserRole + 2).toBool(); |
147 { |
85 btn->setToolButtonStyle(Qt::ToolButtonTextUnderIcon); |
148 list->setCurrentIndex(list->moveCursor(QAbstractItemView::MoveLeft, Qt::NoModifier)); |
86 btn->setIcon(qVariantValue<QIcon>(themes->data(index, Qt::UserRole))); |
149 } |
87 btn->setText((dlc ? "*" : "") + themes->data(index, Qt::DisplayRole).toString()); |
150 |
88 btn->setIconSize(QSize(60, 60)); |
151 void ThemePrompt::moveRight() |
89 btn->setProperty("themeID", QVariant(i)); |
152 { |
90 btn->setStyleSheet("padding: 2px;"); |
153 list->setCurrentIndex(list->moveCursor(QAbstractItemView::MoveRight, Qt::NoModifier)); |
91 connect(btn, SIGNAL(clicked()), this, SLOT(themeClicked())); |
154 } |
92 themesGrid->addWidget(btn); |
155 |
93 } |
156 void ThemePrompt::onAccepted() |
|
157 { |
|
158 themeChosen(list->currentIndex()); |
94 } |
159 } |
95 |
160 |
96 // When a theme is selected |
161 // When a theme is selected |
97 void ThemePrompt::themeClicked() |
162 void ThemePrompt::themeChosen(const QModelIndex & index) |
98 { |
163 { |
99 QWidget * btn = (QWidget*)sender(); |
164 done(filterModel->mapToSource(index).row() + 1); // Since returning 0 means canceled |
100 done(btn->property("themeID").toInt() + 1); // Since returning 0 means canceled |
|
101 } |
165 } |
|
166 |
|
167 // When the text in the filter text box is changed |
|
168 void ThemePrompt::filterChanged(const QString & text) |
|
169 { |
|
170 filterModel->setFilterFixedString(text); |
|
171 list->setCurrentIndex(filterModel->index(0, 0)); |
|
172 } |