feat(contacts): animated avatars (GIF/WebP) with a Settings toggle
Animate contact avatars end to end:
- texture_loader gains LoadAnimatedRGBA: decodes an image into a downscaled
RGBA frame sequence + per-frame durations — animated GIF via stb
(stbi_load_gif_from_memory) and animated WebP via libwebp's WebPAnimDecoder;
stills (and APNG, which stb reads as one image) return a single frame. Frames
are box-downscaled (smaller cap for animations) to bound VRAM, capped at 300.
- The contacts avatar cache now holds a frame sequence; currentAvatarFrame()
advances animated avatars by the ImGui clock and is used everywhere avatars
draw (list, cards, table, grid, preview). When a live animated frame is drawn
it flags the render loop (ConsumeContactsAvatarAnimation, clear-on-read) so
main.cpp keeps producing frames while animation plays and idles when it stops
or the contacts view is hidden.
- New animate_avatars setting (default on) + a Settings appearance toggle
("Animate avatars"); off shows the first frame only. currentAvatarFrame
honors it. +i18n (8 langs, CJK subset rebuilt for 帧/播/첫).
Verified: a 3-frame GIF and a 3-frame animated WebP both decode to 3 frames
with correct 120ms delays through the exact libwebp/stb calls used here.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -6,9 +6,31 @@
|
||||
|
||||
#include "imgui.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
namespace dragonx {
|
||||
namespace util {
|
||||
|
||||
/**
|
||||
* @brief Downscaled RGBA frame sequence for an image (1 frame for stills, N for animations).
|
||||
*/
|
||||
struct AnimFrames {
|
||||
std::vector<std::vector<unsigned char>> frames; ///< each is w*h*4 RGBA (already downscaled)
|
||||
std::vector<float> delaysSec; ///< per-frame duration in seconds (parallel to frames)
|
||||
int w = 0;
|
||||
int h = 0;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Decode an image into 1+ downscaled RGBA frames plus per-frame durations.
|
||||
*
|
||||
* Animated GIF (via stb) and animated WebP (via libwebp WebPAnimDecoder) return every frame (capped at
|
||||
* maxFrames); static formats — and APNG, which stb reads as a single image — return one frame. Frames
|
||||
* are box-downscaled internally (smaller for animations to bound VRAM). The caller uploads each frame
|
||||
* with CreateRawTexture. Returns false on decode failure.
|
||||
*/
|
||||
bool LoadAnimatedRGBA(const char* path, int maxFrames, AnimFrames& out);
|
||||
|
||||
/**
|
||||
* @brief Load a PNG/JPG/BMP image from disk into an OpenGL or DX11 texture.
|
||||
* @param path File path (relative to working directory or absolute)
|
||||
|
||||
Reference in New Issue
Block a user