From e9343090f694ac01a9a67bdb61bfab78484ef904 Mon Sep 17 00:00:00 2001 From: Hugo Pereira Da Costa Date: Thu, 31 Jul 2014 17:32:04 +0200 Subject: [PATCH] started to implement tabbar rendering --- kstyle/animations/breezewidgetstateengine.h | 2 - kstyle/breezeanimationmodes.h | 2 + kstyle/breezehelper.cpp | 84 ++++++++++++++++++++- kstyle/breezehelper.h | 21 ++++++ kstyle/breezemetrics.h | 5 ++ kstyle/breezestyle.cpp | 74 +++++++++++++++++- kstyle/breezestyle.h | 2 +- 7 files changed, 182 insertions(+), 8 deletions(-) diff --git a/kstyle/animations/breezewidgetstateengine.h b/kstyle/animations/breezewidgetstateengine.h index e4f76a45..ee235885 100644 --- a/kstyle/animations/breezewidgetstateengine.h +++ b/kstyle/animations/breezewidgetstateengine.h @@ -157,6 +157,4 @@ namespace Breeze } -Q_DECLARE_OPERATORS_FOR_FLAGS(Breeze::AnimationModes) - #endif diff --git a/kstyle/breezeanimationmodes.h b/kstyle/breezeanimationmodes.h index 272b8f51..8e1bd654 100644 --- a/kstyle/breezeanimationmodes.h +++ b/kstyle/breezeanimationmodes.h @@ -45,4 +45,6 @@ namespace Breeze } +Q_DECLARE_OPERATORS_FOR_FLAGS( Breeze::AnimationModes ); + #endif diff --git a/kstyle/breezehelper.cpp b/kstyle/breezehelper.cpp index 931a5aba..bc7ed325 100644 --- a/kstyle/breezehelper.cpp +++ b/kstyle/breezehelper.cpp @@ -618,7 +618,7 @@ namespace Breeze } - // border + // outline if( outline.isValid() ) { painter->setPen( QPen( outline, 2 ) ); @@ -632,4 +632,86 @@ namespace Breeze } + //______________________________________________________________________________ + void Helper::renderTabBarTab( QPainter* painter, const QRect& rect, const QColor& color, const QColor& outline, Corners corners ) const + { + + // setup painter + painter->setRenderHint( QPainter::Antialiasing, true ); + + const QRectF baseRect( rect ); + + // content + if( color.isValid() ) + { + painter->setPen( Qt::NoPen ); + painter->setBrush( color ); + + QPainterPath path( roundedPath( baseRect, 2.5, corners ) ); + painter->drawPath( path ); + + } + + // outline + if( outline.isValid() ) + { + painter->setPen( QPen( outline, 1 ) ); + painter->setBrush( Qt::NoBrush ); + + QPainterPath path( roundedPath( baseRect.adjusted( 0.5, 0.5, -0.5, -0.5 ), 2, corners ) ); + painter->drawPath( path ); + } + + } + + //______________________________________________________________________________ + QPainterPath Helper::roundedPath( const QRectF& rect, qreal radius, Corners corners ) const + { + + QPainterPath path; + + const QSizeF cornerSize( 2*radius, 2*radius ); + + // rotate counterclockwise + // top left corner + if( corners & CornerTopLeft ) + { + + path.moveTo( rect.topLeft() + QPointF( radius, 0 ) ); + path.arcTo( QRectF( rect.topLeft(), cornerSize ), 90, 90 ); + + } else path.lineTo( rect.topLeft() ); + + // bottom left corner + if( corners & CornerBottomLeft ) + { + + path.lineTo( rect.bottomLeft() + QPointF( 0, radius ) ); + path.arcTo( QRectF( rect.bottomLeft() + QPointF( 0, 2*radius ), cornerSize ), 180, 90 ); + + } else path.lineTo( rect.bottomLeft() ); + + // bottom right corner + if( corners & CornerBottomRight ) + { + + path.lineTo( rect.bottomRight() - QPointF( radius, 0 ) ); + path.arcTo( QRectF( rect.bottomRight() - QPointF( 2*radius, 2*radius ), cornerSize ), 270, 90 ); + + } else path.lineTo( rect.bottomRight() ); + + // top right corner + if( corners & CornerTopRight ) + { + + path.lineTo( rect.topRight() + QPointF( 0, radius ) ); + path.arcTo( QRectF( rect.topRight() - QPointF( 2*radius, 0 ), cornerSize ), 0, 90 ); + + } else path.lineTo( rect.topRight() ); + + path.closeSubpath(); + return path; + + } + } diff --git a/kstyle/breezehelper.h b/kstyle/breezehelper.h index 4512f0fa..65169746 100644 --- a/kstyle/breezehelper.h +++ b/kstyle/breezehelper.h @@ -28,6 +28,8 @@ #include #include +#include + namespace Breeze { @@ -141,6 +143,20 @@ namespace Breeze //! scrollbar handle void renderScrollBarHandle( QPainter*, const QRect&, const QColor& color, const QColor& outline ) const; + //! corner enumeration, needed for tabbar tabs + enum Corner + { + CornerTopLeft = 1 << 0, + CornerTopRight = 1 << 1, + CornerBottomLeft = 1 << 2, + CornerBottomRight = 1 << 3 + }; + + Q_DECLARE_FLAGS( Corners, Corner ); + + //! tabbar tab + void renderTabBarTab( QPainter*, const QRect&, const QColor& color, const QColor& outline, Corners ) const; + //@} protected: @@ -149,6 +165,9 @@ namespace Breeze quint64 colorKey( const QColor& color ) const { return color.isValid() ? color.rgba():0; } + //! return rounded path in a given rect, with only selected corners rounded, and for a given radius + QPainterPath roundedPath( const QRectF&, qreal, Corners ) const; + private: //! configuration @@ -165,4 +184,6 @@ namespace Breeze } +Q_DECLARE_OPERATORS_FOR_FLAGS( Breeze::Helper::Corners ); + #endif diff --git a/kstyle/breezemetrics.h b/kstyle/breezemetrics.h index b7a17b31..8c0b55b3 100644 --- a/kstyle/breezemetrics.h +++ b/kstyle/breezemetrics.h @@ -73,6 +73,11 @@ namespace Breeze Slider_Thickness = 6, Slider_ControlThickness = 20, + // tabbar + TabBar_TabMarginWidth = 4, + TabBar_TabMinWidth = 80, + TabBar_TabMinHeight = 28, + // list headers Header_MarginWidth = 8, Header_BoxTextSpace = 4, diff --git a/kstyle/breezestyle.cpp b/kstyle/breezestyle.cpp index 4441cce9..179eb7dc 100644 --- a/kstyle/breezestyle.cpp +++ b/kstyle/breezestyle.cpp @@ -211,6 +211,14 @@ namespace Breeze case PM_ButtonShiftHorizontal: return 0; case PM_ButtonShiftVertical: return 0; + // tabbar + case PM_TabBarTabShiftVertical: return 0; + case PM_TabBarTabShiftHorizontal: return 0; + case PM_TabBarTabOverlap: return 1; + case PM_TabBarBaseOverlap: return 1; + case PM_TabBarTabHSpace: return 2*Metrics::TabBar_TabMarginWidth; + case PM_TabBarTabVSpace: return 2*Metrics::TabBar_TabMarginWidth; + // scrollbars case PM_ScrollBarExtent: return Metrics::ScrollBar_Extend; case PM_ScrollBarSliderMin: return Metrics::ScrollBar_MinSliderHeight; @@ -251,6 +259,9 @@ namespace Breeze // groupboxes case SH_GroupBox_TextLabelVerticalAlignment: return Qt::AlignVCenter; + // tabbar + case SH_TabBar_Alignment: return Qt::AlignCenter; + // scrollbars case SH_ScrollBar_MiddleClickAbsolutePosition: return true; @@ -328,6 +339,9 @@ namespace Breeze case CT_ProgressBar: return progressBarSizeFromContents( option, size, widget ); case CT_HeaderSection: return headerSectionSizeFromContents( option, size, widget ); + // tabbar + case CT_TabBarTab: return tabBarTabSizeFromContents( option, size, widget ); + // fallback default: return KStyle::sizeFromContents( element, option, size, widget ); @@ -1273,12 +1287,64 @@ namespace Breeze } //______________________________________________________________ - QSize Style::headerSectionSizeFromContents( const QStyleOption*, const QSize& contentsSize, const QWidget* ) const + QSize Style::headerSectionSizeFromContents( const QStyleOption* option, const QSize& contentsSize, const QWidget* ) const { - QSize size( contentsSize ); - size.rwidth() += Metrics::Header_MarkSize + Metrics::Header_BoxTextSpace; - size.setHeight( qMax( size.height(), (int) Metrics::Header_MarkSize ) ); + + // cast option and check + const QStyleOptionHeader* headerOption( qstyleoption_cast( option ) ); + if( !headerOption ) return contentsSize; + + // get text size + const bool horizontal( headerOption->orientation == Qt::Horizontal ); + const bool hasText( !headerOption->text.isEmpty() ); + const bool hasIcon( !headerOption->icon.isNull() ); + + const QSize textSize( hasText ? headerOption->fontMetrics.size( 0, headerOption->text ) : QSize() ); + const QSize iconSize( hasIcon ? QSize( 22,22 ) : QSize() ); + + // contents width + int contentsWidth( 0 ); + if( hasText ) contentsWidth += textSize.width(); + if( hasIcon ) + { + contentsWidth += iconSize.width(); + if( hasText ) contentsWidth += Metrics::Header_BoxTextSpace; + } + + // contents height + int contentsHeight( 0 ); + if( hasText ) contentsHeight = textSize.height(); + if( hasIcon ) contentsHeight = qMax( contentsHeight, iconSize.height() ); + + if( horizontal ) + { + // also add space for icon + contentsWidth += Metrics::Header_MarkSize + Metrics::Header_BoxTextSpace; + contentsHeight = qMax( contentsHeight, (int) Metrics::Header_MarkSize ); + } + + // update contents size, add margins and return + const QSize size( contentsSize.expandedTo( QSize( contentsWidth, contentsHeight ) ) ); return expandSize( size, Metrics::Header_MarginWidth ); + + } + + //______________________________________________________________ + QSize Style::tabBarTabSizeFromContents( const QStyleOption* option, const QSize& contentsSize, const QWidget* ) const + { + + const QStyleOptionTab *tabOption( qstyleoption_cast( option ) ); + + // add margins + QSize size( expandSize( contentsSize, Metrics::TabBar_TabMarginWidth ) ); + + // compare to minimum size + const bool verticalTabs( tabOption && isVerticalTab( tabOption ) ); + if( verticalTabs ) size = size.expandedTo( QSize( Metrics::TabBar_TabMinHeight, Metrics::TabBar_TabMinWidth ) ); + else size = size.expandedTo( QSize( Metrics::TabBar_TabMinWidth, Metrics::TabBar_TabMinHeight ) ); + + return size; + } //______________________________________________________________ diff --git a/kstyle/breezestyle.h b/kstyle/breezestyle.h index 4c0b85af..e3946e74 100644 --- a/kstyle/breezestyle.h +++ b/kstyle/breezestyle.h @@ -248,8 +248,8 @@ namespace Breeze // QSize menuBarItemSizeFromContents( const QStyleOption*, const QSize& size, const QWidget* ) const; // QSize menuItemSizeFromContents( const QStyleOption*, const QSize&, const QWidget* ) const; QSize progressBarSizeFromContents( const QStyleOption*, const QSize&, const QWidget* ) const; + QSize tabBarTabSizeFromContents( const QStyleOption*, const QSize& size, const QWidget* ) const; // QSize tabWidgetSizeFromContents( const QStyleOption*, const QSize& size, const QWidget* ) const; -// QSize tabBarTabSizeFromContents( const QStyleOption*, const QSize& size, const QWidget* ) const; // QSize toolButtonSizeFromContents( const QStyleOption*, const QSize&, const QWidget* ) const; QSize headerSectionSizeFromContents( const QStyleOption*, const QSize&, const QWidget* ) const;