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 <shenlebantongying@gmail.com>
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
This commit is contained in:
Konstantin 2024-09-09 14:48:33 -04:00 committed by GitHub
parent 34e9ad5654
commit aaaeb585b6
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 42 additions and 39 deletions

View file

@ -271,27 +271,13 @@ bool Class::loadIconFromFile( QString const & _filename, bool isFullName )
if ( !img.isNull() ) { if ( !img.isNull() ) {
// Load successful // Load successful
//some icon is very large ,will crash the application.
img = img.scaledToWidth( 64 );
// Apply the color key // Apply the color key
#if ( QT_VERSION >= QT_VERSION_CHECK( 6, 0, 0 ) ) #if ( QT_VERSION >= QT_VERSION_CHECK( 6, 0, 0 ) )
img.setAlphaChannel( img.createMaskFromColor( QColor( 192, 192, 192 ).rgb(), Qt::MaskOutColor ) ); img.setAlphaChannel( img.createMaskFromColor( QColor( 192, 192, 192 ).rgb(), Qt::MaskOutColor ) );
#endif #endif
// Transform it to be square auto result = img.scaled( { iconSize, iconSize }, Qt::KeepAspectRatioByExpanding, Qt::SmoothTransformation );
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();
dictionaryIcon = QIcon( QPixmap::fromImage( result ) ); dictionaryIcon = QIcon( QPixmap::fromImage( result ) );
return !dictionaryIcon.isNull(); return !dictionaryIcon.isNull();
@ -307,18 +293,10 @@ bool Class::loadIconFromText( QString iconUrl, QString const & text )
QImage img( iconUrl ); QImage img( iconUrl );
if ( !img.isNull() ) { if ( !img.isNull() ) {
int iconSize = 64; QImage result = img.scaled( { iconSize, iconSize }, Qt::KeepAspectRatioByExpanding, Qt::SmoothTransformation );
//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();
QPainter painter( &result ); QPainter painter( &result );
painter.setRenderHint( QPainter::RenderHint::Antialiasing ); painter.setRenderHints( QPainter::Antialiasing | QPainter::TextAntialiasing );
painter.drawImage( QPoint( img.width() == max ? 0 : ( max - img.width() ) / 2,
img.height() == max ? 0 : ( max - img.height() ) / 2 ),
img );
painter.setCompositionMode( QPainter::CompositionMode_SourceAtop ); painter.setCompositionMode( QPainter::CompositionMode_SourceAtop );
QFont font = painter.font(); QFont font = painter.font();

View file

@ -316,11 +316,12 @@ protected:
bool synonymSearchEnabled; bool synonymSearchEnabled;
string dictionaryName; string dictionaryName;
std::optional< bool > metadata_enable_fts = std::nullopt; std::optional< bool > metadata_enable_fts = std::nullopt;
// Load user icon if it exist // Load user icon if it exist
// By default set icon to empty // By default set icon to empty
virtual void loadIcon() noexcept; virtual void loadIcon() noexcept;
const int iconSize = 64;
// Load icon from filename directly if isFullName == true // Load icon from filename directly if isFullName == true
// else treat filename as name without extension // else treat filename as name without extension
bool loadIconFromFile( QString const & filename, bool isFullName = false ); bool loadIconFromFile( QString const & filename, bool isFullName = false );

View file

@ -4,6 +4,7 @@
#include <QMenu> #include <QMenu>
#include <QContextMenuEvent> #include <QContextMenuEvent>
#include <QProcess> #include <QProcess>
#include <QStyle>
using std::vector; using std::vector;
@ -18,6 +19,13 @@ DictionaryBar::DictionaryBar( QWidget * parent,
editDictionaryCommand( _editDictionaryCommand ), editDictionaryCommand( _editDictionaryCommand ),
maxDictionaryRefsInContextMenu( maxDictionaryRefsInContextMenu_ ) maxDictionaryRefsInContextMenu( maxDictionaryRefsInContextMenu_ )
{ {
auto iconWidth = this->size().width();
auto iconHeight = this->size().height();
normalIconSize = { std::max( iconWidth, iconHeight ), std::max( iconWidth, iconHeight ) };
setObjectName( "dictionaryBar" ); setObjectName( "dictionaryBar" );
maxDictionaryRefsAction = maxDictionaryRefsAction =
@ -72,14 +80,24 @@ void DictionaryBar::setDictionaries( vector< sptr< Dictionary::Class > > const &
dictActions.append( action ); dictActions.append( action );
} }
setDictionaryIconSize( 21 );
setUpdatesEnabled( true ); 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 ) void DictionaryBar::contextMenuEvent( QContextMenuEvent * event )
@ -87,6 +105,7 @@ void DictionaryBar::contextMenuEvent( QContextMenuEvent * event )
showContextMenu( event ); showContextMenu( event );
} }
void DictionaryBar::showContextMenu( QContextMenuEvent * event, bool extended ) void DictionaryBar::showContextMenu( QContextMenuEvent * event, bool extended )
{ {
QMenu menu( this ); QMenu menu( this );

View file

@ -34,7 +34,14 @@ public:
{ {
return mutedDictionaries; return mutedDictionaries;
} }
void setDictionaryIconSize( int extent );
enum class IconSize {
Small,
Normal,
// TODO: implement something to have an Large option
};
void setDictionaryIconSize( IconSize size );
signals: signals:
@ -69,6 +76,8 @@ private:
QList< QAction * > dictActions; QList< QAction * > dictActions;
QAction * maxDictionaryRefsAction; QAction * maxDictionaryRefsAction;
QSize normalIconSize; // cache icon size set by stylesheet provided by user
protected: protected:
void contextMenuEvent( QContextMenuEvent * event ); void contextMenuEvent( QContextMenuEvent * event );

View file

@ -1655,11 +1655,8 @@ void MainWindow::updateDictionaryBar()
dictionaryBar.setDictionaries( grp->dictionaries ); dictionaryBar.setDictionaries( grp->dictionaries );
int extent = useSmallIconsInToolbarsAction.isChecked() ? dictionaryBar.setDictionaryIconSize( useSmallIconsInToolbarsAction.isChecked() ? DictionaryBar::IconSize::Small :
QApplication::style()->pixelMetric( QStyle::PM_SmallIconSize ) : DictionaryBar::IconSize::Normal );
QApplication::style()->pixelMetric( QStyle::PM_ToolBarIconSize );
dictionaryBar.setDictionaryIconSize( extent );
} }
} }

View file

@ -1110,9 +1110,8 @@ void ScanPopup::on_goForwardButton_clicked() const
void ScanPopup::setDictionaryIconSize() void ScanPopup::setDictionaryIconSize()
{ {
int extent = cfg.usingSmallIconsInToolbars ? QApplication::style()->pixelMetric( QStyle::PM_SmallIconSize ) : dictionaryBar.setDictionaryIconSize( cfg.usingSmallIconsInToolbars ? DictionaryBar::IconSize::Small :
QApplication::style()->pixelMetric( QStyle::PM_ToolBarIconSize ); DictionaryBar::IconSize::Normal );
dictionaryBar.setDictionaryIconSize( extent );
} }
void ScanPopup::setGroupByName( QString const & name ) const void ScanPopup::setGroupByName( QString const & name ) const