You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1994 lines
73 KiB
1994 lines
73 KiB
// krazy:excludeall=qclasses |
|
|
|
////////////////////////////////////////////////////////////////////////////// |
|
// breezestyle.cpp |
|
// Breeze widget style for KDE Frameworks |
|
// ------------------- |
|
// |
|
// Copyright (C) 2014 Hugo Pereira Da Costa <hugo.pereira@free.fr> |
|
// |
|
// This library is free software; you can redistribute it and/or |
|
// modify it under the terms of the GNU Library General Public |
|
// License version 2 as published by the Free Software Foundation. |
|
// |
|
// This library is distributed in the hope that it will be useful, |
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
|
// Library General Public License for more details. |
|
// |
|
// You should have received a copy of the GNU Library General Public License |
|
// along with this library; see the file COPYING.LIB. If not, write to |
|
// the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, |
|
// Boston, MA 02110-1301, USA. |
|
////////////////////////////////////////////////////////////////////////////// |
|
|
|
#include "breezestyle.h" |
|
#include "breezestyle.moc" |
|
|
|
#include "breezeanimations.h" |
|
#include "breezehelper.h" |
|
#include "breezemetrics.h" |
|
#include "breezemnemonics.h" |
|
#include "breezestyleconfigdata.h" |
|
#include "breezewindowmanager.h" |
|
|
|
#include <KColorUtils> |
|
|
|
#include <QApplication> |
|
#include <QAbstractItemView> |
|
#include <QCheckBox> |
|
#include <QComboBox> |
|
#include <QDial> |
|
#include <QDBusConnection> |
|
#include <QDockWidget> |
|
#include <QGroupBox> |
|
#include <QLineEdit> |
|
#include <QPainter> |
|
#include <QPushButton> |
|
#include <QRadioButton> |
|
#include <QScrollBar> |
|
#include <QSplitterHandle> |
|
#include <QTextEdit> |
|
#include <QToolBox> |
|
#include <QToolButton> |
|
|
|
Q_LOGGING_CATEGORY(BREEZE, "breeze") |
|
|
|
namespace Breeze |
|
{ |
|
|
|
//_________________________________________________ |
|
QStyle* Breeze::StylePlugin::create( const QString &key ) |
|
{ |
|
if( key.toLower() == QStringLiteral( "breeze" ) ) return new Style(); |
|
else return nullptr; |
|
} |
|
|
|
//_________________________________________________ |
|
Breeze::StylePlugin::~StylePlugin() |
|
{ |
|
// Delete style when using ::exit() otherwise it'll outlive the unloaded plugin and we'll get a crash |
|
if (qApp) delete qApp->style(); |
|
} |
|
|
|
//______________________________________________________________ |
|
Style::Style( void ): |
|
_addLineButtons( SingleButton ), |
|
_subLineButtons( SingleButton ), |
|
_helper( new Helper( StyleConfigData::self()->sharedConfig() ) ), |
|
_animations( new Animations( this ) ), |
|
_mnemonics( new Mnemonics( this ) ), |
|
_windowManager( new WindowManager( this ) ), |
|
SH_ArgbDndWindow( newStyleHint( QStringLiteral( "SH_ArgbDndWindow" ) ) ), |
|
CE_CapacityBar( newControlElement( QStringLiteral( "CE_CapacityBar" ) ) ) |
|
|
|
{ |
|
|
|
// use DBus connection to update on breeze configuration change |
|
QDBusConnection dbus = QDBusConnection::sessionBus(); |
|
dbus.connect( QString(), |
|
QStringLiteral( "/BreezeStyle" ), |
|
QStringLiteral( "org.kde.Breeze.Style" ), |
|
QStringLiteral( "reparseConfiguration" ), this, SLOT(configurationChanged()) ); |
|
|
|
// enable debugging |
|
QLoggingCategory::setFilterRules(QStringLiteral("breeze.debug = false")); |
|
|
|
// call the slot directly; this initial call will set up things that also |
|
// need to be reset when the system palette changes |
|
loadConfiguration(); |
|
|
|
} |
|
|
|
//______________________________________________________________ |
|
Style::~Style( void ) |
|
{ delete _helper; } |
|
|
|
//______________________________________________________________ |
|
void Style::polish( QWidget* widget ) |
|
{ |
|
if( !widget ) return; |
|
|
|
// register widget to animations |
|
_animations->registerWidget( widget ); |
|
_windowManager->registerWidget( widget ); |
|
|
|
// enable hover effects for all necessary widgets |
|
if( |
|
qobject_cast<QAbstractItemView*>( widget ) |
|
|| qobject_cast<QAbstractSpinBox*>( widget ) |
|
|| qobject_cast<QCheckBox*>( widget ) |
|
|| qobject_cast<QComboBox*>( widget ) |
|
|| qobject_cast<QDial*>( widget ) |
|
|| qobject_cast<QLineEdit*>( widget ) |
|
|| qobject_cast<QPushButton*>( widget ) |
|
|| qobject_cast<QRadioButton*>( widget ) |
|
|| qobject_cast<QScrollBar*>( widget ) |
|
|| qobject_cast<QSlider*>( widget ) |
|
|| qobject_cast<QSplitterHandle*>( widget ) |
|
|| qobject_cast<QTabBar*>( widget ) |
|
|| qobject_cast<QTextEdit*>( widget ) |
|
|| qobject_cast<QToolButton*>( widget ) |
|
) |
|
{ widget->setAttribute( Qt::WA_Hover ); } |
|
|
|
if( QAbstractItemView *itemView = qobject_cast<QAbstractItemView*>( widget ) ) |
|
{ |
|
|
|
// enable hover effects in itemviews' viewport |
|
itemView->viewport()->setAttribute( Qt::WA_Hover ); |
|
|
|
} else if( QAbstractScrollArea* scrollArea = qobject_cast<QAbstractScrollArea*>( widget ) ) { |
|
|
|
// enable hover effect in sunken scrollareas that support focus |
|
if( scrollArea->frameShadow() == QFrame::Sunken && widget->focusPolicy()&Qt::StrongFocus ) |
|
{ widget->setAttribute( Qt::WA_Hover ); } |
|
|
|
} else if( QGroupBox* groupBox = qobject_cast<QGroupBox*>( widget ) ) { |
|
|
|
// checkable group boxes |
|
if( groupBox->isCheckable() ) |
|
{ groupBox->setAttribute( Qt::WA_Hover ); } |
|
|
|
} else if( qobject_cast<QAbstractButton*>( widget ) && qobject_cast<QDockWidget*>( widget->parent() ) ) { |
|
|
|
widget->setAttribute( Qt::WA_Hover ); |
|
|
|
} else if( qobject_cast<QAbstractButton*>( widget ) && qobject_cast<QToolBox*>( widget->parent() ) ) { |
|
|
|
widget->setAttribute( Qt::WA_Hover ); |
|
|
|
} |
|
|
|
// remove opaque painting for scrollbars |
|
if( qobject_cast<QScrollBar*>( widget ) ) |
|
{ |
|
|
|
widget->setAttribute( Qt::WA_OpaquePaintEvent, false ); |
|
|
|
} |
|
|
|
// base class polishing |
|
KStyle::polish( widget ); |
|
|
|
} |
|
|
|
//_______________________________________________________________ |
|
void Style::unpolish( QWidget* widget ) |
|
{ |
|
|
|
// register widget to animations |
|
_windowManager->unregisterWidget( widget ); |
|
|
|
KStyle::unpolish( widget ); |
|
|
|
} |
|
|
|
//______________________________________________________________ |
|
int Style::pixelMetric( PixelMetric metric, const QStyleOption* option, const QWidget* widget ) const |
|
{ |
|
|
|
// handle special cases |
|
switch( metric ) |
|
{ |
|
|
|
// buttons |
|
case PM_ButtonMargin: return Metrics::Button_Margin; |
|
case PM_ButtonDefaultIndicator: return 0; |
|
case PM_ButtonShiftHorizontal: return 0; |
|
case PM_ButtonShiftVertical: return 0; |
|
|
|
// scrollbars |
|
case PM_ScrollBarExtent: return Metrics::ScrollBar_Extend; |
|
case PM_ScrollBarSliderMin: return Metrics::ScrollBar_MinSliderHeight; |
|
|
|
// sliders |
|
case PM_SliderThickness: return Metrics::Slider_ControlThickness; |
|
case PM_SliderControlThickness: return Metrics::Slider_ControlThickness; |
|
case PM_SliderLength: return Metrics::Slider_ControlThickness; |
|
|
|
// checkboxes and radio buttons |
|
case PM_IndicatorWidth: return CheckBox_Size; |
|
case PM_IndicatorHeight: return CheckBox_Size; |
|
case PM_ExclusiveIndicatorWidth: return RadioButton_Size; |
|
case PM_ExclusiveIndicatorHeight: return RadioButton_Size; |
|
|
|
// fallback |
|
default: return KStyle::pixelMetric( metric, option, widget ); |
|
|
|
} |
|
|
|
} |
|
|
|
//______________________________________________________________ |
|
int Style::styleHint( StyleHint hint, const QStyleOption* option, const QWidget* widget, QStyleHintReturn* returnData ) const |
|
{ |
|
switch( hint ) |
|
{ |
|
|
|
// groupbox |
|
case SH_GroupBox_TextLabelColor: |
|
if( option ) return option->palette.color( QPalette::WindowText ).rgba(); |
|
else return QPalette().color( QPalette::WindowText ).rgba(); |
|
|
|
case SH_GroupBox_TextLabelVerticalAlignment: return Qt::AlignVCenter; |
|
|
|
// scrollbar |
|
case SH_ScrollBar_MiddleClickAbsolutePosition: return true; |
|
|
|
// fallback |
|
default: return KStyle::styleHint( hint, option, widget, returnData ); |
|
|
|
} |
|
|
|
} |
|
|
|
//______________________________________________________________ |
|
QRect Style::subElementRect( SubElement element, const QStyleOption* option, const QWidget* widget ) const |
|
{ |
|
switch( element ) |
|
{ |
|
|
|
// checkboxes |
|
case SE_CheckBoxContents: return checkBoxContentsRect( option, widget ); |
|
case SE_CheckBoxFocusRect: return checkBoxFocusRect( option, widget ); |
|
|
|
// radio buttons |
|
case SE_RadioButtonContents: return radioButtonContentsRect( option, widget ); |
|
case SE_RadioButtonFocusRect: return radioButtonFocusRect( option, widget ); |
|
|
|
// progress bars |
|
case SE_ProgressBarGroove: return progressBarGrooveRect( option, widget ); |
|
case SE_ProgressBarContents: return progressBarContentsRect( option, widget ); |
|
case SE_ProgressBarLabel: return progressBarLabelRect( option, widget ); |
|
|
|
// fallback |
|
default: return KStyle::subElementRect( element, option, widget ); |
|
|
|
} |
|
} |
|
|
|
//______________________________________________________________ |
|
QRect Style::subControlRect( ComplexControl element, const QStyleOptionComplex* option, SubControl subControl, const QWidget* widget ) const |
|
{ |
|
switch( element ) |
|
{ |
|
|
|
case CC_ScrollBar: return scrollBarSubControlRect( option, subControl, widget ); |
|
|
|
// fallback |
|
default: return KStyle::subControlRect( element, option, subControl, widget ); |
|
|
|
} |
|
|
|
} |
|
|
|
//______________________________________________________________ |
|
QSize Style::sizeFromContents( ContentsType element, const QStyleOption* option, const QSize& size, const QWidget* widget ) const |
|
{ |
|
|
|
switch( element ) |
|
{ |
|
|
|
// checkboxes and radio buttons |
|
case CT_CheckBox: return checkBoxSizeFromContents( option, size, widget ); |
|
case CT_RadioButton: return checkBoxSizeFromContents( option, size, widget ); |
|
|
|
// progress bar |
|
case CT_ProgressBar: return progressBarSizeFromContents( option, size, widget ); |
|
|
|
// fallback |
|
default: return KStyle::sizeFromContents( element, option, size, widget ); |
|
|
|
} |
|
|
|
} |
|
|
|
//______________________________________________________________ |
|
QStyle::SubControl Style::hitTestComplexControl( ComplexControl control, const QStyleOptionComplex* option, const QPoint& point, const QWidget* widget ) const |
|
{ |
|
switch( control ) |
|
{ |
|
case CC_ScrollBar: |
|
{ |
|
|
|
QRect groove = scrollBarSubControlRect( option, SC_ScrollBarGroove, widget ); |
|
if ( groove.contains( point ) ) |
|
{ |
|
//Must be either page up/page down, or just click on the slider. |
|
//Grab the slider to compare |
|
QRect slider = scrollBarSubControlRect( option, SC_ScrollBarSlider, widget ); |
|
|
|
if( slider.contains( point ) ) return SC_ScrollBarSlider; |
|
else if( preceeds( point, slider, option ) ) return SC_ScrollBarSubPage; |
|
else return SC_ScrollBarAddPage; |
|
|
|
} |
|
|
|
//This is one of the up/down buttons. First, decide which one it is. |
|
if( preceeds( point, groove, option ) ) |
|
{ |
|
|
|
if( _subLineButtons == DoubleButton ) |
|
{ |
|
QRect buttonRect = scrollBarInternalSubControlRect( option, SC_ScrollBarSubLine ); |
|
return scrollBarHitTest( buttonRect, point, option ); |
|
} else return SC_ScrollBarSubLine; |
|
|
|
} |
|
|
|
if( _addLineButtons == DoubleButton ) |
|
{ |
|
|
|
QRect buttonRect = scrollBarInternalSubControlRect( option, SC_ScrollBarAddLine ); |
|
return scrollBarHitTest( buttonRect, point, option ); |
|
|
|
} else return SC_ScrollBarAddLine; |
|
} |
|
|
|
// fallback |
|
default: return KStyle::hitTestComplexControl( control, option, point, widget ); |
|
|
|
} |
|
|
|
} |
|
|
|
//______________________________________________________________ |
|
void Style::drawPrimitive( PrimitiveElement element, const QStyleOption* option, QPainter* painter, const QWidget* widget ) const |
|
{ |
|
|
|
StylePrimitive fcn( nullptr ); |
|
switch( element ) |
|
{ |
|
|
|
// buttons |
|
case PE_PanelButtonCommand: fcn = &Style::drawPanelButtonCommandPrimitive; break; |
|
|
|
// checkboxes and radio buttons |
|
case PE_IndicatorCheckBox: fcn = &Style::drawIndicatorCheckBoxPrimitive; break; |
|
case PE_IndicatorRadioButton: fcn = &Style::drawIndicatorRadioButtonPrimitive; break; |
|
|
|
// focus |
|
case PE_FrameFocusRect: fcn = &Style::drawFrameFocusRectPrimitive; break; |
|
|
|
// fallback |
|
default: break; |
|
|
|
} |
|
|
|
painter->save(); |
|
|
|
// call function if implemented |
|
if( !( fcn && ( this->*fcn )( option, painter, widget ) ) ) |
|
{ KStyle::drawPrimitive( element, option, painter, widget ); } |
|
|
|
painter->restore(); |
|
|
|
} |
|
|
|
//______________________________________________________________ |
|
void Style::drawControl( ControlElement element, const QStyleOption* option, QPainter* painter, const QWidget* widget ) const |
|
{ |
|
|
|
StyleControl fcn( nullptr ); |
|
switch( element ) |
|
{ |
|
|
|
/* |
|
for CE_PushButtonBevel the only thing that is done is draw the PanelButtonCommand primitive |
|
since the prototypes are identical we register the second directly in the control map: fcn = without |
|
using an intermediate function |
|
*/ |
|
case CE_PushButtonBevel: fcn = &Style::drawPanelButtonCommandPrimitive; break; |
|
case CE_PushButtonLabel: fcn = &Style::drawPushButtonLabelControl; break; |
|
|
|
// progress bars |
|
case CE_ProgressBar: fcn = &Style::drawProgressBarControl; break; |
|
case CE_ProgressBarContents: fcn = &Style::drawProgressBarContentsControl; break; |
|
case CE_ProgressBarGroove: fcn = &Style::drawProgressBarGrooveControl; break; |
|
case CE_ProgressBarLabel: fcn = &Style::drawProgressBarLabelControl; break; |
|
|
|
// scrollbars |
|
case CE_ScrollBarSlider: fcn = &Style::drawScrollBarSliderControl; break; |
|
case CE_ScrollBarAddLine: fcn = &Style::drawScrollBarAddLineControl; break; |
|
case CE_ScrollBarAddPage: fcn = &Style::drawScrollBarAddPageControl; break; |
|
case CE_ScrollBarSubLine: fcn = &Style::drawScrollBarSubLineControl; break; |
|
case CE_ScrollBarSubPage: fcn = &Style::drawScrollBarSubPageControl; break; |
|
|
|
// fallback |
|
default: break; |
|
|
|
} |
|
|
|
painter->save(); |
|
|
|
// call function if implemented |
|
if( !( fcn && ( this->*fcn )( option, painter, widget ) ) ) |
|
{ KStyle::drawControl( element, option, painter, widget ); } |
|
|
|
painter->restore(); |
|
|
|
} |
|
|
|
//______________________________________________________________ |
|
void Style::drawComplexControl( ComplexControl element, const QStyleOptionComplex* option, QPainter* painter, const QWidget* widget ) const |
|
{ |
|
|
|
StyleComplexControl fcn( nullptr ); |
|
switch( element ) |
|
{ |
|
|
|
case CC_Slider: fcn = &Style::drawSliderComplexControl; break; |
|
|
|
// fallback |
|
default: break; |
|
|
|
} |
|
|
|
|
|
painter->save(); |
|
|
|
// call function if implemented |
|
if( !( fcn && ( this->*fcn )( option, painter, widget ) ) ) |
|
{ KStyle::drawComplexControl( element, option, painter, widget ); } |
|
|
|
painter->restore(); |
|
|
|
|
|
} |
|
|
|
|
|
//___________________________________________________________________________________ |
|
void Style::drawItemText( |
|
QPainter* painter, const QRect& r, int flags, const QPalette& palette, bool enabled, |
|
const QString &text, QPalette::ColorRole textRole ) const |
|
{ |
|
|
|
// hide mnemonics if requested |
|
if( !_mnemonics->enabled() && ( flags & Qt::TextShowMnemonic ) && !( flags&Qt::TextHideMnemonic ) ) |
|
{ |
|
flags &= ~Qt::TextShowMnemonic; |
|
flags |= Qt::TextHideMnemonic; |
|
} |
|
|
|
if( _animations->widgetEnabilityEngine().enabled() ) |
|
{ |
|
|
|
/* |
|
check if painter engine is registered to WidgetEnabilityEngine, and animated |
|
if yes, merge the palettes. Note: a static_cast is safe here, since only the address |
|
of the pointer is used, not the actual content. |
|
*/ |
|
const QWidget* widget( static_cast<const QWidget*>( painter->device() ) ); |
|
if( _animations->widgetEnabilityEngine().isAnimated( widget, AnimationEnable ) ) |
|
{ |
|
|
|
const QPalette pal = _helper->mergePalettes( palette, _animations->widgetEnabilityEngine().opacity( widget, AnimationEnable ) ); |
|
return KStyle::drawItemText( painter, r, flags, pal, enabled, text, textRole ); |
|
|
|
} |
|
|
|
} |
|
|
|
// fallback |
|
return KStyle::drawItemText( painter, r, flags, palette, enabled, text, textRole ); |
|
|
|
} |
|
|
|
|
|
//_____________________________________________________________________ |
|
bool Style::eventFilter( QObject *object, QEvent *event ) |
|
{ |
|
// fallback |
|
return KStyle::eventFilter( object, event ); |
|
} |
|
|
|
//_____________________________________________________________________ |
|
void Style::configurationChanged() |
|
{ |
|
// reparse breezerc |
|
StyleConfigData::self()->readConfig(); |
|
|
|
// reload configuration |
|
loadConfiguration(); |
|
} |
|
|
|
//_____________________________________________________________________ |
|
void Style::loadConfiguration() |
|
{ |
|
|
|
// load helper configuration |
|
_helper->loadConfig(); |
|
|
|
// update caches size |
|
const int cacheSize( StyleConfigData::cacheEnabled() ? StyleConfigData::maxCacheSize():0 ); |
|
_helper->setMaxCacheSize( cacheSize ); |
|
|
|
// reinitialize engines |
|
_animations->setupEngines(); |
|
_windowManager->initialize(); |
|
|
|
// mnemonics |
|
_mnemonics->setMode( StyleConfigData::mnemonicsMode() ); |
|
} |
|
|
|
//___________________________________________________________________________________________________________________ |
|
QRect Style::checkBoxFocusRect( const QStyleOption* option, const QWidget* widget ) const |
|
{ |
|
|
|
Q_UNUSED( widget ); |
|
|
|
// cast option |
|
const QStyleOptionButton* buttonOption( qstyleoption_cast<const QStyleOptionButton*>( option ) ); |
|
if( !buttonOption ) return option->rect; |
|
|
|
// calculate text rect |
|
const QRect contentsRect( option->rect.adjusted( Metrics::CheckBox_Size + Metrics::CheckBox_BoxTextSpace, 0, 0, 0 ) ); |
|
const QRect boundingRect( option->fontMetrics.boundingRect( contentsRect, Qt::AlignLeft|Qt::AlignVCenter|Qt::TextHideMnemonic, buttonOption->text ) ); |
|
return handleRTL( option, boundingRect ); |
|
|
|
} |
|
|
|
//___________________________________________________________________________________________________________________ |
|
QRect Style::progressBarGrooveRect( const QStyleOption* option, const QWidget* ) const |
|
{ |
|
|
|
// cast option |
|
const QStyleOptionProgressBar* progressBarOption = qstyleoption_cast<const QStyleOptionProgressBar*>( option ); |
|
if( !progressBarOption ) return option->rect; |
|
|
|
// get direction |
|
const State& flags( option->state ); |
|
const bool horizontal( flags&State_Horizontal ); |
|
|
|
QRect rect( option->rect ); |
|
if( progressBarOption->textVisible ) |
|
{ |
|
if( horizontal ) rect.setTop( rect.height() - Metrics::ProgressBar_Thickness ); |
|
else { |
|
|
|
const bool reverseLayout( option->direction == Qt::RightToLeft ); |
|
if( reverseLayout ) rect.setLeft( rect.width() - Metrics::ProgressBar_Thickness ); |
|
else rect.setWidth( Metrics::ProgressBar_Thickness ); |
|
|
|
} |
|
|
|
} else { |
|
|
|
// center everything, if text is hidden |
|
if( horizontal ) return centerRect( rect, rect.width(), Metrics::ProgressBar_Thickness ); |
|
else return centerRect( rect, Metrics::ProgressBar_Thickness, rect.height() ); |
|
|
|
} |
|
return rect; |
|
} |
|
|
|
//___________________________________________________________________________________________________________________ |
|
QRect Style::progressBarContentsRect( const QStyleOption* option, const QWidget* widget ) const |
|
{ return progressBarGrooveRect( option, widget ); } |
|
|
|
//___________________________________________________________________________________________________________________ |
|
QRect Style::progressBarLabelRect( const QStyleOption* option, const QWidget* widget ) const |
|
{ |
|
|
|
Q_UNUSED( widget ); |
|
|
|
// cast option |
|
const QStyleOptionProgressBar* progressBarOption = qstyleoption_cast<const QStyleOptionProgressBar*>( option ); |
|
if( !( progressBarOption && progressBarOption->textVisible ) ) return QRect(); |
|
|
|
// get direction |
|
const State& flags( option->state ); |
|
const bool horizontal( flags&State_Horizontal ); |
|
|
|
QRect rect( option->rect ); |
|
if( horizontal ) rect.setHeight( rect.height() - Metrics::ProgressBar_Thickness - Metrics::ProgressBar_BoxTextSpace ); |
|
else { |
|
|
|
const bool reverseLayout( option->direction == Qt::RightToLeft ); |
|
if( reverseLayout ) rect.setWidth( rect.width() - Metrics::ProgressBar_Thickness - Metrics::ProgressBar_BoxTextSpace ); |
|
else rect.setLeft( Metrics::ProgressBar_Thickness + Metrics::ProgressBar_BoxTextSpace ); |
|
|
|
} |
|
|
|
return rect; |
|
|
|
} |
|
|
|
//___________________________________________________________________________________________________________________ |
|
QRect Style::scrollBarInternalSubControlRect( const QStyleOptionComplex* option, SubControl subControl ) const |
|
{ |
|
|
|
const QRect& r = option->rect; |
|
const State& flags( option->state ); |
|
const bool horizontal( flags&State_Horizontal ); |
|
|
|
switch ( subControl ) |
|
{ |
|
|
|
case SC_ScrollBarSubLine: |
|
{ |
|
int majorSize( scrollBarButtonHeight( _subLineButtons ) ); |
|
if( horizontal ) return handleRTL( option, QRect( r.x(), r.y(), majorSize, r.height() ) ); |
|
else return handleRTL( option, QRect( r.x(), r.y(), r.width(), majorSize ) ); |
|
|
|
} |
|
|
|
case SC_ScrollBarAddLine: |
|
{ |
|
int majorSize( scrollBarButtonHeight( _addLineButtons ) ); |
|
if( horizontal ) return handleRTL( option, QRect( r.right() - majorSize, r.y(), majorSize, r.height() ) ); |
|
else return handleRTL( option, QRect( r.x(), r.bottom() - majorSize, r.width(), majorSize ) ); |
|
} |
|
|
|
default: return QRect(); |
|
|
|
} |
|
} |
|
|
|
//___________________________________________________________________________________________________________________ |
|
QRect Style::scrollBarSubControlRect( const QStyleOptionComplex* option, SubControl subControl, const QWidget* widget ) const |
|
{ |
|
const State& flags( option->state ); |
|
const bool horizontal( flags&State_Horizontal ); |
|
|
|
switch ( subControl ) |
|
{ |
|
|
|
case SC_ScrollBarSubLine: |
|
case SC_ScrollBarAddLine: |
|
return scrollBarInternalSubControlRect( option, subControl ); |
|
|
|
//The main groove area. This is used to compute the others... |
|
case SC_ScrollBarGroove: |
|
{ |
|
QRect top = handleRTL( option, scrollBarInternalSubControlRect( option, SC_ScrollBarSubLine ) ); |
|
QRect bot = handleRTL( option, scrollBarInternalSubControlRect( option, SC_ScrollBarAddLine ) ); |
|
|
|
QPoint topLeftCorner; |
|
QPoint botRightCorner; |
|
|
|
if( horizontal ) |
|
{ |
|
|
|
topLeftCorner = QPoint( top.right() + 1, top.top() ); |
|
botRightCorner = QPoint( bot.left() - 1, top.bottom() ); |
|
|
|
} else { |
|
|
|
topLeftCorner = QPoint( top.left(), top.bottom() + 1 ); |
|
botRightCorner = QPoint( top.right(), bot.top() - 1 ); |
|
|
|
} |
|
|
|
// define rect |
|
return handleRTL( option, QRect( topLeftCorner, botRightCorner ) ); |
|
|
|
} |
|
|
|
case SC_ScrollBarSlider: |
|
{ |
|
const QStyleOptionSlider* sliderOption( qstyleoption_cast<const QStyleOptionSlider*>( option ) ); |
|
if( !sliderOption ) return QRect(); |
|
|
|
//We do handleRTL here to unreflect things if need be |
|
QRect groove = handleRTL( option, scrollBarSubControlRect( option, SC_ScrollBarGroove, widget ) ); |
|
|
|
if ( sliderOption->minimum == sliderOption->maximum ) return groove; |
|
|
|
//Figure out how much room we have.. |
|
int space( horizontal ? groove.width() : groove.height() ); |
|
|
|
//Calculate the portion of this space that the slider should take up. |
|
int sliderSize = space * qreal( sliderOption->pageStep ) / ( sliderOption->maximum - sliderOption->minimum + sliderOption->pageStep ); |
|
sliderSize = qMax( sliderSize, static_cast<int>(Metrics::ScrollBar_MinSliderHeight ) ); |
|
sliderSize = qMin( sliderSize, space ); |
|
|
|
space -= sliderSize; |
|
if( space <= 0 ) return groove; |
|
|
|
int pos = qRound( qreal( sliderOption->sliderPosition - sliderOption->minimum )/ ( sliderOption->maximum - sliderOption->minimum )*space ); |
|
if( sliderOption->upsideDown ) pos = space - pos; |
|
if( horizontal ) return handleRTL( option, QRect( groove.x() + pos, groove.y(), sliderSize, groove.height() ) ); |
|
else return handleRTL( option, QRect( groove.x(), groove.y() + pos, groove.width(), sliderSize ) ); |
|
} |
|
|
|
case SC_ScrollBarSubPage: |
|
{ |
|
|
|
//We do handleRTL here to unreflect things if need be |
|
QRect slider = handleRTL( option, scrollBarSubControlRect( option, SC_ScrollBarSlider, widget ) ); |
|
QRect groove = handleRTL( option, scrollBarSubControlRect( option, SC_ScrollBarGroove, widget ) ); |
|
|
|
if( horizontal ) return handleRTL( option, QRect( groove.x(), groove.y(), slider.x() - groove.x(), groove.height() ) ); |
|
else return handleRTL( option, QRect( groove.x(), groove.y(), groove.width(), slider.y() - groove.y() ) ); |
|
} |
|
|
|
case SC_ScrollBarAddPage: |
|
{ |
|
|
|
//We do handleRTL here to unreflect things if need be |
|
QRect slider = handleRTL( option, scrollBarSubControlRect( option, SC_ScrollBarSlider, widget ) ); |
|
QRect groove = handleRTL( option, scrollBarSubControlRect( option, SC_ScrollBarGroove, widget ) ); |
|
|
|
if( horizontal ) return handleRTL( option, QRect( slider.right() + 1, groove.y(), groove.right() - slider.right(), groove.height() ) ); |
|
else return handleRTL( option, QRect( groove.x(), slider.bottom() + 1, groove.width(), groove.bottom() - slider.bottom() ) ); |
|
|
|
} |
|
|
|
default: return QRect(); |
|
} |
|
} |
|
|
|
|
|
//______________________________________________________________ |
|
QSize Style::checkBoxSizeFromContents( const QStyleOption*, const QSize& contentsSize, const QWidget* ) const |
|
{ |
|
|
|
//Make sure we can fit the indicator |
|
QSize size( contentsSize ); |
|
size.setHeight( qMax( size.height(), (int) Metrics::CheckBox_Size ) ); |
|
|
|
//Add space for the indicator and the icon |
|
size.rwidth() += Metrics::CheckBox_Size + Metrics::CheckBox_BoxTextSpace; |
|
|
|
return size; |
|
|
|
} |
|
|
|
//______________________________________________________________ |
|
QSize Style::progressBarSizeFromContents( const QStyleOption* option, const QSize& contentsSize, const QWidget* ) const |
|
{ |
|
|
|
// cast option |
|
const QStyleOptionProgressBar* progressBarOption = qstyleoption_cast<const QStyleOptionProgressBar*>( option ); |
|
if( !progressBarOption ) return contentsSize; |
|
|
|
const bool textVisible( progressBarOption->textVisible ); |
|
|
|
// make local copy |
|
QSize size( contentsSize ); |
|
|
|
// get direction |
|
const State& flags( option->state ); |
|
const bool horizontal( flags&State_Horizontal ); |
|
|
|
if( horizontal ) { |
|
|
|
size.setWidth( qMax( size.width(), (int) Metrics::ProgressBar_Thickness ) ); |
|
if( textVisible ) size.rheight() += Metrics::ProgressBar_Thickness + Metrics::ProgressBar_BoxTextSpace; |
|
else size.setHeight( Metrics::ProgressBar_Thickness ); |
|
|
|
} else { |
|
|
|
size.setHeight( qMax( size.height(), (int) Metrics::ProgressBar_Thickness ) ); |
|
if( textVisible ) size.rwidth() += Metrics::ProgressBar_Thickness + Metrics::ProgressBar_BoxTextSpace; |
|
else size.setWidth( Metrics::ProgressBar_Thickness ); |
|
|
|
} |
|
|
|
return size; |
|
|
|
} |
|
|
|
//___________________________________________________________________________________ |
|
bool Style::drawFrameFocusRectPrimitive( const QStyleOption* option, QPainter* painter, const QWidget* widget ) const |
|
{ |
|
|
|
// checkboxes and radio buttons |
|
if( |
|
qobject_cast<const QCheckBox*>( widget ) || |
|
qobject_cast<const QRadioButton*>( widget ) ) |
|
{ |
|
painter->translate( 0, 2 ); |
|
painter->setPen( _helper->viewFocusBrush().brush( option->palette.currentColorGroup() ).color() ); |
|
painter->drawLine( option->rect.bottomLeft(), option->rect.bottomRight() ); |
|
} |
|
|
|
return true; |
|
|
|
} |
|
|
|
//______________________________________________________________ |
|
bool Style::drawPanelButtonCommandPrimitive( const QStyleOption* option, QPainter* painter, const QWidget* widget ) const |
|
{ |
|
|
|
Q_UNUSED( widget ); |
|
|
|
const State& flags( option->state ); |
|
const bool enabled( flags & State_Enabled ); |
|
const bool mouseOver( enabled && ( flags & State_MouseOver ) ); |
|
const bool hasFocus( enabled && ( flags & State_HasFocus ) ); |
|
const bool sunken( flags & ( State_On|State_Sunken ) ); |
|
const QPalette& palette( option->palette ); |
|
|
|
// update animation state |
|
// hover takes precedence over focus |
|
_animations->widgetStateEngine().updateState( widget, AnimationHover, mouseOver ); |
|
_animations->widgetStateEngine().updateState( widget, AnimationFocus, hasFocus && !mouseOver ); |
|
|
|
// store animation state |
|
const bool hoverAnimated( _animations->widgetStateEngine().isAnimated( widget, AnimationHover ) ); |
|
const bool focusAnimated( _animations->widgetStateEngine().isAnimated( widget, AnimationFocus ) ); |
|
const qreal hoverOpacity( _animations->widgetStateEngine().opacity( widget, AnimationHover ) ); |
|
const qreal focusOpacity( _animations->widgetStateEngine().opacity( widget, AnimationFocus ) ); |
|
|
|
QColor color; |
|
QColor outline; |
|
const QColor shadow( _helper->alphaColor( palette.color( QPalette::Shadow ), 0.2 ) ); |
|
|
|
const QColor normal( palette.color( QPalette::Window ) ); |
|
const QColor focus( _helper->viewFocusBrush().brush( option->palette.currentColorGroup() ).color() ); |
|
const QColor hover( _helper->viewHoverBrush().brush( option->palette.currentColorGroup() ).color() ); |
|
const QColor defaultOutline( KColorUtils::mix( palette.color( QPalette::Button ), palette.color( QPalette::ButtonText ), 0.4 ) ); |
|
|
|
// colors |
|
if( hoverAnimated ) { |
|
|
|
if( hasFocus ) |
|
{ |
|
|
|
color = KColorUtils::mix( focus, hover, hoverOpacity ); |
|
outline = QColor(); |
|
|
|
} else { |
|
|
|
color = KColorUtils::mix( normal, hover, hoverOpacity ); |
|
outline = _helper->alphaColor( defaultOutline, 1-hoverOpacity ); |
|
|
|
} |
|
|
|
} else if( mouseOver ) { |
|
|
|
color = _helper->viewHoverBrush().brush( option->palette.currentColorGroup() ).color(); |
|
outline = QColor(); |
|
|
|
} else if( focusAnimated ) { |
|
|
|
color = KColorUtils::mix( normal, focus, focusOpacity ); |
|
outline = _helper->alphaColor( defaultOutline, 1-focusOpacity ); |
|
|
|
} else if( hasFocus ) { |
|
|
|
color = focus; |
|
outline = QColor(); |
|
|
|
} else { |
|
|
|
color = normal; |
|
outline = defaultOutline; |
|
|
|
} |
|
|
|
renderButtonSlab( painter, option->rect, color, outline, shadow, hasFocus, sunken ); |
|
|
|
return true; |
|
|
|
} |
|
|
|
//___________________________________________________________________________________ |
|
bool Style::drawIndicatorCheckBoxPrimitive( const QStyleOption* option, QPainter* painter, const QWidget* widget ) const |
|
{ |
|
|
|
Q_UNUSED( widget ); |
|
|
|
// get rect |
|
const State& flags( option->state ); |
|
const bool enabled( flags & State_Enabled ); |
|
const bool mouseOver( enabled && ( flags & State_MouseOver ) ); |
|
const bool sunken( flags & State_Sunken ); |
|
|
|
CheckBoxState state( CheckOff ); |
|
if( flags & State_NoChange ) state = CheckPartial; |
|
else if( flags & State_On ) state = CheckOn; |
|
|
|
// color |
|
const QPalette& palette( option->palette ); |
|
const QColor base( palette.color( QPalette::Window ) ); |
|
const QColor disabled( KColorUtils::mix( base, palette.color( QPalette::WindowText ), 0.4 ) ); |
|
const QColor normal( KColorUtils::mix( base, palette.color( QPalette::WindowText ), 0.5 ) ); |
|
const QColor active( _helper->viewFocusBrush().brush( palette.currentColorGroup() ).color() ); |
|
const QColor hover( _helper->viewHoverBrush().brush( palette.currentColorGroup() ).color() ); |
|
QColor color; |
|
|
|
// mouseOver has precedence over focus |
|
_animations->widgetStateEngine().updateState( widget, AnimationHover, mouseOver ); |
|
|
|
// cannot use transparent colors because of the rendering of the shadow |
|
if( !enabled ) color = disabled; |
|
else if( _animations->widgetStateEngine().isAnimated( widget, AnimationHover ) ) |
|
{ |
|
|
|
const qreal opacity( _animations->widgetStateEngine().opacity( widget, AnimationHover ) ); |
|
if( state != CheckOff ) color = KColorUtils::mix( active, hover, opacity ); |
|
else color = KColorUtils::mix( normal, hover, opacity ); |
|
|
|
} else if( mouseOver ) color = hover; |
|
else if( state != CheckOff ) color = active; |
|
else color = normal; |
|
|
|
// shadow color |
|
const QColor shadow( _helper->alphaColor( palette.color( QPalette::Shadow ), 0.2 ) ); |
|
|
|
// render |
|
renderCheckBox( painter, option->rect, color, shadow, sunken, state ); |
|
|
|
return true; |
|
|
|
} |
|
|
|
//___________________________________________________________________________________ |
|
bool Style::drawIndicatorRadioButtonPrimitive( const QStyleOption* option, QPainter* painter, const QWidget* widget ) const |
|
{ |
|
|
|
Q_UNUSED( widget ); |
|
|
|
// get rect |
|
const State& flags( option->state ); |
|
const bool enabled( flags & State_Enabled ); |
|
const bool mouseOver( enabled && ( flags & State_MouseOver ) ); |
|
const bool sunken( flags & State_Sunken ); |
|
const bool checked( flags & State_On ); |
|
|
|
// color |
|
const QPalette& palette( option->palette ); |
|
const QColor base( palette.color( QPalette::Window ) ); |
|
const QColor disabled( KColorUtils::mix( base, palette.color( QPalette::WindowText ), 0.4 ) ); |
|
const QColor normal( KColorUtils::mix( base, palette.color( QPalette::WindowText ), 0.5 ) ); |
|
const QColor active( _helper->viewFocusBrush().brush( palette.currentColorGroup() ).color() ); |
|
const QColor hover( _helper->viewHoverBrush().brush( palette.currentColorGroup() ).color() ); |
|
QColor color; |
|
|
|
// mouseOver has precedence over focus |
|
_animations->widgetStateEngine().updateState( widget, AnimationHover, mouseOver ); |
|
|
|
// cannot use transparent colors because of the rendering of the shadow |
|
if( !enabled ) color = disabled; |
|
else if( _animations->widgetStateEngine().isAnimated( widget, AnimationHover ) ) |
|
{ |
|
|
|
const qreal opacity( _animations->widgetStateEngine().opacity( widget, AnimationHover ) ); |
|
if( checked ) color = KColorUtils::mix( active, hover, opacity ); |
|
else color = KColorUtils::mix( normal, hover, opacity ); |
|
|
|
} else if( mouseOver ) color = hover; |
|
else if( checked ) color = active; |
|
else color = normal; |
|
|
|
// shadow color |
|
const QColor shadow( _helper->alphaColor( palette.color( QPalette::Shadow ), 0.2 ) ); |
|
|
|
// render |
|
renderRadioButton( painter, option->rect, color, shadow, sunken, checked ); |
|
|
|
return true; |
|
|
|
} |
|
|
|
//___________________________________________________________________________________ |
|
bool Style::drawPushButtonLabelControl( const QStyleOption* option, QPainter* painter, const QWidget* widget ) const |
|
{ |
|
|
|
// need to alter palette for focused buttons |
|
const bool hasFocus( option->state & State_HasFocus ); |
|
const bool mouseOver( option->state & State_MouseOver ); |
|
if( hasFocus && !mouseOver ) |
|
{ |
|
|
|
const QStyleOptionButton* buttonOption = qstyleoption_cast<const QStyleOptionButton*>( option ); |
|
if ( !buttonOption ) return false; |
|
|
|
QStyleOptionButton copy( *buttonOption ); |
|
copy.palette.setColor( QPalette::ButtonText, copy.palette.color( QPalette::HighlightedText ) ); |
|
|
|
// call base class, with modified option |
|
KStyle::drawControl( CE_PushButtonLabel, ©, painter, widget ); |
|
return true; |
|
|
|
} else return false; |
|
|
|
} |
|
|
|
|
|
//___________________________________________________________________________________ |
|
bool Style::drawProgressBarControl( const QStyleOption* option, QPainter* painter, const QWidget* widget ) const |
|
{ |
|
|
|
const QStyleOptionProgressBar* progressBarOption = qstyleoption_cast<const QStyleOptionProgressBar*>( option ); |
|
if( !progressBarOption ) return true; |
|
|
|
// render groove |
|
QStyleOptionProgressBarV2 progressBarOption2 = *progressBarOption; |
|
progressBarOption2.rect = subElementRect( SE_ProgressBarGroove, progressBarOption, widget ); |
|
drawProgressBarGrooveControl( &progressBarOption2, painter, widget ); |
|
|
|
// render contents |
|
progressBarOption2.rect = subElementRect( SE_ProgressBarContents, progressBarOption, widget ); |
|
drawProgressBarContentsControl( &progressBarOption2, painter, widget ); |
|
|
|
// render text |
|
if( progressBarOption->textVisible ) |
|
{ |
|
progressBarOption2.rect = subElementRect( SE_ProgressBarLabel, progressBarOption, widget ); |
|
drawProgressBarLabelControl( &progressBarOption2, painter, widget ); |
|
} |
|
|
|
|
|
return true; |
|
|
|
} |
|
|
|
//___________________________________________________________________________________ |
|
bool Style::drawProgressBarContentsControl( const QStyleOption* option, QPainter* painter, const QWidget* widget ) const |
|
{ |
|
|
|
Q_UNUSED( widget ); |
|
|
|
const QStyleOptionProgressBar* progressBarOption = qstyleoption_cast<const QStyleOptionProgressBar*>( option ); |
|
if( !progressBarOption ) return true; |
|
|
|
const QStyleOptionProgressBarV2* progressBarOption2 = qstyleoption_cast<const QStyleOptionProgressBarV2*>( option ); |
|
|
|
const QRect& r( option->rect ); |
|
const QPalette& palette( option->palette ); |
|
|
|
// check if anything is to be drawn |
|
qreal progress = progressBarOption->progress - progressBarOption->minimum; |
|
if( !progress ) return true; |
|
|
|
const int steps = qMax( progressBarOption->maximum - progressBarOption->minimum, 1 ); |
|
const bool horizontal = !progressBarOption2 || progressBarOption2->orientation == Qt::Horizontal; |
|
|
|
//Calculate width fraction |
|
qreal widthFrac( progress/steps ); |
|
widthFrac = qMin( (qreal)1.0, widthFrac ); |
|
|
|
// convert the pixel width |
|
const int indicatorSize( widthFrac*( horizontal ? r.width():r.height() ) ); |
|
|
|
// do nothing if indicator size is too small |
|
if( indicatorSize < Metrics::ProgressBar_Thickness ) return true; |
|
|
|
QRect indicatorRect; |
|
{ |
|
if ( horizontal ) indicatorRect = QRect( r.x(), r.y(), indicatorSize, r.height() ); |
|
else indicatorRect = QRect( r.x(), r.bottom()- indicatorSize + 1, r.width(), indicatorSize ); |
|
|
|
} |
|
|
|
// handle right to left |
|
indicatorRect = handleRTL( option, indicatorRect ); |
|
|
|
renderProgressBarContents( painter, indicatorRect, palette.color( QPalette::Highlight ) ); |
|
|
|
return true; |
|
|
|
} |
|
|
|
//___________________________________________________________________________________ |
|
bool Style::drawProgressBarGrooveControl( const QStyleOption* option, QPainter* painter, const QWidget* ) const |
|
{ |
|
const QPalette& palette( option->palette ); |
|
const QColor color( _helper->alphaColor( palette.color( QPalette::WindowText ), 0.3 ) ); |
|
renderProgressBarHole( painter, option->rect, color ); |
|
return true; |
|
} |
|
|
|
//___________________________________________________________________________________ |
|
bool Style::drawProgressBarLabelControl( const QStyleOption* option, QPainter* painter, const QWidget* ) const |
|
{ |
|
const QStyleOptionProgressBar* progressBarOption = qstyleoption_cast<const QStyleOptionProgressBar*>( option ); |
|
if( !progressBarOption ) return true; |
|
|
|
const QRect& r( option->rect ); |
|
const QPalette& palette( option->palette ); |
|
const State& flags( option->state ); |
|
const bool enabled( flags&State_Enabled ); |
|
|
|
const QStyleOptionProgressBarV2* progressBarOption2 = qstyleoption_cast<const QStyleOptionProgressBarV2*>( option ); |
|
const bool horizontal = !progressBarOption2 || progressBarOption2->orientation == Qt::Horizontal; |
|
const bool reverseLayout = ( option->direction == Qt::RightToLeft ); |
|
|
|
// rotate label for vertical layout |
|
if( ! ( horizontal || reverseLayout ) ) |
|
{ |
|
|
|
painter->translate( r.topRight() ); |
|
painter->rotate( 90.0 ); |
|
|
|
} else if( !horizontal ) { |
|
|
|
painter->translate( r.bottomLeft() ); |
|
painter->rotate( -90.0 ); |
|
|
|
} |
|
|
|
// define text rect |
|
const QRect textRect( horizontal? r : QRect( 0, 0, r.height(), r.width() ) ); |
|
Qt::Alignment hAlign( ( progressBarOption->textAlignment == Qt::AlignLeft ) ? Qt::AlignHCenter : progressBarOption->textAlignment ); |
|
drawItemText( painter, textRect, Qt::AlignVCenter | hAlign, palette, enabled, progressBarOption->text, QPalette::WindowText ); |
|
|
|
return true; |
|
|
|
} |
|
|
|
//___________________________________________________________________________________ |
|
bool Style::drawScrollBarSliderControl( const QStyleOption* option, QPainter* painter, const QWidget* widget ) const |
|
{ |
|
|
|
Q_UNUSED( widget ); |
|
|
|
// cast option and check |
|
const QStyleOptionSlider *sliderOption = qstyleoption_cast<const QStyleOptionSlider *>( option ); |
|
if( !sliderOption ) return true; |
|
|
|
painter->setClipRect( option->rect ); |
|
|
|
// define handle rect |
|
QRect handleRect; |
|
const State& flags( option->state ); |
|
const bool horizontal( flags & State_Horizontal ); |
|
if( horizontal ) handleRect = centerRect( option->rect, option->rect.width(), Metrics::ScrollBar_SliderWidth ); |
|
else handleRect = centerRect( option->rect, Metrics::ScrollBar_SliderWidth, option->rect.height() ); |
|
|
|
const bool enabled( flags&State_Enabled ); |
|
const bool mouseOver( enabled && ( flags&State_MouseOver ) ); |
|
|
|
QWidget* parent( scrollBarParent( widget ) ); |
|
const bool focus( enabled && parent && parent->hasFocus() ); |
|
|
|
// enable animation state |
|
_animations->scrollBarEngine().updateState( widget, enabled && ( sliderOption->activeSubControls & SC_ScrollBarSlider ) ); |
|
const qreal opacity( _animations->scrollBarEngine().opacity( widget, SC_ScrollBarSlider ) ); |
|
if( widget ) |
|
{ |
|
// render background |
|
// it is necessary to retrive the complete widget rect, in order to properly handle overlaps |
|
// at the scrollbar boundary |
|
// define color |
|
const QPalette& palette( option->palette ); |
|
const QColor color( _helper->alphaColor( palette.color( QPalette::WindowText ), 0.3 ) ); |
|
|
|
// adjust rect |
|
QStyleOptionSlider copy( *sliderOption ); |
|
copy.rect = widget->rect(); |
|
QRect backgroundRect( scrollBarSubControlRect( ©, SC_ScrollBarGroove, widget ) ); |
|
if( horizontal ) backgroundRect = centerRect( backgroundRect, backgroundRect.width(), Metrics::ScrollBar_SliderWidth ); |
|
else backgroundRect = centerRect( backgroundRect, Metrics::ScrollBar_SliderWidth, backgroundRect.height() ); |
|
|
|
renderScrollBarHole( painter, backgroundRect, color ); |
|
|
|
} |
|
|
|
{ |
|
// render handle |
|
// define colors |
|
QColor color; |
|
const QPalette& palette( option->palette ); |
|
|
|
const QColor base( focus ? |
|
_helper->viewFocusBrush().brush( palette.currentColorGroup() ).color(): |
|
_helper->alphaColor( palette.color( QPalette::WindowText ), 0.5 ) ); |
|
|
|
const QColor highlight( _helper->viewHoverBrush().brush( palette.currentColorGroup() ).color() ); |
|
if( opacity >= 0 ) color = KColorUtils::mix( base, highlight, opacity ); |
|
else if( mouseOver ) color = highlight; |
|
else color = base; |
|
|
|
// render |
|
renderScrollBarHandle( painter, handleRect, color, QColor() ); |
|
|
|
} |
|
|
|
return true; |
|
} |
|
|
|
//___________________________________________________________________________________ |
|
bool Style::drawScrollBarAddLineControl( const QStyleOption* option, QPainter* painter, const QWidget* widget ) const |
|
{ |
|
|
|
// do nothing if no buttons are defined |
|
if( _addLineButtons == NoButton ) return true; |
|
|
|
// cast option and check |
|
const QStyleOptionSlider* sliderOption( qstyleoption_cast<const QStyleOptionSlider*>( option ) ); |
|
if ( !sliderOption ) return true; |
|
|
|
const State& flags( option->state ); |
|
const bool horizontal( flags & State_Horizontal ); |
|
const bool reverseLayout( option->direction == Qt::RightToLeft ); |
|
|
|
// adjust rect, based on number of buttons to be drawn |
|
QRect r( scrollBarInternalSubControlRect( sliderOption, SC_ScrollBarAddLine ) ); |
|
|
|
QColor color; |
|
QStyleOptionSlider localOption( *sliderOption ); |
|
if( _addLineButtons == DoubleButton ) |
|
{ |
|
|
|
if( horizontal ) |
|
{ |
|
|
|
//Draw the arrows |
|
const QSize halfSize( r.width()/2, r.height() ); |
|
const QRect leftSubButton( r.topLeft(), halfSize ); |
|
const QRect rightSubButton( leftSubButton.topRight() + QPoint( 1, 0 ), halfSize ); |
|
|
|
localOption.rect = leftSubButton; |
|
color = scrollBarArrowColor( &localOption, reverseLayout ? SC_ScrollBarAddLine:SC_ScrollBarSubLine, widget ); |
|
renderScrollBarArrow( painter, leftSubButton, color, ArrowLeft ); |
|
|
|
localOption.rect = rightSubButton; |
|
color = scrollBarArrowColor( &localOption, reverseLayout ? SC_ScrollBarSubLine:SC_ScrollBarAddLine, widget ); |
|
renderScrollBarArrow( painter, rightSubButton, color, ArrowRight ); |
|
|
|
} else { |
|
|
|
const QSize halfSize( r.width(), r.height()/2 ); |
|
const QRect topSubButton( r.topLeft(), halfSize ); |
|
const QRect botSubButton( topSubButton.bottomLeft() + QPoint( 0, 1 ), halfSize ); |
|
|
|
localOption.rect = topSubButton; |
|
color = scrollBarArrowColor( &localOption, SC_ScrollBarSubLine, widget ); |
|
renderScrollBarArrow( painter, topSubButton, color, ArrowUp ); |
|
|
|
localOption.rect = botSubButton; |
|
color = scrollBarArrowColor( &localOption, SC_ScrollBarAddLine, widget ); |
|
renderScrollBarArrow( painter, botSubButton, color, ArrowDown ); |
|
|
|
} |
|
|
|
} else if( _addLineButtons == SingleButton ) { |
|
|
|
localOption.rect = r; |
|
color = scrollBarArrowColor( &localOption, SC_ScrollBarAddLine, widget ); |
|
if( horizontal ) |
|
{ |
|
|
|
if( reverseLayout ) renderScrollBarArrow( painter, r, color, ArrowLeft ); |
|
else renderScrollBarArrow( painter, r.translated( 1, 0 ), color, ArrowRight ); |
|
|
|
} else renderScrollBarArrow( painter, r.translated( 0, 1 ), color, ArrowDown ); |
|
|
|
} |
|
|
|
return true; |
|
} |
|
|
|
//___________________________________________________________________________________ |
|
bool Style::drawScrollBarAddPageControl( const QStyleOption* option, QPainter* painter, const QWidget* ) const |
|
{ |
|
|
|
// cast option and check |
|
const QStyleOptionSlider* sliderOption( qstyleoption_cast<const QStyleOptionSlider*>( option ) ); |
|
if ( !sliderOption ) return true; |
|
|
|
painter->setClipRect( option->rect ); |
|
|
|
const QPalette& palette( option->palette ); |
|
const QColor color( _helper->alphaColor( palette.color( QPalette::WindowText ), 0.3 ) ); |
|
const State& flags( option->state ); |
|
|
|
// define tiles and adjust rect |
|
QRect backgroundRect; |
|
const bool horizontal( flags & State_Horizontal ); |
|
const bool reverseLayout( sliderOption->direction == Qt::RightToLeft ); |
|
|
|
if( horizontal ) |
|
{ |
|
|
|
backgroundRect = centerRect( option->rect, option->rect.width(), Metrics::ScrollBar_SliderWidth ); |
|
if( reverseLayout ) backgroundRect.adjust( 0, 0, Metrics::ScrollBar_SliderWidth/2, 0 ); |
|
else backgroundRect.adjust( -Metrics::ScrollBar_SliderWidth/2, 0, 0, 0 ); |
|
|
|
|
|
} else { |
|
|
|
backgroundRect = centerRect( option->rect, Metrics::ScrollBar_SliderWidth, option->rect.height() ); |
|
backgroundRect.adjust( 0, -Metrics::ScrollBar_SliderWidth/2, 0, 0 ); |
|
|
|
} |
|
|
|
// render |
|
renderScrollBarHole( painter, backgroundRect, color ); |
|
|
|
return true; |
|
|
|
} |
|
|
|
//___________________________________________________________________________________ |
|
bool Style::drawScrollBarSubLineControl( const QStyleOption* option, QPainter* painter, const QWidget* widget ) const |
|
{ |
|
|
|
// do nothing if no buttons are set |
|
if( _subLineButtons == NoButton ) return true; |
|
|
|
// cast option and check |
|
const QStyleOptionSlider* sliderOption( qstyleoption_cast<const QStyleOptionSlider*>( option ) ); |
|
if ( !sliderOption ) return true; |
|
|
|
const State& flags( option->state ); |
|
const bool horizontal( flags & State_Horizontal ); |
|
const bool reverseLayout( option->direction == Qt::RightToLeft ); |
|
|
|
// colors |
|
const QPalette& palette( option->palette ); |
|
const QColor background( palette.color( QPalette::Window ) ); |
|
|
|
// adjust rect, based on number of buttons to be drawn |
|
QRect r( scrollBarInternalSubControlRect( sliderOption, SC_ScrollBarSubLine ) ); |
|
|
|
QColor color; |
|
QStyleOptionSlider localOption( *sliderOption ); |
|
if( _subLineButtons == DoubleButton ) |
|
{ |
|
|
|
if( horizontal ) |
|
{ |
|
|
|
//Draw the arrows |
|
const QSize halfSize( r.width()/2, r.height() ); |
|
const QRect leftSubButton( r.topLeft(), halfSize ); |
|
const QRect rightSubButton( leftSubButton.topRight() + QPoint( 1, 0 ), halfSize ); |
|
|
|
localOption.rect = leftSubButton; |
|
color = scrollBarArrowColor( &localOption, reverseLayout ? SC_ScrollBarAddLine:SC_ScrollBarSubLine, widget ); |
|
renderScrollBarArrow( painter, leftSubButton, color, ArrowLeft ); |
|
|
|
localOption.rect = rightSubButton; |
|
color = scrollBarArrowColor( &localOption, reverseLayout ? SC_ScrollBarSubLine:SC_ScrollBarAddLine, widget ); |
|
renderScrollBarArrow( painter, rightSubButton, color, ArrowRight ); |
|
|
|
} else { |
|
|
|
const QSize halfSize( r.width(), r.height()/2 ); |
|
const QRect topSubButton( r.topLeft(), halfSize ); |
|
const QRect botSubButton( topSubButton.bottomLeft() + QPoint( 0, 1 ), halfSize ); |
|
|
|
localOption.rect = topSubButton; |
|
color = scrollBarArrowColor( &localOption, SC_ScrollBarSubLine, widget ); |
|
renderScrollBarArrow( painter, topSubButton, color, ArrowUp ); |
|
|
|
localOption.rect = botSubButton; |
|
color = scrollBarArrowColor( &localOption, SC_ScrollBarAddLine, widget ); |
|
renderScrollBarArrow( painter, botSubButton, color, ArrowDown ); |
|
|
|
} |
|
|
|
} else if( _subLineButtons == SingleButton ) { |
|
|
|
localOption.rect = r; |
|
color = scrollBarArrowColor( &localOption, SC_ScrollBarSubLine, widget ); |
|
if( horizontal ) |
|
{ |
|
|
|
if( reverseLayout ) renderScrollBarArrow( painter, r.translated( 1, 0 ), color, ArrowRight ); |
|
else renderScrollBarArrow( painter, r, color, ArrowLeft ); |
|
|
|
} else renderScrollBarArrow( painter, r, color, ArrowUp ); |
|
|
|
} |
|
|
|
return true; |
|
} |
|
|
|
//___________________________________________________________________________________ |
|
bool Style::drawScrollBarSubPageControl( const QStyleOption* option, QPainter* painter, const QWidget* ) const |
|
{ |
|
|
|
// cast option and check |
|
const QStyleOptionSlider* sliderOption( qstyleoption_cast<const QStyleOptionSlider*>( option ) ); |
|
if ( !sliderOption ) return true; |
|
|
|
painter->setClipRect( option->rect ); |
|
|
|
const QPalette& palette( option->palette ); |
|
const QColor color( _helper->alphaColor( palette.color( QPalette::WindowText ), 0.3 ) ); |
|
const State& flags( option->state ); |
|
|
|
// define tiles and adjust rect |
|
QRect backgroundRect; |
|
const bool horizontal( flags & State_Horizontal ); |
|
const bool reverseLayout( sliderOption->direction == Qt::RightToLeft ); |
|
|
|
if( horizontal ) |
|
{ |
|
|
|
backgroundRect = centerRect( option->rect, option->rect.width(), Metrics::ScrollBar_SliderWidth ); |
|
if( reverseLayout ) backgroundRect.adjust( -Metrics::ScrollBar_SliderWidth/2, 0, 0, 0 ); |
|
else backgroundRect.adjust( 0, 0, Metrics::ScrollBar_SliderWidth/2-1, 0 ); |
|
|
|
} else { |
|
|
|
backgroundRect = centerRect( option->rect, Metrics::ScrollBar_SliderWidth, option->rect.height() ); |
|
backgroundRect.adjust( 0, 0, 0, Metrics::ScrollBar_SliderWidth/2-1 ); |
|
|
|
} |
|
|
|
// render |
|
renderScrollBarHole( painter, backgroundRect, color ); |
|
|
|
return true; |
|
|
|
} |
|
|
|
//______________________________________________________________ |
|
bool Style::drawSliderComplexControl( const QStyleOptionComplex* option, QPainter* painter, const QWidget* widget ) const |
|
{ |
|
|
|
const QStyleOptionSlider *sliderOption( qstyleoption_cast<const QStyleOptionSlider *>( option ) ); |
|
if( !sliderOption ) return true; |
|
|
|
const QPalette& palette( option->palette ); |
|
const State& flags( option->state ); |
|
const bool enabled( flags & State_Enabled ); |
|
const bool mouseOver( enabled && ( flags & State_MouseOver ) ); |
|
const bool hasFocus( enabled && ( flags & State_HasFocus ) ); |
|
|
|
// if( sliderOption->subControls & SC_SliderTickmarks ) { renderSliderTickmarks( painter, sliderOption, widget ); } |
|
|
|
// groove |
|
if( sliderOption->subControls & SC_SliderGroove ) |
|
{ |
|
// retrieve holeRect |
|
QRect holeRect( subControlRect( CC_Slider, sliderOption, SC_SliderGroove, widget ) ); |
|
|
|
// adjustments |
|
if( sliderOption->orientation == Qt::Horizontal ) |
|
{ |
|
|
|
holeRect = centerRect( holeRect, holeRect.width()-Metrics::Slider_Thickness, Metrics::Slider_Thickness ); |
|
|
|
} else { |
|
|
|
holeRect = centerRect( holeRect, Metrics::Slider_Thickness, holeRect.height()-Metrics::Slider_Thickness ); |
|
|
|
} |
|
|
|
// base color |
|
const QColor color( _helper->alphaColor( palette.color( QPalette::WindowText ), 0.3 ) ); |
|
|
|
if( !enabled ) renderSliderHole( painter, holeRect, color ); |
|
else { |
|
|
|
// retrieve slider rect |
|
QRect sliderRect( subControlRect( CC_Slider, sliderOption, SC_SliderHandle, widget ) ); |
|
sliderRect = centerRect( sliderRect, Metrics::Slider_ControlThickness, Metrics::Slider_ControlThickness ); |
|
|
|
// define highlight color |
|
const QColor highlight( palette.color( QPalette::Highlight ) ); |
|
|
|
if( sliderOption->orientation == Qt::Horizontal ) |
|
{ |
|
|
|
const bool reverseLayout( option->direction == Qt::RightToLeft ); |
|
|
|
QRect leftRect( holeRect ); |
|
leftRect.setRight( sliderRect.right()-1 ); |
|
renderSliderHole( painter, leftRect, reverseLayout ? color:highlight ); |
|
|
|
QRect rightRect( holeRect ); |
|
rightRect.setLeft( sliderRect.left()+1 ); |
|
renderSliderHole( painter, rightRect, reverseLayout ? highlight:color ); |
|
|
|
} else { |
|
|
|
QRect topRect( holeRect ); |
|
topRect.setBottom( sliderRect.bottom()-1 ); |
|
renderSliderHole( painter, topRect, highlight ); |
|
|
|
QRect bottomRect( holeRect ); |
|
bottomRect.setTop( sliderRect.top()+1 ); |
|
renderSliderHole( painter, bottomRect, color ); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
// handle |
|
if ( sliderOption->subControls & SC_SliderHandle ) |
|
{ |
|
|
|
// get rect and center |
|
QRect sliderRect( subControlRect( CC_Slider, sliderOption, SC_SliderHandle, widget ) ); |
|
sliderRect = centerRect( sliderRect, Metrics::Slider_ControlThickness, Metrics::Slider_ControlThickness ); |
|
|
|
const bool handleActive( sliderOption->activeSubControls & SC_SliderHandle ); |
|
|
|
// define colors |
|
const QColor color( palette.color( QPalette::Button ) ); |
|
const QColor shadow( _helper->alphaColor( palette.color( QPalette::Shadow ), 0.2 ) ); |
|
QColor outline; |
|
|
|
if( handleActive && mouseOver ) outline = _helper->viewHoverBrush().brush( option->palette.currentColorGroup() ).color(); |
|
else if( hasFocus ) outline = _helper->viewFocusBrush().brush( option->palette.currentColorGroup() ).color(); |
|
else outline = KColorUtils::mix( palette.color( QPalette::Button ), palette.color( QPalette::ButtonText ), 0.4 ); |
|
|
|
const bool sunken( flags & (State_On|State_Sunken) ); |
|
renderSliderHandle( painter, sliderRect, color, outline, shadow, hasFocus, sunken ); |
|
|
|
} |
|
|
|
return true; |
|
} |
|
|
|
//______________________________________________________________________________ |
|
void Style::renderButtonSlab( |
|
QPainter* painter, const QRect& r, |
|
const QColor& color, const QColor& outline, const QColor& shadow, |
|
bool focus, bool sunken ) const |
|
{ |
|
|
|
// setup painter |
|
painter->setRenderHint( QPainter::Antialiasing, true ); |
|
|
|
// copy rect |
|
QRectF baseRect( r ); |
|
|
|
// shadow |
|
if( !sunken ) |
|
{ |
|
painter->setPen( QPen( shadow, 2 ) ); |
|
painter->setBrush( Qt::NoBrush ); |
|
const QRectF shadowRect( baseRect.adjusted( 1.5, 1.5, -1.5, -1.5 ).translated( 0, 0.5 ) ); |
|
painter->drawRoundedRect( shadowRect, 2.5, 2.5 ); |
|
} |
|
|
|
// content |
|
{ |
|
|
|
painter->setPen( Qt::NoPen ); |
|
|
|
const QRectF contentRect( baseRect.adjusted( 1, 1, -1, -1 ) ); |
|
QLinearGradient gradient( contentRect.topLeft(), contentRect.bottomLeft() ); |
|
gradient.setColorAt( 0, color.lighter( focus ? 103:101 ) ); |
|
gradient.setColorAt( 1, color.darker( focus ? 110:103 ) ); |
|
painter->setBrush( gradient ); |
|
|
|
painter->drawRoundedRect( contentRect, 3, 3 ); |
|
|
|
} |
|
|
|
// outline |
|
if( outline.isValid() ) |
|
{ |
|
painter->setPen( QPen( outline, 1 ) ); |
|
painter->setBrush( Qt::NoBrush ); |
|
const QRectF outlineRect( baseRect.adjusted( 1.5, 1.5, -1.5, -1.5 ) ); |
|
painter->drawRoundedRect( outlineRect, 2.5, 2.5 ); |
|
|
|
} |
|
|
|
} |
|
|
|
//______________________________________________________________________________ |
|
void Style::renderCheckBox( |
|
QPainter* painter, const QRect& rect, |
|
const QColor& color, const QColor& shadow, |
|
bool sunken, CheckBoxState state ) const |
|
{ |
|
|
|
// setup painter |
|
painter->setRenderHint( QPainter::Antialiasing, true ); |
|
|
|
// copy rect |
|
QRectF baseRect( rect ); |
|
|
|
// shadow |
|
if( !sunken ) |
|
{ |
|
|
|
painter->setPen( QPen( shadow, 2 ) ); |
|
painter->setBrush( Qt::NoBrush ); |
|
|
|
const QRectF shadowRect( baseRect.adjusted( 1.5, 1.5, -1.5, -1.5 ).translated( 0, 0.5 ) ); |
|
painter->drawRoundedRect( shadowRect, 2, 2 ); |
|
|
|
} |
|
|
|
// content |
|
{ |
|
|
|
painter->setPen( QPen( color, 2 ) ); |
|
painter->setBrush( Qt::NoBrush ); |
|
|
|
const QRectF contentRect( baseRect.adjusted( 2, 2, -2, -2 ) ); |
|
painter->drawRoundedRect( contentRect, 2, 2 ); |
|
|
|
} |
|
|
|
// mark |
|
if( state == CheckOn ) |
|
{ |
|
|
|
painter->setBrush( color ); |
|
painter->setPen( Qt::NoPen ); |
|
|
|
const QRectF markerRect( baseRect.adjusted( 5, 5, -5, -5 ) ); |
|
painter->drawRect( markerRect ); |
|
|
|
} else if( state == CheckPartial ) { |
|
|
|
QPen pen( color, 2 ); |
|
pen.setJoinStyle( Qt::MiterJoin ); |
|
painter->setPen( pen ); |
|
|
|
const QRectF markerRect( baseRect.adjusted( 6, 6, -6, -6 ) ); |
|
painter->drawRect( markerRect ); |
|
|
|
painter->setPen( Qt::NoPen ); |
|
painter->setBrush( color ); |
|
painter->setRenderHint( QPainter::Antialiasing, false ); |
|
|
|
QPainterPath path; |
|
path.moveTo( 5, 5 ); |
|
path.lineTo( qreal( Metrics::CheckBox_Size ) -6, 5 ); |
|
path.lineTo( 5, qreal( Metrics::CheckBox_Size ) - 6 ); |
|
painter->drawPath( path ); |
|
|
|
} |
|
|
|
} |
|
|
|
//______________________________________________________________________________ |
|
void Style::renderRadioButton( |
|
QPainter* painter, const QRect& rect, |
|
const QColor& color, const QColor& shadow, |
|
bool sunken, bool checked ) const |
|
{ |
|
|
|
// setup painter |
|
painter->setRenderHint( QPainter::Antialiasing, true ); |
|
|
|
QRectF baseRect( rect ); |
|
|
|
// shadow |
|
if( !sunken ) |
|
{ |
|
|
|
painter->setPen( QPen( shadow, 2 ) ); |
|
painter->setBrush( Qt::NoBrush ); |
|
|
|
const QRectF shadowRect( baseRect.adjusted( 1.5, 1.5, -1.5, -1.5 ).translated( 0, 0.5 ) ); |
|
painter->drawEllipse( shadowRect ); |
|
|
|
} |
|
|
|
// content |
|
{ |
|
|
|
painter->setPen( QPen( color, 2 ) ); |
|
painter->setBrush( Qt::NoBrush ); |
|
|
|
const QRectF contentRect( baseRect.adjusted( 2, 2, -2, -2 ) ); |
|
painter->drawEllipse( contentRect ); |
|
|
|
} |
|
|
|
// mark |
|
if( checked ) |
|
{ |
|
|
|
painter->setBrush( color ); |
|
painter->setPen( Qt::NoPen ); |
|
|
|
const QRectF markerRect( baseRect.adjusted( 5, 5, -5, -5 ) ); |
|
painter->drawEllipse( markerRect ); |
|
|
|
} |
|
|
|
} |
|
|
|
//______________________________________________________________________________ |
|
void Style::renderSliderHole( |
|
QPainter* painter, const QRect& rect, |
|
const QColor& color ) const |
|
{ |
|
|
|
// setup painter |
|
painter->setRenderHint( QPainter::Antialiasing, true ); |
|
|
|
const QRectF baseRect( rect ); |
|
const qreal radius( 0.5*Metrics::Slider_Thickness ); |
|
|
|
// content |
|
if( color.isValid() ) |
|
{ |
|
painter->setPen( Qt::NoPen ); |
|
painter->setBrush( color ); |
|
painter->drawRoundedRect( baseRect, radius, radius ); |
|
} |
|
|
|
return; |
|
|
|
} |
|
|
|
//______________________________________________________________________________ |
|
void Style::renderSliderHandle( |
|
QPainter* painter, const QRect& rect, |
|
const QColor& color, |
|
const QColor& outline, |
|
const QColor& shadow, |
|
bool focus, |
|
bool sunken ) const |
|
{ |
|
|
|
// setup painter |
|
painter->setRenderHint( QPainter::Antialiasing, true ); |
|
|
|
QRectF baseRect( rect ); |
|
|
|
// shadow |
|
if( !sunken ) |
|
{ |
|
|
|
painter->setPen( QPen( shadow, 2 ) ); |
|
painter->setBrush( Qt::NoBrush ); |
|
|
|
const QRectF shadowRect( baseRect.adjusted( 1.5, 1.5, -1.5, -1.5 ).translated( 0, 0.5 ) ); |
|
painter->drawEllipse( shadowRect ); |
|
|
|
} |
|
|
|
// content |
|
if( color.isValid() ) |
|
{ |
|
painter->setPen( Qt::NoPen ); |
|
painter->setBrush( color ); |
|
|
|
const QRectF contentRect( baseRect.adjusted( 1, 1, -1, -1 ) ); |
|
painter->drawEllipse( contentRect ); |
|
|
|
} |
|
|
|
// outline |
|
if( outline.isValid() ) |
|
{ |
|
painter->setBrush( Qt::NoBrush ); |
|
QRectF outlineRect; |
|
if( focus ) |
|
{ |
|
painter->setPen( QPen( outline, 2 ) ); |
|
outlineRect = baseRect.adjusted( 2, 2, -2, -2 ); |
|
} else { |
|
painter->setPen( QPen( outline, 1 ) ); |
|
outlineRect = baseRect.adjusted( 1.5, 1.5, -1.5, -1.5 ); |
|
} |
|
|
|
painter->drawEllipse( outlineRect ); |
|
|
|
} |
|
|
|
} |
|
|
|
//______________________________________________________________________________ |
|
void Style::renderProgressBarHole( |
|
QPainter* painter, const QRect& rect, |
|
const QColor& color ) const |
|
{ |
|
|
|
// setup painter |
|
painter->setRenderHint( QPainter::Antialiasing, true ); |
|
|
|
const QRectF baseRect( rect ); |
|
const qreal radius( 0.5*Metrics::ProgressBar_Thickness ); |
|
|
|
// content |
|
if( color.isValid() ) |
|
{ |
|
painter->setPen( Qt::NoPen ); |
|
painter->setBrush( color ); |
|
painter->drawRoundedRect( baseRect, radius, radius ); |
|
} |
|
|
|
return; |
|
|
|
} |
|
|
|
//______________________________________________________________________________ |
|
void Style::renderScrollBarHandle( |
|
QPainter* painter, const QRect& rect, |
|
const QColor& color, const QColor& outline ) const |
|
{ |
|
|
|
// setup painter |
|
painter->setRenderHint( QPainter::Antialiasing, true ); |
|
|
|
const QRectF baseRect( rect ); |
|
const qreal radius( 0.5*Metrics::ScrollBar_SliderWidth ); |
|
|
|
// content |
|
if( color.isValid() ) |
|
{ |
|
painter->setPen( Qt::NoPen ); |
|
painter->setBrush( color ); |
|
painter->drawRoundedRect( baseRect, radius, radius ); |
|
} |
|
|
|
|
|
// border |
|
if( outline.isValid() ) |
|
{ |
|
painter->setPen( QPen( outline, 2 ) ); |
|
painter->setBrush( Qt::NoBrush ); |
|
|
|
const QRectF outlineRect( baseRect.adjusted( 1, 1, -1, -1 ) ); |
|
painter->drawRoundedRect( outlineRect, radius - 0.5, radius - 0.5 ); |
|
} |
|
|
|
return; |
|
|
|
} |
|
|
|
|
|
//______________________________________________________________________________ |
|
void Style::renderScrollBarArrow( |
|
QPainter* painter, const QRect& rect, const QColor& color, |
|
ArrowOrientation orientation ) const |
|
{ |
|
// setup painter |
|
painter->setRenderHint( QPainter::Antialiasing, true ); |
|
|
|
const qreal penThickness( 1.5 ); |
|
QPolygonF a( genericArrow( orientation, ArrowNormal ) ); |
|
|
|
const QColor base( color ); |
|
|
|
painter->save(); |
|
painter->translate( QRectF(rect).center() ); |
|
|
|
painter->setPen( QPen( base, penThickness, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin ) ); |
|
painter->drawPolyline( a ); |
|
painter->restore(); |
|
|
|
return; |
|
|
|
} |
|
|
|
//______________________________________________________________________________ |
|
QWidget* Style::scrollBarParent( const QWidget* widget ) const |
|
{ |
|
|
|
// check widget and parent |
|
if( !(widget && widget->parentWidget() ) ) return nullptr; |
|
|
|
// try cast to scroll area. Must test both parent and grandparent |
|
QAbstractScrollArea* scrollArea; |
|
if( !(scrollArea = qobject_cast<QAbstractScrollArea*>( widget->parentWidget() ) ) ) |
|
{ scrollArea = qobject_cast<QAbstractScrollArea*>( widget->parentWidget()->parentWidget() ); } |
|
|
|
if( scrollArea && |
|
(widget == scrollArea->verticalScrollBar() || |
|
widget == scrollArea->horizontalScrollBar() ) ) return scrollArea; |
|
else return nullptr; |
|
|
|
} |
|
|
|
//______________________________________________________________________________ |
|
QColor Style::scrollBarArrowColor( const QStyleOptionSlider* option, const SubControl& control, const QWidget* widget ) const |
|
{ |
|
|
|
Q_UNUSED( widget ); |
|
|
|
const QRect& r( option->rect ); |
|
const QPalette& palette( option->palette ); |
|
QColor color( palette.color( QPalette::WindowText ) ); |
|
|
|
// check enabled state |
|
const bool enabled( option->state & State_Enabled ); |
|
if( !enabled ) return color; |
|
|
|
if( |
|
( control == SC_ScrollBarSubLine && option->sliderValue == option->minimum ) || |
|
( control == SC_ScrollBarAddLine && option->sliderValue == option->maximum ) ) |
|
{ |
|
|
|
// manually disable arrow, to indicate that scrollbar is at limit |
|
return palette.color( QPalette::Disabled, QPalette::WindowText ); |
|
|
|
} |
|
|
|
const bool hover( _animations->scrollBarEngine().isHovered( widget, control ) ); |
|
const bool animated( _animations->scrollBarEngine().isAnimated( widget, control ) ); |
|
const qreal opacity( _animations->scrollBarEngine().opacity( widget, control ) ); |
|
|
|
// retrieve mouse position from engine |
|
QPoint position( hover ? _animations->scrollBarEngine().position( widget ) : QPoint( -1, -1 ) ); |
|
if( hover && r.contains( position ) ) |
|
{ |
|
// need to update the arrow controlRect on fly because there is no |
|
// way to get it from the styles directly, outside of repaint events |
|
_animations->scrollBarEngine().setSubControlRect( widget, control, r ); |
|
} |
|
|
|
|
|
if( r.intersects( _animations->scrollBarEngine().subControlRect( widget, control ) ) ) |
|
{ |
|
|
|
QColor highlight = _helper->viewHoverBrush().brush( palette ).color(); |
|
if( animated ) |
|
{ |
|
color = KColorUtils::mix( color, highlight, opacity ); |
|
|
|
} else if( hover ) { |
|
|
|
color = highlight; |
|
|
|
} |
|
|
|
} |
|
|
|
return color; |
|
|
|
} |
|
|
|
//____________________________________________________________________________________ |
|
QPolygonF Style::genericArrow( Style::ArrowOrientation orientation, Style::ArrowSize size ) const |
|
{ |
|
|
|
QPolygonF a; |
|
switch( orientation ) |
|
{ |
|
case ArrowUp: |
|
{ |
|
if( size == ArrowTiny ) a << QPointF( -1.75, 1.125 ) << QPointF( 0.5, -1.125 ) << QPointF( 2.75, 1.125 ); |
|
else if( size == ArrowSmall ) a << QPointF( -2,1.5 ) << QPointF( 0.5, -1.5 ) << QPointF( 3,1.5 ); |
|
else a << QPointF( -4,2 ) << QPointF( 0, -2 ) << QPointF( 4,2 ); |
|
break; |
|
} |
|
|
|
case ArrowDown: |
|
{ |
|
if( size == ArrowTiny ) a << QPointF( -1.75, -1.125 ) << QPointF( 0.5, 1.125 ) << QPointF( 2.75, -1.125 ); |
|
else if( size == ArrowSmall ) a << QPointF( -2,-1.5 ) << QPointF( 0.5, 1.5 ) << QPointF( 3,-1.5 ); |
|
else a << QPointF( -4,-2 ) << QPointF( 0, 2 ) << QPointF( 4,-2 ); |
|
break; |
|
} |
|
|
|
case ArrowLeft: |
|
{ |
|
if( size == ArrowTiny ) a << QPointF( 1.125, -1.75 ) << QPointF( -1.125, 0.5 ) << QPointF( 1.125, 2.75 ); |
|
else if( size == ArrowSmall ) a << QPointF( 1.5,-2 ) << QPointF( -1.5, 0.5 ) << QPointF( 1.5,3 ); |
|
else a << QPointF( 2, -4 ) << QPointF( -2, 0 ) << QPointF( 2, 4 ); |
|
break; |
|
} |
|
|
|
case ArrowRight: |
|
{ |
|
if( size == ArrowTiny ) a << QPointF( -1.125, -1.75 ) << QPointF( 1.125, 0.5 ) << QPointF( -1.125, 2.75 ); |
|
else if( size == ArrowSmall ) a << QPointF( -1.5,-2 ) << QPointF( 1.5, 0.5 ) << QPointF( -1.5,3 ); |
|
else a << QPointF( -2,-4 ) << QPointF( 2, 0 ) << QPointF( -2, 4 ); |
|
break; |
|
} |
|
|
|
default: break; |
|
|
|
} |
|
|
|
return a; |
|
|
|
} |
|
|
|
}
|
|
|