2 * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
4 * Licensed under the Apache License, Version 2.0 (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://www.apache.org/licenses/LICENSE-2.0
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.
17 #include <AppCommon.h>
20 #include "timeout_handler.h"
21 #include "mediainfo.h"
22 #include "mediadata.h"
24 #include "photoviewer_view.h"
25 #include "zoom_view.h"
26 #include "SettingCtxPopup.h"
28 #define MAX_PREVIEWBAR_IMG 7
29 #define PREVIEWBAR_CENTER_IDX 3
30 #define SLIDESHOW_BTN_IDX 2
34 #define IMAGE_PREVIEWBAR_BORDER IMAGEDIR"/zoom_navigator.png"
36 double slideshow_timeout[] = {
37 TIMEOUT_SLIDESHOW_NORMAL,
38 TIMEOUT_SLIDESHOW_SLOW,
39 TIMEOUT_SLIDESHOW_FAST
42 enum _slideshow_state {
47 enum _slideshow_speed {
48 SETTING_SPEED_NORMAL = 0,
58 struct SPhotoViewerView {
61 Evas_Object *btn[MAX_PHOTO_ICONS];
62 Evas_Object *focusedbtn;
69 Evas_Object *photocam;
72 Ecore_Timer *tooltip_timer;
74 CTimeoutHandler cTimeoutHandler;
76 Ecore_Timer *slideshow_timer;
82 CContextPopup *pCtxPopup;
84 Ecore_Timer *focus_timer;
100 slideshow_timer = NULL;
111 ~SPhotoViewerView() {}
114 void CPhotoViewerView::sm_CbPrevBtnClicked(void *dt, Evas_Object *obj,
115 const char *emission, const char *source)
117 CPhotoViewerView* root = (CPhotoViewerView*)dt;
120 root->m_OnPrevBtnClicked(obj, emission, source);
124 void CPhotoViewerView::m_OnPrevBtnClicked(Evas_Object *obj,
125 const char *emission, const char *source)
127 Eina_List *current_list, *prev_list;
133 current_list = eina_list_data_find_list(m->vd->media_list,
138 /* if first photo, show last photo */
139 prev_list = eina_list_prev(current_list);
141 prev_list = eina_list_last(m->vd->media_list);
143 minfo = (CMediaInfo *)eina_list_data_get(prev_list);
145 if (!m_DrawContentArea(minfo))
148 if (!m_DrawTopArea(minfo))
151 m->vd->minfo = minfo;
155 void CPhotoViewerView::sm_CbNextBtnClicked(void *dt, Evas_Object *obj,
156 const char *emission, const char *source)
158 CPhotoViewerView* root = (CPhotoViewerView*)dt;
161 root->m_OnNextBtnClicked(obj, emission, source);
165 void CPhotoViewerView::m_OnNextBtnClicked(Evas_Object *obj,
166 const char *emission, const char *source)
168 Eina_List *current_list, *next_list;
174 current_list = eina_list_data_find_list(m->vd->media_list,
179 /* if last photo, show first photo */
180 next_list = eina_list_next(current_list);
182 next_list = m->vd->media_list;
184 minfo = (CMediaInfo *)eina_list_data_get(next_list);
186 if (!m_DrawContentArea(minfo))
189 if (!m_DrawTopArea(minfo))
192 m->vd->minfo = minfo;
196 void CPhotoViewerView::sm_CbSlideshowBtnClicked(void *dt, Evas_Object *obj,
197 const char *emission, const char *source)
199 CPhotoViewerView* root = (CPhotoViewerView*)dt;
202 root->m_OnSlideshowBtnClicked(obj, emission, source);
206 void CPhotoViewerView::m_OnSlideshowBtnClicked(Evas_Object *obj,
207 const char *emission, const char *source)
209 if (m->slideshow_state == STATE_PAUSE) {
210 if (m->slideshow_timer)
211 ecore_timer_reset(m->slideshow_timer);
213 m->slideshow_timer = ecore_timer_add(
214 slideshow_timeout[m->slideshow_speed],
215 sm_CbTimerSlideshow, this);
217 m->slideshow_state = STATE_PLAY;
220 if (m->slideshow_timer) {
221 ecore_timer_del(m->slideshow_timer);
222 m->slideshow_timer = NULL;
224 m->slideshow_state = STATE_PAUSE;
229 void CPhotoViewerView::sm_CbSettingBtnClicked(void *dt, Evas_Object *obj,
230 const char *emission, const char *source)
232 CPhotoViewerView *root = (CPhotoViewerView*)dt;
235 root->m_OnSettingBtnClicked(obj, emission, source);
239 void CPhotoViewerView::m_OnSettingBtnClicked(Evas_Object *obj,
240 const char *emission, const char *source)
242 if (m->pCtxPopup && m->pCtxPopup->FlagCreate())
245 elm_object_signal_emit(obj, "elm,action,highlight", "elm");
247 CSettingCtxPopup::SCallback cb;
249 cb.onSelected = sm_CbCtxPopupSelected;
251 CSettingCtxPopup *pCtxPopup = new CSettingCtxPopup;
252 m->pCtxPopup = pCtxPopup;
253 pCtxPopup->SetSlideshowSpeed(m->slideshow_speed);
254 pCtxPopup->Create(Base(), &cb);
260 void CPhotoViewerView::sm_CbZoomBtnClicked(void *dt, Evas_Object *obj,
261 const char *emission, const char *source)
263 CPhotoViewerView *root = (CPhotoViewerView*)dt;
266 root->m_OnZoomBtnClicked(obj, emission, source);
270 void CPhotoViewerView::m_OnZoomBtnClicked(Evas_Object *obj,
271 const char *emission, const char *source)
273 if (m->tooltip_timer)
276 if (!CViewMgr::GetInstance()->PushView(VIEW_PHOTO_ZOOM, m->vd->minfo))
277 _ERR("VIEW_PHOTO_ZOOM view create failed");
281 void CPhotoViewerView::sm_CbRotateBtnClicked(void *dt, Evas_Object *obj,
282 const char *emission, const char *source)
284 CPhotoViewerView *root = (CPhotoViewerView*)dt;
287 root->m_OnRotateBtnClicked(obj, emission, source);
291 void CPhotoViewerView::m_OnRotateBtnClicked(Evas_Object *obj,
292 const char *emission, const char *source)
295 Evas_Object *internalimage;
296 const char *file_path;
300 if (!m->vd || !m->vd->minfo)
303 minfo = m->vd->minfo;
305 file_path = minfo->Path();
309 image = elm_image_add(Base());
313 elm_image_file_set(image, file_path, NULL);
315 elm_image_object_size_get(image, &w, &h);
317 /* return temporarily to prevent crash
318 texture size is 4096 */
319 if (w >= 4096 || h >= 4096) {
320 _ERR("Rotation failed");
324 elm_image_orient_set(image, (Elm_Image_Orient)1);
326 internalimage = elm_image_object_get(image);
330 evas_object_image_save(internalimage, file_path,
331 NULL, "quality=100");
333 m_DrawContentArea(minfo);
334 m_DrawTopArea(minfo);
337 evas_object_del(image);
340 void CPhotoViewerView::sm_CbPhotocamLoaded(void *data, Evas_Object *obj, void *event_info)
342 CPhotoViewerView *root = (CPhotoViewerView *)data;
347 root->m_OnPhotocamLoaded(obj);
350 void CPhotoViewerView::sm_CbPhotocamLoadedDetail(void *data, Evas_Object *obj, void *event_info)
352 CPhotoViewerView *root = (CPhotoViewerView *)data;
357 root->m_OnPhotocamLoadedDetail(obj);
360 void CPhotoViewerView::m_OnPhotocamLoaded(Evas_Object *obj)
362 if (m->photocam != m->loading) {
363 if (m->photocam) evas_object_del(m->photocam);
367 elm_object_part_content_set(Base(), PART_CONTENTAREA, obj);
371 void CPhotoViewerView::m_OnPhotocamLoadedDetail(Evas_Object *obj)
376 Eina_Bool CPhotoViewerView::sm_CbTimerTooltip(void *cookie)
378 CPhotoViewerView *root = (CPhotoViewerView *)cookie;
380 Eina_Bool ret = ECORE_CALLBACK_CANCEL;
383 ret = root->m_OnTimerTooltip();
388 Eina_Bool CPhotoViewerView::m_OnTimerTooltip(void)
390 ecore_timer_del(m->tooltip_timer);
391 m->tooltip_timer = NULL;
393 elm_object_tooltip_hide(m->focusedbtn);
395 return ECORE_CALLBACK_CANCEL;
398 void CPhotoViewerView::sm_CbCtxPopupSelected(void *cookie,
399 CContextPopup *instance, const char *text)
401 CPhotoViewerView *root = (CPhotoViewerView *)cookie;
405 root->m_OnCtxPopupSelected(instance, text);
408 void CPhotoViewerView::m_OnCtxPopupSelected(CContextPopup *instance, const char *text)
412 for (i = 0; i < MAX_SPEED_BTNS; i++) {
413 if (!strcmp(speed_text[i], text))
417 if (i == MAX_SPEED_BTNS || i == m->slideshow_speed)
420 m->slideshow_speed = i;
422 if (m->slideshow_timer) {
423 ecore_timer_interval_set(m->slideshow_timer,
424 slideshow_timeout[m->slideshow_speed]);
425 ecore_timer_reset(m->slideshow_timer);
429 bool CPhotoViewerView::m_DrawContentArea(CMediaInfo *minfo)
431 const char *file_path;
434 if (!Base() || !minfo)
437 file_path = minfo->Path();
442 elm_photocam_file_set(m->loading, file_path);
444 elm_photocam_image_size_get(m->loading, &width, &height);
446 elm_photocam_zoom_mode_set(m->loading,
447 ELM_PHOTOCAM_ZOOM_MODE_AUTO_FIT);
449 elm_photocam_zoom_mode_set(m->loading,
450 ELM_PHOTOCAM_ZOOM_MODE_AUTO_FILL);
453 m->loading = elm_photocam_add(Base());
457 evas_object_smart_callback_add(m->loading, "loaded", sm_CbPhotocamLoaded, this);
458 evas_object_smart_callback_add(m->loading, "loaded,detail", sm_CbPhotocamLoadedDetail, this);
460 elm_photocam_file_set(m->loading, file_path);
462 elm_photocam_image_size_get(m->loading, &width, &height);
464 elm_photocam_zoom_mode_set(m->loading,
465 ELM_PHOTOCAM_ZOOM_MODE_AUTO_FIT);
467 elm_photocam_zoom_mode_set(m->loading,
468 ELM_PHOTOCAM_ZOOM_MODE_AUTO_FILL);
470 elm_object_focus_allow_set(m->loading, EINA_FALSE);
471 elm_scroller_policy_set(m->loading,
472 ELM_SCROLLER_POLICY_AUTO, ELM_SCROLLER_POLICY_AUTO);
479 bool CPhotoViewerView::m_DrawTopArea(CMediaInfo *minfo)
481 const char *display_name;
491 display_name = minfo->Name();
495 elm_object_part_text_set(Base(), PART_TITLETEXT, display_name);
497 created_time = minfo->CreatedTime();
498 if (created_time > 0) {
499 localtime_r(&created_time, &tm);
500 strftime(buf, sizeof(buf), "%Y.%m.%d", &tm);
502 snprintf(buf, sizeof(buf), "%s", _(TEXT_NODATE));
504 elm_object_part_text_set(Base(), PART_DATETEXT, buf);
506 elm_photocam_image_size_get(m->photocam, &width, &height);
507 snprintf(buf, sizeof(buf), "%d x %d", width, height);
508 elm_object_part_text_set(Base(), PART_RESOLUTIONTEXT, buf);
510 source = minfo->Source();
511 if (source == E_SOURCE_USB) {
512 elm_object_part_text_set(Base(), PART_SOURCETEXT, _("USB"));
514 elm_object_part_text_set(Base(), PART_SOURCETEXT, _("TV"));
517 snprintf(buf, sizeof(buf), "/%d", m->totalcount);
518 elm_object_part_text_set(Base(), PART_COUNTTEXT, buf);
520 m->current_idx = util_eina_list_get_index(m->vd->media_list, minfo);
521 snprintf(buf, sizeof(buf), "%d", m->current_idx + 1);
522 elm_object_part_text_set(Base(), PART_CURRENTTEXT, buf);
528 Eina_Bool CPhotoViewerView::sm_CbTimerSlideshow(void *dt)
530 sm_CbNextBtnClicked(dt, NULL, NULL, NULL);
532 return ECORE_CALLBACK_RENEW;
535 Evas_Object *CPhotoViewerView::m_AddTooltipBtn(Evas_Object *parent,
536 const char *style_text, const char *tt_text)
542 btn = elm_button_add(parent);
546 elm_object_style_set(btn, style_text);
547 elm_object_tooltip_text_set(btn, tt_text);
548 elm_object_tooltip_style_set(btn, STYLE_TOOLTIP);
549 elm_object_tooltip_orient_set(btn, ELM_TOOLTIP_ORIENT_TOP);
551 evas_object_show(btn);
556 bool CPhotoViewerView::m_DrawBottomArea(void)
560 Edje_Signal_Cb _edje_callback_function[] = {
563 sm_CbSlideshowBtnClicked,
564 sm_CbSettingBtnClicked,
566 sm_CbRotateBtnClicked,
568 static const char * const _source_name[] = {
580 for (i = 0; i < MAX_PHOTO_ICONS; i++) {
581 m->btn[i] = m_AddTooltipBtn(Base(), photo_icon_style[i], _(tooltip_text[i]));
583 for (j = 0; j < i; j++)
588 snprintf(buf, sizeof(buf), "part_btn%d", i);
589 elm_object_part_content_set(Base(), buf, m->btn[i]);
591 elm_object_signal_callback_add(m->btn[i], "btn,anim,finish",
592 _source_name[i], _edje_callback_function[i], this);
594 Connect(m->btn[i], PHOTOVIEWER_BTN,
595 TYPE_KEY_DOWN | TYPE_CLICKED |
596 TYPE_MOUSE_MOVE | TYPE_FOCUSED);
598 elm_object_focus_next_object_set(m->btn[i], m->btn[i], ELM_FOCUS_UP);
599 elm_object_focus_next_object_set(m->btn[i], m->btn[i], ELM_FOCUS_DOWN);
601 elm_object_focus_allow_set(m->btn[i], EINA_FALSE);
604 util_ui_set_focus_directions(m->btn,
605 MAX_PHOTO_ICONS, EINA_TRUE);
607 m->slideshow_state = STATE_PAUSE;
608 m->slideshow_speed = SETTING_SPEED_NORMAL;
613 void CPhotoViewerView::sm_CbShowMenuViewFinish(void *dt, Evas_Object *obj,
614 const char *emission, const char *source)
616 CPhotoViewerView *root = (CPhotoViewerView*)dt;
619 root->m_ShowMenuView();
623 void CPhotoViewerView::m_ShowMenuView(void)
627 for (i = 0; i < MAX_PHOTO_ICONS; i++) {
628 evas_object_freeze_events_set(m->btn[i], EINA_FALSE);
629 elm_object_focus_allow_set(m->btn[i], EINA_TRUE);
633 void CPhotoViewerView::m_HideMenuView(void)
637 for (i = 0; i < MAX_PHOTO_ICONS; i++) {
638 evas_object_freeze_events_set(m->btn[i], EINA_TRUE);
639 elm_object_focus_allow_set(m->btn[i], EINA_FALSE);
643 bool CPhotoViewerView::m_DrawItems(void)
648 if (!m_DrawContentArea(m->vd->minfo))
651 if (!m_DrawTopArea(m->vd->minfo))
654 if (!m_DrawBottomArea())
657 if (!m->cTimeoutHandler.Create(TIMEOUT_PHOTOVIEWER, this))
664 Eina_Bool CPhotoViewerView::sm_CbFocus(void *dt)
666 CPhotoViewerView *root = (CPhotoViewerView*)dt;
668 Eina_Bool ret = ECORE_CALLBACK_CANCEL;
671 ret = root->OnFocus();
676 Eina_Bool CPhotoViewerView::OnFocus(void)
680 /* set focus on Next button in photo viewer */
681 elm_object_focus_set(m->btn[1], EINA_TRUE);
683 return ECORE_CALLBACK_CANCEL;
686 bool CPhotoViewerView::Create(void *data, Evas_Object *eoBase)
693 win = CViewMgr::GetInstance()->Window();
696 m = new SPhotoViewerView;
700 base = elm_layout_add(win);
707 m->pViewMgr = CViewMgr::GetInstance();
711 if (!elm_layout_file_set(base, EDJEFILE, GRP_PHOTO_VIEWER))
715 m->vd = (struct view_data *)data;
716 m->totalcount = eina_list_count(m->vd->media_list);
718 CBaseView::Create(NULL, base);
723 elm_object_signal_callback_add(base, SIG_MENU_SHOW_FINISH, "",
724 sm_CbShowMenuViewFinish, this);
727 m->focus_timer = ecore_timer_add(0.25, sm_CbFocus, this);
732 _ERR("error in creating layout");
733 evas_object_del(base);
740 void CPhotoViewerView::Destroy()
746 for (i = 0; i < MAX_PHOTO_ICONS; i++)
747 Disconnect(m->btn[i]);
749 evas_object_del(Base());
751 CBaseView::Destroy();
753 m->cTimeoutHandler.Destroy();
755 if (m->tooltip_timer)
756 ecore_timer_del(m->tooltip_timer);
758 if (m->slideshow_timer)
759 ecore_timer_del(m->slideshow_timer);
762 ecore_timer_del(m->focus_timer);
764 eina_list_free(m->vd->media_list);
771 void CPhotoViewerView::t_OnShow(void)
775 evas_object_show(Base());
780 void CPhotoViewerView::t_OnHide(void)
784 evas_object_hide(Base());
790 void CPhotoViewerView::t_OnUpdate(void *data)
794 m->vd = (struct view_data *)data;
795 m->totalcount = eina_list_count(m->vd->media_list);
797 if (!m_DrawContentArea(m->vd->minfo))
800 if (!m_DrawTopArea(m->vd->minfo))
804 void CPhotoViewerView::t_OnPause(void)
808 if (m->pCtxPopup && m->pCtxPopup->FlagCreate()) {
809 m->pCtxPopup->Destroy();
814 if (m->tooltip_timer)
815 ecore_timer_freeze(m->tooltip_timer);
817 elm_object_tooltip_hide(m->focusedbtn);
819 if (m->slideshow_timer)
820 ecore_timer_freeze(m->slideshow_timer);
822 m->cTimeoutHandler.Pause();
825 void CPhotoViewerView::t_OnResume(void)
829 if (m->tooltip_timer)
830 ecore_timer_reset(m->tooltip_timer);
832 m->tooltip_timer = ecore_timer_add(TIMEOUT_TOOLTIP,
833 sm_CbTimerTooltip, this);
836 elm_object_tooltip_show(m->focusedbtn);
838 if (m->slideshow_timer)
839 ecore_timer_thaw(m->slideshow_timer);
841 m->cTimeoutHandler.Resume();
843 elm_object_focus_set(m->focusedbtn, EINA_TRUE);
847 void CPhotoViewerView::OnTimeout(void)
849 if (m->tooltip_timer)
852 if (m->pCtxPopup && m->pCtxPopup->FlagCreate()) {
853 m->pCtxPopup->Destroy();
858 elm_object_signal_emit(Base(), SIG_MENU_HIDE, "");
864 Eina_Bool CPhotoViewerView::OnEvent(int type, void *event_info)
872 if (type == ECORE_EVENT_KEY_UP) {
873 Evas_Event_Key_Up *ev = (Evas_Event_Key_Up *)event_info;
875 if (!strcmp(ev->keyname, KEY_LEFT))
876 sm_CbPrevBtnClicked(this, NULL, NULL, NULL);
877 else if (!strcmp(ev->keyname, KEY_RIGHT))
878 sm_CbNextBtnClicked(this, NULL, NULL, NULL);
879 else if (!strcmp(ev->keyname, KEY_UP)) {
880 if (m->slideshow_state == STATE_PAUSE) {
881 elm_object_signal_emit(Base(), SIG_MENU_SHOW, "");
884 } else if (!strcmp(ev->keyname, KEY_ENTER) ||
885 !strcmp(ev->keyname, KEY_ENTER_REMOTE)) {
886 if (m->slideshow_state == STATE_PAUSE) {
887 elm_object_signal_emit(Base(), SIG_MENU_SHOW, "");
890 } else if (!strcmp(ev->keyname, KEY_BACK) ||
891 !strcmp(ev->keyname, KEY_BACK_REMOTE)) {
892 if (m->slideshow_state == STATE_PLAY)
893 OnMouseClicked(PHOTOVIEWER_BTN,
894 m->btn[SLIDESHOW_BTN_IDX]);
896 elm_object_signal_emit(Base(), SIG_MENU_SHOW, "");
899 } else if (!strcmp(ev->keyname, KEY_MENU) ||
900 !strcmp(ev->keyname, KEY_MENU_REMOTE)) {
901 m->pViewMgr->PushView(VIEW_CTXT_MENU, m->vd);
905 if (m->slideshow_state == STATE_PLAY)
906 OnMouseClicked(PHOTOVIEWER_BTN,
907 m->btn[SLIDESHOW_BTN_IDX]);
909 elm_object_signal_emit(Base(), SIG_MENU_SHOW, "");
917 void CPhotoViewerView::OnSKeyDown(int id, Evas *e, Evas_Object *obj,
918 Evas_Event_SKey_Down *ev)
921 case PHOTOVIEWER_BTN:
924 m->pViewMgr->PopView();
925 if (CViewMgr::GetInstance()->CheckEmpty())
929 m->pViewMgr->PushView(VIEW_CTXT_MENU, m->vd);
933 m->cTimeoutHandler.Timeout();
944 void CPhotoViewerView::OnMouseClicked(int id, Evas_Object *obj)
947 case PHOTOVIEWER_BTN:
948 elm_object_signal_emit(obj, "mouse,anim,start", "");
955 void CPhotoViewerView::OnMouseMove(int id, Evas *e, Evas_Object *obj,
956 Evas_Event_Mouse_Move *ev)
959 case PHOTOVIEWER_BTN:
960 if (!elm_object_focus_get(obj))
961 elm_object_focus_set(obj, EINA_TRUE);
968 void CPhotoViewerView::OnFocused(int id, Evas_Object *obj, Elm_Object_Item *item)
971 case PHOTOVIEWER_BTN:
972 if (m->focusedbtn != obj) {
974 elm_object_tooltip_hide(m->focusedbtn);
976 elm_object_tooltip_show(obj);
981 if (m->tooltip_timer)
982 ecore_timer_reset(m->tooltip_timer);
984 m->tooltip_timer = ecore_timer_add(TIMEOUT_TOOLTIP,
985 sm_CbTimerTooltip, this);