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,16 @@ breezestyleplugin.cpp breezetileset.cpp breezewindowmanager.cpp + breezetoolsareamanager.cpp ) 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.h b/kstyle/breeze.h --- a/kstyle/breeze.h +++ b/kstyle/breeze.h @@ -101,7 +101,7 @@ ScrollBar_DoubleButtonHeight = 2*ScrollBar_Extend, // toolbars - ToolBar_FrameWidth = 2, + ToolBar_FrameWidth = 6, ToolBar_HandleExtent = 10, ToolBar_HandleWidth = 6, ToolBar_SeparatorWidth = 8, @@ -187,7 +187,8 @@ AnimationHover = 0x1, AnimationFocus = 0x2, AnimationEnable = 0x4, - AnimationPressed = 0x8 + AnimationPressed = 0x8, + AnimationWindowFocused = 0x10, }; Q_DECLARE_FLAGS(AnimationModes, AnimationMode) diff --git a/kstyle/breezehelper.h b/kstyle/breezehelper.h --- a/kstyle/breezehelper.h +++ b/kstyle/breezehelper.h @@ -28,6 +28,7 @@ #include #include +#include #include #include @@ -245,6 +246,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 +267,23 @@ //* 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 united rectangle of all toolbars in the tools area + QRect toolsAreaToolbarsRect (const QWidget* widget) const; + + QToolBar* grabToolBarForToolsArea ( const QWidget* ) const; + //@} //@name high dpi utility functions diff --git a/kstyle/breezehelper.cpp b/kstyle/breezehelper.cpp --- a/kstyle/breezehelper.cpp +++ b/kstyle/breezehelper.cpp @@ -27,6 +27,10 @@ #include #include +#include +#include +#include +#include #if BREEZE_HAVE_X11 #include @@ -57,6 +61,7 @@ _viewNegativeTextBrush = KStatefulBrush( KColorScheme::View, KColorScheme::NegativeText ); const QPalette palette( QApplication::palette() ); + _config->reparseConfiguration(); 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 ) ); @@ -1604,4 +1609,165 @@ return pixmap.devicePixelRatio(); } + bool Helper::isInToolsArea(const QWidget* widget) const + { + if (!shouldDrawToolsArea(widget)) return false; + + auto castedWidget = const_cast(widget); + + auto grabMainWindow = [](QWidget *widget) { + auto window = qobject_cast(widget->window()); + return window; + }; + auto checkToolbarInToolsArea = [this, grabMainWindow](QWidget* widget) { + auto toolbar = qobject_cast(widget); + + if (toolbar == nullptr) { + return false; + } + + QMainWindow* window; + if (window = grabMainWindow(widget)) { + auto rect = this->toolsAreaToolbarsRect(widget); + if (widget->parentWidget() != widget->window()) return false; + if (toolbar->isFloating()) return false; + if (toolbar->orientation() == Qt::Vertical) return false; + if (window->toolBarArea(toolbar) != Qt::TopToolBarArea) return false; + if (window->width() != rect.width()) return false; + } + + return true; + }; + auto checkMenubarInToolsArea = [grabMainWindow](QWidget *widget) { + QMainWindow* window; + if (window = grabMainWindow(widget)) { + 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(castedWidget)) { + return true; + } else if (checkMenubarInToolsArea(castedWidget)) { + return true; + } else { + auto parent = castedWidget->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()); + } + } + + 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 (this->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 = this->toolsAreaToolbarsRect(widget); + + if (rect.bottom() != widget->geometry().bottom()) return; + } + + + QColor outline( KColorUtils::mix( widget->palette().color( QPalette::Window ), widget->palette().color( QPalette::WindowText ), 0.75 ) ); + + painter->setPen(QPen(outline, 1*widget->screen()->devicePixelRatio())); + painter->setBrush(Qt::NoBrush); + + painter->drawLine( + widget->rect().left() - 100, + widget->rect().bottom()+1, + widget->rect().right() + 100, + widget->rect().bottom()+1 + ); + } + + 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 (this->isInToolsArea(widget)) { + return widget; + } + } + + return nullptr; + } + + bool Helper::shouldDrawToolsArea(const QWidget* widget) const { + if (!widget) return false; + auto toolbar = qobject_cast(widget); + if (toolbar) { + if (toolbar->isFloating()) { + return false; + } + } + return (widget->window()->palette().color(QPalette::Window) != this->titleBarColor(widget->isActiveWindow())); + } + + bool Helper::toolsAreaHasContents(const QWidget* widget) const { + QList widgets = widget->window()->findChildren(); + for (auto widget : widgets) { + if (this->isInToolsArea(widget)) { + return true; + } + } + return false; + } } 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; + //* widget explorer WidgetExplorer* _widgetExplorer = nullptr; diff --git a/kstyle/breezestyle.cpp b/kstyle/breezestyle.cpp --- a/kstyle/breezestyle.cpp +++ b/kstyle/breezestyle.cpp @@ -31,10 +31,13 @@ #include "breezewidgetexplorer.h" #include "breezewindowmanager.h" #include "breezeblurhelper.h" +#include "breezetoolsareamanager.h" #include +#include #include +#include #include #include #include @@ -52,6 +55,7 @@ #include #include #include +#include #include #include #include @@ -166,6 +170,7 @@ , _splitterFactory( new SplitterFactory( this ) ) , _widgetExplorer( new WidgetExplorer( this ) ) , _tabBarData( new BreezePrivate::TabBarData( this ) ) + , _toolsAreaManager ( new ToolsAreaManager( this, _helper ) ) #if BREEZE_HAVE_KSTYLE , SH_ArgbDndWindow( newStyleHint( QStringLiteral( "SH_ArgbDndWindow" ) ) ) , CE_CapacityBar( newControlElement( QStringLiteral( "CE_CapacityBar" ) ) ) @@ -183,6 +188,12 @@ 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()) ); + #if QT_VERSION < 0x050D00 // Check if Qt version < 5.13 this->addEventFilter(qApp); #else @@ -213,6 +224,7 @@ _mdiWindowShadowFactory->registerWidget( widget ); _shadowHelper->registerWidget( widget ); _splitterFactory->registerWidget( widget ); + _toolsAreaManager->registerWidget ( widget ); // enable mouse over effects for all necessary widgets if( @@ -350,8 +362,9 @@ setTranslucentBackground( widget ); + } else if ( qobject_cast (widget)) { + widget->setAttribute(Qt::WA_StyledBackground); } - // base class polishing ParentStyleClass::polish( widget ); @@ -439,6 +452,7 @@ _windowManager->unregisterWidget( widget ); _splitterFactory->unregisterWidget( widget ); _blurHelper->unregisterWidget( widget ); + _toolsAreaManager->unregisterWidget ( widget ); // remove event filter if( qobject_cast( widget ) || @@ -844,6 +858,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 +875,25 @@ } + bool Style::drawWidgetPrimitive( const QStyleOption* option, QPainter* painter, const QWidget* widget ) const { + if (qobject_cast(widget)) { + if (!_helper->toolsAreaHasContents(widget) && _helper->shouldDrawToolsArea(widget)) { + QColor outline( KColorUtils::mix( _helper->titleBarColor(widget->isActiveWindow()), _helper->titleBarTextColor(widget->isActiveWindow()), 0.75 ) ); + + painter->setPen(QPen(outline, 1*widget->screen()->devicePixelRatio())); + painter->setBrush(Qt::NoBrush); + + painter->drawLine( + widget->rect().left() - 100, + widget->rect().top(), + widget->rect().right() + 100, + widget->rect().top() + ); + } + } + return true; + } + //______________________________________________________________ void Style::drawControl( ControlElement element, const QStyleOption* option, QPainter* painter, const QWidget* widget ) const { @@ -882,10 +916,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 +1365,12 @@ // reload configuration loadConfiguration(); + // load new titlebar colours into tools area animations + _toolsAreaManager->updateAnimations(); + + // trigger update of tools area + emit _toolsAreaManager->toolbarUpdated(); + } //____________________________________________________________________ @@ -4225,7 +4265,12 @@ // 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::ButtonText, _helper->titleBarTextColor(widget->isActiveWindow())); + palette.setColor(QPalette::WindowText, _helper->titleBarTextColor(widget->isActiveWindow())); + } // state const State& state( option->state ); @@ -4304,6 +4349,10 @@ // make sure there is enough room for icon if( iconRect.isValid() ) iconRect = centerRect( iconRect, iconSize ); + 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; + // render arrow or icon if( hasArrow && iconRect.isValid() ) { @@ -4329,19 +4378,20 @@ 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; - painter->setFont(toolButtonOption->font); drawItemText( painter, textRect, textFlags, palette, enabled, toolButtonOption->text, textRole ); @@ -4509,15 +4559,28 @@ // copy rect and palette const auto& rect( option->rect ); - const auto& palette( option->palette ); + auto palette( option->palette ); + + 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 ); + + painter->setPen(_helper->titleBarColor(widget->isActiveWindow())); + painter->setBrush(_helper->titleBarColor(widget->isActiveWindow())); + + QRectF copy(widget->geometry()); + copy.setTop(widget->childrenRect().top()); + + painter->drawRect(copy); + // render hover and focus if( useStrongFocus && ( selected || sunken ) ) { @@ -4596,8 +4659,13 @@ } - return true; + if (!_helper->toolsAreaHasToolBar(widget)) { + _helper->renderToolsAreaBorder(painter, widget, true); + } + + painter->restore(); + return true; } @@ -4817,6 +4885,64 @@ return true; } + bool Style::drawToolBarControl( const QStyleOption* option, QPainter* painter, const QWidget* widget ) const + { + auto toolbar = const_cast(qobject_cast(widget)); + + if (!_helper->isInToolsArea(widget)) { + toolbar->setPalette(toolbar->parentWidget()->palette()); + return true; + } + + + auto palette = toolbar->palette(); + palette.setColor( QPalette::Window, _toolsAreaManager->background(widget) ); + palette.setColor( QPalette::WindowText, _toolsAreaManager->foreground(widget) ); + + toolbar->setPalette(palette); + + painter->save(); + painter->setRenderHints( QPainter::Antialiasing ); + + painter->setBrush(palette.color(QPalette::Window)); + painter->setPen(Qt::NoPen); + + QRectF copy(widget->geometry()); + copy.setTop(widget->childrenRect().top() - 10); + + painter->drawRect(copy); + + _helper->renderToolsAreaBorder(painter, widget); + + painter->restore(); + return true; + } + + bool Style::drawMenuBarEmptyAreaControl( const QStyleOption* option, QPainter* painter, const QWidget* widget ) const + { + if (!_helper->isInToolsArea(widget)) { + return true; + } + + painter->save(); + painter->setRenderHints( QPainter::Antialiasing ); + + painter->setPen(_helper->titleBarColor(widget->isActiveWindow())); + painter->setBrush(_helper->titleBarColor(widget->isActiveWindow())); + + QRectF copy(widget->geometry()); + copy.setTop(widget->childrenRect().top()); + + painter->drawRect(copy); + + if (!_helper->toolsAreaHasToolBar(widget)) { + _helper->renderToolsAreaBorder(painter, widget, true); + } + + 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,40 @@ +#ifndef breezetoolsareamanager_h +#define breezetoolsareamanager_h + +#include +#include +#include "breezehelper.h" + +namespace Breeze { + typedef struct ToolsAreaAnimation { + QVariantAnimation* foregroundColorAnimation; + QVariantAnimation* backgroundColorAnimation; + bool prevActive; + }; + class ToolsAreaManager: public QObject + { + Q_OBJECT + + public: + explicit ToolsAreaManager(QObject *parent = nullptr, Helper* helper = nullptr); + ~ToolsAreaManager(); + void registerWidget(QWidget *widget); + void unregisterWidget(QWidget *widget); + void updateAnimations(); + + QColor foreground(const QWidget *widget); + QColor background(const QWidget *widget); + + QMap animationMap; + + Q_SIGNALS: + void toolbarUpdated(); + + private: + void registerAnimation( QWidget *widget ); + QList _registeredWidgets; + Helper* _helper; + }; +} + +#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,156 @@ +#include "breezetoolsareamanager.h" +#include +#include +#include +#include +#include +#include + +namespace Breeze { + ToolsAreaManager::ToolsAreaManager(QObject *parent, Helper *helper) : QObject(parent), _helper(helper) { + + } + + ToolsAreaManager::~ToolsAreaManager() { + for (auto entry : animationMap) { + delete entry.foregroundColorAnimation; + delete entry.backgroundColorAnimation; + } + } + + 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)); + } + } + + 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(50); + backgroundColorAnimation->setDuration(50); + + animationMap[window] = ToolsAreaAnimation{ + foregroundColorAnimation, + backgroundColorAnimation, + window->isActive(), + }; + + connect(window, &QWindow::activeChanged, + this, [=]() { + auto prevActive = animationMap[window].prevActive; + if (prevActive && !window->isActive()) { + foregroundColorAnimation->setDirection(QAbstractAnimation::Backward); + backgroundColorAnimation->setDirection(QAbstractAnimation::Backward); + + foregroundColorAnimation->start(); + backgroundColorAnimation->start(); + } else if (!prevActive && window->isActive()) { + foregroundColorAnimation->setDirection(QAbstractAnimation::Forward); + backgroundColorAnimation->setDirection(QAbstractAnimation::Forward); + + foregroundColorAnimation->start(); + backgroundColorAnimation->start(); + } + animationMap[window].prevActive = window->isActive(); + }); + + } + } + + 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(toolbar, &QToolBar::visibilityChanged, + this, [this]() { + emit this->toolbarUpdated(); + }); + connect(toolbar, &QToolBar::orientationChanged, + this, [this]() { + emit this->toolbarUpdated(); + }); + connect(toolbar, &QToolBar::topLevelChanged, + this, [this]() { + emit this->toolbarUpdated(); + }); + } + connect(widget, &QObject::destroyed, + this, [this, widget]() { + this->unregisterWidget(widget); + }); + registerAnimation(widget); + _registeredWidgets << widget; + emit this->toolbarUpdated(); + } + + void ToolsAreaManager::unregisterWidget(QWidget *widget) + { + _registeredWidgets.removeAll(widget); + QList toRemove; + for (auto window : animationMap.keys()) { + bool hasWidget = false; + 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