diff options
author | Petr Mrázek <peterix@gmail.com> | 2014-06-02 00:49:53 +0200 |
---|---|---|
committer | Petr Mrázek <peterix@gmail.com> | 2014-06-09 01:38:31 +0200 |
commit | f485885757e287546bb27bda5906bfa4adc5494a (patch) | |
tree | 02766b67b4760e0b36c19bd3a5f0c34ed0693f7e /gui/pagedialog | |
parent | 48d3052ac1bf55dfc0d149d5e2590bcd6545dc67 (diff) | |
download | MultiMC-f485885757e287546bb27bda5906bfa4adc5494a.tar MultiMC-f485885757e287546bb27bda5906bfa4adc5494a.tar.gz MultiMC-f485885757e287546bb27bda5906bfa4adc5494a.tar.lz MultiMC-f485885757e287546bb27bda5906bfa4adc5494a.tar.xz MultiMC-f485885757e287546bb27bda5906bfa4adc5494a.zip |
Add and implement pages and page dialog.
Diffstat (limited to 'gui/pagedialog')
-rw-r--r-- | gui/pagedialog/PageDialog.cpp | 154 | ||||
-rw-r--r-- | gui/pagedialog/PageDialog.h | 50 | ||||
-rw-r--r-- | gui/pagedialog/PageDialog_p.h | 106 |
3 files changed, 310 insertions, 0 deletions
diff --git a/gui/pagedialog/PageDialog.cpp b/gui/pagedialog/PageDialog.cpp new file mode 100644 index 00000000..0dda7c1f --- /dev/null +++ b/gui/pagedialog/PageDialog.cpp @@ -0,0 +1,154 @@ +/* Copyright 2014 MultiMC Contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "PageDialog.h" +#include "gui/Platform.h" +#include <QStackedLayout> +#include <QPushButton> +#include <QSortFilterProxyModel> +#include "MultiMC.h" +#include <QStyledItemDelegate> +#include <QListView> +#include <QLineEdit> +#include <QLabel> +#include <QDialogButtonBox> +#include <QGridLayout> + +#include "PageDialog_p.h" +#include <gui/widgets/IconLabel.h> + +class PageEntryFilterModel : public QSortFilterProxyModel +{ +public: + explicit PageEntryFilterModel(QObject *parent = 0) : QSortFilterProxyModel(parent) + { + } + +protected: + bool filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const + { + // Regular contents check, then check page-filter. + if (QSortFilterProxyModel::filterAcceptsRow(sourceRow, sourceParent)) + return true; + + const QString pattern = filterRegExp().pattern(); + const auto model = static_cast<PageModel *>(sourceModel()); + const auto page = model->pages().at(sourceRow); + return page->shouldDisplay(); + } +}; + +PageDialog::PageDialog(BasePageProviderPtr pageProvider, QWidget *parent) : QDialog(parent) +{ + MultiMCPlatform::fixWM_CLASS(this); + createUI(); + setWindowTitle(pageProvider->dialogTitle()); + + m_model = new PageModel(this); + m_proxyModel = new PageEntryFilterModel(this); + int firstIndex = -1; + auto pages = pageProvider->getPages(); + for(auto page: pages) + { + page->index = m_pageStack->addWidget(dynamic_cast<QWidget *>(page)); + if(firstIndex == -1) + { + firstIndex = page->index; + } + } + m_model->setPages(pages); + + m_proxyModel->setSourceModel(m_model); + m_proxyModel->setFilterCaseSensitivity(Qt::CaseInsensitive); + + m_pageList->setIconSize(QSize(pageIconSize, pageIconSize)); + m_pageList->setSelectionMode(QAbstractItemView::SingleSelection); + m_pageList->setVerticalScrollMode(QAbstractItemView::ScrollPerPixel); + m_pageList->setModel(m_proxyModel); + connect(m_pageList->selectionModel(), SIGNAL(currentRowChanged(QModelIndex,QModelIndex)), + this, SLOT(currentChanged(QModelIndex))); + + m_pageStack->setStackingMode(QStackedLayout::StackOne); + m_pageList->setFocus(); +} + +void PageDialog::createUI() +{ + m_pageStack = new QStackedLayout; + m_filter = new QLineEdit; + m_pageList = new PageView; + m_header = new QLabel(); + m_iconHeader = new IconLabel(this, QIcon::fromTheme("bug"), QSize(24,24)); + + QFont headerLabelFont = m_header->font(); + headerLabelFont.setBold(true); + const int pointSize = headerLabelFont.pointSize(); + if (pointSize > 0) + headerLabelFont.setPointSize(pointSize + 2); + m_header->setFont(headerLabelFont); + + QHBoxLayout *headerHLayout = new QHBoxLayout; + const int leftMargin = MMC->style()->pixelMetric(QStyle::PM_LayoutLeftMargin); + headerHLayout->addSpacerItem( + new QSpacerItem(leftMargin, 0, QSizePolicy::Fixed, QSizePolicy::Ignored)); + headerHLayout->addWidget(m_header); + headerHLayout->addSpacerItem( + new QSpacerItem(0, 0, QSizePolicy::Expanding, QSizePolicy::Ignored)); + headerHLayout->addWidget(m_iconHeader); + + m_pageStack->setMargin(0); + m_pageStack->addWidget(new QWidget(this)); + + QDialogButtonBox *buttons = new QDialogButtonBox( + QDialogButtonBox::Ok | QDialogButtonBox::Apply | QDialogButtonBox::Cancel); + buttons->button(QDialogButtonBox::Ok)->setDefault(true); + connect(buttons->button(QDialogButtonBox::Apply), SIGNAL(clicked()), this, SLOT(apply())); + connect(buttons, SIGNAL(accepted()), this, SLOT(accept())); + connect(buttons, SIGNAL(rejected()), this, SLOT(reject())); + + QGridLayout *mainGridLayout = new QGridLayout; + mainGridLayout->addLayout(headerHLayout, 0, 1, 1, 1); + mainGridLayout->addWidget(m_pageList, 0, 0, 2, 1); + mainGridLayout->addLayout(m_pageStack, 1, 1, 1, 1); + mainGridLayout->addWidget(buttons, 2, 0, 1, 2); + mainGridLayout->setColumnStretch(1, 4); + setLayout(mainGridLayout); +} + +void PageDialog::showPage(int row) +{ + auto page = m_model->pages().at(row); + m_pageStack->setCurrentIndex(page->index); + m_header->setText(page->displayName()); + m_iconHeader->setIcon(page->icon()); +} + +void PageDialog::currentChanged(const QModelIndex ¤t) +{ + if (current.isValid()) + { + showPage(m_proxyModel->mapToSource(current).row()); + } + else + { + m_pageStack->setCurrentIndex(0); + m_header->setText(QString()); + m_iconHeader->setIcon(QIcon::fromTheme("bug")); + } +} + +void PageDialog::apply() +{ +} diff --git a/gui/pagedialog/PageDialog.h b/gui/pagedialog/PageDialog.h new file mode 100644 index 00000000..880b7df4 --- /dev/null +++ b/gui/pagedialog/PageDialog.h @@ -0,0 +1,50 @@ +/* Copyright 2014 MultiMC Contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once +#include <QDialog> +#include <QModelIndex> +#include <gui/pages/BasePageProvider.h> + +class IconLabel; +class QSortFilterProxyModel; +class PageModel; +class QLabel; +class QListView; +class QLineEdit; +class QStackedLayout; + +class PageDialog : public QDialog +{ + Q_OBJECT +public: + explicit PageDialog(BasePageProviderPtr pageProvider, QWidget *parent = 0); + virtual ~PageDialog() {}; +private: + void createUI(); +private slots: + void apply(); + void currentChanged(const QModelIndex ¤t); + void showPage(int row); + +private: + QSortFilterProxyModel *m_proxyModel; + PageModel *m_model; + QStackedLayout *m_pageStack; + QLineEdit *m_filter; + QListView *m_pageList; + QLabel *m_header; + IconLabel *m_iconHeader; +}; diff --git a/gui/pagedialog/PageDialog_p.h b/gui/pagedialog/PageDialog_p.h new file mode 100644 index 00000000..36e641e3 --- /dev/null +++ b/gui/pagedialog/PageDialog_p.h @@ -0,0 +1,106 @@ +#pragma once +#include <QListView> +#include <QStyledItemDelegate> +#include <QEvent> +#include <QScrollBar> + +const int pageIconSize = 24; + +class PageViewDelegate : public QStyledItemDelegate +{ +public: + PageViewDelegate(QObject *parent) : QStyledItemDelegate(parent) + { + } + QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const + { + QSize size = QStyledItemDelegate::sizeHint(option, index); + size.setHeight(qMax(size.height(), 32)); + return size; + } +}; + +class PageModel : public QAbstractListModel +{ +public: + PageModel(QObject *parent = 0) : QAbstractListModel(parent) + { + QPixmap empty(pageIconSize, pageIconSize); + empty.fill(Qt::transparent); + m_emptyIcon = QIcon(empty); + } + virtual ~PageModel() {}; + + int rowCount(const QModelIndex &parent = QModelIndex()) const + { + return parent.isValid() ? 0 : m_pages.size(); + } + QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const + { + switch (role) + { + case Qt::DisplayRole: + return m_pages.at(index.row())->displayName(); + case Qt::DecorationRole: + { + QIcon icon = m_pages.at(index.row())->icon(); + if (icon.isNull()) + icon = m_emptyIcon; + return icon; + } + } + return QVariant(); + } + + void setPages(const QList<BasePage *> &pages) + { + beginResetModel(); + m_pages = pages; + endResetModel(); + } + const QList<BasePage *> &pages() const + { + return m_pages; + } + +private: + BasePage * findPageEntryById(QString id) + { + for(auto page: m_pages) + { + if (page->id() == id) + return page; + } + return nullptr; + } + + QList<BasePage *> m_pages; + QIcon m_emptyIcon; +}; + +class PageView : public QListView +{ +public: + PageView(QWidget *parent = 0) : QListView(parent) + { + setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Expanding); + setItemDelegate(new PageViewDelegate(this)); + setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + } + + virtual QSize sizeHint() const + { + int width = sizeHintForColumn(0) + frameWidth() * 2 + 5; + if (verticalScrollBar()->isVisible()) + width += verticalScrollBar()->width(); + return QSize(width, 100); + } + + virtual bool eventFilter(QObject *obj, QEvent *event) + { + if (obj == verticalScrollBar() && + (event->type() == QEvent::Show || event->type() == QEvent::Hide)) + updateGeometry(); + return QListView::eventFilter(obj, event); + } +}; |