跳转至

ui/components/material/cfmaterial_animation_factory.h

Material Design 3 Animation Factory. More...

Namespaces

Name
cf
cf::ui
cf::ui::components
cf::ui::components::material

Classes

Name
class cf::ui::components::material::CFMaterialAnimationFactory
Material Design 3 Animation Factory.

Detailed Description

Material Design 3 Animation Factory.

Author: Charliechen114514 (chengh1922@mails.jlu.edu.cn)

Version: 0.1

Date: 2026-02-28

Copyright: Copyright © 2026

MaterialAnimationFactory creates and manages animations following Material Design 3 motion specifications. It uses a strategy pattern to allow widget-specific customization while maintaining a simple token-based API for users.

Key features:

  • Token-based animation retrieval (e.g., "md.animation.fadeIn")
  • Automatic mapping to MotionSpec for timing and easing
  • Strategy pattern for widget-specific behavior
  • WeakPtr ownership model (factory owns, users hold weak references)
  • Global enable/disable for performance and accessibility

The factory maintains exclusive ownership of all created animations via unique_ptr, while users receive WeakPtr references. This ensures proper lifecycle management and prevents dangling pointers.

Source code

#pragma once

#include "../animation.h"
#include "animation_factory_manager.h"
#include "base/easing.h"
#include "base/weak_ptr/weak_ptr.h"
#include "base/weak_ptr/weak_ptr_factory.h"
#include "cfmaterial_animation_strategy.h"
#include "core/theme.h"
#include "export.h"
#include <QObject>
#include <memory>
#include <string>
#include <unordered_map>

namespace cf::ui::components::material {

// Forward declarations
class CFMaterialFadeAnimation;
class CFMaterialSlideAnimation;
class CFMaterialScaleAnimation;

class CF_UI_EXPORT CFMaterialAnimationFactory : public ICFAnimationManagerFactory {
    Q_OBJECT

  public:
    explicit CFMaterialAnimationFactory(const core::ICFTheme& theme,
                                        std::unique_ptr<AnimationStrategy> strategy = nullptr,
                                        QObject* parent = nullptr);

    ~CFMaterialAnimationFactory() override;

    // Non-copyable, non-movable
    CFMaterialAnimationFactory(const CFMaterialAnimationFactory&) = delete;
    CFMaterialAnimationFactory& operator=(const CFMaterialAnimationFactory&) = delete;
    CFMaterialAnimationFactory(CFMaterialAnimationFactory&&) = delete;
    CFMaterialAnimationFactory& operator=(CFMaterialAnimationFactory&&) = delete;

    cf::WeakPtr<ICFAnimationManagerFactory> GetWeakPtr() override {
        return weak_factory_.GetWeakPtr();
    }

    // Implement pure virtual functions from ICFAnimationManagerFactory
    ICFAnimationManagerFactory::RegisteredResult registerOneAnimation(const QString& name,
                                                                      const QString& type) override;

    ICFAnimationManagerFactory::RegisteredResult
    registerAnimationCreator(const QString& name, AnimationCreator creator) override;

    cf::WeakPtr<ICFAbstractAnimation> getAnimation(const char* animationToken) override;

    cf::WeakPtr<ICFAbstractAnimation> createAnimation(const AnimationDescriptor& descriptor,
                                                      QWidget* targetWidget = nullptr,
                                                      QObject* owner = nullptr);

    cf::WeakPtr<ICFAbstractAnimation> createPropertyAnimation(
        float* value, float from, float to, int durationMs,
        cf::ui::base::Easing::Type easing = cf::ui::base::Easing::Type::EmphasizedDecelerate,
        QWidget* targetWidget = nullptr, QObject* owner = nullptr);

    void setStrategy(std::unique_ptr<AnimationStrategy> strategy);

    AnimationStrategy* strategy() const { return strategy_.get(); }

    void setEnabledAll(bool enabled) override;

    bool isAllEnabled() override { return globalEnabled_; }

    void setTargetFps(const float fps);

    const core::ICFTheme& theme() const { return theme_; }

    size_t animationCount() const { return animations_.size(); }

    float getTargetFps() const { return targetFps_; }

  signals:
    void animationCreated(const QString& token);

    void animationEnabledChanged(bool enabled);

  private:
    const core::ICFTheme& theme_;

    std::unique_ptr<AnimationStrategy> strategy_;

    bool globalEnabled_ = true;

    float targetFps_ = 60.0f;

    std::unordered_map<std::string, std::unique_ptr<ICFAbstractAnimation>> animations_;

    AnimationDescriptor resolveToken(const char* token);

    std::unique_ptr<ICFAbstractAnimation> createFadeAnimation(const AnimationDescriptor& desc,
                                                              QWidget* widget);

    std::unique_ptr<ICFAbstractAnimation> createSlideAnimation(const AnimationDescriptor& desc,
                                                               QWidget* widget);

    std::unique_ptr<ICFAbstractAnimation> createScaleAnimation(const AnimationDescriptor& desc,
                                                               QWidget* widget);

    AnimationDescriptor applyStrategy(const AnimationDescriptor& descriptor, QWidget* widget);

    bool shouldEnableAnimation(QWidget* widget) const;

    cf::WeakPtrFactory<CFMaterialAnimationFactory> weak_factory_{this};
};

} // namespace cf::ui::components::material

Updated on 2026-03-09 at 10:14:01 +0000