QskIcon/QskLabelData introduced
This commit is contained in:
parent
10af58137f
commit
f9f5de8eb0
|
@ -0,0 +1,102 @@
|
|||
/******************************************************************************
|
||||
* QSkinny - Copyright (C) 2016 Uwe Rathmann
|
||||
* This file may be used under the terms of the QSkinny License, Version 1.0
|
||||
*****************************************************************************/
|
||||
|
||||
#include "QskLabelData.h"
|
||||
#include "QskGraphicProvider.h"
|
||||
|
||||
#include <qvariant.h>
|
||||
#include <qhashfunctions.h>
|
||||
|
||||
static void qskRegisterLabelData()
|
||||
{
|
||||
qRegisterMetaType< QskLabelData >();
|
||||
|
||||
#if QT_VERSION < QT_VERSION_CHECK( 6, 0, 0 )
|
||||
QMetaType::registerEqualsComparator< QskLabelData >();
|
||||
#endif
|
||||
}
|
||||
|
||||
Q_CONSTRUCTOR_FUNCTION( qskRegisterLabelData )
|
||||
|
||||
QskLabelData::QskLabelData( const QString& text )
|
||||
: m_text( text )
|
||||
{
|
||||
}
|
||||
|
||||
QskLabelData::QskLabelData( const QskIcon& icon )
|
||||
: m_icon( icon )
|
||||
{
|
||||
}
|
||||
|
||||
QskLabelData::QskLabelData( const QString& text, const QskIcon& icon )
|
||||
: m_text( text )
|
||||
, m_icon( icon )
|
||||
{
|
||||
}
|
||||
|
||||
bool QskLabelData::operator==( const QskLabelData& other ) const noexcept
|
||||
{
|
||||
return ( m_text == other.m_text )
|
||||
&& ( m_icon == other.m_icon );
|
||||
}
|
||||
|
||||
void QskLabelData::setText( const QString& text )
|
||||
{
|
||||
m_text = text;
|
||||
}
|
||||
|
||||
void QskLabelData::setIconSource( const QUrl& source )
|
||||
{
|
||||
m_icon.setSource( source );
|
||||
}
|
||||
|
||||
void QskLabelData::setIcon( const QskIcon& icon )
|
||||
{
|
||||
m_icon = icon;
|
||||
}
|
||||
|
||||
QskHashValue QskLabelData::hash( QskHashValue seed ) const
|
||||
{
|
||||
const auto hash = qHash( m_text, seed );
|
||||
return m_icon.hash( hash );
|
||||
}
|
||||
|
||||
#ifndef QT_NO_DEBUG_STREAM
|
||||
|
||||
#include <qdebug.h>
|
||||
|
||||
QDebug operator<<( QDebug debug, const QskLabelData& labelData )
|
||||
{
|
||||
QDebugStateSaver saver( debug );
|
||||
debug.nospace();
|
||||
|
||||
const auto icon = labelData.icon();
|
||||
const auto text = labelData.text();
|
||||
|
||||
debug << "Label" << "( ";
|
||||
if ( !text.isEmpty() )
|
||||
{
|
||||
debug << text;
|
||||
if ( !icon.isNull() )
|
||||
debug << ", ";
|
||||
}
|
||||
|
||||
if ( !icon.source().isEmpty() )
|
||||
{
|
||||
debug << icon.source();
|
||||
}
|
||||
else if ( !icon.maybeGraphic().isNull() )
|
||||
{
|
||||
debug << "I:" << icon.maybeGraphic().hash( 0 );
|
||||
}
|
||||
|
||||
debug << " )";
|
||||
|
||||
return debug;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#include "moc_QskLabelData.cpp"
|
|
@ -0,0 +1,79 @@
|
|||
/******************************************************************************
|
||||
* QSkinny - Copyright (C) 2016 Uwe Rathmann
|
||||
* This file may be used under the terms of the QSkinny License, Version 1.0
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef QSK_LABEL_DATA_H
|
||||
#define QSK_LABEL_DATA_H
|
||||
|
||||
#include "QskGlobal.h"
|
||||
#include "QskIcon.h"
|
||||
|
||||
#include <qstring.h>
|
||||
#include <qmetatype.h>
|
||||
#include <qdebug.h>
|
||||
|
||||
class QSK_EXPORT QskLabelData
|
||||
{
|
||||
Q_GADGET
|
||||
|
||||
Q_PROPERTY( QString text READ text WRITE setText )
|
||||
Q_PROPERTY( QUrl iconSource READ iconSource WRITE setIconSource )
|
||||
|
||||
public:
|
||||
QskLabelData() = default;
|
||||
|
||||
QskLabelData( const QString& );
|
||||
QskLabelData( const QskIcon& );
|
||||
QskLabelData( const QString&, const QskIcon& );
|
||||
|
||||
bool operator==( const QskLabelData& ) const noexcept;
|
||||
bool operator!=( const QskLabelData& ) const noexcept;
|
||||
|
||||
void setText( const QString& );
|
||||
QString text() const noexcept;
|
||||
|
||||
void setIconSource( const QUrl& );
|
||||
QUrl iconSource() const noexcept;
|
||||
|
||||
void setIcon( const QskIcon& );
|
||||
QskIcon icon() const noexcept;
|
||||
|
||||
QskHashValue hash( QskHashValue ) const;
|
||||
|
||||
private:
|
||||
QString m_text;
|
||||
QskIcon m_icon;
|
||||
};
|
||||
|
||||
Q_DECLARE_METATYPE( QskLabelData )
|
||||
|
||||
inline QString QskLabelData::text() const noexcept
|
||||
{
|
||||
return m_text;
|
||||
}
|
||||
|
||||
inline QskIcon QskLabelData::icon() const noexcept
|
||||
{
|
||||
return m_icon;
|
||||
}
|
||||
|
||||
inline QUrl QskLabelData::iconSource() const noexcept
|
||||
{
|
||||
return m_icon.source();
|
||||
}
|
||||
|
||||
inline bool QskLabelData::operator!=( const QskLabelData& other ) const noexcept
|
||||
{
|
||||
return ( !( *this == other ) );
|
||||
}
|
||||
|
||||
#ifndef QT_NO_DEBUG_STREAM
|
||||
|
||||
class QDebug;
|
||||
|
||||
QSK_EXPORT QDebug operator<<( QDebug, const QskLabelData& );
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -5,8 +5,7 @@
|
|||
|
||||
#include "QskSegmentedBar.h"
|
||||
|
||||
#include "QskGraphic.h"
|
||||
#include "QskGraphicProvider.h"
|
||||
#include "QskLabelData.h"
|
||||
#include "QskTextOptions.h"
|
||||
#include "QskEvent.h"
|
||||
#include "QskSkinlet.h"
|
||||
|
@ -27,33 +26,6 @@ QSK_SYSTEM_STATE( QskSegmentedBar, Selected, QskAspect::FirstSystemState << 1 )
|
|||
QSK_SYSTEM_STATE( QskSegmentedBar, Minimum, QskAspect::FirstSystemState << 2 )
|
||||
QSK_SYSTEM_STATE( QskSegmentedBar, Maximum, QskAspect::FirstSystemState << 3 )
|
||||
|
||||
namespace
|
||||
{
|
||||
class Option
|
||||
{
|
||||
public:
|
||||
Option() = default;
|
||||
|
||||
Option( const QUrl& graphicSource, const QString& text )
|
||||
: graphicSource( graphicSource )
|
||||
, text( text )
|
||||
{
|
||||
#if 1
|
||||
// lazy loading TODO ...
|
||||
if ( !graphicSource.isEmpty() )
|
||||
graphic = Qsk::loadGraphic( graphicSource );
|
||||
#endif
|
||||
}
|
||||
|
||||
QUrl graphicSource;
|
||||
QString text;
|
||||
|
||||
QskGraphic graphic;
|
||||
|
||||
bool isEnabled = true;
|
||||
};
|
||||
}
|
||||
|
||||
class QskSegmentedBar::PrivateData
|
||||
{
|
||||
public:
|
||||
|
@ -62,20 +34,8 @@ class QskSegmentedBar::PrivateData
|
|||
{
|
||||
}
|
||||
|
||||
void addOption( QskSegmentedBar* bar, const Option& option )
|
||||
{
|
||||
this->options += option;
|
||||
|
||||
bar->resetImplicitSize();
|
||||
bar->update();
|
||||
|
||||
Q_EMIT bar->countChanged();
|
||||
|
||||
if ( this->options.count() == 1 )
|
||||
bar->setSelectedIndex( 0 );
|
||||
}
|
||||
|
||||
QVector< Option > options;
|
||||
QVector< QskLabelData > options;
|
||||
QVector< bool > enabled;
|
||||
|
||||
int selectedIndex = -1;
|
||||
int currentIndex = -1;
|
||||
|
@ -139,24 +99,39 @@ QskTextOptions QskSegmentedBar::textOptions() const
|
|||
|
||||
int QskSegmentedBar::addOption( const QUrl& graphicSource, const QString& text )
|
||||
{
|
||||
m_data->addOption( this, Option( graphicSource, text ) );
|
||||
return addOption( QskLabelData( text, graphicSource ) );
|
||||
}
|
||||
|
||||
int QskSegmentedBar::addOption( const QskLabelData& option )
|
||||
{
|
||||
m_data->options += option;
|
||||
m_data->enabled += true;
|
||||
|
||||
resetImplicitSize();
|
||||
update();
|
||||
|
||||
Q_EMIT optionsChanged();
|
||||
|
||||
if ( count() == 1 )
|
||||
setSelectedIndex( 0 );
|
||||
|
||||
return count() - 1;
|
||||
}
|
||||
|
||||
QVariantList QskSegmentedBar::optionAt( int index ) const
|
||||
QskLabelData QskSegmentedBar::optionAt( int index ) const
|
||||
{
|
||||
const auto& options = m_data->options;
|
||||
return m_data->options.value( index );
|
||||
}
|
||||
|
||||
if( index < 0 || index >= options.count() )
|
||||
return QVariantList();
|
||||
void QskSegmentedBar::setOptions( const QVector< QskLabelData >& options )
|
||||
{
|
||||
m_data->options = options;
|
||||
m_data->enabled.fill( true, options.count() );
|
||||
|
||||
const auto& option = options[ index ];
|
||||
resetImplicitSize();
|
||||
update();
|
||||
|
||||
QVariantList list;
|
||||
list += QVariant::fromValue( option.graphic );
|
||||
list += QVariant::fromValue( option.text );
|
||||
|
||||
return list;
|
||||
Q_EMIT optionsChanged();
|
||||
}
|
||||
|
||||
QskAspect::Variation QskSegmentedBar::effectiveVariation() const
|
||||
|
@ -168,21 +143,26 @@ void QskSegmentedBar::mousePressEvent( QMouseEvent* event )
|
|||
{
|
||||
const int index = indexAtPosition( qskMousePosition( event ) );
|
||||
|
||||
if( index < 0 || index >= count() || !m_data->options[ index ].isEnabled )
|
||||
return;
|
||||
|
||||
m_data->isPressed = true;
|
||||
|
||||
if( ( focusPolicy() & Qt::ClickFocus ) == Qt::ClickFocus )
|
||||
if( isSegmentEnabled( index ) )
|
||||
{
|
||||
if( !QGuiApplication::styleHints()->setFocusOnTouchRelease() )
|
||||
m_data->isPressed = true;
|
||||
|
||||
if( ( focusPolicy() & Qt::ClickFocus ) == Qt::ClickFocus )
|
||||
{
|
||||
if( index != m_data->currentIndex )
|
||||
setCurrentIndex( index );
|
||||
if( !QGuiApplication::styleHints()->setFocusOnTouchRelease() )
|
||||
{
|
||||
if( index != m_data->currentIndex )
|
||||
setCurrentIndex( index );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void QskSegmentedBar::mouseUngrabEvent()
|
||||
{
|
||||
m_data->isPressed = false;
|
||||
}
|
||||
|
||||
void QskSegmentedBar::mouseReleaseEvent( QMouseEvent* event )
|
||||
{
|
||||
int index = -1;
|
||||
|
@ -193,15 +173,15 @@ void QskSegmentedBar::mouseReleaseEvent( QMouseEvent* event )
|
|||
index = indexAtPosition( qskMousePosition( event ) );
|
||||
}
|
||||
|
||||
if( index < 0 || !m_data->options[ index ].isEnabled )
|
||||
return;
|
||||
|
||||
if( ( focusPolicy() & Qt::ClickFocus ) == Qt::ClickFocus )
|
||||
if( isSegmentEnabled( index ) )
|
||||
{
|
||||
if( QGuiApplication::styleHints()->setFocusOnTouchRelease() )
|
||||
if( ( focusPolicy() & Qt::ClickFocus ) == Qt::ClickFocus )
|
||||
{
|
||||
if( index != m_data->currentIndex )
|
||||
setCurrentIndex( index );
|
||||
if( QGuiApplication::styleHints()->setFocusOnTouchRelease() )
|
||||
{
|
||||
if( index != m_data->currentIndex )
|
||||
setCurrentIndex( index );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -310,7 +290,7 @@ void QskSegmentedBar::clear()
|
|||
return;
|
||||
|
||||
m_data->options.clear();
|
||||
Q_EMIT countChanged();
|
||||
Q_EMIT optionsChanged();
|
||||
|
||||
if( m_data->selectedIndex >= 0 )
|
||||
{
|
||||
|
@ -329,13 +309,8 @@ void QskSegmentedBar::clear()
|
|||
|
||||
void QskSegmentedBar::setCurrentIndex( int index )
|
||||
{
|
||||
const auto& options = m_data->options;
|
||||
|
||||
if( ( index < 0 ) || ( index >= options.count() )
|
||||
|| !options[ index ].isEnabled )
|
||||
{
|
||||
if ( !isSegmentEnabled( index ) )
|
||||
index = -1;
|
||||
}
|
||||
|
||||
if( index != m_data->currentIndex )
|
||||
{
|
||||
|
@ -351,14 +326,8 @@ int QskSegmentedBar::currentIndex() const
|
|||
|
||||
void QskSegmentedBar::setSelectedIndex( int index )
|
||||
{
|
||||
if( index < 0 || index >= m_data->options.count() )
|
||||
{
|
||||
if ( !isSegmentEnabled( index ) )
|
||||
index = -1;
|
||||
}
|
||||
else if ( !m_data->options[ index ].isEnabled )
|
||||
{
|
||||
index = -1; // ???
|
||||
}
|
||||
|
||||
if( index != m_data->selectedIndex )
|
||||
{
|
||||
|
@ -400,7 +369,7 @@ int QskSegmentedBar::nextIndex( int index, bool forwards ) const
|
|||
|
||||
while( ++index < count )
|
||||
{
|
||||
if( options[ index ].isEnabled )
|
||||
if( isSegmentEnabled( index ) )
|
||||
return index;
|
||||
}
|
||||
}
|
||||
|
@ -411,7 +380,7 @@ int QskSegmentedBar::nextIndex( int index, bool forwards ) const
|
|||
|
||||
while( --index >= 0 )
|
||||
{
|
||||
if( options[ index ].isEnabled )
|
||||
if( isSegmentEnabled( index ) )
|
||||
return index;
|
||||
}
|
||||
}
|
||||
|
@ -419,6 +388,11 @@ int QskSegmentedBar::nextIndex( int index, bool forwards ) const
|
|||
return -1;
|
||||
}
|
||||
|
||||
QVector< QskLabelData > QskSegmentedBar::options() const
|
||||
{
|
||||
return m_data->options;
|
||||
}
|
||||
|
||||
int QskSegmentedBar::count() const
|
||||
{
|
||||
return m_data->options.count();
|
||||
|
@ -426,15 +400,15 @@ int QskSegmentedBar::count() const
|
|||
|
||||
void QskSegmentedBar::setSegmentEnabled( int index, bool enabled )
|
||||
{
|
||||
auto& options = m_data->options;
|
||||
auto& bitVector = m_data->enabled;
|
||||
|
||||
if( ( index < 0 ) || ( index >= options.count() )
|
||||
|| ( options[ index ].isEnabled == enabled ) )
|
||||
if( ( index < 0 ) || ( index >= bitVector.count() )
|
||||
|| ( bitVector[ index ] == enabled ) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
options[ index ].isEnabled = enabled;
|
||||
bitVector[ index ] = enabled;
|
||||
|
||||
if( !enabled )
|
||||
{
|
||||
|
@ -447,12 +421,7 @@ void QskSegmentedBar::setSegmentEnabled( int index, bool enabled )
|
|||
|
||||
bool QskSegmentedBar::isSegmentEnabled( int index ) const
|
||||
{
|
||||
const auto& options = m_data->options;
|
||||
|
||||
if( index < 0 || index >= options.count() )
|
||||
return false;
|
||||
|
||||
return options[ index ].isEnabled;
|
||||
return m_data->enabled.value( index, false );
|
||||
}
|
||||
|
||||
int QskSegmentedBar::indexAtPosition( const QPointF& pos ) const
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
|
||||
class QskTextOptions;
|
||||
class QskGraphic;
|
||||
class QskLabelData;
|
||||
|
||||
class QSK_EXPORT QskSegmentedBar : public QskControl
|
||||
{
|
||||
|
@ -21,13 +22,16 @@ class QSK_EXPORT QskSegmentedBar : public QskControl
|
|||
Q_PROPERTY( Qt::Orientation orientation READ orientation
|
||||
WRITE setOrientation NOTIFY orientationChanged )
|
||||
|
||||
Q_PROPERTY( QVector< QskLabelData > options READ options
|
||||
WRITE setOptions NOTIFY optionsChanged )
|
||||
|
||||
Q_PROPERTY( int selectedIndex READ selectedIndex
|
||||
WRITE setSelectedIndex NOTIFY selectedIndexChanged USER true )
|
||||
|
||||
Q_PROPERTY( int currentIndex READ currentIndex
|
||||
WRITE setCurrentIndex NOTIFY currentIndexChanged )
|
||||
|
||||
Q_PROPERTY( int count READ count NOTIFY countChanged )
|
||||
Q_PROPERTY( int count READ count )
|
||||
|
||||
using Inherited = QskControl;
|
||||
|
||||
|
@ -47,6 +51,12 @@ class QSK_EXPORT QskSegmentedBar : public QskControl
|
|||
QskTextOptions textOptions() const;
|
||||
|
||||
int addOption( const QUrl&, const QString& );
|
||||
int addOption( const QskLabelData& );
|
||||
|
||||
void setOptions( const QVector< QskLabelData >& );
|
||||
|
||||
QVector< QskLabelData > options() const;
|
||||
QskLabelData optionAt( int ) const;
|
||||
|
||||
void clear();
|
||||
|
||||
|
@ -55,8 +65,6 @@ class QSK_EXPORT QskSegmentedBar : public QskControl
|
|||
|
||||
int count() const;
|
||||
|
||||
QVariantList optionAt( int ) const;
|
||||
|
||||
void setSegmentEnabled( int, bool );
|
||||
bool isSegmentEnabled( int ) const;
|
||||
|
||||
|
@ -72,12 +80,13 @@ class QSK_EXPORT QskSegmentedBar : public QskControl
|
|||
Q_SIGNALS:
|
||||
void selectedIndexChanged( int );
|
||||
void currentIndexChanged( int );
|
||||
void countChanged();
|
||||
void optionsChanged();
|
||||
void orientationChanged();
|
||||
|
||||
protected:
|
||||
void mouseReleaseEvent( QMouseEvent* ) override;
|
||||
void mousePressEvent( QMouseEvent* ) override;
|
||||
void mouseReleaseEvent( QMouseEvent* ) override;
|
||||
void mouseUngrabEvent() override;
|
||||
|
||||
void keyPressEvent( QKeyEvent* ) override;
|
||||
void keyReleaseEvent( QKeyEvent* ) override;
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
#include "QskSegmentedBarSkinlet.h"
|
||||
#include "QskSegmentedBar.h"
|
||||
|
||||
#include "QskLabelData.h"
|
||||
#include "QskGraphic.h"
|
||||
#include "QskColorFilter.h"
|
||||
#include "QskFunctions.h"
|
||||
|
@ -18,42 +19,24 @@
|
|||
|
||||
namespace
|
||||
{
|
||||
#if 1 // unify with the implementation from QskMenu
|
||||
template< class T >
|
||||
static inline QVariant qskSampleAt( const QskSegmentedBar* bar, int index )
|
||||
{
|
||||
const auto list = bar->optionAt( index );
|
||||
for ( const auto& value : list )
|
||||
{
|
||||
if ( value.canConvert< T >() )
|
||||
return value;
|
||||
}
|
||||
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
template< class T >
|
||||
static inline T qskValueAt( const QskSegmentedBar* bar, int index )
|
||||
{
|
||||
const auto sample = qskSampleAt< T >( bar, index );
|
||||
return sample.template value< T >();
|
||||
}
|
||||
#endif
|
||||
|
||||
QskGraphic iconAt( const QskSegmentedBar* bar, const int index )
|
||||
{
|
||||
using Q = QskSegmentedBar;
|
||||
|
||||
if ( bar->selectedIndex() == index )
|
||||
{
|
||||
// f.e Material 3 replaces the icon of the selected element by a checkmark
|
||||
/*
|
||||
Material 3 replaces the icon of the selected element by a checkmark,
|
||||
when icon and text are set. So this code is actually not correct
|
||||
as it also replaces the icon when there is no text
|
||||
*/
|
||||
|
||||
const auto icon = bar->symbolHint( Q::Icon | Q::Selected );
|
||||
if ( !icon.isNull() )
|
||||
return icon;
|
||||
}
|
||||
|
||||
return qskValueAt< QskGraphic >( bar, index );
|
||||
return bar->optionAt( index ).icon().graphic();
|
||||
}
|
||||
|
||||
class LayoutEngine : public QskSubcontrolLayoutEngine
|
||||
|
@ -66,8 +49,9 @@ namespace
|
|||
|
||||
setSpacing( bar->spacingHint( Q::Panel ) );
|
||||
|
||||
setGraphicTextElements( bar,
|
||||
Q::Text, qskValueAt< QString >( bar, index ),
|
||||
const auto option = bar->optionAt( index );
|
||||
|
||||
setGraphicTextElements( bar, Q::Text, option.text(),
|
||||
Q::Icon, iconAt( bar, index ).defaultSize() );
|
||||
|
||||
if( bar->orientation() == Qt::Horizontal )
|
||||
|
@ -228,33 +212,31 @@ QSizeF QskSegmentedBarSkinlet::segmentSizeHint(
|
|||
{
|
||||
using Q = QskSegmentedBar;
|
||||
|
||||
QSizeF sizeMax;
|
||||
const QSizeF sizeSymbol =
|
||||
bar->symbolHint( Q::Icon | Q::Selected ).defaultSize();
|
||||
|
||||
const auto graphic0 = bar->symbolHint( Q::Icon | Q::Selected );
|
||||
QSizeF segmentSize;
|
||||
|
||||
for ( int i = 0; i < bar->count(); i++ )
|
||||
{
|
||||
const auto option = bar->optionAt( i );
|
||||
|
||||
auto iconSize = option.icon().graphic().defaultSize();
|
||||
iconSize = iconSize.expandedTo( sizeSymbol );
|
||||
|
||||
LayoutEngine layoutEngine( bar, i );
|
||||
|
||||
auto graphic = qskValueAt< QskGraphic >( bar, i );
|
||||
if ( graphic.isNull() )
|
||||
graphic = graphic0;
|
||||
|
||||
layoutEngine.setGraphicTextElements( bar,
|
||||
Q::Text, qskValueAt< QString >( bar, i ),
|
||||
Q::Icon, graphic.defaultSize() );
|
||||
Q::Text, option.text(), Q::Icon, iconSize );
|
||||
|
||||
const auto size = layoutEngine.sizeHint( which, QSizeF() );
|
||||
|
||||
if( size.width() > sizeMax.width() )
|
||||
sizeMax = size;
|
||||
segmentSize = segmentSize.expandedTo( size );
|
||||
}
|
||||
|
||||
sizeMax = bar->outerBoxSize( Q::Segment, sizeMax );
|
||||
sizeMax = sizeMax.expandedTo( bar->strutSizeHint( Q::Segment ) );
|
||||
sizeMax = sizeMax.grownBy( bar->marginHint( Q::Segment ) );
|
||||
segmentSize = bar->outerBoxSize( Q::Segment, segmentSize );
|
||||
segmentSize = segmentSize.expandedTo( bar->strutSizeHint( Q::Segment ) );
|
||||
segmentSize = segmentSize.grownBy( bar->marginHint( Q::Segment ) );
|
||||
|
||||
return sizeMax;
|
||||
return segmentSize;
|
||||
}
|
||||
|
||||
QSizeF QskSegmentedBarSkinlet::sizeHint( const QskSkinnable* skinnable,
|
||||
|
@ -324,6 +306,7 @@ QRectF QskSegmentedBarSkinlet::sampleRect( const QskSkinnable* skinnable,
|
|||
|
||||
LayoutEngine layoutEngine( bar, index );
|
||||
layoutEngine.setGeometries( rect );
|
||||
|
||||
return layoutEngine.subControlRect( subControl );
|
||||
}
|
||||
|
||||
|
@ -373,7 +356,7 @@ QSGNode* QskSegmentedBarSkinlet::updateSampleNode( const QskSkinnable* skinnable
|
|||
|
||||
if ( subControl == Q::Text )
|
||||
{
|
||||
const auto text = qskValueAt< QString >( bar, index );
|
||||
const auto text = bar->optionAt( index ).text();
|
||||
|
||||
if( !text.isEmpty() )
|
||||
{
|
||||
|
|
|
@ -0,0 +1,133 @@
|
|||
/******************************************************************************
|
||||
* QSkinny - Copyright (C) 2016 Uwe Rathmann
|
||||
* This file may be used under the terms of the QSkinny License, Version 1.0
|
||||
*****************************************************************************/
|
||||
|
||||
#include "QskIcon.h"
|
||||
#include "QskGraphicProvider.h"
|
||||
|
||||
#include <qvariant.h>
|
||||
#include <qhashfunctions.h>
|
||||
|
||||
static void qskRegisterIcon()
|
||||
{
|
||||
qRegisterMetaType< QskIcon >();
|
||||
|
||||
#if QT_VERSION < QT_VERSION_CHECK( 6, 0, 0 )
|
||||
QMetaType::registerEqualsComparator< QskIcon >();
|
||||
#endif
|
||||
}
|
||||
|
||||
Q_CONSTRUCTOR_FUNCTION( qskRegisterIcon )
|
||||
|
||||
QskIcon::QskIcon()
|
||||
: m_data( new Data() )
|
||||
{
|
||||
}
|
||||
|
||||
QskIcon::QskIcon( const QUrl& source )
|
||||
: m_source( source )
|
||||
, m_data( new Data() )
|
||||
{
|
||||
}
|
||||
|
||||
QskIcon::QskIcon( const QskGraphic& graphic )
|
||||
: m_data( new Data() )
|
||||
{
|
||||
if ( !graphic.isNull() )
|
||||
m_data->graphic = new QskGraphic( graphic );
|
||||
}
|
||||
|
||||
bool QskIcon::operator==( const QskIcon& other ) const noexcept
|
||||
{
|
||||
if ( m_data == other.m_data )
|
||||
return true; // copy
|
||||
|
||||
if ( !m_source.isEmpty() || !other.m_source.isEmpty() )
|
||||
return m_source == other.m_source;
|
||||
|
||||
if ( m_data->graphic && other.m_data->graphic )
|
||||
return m_data->graphic == other.m_data->graphic;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void QskIcon::setSource( const QUrl& source )
|
||||
{
|
||||
if ( source != m_source )
|
||||
{
|
||||
m_source = source;
|
||||
|
||||
#if 1
|
||||
m_data.detach(); // needed ???
|
||||
#endif
|
||||
m_data.reset();
|
||||
}
|
||||
}
|
||||
|
||||
void QskIcon::setGraphic( const QskGraphic& graphic )
|
||||
{
|
||||
m_source.clear();
|
||||
m_data.detach();
|
||||
|
||||
if ( m_data->graphic )
|
||||
*m_data->graphic = graphic;
|
||||
else
|
||||
m_data->graphic = new QskGraphic( graphic );
|
||||
}
|
||||
|
||||
QskGraphic QskIcon::graphic() const
|
||||
{
|
||||
if ( m_data->graphic == nullptr && !m_source.isEmpty() )
|
||||
{
|
||||
/*
|
||||
not detaching: lazy loading should affect all copies
|
||||
|
||||
note: even when loadGraphic returns a null graphic we
|
||||
initialize m_iconData to avoid, that loading will
|
||||
be repeated again and again.
|
||||
*/
|
||||
|
||||
m_data->graphic = new QskGraphic( Qsk::loadGraphic( m_source ) );
|
||||
}
|
||||
|
||||
return m_data->graphic ? *m_data->graphic : QskGraphic();
|
||||
}
|
||||
|
||||
QskHashValue QskIcon::hash( QskHashValue seed ) const
|
||||
{
|
||||
if ( !m_source.isEmpty() )
|
||||
return qHash( m_source, seed );
|
||||
|
||||
return maybeGraphic().hash( seed );
|
||||
}
|
||||
|
||||
#ifndef QT_NO_DEBUG_STREAM
|
||||
|
||||
#include <qdebug.h>
|
||||
|
||||
QDebug operator<<( QDebug debug, const QskIcon& icon )
|
||||
{
|
||||
QDebugStateSaver saver( debug );
|
||||
debug.nospace();
|
||||
|
||||
debug << "Icon" << "( ";
|
||||
if ( !icon.source().isEmpty() )
|
||||
{
|
||||
debug << icon.source();
|
||||
}
|
||||
else
|
||||
{
|
||||
const auto graphic = icon.maybeGraphic();
|
||||
if ( !graphic.isNull() )
|
||||
debug << "I:" << graphic.hash( 0 );
|
||||
}
|
||||
|
||||
debug << " )";
|
||||
|
||||
return debug;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#include "moc_QskIcon.cpp"
|
|
@ -0,0 +1,104 @@
|
|||
/******************************************************************************
|
||||
* QSkinny - Copyright (C) 2016 Uwe Rathmann
|
||||
* This file may be used under the terms of the QSkinny License, Version 1.0
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef QSK_ICON_H
|
||||
#define QSK_ICON_H
|
||||
|
||||
#include "QskGlobal.h"
|
||||
#include "QskGraphic.h"
|
||||
|
||||
#include <qurl.h>
|
||||
#include <qmetatype.h>
|
||||
#include <qshareddata.h>
|
||||
|
||||
/*
|
||||
Most controls offer 2 way to pass an icon:
|
||||
|
||||
- URL
|
||||
- QskGraphic
|
||||
|
||||
For the vast majority of the application icons URLs are used
|
||||
that will be loaded at runtime by a QskGraphicProvider.
|
||||
( QML code always uses URLs )
|
||||
|
||||
QskIcon implements a lazy loading strategy, that avoids unsatisfying
|
||||
startup performance from loading to many icons in advance.
|
||||
*/
|
||||
|
||||
class QSK_EXPORT QskIcon
|
||||
{
|
||||
Q_GADGET
|
||||
|
||||
Q_PROPERTY( QskGraphic graphic READ graphic WRITE setGraphic )
|
||||
Q_PROPERTY( QUrl source READ source WRITE setSource )
|
||||
|
||||
public:
|
||||
QskIcon();
|
||||
|
||||
QskIcon( const QUrl& );
|
||||
QskIcon( const QskGraphic& );
|
||||
|
||||
bool operator==( const QskIcon& ) const noexcept;
|
||||
bool operator!=( const QskIcon& ) const noexcept;
|
||||
|
||||
bool isNull() const;
|
||||
|
||||
void setSource( const QUrl& );
|
||||
QUrl source() const noexcept;
|
||||
|
||||
void setGraphic( const QskGraphic& );
|
||||
QskGraphic graphic() const;
|
||||
|
||||
QskGraphic maybeGraphic() const noexcept;
|
||||
|
||||
QskHashValue hash( QskHashValue ) const;
|
||||
|
||||
private:
|
||||
QUrl m_source;
|
||||
|
||||
class Data : public QSharedData
|
||||
{
|
||||
public:
|
||||
~Data() { delete graphic; }
|
||||
QskGraphic* graphic = nullptr;
|
||||
};
|
||||
|
||||
mutable QExplicitlySharedDataPointer< Data > m_data;
|
||||
};
|
||||
|
||||
Q_DECLARE_METATYPE( QskIcon )
|
||||
|
||||
inline bool QskIcon::isNull() const
|
||||
{
|
||||
if ( m_data->graphic )
|
||||
return m_data->graphic->isNull();
|
||||
|
||||
return m_source.isEmpty();
|
||||
}
|
||||
|
||||
inline QUrl QskIcon::source() const noexcept
|
||||
{
|
||||
return m_source;
|
||||
}
|
||||
|
||||
inline QskGraphic QskIcon::maybeGraphic() const noexcept
|
||||
{
|
||||
return m_data->graphic ? *m_data->graphic : QskGraphic();
|
||||
}
|
||||
|
||||
inline bool QskIcon::operator!=( const QskIcon& other ) const noexcept
|
||||
{
|
||||
return ( !( *this == other ) );
|
||||
}
|
||||
|
||||
#ifndef QT_NO_DEBUG_STREAM
|
||||
|
||||
class QDebug;
|
||||
|
||||
QSK_EXPORT QDebug operator<<( QDebug, const QskIcon& );
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -30,6 +30,7 @@ HEADERS += \
|
|||
common/QskGradientStop.h \
|
||||
common/QskHctColor.h \
|
||||
common/QskIntervalF.h \
|
||||
common/QskLabelData.h \
|
||||
common/QskMargins.h \
|
||||
common/QskMetaFunction.h \
|
||||
common/QskMetaFunction.hpp \
|
||||
|
@ -60,6 +61,7 @@ SOURCES += \
|
|||
common/QskGradientStop.cpp \
|
||||
common/QskHctColor.cpp \
|
||||
common/QskIntervalF.cpp \
|
||||
common/QskLabelData.cpp \
|
||||
common/QskMargins.cpp \
|
||||
common/QskMetaFunction.cpp \
|
||||
common/QskMetaInvokable.cpp \
|
||||
|
@ -83,6 +85,7 @@ HEADERS += \
|
|||
graphic/QskGraphicProvider.h \
|
||||
graphic/QskGraphicProviderMap.h \
|
||||
graphic/QskGraphicTextureFactory.h \
|
||||
graphic/QskIcon.h \
|
||||
graphic/QskPainterCommand.h \
|
||||
graphic/QskStandardSymbol.h
|
||||
|
||||
|
@ -95,6 +98,7 @@ SOURCES += \
|
|||
graphic/QskGraphicProvider.cpp \
|
||||
graphic/QskGraphicProviderMap.cpp \
|
||||
graphic/QskGraphicTextureFactory.cpp \
|
||||
graphic/QskIcon.cpp \
|
||||
graphic/QskPainterCommand.cpp \
|
||||
graphic/QskStandardSymbol.cpp
|
||||
|
||||
|
|
Loading…
Reference in New Issue