From aaaeb585b63f34b51e43a81c7b31f2ef7883b799 Mon Sep 17 00:00:00 2001 From: Konstantin Date: Mon, 9 Sep 2024 14:48:33 -0400 Subject: [PATCH] feature: High-quality dictionary icons in toolbar (#1750) * better procedure of image scaling and size choosing * allow user to set toolbar icon size via qt style sheet --------- Co-authored-by: shenleban tongying Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com> --- src/dict/dictionary.cc | 30 ++++-------------------------- src/dict/dictionary.hh | 3 ++- src/ui/dictionarybar.cc | 25 ++++++++++++++++++++++--- src/ui/dictionarybar.hh | 11 ++++++++++- src/ui/mainwindow.cc | 7 ++----- src/ui/scanpopup.cc | 5 ++--- 6 files changed, 42 insertions(+), 39 deletions(-) diff --git a/src/dict/dictionary.cc b/src/dict/dictionary.cc index db460821..112e71ea 100644 --- a/src/dict/dictionary.cc +++ b/src/dict/dictionary.cc @@ -271,27 +271,13 @@ bool Class::loadIconFromFile( QString const & _filename, bool isFullName ) if ( !img.isNull() ) { // Load successful - //some icon is very large ,will crash the application. - img = img.scaledToWidth( 64 ); + // Apply the color key #if ( QT_VERSION >= QT_VERSION_CHECK( 6, 0, 0 ) ) img.setAlphaChannel( img.createMaskFromColor( QColor( 192, 192, 192 ).rgb(), Qt::MaskOutColor ) ); #endif - // Transform it to be square - int max = img.width() > img.height() ? img.width() : img.height(); - - QImage result( max, max, QImage::Format_ARGB32 ); - result.fill( 0 ); // Black transparent - - QPainter painter( &result ); - painter.setRenderHint( QPainter::RenderHint::Antialiasing ); - painter.drawImage( QPoint( img.width() == max ? 0 : ( max - img.width() ) / 2, - img.height() == max ? 0 : ( max - img.height() ) / 2 ), - img ); - - painter.end(); - + auto result = img.scaled( { iconSize, iconSize }, Qt::KeepAspectRatioByExpanding, Qt::SmoothTransformation ); dictionaryIcon = QIcon( QPixmap::fromImage( result ) ); return !dictionaryIcon.isNull(); @@ -307,18 +293,10 @@ bool Class::loadIconFromText( QString iconUrl, QString const & text ) QImage img( iconUrl ); if ( !img.isNull() ) { - int iconSize = 64; - //some icon is very large ,will crash the application. - img = img.scaledToWidth( iconSize ); - QImage result( iconSize, iconSize, QImage::Format_ARGB32 ); - result.fill( 0 ); // Black transparent - int max = img.width() > img.height() ? img.width() : img.height(); + QImage result = img.scaled( { iconSize, iconSize }, Qt::KeepAspectRatioByExpanding, Qt::SmoothTransformation ); QPainter painter( &result ); - painter.setRenderHint( QPainter::RenderHint::Antialiasing ); - painter.drawImage( QPoint( img.width() == max ? 0 : ( max - img.width() ) / 2, - img.height() == max ? 0 : ( max - img.height() ) / 2 ), - img ); + painter.setRenderHints( QPainter::Antialiasing | QPainter::TextAntialiasing ); painter.setCompositionMode( QPainter::CompositionMode_SourceAtop ); QFont font = painter.font(); diff --git a/src/dict/dictionary.hh b/src/dict/dictionary.hh index cdb1e65b..e6d7b121 100644 --- a/src/dict/dictionary.hh +++ b/src/dict/dictionary.hh @@ -316,11 +316,12 @@ protected: bool synonymSearchEnabled; string dictionaryName; std::optional< bool > metadata_enable_fts = std::nullopt; - // Load user icon if it exist // By default set icon to empty virtual void loadIcon() noexcept; + const int iconSize = 64; + // Load icon from filename directly if isFullName == true // else treat filename as name without extension bool loadIconFromFile( QString const & filename, bool isFullName = false ); diff --git a/src/ui/dictionarybar.cc b/src/ui/dictionarybar.cc index 31057e2c..d3a3cc01 100644 --- a/src/ui/dictionarybar.cc +++ b/src/ui/dictionarybar.cc @@ -4,6 +4,7 @@ #include #include #include +#include using std::vector; @@ -18,6 +19,13 @@ DictionaryBar::DictionaryBar( QWidget * parent, editDictionaryCommand( _editDictionaryCommand ), maxDictionaryRefsInContextMenu( maxDictionaryRefsInContextMenu_ ) { + + auto iconWidth = this->size().width(); + auto iconHeight = this->size().height(); + + normalIconSize = { std::max( iconWidth, iconHeight ), std::max( iconWidth, iconHeight ) }; + + setObjectName( "dictionaryBar" ); maxDictionaryRefsAction = @@ -72,14 +80,24 @@ void DictionaryBar::setDictionaries( vector< sptr< Dictionary::Class > > const & dictActions.append( action ); } - setDictionaryIconSize( 21 ); setUpdatesEnabled( true ); } -void DictionaryBar::setDictionaryIconSize( int extent ) +void DictionaryBar::setDictionaryIconSize( IconSize size ) { - setIconSize( QSize( extent, extent ) ); + switch ( size ) { + case IconSize::Small: { + auto smallSize = QApplication::style()->pixelMetric( QStyle::PM_SmallIconSize ); + setIconSize( { smallSize, smallSize } ); + break; + } + + case IconSize::Normal: { + setIconSize( normalIconSize ); + break; + } + } } void DictionaryBar::contextMenuEvent( QContextMenuEvent * event ) @@ -87,6 +105,7 @@ void DictionaryBar::contextMenuEvent( QContextMenuEvent * event ) showContextMenu( event ); } + void DictionaryBar::showContextMenu( QContextMenuEvent * event, bool extended ) { QMenu menu( this ); diff --git a/src/ui/dictionarybar.hh b/src/ui/dictionarybar.hh index 22071017..e6efb0ce 100644 --- a/src/ui/dictionarybar.hh +++ b/src/ui/dictionarybar.hh @@ -34,7 +34,14 @@ public: { return mutedDictionaries; } - void setDictionaryIconSize( int extent ); + + enum class IconSize { + Small, + Normal, + // TODO: implement something to have an Large option + }; + + void setDictionaryIconSize( IconSize size ); signals: @@ -69,6 +76,8 @@ private: QList< QAction * > dictActions; QAction * maxDictionaryRefsAction; + QSize normalIconSize; // cache icon size set by stylesheet provided by user + protected: void contextMenuEvent( QContextMenuEvent * event ); diff --git a/src/ui/mainwindow.cc b/src/ui/mainwindow.cc index 355e6d25..b1d1a617 100644 --- a/src/ui/mainwindow.cc +++ b/src/ui/mainwindow.cc @@ -1655,11 +1655,8 @@ void MainWindow::updateDictionaryBar() dictionaryBar.setDictionaries( grp->dictionaries ); - int extent = useSmallIconsInToolbarsAction.isChecked() ? - QApplication::style()->pixelMetric( QStyle::PM_SmallIconSize ) : - QApplication::style()->pixelMetric( QStyle::PM_ToolBarIconSize ); - - dictionaryBar.setDictionaryIconSize( extent ); + dictionaryBar.setDictionaryIconSize( useSmallIconsInToolbarsAction.isChecked() ? DictionaryBar::IconSize::Small : + DictionaryBar::IconSize::Normal ); } } diff --git a/src/ui/scanpopup.cc b/src/ui/scanpopup.cc index cb428f3f..ed061586 100644 --- a/src/ui/scanpopup.cc +++ b/src/ui/scanpopup.cc @@ -1110,9 +1110,8 @@ void ScanPopup::on_goForwardButton_clicked() const void ScanPopup::setDictionaryIconSize() { - int extent = cfg.usingSmallIconsInToolbars ? QApplication::style()->pixelMetric( QStyle::PM_SmallIconSize ) : - QApplication::style()->pixelMetric( QStyle::PM_ToolBarIconSize ); - dictionaryBar.setDictionaryIconSize( extent ); + dictionaryBar.setDictionaryIconSize( cfg.usingSmallIconsInToolbars ? DictionaryBar::IconSize::Small : + DictionaryBar::IconSize::Normal ); } void ScanPopup::setGroupByName( QString const & name ) const