File indexing completed on 2025-04-27 03:58:24
0001 /* ============================================================ 0002 * 0003 * This file is a part of digiKam project 0004 * https://www.digikam.org 0005 * 0006 * Date : 2010-09-20 0007 * Description : Managing visibility state with animations 0008 * 0009 * SPDX-FileCopyrightText: 2010-2011 by Marcel Wiesweg <marcel dot wiesweg at gmx dot de> 0010 * SPDX-FileCopyrightText: 2012-2024 by Gilles Caulier <caulier dot gilles at gmail dot com> 0011 * 0012 * SPDX-License-Identifier: GPL-2.0-or-later 0013 * 0014 * ============================================================ */ 0015 0016 #include "itemvisibilitycontroller.h" 0017 0018 // Qt includes 0019 0020 #include <QParallelAnimationGroup> 0021 #include <QPropertyAnimation> 0022 0023 // Local includes 0024 0025 #include "digikam_debug.h" 0026 0027 namespace Digikam 0028 { 0029 0030 ItemVisibilityControllerPropertyObject::ItemVisibilityControllerPropertyObject(QObject* const parent) 0031 : QObject (parent), 0032 m_opacity(0), 0033 m_visible(false) 0034 { 0035 } 0036 0037 qreal ItemVisibilityControllerPropertyObject::opacity() const 0038 { 0039 return m_opacity; 0040 } 0041 0042 void ItemVisibilityControllerPropertyObject::setOpacity(qreal opacity) 0043 { 0044 m_opacity = opacity; 0045 0046 Q_EMIT opacityChanged(); 0047 } 0048 0049 bool ItemVisibilityControllerPropertyObject::isVisible() const 0050 { 0051 return m_visible; 0052 } 0053 0054 void ItemVisibilityControllerPropertyObject::setVisible(bool visible) 0055 { 0056 m_visible = visible; 0057 0058 Q_EMIT visibleChanged(); 0059 } 0060 0061 // --------------------------------------------------------------------------------- 0062 0063 AnimatedVisibility::AnimatedVisibility(QObject* const parent) 0064 : ItemVisibilityControllerPropertyObject(parent) 0065 { 0066 m_controller = new ItemVisibilityController(this); 0067 m_controller->addItem(this); 0068 } 0069 0070 ItemVisibilityController* AnimatedVisibility::controller() const 0071 { 0072 return m_controller; 0073 } 0074 0075 // --------------------------------------------------------------------------------- 0076 0077 HidingStateChanger::HidingStateChanger(QObject* const parent) 0078 : ItemVisibilityController(parent), 0079 m_object (nullptr) 0080 { 0081 connect(this, SIGNAL(propertiesAssigned(bool)), 0082 this, SLOT(slotPropertiesAssigned(bool))); 0083 } 0084 0085 HidingStateChanger::HidingStateChanger(QObject* const target, const QByteArray& property, QObject* const parent) 0086 : ItemVisibilityController(parent) 0087 { 0088 connect(this, SIGNAL(propertiesAssigned(bool)), 0089 this, SLOT(slotPropertiesAssigned(bool))); 0090 0091 setTargetObject(target); 0092 setPropertyName(property); 0093 0094 // here, we assume to start with a visible item 0095 0096 setVisible(true); 0097 } 0098 0099 void HidingStateChanger::setTargetObject(QObject* const object) 0100 { 0101 m_object = object; 0102 } 0103 0104 void HidingStateChanger::setPropertyName(const QByteArray& propertyName) 0105 { 0106 m_property = propertyName; 0107 } 0108 0109 void HidingStateChanger::changeValue(const QVariant& value) 0110 { 0111 m_value = value; 0112 0113 if (!hasVisibleItems()) 0114 { 0115 // shortcut 0116 0117 slotPropertiesAssigned(false); 0118 slotPropertiesAssigned(true); 0119 } 0120 else 0121 { 0122 hide(); 0123 } 0124 } 0125 0126 void HidingStateChanger::slotPropertiesAssigned(bool visible) 0127 { 0128 if (!visible) 0129 { 0130 if (m_object) 0131 { 0132 m_object->setProperty(m_property.constData(), m_value); 0133 } 0134 0135 Q_EMIT stateChanged(); 0136 show(); 0137 } 0138 else 0139 { 0140 Q_EMIT finished(); 0141 } 0142 } 0143 0144 // --------------------------------------------------------------------------------- 0145 0146 class Q_DECL_HIDDEN AnimationControl 0147 { 0148 public: 0149 0150 enum Situation 0151 { 0152 MainControl, 0153 IndependentControl, 0154 RemovingControl 0155 }; 0156 0157 public: 0158 0159 explicit AnimationControl(ItemVisibilityController* const q); 0160 AnimationControl(AnimationControl* const other, QObject* const item); 0161 ~AnimationControl(); 0162 0163 void clear(); 0164 0165 void addItem(QAbstractAnimation* const animation, QObject* const item); 0166 QAbstractAnimation* takeItem(QObject* const item); 0167 void moveTo(AnimationControl* const other, QObject* const item); 0168 void moveAllTo(AnimationControl* const other); 0169 0170 bool hasItem(QObject* const o) const; 0171 bool hasVisibleItems(ItemVisibilityController::IncludeFadingOutMode mode) const; 0172 0173 void transitionToVisible(bool show, bool immediately = false); 0174 void animationFinished(); 0175 0176 void syncProperties(QObject* const o); 0177 void connect(QObject* const item); 0178 void disconnect(QObject* const item); 0179 0180 void setEasingCurve(const QEasingCurve& easing); 0181 void setAnimationDuration(int msecs); 0182 0183 public: 0184 0185 QList<QObject*> m_items; 0186 QAbstractAnimation* m_animation; 0187 ItemVisibilityController::State m_state; 0188 Situation m_situation; 0189 0190 private: 0191 0192 void setVisibleProperty(bool value); 0193 void connect(QAbstractAnimation* const anim); 0194 void disconnect(QAbstractAnimation* const anim); 0195 void moveToGroup(); 0196 0197 private: 0198 0199 QParallelAnimationGroup* m_animationGroup; 0200 ItemVisibilityController* const m_q; 0201 }; 0202 0203 AnimationControl::AnimationControl(ItemVisibilityController* const q) 0204 : m_animation (nullptr), 0205 m_state (ItemVisibilityController::Hidden), 0206 m_situation (MainControl), 0207 m_animationGroup(nullptr), 0208 m_q (q) 0209 { 0210 } 0211 0212 AnimationControl::AnimationControl(AnimationControl* const other, QObject* const object) 0213 : m_animation (nullptr), 0214 m_state (other->m_state), 0215 m_situation (IndependentControl), 0216 m_animationGroup(nullptr), 0217 m_q (other->m_q) 0218 { 0219 other->moveTo(this, object); 0220 } 0221 0222 AnimationControl::~AnimationControl() 0223 { 0224 clear(); 0225 delete m_animation; 0226 } 0227 0228 void AnimationControl::clear() 0229 { 0230 m_state = ItemVisibilityController::Hidden; 0231 0232 if (m_animation) 0233 { 0234 disconnect(m_animation); 0235 } 0236 0237 delete m_animation; 0238 m_animation = nullptr; 0239 m_animationGroup = nullptr; // the same pointer as animation 0240 0241 Q_FOREACH (QObject* const item, m_items) 0242 { 0243 disconnect(item); 0244 } 0245 0246 m_items.clear(); 0247 } 0248 0249 void AnimationControl::connect(QObject* const item) 0250 { 0251 m_q->connect(item, SIGNAL(destroyed(QObject*)), 0252 m_q, SLOT(objectDestroyed(QObject*))); 0253 } 0254 0255 void AnimationControl::disconnect(QObject* const item) 0256 { 0257 m_q->disconnect(item, SIGNAL(destroyed(QObject*)), 0258 m_q, SLOT(objectDestroyed(QObject*))); 0259 } 0260 0261 void AnimationControl::connect(QAbstractAnimation* const anim) 0262 { 0263 m_q->connect(anim, SIGNAL(finished()), 0264 m_q, SLOT(animationFinished())); 0265 } 0266 0267 void AnimationControl::disconnect(QAbstractAnimation* const anim) 0268 { 0269 m_q->disconnect(anim, SIGNAL(finished()), 0270 m_q, SLOT(animationFinished())); 0271 } 0272 0273 void AnimationControl::moveToGroup() 0274 { 0275 if (!m_animationGroup) 0276 { 0277 m_animationGroup = new QParallelAnimationGroup; 0278 connect(m_animationGroup); 0279 0280 if (m_animation) 0281 { 0282 disconnect(m_animation); 0283 m_animationGroup->addAnimation(m_animation); 0284 } 0285 0286 m_animation = m_animationGroup; 0287 } 0288 } 0289 0290 void AnimationControl::addItem(QAbstractAnimation* const anim, QObject* const item) 0291 { 0292 // Either there is no group but now for the first time two items, 0293 // or the control got empty intermittently, but still has the group installed 0294 0295 if (!m_items.isEmpty() || m_animationGroup) 0296 { 0297 moveToGroup(); 0298 m_animationGroup->addAnimation(anim); 0299 } 0300 else 0301 { 0302 connect(anim); 0303 m_animation = anim; 0304 } 0305 0306 m_items << item; 0307 } 0308 0309 QAbstractAnimation* AnimationControl::takeItem(QObject* const item) 0310 { 0311 int index = m_items.indexOf(item); 0312 0313 if (index == -1) 0314 { 0315 return nullptr; 0316 } 0317 0318 m_items.removeAt(index); 0319 0320 if (m_animationGroup) 0321 { 0322 return m_animationGroup->takeAnimation(index); 0323 } 0324 else 0325 { 0326 QAbstractAnimation* const anim = m_animation; 0327 disconnect(m_animation); 0328 m_animation = nullptr; 0329 return anim; 0330 } 0331 } 0332 0333 void AnimationControl::moveTo(AnimationControl* const other, QObject* const item) 0334 { 0335 QAbstractAnimation* const anim = takeItem(item); 0336 0337 if (anim) 0338 { 0339 other->addItem(anim, item); 0340 } 0341 } 0342 0343 void AnimationControl::moveAllTo(AnimationControl* const other) 0344 { 0345 Q_FOREACH (QObject* const item, m_items) 0346 { 0347 moveTo(other, item); 0348 } 0349 } 0350 0351 bool AnimationControl::hasItem(QObject* const o) const 0352 { 0353 return m_items.contains(o); 0354 } 0355 0356 bool AnimationControl::hasVisibleItems(ItemVisibilityController::IncludeFadingOutMode mode) const 0357 { 0358 if (m_items.isEmpty()) 0359 { 0360 return false; 0361 } 0362 0363 if (mode == ItemVisibilityController::IncludeFadingOut) 0364 { 0365 return (m_state != ItemVisibilityController::Hidden); 0366 } 0367 else 0368 { 0369 return ((m_state != ItemVisibilityController::Hidden) && (m_state != ItemVisibilityController::FadingOut)); 0370 } 0371 } 0372 0373 void AnimationControl::setVisibleProperty(bool value) 0374 { 0375 Q_FOREACH (QObject* const o, m_items) 0376 { 0377 o->setProperty("visible", value); 0378 } 0379 } 0380 0381 void AnimationControl::syncProperties(QObject* const o) 0382 { 0383 if (m_state == ItemVisibilityController::Visible || m_state == ItemVisibilityController::FadingIn) 0384 { 0385 o->setProperty("visible", true); 0386 o->setProperty("opacity", 1.0); 0387 } 0388 else 0389 { 0390 o->setProperty("visible", false); 0391 o->setProperty("opacity", 0); 0392 } 0393 } 0394 0395 void AnimationControl::transitionToVisible(bool show, bool immediately) 0396 { 0397 //qCDebug(DIGIKAM_WIDGETS_LOG) << "state" << state << "show" << show << items.size(); 0398 0399 if (show) 0400 { 0401 if ((m_state == ItemVisibilityController::Visible) || (m_state == ItemVisibilityController::FadingIn)) 0402 { 0403 return; 0404 } 0405 0406 if (m_state == ItemVisibilityController::Hidden) 0407 { 0408 setVisibleProperty(true); 0409 } 0410 0411 m_state = ItemVisibilityController::FadingIn; 0412 } 0413 else 0414 { 0415 if ((m_state == ItemVisibilityController::Hidden) || (m_state == ItemVisibilityController::FadingOut)) 0416 { 0417 return; 0418 } 0419 0420 m_state = ItemVisibilityController::FadingOut; 0421 } 0422 0423 if (m_animation) 0424 { 0425 QAbstractAnimation::Direction direction = show ? QAbstractAnimation::Forward 0426 : QAbstractAnimation::Backward; 0427 m_animation->setDirection(direction); 0428 0429 if (immediately) 0430 { 0431 m_animation->setCurrentTime(show ? m_animation->totalDuration() : 0); 0432 } 0433 0434 m_animation->start(); 0435 } 0436 } 0437 0438 void AnimationControl::animationFinished() 0439 { 0440 if (m_state == ItemVisibilityController::FadingOut) 0441 { 0442 setVisibleProperty(false); 0443 m_state = ItemVisibilityController::Hidden; 0444 } 0445 else if (m_state == ItemVisibilityController::FadingIn) 0446 { 0447 m_state = ItemVisibilityController::Visible; 0448 } 0449 } 0450 0451 void AnimationControl::setEasingCurve(const QEasingCurve& easing) 0452 { 0453 if (m_animationGroup) 0454 { 0455 for (int i = 0 ; i < m_animationGroup->animationCount() ; ++i) 0456 { 0457 QVariantAnimation* const anim = static_cast<QVariantAnimation*>(m_animationGroup->animationAt(i)); 0458 0459 if (anim) 0460 { 0461 anim->setEasingCurve(easing); 0462 } 0463 } 0464 } 0465 else if (m_animation) 0466 { 0467 QVariantAnimation* const anim = static_cast<QVariantAnimation*>(m_animation); 0468 0469 if (anim) 0470 { 0471 anim->setEasingCurve(easing); 0472 } 0473 } 0474 } 0475 0476 void AnimationControl::setAnimationDuration(int msecs) 0477 { 0478 if (m_animationGroup) 0479 { 0480 for (int i = 0 ; i < m_animationGroup->animationCount() ; ++i) 0481 { 0482 QVariantAnimation* const anim = static_cast<QVariantAnimation*>(m_animationGroup->animationAt(i)); 0483 0484 if (anim) 0485 { 0486 anim->setDuration(msecs); 0487 } 0488 } 0489 } 0490 else if (m_animation) 0491 { 0492 QVariantAnimation* const anim = static_cast<QVariantAnimation*>(m_animation); 0493 0494 if (anim) 0495 { 0496 anim->setDuration(msecs); 0497 } 0498 } 0499 } 0500 0501 // --------------------------------------------------------------------------------- 0502 0503 class Q_DECL_HIDDEN ItemVisibilityController::Private 0504 { 0505 public: 0506 0507 explicit Private(ItemVisibilityController* const qq) 0508 : visible (false), 0509 shallBeShown (true), 0510 itemShallBeShown (nullptr), 0511 animationDuration(75), 0512 easingCurve (QEasingCurve::InOutQuad), 0513 control (nullptr), 0514 q (qq) 0515 { 0516 } 0517 0518 public: 0519 0520 void setVisible(bool v, bool immediately); 0521 void setItemVisible(QObject* const item, bool visible, bool immediately); 0522 0523 AnimationControl* findInChildren(QObject* const item) const; 0524 AnimationControl* getChild(QObject* const item); 0525 void cleanupChildren(QAbstractAnimation* const finishedAnimation); 0526 0527 public: 0528 0529 bool visible; 0530 bool shallBeShown; 0531 QObject* itemShallBeShown; 0532 0533 int animationDuration; 0534 QEasingCurve easingCurve; 0535 0536 AnimationControl* control; 0537 QList<AnimationControl*> childControls; 0538 ItemVisibilityController* const q; 0539 }; 0540 0541 AnimationControl* ItemVisibilityController::Private::findInChildren(QObject* const item) const 0542 { 0543 Q_FOREACH (AnimationControl* const child, childControls) 0544 { 0545 if (child->hasItem(item)) 0546 { // cppcheck-suppress useStlAlgorithm 0547 return child; 0548 } 0549 } 0550 0551 return nullptr; 0552 } 0553 0554 AnimationControl* ItemVisibilityController::Private::getChild(QObject* const item) 0555 { 0556 if (!control) 0557 { 0558 return nullptr; 0559 } 0560 0561 if (control->hasItem(item)) 0562 { 0563 AnimationControl* const child = new AnimationControl(control, item); 0564 childControls << child; 0565 0566 return child; 0567 } 0568 else 0569 { 0570 return findInChildren(item); 0571 } 0572 } 0573 0574 void ItemVisibilityController::Private::cleanupChildren(QAbstractAnimation* const finishedAnimation) 0575 { 0576 QList<AnimationControl*>::iterator it; 0577 0578 for (it = childControls.begin() ; it != childControls.end() ; ) 0579 { 0580 AnimationControl* child = *it; 0581 0582 if ((child->m_state == control->m_state) && (child->m_situation == AnimationControl::IndependentControl)) 0583 { 0584 // merge back to main control 0585 0586 child->moveAllTo(control); 0587 delete child; 0588 it = childControls.erase(it); 0589 } 0590 else if ((child->m_animation == finishedAnimation) && (child->m_situation == AnimationControl::RemovingControl)) 0591 { 0592 Q_FOREACH (QObject* const item, child->m_items) 0593 { 0594 Q_EMIT q->hiddenAndRemoved(item); 0595 } 0596 0597 delete child; 0598 it = childControls.erase(it); 0599 } 0600 else 0601 { 0602 ++it; 0603 } 0604 } 0605 } 0606 0607 void ItemVisibilityController::Private::setVisible(bool v, bool immediately) 0608 { 0609 // no check d->visible == visible 0610 0611 visible = v; 0612 0613 if (control) 0614 { 0615 control->transitionToVisible(shallBeShown && visible, immediately); 0616 } 0617 0618 Q_FOREACH (AnimationControl* const child, childControls) 0619 { 0620 if (child->m_situation == AnimationControl::IndependentControl) 0621 { 0622 child->transitionToVisible(shallBeShown && visible, immediately); 0623 } 0624 } 0625 0626 if (itemShallBeShown) 0627 { 0628 setItemVisible(itemShallBeShown, visible, immediately); 0629 } 0630 } 0631 0632 void ItemVisibilityController::Private::setItemVisible(QObject* const item, bool visible, bool immediately) 0633 { 0634 AnimationControl* const child = getChild(item); 0635 0636 if (child) 0637 { 0638 child->transitionToVisible(visible, immediately); 0639 } 0640 } 0641 0642 // --------------------------------------------------------------------------------- 0643 0644 ItemVisibilityController::ItemVisibilityController(QObject* const parent) 0645 : QObject(parent), 0646 d (new Private(this)) 0647 { 0648 } 0649 0650 ItemVisibilityController::~ItemVisibilityController() 0651 { 0652 clear(); 0653 delete d->control; 0654 delete d; 0655 } 0656 0657 QPropertyAnimation* ItemVisibilityController::createAnimation(QObject*) 0658 { 0659 QPropertyAnimation* const anim = new QPropertyAnimation(this); 0660 anim->setPropertyName("opacity"); 0661 anim->setStartValue(0); 0662 anim->setEndValue(1.0); 0663 anim->setDuration(d->animationDuration); 0664 anim->setEasingCurve(d->easingCurve); 0665 0666 return anim; 0667 } 0668 0669 void ItemVisibilityController::addItem(QObject* item) 0670 { 0671 if (!item) 0672 { 0673 return; 0674 } 0675 0676 if (!d->control) 0677 { 0678 // initialize main control 0679 0680 d->control = new AnimationControl(this); 0681 d->control->transitionToVisible(d->shallBeShown && d->visible); 0682 } 0683 0684 QPropertyAnimation* const anim = createAnimation(item); 0685 anim->setTargetObject(item); 0686 d->control->connect(item); 0687 d->control->syncProperties(item); 0688 d->control->addItem(anim, item); 0689 } 0690 0691 void ItemVisibilityController::removeItem(QObject* item) 0692 { 0693 if (!item || !d->control) 0694 { 0695 return; 0696 } 0697 0698 if (d->control->hasItem(item)) 0699 { 0700 d->control->disconnect(item); 0701 delete d->control->takeItem(item); 0702 } 0703 else 0704 { 0705 AnimationControl* child = d->findInChildren(item); 0706 0707 if (child) 0708 { 0709 child->disconnect(item); 0710 d->childControls.removeOne(child); 0711 delete child; 0712 } 0713 } 0714 } 0715 0716 void ItemVisibilityController::clear() 0717 { 0718 if (d->control) 0719 { 0720 d->control->clear(); 0721 } 0722 0723 Q_FOREACH (AnimationControl* const child, d->childControls) 0724 { 0725 child->clear(); 0726 } 0727 0728 d->childControls.clear(); 0729 0730 d->visible = false; 0731 } 0732 0733 QList<QObject*> ItemVisibilityController::items() const 0734 { 0735 QList<QObject*> items; 0736 0737 if (d->control) 0738 { 0739 items = d->control->m_items; 0740 } 0741 0742 Q_FOREACH (AnimationControl* const child, d->childControls) 0743 { 0744 // cppcheck-suppress useStlAlgorithm 0745 items += child->m_items; 0746 } 0747 0748 return items; 0749 } 0750 0751 QList<QObject*> ItemVisibilityController::visibleItems(IncludeFadingOutMode mode) const 0752 { 0753 QList<QObject*> items; 0754 0755 if (d->control && d->control->hasVisibleItems(mode)) 0756 { 0757 items = d->control->m_items; 0758 } 0759 0760 Q_FOREACH (AnimationControl* const child, d->childControls) 0761 { 0762 if (child->hasVisibleItems(mode)) 0763 { 0764 // cppcheck-suppress useStlAlgorithm 0765 items += child->m_items; 0766 } 0767 } 0768 0769 return items; 0770 } 0771 0772 bool ItemVisibilityController::shallBeShown() const 0773 { 0774 return d->shallBeShown; 0775 } 0776 0777 bool ItemVisibilityController::isVisible() const 0778 { 0779 return d->visible; 0780 } 0781 0782 ItemVisibilityController::State ItemVisibilityController::state() const 0783 { 0784 return (d->control ? d->control->m_state : Hidden); 0785 } 0786 0787 bool ItemVisibilityController::hasVisibleItems(IncludeFadingOutMode mode) const 0788 { 0789 if (d->control && d->control->hasVisibleItems(mode)) 0790 { 0791 return true; 0792 } 0793 0794 Q_FOREACH (AnimationControl* const child, d->childControls) 0795 { 0796 if (child->hasVisibleItems(mode)) 0797 { // cppcheck-suppress useStlAlgorithm 0798 return true; 0799 } 0800 } 0801 0802 return false; 0803 } 0804 0805 void ItemVisibilityController::setEasingCurve(const QEasingCurve& easing) 0806 { 0807 d->easingCurve = easing; 0808 0809 if (d->control) 0810 { 0811 d->control->setEasingCurve(easing); 0812 } 0813 0814 Q_FOREACH (AnimationControl* const child, d->childControls) 0815 { 0816 child->setEasingCurve(easing); 0817 } 0818 } 0819 0820 void ItemVisibilityController::setAnimationDuration(int msecs) 0821 { 0822 d->animationDuration = msecs; 0823 0824 if (d->control) 0825 { 0826 d->control->setAnimationDuration(msecs); 0827 } 0828 0829 Q_FOREACH (AnimationControl* const child, d->childControls) 0830 { 0831 child->setAnimationDuration(msecs); 0832 } 0833 } 0834 0835 void ItemVisibilityController::setShallBeShown(bool shallBeShown) 0836 { 0837 // no check d->shallBeShown == shallBeShown 0838 0839 d->shallBeShown = shallBeShown; 0840 d->itemShallBeShown = nullptr; 0841 0842 // apply 0843 0844 setVisible(d->visible); 0845 } 0846 0847 void ItemVisibilityController::setShallBeShownDirectly(bool shallBeShown) 0848 { 0849 // no check d->shallBeShown == shallBeShown 0850 0851 d->shallBeShown = shallBeShown; 0852 d->itemShallBeShown = nullptr; 0853 0854 // apply 0855 0856 setDirectlyVisible(d->visible); 0857 } 0858 0859 void ItemVisibilityController::setItemThatShallBeShown(QObject* item) 0860 { 0861 d->itemShallBeShown = item; 0862 d->shallBeShown = false; 0863 setVisible(d->visible); 0864 } 0865 0866 void ItemVisibilityController::show() 0867 { 0868 setVisible(true); 0869 } 0870 0871 void ItemVisibilityController::hide() 0872 { 0873 setVisible(false); 0874 } 0875 0876 void ItemVisibilityController::setVisible(bool visible) 0877 { 0878 d->setVisible(visible, false); 0879 } 0880 0881 void ItemVisibilityController::setDirectlyVisible(bool visible) 0882 { 0883 d->setVisible(visible, true); 0884 } 0885 0886 void ItemVisibilityController::showItem(QObject* item) 0887 { 0888 setItemVisible(item, true); 0889 } 0890 0891 void ItemVisibilityController::hideItem(QObject* item) 0892 { 0893 setItemVisible(item, false); 0894 } 0895 0896 void ItemVisibilityController::setItemVisible(QObject* item, bool visible) 0897 { 0898 d->setItemVisible(item, visible, false); 0899 } 0900 0901 void ItemVisibilityController::setItemDirectlyVisible(QObject* item, bool visible) 0902 { 0903 d->setItemVisible(item, visible, true); 0904 } 0905 0906 void ItemVisibilityController::hideAndRemoveItem(QObject* item) 0907 { 0908 AnimationControl* const child = d->getChild(item); 0909 0910 if (child) 0911 { 0912 child->m_situation = AnimationControl::RemovingControl; 0913 child->transitionToVisible(false); 0914 } 0915 } 0916 0917 void ItemVisibilityController::animationFinished() 0918 { 0919 QAbstractAnimation* const animation = static_cast<QAbstractAnimation*>(sender()); 0920 0921 if (d->control && (d->control->m_animation == animation)) 0922 { 0923 d->control->animationFinished(); 0924 Q_EMIT propertiesAssigned(d->control->m_state == Visible); 0925 } 0926 0927 Q_FOREACH (AnimationControl* const child, d->childControls) 0928 { 0929 if (child->m_animation == animation) 0930 { 0931 child->animationFinished(); 0932 0933 Q_FOREACH (QObject* const item, child->m_items) 0934 { 0935 if (d->control) 0936 { 0937 Q_EMIT propertiesAssigned(item, (d->control->m_state == Visible)); 0938 } 0939 } 0940 } 0941 } 0942 0943 // if a child is now in main state, move again to main control 0944 0945 d->cleanupChildren(animation); 0946 } 0947 0948 void ItemVisibilityController::objectDestroyed(QObject* item) 0949 { 0950 removeItem(item); 0951 } 0952 0953 } // namespace Digikam 0954 0955 #include "moc_itemvisibilitycontroller.cpp"