BookShelf/mainwindow.cpp

271 lines
8.6 KiB
C++

#include "mainwindow.h"
#include "corehost.h"
#include <QDebug>
#include <QLineEdit>
#include <QPainter>
#include <QRandomGenerator>
#include <QSplitter>
#include <QTime>
#include <QVBoxLayout>
#define GROUP_COVER0_PATH Qt::UserRole + 1
#define GROUP_COVER1_PATH Qt::UserRole + 2
#define GROUP_COVER2_PATH Qt::UserRole + 3
#define GROUP_TITLE Qt::DisplayRole
#define GROUP_ITEMSCOUNT Qt::UserRole + 4
#define ITEM_ICON_PATH Qt::UserRole + 1
#define ITEM_TITLE Qt::DisplayRole
CoreHost host;
MainWindow::MainWindow(QWidget* parent)
: QMainWindow(parent), groups_view(new QListView(this)),
groups_list(new QStandardItemModel(this)), items_view(new QListView(this)),
items_list(new QStandardItemModel(this)), details_panel(new QSplitter(Qt::Vertical, this)),
cover_display(new QLabel(this)), details_view(new QTableView(this)), details_model(new QStandardItemModel(this)),
labels_view(new QTableView(this)), labels_model(new QStandardItemModel(this))
{
setMinimumSize(800, 600);
groups_view->setModel(groups_list);
items_view->setModel(items_list);
// --------------------------
auto splitter = new QSplitter(this);
setCentralWidget(splitter);
splitter->addWidget(groups_view);
splitter->addWidget(items_view);
groups_list->setHorizontalHeaderLabels(QStringList() << "数量"
<< "名称");
groups_view->setItemDelegate(new GroupDisplayDelegate);
groups_view->setMovement(QListView::Snap);
init_groups_list(groups_list);
items_view->setItemDelegate(new ItemDisplayDelegate());
items_view->setViewMode(QListView::IconMode);
items_view->setResizeMode(QListView::Adjust);
connect(groups_view, &QListView::clicked, this, &MainWindow::init_items_present);
details_view->setModel(details_model);
labels_view->setModel(labels_model);
cover_display->setMinimumSize(200, 300);
splitter->addWidget(details_panel);
details_panel->addWidget(cover_display);
auto tabs = new QTabWidget(this);
details_panel->addWidget(tabs);
tabs->addTab(details_view, "书籍详情");
tabs->addTab(labels_view, "标签编辑");
}
MainWindow::~MainWindow()
{
}
void
MainWindow::init_groups_list(QStandardItemModel* model)
{
model->removeRows(0, model->rowCount());
QRandomGenerator gen;
for (int idx = 0; idx < 200; ++idx) {
auto row = new QStandardItem("无名集合0");
row->setData(gen.generate() % 100, GROUP_ITEMSCOUNT);
row->setData(":/imgs/default/cover_item.jpg", GROUP_COVER0_PATH);
model->appendRow(row);
}
}
void
MainWindow::init_items_present(const QModelIndex& index)
{
items_list->clear();
QRandomGenerator gen(QTime::currentTime().second());
for (int idx = 0; idx < 200; ++idx) {
auto item = new QStandardItem("随机名称");
item->setData((gen.generate() % 2 == 1 ? ":/imgs/default/cover.jpg" : ":/imgs/default/cover_item.jpg"), ITEM_ICON_PATH);
items_list->appendRow(item);
}
}
GroupDisplayDelegate::GroupDisplayDelegate()
{
}
GroupDisplayDelegate::~GroupDisplayDelegate()
{
}
QWidget*
GroupDisplayDelegate::createEditor(QWidget* parent, const QStyleOptionViewItem& option, const QModelIndex& index) const
{
auto font = option.font;
font.setPointSize(26);
auto ins = new QLineEdit(parent);
ins->setFont(font);
return ins;
}
void
GroupDisplayDelegate::setEditorData(QWidget* editor, const QModelIndex& index) const
{
static_cast<QLineEdit*>(editor)->setText(index.data().toString());
}
void
GroupDisplayDelegate::setModelData(QWidget* editor, QAbstractItemModel* model, const QModelIndex& index) const
{
model->setData(index, static_cast<QLineEdit*>(editor)->text());
}
auto calc_textrect1 = [](const QRect& whole_rect, double font_height) -> QRectF {
return QRectF(whole_rect.left() + 145, whole_rect.top() + 20, whole_rect.width() - 165, font_height);
};
void
GroupDisplayDelegate::updateEditorGeometry(QWidget* editor, const QStyleOptionViewItem& option, const QModelIndex& index) const
{
QStyleOptionViewItem new_ = option;
new_.font.setPointSize(26);
new_.fontMetrics = QFontMetrics(new_.font);
editor->setGeometry(calc_textrect1(option.rect, new_.fontMetrics.height()).toRect());
}
void
GroupDisplayDelegate::paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const
{
drawBackground(painter, option, index);
QIcon *icon0 = nullptr, *icon1 = nullptr, *icon2 = nullptr;
auto cover0 = index.data(GROUP_COVER0_PATH);
if (cover0.isNull())
icon0 = host.queryCoverIcon(":/imgs/default/cover.jpg");
else
icon0 = host.queryCoverIcon(cover0.toString());
auto cover1 = index.data(GROUP_COVER1_PATH);
if (cover1.isNull())
icon1 = host.queryCoverIcon(":/imgs/default/cover.jpg");
else
icon1 = host.queryCoverIcon(cover1.toString());
auto cover2 = index.data(GROUP_COVER2_PATH);
if (cover2.isNull())
icon2 = host.queryCoverIcon(":/imgs/default/cover.jpg");
else
icon2 = host.queryCoverIcon(cover2.toString());
auto valid_rect = option.rect - QMargins(15, 15, 15, 15);
auto pixmap1 = icon1->pixmap(100, 150);
QRect rect1(valid_rect.left() + 60, valid_rect.top() + 20, 54, 80);
painter->drawPixmap(rect1, pixmap1);
auto pixmap2 = icon2->pixmap(100, 150);
QRect rect2(valid_rect.left() + 34, valid_rect.top() + 10, 66, 100);
painter->drawPixmap(rect2, pixmap2);
auto pixmap0 = icon0->pixmap(100, 150);
QRect rect0(valid_rect.left(), valid_rect.top(), 80, 120);
painter->drawPixmap(rect0, pixmap0);
QStyleOptionViewItem new_copy = option;
new_copy.font.setPointSize(26);
new_copy.fontMetrics = QFontMetrics(new_copy.font);
drawDisplay(painter, new_copy, calc_textrect1(option.rect, new_copy.fontMetrics.height()).toRect(), index.data().toString());
new_copy.font.setPointSize(18);
new_copy.fontMetrics = QFontMetrics(new_copy.font);
drawDisplay(painter, new_copy, new_copy.rect - QMargins(160, 60, 0, 0), QString("总藏书:%1").arg(index.data(GROUP_ITEMSCOUNT).toUInt()));
}
QSize
GroupDisplayDelegate::sizeHint(const QStyleOptionViewItem& option, const QModelIndex& index) const
{
return QSize(400, 145);
}
ItemDisplayDelegate::ItemDisplayDelegate()
{
}
ItemDisplayDelegate::~ItemDisplayDelegate()
{
}
auto
calc_textrect2
= [](const QRect& boundrect, float height) -> QRect {
return QRect(boundrect.left() + 5, boundrect.bottom() - height - 5, boundrect.width() - 10, height);
};
void
ItemDisplayDelegate::paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const
{
painter->save();
painter->setRenderHint(QPainter::Antialiasing);
drawBackground(painter, option, index);
QPen pen(QColor(0, 0, 200, 150), 3, Qt::SolidLine);
painter->setPen(pen);
QBrush brush(QColor(20, 20, 150, 100));
painter->setBrush(brush);
if (option.state & QStyle::State_Selected)
painter->drawRoundedRect(option.rect - QMargins(2, 2, 2, 2), 5, 5);
QIcon* icon = nullptr;
auto cover = index.data(ITEM_ICON_PATH);
if (!cover.isValid())
icon = host.queryCoverIcon(":/imgs/default/cover.jpg");
else
icon = host.queryCoverIcon(cover.toString());
auto valid_rect = option.rect - QMargins(15, 15, 15, 15);
drawDecoration(painter, option, valid_rect, icon->pixmap(120, 180));
if (option.features & QStyleOptionViewItem::HasCheckIndicator)
drawCheck(painter, option, QRect(option.rect.left() + 5, option.rect.top() + 5, 20, 20), option.checkState);
painter->fillRect(calc_textrect2(option.rect, option.fontMetrics.height() * 1.3), QGradient::Preset::NightFade);
drawDisplay(painter, option, calc_textrect2(option.rect, option.fontMetrics.height() * 1.3), index.data().toString());
painter->restore();
}
QSize
ItemDisplayDelegate::sizeHint(const QStyleOptionViewItem& option, const QModelIndex& index) const
{
return QSize(135, 195);
}
QWidget*
ItemDisplayDelegate::createEditor(QWidget* parent, const QStyleOptionViewItem& option, const QModelIndex& index) const
{
return new QLineEdit(parent);
}
void
ItemDisplayDelegate::setEditorData(QWidget* editor, const QModelIndex& index) const
{
static_cast<QLineEdit*>(editor)->setText(index.data().toString());
}
void
ItemDisplayDelegate::setModelData(QWidget* editor, QAbstractItemModel* model, const QModelIndex& index) const
{
model->setData(index, static_cast<QLineEdit*>(editor)->text());
}
void
ItemDisplayDelegate::updateEditorGeometry(QWidget* editor, const QStyleOptionViewItem& option, const QModelIndex& index) const
{
editor->setGeometry(calc_textrect2(option.rect, option.fontMetrics.height() * 1.3));
}