2 * Copyright 2012 Samsung Electronics Co., Ltd
4 * Licensed under the Flora License, Version 1.1 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://floralicense.org/license/
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
16 #include <Elementary.h>
18 #include "ivug-define.h"
20 #include "ivug-setas-view-callerid.h"
21 #include "ivug-setas-view.h"
23 #include "ivug-selectioninfo.h"
25 #include "ivug-image.h"
26 #include "ivug-drm-common.h"
28 #include "ivug-scissorbox.h"
32 #define EDJ_PATH PREFIX"/res/edje/"PACKAGE
34 #define SETAS_EDJ_FILE EDJ_PATH"/ivug-setas.edj"
36 #define CLICK_TIME_MAX (500) // click time.
37 #define CLICK_WIDTH_MIN (elm_config_finger_size_get() >> 1) //click width, if mouse move under this value and under click time, it is click.
38 #define CLICK_INTERVAL_TIME 0.15
40 /* it is temp define, because scroll, scroll,anim,end is called earlyer.
41 So find bound of scissor box again after SETAS_INTERVAL_TIME */
42 #define SETAS_INTERVAL_TIME 0.1
43 #define SETAS_INTERVAL_TIME_FIRST_LOAD 0.3
45 #define CROP_BOX_INTERVAL_TIME 0.3
50 Evas_Object *notify_area;
51 Evas_Object *photocam;
53 Evas_Object *contents_area;
59 bool bShowMenu; // Current state for button's visibility
64 Evas_Coord_Rectangle rect;
75 Eina_Bool bAspectPreserve;
78 Ecore_Timer *box_timer;
82 #define SETAS_DATA(obj) \
83 (TSetAsData *)evas_object_data_get((Evas_Object *)(obj), "pSetAsData")
85 static void _on_moved(void *data, Evas *e, Evas_Object *obj, void *event_info);
86 static void _on_resized(void *data, Evas *e, Evas_Object *obj, void *event_info);
88 static void _put_scissorbox_default(TSetAsData *pSetAsData)
90 Evas_Object *image = ivug_image_internal_image_get(pSetAsData->photocam);
94 double ratio = pSetAsData->crop.ratio;
95 Evas_Coord_Rectangle rect = {0,};
97 ivug_image_image_size_get(pSetAsData->photocam, &image_w, &image_h); // Get original image size.
99 /*int degree = ivug_image_rotate_get(pSetAsData->photocam);
100 if(degree == 90 || degree == 270) //rotated
107 int lcd_x, lcd_y, lcd_w, lcd_h;
109 evas_object_geometry_get(pSetAsData->contents_area, &lcd_x, &lcd_y, &lcd_w, &lcd_h);
110 MSG_SETAS_HIGH("lcd_x=%d, lcd_y=%d, lcd_w=%d, lcd_h=%d", lcd_x, lcd_y, lcd_w, lcd_h);
113 ivug_image_region_get(pSetAsData->photocam, &px, &py, &pw, &ph);
115 px = (lcd_w - pw) / 2; // do not use previous px, px is invalid because transition effect
117 MSG_SETAS_WARN("region XYWH(%d,%d,%d,%d)", px, py, pw, ph);
121 if ( image_w > image_h ) // Landscape image
123 if(ratio > 1.0) // height is larger
125 iw = image_h / (2 * ratio);
131 ih = (image_h * ratio) / 2;
136 if(ratio > 1.0) // height is larger
138 iw = image_w / (2 * ratio);
144 ih = (image_w * ratio) / 2;
148 ix = (image_w - iw)/2;
149 iy = (image_h - ih)/2;
152 rect.x = (double)ix * pw / image_w + px;
153 rect.y = (double)iy * ph / image_h + py;
155 rect.w = (double)iw * pw / image_w;
156 rect.h = (double)ih * ph / image_h;
158 MSG_SETAS_WARN("Zoom Put Box in LCD XYWH(%d,%d,%d,%d)",
159 rect.x, rect.y, rect.w, rect.h);
161 ivug_scissorbox_region_set(pSetAsData->crop.box, rect.x, rect.y, rect.w, rect.h);
163 ivug_scissorbox_attach(pSetAsData->crop.box, image); // Attach to photocam
165 ivug_scissorbox_boundary_set(pSetAsData->crop.box, px, py, pw, ph);
167 pSetAsData->prev_x = px; //lcd_x is wrong because transition effect
168 pSetAsData->prev_y = py;
169 pSetAsData->prev_w = pw;
170 pSetAsData->prev_h = ph;
173 static Eina_Bool _put_scissorbox_timer_cb(void *data)
175 TSetAsData *pSetAsData = SETAS_DATA(data);
177 pSetAsData->box_timer = NULL;
179 _put_scissorbox_default(pSetAsData);
181 elm_object_disabled_set(pSetAsData->btn_ok, EINA_FALSE);
183 return ECORE_CALLBACK_CANCEL;
188 _on_btn_ok_clicked(void *data, Evas_Object *obj, void *event_info)
190 TSetAsData *pSetAsData = SETAS_DATA(data);
191 IV_ASSERT(pSetAsData != NULL);
193 MSG_SETAS_HIGH("OK button clicked");
194 evas_object_smart_callback_call(pSetAsData->layout, "ok,clicked", NULL);
196 evas_object_event_callback_del_full(pSetAsData->layout, EVAS_CALLBACK_MOVE, _on_moved, pSetAsData->layout);
197 evas_object_event_callback_del_full(pSetAsData->layout, EVAS_CALLBACK_RESIZE, _on_resized, pSetAsData->layout);
199 if ( pSetAsData->crop.box )
201 evas_object_del(pSetAsData->crop.box);
202 pSetAsData->crop.box = NULL;
208 _on_photocam_loaded(void *data, Evas_Object *obj, void *event_info)
210 TSetAsData *pSetAsData = SETAS_DATA(data);
211 MSG_SETAS_HIGH("Photocam preloaded");
214 typedef enum _Evas_Load_Error
216 EVAS_LOAD_ERROR_NONE = 0, /**< No error on load */
217 EVAS_LOAD_ERROR_GENERIC = 1, /**< A non-specific error occurred */
218 EVAS_LOAD_ERROR_DOES_NOT_EXIST = 2, /**< File (or file path) does not exist */
219 EVAS_LOAD_ERROR_PERMISSION_DENIED = 3, /**< Permission deinied to an existing file (or path) */
220 EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED = 4, /**< Allocation of resources failure prevented load */
221 EVAS_LOAD_ERROR_CORRUPT_FILE = 5, /**< File corrupt (but was detected as a known format) */
222 EVAS_LOAD_ERROR_UNKNOWN_FORMAT = 6 /**< File is not a known format */
223 } Evas_Load_Error; /**< Load error you can get from loading of files - see evas_load_error_str() too */
226 Evas_Load_Error error = static_cast<Evas_Load_Error>((int)event_info);
228 if ( error != EVAS_LOAD_ERROR_NONE )
230 MSG_SETAS_ERROR("Error occured during decoding. Error=%d", error);
232 if ( error == EVAS_LOAD_ERROR_UNKNOWN_FORMAT )
234 evas_object_smart_callback_call(pSetAsData->layout, "load,failed", (void *)SETAS_ERROR_TYPE_UNKNOWN_FORMAT);
236 else if ( error == EVAS_LOAD_ERROR_PERMISSION_DENIED )
238 evas_object_smart_callback_call(pSetAsData->layout, "load,failed", (void *)SETAS_ERROR_TYPE_PERMISSION_DENIED);
242 evas_object_smart_callback_call(pSetAsData->layout, "load,failed", (void *)SETAS_ERROR_TYPE_INVALID_FILE);
248 MSG_SETAS_HIGH("Photocam loaded.");
250 pSetAsData->box_timer = ecore_timer_add(CROP_BOX_INTERVAL_TIME, _put_scissorbox_timer_cb, (void *)pSetAsData->layout);
252 evas_object_smart_callback_call(pSetAsData->layout, "loaded", NULL);
254 pSetAsData->notify_area = const_cast<Evas_Object *>(edje_object_part_object_get(_EDJ(pSetAsData->layout),
255 "setasview.contents.swallow.notify"));
257 pSetAsData->notify = ivug_notify_static_create(pSetAsData->notify_area, IDS_CALLER_ID_NOTIFY, NOTIFY_ALIGN_BOTTOM);
261 static void _on_moved(void *data, Evas *e, Evas_Object *obj, void *event_info)
263 // TSetAsData *pSetAsData = SETAS_DATA(data);
267 static void _on_resized(void *data, Evas *e, Evas_Object *obj, void *event_info)
269 TSetAsData *pSetAsData = SETAS_DATA(data);
270 ///////////////////////////////////////////////////////////////////
271 int org_x, org_y, org_w, org_h;
273 MSG_SETAS_MED("prev_x=%d, prev_y=%d, prev_w=%d, prev_h=%d", pSetAsData->prev_x, pSetAsData->prev_y, pSetAsData->prev_w, pSetAsData->prev_h);
275 org_x = pSetAsData->prev_x;
276 org_y = pSetAsData->prev_y;
277 org_w = pSetAsData->prev_w;
278 org_h = pSetAsData->prev_h;
280 if(org_w == 0 || org_h == 0)
283 int org_sx, org_sy, org_sw, org_sh;
284 ivug_scissorbox_region_get(pSetAsData->crop.box, &org_sx, &org_sy, &org_sw, &org_sh);
286 MSG_SETAS_MED("org_sx=%d, org_sy=%d, org_sw=%d, org_sh=%d", org_sx, org_sy, org_sw, org_sh);
288 int dx = org_sx-org_x;
289 int dy = org_sy-org_y;
291 int lcd_x, lcd_y, lcd_w, lcd_h;
293 evas_object_geometry_get(pSetAsData->contents_area, &lcd_x, &lcd_y, &lcd_w, &lcd_h);
294 MSG_SETAS_MED("lcd_x=%d, lcd_y=%d, lcd_w=%d, lcd_h=%d", lcd_x, lcd_y, lcd_w, lcd_h);
306 ph = (img_h * ext_w) / img_w;
310 pw = (img_w * ext_h) / img_h;
322 zoom = (double)pw / img_w;
326 zoom = (double)ph / img_h;
336 sx = lcd_x + (ext_w-img_w*zoom)/2 + dx;
337 sy = lcd_y + (ext_h-img_h*zoom)/2 + dy;
340 int bound_x, bound_y, bound_w, bound_h;
342 bound_x = lcd_x+(ext_w-img_w*zoom)/2;
343 bound_y = lcd_y+(ext_h-img_h*zoom)/2;
344 bound_w = img_w*zoom;
345 bound_h = img_h*zoom;
347 ivug_scissorbox_boundary_set(pSetAsData->crop.box, bound_x, bound_y, bound_w, bound_h);
349 ///////////////////////////////////////////////////////////////////
351 MSG_SETAS_MED("sx=%d, sy=%d, sw=%d, sh=%d", sx, sy, sw, sh);
353 ivug_scissorbox_region_set(pSetAsData->crop.box, sx, sy, sw, sh);
355 pSetAsData->prev_x = bound_x;
356 pSetAsData->prev_y = bound_y;
357 pSetAsData->prev_w = bound_w;
358 pSetAsData->prev_h = bound_h;
360 MSG_SETAS_MED("prev_x=%d, prev_y=%d, prev_w=%d, prev_h=%d", pSetAsData->prev_x, pSetAsData->prev_y, pSetAsData->prev_w, pSetAsData->prev_h);
363 static Evas_Event_Flags _finger_tap_end(void *data , void *event_info)
365 Elm_Gesture_Taps_Info *p = (Elm_Gesture_Taps_Info *) event_info;
367 MSG_SETAS_HIGH("Finger tab end. evt=%d", p->timestamp);
369 if ( p->n != 1 ) return EVAS_EVENT_FLAG_NONE;
371 TSetAsData *pSetAsData = (TSetAsData *)data;
372 IV_ASSERT(pSetAsData != NULL);
374 if(pSetAsData->bShowMenu)
376 MSG_SETAS_HIGH("Hide");
377 elm_win_indicator_mode_set((Evas_Object*)ug_get_window(), ELM_WIN_INDICATOR_HIDE);
378 evas_object_hide(pSetAsData->notify);
382 MSG_SETAS_HIGH("Show");
383 if(gIsDesktopMode() == false)
385 elm_win_indicator_mode_set((Evas_Object *)ug_get_window(), ELM_WIN_INDICATOR_SHOW);
387 evas_object_show(pSetAsData->notify);
390 pSetAsData->bShowMenu = !pSetAsData->bShowMenu;
392 return EVAS_EVENT_FLAG_NONE;
395 void _add_gesture_layer(Evas_Object *parent, TSetAsData *pSetAsData)
397 IV_ASSERT(pSetAsData != NULL);
399 Evas_Object *gesture = pSetAsData->gesture;
401 gesture = elm_gesture_layer_add(parent);
402 elm_gesture_layer_hold_events_set(gesture, EINA_FALSE);
404 elm_gesture_layer_cb_set(gesture, ELM_GESTURE_N_TAPS, ELM_GESTURE_STATE_END, _finger_tap_end, (void *)pSetAsData);
406 if ( elm_gesture_layer_attach(gesture, pSetAsData->photocam) == EINA_FALSE)
408 MSG_SETAS_ERROR("Cannot attach event rect");
411 evas_object_name_set(gesture, "CallerID:Getsture");
414 Evas_Object *_ivug_setas_callerid_create_layout(Evas_Object *parent)
416 TSetAsData *pSetAsData = (TSetAsData *)calloc(1, sizeof(TSetAsData));
418 if ( pSetAsData == NULL )
420 MSG_SETAS_ERROR("Cannot alloc pSetasData");
424 Evas_Object *photocam = NULL;
426 pSetAsData->layout = ivug_layout_add2(parent, SETAS_EDJ_FILE, "setas_view");
427 if ( pSetAsData->layout == NULL )
429 MSG_SETAS_ERROR("Cannot create layout.");
433 MSG_SETAS_HIGH("Create setas layout");
434 pSetAsData->contents_area = ivug_default_layout_add(parent);
435 evas_object_name_set(pSetAsData->contents_area, "contets_area");
436 if ( pSetAsData->contents_area == NULL )
438 MSG_SETAS_ERROR("Cannot create contets_area.");
441 elm_object_part_content_set(pSetAsData->layout, "setasview.contents.swallow", pSetAsData->contents_area);
443 pSetAsData->crop.box = ivug_scissorbox_add(pSetAsData->contents_area);
445 if ( pSetAsData->crop.box == NULL )
447 MSG_SETAS_ERROR("Cannot create layout.");
451 evas_object_smart_member_add(pSetAsData->crop.box, pSetAsData->layout);
453 photocam = ivug_image_create(pSetAsData->layout);
454 ivug_image_animated_set(photocam, EINA_FALSE); // Show first frame only when AGIF
455 ivug_image_hold_set(photocam , EINA_TRUE); // Disable mouse events
457 evas_object_name_set(photocam, "setas_photocam");
459 pSetAsData->photocam = photocam;
461 evas_object_smart_callback_add(photocam, "loaded", _on_photocam_loaded, (void *)pSetAsData->layout);
462 elm_object_part_content_set(pSetAsData->layout, "setasview.photocam", photocam);
463 evas_object_show(photocam);
465 pSetAsData->bShowMenu = true;
466 //_add_gesture_layer(pSetAsData->layout, pSetAsData);
468 evas_object_data_set(pSetAsData->layout, "pSetAsData", pSetAsData);
469 evas_object_event_callback_add(pSetAsData->layout, EVAS_CALLBACK_MOVE, _on_moved, pSetAsData->layout);
470 evas_object_event_callback_add(pSetAsData->layout, EVAS_CALLBACK_RESIZE, _on_resized, pSetAsData->layout);
472 return pSetAsData->layout;
475 if ( pSetAsData->crop.box )
476 evas_object_del(pSetAsData->crop.box);
478 if ( pSetAsData->layout )
479 evas_object_del(pSetAsData->layout);
487 Evas_Object *_ivug_setas_callerid_delete_layout(Evas_Object *obj)
489 TSetAsData *pSetAsData = SETAS_DATA(obj);
490 IV_ASSERT(pSetAsData != NULL);
492 if(pSetAsData->box_timer)
494 ecore_timer_del(pSetAsData->box_timer);
495 pSetAsData->box_timer = NULL;
498 if(pSetAsData->photocam)
500 MSG_SETAS_HIGH("Removing photocam");
501 evas_object_del(pSetAsData->photocam);
502 pSetAsData->photocam = NULL;
505 if(pSetAsData->notify)
507 evas_object_del(pSetAsData->notify);
508 pSetAsData->notify = NULL;
511 if(pSetAsData->contents_area)
513 evas_object_del(pSetAsData->contents_area);
514 pSetAsData->contents_area = NULL;
517 if(pSetAsData->layout)
519 evas_object_event_callback_del_full(pSetAsData->layout, EVAS_CALLBACK_MOVE, _on_moved, pSetAsData->layout);
520 evas_object_event_callback_del_full(pSetAsData->layout, EVAS_CALLBACK_RESIZE, _on_resized, pSetAsData->layout);
521 evas_object_del(pSetAsData->layout);
522 pSetAsData->layout = NULL;
525 if(pSetAsData->crop.box)
527 evas_object_del(pSetAsData->crop.box);
528 pSetAsData->crop.box = NULL;
530 if(pSetAsData->filepath)
532 free(pSetAsData->filepath);
533 pSetAsData->filepath = NULL;
536 if(pSetAsData->drm_filepath)
538 ivug_remove_file(pSetAsData->drm_filepath);
539 free(pSetAsData->drm_filepath);
540 pSetAsData->drm_filepath = NULL;
543 if(pSetAsData->btn_ok)
545 evas_object_del(pSetAsData->btn_ok);
546 pSetAsData->btn_ok = NULL;
554 bool _ivug_setas_callerid_load_file(Evas_Object *obj, const char *filepath)
556 TSetAsData *pSetAsData = SETAS_DATA(obj);
558 MSG_SETAS_HIGH("Load image file : %s", filepath);
560 pSetAsData->filepath = strdup(filepath);
562 Evas_Load_Error error = EVAS_LOAD_ERROR_NONE;
563 error = ivug_image_file_set(pSetAsData->photocam, filepath, "noAnim");
565 if ( error != EVAS_LOAD_ERROR_NONE )
567 MSG_SETAS_ERROR("FileSet Error=%d", error);
569 if ( error == EVAS_LOAD_ERROR_UNKNOWN_FORMAT )
571 evas_object_smart_callback_call(pSetAsData->layout, "load,failed", (void *)SETAS_ERROR_TYPE_UNKNOWN_FORMAT);
574 else if ( error == EVAS_LOAD_ERROR_PERMISSION_DENIED )
576 evas_object_smart_callback_call(pSetAsData->layout, "load,failed", (void *)SETAS_ERROR_TYPE_PERMISSION_DENIED);
581 evas_object_smart_callback_call(pSetAsData->layout, "load,failed", (void *)SETAS_ERROR_TYPE_INVALID_FILE);
591 Evas_Object *_ivug_setas_callerid_internal_image_get(Evas_Object *obj)
593 TSetAsData *pSetAsData = SETAS_DATA(obj);
595 MSG_SETAS_HIGH("Internal image get!");
597 return pSetAsData->photocam;
600 bool _ivug_setas_callerid_select_region_get(Evas_Object *obj, int *x, int *y, int *w, int *h)
602 TSetAsData *pSetAsData = SETAS_DATA(obj);
604 if ( pSetAsData->crop.box == NULL)
609 ivug_scissorbox_region_get(pSetAsData->crop.box, x, y, w, h);
615 void _ivug_setas_callerid_aspect_ratio_set(Evas_Object *obj, double ratio)
617 TSetAsData *pSetAsData = SETAS_DATA(obj);
619 pSetAsData->crop.bAspectPreserve = TRUE;
620 pSetAsData->crop.ratio = ratio;
622 ivug_scissorbox_ratio_fix( pSetAsData->crop.box, EINA_TRUE);
625 void _ivug_setas_callerid_create_menu(Evas_Object *obj, Evas_Object *navi_bar)
627 TSetAsData *pSetAsData = SETAS_DATA(obj);
629 pSetAsData->btn_ok = ivug_button_add(navi_bar, "naviframe/toolbar/default",
630 IDS_SAVE, NULL, _on_btn_ok_clicked, (void *)pSetAsData->layout);
632 Elm_Object_Item *navi_it = elm_naviframe_top_item_get(navi_bar);
633 elm_object_item_part_content_set(navi_it, "toolbar_button1", pSetAsData->btn_ok);
635 elm_object_disabled_set(pSetAsData->btn_ok, EINA_TRUE);