Update project version to 2.2.2, Noto fonts and emoji support. (#1720)
This commit is contained in:
@ -5,7 +5,8 @@
|
||||
#define TAG "LvglGif"
|
||||
|
||||
LvglGif::LvglGif(const lv_img_dsc_t* img_dsc)
|
||||
: gif_(nullptr), timer_(nullptr), last_call_(0), playing_(false), loaded_(false) {
|
||||
: gif_(nullptr), timer_(nullptr), last_call_(0), playing_(false), loaded_(false),
|
||||
loop_delay_ms_(0), loop_waiting_(false), loop_wait_start_(0) {
|
||||
if (!img_dsc || !img_dsc->data) {
|
||||
ESP_LOGE(TAG, "Invalid image descriptor");
|
||||
return;
|
||||
@ -66,6 +67,7 @@ void LvglGif::Start() {
|
||||
|
||||
if (timer_) {
|
||||
playing_ = true;
|
||||
loop_waiting_ = false; // Reset loop waiting state
|
||||
last_call_ = lv_tick_get();
|
||||
lv_timer_resume(timer_);
|
||||
lv_timer_reset(timer_);
|
||||
@ -104,9 +106,15 @@ void LvglGif::Stop() {
|
||||
lv_timer_pause(timer_);
|
||||
}
|
||||
|
||||
// Reset loop waiting state
|
||||
loop_waiting_ = false;
|
||||
|
||||
if (gif_) {
|
||||
gd_rewind(gif_);
|
||||
NextFrame();
|
||||
// Render first frame without advancing
|
||||
if (gif_->canvas) {
|
||||
gd_render_frame(gif_, gif_->canvas);
|
||||
}
|
||||
ESP_LOGD(TAG, "GIF animation stopped and rewound");
|
||||
}
|
||||
}
|
||||
@ -134,6 +142,15 @@ void LvglGif::SetLoopCount(int32_t count) {
|
||||
gif_->loop_count = count;
|
||||
}
|
||||
|
||||
uint32_t LvglGif::GetLoopDelay() const {
|
||||
return loop_delay_ms_;
|
||||
}
|
||||
|
||||
void LvglGif::SetLoopDelay(uint32_t delay_ms) {
|
||||
loop_delay_ms_ = delay_ms;
|
||||
ESP_LOGD(TAG, "Loop delay set to %lu ms", delay_ms);
|
||||
}
|
||||
|
||||
uint16_t LvglGif::width() const {
|
||||
if (!loaded_ || !gif_) {
|
||||
return 0;
|
||||
@ -157,6 +174,18 @@ void LvglGif::NextFrame() {
|
||||
return;
|
||||
}
|
||||
|
||||
// Check if we're in loop wait state (only for infinite loop GIFs with delay)
|
||||
if (loop_waiting_) {
|
||||
uint32_t wait_elapsed = lv_tick_elaps(loop_wait_start_);
|
||||
if (wait_elapsed < loop_delay_ms_) {
|
||||
// Still waiting for loop delay
|
||||
return;
|
||||
}
|
||||
// Loop delay completed, continue playing
|
||||
loop_waiting_ = false;
|
||||
ESP_LOGD(TAG, "Loop delay completed, continuing GIF");
|
||||
}
|
||||
|
||||
// Check if enough time has passed for the next frame
|
||||
uint32_t elapsed = lv_tick_elaps(last_call_);
|
||||
if (elapsed < gif_->gce.delay * 10) {
|
||||
@ -165,15 +194,30 @@ void LvglGif::NextFrame() {
|
||||
|
||||
last_call_ = lv_tick_get();
|
||||
|
||||
// Save file position before getting next frame to detect loop
|
||||
uint32_t pos_before = gif_->f_rw_p;
|
||||
|
||||
// Get next frame
|
||||
int has_next = gd_get_frame(gif_);
|
||||
if (has_next == 0) {
|
||||
// Animation finished, pause timer
|
||||
// Animation truly finished (non-infinite loop)
|
||||
playing_ = false;
|
||||
if (timer_) {
|
||||
lv_timer_pause(timer_);
|
||||
}
|
||||
ESP_LOGD(TAG, "GIF animation completed");
|
||||
return;
|
||||
}
|
||||
|
||||
// Detect loop by checking if file position jumped back (rewound to start)
|
||||
// This works for looping GIFs regardless of when loop_count is set
|
||||
if (loop_delay_ms_ > 0 && gif_->f_rw_p < pos_before) {
|
||||
// File position decreased, meaning GIF looped back to beginning
|
||||
// Start waiting before rendering this frame
|
||||
loop_waiting_ = true;
|
||||
loop_wait_start_ = lv_tick_get();
|
||||
ESP_LOGD(TAG, "GIF completed one cycle, waiting %lu ms before next loop", loop_delay_ms_);
|
||||
return;
|
||||
}
|
||||
|
||||
// Render current frame
|
||||
|
||||
@ -58,6 +58,17 @@ public:
|
||||
*/
|
||||
void SetLoopCount(int32_t count);
|
||||
|
||||
/**
|
||||
* Get loop delay in milliseconds (delay between loops)
|
||||
*/
|
||||
uint32_t GetLoopDelay() const;
|
||||
|
||||
/**
|
||||
* Set loop delay in milliseconds (delay between loops)
|
||||
* @param delay_ms Delay in milliseconds before starting next loop. 0 means no delay.
|
||||
*/
|
||||
void SetLoopDelay(uint32_t delay_ms);
|
||||
|
||||
/**
|
||||
* Get GIF dimensions
|
||||
*/
|
||||
@ -86,6 +97,11 @@ private:
|
||||
bool playing_;
|
||||
bool loaded_;
|
||||
|
||||
// Loop delay configuration
|
||||
uint32_t loop_delay_ms_; // Delay between loops in milliseconds
|
||||
bool loop_waiting_; // Whether we're waiting for the next loop
|
||||
uint32_t loop_wait_start_; // Timestamp when loop wait started
|
||||
|
||||
// Frame update callback
|
||||
std::function<void()> frame_callback_;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user