From 1485616a54cfd3569c6bcda4777f2b8f302c74fc Mon Sep 17 00:00:00 2001 From: Zach Hilman Date: Wed, 17 Oct 2018 21:29:15 -0400 Subject: [PATCH] game_list: Add custom HTMLDelegate to support strikethrough in game list --- src/yuzu/game_list.cpp | 57 ++++++++++++++++++++++++++++++++++++++++++ src/yuzu/game_list.h | 1 + src/yuzu/game_list_p.h | 2 +- 3 files changed, 59 insertions(+), 1 deletion(-) diff --git a/src/yuzu/game_list.cpp b/src/yuzu/game_list.cpp index a5a4aa432b..391cf55bed 100644 --- a/src/yuzu/game_list.cpp +++ b/src/yuzu/game_list.cpp @@ -3,6 +3,7 @@ // Refer to the license.txt file included. #include +#include #include #include #include @@ -12,11 +13,15 @@ #include #include #include +#include +#include +#include #include #include #include "common/common_paths.h" #include "common/common_types.h" #include "common/logging/log.h" +#include "core/file_sys/mode.h" #include "core/file_sys/patch_manager.h" #include "yuzu/compatibility_list.h" #include "yuzu/game_list.h" @@ -25,6 +30,52 @@ #include "yuzu/main.h" #include "yuzu/ui_settings.h" +class HTMLDelegate : public QStyledItemDelegate { +public: + void paint(QPainter* painter, const QStyleOptionViewItem& option, + const QModelIndex& index) const override; + QSize sizeHint(const QStyleOptionViewItem& option, const QModelIndex& index) const override; +}; + +void HTMLDelegate::paint(QPainter* painter, const QStyleOptionViewItem& option, + const QModelIndex& index) const { + QStyleOptionViewItemV4 optionV4 = option; + initStyleOption(&optionV4, index); + + QStyle* style = optionV4.widget ? optionV4.widget->style() : QApplication::style(); + + QTextDocument doc; + doc.setHtml(optionV4.text); + + /// Painting item without text + optionV4.text = QString(); + style->drawControl(QStyle::CE_ItemViewItem, &optionV4, painter); + + QAbstractTextDocumentLayout::PaintContext ctx; + + // Highlighting text if item is selected + if (optionV4.state & QStyle::State_Selected) + ctx.palette.setColor(QPalette::Text, + optionV4.palette.color(QPalette::Active, QPalette::HighlightedText)); + + QRect textRect = style->subElementRect(QStyle::SE_ItemViewItemText, &optionV4); + painter->save(); + painter->translate(textRect.topLeft()); + painter->setClipRect(textRect.translated(-textRect.topLeft())); + doc.documentLayout()->draw(painter, ctx); + painter->restore(); +} + +QSize HTMLDelegate::sizeHint(const QStyleOptionViewItem& option, const QModelIndex& index) const { + QStyleOptionViewItemV4 optionV4 = option; + initStyleOption(&optionV4, index); + + QTextDocument doc; + doc.setHtml(optionV4.text); + doc.setTextWidth(optionV4.rect.width()); + return QSize(doc.idealWidth(), doc.size().height()); +} + GameListSearchField::KeyReleaseEater::KeyReleaseEater(GameList* gamelist) : gamelist{gamelist} {} // EventFilter in order to process systemkeys while editing the searchfield @@ -214,6 +265,7 @@ GameList::GameList(FileSys::VirtualFilesystem vfs, GMainWindow* parent) tree_view->setEditTriggers(QHeaderView::NoEditTriggers); tree_view->setUniformRowHeights(true); tree_view->setContextMenuPolicy(Qt::CustomContextMenu); + tree_view->setItemDelegate(new HTMLDelegate); item_model->insertColumns(0, COLUMN_COUNT); item_model->setHeaderData(COLUMN_NAME, Qt::Horizontal, tr("Name")); @@ -326,6 +378,8 @@ void GameList::PopupContextMenu(const QPoint& menu_location) { QAction* dump_romfs = context_menu.addAction(tr("Dump RomFS")); QAction* copy_tid = context_menu.addAction(tr("Copy Title ID to Clipboard")); QAction* navigate_to_gamedb_entry = context_menu.addAction(tr("Navigate to GameDB entry")); + context_menu.addSeparator(); + QAction* properties = context_menu.addAction(tr("Properties")); open_save_location->setEnabled(program_id != 0); auto it = FindMatchingCompatibilityEntry(compatibility_list, program_id); @@ -339,6 +393,9 @@ void GameList::PopupContextMenu(const QPoint& menu_location) { connect(copy_tid, &QAction::triggered, [&]() { emit CopyTIDRequested(program_id); }); connect(navigate_to_gamedb_entry, &QAction::triggered, [&]() { emit NavigateToGamedbEntryRequested(program_id, compatibility_list); }); + connect(properties, &QAction::triggered, [&]() { + emit OpenGamePropertiesDialogRequested(vfs->OpenFile(path, FileSys::Mode::Read)); + }); context_menu.exec(tree_view->viewport()->mapToGlobal(menu_location)); } diff --git a/src/yuzu/game_list.h b/src/yuzu/game_list.h index 05e115e19f..d347f6acd5 100644 --- a/src/yuzu/game_list.h +++ b/src/yuzu/game_list.h @@ -68,6 +68,7 @@ signals: void OpenFolderRequested(u64 program_id, GameListOpenTarget target); void DumpRomFSRequested(u64 program_id, const std::string& game_path); void CopyTIDRequested(u64 program_id); + void OpenGamePropertiesDialogRequested(FileSys::VirtualFile file); void NavigateToGamedbEntryRequested(u64 program_id, const CompatibilityList& compatibility_list); diff --git a/src/yuzu/game_list_p.h b/src/yuzu/game_list_p.h index 3db0e90da9..a40ccba43f 100644 --- a/src/yuzu/game_list_p.h +++ b/src/yuzu/game_list_p.h @@ -95,7 +95,7 @@ public: if (row2.isEmpty()) return row1; - return row1 + "\n " + row2; + return row1 + "
" + row2; } return GameListItem::data(role);