diff --git a/legacy/elementary/src/bin/test.c b/legacy/elementary/src/bin/test.c index 8e0fddff43..0a3f08b98e 100644 --- a/legacy/elementary/src/bin/test.c +++ b/legacy/elementary/src/bin/test.c @@ -136,6 +136,7 @@ void test_index(void *data, Evas_Object *obj, void *event_info); void test_index2(void *data, Evas_Object *obj, void *event_info); void test_index_horizontal(void *data, Evas_Object *obj, void *event_info); void test_photocam(void *data, Evas_Object *obj, void *event_info); +void test_photocam_remote(void *data, Evas_Object *obj, void *event_info); void test_photo(void *data, Evas_Object *obj, void *event_info); void test_prefs(void *data, Evas_Object *obj, void *event_info); void test_thumb(void *data, Evas_Object *obj, void *event_info); @@ -526,6 +527,7 @@ add_tests: ADD_TEST(NULL, "Images", "Icon Transparent", test_icon_transparent); ADD_TEST(NULL, "Images", "Icon Animation", test_icon_animated); ADD_TEST(NULL, "Images", "Photocam", test_photocam); + ADD_TEST(NULL, "Images", "Photocam Remote", test_photocam_remote); ADD_TEST(NULL, "Images", "Photo", test_photo); ADD_TEST(NULL, "Images", "Thumb", test_thumb); ADD_TEST(NULL, "Images", "Image", test_image); diff --git a/legacy/elementary/src/bin/test_photocam.c b/legacy/elementary/src/bin/test_photocam.c index 75431eee15..9aa470c603 100644 --- a/legacy/elementary/src/bin/test_photocam.c +++ b/legacy/elementary/src/bin/test_photocam.c @@ -370,4 +370,141 @@ test_photocam(void *data __UNUSED__, Evas_Object *obj __UNUSED__, void *event_in evas_object_resize(win, 800, 800); evas_object_show(win); } + +void +test_photocam_remote(void *data __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__) +{ + Evas_Object *win, *ph, *tb2, *bt, *box; + // these were just testing - use the "select photo" browser to select one + static const char *url = "http://eoimages.gsfc.nasa.gov/images/imagerecords/73000/73751/world.topo.bathy.200407.3x21600x10800.jpg"; + + win = elm_win_util_standard_add("photocam", "PhotoCam"); + elm_win_autodel_set(win, EINA_TRUE); + + ph = elm_photocam_add(win); + evas_object_size_hint_weight_set(ph, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + elm_win_resize_object_add(win, ph); + evas_object_data_set(ph, "window", win); + + rect = evas_object_rectangle_add(evas_object_evas_get(win)); + evas_object_color_set(rect, 0, 0, 0, 0); + evas_object_repeat_events_set(rect,1); + evas_object_show(rect); + evas_object_event_callback_add(rect, EVAS_CALLBACK_MOUSE_WHEEL, _photocam_mouse_wheel_cb, ph); + evas_object_raise(rect); + + evas_object_event_callback_add(ph, EVAS_CALLBACK_RESIZE, _photocam_move_resize_cb, ph); + evas_object_event_callback_add(ph, EVAS_CALLBACK_MOVE, _photocam_move_resize_cb, ph); + + evas_object_smart_callback_add(ph, "clicked", my_ph_clicked, win); + evas_object_smart_callback_add(ph, "press", my_ph_press, win); + evas_object_smart_callback_add(ph, "longpressed", my_ph_longpressed, win); + evas_object_smart_callback_add(ph, "clicked,double", my_ph_clicked_double, win); + evas_object_smart_callback_add(ph, "load", my_ph_load, win); + evas_object_smart_callback_add(ph, "loaded", my_ph_loaded, win); + evas_object_smart_callback_add(ph, "load,details", my_ph_load_details, win); + evas_object_smart_callback_add(ph, "loaded,details", my_ph_loaded_details, win); + evas_object_smart_callback_add(ph, "zoom,start", my_ph_zoom_start, win); + evas_object_smart_callback_add(ph, "zoom,stop", my_ph_zoom_stop, win); + evas_object_smart_callback_add(ph, "zoom,change", my_ph_zoom_change, win); + evas_object_smart_callback_add(ph, "scroll,anim,start", my_ph_anim_start, win); + evas_object_smart_callback_add(ph, "scroll,anim,stop", my_ph_anim_stop, win); + evas_object_smart_callback_add(ph, "scroll,drag,start", my_ph_drag_start, win); + evas_object_smart_callback_add(ph, "scroll,drag,stop", my_ph_drag_stop, win); + evas_object_smart_callback_add(ph, "scroll", my_ph_scroll, win); + + elm_photocam_file_set(ph, url); + + evas_object_show(ph); + + tb2 = elm_table_add(win); + evas_object_size_hint_weight_set(tb2, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + elm_win_resize_object_add(win, tb2); + + bt = elm_button_add(win); + elm_object_text_set(bt, "Z -"); + evas_object_smart_callback_add(bt, "clicked", my_bt_zoom_out, ph); + evas_object_size_hint_weight_set(bt, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + evas_object_size_hint_align_set(bt, 0.1, 0.1); + elm_table_pack(tb2, bt, 0, 0, 1, 1); + evas_object_show(bt); + + bt = elm_button_add(win); + elm_object_text_set(bt, "Z +"); + evas_object_smart_callback_add(bt, "clicked", my_bt_zoom_in, ph); + evas_object_size_hint_weight_set(bt, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + evas_object_size_hint_align_set(bt, 0.9, 0.1); + elm_table_pack(tb2, bt, 2, 0, 1, 1); + evas_object_show(bt); + + bt = elm_button_add(win); + elm_object_text_set(bt, "Show 30,50 500x300"); + evas_object_smart_callback_add(bt, "clicked", my_bt_show_reg, ph); + evas_object_size_hint_weight_set(bt, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + evas_object_size_hint_align_set(bt, 0.1, 0.5); + elm_table_pack(tb2, bt, 0, 1, 1, 1); + evas_object_show(bt); + + bt = elm_button_add(win); + elm_object_text_set(bt, "Bring 800,300 500x300"); + evas_object_smart_callback_add(bt, "clicked", my_bt_bring_reg, ph); + evas_object_size_hint_weight_set(bt, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + evas_object_size_hint_align_set(bt, 0.9, 0.5); + elm_table_pack(tb2, bt, 2, 1, 1, 1); + evas_object_show(bt); + + box = elm_box_add(win); + elm_box_horizontal_set(box, EINA_TRUE); + evas_object_size_hint_weight_set(box, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + evas_object_size_hint_align_set(box, 0.0, 0.9); + elm_table_pack(tb2, box, 0, 2, 1, 1); + evas_object_show(box); + + bt = elm_button_add(win); + elm_object_text_set(bt, "Pause On/Off"); + evas_object_smart_callback_add(bt, "clicked", my_bt_pause, ph); + evas_object_size_hint_weight_set(bt, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + elm_box_pack_end(box, bt); + evas_object_show(bt); + + bt = elm_button_add(win); + elm_object_text_set(bt, "Gesture On/Off"); + evas_object_smart_callback_add(bt, "clicked", my_bt_gesture, ph); + evas_object_size_hint_weight_set(bt, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + elm_box_pack_end(box, bt); + evas_object_show(bt); + + box = elm_box_add(win); + elm_box_horizontal_set(box, EINA_TRUE); + evas_object_size_hint_weight_set(box, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + evas_object_size_hint_align_set(box, 0.9, 0.9); + elm_table_pack(tb2, box, 2, 2, 1, 1); + + bt = elm_button_add(win); + elm_object_text_set(bt, "Fit"); + evas_object_smart_callback_add(bt, "clicked", my_bt_zoom_fit, ph); + evas_object_size_hint_weight_set(bt, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + elm_box_pack_end(box, bt); + evas_object_show(bt); + + bt = elm_button_add(win); + elm_object_text_set(bt, "Fit_In"); + evas_object_smart_callback_add(bt, "clicked", my_bt_zoom_fit_in, ph); + evas_object_size_hint_weight_set(bt, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + elm_box_pack_end(box, bt); + evas_object_show(bt); + + bt = elm_button_add(win); + elm_object_text_set(bt, "Fill"); + evas_object_smart_callback_add(bt, "clicked", my_bt_zoom_fill, ph); + evas_object_size_hint_weight_set(bt, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + elm_box_pack_end(box, bt); + evas_object_show(bt); + + evas_object_show(box); + evas_object_show(tb2); + + evas_object_resize(win, 800, 800); + evas_object_show(win); +} #endif diff --git a/legacy/elementary/src/lib/elm_photocam.c b/legacy/elementary/src/lib/elm_photocam.c index 9479d19bd6..05c6a66a59 100644 --- a/legacy/elementary/src/lib/elm_photocam.c +++ b/legacy/elementary/src/lib/elm_photocam.c @@ -45,6 +45,10 @@ static const char SIG_SCROLL_ANIM_START[] = "scroll,anim,start"; static const char SIG_SCROLL_ANIM_STOP[] = "scroll,anim,stop"; static const char SIG_SCROLL_DRAG_START[] = "scroll,drag,start"; static const char SIG_SCROLL_DRAG_STOP[] = "scroll,drag,stop"; +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_CLICKED, ""}, {SIG_PRESS, ""}, @@ -62,11 +66,24 @@ static const Evas_Smart_Cb_Description _smart_callbacks[] = { {SIG_SCROLL_ANIM_STOP, ""}, {SIG_SCROLL_DRAG_START, ""}, {SIG_SCROLL_DRAG_STOP, ""}, + {SIG_DOWNLOAD_START, ""}, + {SIG_DOWNLOAD_PROGRESS, ""}, + {SIG_DOWNLOAD_DONE, ""}, + {SIG_DOWNLOAD_ERROR, ""}, {"focused", ""}, /**< handled by elm_widget */ {"unfocused", ""}, /**< handled by elm_widget */ {NULL, NULL} }; +static inline void +_photocam_image_file_set(Evas_Object *obj, Elm_Photocam_Smart_Data *sd) +{ + if (sd->f) + evas_object_image_mmap_set(obj, sd->f, NULL); + else + evas_object_image_file_set(obj, sd->file, NULL); +} + static void _sizing_eval(Evas_Object *obj) { @@ -225,7 +242,7 @@ _grid_load(Evas_Object *obj, evas_object_image_load_region_set (g->grid[tn].img, g->grid[tn].src.x, g->grid[tn].src.y, g->grid[tn].src.w, g->grid[tn].src.h); - evas_object_image_file_set(g->grid[tn].img, sd->file, NULL); + _photocam_image_file_set(g->grid[tn].img, sd); evas_object_image_preload(g->grid[tn].img, 0); sd->preload_num++; if (sd->preload_num == 1) @@ -1393,6 +1410,9 @@ _elm_photocam_smart_del(Eo *obj, void *_pd, va_list *list EINA_UNUSED) evas_object_del(sd->pan_obj); sd->pan_obj = NULL; + if (sd->f) eina_file_close(sd->f); + free(sd->remote_data); + if (sd->remote) elm_url_cancel(sd->remote); if (sd->file) eina_stringshare_del(sd->file); if (sd->calc_job) ecore_job_del(sd->calc_job); if (sd->scr_timer) ecore_timer_del(sd->scr_timer); @@ -1471,31 +1491,24 @@ elm_photocam_file_set(Evas_Object *obj, } static void -_file_set(Eo *obj, void *_pd, va_list *list) +_internal_file_set(Eo *obj, Elm_Photocam_Smart_Data *sd, const char *file, Eina_File *f, Evas_Load_Error *ret) { + Elm_Widget_Smart_Data *wd = eo_data_scope_get(obj, ELM_OBJ_WIDGET_CLASS); + Evas_Load_Error err; int w, h; double tz; - Evas_Load_Error err; - - const char *file = va_arg(*list, const char *); - Evas_Load_Error *ret = va_arg(*list, Evas_Load_Error *); - if (ret) *ret = EVAS_LOAD_ERROR_NONE; - - Elm_Photocam_Smart_Data *sd = _pd; - Elm_Widget_Smart_Data *wd = eo_data_scope_get(obj, ELM_OBJ_WIDGET_CLASS); if (!eina_stringshare_replace(&sd->file, file)) return; - _grid_clear_all(obj); + sd->f = eina_file_dup(f); - evas_object_hide(sd->img); evas_object_image_smooth_scale_set(sd->img, (sd->no_smooth == 0)); evas_object_image_file_set(sd->img, NULL, NULL); evas_object_image_load_scale_down_set(sd->img, 0); - evas_object_image_file_set(sd->img, sd->file, NULL); + _photocam_image_file_set(sd->img, sd); err = evas_object_image_load_error_get(sd->img); if (err != EVAS_LOAD_ERROR_NONE) { - ERR("Things are going bad for '%s' (%p)", file, sd->img); + ERR("Things are going bad for '%s' (%p) : %i", file, sd->img, err); if (ret) *ret = err; return; } @@ -1506,17 +1519,9 @@ _file_set(Eo *obj, void *_pd, va_list *list) sd->size.imh = h; sd->size.w = sd->size.imw / sd->zoom; sd->size.h = sd->size.imh / sd->zoom; - ELM_SAFE_FREE(sd->g_layer_zoom.bounce.animator, ecore_animator_del); - if (sd->zoom_animator) - { - sd->no_smooth--; - if (sd->no_smooth == 0) _smooth_update(obj); - ecore_animator_del(sd->zoom_animator); - sd->zoom_animator = NULL; - } evas_object_image_file_set(sd->img, NULL, NULL); evas_object_image_load_scale_down_set(sd->img, 8); - evas_object_image_file_set(sd->img, sd->file, NULL); + _photocam_image_file_set(sd->img, sd); err = evas_object_image_load_error_get(sd->img); if (err != EVAS_LOAD_ERROR_NONE) { @@ -1528,7 +1533,6 @@ _file_set(Eo *obj, void *_pd, va_list *list) evas_object_image_preload(sd->img, 0); sd->main_load_pending = EINA_TRUE; - if (sd->calc_job) ecore_job_del(sd->calc_job); sd->calc_job = ecore_job_add(_calc_job_cb, obj); evas_object_smart_callback_call(obj, SIG_LOAD, NULL); sd->preload_num++; @@ -1546,6 +1550,118 @@ _file_set(Eo *obj, void *_pd, va_list *list) if (ret) *ret = evas_object_image_load_error_get(sd->img); } +static void +_elm_photocam_download_done(void *data, Elm_Url *url EINA_UNUSED, Eina_Binbuf *download) +{ + Eo *obj = data; + Elm_Photocam_Smart_Data *sd = eo_data_scope_get(obj, MY_CLASS); + Eina_File *f; + size_t length; + Evas_Load_Error ret = EVAS_LOAD_ERROR_NONE; + + 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); + _internal_file_set(obj, sd, elm_url_get(url), f, &ret); + eina_file_close(f); + + if (ret != EVAS_LOAD_ERROR_NONE) + { + Elm_Photocam_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; +} + +static void +_elm_photocam_download_cancel(void *data, Elm_Url *url EINA_UNUSED, int error) +{ + Eo *obj = data; + Elm_Photocam_Smart_Data *sd = eo_data_scope_get(obj, MY_CLASS); + Elm_Photocam_Error err = { error, EINA_FALSE }; + + evas_object_smart_callback_call(obj, SIG_DOWNLOAD_ERROR, &err); + + sd->remote = NULL; +} + + +static void +_elm_photocam_download_progress(void *data, Elm_Url *url EINA_UNUSED, double now, double total) +{ + Eo *obj = data; + Elm_Photocam_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 +_file_set(Eo *obj, void *_pd, va_list *list) +{ + const char *file = va_arg(*list, const char *); + Evas_Load_Error *ret = va_arg(*list, Evas_Load_Error *); + if (ret) *ret = EVAS_LOAD_ERROR_NONE; + + Elm_Photocam_Smart_Data *sd = _pd; + unsigned int i; + + _grid_clear_all(obj); + ELM_SAFE_FREE(sd->g_layer_zoom.bounce.animator, ecore_animator_del); + if (sd->zoom_animator) + { + sd->no_smooth--; + if (sd->no_smooth == 0) _smooth_update(obj); + ecore_animator_del(sd->zoom_animator); + sd->zoom_animator = NULL; + } + if (sd->calc_job) ecore_job_del(sd->calc_job); + evas_object_hide(sd->img); + if (sd->f) eina_file_close(sd->f); + sd->f = NULL; + + free(sd->remote_data); + 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 ! + sd->remote = elm_url_download(file, + _elm_photocam_download_done, + _elm_photocam_download_cancel, + _elm_photocam_download_progress, + obj); + if (sd->remote) + { + evas_object_smart_callback_call(obj, SIG_DOWNLOAD_START, NULL); + return ; + } + break; + } + + + _internal_file_set(obj, sd, file, NULL, ret); +} + EAPI const char * elm_photocam_file_get(const Evas_Object *obj) { diff --git a/legacy/elementary/src/lib/elm_photocam.h b/legacy/elementary/src/lib/elm_photocam.h index 18b6cec784..d6b7c98b9c 100644 --- a/legacy/elementary/src/lib/elm_photocam.h +++ b/legacy/elementary/src/lib/elm_photocam.h @@ -68,6 +68,31 @@ typedef enum ELM_PHOTOCAM_ZOOM_MODE_LAST } Elm_Photocam_Zoom_Mode; +/** + * Structure associated with smart callback 'download,progress'. + * @since 1.8 + */ +typedef struct _Elm_Photocam_Progress Elm_Photocam_Progress; + +struct _Elm_Photocam_Progress +{ + double now; + double total; +}; + + +/** + * Structre associated with smart callback 'download,error' + * @since 1.8 + */ +typedef struct _Elm_Photocam_Error Elm_Photocam_Error; +struct _Elm_Photocam_Error +{ + int status; + + Eina_Bool open_error; +}; + #ifdef EFL_EO_API_SUPPORT #include "elm_photocam_eo.h" #endif diff --git a/legacy/elementary/src/lib/elm_widget_photocam.h b/legacy/elementary/src/lib/elm_widget_photocam.h index 30911996c5..7b70fcd379 100644 --- a/legacy/elementary/src/lib/elm_widget_photocam.h +++ b/legacy/elementary/src/lib/elm_widget_photocam.h @@ -80,6 +80,10 @@ struct _Elm_Photocam_Smart_Data } g_layer_zoom; const char *file; + Eina_File *f; + + Elm_Url *remote; + void *remote_data; Ecore_Job *calc_job; Ecore_Timer *scr_timer;