QskPushButton::graphicSourceSize added to prevent raster graphics

from being scaled
This commit is contained in:
Uwe Rathmann 2018-11-26 17:52:16 +01:00
parent da89006102
commit 9a1e46e0ba
3 changed files with 105 additions and 20 deletions

View File

@ -25,6 +25,7 @@ class QskPushButton::PrivateData
public: public:
PrivateData( const QString& txt ) PrivateData( const QString& txt )
: text( txt ) : text( txt )
, graphicSourceSize( -1, -1 )
, isGraphicSourceDirty( false ) , isGraphicSourceDirty( false )
{ {
textOptions.setElideMode( Qt::ElideMiddle ); textOptions.setElideMode( Qt::ElideMiddle );
@ -36,6 +37,8 @@ class QskPushButton::PrivateData
QUrl graphicSource; QUrl graphicSource;
QskGraphic graphic; QskGraphic graphic;
QSizeF graphicSourceSize;
bool isGraphicSourceDirty : 1; bool isGraphicSourceDirty : 1;
}; };
@ -141,6 +144,37 @@ QFont QskPushButton::font() const
return effectiveFont( QskPushButton::Text ); return effectiveFont( QskPushButton::Text );
} }
void QskPushButton::resetGraphicSourceSize()
{
setGraphicSourceSize( QSizeF( -1.0, -1.0 ) );
}
void QskPushButton::setGraphicSourceSize( const QSizeF& size )
{
auto newSize = size;
if ( newSize.width() < 0.0 )
newSize.setWidth( -1.0 );
if ( newSize.height() < 0.0 )
newSize.setHeight( -1.0 );
if ( size != m_data->graphicSourceSize )
{
m_data->graphicSourceSize = size;
resetImplicitSize();
polish();
update();
Q_EMIT graphicSourceSizeChanged();
}
}
QSizeF QskPushButton::graphicSourceSize() const
{
return m_data->graphicSourceSize;
}
void QskPushButton::setGraphicSource( const QUrl& url ) void QskPushButton::setGraphicSource( const QUrl& url )
{ {
if ( m_data->graphicSource == url ) if ( m_data->graphicSource == url )
@ -205,10 +239,7 @@ void QskPushButton::updateLayout()
if ( m_data->isGraphicSourceDirty ) if ( m_data->isGraphicSourceDirty )
{ {
if ( !m_data->graphicSource.isEmpty() ) if ( !m_data->graphicSource.isEmpty() )
{
m_data->graphic = loadGraphic( m_data->graphicSource ); m_data->graphic = loadGraphic( m_data->graphicSource );
Q_EMIT graphicChanged();
}
m_data->isGraphicSourceDirty = false; m_data->isGraphicSourceDirty = false;
} }
@ -223,20 +254,40 @@ QSizeF QskPushButton::contentsSizeHint() const
{ {
QSizeF size( 0, 0 ); QSizeF size( 0, 0 );
const QFontMetricsF fm( font() );
if ( !m_data->text.isEmpty() ) if ( !m_data->text.isEmpty() )
{ {
// in elide mode we might want to ignore the text width ??? // in elide mode we might want to ignore the text width ???
const QFontMetricsF fm( font() );
size += fm.size( Qt::TextShowMnemonic, m_data->text ); size += fm.size( Qt::TextShowMnemonic, m_data->text );
} }
if ( !m_data->graphicSource.isEmpty() ) if ( m_data->isGraphicSourceDirty )
{ {
const double dim = 1.5 * size.height(); if ( !m_data->graphicSource.isEmpty() )
size.rheight() += 4 + dim; m_data->graphic = loadGraphic( m_data->graphicSource );
const QSizeF graphicSize = m_data->graphic.defaultSize();
size.rwidth() += graphicSize.width() * dim / graphicSize.height(); m_data->isGraphicSourceDirty = false;
}
if ( !m_data->graphic.isEmpty() )
{
qreal w = m_data->graphicSourceSize.width();
qreal h = m_data->graphicSourceSize.height();
if ( ( w < 0.0 ) && ( h < 0.0 ) )
h = 1.5 * fm.height();
if ( w < 0 )
w = m_data->graphic.widthForHeight( h );
else if ( h < 0 )
h = m_data->graphic.heightForWidth( w );
const qreal padding = 2.0; // Graphic::Padding ???
size.rheight() += 2 * padding + h;
size.rwidth() = qMax( size.width(), w );
} }
const QSizeF minSize( metric( Panel | QskAspect::MinimumWidth ), const QSizeF minSize( metric( Panel | QskAspect::MinimumWidth ),

View File

@ -27,6 +27,10 @@ class QSK_EXPORT QskPushButton : public QskAbstractButton
Q_PROPERTY( QskGraphic graphic READ graphic Q_PROPERTY( QskGraphic graphic READ graphic
WRITE setGraphic NOTIFY graphicChanged FINAL ) WRITE setGraphic NOTIFY graphicChanged FINAL )
Q_PROPERTY( QSizeF graphicSourceSize READ graphicSourceSize
WRITE setGraphicSourceSize RESET resetGraphicSourceSize
NOTIFY graphicSourceSizeChanged FINAL )
Q_PROPERTY( bool flat READ isFlat WRITE setFlat NOTIFY flatChanged FINAL ) Q_PROPERTY( bool flat READ isFlat WRITE setFlat NOTIFY flatChanged FINAL )
Q_PROPERTY( QskCorner corner READ corner WRITE setCorner NOTIFY cornerChanged ) Q_PROPERTY( QskCorner corner READ corner WRITE setCorner NOTIFY cornerChanged )
@ -49,9 +53,12 @@ class QSK_EXPORT QskPushButton : public QskAbstractButton
QskTextOptions textOptions() const; QskTextOptions textOptions() const;
QUrl graphicSource() const; QUrl graphicSource() const;
QSizeF graphicSourceSize() const;
QskGraphic graphic() const; QskGraphic graphic() const;
bool hasGraphic() const; bool hasGraphic() const;
void resetGraphicSourceSize();
void setFlat( bool ); void setFlat( bool );
bool isFlat() const; bool isFlat() const;
@ -65,6 +72,7 @@ class QSK_EXPORT QskPushButton : public QskAbstractButton
void setGraphicSource( const QUrl& url ); void setGraphicSource( const QUrl& url );
void setGraphicSource( const QString& source ); void setGraphicSource( const QString& source );
void setGraphic( const QskGraphic& ); void setGraphic( const QskGraphic& );
void setGraphicSourceSize( const QSizeF & );
Q_SIGNALS: Q_SIGNALS:
void cornerChanged(); void cornerChanged();
@ -74,6 +82,7 @@ class QSK_EXPORT QskPushButton : public QskAbstractButton
void flatChanged(); void flatChanged();
void graphicChanged(); void graphicChanged();
void graphicSourceChanged(); void graphicSourceChanged();
void graphicSourceSizeChanged();
void hovered( bool ); void hovered( bool );

View File

@ -103,9 +103,31 @@ QRectF QskPushButtonSkinlet::graphicRect( const QskPushButton* button ) const
r.setHeight( 0 ); r.setHeight( 0 );
} }
const auto maxSize = button->graphicSourceSize();
if ( maxSize.width() >= 0 || maxSize.height() >= 0 )
{
// limiting the size by graphicSize
const qreal maxW = maxSize.width();
const qreal maxH = maxSize.height();
if ( maxW >= 0.0 && maxW < r.width() )
{
r.setX( r.center().x() - 0.5 * maxW );
r.setWidth( maxW );
}
if ( maxH >= 0.0 && maxH < r.height() )
{
r.setY( r.center().y() - 0.5 * maxH );
r.setHeight( maxH );
}
}
const QSizeF sz = button->graphic().defaultSize(); const QSizeF sz = button->graphic().defaultSize();
if ( r.isEmpty() || sz.isEmpty() )
return r; if ( !( r.isEmpty() || sz.isEmpty() ) )
{
// inner rectangle according to the aspect ratio
const double scaleFactor = const double scaleFactor =
qMin( r.width() / sz.width(), r.height() / sz.height() ); qMin( r.width() / sz.width(), r.height() / sz.height() );
@ -118,7 +140,10 @@ QRectF QskPushButtonSkinlet::graphicRect( const QskPushButton* button ) const
const int x = qFloor( r.center().x() - 0.5 * w ); const int x = qFloor( r.center().x() - 0.5 * w );
const int y = qFloor( r.center().y() - 0.5 * h ); const int y = qFloor( r.center().y() - 0.5 * h );
return QRectF( x, y, w, h ); r = QRectF( x, y, w, h );
}
return r;
} }
QSGNode* QskPushButtonSkinlet::updateTextNode( QSGNode* QskPushButtonSkinlet::updateTextNode(