diff --git a/kdecoration/breezesizegrip.cpp b/kdecoration/breezesizegrip.cpp index 37060bc7..595c49dd 100644 --- a/kdecoration/breezesizegrip.cpp +++ b/kdecoration/breezesizegrip.cpp @@ -1,303 +1,303 @@ /************************************************************************* * Copyright (C) 2014 by Hugo Pereira Da Costa * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program 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 General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * *************************************************************************/ #include "breezesizegrip.h" #include #include #include #include #if BREEZE_HAVE_X11 #include #endif namespace Breeze { //* scoped pointer convenience typedef template using ScopedPointer = QScopedPointer; //_____________________________________________ SizeGrip::SizeGrip( Decoration* decoration ):QWidget(nullptr) ,m_decoration( decoration ) { setAttribute(Qt::WA_NoSystemBackground ); setAutoFillBackground( false ); // cursor setCursor( Qt::SizeFDiagCursor ); // size setFixedSize( QSize( GripSize, GripSize ) ); // mask setMask( QRegion( QVector{ QPoint( 0, GripSize ), QPoint( GripSize, 0 ), QPoint( GripSize, GripSize ), QPoint( 0, GripSize )} ) ); // embed embed(); updatePosition(); // connections auto c = decoration->client().data(); connect( c, &KDecoration2::DecoratedClient::widthChanged, this, &SizeGrip::updatePosition ); connect( c, &KDecoration2::DecoratedClient::heightChanged, this, &SizeGrip::updatePosition ); connect( c, &KDecoration2::DecoratedClient::activeChanged, this, &SizeGrip::updateActiveState ); // show show(); } //_____________________________________________ SizeGrip::~SizeGrip() {} //_____________________________________________ void SizeGrip::updateActiveState() { #if BREEZE_HAVE_X11 if( QX11Info::isPlatformX11() ) { const quint32 value = XCB_STACK_MODE_ABOVE; xcb_configure_window( QX11Info::connection(), winId(), XCB_CONFIG_WINDOW_STACK_MODE, &value ); xcb_map_window( QX11Info::connection(), winId() ); } #endif update(); } //_____________________________________________ void SizeGrip::embed() { #if BREEZE_HAVE_X11 if( !QX11Info::isPlatformX11() ) return; auto c = m_decoration.data()->client().data(); xcb_window_t windowId = c->windowId(); if( windowId ) { /* find client's parent we want the size grip to be at the same level as the client in the stack */ xcb_window_t current = windowId; auto connection = QX11Info::connection(); xcb_query_tree_cookie_t cookie = xcb_query_tree_unchecked( connection, current ); ScopedPointer tree(xcb_query_tree_reply( connection, cookie, nullptr ) ); if( !tree.isNull() && tree->parent ) current = tree->parent; // reparent xcb_reparent_window( connection, winId(), current, 0, 0 ); setWindowTitle( "Breeze::SizeGrip" ); } else { hide(); } #endif } //_____________________________________________ void SizeGrip::paintEvent( QPaintEvent* ) { if( !m_decoration ) return; // get relevant colors const QColor backgroundColor( m_decoration.data()->titleBarColor() ); // create and configure painter QPainter painter(this); painter.setRenderHints(QPainter::Antialiasing ); painter.setPen( Qt::NoPen ); painter.setBrush( backgroundColor ); // polygon painter.drawPolygon( QVector { QPoint( 0, GripSize ), QPoint( GripSize, 0 ), QPoint( GripSize, GripSize ), QPoint( 0, GripSize )} ); } //_____________________________________________ void SizeGrip::mousePressEvent( QMouseEvent* event ) { switch (event->button()) { case Qt::RightButton: { hide(); - QTimer::singleShot(5000, this, SLOT(show())); + QTimer::singleShot(5000, this, &QWidget::show); break; } case Qt::MidButton: { hide(); break; } case Qt::LeftButton: if( rect().contains( event->pos() ) ) { sendMoveResizeEvent( event->pos() ); } break; default: break; } } //_______________________________________________________________________________ void SizeGrip::updatePosition() { #if BREEZE_HAVE_X11 if( !QX11Info::isPlatformX11() ) return; auto c = m_decoration.data()->client().data(); QPoint position( c->width() - GripSize - Offset, c->height() - GripSize - Offset ); quint32 values[2] = { quint32(position.x()), quint32(position.y()) }; xcb_configure_window( QX11Info::connection(), winId(), XCB_CONFIG_WINDOW_X | XCB_CONFIG_WINDOW_Y, values ); #endif } //_____________________________________________ void SizeGrip::sendMoveResizeEvent( QPoint position ) { #if BREEZE_HAVE_X11 if( !QX11Info::isPlatformX11() ) return; // pointer to connection auto connection( QX11Info::connection() ); // client auto c = m_decoration.data()->client().data(); /* get root position matching position need to use xcb because the embedding of the widget breaks QT's mapToGlobal and other methods */ QPoint rootPosition( position ); xcb_get_geometry_cookie_t cookie( xcb_get_geometry( connection, winId() ) ); ScopedPointer reply( xcb_get_geometry_reply( connection, cookie, nullptr ) ); if( reply ) { // translate coordinates xcb_translate_coordinates_cookie_t coordCookie( xcb_translate_coordinates( connection, winId(), reply.data()->root, -reply.data()->border_width, -reply.data()->border_width ) ); ScopedPointer< xcb_translate_coordinates_reply_t> coordReply( xcb_translate_coordinates_reply( connection, coordCookie, nullptr ) ); if( coordReply ) { rootPosition.rx() += coordReply.data()->dst_x; rootPosition.ry() += coordReply.data()->dst_y; } } // move/resize atom if( !m_moveResizeAtom ) { // create atom if not found const QString atomName( "_NET_WM_MOVERESIZE" ); xcb_intern_atom_cookie_t cookie( xcb_intern_atom( connection, false, atomName.size(), qPrintable( atomName ) ) ); ScopedPointer reply( xcb_intern_atom_reply( connection, cookie, nullptr ) ); m_moveResizeAtom = reply ? reply->atom:0; } if( !m_moveResizeAtom ) return; // button release event xcb_button_release_event_t releaseEvent; memset(&releaseEvent, 0, sizeof(releaseEvent)); releaseEvent.response_type = XCB_BUTTON_RELEASE; releaseEvent.event = winId(); releaseEvent.child = XCB_WINDOW_NONE; releaseEvent.root = QX11Info::appRootWindow(); releaseEvent.event_x = position.x(); releaseEvent.event_y = position.y(); releaseEvent.root_x = rootPosition.x(); releaseEvent.root_y = rootPosition.y(); releaseEvent.detail = XCB_BUTTON_INDEX_1; releaseEvent.state = XCB_BUTTON_MASK_1; releaseEvent.time = XCB_CURRENT_TIME; releaseEvent.same_screen = true; xcb_send_event( connection, false, winId(), XCB_EVENT_MASK_BUTTON_RELEASE, reinterpret_cast(&releaseEvent)); xcb_ungrab_pointer( connection, XCB_TIME_CURRENT_TIME ); // move resize event xcb_client_message_event_t clientMessageEvent; memset(&clientMessageEvent, 0, sizeof(clientMessageEvent)); clientMessageEvent.response_type = XCB_CLIENT_MESSAGE; clientMessageEvent.type = m_moveResizeAtom; clientMessageEvent.format = 32; clientMessageEvent.window = c->windowId(); clientMessageEvent.data.data32[0] = rootPosition.x(); clientMessageEvent.data.data32[1] = rootPosition.y(); clientMessageEvent.data.data32[2] = 4; // bottom right clientMessageEvent.data.data32[3] = Qt::LeftButton; clientMessageEvent.data.data32[4] = 0; xcb_send_event( connection, false, QX11Info::appRootWindow(), XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY | XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT, reinterpret_cast(&clientMessageEvent) ); xcb_flush( connection ); #endif } } diff --git a/kdecoration/config/breezeconfigwidget.cpp b/kdecoration/config/breezeconfigwidget.cpp index 49f5a123..69b4e60d 100644 --- a/kdecoration/config/breezeconfigwidget.cpp +++ b/kdecoration/config/breezeconfigwidget.cpp @@ -1,217 +1,217 @@ ////////////////////////////////////////////////////////////////////////////// // breezeconfigurationui.cpp // ------------------- // // Copyright (c) 2009 Hugo Pereira Da Costa // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to // deal in the Software without restriction, including without limitation the // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or // sell copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS // IN THE SOFTWARE. ////////////////////////////////////////////////////////////////////////////// #include "breezeconfigwidget.h" #include "breezeexceptionlist.h" #include "breezesettings.h" #include #include #include namespace Breeze { //_________________________________________________________ ConfigWidget::ConfigWidget( QWidget* parent, const QVariantList &args ): KCModule(parent, args), m_configuration( KSharedConfig::openConfig( QStringLiteral( "breezerc" ) ) ), m_changed( false ) { // configuration m_ui.setupUi( this ); // track ui changes connect( m_ui.titleAlignment, SIGNAL(currentIndexChanged(int)), SLOT(updateChanged()) ); connect( m_ui.buttonSize, SIGNAL(currentIndexChanged(int)), SLOT(updateChanged()) ); - connect( m_ui.outlineCloseButton, SIGNAL(clicked()), SLOT(updateChanged()) ); - connect( m_ui.drawBorderOnMaximizedWindows, SIGNAL(clicked()), SLOT(updateChanged()) ); - connect( m_ui.drawSizeGrip, SIGNAL(clicked()), SLOT(updateChanged()) ); - connect( m_ui.drawBackgroundGradient, SIGNAL(clicked()), SLOT(updateChanged()) ); - connect( m_ui.drawTitleBarSeparator, SIGNAL(clicked()), SLOT(updateChanged()) ); + connect( m_ui.outlineCloseButton, &QAbstractButton::clicked, this, &ConfigWidget::updateChanged ); + connect( m_ui.drawBorderOnMaximizedWindows, &QAbstractButton::clicked, this, &ConfigWidget::updateChanged ); + connect( m_ui.drawSizeGrip, &QAbstractButton::clicked, this, &ConfigWidget::updateChanged ); + connect( m_ui.drawBackgroundGradient, &QAbstractButton::clicked, this, &ConfigWidget::updateChanged ); + connect( m_ui.drawTitleBarSeparator, &QAbstractButton::clicked, this, &ConfigWidget::updateChanged ); // track animations changes - connect( m_ui.animationsEnabled, SIGNAL(clicked()), SLOT(updateChanged()) ); + connect( m_ui.animationsEnabled, &QAbstractButton::clicked, this, &ConfigWidget::updateChanged ); connect( m_ui.animationsDuration, SIGNAL(valueChanged(int)), SLOT(updateChanged()) ); // track shadows changes connect( m_ui.shadowSize, SIGNAL(currentIndexChanged(int)), SLOT(updateChanged()) ); connect( m_ui.shadowStrength, SIGNAL(valueChanged(int)), SLOT(updateChanged()) ); - connect( m_ui.shadowColor, SIGNAL(changed(QColor)), SLOT(updateChanged()) ); + connect( m_ui.shadowColor, &KColorButton::changed, this, &ConfigWidget::updateChanged ); // track exception changes - connect( m_ui.exceptions, SIGNAL(changed(bool)), SLOT(updateChanged()) ); + connect( m_ui.exceptions, &ExceptionListWidget::changed, this, &ConfigWidget::updateChanged ); } //_________________________________________________________ void ConfigWidget::load() { // create internal settings and load from rc files m_internalSettings = InternalSettingsPtr( new InternalSettings() ); m_internalSettings->load(); // assign to ui m_ui.titleAlignment->setCurrentIndex( m_internalSettings->titleAlignment() ); m_ui.buttonSize->setCurrentIndex( m_internalSettings->buttonSize() ); m_ui.drawBorderOnMaximizedWindows->setChecked( m_internalSettings->drawBorderOnMaximizedWindows() ); m_ui.outlineCloseButton->setChecked( m_internalSettings->outlineCloseButton() ); m_ui.drawSizeGrip->setChecked( m_internalSettings->drawSizeGrip() ); m_ui.drawBackgroundGradient->setChecked( m_internalSettings->drawBackgroundGradient() ); m_ui.animationsEnabled->setChecked( m_internalSettings->animationsEnabled() ); m_ui.animationsDuration->setValue( m_internalSettings->animationsDuration() ); m_ui.drawTitleBarSeparator->setChecked( m_internalSettings->drawTitleBarSeparator() ); // load shadows if( m_internalSettings->shadowSize() <= InternalSettings::ShadowVeryLarge ) m_ui.shadowSize->setCurrentIndex( m_internalSettings->shadowSize() ); else m_ui.shadowSize->setCurrentIndex( InternalSettings::ShadowLarge ); m_ui.shadowStrength->setValue( qRound(qreal(m_internalSettings->shadowStrength()*100)/255 ) ); m_ui.shadowColor->setColor( m_internalSettings->shadowColor() ); // load exceptions ExceptionList exceptions; exceptions.readConfig( m_configuration ); m_ui.exceptions->setExceptions( exceptions.get() ); setChanged( false ); } //_________________________________________________________ void ConfigWidget::save() { // create internal settings and load from rc files m_internalSettings = InternalSettingsPtr( new InternalSettings() ); m_internalSettings->load(); // apply modifications from ui m_internalSettings->setTitleAlignment( m_ui.titleAlignment->currentIndex() ); m_internalSettings->setButtonSize( m_ui.buttonSize->currentIndex() ); m_internalSettings->setOutlineCloseButton( m_ui.outlineCloseButton->isChecked() ); m_internalSettings->setDrawBorderOnMaximizedWindows( m_ui.drawBorderOnMaximizedWindows->isChecked() ); m_internalSettings->setDrawSizeGrip( m_ui.drawSizeGrip->isChecked() ); m_internalSettings->setDrawBackgroundGradient( m_ui.drawBackgroundGradient->isChecked() ); m_internalSettings->setAnimationsEnabled( m_ui.animationsEnabled->isChecked() ); m_internalSettings->setAnimationsDuration( m_ui.animationsDuration->value() ); m_internalSettings->setDrawTitleBarSeparator(m_ui.drawTitleBarSeparator->isChecked()); m_internalSettings->setShadowSize( m_ui.shadowSize->currentIndex() ); m_internalSettings->setShadowStrength( qRound( qreal(m_ui.shadowStrength->value()*255)/100 ) ); m_internalSettings->setShadowColor( m_ui.shadowColor->color() ); // save configuration m_internalSettings->save(); // get list of exceptions and write InternalSettingsList exceptions( m_ui.exceptions->exceptions() ); ExceptionList( exceptions ).writeConfig( m_configuration ); // sync configuration m_configuration->sync(); setChanged( false ); // needed to tell kwin to reload when running from external kcmshell { QDBusMessage message = QDBusMessage::createSignal("/KWin", "org.kde.KWin", "reloadConfig"); QDBusConnection::sessionBus().send(message); } // needed for breeze style to reload shadows { QDBusMessage message( QDBusMessage::createSignal("/BreezeDecoration", "org.kde.Breeze.Style", "reparseConfiguration") ); QDBusConnection::sessionBus().send(message); } } //_________________________________________________________ void ConfigWidget::defaults() { // create internal settings and load from rc files m_internalSettings = InternalSettingsPtr( new InternalSettings() ); m_internalSettings->setDefaults(); // assign to ui m_ui.titleAlignment->setCurrentIndex( m_internalSettings->titleAlignment() ); m_ui.buttonSize->setCurrentIndex( m_internalSettings->buttonSize() ); m_ui.drawBorderOnMaximizedWindows->setChecked( m_internalSettings->drawBorderOnMaximizedWindows() ); m_ui.drawSizeGrip->setChecked( m_internalSettings->drawSizeGrip() ); m_ui.drawBackgroundGradient->setChecked( m_internalSettings->drawBackgroundGradient() ); m_ui.animationsEnabled->setChecked( m_internalSettings->animationsEnabled() ); m_ui.animationsDuration->setValue( m_internalSettings->animationsDuration() ); m_ui.drawTitleBarSeparator->setChecked( m_internalSettings->drawTitleBarSeparator() ); m_ui.shadowSize->setCurrentIndex( m_internalSettings->shadowSize() ); m_ui.shadowStrength->setValue( qRound(qreal(m_internalSettings->shadowStrength()*100)/255 ) ); m_ui.shadowColor->setColor( m_internalSettings->shadowColor() ); } //_______________________________________________ void ConfigWidget::updateChanged() { // check configuration if( !m_internalSettings ) return; // track modifications bool modified( false ); if (m_ui.drawTitleBarSeparator->isChecked() != m_internalSettings->drawTitleBarSeparator()) modified = true; if( m_ui.titleAlignment->currentIndex() != m_internalSettings->titleAlignment() ) modified = true; else if( m_ui.buttonSize->currentIndex() != m_internalSettings->buttonSize() ) modified = true; else if( m_ui.outlineCloseButton->isChecked() != m_internalSettings->outlineCloseButton() ) modified = true; else if( m_ui.drawBorderOnMaximizedWindows->isChecked() != m_internalSettings->drawBorderOnMaximizedWindows() ) modified = true; else if( m_ui.drawSizeGrip->isChecked() != m_internalSettings->drawSizeGrip() ) modified = true; else if( m_ui.drawBackgroundGradient->isChecked() != m_internalSettings->drawBackgroundGradient() ) modified = true; // animations else if( m_ui.animationsEnabled->isChecked() != m_internalSettings->animationsEnabled() ) modified = true; else if( m_ui.animationsDuration->value() != m_internalSettings->animationsDuration() ) modified = true; // shadows else if( m_ui.shadowSize->currentIndex() != m_internalSettings->shadowSize() ) modified = true; else if( qRound( qreal(m_ui.shadowStrength->value()*255)/100 ) != m_internalSettings->shadowStrength() ) modified = true; else if( m_ui.shadowColor->color() != m_internalSettings->shadowColor() ) modified = true; // exceptions else if( m_ui.exceptions->isChanged() ) modified = true; setChanged( modified ); } //_______________________________________________ void ConfigWidget::setChanged( bool value ) { emit changed( value ); } } diff --git a/kdecoration/config/breezedetectwidget.cpp b/kdecoration/config/breezedetectwidget.cpp index 76391b61..fff5b53e 100644 --- a/kdecoration/config/breezedetectwidget.cpp +++ b/kdecoration/config/breezedetectwidget.cpp @@ -1,182 +1,182 @@ ////////////////////////////////////////////////////////////////////////////// // breezedetectwidget.cpp // Note: this class is a stripped down version of // /kdebase/workspace/kwin/kcmkwin/kwinrules/detectwidget.cpp // Copyright (c) 2004 Lubos Lunak // ------------------- // // Copyright (c) 2009 Hugo Pereira Da Costa // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to // deal in the Software without restriction, including without limitation the // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or // sell copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS // IN THE SOFTWARE. ////////////////////////////////////////////////////////////////////////////// #include "breezedetectwidget.h" #include "breeze.h" #include #include #include #include #if BREEZE_HAVE_X11 #include #include #endif namespace Breeze { //_________________________________________________________ DetectDialog::DetectDialog( QWidget* parent ): QDialog( parent ) { // setup m_ui.setupUi( this ); - connect( m_ui.buttonBox->button( QDialogButtonBox::Cancel ), SIGNAL(clicked()), this, SLOT(close()) ); + connect( m_ui.buttonBox->button( QDialogButtonBox::Cancel ), &QAbstractButton::clicked, this, &QWidget::close ); m_ui.windowClassCheckBox->setChecked( true ); #if BREEZE_HAVE_X11 if (QX11Info::isPlatformX11()) { // create atom xcb_connection_t* connection( QX11Info::connection() ); const QString atomName( QStringLiteral( "WM_STATE" ) ); xcb_intern_atom_cookie_t cookie( xcb_intern_atom( connection, false, atomName.size(), qPrintable( atomName ) ) ); QScopedPointer reply( xcb_intern_atom_reply( connection, cookie, nullptr) ); m_wmStateAtom = reply ? reply->atom : 0; } #endif } //_________________________________________________________ void DetectDialog::detect( WId window ) { if( window == 0 ) selectWindow(); else readWindow( window ); } //_________________________________________________________ void DetectDialog::readWindow( WId window ) { if( window == 0 ) { emit detectionDone( false ); return; } m_info.reset(new KWindowInfo( window, NET::WMAllProperties, NET::WM2AllProperties )); if( !m_info->valid()) { emit detectionDone( false ); return; } const QString wmClassClass( QString::fromUtf8( m_info->windowClassClass() ) ); const QString wmClassName( QString::fromUtf8( m_info->windowClassName() ) ); m_ui.windowClass->setText( QStringLiteral( "%1 (%2 %3)" ).arg( wmClassClass ).arg( wmClassName ).arg( wmClassClass ) ); m_ui.windowTitle->setText( m_info->name() ); emit detectionDone( exec() == QDialog::Accepted ); } //_________________________________________________________ void DetectDialog::selectWindow() { // use a dialog, so that all user input is blocked // use WX11BypassWM and moving away so that it's not actually visible // grab only mouse, so that keyboard can be used e.g. for switching windows m_grabber = new QDialog( nullptr, Qt::X11BypassWindowManagerHint ); m_grabber->move( -1000, -1000 ); m_grabber->setModal( true ); m_grabber->show(); // need to explicitly override cursor for Qt5 qApp->setOverrideCursor( Qt::CrossCursor ); m_grabber->grabMouse( Qt::CrossCursor ); m_grabber->installEventFilter( this ); } //_________________________________________________________ bool DetectDialog::eventFilter( QObject* o, QEvent* e ) { // check object and event type if( o != m_grabber ) return false; if( e->type() != QEvent::MouseButtonRelease ) return false; // need to explicitly release cursor for Qt5 qApp->restoreOverrideCursor(); // delete old m_grabber delete m_grabber; m_grabber = nullptr; // check button if( static_cast< QMouseEvent* >( e )->button() != Qt::LeftButton ) return true; // read window information readWindow( findWindow() ); return true; } //_________________________________________________________ WId DetectDialog::findWindow() { #if BREEZE_HAVE_X11 if (!QX11Info::isPlatformX11()) { return 0; } // check atom if( !m_wmStateAtom ) return 0; xcb_connection_t* connection( QX11Info::connection() ); xcb_window_t parent( QX11Info::appRootWindow() ); // why is there a loop of only 10 here for( int i = 0; i < 10; ++i ) { // query pointer xcb_query_pointer_cookie_t pointerCookie( xcb_query_pointer( connection, parent ) ); QScopedPointer pointerReply( xcb_query_pointer_reply( connection, pointerCookie, nullptr ) ); if( !( pointerReply && pointerReply->child ) ) return 0; const xcb_window_t child( pointerReply->child ); xcb_get_property_cookie_t cookie( xcb_get_property( connection, 0, child, m_wmStateAtom, XCB_GET_PROPERTY_TYPE_ANY, 0, 0 ) ); QScopedPointer reply( xcb_get_property_reply( connection, cookie, nullptr ) ); if( reply && reply->type ) return child; else parent = child; } #endif return 0; } } diff --git a/kdecoration/config/breezeexceptiondialog.cpp b/kdecoration/config/breezeexceptiondialog.cpp index d2b348ab..1111cb56 100644 --- a/kdecoration/config/breezeexceptiondialog.cpp +++ b/kdecoration/config/breezeexceptiondialog.cpp @@ -1,184 +1,184 @@ ////////////////////////////////////////////////////////////////////////////// // breezeexceptiondialog.cpp // ------------------- // // Copyright (c) 2009 Hugo Pereira Da Costa // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to // deal in the Software without restriction, including without limitation the // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or // sell copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS // IN THE SOFTWARE. ////////////////////////////////////////////////////////////////////////////// #include "breezeexceptiondialog.h" #include "breezedetectwidget.h" #include "config-breeze.h" #if BREEZE_HAVE_X11 #include #endif namespace Breeze { //___________________________________________ ExceptionDialog::ExceptionDialog( QWidget* parent ): QDialog( parent ) { m_ui.setupUi( this ); - connect( m_ui.buttonBox->button( QDialogButtonBox::Cancel ), SIGNAL(clicked()), this, SLOT(close()) ); + connect( m_ui.buttonBox->button( QDialogButtonBox::Cancel ), &QAbstractButton::clicked, this, &QWidget::close ); // store checkboxes from ui into list m_checkboxes.insert( BorderSize, m_ui.borderSizeCheckBox ); // detect window properties - connect( m_ui.detectDialogButton, SIGNAL(clicked()), SLOT(selectWindowProperties()) ); + connect( m_ui.detectDialogButton, &QAbstractButton::clicked, this, &ExceptionDialog::selectWindowProperties ); // connections connect( m_ui.exceptionType, SIGNAL(currentIndexChanged(int)), SLOT(updateChanged()) ); - connect( m_ui.exceptionEditor, SIGNAL(textChanged(QString)), SLOT(updateChanged()) ); + connect( m_ui.exceptionEditor, &QLineEdit::textChanged, this, &ExceptionDialog::updateChanged ); connect( m_ui.borderSizeComboBox, SIGNAL(currentIndexChanged(int)), SLOT(updateChanged()) ); for( CheckBoxMap::iterator iter = m_checkboxes.begin(); iter != m_checkboxes.end(); ++iter ) - { connect( iter.value(), SIGNAL(clicked()), SLOT(updateChanged()) ); } + { connect( iter.value(), &QAbstractButton::clicked, this, &ExceptionDialog::updateChanged ); } - connect( m_ui.hideTitleBar, SIGNAL(clicked()), SLOT(updateChanged()) ); + connect( m_ui.hideTitleBar, &QAbstractButton::clicked, this, &ExceptionDialog::updateChanged ); // hide detection dialog on non X11 platforms #if BREEZE_HAVE_X11 if( !QX11Info::isPlatformX11() ) m_ui.detectDialogButton->hide(); #else m_ui.detectDialogButton->hide(); #endif } //___________________________________________ void ExceptionDialog::setException( InternalSettingsPtr exception ) { // store exception internally m_exception = exception; // type m_ui.exceptionType->setCurrentIndex(m_exception->exceptionType() ); m_ui.exceptionEditor->setText( m_exception->exceptionPattern() ); m_ui.borderSizeComboBox->setCurrentIndex( m_exception->borderSize() ); m_ui.hideTitleBar->setChecked( m_exception->hideTitleBar() ); // mask for( CheckBoxMap::iterator iter = m_checkboxes.begin(); iter != m_checkboxes.end(); ++iter ) { iter.value()->setChecked( m_exception->mask() & iter.key() ); } setChanged( false ); } //___________________________________________ void ExceptionDialog::save() { m_exception->setExceptionType( m_ui.exceptionType->currentIndex() ); m_exception->setExceptionPattern( m_ui.exceptionEditor->text() ); m_exception->setBorderSize( m_ui.borderSizeComboBox->currentIndex() ); m_exception->setHideTitleBar( m_ui.hideTitleBar->isChecked() ); // mask unsigned int mask = None; for( CheckBoxMap::iterator iter = m_checkboxes.begin(); iter != m_checkboxes.end(); ++iter ) { if( iter.value()->isChecked() ) mask |= iter.key(); } m_exception->setMask( mask ); setChanged( false ); } //___________________________________________ void ExceptionDialog::updateChanged() { bool modified( false ); if( m_exception->exceptionType() != m_ui.exceptionType->currentIndex() ) modified = true; else if( m_exception->exceptionPattern() != m_ui.exceptionEditor->text() ) modified = true; else if( m_exception->borderSize() != m_ui.borderSizeComboBox->currentIndex() ) modified = true; else if( m_exception->hideTitleBar() != m_ui.hideTitleBar->isChecked() ) modified = true; else { // check mask for( CheckBoxMap::iterator iter = m_checkboxes.begin(); iter != m_checkboxes.end(); ++iter ) { if( iter.value()->isChecked() != (bool)( m_exception->mask() & iter.key() ) ) { modified = true; break; } } } setChanged( modified ); } //___________________________________________ void ExceptionDialog::selectWindowProperties() { // create widget if( !m_detectDialog ) { m_detectDialog = new DetectDialog( this ); - connect( m_detectDialog, SIGNAL(detectionDone(bool)), SLOT(readWindowProperties(bool)) ); + connect( m_detectDialog, &DetectDialog::detectionDone, this, &ExceptionDialog::readWindowProperties ); } m_detectDialog->detect(0); } //___________________________________________ void ExceptionDialog::readWindowProperties( bool valid ) { Q_CHECK_PTR( m_detectDialog ); if( valid ) { // type m_ui.exceptionType->setCurrentIndex( m_detectDialog->exceptionType() ); // window info const KWindowInfo& info( m_detectDialog->windowInfo() ); switch( m_detectDialog->exceptionType() ) { default: case InternalSettings::ExceptionWindowClassName: m_ui.exceptionEditor->setText( QString::fromUtf8( info.windowClassClass() ) ); break; case InternalSettings::ExceptionWindowTitle: m_ui.exceptionEditor->setText( info.name() ); break; } } delete m_detectDialog; m_detectDialog = nullptr; } } diff --git a/kdecoration/config/breezeexceptionlistwidget.cpp b/kdecoration/config/breezeexceptionlistwidget.cpp index 41a03ec3..fd32654b 100644 --- a/kdecoration/config/breezeexceptionlistwidget.cpp +++ b/kdecoration/config/breezeexceptionlistwidget.cpp @@ -1,345 +1,345 @@ ////////////////////////////////////////////////////////////////////////////// // breezeexceptionlistwidget.cpp // ------------------- // // Copyright (c) 2009 Hugo Pereira Da Costa // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to // deal in the Software without restriction, including without limitation the // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or // sell copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS // IN THE SOFTWARE. ////////////////////////////////////////////////////////////////////////////// #include "breezeexceptionlistwidget.h" #include "breezeexceptiondialog.h" #include #include #include #include //__________________________________________________________ namespace Breeze { //__________________________________________________________ ExceptionListWidget::ExceptionListWidget( QWidget* parent ): QWidget( parent ) { // ui m_ui.setupUi( this ); // list m_ui.exceptionListView->setAllColumnsShowFocus( true ); m_ui.exceptionListView->setRootIsDecorated( false ); m_ui.exceptionListView->setSortingEnabled( false ); m_ui.exceptionListView->setModel( &model() ); m_ui.exceptionListView->sortByColumn( ExceptionModel::ColumnType, Qt::AscendingOrder ); m_ui.exceptionListView->setSizePolicy( QSizePolicy( QSizePolicy::MinimumExpanding, QSizePolicy::Ignored ) ); m_ui.moveUpButton->setIcon( QIcon::fromTheme( QStringLiteral( "arrow-up" ) ) ); m_ui.moveDownButton->setIcon( QIcon::fromTheme( QStringLiteral( "arrow-down" ) ) ); m_ui.addButton->setIcon( QIcon::fromTheme( QStringLiteral( "list-add" ) ) ); m_ui.removeButton->setIcon( QIcon::fromTheme( QStringLiteral( "list-remove" ) ) ); m_ui.editButton->setIcon( QIcon::fromTheme( QStringLiteral( "edit-rename" ) ) ); - connect( m_ui.addButton, SIGNAL(clicked()), SLOT(add()) ); - connect( m_ui.editButton, SIGNAL(clicked()), SLOT(edit()) ); - connect( m_ui.removeButton, SIGNAL(clicked()), SLOT(remove()) ); - connect( m_ui.moveUpButton, SIGNAL(clicked()), SLOT(up()) ); - connect( m_ui.moveDownButton, SIGNAL(clicked()), SLOT(down()) ); - - connect( m_ui.exceptionListView, SIGNAL(activated(QModelIndex)), SLOT(edit()) ); - connect( m_ui.exceptionListView, SIGNAL(clicked(QModelIndex)), SLOT(toggle(QModelIndex)) ); - connect( m_ui.exceptionListView->selectionModel(), SIGNAL(selectionChanged(QItemSelection,QItemSelection)), SLOT(updateButtons()) ); + connect( m_ui.addButton, &QAbstractButton::clicked, this, &ExceptionListWidget::add ); + connect( m_ui.editButton, &QAbstractButton::clicked, this, &ExceptionListWidget::edit ); + connect( m_ui.removeButton, &QAbstractButton::clicked, this, &ExceptionListWidget::remove ); + connect( m_ui.moveUpButton, &QAbstractButton::clicked, this, &ExceptionListWidget::up ); + connect( m_ui.moveDownButton, &QAbstractButton::clicked, this, &ExceptionListWidget::down ); + + connect( m_ui.exceptionListView, &QAbstractItemView::activated, this, &ExceptionListWidget::edit ); + connect( m_ui.exceptionListView, &QAbstractItemView::clicked, this, &ExceptionListWidget::toggle ); + connect( m_ui.exceptionListView->selectionModel(), &QItemSelectionModel::selectionChanged, this, &ExceptionListWidget::updateButtons ); updateButtons(); resizeColumns(); } //__________________________________________________________ void ExceptionListWidget::setExceptions( const InternalSettingsList& exceptions ) { model().set( exceptions ); resizeColumns(); setChanged( false ); } //__________________________________________________________ InternalSettingsList ExceptionListWidget::exceptions() { return model().get(); setChanged( false ); } //__________________________________________________________ void ExceptionListWidget::updateButtons() { bool hasSelection( !m_ui.exceptionListView->selectionModel()->selectedRows().empty() ); m_ui.removeButton->setEnabled( hasSelection ); m_ui.editButton->setEnabled( hasSelection ); m_ui.moveUpButton->setEnabled( hasSelection && !m_ui.exceptionListView->selectionModel()->isRowSelected( 0, QModelIndex() ) ); m_ui.moveDownButton->setEnabled( hasSelection && !m_ui.exceptionListView->selectionModel()->isRowSelected( model().rowCount()-1, QModelIndex() ) ); } //_______________________________________________________ void ExceptionListWidget::add() { QPointer dialog = new ExceptionDialog( this ); dialog->setWindowTitle( i18n( "New Exception - Breeze Settings" ) ); InternalSettingsPtr exception( new InternalSettings() ); exception->load(); dialog->setException( exception ); // run dialog and check existence if( !dialog->exec() ) { delete dialog; return; } dialog->save(); delete dialog; // check exceptions if( !checkException( exception ) ) return; // create new item model().add( exception ); setChanged( true ); // make sure item is selected QModelIndex index( model().index( exception ) ); if( index != m_ui.exceptionListView->selectionModel()->currentIndex() ) { m_ui.exceptionListView->selectionModel()->select( index, QItemSelectionModel::Clear|QItemSelectionModel::Select|QItemSelectionModel::Rows ); m_ui.exceptionListView->selectionModel()->setCurrentIndex( index, QItemSelectionModel::Current|QItemSelectionModel::Rows ); } resizeColumns(); } //_______________________________________________________ void ExceptionListWidget::edit() { // retrieve selection QModelIndex current( m_ui.exceptionListView->selectionModel()->currentIndex() ); if( ! model().contains( current ) ) return; InternalSettingsPtr exception( model().get( current ) ); // create dialog QPointer dialog( new ExceptionDialog( this ) ); dialog->setWindowTitle( i18n( "Edit Exception - Breeze Settings" ) ); dialog->setException( exception ); // map dialog if( !dialog->exec() ) { delete dialog; return; } // check modifications if( !dialog->isChanged() ) return; // retrieve exception dialog->save(); delete dialog; // check new exception validity checkException( exception ); resizeColumns(); setChanged( true ); } //_______________________________________________________ void ExceptionListWidget::remove() { // confirmation dialog { QMessageBox messageBox( QMessageBox::Question, i18n("Question - Breeze Settings" ), i18n("Remove selected exception?"), QMessageBox::Yes | QMessageBox::Cancel ); messageBox.button( QMessageBox::Yes )->setText( i18n("Remove") ); messageBox.setDefaultButton( QMessageBox::Cancel ); if( messageBox.exec() == QMessageBox::Cancel ) return; } // remove model().remove( model().get( m_ui.exceptionListView->selectionModel()->selectedRows() ) ); resizeColumns(); updateButtons(); setChanged( true ); } //_______________________________________________________ void ExceptionListWidget::toggle( const QModelIndex& index ) { if( !model().contains( index ) ) return; if( index.column() != ExceptionModel::ColumnEnabled ) return; // get matching exception InternalSettingsPtr exception( model().get( index ) ); exception->setEnabled( !exception->enabled() ); setChanged( true ); } //_______________________________________________________ void ExceptionListWidget::up() { InternalSettingsList selection( model().get( m_ui.exceptionListView->selectionModel()->selectedRows() ) ); if( selection.empty() ) { return; } // retrieve selected indexes in list and store in model QModelIndexList selectedIndices( m_ui.exceptionListView->selectionModel()->selectedRows() ); InternalSettingsList selectedExceptions( model().get( selectedIndices ) ); InternalSettingsList currentException( model().get() ); InternalSettingsList newExceptions; for( InternalSettingsList::const_iterator iter = currentException.constBegin(); iter != currentException.constEnd(); ++iter ) { // check if new list is not empty, current index is selected and last index is not. // if yes, move. if( !( newExceptions.empty() || selectedIndices.indexOf( model().index( *iter ) ) == -1 || selectedIndices.indexOf( model().index( newExceptions.back() ) ) != -1 ) ) { InternalSettingsPtr last( newExceptions.back() ); newExceptions.removeLast(); newExceptions.append( *iter ); newExceptions.append( last ); } else newExceptions.append( *iter ); } model().set( newExceptions ); // restore selection m_ui.exceptionListView->selectionModel()->select( model().index( selectedExceptions.front() ), QItemSelectionModel::Clear|QItemSelectionModel::Select|QItemSelectionModel::Rows ); for( InternalSettingsList::const_iterator iter = selectedExceptions.constBegin(); iter != selectedExceptions.constEnd(); ++iter ) { m_ui.exceptionListView->selectionModel()->select( model().index( *iter ), QItemSelectionModel::Select|QItemSelectionModel::Rows ); } setChanged( true ); } //_______________________________________________________ void ExceptionListWidget::down() { InternalSettingsList selection( model().get( m_ui.exceptionListView->selectionModel()->selectedRows() ) ); if( selection.empty() ) { return; } // retrieve selected indexes in list and store in model QModelIndexList selectedIndices( m_ui.exceptionListView->selectionModel()->selectedIndexes() ); InternalSettingsList selectedExceptions( model().get( selectedIndices ) ); InternalSettingsList currentExceptions( model().get() ); InternalSettingsList newExceptions; InternalSettingsListIterator iter( currentExceptions ); iter.toBack(); while( iter.hasPrevious() ) { InternalSettingsPtr current( iter.previous() ); // check if new list is not empty, current index is selected and last index is not. // if yes, move. if( !( newExceptions.empty() || selectedIndices.indexOf( model().index( current ) ) == -1 || selectedIndices.indexOf( model().index( newExceptions.front() ) ) != -1 ) ) { InternalSettingsPtr first( newExceptions.front() ); newExceptions.removeFirst(); newExceptions.prepend( current ); newExceptions.prepend( first ); } else newExceptions.prepend( current ); } model().set( newExceptions ); // restore selection m_ui.exceptionListView->selectionModel()->select( model().index( selectedExceptions.front() ), QItemSelectionModel::Clear|QItemSelectionModel::Select|QItemSelectionModel::Rows ); for( InternalSettingsList::const_iterator iter = selectedExceptions.constBegin(); iter != selectedExceptions.constEnd(); ++iter ) { m_ui.exceptionListView->selectionModel()->select( model().index( *iter ), QItemSelectionModel::Select|QItemSelectionModel::Rows ); } setChanged( true ); } //_______________________________________________________ void ExceptionListWidget::resizeColumns() const { m_ui.exceptionListView->resizeColumnToContents( ExceptionModel::ColumnEnabled ); m_ui.exceptionListView->resizeColumnToContents( ExceptionModel::ColumnType ); m_ui.exceptionListView->resizeColumnToContents( ExceptionModel::ColumnRegExp ); } //_______________________________________________________ bool ExceptionListWidget::checkException( InternalSettingsPtr exception ) { while( exception->exceptionPattern().isEmpty() || !QRegExp( exception->exceptionPattern() ).isValid() ) { QMessageBox::warning( this, i18n( "Warning - Breeze Settings" ), i18n("Regular Expression syntax is incorrect") ); QPointer dialog( new ExceptionDialog( this ) ); dialog->setException( exception ); if( dialog->exec() == QDialog::Rejected ) { delete dialog; return false; } dialog->save(); delete dialog; } return true; } } diff --git a/kstyle/animations/breezeanimations.cpp b/kstyle/animations/breezeanimations.cpp index 1101af72..2e8aed4e 100644 --- a/kstyle/animations/breezeanimations.cpp +++ b/kstyle/animations/breezeanimations.cpp @@ -1,230 +1,230 @@ /************************************************************************* * Copyright (C) 2014 by Hugo Pereira Da Costa * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program 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 General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * *************************************************************************/ #include "breezeanimations.h" #include "breezepropertynames.h" #include "breezestyleconfigdata.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include namespace Breeze { //____________________________________________________________ Animations::Animations( QObject* parent ): QObject( parent ) { _widgetEnabilityEngine = new WidgetStateEngine( this ); _busyIndicatorEngine = new BusyIndicatorEngine( this ); _comboBoxEngine = new WidgetStateEngine( this ); _toolButtonEngine = new WidgetStateEngine( this ); _spinBoxEngine = new SpinBoxEngine( this ); _toolBoxEngine = new ToolBoxEngine( this ); registerEngine( _headerViewEngine = new HeaderViewEngine( this ) ); registerEngine( _widgetStateEngine = new WidgetStateEngine( this ) ); registerEngine( _inputWidgetEngine = new WidgetStateEngine( this ) ); registerEngine( _scrollBarEngine = new ScrollBarEngine( this ) ); registerEngine( _stackedWidgetEngine = new StackedWidgetEngine( this ) ); registerEngine( _tabBarEngine = new TabBarEngine( this ) ); registerEngine( _dialEngine = new DialEngine( this ) ); } //____________________________________________________________ void Animations::setupEngines() { // animation steps AnimationData::setSteps( StyleConfigData::animationSteps() ); const bool animationsEnabled( StyleConfigData::animationsEnabled() ); const int animationsDuration( StyleConfigData::animationsDuration() ); _widgetEnabilityEngine->setEnabled( animationsEnabled ); _comboBoxEngine->setEnabled( animationsEnabled ); _toolButtonEngine->setEnabled( animationsEnabled ); _spinBoxEngine->setEnabled( animationsEnabled ); _toolBoxEngine->setEnabled( animationsEnabled ); _widgetEnabilityEngine->setDuration( animationsDuration ); _comboBoxEngine->setDuration( animationsDuration ); _toolButtonEngine->setDuration( animationsDuration ); _spinBoxEngine->setDuration( animationsDuration ); _stackedWidgetEngine->setDuration( animationsDuration ); _toolBoxEngine->setDuration( animationsDuration ); // registered engines foreach( const BaseEngine::Pointer& engine, _engines ) { engine.data()->setEnabled( animationsEnabled ); engine.data()->setDuration( animationsDuration ); } // stacked widget transition has an extra flag for animations _stackedWidgetEngine->setEnabled( animationsEnabled && StyleConfigData::stackedWidgetTransitionsEnabled() ); // busy indicator _busyIndicatorEngine->setEnabled( StyleConfigData::progressBarAnimated() ); _busyIndicatorEngine->setDuration( StyleConfigData::progressBarBusyStepDuration() ); } //____________________________________________________________ void Animations::registerWidget( QWidget* widget ) const { if( !widget ) return; // check against noAnimations property QVariant propertyValue( widget->property( PropertyNames::noAnimations ) ); if( propertyValue.isValid() && propertyValue.toBool() ) return; // all widgets are registered to the enability engine. _widgetEnabilityEngine->registerWidget( widget, AnimationEnable ); // install animation timers // for optimization, one should put with most used widgets here first // buttons if( qobject_cast(widget) ) { _toolButtonEngine->registerWidget( widget, AnimationHover|AnimationFocus ); _widgetStateEngine->registerWidget( widget, AnimationHover|AnimationFocus ); } else if( qobject_cast(widget) || qobject_cast(widget) ) { _widgetStateEngine->registerWidget( widget, AnimationHover|AnimationFocus|AnimationPressed ); } else if( qobject_cast(widget) ) { // register to toolbox engine if needed if( qobject_cast( widget->parent() ) ) { _toolBoxEngine->registerWidget( widget ); } _widgetStateEngine->registerWidget( widget, AnimationHover|AnimationFocus ); } // groupboxes else if( QGroupBox* groupBox = qobject_cast( widget ) ) { if( groupBox->isCheckable() ) { _widgetStateEngine->registerWidget( widget, AnimationHover|AnimationFocus ); } } // sliders else if( qobject_cast( widget ) ) { _scrollBarEngine->registerWidget( widget, AnimationHover|AnimationFocus ); } else if( qobject_cast( widget ) ) { _widgetStateEngine->registerWidget( widget, AnimationHover|AnimationFocus ); } else if( qobject_cast( widget ) ) { _dialEngine->registerWidget( widget, AnimationHover|AnimationFocus ); } // progress bar else if( qobject_cast( widget ) ) { _busyIndicatorEngine->registerWidget( widget ); } // combo box else if( qobject_cast( widget ) ) { _comboBoxEngine->registerWidget( widget, AnimationHover ); _inputWidgetEngine->registerWidget( widget, AnimationHover|AnimationFocus ); } // spinbox else if( qobject_cast( widget ) ) { _spinBoxEngine->registerWidget( widget ); _inputWidgetEngine->registerWidget( widget, AnimationHover|AnimationFocus ); } // editors else if( qobject_cast( widget ) ) { _inputWidgetEngine->registerWidget( widget, AnimationHover|AnimationFocus ); } else if( qobject_cast( widget ) ) { _inputWidgetEngine->registerWidget( widget, AnimationHover|AnimationFocus ); } else if( widget->inherits( "KTextEditor::View" ) ) { _inputWidgetEngine->registerWidget( widget, AnimationHover|AnimationFocus ); } // header views // need to come before abstract item view, otherwise is skipped else if( qobject_cast( widget ) ) { _headerViewEngine->registerWidget( widget ); } // lists else if( qobject_cast( widget ) ) { _inputWidgetEngine->registerWidget( widget, AnimationHover|AnimationFocus ); } // tabbar else if( qobject_cast( widget ) ) { _tabBarEngine->registerWidget( widget ); } // scrollarea else if( QAbstractScrollArea* scrollArea = qobject_cast( widget ) ) { if( scrollArea->frameShadow() == QFrame::Sunken && (widget->focusPolicy()&Qt::StrongFocus) ) { _inputWidgetEngine->registerWidget( widget, AnimationHover|AnimationFocus ); } } // stacked widgets if( QStackedWidget* stack = qobject_cast( widget ) ) { _stackedWidgetEngine->registerWidget( stack ); } } //____________________________________________________________ void Animations::unregisterWidget( QWidget* widget ) const { if( !widget ) return; _widgetEnabilityEngine->unregisterWidget( widget ); _spinBoxEngine->unregisterWidget( widget ); _comboBoxEngine->unregisterWidget( widget ); _busyIndicatorEngine->registerWidget( widget ); // the following allows some optimization of widget unregistration // it assumes that a widget can be registered atmost in one of the // engines stored in the list. foreach( const BaseEngine::Pointer& engine, _engines ) { if( engine && engine.data()->unregisterWidget( widget ) ) break; } } //_______________________________________________________________ void Animations::unregisterEngine( QObject* object ) { int index( _engines.indexOf( qobject_cast(object) ) ); if( index >= 0 ) _engines.removeAt( index ); } //_______________________________________________________________ void Animations::registerEngine( BaseEngine* engine ) { _engines.append( engine ); - connect( engine, SIGNAL(destroyed(QObject*)), this, SLOT(unregisterEngine(QObject*)) ); + connect( engine, &QObject::destroyed, this, &Animations::unregisterEngine ); } } diff --git a/kstyle/animations/breezescrollbardata.cpp b/kstyle/animations/breezescrollbardata.cpp index cc61d079..06f161f7 100644 --- a/kstyle/animations/breezescrollbardata.cpp +++ b/kstyle/animations/breezescrollbardata.cpp @@ -1,230 +1,230 @@ /************************************************************************* * Copyright (C) 2014 by Hugo Pereira Da Costa * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program 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 General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * *************************************************************************/ #include "breezescrollbardata.h" #include #include #include Q_GUI_EXPORT QStyleOptionSlider qt_qscrollbarStyleOption(QScrollBar*); namespace Breeze { //______________________________________________ ScrollBarData::ScrollBarData( QObject* parent, QWidget* target, int duration ): WidgetStateData( parent, target, duration ), _position( -1, -1 ) { target->installEventFilter( this ); _addLineData._animation = new Animation( duration, this ); _subLineData._animation = new Animation( duration, this ); _grooveData._animation = new Animation( duration, this ); - connect( addLineAnimation().data(), SIGNAL(finished()), SLOT(clearAddLineRect()) ); - connect( subLineAnimation().data(), SIGNAL(finished()), SLOT(clearSubLineRect()) ); + connect( addLineAnimation().data(), &QAbstractAnimation::finished, this, &ScrollBarData::clearAddLineRect ); + connect( subLineAnimation().data(), &QAbstractAnimation::finished, this, &ScrollBarData::clearSubLineRect ); // setup animation setupAnimation( addLineAnimation(), "addLineOpacity" ); setupAnimation( subLineAnimation(), "subLineOpacity" ); setupAnimation( grooveAnimation(), "grooveOpacity" ); } //______________________________________________ bool ScrollBarData::eventFilter( QObject* object, QEvent* event ) { if( object != target().data() ) { return WidgetStateData::eventFilter( object, event ); } // check event type switch( event->type() ) { case QEvent::HoverEnter: setGrooveHovered(true); grooveAnimation().data()->setDirection( Animation::Forward ); if( !grooveAnimation().data()->isRunning() ) grooveAnimation().data()->start(); break; case QEvent::HoverMove: hoverMoveEvent( object, event ); break; case QEvent::HoverLeave: setGrooveHovered(false); grooveAnimation().data()->setDirection( Animation::Backward ); if( !grooveAnimation().data()->isRunning() ) grooveAnimation().data()->start(); hoverLeaveEvent( object, event ); break; default: break; } return WidgetStateData::eventFilter( object, event ); } //______________________________________________ const Animation::Pointer& ScrollBarData::animation( QStyle::SubControl subcontrol ) const { switch( subcontrol ) { default: case QStyle::SC_ScrollBarSlider: return animation(); case QStyle::SC_ScrollBarAddLine: return addLineAnimation(); case QStyle::SC_ScrollBarSubLine: return subLineAnimation(); case QStyle::SC_ScrollBarGroove: return grooveAnimation(); } } //______________________________________________ qreal ScrollBarData::opacity( QStyle::SubControl subcontrol ) const { switch( subcontrol ) { default: case QStyle::SC_ScrollBarSlider: return opacity(); case QStyle::SC_ScrollBarAddLine: return addLineOpacity(); case QStyle::SC_ScrollBarSubLine: return subLineOpacity(); case QStyle::SC_ScrollBarGroove: return grooveOpacity(); } } //______________________________________________ void ScrollBarData::hoverMoveEvent( QObject* object, QEvent* event ) { // try cast object to scrollbar QScrollBar* scrollBar( qobject_cast( object ) ); if( !scrollBar || scrollBar->isSliderDown() ) return; // retrieve scrollbar option QStyleOptionSlider opt( qt_qscrollbarStyleOption( scrollBar ) ); // cast event QHoverEvent *hoverEvent = static_cast(event); QStyle::SubControl hoverControl = scrollBar->style()->hitTestComplexControl(QStyle::CC_ScrollBar, &opt, hoverEvent->pos(), scrollBar); // update hover state updateAddLineArrow( hoverControl ); updateSubLineArrow( hoverControl ); // store position _position = hoverEvent->pos(); } //______________________________________________ void ScrollBarData::hoverLeaveEvent( QObject*, QEvent* ) { // reset hover state updateSubLineArrow( QStyle::SC_None ); updateAddLineArrow( QStyle::SC_None ); // reset mouse position _position = QPoint( -1, -1 ); } //_____________________________________________________________________ void ScrollBarData::updateSubLineArrow( QStyle::SubControl hoverControl ) { if( hoverControl == QStyle::SC_ScrollBarSubLine ) { if( !subLineArrowHovered() ) { setSubLineArrowHovered( true ); if( enabled() ) { subLineAnimation().data()->setDirection( Animation::Forward ); if( !subLineAnimation().data()->isRunning() ) subLineAnimation().data()->start(); } else setDirty(); } } else { if( subLineArrowHovered() ) { setSubLineArrowHovered( false ); if( enabled() ) { subLineAnimation().data()->setDirection( Animation::Backward ); if( !subLineAnimation().data()->isRunning() ) subLineAnimation().data()->start(); } else setDirty(); } } } //_____________________________________________________________________ void ScrollBarData::updateAddLineArrow( QStyle::SubControl hoverControl ) { if( hoverControl == QStyle::SC_ScrollBarAddLine ) { if( !addLineArrowHovered() ) { setAddLineArrowHovered( true ); if( enabled() ) { addLineAnimation().data()->setDirection( Animation::Forward ); if( !addLineAnimation().data()->isRunning() ) addLineAnimation().data()->start(); } else setDirty(); } } else { if( addLineArrowHovered() ) { setAddLineArrowHovered( false ); if( enabled() ) { addLineAnimation().data()->setDirection( Animation::Backward ); if( !addLineAnimation().data()->isRunning() ) addLineAnimation().data()->start(); } else setDirty(); } } } } diff --git a/kstyle/animations/breezestackedwidgetdata.cpp b/kstyle/animations/breezestackedwidgetdata.cpp index 85fc29db..359250cb 100644 --- a/kstyle/animations/breezestackedwidgetdata.cpp +++ b/kstyle/animations/breezestackedwidgetdata.cpp @@ -1,139 +1,139 @@ ////////////////////////////////////////////////////////////////////////////// // breezestackedwidgetdata.cpp // data container for QStackedWidget transition // ------------------- // // Copyright (c) 2009 Hugo Pereira Da Costa // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to // deal in the Software without restriction, including without limitation the // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or // sell copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS // IN THE SOFTWARE. ////////////////////////////////////////////////////////////////////////////// #include "breezestackedwidgetdata.h" namespace Breeze { //______________________________________________________ StackedWidgetData::StackedWidgetData( QObject* parent, QStackedWidget* target, int duration ): TransitionData( parent, target, duration ), _target( target ), _index( target->currentIndex() ) { // configure transition - connect( _target.data(), SIGNAL(destroyed()), SLOT(targetDestroyed()) ); + connect( _target.data(), &QObject::destroyed, this, &StackedWidgetData::targetDestroyed ); connect( _target.data(), SIGNAL(currentChanged(int)), SLOT(animate()) ); // disable focus transition().data()->setAttribute(Qt::WA_NoMousePropagation, true); transition().data()->setFlag(TransitionWidget::PaintOnWidget, true); setMaxRenderTime( 50 ); } //___________________________________________________________________ bool StackedWidgetData::initializeAnimation() { // check enability if( !( _target && _target.data()->isVisible() ) ) { return false; } // check index if( _target.data()->currentIndex() == _index ) { return false; } // do not animate if either index or currentIndex is not valid // but update _index none the less if( _target.data()->currentIndex() < 0 || _index < 0 ) { _index = _target.data()->currentIndex(); return false; } // get old widget (matching _index) and initialize transition if( QWidget *widget = _target.data()->widget( _index ) ) { transition().data()->setOpacity( 0 ); startClock(); transition().data()->setGeometry( widget->geometry() ); transition().data()->setStartPixmap( transition().data()->grab( widget ) ); _index = _target.data()->currentIndex(); return !slow(); } else { _index = _target.data()->currentIndex(); return false; } } //___________________________________________________________________ bool StackedWidgetData::animate() { // check enability if( !enabled() ) return false; // initialize animation if( !initializeAnimation() ) return false; // show transition widget transition().data()->show(); transition().data()->raise(); transition().data()->animate(); return true; } //___________________________________________________________________ void StackedWidgetData::finishAnimation() { // disable updates on currentWidget if( _target && _target.data()->currentWidget() ) { _target.data()->currentWidget()->setUpdatesEnabled( false ); } // hide transition transition().data()->hide(); // reenable updates and repaint if( _target && _target.data()->currentWidget() ) { _target.data()->currentWidget()->setUpdatesEnabled( true ); _target.data()->currentWidget()->repaint(); } // invalidate start widget transition().data()->resetStartPixmap(); } //___________________________________________________________________ void StackedWidgetData::targetDestroyed() { setEnabled( false ); _target.clear(); } } diff --git a/kstyle/animations/breezetransitionwidget.cpp b/kstyle/animations/breezetransitionwidget.cpp index 45fd0c92..8cddd45f 100644 --- a/kstyle/animations/breezetransitionwidget.cpp +++ b/kstyle/animations/breezetransitionwidget.cpp @@ -1,304 +1,304 @@ ////////////////////////////////////////////////////////////////////////////// // breezetransitionwidget.cpp // stores event filters and maps widgets to transitions for transitions // ------------------- // // Copyright (c) 2009 Hugo Pereira Da Costa // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to // deal in the Software without restriction, including without limitation the // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or // sell copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS // IN THE SOFTWARE. ////////////////////////////////////////////////////////////////////////////// #include "breezetransitionwidget.h" #include #include #include #include namespace Breeze { //________________________________________________ bool TransitionWidget::_paintEnabled = true; bool TransitionWidget::paintEnabled() { return _paintEnabled; } int TransitionWidget::_steps = 0; //________________________________________________ TransitionWidget::TransitionWidget( QWidget* parent, int duration ): QWidget( parent ), _animation( new Animation( duration, this ) ) { // background flags setAttribute( Qt::WA_NoSystemBackground ); setAutoFillBackground( false ); // setup animation _animation.data()->setStartValue( 0 ); _animation.data()->setEndValue( 1.0 ); _animation.data()->setTargetObject( this ); _animation.data()->setPropertyName( "opacity" ); // hide when animation is finished - connect( _animation.data(), SIGNAL(finished()), SLOT(hide()) ); + connect( _animation.data(), &QAbstractAnimation::finished, this, &QWidget::hide ); } //________________________________________________ QPixmap TransitionWidget::grab( QWidget* widget, QRect rect ) { // change rect if( !rect.isValid() ) rect = widget->rect(); if( !rect.isValid() ) return QPixmap(); // initialize pixmap QPixmap out( rect.size() ); out.fill( Qt::transparent ); _paintEnabled = false; if( testFlag( GrabFromWindow ) ) { rect = rect.translated( widget->mapTo( widget->window(), widget->rect().topLeft() ) ); widget = widget->window(); out = widget->grab( rect ); } else { if( !testFlag( Transparent ) ) { grabBackground( out, widget, rect ); } grabWidget( out, widget, rect ); } _paintEnabled = true; return out; } //________________________________________________ bool TransitionWidget::event( QEvent* event ) { switch( event->type() ) { case QEvent::MouseButtonPress: case QEvent::MouseButtonRelease: case QEvent::KeyPress: case QEvent::KeyRelease: endAnimation(); hide(); event->ignore(); return false; default: return QWidget::event( event ); } } //________________________________________________ void TransitionWidget::paintEvent( QPaintEvent* event ) { // fully transparent case if( opacity() >= 1.0 && endPixmap().isNull() ) return; if( !_paintEnabled ) return; // get rect QRect rect = event->rect(); if( !rect.isValid() ) rect = this->rect(); // local pixmap const bool paintOnWidget( testFlag( PaintOnWidget ) && !testFlag( Transparent ) ); if( !paintOnWidget ) { if( _currentPixmap.isNull() || _currentPixmap.size() != size() ) { _currentPixmap = QPixmap( size() ); } } // fill _currentPixmap.fill( Qt::transparent ); // copy local pixmap to current { QPainter p; // draw end pixmap first, provided that opacity is small enough if( opacity() >= 0.004 && !_endPixmap.isNull() ) { // faded endPixmap if parent target is transparent and opacity is if( opacity() <= 0.996 && testFlag( Transparent ) ) { fade( _endPixmap, _currentPixmap, opacity(), rect ); p.begin( &_currentPixmap ); p.setClipRect( event->rect() ); } else { if( paintOnWidget ) p.begin( this ); else p.begin( &_currentPixmap ); p.setClipRect( event->rect() ); p.drawPixmap( QPoint(), _endPixmap ); } } else { if( paintOnWidget ) p.begin( this ); else p.begin( &_currentPixmap ); p.setClipRect( event->rect() ); } // draw fading start pixmap if( opacity() <= 0.996 && !_startPixmap.isNull() ) { if( opacity() >= 0.004 ) { fade( _startPixmap, _localStartPixmap, 1.0-opacity(), rect ); p.drawPixmap( QPoint(), _localStartPixmap ); } else p.drawPixmap( QPoint(), _startPixmap ); } p.end(); } // copy current pixmap on widget if( !paintOnWidget ) { QPainter p( this ); p.setClipRect( event->rect() ); p.drawPixmap( QPoint(0,0), _currentPixmap ); p.end(); } } //________________________________________________ void TransitionWidget::grabBackground( QPixmap& pixmap, QWidget* widget, QRect& rect ) const { if( !widget ) return; QWidgetList widgets; if( widget->autoFillBackground() ) { widgets.append( widget ); } QWidget *parent(nullptr); // get highest level parent for( parent = widget->parentWidget(); parent; parent = parent->parentWidget() ) { if( !( parent->isVisible() && parent->rect().isValid() ) ) continue; // store in list widgets.append( parent ); // stop at topLevel if( parent->isTopLevel() || parent->autoFillBackground() ) break; } if( !parent ) parent = widget; // painting QPainter p(&pixmap); p.setClipRect( rect ); const QBrush backgroundBrush = parent->palette().brush( parent->backgroundRole()); if( backgroundBrush.style() == Qt::TexturePattern) { p.drawTiledPixmap( rect, backgroundBrush.texture(), widget->mapTo( parent, rect.topLeft() ) ); } else { p.fillRect( pixmap.rect(), backgroundBrush ); } if( parent->isTopLevel() && parent->testAttribute(Qt::WA_StyledBackground)) { QStyleOption option; option.initFrom(parent); option.rect = rect; option.rect.translate( widget->mapTo( parent, rect.topLeft() ) ); p.translate(-option.rect.topLeft()); parent->style()->drawPrimitive ( QStyle::PE_Widget, &option, &p, parent ); p.translate(option.rect.topLeft()); } // draw all widgets in parent list // backward QPaintEvent event(rect); for( int i = widgets.size() - 1; i>=0; i-- ) { QWidget* w = widgets.at(i); w->render( &p, -widget->mapTo( w, rect.topLeft() ), rect, nullptr ); } // end p.end(); } //________________________________________________ void TransitionWidget::grabWidget( QPixmap& pixmap, QWidget* widget, QRect& rect ) const { widget->render( &pixmap, pixmap.rect().topLeft(), rect, QWidget::DrawChildren ); } //________________________________________________ void TransitionWidget::fade( const QPixmap& source, QPixmap& target, qreal opacity, const QRect& rect ) const { if( target.isNull() || target.size() != size() ) { target = QPixmap( size() ); } // erase target target.fill( Qt::transparent ); // check opacity if( opacity*255 < 1 ) return; QPainter p( &target ); p.setClipRect( rect ); // draw pixmap p.drawPixmap( QPoint(0,0), source ); // opacity mask (0.996 corresponds to 254/255) if( opacity <= 0.996 ) { p.setCompositionMode(QPainter::CompositionMode_DestinationIn); QColor color( Qt::black ); color.setAlphaF( opacity ); p.fillRect(rect, color ); } p.end(); } } diff --git a/kstyle/breezeframeshadow.cpp b/kstyle/breezeframeshadow.cpp index d3dc98bb..dc5fead7 100644 --- a/kstyle/breezeframeshadow.cpp +++ b/kstyle/breezeframeshadow.cpp @@ -1,355 +1,355 @@ /************************************************************************* * Copyright (C) 2014 by Hugo Pereira Da Costa * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program 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 General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * *************************************************************************/ #include "breezeframeshadow.h" #include "breeze.h" #include #include #include #include #include #include #include #include namespace Breeze { //____________________________________________________________________________________ bool FrameShadowFactory::registerWidget( QWidget* widget, Helper& helper ) { if( !widget ) return false; if( isRegistered( widget ) ) return false; // check whether widget is a frame, and has the proper shape bool accepted = false; // cast to frame and check QFrame* frame( qobject_cast( widget ) ); if( frame ) { // also do not install on QSplitter /* due to Qt, splitters are set with a frame style that matches the condition below, though no shadow should be installed, obviously */ if( qobject_cast( widget ) ) return false; // further checks on frame shape, and parent if( frame->frameStyle() == (QFrame::StyledPanel | QFrame::Sunken) ) accepted = true; } else if( widget->inherits( "KTextEditor::View" ) ) accepted = true; if( !accepted ) return false; // make sure that the widget is not embedded into a KHTMLView QWidget* parent( widget->parentWidget() ); while( parent && !parent->isTopLevel() ) { if( parent->inherits( "KHTMLView" ) ) return false; parent = parent->parentWidget(); } // store in set _registeredWidgets.insert( widget ); // catch object destruction - connect( widget, SIGNAL(destroyed(QObject*)), SLOT(widgetDestroyed(QObject*)) ); + connect( widget, &QObject::destroyed, this, &FrameShadowFactory::widgetDestroyed ); // install shadow installShadows( widget, helper ); return true; } //____________________________________________________________________________________ void FrameShadowFactory::unregisterWidget( QWidget* widget ) { if( !isRegistered( widget ) ) return; _registeredWidgets.remove( widget ); removeShadows( widget ); } //____________________________________________________________________________________ bool FrameShadowFactory::eventFilter( QObject* object, QEvent* event ) { switch( event->type() ) { // TODO: possibly implement ZOrderChange event, to make sure that // the shadow is always painted on top case QEvent::ZOrderChange: { raiseShadows( object ); break; } default: break; } return QObject::eventFilter( object, event ); } //____________________________________________________________________________________ void FrameShadowFactory::installShadows( QWidget* widget, Helper& helper ) { removeShadows(widget); widget->installEventFilter(this); widget->installEventFilter( &_addEventFilter ); installShadow( widget, helper, SideTop ); installShadow( widget, helper, SideBottom ); widget->removeEventFilter( &_addEventFilter ); } //____________________________________________________________________________________ void FrameShadowFactory::removeShadows( QWidget* widget ) { widget->removeEventFilter( this ); const QList children = widget->children(); foreach( QObject *child, children ) { if( FrameShadow* shadow = qobject_cast(child) ) { shadow->hide(); shadow->setParent(nullptr); shadow->deleteLater(); } } } //____________________________________________________________________________________ void FrameShadowFactory::updateShadowsGeometry( const QObject* object, QRect rect ) const { const QList &children = object->children(); foreach( QObject *child, children ) { if( FrameShadow* shadow = qobject_cast(child) ) { shadow->updateGeometry( rect ); } } } //____________________________________________________________________________________ void FrameShadowFactory::raiseShadows( QObject* object ) const { const QList &children = object->children(); foreach( QObject *child, children ) { if( FrameShadow* shadow = qobject_cast(child) ) { shadow->raise(); } } } //____________________________________________________________________________________ void FrameShadowFactory::update( QObject* object ) const { const QList &children = object->children(); foreach( QObject *child, children ) { if( FrameShadow* shadow = qobject_cast(child) ) { shadow->update();} } } //____________________________________________________________________________________ void FrameShadowFactory::updateState( const QWidget* widget, bool focus, bool hover, qreal opacity, AnimationMode mode ) const { const QList &children = widget->children(); foreach( QObject *child, children ) { if( FrameShadow* shadow = qobject_cast(child) ) { shadow->updateState( focus, hover, opacity, mode ); } } } //____________________________________________________________________________________ void FrameShadowFactory::installShadow( QWidget* widget, Helper& helper, Side area ) const { FrameShadow *shadow(nullptr); shadow = new FrameShadow( area, helper ); shadow->setParent(widget); shadow->hide(); } //____________________________________________________________________________________ void FrameShadowFactory::widgetDestroyed( QObject* object ) { _registeredWidgets.remove( object ); } //____________________________________________________________________________________ FrameShadow::FrameShadow( Side area, Helper& helper ): _helper( helper ), _area( area ) { setAttribute(Qt::WA_OpaquePaintEvent, false); setFocusPolicy(Qt::NoFocus); setAttribute(Qt::WA_TransparentForMouseEvents, true); setContextMenuPolicy(Qt::NoContextMenu); // grab viewport widget QWidget *viewport( this->viewport() ); // set cursor from viewport if (viewport) setCursor(viewport->cursor()); } //____________________________________________________________________________________ void FrameShadow::updateGeometry( QRect rect ) { // show on first call if( isHidden() ) show(); // store offsets between passed rect and parent widget rect QRect parentRect( parentWidget()->contentsRect() ); _margins = QMargins( rect.left() - parentRect.left(), rect.top() - parentRect.top(), rect.right() - parentRect.right(), rect.bottom() - parentRect.bottom() ); // for efficiency, take out the part for which nothing is rendered rect.adjust( 1, 1, -1, -1 ); // adjust geometry const int shadowSize( Metrics::Frame_FrameRadius ); switch( _area ) { case SideTop: rect.setHeight( shadowSize ); break; case SideBottom: rect.setTop( rect.bottom() - shadowSize + 1 ); break; case SideLeft: rect.setWidth(shadowSize); rect.adjust(0, shadowSize, 0, -shadowSize ); break; case SideRight: rect.setLeft(rect.right() - shadowSize + 1 ); rect.adjust(0, shadowSize, 0, -shadowSize ); break; default: return; } setGeometry(rect); } //____________________________________________________________________________________ void FrameShadow::updateState( bool focus, bool hover, qreal opacity, AnimationMode mode ) { bool changed( false ); if( _hasFocus != focus ) { _hasFocus = focus; changed |= true; } if( _mouseOver != hover ) { _mouseOver = hover; changed |= !_hasFocus; } if( _mode != mode ) { _mode = mode; changed |= (_mode == AnimationNone) || (_mode == AnimationFocus) || (_mode == AnimationHover && !_hasFocus ); } if( _opacity != opacity ) { _opacity = opacity; changed |= (_mode != AnimationNone ); } if( changed ) { if( QWidget* viewport = this->viewport() ) { // need to disable viewport updates to avoid some redundant painting // besides it fixes one visual glitch (from Qt) in QTableViews viewport->setUpdatesEnabled( false ); update() ; viewport->setUpdatesEnabled( true ); } else update(); } } //____________________________________________________________________________________ void FrameShadow::paintEvent(QPaintEvent *event ) { // this fixes shadows in frames that change frameStyle() after polish() if( QFrame *frame = qobject_cast( parentWidget() ) ) { if (frame->frameStyle() != (QFrame::StyledPanel | QFrame::Sunken)) return; } const QRect parentRect( parentWidget()->contentsRect().translated( mapFromParent( QPoint( 0, 0 ) ) ) ); const QRect rect( parentRect.adjusted( _margins.left(), _margins.top(), _margins.right(), _margins.bottom() ) ); // render QPainter painter(this); painter.setClipRegion( event->region() ); painter.setRenderHint( QPainter::Antialiasing ); const QColor outline( _helper.frameOutlineColor( palette(), _mouseOver, _hasFocus, _opacity, _mode ) ); painter.setCompositionMode( QPainter::CompositionMode_SourceOver ); _helper.renderFrame( &painter, rect, QColor(), outline ); } //____________________________________________________________________________________ QWidget* FrameShadow::viewport() const { if( !parentWidget() ) return nullptr; else if( QAbstractScrollArea *widget = qobject_cast(parentWidget()) ) { return widget->viewport(); } else return nullptr; } } diff --git a/kstyle/breezemdiwindowshadow.cpp b/kstyle/breezemdiwindowshadow.cpp index 6ef53178..f78e9993 100644 --- a/kstyle/breezemdiwindowshadow.cpp +++ b/kstyle/breezemdiwindowshadow.cpp @@ -1,263 +1,263 @@ /************************************************************************* * Copyright (C) 2014 by Hugo Pereira Da Costa * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program 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 General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * *************************************************************************/ #include "breezemdiwindowshadow.h" #include "breeze.h" #include "breezeboxshadowrenderer.h" #include "breezeshadowhelper.h" #include "breezestyleconfigdata.h" #include #include #include #include namespace Breeze { //____________________________________________________________________ MdiWindowShadow::MdiWindowShadow( QWidget* parent, const TileSet &shadowTiles ): QWidget( parent ), _shadowTiles( shadowTiles ) { setAttribute( Qt::WA_OpaquePaintEvent, false ); setAttribute( Qt::WA_TransparentForMouseEvents, true ); setFocusPolicy( Qt::NoFocus ); } //____________________________________________________________________ void MdiWindowShadow::updateGeometry() { if( !_widget ) return; // metrics const CompositeShadowParams params = ShadowHelper::lookupShadowParams( StyleConfigData::shadowSize() ); if( params.isNone() ) return; const QSize boxSize = BoxShadowRenderer::calculateMinimumBoxSize(params.shadow1.radius) .expandedTo(BoxShadowRenderer::calculateMinimumBoxSize(params.shadow2.radius)); const QSize shadowSize = BoxShadowRenderer::calculateMinimumShadowTextureSize(boxSize, params.shadow1.radius, params.shadow1.offset) .expandedTo(BoxShadowRenderer::calculateMinimumShadowTextureSize(boxSize, params.shadow2.radius, params.shadow2.offset)); const QRect shadowRect(QPoint(0, 0), shadowSize); QRect boxRect(QPoint(0, 0), boxSize); boxRect.moveCenter(shadowRect.center()); const int topSize( boxRect.top() - shadowRect.top() - Metrics::Shadow_Overlap - params.offset.y() ); const int bottomSize( shadowRect.bottom() - boxRect.bottom() - Metrics::Shadow_Overlap + params.offset.y() ); const int leftSize( boxRect.left() - shadowRect.left() - Metrics::Shadow_Overlap - params.offset.x() ); const int rightSize( shadowRect.right() - boxRect.right() - Metrics::Shadow_Overlap + params.offset.x() ); // get tileSet rect auto hole = _widget->frameGeometry(); _shadowTilesRect = hole.adjusted( -leftSize, -topSize, rightSize, bottomSize ); // get parent MDI area's viewport auto parent( parentWidget() ); if (parent && !qobject_cast(parent) && qobject_cast(parent->parentWidget())) { parent = parent->parentWidget(); } if( qobject_cast( parent ) ) { parent = qobject_cast( parent )->viewport(); } // set geometry QRect geometry( _shadowTilesRect ); if( parent ) { geometry &= parent->rect(); hole &= parent->rect(); } // update geometry and mask const QRegion mask = QRegion( geometry ) - hole.adjusted( 2, 2, -2, -2 ); if( mask.isEmpty() ) hide(); else { setGeometry( geometry ); setMask( mask.translated( -geometry.topLeft() ) ); show(); } // translate rendering rect _shadowTilesRect.translate( -geometry.topLeft() ); } //____________________________________________________________________ void MdiWindowShadow::updateZOrder() { stackUnder( _widget ); } //____________________________________________________________________ void MdiWindowShadow::paintEvent( QPaintEvent* event ) { if( !_shadowTiles.isValid() ) return; QPainter painter( this ); painter.setRenderHints( QPainter::Antialiasing ); painter.setClipRegion( event->region() ); _shadowTiles.render( _shadowTilesRect, &painter ); } //____________________________________________________________________ MdiWindowShadowFactory::MdiWindowShadowFactory( QObject* parent ): QObject( parent ) {} //____________________________________________________________________________________ bool MdiWindowShadowFactory::registerWidget( QWidget* widget ) { // check widget type auto subwindow( qobject_cast( widget ) ); if( !subwindow ) return false; if( subwindow->widget() && subwindow->widget()->inherits( "KMainWindow" ) ) return false; // make sure widget is not already registered if( isRegistered( widget ) ) return false; // store in set _registeredWidgets.insert( widget ); // create shadow immediately if widget is already visible if( widget->isVisible() ) { installShadow( widget ); updateShadowGeometry( widget ); updateShadowZOrder( widget ); } widget->installEventFilter( this ); // catch object destruction - connect( widget, SIGNAL(destroyed(QObject*)), SLOT(widgetDestroyed(QObject*)) ); + connect( widget, &QObject::destroyed, this, &MdiWindowShadowFactory::widgetDestroyed ); return true; } //____________________________________________________________________________________ void MdiWindowShadowFactory::unregisterWidget( QWidget* widget ) { if( !isRegistered( widget ) ) return; widget->removeEventFilter( this ); _registeredWidgets.remove( widget ); removeShadow( widget ); } //____________________________________________________________________________________ bool MdiWindowShadowFactory::eventFilter( QObject* object, QEvent* event ) { switch( event->type() ) { // TODO: possibly implement ZOrderChange event, to make sure that // the shadow is always painted on top case QEvent::ZOrderChange: updateShadowZOrder( object ); break; case QEvent::Destroy: if( isRegistered( object ) ) { _registeredWidgets.remove( object ); removeShadow( object ); } break; case QEvent::Hide: hideShadows( object ); break; case QEvent::Show: installShadow( object ); updateShadowGeometry( object ); updateShadowZOrder( object ); break; case QEvent::Move: case QEvent::Resize: updateShadowGeometry( object ); break; default: break; } return QObject::eventFilter( object, event ); } //____________________________________________________________________________________ MdiWindowShadow* MdiWindowShadowFactory::findShadow( QObject* object ) const { // check object, if( !object->parent() ) return nullptr; // find existing window shadows auto children = object->parent()->children(); foreach( QObject *child, children ) { if( MdiWindowShadow* shadow = qobject_cast(child) ) { if( shadow->widget() == object ) return shadow; } } return nullptr; } //____________________________________________________________________________________ void MdiWindowShadowFactory::installShadow( QObject* object ) { // cast auto widget( static_cast( object ) ); if( !widget->parentWidget() ) return; // make sure shadow is not already installed if( findShadow( object ) ) return; if ( !_shadowHelper ) return; // create new shadow auto windowShadow( new MdiWindowShadow( widget->parentWidget(), _shadowHelper->shadowTiles() ) ); windowShadow->setWidget( widget ); } //____________________________________________________________________________________ void MdiWindowShadowFactory::removeShadow( QObject* object ) { if( MdiWindowShadow* windowShadow = findShadow( object ) ) { windowShadow->hide(); windowShadow->deleteLater(); } } //____________________________________________________________________________________ void MdiWindowShadowFactory::widgetDestroyed( QObject* object ) { _registeredWidgets.remove( object ); } } diff --git a/kstyle/breezeshadowhelper.cpp b/kstyle/breezeshadowhelper.cpp index 02181e7a..e5bb1755 100644 --- a/kstyle/breezeshadowhelper.cpp +++ b/kstyle/breezeshadowhelper.cpp @@ -1,451 +1,451 @@ /************************************************************************* * Copyright (C) 2014 by Hugo Pereira Da Costa * * Copyright (C) 2018, 2020 by Vlad Zahorodnii * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program 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 General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * *************************************************************************/ #include "breezeshadowhelper.h" #include "breeze.h" #include "breezeboxshadowrenderer.h" #include "breezehelper.h" #include "breezepropertynames.h" #include "breezestyleconfigdata.h" #include #include #include #include #include #include #include #include #include namespace { using Breeze::CompositeShadowParams; using Breeze::ShadowParams; const CompositeShadowParams s_shadowParams[] = { // None CompositeShadowParams(), // Small CompositeShadowParams( QPoint(0, 3), ShadowParams(QPoint(0, 0), 12, 0.26), ShadowParams(QPoint(0, -2), 6, 0.16)), // Medium CompositeShadowParams( QPoint(0, 4), ShadowParams(QPoint(0, 0), 16, 0.24), ShadowParams(QPoint(0, -2), 8, 0.14)), // Large CompositeShadowParams( QPoint(0, 5), ShadowParams(QPoint(0, 0), 20, 0.22), ShadowParams(QPoint(0, -3), 10, 0.12)), // Very Large CompositeShadowParams( QPoint(0, 6), ShadowParams(QPoint(0, 0), 24, 0.2), ShadowParams(QPoint(0, -3), 12, 0.1)) }; } namespace Breeze { //_____________________________________________________ CompositeShadowParams ShadowHelper::lookupShadowParams(int shadowSizeEnum) { switch (shadowSizeEnum) { case StyleConfigData::ShadowNone: return s_shadowParams[0]; case StyleConfigData::ShadowSmall: return s_shadowParams[1]; case StyleConfigData::ShadowMedium: return s_shadowParams[2]; case StyleConfigData::ShadowLarge: return s_shadowParams[3]; case StyleConfigData::ShadowVeryLarge: return s_shadowParams[4]; default: // Fallback to the Large size. return s_shadowParams[3]; } } //_____________________________________________________ ShadowHelper::ShadowHelper( QObject* parent, Helper& helper ): QObject( parent ), _helper( helper ) { } //_______________________________________________________ ShadowHelper::~ShadowHelper() { qDeleteAll( _shadows ); } //______________________________________________ void ShadowHelper::reset() { _tiles.clear(); _shadowTiles = TileSet(); } //_______________________________________________________ bool ShadowHelper::registerWidget( QWidget* widget, bool force ) { // make sure widget is not already registered if( _widgets.contains( widget ) ) return false; // check if widget qualifies if( !( force || acceptWidget( widget ) ) ) { return false; } // try create shadow directly installShadows( widget ); _widgets.insert( widget ); // install event filter widget->removeEventFilter( this ); widget->installEventFilter( this ); // connect destroy signal - connect( widget, SIGNAL(destroyed(QObject*)), SLOT(objectDeleted(QObject*)) ); + connect( widget, &QObject::destroyed, this, &ShadowHelper::objectDeleted ); return true; } //_______________________________________________________ void ShadowHelper::unregisterWidget( QWidget* widget ) { if( _widgets.remove( widget ) ) { uninstallShadows( widget ); } } //_______________________________________________________ void ShadowHelper::loadConfig() { // reset reset(); // update property for registered widgets for( QWidget* widget : _widgets) { installShadows( widget ); } } //_______________________________________________________ bool ShadowHelper::eventFilter( QObject* object, QEvent* event ) { if( Helper::isX11() ) { // check event type if( event->type() != QEvent::WinIdChange ) return false; // cast widget QWidget* widget( static_cast( object ) ); // install shadows and update winId installShadows( widget ); } else { if( event->type() != QEvent::PlatformSurface ) return false; QWidget* widget( static_cast( object ) ); QPlatformSurfaceEvent* surfaceEvent( static_cast( event ) ); switch( surfaceEvent->surfaceEventType() ) { case QPlatformSurfaceEvent::SurfaceCreated: installShadows( widget ); break; case QPlatformSurfaceEvent::SurfaceAboutToBeDestroyed: // Don't care. break; } } return false; } //_______________________________________________________ TileSet ShadowHelper::shadowTiles() { const CompositeShadowParams params = lookupShadowParams(StyleConfigData::shadowSize()); if (params.isNone()) { return TileSet(); } else if (_shadowTiles.isValid()) { return _shadowTiles; } auto withOpacity = [](const QColor &color, qreal opacity) -> QColor { QColor c(color); c.setAlphaF(opacity); return c; }; const QColor color = StyleConfigData::shadowColor(); const qreal strength = static_cast(StyleConfigData::shadowStrength()) / 255.0; const QSize boxSize = BoxShadowRenderer::calculateMinimumBoxSize(params.shadow1.radius) .expandedTo(BoxShadowRenderer::calculateMinimumBoxSize(params.shadow2.radius)); const qreal dpr = qApp->devicePixelRatio(); const qreal frameRadius = _helper.frameRadius(); BoxShadowRenderer shadowRenderer; shadowRenderer.setBorderRadius(frameRadius); shadowRenderer.setBoxSize(boxSize); shadowRenderer.setDevicePixelRatio(dpr); shadowRenderer.addShadow(params.shadow1.offset, params.shadow1.radius, withOpacity(color, params.shadow1.opacity * strength)); shadowRenderer.addShadow(params.shadow2.offset, params.shadow2.radius, withOpacity(color, params.shadow2.opacity * strength)); QImage shadowTexture = shadowRenderer.render(); const QRect outerRect(QPoint(0, 0), shadowTexture.size() / dpr); QRect boxRect(QPoint(0, 0), boxSize); boxRect.moveCenter(outerRect.center()); // Mask out inner rect. QPainter painter(&shadowTexture); painter.setRenderHint(QPainter::Antialiasing); const QMargins margins = QMargins( boxRect.left() - outerRect.left() - Metrics::Shadow_Overlap - params.offset.x(), boxRect.top() - outerRect.top() - Metrics::Shadow_Overlap - params.offset.y(), outerRect.right() - boxRect.right() - Metrics::Shadow_Overlap + params.offset.x(), outerRect.bottom() - boxRect.bottom() - Metrics::Shadow_Overlap + params.offset.y()); painter.setPen(Qt::NoPen); painter.setBrush(Qt::black); painter.setCompositionMode(QPainter::CompositionMode_DestinationOut); painter.drawRoundedRect( outerRect - margins, frameRadius, frameRadius); // We're done. painter.end(); const QPoint innerRectTopLeft = outerRect.center(); _shadowTiles = TileSet( QPixmap::fromImage(shadowTexture), innerRectTopLeft.x(), innerRectTopLeft.y(), 1, 1); return _shadowTiles; } //_______________________________________________________ void ShadowHelper::objectDeleted( QObject* object ) { QWidget* widget( static_cast( object ) ); _widgets.remove( widget ); _shadows.remove( widget ); } //_______________________________________________________ bool ShadowHelper::isMenu( QWidget* widget ) const { return qobject_cast( widget ); } //_______________________________________________________ bool ShadowHelper::isToolTip( QWidget* widget ) const { return widget->inherits( "QTipLabel" ) || (widget->windowFlags() & Qt::WindowType_Mask) == Qt::ToolTip; } //_______________________________________________________ bool ShadowHelper::isDockWidget( QWidget* widget ) const { return qobject_cast( widget ); } //_______________________________________________________ bool ShadowHelper::isToolBar( QWidget* widget ) const { return qobject_cast( widget ); } //_______________________________________________________ bool ShadowHelper::acceptWidget( QWidget* widget ) const { // flags if( widget->property( PropertyNames::netWMSkipShadow ).toBool() ) return false; if( widget->property( PropertyNames::netWMForceShadow ).toBool() ) return true; // menus if( isMenu( widget ) ) return true; // combobox dropdown lists if( widget->inherits( "QComboBoxPrivateContainer" ) ) return true; // tooltips if( isToolTip( widget ) && !widget->inherits( "Plasma::ToolTip" ) ) { return true; } // detached widgets if( isDockWidget( widget ) || isToolBar( widget ) ) { return true; } // reject return false; } //______________________________________________ const QVector& ShadowHelper::createShadowTiles() { // make sure size is valid if( _tiles.isEmpty() ) { _tiles = { createTile( _shadowTiles.pixmap( 1 ) ), createTile( _shadowTiles.pixmap( 2 ) ), createTile( _shadowTiles.pixmap( 5 ) ), createTile( _shadowTiles.pixmap( 8 ) ), createTile( _shadowTiles.pixmap( 7 ) ), createTile( _shadowTiles.pixmap( 6 ) ), createTile( _shadowTiles.pixmap( 3 ) ), createTile( _shadowTiles.pixmap( 0 ) ) }; } // return relevant list of shadow tiles return _tiles; } //______________________________________________ KWindowShadowTile::Ptr ShadowHelper::createTile( const QPixmap& source ) { KWindowShadowTile::Ptr tile = KWindowShadowTile::Ptr::create(); tile->setImage( source.toImage() ); return tile; } //_______________________________________________________ void ShadowHelper::installShadows( QWidget* widget ) { if( !widget ) return; // only toplevel widgets can cast drop-shadows if( !widget->isWindow() ) return; // widget must have valid native window if( !widget->testAttribute( Qt::WA_WState_Created ) ) return; // create shadow tiles if needed shadowTiles(); if( !_shadowTiles.isValid() ) return; // create platform shadow tiles if needed const QVector& tiles = createShadowTiles(); if( tiles.count() != numTiles ) return; // find a shadow associated with the widget KWindowShadow*& shadow = _shadows[ widget ]; // we want the shadow to be deleted after the decorated window is destroyed if( !shadow ) { shadow = new KWindowShadow( widget->windowHandle() ); } if( shadow->isCreated() ) { shadow->destroy(); } shadow->setTopTile( tiles[ 0 ] ); shadow->setTopRightTile( tiles[ 1 ] ); shadow->setRightTile( tiles[ 2 ] ); shadow->setBottomRightTile( tiles[ 3 ] ); shadow->setBottomTile( tiles[ 4 ] ); shadow->setBottomLeftTile( tiles[ 5 ] ); shadow->setLeftTile( tiles[ 6 ] ); shadow->setTopLeftTile( tiles[ 7 ] ); shadow->setPadding( shadowMargins( widget ) ); shadow->setWindow( widget->windowHandle() ); shadow->create(); } //_______________________________________________________ QMargins ShadowHelper::shadowMargins( QWidget* widget ) const { const CompositeShadowParams params = lookupShadowParams(StyleConfigData::shadowSize()); if (params.isNone()) { return QMargins(); } const QSize boxSize = BoxShadowRenderer::calculateMinimumBoxSize(params.shadow1.radius) .expandedTo(BoxShadowRenderer::calculateMinimumBoxSize(params.shadow2.radius)); const QSize shadowSize = BoxShadowRenderer::calculateMinimumShadowTextureSize(boxSize, params.shadow1.radius, params.shadow1.offset) .expandedTo(BoxShadowRenderer::calculateMinimumShadowTextureSize(boxSize, params.shadow2.radius, params.shadow2.offset)); const QRect shadowRect(QPoint(0, 0), shadowSize); QRect boxRect(QPoint(0, 0), boxSize); boxRect.moveCenter(shadowRect.center()); QMargins margins( boxRect.left() - shadowRect.left() - Metrics::Shadow_Overlap - params.offset.x(), boxRect.top() - shadowRect.top() - Metrics::Shadow_Overlap - params.offset.y(), shadowRect.right() - boxRect.right() - Metrics::Shadow_Overlap + params.offset.x(), shadowRect.bottom() - boxRect.bottom() - Metrics::Shadow_Overlap + params.offset.y()); if (widget->inherits("QBalloonTip")) { // Balloon tip needs special margins to deal with the arrow. int top = widget->contentsMargins().top(); int bottom = widget->contentsMargins().bottom(); // Need to decrement default size further due to extra hard coded round corner. margins -= 1; // Arrow can be either to the top or the bottom. Adjust margins accordingly. const int diff = qAbs(top - bottom); if (top > bottom) { margins.setTop(margins.top() - diff); } else { margins.setBottom(margins.bottom() - diff); } } margins *= _helper.devicePixelRatio(_shadowTiles.pixmap(0)); return margins; } //_______________________________________________________ void ShadowHelper::uninstallShadows( QWidget* widget ) { delete _shadows.take( widget ); } } diff --git a/kstyle/config/breezestyleconfig.cpp b/kstyle/config/breezestyleconfig.cpp index 3b0119e8..a573d0b5 100644 --- a/kstyle/config/breezestyleconfig.cpp +++ b/kstyle/config/breezestyleconfig.cpp @@ -1,162 +1,162 @@ /************************************************************************* * Copyright (C) 2014 by Hugo Pereira Da Costa * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program 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 General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * *************************************************************************/ #include "breezestyleconfig.h" #include "../breeze.h" #include "../config-breeze.h" #include "breezestyleconfigdata.h" #include #include extern "C" { Q_DECL_EXPORT QWidget* allocate_kstyle_config(QWidget* parent) { return new Breeze::StyleConfig(parent); } } namespace Breeze { //__________________________________________________________________ StyleConfig::StyleConfig(QWidget* parent): QWidget(parent) { setupUi(this); // load setup from configData load(); - connect( _tabBarDrawCenteredTabs, SIGNAL(toggled(bool)), SLOT(updateChanged()) ); - connect( _toolBarDrawItemSeparator, SIGNAL(toggled(bool)), SLOT(updateChanged()) ); - connect( _viewDrawFocusIndicator, SIGNAL(toggled(bool)), SLOT(updateChanged()) ); - connect( _dockWidgetDrawFrame, SIGNAL(toggled(bool)), SLOT(updateChanged()) ); - connect( _titleWidgetDrawFrame, SIGNAL(toggled(bool)), SLOT(updateChanged()) ); - connect( _sidePanelDrawFrame, SIGNAL(toggled(bool)), SLOT(updateChanged()) ); - connect( _menuItemDrawThinFocus, SIGNAL(toggled(bool)), SLOT(updateChanged()) ); - connect( _sliderDrawTickMarks, SIGNAL(toggled(bool)), SLOT(updateChanged()) ); - connect( _splitterProxyEnabled, SIGNAL(toggled(bool)), SLOT(updateChanged()) ); + connect( _tabBarDrawCenteredTabs, &QAbstractButton::toggled, this, &StyleConfig::updateChanged ); + connect( _toolBarDrawItemSeparator, &QAbstractButton::toggled, this, &StyleConfig::updateChanged ); + connect( _viewDrawFocusIndicator, &QAbstractButton::toggled, this, &StyleConfig::updateChanged ); + connect( _dockWidgetDrawFrame, &QAbstractButton::toggled, this, &StyleConfig::updateChanged ); + connect( _titleWidgetDrawFrame, &QAbstractButton::toggled, this, &StyleConfig::updateChanged ); + connect( _sidePanelDrawFrame, &QAbstractButton::toggled, this, &StyleConfig::updateChanged ); + connect( _menuItemDrawThinFocus, &QAbstractButton::toggled, this, &StyleConfig::updateChanged ); + connect( _sliderDrawTickMarks, &QAbstractButton::toggled, this, &StyleConfig::updateChanged ); + connect( _splitterProxyEnabled, &QAbstractButton::toggled, this, &StyleConfig::updateChanged ); connect( _mnemonicsMode, SIGNAL(currentIndexChanged(int)), SLOT(updateChanged()) ); - connect( _animationsEnabled, SIGNAL(toggled(bool)), SLOT(updateChanged()) ); + connect( _animationsEnabled, &QAbstractButton::toggled, this, &StyleConfig::updateChanged ); connect( _animationsDuration, SIGNAL(valueChanged(int)), SLOT(updateChanged()) ); connect( _scrollBarAddLineButtons, SIGNAL(currentIndexChanged(int)), SLOT(updateChanged()) ); connect( _scrollBarSubLineButtons, SIGNAL(currentIndexChanged(int)), SLOT(updateChanged()) ); connect( _windowDragMode, SIGNAL(currentIndexChanged(int)), SLOT(updateChanged()) ); - connect( _menuOpacity, SIGNAL(valueChanged(int)), SLOT(updateChanged()) ); + connect( _menuOpacity, &QAbstractSlider::valueChanged, this, &StyleConfig::updateChanged ); } //__________________________________________________________________ void StyleConfig::save() { StyleConfigData::setTabBarDrawCenteredTabs( _tabBarDrawCenteredTabs->isChecked() ); StyleConfigData::setToolBarDrawItemSeparator( _toolBarDrawItemSeparator->isChecked() ); StyleConfigData::setViewDrawFocusIndicator( _viewDrawFocusIndicator->isChecked() ); StyleConfigData::setDockWidgetDrawFrame( _dockWidgetDrawFrame->isChecked() ); StyleConfigData::setTitleWidgetDrawFrame( _titleWidgetDrawFrame->isChecked() ); StyleConfigData::setSidePanelDrawFrame( _sidePanelDrawFrame->isChecked() ); StyleConfigData::setMenuItemDrawStrongFocus( !_menuItemDrawThinFocus->isChecked() ); StyleConfigData::setSliderDrawTickMarks( _sliderDrawTickMarks->isChecked() ); StyleConfigData::setSplitterProxyEnabled( _splitterProxyEnabled->isChecked() ); StyleConfigData::setMnemonicsMode( _mnemonicsMode->currentIndex() ); StyleConfigData::setScrollBarAddLineButtons( _scrollBarAddLineButtons->currentIndex() ); StyleConfigData::setScrollBarSubLineButtons( _scrollBarSubLineButtons->currentIndex() ); StyleConfigData::setAnimationsEnabled( _animationsEnabled->isChecked() ); StyleConfigData::setAnimationsDuration( _animationsDuration->value() ); StyleConfigData::setWindowDragMode( _windowDragMode->currentIndex() ); StyleConfigData::setMenuOpacity( _menuOpacity->value() ); StyleConfigData::self()->save(); // emit dbus signal QDBusMessage message( QDBusMessage::createSignal( QStringLiteral( "/BreezeStyle" ), QStringLiteral( "org.kde.Breeze.Style" ), QStringLiteral( "reparseConfiguration" ) ) ); QDBusConnection::sessionBus().send(message); } //__________________________________________________________________ void StyleConfig::defaults() { StyleConfigData::self()->setDefaults(); load(); } //__________________________________________________________________ void StyleConfig::reset() { // reparse configuration StyleConfigData::self()->load(); load(); } //__________________________________________________________________ void StyleConfig::updateChanged() { bool modified( false ); // check if any value was modified if( _tabBarDrawCenteredTabs->isChecked() != StyleConfigData::tabBarDrawCenteredTabs() ) modified = true; else if( _toolBarDrawItemSeparator->isChecked() != StyleConfigData::toolBarDrawItemSeparator() ) modified = true; else if( _viewDrawFocusIndicator->isChecked() != StyleConfigData::viewDrawFocusIndicator() ) modified = true; else if( _dockWidgetDrawFrame->isChecked() != StyleConfigData::dockWidgetDrawFrame() ) modified = true; else if( _titleWidgetDrawFrame->isChecked() != StyleConfigData::titleWidgetDrawFrame() ) modified = true; else if( _sidePanelDrawFrame->isChecked() != StyleConfigData::sidePanelDrawFrame() ) modified = true; else if( _menuItemDrawThinFocus->isChecked() == StyleConfigData::menuItemDrawStrongFocus() ) modified = true; else if( _sliderDrawTickMarks->isChecked() != StyleConfigData::sliderDrawTickMarks() ) modified = true; else if( _mnemonicsMode->currentIndex() != StyleConfigData::mnemonicsMode() ) modified = true; 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( _animationsEnabled->isChecked() != StyleConfigData::animationsEnabled() ) modified = true; else if( _animationsDuration->value() != StyleConfigData::animationsDuration() ) modified = true; else if( _windowDragMode->currentIndex() != StyleConfigData::windowDragMode() ) modified = true; else if( _menuOpacity->value() != StyleConfigData::menuOpacity() ) modified = true; emit changed(modified); } //__________________________________________________________________ void StyleConfig::load() { _tabBarDrawCenteredTabs->setChecked( StyleConfigData::tabBarDrawCenteredTabs() ); _toolBarDrawItemSeparator->setChecked( StyleConfigData::toolBarDrawItemSeparator() ); _viewDrawFocusIndicator->setChecked( StyleConfigData::viewDrawFocusIndicator() ); _dockWidgetDrawFrame->setChecked( StyleConfigData::dockWidgetDrawFrame() ); _titleWidgetDrawFrame->setChecked( StyleConfigData::titleWidgetDrawFrame() ); _sidePanelDrawFrame->setChecked( StyleConfigData::sidePanelDrawFrame() ); _menuItemDrawThinFocus->setChecked( !StyleConfigData::menuItemDrawStrongFocus() ); _sliderDrawTickMarks->setChecked( StyleConfigData::sliderDrawTickMarks() ); _mnemonicsMode->setCurrentIndex( StyleConfigData::mnemonicsMode() ); _splitterProxyEnabled->setChecked( StyleConfigData::splitterProxyEnabled() ); _scrollBarAddLineButtons->setCurrentIndex( StyleConfigData::scrollBarAddLineButtons() ); _scrollBarSubLineButtons->setCurrentIndex( StyleConfigData::scrollBarSubLineButtons() ); _animationsEnabled->setChecked( StyleConfigData::animationsEnabled() ); _animationsDuration->setValue( StyleConfigData::animationsDuration() ); _windowDragMode->setCurrentIndex( StyleConfigData::windowDragMode() ); _menuOpacity->setValue( StyleConfigData::menuOpacity() ); } }