From c5f4c4df88db39f28f1eb2b000720566f75cf929 Mon Sep 17 00:00:00 2001 From: ShaopengLin Date: Mon, 21 Oct 2024 23:32:03 -0400 Subject: [PATCH 1/9] Introduce src/css_constants.h Effort to reduce css value dependency --- kiwix-desktop.pro | 1 + resources/css/_contentManager.css | 3 ++- resources/css/style.css | 7 +++-- src/contentmanagerdelegate.cpp | 6 ++--- src/css_constants.h | 43 +++++++++++++++++++++++++++++++ src/tabbar.cpp | 7 +++-- src/webview.cpp | 5 +++- 7 files changed, 59 insertions(+), 13 deletions(-) create mode 100644 src/css_constants.h diff --git a/kiwix-desktop.pro b/kiwix-desktop.pro index 2fe14a1b5..46f2368f9 100644 --- a/kiwix-desktop.pro +++ b/kiwix-desktop.pro @@ -140,6 +140,7 @@ HEADERS += \ src/menuproxystyle.h \ src/zimview.h \ src/portutils.h \ + src/css_constants.h \ FORMS += \ src/choiceitem.ui \ diff --git a/resources/css/_contentManager.css b/resources/css/_contentManager.css index 4218c1f1a..289ce8c7c 100644 --- a/resources/css/_contentManager.css +++ b/resources/css/_contentManager.css @@ -24,9 +24,10 @@ QTreeView::item:has-children { border-bottom: 1px solid #cccccc; } + QTreeView { font-family: 'Selawik'; - padding: 4px; + padding: 4px; /* XXX: duplicated in css_constants.h */ border: none; selection-color: black; qproperty-iconSize: 30px; diff --git a/resources/css/style.css b/resources/css/style.css index ae6593e16..19733de27 100644 --- a/resources/css/style.css +++ b/resources/css/style.css @@ -103,7 +103,7 @@ TopWidget QToolButton::menu-indicator { } TopWidget QToolButton#backButton { - margin-left: 6px; /* see also: void WebViewBackMenu::showEvent(QShowEvent *) { geo.setX(geo.x() + 6); } */ + margin-left: 6px; /* XXX: duplicated in css_constants.h */ } TopWidget QToolButton#fullScreenButton { @@ -178,11 +178,10 @@ QTabWidget::pane { border-top: 1px solid #ccc; } -/* paintEvent of src/tabbar.cpp references the value of border and padding */ QTabBar::tab { - border: 1px solid #ccc; + border: 1px solid #ccc; /* XXX: duplicated in css_constants.h */ border-radius: 0; - padding: 4px; + padding: 4px; /* XXX: duplicated in css_constants.h */ padding-top: 6px; } diff --git a/src/contentmanagerdelegate.cpp b/src/contentmanagerdelegate.cpp index ce6aee6eb..60a55e4de 100644 --- a/src/contentmanagerdelegate.cpp +++ b/src/contentmanagerdelegate.cpp @@ -8,6 +8,7 @@ #include "rownode.h" #include "descriptionnode.h" #include "portutils.h" +#include "css_constants.h" ContentManagerDelegate::ContentManagerDelegate(QObject *parent) : QStyledItemDelegate(parent), baseButton(new QPushButton) @@ -284,9 +285,8 @@ QSize ContentManagerDelegate::sizeHint(const QStyleOptionViewItem &option, const const auto treeView = KiwixApp::instance()->getContentManager()->getView()->getView(); const int width = treeView->header()->length() - 2*treeView->indentation(); - // XXX: see QTreeView::padding in resources/css/_contentManager.css - const int verticalPadding = 4; - const int horizontalPadding = 4; + const int verticalPadding = CSS::ContentManagerCSS::QTreeView::padding; + const int horizontalPadding = CSS::ContentManagerCSS::QTreeView::padding; QRect descRect(0, 0, width - 2 * horizontalPadding, 0); /* Based on the rectangle and text, find the best fitting size. */ diff --git a/src/css_constants.h b/src/css_constants.h new file mode 100644 index 000000000..987c77ccd --- /dev/null +++ b/src/css_constants.h @@ -0,0 +1,43 @@ +#ifndef CSS_CONSTANTS_H +#define CSS_CONSTANTS_H + +/** + * @brief The need for this file is due to the lack of support to retrieve CSS + * values of Qt Widgets. Such deficiency means every code that depend on a CSS + * values need to be updated on change to that value. This file makes it so that + * a dependent CSS value only need to be updated here instead of its every use. + * + * - The CSS values in this file should create appropriate namespaces similar to + * a CSS hierarchy. + * - The classes are defined in resources/style.css unless specified. + * - Naming convention should follow Javascript's style naming. + * - Comments should be added to the duplicated css properties in css files. + */ +namespace CSS +{ + +namespace QTabBar { +namespace tab { + const int padding = 4; + const int border = 1; +} +} + +namespace TopWidget { +namespace QToolButton { +namespace backButton { + const int marginLeft = 6; +} +} +} + +/* In _contentManager.css */ +namespace ContentManagerCSS { +namespace QTreeView { + const int padding = 4; +} +} + +} + +#endif // CSS_CONSTANTS_H diff --git a/src/tabbar.cpp b/src/tabbar.cpp index 71b5c538c..3c7632e09 100644 --- a/src/tabbar.cpp +++ b/src/tabbar.cpp @@ -3,6 +3,7 @@ class QMenu; #include "tabbar.h" #include "kiwixapp.h" +#include "css_constants.h" #include #include #include @@ -439,12 +440,10 @@ void TabBar::paintEvent(QPaintEvent *e) bool textRightToLeft = tab_title.isRightToLeft(); bool appRightToLeft = QWidget::isRightToLeft(); - // See QTabBar::tab::padding value in resources/css/style.css - const int padding = 4; + const int padding = CSS::QTabBar::tab::padding; QRect tabTextRect = style()->subElementRect(QStyle::SE_TabBarTabText, &tabopt, this); #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) - // See QTabBar::tab::border value in resources/css/style.css - const int border = 1; + const int border = CSS::QTabBar::tab::border; // Add Padding to left, right. Padding is 4px. Add 5 to account for // Extra pixel from border. diff --git a/src/webview.cpp b/src/webview.cpp index 378179949..de42da42c 100644 --- a/src/webview.cpp +++ b/src/webview.cpp @@ -7,6 +7,7 @@ class QMenu; #include #include "kiwixapp.h" #include "webpage.h" +#include "css_constants.h" #include #include #include @@ -35,7 +36,9 @@ void WebViewBackMenu::showEvent(QShowEvent *) */ QRect geo = geometry(); - geo.moveLeft(geo.left() + 6); // see also: style.css: QToolButton#backButton { margin-left: 6px; } + + const int marginLeft = CSS::TopWidget::QToolButton::backButton::marginLeft; + geo.moveLeft(geo.left() + marginLeft); geo.moveTop(geo.top() + 2); setGeometry(geo); } From de76432f7dc36eae4c915f815f8df695537aa025 Mon Sep 17 00:00:00 2001 From: ShaopengLin Date: Tue, 22 Oct 2024 15:28:56 -0400 Subject: [PATCH 2/9] Enter KiwixApp::getSearchBar() Refactor to reduce getter chaining length --- src/kiwixapp.cpp | 2 +- src/kiwixapp.h | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/kiwixapp.cpp b/src/kiwixapp.cpp index ce0712908..f9be1da4d 100644 --- a/src/kiwixapp.cpp +++ b/src/kiwixapp.cpp @@ -133,7 +133,7 @@ KiwixApp::~KiwixApp() void KiwixApp::newTab() { getTabWidget()->createNewTab(true, false); - auto& searchBarLineEdit = mp_mainWindow->getTopWidget()->getSearchBar().getLineEdit(); + auto& searchBarLineEdit = getSearchBar().getLineEdit(); searchBarLineEdit.setFocus(Qt::MouseFocusReason); searchBarLineEdit.clear(); searchBarLineEdit.clearSuggestions(); diff --git a/src/kiwixapp.h b/src/kiwixapp.h index 5454150f9..fa422fc23 100644 --- a/src/kiwixapp.h +++ b/src/kiwixapp.h @@ -83,6 +83,7 @@ class KiwixApp : public QtSingleApplication MainWindow* getMainWindow() { return mp_mainWindow; } ContentManager* getContentManager() { return mp_manager; } TabBar* getTabWidget() { return getMainWindow()->getTabBar(); } + SearchBar& getSearchBar() { return getMainWindow()->getTopWidget()->getSearchBar(); } QAction* getAction(Actions action); QString getLibraryDirectory() { return m_libraryDirectory; }; kiwix::Server* getLocalServer() { return &m_server; } From d80ba1f012d37ff3c30bd86fa42471e427d5c11e Mon Sep 17 00:00:00 2001 From: ShaopengLin Date: Tue, 22 Oct 2024 15:34:22 -0400 Subject: [PATCH 3/9] Consistent Left&Right Margin for SearchBar --- resources/css/style.css | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/resources/css/style.css b/resources/css/style.css index 19733de27..90c79d009 100644 --- a/resources/css/style.css +++ b/resources/css/style.css @@ -32,7 +32,7 @@ QToolButton { SearchBar { background-color: white; - margin: 2px 5px; + margin: 2px; border: 1px solid #ccc; border-radius: 3px; @@ -43,7 +43,7 @@ SearchBar > QLabel#searchIcon { padding: 0; border: none; background-color: none; - margin: 0px 4px 0px 9px; + margin: 0px 6px; max-height: 38px; max-width: 38px; @@ -68,11 +68,6 @@ SearchBar > QToolButton { max-width: 38px; } -SearchBar > BookmarkButton { - margin-right: 3px; - margin-left: 3px; -} - SearchBar > QToolButton:pressed, SearchBar > QToolButton:hover { border: 1px solid #3366CC; From 4132cb0ddecfb306a2c52f6db0744fa2c26e81d5 Mon Sep 17 00:00:00 2001 From: ShaopengLin Date: Tue, 22 Oct 2024 16:17:39 -0400 Subject: [PATCH 4/9] Align Search Suggestion with Line Edit --- resources/css/style.css | 4 ++-- src/css_constants.h | 5 +++++ src/searchbar.cpp | 40 +++++++++++++++++++++++++++++++++++++++- src/searchbar.h | 1 + 4 files changed, 47 insertions(+), 3 deletions(-) diff --git a/resources/css/style.css b/resources/css/style.css index 90c79d009..ee91655ef 100644 --- a/resources/css/style.css +++ b/resources/css/style.css @@ -32,8 +32,8 @@ QToolButton { SearchBar { background-color: white; - margin: 2px; - border: 1px solid #ccc; + margin: 2px; /* XXX: duplicated in css_constants.h */ + border: 1px solid #ccc; /* XXX: duplicated in css_constants.h */ border-radius: 3px; max-height: 40px; diff --git a/src/css_constants.h b/src/css_constants.h index 987c77ccd..28fa74126 100644 --- a/src/css_constants.h +++ b/src/css_constants.h @@ -23,6 +23,11 @@ namespace tab { } } +namespace SearchBar{ + const int margin = 2; + const int border = 1; +} + namespace TopWidget { namespace QToolButton { namespace backButton { diff --git a/src/searchbar.cpp b/src/searchbar.cpp index 3a2e63c4f..b8291da74 100644 --- a/src/searchbar.cpp +++ b/src/searchbar.cpp @@ -6,6 +6,7 @@ #include "kiwixapp.h" #include "suggestionlistworker.h" +#include "css_constants.h" BookmarkButton::BookmarkButton(QWidget *parent) : QToolButton(parent) @@ -285,7 +286,7 @@ void SearchBarLineEdit::onInitialSuggestions(int) if (m_returnPressed) { openCompletion(getDefaulSuggestionIndex()); } else { - m_completer.complete(); + m_completer.complete(getCompleterRect()); /* Make row 0 appear but do not highlight it */ const auto completerFirstIdx = m_suggestionView->model()->index(0, 0); @@ -339,6 +340,43 @@ QModelIndex SearchBarLineEdit::getDefaulSuggestionIndex() const return QModelIndex(); } +/* Line edit does not span the entire searchBar. Completer is displayed + based on line edit, and thus shifting and resizing is needed. +*/ +QRect SearchBarLineEdit::getCompleterRect() const +{ + auto& searchBar = KiwixApp::instance()->getSearchBar(); + const auto& searchGeo = searchBar.geometry(); + const auto& searchLineEditGeo = searchBar.getLineEdit().geometry(); + + const int margin = CSS::SearchBar::margin; + const int border = CSS::SearchBar::border; + const int spaceAround = margin + border; + + /* Border and margin are not accounted in height and width. */ + const int top = searchGeo.height() - 2 * spaceAround; + const int width = searchGeo.width() - 2 * spaceAround; + + /* Shift completer to one of the two laterals of search bar, where which + one it shifted to dependes on whether the line edit is flipped. + */ + int left = -searchLineEditGeo.left(); + + /* When not flipped, left() is relative to within the search bar border, + thus, we shift by spaceAround to match the side of search bar. + + When flipped, the completer starts at the right end of the search bar + We shift it by width to make the completer start at left lateral of + search bar. Since in a flipped state, left() also considered the opposite + side's border, which means we need to shift by a border width in + addition to spaceAround. + */ + left += isRightToLeft() ? -width + spaceAround + border : spaceAround; + + /* Can't set height to 0. Will cause rectangle to be ignored. */ + return QRect(QPoint(left, top), QSize(width, 1)); +} + SearchBar::SearchBar(QWidget *parent) : QToolBar(parent), m_searchBarLineEdit(this), diff --git a/src/searchbar.h b/src/searchbar.h index b75983008..516f5eb05 100644 --- a/src/searchbar.h +++ b/src/searchbar.h @@ -68,6 +68,7 @@ private slots: void fetchSuggestions(NewSuggestionHandlerFuncPtr callback); QModelIndex getDefaulSuggestionIndex() const; + QRect getCompleterRect() const; }; From da1faa6b24ec3ac029cb3c208fee081ab1008bc9 Mon Sep 17 00:00:00 2001 From: ShaopengLin Date: Tue, 22 Oct 2024 17:05:48 -0400 Subject: [PATCH 5/9] Proper Size for Suggestion View Header&Row evenly spread with fixed height. --- resources/css/popup.css | 17 +++++++++++++++++ src/css_constants.h | 11 +++++++++++ src/searchbar.cpp | 20 ++++++++++++++++++++ src/suggestionlistmodel.cpp | 14 ++++++++++++++ 4 files changed, 62 insertions(+) diff --git a/resources/css/popup.css b/resources/css/popup.css index f1d5a9771..7cf31161d 100644 --- a/resources/css/popup.css +++ b/resources/css/popup.css @@ -3,6 +3,23 @@ QWidget { border: none; } +QHeaderView { + background-color: white; +} + +QHeaderView::section { + border: none; + color: #3b3b3b; + background-color: white; + + margin-top: 5px; /* XXX: duplicated in css_constants.h */ + padding: 5px 10px; /* XXX: duplicated in css_constants.h */ + + font-size: 16px; + line-height: 24px; /* XXX: duplicated in css_constants.h */ + font-weight: 400; +} + QScrollBar { width: 5px; border: none; diff --git a/src/css_constants.h b/src/css_constants.h index 28fa74126..aabb6d06f 100644 --- a/src/css_constants.h +++ b/src/css_constants.h @@ -43,6 +43,17 @@ namespace QTreeView { } } +/* In popup.css */ +namespace PopupCSS { +namespace QHeaderView { +namespace section { + const int marginTop = 5; + const int lineHeight = 24; + const int paddingVertical = 5; +} +} +} + } #endif // CSS_CONSTANTS_H diff --git a/src/searchbar.cpp b/src/searchbar.cpp index b8291da74..44e6efeb5 100644 --- a/src/searchbar.cpp +++ b/src/searchbar.cpp @@ -8,6 +8,8 @@ #include "suggestionlistworker.h" #include "css_constants.h" +namespace HeaderSectionCSS = CSS::PopupCSS::QHeaderView::section; + BookmarkButton::BookmarkButton(QWidget *parent) : QToolButton(parent) { @@ -81,6 +83,24 @@ SearchBarLineEdit::SearchBarLineEdit(QWidget *parent) : m_suggestionView->setRootIsDecorated(false); m_suggestionView->setStyleSheet(KiwixApp::instance()->parseStyleFromFile(":/css/popup.css")); + const int contentHeight = HeaderSectionCSS::lineHeight; + m_suggestionView->setIconSize(QSize(contentHeight, contentHeight)); + + /* The suggestionView sizing unfortunately is not aware of headers. We + have to do this manually. We also sized header the same as items. + */ + connect(&m_suggestionModel, &QAbstractListModel::modelReset, [=](){ + /* +1 for header. */ + const int maxItem = m_completer.maxVisibleItems(); + const int count = std::min(m_suggestionModel.rowCount(), maxItem) + 1; + + const int itemHeight = m_suggestionView->sizeHintForRow(0); + + /* Extra space styling above header and below last suggestion item. */ + const int extraMargin = 2 * HeaderSectionCSS::marginTop; + m_suggestionView->setFixedHeight(itemHeight * count + extraMargin); + }); + connect(m_suggestionView->verticalScrollBar(), &QScrollBar::valueChanged, this, &SearchBarLineEdit::onScroll); diff --git a/src/suggestionlistmodel.cpp b/src/suggestionlistmodel.cpp index 6fe99dad1..716b0f748 100644 --- a/src/suggestionlistmodel.cpp +++ b/src/suggestionlistmodel.cpp @@ -1,8 +1,11 @@ #include "suggestionlistmodel.h" #include "kiwixapp.h" +#include "css_constants.h" #include +namespace HeaderSectionCSS = CSS::PopupCSS::QHeaderView::section; + QString getZimIdFromUrl(QUrl url); SuggestionListModel::SuggestionListModel(QObject *parent) @@ -35,9 +38,20 @@ QVariant SuggestionListModel::data(const QModelIndex &index, int role) const case Qt::UserRole: return m_suggestions.at(row).url; case Qt::DecorationRole: + { const auto library = KiwixApp::instance()->getLibrary(); const auto zimId = getZimIdFromUrl(m_suggestions.at(row).url); return library->getBookIcon(zimId); + } + case Qt::SizeHintRole: + { + /* Padding in css can't change height, we have to achieve padding + by increasing height. + */ + const int padding = HeaderSectionCSS::paddingVertical; + const int lineHeight = HeaderSectionCSS::lineHeight; + return QSize(0, lineHeight + 2 * padding); + } } return QVariant(); } From 42bd6d61361bae16550b9a408fdd5c93ded1074b Mon Sep 17 00:00:00 2001 From: ShaopengLin Date: Tue, 22 Oct 2024 17:23:47 -0400 Subject: [PATCH 6/9] Proper Hover Style to Suggestion Items --- resources/css/popup.css | 13 ++++++++++++- src/searchbar.cpp | 3 +++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/resources/css/popup.css b/resources/css/popup.css index 7cf31161d..cb8114dcc 100644 --- a/resources/css/popup.css +++ b/resources/css/popup.css @@ -1,6 +1,17 @@ -QWidget { +QTreeView { background-color: white; border: none; + outline: none; +} + +QTreeView::item { + border: 1px solid transparent; +} + +QTreeView::item:selected { + border: 1px solid #3366CC; + background-color: #D9E9FF; + color: black; } QHeaderView { diff --git a/src/searchbar.cpp b/src/searchbar.cpp index 44e6efeb5..d512dd733 100644 --- a/src/searchbar.cpp +++ b/src/searchbar.cpp @@ -3,6 +3,7 @@ #include #include #include +#include #include "kiwixapp.h" #include "suggestionlistworker.h" @@ -79,6 +80,8 @@ SearchBarLineEdit::SearchBarLineEdit(QWidget *parent) : /* QCompleter's uses default list views, which do not have headers. */ m_completer.setPopup(m_suggestionView); + /* The Delegate was overwritten by setPopup(), which is not style-aware */ + m_suggestionView->setItemDelegate(new QStyledItemDelegate(this)); m_suggestionView->header()->setStretchLastSection(true); m_suggestionView->setRootIsDecorated(false); m_suggestionView->setStyleSheet(KiwixApp::instance()->parseStyleFromFile(":/css/popup.css")); From 32803df471a9c484618aa9b63e1e20fa5f8989bd Mon Sep 17 00:00:00 2001 From: ShaopengLin Date: Tue, 22 Oct 2024 17:29:52 -0400 Subject: [PATCH 7/9] Fix Qt6 Compilation Failure. Since Qt6, forward declaration doesn't work for QList template. --- src/suggestionlistworker.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/suggestionlistworker.h b/src/suggestionlistworker.h index 4f51b0234..18a80425d 100644 --- a/src/suggestionlistworker.h +++ b/src/suggestionlistworker.h @@ -2,8 +2,7 @@ #define SUGGESTIONLISTWORKER_H #include - -struct SuggestionData; +#include "suggestionlistmodel.h" class SuggestionListWorker : public QThread { From 134be31c67c7b102a339df439549e3e7ed7c41e2 Mon Sep 17 00:00:00 2001 From: ShaopengLin Date: Tue, 22 Oct 2024 17:50:24 -0400 Subject: [PATCH 8/9] Custom Paint Suggestion Icon&Text Spacing Qt does not provide css style or API for modifying icon and text spacing in QTreeView. This is a long issue in buttons as well, as Qt draws icon and texts instead of having them as widgets that can be applied styles. --- kiwix-desktop.pro | 2 + src/css_constants.h | 1 + src/searchbar.cpp | 3 +- src/suggestionlistdelegate.cpp | 72 ++++++++++++++++++++++++++++++++++ src/suggestionlistdelegate.h | 17 ++++++++ 5 files changed, 94 insertions(+), 1 deletion(-) create mode 100644 src/suggestionlistdelegate.cpp create mode 100644 src/suggestionlistdelegate.h diff --git a/kiwix-desktop.pro b/kiwix-desktop.pro index 46f2368f9..9fb0c123e 100644 --- a/kiwix-desktop.pro +++ b/kiwix-desktop.pro @@ -62,6 +62,7 @@ SOURCES += \ src/rownode.cpp \ src/suggestionlistworker.cpp \ src/suggestionlistmodel.cpp \ + src/suggestionlistdelegate.cpp \ src/thumbnaildownloader.cpp \ src/translation.cpp \ src/main.cpp \ @@ -111,6 +112,7 @@ HEADERS += \ src/rownode.h \ src/suggestionlistworker.h \ src/suggestionlistmodel.h \ + src/suggestionlistdelegate.h \ src/thumbnaildownloader.h \ src/translation.h \ src/mainwindow.h \ diff --git a/src/css_constants.h b/src/css_constants.h index aabb6d06f..dba10b0b2 100644 --- a/src/css_constants.h +++ b/src/css_constants.h @@ -50,6 +50,7 @@ namespace section { const int marginTop = 5; const int lineHeight = 24; const int paddingVertical = 5; + const int paddingLeft = 10; } } } diff --git a/src/searchbar.cpp b/src/searchbar.cpp index d512dd733..e1725c652 100644 --- a/src/searchbar.cpp +++ b/src/searchbar.cpp @@ -8,6 +8,7 @@ #include "kiwixapp.h" #include "suggestionlistworker.h" #include "css_constants.h" +#include "suggestionlistdelegate.h" namespace HeaderSectionCSS = CSS::PopupCSS::QHeaderView::section; @@ -81,7 +82,7 @@ SearchBarLineEdit::SearchBarLineEdit(QWidget *parent) : m_completer.setPopup(m_suggestionView); /* The Delegate was overwritten by setPopup(), which is not style-aware */ - m_suggestionView->setItemDelegate(new QStyledItemDelegate(this)); + m_suggestionView->setItemDelegate(new SuggestionListDelegate(this)); m_suggestionView->header()->setStretchLastSection(true); m_suggestionView->setRootIsDecorated(false); m_suggestionView->setStyleSheet(KiwixApp::instance()->parseStyleFromFile(":/css/popup.css")); diff --git a/src/suggestionlistdelegate.cpp b/src/suggestionlistdelegate.cpp new file mode 100644 index 000000000..c77a86399 --- /dev/null +++ b/src/suggestionlistdelegate.cpp @@ -0,0 +1,72 @@ +#include "suggestionlistdelegate.h" +#include "kiwixapp.h" +#include "css_constants.h" + +#include + +namespace HeaderSectionCSS = CSS::PopupCSS::QHeaderView::section; + +void SuggestionListDelegate::paint(QPainter *painter, + const QStyleOptionViewItem &option, + const QModelIndex &index) const +{ + /* Paint without text and icon */ + QStyleOptionViewItem opt(option); + QStyledItemDelegate::paint(painter, opt, QModelIndex()); + + paintIcon(painter, opt, index); + paintText(painter, opt, index); +} + +void SuggestionListDelegate::paintIcon(QPainter *p, + const QStyleOptionViewItem &opt, + const QModelIndex &index) const +{ + QRect pixmapRect = opt.rect; + const int lineHeight = HeaderSectionCSS::lineHeight; + const int paddingLeft = HeaderSectionCSS::paddingLeft; + + const QSize mapSize = QSize(lineHeight, lineHeight); + auto pixmap = index.data(Qt::DecorationRole).value().pixmap(mapSize); + + /* Align icon to Header text */ + if (KiwixApp::isRightToLeft()) + { + const int rightEnd = pixmapRect.width() - mapSize.width(); + pixmapRect.setX(pixmapRect.x() + rightEnd - paddingLeft); + } + else + pixmapRect.setX(pixmapRect.x() + paddingLeft); + + /* Align middle */ + pixmapRect.setY(pixmapRect.y() + (pixmapRect.height() - mapSize.height()) / 2); + pixmapRect.setSize(mapSize); + p->drawPixmap(pixmapRect, pixmap); +} + +void SuggestionListDelegate::paintText(QPainter *p, + const QStyleOptionViewItem &opt, + const QModelIndex &index) const +{ + auto& searchBar = KiwixApp::instance()->getSearchBar(); + const auto& lineEditGeo = searchBar.getLineEdit().geometry(); + + /* Remove border from left() since left is is with respect to border. Detail + reason on how this calculation comes about can be seen in + SearchBarLineEdit::getCompleterRect(); + */ + const int left = lineEditGeo.left() - CSS::SearchBar::border; + QRect textRect = opt.rect; + if (KiwixApp::isRightToLeft()) + { + const auto& searchGeo = searchBar.geometry(); + const int right = searchGeo.width() - left - lineEditGeo.width(); + textRect.setWidth(textRect.width() - right); + } + else + textRect.setX(textRect.x() + left); + + const int flag = {Qt::AlignVCenter | Qt::AlignLeading}; + const QString text = index.data(Qt::DisplayRole).toString(); + p->drawText(textRect, flag, text); +} diff --git a/src/suggestionlistdelegate.h b/src/suggestionlistdelegate.h new file mode 100644 index 000000000..426964eb2 --- /dev/null +++ b/src/suggestionlistdelegate.h @@ -0,0 +1,17 @@ +#ifndef SUGGESTIONLISTDELEGATE_H +#define SUGGESTIONLISTDELEGATE_H + +#include + +class SuggestionListDelegate : public QStyledItemDelegate +{ +public: + SuggestionListDelegate(QObject *parent = nullptr) : QStyledItemDelegate(parent) {}; + void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const override; + +private: + void paintIcon(QPainter *p, const QStyleOptionViewItem &opt, const QModelIndex &index) const; + void paintText(QPainter *p, const QStyleOptionViewItem &opt, const QModelIndex &index) const; +}; + +#endif // SUGGESTIONLISTDELEGATE_H From c3f4a1e041941f3ecdf7601c5fc7be5efb83258b Mon Sep 17 00:00:00 2001 From: ShaopengLin Date: Tue, 22 Oct 2024 17:55:24 -0400 Subject: [PATCH 9/9] Custom Elide for Suggestion List Text Qt painting also doesn't have elide support. --- src/suggestionlistdelegate.cpp | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/src/suggestionlistdelegate.cpp b/src/suggestionlistdelegate.cpp index c77a86399..954f7782e 100644 --- a/src/suggestionlistdelegate.cpp +++ b/src/suggestionlistdelegate.cpp @@ -68,5 +68,23 @@ void SuggestionListDelegate::paintText(QPainter *p, const int flag = {Qt::AlignVCenter | Qt::AlignLeading}; const QString text = index.data(Qt::DisplayRole).toString(); - p->drawText(textRect, flag, text); + + /* Custom text elide. */ + const QFontMetrics metrics = opt.fontMetrics; + const int elideMarkerLength = metrics.tightBoundingRect("(...)").width(); + const int textLength = textRect.width() - elideMarkerLength; + QString elidedText = metrics.elidedText(text, Qt::ElideRight, textLength); + if (elidedText != text) + { + /* Remove built-in elide marker */ + elidedText.chop(1); + + /* drawText's Align direction determines text direction */ + const bool textDirFlipped = KiwixApp::isRightToLeft() != text.isRightToLeft(); + elidedText = textDirFlipped ? "(...)" + elidedText.trimmed() + : elidedText.trimmed() + "(...)"; + p->drawText(textRect, flag, elidedText); + } + else + p->drawText(textRect, flag, text); }