From fa386ccc85e0df92fb99076727fe1ab432b8c11f Mon Sep 17 00:00:00 2001 From: Tsu Jan Date: Fri, 3 Feb 2023 02:47:37 +0330 Subject: [PATCH] Also animate busy progressbars without `QWidget`. --- Kvantum/ChangeLog | 1 + Kvantum/NEWS | 2 +- Kvantum/style/Kvantum.cpp | 74 +++++++++------------------ Kvantum/style/Kvantum.h | 11 +--- Kvantum/style/animation/animation.cpp | 23 ++++++++- Kvantum/style/animation/animation.h | 28 ++++++++-- Kvantum/style/eventFiltering.cpp | 44 +++------------- 7 files changed, 81 insertions(+), 102 deletions(-) diff --git a/Kvantum/ChangeLog b/Kvantum/ChangeLog index f95bf80e..2e0af35b 100644 --- a/Kvantum/ChangeLog +++ b/Kvantum/ChangeLog @@ -8,6 +8,7 @@ V1.0.8 * Limited the extra vertical margins of menu-item icons to 1px. * Smaller text-icon spacing for editable comboboxes that are drawn as lineedits. * Added vertical text margins of lineedits to their heights. + * Also animate busy progressbars without `QWidget`. V1.0.7 --------- diff --git a/Kvantum/NEWS b/Kvantum/NEWS index 45a934eb..87fee55a 100644 --- a/Kvantum/NEWS +++ b/Kvantum/NEWS @@ -1,5 +1,5 @@ Latest version: - 29 Jan 2023, V1.0.8 + 3 Feb 2023, V1.0.8 See "ChangeLog" for changes. diff --git a/Kvantum/style/Kvantum.cpp b/Kvantum/style/Kvantum.cpp index 88c5e597..da46b4e7 100644 --- a/Kvantum/style/Kvantum.cpp +++ b/Kvantum/style/Kvantum.cpp @@ -171,7 +171,6 @@ static inline QString getName(const QColor &col) Style::Style(bool useDark) : QCommonStyle() { - progressTimer_ = new QTimer(this); opacityTimer_ = opacityTimerOut_ = nullptr; animationOpacity_ = animationOpacityOut_ = 100; animationStartState_ = animationStartStateOut_ = "normal"; @@ -315,8 +314,6 @@ Style::Style(bool useDark) : QCommonStyle() ticklessSliderHandleSize_ = -1; isKisSlider_ = false; - connect(progressTimer_, &QTimer::timeout, this, &Style::advanceProgressbar); - if (tspec_.animate_states) { opacityTimer_ = new QTimer(this); @@ -428,12 +425,6 @@ Style::~Style() /* all the following timers have "this" as their parent but are explicitly deleted here only to be listed */ - if (progressTimer_) - { - progressTimer_->stop(); - delete progressTimer_; - progressTimer_ = nullptr; - } if (opacityTimer_) { opacityTimer_->stop(); @@ -831,37 +822,6 @@ void Style::setupThemeDeps() settings_ = defaultSettings_; } -void Style::advanceProgressbar() -{ - QMap::iterator it; - for (it = progressbars_.begin(); it != progressbars_.end(); ++it) - { - auto widget = it.key(); - if (widget && widget->isVisible()) - { - if (it.value() > INT_MAX - 2) - it.value() = 0; - else - it.value() += 2; - widget->update(); - } - } -} - -void Style::forgetProgressBar(QObject *o) -{ - if (auto w = qobject_cast(o)) - { - if (progressbars_.contains(w)) - { - disconnect(w, &QObject::destroyed, this, &Style::forgetProgressBar); - progressbars_.remove(w); - if (progressbars_.size() == 0) - progressTimer_->stop(); - } - } -} - void Style::forgetPopupOrigin(QObject *o) { if (auto w = qobject_cast(o)) @@ -8030,6 +7990,16 @@ void Style::drawControl(QStyle::ControlElement element, bool thin = false; if (opt->maximum != 0 || opt->minimum != 0) { + if (QObject *styleObject = option->styleObject) + { // could only have ProgressbarAnimation + if (Animation *animation = animations_.take(styleObject)) + { + animation->stop(); + delete animation; + animation = nullptr; + } + } + int length = isVertical ? h : w; int empty = length - sliderPositionFromValue(opt->minimum, @@ -8111,11 +8081,17 @@ void Style::drawControl(QStyle::ControlElement element, if (thin) painter->restore(); } - else if (widget) + else if (QObject *styleObject = option->styleObject) { // busy progressbar if (!r.isValid()) return; - QWidget *wi = const_cast(widget); - int animcount = progressbars_[wi]; + ProgressbarAnimation *anim = qobject_cast(animations_.value(styleObject)); + if (!anim) + { + anim = new ProgressbarAnimation(styleObject); + startAnimation(anim); + return; + } + int animPixels = anim->pixels(); int pm = qMin(qMax(pixelMetric(PM_ProgressBarChunkWidth),fspec.left+fspec.right),r.width()/2-2); if (pm > h && h >= fspec.left+fspec.right @@ -8123,20 +8099,20 @@ void Style::drawControl(QStyle::ControlElement element, { // make it compact with ordinary progressbars pm = h; } - QRect R = r.adjusted(animcount,0,0,0); + QRect R = r.adjusted(animPixels,0,0,0); if (isVertical) { if (inverted) - R.setX(r.x()+r.width()-(animcount % r.width())); + R.setX(r.x()+r.width()-(animPixels % r.width())); else - R.setX(r.x()+(animcount % r.width())); + R.setX(r.x()+(animPixels % r.width())); } else { if (inverted) - R.setX(r.x()+r.width()-(animcount % r.width())); + R.setX(r.x()+r.width()-(animPixels % r.width())); else - R.setX(r.x()+(animcount % r.width())); + R.setX(r.x()+(animPixels % r.width())); } int W = !isRounded ? pm : !isVertical ? qMax(h,pm) : qMax(w,pm); if (W <= 0 || W > r.width()) return; @@ -8220,8 +8196,6 @@ void Style::drawControl(QStyle::ControlElement element, renderInterior(painter,R,fspec,ispec,ispec.element+"-"+status,true); } } - else - QCommonStyle::drawControl(element,option,painter,widget); } break; diff --git a/Kvantum/style/Kvantum.h b/Kvantum/style/Kvantum.h index 04d9f886..260e5a5f 100644 --- a/Kvantum/style/Kvantum.h +++ b/Kvantum/style/Kvantum.h @@ -1,5 +1,5 @@ /* - * Copyright (C) Pedram Pourang (aka Tsu Jan) 2014-2019 + * Copyright (C) Pedram Pourang (aka Tsu Jan) 2014-2023 * * Kvantum is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the @@ -432,10 +432,6 @@ class Style : public QCommonStyle { } private slots: - /* For busy progress bars. */ - void advanceProgressbar(); - void forgetProgressBar(QObject *o); - void forgetPopupOrigin(QObject *o); void forgetMovedMenu(QObject *o); @@ -457,7 +453,7 @@ class Style : public QCommonStyle { QString xdg_config_home; - QTimer *progressTimer_, *opacityTimer_, *opacityTimerOut_; + QTimer *opacityTimer_, *opacityTimerOut_; mutable int animationOpacity_, animationOpacityOut_; // A value >= 100 stops state change animation. /* The start state for state change animation */ mutable QString animationStartState_, animationStartStateOut_; @@ -465,9 +461,6 @@ class Style : public QCommonStyle { QPointer animatedWidget_, animatedWidgetOut_; QHash> popupOrigins_; - /* List of busy progress bars */ - QMap progressbars_; - /* List of menus that are moved because of their shadows. */ QSet movedMenus_; diff --git a/Kvantum/style/animation/animation.cpp b/Kvantum/style/animation/animation.cpp index eee458d2..c56eed04 100644 --- a/Kvantum/style/animation/animation.cpp +++ b/Kvantum/style/animation/animation.cpp @@ -1,7 +1,7 @@ // Adapted from Qt /* - * Copyright (C) Pedram Pourang (aka Tsu Jan) 2016-2021 + * Copyright (C) Pedram Pourang (aka Tsu Jan) 2016-2023 * * Kvantum is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the @@ -118,6 +118,27 @@ void Animation::updateCurrentTime(int) /*************************/ +ProgressbarAnimation::ProgressbarAnimation(QObject *target) : Animation(target), + pixels_(0) +{ + setFrameRate(TwentyFps); +} + +int ProgressbarAnimation::pixels() const { + return pixels_; +} + +void ProgressbarAnimation::updateTarget() +{ + if (pixels_ > INT_MAX - 2) + pixels_ = 0; + else + pixels_ += 2; + Animation::updateTarget(); +} + +/*************************/ + NumberAnimation::NumberAnimation(QObject *target) : Animation(target), start_(0.0), diff --git a/Kvantum/style/animation/animation.h b/Kvantum/style/animation/animation.h index 1dcbcd67..38bee903 100644 --- a/Kvantum/style/animation/animation.h +++ b/Kvantum/style/animation/animation.h @@ -1,7 +1,7 @@ // Adapted from Qt /* - * Copyright (C) Pedram Pourang (aka Tsu Jan) 2016-2021 + * Copyright (C) Pedram Pourang (aka Tsu Jan) 2016-2023 * * Kvantum is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the @@ -49,13 +49,14 @@ class Animation : public QAbstractAnimation enum FrameRate { DefaultFps, SixtyFps, - ThirtyFps + ThirtyFps, + TwentyFps }; FrameRate frameRate() const; void setFrameRate(FrameRate fps); - void updateTarget(); + virtual void updateTarget(); public Q_SLOTS: void start(); @@ -72,6 +73,25 @@ public Q_SLOTS: int skip_; }; +/*************************/ + +class ProgressbarAnimation : public Animation +{ + Q_OBJECT + +public: + ProgressbarAnimation(QObject *target); + + void updateTarget() override; + + int pixels() const; + +private: + int pixels_; +}; + +/*************************/ + class NumberAnimation : public Animation { Q_OBJECT @@ -96,6 +116,8 @@ class NumberAnimation : public Animation mutable qreal prev_; }; +/*************************/ + class ScrollbarAnimation : public NumberAnimation { Q_OBJECT diff --git a/Kvantum/style/eventFiltering.cpp b/Kvantum/style/eventFiltering.cpp index 838484ae..624d6181 100644 --- a/Kvantum/style/eventFiltering.cpp +++ b/Kvantum/style/eventFiltering.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) Pedram Pourang (aka Tsu Jan) 2014-2022 + * Copyright (C) Pedram Pourang (aka Tsu Jan) 2014-2023 * * Kvantum is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the @@ -220,22 +220,8 @@ bool Style::eventFilter(QObject *o, QEvent *e) { if (w->inherits("KisAbstractSliderSpinBox") || w->inherits("Digikam::DAbstractSliderSpinBox")) isKisSlider_ = true; - else if (QProgressBar *pb = qobject_cast(o)) - { - if (pb->maximum() == 0 && pb->minimum() == 0) - { // add the busy progress bar to the list - if (!progressbars_.contains(w)) - { - progressbars_.insert(w, 0); - connect(w, &QObject::destroyed, this, &Style::forgetProgressBar); - if (!progressTimer_->isActive()) - progressTimer_->start(50); - } - } - else - forgetProgressBar(o); + else if (qobject_cast(o)) isKisSlider_ = false; - } else if (w->isWindow() && w->testAttribute(Qt::WA_StyledBackground) && w->testAttribute(Qt::WA_TranslucentBackground) @@ -960,20 +946,7 @@ bool Style::eventFilter(QObject *o, QEvent *e) connect(w, &QObject::destroyed, this, &Style::forgetPopupOrigin); } - if (QProgressBar *pb = qobject_cast(o)) - { - if (pb->maximum() == 0 && pb->minimum() == 0) - { - if (!progressbars_.contains(w)) - { - progressbars_.insert(w, 0); - connect(w, &QObject::destroyed, this, &Style::forgetProgressBar); - } - if (!progressTimer_->isActive()) - progressTimer_->start(50); - } - } - else if (QMenu *menu = qobject_cast(o)) + if (QMenu *menu = qobject_cast(o)) { //if (isLibreoffice_) break; if (w->testAttribute(Qt::WA_X11NetWmWindowTypeMenu)) break; // detached menu @@ -1497,14 +1470,9 @@ bool Style::eventFilter(QObject *o, QEvent *e) /* remove the widget from some lists when it becomes hidden */ if (qobject_cast(w)) forgetMovedMenu(o); - if (!progressbars_.isEmpty() && qobject_cast(o)) - { - forgetProgressBar(o); - break; - } - else if (tspec_.animate_states - && (w->windowType() == Qt::Popup - || w->windowType() == Qt::ToolTip)) + if (tspec_.animate_states + && (w->windowType() == Qt::Popup + || w->windowType() == Qt::ToolTip)) { forgetPopupOrigin(o); break; // popups aren't animated (see below)