diff --git a/kstyle/animations/breezeanimations.cpp b/kstyle/animations/breezeanimations.cpp index eb49d3ba..0f942254 100644 --- a/kstyle/animations/breezeanimations.cpp +++ b/kstyle/animations/breezeanimations.cpp @@ -1,235 +1,235 @@ /************************************************************************* * 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 ) ); - registerEngine( _multiStateEngine = new CheckBoxEngine( this ) ); + registerEngine( _checkBoxEngine = new CheckBoxEngine( 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 propery 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 ); - _multiStateEngine->registerWidget( widget ); + _checkBoxEngine->registerWidget( widget ); } 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 ); - _multiStateEngine->registerWidget( widget ); + _checkBoxEngine->registerWidget( widget ); } } // 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*)) ); } } diff --git a/kstyle/animations/breezeanimations.h b/kstyle/animations/breezeanimations.h index f7c0b7b8..f2e0c772 100644 --- a/kstyle/animations/breezeanimations.h +++ b/kstyle/animations/breezeanimations.h @@ -1,170 +1,170 @@ #ifndef breezeanimations_h #define breezeanimations_h /************************************************************************* * 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 "breezebusyindicatorengine.h" #include "breezedialengine.h" #include "breezeheaderviewengine.h" #include "breezescrollbarengine.h" #include "breezespinboxengine.h" #include "breezestackedwidgetengine.h" #include "breezetabbarengine.h" #include "breezetoolboxengine.h" #include "breezewidgetstateengine.h" #include "breezecheckboxengine.h" #include #include namespace Breeze { //* stores engines class Animations: public QObject { Q_OBJECT public: //* constructor explicit Animations( QObject* ); //* register animations corresponding to given widget, depending on its type. void registerWidget( QWidget* widget ) const; /** unregister all animations associated to a widget */ void unregisterWidget( QWidget* widget ) const; //* enability engine WidgetStateEngine& widgetEnabilityEngine() const { return *_widgetEnabilityEngine; } //* abstractButton engine WidgetStateEngine& widgetStateEngine() const { return *_widgetStateEngine; } //* editable combobox arrow hover engine WidgetStateEngine& comboBoxEngine() const { return *_comboBoxEngine; } //* Tool buttons arrow hover engine WidgetStateEngine& toolButtonEngine() const { return *_toolButtonEngine; } //* item view engine WidgetStateEngine& inputWidgetEngine() const { return *_inputWidgetEngine; } //* busy indicator BusyIndicatorEngine& busyIndicatorEngine() const { return *_busyIndicatorEngine; } //* header view engine HeaderViewEngine& headerViewEngine() const { return *_headerViewEngine; } //* scrollbar engine ScrollBarEngine& scrollBarEngine() const { return *_scrollBarEngine; } //* dial engine DialEngine& dialEngine() const { return *_dialEngine; } //* spinbox engine SpinBoxEngine& spinBoxEngine() const { return *_spinBoxEngine; } //* tabbar TabBarEngine& tabBarEngine() const { return *_tabBarEngine; } //* toolbox ToolBoxEngine& toolBoxEngine() const { return *_toolBoxEngine; } //* multi state engine - CheckBoxEngine& multiStateEngine() const - { return *_multiStateEngine; } + CheckBoxEngine& checkBoxEngine() const + { return *_checkBoxEngine; } //* setup engines void setupEngines(); protected Q_SLOTS: //* enregister engine void unregisterEngine( QObject* ); private: //* register new engine void registerEngine( BaseEngine* ); //* busy indicator BusyIndicatorEngine* _busyIndicatorEngine = nullptr; //* headerview hover effect HeaderViewEngine* _headerViewEngine = nullptr; //* widget enability engine WidgetStateEngine* _widgetEnabilityEngine = nullptr; //* abstract button engine WidgetStateEngine* _widgetStateEngine = nullptr; //* editable combobox arrow hover effect WidgetStateEngine* _comboBoxEngine = nullptr; //* mennu toolbutton arrow hover effect WidgetStateEngine* _toolButtonEngine = nullptr; //* item view engine WidgetStateEngine* _inputWidgetEngine = nullptr; //* scrollbar engine ScrollBarEngine* _scrollBarEngine = nullptr; //* dial engine DialEngine* _dialEngine = nullptr; //* spinbox engine SpinBoxEngine* _spinBoxEngine = nullptr; //* stacked widget engine StackedWidgetEngine* _stackedWidgetEngine = nullptr; //* tabbar engine TabBarEngine* _tabBarEngine = nullptr; //* toolbar engine ToolBoxEngine* _toolBoxEngine = nullptr; //* multi state engine - CheckBoxEngine *_multiStateEngine = nullptr; + CheckBoxEngine *_checkBoxEngine = nullptr; //* keep list of existing engines QList< BaseEngine::Pointer > _engines; }; } #endif diff --git a/kstyle/checkbox.cpp b/kstyle/checkbox.cpp index da8879d1..5c3d09ef 100644 --- a/kstyle/checkbox.cpp +++ b/kstyle/checkbox.cpp @@ -1,190 +1,190 @@ #include "breezestyle.h" #include "breeze.h" #include "breezeanimations.h" #include "breezecheckboxdata.h" #include #include #include #include #include #include #include #include #include namespace Breeze { static void renderCheckMark(QPainter *painter, const QPoint &position, const QColor &color, const CheckBoxRenderState &s) { painter->setBrush(Qt::NoBrush); painter->setPen(QPen(color, 2, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin)); QPainterPath pp; const QPointF linePointPosition[] = {s.linePointPosition0, s.linePointPosition1, s.linePointPosition2}; const QPointF pointPosition[] = {s.pointPosition0, s.pointPosition1, s.pointPosition2}; const qreal pointRadius[] = {s.pointRadius0, s.pointRadius1, s.pointRadius2}; int i = 0; for(; i < 3; ++i) { if(!isInvalidPointF(linePointPosition[i])) { pp.moveTo(linePointPosition[i]); break; } } for(; i < 3; ++i) { if(!isInvalidPointF(linePointPosition[i])) { pp.lineTo(linePointPosition[i]); } } pp.translate(s.position + position); painter->drawPath(pp); painter->setPen(Qt::NoPen); for (int i = 0; i < 3; ++i) { if (isInvalidPointF(pointPosition[i]) || qFuzzyIsNull(pointRadius[i])) { continue; } painter->setBrush(color); painter->drawEllipse(pointPosition[i] + position, pointRadius[i], pointRadius[i]); } } //___________________________________________________________________________________ void Style::drawChoicePrimitive(const QStyleOption *option, QPainter *painter, const QWidget* widget, bool isRadioButton) const { // copy rect and palette const auto& rect( option->rect ); const auto& palette( option->palette ); // copy state const State& state( option->state ); const bool enabled( state & State_Enabled ); // State_Selected can be active in list and menu items const bool mouseOver( enabled && ( state & (State_MouseOver | State_Selected) ) ); const bool hasFocus( enabled && ( state & (State_HasFocus | State_Selected) ) ); const bool isChecked( state & State_On ); // focus takes precedence over mouse over _animations->widgetStateEngine().updateState( widget, AnimationFocus, hasFocus ); _animations->widgetStateEngine().updateState( widget, AnimationHover, mouseOver ); _animations->widgetStateEngine().updateState( widget, AnimationPressed, isChecked ); // Render background and frame // Foreground and background color const auto &normalBackground = palette.color(QPalette::Base); const auto &normalForeground = palette.color(QPalette::Text); const auto &checkedBackground = palette.color(QPalette::Highlight); const auto &checkedForeground = palette.color(QPalette::HighlightedText); const qreal stateOpacityOrInvalid = _animations->widgetStateEngine().opacity( widget, AnimationPressed ); const qreal stateOpacity = stateOpacityOrInvalid != AnimationData::OpacityInvalid ? stateOpacityOrInvalid : 1.0 * int(isChecked); const auto background = KColorUtils::mix(normalBackground, checkedBackground, stateOpacity); const auto foreground = KColorUtils::mix(normalForeground, checkedForeground, stateOpacity); // Frame color - hover priority const AnimationMode mode( _animations->widgetStateEngine().frameAnimationMode( widget ) ); const qreal opacity( _animations->widgetStateEngine().frameOpacity( widget ) ); QColor outline = _helper->frameOutlineColor(palette, mouseOver, hasFocus, opacity, mode, background); _helper->renderFrame( painter, rect.adjusted(0, 0, -0, -0), background, outline , isRadioButton); // Render mark static const auto inQuadEasingCurve = [](qreal v) { return v*v; }; static const auto outQuadEasingCurve = [](qreal v) { return 1.0-inQuadEasingCurve(1.0-v); }; painter->setRenderHint( QPainter::Antialiasing, true ); if(isRadioButton) { RadioButtonState radioButtonState = state & State_On ? RadioOn : RadioOff; if( _animations->widgetStateEngine().isAnimated( widget, AnimationPressed ) ) { radioButtonState = radioButtonState == RadioOn ? RadioOffToOn : RadioOnToOff; } if(radioButtonState == RadioOff) { return; } const QPointF center = {rect.x() + rect.width() / 2.0, rect.y() + rect.height() / 2.0}; const qreal fullRadius = 4.0; if(radioButtonState == RadioOn) { painter->setBrush( foreground ); painter->setPen( Qt::NoPen ); painter->drawEllipse(center, fullRadius, fullRadius); } else { const qreal radius = outQuadEasingCurve(stateOpacity) * fullRadius; painter->setBrush(foreground); painter->setPen( Qt::NoPen ); painter->drawEllipse(center, radius, radius); } } else { const CheckBoxState checkBoxState = state & State_NoChange ? CheckPartial : state & State_On ? CheckOn : CheckOff; - bool startAnim = (checkBoxState != _animations->multiStateEngine().state(widget)); - _animations->multiStateEngine().updateState(widget, checkBoxState); + bool startAnim = (checkBoxState != _animations->checkBoxEngine().state(widget)); + _animations->checkBoxEngine().updateState(widget, checkBoxState); - const CheckBoxState previousCheckBoxState = _animations->multiStateEngine().previousState(widget); + const CheckBoxState previousCheckBoxState = _animations->checkBoxEngine().previousState(widget); - qreal progress = _animations->multiStateEngine().progress(widget); - if(!_animations->multiStateEngine().isAnimated(widget)) { + qreal progress = _animations->checkBoxEngine().progress(widget); + if(!_animations->checkBoxEngine().isAnimated(widget)) { progress = 1.0; } const QPoint centerOffset = {rect.width()/2 + rect.x(), rect.height()/2 + rect.y()}; - DataMap::Value dataPtr = _animations->multiStateEngine().data(widget); + DataMap::Value dataPtr = _animations->checkBoxEngine().data(widget); static const auto stateToData = [](CheckBoxState state) -> const CheckBoxRenderState * { switch(state) { case CheckUnknown: case CheckOff: return &CheckBoxData::offState; case CheckOn: return &CheckBoxData::onState; case CheckPartial: return &CheckBoxData::partialState; }; return nullptr; }; const CheckBoxRenderState *state = nullptr; if (dataPtr.isNull()) { state = stateToData(checkBoxState); Q_CHECK_PTR(state); } else { CheckBoxData *data = dataPtr.data(); state = &data->renderState; if(previousCheckBoxState == CheckBoxState::CheckUnknown) { // First rendering. Don't animate, it is initial state. data->renderState = *q_check_ptr(stateToData(checkBoxState)); } else { if (startAnim) { data->timeline->stop(); if (previousCheckBoxState == CheckOff && checkBoxState == CheckOn) { data->timeline->setTransitions(&CheckBoxData::offToOnTransition); } if (previousCheckBoxState == CheckOn && checkBoxState == CheckOff) { data->timeline->setTransitions(&CheckBoxData::onToOffTransition); } if (previousCheckBoxState == CheckOff && checkBoxState == CheckPartial) { data->timeline->setTransitions(&CheckBoxData::offToPartialTransition); } if (previousCheckBoxState == CheckPartial && checkBoxState == CheckOff) { data->timeline->setTransitions(&CheckBoxData::partialToOffTransition); } if (previousCheckBoxState == CheckPartial && checkBoxState == CheckOn) { data->timeline->setTransitions(&CheckBoxData::partialToOnTransition); } if (previousCheckBoxState == CheckOn && checkBoxState == CheckPartial) { data->timeline->setTransitions(&CheckBoxData::onToPartialTransition); } data->timeline->start(); } } } renderCheckMark(painter, centerOffset, foreground, *state); } } }