跳转至

ui/components/material/cfmaterial_scale_animation.h

Material Design 3 Scale Animation. More...

Namespaces

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

Classes

Name
class cf::ui::components::material::CFMaterialScaleAnimation
Material Design 3 Scale Animation.

Detailed Description

Material Design 3 Scale Animation.

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

Version: 0.1

Date: 2026-02-28

Copyright: Copyright © 2026

Implements a scale animation that follows Material Design 3 motion specifications. Animates the size of a widget from a start scale to an end scale using the specified timing and easing curve.

This animation integrates with the MaterialMotionScheme to obtain duration and easing values based on the motion token (e.g., "md.motion.shortEnter").

Source code

#pragma once

#include "base/weak_ptr/weak_ptr.h"
#include "base/weak_ptr/weak_ptr_factory.h"
#include "components/timing_animation.h"
#include "core/motion_spec.h"
#include "export.h"
#include <QTransform>
#include <QWidget>

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

class CF_UI_EXPORT CFMaterialScaleAnimation : public ICFTimingAnimation {
    Q_OBJECT

  public:
    explicit CFMaterialScaleAnimation(cf::ui::core::IMotionSpec* spec, QObject* parent = nullptr);

    ~CFMaterialScaleAnimation() override;

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

    // =========================================================================
    // ICFAbstractAnimation Interface
    // =========================================================================

    void start(Direction dir = Direction::Forward) override;

    void pause() override;

    void stop() override;

    void reverse() override;

    bool tick(int dt) override;

    // =========================================================================
    // ICFTimingAnimation Interface
    // =========================================================================

    float currentValue() const override { return currentScale_; }

    // =========================================================================
    // Scale-Specific Methods
    // =========================================================================

    void setTargetWidget(QWidget* widget);

    QWidget* targetWidget() const { return targetWidget_; }

    void setScaleFromCenter(bool center) { scaleFromCenter_ = center; }

    bool scaleFromCenter() const { return scaleFromCenter_; }

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

  private:
    float currentScale_ = 1.0f;

    QWidget* targetWidget_ = nullptr;

    QRect originalGeometry_;

    bool scaleFromCenter_ = true;

    int durationMs_ = 200;

    int delayMs_ = 0;

    int elapsedTime_ = 0;

    void applyScale(float scale);

    QRect calculateScaledGeometry(float scale) const;

    float calculateEasedProgress(float linearProgress) const;

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

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

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