ui/components/material/cfmaterial_property_animation.cpp¶
Material Design 3 Property Animation Implementation. More...
Namespaces¶
| Name |
|---|
| cf |
| cf::ui |
| cf::ui::components |
| cf::ui::components::material |
Detailed Description¶
Material Design 3 Property Animation Implementation.
Version: 0.1
Date: 2026-03-01
Copyright: Copyright © 2026
Implements the CFMaterialPropertyAnimation class for float property animations following Material Design 3 motion specifications.
Source code¶
#include "cfmaterial_property_animation.h"
#include "base/easing.h"
#include <QWidget>
namespace cf::ui::components::material {
// =============================================================================
// Constructor / Destructor
// =============================================================================
CFMaterialPropertyAnimation::CFMaterialPropertyAnimation(
float* value, float from, float to, int durationMs, base::Easing::Type easing, QObject* parent)
: ICFAbstractAnimation(parent)
, m_value(value)
, m_from(from)
, m_to(to)
, m_durationMs(durationMs)
, m_easing(easing)
, m_elapsed(0)
, m_targetWidget(nullptr)
, m_timer(new QTimer(this)) {
// Setup timer with dynamic interval
m_timer->setInterval(calculateInterval());
connect(m_timer, &QTimer::timeout, this, &CFMaterialPropertyAnimation::onTimerTick);
// Set initial value
if (m_value) {
*m_value = from;
}
}
CFMaterialPropertyAnimation::~CFMaterialPropertyAnimation() {
if (m_timer) {
m_timer->stop();
}
}
// =============================================================================
// ICFAbstractAnimation Interface
// =============================================================================
void CFMaterialPropertyAnimation::start(Direction dir) {
if (m_state == State::Running) {
return; // Already running
}
m_elapsed = 0;
m_state = State::Running;
// Set initial value based on direction
if (m_value) {
if (dir == Direction::Forward) {
*m_value = m_from;
} else {
*m_value = m_to;
}
}
emit started();
// Update target widget
if (m_targetWidget) {
m_targetWidget->update();
}
// Start the internal timer (60 FPS ~ 16ms)
if (m_timer) {
m_timer->start();
}
}
void CFMaterialPropertyAnimation::pause() {
if (m_state == State::Running) {
m_state = State::Paused;
if (m_timer) {
m_timer->stop();
}
emit paused();
}
}
void CFMaterialPropertyAnimation::stop() {
m_state = State::Idle;
if (m_timer) {
m_timer->stop();
}
m_elapsed = 0;
// Reset to initial value
if (m_value) {
*m_value = m_from;
}
if (m_targetWidget) {
m_targetWidget->update();
}
emit stopped();
}
void CFMaterialPropertyAnimation::reverse() {
if (m_state == State::Running) {
// Calculate remaining progress and reverse from there
float progress = static_cast<float>(m_elapsed) / m_durationMs;
progress = 1.0f - progress; // Reverse progress
m_elapsed = static_cast<int>(progress * m_durationMs);
// Swap from/to for reverse
std::swap(m_from, m_to);
} else {
// Start in reverse direction
start(Direction::Backward);
}
emit reversed();
}
bool CFMaterialPropertyAnimation::tick(int dt) {
if (m_state != State::Running) {
return false;
}
m_elapsed += dt;
// Calculate progress
float progress = static_cast<float>(m_elapsed) / m_durationMs;
// Clamp progress
if (progress > 1.0f) {
progress = 1.0f;
}
// Apply easing
QEasingCurve easingCurve = base::Easing::fromEasingType(m_easing);
float easedProgress = static_cast<float>(easingCurve.valueForProgress(progress));
// Calculate current value based on range
if (m_value) {
*m_value = m_from + (m_to - m_from) * easedProgress;
}
// Emit progress signal
emit progressChanged(easedProgress);
// Update target widget
if (m_targetWidget) {
m_targetWidget->update();
}
// Check if animation is complete
if (progress >= 1.0f) {
m_state = State::Finished;
if (m_timer) {
m_timer->stop();
}
emit finished();
return false;
}
return true;
}
// =============================================================================
// Property-Specific Methods
// =============================================================================
void CFMaterialPropertyAnimation::setTargetWidget(QWidget* widget) {
m_targetWidget = widget;
}
// =============================================================================
// Private Slots
// =============================================================================
void CFMaterialPropertyAnimation::onTimerTick() {
tick(calculateInterval());
}
} // namespace cf::ui::components::material
Updated on 2026-03-09 at 10:14:01 +0000