* Fix elm to use key not keyname (otherwise xmodmap and friends
don't work).
+
+2013-08-09 Cedric Bail
+
+ * Add support for URL in Elm_Image.
* Move cursor when mouse moves with longpress.
* Show magnifier when selection handlers are pressed or moved.
* Change the method to calculate a distance which be scrolled from linear to sine curve.
+ * Add support for URL in Elm_Image.
Fixes:
* Now elm_datetime_field_limit_set() can set year limits wihtout problems.
void test_popup(void *data, Evas_Object *obj, void *event_info);
void test_dayselector(void *data, Evas_Object *obj, void *event_info);
void test_image(void *data, Evas_Object *obj, void *event_info);
+void test_remote_image(void *data, Evas_Object *obj, void *event_info);
void test_external_button(void *data, Evas_Object *obj, void *event_info);
void test_external_slider(void *data, Evas_Object *obj, void *event_info);
void test_external_scroller(void *data, Evas_Object *obj, void *event_info);
ADD_TEST(NULL, "Images", "Photo", test_photo);
ADD_TEST(NULL, "Images", "Thumb", test_thumb);
ADD_TEST(NULL, "Images", "Image", test_image);
+ ADD_TEST(NULL, "Images", "Image Remote", test_remote_image);
ADD_TEST(NULL, "Images", "Slideshow", test_slideshow);
#ifdef HAVE_EMOTION
ADD_TEST(NULL, "Images", "Video", test_video);
evas_object_resize(win, 320, 480);
evas_object_show(win);
}
+
+void
+test_remote_image(void *data __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
+{
+ Evas_Object *win, *box, *im, *rd, *rdg = NULL;
+ int i;
+
+ win = elm_win_util_standard_add("image test", "Image Test");
+ elm_win_autodel_set(win, EINA_TRUE);
+
+ box = elm_box_add(win);
+ evas_object_size_hint_weight_set(box, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+ elm_win_resize_object_add(win, box);
+ evas_object_show(box);
+
+ im = elm_image_add(win);
+ elm_image_file_set(im, "http://31.media.tumblr.com/29f1ecd4f98aaff73fb21f479b450d4c/tumblr_mqsxdciQmB1rrju89o1_1280.jpg", NULL);
+ elm_image_resizable_set(im, EINA_TRUE, EINA_TRUE);
+ evas_object_size_hint_weight_set(im, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+ evas_object_size_hint_align_set(im, EVAS_HINT_FILL, EVAS_HINT_FILL);
+
+ elm_box_pack_end(box, im);
+ evas_object_show(im);
+
+ evas_object_data_set(win, "im", im);
+
+ for (i = 0; images_orient[i].name; ++i)
+ {
+ rd = elm_radio_add(win);
+ evas_object_size_hint_align_set(rd, EVAS_HINT_FILL, EVAS_HINT_FILL);
+ evas_object_size_hint_weight_set(rd, EVAS_HINT_EXPAND, 0.0);
+ elm_radio_state_value_set(rd, images_orient[i].orient);
+ elm_object_text_set(rd, images_orient[i].name);
+ elm_box_pack_end(box, rd);
+ evas_object_show(rd);
+ evas_object_smart_callback_add(rd, "changed", my_im_ch, win);
+ if (!rdg)
+ {
+ rdg = rd;
+ evas_object_data_set(win, "rdg", rdg);
+ }
+ else
+ {
+ elm_radio_group_add(rd, rdg);
+ }
+ }
+
+ evas_object_resize(win, 320, 480);
+ evas_object_show(win);
+}
#endif
elm_toolbar.c \
elm_transit.c \
elm_util.c \
+elm_url.c \
elm_video.c \
elm_web.c \
elm_web2.c \
static const char SIG_DND[] = "drop";
static const char SIG_CLICKED[] = "clicked";
+static const char SIG_DOWNLOAD_START[] = "download,start";
+static const char SIG_DOWNLOAD_PROGRESS[] = "download,progress";
+static const char SIG_DOWNLOAD_DONE[] = "download,done";
+static const char SIG_DOWNLOAD_ERROR[] = "download,error";
static const Evas_Smart_Cb_Description _smart_callbacks[] = {
{SIG_DND, ""},
{SIG_CLICKED, ""},
+ {SIG_DOWNLOAD_START, ""},
+ {SIG_DOWNLOAD_PROGRESS, ""},
+ {SIG_DOWNLOAD_DONE, ""},
+ {SIG_DOWNLOAD_ERROR, ""},
{NULL, NULL}
};
static Eina_Bool
_elm_image_edje_file_set(Evas_Object *obj,
const char *file,
+ Eina_File *f,
const char *group)
{
Evas_Object *pclip;
}
sd->edje = EINA_TRUE;
- if (!edje_object_file_set(sd->img, file, group))
+ if (f)
+ {
+ if (!edje_object_mmap_set(sd->img, f, group))
+ {
+ ERR("failed to set edje file '%s', group '%s': %s", file, group,
+ edje_load_error_str(edje_object_load_error_get(sd->img)));
+ return EINA_FALSE;
+ }
+ }
+ else if (!edje_object_file_set(sd->img, file, group))
{
ERR("failed to set edje file '%s', group '%s': %s", file, group,
edje_load_error_str(edje_object_load_error_get(sd->img)));
if (sd->anim_timer) ecore_timer_del(sd->anim_timer);
if (sd->img) evas_object_del(sd->img);
if (sd->prev_img) evas_object_del(sd->prev_img);
+ if (sd->remote) elm_url_cancel(sd->remote);
+ free(sd->remote_data);
+ eina_stringshare_del(sd->key);
eo_do_super(obj, MY_CLASS, evas_obj_smart_del());
}
}
static void
-_elm_image_smart_file_set(Eo *obj, void *_pd, va_list *list)
+_elm_image_smart_internal_file_set(Eo *obj, Elm_Image_Smart_Data *sd,
+ const char *file, Eina_File *f, const char *key, Eina_Bool *ret)
{
- const char *file = va_arg(*list, const char *);
- const char *key = va_arg(*list, const char *);
- Eina_Bool *ret = va_arg(*list, Eina_Bool *);
-
Evas_Coord w, h;
- Elm_Image_Smart_Data *sd = _pd;
-
if (eina_str_has_extension(file, ".edj"))
{
- Eina_Bool int_ret = _elm_image_edje_file_set(obj, file, key);
+ Eina_Bool int_ret = _elm_image_edje_file_set(obj, file, f, key);
if (ret) *ret = int_ret;
return;
}
_elm_image_file_set_do(obj);
- evas_object_image_file_set(sd->img, file, key);
+ if (f)
+ evas_object_image_mmap_set(sd->img, f, key);
+ else
+ evas_object_image_file_set(sd->img, file, key);
sd->preloading = EINA_TRUE;
evas_object_hide(sd->img);
_elm_image_internal_sizing_eval(obj, sd);
if (ret) *ret = EINA_TRUE;
+}
+
+static void
+_elm_image_smart_download_done(void *data, Elm_Url *url EINA_UNUSED, Eina_Binbuf *download)
+{
+ Eo *obj = data;
+ Elm_Image_Smart_Data *sd = eo_data_scope_get(obj, MY_CLASS);
+ Eina_File *f;
+ size_t length;
+ Eina_Bool ret = EINA_FALSE;
+
+ if (sd->remote_data) free(sd->remote_data);
+ length = eina_binbuf_length_get(download);
+ sd->remote_data = eina_binbuf_string_steal(download);
+ f = eina_file_virtualize(elm_url_get(url),
+ sd->remote_data, length,
+ EINA_FALSE);
+ _elm_image_smart_internal_file_set(obj, sd, elm_url_get(url), f, sd->key, &ret);
+ eina_file_close(f);
+
+ if (!ret)
+ {
+ Elm_Image_Error err = { 0, EINA_TRUE };
+
+ free(sd->remote_data);
+ sd->remote_data = NULL;
+ evas_object_smart_callback_call(obj, SIG_DOWNLOAD_ERROR, &err);
+ }
+ else
+ {
+ evas_object_smart_callback_call(obj, SIG_DOWNLOAD_DONE, NULL);
+ }
+
+ sd->remote = NULL;
+ eina_stringshare_del(sd->key);
+ sd->key = NULL;
+}
+
+static void
+_elm_image_smart_download_cancel(void *data, Elm_Url *url EINA_UNUSED, int error)
+{
+ Eo *obj = data;
+ Elm_Image_Smart_Data *sd = eo_data_scope_get(obj, MY_CLASS);
+ Elm_Image_Error err = { error, EINA_FALSE };
+
+ evas_object_smart_callback_call(obj, SIG_DOWNLOAD_ERROR, &err);
+
+ sd->remote = NULL;
+ eina_stringshare_del(sd->key);
+ sd->key = NULL;
+}
+
+static void
+_elm_image_smart_download_progress(void *data, Elm_Url *url EINA_UNUSED, double now, double total)
+{
+ Eo *obj = data;
+ Elm_Image_Progress progress;
+
+ progress.now = now;
+ progress.total = total;
+ evas_object_smart_callback_call(obj, SIG_DOWNLOAD_PROGRESS, &progress);
+}
+
+static const char *remote_uri[] = {
+ "http://", "https://", "ftp://"
+};
+
+static void
+_elm_image_smart_file_set(Eo *obj, void *_pd, va_list *list)
+{
+ const char *file = va_arg(*list, const char *);
+ const char *key = va_arg(*list, const char *);
+ Eina_Bool *ret = va_arg(*list, Eina_Bool *);
+
+ Elm_Image_Smart_Data *sd = _pd;
+
+ unsigned int i;
+
+ if (sd->remote) elm_url_cancel(sd->remote);
+ sd->remote = NULL;
+
+ for (i = 0; i < sizeof (remote_uri) / sizeof (remote_uri[0]); ++i)
+ if (strncmp(remote_uri[i], file, strlen(remote_uri[i])) == 0)
+ {
+ // Found a remote target !
+ evas_object_hide(sd->img);
+ sd->remote = elm_url_download(file,
+ _elm_image_smart_download_done,
+ _elm_image_smart_download_cancel,
+ _elm_image_smart_download_progress,
+ obj);
+ if (sd->remote)
+ {
+ evas_object_smart_callback_call(obj, SIG_DOWNLOAD_START, NULL);
+ eina_stringshare_replace(&sd->key, key);
+ if (ret) *ret = EINA_TRUE;
+ return ;
+ }
+ break;
+ }
+
+ _elm_image_smart_internal_file_set(obj, sd, file, NULL, key, ret);
}
EAPI void
ELM_IMAGE_FLIP_TRANSVERSE = 7 /**< flip the image along the y = x line (top-left to bottom-right) */
} Elm_Image_Orient;
+/**
+ * Structure associated with smart callback 'download,progress'.
+ * @since 1.8
+ */
+typedef struct _Elm_Image_Progress Elm_Image_Progress;
+
+struct _Elm_Image_Progress
+{
+ double now;
+ double total;
+};
+
+
+/**
+ * Structre associated with smart callback 'download,error'
+ * @since 1.8
+ */
+typedef struct _Elm_Image_Error Elm_Image_Error;
+struct _Elm_Image_Error
+{
+ int status;
+ Eina_Bool open_error;
+};
Edje_Signal_Cb func_cb);
/* end of DEPRECATED */
+
+/* Elm helper to download content */
+typedef struct _Elm_Url Elm_Url;
+
+typedef void (*Elm_Url_Done)(void *data, Elm_Url *url, Eina_Binbuf *download);
+typedef void (*Elm_Url_Cancel)(void *data, Elm_Url *url, int error);
+typedef void (*Elm_Url_Progress)(void *data, Elm_Url *url, double now, double total);
+
+Elm_Url *elm_url_download(const char *url, Elm_Url_Done done_cb, Elm_Url_Cancel cancel_cb, Elm_Url_Progress progress_cb, const void *data);
+void elm_url_cancel(Elm_Url *r);
+const char *elm_url_get(Elm_Url *r);
+
extern char *_elm_appname;
extern Elm_Config *_elm_config;
extern const char *_elm_data_dir;
--- /dev/null
+#ifdef HAVE_CONFIG_H
+# include "elementary_config.h"
+#endif
+
+#include <Elementary.h>
+#include "elm_priv.h"
+
+struct _Elm_Url
+{
+ const char *url;
+
+ struct {
+ Elm_Url_Done done;
+ Elm_Url_Cancel cancel;
+ Elm_Url_Progress progress;
+ } cb;
+
+ const void *data;
+
+ Ecore_Con_Url *target;
+ Eina_Binbuf *download;
+
+ struct {
+ Ecore_Event_Handler *progress;
+ Ecore_Event_Handler *done;
+ Ecore_Event_Handler *data;
+ } handler;
+};
+
+static void
+_elm_url_free(Elm_Url *r)
+{
+ ecore_con_url_free(r->target);
+ eina_binbuf_free(r->download);
+ ecore_event_handler_del(r->handler.progress);
+ ecore_event_handler_del(r->handler.done);
+ ecore_event_handler_del(r->handler.data);
+ eina_stringshare_del(r->url);
+ free(r);
+}
+
+static Eina_Bool
+_elm_url_progress(void *data, int type EINA_UNUSED, void *event)
+{
+ Ecore_Con_Event_Url_Progress *url_progress = event;
+ Elm_Url *r = data;
+
+ if (url_progress->url_con != r->target) return EINA_TRUE;
+
+ r->cb.progress((void*) r->data, r, url_progress->down.now, url_progress->down.total);
+
+ return EINA_TRUE;
+}
+
+static Eina_Bool
+_elm_url_done(void *data, int type EINA_UNUSED, void *event)
+{
+ Ecore_Con_Event_Url_Complete *url_complete = event;
+ Elm_Url *r = data;
+
+ if (url_complete->url_con != r->target) return EINA_TRUE;
+
+ if (url_complete->status == 200)
+ {
+ r->cb.done((void*) r->data, r, r->download);
+ }
+ else
+ {
+ r->cb.cancel((void*) r->data, r, url_complete->status);
+ }
+
+ _elm_url_free(r);
+
+ return EINA_TRUE;
+}
+
+static Eina_Bool
+_elm_url_data(void *data, int type EINA_UNUSED, void *event)
+{
+ Ecore_Con_Event_Url_Data *url_data = event;
+ Elm_Url *r = data;
+
+ if (url_data->url_con != r->target) return EINA_TRUE;
+
+ eina_binbuf_append_length(r->download, url_data->data, url_data->size);
+
+ return EINA_TRUE;
+}
+
+Elm_Url *
+elm_url_download(const char *url, Elm_Url_Done done_cb, Elm_Url_Cancel cancel_cb, Elm_Url_Progress progress_cb, const void *data)
+{
+ Ecore_Con_Url *target;
+ Elm_Url *r;
+
+ ecore_con_url_init();
+
+ target = ecore_con_url_new(url);
+ if (!target) goto on_error;
+
+ if (getenv("http_proxy")) ecore_con_url_proxy_set(target, getenv("http_proxy"));
+ if (getenv("https_proxy")) ecore_con_url_proxy_set(target, getenv("https_proxy"));
+ if (getenv("ftp_proxy")) ecore_con_url_proxy_set(target, getenv("ftp_proxy"));
+
+ r = malloc(sizeof (Elm_Url));
+ if (!r) goto on_error;
+
+ r->url = eina_stringshare_add(url);
+ r->cb.done = done_cb;
+ r->cb.cancel = cancel_cb;
+ r->cb.progress = progress_cb;
+ r->data = data;
+
+ r->download = eina_binbuf_new();
+ r->target = target;
+ r->handler.progress = ecore_event_handler_add(ECORE_CON_EVENT_URL_PROGRESS, _elm_url_progress, r);
+ r->handler.done = ecore_event_handler_add(ECORE_CON_EVENT_URL_COMPLETE, _elm_url_done, r);
+ r->handler.data = ecore_event_handler_add(ECORE_CON_EVENT_URL_DATA, _elm_url_data, r);
+
+ if (!ecore_con_url_get(r->target))
+ {
+ _elm_url_free(r);
+ cancel_cb((void*) data, NULL, -1);
+ return NULL;
+ }
+
+ return r;
+
+ on_error:
+ ecore_con_url_shutdown();
+
+ cancel_cb((void*) data, NULL, -1);
+ return NULL;
+}
+
+void
+elm_url_cancel(Elm_Url *r)
+{
+ r->cb.cancel((void*) r->data, r, 0);
+ _elm_url_free(r);
+}
+
+const char *
+elm_url_get(Elm_Url *r)
+{
+ return r->url;
+}
Evas_Object *prev_img;
Ecore_Timer *anim_timer;
+ Elm_Url *remote;
+ const char *key;
+ void *remote_data;
+
double scale;
double frame_duration;