diff --git a/kstyle/CMakeLists.txt b/kstyle/CMakeLists.txt
--- a/kstyle/CMakeLists.txt
+++ b/kstyle/CMakeLists.txt
@@ -5,7 +5,8 @@
Config
GuiAddons
ConfigWidgets
- WindowSystem)
+ WindowSystem
+ IconThemes)
find_package(Qt5 COMPONENTS Quick)
set(BREEZE_HAVE_QTQUICK ${Qt5Quick_FOUND})
@@ -93,15 +94,17 @@
breezestyleplugin.cpp
breezetileset.cpp
breezewindowmanager.cpp
+ breezetoolsareamanager.cpp
)
+kconfig_add_kcfg_files(breeze_PART_SRCS ../kdecoration/breezesettings.kcfgc)
kconfig_add_kcfg_files(breeze_PART_SRCS breezestyleconfigdata.kcfgc)
add_library(breeze MODULE ${breeze_PART_SRCS})
target_link_libraries(breeze Qt5::Core Qt5::Gui Qt5::Widgets Qt5::DBus)
if( BREEZE_HAVE_QTQUICK )
target_link_libraries(breeze Qt5::Quick)
endif()
-target_link_libraries(breeze KF5::ConfigCore KF5::ConfigWidgets KF5::GuiAddons KF5::WindowSystem)
+target_link_libraries(breeze KF5::ConfigCore KF5::ConfigWidgets KF5::GuiAddons KF5::WindowSystem KF5::IconThemes)
target_link_libraries(breeze breezecommon5)
if(KF5FrameworkIntegration_FOUND)
diff --git a/kstyle/breeze.kcfg b/kstyle/breeze.kcfg
--- a/kstyle/breeze.kcfg
+++ b/kstyle/breeze.kcfg
@@ -134,6 +134,10 @@
true
+
+ true
+
+
diff --git a/kstyle/breezehelper.h b/kstyle/breezehelper.h
--- a/kstyle/breezehelper.h
+++ b/kstyle/breezehelper.h
@@ -23,25 +23,30 @@
#include "breeze.h"
#include "breezeanimationdata.h"
+#include "breezesettings.h"
#include "config-breeze.h"
#include
#include
+#include
+#include
#include
#include
namespace Breeze
{
//* breeze style helper class.
/** contains utility functions used at multiple places in both breeze style and breeze window decoration */
- class Helper
+ class Helper : public QObject
{
+ Q_OBJECT
+
public:
//* constructor
- explicit Helper( KSharedConfig::Ptr );
+ explicit Helper( KSharedConfig::Ptr, QObject *parent = nullptr );
//* destructor
virtual ~Helper()
@@ -53,6 +58,9 @@
//* pointer to shared config
KSharedConfig::Ptr config() const;
+ //* pointer to kdecoration config
+ QSharedPointer decorationConfig() const;
+
//*@name color utilities
//@{
@@ -245,6 +253,9 @@
//* generic shadow for ellipses
void renderEllipseShadow( QPainter*, const QRectF&, const QColor& ) const;
+
+ //* draw the tools area border
+ void renderToolsAreaBorder ( QPainter*, const QWidget*, bool menubar = false ) const;
//@}
@@ -263,6 +274,29 @@
//* returns true if a given widget supports alpha channel
bool hasAlphaChannel( const QWidget* ) const;
+ //* returns true if widget is in the tools area
+ bool isInToolsArea( const QWidget* ) const;
+
+ //* returns false if tools area is empty
+ bool toolsAreaHasContents ( const QWidget* ) const;
+
+ //* returns true if tools area has a toolbar
+ bool toolsAreaHasToolBar ( const QWidget* ) const;
+
+ //* returns true if the tools area should be drawn
+ bool shouldDrawToolsArea ( const QWidget* ) const;
+
+ //* returns the tools area border color
+ QColor toolsAreaBorderColor ( const QWidget* ) const;
+
+ //* returns the united rectangle of all toolbars in the tools area
+ QRect toolsAreaToolbarsRect (const QWidget* widget) const;
+
+ QToolBar* grabToolBarForToolsArea ( const QWidget* ) const;
+
+ void setToolsAreaEnabled(bool enabled)
+ { _toolsAreaEnabled = enabled; };
+
//@}
//@name high dpi utility functions
@@ -308,6 +342,12 @@
//* configuration
KSharedConfig::Ptr _config;
+ //* KWin configuration
+ KSharedConfig::Ptr _kwinConfig;
+
+ //* decoration configuration
+ QSharedPointer _decorationConfig;
+
//*@name brushes
//@{
KStatefulBrush _viewFocusBrush;
@@ -323,6 +363,8 @@
QColor _inactiveTitleBarTextColor;
//@}
+ bool _toolsAreaEnabled;
+
};
}
diff --git a/kstyle/breezehelper.cpp b/kstyle/breezehelper.cpp
--- a/kstyle/breezehelper.cpp
+++ b/kstyle/breezehelper.cpp
@@ -26,7 +26,11 @@
#include
#include
+#include
+#include
#include
+#include
+#include
#if BREEZE_HAVE_X11
#include
@@ -41,27 +45,55 @@
static const qreal arrowShade = 0.15;
//____________________________________________________________________
- Helper::Helper( KSharedConfig::Ptr config ):
- _config( std::move( config ) )
- {}
+ Helper::Helper( KSharedConfig::Ptr config, QObject *parent ) :
+ _config( std::move( config ) ),
+ _kwinConfig( KSharedConfig::openConfig("kwinrc") ),
+ _decorationConfig( new InternalSettings() ),
+ QObject ( parent )
+ {
+ if (qApp) {
+ connect(qApp, &QApplication::paletteChanged, this, [=]() {
+ if (qApp->property("KDE_COLOR_SCHEME_PATH").isValid()) {
+ const auto path = qApp->property("KDE_COLOR_SCHEME_PATH").toString();
+ KConfig config(path, KConfig::SimpleConfig);
+ KConfigGroup group( config.group("WM") );
+ const QPalette palette( QApplication::palette() );
+ _activeTitleBarColor = group.readEntry( "activeBackground", palette.color( QPalette::Active, QPalette::Highlight ) );
+ _activeTitleBarTextColor = group.readEntry( "activeForeground", palette.color( QPalette::Active, QPalette::HighlightedText ) );
+ _inactiveTitleBarColor = group.readEntry( "inactiveBackground", palette.color( QPalette::Disabled, QPalette::Highlight ) );
+ _inactiveTitleBarTextColor = group.readEntry( "inactiveForeground", palette.color( QPalette::Disabled, QPalette::HighlightedText ) );
+ }
+ });
+ }
+ }
//____________________________________________________________________
KSharedConfig::Ptr Helper::config() const
{ return _config; }
+
+ //____________________________________________________________________
+ QSharedPointer Helper::decorationConfig() const
+ { return _decorationConfig; }
+
//____________________________________________________________________
void Helper::loadConfig()
{
_viewFocusBrush = KStatefulBrush( KColorScheme::View, KColorScheme::FocusColor );
_viewHoverBrush = KStatefulBrush( KColorScheme::View, KColorScheme::HoverColor );
_viewNegativeTextBrush = KStatefulBrush( KColorScheme::View, KColorScheme::NegativeText );
const QPalette palette( QApplication::palette() );
- const KConfigGroup group( _config->group( "WM" ) );
- _activeTitleBarColor = group.readEntry( "activeBackground", palette.color( QPalette::Active, QPalette::Highlight ) );
- _activeTitleBarTextColor = group.readEntry( "activeForeground", palette.color( QPalette::Active, QPalette::HighlightedText ) );
- _inactiveTitleBarColor = group.readEntry( "inactiveBackground", palette.color( QPalette::Disabled, QPalette::Highlight ) );
- _inactiveTitleBarTextColor = group.readEntry( "inactiveForeground", palette.color( QPalette::Disabled, QPalette::HighlightedText ) );
+ _config->reparseConfiguration();
+ _kwinConfig->reparseConfiguration();
+ _decorationConfig->load();
+ KConfig config(qApp->property("KDE_COLOR_SCHEME_PATH").toString(), KConfig::SimpleConfig);
+ KConfigGroup appGroup( config.group("WM") );
+ KConfigGroup globalGroup( _config->group("WM") );
+ _activeTitleBarColor = appGroup.readEntry( "activeBackground", globalGroup.readEntry( "activeBackground", palette.color( QPalette::Active, QPalette::Highlight ) ) );
+ _activeTitleBarTextColor = appGroup.readEntry( "activeForeground", globalGroup.readEntry( "activeForeground", palette.color( QPalette::Active, QPalette::HighlightedText ) ) );
+ _inactiveTitleBarColor = appGroup.readEntry( "inactiveBackground", globalGroup.readEntry( "inactiveBackground", palette.color( QPalette::Disabled, QPalette::Highlight ) ) );
+ _inactiveTitleBarTextColor = appGroup.readEntry( "inactiveForeground", globalGroup.readEntry( "inactiveForeground", palette.color( QPalette::Disabled, QPalette::HighlightedText ) ) );
}
//____________________________________________________________________
@@ -1604,4 +1636,180 @@
return pixmap.devicePixelRatio();
}
+ bool Helper::isInToolsArea(const QWidget* widget) const
+ {
+ if (!shouldDrawToolsArea(widget)) return false;
+
+ auto grabMainWindow = [](const QWidget *widget) {
+ auto window = qobject_cast(widget->window());
+ return window;
+ };
+ auto checkToolbarInToolsArea = [this, grabMainWindow](const QWidget* widget) {
+ auto toolbar = qobject_cast(widget);
+ if (!toolbar) return false;
+
+ QMainWindow* window = grabMainWindow(widget);
+ if (window) {
+ auto rect = toolsAreaToolbarsRect(widget);
+ if (widget->parentWidget() != widget->window()) return false;
+ if (toolbar->isFloating()) return false;
+ if (toolbar->orientation() == Qt::Vertical) return false;
+ if (window->toolBarArea(const_cast(toolbar)) != Qt::TopToolBarArea) return false;
+ if (window->width() != rect.width()) return false;
+ }
+
+ return true;
+ };
+ auto checkMenubarInToolsArea = [grabMainWindow](const QWidget *widget) {
+ QMainWindow* window = grabMainWindow(widget);
+ if (window) {
+ if (window->menuWidget() == widget) {
+ return true;
+ }
+ }
+
+ return false;
+ };
+
+ if (!widget) return false;
+
+ if (!widget->isVisible()) {
+ return false;
+ }
+ if (widget->window()->windowType() == Qt::Dialog) {
+ return false;
+ }
+
+ if (checkToolbarInToolsArea(widget)) {
+ return true;
+ } else if (checkMenubarInToolsArea(widget)) {
+ return true;
+ } else {
+ auto parent = widget->parentWidget();
+ while (parent != nullptr) {
+ if (checkToolbarInToolsArea(parent)) {
+ return true;
+ }
+ if (checkMenubarInToolsArea(parent)) {
+ return true;
+ }
+ parent = parent->parentWidget();
+ }
+ }
+
+ return false;
+ }
+
+ QRect Helper::toolsAreaToolbarsRect (const QWidget* widget) const {
+ auto window = qobject_cast(widget->window());
+ if (!window) return QRect();
+
+ QList widgets = window->findChildren(QString(), Qt::FindDirectChildrenOnly);
+ QRect rect = QRect();
+ for (auto toolbar : widgets) {
+ if (window->toolBarArea(toolbar) == Qt::TopToolBarArea) {
+ rect = rect.united(toolbar->geometry());
+ }
+ }
+ QList menuWidgets = window->findChildren(QString(), Qt::FindDirectChildrenOnly);
+ for (auto menubar : menuWidgets) {
+ rect = rect.united(menubar->geometry());
+ }
+
+ return rect;
+ }
+
+ bool Helper::toolsAreaHasToolBar (const QWidget* widget) const {
+ if (!shouldDrawToolsArea(widget)) return false;
+
+ auto mainWindow = qobject_cast(widget->window());
+ if (mainWindow == nullptr) {
+ return false;
+ }
+
+ QList widgets = mainWindow->findChildren(QString(), Qt::FindDirectChildrenOnly);
+ for (auto widget : widgets) {
+ if (isInToolsArea(widget) == true) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ void Helper::renderToolsAreaBorder(QPainter* painter, const QWidget* widget, bool menubar) const {
+ if (!shouldDrawToolsArea(widget)) return;
+
+ if (!menubar) {
+ auto rect = toolsAreaToolbarsRect(widget);
+
+ if (rect.bottom() != widget->geometry().bottom()) return;
+ }
+
+ painter->setPen(toolsAreaBorderColor(widget));
+ painter->setRenderHints(QPainter::Antialiasing, false);
+ painter->setBrush(Qt::NoBrush);
+
+ painter->drawLine(
+ widget->rect().left()*2,
+ widget->rect().bottom(),
+ widget->rect().right()*2,
+ widget->rect().bottom()
+ );
+ }
+
+ QToolBar* Helper::grabToolBarForToolsArea(const QWidget *widget) const {
+ auto mainWindow = qobject_cast(widget->window());
+ if (mainWindow == nullptr) {
+ return nullptr;
+ }
+
+ QList widgets = mainWindow->findChildren(QString(), Qt::FindDirectChildrenOnly);
+ for (auto widget : widgets) {
+ if (isInToolsArea(widget)) {
+ return widget;
+ }
+ }
+
+ return nullptr;
+ }
+
+ bool Helper::shouldDrawToolsArea(const QWidget* widget) const {
+ if (!widget) return false;
+ if (!_toolsAreaEnabled) return false;
+ KConfigGroup kdecorationGroup(_kwinConfig->group("org.kde.kdecoration2"));
+ auto borderSize = kdecorationGroup.readEntry("BorderSize", "Invalid");
+ if (borderSize != "None" && borderSize != "NoSides") {
+ return false;
+ }
+ auto toolbar = qobject_cast(widget);
+ if (toolbar) {
+ if (toolbar->isFloating()) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ bool Helper::toolsAreaHasContents(const QWidget* widget) const {
+ QList widgets = widget->window()->findChildren();
+ for (auto widget : widgets) {
+ if (isInToolsArea(widget)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ QColor Helper::toolsAreaBorderColor(const QWidget* widget) const {
+ QColor border(
+ KColorUtils::mix(
+ titleBarColor(widget->isActiveWindow()),
+ titleBarTextColor(widget->isActiveWindow()),
+ 0.5
+ )
+ );
+ border.setAlpha(255);
+ return border;
+ }
}
diff --git a/kstyle/breezestyle.h b/kstyle/breezestyle.h
--- a/kstyle/breezestyle.h
+++ b/kstyle/breezestyle.h
@@ -60,6 +60,7 @@
class WidgetExplorer;
class WindowManager;
class BlurHelper;
+ class ToolsAreaManager;
//* convenience typedef for base class
#if !BREEZE_HAVE_KSTYLE
@@ -275,6 +276,7 @@
bool drawIndicatorToolBarHandlePrimitive( const QStyleOption*, QPainter*, const QWidget* ) const;
bool drawIndicatorToolBarSeparatorPrimitive( const QStyleOption*, QPainter*, const QWidget* ) const;
bool drawIndicatorBranchPrimitive( const QStyleOption*, QPainter*, const QWidget* ) const;
+ bool drawWidgetPrimitive( const QStyleOption*, QPainter*, const QWidget* ) const;
//@}
@@ -306,6 +308,8 @@
bool drawToolBoxTabLabelControl( const QStyleOption*, QPainter*, const QWidget* ) const;
bool drawToolBoxTabShapeControl( const QStyleOption*, QPainter*, const QWidget* ) const;
bool drawDockWidgetTitleControl( const QStyleOption*, QPainter*, const QWidget* ) const;
+ bool drawToolBarControl( const QStyleOption*, QPainter*, const QWidget* ) const;
+ bool drawMenuBarEmptyAreaControl( const QStyleOption*, QPainter*, const QWidget* ) const;
//*@}
@@ -497,6 +501,9 @@
//* splitter Factory, to extend splitters hit area
SplitterFactory* _splitterFactory = nullptr;
+ //* signal manager for the tools area
+ ToolsAreaManager* _toolsAreaManager = nullptr;
+
//* widget explorer
WidgetExplorer* _widgetExplorer = nullptr;
diff --git a/kstyle/breezestyle.cpp b/kstyle/breezestyle.cpp
--- a/kstyle/breezestyle.cpp
+++ b/kstyle/breezestyle.cpp
@@ -31,13 +31,17 @@
#include "breezewidgetexplorer.h"
#include "breezewindowmanager.h"
#include "breezeblurhelper.h"
+#include "breezetoolsareamanager.h"
#include
+#include
#include
+#include
#include
#include
#include
+#include
#include
#include
#include
@@ -164,6 +168,7 @@
, _frameShadowFactory( new FrameShadowFactory( this ) )
, _mdiWindowShadowFactory( new MdiWindowShadowFactory( this ) )
, _splitterFactory( new SplitterFactory( this ) )
+ , _toolsAreaManager ( new ToolsAreaManager( _helper, this ) )
, _widgetExplorer( new WidgetExplorer( this ) )
, _tabBarData( new BreezePrivate::TabBarData( this ) )
#if BREEZE_HAVE_KSTYLE
@@ -183,6 +188,17 @@
QStringLiteral( "/BreezeDecoration" ),
QStringLiteral( "org.kde.Breeze.Style" ),
QStringLiteral( "reparseConfiguration" ), this, SLOT(configurationChanged()) );
+
+ dbus.connect( QString(),
+ QStringLiteral( "/KGlobalSettings" ),
+ QStringLiteral( "org.kde.KGlobalSettings" ),
+ QStringLiteral( "notifyChange" ), this, SLOT(configurationChanged()) );
+
+ dbus.connect( QString(),
+ QStringLiteral( "/KWin" ),
+ QStringLiteral( "org.kde.KWin" ),
+ QStringLiteral( "reloadConfig" ), this, SLOT(configurationChanged()));
+
#if QT_VERSION < 0x050D00 // Check if Qt version < 5.13
this->addEventFilter(qApp);
#else
@@ -213,6 +229,7 @@
_mdiWindowShadowFactory->registerWidget( widget );
_shadowHelper->registerWidget( widget );
_splitterFactory->registerWidget( widget );
+ _toolsAreaManager->registerWidget ( widget );
// enable mouse over effects for all necessary widgets
if(
@@ -350,8 +367,9 @@
setTranslucentBackground( widget );
+ } else if ( qobject_cast (widget) || qobject_cast (widget) ) {
+ widget->setAttribute(Qt::WA_StyledBackground);
}
-
// base class polishing
ParentStyleClass::polish( widget );
@@ -439,6 +457,7 @@
_windowManager->unregisterWidget( widget );
_splitterFactory->unregisterWidget( widget );
_blurHelper->unregisterWidget( widget );
+ _toolsAreaManager->unregisterWidget ( widget );
// remove event filter
if( qobject_cast( widget ) ||
@@ -844,6 +863,7 @@
case PE_FrameTabBarBase: fcn = &Style::drawFrameTabBarBasePrimitive; break;
case PE_FrameWindow: fcn = &Style::drawFrameWindowPrimitive; break;
case PE_FrameFocusRect: fcn = _frameFocusPrimitive; break;
+ case PE_Widget: fcn = &Style::drawWidgetPrimitive; break;
// fallback
default: break;
@@ -860,6 +880,53 @@
}
+ bool Style::drawWidgetPrimitive( const QStyleOption* option, QPainter* painter, const QWidget* widget ) const {
+ Q_UNUSED(option)
+ if (qobject_cast(widget) || qobject_cast (widget)) {
+ if (!_helper->toolsAreaHasContents(widget) && _helper->shouldDrawToolsArea(widget)) {
+ painter->save();
+ painter->setPen(_helper->toolsAreaBorderColor(widget));
+ painter->setRenderHints(QPainter::Antialiasing, false);
+ painter->setBrush(Qt::NoBrush);
+
+ painter->drawLine(
+ widget->rect().left()*2,
+ widget->rect().top(),
+ widget->rect().right()*2,
+ widget->rect().top()
+ );
+ painter->restore();
+ } else if (_helper->shouldDrawToolsArea(widget)) {
+ auto rect = _helper->toolsAreaToolbarsRect(widget);
+
+ painter->save();
+ {
+ painter->setBrush(_helper->titleBarColor(widget->isActiveWindow()));
+ painter->setPen(Qt::NoPen);
+
+ painter->drawRect(rect);
+ }
+ painter->restore();
+
+ painter->save();
+ {
+ painter->setPen(_helper->toolsAreaBorderColor(widget));
+ painter->setBrush(Qt::NoBrush);
+ painter->setRenderHints(QPainter::Antialiasing, false);
+
+ painter->drawLine(
+ rect.left()*2,
+ rect.bottom(),
+ rect.right()*2,
+ rect.bottom()
+ );
+ }
+ painter->restore();
+ }
+ }
+ return true;
+ }
+
//______________________________________________________________
void Style::drawControl( ControlElement element, const QStyleOption* option, QPainter* painter, const QWidget* widget ) const
{
@@ -882,10 +949,10 @@
case CE_RadioButtonLabel: fcn = &Style::drawCheckBoxLabelControl; break;
case CE_ToolButtonLabel: fcn = &Style::drawToolButtonLabelControl; break;
case CE_ComboBoxLabel: fcn = &Style::drawComboBoxLabelControl; break;
- case CE_MenuBarEmptyArea: fcn = &Style::emptyControl; break;
+ case CE_MenuBarEmptyArea: fcn = &Style::drawMenuBarEmptyAreaControl; break;
case CE_MenuBarItem: fcn = &Style::drawMenuBarItemControl; break;
case CE_MenuItem: fcn = &Style::drawMenuItemControl; break;
- case CE_ToolBar: fcn = &Style::emptyControl; break;
+ case CE_ToolBar: fcn = &Style::drawToolBarControl; break;
case CE_ProgressBar: fcn = &Style::drawProgressBarControl; break;
case CE_ProgressBarContents: fcn = &Style::drawProgressBarContentsControl; break;
case CE_ProgressBarGroove: fcn = &Style::drawProgressBarGrooveControl; break;
@@ -1331,6 +1398,12 @@
// reload configuration
loadConfiguration();
+ // load new titlebar colours into tools area animations
+ _toolsAreaManager->updateAnimations();
+
+ // trigger update of tools area
+ emit _toolsAreaManager->toolbarUpdated();
+
}
//____________________________________________________________________
@@ -1381,6 +1454,7 @@
// load helper configuration
_helper->loadConfig();
+ _helper->setToolsAreaEnabled(StyleConfigData::toolsAreaEnabled() );
// reinitialize engines
_animations->setupEngines();
@@ -4225,7 +4299,6 @@
// copy rect and palette
const auto& rect = option->rect;
- const auto& palette = option->palette;
// state
const State& state( option->state );
@@ -4329,19 +4402,30 @@
else if( mouseOver && flat ) iconMode = QIcon::Active;
else iconMode = QIcon::Normal;
- const QPixmap pixmap = toolButtonOption->icon.pixmap( iconSize, iconMode, iconState );
+ QPixmap pixmap = toolButtonOption->icon.pixmap( iconSize, iconMode, iconState );
+ if (_helper->isInToolsArea(widget)) {
+ KIconLoader::global()->setCustomPalette(widget->palette());
+ pixmap = toolButtonOption->icon.pixmap( iconSize, iconMode, iconState );
+ KIconLoader::global()->resetPalette();
+ }
drawItemPixmap( painter, iconRect, Qt::AlignCenter, pixmap );
}
// render text
if( hasText && textRect.isValid() )
{
-
QPalette::ColorRole textRole( QPalette::ButtonText );
if( flat ) textRole = ( ((hasFocus&&sunken) || (state & State_Sunken))&&!mouseOver) ? QPalette::HighlightedText: QPalette::WindowText;
else if( hasFocus&&!mouseOver ) textRole = QPalette::HighlightedText;
+ auto palette = option->palette;
+
+ if (_helper->isInToolsArea(widget)) {
+ palette.setColor(QPalette::ButtonText, _helper->titleBarTextColor(widget->isActiveWindow()));
+ palette.setColor(QPalette::WindowText, _helper->titleBarTextColor(widget->isActiveWindow()));
+ }
+
painter->setFont(toolButtonOption->font);
drawItemText( painter, textRect, textFlags, palette, enabled, toolButtonOption->text, textRole );
@@ -4509,15 +4593,22 @@
// copy rect and palette
const auto& rect( option->rect );
- const auto& palette( option->palette );
+ auto palette( option->palette );
+
+ if (_helper->isInToolsArea(widget)) {
+ palette.setColor(QPalette::WindowText, _helper->titleBarTextColor(widget->isActiveWindow()));
+ }
// 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_Sunken) );
const bool useStrongFocus( StyleConfigData::menuItemDrawStrongFocus() );
+ painter->save();
+ painter->setRenderHints( QPainter::Antialiasing );
+
// render hover and focus
if( useStrongFocus && ( selected || sunken ) )
{
@@ -4596,8 +4687,13 @@
}
- return true;
+ if (!_helper->toolsAreaHasToolBar(widget)) {
+ _helper->renderToolsAreaBorder(painter, widget, true);
+ }
+
+ painter->restore();
+ return true;
}
@@ -4817,6 +4913,41 @@
return true;
}
+ bool Style::drawToolBarControl( const QStyleOption* option, QPainter* painter, const QWidget* widget ) const
+ {
+ Q_UNUSED(option)
+ Q_UNUSED(painter)
+ auto toolbar = const_cast(widget);
+
+ if (!_helper->isInToolsArea(widget)) {
+ if (_toolsAreaManager->widgetHasCorrectPaletteSet(toolbar)) {
+ toolbar->setPalette(toolbar->parentWidget()->palette());
+ }
+ return true;
+ }
+
+ if (!_toolsAreaManager->widgetHasCorrectPaletteSet(widget)) {
+ auto palette = toolbar->palette();
+ palette.setColor( QPalette::Window, _toolsAreaManager->background(widget) );
+ palette.setColor( QPalette::WindowText, _toolsAreaManager->foreground(widget) );
+ toolbar->setPalette(palette);
+ }
+
+ return true;
+ }
+
+ bool Style::drawMenuBarEmptyAreaControl( const QStyleOption* option, QPainter* painter, const QWidget* widget ) const
+ {
+ Q_UNUSED(option)
+ if (!_helper->isInToolsArea(widget)) {
+ return true;
+ }
+
+ painter->save();
+ painter->restore();
+ return true;
+ }
+
//___________________________________________________________________________________
bool Style::drawProgressBarControl( const QStyleOption* option, QPainter* painter, const QWidget* widget ) const
{
diff --git a/kstyle/breezetoolsareamanager.h b/kstyle/breezetoolsareamanager.h
new file mode 100644
--- /dev/null
+++ b/kstyle/breezetoolsareamanager.h
@@ -0,0 +1,44 @@
+#ifndef breezetoolsareamanager_h
+#define breezetoolsareamanager_h
+
+#include
+#include
+#include "breezestyle.h"
+#include "breezehelper.h"
+
+namespace Breeze {
+ struct ToolsAreaAnimation {
+ QPointer foregroundColorAnimation;
+ QPointer backgroundColorAnimation;
+ bool prevActive;
+ };
+ class ToolsAreaManager: public QObject
+ {
+ Q_OBJECT
+
+ public:
+ explicit ToolsAreaManager(Helper* helper, QObject *parent = nullptr);
+ ~ToolsAreaManager();
+ void registerWidget(QWidget *widget);
+ void unregisterWidget(QWidget *widget);
+ void updateAnimations();
+
+ QColor foreground(const QWidget *widget);
+ QColor background(const QWidget *widget);
+
+ bool widgetHasCorrectPaletteSet(const QWidget *widget);
+
+ Q_SIGNALS:
+ void toolbarUpdated();
+
+ private:
+ void registerAnimation( QWidget *widget );
+ bool animationRunning( const QWidget *widget );
+ QSet _registeredWidgets;
+ Helper* _helper;
+
+ QMap animationMap;
+ };
+}
+
+#endif
\ No newline at end of file
diff --git a/kstyle/breezetoolsareamanager.cpp b/kstyle/breezetoolsareamanager.cpp
new file mode 100644
--- /dev/null
+++ b/kstyle/breezetoolsareamanager.cpp
@@ -0,0 +1,201 @@
+#include "breezetoolsareamanager.h"
+#include
+#include
+#include
+#include
+#include
+#include
+
+namespace Breeze {
+ ToolsAreaManager::ToolsAreaManager(Helper *helper, QObject *parent) : QObject(parent), _helper(helper) {}
+
+ ToolsAreaManager::~ToolsAreaManager() {}
+
+ void ToolsAreaManager::updateAnimations() {
+ for (auto entry : animationMap) {
+ entry.foregroundColorAnimation->setStartValue(_helper->titleBarTextColor(false));
+ entry.foregroundColorAnimation->setEndValue(_helper->titleBarTextColor(true));
+
+ entry.backgroundColorAnimation->setStartValue(_helper->titleBarColor(false));
+ entry.backgroundColorAnimation->setEndValue(_helper->titleBarColor(true));
+
+ entry.foregroundColorAnimation->setDuration(
+ _helper->decorationConfig()->animationsEnabled() ?
+ _helper->decorationConfig()->animationsDuration() :
+ 0
+ );
+ entry.backgroundColorAnimation->setDuration(
+ _helper->decorationConfig()->animationsEnabled() ?
+ _helper->decorationConfig()->animationsDuration() :
+ 0
+ );
+ }
+ }
+
+ void ToolsAreaManager::registerAnimation(QWidget *widget) {
+ auto window = widget->window()->windowHandle();
+ if (window && !animationMap.contains(window)) {
+
+ auto foregroundColorAnimation = new QVariantAnimation(this);
+ connect(foregroundColorAnimation, &QVariantAnimation::valueChanged,
+ this, &ToolsAreaManager::toolbarUpdated);
+
+ auto backgroundColorAnimation = new QVariantAnimation(this);
+ connect(backgroundColorAnimation, &QVariantAnimation::valueChanged,
+ this, &ToolsAreaManager::toolbarUpdated);
+
+ foregroundColorAnimation->setStartValue(_helper->titleBarTextColor(false));
+ foregroundColorAnimation->setEndValue(_helper->titleBarTextColor(true));
+
+ backgroundColorAnimation->setStartValue(_helper->titleBarColor(false));
+ backgroundColorAnimation->setEndValue(_helper->titleBarColor(true));
+
+ foregroundColorAnimation->setDuration(
+ _helper->decorationConfig()->animationsEnabled() ?
+ _helper->decorationConfig()->animationsDuration() :
+ 0
+ );
+ backgroundColorAnimation->setDuration(
+ _helper->decorationConfig()->animationsEnabled() ?
+ _helper->decorationConfig()->animationsDuration() :
+ 0
+ );
+
+ animationMap[window] = ToolsAreaAnimation{
+ foregroundColorAnimation,
+ backgroundColorAnimation,
+ window->isActive(),
+ };
+
+ connect(window, &QWindow::activeChanged,
+ this, [=]() {
+ if (animationMap[window].foregroundColorAnimation.isNull() || animationMap[window].backgroundColorAnimation.isNull()) return;
+
+ auto prevActive = animationMap[window].prevActive;
+ if (prevActive && !window->isActive()) {
+ animationMap[window].foregroundColorAnimation->setDirection(QAbstractAnimation::Backward);
+ animationMap[window].backgroundColorAnimation->setDirection(QAbstractAnimation::Backward);
+
+ animationMap[window].foregroundColorAnimation->start();
+ animationMap[window].backgroundColorAnimation->start();
+ } else if (!prevActive && window->isActive()) {
+ animationMap[window].foregroundColorAnimation->setDirection(QAbstractAnimation::Forward);
+ animationMap[window].backgroundColorAnimation->setDirection(QAbstractAnimation::Forward);
+
+ animationMap[window].foregroundColorAnimation->start();
+ animationMap[window].backgroundColorAnimation->start();
+ }
+ animationMap[window].prevActive = window->isActive();
+ });
+
+ }
+ }
+
+ bool ToolsAreaManager::animationRunning(const QWidget *widget) {
+ auto window = widget->window()->windowHandle();
+ if (window && animationMap.contains(window)) {
+ return (
+ animationMap[window].foregroundColorAnimation->state() == QAbstractAnimation::Running
+ &&
+ animationMap[window].backgroundColorAnimation->state() == QAbstractAnimation::Running
+ );
+ }
+ return false;
+ }
+
+ QColor ToolsAreaManager::foreground(const QWidget *widget) {
+ auto window = widget->window()->windowHandle();
+ if (window && animationMap.contains(window) && animationMap[window].foregroundColorAnimation) {
+ return animationMap[window].foregroundColorAnimation->currentValue().value();
+ }
+ return QColor();
+ }
+
+ QColor ToolsAreaManager::background(const QWidget *widget) {
+ auto window = widget->window()->windowHandle();
+ if (window && animationMap.contains(window) && animationMap[window].backgroundColorAnimation) {
+ return animationMap[window].backgroundColorAnimation->currentValue().value();
+ }
+ return QColor();
+ }
+
+
+ void ToolsAreaManager::registerWidget(QWidget *widget)
+ {
+ auto window = qobject_cast (widget);
+ if (window) {
+ connect(this, &ToolsAreaManager::toolbarUpdated,
+ window, [this, window]() {
+ if (_helper->toolsAreaHasContents(window)) {
+ window->setContentsMargins(0,0,0,0);
+ } else {
+ window->setContentsMargins(0,1,0,0);
+ }
+ });
+ }
+ connect(this, &ToolsAreaManager::toolbarUpdated,
+ widget, [widget]() {
+ widget->update();
+ });
+ auto toolbar = qobject_cast(widget);
+ if (toolbar) {
+ connect(this, &ToolsAreaManager::toolbarUpdated,
+ widget, [=]() {
+ const auto rect = _helper->toolsAreaToolbarsRect(widget);
+ if (rect.bottom() != widget->geometry().bottom()) {
+ toolbar->setContentsMargins(0,0,0,0);
+ } else {
+ toolbar->setContentsMargins(0,0,0,4);
+ }
+ });
+ connect(toolbar, &QToolBar::visibilityChanged,
+ this, [this]() {
+ emit toolbarUpdated();
+ });
+ connect(toolbar, &QToolBar::orientationChanged,
+ this, [this]() {
+ emit toolbarUpdated();
+ });
+ connect(toolbar, &QToolBar::topLevelChanged,
+ this, [this]() {
+ emit toolbarUpdated();
+ });
+ }
+ connect(widget, &QObject::destroyed,
+ this, [this, widget]() {
+ unregisterWidget(widget);
+ });
+ registerAnimation(widget);
+ _registeredWidgets << widget;
+ emit toolbarUpdated();
+ }
+
+ bool ToolsAreaManager::widgetHasCorrectPaletteSet(const QWidget *widget)
+ {
+ if (animationRunning(widget)) return true;
+ return (
+ widget->palette().color(QPalette::Window) == background(widget)
+ &&
+ widget->palette().color(QPalette::WindowText) == foreground(widget)
+ );
+ }
+
+ void ToolsAreaManager::unregisterWidget(QWidget *widget)
+ {
+ if (qobject_cast(widget)) widget->setContentsMargins(0,0,0,0);
+ _registeredWidgets.remove(widget);
+ QList toRemove;
+ for (auto window : animationMap.keys()) {
+ if (std::none_of(_registeredWidgets.begin(), _registeredWidgets.end(), [window](QWidget *widget) {
+ return window == widget->window()->windowHandle();
+ })) {
+ delete animationMap[window].foregroundColorAnimation;
+ delete animationMap[window].backgroundColorAnimation;
+ toRemove << window;
+ }
+ }
+ for (auto entry : toRemove) {
+ animationMap.remove(entry);
+ }
+ }
+}
\ No newline at end of file
diff --git a/kstyle/config/breezestyleconfig.cpp b/kstyle/config/breezestyleconfig.cpp
--- a/kstyle/config/breezestyleconfig.cpp
+++ b/kstyle/config/breezestyleconfig.cpp
@@ -54,6 +54,7 @@
connect( _menuItemDrawThinFocus, &QAbstractButton::toggled, this, &StyleConfig::updateChanged );
connect( _sliderDrawTickMarks, &QAbstractButton::toggled, this, &StyleConfig::updateChanged );
connect( _splitterProxyEnabled, &QAbstractButton::toggled, this, &StyleConfig::updateChanged );
+ connect( _toolsAreaEnabled, &QAbstractButton::toggled, this, &StyleConfig::updateChanged );
connect( _mnemonicsMode, SIGNAL(currentIndexChanged(int)), SLOT(updateChanged()) );
connect( _animationsEnabled, &QAbstractButton::toggled, this, &StyleConfig::updateChanged );
connect( _animationsDuration, SIGNAL(valueChanged(int)), SLOT(updateChanged()) );
@@ -76,6 +77,7 @@
StyleConfigData::setMenuItemDrawStrongFocus( !_menuItemDrawThinFocus->isChecked() );
StyleConfigData::setSliderDrawTickMarks( _sliderDrawTickMarks->isChecked() );
StyleConfigData::setSplitterProxyEnabled( _splitterProxyEnabled->isChecked() );
+ StyleConfigData::setToolsAreaEnabled( _toolsAreaEnabled->isChecked() );
StyleConfigData::setMnemonicsMode( _mnemonicsMode->currentIndex() );
StyleConfigData::setScrollBarAddLineButtons( _scrollBarAddLineButtons->currentIndex() );
StyleConfigData::setScrollBarSubLineButtons( _scrollBarSubLineButtons->currentIndex() );
@@ -127,6 +129,7 @@
else if( _scrollBarAddLineButtons->currentIndex() != StyleConfigData::scrollBarAddLineButtons() ) modified = true;
else if( _scrollBarSubLineButtons->currentIndex() != StyleConfigData::scrollBarSubLineButtons() ) modified = true;
else if( _splitterProxyEnabled->isChecked() != StyleConfigData::splitterProxyEnabled() ) modified = true;
+ else if( _toolsAreaEnabled->isChecked() != StyleConfigData::toolsAreaEnabled() ) modified = true;
else if( _animationsEnabled->isChecked() != StyleConfigData::animationsEnabled() ) modified = true;
else if( _animationsDuration->value() != StyleConfigData::animationsDuration() ) modified = true;
else if( _windowDragMode->currentIndex() != StyleConfigData::windowDragMode() ) modified = true;
@@ -150,6 +153,7 @@
_sliderDrawTickMarks->setChecked( StyleConfigData::sliderDrawTickMarks() );
_mnemonicsMode->setCurrentIndex( StyleConfigData::mnemonicsMode() );
_splitterProxyEnabled->setChecked( StyleConfigData::splitterProxyEnabled() );
+ _toolsAreaEnabled->setChecked( StyleConfigData::toolsAreaEnabled() );
_scrollBarAddLineButtons->setCurrentIndex( StyleConfigData::scrollBarAddLineButtons() );
_scrollBarSubLineButtons->setCurrentIndex( StyleConfigData::scrollBarSubLineButtons() );
_animationsEnabled->setChecked( StyleConfigData::animationsEnabled() );
diff --git a/kstyle/config/ui/breezestyleconfig.ui b/kstyle/config/ui/breezestyleconfig.ui
--- a/kstyle/config/ui/breezestyleconfig.ui
+++ b/kstyle/config/ui/breezestyleconfig.ui
@@ -39,7 +39,7 @@
General
- -
+
-
@@ -65,7 +65,7 @@
- -
+
-
&Keyboard accelerators visibility:
@@ -78,7 +78,7 @@
- -
+
-
-
@@ -97,7 +97,7 @@
- -
+
-
Qt::Horizontal
@@ -110,7 +110,7 @@
- -
+
-
-
@@ -129,7 +129,7 @@
- -
+
-
Qt::Vertical
@@ -170,6 +170,13 @@
+ -
+
+
+ Visually merge toolbars and menubars into window titlebar
+
+
+