#pragma once #include "core/domain/Project.h" #include class TimelineWidget final : public QWidget { Q_OBJECT public: explicit TimelineWidget(QWidget* parent = nullptr); void setFrameRange(int start, int end); void setCurrentFrame(int frame); int currentFrame() const { return m_currentFrame; } void setSelectionRange(int start, int end); // -1,-1 清除 int selectionStart() const { return m_selStart; } int selectionEnd() const { return m_selEnd; } // 只显示“当前选中实体”的关键帧标记 void setKeyframeTracks(const core::Project::Entity* entityOrNull); enum class KeyKind { None, Location, UserScale, Image }; KeyKind selectedKeyKind() const { return m_selKeyKind; } int selectedKeyFrame() const { return m_selKeyFrame; } bool hasSelectedKeyframe() const { return m_selKeyKind != KeyKind::None && m_selKeyFrame >= 0; } signals: void frameScrubbed(int frame); // 拖动中实时触发(用于实时预览) void frameCommitted(int frame); // 松手/点击确认(用于较重的刷新) void contextMenuRequested(const QPoint& globalPos, int frame); void keyframeSelectionChanged(KeyKind kind, int frame); void intervalSelectionChanged(int start, int end); protected: void paintEvent(QPaintEvent*) override; void mousePressEvent(QMouseEvent*) override; void mouseMoveEvent(QMouseEvent*) override; void mouseReleaseEvent(QMouseEvent*) override; void wheelEvent(QWheelEvent*) override; private: int xToFrame(int x) const; int frameToX(int frame) const; QRect trackRect() const; void setFrameInternal(int frame, bool commit); private: int m_start = 0; int m_end = 600; int m_currentFrame = 0; int m_selStart = -1; int m_selEnd = -1; bool m_dragging = false; QPoint m_pressPos; bool m_moved = false; // snapshot(避免频繁遍历 workspace) QVector m_locFrames; QVector m_scaleFrames; QVector m_imgFrames; KeyKind m_selKeyKind = KeyKind::None; int m_selKeyFrame = -1; };