1 #include <Elementary.h>
3 #include "elm_widget_photocam.h"
6 * TODO (maybe - optional future stuff):
8 * 1. wrap photo in theme edje so u can have styling around photo (like white
11 * 3. rotation flags in exif handling (nasty! should have rot in evas)
14 EAPI const char ELM_PHOTOCAM_SMART_NAME[] = "elm_photocam";
15 EAPI const char ELM_PHOTOCAM_PAN_SMART_NAME[] = "elm_photocam_pan";
17 static const char SIG_CLICKED[] = "clicked";
18 static const char SIG_PRESS[] = "press";
19 static const char SIG_LONGPRESSED[] = "longpressed";
20 static const char SIG_CLICKED_DOUBLE[] = "clicked,double";
21 static const char SIG_LOAD[] = "load";
22 static const char SIG_LOADED[] = "loaded";
23 static const char SIG_LOAD_DETAIL[] = "load,detail";
24 static const char SIG_LOADED_DETAIL[] = "loaded,detail";
25 static const char SIG_ZOOM_START[] = "zoom,start";
26 static const char SIG_ZOOM_STOP[] = "zoom,stop";
27 static const char SIG_ZOOM_CHANGE[] = "zoom,change";
28 static const char SIG_SCROLL[] = "scroll";
29 static const char SIG_SCROLL_ANIM_START[] = "scroll,anim,start";
30 static const char SIG_SCROLL_ANIM_STOP[] = "scroll,anim,stop";
31 static const char SIG_SCROLL_DRAG_START[] = "scroll,drag,start";
32 static const char SIG_SCROLL_DRAG_STOP[] = "scroll,drag,stop";
33 static const Evas_Smart_Cb_Description _smart_callbacks[] = {
36 {SIG_LONGPRESSED, ""},
37 {SIG_CLICKED_DOUBLE, ""},
40 {SIG_LOAD_DETAIL, ""},
41 {SIG_LOADED_DETAIL, ""},
44 {SIG_ZOOM_CHANGE, ""},
46 {SIG_SCROLL_ANIM_START, ""},
47 {SIG_SCROLL_ANIM_STOP, ""},
48 {SIG_SCROLL_DRAG_START, ""},
49 {SIG_SCROLL_DRAG_STOP, ""},
53 static const Evas_Smart_Interface *_smart_interfaces[] =
55 (Evas_Smart_Interface *)&ELM_SCROLLABLE_IFACE, NULL
58 EVAS_SMART_SUBCLASS_IFACE_NEW
59 (ELM_PHOTOCAM_SMART_NAME, _elm_photocam, Elm_Photocam_Smart_Class,
60 Elm_Widget_Smart_Class, elm_widget_smart_class_get, _smart_callbacks,
63 ELM_INTERNAL_SMART_SUBCLASS_NEW
64 (ELM_PHOTOCAM_PAN_SMART_NAME, _elm_photocam_pan,
65 Elm_Photocam_Pan_Smart_Class, Elm_Pan_Smart_Class, elm_pan_smart_class_get,
69 _sizing_eval(Evas_Object *obj)
71 Evas_Coord minw = -1, minh = -1, maxw = -1, maxh = -1;
73 ELM_PHOTOCAM_DATA_GET(obj, sd);
75 evas_object_size_hint_max_get
76 (ELM_WIDGET_DATA(sd)->resize_obj, &maxw, &maxh);
77 evas_object_size_hint_min_set(obj, minw, minh);
78 evas_object_size_hint_max_set(obj, maxw, maxh);
82 _calc_job_cb(void *data)
84 Elm_Photocam_Smart_Data *sd = data;
85 Evas_Coord minw, minh;
91 sd->resized = EINA_FALSE;
92 if (sd->mode != ELM_PHOTOCAM_ZOOM_MODE_MANUAL)
96 elm_photocam_zoom_set(ELM_WIDGET_DATA(sd)->obj, tz);
99 if ((minw != sd->minw) || (minh != sd->minh))
104 evas_object_smart_callback_call(sd->pan_obj, "changed", NULL);
105 _sizing_eval(ELM_WIDGET_DATA(sd)->obj);
108 evas_object_smart_changed(sd->pan_obj);
112 _elm_photocam_pan_smart_add(Evas_Object *obj)
114 /* here just to allocate our extended data */
115 EVAS_SMART_DATA_ALLOC(obj, Elm_Photocam_Pan_Smart_Data);
117 ELM_PAN_CLASS(_elm_photocam_pan_parent_sc)->base.add(obj);
121 _elm_photocam_pan_smart_move(Evas_Object *obj,
122 Evas_Coord x __UNUSED__,
123 Evas_Coord y __UNUSED__)
125 ELM_PHOTOCAM_PAN_DATA_GET(obj, psd);
127 if (psd->wsd->calc_job) ecore_job_del(psd->wsd->calc_job);
128 psd->wsd->calc_job = ecore_job_add(_calc_job_cb, psd->wsd);
132 _elm_photocam_pan_smart_resize(Evas_Object *obj,
138 ELM_PHOTOCAM_PAN_DATA_GET(obj, psd);
140 evas_object_geometry_get(obj, NULL, NULL, &ow, &oh);
141 if ((ow == w) && (oh == h)) return;
143 psd->wsd->resized = EINA_TRUE;
144 if (psd->wsd->calc_job) ecore_job_del(psd->wsd->calc_job);
145 psd->wsd->calc_job = ecore_job_add(_calc_job_cb, psd->wsd);
149 _image_place(Evas_Object *obj,
157 Evas_Coord ax, ay, gw, gh;
159 ELM_PHOTOCAM_DATA_GET(obj, sd);
165 if (!sd->zoom_g_layer)
167 if (ow > gw) ax = (ow - gw) / 2;
168 if (oh > gh) ay = (oh - gh) / 2;
170 evas_object_move(sd->img, ox + 0 - px + ax, oy + 0 - py + ay);
171 evas_object_resize(sd->img, gw, gh);
175 sd->show.show = EINA_FALSE;
176 sd->s_iface->content_region_show
177 (obj, sd->show.x, sd->show.y, sd->show.w, sd->show.h);
182 _grid_load(Evas_Object *obj,
186 Evas_Coord ox, oy, ow, oh, cvx, cvy, cvw, cvh, gw, gh, tx, ty;
188 ELM_PHOTOCAM_DATA_GET(obj, sd);
190 evas_object_geometry_get(sd->pan_obj, &ox, &oy, &ow, &oh);
191 evas_output_viewport_get(evas_object_evas_get(obj), &cvx, &cvy, &cvw, &cvh);
195 for (y = 0; y < g->gh; y++)
197 for (x = 0; x < g->gw; x++)
199 int tn, xx, yy, ww, hh;
200 Eina_Bool visible = EINA_FALSE;
202 tn = (y * g->gw) + x;
203 xx = g->grid[tn].out.x;
204 yy = g->grid[tn].out.y;
205 ww = g->grid[tn].out.w;
206 hh = g->grid[tn].out.h;
207 if ((gw != g->w) && (g->w > 0))
210 xx = (gw * xx) / g->w;
211 ww = ((gw * (tx + ww)) / g->w) - xx;
213 if ((gh != g->h) && (g->h > 0))
216 yy = (gh * yy) / g->h;
217 hh = ((gh * (ty + hh)) / g->h) - yy;
219 if (ELM_RECTS_INTERSECT(xx - sd->pan_x + ox,
221 ww, hh, cvx, cvy, cvw, cvh))
223 if ((visible) && (!g->grid[tn].have) && (!g->grid[tn].want))
225 g->grid[tn].want = 1;
226 evas_object_hide(g->grid[tn].img);
227 evas_object_image_file_set(g->grid[tn].img, NULL, NULL);
228 evas_object_image_load_scale_down_set
229 (g->grid[tn].img, g->zoom);
230 evas_object_image_load_region_set
231 (g->grid[tn].img, g->grid[tn].src.x, g->grid[tn].src.y,
232 g->grid[tn].src.w, g->grid[tn].src.h);
233 evas_object_image_file_set(g->grid[tn].img, sd->file, NULL);
234 evas_object_image_preload(g->grid[tn].img, 0);
236 if (sd->preload_num == 1)
238 edje_object_signal_emit
239 (ELM_WIDGET_DATA(sd)->resize_obj,
240 "elm,state,busy,start", "elm");
241 evas_object_smart_callback_call
242 (obj, SIG_LOAD_DETAIL, NULL);
245 else if ((g->grid[tn].want) && (!visible))
248 if (!sd->preload_num)
250 edje_object_signal_emit
251 (ELM_WIDGET_DATA(sd)->resize_obj,
252 "elm,state,busy,stop", "elm");
253 evas_object_smart_callback_call
254 (obj, SIG_LOADED_DETAIL, NULL);
256 g->grid[tn].want = 0;
257 evas_object_hide(g->grid[tn].img);
258 evas_object_image_preload(g->grid[tn].img, 1);
259 evas_object_image_file_set(g->grid[tn].img, NULL, NULL);
261 else if ((g->grid[tn].have) && (!visible))
263 g->grid[tn].have = 0;
264 evas_object_hide(g->grid[tn].img);
265 evas_object_image_preload(g->grid[tn].img, 1);
266 evas_object_image_file_set(g->grid[tn].img, NULL, NULL);
273 _grid_place(Evas_Object *obj,
282 Evas_Coord ax, ay, gw, gh, tx, ty;
285 ELM_PHOTOCAM_DATA_GET(obj, sd);
291 if (!sd->zoom_g_layer)
293 if (ow > gw) ax = (ow - gw) / 2;
294 if (oh > gh) ay = (oh - gh) / 2;
296 for (y = 0; y < g->gh; y++)
298 for (x = 0; x < g->gw; x++)
300 int tn, xx, yy, ww, hh;
302 tn = (y * g->gw) + x;
303 xx = g->grid[tn].out.x;
304 yy = g->grid[tn].out.y;
305 ww = g->grid[tn].out.w;
306 hh = g->grid[tn].out.h;
307 if ((gw != g->w) && (g->w > 0))
310 xx = (gw * xx) / g->w;
311 ww = ((gw * (tx + ww)) / g->w) - xx;
313 if ((gh != g->h) && (g->h > 0))
316 yy = (gh * yy) / g->h;
317 hh = ((gh * (ty + hh)) / g->h) - yy;
319 evas_object_move(g->grid[tn].img,
322 evas_object_resize(g->grid[tn].img, ww, hh);
328 _elm_photocam_pan_smart_calculate(Evas_Object *obj)
332 Evas_Coord ox, oy, ow, oh;
334 ELM_PHOTOCAM_PAN_DATA_GET(obj, psd);
336 evas_object_geometry_get(obj, &ox, &oy, &ow, &oh);
338 ELM_WIDGET_DATA(psd->wsd)->obj, psd->wsd->pan_x, psd->wsd->pan_y,
339 ox - psd->wsd->g_layer_zoom.imx, oy - psd->wsd->g_layer_zoom.imy, ow,
342 EINA_LIST_FOREACH(psd->wsd->grids, l, g)
344 _grid_load(ELM_WIDGET_DATA(psd->wsd)->obj, g);
346 ELM_WIDGET_DATA(psd->wsd)->obj, g, psd->wsd->pan_x,
347 psd->wsd->pan_y, ox - psd->wsd->g_layer_zoom.imx,
348 oy - psd->wsd->g_layer_zoom.imy, ow, oh);
353 _elm_photocam_pan_smart_pos_set(Evas_Object *obj,
357 ELM_PHOTOCAM_PAN_DATA_GET(obj, psd);
359 if ((x == psd->wsd->pan_x) && (y == psd->wsd->pan_y)) return;
362 evas_object_smart_changed(obj);
366 _elm_photocam_pan_smart_pos_get(const Evas_Object *obj,
370 ELM_PHOTOCAM_PAN_DATA_GET(obj, psd);
372 if (x) *x = psd->wsd->pan_x;
373 if (y) *y = psd->wsd->pan_y;
377 _elm_photocam_pan_smart_pos_max_get(const Evas_Object *obj,
383 ELM_PHOTOCAM_PAN_DATA_GET(obj, psd);
385 evas_object_geometry_get(obj, NULL, NULL, &ow, &oh);
386 ow = psd->wsd->minw - ow;
388 oh = psd->wsd->minh - oh;
395 _elm_photocam_pan_smart_pos_min_get(const Evas_Object *obj __UNUSED__,
404 _elm_photocam_pan_smart_content_size_get(const Evas_Object *obj,
408 ELM_PHOTOCAM_PAN_DATA_GET(obj, psd);
410 if (w) *w = psd->wsd->minw;
411 if (h) *h = psd->wsd->minh;
415 _elm_photocam_pan_smart_set_user(Elm_Photocam_Pan_Smart_Class *sc)
417 ELM_PAN_CLASS(sc)->base.add = _elm_photocam_pan_smart_add;
418 ELM_PAN_CLASS(sc)->base.move = _elm_photocam_pan_smart_move;
419 ELM_PAN_CLASS(sc)->base.resize = _elm_photocam_pan_smart_resize;
420 ELM_PAN_CLASS(sc)->base.calculate = _elm_photocam_pan_smart_calculate;
422 ELM_PAN_CLASS(sc)->pos_set = _elm_photocam_pan_smart_pos_set;
423 ELM_PAN_CLASS(sc)->pos_get = _elm_photocam_pan_smart_pos_get;
424 ELM_PAN_CLASS(sc)->pos_max_get = _elm_photocam_pan_smart_pos_max_get;
425 ELM_PAN_CLASS(sc)->pos_min_get = _elm_photocam_pan_smart_pos_min_get;
426 ELM_PAN_CLASS(sc)->content_size_get =
427 _elm_photocam_pan_smart_content_size_get;
431 _nearest_pow2_get(int num)
433 unsigned int n = num - 1;
445 _grid_clear(Evas_Object *obj,
450 ELM_PHOTOCAM_DATA_GET(obj, sd);
452 if (!g->grid) return;
453 for (y = 0; y < g->gh; y++)
455 for (x = 0; x < g->gw; x++)
459 tn = (y * g->gw) + x;
460 evas_object_del(g->grid[tn].img);
461 if (g->grid[tn].want)
464 if (!sd->preload_num)
466 edje_object_signal_emit
467 (ELM_WIDGET_DATA(sd)->resize_obj,
468 "elm,state,busy,stop", "elm");
469 evas_object_smart_callback_call
470 (obj, SIG_LOAD_DETAIL, NULL);
483 _tile_preloaded_cb(void *data,
485 Evas_Object *o __UNUSED__,
486 void *event_info __UNUSED__)
488 Elm_Photocam_Grid_Item *git = data;
493 evas_object_show(git->img);
495 git->sd->preload_num--;
496 if (!git->sd->preload_num)
498 edje_object_signal_emit
499 (ELM_WIDGET_DATA(git->sd)->resize_obj, "elm,state,busy,stop",
501 evas_object_smart_callback_call
502 (ELM_WIDGET_DATA(git->sd)->obj, SIG_LOADED_DETAIL, NULL);
508 _grid_zoom_calc(double zoom)
513 return _nearest_pow2_get(z);
516 static Elm_Phocam_Grid *
517 _grid_create(Evas_Object *obj)
522 ELM_PHOTOCAM_DATA_GET(obj, sd);
524 g = calloc(1, sizeof(Elm_Phocam_Grid));
527 g->zoom = _grid_zoom_calc(sd->zoom);
528 g->tsize = sd->tsize;
529 g->iw = sd->size.imw;
530 g->ih = sd->size.imh;
532 g->w = g->iw / g->zoom;
533 g->h = g->ih / g->zoom;
542 g->gw = (g->w + g->tsize - 1) / g->tsize;
543 g->gh = (g->h + g->tsize - 1) / g->tsize;
551 g->grid = calloc(1, sizeof(Elm_Photocam_Grid_Item) * g->gw * g->gh);
560 for (y = 0; y < g->gh; y++)
562 for (x = 0; x < g->gw; x++)
566 tn = (y * g->gw) + x;
567 g->grid[tn].src.x = x * g->tsize;
568 if (x == (g->gw - 1))
569 g->grid[tn].src.w = g->w - ((g->gw - 1) * g->tsize);
571 g->grid[tn].src.w = g->tsize;
572 g->grid[tn].src.y = y * g->tsize;
573 if (y == (g->gh - 1))
574 g->grid[tn].src.h = g->h - ((g->gh - 1) * g->tsize);
576 g->grid[tn].src.h = g->tsize;
578 g->grid[tn].out.x = g->grid[tn].src.x;
579 g->grid[tn].out.y = g->grid[tn].src.y;
580 g->grid[tn].out.w = g->grid[tn].src.w;
581 g->grid[tn].out.h = g->grid[tn].src.h;
585 evas_object_image_add(evas_object_evas_get(obj));
586 evas_object_image_load_orientation_set(g->grid[tn].img, EINA_TRUE);
587 evas_object_image_scale_hint_set
588 (g->grid[tn].img, EVAS_IMAGE_SCALE_HINT_DYNAMIC);
589 evas_object_pass_events_set(g->grid[tn].img, EINA_TRUE);
591 /* XXX: check this */
592 evas_object_smart_member_add(g->grid[tn].img, sd->pan_obj);
593 elm_widget_sub_object_add(obj, g->grid[tn].img);
594 evas_object_image_filled_set(g->grid[tn].img, 1);
595 evas_object_event_callback_add
596 (g->grid[tn].img, EVAS_CALLBACK_IMAGE_PRELOADED,
597 _tile_preloaded_cb, &(g->grid[tn]));
605 _grid_clear_all(Evas_Object *obj)
609 ELM_PHOTOCAM_DATA_GET(obj, sd);
611 EINA_LIST_FREE (sd->grids, g)
619 _smooth_update(Evas_Object *obj)
625 ELM_PHOTOCAM_DATA_GET(obj, sd);
627 EINA_LIST_FOREACH(sd->grids, l, g)
629 for (y = 0; y < g->gh; y++)
631 for (x = 0; x < g->gw; x++)
635 tn = (y * g->gw) + x;
636 evas_object_image_smooth_scale_set
637 (g->grid[tn].img, (!sd->no_smooth));
642 evas_object_image_smooth_scale_set(sd->img, (!sd->no_smooth));
646 _grid_raise(Elm_Phocam_Grid *g)
650 for (y = 0; y < g->gh; y++)
652 for (x = 0; x < g->gw; x++)
656 tn = (y * g->gw) + x;
657 evas_object_raise(g->grid[tn].img);
663 _scroll_timeout_cb(void *data)
665 ELM_PHOTOCAM_DATA_GET(data, sd);
668 if (!sd->no_smooth) _smooth_update(data);
670 sd->scr_timer = NULL;
672 return ECORE_CALLBACK_CANCEL;
676 _main_img_preloaded_cb(void *data,
678 Evas_Object *o __UNUSED__,
679 void *event_info __UNUSED__)
681 Evas_Object *obj = data;
684 ELM_PHOTOCAM_DATA_GET(data, sd);
686 evas_object_show(sd->img);
687 sd->main_load_pending = 0;
688 g = _grid_create(obj);
691 sd->grids = eina_list_prepend(sd->grids, g);
694 if (sd->calc_job) ecore_job_del(sd->calc_job);
695 sd->calc_job = ecore_job_add(_calc_job_cb, sd);
696 evas_object_smart_callback_call(data, SIG_LOADED, NULL);
698 if (!sd->preload_num)
700 edje_object_signal_emit
701 (ELM_WIDGET_DATA(sd)->resize_obj, "elm,state,busy,stop", "elm");
702 evas_object_smart_callback_call(obj, SIG_LOADED_DETAIL, NULL);
707 _zoom_do(Evas_Object *obj,
710 Evas_Coord xx, yy, ow, oh;
712 ELM_PHOTOCAM_DATA_GET(obj, sd);
714 sd->size.w = (sd->size.ow * (1.0 - t)) + (sd->size.nw * t);
715 sd->size.h = (sd->size.oh * (1.0 - t)) + (sd->size.nh * t);
716 sd->s_iface->content_viewport_size_get(obj, &ow, &oh);
717 xx = (sd->size.spos.x * sd->size.w) - (ow / 2);
718 yy = (sd->size.spos.y * sd->size.h) - (oh / 2);
720 else if (xx > (sd->size.w - ow))
721 xx = sd->size.w - ow;
723 else if (yy > (sd->size.h - oh))
724 yy = sd->size.h - oh;
726 sd->show.show = EINA_TRUE;
732 if (sd->calc_job) ecore_job_del(sd->calc_job);
733 sd->calc_job = ecore_job_add(_calc_job_cb, sd);
736 Eina_List *l, *l_next;
739 EINA_LIST_FOREACH_SAFE(sd->grids, l, l_next, g)
743 sd->grids = eina_list_remove_list(sd->grids, l);
755 _zoom_anim_cb(void *data)
759 Evas_Object *obj = data;
761 ELM_PHOTOCAM_DATA_GET(obj, sd);
763 t = ecore_loop_time_get();
766 else if (sd->t_end > sd->t_start)
767 t = (t - sd->t_start) / (sd->t_end - sd->t_start);
772 go = _zoom_do(obj, t);
776 if (!sd->no_smooth) _smooth_update(data);
777 sd->zoom_animator = NULL;
778 evas_object_smart_callback_call(obj, SIG_ZOOM_STOP, NULL);
785 _long_press_cb(void *data)
787 ELM_PHOTOCAM_DATA_GET(data, sd);
789 sd->long_timer = NULL;
790 sd->longpressed = EINA_TRUE;
791 evas_object_smart_callback_call(data, SIG_LONGPRESSED, NULL);
793 return ECORE_CALLBACK_CANCEL;
797 _mouse_down_cb(void *data,
798 Evas *evas __UNUSED__,
799 Evas_Object *obj __UNUSED__,
802 Evas_Event_Mouse_Down *ev = event_info;
804 ELM_PHOTOCAM_DATA_GET(data, sd);
806 if (ev->button != 1) return;
807 if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) sd->on_hold = EINA_TRUE;
808 else sd->on_hold = EINA_FALSE;
809 if (ev->flags & EVAS_BUTTON_DOUBLE_CLICK)
810 evas_object_smart_callback_call(data, SIG_CLICKED_DOUBLE, NULL);
812 evas_object_smart_callback_call(data, SIG_PRESS, NULL);
813 sd->longpressed = EINA_FALSE;
814 if (sd->long_timer) ecore_timer_del(sd->long_timer);
815 sd->long_timer = ecore_timer_add
816 (_elm_config->longpress_timeout, _long_press_cb, data);
820 _mouse_up_cb(void *data,
821 Evas *evas __UNUSED__,
822 Evas_Object *obj __UNUSED__,
825 Evas_Event_Mouse_Up *ev = event_info;
827 ELM_PHOTOCAM_DATA_GET(data, sd);
829 if (ev->button != 1) return;
830 if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) sd->on_hold = EINA_TRUE;
831 else sd->on_hold = EINA_FALSE;
834 ecore_timer_del(sd->long_timer);
835 sd->long_timer = NULL;
838 evas_object_smart_callback_call(data, SIG_CLICKED, NULL);
839 sd->on_hold = EINA_FALSE;
843 _elm_photocam_smart_on_focus(Evas_Object *obj)
845 ELM_PHOTOCAM_DATA_GET(obj, sd);
847 if (elm_widget_focus_get(obj))
849 edje_object_signal_emit
850 (ELM_WIDGET_DATA(sd)->resize_obj, "elm,action,focus", "elm");
851 evas_object_focus_set(ELM_WIDGET_DATA(sd)->resize_obj, EINA_TRUE);
855 edje_object_signal_emit
856 (ELM_WIDGET_DATA(sd)->resize_obj, "elm,action,unfocus", "elm");
857 evas_object_focus_set(ELM_WIDGET_DATA(sd)->resize_obj, EINA_FALSE);
864 _elm_photocam_smart_theme(Evas_Object *obj)
866 if (!ELM_WIDGET_CLASS(_elm_photocam_parent_sc)->theme(obj))
875 _scroll_animate_start_cb(Evas_Object *obj,
876 void *data __UNUSED__)
878 evas_object_smart_callback_call(obj, SIG_SCROLL_ANIM_START, NULL);
882 _scroll_animate_stop_cb(Evas_Object *obj,
883 void *data __UNUSED__)
885 evas_object_smart_callback_call(obj, SIG_SCROLL_ANIM_STOP, NULL);
889 _scroll_drag_start_cb(Evas_Object *obj,
890 void *data __UNUSED__)
892 evas_object_smart_callback_call(obj, SIG_SCROLL_DRAG_START, NULL);
896 _scroll_drag_stop_cb(Evas_Object *obj,
897 void *data __UNUSED__)
899 evas_object_smart_callback_call(obj, SIG_SCROLL_DRAG_STOP, NULL);
903 _scroll_cb(Evas_Object *obj,
904 void *data __UNUSED__)
906 ELM_PHOTOCAM_DATA_GET(obj, sd);
911 if (sd->no_smooth == 1) _smooth_update(obj);
914 if (sd->scr_timer) ecore_timer_del(sd->scr_timer);
915 sd->scr_timer = ecore_timer_add(0.5, _scroll_timeout_cb, obj);
917 evas_object_smart_callback_call(obj, SIG_SCROLL, NULL);
921 _elm_photocam_smart_event(Evas_Object *obj,
922 Evas_Object *src __UNUSED__,
923 Evas_Callback_Type type,
931 Evas_Coord step_x = 0;
932 Evas_Coord step_y = 0;
933 Evas_Coord page_x = 0;
934 Evas_Coord page_y = 0;
935 Evas_Event_Key_Down *ev = event_info;
937 ELM_PHOTOCAM_DATA_GET(obj, sd);
939 if (elm_widget_disabled_get(obj)) return EINA_FALSE;
941 if (type != EVAS_CALLBACK_KEY_DOWN) return EINA_FALSE;
942 if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) return EINA_FALSE;
944 sd->s_iface->content_pos_get(obj, &x, &y);
945 sd->s_iface->step_size_get(obj, &step_x, &step_y);
946 sd->s_iface->page_size_get(obj, &page_x, &page_y);
947 sd->s_iface->content_viewport_size_get(obj, &v_w, &v_h);
949 if ((!strcmp(ev->keyname, "Left")) ||
950 ((!strcmp(ev->keyname, "KP_Left")) && (!ev->string)))
954 else if ((!strcmp(ev->keyname, "Right")) ||
955 ((!strcmp(ev->keyname, "KP_Right")) && (!ev->string)))
959 else if ((!strcmp(ev->keyname, "Up")) ||
960 ((!strcmp(ev->keyname, "KP_Up")) && (!ev->string)))
964 else if ((!strcmp(ev->keyname, "Down")) ||
965 ((!strcmp(ev->keyname, "KP_Down")) && (!ev->string)))
969 else if ((!strcmp(ev->keyname, "Prior")) ||
970 ((!strcmp(ev->keyname, "KP_Prior")) && (!ev->string)))
973 y -= -(page_y * v_h) / 100;
977 else if ((!strcmp(ev->keyname, "Next")) ||
978 ((!strcmp(ev->keyname, "KP_Next")) && (!ev->string)))
981 y += -(page_y * v_h) / 100;
985 else if ((!strcmp(ev->keyname, "KP_Add")))
987 zoom = elm_photocam_zoom_get(obj);
989 elm_photocam_zoom_mode_set(obj, ELM_PHOTOCAM_ZOOM_MODE_MANUAL);
990 elm_photocam_zoom_set(obj, zoom);
993 else if ((!strcmp(ev->keyname, "KP_Subtract")))
995 zoom = elm_photocam_zoom_get(obj);
997 elm_photocam_zoom_mode_set(obj, ELM_PHOTOCAM_ZOOM_MODE_MANUAL);
998 elm_photocam_zoom_set(obj, zoom);
1001 else return EINA_FALSE;
1003 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
1004 sd->s_iface->content_pos_set(obj, x, y, EINA_TRUE);
1010 _bounce_eval(void *data)
1012 Elm_Photocam_Smart_Data *sd = data;
1015 if ((sd->g_layer_zoom.imx == sd->g_layer_zoom.bounce.x_end) &&
1016 (sd->g_layer_zoom.imy == sd->g_layer_zoom.bounce.y_end))
1018 sd->g_layer_zoom.imx = 0;
1019 sd->g_layer_zoom.imy = 0;
1020 sd->zoom_g_layer = EINA_FALSE;
1021 sd->g_layer_zoom.bounce.animator = NULL;
1023 sd->s_iface->freeze_set(ELM_WIDGET_DATA(sd)->obj, EINA_FALSE);
1025 return ECORE_CALLBACK_CANCEL;
1028 t = ecore_loop_time_get();
1029 tt = (t - sd->g_layer_zoom.bounce.t_start) /
1030 (sd->g_layer_zoom.bounce.t_end -
1031 sd->g_layer_zoom.bounce.t_start);
1033 tt = 1.0 - (tt * tt);
1035 if (t > sd->g_layer_zoom.bounce.t_end)
1037 sd->g_layer_zoom.imx = 0;
1038 sd->g_layer_zoom.imy = 0;
1039 sd->zoom_g_layer = EINA_FALSE;
1041 sd->s_iface->freeze_set(ELM_WIDGET_DATA(sd)->obj, EINA_FALSE);
1043 _zoom_do(ELM_WIDGET_DATA(sd)->obj, 1.0);
1044 sd->g_layer_zoom.bounce.animator = NULL;
1045 return ECORE_CALLBACK_CANCEL;
1048 if (sd->g_layer_zoom.imx != sd->g_layer_zoom.bounce.x_end)
1049 sd->g_layer_zoom.imx =
1050 sd->g_layer_zoom.bounce.x_start * (1.0 - tt) +
1051 sd->g_layer_zoom.bounce.x_end * tt;
1053 if (sd->g_layer_zoom.imy != sd->g_layer_zoom.bounce.y_end)
1054 sd->g_layer_zoom.imy =
1055 sd->g_layer_zoom.bounce.y_start * (1.0 - tt) +
1056 sd->g_layer_zoom.bounce.y_end * tt;
1058 _zoom_do(ELM_WIDGET_DATA(sd)->obj, 1.0 - (1.0 - tt));
1060 return ECORE_CALLBACK_RENEW;
1064 _g_layer_zoom_do(Elm_Photocam_Smart_Data *sd,
1067 Elm_Gesture_Zoom_Info *g_layer)
1069 int regx, regy, regw, regh, ix, iy, iw, ih;
1070 Evas_Coord rx, ry, rw, rh;
1074 obj = ELM_WIDGET_DATA(sd)->obj;
1075 sd->mode = ELM_PHOTOCAM_ZOOM_MODE_MANUAL;
1076 sd->zoom = sd->g_layer_start / g_layer->zoom;
1077 sd->size.ow = sd->size.w;
1078 sd->size.oh = sd->size.h;
1079 sd->s_iface->content_pos_get(obj, &rx, &ry);
1080 sd->s_iface->content_viewport_size_get(obj, &rw, &rh);
1081 if ((rw <= 0) || (rh <= 0)) return;
1083 sd->size.nw = (double)sd->size.imw / sd->zoom;
1084 sd->size.nh = (double)sd->size.imh / sd->zoom;
1086 elm_photocam_image_region_get(obj, ®x, ®y, ®w, ®h);
1087 evas_object_geometry_get(sd->img, &ix, &iy, &iw, &ih);
1089 sd->pvx = g_layer->x;
1090 sd->pvy = g_layer->y;
1092 xx = (px / sd->zoom) - sd->pvx;
1093 yy = (py / sd->zoom) - sd->pvy;
1094 sd->g_layer_zoom.imx = 0;
1095 sd->g_layer_zoom.imy = 0;
1097 if ((xx < 0) || (rw > sd->size.nw))
1099 sd->g_layer_zoom.imx = xx;
1102 else if ((xx + rw) > sd->size.nw)
1104 sd->g_layer_zoom.imx = xx + rw - sd->size.nw;
1105 xx = sd->size.nw - rw;
1108 if ((yy < 0) || (rh > sd->size.nh))
1110 sd->g_layer_zoom.imy = yy;
1113 else if ((yy + rh) > sd->size.nh)
1115 sd->g_layer_zoom.imy = yy + rh - sd->size.nh;
1116 yy = sd->size.nh - rh;
1119 sd->size.spos.x = (double)(xx + (rw / 2)) / (double)(sd->size.nw);
1120 sd->size.spos.y = (double)(yy + (rh / 2)) / (double)(sd->size.nh);
1125 static Evas_Event_Flags
1126 _g_layer_zoom_start_cb(void *data,
1129 Elm_Gesture_Zoom_Info *p = event_info;
1130 Elm_Photocam_Smart_Data *sd = data;
1131 double marginx = 0, marginy = 0;
1135 if (sd->g_layer_zoom.bounce.animator)
1137 ecore_animator_del(sd->g_layer_zoom.bounce.animator);
1138 sd->g_layer_zoom.bounce.animator = NULL;
1140 sd->zoom_g_layer = EINA_TRUE;
1142 sd->s_iface->freeze_set(ELM_WIDGET_DATA(sd)->obj, EINA_TRUE);
1144 elm_photocam_image_region_get(ELM_WIDGET_DATA(sd)->obj, &x, &y, &w, &h);
1145 sd->s_iface->content_viewport_size_get(ELM_WIDGET_DATA(sd)->obj, &rw, &rh);
1147 if (rw > sd->size.nw)
1148 marginx = (rw - sd->size.nw) / 2;
1149 if (rh > sd->size.nh)
1150 marginy = (rh - sd->size.nh) / 2;
1152 sd->g_layer_start = sd->zoom;
1154 sd->zoom_point_x = x + ((p->x - marginx) * sd->zoom) +
1155 sd->g_layer_zoom.imx;
1156 sd->zoom_point_y = y + ((p->y - marginy) * sd->zoom) +
1157 sd->g_layer_zoom.imy;
1159 return EVAS_EVENT_FLAG_NONE;
1162 static Evas_Event_Flags
1163 _g_layer_zoom_move_cb(void *data,
1166 Elm_Photocam_Smart_Data *sd = data;
1167 Elm_Gesture_Zoom_Info *p = event_info;
1169 _g_layer_zoom_do(sd, sd->zoom_point_x, sd->zoom_point_y, p);
1171 return EVAS_EVENT_FLAG_NONE;
1174 static Evas_Event_Flags
1175 _g_layer_zoom_end_cb(void *data,
1176 void *event_info __UNUSED__)
1178 Elm_Photocam_Smart_Data *sd = data;
1181 sd->s_iface->content_viewport_size_get(ELM_WIDGET_DATA(sd)->obj, &rw, &rh);
1182 sd->g_layer_start = 1.0;
1184 if (sd->g_layer_zoom.imx || sd->g_layer_zoom.imy)
1188 t = ecore_loop_time_get();
1189 sd->g_layer_zoom.bounce.x_start = sd->g_layer_zoom.imx;
1190 sd->g_layer_zoom.bounce.y_start = sd->g_layer_zoom.imy;
1191 sd->g_layer_zoom.bounce.x_end = 0;
1192 sd->g_layer_zoom.bounce.y_end = 0;
1194 if (rw > sd->size.nw &&
1200 if ((sd->size.imw < rw) && (sd->size.imh < rh))
1203 sd->size.nw = sd->size.imw;
1204 sd->size.nh = sd->size.imh;
1208 ph = (sd->size.imh * rw) / sd->size.imw;
1211 pw = (sd->size.imw * rh) / sd->size.imh;
1218 if (sd->size.imw > sd->size.imh)
1219 z = (double)sd->size.imw / pw;
1221 z = (double)sd->size.imh / ph;
1227 sd->g_layer_zoom.bounce.x_end = (sd->size.nw - rw) / 2;
1228 sd->g_layer_zoom.bounce.y_end = (sd->size.nh - rh) / 2;
1234 xx = (sd->zoom_point_x / sd->zoom) - sd->pvx;
1235 yy = (sd->zoom_point_y / sd->zoom) - sd->pvy;
1240 if (rw > sd->size.nw)
1241 sd->g_layer_zoom.bounce.x_end = (sd->size.nw - rw) / 2;
1242 if ((xx + rw) > sd->size.nw)
1243 xx = sd->size.nw - rw;
1245 if (rh > sd->size.nh)
1246 sd->g_layer_zoom.bounce.y_end = (sd->size.nh - rh) / 2;
1247 if ((yy + rh) > sd->size.nh)
1248 yy = sd->size.nh - rh;
1250 sd->size.spos.x = (double)(xx + (rw / 2)) / (double)(sd->size.nw);
1251 sd->size.spos.y = (double)(yy + (rh / 2)) / (double)(sd->size.nh);
1254 sd->g_layer_zoom.bounce.t_start = t;
1255 sd->g_layer_zoom.bounce.t_end = t +
1256 _elm_config->page_scroll_friction;
1258 sd->g_layer_zoom.bounce.animator =
1259 ecore_animator_add(_bounce_eval, sd);
1263 sd->s_iface->freeze_set(ELM_WIDGET_DATA(sd)->obj, EINA_FALSE);
1264 sd->zoom_g_layer = EINA_FALSE;
1267 return EVAS_EVENT_FLAG_NONE;
1271 _elm_photocam_smart_add(Evas_Object *obj)
1273 Evas_Coord minw, minh;
1274 Elm_Photocam_Pan_Smart_Data *pan_data;
1275 Eina_Bool bounce = _elm_config->thumbscroll_bounce_enable;
1277 EVAS_SMART_DATA_ALLOC(obj, Elm_Photocam_Smart_Data);
1279 ELM_WIDGET_DATA(priv)->resize_obj =
1280 edje_object_add(evas_object_evas_get(obj));
1282 ELM_WIDGET_CLASS(_elm_photocam_parent_sc)->base.add(obj);
1284 elm_widget_theme_object_set
1285 (obj, ELM_WIDGET_DATA(priv)->resize_obj, "photocam", "base",
1286 elm_widget_style_get(obj));
1288 priv->hit_rect = evas_object_rectangle_add(evas_object_evas_get(obj));
1289 evas_object_smart_member_add(priv->hit_rect, obj);
1290 elm_widget_sub_object_add(obj, priv->hit_rect);
1292 /* common scroller hit rectangle setup */
1293 evas_object_color_set(priv->hit_rect, 0, 0, 0, 0);
1294 evas_object_show(priv->hit_rect);
1295 evas_object_repeat_events_set(priv->hit_rect, EINA_TRUE);
1297 elm_widget_can_focus_set(obj, EINA_TRUE);
1299 priv->s_iface = evas_object_smart_interface_get
1300 (obj, ELM_SCROLLABLE_IFACE_NAME);
1302 priv->s_iface->objects_set
1303 (obj, ELM_WIDGET_DATA(priv)->resize_obj, priv->hit_rect);
1305 priv->s_iface->animate_start_cb_set(obj, _scroll_animate_start_cb);
1306 priv->s_iface->animate_stop_cb_set(obj, _scroll_animate_stop_cb);
1307 priv->s_iface->drag_start_cb_set(obj, _scroll_drag_start_cb);
1308 priv->s_iface->drag_stop_cb_set(obj, _scroll_drag_stop_cb);
1309 priv->s_iface->scroll_cb_set(obj, _scroll_cb);
1311 priv->s_iface->bounce_allow_set(obj, bounce, bounce);
1313 priv->pan_obj = evas_object_smart_add
1314 (evas_object_evas_get(obj), _elm_photocam_pan_smart_class_new());
1315 pan_data = evas_object_smart_data_get(priv->pan_obj);
1316 pan_data->wsd = priv;
1318 priv->s_iface->extern_pan_set(obj, priv->pan_obj);
1320 priv->zoom_g_layer = EINA_FALSE;
1321 priv->g_layer_start = 1.0;
1323 priv->mode = ELM_PHOTOCAM_ZOOM_MODE_MANUAL;
1326 priv->img = evas_object_image_add(evas_object_evas_get(obj));
1327 evas_object_image_load_orientation_set(priv->img, EINA_TRUE);
1328 evas_object_image_scale_hint_set(priv->img, EVAS_IMAGE_SCALE_HINT_DYNAMIC);
1329 evas_object_event_callback_add
1330 (priv->img, EVAS_CALLBACK_MOUSE_DOWN, _mouse_down_cb, obj);
1331 evas_object_event_callback_add
1332 (priv->img, EVAS_CALLBACK_MOUSE_UP, _mouse_up_cb, obj);
1333 evas_object_image_scale_hint_set(priv->img, EVAS_IMAGE_SCALE_HINT_STATIC);
1336 evas_object_smart_member_add(priv->img, priv->pan_obj);
1338 elm_widget_sub_object_add(obj, priv->img);
1339 evas_object_image_filled_set(priv->img, EINA_TRUE);
1340 evas_object_event_callback_add
1341 (priv->img, EVAS_CALLBACK_IMAGE_PRELOADED, _main_img_preloaded_cb, obj);
1343 edje_object_size_min_calc(ELM_WIDGET_DATA(priv)->resize_obj, &minw, &minh);
1344 evas_object_size_hint_min_set(obj, minw, minh);
1351 _elm_photocam_smart_del(Evas_Object *obj)
1355 ELM_PHOTOCAM_DATA_GET(obj, sd);
1357 EINA_LIST_FREE (sd->grids, g)
1359 if (g->grid) free(g->grid);
1362 evas_object_del(sd->pan_obj);
1365 if (sd->file) eina_stringshare_del(sd->file);
1366 if (sd->calc_job) ecore_job_del(sd->calc_job);
1367 if (sd->scr_timer) ecore_timer_del(sd->scr_timer);
1368 if (sd->zoom_animator) ecore_animator_del(sd->zoom_animator);
1369 if (sd->g_layer_zoom.bounce.animator)
1370 ecore_animator_del(sd->g_layer_zoom.bounce.animator);
1371 if (sd->long_timer) ecore_timer_del(sd->long_timer);
1373 ELM_WIDGET_CLASS(_elm_photocam_parent_sc)->base.del(obj);
1377 _elm_photocam_smart_move(Evas_Object *obj,
1381 ELM_PHOTOCAM_DATA_GET(obj, sd);
1383 ELM_WIDGET_CLASS(_elm_photocam_parent_sc)->base.move(obj, x, y);
1385 evas_object_move(sd->hit_rect, x, y);
1389 _elm_photocam_smart_resize(Evas_Object *obj,
1393 ELM_PHOTOCAM_DATA_GET(obj, sd);
1395 ELM_WIDGET_CLASS(_elm_photocam_parent_sc)->base.resize(obj, w, h);
1397 evas_object_resize(sd->hit_rect, w, h);
1401 _elm_photocam_smart_member_add(Evas_Object *obj,
1402 Evas_Object *member)
1404 ELM_PHOTOCAM_DATA_GET(obj, sd);
1406 ELM_WIDGET_CLASS(_elm_photocam_parent_sc)->base.member_add(obj, member);
1409 evas_object_raise(sd->hit_rect);
1413 _elm_photocam_smart_set_user(Elm_Photocam_Smart_Class *sc)
1415 ELM_WIDGET_CLASS(sc)->base.add = _elm_photocam_smart_add;
1416 ELM_WIDGET_CLASS(sc)->base.del = _elm_photocam_smart_del;
1417 ELM_WIDGET_CLASS(sc)->base.move = _elm_photocam_smart_move;
1418 ELM_WIDGET_CLASS(sc)->base.resize = _elm_photocam_smart_resize;
1419 ELM_WIDGET_CLASS(sc)->base.member_add = _elm_photocam_smart_member_add;
1421 ELM_WIDGET_CLASS(sc)->on_focus = _elm_photocam_smart_on_focus;
1422 ELM_WIDGET_CLASS(sc)->theme = _elm_photocam_smart_theme;
1423 ELM_WIDGET_CLASS(sc)->event = _elm_photocam_smart_event;
1426 EAPI const Elm_Photocam_Smart_Class *
1427 elm_photocam_smart_class_get(void)
1429 static Elm_Photocam_Smart_Class _sc =
1430 ELM_PHOTOCAM_SMART_CLASS_INIT_NAME_VERSION(ELM_PHOTOCAM_SMART_NAME);
1431 static const Elm_Photocam_Smart_Class *class = NULL;
1432 Evas_Smart_Class *esc = (Evas_Smart_Class *)&_sc;
1434 if (class) return class;
1436 _elm_photocam_smart_set(&_sc);
1437 esc->callbacks = _smart_callbacks;
1444 elm_photocam_add(Evas_Object *parent)
1448 EINA_SAFETY_ON_NULL_RETURN_VAL(parent, NULL);
1450 obj = elm_widget_add(_elm_photocam_smart_class_new(), parent);
1451 if (!obj) return NULL;
1453 if (!elm_widget_sub_object_add(parent, obj))
1454 ERR("could not add %p as sub object of %p", obj, parent);
1459 EAPI Evas_Load_Error
1460 elm_photocam_file_set(Evas_Object *obj,
1465 Evas_Load_Error err;
1467 ELM_PHOTOCAM_CHECK(obj) EVAS_LOAD_ERROR_NONE;
1468 ELM_PHOTOCAM_DATA_GET(obj, sd);
1470 if (!eina_stringshare_replace(&sd->file, file)) return EVAS_LOAD_ERROR_NONE;
1471 _grid_clear_all(obj);
1473 evas_object_hide(sd->img);
1474 evas_object_image_smooth_scale_set(sd->img, (sd->no_smooth == 0));
1475 evas_object_image_file_set(sd->img, NULL, NULL);
1476 evas_object_image_load_scale_down_set(sd->img, 0);
1477 evas_object_image_file_set(sd->img, sd->file, NULL);
1478 err = evas_object_image_load_error_get(sd->img);
1479 if (err != EVAS_LOAD_ERROR_NONE)
1481 ERR("Things are going bad for '%s' (%p)", file, sd->img);
1484 evas_object_image_size_get(sd->img, &w, &h);
1486 sd->do_region = evas_object_image_region_support_get(sd->img);
1489 sd->size.w = sd->size.imw / sd->zoom;
1490 sd->size.h = sd->size.imh / sd->zoom;
1491 if (sd->g_layer_zoom.bounce.animator)
1493 ecore_animator_del(sd->g_layer_zoom.bounce.animator);
1494 sd->g_layer_zoom.bounce.animator = NULL;
1496 if (sd->zoom_animator)
1499 if (sd->no_smooth == 0) _smooth_update(obj);
1500 ecore_animator_del(sd->zoom_animator);
1501 sd->zoom_animator = NULL;
1503 evas_object_image_file_set(sd->img, NULL, NULL);
1504 evas_object_image_load_scale_down_set(sd->img, 8);
1505 evas_object_image_file_set(sd->img, sd->file, NULL);
1506 err = evas_object_image_load_error_get(sd->img);
1507 if (err != EVAS_LOAD_ERROR_NONE)
1509 ERR("Things are going bad for '%s' (%p)", file, sd->img);
1513 evas_object_image_preload(sd->img, 0);
1514 sd->main_load_pending = EINA_TRUE;
1516 if (sd->calc_job) ecore_job_del(sd->calc_job);
1517 sd->calc_job = ecore_job_add(_calc_job_cb, sd);
1518 evas_object_smart_callback_call(obj, SIG_LOAD, NULL);
1520 if (sd->preload_num == 1)
1522 edje_object_signal_emit
1523 (ELM_WIDGET_DATA(sd)->resize_obj, "elm,state,busy,start", "elm");
1524 evas_object_smart_callback_call(obj, SIG_LOAD_DETAIL, NULL);
1529 elm_photocam_zoom_set(ELM_WIDGET_DATA(sd)->obj, tz);
1531 return evas_object_image_load_error_get(sd->img);
1535 elm_photocam_file_get(const Evas_Object *obj)
1537 ELM_PHOTOCAM_CHECK(obj) NULL;
1538 ELM_PHOTOCAM_DATA_GET(obj, sd);
1544 elm_photocam_zoom_set(Evas_Object *obj,
1550 Elm_Phocam_Grid *g, *g_zoom = NULL;
1551 Evas_Coord pw, ph, rx, ry, rw, rh;
1552 int zoom_changed = 0, started = 0;
1554 ELM_PHOTOCAM_CHECK(obj);
1555 ELM_PHOTOCAM_DATA_GET(obj, sd);
1557 if (zoom <= (1.0 / 256.0)) zoom = (1.0 / 256.0);
1558 if (zoom == sd->zoom) return;
1561 sd->size.ow = sd->size.w;
1562 sd->size.oh = sd->size.h;
1563 sd->s_iface->content_pos_get(obj, &rx, &ry);
1564 sd->s_iface->content_viewport_size_get(obj, &rw, &rh);
1565 if ((rw <= 0) || (rh <= 0)) return;
1567 if (sd->mode == ELM_PHOTOCAM_ZOOM_MODE_MANUAL)
1569 sd->size.nw = (double)sd->size.imw / sd->zoom;
1570 sd->size.nh = (double)sd->size.imh / sd->zoom;
1572 else if (sd->mode == ELM_PHOTOCAM_ZOOM_MODE_AUTO_FIT)
1574 if ((sd->size.imw < 1) || (sd->size.imh < 1))
1581 ph = (sd->size.imh * rw) / sd->size.imw;
1584 pw = (sd->size.imw * rh) / sd->size.imh;
1591 if (sd->size.imw > sd->size.imh)
1592 z = (double)sd->size.imw / pw;
1594 z = (double)sd->size.imh / ph;
1602 else if (sd->mode == ELM_PHOTOCAM_ZOOM_MODE_AUTO_FILL)
1604 if ((sd->size.imw < 1) || (sd->size.imh < 1))
1611 ph = (sd->size.imh * rw) / sd->size.imw;
1614 pw = (sd->size.imw * rh) / sd->size.imh;
1621 if (sd->size.imw > sd->size.imh)
1622 z = (double)sd->size.imw / pw;
1624 z = (double)sd->size.imh / ph;
1632 else if (sd->mode == ELM_PHOTOCAM_ZOOM_MODE_AUTO_FIT_IN)
1634 if ((sd->size.imw < 1) || (sd->size.imh < 1))
1639 else if ((sd->size.imw < rw) && (sd->size.imh < rh))
1641 if (1 != sd->zoom) zoom_changed = 1;
1643 sd->size.nw = sd->size.imw;
1644 sd->size.nh = sd->size.imh;
1648 ph = (sd->size.imh * rw) / sd->size.imw;
1651 pw = (sd->size.imw * rh) / sd->size.imh;
1656 if (sd->size.imw > sd->size.imh)
1657 z = (double)sd->size.imw / pw;
1659 z = (double)sd->size.imh / ph;
1668 if (sd->main_load_pending)
1670 sd->size.w = sd->size.nw;
1671 sd->size.h = sd->size.nh;
1676 EINA_LIST_FOREACH(sd->grids, l, g)
1678 if (g->zoom == _grid_zoom_calc(sd->zoom))
1680 sd->grids = eina_list_remove(sd->grids, g);
1681 sd->grids = eina_list_prepend(sd->grids, g);
1687 g = _grid_create(obj);
1690 if (eina_list_count(sd->grids) > 1)
1692 g_zoom = eina_list_last(sd->grids)->data;
1693 sd->grids = eina_list_remove(sd->grids, g_zoom);
1694 _grid_clear(obj, g_zoom);
1696 EINA_LIST_FOREACH(sd->grids, l, g_zoom)
1701 sd->grids = eina_list_prepend(sd->grids, g);
1705 EINA_LIST_FREE (sd->grids, g)
1707 _grid_clear(obj, g);
1713 sd->t_start = ecore_loop_time_get();
1714 sd->t_end = sd->t_start + _elm_config->zoom_friction;
1715 if ((sd->size.w > 0) && (sd->size.h > 0))
1717 sd->size.spos.x = (double)(rx + (rw / 2)) / (double)sd->size.w;
1718 sd->size.spos.y = (double)(ry + (rh / 2)) / (double)sd->size.h;
1722 sd->size.spos.x = 0.5;
1723 sd->size.spos.y = 0.5;
1725 if (rw > sd->size.w) sd->size.spos.x = 0.5;
1726 if (rh > sd->size.h) sd->size.spos.y = 0.5;
1727 if (sd->size.spos.x > 1.0) sd->size.spos.x = 1.0;
1728 if (sd->size.spos.y > 1.0) sd->size.spos.y = 1.0;
1736 if (!sd->zoom_animator)
1738 sd->zoom_animator = ecore_animator_add(_zoom_anim_cb, obj);
1740 if (sd->no_smooth == 1) _smooth_update(obj);
1745 an = sd->zoom_animator;
1748 if (!_zoom_anim_cb(obj))
1750 ecore_animator_del(an);
1755 if (sd->calc_job) ecore_job_del(sd->calc_job);
1756 sd->calc_job = ecore_job_add(_calc_job_cb, sd);
1760 evas_object_smart_callback_call(obj, SIG_ZOOM_START, NULL);
1762 evas_object_smart_callback_call(obj, SIG_ZOOM_STOP, NULL);
1765 evas_object_smart_callback_call(obj, SIG_ZOOM_CHANGE, NULL);
1769 elm_photocam_zoom_get(const Evas_Object *obj)
1771 ELM_PHOTOCAM_CHECK(obj) 1.0;
1772 ELM_PHOTOCAM_DATA_GET(obj, sd);
1778 elm_photocam_zoom_mode_set(Evas_Object *obj,
1779 Elm_Photocam_Zoom_Mode mode)
1783 ELM_PHOTOCAM_CHECK(obj);
1784 ELM_PHOTOCAM_DATA_GET(obj, sd);
1786 if (sd->mode == mode) return;
1791 elm_photocam_zoom_set(ELM_WIDGET_DATA(sd)->obj, tz);
1794 EAPI Elm_Photocam_Zoom_Mode
1795 elm_photocam_zoom_mode_get(const Evas_Object *obj)
1797 ELM_PHOTOCAM_CHECK(obj) ELM_PHOTOCAM_ZOOM_MODE_LAST;
1798 ELM_PHOTOCAM_DATA_GET(obj, sd);
1804 elm_photocam_image_size_get(const Evas_Object *obj,
1808 ELM_PHOTOCAM_CHECK(obj);
1809 ELM_PHOTOCAM_DATA_GET(obj, sd);
1811 if (w) *w = sd->size.imw;
1812 if (h) *h = sd->size.imh;
1816 elm_photocam_image_region_get(const Evas_Object *obj,
1822 Evas_Coord sx, sy, sw, sh;
1824 ELM_PHOTOCAM_CHECK(obj);
1825 ELM_PHOTOCAM_DATA_GET(obj, sd);
1827 sd->s_iface->content_pos_get(obj, &sx, &sy);
1828 sd->s_iface->content_viewport_size_get(obj, &sw, &sh);
1833 *x = (sd->size.imw * sx) / sd->size.w;
1834 if (*x > sd->size.imw) *x = sd->size.imw;
1838 *w = (sd->size.imw * sw) / sd->size.w;
1839 if (*w > sd->size.imw) *w = sd->size.imw;
1854 *y = (sd->size.imh * sy) / sd->size.h;
1855 if (*y > sd->size.imh) *y = sd->size.imh;
1859 *h = (sd->size.imh * sh) / sd->size.h;
1860 if (*h > sd->size.imh) *h = sd->size.imh;
1873 elm_photocam_image_region_show(Evas_Object *obj,
1881 ELM_PHOTOCAM_CHECK(obj);
1882 ELM_PHOTOCAM_DATA_GET(obj, sd);
1884 if ((sd->size.imw < 1) || (sd->size.imh < 1)) return;
1885 rx = (x * sd->size.w) / sd->size.imw;
1886 ry = (y * sd->size.h) / sd->size.imh;
1887 rw = (w * sd->size.w) / sd->size.imw;
1888 rh = (h * sd->size.h) / sd->size.imh;
1891 if ((rx + rw) > sd->size.w) rx = sd->size.w - rw;
1892 if ((ry + rh) > sd->size.h) ry = sd->size.h - rh;
1893 if (sd->g_layer_zoom.bounce.animator)
1895 ecore_animator_del(sd->g_layer_zoom.bounce.animator);
1896 sd->g_layer_zoom.bounce.animator = NULL;
1899 if (sd->zoom_animator)
1902 ecore_animator_del(sd->zoom_animator);
1903 sd->zoom_animator = NULL;
1905 evas_object_smart_callback_call(obj, SIG_ZOOM_STOP, NULL);
1907 sd->s_iface->content_region_show(obj, rx, ry, rw, rh);
1911 elm_photocam_image_region_bring_in(Evas_Object *obj,
1919 ELM_PHOTOCAM_CHECK(obj);
1920 ELM_PHOTOCAM_DATA_GET(obj, sd);
1922 if ((sd->size.imw < 1) || (sd->size.imh < 1)) return;
1923 rx = (x * sd->size.w) / sd->size.imw;
1924 ry = (y * sd->size.h) / sd->size.imh;
1925 rw = (w * sd->size.w) / sd->size.imw;
1926 rh = (h * sd->size.h) / sd->size.imh;
1929 if ((rx + rw) > sd->size.w) rx = sd->size.w - rw;
1930 if ((ry + rh) > sd->size.h) ry = sd->size.h - rh;
1931 if (sd->g_layer_zoom.bounce.animator)
1933 ecore_animator_del(sd->g_layer_zoom.bounce.animator);
1934 sd->g_layer_zoom.bounce.animator = NULL;
1937 if (sd->zoom_animator)
1940 if (!sd->no_smooth) _smooth_update(obj);
1941 ecore_animator_del(sd->zoom_animator);
1942 sd->zoom_animator = NULL;
1944 evas_object_smart_callback_call(obj, SIG_ZOOM_STOP, NULL);
1946 sd->s_iface->region_bring_in(obj, rx, ry, rw, rh);
1950 elm_photocam_paused_set(Evas_Object *obj,
1953 ELM_PHOTOCAM_CHECK(obj);
1954 ELM_PHOTOCAM_DATA_GET(obj, sd);
1958 if (sd->paused == paused) return;
1959 sd->paused = paused;
1960 if (!sd->paused) return;
1962 if (sd->g_layer_zoom.bounce.animator)
1964 ecore_animator_del(sd->g_layer_zoom.bounce.animator);
1965 sd->g_layer_zoom.bounce.animator = NULL;
1968 if (sd->zoom_animator)
1970 ecore_animator_del(sd->zoom_animator);
1971 sd->zoom_animator = NULL;
1973 evas_object_smart_callback_call(obj, SIG_ZOOM_STOP, NULL);
1978 elm_photocam_paused_get(const Evas_Object *obj)
1980 ELM_PHOTOCAM_CHECK(obj) EINA_FALSE;
1981 ELM_PHOTOCAM_DATA_GET(obj, sd);
1987 elm_photocam_internal_image_get(const Evas_Object *obj)
1989 ELM_PHOTOCAM_CHECK(obj) NULL;
1990 ELM_PHOTOCAM_DATA_GET(obj, sd);
1996 elm_photocam_bounce_set(Evas_Object *obj,
2000 ELM_PHOTOCAM_CHECK(obj);
2001 ELM_PHOTOCAM_DATA_GET(obj, sd);
2003 sd->s_iface->bounce_allow_set(obj, h_bounce, v_bounce);
2007 elm_photocam_bounce_get(const Evas_Object *obj,
2008 Eina_Bool *h_bounce,
2009 Eina_Bool *v_bounce)
2011 ELM_PHOTOCAM_CHECK(obj);
2012 ELM_PHOTOCAM_DATA_GET(obj, sd);
2014 sd->s_iface->bounce_allow_get(obj, h_bounce, v_bounce);
2018 elm_photocam_gesture_enabled_set(Evas_Object *obj,
2021 ELM_PHOTOCAM_CHECK(obj);
2022 ELM_PHOTOCAM_DATA_GET(obj, sd);
2024 gesture = !!gesture;
2026 if (sd->do_gesture == gesture) return;
2028 sd->do_gesture = gesture;
2032 evas_object_del(sd->g_layer);
2036 if (!gesture) return;
2038 sd->g_layer = elm_gesture_layer_add(obj);
2039 if (!sd->g_layer) return;
2041 elm_gesture_layer_attach(sd->g_layer, obj);
2042 elm_gesture_layer_cb_set
2043 (sd->g_layer, ELM_GESTURE_ZOOM, ELM_GESTURE_STATE_START,
2044 _g_layer_zoom_start_cb, sd);
2045 elm_gesture_layer_cb_set
2046 (sd->g_layer, ELM_GESTURE_ZOOM, ELM_GESTURE_STATE_MOVE,
2047 _g_layer_zoom_move_cb, sd);
2048 elm_gesture_layer_cb_set
2049 (sd->g_layer, ELM_GESTURE_ZOOM, ELM_GESTURE_STATE_END,
2050 _g_layer_zoom_end_cb, sd);
2051 elm_gesture_layer_cb_set
2052 (sd->g_layer, ELM_GESTURE_ZOOM, ELM_GESTURE_STATE_ABORT,
2053 _g_layer_zoom_end_cb, sd);
2057 elm_photocam_gesture_enabled_get(const Evas_Object *obj)
2059 ELM_PHOTOCAM_CHECK(obj) EINA_FALSE;
2060 ELM_PHOTOCAM_DATA_GET(obj, sd);
2062 return sd->do_gesture;