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.
5289 lines
204 KiB
5289 lines
204 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 "breezeanimationmodes.h" |
|
#include "breezeframeshadow.h" |
|
#include "breezehelper.h" |
|
#include "breezemetrics.h" |
|
#include "breezemdiwindowshadow.h" |
|
#include "breezemnemonics.h" |
|
#include "breezeshadowhelper.h" |
|
#include "breezesplitterproxy.h" |
|
#include "breezestyleconfigdata.h" |
|
#include "breezewindowmanager.h" |
|
|
|
#include <KColorUtils> |
|
|
|
#include <QApplication> |
|
#include <QAbstractItemView> |
|
#include <QCheckBox> |
|
#include <QComboBox> |
|
#include <QDial> |
|
#include <QDBusConnection> |
|
#include <QDockWidget> |
|
#include <QFormLayout> |
|
#include <QGraphicsView> |
|
#include <QGroupBox> |
|
#include <QLineEdit> |
|
#include <QMainWindow> |
|
#include <QMdiSubWindow> |
|
#include <QMenu> |
|
#include <QPainter> |
|
#include <QPushButton> |
|
#include <QRadioButton> |
|
#include <QScrollBar> |
|
#include <QSplitterHandle> |
|
#include <QTextEdit> |
|
#include <QToolBox> |
|
#include <QToolButton> |
|
|
|
Q_LOGGING_CATEGORY(BREEZE, "breeze") |
|
|
|
namespace BreezePrivate |
|
{ |
|
// needed to keep track of tabbars when being dragged |
|
class TabBarData: public QObject |
|
{ |
|
|
|
public: |
|
|
|
//! constructor |
|
explicit TabBarData( QObject* parent ): |
|
QObject( parent ) |
|
{} |
|
|
|
//! destructor |
|
virtual ~TabBarData( void ) |
|
{} |
|
|
|
//! assign target tabBar |
|
void lock( const QWidget* widget ) |
|
{ _tabBar = widget; } |
|
|
|
//! true if tabbar is locked |
|
bool isLocked( const QWidget* widget ) const |
|
{ return _tabBar && _tabBar.data() == widget; } |
|
|
|
//! release |
|
void release( void ) |
|
{ _tabBar.clear(); } |
|
|
|
private: |
|
|
|
//! pointer to target tabBar |
|
QPointer<const QWidget> _tabBar; |
|
|
|
}; |
|
|
|
} |
|
|
|
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() ) ), |
|
_shadowHelper( new ShadowHelper( this, *_helper ) ), |
|
_animations( new Animations( this ) ), |
|
_mnemonics( new Mnemonics( this ) ), |
|
_windowManager( new WindowManager( this ) ), |
|
_frameShadowFactory( new FrameShadowFactory( this ) ), |
|
_mdiWindowShadowFactory( new MdiWindowShadowFactory( this ) ), |
|
_splitterFactory( new SplitterFactory( this ) ), |
|
_tabBarData( new BreezePrivate::TabBarData( 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 _shadowHelper; |
|
delete _helper; |
|
} |
|
|
|
//______________________________________________________________ |
|
void Style::polish( QApplication* ) |
|
{ |
|
|
|
// alter palette for relevant framed widgets |
|
const QPalette palette( _helper->framePalette( QGuiApplication::palette() ) ); |
|
QApplication::setPalette( palette, "QDockWidget" ); |
|
QApplication::setPalette( palette, "QGroupBox" ); |
|
QApplication::setPalette( palette, "QTabWidget" ); |
|
|
|
} |
|
|
|
//______________________________________________________________ |
|
void Style::polish( QWidget* widget ) |
|
{ |
|
if( !widget ) return; |
|
|
|
// register widget to animations |
|
_animations->registerWidget( widget ); |
|
_windowManager->registerWidget( widget ); |
|
_frameShadowFactory->registerWidget( widget, *_helper ); |
|
_mdiWindowShadowFactory->registerWidget( widget ); |
|
_shadowHelper->registerWidget( widget ); |
|
_splitterFactory->registerWidget( widget ); |
|
|
|
// enable mouse over 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 mouse over effects in itemviews' viewport |
|
itemView->viewport()->setAttribute( Qt::WA_Hover ); |
|
|
|
} else if( QAbstractScrollArea* scrollArea = qobject_cast<QAbstractScrollArea*>( widget ) ) { |
|
|
|
// enable mouse over 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 ); |
|
|
|
} else if( qobject_cast<QFrame*>( widget ) && widget->parent() && widget->parent()->inherits( "KTitleWidget" ) ) { |
|
|
|
widget->setAutoFillBackground( false ); |
|
|
|
} |
|
|
|
if( qobject_cast<QScrollBar*>( widget ) ) |
|
{ |
|
|
|
// remove opaque painting for scrollbars |
|
widget->setAttribute( Qt::WA_OpaquePaintEvent, false ); |
|
|
|
} else if( QAbstractScrollArea* scrollArea = qobject_cast<QAbstractScrollArea*>( widget ) ) { |
|
|
|
// make sure scrollbar background role matches viewport |
|
QWidget* viewport( scrollArea->viewport() ); |
|
QScrollBar* scrollBar; |
|
|
|
// make sure scrollbar background color matches |
|
if( viewport && ( scrollBar = scrollArea->verticalScrollBar() ) ) scrollBar->setBackgroundRole( scrollArea->viewport()->backgroundRole() ); |
|
if( viewport && ( scrollBar = scrollArea->horizontalScrollBar() ) ) scrollBar->setBackgroundRole( scrollArea->viewport()->backgroundRole() ); |
|
|
|
} else if( QToolButton* toolButton = qobject_cast<QToolButton*>( widget ) ) { |
|
|
|
if( toolButton->autoRaise() ) |
|
{ |
|
// for flat toolbuttons, adjust foreground and background role accordingly |
|
widget->setBackgroundRole( QPalette::NoRole ); |
|
widget->setForegroundRole( QPalette::WindowText ); |
|
} |
|
|
|
} else if( qobject_cast<QDockWidget*>( widget ) ) { |
|
|
|
// add event filter on dock widgets |
|
// and alter palette |
|
widget->setAutoFillBackground( false ); |
|
widget->setContentsMargins( Metrics::Frame_FrameWidth, Metrics::Frame_FrameWidth, Metrics::Frame_FrameWidth, Metrics::Frame_FrameWidth ); |
|
addEventFilter( widget ); |
|
|
|
} else if( qobject_cast<QMdiSubWindow*>( widget ) ) { |
|
|
|
widget->setAutoFillBackground( false ); |
|
addEventFilter( widget ); |
|
|
|
} else if( qobject_cast<QMenu*>( widget ) ) { |
|
|
|
setTranslucentBackground( widget ); |
|
|
|
} else if( widget->inherits( "QComboBoxPrivateContainer" ) ) { |
|
|
|
addEventFilter( widget ); |
|
setTranslucentBackground( widget ); |
|
|
|
} else if( widget->inherits( "QTipLabel" ) ) { |
|
|
|
setTranslucentBackground( widget ); |
|
|
|
} |
|
|
|
|
|
// base class polishing |
|
KStyle::polish( widget ); |
|
|
|
} |
|
|
|
//_______________________________________________________________ |
|
void Style::unpolish( QWidget* widget ) |
|
{ |
|
|
|
// register widget to animations |
|
_animations->unregisterWidget( widget ); |
|
_frameShadowFactory->unregisterWidget( widget ); |
|
_mdiWindowShadowFactory->unregisterWidget( widget ); |
|
_shadowHelper->unregisterWidget( widget ); |
|
_windowManager->unregisterWidget( widget ); |
|
_splitterFactory->unregisterWidget( widget ); |
|
|
|
KStyle::unpolish( widget ); |
|
|
|
} |
|
|
|
//______________________________________________________________ |
|
int Style::pixelMetric( PixelMetric metric, const QStyleOption* option, const QWidget* widget ) const |
|
{ |
|
|
|
// handle special cases |
|
switch( metric ) |
|
{ |
|
|
|
// frame width |
|
case PM_DefaultFrameWidth: |
|
case PM_ComboBoxFrameWidth: |
|
case PM_SpinBoxFrameWidth: |
|
case PM_ToolBarFrameWidth: |
|
return Metrics::Frame_FrameWidth; |
|
|
|
case PM_ToolTipLabelFrameWidth: |
|
return Metrics::ToolTip_FrameWidth; |
|
|
|
// layout |
|
case PM_LayoutLeftMargin: |
|
case PM_LayoutTopMargin: |
|
case PM_LayoutRightMargin: |
|
case PM_LayoutBottomMargin: |
|
{ |
|
/* |
|
use either Child margin or TopLevel margin, |
|
depending on widget type |
|
*/ |
|
if( ( option && ( option->state & QStyle::State_Window ) ) || ( widget && widget->isWindow() ) ) |
|
{ |
|
|
|
return Metrics::Layout_TopLevelMarginWidth; |
|
|
|
} else { |
|
|
|
return Metrics::Layout_ChildMarginWidth; |
|
|
|
} |
|
|
|
} |
|
|
|
case PM_LayoutHorizontalSpacing: return Metrics::Layout_DefaultSpacing; |
|
case PM_LayoutVerticalSpacing: return Metrics::Layout_DefaultSpacing; |
|
|
|
// buttons |
|
case PM_ButtonMargin: return Metrics::Button_MarginWidth; |
|
case PM_ButtonDefaultIndicator: return 0; |
|
case PM_ButtonShiftHorizontal: return 0; |
|
case PM_ButtonShiftVertical: return 0; |
|
|
|
// menubars |
|
case PM_MenuBarPanelWidth: return 0; |
|
case PM_MenuBarHMargin: return 0; |
|
case PM_MenuBarVMargin: return 0; |
|
case PM_MenuBarItemSpacing: return 0; |
|
case PM_MenuDesktopFrameWidth: return 0; |
|
|
|
// menu buttons |
|
case PM_MenuButtonIndicator: return Metrics::MenuButton_IndicatorWidth; |
|
|
|
// toolbars |
|
case PM_ToolBarHandleExtent: return Metrics::ToolBar_HandleWidth; |
|
case PM_ToolBarSeparatorExtent: return Metrics::ToolBar_SeparatorWidth; |
|
case PM_ToolBarExtensionExtent: return Metrics::ToolBar_ExtensionWidth; |
|
|
|
// toolbar items |
|
case PM_ToolBarItemMargin: return 0; |
|
case PM_ToolBarItemSpacing: return Metrics::ToolBar_ItemSpacing; |
|
|
|
// tabbars |
|
case PM_TabBarTabShiftVertical: return 0; |
|
case PM_TabBarTabShiftHorizontal: return 0; |
|
case PM_TabBarTabOverlap: return Metrics::TabBar_TabOverlap; |
|
case PM_TabBarBaseOverlap: return Metrics::TabBar_BaseOverlap; |
|
case PM_TabBarTabHSpace: return 2*Metrics::TabBar_TabMarginWidth; |
|
case PM_TabBarTabVSpace: return 2*Metrics::TabBar_TabMarginHeight; |
|
|
|
// 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 CheckBox_Size; |
|
case PM_ExclusiveIndicatorHeight: return CheckBox_Size; |
|
|
|
// list heaaders |
|
case PM_HeaderMarkSize: return Metrics::Header_ArrowSize; |
|
case PM_HeaderMargin: return Metrics::Header_MarginWidth; |
|
|
|
// dock widget |
|
// return 0 here, since frame is handled directly in polish |
|
case PM_DockWidgetFrameWidth: return 0; |
|
case PM_DockWidgetTitleMargin: return Frame_FrameWidth; |
|
|
|
// fallback |
|
default: return KStyle::pixelMetric( metric, option, widget ); |
|
|
|
} |
|
|
|
} |
|
|
|
//______________________________________________________________ |
|
int Style::styleHint( StyleHint hint, const QStyleOption* option, const QWidget* widget, QStyleHintReturn* returnData ) const |
|
{ |
|
switch( hint ) |
|
{ |
|
|
|
|
|
case SH_RubberBand_Mask: |
|
{ |
|
|
|
if( QStyleHintReturnMask *mask = qstyleoption_cast<QStyleHintReturnMask*>( returnData ) ) |
|
{ |
|
|
|
mask->region = option->rect; |
|
|
|
// need to check on widget before removing inner region |
|
// in order to still preserve rubberband in MainWindow and QGraphicsView |
|
// in QMainWindow because it looks better |
|
// in QGraphicsView because the painting fails completely otherwise |
|
if( widget && ( |
|
qobject_cast<const QAbstractItemView*>( widget->parent() ) || |
|
qobject_cast<const QGraphicsView*>( widget->parent() ) || |
|
qobject_cast<const QMainWindow*>( widget->parent() ) ) ) |
|
{ return true; } |
|
|
|
// also check if widget's parent is some itemView viewport |
|
if( widget && widget->parent() && |
|
qobject_cast<const QAbstractItemView*>( widget->parent()->parent() ) && |
|
static_cast<const QAbstractItemView*>( widget->parent()->parent() )->viewport() == widget->parent() ) |
|
{ return true; } |
|
|
|
// mask out center |
|
mask->region -= insideMargin( option->rect, 1 ); |
|
|
|
return true; |
|
} |
|
return false; |
|
} |
|
|
|
// combobox |
|
case SH_ComboBox_ListMouseTracking: return true; |
|
|
|
// menubar |
|
case SH_MenuBar_MouseTracking: return true; |
|
|
|
// menu |
|
case SH_Menu_MouseTracking: return true; |
|
case SH_Menu_SubMenuPopupDelay: return 150; |
|
case SH_Menu_SloppySubMenus: return true; |
|
case SH_Menu_SupportsSections: return true; |
|
|
|
// groupboxes |
|
case SH_GroupBox_TextLabelVerticalAlignment: return Qt::AlignVCenter; |
|
|
|
// tabbar |
|
case SH_TabBar_Alignment: return Qt::AlignCenter; |
|
|
|
// toolbox |
|
case SH_ToolBox_SelectedPageTitleBold: return false; |
|
|
|
// scrollbars |
|
case SH_ScrollBar_MiddleClickAbsolutePosition: return true; |
|
|
|
// forms |
|
case SH_FormLayoutFormAlignment: return Qt::AlignLeft | Qt::AlignTop; |
|
case SH_FormLayoutLabelAlignment: return Qt::AlignRight; |
|
case SH_FormLayoutFieldGrowthPolicy: return QFormLayout::ExpandingFieldsGrow; |
|
case SH_FormLayoutWrapPolicy: return QFormLayout::DontWrapRows; |
|
|
|
// message box |
|
case SH_MessageBox_TextInteractionFlags: return Qt::TextSelectableByMouse | Qt::LinksAccessibleByMouse; |
|
|
|
// dialog buttons |
|
case SH_ProgressDialog_CenterCancelButton: |
|
case SH_MessageBox_CenterButtons: |
|
return false; |
|
|
|
// input panel |
|
case SH_RequestSoftwareInputPanel: return RSIP_OnMouseClick; |
|
|
|
// fallback |
|
default: return KStyle::styleHint( hint, option, widget, returnData ); |
|
|
|
} |
|
|
|
} |
|
|
|
//______________________________________________________________ |
|
QRect Style::subElementRect( SubElement element, const QStyleOption* option, const QWidget* widget ) const |
|
{ |
|
switch( element ) |
|
{ |
|
|
|
// checkboxes and radio buttons |
|
case SE_CheckBoxContents: return checkBoxContentsRect( option, widget ); |
|
case SE_RadioButtonContents: return checkBoxContentsRect( option, widget ); |
|
|
|
// line edit content |
|
case SE_LineEditContents: return lineEditContentsRect( 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 ); |
|
|
|
// headers |
|
case SE_HeaderArrow: return headerArrowRect( option, widget ); |
|
case SE_HeaderLabel: return headerLabelRect( option, widget ); |
|
|
|
// tabbars |
|
case SE_TabWidgetTabBar: return tabWidgetTabBarRect( option, widget ); |
|
case SE_TabWidgetTabContents: return tabWidgetTabContentsRect( option, widget ); |
|
case SE_TabWidgetTabPane: return tabWidgetTabPaneRect( option, widget ); |
|
case SE_TabWidgetLeftCorner: return tabWidgetCornerRect( SE_TabWidgetLeftCorner, option, widget ); |
|
case SE_TabWidgetRightCorner: return tabWidgetCornerRect( SE_TabWidgetRightCorner, option, widget ); |
|
|
|
// toolbox |
|
case SE_ToolBoxTabContents: return toolBoxTabContentsRect( 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_GroupBox: return groupBoxSubControlRect( option, subControl, widget ); |
|
case CC_ToolButton: return toolButtonSubControlRect( option, subControl, widget ); |
|
case CC_ComboBox: return comboBoxSubControlRect( option, subControl, widget ); |
|
case CC_SpinBox: return spinBoxSubControlRect( option, subControl, widget ); |
|
case CC_ScrollBar: return scrollBarSubControlRect( option, subControl, widget ); |
|
case CC_Dial: return dialSubControlRect( 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 ) |
|
{ |
|
|
|
case CT_CheckBox: return checkBoxSizeFromContents( option, size, widget ); |
|
case CT_RadioButton: return checkBoxSizeFromContents( option, size, widget ); |
|
case CT_LineEdit: return lineEditSizeFromContents( option, size, widget ); |
|
case CT_ComboBox: return comboBoxSizeFromContents( option, size, widget ); |
|
case CT_SpinBox: return spinBoxSizeFromContents( option, size, widget ); |
|
case CT_PushButton: return pushButtonSizeFromContents( option, size, widget ); |
|
case CT_ToolButton: return toolButtonSizeFromContents( option, size, widget ); |
|
case CT_MenuBar: return defaultSizeFromContents( option, size, widget ); |
|
case CT_MenuBarItem: return menuBarItemSizeFromContents( option, size, widget ); |
|
case CT_MenuItem: return menuItemSizeFromContents( option, size, widget ); |
|
case CT_ProgressBar: return progressBarSizeFromContents( option, size, widget ); |
|
|
|
// tabbars |
|
case CT_TabWidget: return tabWidgetSizeFromContents( option, size, widget ); |
|
case CT_TabBarTab: return tabBarTabSizeFromContents( option, size, widget ); |
|
|
|
// item views |
|
case CT_HeaderSection: return headerSectionSizeFromContents( option, size, widget ); |
|
case CT_ItemViewItem: return itemViewItemSizeFromContents( 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; |
|
case PE_PanelButtonTool: fcn = &Style::drawPanelButtonToolPrimitive; break; |
|
|
|
// scroll areas |
|
case PE_PanelScrollAreaCorner: fcn = &Style::drawPanelScrollAreaCornerPrimitive; break; |
|
|
|
|
|
// menus |
|
case PE_PanelMenu: fcn = &Style::drawPanelMenuPrimitive; break; |
|
|
|
// tooltips |
|
case PE_PanelTipLabel: fcn = &Style::drawPanelTipLabelPrimitive; break; |
|
|
|
// item view |
|
case PE_PanelItemViewItem: fcn = &Style::drawPanelItemViewItemPrimitive; break; |
|
|
|
// checkboxes and radio buttons |
|
case PE_IndicatorCheckBox: fcn = &Style::drawIndicatorCheckBoxPrimitive; break; |
|
case PE_IndicatorRadioButton: fcn = &Style::drawIndicatorRadioButtonPrimitive; break; |
|
|
|
// menu indicator |
|
case PE_IndicatorButtonDropDown: fcn = &Style::drawIndicatorButtonDropDownPrimitive; break; |
|
|
|
// arrows |
|
case PE_IndicatorArrowUp: fcn = &Style::drawIndicatorArrowUpPrimitive; break; |
|
case PE_IndicatorArrowDown: fcn = &Style::drawIndicatorArrowDownPrimitive; break; |
|
case PE_IndicatorArrowLeft: fcn = &Style::drawIndicatorArrowLeftPrimitive; break; |
|
case PE_IndicatorArrowRight: fcn = &Style::drawIndicatorArrowRightPrimitive; break; |
|
case PE_IndicatorHeaderArrow: fcn = &Style::drawIndicatorHeaderArrowPrimitive; break; |
|
case PE_IndicatorToolBarSeparator: fcn = &Style::drawIndicatorToolBarSeparatorPrimitive; break; |
|
case PE_IndicatorBranch: fcn = &Style::drawIndicatorBranchPrimitive; break; |
|
|
|
// frames |
|
case PE_FrameStatusBar: fcn = &Style::emptyPrimitive; break; |
|
case PE_Frame: fcn = &Style::drawFramePrimitive; break; |
|
case PE_FrameLineEdit: fcn = &Style::drawFramePrimitive; break; |
|
case PE_FrameMenu: fcn = &Style::drawFrameMenuPrimitive; break; |
|
case PE_FrameGroupBox: fcn = &Style::drawFrameGroupBoxPrimitive; break; |
|
case PE_FrameTabWidget: fcn = &Style::drawFrameTabWidgetPrimitive; break; |
|
case PE_FrameTabBarBase: fcn = &Style::drawFrameTabBarBasePrimitive; break; |
|
case PE_FrameWindow: fcn = &Style::drawFrameWindowPrimitive; break; |
|
|
|
// disable all focus rect rendering |
|
// it is handled directly in the relevant primitives |
|
case PE_FrameFocusRect: fcn = &Style::emptyPrimitive; 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; |
|
case CE_CheckBoxLabel: fcn = &Style::drawCheckBoxLabelControl; break; |
|
case CE_RadioButtonLabel: fcn = &Style::drawCheckBoxLabelControl; break; |
|
|
|
// combobox |
|
case CE_ComboBoxLabel: fcn = &Style::drawComboBoxLabelControl; break; |
|
|
|
// menu bars |
|
case CE_MenuBarEmptyArea: fcn = &Style::emptyControl; break; |
|
|
|
// menubar items |
|
case CE_MenuBarItem: fcn = &Style::drawMenuBarItemControl; break; |
|
|
|
// menu items |
|
case CE_MenuItem: fcn = &Style::drawMenuItemControl; break; |
|
|
|
// toolbar |
|
case CE_ToolBar: fcn = &Style::emptyControl; 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; |
|
|
|
// frame |
|
case CE_ShapedFrame: fcn = &Style::drawShapedFrameControl; break; |
|
|
|
// rubber band |
|
case CE_RubberBand: fcn = &Style::drawRubberBandControl; break; |
|
|
|
// size grip |
|
// no size grip is rendered, since its usage is discouraged |
|
case CE_SizeGrip: fcn = &Style::emptyControl; break; |
|
|
|
// list headers |
|
case CE_HeaderSection: fcn = &Style::drawHeaderSectionControl; break; |
|
case CE_HeaderEmptyArea: fcn = &Style::drawHeaderEmptyAreaControl; break; |
|
|
|
// tabbar |
|
case CE_TabBarTabLabel: fcn = &Style::drawTabBarTabLabelControl; break; |
|
case CE_TabBarTabShape: fcn = &Style::drawTabBarTabShapeControl; break; |
|
|
|
// toolbox |
|
case CE_ToolBoxTabLabel: fcn = &Style::drawToolBoxTabLabelControl; break; |
|
case CE_ToolBoxTabShape: fcn = &Style::drawToolBoxTabShapeControl; break; |
|
|
|
// dock widget titlebar |
|
case CE_DockWidgetTitle: fcn = &Style::drawDockWidgetTitleControl; 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_ToolButton: fcn = &Style::drawToolButtonComplexControl; break; |
|
case CC_ComboBox: fcn = &Style::drawComboBoxComplexControl; break; |
|
case CC_SpinBox: fcn = &Style::drawSpinBoxComplexControl; break; |
|
case CC_Slider: fcn = &Style::drawSliderComplexControl; break; |
|
case CC_Dial: fcn = &Style::drawDialComplexControl; break; |
|
case CC_ScrollBar: fcn = &Style::drawScrollBarComplexControl; 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 copy = _helper->disabledPalette( palette, _animations->widgetEnabilityEngine().opacity( widget, AnimationEnable ) ); |
|
return KStyle::drawItemText( painter, r, flags, copy, enabled, text, textRole ); |
|
|
|
} |
|
|
|
} |
|
|
|
// fallback |
|
return KStyle::drawItemText( painter, r, flags, palette, enabled, text, textRole ); |
|
|
|
} |
|
|
|
|
|
//_____________________________________________________________________ |
|
bool Style::eventFilter( QObject *object, QEvent *event ) |
|
{ |
|
|
|
if( QDockWidget* dockWidget = qobject_cast<QDockWidget*>( object ) ) { return eventFilterDockWidget( dockWidget, event ); } |
|
else if( QMdiSubWindow* subWindow = qobject_cast<QMdiSubWindow*>( object ) ) { return eventFilterMdiSubWindow( subWindow, event ); } |
|
|
|
// cast to QWidget |
|
QWidget *widget = static_cast<QWidget*>( object ); |
|
if( widget->inherits( "QComboBoxPrivateContainer" ) ) { return eventFilterComboBoxContainer( widget, event ); } |
|
|
|
// fallback |
|
return KStyle::eventFilter( object, event ); |
|
} |
|
|
|
//____________________________________________________________________________ |
|
bool Style::eventFilterDockWidget( QDockWidget* dockWidget, QEvent* event ) |
|
{ |
|
if( event->type() == QEvent::Paint && !dockWidget->isWindow() ) |
|
{ |
|
// create painter and clip |
|
QPainter painter( dockWidget ); |
|
QPaintEvent *paintEvent = static_cast<QPaintEvent*>( event ); |
|
painter.setClipRegion( paintEvent->region() ); |
|
|
|
// define color and render |
|
const QColor outline( _helper->frameOutlineColor( dockWidget->palette() ) ); |
|
_helper->renderFrame( &painter, dockWidget->rect(), QColor(), outline ); |
|
|
|
} |
|
|
|
return false; |
|
|
|
} |
|
|
|
//____________________________________________________________________________ |
|
bool Style::eventFilterMdiSubWindow( QMdiSubWindow* subWindow, QEvent* event ) |
|
{ |
|
|
|
if( event->type() == QEvent::Paint ) |
|
{ |
|
QPainter painter( subWindow ); |
|
QPaintEvent* paintEvent( static_cast<QPaintEvent*>( event ) ); |
|
painter.setClipRegion( paintEvent->region() ); |
|
|
|
const QRect rect( subWindow->rect() ); |
|
const QColor background( subWindow->palette().color( QPalette::Window ) ); |
|
|
|
if( subWindow->isMaximized() ) |
|
{ |
|
|
|
// full painting |
|
painter.setPen( Qt::NoPen ); |
|
painter.setBrush( background ); |
|
painter.drawRect( rect ); |
|
|
|
} else { |
|
|
|
// framed painting |
|
_helper->renderMenuFrame( &painter, rect, background, QColor() ); |
|
|
|
} |
|
|
|
} |
|
|
|
// continue with normal painting |
|
return false; |
|
|
|
} |
|
|
|
//_________________________________________________________ |
|
bool Style::eventFilterComboBoxContainer( QWidget* widget, QEvent* event ) |
|
{ |
|
if( event->type() == QEvent::Paint ) |
|
{ |
|
|
|
QPainter painter( widget ); |
|
QPaintEvent *paintEvent = static_cast<QPaintEvent*>( event ); |
|
painter.setClipRegion( paintEvent->region() ); |
|
|
|
const QRect rect( widget->rect() ); |
|
const QPalette& palette( widget->palette() ); |
|
const QColor background( _helper->frameBackgroundColor( palette ) ); |
|
const QColor outline( _helper->frameOutlineColor( palette ) ); |
|
|
|
const bool hasAlpha( _helper->hasAlphaChannel( widget ) ); |
|
if( hasAlpha ) |
|
{ |
|
|
|
painter.setCompositionMode( QPainter::CompositionMode_Source ); |
|
_helper->renderMenuFrame( &painter, rect, background, outline, true ); |
|
|
|
} else { |
|
|
|
_helper->renderMenuFrame( &painter, rect, background, outline, false ); |
|
|
|
} |
|
|
|
} |
|
|
|
return false; |
|
|
|
} |
|
|
|
//_____________________________________________________________________ |
|
void Style::configurationChanged() |
|
{ |
|
|
|
// reparse breezerc |
|
StyleConfigData::self()->readConfig(); |
|
|
|
// reload configuration |
|
loadConfiguration(); |
|
} |
|
|
|
//_____________________________________________________________________ |
|
void Style::loadConfiguration() |
|
{ |
|
|
|
// load helper configuration |
|
_helper->loadConfig(); |
|
|
|
// reinitialize engines |
|
_animations->setupEngines(); |
|
_windowManager->initialize(); |
|
|
|
// mnemonics |
|
_mnemonics->setMode( StyleConfigData::mnemonicsMode() ); |
|
|
|
// splitter proxy |
|
_splitterFactory->setEnabled( StyleConfigData::splitterProxyEnabled() ); |
|
|
|
|
|
// set mdiwindow factory shadow tiles |
|
_mdiWindowShadowFactory->setShadowTiles( _shadowHelper->shadowTiles() ); |
|
} |
|
|
|
//___________________________________________________________________________________________________________________ |
|
QRect Style::lineEditContentsRect( const QStyleOption* option, const QWidget* ) const |
|
{ |
|
// cast option and check |
|
const QStyleOptionFrame* frameOption( qstyleoption_cast<const QStyleOptionFrame*>( option ) ); |
|
if( !frameOption ) return option->rect; |
|
|
|
// check flatness |
|
const bool flat( frameOption->lineWidth == 0 ); |
|
return flat ? option->rect : insideMargin( option->rect, Metrics::LineEdit_MarginWidth + Metrics::Frame_FrameWidth ); |
|
} |
|
|
|
//___________________________________________________________________________________________________________________ |
|
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& state( option->state ); |
|
const bool horizontal( state & State_Horizontal ); |
|
const bool textVisible( progressBarOption->textVisible ); |
|
const bool busy( progressBarOption->minimum == 0 && progressBarOption->maximum == 0 ); |
|
|
|
QRect rect( option->rect ); |
|
if( textVisible && !busy ) |
|
{ |
|
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* ) const |
|
{ |
|
|
|
// cast option |
|
const QStyleOptionProgressBar* progressBarOption( qstyleoption_cast<const QStyleOptionProgressBar*>( option ) ); |
|
if( !( progressBarOption && progressBarOption->textVisible ) ) return QRect(); |
|
|
|
// get direction |
|
const State& state( option->state ); |
|
const bool horizontal( state & 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::headerArrowRect( const QStyleOption* option, const QWidget* ) const |
|
{ |
|
|
|
// cast option and check |
|
const QStyleOptionHeader* headerOption( qstyleoption_cast<const QStyleOptionHeader*>( option ) ); |
|
if( !headerOption ) return option->rect; |
|
|
|
// check if arrow is necessary |
|
if( headerOption->sortIndicator == QStyleOptionHeader::None ) return QRect(); |
|
|
|
QRect arrowRect( insideMargin( option->rect, Metrics::Header_MarginWidth ) ); |
|
arrowRect.setLeft( arrowRect.right() - Metrics::Header_ArrowSize ); |
|
|
|
return handleRTL( option, arrowRect ); |
|
|
|
} |
|
|
|
//___________________________________________________________________________________________________________________ |
|
QRect Style::headerLabelRect( const QStyleOption* option, const QWidget* ) const |
|
{ |
|
|
|
// cast option and check |
|
const QStyleOptionHeader* headerOption( qstyleoption_cast<const QStyleOptionHeader*>( option ) ); |
|
if( !headerOption ) return option->rect; |
|
|
|
// check if arrow is necessary |
|
QRect labelRect( insideMargin( option->rect, Metrics::Header_MarginWidth ) ); |
|
if( headerOption->sortIndicator == QStyleOptionHeader::None ) return labelRect; |
|
|
|
labelRect.adjust( 0, 0, -Metrics::Header_ArrowSize-Metrics::Header_BoxTextSpace, 0 ); |
|
return handleRTL( option, labelRect ); |
|
|
|
} |
|
|
|
//____________________________________________________________________ |
|
QRect Style::tabWidgetTabBarRect( const QStyleOption* option, const QWidget* widget ) const |
|
{ |
|
|
|
// cast option and check |
|
const QStyleOptionTabWidgetFrame* tabOption = qstyleoption_cast<const QStyleOptionTabWidgetFrame*>( option ); |
|
if( !tabOption ) return option->rect; |
|
|
|
// do nothing if tabbar is hidden |
|
const QSize tabBarSize( tabOption->tabBarSize ); |
|
if( tabBarSize.isEmpty() ) return option->rect; |
|
|
|
QRect rect( option->rect ); |
|
QRect tabBarRect( QPoint(0, 0), tabBarSize ); |
|
|
|
// horizontal positioning |
|
const bool verticalTabs( isVerticalTab( tabOption->shape ) ); |
|
if( verticalTabs ) |
|
{ |
|
|
|
tabBarRect.setHeight( qMin( tabBarRect.height(), rect.height() - 2 ) ); |
|
tabBarRect.moveTop( rect.top() + ( rect.height() - tabBarRect.height() )/2 ); |
|
|
|
} else { |
|
|
|
// adjust rect to deal with corner buttons |
|
if( !tabOption->leftCornerWidgetSize.isEmpty() ) |
|
{ |
|
const QRect buttonRect( subElementRect( SE_TabWidgetLeftCorner, option, widget ) ); |
|
rect.setLeft( buttonRect.width() - 1 ); |
|
} |
|
|
|
if( !tabOption->rightCornerWidgetSize.isEmpty() ) |
|
{ |
|
const QRect buttonRect( subElementRect( SE_TabWidgetRightCorner, option, widget ) ); |
|
rect.setRight( buttonRect.left() ); |
|
} |
|
|
|
tabBarRect.setWidth( qMin( tabBarRect.width(), rect.width() - 2 ) ); |
|
tabBarRect.moveLeft( rect.left() + (rect.width() - tabBarRect.width())/2 ); |
|
|
|
} |
|
|
|
// vertical positioning |
|
switch( tabOption->shape ) |
|
{ |
|
case QTabBar::RoundedNorth: |
|
case QTabBar::TriangularNorth: |
|
tabBarRect.moveTop( rect.top()+1 ); |
|
break; |
|
|
|
case QTabBar::RoundedSouth: |
|
case QTabBar::TriangularSouth: |
|
tabBarRect.moveBottom( rect.bottom()-1 ); |
|
break; |
|
|
|
case QTabBar::RoundedWest: |
|
case QTabBar::TriangularWest: |
|
tabBarRect.moveLeft( rect.left()+1 ); |
|
break; |
|
|
|
case QTabBar::RoundedEast: |
|
case QTabBar::TriangularEast: |
|
tabBarRect.moveRight( rect.right()-1 ); |
|
break; |
|
|
|
default: break; |
|
|
|
} |
|
|
|
return tabBarRect; |
|
|
|
} |
|
|
|
//____________________________________________________________________ |
|
QRect Style::tabWidgetTabContentsRect( const QStyleOption* option, const QWidget* widget ) const |
|
{ |
|
|
|
// cast option and check |
|
const QStyleOptionTabWidgetFrame* tabOption = qstyleoption_cast<const QStyleOptionTabWidgetFrame*>( option ); |
|
if( !tabOption ) return option->rect; |
|
|
|
// do nothing if tabbar is hidden |
|
if( tabOption->tabBarSize.isEmpty() ) return option->rect; |
|
const QRect rect = tabWidgetTabPaneRect( option, widget ); |
|
|
|
const bool documentMode( tabOption->lineWidth == 0 ); |
|
if( documentMode ) |
|
{ |
|
|
|
// add margin only to the relevant side |
|
switch( tabOption->shape ) |
|
{ |
|
case QTabBar::RoundedNorth: |
|
case QTabBar::TriangularNorth: |
|
return rect.adjusted( 0, Metrics::TabWidget_MarginWidth, 0, 0 ); |
|
|
|
case QTabBar::RoundedSouth: |
|
case QTabBar::TriangularSouth: |
|
return rect.adjusted( 0, 0, 0, -Metrics::TabWidget_MarginWidth ); |
|
|
|
case QTabBar::RoundedWest: |
|
case QTabBar::TriangularWest: |
|
return rect.adjusted( Metrics::TabWidget_MarginWidth, 0, 0, 0 ); |
|
|
|
case QTabBar::RoundedEast: |
|
case QTabBar::TriangularEast: |
|
return rect.adjusted( 0, 0, -Metrics::TabWidget_MarginWidth, 0 ); |
|
|
|
default: return rect; |
|
} |
|
|
|
} else return insideMargin( rect, Metrics::TabWidget_MarginWidth ); |
|
|
|
} |
|
|
|
//____________________________________________________________________ |
|
QRect Style::tabWidgetCornerRect( SubElement element, const QStyleOption* option, const QWidget* ) const |
|
{ |
|
|
|
// cast option and check |
|
const QStyleOptionTabWidgetFrame* tabOption = qstyleoption_cast<const QStyleOptionTabWidgetFrame*>( option ); |
|
if( !tabOption ) return option->rect; |
|
|
|
// do nothing if tabbar is hidden |
|
const QSize tabBarSize( tabOption->tabBarSize ); |
|
if( tabBarSize.isEmpty() ) return QRect(); |
|
|
|
// do nothing for vertical tabs |
|
const bool verticalTabs( isVerticalTab( tabOption->shape ) ); |
|
if( verticalTabs ) return QRect(); |
|
|
|
const QRect rect( option->rect ); |
|
QRect cornerRect( QPoint( 0, 0 ), QSize( tabBarSize.height(), tabBarSize.height() + 1 ) ); |
|
if( element == SE_TabWidgetRightCorner ) cornerRect.moveRight( rect.right() ); |
|
else cornerRect.moveLeft( rect.left() ); |
|
|
|
switch( tabOption->shape ) |
|
{ |
|
case QTabBar::RoundedNorth: |
|
case QTabBar::TriangularNorth: |
|
cornerRect.moveTop( rect.top() ); |
|
break; |
|
|
|
case QTabBar::RoundedSouth: |
|
case QTabBar::TriangularSouth: |
|
cornerRect.moveBottom( rect.bottom() ); |
|
break; |
|
|
|
default: break; |
|
} |
|
|
|
return handleRTL( option, cornerRect ); |
|
|
|
} |
|
|
|
//____________________________________________________________________ |
|
QRect Style::tabWidgetTabPaneRect( const QStyleOption* option, const QWidget* ) const |
|
{ |
|
|
|
const QStyleOptionTabWidgetFrame* tabOption = qstyleoption_cast<const QStyleOptionTabWidgetFrame*>( option ); |
|
if( !tabOption || tabOption->tabBarSize.isEmpty() ) return option->rect; |
|
|
|
const int overlap = Metrics::TabBar_BaseOverlap - 1; |
|
const QSize tabBarSize( tabOption->tabBarSize - QSize( overlap, overlap ) ); |
|
|
|
QRect rect( option->rect ); |
|
switch( tabOption->shape ) |
|
{ |
|
case QTabBar::RoundedNorth: |
|
case QTabBar::TriangularNorth: |
|
rect.adjust( 0, tabBarSize.height(), 0, 0 ); |
|
break; |
|
|
|
case QTabBar::RoundedSouth: |
|
case QTabBar::TriangularSouth: |
|
rect.adjust( 0, 0, 0, -tabBarSize.height() ); |
|
break; |
|
|
|
case QTabBar::RoundedWest: |
|
case QTabBar::TriangularWest: |
|
rect.adjust( tabBarSize.width(), 0, 0, 0 ); |
|
break; |
|
|
|
case QTabBar::RoundedEast: |
|
case QTabBar::TriangularEast: |
|
rect.adjust( 0, 0, -tabBarSize.width(), 0 ); |
|
break; |
|
|
|
default: break; |
|
} |
|
|
|
return rect; |
|
|
|
} |
|
|
|
//____________________________________________________________________ |
|
QRect Style::toolBoxTabContentsRect( const QStyleOption* option, const QWidget* widget ) const |
|
{ |
|
|
|
// cast option and check |
|
const QStyleOptionToolBox* toolBoxOption( qstyleoption_cast<const QStyleOptionToolBox *>( option ) ); |
|
if( !toolBoxOption ) return option->rect; |
|
|
|
// copy rect |
|
const QRect& rect( option->rect ); |
|
|
|
int contentsWidth(0); |
|
if( !toolBoxOption->icon.isNull() ) |
|
{ |
|
const int iconSize( pixelMetric( QStyle::PM_SmallIconSize, option, widget ) ); |
|
contentsWidth += iconSize; |
|
|
|
if( !toolBoxOption->text.isEmpty() ) contentsWidth += Metrics::ToolBox_TabBoxTextSpace; |
|
} |
|
|
|
if( !toolBoxOption->text.isEmpty() ) |
|
{ |
|
|
|
const int textWidth = toolBoxOption->fontMetrics.size( _mnemonics->textFlags(), toolBoxOption->text ).width(); |
|
contentsWidth += textWidth; |
|
|
|
} |
|
|
|
contentsWidth = qMin( contentsWidth, rect.width() ); |
|
contentsWidth = qMax( contentsWidth, (int)Metrics::ToolBox_TabMinWidth ); |
|
return centerRect( rect, contentsWidth, rect.height() ); |
|
|
|
} |
|
|
|
//______________________________________________________________ |
|
QRect Style::groupBoxSubControlRect( const QStyleOptionComplex* option, SubControl subControl, const QWidget* widget ) const |
|
{ |
|
|
|
QRect rect = option->rect; |
|
switch( subControl ) |
|
{ |
|
|
|
case SC_GroupBoxFrame: return rect; |
|
|
|
case SC_GroupBoxContents: |
|
{ |
|
|
|
// cast option and check |
|
const QStyleOptionGroupBox *groupBoxOption = qstyleoption_cast<const QStyleOptionGroupBox*>( option ); |
|
if( !groupBoxOption ) break; |
|
|
|
// take out frame width |
|
rect = insideMargin( rect, Metrics::Frame_FrameWidth ); |
|
|
|
// get state |
|
const bool checkable( groupBoxOption->subControls & QStyle::SC_GroupBoxCheckBox ); |
|
const bool emptyText( groupBoxOption->text.isEmpty() ); |
|
|
|
// calculate title height |
|
int titleHeight( 0 ); |
|
if( !emptyText ) titleHeight = groupBoxOption->fontMetrics.height(); |
|
if( checkable ) titleHeight = qMax( titleHeight, (int) Metrics::CheckBox_Size ); |
|
|
|
// add margin |
|
if( titleHeight > 0 ) titleHeight += 2*Metrics::GroupBox_TitleMarginWidth; |
|
|
|
rect.adjust( 0, titleHeight, 0, 0 ); |
|
return rect; |
|
|
|
} |
|
|
|
case SC_GroupBoxCheckBox: |
|
case SC_GroupBoxLabel: |
|
{ |
|
|
|
// cast option and check |
|
const QStyleOptionGroupBox *groupBoxOption = qstyleoption_cast<const QStyleOptionGroupBox*>( option ); |
|
if( !groupBoxOption ) break; |
|
|
|
// take out frame width |
|
rect = insideMargin( rect, Metrics::Frame_FrameWidth ); |
|
|
|
const bool emptyText( groupBoxOption->text.isEmpty() ); |
|
const bool checkable( groupBoxOption->subControls & QStyle::SC_GroupBoxCheckBox ); |
|
|
|
// calculate title height |
|
int titleHeight( 0 ); |
|
int titleWidth( 0 ); |
|
if( !emptyText ) |
|
{ |
|
const QFontMetrics fontMetrics = option->fontMetrics; |
|
titleHeight = qMax( titleHeight, fontMetrics.height() ); |
|
titleWidth += fontMetrics.size( _mnemonics->textFlags(), groupBoxOption->text ).width(); |
|
} |
|
|
|
if( checkable ) |
|
{ |
|
titleHeight = qMax( titleHeight, (int) Metrics::CheckBox_Size ); |
|
titleWidth += Metrics::CheckBox_Size; |
|
if( !emptyText ) titleWidth += Metrics::CheckBox_BoxTextSpace; |
|
} |
|
|
|
// adjust height |
|
QRect titleRect( rect ); |
|
titleRect.setHeight( titleHeight ); |
|
titleRect.translate( 0, Metrics::GroupBox_TitleMarginWidth ); |
|
|
|
// center |
|
titleRect = centerRect( titleRect, titleWidth, titleHeight ); |
|
|
|
if( subControl == SC_GroupBoxCheckBox ) |
|
{ |
|
|
|
// vertical centering |
|
titleRect = centerRect( titleRect, titleWidth, Metrics::CheckBox_Size ); |
|
|
|
// horizontal positioning |
|
const QRect subRect( titleRect.topLeft(), QSize( Metrics::CheckBox_Size, titleRect.height() ) ); |
|
return visualRect( option->direction, titleRect, subRect ); |
|
|
|
} else { |
|
|
|
// vertical centering |
|
QFontMetrics fontMetrics = option->fontMetrics; |
|
titleRect = centerRect( titleRect, titleWidth, fontMetrics.height() ); |
|
|
|
// horizontal positioning |
|
QRect subRect( titleRect ); |
|
if( checkable ) subRect.adjust( Metrics::CheckBox_Size + Metrics::CheckBox_BoxTextSpace, 0, 0, 0 ); |
|
return visualRect( option->direction, titleRect, subRect ); |
|
|
|
} |
|
|
|
} |
|
|
|
default: break; |
|
|
|
} |
|
|
|
return KStyle::subControlRect( CC_GroupBox, option, subControl, widget ); |
|
|
|
} |
|
|
|
//___________________________________________________________________________________________________________________ |
|
QRect Style::toolButtonSubControlRect( const QStyleOptionComplex* option, SubControl subControl, const QWidget* widget ) const |
|
{ |
|
|
|
// cast option and check |
|
const QStyleOptionToolButton* toolButtonOption = qstyleoption_cast<const QStyleOptionToolButton*>( option ); |
|
if( !toolButtonOption ) return KStyle::subControlRect( CC_ToolButton, option, subControl, widget ); |
|
|
|
const bool hasPopupMenu( toolButtonOption->features & QStyleOptionToolButton::MenuButtonPopup ); |
|
const bool hasInlineIndicator( toolButtonOption->features & QStyleOptionToolButton::HasMenu && !hasPopupMenu ); |
|
|
|
// store rect |
|
const QRect& rect( option->rect ); |
|
const int menuButtonWidth( Metrics::MenuButton_IndicatorWidth ); |
|
switch( subControl ) |
|
{ |
|
case SC_ToolButtonMenu: |
|
{ |
|
|
|
// check fratures |
|
if( !(hasPopupMenu || hasInlineIndicator ) ) return QRect(); |
|
|
|
// check features |
|
QRect menuRect( rect ); |
|
menuRect.setLeft( rect.right() + 1 - menuButtonWidth ); |
|
if( hasInlineIndicator ) |
|
{ menuRect.setTop( menuRect.bottom() + 1 - menuButtonWidth ); } |
|
|
|
return handleRTL( option, menuRect ); |
|
} |
|
|
|
case SC_ToolButton: |
|
{ |
|
|
|
if( hasPopupMenu ) |
|
{ |
|
|
|
QRect contentsRect( rect ); |
|
contentsRect.setRight( rect.right() - menuButtonWidth ); |
|
return handleRTL( option, contentsRect ); |
|
|
|
} else return rect; |
|
|
|
} |
|
|
|
default: return QRect(); |
|
|
|
} |
|
|
|
} |
|
|
|
//___________________________________________________________________________________________________________________ |
|
QRect Style::comboBoxSubControlRect( const QStyleOptionComplex* option, SubControl subControl, const QWidget* widget ) const |
|
{ |
|
// cast option and check |
|
const QStyleOptionComboBox *comboBoxOption( qstyleoption_cast<const QStyleOptionComboBox*>( option ) ); |
|
if( !comboBoxOption ) return KStyle::subControlRect( CC_ComboBox, option, subControl, widget ); |
|
|
|
const bool editable( comboBoxOption->editable ); |
|
const bool flat( editable && !comboBoxOption->frame ); |
|
|
|
// copy rect |
|
QRect rect( option->rect ); |
|
|
|
switch( subControl ) |
|
{ |
|
case SC_ComboBoxFrame: return flat ? rect : QRect(); |
|
case SC_ComboBoxListBoxPopup: return rect; |
|
|
|
case SC_ComboBoxArrow: |
|
{ |
|
|
|
// take out frame width |
|
if( !flat ) rect = insideMargin( rect, Metrics::Frame_FrameWidth ); |
|
|
|
QRect arrowRect; |
|
if( editable ) |
|
{ |
|
|
|
arrowRect = QRect( |
|
rect.right() - Metrics::MenuButton_IndicatorWidth, |
|
rect.top(), |
|
Metrics::MenuButton_IndicatorWidth, |
|
rect.height() ); |
|
|
|
} else { |
|
|
|
arrowRect = QRect( |
|
rect.right() - Metrics::MenuButton_IndicatorWidth, |
|
rect.top(), |
|
Metrics::MenuButton_IndicatorWidth, |
|
rect.height() ); |
|
|
|
} |
|
|
|
arrowRect = centerRect( arrowRect, Metrics::MenuButton_IndicatorWidth, Metrics::MenuButton_IndicatorWidth ); |
|
return handleRTL( option, arrowRect ); |
|
|
|
} |
|
|
|
case SC_ComboBoxEditField: |
|
{ |
|
|
|
// take out frame width |
|
if( !flat ) rect = insideMargin( rect, Metrics::Frame_FrameWidth ); |
|
|
|
QRect labelRect; |
|
const bool editable( comboBoxOption->editable ); |
|
|
|
if( editable ) |
|
{ |
|
|
|
labelRect = QRect( |
|
rect.left(), rect.top(), |
|
rect.width() - Metrics::MenuButton_IndicatorWidth, |
|
rect.height() ); |
|
|
|
// remove right side line editor margin |
|
if( !flat ) |
|
{ labelRect.adjust( Metrics::LineEdit_MarginWidth, Metrics::LineEdit_MarginWidth, 0, -Metrics::LineEdit_MarginWidth ); } |
|
|
|
} else { |
|
|
|
labelRect = QRect( |
|
rect.left(), rect.top(), |
|
rect.width() - Metrics::MenuButton_IndicatorWidth - Metrics::ComboBox_BoxTextSpace, |
|
rect.height() ); |
|
|
|
// remove right side button margin |
|
labelRect.adjust( Metrics::ComboBox_MarginWidth, Metrics::ComboBox_MarginWidth, 0, -Metrics::ComboBox_MarginWidth ); |
|
|
|
} |
|
|
|
return handleRTL( option, labelRect ); |
|
|
|
} |
|
|
|
default: break; |
|
|
|
} |
|
|
|
return KStyle::subControlRect( CC_ComboBox, option, subControl, widget ); |
|
|
|
} |
|
|
|
//___________________________________________________________________________________________________________________ |
|
QRect Style::spinBoxSubControlRect( const QStyleOptionComplex* option, SubControl subControl, const QWidget* widget ) const |
|
{ |
|
|
|
// cast option and check |
|
const QStyleOptionSpinBox *spinBoxOption( qstyleoption_cast<const QStyleOptionSpinBox*>( option ) ); |
|
if( !spinBoxOption ) return KStyle::subControlRect( CC_SpinBox, option, subControl, widget ); |
|
const bool flat( !spinBoxOption->frame ); |
|
|
|
// copy rect |
|
QRect rect( option->rect ); |
|
|
|
switch( subControl ) |
|
{ |
|
case SC_SpinBoxFrame: return flat ? QRect():rect; |
|
|
|
case SC_SpinBoxUp: |
|
case SC_SpinBoxDown: |
|
{ |
|
|
|
// take out frame width |
|
if( !flat ) rect = insideMargin( rect, Metrics::Frame_FrameWidth ); |
|
|
|
QRect arrowRect; |
|
arrowRect = QRect( |
|
rect.right() - Metrics::SpinBox_ArrowButtonWidth, |
|
rect.top(), |
|
Metrics::SpinBox_ArrowButtonWidth, |
|
rect.height() ); |
|
|
|
arrowRect = centerRect( arrowRect, Metrics::SpinBox_ArrowButtonWidth, Metrics::SpinBox_ArrowButtonWidth ); |
|
arrowRect.setHeight( Metrics::SpinBox_ArrowButtonWidth/2 ); |
|
if( subControl == SC_SpinBoxDown ) arrowRect.translate( 0, Metrics::SpinBox_ArrowButtonWidth/2 ); |
|
|
|
return handleRTL( option, arrowRect ); |
|
|
|
} |
|
|
|
case SC_SpinBoxEditField: |
|
{ |
|
|
|
// take out frame width |
|
if( !flat ) rect = insideMargin( rect, Metrics::Frame_FrameWidth ); |
|
|
|
QRect labelRect; |
|
labelRect = QRect( |
|
rect.left(), rect.top(), |
|
rect.width() - Metrics::SpinBox_ArrowButtonWidth, |
|
rect.height() ); |
|
|
|
// remove right side line editor margins |
|
if( !flat ) labelRect.adjust( Metrics::LineEdit_MarginWidth, Metrics::LineEdit_MarginWidth, 0, -Metrics::LineEdit_MarginWidth ); |
|
|
|
return handleRTL( option, labelRect ); |
|
|
|
} |
|
|
|
default: break; |
|
|
|
} |
|
|
|
return KStyle::subControlRect( CC_SpinBox, option, subControl, widget ); |
|
|
|
} |
|
|
|
//___________________________________________________________________________________________________________________ |
|
QRect Style::scrollBarInternalSubControlRect( const QStyleOptionComplex* option, SubControl subControl ) const |
|
{ |
|
|
|
const QRect& r = option->rect; |
|
const State& state( option->state ); |
|
const bool horizontal( state & 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 |
|
{ |
|
|
|
// cast option and check |
|
const QStyleOptionSlider* sliderOption( qstyleoption_cast<const QStyleOptionSlider*>( option ) ); |
|
if( !sliderOption ) return KStyle::subControlRect( CC_ScrollBar, option, subControl, widget ); |
|
|
|
// get relevant state |
|
const State& state( option->state ); |
|
const bool horizontal( state & State_Horizontal ); |
|
|
|
switch ( subControl ) |
|
{ |
|
|
|
case SC_ScrollBarSubLine: |
|
case SC_ScrollBarAddLine: |
|
return scrollBarInternalSubControlRect( option, subControl ); |
|
|
|
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: |
|
{ |
|
// We handle RTL 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 KStyle::subControlRect( CC_ScrollBar, option, subControl, widget );; |
|
} |
|
} |
|
|
|
//___________________________________________________________________________________________________________________ |
|
QRect Style::dialSubControlRect( const QStyleOptionComplex* option, SubControl subControl, const QWidget* widget ) const |
|
{ |
|
|
|
// cast option and check |
|
const QStyleOptionSlider* sliderOption( qstyleoption_cast<const QStyleOptionSlider*>( option ) ); |
|
if( !sliderOption ) return KStyle::subControlRect( CC_Dial, option, subControl, widget ); |
|
|
|
// adjust rect to be square, and centered |
|
QRect rect( option->rect ); |
|
const int dimension( qMin( rect.width(), rect.height() ) ); |
|
rect = centerRect( rect, dimension, dimension ); |
|
|
|
switch( subControl ) |
|
{ |
|
case QStyle::SC_DialGroove: return insideMargin( rect, (Metrics::Slider_ControlThickness - Metrics::Slider_Thickness)/2 ); |
|
case QStyle::SC_DialHandle: |
|
{ |
|
|
|
// calculate angle at which handle needs to be drawn |
|
const qreal angle( dialAngle( sliderOption, sliderOption->sliderPosition ) ); |
|
|
|
// groove rect |
|
const QRectF grooveRect( insideMargin( rect, Metrics::Slider_ControlThickness/2 ) ); |
|
qreal radius( grooveRect.width()/2 ); |
|
|
|
// slider center |
|
QPointF center( grooveRect.center() + QPointF( radius*std::cos( angle ), -radius*std::sin( angle ) ) ); |
|
|
|
// slider rect |
|
QRect handleRect( 0, 0, Metrics::Slider_ControlThickness, Metrics::Slider_ControlThickness ); |
|
handleRect.moveCenter( center.toPoint() ); |
|
return handleRect; |
|
|
|
} |
|
|
|
default: return KStyle::subControlRect( CC_Dial, option, subControl, widget );; |
|
|
|
} |
|
|
|
} |
|
|
|
//______________________________________________________________ |
|
QSize Style::checkBoxSizeFromContents( const QStyleOption*, const QSize& contentsSize, const QWidget* ) const |
|
{ |
|
// get contents size |
|
QSize size( contentsSize ); |
|
|
|
// add focus height |
|
size = expandSize( size, 0, Metrics::CheckBox_FocusMarginWidth ); |
|
|
|
// make sure there is enough height for indicator |
|
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::lineEditSizeFromContents( const QStyleOption* option, const QSize& contentsSize, const QWidget* ) const |
|
{ |
|
// cast option and check |
|
const QStyleOptionFrame* frameOption( qstyleoption_cast<const QStyleOptionFrame*>( option ) ); |
|
if( !frameOption ) return contentsSize; |
|
|
|
const bool flat( frameOption->lineWidth == 0 ); |
|
return flat ? contentsSize : expandSize( contentsSize, Metrics::LineEdit_MarginWidth + Metrics::Frame_FrameWidth ); |
|
} |
|
|
|
//______________________________________________________________ |
|
QSize Style::comboBoxSizeFromContents( const QStyleOption* option, const QSize& contentsSize, const QWidget* ) const |
|
{ |
|
|
|
// cast option and check |
|
const QStyleOptionComboBox* comboBoxOption( qstyleoption_cast<const QStyleOptionComboBox*>( option ) ); |
|
if( !comboBoxOption ) return contentsSize; |
|
|
|
const bool editable( comboBoxOption->editable ); |
|
const bool flat( !comboBoxOption->frame ); |
|
|
|
// copy size |
|
QSize size( contentsSize ); |
|
|
|
// add relevant margins |
|
if( editable && !flat ) size = expandSize( size, Metrics::LineEdit_MarginWidth ); |
|
else if( !editable ) size = expandSize( size, Metrics::ComboBox_MarginWidth ); |
|
|
|
// make sure there is enough height for the button |
|
size.setHeight( qMax( size.height(), (int)Metrics::MenuButton_IndicatorWidth ) ); |
|
|
|
// add button width and spacing |
|
size.rwidth() += Metrics::MenuButton_IndicatorWidth; |
|
if( !editable ) size.rwidth() += Metrics::ComboBox_BoxTextSpace; |
|
|
|
// add framewidth if needed |
|
return flat ? size : expandSize( size, Metrics::Frame_FrameWidth ); |
|
|
|
} |
|
|
|
//______________________________________________________________ |
|
QSize Style::spinBoxSizeFromContents( const QStyleOption* option, const QSize& contentsSize, const QWidget* ) const |
|
{ |
|
|
|
// cast option and check |
|
const QStyleOptionSpinBox *spinBoxOption( qstyleoption_cast<const QStyleOptionSpinBox*>( option ) ); |
|
if( !spinBoxOption ) return contentsSize; |
|
|
|
const bool flat( !spinBoxOption->frame ); |
|
|
|
// copy size |
|
QSize size( contentsSize ); |
|
|
|
// add editor margins |
|
if( !flat ) size = expandSize( size, Metrics::LineEdit_MarginWidth ); |
|
|
|
// make sure there is enough height for the button |
|
size.setHeight( qMax( size.height(), (int)Metrics::SpinBox_ArrowButtonWidth ) ); |
|
|
|
// add button width and spacing |
|
size.rwidth() += Metrics::SpinBox_ArrowButtonWidth; |
|
|
|
// add framewidth if needed |
|
return flat ? size : expandSize( size, Metrics::Frame_FrameWidth ); |
|
|
|
} |
|
|
|
//______________________________________________________________ |
|
QSize Style::pushButtonSizeFromContents( const QStyleOption* option, const QSize& contentsSize, const QWidget* widget ) const |
|
{ |
|
|
|
// cast option and check |
|
const QStyleOptionButton* buttonOption( qstyleoption_cast<const QStyleOptionButton*>( option ) ); |
|
if( !buttonOption ) return contentsSize; |
|
|
|
const bool flat( buttonOption->features & QStyleOptionButton::Flat ); |
|
|
|
QSize size( contentsSize ); |
|
|
|
// add space for arrow |
|
if( buttonOption->features & QStyleOptionButton::HasMenu ) |
|
{ |
|
size.rheight() += 2*Metrics::Button_MarginWidth; |
|
size.setHeight( qMax( size.height(), int( Metrics::MenuButton_IndicatorWidth ) ) ); |
|
size.rwidth() += Metrics::Button_MarginWidth; |
|
|
|
if( !( buttonOption->icon.isNull() && buttonOption->text.isEmpty() ) ) |
|
{ size.rwidth() += Metrics::Button_BoxTextSpace; } |
|
|
|
} else size = expandSize( size, Metrics::Button_MarginWidth ); |
|
|
|
// add space for icon |
|
if( !buttonOption->icon.isNull() ) |
|
{ |
|
|
|
QSize iconSize = buttonOption->iconSize; |
|
if( !iconSize.isValid() ) iconSize = QSize( pixelMetric( PM_SmallIconSize, option, widget ), pixelMetric( PM_SmallIconSize, option, widget ) ); |
|
|
|
size.setHeight( qMax( size.height(), iconSize.height() ) ); |
|
|
|
if( !buttonOption->text.isEmpty() ) |
|
{ size.rwidth() += Metrics::Button_BoxTextSpace; } |
|
|
|
} |
|
|
|
// finally add margins |
|
return flat ? size : expandSize( size, Metrics::Frame_FrameWidth ); |
|
|
|
} |
|
|
|
//______________________________________________________________ |
|
QSize Style::toolButtonSizeFromContents( const QStyleOption* option, const QSize& contentsSize, const QWidget* ) const |
|
{ |
|
|
|
// cast option and check |
|
const QStyleOptionToolButton* toolButtonOption = qstyleoption_cast<const QStyleOptionToolButton*>( option ); |
|
if( !toolButtonOption ) return contentsSize; |
|
|
|
// copy size |
|
QSize size = contentsSize; |
|
|
|
// get relevant state flags |
|
const State& state( option->state ); |
|
const bool autoRaise( state & State_AutoRaise ); |
|
const bool hasPopupMenu( toolButtonOption->subControls & SC_ToolButtonMenu ); |
|
const bool hasInlineIndicator( toolButtonOption->features & QStyleOptionToolButton::HasMenu && !hasPopupMenu ); |
|
const int marginWidth( autoRaise ? Metrics::ToolButton_MarginWidth : Metrics::Button_MarginWidth + Metrics::Frame_FrameWidth ); |
|
|
|
if( hasInlineIndicator ) size.rwidth() += Metrics::ToolButton_BoxTextSpace; |
|
size = expandSize( size, marginWidth ); |
|
|
|
return size; |
|
} |
|
|
|
//______________________________________________________________ |
|
QSize Style::menuBarItemSizeFromContents( const QStyleOption*, const QSize& contentsSize, const QWidget* ) const |
|
{ return expandSize( contentsSize, Metrics::MenuBarItem_MarginWidth, Metrics::MenuBarItem_MarginHeight ); } |
|
|
|
|
|
//______________________________________________________________ |
|
QSize Style::menuItemSizeFromContents( const QStyleOption* option, const QSize& contentsSize, const QWidget* widget ) const |
|
{ |
|
|
|
// cast option and check |
|
const QStyleOptionMenuItem* menuItemOption = qstyleoption_cast<const QStyleOptionMenuItem*>( option ); |
|
if( !menuItemOption ) return contentsSize; |
|
|
|
// First, we calculate the intrinsic size of the item. |
|
// this must be kept consistent with what's in drawMenuItemControl |
|
QSize size( contentsSize ); |
|
switch ( menuItemOption->menuItemType ) |
|
{ |
|
|
|
case QStyleOptionMenuItem::Normal: |
|
case QStyleOptionMenuItem::DefaultItem: |
|
case QStyleOptionMenuItem::SubMenu: |
|
{ |
|
|
|
const int iconWidth( qMax( menuItemOption->maxIconWidth, pixelMetric( PM_SmallIconSize, option, widget ) ) ); |
|
int leftColumnWidth( iconWidth ); |
|
|
|
// add space with respect to text |
|
leftColumnWidth += Metrics::MenuItem_BoxTextSpace; |
|
|
|
// add checkbox indicator width |
|
if( menuItemOption->menuHasCheckableItems ) |
|
{ leftColumnWidth += Metrics::CheckBox_Size + Metrics::MenuItem_BoxTextSpace; } |
|
|
|
// add spacing for accelerator |
|
/* |
|
Note: |
|
The width of the accelerator itself is not included here since |
|
Qt will add that on separately after obtaining the |
|
sizeFromContents() for each menu item in the menu to be shown |
|
( see QMenuPrivate::calcActionRects() ) |
|
*/ |
|
const bool hasAccelerator( menuItemOption->text.indexOf( QLatin1Char( '\t' ) ) >= 0 ); |
|
if( hasAccelerator ) size.rwidth() += Metrics::MenuItem_BoxTextSpace; |
|
|
|
// right column |
|
const int rightColumnWidth = Metrics::MenuButton_IndicatorWidth + Metrics::MenuItem_BoxTextSpace; |
|
size.rwidth() += leftColumnWidth + rightColumnWidth; |
|
|
|
// make sure height is large enough for icon and arrow |
|
size.setHeight( qMax( size.height(), (int) Metrics::MenuButton_IndicatorWidth ) ); |
|
size.setHeight( qMax( size.height(), (int) Metrics::CheckBox_Size ) ); |
|
size.setHeight( qMax( size.height(), (int) iconWidth ) ); |
|
return expandSize( size, Metrics::MenuItem_MarginWidth ); |
|
|
|
} |
|
|
|
case QStyleOptionMenuItem::Separator: |
|
{ |
|
|
|
if( menuItemOption->text.isEmpty() && menuItemOption->icon.isNull() ) |
|
{ |
|
|
|
return expandSize( QSize(0,1), Metrics::MenuItem_MarginWidth ); |
|
|
|
|
|
} else { |
|
|
|
// separator can have a title and an icon |
|
// in that case they are rendered as menubar 'title', which |
|
// corresponds to checked toolbuttons. |
|
// a rectangle identical to the one of normal items is returned. |
|
QStyleOptionMenuItem copy( *menuItemOption ); |
|
copy.menuItemType = QStyleOptionMenuItem::Normal; |
|
return menuItemSizeFromContents( ©, contentsSize, widget ); |
|
|
|
} |
|
|
|
} |
|
|
|
// for all other cases, return input |
|
default: return contentsSize; |
|
} |
|
|
|
} |
|
|
|
//______________________________________________________________ |
|
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& state( option->state ); |
|
const bool horizontal( state & 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; |
|
|
|
} |
|
|
|
//______________________________________________________________ |
|
QSize Style::headerSectionSizeFromContents( const QStyleOption* option, const QSize& contentsSize, const QWidget* ) const |
|
{ |
|
|
|
// cast option and check |
|
const QStyleOptionHeader* headerOption( qstyleoption_cast<const QStyleOptionHeader*>( 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_ArrowSize + Metrics::Header_BoxTextSpace; |
|
contentsHeight = qMax( contentsHeight, (int) Metrics::Header_ArrowSize ); |
|
} |
|
|
|
// update contents size, add margins and return |
|
const QSize size( contentsSize.expandedTo( QSize( contentsWidth, contentsHeight ) ) ); |
|
return expandSize( size, Metrics::Header_MarginWidth ); |
|
|
|
} |
|
|
|
//______________________________________________________________ |
|
QSize Style::itemViewItemSizeFromContents( const QStyleOption* option, const QSize& contentsSize, const QWidget* widget ) const |
|
{ |
|
// call base class |
|
QSize size( KStyle::sizeFromContents( CT_ItemViewItem, option, contentsSize, widget ) ); |
|
|
|
// add margins |
|
return expandSize( size, Metrics::ItemView_ItemMarginWidth ); |
|
|
|
} |
|
|
|
//______________________________________________________________ |
|
QSize Style::tabWidgetSizeFromContents( const QStyleOption* option, const QSize& contentsSize, const QWidget* ) const |
|
{ |
|
|
|
// cast option and check |
|
const QStyleOptionTabWidgetFrame* tabOption = qstyleoption_cast<const QStyleOptionTabWidgetFrame*>( option ); |
|
if( !tabOption ) return expandSize( contentsSize, Metrics::Frame_FrameWidth ); |
|
|
|
// tab orientation |
|
const bool verticalTabs( tabOption && isVerticalTab( tabOption->shape ) ); |
|
|
|
// need to reduce the size in the tabbar direction, due to a bug in QTabWidget::minimumSize |
|
return verticalTabs ? |
|
expandSize( contentsSize, Metrics::Frame_FrameWidth, Metrics::Frame_FrameWidth - 1 ): |
|
expandSize( contentsSize, Metrics::Frame_FrameWidth - 1, Metrics::Frame_FrameWidth ); |
|
|
|
} |
|
|
|
//______________________________________________________________ |
|
QSize Style::tabBarTabSizeFromContents( const QStyleOption* option, const QSize& contentsSize, const QWidget* ) const |
|
{ |
|
const QStyleOptionTab *tabOption( qstyleoption_cast<const QStyleOptionTab*>( option ) ); |
|
|
|
// add margins |
|
QSize size( contentsSize ); |
|
|
|
// compare to minimum size |
|
const bool verticalTabs( tabOption && isVerticalTab( tabOption ) ); |
|
if( verticalTabs ) |
|
{ |
|
|
|
size = expandSize( size, Metrics::TabBar_TabMarginHeight, Metrics::TabBar_TabMarginWidth ); |
|
size = size.expandedTo( QSize( Metrics::TabBar_TabMinHeight, Metrics::TabBar_TabMinWidth ) ); |
|
|
|
} else { |
|
|
|
size = expandSize( size, Metrics::TabBar_TabMarginWidth, Metrics::TabBar_TabMarginHeight ); |
|
size = size.expandedTo( QSize( Metrics::TabBar_TabMinWidth, Metrics::TabBar_TabMinHeight ) ); |
|
|
|
} |
|
|
|
return size; |
|
|
|
} |
|
|
|
//______________________________________________________________ |
|
bool Style::drawFramePrimitive( const QStyleOption* option, QPainter* painter, const QWidget* widget ) const |
|
{ |
|
|
|
const State& state( option->state ); |
|
|
|
// do nothing for flat frames |
|
const bool isTitleWidget( widget && widget->parent() && widget->parent()->inherits( "KTitleWidget" ) ); |
|
|
|
if( !isTitleWidget && !( state & (State_Sunken | State_Raised ) ) ) return true; |
|
|
|
const bool isQtQuickControl = !widget && option && option->styleObject && option->styleObject->inherits( "QQuickStyleItem" ); |
|
const bool isInputWidget( ( widget && widget->testAttribute( Qt::WA_Hover ) ) || |
|
( isQtQuickControl && option->styleObject->property( "elementType" ).toString() == QStringLiteral( "edit") ) ); |
|
|
|
const QPalette& palette( option->palette ); |
|
const bool enabled( state & State_Enabled ); |
|
const bool mouseOver( enabled && isInputWidget && ( state & State_MouseOver ) ); |
|
const bool hasFocus( enabled && ( state & State_HasFocus ) ); |
|
|
|
// focus takes precedence over mouse over |
|
_animations->lineEditEngine().updateState( widget, AnimationFocus, hasFocus ); |
|
_animations->lineEditEngine().updateState( widget, AnimationHover, mouseOver && !hasFocus ); |
|
|
|
// retrieve animation mode and opacity |
|
const AnimationMode mode( _animations->lineEditEngine().frameAnimationMode( widget ) ); |
|
const qreal opacity( _animations->lineEditEngine().frameOpacity( widget ) ); |
|
|
|
// update frame shadow factory |
|
if( _frameShadowFactory->isRegistered( widget ) ) |
|
{ _frameShadowFactory->updateState( widget, hasFocus, mouseOver, opacity, mode ); } |
|
|
|
// render |
|
const QColor background( isTitleWidget ? palette.color( widget->backgroundRole() ):QColor() ); |
|
const QColor outline( _helper->frameOutlineColor( option->palette, mouseOver, hasFocus, opacity, mode ) ); |
|
_helper->renderFrame( painter, option->rect, background, outline, hasFocus ); |
|
|
|
return true; |
|
|
|
} |
|
|
|
//___________________________________________________________________________________ |
|
bool Style::drawFrameMenuPrimitive( const QStyleOption* option, QPainter* painter, const QWidget* widget ) const |
|
{ |
|
|
|
const QPalette& palette( option->palette ); |
|
const QColor background( _helper->frameBackgroundColor( palette ) ); |
|
const QColor outline( _helper->frameOutlineColor( palette ) ); |
|
|
|
const bool hasAlpha( _helper->hasAlphaChannel( widget ) ); |
|
if( hasAlpha ) |
|
{ |
|
|
|
painter->setCompositionMode( QPainter::CompositionMode_Source ); |
|
_helper->renderMenuFrame( painter, option->rect, background, outline, true ); |
|
|
|
} else { |
|
|
|
_helper->renderMenuFrame( painter, option->rect, background, outline, false ); |
|
|
|
} |
|
|
|
return true; |
|
|
|
} |
|
|
|
//______________________________________________________________ |
|
bool Style::drawFrameGroupBoxPrimitive( const QStyleOption* option, QPainter* painter, const QWidget* ) const |
|
{ |
|
|
|
// cast option and check |
|
const QStyleOptionFrame *frameOption( qstyleoption_cast<const QStyleOptionFrame*>( option ) ); |
|
if( !frameOption ) return true; |
|
|
|
// no frame for flat groupboxes |
|
QStyleOptionFrameV2 frameOption2( *frameOption ); |
|
if( frameOption2.features & QStyleOptionFrameV2::Flat ) return true; |
|
|
|
// normal frame |
|
const QPalette& palette( option->palette ); |
|
const QColor background( palette.color( QPalette::Window ) ); |
|
const QColor outline( _helper->frameOutlineColor( palette ) ); |
|
|
|
_helper->renderFrame( painter, option->rect, background, outline ); |
|
|
|
return true; |
|
|
|
} |
|
|
|
//___________________________________________________________________________________ |
|
bool Style::drawFrameTabWidgetPrimitive( const QStyleOption* option, QPainter* painter, const QWidget* ) const |
|
{ |
|
|
|
// tabwidget frame |
|
// cast option and check |
|
const QStyleOptionTabWidgetFrame* tabOption( qstyleoption_cast<const QStyleOptionTabWidgetFrame*>( option ) ); |
|
if( !tabOption ) return true; |
|
|
|
// do nothing if tabbar is hidden |
|
if( tabOption->tabBarSize.isEmpty() ) return true; |
|
|
|
// adjust rect to handle overlaps |
|
QRect rect( option->rect ); |
|
|
|
const QSize tabBarSize( tabOption->tabBarSize ); |
|
Helper::Corners corners = Helper::CornersAll; |
|
|
|
// adjust corners to deal with oversized tabbars |
|
switch( tabOption->shape ) |
|
{ |
|
case QTabBar::RoundedNorth: |
|
case QTabBar::TriangularNorth: |
|
if( tabBarSize.width() >= rect.width()-2*Metrics::TabBar_TabRadius ) corners &= ~Helper::CornersTop; |
|
break; |
|
|
|
case QTabBar::RoundedSouth: |
|
case QTabBar::TriangularSouth: |
|
if( tabBarSize.width() >= rect.width()-2*Metrics::TabBar_TabRadius ) corners &= ~Helper::CornersBottom; |
|
break; |
|
|
|
case QTabBar::RoundedWest: |
|
case QTabBar::TriangularWest: |
|
if( tabBarSize.height() >= rect.height()-2*Metrics::TabBar_TabRadius ) corners &= ~Helper::CornersLeft; |
|
break; |
|
|
|
case QTabBar::RoundedEast: |
|
case QTabBar::TriangularEast: |
|
if( tabBarSize.height() >= rect.height()-2*Metrics::TabBar_TabRadius ) corners &= ~Helper::CornersRight; |
|
break; |
|
|
|
default: break; |
|
} |
|
|
|
// define colors |
|
const QPalette& palette( option->palette ); |
|
const QColor background( palette.color( QPalette::Window ) ); |
|
const QColor outline( _helper->frameOutlineColor( palette ) ); |
|
_helper->renderTabWidgetFrame( painter, rect, background, outline, corners ); |
|
|
|
return true; |
|
} |
|
|
|
//___________________________________________________________________________________ |
|
bool Style::drawFrameTabBarBasePrimitive( const QStyleOption* option, QPainter* painter, const QWidget* ) const |
|
{ |
|
|
|
/* |
|
tabbar frame |
|
used either for 'separate' tabbar, or in 'document mode' |
|
*/ |
|
|
|
// cast option and check |
|
const QStyleOptionTabBarBase* tabOption( qstyleoption_cast<const QStyleOptionTabBarBase*>( option ) ); |
|
if( !tabOption ) return true; |
|
|
|
// get rect, orientation, palette |
|
const QRect rect( option->rect ); |
|
const QColor outline( _helper->frameOutlineColor( option->palette ) ); |
|
|
|
// setup painter |
|
painter->setBrush( Qt::NoBrush ); |
|
painter->setRenderHint( QPainter::Antialiasing, false ); |
|
painter->setPen( QPen( outline, 1 ) ); |
|
|
|
// render |
|
switch( tabOption->shape ) |
|
{ |
|
case QTabBar::RoundedNorth: |
|
case QTabBar::TriangularNorth: |
|
painter->drawLine( rect.bottomLeft(), rect.bottomRight() ); |
|
break; |
|
|
|
case QTabBar::RoundedSouth: |
|
case QTabBar::TriangularSouth: |
|
painter->drawLine( rect.topLeft(), rect.topRight() ); |
|
break; |
|
|
|
case QTabBar::RoundedWest: |
|
case QTabBar::TriangularWest: |
|
painter->drawLine( rect.topRight(), rect.bottomRight() ); |
|
break; |
|
|
|
case QTabBar::RoundedEast: |
|
case QTabBar::TriangularEast: |
|
painter->drawLine( rect.topLeft(), rect.bottomLeft() ); |
|
break; |
|
|
|
default: |
|
break; |
|
|
|
} |
|
|
|
return true; |
|
|
|
} |
|
|
|
//___________________________________________________________________________________ |
|
bool Style::drawFrameWindowPrimitive( const QStyleOption* option, QPainter* painter, const QWidget* ) const |
|
{ |
|
|
|
// copy rect and palette |
|
const QRect& rect( option->rect ); |
|
const QPalette& palette( option->palette ); |
|
const State state( option->state ); |
|
const bool selected( state & State_Selected ); |
|
|
|
// render frame outline |
|
const QColor outline( _helper->frameOutlineColor( palette, false, selected ) ); |
|
_helper->renderMenuFrame( painter, rect, QColor(), outline ); |
|
|
|
return true; |
|
|
|
} |
|
|
|
//___________________________________________________________________________________ |
|
bool Style::drawIndicatorArrowPrimitive( ArrowOrientation orientation, const QStyleOption* option, QPainter* painter, const QWidget* ) const |
|
{ |
|
|
|
// store rect and palette |
|
const QRectF rect( option->rect ); |
|
const QPalette& palette( option->palette ); |
|
|
|
// store state |
|
const State& state( option->state ); |
|
const bool enabled( state & State_Enabled ); |
|
bool mouseOver( enabled && ( state & State_MouseOver ) ); |
|
|
|
// color |
|
QColor color; |
|
if( mouseOver ) color = _helper->hoverColor( palette ); |
|
else color = palette.color( QPalette::WindowText ); |
|
|
|
// arrow |
|
const QPolygonF arrow( genericArrow( orientation, ArrowNormal ) ); |
|
const qreal penThickness = 1.5; |
|
|
|
painter->setRenderHint( QPainter::Antialiasing ); |
|
painter->translate( rect.center() ); |
|
painter->setPen( QPen( color, penThickness ) ); |
|
painter->drawPolyline( arrow ); |
|
|
|
return true; |
|
} |
|
|
|
//___________________________________________________________________________________ |
|
bool Style::drawIndicatorHeaderArrowPrimitive( const QStyleOption* option, QPainter* painter, const QWidget* ) const |
|
{ |
|
const QStyleOptionHeader *headerOption( qstyleoption_cast<const QStyleOptionHeader*>( option ) ); |
|
const State& state( option->state ); |
|
|
|
// arrow orientation |
|
ArrowOrientation orientation( ArrowNone ); |
|
if( state & State_UpArrow || ( headerOption && headerOption->sortIndicator==QStyleOptionHeader::SortUp ) ) orientation = ArrowUp; |
|
else if( state & State_DownArrow || ( headerOption && headerOption->sortIndicator==QStyleOptionHeader::SortDown ) ) orientation = ArrowDown; |
|
if( orientation == ArrowNone ) return true; |
|
|
|
// state, rect and palette |
|
const QRectF& rect( option->rect ); |
|
const QPalette& palette( option->palette ); |
|
|
|
// define color and polygon for drawing arrow |
|
const QPolygonF arrow( genericArrow( orientation, ArrowNormal ) ); |
|
const QColor color = palette.color( QPalette::WindowText ); |
|
const qreal penThickness = 1.5; |
|
|
|
// render arrow |
|
painter->setRenderHint( QPainter::Antialiasing ); |
|
painter->setPen( QPen( color, penThickness ) ); |
|
painter->setBrush( Qt::NoBrush ); |
|
painter->translate( rect.center() ); |
|
painter->drawPolyline( arrow ); |
|
|
|
return true; |
|
} |
|
|
|
//______________________________________________________________ |
|
bool Style::drawPanelButtonCommandPrimitive( const QStyleOption* option, QPainter* painter, const QWidget* widget ) const |
|
{ |
|
|
|
// cast option and check |
|
const QStyleOptionButton* buttonOption( qstyleoption_cast< const QStyleOptionButton* >( option ) ); |
|
if( !buttonOption ) return true; |
|
|
|
// rect and palette |
|
const QRect& rect( option->rect ); |
|
|
|
// button state |
|
const State& state( option->state ); |
|
const bool enabled( state & State_Enabled ); |
|
const bool mouseOver( enabled && ( state & State_MouseOver ) ); |
|
const bool hasFocus( enabled && ( state & State_HasFocus ) ); |
|
const bool sunken( state & ( State_On|State_Sunken ) ); |
|
const bool flat( buttonOption->features & QStyleOptionButton::Flat ); |
|
|
|
// update animation state |
|
// mouse over takes precedence over focus |
|
_animations->widgetStateEngine().updateState( widget, AnimationHover, mouseOver ); |
|
_animations->widgetStateEngine().updateState( widget, AnimationFocus, hasFocus && !mouseOver ); |
|
|
|
const AnimationMode mode( _animations->widgetStateEngine().buttonAnimationMode( widget ) ); |
|
const qreal opacity( _animations->widgetStateEngine().buttonOpacity( widget ) ); |
|
|
|
if( flat ) |
|
{ |
|
|
|
// define colors and render |
|
const QPalette& palette( option->palette ); |
|
const QColor color( _helper->toolButtonColor( palette, mouseOver, hasFocus || sunken, opacity, mode ) ); |
|
_helper->renderToolButtonFrame( painter, rect, color, sunken ); |
|
|
|
} else { |
|
|
|
// update button color from palette in case button is default |
|
QPalette palette( option->palette ); |
|
if( enabled && buttonOption->features & QStyleOptionButton::DefaultButton ) |
|
{ |
|
const QColor button( palette.color( QPalette::Button ) ); |
|
const QColor base( palette.color( QPalette::Base ) ); |
|
palette.setColor( QPalette::Button, KColorUtils::mix( button, base, 0.7 ) ); |
|
} |
|
|
|
const QColor shadow( _helper->shadowColor( palette ) ); |
|
const QColor outline( _helper->buttonOutlineColor( palette, mouseOver, hasFocus, opacity, mode ) ); |
|
const QColor background( _helper->buttonBackgroundColor( palette, mouseOver, hasFocus, opacity, mode ) ); |
|
|
|
// render |
|
_helper->renderButtonFrame( painter, rect, background, outline, shadow, hasFocus, sunken ); |
|
|
|
} |
|
|
|
return true; |
|
|
|
} |
|
|
|
//______________________________________________________________ |
|
bool Style::drawPanelButtonToolPrimitive( const QStyleOption* option, QPainter* painter, const QWidget* widget ) const |
|
{ |
|
|
|
/* |
|
For toolbutton in TabBars, corresponding to expanding arrows, no frame is drawn |
|
However one needs to draw the window background, because the button rect might |
|
overlap with some tab below. ( this is a Qt bug ) |
|
*/ |
|
if( const QTabBar* tabBar = qobject_cast<const QTabBar*>( widget->parent() ) ) |
|
{ |
|
QRect rect( option->rect ); |
|
|
|
// overlap. |
|
// subtract 1, because of the empty pixel left the tabwidget frame |
|
const int overlap( Metrics::TabBar_BaseOverlap - 1 ); |
|
|
|
// adjust rect based on tabbar shape |
|
switch( tabBar->shape() ) |
|
{ |
|
case QTabBar::RoundedNorth: |
|
case QTabBar::TriangularNorth: |
|
rect.adjust( 0, 0, 0, -overlap ); |
|
break; |
|
|
|
case QTabBar::RoundedSouth: |
|
case QTabBar::TriangularSouth: |
|
rect.adjust( 0, overlap, 0, 0 ); |
|
break; |
|
|
|
case QTabBar::RoundedWest: |
|
case QTabBar::TriangularWest: |
|
rect.adjust( 0, 0, -overlap, 0 ); |
|
break; |
|
|
|
case QTabBar::RoundedEast: |
|
case QTabBar::TriangularEast: |
|
rect.adjust( overlap, 0, 0, 0 ); |
|
break; |
|
|
|
default: break; |
|
|
|
} |
|
|
|
// get the relevant palette |
|
const QWidget* parent( tabBar->parentWidget() ); |
|
if( qobject_cast<const QTabWidget*>( parent ) ) |
|
{ parent = parent->parentWidget(); } |
|
const QPalette palette( parent ? parent->palette() : QGuiApplication::palette() ); |
|
|
|
// render flat background |
|
painter->setPen( Qt::NoPen ); |
|
painter->setBrush( palette.color( QPalette::Window ) ); |
|
painter->drawRect( rect ); |
|
|
|
return true; |
|
|
|
} |
|
|
|
// copy palette and rect |
|
const QPalette& palette( option->palette ); |
|
QRect rect( option->rect ); |
|
|
|
// store relevant flags |
|
const State& state( option->state ); |
|
const bool autoRaise( state & State_AutoRaise ); |
|
const bool enabled( state & State_Enabled ); |
|
const bool sunken( ( state & State_On ) || ( state & State_Sunken ) ); |
|
const bool mouseOver( enabled && (option->state & State_MouseOver) ); |
|
const bool hasFocus( enabled && (option->state & State_HasFocus) ); |
|
|
|
if( !autoRaise ) |
|
{ |
|
|
|
/* need to check widget for popup mode, because option is not set properly */ |
|
const QToolButton* toolButton( qobject_cast<const QToolButton*>( widget ) ); |
|
const bool hasPopupMenu( toolButton && toolButton->popupMode() == QToolButton::MenuButtonPopup ); |
|
|
|
// render as push button |
|
const QColor shadow( _helper->shadowColor( palette ) ); |
|
const QColor outline( _helper->buttonOutlineColor( palette, mouseOver, hasFocus ) ); |
|
const QColor background( _helper->buttonBackgroundColor( palette, mouseOver, hasFocus ) ); |
|
|
|
// adjust frame in case of menu |
|
if( hasPopupMenu ) |
|
{ |
|
painter->setClipRect( rect ); |
|
rect.adjust( 0, 0, Metrics::Frame_FrameRadius, 0 ); |
|
rect = handleRTL( option, rect ); |
|
} |
|
|
|
// render |
|
_helper->renderButtonFrame( painter, rect, background, outline, shadow, hasFocus, sunken ); |
|
|
|
} else { |
|
|
|
const QColor color( _helper->toolButtonColor( palette, mouseOver, hasFocus || sunken ) ); |
|
_helper->renderToolButtonFrame( painter, rect, color, sunken ); |
|
|
|
} |
|
|
|
return true; |
|
} |
|
|
|
//___________________________________________________________________________________ |
|
bool Style::drawPanelScrollAreaCornerPrimitive( const QStyleOption* option, QPainter* painter, const QWidget* widget ) const |
|
{ |
|
|
|
// make sure background role matches viewport |
|
const QAbstractScrollArea* scrollArea; |
|
if( ( scrollArea = qobject_cast<const QAbstractScrollArea*>( widget ) ) && scrollArea->viewport() ) |
|
{ |
|
|
|
painter->setBrush( option->palette.color( scrollArea->viewport()->backgroundRole() ) ); |
|
painter->setPen( Qt::NoPen ); |
|
painter->drawRect( option->rect ); |
|
return true; |
|
|
|
} else { |
|
|
|
return false; |
|
|
|
} |
|
|
|
} |
|
//___________________________________________________________________________________ |
|
bool Style::drawPanelMenuPrimitive( const QStyleOption* option, QPainter* painter, const QWidget* widget ) const |
|
{ |
|
|
|
// do nothing if menu is embedded in another widget |
|
// this corresponds to having a transparent background |
|
if( widget && !widget->isWindow() ) return true; |
|
|
|
const QPalette& palette( option->palette ); |
|
const QColor background( _helper->frameBackgroundColor( palette ) ); |
|
const QColor outline( _helper->frameOutlineColor( palette ) ); |
|
|
|
const bool hasAlpha( _helper->hasAlphaChannel( widget ) ); |
|
if( hasAlpha ) |
|
{ |
|
|
|
painter->setCompositionMode( QPainter::CompositionMode_Source ); |
|
_helper->renderMenuFrame( painter, option->rect, background, outline, true ); |
|
|
|
} else { |
|
|
|
_helper->renderMenuFrame( painter, option->rect, background, outline, false ); |
|
|
|
} |
|
|
|
return true; |
|
|
|
} |
|
|
|
//___________________________________________________________________________________ |
|
bool Style::drawPanelTipLabelPrimitive( const QStyleOption* option, QPainter* painter, const QWidget* widget ) const |
|
{ |
|
|
|
// force registration of widget |
|
if( widget && widget->window() ) |
|
{ _shadowHelper->registerWidget( widget->window(), true ); } |
|
|
|
const QPalette& palette( option->palette ); |
|
const QColor background( palette.color( QPalette::ToolTipBase ) ); |
|
const QColor outline( KColorUtils::mix( palette.color( QPalette::ToolTipBase ), palette.color( QPalette::ToolTipText ), 0.25 ) ); |
|
|
|
const bool hasAlpha( _helper->hasAlphaChannel( widget ) ); |
|
if( hasAlpha ) |
|
{ |
|
|
|
painter->setCompositionMode( QPainter::CompositionMode_Source ); |
|
_helper->renderMenuFrame( painter, option->rect, background, outline, true ); |
|
|
|
} else { |
|
|
|
_helper->renderMenuFrame( painter, option->rect, background, outline, false ); |
|
|
|
} |
|
|
|
return true; |
|
|
|
} |
|
|
|
//___________________________________________________________________________________ |
|
bool Style::drawPanelItemViewItemPrimitive( const QStyleOption* option, QPainter* painter, const QWidget* widget ) const |
|
{ |
|
|
|
// cast option and check |
|
const QStyleOptionViewItem *viewItemOption = qstyleoption_cast<const QStyleOptionViewItem*>( option ); |
|
if( !viewItemOption ) return false; |
|
|
|
// try cast widget |
|
const QAbstractItemView *abstractItemView = qobject_cast<const QAbstractItemView *>( widget ); |
|
|
|
// store palette and rect |
|
const QPalette& palette( option->palette ); |
|
const QRect& rect( option->rect ); |
|
|
|
// store flags |
|
const State& state( option->state ); |
|
const bool mouseOver( ( state & State_MouseOver ) && ( !abstractItemView || abstractItemView->selectionMode() != QAbstractItemView::NoSelection ) ); |
|
const bool selected( state & State_Selected ); |
|
const bool enabled( state & State_Enabled ); |
|
const bool active( state & State_Active ); |
|
|
|
const bool hasCustomBackground = viewItemOption->backgroundBrush.style() != Qt::NoBrush && !( state & State_Selected ); |
|
const bool hasSolidBackground = !hasCustomBackground || viewItemOption->backgroundBrush.style() == Qt::SolidPattern; |
|
const bool hasAlternateBackground( viewItemOption->features & QStyleOptionViewItemV2::Alternate ); |
|
|
|
// do nothing if no background is to be rendered |
|
if( !( mouseOver || selected || hasCustomBackground || hasAlternateBackground ) ) |
|
{ return true; } |
|
|
|
// define color group |
|
QPalette::ColorGroup colorGroup; |
|
if( enabled ) colorGroup = active ? QPalette::Normal : QPalette::Inactive; |
|
else colorGroup = QPalette::Disabled; |
|
|
|
// render alternate background |
|
if( viewItemOption && ( viewItemOption->features & QStyleOptionViewItemV2::Alternate ) ) |
|
{ |
|
painter->setPen( Qt::NoPen ); |
|
painter->setBrush( palette.brush( colorGroup, QPalette::AlternateBase ) ); |
|
painter->drawRect( rect ); |
|
} |
|
|
|
// stop here if no highlight is needed |
|
if( !( mouseOver || selected ||hasCustomBackground ) ) |
|
{ return true; } |
|
|
|
// render custom background |
|
if( hasCustomBackground && !hasSolidBackground ) |
|
{ |
|
|
|
painter->setBrushOrigin( viewItemOption->rect.topLeft() ); |
|
painter->setBrush( viewItemOption->backgroundBrush ); |
|
painter->setPen( Qt::NoPen ); |
|
painter->drawRect( viewItemOption->rect ); |
|
return true; |
|
|
|
} |
|
|
|
// render selection |
|
// define color |
|
QColor color; |
|
if( hasCustomBackground && hasSolidBackground ) color = viewItemOption->backgroundBrush.color(); |
|
else color = palette.color( colorGroup, QPalette::Highlight ); |
|
|
|
// change color to implement mouse over |
|
if( mouseOver && !hasCustomBackground ) |
|
{ |
|
if( !selected ) color.setAlphaF( 0.2 ); |
|
else color = color.lighter( 110 ); |
|
} |
|
|
|
// get selection path |
|
Helper::Corners corners; |
|
const bool hasSingleSelection( abstractItemView && abstractItemView->selectionMode() == QAbstractItemView::SingleSelection ); |
|
if( hasSingleSelection ) |
|
{ |
|
|
|
// round relevant corners |
|
if( |
|
viewItemOption->viewItemPosition == QStyleOptionViewItemV4::OnlyOne || |
|
viewItemOption->viewItemPosition == QStyleOptionViewItemV4::Invalid || |
|
( abstractItemView && abstractItemView->selectionBehavior() != QAbstractItemView::SelectRows ) ) |
|
{ |
|
|
|
corners = Helper::CornersAll; |
|
|
|
} else { |
|
|
|
if( viewItemOption->viewItemPosition == QStyleOptionViewItemV4::Beginning ) corners |= Helper::CornersLeft; |
|
if( viewItemOption->viewItemPosition == QStyleOptionViewItemV4::Beginning ) corners |= Helper::CornersRight; |
|
|
|
} |
|
|
|
} |
|
|
|
// render |
|
_helper->renderSelection( painter, rect, color, corners ); |
|
|
|
return true; |
|
} |
|
|
|
//___________________________________________________________________________________ |
|
bool Style::drawIndicatorCheckBoxPrimitive( const QStyleOption* option, QPainter* painter, const QWidget* widget ) const |
|
{ |
|
|
|
// get rect |
|
const State& state( option->state ); |
|
const bool enabled( state & State_Enabled ); |
|
const bool mouseOver( enabled && ( state & State_MouseOver ) ); |
|
const bool sunken( enabled && ( state & State_Sunken ) ); |
|
const bool active( ( state & (State_On|State_NoChange) ) ); |
|
|
|
// checkbox state |
|
Helper::CheckBoxState checkBoxState( Helper::CheckOff ); |
|
if( state & State_NoChange ) checkBoxState = Helper::CheckPartial; |
|
else if( state & State_On ) checkBoxState = Helper::CheckOn; |
|
|
|
// animation state |
|
_animations->widgetStateEngine().updateState( widget, AnimationHover, mouseOver ); |
|
const AnimationMode mode( _animations->widgetStateEngine().isAnimated( widget, AnimationHover ) ? AnimationHover:AnimationNone ); |
|
const qreal opacity( _animations->widgetStateEngine().opacity( widget, AnimationHover ) ); |
|
|
|
// colors |
|
const QPalette& palette( option->palette ); |
|
const QColor color( _helper->checkBoxIndicatorColor( palette, mouseOver, enabled && active, opacity, mode ) ); |
|
const QColor shadow( _helper->shadowColor( palette ) ); |
|
|
|
// render |
|
_helper->renderCheckBox( painter, option->rect, color, shadow, sunken, checkBoxState ); |
|
|
|
return true; |
|
|
|
} |
|
|
|
//___________________________________________________________________________________ |
|
bool Style::drawIndicatorRadioButtonPrimitive( const QStyleOption* option, QPainter* painter, const QWidget* widget ) const |
|
{ |
|
|
|
// get rect |
|
const State& state( option->state ); |
|
const bool enabled( state & State_Enabled ); |
|
const bool mouseOver( enabled && ( state & State_MouseOver ) ); |
|
const bool sunken( state & State_Sunken ); |
|
const bool checked( state & State_On ); |
|
|
|
// update only mouse over |
|
_animations->widgetStateEngine().updateState( widget, AnimationHover, mouseOver ); |
|
const AnimationMode mode( _animations->widgetStateEngine().isAnimated( widget, AnimationHover ) ? AnimationHover:AnimationNone ); |
|
const qreal opacity( _animations->widgetStateEngine().opacity( widget, AnimationHover ) ); |
|
|
|
// colors |
|
const QPalette& palette( option->palette ); |
|
const QColor color( _helper->checkBoxIndicatorColor( palette, mouseOver, enabled && checked, opacity, mode ) ); |
|
const QColor shadow( _helper->shadowColor( palette ) ); |
|
|
|
// render |
|
_helper->renderRadioButton( painter, option->rect, color, shadow, sunken, checked ); |
|
|
|
return true; |
|
|
|
} |
|
|
|
//___________________________________________________________________________________ |
|
bool Style::drawIndicatorButtonDropDownPrimitive( const QStyleOption* option, QPainter* painter, const QWidget* widget ) const |
|
{ |
|
|
|
// store palette and rect |
|
const QPalette& palette( option->palette ); |
|
const QRect& rect( option->rect ); |
|
|
|
// store state |
|
const State& state( option->state ); |
|
const bool enabled( state & State_Enabled ); |
|
bool mouseOver( enabled && ( state & State_MouseOver ) ); |
|
const bool sunken( enabled && ( state & State_Sunken ) ); |
|
|
|
// arrow color |
|
QColor arrowColor; |
|
if( mouseOver ) arrowColor = _helper->hoverColor( palette ); |
|
else arrowColor = palette.color( QPalette::WindowText ); |
|
|
|
// for toolbuttons, need to render the relevant part of the frame |
|
const QToolButton* toolButton( qobject_cast<const QToolButton*>( widget ) ); |
|
if( toolButton && toolButton->popupMode() == QToolButton::MenuButtonPopup ) |
|
{ |
|
|
|
const bool hasFocus( enabled && ( state & State_HasFocus ) ); |
|
const bool autoRaise( state & State_AutoRaise ); |
|
if( !autoRaise ) |
|
{ |
|
|
|
// render as push button |
|
const QColor shadow( _helper->shadowColor( palette ) ); |
|
const QColor outline( _helper->buttonOutlineColor( palette, mouseOver, hasFocus ) ); |
|
const QColor background( _helper->buttonBackgroundColor( palette, mouseOver, hasFocus ) ); |
|
|
|
QRect frameRect( rect ); |
|
painter->setClipRect( rect ); |
|
frameRect.adjust( -Metrics::Frame_FrameRadius, 0, 0, 0 ); |
|
frameRect = handleRTL( option, frameRect ); |
|
|
|
// render |
|
_helper->renderButtonFrame( painter, frameRect, background, outline, shadow, hasFocus, sunken ); |
|
|
|
// disable mouse over and adjust arrow color |
|
mouseOver = false; |
|
arrowColor = palette.color( QPalette::ButtonText ); |
|
|
|
} |
|
|
|
} |
|
|
|
return true; |
|
|
|
} |
|
|
|
//___________________________________________________________________________________ |
|
bool Style::drawIndicatorToolBarSeparatorPrimitive( const QStyleOption* option, QPainter* painter, const QWidget* ) const |
|
{ |
|
|
|
// do nothing if disabled from options |
|
if( !StyleConfigData::toolBarDrawItemSeparator() ) return true; |
|
|
|
const State& state( option->state ); |
|
const bool separatorIsVertical( state & State_Horizontal ); |
|
const QRect& rect( option->rect ); |
|
const QColor color( _helper->separatorColor( option->palette ) ); |
|
|
|
_helper->renderSeparator( painter, rect, color, separatorIsVertical ); |
|
return true; |
|
|
|
} |
|
|
|
//___________________________________________________________________________________ |
|
bool Style::drawIndicatorBranchPrimitive( const QStyleOption* option, QPainter* painter, const QWidget* ) const |
|
{ |
|
|
|
const State& state( option->state ); |
|
const QRect& rect( option->rect ); |
|
const QPalette& palette( option->palette ); |
|
|
|
const bool reverseLayout( option->direction == Qt::RightToLeft ); |
|
|
|
//draw expander |
|
int expanderAdjust = 0; |
|
if( state & State_Children ) |
|
{ |
|
|
|
// state |
|
const bool expanderOpen( state & State_Open ); |
|
const bool enabled( state & State_Enabled ); |
|
const bool mouseOver( enabled && ( state & State_MouseOver ) ); |
|
|
|
// expander rect |
|
int expanderSize = qMin( rect.width(), rect.height() ); |
|
expanderSize = qMin( expanderSize, (int) Metrics::ItemView_ArrowSize ); |
|
expanderAdjust = expanderSize/2 + 1; |
|
QRect arrowRect = centerRect( rect, expanderSize, expanderSize ); |
|
|
|
// get size from option |
|
QPolygonF arrow; |
|
if( expanderOpen ) arrow = genericArrow( ArrowDown, ArrowNormal ); |
|
else if( reverseLayout ) arrow = genericArrow( ArrowLeft, ArrowNormal ); |
|
else arrow = genericArrow( ArrowRight, ArrowNormal ); |
|
|
|
const qreal penThickness( 1.5 ); |
|
const QColor arrowColor( mouseOver ? _helper->hoverColor( palette ) : palette.color( QPalette::Text ) ); |
|
|
|
// arrows |
|
painter->save(); |
|
painter->setRenderHints( QPainter::Antialiasing ); |
|
painter->setPen( QPen( arrowColor, penThickness ) ); |
|
painter->translate( QRectF( arrowRect ).center() ); |
|
painter->drawPolyline( arrow ); |
|
painter->restore(); |
|
|
|
} |
|
|
|
// tree branches |
|
if( !StyleConfigData::viewDrawTreeBranchLines() ) return true; |
|
|
|
const QPoint center( rect.center() ); |
|
const QColor lineColor( KColorUtils::mix( palette.color( QPalette::Base ), palette.color( QPalette::Text ), 0.25 ) ); |
|
painter->setRenderHint( QPainter::Antialiasing, false ); |
|
painter->setPen( lineColor ); |
|
if ( state & ( State_Item | State_Children | State_Sibling ) ) |
|
{ |
|
const QLine line( QPoint( center.x(), rect.top() ), QPoint( center.x(), center.y() - expanderAdjust ) ); |
|
painter->drawLine( line ); |
|
} |
|
|
|
//The right/left ( depending on dir ) line gets drawn if we have an item |
|
if ( state & State_Item ) |
|
{ |
|
const QLine line = reverseLayout ? |
|
QLine( QPoint( rect.left(), center.y() ), QPoint( center.x() - expanderAdjust, center.y() ) ): |
|
QLine( QPoint( center.x() + expanderAdjust, center.y() ), QPoint( rect.right(), center.y() ) ); |
|
painter->drawLine( line ); |
|
|
|
} |
|
|
|
//The bottom if we have a sibling |
|
if ( state & State_Sibling ) |
|
{ |
|
const QLine line( QPoint( center.x(), center.y() + expanderAdjust ), QPoint( center.x(), rect.bottom() ) ); |
|
painter->drawLine( line ); |
|
} |
|
|
|
return true; |
|
} |
|
|
|
//___________________________________________________________________________________ |
|
bool Style::drawPushButtonLabelControl( const QStyleOption* option, QPainter* painter, const QWidget* widget ) const |
|
{ |
|
|
|
// cast option and check |
|
const QStyleOptionButton* buttonOption( qstyleoption_cast<const QStyleOptionButton*>( option ) ); |
|
if( !buttonOption ) return true; |
|
|
|
// rect |
|
const QRect rect( option->rect ); |
|
QRect contentsRect( insideMargin( rect, Metrics::Frame_FrameWidth ) ); |
|
|
|
// palette |
|
const QPalette& palette( option->palette ); |
|
|
|
// state |
|
const State& state( option->state ); |
|
const bool enabled( state & State_Enabled ); |
|
const bool sunken( ( state & State_On ) || ( state & State_Sunken ) ); |
|
const bool mouseOver( enabled && (option->state & State_MouseOver) ); |
|
const bool hasFocus( enabled && !mouseOver && (option->state & State_HasFocus) ); |
|
const bool flat( buttonOption->features & QStyleOptionButton::Flat ); |
|
|
|
// alignment |
|
const int alignment = _mnemonics->textFlags() | Qt::AlignCenter; |
|
|
|
// color role |
|
QPalette::ColorRole textRole; |
|
if( flat ) |
|
{ |
|
|
|
if( hasFocus && sunken ) textRole = QPalette::HighlightedText; |
|
else textRole = QPalette::WindowText; |
|
|
|
} else if( hasFocus ) textRole = QPalette::HighlightedText; |
|
else textRole = QPalette::ButtonText; |
|
|
|
// menu arrow |
|
if( buttonOption->features & QStyleOptionButton::HasMenu ) |
|
{ |
|
|
|
// define rect |
|
QRect arrowRect( contentsRect ); |
|
arrowRect.setLeft( contentsRect.right() - Metrics::MenuButton_IndicatorWidth ); |
|
arrowRect = centerRect( arrowRect, Metrics::MenuButton_IndicatorWidth, Metrics::MenuButton_IndicatorWidth ); |
|
|
|
contentsRect.setRight( arrowRect.left() - Metrics::Button_BoxTextSpace - 1 ); |
|
contentsRect.adjust( Metrics::Button_MarginWidth, Metrics::Button_MarginWidth, 0, -Metrics::Button_MarginWidth ); |
|
|
|
arrowRect = handleRTL( option, arrowRect ); |
|
|
|
// define color |
|
const QColor arrowColor( palette.color( textRole ) ); |
|
|
|
// render arrow |
|
const QPolygonF arrow( genericArrow( ArrowDown, ArrowNormal ) ); |
|
const qreal penThickness = 1.5; |
|
|
|
painter->save(); |
|
painter->setRenderHints( QPainter::Antialiasing ); |
|
painter->setPen( QPen( arrowColor, penThickness ) ); |
|
painter->translate( QRectF( arrowRect ).center() ); |
|
painter->drawPolyline( arrow ); |
|
painter->restore(); |
|
|
|
} else contentsRect = insideMargin( contentsRect, Metrics::Button_MarginWidth ); |
|
|
|
// text size |
|
QSize contentsSize; |
|
if( !buttonOption->text.isEmpty() ) |
|
{ |
|
contentsSize = option->fontMetrics.size( _mnemonics->textFlags(), buttonOption->text ); |
|
if( !buttonOption->icon.isNull() ) contentsSize.rwidth() += Metrics::Button_BoxTextSpace; |
|
} |
|
|
|
// icon size |
|
QSize iconSize; |
|
if( !buttonOption->icon.isNull() ) |
|
{ |
|
iconSize = buttonOption->iconSize; |
|
if( !iconSize.isValid() ) iconSize = QSize( pixelMetric( PM_SmallIconSize ), pixelMetric( PM_SmallIconSize, option, widget ) ); |
|
|
|
contentsSize.setHeight( qMax( contentsSize.height(), iconSize.height() ) ); |
|
contentsSize.rwidth() += iconSize.width(); |
|
} |
|
|
|
// adjust contents rect |
|
contentsRect = centerRect( contentsRect, contentsSize ); |
|
|
|
if( !buttonOption->icon.isNull() ) |
|
{ |
|
|
|
// icon rect |
|
QRect iconRect; |
|
if( buttonOption->text.isEmpty() ) iconRect = centerRect( contentsRect, iconSize ); |
|
else { |
|
|
|
iconRect = contentsRect; |
|
iconRect.setWidth( iconSize.width() ); |
|
iconRect = centerRect( iconRect, iconSize ); |
|
contentsRect.setLeft( iconRect.right() + 1 + Metrics::Button_BoxTextSpace ); |
|
|
|
} |
|
|
|
iconRect = handleRTL( option, iconRect ); |
|
|
|
// icon mode |
|
QIcon::Mode mode; |
|
if( hasFocus ) mode = QIcon::Active; |
|
else if( enabled ) mode = QIcon::Normal; |
|
else mode = QIcon::Disabled; |
|
|
|
// icon state |
|
QIcon::State iconState = sunken ? QIcon::On : QIcon::Off; |
|
|
|
// icon |
|
QPixmap pixmap = buttonOption->icon.pixmap( iconSize, mode, iconState ); |
|
drawItemPixmap( painter, iconRect, alignment, pixmap ); |
|
|
|
} |
|
|
|
// text |
|
if( !buttonOption->text.isEmpty() ) |
|
{ |
|
contentsRect = handleRTL( option, contentsRect ); |
|
drawItemText( painter, contentsRect, alignment, palette, enabled, buttonOption->text, textRole ); |
|
} |
|
|
|
return true; |
|
|
|
} |
|
|
|
//___________________________________________________________________________________ |
|
bool Style::drawCheckBoxLabelControl( const QStyleOption* option, QPainter* painter, const QWidget* widget ) const |
|
{ |
|
|
|
// cast option and check |
|
const QStyleOptionButton* buttonOption( qstyleoption_cast<const QStyleOptionButton*>(option) ); |
|
if( !buttonOption ) return true; |
|
|
|
// copy palette and rect |
|
const QPalette& palette( option->palette ); |
|
const QRect& rect( option->rect ); |
|
|
|
// store state |
|
const State& state( option->state ); |
|
const bool enabled( state & State_Enabled ); |
|
|
|
// text alignment |
|
const bool reverseLayout( option->direction == Qt::RightToLeft ); |
|
const int alignment = _mnemonics->textFlags() | Qt::AlignVCenter | (reverseLayout ? Qt::AlignRight:Qt::AlignLeft ); |
|
|
|
// text rect |
|
QRect textRect( rect ); |
|
|
|
// render icon |
|
if( !buttonOption->icon.isNull() ) |
|
{ |
|
const QIcon::Mode mode( enabled ? QIcon::Normal : QIcon::Disabled ); |
|
const QPixmap pixmap( buttonOption->icon.pixmap( buttonOption->iconSize, mode ) ); |
|
drawItemPixmap( painter, rect, alignment, pixmap ); |
|
|
|
// adjust rect (copied from QCommonStyle) |
|
textRect.setLeft( textRect.left() + buttonOption->iconSize.width() + 4 ); |
|
textRect = handleRTL( option, textRect ); |
|
|
|
} |
|
|
|
// render text |
|
if( !buttonOption->text.isEmpty() ) |
|
{ |
|
textRect = option->fontMetrics.boundingRect( textRect, alignment, buttonOption->text ); |
|
drawItemText( painter, textRect, alignment, palette, enabled, buttonOption->text, QPalette::WindowText ); |
|
|
|
// check focus state |
|
const bool hasFocus( enabled && ( state & State_HasFocus ) ); |
|
|
|
// update animation state |
|
_animations->widgetStateEngine().updateState( widget, AnimationFocus, hasFocus ); |
|
const bool isFocusAnimated( _animations->widgetStateEngine().isAnimated( widget, AnimationFocus ) ); |
|
const qreal opacity( _animations->widgetStateEngine().opacity( widget, AnimationFocus ) ); |
|
|
|
// focus color |
|
QColor focusColor; |
|
if( isFocusAnimated ) focusColor = _helper->alphaColor( _helper->focusColor( palette ), opacity ); |
|
else if( hasFocus ) focusColor = _helper->focusColor( palette ); |
|
|
|
// render focus |
|
if( focusColor.isValid() ) |
|
{ |
|
painter->translate( 0, 2 ); |
|
painter->setPen( focusColor ); |
|
painter->drawLine( textRect.bottomLeft(), textRect.bottomRight() ); |
|
} |
|
} |
|
|
|
return true; |
|
|
|
} |
|
|
|
|
|
//___________________________________________________________________________________ |
|
bool Style::drawComboBoxLabelControl( const QStyleOption* option, QPainter* painter, const QWidget* widget ) const |
|
{ |
|
|
|
const QStyleOptionComboBox* comboBoxOption( qstyleoption_cast<const QStyleOptionComboBox*>( option ) ); |
|
if( !comboBoxOption ) return false; |
|
if( comboBoxOption->editable ) return false; |
|
|
|
// need to alter palette for focused buttons |
|
const State& state( option->state ); |
|
const bool enabled( state & State_Enabled ); |
|
const bool sunken( ( state & State_On ) || ( state & State_Sunken ) ); |
|
const bool mouseOver( enabled && (option->state & State_MouseOver) ); |
|
const bool hasFocus( enabled && !mouseOver && (option->state & State_HasFocus) ); |
|
const bool flat( !comboBoxOption->frame ); |
|
|
|
QPalette::ColorRole textRole; |
|
if( flat ) { |
|
|
|
if( hasFocus && sunken ) textRole = QPalette::HighlightedText; |
|
else textRole = QPalette::WindowText; |
|
|
|
} else if( hasFocus ) textRole = QPalette::HighlightedText; |
|
else textRole = QPalette::ButtonText; |
|
|
|
// change pen color directly |
|
painter->setPen( QPen( option->palette.color( textRole ), 1 ) ); |
|
|
|
// call base class method |
|
KStyle::drawControl( CE_ComboBoxLabel, option, painter, widget ); |
|
return true; |
|
|
|
} |
|
|
|
//___________________________________________________________________________________ |
|
bool Style::drawMenuBarItemControl( const QStyleOption* option, QPainter* painter, const QWidget* ) const |
|
{ |
|
|
|
// cast option and check |
|
const QStyleOptionMenuItem* menuItemOption = qstyleoption_cast<const QStyleOptionMenuItem*>( option ); |
|
if ( !menuItemOption ) return true; |
|
|
|
const State& state( option->state ); |
|
const bool enabled( state & State_Enabled ); |
|
const bool selected( enabled && (state & State_Selected) ); |
|
const bool sunken( enabled && (state & State_Sunken) ); |
|
|
|
const QPalette& palette( option->palette ); |
|
const QRect& rect( option->rect ); |
|
|
|
// get text rect |
|
const int alignment( Qt::AlignCenter|_mnemonics->textFlags() ); |
|
const QRect textRect = option->fontMetrics.boundingRect( rect, alignment, menuItemOption->text ); |
|
|
|
// render text |
|
drawItemText( painter, textRect, alignment, palette, enabled, menuItemOption->text, QPalette::WindowText ); |
|
|
|
// render outline |
|
if( selected || sunken ) |
|
{ |
|
|
|
QColor outlineColor; |
|
if( sunken ) outlineColor = _helper->focusColor( palette ); |
|
else if( selected ) outlineColor = _helper->hoverColor( palette ); |
|
|
|
painter->translate( 0, 2 ); |
|
painter->setBrush( Qt::NoBrush ); |
|
painter->setPen( outlineColor ); |
|
painter->drawLine( textRect.bottomLeft(), textRect.bottomRight() ); |
|
|
|
} |
|
|
|
return true; |
|
|
|
} |
|
|
|
|
|
//___________________________________________________________________________________ |
|
bool Style::drawMenuItemControl( const QStyleOption* option, QPainter* painter, const QWidget* widget ) const |
|
{ |
|
|
|
// cast option and check |
|
const QStyleOptionMenuItem* menuItemOption = qstyleoption_cast<const QStyleOptionMenuItem*>( option ); |
|
if( !menuItemOption ) return true; |
|
if( menuItemOption->menuItemType == QStyleOptionMenuItem::EmptyArea ) return true; |
|
|
|
// copy rect and palette |
|
const QRect& rect( option->rect ); |
|
const QPalette& palette( option->palette ); |
|
|
|
// get rect available for contents |
|
QRect contentsRect( insideMargin( rect, Metrics::MenuItem_MarginWidth ) ); |
|
|
|
// deal with separators |
|
if( menuItemOption->menuItemType == QStyleOptionMenuItem::Separator ) |
|
{ |
|
|
|
// normal separator |
|
if( menuItemOption->text.isEmpty() && menuItemOption->icon.isNull() ) |
|
{ |
|
|
|
const QColor color( _helper->separatorColor( palette ) ); |
|
_helper->renderSeparator( painter, contentsRect, color ); |
|
return true; |
|
|
|
} else { |
|
|
|
// separator can have a title and an icon |
|
// in that case they are rendered as normal, disabled items |
|
QStyleOptionMenuItem copy( *menuItemOption ); |
|
copy.menuItemType = QStyleOptionMenuItem::Normal; |
|
copy.state &= ~(State_Selected|State_Enabled|State_HasFocus|State_MouseOver); |
|
return drawMenuItemControl( ©, painter, widget ); |
|
|
|
} |
|
|
|
} |
|
|
|
// store state |
|
const State& state( option->state ); |
|
const bool enabled( state & State_Enabled ); |
|
const bool selected( enabled && (state & State_Selected) ); |
|
const bool sunken( enabled && (state & (State_On|State_Sunken) ) ); |
|
|
|
// define relevant rectangles |
|
// checkbox |
|
QRect checkBoxRect; |
|
if( menuItemOption->menuHasCheckableItems ) |
|
{ |
|
checkBoxRect = QRect( contentsRect.left(), contentsRect.top() + (contentsRect.height()-Metrics::CheckBox_Size)/2, Metrics::CheckBox_Size, Metrics::CheckBox_Size ); |
|
contentsRect.setLeft( checkBoxRect.right() + Metrics::MenuItem_BoxTextSpace + 1 ); |
|
} |
|
|
|
// render checkbox indicator |
|
if( menuItemOption->checkType == QStyleOptionMenuItem::NonExclusive ) |
|
{ |
|
|
|
checkBoxRect = handleRTL( option, checkBoxRect ); |
|
|
|
// checkbox state |
|
Helper::CheckBoxState state( menuItemOption->checked ? Helper::CheckOn : Helper::CheckOff ); |
|
const bool active( menuItemOption->checked ); |
|
const QColor color( _helper->checkBoxIndicatorColor( palette, enabled && selected, enabled && active ) ); |
|
const QColor shadow( _helper->shadowColor( palette ) ); |
|
_helper->renderCheckBox( painter, checkBoxRect, color, shadow, sunken, state ); |
|
|
|
} else if( menuItemOption->checkType == QStyleOptionMenuItem::Exclusive ) { |
|
|
|
checkBoxRect = handleRTL( option, checkBoxRect ); |
|
|
|
const bool active( menuItemOption->checked ); |
|
const QColor color( _helper->checkBoxIndicatorColor( palette, enabled && selected, enabled && active ) ); |
|
const QColor shadow( _helper->shadowColor( palette ) ); |
|
_helper->renderRadioButton( painter, checkBoxRect, color, shadow, sunken, active ); |
|
|
|
} |
|
|
|
// icon |
|
const int iconWidth( qMax( menuItemOption->maxIconWidth, pixelMetric( PM_SmallIconSize, option, widget ) ) ); |
|
QRect iconRect( contentsRect.left(), contentsRect.top() + (contentsRect.height()-iconWidth)/2, iconWidth, iconWidth ); |
|
contentsRect.setLeft( iconRect.right() + Metrics::MenuItem_BoxTextSpace + 1 ); |
|
|
|
const QSize iconSize( pixelMetric( PM_SmallIconSize, option, widget ), pixelMetric( PM_SmallIconSize, option, widget ) ); |
|
iconRect = centerRect( iconRect, iconSize ); |
|
|
|
if( !menuItemOption->icon.isNull() ) |
|
{ |
|
|
|
iconRect = handleRTL( option, iconRect ); |
|
|
|
// icon mode |
|
QIcon::Mode mode; |
|
if( selected ) mode = QIcon::Active; |
|
else if( enabled ) mode = QIcon::Normal; |
|
else mode = QIcon::Disabled; |
|
|
|
// icon state |
|
const QIcon::State iconState( sunken ? QIcon::On:QIcon::Off ); |
|
const QPixmap icon = menuItemOption->icon.pixmap( iconRect.size(), mode, iconState ); |
|
painter->drawPixmap( iconRect, icon ); |
|
|
|
} |
|
|
|
// arrow |
|
QRect arrowRect( contentsRect.right() - Metrics::MenuButton_IndicatorWidth, contentsRect.top() + (contentsRect.height()-Metrics::MenuButton_IndicatorWidth)/2, Metrics::MenuButton_IndicatorWidth, Metrics::MenuButton_IndicatorWidth ); |
|
contentsRect.setRight( arrowRect.left() - Metrics::MenuItem_BoxTextSpace - 1 ); |
|
if( menuItemOption->menuItemType == QStyleOptionMenuItem::SubMenu ) |
|
{ |
|
|
|
const bool reverseLayout( option->direction == Qt::RightToLeft ); |
|
const QPolygonF arrow( genericArrow( reverseLayout ? ArrowLeft:ArrowRight, ArrowNormal ) ); |
|
const qreal penThickness = 1.5; |
|
QColor arrowColor; |
|
if( sunken ) arrowColor = _helper->focusColor( palette ); |
|
else if( selected ) arrowColor = _helper->hoverColor( palette ); |
|
else arrowColor = palette.color( QPalette::WindowText ); |
|
|
|
painter->save(); |
|
painter->setRenderHints( QPainter::Antialiasing ); |
|
painter->translate( QRectF( arrowRect ).center() ); |
|
painter->setPen( QPen( arrowColor, penThickness ) ); |
|
painter->drawPolyline( arrow ); |
|
painter->restore(); |
|
|
|
} |
|
|
|
|
|
// text |
|
QRect textRect = contentsRect; |
|
if( !menuItemOption->text.isEmpty() ) |
|
{ |
|
|
|
// adjust textRect |
|
QString text = menuItemOption->text; |
|
textRect = centerRect( textRect, textRect.width(), option->fontMetrics.size( _mnemonics->textFlags(), text ).height() ); |
|
textRect = handleRTL( option, textRect ); |
|
|
|
// set font |
|
painter->setFont( menuItemOption->font ); |
|
|
|
// locate accelerator and render |
|
const int tabPosition( text.indexOf( QLatin1Char( '\t' ) ) ); |
|
if( tabPosition >= 0 ) |
|
{ |
|
QString accelerator( text.mid( tabPosition + 1 ) ); |
|
text = text.left( tabPosition ); |
|
drawItemText( painter, textRect, Qt::AlignRight | Qt::AlignVCenter | _mnemonics->textFlags(), palette, enabled, accelerator, QPalette::WindowText ); |
|
} |
|
|
|
// render text |
|
const int textFlags( Qt::AlignLeft | Qt::AlignVCenter | _mnemonics->textFlags() ); |
|
textRect = option->fontMetrics.boundingRect( textRect, textFlags, text ); |
|
drawItemText( painter, textRect, textFlags, palette, enabled, text, QPalette::WindowText ); |
|
|
|
// render hover and focus |
|
if( selected || sunken ) |
|
{ |
|
|
|
QColor outlineColor; |
|
if( sunken ) outlineColor = _helper->focusColor( palette ); |
|
else if( selected ) outlineColor = _helper->hoverColor( palette ); |
|
|
|
painter->save(); |
|
painter->setRenderHint( QPainter::Antialiasing, false ); |
|
painter->translate( 0, 2 ); |
|
painter->setBrush( Qt::NoBrush ); |
|
painter->setPen( outlineColor ); |
|
painter->drawLine( textRect.bottomLeft(), textRect.bottomRight() ); |
|
painter->restore(); |
|
|
|
} |
|
|
|
} |
|
|
|
return true; |
|
} |
|
|
|
//___________________________________________________________________________________ |
|
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 ); |
|
|
|
// enable busy animations |
|
/* need to check both widget and passed styleObject, used for QML */ |
|
if(( widget || progressBarOption->styleObject ) && _animations->busyIndicatorEngine().enabled() ) |
|
{ |
|
|
|
// register QML object if defined |
|
if( !widget && progressBarOption->styleObject ) |
|
{ _animations->busyIndicatorEngine().registerWidget( progressBarOption->styleObject ); } |
|
|
|
_animations->busyIndicatorEngine().setAnimated( widget ? widget : progressBarOption->styleObject, progressBarOption->maximum == 0 && progressBarOption->minimum == 0 ); |
|
|
|
} |
|
|
|
// check if animated and pass to option |
|
if( _animations->busyIndicatorEngine().isAnimated( widget ? widget : progressBarOption->styleObject ) ) |
|
{ progressBarOption2.progress = _animations->busyIndicatorEngine().value(); } |
|
|
|
// 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* ) const |
|
{ |
|
|
|
const QStyleOptionProgressBar* progressBarOption( qstyleoption_cast<const QStyleOptionProgressBar*>( option ) ); |
|
if( !progressBarOption ) return true; |
|
|
|
const QStyleOptionProgressBarV2* progressBarOption2( qstyleoption_cast<const QStyleOptionProgressBarV2*>( option ) ); |
|
|
|
const QRect& rect( option->rect ); |
|
const QPalette& palette( option->palette ); |
|
|
|
// check if anything is to be drawn |
|
qreal progress = progressBarOption->progress - progressBarOption->minimum; |
|
const bool busyIndicator = ( progressBarOption->minimum == 0 && progressBarOption->maximum == 0 ); |
|
if( busyIndicator ) progress = _animations->busyIndicatorEngine().value(); |
|
|
|
if( busyIndicator ) |
|
{ |
|
|
|
const bool horizontal = !progressBarOption2 || progressBarOption2->orientation == Qt::Horizontal; |
|
const bool reverse = horizontal && option->direction == Qt::RightToLeft; |
|
|
|
const QColor first( palette.color( QPalette::Highlight ) ); |
|
const QColor second( KColorUtils::mix( palette.color( QPalette::Highlight ), palette.color( QPalette::Window ), 0.7 ) ); |
|
_helper->renderProgressBarBusyContents( painter, rect, first, second, horizontal, reverse, progress ); |
|
|
|
} else if( progress ) { |
|
|
|
const int steps = qMax( progressBarOption->maximum - progressBarOption->minimum, 1 ); |
|
const bool horizontal = !progressBarOption2 || progressBarOption2->orientation == Qt::Horizontal; |
|
|
|
//Calculate width fraction |
|
qreal widthFrac( busyIndicator ? ProgressBar_BusyIndicatorSize/100.0 : progress/steps ); |
|
widthFrac = qMin( (qreal)1.0, widthFrac ); |
|
|
|
// convert the pixel width |
|
const int indicatorSize( widthFrac*( horizontal ? rect.width():rect.height() ) ); |
|
|
|
// do nothing if indicator size is too small |
|
if( indicatorSize < Metrics::ProgressBar_Thickness ) return true; |
|
|
|
QRect indicatorRect; |
|
|
|
if ( horizontal ) indicatorRect = QRect( rect.x(), rect.y(), indicatorSize, rect.height() ); |
|
else indicatorRect = QRect( rect.x(), rect.bottom()- indicatorSize + 1, rect.width(), indicatorSize ); |
|
|
|
// handle right to left |
|
indicatorRect = handleRTL( option, indicatorRect ); |
|
_helper->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 ) ); |
|
_helper->renderProgressBarGroove( 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& rect( option->rect ); |
|
const QPalette& palette( option->palette ); |
|
const State& state( option->state ); |
|
const bool enabled( state & 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( rect.topRight() ); |
|
painter->rotate( 90.0 ); |
|
|
|
} else if( !horizontal ) { |
|
|
|
painter->translate( rect.bottomLeft() ); |
|
painter->rotate( -90.0 ); |
|
|
|
} |
|
|
|
// define text rect |
|
const QRect textRect( horizontal? rect : QRect( 0, 0, rect.height(), rect.width() ) ); |
|
Qt::Alignment hAlign( ( progressBarOption->textAlignment == Qt::AlignLeft ) ? Qt::AlignHCenter : progressBarOption->textAlignment ); |
|
drawItemText( painter, textRect, Qt::AlignBottom | hAlign, palette, enabled, progressBarOption->text, QPalette::WindowText ); |
|
|
|
return true; |
|
|
|
} |
|
|
|
//___________________________________________________________________________________ |
|
bool Style::drawScrollBarSliderControl( const QStyleOption* option, QPainter* painter, const QWidget* widget ) const |
|
{ |
|
|
|
// 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& state( option->state ); |
|
const bool horizontal( state & 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( state & State_Enabled ); |
|
const bool mouseOver( enabled && ( state & 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 retrieve 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() ); |
|
|
|
_helper->renderScrollBarGroove( painter, backgroundRect, color ); |
|
|
|
} |
|
|
|
{ |
|
// render handle |
|
// define colors |
|
QColor color; |
|
const QPalette& palette( option->palette ); |
|
|
|
const QColor base( focus ? |
|
_helper->focusColor( palette ): |
|
_helper->alphaColor( palette.color( QPalette::WindowText ), 0.5 ) ); |
|
|
|
const QColor highlight( _helper->hoverColor( palette ) ); |
|
if( opacity >= 0 ) color = KColorUtils::mix( base, highlight, opacity ); |
|
else if( mouseOver ) color = highlight; |
|
else color = base; |
|
|
|
// render |
|
_helper->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& state( option->state ); |
|
const bool horizontal( state & State_Horizontal ); |
|
const bool reverseLayout( option->direction == Qt::RightToLeft ); |
|
|
|
// adjust rect, based on number of buttons to be drawn |
|
QRect rect( scrollBarInternalSubControlRect( sliderOption, SC_ScrollBarAddLine ) ); |
|
|
|
QColor color; |
|
QStyleOptionSlider copy( *sliderOption ); |
|
if( _addLineButtons == DoubleButton ) |
|
{ |
|
|
|
if( horizontal ) |
|
{ |
|
|
|
//Draw the arrows |
|
const QSize halfSize( rect.width()/2, rect.height() ); |
|
const QRect leftSubButton( rect.topLeft(), halfSize ); |
|
const QRect rightSubButton( leftSubButton.topRight() + QPoint( 1, 0 ), halfSize ); |
|
|
|
copy.rect = leftSubButton; |
|
color = scrollBarArrowColor( ©, reverseLayout ? SC_ScrollBarAddLine:SC_ScrollBarSubLine, widget ); |
|
renderScrollBarArrow( painter, leftSubButton, color, ArrowLeft ); |
|
|
|
copy.rect = rightSubButton; |
|
color = scrollBarArrowColor( ©, reverseLayout ? SC_ScrollBarSubLine:SC_ScrollBarAddLine, widget ); |
|
renderScrollBarArrow( painter, rightSubButton, color, ArrowRight ); |
|
|
|
} else { |
|
|
|
const QSize halfSize( rect.width(), rect.height()/2 ); |
|
const QRect topSubButton( rect.topLeft(), halfSize ); |
|
const QRect botSubButton( topSubButton.bottomLeft() + QPoint( 0, 1 ), halfSize ); |
|
|
|
copy.rect = topSubButton; |
|
color = scrollBarArrowColor( ©, SC_ScrollBarSubLine, widget ); |
|
renderScrollBarArrow( painter, topSubButton, color, ArrowUp ); |
|
|
|
copy.rect = botSubButton; |
|
color = scrollBarArrowColor( ©, SC_ScrollBarAddLine, widget ); |
|
renderScrollBarArrow( painter, botSubButton, color, ArrowDown ); |
|
|
|
} |
|
|
|
} else if( _addLineButtons == SingleButton ) { |
|
|
|
copy.rect = rect; |
|
color = scrollBarArrowColor( ©, SC_ScrollBarAddLine, widget ); |
|
if( horizontal ) |
|
{ |
|
|
|
if( reverseLayout ) renderScrollBarArrow( painter, rect, color, ArrowLeft ); |
|
else renderScrollBarArrow( painter, rect.translated( 1, 0 ), color, ArrowRight ); |
|
|
|
} else renderScrollBarArrow( painter, rect.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& state( option->state ); |
|
|
|
// define tiles and adjust rect |
|
QRect backgroundRect; |
|
const bool horizontal( state & 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 |
|
_helper->renderScrollBarGroove( 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& state( option->state ); |
|
const bool horizontal( state & 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 rect( scrollBarInternalSubControlRect( sliderOption, SC_ScrollBarSubLine ) ); |
|
|
|
QColor color; |
|
QStyleOptionSlider copy( *sliderOption ); |
|
if( _subLineButtons == DoubleButton ) |
|
{ |
|
|
|
if( horizontal ) |
|
{ |
|
|
|
//Draw the arrows |
|
const QSize halfSize( rect.width()/2, rect.height() ); |
|
const QRect leftSubButton( rect.topLeft(), halfSize ); |
|
const QRect rightSubButton( leftSubButton.topRight() + QPoint( 1, 0 ), halfSize ); |
|
|
|
copy.rect = leftSubButton; |
|
color = scrollBarArrowColor( ©, reverseLayout ? SC_ScrollBarAddLine:SC_ScrollBarSubLine, widget ); |
|
renderScrollBarArrow( painter, leftSubButton, color, ArrowLeft ); |
|
|
|
copy.rect = rightSubButton; |
|
color = scrollBarArrowColor( ©, reverseLayout ? SC_ScrollBarSubLine:SC_ScrollBarAddLine, widget ); |
|
renderScrollBarArrow( painter, rightSubButton, color, ArrowRight ); |
|
|
|
} else { |
|
|
|
const QSize halfSize( rect.width(), rect.height()/2 ); |
|
const QRect topSubButton( rect.topLeft(), halfSize ); |
|
const QRect botSubButton( topSubButton.bottomLeft() + QPoint( 0, 1 ), halfSize ); |
|
|
|
copy.rect = topSubButton; |
|
color = scrollBarArrowColor( ©, SC_ScrollBarSubLine, widget ); |
|
renderScrollBarArrow( painter, topSubButton, color, ArrowUp ); |
|
|
|
copy.rect = botSubButton; |
|
color = scrollBarArrowColor( ©, SC_ScrollBarAddLine, widget ); |
|
renderScrollBarArrow( painter, botSubButton, color, ArrowDown ); |
|
|
|
} |
|
|
|
} else if( _subLineButtons == SingleButton ) { |
|
|
|
copy.rect = rect; |
|
color = scrollBarArrowColor( ©, SC_ScrollBarSubLine, widget ); |
|
if( horizontal ) |
|
{ |
|
|
|
if( reverseLayout ) renderScrollBarArrow( painter, rect.translated( 1, 0 ), color, ArrowRight ); |
|
else renderScrollBarArrow( painter, rect, color, ArrowLeft ); |
|
|
|
} else renderScrollBarArrow( painter, rect, 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& state( option->state ); |
|
|
|
// define tiles and adjust rect |
|
QRect backgroundRect; |
|
const bool horizontal( state & 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 |
|
_helper->renderScrollBarGroove( painter, backgroundRect, color ); |
|
|
|
return true; |
|
|
|
} |
|
|
|
//___________________________________________________________________________________ |
|
bool Style::drawShapedFrameControl( const QStyleOption* option, QPainter* painter, const QWidget* ) const |
|
{ |
|
|
|
// cast option and check |
|
const QStyleOptionFrameV3* frameOpt = qstyleoption_cast<const QStyleOptionFrameV3*>( option ); |
|
if( !frameOpt ) return false; |
|
|
|
switch( frameOpt->frameShape ) |
|
{ |
|
|
|
case QFrame::Box: |
|
{ |
|
if( option->state & State_Sunken ) return true; |
|
else break; |
|
} |
|
|
|
case QFrame::HLine: |
|
case QFrame::VLine: |
|
{ |
|
|
|
const QRect& rect( option->rect ); |
|
const QColor color( _helper->separatorColor( option->palette ) ); |
|
const bool isVertical( frameOpt->frameShape == QFrame::VLine ); |
|
_helper->renderSeparator( painter, rect, color, isVertical ); |
|
return true; |
|
} |
|
|
|
default: break; |
|
|
|
} |
|
|
|
return false; |
|
|
|
} |
|
|
|
//___________________________________________________________________________________ |
|
bool Style::drawRubberBandControl( const QStyleOption* option, QPainter* painter, const QWidget* ) const |
|
{ |
|
|
|
const QPalette& palette( option->palette ); |
|
const QRect rect( option->rect ); |
|
|
|
QColor color = palette.color( QPalette::Highlight ); |
|
painter->setPen( KColorUtils::mix( color, palette.color( QPalette::Active, QPalette::WindowText ) ) ); |
|
color.setAlpha( 50 ); |
|
painter->setBrush( color ); |
|
painter->setClipRegion( rect ); |
|
painter->drawRect( rect.adjusted( 0,0,-1,-1 ) ); |
|
return true; |
|
|
|
} |
|
|
|
//___________________________________________________________________________________ |
|
bool Style::drawHeaderSectionControl( const QStyleOption* option, QPainter* painter, const QWidget* widget ) const |
|
{ |
|
|
|
const QRect& rect( option->rect ); |
|
const QPalette& palette( option->palette ); |
|
const State& state( option->state ); |
|
const bool enabled( state & State_Enabled ); |
|
const bool mouseOver( enabled && ( state & State_MouseOver ) ); |
|
const bool sunken( enabled && ( state & (State_On|State_Sunken) ) ); |
|
|
|
const QStyleOptionHeader* headerOption( qstyleoption_cast<const QStyleOptionHeader*>( option ) ); |
|
if( !headerOption ) return true; |
|
|
|
const bool horizontal( headerOption->orientation == Qt::Horizontal ); |
|
const bool isFirst( horizontal && ( headerOption->position == QStyleOptionHeader::Beginning ) ); |
|
const bool isCorner( widget && widget->inherits( "QTableCornerButton" ) ); |
|
const bool reverseLayout( option->direction == Qt::RightToLeft ); |
|
|
|
// update animation state |
|
_animations->headerViewEngine().updateState( widget, rect.topLeft(), mouseOver ); |
|
const bool animated( enabled && _animations->headerViewEngine().isAnimated( widget, rect.topLeft() ) ); |
|
const qreal opacity( _animations->headerViewEngine().opacity( widget, rect.topLeft() ) ); |
|
|
|
// fill |
|
const QColor normal( palette.color( QPalette::Window ) ); |
|
const QColor focus( KColorUtils::mix( normal, _helper->focusColor( palette ), 0.2 ) ); |
|
const QColor hover( KColorUtils::mix( normal, _helper->hoverColor( palette ), 0.2 ) ); |
|
|
|
QColor color; |
|
if( sunken ) color = focus; |
|
else if( animated ) color = KColorUtils::mix( normal, hover, opacity ); |
|
else if( mouseOver ) color = hover; |
|
else color = normal; |
|
|
|
painter->setRenderHint( QPainter::Antialiasing, false ); |
|
painter->setBrush( color ); |
|
painter->setPen( Qt::NoPen ); |
|
painter->drawRect( rect ); |
|
|
|
// outline |
|
painter->setBrush( Qt::NoBrush ); |
|
painter->setPen( _helper->alphaColor( palette.color( QPalette::WindowText ), 0.1 ) ); |
|
|
|
if( isCorner ) |
|
{ |
|
|
|
if( reverseLayout ) painter->drawPoint( rect.bottomLeft() ); |
|
else painter->drawPoint( rect.bottomRight() ); |
|
|
|
|
|
} else if( horizontal ) { |
|
|
|
painter->drawLine( rect.bottomLeft(), rect.bottomRight() ); |
|
|
|
} else { |
|
|
|
if( reverseLayout ) painter->drawLine( rect.topLeft(), rect.bottomLeft() ); |
|
else painter->drawLine( rect.topRight(), rect.bottomRight() ); |
|
|
|
} |
|
|
|
// separators |
|
painter->setPen( _helper->alphaColor( palette.color( QPalette::WindowText ), 0.2 ) ); |
|
|
|
if( horizontal ) |
|
{ |
|
if( headerOption->section != 0 || isFirst ) |
|
{ |
|
|
|
if( reverseLayout ) painter->drawLine( rect.topLeft(), rect.bottomLeft() - QPoint( 0, 1 ) ); |
|
else painter->drawLine( rect.topRight(), rect.bottomRight() - QPoint( 0, 1 ) ); |
|
|
|
} |
|
|
|
} else { |
|
|
|
if( reverseLayout ) painter->drawLine( rect.bottomLeft()+QPoint( 1, 0 ), rect.bottomRight() ); |
|
else painter->drawLine( rect.bottomLeft(), rect.bottomRight() - QPoint( 1, 0 ) ); |
|
|
|
} |
|
|
|
return true; |
|
|
|
} |
|
|
|
//___________________________________________________________________________________ |
|
bool Style::drawHeaderEmptyAreaControl( const QStyleOption* option, QPainter* painter, const QWidget* ) const |
|
{ |
|
|
|
// use the same background as in drawHeaderPrimitive |
|
const QRect& rect( option->rect ); |
|
QPalette palette( option->palette ); |
|
|
|
const bool horizontal( option->state & QStyle::State_Horizontal ); |
|
const bool reverseLayout( option->direction == Qt::RightToLeft ); |
|
|
|
// fill |
|
painter->setRenderHint( QPainter::Antialiasing, false ); |
|
painter->setBrush( palette.color( QPalette::Window ) ); |
|
painter->setPen( Qt::NoPen ); |
|
painter->drawRect( rect ); |
|
|
|
// outline |
|
painter->setBrush( Qt::NoBrush ); |
|
painter->setPen( _helper->alphaColor( palette.color( QPalette::WindowText ), 0.1 ) ); |
|
|
|
if( horizontal ) { |
|
|
|
painter->drawLine( rect.bottomLeft(), rect.bottomRight() ); |
|
|
|
} else { |
|
|
|
if( reverseLayout ) painter->drawLine( rect.topLeft(), rect.bottomLeft() ); |
|
else painter->drawLine( rect.topRight(), rect.bottomRight() ); |
|
|
|
} |
|
|
|
return true; |
|
|
|
} |
|
|
|
//___________________________________________________________________________________ |
|
bool Style::drawTabBarTabLabelControl( const QStyleOption* option, QPainter* painter, const QWidget* widget ) const |
|
{ |
|
|
|
// call parent style method |
|
KStyle::drawControl( CE_TabBarTabLabel, option, painter, widget ); |
|
|
|
// check focus |
|
const State& state( option->state ); |
|
const bool hasFocus( state & State_HasFocus ); |
|
const bool selected( state & State_Selected ); |
|
if( !( hasFocus && selected ) ) return true; |
|
|
|
// code is copied from QCommonStyle, but adds focus |
|
// cast option and check |
|
const QStyleOptionTab *tabOption( qstyleoption_cast<const QStyleOptionTab*>(option) ); |
|
if( !tabOption || tabOption->text.isEmpty() ) return true; |
|
|
|
// tab option rect |
|
QRect rect = tabOption->rect; |
|
const bool verticalTabs( isVerticalTab( tabOption ) ); |
|
const int alignment = Qt::AlignCenter | _mnemonics->textFlags(); |
|
|
|
// text rect |
|
QRect textRect( subElementRect(SE_TabBarTabText, option, widget) ); |
|
|
|
if( verticalTabs ) |
|
{ |
|
|
|
// properly rotate painter |
|
painter->save(); |
|
int newX, newY, newRot; |
|
if( tabOption->shape == QTabBar::RoundedEast || tabOption->shape == QTabBar::TriangularEast) |
|
{ |
|
|
|
newX = rect.width() + rect.x(); |
|
newY = rect.y(); |
|
newRot = 90; |
|
|
|
} else { |
|
|
|
newX = rect.x(); |
|
newY = rect.y() + rect.height(); |
|
newRot = -90; |
|
|
|
} |
|
|
|
QTransform transform; |
|
transform.translate( newX, newY ); |
|
transform.rotate(newRot); |
|
painter->setTransform( transform, true ); |
|
|
|
} |
|
|
|
// adjust text rect based on font metrics |
|
textRect = option->fontMetrics.boundingRect( textRect, alignment, tabOption->text ); |
|
|
|
// render focus line |
|
painter->translate( 0, 2 ); |
|
painter->setPen( _helper->focusColor( option->palette ) ); |
|
painter->drawLine( textRect.bottomLeft(), textRect.bottomRight() ); |
|
|
|
if( verticalTabs ) painter->restore(); |
|
|
|
return true; |
|
|
|
} |
|
|
|
//___________________________________________________________________________________ |
|
bool Style::drawTabBarTabShapeControl( const QStyleOption* option, QPainter* painter, const QWidget* widget ) const |
|
{ |
|
|
|
const QStyleOptionTab* tabOption( qstyleoption_cast<const QStyleOptionTab*>( option ) ); |
|
if( !tabOption ) return true; |
|
|
|
// palette and state |
|
const QPalette& palette( option->palette ); |
|
const State& state( option->state ); |
|
const bool enabled( state & State_Enabled ); |
|
const bool selected( state & State_Selected ); |
|
const bool mouseOver( enabled && !selected && ( state & State_MouseOver ) ); |
|
|
|
// check if tab is being dragged |
|
const bool isDragged( widget && selected && painter->device() != widget ); |
|
const bool isLocked( widget && _tabBarData->isLocked( widget ) ); |
|
|
|
// store rect |
|
QRect rect( option->rect ); |
|
|
|
// animation state |
|
_animations->tabBarEngine().updateState( widget, rect.topLeft(), mouseOver ); |
|
const bool animated( enabled && !selected && _animations->tabBarEngine().isAnimated( widget, rect.topLeft() ) ); |
|
const qreal opacity( _animations->tabBarEngine().opacity( widget, rect.topLeft() ) ); |
|
|
|
// lock state |
|
if( selected && widget && isDragged ) _tabBarData->lock( widget ); |
|
else if( widget && selected && _tabBarData->isLocked( widget ) ) _tabBarData->release(); |
|
|
|
// tab position |
|
const QStyleOptionTab::TabPosition& position = tabOption->position; |
|
const bool isSingle( position == QStyleOptionTab::OnlyOneTab ); |
|
bool isFirst( isSingle || position == QStyleOptionTab::Beginning ); |
|
bool isLast( isSingle || position == QStyleOptionTab::End ); |
|
bool isLeftOfSelected( !isLocked && tabOption->selectedPosition == QStyleOptionTab::NextIsSelected ); |
|
bool isRightOfSelected( !isLocked && tabOption->selectedPosition == QStyleOptionTab::PreviousIsSelected ); |
|
|
|
// true if widget is aligned to the frame |
|
/* need to check for 'isRightOfSelected' because for some reason the isFirst flag is set when active tab is being moved */ |
|
isFirst &= !isRightOfSelected; |
|
isLast &= !isLeftOfSelected; |
|
|
|
// swap state based on reverse layout, so that they become layout independent |
|
const bool reverseLayout( option->direction == Qt::RightToLeft ); |
|
const bool verticalTabs( isVerticalTab( tabOption ) ); |
|
if( reverseLayout && !verticalTabs ) |
|
{ |
|
qSwap( isFirst, isLast ); |
|
qSwap( isLeftOfSelected, isRightOfSelected ); |
|
} |
|
|
|
// adjust rect and define corners based on tabbar orientation |
|
Helper::Corners corners; |
|
switch( tabOption->shape ) |
|
{ |
|
case QTabBar::RoundedNorth: |
|
case QTabBar::TriangularNorth: |
|
if( selected ) { |
|
|
|
corners = Helper::CornerTopLeft|Helper::CornerTopRight; |
|
rect.adjust( 0, 0, 0, Metrics::TabBar_TabRadius ); |
|
|
|
} else { |
|
|
|
rect.adjust( 0, 0, 0, -1 ); |
|
if( isFirst ) corners |= Helper::CornerTopLeft; |
|
if( isLast ) corners |= Helper::CornerTopRight; |
|
if( isRightOfSelected ) rect.adjust( -Metrics::TabBar_TabRadius, 0, 0, 0 ); |
|
if( isLeftOfSelected ) rect.adjust( 0, 0, Metrics::TabBar_TabOverlap, 0 ); |
|
else if( !isLast ) rect.adjust( 0, 0, Metrics::TabBar_TabOverlap, 0 ); |
|
|
|
} |
|
break; |
|
|
|
case QTabBar::RoundedSouth: |
|
case QTabBar::TriangularSouth: |
|
if( selected ) { |
|
|
|
corners = Helper::CornerBottomLeft|Helper::CornerBottomRight; |
|
rect.adjust( 0, -Metrics::TabBar_TabRadius, 0, 0 ); |
|
|
|
} else { |
|
|
|
rect.adjust( 0, 1, 0, 0 ); |
|
if( isFirst ) corners |= Helper::CornerBottomLeft; |
|
if( isLast ) corners |= Helper::CornerBottomRight; |
|
if( isRightOfSelected ) rect.adjust( -Metrics::TabBar_TabRadius, 0, 0, 0 ); |
|
if( isLeftOfSelected ) rect.adjust( 0, 0, Metrics::TabBar_TabOverlap, 0 ); |
|
else if( !isLast ) rect.adjust( 0, 0, Metrics::TabBar_TabOverlap, 0 ); |
|
|
|
} |
|
break; |
|
|
|
case QTabBar::RoundedWest: |
|
case QTabBar::TriangularWest: |
|
if( selected ) |
|
{ |
|
corners = Helper::CornerTopLeft|Helper::CornerBottomLeft; |
|
rect.adjust( 0, 0, Metrics::TabBar_TabRadius, 0 ); |
|
|
|
} else { |
|
|
|
rect.adjust( 0, 0, -1, 0 ); |
|
if( isFirst ) corners |= Helper::CornerTopLeft; |
|
if( isLast ) corners |= Helper::CornerBottomLeft; |
|
if( isRightOfSelected ) rect.adjust( 0, -Metrics::TabBar_TabRadius, 0, 0 ); |
|
if( isLeftOfSelected ) rect.adjust( 0, 0, 0, Metrics::TabBar_TabRadius ); |
|
else if( !isLast ) rect.adjust( 0, 0, 0, Metrics::TabBar_TabOverlap ); |
|
|
|
} |
|
break; |
|
|
|
case QTabBar::RoundedEast: |
|
case QTabBar::TriangularEast: |
|
if( selected ) |
|
{ |
|
|
|
corners = Helper::CornerTopRight|Helper::CornerBottomRight; |
|
rect.adjust( -Metrics::TabBar_TabRadius, 0, 0, 0 ); |
|
|
|
} else { |
|
|
|
rect.adjust( 1, 0, 0, 0 ); |
|
if( isFirst ) corners |= Helper::CornerTopRight; |
|
if( isLast ) corners |= Helper::CornerBottomRight; |
|
if( isRightOfSelected ) rect.adjust( 0, -Metrics::TabBar_TabRadius, 0, 0 ); |
|
if( isLeftOfSelected ) rect.adjust( 0, 0, 0, Metrics::TabBar_TabRadius ); |
|
else if( !isLast ) rect.adjust( 0, 0, 0, Metrics::TabBar_TabOverlap ); |
|
|
|
} |
|
break; |
|
|
|
default: break; |
|
} |
|
|
|
// color |
|
QColor color; |
|
if( selected ) color = palette.color( QPalette::Window ); |
|
else { |
|
|
|
const QColor normal( _helper->alphaColor( palette.color( QPalette::WindowText ), 0.2 ) ); |
|
const QColor hover( _helper->alphaColor( _helper->hoverColor( palette ), 0.2 ) ); |
|
if( animated ) color = KColorUtils::mix( normal, hover, opacity ); |
|
else if( mouseOver ) color = hover; |
|
else color = normal; |
|
|
|
} |
|
|
|
// outline |
|
const QColor outline( selected ? _helper->alphaColor( palette.color( QPalette::WindowText ), 0.25 ) : QColor() ); |
|
|
|
// render |
|
_helper->renderTabBarTab( painter, rect, color, outline, corners ); |
|
|
|
return true; |
|
|
|
} |
|
|
|
//___________________________________________________________________________________ |
|
bool Style::drawToolBoxTabLabelControl( const QStyleOption* option, QPainter* painter, const QWidget* widget ) const |
|
{ |
|
|
|
// rendering is similar to drawPushButtonLabelControl |
|
|
|
// cast option and check |
|
const QStyleOptionToolBox* toolBoxOption( qstyleoption_cast<const QStyleOptionToolBox *>( option ) ); |
|
if( !toolBoxOption ) return true; |
|
|
|
// copy palette |
|
const QPalette& palette( option->palette ); |
|
|
|
const State& state( option->state ); |
|
const bool enabled( state & State_Enabled ); |
|
|
|
// text alignment |
|
const int alignment = _mnemonics->textFlags() | Qt::AlignCenter; |
|
|
|
// contents rect |
|
const QRect rect( toolBoxTabContentsRect( option, widget ) ); |
|
|
|
// store icon size |
|
const int iconSize( pixelMetric( QStyle::PM_SmallIconSize, option, widget ) ); |
|
|
|
// find contents size and rect |
|
QRect contentsRect( rect ); |
|
QSize contentsSize; |
|
if( !toolBoxOption->text.isEmpty() ) |
|
{ |
|
contentsSize = option->fontMetrics.size( _mnemonics->textFlags(), toolBoxOption->text ); |
|
if( !toolBoxOption->icon.isNull() ) contentsSize.rwidth() += Metrics::ToolBox_TabBoxTextSpace; |
|
} |
|
|
|
// icon size |
|
if( !toolBoxOption->icon.isNull() ) |
|
{ |
|
|
|
contentsSize.setHeight( qMax( contentsSize.height(), iconSize ) ); |
|
contentsSize.rwidth() += iconSize; |
|
|
|
} |
|
|
|
// adjust contents rect |
|
contentsRect = centerRect( contentsRect, contentsSize ); |
|
|
|
// render icon |
|
if( !toolBoxOption->icon.isNull() ) |
|
{ |
|
|
|
// icon rect |
|
QRect iconRect; |
|
if( toolBoxOption->text.isEmpty() ) iconRect = centerRect( contentsRect, iconSize, iconSize ); |
|
else { |
|
|
|
iconRect = contentsRect; |
|
iconRect.setWidth( iconSize ); |
|
iconRect = centerRect( iconRect, iconSize, iconSize ); |
|
contentsRect.setLeft( iconRect.right() + 1 + Metrics::ToolBox_TabBoxTextSpace ); |
|
|
|
} |
|
|
|
iconRect = handleRTL( option, iconRect ); |
|
const QIcon::Mode mode( enabled ? QIcon::Normal : QIcon::Disabled ); |
|
const QPixmap pixmap( toolBoxOption->icon.pixmap( iconSize, mode ) ); |
|
drawItemPixmap( painter, iconRect, alignment, pixmap ); |
|
|
|
} |
|
|
|
// render text |
|
if( !toolBoxOption->text.isEmpty() ) |
|
{ |
|
contentsRect = handleRTL( option, contentsRect ); |
|
drawItemText( painter, contentsRect, alignment, palette, enabled, toolBoxOption->text, QPalette::WindowText ); |
|
} |
|
|
|
return true; |
|
} |
|
|
|
//___________________________________________________________________________________ |
|
bool Style::drawToolBoxTabShapeControl( const QStyleOption* option, QPainter* painter, const QWidget* widget ) const |
|
{ |
|
|
|
// cast option and check |
|
const QStyleOptionToolBox* toolBoxOption( qstyleoption_cast<const QStyleOptionToolBox *>( option ) ); |
|
if( !toolBoxOption ) return true; |
|
|
|
// copy rect and palette |
|
const QRect& rect( option->rect ); |
|
const QRect tabRect( toolBoxTabContentsRect( option, widget ) ); |
|
|
|
/* |
|
important: option returns the wrong palette. |
|
we use the widget palette instead, when set |
|
*/ |
|
const QPalette palette( widget ? widget->palette() : option->palette ); |
|
|
|
// store flags |
|
const State& flags( option->state ); |
|
const bool enabled( flags&State_Enabled ); |
|
const bool selected( flags&State_Selected ); |
|
const bool mouseOver( enabled && !selected && ( flags&State_MouseOver ) ); |
|
|
|
// update animation state |
|
/* |
|
the proper widget ( the toolbox tab ) is not passed as argument by Qt. |
|
What is passed is the toolbox directly. To implement animations properly, |
|
the painter->device() is used instead |
|
*/ |
|
bool isAnimated( false ); |
|
qreal opacity( AnimationData::OpacityInvalid ); |
|
QPaintDevice* device = painter->device(); |
|
if( enabled && device ) |
|
{ |
|
_animations->toolBoxEngine().updateState( device, mouseOver ); |
|
isAnimated = _animations->toolBoxEngine().isAnimated( device ); |
|
opacity = _animations->toolBoxEngine().opacity( device ); |
|
} |
|
|
|
// color |
|
QColor outline; |
|
if( selected ) outline = _helper->focusColor( palette ); |
|
else outline = _helper->frameOutlineColor( palette, mouseOver, false, opacity, isAnimated ? AnimationHover:AnimationNone ); |
|
|
|
// render |
|
_helper->renderToolBoxFrame( painter, rect, tabRect.width(), outline ); |
|
|
|
return true; |
|
} |
|
|
|
//___________________________________________________________________________________ |
|
bool Style::drawDockWidgetTitleControl( const QStyleOption* option, QPainter* painter, const QWidget* widget ) const |
|
{ |
|
|
|
// cast option and check |
|
const QStyleOptionDockWidget* dockWidgetOption = ::qstyleoption_cast<const QStyleOptionDockWidget*>( option ); |
|
if ( !dockWidgetOption ) return true; |
|
|
|
const QPalette& palette( option->palette ); |
|
const State& state( option->state ); |
|
const bool enabled( state & State_Enabled ); |
|
const bool reverseLayout( option->direction == Qt::RightToLeft ); |
|
|
|
// cast to v2 to check vertical bar |
|
const QStyleOptionDockWidgetV2 *v2 = qstyleoption_cast<const QStyleOptionDockWidgetV2*>( option ); |
|
const bool verticalTitleBar( v2 ? v2->verticalTitleBar : false ); |
|
|
|
const QRect buttonRect( subElementRect( dockWidgetOption->floatable ? SE_DockWidgetFloatButton : SE_DockWidgetCloseButton, option, widget ) ); |
|
|
|
// get rectangle and adjust to properly accounts for buttons |
|
QRect rect( insideMargin( dockWidgetOption->rect, Frame_FrameWidth ) ); |
|
if( verticalTitleBar ) |
|
{ |
|
|
|
if( buttonRect.isValid() ) rect.setTop( buttonRect.bottom()+1 ); |
|
|
|
} else if( reverseLayout ) { |
|
|
|
if( buttonRect.isValid() ) rect.setLeft( buttonRect.right()+1 ); |
|
rect.adjust( 0,0,-4,0 ); |
|
|
|
} else { |
|
|
|
if( buttonRect.isValid() ) rect.setRight( buttonRect.left()-1 ); |
|
rect.adjust( 4,0,0,0 ); |
|
|
|
} |
|
|
|
QString title( dockWidgetOption->title ); |
|
int titleWidth = dockWidgetOption->fontMetrics.size( _mnemonics->textFlags(), title ).width(); |
|
int width = verticalTitleBar ? rect.height() : rect.width(); |
|
if( width < titleWidth ) title = dockWidgetOption->fontMetrics.elidedText( title, Qt::ElideRight, width, Qt::TextShowMnemonic ); |
|
|
|
if( verticalTitleBar ) |
|
{ |
|
|
|
QSize size = rect.size(); |
|
size.transpose(); |
|
rect.setSize( size ); |
|
|
|
painter->save(); |
|
painter->translate( rect.left(), rect.top() + rect.width() ); |
|
painter->rotate( -90 ); |
|
painter->translate( -rect.left(), -rect.top() ); |
|
drawItemText( painter, rect, Qt::AlignLeft | Qt::AlignVCenter | _mnemonics->textFlags(), palette, enabled, title, QPalette::WindowText ); |
|
painter->restore(); |
|
|
|
|
|
} else { |
|
|
|
drawItemText( painter, rect, Qt::AlignLeft | Qt::AlignVCenter | _mnemonics->textFlags(), palette, enabled, title, QPalette::WindowText ); |
|
|
|
} |
|
|
|
return true; |
|
|
|
|
|
} |
|
|
|
//______________________________________________________________ |
|
bool Style::drawToolButtonComplexControl( const QStyleOptionComplex* option, QPainter* painter, const QWidget* widget ) const |
|
{ |
|
|
|
// cast option and check |
|
const QStyleOptionToolButton* toolButtonOption( qstyleoption_cast<const QStyleOptionToolButton*>( option ) ); |
|
if( !toolButtonOption ) return false; |
|
|
|
// need to alter palette for focused buttons |
|
const State& state( option->state ); |
|
const bool enabled( state & State_Enabled ); |
|
const bool sunken( ( state & State_On ) || ( state & State_Sunken ) ); |
|
const bool mouseOver( enabled && (option->state & State_MouseOver) ); |
|
const bool hasFocus( enabled && (option->state & State_HasFocus) ); |
|
const bool autoRaise( state & State_AutoRaise ); |
|
|
|
// define text role for label and arrow |
|
QPalette::ColorRole textRole; |
|
if( autoRaise ) |
|
{ |
|
|
|
if( sunken && !mouseOver ) textRole = QPalette::HighlightedText; |
|
else textRole = QPalette::WindowText; |
|
|
|
} else if( hasFocus && !mouseOver ) textRole = QPalette::HighlightedText; |
|
else textRole = QPalette::ButtonText; |
|
|
|
const bool hasPopupMenu( toolButtonOption->subControls & SC_ToolButtonMenu ); |
|
const bool hasInlineIndicator( toolButtonOption->features & QStyleOptionToolButton::HasMenu && !hasPopupMenu ); |
|
|
|
const QRect buttonRect( subControlRect( CC_ToolButton, option, SC_ToolButton, widget ) ); |
|
const QRect menuRect( subControlRect( CC_ToolButton, option, SC_ToolButtonMenu, widget ) ); |
|
|
|
// frame |
|
if( toolButtonOption->subControls & SC_ToolButton ) |
|
{ |
|
// get relevant rect |
|
QStyleOptionToolButton copy( *toolButtonOption ); |
|
copy.rect = buttonRect; |
|
|
|
drawPrimitive( PE_PanelButtonTool, ©, painter, widget); |
|
} |
|
|
|
// arrow |
|
if( toolButtonOption->subControls & SC_ToolButtonMenu ) |
|
{ |
|
|
|
QStyleOptionToolButton copy( *toolButtonOption ); |
|
copy.rect = menuRect; |
|
copy.palette.setColor( QPalette::WindowText, option->palette.color( textRole ) ); |
|
if( !autoRaise ) |
|
{ drawPrimitive( PE_IndicatorButtonDropDown, ©, painter, widget ); } |
|
|
|
copy.state &= ~State_MouseOver; |
|
drawPrimitive( PE_IndicatorArrowDown, ©, painter, widget ); |
|
|
|
} else if( hasInlineIndicator ) { |
|
|
|
QStyleOptionToolButton copy( *toolButtonOption ); |
|
copy.rect = menuRect; |
|
copy.state &= ~State_MouseOver; |
|
copy.palette.setColor( QPalette::WindowText, option->palette.color( textRole ) ); |
|
drawPrimitive( PE_IndicatorArrowDown, ©, painter, widget ); |
|
|
|
} |
|
|
|
// contents |
|
{ |
|
|
|
// define contents rect |
|
QRect contentsRect( buttonRect ); |
|
const int marginWidth( autoRaise ? Metrics::ToolButton_MarginWidth : Metrics::Button_MarginWidth + Metrics::Frame_FrameWidth ); |
|
contentsRect = insideMargin( contentsRect, marginWidth ); |
|
if( hasInlineIndicator ) contentsRect.setRight( contentsRect.right() - Metrics::ToolButton_BoxTextSpace ); |
|
|
|
// copy option, adjust rect and palette |
|
QStyleOptionToolButton copy( *toolButtonOption ); |
|
copy.rect = contentsRect; |
|
copy.palette.setColor( QPalette::Text, option->palette.color( textRole ) ); |
|
copy.palette.setColor( QPalette::WindowText, option->palette.color( textRole ) ); |
|
copy.palette.setColor( QPalette::ButtonText, option->palette.color( textRole ) ); |
|
|
|
// render |
|
drawControl( CE_ToolButtonLabel, ©, painter, widget); |
|
|
|
} |
|
|
|
return true; |
|
} |
|
|
|
//______________________________________________________________ |
|
bool Style::drawComboBoxComplexControl( const QStyleOptionComplex* option, QPainter* painter, const QWidget* widget ) const |
|
{ |
|
|
|
// cast option and check |
|
const QStyleOptionComboBox* comboBoxOption( qstyleoption_cast<const QStyleOptionComboBox*>( option ) ); |
|
if( !comboBoxOption ) return true; |
|
|
|
// rect and palette |
|
const QRect& rect( option->rect ); |
|
const QPalette& palette( option->palette ); |
|
|
|
// state |
|
const State& state( option->state ); |
|
const bool enabled( state & State_Enabled ); |
|
const bool mouseOver( enabled && ( state & State_MouseOver ) ); |
|
const bool hasFocus( state & State_HasFocus ); |
|
const bool editable( comboBoxOption->editable ); |
|
const bool sunken( state & (State_On|State_Sunken) ); |
|
const bool flat( !comboBoxOption->frame ); |
|
|
|
// frame |
|
if( option->subControls & SC_ComboBoxFrame ) |
|
{ |
|
|
|
if( editable ) |
|
{ |
|
|
|
const QColor color( palette.color( QPalette::Base ) ); |
|
if( flat ) |
|
{ |
|
|
|
painter->setBrush( color ); |
|
painter->setPen( Qt::NoPen ); |
|
painter->drawRect( rect ); |
|
|
|
} else { |
|
|
|
// editable combobox. Make it look like a LineEdit |
|
// update animation state |
|
// focus takes precedence over hover |
|
_animations->lineEditEngine().updateState( widget, AnimationFocus, hasFocus ); |
|
_animations->lineEditEngine().updateState( widget, AnimationHover, mouseOver && !hasFocus ); |
|
|
|
// outline color |
|
const QColor outline( _helper->frameOutlineColor( palette, mouseOver, hasFocus, |
|
_animations->lineEditEngine().frameOpacity( widget ), |
|
_animations->lineEditEngine().frameAnimationMode( widget ) ) ); |
|
|
|
// render |
|
_helper->renderFrame( painter, rect, color, outline, hasFocus ); |
|
} |
|
|
|
} else { |
|
|
|
// update animation state |
|
// hover takes precedence over focus |
|
_animations->lineEditEngine().updateState( widget, AnimationHover, mouseOver ); |
|
_animations->lineEditEngine().updateState( widget, AnimationFocus, hasFocus && !mouseOver ); |
|
const AnimationMode mode( _animations->lineEditEngine().buttonAnimationMode( widget ) ); |
|
const qreal opacity( _animations->lineEditEngine().buttonOpacity( widget ) ); |
|
|
|
if( flat ) { |
|
|
|
// define colors and render |
|
const QColor color( _helper->toolButtonColor( palette, mouseOver, hasFocus || sunken, opacity, mode ) ); |
|
_helper->renderToolButtonFrame( painter, rect, color, sunken ); |
|
|
|
} else { |
|
|
|
// define colors |
|
const QColor shadow( _helper->shadowColor( palette ) ); |
|
const QColor outline( _helper->buttonOutlineColor( palette, mouseOver, hasFocus, opacity, mode ) ); |
|
const QColor background( _helper->buttonBackgroundColor( palette, mouseOver, hasFocus, opacity, mode ) ); |
|
|
|
// render |
|
_helper->renderButtonFrame( painter, rect, background, outline, shadow, hasFocus, sunken ); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
// arrow |
|
if( option->subControls & SC_ComboBoxArrow ) |
|
{ |
|
|
|
// detect empty comboboxes |
|
const QComboBox* comboBox = qobject_cast<const QComboBox*>( widget ); |
|
const bool empty( comboBox && !comboBox->count() ); |
|
|
|
QColor arrowColor; |
|
if( editable ) |
|
{ |
|
|
|
if( empty || !enabled ) arrowColor = palette.color( QPalette::Disabled, QPalette::Text ); |
|
else { |
|
|
|
// check animation state |
|
const bool subControlHover( enabled && mouseOver && comboBoxOption->activeSubControls&SC_ComboBoxArrow ); |
|
_animations->comboBoxEngine().updateState( widget, AnimationHover, subControlHover ); |
|
|
|
const bool animated( enabled && _animations->comboBoxEngine().isAnimated( widget, AnimationHover ) ); |
|
const qreal opacity( _animations->comboBoxEngine().opacity( widget, AnimationHover ) ); |
|
|
|
// color |
|
const QColor normal( palette.color( QPalette::Text ) ); |
|
const QColor hover( _helper->hoverColor( palette ) ); |
|
|
|
if( animated ) |
|
{ |
|
arrowColor = KColorUtils::mix( normal, hover, opacity ); |
|
|
|
} else if( subControlHover ) { |
|
|
|
arrowColor = hover; |
|
|
|
} else arrowColor = normal; |
|
|
|
} |
|
|
|
} else if( flat ) { |
|
|
|
if( empty || !enabled ) arrowColor = palette.color( QPalette::Disabled, QPalette::WindowText ); |
|
else if( hasFocus && !mouseOver && sunken ) arrowColor = palette.color( QPalette::HighlightedText ); |
|
else arrowColor = palette.color( QPalette::WindowText ); |
|
|
|
} else if( empty || !enabled ) arrowColor = palette.color( QPalette::Disabled, QPalette::ButtonText ); |
|
else if( hasFocus && !mouseOver ) arrowColor = palette.color( QPalette::HighlightedText ); |
|
else arrowColor = palette.color( QPalette::ButtonText ); |
|
|
|
// render arrow |
|
const QRectF arrowRect( comboBoxSubControlRect( option, SC_ComboBoxArrow, widget ) ); |
|
const QPolygonF arrow( genericArrow( ArrowDown, ArrowNormal ) ); |
|
const qreal penThickness( 1.5 ); |
|
|
|
painter->save(); |
|
painter->translate( arrowRect.center() ); |
|
painter->setRenderHint( QPainter::Antialiasing ); |
|
painter->setPen( QPen( arrowColor, penThickness ) ); |
|
painter->drawPolyline( arrow ); |
|
painter->restore(); |
|
|
|
} |
|
|
|
return true; |
|
|
|
} |
|
|
|
//______________________________________________________________ |
|
bool Style::drawSpinBoxComplexControl( const QStyleOptionComplex* option, QPainter* painter, const QWidget* widget ) const |
|
{ |
|
|
|
const QStyleOptionSpinBox *spinBoxOption( qstyleoption_cast<const QStyleOptionSpinBox*>( option ) ); |
|
if( !spinBoxOption ) return true; |
|
|
|
const State& state( option->state ); |
|
const QPalette& palette( option->palette ); |
|
const bool enabled( state & State_Enabled ); |
|
const bool mouseOver( enabled && ( state & State_MouseOver ) ); |
|
const bool hasFocus( enabled && ( state & State_HasFocus ) ); |
|
const bool flat( !spinBoxOption->frame ); |
|
|
|
if( option->subControls & SC_SpinBoxFrame ) |
|
{ |
|
|
|
const QColor background( palette.color( QPalette::Base ) ); |
|
if( flat ) |
|
{ |
|
|
|
painter->setBrush( background ); |
|
painter->setPen( Qt::NoPen ); |
|
painter->drawRect( option->rect ); |
|
|
|
} else { |
|
|
|
// update animation state |
|
// focus takes precedence over hover |
|
_animations->lineEditEngine().updateState( widget, AnimationFocus, hasFocus ); |
|
_animations->lineEditEngine().updateState( widget, AnimationHover, mouseOver && !hasFocus ); |
|
|
|
// outline color |
|
const QColor outline( _helper->frameOutlineColor( palette, mouseOver, hasFocus, |
|
_animations->lineEditEngine().frameOpacity( widget ), |
|
_animations->lineEditEngine().frameAnimationMode( widget ) ) ); |
|
|
|
// render |
|
_helper->renderFrame( painter, option->rect, background, outline, hasFocus ); |
|
} |
|
|
|
} |
|
|
|
if( option->subControls & SC_SpinBoxUp ) renderSpinBoxArrow( painter, spinBoxOption, widget, SC_SpinBoxUp ); |
|
if( option->subControls & SC_SpinBoxDown ) renderSpinBoxArrow( painter, spinBoxOption, widget, SC_SpinBoxDown ); |
|
|
|
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& state( option->state ); |
|
const bool enabled( state & State_Enabled ); |
|
const bool mouseOver( enabled && ( state & State_MouseOver ) ); |
|
const bool hasFocus( enabled && ( state & State_HasFocus ) ); |
|
|
|
// do not render tickmarks |
|
if( sliderOption->subControls & SC_SliderTickmarks ) |
|
{} |
|
|
|
// groove |
|
if( sliderOption->subControls & SC_SliderGroove ) |
|
{ |
|
// retrieve groove rect |
|
QRect grooveRect( subControlRect( CC_Slider, sliderOption, SC_SliderGroove, widget ) ); |
|
|
|
// adjustments |
|
if( sliderOption->orientation == Qt::Horizontal ) |
|
{ |
|
|
|
grooveRect = centerRect( grooveRect, grooveRect.width()-Metrics::Slider_Thickness, Metrics::Slider_Thickness ); |
|
|
|
} else { |
|
|
|
grooveRect = centerRect( grooveRect, Metrics::Slider_Thickness, grooveRect.height()-Metrics::Slider_Thickness ); |
|
|
|
} |
|
|
|
// base color |
|
const QColor grooveColor( _helper->alphaColor( palette.color( QPalette::WindowText ), 0.3 ) ); |
|
|
|
if( !enabled ) _helper->renderSliderGroove( painter, grooveRect, grooveColor ); |
|
else { |
|
|
|
// handle rect |
|
QRect handleRect( subControlRect( CC_Slider, sliderOption, SC_SliderHandle, widget ) ); |
|
handleRect = centerRect( handleRect, Metrics::Slider_ControlThickness, Metrics::Slider_ControlThickness ); |
|
|
|
// highlight color |
|
const QColor highlight( palette.color( QPalette::Highlight ) ); |
|
|
|
if( sliderOption->orientation == Qt::Horizontal ) |
|
{ |
|
|
|
const bool reverseLayout( option->direction == Qt::RightToLeft ); |
|
|
|
QRect leftRect( grooveRect ); |
|
leftRect.setRight( handleRect.right()-1 ); |
|
_helper->renderSliderGroove( painter, leftRect, reverseLayout ? grooveColor:highlight ); |
|
|
|
QRect rightRect( grooveRect ); |
|
rightRect.setLeft( handleRect.left()+1 ); |
|
_helper->renderSliderGroove( painter, rightRect, reverseLayout ? highlight:grooveColor ); |
|
|
|
} else { |
|
|
|
QRect topRect( grooveRect ); |
|
topRect.setBottom( handleRect.bottom()-1 ); |
|
_helper->renderSliderGroove( painter, topRect, highlight ); |
|
|
|
QRect bottomRect( grooveRect ); |
|
bottomRect.setTop( handleRect.top()+1 ); |
|
_helper->renderSliderGroove( painter, bottomRect, grooveColor ); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
// handle |
|
if ( sliderOption->subControls & SC_SliderHandle ) |
|
{ |
|
|
|
// get rect and center |
|
QRect handleRect( subControlRect( CC_Slider, sliderOption, SC_SliderHandle, widget ) ); |
|
handleRect = centerRect( handleRect, Metrics::Slider_ControlThickness, Metrics::Slider_ControlThickness ); |
|
|
|
// handle state |
|
const bool handleActive( sliderOption->activeSubControls & SC_SliderHandle ); |
|
const bool sunken( state & (State_On|State_Sunken) ); |
|
|
|
// animation state |
|
_animations->sliderEngine().updateState( widget, enabled && handleActive ); |
|
const AnimationMode mode( _animations->sliderEngine().isAnimated( widget ) ? AnimationHover:AnimationNone ); |
|
const qreal opacity( _animations->sliderEngine().opacity( widget ) ); |
|
|
|
// define colors |
|
const QColor background( palette.color( QPalette::Button ) ); |
|
const QColor outline( _helper->sliderOutlineColor( palette, handleActive && mouseOver, hasFocus, opacity, mode ) ); |
|
const QColor shadow( _helper->shadowColor( palette ) ); |
|
|
|
// render |
|
_helper->renderSliderHandle( painter, handleRect, background, outline, shadow, hasFocus, sunken ); |
|
|
|
} |
|
|
|
return true; |
|
} |
|
|
|
//______________________________________________________________ |
|
bool Style::drawDialComplexControl( const QStyleOptionComplex* option, QPainter* painter, const QWidget* widget ) const |
|
{ |
|
|
|
// cast option and check |
|
const QStyleOptionSlider *sliderOption( qstyleoption_cast<const QStyleOptionSlider*>( option ) ); |
|
if( !sliderOption ) return true; |
|
|
|
const QPalette& palette( option->palette ); |
|
const State& state( option->state ); |
|
const bool enabled( state & State_Enabled ); |
|
const bool mouseOver( enabled && ( state & State_MouseOver ) ); |
|
const bool hasFocus( enabled && ( state & State_HasFocus ) ); |
|
|
|
// do not render tickmarks |
|
if( sliderOption->subControls & SC_DialTickmarks ) |
|
{} |
|
|
|
// groove |
|
if( sliderOption->subControls & SC_DialGroove ) |
|
{ |
|
|
|
// groove rect |
|
QRect grooveRect( subControlRect( CC_Dial, sliderOption, SC_SliderGroove, widget ) ); |
|
|
|
// groove |
|
const QColor grooveColor( KColorUtils::mix( palette.color( QPalette::Window ), palette.color( QPalette::WindowText ), 0.3 ) ); |
|
|
|
// render groove |
|
_helper->renderDialGroove( painter, grooveRect, grooveColor ); |
|
|
|
if( enabled ) |
|
{ |
|
|
|
// highlight |
|
const QColor highlight( palette.color( QPalette::Highlight ) ); |
|
|
|
// angles |
|
const qreal first( dialAngle( sliderOption, sliderOption->minimum ) ); |
|
const qreal second( dialAngle( sliderOption, sliderOption->sliderPosition ) ); |
|
|
|
// render contents |
|
_helper->renderDialContents( painter, grooveRect, highlight, first, second ); |
|
|
|
} |
|
|
|
} |
|
|
|
// handle |
|
if ( sliderOption->subControls & SC_DialHandle ) |
|
{ |
|
|
|
// get handle rect |
|
QRect handleRect( subControlRect( CC_Dial, sliderOption, SC_DialHandle, widget ) ); |
|
handleRect = centerRect( handleRect, Metrics::Slider_ControlThickness, Metrics::Slider_ControlThickness ); |
|
|
|
// handle state |
|
const bool handleActive( mouseOver && handleRect.contains( _animations->dialEngine().position( widget ) ) ); |
|
const bool sunken( state & (State_On|State_Sunken) ); |
|
|
|
// animation state |
|
_animations->dialEngine().setHandleRect( widget, handleRect ); |
|
_animations->dialEngine().updateState( widget, enabled && handleActive ); |
|
const AnimationMode mode( _animations->dialEngine().isAnimated( widget ) ? AnimationHover:AnimationNone ); |
|
const qreal opacity( _animations->dialEngine().opacity( widget ) ); |
|
|
|
// define colors |
|
const QColor background( palette.color( QPalette::Button ) ); |
|
const QColor outline( _helper->sliderOutlineColor( palette, handleActive && mouseOver, hasFocus, opacity, mode ) ); |
|
const QColor shadow( _helper->shadowColor( palette ) ); |
|
|
|
// render |
|
_helper->renderSliderHandle( painter, handleRect, background, outline, shadow, hasFocus, sunken ); |
|
|
|
} |
|
|
|
return true; |
|
} |
|
|
|
//______________________________________________________________ |
|
bool Style::drawScrollBarComplexControl( const QStyleOptionComplex* option, QPainter* painter, const QWidget* widget ) const |
|
{ |
|
|
|
if( widget ) |
|
{ |
|
painter->setBrush( option->palette.color( widget->backgroundRole() ) ); |
|
painter->setPen( Qt::NoPen ); |
|
painter->drawRect( option->rect ); |
|
} |
|
|
|
// call base class primitive |
|
KStyle::drawComplexControl( CC_ScrollBar, option, painter, widget ); |
|
return true; |
|
} |
|
|
|
//______________________________________________________________________________ |
|
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 ); |
|
const QPolygonF arrow( 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( arrow ); |
|
painter->restore(); |
|
|
|
return; |
|
|
|
} |
|
|
|
//____________________________________________________________________________________________________ |
|
void Style::renderSpinBoxArrow( QPainter* painter, const QStyleOptionSpinBox* option, const QWidget* widget, const SubControl& subControl ) const |
|
{ |
|
|
|
const QPalette& palette( option->palette ); |
|
const State& state( option->state ); |
|
|
|
// enable state |
|
bool enabled( state & State_Enabled ); |
|
|
|
// check steps enable step |
|
const bool atLimit( |
|
(subControl == SC_SpinBoxUp && !(option->stepEnabled & QAbstractSpinBox::StepUpEnabled )) || |
|
(subControl == SC_SpinBoxDown && !(option->stepEnabled & QAbstractSpinBox::StepDownEnabled ) ) ); |
|
|
|
// update enabled state accordingly |
|
enabled &= !atLimit; |
|
|
|
// update mouse-over effect |
|
const bool mouseOver( enabled && ( state & State_MouseOver ) ); |
|
|
|
// check animation state |
|
const bool subControlHover( enabled && mouseOver && ( option->activeSubControls & subControl ) ); |
|
_animations->spinBoxEngine().updateState( widget, subControl, subControlHover ); |
|
|
|
const bool animated( enabled && _animations->spinBoxEngine().isAnimated( widget, subControl ) ); |
|
const qreal opacity( _animations->spinBoxEngine().opacity( widget, subControl ) ); |
|
|
|
QColor color; |
|
if( animated ) |
|
{ |
|
|
|
QColor highlight = _helper->hoverColor( palette ); |
|
color = KColorUtils::mix( palette.color( QPalette::Text ), highlight, opacity ); |
|
|
|
} else if( subControlHover ) { |
|
|
|
color = _helper->hoverColor( palette ); |
|
|
|
} else if( atLimit ) { |
|
|
|
color = palette.color( QPalette::Disabled, QPalette::Text ); |
|
|
|
} else { |
|
|
|
color = palette.color( QPalette::Text ); |
|
|
|
} |
|
|
|
const QPolygonF arrow( genericArrow( ( subControl == SC_SpinBoxUp ) ? ArrowUp:ArrowDown, ArrowNormal ) ); |
|
const QRectF arrowRect( subControlRect( CC_SpinBox, option, subControl, widget ) ); |
|
|
|
painter->save(); |
|
painter->translate( arrowRect.center() ); |
|
painter->setRenderHint( QPainter::Antialiasing ); |
|
|
|
const qreal penThickness = 1.6; |
|
painter->setPen( QPen( color, penThickness ) ); |
|
painter->drawPolyline( arrow ); |
|
painter->restore(); |
|
|
|
return; |
|
|
|
} |
|
|
|
//______________________________________________________________________________ |
|
qreal Style::dialAngle( const QStyleOptionSlider* sliderOption, int value ) const |
|
{ |
|
|
|
// calculate angle at which handle needs to be drawn |
|
qreal angle( 0 ); |
|
if( sliderOption->maximum == sliderOption->minimum ) angle = M_PI / 2; |
|
else { |
|
|
|
qreal fraction( qreal( value - sliderOption->minimum )/qreal( sliderOption->maximum - sliderOption->minimum ) ); |
|
if( !sliderOption->upsideDown ) fraction = 1.0 - fraction; |
|
|
|
if( sliderOption->dialWrapping ) angle = 1.5*M_PI - fraction*2*M_PI; |
|
else angle = ( M_PI*8 - fraction*10*M_PI )/6; |
|
|
|
} |
|
|
|
return angle; |
|
|
|
} |
|
|
|
//______________________________________________________________________________ |
|
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 |
|
{ |
|
|
|
const QRect& rect( 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 mouseOver( _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( mouseOver ? _animations->scrollBarEngine().position( widget ) : QPoint( -1, -1 ) ); |
|
if( mouseOver && rect.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, rect ); |
|
} |
|
|
|
|
|
if( rect.intersects( _animations->scrollBarEngine().subControlRect( widget, control ) ) ) |
|
{ |
|
|
|
QColor highlight = _helper->hoverColor( palette ); |
|
if( animated ) |
|
{ |
|
color = KColorUtils::mix( color, highlight, opacity ); |
|
|
|
} else if( mouseOver ) { |
|
|
|
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; |
|
|
|
} |
|
|
|
//____________________________________________________________________________________ |
|
void Style::setTranslucentBackground( QWidget* widget ) const |
|
{ |
|
widget->setAttribute( Qt::WA_TranslucentBackground ); |
|
|
|
#ifdef Q_WS_WIN |
|
// FramelessWindowHint is needed on windows to make WA_TranslucentBackground work properly |
|
widget->setWindowFlags( widget->windowFlags() | Qt::FramelessWindowHint ); |
|
#endif |
|
|
|
} |
|
|
|
}
|
|
|