651 lines
20 KiB
C
651 lines
20 KiB
C
#include "efm_icon.h"
|
|
#include <Emotion.h>
|
|
|
|
// XXX: support animated files (anim gif etc.)
|
|
// XXX: support video files (mp4 etc.)
|
|
// XXX: support edj files ???
|
|
// XXX: url's ?
|
|
|
|
typedef struct _Smart_Data Smart_Data;
|
|
|
|
struct _Smart_Data
|
|
{
|
|
Evas_Object_Smart_Clipped_Data __clipped_data;
|
|
|
|
Eina_Rectangle geom;
|
|
|
|
Evas_Object *o_smart; // the smart object container itself
|
|
Evas_Object *o_image; // the image to be shown right now
|
|
Evas_Object *o_image2; // the image being loaded still
|
|
Evas_Object *o_video; // the image used for video/audio playback
|
|
|
|
Ecore_Timer *settle_timer; // time to figure out when
|
|
Ecore_Job *wakeup; // a job to wake up the loop
|
|
Eina_Stringshare *file; // file path or...
|
|
Eina_Stringshare *thumb; // thumb path
|
|
Eina_Stringshare *video; // video path
|
|
Ecore_Timer *anim_timer; // timer for animation frame flipping
|
|
|
|
int load_size; // the sie we want to load now
|
|
int orig_w, orig_h; // the sie of the img we loaded
|
|
int frame; // current frame to display
|
|
int frame_count; // number of frames in anim
|
|
double video_ratio; // aspect ratio for videos
|
|
Evas_Image_Animated_Loop_Hint loop_type; // animated loop type
|
|
Eina_Bool alpha : 1; // does the img have alpha
|
|
Eina_Bool svg : 1; // is the img a svg
|
|
Eina_Bool newfile : 1; // did we just set a new file
|
|
Eina_Bool animated : 1; // is this animated?
|
|
Eina_Bool vid_stream : 1; // is this video (has video frames?)
|
|
Eina_Bool audio : 1; // is this audio (has audo)
|
|
Eina_Bool mono_thumb : 1; // is thumb of mono white alpha img
|
|
};
|
|
|
|
static Evas_Smart *_smart = NULL;
|
|
static Evas_Smart_Class _sc = EVAS_SMART_CLASS_INIT_NULL;
|
|
static Evas_Smart_Class _sc_parent = EVAS_SMART_CLASS_INIT_NULL;
|
|
|
|
static void _image_add(Smart_Data *sd);
|
|
static int _size_choose(Smart_Data *sd, const int *sizes);
|
|
static void _cb_wakeup(void *data);
|
|
static void _wakeup(Smart_Data *sd);
|
|
static void _image_file_set(Smart_Data *sd);
|
|
static void _image_thumb_set(Smart_Data *sd);
|
|
static void _image_resized(Smart_Data *sd);
|
|
static Eina_Bool _cb_settle_timer(void *data);
|
|
static void _cb_image_preload(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED);
|
|
static void _handle_frame(Smart_Data *sd);
|
|
|
|
// sizes stored in thumbnail files that we might want to look at
|
|
static const int _thumb_sizes[] = { 512, 256, 128, 64, 32, 16, 0 };
|
|
// sizes we might want to load/render svg's at
|
|
static const int _svg_sizes[] = { 4096, 2048, 1024, 512, 256, 128, 64, 32, 16, 0 };
|
|
|
|
#define ENTRY Smart_Data *sd = evas_object_smart_data_get(obj); if (!sd) return
|
|
|
|
static void
|
|
_image_add(Smart_Data *sd)
|
|
{ // add a new hidden image object (image2) that will be busy loading
|
|
Evas_Object *o;
|
|
|
|
if (sd->o_image2) evas_object_del(sd->o_image2);
|
|
sd->o_image2 = o = evas_object_image_filled_add
|
|
(evas_object_evas_get(sd->o_smart));
|
|
evas_object_image_scale_hint_set(o, EVAS_IMAGE_SCALE_HINT_STATIC);
|
|
evas_object_smart_member_add(o, sd->o_smart); // this is a member
|
|
evas_object_image_load_head_skip_set(o, EINA_TRUE); // fileset no load head
|
|
// when the image is fully loaded then call this callback so its all
|
|
// ready and no more i/o is happening (this happens in a thread)
|
|
evas_object_event_callback_add(o, EVAS_CALLBACK_IMAGE_PRELOADED,
|
|
_cb_image_preload, sd);
|
|
}
|
|
|
|
static int
|
|
_size_choose(Smart_Data *sd, const int *sizes)
|
|
{ // find the next size up we want given the current object size
|
|
int i, max_size = 0;
|
|
|
|
// use the biggest axis as our desired size
|
|
if (sd->geom.w > sd->geom.h) max_size = sd->geom.w;
|
|
else max_size = sd->geom.h;
|
|
for (i = 0; sizes[i] > 0; i++)
|
|
{
|
|
if (i > 0)
|
|
{ // if we're not the first item in the sizes
|
|
// if size is bigger than this slot - return the size up
|
|
if (max_size > sizes[i]) return sizes[i - 1];
|
|
}
|
|
else
|
|
{ // we're after the first item in our sizes so use biggest
|
|
if (max_size > sizes[i]) return sizes[i];
|
|
}
|
|
}
|
|
return sizes[i - 1]; // no size found - choose smallest
|
|
}
|
|
|
|
static void
|
|
_cb_wakeup(void *data)
|
|
{ // we woke up - mark obj as changed....
|
|
Smart_Data *sd = data;
|
|
sd->wakeup = NULL;
|
|
evas_object_smart_changed(sd->o_smart);
|
|
}
|
|
|
|
static void
|
|
_wakeup(Smart_Data *sd)
|
|
{ // wake up the main loop so we spin around and do things
|
|
if (sd->wakeup) ecore_job_del(sd->wakeup);
|
|
sd->wakeup = ecore_job_add(_cb_wakeup, sd);
|
|
}
|
|
|
|
static void
|
|
_image_file_set_final(Smart_Data *sd, const char *file, const char *group)
|
|
{ // complete image file load/setup, gtrigger preload etc.
|
|
const char *ext;
|
|
|
|
// skip head will make animated not work - so skip it if format might
|
|
// be animated so we can flip frames
|
|
ext = strrchr(file, '.');
|
|
if (ext && ((!strcasecmp(ext, ".gif")) ||
|
|
(!strcasecmp(ext, ".webp")) ||
|
|
(!strcasecmp(ext, ".avif")) ||
|
|
(!strcasecmp(ext, ".avifs")) ||
|
|
(!strcasecmp(ext, ".jxl"))))
|
|
evas_object_image_load_head_skip_set(sd->o_image2, EINA_FALSE);
|
|
evas_object_image_file_set(sd->o_image2, file, group);
|
|
evas_object_image_preload(sd->o_image2, EINA_FALSE);
|
|
evas_object_smart_changed(sd->o_smart);
|
|
_wakeup(sd);
|
|
}
|
|
|
|
static void
|
|
_image_file_set(Smart_Data *sd)
|
|
{ // set a generic target image file
|
|
int load_size = _size_choose(sd, _svg_sizes);
|
|
|
|
if (sd->o_video)
|
|
{ // nuke previous video object if there
|
|
evas_object_del(sd->o_video);
|
|
sd->o_video = NULL;
|
|
}
|
|
if (sd->svg)
|
|
{ // if it's a svg file...
|
|
if (!sd->settle_timer)
|
|
{ // if we dont have a pending settle timer anymore use an EXACT sz
|
|
if (sd->geom.w > sd->geom.h) load_size = sd->geom.w;
|
|
else load_size = sd->geom.h;
|
|
}
|
|
}
|
|
// we already have this thumbnail size so no point loading it again
|
|
if (load_size == sd->load_size) return;
|
|
_image_add(sd);
|
|
sd->load_size = load_size;
|
|
if (sd->svg)
|
|
{ // it's a svg so tell the svg loader to render at this size
|
|
if (sd->load_size == 0) return;
|
|
evas_object_image_load_size_set(sd->o_image2,
|
|
sd->load_size, sd->load_size);
|
|
}
|
|
_image_file_set_final(sd, sd->file, NULL);
|
|
}
|
|
|
|
static void
|
|
_image_thumb_set(Smart_Data *sd)
|
|
{ // set a thumb file from our stored thumbnails
|
|
char buf[64];
|
|
int load_size = _size_choose(sd, _thumb_sizes);
|
|
|
|
// we already have this thumbnail size so no point loading it again
|
|
if (load_size == sd->load_size) return;
|
|
_image_add(sd);
|
|
if (sd->newfile)
|
|
{
|
|
Eet_File *ef = eet_open(sd->thumb, EET_FILE_MODE_READ);
|
|
if (ef)
|
|
{
|
|
int size;
|
|
char *mono = eet_read(ef, "image/thumb/mono", &size);
|
|
|
|
if (mono)
|
|
{
|
|
sd->mono_thumb = *mono;
|
|
free(mono);
|
|
}
|
|
eet_close(ef);
|
|
}
|
|
}
|
|
sd->load_size = load_size;
|
|
snprintf(buf, sizeof(buf), "image/thumb/%i", sd->load_size);
|
|
_image_file_set_final(sd, sd->thumb, buf);
|
|
}
|
|
|
|
static void
|
|
_cb_vid_frame(void *data, Evas_Object *obj EINA_UNUSED, void *event EINA_UNUSED)
|
|
{ // we decoded a frame - make sure vide3o is shown now we have a frame
|
|
Smart_Data *sd = data;
|
|
|
|
evas_object_show(sd->o_video);
|
|
}
|
|
|
|
static void
|
|
_cb_vid_resize(void *data, Evas_Object *obj EINA_UNUSED, void *event EINA_UNUSED)
|
|
{ // the video changed video size - tell owner we loaded or resized
|
|
Smart_Data *sd = data;
|
|
|
|
emotion_object_size_get(sd->o_video, &(sd->orig_w), &(sd->orig_h));
|
|
sd->video_ratio = emotion_object_ratio_get(sd->o_video);
|
|
if (sd->newfile)
|
|
{ // it's a new file, so say we loaded as its the first time
|
|
evas_object_smart_callback_call(sd->o_smart, "loaded", NULL);
|
|
sd->newfile = EINA_FALSE;
|
|
}
|
|
else // already playing the file - not new, si resized
|
|
evas_object_smart_callback_call(sd->o_smart, "resized", NULL);
|
|
}
|
|
|
|
static void
|
|
_cb_vid_open_done(void *data, Evas_Object *obj EINA_UNUSED, void *event EINA_UNUSED)
|
|
{ // we finished opening - now go to 0 and play
|
|
Smart_Data *sd = data;
|
|
|
|
emotion_object_position_set(sd->o_video, 0.0);
|
|
emotion_object_play_set(sd->o_video, EINA_TRUE);
|
|
}
|
|
|
|
static void
|
|
_cb_vid_play_finish(void *data, Evas_Object *obj EINA_UNUSED, void *event EINA_UNUSED)
|
|
{ // we finished playing go back to 0 and restart so we loop
|
|
Smart_Data *sd = data;
|
|
|
|
emotion_object_play_set(sd->o_video, EINA_FALSE);
|
|
emotion_object_position_set(sd->o_video, 0.0);
|
|
emotion_object_play_set(sd->o_video, EINA_TRUE);
|
|
}
|
|
|
|
static void
|
|
_image_video_set(Smart_Data *sd)
|
|
{ // set a video file
|
|
static Eina_Bool emotion_initted = EINA_FALSE;
|
|
Evas_Object *o;
|
|
|
|
if (sd->o_image)
|
|
{ // nuke previous image object if there
|
|
evas_object_del(sd->o_image);
|
|
sd->o_image = NULL;
|
|
}
|
|
if (sd->o_image2)
|
|
{ // nuke previous image object if there
|
|
evas_object_del(sd->o_image2);
|
|
sd->o_image2 = NULL;
|
|
}
|
|
if (sd->o_video)
|
|
{ // nuke previous video object if there
|
|
evas_object_del(sd->o_video);
|
|
sd->o_video = NULL;
|
|
}
|
|
|
|
if (!emotion_initted)
|
|
{ // emotion needs an init - so init it first time only
|
|
emotion_init();
|
|
emotion_initted = EINA_TRUE;
|
|
}
|
|
// XXX: sometimes this stalls because gstreamer is updating registry data
|
|
// in gstreamer_module_init -> gst_init_check -> g_option_context_parse
|
|
// -> gst_update_registry -> gst_poll_wait
|
|
sd->o_video = o = emotion_object_add(evas_object_evas_get(sd->o_smart));
|
|
emotion_object_keep_aspect_set(o, EMOTION_ASPECT_KEEP_NONE);
|
|
evas_object_smart_member_add(o, sd->o_smart); // this is a member
|
|
evas_object_smart_callback_add(o, "frame_decode", _cb_vid_frame, sd);
|
|
evas_object_smart_callback_add(o, "frame_resize", _cb_vid_resize, sd);
|
|
evas_object_smart_callback_add(o, "open_done", _cb_vid_open_done, sd);
|
|
evas_object_smart_callback_add(o, "playback_finished", _cb_vid_play_finish, sd);
|
|
// other callbacks - we don't need these for now
|
|
// evas_object_smart_callback_add(o, "decode_stop", _cb_vid_stop, obj);
|
|
// evas_object_smart_callback_add(o, "progress_change", _cb_vid_progress, obj);
|
|
// evas_object_smart_callback_add(o, "position_update", _cb_position_update, obj);
|
|
// evas_object_smart_callback_add(o, "length_change", _cb_length_change, obj);
|
|
// evas_object_smart_callback_add(o, "title_change", _cb_title_change, obj);
|
|
// evas_object_smart_callback_add(o, "audio_level_change", _cb_audio_change, obj);
|
|
// evas_object_smart_callback_add(o, "playback_started", _cb_play_start, obj);
|
|
emotion_object_file_set(o, sd->video);
|
|
emotion_object_audio_mute_set(o, EINA_TRUE);
|
|
emotion_object_audio_volume_set(o, 0.0);
|
|
}
|
|
|
|
static void
|
|
_image_resized(Smart_Data *sd)
|
|
{ // the image was just resized to handle that settling "idle" timer
|
|
if (sd->svg)
|
|
{ // it's an svg - so set up a timer so if we dont resize again for 0.2s
|
|
if (sd->settle_timer) ecore_timer_reset(sd->settle_timer);
|
|
else sd->settle_timer = ecore_timer_add(0.2, _cb_settle_timer, sd);
|
|
}
|
|
else
|
|
{ // not a svg - nuke settle timer from space - the only way to be sure
|
|
if (sd->settle_timer)
|
|
{
|
|
ecore_timer_del(sd->settle_timer);
|
|
sd->settle_timer = NULL;
|
|
}
|
|
}
|
|
}
|
|
|
|
static void
|
|
_image_update(Smart_Data *sd)
|
|
{ // update the image - perhaps size changed...
|
|
if (sd->thumb) _image_thumb_set(sd);
|
|
else if (sd->file) _image_file_set(sd);
|
|
}
|
|
|
|
static Eina_Bool
|
|
_cb_settle_timer(void *data)
|
|
{ // when the image settles and stops being resized after a bit...
|
|
Smart_Data *sd = data;
|
|
|
|
sd->settle_timer = NULL;
|
|
_image_update(sd);
|
|
return EINA_FALSE;
|
|
}
|
|
|
|
static int
|
|
_frame_num_get(Smart_Data *sd)
|
|
{
|
|
int fr, fr2;
|
|
|
|
// ping pong - first and last frame only appear once at each end
|
|
if (sd->loop_type == EVAS_IMAGE_ANIMATED_HINT_PINGPONG)
|
|
{
|
|
fr = sd->frame % ((sd->frame_count * 2) - 2);
|
|
fr2 = sd->frame % sd->frame_count + 1;
|
|
if (fr >= sd->frame_count) fr = sd->frame_count - 1 - fr2;
|
|
}
|
|
// loop
|
|
else fr = sd->frame % sd->frame_count;
|
|
return fr;
|
|
}
|
|
|
|
static Eina_Bool
|
|
_cb_anim_timer(void *data)
|
|
{
|
|
Smart_Data *sd = data;
|
|
int fr;
|
|
|
|
sd->anim_timer = NULL;
|
|
sd->frame++;
|
|
fr = _frame_num_get(sd);
|
|
printf("T: %1.3f %i / %i\n", ecore_time_get(), fr, sd->frame_count);
|
|
evas_object_image_animated_frame_set(sd->o_image, fr);
|
|
_handle_frame(sd);
|
|
return EINA_FALSE;
|
|
}
|
|
|
|
static void
|
|
_handle_frame(Smart_Data *sd)
|
|
{
|
|
int fr;
|
|
double t;
|
|
|
|
fr = _frame_num_get(sd);
|
|
t = evas_object_image_animated_frame_duration_get(sd->o_image, fr, 0);
|
|
if (sd->anim_timer) ecore_timer_del(sd->anim_timer);
|
|
sd->anim_timer = ecore_timer_add(t, _cb_anim_timer, sd);
|
|
}
|
|
|
|
static void
|
|
_cb_image_preload(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
|
|
{ // whenb an image that was being loaded in the background has now finished
|
|
Smart_Data *sd = data;
|
|
|
|
if (sd->o_image) evas_object_del(sd->o_image);
|
|
sd->o_image = sd->o_image2;
|
|
if (!sd->o_image2) return;
|
|
sd->o_image2 = NULL;
|
|
evas_object_image_size_get(sd->o_image, &(sd->orig_w), &(sd->orig_h));
|
|
sd->alpha = evas_object_image_alpha_get(sd->o_image);
|
|
evas_object_show(sd->o_image);
|
|
if (sd->newfile)
|
|
{
|
|
sd->newfile = EINA_FALSE;
|
|
evas_object_smart_callback_call(sd->o_smart, "loaded", NULL);
|
|
}
|
|
sd->animated = evas_object_image_animated_get(sd->o_image);
|
|
if (sd->animated)
|
|
{
|
|
sd->loop_type = evas_object_image_animated_loop_type_get(sd->o_image);
|
|
sd->frame_count = evas_object_image_animated_frame_count_get(sd->o_image);
|
|
if (sd->frame_count < 3) sd->loop_type = EVAS_IMAGE_ANIMATED_HINT_LOOP;
|
|
else if (sd->frame_count < 2) sd->animated = EINA_FALSE;
|
|
if (sd->animated) _handle_frame(sd);
|
|
}
|
|
}
|
|
|
|
// gui code
|
|
static void
|
|
_smart_add(Evas_Object *obj)
|
|
{ // create a new efm icon
|
|
Smart_Data *sd;
|
|
|
|
sd = calloc(1, sizeof(Smart_Data));
|
|
if (!sd) return;
|
|
evas_object_smart_data_set(obj, sd);
|
|
|
|
_sc_parent.add(obj);
|
|
|
|
sd->o_smart = obj;
|
|
}
|
|
|
|
static void
|
|
_smart_del(Evas_Object *obj)
|
|
{ // delete/free efm view
|
|
ENTRY;
|
|
|
|
if (sd->o_image)
|
|
{
|
|
evas_object_del(sd->o_image);
|
|
sd->o_image = NULL;
|
|
}
|
|
if (sd->o_image2)
|
|
{
|
|
evas_object_del(sd->o_image2);
|
|
sd->o_image2 = NULL;
|
|
}
|
|
if (sd->o_video)
|
|
{
|
|
evas_object_del(sd->o_video);
|
|
sd->o_video = NULL;
|
|
}
|
|
if (sd->settle_timer)
|
|
{
|
|
ecore_timer_del(sd->settle_timer);
|
|
sd->settle_timer = NULL;
|
|
}
|
|
if (sd->wakeup)
|
|
{
|
|
ecore_job_del(sd->wakeup);
|
|
sd->wakeup = NULL;
|
|
}
|
|
if (sd->anim_timer)
|
|
{
|
|
ecore_timer_del(sd->anim_timer);
|
|
sd->anim_timer = NULL;
|
|
}
|
|
eina_stringshare_replace(&(sd->thumb), NULL);
|
|
eina_stringshare_replace(&(sd->file), NULL);
|
|
eina_stringshare_replace(&(sd->video), NULL);
|
|
|
|
_sc_parent.del(obj);
|
|
evas_object_smart_data_set(obj, NULL);
|
|
}
|
|
|
|
static void
|
|
_smart_move(Evas_Object *obj, Evas_Coord x, Evas_Coord y)
|
|
{ // efm icon object moved
|
|
ENTRY;
|
|
|
|
if ((sd->geom.x == x) && (sd->geom.y == y)) return;
|
|
sd->geom.x = x;
|
|
sd->geom.y = y;
|
|
evas_object_smart_changed(obj);
|
|
}
|
|
|
|
static void
|
|
_smart_resize(Evas_Object *obj, Evas_Coord w, Evas_Coord h)
|
|
{ // efm icon object resized
|
|
ENTRY;
|
|
|
|
if ((sd->geom.w == w) && (sd->geom.h == h)) return;
|
|
sd->geom.w = w;
|
|
sd->geom.h = h;
|
|
_image_resized(sd);
|
|
_image_update(sd);
|
|
evas_object_smart_changed(obj);
|
|
}
|
|
|
|
static void
|
|
_smart_calculate(Evas_Object *obj)
|
|
{ // recalce position/size
|
|
ENTRY;
|
|
|
|
if (sd->o_image)
|
|
evas_object_geometry_set(sd->o_image,
|
|
sd->geom.x, sd->geom.y,
|
|
sd->geom.w, sd->geom.h);
|
|
if (sd->o_image2)
|
|
evas_object_geometry_set(sd->o_image2,
|
|
sd->geom.x, sd->geom.y,
|
|
sd->geom.w, sd->geom.h);
|
|
if (sd->o_video)
|
|
evas_object_geometry_set(sd->o_video,
|
|
sd->geom.x, sd->geom.y,
|
|
sd->geom.w, sd->geom.h);
|
|
_image_update(sd);
|
|
}
|
|
|
|
Evas_Object *
|
|
efm_icon_add(Evas_Object *parent)
|
|
{ // add new icon object
|
|
if (!_smart)
|
|
{
|
|
evas_object_smart_clipped_smart_set(&_sc_parent);
|
|
_sc = _sc_parent;
|
|
_sc.name = "efm_icon";
|
|
_sc.version = EVAS_SMART_CLASS_VERSION;
|
|
_sc.add = _smart_add;
|
|
_sc.del = _smart_del;
|
|
_sc.resize = _smart_resize;
|
|
_sc.move = _smart_move;
|
|
_sc.calculate = _smart_calculate;
|
|
};
|
|
if (!_smart) _smart = evas_smart_class_new(&_sc);
|
|
return evas_object_smart_add(evas_object_evas_get(parent), _smart);
|
|
}
|
|
|
|
void
|
|
efm_icon_file_set(Evas_Object *obj, const char *file)
|
|
{ // set a regular file as the icon
|
|
ENTRY;
|
|
|
|
if ((sd->file) && (file) && (!strcmp(sd->file, file))) return;
|
|
if ((!sd->file) && (!file)) return;
|
|
eina_stringshare_replace(&(sd->thumb), NULL);
|
|
eina_stringshare_replace(&(sd->file), file);
|
|
eina_stringshare_replace(&(sd->video), NULL);
|
|
sd->svg = EINA_FALSE;
|
|
if ((sd->file) &&
|
|
((eina_fnmatch("*.svg", sd->file, EINA_FNMATCH_CASEFOLD) ||
|
|
eina_fnmatch("*.svgz", sd->file, EINA_FNMATCH_CASEFOLD) ||
|
|
eina_fnmatch("*.svg.gz", sd->file, EINA_FNMATCH_CASEFOLD))))
|
|
sd->svg = EINA_TRUE;
|
|
sd->load_size = -1;
|
|
sd->newfile = EINA_TRUE;
|
|
sd->mono_thumb = EINA_FALSE;
|
|
sd->frame = 0;
|
|
if (sd->anim_timer)
|
|
{
|
|
ecore_timer_del(sd->anim_timer);
|
|
sd->anim_timer = NULL;
|
|
}
|
|
if (sd->settle_timer)
|
|
{ // thumbnails dont need settle timers like svg's might
|
|
ecore_timer_del(sd->settle_timer);
|
|
sd->settle_timer = NULL;
|
|
}
|
|
_image_resized(sd);
|
|
_image_file_set(sd);
|
|
}
|
|
|
|
void
|
|
efm_icon_thumb_set(Evas_Object *obj, const char *thumb)
|
|
{ // specifically add generated thumb file
|
|
ENTRY;
|
|
|
|
if ((sd->thumb) && (thumb) && (!strcmp(sd->thumb, thumb))) return;
|
|
if ((!sd->thumb) && (!thumb)) return;
|
|
eina_stringshare_replace(&(sd->file), NULL);
|
|
eina_stringshare_replace(&(sd->thumb), thumb);
|
|
eina_stringshare_replace(&(sd->video), NULL);
|
|
sd->svg = EINA_FALSE;
|
|
sd->load_size = -1;
|
|
sd->newfile = EINA_TRUE;
|
|
sd->mono_thumb = EINA_FALSE;
|
|
sd->frame = 0;
|
|
if (sd->anim_timer)
|
|
{
|
|
ecore_timer_del(sd->anim_timer);
|
|
sd->anim_timer = NULL;
|
|
}
|
|
if (sd->settle_timer)
|
|
{ // thumbnails dont need settle timers like svg's might
|
|
ecore_timer_del(sd->settle_timer);
|
|
sd->settle_timer = NULL;
|
|
}
|
|
_image_thumb_set(sd);
|
|
}
|
|
|
|
void
|
|
efm_icon_video_set(Evas_Object *obj, const char *video)
|
|
{ // specifically load file as a video (or audio) and not as a still image
|
|
ENTRY;
|
|
|
|
if ((sd->video) && (video) && (!strcmp(sd->video, video))) return;
|
|
if ((!sd->video) && (!video)) return;
|
|
eina_stringshare_replace(&(sd->file), NULL);
|
|
eina_stringshare_replace(&(sd->thumb), NULL);
|
|
eina_stringshare_replace(&(sd->video), video);
|
|
sd->svg = EINA_FALSE;
|
|
sd->load_size = -1;
|
|
sd->newfile = EINA_TRUE;
|
|
sd->mono_thumb = EINA_FALSE;
|
|
sd->frame = 0;
|
|
sd->video_ratio = 0.0;
|
|
if (sd->anim_timer)
|
|
{
|
|
ecore_timer_del(sd->anim_timer);
|
|
sd->anim_timer = NULL;
|
|
}
|
|
if (sd->settle_timer)
|
|
{ // thumbnails dont need settle timers like svg's might
|
|
ecore_timer_del(sd->settle_timer);
|
|
sd->settle_timer = NULL;
|
|
}
|
|
_image_resized(sd);
|
|
_image_video_set(sd);
|
|
}
|
|
|
|
void
|
|
efm_icon_size_get(Evas_Object *obj, int *w, int *h)
|
|
{ // get image pixel size
|
|
ENTRY;
|
|
|
|
if ((sd->o_video) && (sd->video_ratio > 0.0))
|
|
{
|
|
int vid_w, vid_h;
|
|
|
|
vid_w = ((double)sd->orig_h + 0.5) * sd->video_ratio;
|
|
vid_h = sd->orig_h;
|
|
if (w) *w = vid_w;
|
|
if (h) *h = vid_h;
|
|
}
|
|
else
|
|
{
|
|
if (w) *w = sd->orig_w;
|
|
if (h) *h = sd->orig_h;
|
|
}
|
|
}
|
|
|
|
Eina_Bool
|
|
efm_icon_alpha_get(Evas_Object *obj)
|
|
{ // get image alpha flag
|
|
ENTRY EINA_FALSE;
|
|
|
|
return sd->alpha;
|
|
}
|
|
|
|
Eina_Bool
|
|
efm_icon_mono_get(Evas_Object *obj)
|
|
{ // get thumb mono flag
|
|
ENTRY EINA_FALSE;
|
|
|
|
return sd->mono_thumb;
|
|
}
|