Merge branch 'uwerat-master' into material-theme

This commit is contained in:
Peter Hartmann 2022-06-15 10:58:56 +02:00
commit bac7a2024a
9 changed files with 288 additions and 76 deletions

View File

@ -14,40 +14,103 @@
ShadowedBox::ShadowedBox( QQuickItem* parentItem ) ShadowedBox::ShadowedBox( QQuickItem* parentItem )
: QskBox( true, parentItem ) : QskBox( true, parentItem )
{ {
QColor c( Qt::darkRed );
#if 0
c.setAlpha( 100 );
#endif
setGradientHint( Panel, c );
setBoxShapeHint( Panel, QskBoxShapeMetrics( 40, 0, 15, 0 ) );
setBoxBorderMetricsHint( Panel, 0 );
#if 0
setBoxBorderMetricsHint( Panel, 10 );
setBoxBorderColorsHint( Panel, Qt::blue );
#endif
setShadowColorHint( Panel, Qt::black );
} }
ShadowedBox::~ShadowedBox() ShadowedBox::~ShadowedBox()
{ {
} }
void ShadowedBox::setShadow( const QskShadowMetrics& shadow ) void ShadowedBox::setOffsetX( qreal dx )
{ {
setShadowMetricsHint( Panel, shadow ); auto metrics = shadowMetrics();
metrics.setOffsetX( dx );
setShadowMetrics( metrics );
} }
void ShadowedBox::setShadowColor( const QColor& color ) qreal ShadowedBox::offsetX() const
{ {
return shadowMetrics().offset().x();
}
void ShadowedBox::setOffsetY( qreal dy )
{
auto metrics = shadowMetrics();
metrics.setOffsetY( dy );
setShadowMetrics( metrics );
}
qreal ShadowedBox::offsetY() const
{
return shadowMetrics().offset().y();
}
void ShadowedBox::setSpreadRadius( qreal radius )
{
auto metrics = shadowMetrics();
metrics.setSpreadRadius( radius );
setShadowMetrics( metrics );
}
qreal ShadowedBox::spreadRadius() const
{
return shadowMetrics().spreadRadius();
}
void ShadowedBox::setBlurRadius( qreal radius )
{
auto metrics = shadowMetrics();
metrics.setBlurRadius( radius );
setShadowMetrics( metrics );
}
qreal ShadowedBox::blurRadius() const
{
return shadowMetrics().blurRadius();
}
void ShadowedBox::setOpacity( qreal opacity )
{
opacity = qBound( 0.0, opacity, 1.0 );
auto color = shadowColorHint( Panel );
color.setAlphaF( opacity );
setShadowColorHint( Panel, color ); setShadowColorHint( Panel, color );
} }
void ShadowedBox::setGradient( const QskGradient& gradient ) qreal ShadowedBox::opacity() const
{ {
setGradientHint( Panel, gradient ); return shadowColorHint( Panel ).alphaF();
} }
void ShadowedBox::setShape( const QskBoxShapeMetrics& shape ) QskShadowMetrics ShadowedBox::shadowMetrics() const
{ {
setBoxShapeHint( Panel, shape ); return shadowMetricsHint( Panel );
} }
void ShadowedBox::setBorderWidth( qreal width ) void ShadowedBox::setShadowMetrics( const QskShadowMetrics& metrics )
{ {
setBoxBorderMetricsHint( Panel, width ); setShadowMetricsHint( Panel, metrics );
}
void ShadowedBox::setBorderColors( const QskBoxBorderColors& colors )
{
setBoxBorderColorsHint( Panel, colors );
} }
#include "moc_ShadowedBox.cpp" #include "moc_ShadowedBox.cpp"

View File

@ -7,25 +7,34 @@
#include <QskBox.h> #include <QskBox.h>
class QskGradient;
class QskShadowMetrics; class QskShadowMetrics;
class QskBoxShapeMetrics;
class QskBoxBorderColors;
class ShadowedBox : public QskBox class ShadowedBox : public QskBox
{ {
Q_OBJECT Q_OBJECT
public: public:
ShadowedBox(QQuickItem* parent = nullptr); ShadowedBox( QQuickItem* parent = nullptr );
~ShadowedBox() override; ~ShadowedBox() override;
void setShape( const QskBoxShapeMetrics& ); qreal offsetX() const;
void setGradient( const QskGradient& ); qreal offsetY() const;
void setBorderWidth( qreal width ); qreal spreadRadius() const;
void setBorderColors( const QskBoxBorderColors& ); qreal blurRadius() const;
void setShadow( const QskShadowMetrics& ); qreal opacity() const;
void setShadowColor( const QColor& );
public Q_SLOTS:
void setOffsetX( qreal );
void setOffsetY( qreal );
void setSpreadRadius( qreal );
void setBlurRadius( qreal );
void setOpacity( qreal );
private:
QskShadowMetrics shadowMetrics() const;
void setShadowMetrics( const QskShadowMetrics& );
}; };

View File

@ -7,43 +7,122 @@
#include <QskObjectCounter.h> #include <QskObjectCounter.h>
#include <QskWindow.h> #include <QskWindow.h>
#include <QskLinearBox.h> #include <QskGridBox.h>
#include <QskSlider.h>
#include <QskTextLabel.h>
#include <QskRgbValue.h> #include <QskRgbValue.h>
#include <QskGradient.h>
#include <QskShadowMetrics.h>
#include <QskBoxShapeMetrics.h>
#include <QskBoxBorderColors.h>
#include <SkinnyShortcut.h> #include <SkinnyShortcut.h>
#include <QGuiApplication> #include <QGuiApplication>
#include <QFontMetrics>
class Box : public ShadowedBox class BoxPanel : public QskBox
{ {
public: public:
Box( QQuickItem* parent = nullptr ) BoxPanel( QQuickItem* parent = nullptr )
: ShadowedBox( parent ) : QskBox( parent )
{ {
const qreal w = 10; setAutoLayoutChildren( true );
setPadding( 60 );
QskShadowMetrics shadow; setPanel( true );
//shadow.setOffset( 20.0, 20.0 ); setGradientHint( QskBox::Panel, QGradient::SnowAgain );
shadow.setSpreadRadius( w ); }
shadow.setBlurRadius( w ); };
setShadow( shadow ); class Slider : public QskSlider
setShadowColor( Qt::black ); {
public:
Slider( qreal min, qreal max, qreal step, qreal value, QQuickItem* parent = nullptr )
: QskSlider( parent )
{
setBoundaries( min, max );
setStepSize( step );
setSnap( true );
setValue( value );
}
};
QColor c( Qt::darkRed ); class ValueLabel : public QskTextLabel
#if 0 {
c.setAlpha( 100 ); public:
#endif ValueLabel( QQuickItem* parent = nullptr )
: QskTextLabel( parent )
{
setFixedWidth( QFontMetrics( font() ).horizontalAdvance( "-100" ) );
setAlignment( Qt::AlignLeft | Qt::AlignVCenter );
}
setGradient( c ); void setValue( qreal value )
setShape( QskBoxShapeMetrics( 40, 10, 15, 5 ) ); {
setText( QString::number( value ) );
}
};
setBorderWidth( w ); class GridBox : public QskGridBox
setBorderColors( Qt::blue ); {
public:
GridBox( QQuickItem* parent = nullptr )
: QskGridBox( parent )
{
setMargins( 5 );
setColumnStretchFactor( 1, 1 );
auto sliderX = new Slider( -50, 50, 1, 10 );
auto sliderY = new Slider( -50, 50, 1, 10 );
auto sliderSpread = new Slider( 0, 50, 1, 0 );
auto sliderBlur = new Slider( 0, 50, 1, 10 );
auto sliderOpacity = new Slider( 0, 1, 0.01, 1 );
auto panel = new BoxPanel();
int row = 0;
addSlider( row++, "Offset X", sliderX );
addSlider( row++, "Offset Y", sliderY );
addSlider( row++, "Spread Radius", sliderSpread );
addSlider( row++, "Blur Radius", sliderBlur );
addSlider( row++, "Opacity", sliderOpacity );
addItem( panel, row, 0, -1, -1 );
auto box = new ShadowedBox( panel );
box->setOffsetX( sliderX->value() );
box->setOffsetY( sliderY->value() );
box->setSpreadRadius( sliderSpread->value() );
box->setBlurRadius( sliderBlur->value() );
box->setOpacity( sliderOpacity->value() );
connect( sliderX, &QskSlider::valueChanged,
box, &ShadowedBox::setOffsetX );
connect( sliderY, &QskSlider::valueChanged,
box, &ShadowedBox::setOffsetY );
connect( sliderSpread, &QskSlider::valueChanged,
box, &ShadowedBox::setSpreadRadius );
connect( sliderBlur, &QskSlider::valueChanged,
box, &ShadowedBox::setBlurRadius );
connect( sliderOpacity, &QskSlider::valueChanged,
box, &ShadowedBox::setOpacity );
}
private:
void addSlider( int row, const QString& text, QskSlider* slider )
{
addItem( new QskTextLabel( text ), row, 0 );
addItem( slider, row, 1 );
auto label = new ValueLabel();
label->setValue( slider->value() );
addItem( label, row, 2 );
connect( slider, &QskSlider::valueChanged,
label, [label]( qreal value ) { label->setText( QString::number( value ) ); } );
} }
}; };
@ -57,20 +136,8 @@ int main( int argc, char* argv[] )
SkinnyShortcut::enable( SkinnyShortcut::AllShortcuts ); SkinnyShortcut::enable( SkinnyShortcut::AllShortcuts );
auto layout = new QskLinearBox();
layout->setPanel( true );
#if 1
layout->setGradientHint( QskBox::Panel,
QskGradient( Qt::Vertical, QskRgb::WhiteSmoke, QskRgb::MistyRose ) );
#else
layout->setGradientHint( QskBox::Panel, Qt::white );
#endif
layout->setPadding( 60 );
(void ) new Box( layout );
QskWindow window; QskWindow window;
window.setColor( QskRgb::PapayaWhip ); window.addItem( new GridBox() );
window.addItem( layout );
window.resize( 600, 600 ); window.resize( 600, 600 );
window.show(); window.show();

View File

@ -434,7 +434,7 @@ void Editor::setupPushButton()
using A = QskAspect; using A = QskAspect;
using Q = QskPushButton; using Q = QskPushButton;
setStrutSize( Q::Panel, -1, 31 ); setFlagHint( Q::Panel | QskAspect::Direction, Qsk::LeftToRight );
setSpacing( Q::Panel, qskDpiScaled( 4 ) ); setSpacing( Q::Panel, qskDpiScaled( 4 ) );
setPadding( Q::Panel, { 24, 0, 20, 0 } ); setPadding( Q::Panel, { 24, 0, 20, 0 } );
@ -473,6 +473,8 @@ void Editor::setupPushButton()
setBoxBorderMetrics( Q::Panel, 1, { QskStateCombination::CombinationNoState, Q::Outlined } ); setBoxBorderMetrics( Q::Panel, 1, { QskStateCombination::CombinationNoState, Q::Outlined } );
setBoxBorderColors( Q::Panel | Q::Outlined, m_pal.outline ); setBoxBorderColors( Q::Panel | Q::Outlined, m_pal.outline );
setPadding( Q::Graphic, 5 );
setGradient( Q::Panel | Q::Disabled, Qt::transparent, combination ); setGradient( Q::Panel | Q::Disabled, Qt::transparent, combination );
setBoxBorderColors( Q::Panel | Q::Outlined | Q::Disabled, c1 ); setBoxBorderColors( Q::Panel | Q::Outlined | Q::Disabled, c1 );

View File

@ -566,7 +566,7 @@ void Editor::setupPushButton()
using Q = QskPushButton; using Q = QskPushButton;
// Panel // Panel
setFlagHint( Q::Panel | QskAspect::Direction, Qsk::TopToBottom );
setStrutSize( Q::Panel, qskDpiScaled( 75.0 ), qskDpiScaled( 23.0 ) ); setStrutSize( Q::Panel, qskDpiScaled( 75.0 ), qskDpiScaled( 23.0 ) );
setMargin( Q::Panel, 0 ); setMargin( Q::Panel, 0 );
@ -594,6 +594,9 @@ void Editor::setupPushButton()
setColor( Q::Text, m_pal.themeForeground ); setColor( Q::Text, m_pal.themeForeground );
setColor( Q::Text | Q::Disabled, m_pal.darker200 ); setColor( Q::Text | Q::Disabled, m_pal.darker200 );
// Graphic
setPadding( Q::Graphic, 2 );
} }
void Editor::setupDialogButton() void Editor::setupDialogButton()

View File

@ -32,6 +32,7 @@ class QSK_EXPORT QskAspect
NoPrimitive = 0, NoPrimitive = 0,
Alignment, Alignment,
Direction,
Style, Style,
GraphicRole, GraphicRole,
FontRole, FontRole,

View File

@ -45,6 +45,9 @@ class QSK_EXPORT QskShadowMetrics
constexpr qreal totalRadius() const noexcept; constexpr qreal totalRadius() const noexcept;
void setOffsetX( qreal dx ) noexcept;
void setOffsetY( qreal dy ) noexcept;
void setOffset( qreal dx, qreal dy ) noexcept; void setOffset( qreal dx, qreal dy ) noexcept;
void setOffset( const QPointF& ) noexcept; void setOffset( const QPointF& ) noexcept;
@ -98,6 +101,7 @@ inline constexpr bool QskShadowMetrics::operator==(
const QskShadowMetrics& other ) const noexcept const QskShadowMetrics& other ) const noexcept
{ {
return ( m_sizeMode == other.m_sizeMode ) return ( m_sizeMode == other.m_sizeMode )
&& ( m_offset == other.m_offset )
&& ( m_spreadRadius == other.m_spreadRadius ) && ( m_spreadRadius == other.m_spreadRadius )
&& ( m_blurRadius == other.m_blurRadius ) && ( m_blurRadius == other.m_blurRadius )
&& ( m_sizeMode == other.m_sizeMode ); && ( m_sizeMode == other.m_sizeMode );
@ -144,6 +148,16 @@ inline constexpr Qt::SizeMode QskShadowMetrics::sizeMode() const noexcept
return m_sizeMode; return m_sizeMode;
} }
inline void QskShadowMetrics::setOffsetX( qreal dx ) noexcept
{
m_offset.rx() = dx;
}
inline void QskShadowMetrics::setOffsetY( qreal dy ) noexcept
{
m_offset.ry() = dy;
}
inline void QskShadowMetrics::setOffset( qreal dx, qreal dy ) noexcept inline void QskShadowMetrics::setOffset( qreal dx, qreal dy ) noexcept
{ {
m_offset.rx() = dx; m_offset.rx() = dx;

View File

@ -77,11 +77,24 @@ QRectF QskPushButtonSkinlet::textRect(
if ( button->hasGraphic() ) if ( button->hasGraphic() )
{ {
// in case of having text + graphic we put the text at the bottom const auto orientation = button->flagHint( QskPushButton::Panel | QskAspect::Direction, Qsk::LeftToRight );
qreal h = button->effectiveFontHeight( QskPushButton::Text ); switch( orientation )
if ( h < r.height() ) {
r.setTop( r.bottom() - h ); case Qsk::LeftToRight:
{
const auto graphicsRect = subControlRect( button, contentsRect, QskPushButton::Graphic );
const auto spacing = button->metric( QskPushButton::Panel | QskAspect::Spacing );
r.setX( r.x() + graphicsRect.width() + spacing );
break;
}
default: // Qsk::TopToBottom, the other ones are not handled yet
{
qreal h = button->effectiveFontHeight( QskPushButton::Text );
if ( h < r.height() )
r.setTop( r.bottom() - h );
}
}
} }
return r; return r;
@ -94,7 +107,10 @@ QRectF QskPushButtonSkinlet::graphicRect(
auto r = button->subControlContentsRect( contentsRect, QskPushButton::Panel ); auto r = button->subControlContentsRect( contentsRect, QskPushButton::Panel );
if ( !button->text().isEmpty() ) const auto orientation = button->flagHint( QskPushButton::Panel
| QskAspect::Direction, Qsk::LeftToRight );
if ( !button->text().isEmpty() && orientation == Qsk::TopToBottom )
{ {
const auto textRect = subControlRect( button, contentsRect, QskPushButton::Text ); const auto textRect = subControlRect( button, contentsRect, QskPushButton::Text );
qreal h = textRect.height() + button->spacingHint( QskPushButton::Panel ); qreal h = textRect.height() + button->spacingHint( QskPushButton::Panel );
@ -106,6 +122,7 @@ QRectF QskPushButtonSkinlet::graphicRect(
} }
const auto maxSize = button->graphicSourceSize(); const auto maxSize = button->graphicSourceSize();
if ( maxSize.width() >= 0 || maxSize.height() >= 0 ) if ( maxSize.width() >= 0 || maxSize.height() >= 0 )
{ {
// limiting the size by graphicSize // limiting the size by graphicSize
@ -134,15 +151,34 @@ QRectF QskPushButtonSkinlet::graphicRect(
const double scaleFactor = const double scaleFactor =
qMin( r.width() / sz.width(), r.height() / sz.height() ); qMin( r.width() / sz.width(), r.height() / sz.height() );
// early aligning to avoid pointless operations, that finally will
// have no effect, when drawing to an integer based paint device
const int w = qFloor( scaleFactor * sz.width() ); const int w = qFloor( scaleFactor * sz.width() );
const int h = qFloor( scaleFactor * sz.height() ); const int h = qFloor( scaleFactor * sz.height() );
const int x = qFloor( r.center().x() - 0.5 * w ); int x, y;
const int y = qFloor( r.center().y() - 0.5 * h );
const auto orientation = button->flagHint( QskPushButton::Panel
| QskAspect::Direction, Qsk::LeftToRight );
switch( orientation )
{
case Qsk::LeftToRight:
{
x = r.left();
y = r.top();
break;
}
default: // TopToBottom
{
// early aligning to avoid pointless operations, that finally will
// have no effect, when drawing to an integer based paint device
x = qFloor( r.center().x() - 0.5 * w );
y = qFloor( r.center().y() - 0.5 * h );
}
}
r = QRectF( x, y, w, h ); r = QRectF( x, y, w, h );
const auto padding = button->paddingHint( QskPushButton::Graphic );
r = r.marginsRemoved( padding );
} }
return r; return r;
@ -213,10 +249,25 @@ QSizeF QskPushButtonSkinlet::sizeHint( const QskSkinnable* skinnable,
} }
} }
const qreal padding = 2.0; // paddingHint( Graphic ) ??? const QMarginsF padding = button->paddingHint( QskPushButton::Graphic );
size.rheight() += 2 * padding + h; const auto orientation = button->flagHint( QskPushButton::Panel
size.rwidth() = qMax( size.width(), w ); | QskAspect::Direction, Qsk::LeftToRight );
switch( orientation )
{
case Qsk::LeftToRight:
{
size.rwidth() += padding.left() + w + padding.right();
size.rheight() = qMax( size.height(), h );
break;
}
default: // TopToBottom
{
size.rheight() += padding.top() + h + padding.bottom();
size.rwidth() = qMax( size.width(), w );
}
}
} }
size = size.expandedTo( button->strutSizeHint( QskPushButton::Panel ) ); size = size.expandedTo( button->strutSizeHint( QskPushButton::Panel ) );

View File

@ -48,6 +48,8 @@ void QskShadedBoxNode::setShadowData(
insertChildNodeBefore( m_shadowNode, &m_boxNode ); insertChildNodeBefore( m_shadowNode, &m_boxNode );
} }
m_shadowNode->setColor( color );
m_shadowNode->setRect( metrics.shadowRect( rect ) ); m_shadowNode->setRect( metrics.shadowRect( rect ) );
m_shadowNode->setShape( shape ); m_shadowNode->setShape( shape );
m_shadowNode->setBlurRadius( metrics.blurRadius() ); m_shadowNode->setBlurRadius( metrics.blurRadius() );