From a7dc75acd4634ef69430c60ccb7b22067507af3d Mon Sep 17 00:00:00 2001 From: Jisung Ahn Date: Wed, 22 Aug 2012 13:50:48 +0900 Subject: [PATCH] add missing file Change-Id: Ic21b33793e72879be37296180ad43f19aa5785cb --- common/include/ivug-callback.h | 37 + common/include/ivug-config.h | 59 + common/include/ivug-db.h | 67 + common/include/ivug-drm.h | 92 + common/include/ivug-exif.h | 36 + common/include/ivug-file-info.h | 58 + common/include/ivug-message.h | 44 + common/include/ivug-util.h | 87 + common/include/ivug-uuid.h | 47 + common/src/ivug-callback.c | 50 + common/src/ivug-callback.c.bak | 51 + common/src/ivug-config.c | 223 ++ common/src/ivug-db.c | 417 +++ common/src/ivug-drm.c | 363 +++ common/src/ivug-exif.c | 1460 +++++++++ common/src/ivug-file-info.c | 740 +++++ common/src/ivug-message.c | 548 ++++ common/src/ivug-util.c | 353 +++ common/src/ivug-uuid.c | 96 + feature/CMakeLists.txt | 53 + feature/include/ivug-email.h | 50 + feature/include/ivug-ext-ug.h | 48 + feature/include/ivug-vibration.h | 49 + feature/src/ivug-ext-ug.c | 500 +++ feature/src/ivug-vibration.c | 118 + include/ivug-datatypes.h | 61 + include/ivug-define.h | 51 + main/layout/crop-view/T06_controlbar_bg.png | Bin 0 -> 114793 bytes main/layout/gengrid/00_winset_thumbs_bg.png | Bin 0 -> 3233 bytes main/layout/gengrid/00_winset_thumbs_focus_bg.png | Bin 0 -> 3145 bytes main/layout/icons/T01_btn_paused.png | Bin 0 -> 5941 bytes .../theme/blue/00_winset_control_toolbar_bg.png | Bin 0 -> 2798 bytes .../theme/blue/00_winset_control_top_arrow.png | Bin 0 -> 3055 bytes .../images/theme/blue/00_winset_control_top_bg.png | Bin 0 -> 2807 bytes .../images/theme/blue/00_winset_title_bg.png | Bin 0 -> 2799 bytes .../images/theme/blue/00_winset_title_line.png | Bin 0 -> 2813 bytes .../images/theme/blue/T01_Edit Field_clear.png | Bin 0 -> 3268 bytes main/layout/images/theme/blue/T01_title_btn.png | Bin 0 -> 3129 bytes .../images/theme/blue/T01_title_btn_press.png | Bin 0 -> 3126 bytes .../theme/white/00_winset_control_toolbar_bg.png | Bin 0 -> 2879 bytes .../theme/white/00_winset_control_top_arrow.png | Bin 0 -> 3190 bytes .../theme/white/00_winset_control_top_bg.png | Bin 0 -> 2844 bytes .../images/theme/white/00_winset_title_bg.png | Bin 0 -> 2872 bytes .../images/theme/white/00_winset_title_line.png | Bin 0 -> 2802 bytes .../images/theme/white/T01_Edit Field_clear.png | Bin 0 -> 3268 bytes main/layout/images/theme/white/T01_title_btn.png | Bin 0 -> 3129 bytes .../images/theme/white/T01_title_btn_press.png | Bin 0 -> 3126 bytes main/layout/ivug-crop-view.edc | 278 ++ main/layout/ivug-gengrid.edc | 211 ++ main/layout/ivug-name-view.edc | 96 + main/layout/ivug-popup.edc | 172 ++ main/layout/ivug-theme.edc | 171 ++ .../images/01_Control icon/00_winset_btn_prev.png | Bin 0 -> 3235 bytes .../01_Control icon/01_controlbar_icon_trim.png | Bin 0 -> 3523 bytes .../01_Control icon/01_controllbar_icon_close.png | Bin 0 -> 1076 bytes .../T01_1_controlbar_icon_detail.png | Bin 0 -> 3273 bytes .../01_Control icon/T01_1_title_icon_set_as.png | Bin 0 -> 1520 bytes .../01_Control icon/T01_Option tray_Edit.png | Bin 0 -> 5876 bytes .../images/01_Control icon/T01_Title_icon_more.png | Bin 0 -> 3061 bytes .../01_Control icon/T01_controlbar_icon_add.png | Bin 0 -> 3009 bytes .../01_Control icon/T01_controlbar_icon_save.png | Bin 0 -> 3238 bytes .../01_Control icon/T01_controlbar_icon_share.png | Bin 0 -> 3310 bytes .../images/Popup_icon/T01_1_popup_icon_Crop.png | Bin 0 -> 1464 bytes .../T01_1_popup_icon_Paste from Clipboard.png | Bin 0 -> 1547 bytes main/res/po/.pot | 142 + main/res/po/ar.po | 186 ++ main/res/po/bg.po | 186 ++ main/res/po/ca.po | 186 ++ main/res/po/cs.po | 186 ++ main/res/po/csv2po_v2 | Bin 0 -> 7586 bytes main/res/po/da.po | 186 ++ main/res/po/en_US.po | 186 ++ main/res/po/fi.po | 186 ++ main/res/po/he.po | 186 ++ main/res/po/hi.po | 186 ++ main/res/po/hr.po | 186 ++ main/res/po/hu.po | 186 ++ main/res/po/id.po | 186 ++ main/res/po/lt.po | 186 ++ main/res/po/lv.po | 186 ++ main/res/po/ms.po | 186 ++ main/res/po/no.po | 186 ++ main/res/po/pl.po | 186 ++ main/res/po/ro.po | 186 ++ main/res/po/sk.po | 186 ++ main/res/po/sl.po | 186 ++ main/res/po/sr.po | 186 ++ main/res/po/sv.po | 186 ++ main/res/po/th.po | 186 ++ main/res/po/uk.po | 186 ++ main/res/po/vi.po | 186 ++ main/src/control/ivug-context.c | 364 +++ main/src/control/ivug-context.h | 71 + main/src/control/ivug-crop-ug.cpp | 142 + main/src/control/ivug-crop-ug.h | 44 + main/src/control/ivug-detail-info.c | 703 +++++ main/src/control/ivug-detail-info.h | 85 + main/src/control/ivug-filter.c | 161 + main/src/control/ivug-filter.h | 41 + main/src/control/ivug-popup.c | 643 ++++ main/src/control/ivug-popup.h | 82 + main/src/control/ivug-selectioninfo.c | 151 + main/src/control/ivug-selectioninfo.h | 33 + main/src/control/ivug-setas.cpp | 321 ++ main/src/control/ivug-setas.h | 42 + main/src/control/ivug-widget.c | 215 ++ main/src/control/ivug-widget.h | 61 + main/src/include/ivug-common.h | 80 + main/src/include/ivug-crop-view.h | 70 + main/src/include/ivug-details-view.h | 78 + main/src/include/ivug-main-view.h | 211 ++ main/src/include/ivug-name-view.h | 78 + main/src/include/ivug-setas-view.h | 103 + main/src/include/ivug-slider-item.h | 181 ++ main/src/include/ivug-slider.h | 132 + main/src/include/ivug-string.h | 166 + main/src/slider/ivug-slider-item.cpp | 1203 ++++++++ main/src/slider/ivug-slider-mouse.cpp | 819 +++++ main/src/slider/ivug-slider-priv.h | 188 ++ main/src/slider/ivug-slider.cpp | 1201 ++++++++ main/src/view/ivug-crop-view.cpp | 494 +++ main/src/view/ivug-main-view-menu.cpp | 920 ++++++ main/src/view/ivug-main-view-menu.h | 50 + main/src/view/ivug-main-view-toolbar.cpp | 478 +++ main/src/view/ivug-main-view-toolbar.h | 43 + main/src/view/ivug-main-view.cpp | 1775 +++++++++++ main/src/view/ivug-name-view.c | 436 +++ main/src/view/ivug-setas-view-callerid.cpp | 653 ++++ main/src/view/ivug-setas-view-callerid.h | 49 + main/src/view/ivug-setas-view-wallpaper.cpp | 349 +++ main/src/view/ivug-setas-view-wallpaper.h | 43 + medialist/CMakeLists.txt | 50 + medialist/include/ivug-media.h | 74 + medialist/include/ivug-medialist.h | 101 + medialist/src/ivug-data-list.c | 273 ++ medialist/src/ivug-data-list.h | 41 + medialist/src/ivug-mediadata.c | 380 +++ medialist/src/ivug-mediadata.h | 52 + medialist/src/ivug-medialist.c | 687 +++++ packaging/changelog | 3232 ++++++++++++++++++++ res/images/T01_Nocontents_broken.png | Bin 0 -> 4880 bytes res/manifest/ug-image-viewer-efl.png | Bin 0 -> 12447 bytes res/manifest/ug-image-viewer-efl.xml | 26 + slideshow/CMakeLists.txt | 82 + slideshow/include/ivug-slideshow.h | 137 + slideshow/res/images/T01_Noise.png | Bin 0 -> 7937 bytes slideshow/res/layout/icons/T01_btn_play.png | Bin 0 -> 6920 bytes slideshow/res/layout/ivug-ss-ly.edc | 146 + slideshow/src/effect/include/ivug-anim.h | 64 + slideshow/src/effect/include/ivug-effect.h | 98 + slideshow/src/effect/ivug-anim.c | 177 ++ slideshow/src/effect/ivug-blind.c | 313 ++ slideshow/src/effect/ivug-dissolve.c | 369 +++ slideshow/src/effect/ivug-effect.c | 233 ++ slideshow/src/effect/ivug-fade.c | 160 + slideshow/src/effect/ivug-iris.c | 178 ++ slideshow/src/effect/ivug-slide.c | 148 + slideshow/src/effect/ivug-xcapture.c | 339 ++ slideshow/src/effect/ivug-xcapture.h | 30 + slideshow/src/effect/template.c | 82 + slideshow/src/ivug-slideshow.cpp | 1002 ++++++ widget/CMakeLists.txt | 79 + widget/include/Animation.h | 114 + widget/include/ECoreAnimator.h | 124 + widget/include/EFLUtil.h | 61 + widget/include/EvasSmartObj.h | 168 + widget/include/Exception.h | 33 + widget/include/Object.h | 33 + widget/include/Primitives.h | 272 ++ widget/include/ScrollerClient.h | 122 + widget/include/Transit.h | 176 ++ widget/include/ivug-image.h | 119 + widget/include/ivug-listpopup.h | 71 + widget/include/ivug-scissorbox.h | 54 + widget/res/images/crop/T06_selection.png | Bin 0 -> 3259 bytes widget/res/images/crop/T06_selection_Delete.png | Bin 0 -> 5446 bytes .../res/images/crop/T06_selection_Resizing_V.png | Bin 0 -> 5852 bytes .../res/images/crop/T06_selection_Resizing_h.png | Bin 0 -> 6714 bytes widget/res/images/crop/T06_selection_Rotate.png | Bin 0 -> 7466 bytes widget/res/images/scissorbox/T01_CallerID_hold.png | Bin 0 -> 2881 bytes .../res/images/scissorbox/T01_CallerID_line_W.png | Bin 0 -> 2802 bytes .../scissorbox/T01_CallerID_line_W_press.png | Bin 0 -> 2808 bytes .../res/images/scissorbox/T01_CallerID_line_h.png | Bin 0 -> 2807 bytes .../scissorbox/T01_CallerID_line_h_press.png | Bin 0 -> 2807 bytes .../res/images/scissorbox/T01_CallerID_normal.png | Bin 0 -> 2879 bytes .../res/images/scissorbox/T01_CallerID_press.png | Bin 0 -> 2845 bytes .../res/images/scissorbox/T01_btn_optiontray.png | Bin 0 -> 3151 bytes widget/res/layout/ivug-scroller.edc | 40 + widget/src/common/BufferCanvas.h | 54 + widget/src/common/Primitives.cpp | 61 + widget/src/common/Scroller.cpp | 1386 +++++++++ widget/src/common/Scroller.h | 197 ++ widget/src/image/ivug-image-photocam.cpp | 487 +++ widget/src/scissorbox/ScissorBox.cpp | 1727 +++++++++++ widget/src/scissorbox/ScissorBox.h | 118 + widget/src/scissorbox/ivug-scissorbox.cpp | 122 + widget/src/util/EFLUtil.cpp | 355 +++ widget/src/util/ivug-listpopup.c | 483 +++ 198 files changed, 39367 insertions(+) create mode 100755 common/include/ivug-callback.h create mode 100755 common/include/ivug-config.h create mode 100755 common/include/ivug-db.h create mode 100755 common/include/ivug-drm.h create mode 100755 common/include/ivug-exif.h create mode 100755 common/include/ivug-file-info.h create mode 100755 common/include/ivug-message.h create mode 100755 common/include/ivug-util.h create mode 100755 common/include/ivug-uuid.h create mode 100755 common/src/ivug-callback.c create mode 100755 common/src/ivug-callback.c.bak create mode 100755 common/src/ivug-config.c create mode 100755 common/src/ivug-db.c create mode 100755 common/src/ivug-drm.c create mode 100755 common/src/ivug-exif.c create mode 100755 common/src/ivug-file-info.c create mode 100755 common/src/ivug-message.c create mode 100755 common/src/ivug-util.c create mode 100755 common/src/ivug-uuid.c create mode 100755 feature/CMakeLists.txt create mode 100755 feature/include/ivug-email.h create mode 100755 feature/include/ivug-ext-ug.h create mode 100755 feature/include/ivug-vibration.h create mode 100755 feature/src/ivug-ext-ug.c create mode 100755 feature/src/ivug-vibration.c create mode 100755 include/ivug-datatypes.h create mode 100755 include/ivug-define.h create mode 100755 main/layout/crop-view/T06_controlbar_bg.png create mode 100755 main/layout/gengrid/00_winset_thumbs_bg.png create mode 100755 main/layout/gengrid/00_winset_thumbs_focus_bg.png create mode 100755 main/layout/icons/T01_btn_paused.png create mode 100755 main/layout/images/theme/blue/00_winset_control_toolbar_bg.png create mode 100755 main/layout/images/theme/blue/00_winset_control_top_arrow.png create mode 100755 main/layout/images/theme/blue/00_winset_control_top_bg.png create mode 100755 main/layout/images/theme/blue/00_winset_title_bg.png create mode 100755 main/layout/images/theme/blue/00_winset_title_line.png create mode 100755 main/layout/images/theme/blue/T01_Edit Field_clear.png create mode 100755 main/layout/images/theme/blue/T01_title_btn.png create mode 100755 main/layout/images/theme/blue/T01_title_btn_press.png create mode 100755 main/layout/images/theme/white/00_winset_control_toolbar_bg.png create mode 100755 main/layout/images/theme/white/00_winset_control_top_arrow.png create mode 100755 main/layout/images/theme/white/00_winset_control_top_bg.png create mode 100755 main/layout/images/theme/white/00_winset_title_bg.png create mode 100755 main/layout/images/theme/white/00_winset_title_line.png create mode 100755 main/layout/images/theme/white/T01_Edit Field_clear.png create mode 100755 main/layout/images/theme/white/T01_title_btn.png create mode 100755 main/layout/images/theme/white/T01_title_btn_press.png create mode 100755 main/layout/ivug-crop-view.edc create mode 100755 main/layout/ivug-gengrid.edc create mode 100755 main/layout/ivug-name-view.edc create mode 100755 main/layout/ivug-popup.edc create mode 100755 main/layout/ivug-theme.edc create mode 100755 main/res/images/01_Control icon/00_winset_btn_prev.png create mode 100755 main/res/images/01_Control icon/01_controlbar_icon_trim.png create mode 100755 main/res/images/01_Control icon/01_controllbar_icon_close.png create mode 100755 main/res/images/01_Control icon/T01_1_controlbar_icon_detail.png create mode 100755 main/res/images/01_Control icon/T01_1_title_icon_set_as.png create mode 100755 main/res/images/01_Control icon/T01_Option tray_Edit.png create mode 100755 main/res/images/01_Control icon/T01_Title_icon_more.png create mode 100755 main/res/images/01_Control icon/T01_controlbar_icon_add.png create mode 100755 main/res/images/01_Control icon/T01_controlbar_icon_save.png create mode 100755 main/res/images/01_Control icon/T01_controlbar_icon_share.png create mode 100755 main/res/images/Popup_icon/T01_1_popup_icon_Crop.png create mode 100755 main/res/images/Popup_icon/T01_1_popup_icon_Paste from Clipboard.png create mode 100755 main/res/po/.pot create mode 100755 main/res/po/ar.po create mode 100755 main/res/po/bg.po create mode 100755 main/res/po/ca.po create mode 100755 main/res/po/cs.po create mode 100755 main/res/po/csv2po_v2 create mode 100755 main/res/po/da.po create mode 100755 main/res/po/en_US.po create mode 100755 main/res/po/fi.po create mode 100755 main/res/po/he.po create mode 100755 main/res/po/hi.po create mode 100755 main/res/po/hr.po create mode 100755 main/res/po/hu.po create mode 100755 main/res/po/id.po create mode 100755 main/res/po/lt.po create mode 100755 main/res/po/lv.po create mode 100755 main/res/po/ms.po create mode 100755 main/res/po/no.po create mode 100755 main/res/po/pl.po create mode 100755 main/res/po/ro.po create mode 100755 main/res/po/sk.po create mode 100755 main/res/po/sl.po create mode 100755 main/res/po/sr.po create mode 100755 main/res/po/sv.po create mode 100755 main/res/po/th.po create mode 100755 main/res/po/uk.po create mode 100755 main/res/po/vi.po create mode 100755 main/src/control/ivug-context.c create mode 100755 main/src/control/ivug-context.h create mode 100755 main/src/control/ivug-crop-ug.cpp create mode 100755 main/src/control/ivug-crop-ug.h create mode 100755 main/src/control/ivug-detail-info.c create mode 100755 main/src/control/ivug-detail-info.h create mode 100755 main/src/control/ivug-filter.c create mode 100755 main/src/control/ivug-filter.h create mode 100755 main/src/control/ivug-popup.c create mode 100755 main/src/control/ivug-popup.h create mode 100755 main/src/control/ivug-selectioninfo.c create mode 100755 main/src/control/ivug-selectioninfo.h create mode 100755 main/src/control/ivug-setas.cpp create mode 100755 main/src/control/ivug-setas.h create mode 100755 main/src/control/ivug-widget.c create mode 100755 main/src/control/ivug-widget.h create mode 100755 main/src/include/ivug-common.h create mode 100755 main/src/include/ivug-crop-view.h create mode 100755 main/src/include/ivug-details-view.h create mode 100755 main/src/include/ivug-main-view.h create mode 100755 main/src/include/ivug-name-view.h create mode 100755 main/src/include/ivug-setas-view.h create mode 100755 main/src/include/ivug-slider-item.h create mode 100755 main/src/include/ivug-slider.h create mode 100755 main/src/include/ivug-string.h create mode 100755 main/src/slider/ivug-slider-item.cpp create mode 100755 main/src/slider/ivug-slider-mouse.cpp create mode 100755 main/src/slider/ivug-slider-priv.h create mode 100755 main/src/slider/ivug-slider.cpp create mode 100755 main/src/view/ivug-crop-view.cpp create mode 100755 main/src/view/ivug-main-view-menu.cpp create mode 100755 main/src/view/ivug-main-view-menu.h create mode 100755 main/src/view/ivug-main-view-toolbar.cpp create mode 100755 main/src/view/ivug-main-view-toolbar.h create mode 100755 main/src/view/ivug-main-view.cpp create mode 100755 main/src/view/ivug-name-view.c create mode 100755 main/src/view/ivug-setas-view-callerid.cpp create mode 100755 main/src/view/ivug-setas-view-callerid.h create mode 100755 main/src/view/ivug-setas-view-wallpaper.cpp create mode 100755 main/src/view/ivug-setas-view-wallpaper.h create mode 100755 medialist/CMakeLists.txt create mode 100755 medialist/include/ivug-media.h create mode 100755 medialist/include/ivug-medialist.h create mode 100755 medialist/src/ivug-data-list.c create mode 100755 medialist/src/ivug-data-list.h create mode 100755 medialist/src/ivug-mediadata.c create mode 100755 medialist/src/ivug-mediadata.h create mode 100755 medialist/src/ivug-medialist.c create mode 100755 packaging/changelog create mode 100755 res/images/T01_Nocontents_broken.png create mode 100755 res/manifest/ug-image-viewer-efl.png create mode 100755 res/manifest/ug-image-viewer-efl.xml create mode 100755 slideshow/CMakeLists.txt create mode 100755 slideshow/include/ivug-slideshow.h create mode 100755 slideshow/res/images/T01_Noise.png create mode 100755 slideshow/res/layout/icons/T01_btn_play.png create mode 100755 slideshow/res/layout/ivug-ss-ly.edc create mode 100755 slideshow/src/effect/include/ivug-anim.h create mode 100755 slideshow/src/effect/include/ivug-effect.h create mode 100755 slideshow/src/effect/ivug-anim.c create mode 100755 slideshow/src/effect/ivug-blind.c create mode 100755 slideshow/src/effect/ivug-dissolve.c create mode 100755 slideshow/src/effect/ivug-effect.c create mode 100755 slideshow/src/effect/ivug-fade.c create mode 100755 slideshow/src/effect/ivug-iris.c create mode 100755 slideshow/src/effect/ivug-slide.c create mode 100755 slideshow/src/effect/ivug-xcapture.c create mode 100755 slideshow/src/effect/ivug-xcapture.h create mode 100755 slideshow/src/effect/template.c create mode 100755 slideshow/src/ivug-slideshow.cpp create mode 100755 widget/CMakeLists.txt create mode 100755 widget/include/Animation.h create mode 100755 widget/include/ECoreAnimator.h create mode 100755 widget/include/EFLUtil.h create mode 100755 widget/include/EvasSmartObj.h create mode 100755 widget/include/Exception.h create mode 100755 widget/include/Object.h create mode 100755 widget/include/Primitives.h create mode 100755 widget/include/ScrollerClient.h create mode 100755 widget/include/Transit.h create mode 100755 widget/include/ivug-image.h create mode 100755 widget/include/ivug-listpopup.h create mode 100755 widget/include/ivug-scissorbox.h create mode 100755 widget/res/images/crop/T06_selection.png create mode 100755 widget/res/images/crop/T06_selection_Delete.png create mode 100755 widget/res/images/crop/T06_selection_Resizing_V.png create mode 100755 widget/res/images/crop/T06_selection_Resizing_h.png create mode 100755 widget/res/images/crop/T06_selection_Rotate.png create mode 100755 widget/res/images/scissorbox/T01_CallerID_hold.png create mode 100755 widget/res/images/scissorbox/T01_CallerID_line_W.png create mode 100755 widget/res/images/scissorbox/T01_CallerID_line_W_press.png create mode 100755 widget/res/images/scissorbox/T01_CallerID_line_h.png create mode 100755 widget/res/images/scissorbox/T01_CallerID_line_h_press.png create mode 100755 widget/res/images/scissorbox/T01_CallerID_normal.png create mode 100755 widget/res/images/scissorbox/T01_CallerID_press.png create mode 100755 widget/res/images/scissorbox/T01_btn_optiontray.png create mode 100755 widget/res/layout/ivug-scroller.edc create mode 100755 widget/src/common/BufferCanvas.h create mode 100755 widget/src/common/Primitives.cpp create mode 100755 widget/src/common/Scroller.cpp create mode 100755 widget/src/common/Scroller.h create mode 100755 widget/src/image/ivug-image-photocam.cpp create mode 100755 widget/src/scissorbox/ScissorBox.cpp create mode 100755 widget/src/scissorbox/ScissorBox.h create mode 100755 widget/src/scissorbox/ivug-scissorbox.cpp create mode 100755 widget/src/util/EFLUtil.cpp create mode 100755 widget/src/util/ivug-listpopup.c diff --git a/common/include/ivug-callback.h b/common/include/ivug-callback.h new file mode 100755 index 0000000..fac346c --- /dev/null +++ b/common/include/ivug-callback.h @@ -0,0 +1,37 @@ +/* + * Copyright 2012 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.tizenopensource.org/license + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +#ifndef __IVUG_CALLBACK_H__ +#define __IVUG_CALLBACK_H__ + +typedef void (*callback_func_t) (void *data1, void *data2, void *data3, void *user_data); + +typedef struct { + callback_func_t CBFunc; + void *data; +}callback_handle_t; + +callback_handle_t * ivug_callback_register(void); + +void ivug_callback_set_callback(callback_handle_t *handle, callback_func_t callback, void *data); + +void ivug_callback_call(callback_handle_t *handle, void *data1, void *data2, void *data3); + +void ivug_callback_unregister(callback_handle_t *handle); + +#endif // __IVUG_CALLBACK_H__ +//! End of a file diff --git a/common/include/ivug-config.h b/common/include/ivug-config.h new file mode 100755 index 0000000..e6a480c --- /dev/null +++ b/common/include/ivug-config.h @@ -0,0 +1,59 @@ +/* + * Copyright 2012 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.tizenopensource.org/license + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __IVUG_CONFIG_H__ +#define __IVUG_CONFIG_H__ + +#include + +typedef enum { + SLIDE_SHOW_MODE_NORMAL = 0x00, + SLIDE_SHOW_MODE_REPEAT = 0x01, + SLIDE_SHOW_MODE_SHUFFLE = 0x02, + SLIDE_SHOW_MODE_SHUFFLE_REPEAT = 0x03, +} slide_show_mode; + +typedef enum { + IVUG_EFFECT_TYPE_UNKNOWN = -1, + + IVUG_EFFECT_TYPE_IRIS= 0x00, + IVUG_EFFECT_TYPE_DISSOLVE, + IVUG_EFFECT_TYPE_SLIDE, + IVUG_EFFECT_TYPE_DISSOLVE_FADE, + IVUG_EFFECT_TYPE_SPLIT, + IVUG_EFFECT_TYPE_MAX, +} ivug_effect_type; + +typedef void (*_vconf_state_changed_cb)(keynode_t* node, void *data); + +#ifdef __cplusplus +extern "C" { +#endif + +bool ivug_config_set_lockscreen_image(const char* filepath); + +bool ivug_config_set_homescreen_image(const char* filepath); + +void ivug_config_get_slideshow_setting(slide_show_mode * /* OUT */ mode, + double * /* OUT */ interval_time, + ivug_effect_type * /* OUT */ effect_type); + +#ifdef __cplusplus +} +#endif + + +#endif // __IVUG_CONFIG_H__ diff --git a/common/include/ivug-db.h b/common/include/ivug-db.h new file mode 100755 index 0000000..7d6e7de --- /dev/null +++ b/common/include/ivug-db.h @@ -0,0 +1,67 @@ +/* + * Copyright 2012 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.tizenopensource.org/license + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __IVUG_DB_H__ +#define __IVUG_DB_H__ + +#include + +#include "ivug-datatypes.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef void *filter_handle; +typedef void *media_handle; + +typedef bool (*ivug_db_cb)(media_handle media, void *user_data); + +#define IVUG_MAX_CONDITION_LEN (1024) + +bool ivug_db_create(void); +bool ivug_db_destroy(void); + +bool ivug_db_create_filter(filter_handle *filter); +bool ivug_db_destroy_filter(filter_handle filter); +bool ivug_db_set_filter(filter_handle filter, ivug_view_by view_by, ivug_media_type media_type, char *condition); +bool ivug_db_set_filter_offset(filter_handle filter, int stp, int endp); + +media_handle ivug_db_get_file_handle(const char* filepath); +media_handle ivug_db_get_file_handle_from_media_id(const char* media_id); +media_handle ivug_db_get_folder_handle(const char* folderpath); + +bool ivug_db_destroy_file_handle(media_handle m_handle); +bool ivug_db_destroy_folder_handle(media_handle m_handle); + +bool ivug_db_get_all_folder_list(ivug_db_cb callback, void *data); + +/* + below functions returned values should be freed by user +*/ +char *ivug_db_get_file_path(media_handle media); +char *ivug_db_get_folder_name(media_handle media); +char *ivug_db_get_folder_id(media_handle media); +char *ivug_db_get_folder_path(media_handle media); + + +#ifdef __cplusplus +} +#endif + + +#endif // __IVUG_DB_H__ + diff --git a/common/include/ivug-drm.h b/common/include/ivug-drm.h new file mode 100755 index 0000000..891100c --- /dev/null +++ b/common/include/ivug-drm.h @@ -0,0 +1,92 @@ +/* + * Copyright 2012 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.tizenopensource.org/license + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __IVUG_DRM_H__ +#define __IVUG_DRM_H__ + +#include + +typedef enum IVUG_DRM_SETAS_TYPE +{ + IVUG_DRM_SETAS_NONE = -1, + IVUG_DRM_SETAS_WALLPAPER, + IVUG_DRM_SETAS_CALLERID, +}_ivug_drm_setas_type; + +typedef enum +{ + IVUG_DRM_RESULT_LIMITED = -1, + IVUG_DRM_RESULT_UNLIMITED, + IVUG_DRM_RESULT_COUNT, + IVUG_DRM_RESULT_DATETIME, + IVUG_DRM_RESULT_INTERVAL_DAYS, + IVUG_DRM_RESULT_TIMED_COUNT, + IVUG_DRM_RESULT_ACCUMULATED, + IVUG_DRM_RESULT_INDIVIDUAL, + IVUG_DRM_RESULT_SYSTEM, +}drm_constraints; + +typedef struct +{ + drm_constraints constraints; + int data; +}drm_data_t; + +typedef void *drm_handle_t; + +#ifdef __cplusplus +extern "C" { +#endif + +/* + Check whether @param file_path is DRM or not. +*/ +bool ivug_drm_is_drm_file(const char* file_path); + +/* + Check RO is valid. + FL case : Always return true(valid RO). +*/ +bool ivug_drm_has_valid_ro(const char *path); + +/* + Retrieving infomation from file +*/ +char* ivug_drm_get_drm_vendor_info(const char *path); +bool ivug_drm_get_forwarding_info(const char *path); + +bool ivug_drm_is_possible_to_setas(const char* path, _ivug_drm_setas_type type); + +/* + Decrypt DRM file and allocated in memory. + + CAUTION : this functionn read entire file and allocate memory with size of entire file. +*/ +drm_data_t * ivug_drm_check_constraint(const char* path); + +/* return value must be freed */ +char * ivug_drm_get_right_url(const char *path); +char * ivug_drm_get_mime(const char *path); + + + +#ifdef __cplusplus +} +#endif + + +#endif // __IVUG_DRM_H__ + diff --git a/common/include/ivug-exif.h b/common/include/ivug-exif.h new file mode 100755 index 0000000..a76913b --- /dev/null +++ b/common/include/ivug-exif.h @@ -0,0 +1,36 @@ +/* + * Copyright 2012 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.tizenopensource.org/license + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __IVUG_EXIF_H__ +#define __IVUG_EXIF_H__ + +#ifdef __cplusplus +extern "C" { +#endif + + +int ivug_exif_set_rotate(const char *file, int degree); + +int ivug_exif_get_rotate(const char *file, int *degree); + + +#ifdef __cplusplus +} +#endif + +#endif //__IVUG_EXIF_H__ + + diff --git a/common/include/ivug-file-info.h b/common/include/ivug-file-info.h new file mode 100755 index 0000000..7f35502 --- /dev/null +++ b/common/include/ivug-file-info.h @@ -0,0 +1,58 @@ +/* + * Copyright 2012 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.tizenopensource.org/license + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __IVUG_FILE_INFO_H__ +#define __IVUG_FILE_INFO_H__ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* + ivug_fileinfo_*() returns false when error. otherwise return true and fill proper value in [out] param +*/ +bool ivug_fileinfo_get_image_gps_info(const char* filepath, double * /* OUT */ latitude, double * /* OUT */ longitude); +bool ivug_fileinfo_get_video_gps_info(const char *filepath, double * /* OUT */ latitude, double * /* OUT */ longitude); + +bool ivug_fileinfo_get_video_resolution(const char *filepath, int * /* OUT */ pWidth, int * /* OUT */pHeight); +bool ivug_fileinfo_get_image_resolution(const char *filepath, int * /* OUT */ pWidth, int * /* OUT */pHeight); + + +/* + return file extension string. if file is DRM file, decrypted file extension is returned. + + CAUTION : user should free returned string. +*/ +char *ivug_fileinfo_get_file_extension(const char *filepath); + + +/* + return mine type from drm or non-drm file. + + CAUTION : user should free returned string. +*/ +char *ivug_fileinfo_get_mime_type(const char *filepath); + + +#ifdef __cplusplus +} +#endif + + +#endif // __IVUG_FILE_INFO_H__ + diff --git a/common/include/ivug-message.h b/common/include/ivug-message.h new file mode 100755 index 0000000..5d73980 --- /dev/null +++ b/common/include/ivug-message.h @@ -0,0 +1,44 @@ +/* + * Copyright 2012 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.tizenopensource.org/license + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __MESSAGE_H__ +#define __ MESSAGE_H__ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef void * MessageHandle; +typedef void (*FnMessage)( int param1, int param2, int param3, void *param4, void *client_data); + + +bool remove_message_handle(MessageHandle handle); + +MessageHandle create_message_handle(); + +bool register_message(MessageHandle handle, const char *command, FnMessage cb, void *data ); +bool unregister_message(MessageHandle handle, const char *command, FnMessage cb); + +bool send_message(MessageHandle handle, const char *command, int param1, int param2, int param3, void *param4); + +#ifdef __cplusplus +} +#endif + +#endif // __FMRADIO_MESSAGE_H__ + diff --git a/common/include/ivug-util.h b/common/include/ivug-util.h new file mode 100755 index 0000000..fa0f99f --- /dev/null +++ b/common/include/ivug-util.h @@ -0,0 +1,87 @@ +/* + * Copyright 2012 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.tizenopensource.org/license + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __IVUG_UTIL_H__ +#define __IVUG_UTIL_H__ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* + +*/ +bool ivug_is_web_uri(const char* uri); + +bool ivug_remove_file(const char *filepath); + +bool ivug_is_file_exist(const char* filepath); + +bool ivug_rename_file(const char *src, const char *dst); + +bool ivug_copy_file(const char *filename, const char *dest); + +const char *ivug_get_filename(const char *filepath); + +unsigned int get_distance(int prevX, int prevY, int X, int Y); + +/* + Generate temporary file name with given path and extension. + returned value should free() by user. +*/ +char *ivug_mktemp(char* filepath, char*ext); + + +/* + LCD sleep control. +*/ +bool ivug_prohibit_lcd_off(void); +bool ivug_allow_lcd_off(void); + + +/* + Get mime type from file path. Can be used either DRM and non DRM. + should free returned after use. +*/ + +bool ivug_is_editable_video_file(char *filepath); + + +/* + returned values should be freed by user +*/ +int ivug_atoi(const char *number); + +double ivug_atod(const char *number); + +char * ivug_generate_file_name(const char *filepath); + +/* + Removes leading and trailing whitespace from string + This function doesn't allocate or reallocate any memory +*/ +char * ivug_strip_string(char* name); + +#ifdef __cplusplus +} +#endif + + + +#endif //__IVUG_UTIL_H__ + diff --git a/common/include/ivug-uuid.h b/common/include/ivug-uuid.h new file mode 100755 index 0000000..661515e --- /dev/null +++ b/common/include/ivug-uuid.h @@ -0,0 +1,47 @@ +/* + * Copyright 2012 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.tizenopensource.org/license + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __IVUG_UUID_H__ +#define __IVUG_UUID_H__ + +#include "ivug-datatypes.h" +#include + + + +#ifdef __cplusplus +extern "C" { +#endif + +UUID uuid_assign(UUID id); + +void uuid_free(UUID id); + +int uuid_compare(UUID id1, UUID id2); + +const char *uuid_getchar(UUID id); + +UUID uuid_getuuid(const char *szID); + +bool uuid_is_valid(UUID id); + + +#ifdef __cplusplus +} +#endif + +#endif // __IVUG_UUID_H__ + diff --git a/common/src/ivug-callback.c b/common/src/ivug-callback.c new file mode 100755 index 0000000..60daad8 --- /dev/null +++ b/common/src/ivug-callback.c @@ -0,0 +1,50 @@ +/* + * Copyright 2012 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.tizenopensource.org/license + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "ivug-debug.h" +#include "ivug-callback.h" + +#include +//callback_func_t g_callback; + +callback_handle_t * ivug_callback_register() +{ + callback_handle_t *callback_handle = calloc(1, sizeof(callback_handle_t)); + return callback_handle; +} + +void ivug_callback_set_callback(callback_handle_t *handle, callback_func_t callback, void *data) +{ + IV_ASSERT(handle != NULL); + handle->CBFunc = callback; + handle->data = data; +} + +void ivug_callback_call(callback_handle_t *handle, void *data1, void *data2, void *data3) +{ + IV_ASSERT(handle != NULL); + if(handle->CBFunc) + { + (handle->CBFunc)(data1, data2, data3, handle->data); + } +} + +void ivug_callback_unregister(callback_handle_t *handle) +{ + IV_ASSERT(handle != NULL); + free(handle); +} + diff --git a/common/src/ivug-callback.c.bak b/common/src/ivug-callback.c.bak new file mode 100755 index 0000000..87aa41a --- /dev/null +++ b/common/src/ivug-callback.c.bak @@ -0,0 +1,51 @@ +/* + * Copyright 2012 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.tizenopensource.org/license + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +#include "ivug-debug.h" +#include "ivug-callback.h" + +#include +//callback_func_t g_callback; + +callback_handle_t * ivug_callback_register() +{ + callback_handle_t *callback_handle = calloc(1, sizeof(callback_handle_t)); + return callback_handle; +} + +void ivug_callback_set_callback(callback_handle_t *handle, callback_func_t callback, void *data) +{ + IV_ASSERT(handle != NULL); + handle->CBFunc = callback; + handle->data = data; +} + +void ivug_callback_call(callback_handle_t *handle, void *data1, void *data2, void *data3) +{ + IV_ASSERT(handle != NULL); + if(handle->CBFunc) + { + (handle->CBFunc)(data1, data2, data3, handle->data); + } +} + +void ivug_callback_unregister(callback_handle_t *handle) +{ + IV_ASSERT(handle != NULL); + free(handle); +} + diff --git a/common/src/ivug-config.c b/common/src/ivug-config.c new file mode 100755 index 0000000..2efd873 --- /dev/null +++ b/common/src/ivug-config.c @@ -0,0 +1,223 @@ +/* + * Copyright 2012 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.tizenopensource.org/license + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +//#include "ivug-common.h" +#include "ivug-define.h" +#include "ivug-datatypes.h" +#include "ivug-uuid.h" + +#include +#include + +#include "statistics.h" +#include "ivug-debug.h" + +#include "ivug-config.h" + +#include +#include + +//TODO: Request vconf key to setting part, Slide show setting vconf key +#define VCONFKEY_GALLERY_INTERVAL_TIME "db/setting/gallery/interval_time" //double +#define VCONFKEY_GALLERY_REPEAT_STATE "db/setting/gallery/repeat_state" //boolean +#define VCONFKEY_GALLERY_SHUFFLE_STATE "db/setting/gallery/shuffle_state" //boolean +#define VCONFKEY_GALLERY_TRANSITION_EFFECT "db/setting/gallery/ss_effect" //char + +enum { STATE_FALSE = 0, STATE_TRUE = 1, }; + +/* + Set lock screen with given image. + + CAUTION : does not check filepath integrity +*/ +bool ivug_config_set_lockscreen_image(const char* filepath) +{ + if(filepath == NULL) + { + MSG_IMAGEVIEW_ERROR("Lock screen path is NULL"); + return FALSE; + } + + if(vconf_set_str( VCONFKEY_IDLE_LOCK_BGSET, filepath ) < 0) + { + MSG_IMAGEVIEW_ERROR("Lockscreen set Error : %s", filepath); + return FALSE; + } + + MSG_IMAGEVIEW_HIGH("Set Lockscreen filepath = %s", filepath); + + return TRUE; +} + +/* + Set home screen with given image + + CAUTION : does not check filepath integrity +*/ +bool ivug_config_set_homescreen_image( const char* filepath ) +{ + if(filepath == NULL) + { + MSG_IMAGEVIEW_ERROR("Home screen path is NULL"); + return FALSE; + } +// TODO : Need to check file existence????? + if(vconf_set_str(VCONFKEY_BGSET, filepath) < 0) + { + MSG_IMAGEVIEW_ERROR("Homescreen set Error"); + return FALSE; + } + + MSG_IMAGEVIEW_HIGH("Set Homescreen filepath = %s", filepath); + return TRUE; +} + + +static bool +_ivug_config_get_slideshow_repeat_state(void) +{ + int repeat_state = STATE_FALSE; + + if(vconf_get_bool(VCONFKEY_GALLERY_REPEAT_STATE, &repeat_state) < 0) + { + MSG_IMAGEVIEW_ERROR("vconf_get_bool failed, set as repeat state as default: false"); + return false; + } + + MSG_IMAGEVIEW_HIGH("repeat state is: %d", repeat_state); + + return (repeat_state == STATE_TRUE ? true : false); +} + +static bool +_ivug_config_get_slideshow_shuffle_state(void) +{ + int shuffle_state = STATE_FALSE; + + if(vconf_get_bool(VCONFKEY_GALLERY_SHUFFLE_STATE, &shuffle_state) < 0) + { + MSG_IMAGEVIEW_ERROR("vconf_get_bool failed, set as shuffle state as default: false"); + return false; + } + + MSG_IMAGEVIEW_HIGH("shuffle state is: %d", shuffle_state); + + return (shuffle_state == STATE_TRUE ? true : false); +} + +static double +_ivug_config_get_slideshow_interval_time(void) +{ + double interval_time = 0.0; + + if(vconf_get_dbl(VCONFKEY_GALLERY_INTERVAL_TIME, &interval_time) < 0) + { + MSG_IMAGEVIEW_ERROR("vconf_get_dbl failed, set as interval time as -1"); + + interval_time = -1.0; + } + + MSG_IMAGEVIEW_HIGH("interval time is: %f", interval_time); + return interval_time; +} + +static char * +_ivug_config_get_slideshow_effect_type(void) +{ +// TODO : Free returned string?? + char *effect_str = NULL; + effect_str = vconf_get_str(VCONFKEY_GALLERY_TRANSITION_EFFECT); + + if(!effect_str) + { + MSG_IMAGEVIEW_ERROR("vconf_get_str failed, set as effect type as default"); + + effect_str = NULL; + } + + MSG_IMAGEVIEW_HIGH("effect is: %s", effect_str); + + return effect_str; +} + +static ivug_effect_type +_ivug_config_get_effect_type_by_string(char *effect_str) +{ + IV_ASSERT(effect_str != NULL); + + ivug_effect_type type = IVUG_EFFECT_TYPE_SLIDE; + + if(!strncmp(effect_str, "Slide", strlen(effect_str))) + { + type = IVUG_EFFECT_TYPE_SLIDE; + } + else if(!strncmp(effect_str, "Iris", strlen(effect_str))) + { + type = IVUG_EFFECT_TYPE_IRIS; + } + else if(!strncmp(effect_str, "Dissolve", strlen(effect_str))) + { + type = IVUG_EFFECT_TYPE_DISSOLVE; + } + else if(!strncmp(effect_str, "DissolveFade", strlen(effect_str))) + { + type = IVUG_EFFECT_TYPE_DISSOLVE_FADE; + } + else if(!strncmp(effect_str, "Split", strlen(effect_str))) + { + type = IVUG_EFFECT_TYPE_SPLIT; + } + else //Set all other cases as default NONE + { + MSG_SLIDER_WARN("Invalid type : %s", effect_str); + type = IVUG_EFFECT_TYPE_UNKNOWN; + } + + MSG_IMAGEVIEW_HIGH("effect_str = %s, type = %d", effect_str, type); + + return type; +} + +void +ivug_config_get_slideshow_setting(slide_show_mode *mode, + double *interval_time, + ivug_effect_type *effect_type) +{ + *mode = SLIDE_SHOW_MODE_NORMAL; + + bool state; + + state = _ivug_config_get_slideshow_repeat_state(); + if(state == true) + { + *mode |= SLIDE_SHOW_MODE_REPEAT; + } + + state = _ivug_config_get_slideshow_shuffle_state(); + if(state == true) + { + *mode |= SLIDE_SHOW_MODE_SHUFFLE; + } + + *interval_time = _ivug_config_get_slideshow_interval_time(); + + /* EFFECT_NONE, EFFECT_DISSOLVE_FADE, EFFECT_DISSOLVE_FADE, EFFECT_IRIS */ + char *effect = _ivug_config_get_slideshow_effect_type(); + + *effect_type = _ivug_config_get_effect_type_by_string(effect); +} + + diff --git a/common/src/ivug-db.c b/common/src/ivug-db.c new file mode 100755 index 0000000..288fe6e --- /dev/null +++ b/common/src/ivug-db.c @@ -0,0 +1,417 @@ +/* + * Copyright 2012 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.tizenopensource.org/license + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "ivug-define.h" +#include "ivug-debug.h" +#include "ivug-util.h" +#include "ivug-db.h" + +#include +#include + +#define LOG_LVL DBG_MSG_LVL_HIGH +#define LOG_CAT "IV-DB" + +typedef struct _Ivug_DB +{ + ivug_db_cb callback; + media_handle *m_handle; + void *data; +}Ivug_DB; + +static char *_strerror_db(int error) +{ + switch(error) + { + case MEDIA_CONTENT_ERROR_INVALID_PARAMETER: + return "Invalid parameter"; + case MEDIA_CONTENT_ERROR_OUT_OF_MEMORY : + return "Out of memory"; + case MEDIA_CONTENT_ERROR_DB_FAILED : + return "DB operation failed"; + default: + { + static char buf[40]; + sprintf(buf, "Error Code=%d", error); + return buf; + } + + } +} + +bool ivug_db_create(void) +{ + int ret = MEDIA_CONTENT_ERROR_NONE; + + ret = media_content_connect(); + if(ret != MEDIA_CONTENT_ERROR_NONE) + { + MSG_ERROR("media_content_connect is failed, err:%s", _strerror_db(ret)); + return false; + } + + MSG_HIGH("ivug_db_create success"); + return true; +} + +bool ivug_db_destroy(void) +{ + int ret = MEDIA_CONTENT_ERROR_NONE; + + ret = media_content_disconnect(); + if(ret != MEDIA_CONTENT_ERROR_NONE) + { + MSG_ERROR("media_content_disconnect is failed, err:%s", _strerror_db(ret)); + return false; + } + + MSG_HIGH("ivug_db_destroy success"); + return true; +} + +bool ivug_db_destroy_file_handle(media_handle m_handle) +{ + media_info_h minfo = (media_info_h)m_handle; + int ret = MEDIA_CONTENT_ERROR_NONE; + + ret = media_info_destroy(minfo); + if(ret != MEDIA_CONTENT_ERROR_NONE) + { + MSG_ERROR("media_info_destroy is failed, err = %s", _strerror_db(ret)); + return false; + } + + return true; +} + +bool ivug_db_destroy_folder_handle(media_handle m_handle) +{ + media_folder_h minfo = (media_folder_h)m_handle; + int ret = MEDIA_CONTENT_ERROR_NONE; + + ret = media_folder_destroy(minfo); + if(ret != MEDIA_CONTENT_ERROR_NONE) + { + MSG_ERROR("media_folder_destroy is failed, err = %s", _strerror_db(ret)); + return false; + } + + return true; +} + +bool ivug_db_create_filter(filter_handle *filter) +{ + filter_h *media_filter = (filter_h *)filter; + int ret = MEDIA_CONTENT_ERROR_NONE; + + ret = media_filter_create(media_filter); + if(ret != MEDIA_CONTENT_ERROR_NONE) + { + MSG_ERROR("media_filter_create is failed, err = %s", _strerror_db(ret)); + return false; + } + MSG_MED("ivug_db_create_filter success"); + return true; +} + +bool ivug_db_destroy_filter(filter_handle filter) +{ + filter_h media_filter = (filter_h)filter; + + int ret = MEDIA_CONTENT_ERROR_NONE; + + ret = media_filter_destroy(media_filter); + if(ret != MEDIA_CONTENT_ERROR_NONE) + { + MSG_ERROR("media_filter_destroy is failed, err = %s", _strerror_db(ret)); + return false; + } + MSG_MED("ivug_db_destroy_filter success"); + return true; +} + +bool ivug_db_set_filter_condition(filter_handle media_filter, const char *condition) +{ + IV_ASSERT(condition != NULL); + + MSG_HIGH("condition str = %s", condition); + int ret = media_filter_set_condition(media_filter, condition, MEDIA_CONTENT_COLLATE_DEFAULT); + if(ret != MEDIA_CONTENT_ERROR_NONE) + { + MSG_ERROR("media_filter_set_condition is failed, err = %s", _strerror_db(ret)); + return false; + } + return true; +} + +bool ivug_db_set_filter(filter_handle filter, ivug_view_by view_by, ivug_media_type media_type, char *condition) +{ + filter_h media_filter = (filter_h)filter; + + int ret = MEDIA_CONTENT_ERROR_NONE; + + if(condition == NULL) + { + condition = calloc(1, sizeof(char)*IVUG_MAX_CONDITION_LEN); + } + else + { + strcat(condition," AND "); + } + + /*MEDIA_TYPE 0-image, 1-video, 2-sound, 3-music*/ + switch(media_type) + { + case IVUG_MEDIA_TYPE_IMAGE: + strcat(condition, "(MEDIA_TYPE=0)"); + break; + case IVUG_MEDIA_TYPE_VIDEO: + strcat(condition,"(MEDIA_TYPE=1)"); + break; + case IVUG_MEDIA_TYPE_ALL: + strcat(condition, "(MEDIA_TYPE=0 OR MEDIA_TYPE=1)"); + break; + default: + MSG_FATAL("Invalid media type : %d", media_type); + break; + } + + if(view_by == IVUG_VIEW_BY_FAVORITES) + { + strcat(condition, " AND MEDIA_FAVORITE=1"); + } + + if(condition) + { + if(ivug_db_set_filter_condition(media_filter, condition) == false) + { + goto SET_FILTER_ERROR; + } + } + + ret = media_filter_set_order(media_filter, MEDIA_CONTENT_ORDER_DESC, MEDIA_MODIFIED_TIME, MEDIA_CONTENT_COLLATE_NOCASE); + if(ret != MEDIA_CONTENT_ERROR_NONE) + { + MSG_ERROR("media_filter_set_order is failed, err = %s", _strerror_db(ret)); + goto SET_FILTER_ERROR; + } + + if(condition) + free(condition); + + MSG_MED("ivug_db_set_filter success, view_by:%d, media_type:%d", view_by, media_type); + return true; + +SET_FILTER_ERROR: + if(condition) + free(condition); + return false; +} + +bool ivug_db_set_filter_offset(filter_handle filter, int stp, int endp) +{ + filter_h media_filter = (filter_h)filter; + + int ret = MEDIA_CONTENT_ERROR_NONE; + + ret = media_filter_set_offset(media_filter, stp, endp-stp+1); + if(ret != MEDIA_CONTENT_ERROR_NONE) + { + MSG_ERROR("media_filter_set_offset is failed, err = %s", _strerror_db(ret)); + return false; + } + + return true; +} + +bool _media_item_cb(media_info_h item, void *user_data) +{ + media_handle *m_handle = (media_handle *)user_data; + + media_info_clone((media_info_h *)m_handle, item); + + return false; //only 1 item +} + +media_handle ivug_db_get_file_handle(const char* filepath) +{ + IV_ASSERT(filepath != NULL); + + int ret = MEDIA_CONTENT_ERROR_NONE; + filter_handle media_filter = NULL; + + char buf[1024] = {0,}; + snprintf(buf, sizeof(buf), "MEDIA_PATH=\'%s\'", filepath); + + media_handle m_handle = NULL; + + ivug_db_create_filter(&media_filter); + ivug_db_set_filter_condition(media_filter, buf); + ret = media_info_foreach_media_from_db(media_filter, _media_item_cb, &m_handle); + if(ret != MEDIA_CONTENT_ERROR_NONE) + { + MSG_ERROR("media_info_foreach_media_from_db is failed, err = %s", _strerror_db(ret)); + goto GET_ITEM_ERROR; + } + ivug_db_destroy_filter(media_filter); + + return m_handle; + +GET_ITEM_ERROR: + if(media_filter) + ivug_db_destroy_filter(media_filter); + + return NULL; +} + +media_handle ivug_db_get_file_handle_from_media_id(const char* media_id) +{ + IV_ASSERT(media_id != NULL); + + media_handle m_handle = NULL; + + int ret = media_info_get_media_from_db(media_id, (media_info_h*)&m_handle); + if(ret != MEDIA_CONTENT_ERROR_NONE) + { + MSG_ERROR("media_info_get_media_from_db is failed, err = %s", _strerror_db(ret)); + return NULL; + } + + return m_handle; +} + +static bool _media_folder_item_cb(media_folder_h item, void *user_data) +{ + media_handle *t_handle = (media_handle *)user_data; + + media_folder_clone((media_folder_h *)t_handle, item); + + return false; //only 1 item +} + +media_handle ivug_db_get_folder_handle(const char* folderpath) +{ + IV_ASSERT(folderpath != NULL); + + int ret = MEDIA_CONTENT_ERROR_NONE; + filter_handle media_filter = NULL; + + char buf[1024] = {0,}; + snprintf(buf, sizeof(buf), "FOLDER_PATH=\'%s\'", folderpath); + + media_handle m_handle = NULL; + + ivug_db_create_filter(&media_filter); + ivug_db_set_filter_condition(media_filter, buf); + ret = media_folder_foreach_folder_from_db(media_filter, _media_folder_item_cb, &m_handle); + if(ret != MEDIA_CONTENT_ERROR_NONE) + { + MSG_ERROR("media_folder_foreach_folder_from_db is failed, err = %s", _strerror_db(ret)); + goto GET_ITEM_ERROR; + } + ivug_db_destroy_filter(media_filter); + + return m_handle; + +GET_ITEM_ERROR: + if(media_filter) + ivug_db_destroy_filter(media_filter); + + return NULL; +} + +static bool _media_folder_list_cb(media_folder_h item, void *user_data) +{ + Ivug_DB *iv_db = (Ivug_DB *)user_data; + + if(iv_db->callback) + { + iv_db->callback((media_handle)item, iv_db->data); + } + + return true; +} + +bool ivug_db_get_all_folder_list(ivug_db_cb callback, void *data) +{ + int ret = MEDIA_CONTENT_ERROR_NONE; + filter_handle media_filter = NULL; + + Ivug_DB *iv_db = calloc(1, sizeof(Ivug_DB)); + iv_db->callback = callback; + iv_db->data = data; + + ivug_db_create_filter(&media_filter); + ret = media_folder_foreach_folder_from_db(media_filter, _media_folder_list_cb, iv_db); + + free(iv_db); + + if(ret != MEDIA_CONTENT_ERROR_NONE) + { + MSG_ERROR("media_folder_foreach_folder_from_db is failed, err = %s", _strerror_db(ret)); + goto GET_ITEM_ERROR; + } + ivug_db_destroy_filter(media_filter); + + return true; + +GET_ITEM_ERROR: + if(media_filter) + ivug_db_destroy_filter(media_filter); + + return false; +} + +char *ivug_db_get_file_path(media_handle media) +{ + media_info_h file_item = (media_info_h)media; + char *name = NULL; + + media_info_get_file_path(file_item, &name); + + return name; +} + +char *ivug_db_get_folder_name(media_handle media) +{ + media_folder_h folder_item = (media_folder_h)media; + char *name = NULL; + + media_folder_get_name(folder_item, &name); + + return name; +} + +char *ivug_db_get_folder_id(media_handle media) +{ + media_folder_h folder_item = (media_folder_h)media; + char *id = NULL; + + media_folder_get_folder_id(folder_item, &id); + + return id; +} + +char *ivug_db_get_folder_path(media_handle media) +{ + media_folder_h folder_item = (media_folder_h)media; + char *path = NULL; + + media_folder_get_path(folder_item, &path); + + return path; +} + diff --git a/common/src/ivug-drm.c b/common/src/ivug-drm.c new file mode 100755 index 0000000..3f090bc --- /dev/null +++ b/common/src/ivug-drm.c @@ -0,0 +1,363 @@ +/* + * Copyright 2012 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.tizenopensource.org/license + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "ivug-drm.h" + +#include + +#include +#include +#include +#include +#include +#include +#include + +#include "ivug-define.h" +#include "ivug-debug.h" +#include "ivug-file-info.h" +#include "ivug-util.h" + +#include //ecore_file_dir_is_empty + +#define IVUG_DRM_TEMP_DIR DATADIR"/ug-image-viewer-efl/.tmp" + +#define MOUNTH_COUNT 12 //used for drm file info, +#define DAY_COUNT 30 +#define HOUR_COUNT 24 + + +char* +ivug_drm_get_drm_vendor_info(const char *path) +{ + IV_ASSERT(path != NULL); + + drm_result_e ret = DRM_RETURN_INTERNAL_ERROR; + drm_content_info_s content_info; + memset(&content_info, 0x0, sizeof(drm_content_info_s)); + + ret = drm_get_content_info(path, &content_info); + if(ret != DRM_RETURN_SUCCESS) + { + MSG_IVUG_ERROR("drm_get_content_info Error. %s, ret = %d", path, ret); + return NULL; + } + + if(strlen(content_info.author) > 0) + { + return strdup(content_info.author); + } + + return NULL; +} + +bool +ivug_drm_get_forwarding_info(const char *path) +{ + IV_ASSERT(path != NULL); + + ivug_retvm_if(!path, false, "path is NULL"); + + drm_bool_type_e is_allowed = DRM_UNKNOWN; + drm_action_type_e action = DRM_IS_FORWARDING_ALLOWED; + drm_action_allowed_data_s action_data; + int ret = -1; + + memset(&action_data, 0x00, sizeof(drm_action_allowed_data_s)); + + ret = drm_is_action_allowed(action, &action_data, &is_allowed); + if(ret != DRM_RETURN_SUCCESS) + { + MSG_IVUG_ERROR("drm_is_action_allowed failed: %d", ret); + return false; + } + + if(is_allowed == DRM_TRUE) + { + MSG_IVUG_ERROR("Possible to forwarding. file=%s", path); + return true; + } + else + { + MSG_IVUG_ERROR("Impossible to forwarding. file=%s", path); + return false; + } +} + +char * +ivug_drm_get_right_url(const char *path) +{ + drm_content_info_s content_info; + memset(&content_info,0x0,sizeof(drm_content_info_s)); + int ret = -1; + + ret = drm_get_content_info(path, &content_info); + if(ret != DRM_RETURN_SUCCESS) + { + MSG_IVUG_ERROR("drm_get_content_info Error. %s, ret = %d", path, ret); + return NULL; + } + + if('\0' == content_info.rights_url[0]) + { + MSG_IVUG_ERROR("rights_url is NULL. %s", path); + return NULL; + } + MSG_IVUG_HIGH("rights_url = %s", content_info.rights_url); + + return strdup(content_info.rights_url); +} + +char * +ivug_drm_get_mime(const char *path) +{ + drm_content_info_s content_info; + memset(&content_info,0x0,sizeof(drm_content_info_s)); + int ret = -1; + + ret = drm_get_content_info(path, &content_info); + if(ret != DRM_RETURN_SUCCESS) + { + MSG_IVUG_ERROR("drm_get_content_info Error. %s, ret = %d", path, ret); + return NULL; + } + + if('\0' == content_info.mime_type[0]) + { + MSG_IVUG_ERROR("mime_type is NULL. %s", path); + return NULL; + } + MSG_IVUG_HIGH("mime_type = %s", content_info.mime_type); + + return strdup(content_info.mime_type); +} + + +bool +ivug_drm_has_valid_ro(const char *path) +{ + IV_ASSERT(path != NULL); + + drm_result_e ret; + + drm_license_status_e status = DRM_LICENSE_STATUS_UNDEFINED; + + ret = drm_get_license_status(path, DRM_PERMISSION_TYPE_DISPLAY, &status); + if(ret != DRM_RETURN_SUCCESS) + { + MSG_IVUG_ERROR("drm_get_license_status Error. %s, ret = %d", path, ret); + return false; + } + + if(status != DRM_LICENSE_STATUS_VALID) + { + MSG_IVUG_ERROR("No valid right. %s, status = %d", path, status); + return false; + } + + return true; +} + +bool +ivug_drm_is_drm_file(const char* file_path) +{ + IV_ASSERT(file_path != NULL); + + drm_bool_type_e isDRM = DRM_FALSE; + + if(drm_is_drm_file(file_path, &isDRM) == DRM_RETURN_SUCCESS) + { + if(isDRM == DRM_TRUE) + { + MSG_IVUG_MED("DRM file. path=%s", file_path); + return true; + } + return false; + } + + return false; +} + +bool ivug_drm_is_possible_to_setas(const char* path, _ivug_drm_setas_type type) +{ + ivug_retvm_if(!path, false, "path is NULL"); + + drm_bool_type_e is_allowed = DRM_UNKNOWN; + drm_action_type_e action = DRM_HAS_VALID_SETAS_STATUS; + drm_action_allowed_data_s action_data; + int ret = -1; + + memset(&action_data, 0x00, sizeof(drm_action_allowed_data_s)); + + ret = drm_is_action_allowed(action, &action_data, &is_allowed); + if(ret != DRM_RETURN_SUCCESS) + { + MSG_IVUG_ERROR("drm_is_action_allowed failed: %d", ret); + return false; + } + + if(is_allowed == DRM_TRUE) + { + MSG_IVUG_ERROR("Possible to setas. file=%s", path); + return true; + } + else + { + MSG_IVUG_ERROR("Impossible to setas. file=%s", path); + return false; + } +} + + +drm_data_t * ivug_drm_check_constraint(const char* file_path) +{ + + drm_constraint_info_s constraint_info; + drm_permission_type_e perm_type = DRM_PERMISSION_TYPE_DISPLAY; + int ret = -1; + + memset(&constraint_info, 0x0, sizeof(drm_constraint_info_s)); + + ret = drm_get_constraint_info(file_path, perm_type, &constraint_info); + if(ret != DRM_RETURN_SUCCESS) + { + MSG_IVUG_ERROR("drm_get_constraint_info Failed!!, ret=0x%x", ret); + return NULL; + } + + drm_data_t *result = calloc(1, sizeof(drm_data_t)); + + if(constraint_info.const_type.is_unlimited) + { + MSG_IVUG_HIGH("Unlimited:for permission=%d", perm_type); + + result->constraints = IVUG_DRM_RESULT_UNLIMITED; + result->data = -1; + return result; + } + + if(constraint_info.const_type.is_accumulated){ + MSG_IVUG_HIGH("Accumulated Constraint is present"); + MSG_IVUG_HIGH("accumulated_original_seconds=%d", + constraint_info.accumulated_original_seconds); + MSG_IVUG_HIGH("accumulated_remaining_seconds=%d", + constraint_info.accumulated_remaining_seconds); + + result->constraints = IVUG_DRM_RESULT_ACCUMULATED; + result->data = -1; + return result; + } + + if(constraint_info.const_type.is_count){ + MSG_IVUG_HIGH("Count Constraint is present"); + MSG_IVUG_HIGH("original_count=%d", + constraint_info.original_count); + MSG_IVUG_HIGH("remaining_count=%d", + constraint_info.remaining_count); + + result->constraints = IVUG_DRM_RESULT_COUNT; + result->data = constraint_info.remaining_count; + return result; + } + + if(constraint_info.const_type.is_datetime){ + MSG_IVUG_HIGH("DATETIME Constraint is present"); + MSG_IVUG_HIGH("start_time:" + "Year=%d,Month=%d,Day=%d,Hour=%d, minute=%d, Second=%d", + constraint_info.start_time.tm_year, + constraint_info.start_time.tm_mon, + constraint_info.start_time.tm_mday, + constraint_info.start_time.tm_hour, + constraint_info.start_time.tm_min, + constraint_info.start_time.tm_sec); + + MSG_IVUG_HIGH("end_time:" + "Year=%d,Month=%d,Day=%d,Hour=%d, minute=%d, Second=%d", + constraint_info.end_time.tm_year, + constraint_info.end_time.tm_mon, + constraint_info.end_time.tm_mday, + constraint_info.end_time.tm_hour, + constraint_info.end_time.tm_min, + constraint_info.end_time.tm_sec); + + result->constraints = IVUG_DRM_RESULT_DATETIME; + //result->data = constraint.curCount; + result->data = -1; + return result; + } + + if(constraint_info.const_type.is_individual){ + MSG_IVUG_HIGH("INDIVIDUAL Constraint is present"); + MSG_IVUG_HIGH("individual_identity_type=%d " + "individual_id=%s", + constraint_info.individual_identity_type, + constraint_info.individual_id); + + result->constraints = IVUG_DRM_RESULT_INDIVIDUAL; + result->data = -1; + return result; + } + + if(constraint_info.const_type.is_interval){ + MSG_IVUG_HIGH("INTERVAL Constraint is present"); + MSG_IVUG_HIGH("interval_time:" + "Year=%d,Month=%d,Day=%d,Hour=%d, minute=%d, Second=%d", + constraint_info.interval_time.tm_year, + constraint_info.interval_time.tm_mon, + constraint_info.interval_time.tm_mday, + constraint_info.interval_time.tm_hour, + constraint_info.interval_time.tm_min, + constraint_info.interval_time.tm_sec); + + result->constraints = IVUG_DRM_RESULT_INTERVAL_DAYS; + result->data = ((constraint_info.interval_time.tm_year*MOUNTH_COUNT+constraint_info.interval_time.tm_mon)* + DAY_COUNT+constraint_info.interval_time.tm_mday); + return result; + } + + if(constraint_info.const_type.is_system){ + MSG_IVUG_HIGH("SYSTEM Constraint is present"); + MSG_IVUG_HIGH("system_identity_type=%d " + "system_id=%s", + constraint_info.system_identity_type, + constraint_info.system_id); + + result->constraints = IVUG_DRM_RESULT_SYSTEM; + result->data = -1; + return result; + } + + if(constraint_info.const_type.is_timedcount){ + MSG_IVUG_HIGH("TIMED-COUNT Constraint is present"); + MSG_IVUG_HIGH("timed_original_count=%d", + constraint_info.timed_original_count); + + MSG_IVUG_HIGH("timed_remaining_count=%d", + constraint_info.timed_remaining_count); + + MSG_IVUG_HIGH("timed_count_timer=%d", + constraint_info.timed_count_timer); + + result->constraints = IVUG_DRM_RESULT_TIMED_COUNT; + result->data = -1; + return result; + } + + MSG_IVUG_WARN("Undefined constraints"); + free(result); + + return NULL; +} + diff --git a/common/src/ivug-exif.c b/common/src/ivug-exif.c new file mode 100755 index 0000000..97fe9d9 --- /dev/null +++ b/common/src/ivug-exif.c @@ -0,0 +1,1460 @@ +/* + * Copyright 2012 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.tizenopensource.org/license + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * The Exif specification defines an Orientation Tag to indicate the orientation of the + * camera relative to the captured scene. This can be used by the camera either to + * indicate the orientation automatically by an orientation sensor, + * or to allow the user to indicate the orientation manually by a menu switch, + * without actually transforming the image data itself. + * Here is an explanation given by TsuruZoh Tachibanaya in + * his description of the Exif file format: + * + * The orientation of the camera relative to the scene, when the image was captured. + * The relation of the '0th row' and '0th column' to visual position is shown as below. + * + * Value 0th Row 0th Column + * 1 top left side + * 2 top right side + * 3 bottom right side + * 4 bottom left side + * 5 left side top + * 6 right side top + * 7 right side bottom + * 8 left side bottom + * + * Read this table as follows (thanks to Peter Nielsen for clarifying this - see also below): + * Entry #6 in the table says that the 0th row in the stored image is the right side of + * the captured scene, and the 0th column in the stored image is the top side of + * the captured scene. + * + * Here is another description given by Adam M. Costello: + * + * For convenience, here is what the letter F would look like if it were tagged correctly + * and displayed by a program that ignores the orientation tag + * (thus showing the stored image): + * + * 1 2 3 4 5 6 7 8 + * + * 888888 888888 88 88 8888888888 88 88 8888888888 + * 88 88 88 88 88 88 88 88 88 88 88 88 + * 8888 8888 8888 8888 88 8888888888 8888888888 88 + * 88 88 88 88 + * 88 88 888888 888888 +*/ + +#include "ivug-debug.h" +#include "ivug-exif.h" + +#undef LOG_LVL +#define LOG_LVL (DBG_MSG_LVL_MED | DBG_MSG_LVL_DEBUG) + +#undef LOG_CAT +#define LOG_CAT "IV-UTIL" + + +#if 0 + +#include +#include + +static int _save_exif_orientation(FILE *src_fp, char *value, bool bSave) +{ + MSG_ASSERT(src_fp != NULL); + + unsigned char tmp[2048] = {0}; + size_t io_size = 0; + io_size = fread(tmp, sizeof(char), 18, src_fp); + if (strcasecmp((const char *)&tmp[2], "Exif")){ + MSG_ERROR("This is not a EXIF file!"); + goto ERROR; + } + + while (1) { + /*Read Marker*/ + memset(tmp, 0, 2048); + io_size = fread(tmp, sizeof(char), 8, src_fp); + if (io_size < 1) { + MSG_ERROR("Encode error!"); + goto ERROR; + } + /*When marker is Orientation*/ + if (tmp[0] == 0x12 && tmp[1] == 0x01) { + if (bSave) { + io_size = fwrite(value, 1, 1, src_fp); + MSG_HIGH("write value: %d!", value[0]); + } else { + memset(tmp, 0, 2048); + io_size = fread(value, sizeof(char), 1, src_fp); + MSG_HIGH("Read value: %d!", value[0]); + } + if (io_size < 1) { + MSG_ERROR("Write or read error!"); + goto ERROR; + } + MSG_HIGH("Read or write value: %d!", value[0]); + break; + } else if (tmp[0] == 0x69 && tmp[1] == 0x87) { + break; + } else { + if (-1 == fseek(src_fp, 4, SEEK_CUR)) { + MSG_ERROR("fseek error!"); + goto ERROR; + } + } + + } + return 0; + ERROR: + return -1; +} + + +static int _save_jfif_orientation(FILE *src_fp, char *value, bool bSave) +{ + MSG_ASSERT(src_fp != NULL); + + unsigned char tmp[2048] = {0}; + size_t io_size = 0; + io_size = fread(tmp, sizeof(char), 36, src_fp); + + if (strcasecmp((const char *)&tmp[2], "jfif")) + { + MSG_ERROR("This is not a jfif file!"); + goto ERROR; + } + if (tmp[17] < 0xE1 || tmp[17] > 0xEF) + { + MSG_ERROR("This file is no orientation!"); + goto ERROR; + } + + while (1) { + /*Read Marker*/ + memset(tmp, 0, 2048); + io_size = fread(tmp, sizeof(char), 8, src_fp); + if (io_size < 1) + { + MSG_ERROR("Encode error!"); + goto ERROR; + } + + MSG_HIGH("tmp[0] is %02x, tmp[1] is %02x", tmp[0], tmp[1]); + + /*When marker is Orientation*/ + if (tmp[0] == 0x01 && tmp[1] == 0x12) { + memset(tmp, 0, 2048); + io_size = fread(tmp, sizeof(char), 1, src_fp); + if (io_size < 1) { + MSG_ERROR("Write error!"); + goto ERROR; + } + if (bSave) { + io_size = fwrite(value, 1, 1, src_fp); + } else { + memset(tmp, 0, 2048); + io_size = fread(value, sizeof(char), 1, src_fp); + } + if (io_size < 1) { + MSG_ERROR("Write or read error!"); + goto ERROR; + } + MSG_HIGH("Read or write value: %d!", value[0]); + break; + } else if (tmp[0] == 0x87 && tmp[1] == 0x69) { + break; + } else { + if (-1 == fseek(src_fp, 4, SEEK_CUR)) { + MSG_ERROR("fseek error!"); + goto ERROR; + } + } + + } + return 0; + ERROR: + return -1; + +} + +static int _jpeg_rotate(const char *file_path, char *value, bool bSave) +{ + MSG_ASSERT(file_path != NULL); + + int ret = -1; + FILE *src_fp = fopen(file_path, "rb+"); + if (NULL == src_fp) + { + MSG_ERROR("Open file error! %s", file_path); + return -1; + } + + unsigned char tmp[2048] = {0}; + size_t io_size = 0; + + io_size = fread(tmp, sizeof(char), 2, src_fp); + + if (io_size < 1 || 0xFF != tmp[0] || 0xD8 != tmp[1]) + { + MSG_ERROR("This is not a JPEG file!"); + goto ERROR; + } + + /*Read APP1 lable*/ + memset(tmp, 0, 2048); + io_size = fread(tmp, sizeof(char), 2, src_fp); + if (io_size < 1 || 0xFF != tmp[0]) + { + MSG_ERROR("This is not a EXIF file!"); + goto ERROR; + } + + if (tmp[1] == 0xE0) + { + ret = _save_jfif_orientation(src_fp, value, bSave); + } + else if (tmp[1] == 0xE1) + { + ret = _save_exif_orientation(src_fp, value, bSave); + } + else + { + MSG_ERROR("This is not a EXIF file!"); + goto ERROR; + } + + ERROR: + fclose(src_fp); + return ret; +} +#endif + +#if 1 + + +#include +#include +#include +#include + +#define GL_EXIF_BUF_LEN_MAX 65536L +#define GL_EXIF_BUF_TIME_LEN_MAX 20 +#define GL_EXIF_DEFAULT_YEAR 1900 + +#define GL_EXIF_SOI 0xD8 +#define GL_EXIF_TAG 0xFF +#define GL_EXIF_APP0 0xE0 +#define GL_EXIF_APP1 0xE1 +#define GL_EXIF_JFIF_00 0x00 +#define GL_EXIF_JFIF_01 0x01 +#define GL_EXIF_JFIF_02 0x02 + +#define GL_EXI_TMP_JPEG_FILE "/opt/media/.gallery_tmp_write_exif.jpg" + +/* Write one byte, testing for EOF */ +static int __gl_exif_write_1_byte(FILE *fd, int c) +{ + if (fputc(c, fd) < 0) { + MSG_ERROR("fputc failed!"); + return -1; + } + + return 0; +} + +/* Read one byte, testing for EOF */ +static int __gl_exif_read_1_byte(FILE *fd) +{ + int c = 0; + + /* Return next input byte, or EOF if no more */ + c = getc(fd); + if (c == EOF) { + MSG_ERROR("Premature EOF in JPEG file!"); + return -1; + } + + return c; +} + +/* Read 2 bytes, convert to unsigned int */ +/* All 2-byte quantities in JPEG markers are MSB first */ +static int __gl_exif_read_2_bytes(FILE *fd, unsigned int *len) +{ + int c1 = 0; + int c2 = 0; + + /* Return next input byte, or EOF if no more */ + c1 = getc(fd); + if (c1 == EOF) { + MSG_ERROR("Premature EOF in JPEG file!"); + return -1; + } + + /* Return next input byte, or EOF if no more */ + c2 = getc(fd); + if (c2 == EOF) { + MSG_ERROR("Premature EOF in JPEG file!"); + return -1; + } + + if (len) + *len = (((unsigned int)c1) << 8) + ((unsigned int)c2); + + return 0; +} + +/* Add raw exif tag and data */ +static int __gl_exif_add_header(FILE *fd, unsigned int *orientation) +{ + int i = 0; + int ret = -1; + char *time_buf = NULL; + unsigned int offset = 0; + + /* raw EXIF header data */ + const unsigned char exif1[] = { + GL_EXIF_TAG, GL_EXIF_SOI, GL_EXIF_TAG, GL_EXIF_APP1 + }; + /* Write File head, check for JPEG SOI + Exif APP1 */ + for (i = 0; i < 4; i++) { + if (__gl_exif_write_1_byte(fd, exif1[i]) < 0) + goto GL_EXIF_FAILED; + } + /* SET the marker parameter length count */ + /* Length includes itself, so must be at least 2 + Following Exif data length must be at least 6; 30+36 bytes*/ + const unsigned char exif2[] = { 0x00, 0x42 }; + for (i = 0; i < 2; i++) { + if (__gl_exif_write_1_byte(fd, exif2[i]) < 0) + goto GL_EXIF_FAILED; + } + + /* Write Exif head -- "Exif" */ + const unsigned char exif3[] = { 0x45, 0x78, 0x69, 0x66, 0x00, 0x00 }; + for (i = 0; i < 6; i++) { + if (__gl_exif_write_1_byte(fd, exif3[i]) < 0) + goto GL_EXIF_FAILED; + } + + /* Set byte order and Tag Mark , "II(0x4949)" */ + const unsigned char exif4[] = { 0x49, 0x49, 0x2A, 0x00 }; + for (i = 0; i < 4; i++) { + if (__gl_exif_write_1_byte(fd, exif4[i]) < 0) + goto GL_EXIF_FAILED; + } + offset += 4; + + /* Set first IFD offset (offset to IFD0) , II-08000000 */ + const unsigned char exif5[] = { 0x08, 0x00, 0x00, 0x00 }; + for (i = 0; i < 4; i++) { + if (__gl_exif_write_1_byte(fd, exif5[i]) < 0) + goto GL_EXIF_FAILED; + } + offset += 4; + + /* IFD: Image File Directory */ + /* Set the number of directory entries contained in this IFD, - EEEE ; + * 2 entry: orientation, data time */ + const unsigned char exif6[] = { 0x02, 0x00 }; + for (i = 0; i < 2; i++) { + if (__gl_exif_write_1_byte(fd, exif6[i]) < 0) + goto GL_EXIF_FAILED; + } + offset += 2; + + /* Add Orientation Tag in IFD0; 0x0112 */ + const unsigned char exif7[] = { 0x12, 0x01 }; + for (i = 0; i < 2; i++) { + if (__gl_exif_write_1_byte(fd, exif7[i]) < 0) + goto GL_EXIF_FAILED; + } + offset += 2; + + MSG_HIGH("Write: %d", *orientation); + const unsigned char exif8[] = { 0x03, 0x00, 0x01, 0x00, 0x00, 0x00 }; + for (i = 0; i < 6; i++) { + if (__gl_exif_write_1_byte(fd, exif8[i]) < 0) + goto GL_EXIF_FAILED; + } + offset += 6; + + /* Set the Orientation value */ + if (__gl_exif_write_1_byte(fd, (unsigned char)(*orientation)) < 0) + goto GL_EXIF_FAILED; + + const unsigned char exif9[] = { 0x00, 0x00, 0x00 }; + for (i = 0; i < 3; i++) { + if (__gl_exif_write_1_byte(fd, exif9[i]) < 0) + goto GL_EXIF_FAILED; + } + offset += 4; + + /* Add Data Time Tag in IFD0; 0x0132 */ + const unsigned char exif10[] = { 0x32, 0x01 }; + for (i = 0; i < 2; i++) { + if (__gl_exif_write_1_byte(fd, exif10[i]) < 0) + goto GL_EXIF_FAILED; + } + offset += 2; + + /* Type: strings */ + const unsigned char exif11[] = { 0x02, 0x00 }; + for (i = 0; i < 2; i++) { + if (__gl_exif_write_1_byte(fd, exif11[i]) < 0) + goto GL_EXIF_FAILED; + } + offset += 2; + + /* Data lengh, byte count */ + const unsigned char exif12[] = { 0x14, 0x00, 0x00, 0x00 }; + for (i = 0; i < 4; i++) { + if (__gl_exif_write_1_byte(fd, exif12[i]) < 0) + goto GL_EXIF_FAILED; + } + offset += 8; + + /* 20 bytes larger than 4 bytes, + * so next 4 bytes is data offset start from "II"(0x4949)*/ + + MSG_HIGH("offset: %2X", offset + 8); + /* Too add data offset, plus 4 bytes self and plus 4 bytes IFD terminator */ + if (__gl_exif_write_1_byte(fd, (unsigned char)(offset + 4)) < 0) + goto GL_EXIF_FAILED; + + const unsigned char exif13[] = { 0x00, 0x00, 0x00 }; + for (i = 0; i < 3; i++) { + if (__gl_exif_write_1_byte(fd, exif13[i]) < 0) + goto GL_EXIF_FAILED; + } + + /*After last directory entry, there is a 4bytes of data('LLLLLLLL' at the chart), + * it means an offset to next IFD. If its value is '0x00000000', + * it means this is the last IFD and there is no linked IFD */ + const unsigned char exif14[] = { 0x00, 0x00, 0x00, 0x00 }; + for (i = 0; i < 4; i++) { + if (__gl_exif_write_1_byte(fd, exif14[i]) < 0) + goto GL_EXIF_FAILED; + } + + /* Date Time of image was last modified. + * Data format is "YYYY:MM:DD HH:MM:SS"+0x00, total 20bytes + */ + time_t t; + struct tm tms; + struct tm *tm; + + t = time (NULL); + tm = localtime_r(&t, &tms); + + time_buf = (char *)calloc(1, GL_EXIF_BUF_TIME_LEN_MAX); + if (time_buf == NULL) { + MSG_ERROR("Faild to allocate memory!"); + goto GL_EXIF_FAILED; + } + snprintf(time_buf, GL_EXIF_BUF_TIME_LEN_MAX, + "%04i:%02i:%02i %02i:%02i:%02i", + tm->tm_year + GL_EXIF_DEFAULT_YEAR, tm->tm_mon + 1, + tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec); + + MSG_HIGH("time_buf: %s", time_buf); + if (fwrite(time_buf, 1, GL_EXIF_BUF_TIME_LEN_MAX, fd) != GL_EXIF_BUF_TIME_LEN_MAX) { + MSG_WARN("Write size are diff!"); + goto GL_EXIF_FAILED; + } + + ret = 0; + + GL_EXIF_FAILED: + + MSG_HIGH("All done"); + if (time_buf) + free(time_buf); + return ret; +} + +/* Add exif to jfif 1.00, to add exif for some cases */ +static int __gl_exif_rw_jfif_1dot00(const char *file_path, unsigned int *orientation) +{ + unsigned char tmp[GL_EXIF_BUF_LEN_MAX] = { 0, }; + FILE *fd = NULL; + int ret = -1; + int tmp_exif = -1; + + if ((fd = fopen(file_path, "rb+")) == NULL) { + MSG_ERROR("Can't open %s!", file_path); + return -1; + } + + char *tmp_file = GL_EXI_TMP_JPEG_FILE; + FILE *tmp_fd = NULL; + if ((tmp_fd = fopen(tmp_file, "wb+")) == NULL) { + MSG_ERROR("Can't open %s!", tmp_file); + goto GL_EXIF_FAILED; + } + + /* Remove header of JFIF from 0 to first 0xFF */ + bool b_tag_ff = false; + while(1) { + tmp_exif = __gl_exif_read_1_byte(fd); + if (tmp_exif < 0) + goto GL_EXIF_FAILED; + + tmp[0] = (unsigned char)tmp_exif; + + MSG_HIGH("- %02X", tmp[0]); + if (!b_tag_ff) { + if (tmp[0] == GL_EXIF_TAG) { + MSG_WARN("0xFF!"); + b_tag_ff = true; + } + /* Move back 1 byte */ + fseek(tmp_fd, -1, SEEK_CUR); + break; + } + } + + /* Add raw EXIF header data */ + if (__gl_exif_add_header(tmp_fd, orientation) < 0) + goto GL_EXIF_FAILED; + + size_t r_size = 0; + memset(tmp, 0x00, GL_EXIF_BUF_LEN_MAX); + /* Write JPEG image data from first 0xFF to tmp file after EXIF header */ + while ((r_size = fread(tmp, 1, sizeof(tmp), fd)) > 0) { + MSG_HIGH("r_size: %ld", r_size); + if (fwrite(tmp, 1, r_size, tmp_fd) != r_size) + MSG_WARN("Write and read size are diff!"); + + memset(tmp, 0x00, GL_EXIF_BUF_LEN_MAX); + } + + fclose(fd); + fd = fopen(file_path, "wb"); + if (!fd) { + MSG_ERROR("Error creating file %s!", file_path); + goto GL_EXIF_FAILED; + } + + memset(tmp, 0x00, GL_EXIF_BUF_LEN_MAX); + /* Write back tmp file after to JPEG image */ + fseek(tmp_fd, 0, SEEK_SET); + while ((r_size = fread(tmp, 1, sizeof(tmp), tmp_fd)) > 0) { + MSG_HIGH("r_size: %ld", r_size); + if (fwrite(tmp, 1, r_size, fd) != r_size) + MSG_WARN("Write and read size are diff!"); + + memset(tmp, 0x00, GL_EXIF_BUF_LEN_MAX); + } + + ret = 0; + + GL_EXIF_FAILED: + + if (fd) + fclose(fd); + if (tmp_fd) + fclose(tmp_fd); + + if (tmp_file) { + /* Delete tmp file */ + if (!ecore_file_unlink(tmp_file)) + MSG_ERROR("Delete file failed"); + } + + MSG_HIGH("All done"); + return ret; +} + +/* Add exif to jfif 1.01, older version, don't have exif */ +static int __gl_exif_rw_jfif_1dot01(const char *file_path, unsigned int *orientation) +{ + unsigned char tmp[GL_EXIF_BUF_LEN_MAX] = { 0, }; + FILE *fd = NULL; + int ret = -1; + + if ((fd = fopen(file_path, "rb+")) == NULL) { + MSG_ERROR("Can't open %s!", file_path); + return -1; + } + + char *tmp_file = GL_EXI_TMP_JPEG_FILE; + FILE *tmp_fd = NULL; + if ((tmp_fd = fopen(tmp_file, "wb+")) == NULL) { + MSG_ERROR("Can't open %s!", tmp_file); + goto GL_EXIF_FAILED; + } + + /* Add raw EXIF header data */ + if (__gl_exif_add_header(tmp_fd, orientation) < 0) + goto GL_EXIF_FAILED; + + size_t r_size = 0; + /* Remove start of JPEG image data section, 20 bytes */ + r_size = fread(tmp, sizeof(char), 20, fd); + + memset(tmp, 0x00, GL_EXIF_BUF_LEN_MAX); + /* Write JPEG image data to tmp file after EXIF header */ + while ((r_size = fread(tmp, 1, sizeof(tmp), fd)) > 0) { + MSG_HIGH("r_size: %ld", r_size); + if (fwrite(tmp, 1, r_size, tmp_fd) != r_size) + MSG_WARN("Write and read size are diff!"); + + memset(tmp, 0x00, GL_EXIF_BUF_LEN_MAX); + } + + fclose(fd); + fd = fopen(file_path, "wb"); + if (!fd) { + MSG_ERROR("Error creating file %s!", file_path); + goto GL_EXIF_FAILED; + } + + memset(tmp, 0x00, GL_EXIF_BUF_LEN_MAX); + /* Write back tmp file after to JPEG image */ + fseek(tmp_fd, 0, SEEK_SET); + while ((r_size = fread(tmp, 1, sizeof(tmp), tmp_fd)) > 0) { + MSG_HIGH("r_size: %ld", r_size); + if (fwrite(tmp, 1, r_size, fd) != r_size) + MSG_WARN("Write and read size are diff!"); + + memset(tmp, 0x00, GL_EXIF_BUF_LEN_MAX); + } + + ret = 0; + + GL_EXIF_FAILED: + + if (fd) + fclose(fd); + if (tmp_fd) + fclose(tmp_fd); + + if (tmp_file) { + /* Delete tmp file */ + if (!ecore_file_unlink(tmp_file)) + MSG_ERROR("Delete file failed"); + } + + MSG_HIGH("All done"); + return ret; +} + +/* Add exif to jfif 1.02, to add exif for some cases */ +static int __gl_exif_rw_jfif_1dot02(const char *file_path, unsigned int *orientation) +{ + unsigned char tmp[GL_EXIF_BUF_LEN_MAX] = { 0, }; + FILE *fd = NULL; + int ret = -1; + int tmp_exif = -1; + + if ((fd = fopen(file_path, "rb+")) == NULL) { + MSG_ERROR("Can't open %s!", file_path); + return -1; + } + + char *tmp_file = GL_EXI_TMP_JPEG_FILE; + FILE *tmp_fd = NULL; + if ((tmp_fd = fopen(tmp_file, "wb+")) == NULL) { + MSG_ERROR("Can't open %s!", tmp_file); + goto GL_EXIF_FAILED; + } + + /* Copy header of JFIF from 0 to first 0xFF */ + bool b_tag_ff = false; + while(1) { + tmp_exif = __gl_exif_read_1_byte(fd); + if (tmp_exif < 0) + goto GL_EXIF_FAILED; + + tmp[0] = (unsigned char)tmp_exif; + + MSG_HIGH("- %02X", tmp[0]); + if (!b_tag_ff) { + if (tmp[0] == GL_EXIF_TAG) { + MSG_WARN("0xFF!"); + b_tag_ff = true; + } + /* Move back 1 byte */ + fseek(tmp_fd, -1, SEEK_CUR); + break; + } + + if (__gl_exif_write_1_byte(tmp_fd, tmp[0]) < 0) + goto GL_EXIF_FAILED; + + } + + /* Add raw EXIF header data */ + if (__gl_exif_add_header(tmp_fd, orientation) < 0) + goto GL_EXIF_FAILED; + + size_t r_size = 0; + memset(tmp, 0x00, GL_EXIF_BUF_LEN_MAX); + /* Write JPEG image data from first 0xFF to tmp file after EXIF header */ + while ((r_size = fread(tmp, 1, sizeof(tmp), fd)) > 0) { + MSG_HIGH("r_size: %ld", r_size); + if (fwrite(tmp, 1, r_size, tmp_fd) != r_size) + MSG_WARN("Write and read size are diff!"); + + memset(tmp, 0x00, GL_EXIF_BUF_LEN_MAX); + } + + fclose(fd); + fd = fopen(file_path, "wb"); + if (!fd) { + MSG_ERROR("Error creating file %s!", file_path); + goto GL_EXIF_FAILED; + } + + memset(tmp, 0x00, GL_EXIF_BUF_LEN_MAX); + /* Write back tmp file after to JPEG image */ + fseek(tmp_fd, 0, SEEK_SET); + while ((r_size = fread(tmp, 1, sizeof(tmp), tmp_fd)) > 0) { + MSG_HIGH("r_size: %ld", r_size); + if (fwrite(tmp, 1, r_size, fd) != r_size) + MSG_WARN("Write and read size are diff!"); + + memset(tmp, 0x00, GL_EXIF_BUF_LEN_MAX); + } + + ret = 0; + + GL_EXIF_FAILED: + + if (fd) + fclose(fd); + if (tmp_fd) + fclose(tmp_fd); + + if (tmp_file) { + /* Delete tmp file */ + if (!ecore_file_unlink(tmp_file)) + MSG_ERROR("Delete file failed"); + } + + MSG_HIGH("All done"); + return ret; +} + +static int __gl_exif_rw_jfif(FILE *fd, const char *file_path, + unsigned int *orientation, bool b_write) +{ + unsigned char tmp[GL_EXIF_BUF_LEN_MAX] = { 0, }; + int i = 0; + unsigned int length = 0; + int tmp_exif = -1; + bool is_motorola = false; /* Flag for byte order */ + unsigned int offset = 0; + int ret = -1; + unsigned char version = 0x00; + + if (__gl_exif_read_2_bytes(fd, &length) < 0) + goto GL_EXIF_FAILED; + MSG_HIGH("length: %d", length); + + for (i = 0; i < 5; i++) { + tmp_exif = __gl_exif_read_1_byte(fd); + if (tmp_exif < 0) + goto GL_EXIF_FAILED; + tmp[i] = (unsigned char)tmp_exif; + } + + /* JFIF0 */ + if (tmp[0] != 0x4A || tmp[1] != 0x46 || tmp[2] != 0x49 || + tmp[3] != 0x46 || tmp[4] != 0x00) { + MSG_ERROR("Not met Jfif!"); + goto GL_EXIF_FAILED; + } + + for (i = 0; i < 2; i++) { + tmp_exif = __gl_exif_read_1_byte(fd); + if (tmp_exif < 0) + goto GL_EXIF_FAILED; + tmp[i] = (unsigned char)tmp_exif; + } + + /* Check JFIF version */ + if (tmp[0] == 0x01 && tmp[1] == GL_EXIF_JFIF_00) { + MSG_HIGH("Jfif 1.00"); + } else if (tmp[0] == 0x01 && tmp[1] == GL_EXIF_JFIF_01) { + MSG_HIGH("Jfif 1.01"); + } else if (tmp[0] == 0x01 && tmp[1] == GL_EXIF_JFIF_02) { + MSG_HIGH("Jfif 1.02"); + } else { + MSG_ERROR("Unknow Jfif version[%d.%d]!", tmp[0], tmp[1]); + goto GL_EXIF_FAILED; + } + + /* Save version */ + version = tmp[1]; + + /* Find APP1 */ + bool b_tag_ff = false; + while(1) { + tmp_exif = __gl_exif_read_1_byte(fd); + if (tmp_exif < 0) + goto GL_EXIF_FAILED; + + tmp[0] = (unsigned char)tmp_exif; + + MSG_HIGH("- %02X", tmp[0]); + if (!b_tag_ff) { + /* Get first tag */ + if (tmp[0] == GL_EXIF_TAG) { + MSG_WARN("0xFF!"); + b_tag_ff = true; + } + continue; + } + + /* Get APP1 */ + if (tmp[0] == GL_EXIF_APP1) { + MSG_WARN("Exif in APP1!"); + break; + } + + MSG_WARN("No Exif in APP1!"); + + /* Close file */ + fclose(fd); + if (!b_write) { + /* Normal orientation = 0degree = 1 */ + *orientation = 1; + return 0; + } + + if (version == GL_EXIF_JFIF_00) { + return __gl_exif_rw_jfif_1dot00(file_path, orientation); + } else if (version == GL_EXIF_JFIF_01) { + return __gl_exif_rw_jfif_1dot01(file_path, orientation); + } else { + return __gl_exif_rw_jfif_1dot02(file_path, orientation); + } + } + + /* Find Exif */ + while(1) { + tmp_exif = __gl_exif_read_1_byte(fd); + if (tmp_exif < 0) + goto GL_EXIF_FAILED; + + tmp[0] = (unsigned char)tmp_exif; + if (tmp[0] != 0x45) + continue; + + for (i = 0; i < 5; i++) { + tmp_exif = __gl_exif_read_1_byte(fd); + if (tmp_exif < 0) + goto GL_EXIF_FAILED; + + tmp[i] = (unsigned char)tmp_exif; + MSG_HIGH("- %02X", tmp[i]); + } + if (tmp[0] == 0x78 && tmp[1] == 0x69 && tmp[2] == 0x66 && + tmp[3] == 0x00 && tmp[4] == 0x00) { + MSG_WARN("Met Exif!"); + break; + } else { + MSG_WARN("Not met Exif!"); + goto GL_EXIF_FAILED; + } + } + + /* Read Exif body */ + for (i = 0; i < 4; i++) { + tmp_exif = __gl_exif_read_1_byte(fd); + if (tmp_exif < 0) + goto GL_EXIF_FAILED; + tmp[i] = (unsigned char)tmp_exif; + } + + /* Check byte order and Tag Mark , "II(0x4949)" or "MM(0x4d4d)" */ + if (tmp[0] == 0x49 && tmp[1] == 0x49 && tmp[2] == 0x2A && + tmp[3] == 0x00) { + MSG_HIGH("Intel"); + is_motorola = false; + } else if (tmp[0] == 0x4D && tmp[1] == 0x4D && tmp[2] == 0x00 && + tmp[3] == 0x2A) { + MSG_HIGH("Motorola"); + is_motorola = true; + } else { + goto GL_EXIF_FAILED; + } + + for (i = 0; i < 4; i++) { + tmp_exif = __gl_exif_read_1_byte(fd); + if (tmp_exif < 0) + goto GL_EXIF_FAILED; + + tmp[i] = (unsigned char)tmp_exif; + MSG_HIGH("- %02X", tmp[i]); + } + + /* Get first IFD offset (offset to IFD0) , MM-08000000, II-00000008 */ + if (is_motorola) { + if (tmp[4] != 0 && tmp[5] != 0) + goto GL_EXIF_FAILED; + offset = tmp[6]; + offset <<= 8; + offset += tmp[7]; + } else { + if (tmp[7] != 0 && tmp[6] != 0) + goto GL_EXIF_FAILED; + offset = tmp[5]; + offset <<= 8; + offset += tmp[4]; + } + MSG_HIGH("offset: %d", offset); + + /* IFD: Image File Directory */ + /* Get the number of directory entries contained in this IFD, - 2 bytes, EE */ + unsigned int tags_cnt = 0; + for (i = 0; i < 2; i++) { + tmp_exif = __gl_exif_read_1_byte(fd); + if (tmp_exif < 0) + goto GL_EXIF_FAILED; + + tmp[i] = (unsigned char)tmp_exif; + } + if (is_motorola) { + tags_cnt = tmp[0]; + tags_cnt <<= 8; + tags_cnt += tmp[1]; + } else { + tags_cnt = tmp[1]; + tags_cnt <<= 8; + tags_cnt += tmp[0]; + } + MSG_HIGH("tags_cnt: %d", tags_cnt); + if (tags_cnt == 0) { + MSG_ERROR("tags_cnt == 0 - 2"); + goto GL_EXIF_FAILED; + } + + /* Search for Orientation Tag in IFD0 */ + unsigned int tag_num = 0; + while (1) { + /* Every directory entry size is 12 */ + for (i = 0; i < 12; i++) { + tmp_exif = __gl_exif_read_1_byte(fd); + if (tmp_exif < 0) + goto GL_EXIF_FAILED; + + tmp[i] = (unsigned char)tmp_exif; + } + /* Get Tag number */ + if (is_motorola) { + tag_num = tmp[0]; + tag_num <<= 8; + tag_num += tmp[1]; + } else { + tag_num = tmp[1]; + tag_num <<= 8; + tag_num += tmp[0]; + } + /* found Orientation Tag */ + if (tag_num == 0x0112) { + MSG_WARN("Found orientation tag!"); + break; + } + if (--tags_cnt == 0) { + MSG_ERROR("tags_cnt == 0"); + goto GL_EXIF_FAILED; + } + } + + /* |TT|ff|NNNN|DDDD| --- TT - 2 bytes, tag NO. ;ff - 2 bytes, data format + NNNN - 4 bytes, entry count; DDDD - 4 bytes Data value */ + if (b_write) { + MSG_HIGH("Write: %d", *orientation); + /* Set the Orientation value */ + if (is_motorola) + tmp[9] = (unsigned char)(*orientation); + else + tmp[8] = (unsigned char)(*orientation); + + /* Move pointer back to the entry start point */ + fseek(fd, -12, SEEK_CUR); + fwrite(tmp, 1, 10, fd); + } else { + /* Get the Orientation value */ + if (is_motorola) { + if (tmp[8] != 0) { + MSG_ERROR("tmp[8] != 0"); + goto GL_EXIF_FAILED; + } + *orientation = (unsigned int)tmp[9]; + } else { + if (tmp[9] != 0) { + MSG_ERROR("tmp[9] != 0"); + goto GL_EXIF_FAILED; + } + *orientation = (unsigned int)tmp[8]; + } + if (*orientation > 8) { + MSG_ERROR("*orient > 8"); + goto GL_EXIF_FAILED; + } + MSG_HIGH("Read: %d", *orientation); + } + + ret = 0; + + GL_EXIF_FAILED: + + fclose(fd); + MSG_HIGH("All done"); + return ret; +} + +static int __gl_exif_rw_orient(const char *file_path, unsigned int *orient, bool b_write) +{ + MSG_HIGH("b_write: %d", b_write); + unsigned int length = 0; + unsigned int i = 0; + bool is_motorola = false; /* Flag for byte order */ + unsigned int offset = 0; + unsigned int jfif_offset = 0; + unsigned int tags_cnt = 0; + unsigned int tag_num = 0; + int tmp_exif = -1; + unsigned char exif_data[GL_EXIF_BUF_LEN_MAX] = { 0, }; + FILE *fd = NULL; + int ret = -1; + + if (b_write) { + if ((fd = fopen(file_path, "rb+")) == NULL) { + MSG_ERROR("Can't open %s!", file_path); + return -1; + } + } else { + if ((fd = fopen(file_path, "rb")) == NULL) { + MSG_ERROR("Can't open %s!", file_path); + return -1; + } + } + + /* Read File head, check for JPEG SOI + Exif APP1 */ + for (i = 0; i < 4; i++) { + tmp_exif = __gl_exif_read_1_byte(fd); + if (tmp_exif < 0) + goto GL_EXIF_FAILED; + + exif_data[i] = (unsigned char)tmp_exif; + } + + if (exif_data[0] == GL_EXIF_TAG && exif_data[1] == GL_EXIF_SOI) { + MSG_HIGH("JPEG file"); + } else { + MSG_ERROR("Not a JPEG file!"); + goto GL_EXIF_FAILED; + } + + if (exif_data[2] == GL_EXIF_TAG && exif_data[3] == GL_EXIF_APP1) { + MSG_WARN("Exif in APP1!"); + } else if (exif_data[2] == GL_EXIF_TAG && + exif_data[3] == GL_EXIF_APP0) { + MSG_WARN("Jfif in APP0!"); + int ret = __gl_exif_rw_jfif(fd, file_path, orient, b_write); + return ret; + } else { + MSG_ERROR("Not a Exif in APP1 or Jiff in APP2[%d]!", exif_data[3]); + goto GL_EXIF_FAILED; + } + + /* Get the marker parameter length count */ + if (__gl_exif_read_2_bytes(fd, &length) < 0) + goto GL_EXIF_FAILED; + MSG_HIGH("length: %d", length); + /* Length includes itself, so must be at least 2 + Following Exif data length must be at least 6 */ + if (length < 8) { + MSG_ERROR("length < 8"); + goto GL_EXIF_FAILED; + } + length -= 8; + + /* Length of an IFD entry */ + if (length < 12) { + MSG_ERROR("length < 12"); + goto GL_EXIF_FAILED; + } + + /* Read Exif head, check for "Exif" */ + for (i = 0; i < 6; i++) { + tmp_exif = __gl_exif_read_1_byte(fd); + if (tmp_exif < 0) + goto GL_EXIF_FAILED; + + exif_data[i] = (unsigned char)tmp_exif; + MSG_HIGH("- %02X", exif_data[i]); + } + + if (exif_data[0] != 0x45 || exif_data[1] != 0x78 || + exif_data[2] != 0x69 || exif_data[3] != 0x66 || + exif_data[4] != 0x00 || exif_data[5] != 0x00) { + MSG_ERROR("Not met Exif!"); + goto GL_EXIF_FAILED; + } + + /* Read Exif body */ + for (i = 0; i < length; i++) { + tmp_exif = __gl_exif_read_1_byte(fd); + if (tmp_exif < 0) + goto GL_EXIF_FAILED; + exif_data[i] = (unsigned char)tmp_exif; + } + + /* Check byte order and Tag Mark , "II(0x4949)" or "MM(0x4d4d)" */ + if (exif_data[0] == 0x49 && exif_data[1] == 0x49 && + exif_data[2] == 0x2A && exif_data[3] == 0x00) { + MSG_HIGH("Intel"); + is_motorola = false; + } else if (exif_data[0] == 0x4D && exif_data[1] == 0x4D && + exif_data[2] == 0x00 && exif_data[3] == 0x2A) { + MSG_HIGH("Motorola"); + is_motorola = true; + } else { + goto GL_EXIF_FAILED; + } + + /* Get first IFD offset (offset to IFD0) , MM-00000008, II-08000000 */ + if (is_motorola) { + if (exif_data[4] != 0 && exif_data[5] != 0) + goto GL_EXIF_FAILED; + offset = exif_data[6]; + offset <<= 8; + offset += exif_data[7]; + } else { + if (exif_data[7] != 0 && exif_data[6] != 0) + goto GL_EXIF_FAILED; + offset = exif_data[5]; + offset <<= 8; + offset += exif_data[4]; + } + /* check end of data segment */ + if (offset > length - 2) { + MSG_ERROR("offset > length - 2"); + goto GL_EXIF_FAILED; + } + /* IFD: Image File Directory */ + /* Get the number of directory entries contained in this IFD, - EEEE */ + if (is_motorola) { + tags_cnt = exif_data[offset]; + tags_cnt <<= 8; + tags_cnt += exif_data[offset+1]; + } else { + tags_cnt = exif_data[offset+1]; + tags_cnt <<= 8; + tags_cnt += exif_data[offset]; + } + if (tags_cnt == 0) { + MSG_ERROR("tags_cnt == 0 - 2"); + goto GL_EXIF_FAILED; + } + offset += 2; + + /* check end of data segment */ + if (offset > length - 12) { + MSG_ERROR("offset > length - 12"); + goto GL_EXIF_FAILED; + } + + /* Search for Orientation Tag in IFD0 */ + while (1) { + /* Get Tag number */ + if (is_motorola) { + tag_num = exif_data[offset]; + tag_num <<= 8; + tag_num += exif_data[offset+1]; + } else { + tag_num = exif_data[offset+1]; + tag_num <<= 8; + tag_num += exif_data[offset]; + } + /* found Orientation Tag */ + if (tag_num == 0x0112) { + MSG_WARN("Found orientation tag!"); + break; + } + if (--tags_cnt == 0) { + MSG_ERROR("tags_cnt == 0"); + goto GL_EXIF_FAILED; + } + /* Every directory entry size is 12 */ + offset += 12; + } + + if (b_write) { + MSG_HIGH("Write: %d", *orient); + /* Set the Orientation value */ + if (is_motorola) + exif_data[offset+9] = (unsigned char)(*orient); + else + exif_data[offset+8] = (unsigned char)(*orient); + + fseek(fd, jfif_offset + (4 + 2 + 6 + 2) + offset, SEEK_SET); + fwrite(exif_data + 2 + offset, 1, 10, fd); + } else { + /* Get the Orientation value */ + if (is_motorola) { + if (exif_data[offset+8] != 0) { + MSG_ERROR("exif_data[offset+8] != 0"); + goto GL_EXIF_FAILED; + } + *orient = (unsigned int)exif_data[offset+9]; + } else { + if (exif_data[offset+9] != 0) { + MSG_ERROR("exif_data[offset+9] != 0"); + goto GL_EXIF_FAILED; + } + *orient = (unsigned int)exif_data[offset+8]; + } + if (*orient > 8) { + MSG_ERROR("*orient > 8"); + goto GL_EXIF_FAILED; + } + MSG_HIGH("Read: %d", *orient); + } + + ret = 0; + + GL_EXIF_FAILED: + + fclose(fd); + MSG_HIGH("All done"); + return ret; +} + + +#endif + +#if 0 +#include +#include + + +static inline bool _get_exif_short(ExifData *ed, ExifTag tag, short *value) +{ + ExifEntry *entry = NULL; + /** get exifentry*/ + entry = exif_data_get_entry(ed, tag); + if (!entry) + { + MSG_ERROR("Cannot find entry"); + return false; + } + + /** get value of the entry*/ + *value = exif_get_short(entry->data, exif_data_get_byte_order(entry->parent->parent)); + + return true; +} + +static inline bool _set_exif_short(ExifData *ed, ExifTag tag, short value) +{ + ExifEntry *entry = NULL; + /** get exifentry*/ + entry = exif_data_get_entry(ed, tag); + if (!entry) + { + MSG_ERROR("Cannot find entry"); + return false; + } + + /** set value of the entry*/ + exif_set_short(entry->data, exif_data_get_byte_order(entry->parent->parent), value); + + return true; +} + +int GetEXIFOrientation(const char *filepath, int *orientation) +{ + ExifData *ed = NULL; + + ed = exif_data_new_from_file(filepath); + if (ed == NULL) + { + MSG_ERROR("Cannot get exif data from %s", filepath); + return -1; + } + +// EXIF + if(_get_exif_short(ed, EXIF_TAG_ORIENTATION, orientation) == false) + { + MSG_ERROR("Get orientation failed"); + /* Free the EXIF data */ + exif_data_unref(ed); + return -1; + } + + MSG_HIGH("Orentation : %d", *orientation); + + /* Free the EXIF data */ + exif_data_unref(ed); + + return 0; +} + + +int SetEXIFOrientation(const char *filepath, int orientation) +{ + JPEGData *jdata; + unsigned char *d = NULL; + unsigned int ds; + + + ExifData *ed = NULL; + + ed = exif_data_new_from_file(filepath); + if (ed == NULL) + { + MSG_ERROR("Cannot get exif data from %s", filepath); + return -1; + } + + if(_set_exif_short(ed, EXIF_TAG_ORIENTATION, orientation) == false) + { + MSG_ERROR("Get orientation failed"); + /* Free the EXIF data */ + exif_data_unref(ed); + return -1; + } + + + /* Parse the JPEG file. */ + jdata = jpeg_data_new (); + jpeg_data_load_file (jdata, filepath); + + /* Make sure the EXIF data is not too big. */ + exif_data_save_data (ed, &d, &ds); + if (ds) + { + free (d); + if (ds > 0xffff) + MSG_ERROR("Too much EXIF data(%i bytes). Only %i bytes are allowed."), ds, 0xffff); + } + + jpeg_data_set_exif_data (jdata, ed); + + /* Save the modified image. */ + jpeg_data_save_file (jdata, filepath); + jpeg_data_unref (jdata); + + +// EXIF + MSG_HIGH("Orentation : %d", *orientation); + + /* Free the EXIF data */ + exif_data_unref(ed); + return 0; +} +#endif + + +/* 1 : top left + 2 : top right + 3 : bottom right + 4 : bottom left + 5 : left top + 6 : right top + 7 : right bottom + 8 : left bottom */ + +#define IVUG_EXIF_ROTATE_0 (1) +#define IVUG_EXIF_ROTATE_90 (6) +#define IVUG_EXIF_ROTATE_180 (3) +#define IVUG_EXIF_ROTATE_270 (8) + + +int ivug_exif_get_rotate(const char *file, int *degree) +{ + MSG_ASSERT(file != NULL); + + unsigned int orientation = 0; + + int ret = __gl_exif_rw_orient(file, &orientation, false); + if (-1 != ret && 0 != orientation) + { + switch (orientation) + { + case IVUG_EXIF_ROTATE_0: + *degree = 0; + break; + case IVUG_EXIF_ROTATE_90: + *degree = 90; + break; + case IVUG_EXIF_ROTATE_180: + *degree = 180; + break; + case IVUG_EXIF_ROTATE_270: + *degree = 270; + break; + default: + *degree = 0; + MSG_ERROR("Invalid Orientation : %d", orientation); + break; + } + + MSG_HIGH("Get Degree: %d' %s", *degree, file); + return 0; + + } + + MSG_ERROR("Unknown Degree: %s", file); + return -1; +} + + + +int ivug_exif_set_rotate(const char *file, int degree) +{ + MSG_ASSERT(file != NULL); + + MSG_HIGH("Set Degree: %d' %s", degree, file); + + unsigned int orientation; + + switch (degree){ + case 0: + case 360: + orientation = IVUG_EXIF_ROTATE_0; + break; + case 90: + case -270: + orientation = IVUG_EXIF_ROTATE_90; + break; + case 180: + case -180: + orientation = IVUG_EXIF_ROTATE_180; + break; + case 270: + case -90: + orientation = IVUG_EXIF_ROTATE_270; + break; + default: + orientation = IVUG_EXIF_ROTATE_0;; + MSG_ERROR("Invalid Degree : %d", degree); + break; + } + + int ret = __gl_exif_rw_orient(file, &orientation, true); + + return ret; +} + + diff --git a/common/src/ivug-file-info.c b/common/src/ivug-file-info.c new file mode 100755 index 0000000..b4f985e --- /dev/null +++ b/common/src/ivug-file-info.c @@ -0,0 +1,740 @@ +/* + * Copyright 2012 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.tizenopensource.org/license + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "ivug-file-info.h" +#include "ivug-debug.h" +#include "ivug-drm.h" +#include "ivug-util.h" + +#include //for exif +#include +#include +#include +#include +#include +#include + +#include + +#define BUF_LEN (255) + +static const char *_conver_error(int err) +{ + switch(err) + { + case METADATA_EXTRACTOR_ERROR_NONE: + return "Successful"; + case METADATA_EXTRACTOR_ERROR_INVALID_PARAMETER: + return "Invalid parameter"; + case METADATA_EXTRACTOR_ERROR_OUT_OF_MEMORY: + return "Out of memory"; + case METADATA_EXTRACTOR_ERROR_FILE_EXISTS: + return "File already exists"; + case METADATA_EXTRACTOR_ERROR_OPERATION_FAILED: + return "Operation failed"; + default: + { + static char error[128]; + sprintf(error, "Unknow Error : %d(0x%08x)", err, err); + return error; + } + } + return NULL; +} + +static bool _get_exif_string(ExifData *ed, ExifTag tag, const char *buf, int buf_len) +{ + ExifEntry *entry = NULL; + /** get exifentry*/ + entry = exif_data_get_entry(ed, tag); + if (!entry) + { + return false; + } + + /** get value of the entry*/ + if(exif_entry_get_value(entry, (char *)buf, buf_len) == NULL) + { + return false; + } + return true; +} + +static bool _get_exif_short(ExifData *ed, ExifTag tag, int *value) +{ + ExifEntry *entry = NULL; + /** get exifentry*/ + entry = exif_data_get_entry(ed, tag); + if (!entry) + { + return false; + } + + /** get value of the entry*/ + *value = exif_get_short(entry->data, exif_data_get_byte_order(entry->parent->parent)); + + return true; +} + + +bool _get_video_gps_info(const char *filepath, double *latitude, double *longitude) +{ + IV_ASSERT(filepath != NULL); + IV_ASSERT(latitude != NULL); + IV_ASSERT(longitude != NULL); + + int ret = METADATA_EXTRACTOR_ERROR_NONE; + metadata_extractor_h metadata; + + char *latitude_str; + char *longitude_str; + + *latitude = 0.0; + *longitude = 0.0; + + ret = metadata_extractor_create(&metadata); + if(ret != METADATA_EXTRACTOR_ERROR_NONE) + { + MSG_UTIL_ERROR("Fail metadata_extractor_create [%s]", _conver_error(ret)); + return false; + } + + ret = metadata_extractor_set_path(metadata, filepath); + if(ret != METADATA_EXTRACTOR_ERROR_NONE) + { + MSG_UTIL_ERROR("Fail metadata_extractor_set_path [%s]", _conver_error(ret)); + ret = metadata_extractor_destroy(metadata); + MSG_UTIL_HIGH("metadata_extractor_destroy [%s]", _conver_error(ret)); + return false; + } + + ret = metadata_extractor_get_metadata(metadata, METADATA_LATITUDE, &latitude_str); + if(ret != METADATA_EXTRACTOR_ERROR_NONE) + { + MSG_UTIL_ERROR("Fail metadata_extractor_get_metadata [%s]", _conver_error(ret)); + ret = metadata_extractor_destroy(metadata); + MSG_UTIL_HIGH("metadata_extractor_destroy [%s]", _conver_error(ret)); + return false; + } + + ret = metadata_extractor_get_metadata(metadata, METADATA_LONGITUDE, &longitude_str); + if(ret != METADATA_EXTRACTOR_ERROR_NONE) + { + MSG_UTIL_ERROR("Fail metadata_extractor_get_metadata [%s]", _conver_error(ret)); + ret = metadata_extractor_destroy(metadata); + MSG_UTIL_HIGH("metadata_extractor_destroy [%s]", _conver_error(ret)); + return false; + } + + MSG_UTIL_LOW("lat = %s, longi = %s", latitude_str, longitude_str); + *latitude = ivug_atod(latitude_str); + *longitude = ivug_atod(longitude_str); + + ret = metadata_extractor_destroy(metadata); + if(ret != METADATA_EXTRACTOR_ERROR_NONE) + { + MSG_UTIL_ERROR("Fail metadata_extractor_destroy [%s]", _conver_error(ret)); + } + + return true; +} + +/* LATITUDE : -90 ~ +90, LONGITUDE : -180 ~ +180) */ +bool _get_gps_info_from_exifdata(ExifData *ed, double *latitude, double *longitude) +{ + IV_ASSERT(ed != NULL); + IV_ASSERT(latitude != NULL); + IV_ASSERT(longitude != NULL); + + ExifIfd ifd; + ExifTag tag; + + char buf[BUF_LEN+1] = {'\0',}; + + double multiplier = 1.0; + + ifd = EXIF_IFD_GPS; + tag = EXIF_TAG_GPS_LATITUDE_REF; + + if(_get_exif_string(ed, tag, buf, BUF_LEN) == false) + { + return false; + } + + if(buf[0] == 'S') /* SOUTH */ + { + multiplier = -1.0; + } + + tag = EXIF_TAG_GPS_LATITUDE; + + if(_get_exif_string(ed, tag, buf, BUF_LEN) == false) + { + return false; + } + + { + buf[strlen(buf)] = '\0'; + double tmp_arr[3] = { 0.0, 0.0, 0.0 }; + int count = 0; + char* p = strtok(buf, ", "); + /** split the buf by , */ + while(p != NULL) + { + tmp_arr[count] = ivug_atod(p); + count++; + p=strtok(NULL, ", "); + } + + if( count != 3 ) + { + MSG_UTIL_ERROR("Cannot get latitude info : %s", p); + return false; + } + *latitude = multiplier*(tmp_arr[0] + tmp_arr[1]/60 + tmp_arr[2]/3600); + } + + multiplier = 1.0; + tag = EXIF_TAG_GPS_LONGITUDE_REF; + + if(_get_exif_string(ed, tag, buf, BUF_LEN) == false) + { + return false; + } + + if(buf[0] == 'W') /* WEST */ + { + multiplier = -1.0; + } + + tag = EXIF_TAG_GPS_LONGITUDE; + + if(_get_exif_string(ed, tag, buf, BUF_LEN) == false) + { + return false; + } + + { + buf[strlen(buf)] = '\0'; + double tmp_arr[3] = { 0.0, 0.0, 0.0 }; + int count = 0; + char* p = strtok(buf, ", "); + /** split the buf by , */ + while(p != NULL) + { + tmp_arr[count] = ivug_atod(p); + count++; + p=strtok(NULL, ", "); + } + + if( count != 3 ) + { + MSG_UTIL_ERROR("Cannot get Longitude info : %s", p); + return false; + } + + *longitude = multiplier*(tmp_arr[0] + tmp_arr[1]/60 + tmp_arr[2]/3600); + } + + return true; +} + +bool _get_image_gps_info(const char* filepath, double *latitude, double *longitude) +{ + IV_ASSERT(filepath != NULL); + IV_ASSERT(latitude != NULL); + IV_ASSERT(longitude != NULL); + + ExifData *ed = NULL; + + /** get exifdata*/ + ed = exif_data_new_from_file(filepath); + if (!ed) + { + return false; + } + + if(_get_gps_info_from_exifdata(ed, latitude, longitude) == false) + { + exif_data_unref(ed); + return false; + } + + exif_data_unref(ed); + + return true; +} + +bool _get_orientation_from_exifdata(ExifData *ed, /*OUT*/int *orient) +{ + MSG_DETAIL_HIGH("_get_orientation_from_exifdata"); + ExifIfd ifd; + ExifTag tag; + + ifd = EXIF_IFD_EXIF; + tag = EXIF_TAG_ORIENTATION; + + if(_get_exif_short(ed, tag, orient) == false) + { + return false; + } + + MSG_DETAIL_HIGH("orientation = %d", *orient); + /* 1 : top left + 2 : top right + 3 : bottom right + 4 : bottom left + 5 : left top + 6 : right top + 7 : right bottom + 8 : left bottom */ + return true; +} + +/* out value must be freed */ +bool _get_maker_from_exifdata(ExifData *ed, /*OUT*/char *maker) +{ + MSG_DETAIL_HIGH("_get_maker_from_exifdata"); + ExifIfd ifd; + ExifTag tag; + + char buf[BUF_LEN+1] = {'\0',}; + + ifd = EXIF_IFD_EXIF; + tag = EXIF_TAG_MAKE; + + if(_get_exif_string(ed, tag, buf, BUF_LEN) == false) + { + return false; + } + MSG_DETAIL_HIGH("Maker = %s", buf); + + maker = strdup(buf); + return true; +} + +/* out value must be freed */ +bool _get_model_from_exifdata(ExifData *ed, /*OUT*/char *model) +{ + MSG_DETAIL_HIGH("_get_model_from_exifdata"); + ExifIfd ifd; + ExifTag tag; + + char buf[BUF_LEN+1] = {'\0',}; + + ifd = EXIF_IFD_EXIF; + tag = EXIF_TAG_MODEL; + + if(_get_exif_string(ed, tag, buf, BUF_LEN) == false) + { + return false; + } + MSG_DETAIL_HIGH("Model = %s", buf); + + model = strdup(buf); + return true; +} + +bool _get_flash_from_exifdata(ExifData *ed, /*OUT*/int *status) +{ + MSG_DETAIL_HIGH("_get_flash_from_exifdata"); + ExifIfd ifd; + ExifTag tag; + + ifd = EXIF_IFD_EXIF; + tag = EXIF_TAG_FLASH; + + if(_get_exif_short(ed, tag, status) == false) + { + return false; + } + + MSG_DETAIL_HIGH("Flash status = %d", *status); + /* LSB + 0b : Flash did not fire + 1b : Flash fired */ + return true; +} + +/* out value must be freed */ +bool _get_focal_length_from_exifdata(ExifData *ed, /*OUT*/char *length) +{ + MSG_DETAIL_HIGH("_get_focal_length_from_exifdata"); + ExifIfd ifd; + ExifTag tag; + + char buf[BUF_LEN+1] = {'\0',}; + + ifd = EXIF_IFD_EXIF; + tag = EXIF_TAG_FOCAL_LENGTH; + + if(_get_exif_string(ed, tag, buf, BUF_LEN) == false) + { + return false; + } + MSG_DETAIL_HIGH("Focal length = %s", buf); + + length = strdup(buf); + return true; +} + +bool _get_white_balance_from_exifdata(ExifData *ed, int *white_balance) +{ + MSG_DETAIL_HIGH("_get_white_balance_from_exifdata"); + ExifIfd ifd; + ExifTag tag; + + ifd = EXIF_IFD_EXIF; + tag = EXIF_TAG_WHITE_BALANCE; + + if(_get_exif_short(ed, tag, white_balance) == false) + { + return false; + } + + MSG_DETAIL_HIGH("White balance = %d", *white_balance); + /* 0 : auto white balance + 1 : menual white balance */ + return true; +} + + +static bool _get_image_resolution(const char *path, int * /* OUT */ pWidth, int * /* OUT */pHeight) +{ + IV_ASSERT(path != NULL); + + int width = 0; + int height = 0; + + Evas *canvas; + Ecore_Evas *ee; + + ee = ecore_evas_buffer_new(1, 1); + if (!ee) + { + MSG_DETAIL_ERROR("Cannot get EVAS"); + return false; + } + + canvas = ecore_evas_get(ee); + + Evas_Object *img = evas_object_image_add(canvas); + + evas_object_image_file_set(img, NULL, NULL); + evas_object_image_load_orientation_set(img, EINA_TRUE); + evas_object_image_load_scale_down_set(img, 0); + + evas_object_image_file_set(img, path, NULL); + Evas_Load_Error error = evas_object_image_load_error_get(img); + if ( error != EVAS_LOAD_ERROR_NONE) + { + MSG_DETAIL_ERROR("Decoding Error(%d) : %s", error, path); + evas_object_del(img); + ecore_evas_free(ee); + return false; + } + + evas_object_image_size_get(img, &width, &height); + + evas_object_image_file_set(img, NULL, NULL); + evas_object_del(img); + + ecore_evas_free(ee); + + *pWidth = width; + *pHeight = height; + + MSG_DETAIL_HIGH("widht & height is [%d, %d]", width, height); + + return true; +} + + + +static bool +_get_video_resolution(const char *path, int * /* OUT */ pWidth, int * /* OUT */pHeight) +{ + IV_ASSERT(path != NULL); + + int ret = METADATA_EXTRACTOR_ERROR_NONE; + metadata_extractor_h metadata; + + char *width_str; + char *height_str; + + ret = metadata_extractor_create(&metadata); + if(ret != METADATA_EXTRACTOR_ERROR_NONE) + { + MSG_UTIL_ERROR("Fail metadata_extractor_create [%s]", _conver_error(ret)); + return false; + } + + ret = metadata_extractor_set_path(metadata, path); + if(ret != METADATA_EXTRACTOR_ERROR_NONE) + { + MSG_UTIL_ERROR("Fail metadata_extractor_set_path [%s]", _conver_error(ret)); + ret = metadata_extractor_destroy(metadata); + MSG_UTIL_HIGH("metadata_extractor_destroy [%s]", _conver_error(ret)); + return false; + } + + ret = metadata_extractor_get_metadata(metadata, METADATA_VIDEO_WIDTH, &width_str); + if(ret != METADATA_EXTRACTOR_ERROR_NONE) + { + MSG_UTIL_ERROR("Fail metadata_extractor_get_metadata [%s]", _conver_error(ret)); + ret = metadata_extractor_destroy(metadata); + MSG_UTIL_HIGH("metadata_extractor_destroy [%s]", _conver_error(ret)); + return false; + } + + ret = metadata_extractor_get_metadata(metadata, METADATA_VIDEO_HEIGHT, &height_str); + if(ret != METADATA_EXTRACTOR_ERROR_NONE) + { + MSG_UTIL_ERROR("Fail metadata_extractor_get_metadata [%s]", _conver_error(ret)); + ret = metadata_extractor_destroy(metadata); + MSG_UTIL_HIGH("metadata_extractor_destroy [%s]", _conver_error(ret)); + return false; + } + + MSG_UTIL_LOW("w = %s, h = %s", width_str, height_str); + *pWidth = ivug_atoi(width_str); + *pHeight = ivug_atoi(height_str); + + ret = metadata_extractor_destroy(metadata); + if(ret != METADATA_EXTRACTOR_ERROR_NONE) + { + MSG_UTIL_ERROR("Fail metadata_extractor_destroy [%s]", _conver_error(ret)); + } + + return true; +} + + + +static char* +_get_drm_get_extension(const char* path) +{ +#define EXT_SIZE 128 +#define EXT_SPLITTER '.' + + IV_ASSERT(path != NULL ); + + char *mime_type = ivug_drm_get_mime(path); + MSG_IVUG_HIGH("mime_type: %s", mime_type); + + char **ext = NULL; + int length = -1; + int ret = -1; + char *result_ext = NULL; + + ret = mime_type_get_file_extension(mime_type, &ext, &length); + free(mime_type); + + if(ret != MIME_TYPE_ERROR_NONE) + { + MSG_IVUG_ERROR("mime_type_get_file_extension failed: %d", ret); + return NULL; + } + if(length <= 0) + { + MSG_IVUG_ERROR("mime_type_get_file_extension length is invalid: %d", length); + return NULL; + } + + int i; + for(i=0; i // gettid() +#include + +#include +#include + +#undef UNIT_TEST + +#ifdef UNIT_TEST +/* + Build gcc fmradio_message.c `pkg-config --cflags --libs eina dlog ecore ecore-input` +*/ +#include + +#include +#include + +#undef LOG_TAG +#define LOG_TAG "UTT_MESSAGE" + +#define MSG_ASSERT(expr) do { if( !(expr) ) { LOG(LOG_INFO, LOG_TAG, "[%s] ASSERT : " #expr, __func__ ); assert(0); } }while(0) + +#define MSG_FATAL(...) do { LOG(LOG_INFO, LOG_TAG, ##__VA_ARGS__); assert(0); } while(0) +#define MSG_WARN(...) LOG(LOG_INFO, LOG_TAG, ##__VA_ARGS__) +#define MSG_ERROR(...) LOG(LOG_INFO, LOG_TAG, ##__VA_ARGS__) +#define MSG_HIGH(...) LOG(LOG_INFO, LOG_TAG, ##__VA_ARGS__) +#define MSG_MED(...) LOG(LOG_INFO, LOG_TAG, ##__VA_ARGS__) +#else + +#include "ivug-debug.h" + +#define LOG_LVL DBG_MSG_LVL_HIGH +#define LOG_CAT "IV-MESSAGE" + +#endif + +#define MAX_COMMAND_LENGTH (30) // Max length of each command + +typedef struct { + int param1; + int param2; + int param3; + void *param4; + + char command[MAX_COMMAND_LENGTH]; +} MyData; + +typedef struct { + FnMessage callback; + void *client_data; + + bool delete_me; +} RegisteredCallback; + +typedef struct { + EINA_INLIST; + + char command[MAX_COMMAND_LENGTH]; + Eina_List/**/ *cblist; +} CommandList; + +typedef struct { + Ecore_Pipe *pipe; + + Eina_Inlist *command_list; + int registered_count; + + pthread_mutex_t pipe_mutex; + +} _MessageHandle, *_PMessageHandle; + +#define PRINT_ERRNO(errno, fmt, arg...) \ + do { \ + char szError[256]; \ + int perr; \ + perr = strerror_r(errno, szError, sizeof(szError)); \ + \ + if ( perr ) { \ + MSG_ERROR(fmt " %s", ##arg, szError); \ + } \ + else { \ + MSG_ERROR(fmt " Errno=%d", ##arg, errno); \ + } \ + } while(0) + + +RegisteredCallback *_find_callback(Eina_List *cb_list, FnMessage cb) +{ + Eina_List *l; + RegisteredCallback *pCallback; + + EINA_LIST_FOREACH(cb_list,l, pCallback) + { + if (( pCallback->callback == cb)) + { + return pCallback; + } + } + +// Not found!. + return NULL; +} + + +CommandList *_find_command(Eina_Inlist *command_list, const char *command) +{ + CommandList *l; + + EINA_INLIST_FOREACH(command_list, l) + { + if ( strncmp(l->command, command, MAX_COMMAND_LENGTH ) == 0 ) + { + return l; + } + } + + return NULL; +} + + +static void _cleanup(_PMessageHandle pmessage) +{ + CommandList *pData; + Eina_Inlist *l2; + + EINA_INLIST_FOREACH_SAFE(pmessage->command_list, l2, pData) + { + RegisteredCallback *pCallback = NULL; + Eina_List *l, *l_next; + + EINA_LIST_FOREACH_SAFE(pData->cblist, l, l_next, pCallback) + { + if ( pCallback->delete_me == true ) + { + pData->cblist = eina_list_remove_list(pData->cblist, l); + pCallback->delete_me = false; + free(pCallback); + pmessage->registered_count--; + } + } + + if ( eina_list_count(pData->cblist) == 0 ) + { + pmessage->command_list = eina_inlist_remove(pmessage->command_list, EINA_INLIST_GET(pData)); + + MSG_HIGH("Remve cmd slot for %s", pData->command); + free(pData); + } + } + +} + + +void pipe_cb(void *data, void *buffer, unsigned int nbyte) +{ + _PMessageHandle pmessage = (_PMessageHandle)data; + MyData *mydata = buffer; + + if ( nbyte != sizeof(MyData) ) + { + MSG_ERROR("Invalid command!!. pipe=0x%08x nByte=%d", pmessage->pipe, nbyte); + return ; + } + + MSG_MED("Read from pipe. Pipe=0x%08x nByte=%d Cmd=%s Param1=%d", pmessage->pipe, nbyte , mydata->command, mydata->param1 ); + +// dump_message(pmessage); + + CommandList *pData; + + pData = _find_command(pmessage->command_list, mydata->command); + +// Clean up deleted callback + if ( pData != NULL ) // Add new command + { + RegisteredCallback *pCallback = NULL; + Eina_List *l; + + EINA_LIST_FOREACH(pData->cblist, l, pCallback) + { + if ( pCallback->delete_me == false ) + { + pCallback->callback(mydata->param1, mydata->param2, mydata->param3, mydata->param4, pCallback->client_data); // Call user function + } + } + + _cleanup(pmessage); + return; + } + + MSG_ERROR("Unknown command. pipe=0x%08x nByte=%d [%s:%d]", pmessage->pipe, nbyte, mydata->command, mydata->param1); +} + + +MessageHandle create_message_handle() +{ + _PMessageHandle pmessage = (_PMessageHandle) malloc( sizeof(_MessageHandle) ); + + if ( pmessage == NULL ) + { + MSG_FATAL("Cannot allocate memory. Size=%d", sizeof(_MessageHandle)); + return NULL; + } + + memset(pmessage, 0x00, sizeof(_MessageHandle) ); + + if ( pthread_mutex_init(&pmessage->pipe_mutex, NULL) != 0 ) // if falied, + { + PRINT_ERRNO(errno, "Mutex init error" ); + + free(pmessage); + return NULL; + } + + pmessage->pipe = ecore_pipe_add(pipe_cb, pmessage); + + if (pmessage->pipe == NULL ) + { + MSG_ERROR("Failed to creating ecore pipe"); + if ( pthread_mutex_destroy(&pmessage->pipe_mutex) != 0 ) + { + PRINT_ERRNO(errno, "Mutex destroy error" ); + // Go through + } + + free(pmessage); + return NULL; + } + + return (MessageHandle)pmessage; +} + +bool remove_message_handle(MessageHandle handle) +{ + _PMessageHandle pmessage = (_PMessageHandle)handle; + + // this function can be called in signal handler. so assert() cannot be used in this function + if (pmessage == NULL ) + { + MSG_WARN("Message handle is NULL"); + return true; + } + + MSG_HIGH("Remove message handle. Handle=0x%08x", handle); + if (pmessage->pipe != NULL ) + { + ecore_pipe_del(pmessage->pipe); + pmessage->pipe = NULL; + } + + if ( pthread_mutex_destroy(&pmessage->pipe_mutex) != 0 ) + { + PRINT_ERRNO(errno, "Mutex destroy error" ); + + // Go through + } + + CommandList *pData; + + EINA_INLIST_FOREACH(pmessage->command_list, pData) + { + RegisteredCallback *pCallback = NULL; + EINA_LIST_FREE(pData->cblist, pCallback) + { + free(pCallback); + pmessage->registered_count--; + } + } + + while (pmessage->command_list) + { + Eina_Inlist *aux = pmessage->command_list; + pmessage->command_list = eina_inlist_remove(pmessage->command_list, pmessage->command_list); + free(aux); + } + + MSG_HIGH("Registered Count=%d", pmessage->registered_count); + + free(pmessage); + + return true; +} + +bool send_message(MessageHandle handle, const char *command, int param1, int param2, int param3, void *param4) +{ + _PMessageHandle pmessage = (_PMessageHandle)handle; + + if ( pthread_mutex_lock(&pmessage->pipe_mutex) != 0 ) + { + PRINT_ERRNO(errno, "Mutex lock error" ); + + return false; + } + + MyData data = {0,}; + + data.param1 = param1; + data.param2 = param2; + data.param3 = param3; + data.param4 = param4; + + strncpy(data.command, command, MAX_COMMAND_LENGTH-1); + + MSG_MED("Write to pipe. tID=0x%08x Pipe=0x%08x Cmd=%s Param1=%d", pthread_self(), pmessage->pipe, data.command, data.param1); + + MSG_ASSERT(pmessage->pipe != NULL); + + if ( ecore_pipe_write(pmessage->pipe, &data, sizeof(MyData)) == EINA_FALSE) + { + MSG_ERROR("Writing to pipe is failed. pipe=0x%08x size=%d", pmessage->pipe, sizeof(MyData)); + + if ( pthread_mutex_unlock(&pmessage->pipe_mutex) != 0 ) + { + PRINT_ERRNO(errno, "Mutex unlock error" ); + + // Go through + } + + return false; + } + + if ( pthread_mutex_unlock(&pmessage->pipe_mutex) != 0 ) + { + PRINT_ERRNO(errno, "Mutex unlock error" ); + + // Go through + } + + return true; +} + +bool register_message(MessageHandle handle, const char *command, FnMessage cb, void *data) +{ + + MSG_ASSERT(handle != NULL); + MSG_ASSERT(command != NULL); + MSG_ASSERT(cb != NULL); + + _PMessageHandle pmessage = (_PMessageHandle)handle; + + CommandList *pData; + + pData = _find_command(pmessage->command_list, command); + + if ( pData == NULL ) // Add new command + { + pData = (CommandList *)calloc(1, sizeof(CommandList)); + + strncpy(pData->command, command, MAX_COMMAND_LENGTH - 1); + + pmessage->command_list = eina_inlist_append(pmessage->command_list, EINA_INLIST_GET(pData)); + + MSG_MED("Add new cmd slot for %s", command); + } + +// Find callback list. + RegisteredCallback *pCallback; + + pCallback = _find_callback(pData->cblist, cb); + + if ( pCallback == NULL ) + { + pCallback = (RegisteredCallback *)malloc(sizeof(RegisteredCallback)); + + pCallback->callback = cb; + pCallback->client_data = data; + pCallback->delete_me = false; + + pData->cblist = eina_list_append(pData->cblist, pCallback); + } + else + { + pCallback->delete_me = false; // Reuse slot. + + if ( pCallback->client_data != data ) + { + MSG_WARN("Already registered. CB is different. Old=0x%08x New=0x%08x", pCallback->client_data,data ); + pCallback->client_data = data; // Overwirte callback data. + + return true; + } + + MSG_ERROR("Already registered."); + return false; + } + + pmessage->registered_count++; + + MSG_MED("Registered command : %s cb=0x%08x", command, cb); + + return true; +} + +bool unregister_message(MessageHandle handle, const char *command, FnMessage cb) +{ + MSG_ASSERT(handle != NULL); + MSG_ASSERT(command != NULL); + + _PMessageHandle pmessage = (_PMessageHandle)handle; + + CommandList *pData; + + pData = _find_command(pmessage->command_list, command); + + if ( pData == NULL ) + { + MSG_ERROR("Unknown command : %s cb=0x%08x", command, cb); + return false; + } + + RegisteredCallback *pCallback; + + pCallback = _find_callback(pData->cblist, cb); + + if ( pCallback != NULL ) + { + pCallback->callback = (FnMessage)0xDEADDEAD; + pCallback->client_data = (void *)0xDEADBEAF; + pCallback->delete_me = true; + + return true; + } + + MSG_ERROR("Unknown command : %s cb=0x%08x", command, cb); + + return false; +} + + +void dump_message(MessageHandle handle) +{ + _PMessageHandle pmessage = (_PMessageHandle)handle; + CommandList *pData; + + MSG_HIGH("*****************************"); + MSG_HIGH(" Total : %d CommandList=0x%08x", pmessage->registered_count, pmessage->command_list); + + EINA_INLIST_FOREACH(pmessage->command_list, pData) + { + MSG_HIGH(" Command : \"%s\" 0x%08x", pData->command, pData ); + + RegisteredCallback *pCallback = NULL; + Eina_List *l; + + EINA_LIST_FOREACH(pData->cblist, l, pCallback) + { + MSG_HIGH(" Callback=0x%08x, Data=0x%08x", pCallback->callback, pCallback->client_data); + + } + } + + MSG_HIGH("*****************************"); + +} + + +#ifdef UNIT_TEST + +void mycmd1(int param1, int param2, int param3, void *param4, void *client_data) +{ + printf("Received MyCmd1\n"); + + printf("param1 = %s, param2 = %s, param3 = %s, param4 = %s\n", + (char *)param1, (char *)param2, (char *)param3, (char *)param4); +} + +void mycmd2(int param1, int param2, int param3, void *param4, void *client_data) +{ + printf("Received MyCmd2\n"); +} + +void mycmd3(int param1, int param2, int param3, void *param4, void *client_data) +{ + printf("Received MyCmd3\n"); +} + + +Eina_Bool on_timer1(void *data) +{ + MessageHandle hMessage = data; + + send_message(hMessage, "mycmd1", (int)"My", (int)"Name", (int)"Is", NULL); + + //send_message(hMessage, "mycmd2", 0, 0, 0, NULL); +} + +static Eina_Bool _keydown_event(void *data, int type, void *event) +{ + Ecore_Event_Key *ev = event; + + printf("Key event : %s", ev->keyname); + + return true; +} + +int main(void) +{ + ecore_init(); + ecore_event_init(); + eina_init(); + + MessageHandle hMessage = create_message_handle(); + + register_message(hMessage, "mycmd1", mycmd1, NULL); + register_message(hMessage, "mycmd2", mycmd2, NULL); + register_message(hMessage, "mycmd3", mycmd3, NULL); + + dump_message(hMessage); + + unregister_message(hMessage, "mycmd3", mycmd3); + + dump_message(hMessage); + + ecore_timer_add(0.5, on_timer1, hMessage); + + ecore_event_handler_add(ECORE_EVENT_KEY_DOWN, _keydown_event, NULL); + + ecore_main_loop_begin(); + + remove_message_handle(hMessage); + + ecore_event_shutdown(); + ecore_shutdown(); + eina_shutdown(); + + return 0; +} + +#endif + diff --git a/common/src/ivug-util.c b/common/src/ivug-util.c new file mode 100755 index 0000000..abc5702 --- /dev/null +++ b/common/src/ivug-util.c @@ -0,0 +1,353 @@ +/* + * Copyright 2012 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.tizenopensource.org/license + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +#include "ivug-define.h" +#include "ivug-uuid.h" + +#include "ivug-util.h" +#include "ivug-debug.h" +#include "ivug-file-info.h" + +#include "ivug-db.h" + +#include +#include + +#include + +#include +#include + +#include // mkdir +#include // mkdir + +#include + +/* + If filepath is web url, return TRUE. + +*/ +bool ivug_is_web_uri(const char* uri) +{ +//check file url type. local , http, ftp. + IV_ASSERT(uri != NULL); + + static const char* web_protocal_name[] = + { + "http://", + "https://", + "ftp://", + NULL, + }; + + int i = 0; + while (web_protocal_name[i] != NULL) + { + if ( strlen(uri) > strlen(web_protocal_name[i]) ) + { + if (strncmp(uri, web_protocal_name[i], strlen(web_protocal_name[i])) == 0) + { + return true; + } + } + + i++; + } + + MSG_UTIL_MED("Not web uri. %s", uri); + + return false; +} + + +unsigned int get_distance(int prevX, int prevY, int X, int Y) +{ + int dx = prevX - X; + int dy = prevY - Y; + + return sqrt(dx*dx + dy*dy); +} + + + +#define USE_ECORE_FILE + +#include + +/* + Remove fname file. + Returns true fname is not exist or removed sucessfully +*/ +bool ivug_remove_file(const char *filepath) +{ + char error_msg[256]; + if (ecore_file_exists(filepath) == EINA_FALSE) + { + MSG_UTIL_ERROR("Already removed.%s", filepath); + return true; + } + +#ifdef USE_ECORE_FILE + if ( ecore_file_unlink(filepath) == EINA_FALSE) + { + MSG_UTIL_ERROR("Cannot remove file : %s %s", filepath, strerror_r(errno, error_msg, sizeof(error_msg)) ); + return false; + } + + return true; +#else + if ( unlink(filepath) != 0 ) + { + MSG_UTIL_ERROR("Cannot remove file : %s %s", filepath, strerror_r(errno, error_msg, sizeof(error_msg)) ); + return false; + } + + return true; +#endif +} + +bool ivug_rename_file(const char *src, const char *dst) +{ + if (ecore_file_exists(src) == EINA_FALSE) + { + MSG_UTIL_ERROR("Source file is not exist : %s", src); + return false; + } + + if (dst == NULL) + { + MSG_UTIL_ERROR("Destination file is NULL"); + return false; + } + + char error_msg[256]; + + if ( rename(src, dst) < 0) + { + MSG_UTIL_ERROR("Cannot rename from %s to %s : %s", src, dst, strerror_r(errno, error_msg, sizeof(error_msg)) ); + return false; + } + + return true; +} + +bool ivug_copy_file(const char *filename, const char *dest) +{ +#define DIR_MASK_DEFAULT 0775 + if ( filename == NULL) + { + MSG_MAIN_ERROR("File does not existfilepath=%s", filename); + return false; + } + + if(ecore_file_cp(filename, dest) == EINA_FALSE) + { + MSG_MAIN_ERROR("ecore_file_cp failed. From %s To %s", filename, dest); + return false; + } + + return true; +} + + +char * +ivug_mktemp(char* filepath, char*ext) +{ + ivug_retv_if(!filepath || !ext, NULL); + + MSG_IVUG_HIGH("filepath %s, ext %s", filepath, ext); + + char tempname[IVUG_MAX_FILE_PATH_LEN+1] = {0}; + snprintf(tempname, sizeof(tempname), "%s_0.%s",filepath, ext); + int i = 1; + +// TODO : Will implement with another algorithm + while(ecore_file_exists(tempname) == EINA_TRUE ) + { + snprintf(tempname, sizeof(tempname),"%s_%d.%s", filepath, i, ext); + i++; + } + + MSG_IVUG_HIGH( " tempname %s, i %d", tempname, i); + + return strdup(tempname); +} + + +/* + Check whether given filepath file exists + + CAUTION : filepath cannot be NULL. +*/ +bool ivug_is_file_exist(const char* filepath) +{ + IV_ASSERT(filepath != NULL); + + if ( ecore_file_exists(filepath) == EINA_TRUE) + { + return true; + } + + return false; +} + + +/* + Returns start pointer of filename within filepath. + No memory allocated in this function. so user do not free returned pointer. + + CAUTION : filepath cannot be NULL. +*/ +const char * ivug_get_filename(const char *filepath) +{ + if ( filepath == NULL ) + { + MSG_UTIL_WARN("File path is NULL"); + return "NULL"; + } + +#ifdef USE_ECORE_FILE + return ecore_file_file_get(filepath); +#else + +#define DIRECORY_SPLITTER '/' + const char*pFileName = NULL; + + pFileName = strrchr(filepath, DIRECORY_SPLITTER); + pFileName = (NULL == pFileName)? "": (pFileName+1); + + return pFileName; +#endif + +} + +bool ivug_prohibit_lcd_off(void) +{ + MSG_UTIL_MED("START : Sleep disabled"); + return (power_lock_state(POWER_STATE_NORMAL, 0)==0 ? true : false); +} + +bool ivug_allow_lcd_off(void) +{ + MSG_UTIL_MED("END : Sleep disabled"); + return (power_unlock_state(POWER_STATE_NORMAL)==0 ? true : false); +} + +int ivug_atoi(const char *number) +{ + char *endptr = NULL; + long val = 0; + + errno = 0; + + val = strtol(number, &endptr, 10); + + if((errno == ERANGE && (val == LONG_MAX || val == LONG_MIN)) || (errno != 0 && val == 0)) + { + MSG_UTIL_ERROR("strtol, val = %d", val); + return -1; + } + + if(endptr == number) + { + MSG_UTIL_ERROR("No digits were found, number = %s", number); + return -1; + } + + return (int)val; +} + +double ivug_atod(const char *number) +{ + char *endptr = NULL; + double val = 0; + + errno = 0; + + val = strtod(number, &endptr); + + if((errno == ERANGE && (val == -HUGE_VAL || val == HUGE_VAL)) || (errno != 0 && val == 0)) + { + MSG_UTIL_ERROR("strtod, val = %d", val); + return -1; + } + + if(endptr == number) + { + MSG_UTIL_ERROR("No digits were found, number = %s", number); + return -1; + } + + return val; +} + +char * ivug_generate_file_name(const char *filepath) +{ + IV_ASSERT(filepath != NULL); + + MSG_SETAS_HIGH("filepath %s", filepath); + + char tempname[IVUG_MAX_FILE_PATH_LEN+1] = {0,}; + char *ext = ivug_fileinfo_get_file_extension(filepath); + char *filename = ecore_file_strip_ext(ecore_file_file_get(filepath)); + char *dir = ecore_file_dir_get(filepath); + + int i = 0; + + for(i=1; i // for NULL +#include // free +#include // strdup + +UUID uuid_assign(UUID id) +{ +#ifdef _USE_MEDIAINFO_STRINGID_ + if ( id == NULL ) + return NULL; + + return strdup(id); +#else + return id; +#endif +} + + +void uuid_free(UUID id) +{ +#ifdef _USE_MEDIAINFO_STRINGID_ + if ( id != NULL ) + free((void *)id); +#endif +} + + +int uuid_compare(UUID id1, UUID id2) +{ +#ifdef _USE_MEDIAINFO_STRINGID_ + return strcmp(id1, id2); +#else + return id1 - id2; +#endif +} + +const char *uuid_getchar(UUID id) +{ +#ifdef _USE_MEDIAINFO_STRINGID_ + if ( id == NULL ) + { + return "NULL"; + } + + return id; +#else + { + static char buffer[255]; + + sprintf(buffer, "%d", id); + + return buffer; + } +#endif + +} + + +UUID uuid_getuuid(const char *szID) +{ + if ( szID == NULL ) + { + return INVALID_UUID; + } + +#ifdef _USE_MEDIAINFO_STRINGID_ + return strdup(szID); +#else + return ivug_atoi(szID); +#endif + +} + +bool uuid_is_valid(UUID id) +{ + return (id != INVALID_UUID) ? true : false; +} + + + diff --git a/feature/CMakeLists.txt b/feature/CMakeLists.txt new file mode 100755 index 0000000..690bd1e --- /dev/null +++ b/feature/CMakeLists.txt @@ -0,0 +1,53 @@ +CMAKE_MINIMUM_REQUIRED(VERSION 2.6) +PROJECT(ivug_feature C CXX) + +SET(PREFIX ${CMAKE_INSTALL_PREFIX}) +SET(VERSION 0.1.0) + +SET(SRCS + src/ivug-vibration.c + src/ivug-ext-ug.c +) + +INCLUDE_DIRECTORIES( + ${CMAKE_SOURCE_DIR}/include + ${IVUG_SOURCE_COMMON_DIR}/include + include +) + +MESSAGE("Checking " ${PROJECT_NAME} ) + +INCLUDE(FindPkgConfig) +pkg_check_modules(${PROJECT_NAME}_pkgs REQUIRED + evas + ecore + ecore-x + elementary + dlog + ui-gadget-1 # Motion + capi-system-haptic + capi-system-sensor +) + +FOREACH(flag ${${PROJECT_NAME}_pkgs_CFLAGS}) + SET(EXTRA_CXXFLAGS "${EXTRA_CXXFLAGS} ${flag}") +ENDFOREACH(flag) + +SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${EXTRA_CXXFLAGS} -Wall") +SET(CMAKE_C_FLAGS ${CMAKE_CXX_FLAGS}) + +ADD_DEFINITIONS("-DPREFIX=\"${CMAKE_INSTALL_PREFIX}\"") +ADD_DEFINITIONS("-DLOG_LVL=DBG_MSG_LVL_HIGH") +ADD_DEFINITIONS("-DLOG_CAT=\"IV-FEATURE\"") + +ADD_LIBRARY(${PROJECT_NAME} SHARED ${SRCS}) + +SET_TARGET_PROPERTIES(${PROJECT_NAME} PROPERTIES SOVERSION ${VERSION} ) +SET_TARGET_PROPERTIES(${PROJECT_NAME} PROPERTIES INSTALL_RPATH ${CMAKE_INSTALL_PREFIX}/lib) + +TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${${PROJECT_NAME}_pkgs_LDFLAGS} + ivug_common +) + +INSTALL(TARGETS ${PROJECT_NAME} DESTINATION lib) + diff --git a/feature/include/ivug-email.h b/feature/include/ivug-email.h new file mode 100755 index 0000000..1b409a8 --- /dev/null +++ b/feature/include/ivug-email.h @@ -0,0 +1,50 @@ +/* + * Copyright 2012 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.tizenopensource.org/license + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __IVUG_EMAIL_H__ +#define __IVUG_EMAIL_H__ + +#include + +typedef struct +{ + void *email_handle; + Evas_Smart_Cb callback; + void *data; +}email_handle_t; + +#ifdef __cplusplus +extern "C" { +#endif + +email_handle_t * ivug_email_create(); + +bool ivug_email_destroy(email_handle_t *e_handle); + +bool ivug_email_set_message(email_handle_t *e_handle, const char *title, const char *content); + +bool ivug_email_set_file(email_handle_t *e_handle, const char *filepath); + +bool ivug_email_set_recipient(email_handle_t *e_handle, const char *address); + +bool ivug_email_send_message(email_handle_t *e_handle, Evas_Smart_Cb callback, void *data); + +#ifdef __cplusplus +} +#endif + +#endif //__IVUG_EMAIL_H__ + diff --git a/feature/include/ivug-ext-ug.h b/feature/include/ivug-ext-ug.h new file mode 100755 index 0000000..c44839d --- /dev/null +++ b/feature/include/ivug-ext-ug.h @@ -0,0 +1,48 @@ +/* + * Copyright 2012 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.tizenopensource.org/license + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __IVUG_EXT_UG_H__ +#define __IVUG_EXT_UG_H__ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef void (*ug_destroy_cb)(ui_gadget_h ug, void *data); +typedef void (*ug_result_cb)(ui_gadget_h ug, service_h service, void *data); + + +/* + Launch extern module. +*/ +bool ivug_ext_launch_videoplayer_simple(const char *filepath); +bool ivug_ext_launch_videoplayer(const char *uri); + +ui_gadget_h ivug_ext_launch_contact(const char *uri, ug_destroy_cb func, void *data); + + +bool ivug_ext_launch_browser(const char *uri); +bool ivug_ext_launch_default(const char *uri, const char *operation, const char *pkg, void *data); + +#ifdef __cplusplus +} +#endif + +#endif //__IVUG_EXT_UG_H__ + diff --git a/feature/include/ivug-vibration.h b/feature/include/ivug-vibration.h new file mode 100755 index 0000000..0523683 --- /dev/null +++ b/feature/include/ivug-vibration.h @@ -0,0 +1,49 @@ +/* + * Copyright 2012 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.tizenopensource.org/license + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __IVUG_VIBRATION_H__ +#define __IVUG_VIBRATION_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +#define INVALID_HAPTIC_HANDLE (-1) +#define VIBRATION_DURATION (500) // 500 ms + +/* + If success, returns handle. otherwise -1. +*/ +int ivug_vibration_create(void); + +/* + duration in ms +*/ +bool ivug_vibration_play(int handle, int duration); + +bool ivug_vibration_stop(int handle); + +bool ivug_vibration_delete(int handle); + + +#ifdef __cplusplus +} +#endif + +#endif // __IVUG_VIBRATION_H__ + diff --git a/feature/src/ivug-ext-ug.c b/feature/src/ivug-ext-ug.c new file mode 100755 index 0000000..e8d1e4e --- /dev/null +++ b/feature/src/ivug-ext-ug.c @@ -0,0 +1,500 @@ +/* + * Copyright 2012 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.tizenopensource.org/license + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include + +#include +#include + +#include "ivug-ext-ug.h" +#include "ivug-util.h" +#include "ivug-debug.h" + +//definition +#define CONTACT_UG_NAME "contacts-list-efl" + +#define VIDEOPLAYER_PKG_NAME "org.tizen.video-player" +#define BROWSER_PKG_NAME "org.tizen.browser" + +#define MIME_TYPE_LEN 255 + +typedef struct { + ug_destroy_cb destroy_func; + ug_result_cb result_func; + void *cb_data; +}ext_ug_t; + +static bool _data_print(service_h service, const char *key, void *user_data) +{ + MSG_IVUG_HIGH(" %s", key); + + return true; +} + +static void print_service_data(service_h service) +{ + int ret = service_foreach_extra_data(service, _data_print, NULL); + + if(SERVICE_ERROR_NONE != ret) + { + MSG_IVUG_ERROR("service_foreach_extra_data ERROR"); + } +} + +static void +_ivug_ext_ug_layout_cb(ui_gadget_h ug, enum ug_mode mode, void *priv) +{ + Evas_Object *base, *win; + + if (!ug ) return; + + base = ug_get_layout(ug); + if (!base) + { + ug_destroy(ug); + return; + } + + win = ug_get_window(); + + switch (mode) + { + case UG_MODE_FULLVIEW: + MSG_IMAGEVIEW_HIGH("Creating UG layout"); + evas_object_size_hint_weight_set(base, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + elm_win_resize_object_add(win, base); + evas_object_show(base); + break; + default: + MSG_IMAGEVIEW_ERROR("Unhandled Mode : %d", mode); + break; + } +} + + +static void +_ivug_ext_ug_result_cb(ui_gadget_h ug, service_h result, void *priv) +{ + if (!ug ) return; + + if (result) + { + print_service_data(result); + } + + ext_ug_t *ug_struct = (ext_ug_t *)priv; + + if(ug_struct->result_func) + ug_struct->result_func(ug, result, ug_struct->cb_data); +} + + +static void +_ivug_ext_ug_destroy_cb(ui_gadget_h ug, void *priv) +{ + if (!ug ) return; + + ext_ug_t *ug_struct = (ext_ug_t *)priv; + + MSG_IMAGEVIEW_HIGH("Destroy ug"); + ug_destroy(ug); + + ug_struct->destroy_func(ug, ug_struct->cb_data); + + free(ug_struct); +} + +ui_gadget_h _ivug_ext_launch_ug(const char *pkgname, service_h service, ug_destroy_cb func, void *data) +{ + ui_gadget_h ug = NULL; + struct ug_cbs cbs = {0, }; + + ext_ug_t *ug_struct = calloc(1, sizeof(ug_struct)); + ug_struct->result_func = NULL; + ug_struct->destroy_func = func; + ug_struct->cb_data = data; + + cbs.layout_cb = _ivug_ext_ug_layout_cb; + cbs.result_cb = _ivug_ext_ug_result_cb; + cbs.destroy_cb = _ivug_ext_ug_destroy_cb; + cbs.priv = ug_struct; + + ug = ug_create( NULL, pkgname, UG_MODE_FULLVIEW, service, &cbs ); + + return ug; +} + +ui_gadget_h _ivug_ext_launch_ug_with_result(const char *pkgname, + service_h service, ug_result_cb result_func, ug_destroy_cb destroy_func, void *data) +{ + ui_gadget_h ug = NULL; + struct ug_cbs cbs = {0, }; + + ext_ug_t *ug_struct = calloc(1, sizeof(ug_struct)); + ug_struct->result_func = result_func; + ug_struct->destroy_func = destroy_func; + ug_struct->cb_data = data; + + cbs.layout_cb = _ivug_ext_ug_layout_cb; + cbs.result_cb = _ivug_ext_ug_result_cb; + cbs.destroy_cb = _ivug_ext_ug_destroy_cb; + cbs.priv = ug_struct; + + ug = ug_create( NULL, pkgname, UG_MODE_FULLVIEW, service, &cbs ); + + return ug; +} + + +void ivug_ext_service_reply_cb(service_h request, service_h reply, service_result_e result, void *user_data) +{ + MSG_IMAGEVIEW_HIGH("ivug_ext_service_reply_cb"); + switch(result) + { + case SERVICE_RESULT_SUCCEEDED: + MSG_IMAGEVIEW_HIGH("SERVICE_RESULT_SUCCEEDED"); + break; + case SERVICE_RESULT_FAILED: + MSG_IMAGEVIEW_HIGH("SERVICE_RESULT_FAILED"); + break; + case SERVICE_RESULT_CANCELED: + MSG_IMAGEVIEW_HIGH("SERVICE_RESULT_CANCELED"); + break; + default: + MSG_IMAGEVIEW_ERROR("unhandled value %d", result); + break; + } +} + + +ui_gadget_h ivug_ext_launch_contact(const char *uri, ug_destroy_cb func, void *data) +{ + MSG_IMAGEVIEW_HIGH("%s. URI=%s", __func__, uri); + + int ret = -1; + + service_h handle; + ui_gadget_h ug = NULL; + + ret = service_create(&handle); + if(ret != SERVICE_ERROR_NONE) + { + MSG_IMAGEVIEW_ERROR("service_create failed, %d", ret); + return NULL; + } + + /*ret = service_set_operation(handle, SERVICE_OPERATION_VIEW); + if(ret != SERVICE_ERROR_NONE) + { + MSG_IMAGEVIEW_ERROR("service_set_operation failed, %d", ret); + goto MESSAGE_END; + }*/ + + ret = service_set_uri (handle, uri); + if(ret != SERVICE_ERROR_NONE) + { + MSG_IMAGEVIEW_ERROR("service_set_uri failed, %d", ret); + goto CONTACT_END; + } + + ret = service_add_extra_data(handle, "type", "41"); + if(ret != SERVICE_ERROR_NONE) + { + MSG_IMAGEVIEW_ERROR("service_add_extra_data failed, %d", ret); + goto CONTACT_END; + } + + ret = service_add_extra_data(handle, "ct_path", uri); + if(ret != SERVICE_ERROR_NONE) + { + MSG_IMAGEVIEW_ERROR("service_add_extra_data failed, %d", ret); + goto CONTACT_END; + } + + /*const char *pkgname = CONTACT_UG_NAME; + + ret = service_set_package(handle, pkgname); + if(ret != SERVICE_ERROR_NONE) + { + MSG_IMAGEVIEW_ERROR("service_set_uri failed, %d", ret); + goto CONTACT_END; + }*/ + + ug = _ivug_ext_launch_ug(CONTACT_UG_NAME, handle, func, data); + +CONTACT_END: + if(service_destroy(handle) != SERVICE_ERROR_NONE) + { + MSG_IMAGEVIEW_ERROR("service_destroy failed, %d", ret); + return NULL; + } + + return (ret == SERVICE_ERROR_NONE ? ug : NULL); +} + +bool ivug_ext_launch_videoplayer(const char *uri) +{ + MSG_IMAGEVIEW_HIGH("%s. URI=%s", __func__, uri); + + int ret = -1; + + service_h handle; + + ret = service_create(&handle); + if(ret != SERVICE_ERROR_NONE) + { + MSG_IMAGEVIEW_ERROR("service_create failed, %d", ret); + return false; + } + + ret = service_set_operation(handle, SERVICE_OPERATION_VIEW); + if(ret != SERVICE_ERROR_NONE) + { + MSG_IMAGEVIEW_ERROR("service_set_operation failed, %d", ret); + goto VIDEO_PLAYER_END; + } + + ret = service_set_uri (handle, uri); + if(ret != SERVICE_ERROR_NONE) + { + MSG_IMAGEVIEW_ERROR("service_set_uri failed, %d", ret); + goto VIDEO_PLAYER_END; + } + + ret = service_add_extra_data(handle, "path", uri); + if(ret != SERVICE_ERROR_NONE) + { + MSG_IMAGEVIEW_ERROR("service_add_extra_data failed, %d", ret); + goto VIDEO_PLAYER_END; + } + + ret = service_add_extra_data(handle, "launching_application", "image_viewer"); + if(ret != SERVICE_ERROR_NONE) + { + MSG_IMAGEVIEW_ERROR("service_add_extra_data failed, %d", ret); + goto VIDEO_PLAYER_END; + } + + const char *pkgname = VIDEOPLAYER_PKG_NAME; + + ret = service_set_package(handle, pkgname); + if(ret != SERVICE_ERROR_NONE) + { + MSG_IMAGEVIEW_ERROR("service_set_uri failed, %d", ret); + goto VIDEO_PLAYER_END; + } + + ret = service_send_launch_request(handle, ivug_ext_service_reply_cb, NULL); + if(ret != SERVICE_ERROR_NONE) + { + MSG_IMAGEVIEW_ERROR("service_send_launch_request failed, %d", ret); + goto VIDEO_PLAYER_END; + } + +VIDEO_PLAYER_END: + if(service_destroy(handle) != SERVICE_ERROR_NONE) + { + MSG_IMAGEVIEW_ERROR("service_destroy failed, %d", ret); + return false; + } + + return (ret == SERVICE_ERROR_NONE ? true : false); +} + +bool ivug_ext_launch_videoplayer_simple(const char *uri) +{ + MSG_IMAGEVIEW_HIGH("%s. URI=%s", __func__, uri); + + int ret = -1; + + service_h handle; + + ret = service_create(&handle); + if(ret != SERVICE_ERROR_NONE) + { + MSG_IMAGEVIEW_ERROR("service_create failed, %d", ret); + return false; + } + + ret = service_set_operation(handle, SERVICE_OPERATION_VIEW); + if(ret != SERVICE_ERROR_NONE) + { + MSG_IMAGEVIEW_ERROR("service_set_operation failed, %d", ret); + goto VIDEO_PLAYER_SIMPLE_END; + } + + ret = service_set_uri (handle, uri); + if(ret != SERVICE_ERROR_NONE) + { + MSG_IMAGEVIEW_ERROR("service_set_uri failed, %d", ret); + goto VIDEO_PLAYER_SIMPLE_END; + } + + ret = service_add_extra_data(handle, "path", uri); + if(ret != SERVICE_ERROR_NONE) + { + MSG_IMAGEVIEW_ERROR("service_add_extra_data failed, %d", ret); + goto VIDEO_PLAYER_SIMPLE_END; + } + + // Camera -> Image Viewer -> Video player, In this case, launching_application bundle's value should be "light_play_view" + ret = service_add_extra_data(handle, "launching_application", "light_play_view"); + if(ret != SERVICE_ERROR_NONE) + { + MSG_IMAGEVIEW_ERROR("service_add_extra_data failed, %d", ret); + goto VIDEO_PLAYER_SIMPLE_END; + } + + const char *pkgname = VIDEOPLAYER_PKG_NAME; + + ret = service_set_package(handle, pkgname); + if(ret != SERVICE_ERROR_NONE) + { + MSG_IMAGEVIEW_ERROR("service_set_uri failed, %d", ret); + goto VIDEO_PLAYER_SIMPLE_END; + } + + ret = service_send_launch_request(handle, ivug_ext_service_reply_cb, NULL); + if(ret != SERVICE_ERROR_NONE) + { + MSG_IMAGEVIEW_ERROR("service_send_launch_request failed, %d", ret); + goto VIDEO_PLAYER_SIMPLE_END; + } + +VIDEO_PLAYER_SIMPLE_END: + if(service_destroy(handle) != SERVICE_ERROR_NONE) + { + MSG_IMAGEVIEW_ERROR("service_destroy failed, %d", ret); + return false; + } + + return (ret == SERVICE_ERROR_NONE ? true : false); +} + + + +bool ivug_ext_launch_browser(const char *uri) +{ + MSG_IMAGEVIEW_HIGH("%s. URI=%s", __func__, uri); + + int ret = -1; + + service_h handle; + + ret = service_create(&handle); + if(ret != SERVICE_ERROR_NONE) + { + MSG_IMAGEVIEW_ERROR("service_create failed, %d", ret); + return false; + } + + ret = service_set_operation(handle, SERVICE_OPERATION_VIEW); + if(ret != SERVICE_ERROR_NONE) + { + MSG_IMAGEVIEW_ERROR("service_set_operation failed, %d", ret); + goto BROWSER_END; + } + + ret = service_add_extra_data(handle, "url", uri); + if(ret != SERVICE_ERROR_NONE) + { + MSG_IMAGEVIEW_ERROR("service_add_extra_data failed, %d", ret); + goto BROWSER_END; + } + + const char *pkgname = BROWSER_PKG_NAME; + + ret = service_set_package(handle, pkgname); + if(ret != SERVICE_ERROR_NONE) + { + MSG_IMAGEVIEW_ERROR("service_set_uri failed, %d", ret); + goto BROWSER_END; + } + + ret = service_send_launch_request(handle, ivug_ext_service_reply_cb, NULL); + if(ret != SERVICE_ERROR_NONE) + { + MSG_IMAGEVIEW_ERROR("service_send_launch_request failed, %d", ret); + goto BROWSER_END; + } + +BROWSER_END: + if(service_destroy(handle) != SERVICE_ERROR_NONE) + { + MSG_IMAGEVIEW_ERROR("service_destroy failed, %d", ret); + return false; + } + + return (ret == SERVICE_ERROR_NONE ? true : false); +} + + + +bool ivug_ext_launch_default(const char *uri, const char *operation, const char *pkg, void *data) +{ + MSG_IMAGEVIEW_HIGH("%s.", __func__); + + int ret = -1; + int destroy_ret = -1; + + service_h handle; + + ret = service_create(&handle); + if(ret != SERVICE_ERROR_NONE) + { + MSG_IMAGEVIEW_ERROR("service_create failed, %d", ret); + return NULL; + } + + ret = service_set_operation(handle, operation); + if(ret != SERVICE_ERROR_NONE) + { + MSG_IMAGEVIEW_ERROR("service_set_operation %s failed, %d", operation, ret); + goto LAUNCH_END; + } + + ret = service_set_uri (handle, uri); + if(ret != SERVICE_ERROR_NONE) + { + MSG_IMAGEVIEW_ERROR("service_set_uri %s failed, %d", uri, ret); + goto LAUNCH_END; + } + + ret = service_set_package(handle, pkg); + if(ret != SERVICE_ERROR_NONE) + { + MSG_IMAGEVIEW_ERROR("service_set_package %s failed, %d", pkg, ret); + goto LAUNCH_END; + } + + ret = service_send_launch_request(handle, ivug_ext_service_reply_cb, NULL); + if(ret != SERVICE_ERROR_NONE) + { + MSG_IMAGEVIEW_ERROR("service_send_launch_request failed, %d", ret); + goto LAUNCH_END; + } + +LAUNCH_END: + destroy_ret = service_destroy(handle); + if(destroy_ret != SERVICE_ERROR_NONE) + { + MSG_IMAGEVIEW_ERROR("service_destroy failed, %d", destroy_ret); + return NULL; + } + + return (ret == SERVICE_ERROR_NONE ? true : false); +} + diff --git a/feature/src/ivug-vibration.c b/feature/src/ivug-vibration.c new file mode 100755 index 0000000..8ffcf4d --- /dev/null +++ b/feature/src/ivug-vibration.c @@ -0,0 +1,118 @@ +/* + * Copyright 2012 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.tizenopensource.org/license + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "ivug-vibration.h" +#include "ivug-debug.h" + +#include +#include + +static const char *_conver_error(int err) +{ + switch(err) + { + case HAPTIC_ERROR_NONE: + return "Successful"; + case HAPTIC_ERROR_INVALID_PARAMETER: + return "Invalid parameter"; + case HAPTIC_ERROR_NO_SUCH_FILE: + return "No such file"; + case HAPTIC_ERROR_NOT_SUPPORTED_FORMAT: + return "Not supported file format"; + case HAPTIC_ERROR_NOT_INITIALIZED: + return "Not initialized"; + case HAPTIC_ERROR_OPERATION_FAILED: + return "Operation failed"; + default: + { + static char error[128]; + sprintf(error, "Unknow Error : %d(0x%08x)", err, err); + return error; + } + } + + return NULL; + +} + + +int ivug_vibration_create() +{ + int ret = HAPTIC_ERROR_NONE; + + ret = haptic_initialize(); + + if (ret != HAPTIC_ERROR_NONE) + { + MSG_UTIL_ERROR("device_haptic_open failed. %s", _conver_error(ret)); + return -1; + } + + int vib_index = 0; // Means all vibratior. + + return vib_index; +} + +bool ivug_vibration_play(int handle, int duration) +{ + int ret = HAPTIC_ERROR_NONE; + + MSG_UTIL_HIGH("Vibration start. Handle=%d duration=%f", handle, duration); + + ret = haptic_vibrate_monotone(handle, duration, HAPTIC_LEVEL_3); + + if (ret != HAPTIC_ERROR_NONE) + { + MSG_UTIL_ERROR("haptic_vibrate_monotone error Handle=%d. %s", handle, _conver_error(ret)); + return false; + } + + return true; +} + +bool ivug_vibration_stop(int handle) +{ + MSG_UTIL_HIGH("Vibration stop. Handle=%d", handle); + + int ret = HAPTIC_ERROR_NONE; + + ret = haptic_stop_device(handle); + if (ret != 0) + { + MSG_UTIL_ERROR("haptic_stop_device failed. %s", _conver_error(ret)); + } + + return true; +} + + +bool ivug_vibration_delete(int handle) +{ + MSG_UTIL_HIGH("Vibration deinit. Handle=%d", handle); + + int ret = HAPTIC_ERROR_NONE; + + ret = haptic_deinitialize(); + + if (ret != HAPTIC_ERROR_NONE) + { + MSG_UTIL_ERROR("device_haptic_close failed. %s", _conver_error(ret)); + } + + return true; +} + + diff --git a/include/ivug-datatypes.h b/include/ivug-datatypes.h new file mode 100755 index 0000000..4348b5e --- /dev/null +++ b/include/ivug-datatypes.h @@ -0,0 +1,61 @@ +/* + * Copyright 2012 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.tizenopensource.org/license + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __IVUG_DATATYPES_H__ +#define __IVUG_DATATYPES_H__ + +#include "ivug-define.h" +#include + +#ifdef _USE_MEDIAINFO_STRINGID_ + typedef const char *UUID; + + #define INVALID_UUID ((UUID)NULL) +#else + typedef int UUID; + + #define INVALID_UUID ((UUID)-1) +#endif + +typedef enum { + IVUG_VIEW_BY_INVAILD = 0x00, + IVUG_VIEW_BY_FILE, + IVUG_VIEW_BY_ALL, + IVUG_VIEW_BY_FAVORITES, + IVUG_VIEW_BY_FOLDER, + IVUG_VIEW_BY_PLACES, + IVUG_VIEW_BY_CONTACT_ID, +} ivug_view_by; + +typedef enum { + IVUG_MEDIA_TYPE_ALL = 0x00, //default value + IVUG_MEDIA_TYPE_IMAGE, + IVUG_MEDIA_TYPE_VIDEO, + IVUG_MEDIA_TYPE_MAX, +} ivug_media_type; + + +typedef enum { + IVUG_MEDIA_SORT_NONE = 0x00, /**< No sort */ + IVUG_MEDIA_ASC_BY_NAME, /**< Ascending sort as file name */ + IVUG_MEDIA_DESC_BY_NAME, /**< Descending sort as file name */ + IVUG_MEDIA_ASC_BY_DATE, /**< Ascending sort as created date */ + IVUG_MEDIA_DESC_BY_DATE, /**< Descending sort as created date */ +} ivug_sort_type; + + +#endif // __IVUG_DATATYPES_H__ + diff --git a/include/ivug-define.h b/include/ivug-define.h new file mode 100755 index 0000000..6c706ea --- /dev/null +++ b/include/ivug-define.h @@ -0,0 +1,51 @@ +/* + * Copyright 2012 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.tizenopensource.org/license + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + ONLY system widely used definition. +*/ + +#pragma once + +/* +# use string UUID +ADD_DEFINITIONS("-D_USE_MEDIAINFO_STRINGID_") +*/ +#define _USE_MEDIAINFO_STRINGID_ + +#define USE_RESCAN_FILE_PATH_AT_LIST + +#define IVUG_MAX_FILE_PATH_LEN (4096) + +#define DIR_MASK_DEFAULT 0775 + +#define USE_CUSTOM_STYLE + +/* + Time analysis data will be stored as file +*/ +#define TA_SAVETO_FILE + +// Temp. will be removed. +#ifdef TARGET +// todo about arm +#endif + +#define USE_NEW_DB_API + +#define ZOOM_LEVEL_STEP (0.7) +#define ZOOM_LEVEL_MAX (4) + diff --git a/main/layout/crop-view/T06_controlbar_bg.png b/main/layout/crop-view/T06_controlbar_bg.png new file mode 100755 index 0000000000000000000000000000000000000000..864585cd3dd27be85cf23b0ffd27eeb6f32e7f03 GIT binary patch literal 114793 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 ZMcTy1MWwGa&FFrZh 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 KMNUMnLSTaEfvn{K literal 0 HcmV?d00001 diff --git a/main/layout/gengrid/00_winset_thumbs_bg.png b/main/layout/gengrid/00_winset_thumbs_bg.png new file mode 100755 index 0000000000000000000000000000000000000000..6226c9041b06731979e43e5548083dc96603c5aa GIT binary patch literal 3233 zcmbW3={pqq8^*s58T*zc>oN8wj9qqS>}wbqwAe>UmXs~B8|e_TH=?qQB~haZHI|TN zY+1*WJ%p1b$}&IaANXC@IWO+#b3N~#`@Y{i$(O86SeXQv0069JriON>e158z4D_dy zyK?UzFb0@9-2s64>_4Ib`A^RQz+`g+iM({l$3NKrj*owUs2LI|8W7~~edCrF0HKpO zdko5cl~-qfW*1?BjecU`Z^y$RYKKUP=1!M_K^ZyBvC!fP9@`d9BO^M&t|BaLYHIW& z9$Q(KhfL#;MdR0Kmae?+LwgEKUOsqO`Ryh>;*408QvHGXo%56_6B!lBn!!h`cK_ z(eX5-;Pi_Y4AI;`KRgvt3iOR>qH(!W_MnIkxb}FsFMvyOz*YLe@-T?T9ppvO0GB6F z9-5+bAbQpdYY2R_Kvnx4S+=EV6FoUEI`2)n{Xb` zMF7_>aq&&w;i>AT&Uq#ft@CmSEo&s&@hT|VUP=iI6BIU$dJwWE^w>4{o$6c zFW(xL$FCHl!v1xq7l5L4o>R9w$Dw4l8ZucemB4mgZtWvIRm|Oe;bf`5GC&`Ix!|b5 z6Ipn@K(rQpwBN~d$xS++Ys^J=_fx#<*!ACnqSZ;qoq&I`F)DscoS0ZzTpTxVN4U6k zJ4T*hTCbBFk8k~o(mvYX`}$#CB1Y+Ij0xSr*Vf)$%Mzjf490l(spT}2qXuT`k?^os zyO}!?4dY(0*s=U(Mnmhum$@OPpV)D_orSMu2N{2kCR z0_;9ddN)&+d6ra`APkPGz?b4@@XQW74n3%}ifi_fHO3Cg_6rq^U$QG5@VHCs_Ja19 z3a#=aJf_?qrS~$*={T9*sm-#@2Kmyq==Jr5rVdeN5B~a4S*R~-W#Zi!)pn`ZeG~WZ z!5VXqg&R|J@D;@xNM&7v{J5dj3xVO&FpBF4uu_P*b zUGc?d=VYTRO)G6HP1c*$YBtJnrOif-PKPmU2A$^8SENlaY2-7w75fSM=`yA=UMn5V zy&8GEZ;4=WqhZL$+hv=%g&(d(7h3w4&4e|t{1%FYAES=_ewXc;u%PMdStRHwEaY?A zpHu_=wT0oGlpnUpt8Mzo61Ob3oVoaP;-L165#zs%*&p5LxUwLz;Md{T@j{AT3Myq` zwPv-MZ)Zg;JzuJ2sb$&O*W35JZ!}M}Ku2**X{BJLV60%a!PPm`S(Z>vc;{tSx9D8z zv`J{Xo#3qDRDyPJzFKcwjjNU%ZLDrA<18auXIfVlj$+zse-J(sDjN7}m&WNSH3UCG zq#MSa57Y3erfoB`IWzKo}1r>q36DT^iJ5ewL-+J6jcHgS3gkyj>B8d%)8j ztH){^N<#4aZd-i1KXrqiE$A+2tIsISI9=~mCpC06^w_ld7hX@8MLrOxdQ!uwgP<&0 zk_JPY9AgmU^2gyp_4c;N$3(r<04!QyP%%d}WN-?3XV&nyVYcB+0Y=eA{k_V2y$*SAr`{1X4sCYJLP$d%R-<uNw) zF}Za&p^Udeo=a9UTi+6EeeucP1{|<*-ba$#XG0`YnZjCyTQOqrLA62bIPwZi#CqEl zW)+_CJ-taaOyZMriR=YWW(TIFgvj-&v5l)XXt>ktTeshdI6+;Wv#Lv-={fnv?e)MO4i}hX1@Lj1h+4MC5Ph z8yDE;AG)}^ytnDq9UNVo2|qHS{K@`QMcXONd>%}a)&EkF02QpNjU$6J<2g(jJ`7<-AbhNoUM;^*@ zl+%Ax)Wg)y3V?7)0HWgn_(eVCDgbvC09bPcKrB;{Z|IcF- zG9>)(`&3WZIQGb<8b9RRXkKR>Bxf!4#$p@opfxx*#)9z7ezlCu81u-T_k_Vae|`|T r5SihSkuaf9jLe91Xnt^7I+aQbtg0366~C-OpRT~n$l9<5;TrotedWWh literal 0 HcmV?d00001 diff --git a/main/layout/gengrid/00_winset_thumbs_focus_bg.png b/main/layout/gengrid/00_winset_thumbs_focus_bg.png new file mode 100755 index 0000000000000000000000000000000000000000..3f0e9c41c76249bae6a77ea3cc9fff2505f8d8e6 GIT binary patch literal 3145 zcma);Rag|-8ip5wbcr;=rX)sSXry6=PJzK0z@P_2Bt$8}89Lk`BJCikbV%sn5K4o@ zARsw}w1D7|5R{mM`<&y|dG@m}{`FnFf2{voH!J>O|;#jqGj%z;O0gP=M?w+yKy9dcxtCE_wI__}upJ@f9?N!v%f)ecU~7x&aV0 ziL*f?Y*sln_hxorrg50Zrasmjw1U>KL=1b17(|GU)g(?Re}coR<&3^Q6<>E=9A#1x z<^hM56k`JYIL)Hav!ux9aS1&KbD__@MjQ8*`;T9bX|0rR<7x+JnrRu+jTEeuFpMQI zfis^XyV^VF7G-p>^rF6imA2MZ==PBa1=tVQ(6}JnO!F2{1PwFLf@braX4!MGWR^8p z))fj&6h(7D%0*LJ3_H*XNrDvu9RmssE>p|~y!;DI*|3H0HX%uIzNm zDO*RTH8_h$9;?XmX}b@AycCX;ZMTnth|HBlqH+?R`MUJlJ8H79v-867(mEf#{l;2Io zSy2Ja^LqenHTblAl%S==ctp+(1d_jM9~tJI2N-wbM}7cY(-W0J^wes1(E^~ChlNz> z^6j*6OEpuUYdJmD!f@!Q90e0?Z-ueK=v^`A{2e9BBVZCS{Z;%BN9ac#e#K@hkC;?n zW|>yoH_V#8EI*xSb6X@Dv2;|r-Lz+&geK!CoD)zYNwi#9(fdLzMpSHxqJr<^*sX+3 zQD|wnqG0n*OI$W3L$0r>J)W`G~`qMnk#B*cvO%kBqP3gklxmD1&DVA6x_E zvXeRUaz6OK;?;bhoWJs+%!6ezSqt7J+x(fEMxp(ttW0Mctoou9U8+lOwQxCOStoDR z<#Nh~_+6KQ>Od+stbQ|{GF2c<&`Cho2xW${7&j^wJSVDnW|B^Yjxx%sRa`i=*z}cH z{h1%_+|KfHu_z-ckx{nfvryL1IC#5?C|f*SUYzjolyUV7#1Pw%!O$&hkyWXZ97Q8u zk<|B-u3j}Xs*j}vFLXyQ;uhN$6&Cpxg|-~%an3q^FZONbC9HdHnD8vIE-5ZiyJgDj z+CI;=o-WQuoKZ@)hgIa`tzTNj7N1qTldakx$!Tm_Q1L8nnAd~LW6$&D=YaY%(`f=0 z86S{Cy{m?wGd@%91Tr$ka71>+p(S{7xM{f2Jb~OVGtCNlh7)zONAELlFb zCMk0YgrKFuUeER7EWMU<2lmd=zi*lyeQB9cq4*@RUZ*ecj8l+b-lFS9MhU0S!{ zvq6`r7sr;Oi+vEzL{-pPAHTtR5w#M>+0|8f7U;mrIe#7HzvQ5vywBGGh63qA7n3uFUG%dGp<>* zFSOglH{Oc2SG6lZ+1g*NHK@Qvwf7WM~(c zQ=8MeQA~Qdsl4gA89Vi~Pw}Z_uARc|4{hD>PgYBV+6+(AWW8p~!!6;KSoG@^5vU6^ z1z9mxRaX#Ly65zjOY6Iq|I-Dn1r3!M`5C+GeJag$-F3Z|Z9cizqi5mwMaZt?5b_`> z!kni-Q^sR;u@0vW_CxLoy-U(oBe{LAnb^>MkVnwv&`pl0h*)Z=5c25$@~}c^ZzYqM zLiA*gz7+m>^aG94vQuJPIHP!UY&0@PJIOZ=#XBgMp%gec1;0J3_fs!jZzcyVXQ}#9 z+C&MWRVs5sV^XDFv0l4V#@()O1cgHx-!wg^Dg&uhzIF5M?BT|C>^yFsVIh<&6WV>% zH#nczx)WW*St7$GrIxN^7H4ts@xOFgA;p{z&TpL!JfB1#+{)jI7KRQg55|qduRsJW zwu~U=A&r^OMUP{~f> z%HX&^E-@9f#24$+^Db-Z@vD-uc7p4G`;hzU@{Dw@19N(5#&QPpEvAXdS4^{)Uv2Du z*C#HkGLHeAJpz?SH_pF?x!DkU#+n4_S@*99HKm;5n;xU5k8La4{0K- zlSePC8!~tO@%9+^HBg#KnaTFgC!O;mzIwrnt9x{_djd>qlXoA4me0`)|8bWe%@4f+ z%ihX1$g#;jaBz00x9rmz99^3UIW#2w!SX~=!!Fol8}Z(Aay4Q&6}>g^0GEaf3zzvZ zsdn9aEnrRKICa>v ztKmsQb|vA87hyA`>2;|4-YQ?N3UPX;Dfk;Fd2}RKRdc#&JH%(NV{dnsb2{8#{D|1w zFcB!eSgdRU&ozFaUrez*tWg5j6Q_ zq?!pM%LsI7^o851=+++@cgqIkzex0mkl3^j9PPDO_xp}{YF`ep5jtliXxRmVWlcxh zZjQax*V8MhXvhotCU}X8{?uu#@FiA>6ZucpiRk9hvY!C`yuafKCu#qP|7!Dp`v0!~ z&3|2kmi>S8|AzlshU%a2-)sCe|9Ai2^}qRlZP+&w=&RqAbtvgS-H}N1moJTXC;=do ZDFIsqy`KTeJ?rGHfU&-XUM0*i;@>JHjr#xq literal 0 HcmV?d00001 diff --git a/main/layout/icons/T01_btn_paused.png b/main/layout/icons/T01_btn_paused.png new file mode 100755 index 0000000000000000000000000000000000000000..dae1d84f40b93e06f2313f6c24d54f190c5b12d1 GIT binary patch literal 5941 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 literal 0 HcmV?d00001 diff --git a/main/layout/images/theme/blue/00_winset_control_toolbar_bg.png b/main/layout/images/theme/blue/00_winset_control_toolbar_bg.png new file mode 100755 index 0000000000000000000000000000000000000000..33148b2c85ba80d73ce28658e5eeee91c9ad06c6 GIT binary patch literal 2798 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 Th#9g>00000NkvXXu0mjfQ@YYe literal 0 HcmV?d00001 diff --git a/main/layout/images/theme/blue/T01_title_btn_press.png b/main/layout/images/theme/blue/T01_title_btn_press.png new file mode 100755 index 0000000000000000000000000000000000000000..49861ed6816e1d36764e2f327b59ebf50dd904da GIT binary patch literal 3126 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 literal 0 HcmV?d00001 diff --git a/main/layout/images/theme/white/00_winset_control_top_arrow.png b/main/layout/images/theme/white/00_winset_control_top_arrow.png new file mode 100755 index 0000000000000000000000000000000000000000..508c2c8300f490403b01b8ce184d86b4d90d303c GIT binary patch literal 3190 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 literal 0 HcmV?d00001 diff --git a/main/layout/images/theme/white/00_winset_control_top_bg.png b/main/layout/images/theme/white/00_winset_control_top_bg.png new file mode 100755 index 0000000000000000000000000000000000000000..d92230a88f7d34ad2ab833fdf3d6e40ea7f2e509 GIT binary patch literal 2844 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 literal 0 HcmV?d00001 diff --git a/main/layout/images/theme/white/00_winset_title_line.png b/main/layout/images/theme/white/00_winset_title_line.png new file mode 100755 index 0000000000000000000000000000000000000000..e28797828da57e169e98c212c7ee06e75f6f7ee2 GIT binary patch literal 2802 zcmVKLZ*U+IBfRsybQWXdwQbLP>6pAqfylh#{fb6;Z(vMMVS~$e@S=j*ftg6;Uhf59&ghTmgWD0l;*T zI709Y^p6lP1rIRMx#05C~cW=H_Aw*bJ-5DT&Z2n+x)QHX^p z00esgV8|mQcmRZ%02D^@S3L16t`O%c004NIvOKvYIYoh62rY33S640`D9%Y2D-rV&neh&#Q1i z007~1e$oCcFS8neI|hJl{-P!B1ZZ9hpmq0)X0i`JwE&>$+E?>%_LC6RbVIkUx0b+_+BaR3cnT7Zv!AJxW zizFb)h!jyGOOZ85F;a?DAXP{m@;!0_IfqH8(HlgRxt7s3}k3K`kFu>>-2Q$QMFfPW!La{h336o>X zu_CMttHv6zR;&ZNiS=X8v3CR#fknUxHUxJ0uoBa_M6WNWeqIg~6QE69c9o#eyhGvpiOA@W-aonk<7r1(?fC{oI5N*U!4 zfg=2N-7=cNnjjOr{yriy6mMFgG#l znCF=fnQv8CDz++o6_Lscl}eQ+l^ZHARH>?_s@|##Rr6KLRFA1%Q+=*RRWnoLsR`7U zt5vFIcfW3@?wFpwUVxrVZ>QdQz32KIeJ}k~{cZZE^+ya? z2D1z#2HOnI7(B%_ac?{wFUQ;QQA1tBKtrWrm0_3Rgps+?Jfqb{jYbcQX~taRB;#$y zZN{S}1|}gUOHJxc?wV3fxuz+mJ4`!F$IZ;mqRrNsHJd##*D~ju=bP7?-?v~|cv>vB zsJ6IeNwVZxrdjT`yl#bBIa#GxRa#xMMy;K#CDyyGyQdMSxlWT#tDe?p!?5wT$+oGt z8L;Kp2HUQ-ZMJ=3XJQv;x5ci*?vuTfeY$;({XGW_huIFR9a(?@3)XSs8O^N5RyOM=TTmp(3=8^+zpz2r)C z^>JO{deZfso3oq3?Wo(Y?l$ge?uXo;%ru`Vo>?<<(8I_>;8Eq#KMS9gFl*neeosSB zfoHYnBQIkwkyowPu(zdms`p{<7e4kra-ZWq<2*OsGTvEV%s0Td$hXT+!*8Bnh2KMe zBmZRodjHV?r+_5^X9J0WL4jKW`}lf%A-|44I@@LTvf1rHjG(ze6+w@Jt%Bvjts!X0 z?2xS?_ve_-kiKB_KiJlZ$9G`c^=E@oNG)mWWaNo-3TIW8)$Hg0Ub-~8?KhvJ>$ z3*&nim@mj(aCxE5!t{lw7O5^0EIO7zOo&c6l<+|iDySBWCGrz@C5{St!X3hAA}`T4 z(TLbXTq+(;@<=L8dXnssyft|w#WSTW<++3>sgS%(4NTpeI-VAqb|7ssJvzNHgOZVu zaYCvgO_R1~>SyL=cFU|~g|hy|Zi}}s9+d~lYqOB71z9Z$wnC=pR9Yz4DhIM>Wmjgu z&56o6maCpC&F##y%G;1PobR9i?GnNg;gYtchD%p19a!eQtZF&3JaKv33gZ<8D~47E ztUS1iwkmDaPpj=$m#%)jCVEY4fnLGNg2A-`YwHVD3gv};>)hAvT~AmqS>Lr``i7kw zJ{5_It`yrBmlc25DBO7E8;5VoznR>Ww5hAaxn$2~(q`%A-YuS64wkBy=9dm`4cXeX z4c}I@?e+FW+b@^RDBHV(wnMq2zdX3SWv9u`%{xC-q*U}&`cyXV(%rRT*Z6MH?i+i& z_B8C(+grT%{XWUQ+f@NoP1R=AW&26{v-dx)iK^-Nmiuj8txj!m?Z*Ss1N{dh4z}01 z)YTo*JycSU)+_5r4#yw9{+;i4Ee$peRgIj+;v;ZGdF1K$3E%e~4LaI(jC-u%2h$&R z9cLXcYC@Xwnns&bn)_Q~Te?roKGD|d-g^8;+aC{{G(1^(O7m37Y1-+6)01cN&y1aw zoqc{T`P^XJqPBbIW6s}d4{z_f5Om?vMgNQEJG?v2T=KYd^0M3I6IZxbny)%vZR&LD zJpPl@Psh8QyPB@KTx+@RdcC!KX7}kEo;S|j^u2lU7XQ}Oo;f|;z4Ll+_r>@1-xl3| zawq-H%e&ckC+@AhPrP6BKT#_XdT7&;F71j}Joy zkC~6lh7E@6o;W@^IpRNZ{ptLtL(gQ-CY~4mqW;US7Zxvm_|@yz&e53Bp_lTPlfP|z zrTyx_>lv@x#=^!PzR7qqF<$gm`|ZJZ+;<)Cqu&ot2z=0000WV@Og>004R=004l4008;_004mL004C`008P>0026e000+nl3&F} z0000TNklKLZ*U+IBfRsybQWXdwQbLP>6pAqfylh#{fb6;Z(vMMVS~$e@S=j*ftg6;Uhf59&ghTmgWD0l;*T zI709Y^p6lP1rIRMx#05C~cW=H_Aw*bJ-5DT&Z2n+x)QHX^p z00esgV8|mQcmRZ%02D^@S3L16t`O%c004NIvOKvYIYoh62rY33S640`D9%Y2D-rV&neh&#Q1i z007~1e$oCcFS8neI|hJl{-P!B1ZZ9hpmq0)X0i`JwE&>$+E?>%_LC6RbVIkUx0b+_+BaR3cnT7Zv!AJxW zizFb)h!jyGOOZ85F;a?DAXP{m@;!0_IfqH8(HlgRxt7s3}k3K`kFu>>-2Q$QMFfPW!La{h336o>X zu_CMttHv6zR;&ZNiS=X8v3CR#fknUxHUxJ0uoBa_M6WNWeqIg~6QE69c9o#eyhGvpiOA@W-aonk<7r1(?fC{oI5N*U!4 zfg=2N-7=cNnjjOr{yriy6mMFgG#l znCF=fnQv8CDz++o6_Lscl}eQ+l^ZHARH>?_s@|##Rr6KLRFA1%Q+=*RRWnoLsR`7U zt5vFIcfW3@?wFpwUVxrVZ>QdQz32KIeJ}k~{cZZE^+ya? z2D1z#2HOnI7(B%_ac?{wFUQ;QQA1tBKtrWrm0_3Rgps+?Jfqb{jYbcQX~taRB;#$y zZN{S}1|}gUOHJxc?wV3fxuz+mJ4`!F$IZ;mqRrNsHJd##*D~ju=bP7?-?v~|cv>vB zsJ6IeNwVZxrdjT`yl#bBIa#GxRa#xMMy;K#CDyyGyQdMSxlWT#tDe?p!?5wT$+oGt z8L;Kp2HUQ-ZMJ=3XJQv;x5ci*?vuTfeY$;({XGW_huIFR9a(?@3)XSs8O^N5RyOM=TTmp(3=8^+zpz2r)C z^>JO{deZfso3oq3?Wo(Y?l$ge?uXo;%ru`Vo>?<<(8I_>;8Eq#KMS9gFl*neeosSB zfoHYnBQIkwkyowPu(zdms`p{<7e4kra-ZWq<2*OsGTvEV%s0Td$hXT+!*8Bnh2KMe zBmZRodjHV?r+_5^X9J0WL4jKW`}lf%A-|44I@@LTvf1rHjG(ze6+w@Jt%Bvjts!X0 z?2xS?_ve_-kiKB_KiJlZ$9G`c^=E@oNG)mWWaNo-3TIW8)$Hg0Ub-~8?KhvJ>$ z3*&nim@mj(aCxE5!t{lw7O5^0EIO7zOo&c6l<+|iDySBWCGrz@C5{St!X3hAA}`T4 z(TLbXTq+(;@<=L8dXnssyft|w#WSTW<++3>sgS%(4NTpeI-VAqb|7ssJvzNHgOZVu zaYCvgO_R1~>SyL=cFU|~g|hy|Zi}}s9+d~lYqOB71z9Z$wnC=pR9Yz4DhIM>Wmjgu z&56o6maCpC&F##y%G;1PobR9i?GnNg;gYtchD%p19a!eQtZF&3JaKv33gZ<8D~47E ztUS1iwkmDaPpj=$m#%)jCVEY4fnLGNg2A-`YwHVD3gv};>)hAvT~AmqS>Lr``i7kw zJ{5_It`yrBmlc25DBO7E8;5VoznR>Ww5hAaxn$2~(q`%A-YuS64wkBy=9dm`4cXeX z4c}I@?e+FW+b@^RDBHV(wnMq2zdX3SWv9u`%{xC-q*U}&`cyXV(%rRT*Z6MH?i+i& z_B8C(+grT%{XWUQ+f@NoP1R=AW&26{v-dx)iK^-Nmiuj8txj!m?Z*Ss1N{dh4z}01 z)YTo*JycSU)+_5r4#yw9{+;i4Ee$peRgIj+;v;ZGdF1K$3E%e~4LaI(jC-u%2h$&R z9cLXcYC@Xwnns&bn)_Q~Te?roKGD|d-g^8;+aC{{G(1^(O7m37Y1-+6)01cN&y1aw zoqc{T`P^XJqPBbIW6s}d4{z_f5Om?vMgNQEJG?v2T=KYd^0M3I6IZxbny)%vZR&LD zJpPl@Psh8QyPB@KTx+@RdcC!KX7}kEo;S|j^u2lU7XQ}Oo;f|;z4Ll+_r>@1-xl3| zawq-H%e&ckC+@AhPrP6BKT#_XdT7&;F71j}Joy zkC~6lh7E@6o;W@^IpRNZ{ptLtL(gQ-CY~4mqW;US7Zxvm_|@yz&e53Bp_lTPlfP|z zrTyx_>lv@x#=^!PzR7qqF<$gm`|ZJZ+;<)Cqu&ot2z=0000WV@Og>004R=004l4008;_004mL004C`008P>0026e000+nl3&F} z0005+Nkl)2|ha36dv85#7nI_ouwA_3OkjyaGyiI^${zPyvYHr|@Ik;1pJEsVEQ87X}0 z(l$JKjRMamumsNaK_b{;_U_n0^C$^~-+O&|E^yPQ4t(m~&uZ;l^a{K-43_i2E8)Yp zeV2&9cgu9_E71lI@S`D+x5SG+64&5M;8R1ux-~yk;ud_+eHGe;hDwOS_niZMCB)%} z46;xO75Jf(xT}O3yhN1fBB2H^m4$9esKHByxoZ+?@X~3ti-air_KLZ*U+IBfRsybQWXdwQbLP>6pAqfylh#{fb6;Z(vMMVS~$e@S=j*ftg6;Uhf59&ghTmgWD0l;*T zI709Y^p6lP1rIRMx#05C~cW=H_Aw*bJ-5DT&Z2n+x)QHX^p z00esgV8|mQcmRZ%02D^@S3L16t`O%c004NIvOKvYIYoh62rY33S640`D9%Y2D-rV&neh&#Q1i z007~1e$oCcFS8neI|hJl{-P!B1ZZ9hpmq0)X0i`JwE&>$+E?>%_LC6RbVIkUx0b+_+BaR3cnT7Zv!AJxW zizFb)h!jyGOOZ85F;a?DAXP{m@;!0_IfqH8(HlgRxt7s3}k3K`kFu>>-2Q$QMFfPW!La{h336o>X zu_CMttHv6zR;&ZNiS=X8v3CR#fknUxHUxJ0uoBa_M6WNWeqIg~6QE69c9o#eyhGvpiOA@W-aonk<7r1(?fC{oI5N*U!4 zfg=2N-7=cNnjjOr{yriy6mMFgG#l znCF=fnQv8CDz++o6_Lscl}eQ+l^ZHARH>?_s@|##Rr6KLRFA1%Q+=*RRWnoLsR`7U zt5vFIcfW3@?wFpwUVxrVZ>QdQz32KIeJ}k~{cZZE^+ya? z2D1z#2HOnI7(B%_ac?{wFUQ;QQA1tBKtrWrm0_3Rgps+?Jfqb{jYbcQX~taRB;#$y zZN{S}1|}gUOHJxc?wV3fxuz+mJ4`!F$IZ;mqRrNsHJd##*D~ju=bP7?-?v~|cv>vB zsJ6IeNwVZxrdjT`yl#bBIa#GxRa#xMMy;K#CDyyGyQdMSxlWT#tDe?p!?5wT$+oGt z8L;Kp2HUQ-ZMJ=3XJQv;x5ci*?vuTfeY$;({XGW_huIFR9a(?@3)XSs8O^N5RyOM=TTmp(3=8^+zpz2r)C z^>JO{deZfso3oq3?Wo(Y?l$ge?uXo;%ru`Vo>?<<(8I_>;8Eq#KMS9gFl*neeosSB zfoHYnBQIkwkyowPu(zdms`p{<7e4kra-ZWq<2*OsGTvEV%s0Td$hXT+!*8Bnh2KMe zBmZRodjHV?r+_5^X9J0WL4jKW`}lf%A-|44I@@LTvf1rHjG(ze6+w@Jt%Bvjts!X0 z?2xS?_ve_-kiKB_KiJlZ$9G`c^=E@oNG)mWWaNo-3TIW8)$Hg0Ub-~8?KhvJ>$ z3*&nim@mj(aCxE5!t{lw7O5^0EIO7zOo&c6l<+|iDySBWCGrz@C5{St!X3hAA}`T4 z(TLbXTq+(;@<=L8dXnssyft|w#WSTW<++3>sgS%(4NTpeI-VAqb|7ssJvzNHgOZVu zaYCvgO_R1~>SyL=cFU|~g|hy|Zi}}s9+d~lYqOB71z9Z$wnC=pR9Yz4DhIM>Wmjgu z&56o6maCpC&F##y%G;1PobR9i?GnNg;gYtchD%p19a!eQtZF&3JaKv33gZ<8D~47E ztUS1iwkmDaPpj=$m#%)jCVEY4fnLGNg2A-`YwHVD3gv};>)hAvT~AmqS>Lr``i7kw zJ{5_It`yrBmlc25DBO7E8;5VoznR>Ww5hAaxn$2~(q`%A-YuS64wkBy=9dm`4cXeX z4c}I@?e+FW+b@^RDBHV(wnMq2zdX3SWv9u`%{xC-q*U}&`cyXV(%rRT*Z6MH?i+i& z_B8C(+grT%{XWUQ+f@NoP1R=AW&26{v-dx)iK^-Nmiuj8txj!m?Z*Ss1N{dh4z}01 z)YTo*JycSU)+_5r4#yw9{+;i4Ee$peRgIj+;v;ZGdF1K$3E%e~4LaI(jC-u%2h$&R z9cLXcYC@Xwnns&bn)_Q~Te?roKGD|d-g^8;+aC{{G(1^(O7m37Y1-+6)01cN&y1aw zoqc{T`P^XJqPBbIW6s}d4{z_f5Om?vMgNQEJG?v2T=KYd^0M3I6IZxbny)%vZR&LD zJpPl@Psh8QyPB@KTx+@RdcC!KX7}kEo;S|j^u2lU7XQ}Oo;f|;z4Ll+_r>@1-xl3| zawq-H%e&ckC+@AhPrP6BKT#_XdT7&;F71j}Joy zkC~6lh7E@6o;W@^IpRNZ{ptLtL(gQ-CY~4mqW;US7Zxvm_|@yz&e53Bp_lTPlfP|z zrTyx_>lv@x#=^!PzR7qqF<$gm`|ZJZ+;<)Cqu&ot2z=0000WV@Og>004R=004l4008;_004mL004C`008P>0026e000+nl3&F} z0004GNklAs=7{>AcokeVhI7O)iUBzS*`eB4l7K@)KRB#gfFa@{6C7aZM zkSGdXC6c6z5xX?f`JVCRe#gO0&nxmgr-3d-0gOUt*0lF^O>X8q-jd=8X*Mj zb{pHahd~ekyb0HJN6kj#!*yMbT9YIRe`U2=5y$bn1je0Chva-NMF5WD0E{Kjvn-3# z>BK#$)oK7e2~?$&WLb6>6hZ)0Wihz@mU|-kXACsZKm!dl&_DwXG|)f;4g3X@dz;)% zc}pa))LIwyt~8gPxs-tawO(J#bXlS(0`R3$Y7&OwY`@=^qV0A|6h$+o)TC(Teh>sW zj`Lct*Rd>%N~Hoonx<&2+3j}3aXbV3>mJ}{fiMIHKp&`I#(Q7^%#~8p;_S}=&peX9 Th#9g>00000NkvXXu0mjfQ@YYe literal 0 HcmV?d00001 diff --git a/main/layout/images/theme/white/T01_title_btn_press.png b/main/layout/images/theme/white/T01_title_btn_press.png new file mode 100755 index 0000000000000000000000000000000000000000..49861ed6816e1d36764e2f327b59ebf50dd904da GIT binary patch literal 3126 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 literal 0 HcmV?d00001 diff --git a/main/res/images/01_Control icon/01_controllbar_icon_close.png b/main/res/images/01_Control icon/01_controllbar_icon_close.png new file mode 100755 index 0000000000000000000000000000000000000000..91b04e56cda2ca04c0272a8608bf76b9e2aa0185 GIT binary patch literal 1076 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 Hu0mjfQ;iJw literal 0 HcmV?d00001 diff --git a/main/res/images/01_Control icon/T01_1_title_icon_set_as.png b/main/res/images/01_Control icon/T01_1_title_icon_set_as.png new file mode 100755 index 0000000000000000000000000000000000000000..72b74da9f591d04face4d12963f3b85412ab1263 GIT binary patch literal 1520 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 literal 0 HcmV?d00001 diff --git a/main/res/images/01_Control icon/T01_Title_icon_more.png b/main/res/images/01_Control icon/T01_Title_icon_more.png new file mode 100755 index 0000000000000000000000000000000000000000..651c8e1e14b8e162e5001eae50b5d44f5dbf117e GIT binary patch literal 3061 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 Y0G~tc&d7UTwEzGB07*qoM6N<$g1FW5_5c6? literal 0 HcmV?d00001 diff --git a/main/res/images/01_Control icon/T01_controlbar_icon_share.png b/main/res/images/01_Control icon/T01_controlbar_icon_share.png new file mode 100755 index 0000000000000000000000000000000000000000..f21b00c8d162512da8877374ddc4c226088055f7 GIT binary patch literal 3310 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 bnR*o1LsqsH-G6#D`Y(0mEO(yGUbpohdkhwW literal 0 HcmV?d00001 diff --git a/main/res/images/Popup_icon/T01_1_popup_icon_Paste from Clipboard.png b/main/res/images/Popup_icon/T01_1_popup_icon_Paste from Clipboard.png new file mode 100755 index 0000000000000000000000000000000000000000..14b8895bdfb2e6f65cf1a178326d211fedec4eb2 GIT binary patch literal 1547 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=k|nMYCBgY=CFO}lsSJ)O`AMk? zp1FzXsX?iUDV2pMQ*9U+n3Xa^B1$5BeXNr6bM+EIYV;~{3xK*A7;Nk-3KEmEQ%e+* zQqwc@Y?a>c-mj#PnPRIHZt82`Ti~3Uk?B!Ylp0*+7m{3+ootz+WN)WnQ(*-(AUCxn zQK2F?C$HG5!d3}vt`(3C64qBz04piUwpD^SD#ABF!8yMuRl!uxKsVXI%uvD1M9IxIyg#@@$ndN=gc>^!3Zj z%k|2Q_413-^$jg8E%gnI^o@*kfhu&1EAvVcD|GXUm0>2hq!uR^WfqiV=I1GZOiWD5 zFD$Tv3bSNU;+l1ennz|zM-B0$V)JVzP|XC=H|jx7ncO3BHWAB;NpiyW)Z+ZoqGVvir744~DzI`cN=+=uFAB-e&w+(vKt_H^esM;Afr4|esh*)icxGNo zet9uiy|1s8XI^nhVqS8pr;Du;&;-5A%oHnEOH(%kGZ$wkU|<^>x*9r}S~^>rShyHD zTRIv#8yUd#y5uL9=BDPA!1Sgd^t#~G3rY&P1wfl!Qj0RnQd8WD@^clyUbf1_?G{Iz z=0WwQ;C71>PQCg-$LND17Ac}(Lcr7mV#1RxkONQnsd>QEUIa|muTE<%VqjpZ_jGX# zskrqf`o6n!pp5-$NyB48fo6iXy(^|i^j{1<(joCxXlX}Wl}Ejk|HN-5s$P5DzC`#N z2Du!Wp_J4mk(_sb{oKN}yLVTYpL=JU{{8pE!=+{Kzu$YG{=H`Z{m+lvcn&8xy2*1} zcrXYxuqZGBDTMU^P_Eqys8)UVXnLh|xbXPxC>tK_IU0!4SgLz(47ffEnB3}_PX>WRW_`k{B zcMq%%pPIn+Wasx99#9NER<9BhlYgA& zLyNpRkKrEX$A0hEI*A`x^wOs!;PMx>v#*7irOvsl-0pp;;IMtpbtP_%hkN3gG#>Af zXVQ4O=X$Aw_4DjyQT4Z$zV*HK@J>R6;Pb)*#aUK*JGRUZk8I#r|885(xt*+HmAVt& zF6d4Pea95q{+Z>)7t4Z;*OMIPY@M&<%`m;;@m>j*jV89s9vW~ud}id`!??Y2-*nRt z2Q|M~#E4M!S&;P z?MhD?&HeoODt|oHIQM(`uA2Tuw@qXh`KN1woa8X!qxu1c)l6)>6YlR_3@V;IUHx3v IIVCg!001&Sg#Z8m literal 0 HcmV?d00001 diff --git a/main/res/po/.pot b/main/res/po/.pot new file mode 100755 index 0000000..1f0dd57 --- /dev/null +++ b/main/res/po/.pot @@ -0,0 +1,142 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR , YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2010-10-12 09:32+0900\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=CHARSET\n" +"Content-Transfer-Encoding: 8bit\n" + +#: src/util/mb_util.c:318 +msgid "IDS_COM_SK_DELETE" +msgstr "" + +#: src/util/mb_util.c:321 +msgid "IDS_COM_POP_CLOSE_A" +msgstr "" + +#: src/util/mb_util.c:474 src/features/slide_view.c:3238 +msgid "Done" +msgstr "" + +#. UI_contextpopup_insert_text( context_popup, 3, _("Message"), _("Email"), _("Bluetooth")); +#: src/util/mb_util.c:812 src/util/mb_util.c:819 +msgid "IDS_COM_BODY_MESSAGE" +msgstr "" + +#: src/util/mb_util.c:813 src/util/mb_util.c:820 +msgid "IDS_COM_BODY_EMAIL" +msgstr "" + +#: src/util/mb_util.c:814 +msgid "IDS_COM_BODY_BLUETOOTH" +msgstr "" + +#. UI_contextpopup_insert_text( context_popup, 2, _("Wallpaper"), _("Caller ID")); +#: src/util/mb_util.c:825 +msgid "IDS_MEDIABR_OPT_WALLPAPER" +msgstr "" + +#: src/util/mb_util.c:826 +msgid "IDS_MEDIABR_OPT2_CALLER_ID" +msgstr "" + +#. struct appdata *pAppData = (struct appdata*)pUserData; +#: video/MpUtil.c:300 video/MpUtil.c:303 video/MpVideoAppCtrl.c:165 +#: video/MpVideoAppCtrl.c:169 +msgid "IDS_COM_BODY_LOW_BATTERY" +msgstr "" + +#: video/MpUtil.c:886 +msgid "IDS_COM_SK_OK" +msgstr "" + +#: video/MpUtil.c:901 src/features/set_as.c:504 +msgid "IDS_IMGE_BUTTON_CANCEL" +msgstr "" + +#: video/MpVideoAppCtrl.c:189 +msgid "IDS_SL_HEADER_CONFIRM" +msgstr "" + +#: video/MpVideoAppCtrl.c:189 video/MpVideoAppCtrl.c:358 +msgid "Current mode is silent mode
Continue play?" +msgstr "" + +#: video/MpVideoAppCtrl.c:358 +msgid "Confirm" +msgstr "" + +#. Popup +#: video/MpVideoAppCtrl.c:1144 +msgid "Bluetooth disconnected" +msgstr "" + +#. 6. +#: video/PlayViewCtrl.c:929 +msgid "IDS_VPL_DETAILS_BACK" +msgstr "" + +#: video/PlayViewCtrl.c:1045 +msgid "pSoftkey, NULL, _("IDS_VPL_OPT_CONNECTED_HOME"), SoftkeyAllshare_cb, pAppData); +#: video/PlayViewCtrl.c:1108 +msgid "IDS_VPL_OPT_SUBTITLES" +msgstr "" + +#: video/PlayViewCtrl.c:1111 +msgid "IDS_VPL_OPT_DETAILS" +msgstr "" + +#. edje_edit_state_text_set(pAppData->pSubtitlePopupEdj, "subtitle_popup_text", "default 0.0", _("IDS_VPL_OPT_DISPLAY_SUBTITLE")); +#: video/PlayViewCtrl.c:1431 video/PlayViewCtrl.c:1583 +msgid "IDS_VPL_OPT_DISPLAY_SUBTITLE" +msgstr "" + +#. chenhanwu +#: src/features/set_as.c:503 +msgid "IDS_COM_SK_DONE" +msgstr "" + +#: src/features/slide_view.c:1952 src/features/slide_view.c:2002 +msgid "Prev" +msgstr "" + +#: src/features/slide_view.c:3242 +msgid "IDS_COM_SK_CANCEL" +msgstr "" diff --git a/main/res/po/ar.po b/main/res/po/ar.po new file mode 100755 index 0000000..9fe1d75 --- /dev/null +++ b/main/res/po/ar.po @@ -0,0 +1,186 @@ +msgid "IDS_IV_BODY_ACCUMULATED_TIME" +msgstr "الوقت المتراكم" + +msgid "IDS_IV_HEADER_ADD_TAG" +msgstr "إضافة علامة" + +msgid "IDS_IV_POP_ADDED" +msgstr "تمت الإضافة" + +msgid "IDS_IV_BODY_ANY" +msgstr "أي" + +msgid "IDS_IV_BODY_AVAILABLE_USES" +msgstr "الاستخدامات المتوفرة" + +msgid "IDS_IV_BODY_BASIC" +msgstr "أساسي" + +msgid "IDS_IV_BODY_CALLER_IMAGE" +msgstr "صورة المتصل" + +msgid "IDS_IV_BODY_COUNT" +msgstr "العدد" + +msgid "IDS_IV_BODY_DATE_CREATED" +msgstr "تاريخ الإنشاء" + +msgid "IDS_IV_BODY_DISPLAY" +msgstr "الشاشة" + +msgid "IDS_IV_POP_ENTER_TAG_NAME" +msgstr "أدخل اسم الرمز" + +msgid "IDS_IV_POP_ENTRY_IS_EMPTY" +msgstr "المدخل خالي" + +msgid "IDS_IV_BODY_EXECUTE" +msgstr "تنفيذ" + +msgid "IDS_IV_BODY_FILE_FORMAT" +msgstr "تنسيق الملف" + +msgid "IDS_IV_BODY_FILE_LOCATION" +msgstr "موقع الملف" + +msgid "IDS_IV_BODY_FORWARDING" +msgstr "التحويل" + +msgid "IDS_IV_HEADER_HOME_SCREEN_WALLPAPER_ABB" +msgstr "خلفية الشاشة الرئيسية" + +msgid "IDS_IV_BODY_IMPOSSIBLE" +msgstr "غير ممكن" + +msgid "IDS_IV_BODY_INDIVIDUAL" +msgstr "فردي" + +msgid "IDS_IV_BODY_INTERVAL" +msgstr "الفترة" + +msgid "IDS_IV_POP_INVALID_IMAGE_FILE" +msgstr "ملف صورة غير صالح" + +msgid "IDS_IV_BODY_LATITUDE" +msgstr "المدى" + +msgid "IDS_IV_BODY_LOCATIONS" +msgstr "المواقع" + +msgid "IDS_IV_HEADER_LOCK_SCREEN_WALLPAPER_ABB" +msgstr "خلفية شاشة القفل" + +msgid "IDS_IV_BODY_LONGITUDE" +msgstr "خط الطول" + +msgid "IDS_IV_POP_MAXIMUM_NUMBER_OF_CHARACTERS_HPD_REACHED" +msgstr "تم بلوغ أقصى عدد من الأحرف (%d)" + +msgid "IDS_IV_BODY_N_A" +msgstr "غير متاح" + +msgid "IDS_IV_BODY_NEW_TAG" +msgstr "علامة جديدة" + +msgid "IDS_IV_POP_PERMISSION_DENIED" +msgstr "تم رفض الإذن" + +msgid "IDS_IV_BODY_POSSIBLE" +msgstr "ممكن" + +msgid "IDS_IV_BODY_PRINT" +msgstr "طباعة" + +msgid "IDS_IV_OPT_PRINT_VIA_BLUETOOTH" +msgstr "طباعة عبر البلوتوث" + +msgid "IDS_IV_BODY_RESOLUTION" +msgstr "الدقة" + +msgid "IDS_IV_BODY_RIGHT_STATUS" +msgstr "حالة الحقوق" + +msgid "IDS_IV_POP_SD_CARD_REMOVED" +msgstr "تمت إزالة بطاقة SD" + +msgid "IDS_IV_POP_SELECT_DEVICE" +msgstr "تحديد جهاز" + +msgid "IDS_IV_BODY_SERVER_NAME" +msgstr "اسم الخادم" + +msgid "IDS_IV_OPT_SET_AS" +msgstr "تعيين" + +msgid "IDS_IV_POP_SET_WALLPAPER_FOR_HOME_SCREEN_AND_LOCK_SCREEN" +msgstr "تعيين خلفية للشاشة الرئيسية وشاشة القفل" + +msgid "IDS_IV_OPT_SHARE" +msgstr "مشاركة" + +msgid "IDS_IV_OPT_SLIDE_SHOW" +msgstr "عرض الصور" + +msgid "IDS_IV_BODY_TIMED_COUNT" +msgstr "عداد محدد زمنيا" + +msgid "IDS_IV_OPT_TRIM" +msgstr "شذب" + +msgid "IDS_IV_BODY_UNLIMITED" +msgstr "غير محدود" + +msgid "IDS_IV_BODY_VALIDITY" +msgstr "الصلاحية" + +msgid "IDS_IV_BODY_VENDOR" +msgstr "التاجر" + +msgid "IDS_IV_OPT_FILE_TRANSFER" +msgstr "نقل الملف" + +msgid "IDS_IV_BODY_DO_NOT_SHOW_AGAIN" +msgstr "عدم العرض مرة أخرى" + +msgid "IDS_IV_BODY_TAP_AND_HOLD_AT_TWO_POINTS_THEN_TILT_DEVICE_BACK_AND_FORTH_TO_REDUCE_OR_ENLARGE_SCREEN" +msgstr "انقر مع الاستمرار فوق نقطتين ثم قم بإمالة الجهاز للخلف والأمام لتصغير الشاشة أو تكبيرها" + +msgid "IDS_IV_HEADER_LEARN_ABOUT_TILT" +msgstr "تعرف على الإمالة" + +msgid "IDS_IV_HEADER_ALL_ALBUMS" +msgstr "كافة الألبومات" + +msgid "IDS_IV_OPT_TAG" +msgstr "علامة" + +msgid "IDS_IV_OPT_HOME_AND_LOCK_SCREEN_WALLPAPER" +msgstr "خلفية ‏‫شاشة القفل والشاشة الرئيسية‬" + +msgid "IDS_IV_OPT_USE_MOTION" +msgstr "استخدام الحركة" + +msgid "IDS_MEDIABR_OPT_CREATE_TAG" +msgstr "إنشاء ع." + +msgid "IDS_IV_BODY_HOME_AND_LOCK_SCREENS" +msgstr "شاشتا القفل والرئيسية" + +msgid "IDS_IV_OPT_COPY_TO_CLIPBOARD" +msgstr "نسخ إلى الحافظة" + +msgid "IDS_IV_BODY_CROP" +msgstr "قص" + +msgid "IDS_IV_BODY_HOME_SCREEN" +msgstr "الشاشة الرئيسية" + +msgid "IDS_IV_BODY_LOCK_SCREEN" +msgstr "قفل الشاشة" + +msgid "IDS_IV_OPT_ROTATE_LEFT" +msgstr "تدوير لليسار" + +msgid "IDS_IV_OPT_ROTATE_RIGHT" +msgstr "تدوير لليمين" + diff --git a/main/res/po/bg.po b/main/res/po/bg.po new file mode 100755 index 0000000..406ee05 --- /dev/null +++ b/main/res/po/bg.po @@ -0,0 +1,186 @@ +msgid "IDS_IV_BODY_ACCUMULATED_TIME" +msgstr "Натрупано време" + +msgid "IDS_IV_HEADER_ADD_TAG" +msgstr "Добави таг" + +msgid "IDS_IV_POP_ADDED" +msgstr "Добавен" + +msgid "IDS_IV_BODY_ANY" +msgstr "Всеки" + +msgid "IDS_IV_BODY_AVAILABLE_USES" +msgstr "Налични употреби" + +msgid "IDS_IV_BODY_BASIC" +msgstr "Базово" + +msgid "IDS_IV_BODY_CALLER_IMAGE" +msgstr "Изобр. повикващ" + +msgid "IDS_IV_BODY_COUNT" +msgstr "Броене" + +msgid "IDS_IV_BODY_DATE_CREATED" +msgstr "Дата на създаване" + +msgid "IDS_IV_BODY_DISPLAY" +msgstr "Дисплей" + +msgid "IDS_IV_POP_ENTER_TAG_NAME" +msgstr "Въведете име на таг" + +msgid "IDS_IV_POP_ENTRY_IS_EMPTY" +msgstr "Празен запис" + +msgid "IDS_IV_BODY_EXECUTE" +msgstr "Изпълни" + +msgid "IDS_IV_BODY_FILE_FORMAT" +msgstr "Формат на файла" + +msgid "IDS_IV_BODY_FILE_LOCATION" +msgstr "Местоположение на файла" + +msgid "IDS_IV_BODY_FORWARDING" +msgstr "Препращане" + +msgid "IDS_IV_HEADER_HOME_SCREEN_WALLPAPER_ABB" +msgstr "Тапет начален екран" + +msgid "IDS_IV_BODY_IMPOSSIBLE" +msgstr "Невъзможно" + +msgid "IDS_IV_BODY_INDIVIDUAL" +msgstr "Индивидуален" + +msgid "IDS_IV_BODY_INTERVAL" +msgstr "Интервал" + +msgid "IDS_IV_POP_INVALID_IMAGE_FILE" +msgstr "Невалиден файл на изображение" + +msgid "IDS_IV_BODY_LATITUDE" +msgstr "Геогр. ширина" + +msgid "IDS_IV_BODY_LOCATIONS" +msgstr "Местоположения" + +msgid "IDS_IV_HEADER_LOCK_SCREEN_WALLPAPER_ABB" +msgstr "Тапет заключен екран" + +msgid "IDS_IV_BODY_LONGITUDE" +msgstr "Геогр. дължина" + +msgid "IDS_IV_POP_MAXIMUM_NUMBER_OF_CHARACTERS_HPD_REACHED" +msgstr "Достигнат е максималният брой знаци (%d)" + +msgid "IDS_IV_BODY_N_A" +msgstr "н.д." + +msgid "IDS_IV_BODY_NEW_TAG" +msgstr "Нов таг" + +msgid "IDS_IV_POP_PERMISSION_DENIED" +msgstr "Отказано разрешение" + +msgid "IDS_IV_BODY_POSSIBLE" +msgstr "Lъзможно" + +msgid "IDS_IV_BODY_PRINT" +msgstr "Отпечатаване" + +msgid "IDS_IV_OPT_PRINT_VIA_BLUETOOTH" +msgstr "Печат чрез Bluetooth" + +msgid "IDS_IV_BODY_RESOLUTION" +msgstr "Разделителна способност" + +msgid "IDS_IV_BODY_RIGHT_STATUS" +msgstr "Състояние на правата" + +msgid "IDS_IV_POP_SD_CARD_REMOVED" +msgstr "SD картата е извадена" + +msgid "IDS_IV_POP_SELECT_DEVICE" +msgstr "Избор на устр-во" + +msgid "IDS_IV_BODY_SERVER_NAME" +msgstr "Име на сървър" + +msgid "IDS_IV_OPT_SET_AS" +msgstr "Задаване като" + +msgid "IDS_IV_POP_SET_WALLPAPER_FOR_HOME_SCREEN_AND_LOCK_SCREEN" +msgstr "Задаване на тапет за началния екран и екрана за заключване" + +msgid "IDS_IV_OPT_SHARE" +msgstr "Споделям" + +msgid "IDS_IV_OPT_SLIDE_SHOW" +msgstr "Слайдшоу" + +msgid "IDS_IV_BODY_TIMED_COUNT" +msgstr "Отброяване по време" + +msgid "IDS_IV_OPT_TRIM" +msgstr "Орязване" + +msgid "IDS_IV_BODY_UNLIMITED" +msgstr "Неограничен" + +msgid "IDS_IV_BODY_VALIDITY" +msgstr "Валидност" + +msgid "IDS_IV_BODY_VENDOR" +msgstr "Доставчик" + +msgid "IDS_IV_OPT_FILE_TRANSFER" +msgstr "Прехвърляне на файл" + +msgid "IDS_IV_BODY_DO_NOT_SHOW_AGAIN" +msgstr "Не показвай отново" + +msgid "IDS_IV_BODY_TAP_AND_HOLD_AT_TWO_POINTS_THEN_TILT_DEVICE_BACK_AND_FORTH_TO_REDUCE_OR_ENLARGE_SCREEN" +msgstr "Чукнете и задръжте в две точки, след което наклонете устройството напред-назад, за да намалите или увеличите екрана" + +msgid "IDS_IV_HEADER_LEARN_ABOUT_TILT" +msgstr "Научете за накланянето" + +msgid "IDS_IV_HEADER_ALL_ALBUMS" +msgstr "Всички албуми" + +msgid "IDS_IV_OPT_TAG" +msgstr "Таг" + +msgid "IDS_IV_OPT_HOME_AND_LOCK_SCREEN_WALLPAPER" +msgstr "Тапет на началния екран и на заключен екран" + +msgid "IDS_IV_OPT_USE_MOTION" +msgstr "С движение" + +msgid "IDS_MEDIABR_OPT_CREATE_TAG" +msgstr "Създ. таг" + +msgid "IDS_IV_BODY_HOME_AND_LOCK_SCREENS" +msgstr "Начален и заключен екран" + +msgid "IDS_IV_OPT_COPY_TO_CLIPBOARD" +msgstr "Копирай в клипборда" + +msgid "IDS_IV_BODY_CROP" +msgstr "Изрязване" + +msgid "IDS_IV_BODY_HOME_SCREEN" +msgstr "Начален екран" + +msgid "IDS_IV_BODY_LOCK_SCREEN" +msgstr "Заключен екран" + +msgid "IDS_IV_OPT_ROTATE_LEFT" +msgstr "Завъртане наляво" + +msgid "IDS_IV_OPT_ROTATE_RIGHT" +msgstr "Завъртане надясно" + diff --git a/main/res/po/ca.po b/main/res/po/ca.po new file mode 100755 index 0000000..ff84b36 --- /dev/null +++ b/main/res/po/ca.po @@ -0,0 +1,186 @@ +msgid "IDS_IV_BODY_ACCUMULATED_TIME" +msgstr "Temps acumulat" + +msgid "IDS_IV_HEADER_ADD_TAG" +msgstr "Afeg etiq" + +msgid "IDS_IV_POP_ADDED" +msgstr "Afegit" + +msgid "IDS_IV_BODY_ANY" +msgstr "Qualsevol" + +msgid "IDS_IV_BODY_AVAILABLE_USES" +msgstr "Usos disponibles" + +msgid "IDS_IV_BODY_BASIC" +msgstr "Bàsic" + +msgid "IDS_IV_BODY_CALLER_IMAGE" +msgstr "Imatge de la persona que truca" + +msgid "IDS_IV_BODY_COUNT" +msgstr "Comptatge" + +msgid "IDS_IV_BODY_DATE_CREATED" +msgstr "Data creació" + +msgid "IDS_IV_BODY_DISPLAY" +msgstr "Pantalla" + +msgid "IDS_IV_POP_ENTER_TAG_NAME" +msgstr "Introduir nom d'etiqueta" + +msgid "IDS_IV_POP_ENTRY_IS_EMPTY" +msgstr "L'entrada és buida" + +msgid "IDS_IV_BODY_EXECUTE" +msgstr "Executar" + +msgid "IDS_IV_BODY_FILE_FORMAT" +msgstr "Format del fitxer" + +msgid "IDS_IV_BODY_FILE_LOCATION" +msgstr "Ubicació del fitxer" + +msgid "IDS_IV_BODY_FORWARDING" +msgstr "Reenviant" + +msgid "IDS_IV_HEADER_HOME_SCREEN_WALLPAPER_ABB" +msgstr "Fons pantalla inici" + +msgid "IDS_IV_BODY_IMPOSSIBLE" +msgstr "No és possible" + +msgid "IDS_IV_BODY_INDIVIDUAL" +msgstr "Individual" + +msgid "IDS_IV_BODY_INTERVAL" +msgstr "Interval" + +msgid "IDS_IV_POP_INVALID_IMAGE_FILE" +msgstr "Arxiu d'imatges no vàlid" + +msgid "IDS_IV_BODY_LATITUDE" +msgstr "Latitud" + +msgid "IDS_IV_BODY_LOCATIONS" +msgstr "Ubicacions" + +msgid "IDS_IV_HEADER_LOCK_SCREEN_WALLPAPER_ABB" +msgstr "Bloq fons pant inici" + +msgid "IDS_IV_BODY_LONGITUDE" +msgstr "Longitud" + +msgid "IDS_IV_POP_MAXIMUM_NUMBER_OF_CHARACTERS_HPD_REACHED" +msgstr "S'ha assolit el nombre màxim de caràcters (%d)" + +msgid "IDS_IV_BODY_N_A" +msgstr "N/D" + +msgid "IDS_IV_BODY_NEW_TAG" +msgstr "Nova etiqueta" + +msgid "IDS_IV_POP_PERMISSION_DENIED" +msgstr "Permís denegat" + +msgid "IDS_IV_BODY_POSSIBLE" +msgstr "Possible" + +msgid "IDS_IV_BODY_PRINT" +msgstr "Imprimir" + +msgid "IDS_IV_OPT_PRINT_VIA_BLUETOOTH" +msgstr "Imprimir mitjançant Bluetooth" + +msgid "IDS_IV_BODY_RESOLUTION" +msgstr "Resolució" + +msgid "IDS_IV_BODY_RIGHT_STATUS" +msgstr "Estat correcte" + +msgid "IDS_IV_POP_SD_CARD_REMOVED" +msgstr "Sense targeta SD" + +msgid "IDS_IV_POP_SELECT_DEVICE" +msgstr "Seleccioni dispositiu" + +msgid "IDS_IV_BODY_SERVER_NAME" +msgstr "Nom del servidor" + +msgid "IDS_IV_OPT_SET_AS" +msgstr "Definir com a" + +msgid "IDS_IV_POP_SET_WALLPAPER_FOR_HOME_SCREEN_AND_LOCK_SCREEN" +msgstr "Definir fons de la pantalla d'inici i bloquejar pantalla" + +msgid "IDS_IV_OPT_SHARE" +msgstr "Compartir" + +msgid "IDS_IV_OPT_SLIDE_SHOW" +msgstr "Presentació de diapositives" + +msgid "IDS_IV_BODY_TIMED_COUNT" +msgstr "Compte contrarellotge" + +msgid "IDS_IV_OPT_TRIM" +msgstr "Acoblar" + +msgid "IDS_IV_BODY_UNLIMITED" +msgstr "Il·limitat" + +msgid "IDS_IV_BODY_VALIDITY" +msgstr "Validesa" + +msgid "IDS_IV_BODY_VENDOR" +msgstr "Proveïdor" + +msgid "IDS_IV_OPT_FILE_TRANSFER" +msgstr "Transferència de fitxer" + +msgid "IDS_IV_BODY_DO_NOT_SHOW_AGAIN" +msgstr "No tornar a mostrar" + +msgid "IDS_IV_BODY_TAP_AND_HOLD_AT_TWO_POINTS_THEN_TILT_DEVICE_BACK_AND_FORTH_TO_REDUCE_OR_ENLARGE_SCREEN" +msgstr "Mantingui tocats dos punts i inclini el dispositiu endavant i endarrere per reduir o ampliar la pantalla" + +msgid "IDS_IV_HEADER_LEARN_ABOUT_TILT" +msgstr "Més info inclinació" + +msgid "IDS_IV_HEADER_ALL_ALBUMS" +msgstr "Tots els àlbums" + +msgid "IDS_IV_OPT_TAG" +msgstr "Etiqueta" + +msgid "IDS_IV_OPT_HOME_AND_LOCK_SCREEN_WALLPAPER" +msgstr "Fons de pantalla de pantalla d'inici i bloqueig" + +msgid "IDS_IV_OPT_USE_MOTION" +msgstr "Utilitzar moviment" + +msgid "IDS_MEDIABR_OPT_CREATE_TAG" +msgstr "Crear etiq" + +msgid "IDS_IV_BODY_HOME_AND_LOCK_SCREENS" +msgstr "Pantalla inici i bloqueig" + +msgid "IDS_IV_OPT_COPY_TO_CLIPBOARD" +msgstr "Copiar al porta-retalls" + +msgid "IDS_IV_BODY_CROP" +msgstr "Retallar" + +msgid "IDS_IV_BODY_HOME_SCREEN" +msgstr "Pantalla d'inici" + +msgid "IDS_IV_BODY_LOCK_SCREEN" +msgstr "Bloquejar pantalla" + +msgid "IDS_IV_OPT_ROTATE_LEFT" +msgstr "Girar cap a l'esquerra" + +msgid "IDS_IV_OPT_ROTATE_RIGHT" +msgstr "Girar cap a la dreta" + diff --git a/main/res/po/cs.po b/main/res/po/cs.po new file mode 100755 index 0000000..39fd66a --- /dev/null +++ b/main/res/po/cs.po @@ -0,0 +1,186 @@ +msgid "IDS_IV_BODY_ACCUMULATED_TIME" +msgstr "Celkový čas" + +msgid "IDS_IV_HEADER_ADD_TAG" +msgstr "Přid. zn." + +msgid "IDS_IV_POP_ADDED" +msgstr "Přidáno" + +msgid "IDS_IV_BODY_ANY" +msgstr "VÅ¡e" + +msgid "IDS_IV_BODY_AVAILABLE_USES" +msgstr "Počet použití k dispozici" + +msgid "IDS_IV_BODY_BASIC" +msgstr "Základní" + +msgid "IDS_IV_BODY_CALLER_IMAGE" +msgstr "Obrázek volajícího" + +msgid "IDS_IV_BODY_COUNT" +msgstr "Počet" + +msgid "IDS_IV_BODY_DATE_CREATED" +msgstr "Datum vytvoření" + +msgid "IDS_IV_BODY_DISPLAY" +msgstr "Displej" + +msgid "IDS_IV_POP_ENTER_TAG_NAME" +msgstr "Zadejte název značky" + +msgid "IDS_IV_POP_ENTRY_IS_EMPTY" +msgstr "Prázdná položka" + +msgid "IDS_IV_BODY_EXECUTE" +msgstr "Provést" + +msgid "IDS_IV_BODY_FILE_FORMAT" +msgstr "Formát souboru" + +msgid "IDS_IV_BODY_FILE_LOCATION" +msgstr "Umístění souboru" + +msgid "IDS_IV_BODY_FORWARDING" +msgstr "Předání" + +msgid "IDS_IV_HEADER_HOME_SCREEN_WALLPAPER_ABB" +msgstr "Pozadí dom. obrazovky" + +msgid "IDS_IV_BODY_IMPOSSIBLE" +msgstr "Nemožné" + +msgid "IDS_IV_BODY_INDIVIDUAL" +msgstr "Individuální" + +msgid "IDS_IV_BODY_INTERVAL" +msgstr "Interval" + +msgid "IDS_IV_POP_INVALID_IMAGE_FILE" +msgstr "Neplatný soubor obrázku" + +msgid "IDS_IV_BODY_LATITUDE" +msgstr "Zeměpisná šířka" + +msgid "IDS_IV_BODY_LOCATIONS" +msgstr "Polohy" + +msgid "IDS_IV_HEADER_LOCK_SCREEN_WALLPAPER_ABB" +msgstr "Zamknout pozadí obr." + +msgid "IDS_IV_BODY_LONGITUDE" +msgstr "Zeměpisná délka" + +msgid "IDS_IV_POP_MAXIMUM_NUMBER_OF_CHARACTERS_HPD_REACHED" +msgstr "Bylo dosaženo maximálního počtu znaků (%d)" + +msgid "IDS_IV_BODY_N_A" +msgstr "Nepoužito" + +msgid "IDS_IV_BODY_NEW_TAG" +msgstr "Nová značka" + +msgid "IDS_IV_POP_PERMISSION_DENIED" +msgstr "Povolení bylo odepřeno" + +msgid "IDS_IV_BODY_POSSIBLE" +msgstr "Možné" + +msgid "IDS_IV_BODY_PRINT" +msgstr "Tisk" + +msgid "IDS_IV_OPT_PRINT_VIA_BLUETOOTH" +msgstr "Tisk přes Bluetooth" + +msgid "IDS_IV_BODY_RESOLUTION" +msgstr "RozliÅ¡ení" + +msgid "IDS_IV_BODY_RIGHT_STATUS" +msgstr "Stav práv" + +msgid "IDS_IV_POP_SD_CARD_REMOVED" +msgstr "SD karta byla vyjmuta" + +msgid "IDS_IV_POP_SELECT_DEVICE" +msgstr "Zvolte umístění" + +msgid "IDS_IV_BODY_SERVER_NAME" +msgstr "Název serveru" + +msgid "IDS_IV_OPT_SET_AS" +msgstr "Nastavit jako" + +msgid "IDS_IV_POP_SET_WALLPAPER_FOR_HOME_SCREEN_AND_LOCK_SCREEN" +msgstr "Nastavit pozadí pro domovskou obrazovku a zamknout obrazovku" + +msgid "IDS_IV_OPT_SHARE" +msgstr "Sdílet" + +msgid "IDS_IV_OPT_SLIDE_SHOW" +msgstr "Prezentace" + +msgid "IDS_IV_BODY_TIMED_COUNT" +msgstr "Násobek času" + +msgid "IDS_IV_OPT_TRIM" +msgstr "Oříznout" + +msgid "IDS_IV_BODY_UNLIMITED" +msgstr "Neomezeno" + +msgid "IDS_IV_BODY_VALIDITY" +msgstr "Platnost" + +msgid "IDS_IV_BODY_VENDOR" +msgstr "Dodavatel" + +msgid "IDS_IV_OPT_FILE_TRANSFER" +msgstr "Přenos souboru" + +msgid "IDS_IV_BODY_DO_NOT_SHOW_AGAIN" +msgstr "Znovu nezobrazovat" + +msgid "IDS_IV_BODY_TAP_AND_HOLD_AT_TWO_POINTS_THEN_TILT_DEVICE_BACK_AND_FORTH_TO_REDUCE_OR_ENLARGE_SCREEN" +msgstr "Chcete-li zmenÅ¡it nebo zvětÅ¡it displej, klepněte na dvě místa a držte je, a potom naklánějte zařízení dozadu a dopředu" + +msgid "IDS_IV_HEADER_LEARN_ABOUT_TILT" +msgstr "Informace o naklonění" + +msgid "IDS_IV_HEADER_ALL_ALBUMS" +msgstr "VÅ¡echna alba" + +msgid "IDS_IV_OPT_TAG" +msgstr "Značka" + +msgid "IDS_IV_OPT_HOME_AND_LOCK_SCREEN_WALLPAPER" +msgstr "Pozadí domovské obrazovky a zamknutého displeje" + +msgid "IDS_IV_OPT_USE_MOTION" +msgstr "Použít pohyb" + +msgid "IDS_MEDIABR_OPT_CREATE_TAG" +msgstr "Vytv. zn." + +msgid "IDS_IV_BODY_HOME_AND_LOCK_SCREENS" +msgstr "Domovská a zamknutá obrazovka" + +msgid "IDS_IV_OPT_COPY_TO_CLIPBOARD" +msgstr "Kopírovat do schránky" + +msgid "IDS_IV_BODY_CROP" +msgstr "Oříznout" + +msgid "IDS_IV_BODY_HOME_SCREEN" +msgstr "Domovská obrazovka" + +msgid "IDS_IV_BODY_LOCK_SCREEN" +msgstr "Zamknout displej" + +msgid "IDS_IV_OPT_ROTATE_LEFT" +msgstr "Otočit doleva" + +msgid "IDS_IV_OPT_ROTATE_RIGHT" +msgstr "Otočit doprava" + diff --git a/main/res/po/csv2po_v2 b/main/res/po/csv2po_v2 new file mode 100755 index 0000000000000000000000000000000000000000..d9255125385073211ea0cdb0e6cb039edbdcb2e0 GIT binary patch literal 7586 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 uu*6YPFFn(f // ug_destroy_me +#include "ivug-context.h" + +#define MAX_INSTALNCE (5) + +typedef struct +{ + ui_gadget_h ug; // ug handle + + Evas_Object *parent_win; +// EFL theme + Elm_Theme *th; + +// Window Geometry + int win_w, win_h; //size + int rot; //window rotation value ( 0~360 ) + + callback_handle_t *callback_handle; + +} AppData; + +static Eina_List *ContextList = NULL; + +Elm_Theme* +gGetSystemTheme(void) +{ + AppData *ugContext; + ugContext = eina_list_data_get(ContextList); + + IV_ASSERT(ugContext != NULL); + + return ugContext->th; +} + +void +gGetSystemDimension(int *w, int *h) +{ + AppData *ugContext; + ugContext = eina_list_data_get(ContextList); + + IV_ASSERT(ugContext != NULL); + IV_ASSERT(w != NULL); + IV_ASSERT(h != NULL); + + *w = ugContext->win_w; + *h = ugContext->win_h; +} + + +void +gSetRotationDegree(int degree) +{ + AppData *ugContext; + ugContext = eina_list_data_get(ContextList); + + IV_ASSERT(ugContext != NULL); + + ugContext->rot = degree; +} + + + +int +gGetRotationDegree(void) +{ +#if 0 + AppData *ugContext; + ugContext = eina_list_data_get(ContextList); + + IV_ASSERT(ugContext != NULL); + + return ugContext->rot; +#else + return elm_win_rotation_get(ug_get_window()); +#endif + +} + +int gGetScreenWidth() +{ + AppData *ugContext; + ugContext = eina_list_data_get(ContextList); + + IV_ASSERT(ugContext != NULL); + + return ugContext->win_w; + +} + +int gGetScreenHeight() +{ + AppData *ugContext; + ugContext = eina_list_data_get(ContextList); + + IV_ASSERT(ugContext != NULL); + + return ugContext->win_h; + +} + +ui_gadget_h +gGetUGHandle(void) +{ + AppData *ugContext; + ugContext = eina_list_data_get(ContextList); + + IV_ASSERT(ugContext != NULL); + + MSG_IMAGEVIEW_HIGH("Get ug handle = 0x%08x", ugContext->ug); + + return ugContext->ug; +} + +Evas_Object * +gGetCurrentWindow(void) +{ + AppData *ugContext; + ugContext = eina_list_data_get(ContextList); + + IV_ASSERT(ugContext != NULL); + + MSG_IMAGEVIEW_HIGH("Get ug handle = 0x%08x", ugContext->ug); + + return ugContext->parent_win; +} + +callback_handle_t * +gGetCallbackHandle(void) +{ + AppData *ugContext; + ugContext = eina_list_data_get(ContextList); + + IV_ASSERT(ugContext != NULL); + + return ugContext->callback_handle; +} + + +#define IVUG_NAVIFRAME_NAME EDJ_PATH"/ivug-naviframe.edj" +#define IVUG_TOOLBAR_NAME EDJ_PATH"/ivug-toolbar.edj" +#define IVUG_BUTTON_NAME EDJ_PATH"/ivug-button.edj" +#define IVUG_SELECTION_INFO_NAME EDJ_PATH"/ivug-selectioninfo.edj" +#define IVUG_GENLIST EDJ_PATH"/ivug-genlist.edj" +#define IVUG_GENGRID EDJ_PATH"/ivug-gengrid.edj" + +static char *edj[] = { + IVUG_NAVIFRAME_NAME, + IVUG_TOOLBAR_NAME, + IVUG_BUTTON_NAME, + IVUG_SELECTION_INFO_NAME, + IVUG_GENLIST, + IVUG_GENGRID, + NULL, +}; + +bool +ivug_context_init(ui_gadget_h ug) +{ + AppData *Context = malloc(sizeof(AppData)); + if(Context == NULL) + { + MSG_IVUG_ERROR("Cannot allock memory"); + return false; + } + + Context->ug = ug; + Context->parent_win = ug_get_window(); + + if ( Context->parent_win ) + { + Context->rot = elm_win_rotation_get(Context->parent_win); + } + else + { + MSG_IMAGEVIEW_WARN("Cannot get parent window. rotation angle set as 0"); + Context->rot = 0; + } + +//get window width, height + int w, h; + + evas_object_geometry_get(Context->parent_win, NULL, NULL, &w, &h); + MSG_IMAGEVIEW_HIGH("Screen WH(%dx%d)", w, h); +// ecore_x_window_size_get(ecore_x_window_root_first_get(), &w, &h); + Context->win_w = w; + Context->win_h = h; + + int i = 0; + + Context->th = elm_theme_new(); + + IV_ASSERT(Context->th != NULL); + + elm_theme_ref_set(Context->th, NULL); + + for ( i = 0; edj[i] != NULL; i++) + { + elm_theme_extension_add(Context->th, edj[i]); + } + + ContextList = eina_list_prepend(ContextList, Context); + + MSG_IVUG_HIGH("Append to list. Context=0x%08x", Context); + +#ifdef USE_NEW_DB_API + ivug_db_create(); +#endif + + Context->callback_handle = ivug_callback_register(); + if(Context->callback_handle == NULL) + { + MSG_IVUG_ERROR("ivug_callback_register error"); + goto ERROR; + } + + bindtextdomain(IVUG_TEXT_DOMAIN, IVUG_LOCALEDIR); //bind text domain + return TRUE; + +/**** Error routine ****/ +ERROR: + + if(Context->callback_handle) + { + ivug_callback_unregister(Context->callback_handle); + } + +#ifdef USE_NEW_DB_API + ivug_db_destroy(); +#endif + + Context = eina_list_data_get(ContextList); + ContextList = eina_list_remove_list(ContextList, ContextList); + + if(Context->th) + { + int i = 0; + for ( i = 0; edj[i] != NULL; i++) + { + elm_theme_extension_del(Context->th, edj[i]); + } + + elm_theme_free(Context->th); + } + + MSG_IVUG_HIGH("Remove from list. Context=0x%08x, ug=0x%08x", Context, Context->ug); + + free(Context); + + return false; +} + + +bool +ivug_context_deinit(ui_gadget_h ug) +{ + AppData *Context; + + Eina_List *l = NULL; + Eina_List *l_next = NULL; + + EINA_LIST_FOREACH_SAFE(ContextList, l, l_next, Context) + { + if(Context == NULL) + { + MSG_SDATA_ERROR("Context is NULL"); + return false; + } + if (Context->ug == ug) + { + ContextList = eina_list_remove_list(ContextList, l); + break; + } + } + + if(Context->callback_handle) + { + ivug_callback_unregister(Context->callback_handle); + } + +#ifdef USE_NEW_DB_API + PERF_CHECK_BEGIN(LVL2, "ivug_db_destroy"); + ivug_db_destroy(); + PERF_CHECK_END(LVL2, "ivug_db_destroy"); +#endif + + PERF_CHECK_BEGIN(LVL2, "elm_theme_free"); + if(Context->th) + { + int i = 0; + for ( i = 0; edj[i] != NULL; i++) + { + elm_theme_extension_del(Context->th, edj[i]); + } + elm_theme_free(Context->th); + } + PERF_CHECK_END(LVL2, "elm_theme_free"); + + MSG_IVUG_HIGH("Remove from list. Context=0x%08x, ug=0x%08x", Context, Context->ug); + + free(Context); + + return true; +} + + +void ivug_context_destroy_me(const char *file, int line) +{ +#if 0 + int x = 0; + int y = 0; + int w = 0; + int h = 0; + + MSG_MAIN_WARN("Apply event blocker"); + pMainView->event_blocker = evas_object_rectangle_add(evas_object_evas_get(pMainView->layout)); + evas_object_geometry_get(pMainView->layout, &x, &y, &w, &h); + evas_object_move(pMainView->event_blocker, x, y); + evas_object_resize(pMainView->event_blocker, w, h); + evas_object_color_set(pMainView->event_blocker, 0, 0, 0, 0); + evas_object_show(pMainView->event_blocker); + + if(/* It is launched by app service */) + { + MSG_MAIN_HIGH("Hide UG"); + elm_win_lower(ug_get_window()); + return; + } +#endif + AppData *ugContext; + ugContext = eina_list_data_get(ContextList); + + //IV_ASSERT(ugContext != NULL); + if (NULL != ugContext) { + + MSG_IMAGEVIEW_HIGH("Get ug handle = 0x%08x", ugContext->ug); + ug_destroy_me(ugContext->ug); + } else { + MSG_IMAGEVIEW_HIGH("ugContext is NULL."); + } + +} + + diff --git a/main/src/control/ivug-context.h b/main/src/control/ivug-context.h new file mode 100755 index 0000000..69e9270 --- /dev/null +++ b/main/src/control/ivug-context.h @@ -0,0 +1,71 @@ +/* + * Copyright 2012 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.tizenopensource.org/license + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +#ifndef __IVUG_CONTEXT_H__ +#define __IVUG_CONTEXT_H__ + +#include "ivug-common.h" +#include "ivug-callback.h" +#include + +/* + Managing context(instance) +*/ +#ifdef __cplusplus +extern "C" { +#endif + +bool +ivug_context_deinit(ui_gadget_h ug); + +bool +ivug_context_init(ui_gadget_h ug); + +void +ivug_context_destroy_me(const char *file, int line); + +#define DESTROY_ME() \ + do { \ + ivug_context_destroy_me(__FILE__, __LINE__); \ + } while(0) + +void +gSetRotationDegree(int degree); + +Elm_Theme* +gGetSystemTheme(void); + +int +gGetRotationDegree(void); + +ui_gadget_h +gGetUGHandle(void); + +Evas_Object * +gGetCurrentWindow(void); + +callback_handle_t * +gGetCallbackHandle(void); + +int gGetScreenWidth(); +int gGetScreenHeight(); + +#ifdef __cplusplus +} +#endif + +#endif //__IVUG_CONTEXT_H__ \ No newline at end of file diff --git a/main/src/control/ivug-crop-ug.cpp b/main/src/control/ivug-crop-ug.cpp new file mode 100755 index 0000000..13bcb40 --- /dev/null +++ b/main/src/control/ivug-crop-ug.cpp @@ -0,0 +1,142 @@ +/* + * Copyright 2012 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.tizenopensource.org/license + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include // ug_destroy_me, ug_send_result + +#include "ivug-crop-view.h" +#include "ivug-crop-ug.h" + +#include "ivug-debug.h" +#include "ivug-string.h" +#include "ivug-context.h" + +#undef LOG_LVL +#define LOG_LVL DBG_MSG_LVL_MED + +#undef LOG_CAT +#define LOG_CAT "IV-CROP-UG" + +static void +_send_result(ui_gadget_h ug, const char *key1, const char *val1, const char *key2, const char *val2) +{ + ivug_ret_if(!ug); + + service_h service; + service_create(&service); + + if(key1 && val1) + { + MSG_HIGH("Bundle 1 : [%s = %s]", key1, val1); + service_add_extra_data(service, key1, val1); + } + if(key2 && val2) + { + MSG_HIGH("Bundle 2 : [%s = %s]", key2, val2); + service_add_extra_data(service, key2, val2); + } + ug_send_result(gGetUGHandle(), service); + + service_destroy(service); +} + +static void _ivug_crop_view_ok_clicked_cb(void *data, Evas_Object *obj, void *event_info) +{ + char *path = (char *)event_info; + + evas_object_smart_callback_del(obj, "ok,clicked", _ivug_crop_view_ok_clicked_cb); + + _send_result(gGetUGHandle(), "crop_image_path", path, NULL, NULL); + + MSG_HIGH("Start destroy ug"); + ug_destroy_me(gGetUGHandle()); +} + +static void _ivug_crop_view_cancel_clicked_cb(void *data, Evas_Object *obj, void *event_info) +{ + //ivug_crop_ug_destroy((IvugCropUG *)data); + + evas_object_smart_callback_del(obj, "cancel,clicked", _ivug_crop_view_cancel_clicked_cb); + + _send_result(gGetUGHandle(), "crop_image_path", NULL, NULL, NULL); + + MSG_HIGH("Start destroy ug"); + ug_destroy_me(gGetUGHandle()); +} + +static void _ivug_crop_view_destroyed_cb(void *data, Evas_Object *obj, void *event_info) +{ + IvugCropUG *crop_ug = (IvugCropUG *)data; + + crop_ug->crop_view = NULL; +} + +IvugCropUG * ivug_crop_ug_create(Evas_Object *parent, int w, int h, bool bRatioFix, const char *filepath) +{ + IvugCropUG *crop_ug = (IvugCropUG *)calloc(1, sizeof(IvugCropUG)); + + IvugCropView *crop_view = NULL; + Evas_Object *layout = NULL; + + crop_view = ivug_crop_view_create(parent); + if(crop_view == NULL) + { + MSG_ERROR("ivug_crop_view_create error"); + return NULL; + } + + ivug_crop_view_box_size_set(crop_view, w, h); + ivug_crop_view_file_set(crop_view, filepath); + ivug_crop_view_box_ratio_fix(crop_view, bRatioFix); + + layout = ivug_crop_view_get_object(crop_view); + + evas_object_smart_callback_add(layout, "ok,clicked", _ivug_crop_view_ok_clicked_cb, crop_ug); + evas_object_smart_callback_add(layout, "cancel,clicked", _ivug_crop_view_cancel_clicked_cb, crop_ug); + evas_object_smart_callback_add(layout, "destroyed", _ivug_crop_view_destroyed_cb, crop_ug); + + crop_ug->crop_view = crop_view; + crop_ug->layout = layout; + crop_ug->parent = parent; + + return crop_ug; +} + +Evas_Object * ivug_crop_ug_get_layout(IvugCropUG * crop_ug) +{ + IV_ASSERT(crop_ug != NULL); + + return crop_ug->layout; +} + +bool ivug_crop_ug_destroy(IvugCropUG * crop_ug) +{ + IV_ASSERT(crop_ug != NULL); + + if(crop_ug->crop_view) + { + ivug_crop_view_destroy(crop_ug->crop_view); + crop_ug->crop_view = NULL; + } + crop_ug->layout = NULL; + + free(crop_ug); + + return true; +} + + diff --git a/main/src/control/ivug-crop-ug.h b/main/src/control/ivug-crop-ug.h new file mode 100755 index 0000000..d1921a1 --- /dev/null +++ b/main/src/control/ivug-crop-ug.h @@ -0,0 +1,44 @@ +/* + * Copyright 2012 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.tizenopensource.org/license + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __IVUG_CROP_UG_H__ +#define __IVUG_CROP_UG_H__ + +#include "ivug-crop-view.h" + +typedef struct { + IvugCropView *crop_view; + Evas_Object *layout; + Evas_Object *parent; +} IvugCropUG; + +#ifdef __cplusplus +extern "C" { +#endif + +IvugCropUG * ivug_crop_ug_create(Evas_Object *parent, int w, int h, bool bRatioFix, const char *filepath); + +Evas_Object * ivug_crop_ug_get_layout(IvugCropUG * crop_ug); + +bool ivug_crop_ug_destroy(IvugCropUG * crop_ug); + + +#ifdef __cplusplus +} +#endif + +#endif // __IVUG_CROP_UG_H__ + diff --git a/main/src/control/ivug-detail-info.c b/main/src/control/ivug-detail-info.c new file mode 100755 index 0000000..d6f7f9f --- /dev/null +++ b/main/src/control/ivug-detail-info.c @@ -0,0 +1,703 @@ +/* + * Copyright 2012 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.tizenopensource.org/license + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "ivug-detail-info.h" + +#include +#include + +#include + +#include + +#include + +#include +#include +#include +#include +#include +#include + +#include "ivug-details-view.h" +#include + +#include "ivug-drm.h" +#include "ivug-file-info.h" + +#define NOMAL_BUF 128 + +#define DETAILS_DIR_PATH_LEN_MAX 4096 + +enum IVUG_SIZE_TYPE +{ + SIZE_BYTE = 0, + SIZE_KB, + SIZE_MB, + SIZE_GB +}; + +/* + Shuld free returned value after use +*/ +static char* +_get_icu_time_string(const char *locale, const char *customSkeleton, const char *timezone, UDate date) +{ +#define UG_ICU_ARR_LENGTH 256 + + IV_ASSERT(customSkeleton != NULL); + IV_ASSERT(timezone != NULL); + + /* + Copy a byte string encoded in the default codepage to a ustring. + Copies at most n characters. The result will be null terminated if the length of src is less than n. Performs a host byte to UChar conversion + */ + UChar ucustomSkeleton[UG_ICU_ARR_LENGTH] = {0,}; + + if(u_uastrncpy(ucustomSkeleton, customSkeleton, UG_ICU_ARR_LENGTH) == NULL) + { + MSG_UTIL_ERROR("u_uastrncpy() error."); + return NULL; + } + + UChar utimezone[UG_ICU_ARR_LENGTH] = {0,}; + + if ( u_uastrncpy(utimezone, timezone, UG_ICU_ARR_LENGTH) == NULL ) + { + MSG_UTIL_ERROR("u_uastrncpy() error."); + return NULL; + } + + UErrorCode status = U_ZERO_ERROR; + UDateTimePatternGenerator *generator; + UDateFormat *formatter; + + UChar bestPattern[UG_ICU_ARR_LENGTH] = {0,}; + UChar formatted[UG_ICU_ARR_LENGTH] = {0,}; + char formattedString[UG_ICU_ARR_LENGTH] = {0,}; + int32_t bestPatternLength, formattedLength; + + ucal_setDefaultTimeZone(utimezone , &status); + + if (U_FAILURE(status)) + { + MSG_UTIL_ERROR("ucal_setDefaultTimeZone() is failed"); + return NULL; + } + + uloc_setDefault(getenv("LC_TIME"), &status); + + if (U_FAILURE(status)) + { + MSG_UTIL_ERROR("ucal_setDefaultTimeZone() is failed"); + return NULL; + } + + generator = udatpg_open(locale, &status); + if(generator == NULL) + { + return NULL; + } + + bestPatternLength = udatpg_getBestPattern(generator, ucustomSkeleton, u_strlen(ucustomSkeleton), bestPattern, UG_ICU_ARR_LENGTH, &status); + if(bestPatternLength <= 0) + { + return NULL; + } + + formatter = udat_open(UDAT_IGNORE, UDAT_IGNORE, locale, NULL, -1, bestPattern, -1, &status); + if(formatter == 0) + { + return NULL; + } + + formattedLength = udat_format(formatter, date, formatted, UG_ICU_ARR_LENGTH, NULL, &status); + if(formattedLength <= 0) + { + return NULL; + } + + u_austrcpy(formattedString, formatted); + udatpg_close(generator); + udat_close(formatter); + + if(strlen(formattedString) == 0) + { + return NULL; + } + + return strdup(formattedString); +} + + +/* + Should free returned value after use +*/ +static char * +_get_drm_availabile_string(drm_permission_type_e permissionType) +{ + switch(permissionType) + { + case DRM_PERMISSION_TYPE_ANY: + return strdup(IDS_ANY); + break; + + case DRM_PERMISSION_TYPE_PLAY: + return strdup(IDS_PLAY); + break; + + case DRM_PERMISSION_TYPE_COLLABORATIVE_PLAY: + return strdup(IDS_COLLABORATIVE_PLAY); + break; + + case DRM_PERMISSION_TYPE_DISPLAY: + return strdup(IDS_DISPLAY); + break; + + case DRM_PERMISSION_TYPE_EXECUTE: + return strdup(IDS_EXECUTE); + break; + + case DRM_PERMISSION_TYPE_PRINT: + return strdup(IDS_PRINT); + break; + + case DRM_PERMISSION_TYPE_EXPORT_COPY: + return strdup(IDS_COPY); + break; + + case DRM_PERMISSION_TYPE_EXPORT_MOVE: + return strdup(IDS_MOVE); + break; + + default: + return strdup(IDS_N_A); + break; + + } +} + +static char* +_get_icu_date(time_t mtime) +{ +#define UG_DATE_FORMAT_12 "yMMMdhms" +#define UG_DATE_FORMAT_24 "yMMMdHms" + + char* skeleton = NULL; + + bool hours_24 = false; + int ret = -1; + + ret = runtime_info_get_value_bool(RUNTIME_INFO_KEY_24HOUR_CLOCK_FORMAT_ENABLED, &hours_24); + if(ret != RUNTIME_INFO_ERROR_NONE) + { + MSG_DETAIL_ERROR("Cannot get 24 hours format"); + return NULL; + } + + if(hours_24 == true) + { + skeleton = UG_DATE_FORMAT_24; + } + else + { + skeleton = UG_DATE_FORMAT_12; + } + + char *locale = vconf_get_str(VCONFKEY_REGIONFORMAT); /* eg. en_US.UTF-8*/ + if(locale == NULL) + { + MSG_DETAIL_ERROR("Cannot get region format."); + locale = "en_US.UTF-8"; // Default value. + } + + char *timezone = NULL; + + timezone = vconf_get_str(VCONFKEY_SETAPPL_TIMEZONE_ID); // eg Asia/Seoul + if(timezone == NULL) + { +// TODO : How to get default time zone???? + MSG_DETAIL_ERROR("Cannot get time zone"); + return NULL; + } + + MSG_DETAIL_HIGH("Locale:%s TimeZone:%s TimeFormat:%s", locale, skeleton, timezone); + + char* datestr = NULL; + + datestr = _get_icu_time_string(locale, skeleton, timezone, (UDate)mtime * 1000); + + if(datestr == NULL) + { + MSG_DETAIL_ERROR("Cannot get time string"); + return NULL; + } + + MSG_DETAIL_HIGH("ICU Date : %s", datestr); + return datestr; + +} + +static char * +_get_filesize_string(size_t size) +{ +#define FILE_SIZE_LEN_MAX 64 + + MSG_DETAIL_HIGH("Entered size = %d", size); + + char *tmp = (char *)calloc(1, sizeof(char)*(FILE_SIZE_LEN_MAX+1)); + if (tmp == NULL) + { + return NULL; + } + + if(size > (1<<30)) // GB + { + snprintf(tmp,FILE_SIZE_LEN_MAX,"%.1f GB", (double)size/(1<<30)); + } + else if(size > (1<<20)) // MB + { + snprintf(tmp,FILE_SIZE_LEN_MAX,"%.1f MB", (double)size/(1<<20)); + } + else if(size > (1<<10)) // KB + { + snprintf(tmp,FILE_SIZE_LEN_MAX,"%zu KB", size/(1<<10)); + } + else // Byte + { + snprintf(tmp,FILE_SIZE_LEN_MAX,"%zu B", size); + } + + MSG_DETAIL_HIGH("Result Size = %s", tmp); + return tmp; +} + +void +ivug_details_info_set_file_information(ivug_file_info_t * const pFileInfo, const char *path) +{ + ivug_ret_if( NULL == pFileInfo ); + ivug_ret_if( NULL == path ); + +/*** get file path*/ + pFileInfo->filepath = strdup(path); + + struct stat statbuf; + + if(stat(path,&statbuf) == -1) + { + MSG_DETAIL_ERROR("Cannot get stat()"); + return ; + } + + pFileInfo->size = statbuf.st_size; + pFileInfo->date = statbuf.st_mtime; + + pFileInfo->create_date = _get_icu_date(pFileInfo->date); + + if ( pFileInfo->create_date == NULL ) + { + pFileInfo->create_date = strdup(IDS_N_A); + } + + pFileInfo->file_ext = ivug_fileinfo_get_file_extension(path); + + if ( pFileInfo->file_ext == NULL ) + { + pFileInfo->file_ext = strdup(IDS_UNKNOWN); + } + + pFileInfo->filesize = _get_filesize_string(pFileInfo->size); + + MSG_DETAIL_HIGH("Basic Info : ext=%s size=%s", pFileInfo->file_ext, pFileInfo->filesize); + + return ; + +} + + +void +ivug_details_info_set_gps_info(ivug_file_info_t * const pFileInfo, const char *path) +{ +#define UG_EXIF_ARR_LENGTH 255 + + ivug_retm_if(!pFileInfo, "data is NULL"); + ivug_retm_if(!path, "path is NULL"); + + pFileInfo->longitude = calloc(1, sizeof(char)*UG_EXIF_ARR_LENGTH); + if(pFileInfo->longitude == NULL) + { + return; + } + + pFileInfo->latitude = calloc(1, sizeof(char)*UG_EXIF_ARR_LENGTH); + if(pFileInfo->latitude == NULL) + { + return; + } + + + double longtitude = 0.0; + double latitude = 0.0; + + bool bret = false; + + if(pFileInfo->file_type == IVUG_DETAIL_IMAGE_TYPE) // this will be removed!!!! + { + bret = ivug_fileinfo_get_image_gps_info(path, &latitude, &longtitude); + } + else if(pFileInfo->file_type == IVUG_DETAIL_VIDEO_TYPE) + { + bret = ivug_fileinfo_get_video_gps_info(path, &latitude, &longtitude); + } + + if ( bret == false) + { + latitude = 0; + longtitude = 0; + } + + if(latitude != 0.0) + { + snprintf(pFileInfo->latitude, UG_EXIF_ARR_LENGTH, "%.5f", latitude); + } + else + { + snprintf(pFileInfo->latitude, UG_EXIF_ARR_LENGTH, "%s", IDS_UNKNOWN); + } + if(longtitude != 0.0) + { + snprintf(pFileInfo->longitude, UG_EXIF_ARR_LENGTH, "%.5f", longtitude); + } + else + { + snprintf(pFileInfo->longitude, UG_EXIF_ARR_LENGTH, "%s", IDS_UNKNOWN); + } +} + +void +ivug_details_info_set_resolution(ivug_file_info_t * const pFileInfo, const char *path, int stype) +{ + ivug_retm_if(!pFileInfo, "data is NULL"); + ivug_retm_if(!path, "path is NULL"); + + MSG_DETAIL_HIGH("slide type is %d", stype); + + pFileInfo->resolution = (char *)malloc(sizeof(char)*NOMAL_BUF+1); + if(pFileInfo->resolution == NULL) + { + return ; + } + memset(pFileInfo->resolution,0,(sizeof(char)* NOMAL_BUF + 1)); + + + int width, height; + + switch(stype) + { + /*Image type && !drm*/ + case SLIDE_TYPE_IMAGE: + pFileInfo->file_type = IVUG_DETAIL_IMAGE_TYPE; + + if ( ivug_fileinfo_get_image_resolution(path, &width, &height) == false) + { + snprintf(pFileInfo->resolution, NOMAL_BUF, "%s", IDS_N_A); + } + else + { + snprintf(pFileInfo->resolution, NOMAL_BUF,"%dX%d", width, height); + } + + break; + + /* Video type */ + case SLIDE_TYPE_VIDEO: + pFileInfo->file_type = IVUG_DETAIL_VIDEO_TYPE; + + if ( ivug_fileinfo_get_video_resolution(path, &width, &height) == false) + { + snprintf(pFileInfo->resolution, NOMAL_BUF, "%s", IDS_N_A); + } + else + { + snprintf(pFileInfo->resolution, NOMAL_BUF,"%dX%d", width, height); + } + + + break; + + case SLIDE_TYPE_STREAMING: + pFileInfo->file_type = IVUG_DETAIL_VIDEO_TYPE; + break; + + default: + break; + + } + +} + +void +ivug_details_info_set_location(ivug_file_info_t * const pFileInfo, const char *path) +{ + ivug_retm_if(!pFileInfo, "data is NULL"); + ivug_retm_if(!path, "path is NULL"); + + pFileInfo->file_location = strdup(path); +} + +void +ivug_details_info_set_filename(ivug_file_info_t * const pFileInfo, const char *path) +{ + ivug_retm_if(!pFileInfo, "data is NULL"); + ivug_retm_if(!path, "path is NULL"); + + /** get file name */ + pFileInfo->filename = ecore_file_strip_ext(ecore_file_file_get(path)); +} + +void _add_string(char *org, char *add_string) +{ + char *string = strdup(add_string); + if(org == NULL) + { + org = string; + } + else + { + org = g_strconcat(org, "/", string, NULL); + free(string); + } +} + +void +ivug_details_info_set_drm_info(ivug_file_info_t * const pFileInfo, const char *path) +{ +#define VALIDITY_SIZE 80 + +#define MOUNTH_COUNT 12 //used for drm file info, +#define DAY_COUNT 30 +#define HOUR_COUNT 24 +#define SECOND_COUNT 3600.0 + + ivug_retm_if(!pFileInfo, "data is NULL"); + ivug_retm_if(!path, "path is NULL"); + + pFileInfo->vendor = NULL; + pFileInfo->forwarding = NULL; + pFileInfo->available_uses = NULL; + pFileInfo->type = NULL; + + bool valid_ro = false; + + valid_ro = ivug_drm_has_valid_ro(path); + + if(false == valid_ro) + { + MSG_DETAIL_WARN("%s is not valid right object", path); + return ; + } + +// Get Vendor + pFileInfo->vendor = ivug_drm_get_drm_vendor_info(path); + + if ( pFileInfo->vendor == NULL ) + { + // Set default value. + pFileInfo->vendor = strdup(IDS_UNKNOWN); + } + +// Get forwarding + if ( ivug_drm_get_forwarding_info(path) == true ) + { + pFileInfo->forwarding = strdup(IDS_POSSIBLE); + } + else + { + pFileInfo->forwarding = strdup(IDS_IMPOSSIBLE); + } + +// Get Validity/Type/Available + + drm_constraint_info_s constraint_info; + int ret = -1; + int i = -1; + char *string = NULL; + char validity[VALIDITY_SIZE] = ""; + + for(i=DRM_PERMISSION_TYPE_NONE; i<=DRM_PERMISSION_TYPE_EXPORT_MOVE; i++) + { + memset(&constraint_info, 0x0, sizeof(drm_constraint_info_s)); + + ret = drm_get_constraint_info(path, i, &constraint_info); + if(ret != DRM_RETURN_SUCCESS) + { + MSG_IVUG_ERROR("drm_get_constraint_info Failed!!, perm_type=%d ret=0x%x", i, ret); + continue; + } + + string = _get_drm_availabile_string(i); + _add_string(pFileInfo->available_uses, string); + free(string); + + if(constraint_info.const_type.is_unlimited) + { + MSG_IVUG_HIGH("Unlimited:for permission=%d", i); + + _add_string(pFileInfo->type, IDS_UNLIMITED); + _add_string(pFileInfo->validity, IDS_UNLIMITED); + } + + if(constraint_info.const_type.is_accumulated){ + MSG_IVUG_HIGH("Accumulated Constraint is present"); + MSG_IVUG_HIGH("accumulated_original_seconds=%d", + constraint_info.accumulated_original_seconds); + MSG_IVUG_HIGH("accumulated_remaining_seconds=%d", + constraint_info.accumulated_remaining_seconds); + + _add_string(pFileInfo->type, IDS_ACCUMULATED_TIME); + snprintf(validity, sizeof(validity),"Total %.1f hours", + constraint_info.accumulated_remaining_seconds/SECOND_COUNT); + _add_string(pFileInfo->validity, validity); + } + + if(constraint_info.const_type.is_count){ + MSG_IVUG_HIGH("Count Constraint is present"); + MSG_IVUG_HIGH("original_count=%d", + constraint_info.original_count); + MSG_IVUG_HIGH("remaining_count=%d", + constraint_info.remaining_count); + + _add_string(pFileInfo->type, IDS_COUNT); + snprintf(validity, sizeof(validity),"%d left", constraint_info.remaining_count); + _add_string(pFileInfo->validity, validity); + } + + if(constraint_info.const_type.is_datetime){ + MSG_IVUG_HIGH("DATETIME Constraint is present"); + MSG_IVUG_HIGH("start_time:" + "Year=%d,Month=%d,Day=%d,Hour=%d, minute=%d, Second=%d", + constraint_info.start_time.tm_year, + constraint_info.start_time.tm_mon, + constraint_info.start_time.tm_mday, + constraint_info.start_time.tm_hour, + constraint_info.start_time.tm_min, + constraint_info.start_time.tm_sec); + + MSG_IVUG_HIGH("end_time:" + "Year=%d,Month=%d,Day=%d,Hour=%d, minute=%d, Second=%d", + constraint_info.end_time.tm_year, + constraint_info.end_time.tm_mon, + constraint_info.end_time.tm_mday, + constraint_info.end_time.tm_hour, + constraint_info.end_time.tm_min, + constraint_info.end_time.tm_sec); + + _add_string(pFileInfo->type, IDS_TIME); + snprintf(validity, sizeof(validity),"%d.%d.%d %d:%d ~ %d.%d.%d %d:%d:%d", + constraint_info.start_time.tm_mday, + constraint_info.start_time.tm_mon, + constraint_info.start_time.tm_year, + constraint_info.start_time.tm_hour, + constraint_info.start_time.tm_sec, + constraint_info.end_time.tm_mday, + constraint_info.end_time.tm_mon, + constraint_info.end_time.tm_year, + constraint_info.end_time.tm_hour, + constraint_info.end_time.tm_min, + constraint_info.end_time.tm_sec + ); + _add_string(pFileInfo->validity, validity); + } + + if(constraint_info.const_type.is_individual){ + MSG_IVUG_HIGH("INDIVIDUAL Constraint is present"); + MSG_IVUG_HIGH("individual_identity_type=%d " + "individual_id=%s", + constraint_info.individual_identity_type, + constraint_info.individual_id); + + _add_string(pFileInfo->type, IDS_INDIVIDUAL); + _add_string(pFileInfo->validity, IDS_INDIVIDUAL); + } + + if(constraint_info.const_type.is_interval){ + MSG_IVUG_HIGH("INTERVAL Constraint is present"); + MSG_IVUG_HIGH("interval_time:" + "Year=%d,Month=%d,Day=%d,Hour=%d, minute=%d, Second=%d", + constraint_info.interval_time.tm_year, + constraint_info.interval_time.tm_mon, + constraint_info.interval_time.tm_mday, + constraint_info.interval_time.tm_hour, + constraint_info.interval_time.tm_min, + constraint_info.interval_time.tm_sec); + + _add_string(pFileInfo->type, IDS_INTERVAL); + if(constraint_info.interval_time.tm_year == 0 + && constraint_info.interval_time.tm_mon == 0 + && constraint_info.interval_time.tm_mday == 0 + && constraint_info.interval_time.tm_hour == 0) + { + snprintf(validity, sizeof(validity),"Total %d miniutes", constraint_info.interval_time.tm_min); + } + else + { + snprintf(validity, sizeof(validity),"Total %d hours", + ((constraint_info.interval_time.tm_year*MOUNTH_COUNT + + constraint_info.interval_time.tm_mon)*DAY_COUNT + + constraint_info.interval_time.tm_mday)*HOUR_COUNT + + constraint_info.interval_time.tm_hour + ); + } + _add_string(pFileInfo->validity, validity); + } + + if(constraint_info.const_type.is_system){ + MSG_IVUG_HIGH("SYSTEM Constraint is present"); + MSG_IVUG_HIGH("system_identity_type=%d " + "system_id=%s", + constraint_info.system_identity_type, + constraint_info.system_id); + + _add_string(pFileInfo->type, IDS_SYSTEM); + _add_string(pFileInfo->validity, IDS_SYSTEM); + } + + if(constraint_info.const_type.is_timedcount){ + MSG_IVUG_HIGH("TIMED-COUNT Constraint is present"); + MSG_IVUG_HIGH("timed_original_count=%d", + constraint_info.timed_original_count); + + MSG_IVUG_HIGH("timed_remaining_count=%d", + constraint_info.timed_remaining_count); + + MSG_IVUG_HIGH("timed_count_timer=%d", + constraint_info.timed_count_timer); + + _add_string(pFileInfo->type, IDS_TIMED_COUNT); + snprintf(validity, sizeof(validity),"%d (%d sec)", + constraint_info.timed_remaining_count, + constraint_info.timed_count_timer + ); + _add_string(pFileInfo->validity, validity); + } + + MSG_IVUG_WARN("Undefined constraints"); + } + + return; +} + + diff --git a/main/src/control/ivug-detail-info.h b/main/src/control/ivug-detail-info.h new file mode 100755 index 0000000..b98f14b --- /dev/null +++ b/main/src/control/ivug-detail-info.h @@ -0,0 +1,85 @@ +/* + * Copyright 2012 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.tizenopensource.org/license + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __IVUG_DETAIL_COMMON_H__ +#define __IVUG_DETAIL_COMMON_H__ + +#include + +#include "ivug-common.h" +#include "ivug-drm.h" + +typedef enum { + IVUG_DETAIL_ERROR_TYPE = -1, + IVUG_DETAIL_IMAGE_TYPE, + IVUG_DETAIL_VIDEO_TYPE +} ivug_detail_file_t; + +typedef struct { +/** Common info*/ + time_t date; // Seconds since 1970-1-1 + size_t size; + + ivug_detail_file_t file_type; + + char *filesize; + char *filepath; + char *filename; + char *file_ext; + char *file_location; + char *contains; + char *create_date; + +/**resolution */ + char *resolution; + +/**Gps info */ + char *latitude; + char *longitude; + +/** Drm info */ + char *vendor; + char *forwarding; + char *available_uses; + char *type; + char *validity; +}ivug_file_info_t; + +#ifdef __cplusplus +extern "C" { +#endif + +// TODO : Remove dependacy ivug-detail-view and ivug-detail-info. + +void ivug_details_info_set_file_information(ivug_file_info_t * const pFileInfo, const char *path); + +void ivug_details_info_set_gps_info(ivug_file_info_t * const pFileInfo, const char *path); + +void ivug_details_info_set_resolution(ivug_file_info_t * const pFileInfo, const char *path, int stype); + +void ivug_details_info_set_location(ivug_file_info_t * const pFileInfo, const char *path); + +void ivug_details_info_set_filename(ivug_file_info_t * const pFileInfo, const char *path); + +void ivug_details_info_set_drm_info(ivug_file_info_t * const pFileInfo,const char *path); + +#ifdef __cplusplus +} +#endif + + +#endif // __IVUG_DETAIL_COMMON_H__ + diff --git a/main/src/control/ivug-filter.c b/main/src/control/ivug-filter.c new file mode 100755 index 0000000..56e08f7 --- /dev/null +++ b/main/src/control/ivug-filter.c @@ -0,0 +1,161 @@ +/* + * Copyright 2012 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.tizenopensource.org/license + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "ivug-datatypes.h" +#include "ivug-filter.h" + +#include + +#include "ivug-debug.h" +#include "ivug-uuid.h" +#include "ivug-util.h" +#include "ivug-context.h" + +Filter_struct *ivug_data_filter_create(const ivug_parameter *param) +{ + IV_ASSERT(param != NULL); + + Filter_struct *filter_str = calloc(1, sizeof(Filter_struct)); + IV_ASSERT(filter_str != NULL); + + filter_str->type = FILTER_DB; + + filter_str->view_by = param->view_by; + filter_str->media_type = param->media_type; + filter_str->sort_type = param->sort_type; + filter_str->index = param->start_index; + + DB_Filter *filter = calloc(1, sizeof(DB_Filter)); + + IV_ASSERT(filter != NULL); + + MSG_SDATA_HIGH("param->view_by is %d", param->view_by); + switch(param->view_by) + { + case IVUG_VIEW_BY_PLACES: + filter->place.max_longitude = param->max_longitude; + filter->place.min_longitude = param->min_longitude; + filter->place.max_latitude = param->max_latitude; + filter->place.min_latitude = param->min_latitude; + break; + + case IVUG_VIEW_BY_FILE: + filter->file_path = strdup(param->filepath); + break; + case IVUG_VIEW_BY_ALL: + filter->album_id = uuid_assign(param->album_id); + break; + case IVUG_VIEW_BY_FOLDER: + filter->album_id = uuid_assign(param->album_id); + break; + case IVUG_VIEW_BY_INVAILD: + default: + MSG_SDATA_WARN("Invalid ViewBy : %d", param->view_by); + break; + + } + + filter_str->db_filter = filter; + + return filter_str; + +} + +void ivug_data_filter_delete(Filter_struct *filter_str) +{ + IV_ASSERT(filter_str != NULL); + + MSG_SDATA_HIGH("Removing filter struct. Type=%d", filter_str->type); + + if(filter_str->type == FILTER_DB) + { + DB_Filter *filter = filter_str->db_filter; + switch(filter_str->view_by) + { + case IVUG_VIEW_BY_PLACES: + break; + case IVUG_VIEW_BY_FILE: + if ( filter->file_path ) + { + free(filter->file_path); + } + break; + case IVUG_VIEW_BY_ALL: + uuid_free(filter->album_id); + break; + + case IVUG_VIEW_BY_FOLDER: + uuid_free(filter->album_id); + break; + + case IVUG_VIEW_BY_INVAILD: + default: + MSG_SDATA_WARN("Invalid ViewBy : %d", filter_str->view_by); + break; + } + free(filter); + } + free(filter_str); +} + + +Filter_struct *ivug_data_filter_copy(const Filter_struct *filter_str) +{ + IV_ASSERT(filter_str != NULL); + Filter_struct *cFilter_str = malloc(sizeof(Filter_struct)); + IV_ASSERT(cFilter_str != NULL); + + memcpy(cFilter_str, filter_str, sizeof(Filter_struct)); + + if(filter_str->type == FILTER_DB) + { + DB_Filter *filter = filter_str->db_filter; + DB_Filter *cFilter = malloc(sizeof(DB_Filter)); + memcpy(cFilter, filter, sizeof(DB_Filter)); + + switch(filter_str->view_by) + { + case IVUG_VIEW_BY_PLACES: + break; + + case IVUG_VIEW_BY_FILE: + cFilter->file_path = strdup( filter->file_path ); + + if ( filter->file_path ) + { + free(filter->file_path); + } + break; + + case IVUG_VIEW_BY_ALL: + cFilter->album_id = uuid_assign( filter->album_id ); + break; + + case IVUG_VIEW_BY_FOLDER: + cFilter->album_id = uuid_assign( filter->album_id ); + break; + + case IVUG_VIEW_BY_INVAILD: + default: + MSG_SDATA_WARN("Invalid ViewBy : %d", filter_str->view_by); + break; + } + + cFilter_str->db_filter = cFilter; + } + return cFilter_str; +} + diff --git a/main/src/control/ivug-filter.h b/main/src/control/ivug-filter.h new file mode 100755 index 0000000..482740d --- /dev/null +++ b/main/src/control/ivug-filter.h @@ -0,0 +1,41 @@ +/* + * Copyright 2012 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.tizenopensource.org/license + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __IVUG_FILTER_H__ +#define __IVUG_FILTER_H__ + +#include "ivug-parameter.h" +#include "ivug-medialist.h" +#include + + +#ifdef __cplusplus +extern "C" { +#endif + +Filter_struct *ivug_data_filter_create(const ivug_parameter *param); + +Filter_struct *ivug_data_filter_copy(const Filter_struct *filter); + +void ivug_data_filter_delete(Filter_struct *filter); + +#ifdef __cplusplus +} +#endif + + +#endif // __IVUG_FILTER_H__ + diff --git a/main/src/control/ivug-popup.c b/main/src/control/ivug-popup.c new file mode 100755 index 0000000..78c9d5e --- /dev/null +++ b/main/src/control/ivug-popup.c @@ -0,0 +1,643 @@ +/* + * Copyright 2012 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.tizenopensource.org/license + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "ivug-popup.h" +#include "ivug-vibration.h" + +#define NOTIFY_TIMEOUT 3.0 + +#define IVUG_POPUP_EDJ_NAME EDJ_PATH"/ivug-popup.edj" + +typedef struct _Ivug_Popup +{ + Evas_Object *parent; + Evas_Object *popup; + Evas_Object *layout; + + Evas_Object *obj; + + int selected_index; + + Popup_Response response; + + int haptic_handle; + + Evas_Smart_Cb callback; + void *data; + +}Ivug_Popup; + +typedef struct +{ + int index; + char *name; + Evas_Object *radio_main; + Ivug_Popup *p_iv_popup; +} ivug_radio_popup_item; + +static Ivug_Popup * ivug_popup_create() +{ + Ivug_Popup *iv_popup = calloc(1, sizeof(Ivug_Popup)); + + iv_popup->haptic_handle = INVALID_HAPTIC_HANDLE; + + return iv_popup; +} + +static void ivug_popup_delete(Ivug_Popup *iv_popup) +{ + if ( iv_popup->haptic_handle != INVALID_HAPTIC_HANDLE ) + { + ivug_vibration_stop(iv_popup->haptic_handle); + ivug_vibration_delete(iv_popup->haptic_handle); + + iv_popup->haptic_handle = INVALID_HAPTIC_HANDLE; + } + + if(iv_popup->popup) + { + evas_object_del(iv_popup->popup); + iv_popup->popup = NULL; + } + + if(iv_popup->layout) + { + evas_object_del(iv_popup->layout); + iv_popup->layout = NULL; + } + + free(iv_popup); +} + +static void _on_popup_response(void *data, Evas_Object *obj, void *event_info ) +{ + IV_ASSERT(data != NULL); + + Ivug_Popup *iv_popup = (Ivug_Popup *)data; + Popup_Response response = (Popup_Response)evas_object_data_get(obj, "response"); + MSG_IMAGEVIEW_HIGH("response callback=%d", response); + + if(iv_popup->callback) + { + iv_popup->callback(iv_popup->data, iv_popup->popup, (void *)response); + } + + ivug_popup_delete(iv_popup); +} + + +static void _on_ctxpopup_dismissed( void *data, Evas_Object *obj, void *event_info ) +{ +// Triggered when clicked outside ctxpopup + MSG_IMAGEVIEW_HIGH("Dismissed response"); + + Ivug_Popup *iv_popup = (Ivug_Popup *)data; + + ivug_popup_delete(iv_popup); +} + +Evas_Object* +ivug_deletepopup_show(Evas_Object* parent, const char* title, + const char* contents, Evas_Smart_Cb response, void* user_data) +{ + Evas_Object *popup; + Evas_Object *btn_delete; + Evas_Object *btn_cancel; + //create popup + + IV_ASSERT(response != NULL); + + Ivug_Popup *iv_popup = ivug_popup_create(); + + popup = elm_popup_add(parent); + evas_object_size_hint_weight_set(popup, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + elm_object_text_set(popup, contents); + elm_object_part_text_set(popup, "title,text", title); + + btn_delete = elm_button_add(popup); + elm_object_style_set(btn_delete, "popup_button/default"); + elm_object_text_set(btn_delete, IDS_DELETE); + elm_object_part_content_set(popup, "button1", btn_delete); + evas_object_data_set(btn_delete, "response", (void *)POPUP_RESPONSE_OK); + evas_object_smart_callback_add(btn_delete, "clicked", _on_popup_response, iv_popup); + + btn_cancel = elm_button_add(popup); + elm_object_style_set(btn_cancel, "popup_button/default"); + elm_object_text_set(btn_cancel, IDS_CANCEL); + elm_object_part_content_set(popup, "button2", btn_cancel); + evas_object_data_set(btn_cancel, "response", (void *)POPUP_RESPONSE_CANCEL); + evas_object_smart_callback_add(btn_cancel, "clicked", _on_popup_response, iv_popup); + + iv_popup->popup = popup; + iv_popup->callback = response; + iv_popup->data = user_data; + + evas_object_show(popup); + + return popup; +} + + +Evas_Object* +ivug_2btn_popup_show(Evas_Object* parent, const char* title, + const char* contents, Evas_Smart_Cb response, void* user_data) +{ + IV_ASSERT(response != NULL); + + Ivug_Popup *iv_popup = ivug_popup_create(); + + Evas_Object *popup; + Evas_Object *btn_yes; + Evas_Object *btn_no; + //create popup + + popup = elm_popup_add(parent); + evas_object_size_hint_weight_set(popup, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + elm_object_text_set(popup, contents); + if(title) + { + elm_object_part_text_set(popup, "title,text", title); + } + + btn_yes = elm_button_add(popup); + elm_object_style_set(btn_yes, "popup_button/default"); + elm_object_text_set(btn_yes, IDS_YES); + elm_object_part_content_set(popup, "button1", btn_yes); + evas_object_data_set(btn_yes, "response", (void *)POPUP_RESPONSE_OK); + evas_object_smart_callback_add(btn_yes, "clicked", _on_popup_response, iv_popup); + + btn_no = elm_button_add(popup); + elm_object_style_set(btn_no, "popup_button/default"); + elm_object_text_set(btn_no, IDS_NO); + elm_object_part_content_set(popup, "button2", btn_no); + evas_object_data_set(btn_no, "response", (void *)POPUP_RESPONSE_CANCEL); + evas_object_smart_callback_add(btn_no, "clicked", _on_popup_response, iv_popup); + + iv_popup->popup = popup; + iv_popup->callback = response; + iv_popup->data = user_data; + + evas_object_show(popup); + evas_object_layer_set(popup, EVAS_LAYER_MAX); + + return popup; +} + +Evas_Object* +ivug_1btn_popup_show(Evas_Object* parent, const char* title, + const char* contents, Evas_Smart_Cb response, void* user_data) +{ + IV_ASSERT(response != NULL); + + Ivug_Popup *iv_popup = ivug_popup_create(); + + Evas_Object *popup; + Evas_Object *btn_yes; + //create popup + + popup = elm_popup_add(parent); + evas_object_size_hint_weight_set(popup, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + elm_object_text_set(popup, contents); + if(title) + { + elm_object_part_text_set(popup, "title,text", title); + } + + btn_yes = elm_button_add(popup); + elm_object_style_set(btn_yes, "popup_button/default"); + elm_object_text_set(btn_yes, IDS_OK); + elm_object_part_content_set(popup, "button1", btn_yes); + evas_object_data_set(btn_yes, "response", (void *)POPUP_RESPONSE_OK); + evas_object_smart_callback_add(btn_yes, "clicked", _on_popup_response, iv_popup); + + iv_popup->popup = popup; + iv_popup->callback = response; + iv_popup->data = user_data; + + evas_object_show(popup); + evas_object_layer_set(popup, EVAS_LAYER_MAX); + + return popup; +} + +static void _on_longpress_popup_selected(void *data, Evas_Object *obj, void *event_info) +{ + IV_ASSERT(data != NULL); + + Ivug_Popup *iv_popup = (Ivug_Popup *)data; + + const char *label = elm_object_item_text_get((Elm_Object_Item *)event_info); + if(label == NULL) + { + MSG_MAIN_ERROR("label is NULL"); + ivug_popup_delete(iv_popup); + return; + } + MSG_MAIN_HIGH("text(%s) is clicked", label); + + Longpress_Popup_Response response = LPPOPUP_RESPONSE_NONE; + if(strncmp(label, IDS_COPY, strlen(label)) == 0) + { + response = LPPOPUP_RESPONSE_COPY; + } + else + { + MSG_MAIN_WARN("Unknown Share type : %s", label); + } + MSG_MAIN_HIGH("response=%d", response); + + if(iv_popup->callback) + { + iv_popup->callback(iv_popup->data, iv_popup->popup, (void *)response); + } + + ivug_popup_delete(iv_popup); +} + +Evas_Object* +ivug_longpress_popup_show(Evas_Object *parent, int x, int y, Evas_Smart_Cb response, void *data) +{ + Ivug_Popup *iv_popup = ivug_popup_create(); + + Evas_Object* ctx_popup = NULL; + + ctx_popup = elm_ctxpopup_add(parent); + + elm_ctxpopup_item_append(ctx_popup, IDS_COPY, NULL, _on_longpress_popup_selected, iv_popup); + + evas_object_smart_callback_add(ctx_popup, "dismissed", _on_ctxpopup_dismissed, iv_popup); + + evas_object_move(ctx_popup, x, y); + + iv_popup->popup = ctx_popup; + iv_popup->callback = response; + iv_popup->data = data; + + evas_object_show(ctx_popup); + + return ctx_popup; +} + +void +_ivug_rename_enter_click_cb(void *data, Evas_Object *obj, void *event_info) +{ + Ivug_Popup *iv_popup = (Ivug_Popup *)data; + IV_ASSERT(iv_popup != NULL); + + Evas_Object *entry = iv_popup->obj; + + char *name = elm_entry_markup_to_utf8 ( elm_entry_entry_get(entry) ); + + MSG_IMAGEVIEW_HIGH("name = %s", name); + + if(name) + { + char *new_name = NULL; + new_name = ivug_strip_string(name); + if(new_name == NULL) + { + MSG_IMAGEVIEW_ERROR( "rename failed"); + free(name); + ecore_imf_context_input_panel_hide(elm_entry_imf_context_get(entry)); + return; + } + elm_object_text_set(entry, new_name); + if(iv_popup->callback) + { + iv_popup->callback(iv_popup->data, iv_popup->popup, (void *)POPUP_RESPONSE_OK); + } + ivug_popup_delete(iv_popup); + } + else + { + //ecore_imf_context_input_panel_hide(elm_entry_imf_context_get(entry)); + } +} + +void +_ivug_rename_entry_changed(void *data, Evas_Object *obj, void *event_info) +{ + Ivug_Popup *iv_popup = (Ivug_Popup *)data; + IV_ASSERT(iv_popup != NULL); + + Evas_Object *entry = iv_popup->obj; + Evas_Object *btn_ok = elm_object_part_content_get(iv_popup->popup, "button1"); + + char *content = elm_entry_markup_to_utf8 ( elm_entry_entry_get(entry) ); + + if (strlen(content) == 0) + { + MSG_IMAGEVIEW_HIGH("ISF1 : %s", content); + elm_object_disabled_set(btn_ok, EINA_TRUE); + } + else + { + MSG_IMAGEVIEW_HIGH("ISF : %s", content); + elm_object_disabled_set(btn_ok, EINA_FALSE); + } + free(content); +} + +void +_ivug_rename_maxlength_reached(void *data, Evas_Object *obj, void *event_info) +{ + Ivug_Popup *iv_popup = (Ivug_Popup *)data; + IV_ASSERT(iv_popup != NULL); + + if ( iv_popup->haptic_handle == INVALID_HAPTIC_HANDLE ) + { + iv_popup->haptic_handle = ivug_vibration_create(); + } + else + { + ivug_vibration_stop(iv_popup->haptic_handle); + } + + ivug_vibration_play(iv_popup->haptic_handle ,VIBRATION_DURATION); + +} + +Evas_Object *ivug_rename_popup_show(Evas_Object *parent, const char *filename, Evas_Smart_Cb response, void *data) +{ + Evas_Object *popup = NULL; + Evas_Object *entry = NULL; + Evas_Object *layout = NULL; + + Ivug_Popup *iv_popup = ivug_popup_create(); + + popup = elm_popup_add(parent); + if(!popup) + { + MSG_IMAGEVIEW_ERROR("popup is NULL"); + goto ENTRY_POPUP_FREE; + } + //evas_object_size_hint_weight_set(popup, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + //elm_object_style_set(popup, "menustyle"); + elm_object_part_text_set(popup, "title,text", "Rename"); + + layout = elm_layout_add(popup); + if(!layout) + { + MSG_IMAGEVIEW_ERROR("layout is NULL"); + goto ENTRY_POPUP_FREE; + } + if(elm_layout_file_set(layout, IVUG_POPUP_EDJ_NAME, "popup_entryview") == EINA_FALSE) + { + MSG_IMAGEVIEW_ERROR("elm_layout_file_set error");; + goto ENTRY_POPUP_FREE; + } + //evas_object_size_hint_align_set(layout, EVAS_HINT_FILL, EVAS_HINT_FILL); + evas_object_size_hint_weight_set(layout, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + + entry = elm_entry_add(popup); + elm_entry_scrollable_set(entry, EINA_TRUE); + elm_entry_single_line_set(entry, EINA_TRUE); + elm_object_text_set(entry, filename); + elm_entry_cursor_end_set(entry); + elm_object_part_content_set(layout, "elm.swallow.content", entry); + elm_object_content_set(popup, layout); + + evas_object_smart_callback_add(entry, "activated", _ivug_rename_enter_click_cb, iv_popup); + evas_object_smart_callback_add(entry, "changed", _ivug_rename_entry_changed, iv_popup); + + static Elm_Entry_Filter_Limit_Size limit_filter_data; + limit_filter_data.max_char_count = 64; + limit_filter_data.max_byte_count = 0; + elm_entry_markup_filter_append(entry, elm_entry_filter_limit_size, &limit_filter_data); + evas_object_smart_callback_add(entry, "maxlength,reached", _ivug_rename_maxlength_reached, (void *)iv_popup); + + evas_object_show(layout); + + Evas_Object *btn_ok = elm_button_add(popup); + elm_object_style_set(btn_ok, "popup_button/default"); + elm_object_text_set(btn_ok, IDS_OK); + elm_object_part_content_set(popup, "button1", btn_ok); + evas_object_data_set(btn_ok, "response", (void *)POPUP_RESPONSE_OK); + evas_object_smart_callback_add(btn_ok, "clicked", _ivug_rename_enter_click_cb, iv_popup); + + Evas_Object *btn_cancel = elm_button_add(popup); + elm_object_style_set(btn_cancel, "popup_button/default"); + elm_object_text_set(btn_cancel, IDS_CANCEL); + elm_object_part_content_set(popup, "button2", btn_cancel); + evas_object_data_set(btn_cancel, "response", (void *)POPUP_RESPONSE_CANCEL); + evas_object_smart_callback_add(btn_cancel, "clicked", _on_popup_response, iv_popup); + + iv_popup->popup = popup; + iv_popup->callback = response; + iv_popup->data = data; + iv_popup->obj = entry; + + evas_object_show(popup); + + return popup; + +ENTRY_POPUP_FREE: + if(popup) + { + evas_object_del(popup); + } + if(layout) + { + evas_object_del(layout); + } + if(entry) + { + evas_object_del(entry); + } + return NULL; +} + +static void _block_clicked_cb(void *data, Evas_Object *obj, void *event_info) +{ + IV_ASSERT(data != NULL); + + Ivug_Popup *iv_popup = (Ivug_Popup *)data; + Popup_Response response = (Popup_Response)evas_object_data_get(obj, "response"); + MSG_IMAGEVIEW_HIGH("response callback=%d", response); + + if(iv_popup->callback) + { + iv_popup->callback(iv_popup->data, iv_popup->popup, (void *)response); + } + + ivug_popup_delete(iv_popup); +} + +static char * +_gl_text_get(void *data, Evas_Object *obj, const char *part) +{ + ivug_radio_popup_item *popup_item = (ivug_radio_popup_item *)data; + //int index = popup_item->index; + + if (strcmp(part, "elm.text") == 0) + { + return strdup(popup_item->name); + } + return NULL; +} + +static Evas_Object * +_gl_content_get(void *data, Evas_Object *obj, const char *part) +{ + ivug_radio_popup_item *popup_item = (ivug_radio_popup_item *)data; + + Evas_Object *radio; + Evas_Object *radio_main = popup_item->radio_main; + int index = popup_item->index; + int selected_index = popup_item->p_iv_popup->selected_index; + + if (strcmp(part, "elm.icon") == 0 || strcmp(part, "elm.swallow.icon") == 0) + { + radio = elm_radio_add(obj); + elm_radio_state_value_set(radio, index); + elm_radio_group_add(radio, radio_main); + if (index == selected_index) + elm_radio_value_set(radio, selected_index); + evas_object_size_hint_weight_set(radio, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + evas_object_size_hint_align_set(radio, EVAS_HINT_FILL, EVAS_HINT_FILL); + + return radio; + } + + return NULL; +} + +static void +_gl_del(void *data, Evas_Object *obj) +{ + ivug_radio_popup_item *popup_item = (ivug_radio_popup_item *)data; + + if(popup_item->name) + { + free(popup_item->name); + popup_item->name = NULL; + } + + free(popup_item); + + return; +} + +static void +_gl_sel(void *data, Evas_Object *obj, void *event_info) +{ + IV_ASSERT(data != NULL); + + Ivug_Popup *iv_popup = (Ivug_Popup *)data; + + Elm_Object_Item *item = (Elm_Object_Item *) event_info; + ivug_radio_popup_item *popup_item = NULL; + + MSG_IMAGEVIEW_HIGH("_gl_sel"); + + if (item) + { + popup_item = (ivug_radio_popup_item *)elm_object_item_data_get(item); + iv_popup->selected_index = popup_item->index; + elm_genlist_item_update(item); + + if(iv_popup->callback) + { + iv_popup->callback(iv_popup->data, iv_popup->popup, (void *)iv_popup->selected_index); + } + + ivug_popup_delete(iv_popup); + } +} + +Evas_Object *ivug_radio_popoup_show(Evas_Object *parent, char *title, + int selected_index, Eina_List *name_list, Evas_Smart_Cb response, void *data) +{ +#define GET_POPUP_HEIGHT(icnt) (((113*icnt-1) > 408) ? (408) : (113*icnt-1)) +#define GET_POPUP_WIDTH(icnt) (614) + + Evas_Object *popup; + int index = 0; + Elm_Object_Item *item; + Evas_Object *genlist; + Evas_Object *btn_close; + Evas_Object *radio_main; + + static Elm_Genlist_Item_Class itc = {0,}; + + ivug_radio_popup_item *popup_item; + + Ivug_Popup *iv_popup = ivug_popup_create(); + + popup = elm_popup_add(parent); + elm_object_style_set(popup, "min_menustyle"); + elm_object_part_text_set(popup, "title,text", title); + evas_object_smart_callback_add(popup, "block,clicked", _block_clicked_cb, iv_popup); + evas_object_size_hint_weight_set(popup, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + + btn_close = elm_button_add(popup); + elm_object_style_set(btn_close, "popup_button/default"); + elm_object_text_set(btn_close, IDS_CLOSE); + elm_object_part_content_set(popup, "button1", btn_close); + evas_object_data_set(btn_close, "response", (void *)POPUP_RESPONSE_OK); + evas_object_smart_callback_add(btn_close, "clicked", _on_popup_response, iv_popup); + + itc.item_style = "1text.1icon.2"; + itc.func.text_get = _gl_text_get; + itc.func.content_get = _gl_content_get; + itc.func.state_get = NULL; + itc.func.del = _gl_del; + + genlist = elm_genlist_add(popup); + evas_object_size_hint_weight_set(genlist, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + evas_object_size_hint_align_set(genlist, EVAS_HINT_FILL, EVAS_HINT_FILL); + evas_object_propagate_events_set(genlist, EINA_FALSE); + + radio_main = elm_radio_add(genlist); + elm_radio_state_value_set(radio_main, -1); + elm_radio_value_set(radio_main, -1); + evas_object_propagate_events_set(radio_main, EINA_FALSE); + + Eina_List *l = NULL; + char *name = NULL; + + EINA_LIST_FOREACH(name_list, l, name) + { + popup_item = calloc(1, sizeof(ivug_radio_popup_item)); + popup_item->index = index++; + popup_item->name = strdup(name); + popup_item->radio_main = radio_main; + popup_item->p_iv_popup = iv_popup; + + item = elm_genlist_item_append(genlist, &itc, (void *)popup_item, NULL, + ELM_GENLIST_ITEM_NONE, _gl_sel, iv_popup); + } + + Evas_Object *box; + box = elm_box_add(popup); + evas_object_size_hint_min_set(box, GET_POPUP_WIDTH(index-1) * elm_config_scale_get(), GET_POPUP_HEIGHT(index-1) * elm_config_scale_get()); + evas_object_show(genlist); + elm_box_pack_end(box, genlist); + elm_object_content_set(popup, box); + //elm_object_content_set(popup, genlist); + + iv_popup->popup = popup; + iv_popup->callback = response; + iv_popup->data = data; + iv_popup->obj = radio_main; + iv_popup->selected_index = selected_index; + + evas_object_show(popup); + + return popup; +} + + diff --git a/main/src/control/ivug-popup.h b/main/src/control/ivug-popup.h new file mode 100755 index 0000000..dd1a1ba --- /dev/null +++ b/main/src/control/ivug-popup.h @@ -0,0 +1,82 @@ +/* + * Copyright 2012 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.tizenopensource.org/license + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __IVUG_POPUP_H__ +#define __IVUG_POPUP_H__ + +#include "ivug-common.h" + +typedef enum _Popup_Response +{ + POPUP_RESPONSE_NONE = -1, + POPUP_RESPONSE_TIMEOUT = -2, + POPUP_RESPONSE_OK = -3, + POPUP_RESPONSE_CANCEL = -4, + POPUP_RESPONSE_CLOSE = -5 +}Popup_Response; + +typedef enum _Longpress_Popup_Response +{ + LPPOPUP_RESPONSE_NONE = 0, + LPPOPUP_RESPONSE_COPY, + LPPOPUP_RESPONSE_MANUALLY_DETECT, +}Longpress_Popup_Response; + +// Selected data + +#ifdef __cplusplus +extern "C" { +#endif + +Evas_Object* ivug_1btn_popup_show(Evas_Object* parent, const char* title, + const char* contents, Evas_Smart_Cb response, void* user_data); + + +/* + Create & show popup with 2 button (Yes/No) +*/ +Evas_Object* ivug_2btn_popup_show(Evas_Object* parent, const char* title, + const char* contents, Evas_Smart_Cb response, void* user_data); + +/* + Create & show popup with no button. + TODO : Rename function +*/ + +Evas_Object* +ivug_deletepopup_show(Evas_Object* parent, const char* title, + const char* contents, Evas_Smart_Cb response, void* user_data); + + +/* + Create show copy popup in coordinate (x,y) +*/ +Evas_Object* ivug_longpress_popup_show(Evas_Object *parent, int x, int y, Evas_Smart_Cb response, void *data); + +Evas_Object* ivug_deletepopup_show(Evas_Object* parent, const char* title, + const char* contents, Evas_Smart_Cb response, void* user_data); + +Evas_Object *ivug_rename_popup_show(Evas_Object *parent, const char *filename, Evas_Smart_Cb response, void *data); + +Evas_Object *ivug_radio_popoup_show(Evas_Object *parent, char *title, + int selected_index, Eina_List *name_list, Evas_Smart_Cb response, void *data); + +#ifdef __cplusplus +} +#endif + + +#endif //__IVUG_POPUP_H__ diff --git a/main/src/control/ivug-selectioninfo.c b/main/src/control/ivug-selectioninfo.c new file mode 100755 index 0000000..10aa0c8 --- /dev/null +++ b/main/src/control/ivug-selectioninfo.c @@ -0,0 +1,151 @@ +/* + * Copyright 2012 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.tizenopensource.org/license + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "ivug-common.h" + +#include + +#include "ivug-selectioninfo.h" + +#define NOTIFY_TIMEOUT 3.0 + +static void +_ivug_selectioninfo_timeout_cb(void *data, Evas_Object *obj, void *event_info) +{ + ivug_ret_if(obj == NULL); + + evas_object_del(obj); + obj = NULL; +} + +static void _on_resize(void *data, Evas *e, Evas_Object *obj, void *event_info) +{ + Evas_Coord x,y,w,h; + evas_object_geometry_get(obj, &x, &y, &w, &h); + + MSG_IMAGEVIEW_HIGH("Selection resized geomtery XYWH(%d,%d,%d,%d) angle=%d", x, y, w, h, gGetRotationDegree()); + + Evas_Object* layout = elm_object_content_get(obj); + ivug_retm_if(layout == NULL, "Notify content is NULL"); + + //Get the selectioninfo text + const char* text = edje_object_part_text_get(_EDJ(layout), "elm.text"); + +#ifdef USE_CUSTOM_STYLE + elm_object_theme_set(layout, gGetSystemTheme()); + + int rot_angle = gGetRotationDegree(); + if ( (rot_angle == 0) || (rot_angle == 180) ) + { + elm_layout_theme_set(layout, "standard", "selectioninfo", "vertical/bottom_86"); + } + else + { + elm_layout_theme_set(layout, "standard", "selectioninfo", "horizontal/bottom_64"); + } +#endif + + if(text) + { + //Reset the text, because the text will be missed if no reset + edje_object_part_text_set(_EDJ(layout), "elm.text", text); + } + +} + + +Evas_Object* +ivug_selectioninfo_create(Evas_Object* parent, const char* text) +{ + Evas_Object *notify; + + notify = elm_notify_add(parent); + ivug_retv_if(notify == NULL, NULL); + elm_notify_orient_set(notify, ELM_NOTIFY_ORIENT_BOTTOM); + evas_object_size_hint_weight_set(notify, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + evas_object_size_hint_align_set(notify, EVAS_HINT_FILL, EVAS_HINT_FILL); + evas_object_smart_callback_add(notify, "timeout", _ivug_selectioninfo_timeout_cb, NULL); + elm_notify_timeout_set(notify, NOTIFY_TIMEOUT); + + int rot_angle = gGetRotationDegree(); + + Evas_Object* layout = elm_layout_add(parent); + +#ifdef USE_CUSTOM_STYLE + elm_object_theme_set(layout, gGetSystemTheme()); + + if ( (rot_angle == 0) || (rot_angle == 180) ) + { + elm_layout_theme_set(layout, "standard", "selectioninfo", "vertical/bottom_86"); + } + else + { + elm_layout_theme_set(layout, "standard", "selectioninfo", "horizontal/bottom_64"); + } +#endif + + evas_object_size_hint_weight_set(layout, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + evas_object_size_hint_align_set(layout, EVAS_HINT_FILL, EVAS_HINT_FILL); + elm_object_content_set(notify, layout); + edje_object_part_text_set(_EDJ(layout), "elm.text", text); + + evas_object_event_callback_add(notify, EVAS_CALLBACK_RESIZE, _on_resize, NULL); + + evas_object_show(notify); + + return notify; +} + +Evas_Object* +ivug_notify_create(Evas_Object* parent, const char* text) +{ + Evas_Object *notify; + + notify = elm_notify_add(parent); + ivug_retv_if(notify == NULL, NULL); + elm_notify_orient_set(notify, ELM_NOTIFY_ORIENT_BOTTOM); + evas_object_size_hint_weight_set(notify, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + evas_object_size_hint_align_set(notify, EVAS_HINT_FILL, EVAS_HINT_FILL); + + int rot_angle = gGetRotationDegree(); + + Evas_Object* layout = elm_layout_add(parent); + +#ifdef USE_CUSTOM_STYLE + elm_object_theme_set(layout, gGetSystemTheme()); + + if ( (rot_angle == 0) || (rot_angle == 180) ) + { + elm_layout_theme_set(layout, "standard", "selectioninfo", "vertical/bottom_86"); + } + else + { + elm_layout_theme_set(layout, "standard", "selectioninfo", "horizontal/bottom_64"); + } +#endif + + evas_object_size_hint_weight_set(layout, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + evas_object_size_hint_align_set(layout, EVAS_HINT_FILL, EVAS_HINT_FILL); + elm_object_content_set(notify, layout); + edje_object_part_text_set(_EDJ(layout), "elm.text", text); + + evas_object_event_callback_add(notify, EVAS_CALLBACK_RESIZE, _on_resize, NULL); + + evas_object_show(notify); + + return notify; +} + diff --git a/main/src/control/ivug-selectioninfo.h b/main/src/control/ivug-selectioninfo.h new file mode 100755 index 0000000..ceb01a4 --- /dev/null +++ b/main/src/control/ivug-selectioninfo.h @@ -0,0 +1,33 @@ +/* + * Copyright 2012 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.tizenopensource.org/license + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __IVUG_SELECTIONINFO_H__ +#define __IVUG_SELECTIONINFO_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +/* time out applied */ +Evas_Object * ivug_selectioninfo_create(Evas_Object* parent, const char* contents); + +Evas_Object * ivug_notify_create(Evas_Object* parent, const char* text); + +#ifdef __cplusplus +} +#endif + +#endif // __IVUG_SELECTIONINFO_H__ diff --git a/main/src/control/ivug-setas.cpp b/main/src/control/ivug-setas.cpp new file mode 100755 index 0000000..18db6fe --- /dev/null +++ b/main/src/control/ivug-setas.cpp @@ -0,0 +1,321 @@ +/* + * Copyright 2012 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.tizenopensource.org/license + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include + +#include "ivug-common.h" + +#include "ivug-debug.h" +#include "ivug-util.h" +#include "ivug-image.h" + +#include "ivug-setas.h" + +/* + Used for storing cropped image. +*/ +#define IVUG_HOME_SCREEN_TEMP_PATH DATA_PATH"/.homescreen_tmp.jpg" +#define IVUG_LOCK_SCREEN_TEMP_PATH DATA_PATH"/.lockscreen_tmp.jpg" + + +static Eina_Bool _crop_image(Evas_Object *photocam, Evas_Coord_Rectangle *rect, const char *save_file, const char *option) +{ + if (ivug_remove_file(save_file) == false) + { + MSG_SETAS_ERROR( "Delete file %s: failed", save_file); + return EINA_FALSE; + } + + Evas_Object *ret_image = NULL; + + ret_image = ivug_image_region_image_get(photocam, rect->x, rect->y, rect->w , rect->h); + + if(ret_image == NULL) + { + MSG_SETAS_ERROR("Region get faied."); + return EINA_FALSE; + } + + if (evas_object_image_save(ret_image, save_file, NULL, option) == EINA_FALSE) + { + MSG_SETAS_ERROR("evas_object_image_save error. %s", save_file); + MSG_SETAS_ERROR("setas image save faied."); + evas_object_del(ret_image); + return EINA_FALSE; + } + + evas_object_del(ret_image); + + return EINA_TRUE; +} + + +static Eina_Bool _photocam_image_save(Evas_Object *photocam, Evas_Coord_Rectangle *rect, const char* tmp_file, const char* final_file) +{ +//2. Crop image and save it as tmp file + Eina_Bool ret; + + if ( tmp_file == NULL ) + { + if (ivug_remove_file(final_file) == false) // Remove dest file + { + MSG_SETAS_ERROR( "Delete file %s failed", final_file); + goto error; + } + + ret = _crop_image(photocam, rect, final_file, "quality=100 compress=9"); + if(ret == EINA_FALSE) + { + MSG_SETAS_ERROR("crop image failed!"); + goto error; + } + + } + else + { + // save ½ÇÆнà ÇöÀçÀÇ image¸¦ º¸È£Çϱâ À§ÇØ ¸ÕÀú tmp¿¡ ÀúÀåÇÑ ´ÙÀ½ rename ÇÑ´Ù. + ret = _crop_image(photocam, rect, tmp_file, "quality=100 compress=9"); + if(ret == EINA_FALSE) + { + MSG_SETAS_ERROR("crop image failed!"); + goto error; + } + + //3. Delete the lockscreen file if exist + if (ivug_remove_file(final_file) == false) + { + MSG_SETAS_ERROR( "Delete file %s failed", final_file); + goto error; + } + + //4. rename the tmp file to lock screen file + if(ivug_rename_file(tmp_file, final_file) == false) + { + MSG_SETAS_ERROR( "Rename file %s to %s failed", tmp_file, final_file); + goto error; + } + } + + return EINA_TRUE; +error: + + if(ivug_remove_file(tmp_file) == false) + { + MSG_SETAS_ERROR( "Delete file %s failed", tmp_file); + } + + return EINA_FALSE; +} + +Eina_Bool +_ivug_setas_save_home_screen(Evas_Object *photocam, Evas_Coord_Rectangle *rect, const char *dest) +{ + MSG_SETAS_HIGH("Change Home Screen"); + + Eina_Bool ret = EINA_FALSE; + + ret = _photocam_image_save(photocam, rect, IVUG_HOME_SCREEN_TEMP_PATH, dest); + + if(ret == EINA_FALSE) + { + MSG_SETAS_ERROR("Create screen file failed"); + return EINA_FALSE; + } + + return EINA_TRUE; +} + +Eina_Bool +_ivug_setas_save_lock_screen(Evas_Object *photocam, Evas_Coord_Rectangle *rect, const char *dest) +{ + MSG_SETAS_HIGH("Change Lock Screen"); + + Eina_Bool ret = EINA_FALSE; + + ret = _photocam_image_save(photocam, rect, IVUG_LOCK_SCREEN_TEMP_PATH, dest); + + if(ret == EINA_FALSE) + { + MSG_SETAS_ERROR( "Create screen file failed"); + return EINA_FALSE; + } + + return EINA_TRUE; +} + +Eina_Bool +_ivug_setas_save_homenlock_screen(Evas_Object *photocam, Evas_Coord_Rectangle *rect, const char *home, const char *lock) +{ + MSG_SETAS_HIGH("Change Home&Lock Screen"); + +// Set homescreen image + Eina_Bool ret = EINA_FALSE; + + ret = _photocam_image_save(photocam, rect, IVUG_HOME_SCREEN_TEMP_PATH, home); + + if(ret == EINA_FALSE) + { + MSG_SETAS_ERROR( "Create screen file failed"); + return EINA_FALSE; + } + + if (ivug_remove_file(IVUG_LOCK_SCREEN_TEMP_PATH) == false) + { + MSG_SETAS_ERROR( "Detele file %s: failed", IVUG_LOCK_SCREEN_TEMP_PATH); + return EINA_FALSE; + } + +// Make a copy from home screen to lock screen + if( ecore_file_cp(home, IVUG_LOCK_SCREEN_TEMP_PATH) == EINA_FALSE) + { + MSG_SETAS_ERROR( "File copy failed"); + return EINA_FALSE; + } + + if(ivug_rename_file(IVUG_LOCK_SCREEN_TEMP_PATH, lock) == false) + { + MSG_SETAS_ERROR( "Rename file %s to %s failed", IVUG_LOCK_SCREEN_TEMP_PATH, lock ); + if(ivug_remove_file(IVUG_LOCK_SCREEN_TEMP_PATH)== false) + { + MSG_SETAS_ERROR( "delete tmp lock file failed %s", IVUG_LOCK_SCREEN_TEMP_PATH); + } + + return EINA_FALSE; + } + + sync(); //sync copied file. + + return EINA_TRUE; +} + + +#if 0 +static Eina_Bool +_ivug_setas_view_create_croped_image(Evas_Object *photocam, const char *save_file, + Evas_Coord_Rectangle rect, int width, int height, bool bFreeSize) +{ + IV_ASSERT(photocam != NULL); + IV_ASSERT(save_file != NULL); + + if(bFreeSize == true) + { + width = rect.w; + height = rect.h; + } + + if(width <= 0 || height <= 0) + { + MSG_SETAS_ERROR("input size parameter is invalid, w = %d, h = %d", width, height); + return EINA_FALSE; + } + + Evas_Object *ret_image = NULL; + + MSG_SETAS_HIGH("SCissorbox Rect:(%d,%d,%d,%d) Final=(%d,%d)", rect.x, rect.y, rect.w, rect.h, width, height); + + ret_image = ivug_image_region_image_get(photocam, rect.x, rect.y, rect.w, rect.h); + if(ret_image == NULL) + { + MSG_SETAS_ERROR("Region get faied."); + return EINA_FALSE; + } + + if (evas_object_image_save(ret_image, save_file, NULL, "quality=100 compress=9") == EINA_FALSE) + { + MSG_SETAS_ERROR("evas_object_image_save error. %s", save_file); + evas_object_del(ret_image); + return EINA_FALSE; + } + else + { + int fd = open(save_file, O_RDONLY); + if(fd < 0) + { + MSG_SETAS_ERROR("%s open error[%d]", save_file, fd); + evas_object_del(ret_image); + return EINA_FALSE; + } + fsync(fd); + int ret = close(fd); + if(ret < 0) + { + MSG_SETAS_ERROR("%s open error[%d]", save_file, ret); + } + } + + evas_object_del(ret_image); + + return EINA_TRUE; +} + + +static void +_ivug_setas_save_callerimage(Evas_Object *photocam, Evas_Coord_Rectangle *rect, char *filepath) +{ + MSG_SETAS_HIGH("Save CallerID"); + + char* save_file = SET_AS_CALL_ID_PATH; + + Evas_Coord_Rectangle box_rect; + + ivug_scissorbox_region_get(pSetAsView->select_box, &(box_rect.x), &(box_rect.y), &(box_rect.w), &(box_rect.h)); + + Eina_Bool crop_sel_ret = _ivug_setas_view_create_croped_image(photocam, + save_file, box_rect, pSetAsView->box_width, pSetAsView->box_height, pSetAsView->bFreeSize); + if(crop_sel_ret == EINA_FALSE) + { + MSG_SETAS_ERROR( "Crop selector image failed!"); + } + + const char *lcd_file = SET_AS_CALL_ID_LCD_PATH; // ????? + + Eina_Bool crop_lcd_ret = EINA_FALSE; + + crop_lcd_ret = _ivug_setas_view_create_fit_image(pSetAsView->layout, pSetAsView->photocam, lcd_file); + if(crop_lcd_ret == EINA_FALSE) + { + MSG_SETAS_ERROR( "Crop lcd image failed!"); + } + + if(pSetAsView->mode == IVUG_SETAS_UG || pSetAsView->mode == IVUG_SETAS_APPSVC) + { + if ( crop_lcd_ret == EINA_TRUE && crop_sel_ret == EINA_TRUE ) + { + _ivug_setas_view_send_result(gGetUGHandle(), "crop_image_path", save_file, "image_path", lcd_file); + } + } +} +#endif + +Eina_Bool +_ivug_setas_save_cropimage(Evas_Object *photocam, Evas_Coord_Rectangle *rect, const char *filepath) +{ + MSG_SETAS_HIGH("Save Cropped"); + + Eina_Bool ret = EINA_FALSE; + + ret = _photocam_image_save(photocam, rect, NULL, filepath); + + if(ret == EINA_FALSE) + { + MSG_SETAS_ERROR( "Create cropimage file failed"); + return EINA_FALSE; + } + + return EINA_TRUE; +} + + diff --git a/main/src/control/ivug-setas.h b/main/src/control/ivug-setas.h new file mode 100755 index 0000000..9564954 --- /dev/null +++ b/main/src/control/ivug-setas.h @@ -0,0 +1,42 @@ +/* + * Copyright 2012 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.tizenopensource.org/license + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __IVUG_SETAS_H__ +#define __IVUG_SETAS_H__ + + +#ifdef __cplusplus +extern "C" { +#endif + +Eina_Bool +_ivug_setas_save_home_screen(Evas_Object *photocam, Evas_Coord_Rectangle *rect, const char *dest); + +Eina_Bool +_ivug_setas_save_lock_screen(Evas_Object *photocam, Evas_Coord_Rectangle *rect, const char *dest); + +Eina_Bool +_ivug_setas_save_homenlock_screen(Evas_Object *photocam, Evas_Coord_Rectangle *rect, const char *home, const char *lock); + +Eina_Bool +_ivug_setas_save_cropimage(Evas_Object *photocam, Evas_Coord_Rectangle *rect, const char *filepath); + +#ifdef __cplusplus +} +#endif + +#endif // __IVUG_SETAS_H__ + diff --git a/main/src/control/ivug-widget.c b/main/src/control/ivug-widget.c new file mode 100755 index 0000000..502a13c --- /dev/null +++ b/main/src/control/ivug-widget.c @@ -0,0 +1,215 @@ +/* + * Copyright 2012 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.tizenopensource.org/license + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "ivug-common.h" +#include "ivug-widget.h" + +#include + +#include + +static void _on_obj_deleted(void * data, Evas * e, Evas_Object * obj, void * event_info) +{ + char *szMsg = (char *)data; + IV_ASSERT(szMsg != NULL); + + MSG_MAIN_HIGH("On Object deleted. %s", szMsg); + + free(szMsg); +} + +void ivug_on_obj_deleted(Evas_Object* obj, const char *msg, const char *func, int line) +{ + static char buf[1024]; + + sprintf(buf, "%s(L%d):%s", func, line, msg); + + evas_object_event_callback_add(obj, EVAS_CALLBACK_DEL, _on_obj_deleted, strdup(buf)); +} + +Evas_Object* ivug_bg_add(Evas_Object* parent, int r, int g, int b) +{ + IV_ASSERT(parent != NULL); + + Evas_Object *bg = elm_bg_add(parent); + evas_object_size_hint_weight_set(bg, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + evas_object_size_hint_align_set(bg, EVAS_HINT_FILL, EVAS_HINT_FILL); + +// elm_win_resize_object_add(parent, bg); + + elm_bg_color_set(bg, r, g, b); + + evas_object_show(bg); + + return bg; +} + +Evas_Object * +ivug_layout_add(Evas_Object *parent, const char *edj, const char *group) +{ + IV_ASSERT(parent != NULL); + + Evas_Object *layout; + + layout = elm_layout_add(parent); + + if ( layout == NULL ) + { + MSG_SETAS_ERROR("Cannot create layout"); + return NULL; + } + + if (elm_layout_file_set(layout, edj, group) == EINA_FALSE) + { + MSG_SETAS_ERROR("edj loading fail, filepath=%s Group=%s", edj, group); + evas_object_del(layout); + return NULL; + } + + evas_object_size_hint_expand_set(layout, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + evas_object_size_hint_fill_set(layout, EVAS_HINT_FILL, EVAS_HINT_FILL); + +#ifdef USE_WIN_AS_PARENT + elm_win_resize_object_add( ug_get_window(), layout); +#else + Evas_Coord x, y, w, h; + evas_object_geometry_get(parent, &x, &y, &w, &h); + + evas_object_move(layout, x, y); + evas_object_resize(layout, w, h); +#endif + + return layout; +} + +Evas_Object* +ivug_default_layout_add( Evas_Object *win) +{ + IV_ASSERT(win != NULL); + + Evas_Object *layout; + layout = elm_layout_add(win); + + if ( layout == NULL ) + { + MSG_SETAS_ERROR("Cannot create layout"); + return NULL; + } + + Eina_Bool ret = EINA_FALSE; + + const char *profile = elm_config_profile_get(); + if (!strcmp(profile,"mobile")) + { + ret = elm_layout_theme_set(layout, "layout", "application", "default"); + MSG_SETAS_HIGH("layout/application/default"); + } + else if (!strcmp(profile,"desktop")) + { + ret = elm_layout_theme_set(layout, "layout", "application", "noindicator"); + MSG_SETAS_HIGH("layout/application/noindicator"); + } + + if (ret == EINA_FALSE) + { + MSG_SETAS_ERROR("theme set fail"); + evas_object_del(layout); + return NULL; + } + + evas_object_size_hint_expand_set( layout, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + evas_object_size_hint_fill_set(layout, EVAS_HINT_FILL, EVAS_HINT_FILL ); + +#ifdef USE_WIN_AS_PARENT + elm_win_resize_object_add( ug_get_window(), layout); +#else + Evas_Coord x, y, w, h; + evas_object_geometry_get(parent, &x, &y, &w, &h); + + evas_object_move(layout, x, y); + evas_object_resize(layout, w, h); +#endif + + evas_object_show(layout); + return layout; +} + + +Evas_Object *ivug_button_add(Evas_Object *parent, const char *style, const char *caption, Evas_Object *icon, Evas_Smart_Cb pFunc, const void * data ) +{ + IV_ASSERT(parent != NULL); + + Evas_Object *btn; + + btn = elm_button_add(parent); + if ( btn == NULL ) + { + return NULL; + } + + if ( style ) + elm_object_style_set(btn, style); + + if ( caption ) + elm_object_text_set(btn, caption); + + if ( icon ) + elm_object_part_content_set(btn, "icon", icon); + + elm_object_focus_allow_set(btn, EINA_FALSE); + evas_object_propagate_events_set(btn, EINA_FALSE); + + evas_object_smart_callback_add(btn, "clicked", pFunc, (void*)data); + + return btn; +} + +Evas_Object *ivug_icon_add(Evas_Object *parent, const char *edjname, const char *groupname) +{ + Evas_Object *icon; + + icon = elm_icon_add(parent); + + if ( elm_icon_file_set(icon, edjname, groupname) == EINA_FALSE) + { + MSG_IVUG_ERROR("Cannot file set. EDJ=%s Group=%s", edjname, groupname); + evas_object_del(icon); + return NULL; + } + + evas_object_size_hint_aspect_set(icon, EVAS_ASPECT_CONTROL_VERTICAL, 1, 1); + elm_icon_resizable_set(icon, 1, 1); + evas_object_size_hint_expand_set(icon, 1, 1); + + return icon; +} + +Evas_Object *ivug_controlbar_add(Evas_Object *parent, const char *style) +{ + Evas_Object *toolbar = elm_toolbar_add(parent); + if (!toolbar) + { + MSG_MAIN_ERROR("tool bar failed"); + return NULL; + } + elm_toolbar_shrink_mode_set(toolbar, ELM_TOOLBAR_SHRINK_EXPAND); + if(style) + elm_object_style_set(toolbar, style); + //elm_toolbar_homogeneous_set(toolbar, EINA_FALSE); + + return toolbar; +} + diff --git a/main/src/control/ivug-widget.h b/main/src/control/ivug-widget.h new file mode 100755 index 0000000..9433e46 --- /dev/null +++ b/main/src/control/ivug-widget.h @@ -0,0 +1,61 @@ +/* + * Copyright 2012 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.tizenopensource.org/license + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __IVUG_WIDGET_H__ +#define __IVUG_WIDGET_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +/* + Internal use only... use macro DELETE_LOG instead +*/ +void ivug_on_obj_deleted(Evas_Object* obj, const char *msg, const char *func, int line); + + +#define DELETE_NOTIFY(obj) \ + ivug_on_obj_deleted(obj, #obj, __func__, __LINE__) + +/* + Create elm_bg with color - r,g,b +*/ +Evas_Object * +ivug_bg_add(Evas_Object* parent, int r, int g, int b); + +Evas_Object * +ivug_layout_add(Evas_Object *win, const char *edjname, const char *groupname); + +Evas_Object* +ivug_default_layout_add( Evas_Object *win); + +Evas_Object * +ivug_button_add(Evas_Object *parent, const char *style, const char *caption, Evas_Object *icon, Evas_Smart_Cb pFunc, const void *data ); + +Evas_Object * +ivug_icon_add(Evas_Object *parent, const char *edjname, const char *groupname); + +Evas_Object * +ivug_controlbar_add(Evas_Object *parent, const char *style); + + +#ifdef __cplusplus +} +#endif + + +#endif // __IVUG_WIDGET_H__ + diff --git a/main/src/include/ivug-common.h b/main/src/include/ivug-common.h new file mode 100755 index 0000000..6ebc0e2 --- /dev/null +++ b/main/src/include/ivug-common.h @@ -0,0 +1,80 @@ +/* + * Copyright 2012 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.tizenopensource.org/license + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __IVUG_COMMON_H__ +#define __IVUG_COMMON_H__ + +#include "ivug-define.h" +#include "ivug-datatypes.h" +#include "ivug-uuid.h" + +#include +#include + +#include "statistics.h" +#include "ivug-debug.h" +#include "ivug-string.h" +#include "ivug-util.h" +#include "ivug-define.h" +#include "ivug-config.h" +#include "ivug-widget.h" +#include "ivug-context.h" + +/* +Definition "PREFIX" is declared in CMakelist.txt + PREFIX is "/opt/ug" + PACKAGE is "ug-image-viewer-efl" + + Path name does not include trailing /. + + DATA_PATH is /opt/ug/data +*/ + +#define LOCALE_PATH PREFIX"/res/locale" +#define IMAGE_PATH PREFIX"/res/images/"PACKAGE +#define EDJ_PATH PREFIX"/res/edje/"PACKAGE +#define DATA_PATH DATADIR"/"PACKAGE + +/* + Home screen and Lock screen image should be put in DATA_PATH. +*/ + + +#define USE_WIN_AS_PARENT + +#define NAVI_OPTION_BTN_STYLE "naviframe/title/default"//"multiline" + +#define WHITE_THEME + +#ifdef WHITE_THEME +#define IVUG_DEFAULT_BG_COLOR 249 +#else +#define IVUG_DEFAULT_BG_COLOR 48 +#endif + +#define USE_DEFAULT_DOWNLOADS_FOLDER + +#ifdef USE_DEFAULT_DOWNLOADS_FOLDER +#define DEFAULT_DOWNLOADS_FOLDER "/opt/media/Downloads" +#endif + + +#define _EDJ(o) elm_layout_edje_get(o) + +#define MENUBAR_TIMEOUT_SEC (5.0f) // 5sec + +#endif /* __IVUG_COMMON_H__ */ + diff --git a/main/src/include/ivug-crop-view.h b/main/src/include/ivug-crop-view.h new file mode 100755 index 0000000..40b278a --- /dev/null +++ b/main/src/include/ivug-crop-view.h @@ -0,0 +1,70 @@ +/* + * Copyright 2012 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.tizenopensource.org/license + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __IVUG_CROP_VIEW_H__ +#define __IVUG_CROP_VIEW_H__ + +typedef struct { + Evas_Object *layout; + Evas_Object *notify; + + Evas_Object *photocam; + Evas_Object *cropbox; + + Evas_Object *gesture; + + bool bShowMenu; + char *file_path; + char *result_path; + + Ecore_Timer *timer; + + Evas_Object *btn_ok; + + int w; + int h; +} IvugCropView; + +/* + signals + "loaded" with error code + "ok,clicked" - Button "OK" clicked with filepath + "cancel,clicked" - Button "Cancel" clicked + "destroyed" +*/ + +#ifdef __cplusplus +extern "C" { +#endif + +IvugCropView *ivug_crop_view_create(Evas_Object *parent); + +bool ivug_crop_view_box_size_set(IvugCropView *pCropView, int w, int h); + +bool ivug_crop_view_box_ratio_fix(IvugCropView *pCropView, bool bFix); + +bool ivug_crop_view_file_set(IvugCropView *pCropView, const char *file); + +void ivug_crop_view_destroy(IvugCropView *pCropView); + +Evas_Object *ivug_crop_view_get_object(IvugCropView *pCropView); + +#ifdef __cplusplus +} +#endif + +#endif // __IVUG_CROP_VIEW_H__ + diff --git a/main/src/include/ivug-details-view.h b/main/src/include/ivug-details-view.h new file mode 100755 index 0000000..97b2658 --- /dev/null +++ b/main/src/include/ivug-details-view.h @@ -0,0 +1,78 @@ +/* + * Copyright 2012 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.tizenopensource.org/license + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __DETAILS_VIEW_H__ +#define __DETAILS_VIEW_H__ + +#include +#include "ivug-datatypes.h" +#include "ivug-media.h" +#include "ivug-name-view.h" + +#include "ivug-detail-info.h" + +/* + "renamed" +*/ + +typedef struct { + Evas_Object *parent; + Evas_Object *bg; + + Evas_Object *layout; + Evas *evas; + Evas_Object *genlist; + +/* + |---------------| + | naviframe | + |---------------| + | | + | genlist | + | | + |---------------| +*/ + +/* Genlist class */ + Elm_Genlist_Item_Class itc; + Elm_Genlist_Item_Class title_itc; + Elm_Genlist_Item_Class multiline_icon_itc; + Elm_Genlist_Item_Class multiline_itc; + + ivug_file_info_t file_Info; + + Ivug_NameView *pAddTagView; + Media_Data *mdata; +} Ivug_DetailsView; + +#ifdef __cplusplus +extern "C" { +#endif + +Ivug_DetailsView *ivug_details_view_screen_create(Evas_Object *parent, Media_Data *mdata, ivug_view_by view_by); + +void ivug_details_view_destroy(Ivug_DetailsView *pDetailsView); + +Evas_Object *ivug_details_view_object_get(Ivug_DetailsView *pDetailsView); + +#ifdef __cplusplus +} +#endif + + +#endif // __DETAILS_VIEW_H__ + + diff --git a/main/src/include/ivug-main-view.h b/main/src/include/ivug-main-view.h new file mode 100755 index 0000000..c41a70b --- /dev/null +++ b/main/src/include/ivug-main-view.h @@ -0,0 +1,211 @@ +/* + * Copyright 2012 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.tizenopensource.org/license + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __IVUG_MAIN_VIEWER_H__ +#define __IVUG_MAIN_VIEWER_H__ + +#include "ivug-common.h" +#include "ivug-parameter.h" +#include "ivug-medialist.h" + +#include "ivug-name-view.h" +#include "ivug-details-view.h" +#include "ivug-setas-view.h" + +#define MAX_CTRL_ITEM_CNT 5 +#define MAX_NAVI_ITEM_CNT 3 + +//navigation bar type +typedef enum { + NAVI_BAR_TYPE_NONE = 0x00, + NAVI_BAR_TYPE_EMPTY, // no control bar + NAVI_BAR_TYPE_IMAGE, // [Set, Info] default + NAVI_BAR_TYPE_FILE, // [Set, Info] default + NAVI_BAR_TYPE_VIDEO, // [Set, Info] default + NAVI_BAR_TYPE_SELECT, // [Ok, Cancel] from take photo +} ivug_toolbar; + +//control bar type +typedef enum { + CTRL_BAR_TYPE_NONE = 0x00, + CTRL_BAR_TYPE_EMPTY, // not exist ctrl bar + CTRL_BAR_TYPE_FILE, // [Delete,Share,Set,Info] file manager, video at gallery + CTRL_BAR_TYPE_IMAGE, // [Delete,Share, Slide show] from gallery + CTRL_BAR_TYPE_VIDEO, // [Delete,Share, Slide show] from gallery +} ivug_ctrlbar; + +typedef enum { +// only shows in ctrlbar + TOOLBUTTON_DELETE, + TOOLBUTTON_SHARE, + TOOLBUTTON_SLIDESHOW, + +// shows in either toolbar or ctrlbar + TOOLBUTTON_SETAS, + TOOLBUTTON_DETAILS, + +// only shows in toolbar + TOOLBUTTON_OK, + TOOLBUTTON_CANCEL, + +// Navigation hearder + TOOLBUTTON_TOOL, + +// NULL button for spacing + TOOLBUTTON_NULL, + TOOLBUTTON_MAX, +} ToolButtonType; + +typedef enum { + TOOLBUTTON_IN_NONE, + TOOLBUTTON_IN_TOOLBAR, + TOOLBUTTON_IN_CTRLBAR, +} TooButtonPos; + +typedef struct { + Elm_Object_Item *item; // Control bar item in navigation header. ex) SetAs, Favorite, Info + TooButtonPos pos; +} ControlBar_Item; + + +typedef struct _SlideShow SlideShow; + +typedef struct { + Evas_Object *parent; + Evas_Object *layout ; /*Layout widget based on EDJ*/ + + Evas_Object *navi_bar; + Evas_Object *empty_layout; + Elm_Object_Item *navi_it; + Evas_Object* slider; //image viewer slider + + Evas_Object *area_obj; //lcd area except indicator + + Evas_Object* selectioninfo; + + Evas_Object *zoom_slider; + int zoom_level; + +/* + |------------------| + | navi_bar | + |------------------| + | tool_bar | + |------------------| + | | + | | + | | + | | + |------------------| + | ctrl_bar | + |------------------| +*/ + +// Toolbar + Evas_Object *tool_bar; + ivug_toolbar tool_bar_type; + +// Controlbar + Evas_Object *ctrl_bar; + ivug_ctrlbar ctrl_bar_type; + + ControlBar_Item items[TOOLBUTTON_MAX]; + + bool bSetThmByUser; + + Evas_Object* popup; //popup + + Evas_Object* longpress_popup; //long press popup + bool bLongpressEnd; + +// child view. + Ivug_SetAsView *pSetAsView; + + Ivug_DetailsView *pDetailsView; + +// List + Media_List *mList; + +//flag + bool bShowMenu; + bool bFootSteps; + + ivug_mode mode; + ivug_view_by view_by; + + ui_gadget_h ext_ug; + + Ecore_Event_Handler *keydown_handler; + + Ecore_Timer *exit_timer; + Ecore_Timer *hide_timer; + int hide_count; + + Ecore_Timer *popup_timer; + + char *album_name; + +// Slide show; + SlideShow *ssHandle; +} Ivug_MainView; + +#ifdef __cplusplus +extern "C" { +#endif + +/* + Create MainView layout +*/ +Ivug_MainView * +ivug_main_view_create(Evas_Object* parent, ivug_mode mode, ivug_view_by view_by); + +Evas_Object * +ivug_main_view_object_get(Ivug_MainView *pMainView); + +void ivug_main_view_start(Ivug_MainView *pMainView); + +/* + Load media list from parameter. +*/ +bool ivug_main_view_load_list(Ivug_MainView *pMainView, ivug_parameter *ivug_param); + +/* + Start slide show. +*/ +void ivug_main_view_start_slideshow(Ivug_MainView *pMainView, Eina_Bool bSlideFirst); + +void ivug_main_view_resume(Ivug_MainView *pMainView); +void ivug_main_view_pause(Ivug_MainView *pMainView); + + +void ivug_main_view_destroy(Ivug_MainView *pMainView); + + +/* + Control GUI +*/ +void ivug_main_view_show_menu_bar(Ivug_MainView *pMainView); +void ivug_main_view_hide_menu_bar(Ivug_MainView *pMainView); + +void ivug_main_view_set_hide_timer(Ivug_MainView *pMainView); +void ivug_main_view_del_hide_timer(Ivug_MainView *pMainView); + +#ifdef __cplusplus +} +#endif + +#endif //__IVUG_MAIN_VIEWER_H__ + diff --git a/main/src/include/ivug-name-view.h b/main/src/include/ivug-name-view.h new file mode 100755 index 0000000..4e76df7 --- /dev/null +++ b/main/src/include/ivug-name-view.h @@ -0,0 +1,78 @@ +/* + * Copyright 2012 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.tizenopensource.org/license + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __IVUG_NAME_VIEW_H__ +#define __IVUG_NAME_VIEW_H__ + +#include "ivug-common.h" +#include "ivug-media.h" + +typedef enum { + NAME_VIEW_RESPONSE_OK, + NAME_VIEW_RESPONSE_CANCEL, +} ivug_name_response; + +typedef void (*FNResponse)(ivug_name_response resp, const char *string, void *pClientData); + +typedef struct _Ivug_NameView +{ + Evas_Object *bg; + Evas_Object *layout; + Evas_Object *content; + + Evas_Object *navibar; + + Evas_Object *editfield; + Evas_Object *entry; + Evas_Object *btn_done; + + int haptic_handle; // Negative if invalid + + FNResponse fnresponse; + void *clientdata; + +} Ivug_NameView; + +#ifdef __cplusplus +extern "C" { +#endif + +Ivug_NameView * +ivug_name_view_create(Evas_Object *parent, const char *title); + +void +ivug_name_view_set_title(Ivug_NameView *pNameView, const char *title); + +void +ivug_name_view_set_entry(Ivug_NameView *pNameView, const char *str); + +void +ivug_name_view_set_response_callback(Ivug_NameView *pNameView, FNResponse resp, void *data); + +void +ivug_name_view_destroy(Ivug_NameView *pNameView); + +Evas_Object * +ivug_name_view_object_get(Ivug_NameView *pNameView); + + +#ifdef __cplusplus +} +#endif + +#endif // __IVUG_NAME_VIEW_H__ + + diff --git a/main/src/include/ivug-setas-view.h b/main/src/include/ivug-setas-view.h new file mode 100755 index 0000000..5b7cce6 --- /dev/null +++ b/main/src/include/ivug-setas-view.h @@ -0,0 +1,103 @@ +/* + * Copyright 2012 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.tizenopensource.org/license + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __IVUG_SETAS_VIEW_H__ +#define __IVUG_SETAS_VIEW_H__ + +#include "ivug-common.h" + +typedef enum { + NOTI_SUCCESS, + NOTI_FAIL, +} TEXT_POPUP_TYPE; + +typedef enum { + IVUG_CTRLBAR_SET_SCREEN_HOME, + IVUG_CTRLBAR_SET_SCREEN_LOCK, + IVUG_CTRLBAR_SET_SCREEN_BOTH, + IVUG_CTRLBAR_SET_SCREEN_UNDEFINED, // Show select popup when click ok button. + IVUG_CTRLBAR_SET_SCREEN_CALLERID, + IVUG_CTRLBAR_SET_SCREEN_VIDEO_CALL_ID, + IVUG_CTRLBAR_SET_SCREEN_MAX +} ivug_set_screen_type; + +typedef enum { + IVUG_SETAS_NORMAL, // launched from mainview + IVUG_SETAS_UG, // ug mode + IVUG_SETAS_APPSVC // appsvc mode +} ivug_setas_mode; + +typedef enum { + SETAS_ERROR_TYPE_NONE, + SETAS_ERROR_TYPE_UNKNOWN_FORMAT, + SETAS_ERROR_TYPE_PERMISSION_DENIED, + SETAS_ERROR_TYPE_INVALID_FILE, + SETAS_ERROR_TYPE_GENERAL, +} SetAs_Error; + +typedef struct { + Evas_Object *ly_effect; // Layout for transition effect + + Evas_Object *content; // content + Evas_Object *genlist_popup; + + char *filename; + + ivug_setas_mode Mode; + ivug_set_screen_type Type; +} Ivug_SetAsView; + +#ifdef __cplusplus +extern "C" { +#endif + +Ivug_SetAsView * +ivug_setas_view_screen_ug_create(Evas_Object *parent, const char* filepath, ivug_setas_mode mode, ivug_set_screen_type type); + +Ivug_SetAsView * +ivug_setas_view_callerid_ug_create(Evas_Object *parent, const char* filepath, ivug_setas_mode mode, int output_width, int output_height); + +Ivug_SetAsView * +ivug_setas_view_video_call_id_ug_create(Evas_Object *parent, const char* filepath, ivug_setas_mode mode, int output_width, int output_height); + +void +ivug_setas_view_destroy(Ivug_SetAsView *data); + +Evas_Object * +ivug_setas_view_object_get(Ivug_SetAsView *pSetAsView); + +// Called by main_view +Ivug_SetAsView * +ivug_setas_view_screen_create(Evas_Object *parent, const char* filepath, ivug_setas_mode mode, ivug_set_screen_type screen_type); + + +#if 0 +Ivug_SetAsView * +ivug_setas_view_add(Evas_Object *parent); + +void +ivug_setas_view_source_file_set(Ivug_SetAsView *pSetAsView, const char* filepath); + +void +ivug_setas_view_mode_set(Ivug_SetAsView *pSetAsView, ivug_set_screen_type screen_type); +#endif + +#ifdef __cplusplus +} +#endif + + +#endif //__IVUG_SETAS_VIEW_H__ diff --git a/main/src/include/ivug-slider-item.h b/main/src/include/ivug-slider-item.h new file mode 100755 index 0000000..d1b9dca --- /dev/null +++ b/main/src/include/ivug-slider-item.h @@ -0,0 +1,181 @@ +/* + * Copyright 2012 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.tizenopensource.org/license + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include "ivug-common.h" +#include "ivug-medialist.h" +#include "ivug-slider.h" + +typedef struct _Slide_Item Slide_Item; + +typedef void (*OnSliderStateChanged)(slide_state_t state, Slide_Item *si, void *client_data); + +typedef enum +{ + SITEM_TYPE_UNKNOWN, + SITEM_TYPE_IMAGE, + SITEM_TYPE_VIDEO, +} sitem_type_t; + +struct _Slide_Item { + int x, y, w, h; // Object geometry +//Data + slide_state_t state; + sitem_type_t type; + + Media_Item *mitem; + +//flag + Eina_Bool thumbnail_show; + +// UI + Evas_Object* layout; + Evas_Object* thumbnail; // thumbnail + + Evas_Object* vIcon; //video play icon + + Evas_Object* photocam; // photocam + + Evas_Object* progress; //progress bar + +// Callback + bool bMenuVisible; + OnSliderStateChanged cb; + void *client_data; +}; + +#ifdef __cplusplus +extern "C" { +#endif + +// GUI related +Slide_Item* +ivug_slider_item_add(Evas_Object *slider); + +void +ivug_slider_item_del(Slide_Item *si); + +// Geometry +void +ivug_slider_item_hide(Slide_Item *si); + +void +ivug_slider_item_show(Slide_Item *si); + +void +ivug_slider_item_move(Slide_Item *si, int x, int y); + +void +ivug_slider_item_resize(Slide_Item *si, int w, int h); + +void +ivug_slider_item_clip_set(Slide_Item *si, Evas_Object *clipper); + +void +ivug_slider_item_clip_unset(Slide_Item *si); + + +// Callback +bool +ivug_slider_item_set_callback(Slide_Item* si, OnSliderStateChanged cb, void *data); + + +// Data +const Media_Item * +ivug_slider_item_data_get(Slide_Item *si); + +/* + When item is NULL, Data is cleared +*/ +bool +ivug_slider_item_data_set(Slide_Item *si, Media_Item *item); + +bool +ivug_slider_item_icon_click_check(Slide_Item *si, int x, int y); + +drm_data_t * +ivug_slider_item_check_drm_constraint(Slide_Item *si); + + +// Item state +bool +ivug_slider_item_load(Slide_Item *si); + +void +ivug_slider_item_play(Slide_Item* si); + +void +ivug_slider_item_pause(Slide_Item* si); // --> Hide + +void +ivug_slider_item_resume(Slide_Item* si); // --> Show + +void +ivug_slider_item_stop(Slide_Item* si); + +void +ivug_slider_item_video_play(Slide_Item* si); + +void +ivug_slider_item_video_pause(Slide_Item* si); + + +// Control +bool +ivug_slider_item_region_size_get(Slide_Item *si, int *x, int *y, int *w, int *h); + +void +ivug_slider_item_hold_set(Slide_Item *si, Eina_Bool hold); // Ignore mouse event + +void +ivug_slider_item_zoom_reset(Slide_Item *si, Eina_Bool bAnim, int center_x, int center_y); + +void +ivug_slider_item_zoom_set(Slide_Item *si, double zoom, int center_x, int center_y); + +double +ivug_slider_item_zoom_get(Slide_Item* si); + +bool +ivug_slider_item_image_rotate_set(Slide_Item *si, int angle); + + +void +ivug_slider_item_hide_menu(Slide_Item* si); + +void +ivug_slider_item_show_menu(Slide_Item* si); + +Eina_Bool +ivug_slider_item_video_is_playing(Slide_Item* si); + + +Evas_Object * +ivug_slider_item_image_get(Slide_Item* si); + +void +ivug_slider_item_image_size_get(Slide_Item* si, int *w, int *h); + +int +ivug_slider_item_zoom_level_get(Slide_Item* si); + +#ifdef __cplusplus +} +#endif + + + diff --git a/main/src/include/ivug-slider.h b/main/src/include/ivug-slider.h new file mode 100755 index 0000000..4ca46ee --- /dev/null +++ b/main/src/include/ivug-slider.h @@ -0,0 +1,132 @@ +/* + * Copyright 2012 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.tizenopensource.org/license + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __IVUG_SLIDER_H__ +#define __IVUG_SLIDER_H__ + +#include +#include "ivug-medialist.h" +#include "ivug-drm.h" + +typedef enum { + SLIDE_STATE_NONE = 0x00, + SLIDE_STATE_SET, // Thumbnail is displayed. + + SLIDE_STATE_DRM_CHECKING, // wait for drm popup + + SLIDE_STATE_READY, // Got original media + + SLIDE_STATE_LOADING, // Load main image or drm decryption. + SLIDE_STATE_LOADED, // Image is shown + +// Error state + SLIDE_STATE_NO_RIGHT, + SLIDE_STATE_ERROR, +} slide_state_t; + + +typedef enum { + SLIDE_TO_RIGHT = 0x00, + SLIDE_TO_LEFT, + SLIDE_INSTANTLY, +} slide_dir_t; + +typedef enum { + LONGTAP_ENDED, + LONGTAP_CANCELED, +} longtap_state; + + +/* + Slider signal list. + + "slider,clicked" : when click once + "slider,longpressed" : when long pressed on slider + "slider,clicked,icon" : video icon clicked. + "slider,item,changed" : + + "slider,item,state,changed" + "slider,item,deleted" +*/ + +#ifdef __cplusplus +extern "C" { +#endif + +Evas_Object* +ivug_slider_add(Evas_Object* parent); + +void +ivug_slider_start(Evas_Object *obj); + +Eina_Bool +ivug_slider_set_medialist(Evas_Object* obj, Media_List *mList, Media_Item *current); + +void +ivug_slider_set_item(Evas_Object* obj, Media_Item *item, slide_dir_t dir); + +/* + Delete current media item +*/ +void +ivug_slider_delete_item(Evas_Object* obj); + +Media_Item * +ivug_slider_get_item(Evas_Object* obj); + +slide_state_t +ivug_slider_get_state(Evas_Object* obj); + +/* + Go background - stop animation +*/ +void +ivug_slider_pause(Evas_Object* obj); + +/* + Go foreground - start animation +*/ +void +ivug_slider_resume(Evas_Object* obj); + +void +ivug_slider_skip(Evas_Object* obj); + +bool +ivug_slider_load(Evas_Object* obj); + +void +ivug_slider_dump_photocam(Evas_Object* obj); + +void +ivug_slider_set_menu_visibility(Evas_Object* obj, Eina_Bool bVisible); + +unsigned int +ivug_slider_zoom_level_get(Evas_Object *obj); + +void +ivug_slider_zoom_in(Evas_Object *obj); + +void +ivug_slider_zoom_out(Evas_Object *obj); + +#ifdef __cplusplus +} +#endif + + +#endif // __IVUG_SLIDER_H__ + diff --git a/main/src/include/ivug-string.h b/main/src/include/ivug-string.h new file mode 100755 index 0000000..77ea725 --- /dev/null +++ b/main/src/include/ivug-string.h @@ -0,0 +1,166 @@ +/* + * Copyright 2012 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.tizenopensource.org/license + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __IVUG_STRING_H__ +#define __IVUG_STRING_H__ + +#include +#include + +/* Original code is in appcore-common.h */ +#define gettext_noop(str) (str) /**< keyword for xgettext to extract translatable strings */ +#define N_(str) gettext_noop(str) /**< gettext_noop alias */ + + +#define LOCALE_PATH PREFIX"/res/locale" /*TODO!!!*/ + +#ifndef PACKAGE +#error PACKAGE is not defined +#endif + +#ifndef LOCALE_PATH +#error LOCALE_PATH is not defined +#endif + +//string +#define IVUG_TEXT_DOMAIN PACKAGE +#define IVUG_LOCALEDIR LOCALE_PATH + +/***********************************************/ +/* String has to be sorted in ascending order. */ +/***********************************************/ + +// Not yet translated + +#define IDS_DRM_INTERVAL_BASED_DAYS _("You can use %s for %d days. Would you like to open it now?") +#define IDS_DRM_TIME_BASED_GET _("%s is about to be locked. Do you want to get more licenses?") +#define IDS_DRM_COUNT_BASED_OPEN_ONE _("You have one more use of %s. Do you want to open it now?") +#define IDS_DRM_COUNT_BASED_OPEN_MANY _("You have %d more uses of %s. Do you want to open it now?") +#define IDS_DRM_COUNT_BASED_ONE_MORE_GET _("You have one more use of %s. Do you want to get more licenses?") +#define IDS_DRM_COUNT_BASED_NO_MORE_GET _("You have no more use of %s. Do you want to get more licenses?") +#define IDS_DRM_UNLOCK _("%s is currently locked. Do you want to unlock it now?") + +#define IDS_COLLABORATIVE_PLAY _("Collaborative play") + +#define IDS_CALLER_ID_NOTIFY _("Selected area wiil be applied to caller image") +#define IDS_CROP_NOTIFY _("Select image area") +#define IDS_CHANGE_NAME _("Change name") +#define IDS_MMS _("MMS") +#define IDS_SHARE_VIA _("Share via") +#define IDS_DO_NOT_SEND _("Do not send") +#define IDS_SEND _("Send") +#define IDS_ENTER_NAME _("Enter name") + +#define IDS_NULL _("") + +/* Registered string in STMS IV */ +#define IDS_ACCUMULATED_TIME (dgettext(IVUG_TEXT_DOMAIN, "IDS_IV_ACCUMULATED_TIME")) +#define IDS_ADDED (dgettext(IVUG_TEXT_DOMAIN, "IDS_IV_POP_ADDED")) +#define IDS_ALL_ALBUMS (dgettext(IVUG_TEXT_DOMAIN, "IDS_IV_HEADER_ALL_ALBUMS")) +#define IDS_ANY (dgettext(IVUG_TEXT_DOMAIN, "IDS_IV_BODY_ANY")) +#define IDS_AVAILABLE_USES (dgettext(IVUG_TEXT_DOMAIN, "IDS_IV_BODY_AVAILABLE_USES")) +#define IDS_BASIC (dgettext(IVUG_TEXT_DOMAIN, "IDS_IV_BODY_BASIC")) +#define IDS_CALLER_IMAGE (dgettext(IVUG_TEXT_DOMAIN, "IDS_IV_BODY_CALLER_IMAGE")) +#define IDS_COPY_TO_CLIPBOARD (dgettext(IVUG_TEXT_DOMAIN, "IDS_IV_OPT_COPY_TO_CLIPBOARD")) +#define IDS_COUNT (dgettext(IVUG_TEXT_DOMAIN, "IDS_IV_BODY_COUNT")) +#define IDS_CROP (dgettext(IVUG_TEXT_DOMAIN, "IDS_IV_BODY_CROP")) +#define IDS_DATE_CREATED (dgettext(IVUG_TEXT_DOMAIN, "IDS_IV_BODY_DATE_CREATED")) +#define IDS_DISPLAY (dgettext(IVUG_TEXT_DOMAIN, "IDS_IV_BODY_DISPLAY")) +#define IDS_ENTRY_IS_EMPTY (dgettext(IVUG_TEXT_DOMAIN, "IDS_IV_POP_ENTRY_IS_EMPTY")) +#define IDS_EXECUTE (dgettext(IVUG_TEXT_DOMAIN, "IDS_IV_BODY_EXECUTE")) +#define IDS_FORMAT (dgettext(IVUG_TEXT_DOMAIN, "IDS_IV_BODY_FILE_FORMAT")) +#define IDS_FILE_LOCATION (dgettext(IVUG_TEXT_DOMAIN, "IDS_IV_BODY_FILE_LOCATION")) +#define IDS_FILE_TRANSFER (dgettext(IVUG_TEXT_DOMAIN, "IDS_IV_OPT_FILE_TRANSFER")) +#define IDS_FORWARDING (dgettext(IVUG_TEXT_DOMAIN, "IDS_IV_BODY_FORWARDING")) +#define IDS_HOME_AND_LOCK_SCREEN_WALLPAPER (dgettext(IVUG_TEXT_DOMAIN, "IDS_IV_OPT_HOME_AND_LOCK_SCREEN_WALLPAPER")) +#define IDS_HOME_AND_LOCK_SCREENS (dgettext(IVUG_TEXT_DOMAIN, "IDS_IV_BODY_HOME_AND_LOCK_SCREENS")) +#define IDS_HOME_SCREEN (dgettext(IVUG_TEXT_DOMAIN, "IDS_IV_BODY_HOME_SCREEN")) +#define IDS_HOME_SCREEN_WALLPAPER (dgettext(IVUG_TEXT_DOMAIN, "IDS_IV_HEADER_HOME_SCREEN_WALLPAPER_ABB")) +#define IDS_IMPOSSIBLE (dgettext(IVUG_TEXT_DOMAIN, "IDS_IV_BODY_IMPOSSIBLE")) +#define IDS_INDIVIDUAL (dgettext(IVUG_TEXT_DOMAIN, "IDS_IV_BODY_INDIVIDUAL")) +#define IDS_INTERVAL (dgettext(IVUG_TEXT_DOMAIN, "IDS_IV_BODY_INTERVAL")) +#define IDS_INVALID_IMAGE_FILE (dgettext(IVUG_TEXT_DOMAIN, "IDS_IV_POP_INVALID_IMAGE_FILE")) +#define IDS_LATITUDE (dgettext(IVUG_TEXT_DOMAIN, "IDS_IV_BODY_LATITUDE")) +#define IDS_LOCK_SCREEN (dgettext(IVUG_TEXT_DOMAIN, "IDS_IV_BODY_LOCK_SCREEN")) +#define IDS_LOCK_SCREEN_WALLPAPER (dgettext(IVUG_TEXT_DOMAIN, "IDS_IV_HEADER_LOCK_SCREEN_WALLPAPER_ABB")) +#define IDS_LONGITUDE (dgettext(IVUG_TEXT_DOMAIN, "IDS_IV_BODY_LONGITUDE")) +#define IDS_MAX_CHAR_LENGTH_REACHED (dgettext(IVUG_TEXT_DOMAIN, "IDS_IV_POP_MAXIMUM_NUMBER_OF_CHARACTERS_HPD_REACHED")) +#define IDS_N_A (dgettext(IVUG_TEXT_DOMAIN, "IDS_IV_BODY_N_A")) +#define IDS_PERMISSION_DENIED (dgettext(IVUG_TEXT_DOMAIN, "IDS_IV_POP_PERMISSION_DENIED")) +#define IDS_POSSIBLE (dgettext(IVUG_TEXT_DOMAIN, "IDS_IV_BODY_POSSIBLE")) +#define IDS_PRINT (dgettext(IVUG_TEXT_DOMAIN, "IDS_IV_BODY_PRINT")) +#define IDS_PRINT_VIA_BLUETOOH (dgettext(IVUG_TEXT_DOMAIN, "IDS_IV_OPT_PRINT_VIA_BLUETOOTH")) +#define IDS_RESOLUTION (dgettext(IVUG_TEXT_DOMAIN, "IDS_IV_BODY_RESOLUTION")) +#define IDS_RIGHT_STATUS (dgettext(IVUG_TEXT_DOMAIN, "IDS_IV_BODY_RIGHT_STATUS")) +#define IDS_ROTATE_LEFT (dgettext(IVUG_TEXT_DOMAIN, "IDS_IV_OPT_ROTATE_LEFT")) +#define IDS_ROTATE_RIGHT (dgettext(IVUG_TEXT_DOMAIN, "IDS_IV_OPT_ROTATE_RIGHT")) +#define IDS_SD_CARD_REMOVED (dgettext(IVUG_TEXT_DOMAIN, "IDS_IV_POP_SD_CARD_REMOVED")) +#define IDS_SELECT_DEVICE (dgettext(IVUG_TEXT_DOMAIN, "IDS_IV_POP_SELECT_DEVICE")) +#define IDS_SERVER_NAME (dgettext(IVUG_TEXT_DOMAIN, "IDS_IV_BODY_SERVER_NAME")) +#define IDS_SET_AS (dgettext(IVUG_TEXT_DOMAIN, "IDS_IV_OPT_SET_AS")) +#define IDS_SET_WALLPAPER_FOR_HOME_SCREEN_AND_LOCK_SCREEN (dgettext(IVUG_TEXT_DOMAIN, "IDS_IV_POP_SET_WALLPAPER_FOR_HOME_SCREEN_AND_LOCK_SCREEN")) +#define IDS_SHARE (dgettext(IVUG_TEXT_DOMAIN, "IDS_IV_OPT_SHARE")) +#define IDS_SLIDE_SHOW (dgettext(IVUG_TEXT_DOMAIN, "IDS_IV_OPT_SLIDE_SHOW")) +#define IDS_TIMED_COUNT (dgettext(IVUG_TEXT_DOMAIN, "IDS_IV_BODY_TIMED_COUNT")) +#define IDS_TRIM (dgettext(IVUG_TEXT_DOMAIN, "IDS_IV_OPT_TRIM")) +#define IDS_UNLIMITED (dgettext(IVUG_TEXT_DOMAIN, "IDS_IV_BODY_UNLIMITED")) +#define IDS_VALIDITY (dgettext(IVUG_TEXT_DOMAIN, "IDS_IV_BODY_VALIDITY")) +#define IDS_VENDOR (dgettext(IVUG_TEXT_DOMAIN, "IDS_IV_BODY_VENDOR")) + + +// System string. + +#define IDS_APPLICATION_NOT_INSTALLED (dgettext("sys_string", "IDS_COM_BODY_APPLICATION_NOT_INSTALLED")) +#define IDS_BACK (dgettext("sys_string", "IDS_COM_BODY_BACK")) +#define IDS_CANCEL (dgettext("sys_string", "IDS_COM_SK_CANCEL")) +#define IDS_CLOSE (dgettext("sys_string", "IDS_COM_BODY_CLOSE")) +#define IDS_COPY (dgettext("sys_string", "IDS_COM_BODY_COPY")) +#define IDS_COPIED_TO_CLIPBOARD (dgettext("sys_string", "IDS_COM_POP_COPIED_TO_CLIPBOARD")) +#define IDS_DETAILS (dgettext("sys_string", "IDS_COM_BODY_DETAILS")) +#define IDS_DELETE_MSG (dgettext("sys_string", "IDS_COM_POP_DELETE_Q")) +#define IDS_DELETE (dgettext("sys_string", "IDS_COM_BODY_DELETE")) +#define IDS_DELETED (dgettext("sys_string", "IDS_COM_POP_DELETED")) +#define IDS_DONE (dgettext("sys_string", "IDS_COM_SK_DONE")) +#define IDS_DOWNLOAD (dgettext("sys_string", "IDS_COM_SK_DOWNLOAD")) +#define IDS_DOWNLOAD_FAILED (dgettext("sys_string", "IDS_COM_POP_DOWNLOAD_FAILED")) +#define IDS_EDIT (dgettext("sys_string", "IDS_COM_BODY_EDIT")) +#define IDS_ERROR (dgettext("sys_string", "IDS_COM_POP_ERROR")) +#define IDS_FAILED (dgettext("sys_string", "IDS_COM_POP_FAILED")) +#define IDS_FAVOURITES (dgettext("sys_string", "IDS_COM_BODY_FAVOURITES")) +#define IDS_LOADING (dgettext("sys_string", "IDS_COM_BODY_LOADING")) +#define IDS_LOCATION (dgettext("sys_string", "IDS_COM_BODY_LOCATION")) +#define IDS_MORE (dgettext("sys_string", "IDS_COM_BODY_MORE")) +#define IDS_MOVE (dgettext("sys_string", "IDS_COM_BODY_MOVE")) +#define IDS_NAME (dgettext("sys_string", "IDS_COM_BODY_DETAILS_NAME")) +#define IDS_NO (dgettext("sys_string", "IDS_COM_SK_NO")) +#define IDS_NO_NAME (dgettext("sys_string", "IDS_COM_BODY_NO_NAME")) +#define IDS_OK (dgettext("sys_string", "IDS_COM_SK_OK")) +#define IDS_PLAY (dgettext("sys_string", "IDS_COM_SK_PLAY")) +#define IDS_SAVE (dgettext("sys_string", "IDS_COM_SK_SAVE")) +#define IDS_SAVED (dgettext("sys_string", "IDS_COM_POP_SAVED")) +#define IDS_SET (dgettext("sys_string", "IDS_COM_SK_SET")) +#define IDS_SIZE (dgettext("sys_string", "IDS_COM_BODY_SIZE")) +#define IDS_SUCCESS (dgettext("sys_string", "IDS_COM_POP_SUCCESS")) +#define IDS_SYSTEM (dgettext("sys_string", "IDS_COM_BODY_SYSTEM")) +#define IDS_TIME (dgettext("sys_string", "IDS_COM_POP_TIME")) +#define IDS_TYPE (dgettext("sys_string", "IDS_COM_POP_TYPE")) +#define IDS_UNKNOWN (dgettext("sys_string", "IDS_COM_BODY_UNKNOWN")) +#define IDS_YES (dgettext("sys_string", "IDS_COM_SK_YES")) + + +#endif // __IVUG_STRING_H__ + + diff --git a/main/src/slider/ivug-slider-item.cpp b/main/src/slider/ivug-slider-item.cpp new file mode 100755 index 0000000..490bcc5 --- /dev/null +++ b/main/src/slider/ivug-slider-item.cpp @@ -0,0 +1,1203 @@ +/* + * Copyright 2012 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.tizenopensource.org/license + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "ivug-common.h" + +#include "ivug-slider-item.h" + +#include "ivug-image.h" +#include "ivug-drm.h" + +#include "ivug-config.h" + + +#define DEFAULT_THUMBNAIL_PATH IMAGE_PATH"/T01_Nocontents_broken.png" +#define DRM_NO_RIGHT_IMAGE_PATH IMAGE_PATH"/image_drm_no_rights.jpg" + +#define IVUG_SLIDER_EDJ EDJ_PATH"/ivug-slider.edj" + +#undef USE_IMAGE_THUMBNAIL +#define USE_VIDEO_THUMBNAIL + +/* + Use elm_icon istead of elm_image. elm_icon preserve image ratio. and seems more faster. +*/ + +// Forward declaration + +static bool +_show_thumbnail( Slide_Item* si, const char *filepath) +{ +// TODO : When image orientatin is not 0 degree, rotate thumbnail also + IV_ASSERT(si != NULL); + + if (si->thumbnail == NULL) + { + MSG_SITEM_FATAL("slide item or thumbnail object is NULL"); + return false; + } + + if ( filepath == NULL ) + { + // Set default filepath. + filepath = DEFAULT_THUMBNAIL_PATH; + } + + MSG_SITEM_MED("Set thumbnail : %s", ivug_get_filename(filepath)); + + if (ivug_is_file_exist(filepath) == false ) + { + MSG_SITEM_ERROR("Cannot find thumbnail : %s", filepath); + filepath = DEFAULT_THUMBNAIL_PATH; + } + + if (elm_icon_file_set(si->thumbnail, filepath, NULL) == EINA_FALSE) + { + MSG_SITEM_ERROR("Cannot load thumbnail : %s", filepath); + return false; + } + + evas_object_repeat_events_set(si->thumbnail, EINA_FALSE); + edje_object_signal_emit((si->layout), "elm,state,show_thumbnail", "slider"); + + return true; +} + +static bool +_hide_thumbnail(Slide_Item* si) +{ + IV_ASSERT(si != NULL); + + evas_object_repeat_events_set(si->thumbnail, EINA_TRUE); + + edje_object_signal_emit((si->layout), "elm,state,hide_thumbnail", "slider"); + + return true; +} + +static void _show_progressbar(Slide_Item *si) +{ + IV_ASSERT(si != NULL); + + if ( si->progress ) + { + elm_progressbar_pulse(si->progress, EINA_TRUE); //start pulse. + } + edje_object_signal_emit((si->layout), "elm,state,show,progress", "slider"); +} + +static void _hide_progressbar(Slide_Item *si) +{ + IV_ASSERT(si != NULL); + + if ( si->progress ) + { + elm_progressbar_pulse(si->progress, EINA_FALSE); //stop pulse. + } + edje_object_signal_emit((si->layout), "elm,state,hide,progress", "slider"); +} + + +static void _show_videoicon(Slide_Item *si) +{ + IV_ASSERT(si != NULL); + + edje_object_signal_emit((si->layout), "elm,state,show_icon", "slider"); // Hide video play icon +} + +static void _hide_videoicon(Slide_Item *si) +{ + IV_ASSERT(si != NULL); + + edje_object_signal_emit((si->layout), "elm,state,hide_icon", "slider"); // Hide video play icon + +// edje_object_signal_emit((si->layout), "elm,state,hide_icon", "slider"); // Hide video play icon +} + +static bool _start_drm_consume(Slide_Item *si) +{ + return true; +} + +static bool _stop_drm_consume(Slide_Item *si) +{ + return true; +} + +static bool _pause_drm_consume(Slide_Item *si) +{ + return true; +} + +static bool _resume_drm_consume(Slide_Item *si) +{ + return true; +} + + +static sitem_type_t _get_sitem_type(Media_Type mtype) +{ + switch(mtype) + { + case SLIDE_TYPE_IMAGE: + return SITEM_TYPE_IMAGE; + + case SLIDE_TYPE_VIDEO: + case SLIDE_TYPE_STREAMING: + return SITEM_TYPE_VIDEO; + + case SLIDE_TYPE_NONE: + case SLIDE_TYPE_UNKNOWN: + default: + return SITEM_TYPE_UNKNOWN; + } + + return SITEM_TYPE_UNKNOWN; +} + + + + +inline +void _call_user_callback(Slide_Item* si) +{ + if ( si->cb ) + { + (si->cb)(si->state, si, si->client_data); + } +} + + +static void +_photocam_loaded_cb(void *data, Evas_Object *obj, void *event_info) +{ + IV_ASSERT(data != NULL); + + Slide_Item* si = static_cast(data); + +//hide progress. + _hide_progressbar(si); + + if ( si->mitem == NULL) + { + MSG_SITEM_ERROR("Debug Me! Data item is NULL."); + return; + } + + Media_Data* mdata = ivug_medialist_get_data(si->mitem); + if(mdata == NULL) + { + MSG_SITEM_ERROR("ivug_medialist_get_data failed."); + si->state = SLIDE_STATE_ERROR; + return; + } + +#if 0 + typedef enum _Evas_Load_Error + { + EVAS_LOAD_ERROR_NONE = 0, /**< No error on load */ + EVAS_LOAD_ERROR_GENERIC = 1, /**< A non-specific error occurred */ + EVAS_LOAD_ERROR_DOES_NOT_EXIST = 2, /**< File (or file path) does not exist */ + EVAS_LOAD_ERROR_PERMISSION_DENIED = 3, /**< Permission deinied to an existing file (or path) */ + EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED = 4, /**< Allocation of resources failure prevented load */ + EVAS_LOAD_ERROR_CORRUPT_FILE = 5, /**< File corrupt (but was detected as a known format) */ + EVAS_LOAD_ERROR_UNKNOWN_FORMAT = 6 /**< File is not a known format */ + } Evas_Load_Error; /**< Load error you can get from loading of files - see evas_load_error_str() too */ +#endif + +// Evas_Load_Error error = static_cast(reinterpret_cast(event_info)); + Evas_Load_Error error = evas_object_image_load_error_get(ivug_image_internal_image_get(si->photocam)); + + if ( error != EVAS_LOAD_ERROR_NONE ) + { + MSG_SITEM_ERROR("Image loading failed. Error=%d File=%s", error, mdata->filepath); + si->state = SLIDE_STATE_ERROR; + + evas_object_hide(si->photocam); + + if ( error == EVAS_LOAD_ERROR_PERMISSION_DENIED) + { + _show_thumbnail(si, DRM_NO_RIGHT_IMAGE_PATH); + } + else + { + _show_thumbnail(si, DEFAULT_THUMBNAIL_PATH); + } + + _call_user_callback(si); + + return ; + } + + si->state = SLIDE_STATE_LOADED; + + int w, h; + + ivug_image_image_size_get(si->photocam, &w, &h); + + if (mdata->slide_type == SLIDE_TYPE_VIDEO || mdata->slide_type == SLIDE_TYPE_STREAMING) //if slide type is video, + { + // TODO : Never get here.. + MSG_SITEM_FATAL("slide type is video. thumbnail image "); + return; + } + + evas_object_show(obj); //photocam show. + +//hide thumbnail. + MSG_SITEM_HIGH("Thumbnail Hide"); + +#ifdef USE_IMAGE_THUMBNAIL + _hide_thumbnail(si); +#endif + + _call_user_callback(si); + + MSG_SITEM_HIGH("Photocam Pre-loaded. File=%s", ivug_get_filename(mdata->filepath)); +} + + +static bool _set_mitem(Slide_Item* si, Media_Item *item) +{ + Media_Data *mdata = ivug_medialist_get_data(item); + IV_ASSERT(mdata != NULL); + + si->mitem = item; + + si->type = _get_sitem_type(mdata->slide_type); + + evas_object_smart_callback_add(si->photocam, "loaded", _photocam_loaded_cb, si); + + if ( si->type == SITEM_TYPE_IMAGE ) + { + _hide_videoicon(si); + +#ifdef USE_IMAGE_THUMBNAIL +// Set thumbnail + _show_thumbnail(si, mdata->thumbnail_path); +#endif + edje_object_part_swallow(si->layout, "slider.contents", si->photocam); + + MSG_SITEM_HIGH("SItem type is IMAGE"); + } + else if ( si->type == SITEM_TYPE_VIDEO ) + { + elm_icon_file_set(si->vIcon, EDJ_PATH"/ivug-icons.edj", "btn.video.play"); + _show_thumbnail(si, mdata->thumbnail_path); + _show_videoicon(si); + + MSG_SITEM_HIGH("SItem type is VIDEO"); + } + else + { + MSG_SITEM_HIGH("SItem type is UNKNOWN"); + _show_thumbnail(si, mdata->thumbnail_path); + _hide_videoicon(si); + } + + switch(mdata->slide_type) + { + case SLIDE_TYPE_IMAGE: + MSG_SITEM_HIGH("Set image. %s", ivug_get_filename(mdata->filepath)); + + if(mdata->bIsDRMContent == EINA_FALSE) + { + si->state = SLIDE_STATE_READY; + } + else + { + si->state = SLIDE_STATE_DRM_CHECKING; + } + break; + + case SLIDE_TYPE_VIDEO: + case SLIDE_TYPE_STREAMING: + MSG_SITEM_HIGH("Set video. %s", ivug_get_filename(mdata->filepath)); + + si->state = SLIDE_STATE_READY; // Video dont need to load photocam + break; + + case SLIDE_TYPE_UNKNOWN: + MSG_SITEM_ERROR("Unknown image. %s", ivug_get_filename(mdata->filepath)); + + si->state = SLIDE_STATE_ERROR; + + break; + + default: + MSG_SITEM_ERROR("slide type invaild. Type=%d", mdata->slide_type); + si->state = SLIDE_STATE_ERROR; + return true; + break; + + } + + return true; +} + + +static bool _unset_mitem(Slide_Item* si) +{ + Media_Data *mdata = ivug_medialist_get_data(si->mitem); + + si->state = SLIDE_STATE_NONE; + + if ( mdata == NULL ) + { + MSG_SITEM_ERROR("Data is NULL"); + return true; + } + + MSG_SITEM_HIGH("Clear Image. %s", ivug_get_filename(mdata->filepath)); + +// Unswallow photocam/videocam + edje_object_part_unswallow(si->layout, edje_object_part_swallow_get(si->layout, "slider.contents")); + + switch(si->type) + { + case SITEM_TYPE_IMAGE: + evas_object_hide(si->photocam); + evas_object_smart_callback_del_full(si->photocam, "loaded", _photocam_loaded_cb, si); + ivug_image_unset(si->photocam); //init photocam. + break; + case SITEM_TYPE_VIDEO: + break; + default: + break; + } + +// Resetting GUI + _hide_progressbar(si); + _hide_thumbnail(si); + _hide_videoicon(si); + + si->type = SITEM_TYPE_UNKNOWN; + si->mitem = NULL; + + MSG_SITEM_HIGH("Slider Item is cleared."); + + return true; +} + + +static void _on_event_mouse_down(void *data, Evas *evas, Evas_Object *obj, void *event_info) +{ + MSG_SLIDER_HIGH("Event layer clicked : %s Layer=%d", evas_object_name_get(obj), evas_object_layer_get(obj)); +} + + +Slide_Item* +ivug_slider_item_add(Evas_Object *slider) +{ + Slide_Item* si = NULL; + + PERF_CHECK_BEGIN(LVL6, "init variable"); + + //create item + si = (Slide_Item*)calloc(1, sizeof (Slide_Item)); + + if ( si == NULL ) + { + MSG_SITEM_FATAL("Cannot allocated memory : %d.", sizeof (Slide_Item)); + return NULL; + } + + si->state = SLIDE_STATE_NONE; //set slide state + si->type = SITEM_TYPE_UNKNOWN; + + PERF_CHECK_END(LVL6, "init variable"); + +//Create the slider item layout + PERF_CHECK_BEGIN(LVL6, "create slider item layout"); + + Evas_Object *layout = edje_object_add(evas_object_evas_get(slider)); + if(edje_object_file_set(layout, IVUG_SLIDER_EDJ, "slider") == EINA_FALSE) + { + MSG_SITEM_ERROR("Cannot load file : %s", IVUG_SLIDER_EDJ); + free(si); + + return NULL; + } + + evas_object_name_set(layout, "Slider item edj"); + evas_object_event_callback_add(layout, EVAS_CALLBACK_MOUSE_DOWN, _on_event_mouse_down, NULL); + + si->layout = layout; + + PERF_CHECK_END(LVL6, "create slider item layout"); + +//set thumbnail. + PERF_CHECK_BEGIN(LVL6, "set thumbnail"); + + si->thumbnail = elm_icon_add(slider); + evas_object_name_set(si->thumbnail, "Thumbnail"); + evas_object_event_callback_add(si->thumbnail, EVAS_CALLBACK_MOUSE_DOWN, _on_event_mouse_down, NULL); + + edje_object_part_swallow(si->layout, "slider.thumbnail", si->thumbnail); + + PERF_CHECK_END(LVL6, "set thumbnail"); + +//set progress + PERF_CHECK_BEGIN(LVL6, "set progress"); + + PERF_CHECK_BEGIN(LVL7, "elm_progressbar_add"); + si->progress = elm_progressbar_add(slider); + elm_object_style_set(si->progress, "list_process"); + elm_progressbar_pulse(si->progress, EINA_FALSE); + PERF_CHECK_END(LVL7, "elm_progressbar_add"); + + PERF_CHECK_BEGIN(LVL7, "swallow progress"); + edje_object_part_swallow(si->layout, "slider.progress", si->progress); + PERF_CHECK_END(LVL7, "swallow progress"); + + PERF_CHECK_END(LVL6, "set progress"); + +//Add the photocam + PERF_CHECK_BEGIN(LVL6, "ivug_image_create"); + + si->photocam = ivug_image_create(si->layout); + evas_object_name_set(si->photocam, "photocam"); + + PERF_CHECK_END(LVL6, "ivug_image_create"); + + PERF_CHECK_BEGIN(LVL6, "video icon"); + +// z-order be decided along added order + evas_object_smart_member_add(si->layout, slider); + + si->vIcon = elm_icon_add(slider); + elm_icon_file_set(si->vIcon, EDJ_PATH"/ivug-icons.edj", "btn.video.play"); + + evas_object_name_set(si->vIcon, "video icon"); + evas_object_event_callback_add(si->vIcon, EVAS_CALLBACK_MOUSE_DOWN, _on_event_mouse_down, NULL); + + edje_object_part_swallow(si->layout, "slider.icon", si->vIcon); +// evas_object_smart_member_add(si->vIcon, slider); + PERF_CHECK_END(LVL6, "video icon"); + + si->bMenuVisible = true; // Default visibility is true + + MSG_SITEM_HIGH("Creating slider item. 0x%08x.", si); + + return si; +} + + +void +ivug_slider_item_resize(Slide_Item* si, int w, int h) +{ + IV_ASSERT(si != NULL ); + + if ( si->w == w && si->h == h ) return; + // TODO : Impelement + MSG_SITEM_HIGH("SLIDER Resize to WH(%d,%d)", w, h ); + +// w,h is not Image's scale, but Object's scale + si->w = w; + si->h = h; + +// MSG_SITEM_HIGH("resize layout: %d, %d", si->w, si->h); + evas_object_resize(si->layout, si->w, si->h); + +} + + +void ivug_slider_item_move(Slide_Item* si, int x, int y) +{ + IV_ASSERT(si != NULL ); + + MSG_SITEM_MED("SLIDER Move to XY(%d,%d)", x, y); + + if ( si->x == x && si->y == y) return; + + //photocam + si->x = x; + si->y = y; + + if ( si->w == 0 || si->h == 0) return; + + evas_object_move(si->layout, x, y); + +// Center align +// evas_object_move(); +// si->vIcon + +} + +void ivug_slider_item_del(Slide_Item* si) +{ + IV_ASSERT(si != NULL ); + + MSG_SITEM_HIGH("Removing Slider Item"); + + ivug_slider_item_stop(si); + + si->mitem = NULL; // for error handling + + if (si->photocam) + { + evas_object_del(si->photocam); + si->photocam = NULL; + } + + if (si->thumbnail) + { + evas_object_del(si->thumbnail); + si->thumbnail = NULL; + } + + if (si->progress) + { + evas_object_del(si->progress); + si->progress = NULL; + } + + if(si->layout) + { + evas_object_del(si->layout); + si->layout = NULL; + } + + if ( si->vIcon ) + { + evas_object_del(si->vIcon); + si->vIcon = NULL; + } + + free(si); + + si = NULL; + + MSG_SITEM_HIGH("Removed Slider Item"); + +} + +void ivug_slider_item_hide(Slide_Item* si) +{ + IV_ASSERT(si != NULL ); + + MSG_SITEM_HIGH("Hide slide item"); + evas_object_hide(si->layout); +} + + +void ivug_slider_item_show(Slide_Item* si) +{ + IV_ASSERT(si != NULL ); + + MSG_SITEM_HIGH("Show slide item"); + evas_object_show(si->layout); +} + + +void +ivug_slider_item_clip_set(Slide_Item* si, Evas_Object *clipper) +{ + IV_ASSERT(si != NULL ); +// no need to check layout is NULL + int x, y, w, h; + + evas_object_geometry_get(clipper, &x, &y, &w, &h); + + MSG_SITEM_HIGH("Clip SET!! Geometry(%d,%d,%d,%d)", x, y, w, h); + + evas_object_clip_set(si->layout, clipper); +} + +void +ivug_slider_item_clip_unset(Slide_Item* si) +{ + IV_ASSERT(si != NULL ); +// no need to check layout is NULL + evas_object_clip_unset(si->layout); +} + +bool +ivug_slider_item_data_set(Slide_Item* si, Media_Item *item) +{ + IV_ASSERT(si != NULL ); + + if ( item == NULL ) + { + if ( si->state == SLIDE_STATE_NONE ) + { + MSG_SITEM_WARN("Slide item is already cleared. just return. Mitem=0x%08x", si->mitem); + return true; + } + +// Remove callback because when photocam_file_set(with file name=NULL) trigger "loaded" callback + _unset_mitem(si); + } + else + { + if ( si->state != SLIDE_STATE_NONE ) + { + MSG_SITEM_WARN("State is not none. State=%d Unset First", si->state); + _unset_mitem(si); + } + + _set_mitem(si, item); + } + + return true; +} + + +// Ready to Loading +bool +ivug_slider_item_load(Slide_Item *si) +{ + IV_ASSERT(si != NULL); + + if (si->state != SLIDE_STATE_READY) + { + MSG_SITEM_ERROR("Invalid state : %d", si->state); + return false; + } + + Media_Data *mdata = ivug_medialist_get_data(si->mitem); + IV_ASSERT(mdata != NULL); + + if(mdata->filepath == NULL) + { + MSG_SITEM_ERROR("file path is NULL"); + return false; + } + + MSG_SITEM_HIGH("Load file. %s", ivug_get_filename(mdata->filepath)); + + char path[IVUG_MAX_FILE_PATH_LEN] = {0,}; + + if ( mdata->bIsDRMContent == EINA_TRUE ) + { + _hide_progressbar(si); + + MSG_SITEM_ERROR("Image loading failed. RO expired File=%s", mdata->filepath); + si->state = SLIDE_STATE_ERROR; + + evas_object_hide(si->photocam); + _show_thumbnail(si, DRM_NO_RIGHT_IMAGE_PATH); + + _call_user_callback(si); + + return false; + } + else + { + strncpy(path, mdata->filepath, sizeof(path)); + } + + switch(mdata->slide_type) + { + case SLIDE_TYPE_IMAGE: + { + si->state = SLIDE_STATE_LOADING; + + if (ivug_image_file_set(si->photocam, path, NULL) != EVAS_LOAD_ERROR_NONE) + { + MSG_SITEM_ERROR("Failed photocam to set file file=%s", path); + si->state = SLIDE_STATE_ERROR; + + _call_user_callback(si); + return false; + } + + return true; + + } + break; + case SLIDE_TYPE_VIDEO: + si->state = SLIDE_STATE_LOADED; + + break; + case SLIDE_TYPE_STREAMING: + si->state = SLIDE_STATE_LOADED; + return true; + + break; + + default: + MSG_SITEM_ERROR("slide type invaild. Type=%d", mdata->slide_type); + return false; + break; + } + + return true; +} + +void ivug_slider_item_play(Slide_Item* si) +{ + IV_ASSERT(si != NULL ); + + Media_Data *mdata = ivug_medialist_get_data(si->mitem); + + MSG_SITEM_HIGH("Start sitem. %s", mdata->filepath); + + if ( si->state != SLIDE_STATE_LOADED ) + { + MSG_SITEM_ERROR("Play. but state is %d", si->state); + } + + if(mdata->bIsDRMContent == true) + { + _start_drm_consume(si); + } + +// Start animation + if ( si->type == SITEM_TYPE_IMAGE ) + { + ivug_image_animated_set(si->photocam, EINA_TRUE); + } +} + +void ivug_slider_item_stop(Slide_Item* si) +{ + IV_ASSERT(si != NULL ); + + if ( si->state != SLIDE_STATE_LOADED ) + { + // When very first/last image and invalid + return; + } + + Media_Data *mdata = ivug_medialist_get_data(si->mitem); + MSG_SITEM_HIGH("Stop sitem. %s", mdata->filepath); + + if(mdata->bIsDRMContent == true) + { + _stop_drm_consume(si); + } + + if (si->type == SITEM_TYPE_VIDEO) + { + // Nothing to do + } + else if ( si->type == SITEM_TYPE_IMAGE ) + { + ivug_image_animated_set(si->photocam, EINA_FALSE); + } +} + + +void ivug_slider_item_pause(Slide_Item* si) +{ + IV_ASSERT(si != NULL ); + + if ( si->state != SLIDE_STATE_LOADED ) + { + // When very first/last image and invalid + return; + } + + Media_Data *mdata = ivug_medialist_get_data(si->mitem); + MSG_SITEM_HIGH("Pause sitem. %s", mdata->filepath); + + if(mdata->bIsDRMContent == true) + { + _pause_drm_consume(si); + } + + if (si->type == SITEM_TYPE_VIDEO) + { + // Nothing to do + } + else if ( si->type == SITEM_TYPE_IMAGE ) + { + ivug_image_animated_set(si->photocam, EINA_FALSE); + } +} + +void ivug_slider_item_resume(Slide_Item* si) +{ + IV_ASSERT(si != NULL ); + + if ( si->state != SLIDE_STATE_LOADED ) + { + // When very first/last image and invalid + return; + } + + Media_Data *mdata = ivug_medialist_get_data(si->mitem); + MSG_SITEM_HIGH("Resume sitem. %s", mdata->filepath); + + if(mdata->bIsDRMContent == true) + { + _resume_drm_consume(si); + } + + if (si->type == SITEM_TYPE_IMAGE) + { + ivug_image_animated_set(si->photocam, EINA_TRUE); + } +} + +bool +ivug_slider_item_set_callback(Slide_Item* si, OnSliderStateChanged cb, void *data) +{ + IV_ASSERT(si != NULL ); + + si->cb = cb; + si->client_data = data; + + return true; +} + +const Media_Item * +ivug_slider_item_data_get(Slide_Item *si) +{ + IV_ASSERT(si != NULL); + + return si->mitem; +} + +// Photocam +bool +ivug_slider_item_region_size_get(Slide_Item* si, int *x, int *y, int *w, int *h) +{ + IV_ASSERT(si != NULL ); + + if ( si->mitem == NULL) + { + MSG_SITEM_ERROR("Debug Me! Data item is NULL."); + return false; + } + + Media_Data *mdata = ivug_medialist_get_data(si->mitem); + + if ( mdata == NULL ) + { + MSG_SITEM_ERROR("slide type is NULL. Item=0x%08x", si); + return false; // TODO : Temp.. + } + + switch(si->type) + { + case SITEM_TYPE_IMAGE: + { + ivug_image_region_get(si->photocam, x, y, w, h); + } + break; + + case SITEM_TYPE_VIDEO: + { + return false; + } + break; + + case SITEM_TYPE_UNKNOWN: + return false; + break; + + default: + MSG_SITEM_ERROR("Unknwon type: %d", si->type); + return false; + break; + } + + return true; +} + + + +void +ivug_slider_item_hold_set(Slide_Item* si, Eina_Bool hold) +{ + IV_ASSERT(si != NULL ); + + switch(si->type) + { + case SITEM_TYPE_IMAGE: + { + ivug_image_hold_set(si->photocam, hold); + } + break; + + case SITEM_TYPE_VIDEO: + { + + } + break; + + case SITEM_TYPE_UNKNOWN: + default: + MSG_SITEM_ERROR("Unknwon type: %d", si->type); + break; + } + + +} + + +void +ivug_slider_item_zoom_reset(Slide_Item* si, Eina_Bool bAnim, int center_x, int center_y) +{ + IV_ASSERT(si != NULL ); + + switch(si->type) + { + case SITEM_TYPE_IMAGE: + { + Evas_Point pt; + + pt.x = center_x; + pt.y = center_y; + + ivug_image_zoom_reset(si->photocam, &pt); + } + break; + + case SITEM_TYPE_VIDEO: + { + + } + break; + + case SITEM_TYPE_UNKNOWN: + break; + + default: + MSG_SITEM_ERROR("Unknwon type: %d", si->type); + break; + + } + +} + + +void +ivug_slider_item_zoom_set(Slide_Item* si, double zoom, int center_x, int center_y) +{ + IV_ASSERT(si != NULL ); + + switch(si->type) + { + case SITEM_TYPE_IMAGE: + { + Evas_Point Center; + + Center.x = center_x; + Center.y = center_y; + ivug_image_zoom_set(si->photocam, zoom, &Center); + + } + break; + + case SITEM_TYPE_VIDEO: + break; + + case SITEM_TYPE_UNKNOWN: + break; + + default: + MSG_SITEM_ERROR("Unknwon type: %d", si->type); + break; + + } + +} + +double +ivug_slider_item_zoom_get(Slide_Item* si) +{ + IV_ASSERT(si != NULL ); + + double ret = 1.0; + + switch(si->type) + { + case SITEM_TYPE_IMAGE: + { + ret = ivug_image_zoom_get(si->photocam); + } + break; + + case SITEM_TYPE_VIDEO: + break; + + case SITEM_TYPE_UNKNOWN: + break; + + default: + MSG_SITEM_ERROR("Unknwon type: %d", si->type); + break; + + } + + + return ret; +} + +bool +ivug_slider_item_icon_click_check(Slide_Item *si, int x, int y) +{ + MSG_SITEM_HIGH("Check play icon clicked. SI=0x%08x, XY(%d,%d)", si, x, y); + + IV_ASSERT(si != NULL ); + + Media_Data *mdata = ivug_medialist_get_data(si->mitem); + + if ( mdata == NULL ) + { + MSG_SITEM_ERROR("Debug Me! Data item is NULL."); + return false; + } + + if ( mdata->slide_type == SLIDE_TYPE_VIDEO || mdata->slide_type == SLIDE_TYPE_STREAMING ) + { + if (si->vIcon) + { + Evas_Coord ix,iy,iw,ih; + + evas_object_geometry_get(si->vIcon, &ix, &iy, &iw, &ih); + + bool bInside = !( (x) > (ix + iw) || (x) < (ix) + || (y) > (iy + iw) || (y) < (iy) ); + + MSG_SITEM_HIGH("Item XYWH(%d,%d,%d,%d) XY(%d,%d) bInside=%d", ix,iy,iw,ih, x, y, bInside); + + return bInside; + } + } + + MSG_SITEM_HIGH("Slide type = %d", mdata->slide_type); + return false; +} + +drm_data_t * ivug_slider_item_check_drm_constraint(Slide_Item *si) +{ + IV_ASSERT(si != NULL); + + Media_Data *mdata = ivug_medialist_get_data(si->mitem); + if(mdata == NULL) + { + MSG_SLIDER_ERROR("mdata is NULL"); + return NULL; + } + + if(mdata->bIsDRMContent == EINA_FALSE) + { + MSG_SLIDER_HIGH("It is not DRM file, path = %s", mdata->filepath); + return NULL; + } + + MSG_SITEM_HIGH("before check valid"); + if(ivug_drm_has_valid_ro(mdata->filepath) == 0) + { + MSG_SLIDER_HIGH("RO is invalid, path = %s", mdata->filepath); + si->state = SLIDE_STATE_ERROR; + _show_thumbnail(si, DRM_NO_RIGHT_IMAGE_PATH); + evas_object_smart_callback_call(si->photocam, "loaded", (void *)EVAS_LOAD_ERROR_PERMISSION_DENIED); + //for lauch WAP purchase page + drm_data_t *result = (drm_data_t *)calloc(1, sizeof(drm_data_t)); + result->constraints = IVUG_DRM_RESULT_LIMITED; + result->data = -1; + return result; + } + MSG_SITEM_HIGH("RO is valid, path = %s", mdata->filepath); + + return ivug_drm_check_constraint(mdata->filepath); +} + + +// Video specific APIs + +void ivug_slider_item_video_play(Slide_Item* si) +{ + IV_ASSERT(si != NULL ); + + MSG_SITEM_HIGH("Start Video play"); + + if (si->type == SITEM_TYPE_VIDEO) + { + + } + +} + + +void ivug_slider_item_video_pause(Slide_Item* si) +{ + IV_ASSERT(si != NULL ); + + MSG_SITEM_HIGH("Pause Video play"); + + if (si->type == SITEM_TYPE_VIDEO) + { + } +} + + +Eina_Bool ivug_slider_item_video_is_playing(Slide_Item* si) +{ + return false; + + if (si->type == SITEM_TYPE_VIDEO ) + { + + } + + return false; + +} + +void ivug_slider_item_hide_menu(Slide_Item* si) +{ + IV_ASSERT(si != NULL ); + + MSG_SITEM_HIGH("Hide menu"); + + si->bMenuVisible = false; + + return ; +} + + +void ivug_slider_item_show_menu(Slide_Item* si) +{ + IV_ASSERT(si != NULL ); + + MSG_SITEM_HIGH("Show menu"); + + si->bMenuVisible = true; + + return ; +} + +Evas_Object * +ivug_slider_item_image_get(Slide_Item* si) +{ + IV_ASSERT(si != NULL ); + + if ( (si->type == SITEM_TYPE_IMAGE) && (si->state == SLIDE_STATE_LOADED) ) + { + return ivug_image_internal_image_get(si->photocam); + } + + return NULL; + +} + + +void ivug_slider_item_image_size_get(Slide_Item* si, int *w, int *h) +{ + IV_ASSERT(si != NULL ); + + if ( (si->type == SITEM_TYPE_IMAGE) && (si->state == SLIDE_STATE_LOADED) ) + { + ivug_image_image_size_get(si->photocam, w, h); + } +} + diff --git a/main/src/slider/ivug-slider-mouse.cpp b/main/src/slider/ivug-slider-mouse.cpp new file mode 100755 index 0000000..78f9f04 --- /dev/null +++ b/main/src/slider/ivug-slider-mouse.cpp @@ -0,0 +1,819 @@ +/* + * Copyright 2012 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.tizenopensource.org/license + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "ivug-common.h" +#include "ivug-slider-item.h" +#include "ivug-slider.h" + +#include "ivug-slider-priv.h" +#include "ECoreAnimator.h" + +#define LOGNTAP_THRESHOLD (100) // allow moving distance(pixel) + +#define LOG_LVL DBG_MSG_LVL_HIGH +#define LOG_CAT "IV-SMOUSE" + + +void +_ivug_slider_pass_event_to_item(struct Smart_Data *sd, Eina_Bool bPass) +{ + sd->bPassEvent = bPass; + + if ( bPass == EINA_TRUE) + { + MSG_SLIDER_MED("Photocam can get Event"); + } + else + { + MSG_SLIDER_MED("Photocam can not get Event"); + } + + for (int i = 0; i < MAX_SLIDE; i++) + { + ivug_slider_item_hold_set(sd->slide[i], !bPass); + } +} + +#define _ivug_slider_edge_state_get(si) __ivug_slider_edge_state_get(si, __func__, __LINE__) + +slide_edge_t __ivug_slider_edge_state_get(Slide_Item *si, const char *func, int line) +{ + int nx, ny, nw, nh; + + slide_edge_t result = EDGE::SLIDE_NO_EDGE; + + if ( ivug_slider_item_region_size_get(si, &nx, &ny, &nw, &nh) == false) + { + // false means video file item. in this case, no photocam exists. + MSG_HIGH("[%s:%4d] Slide fit. Thumbnail only", func, line); + result = EDGE::SLIDE_FIT; + + return result; + } + else + { + if ( nw <= (si->w + IMAGE_SCROLL_MARGIN) && (nh <= si->h + IMAGE_SCROLL_MARGIN)) + { + MSG_HIGH("[%20s:%4d] Slide fit", func, line); + result = EDGE::SLIDE_FIT; + } + else + { + if ( nx >= si->x - IMAGE_MOVE_MARGIN) + { + MSG_HIGH("[%20s:%4d] image edge left. N(%d,%d) Si(%d,%d)", func, line, nx, nw, si->x, si->w); + + result = (result | EDGE::SLIDE_LEFT_EDGE); + } + + if ( nx + nw <= si->x + si->w + IMAGE_MOVE_MARGIN) + { //edge right + MSG_HIGH("[%20s:%4d] image edge right. N(%d,%d) Si(%d,%d)", func, line, nx, nw, si->x, si->w); + result = (result | EDGE::SLIDE_RIGHT_EDGE); + } +#if UNUSED + if ( ny >= si->y ) + { + MSG_HIGH("[%20s:%4d] image edge top", func, line); + result = (result | EDGE::SLIDE_TOP_EDGE); + } + + if ( ny + nh <= si->y + si->h) + { //edge right + MSG_HIGH("[%20s:%4d] image edge bottom", func, line); + result = (result | EDGE::SLIDE_BOTTOM_EDGE); + } +#endif + + } + } + + if ( result == EDGE::SLIDE_NO_EDGE ) + { + MSG_HIGH("[%20s:%4d] image over screen. Edge=%d N(%d,%d,%d,%d) Si(%d,%d,%d,%d)", func, line, result, nx, ny, nw, nh, si->x, si->y, si->w, si->h); + } + + return result; +} + +static void _put_originate(struct Smart_Data *sd, shift_direction_t dir, int momentum) +{ + if ( dir == SLIDE_SHIFT_TO_LEFT ) + { + if ( sd->slide[PREV_SLIDE]->state == SLIDE_STATE_NONE ) + { + dir = SLIDE_SHIFT_NONE; + } + } + + if ( dir == SLIDE_SHIFT_TO_RIGHT ) + { + if ( sd->slide[NEXT_SLIDE]->state == SLIDE_STATE_NONE ) + { + dir = SLIDE_SHIFT_NONE; + } + } + + int src_x, dst_x; + + switch(dir) + { + case SLIDE_SHIFT_TO_LEFT: + src_x = sd->slide[CENTER_SLIDE]->x; + dst_x = sd->x + sd->slide[CENTER_SLIDE]->w + IMAGE_BETWEEN_MARGIN; + + MSG_HIGH("Scroll --->. Move from %d, %d", src_x, dst_x); + + _ivug_slider_start_slide(sd, src_x, dst_x, momentum); + break; + + case SLIDE_SHIFT_TO_RIGHT: + src_x = sd->slide[CENTER_SLIDE]->x; + dst_x = sd->x -sd->slide[CENTER_SLIDE]->w - IMAGE_BETWEEN_MARGIN; + + MSG_HIGH("Scroll <---. Move from %d, %d", src_x, dst_x); + + _ivug_slider_start_slide(sd, src_x, dst_x, momentum); + break; + + case SLIDE_SHIFT_NONE: + src_x = sd->slide[CENTER_SLIDE]->x; + dst_x = sd->x; + + MSG_HIGH("Scroll to center. Move from %d, %d", src_x , dst_x); + + if (src_x == dst_x ) + { + MSG_SLIDER_WARN("No need to animation"); + return ; + } + // Defaut velocity + _ivug_slider_start_slide(sd, src_x, dst_x, ANIN_VELOCITY); + + break; + } + +} + +shift_direction_t _get_shift_direction(struct Smart_Data *sd) +{ +#define SHIFT_THRESHOLD (0.0f) + + Slide_Item* si = sd->slide[CENTER_SLIDE]; + + if ( abs( si->x - sd->x ) < 10 ) + { + MSG_HIGH("Shift None. si->x=%d sd->x=%d", si->x, sd->x); + return SLIDE_SHIFT_NONE; + } + + if ( (si->x - sd->x) > sd->w * SHIFT_THRESHOLD ) + { + // Scroll to ---> + MSG_HIGH("Shift ---->. si->x=%d sd->x=%d", si->x, sd->x); + return SLIDE_SHIFT_TO_LEFT; + } + else if ((si->x - sd->x) + si->w < sd->w * (1.0f - SHIFT_THRESHOLD) ) + { + // Scroll to <--- + MSG_HIGH("Shift <----. si->x=%d sd->x=%d", si->x, sd->x); + return SLIDE_SHIFT_TO_RIGHT; + } + + return SLIDE_SHIFT_NONE; + +} + + +Evas_Event_Flags _zoom_start(void *data, void *event_info) +{ + Elm_Gesture_Zoom_Info *p = (Elm_Gesture_Zoom_Info *) event_info; + MSG_LOW("zoom start <%d,%d> <%f>", p->x, p->y, p->zoom); + + struct Smart_Data *sd = (struct Smart_Data *) evas_object_smart_data_get((Evas_Object *)data); + Slide_Item* si = sd->slide[CENTER_SLIDE]; + + MSG_HIGH("%s MoveX=%d", __func__, si->x); + + sd->bZooming = false; + + if ( abs(si->x - sd->x) < IMAGE_MOVE_MARGIN) + { + _ivug_slider_slide_move(sd, 0, si->y); // Move to Center + _ivug_slider_pass_event_to_item(sd, EINA_TRUE); + sd->bZooming = true; + } + + return EVAS_EVENT_FLAG_NONE; +} + +Evas_Event_Flags _zoom_move(void *data, void *event_info) +{ + Elm_Gesture_Zoom_Info *p = (Elm_Gesture_Zoom_Info *) event_info; + MSG_LOW("zoom move <%d,%d> <%f>", p->x, p->y, p->zoom); + + struct Smart_Data *sd = (struct Smart_Data *) evas_object_smart_data_get((Evas_Object *)data); + Slide_Item* si = sd->slide[CENTER_SLIDE]; + + if ( sd->bZooming == false ) return EVAS_EVENT_FLAG_NONE; + + MSG_MED("%s MoveX=%d", __func__, si->x); + + return EVAS_EVENT_FLAG_NONE; +} + +Evas_Event_Flags _zoom_end(void *data, void *event_info) +{ + Elm_Gesture_Zoom_Info *p = (Elm_Gesture_Zoom_Info *) event_info; + MSG_LOW("zoom end <%d,%d> <%f>", p->x, p->y, p->zoom); + + struct Smart_Data *sd = (struct Smart_Data *) evas_object_smart_data_get((Evas_Object *)data); + Slide_Item* si = sd->slide[CENTER_SLIDE]; + + if ( sd->bZooming == false ) + { +// Flick image + shift_direction_t dir = _get_shift_direction(sd); + _put_originate(sd, dir, ANIN_VELOCITY); + + return EVAS_EVENT_FLAG_NONE; + } + + MSG_HIGH("%s. CenteSize WH(%d,%d)", __func__, si->w, si->h); // Si->w,h didnot change. after zoom + + sd->edge = _ivug_slider_edge_state_get(si); // Update Edge + + return EVAS_EVENT_FLAG_NONE; +} + +Evas_Event_Flags _zoom_abort(void *data, void *event_info) +{ + Elm_Gesture_Zoom_Info *p = (Elm_Gesture_Zoom_Info *) event_info; + MSG_LOW("zoom abort <%d,%d> <%f>", p->x, p->y, p->zoom); + + struct Smart_Data *sd = (struct Smart_Data *) evas_object_smart_data_get((Evas_Object *)data); + Slide_Item* si = sd->slide[CENTER_SLIDE]; + + if ( sd->bZooming == false ) + { +// Flick image + shift_direction_t dir = _get_shift_direction(sd); + _put_originate(sd, dir, ANIN_VELOCITY); + + return EVAS_EVENT_FLAG_NONE; + } + + MSG_HIGH("%s. CenteSize WH(%d,%d)", __func__, si->w, si->h); // Si->w,h didnot change. after zoom + + sd->edge = _ivug_slider_edge_state_get(si); // Update Edge + + return EVAS_EVENT_FLAG_NONE; +} + +Evas_Event_Flags _momentum_start(void *data, void *event_info) +{ + Elm_Gesture_Momentum_Info *p = (Elm_Gesture_Momentum_Info *) event_info; + MSG_HIGH("momentum_start <%d,%d>", p->x2, p->y2); + + if ( p->n != 1 ) return EVAS_EVENT_FLAG_NONE; + + struct Smart_Data *sd = (struct Smart_Data *) evas_object_smart_data_get((Evas_Object *)data); + Slide_Item* si = sd->slide[CENTER_SLIDE]; + +//save down position. + sd->prev_x = p->x2; + sd->prev_y = p->y2; + +// End animation + sd->anim->Stop(); + +// Update Center!. + + sd->edge = _ivug_slider_edge_state_get(si); + + sd->bMomentumStarted = true; + + return EVAS_EVENT_FLAG_NONE; +} + +Evas_Event_Flags _momentum_move(void *data, void *event_info) +{ + Elm_Gesture_Momentum_Info *p = (Elm_Gesture_Momentum_Info *) event_info; + // _momentum_move is comming when pinch zoom + if ( p->n != 1 ) return EVAS_EVENT_FLAG_NONE; + + MSG_LOW("momentum move <%d,%d>, <%d,%d>, p->n=%d", p->x1, p->y1, p->x2, p->y2, p->n); + + struct Smart_Data *sd = (struct Smart_Data *) evas_object_smart_data_get((Evas_Object *)data); + Slide_Item* si = sd->slide[CENTER_SLIDE]; + + int dist_down_x = p->x2 - p->x1; + int dist_down_y = p->y2 - p->y1; + + if(sqrt(dist_down_x*dist_down_x + dist_down_y*dist_down_y) > LOGNTAP_THRESHOLD) + { + MSG_LOW("Long press cancel"); + sd->bLongtapEnable = false; + } + + if(sd->bLongtapEnable == true) + { + int longtap_dx = p->x2 - sd->longtap_prev_x; + int longtap_dy = p->y2 - sd->longtap_prev_y; + + if(sqrt(longtap_dx*longtap_dx + longtap_dy*longtap_dy) > LOGNTAP_THRESHOLD) + { + MSG_LOW("Long press cancel"); + evas_object_smart_callback_call(sd->obj, "slider,longpress,end", (void*)LONGTAP_ENDED); + } + } + +// MSG_HIGH("%s. XY(%d,%d)", __func__, cur->x, cur->y); + if ( sd->edge == EDGE::SLIDE_NO_EDGE ) + { + MSG_HIGH("Photocam handle this event"); + return EVAS_EVENT_FLAG_NONE; + } + + int dx, dy; + + dx = p->x2 - sd->prev_x; + dy = p->y2 - sd->prev_y; + + if ( dx == 0 ) return EVAS_EVENT_FLAG_NONE; + + sd->prev_x = p->x2; + sd->prev_y = p->y2; + + int dst_x, dst_y; + + dst_x = si->x + (dx); + dst_y = si->y + (dy); + + if ( sd->edge == EDGE::SLIDE_FIT) + { + MSG_HIGH("Case 1. edge=%d, X=%d dx=%d si->x=%d", sd->edge, dst_x, dx, si->x); + _ivug_slider_pass_event_to_item(sd, EINA_FALSE); + + if ( dst_x >= 0 && sd->slide[PREV_SLIDE]->state == SLIDE_STATE_NONE) + { + MSG_HIGH("first file"); + dst_x = 0; + } + + if ( dst_x < 0 && sd->slide[NEXT_SLIDE]->state == SLIDE_STATE_NONE) + { + MSG_HIGH("last file"); + dst_x = 0; + } + + _ivug_slider_slide_move(sd, dst_x , si->y); + + return EVAS_EVENT_FLAG_NONE; + } + + if ( (si->x - sd->x) * (dst_x - sd->x) < 0 ) + { + MSG_HIGH("Case a. edge=%d, X=%d dx=%d si->x=%d", sd->edge, dst_x, dx, si->x); + + dst_x = 0; + _ivug_slider_pass_event_to_item(sd, EINA_TRUE); + _ivug_slider_slide_move(sd, dst_x , si->y); + + return EVAS_EVENT_FLAG_NONE; + } + + if ( si->x != sd->x ) + { + MSG_HIGH("Case 2. edge=%d, X=%d dx=%d si->x=%d", sd->edge, dst_x, dx, si->x); + + _ivug_slider_pass_event_to_item(sd, EINA_FALSE); + + if ( dst_x >= 0 && sd->slide[PREV_SLIDE]->state == SLIDE_STATE_NONE) + { + MSG_HIGH("first file"); + dst_x = 0; + } + + if ( dst_x < 0 && sd->slide[NEXT_SLIDE]->state == SLIDE_STATE_NONE) + { + MSG_HIGH("last file"); + dst_x = 0; + } + + _ivug_slider_slide_move(sd, dst_x , si->y); + + return EVAS_EVENT_FLAG_NONE; + } + + if ( sd->edge & EDGE::SLIDE_LEFT_EDGE) + { + if ( dx > 0 ) // Mouse --> + { + MSG_HIGH("Case 3. edge=%d, X=%d dx=%d si->x=%d", sd->edge, dst_x, dx, si->x); + + _ivug_slider_pass_event_to_item(sd, EINA_FALSE); + + if ( dst_x >= 0 && sd->slide[PREV_SLIDE]->state == SLIDE_STATE_NONE) + { + MSG_HIGH("first file"); + dst_x = 0; + } + + _ivug_slider_slide_move(sd, dst_x , si->y); + + return EVAS_EVENT_FLAG_NONE; + } + else + { + MSG_HIGH("Case 4. edge=%d, X=%d dx=%d si->x=%d", sd->edge, dst_x, dx, si->x); + + _ivug_slider_pass_event_to_item(sd, EINA_TRUE); + } + } + + if ( sd->edge & EDGE::SLIDE_RIGHT_EDGE) + { + if ( dx < 0 ) // Mouse <-- + { + MSG_HIGH("Case 5. edge=%d, X=%d dx=%d si->x=%d", sd->edge, dst_x, dx, si->x); + + _ivug_slider_pass_event_to_item(sd, EINA_FALSE); + + if ( dst_x < 0 && sd->slide[NEXT_SLIDE]->state == SLIDE_STATE_NONE) + { + MSG_HIGH("last file"); + dst_x = 0; + } + + _ivug_slider_slide_move(sd, dst_x , si->y); + + return EVAS_EVENT_FLAG_NONE; + } + else + { + + MSG_HIGH("Case 6. edge=%d, X=%d dx=%d si->x=%d", sd->edge, dst_x, dx, si->x); + + _ivug_slider_pass_event_to_item(sd, EINA_TRUE); + + } + } + + sd->edge = _ivug_slider_edge_state_get(si); + return EVAS_EVENT_FLAG_NONE; + +} + +Evas_Event_Flags _momentum_end(void *data, void *event_info) +{ + Elm_Gesture_Momentum_Info *p = (Elm_Gesture_Momentum_Info *) event_info; + if ( p->n != 1 ) return EVAS_EVENT_FLAG_NONE; + + MSG_HIGH("momentum end Cur=<%d,%d> M=<%d,%d>", p->x2, p->y2, p->mx, p->my); + + struct Smart_Data *sd = (struct Smart_Data *) evas_object_smart_data_get((Evas_Object *)data); + + Slide_Item *si = sd->slide[CENTER_SLIDE]; + + MSG_HIGH("Mouse Up : si->XYWH(%d,%d,%d,%d)", si->x, si->y, si->w, si->h); + +// Find Scroll Direction + sd->edge = _ivug_slider_edge_state_get(si); + + shift_direction_t dir = SLIDE_SHIFT_NONE; + + bool isFlick = abs(p->mx) < 1500 ? false : true; + + if ( isFlick == true ) + { +// momentumÀÌ 0ÀÌ ¾Æ´Ñ °æ¿ì(flick animation Áß°£¿¡ ´Ù½Ã click½Ã) center¸¦ ¾÷µ¥ÀÌÆ® Çؾߵdzª? ±×·¸°Ô ÇÏ¸é ºÎµå·¯¿ö Áúµí.. Çѵ¥.. ÀÏ´Ü pass + MSG_UTIL_HIGH("Velocity = %d Momentum=%d", sd->momentum, p->mx); + + sd->momentum += p->mx; + + if ( (sd->edge & EDGE::SLIDE_LEFT_EDGE) && p->mx > 0) + { + // Flick + if ( p->mx + (si->x - sd->x) > sd->w ) + { + // Flick right + MSG_HIGH("Flick Right ----------->"); + dir = SLIDE_SHIFT_TO_LEFT; + } + } + + if ( (sd->edge & EDGE::SLIDE_RIGHT_EDGE) && p->mx < 0) + { + // Flick + if ( p->mx + ((si->x - sd->x) + si->w ) < 0 ) + { + // Flick left + MSG_HIGH("Flick Left <-----------"); + dir = SLIDE_SHIFT_TO_RIGHT; + } + } + + MSG_UTIL_HIGH("Velocity2 = %d", sd->momentum); + _put_originate(sd, dir, sd->momentum); + + } + else + { + MSG_HIGH("Si->x=%d", si->x); + + dir = _get_shift_direction(sd); + _put_originate(sd, dir, ANIN_VELOCITY); + + } + + sd->bLongtapEnable = true; + + sd->bMomentumStarted = false; + + return EVAS_EVENT_FLAG_NONE; +} + +Evas_Event_Flags _momentum_abort(void *data, void *event_info) +{ + Elm_Gesture_Momentum_Info *p = (Elm_Gesture_Momentum_Info *) event_info; + + MSG_HIGH("momentum abort Cur=<%d,%d> M=<%d,%d> N=%d", p->x2, p->y2, p->mx, p->my, p->n); + + if ( p->n != 1 ) return EVAS_EVENT_FLAG_NONE; + + struct Smart_Data *sd = (struct Smart_Data *) evas_object_smart_data_get((Evas_Object *)data); + + Slide_Item *si = sd->slide[CENTER_SLIDE]; + + MSG_HIGH("Mouse Up : si->XYWH(%d,%d,%d,%d)", si->x, si->y, si->w, si->h); + +// Find Scroll Direction + sd->edge = _ivug_slider_edge_state_get(si); + + shift_direction_t dir = SLIDE_SHIFT_NONE; + + bool isFlick = abs(p->mx) < 1500 ? false : true; + + if ( isFlick == true ) + { + if ( (sd->edge & EDGE::SLIDE_LEFT_EDGE) && p->mx > 0) + { + // Flick + if ( p->mx + ((si->x - sd->x) ) > sd->w ) + { + // Flick right + MSG_HIGH("Flick Right"); + dir = SLIDE_SHIFT_TO_LEFT; + } + } + + if ( (sd->edge & EDGE::SLIDE_RIGHT_EDGE) && p->mx < 0) + { + // Flick + if ( p->mx + ((si->x - sd->x) + si->w ) < 0 ) + { + // Flick left + MSG_HIGH("Flick Left"); + dir = SLIDE_SHIFT_TO_RIGHT; + } + } + } + else + { + MSG_HIGH("Si->x=%d", si->x); + dir = _get_shift_direction(sd); + } + + _put_originate(sd, dir, ANIN_VELOCITY); + + sd->bLongtapEnable = true; + + sd->bMomentumStarted = false; + + return EVAS_EVENT_FLAG_NONE; +} + + + +Evas_Event_Flags _flick_start(void *data, void *event_info) +{ + Elm_Gesture_Line_Info *p = (Elm_Gesture_Line_Info *) event_info; + + MSG_LOW("flick started x1,x2=(%d,%d) tx=%u mx=%d n=%u", + p->momentum.x1, p->momentum.x2, p->momentum.tx, + p->momentum.mx, p->momentum.n); + + return EVAS_EVENT_FLAG_NONE; +} + + +Evas_Event_Flags _flick_move(void *data, void *event_info) +{ + Elm_Gesture_Line_Info *p = (Elm_Gesture_Line_Info *) event_info; + + MSG_LOW("flick moving x1,x2=(%d,%d) tx=%u mx=%d n=%u", + p->momentum.x1, p->momentum.x2, p->momentum.tx, + p->momentum.mx, p->momentum.n); + + return EVAS_EVENT_FLAG_NONE; + +} + + +Evas_Event_Flags _flick_end(void *data, void *event_info) +{ + Elm_Gesture_Line_Info *p = (Elm_Gesture_Line_Info *) event_info; + + MSG_LOW("flick ended x1,x2=(%d,%d) tx=%u mx=%d n=%u", + p->momentum.x1, p->momentum.x2, p->momentum.tx, + p->momentum.mx, p->momentum.n); + return EVAS_EVENT_FLAG_NONE; +} + + +Evas_Event_Flags _flick_abort(void *data, void *event_info) +{ + Elm_Gesture_Line_Info *p = (Elm_Gesture_Line_Info *) event_info; + + MSG_LOW("flick aborted x1,x2=(%d,%d) tx=%u mx=%d n=%u", + p->momentum.x1, p->momentum.x2, p->momentum.tx, + p->momentum.mx, p->momentum.n); + return EVAS_EVENT_FLAG_NONE; +} + + + +Evas_Event_Flags _dbl_click_start(void *data , void *event_info) +{ + Elm_Gesture_Taps_Info *p = (Elm_Gesture_Taps_Info *) event_info; + + MSG_HIGH("Double click start"); + + if ( p->n != 1 ) return EVAS_EVENT_FLAG_NONE; + + return EVAS_EVENT_FLAG_NONE; +} + +Evas_Event_Flags _dbl_click_end(void *data , void *event_info) +{ + Elm_Gesture_Taps_Info *p = (Elm_Gesture_Taps_Info *) event_info; + + MSG_HIGH("Double click end"); + + if ( p->n != 1 ) return EVAS_EVENT_FLAG_NONE; + + return EVAS_EVENT_FLAG_NONE; +} + +Evas_Event_Flags _dbl_click_abort(void *data , void *event_info) +{ + Elm_Gesture_Taps_Info *p = (Elm_Gesture_Taps_Info *) event_info; + + MSG_HIGH("Double click abort"); + + if ( p->n != 1 ) return EVAS_EVENT_FLAG_NONE; + + return EVAS_EVENT_FLAG_NONE; +} + +Evas_Event_Flags n_finger_tap_start(void *data , void *event_info) +{ + Elm_Gesture_Taps_Info *p = (Elm_Gesture_Taps_Info *) event_info; + + MSG_HIGH("Finger tab start. Time=%d", p->timestamp); + + if ( p->n != 1 ) return EVAS_EVENT_FLAG_NONE; + + return EVAS_EVENT_FLAG_NONE; +} + + +Evas_Event_Flags n_finger_tap_end(void *data , void *event_info) +{ + Elm_Gesture_Taps_Info *p = (Elm_Gesture_Taps_Info *) event_info; + + MSG_HIGH("Finger tab end. Time=%d", p->timestamp); + + if ( p->n != 1 ) return EVAS_EVENT_FLAG_NONE; + + struct Smart_Data *sd = (struct Smart_Data *) evas_object_smart_data_get((Evas_Object *)data); + + Slide_Item *si = sd->slide[CENTER_SLIDE]; + + if ( ivug_slider_item_icon_click_check(si, p->x, p->y ) == true ) + { + evas_object_smart_callback_call(sd->obj, "slider,clicked,icon", si); // Clicked video icon + } + else + { + evas_object_smart_callback_call(sd->obj, "slider,clicked", si); + } + + return EVAS_EVENT_FLAG_NONE; +} + +Evas_Event_Flags n_finger_tap_abort(void *data , void *event_info) +{ + Elm_Gesture_Taps_Info *p = (Elm_Gesture_Taps_Info *) event_info; + + MSG_HIGH("Finger tab aborted. Time=%d", p->timestamp); + + if ( p->n != 1 ) return EVAS_EVENT_FLAG_NONE; + + return EVAS_EVENT_FLAG_NONE; +} + + +Evas_Event_Flags n_long_tap_start(void *data , void *event_info) +{ + Elm_Gesture_Taps_Info *p = (Elm_Gesture_Taps_Info *) event_info; + + MSG_HIGH("Long tab start, x=%d, y=%d", p->x, p->y); + + if ( p->n != 1 ) return EVAS_EVENT_FLAG_NONE; + + struct Smart_Data *sd = (struct Smart_Data *) evas_object_smart_data_get((Evas_Object *)data); + + if(sd->bLongtapEnable == false) + { + MSG_HIGH("It is not long tap case"); + return EVAS_EVENT_FLAG_NONE; + } + + if(sd->bMomentumStarted == true) // compare down and longpressed position + { + sd->longtap_prev_x = p->x; + sd->longtap_prev_y = p->y; + + int longtap_dx = sd->prev_x - sd->longtap_prev_x; + int longtap_dy = sd->prev_y - sd->longtap_prev_y; + + if(sqrt(longtap_dx*longtap_dx + longtap_dy*longtap_dy) > LOGNTAP_THRESHOLD) + { + MSG_HIGH("It is not long tap"); + return EVAS_EVENT_FLAG_NONE; + } + } + + evas_object_smart_callback_call(sd->obj, "slider,longpressed", p); + + return EVAS_EVENT_FLAG_NONE; + +} + +Evas_Event_Flags n_long_tap_move(void *data , void *event_info) +{ + Elm_Gesture_Taps_Info *p = (Elm_Gesture_Taps_Info *) event_info; + + MSG_HIGH("Long tab move"); + + if ( p->n != 1 ) return EVAS_EVENT_FLAG_NONE; + + return EVAS_EVENT_FLAG_NONE; +} + +Evas_Event_Flags n_long_tap_end(void *data , void *event_info) +{ + Elm_Gesture_Taps_Info *p = (Elm_Gesture_Taps_Info *) event_info; + + MSG_HIGH("Long tab end"); + + if ( p->n != 1 ) return EVAS_EVENT_FLAG_NONE; + + MSG_HIGH("Long press end"); + + struct Smart_Data *sd = (struct Smart_Data *) evas_object_smart_data_get((Evas_Object *)data); + + evas_object_smart_callback_call(sd->obj, "slider,longpress,end", (void*)LONGTAP_ENDED); + + return EVAS_EVENT_FLAG_NONE; + +} + +Evas_Event_Flags n_long_tap_abort(void *data , void *event_info) +{ + Elm_Gesture_Taps_Info *p = (Elm_Gesture_Taps_Info *) event_info; + + MSG_HIGH("Long tab abort"); + + if ( p->n != 1 ) return EVAS_EVENT_FLAG_NONE; + + return EVAS_EVENT_FLAG_NONE; + +} + + diff --git a/main/src/slider/ivug-slider-priv.h b/main/src/slider/ivug-slider-priv.h new file mode 100755 index 0000000..6c81284 --- /dev/null +++ b/main/src/slider/ivug-slider-priv.h @@ -0,0 +1,188 @@ +/* + * Copyright 2012 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.tizenopensource.org/license + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __IVUG_SLIDER_PRIV_H__ +#define __IVUG_SLIDER_PRIV_H__ + +#include "ivug-define.h" +#include "ivug-medialist.h" + +/*********************************************************************/ +/* Configuration */ +/*********************************************************************/ + +/* elm_config_finger_size_get = 40 */ +#define IMAGE_BETWEEN_MARGIN (30) // The value is width between photocam(unit is pixel). +#define IMAGE_MOVE_MARGIN ((int)IMAGE_BETWEEN_MARGIN*0.8) +/* If moved width is larger than IMAGE_SCROLL_MARGIN, image is scrolled */ +#define IMAGE_SCROLL_MARGIN (5) /* vertical move doen't over 5 pixel width */ +#define LONG_PRESS_MARGIN ((int)(elm_config_finger_size_get() / 3)) + + +#define ANIN_VELOCITY (5000) + + +typedef int slide_edge_t; + +namespace EDGE { + const int SLIDE_NO_EDGE = (1<<0); // 1 + + const int SLIDE_LEFT_EDGE = (1<<1); // 2 + const int SLIDE_RIGHT_EDGE = (1<<2); // 4 + + const int SLIDE_FIT = SLIDE_LEFT_EDGE | SLIDE_RIGHT_EDGE; +}; + +typedef enum { + SLIDE_SHIFT_NONE = 0x00, + SLIDE_SHIFT_TO_RIGHT, // <---------------------Mouse + SLIDE_SHIFT_TO_LEFT, // Mouse---------------------> +} shift_direction_t; + + +//ENUM +typedef enum { + CENTER_SLIDE, + NEXT_SLIDE, + PREV_SLIDE, + MAX_SLIDE, +} slide_index_t; + +class ECoreAnimator; +class CAnimator; + +#define USE_CALC_JOB + +// slider +typedef struct Smart_Data +{ + Evas_Object *obj; // smart object itself. + Evas_Coord x, y, w, h; // Geometry of slider + + Evas_Object *clipper; + +//silde + Slide_Item* slide[MAX_SLIDE]; + +//data list + Eina_Bool bShow; + + Media_List* media_list; // Storing entire media list. + +// for flick anim + CAnimator *tween; + ECoreAnimator *anim; + + shift_direction_t last_dir; + int momentum; + +//Mouse event handler + Evas_Object *event_obj; // Mouse event receiver. + Evas_Object *gesture; + + bool bPassEvent; + bool bZooming; + + int prev_x; + int prev_y; + + bool bLongtapEnable; + bool bMomentumStarted; + int longtap_prev_x; + int longtap_prev_y; + + slide_edge_t edge; + + Ecore_Idler *load_idler; + Ecore_Idler *item_load_idler; + + unsigned int zoom_level; + +#ifdef USE_CALC_JOB + Ecore_Job *calc_job; +#endif + +} _Smart_Data; + + +#ifdef __cplusplus +extern "C" { +#endif + + +// Common function between slide show and slider. + +void _ivug_slider_slide_move(struct Smart_Data *sd, Evas_Coord x, Evas_Coord y); + +// Common function between slide and slide mouse. + +void _ivug_slider_start_slide(struct Smart_Data *sd, int src_x, int dst_x, int momentum); + +void _ivug_slider_slide_shift(struct Smart_Data *sd, shift_direction_t direction); + +Evas_Event_Flags _zoom_start(void *data, void *event_info); + +Evas_Event_Flags _zoom_move(void *data, void *event_info); + +Evas_Event_Flags _zoom_end(void *data, void *event_info); + +Evas_Event_Flags _zoom_abort(void *data, void *event_info); + +Evas_Event_Flags _momentum_start(void *data, void *event_info); + +Evas_Event_Flags _momentum_move(void *data, void *event_info); + +Evas_Event_Flags _momentum_end(void *data, void *event_info); + +Evas_Event_Flags _momentum_abort(void *data, void *event_info); + +Evas_Event_Flags _dbl_click_start(void *data , void *event_info); + +Evas_Event_Flags _dbl_click_end(void *data , void *event_info); + +Evas_Event_Flags _dbl_click_abort(void *data , void *event_info); + +Evas_Event_Flags _flick_start(void *data, void *event_info); + +Evas_Event_Flags _flick_move(void *data, void *event_info); + +Evas_Event_Flags _flick_end(void *data, void *event_info); + +Evas_Event_Flags _flick_abort(void *data, void *event_info); + +Evas_Event_Flags n_finger_tap_start(void *data , void *event_info); + +Evas_Event_Flags n_finger_tap_end(void *data , void *event_info); + +Evas_Event_Flags n_finger_tap_abort(void *data , void *event_info); + +Evas_Event_Flags n_long_tap_start(void *data , void *event_info); + +Evas_Event_Flags n_long_tap_move(void *data , void *event_info); + +Evas_Event_Flags n_long_tap_end(void *data , void *event_info); + +Evas_Event_Flags n_long_tap_abort(void *data , void *event_info); + + +#ifdef __cplusplus +} +#endif + + + +#endif // __IVUG_SLIDER_PRIV_H__ + diff --git a/main/src/slider/ivug-slider.cpp b/main/src/slider/ivug-slider.cpp new file mode 100755 index 0000000..1504e2a --- /dev/null +++ b/main/src/slider/ivug-slider.cpp @@ -0,0 +1,1201 @@ +/* + * Copyright 2012 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.tizenopensource.org/license + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include // ug_destroy_me, ug_send_result + +#include "ivug-slider.h" +#include "ivug-common.h" + +#include "ivug-parameter.h" +#include "ivug-define.h" +#include "ivug-config.h" + +#include "ivug-util.h" +#include "ivug-medialist.h" +#include "ivug-media.h" + +#include "ivug-drm.h" +#include "ivug-mouse-event.h" +#include "ivug-slider-item.h" + +#include "ivug-slider-priv.h" + +#include "ivug-image.h" + +#include "Animation.h" +#include "ECoreAnimator.h" +#include "ivug-slideshow.h" +#include "EFLUtil.h" + +#define LOG_CAT "IV-SLIDER" + +/* local subsystem globals */ +static Evas_Smart *_smart_ = NULL; + +#define USE_CLIPPER + +// Forward declaration +void _ivug_slider_slide_resize(struct Smart_Data *sd, Evas_Coord w, Evas_Coord h); +void _ivug_slider_slide_move(struct Smart_Data *sd, Evas_Coord x, Evas_Coord y); + +const char *_GetStateString(slide_state_t state) +{ + static const char *szState[] = + { + "None", + "Set", + "Downloading", + "DRM Checking", + "Ready", + "Loading", + "Loaded", + "Download Failed", + "No Right", + "Error", + }; + + return szState[state]; +} + +static Eina_Bool _idler_loading_func(void* data) +{ + struct Smart_Data *sd = static_cast(data); + + sd->load_idler = NULL; + MSG_SLIDER_HIGH("Do idle loading"); + + int i; + if ( sd->slide[CENTER_SLIDE]->state == SLIDE_STATE_READY ) // Center image must be loaded even while other image is loading. + { + ivug_slider_item_load(sd->slide[CENTER_SLIDE]); + goto end; + } + + for ( i = 0; i < MAX_SLIDE ; i++) + { + if ( sd->slide[i]->state == SLIDE_STATE_LOADING ) + { + goto end; + } + } + + if ( sd->slide[NEXT_SLIDE]->state == SLIDE_STATE_READY ) + { + ivug_slider_item_load(sd->slide[NEXT_SLIDE]); + goto end; + } + + if ( sd->slide[PREV_SLIDE]->state == SLIDE_STATE_READY ) + { + ivug_slider_item_load(sd->slide[PREV_SLIDE]); + goto end; + } + + MSG_SLIDER_WARN("Set Data loading State=%s,%s,%s", + _GetStateString(sd->slide[PREV_SLIDE]->state), + _GetStateString(sd->slide[CENTER_SLIDE]->state), + _GetStateString(sd->slide[NEXT_SLIDE]->state) + ); + +end: + return ECORE_CALLBACK_CANCEL; + +} + +static void _do_load(struct Smart_Data *sd) +{ + if ( sd->load_idler ) + { + ecore_idler_del(sd->load_idler); + sd->load_idler = NULL; + } + + MSG_SLIDER_HIGH("Add idler for loading."); + sd->load_idler = ecore_idler_add(_idler_loading_func, sd); +} + +static void _ivug_slider_on_center_changed(Evas_Object *obj, Slide_Item *old, Slide_Item *cur) +{ + IV_ASSERT(old != cur ); + + struct Smart_Data *sd = (struct Smart_Data *) evas_object_smart_data_get(obj); + + if ( old != NULL ) + { + ivug_slider_item_zoom_reset(old, EINA_TRUE, 0, 0); + + ivug_slider_item_pause(old); // Pause DRM consume/Animation + } + + if(cur->state == SLIDE_STATE_LOADED) + { + ivug_slider_item_play(cur); + } + else + { + MSG_SLIDER_ERROR("Invalid state : %s", _GetStateString(cur->state)); + } + + MSG_SLIDER_HIGH("Center item changed. State=%s", _GetStateString(cur->state)); + + evas_object_smart_callback_call(sd->obj, "slider,item,changed", cur); +} + +void _ivug_slider_item_state_changed(slide_state_t state, Slide_Item *si, void *client_data) +{ + struct Smart_Data *sd = static_cast(client_data); + IV_ASSERT(sd != NULL); + + if ( sd->slide[CENTER_SLIDE] == si ) + { + MSG_SLIDER_HIGH("Center Item state changed. Old=%s New=%s", _GetStateString(state), _GetStateString(si->state)); + + if ( state == SLIDE_STATE_LOADED ) + { + ivug_slider_item_play(si); + evas_object_smart_callback_call(sd->obj, "slider,item,state,changed", si); + } + else + { + evas_object_smart_callback_call(sd->obj, "slider,item,state,changed", si); + } + } + + _do_load(sd); + +} + +static void _on_event_mouse_down(void *data, Evas *evas, Evas_Object *obj, void *event_info) +{ + MSG_SLIDER_HIGH("Event layer clicked : %s Layer=%d", evas_object_name_get(obj), evas_object_layer_get(obj)); +} + +static Eina_Bool _item_loader(void* data) +{ + IV_ASSERT(data != NULL); + struct Smart_Data *sd = (struct Smart_Data *) evas_object_smart_data_get((Evas_Object *)data); + + sd->item_load_idler = NULL; + + Slide_Item *si = sd->slide[CENTER_SLIDE]; + + si->state = SLIDE_STATE_READY; + + ivug_slider_item_load(si); + + return ECORE_CALLBACK_CANCEL; +} + +static void _sizing_eval(void *data) +{ + struct Smart_Data *sd = (struct Smart_Data *)data; + + sd->calc_job = NULL; + + MSG_SLIDER_HIGH("Object geometry resized. (%d,%d,%d,%d)", sd->x, sd->y , sd->w , sd->h); + +#ifdef USE_CLIPPER + evas_object_move(sd->clipper, sd->x, sd->y); + evas_object_resize(sd->clipper, sd->w, sd->h); +#endif + + evas_object_move(sd->event_obj, sd->x, sd->y); + evas_object_resize(sd->event_obj, sd->w, sd->h); + + evas_object_smart_changed(sd->obj); +} + +static void +_ivug_slider_smart_add(Evas_Object *obj) +{ + MSG_SLIDER_HIGH("Slider Add : 0x%08x", obj); + + PERF_CHECK_BEGIN(LVL4, "slider smart add"); + + struct Smart_Data *sd = (struct Smart_Data *)calloc(1, sizeof(struct Smart_Data)); + ivug_ret_if(!sd); + evas_object_smart_data_set(obj, sd); + + sd->obj = obj; + sd->momentum = 0; + + sd->anim = new ECoreAnimator(); + + sd->edge = EDGE::SLIDE_FIT; + sd->last_dir = SLIDE_SHIFT_TO_RIGHT; /* default for first loading*/ + sd->bPassEvent = false; + + //create slider item. + for (int idx = 0; idx < MAX_SLIDE; idx++) + { + PERF_CHECK_BEGIN(LVL5, "add slider item"); + sd->slide[idx] = ivug_slider_item_add(obj); + PERF_CHECK_END(LVL5, "add slider item"); + + ivug_slider_item_set_callback(sd->slide[idx], _ivug_slider_item_state_changed, sd); + } + + sd->event_obj = evas_object_rectangle_add(evas_object_evas_get(obj)); + evas_object_name_set(sd->event_obj, "slider-event"); + evas_object_color_set(sd->event_obj , 0, 0, 0, 0); // Fully Transparent object. + evas_object_size_hint_align_set(sd->event_obj, EVAS_HINT_FILL, EVAS_HINT_FILL); + evas_object_size_hint_weight_set(sd->event_obj, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + evas_object_repeat_events_set(sd->event_obj, EINA_TRUE); + evas_object_show(sd->event_obj); + + evas_object_smart_member_add(sd->event_obj, obj); + + sd->gesture = elm_gesture_layer_add(sd->event_obj); + elm_gesture_layer_hold_events_set(sd->gesture, EINA_FALSE); + + elm_gesture_layer_cb_set(sd->gesture, ELM_GESTURE_ZOOM, ELM_GESTURE_STATE_START, _zoom_start, obj); + elm_gesture_layer_cb_set(sd->gesture, ELM_GESTURE_ZOOM, ELM_GESTURE_STATE_MOVE, _zoom_move, obj); + elm_gesture_layer_cb_set(sd->gesture, ELM_GESTURE_ZOOM, ELM_GESTURE_STATE_END, _zoom_end, obj); + elm_gesture_layer_cb_set(sd->gesture, ELM_GESTURE_ZOOM, ELM_GESTURE_STATE_ABORT, _zoom_abort, obj); + + elm_gesture_layer_cb_set(sd->gesture, ELM_GESTURE_MOMENTUM, ELM_GESTURE_STATE_START, _momentum_start, obj); + elm_gesture_layer_cb_set(sd->gesture, ELM_GESTURE_MOMENTUM, ELM_GESTURE_STATE_MOVE, _momentum_move, obj); + elm_gesture_layer_cb_set(sd->gesture, ELM_GESTURE_MOMENTUM, ELM_GESTURE_STATE_END, _momentum_end, obj); + elm_gesture_layer_cb_set(sd->gesture, ELM_GESTURE_MOMENTUM, ELM_GESTURE_STATE_ABORT, _momentum_abort, obj); + elm_gesture_layer_cb_set(sd->gesture, ELM_GESTURE_N_FLICKS, ELM_GESTURE_STATE_START, _flick_start, obj); + elm_gesture_layer_cb_set(sd->gesture, ELM_GESTURE_N_FLICKS, ELM_GESTURE_STATE_END, _flick_move, obj); + elm_gesture_layer_cb_set(sd->gesture, ELM_GESTURE_N_FLICKS, ELM_GESTURE_STATE_END, _flick_end, obj); + elm_gesture_layer_cb_set(sd->gesture, ELM_GESTURE_N_FLICKS, ELM_GESTURE_STATE_ABORT, _flick_abort, obj); + + elm_gesture_layer_cb_set(sd->gesture, ELM_GESTURE_N_DOUBLE_TAPS, ELM_GESTURE_STATE_START, _dbl_click_start, obj); + elm_gesture_layer_cb_set(sd->gesture, ELM_GESTURE_N_DOUBLE_TAPS, ELM_GESTURE_STATE_END, _dbl_click_end, obj); + elm_gesture_layer_cb_set(sd->gesture, ELM_GESTURE_N_DOUBLE_TAPS, ELM_GESTURE_STATE_ABORT, _dbl_click_abort, obj); + + elm_gesture_layer_cb_set(sd->gesture, ELM_GESTURE_N_TAPS, ELM_GESTURE_STATE_START, n_finger_tap_start, obj); + elm_gesture_layer_cb_set(sd->gesture, ELM_GESTURE_N_TAPS, ELM_GESTURE_STATE_END, n_finger_tap_end, obj); + elm_gesture_layer_cb_set(sd->gesture, ELM_GESTURE_N_TAPS, ELM_GESTURE_STATE_ABORT, n_finger_tap_abort, obj); + + elm_gesture_layer_cb_set(sd->gesture, ELM_GESTURE_N_LONG_TAPS, ELM_GESTURE_STATE_START, n_long_tap_start, obj); + elm_gesture_layer_cb_set(sd->gesture, ELM_GESTURE_N_LONG_TAPS, ELM_GESTURE_STATE_MOVE, n_long_tap_move, obj); + elm_gesture_layer_cb_set(sd->gesture, ELM_GESTURE_N_LONG_TAPS, ELM_GESTURE_STATE_END, n_long_tap_end, obj); + elm_gesture_layer_cb_set(sd->gesture, ELM_GESTURE_N_LONG_TAPS, ELM_GESTURE_STATE_ABORT, n_long_tap_abort, obj); + + if ( elm_gesture_layer_attach(sd->gesture, sd->event_obj) == EINA_FALSE) + { + MSG_SLIDER_ERROR("Cannot attach event rect"); + } + evas_object_name_set(sd->gesture, "Slider:Getsture"); + + evas_object_event_callback_add(obj, EVAS_CALLBACK_MOUSE_DOWN, _on_event_mouse_down, NULL); + evas_object_event_callback_add(sd->event_obj, EVAS_CALLBACK_MOUSE_DOWN, _on_event_mouse_down, NULL); + + sd->bLongtapEnable = true; + +#if 0 + for (int idx = 0; idx < MAX_SLIDE; idx++) + { + // Video iconÀÌ event¸¦ ¸ÕÀú ¹Þ°Ô Çϱâ À§ÇØ z orderÀ» º¯°æ ÇÑ´Ù. + evas_object_stack_above(sd->slide[idx]->vIcon, sd->event_obj); + } +#endif + + +#ifdef USE_CLIPPER + sd->clipper = evas_object_rectangle_add(evas_object_evas_get(obj)); + evas_object_color_set(sd->clipper, 255,255,255,255); + evas_object_smart_member_add(sd->clipper, obj); + evas_object_name_set(sd->clipper, "slider-clipper"); + + MSG_SLIDER_HIGH("Create clipper(0x%08x)", sd->clipper); + + evas_object_show(sd->clipper); +#endif + + PERF_CHECK_END(LVL4, "slider smart add"); + + return; + +} + +static void +_ivug_slider_smart_del(Evas_Object *obj) +{ + MSG_SLIDER_HIGH("Slider delete. obj=0x%08x", obj); + + struct Smart_Data *sd = (struct Smart_Data *) evas_object_smart_data_get(obj); + ivug_ret_if(!sd); + + if ( sd->tween) delete sd->tween; + sd->tween = NULL; + + if ( sd->anim) delete sd->anim; + sd->anim = NULL; + + if ( sd->item_load_idler ) + { + ecore_idler_del(sd->item_load_idler); + sd->item_load_idler = NULL; + } + + if ( sd->load_idler ) + { + ecore_idler_del(sd->load_idler); + sd->load_idler = NULL; + } + + if ( sd->calc_job ) ecore_job_del(sd->calc_job); + sd->calc_job = NULL; + + if ( sd->event_obj ) + { + evas_object_del(sd->event_obj); + sd->event_obj = NULL; + } + + if ( sd->gesture ) + { + evas_object_del(sd->gesture); + sd->gesture = NULL; + } + + for (int i = 0; i < MAX_SLIDE ; i++) //delete layout + { + ivug_slider_item_del(sd->slide[i]); + sd->slide[i] = NULL; + } + +#ifdef USE_CLIPPER + if ( sd->clipper ) + { + evas_object_del(sd->clipper); + sd->clipper = NULL; + } +#endif + + free(sd); + +} + + +static void +_ivug_slider_smart_move(Evas_Object *obj, Evas_Coord x, Evas_Coord y) +{ + struct Smart_Data *sd = (struct Smart_Data *) evas_object_smart_data_get(obj); + MSG_ASSERT(sd != NULL); + + if ((sd->x == x) && (sd->y == y)) return; + + MSG_SLIDER_MED("Slider Move : XY(%d,%d)", x, y); + + sd->x = x; + sd->y = y; + +#ifdef USE_CALC_JOB + if ( sd->calc_job ) ecore_job_del(sd->calc_job); + sd->calc_job = NULL; + + sd->calc_job = ecore_job_add(_sizing_eval, sd); +#else + evas_object_smart_changed(obj); +#endif + +} + +static void +_ivug_slider_smart_resize(Evas_Object *obj, Evas_Coord w, Evas_Coord h) +{ + struct Smart_Data *sd = (struct Smart_Data *) evas_object_smart_data_get(obj); + MSG_ASSERT(sd != NULL); + + if ((sd->w == w) && (sd->h == h)) return; + + MSG_SLIDER_MED("Slider Resize : WH(%d,%d)", w,h); + + sd->w = w; + sd->h = h; + +#ifdef USE_CALC_JOB + if ( sd->calc_job ) ecore_job_del(sd->calc_job); + sd->calc_job = NULL; + + sd->calc_job = ecore_job_add(_sizing_eval, sd); +#else + evas_object_smart_changed(obj); +#endif + +} + +static void +_ivug_slider_smart_show(Evas_Object *obj) +{ + struct Smart_Data *sd = (struct Smart_Data *) evas_object_smart_data_get(obj); + MSG_ASSERT(sd != NULL); + + if ( sd->bShow == EINA_TRUE) return; + + sd->bShow = EINA_TRUE; + + MSG_SLIDER_HIGH("Slider Show"); + + ivug_slider_item_show(sd->slide[CENTER_SLIDE]); + ivug_slider_item_show(sd->slide[NEXT_SLIDE]); + ivug_slider_item_show(sd->slide[PREV_SLIDE]); + + evas_object_show(sd->event_obj); + evas_object_show(sd->clipper); +} + +static void +_ivug_slider_smart_hide(Evas_Object *obj) +{ + struct Smart_Data *sd = (struct Smart_Data *) evas_object_smart_data_get(obj); + MSG_ASSERT(sd != NULL); + + if ( sd->bShow == EINA_FALSE) return; + + sd->bShow = EINA_FALSE; + + MSG_SLIDER_HIGH("Slider Hide"); + + ivug_slider_item_hide(sd->slide[CENTER_SLIDE]); + ivug_slider_item_hide(sd->slide[NEXT_SLIDE]); + ivug_slider_item_hide(sd->slide[PREV_SLIDE]); + + evas_object_hide(sd->event_obj); + evas_object_hide(sd->clipper); +} + +static void +_ivug_slider_smart_clip_set(Evas_Object *obj, Evas_Object * clip) +{ + int x, y, w, h; + evas_object_geometry_get(clip, &x, &y, &w, &h); + MSG_SLIDER_HIGH("Slider Clip set : Clipper=0x%08x (%d,%d,%d,%d)", x, y, w, h); + +#ifdef USE_CLIPPER + struct Smart_Data *sd = (struct Smart_Data *) evas_object_smart_data_get(obj); + + for (int i = 0; i < MAX_SLIDE; i++) + { //set resize + ivug_slider_item_clip_set(sd->slide[i], sd->clipper); + } + + evas_object_clip_set(sd->event_obj, sd->clipper); +#endif + +} + +static void +_ivug_slider_smart_clip_unset(Evas_Object *obj) +{ + MSG_SLIDER_HIGH("Slider Clip unset"); + +#ifdef USE_CLIPPER + struct Smart_Data *sd = (struct Smart_Data *) evas_object_smart_data_get(obj); + + for (int i = 0; i < MAX_SLIDE; i++) + { //set resize + ivug_slider_item_clip_unset(sd->slide[i]); + } + + evas_object_clip_unset(sd->event_obj); +#endif + +} + +static void +_ivug_slider_smart_calculate(Evas_Object *obj) +{ + struct Smart_Data *sd = (struct Smart_Data *) evas_object_smart_data_get(obj); + if ((sd->w == 0) || (sd->h == 0)) return; + + MSG_SLIDER_MED("Slider Calculate : XYWH(%d,%d, %d,%d)", sd->x, sd->y, sd->w, sd->h); + + sd->anim->Stop(); + + _ivug_slider_slide_resize(sd, sd->w, sd->h); + _ivug_slider_slide_move(sd, sd->x, sd->y); +} + +// Smart Object +static void +_ivug_slider_smart_init(void) +{ + if (_smart_) return; + { + const char* name = eina_stringshare_add("ivug-slider"); + MSG_SLIDER_MED("name=%s", name); + static Evas_Smart_Class sc = + { + NULL, + EVAS_SMART_CLASS_VERSION, + _ivug_slider_smart_add, + _ivug_slider_smart_del, + _ivug_slider_smart_move, + _ivug_slider_smart_resize, + _ivug_slider_smart_show, + _ivug_slider_smart_hide, + NULL, + _ivug_slider_smart_clip_set, + _ivug_slider_smart_clip_unset, + _ivug_slider_smart_calculate, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL + }; //Evas_smart_Class + sc.name = name; + _smart_ = evas_smart_class_new(&sc); + } +} + + +/******* slide UI function *******/ + +void +_ivug_slider_slide_move(struct Smart_Data *sd, Evas_Coord x, Evas_Coord y) +{ + IV_ASSERT(sd != NULL); + + MSG_SLIDER_LOW("Slider move. XY(%d,%d)", x, y); +#if 0 + int nOffset = 100; // For debugging + x += nOffset; +#endif +// TODO : If size is smaller than screen's, image should be put in middle + ivug_slider_item_move(sd->slide[CENTER_SLIDE], x, y); + +// TODO : so as to increas perf, dont draw slide under certain condition + ivug_slider_item_move(sd->slide[PREV_SLIDE], x - sd->slide[PREV_SLIDE]->w - IMAGE_BETWEEN_MARGIN , y); + ivug_slider_item_move(sd->slide[NEXT_SLIDE], x + sd->slide[CENTER_SLIDE]->w + IMAGE_BETWEEN_MARGIN , y); +} + +void +_ivug_slider_slide_resize(struct Smart_Data *sd, Evas_Coord w, Evas_Coord h) +{ + IV_ASSERT(sd != NULL); + + ivug_slider_item_resize(sd->slide[CENTER_SLIDE], sd->w, sd->h); + ivug_slider_item_resize(sd->slide[PREV_SLIDE], sd->w, sd->h); + ivug_slider_item_resize(sd->slide[NEXT_SLIDE], sd->w, sd->h); +} + + +static void _ivug_slider_on_tween(double value, void *data) +{ + struct Smart_Data *sd = (struct Smart_Data *)data; + + _ivug_slider_slide_move(sd, value, sd->y); +} + +static void _ivug_slider_on_moment(double value, void *data) +{ + struct Smart_Data *sd = (struct Smart_Data *)data; + + sd->momentum = value; +} + +static bool _ivug_slider_on_ecore_animator(double value, void *pData) +{ + struct Smart_Data *sd = (struct Smart_Data *)pData; + + if ( sd->tween->IsFinished() ) + { + MSG_SLIDER_HIGH("animation ended"); + + shift_direction_t direction = SLIDE_SHIFT_NONE; + + if ( (sd->slide[CENTER_SLIDE]->x - sd->x) + sd->slide[CENTER_SLIDE]->w < 0 ) + { + direction = SLIDE_SHIFT_TO_RIGHT; + } + else if ( (sd->slide[CENTER_SLIDE]->x - sd->x) > sd->w ) + { + direction = SLIDE_SHIFT_TO_LEFT; + } + + _ivug_slider_slide_shift(sd, direction); // Change center item + + delete sd->tween; + sd->tween = NULL; + return false; + } + + MSG_SLIDER_LOW("On Animaion. %f ", value); + + sd->tween->Update(value); + + return true; +} + +void +_ivug_slider_start_slide(struct Smart_Data *sd, int src_x, int dst_x, int momentum) + { + // Slider Move animation. + IV_ASSERT(sd != NULL); + +// TODO : If transition is preceeding, change slide item, + sd->anim->Stop(); + + if ( sd->tween ) delete sd->tween; + sd->tween = NULL; + + if ( src_x == dst_x ) + { + MSG_SLIDER_ERROR("Src and Dest are same."); + return; + } + + double duration; + + duration = (src_x - dst_x) / (double)momentum; + + duration = fabs(duration); + + sd->tween = new CGroupAnimator(); + + sd->tween->AddAnimator(new CSingleAnimator(src_x, dst_x, duration, CTranstionFunc::LinearTransit, _ivug_slider_on_tween, sd)); + sd->tween->AddAnimator(new CSingleAnimator(sd->momentum, 0, duration, CTranstionFunc::LinearTransit, _ivug_slider_on_moment, sd)); + + sd->anim->Start(_ivug_slider_on_ecore_animator, (void *)sd); + + MSG_SLIDER_HIGH("Start scroll anim from %d~%d duration=%f Momentyum=%d~%d", src_x, dst_x, duration, sd->momentum, sd->momentum + (src_x - dst_x)); + +} + +void +_ivug_slider_slide_shift(struct Smart_Data *sd, shift_direction_t direction) +{ + IV_ASSERT(sd != NULL); + + if ( direction == SLIDE_SHIFT_NONE ) + { + MSG_SLIDER_ERROR("Shift none!. just return"); + return; + } + + sd->zoom_level = 0; //reset zoom level + + Media_Item *item = NULL; + Slide_Item *NewItem = NULL; + + if ( direction == SLIDE_SHIFT_TO_RIGHT ) + { + MSG_SLIDER_HIGH( "Slide shited. <-----"); + + NewItem = sd->slide[PREV_SLIDE]; + + item = ivug_medialist_get_next(sd->media_list, sd->slide[NEXT_SLIDE]->mitem); + + sd->slide[PREV_SLIDE] = sd->slide[CENTER_SLIDE]; + sd->slide[CENTER_SLIDE] = sd->slide[NEXT_SLIDE]; + sd->slide[NEXT_SLIDE] = NewItem; + + } + else + { + MSG_SLIDER_HIGH( "Slide shited. ----->"); + + NewItem = sd->slide[NEXT_SLIDE]; + item = ivug_medialist_get_prev(sd->media_list, sd->slide[PREV_SLIDE]->mitem); + + sd->slide[NEXT_SLIDE] = sd->slide[CENTER_SLIDE]; + sd->slide[CENTER_SLIDE] = sd->slide[PREV_SLIDE]; + sd->slide[PREV_SLIDE] = NewItem; + } + + ivug_slider_item_data_set(NewItem, item); //set data. + + _do_load(sd); + + MSG_SLIDER_HIGH("Center slide. XY(%d,%d)", sd->slide[CENTER_SLIDE]->x , sd->slide[CENTER_SLIDE]->y); + + sd->last_dir = direction; + + if ( direction == SLIDE_SHIFT_TO_RIGHT ) + { + _ivug_slider_on_center_changed(sd->obj, sd->slide[PREV_SLIDE], sd->slide[CENTER_SLIDE]); + } + else + { + _ivug_slider_on_center_changed(sd->obj, sd->slide[NEXT_SLIDE], sd->slide[CENTER_SLIDE]); + } + +} + + +Evas_Object* +ivug_slider_add(Evas_Object* parent) +{ + Evas_Object *obj = NULL; + _ivug_slider_smart_init(); //init smart object for ivug slider + + PERF_CHECK_BEGIN(LVL3, "evas_object_smart_add"); + + obj = evas_object_smart_add(evas_object_evas_get(parent), _smart_); //create smart object. + evas_object_name_set(obj, "Slider"); + + ivug_retv_if(!obj, NULL); + + PERF_CHECK_END(LVL3, "evas_object_smart_add"); + + MSG_SLIDER_HIGH("Slider Added Obj(0x%08x) Evas(0x%08x) Parent(0x%08x)", obj, evas_object_evas_get(parent), parent); + + return obj; +} + +void +ivug_slider_start(Evas_Object *obj) +{ + IV_ASSERT(obj != NULL); + struct Smart_Data *sd = (struct Smart_Data *) evas_object_smart_data_get(obj); + + MSG_SLIDER_HIGH("Slider start"); + +} + + +Media_Item * +ivug_slider_get_item(Evas_Object* obj) +{ + IV_ASSERT(obj != NULL); + struct Smart_Data *sd = (struct Smart_Data *) evas_object_smart_data_get(obj); + + return sd->slide[CENTER_SLIDE]->mitem; +} + +slide_state_t +ivug_slider_get_state(Evas_Object* obj) +{ + IV_ASSERT(obj != NULL); + struct Smart_Data *sd = (struct Smart_Data *) evas_object_smart_data_get(obj); + IV_ASSERT(sd != NULL); + + return sd->slide[CENTER_SLIDE]->state; +} + +void +ivug_slider_delete_item(Evas_Object* obj) +{ + IV_ASSERT(obj != NULL); + struct Smart_Data *sd = (struct Smart_Data *) evas_object_smart_data_get(obj); + IV_ASSERT(sd != NULL); + + ivug_slider_item_stop(sd->slide[CENTER_SLIDE]); + + shift_direction_t direction = SLIDE_SHIFT_NONE; + + if (sd->slide[NEXT_SLIDE]->state != SLIDE_STATE_NONE) + { + MSG_SLIDER_HIGH("right slide state : %s", _GetStateString(sd->slide[NEXT_SLIDE]->state)); + direction = SLIDE_SHIFT_TO_RIGHT; + } + else if (sd->slide[PREV_SLIDE]->state != SLIDE_STATE_NONE) + { + MSG_SLIDER_HIGH("left slide state : %s", _GetStateString(sd->slide[PREV_SLIDE]->state)); + direction = SLIDE_SHIFT_TO_LEFT; + } + + MSG_SLIDER_HIGH("shift direction = %d ", direction); + + ivug_medialist_delete_item(sd->media_list, sd->slide[CENTER_SLIDE]->mitem ); //delete data. + ivug_slider_item_data_set(sd->slide[CENTER_SLIDE], NULL); + + Media_Item* item = NULL; + +//move slide. + if ( direction == SLIDE_SHIFT_TO_RIGHT ) // <-------------- Next image + { + Slide_Item *tmp = sd->slide[CENTER_SLIDE]; + + item = ivug_medialist_get_next(sd->media_list, sd->slide[NEXT_SLIDE]->mitem); //get next data. + + sd->slide[CENTER_SLIDE] = sd->slide[NEXT_SLIDE]; + sd->slide[NEXT_SLIDE] = tmp; + + if(item != NULL) + { + ivug_slider_item_data_set(sd->slide[NEXT_SLIDE], item); + ivug_slider_item_load(sd->slide[NEXT_SLIDE]); + } + else + { + MSG_SLIDER_WARN("Item is NULL"); + } + } + else if ( direction == SLIDE_SHIFT_TO_LEFT) // Prev Image -----------> + { + Slide_Item *tmp = sd->slide[CENTER_SLIDE]; + + item = ivug_medialist_get_prev(sd->media_list, sd->slide[PREV_SLIDE]->mitem); + + sd->slide[CENTER_SLIDE] = sd->slide[PREV_SLIDE]; + sd->slide[PREV_SLIDE] = tmp; + + if(item != NULL) + { + ivug_slider_item_data_set(sd->slide[PREV_SLIDE], item); + ivug_slider_item_load(sd->slide[PREV_SLIDE]); + } + else + { + MSG_SLIDER_WARN("Item is NULL"); + } + } + else // Shift none + { + MSG_SLIDER_WARN("Direction is NONE"); + } + + _ivug_slider_slide_move(sd, 0 , 0); //draw item + + _ivug_slider_on_center_changed(sd->obj, NULL, sd->slide[CENTER_SLIDE]); + +// evas_object_smart_callback_call(sd->obj, "slider,item,deleted", sd->slide[CENTER_SLIDE]); + +} + +Eina_Bool +ivug_slider_set_medialist(Evas_Object* obj, Media_List *mList, Media_Item *current) +{ + IV_ASSERT(obj != NULL); + struct Smart_Data *sd = (struct Smart_Data *) evas_object_smart_data_get(obj); + IV_ASSERT(current != NULL); + + sd->media_list = mList; + + //set init + PERF_CHECK_BEGIN(LVL4, "set center"); + + ivug_slider_item_data_set(sd->slide[CENTER_SLIDE], current); + ivug_slider_item_load(sd->slide[CENTER_SLIDE]); + + PERF_CHECK_END(LVL4, "set center"); + + Media_Item *item = ivug_medialist_get_next(sd->media_list, current); + + PERF_CHECK_BEGIN(LVL4, "set next"); + + ivug_slider_item_data_set(sd->slide[NEXT_SLIDE], item); + + PERF_CHECK_END(LVL4, "set next"); + + item = ivug_medialist_get_prev(sd->media_list, current); + + PERF_CHECK_BEGIN(LVL4, "set prev"); + + ivug_slider_item_data_set(sd->slide[PREV_SLIDE], item); + + PERF_CHECK_END(LVL4, "set prev"); + + PERF_CHECK_BEGIN(LVL4, "_ivug_slider_on_center_changed"); + + _ivug_slider_on_center_changed(sd->obj, NULL, sd->slide[CENTER_SLIDE]); + + PERF_CHECK_END(LVL4, "_ivug_slider_on_center_changed"); + + return EINA_TRUE; +}//ivug slider set list + +void +ivug_slider_set_item(Evas_Object* obj, Media_Item *newItem, slide_dir_t dir) +{ + IV_ASSERT(obj != NULL); + IV_ASSERT(newItem != NULL); + + struct Smart_Data *sd = (struct Smart_Data *) evas_object_smart_data_get(obj); + + MSG_SLIDER_HIGH("Slider set item. Dir=%d", dir); + + Media_Item *mitem = NULL; + + if ( ivug_slider_item_data_get(sd->slide[CENTER_SLIDE]) == newItem ) + { + MSG_SLIDER_HIGH("Same item."); + return ; + } + + switch(dir) + { + case SLIDE_TO_RIGHT: // <--------------- Next image + ivug_slider_item_data_set(sd->slide[NEXT_SLIDE], newItem); + + _ivug_slider_start_slide(sd, sd->slide[CENTER_SLIDE]->x , sd->slide[CENTER_SLIDE]->w + IMAGE_BETWEEN_MARGIN, ANIN_VELOCITY); + + mitem = ivug_medialist_get_prev(sd->media_list, newItem); + + ivug_slider_item_data_set(sd->slide[PREV_SLIDE], mitem); + break; + case SLIDE_TO_LEFT: // Prev Image ------------------> + ivug_slider_item_data_set(sd->slide[PREV_SLIDE], newItem); + + _ivug_slider_start_slide(sd, sd->slide[CENTER_SLIDE]->x , sd->slide[CENTER_SLIDE]->w + IMAGE_BETWEEN_MARGIN, ANIN_VELOCITY); + + mitem = ivug_medialist_get_next(sd->media_list, newItem); + + ivug_slider_item_data_set(sd->slide[NEXT_SLIDE], mitem); + break; + case SLIDE_INSTANTLY: +// For avoid blinking, set item in next_slide and then swap with center + ivug_slider_item_data_set(sd->slide[NEXT_SLIDE], newItem); + + Slide_Item *sitem = sd->slide[CENTER_SLIDE]; + sd->slide[CENTER_SLIDE] = sd->slide[NEXT_SLIDE]; + sd->slide[NEXT_SLIDE] = sitem; + + _ivug_slider_slide_move(sd, 0, 0); + + mitem = ivug_medialist_get_next(sd->media_list, newItem); + ivug_slider_item_data_set(sd->slide[NEXT_SLIDE], mitem); + + mitem = ivug_medialist_get_prev(sd->media_list, newItem); + ivug_slider_item_data_set(sd->slide[PREV_SLIDE], mitem); + + _ivug_slider_on_center_changed(sd->obj, sitem , sd->slide[CENTER_SLIDE]); + break; + } + +} + + +// Goto Background +void +ivug_slider_pause(Evas_Object *obj) +{ + IV_ASSERT(obj != NULL); + struct Smart_Data *sd = (struct Smart_Data *) evas_object_smart_data_get(obj); + + MSG_SLIDER_HIGH("Slider pause"); + + ivug_slider_item_pause(sd->slide[CENTER_SLIDE]); +} + +// Goto Foreground +void +ivug_slider_resume(Evas_Object *obj) +{ + IV_ASSERT(obj != NULL); + struct Smart_Data *sd = (struct Smart_Data *) evas_object_smart_data_get(obj); + + MSG_SLIDER_HIGH("Slider resume"); + + ivug_slider_item_resume(sd->slide[CENTER_SLIDE]); +} + +void +ivug_slider_skip(Evas_Object* obj) +{ + ivug_ret_if(!obj); // TODO + struct Smart_Data *sd = (struct Smart_Data *) evas_object_smart_data_get(obj); + + if ( sd->last_dir == SLIDE_SHIFT_TO_RIGHT) // <-------------- + { + if(sd->slide[NEXT_SLIDE]->mitem == NULL) + { + MSG_SLIDER_HIGH("next is NULL"); + if(sd->slide[PREV_SLIDE]->mitem == NULL) + { + MSG_SLIDER_HIGH("prev is NULL too, exit Image viewer"); + ug_destroy_me(gGetUGHandle()); + return; + } + _ivug_slider_start_slide(sd, sd->slide[CENTER_SLIDE]->x , sd->slide[CENTER_SLIDE]->w + IMAGE_BETWEEN_MARGIN, ANIN_VELOCITY); + } + else + { + _ivug_slider_start_slide(sd, sd->slide[CENTER_SLIDE]->x , -sd->slide[CENTER_SLIDE]->w - IMAGE_BETWEEN_MARGIN, ANIN_VELOCITY); + } + } + else if (sd->last_dir == SLIDE_SHIFT_TO_LEFT) // --------------> + { + if(sd->slide[PREV_SLIDE]->mitem == NULL) + { + MSG_SLIDER_HIGH("prev is NULL"); + if(sd->slide[NEXT_SLIDE]->mitem == NULL) + { + MSG_SLIDER_HIGH("mext is NULL too, exit Image viewer"); + ug_destroy_me(gGetUGHandle()); + return; + } + _ivug_slider_start_slide(sd, sd->slide[CENTER_SLIDE]->x , -sd->slide[CENTER_SLIDE]->w - IMAGE_BETWEEN_MARGIN, ANIN_VELOCITY); + } + else + { + _ivug_slider_start_slide(sd, sd->slide[CENTER_SLIDE]->x , sd->slide[CENTER_SLIDE]->w + IMAGE_BETWEEN_MARGIN, ANIN_VELOCITY); + } + } +} + +bool ivug_slider_load(Evas_Object* obj) +{ + IV_ASSERT(obj != NULL); + struct Smart_Data *sd = (struct Smart_Data *) evas_object_smart_data_get(obj); + + ivug_retv_if(!sd, EINA_FALSE); //check smart data. + + if ( sd->item_load_idler ) + { + ecore_idler_del(sd->item_load_idler); + sd->item_load_idler = NULL; + } + + sd->item_load_idler = ecore_idler_add(_item_loader, (void *)obj); + + return true; +} + +void +ivug_slider_set_menu_visibility(Evas_Object* obj, Eina_Bool bVisible) +{ + IV_ASSERT(obj != NULL); + struct Smart_Data *sd = (struct Smart_Data *) evas_object_smart_data_get(obj); + + Slide_Item *si = sd->slide[CENTER_SLIDE]; + + if ( bVisible == EINA_TRUE ) + { + ivug_slider_item_show_menu(si); + } + else + { + ivug_slider_item_hide_menu(si); + } +} + + + + +// For debugging. +void ivug_slider_dump_photocam(Evas_Object* obj) +{ + struct Smart_Data *sd = (struct Smart_Data *) evas_object_smart_data_get(obj); + +// EFL::dump_obj(sd->slide[CENTER_SLIDE]->photocam, 0); +// EFL::dump_obj(obj, 0); + + Evas_Object *clipper; + + clipper = evas_object_clip_get(obj); + if (clipper) + { + Eina_List *clippees; + + Eina_List *l; + + clippees = (Eina_List *)evas_object_clipees_get(clipper); + MSG_SLIDER_HIGH("Clipper clips %i objects", eina_list_count(clippees)); + + void *data; + + EINA_LIST_FOREACH(clippees, l, data) + { + Evas_Object *obj_tmp = (Evas_Object *)data; + + int x, y, w, h; + evas_object_geometry_get(obj_tmp, &x, &y, &w, &h); + + MSG_SLIDER_HIGH("Obj=%s(%s) Geometry(%d,%d,%d,%d)", + evas_object_name_get(obj_tmp), evas_object_type_get(obj_tmp), + x, y, w, h); + // evas_object_show(obj_tmp); + } + } + + + Evas *e = evas_object_evas_get(sd->slide[CENTER_SLIDE]->photocam); + + int w, h; + + evas_output_size_get(e, &w, &h); + + int vx, vy, vw, vh; + + evas_output_viewport_get(e, &vx, &vy, &vw, &vh); + + EFL::dump_obj(sd->obj); + + MSG_SLIDER_HIGH("Evas Size(%d,%d) Viewport(%d,%d,%d,%d)", w, h, vx, vy, vw, vh); + +} + +unsigned int +ivug_slider_zoom_level_get(Evas_Object *obj) +{ + IV_ASSERT(obj != NULL); + struct Smart_Data *sd = (struct Smart_Data *) evas_object_smart_data_get(obj); + + MSG_SLIDER_HIGH("Slider zoom level"); + + return sd->zoom_level; +} + +void +ivug_slider_zoom_in(Evas_Object *obj) +{ + IV_ASSERT(obj != NULL); + struct Smart_Data *sd = (struct Smart_Data *) evas_object_smart_data_get(obj); + + MSG_SLIDER_HIGH("Slider zoom in"); + + if(sd->zoom_level > ZOOM_LEVEL_MAX) + { + MSG_MAIN_ERROR("zoom_level is %d", sd->zoom_level); + return; + } + + Slide_Item *si = sd->slide[CENTER_SLIDE]; + + double zoom = 0.0; + Evas_Coord ix = 0, iy= 0, iw= 0, ih= 0; + + evas_object_geometry_get(si->photocam, &ix, &iy, &iw, &ih); + + zoom = ivug_slider_item_zoom_get(si); + zoom *= ZOOM_LEVEL_STEP; + ivug_slider_item_zoom_set(si, zoom, iw/2, ih/2); + + ivug_slider_item_hold_set(si, EINA_FALSE); + + sd->zoom_level++; +} + +void +ivug_slider_zoom_out(Evas_Object *obj) +{ + IV_ASSERT(obj != NULL); + struct Smart_Data *sd = (struct Smart_Data *) evas_object_smart_data_get(obj); + + MSG_SLIDER_HIGH("Slider zoom in"); + + if(sd->zoom_level == 0) + { + MSG_MAIN_ERROR("zoom_level is 0"); + return; + } + + Slide_Item *si = sd->slide[CENTER_SLIDE]; + + double zoom = 0.0; + Evas_Coord ix = 0, iy= 0, iw= 0, ih= 0; + + evas_object_geometry_get(si->photocam, &ix, &iy, &iw, &ih); + + zoom = ivug_slider_item_zoom_get(si); + zoom /= ZOOM_LEVEL_STEP; + ivug_slider_item_zoom_set(si, zoom, iw/2, ih/2); + + ivug_slider_item_hold_set(si, EINA_FALSE); + + sd->zoom_level--; +} + diff --git a/main/src/view/ivug-crop-view.cpp b/main/src/view/ivug-crop-view.cpp new file mode 100755 index 0000000..49411d0 --- /dev/null +++ b/main/src/view/ivug-crop-view.cpp @@ -0,0 +1,494 @@ +/* + * Copyright 2012 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.tizenopensource.org/license + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include + +#include "ivug-crop-view.h" +#include "EFLUtil.h" +#include "ivug-debug.h" +#include "ivug-image.h" +#include "ivug-scissorbox.h" +#include "ivug-context.h" +#include "ivug-util.h" +#include "ivug-selectioninfo.h" + +#undef LOG_LVL +#define LOG_LVL DBG_MSG_LVL_MED + +#undef LOG_CAT +#define LOG_CAT "IV-CROP" + +#define EDJ_PATH PREFIX"/res/edje/"PACKAGE + +static void _on_layout_resized(void *data, Evas *e, Evas_Object *obj, void *event_info) +{ + IvugCropView *pCropView = static_cast(data); + /////////////////////////////////////////////////////////////////// + int org_x, org_y, org_w, org_h; + + ivug_image_region_get(pCropView->photocam, &org_x, &org_y, &org_w, &org_h); + + if(org_w == 0 || org_h == 0) + return; + + MSG_MED("org_x=%d, org_y=%d, org_w=%d, org_h=%d", org_x, org_y, org_w, org_h); + + int org_sx, org_sy, org_sw, org_sh; + ivug_scissorbox_region_get(pCropView->cropbox, &org_sx, &org_sy, &org_sw, &org_sh); + + MSG_MED("org_sx=%d, org_sy=%d, org_sw=%d, org_sh=%d", org_sx, org_sy, org_sw, org_sh); + + int dx = org_sx-org_x; + int dy = org_sy-org_y; + + int lcd_x, lcd_y, lcd_w, lcd_h; + + evas_object_geometry_get(obj, &lcd_x, &lcd_y, &lcd_w, &lcd_h); + MSG_MED("lcd_x=%d, lcd_y=%d, lcd_w=%d, lcd_h=%d", lcd_x, lcd_y, lcd_w, lcd_h); + + int ph, pw; + + int img_w, img_h; + int ext_w, ext_h; + + img_w = org_w; + img_h = org_h; + ext_w = lcd_w; + ext_h = lcd_h; + + ph = (img_h * ext_w) / img_w; + + if (ph > ext_h) + { + pw = (img_w * ext_h) / img_h; + ph = ext_h; + } + else + { + pw = ext_w; + } + + double zoom = 0.0; + + if ( img_w > img_h) + { + zoom = (double)pw / img_w; + } + else + { + zoom = (double)ph / img_h; + } + + int sx, sy, sw, sh; + + sw = org_sw*zoom; + sh = org_sh*zoom; + dx *= zoom; + dy *= zoom; + + sx = (ext_w-img_w*zoom)/2 + dx; + sy = (ext_h-img_h*zoom)/2 + dy; + + ivug_scissorbox_boundary_set(pCropView->cropbox, (ext_w-img_w*zoom)/2, (ext_h-img_h*zoom)/2, img_w*zoom, img_h*zoom); + + /////////////////////////////////////////////////////////////////// + + MSG_MED("sx=%d, sy=%d, sw=%d, sh=%d", sx, sy, sw, sh); + + ivug_scissorbox_region_set(pCropView->cropbox, sx, sy, sw, sh); +} + +void _on_test(void *data, Evas_Object *obj, void *event_info) +{ + MSG_HIGH("Test signal received"); +} + +static Eina_Bool _on_crop_timer_expired(void *data) +{ + IvugCropView *pCropView = static_cast(data); + + pCropView->timer = NULL; + + elm_object_disabled_set(pCropView->btn_ok, EINA_FALSE); + + MSG_HIGH("Image preloaded"); + + int x, y, w, h; + ivug_image_region_get(pCropView->photocam, &x, &y, &w, &h); + + // Check error!. + + MSG_HIGH("Photcam image Geometry : %d,%d,%d,%d", x, y, w, h); + + // Get Internal image and set that as scissorbox client + Evas_Object *subObj = ivug_image_internal_image_get(pCropView->photocam); + + // Move crop box + ivug_scissorbox_attach(pCropView->cropbox, subObj); + + int nW = 0; + int nH = 0; + + if(pCropView->w > 0 && pCropView->h > 0) + { + nW = pCropView->w; + nH = pCropView->h; + } + else + { + nW = w / 2; + nH = h / 2; + } + + ivug_scissorbox_region_set(pCropView->cropbox, x + (w - nW) / 2, y + (h - nH) / 2, nW, nH); + + pCropView->notify = ivug_notify_create(pCropView->layout, IDS_CROP_NOTIFY); + + return ECORE_CALLBACK_CANCEL; +} + +void _on_preloaded(void *data, Evas_Object *obj, void *event_info) +{ + IV_ASSERT(data != NULL); + + IvugCropView *pCropView = static_cast(data); + + MSG_HIGH("Image preloaded"); + + double zoom = ivug_image_zoom_get(pCropView->photocam); + + MSG_HIGH("zoom = %g", zoom); + + pCropView->timer = ecore_timer_add(0.5, _on_crop_timer_expired, data); + + return; +} + +static void +_ivug_crop_view_response_cb( void *data, Evas_Object *obj, void *event_info ) +{ + IV_ASSERT(obj != NULL); + IV_ASSERT(data != NULL); + + MSG_HIGH( "response callback=%d",(int)event_info); + IvugCropView *pCropView = static_cast(data); + + evas_object_hide(obj); // popup + evas_object_del(obj); + + // Remove view. + evas_object_smart_callback_call(pCropView->layout, "destroyed", NULL); + + evas_object_smart_callback_call(pCropView->layout, "ok,clicked", pCropView->result_path); + + ivug_crop_view_destroy(pCropView); +} + + +static Evas_Object* +_show_exit_popup( Evas_Object *parent, const char *title, const char *desc, void *data) +{ + MSG_HIGH( "title: %s, desc %s", title, desc); + + Evas_Object* style1_popup = elm_popup_add(parent); + evas_object_size_hint_weight_set(style1_popup, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + elm_popup_timeout_set(style1_popup, (double)2.0); + elm_object_text_set(style1_popup, desc); + elm_object_part_text_set(style1_popup, "title,text", title); + + evas_object_smart_callback_add(style1_popup, "timeout", _ivug_crop_view_response_cb, data); + + evas_object_show(style1_popup); + evas_object_layer_set(style1_popup, EVAS_LAYER_MAX); + + return style1_popup; +} + +static void _on_btn_save(void *data, Evas_Object *obj, void *event_info) +{ + IV_ASSERT(data != NULL); + + IvugCropView *pCropView = static_cast(data); + int rx, ry, rw, rh; + Evas_Object *ret_image = NULL; + + char* save_file = ivug_generate_file_name(pCropView->file_path); + if(save_file == NULL) + { + MSG_SETAS_ERROR("Cannot generate file name"); + goto SAVE_FAILED; + } + + MSG_HIGH("Save clicked. %s", save_file); + +// Get region + ivug_scissorbox_region_get(pCropView->cropbox, &rx, &ry, &rw, &rh); + +// Save File + MSG_HIGH("SCissorbox Rect:(%d,%d,%d,%d)", rx, ry, rw, rh); + + ret_image = ivug_image_region_image_get(pCropView->photocam, rx, ry, rw, rh); + + if(ret_image == NULL) + { + MSG_ERROR("Region get faied."); + goto SAVE_FAILED; + } + + if (evas_object_image_save(ret_image, save_file, NULL, "quality=100 compress=9") == EINA_FALSE) + { + MSG_ERROR("evas_object_image_save error. %s", save_file); + goto SAVE_FAILED; + } + +// Check again! + { + int fd = open(save_file, O_RDONLY); + if(fd < 0) + { + MSG_ERROR("%s open error[%d]", save_file, fd); + goto SAVE_FAILED; + } + + int ret = close(fd); + if(ret < 0) + { + MSG_ERROR("%s open error[%d]", save_file, ret); + } + } + + pCropView->result_path = strdup(save_file); + + _show_exit_popup(pCropView->layout, IDS_CROP, IDS_SUCCESS, data); + + evas_object_del(ret_image); + free(save_file); + + return; + +SAVE_FAILED: + _show_exit_popup(pCropView->layout, IDS_CROP, IDS_FAILED, data); + + if(ret_image) + evas_object_del(ret_image); + if(save_file) + free(save_file); + + return; +} + +static void _on_btn_cancel(void *data, Evas_Object *obj, void *event_info) +{ + IV_ASSERT(data != NULL); + + IvugCropView *pCropView = static_cast(data); + + MSG_HIGH("Cancel clicked"); + + evas_object_smart_callback_call(pCropView->layout, "destroyed", NULL); + + evas_object_smart_callback_call(pCropView->layout, "cancel,clicked", NULL); + + ivug_crop_view_destroy(pCropView); +} + +static Evas_Event_Flags _finger_tap_end(void *data , void *event_info) +{ + Elm_Gesture_Taps_Info *p = (Elm_Gesture_Taps_Info *) event_info; + + MSG_HIGH("Finger tab end. evt=%d", p->timestamp); + + if ( p->n != 1 ) return EVAS_EVENT_FLAG_NONE; + + IvugCropView *pCropView = static_cast(data); + IV_ASSERT(pCropView != NULL); + + if(pCropView->bShowMenu) + { + MSG_HIGH("Hide"); + elm_win_indicator_mode_set((Evas_Object*)ug_get_window(), ELM_WIN_INDICATOR_HIDE); + evas_object_hide(pCropView->notify); + edje_object_signal_emit(_EDJ(pCropView->layout), "elm,state,hide", "event"); + } + else + { + MSG_HIGH("Show"); + elm_win_indicator_mode_set((Evas_Object*)ug_get_window(), ELM_WIN_INDICATOR_SHOW); + evas_object_show(pCropView->notify); + edje_object_signal_emit(_EDJ(pCropView->layout), "elm,state,show", "event"); + } + + pCropView->bShowMenu = !pCropView->bShowMenu; + + return EVAS_EVENT_FLAG_NONE; +} + +void _add_gesture_layer(Evas_Object *parent, IvugCropView *pCropView) +{ + IV_ASSERT(pCropView != NULL); + + Evas_Object *gesture = pCropView->gesture; + + gesture = elm_gesture_layer_add(parent); + elm_gesture_layer_hold_events_set(gesture, EINA_TRUE); + + elm_gesture_layer_cb_set(gesture, ELM_GESTURE_N_TAPS, ELM_GESTURE_STATE_END, _finger_tap_end, (void *)pCropView); + + if ( elm_gesture_layer_attach(gesture, pCropView->photocam) == EINA_FALSE) + { + MSG_ERROR("Cannot attach event rect"); + } + + evas_object_name_set(gesture, "Crop:Getsture"); +} + +IvugCropView *ivug_crop_view_create(Evas_Object *parent) +{ + IvugCropView *pCropView = (IvugCropView *)calloc(1, sizeof(IvugCropView)); + + Evas_Object *layout; + + layout = EFL::create_layout(parent, EDJ_PATH"/ivug-crop-view.edj", "crop_view"); + + if ( layout == NULL ) + { + MSG_ERROR("Cannot create crop view"); + delete pCropView; + + return NULL; + } + + pCropView->layout = layout; + evas_object_event_callback_add(layout, EVAS_CALLBACK_RESIZE, _on_layout_resized, pCropView ); + evas_object_size_hint_weight_set(layout, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND ); + + pCropView->photocam = ivug_image_create(layout); + ivug_image_animated_set(pCropView->photocam, EINA_FALSE); + ivug_image_hold_set(pCropView->photocam , EINA_TRUE); // Disable mouse events + evas_object_smart_callback_add(pCropView->photocam, "loaded", _on_preloaded, pCropView); + + elm_object_part_content_set(layout, "photocam", pCropView->photocam ); + + pCropView->bShowMenu = true; + _add_gesture_layer(layout, pCropView); + + pCropView->cropbox = ivug_scissorbox_add(layout); + ivug_scissorbox_type_set(pCropView->cropbox, SCISSOR_BOX_TYPE_2); + + elm_object_part_content_set(layout, "scissorbox", pCropView->cropbox); + +// Create button + Evas_Object *btn = NULL; + + btn = EFL::create_button(layout, "btn_style1", NULL, IDS_SAVE); + evas_object_smart_callback_add(btn, "clicked", _on_btn_save, (void *)pCropView); + elm_object_part_content_set(layout, "btn.save", btn); + + pCropView->btn_ok = btn; + + btn = EFL::create_button(layout, "btn_style1", NULL, IDS_CANCEL); + evas_object_smart_callback_add(btn, "clicked", _on_btn_cancel, (void *)pCropView); + elm_object_part_content_set(layout, "btn.cancel", btn); + + MSG_HIGH("Create CropView"); + + evas_object_smart_callback_add(layout, "test", _on_test, NULL); + + elm_object_disabled_set(pCropView->btn_ok, EINA_TRUE); + + elm_win_resize_object_add(gGetCurrentWindow(), layout); + + evas_object_show(layout); + + pCropView->w = 0; + pCropView->h = 0; + + return pCropView; + +} + +bool ivug_crop_view_box_size_set(IvugCropView *pCropView, int w, int h) +{ + IV_ASSERT(pCropView != NULL); + + pCropView->w = w; + pCropView->h = h; + + return true; +} + +bool ivug_crop_view_box_ratio_fix(IvugCropView *pCropView, bool bFix) +{ + IV_ASSERT(pCropView != NULL); + + ivug_scissorbox_ratio_fix(pCropView->cropbox, bFix); + + return true; +} + +bool ivug_crop_view_file_set(IvugCropView *pCropView, const char *file) +{ + IV_ASSERT(pCropView != NULL); + + Evas_Load_Error err; + + if ( pCropView->file_path ) + { + free(pCropView->file_path); + } + + pCropView->file_path = strdup(file); + + err = ivug_image_file_set(pCropView->photocam, file, NULL); + evas_object_smart_callback_call(pCropView->layout, "test", NULL); + + return true; +} + +void ivug_crop_view_destroy(IvugCropView *pCropView) +{ + IV_ASSERT(pCropView != NULL); + + MSG_HIGH("Destroy CropView"); + + if(pCropView->timer) + { + ecore_timer_del(pCropView->timer); + pCropView->timer = NULL; + } + + if ( pCropView->file_path ) + free(pCropView->file_path); + + if ( pCropView->result_path) + free(pCropView->result_path); + + if ( pCropView->layout ) + evas_object_del(pCropView->layout); + + delete pCropView; +} + +Evas_Object *ivug_crop_view_get_object(IvugCropView *pCropView) +{ + IV_ASSERT(pCropView != NULL); + + return pCropView->layout; +} + + + diff --git a/main/src/view/ivug-main-view-menu.cpp b/main/src/view/ivug-main-view-menu.cpp new file mode 100755 index 0000000..6326801 --- /dev/null +++ b/main/src/view/ivug-main-view-menu.cpp @@ -0,0 +1,920 @@ +/* + * Copyright 2012 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.tizenopensource.org/license + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "ivug-common.h" +#include "ivug-main-view.h" +#include "ivug-main-view-toolbar.h" +#include "ivug-main-view-menu.h" + +#include "ivug-slider.h" +#include "ivug-listpopup.h" +#include "ivug-ext-ug.h" +#include "ivug-popup.h" +#include "ivug-selectioninfo.h" + +#include "ivug-media.h" +#include "ivug-slideshow.h" + +#include "ivug-file-info.h" + +#include "ivug-exif.h" + +#include +#include // ug_destroy_me, ug_send_result +#include //app_manager_get_app_name + +#include "ivug-crop-view.h" + +enum { + IVUG_SHARE_TYPE_MESSAGE = 0x00, + IVUG_SHARE_TYPE_EMAIL, + IVUG_SHARE_TYPE_BLUETOOTH, + IVUG_SHARE_TYPE_PRINT_VIA_BLUETOOTH, + IVUG_SHARE_TYPE_SNS, + IVUG_SHARE_TYPE_WIFI, + IVUG_SHARE_TYPE_PRINT, +}; + +//set as +enum { + IVUG_SET_AS_TYPE_HOME = 0x00, + IVUG_SET_AS_TYPE_LOCK, + IVUG_SET_AS_TYPE_BOTH, + IVUG_SET_AS_TYPE_CALLER_ID, +}; + +#undef IVUG_DEFINE_EXIF_ROTATE + +#define POPUP_ICON_DIRECTORY_PATH IMAGE_PATH"/Popup_icon" + +#define ICON_PATH_CROP POPUP_ICON_DIRECTORY_PATH"/T01_1_popup_icon_Crop.png" +#define ICON_PATH_PASTE_FROM_CLIPBOARD POPUP_ICON_DIRECTORY_PATH"/T01_1_popup_icon_Paste from Clipboard.png" + +static void +_on_ext_ug_destroy_cb(ui_gadget_h ug, void *priv) +{ + if (!ug ) return; + + Ivug_MainView *pMainView = (Ivug_MainView *)priv; + + MSG_IMAGEVIEW_HIGH("UG destroyed"); + + pMainView->ext_ug = NULL; + + ivug_main_view_set_hide_timer(pMainView); +} + +static void _on_selectioninfo_deleted(void * data, Evas * e, Evas_Object * obj, void * event_info) +{ + Ivug_MainView *pMainView = (Ivug_MainView *)data; + IV_ASSERT(pMainView != NULL); + + MSG_MAIN_HIGH("selection info deleted"); + + pMainView->selectioninfo = NULL; +} + +void _ivug_selectioninfo_create(Ivug_MainView *pMainView, const char *string) +{ + IV_ASSERT(pMainView != NULL); + + if(pMainView->selectioninfo) + { + evas_object_del(pMainView->selectioninfo); + pMainView->selectioninfo = NULL; + } + + pMainView->selectioninfo = ivug_selectioninfo_create(pMainView->layout, string); + IV_ASSERT(pMainView->selectioninfo != NULL); + + evas_object_event_callback_add(pMainView->selectioninfo, EVAS_CALLBACK_DEL, _on_selectioninfo_deleted, pMainView); +} + + +void _delete_details_view(Ivug_MainView *pMainView ) +{ + Evas_Object *detail_view_layout = elm_object_item_part_content_unset(pMainView->navi_it, "elm.swallow.detail"); + + MSG_MAIN_HIGH("Delete detail view. old layout=0x%08x", detail_view_layout); + + ivug_details_view_destroy(pMainView->pDetailsView); // Delete detail view. + pMainView->pDetailsView = NULL; + +} + +static void +_on_setasview_deleted(void *data, Evas *e , Evas_Object *obj , void *event_info ) +{ + ivug_retm_if(!data, "data is NULL"); + Ivug_MainView *pMainView = (Ivug_MainView *)data; + MSG_MAIN_HIGH("SetAS View is destroyed"); + + pMainView->pSetAsView = NULL; + + ivug_main_view_set_hide_timer(pMainView); +} + +static void +_on_popup_response(void *data, Evas_Object *obj, void *event_info) +{ + IV_ASSERT(data != NULL); + Ivug_MainView *pMainView = (Ivug_MainView *)data; + ivug_main_view_set_hide_timer(pMainView); +} + +void _on_share_selected(void *data, Evas_Object *obj, void *event_info) +{ + IV_ASSERT(data != NULL); + + Ivug_MainView *pMainView = (Ivug_MainView *)data; + IV_ASSERT(pMainView->ext_ug == NULL); + + Ivug_ListPopup_Item *item = (Ivug_ListPopup_Item *)event_info; + + const char *label = (const char *)ivug_listpopup_item_get_data(item); + + if(label == NULL) + { + MSG_MAIN_ERROR("label is NULL"); + evas_object_del(obj); + ivug_main_view_set_hide_timer(pMainView); + return; + } + MSG_MAIN_HIGH("text(%s) is clicked", label); + + Media_Item *mitem = ivug_slider_get_item(pMainView->slider); + Media_Data *mdata = ivug_medialist_get_data(mitem); + + if(mdata == NULL) + { + MSG_MAIN_ERROR("sd is NULL"); + evas_object_del(obj); + return; + } + + char *path = NULL; + path = mdata->filepath; + + bool ret = false; + + ret = ivug_ext_launch_default(path, SERVICE_OPERATION_SEND, label, data); + + /* appsvc failed or ug_create failed */ + if(ret == false) + { + ivug_1btn_popup_show(pMainView->layout, NULL, IDS_APPLICATION_NOT_INSTALLED, _on_popup_response, pMainView); + } + + evas_object_del(obj); +} + +void _on_setas_selected(void *data, Evas_Object *obj, void *event_info) +{ + IV_ASSERT(data != NULL); + + Ivug_MainView *pMainView = (Ivug_MainView *)data; + + + Ivug_ListPopup_Item *item = (Ivug_ListPopup_Item *)event_info; + + const char *label = (const char *)ivug_listpopup_item_get_data(item); + + if(label == NULL) + { + MSG_MAIN_ERROR("label is NULL"); + evas_object_del(obj); + ivug_main_view_set_hide_timer(pMainView); + return; + } + MSG_MAIN_HIGH("text(%s) is clicked", label); + + Media_Item *mitem = ivug_slider_get_item(pMainView->slider); + Media_Data *mdata = ivug_medialist_get_data(mitem); + if(mdata == NULL) + { + MSG_MAIN_ERROR("sd is NULL"); + evas_object_del(obj); + ivug_main_view_set_hide_timer(pMainView); + return; + } + + Evas_Object *setasOjbect; + + if(strncmp(label, IDS_HOME_SCREEN, strlen(label)) == 0) + { + pMainView->pSetAsView = ivug_setas_view_screen_create(pMainView->layout, mdata->filepath, + IVUG_SETAS_NORMAL, IVUG_CTRLBAR_SET_SCREEN_HOME); + setasOjbect = ivug_setas_view_object_get(pMainView->pSetAsView); + evas_object_event_callback_add(setasOjbect, EVAS_CALLBACK_DEL, _on_setasview_deleted, pMainView); + } + else if(strncmp(label, IDS_LOCK_SCREEN, strlen(label)) == 0) + { + pMainView->pSetAsView = ivug_setas_view_screen_create(pMainView->layout, mdata->filepath, + IVUG_SETAS_NORMAL, IVUG_CTRLBAR_SET_SCREEN_LOCK); + setasOjbect = ivug_setas_view_object_get(pMainView->pSetAsView); + evas_object_event_callback_add(setasOjbect, EVAS_CALLBACK_DEL, _on_setasview_deleted, pMainView); + } + else if(strncmp(label, IDS_HOME_AND_LOCK_SCREENS, strlen(label)) == 0) + { + pMainView->pSetAsView = ivug_setas_view_screen_create(pMainView->layout, mdata->filepath, + IVUG_SETAS_NORMAL, IVUG_CTRLBAR_SET_SCREEN_BOTH); + setasOjbect = ivug_setas_view_object_get(pMainView->pSetAsView); + evas_object_event_callback_add(setasOjbect, EVAS_CALLBACK_DEL, _on_setasview_deleted, pMainView); + } + else if(strncmp(label, IDS_CALLER_IMAGE, strlen(label)) == 0) + { + pMainView->ext_ug = ivug_ext_launch_contact(mdata->filepath, _on_ext_ug_destroy_cb, data); + } + + evas_object_del(obj); +} + +static void +_on_delete_selected(void *data, Evas_Object *obj, void *event_info) +{ + Ivug_MainView *pMainView = (Ivug_MainView *)data; + IV_ASSERT(pMainView != NULL); + + int response_id = (int)event_info; + if(response_id == POPUP_RESPONSE_CANCEL) + { + MSG_MAIN_HIGH("cancel selected"); + ivug_main_view_set_hide_timer(pMainView); + return; + } + + if(pMainView->pDetailsView) + { + MSG_MAIN_HIGH("Delete details view."); + _change_close_to_details(pMainView); + _delete_details_view(pMainView); + } + + MSG_MAIN_HIGH("Removing current slide."); + + ivug_main_view_set_hide_timer(pMainView); + + _ivug_selectioninfo_create(pMainView, IDS_DELETED); + + ivug_slider_delete_item(pMainView->slider); // this routine fire "item.changed" +} + +static void +_on_rename_selected(void *data, Evas_Object *obj, void *event_info) +{ + int response_id = (int)event_info; + IV_ASSERT(data != NULL); + + Ivug_MainView *pMainView = (Ivug_MainView *)data; + + MSG_MAIN_HIGH("DRM popup selected : %d", response_id); + + if(response_id == POPUP_RESPONSE_CANCEL) + { + MSG_MAIN_HIGH("cancel selected"); + } + else + { + MSG_MAIN_HIGH("unlock process"); + + Media_Item *mitem = ivug_slider_get_item(pMainView->slider); + Media_Data *mdata = ivug_medialist_get_data(mitem); + + IV_ASSERT(mdata != NULL); + + const char *old_fullpath = mdata->filepath; + char *old_dir = ecore_file_dir_get(old_fullpath); + char *ext = ivug_fileinfo_get_file_extension(old_fullpath); + + Evas_Object *popup = obj; + Evas_Object *layout = elm_object_content_get(popup); + Evas_Object *entry = elm_object_part_content_get(layout, "elm.swallow.content"); + + const char *new_name = elm_entry_entry_get(entry); + char new_fullpath[IVUG_MAX_FILE_PATH_LEN] = {0,}; + snprintf(new_fullpath, sizeof(new_fullpath),"%s/%s.%s", old_dir, new_name, ext); + + if(ivug_rename_file(old_fullpath, new_fullpath) == false) + { + MSG_MAIN_ERROR("ivug_rename_file failed"); + } + else + { + MSG_MAIN_HIGH("Rename %s -> %s", old_fullpath, new_fullpath); + free(mdata->filepath); + mdata->filepath = strdup(new_fullpath); + } + } + ivug_main_view_set_hide_timer(pMainView); +} + + +//////////////////////////////////////////////////////////////////////////////////////////////////////////// +// +// Button handlers +// + +static void _dismissed_cb(void *data, Evas_Object *obj, void *event_info) +{ + Ivug_MainView *pMainView = (Ivug_MainView *)data; + //evas_object_del(obj); + ivug_main_view_set_hide_timer(pMainView); + + if(pMainView->popup) + { + MSG_MAIN_HIGH("Removing popup 1"); + evas_object_del(pMainView->popup); + pMainView->popup = NULL; + } + else + { + MSG_MAIN_HIGH("Removing popup 2"); + evas_object_del(obj); + } + + MSG_MAIN_HIGH("Popup dismissed"); +} + +#ifndef USE_DEFAULT_DOWNLOADS_FOLDER +static bool +_iter_album_list(media_handle media, void *user_data) +{ + ivug_listpopup_itemlist items = (ivug_listpopup_itemlist)user_data; + + char *name = ivug_db_get_folder_name(media); + char *path = ivug_db_get_folder_path(media); + + if(strlen(name) == 0) + { + ivug_listpopup_itemlist_add(items, 0, NULL, IDS_NO_NAME, (void *)strdup(path), false); // TODO : Memory leak uuid. + } + else + { + ivug_listpopup_itemlist_add(items, 0, NULL, name, (void *)strdup(path), false); + } + + if(name) + free(name); + if(path) + free(path); + + return 0; +} +#endif + +void on_btn_back_clicked(void *data, Evas_Object *obj, void *event_info) +{ +// Back from main view + Ivug_MainView *pMainView = (Ivug_MainView *)data; + IV_ASSERT(pMainView != NULL); + + MSG_MAIN_WARN("Back key from main view pressed"); + + ivug_main_view_del_hide_timer(pMainView); + +// otherwise, from gallery, ug will be terminated + evas_object_smart_callback_del(obj, "clicked", on_btn_back_clicked); + +// Slider should be removed before mList is freed. + if ( pMainView->slider ) + { + evas_object_del(pMainView->slider); + pMainView->slider = NULL; + } + + if ( pMainView->pSetAsView ) + { + MSG_MAIN_HIGH("SetAS View Destroy"); + ivug_setas_view_destroy(pMainView->pSetAsView); + pMainView->pSetAsView = NULL; + } + + if ( pMainView->pDetailsView ) + { + MSG_MAIN_HIGH("Details View Destroy"); + + ivug_details_view_destroy(pMainView->pDetailsView); + pMainView->pDetailsView = NULL; + } + +#if 1 + if(pMainView->layout) // Remove topmost parent in main view. + { + evas_object_del(pMainView->layout); + pMainView->layout = NULL; + } + + if(pMainView->empty_layout) + { + evas_object_del(pMainView->empty_layout); + pMainView->empty_layout = NULL; + } +#else + + evas_object_hide(pMainView->parent); + + evas_render(evas_object_evas_get(pMainView->parent)); + +#endif + + if ( pMainView->mList ) + { + MSG_MAIN_HIGH("Remove media list"); + ivug_medialist_del(pMainView->mList); // ivug_medialist_del() is not working on destroy cb. + pMainView->mList = NULL; + } + +#if 0 + /* comment below, because t show main view and this back btn, + *firstly slide show view is mouse up, then ivug_ss_delete() will be invoked in taht mouse up cb + */ + /* free slideshow */ + if ( pMainView->ssHandle ) + { + ivug_ss_delete(pMainView->ssHandle); + } +#endif + DESTROY_ME(); +} + +void on_btn_setas_clicked(void *data, Evas_Object *obj, void *event_info) +{ + Ivug_MainView *pMainView = (Ivug_MainView *)data; + IV_ASSERT(pMainView != NULL); + + if(pMainView->popup) + { + MSG_MAIN_ERROR("popup already exist"); + return; + } + + Media_Item *mitem = ivug_slider_get_item(pMainView->slider); + Media_Data *mdata = ivug_medialist_get_data(mitem); + + IV_ASSERT(mdata != NULL); + + if ( mdata->filepath == NULL) + { + MSG_MAIN_ERROR("File path is NULL"); + return; + } + + ivug_main_view_del_hide_timer(pMainView); + + Evas_Object* popup = NULL; + popup = ivug_listpopup_add(pMainView->layout); + + evas_object_smart_callback_add(popup, "popup,dismissed", _dismissed_cb, pMainView); + evas_object_smart_callback_add(popup, "popup,selected", _on_setas_selected, pMainView); + + if (mdata->bIsDRMContent) + { + Ivug_ListPopup_Item *it = NULL; + + bool bDisableWallpaper = !ivug_drm_is_possible_to_setas(mdata->filepath, IVUG_DRM_SETAS_WALLPAPER); + bool bDisableCallerImage = !ivug_drm_is_possible_to_setas(mdata->filepath, IVUG_DRM_SETAS_CALLERID); + + it = ivug_listpopup_item_append(popup, NULL, IDS_HOME_SCREEN, IDS_HOME_SCREEN); + + if(bDisableWallpaper == true) + { + ivug_listpopup_item_disabled_set(it); + } + + it = ivug_listpopup_item_append(popup, NULL, IDS_LOCK_SCREEN, IDS_LOCK_SCREEN); + + if(bDisableWallpaper == true) + { + ivug_listpopup_item_disabled_set(it); + } + + it = ivug_listpopup_item_append(popup, NULL, IDS_HOME_AND_LOCK_SCREENS, IDS_HOME_AND_LOCK_SCREENS); + if(bDisableWallpaper == true) + { + ivug_listpopup_item_disabled_set(it); + } + + it = ivug_listpopup_item_append(popup, NULL, IDS_CALLER_IMAGE, IDS_CALLER_IMAGE); + if(bDisableCallerImage == true) + { + ivug_listpopup_item_disabled_set(it); + } + } + else + { + ivug_listpopup_item_append(popup, NULL, IDS_HOME_SCREEN, IDS_HOME_SCREEN); + ivug_listpopup_item_append(popup, NULL, IDS_LOCK_SCREEN, IDS_LOCK_SCREEN); + ivug_listpopup_item_append(popup, NULL, IDS_HOME_AND_LOCK_SCREENS, IDS_HOME_AND_LOCK_SCREENS); + ivug_listpopup_item_append(popup, NULL, IDS_CALLER_IMAGE, IDS_CALLER_IMAGE); + + } + + const Elm_Object_Item *item = pMainView->items[TOOLBUTTON_SETAS].item; + Evas_Object *button = elm_toolbar_item_object_get(item); + + Evas_Coord x, y; + Evas_Coord w, h; + evas_object_geometry_get(button, &x, &y, &w, &h); + MSG_MAIN_MED("x = %d, y = %d, w = %d, h = %d", x, y, w, h); + + + ivug_listpopup_context_show(popup, pMainView->area_obj, x+w/2, y+h); + IVUG_FUNC_LEAVE(); + return; +} + + +static void +_ivug_detail_view_renamed_cb(void *data, Evas_Object *obj, void *event_info) +{ + Ivug_MainView *pMainView = (Ivug_MainView *)data; + + if(pMainView->view_by == IVUG_VIEW_BY_FILE) + { + const char *title = (const char *)event_info; + elm_object_item_part_text_set(pMainView->navi_it, "elm.text.title", title); + } +} + +void on_btn_details_clicked(void *data, Evas_Object *obj, void *event_info) +{ + MSG_MAIN_HIGH("ENTER : Btn detail view clicked. obj=0x%08x data=0x%08x", obj, data); + ivug_ret_if(!obj||!data); + + Ivug_MainView *pMainView = (Ivug_MainView *)data; + + if(pMainView->pDetailsView) + { + MSG_MAIN_ERROR("details view already created"); + return; + } + if(pMainView->bShowMenu == false) + { + MSG_MAIN_ERROR("details view is hiding now"); + return; + } + + ivug_main_view_del_hide_timer(pMainView); + + Media_Item *mitem = ivug_slider_get_item(pMainView->slider); + Media_Data *mdata = ivug_medialist_get_data(mitem); + IV_ASSERT(mdata != NULL); + + pMainView->pDetailsView = ivug_details_view_screen_create(pMainView->navi_bar, mdata, pMainView->view_by); + + if(!pMainView->pDetailsView) + { + MSG_MAIN_ERROR("create details view failed"); + ivug_main_view_set_hide_timer(pMainView); + return; + } + + Evas_Object *detail_layout = ivug_details_view_object_get(pMainView->pDetailsView); + + elm_object_item_part_content_set(pMainView->navi_it, "elm.swallow.detail", detail_layout); + + evas_object_smart_callback_add(detail_layout, "renamed", _ivug_detail_view_renamed_cb, pMainView); + + _change_details_to_close(pMainView); + + MSG_MAIN_HIGH("LEAVE : Btn detail view clicked. obj=0x%08x data=0x%08x", obj, data); +} + + + +void on_btn_delete_clicked(void *data, Evas_Object *obj, void *event_info) +{ + Ivug_MainView *pMainView = (Ivug_MainView *)data; + IV_ASSERT(pMainView != NULL); + + ivug_main_view_del_hide_timer(pMainView); + + ivug_deletepopup_show(pMainView->layout, NULL, IDS_DELETE_MSG, _on_delete_selected, pMainView); + + return; +} + +bool _share_pkg_cb(service_h service, const char *package, void *user_data) +{ + Evas_Object* popup = (Evas_Object*)user_data; + + char *name = NULL; + + app_manager_get_app_name(package, &name); + + ivug_listpopup_item_append(popup, NULL, name, (void *)strdup(package)); + + free(name); + + return true; +} + +void on_btn_share_clicked(void *data, Evas_Object *obj, void *event_info) +{ + Ivug_MainView *pMainView = (Ivug_MainView *)data; + IV_ASSERT(pMainView != NULL); + + if(pMainView->popup) + { + MSG_MAIN_ERROR("popup already exist"); + return; + } + + Media_Item *mitem = ivug_slider_get_item(pMainView->slider); + Media_Data *mdata = ivug_medialist_get_data(mitem); + IV_ASSERT(mdata != NULL); + + if ( mdata->filepath == NULL) + { + MSG_MAIN_ERROR("File path is NULL"); + return; + } + + ivug_main_view_del_hide_timer(pMainView); + + Evas_Object* popup = NULL; + popup = ivug_listpopup_add(pMainView->layout); + + evas_object_smart_callback_add(popup, "popup,dismissed", _dismissed_cb, pMainView); + evas_object_smart_callback_add(popup, "popup,selected", _on_share_selected, pMainView); + + service_h service; + service_create(&service); + service_set_operation(service, SERVICE_OPERATION_SEND); + service_set_uri(service, mdata->filepath); + service_foreach_app_matched(service, _share_pkg_cb, (void *)popup); + + const Elm_Object_Item *item = pMainView->items[TOOLBUTTON_SHARE].item; + Evas_Object *button = elm_toolbar_item_object_get(item); + + Evas_Coord x, y; + Evas_Coord w, h; + evas_object_geometry_get(button, &x, &y, &w, &h); + MSG_MAIN_MED("x = %d, y = %d, w = %d, h = %d", x, y, w, h); + + ivug_listpopup_context_show(popup, pMainView->area_obj, x+w/2, y+h); +} + +void on_btn_slideshow_clicked(void *data, Evas_Object *obj, void *event_info) +{ + Ivug_MainView *pMainView = (Ivug_MainView *)data; + IV_ASSERT(pMainView != NULL); + + MSG_MAIN_HIGH("Start slide show"); + +/* + Just for debugging. +*/ +#if 0 + ivug_slider_dump_photocam(pMainView->slider); + return; + +#endif + if ( strcmp (elm_object_widget_type_get(obj), "toolbar") != 0 ) + { + MSG_MAIN_FATAL("Not toolbar"); + return; + } + + Elm_Object_Item *ctrl_bar_item = (Elm_Object_Item *)event_info; + + if(elm_object_item_disabled_get(ctrl_bar_item) == EINA_TRUE) + { + MSG_MAIN_WARN("Slide show already started"); + return; + } + + elm_object_item_disabled_set(ctrl_bar_item, EINA_TRUE); + + if(pMainView->pDetailsView) + { + MSG_MAIN_HIGH("Exit details view"); + _change_close_to_details(pMainView); + _delete_details_view(pMainView); + ivug_main_view_set_hide_timer(pMainView); // for hide_count + } + + ivug_main_view_start_slideshow(pMainView, EINA_TRUE); + +} + +void on_btn_details_close_clicked(void *data, Evas_Object *obj, void *event_info) +{ + Ivug_MainView *pMainView = (Ivug_MainView *)data; + IV_ASSERT(pMainView != NULL); + + MSG_MAIN_HIGH("ENTER : Btn detail close clicked. obj=0x%08x data=0x%08x", obj, data); + + _change_close_to_details(pMainView); + _delete_details_view(pMainView); + + ivug_main_view_set_hide_timer(pMainView); + + MSG_MAIN_HIGH("LEAVE : Btn detail close clicked. obj=0x%08x data=0x%08x", obj, data); +} + +/* + Used for only view type is select +*/ +void on_btn_selectok_clicked(void *data, Evas_Object *obj, void *event_info) +{ + Ivug_MainView *pMainView = (Ivug_MainView *)data; + IV_ASSERT(pMainView != NULL); + + MSG_MAIN_HIGH("Select OK."); + + service_h service; + service_create(&service); + + service_add_extra_data(service, "Result", "Ok"); + ug_send_result(gGetUGHandle(), service); + + service_destroy(service); + + DESTROY_ME(); + +} +/* + Used for only view type is select +*/ +void on_btn_selectcancel_clicked(void *data, Evas_Object *obj, void *event_info) +{ + Ivug_MainView *pMainView = (Ivug_MainView *)data; + IV_ASSERT(pMainView != NULL); + + MSG_MAIN_HIGH("Select Cancel"); + +//send result to caller + service_h service; + service_create(&service); + + service_add_extra_data(service, "Result", "Cancel"); + ug_send_result(gGetUGHandle(), service); + + service_destroy(service); + + DESTROY_ME(); + +} + +void on_btn_rename_clicked(void *data, Evas_Object *obj, void *event_info) +{ + Ivug_MainView *pMainView = (Ivug_MainView *)data; + IV_ASSERT(pMainView != NULL); + + Media_Item *mitem = ivug_slider_get_item(pMainView->slider); + Media_Data *mdata = ivug_medialist_get_data(mitem); + + IV_ASSERT(mdata != NULL); + + ivug_main_view_del_hide_timer(pMainView); + + char *old_fullpath = mdata->filepath; + const char *old_name = ecore_file_file_get(old_fullpath); + + ivug_rename_popup_show(pMainView->layout, ecore_file_strip_ext(old_name), _on_rename_selected, pMainView); + +} + +static void +_on_copy_selected(void *data, Evas_Object *obj) +{ + Ivug_MainView *pMainView = (Ivug_MainView *)data; + IV_ASSERT(pMainView != NULL); + + //get current file path. + Media_Item *mitem = ivug_slider_get_item(pMainView->slider); + Media_Data *mdata = ivug_medialist_get_data(mitem); + if (mdata == NULL) + { + MSG_MAIN_ERROR("slider data is NULL"); + return; + } + + char *path = NULL; + int len = 0; + + if(mdata->slide_type == SLIDE_TYPE_VIDEO) + { + path = mdata->thumbnail_path; + } + else + { + path = mdata->filepath; + } + len = strlen(path)+1; + + if (len < IVUG_MAX_FILE_PATH_LEN) + { + MSG_MAIN_HIGH("file path = %s", path); + elm_cnp_selection_set(pMainView->layout, ELM_SEL_TYPE_CLIPBOARD, ELM_SEL_FORMAT_IMAGE, path, len); + _ivug_selectioninfo_create(pMainView, IDS_COPIED_TO_CLIPBOARD); + } + else + { + MSG_MAIN_ERROR("slider file path is too long"); + _ivug_selectioninfo_create(pMainView, IDS_FAILED); + } + evas_object_del(obj); +} + +static void +_on_crop_selected(void *data, Evas_Object *obj) +{ + Ivug_MainView *pMainView = (Ivug_MainView *)data; + IV_ASSERT(pMainView != NULL); + + //get current file path. + Media_Item *WMitem = ivug_slider_get_item(pMainView->slider); + Media_Data *mdata = ivug_medialist_get_data(WMitem); + + if (mdata == NULL) + { + MSG_MAIN_ERROR("slider data is NULL"); + return; + } + + MSG_MAIN_HIGH("Create Crop view"); + + IvugCropView *pCropView = ivug_crop_view_create(pMainView->layout); + + ivug_crop_view_file_set(pCropView, mdata->filepath); + + evas_object_del(obj); // Remove ctx popup +} + +static void _on_tool_selected(void *data, Evas_Object *obj, void *event_info) +{ +// obj is ctxpopup!. + Ivug_MainView *pMainView = (Ivug_MainView *)data; + + Ivug_ListPopup_Item *item = (Ivug_ListPopup_Item *)event_info; + + const char *label = (const char *)ivug_listpopup_item_get_data(item); + if(label == NULL) + { + ivug_main_view_set_hide_timer(pMainView); + return; + } + + MSG_MAIN_HIGH("text(%s) is clicked", label); + + if(strncmp(label, IDS_COPY_TO_CLIPBOARD, strlen(label)) == 0) + { + _on_copy_selected(data, obj); + ivug_main_view_set_hide_timer(pMainView); + } + else if(strncmp(label, IDS_CROP, strlen(label)) == 0) + { + _on_crop_selected(data, obj); + } +} + +void on_btn_tool_clicked(void *data, Evas_Object *obj, void *event_info) +{ + Ivug_MainView *pMainView = (Ivug_MainView *)data; + IV_ASSERT(pMainView != NULL); + + Media_Item *mitem = ivug_slider_get_item(pMainView->slider); + Media_Data *mdata = ivug_medialist_get_data(mitem); + + IV_ASSERT(mdata != NULL); + + ivug_main_view_del_hide_timer(pMainView); + + Evas_Object* popup = NULL; + popup = ivug_listpopup_add(pMainView->area_obj); + + evas_object_smart_callback_add(popup, "popup,dismissed", _dismissed_cb, pMainView); + evas_object_smart_callback_add(popup, "popup,selected", _on_tool_selected, pMainView); + + if(mdata->slide_type == SLIDE_TYPE_IMAGE) + { + ivug_listpopup_item_append(popup, ICON_PATH_CROP, IDS_CROP, IDS_CROP); + } + + const Elm_Object_Item *item = pMainView->items[TOOLBUTTON_TOOL].item; + Evas_Object *button = elm_toolbar_item_object_get(item); + + Evas_Coord x, y; + Evas_Coord w, h; + evas_object_geometry_get(button, &x, &y, &w, &h); + MSG_MAIN_MED("x = %d, y = %d, w = %d, h = %d", x, y, w, h); + + ivug_listpopup_context_show(popup, pMainView->area_obj, x+w/2, y+h); + +} + diff --git a/main/src/view/ivug-main-view-menu.h b/main/src/view/ivug-main-view-menu.h new file mode 100755 index 0000000..2842481 --- /dev/null +++ b/main/src/view/ivug-main-view-menu.h @@ -0,0 +1,50 @@ +/* + * Copyright 2012 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.tizenopensource.org/license + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __IVUG_MAINVIEW_MENU_H__ +#define __IVUG_MAINVIEW_MENU_H__ + + +#ifdef __cplusplus +extern "C" { +#endif + +/* + Button handlers for main view +*/ + +void on_btn_selectcancel_clicked(void *data, Evas_Object *obj, void *event_info); +void on_btn_selectok_clicked(void *data, Evas_Object *obj, void *event_info); +void on_btn_slideshow_clicked(void *data, Evas_Object *obj, void *event_info); +void on_btn_share_clicked(void *data, Evas_Object *obj, void *event_info); +void on_btn_delete_clicked(void *data, Evas_Object *obj, void *event_info); +void on_btn_details_clicked(void *data, Evas_Object *obj, void *event_info); +void on_btn_setas_clicked(void *data, Evas_Object *obj, void *event_info); +void on_btn_back_clicked(void *data, Evas_Object *obj, void *event_info); +void on_btn_details_close_clicked(void *data, Evas_Object *obj, void *event_info); + +void on_btn_rename_clicked(void *data, Evas_Object *obj, void *event_info); +void on_btn_tool_clicked(void *data, Evas_Object *obj, void *event_info); + +void _ivug_selectioninfo_create(Ivug_MainView *pMainView, const char *string); + +#ifdef __cplusplus +} +#endif + + +#endif // __IVUG_MAINVIEW_MENU_H__ + diff --git a/main/src/view/ivug-main-view-toolbar.cpp b/main/src/view/ivug-main-view-toolbar.cpp new file mode 100755 index 0000000..0cdaaa8 --- /dev/null +++ b/main/src/view/ivug-main-view-toolbar.cpp @@ -0,0 +1,478 @@ +/* + * Copyright 2012 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.tizenopensource.org/license + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "ivug-common.h" +#include "ivug-main-view.h" +#include "ivug-main-view-menu.h" + +#include "ivug-slider.h" + +#define CONTROL_ICON_DIRECTORY_PATH IMAGE_PATH"/01_Control icon" + +#define ICON_PATH_DELETE CONTROL_ICON_DIRECTORY_PATH"/T01_controlbar_icon_delete.png" +#define ICON_PATH_SHARE CONTROL_ICON_DIRECTORY_PATH"/T01_controlbar_icon_share.png" +#define ICON_PATH_SETAS CONTROL_ICON_DIRECTORY_PATH"/T01_1_title_icon_set_as.png" +#define ICON_PATH_SLIDESHOW CONTROL_ICON_DIRECTORY_PATH"/T01_controlbar_icon_slideshow.png" +#define ICON_PATH_INFO CONTROL_ICON_DIRECTORY_PATH"/T01_1_controlbar_icon_detail.png" +#define ICON_PATH_SAVE CONTROL_ICON_DIRECTORY_PATH"/T01_controlbar_icon_save.png" +#define ICON_PATH_CLOSE CONTROL_ICON_DIRECTORY_PATH"/01_controllbar_icon_close.png" +#define ICON_PATH_MORE CONTROL_ICON_DIRECTORY_PATH"/T01_Title_icon_more.png" + +static void _toolbar_item_append(ControlBar_Item * /*INOUT*/item, Evas_Object *parent, const char *iconpath, const char *caption, Evas_Smart_Cb fnClick, void *data) +{ + item->item = elm_toolbar_item_append(parent, iconpath, NULL, fnClick, data); + + item->pos = TOOLBUTTON_IN_TOOLBAR; +} + +static void _ctrlbar_item_append(ControlBar_Item * /*INOUT*/item, Evas_Object *parent, const char *iconpath, const char *caption, Evas_Smart_Cb fnClick, void *data) +{ + item->item = elm_toolbar_item_append(parent, iconpath, NULL, fnClick, data); + + item->pos = TOOLBUTTON_IN_CTRLBAR; +} + +static void _toolbutton_set_disabled(ControlBar_Item * /*INOUT*/item) +{ + if ( item->item == NULL ) + return; + + /*if(item->pos == TOOLBUTTON_IN_TOOLBAR) + { + Evas_Object *button = elm_object_item_part_content_get(item->item, "object"); + elm_object_disabled_set(button, EINA_TRUE); + } + else*/ + { + elm_object_item_disabled_set(item->item, EINA_TRUE); + } +} + +static void _toolbutton_set_enabled(ControlBar_Item * /*INOUT*/item) +{ + if ( item->item == NULL ) + return; + + /*if(item->pos == TOOLBUTTON_IN_TOOLBAR) + { + Evas_Object *button = elm_object_item_part_content_get(item->item, "object"); + elm_object_disabled_set(button, EINA_FALSE); + } + else*/ + { + elm_object_item_disabled_set(item->item, EINA_FALSE); + } +} + + +ivug_toolbar +_get_tool_bar_type(ivug_mode mode, Media_Type slide_type ) +{ + ivug_toolbar tool_bar_type = NAVI_BAR_TYPE_NONE; + + //calc navi bar style , temporary code. + static const char *szType[] = { + "[ INVALID ]", + "[ ]", + "[Set, Info]", + "[Ok, Cancel]", + }; + + + switch (mode) + { + case IVUG_MODE_NORMAL: + case IVUG_MODE_CAMERA: + case IVUG_MODE_SLIDESHOW: + tool_bar_type = NAVI_BAR_TYPE_EMPTY; + if (slide_type == SLIDE_TYPE_IMAGE) + { + tool_bar_type = NAVI_BAR_TYPE_IMAGE; + } + else if (slide_type == SLIDE_TYPE_VIDEO) + { + tool_bar_type = NAVI_BAR_TYPE_VIDEO; + } + else if (slide_type == SLIDE_TYPE_STREAMING) + { + tool_bar_type = NAVI_BAR_TYPE_EMPTY; + } + else + { + tool_bar_type = NAVI_BAR_TYPE_EMPTY; + } + break; + case IVUG_MODE_SINGLE: + case IVUG_MODE_FILE: + tool_bar_type = NAVI_BAR_TYPE_FILE; + + break; + case IVUG_MODE_DISPLAY: + tool_bar_type = NAVI_BAR_TYPE_SELECT; + + break; + default: + MSG_MAIN_ERROR("Unhandled mode : %d", mode); + tool_bar_type = NAVI_BAR_TYPE_EMPTY; + + break; + } + + MSG_MAIN_MED("Mode=%d Slide=%d ToolBar=%s", mode, slide_type, szType[tool_bar_type]); + + return tool_bar_type; +} + + +ivug_ctrlbar +_get_ctrl_bar_type(ivug_mode mode, Media_Type slide_type) +{ + // this is temporary code. + ivug_ctrlbar type = CTRL_BAR_TYPE_FILE; + + static const char *szType[] = { + "[ Invalid ]", + "[ None ]", + "[Delete,Share,Set,Info]", + "[Share, Set, Save, Info]", + "[Delete,Share, Slide show]", + }; + + switch (mode) + { + case IVUG_MODE_NORMAL: + case IVUG_MODE_CAMERA: + case IVUG_MODE_SLIDESHOW: + if (slide_type == SLIDE_TYPE_IMAGE) + { + type = CTRL_BAR_TYPE_IMAGE; + } + else if (slide_type == SLIDE_TYPE_VIDEO) + { + type = CTRL_BAR_TYPE_VIDEO; + } + else if (slide_type == SLIDE_TYPE_UNKNOWN) + { + type = CTRL_BAR_TYPE_IMAGE; + } + else + { + MSG_MAIN_ERROR("Unhandled slide type : %d", slide_type); + type = CTRL_BAR_TYPE_FILE; + } + break; + case IVUG_MODE_SINGLE: + case IVUG_MODE_FILE: + type = CTRL_BAR_TYPE_FILE; + break; + case IVUG_MODE_DISPLAY: + type = CTRL_BAR_TYPE_EMPTY; + break; + case IVUG_MODE_SETAS: + type = CTRL_BAR_TYPE_EMPTY; + break; + default: + MSG_MAIN_ERROR("Unhandled mode : %d", mode); + type = CTRL_BAR_TYPE_FILE; + } + + MSG_MAIN_MED("Mode=%d Slide=%d CtrlBar=%s", mode, slide_type, szType[type]); + + return type; + +} + + + + +Evas_Object *_create_ctrl_bar(Evas_Object *parent) +{ + Evas_Object *toolbar = elm_toolbar_add(parent); + +//create control bar + if (toolbar == NULL) + { + MSG_MAIN_ERROR("controlbar create failed"); + return NULL; + } + + elm_object_style_set(toolbar, "default"); + elm_toolbar_shrink_mode_set(toolbar, ELM_TOOLBAR_SHRINK_EXPAND); + + //elm_toolbar_homogeneous_set(toolbar, EINA_FALSE); + + MSG_MAIN_HIGH("Create ctrl_bar. Obj=0x%08x", toolbar); + + return toolbar; + +} + +Evas_Object *_create_tool_bar(Evas_Object *parent) +{ + Evas_Object *toolbar; + + toolbar = ivug_controlbar_add(parent, "naviframe"); + + MSG_MAIN_HIGH("Create tool_bar. Obj=0x%08x", toolbar); + + return toolbar; +} + + + +void _update_tool_bar(Ivug_MainView *pMainView, ivug_toolbar barType) +{ + +/* + |------------------| + |elm_navigation_bar| + |------------------| + | tool_bar | + |------------------| + | | + | | + | | + | | + |------------------| + | ctrl_bar | + |------------------| +*/ + Evas_Object *tool_bar = pMainView->tool_bar; + + MSG_MAIN_HIGH("Update tool_bar. Type=%d", barType); + +//remove old control bar item. + int i = 0; + + for ( i = 0; i< TOOLBUTTON_MAX ; i++) + { + if ( pMainView->items[i].pos == TOOLBUTTON_IN_TOOLBAR ) + { + elm_object_item_del(pMainView->items[i].item); + pMainView->items[i].item = NULL; + pMainView->items[i].pos = TOOLBUTTON_IN_NONE; + } + } + + switch(barType) + { + case NAVI_BAR_TYPE_IMAGE: + _toolbar_item_append(&pMainView->items[TOOLBUTTON_SHARE], tool_bar, ICON_PATH_SHARE, NULL, on_btn_share_clicked, pMainView); + _toolbar_item_append(&pMainView->items[TOOLBUTTON_SETAS], tool_bar, ICON_PATH_SETAS, NULL, on_btn_setas_clicked, pMainView); + _toolbar_item_append(&pMainView->items[TOOLBUTTON_TOOL], tool_bar, ICON_PATH_MORE, NULL, on_btn_tool_clicked, pMainView); + + break; + case NAVI_BAR_TYPE_VIDEO: + _toolbar_item_append(&pMainView->items[TOOLBUTTON_SHARE], tool_bar, ICON_PATH_SHARE, NULL, on_btn_share_clicked, pMainView); + _toolbar_item_append(&pMainView->items[TOOLBUTTON_TOOL], tool_bar, ICON_PATH_MORE, NULL, on_btn_tool_clicked, pMainView); + + break; + case NAVI_BAR_TYPE_FILE: + _toolbar_item_append(&pMainView->items[TOOLBUTTON_SHARE], tool_bar, ICON_PATH_SHARE, NULL, on_btn_share_clicked, pMainView); + _toolbar_item_append(&pMainView->items[TOOLBUTTON_SETAS], tool_bar, ICON_PATH_SETAS, NULL, on_btn_setas_clicked, pMainView); + _toolbar_item_append(&pMainView->items[TOOLBUTTON_TOOL], tool_bar, ICON_PATH_MORE, NULL, on_btn_tool_clicked, pMainView); + + break; + case NAVI_BAR_TYPE_SELECT: + _toolbar_item_append(&pMainView->items[TOOLBUTTON_OK], tool_bar, ICON_PATH_SAVE, NULL, on_btn_selectok_clicked, pMainView); + _toolbar_item_append(&pMainView->items[TOOLBUTTON_CANCEL], tool_bar, ICON_PATH_CLOSE, NULL, on_btn_selectcancel_clicked, pMainView); + + break; + default: + MSG_MAIN_ERROR("Unhandled... %d", barType); + break; + + } + +} + + +void _update_ctrl_bar(Ivug_MainView *pMainView, ivug_ctrlbar barType) +{ + Evas_Object *ctrl_bar = pMainView->ctrl_bar; + + MSG_MAIN_HIGH("Update ctrl_bar. barType=%d", barType); + +//remove old control bar item. + int i = 0; + + for ( i = 0; i< TOOLBUTTON_MAX ; i++) + { + if ( pMainView->items[i].pos == TOOLBUTTON_IN_CTRLBAR ) + { + elm_object_item_del(pMainView->items[i].item); + pMainView->items[i].item = NULL; + pMainView->items[i].pos = TOOLBUTTON_IN_NONE; + } + } + +/* + IVUG_MODE_NORMAL => + Depends on content + Image [Delete,Share, Slide show] -> CTRL_BAR_TYPE_IMAGE + Video [Delete,Share, Slide show] -> CTRL_BAR_TYPE_VIDEO + + IVUG_MODE_SINGLE, IVUG_MODE_FILE, => CTRL_BAR_TYPE_FILE [Delete,Share,Set,Info] + IVUG_MODE_DISPLAY => CTRL_BAR_TYPE_EMPTY + + if ((mode == IVUG_MODE_FILE) || (mode == IVUG_MODE_SINGLE)) + barType == CTRL_BAR_TYPE_FILE + +*/ + switch(barType) + { + case CTRL_BAR_TYPE_FILE: + _ctrlbar_item_append(&pMainView->items[TOOLBUTTON_DELETE], ctrl_bar, ICON_PATH_DELETE, NULL, on_btn_delete_clicked, pMainView); + _ctrlbar_item_append(&pMainView->items[TOOLBUTTON_DETAILS], ctrl_bar, ICON_PATH_INFO, NULL, on_btn_details_clicked, pMainView); + break; + + case CTRL_BAR_TYPE_IMAGE: + _ctrlbar_item_append(&pMainView->items[TOOLBUTTON_DELETE], ctrl_bar, ICON_PATH_DELETE, NULL, on_btn_delete_clicked, pMainView); + _ctrlbar_item_append(&pMainView->items[TOOLBUTTON_SLIDESHOW], ctrl_bar, ICON_PATH_SLIDESHOW, NULL, on_btn_slideshow_clicked, pMainView); + _ctrlbar_item_append(&pMainView->items[TOOLBUTTON_DETAILS], ctrl_bar, ICON_PATH_INFO, NULL, on_btn_details_clicked, pMainView); + break; + + case CTRL_BAR_TYPE_VIDEO: + _ctrlbar_item_append(&pMainView->items[TOOLBUTTON_DELETE], ctrl_bar, ICON_PATH_DELETE, NULL, on_btn_delete_clicked, pMainView); + _ctrlbar_item_append(&pMainView->items[TOOLBUTTON_SLIDESHOW], ctrl_bar, ICON_PATH_SLIDESHOW, NULL, on_btn_slideshow_clicked, pMainView); + _ctrlbar_item_append(&pMainView->items[TOOLBUTTON_DETAILS], ctrl_bar, ICON_PATH_INFO, NULL, on_btn_details_clicked, pMainView); + break; + + default: + MSG_MAIN_ERROR("Unhandled ctrl bar type=%d", barType); + break; + } + +// ivug_main_view_on_rotate( pMainView, gGetRotationDegree()); // TODO +} + + +void _update_toolbuttons(Ivug_MainView *pMainView) +{ +// If Inavalid image, disable all buttons. + slide_state_t state = ivug_slider_get_state(pMainView->slider); + + Media_Item *mitem = ivug_slider_get_item(pMainView->slider); + Media_Data *mdata = ivug_medialist_get_data(mitem); + + _toolbutton_set_disabled(&pMainView->items[TOOLBUTTON_NULL]); + + if ( state == SLIDE_STATE_ERROR) + { + _toolbutton_set_disabled(&pMainView->items[TOOLBUTTON_SETAS]); + _toolbutton_set_disabled(&pMainView->items[TOOLBUTTON_TOOL]); + + return ; + } + +// Enable all button + int i = 0; + for ( i = 0; i< TOOLBUTTON_MAX ; i++) + { + _toolbutton_set_enabled(&pMainView->items[i]); + } + +// If Video, DRM, disable SetAs button +// If Video when CTRL_BAR_TYPE_FILE, disable Set + + if (mdata->slide_type == SLIDE_TYPE_STREAMING) + { + _toolbutton_set_disabled(&pMainView->items[TOOLBUTTON_SHARE]); + _toolbutton_set_disabled(&pMainView->items[TOOLBUTTON_SETAS]); + } + // If uneditable video, disable Editor + else if (mdata->slide_type == SLIDE_TYPE_VIDEO) + { + _toolbutton_set_disabled(&pMainView->items[TOOLBUTTON_TOOL]); + } + + if(mdata->bIsDRMContent == EINA_TRUE) + { + _toolbutton_set_disabled(&pMainView->items[TOOLBUTTON_TOOL]); + if(ivug_drm_is_possible_to_setas(mdata->filepath, IVUG_DRM_SETAS_WALLPAPER) == false && + ivug_drm_is_possible_to_setas(mdata->filepath, IVUG_DRM_SETAS_CALLERID) == false) + { + _toolbutton_set_disabled(&pMainView->items[TOOLBUTTON_SETAS]); + } + if(ivug_drm_get_forwarding_info(mdata->filepath) == false) + { + _toolbutton_set_disabled(&pMainView->items[TOOLBUTTON_SHARE]); + } + } +} + +void _change_details_to_close(Ivug_MainView *pMainView) +{ + IV_ASSERT(pMainView != NULL); + + Evas_Object *btn; + +// Change "details" to "close" + if ( pMainView->items[TOOLBUTTON_DETAILS].pos == TOOLBUTTON_IN_CTRLBAR ) // If detail button is in ctrl_bar + { + // Remove details item & Add close item + btn = elm_object_item_part_content_unset(pMainView->items[TOOLBUTTON_DETAILS].item, "object"); + evas_object_del(btn); + + elm_object_item_del(pMainView->items[TOOLBUTTON_DETAILS].item); + pMainView->items[TOOLBUTTON_DETAILS].item = NULL; + + _ctrlbar_item_append(&pMainView->items[TOOLBUTTON_DETAILS], pMainView->ctrl_bar, ICON_PATH_CLOSE, NULL, on_btn_details_close_clicked, pMainView); + } + else + { + // Remove details item & Add close item + btn = elm_object_item_part_content_unset(pMainView->items[TOOLBUTTON_DETAILS].item, "object"); + evas_object_del(btn); + + elm_object_item_del(pMainView->items[TOOLBUTTON_DETAILS].item); + pMainView->items[TOOLBUTTON_DETAILS].item = NULL; + + _toolbar_item_append(&pMainView->items[TOOLBUTTON_DETAILS], pMainView->tool_bar, ICON_PATH_CLOSE, NULL, on_btn_details_close_clicked, pMainView); + } + +} + +void _change_close_to_details(Ivug_MainView *pMainView) +{ + IV_ASSERT(pMainView != NULL); + + Evas_Object *btn; + + if ( pMainView->items[TOOLBUTTON_DETAILS].pos == TOOLBUTTON_IN_CTRLBAR ) // If detail button is in ctrl_bar + { + // Remove details item & Add close item + btn = elm_object_item_part_content_unset(pMainView->items[TOOLBUTTON_DETAILS].item, "object"); + evas_object_del(btn); + + elm_object_item_del(pMainView->items[TOOLBUTTON_DETAILS].item); + pMainView->items[TOOLBUTTON_DETAILS].item = NULL; + + _ctrlbar_item_append(&pMainView->items[TOOLBUTTON_DETAILS], pMainView->ctrl_bar, ICON_PATH_INFO, NULL, on_btn_details_clicked, pMainView); + } + else + { + // Remove details item & Add close item + btn = elm_object_item_part_content_unset(pMainView->items[TOOLBUTTON_DETAILS].item, "object"); + evas_object_del(btn); + + elm_object_item_del(pMainView->items[TOOLBUTTON_DETAILS].item); + pMainView->items[TOOLBUTTON_DETAILS].item = NULL; + + _toolbar_item_append(&pMainView->items[TOOLBUTTON_DETAILS], pMainView->tool_bar, ICON_PATH_INFO, NULL, on_btn_details_clicked, pMainView); + } +} + diff --git a/main/src/view/ivug-main-view-toolbar.h b/main/src/view/ivug-main-view-toolbar.h new file mode 100755 index 0000000..080a5e0 --- /dev/null +++ b/main/src/view/ivug-main-view-toolbar.h @@ -0,0 +1,43 @@ +/* + * Copyright 2012 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.tizenopensource.org/license + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __IVUG_MAIN_VIEW_TOOLBAR_H__ +#define __IVUG_MAIN_VIEW_TOOLBAR_H__ + + +/* + Get ctrl/tool bar type from slide type. +*/ +ivug_ctrlbar _get_ctrl_bar_type(ivug_mode mode, Media_Type slide_type); +ivug_toolbar _get_tool_bar_type(ivug_mode mode, Media_Type slide_type ); + +Evas_Object *_create_ctrl_bar(Evas_Object *parent); +Evas_Object *_create_tool_bar(Evas_Object *parent); + + +void _update_ctrl_bar(Ivug_MainView *pMainView, ivug_ctrlbar barType); +void _update_tool_bar(Ivug_MainView *pMainView, ivug_toolbar barType); + +/* + Enable / Disable buttons on tool bar +*/ +void _update_toolbuttons(Ivug_MainView *pMainView); + + +void _change_close_to_details(Ivug_MainView *pMainView); +void _change_details_to_close(Ivug_MainView *pMainView); + +#endif // __IVUG_MAIN_VIEW_TOOLBAR_H__ diff --git a/main/src/view/ivug-main-view.cpp b/main/src/view/ivug-main-view.cpp new file mode 100755 index 0000000..3f258e0 --- /dev/null +++ b/main/src/view/ivug-main-view.cpp @@ -0,0 +1,1775 @@ +/* + * Copyright 2012 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.tizenopensource.org/license + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include // ug_destroy_me, ug_send_result +#include +#include +#include // Key event + +#include "ivug-common.h" +#include "ivug-parameter.h" + +#include "ivug-main-view.h" +#include "ivug-main-view-toolbar.h" +#include "ivug-main-view-menu.h" + +#include "ivug-filter.h" + +#include "ivug-ext-ug.h" + +#include "ivug-util.h" +#include "ivug-medialist.h" +#include "ivug-media.h" + +#include "ivug-popup.h" +#include "ivug-selectioninfo.h" + +#include "ivug-slider-item.h" +#include "ivug-slider.h" + +#include "ivug-setas-view.h" +#include "ivug-name-view.h" +#include "ivug-details-view.h" + +#include "ivug-listpopup.h" +#include "ivug-slideshow.h" + +#include "ivug-ext-ug.h" + +#include "ivug-drm.h" +#include "EFLUtil.h" + +#include "ivug-image.h" + +#undef HIDE_INDICATOR // For testing. +#define TEST_MOUSE_EVENT + +#define DEFAULT_THUMBNAIL_PATH IMAGE_PATH"/T01_Nocontents_broken.png" + +#define LONGTAP_TIMEOUT (2.0) // 2secs + +// EDJE +#define IVUG_MAIN_EDJ EDJ_PATH"/ivug-main.edj" +/////////////////////////////////////////////////////////////////////////////////////////////////// +// +// +static bool _destory_slideshow_and_ug(Ivug_MainView *pMainView, int state, bool bMmc_out); +static void _on_slideshow_finished(void *data, Evas_Object *obj, void *event_info); + + +static void +_send_result_footsteps(ui_gadget_h ug) +{ +//result bundle key +#define IVUG_RESULT_BUNDLE_KEY_EXIT "EXIT" + +//result bundle value +#define IVUG_RESULT_BUNDLE_VALUE_NORMAL "NORMAL" + + ivug_ret_if(!ug); + + service_h service; + service_create(&service); + + service_add_extra_data(service, IVUG_RESULT_BUNDLE_KEY_EXIT, IVUG_RESULT_BUNDLE_VALUE_NORMAL); + ug_send_result(gGetUGHandle(), service); + + service_destroy(service); +} + +static void _update_title(Ivug_MainView *pMainView) +{ +#define MAX_TITLE_LEN 256 + + static char title[MAX_TITLE_LEN]; + static char subtitle[MAX_TITLE_LEN]; + + Media_Item *mitem = ivug_slider_get_item(pMainView->slider); + Media_Data *mdata = ivug_medialist_get_data(mitem); + + + if (mdata == NULL) + { + MSG_MAIN_ERROR("slider data is NULL"); + return; + } + + if (pMainView->view_by == IVUG_VIEW_BY_FOLDER || pMainView->view_by == IVUG_VIEW_BY_ALL) + { + snprintf(title, sizeof(title), "%s", pMainView->album_name); + snprintf(subtitle, sizeof(subtitle), "%d/%d", + mdata->index + 1, + ivug_medialist_get_count(pMainView->mList)); //get title. + + elm_object_item_part_text_set(pMainView->navi_it, "subtitle", subtitle); + } + else if(mdata->filepath != NULL) + { + const char* filename = ivug_get_filename(mdata->filepath); + if(filename) + { + snprintf(title, sizeof(title), "%s", filename); + } + } + + IV_ASSERT(pMainView->navi_bar != NULL); + + MSG_MAIN_HIGH("Update title : %s", title); + + elm_object_item_text_set(pMainView->navi_it, title); + +} + +static bool _is_mmc_inserted(void) +{ + int noti_message; + int ret = -1; + + ret = vconf_get_int(VCONFKEY_SYSMAN_MMC_STATUS, ¬i_message); + + if ( ret != 0 ) // falied + { + MSG_NOTI_ERROR("Get %s is failed", VCONFKEY_SYSMAN_MMC_STATUS); + return false; + } + + if(noti_message==VCONFKEY_SYSMAN_MMC_MOUNTED) + { + return true; + } + + return false; + +} + + +static void +_on_longpress_popup_selected(void *data, Evas_Object *obj, void *event_info) +{ + Ivug_MainView *pMainView = (Ivug_MainView *)data; + IV_ASSERT(pMainView != NULL); + +// Destroy copy popup + pMainView->longpress_popup = NULL; // object is removed automatically + + int response = (int)event_info; + + Media_Item *mtiem = ivug_slider_get_item(pMainView->slider); + Media_Data *mdata = ivug_medialist_get_data(mtiem); + if (mdata == NULL) + { + MSG_MAIN_ERROR("slider data is NULL"); + return; + } + + if(response == LPPOPUP_RESPONSE_COPY) + { + //get current file path. + + char *path = NULL; + int len = 0; + // This Will add to the article + char buf[IVUG_MAX_FILE_PATH_LEN] = {0,}; + + if(mdata->slide_type == SLIDE_TYPE_STREAMING) + { + path = mdata->fileurl; + len = strlen(mdata->fileurl)+1; + strncpy(buf, mdata->fileurl, IVUG_MAX_FILE_PATH_LEN); + } + else + { + path = mdata->filepath; + len = strlen(mdata->filepath)+strlen("file://")+1; + snprintf(buf, IVUG_MAX_FILE_PATH_LEN, "file://%s", mdata->filepath); + } + + if (len < IVUG_MAX_FILE_PATH_LEN) + { + MSG_MAIN_HIGH("file path = %s, file url =%s", path, buf); + elm_cnp_selection_set(pMainView->layout, ELM_SEL_TYPE_CLIPBOARD, ELM_SEL_FORMAT_IMAGE, buf, sizeof(buf)); + _ivug_selectioninfo_create(pMainView, IDS_COPIED_TO_CLIPBOARD); + } + else + { + MSG_MAIN_ERROR("slider file path is too long"); + } + } +} + +static Eina_Bool _on_key_down(void *user_data, int type, void *event) +{ + if (!user_data) { + MSG_IMAGEVIEW_ERROR("user data is NULL"); + return ECORE_CALLBACK_PASS_ON; + } + + Ivug_MainView *pMainView = (Ivug_MainView *)user_data; + + Ecore_Event_Key *key_event = (Ecore_Event_Key *) event; + + if (!strcmp(key_event->keyname, KEY_END)) + { + MSG_IMAGEVIEW_HIGH("Bakc(End) key"); + } + else if (!strcmp(key_event->keyname, KEY_SELECT)) + { + MSG_IMAGEVIEW_HIGH("Home key"); + } + else if (!strcmp(key_event->keyname, KEY_POWER)) + { + MSG_IMAGEVIEW_HIGH("Power key"); + if ( pMainView->ssHandle ) + { + ivug_ss_stop(pMainView->ssHandle); + } + } + + MSG_IMAGEVIEW_LOW("Key down : %s", key_event->keyname); + + return ECORE_CALLBACK_PASS_ON; +} + +static Eina_Bool _on_exit_timer_expired(void *data) +{ + ivug_retv_if(!data, ECORE_CALLBACK_CANCEL); + + Ivug_MainView *pMainView = (Ivug_MainView *)data; + + pMainView->exit_timer = NULL; + + DESTROY_ME(); + + return ECORE_CALLBACK_CANCEL; +} + +static void _on_resize(void *data, Evas *e, Evas_Object *obj, void *event_info) +{ + Ivug_MainView *pMainView = static_cast(data); + IV_ASSERT(pMainView != NULL); + + Evas_Coord x,y,w,h; + evas_object_geometry_get(obj, &x, &y, &w, &h); + /** + * during slideshow, after rotation, resize cb of slideshow obj cannot be invoked, + so invoke it manually + */ + if(pMainView->ssHandle) + ivug_ss_resize(pMainView->ssHandle); + MSG_MAIN_HIGH("MainView resized geomtery XYWH(%d,%d,%d,%d) Rotate=%d", x, y, w, h, gGetRotationDegree()); +} + +static void +_on_popup_response(void *data, Evas_Object *obj, void *event_info) +{ + IV_ASSERT(data != NULL); + Ivug_MainView *pMainView = (Ivug_MainView *)data; + + ivug_main_view_set_hide_timer(pMainView); +} + +static bool _destory_slideshow_and_ug(Ivug_MainView *pMainView, + int state, + bool bMmc_out) +{ + IV_ASSERT(pMainView != NULL); + evas_object_smart_callback_del_full(ivug_ss_object_get(pMainView->ssHandle), + "slideshow,finished", _on_slideshow_finished, pMainView); + + ivug_allow_lcd_off(); + /*from gallery ablum*/ + if(pMainView->mode == IVUG_MODE_SLIDESHOW || bMmc_out) + { + MSG_MAIN_HIGH("image viewer end cause slide show ended"); + DESTROY_ME(); + return true; + } + if(state == SLIDE_SHOW_STOPPED) + { + if(pMainView->bFootSteps == true) // does not exit when View By is by Place + { + MSG_MAIN_HIGH("image viewer end cause footsteps slide show ended"); + _send_result_footsteps(gGetUGHandle()); + DESTROY_ME(); + return true; + } + } + return false; +} + + +static void _on_mmc_state_changed(keynode_t* node, void *data) +{ + Ivug_MainView *pMainView = (Ivug_MainView *)data; + if (NULL == pMainView) { + return; + } + + if(_is_mmc_inserted() == false ) + { + MSG_IMAGEVIEW_WARN("MMC Removed!. Request destroy UG=0x%08x", gGetUGHandle()); + + if ( pMainView->ext_ug ) + { + MSG_IMAGEVIEW_HIGH("Extern UG is running"); + } + + if(pMainView->ssHandle) + { + ivug_1btn_popup_show(ivug_ss_object_get(pMainView->ssHandle), IDS_ERROR, IDS_SD_CARD_REMOVED, _on_popup_response, pMainView); + pMainView->ssHandle->state = SLIDE_SHOW_STOPPED; + _destory_slideshow_and_ug(pMainView, pMainView->ssHandle->state, true); + } else { + ivug_1btn_popup_show(pMainView->layout, IDS_ERROR, IDS_SD_CARD_REMOVED, _on_popup_response, pMainView); + pMainView->exit_timer = ecore_timer_add(0.2, _on_exit_timer_expired, data); + } + } +} + +static void _show_zoom_icon(void *data) +{ + ivug_ret_if(!data); + + MSG_MAIN_ERROR("_show_zoom_icon"); + + Ivug_MainView *pMainView = (Ivug_MainView *)data; + + /*unsigned int zoom_level = ivug_slider_zoom_level_get(pMainView->slider); + if(zoom_level == 0) + { + edje_object_signal_emit(_EDJ(pMainView->empty_layout), "elm,state,btn_zoom_out,disable","elm"); + edje_object_signal_emit(_EDJ(pMainView->empty_layout), "elm,state,btn_zoom_in,enable","elm"); + } + else if(zoom_level == ZOOM_LEVEL_MAX) + { + edje_object_signal_emit(_EDJ(pMainView->empty_layout), "elm,state,btn_zoom_in,disable","elm"); + edje_object_signal_emit(_EDJ(pMainView->empty_layout), "elm,state,btn_zoom_out,enable","elm"); + } + else*/ + { + edje_object_signal_emit(_EDJ(pMainView->empty_layout), "elm,state,btn_zoom_out,enable","elm"); + edje_object_signal_emit(_EDJ(pMainView->empty_layout), "elm,state,btn_zoom_in,enable","elm"); + } + + edje_object_signal_emit(_EDJ(pMainView->empty_layout), "elm,state,zoom_slider,show","elm"); +} + +static void _update_main_view(Ivug_MainView *pMainView) +{ + if (NULL == pMainView) { + return; + } + + Media_Item *mitem = ivug_slider_get_item(pMainView->slider); + Media_Data *mdata = ivug_medialist_get_data(mitem); + + if(mdata == NULL) + { + MSG_MAIN_ERROR("mdata is NULL"); + return; + } + + PERF_CHECK_BEGIN(LVL6, "Set menu title"); + + _update_title(pMainView); + + PERF_CHECK_END(LVL6, "Set menu title"); + + ivug_ctrlbar ctrlBarType; + ivug_toolbar toolBarType; + + ctrlBarType = _get_ctrl_bar_type(pMainView->mode, mdata->slide_type); + toolBarType = _get_tool_bar_type(pMainView->mode, mdata->slide_type); + + if ( toolBarType != pMainView->tool_bar_type ) // when change toolbar Type + { + PERF_CHECK_BEGIN(LVL6, "add toolbar item"); + + MSG_MAIN_HIGH("ToolBar update. Old=%d Cur=%d", toolBarType , pMainView->tool_bar_type); + + if ( toolBarType == NAVI_BAR_TYPE_EMPTY ) + { + elm_object_item_part_content_unset(pMainView->navi_it, "optionheader"); // Unset toolbar + } + else + { + elm_object_item_part_content_set(pMainView->navi_it, "optionheader", pMainView->tool_bar); + + _update_tool_bar(pMainView, toolBarType); + } + + pMainView->tool_bar_type = toolBarType; + + PERF_CHECK_END(LVL6, "add toolbar item"); + } + + if ( ctrlBarType != pMainView->ctrl_bar_type ) // when change ctrlbar Type + { + PERF_CHECK_BEGIN(LVL6, "add contolbar item"); + + MSG_MAIN_HIGH("CtrlBar update. Old=%d Cur=%d", ctrlBarType , pMainView->ctrl_bar_type); + _update_ctrl_bar(pMainView, ctrlBarType); + pMainView->ctrl_bar_type = ctrlBarType; + + PERF_CHECK_END(LVL6, "add contolbar item"); + } + +// Enable or Disable toolbar buttons. + _update_toolbuttons(pMainView); + + _show_zoom_icon(pMainView); +} + +static void +_ivug_main_drm_popup_purchase_cb(void *data, Evas_Object *obj, void *event_info) +{ + int response_id = (int)event_info; + IV_ASSERT(data != NULL); + + Ivug_MainView *pMainView = (Ivug_MainView *)data; + + MSG_MAIN_HIGH("DRM popup selected : %d", response_id); + + if(response_id == POPUP_RESPONSE_CANCEL) + { + MSG_MAIN_HIGH("cancel selected"); +#ifdef USE_SLIDE_SKIP + MSG_MAIN_HIGH("shift again"); + ivug_slider_skip(pMainView->slider); +#else + ivug_slider_load(pMainView->slider); +#endif + } + else + { + MSG_MAIN_HIGH("unlock process"); + + Media_Item *mitem = ivug_slider_get_item(pMainView->slider); + Media_Data *mdata = ivug_medialist_get_data(mitem); + + char *url = ivug_drm_get_right_url(mdata->filepath); + if (url != NULL) + { + MSG_MAIN_HIGH("path = %s, right url : %s", mdata->filepath, url); + ivug_ext_launch_browser(url); + free(url); + } + else + { + MSG_MAIN_ERROR("ivug_drm_get_right_url error. path = %s", mdata->filepath); + } + } +} + + +static void +_ivug_main_drm_popup_response_cb(void *data, Evas_Object *obj, void *event_info) +{ + int response_id = (int)event_info; + IV_ASSERT(data != NULL); + + Ivug_MainView *pMainView = (Ivug_MainView *)data; + + MSG_MAIN_HIGH("DRM popup selected : %d", response_id); + + if(response_id == POPUP_RESPONSE_CANCEL) + { + MSG_MAIN_HIGH("cancel selected"); +#ifdef USE_SLIDE_SKIP + MSG_MAIN_HIGH("shift again"); + ivug_slider_skip(pMainView->slider); +#else + ivug_slider_load(pMainView->slider); +#endif + + } + else + { + ivug_slider_load(pMainView->slider); + } +} + + +void _ivug_main_view_drm_process(drm_constraints result, int info, void *data) +{ +#define MAX_DBUFFER_SIZE 2048 + + ivug_ret_if(!data); + Ivug_MainView *pMainView = (Ivug_MainView *)data; + + char string[MAX_DBUFFER_SIZE] = ""; + Media_Item *mitem = ivug_slider_get_item(pMainView->slider); + Media_Data *mdata = ivug_medialist_get_data(mitem); + slide_state_t state = ivug_slider_get_state(pMainView->slider); + + if(mdata == NULL) + { + MSG_MAIN_ERROR("mdata is NULL"); + return; + } + + switch(result) + { + case IVUG_DRM_RESULT_LIMITED: + MSG_MAIN_HIGH("Limited"); + snprintf(string, sizeof(string), + IDS_DRM_UNLOCK, + ecore_file_file_get(mdata->filepath)); + ivug_2btn_popup_show(pMainView->layout, NULL, string, _ivug_main_drm_popup_purchase_cb, pMainView); + break; + case IVUG_DRM_RESULT_UNLIMITED: + MSG_MAIN_HIGH("Unlimited"); + if(state != SLIDE_STATE_LOADED) + { + ivug_slider_load(pMainView->slider); + } + break; + case IVUG_DRM_RESULT_COUNT: + MSG_MAIN_HIGH("Count = %d", info); + if(info > 2) + { + ivug_slider_load(pMainView->slider); + } + else if(info == 2) + { + snprintf(string, sizeof(string), + IDS_DRM_COUNT_BASED_OPEN_MANY, 2, + ecore_file_file_get(mdata->filepath)); + ivug_2btn_popup_show(pMainView->layout, NULL, string, _ivug_main_drm_popup_response_cb, pMainView); + } + else + { + snprintf(string, sizeof(string), + IDS_DRM_COUNT_BASED_OPEN_ONE, + ecore_file_file_get(mdata->filepath)); + ivug_2btn_popup_show(pMainView->layout, NULL, string, _ivug_main_drm_popup_response_cb, pMainView); + } + break; + case IVUG_DRM_RESULT_INTERVAL_DAYS: + MSG_MAIN_HIGH("Interval days = %d", info); + snprintf(string, sizeof(string), + IDS_DRM_INTERVAL_BASED_DAYS, + ecore_file_file_get(mdata->filepath), + info); + ivug_2btn_popup_show(pMainView->layout, NULL, string, _ivug_main_drm_popup_response_cb, pMainView); + break; + case IVUG_DRM_RESULT_ACCUMULATED: + MSG_MAIN_HIGH("Accumulated time = %d", info); + /* TODO : get more license popup? */ + break; + case IVUG_DRM_RESULT_DATETIME: + case IVUG_DRM_RESULT_TIMED_COUNT: + case IVUG_DRM_RESULT_SYSTEM: + default : + ivug_slider_load(pMainView->slider); + break; + } +} + + +static void +_on_slider_clicked(void *data, Evas_Object *obj, void *event_info) +{ + MSG_MAIN_HIGH("Main View Clicked"); + IV_ASSERT(data != NULL); + + Ivug_MainView *pMainView = (Ivug_MainView *)data; + +// TODO : Bug. menu bar is blinking when stopping slide show. + if (pMainView->bShowMenu) + { + ivug_main_view_hide_menu_bar(pMainView); + } + else + { + ivug_main_view_show_menu_bar(pMainView); + } + +} + +static void +_on_slider_icon_clicked(void *data, Evas_Object *obj, void *event_info) +{ + MSG_MAIN_HIGH("Main View Video icon Clicked"); + IV_ASSERT(data != NULL); + + Ivug_MainView *pMainView = (Ivug_MainView *)data; + + Media_Item *mitem = ivug_slider_get_item(pMainView->slider); + Media_Data *mdata = ivug_medialist_get_data(mitem); + if (mdata == NULL) + { + MSG_MAIN_ERROR("slide data is NULL"); + return; + } + + if (pMainView->mode == IVUG_MODE_FILE || pMainView->mode == IVUG_MODE_DISPLAY || pMainView->mode == IVUG_MODE_SINGLE ) + { // TODO : Need description + MSG_MAIN_HIGH("Launching simple video player. Mode=%d", pMainView->mode); + ivug_ext_launch_videoplayer_simple(mdata->filepath); + } + else + { + MSG_MAIN_HIGH("Launching normal video player"); + ivug_ext_launch_videoplayer(mdata->filepath); + } + +} + +static Eina_Bool _ivug_long_press_timer_expired(void *data) +{ + ivug_retv_if(!data, ECORE_CALLBACK_CANCEL); + + Ivug_MainView *pMainView = (Ivug_MainView *)data; + + MSG_SETAS_HIGH("long press timer expired"); + + pMainView->popup_timer = NULL; + + if(pMainView->bLongpressEnd == false) // still press + { + if(pMainView->longpress_popup) + { + IVUG_DEBUG_WARNING("copy popup remove"); + evas_object_del(pMainView->longpress_popup); + pMainView->longpress_popup = NULL; + } + } + + + return ECORE_CALLBACK_CANCEL; +} + +static void +_on_slider_long_pressed(void *data, Evas_Object *obj, void *event_info) +{ + Elm_Gesture_Taps_Info *p = (Elm_Gesture_Taps_Info *) event_info; + ivug_ret_if(!data||!p); + + Ivug_MainView *pMainView = (Ivug_MainView *)data; + + MSG_MAIN_HIGH("LongPressed XY(%d,%d)", p->x, p->y); + + int x = p->x; + int y = p->y; + + if ( ivug_slider_get_state(pMainView->slider) != SLIDE_STATE_LOADED) + { + MSG_MAIN_ERROR("Long pressed. but state is not ready"); + return; + } + + pMainView->longpress_popup = ivug_longpress_popup_show(pMainView->slider, x, y, _on_longpress_popup_selected, pMainView); + if (pMainView->longpress_popup == NULL) + { + IVUG_DEBUG_WARNING("long press popup create failed"); + return ; + } + + pMainView->bLongpressEnd = false; + pMainView->popup_timer = ecore_timer_add(LONGTAP_TIMEOUT, _ivug_long_press_timer_expired, pMainView); +} + +static void +_on_slider_long_press_end(void *data, Evas_Object *obj, void *event_info) +{ + //Elm_Gesture_Taps_Info *p = (Elm_Gesture_Taps_Info *) event_info; + //ivug_ret_if(!data||!p); + ivug_ret_if(!data); + + Ivug_MainView *pMainView = (Ivug_MainView *)data; + + pMainView->bLongpressEnd = true; + + if(pMainView->popup_timer) + { + ecore_timer_del(pMainView->popup_timer); + pMainView->popup_timer = NULL; + } + + if((int)event_info == LONGTAP_CANCELED) + { + if(pMainView->longpress_popup) + { + IVUG_DEBUG_WARNING("copy popup remove"); + evas_object_del(pMainView->longpress_popup); + pMainView->longpress_popup = NULL; + } + } +} + +static void _on_remove_main_view_ui(Ivug_MainView *pMainView) +{ + IV_ASSERT(pMainView != NULL); + + ivug_main_view_del_hide_timer(pMainView); + + // Slider should be removed before mList is freed. + if ( pMainView->slider ) + { + evas_object_del(pMainView->slider); + pMainView->slider = NULL; + } + + if ( pMainView->pSetAsView ) + { + MSG_MAIN_HIGH("SetAS View Destroy"); + ivug_setas_view_destroy(pMainView->pSetAsView); + pMainView->pSetAsView = NULL; + } + + if ( pMainView->pDetailsView ) + { + MSG_MAIN_HIGH("Details View Destroy"); + + ivug_details_view_destroy(pMainView->pDetailsView); + pMainView->pDetailsView = NULL; + } + + if(pMainView->layout) // Remove topmost parent in main view. + { + evas_object_del(pMainView->layout); + pMainView->layout = NULL; + } + + if(pMainView->empty_layout) + { + evas_object_del(pMainView->empty_layout); + pMainView->empty_layout = NULL; + } + + if ( pMainView->mList ) + { + MSG_MAIN_HIGH("Remove media list"); + ivug_medialist_del(pMainView->mList); // ivug_medialist_del() is not working on destroy cb. + pMainView->mList = NULL; + } + + DESTROY_ME(); +} + + +static void +_on_slider_item_changed(void *data, Evas_Object *obj, void *event_info) +{ + IV_ASSERT(data != NULL); + + Ivug_MainView *pMainView = (Ivug_MainView *)data; + Slide_Item *sitem = (Slide_Item *)event_info; + + MSG_MAIN_HIGH("Image slider changed callback. "); + + if ( sitem == NULL || sitem->mitem == NULL) + { + // There is no item existed. terminate UG + MSG_MAIN_ERROR("No item is remained. exit UG. Sitem=0x%08x", sitem); + _on_remove_main_view_ui(pMainView); + //DESTROY_ME(); + + return; + } + + if(pMainView->selectioninfo != NULL) + { + MSG_MAIN_MED("Delete small noti"); + evas_object_del(pMainView->selectioninfo); + pMainView->selectioninfo = NULL; + } + + if (pMainView->longpress_popup) + { + MSG_MAIN_MED("Delete copy popup"); + evas_object_del(pMainView->longpress_popup); + pMainView->longpress_popup = NULL; + } + +// TODO : DRM consumption + drm_data_t *drm_data = ivug_slider_item_check_drm_constraint(sitem); + if(drm_data) + { + _ivug_main_view_drm_process(drm_data->constraints, drm_data->data, pMainView); + free(drm_data); + } + +// Update Main View. + if ( pMainView->bShowMenu == true ) + { + PERF_CHECK_BEGIN(LVL5, "Update main view"); + _update_main_view(pMainView); + PERF_CHECK_END(LVL5, "Update main view"); + } + + pMainView->zoom_level = 1; + elm_slider_value_set(pMainView->zoom_slider, 1.0); +} + + +static void +_on_slider_item_state_changed(void *data, Evas_Object *obj, void *event_info) +{ + MSG_MAIN_HIGH("Image slider item state changed callback. "); + ivug_ret_if(!data); + + Ivug_MainView *pMainView = (Ivug_MainView *)data; + Slide_Item *sitem = (Slide_Item *)event_info; + + if ( sitem == NULL || sitem->mitem == NULL) + { + // There is no item existed. terminate UG + MSG_MAIN_ERROR("No item is remained. exit UG"); + DESTROY_ME(); + + return; + } + +// TODO : DRM consumption + +// Update Main View. + if ( pMainView->bShowMenu == true ) + { + _update_toolbuttons(pMainView); + } +} + +void _on_receive_mouse_down (void *data, Evas *e, Evas_Object *obj, void *event_info) +{ + Ivug_MainView *pMainView = (Ivug_MainView *)data; + if (NULL == pMainView) { + return; + } + + ivug_main_view_del_hide_timer(pMainView); + + MSG_MAIN_HIGH("Event layer clicked : %s %s Layer=%d",evas_object_name_get(obj), evas_object_type_get(obj), evas_object_layer_get(obj)); +} + +#ifdef TEST_MOUSE_EVENT +void _on_receive_mouse_down1 (void *data, Evas *e, Evas_Object *obj, void *event_info) +{ + char *name = (char *)data; + + MSG_MAIN_HIGH("Event layer clicked : %s %s Layer=%d",evas_object_name_get(obj), name, evas_object_layer_get(obj)); +} +#endif + + +void _on_receive_mouse_up (void *data, Evas *e, Evas_Object *obj, void *event_info) +{ + Ivug_MainView *pMainView = (Ivug_MainView *)data; + if (NULL == pMainView) { + return; + } + + ivug_main_view_set_hide_timer(pMainView); +} + +static void +_on_menu_state_changed(void *data, Evas_Object *obj, const char *emission, const char *source) +{ + Ivug_MainView *pMainView = static_cast(data); + if (NULL == pMainView) { + return; + } + + MSG_MAIN_HIGH("Receive %s %s", emission, source); + + if ( strncmp(emission, "menu,show,finished", strlen(emission)) == 0 ) + { + elm_object_disabled_set(pMainView->ctrl_bar, EINA_FALSE); + } + else + { + evas_object_hide(pMainView->ctrl_bar); + elm_object_disabled_set(pMainView->ctrl_bar, EINA_TRUE); + } +} + + +#if 0 +static void +_need_prev(void *data, Evas_Object *obj, void *event_info) +{ + Ivug_MainView *pMainView = static_cast(data); + if (NULL == pMainView) { + return; + } + + Thumblist_Block_Index *block = (Thumblist_Block_Index *)event_info; + + Media_Item *iter = (Media_Item *)block->item_data; + Media_Data *pData; + int i = 0; + + PERF_CHECK_BEGIN("Load thumb list"); + + for ( i = 0 ; i < block->count; i++) + { + iter = ivug_medialist_get_prev(pMainView->mList, iter); + + if ( iter == NULL ) break; + + pData = ivug_medialist_get_data(iter); + + PERF_CHECK_BEGIN(" Prepend Item"); + if ( pData->thumbnail_path == NULL ) + ivug_thumblist_prepend_item(pMainView->thumbs, DEFAULT_THUMBNAIL_PATH, iter); + else + ivug_thumblist_prepend_item(pMainView->thumbs, pData->thumbnail_path, iter); + + PERF_CHECK_END(" Prepend Item"); + } + + PERF_CHECK_END("Load thumb list"); +} + +static void +_need_next(void *data, Evas_Object *obj, void *event_info) +{ + Ivug_MainView *pMainView = static_cast(data); + if (NULL == pMainView) { + return; + } + + Thumblist_Block_Index *block = (Thumblist_Block_Index *)event_info; + + Media_Item *iter = (Media_Item *)block->item_data; + Media_Data *pData; + int i = 0; + + PERF_CHECK_BEGIN("Load thumb list"); + + for ( i = 0 ; i < block->count; i++) + { + iter = ivug_medialist_get_next(pMainView->mList, iter); + + if ( iter == NULL ) break; + + pData = ivug_medialist_get_data(iter); + + PERF_CHECK_BEGIN(" Append Item"); + + if ( pData->thumbnail_path == NULL ) + ivug_thumblist_append_item(pMainView->thumbs, DEFAULT_THUMBNAIL_PATH, iter); + else + ivug_thumblist_append_item(pMainView->thumbs, pData->thumbnail_path, iter); + + PERF_CHECK_END(" Append Item"); + } + + PERF_CHECK_END("Load thumb list"); + +} +#endif + + + +/////////////////////////////////////////////////////////////////////////////////////////////////// +// +// External APIs +// + +static char * _ivug_get_folder_name(char *filepath) +{ + char *folder = ecore_file_dir_get(filepath); + + char *name = NULL; + + name = strrchr(folder, '/'); + if ( (name != NULL) && ((name+1) != NULL) ) + { + return strdup(name + 1); + } + + return NULL; +} + + +bool +ivug_main_view_load_list(Ivug_MainView *pMainView, ivug_parameter *ivug_param) +{ + MSG_MAIN_HIGH("Load media list."); + + PERF_CHECK_BEGIN(LVL2, "create media list"); + if (NULL == pMainView) { + return false; + } + + Media_List *mlist = ivug_medialist_create(); + if (mlist == NULL) + { + MSG_MAIN_ERROR("Creating media list failed"); + return false; + } + PERF_CHECK_END(LVL2, "create media list"); + + PERF_CHECK_BEGIN(LVL2, "create filter"); + + Filter_struct *filter = ivug_data_filter_create(ivug_param); + if (filter == NULL) + { + MSG_MAIN_ERROR("Creating filter failed"); + free(mlist); + return false; + } + + PERF_CHECK_END(LVL2, "create filter"); + + Media_Item *current = NULL; + Media_Data *pData = NULL; + + { + PERF_CHECK_BEGIN(LVL2, "media list load"); + current = ivug_medialist_load(mlist, filter); + PERF_CHECK_END(LVL2, "media list load"); + } + + if(current == NULL) + { + MSG_MAIN_ERROR("Media list load failed"); + goto LOAD_LIST_FAILED; + } + + pData = ivug_medialist_get_data(current); + if(pData == NULL) + { + MSG_MAIN_ERROR("current data is NULL"); + goto LOAD_LIST_FAILED; + } + if(pData->fileurl == NULL) + { + MSG_MAIN_ERROR("current fileurl is NULL"); + goto LOAD_LIST_FAILED; + } + + +#ifdef USE_RESCAN_FILE_PATH_AT_LIST + if(strncmp(pData->fileurl, ivug_param->filepath, strlen(pData->fileurl)) != 0) + { + current = ivug_medialist_find_item_by_filename(mlist, ivug_param->filepath); + if(current == NULL) + { + MSG_MAIN_ERROR("Media list load failed, %s is not exist at list", ivug_param->filepath); + goto LOAD_LIST_FAILED; + } + } +#endif + + if(ivug_param->view_by == IVUG_VIEW_BY_ALL) + { + pMainView->album_name = strdup(IDS_ALL_ALBUMS); + } + else if(ivug_param->view_by == IVUG_VIEW_BY_FOLDER) + { + // TODO : it is not run!! DB problem!!! + /* + media_handle m_handle = ivug_db_get_folder_handle(ecore_file_dir_get(ivug_param->filepath)); + if(m_handle == NULL) + { + MSG_IVUG_FATAL("View by Folder. but media handle is NULL" ); + return NULL; + } + + pMainView->album_name = ivug_db_get_folder_name(m_handle); + */ + pMainView->album_name = _ivug_get_folder_name(ivug_param->filepath); + if(pMainView->album_name == NULL) + { + pMainView->album_name = strdup(IDS_NO_NAME); + } + } + + if(ivug_param->footsteps == true) + { + pMainView->bFootSteps = true; + } + + pMainView->mList = mlist; + + PERF_CHECK_BEGIN(LVL2, "media list set"); + if(ivug_slider_set_medialist(pMainView->slider, mlist, current) == EINA_FALSE) + { + MSG_MAIN_ERROR("ivug_slider_set_medialist error"); + goto LOAD_LIST_FAILED; + } + PERF_CHECK_END(LVL2, "media list set"); + + return true; + +LOAD_LIST_FAILED: + if(filter) + ivug_data_filter_delete(filter); + if(mlist) + ivug_medialist_del(mlist); + pMainView->mList = NULL; + return false; +} + +static void +_on_slideshow_finished(void *data, Evas_Object *obj, void *event_info) +{ + MSG_MAIN_HIGH("_on_slideshow_finished"); + IV_ASSERT(data != NULL); + + Ivug_MainView *pMainView = (Ivug_MainView *)data; + + int ss_state = (int)event_info; + bool bDestoryed = false; + bDestoryed = _destory_slideshow_and_ug(pMainView, ss_state, false); + if (bDestoryed) { + return; + } + + Media_Item * item = NULL; + item = ivug_ss_item_get(pMainView->ssHandle); + ivug_ss_delete(pMainView->ssHandle); + if(item) { + ivug_slider_set_item(pMainView->slider, item, SLIDE_INSTANTLY); + } + pMainView->ssHandle = NULL; + +// ivug_slider_load(pMainView->slider); + + ivug_slider_load(pMainView->slider); + + ivug_main_view_show_menu_bar(pMainView); +} + +static void +_ivug_main_view_zoom_out_cb(void *data, Evas_Object *obj, const char *emission, const char *source) +{ + ivug_ret_if(!obj); + ivug_ret_if(!data); + + MSG_MAIN_ERROR("_ivug_main_view_zoom_out_cb"); + + Ivug_MainView *pMainView = (Ivug_MainView *)data; + + ivug_slider_zoom_out(pMainView->slider); + + _show_zoom_icon(data); +} + +static void +_ivug_main_view_zoom_in_cb(void *data, Evas_Object *obj, const char *emission, const char *source) +{ + ivug_ret_if(!obj); + ivug_ret_if(!data); + + MSG_MAIN_ERROR("_ivug_main_view_zoom_in_cb"); + + Ivug_MainView *pMainView = (Ivug_MainView *)data; + + ivug_slider_zoom_in(pMainView->slider); + + _show_zoom_icon(data); +} + +static void _zoom_slider_change_cb(void *data, Evas_Object *obj, void *event_info) +{ + Ivug_MainView *pMainView = (Ivug_MainView *)data; + + int value = (int)elm_slider_value_get(pMainView->zoom_slider); + + MSG_MAIN_HIGH("value = %d", value); + + while(pMainView->zoom_level > 0 + && pMainView->zoom_level <= ZOOM_LEVEL_MAX+1 + && value != pMainView->zoom_level) + { + if(value > pMainView->zoom_level) + { + ivug_slider_zoom_in(pMainView->slider); + pMainView->zoom_level++; + } + else if(value < pMainView->zoom_level) + { + ivug_slider_zoom_out(pMainView->slider); + pMainView->zoom_level--; + } + } +} + +Ivug_MainView * +ivug_main_view_create(Evas_Object* parent, ivug_mode mode, ivug_view_by view_by) +{ + IV_ASSERT(parent != NULL); + + MSG_MAIN_HIGH("Creating main view. Parent=0x%08x Mode=%d ViewBy=%d", parent, mode, view_by); + + PERF_CHECK_BEGIN(LVL2, "Create layout"); + +//create main view layout + Ivug_MainView *pMainView = (Ivug_MainView *)calloc(1, sizeof(Ivug_MainView) ); + IV_ASSERT(pMainView != NULL); + +// Set default value + pMainView->parent = parent; + pMainView->mode = mode; + pMainView->view_by = view_by; + if(mode != IVUG_MODE_SLIDESHOW) + { + pMainView->bShowMenu = true; + } + else + { + pMainView->bShowMenu = false; + } + + pMainView->hide_count = -1; + + Evas_Object *layout; + layout = elm_layout_add(parent); + if ( layout == NULL) //if failed + { + MSG_MAIN_ERROR("main layout create failed"); + free(pMainView); + return NULL; + } + + pMainView->layout = layout; + evas_object_name_set(pMainView->layout, "Main Layout"); + + PERF_CHECK_END(LVL2, "Create layout"); + + PERF_CHECK_BEGIN(LVL2, "elm_layout_file_set"); + if (elm_layout_file_set(layout, IVUG_MAIN_EDJ, "mainview") == EINA_FALSE) + { + MSG_MAIN_ERROR("edj loading fail, file=%s group=%s", IVUG_MAIN_EDJ, IVUG_MAIN_EDJ); + evas_object_del(layout); + free(pMainView); + return NULL; + } + + edje_object_signal_callback_add(_EDJ(pMainView->layout), + "menu,hide,finished", + "edc", + _on_menu_state_changed, + (void *)pMainView); + + edje_object_signal_callback_add(_EDJ(pMainView->layout), + "menu,show,finished", + "edc", + _on_menu_state_changed, + (void *)pMainView); + + evas_object_show(layout); + + PERF_CHECK_END(LVL2, "elm_layout_file_set"); + +// Navigation bar + PERF_CHECK_BEGIN(LVL2, "elm_naviframe_add"); + + pMainView->navi_bar = elm_naviframe_add(layout); + if ( pMainView->navi_bar == NULL) + { + MSG_MAIN_ERROR("navigation bar failed"); + ivug_main_view_destroy(pMainView); + return NULL; + } + evas_object_name_set(pMainView->navi_bar, "Main naviframe"); + +// Layout life cycle is controlled by application explictily. + elm_naviframe_content_preserve_on_pop_set(pMainView->navi_bar, EINA_TRUE); + +#ifdef USE_CUSTOM_STYLE + elm_object_theme_set(pMainView->navi_bar, gGetSystemTheme() ); +#endif + const char *profile = elm_config_profile_get(); + if (!strcmp(profile,"mobile")) + { + elm_object_style_set(pMainView->navi_bar, "ivug-main/default"); + } + else if (!strcmp(profile,"desktop")) + { + elm_object_style_set(pMainView->navi_bar, "ivug-main/noindicator"); + } + + elm_object_part_content_set(layout, "mainview.navibar", pMainView->navi_bar); //swallow + + PERF_CHECK_END(LVL2, "elm_naviframe_add"); + + PERF_CHECK_BEGIN(LVL2, "elm_layout_add"); + + pMainView->empty_layout = elm_layout_add(layout); //create centents layout. + if (elm_layout_file_set(pMainView->empty_layout, IVUG_MAIN_EDJ, "navi_content") == EINA_FALSE) + { + IVUG_DEBUG_WARNING("layout sawllow failed"); + ivug_main_view_destroy(pMainView); + return NULL; + } + + evas_object_name_set(pMainView->empty_layout, "Empty layout"); + PERF_CHECK_END(LVL2,"elm_layout_add"); + +//create slider + PERF_CHECK_BEGIN(LVL2, "ivug_slider_add"); + + pMainView->slider = ivug_slider_add(pMainView->empty_layout); + if (pMainView->slider == NULL) + { + MSG_MAIN_ERROR("image slider create failed"); + ivug_main_view_destroy(pMainView); + return NULL; + } + + elm_object_part_content_set(pMainView->empty_layout, "mainview.slider", pMainView->slider); //swallow + + PERF_CHECK_END(LVL2, "ivug_slider_add"); + + Evas_Object *slider = elm_slider_add(pMainView->empty_layout); + //elm_slider_indicator_show_set(slider, EINA_TRUE); + //evas_object_size_hint_weight_set(slider, EVAS_HINT_EXPAND, 0.0); + //evas_object_size_hint_align_set(slider, EVAS_HINT_FILL, 0.5); + elm_slider_indicator_format_set(slider, "%1.0f"); + elm_slider_min_max_set(slider, 1, 5); + elm_slider_value_set(slider, 1); + + //evas_object_smart_callback_add(slider, "slider,drag,start", _slider_ebook_drag_start_cb, slider); + //evas_object_smart_callback_add(slider, "slider,drag,stop", _slider_ebook_drag_stop_cb, slider); + evas_object_smart_callback_add(slider, "changed", _zoom_slider_change_cb, pMainView); + + elm_object_part_content_set(pMainView->empty_layout, "zoom_slider_area", slider); //swallow + + pMainView->zoom_slider = slider; + pMainView->zoom_level = 1; + + PERF_CHECK_BEGIN(LVL2, "ivug_button_add"); + Evas_Object *back_btn = ivug_button_add(pMainView->navi_bar, "naviframe/end_btn/default", IDS_BACK, NULL, on_btn_back_clicked, pMainView); + PERF_CHECK_END(LVL2, "ivug_button_add"); + + PERF_CHECK_BEGIN(LVL2, "elm_naviframe_item_push"); + pMainView->navi_it = elm_naviframe_item_push(pMainView->navi_bar, IDS_LOADING , back_btn, NULL, pMainView->empty_layout, NULL); + PERF_CHECK_END(LVL2, "elm_naviframe_item_push"); + + //if (pMainView->mode != IVUG_MODE_DISPLAY && pMainView->mode != IVUG_MODE_SLIDESHOW) // Display mode has no control bar in bottom. + if (pMainView->mode != IVUG_MODE_DISPLAY) // Display mode has no control bar in bottom. + { + PERF_CHECK_BEGIN(LVL2, "create ctrl bar"); + pMainView->ctrl_bar = _create_ctrl_bar(pMainView->navi_bar); + evas_object_name_set(pMainView->ctrl_bar, "Main Controlbar"); + elm_object_item_part_content_set(pMainView->navi_it, "controlbar", pMainView->ctrl_bar); + PERF_CHECK_END(LVL2, "create ctrl bar"); + } + + PERF_CHECK_BEGIN(LVL2, "create tool bar"); + pMainView->tool_bar = _create_tool_bar(pMainView->navi_bar); + evas_object_name_set(pMainView->tool_bar, "Main Toolbar"); + PERF_CHECK_END(LVL2, "create tool bar"); + + PERF_CHECK_BEGIN(LVL2, "add event handler"); + +// elm_object_part_content_set(layout, "mainview.slider", pMainView->slider); //swallow + +//register mouse call back. + evas_object_smart_callback_add(pMainView->slider, "slider,clicked", _on_slider_clicked, pMainView); + evas_object_smart_callback_add(pMainView->slider, "slider,longpressed", _on_slider_long_pressed, pMainView); + evas_object_smart_callback_add(pMainView->slider, "slider,longpress,end", _on_slider_long_press_end, pMainView); + evas_object_smart_callback_add(pMainView->slider, "slider,clicked,icon", _on_slider_icon_clicked, pMainView); + + evas_object_smart_callback_add(pMainView->slider, "slider,item,changed", _on_slider_item_changed, pMainView); + evas_object_smart_callback_add(pMainView->slider, "slider,item,state,changed", _on_slider_item_state_changed, pMainView); + + evas_object_event_callback_add(pMainView->slider, EVAS_CALLBACK_MOUSE_DOWN, _on_receive_mouse_down, pMainView); + evas_object_event_callback_add(pMainView->slider, EVAS_CALLBACK_MOUSE_UP, _on_receive_mouse_up, pMainView); + + //MSG_MAIN_HIGH("binded main win address is %p\n", main_win); + +#ifdef TEST_MOUSE_EVENT + evas_object_event_callback_add(pMainView->navi_bar, EVAS_CALLBACK_MOUSE_DOWN, _on_receive_mouse_down1, (void *)"navigarion"); + evas_object_event_callback_add(pMainView->layout, EVAS_CALLBACK_MOUSE_DOWN, _on_receive_mouse_down1, (void *)"layout"); + evas_object_event_callback_add(pMainView->slider, EVAS_CALLBACK_MOUSE_DOWN, _on_receive_mouse_down1, (void *)"slider"); + evas_object_event_callback_add(const_cast(edje_object_part_object_get(_EDJ(pMainView->layout) , "clip")), EVAS_CALLBACK_MOUSE_DOWN, _on_receive_mouse_down1, (void *)"clip"); + evas_object_event_callback_add(const_cast(edje_object_part_object_get(_EDJ(pMainView->layout) , "mainview.navibar")), EVAS_CALLBACK_MOUSE_DOWN, _on_receive_mouse_down1, (void *)"navi swallow"); + evas_object_event_callback_add(pMainView->ctrl_bar, EVAS_CALLBACK_MOUSE_DOWN, _on_receive_mouse_down1, (void *)"controlbar"); +#endif + + evas_object_event_callback_add(pMainView->layout, EVAS_CALLBACK_RESIZE, _on_resize, pMainView); + + // zoom icon + edje_object_signal_callback_add(_EDJ(pMainView->empty_layout), + "mainview,zoom_out,clicked", + "", + _ivug_main_view_zoom_out_cb, + (void *)pMainView); + edje_object_signal_callback_add(_EDJ(pMainView->empty_layout), + "mainview,zoom_in,clicked", + "", + _ivug_main_view_zoom_in_cb, + (void *)pMainView); + + _show_zoom_icon(pMainView); + + int ret = -1; + MSG_IMAGEVIEW_HIGH("Register System notifications"); + ret = vconf_notify_key_changed(VCONFKEY_SYSMAN_MMC_STATUS, _on_mmc_state_changed, pMainView); + if ( ret == -1 ) + { + MSG_IMAGEVIEW_ERROR("Register %s is failed", VCONFKEY_SYSMAN_MMC_STATUS); + } + + pMainView->keydown_handler = ecore_event_handler_add(ECORE_EVENT_KEY_DOWN, _on_key_down, (void *)pMainView); + + MSG_MAIN_HIGH("Main View Created"); + +// For debugging. + DELETE_NOTIFY(pMainView->layout); + + PERF_CHECK_END(LVL2, "add event handler"); + + return pMainView; + +} + +void ivug_main_view_start_slideshow(Ivug_MainView *pMainView, Eina_Bool bSlideFirst) +{ + IV_ASSERT(pMainView != NULL); + + // Stop animation & movie play before slideshow is started. + ivug_slider_pause(pMainView->slider); + + // TODO : After slideshow is finished, how can I resume??? + + ivug_prohibit_lcd_off(); + ivug_main_view_hide_menu_bar(pMainView); + + Media_Item *current = ivug_slider_get_item(pMainView->slider); + + pMainView->ssHandle = ivug_ss_create(pMainView->layout); + +// Register callback + evas_object_smart_callback_add(ivug_ss_object_get(pMainView->ssHandle), "slideshow,finished", _on_slideshow_finished, pMainView); + + ivug_ss_start(pMainView->ssHandle, current, pMainView->mList, bSlideFirst); +} + + +Evas_Object * +ivug_main_view_object_get(Ivug_MainView *pMainView) +{ + IV_ASSERT(pMainView != NULL); + + return pMainView->layout; +} + +void +ivug_main_view_start(Ivug_MainView *pMainView) +{ + IV_ASSERT(pMainView != NULL); + + if(pMainView->mode == IVUG_MODE_SLIDESHOW || pMainView->bFootSteps == true) + { + MSG_MAIN_HIGH("Slide show running"); + ivug_main_view_start_slideshow(pMainView, EINA_FALSE); + return; + } + + ivug_main_view_set_hide_timer(pMainView); + + PERF_CHECK_BEGIN(LVL2, "slider start"); + ivug_slider_start(pMainView->slider); + PERF_CHECK_END(LVL2, "slider start"); + + pMainView->area_obj = evas_object_rectangle_add(evas_object_evas_get(pMainView->layout)); + evas_object_size_hint_expand_set(pMainView->area_obj, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + evas_object_size_hint_fill_set(pMainView->area_obj, EVAS_HINT_FILL, EVAS_HINT_FILL); + evas_object_color_set(pMainView->area_obj, 0,0,0,0); + elm_object_part_content_set(pMainView->layout, "mainview.area", pMainView->area_obj); + + evas_object_show(pMainView->area_obj); +} + + +void +ivug_main_view_resume(Ivug_MainView *pMainView) +{ + IV_ASSERT(pMainView != NULL); + + MSG_MAIN_HIGH("Main View Update"); + + Media_Item *mitem = ivug_slider_get_item(pMainView->slider); + Media_Data *mdata = ivug_medialist_get_data(mitem); + + IV_ASSERT(mdata != NULL); + +// TODO : Check this routine!. +// TODO : Should implement again!! + + if (mdata->slide_type == SLIDE_TYPE_IMAGE || mdata->slide_type == SLIDE_TYPE_VIDEO ) + { + if(mdata->filepath && ecore_file_exists(mdata->filepath)) // Current file is not deleted + { + MSG_MAIN_HIGH("Current filepath : %s", mdata->filepath); + } + else + { + /*if file is not exist ug terminated temporally */ + MSG_MAIN_ERROR("Center file is not exist. stype=%d name=%s", mdata->slide_type, mdata->filepath); + DESTROY_ME(); + return ; + } + } + else + { + MSG_MAIN_ERROR("Unhandled slide type : %d", mdata->slide_type); + } + +// When resume, menu bar will be appeared. + ivug_main_view_show_menu_bar(pMainView); + + ivug_slider_resume(pMainView->slider); +} + +void +ivug_main_view_pause(Ivug_MainView *pMainView) +{ + IV_ASSERT(pMainView != NULL); + + if ( pMainView->ssHandle ) + { + ivug_ss_stop(pMainView->ssHandle); + } + + ivug_slider_pause(pMainView->slider); + + if(pMainView->bShowMenu == true) + { + ivug_main_view_del_hide_timer(pMainView); + } + // Stop photocam If AGIF +} + + +void +ivug_main_view_destroy(Ivug_MainView *pMainView) +{ + IV_ASSERT(pMainView != NULL); + + MSG_MAIN_HIGH("ENTER : Main View Destroy. pMainView=0x%08x", pMainView); + + ivug_main_view_del_hide_timer(pMainView); + + if (pMainView->popup_timer) + { + ecore_timer_del(pMainView->popup_timer); + pMainView->popup_timer = NULL; + } + + if (pMainView->ext_ug) + { + MSG_MAIN_HIGH("External UG Destroy"); + ug_destroy(pMainView->ext_ug); + pMainView->ext_ug = NULL; + } + + if (pMainView->exit_timer) + { + ecore_timer_del(pMainView->exit_timer); + pMainView->exit_timer = NULL; + } + + if ( pMainView->zoom_slider ) + { + evas_object_del(pMainView->zoom_slider); + pMainView->zoom_slider = NULL; + } + + if ( pMainView->slider ) + { + evas_object_del(pMainView->slider); + pMainView->slider = NULL; + } + + int ret = -1; + + MSG_MAIN_HIGH("Unregister system notifications"); + + if(pMainView->keydown_handler) + { + ecore_event_handler_del(pMainView->keydown_handler); + pMainView->keydown_handler = NULL; + } + + ret = vconf_ignore_key_changed(VCONFKEY_SYSMAN_MMC_STATUS, _on_mmc_state_changed); + if ( ret == -1 ) + { + MSG_MAIN_ERROR("Unegister %s is failed", VCONFKEY_SYSMAN_MMC_STATUS); + } + + if(pMainView->album_name) + { + free(pMainView->album_name); + } + + if(pMainView->area_obj) + { + evas_object_del(pMainView->area_obj); + pMainView->area_obj = NULL; + } + +// Who remove medialist????? + _on_remove_main_view_ui(pMainView); + + EFL::dump_obj(pMainView->parent, 0); + free(pMainView); + + MSG_MAIN_HIGH("LEAVE : Main View Destroy."); + + return ; +} + +static Eina_Bool _on_hide_timer_expired(void *data) +{ + ivug_retv_if(!data, ECORE_CALLBACK_CANCEL); + + Ivug_MainView *pMainView = (Ivug_MainView *)data; + + pMainView->hide_timer = NULL; + + ivug_main_view_hide_menu_bar(pMainView); + + return ECORE_CALLBACK_CANCEL; +} + +void ivug_main_view_set_hide_timer(Ivug_MainView *pMainView) +{ + IV_ASSERT(pMainView != NULL); + + pMainView->hide_count++; + if(pMainView->hide_count < 0) + { + return ; + } + + if(pMainView->mode == IVUG_MODE_DISPLAY || pMainView->mode == IVUG_MODE_SETAS) + { + return; + } + + if(pMainView->bShowMenu == EINA_TRUE) + { + if(pMainView->hide_timer) + { + ecore_timer_del(pMainView->hide_timer); + } + pMainView->hide_timer = ecore_timer_add(MENUBAR_TIMEOUT_SEC, _on_hide_timer_expired, (void *)pMainView); + } +} + +void ivug_main_view_del_hide_timer(Ivug_MainView *pMainView) +{ + IV_ASSERT(pMainView != NULL); + + pMainView->hide_count--; + MSG_MAIN_HIGH("hide_count = %d", pMainView->hide_count); + + if(pMainView->hide_timer) + { + ecore_timer_del(pMainView->hide_timer); + pMainView->hide_timer = NULL; + } +} + +void +ivug_main_view_show_menu_bar(Ivug_MainView *pMainView) +{ + MSG_MAIN_HIGH("Show Menu"); + if (NULL == pMainView) { + return; + } + + pMainView->bShowMenu = true; + evas_object_show(pMainView->ctrl_bar); + + _update_main_view(pMainView); + +#ifdef HIDE_INDICATOR + elm_win_indicator_mode_set(ug_get_window(), ELM_WIN_INDICATOR_HIDE); +#else + elm_win_indicator_mode_set((Evas_Object *)ug_get_window(), ELM_WIN_INDICATOR_SHOW); +#endif +// edje_object_signal_emit(_EDJ(pMainView->layout), "mainview,show,menu", "elm"); + + edje_object_signal_emit(_EDJ(pMainView->empty_layout), "elm,state,show", "user"); + + elm_naviframe_item_title_visible_set(pMainView->navi_it, EINA_TRUE); + elm_object_item_signal_emit(pMainView->navi_it, "elm,state,controlbar,open", ""); + + ivug_slider_set_menu_visibility(pMainView->slider, EINA_TRUE); + +#ifdef TEST_MOUSE_EVENT + Eina_List *l = const_cast(evas_object_clipees_get(pMainView->navi_bar)); + + MSG_MAIN_HIGH("Clipper clips %i objects", eina_list_count(l)); + + void *obj; + Eina_List *l1; + + EINA_LIST_FOREACH(l, l1, obj) + { + MSG_MAIN_HIGH("Object Type : %s", evas_object_name_get((Evas_Object *)obj)); + } + + Evas_Object *above; + Evas_Object *below; + + above = evas_object_above_get(pMainView->navi_bar); + MSG_MAIN_HIGH("Navi Above : 0x%08x %s %s", above, evas_object_name_get(above), evas_object_type_get(above)); + + below = evas_object_below_get(pMainView->navi_bar); + MSG_MAIN_HIGH("Navi Below : 0x%08x %s %s", below, evas_object_name_get(below), evas_object_type_get(below)); + + above = evas_object_above_get(pMainView->slider); + MSG_MAIN_HIGH("Slider Above : 0x%08x %s %s", above, evas_object_name_get(above), evas_object_type_get(above)); + + below = evas_object_below_get(pMainView->slider); + MSG_MAIN_HIGH("Slider Below : 0x%08x %s %s", below, evas_object_name_get(below), evas_object_type_get(below)); +#endif + + ivug_main_view_set_hide_timer(pMainView); + +} + +void +ivug_main_view_hide_menu_bar(Ivug_MainView *pMainView) +{ + MSG_MAIN_HIGH("Hide Menu"); + if (NULL == pMainView) { + return; + } + + ivug_main_view_del_hide_timer(pMainView); + + pMainView->bShowMenu = false; + + elm_object_disabled_set(pMainView->ctrl_bar, EINA_TRUE); + + edje_object_signal_emit(_EDJ(pMainView->empty_layout), "elm,state,hide", "user"); + + elm_win_indicator_mode_set((Evas_Object *)ug_get_window(), ELM_WIN_INDICATOR_HIDE); + +// edje_object_signal_emit(_EDJ(pMainView->layout), "mainview,hide,menu","elm"); + elm_naviframe_item_title_visible_set(pMainView->navi_it, EINA_FALSE); + elm_object_item_signal_emit(pMainView->navi_it, "elm,state,controlbar,close", ""); + + // zoom icon + edje_object_signal_emit(_EDJ(pMainView->empty_layout), "elm,state,btn_zoom_out,hide","elm"); + edje_object_signal_emit(_EDJ(pMainView->empty_layout), "elm,state,btn_zoom_in,hide","elm"); + edje_object_signal_emit(_EDJ(pMainView->empty_layout), "elm,state,zoom_slider,hide","elm"); + + ivug_slider_set_menu_visibility(pMainView->slider, EINA_FALSE); + +} + diff --git a/main/src/view/ivug-name-view.c b/main/src/view/ivug-name-view.c new file mode 100755 index 0000000..e032e61 --- /dev/null +++ b/main/src/view/ivug-name-view.c @@ -0,0 +1,436 @@ +/* + * Copyright 2012 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.tizenopensource.org/license + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include "ivug-common.h" + +#include "ivug-name-view.h" +#include "ivug-popup.h" + +#include "ivug-media.h" +#include "ivug-vibration.h" + +static void +_ivug_rename_view_enter_click_cb(void *data, Evas_Object *obj, void *event_info) +{ + MSG_IMAGEVIEW_HIGH("inside ..."); + Ivug_NameView *pNameView = (Ivug_NameView *)data; + IV_ASSERT(pNameView != NULL); + + Evas_Object *entry = elm_object_part_content_get(pNameView->editfield, "elm.swallow.content"); + + char *name = elm_entry_markup_to_utf8 ( elm_entry_entry_get(entry) ); + + MSG_IMAGEVIEW_HIGH("name = %s", name); + + if(name) + { + char *new_name = NULL; + new_name = ivug_strip_string(name); + if(new_name == NULL) + { + MSG_IMAGEVIEW_ERROR("ivug_strip_string failed"); + free (name); + ecore_imf_context_input_panel_hide(elm_entry_imf_context_get(entry)); + return; + } + + if ( pNameView->fnresponse ) + { + (pNameView->fnresponse)(NAME_VIEW_RESPONSE_OK, new_name, pNameView->clientdata); + } + + free(name); + + ivug_name_view_destroy(pNameView); + } + else + { + ecore_imf_context_input_panel_hide(elm_entry_imf_context_get(entry)); + } +} + +void +_ivug_name_view_maxlength_reached(void *data, Evas_Object *obj, void *event_info) +{ + Ivug_NameView *pNameView = (Ivug_NameView *)data; + IV_ASSERT(pNameView != NULL); + + if ( pNameView->haptic_handle == INVALID_HAPTIC_HANDLE ) + { + pNameView->haptic_handle = ivug_vibration_create(); + } + else + { + ivug_vibration_stop(pNameView->haptic_handle); + } + + ivug_vibration_play(pNameView->haptic_handle ,VIBRATION_DURATION); + +} + +static void +_on_popup_response(void *data, Evas_Object *obj, void *event_info) +{ + IV_ASSERT(data != NULL); + Ivug_NameView *pNameView = (Ivug_NameView *)data; + + ivug_name_view_destroy(pNameView); +} + + +static void +_ivug_name_view_done_cb(void *data, Evas_Object* obj, void* event_info ) +{ + MSG_IMAGEVIEW_HIGH( "pNameView Done "); + Ivug_NameView *pNameView = (Ivug_NameView *)data; + IV_ASSERT(pNameView != NULL); + + Evas_Object *entry = elm_object_part_content_get(pNameView->editfield, "elm.swallow.content"); + + char *name = elm_entry_markup_to_utf8 ( elm_entry_entry_get(entry) ); + + MSG_IMAGEVIEW_HIGH("name = %s", name); + + if(name) + { + char *new_name = NULL; + new_name = ivug_strip_string(name); + if(new_name == NULL) + { + MSG_IMAGEVIEW_ERROR( "ivug_strip_string failed"); + ivug_1btn_popup_show(pNameView->layout, IDS_ERROR, IDS_ENTRY_IS_EMPTY, _on_popup_response, pNameView); + free (name); + return; + } + + if ( pNameView->fnresponse ) + { + (pNameView->fnresponse)(NAME_VIEW_RESPONSE_OK, new_name, pNameView->clientdata); + } + + free(name); + } + + ivug_name_view_destroy(pNameView); +} + +static void +_ivug_name_view_cancel_cb(void *data, Evas_Object *obj, void *event_info) +{ + MSG_IMAGEVIEW_HIGH("pNameView Back"); + Ivug_NameView *pNameView = (Ivug_NameView *)data; + IV_ASSERT(pNameView != NULL); + + if ( pNameView->fnresponse ) + { + (pNameView->fnresponse)(NAME_VIEW_RESPONSE_CANCEL, NULL, pNameView->clientdata); + } + + ivug_name_view_destroy(pNameView); +} + +static void _ivug_name_view_on_entry_changed(void *data, Evas_Object *obj, void *event_info) +{ + Ivug_NameView *pNameView = (Ivug_NameView *)data; + IV_ASSERT(pNameView != NULL); + + if (elm_object_focus_get(pNameView->editfield)) + { + if (elm_entry_is_empty(obj)) + elm_object_signal_emit(pNameView->editfield, "elm,state,eraser,hide", "elm"); + else + elm_object_signal_emit(pNameView->editfield, "elm,state,eraser,show", "elm"); + } + + Evas_Object *entry; + + entry = elm_object_part_content_get(pNameView->editfield, "elm.swallow.content"); + + char *content = elm_entry_markup_to_utf8 ( elm_entry_entry_get(entry) ); + + if (strlen(content) == 0) + { + MSG_IMAGEVIEW_HIGH("ISF1 : %s", content); + elm_object_part_text_set(pNameView->editfield, "elm.guidetext", IDS_ENTER_NAME); + //elm_object_disabled_set(pNameView->btn_done, EINA_TRUE); + } + else + { + MSG_IMAGEVIEW_HIGH("ISF : %s", content); + elm_object_part_text_set(pNameView->editfield, "elm.guidetext", IDS_NULL); + elm_object_disabled_set(pNameView->btn_done, EINA_FALSE); + } + + free(content ); + +} + +static void _ivug_name_view_on_entry_changed_user(void *data, Evas_Object *obj, void *event_info) +{ + MSG_IMAGEVIEW_HIGH("Entry changed by user"); +} + +static void _ivug_name_view_on_entry_focused(void *data, Evas_Object *obj, void *event_info) +{ + MSG_IMAGEVIEW_HIGH("_ivug_name_view_on_entry_focused"); + if (!elm_entry_is_empty(obj)) + elm_object_signal_emit(data, "elm,state,eraser,show", "elm"); + elm_object_signal_emit(data, "elm,state,guidetext,hide", "elm"); +} + +static void _ivug_name_view_on_entry_unfocused(void *data, Evas_Object *obj, void *event_info) +{ + MSG_IMAGEVIEW_HIGH("_ivug_name_view_on_entry_unfocused"); + if (elm_entry_is_empty(obj)) + elm_object_signal_emit(data, "elm,state,guidetext,show", "elm"); + elm_object_signal_emit(data, "elm,state,eraser,hide", "elm"); +} + + +static void +_ivug_name_view_eraser_clicked_cb(void *data, Evas_Object *obj, const char *emission, const char *source) +{ + elm_entry_entry_set(data, ""); +} + +static Evas_Object *_ivug_name_view_editfield_create(void *data, Evas_Object *obj) +{ + Ivug_NameView *pNameView = (Ivug_NameView *)data; + + Evas_Object *editfield = elm_layout_add(obj); + elm_layout_theme_set(editfield, "layout", "editfield", "default"); + + Evas_Object *entry = elm_entry_add(editfield); + elm_entry_single_line_set(entry, EINA_TRUE); + elm_entry_scrollable_set(entry, EINA_TRUE); + + evas_object_smart_callback_add(entry, "activated", _ivug_rename_view_enter_click_cb, pNameView); + evas_object_smart_callback_add(entry, "changed", _ivug_name_view_on_entry_changed, pNameView); + evas_object_smart_callback_add(entry, "changed,user", _ivug_name_view_on_entry_changed_user, pNameView); + evas_object_smart_callback_add(entry, "focused", _ivug_name_view_on_entry_focused, editfield); + evas_object_smart_callback_add(entry, "unfocused", _ivug_name_view_on_entry_unfocused, editfield); + + elm_object_part_content_set(editfield, "elm.swallow.content", entry); + elm_object_signal_callback_add(editfield, "elm,eraser,clicked", "elm", _ivug_name_view_eraser_clicked_cb, entry); + + static Elm_Entry_Filter_Limit_Size limit_filter_data; + limit_filter_data.max_char_count = 64; + limit_filter_data.max_byte_count = 0; + elm_entry_markup_filter_append(entry, elm_entry_filter_limit_size, &limit_filter_data); + + evas_object_smart_callback_add(entry, "maxlength,reached", _ivug_name_view_maxlength_reached, (void *) pNameView); + + elm_object_part_text_set(editfield, "elm.guidetext", IDS_ENTER_NAME); + + MSG_IMAGEVIEW_HIGH("entry = %s", elm_entry_entry_get(entry)); + + pNameView->entry = entry; + + pNameView->editfield = editfield; + + return pNameView->editfield; + +} + +static Evas_Object *_ivug_name_view_create_content(Ivug_NameView *pNameView, Evas_Object *parent) +{ + ivug_retvm_if(!pNameView, NULL, "pNameView is NULL"); + ivug_retvm_if(!parent, NULL, "parent is NULL"); + + Eina_Bool ret = EINA_FALSE; + + Evas_Object *content_lay = elm_layout_add(parent); + evas_object_size_hint_weight_set(content_lay, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + evas_object_size_hint_fill_set(content_lay, EVAS_HINT_FILL, EVAS_HINT_FILL ); + ret = elm_layout_file_set(content_lay, EDJ_PATH"/ivug-name-view.edj", "name_view"); + MSG_IMAGEVIEW_HIGH("ret is %d", ret); + ivug_retvm_if(ret == EINA_FALSE, NULL, "elm_layout_file_set ailed"); + + Evas_Object *editfield = _ivug_name_view_editfield_create(pNameView, content_lay); + elm_object_part_content_set(content_lay, "entry_part", editfield); + + evas_object_show(editfield); + + return content_lay; +} + +Ivug_NameView * +ivug_name_view_create(Evas_Object *parent, const char *title) +{ + MSG_IMAGEVIEW_HIGH( "... "); + + IV_ASSERT(parent != NULL); + + Ivug_NameView *pNameView = calloc(1, sizeof(Ivug_NameView)); + // TODO : ASSERT + if ( pNameView == NULL) + { + MSG_IMAGEVIEW_ERROR("Cannot allocated memory"); + return NULL; + } + + pNameView->haptic_handle = INVALID_HAPTIC_HANDLE; // Invalid + + MSG_IMAGEVIEW_HIGH( "Add Name View creation"); + + pNameView->layout = ivug_default_layout_add(parent); + + if ( pNameView->layout == NULL) + { + MSG_IMAGEVIEW_ERROR("Cannot create layout"); + free(pNameView); + return NULL; + } + + pNameView->bg = ivug_bg_add(pNameView->layout, IVUG_DEFAULT_BG_COLOR, IVUG_DEFAULT_BG_COLOR, IVUG_DEFAULT_BG_COLOR); + + if ( pNameView->bg == NULL) + { + MSG_IMAGEVIEW_ERROR("Cannot create bg"); + free(pNameView); + return NULL; + } + + elm_object_part_content_set(pNameView->layout, "elm.swallow.bg", pNameView->bg); + + Evas_Object *navi_bar; + navi_bar = elm_naviframe_add(pNameView->layout); + + if ( navi_bar == NULL) + { + MSG_IMAGEVIEW_ERROR("Cannot create navigation bar"); + free(pNameView); + return NULL; + } +#ifdef USE_CUSTOM_STYLE + elm_object_theme_set(navi_bar, gGetSystemTheme()); +#endif + elm_object_style_set(navi_bar, "ivug/default"); + + elm_object_part_content_set(pNameView->layout, "elm.swallow.content", navi_bar ); + evas_object_show(navi_bar); + + pNameView->navibar = navi_bar; + + pNameView->content = _ivug_name_view_create_content(pNameView, navi_bar); + if(pNameView->content == NULL) + { + MSG_IMAGEVIEW_ERROR("Cannot create navigation bar"); + free(pNameView); + return NULL; + } + + Evas_Object *cancel_button, *done_button; + + cancel_button = ivug_button_add(navi_bar, NAVI_OPTION_BTN_STYLE, IDS_CANCEL, NULL, _ivug_name_view_cancel_cb, pNameView ); + + done_button = ivug_button_add(navi_bar, NAVI_OPTION_BTN_STYLE, IDS_DONE, NULL, _ivug_name_view_done_cb, pNameView ); + + pNameView->btn_done = done_button; + + //elm_object_disabled_set(done_button, EINA_TRUE); + + Elm_Object_Item *navi_it = NULL; + navi_it = elm_naviframe_item_push(pNameView->navibar, title, NULL, NULL, pNameView->content, NULL); + + elm_entry_cursor_end_set(pNameView->entry); + evas_object_show(pNameView->entry); + elm_object_focus_set(pNameView->entry, EINA_TRUE); // show keypad + + elm_object_item_part_content_set(navi_it, "title_left_btn", done_button); + elm_object_item_part_content_set(navi_it, "title_right_btn", cancel_button); + + return pNameView; +} + + +void +ivug_name_view_destroy(Ivug_NameView *pNameView) +{ + ivug_ret_if(pNameView == NULL); + + MSG_IMAGEVIEW_HIGH( "Destroy Name View"); + + if ( pNameView->haptic_handle != INVALID_HAPTIC_HANDLE ) + { + ivug_vibration_stop(pNameView->haptic_handle); + ivug_vibration_delete(pNameView->haptic_handle); + + pNameView->haptic_handle = INVALID_HAPTIC_HANDLE; + } + + + if(pNameView->layout) + { + evas_object_del(pNameView->layout); + pNameView->layout = NULL; + } + + free(pNameView); + pNameView = NULL; + + MSG_IMAGEVIEW_HIGH("Name view removed"); +} + + +Evas_Object * +ivug_name_view_object_get(Ivug_NameView *pNameView) +{ + IV_ASSERT(pNameView != NULL); + + return pNameView->layout; + +} + +void +ivug_name_view_set_response_callback(Ivug_NameView *pNameView, FNResponse resp, void *data) +{ + IV_ASSERT(pNameView != NULL); + + if ( pNameView->fnresponse != NULL ) + { + MSG_IMAGEVIEW_WARN("Old response callback is overwritten"); + } + + pNameView->fnresponse = resp; + pNameView->clientdata = data; + +} + +void +ivug_name_view_set_title(Ivug_NameView *pNameView, const char *title) +{ + IV_ASSERT(pNameView!=NULL); + + Elm_Object_Item *navi_it; + + navi_it = elm_naviframe_top_item_get(pNameView->navibar); + + elm_object_item_part_text_set(navi_it, "elm.text.title", title); +} + +void +ivug_name_view_set_entry(Ivug_NameView *pNameView, const char *str) +{ + IV_ASSERT(pNameView!=NULL); + + elm_entry_entry_set(pNameView->entry, str); + + elm_entry_cursor_end_set(pNameView->entry); +} + + diff --git a/main/src/view/ivug-setas-view-callerid.cpp b/main/src/view/ivug-setas-view-callerid.cpp new file mode 100755 index 0000000..f3f22c9 --- /dev/null +++ b/main/src/view/ivug-setas-view-callerid.cpp @@ -0,0 +1,653 @@ +/* + * Copyright 2012 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.tizenopensource.org/license + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include + +#include "ivug-setas-view-callerid.h" +#include "ivug-setas-view.h" + +#include "ivug-selectioninfo.h" + +#include "ivug-image.h" +#include "ivug-drm.h" +#include "EFLUtil.h" +#include "ivug-scissorbox.h" + +#define EDJ_PATH PREFIX"/res/edje/"PACKAGE + +#define SETAS_EDJ_FILE EDJ_PATH"/ivug-setas.edj" + +#define CLICK_TIME_MAX (500) // click time. +#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. +#define CLICK_INTERVAL_TIME 0.15 + +/* it is temp define, because scroll, scroll,anim,end is called earlyer. + So find bound of scissor box again after SETAS_INTERVAL_TIME */ +#define SETAS_INTERVAL_TIME 0.1 +#define SETAS_INTERVAL_TIME_FIRST_LOAD 0.3 + +#define POPUP_ICON_DIRECTORY_PATH IMAGE_PATH"/Popup_icon" + +#define CONTROL_ICON_DIRECTORY_PATH IMAGE_PATH"/01_Control icon" +#define ICON_PATH_SAVE CONTROL_ICON_DIRECTORY_PATH"/T01_controlbar_icon_save.png" +#define ICON_PATH_PREV CONTROL_ICON_DIRECTORY_PATH"/00_winset_btn_prev.png" + +typedef struct { + Evas_Object *layout; + Evas_Object *btn_layout; // ???? + Evas_Object *notify; + Evas_Object *photocam; + + Evas_Object *gesture; + + Elm_Object_Item *btn_ok; + Elm_Object_Item *btn_cancel; + + bool bShowMenu; // Current state for button's visibility + + char *drm_filepath; + + Ecore_Timer *timer; + + struct { + Evas_Object *box; + double ratio; + + Eina_Bool bAspectPreserve; + } crop; + + +} TSetAsData; + +#define SETAS_DATA(obj) \ + (TSetAsData *)evas_object_data_get((Evas_Object *)(obj), "pSetAsData") + + + +static void +_ConvertARGB888toY(unsigned char* pBuf, unsigned char* pGrayBuf, int width, int height) +{ +/* + User should malloc output buffer +*/ + unsigned char* pSrc = (unsigned char*) pBuf; + unsigned char* pDSt = (unsigned char*) pGrayBuf; + + unsigned char* pEnd = pDSt + height * width; + + while (pDSt < pEnd) + { + pSrc++; // throw Alpaha value + + unsigned long r = *pSrc++; + unsigned long g = *pSrc++; + unsigned long b = *pSrc++; + + *pDSt++ = (308 * r + 600 * g + 116 * b) >> 10; + } +} + +static void _put_scissorbox(Evas_Object *obj) +{ + TSetAsData *pSetAsData = SETAS_DATA(obj); + + Evas_Object *image = ivug_image_internal_image_get(pSetAsData->photocam); + + Evas_Coord_Rectangle rect; + + { + int image_w = 0; + int image_h = 0; + double ratio = pSetAsData->crop.ratio; + + ivug_image_image_size_get(pSetAsData->photocam, &image_w, &image_h); // Get original image size. + + int px, py, pw, ph; + ivug_image_region_get(pSetAsData->photocam, &px, &py, &pw, &ph); + + int ix, iy, iw, ih; + + if ( image_w > image_h ) // Landscape image + { + if(ratio > 1.0) // height is larger + { + iw = image_h / (2 * ratio); + ih = image_h / 2; + } + else + { + iw = image_h / 2; + ih = (image_h * ratio) / 2; + } + } + else + { + if(ratio > 1.0) // height is larger + { + iw = image_w / (2 * ratio); + ih = image_w / 2; + } + else + { + iw = image_w / 2; + ih = (image_w * ratio) / 2; + } + } + + ix = (image_w - iw)/2; + iy = (image_h - ih)/2; + + + rect.x = (double)ix * pw / image_w + px; + rect.y = (double)iy * ph / image_h + py; + + rect.w = (double)iw * pw / image_w; + rect.h = (double)ih * ph / image_h; + + MSG_SETAS_WARN("Zoom Put Box in LCD XYWH(%d,%d,%d,%d)", + rect.x, rect.y, rect.w, rect.h); + + ivug_scissorbox_region_set(pSetAsData->crop.box, rect.x, rect.y, rect.w, rect.h); + + } + + ivug_scissorbox_attach(pSetAsData->crop.box, image); // Attach to photocam + +} + +static void +_on_btn_ok_clicked(void *data, Evas_Object *obj, void *event_info) +{ + TSetAsData *pSetAsData = SETAS_DATA(data); + IV_ASSERT(pSetAsData != NULL); + + MSG_SETAS_HIGH("OK button clicked"); +#if 0 + + edje_object_signal_callback_del(_EDJ(pSetAsData->btn_layout), + "setasview,set,clicked", + "", + _on_btn_ok_clicked); +#endif + evas_object_smart_callback_call(pSetAsData->layout, "ok,clicked", NULL); + + if ( pSetAsData->crop.box ) + { + evas_object_del(pSetAsData->crop.box); + pSetAsData->crop.box = NULL; + } + +} + + +static void +_on_btn_cancel_clicked(void *data, Evas_Object *obj, void *event_info) +{ + TSetAsData *pSetAsData = SETAS_DATA(data); + IV_ASSERT(pSetAsData != NULL); + + MSG_SETAS_HIGH("Cancel button clicked"); + evas_object_smart_callback_call(pSetAsData->layout, "cancel,clicked", NULL); + + if ( pSetAsData->crop.box ) + { + evas_object_del(pSetAsData->crop.box); + pSetAsData->crop.box = NULL; + } + +// _ivug_setas_view_remove(pSetAsData); +} + +static Eina_Bool _on_detect_expired(void *data) +{ + ivug_retv_if(!data, ECORE_CALLBACK_CANCEL); + + TSetAsData *pSetAsData = SETAS_DATA(data); + + pSetAsData->timer = NULL; + + _put_scissorbox(pSetAsData->layout); + + elm_object_item_disabled_set(pSetAsData->btn_ok, EINA_FALSE); + + evas_object_smart_callback_call(pSetAsData->layout, "loaded", NULL); + + pSetAsData->notify = ivug_notify_create(pSetAsData->layout, IDS_CALLER_ID_NOTIFY); + + return ECORE_CALLBACK_CANCEL; +} + + +static void +_on_photocam_loaded(void *data, Evas_Object *obj, void *event_info) +{ + TSetAsData *pSetAsData = SETAS_DATA(data); + MSG_SETAS_HIGH("Photocam preloaded"); +#if 0 + typedef enum _Evas_Load_Error + { + EVAS_LOAD_ERROR_NONE = 0, /**< No error on load */ + EVAS_LOAD_ERROR_GENERIC = 1, /**< A non-specific error occurred */ + EVAS_LOAD_ERROR_DOES_NOT_EXIST = 2, /**< File (or file path) does not exist */ + EVAS_LOAD_ERROR_PERMISSION_DENIED = 3, /**< Permission deinied to an existing file (or path) */ + EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED = 4, /**< Allocation of resources failure prevented load */ + EVAS_LOAD_ERROR_CORRUPT_FILE = 5, /**< File corrupt (but was detected as a known format) */ + EVAS_LOAD_ERROR_UNKNOWN_FORMAT = 6 /**< File is not a known format */ + } Evas_Load_Error; /**< Load error you can get from loading of files - see evas_load_error_str() too */ +#endif + +// Evas_Load_Error error = static_cast((int)event_info); + Evas_Load_Error error = evas_object_image_load_error_get(ivug_image_internal_image_get(obj)); + + if ( error != EVAS_LOAD_ERROR_NONE ) + { + MSG_SETAS_ERROR("Error occured during decoding. Error=%d", error); + + if ( error == EVAS_LOAD_ERROR_UNKNOWN_FORMAT ) + { + evas_object_smart_callback_call(pSetAsData->layout, "load,failed", (void *)SETAS_ERROR_TYPE_UNKNOWN_FORMAT); + } + else if ( error == EVAS_LOAD_ERROR_PERMISSION_DENIED ) + { + evas_object_smart_callback_call(pSetAsData->layout, "load,failed", (void *)SETAS_ERROR_TYPE_PERMISSION_DENIED); + } + else + { + evas_object_smart_callback_call(pSetAsData->layout, "load,failed", (void *)SETAS_ERROR_TYPE_INVALID_FILE); + } + + return; + } + +// Remove thumbnail + Evas_Object *object = elm_object_part_content_unset(pSetAsData->layout, "setasview.thumbnail"); + if(object != NULL) + { + evas_object_del(object); + } + + MSG_SETAS_HIGH("Photocam loaded."); + + pSetAsData->timer = ecore_timer_add(0.5, _on_detect_expired, data); +} + + +static void _on_moved(void *data, Evas *e, Evas_Object *obj, void *event_info) +{ +// TSetAsData *pSetAsData = SETAS_DATA(data); + +} + +static void _on_resized(void *data, Evas *e, Evas_Object *obj, void *event_info) +{ + TSetAsData *pSetAsData = SETAS_DATA(data); + /////////////////////////////////////////////////////////////////// + int org_x, org_y, org_w, org_h; + + ivug_image_region_get(pSetAsData->photocam, &org_x, &org_y, &org_w, &org_h); + + if(org_w == 0 || org_h == 0) + return; + + MSG_SETAS_MED("org_x=%d, org_y=%d, org_w=%d, org_h=%d", org_x, org_y, org_w, org_h); + + int org_sx, org_sy, org_sw, org_sh; + ivug_scissorbox_region_get(pSetAsData->crop.box, &org_sx, &org_sy, &org_sw, &org_sh); + + MSG_SETAS_MED("org_sx=%d, org_sy=%d, org_sw=%d, org_sh=%d", org_sx, org_sy, org_sw, org_sh); + + int dx = org_sx-org_x; + int dy = org_sy-org_y; + + int lcd_x, lcd_y, lcd_w, lcd_h; + + evas_object_geometry_get(obj, &lcd_x, &lcd_y, &lcd_w, &lcd_h); + MSG_SETAS_MED("lcd_x=%d, lcd_y=%d, lcd_w=%d, lcd_h=%d", lcd_x, lcd_y, lcd_w, lcd_h); + + int ph, pw; + + int img_w, img_h; + int ext_w, ext_h; + + img_w = org_w; + img_h = org_h; + ext_w = lcd_w; + ext_h = lcd_h; + + ph = (img_h * ext_w) / img_w; + + if (ph > ext_h) + { + pw = (img_w * ext_h) / img_h; + ph = ext_h; + } + else + { + pw = ext_w; + } + + double zoom = 0.0; + + if ( img_w > img_h) + { + zoom = (double)pw / img_w; + } + else + { + zoom = (double)ph / img_h; + } + + int sx, sy, sw, sh; + + sw = org_sw*zoom; + sh = org_sh*zoom; + dx *= zoom; + dy *= zoom; + + sx = (ext_w-img_w*zoom)/2 + dx; + sy = (ext_h-img_h*zoom)/2 + dy; + + ivug_scissorbox_boundary_set(pSetAsData->crop.box, (ext_w-img_w*zoom)/2, (ext_h-img_h*zoom)/2, img_w*zoom, img_h*zoom); + + /////////////////////////////////////////////////////////////////// + + MSG_SETAS_MED("sx=%d, sy=%d, sw=%d, sh=%d", sx, sy, sw, sh); + + ivug_scissorbox_region_set(pSetAsData->crop.box, sx, sy, sw, sh); +} + +static void _on_removed(void *data, Evas *e, Evas_Object *obj, void *event_info) +{ + TSetAsData *pSetAsData = SETAS_DATA(data); + + MSG_SETAS_HIGH("Remoing SetAsData"); + + if(pSetAsData->timer) + { + ecore_timer_del(pSetAsData->timer); + pSetAsData->timer = NULL; + } + + if(pSetAsData->notify) + { + evas_object_del(pSetAsData->notify); + pSetAsData->notify = NULL; + } + + if(pSetAsData->crop.box) + { + evas_object_del(pSetAsData->crop.box); + pSetAsData->crop.box = NULL; + } + + if(pSetAsData->photocam) + { + evas_object_del(pSetAsData->photocam); + pSetAsData->photocam = NULL; + } + + if(pSetAsData->drm_filepath) + { + ivug_remove_file(pSetAsData->drm_filepath); + free(pSetAsData->drm_filepath); + pSetAsData->drm_filepath = NULL; + } + + free(pSetAsData); + +} + +static Evas_Event_Flags _finger_tap_end(void *data , void *event_info) +{ + Elm_Gesture_Taps_Info *p = (Elm_Gesture_Taps_Info *) event_info; + + MSG_SETAS_HIGH("Finger tab end. evt=%d", p->timestamp); + + if ( p->n != 1 ) return EVAS_EVENT_FLAG_NONE; + + TSetAsData *pSetAsData = (TSetAsData *)data; + IV_ASSERT(pSetAsData != NULL); + + if(pSetAsData->bShowMenu) + { + MSG_SETAS_HIGH("Hide"); + elm_win_indicator_mode_set((Evas_Object*)ug_get_window(), ELM_WIN_INDICATOR_HIDE); + evas_object_hide(pSetAsData->notify); + edje_object_signal_emit(_EDJ(pSetAsData->btn_layout), "elm,state,hide", "event"); + } + else + { + MSG_SETAS_HIGH("Show"); + elm_win_indicator_mode_set((Evas_Object*)ug_get_window(), ELM_WIN_INDICATOR_SHOW); + evas_object_show(pSetAsData->notify); + edje_object_signal_emit(_EDJ(pSetAsData->btn_layout), "elm,state,show", "event"); + } + + pSetAsData->bShowMenu = !pSetAsData->bShowMenu; + + return EVAS_EVENT_FLAG_NONE; +} + +void _add_gesture_layer(Evas_Object *parent, TSetAsData *pSetAsData) +{ + IV_ASSERT(pSetAsData != NULL); + + Evas_Object *gesture = pSetAsData->gesture; + + gesture = elm_gesture_layer_add(parent); + elm_gesture_layer_hold_events_set(gesture, EINA_TRUE); + + elm_gesture_layer_cb_set(gesture, ELM_GESTURE_N_TAPS, ELM_GESTURE_STATE_END, _finger_tap_end, (void *)pSetAsData); + + if ( elm_gesture_layer_attach(gesture, pSetAsData->photocam) == EINA_FALSE) + { + MSG_SETAS_ERROR("Cannot attach event rect"); + } + + evas_object_name_set(gesture, "CallerID:Getsture"); +} + +Evas_Object *_ivug_setas_callerid_create_layout(Evas_Object *parent) +{ + TSetAsData *pSetAsData = (TSetAsData *)calloc(1, sizeof(TSetAsData)); + + if ( pSetAsData == NULL ) + { + MSG_SETAS_ERROR("Cannot alloc pSetasData"); + return NULL; + } + + Elm_Object_Item *item[4]; + Evas_Object *controlbar = NULL; + + pSetAsData->layout = ivug_layout_add(parent , SETAS_EDJ_FILE, "setas_view"); + if ( pSetAsData->layout == NULL ) + { + MSG_SETAS_ERROR("Cannot create layout."); + goto error; + } + evas_object_event_callback_add(pSetAsData->layout, EVAS_CALLBACK_MOVE, _on_moved, pSetAsData->layout); + evas_object_event_callback_add(pSetAsData->layout, EVAS_CALLBACK_RESIZE, _on_resized, pSetAsData->layout); + + pSetAsData->crop.box = ivug_scissorbox_add(pSetAsData->layout); + + if ( pSetAsData->crop.box == NULL ) + { + MSG_SETAS_ERROR("Cannot create layout."); + goto error; + } + + evas_object_smart_member_add(pSetAsData->crop.box, pSetAsData->layout); +// Create child + pSetAsData->btn_layout = ivug_layout_add(pSetAsData->layout , SETAS_EDJ_FILE, "setas_view_btn"); + if ( pSetAsData->btn_layout == NULL ) + { + MSG_SETAS_ERROR("Cannot create btn_layout."); + goto error; + } + evas_object_smart_member_add(pSetAsData->btn_layout, pSetAsData->layout); + + + Evas_Object *photocam; + photocam = ivug_image_create(pSetAsData->layout); + ivug_image_animated_set(photocam, EINA_FALSE); // Show first frame only when AGIF + ivug_image_hold_set(photocam , EINA_TRUE); // Disable mouse events + + evas_object_name_set(photocam, "setas_photocam"); + + evas_object_smart_callback_add(photocam, "loaded", _on_photocam_loaded, (void *)pSetAsData->layout); + elm_object_part_content_set(pSetAsData->layout, "setasview.photocam", photocam); + evas_object_show(photocam); + + pSetAsData->photocam = photocam; + + pSetAsData->bShowMenu = true; + _add_gesture_layer(pSetAsData->layout, pSetAsData); + + controlbar = ivug_controlbar_add(pSetAsData->layout, "default"); + + item[0] = elm_toolbar_item_append(controlbar, ICON_PATH_SAVE, NULL, _on_btn_ok_clicked, (void *)pSetAsData->layout); + item[1] = elm_toolbar_item_append(controlbar, NULL, NULL, NULL, NULL); + item[2] = elm_toolbar_item_append(controlbar, NULL, NULL, NULL, NULL); + item[3] = elm_toolbar_item_append(controlbar, ICON_PATH_PREV, NULL, _on_btn_cancel_clicked, (void *)pSetAsData->layout); + + elm_object_item_disabled_set(item[1], EINA_TRUE); + elm_object_item_disabled_set(item[2], EINA_TRUE); + + pSetAsData->btn_layout = ivug_layout_add(pSetAsData->layout , SETAS_EDJ_FILE, "setas_view_btn"); + if ( pSetAsData->btn_layout == NULL ) + { + MSG_SETAS_ERROR("Cannot create btn_layout."); + goto error; + } + + elm_object_part_content_set(pSetAsData->btn_layout, "controlbar", controlbar); + + //Evas_Object *back_btn = ivug_button_add(controlbar, "naviframe/end_btn/default", IDS_BACK, NULL, _on_btn_cancel_clicked, pSetAsData->layout); + + //elm_object_part_content_set(pSetAsData->btn_layout, "elm.swallow.prev_btn", back_btn); + + evas_object_smart_member_add(pSetAsData->btn_layout, pSetAsData->layout); + + pSetAsData->btn_ok = item[0]; + pSetAsData->btn_cancel = item[3]; + elm_object_item_disabled_set(pSetAsData->btn_ok, EINA_TRUE); + + MSG_SETAS_HIGH("Create setas layout"); + + evas_object_data_set( pSetAsData->layout, "pSetAsData", pSetAsData); + evas_object_event_callback_add(pSetAsData->layout, EVAS_CALLBACK_DEL, _on_removed, pSetAsData->layout); + + return pSetAsData->layout; + +error: + if ( pSetAsData->crop.box ) + evas_object_del(pSetAsData->crop.box); + + if ( pSetAsData->btn_layout ) + evas_object_del(pSetAsData->btn_layout); + + if ( pSetAsData->layout ) + evas_object_del(pSetAsData->layout); + + if ( pSetAsData ) + free(pSetAsData); + + return NULL; +} + + +bool _ivug_setas_callerid_load_file(Evas_Object *obj, const char *filepath) +{ + TSetAsData *pSetAsData = SETAS_DATA(obj); + + MSG_SETAS_HIGH("Load image file : %s", filepath); + + Evas_Load_Error error = EVAS_LOAD_ERROR_NONE; + + if(ivug_drm_is_drm_file(filepath)) + { + MSG_SETAS_HIGH("DRM File : %s", filepath); + error = EVAS_LOAD_ERROR_PERMISSION_DENIED; + } + else + { + error = ivug_image_file_set(pSetAsData->photocam, filepath, "noAnim"); + } + + if ( error != EVAS_LOAD_ERROR_NONE ) + { + // TODO : What is good for error handing?????? + MSG_SETAS_ERROR("FileSet Error=%d", error); + + if ( error == EVAS_LOAD_ERROR_UNKNOWN_FORMAT ) + { + evas_object_smart_callback_call(pSetAsData->layout, "load,failed", (void *)SETAS_ERROR_TYPE_UNKNOWN_FORMAT); + return false; + } + else if ( error == EVAS_LOAD_ERROR_PERMISSION_DENIED ) + { + evas_object_smart_callback_call(pSetAsData->layout, "load,failed", (void *)SETAS_ERROR_TYPE_PERMISSION_DENIED); + return false; + } + else + { + evas_object_smart_callback_call(pSetAsData->layout, "load,failed", (void *)SETAS_ERROR_TYPE_INVALID_FILE); + return false; + } + + return false; + } + + return true; +} + +Evas_Object *_ivug_setas_callerid_internal_image_get(Evas_Object *obj) +{ + TSetAsData *pSetAsData = SETAS_DATA(obj); + + MSG_SETAS_HIGH("Internal image get!"); + + return pSetAsData->photocam; +} + +bool _ivug_setas_callerid_select_region_get(Evas_Object *obj, int *x, int *y, int *w, int *h) +{ + TSetAsData *pSetAsData = SETAS_DATA(obj); + + if ( pSetAsData->crop.box == NULL) + { + return false; + } + + ivug_scissorbox_region_get(pSetAsData->crop.box, x, y, w, h); + + return true; +} + + +void _ivug_setas_callerid_aspect_ratio_set(Evas_Object *obj, double ratio) +{ + TSetAsData *pSetAsData = SETAS_DATA(obj); + + pSetAsData->crop.bAspectPreserve = TRUE; + pSetAsData->crop.ratio = ratio; + + ivug_scissorbox_ratio_fix( pSetAsData->crop.box, EINA_TRUE); +} + + + diff --git a/main/src/view/ivug-setas-view-callerid.h b/main/src/view/ivug-setas-view-callerid.h new file mode 100755 index 0000000..fcdb17c --- /dev/null +++ b/main/src/view/ivug-setas-view-callerid.h @@ -0,0 +1,49 @@ +/* + * Copyright 2012 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.tizenopensource.org/license + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __IVUG_SETAS_CALLERID_H__ +#define __IVUG_SETAS_CALLERID_H__ + +#include "ivug-common.h" + +// This functions are used for Crop(AUL) and CallerID(UG) + +#ifdef __cplusplus +extern "C" { +#endif + + +/* + "load,failed" - Image decoding error + "ok,clicked" - Button "OK" clicked + "cancel,clicked" - Button "Cancel" clicked +*/ +Evas_Object *_ivug_setas_callerid_create_layout(Evas_Object *parent); + +bool _ivug_setas_callerid_load_file(Evas_Object *obj, const char *filepath); + +Evas_Object *_ivug_setas_callerid_internal_image_get(Evas_Object *obj); + +bool _ivug_setas_callerid_select_region_get(Evas_Object *obj, int *x, int *y, int *w, int *h); + +void _ivug_setas_callerid_aspect_ratio_set(Evas_Object *obj, double ratio); + +#ifdef __cplusplus +} +#endif + + +#endif //__IVUG_SETAS_CALLERID_H__ \ No newline at end of file diff --git a/main/src/view/ivug-setas-view-wallpaper.cpp b/main/src/view/ivug-setas-view-wallpaper.cpp new file mode 100755 index 0000000..0360f13 --- /dev/null +++ b/main/src/view/ivug-setas-view-wallpaper.cpp @@ -0,0 +1,349 @@ +/* + * Copyright 2012 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.tizenopensource.org/license + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include + +#include "ivug-setas-view-wallpaper.h" +#include "ivug-setas-view.h" + +#include "ivug-image.h" +#include "ivug-drm.h" +#include "EFLUtil.h" + +#define EDJ_PATH PREFIX"/res/edje/"PACKAGE + +#define SETAS_EDJ_FILE EDJ_PATH"/ivug-setas.edj" + +#define CLICK_TIME_MAX (500) // click time. +#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. +#define CLICK_INTERVAL_TIME 0.15 + +/* it is temp define, because scroll, scroll,anim,end is called earlyer. + So find bound of scissor box again after SETAS_INTERVAL_TIME */ +#define SETAS_INTERVAL_TIME 0.1 +#define SETAS_INTERVAL_TIME_FIRST_LOAD 0.3 + +#define POPUP_ICON_DIRECTORY_PATH IMAGE_PATH"/Popup_icon" + +#define CONTROL_ICON_DIRECTORY_PATH IMAGE_PATH"/01_Control icon" +#define ICON_PATH_SAVE CONTROL_ICON_DIRECTORY_PATH"/T01_controlbar_icon_save.png" +#define ICON_PATH_PREV CONTROL_ICON_DIRECTORY_PATH"/00_winset_btn_prev.png" + +typedef struct { + Evas_Object *layout; + Evas_Object *btn_layout; // ???? + Evas_Object *photocam; + + Evas_Object *btn_ok; + Evas_Object *btn_cancel; + + bool bShowMenu; // Current state for button's visibility + + char *drm_filepath; +} TSetAsData; + +#define SETAS_DATA(obj) \ + (TSetAsData *)evas_object_data_get((Evas_Object *)(obj), "pSetAsData") + + +static void +_show_menu(Evas_Object *layout) +{ + IV_ASSERT(layout != NULL); + + +} + +static void +_hide_menu(Evas_Object *layout) +{ + IV_ASSERT(layout != NULL); + +} + + +static void +_on_btn_ok_clicked(void *data, Evas_Object *obj, void *event_info) +{ + TSetAsData *pSetAsData = SETAS_DATA(data); + IV_ASSERT(pSetAsData != NULL); + + MSG_SETAS_HIGH("OK button clicked"); +#if 0 + + edje_object_signal_callback_del(_EDJ(pSetAsData->btn_layout), + "setasview,set,clicked", + "", + _on_btn_ok_clicked); +#endif + + evas_object_smart_callback_call(pSetAsData->layout, "ok,clicked", NULL); +} + + +static void +_on_btn_cancel_clicked(void *data, Evas_Object *obj, void *event_info) +{ + TSetAsData *pSetAsData = SETAS_DATA(data); + IV_ASSERT(pSetAsData != NULL); + + MSG_SETAS_HIGH("Cancel button clicked"); + evas_object_smart_callback_call(pSetAsData->layout, "cancel,clicked", NULL); + +// _ivug_setas_view_remove(pSetAsData); +} + +static void +_on_photocam_loaded(void *data, Evas_Object *obj, void *event_info) +{ + TSetAsData *pSetAsData = SETAS_DATA(data); + MSG_SETAS_HIGH("Photocam preloaded"); +#if 0 + typedef enum _Evas_Load_Error + { + EVAS_LOAD_ERROR_NONE = 0, /**< No error on load */ + EVAS_LOAD_ERROR_GENERIC = 1, /**< A non-specific error occurred */ + EVAS_LOAD_ERROR_DOES_NOT_EXIST = 2, /**< File (or file path) does not exist */ + EVAS_LOAD_ERROR_PERMISSION_DENIED = 3, /**< Permission deinied to an existing file (or path) */ + EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED = 4, /**< Allocation of resources failure prevented load */ + EVAS_LOAD_ERROR_CORRUPT_FILE = 5, /**< File corrupt (but was detected as a known format) */ + EVAS_LOAD_ERROR_UNKNOWN_FORMAT = 6 /**< File is not a known format */ + } Evas_Load_Error; /**< Load error you can get from loading of files - see evas_load_error_str() too */ +#endif + + Evas_Load_Error error = static_cast((int)event_info); + + if ( error != EVAS_LOAD_ERROR_NONE ) + { + MSG_SETAS_ERROR("Error occured during decoding. Error=%d", error); + + if ( error == EVAS_LOAD_ERROR_UNKNOWN_FORMAT ) + { + evas_object_smart_callback_call(pSetAsData->layout, "load,failed", (void *)SETAS_ERROR_TYPE_UNKNOWN_FORMAT); + } + else if ( error == EVAS_LOAD_ERROR_PERMISSION_DENIED ) + { + evas_object_smart_callback_call(pSetAsData->layout, "load,failed", (void *)SETAS_ERROR_TYPE_PERMISSION_DENIED); + } + else + { + evas_object_smart_callback_call(pSetAsData->layout, "load,failed", (void *)SETAS_ERROR_TYPE_INVALID_FILE); + } + + return; + } + +// Remove thumbnail + Evas_Object *object = elm_object_part_content_unset(pSetAsData->layout, "setasview.thumbnail"); + if(object != NULL) + { + evas_object_del(object); + } + + MSG_SETAS_HIGH("Photocam loaded."); + elm_object_disabled_set(pSetAsData->btn_ok, EINA_FALSE); + + + evas_object_smart_callback_call(pSetAsData->layout, "loaded", NULL); + + +} + + +static void _on_moved(void *data, Evas *e, Evas_Object *obj, void *event_info) +{ +// TSetAsData *pSetAsData = SETAS_DATA(data); + +} + +static void _on_resized(void *data, Evas *e, Evas_Object *obj, void *event_info) +{ +// TSetAsData *pSetAsData = SETAS_DATA(data); + +} + +static void _on_removed(void *data, Evas *e, Evas_Object *obj, void *event_info) +{ + TSetAsData *pSetAsData = SETAS_DATA(data); + + MSG_SETAS_HIGH("Remoing SetAsData"); + + if(pSetAsData->photocam) + { + evas_object_del(pSetAsData->photocam); + pSetAsData->photocam = NULL; + } + + if(pSetAsData->drm_filepath) + { + ivug_remove_file(pSetAsData->drm_filepath); + free(pSetAsData->drm_filepath); + pSetAsData->drm_filepath = NULL; + } + + free(pSetAsData); + +} + + +static void +_on_bg_clicked(void *data, Evas_Object* obj, const char *emission, const char *source ) +{ + MSG_SETAS_HIGH("BG Clicked"); + + TSetAsData *pSetAsData = SETAS_DATA(data); + + MSG_SETAS_HIGH("Bar flag is = %d", pSetAsData->bShowMenu); + if(pSetAsData->bShowMenu == true) + { + pSetAsData->bShowMenu = false; + _hide_menu(pSetAsData->btn_layout); + } + else + { + pSetAsData->bShowMenu = true; + _show_menu(pSetAsData->btn_layout); + } +} + +Evas_Object *_ivug_setas_create_layout(Evas_Object *parent) +{ + TSetAsData *pSetAsData = (TSetAsData *)calloc(1, sizeof(TSetAsData)); + + if ( pSetAsData == NULL ) + { + MSG_SETAS_ERROR("Cannot alloc pSetasData"); + return NULL; + } + + pSetAsData->layout = ivug_layout_add(parent , SETAS_EDJ_FILE, "setas_view"); + if ( pSetAsData->layout == NULL ) + { + MSG_SETAS_ERROR("Cannot create layout."); + free(pSetAsData); + return NULL; + } + evas_object_event_callback_add(pSetAsData->layout, EVAS_CALLBACK_MOVE, _on_moved, pSetAsData->layout); + evas_object_event_callback_add(pSetAsData->layout, EVAS_CALLBACK_RESIZE, _on_resized, pSetAsData->layout); + + Evas_Object *photocam; + photocam = ivug_image_create(pSetAsData->layout); + ivug_image_animated_set(photocam, EINA_FALSE); // Show first frame only when AGIF + evas_object_name_set(photocam, "setas_photocam"); + + evas_object_smart_callback_add(photocam, "loaded", _on_photocam_loaded, (void *)pSetAsData->layout); + elm_object_part_content_set(pSetAsData->layout, "setasview.photocam", photocam); + evas_object_show(photocam); + + pSetAsData->photocam = photocam; + + Evas_Object *controlbar = ivug_controlbar_add(pSetAsData->layout, "default"); + Elm_Object_Item *item[4]; + + item[0] = elm_toolbar_item_append(controlbar, ICON_PATH_SAVE, NULL, _on_btn_ok_clicked, (void *)pSetAsData->layout); + item[1] = elm_toolbar_item_append(controlbar, NULL, NULL, NULL, NULL); + item[2] = elm_toolbar_item_append(controlbar, NULL, NULL, NULL, NULL); + item[3] = elm_toolbar_item_append(controlbar, ICON_PATH_PREV, NULL, _on_btn_cancel_clicked, (void *)pSetAsData->layout); + + elm_object_item_disabled_set(item[1], EINA_TRUE); + elm_object_item_disabled_set(item[2], EINA_TRUE); + + pSetAsData->btn_layout = ivug_layout_add(pSetAsData->layout , SETAS_EDJ_FILE, "setas_view_btn"); + if ( pSetAsData->btn_layout == NULL ) + { + MSG_SETAS_ERROR("Cannot create btn_layout."); + evas_object_del(pSetAsData->layout); + free(pSetAsData); + return NULL; + } + + elm_object_part_content_set(pSetAsData->btn_layout, "controlbar", controlbar); + + //Evas_Object *back_btn = ivug_button_add(controlbar, "naviframe/end_btn/default", IDS_BACK, NULL, _on_btn_cancel_clicked, pSetAsData->layout); + + //elm_object_part_content_set(pSetAsData->btn_layout, "elm.swallow.prev_btn", back_btn); + + evas_object_smart_member_add(pSetAsData->btn_layout, pSetAsData->layout); + + edje_object_signal_callback_add(_EDJ(pSetAsData->layout), + "setasview,bg,clicked", "edc", + _on_bg_clicked, + (void *)pSetAsData->layout); + + pSetAsData->bShowMenu = true; + elm_object_disabled_set(pSetAsData->btn_ok, EINA_TRUE); + + MSG_SETAS_HIGH("Create setas layout"); + + evas_object_data_set(pSetAsData->layout, "pSetAsData", pSetAsData); + evas_object_event_callback_add(pSetAsData->layout, EVAS_CALLBACK_DEL, _on_removed, pSetAsData->layout); + + return pSetAsData->layout; +} + +bool _ivug_setas_load_file(Evas_Object *obj, const char *filepath) +{ + TSetAsData *pSetAsData = SETAS_DATA(obj); + + MSG_SETAS_HIGH("Load image file : %s", filepath); + + Evas_Load_Error error = EVAS_LOAD_ERROR_NONE; + + if(ivug_drm_is_drm_file(filepath)) + { + MSG_SETAS_HIGH("DRM File : %s", filepath); + error = EVAS_LOAD_ERROR_PERMISSION_DENIED; + } + else + { + error = ivug_image_file_set(pSetAsData->photocam, filepath, "noAnim"); + } + + if ( error != EVAS_LOAD_ERROR_NONE ) + { + // TODO : What is good for error handing?????? + MSG_SETAS_ERROR("FileSet Error=%d", error); + + if ( error == EVAS_LOAD_ERROR_UNKNOWN_FORMAT ) + { + evas_object_smart_callback_call(pSetAsData->layout, "load,failed", (void *)SETAS_ERROR_TYPE_UNKNOWN_FORMAT); + return false; + } + else if ( error == EVAS_LOAD_ERROR_PERMISSION_DENIED ) + { + evas_object_smart_callback_call(pSetAsData->layout, "load,failed", (void *)SETAS_ERROR_TYPE_PERMISSION_DENIED); + return false; + } + else + { + evas_object_smart_callback_call(pSetAsData->layout, "load,failed", (void *)SETAS_ERROR_TYPE_INVALID_FILE); + return false; + } + + return false; + } + + return true; +} + +Evas_Object *_ivug_setas_internal_image_get(Evas_Object *obj) +{ + TSetAsData *pSetAsData = SETAS_DATA(obj); + + return pSetAsData->photocam; +} + + diff --git a/main/src/view/ivug-setas-view-wallpaper.h b/main/src/view/ivug-setas-view-wallpaper.h new file mode 100755 index 0000000..090a7fa --- /dev/null +++ b/main/src/view/ivug-setas-view-wallpaper.h @@ -0,0 +1,43 @@ +/* + * Copyright 2012 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.tizenopensource.org/license + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __IVUG_SETAS_WALLPAPER_H__ +#define __IVUG_SETAS_WALLPAPER_H__ + +#include "ivug-common.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +/* + "load,failed" - Image decoding error + "ok,clicked" - Button "OK" clicked + "cancel,clicked" - Button "Cancel" clicked +*/ +Evas_Object *_ivug_setas_create_layout(Evas_Object *parent); + +bool _ivug_setas_load_file(Evas_Object *obj, const char *filepath); + +Evas_Object *_ivug_setas_internal_image_get(Evas_Object *obj); + +#ifdef __cplusplus +} +#endif + + +#endif //__IVUG_SETAS_WALLPAPER_H__ \ No newline at end of file diff --git a/medialist/CMakeLists.txt b/medialist/CMakeLists.txt new file mode 100755 index 0000000..810ad7d --- /dev/null +++ b/medialist/CMakeLists.txt @@ -0,0 +1,50 @@ +CMAKE_MINIMUM_REQUIRED(VERSION 2.6) +PROJECT(ivug_medialist C CXX) + +SET(PREFIX ${CMAKE_INSTALL_PREFIX}) +SET(VERSION 0.1.0) + +INCLUDE_DIRECTORIES( + include + src + ${CMAKE_SOURCE_DIR}/include + ${IVUG_SOURCE_COMMON_DIR}/include + ${IVUG_SOURCE_FEATURE_DIR}/include +) + +SET(SRCS + src/ivug-medialist.c + src/ivug-mediadata.c + src/ivug-data-list.c +) + +MESSAGE("Checking " ${PROJECT_NAME} ) + +INCLUDE(FindPkgConfig) +pkg_check_modules(${PROJECT_NAME}_pkgs REQUIRED + elementary + dlog + ui-gadget-1 + eina + ecore + capi-content-media-content +) + +FOREACH(flag ${${PROJECT_NAME}_pkgs_CFLAGS}) + SET(EXTRA_CXXFLAGS "${EXTRA_CXXFLAGS} ${flag}") +ENDFOREACH(flag) + +SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${EXTRA_CXXFLAGS} -Wall") +SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${CMAKE_CXX_FLAGS}") + +ADD_DEFINITIONS("-DPREFIX=\"${CMAKE_INSTALL_PREFIX}\"") + +ADD_LIBRARY(${PROJECT_NAME} SHARED ${SRCS}) +SET_TARGET_PROPERTIES(${PROJECT_NAME} PROPERTIES SOVERSION ${VERSION} ) +SET_TARGET_PROPERTIES(${PROJECT_NAME} PROPERTIES INSTALL_RPATH ${CMAKE_INSTALL_PREFIX}/lib) + +TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${${PROJECT_NAME}_pkgs_LDFLAGS} +ivug_common ivug_feature) + +INSTALL(TARGETS ${PROJECT_NAME} DESTINATION lib) + diff --git a/medialist/include/ivug-media.h b/medialist/include/ivug-media.h new file mode 100755 index 0000000..6d65b2f --- /dev/null +++ b/medialist/include/ivug-media.h @@ -0,0 +1,74 @@ +/* + * Copyright 2012 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.tizenopensource.org/license + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __IVUG_MEDIA_H__ +#define __IVUG_MEDIA_H__ + +#include "ivug-datatypes.h" +#include "ivug-db.h" + +#include +#include + +//slide type +typedef enum { + SLIDE_TYPE_NONE = 0x00, + SLIDE_TYPE_IMAGE, + SLIDE_TYPE_VIDEO, + SLIDE_TYPE_STREAMING, + SLIDE_TYPE_UNKNOWN, // File is exists but it's type is unknown. +} Media_Type; + +// Meida_Data can be one in File, DB, PTP, DLNA + +/* + This struct represents data for slide. + thumbnail_path is slide's thumbnail image path. + fileurl is saved item in media service. and drm. + filepath is local file path. if fileurl is http://.../test.jpg, filepath is NULL, when complete download filepath change to saved local file path. +*/ +typedef struct { + media_handle m_hadle; + + int index; + +//Data + Media_Type slide_type; //image, video + bool bIsDRMContent; + + UUID mediaID; // Unique Media ID + + char* thumbnail_path; // thumbnail image file path. + char* fileurl; // file url. + char* filepath; // file path in local file system. + char* drm_filepath; +} Media_Data; + + +#ifdef __cplusplus +extern "C" { +#endif + +bool ivug_mediadata_delete(Media_Data * mdata); + +bool ivug_mediadata_free(Media_Data * mdata); + + +#ifdef __cplusplus +} +#endif + +#endif // __IVUG_MEDIA_H__ diff --git a/medialist/include/ivug-medialist.h b/medialist/include/ivug-medialist.h new file mode 100755 index 0000000..aa89b11 --- /dev/null +++ b/medialist/include/ivug-medialist.h @@ -0,0 +1,101 @@ +/* + * Copyright 2012 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.tizenopensource.org/license + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __IVUG_MEDIALIST_H__ +#define __IVUG_MEDIALIST_H__ + +#include "ivug-datatypes.h" +#include "ivug-media.h" + +#include "ivug-define.h" + +typedef void *Media_Item; + +typedef enum { + FILTER_DB, +}filter_type_e; + +typedef struct _DB_Filter{ + + union { /* CAUTION : Union type. check view_by variable before free()*/ + char *file_path; + struct { + double max_longitude; + double min_longitude; + double max_latitude; + double min_latitude; + } place; + + UUID album_id; // Cluster id + }; + +} DB_Filter; + +typedef struct _Filter_struct{ + filter_type_e type; + ivug_view_by view_by; + ivug_media_type media_type; + ivug_sort_type sort_type; + int index; + + DB_Filter *db_filter; +}Filter_struct; + + +/* Opaque pointer for media list. */ +typedef void *Media_List; + +#ifdef __cplusplus +extern "C" { +#endif + +Media_List * ivug_medialist_create(); + +Media_Item * ivug_medialist_find_item_by_filename(Media_List *mList, const char* filepath); + +Media_Item *ivug_medialist_load(Media_List *mList, const Filter_struct *filter); + +void ivug_medialist_del(Media_List *mList); + +/* + return total count +*/ +int ivug_medialist_get_count(Media_List *mList); + +int ivug_medialist_get_index(Media_List *mList, Media_Item *item); + + +Media_Item *ivug_medialist_get_first(Media_List *mList); +Media_Item *ivug_medialist_get_last(Media_List *mList); + +Media_Item *ivug_medialist_get_next(Media_List *mList, Media_Item *item); +Media_Item *ivug_medialist_get_prev(Media_List *mList, Media_Item *item); + +void ivug_medialist_delete_item(Media_List *mList, Media_Item *item); + +Media_Data *ivug_medialist_get_data(Media_Item *item); + +Media_Item *ivug_medialist_get_random_item(Media_List *mList); +Media_Item *ivug_medialist_get_shuffle_item(Media_List *mList, Media_Item *item); + +Media_Item *ivug_medialist_find_item_by_index(Media_List *mList, int index); + +#ifdef __cplusplus +} +#endif + +#endif //__IVUG_MEDIALIST_H__ + diff --git a/medialist/src/ivug-data-list.c b/medialist/src/ivug-data-list.c new file mode 100755 index 0000000..71fface --- /dev/null +++ b/medialist/src/ivug-data-list.c @@ -0,0 +1,273 @@ +/* + * Copyright 2012 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.tizenopensource.org/license + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "ivug-data-list.h" +#include "ivug-uuid.h" + +#include "ivug-debug.h" +#include "ivug-media.h" +#include "ivug-mediadata.h" +#include "ivug-medialist.h" + +#include "ivug-db.h" + +#include + +#include + +static char *_strerror_db(int error) +{ + switch(error) + { + case MEDIA_CONTENT_ERROR_INVALID_PARAMETER: + return "Invalid parameter"; + case MEDIA_CONTENT_ERROR_OUT_OF_MEMORY : + return "Out of memory"; + case MEDIA_CONTENT_ERROR_DB_FAILED : + return "DB operation failed"; + default: + { + static char buf[40]; + sprintf(buf, "Error Code=%d", error); + return buf; + } + + } +} + +//Eina List Function. + +static bool +_ivug_list_media_item_cb(media_info_h item, void *user_data) +{ + IV_ASSERT(user_data != NULL); + + media_info_h media = NULL; + media_info_clone(&media, item); + + Eina_List **list = (Eina_List **)user_data; + *list = eina_list_append(*list, media); + + return true; +} + + +Eina_List * +ivug_list_load_DB_items(const Filter_struct *filter, int stp, int endp) +{ + IV_ASSERT(filter != NULL); + + DB_Filter *db_filter = filter->db_filter; + char *string = NULL; + + if (filter->view_by == IVUG_VIEW_BY_FILE) + { + Eina_List *list = NULL; + Media_Data *mData = ivug_alloc_mediadata_from_filepath(db_filter->file_path); + + list = eina_list_append(list, mData); + return list; + } + + filter_handle media_filter = NULL; + ivug_db_create_filter(&media_filter); + + if(filter->view_by == IVUG_VIEW_BY_PLACES) + { + string = calloc(1, sizeof(char)*IVUG_MAX_CONDITION_LEN); + snprintf(string, IVUG_MAX_CONDITION_LEN, + "(MEDIA_LONGITUDE >= %f AND MEDIA_LONGITUDE <= %f AND MEDIA_LATITUDE >= %f AND MEDIA_LATITUDE <= %f)", + db_filter->place.min_longitude, db_filter->place.max_longitude, + db_filter->place.min_latitude, db_filter->place.max_latitude); + } + ivug_db_set_filter(media_filter, filter->view_by, filter->media_type, string); + + ivug_db_set_filter_offset(media_filter, stp, endp); + + int ret = MEDIA_CONTENT_ERROR_NONE; + + Eina_List *item_list = NULL; + + switch(filter->view_by) + { + case IVUG_VIEW_BY_FOLDER: + ret = media_folder_foreach_media_from_db(db_filter->album_id, + media_filter, _ivug_list_media_item_cb, &item_list); + break; + + case IVUG_VIEW_BY_ALL: + ret = media_info_foreach_media_from_db(media_filter, _ivug_list_media_item_cb, &item_list); + break; + + case IVUG_VIEW_BY_FAVORITES: + ret = media_info_foreach_media_from_db(media_filter, _ivug_list_media_item_cb, &item_list); + break; + + case IVUG_VIEW_BY_PLACES: + ret = media_info_foreach_media_from_db(media_filter, _ivug_list_media_item_cb, &item_list); + break; + + default: + MSG_SDATA_FATAL("Invalid View By=%d", filter->view_by); + return NULL; + } + + ivug_db_destroy_filter(media_filter); + + if ( ret != MEDIA_CONTENT_ERROR_NONE ) + { + MSG_SDATA_ERROR("[%s] Error=%d VieBy=%d", __func__, ret, filter->view_by); + return NULL; + } + +// Creating media_list. + Eina_List *slide_list = NULL; + + Eina_List *item; + media_info_h mitem = NULL; + + Media_Data *mdata = NULL; + + int i = 0; + + EINA_LIST_FOREACH(item_list, item, mitem) + { + mdata = ivug_alloc_mediadata_from_media_handle(mitem); + mdata->index = i + stp; + + i++; + + IV_ASSERT(mdata != NULL); + + MSG_SDATA_LOW("Add Mdata. Mdata=0x%08x %s", mdata, mdata->filepath); + slide_list = eina_list_append(slide_list, mdata); + } + + EINA_LIST_FREE(item_list, mitem) + { + media_info_destroy(mitem); + } + + MSG_SDATA_HIGH("Item header=0x%08x Item loaded(%d~%d)", slide_list, stp, endp); + + return slide_list; +} + +int ivug_list_get_item_cnt(const Filter_struct *filter) +{ + filter_h media_filter = NULL; + + int ret = MEDIA_CONTENT_ERROR_NONE; + + int count = 0; + + char *string = NULL; + + DB_Filter *db_filter = filter->db_filter; + + ivug_db_create_filter((filter_handle*)&media_filter); + if(filter->view_by == IVUG_VIEW_BY_PLACES) + { + string = calloc(1, sizeof(char)*IVUG_MAX_CONDITION_LEN); + snprintf(string, IVUG_MAX_CONDITION_LEN, + "(MEDIA_LONGITUDE >= %f AND MEDIA_LONGITUDE <= %f AND MEDIA_LATITUDE >= %f AND MEDIA_LATITUDE <= %f)", + db_filter->place.min_longitude, db_filter->place.max_longitude, + db_filter->place.min_latitude, db_filter->place.max_latitude); + } + ivug_db_set_filter(media_filter, filter->view_by, filter->media_type, string); + + switch(filter->view_by) + { + case IVUG_VIEW_BY_ALL: + ret = media_info_get_media_count_from_db(media_filter, &count); + if(ret != MEDIA_CONTENT_ERROR_NONE) + { + MSG_SDATA_ERROR("media_info_get_media_count_from_db is failed, err = %s", _strerror_db(ret)); + goto GET_COUNT_ERROR; + } + MSG_SDATA_HIGH("IVUG_VIEW_BY_ALL. MediaType=%d Count=%d", filter->media_type, count); + break; + case IVUG_VIEW_BY_PLACES: + ret = media_info_get_media_count_from_db(media_filter, &count); + if(ret != MEDIA_CONTENT_ERROR_NONE) + { + MSG_SDATA_ERROR("media_info_get_media_count_from_db is failed, err = %s", _strerror_db(ret)); + goto GET_COUNT_ERROR; + } + MSG_SDATA_HIGH("IVUG_VIEW_BY_PLACES. Count=%d", count); + break; + case IVUG_VIEW_BY_FOLDER: + if(db_filter->album_id == NULL) + { + MSG_SDATA_ERROR("album_id is NULL"); + goto GET_COUNT_ERROR; + } + ret = media_folder_get_media_count_from_db(db_filter->album_id, media_filter, &count); + if(ret != MEDIA_CONTENT_ERROR_NONE) + { + MSG_SDATA_ERROR("media_folder_get_media_count_from_db is failed, err = %s", _strerror_db(ret)); + goto GET_COUNT_ERROR; + } + MSG_SDATA_HIGH("IVUG_VIEW_BY_FOLDER. Count=%d", count); + break; + case IVUG_VIEW_BY_FAVORITES: + ret = media_info_get_media_count_from_db(media_filter, &count); + if(ret != MEDIA_CONTENT_ERROR_NONE) + { + MSG_SDATA_ERROR("media_info_get_media_count_from_db is failed, err = %s", _strerror_db(ret)); + goto GET_COUNT_ERROR; + } + MSG_SDATA_HIGH("IVUG_VIEW_BY_FAVORITES. Count=%d", count); + break; + case IVUG_VIEW_BY_FILE: + count = 1; // item count is always 1 when by file + break; + default: + MSG_SDATA_ERROR("Unhandled view_by : %d", filter->view_by); + goto GET_COUNT_ERROR; + break; + } + + MSG_SDATA_HIGH("ivug_db_get_count success, count = %d", count); + + ivug_db_destroy_filter(media_filter); + return count; + +GET_COUNT_ERROR: + MSG_SDATA_ERROR("ivug_db_get_count FAILED"); + + ivug_db_destroy_filter(media_filter); + return -1; +} + +void ivug_list_delete_items(Eina_List *items) +{ + Media_Data* mdata; + + if ( items == NULL ) + { + MSG_SDATA_HIGH("Item list is NULL."); + return; + } + + MSG_SDATA_HIGH("Removing items. Count=%d", eina_list_count(items)); + + EINA_LIST_FREE(items, mdata) + { + ivug_free_mediadata(mdata); + } +} + diff --git a/medialist/src/ivug-data-list.h b/medialist/src/ivug-data-list.h new file mode 100755 index 0000000..94fd945 --- /dev/null +++ b/medialist/src/ivug-data-list.h @@ -0,0 +1,41 @@ +/* + * Copyright 2012 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.tizenopensource.org/license + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __IVUG_DATA_LIST_H__ +#define __IVUG_DATA_LIST_H__ + +#include "ivug-medialist.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* + stp/endp is botn -1 when want to retrieve all items. +*/ +Eina_List *ivug_list_load_DB_items(const Filter_struct *filter, int stp, int endp); + +int ivug_list_get_item_cnt(const Filter_struct *filter); + +void ivug_list_delete_items(Eina_List *items); + +#ifdef __cplusplus +} +#endif + +#endif + + diff --git a/medialist/src/ivug-mediadata.c b/medialist/src/ivug-mediadata.c new file mode 100755 index 0000000..b593bea --- /dev/null +++ b/medialist/src/ivug-mediadata.c @@ -0,0 +1,380 @@ +/* + * Copyright 2012 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.tizenopensource.org/license + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "ivug-define.h" +#include "ivug-datatypes.h" +#include "ivug-uuid.h" +#include "ivug-debug.h" +#include "ivug-mediadata.h" +#include "ivug-util.h" +#include "ivug-drm.h" +#include "ivug-file-info.h" + +#include "ivug-db.h" + +#include + +#define IMAGE_PATH PREFIX"/res/images/"PACKAGE +#define DEFAULT_THUMBNAIL_PATH IMAGE_PATH"/T01_Nocontents_broken.png" + +static char *_strerror_db(int error) +{ + switch(error) + { + case MEDIA_CONTENT_ERROR_INVALID_PARAMETER: + return "Invalid parameter"; + case MEDIA_CONTENT_ERROR_OUT_OF_MEMORY : + return "Out of memory"; + case MEDIA_CONTENT_ERROR_DB_FAILED : + return "DB operation failed"; + default: + { + static char buf[40]; + sprintf(buf, "Error Code=%d", error); + return buf; + } + + } +} + +Media_Data *ivug_alloc_mediadata_from_media_handle(media_handle media) +{ + IV_ASSERT(media != NULL); + + Media_Data * mdata = NULL; + mdata = (Media_Data *) calloc(1, sizeof(Media_Data)); + if (mdata == NULL) + { + MSG_SDATA_ERROR("Cannot allocate memory"); + return NULL; + } + + media_info_h item = (media_info_h)media; + + int ret = media_info_clone((media_info_h*)&(mdata->m_hadle), item); + if(ret != MEDIA_CONTENT_ERROR_NONE) + { + MSG_SDATA_ERROR("media_info_foreach_media_from_db is failed, err = %s", _strerror_db(ret)); + goto ALLOC_MHANDLE_ERROR; + } + + char *uuid = NULL; + + ret = media_info_get_media_id(item, &uuid); + if(ret != MEDIA_CONTENT_ERROR_NONE) + { + MSG_SDATA_ERROR("media_info_foreach_media_from_db is failed, err = %s", _strerror_db(ret)); + goto ALLOC_MHANDLE_ERROR; + } + mdata->mediaID = uuid_assign(uuid); + free(uuid); + + //file url + ret = media_info_get_file_path(item, &(mdata->fileurl)); + if(ret != MEDIA_CONTENT_ERROR_NONE) + { + MSG_SDATA_ERROR("media_info_foreach_media_from_db is failed, err = %s", _strerror_db(ret)); + goto ALLOC_MHANDLE_ERROR; + } + if (mdata->fileurl == NULL) + { + goto ALLOC_MHANDLE_ERROR; + } + + ret = media_info_get_thumbnail_path(item, &(mdata->thumbnail_path)); + if(ret != MEDIA_CONTENT_ERROR_NONE) + { + MSG_SDATA_ERROR("media_info_foreach_media_from_db is failed, err = %s", _strerror_db(ret)); + goto ALLOC_MHANDLE_ERROR; + } + if(mdata->thumbnail_path == NULL) + { + mdata->thumbnail_path = strdup(DEFAULT_THUMBNAIL_PATH); + } + + ret = media_info_is_drm(item, &(mdata->bIsDRMContent)); + if(ret != MEDIA_CONTENT_ERROR_NONE) + { + MSG_SDATA_ERROR("media_info_foreach_media_from_db is failed, err = %s", _strerror_db(ret)); + goto ALLOC_MHANDLE_ERROR; + } + + media_content_type_e media_type = 0; + ret = media_info_get_media_type(item, &media_type); + if(ret != MEDIA_CONTENT_ERROR_NONE) + { + MSG_SDATA_ERROR("media_info_foreach_media_from_db is failed, err = %s", _strerror_db(ret)); + goto ALLOC_MHANDLE_ERROR; + } + + if(media_type == MEDIA_CONTENT_TYPE_IMAGE) + { + MSG_SDATA_MED("Local image : %s. %s", uuid_getchar( mdata->mediaID ), mdata->fileurl); + + mdata->slide_type = SLIDE_TYPE_IMAGE; + mdata->filepath = strdup(mdata->fileurl); + + if (ivug_drm_is_drm_file(mdata->filepath) == EINA_TRUE) + { + mdata->bIsDRMContent = EINA_TRUE; + } + + } + else if(media_type == MEDIA_CONTENT_TYPE_VIDEO) + { + MSG_SDATA_MED("Local video : %s. %s", uuid_getchar(mdata->mediaID), mdata->fileurl); + + mdata->slide_type = SLIDE_TYPE_VIDEO; + mdata->filepath = strdup(mdata->fileurl); + + if (ivug_drm_is_drm_file(mdata->filepath) == EINA_TRUE) + { + mdata->bIsDRMContent = EINA_TRUE; + } + + } + + return mdata; + +ALLOC_MHANDLE_ERROR: + if(mdata) + { + ivug_free_mediadata(mdata); + } + return NULL; +} + +Media_Data *ivug_alloc_mediadata_from_filepath(const char *filepath) +{ + IV_ASSERT(filepath != NULL); + + Media_Data * mdata = NULL; + + media_handle m_handle = ivug_db_get_file_handle(filepath); + if(m_handle) + { + mdata = ivug_alloc_mediadata_from_media_handle(m_handle); + if(mdata != NULL) + { + MSG_SDATA_HIGH("File path founded in DB."); + return mdata; + } + } + // Some file does not have media handle ex) USB host, Not inserted in DB yet + + MSG_SDATA_WARN("Cannot find in DB."); + + mdata = (Media_Data *) calloc(1, sizeof(Media_Data)); + if (mdata == NULL) + { + MSG_SDATA_ERROR("Cannot allocate memory"); + return NULL; + } + mdata->mediaID = INVALID_UUID; //copy id WMitem + + if (ivug_drm_is_drm_file(filepath) == EINA_TRUE) + { + mdata->bIsDRMContent = true; + } + char *mime_type = NULL; + mime_type = ivug_fileinfo_get_mime_type(filepath); + if (mime_type == NULL) + { + MSG_SDATA_WARN("file path is not vaild = %s", filepath); + mdata->slide_type = SLIDE_TYPE_UNKNOWN; + mdata->fileurl = NULL; + mdata->filepath = NULL; + return mdata; + } + + Media_Type slide_type = SLIDE_TYPE_NONE; + //image + if (strncmp(mime_type, "image/", strlen("image/")) == 0) + { + slide_type = SLIDE_TYPE_IMAGE; + } + else if (strncmp(mime_type, "video/", strlen("video/")) == 0) + { + slide_type = SLIDE_TYPE_VIDEO; + } + else + { + slide_type = SLIDE_TYPE_NONE; + } + MSG_SDATA_HIGH("File=%s Mime=%s", filepath, mime_type); + free(mime_type); //free strdup + if (slide_type == SLIDE_TYPE_IMAGE) + { + mdata->slide_type = SLIDE_TYPE_IMAGE; + mdata->fileurl = strdup(filepath); + if (mdata->fileurl == NULL) + { + MSG_SDATA_ERROR("strdup return NULL"); + goto ERROR; + } + mdata->filepath = strdup(filepath); + if (mdata->filepath == NULL) + { + MSG_SDATA_ERROR("strdup return NULL"); + free(mdata->fileurl); + goto ERROR; + } + } + else if (slide_type == SLIDE_TYPE_VIDEO) + { + mdata->slide_type = SLIDE_TYPE_VIDEO; + mdata->fileurl = strdup(filepath); + if (mdata->fileurl == NULL) + { + MSG_SDATA_ERROR("strdup return NULL"); + goto ERROR; + } + mdata->filepath = strdup(filepath); + if (mdata->filepath == NULL) + { + MSG_SDATA_ERROR("strdup return NULL"); + free(mdata->fileurl); + goto ERROR; + } + } + else + { + MSG_SDATA_WARN("file path is not vaild = %s", filepath); + mdata->slide_type = SLIDE_TYPE_UNKNOWN; + mdata->fileurl = NULL; + mdata->filepath = NULL; + } + return mdata; +ERROR: + if (mdata) + { + ivug_free_mediadata(mdata); + } + return NULL; +} + +void ivug_free_mediadata(Media_Data * mdata) +{ + IV_ASSERT(mdata != NULL); + +#ifdef USE_NEW_DB_API + if(mdata->m_hadle) + { + media_info_destroy(mdata->m_hadle); + mdata->m_hadle = NULL; + } +#endif + + uuid_free(mdata->mediaID); + + //file path + if (mdata->filepath) + { + //IVUG_DEBUG_MSG("filepath =%s", sd->filepath); + free(mdata->filepath); + mdata->filepath = NULL; + } + + //file url + if (mdata->fileurl) + { + MSG_SDATA_MED("Remove media data. %s", mdata->fileurl); + free(mdata->fileurl); + mdata->fileurl = NULL; + } + + if (mdata->thumbnail_path) + { + free(mdata->thumbnail_path); + mdata->thumbnail_path = NULL; + } + + if (mdata->drm_filepath) + { + if ( ivug_remove_file(mdata->drm_filepath) == false) + { + MSG_SDATA_ERROR("Cannot delete drm file : %s", mdata->drm_filepath); + // Go though + } + + free(mdata->drm_filepath); + mdata->drm_filepath = NULL; + } + + free(mdata); +} + +bool ivug_mediadata_delete(Media_Data * mdata) +{ + IV_ASSERT(mdata != NULL); + + if (uuid_is_valid(mdata->mediaID) == true ) + { + int ret = media_info_delete_from_db(mdata->mediaID); + if (ret == MEDIA_CONTENT_ERROR_NONE) + { + if (mdata->filepath) + { + MSG_SDATA_HIGH("File removed. %s", mdata->filepath); + if (ivug_remove_file(mdata->filepath) == false) + { + MSG_SDATA_ERROR("file remove error : %s", mdata->filepath); + } + } + else + { + MSG_SDATA_ERROR("File path is NULL", mdata->filepath); + } + } + else + { + MSG_SDATA_ERROR("media_info_delete_from_db faild=%d uuid=%s file=%s", ret, uuid_getchar(mdata->mediaID), mdata->filepath); + return false; + } + } + else + { + MSG_SDATA_WARN("Invalid UUID. Path=%s", mdata->filepath); + + if (mdata->filepath) + { + MSG_SDATA_HIGH("File removed. %s", mdata->filepath); + + if (ivug_remove_file(mdata->filepath) == false) + { + MSG_SDATA_ERROR("file remove error : %s", mdata->filepath); + } + } + else + { + MSG_SDATA_ERROR("File path is NULL", mdata->filepath); + } + + } + + if (mdata->drm_filepath) + { + if ( ivug_remove_file(mdata->drm_filepath) == false) + { + MSG_SDATA_ERROR("Cannot delete drm file : %s", mdata->drm_filepath); + // Go though + } + } + + return true; +} + + diff --git a/medialist/src/ivug-mediadata.h b/medialist/src/ivug-mediadata.h new file mode 100755 index 0000000..f1f7b61 --- /dev/null +++ b/medialist/src/ivug-mediadata.h @@ -0,0 +1,52 @@ +/* + * Copyright 2012 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.tizenopensource.org/license + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __IVUG_MEDIADATA_H__ +#define __IVUG_MEDIADATA_H__ + +#include "ivug-media.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Converting Media_Data from filepath + * @param filepath[in] + * +**/ +Media_Data *ivug_alloc_mediadata_from_filepath(const char* filepath); + +/** + * Converting WMitem to Media_Data + * @param item[in] + * +**/ + +Media_Data *ivug_alloc_mediadata_from_media_handle(media_handle media); + +/** + * Free memory used by Media_Data + * @param mdata[in] + * +**/ +void ivug_free_mediadata(Media_Data* mdata); + +#ifdef __cplusplus +} +#endif + +#endif // __IVUG_MEDIADATA_H__ diff --git a/medialist/src/ivug-medialist.c b/medialist/src/ivug-medialist.c new file mode 100755 index 0000000..39ff16f --- /dev/null +++ b/medialist/src/ivug-medialist.c @@ -0,0 +1,687 @@ +/* + * Copyright 2012 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.tizenopensource.org/license + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "ivug-define.h" + +#include "ivug-debug.h" +#include "ivug-medialist.h" + +#include "ivug-mediadata.h" + +#include "ivug-data-list.h" + +#include "ivug-db.h" + +#include + +#undef DEBUG_DUMP_LIST + +#define LOAD_BLOCK_COUNT (100) + +#undef UNIT_TEST +#define UT_USE_DB +#define UT_TOTAL (50) +#define UT_INDEX (49) + +typedef struct { + Eina_List *header; // Start pointer for media list + int count; // Total count + + Ecore_Thread *thread; // Loading thread + Eina_Lock mutex; + Eina_Condition condition; + Eina_Lock end_mutex; + + Eina_Bool bTerminate; // + + bool bLoading; // Is thread loading on progress? + Filter_struct *filter_str; + + Eina_List *shufflelist; // Shuffle liste + +} _Media_List; + + +typedef struct { + _Media_List *_mList; + const Filter_struct *filter_str; + + int center_block; + int max_block; +} ThreadParam; + +typedef enum { + BLOCK_LEFT, + BLOCK_RIGHT, +} BlockType; + +typedef struct { + _Media_List *_mList; + + BlockType direction; + Eina_List *list; +} ThreadMSG; + +static int _get_block_num(int index) +{ + return (index / LOAD_BLOCK_COUNT); +} + +static Eina_List *_load_block(const Filter_struct *filter, int block_num) +{ + int stp = block_num * LOAD_BLOCK_COUNT; + int endp = ((block_num + 1) * LOAD_BLOCK_COUNT) - 1; + + Eina_List *header = NULL; + +#ifdef UT_USE_DB + header = ivug_list_load_DB_items(filter, stp, endp); +#else + Eina_List *header = NULL; + + int i; + Media_Data *data; + + for (i = stp; i <= endp; i++) + { + data = malloc(sizeof(Media_Data)); + data->index = i; + + header = eina_list_append(header, data); + } +#endif + + MSG_SDATA_HIGH("Loaded block : %d", block_num); + + return header; +} + + +static void _doLoad(Ecore_Thread *thread, _Media_List *_mList, const Filter_struct *filter, int center, int max_block) +{ + bool bRightEnd = false; + bool bLeftEnd = false; + int iter = 1; + + Eina_List *left; + Eina_List *right; + + while((bLeftEnd && bRightEnd) == false) + { + if ( center + iter <= max_block ) + { + right = _load_block(filter, center + iter); + +#if 0 + if ( ecore_thread_check(thread) == EINA_TRUE ) + { + MSG_SDATA_HIGH("Check True"); + ivug_list_delete_items(right); + break; + } +#else + if ( _mList->bTerminate == EINA_TRUE ) + { + MSG_SDATA_HIGH("Check True"); + ivug_list_delete_items(right); + return; + } +#endif + IV_ASSERT(right != NULL); + _mList->header = eina_list_merge (_mList->header, right); + } + else + { + bRightEnd = true; + } + + if ( center - iter >= 0) + { + left = _load_block(filter , center - iter); + +#if 0 + if ( ecore_thread_check(thread) == EINA_TRUE ) + { + MSG_SDATA_HIGH("Check True"); + ivug_list_delete_items(left); + break; + } +#else + if ( _mList->bTerminate == EINA_TRUE ) + { + MSG_SDATA_HIGH("Check True"); + ivug_list_delete_items(left); + return; + } +#endif + IV_ASSERT(left != NULL); + + _mList->header = eina_list_merge (left, _mList->header); + + } + else + { + bLeftEnd = true; + } + + iter++; + usleep(100); + } + + MSG_SDATA_HIGH("EinaCount=%d Count=%d", eina_list_count(_mList->header), _mList->count); +} + + +static void loader_heavy(void *data, Ecore_Thread *thread) +{ + MSG_SDATA_HIGH("Thread started. tID=0x%08x", thread); + ThreadParam *pParam = data; + +#if 0 + if ( ecore_thread_check(thread) == EINA_TRUE ) + { + MSG_SDATA_HIGH("Check True"); + return; + } +#else + + if ( pParam->_mList->bTerminate == EINA_TRUE ) + { + MSG_SDATA_HIGH("Check True"); + return; + } +#endif + + eina_lock_new(&pParam->_mList->mutex); + eina_condition_new(&pParam->_mList->condition, &pParam->_mList->mutex); + + MSG_SDATA_HIGH("Load : Begin"); + + _doLoad(thread, pParam->_mList, pParam->filter_str, pParam->center_block, pParam->max_block); + + MSG_SDATA_HIGH("Load : End"); + + pParam->_mList->thread = NULL; + + eina_lock_take(&pParam->_mList->mutex); + eina_condition_signal(&pParam->_mList->condition); + eina_lock_release(&pParam->_mList->mutex); + +} + + +static void loader_end(void *data, Ecore_Thread *thread) +{ +// ThreadParam *pParam = data; + + // MSG_SDATA_HIGH("Thread Ended. EinaCount=%d Count=%d", eina_list_count(pParam->_mList), pParam->_mList->count); + MSG_SDATA_HIGH("Thread Ended. tID=0x%08x", thread); + + PERF_CHECK_END(LVL3, "Deffered loading"); +} + +static void loader_cancel(void *data, Ecore_Thread *thread) +{ + MSG_SDATA_HIGH("Thread canceled. tID=0x%08x", thread); + + PERF_CHECK_END(LVL3, "Deffered loading"); +} + +static int _sort_cb(const void *d1, const void *d2) +{ + return (rand() % 4 - 2) ; +} + +static Media_Item *_find_item(Media_List *mList, int index) +{ + IV_ASSERT(mList != NULL); + _Media_List *_mList = (_Media_List *)mList; + + Eina_List *l; + Media_Data *data; + + EINA_LIST_FOREACH(_mList->header, l, data) + { + if ( data->index == index) + { + return (Media_Item *)l; + } + } + + return NULL; +} + + +#ifdef DEBUG_DUMP_LIST +static void _print_shuffle(void *data) +{ + MSG_SDATA_HIGH("Item : %d", (int)data); +} + +static void _dump_list(Eina_List *list, void (*func)(void *)) +{ + Eina_List *l; + void *data; + + EINA_LIST_FOREACH(list, l, data) + { + func(data); + } + +} +#endif + + +Media_List *ivug_medialist_create() +{ + _Media_List *_mList = calloc(1, sizeof(_Media_List)); + IV_ASSERT(_mList != NULL); + + srand((unsigned)time(NULL)); + + MSG_SDATA_HIGH("Create media list : 0x%08x", _mList); + + return (Media_List *)_mList; +} + +Media_Item * ivug_medialist_find_item_by_filename(Media_List *mList, const char* filepath) +{ + IV_ASSERT(mList != NULL); + IV_ASSERT(filepath != NULL); + _Media_List *_mList = (_Media_List *)mList; + + Eina_List *l; + Media_Data *data; + + EINA_LIST_FOREACH(_mList->header, l, data) + { + if(strncmp(data->fileurl, filepath, strlen(data->fileurl)) == 0) + { + return (Media_Item *)l; + } + } + MSG_SDATA_ERROR("Cannot find file path %s at list", filepath); + return NULL; +} + +Media_Item *ivug_medialist_load(Media_List *mList, const Filter_struct *filter) +{ + IV_ASSERT(mList != NULL); + _Media_List *_mList = (_Media_List *)mList; + + MSG_SDATA_HIGH("Create slide data list. index=%d", filter->index); + + if ( _mList->header != NULL ) + { + MSG_SDATA_FATAL("Header is not NULL"); + return NULL; + } +// _mList->filter = ivug_data_filter_copy(filter); + + int db_idx = 0; + +#ifdef UNIT_TEST + _mList->count = UT_TOTAL; + db_idx = UT_INDEX; + +#else + PERF_CHECK_BEGIN(LVL3, "MediaList - Get list count"); + + _mList->count = ivug_list_get_item_cnt(filter); + + PERF_CHECK_END(LVL3, "MediaList - Get list count"); + + MSG_SDATA_HIGH("Total item count=%d", _mList->count); + db_idx = filter->index - 1; +#endif + + if ( _mList->count < db_idx) + { + MSG_SDATA_ERROR("Invalid param"); + return NULL; + } + + int block_num = _get_block_num(db_idx); + int block_max = _get_block_num(_mList->count - 1); + + MSG_SDATA_HIGH("Total=%d Current=%d Block Count=%d", _mList->count, db_idx, block_max); + + PERF_CHECK_BEGIN(LVL3, "MediaList - load first block"); + + // Load Center + _mList->header = _load_block(filter, block_num); // Load current block + + PERF_CHECK_END(LVL3, "MediaList - load first block"); + + if(_mList->header == NULL) + { + MSG_SDATA_FATAL("MediaList is NULL"); + return NULL; + } + +// find current data; + MSG_SDATA_HIGH("Header=0x%08x Current nTh=%d", _mList->header, db_idx - (block_num * LOAD_BLOCK_COUNT)); + + PERF_CHECK_BEGIN(LVL3, "MediaList - Find current"); + + Eina_List *current = eina_list_nth_list(_mList->header, db_idx - (block_num * LOAD_BLOCK_COUNT)); + + PERF_CHECK_END(LVL3, "MediaList - Find current"); + + if(current == NULL) + { + MSG_SDATA_HIGH("current is NULL"); + return NULL; + } + + + PERF_CHECK_BEGIN(LVL3, "MediaList - shuffle"); + + int i; + _mList->shufflelist = NULL; + for ( i = 0; i < _mList->count; i++) + { + _mList->shufflelist = eina_list_append(_mList->shufflelist, (void *)i); + } + + _mList->shufflelist = eina_list_sort(_mList->shufflelist, eina_list_count(_mList->shufflelist), _sort_cb); + + PERF_CHECK_END(LVL3, "MediaList - shuffle"); + + // _dump_list(_mList->shufflelist, _print_shuffle); + // MSG_SDATA_HIGH("ParamPath=%s CurrentPath=%s", param->filepath, _mList->current->filepath); + + if ( block_max == 0 && eina_list_count(_mList->header) < LOAD_BLOCK_COUNT ) + { + MSG_SDATA_HIGH("Deffered loading is not needed. BolckMax=%d FirstBlockCount=%d", block_max, eina_list_count(_mList->header)); + return (Media_Item *)current; + } + + ThreadParam *pParam = NULL; + + pParam = malloc(sizeof(ThreadParam)); + + pParam->filter_str = filter; + pParam->_mList = _mList; + pParam->center_block = block_num; + pParam->max_block = block_max; + + _mList->bLoading = true; + + eina_lock_new(&_mList->end_mutex); + + MSG_SDATA_HIGH("Starting thread"); + + PERF_CHECK_BEGIN(LVL3, "Deffered loading"); + + _mList->thread = ecore_thread_run(loader_heavy, loader_end, loader_cancel, pParam); + MSG_SDATA_HIGH("Thread ID= 0x%08x", _mList->thread); + MSG_SDATA_HIGH("Create slide data list END"); + + return (Media_Item *)current; +} + +void +ivug_medialist_del(Media_List *mList) +{ + IV_ASSERT(mList != NULL); + _Media_List *_mList = (_Media_List *)mList; + + MSG_SDATA_HIGH("Removing all media data"); + + if ( _mList->thread ) + { + MSG_SDATA_HIGH("1. Thread cancel"); +#if 0 + if ( ecore_thread_cancel(_mList->thread) == EINA_TRUE ) + { + MSG_SDATA_HIGH("Thread canceled"); + } +#endif + _mList->bTerminate = EINA_TRUE; + + eina_condition_wait(&_mList->condition); + eina_lock_release(&_mList->mutex); + + _mList->thread = NULL; + MSG_SDATA_HIGH("2. Thread cancel"); + } + + ivug_list_delete_items(_mList->header); + _mList->header = NULL; + + eina_list_free(_mList->shufflelist); + _mList->shufflelist = NULL; + free(_mList); + +} + + +int ivug_medialist_get_count(Media_List *mList) +{ + IV_ASSERT(mList != NULL); + _Media_List *_mList = (_Media_List *)mList; + + return _mList->count; +} + +int ivug_medialist_get_index(Media_List *mList, Media_Item *item) +{ + IV_ASSERT(mList != NULL); + + Media_Data *pData; + + MSG_SDATA_HIGH("Loading is not finished"); + pData = (Media_Data *)eina_list_data_get((Eina_List *)item); + + return pData->index + 1; + + +#if 0 + PERF_CHECK_BEGIN("Get Index"); + + for (tmp = _mList->header, i= 0; tmp != NULL ; tmp = eina_list_next(tmp), i++) + { + if ( item == tmp ) + { + PERF_CHECK_END("Get Index"); + return i+1; // This index starts from 1 + } + } + + PERF_CHECK_END("Get Index"); + + + return 0; // Cannot find. +#endif + +} + +Media_Item *ivug_medialist_get_first(Media_List *mList) +{ + IV_ASSERT(mList != NULL); + _Media_List *_mList = (_Media_List *)mList; + + return (Media_Item *)_mList->header; +} + + +Media_Item *ivug_medialist_get_last(Media_List *mList) +{ + IV_ASSERT(mList != NULL); + _Media_List *_mList = (_Media_List *)mList; + + return (Media_Item *)eina_list_last(_mList->header); +} + +Media_Item *ivug_medialist_get_next(Media_List *mList, Media_Item *item) +{ + IV_ASSERT(mList != NULL); + + IV_ASSERT(item != NULL); + Eina_List *next = eina_list_next((Eina_List *)item); + + return (Media_Item *)next; +} + + +Media_Item *ivug_medialist_get_prev(Media_List *mList, Media_Item *item) +{ + IV_ASSERT(mList != NULL); + + IV_ASSERT(item != NULL); + Eina_List *prev = eina_list_prev((Eina_List *)item); + + return (Media_Item *)prev; + +} + +Media_Data *ivug_medialist_get_data(Media_Item *item) +{ + IV_ASSERT(item != NULL); + + return (Media_Data *)eina_list_data_get((Eina_List *)item); +} + + +void ivug_medialist_delete_item(Media_List *mList, Media_Item *item) +{ + PERF_CHECK_BEGIN(LVL1, "MediaList - delete"); + + IV_ASSERT(mList != NULL); + _Media_List *_mList = (_Media_List *)mList; + + Media_Data *pData = (Media_Data *)eina_list_data_get((Eina_List *)item); + + Eina_List *list = eina_list_next((Eina_List *)item); + Eina_List *l; + Media_Data *data; + + EINA_LIST_FOREACH(list, l, data) + { + data->index = data->index - 1; + } + + _mList->header = eina_list_remove_list(_mList->header, (Eina_List *)item); + + // Change index + if ( ivug_mediadata_delete(pData) == false ) + { + MSG_SDATA_HIGH("Cannot delete mediadata"); + } + ivug_free_mediadata(pData); + + // Shuffle list? + _mList->count--; + + Eina_List *found = eina_list_data_find_list(_mList->shufflelist, (void *)_mList->count); + + _mList->shufflelist = eina_list_remove(_mList->shufflelist, found); + + MSG_SDATA_HIGH("Item removed. Total=%d", _mList->count); + + PERF_CHECK_END(LVL1, "MediaList - delete"); +} + + +Media_Item *ivug_medialist_get_random_item(Media_List *mList) +{ + IV_ASSERT(mList != NULL); + _Media_List *_mList = (_Media_List *)mList; + + int count = eina_list_count(_mList->header); + + return (Media_Item *)eina_list_nth_list(_mList->header, random() % count); +} + +Media_Item *ivug_medialist_get_shuffle_item(Media_List *mList, Media_Item *item) +{ + IV_ASSERT(mList != NULL); + _Media_List *_mList = (_Media_List *)mList; + + Media_Data *pData = (Media_Data *)eina_list_data_get((Eina_List *)item); + + Eina_List *found = eina_list_data_find_list(_mList->shufflelist, (void *)pData->index); + + if ( found != NULL ) + { + Media_Item *next; + Eina_List *iter; + + iter = eina_list_next(found); + + if ( iter == NULL ) + { + int nFirstIdx = (int)eina_list_data_get(_mList->shufflelist); + + next = _find_item(mList, nFirstIdx); + + MSG_SDATA_HIGH("End reached. rewind to first. Index=%d", nFirstIdx); + + return next; + } + + do { + next = _find_item(mList, (int)eina_list_data_get(iter)); + + if ( next == NULL ) + { + MSG_SDATA_HIGH("Index : %d is not loaded", (int)eina_list_data_get(iter)); + _mList->shufflelist = eina_list_demote_list(_mList->shufflelist, iter); + } + + iter = eina_list_next(found); + + } while(next == NULL); + + Media_Data *nData = (Media_Data *)eina_list_data_get((Eina_List *)next); + + MSG_SDATA_HIGH("Shuffle : %d->%d", pData->index, nData->index ); + +// _dump_list(_mList->shufflelist, _print_shuffle); + return next; + } + + MSG_SDATA_ERROR("Cannot find data. Index=%d", pData->index); + return NULL; +} + +Media_Item * +ivug_medialist_find_item_by_index(Media_List *mList, int index) +{ + IV_ASSERT(mList != NULL); + + _Media_List *_mList = (_Media_List *)mList; + + Media_Data *current = NULL; + Eina_List *l = NULL; + + EINA_LIST_FOREACH(_mList->header, l, current) + { + if(current == NULL) + { + MSG_IVUG_ERROR("album list is NULL"); + break; + } + if(current->index == index) + { + return (Media_Item *)l; + } + } + return NULL; +} + + diff --git a/packaging/changelog b/packaging/changelog new file mode 100755 index 0000000..ce82553 --- /dev/null +++ b/packaging/changelog @@ -0,0 +1,3232 @@ +ug-image-viewer-efl (1.6.34) unstable; urgency=low + + * fix desktop mode GUI + * Tag: ug-image-viewer-efl_1.6.34 + + -- root Mon, 06 Aug 2012 16:44:48 +0900 + +ug-image-viewer-efl (1.6.33) unstable; urgency=low + + * fix build error + * Tag: ug-image-viewer-efl_1.6.33 + + -- root Mon, 06 Aug 2012 11:55:17 +0900 + +ug-image-viewer-efl (1.6.32) unstable; urgency=low + + * fix web downloader api + * Tag: ug-image-viewer-efl_1.6.32 + + -- root Mon, 06 Aug 2012 10:55:28 +0900 + +ug-image-viewer-efl (1.6.31) unstable; urgency=low + + * fix cropbox bound bug + * Tag: ug-image-viewer-efl_1.6.31 + + -- root Sat, 04 Aug 2012 11:39:00 +0900 + +ug-image-viewer-efl (1.6.30) unstable; urgency=low + + * fix setas control bar + * Tag: ug-image-viewer-efl_1.6.30 + + -- root Fri, 03 Aug 2012 10:40:17 +0900 + +ug-image-viewer-efl (1.6.29) unstable; urgency=low + + * update version + * Tag: ug-image-viewer-efl_1.6.29 + + -- root Wed, 01 Aug 2012 20:06:32 +0900 + +ug-image-viewer-efl (1.6.28) unstable; urgency=low + + * change face dependency + * Tag: ug-image-viewer-efl_1.6.28 + + -- root Wed, 01 Aug 2012 14:36:29 +0900 + +ug-image-viewer-efl (1.6.27) unstable; urgency=low + + * apply manifest + * Tag: ug-image-viewer-efl_1.6.27 + + -- root Tue, 31 Jul 2012 19:23:26 +0900 + +ug-image-viewer-efl (1.6.26) unstable; urgency=low + + * update version + * Tag: ug-image-viewer-efl_1.6.26 + + -- root Mon, 30 Jul 2012 09:43:41 +0900 + +ug-image-viewer-efl (1.6.25) unstable; urgency=low + + * update version + * Tag: ug-image-viewer-efl_1.6.25 + + -- root Sat, 28 Jul 2012 16:39:40 +0900 + +ug-image-viewer-efl (1.6.24) unstable; urgency=low + + * update version + * Tag: ug-image-viewer-efl_1.6.24 + + -- root Sat, 28 Jul 2012 13:32:23 +0900 + +ug-image-viewer-efl (1.6.23) unstable; urgency=low + + * fix crop BS + * Tag: ug-image-viewer-efl_1.6.23 + + -- root Fri, 27 Jul 2012 17:17:46 +0900 + +ug-image-viewer-efl (1.6.22) unstable; urgency=low + + * rename player handle + * Tag: ug-image-viewer-efl_1.6.22 + + -- root Fri, 27 Jul 2012 15:49:06 +0900 + +ug-image-viewer-efl (1.6.21) unstable; urgency=low + + * update version + * Tag: ug-image-viewer-efl_1.6.21 + + -- root Fri, 27 Jul 2012 14:21:01 +0900 + +ug-image-viewer-efl (1.6.20) unstable; urgency=low + + * fix emulater BS + * Tag: ug-image-viewer-efl_1.6.20 + + -- root Fri, 27 Jul 2012 14:05:31 +0900 + +ug-image-viewer-efl (1.6.19) unstable; urgency=low + + * fix camera folder path, motion popup text color + * Tag: ug-image-viewer-efl_1.6.19 + + -- root Thu, 26 Jul 2012 19:59:08 +0900 + +ug-image-viewer-efl (1.6.18) unstable; urgency=low + + * fix BS when crop failed + * Tag: ug-image-viewer-efl_1.6.18 + + -- root Thu, 26 Jul 2012 11:22:14 +0900 + +ug-image-viewer-efl (1.6.17) unstable; urgency=low + + * apply white theme + * Tag: ug-image-viewer-efl_1.6.17 + + -- root Thu, 26 Jul 2012 09:26:53 +0900 + +ug-image-viewer-efl (1.6.16) unstable; urgency=low + + * change api + * Tag: ug-image-viewer-efl_1.6.16 + + -- root Wed, 25 Jul 2012 13:26:03 +0900 + +ug-image-viewer-efl (1.6.15) unstable; urgency=low + + * update version + * Tag: ug-image-viewer-efl_1.6.15 + + -- root Mon, 23 Jul 2012 21:24:32 +0900 + +ug-image-viewer-efl (1.6.14) unstable; urgency=low + + * update version + * Tag: ug-image-viewer-efl_1.6.14 + + -- root Mon, 23 Jul 2012 17:03:57 +0900 + +ug-image-viewer-efl (1.6.13) unstable; urgency=low + + * fix BS + * Tag: ug-image-viewer-efl_1.6.13 + + -- root Mon, 23 Jul 2012 14:57:46 +0900 + +ug-image-viewer-efl (1.6.12) unstable; urgency=low + + * update version + * Tag: ug-image-viewer-efl_1.6.12 + + -- root Fri, 20 Jul 2012 15:51:05 +0900 + +ug-image-viewer-efl (1.6.11) unstable; urgency=low + + * apply motion zoom + * Tag: ug-image-viewer-efl_1.6.11 + + -- root Fri, 20 Jul 2012 15:16:09 +0900 + +ug-image-viewer-efl (1.6.10) unstable; urgency=low + + * apply managed UG api. + * Tag: ug-image-viewer-efl_1.6.10 + + -- root Wed, 18 Jul 2012 19:29:52 +0900 + +ug-image-viewer-efl (1.6.9) unstable; urgency=low + + * fix build error + * Tag: ug-image-viewer-efl_1.6.9 + + -- root Tue, 17 Jul 2012 18:34:39 +0900 + +ug-image-viewer-efl (1.6.8) unstable; urgency=low + + * fix slide show BS + * Tag: ug-image-viewer-efl_1.6.8 + + -- root Tue, 17 Jul 2012 18:16:06 +0900 + +ug-image-viewer-efl (1.6.7) unstable; urgency=low + + * update image viewer + * Tag: ug-image-viewer-efl_1.6.7 + + -- root Mon, 16 Jul 2012 16:22:35 +0900 + +ug-image-viewer-efl (1.6.6) unstable; urgency=low + + * apply video call id + * Tag: ug-image-viewer-efl_1.6.6 + + -- root Mon, 16 Jul 2012 11:57:58 +0900 + +ug-image-viewer-efl (1.6.5) unstable; urgency=low + + * fix crop box style, phone ug name + * Tag: ug-image-viewer-efl_1.6.5 + + -- root Fri, 13 Jul 2012 14:43:26 +0900 + +ug-image-viewer-efl (1.6.3) unstable; urgency=low + + * fix bs when delete item + * Tag: ug-image-viewer-efl_1.6.3 + + -- root Thu, 12 Jul 2012 19:20:07 +0900 + +ug-image-viewer-efl (1.6.2) unstable; urgency=low + + * fix bs + * Git: slp/pkgs/u/ug-image-viewer-efl.git + * Tag: ug-image-viewer-efl_1.6.2 + + -- Jisung Ahn Wed, 11 Jul 2012 17:10:47 +0900 + +ug-image-viewer-efl (1.6.1) unstable; urgency=low + + * fix slideshow bs, hide menu at setas + * Git: slp/pkgs/u/ug-image-viewer-efl.git + * Tag: ug-image-viewer-efl_1.6.1 + + -- Jisung Ahn Tue, 10 Jul 2012 18:42:34 +0900 + +ug-image-viewer-efl (1.6.0) unstable; urgency=low + + * apply new DB api + * Git: slp/pkgs/u/ug-image-viewer-efl.git + * Tag: ug-image-viewer-efl_1.6.0 + + -- Jisung Ahn Thu, 05 Jul 2012 10:33:11 +0900 + +ug-image-viewer-efl (1.5.19) unstable; urgency=low + + * fix bug, launch speed + * Git: slp/pkgs/u/ug-image-viewer-efl.git + * Tag: ug-image-viewer-efl_1.5.19 + + -- Jisung Ahn Fri, 06 Jul 2012 17:39:24 +0900 + +ug-image-viewer-efl (1.5.18) unstable; urgency=low + + * fix bundle bug + * Git: slp/pkgs/u/ug-image-viewer-efl.git + * Tag: ug-image-viewer-efl_1.5.18 + + -- Jisung Ahn Wed, 04 Jul 2012 15:39:55 +0900 + +ug-image-viewer-efl (1.5.17) unstable; urgency=low + + * show popup at save fail + * Git: slp/pkgs/u/ug-image-viewer-efl.git + * Tag: ug-image-viewer-efl_1.5.17 + + -- Jisung Ahn Tue, 03 Jul 2012 21:23:44 +0900 + +ug-image-viewer-efl (1.5.16) unstable; urgency=low + + * fix bug, fix GUI + * Git: slp/pkgs/u/ug-image-viewer-efl.git + * Tag: ug-image-viewer-efl_1.5.16 + + -- Jisung Ahn Mon, 02 Jul 2012 20:29:25 +0900 + +ug-image-viewer-efl (1.5.15) unstable; urgency=low + + * enable face method, apply blue theme + * Git: slp/pkgs/u/ug-image-viewer-efl.git + * Tag: ug-image-viewer-efl_1.5.15 + + -- Jisung Ahn Fri, 29 Jun 2012 20:28:10 +0900 + +ug-image-viewer-efl (1.5.14) unstable; urgency=low + + * enable allshare + * Git: slp/pkgs/u/ug-image-viewer-efl.git + * Tag: ug-image-viewer-efl_1.5.14 + + -- Jisung Ahn Wed, 27 Jun 2012 19:30:33 +0900 + +ug-image-viewer-efl (1.5.13) unstable; urgency=low + + * apply face tag + * Git: slp/pkgs/u/ug-image-viewer-efl.git + * Tag: ug-image-viewer-efl_1.5.13 + + -- Jisung Ahn Mon, 25 Jun 2012 21:10:37 +0900 + +ug-image-viewer-efl (1.5.12) unstable; urgency=low + + * fix set as GUI + * Git: slp/pkgs/u/ug-image-viewer-efl.git + * Tag: ug-image-viewer-efl_1.5.12 + + -- Jisung Ahn Mon, 18 Jun 2012 10:35:45 +0900 + +ug-image-viewer-efl (1.5.11) unstable; urgency=low + + * Fix B/S when set wallpaper + * Git: slp/pkgs/u/ug-image-viewer-efl.git + * Tag: ug-image-viewer-efl_1.5.11 + + -- Jisung Ahn Wed, 13 Jun 2012 13:27:27 +0900 + +ug-image-viewer-efl (1.5.10) unstable; urgency=low + + * remove mss + * Git: slp/pkgs/u/ug-image-viewer-efl.git + * Tag: ug-image-viewer-efl_1.5.10 + + -- Jisung Ahn Mon, 11 Jun 2012 17:52:04 +0900 + +ug-image-viewer-efl (1.5.9) unstable; urgency=low + + * check drm at file set + * Git: slp/pkgs/u/ug-image-viewer-efl.git + * Tag: ug-image-viewer-efl_1.5.9 + + -- Jisung Ahn Thu, 07 Jun 2012 19:11:45 +0900 + +ug-image-viewer-efl (1.5.8) unstable; urgency=low + + * fix error, apply asf(disabled) + * Git: slp/pkgs/u/ug-image-viewer-efl.git + * Tag: ug-image-viewer-efl_1.5.8 + + -- Jisung Ahn Thu, 07 Jun 2012 10:05:15 +0900 + +ug-image-viewer-efl (1.5.7) unstable; urgency=low + + * fix ux feedback + * Git: slp/pkgs/u/ug-image-viewer-efl.git + * Tag: ug-image-viewer-efl_1.5.7 + + -- Jisung Ahn Mon, 04 Jun 2012 17:36:31 +0900 + +ug-image-viewer-efl (1.5.6) unstable; urgency=low + + * update slideshow + * Git: slp/pkgs/u/ug-image-viewer-efl.git + * Tag: ug-image-viewer-efl_1.5.6 + + -- Jisung Ahn Mon, 04 Jun 2012 11:04:51 +0900 + +ug-image-viewer-efl (1.5.5) unstable; urgency=low + + * fix rotate reset bs at invalid file + * Git: slp/pkgs/u/ug-image-viewer-efl.git + * Tag: ug-image-viewer-efl_1.5.5 + + -- Jisung Ahn Tue, 29 May 2012 10:41:25 +0900 + +ug-image-viewer-efl (1.5.4) unstable; urgency=low + + * apply rotate function + * Git: slp/pkgs/u/ug-image-viewer-efl.git + * Tag: ug-image-viewer-efl_1.5.4 + + -- Jisung Ahn Fri, 25 May 2012 19:30:31 +0900 + +ug-image-viewer-efl (1.5.3) unstable; urgency=low + + * update drm, fix bug + * Git: slp/pkgs/u/ug-image-viewer-efl.git + * Tag: ug-image-viewer-efl_1.5.3 + + -- Jisung Ahn Fri, 25 May 2012 10:28:04 +0900 + +ug-image-viewer-efl (1.5.2) unstable; urgency=low + + * update slide show effect + * Git: slp/pkgs/u/ug-image-viewer-efl.git + * Tag: ug-image-viewer-efl_1.5.2 + + -- Jisung Ahn Wed, 23 May 2012 15:22:11 +0900 + +ug-image-viewer-efl (1.5.1) unstable; urgency=low + + * apply copy popup + * Git: slp/pkgs/u/ug-image-viewer-efl.git + * Tag: ug-image-viewer-efl_1.5.1 + + -- Jisung Ahn Mon, 21 May 2012 10:32:32 +0900 + +ug-image-viewer-efl (1.5.0) unstable; urgency=low + + * Add thumblist. Implement scroller. + * Git: slp/pkgs/u/ug-image-viewer-efl.git + * Tag: ug-image-viewer-efl_1.5.0 + + -- Jisung Ahn Wed, 16 May 2012 10:50:02 +0900 + +ug-image-viewer-efl (1.4.47) unstable; urgency=low + + * enable done btn + * Git: slp/pkgs/u/ug-image-viewer-efl.git + * Tag: ug-image-viewer-efl_1.4.47 + + -- Jisung Ahn Tue, 15 May 2012 17:17:55 +0900 + +ug-image-viewer-efl (1.4.46) unstable; urgency=low + + * fix slide show bug + * Git: slp/pkgs/u/ug-image-viewer-efl.git + * Tag: ug-image-viewer-efl_1.4.46 + + -- Jisung Ahn Mon, 14 May 2012 16:31:10 +0900 + +ug-image-viewer-efl (1.4.45) unstable; urgency=low + + * fix bug + * Git: slp/pkgs/u/ug-image-viewer-efl.git + * Tag: ug-image-viewer-efl_1.4.45 + + -- Jisung Ahn Mon, 14 May 2012 11:41:37 +0900 + +ug-image-viewer-efl (1.4.44) unstable; urgency=low + + * update version + * Git: slp/pkgs/u/ug-image-viewer-efl.git + * Tag: ug-image-viewer-efl_1.4.44 + + -- Jisung Ahn Tue, 08 May 2012 14:35:32 +0900 + +ug-image-viewer-efl (1.4.43) unstable; urgency=low + + * apply motion panning, tool button + * Git: slp/pkgs/u/ug-image-viewer-efl.git + * Tag: ug-image-viewer-efl_1.4.43 + + -- Jisung Ahn Mon, 07 May 2012 10:59:40 +0900 + +ug-image-viewer-efl (1.4.42) unstable; urgency=low + + * fix string + * Git: slp/pkgs/u/ug-image-viewer-efl.git + * Tag: ug-image-viewer-efl_1.4.42 + + -- Jisung Ahn Thu, 03 May 2012 12:06:51 +0900 + +ug-image-viewer-efl (1.4.41) unstable; urgency=low + + * remove useless code + * Git: slp/pkgs/u/ug-image-viewer-efl.git + * Tag: ug-image-viewer-efl_1.4.41 + + -- Jisung Ahn Fri, 13 Apr 2012 11:35:33 +0900 + +ug-image-viewer-efl (1.4.40) unstable; urgency=low + + * fix BS at abnomal exit case + * Git: slp/pkgs/u/ug-image-viewer-efl.git + * Tag: ug-image-viewer-efl_1.4.40 + + -- Jisung Ahn Thu, 12 Apr 2012 13:54:12 +0900 + +ug-image-viewer-efl (1.4.39) unstable; urgency=low + + * fix BS + * Git: slp/pkgs/u/ug-image-viewer-efl.git + * Tag: ug-image-viewer-efl_1.4.39 + + -- Jisung Ahn Tue, 10 Apr 2012 18:03:27 +0900 + +ug-image-viewer-efl (1.4.38) unstable; urgency=low + + * apply url-downloader + * Git: slp/pkgs/u/ug-image-viewer-efl.git + * Tag: ug-image-viewer-efl_1.4.38 + + -- Jisung Ahn Fri, 06 Apr 2012 13:59:07 +0900 + +ug-image-viewer-efl (1.4.37) unstable; urgency=low + + * capi-uix-face API is changed + * Git: slp/pkgs/u/ug-image-viewer-efl.git + * Tag: ug-image-viewer-efl_1.4.37 + + -- Jisung Ahn Thu, 29 Mar 2012 20:05:16 +0900 + +ug-image-viewer-efl (1.4.36) unstable; urgency=low + + * fix detail bug, red box bug, allshare icon + * Git: slp/pkgs/u/ug-image-viewer-efl.git + * Tag: ug-image-viewer-efl_1.4.36 + + -- Jisung Ahn Thu, 29 Mar 2012 17:02:47 +0900 + +ug-image-viewer-efl (1.4.35) unstable; urgency=low + + * fix jira issue(motion popup), disable toolbar button + * Git: slp/pkgs/u/ug-image-viewer-efl.git + * Tag: ug-image-viewer-efl_1.4.35 + + -- Jisung Ahn Tue, 27 Mar 2012 13:48:58 +0900 + +ug-image-viewer-efl (1.4.34) unstable; urgency=low + + * apply capi at setas + * Git: slp/pkgs/u/ug-image-viewer-efl.git + * Tag: ug-image-viewer-efl_1.4.34 + + -- Jisung Ahn Mon, 26 Mar 2012 13:47:07 +0900 + +ug-image-viewer-efl (1.4.33) unstable; urgency=low + + * fix add tag view + * Git: slp/pkgs/u/ug-image-viewer-efl.git + * Tag: ug-image-viewer-efl_1.4.33 + + -- Jisung Ahn Fri, 23 Mar 2012 10:48:47 +0900 + +ug-image-viewer-efl (1.4.32) unstable; urgency=low + + * add timeout callback + * Git: slp/pkgs/u/ug-image-viewer-efl.git + * Tag: ug-image-viewer-efl_1.4.32 + + -- Jisung Ahn Thu, 22 Mar 2012 09:41:07 +0900 + +ug-image-viewer-efl (1.4.31) unstable; urgency=low + + * fix BS + * Git: slp/pkgs/u/ug-image-viewer-efl.git + * Tag: ug-image-viewer-efl_1.4.31 + + -- Jisung Ahn Tue, 20 Mar 2012 10:37:46 +0900 + +ug-image-viewer-efl (1.4-30) unstable; urgency=low + + * update naviframe, genlist + * Git: slp/pkgs/u/ug-image-viewer-efl.git + * Tag: ug-image-viewer-efl_1.4-30 + + -- Jisung Ahn Thu, 15 Mar 2012 21:22:49 +0900 + +ug-image-viewer-efl (1.4-29) unstable; urgency=low + + * fix bug + * Git: slp/pkgs/u/ug-image-viewer-efl.git + * Tag: ug-image-viewer-efl_1.4-29 + + -- Jisung Ahn Wed, 14 Mar 2012 18:54:39 +0900 + +ug-image-viewer-efl (1.4-28) unstable; urgency=low + + * update EFL 1.0 + * Git: slp/pkgs/u/ug-image-viewer-efl.git + * Tag: ug-image-viewer-efl_1.4-28 + + -- Jisung Ahn Tue, 13 Mar 2012 20:58:59 +0900 + +ug-image-viewer-efl (1.4-27) unstable; urgency=low + + * change to CAPI, remove editfield api + * Git: slp/pkgs/u/ug-image-viewer-efl.git + * Tag: ug-image-viewer-efl_1.4-27 + + -- Jisung Ahn Tue, 28 Feb 2012 17:43:07 +0900 + +ug-image-viewer-efl (1.4-26) unstable; urgency=low + + * Can set resolution at set as view + * Git: slp/pkgs/u/ug-image-viewer-efl.git + * Tag: ug-image-viewer-efl_1.4-26 + + -- Jisung Ahn Thu, 23 Feb 2012 19:22:46 +0900 + +ug-image-viewer-efl (1.4-25) unstable; urgency=low + + * update changelog + * Git: slp/pkgs/u/ug-image-viewer-efl.git + * Tag: ug-image-viewer-efl_1.4-25 + + -- Jisung Ahn Thu, 23 Feb 2012 17:41:57 +0900 + +ug-image-viewer-efl (1.4-24) unstable; urgency=low + + * fix bug + * Git: slp/pkgs/u/ug-image-viewer-efl.git + * Tag: ug-image-viewer-efl_1.4-24 + + -- Jisung Ahn Mon, 20 Feb 2012 20:26:27 +0900 + +ug-image-viewer-efl (1.4-23) unstable; urgency=low + + * update efl api + * Git: slp/pkgs/u/ug-image-viewer-efl.git + * Tag: ug-image-viewer-efl_1.4-23 + + -- Jisung Ahn Wed, 15 Feb 2012 20:40:50 +0900 + +ug-image-viewer-efl (1.4-22) unstable; urgency=low + + * fix bugs + * Git: slp/pkgs/u/ug-image-viewer-efl.git + * Tag: ug-image-viewer-efl_1.4-22 + + -- Jisung Ahn Wed, 08 Feb 2012 11:26:49 +0900 + +ug-image-viewer-efl (1.4-21) unstable; urgency=low + + * add slider_pause, slider_resume + * Git: slp/pkgs/u/ug-image-viewer-efl.git + * Tag: ug-image-viewer-efl_1.4-21 + + -- Jisung Ahn Fri, 03 Feb 2012 14:31:47 +0900 + +ug-image-viewer-efl (1.4-20) unstable; urgency=low + + * fix bug + * Git: slp/pkgs/u/ug-image-viewer-efl.git + * Tag: ug-image-viewer-efl_1.4-20 + + -- Jisung Ahn Thu, 02 Feb 2012 19:08:14 +0900 + +ug-image-viewer-efl (1.4-19) unstable; urgency=low + + * enable setas button + * Git: slp/pkgs/u/ug-image-viewer-efl.git + * Tag: ug-image-viewer-efl_1.4-19 + + -- Jisung Ahn Wed, 01 Feb 2012 14:39:00 +0900 + +ug-image-viewer-efl (1.4-18) unstable; urgency=low + + * upload for minfo + * Git: slp/pkgs/u/ug-image-viewer-efl.git + * Tag: ug-image-viewer-efl_1.4-18 + + -- Jisung Ahn Tue, 31 Jan 2012 17:07:10 +0900 + +ug-image-viewer-efl (1.4-17) unstable; urgency=low + + * implement media list + * Git: slp/pkgs/u/ug-image-viewer-efl.git + * Tag: ug-image-viewer-efl_1.4-17 + + -- Jisung Ahn Fri, 27 Jan 2012 17:50:50 +0900 + +ug-image-viewer-efl (1.4-16) unstable; urgency=low + + * change face detect api + * Git: slp/pkgs/u/ug-image-viewer-efl.git + * Tag: ug-image-viewer-efl_1.4-16 + + -- Jisung Ahn Thu, 26 Jan 2012 19:48:19 +0900 + +ug-image-viewer-efl (1.4-15) unstable; urgency=low + + * change idler to job + * Git: slp/pkgs/u/ug-image-viewer-efl.git + * Tag: ug-image-viewer-efl_1.4-15 + + -- Jisung Ahn Wed, 25 Jan 2012 16:02:23 +0900 + +ug-image-viewer-efl (1.4-14) unstable; urgency=low + + * fix crash for setas view + * Git: slp/pkgs/u/ug-image-viewer-efl.git + * Tag: ug-image-viewer-efl_1.4-14 + + -- Jisung Ahn Fri, 20 Jan 2012 14:57:32 +0900 + +ug-image-viewer-efl (1.4-13) unstable; urgency=low + + * change share option + * Git: slp/pkgs/u/ug-image-viewer-efl.git + * Tag: ug-image-viewer-efl_1.4-13 + + -- Jisung Ahn Thu, 19 Jan 2012 19:25:03 +0900 + +ug-image-viewer-efl (1.4-12) unstable; urgency=low + + * media svc api change + * Git: slp/pkgs/u/ug-image-viewer-efl.git + * Tag: ug-image-viewer-efl_1.4-12 + + -- Jisung Ahn Wed, 18 Jan 2012 16:52:36 +0900 + +ug-image-viewer-efl (1.4-11) unstable; urgency=low + + * remove editfield edc + * Git: slp/pkgs/u/ug-image-viewer-efl.git + * Tag: ug-image-viewer-efl_1.4-11 + + -- Jisung Ahn Tue, 17 Jan 2012 17:31:54 +0900 + +ug-image-viewer-efl (1.4-10) unstable; urgency=low + + * update naviframe, entry edc + * Git: slp/pkgs/u/ug-image-viewer-efl.git + * Tag: ug-image-viewer-efl_1.4-10 + + -- Jisung Ahn Tue, 17 Jan 2012 15:32:50 +0900 + +ug-image-viewer-efl (1.4-9) unstable; urgency=low + + * update changelog + * Git: slp/pkgs/u/ug-image-viewer-efl.git + * Tag: ug-image-viewer-efl_1.4-9 + + -- Jisung Ahn Mon, 16 Jan 2012 13:57:32 +0900 + +ug-image-viewer-efl (1.4-8) unstable; urgency=low + + * code refine + * Git: slp/pkgs/u/ug-image-viewer-efl.git + * Tag: ug-image-viewer-efl_1.4-8 + + -- Jisung Ahn Fri, 06 Jan 2012 10:52:07 +0900 + +ug-image-viewer-efl (1.4-7) unstable; urgency=low + + * apply string + * Git: slp/pkgs/u/ug-image-viewer-efl.git + * Tag: ug-image-viewer-efl_1.4-7 + + -- Jisung Ahn Mon, 26 Dec 2011 15:48:47 +0900 + +ug-image-viewer-efl (1.4-6) unstable; urgency=low + + * Update Changelog + * Git: slp/pkgs/u/ug-image-viewer-efl.git + * Tag: ug-image-viewer-efl_1.4-6 + + -- Jisung Ahn Thu, 22 Dec 2011 10:16:04 +0900 + +ug-image-viewer-efl (1.4-5) unstable; urgency=low + + * Update changelog + * Git: slp/pkgs/u/ug-image-viewer-efl.git + * Tag: ug-image-viewer-efl_1.4-5 + + -- Li Suxia Tue, 20 Dec 2011 10:08:15 +0800 + +ug-image-viewer-efl (1.4-4) unstable; urgency=low + + * Update changelog + * Git: slp/pkgs/u/ug-image-viewer-efl.git + * Tag: ug-image-viewer-efl_1.4-4 + + -- Li Suxia Mon, 19 Dec 2011 16:45:24 +0800 + +ug-image-viewer-efl (1.4-3) unstable; urgency=low + + * update changelog + * Git: slp/pkgs/u/ug-image-viewer-efl.git + * Tag: ug-image-viewer-efl_1.4-3 + + -- Jisung Ahn Mon, 19 Dec 2011 13:52:58 +0900 + +ug-image-viewer-efl (1.4-2) unstable; urgency=low + + * enable facebook appsvc + * Git: slp/pkgs/u/ug-image-viewer-efl.git + * Tag: ug-image-viewer-efl_1.4-2 + + -- Jisung Ahn Wed, 14 Dec 2011 15:09:23 +0900 + +ug-image-viewer-efl (1.4-1) unstable; urgency=low + + * version up + * Git: slp-source.sec.samsung.net:slp/pkgs/u/ug-image-viewer-efl.git + * Tag: ug-image-viewer-efl_1.4-1 + + -- Jisung Ahn Tue, 13 Dec 2011 12:35:01 +0900 + +ug-image-viewer-efl (1.4-0) unstable; urgency=low + + * upload refactoring + * Git: slp-source.sec.samsung.net:slp/pkgs/u/ug-image-viewer-efl.git + * Tag: ug-image-viewer-efl_1.4-0 + + -- Jisung Ahn Fri, 09 Dec 2011 17:17:46 +0900 + +ug-image-viewer-efl (1.3-77) unstable; urgency=low + + * prepare code open + * Git: slp-source.sec.samsung.net:slp/pkgs/u/ug-image-viewer-efl.git + * Tag: ug-image-viewer-efl_1.3-77 + + -- Jisung Ahn Wed, 07 Dec 2011 10:48:42 +0900 + +ug-image-viewer-efl (1.3-76) unstable; urgency=low + + * fix CQ H0100137612(BS at wma file) + * Git: slp-source.sec.samsung.net:slp/pkgs/u/ug-image-viewer-efl.git + * Tag: ug-image-viewer-efl_1.3-76 + + -- Jisung Ahn Mon, 28 Nov 2011 17:10:49 +0900 + +ug-image-viewer-efl (1.3-75) unstable; urgency=low + + * close detail view at web album + * Git: slp-source.sec.samsung.net:slp/pkgs/u/ug-image-viewer-efl.git + * Tag: ug-image-viewer-efl_1.3-75 + + -- Jisung Ahn Thu, 24 Nov 2011 20:52:51 +0900 + +ug-image-viewer-efl (1.3-74) unstable; urgency=low + + * version for upload + * Git: slp-source.sec.samsung.net:slp/pkgs/u/ug-image-viewer-efl.git + * Tag: ug-image-viewer-efl_1.3-74 + + -- Jisung Ahn Thu, 24 Nov 2011 19:48:40 +0900 + +ug-image-viewer-efl (1.3-73) unstable; urgency=low + + * update changelog + * Git: slp-source.sec.samsung.net:slp/pkgs/u/ug-image-viewer-efl.git + * Tag: ug-image-viewer-efl_1.3-73 + + -- Jisung Ahn Wed, 23 Nov 2011 13:11:47 +0900 + +ug-image-viewer-efl (1.3-72) unstable; urgency=low + + * Details view is popped from naviframe when destroy. + * Git: slp-source.sec.samsung.net:slp/pkgs/u/ug-image-viewer-efl.git + * Tag: ug-image-viewer-efl_1.3-72 + + -- root Tue, 22 Nov 2011 20:17:20 +0900 + +ug-image-viewer-efl (1.3-71) unstable; urgency=low + + * delete event blocker, destroy detail view + * Git: slp-source.sec.samsung.net:slp/pkgs/u/ug-image-viewer-efl.git + * Tag: ug-image-viewer-efl_1.3-71 + + -- Jisung Ahn Wed, 16 Nov 2011 20:05:37 +0900 + +ug-image-viewer-efl (1.3-70) unstable; urgency=low + + * fix Lockup issue + * Git: slp-source.sec.samsung.net:slp/pkgs/u/ug-image-viewer-efl.git + * Tag: ug-image-viewer-efl_1.3-70 + + -- Jisung Ahn Tue, 15 Nov 2011 18:53:40 +0900 + +ug-image-viewer-efl (1.3-69) unstable; urgency=low + + * fix GUI + * Git: slp-source.sec.samsung.net:slp/pkgs/u/ug-image-viewer-efl.git + * Tag: ug-image-viewer-efl_1.3-69 + + -- Jisung Ahn Mon, 14 Nov 2011 21:27:06 +0900 + +ug-image-viewer-efl (1.3-68) unstable; urgency=low + + * fix popup width, change back key concept + * Git: slp-source.sec.samsung.net:slp/pkgs/u/ug-image-viewer-efl.git + * Tag: ug-image-viewer-efl_1.3-68 + + -- Jisung Ahn Thu, 10 Nov 2011 17:02:20 +0900 + +ug-image-viewer-efl (1.3-67) unstable; urgency=low + + * fix prevet, set as bug, log, mss, photocam + * Git: slp-source.sec.samsung.net:slp/pkgs/u/ug-image-viewer-efl.git + * Tag: ug-image-viewer-efl_1.3-67 + + -- Jisung Ahn Wed, 09 Nov 2011 15:32:32 +0900 + +ug-image-viewer-efl (1.3-66) unstable; urgency=low + + * fix places view BS, Modify all share icon position Response popup immediately. + * Git: slp-source.sec.samsung.net:slp/pkgs/u/ug-image-viewer-efl.git + * Tag: ug-image-viewer-efl_1.3-66 + + -- Jisung Ahn Thu, 03 Nov 2011 17:39:14 +0900 + +ug-image-viewer-efl (1.3-65) unstable; urgency=low + + * change editfield focus method + * Git: slp-source.sec.samsung.net:slp/pkgs/u/ug-image-viewer-efl.git + * Tag: ug-image-viewer-efl_1.3-65 + + -- Jisung Ahn Wed, 02 Nov 2011 16:17:04 +0900 + +ug-image-viewer-efl (1.3-64) unstable; urgency=low + + * apply minfo api change + * Git: slp-source.sec.samsung.net:slp/pkgs/u/ug-image-viewer-efl.git + * Tag: ug-image-viewer-efl_1.3-64 + + -- Jisung Ahn Wed, 02 Nov 2011 16:13:55 +0900 + +ug-image-viewer-efl (1.3-63) unstable; urgency=low + + * fix detail view effect, add scroll bar + * Git: slp-source.sec.samsung.net:slp/pkgs/u/ug-image-viewer-efl.git + * Tag: ug-image-viewer-efl_1.3-63 + + -- Jisung Ahn Mon, 31 Oct 2011 20:58:30 +0900 + +ug-image-viewer-efl (1.3-62) unstable; urgency=low + + * fix share popup at web album, fix click event duration + * Git: slp-source.sec.samsung.net:slp/pkgs/u/ug-image-viewer-efl.git + * Tag: ug-image-viewer-efl_1.3-62 + + -- Jisung Ahn Mon, 31 Oct 2011 18:03:57 +0900 + +ug-image-viewer-efl (1.3-61) unstable; urgency=low + + * change appsvc to ug, fix web download, fix add tag view max length effect + * Git: slp-source.sec.samsung.net:slp/pkgs/u/ug-image-viewer-efl.git + * Tag: ug-image-viewer-efl_1.3-61 + + -- Jisung Ahn Thu, 27 Oct 2011 15:38:52 +0900 + +ug-image-viewer-efl (1.3-60) unstable; urgency=low + + * Fix details issue launch from myfile and adjust details view layout + * Git: slp-source.sec.samsung.net:slp/pkgs/u/ug-image-viewer-efl.git + * Tag: ug-image-viewer-efl_1.3-60 + + -- Jisung Ahn Wed, 26 Oct 2011 13:02:01 +0900 + +ug-image-viewer-efl (1.3-59) unstable; urgency=low + + * fix BS while destroying, fix bundle value at allshare video + * Git: slp-source.sec.samsung.net:slp/pkgs/u/ug-image-viewer-efl.git + * Tag: ug-image-viewer-efl_1.3-59 + + -- Jisung Ahn Tue, 25 Oct 2011 16:53:42 +0900 + +ug-image-viewer-efl (1.3-58) unstable; urgency=low + + * get application list from appsvc at share + * Git: slp-source.sec.samsung.net:slp/pkgs/u/ug-image-viewer-efl.git + * Tag: ug-image-viewer-efl_1.3-58 + + -- Jisung Ahn Mon, 24 Oct 2011 14:34:34 +0900 + +ug-image-viewer-efl (1.3-57) unstable; urgency=low + + * Fix scissorbox issue & implement new details view + * Git: slp-source.sec.samsung.net:slp/pkgs/u/ug-image-viewer-efl.git + * Tag: ug-image-viewer-efl_1.3-57 + + -- Li Suxia Sat, 22 Oct 2011 10:37:43 +0800 + +ug-image-viewer-efl (1.3-56) unstable; urgency=low + + * send result to caller when file type not supported + * Git: slp-source.sec.samsung.net:slp/pkgs/u/ug-image-viewer-efl.git + * Tag: ug-image-viewer-efl_1.3-56 + + -- Jisung Ahn Wed, 19 Oct 2011 17:51:23 +0900 + +ug-image-viewer-efl (1.3-55) unstable; urgency=low + + * fix UI bug + * Git: slp-source.sec.samsung.net:slp/pkgs/u/ug-image-viewer-efl.git + * Tag: ug-image-viewer-efl_1.3-55 + + -- Jisung Ahn Tue, 18 Oct 2011 13:48:30 +0900 + +ug-image-viewer-efl (1.3-54) unstable; urgency=low + + * update scissor box when rotated, update set as view + * Git: slp-source.sec.samsung.net:slp/pkgs/u/ug-image-viewer-efl.git + * Tag: ug-image-viewer-efl_1.3-54 + + -- Jisung Ahn Thu, 13 Oct 2011 20:31:20 +0900 + +ug-image-viewer-efl (1.3-53) unstable; urgency=low + + * add trim menu at video file + * Git: slp-source.sec.samsung.net:slp/pkgs/u/ug-image-viewer-efl.git + * Tag: ug-image-viewer-efl_1.3-53 + + -- Jisung Ahn Wed, 12 Oct 2011 21:10:51 +0900 + +ug-image-viewer-efl (1.3-52) unstable; urgency=low + + * slide show end when flicked + * Git: slp-source.sec.samsung.net:slp/pkgs/u/ug-image-viewer-efl.git + * Tag: ug-image-viewer-efl_1.3-52 + + -- Jisung Ahn Tue, 11 Oct 2011 22:48:19 +0900 + +ug-image-viewer-efl (1.3-51) unstable; urgency=low + + * fix CQ and bug + * Git: slp-source.sec.samsung.net:slp/pkgs/u/ug-image-viewer-efl.git + * Tag: ug-image-viewer-efl_1.3-51 + + -- Jisung Ahn Tue, 11 Oct 2011 21:17:37 +0900 + +ug-image-viewer-efl (1.3-50) unstable; urgency=low + + * fix UI + * Git: slp-source.sec.samsung.net:slp/pkgs/u/ug-image-viewer-efl.git + * Tag: ug-image-viewer-efl_1.3-50 + + -- Jisung Ahn Tue, 11 Oct 2011 12:59:59 +0900 + +ug-image-viewer-efl (1.3-49) unstable; urgency=low + + * apply HD GUI, navi frame + * Git: slp-source.sec.samsung.net:slp/pkgs/u/ug-image-viewer-efl.git + * Tag: ug-image-viewer-efl_1.3-49 + + -- Jisung Ahn Mon, 10 Oct 2011 20:11:32 +0900 + +ug-image-viewer-efl (1.3-48) unstable; urgency=low + + * apply app service twitter, picasa + * Git: slp-source.sec.samsung.net:slp/pkgs/u/ug-image-viewer-efl.git + * Tag: ug-image-viewer-efl_1.3-48 + + -- Jisung Ahn Thu, 06 Oct 2011 19:42:59 +0900 + +ug-image-viewer-efl (1.3-47) unstable; urgency=low + + * change save view to save popup + * Git: slp-source.sec.samsung.net:slp/pkgs/u/ug-image-viewer-efl.git + * Tag: ug-image-viewer-efl_1.3-47 + + -- Jisung Ahn Thu, 06 Oct 2011 13:39:58 +0900 + +ug-image-viewer-efl (1.3-46) unstable; urgency=low + + * fix Details view bug + * Git: slp-source.sec.samsung.net:slp/pkgs/u/ug-image-viewer-efl.git + * Tag: ug-image-viewer-efl_1.3-46 + + -- Jisung Ahn Wed, 05 Oct 2011 19:33:59 +0900 + +ug-image-viewer-efl (1.3-45) unstable; urgency=low + + * apply scale decoding and footstep, update slide show, fix bug + * Git: slp-source.sec.samsung.net:slp/pkgs/u/ug-image-viewer-efl.git + * Tag: ug-image-viewer-efl_1.3-45 + + -- Jisung Ahn Tue, 04 Oct 2011 20:14:35 +0900 + +ug-image-viewer-efl (1.3-44) unstable; urgency=low + + * apply allshare + * Git: slp-source.sec.samsung.net:slp/pkgs/u/ug-image-viewer-efl.git + * Tag: ug-image-viewer-efl_1.3-44 + + -- Jisung Ahn Fri, 30 Sep 2011 14:59:37 +0900 + +ug-image-viewer-efl (1.3-43) unstable; urgency=low + + * enable dissolve effect, footsteps, enter key + * Git: slp-source.sec.samsung.net:slp/pkgs/u/ug-image-viewer-efl.git + * Tag: ug-image-viewer-efl_1.3-43 + + -- Jisung Ahn Thu, 29 Sep 2011 14:17:09 +0900 + +ug-image-viewer-efl (1.3-42) unstable; urgency=low + + * code clean, change set as view GUI + * Git: slp-source.sec.samsung.net:slp/pkgs/u/ug-image-viewer-efl.git + * Tag: ug-image-viewer-efl_1.3-42 + + -- Jisung Ahn Thu, 22 Sep 2011 17:32:51 +0900 + +ug-image-viewer-efl (1.3-41) unstable; urgency=low + + * Fix minor GUI bugs. + * Git: slp-source.sec.samsung.net:slp/pkgs/u/ug-image-viewer-efl.git + * Tag: ug-image-viewer-efl_1.3-41 + + -- Hyunwoo Kim Mon, 19 Sep 2011 19:32:15 +0900 + +ug-image-viewer-efl (1.3-40) unstable; urgency=low + + * enable motion, prevent mouse event when destroy, enable scroll margin + * Git: slp-source.sec.samsung.net:slp/pkgs/u/ug-image-viewer-efl.git + * Tag: ug-image-viewer-efl_1.3-40 + + -- Jisung Ahn Sat, 17 Sep 2011 15:18:06 +0900 + +ug-image-viewer-efl (1.3-39) unstable; urgency=low + + * Disable any events just before terminate ug. + * Git: slp-source.sec.samsung.net:slp/pkgs/u/ug-image-viewer-efl.git + * Tag: ug-image-viewer-efl_1.3-39 + + -- Hyunwoo Kim Fri, 16 Sep 2011 22:35:07 +0900 + +ug-image-viewer-efl (1.3-38) unstable; urgency=low + + * Remove copy popup when flicking. + * Apply new GUI guide + * Git: slp-source.sec.samsung.net:slp/pkgs/u/ug-image-viewer-efl.git + * Tag: ug-image-viewer-efl_1.3-38 + + -- Hyunwoo Kim Fri, 16 Sep 2011 18:23:03 +0900 + +ug-image-viewer-efl (1.3-37) unstable; urgency=low + + * Upload for verification + * Git: slp-source.sec.samsung.net:slp/pkgs/u/ug-image-viewer-efl.git + * Tag: ug-image-viewer-efl_1.3-37 + + -- Jisung Ahn Thu, 15 Sep 2011 19:51:59 +0900 + +ug-image-viewer-efl (1.3-36) unstable; urgency=low + + * Fix issue thoat file_unset is not called sometimes + * Popup shows longer when setting wallpaper + * Git: slp-source.sec.samsung.net:slp/pkgs/u/ug-image-viewer-efl.git + * Tag: ug-image-viewer-efl_1.3-36 + + -- Jisung Ahn Wed, 14 Sep 2011 12:44:12 +0900 + +ug-image-viewer-efl (1.3-35) unstable; urgency=low + + * fix minor BUG + * Git: slp-source.sec.samsung.net:slp/pkgs/u/ug-image-viewer-efl.git + * Tag: ug-image-viewer-efl_1.3-35 + + -- Jisung Ahn Fri, 09 Sep 2011 20:46:13 +0900 + +ug-image-viewer-efl (1.3-34) unstable; urgency=low + + * modify zoom, UI, set as exif + * Git: slp-source.sec.samsung.net:slp/pkgs/u/ug-image-viewer-efl.git + * Tag: ug-image-viewer-efl_1.3-34 + + -- Jisung Ahn Fri, 09 Sep 2011 14:55:33 +0900 + +ug-image-viewer-efl (1.3-33) unstable; urgency=low + + * Implement tap zoom + * Git: slp-source.sec.samsung.net:slp/pkgs/u/ug-image-viewer-efl.git + * Tag: ug-image-viewer-efl_1.3-33 + + -- Jisung Ahn Thu, 08 Sep 2011 16:44:19 +0900 + +ug-image-viewer-efl (1.3-32) unstable; urgency=low + + * include image-vewer-ext-engine only armel build + * Git: slp-source.sec.samsung.net:slp/pkgs/u/ug-image-viewer-efl.git + * Tag: ug-image-viewer-efl_1.3-32 + + -- Jisung Ahn Wed, 07 Sep 2011 20:58:41 +0900 + +ug-image-viewer-efl (1.3-31) unstable; urgency=low + + * add dependency image-viewer-ext-engine + * Git: slp-source.sec.samsung.net:slp/pkgs/u/ug-image-viewer-efl.git + * Tag: ug-image-viewer-efl_1.3-31 + + -- Jisung Ahn Wed, 07 Sep 2011 19:45:13 +0900 + +ug-image-viewer-efl (1.3-30) unstable; urgency=low + + * disable allshare + * Git: slp-source.sec.samsung.net:slp/pkgs/u/ug-image-viewer-efl.git + * Tag: ug-image-viewer-efl_1.3-30 + + -- Jisung Ahn Fri, 02 Sep 2011 15:06:18 +0900 + +ug-image-viewer-efl (1.3-29) unstable; urgency=low + + * update changelog + * Git: slp-source.sec.samsung.net:slp/pkgs/u/ug-image-viewer-efl.git + * Tag: ug-image-viewer-efl_1.3-29 + + -- Jisung Ahn Wed, 31 Aug 2011 20:06:40 +0900 + +ug-image-viewer-efl (1.3-28) unstable; urgency=low + + * avoid appsvc bug + * Git: slp-source.sec.samsung.net:slp/pkgs/u/ug-image-viewer-efl.git + * Tag: ug-image-viewer-efl_1.3-28 + + -- Jisung Ahn Wed, 31 Aug 2011 14:58:02 +0900 + +ug-image-viewer-efl (1.3-27) unstable; urgency=low + + * prepare source open + * Git: slp-source.sec.samsung.net:slp/pkgs/u/ug-image-viewer-efl.git + * Tag: ug-image-viewer-efl_1.3-27 + + -- Jisung Ahn Tue, 30 Aug 2011 15:01:55 +0900 + +ug-image-viewer-efl (1.3-26) unstable; urgency=low + + * apply DRM image operation + * Git: slp-source.sec.samsung.net:slp/pkgs/u/ug-image-viewer-efl.git + * Tag: ug-image-viewer-efl_1.3-26 + + -- Jisung Ahn Wed, 17 Aug 2011 20:14:44 +0900 + +ug-image-viewer-efl (1.3-25) unstable; urgency=low + + * apply agif, remove widget type, add margin,, apply pm api + * Git: slp-source.sec.samsung.net:slp/pkgs/u/ug-image-viewer-efl.git + * Tag: ug-image-viewer-efl_1.3-25 + + -- Jisung Ahn Tue, 16 Aug 2011 20:08:24 +0900 + +ug-image-viewer-efl (1.3-24) unstable; urgency=low + + * fix BS when copy popup at web image + * Git: slp-source.sec.samsung.net:slp/pkgs/u/ug-image-viewer-efl.git + * Tag: ug-image-viewer-efl_1.3-24 + + -- Jisung Ahn Fri, 05 Aug 2011 11:27:33 +0900 + +ug-image-viewer-efl (1.3-23) unstable; urgency=low + + * Fix B/S when delete item in 2 items + * Git: slp-source.sec.samsung.net:slp/pkgs/u/ug-image-viewer-efl.git + * Tag: ug-image-viewer-efl_1.3-23 + + -- Jisung Ahn Thu, 04 Aug 2011 21:04:55 +0900 + +ug-image-viewer-efl (1.3-22) unstable; urgency=low + + * Fix B/S when delete item in myfile + * Git: slp-source.sec.samsung.net:slp/pkgs/u/ug-image-viewer-efl.git + * Tag: ug-image-viewer-efl_1.3-22 + + -- Hyunwoo Kim Thu, 04 Aug 2011 17:52:27 +0900 + +ug-image-viewer-efl (1.3-21) unstable; urgency=low + + * Ctrl bar is disabled during downloading. + * Change internal slider APIs + * Bug fixed that cannot get next item when flick continously. + * Implement details view + * Git: slp-source.sec.samsung.net:slp/pkgs/u/ug-image-viewer-efl.git + * Tag: ug-image-viewer-efl_1.3-21 + + -- Hyunwoo Kim Tue, 02 Aug 2011 20:27:02 +0900 + +ug-image-viewer-efl (1.3-20) unstable; urgency=low + + * fix save view bug + * Git: slp-source.sec.samsung.net:slp/pkgs/u/ug-image-viewer-efl + * Tag: ug-image-viewer-efl_1.3-20 + + -- Jisung Ahn Thu, 28 Jul 2011 20:08:08 +0900 + +ug-image-viewer-efl (1.3-19) unstable; urgency=low + + * code refactoring + * Git: slp-source.sec.samsung.net:slp/pkgs/u/ug-image-viewer-efl + * Tag: ug-image-viewer-efl_1.3-19 + + -- Jisugn Ahn Tue, 26 Jul 2011 20:23:05 +0900 + +ug-image-viewer-efl (1.3-18) unstable; urgency=low + + * fix control bar, button style, shuffle, Eina_Bool + * Git: slp-source.sec.samsung.net:slp/pkgs/u/ug-image-viewer-efl + * Tag: ug-image-viewer-efl_1.3-18 + + -- Jisung Ahn Fri, 22 Jul 2011 18:05:16 +0900 + +ug-image-viewer-efl (1.3-17) unstable; urgency=low + + * fix emulator BS + * Git: slp-source.sec.samsung.net:slp/pkgs/u/ug-image-viewer-efl + * Tag: ug-image-viewer-efl_1.3-17 + + -- Jisung Ahn Thu, 21 Jul 2011 21:54:32 +0900 + +ug-image-viewer-efl (1.3-16) unstable; urgency=low + + * apply new slide show + * Git: slp-source.sec.samsung.net:slp/pkgs/u/ug-image-viewer-efl + * Tag: ug-image-viewer-efl_1.3-16 + + -- Jisung Ahn Thu, 21 Jul 2011 19:50:17 +0900 + +ug-image-viewer-efl (1.3-15) unstable; urgency=low + + * apply transition effect + * Git: slp-source.sec.samsung.net:slp/pkgs/u/ug-image-viewer-efl + * Tag: ug-image-viewer-efl_1.3-15 + + -- Jisung Ahn Wed, 20 Jul 2011 17:54:45 +0900 + +ug-image-viewer-efl (1.3-14) unstable; urgency=low + + * fix build error, rotate error + * Git: slp-source.sec.samsung.net:slp/pkgs/u/ug-image-viewer-efl + * Tag: ug-image-viewer-efl_1.3-14 + + -- Jisung Ahn Mon, 11 Jul 2011 22:07:52 +0900 + +ug-image-viewer-efl (1.3-13) unstable; urgency=low + + * ImageViewer is terminated when MMC is removed. + * Add tag view is refined + * Git: slp-source.sec.samsung.net:slp/pkgs/u/ug-image-viewer-efl + * Tag: ug-image-viewer-efl_1.3-13 + + -- Hyunwoo Kim Thu, 07 Jul 2011 19:43:59 +0900 + +ug-image-viewer-efl (1.3-12) unstable; urgency=low + + * fix cq, scissor box, svace + * Git: slp-source.sec.samsung.net:slp/pkgs/u/ug-image-viewer-efl + * Tag: ug-image-viewer-efl_1.3-12 + + -- Jisung Ahn Mon, 04 Jul 2011 20:14:32 +0900 + +ug-image-viewer-efl (1.3-11) unstable; urgency=low + + * apply all share, fix delete BS + * Git: slp-source.sec.samsung.net:slp/pkgs/u/ug-image-viewer-efl + * Tag: ug-image-viewer-efl_1.3-11 + + -- Jisung Ahn Fri, 01 Jul 2011 19:17:02 +0900 + +ug-image-viewer-efl (1.3-10) unstable; urgency=low + + * apply window loading + * Git: slp-source.sec.samsung.net:slp/pkgs/u/ug-image-viewer-efl + * Tag: ug-image-viewer-efl_1.3-10 + + -- Jisung Ahn Wed, 29 Jun 2011 20:16:35 +0900 + +ug-image-viewer-efl (1.3-09) unstable; urgency=low + + * Fixed CQ + * Implement mouse event handler. + * Git: slp-source.sec.samsung.net:slp/pkgs/u/ug-image-viewer-efl + * Tag: ug-image-viewer-efl_1.3-09 + + -- Hyunwoo Kim Tue, 28 Jun 2011 10:47:43 +0900 + +ug-image-viewer-efl (1.3-08) unstable; urgency=low + + * Remove dependancy between ugd and other view. + * Fix prevents bug + * Support for multi instance + * Refactoring SetAs View + * Git: slp-source.sec.samsung.net:slp/pkgs/u/ug-image-viewer-efl + * Tag: ug-image-viewer-efl_1.3-08 + + -- Hyunwoo Kim Fri, 24 Jun 2011 19:37:35 +0900 + +ug-image-viewer-efl (1.3-07) unstable; urgency=low + + * Upload for CQ defects fix, reupload + * Git: slp-source.sec.samsung.net:slp/pkgs/u/ug-image-viewer-efl + * Tag: ug-image-viewer-efl_1.3-07 + + -- Li Suxia Wed, 22 Jun 2011 16:22:26 +0800 + +ug-image-viewer-efl (1.3-06) lucid; urgency=low + + * Upload for CQ defects fix + * Git: slp-source.sec.samsung.net:slp/pkgs/u/ug-image-viewer-efl + * Tag: ug-image-viewer-efl_1.3-06 + + -- Li Suxia Wed, 22 Jun 2011 14:56:26 +0800 + +ug-image-viewer-efl (1.3-05) unstable; urgency=low + + * Improvement pinch zoom algorithm. + * Decrease animation time from 500ms to 200ms + * Git: slp-source.sec.samsung.net:slp/pkgs/u/ug-image-viewer-efl + * Tag: ug-image-viewer-efl_1.3-05 + + -- Hyunwoo Kim Tue, 14 Jun 2011 15:50:33 +0900 + +ug-image-viewer-efl (1.3-04) unstable; urgency=low + + * apply sns finalize + * Git: slp-source.sec.samsung.net:slp/pkgs/u/ug-image-viewer-efl + * Tag: ug-image-viewer-efl_1.3-04 + + -- Jisung Ahn Wed, 08 Jun 2011 15:34:25 +0900 + +ug-image-viewer-efl (1.3-03) unstable; urgency=low + + * update changelog + * Git: slp-source.sec.samsung.net:slp/pkgs/u/ug-image-viewer-efl + * Tag: ug-image-viewer-efl_1.3-03 + + -- Jisung Ahn Wed, 08 Jun 2011 14:18:52 +0900 + +ug-image-viewer-efl (1.3-02) unstable; urgency=low + + * update changelog + * Git: slp-source.sec.samsung.net:slp/pkgs/u/ug-image-viewer-efl + * Tag: ug-image-viewer-efl_1.3-02 + + -- Jisung Ahn Fri, 03 Jun 2011 19:00:26 +0900 + +ug-image-viewer-efl (1.3-01) unstable; urgency=low + + * Fix bug that video file does not flicked. + * Git: slp-source.sec.samsung.net:slp/pkgs/u/ug-image-viewer-efl + * Tag: ug-image-viewer-efl_1.3-01 + + -- Hyunwoo Kim Thu, 02 Jun 2011 09:51:42 +0900 + +ug-image-viewer-efl (1.3-00) unstable; urgency=low + + * Refactoring slide item + * Git: slp-source.sec.samsung.net:slp/pkgs/u/ug-image-viewer-efl + * Tag: ug-image-viewer-efl_1.3-00 + + -- Jisung ahn Thu, 02 Jun 2011 09:51:42 +0900 + +ug-image-viewer-efl (1.2-12) unstable; urgency=low + + * fix control bar, block sns finalize, add test program, fix crop bug + * Git: slp-source.sec.samsung.net:slp/pkgs/u/ug-image-viewer-efl + * Tag: ug-image-viewer-efl_1.2-12 + + -- Jisung Ahn Wed, 01 Jun 2011 21:29:06 +0900 + +ug-image-viewer-efl (1.2-11) unstable; urgency=low + + * code clean, fix bs, rotate bug + * Git: slp-source.sec.samsung.net:slp/pkgs/u/ug-image-viewer-efl + * Tag: ug-image-viewer-efl_1.2-11 + + -- Jisung ahn Mon, 30 May 2011 20:48:29 +0900 + +ug-image-viewer-efl (1.2-10) unstable; urgency=low + + * fix bug, apply setas view click event + * Git: slp-source.sec.samsung.net:slp/pkgs/u/ug-image-viewer-efl + * Tag: ug-image-viewer-efl_1.2-10 + + -- Jisung Ahn Thu, 26 May 2011 20:56:01 +0900 + +ug-image-viewer-efl (1.2-9) unstable; urgency=low + + * mouse event change ecore to evas, popup style change + * Git: slp-source.sec.samsung.net:slp/pkgs/u/ug-image-viewer-efl + * Tag: ug-image-viewer-efl_1.2-9 + + -- Jisung Ahn Wed, 25 May 2011 19:34:02 +0900 + +ug-image-viewer-efl (1.2-8) unstable; urgency=low + + * fix icon, drm problem, warning, etc... + * Git: slp-source.sec.samsung.net:slp/pkgs/u/ug-image-viewer-efl + * Tag: ug-image-viewer-efl_1.2-8 + + -- Jisung Ahn Tue, 24 May 2011 16:27:54 +0900 + +ug-image-viewer-efl (1.2-7) unstable; urgency=low + + * Block exif + * Git: slp-source.sec.samsung.net:slp/pkgs/u/ug-image-viewer-efl + * Tag: ug-image-viewer-efl_1.2-7 + + -- Jisung Ahn Tue, 24 May 2011 11:44:09 +0900 + +ug-image-viewer-efl (1.2-6) unstable; urgency=low + + * Fix string issue, and update list issue + * Git: slp-source.sec.samsung.net:slp/pkgs/u/ug-image-viewer-efl + * Tag: ug-image-viewer-efl_1.2-6 + + -- Li Suxia Tue, 24 May 2011 10:35:04 +0800 + +ug-image-viewer-efl (1.2-5) unstable; urgency=low + + * fixed black screen when web image resume + * Git: slp-source.sec.samsung.net:slp/pkgs/u/ug-image-viewer-efl + * Tag: ug-image-viewer-efl_1.2-5 + + -- DongJin Choi Thu, 19 May 2011 17:50:32 +0900 + +ug-image-viewer-efl (1.2-4) unstable; urgency=low + + * updated changelog. fix installation error + * Git: slp-source.sec.samsung.net:slp/pkgs/u/ug-image-viewer-efl + * Tag: ug-image-viewer-efl_1.2-4 + + -- DongJin Choi Thu, 19 May 2011 12:43:10 +0900 + +ug-image-viewer-efl (1.2-3) unstable; urgency=low + + * updated changelog + * Git: slp-source.sec.samsung.net:slp/pkgs/u/ug-image-viewer-efl + * Tag: ug-image-viewer-efl_1.2-3 + + -- DongJin Choi Thu, 19 May 2011 12:15:30 +0900 + +ug-image-viewer-efl (1.2-2) unstable; urgency=low + + * updated changelog + * Git: slp-source.sec.samsung.net:slp/pkgs/u/ug-image-viewer-efl + * Tag: ug-image-viewer-efl_1.2-2 + + -- DongJin Choi Thu, 19 May 2011 11:50:30 +0900 + +ug-image-viewer-efl (1.2-1) unstable; urgency=low + + * changed media-svc to libmedia-info + * removed elm_priv.h + * inserted bundle key for video player + * modified myphotocam mouse event + * Git: slp-source.sec.samsung.net:slp/pkgs/u/ug-image-viewer-efl + * Tag: ug-image-viewer-efl_1.2-1 + + -- DongJin Choi Wed, 18 May 2011 16:51:19 +0900 + +ug-image-viewer-efl (1.2-00) unstable; urgency=low + + * Change directory structures + * Git: slp-source.sec.samsung.net:slp/pkgs/u/ug-image-viewer-efl + * Tag: ug-image-viewer-efl_1.2-00 + + -- Hyunwoo Kim Wed, 18 May 2011 11:03:04 +0900 + +ug-image-viewer-efl (1.1-38) unstable; urgency=low + + * fixed black screen error, improvement image viewer loading time, fixed + some bug + * Git: slp-source.sec.samsung.net:slp/pkgs/u/ug-image-viewer-efl + * Tag: ug-image-viewer-efl_1.1-38 + + -- Li Suxia Wed, 18 May 2011 10:52:02 +0900 + +ug-image-viewer-efl (1.1-37) unstable; urgency=low + + * Fix delete & tag message + * Git: slp-source.sec.samsung.net:slp/pkgs/u/ug-image-viewer-efl + * Tag: ug-image-viewer-efl_1.1-37 + + -- Li Suxia Thu, 12 May 2011 21:44:41 +0800 + +ug-image-viewer-efl (1.1-36) unstable; urgency=low + + * fixed BS + * Git: slp-source.sec.samsung.net:slp/pkgs/u/ug-image-viewer-efl + * Tag: ug-image-viewer-efl_1.1-36 + + -- DongJin Choi Thu, 12 May 2011 21:11:10 +0900 + +ug-image-viewer-efl (1.1-35) unstable; urgency=low + + * Upload again + * Git: slp-source.sec.samsung.net:slp/pkgs/u/ug-image-viewer-efl + * Tag: ug-image-viewer-efl_1.1-35 + + -- Li Suxia Wed, 11 May 2011 14:14:11 +0800 + +ug-image-viewer-efl (1.1-34) unstable; urgency=low + + * Fix DRM issue & implement pause/resume + * Git: slp-source.sec.samsung.net:slp/pkgs/u/ug-image-viewer-efl + * Tag: ug-image-viewer-efl_1.1-34 + + -- Li Suxia Wed, 11 May 2011 11:24:11 +0800 + +ug-image-viewer-efl (1.1-33) unstable; urgency=low + + * changed sns-framework pkg name to social-service + * Git: slp-source.sec.samsung.net:slp/pkgs/u/ug-image-viewer-efl + * Tag: ug-image-viewer-efl_1.1-33 + + -- DongJin Choi Mon, 02 May 2011 20:06:10 +0900 + +ug-image-viewer-efl (1.1-32) unstable; urgency=low + + * Replace setas genlist with default + * Git: slp-source.sec.samsung.net:slp/pkgs/u/ug-image-viewer-efl + * Tag: ug-image-viewer-efl_1.1-32 + + -- LiSuxia Tue, 03 May 2011 20:25:10 +0800 + +ug-image-viewer-efl (1.1-31) unstable; urgency=low + + * disable animation GIF + * Git: slp-source.sec.samsung.net:slp/pkgs/u/ug-image-viewer-efl + * Tag: ug-image-viewer-efl_1.1-31 + + -- DongJin Choi Mon, 02 May 2011 20:06:10 +0900 + +ug-image-viewer-efl (1.1-30) unstable; urgency=low + + * inserted evas_norender function at exit image viewer UG + * Git: slp-source.sec.samsung.net:slp/pkgs/u/ug-image-viewer-efl + * Tag: ug-image-viewer-efl_1.1-30 + + -- DongJin Choi Mon, 02 May 2011 19:06:10 +0900 + +ug-image-viewer-efl (1.1-29) unstable; urgency=low + + * exit elm_photocam_file_set function when Animation gif loading error + * Git: slp-source.sec.samsung.net:slp/pkgs/u/ug-image-viewer-efl + * Tag: ug-image-viewer-efl_1.1-29 + + -- DongJin Choi Thu, 28 Apr 2011 20:21:11 +0900 + +ug-image-viewer-efl (1.1-28) unstable; urgency=low + + * changed macro name & updated calc_job function + * Git: slp-source.sec.samsung.net:slp/pkgs/u/ug-image-viewer-efl + * Tag: ug-image-viewer-efl_1.1-28 + + -- DongJin Choi Thu, 28 Apr 2011 16:28:10 +0900 + +ug-image-viewer-efl (1.1-27) unstable; urgency=low + + * fixed bulid break. + * Git: slp-source.sec.samsung.net:slp/pkgs/u/ug-image-viewer-efl + * Tag: ug-image-viewer-efl_1.1-27 + + -- DongJin Choi Thu, 28 Apr 2011 10:41:10 +0900 + +ug-image-viewer-efl (1.1-26) unstable; urgency=low + + * changed BT launch method & fixed some bug + * Git: slp-source.sec.samsung.net:slp/pkgs/u/ug-image-viewer-efl + * Tag: ug-image-viewer-efl_1.1-26 + + -- DongJin Choi Wed, 27 Apr 2011 21:07:30 +0900 + +ug-image-viewer-efl (1.1-25) unstable; urgency=low + + * Fix full build break + + -- Mike McCormack Wed, 27 Apr 2011 19:19:17 +0900 + +ug-image-viewer-efl (1.1-24) unstable; urgency=low + + * Add media-type support & fix issues: title, face detect + * Git: slp-source.sec.samsung.net:slp/pkgs/u/ug-image-viewer-efl + * Tag: ug-image-viewer-efl_1.1-24 + + -- Li Suxia Tue, 26 Apr 2011 17:14:31 +0800 + +ug-image-viewer-efl (1.1-23) unstable; urgency=low + + * fixed sizing error & fixed some bug + * Git: slp-source.sec.samsung.net:slp/pkgs/u/ug-image-viewer-efl + * Tag: ug-image-viewer-efl_1.1-23 + + -- DongJin Choi Mon, 25 Apr 2011 11:59:30 +0900 + +ug-image-viewer-efl (1.1-22) unstable; urgency=low + + * Fix issues on crop image + * Git: slp-source.sec.samsung.net:slp/pkgs/u/ug-image-viewer-efl + * Tag: ug-image-viewer-efl_1.1-22 + + -- Li Suxia Thu, 21 Apr 2011 19:14:33 +0800 + +ug-image-viewer-efl (1.1-21) unstable; urgency=low + + * fixed some error, changed snsfw name, inserted web album view function + * Git: slp-source.sec.samsung.net:slp/pkgs/u/ug-image-viewer-efl + * Tag: ug-image-viewer-efl_1.1-21 + + -- DongJin Choi Wed, 20 Apr 2011 21:01:30 +0800 + +ug-image-viewer-efl (1.1-20) unstable; urgency=low + + * Fix issue on destroy & modify controlbar option for video + * Git: slp-source.sec.samsung.net:slp/pkgs/u/ug-image-viewer-efl + * Tag: ug-image-viewer-efl_1.1-20 + + -- Li Suxia Wed, 20 Apr 2011 17:01:30 +0800 + +ug-image-viewer-efl (1.1-19) unstable; urgency=low + + * fixed error in caller id mode + * Git: slp-source.sec.samsung.net:slp/pkgs/u/ug-image-viewer-efl + * Tag: ug-image-viewer-efl_1.1-19 + + -- DongJin Choi Tue, 19 Apr 2011 23:57:39 +0900 + +ug-image-viewer-efl (1.1-18) unstable; urgency=low + + * Fix issue on destroy slider + * Git: slp-source.sec.samsung.net:slp/pkgs/u/ug-image-viewer-efl + * Tag: ug-image-viewer-efl_1.1-18 + + -- Li Suxia Tue, 19 Apr 2011 12:56:37 +0800 + +ug-image-viewer-efl (1.1-17) unstable; urgency=low + + * Dim option for video & DRM file + * Git: slp-source.sec.samsung.net:slp/pkgs/u/ug-image-viewer-efl + * Tag: ug-image-viewer-efl_1.1-17 + + -- Li Suxia Mon, 18 Apr 2011 17:11:14 +0800 + +ug-image-viewer-efl (1.1-16) unstable; urgency=low + + * re-upload + * Git: slp-source.sec.samsung.net:slp/pkgs/u/ug-image-viewer-efl + * Tag: ug-image-viewer-efl_1.1-16 + + -- DongJin Choi Fri, 15 Apr 2011 16:15:39 +0900 + +ug-image-viewer-efl (1.1-15) unstable; urgency=low + + * inserted tag option + * Git: slp-source.sec.samsung.net:slp/pkgs/u/ug-image-viewer-efl + * Tag: ug-image-viewer-efl_1.1-15 + + -- DongJin Choi Fri, 15 Apr 2011 14:22:39 +0900 + +ug-image-viewer-efl (1.1-14) unstable; urgency=low + + * fixed delete slide error + * Git: slp-source.sec.samsung.net:slp/pkgs/u/ug-image-viewer-efl + * Tag: ug-image-viewer-efl_1.1-14 + + -- DongJin Choi Fri, 15 Apr 2011 10:22:39 +0900 + +ug-image-viewer-efl (1.1-13) unstable; urgency=low + + * Reupload + * Git: slp-source.sec.samsung.net:slp/pkgs/u/ug-image-viewer-efl + * Tag: ug-image-viewer-efl_1.1-13 + + -- Li Suxia Thu, 14 Apr 2011 17:06:33 +0800 + +ug-image-viewer-efl (1.1-12) unstable; urgency=low + + * Fix popup bs & implement view by favourite + * Git: slp-source.sec.samsung.net:slp/pkgs/u/ug-image-viewer-efl + * Tag: ug-image-viewer-efl_1.1-12 + + -- Li Suxia Thu, 14 Apr 2011 18:58:33 +0800 + +ug-image-viewer-efl (1.1-11) lucid; urgency=low + + * Fix popup bs & implement view by favourite + * Git: slp-source.sec.samsung.net:slp/pkgs/u/ug-image-viewer-efl + * Tag: ug-image-viewer-efl_1.1-11 + + -- Li Suxia Thu, 14 Apr 2011 18:45:26 +0800 + +ug-image-viewer-efl (1.1-10) unstable; urgency=low + + * fixed display mode error + * Git: slp-source.sec.samsung.net:slp/pkgs/u/ug-image-viewer-efl + * Tag: ug-image-viewer-efl_1.1-10 + + -- DongJin Choi Thu, 14 Apr 2011 17:59:39 +0900 + +ug-image-viewer-efl (1.1-9) unstable; urgency=low + + * reupload image ug, because snsfw, updated changed log + * Git: slp-source.sec.samsung.net:slp/pkgs/u/ug-image-viewer-efl + * Tag: ug-image-viewer-efl_1.1-9 + + -- DongJin Choi Tue, 12 Apr 2011 16:12:39 +0900 + +ug-image-viewer-efl (1.1-8) unstable; urgency=low + + * fixed build break + * Git: slp-source.sec.samsung.net:slp/pkgs/u/ug-image-viewer-efl + * Tag: ug-image-viewer-efl_1.1-8 + + -- DongJin Choi Tue, 12 Apr 2011 16:12:39 +0900 + +ug-image-viewer-efl (1.1-7) unstable; urgency=low + + * fixed build break , wink, face detection engine + * Git: slp-source.sec.samsung.net:slp/pkgs/u/ug-image-viewer-efl + * Tag: ug-image-viewer-efl_1.1-6 + + -- DongJin Choi Tue, 12 Apr 2011 10:04:39 +0900 + +ug-image-viewer-efl (1.1-6) unstable; urgency=low + + * fixed build break in i386 + * Git: slp-source.sec.samsung.net:slp/pkgs/u/ug-image-viewer-efl + * Tag: ug-image-viewer-efl_1.1-6 + + -- DongJin Choi Tue, 12 Apr 2011 09:44:19 +0900 + +ug-image-viewer-efl (1.1-5) unstable; urgency=low + + * fixed build break i386 + * Git: slp-source.sec.samsung.net:slp/pkgs/u/ug-image-viewer-efl + * Tag: ug-image-viewer-efl_1.1-5 + + -- DongJin Choi Tue, 12 Apr 2011 08:41:26 +0900 + +ug-image-viewer-efl (1.1-4) unstable; urgency=low + + * fixed build break i386 + * Git: slp-source.sec.samsung.net:slp/pkgs/u/ug-image-viewer-efl + * Tag: ug-image-viewer-efl_1.1-4 + + -- DongJin Choi Tue, 12 Apr 2011 07:50:28 +0900 + +ug-image-viewer-efl (1.1-3) unstable; urgency=low + + * fixed build break + * Git: slp-source.sec.samsung.net:slp/pkgs/u/ug-image-viewer-efl + * Tag: ug-image-viewer-efl_1.1-3 + + -- DongJin Choi Tue, 12 Apr 2011 07:33:26 +0900 + +ug-image-viewer-efl (1.1-2) unstable; urgency=low + + * fixed build break + * Git: slp-source.sec.samsung.net:slp/pkgs/u/ug-image-viewer-efl + * Tag: ug-image-viewer-efl_1.1-2 + + -- DongJin Choi Mon, 11 Apr 2011 22:04:17 +0900 + +ug-image-viewer-efl (1.1-1) unstable; urgency=low + + * enable new image viewer + * Git: slp-source.sec.samsung.net:slp/pkgs/u/ug-image-viewer-efl + * Tag: ug-image-viewer-efl_1.1-1 + + -- DongJin Choi Mon, 11 Apr 2011 20:44:49 +0900 + +ug-image-viewer-efl (1.0-182) unstable; urgency=low + + * remove deprecated api of ctxpopup + * Git: slp-source.sec.samsung.net:slp/pkgs/u/ug-image-viewer-efl + * Tag: ug-image-viewer-efl_1.0-182 + + -- DongJin Choi Thu, 07 Apr 2011 21:00:26 +0900 + +ug-image-viewer-efl (1.0-181) unstable; urgency=low + + * updated changelog + * Git: slp-source.sec.samsung.net:slp/pkgs/u/ug-image-viewer-efl + * Tag: ug-image-viewer-efl_1.0-181 + + -- Li Suxia Sat, 02 Apr 2011 10:22:15 +0900 + +ug-image-viewer-efl (1.0-180) unstable; urgency=low + + * updated changelog + * Git: slp-source.sec.samsung.net:slp/pkgs/u/ug-image-viewer-efl + * Tag: ug-image-viewer-efl_1.0-180 + + -- Li Suxia Thu, 24 Mar 2011 14:15:06 +0900 + +ug-image-viewer-efl (1.0-179) unstable; urgency=low + + * updated changelog + * Git: slp-source.sec.samsung.net:slp/pkgs/u/ug-image-viewer-efl + * Tag: ug-image-viewer-efl_1.0-179 + + -- Li Suxia Tue, 22 Mar 2011 13:54:33 +0900 + +ug-image-viewer-efl (1.0-178) unstable; urgency=low + + * updated changelog + * Git: slp-source.sec.samsung.net:slp/pkgs/u/ug-image-viewer-efl + * Tag: ug-image-viewer-efl_1.0-178 + + -- Li Suxia Mon, 21 Mar 2011 21:39:52 +0900 + +ug-image-viewer-efl (1.0-176) unstable; urgency=low + + * updated changelog + * Git: slp-source.sec.samsung.net:slp/pkgs/u/ug-image-viewer-efl + * Tag: ug-image-viewer-efl_1.0-176 + + -- DongJin Choi Fri, 18 Mar 2011 11:28:22 +0900 + +ug-image-viewer-efl (1.0-175) unstable; urgency=low + + * fixed BS + * Git: slp-source.sec.samsung.net:slp/pkgs/u/ug-image-viewer-efl + * Tag: ug-image-viewer-efl_1.0-175 + + -- DongJin Choi Fri, 18 Mar 2011 11:05:58 +0900 + +ug-image-viewer-efl (1.0-174) unstable; urgency=low + + * inserted image-viewer base photocam + * Git: slp-source.sec.samsung.net:slp/pkgs/u/ug-image-viewer-efl + * Tag: ug-image-viewer-efl_1.0-174 + + -- DongJin Choi Tue, 15 Mar 2011 09:46:46 +0900 + +ug-image-viewer-efl (1.0-173) unstable; urgency=low + + * modify snsfw api return value. + * Git: slp-source.sec.samsung.net:slp/pkgs/u/ug-image-viewer-efl + * Tag: ug-image-viewer-efl_1.0-173 + + -- DongJin Choi Mon, 14 Mar 2011 15:55:13 +0900 + +ug-image-viewer-efl (1.0-172) unstable; urgency=low + + * updated changelog + * Git: slp-source.sec.samsung.net:slp/pkgs/u/ug-image-viewer-efl + * Tag: ug-image-viewer-efl_1.0-172 + + -- DongJin Choi Thu, 10 Mar 2011 19:59:20 +0900 + +ug-image-viewer-efl (1.0-171) unstable; urgency=low + + * remove sns framework wrong used code. + * Git: slp-source.sec.samsung.net:slp/pkgs/u/ug-image-viewer-efl + * Tag: ug-image-viewer-efl_1.0-171 + + -- DongJin Choi Thu, 10 Mar 2011 18:58:32 +0900 + +ug-image-viewer-efl (1.0-170) unstable; urgency=low + + * Upload again. + * Git: slp-source.sec.samsung.net:slp/pkgs/u/ug-image-viewer-efl + * Tag: ug-image-viewer-efl_1.0-170 + + -- Li Suxia Thu, 10 Mar 2011 09:23:50 +0900 + +ug-image-viewer-efl (1.0-169) unstable; urgency=low + + * Update git info. + * Git: slp-source.sec.samsung.net:slp/pkgs/u/ug-image-viewer-efl + * Tag: ug-image-viewer-efl_1.0-169 + + -- Li Suxia Wed, 09 Mar 2011 19:57:27 +0900 + +ug-image-viewer-efl (1.0-168) unstable; urgency=low + + * Update changelog again + * Git: slp-source.sec.samsung.net:slp/pkgs/u/ug-image-viewer-efl + * Tag: ug-image-viewer-efl_1.0-168 + + -- Li Suxia Wed, 09 Mar 2011 19:01:06 +0900 + +ug-image-viewer-efl (1.0-167) unstable; urgency=low + + * update changelog & add stat. + * Git: slp-source.sec.samsung.net:slp/pkgs/u/ug-image-viewer-efl + * Tag: ug-image-viewer-efl_1.0-167 + + -- Li Suxia Wed, 09 Mar 2011 14:46:18 +0900 + +ug-image-viewer-efl (1.0-166) unstable; urgency=low + + * change sns launch method aul -> ug. + * Git: slp-source.sec.samsung.net:slp/pkgs/u/ug-image-viewer-efl + * Tag: ug-image-viewer-efl_1.0-166 + + -- DongJin Choi Tue, 08 Mar 2011 10:43:07 +0900 + +ug-image-viewer-efl (1.0-165) unstable; urgency=low + + * Update changelog + * Git: slp-source.sec.samsung.net:slp/pkgs/u/ug-image-viewer-efl + * Tag: ug-image-viewer-efl_1.0-165 + + -- Li Suxia Fri, 04 Mar 2011 15:41:03 +0900 + +ug-image-viewer-efl (1.0-164) unstable; urgency=low + + * updated changelog + * Git: slp-source.sec.samsung.net:slp/pkgs/u/ug-image-viewer-efl + * Tag: ug-image-viewer-efl_1.0-164 + + -- DongJin Choi Mon, 28 Feb 2011 21:05:38 +0900 + +ug-image-viewer-efl (1.0-163) unstable; urgency=low + + * updated changelog + * Git: slp-source.sec.samsung.net:slp/pkgs/u/ug-image-viewer-efl + * Tag: ug-image-viewer-efl_1.0-163 + + -- Li Suxia Mon, 28 Feb 2011 21:03:30 +0900 + +ug-image-viewer-efl (1.0-162) unstable; urgency=low + + * fixed web download image problem. + * Git: slp-source.sec.samsung.net:slp/pkgs/u/ug-image-viewer-efl + * Tag: ug-image-viewer-efl_1.0-162 + + -- Li Suxia Mon, 28 Feb 2011 20:25:45 +0900 + +ug-image-viewer-efl (1.0-161) unstable; urgency=low + + * Apply new UI for setas wallpaper + * Git: slp-source.sec.samsung.net:slp/pkgs/u/ug-image-viewer-efl + * Tag: ug-image-viewer-efl_1.0-161 + + -- Li Suxia Fri, 25 Feb 2011 16:36:41 +0800 + +ug-image-viewer-efl (1.0-160) unstable; urgency=low + + * Fix pause/resume issue for win rotate + * Git: slp-source.sec.samsung.net:slp/pkgs/u/ug-image-viewer-efl + * Tag: ug-image-viewer-efl_1.0-160 + + -- Li Suxia Wed, 23 Feb 2011 17:55:26 +0800 + +ug-image-viewer-efl (1.0-159) unstable; urgency=low + + * fixed some CQ, crash log + * Git: slp-source.sec.samsung.net:slp/pkgs/u/ug-image-viewer-efl + * Tag: ug-image-viewer-efl_1.0-159 + + -- DongJin Choi Tue, 22 Feb 2011 20:12:27 +0900 + +ug-image-viewer-efl (1.0-158) unstable; urgency=low + + * Enable control bar for single mode & return result for SETAS + * Git: slp-source.sec.samsung.net:slp/pkgs/u/ug-image-viewer-efl + * Tag: ug-image-viewer-efl_1.0-158 + + -- Li Suxia Tue, 22 Feb 2011 17:55:16 +0800 + +ug-image-viewer-efl (1.0-157) unstable; urgency=low + + * Fix pause/resume issue related with win rotate + * Fix set home & lock screen related issue + * Git: slp-source.sec.samsung.net:slp/pkgs/u/ug-image-viewer-efl + * Tag: ug-image-viewer-efl_1.0-157 + + -- Li Suxia Mon, 21 Feb 2011 17:56:34 +0800 + +ug-image-viewer-efl (1.0-155) unstable; urgency=low + + * Fix rectangle select issue & zoom rate issue & create lcd size image. + * Git: slp-source.sec.samsung.net:slp/pkgs/u/ug-image-viewer-efl + * Tag: ug-image-viewer-efl_1.0-155 + + -- Li Suxia Fri, 18 Feb 2011 17:28:29 +0800 + +ug-image-viewer-efl (1.0-154) unstable; urgency=low + + * fixed black screen problem when multi down , serveral times. + * Git: slp-source.sec.samsung.net:slp/pkgs/u/ug-image-viewer-efl + * Tag: ug-image-viewer-efl_1.0-154 + + -- Li Suxia Thu, 17 Feb 2011 14:03:36 +0900 + +ug-image-viewer-efl (1.0-153) unstable; urgency=low + + * Revise navibar & control bar for camera UG + * Git: slp-source.sec.samsung.net:slp/pkgs/u/ug-image-viewer-efl + * Tag: ug-image-viewer-efl_1.0-153 + + -- Li Suxia Thu, 17 Feb 2011 09:19:25 +0800 + +ug-image-viewer-efl (1.0-152) unstable; urgency=low + + * Support selector for callerID ug, fix sort by issue + * Git: slp-source.sec.samsung.net:slp/pkgs/u/ug-image-viewer-efl + * Tag: ug-image-viewer-efl_1.0-152 + + -- Li Suxia Wed, 16 Feb 2011 08:35:18 +0800 + +ug-image-viewer-efl (1.0-151) unstable; urgency=low + + * Implement callerID & wallpaper ug, refine single ug + * Git: slp-source.sec.samsung.net:slp/pkgs/u/ug-image-viewer-efl + * Tag: ug-image-viewer-efl_1.0-151 + + -- Li Suxia Mon, 14 Feb 2011 08:43:20 +0800 + +ug-image-viewer-efl (1.0-150) unstable; urgency=low + + * sensor framework disable when image viewer go to background + * Git: slp-source.sec.samsung.net:slp/pkgs/u/ug-image-viewer-efl + * Tag: ug-image-viewer-efl_1.0-150 + + -- DongJin Choi Thu, 10 Feb 2011 14:36:02 +0900 + +ug-image-viewer-efl (1.0-149) unstable; urgency=low + + * inserted pmapi package + * Git: slp-source.sec.samsung.net:slp/pkgs/u/ug-image-viewer-efl + * Tag: ug-image-viewer-efl_1.0-149 + + -- DongJin Choi Tue, 08 Feb 2011 18:06:24 +0900 + +ug-image-viewer-efl (1.0-148) unstable; urgency=low + + * rollback End key policy + * Git: slp-source.sec.samsung.net:slp/pkgs/u/ug-image-viewer-efl + * Tag: ug-image-viewer-efl_1.0-148 + + -- DongJin Choi Mon, 07 Feb 2011 14:14:31 +0900 + +ug-image-viewer-efl (1.0-147) unstable; urgency=low + + * fixed Gallery BS problem ( remove undefined symbol mb_app_common_set_property) + * Git: slp-source.sec.samsung.net:slp/pkgs/u/ug-image-viewer-efl + * Tag: ug-image-viewer-efl_1.0-147 + + -- DongJin Choi Sat, 05 Feb 2011 09:25:23 +0900 + +ug-image-viewer-efl (1.0-146) unstable; urgency=low + + * fixed some bug. + * Git: slp-source.sec.samsung.net:slp/pkgs/u/ug-image-viewer-efl + * Tag: ug-image-viewer-efl_1.0-146 + + -- DongJin Choi Tue, 01 Feb 2011 21:55:05 +0900 + +ug-image-viewer-efl (1.0-145) unstable; urgency=low + + * inserted gethering sns service list code. + * removed undefined function. ( mb_app_common_set_category ) + * image-viewer destory, when ums connected. + * Git: slp-source.sec.samsung.net:slp/pkgs/u/ug-image-viewer-efl + * Tag: ug-image-viewer-efl_1.0-145 + + -- DongJin Choi Tue, 01 Feb 2011 21:07:01 +0900 + +ug-image-viewer-efl (1.0-144) unstable; urgency=low + + * Fixed web image issue + * Git: slp-source.sec.samsung.net:slp/pkgs/u/ug-image-viewer-efl + * Tag: ug-image-viewer-efl_1.0-144 + + -- Li Suxia Mon, 31 Jan 2011 09:16:39 +0800 + +ug-image-viewer-efl (1.0-143) unstable; urgency=low + + * Fixed black screen issue for web image & popup issue + * Git: slp-source.sec.samsung.net:slp/pkgs/u/ug-image-viewer-efl + * Tag: ug-image-viewer-efl_1.0-143 + + -- Li Suxia Wed, 26 Jan 2011 17:37:11 +0800 + +ug-image-viewer-efl (1.0-142) unstable; urgency=low + + * Fixed BS related END KEY + * Git: slp-source.sec.samsung.net:slp/pkgs/u/ug-image-viewer-efl + * Tag: ug-image-viewer-efl_1.0-142 + + -- DongJin Choi Tue, 25 Jan 2011 14:58:34 +0900 + +ug-image-viewer-efl (1.0-141) unstable; urgency=low + + * remove unused code in image_resize & image blend function & modify code related NFC + * Git: slp-source.sec.samsung.net:slp/pkgs/u/ug-image-viewer-efl + * Tag: ug-image-viewer-efl_1.0-141 + + -- DongJin Choi Mon, 24 Jan 2011 14:17:27 +0900 + +ug-image-viewer-efl (1.0-139) unstable; urgency=low + + * Fix update slideshow issue + * Git: slp-source.sec.samsung.net:slp/pkgs/u/ug-image-viewer-efl + * Tag: ug-image-viewer-efl_1.0-139 + + -- Li Suxia Sat, 22 Jan 2011 11:02:07 +0800 + +ug-image-viewer-efl (1.0-138) unstable; urgency=low + + * Fix buidl break + * Git: slp-source.sec.samsung.net:slp/pkgs/u/ug-image-viewer-efl + * Tag: ug-image-viewer-efl_1.0-138 + + -- Li Suxia Wed, 19 Jan 2011 20:06:11 +0800 + +ug-image-viewer-efl (1.0-137) unstable; urgency=low + + * Apply new dir policy & fix ug close cb issue + * Git: slp-source.sec.samsung.net:slp/pkgs/u/ug-image-viewer-efl + * Tag: ug-image-viewer-efl_1.0-137 + + -- Li Suxia Wed, 19 Jan 2011 17:58:32 +0800 + +ug-image-viewer-efl (1.0-136) unstable; urgency=low + + * Fixed BS at the Web Image Down Load + * Git: slp-source.sec.samsung.net:slp/pkgs/u/ug-image-viewer-efl + * Tag: ug-image-viewer-efl_1.0-136 + + -- DongJin Choi Tue, 18 Jan 2011 18:40:41 +0900 + +ug-image-viewer-efl (1.0-135) unstable; urgency=low + + * Fix H0100118455: previous change error + * Git: slp-source.sec.samsung.net:slp/pkgs/u/ug-image-viewer-efl + * Tag: ug-image-viewer-efl_1.0-135 + + -- Li Suxia Mon, 17 Jan 2011 11:50:31 +0800 + +ug-image-viewer-efl (1.0-134) unstable; urgency=low + + * Fix H0100118455 + * Git: slp-source.sec.samsung.net:slp/pkgs/u/ug-image-viewer-efl + * Tag: ug-image-viewer-efl_1.0-134 + + -- Li Suxia Mon, 17 Jan 2011 10:54:17 +0800 + +ug-image-viewer-efl (1.0-133) unstable; urgency=low + + * Upload to fix H0100112470 + * Git: slp-source.sec.samsung.net:slp/pkgs/u/ug-image-viewer-efl + * Tag: ug-image-viewer-efl_1.0-133 + + -- Li Suxia Thu, 13 Jan 2011 16:04:33 +0800 + +ug-image-viewer-efl (1.0-132) unstable; urgency=low + + * enable UG BACK KEY + * Git: slp-source.sec.samsung.net:slp/pkgs/u/ug-image-viewer-efl + * Tag: ug-image-viewer-efl_1.0-132 + + -- DongJin Choi Thu, 13 Jan 2011 11:48:01 +0900 + +ug-image-viewer-efl (1.0-131) unstable; urgency=low + + * Remove heynoti depends + * Fix H0100116919 again: previous change merge conflict + * changed eml_popup_timeout_set parameter type + * Add support for view by tag + * Git: slp-source.sec.samsung.net:slp/pkgs/u/ug-image-viewer-efl + * Tag: ug-image-viewer-efl_1.0-131 + + -- DongJin Choi Wed, 12 Jan 2011 15:20:27 +0900 + +ug-image-viewer-efl (1.0-130) unstable; urgency=low + + * Update geo list by media-svc change + * Git: slp-source.sec.samsung.net:slp/pkgs/u/ug-image-viewer-efl + * Tag: ug-image-viewer-efl_1.0-130 + + -- Li Suxia Wed, 05 Jan 2011 17:16:27 +0800 + +ug-image-viewer-efl (1.0-129) unstable; urgency=low + + * Fix set issue: button not work & exit after done + * Git: slp-source.sec.samsung.net:slp/pkgs/u/ug-image-viewer-efl + * Tag: ug-image-viewer-efl_1.0-129 + + -- Li Suxia Wed, 05 Jan 2011 14:20:03 +0800 + +ug-image-viewer-efl (1.0-128) unstable; urgency=low + + * Fix buildbreak on Elm_softkey related + * Git: slp-source.sec.samsung.net:slp/pkgs/u/ug-image-viewer-efl + * Tag: ug-image-viewer-efl_1.0-128 + + -- Li Suxia Tue, 04 Jan 2011 13:59:53 +0800 + +ug-image-viewer-efl (1.0-127) unstable; urgency=low + + * fixed long press error + * Update footstep by gallery request + * Git: slp-source.sec.samsung.net:slp/pkgs/u/ug-image-viewer-efl + * Tag: ug-image-viewer-efl_1.0-127 + + -- DongJin Choi Tue, 04 Jan 2011 12:09:35 +0900 + +ug-image-viewer-efl (1.0-126) unstable; urgency=low + + * Exit imageviewer once slideshow is finished from footst.. + * fixed long press action. CQ H0100114062 + * Git: slp-source.sec.samsung.net:slp/pkgs/u/ug-image-viewer-efl + * Tag: ug-image-viewer-efl_1.0-126 + + -- DongJin Choi Thu, 30 Dec 2010 17:47:28 +0900 + +ug-image-viewer-efl (1.0-125) unstable; urgency=low + + * Fix delete issue & bs on launch myfile detail ug + * Git: slp-source.sec.samsung.net:slp/pkgs/u/ug-image-viewer-efl + * Tag: ug-image-viewer-efl_1.0-125 + + -- Li Suxia Tue, 28 Dec 2010 08:33:51 +0800 + +ug-image-viewer-efl (1.0-124) unstable; urgency=low + + * fixed tag name + * Git: slp-source.sec.samsung.net:slp/pkgs/u/ug-image-viewer-efl + * Tag: ug-image-viewer-efl_1.0-124 + + -- Li Suxia Mon, 27 Dec 2010 11:10:11 +0900 + +ug-image-viewer-efl (1.0-123) unstable; urgency=low + + * Regarding Text display error + * Comment out appcore api in video. + * Git: slp-source.sec.samsung.net:slp/pkgs/u/ug-image-viewer-efl + * Tag: ug-image-viewer-efl_1.0-123 + + -- Li Suxia Mon, 27 Dec 2010 11:04:13 +0900 + +ug-image-viewer-efl (1.0-122) unstable; urgency=low + + * Remove depends on appcore + * Git: slp-source.sec.samsung.net:slp/pkgs/u/ug-image-viewer-efl + * Tag: ug-image-viewer-efl_1.0-122 + + -- Li Suxia Fri, 24 Dec 2010 15:05:57 +0800 + +ug-image-viewer-efl (1.0-121) unstable; urgency=low + + * Remove appcore_set_i18n + * Git: slp-source.sec.samsung.net:slp/pkgs/u/ug-image-viewer-efl + * Tag: ug-image-viewer-efl_1.0-121 + + -- Li Suxia Wed, 22 Dec 2010 10:49:02 +0800 + +ug-image-viewer-efl (1.0-120) unstable; urgency=low + + * Fix web image download cancel BS + * Git: slp-source.sec.samsung.net:slp/pkgs/u/ug-image-viewer-efl + * Tag: ug-image-viewer-efl_1.0-120 + + -- Li Suxia Tue, 21 Dec 2010 15:07:54 +0800 + +ug-image-viewer-efl (1.0-119) unstable; urgency=low + + * Remove bluetooth-app in makefile + * Git: slp-source.sec.samsung.net:slp/pkgs/u/ug-image-viewer-efl + * Tag: ug-image-viewer-efl_1.0-119 + + -- Li Suxia Mon, 20 Dec 2010 13:21:18 +0800 + +ug-image-viewer-efl (1.0-118) unstable; urgency=low + + * Remove video depends & applog + * Git: slp-source.sec.samsung.net:slp/pkgs/u/ug-image-viewer-efl + * Tag: ug-image-viewer-efl_1.0-118 + + -- Li Suxia Mon, 20 Dec 2010 11:32:43 +0800 + +ug-image-viewer-efl (1.0-117) unstable; urgency=low + + * Fix exit issue for video change + * Git: slp-source.sec.samsung.net:slp/pkgs/u/ug-image-viewer-efl + * Tag: ug-image-viewer-efl_1.0-117 + + -- Li Suxia Fri, 17 Dec 2010 17:38:13 +0800 + +ug-image-viewer-efl (1.0-116) unstable; urgency=low + + * Upload again for web issue + * Git: slp-source.sec.samsung.net:slp/pkgs/u/ug-image-viewer-efl + * Tag: ug-image-viewer-efl_1.0-116 + + -- Li Suxia Thu, 16 Dec 2010 10:27:46 +0800 + +ug-image-viewer-efl (1.0-115) unstable; urgency=low + + * Comment out object del for BS + * Git: slp-source.sec.samsung.net:slp/pkgs/u/ug-image-viewer-efl + * Tag: ug-image-viewer-efl_1.0-115 + + -- Li Suxia Wed, 15 Dec 2010 18:24:19 +0800 + +ug-image-viewer-efl (1.0-114) unstable; urgency=low + + * Fix pkg install issue + * Git: slp-source.sec.samsung.net:slp/pkgs/u/ug-image-viewer-efl + * Tag: ug-image-viewer-efl_1.0-114 + + -- Li Suxia Wed, 15 Dec 2010 09:41:45 +0800 + +ug-image-viewer-efl (1.0-113) unstable; urgency=low + + * Fix view by places issue + * Git: slp-source.sec.samsung.net:slp/pkgs/u/ug-image-viewer-efl + * Tag: ug-image-viewer-efl_1.0-113 + + -- Li Suxia Tue, 14 Dec 2010 19:25:04 +0800 + +ug-image-viewer-efl (1.0-112) unstable; urgency=low + + * Add view by place & fix i18n issue + * Git: slp-source.sec.samsung.net:slp/pkgs/u/ug-image-viewer-efl + * Tag: ug-image-viewer-efl_1.0-112 + + -- Li Suxia Tue, 14 Dec 2010 18:54:34 +0800 + +ug-image-viewer-efl (1.0-111) unstable; urgency=low + + * Add share by twitter, print via bluetooth, update web image download + * Git: slp-source.sec.samsung.net:slp/pkgs/u/ug-image-viewer-efl + * Tag: ug-image-viewer-efl_1.0-111 + + -- Li Suxia Tue, 14 Dec 2010 10:31:57 +0800 + +ug-image-viewer-efl (1.0-110) unstable; urgency=low + + * Update Po to fix multi-language issue + * Git: slp-source.sec.samsung.net:slp/pkgs/u/ug-image-viewer-efl + * Tag: ug-image-viewer-efl_1.0-110 + + -- Li Suxia Fri, 10 Dec 2010 16:53:48 +0800 + +ug-image-viewer-efl (1.0-109) unstable; urgency=low + + * Fix break for sns + * Git: slp-source.sec.samsung.net:slp/pkgs/u/ug-image-viewer-efl + * Tag: ug-image-viewer-efl_1.0-109 + + -- Li Suxia Fri, 10 Dec 2010 08:44:05 +0800 + +ug-image-viewer-efl (1.0-108) unstable; urgency=low + + * Fix break for Edje_Edit.h + * Git: slp-source.sec.samsung.net:slp/pkgs/u/ug-image-viewer-efl + * Tag: ug-image-viewer-efl_1.0-108 + + -- Li Suxia Wed, 08 Dec 2010 17:31:20 +0800 + +ug-image-viewer-efl (1.0-107) unstable; urgency=low + + * add proction code to video + * Git: slp-source.sec.samsung.net:slp/pkgs/u/ug-image-viewer-efl + * Tag: ug-image-viewer-efl_1.0-107 + + -- Li Suxia Wed, 08 Dec 2010 17:16:56 +0800 + +ug-image-viewer-efl (1.0-106) unstable; urgency=low + + * add proction code to video + * Git: 165.213.180.234:/git/slp/pkgs/ug-image-viewer-efl + * Tag: ug-image-viewer-efl_1.0-106 + + -- Li Wen Fri, 03 Dec 2010 18:34:08 +0800 + +ug-image-viewer-efl (1.0-105) unstable; urgency=low + + * Fix BS on object del + * Git: 165.213.180.234:/git/slp/pkgs/ug-image-viewer-efl + * Tag: ug-image-viewer-efl_1.0-105 + + -- Li Wen Fri, 03 Dec 2010 17:34:08 +0800 + +ug-image-viewer-efl (1.0-104) unstable; urgency=low + + * Change video capture code + * Git: 165.213.180.234:/git/slp/pkgs/ug-image-viewer-efl + * Tag: ug-image-viewer-efl_1.0-104 + + -- Li Wen Wed, 01 Dec 2010 17:28:20 +0800 + +ug-image-viewer-efl (1.0-103) unstable; urgency=low + + * Revise multi-language support + * Git: 165.213.180.234:/git/slp/pkgs/ug-image-viewer-efl + * Tag: ug-image-viewer-efl_1.0-103 + + -- Li Suxia Wed, 01 Dec 2010 16:58:20 +0800 + +ug-image-viewer-efl (1.0-102) unstable; urgency=low + + * Revert GUI change & fix delete controlbar BS + * Git: 165.213.180.234:/git/slp/pkgs/ug-image-viewer-efl + * Tag: ug-image-viewer-efl_1.0-102 + + -- Li Suxia Tue, 30 Nov 2010 17:05:16 +0800 + +ug-image-viewer-efl (1.0-101) unstable; urgency=low + + * Change bluetooth launch + * Git: 165.213.180.234:/git/slp/pkgs/ug-image-viewer-efl + * Tag: ug-image-viewer-efl_1.0-101 + + -- Li Suxia Mon, 29 Nov 2010 18:28:32 +0800 + +ug-image-viewer-efl (1.0-100) unstable; urgency=low + + * Support Korea language & enable web image download + * Git: 165.213.180.234:/git/slp/pkgs/ug-image-viewer-efl + * Tag: ug-image-viewer-efl_1.0-100 + + -- Li Suxia Mon, 29 Nov 2010 18:17:17 +0800 + +ug-image-viewer-efl (1.0-99) unstable; urgency=low + + * Fix issue: unable to launch image-editor + * Git: 165.213.180.234:/git/slp/pkgs/ug-image-viewer-efl + * Tag: ug-image-viewer-efl_1.0-99 + + -- Li Suxia Mon, 29 Nov 2010 09:01:09 +0800 + +ug-image-viewer-efl (1.0-98) unstable; urgency=low + + * Support open file not in default dir + * Git: 165.213.180.234:/git/slp/pkgs/ug-image-viewer-efl + * Tag: ug-image-viewer-efl_1.0-98 + + -- Li Suxia Fri, 26 Nov 2010 16:36:42 +0800 + +ug-image-viewer-efl (1.0-97) unstable; urgency=low + + * Upload for view by all + * Git: 165.213.180.234:/git/slp/pkgs/ug-image-viewer-efl + * Tag: ug-image-viewer-efl_1.0-97 + + -- Li Suxia Fri, 26 Nov 2010 13:27:57 +0800 + +ug-image-viewer-efl (1.0-96) unstable; urgency=low + + * Enable web image download + * Git: 165.213.180.234:/git/slp/pkgs/ug-image-viewer-efl + * Tag: ug-image-viewer-efl_1.0-96 + + -- Li Suxia Tue, 23 Nov 2010 17:03:06 +0800 + +ug-image-viewer-efl (1.0-95) unstable; urgency=low + + * fix adding bookmark BS issue. + * Git: 165.213.180.234:/git/slp/pkgs/ug-image-viewer-efl + * Tag: ug-image-viewer-efl_1.0-95 + + -- Li Wen Mon, 22 Nov 2010 21:08:46 +0800 + +ug-image-viewer-efl (1.0-94) unstable; urgency=low + + * change to Syspopup_launch(volume, NULL) + * Git: 165.213.180.234:/git/slp/pkgs/ug-image-viewer-efl + * Tag: ug-image-viewer-efl_1.0-94 + + -- Li Wen Mon, 22 Nov 2010 14:08:46 +0800 + +ug-image-viewer-efl (1.0-93) unstable; urgency=low + + * Upload for SINGLE mode issue fix + * Git: 165.213.180.234:/git/slp/pkgs/ug-image-viewer-efl + * Tag: ug-image-viewer-efl_1.0-93 + + -- Li Suxia Fri, 19 Nov 2010 13:08:46 +0800 + +ug-image-viewer-efl (1.0-92) unstable; urgency=low + + * Reupload for build error + * Git: 165.213.180.234:/git/slp/pkgs/ug-image-viewer-efl + * Tag: ug-image-viewer-efl_1.0-92 + + -- Li Suxia Thu, 18 Nov 2010 16:12:13 +0800 + +ug-image-viewer-efl (1.0-91) unstable; urgency=low + + * Fix editor issue and photocam issue. + * Git: 165.213.180.234:/git/slp/pkgs/ug-image-viewer-efl + * Tag: ug-image-viewer-efl_1.0-91 + + -- Li Suxia Thu, 18 Nov 2010 15:02:57 +0800 + +ug-image-viewer-efl (1.0-90) unstable; urgency=low + + * Remove UI window & add dbg package + * Git: 165.213.180.234:/git/slp/pkgs/ug-image-viewer-efl + * Tag: ug-image-viewer-efl_1.0-90 + + -- Li Suxia Thu, 18 Nov 2010 09:52:37 +0800 + +ug-image-viewer-efl (1.0-89) unstable; urgency=low + + * Fix web download & copy & ctxpopup position issue + * Git: 165.213.180.234:/git/slp/pkgs/ug-image-viewer-efl + * Tag: ug-image-viewer-efl_1.0-89 + + -- Li Suxia Tue, 16 Nov 2010 16:33:24 +0800 + +ug-image-viewer-efl (1.0-88) unstable; urgency=low + + * Remove mm_session & enable web image download + * Git: 165.213.180.234:/git/slp/pkgs/ug-image-viewer-efl + * Tag: ug-image-viewer-efl_1.0-88 + + -- Li Suxia Mon, 15 Nov 2010 17:51:21 +0800 + +ug-image-viewer-efl (1.0-87) unstable; urgency=low + + * enabel ug-imageviewer's own wrapper + * Git: 165.213.180.234:/git/slp/pkgs/ug-image-viewer-efl + * Tag: ug-image-viewer-efl_1.0-87 + + -- Gao Wei Mon, 15 Nov 2010 14:49:49 +0800 + +ug-image-viewer-efl (1.0-86) unstable; urgency=low + + * Fix slideshow & play lock up issue & refine copy + * Git: 165.213.180.234:/git/slp/pkgs/ug-image-viewer-efl + * Tag: ug-image-viewer-efl_1.0-86 + + -- Li Suxia Fri, 12 Nov 2010 14:49:49 +0800 + +ug-image-viewer-efl (1.0-85) unstable; urgency=low + + * enabling ug's own mb-svc-wrapper + * Git: 165.213.180.234:/git/slp/pkgs/ug-image-viewer-efl + * Tag: ug-image-viewer-efl_1.0-85 + + -- Gao Wei Fri, 12 Nov 2010 10:47:19 +0800 + +ug-image-viewer-efl (1.0-84) unstable; urgency=low + + * Enable video-player for camera + * Git: 165.213.180.234:/git/slp/pkgs/ug-image-viewer-efl + * Tag: ug-image-viewer-efl_1.0-84 + + -- Li Suxia Thu, 11 Nov 2010 16:55:57 +0800 + +ug-image-viewer-efl (1.0-83) unstable; urgency=low + + * Fix set as issue: only close button show + * Git: 165.213.180.234:/git/slp/pkgs/ug-image-viewer-efl + * Tag: ug-image-viewer-efl_1.0-83 + + -- Li Suxia Wed, 10 Nov 2010 15:04:47 +0800 + +ug-image-viewer-efl (1.0-82) unstable; urgency=low + + * re-packaging + * Git: 165.213.180.234:/git/slp/pkgs/ug-image-viewer-efl + * Tag: ug-image-viewer-efl_1.0-82 + + -- Gao Wei Mon, 08 Nov 2010 10:47:19 +0800 + +ug-image-viewer-efl (1.0-81) unstable; urgency=low + + * Enable EXIF & Change phtocao bounce by EFL + * Git: 165.213.180.234:/git/slp/pkgs/ug-image-viewer-efl + * Tag: ug-image-viewer-efl_1.0-81 + + -- Li Suxia Sat, 06 Nov 2010 14:47:19 +0800 + +ug-image-viewer-efl (1.0-80) unstable; urgency=low + + * Reupload by media-svc + * Git: 165.213.180.234:/git/slp/pkgs/ug-image-viewer-efl + * Tag: ug-image-viewer-efl_1.0-80 + + -- Li Suxia Fri, 05 Nov 2010 13:38:48 +0800 + +ug-image-viewer-efl (1.0-79) unstable; urgency=low + + * Seperate image-viewer from ug & remove apputil dependency + * Git: 165.213.180.234:/git/slp/pkgs/ug-image-viewer-efl + * Tag: ug-image-viewer-efl_1.0-79 + + -- Li Suxia Fri, 05 Nov 2010 08:42:51 +0800 + +ug-image-viewer-efl (1.0-78) unstable; urgency=low + + * Comment out EXIF + * Git: 165.213.180.234:/git/slp/pkgs/ug-image-viewer-efl + * Tag: ug-image-viewer-efl_1.0-78 + + -- Li Suxia Thu, 04 Nov 2010 17:09:18 +0800 + +ug-image-viewer-efl (1.0-77) unstable; urgency=low + + * Fix email issue + * Git: 165.213.180.234:/git/slp/pkgs/ug-image-viewer-efl + * Tag: ug-image-viewer-efl_1.0-77 + + -- Li Suxia Thu, 04 Nov 2010 17:01:56 +0800 + +ug-image-viewer-efl (1.0-76) unstable; urgency=low + + * Reupload for media-svc change and fix drag issue on video + * Git: 165.213.180.234:/git/slp/pkgs/ug-image-viewer-efl + * Tag: ug-image-viewer-efl_1.0-76 + + -- Hyunjun Ko Wed, 03 Oct 2010 19:40:12 +0800 + +ug-image-viewer-efl (1.0-75) unstable; urgency=low + + * Reupload for media-svc change + * Git: 165.213.180.234:/git/slp/pkgs/ug-image-viewer-efl + * Tag: ug-image-viewer-efl_1.0-75 + + -- Li Suxia Wed, 03 Nov 2010 15:43:41 +0800 + +ug-image-viewer-efl (1.0-74) unstable; urgency=low + + * Fix pinch zoom issue: disable bounce animator + * Git: 165.213.180.234:/git/slp/pkgs/ug-image-viewer-efl + * Tag: ug-image-viewer-efl_1.0-74 + + -- Li Suxia Wed, 03 Nov 2010 11:24:49 +0800 + +ug-image-viewer-efl (1.0-73) unstable; urgency=low + + * Fix Set as issue + * Git: 165.213.180.234:/git/slp/pkgs/ug-image-viewer-efl + * Tag: ug-image-viewer-efl_1.0-73 + + -- Li Suxia Mon, 01 Nov 2010 17:30:21 +0800 + +ug-image-viewer-efl (1.0-72) unstable; urgency=low + + * Fix delete issue on receive event after destroy + * Git: 165.213.180.234:/git/slp/pkgs/ug-image-viewer-efl + * Tag: ug-image-viewer-efl_1.0-72 + + -- Li Suxia Fri, 29 Oct 2010 18:04:13 +0800 + +ug-image-viewer-efl (1.0-71) unstable; urgency=low + + * Fix delete issue on continuous click + * Git: 165.213.180.234:/git/slp/pkgs/ug-image-viewer-efl + * Tag: ug-image-viewer-efl_1.0-71 + + -- Li Suxia Fri, 29 Oct 2010 10:58:21 +0800 + +ug-image-viewer-efl (1.0-70) unstable; urgency=low + + * Reupload because of mistake + * Git: 165.213.180.234:/git/slp/pkgs/ug-image-viewer-efl + * Tag: ug-image-viewer-efl_1.0-70 + + -- Hyunjun Ko Wed, 27 Oct 2010 16:40:12 +0800 + +ug-image-viewer-efl (1.0-69) unstable; urgency=low + + * Reupload with media svc change. + * Git: 165.213.180.234:/git/slp/pkgs/ug-image-viewer-efl + * Tag: ug-image-viewer-efl_1.0-69 + + -- Hyunjun Ko Wed, 27 Oct 2010 16:25:12 +0800 + +ug-image-viewer-efl (1.0-68) unstable; urgency=low + + * Disable log info for demo + * Git: 165.213.180.234:/git/slp/pkgs/ug-image-viewer-efl + * Tag: ug-image-viewer-efl_1.0-68 + + -- Li Suxia Wed, 27 Oct 2010 14:05:34 +0800 + +ug-image-viewer-efl (1.0-67) unstable; urgency=low + + * Fix delete issue + * Git: 165.213.180.234:/git/slp/pkgs/ug-image-viewer-efl + * Tag: ug-image-viewer-efl_1.0-67 + + -- Li Suxia Wed, 27 Oct 2010 11:50:56 +0800 + +ug-image-viewer-efl (1.0-66) unstable; urgency=low + + * Fix album delete error + * Git: 165.213.180.234:/git/slp/pkgs/ug-image-viewer-efl + * Tag: ug-image-viewer-efl_1.0-66 + + -- Li Suxia Wed, 27 Oct 2010 09:08:12 +0800 + +ug-image-viewer-efl (1.0-65) unstable; urgency=low + + * Add test code + * Git: 165.213.180.234:/git/slp/pkgs/ug-image-viewer-efl + * Tag: ug-image-viewer-efl_1.0-65 + + -- Li Suxia Tue, 26 Oct 2010 17:53:01 +0800 + +ug-image-viewer-efl (1.0-63) unstable; urgency=low + + * Fix exit issue + * Git: 165.213.180.234:/git/slp/pkgs/ug-image-viewer-efl + * Tag: ug-image-viewer-efl_1.0-63 + + -- Li Suxia Tue, 26 Oct 2010 14:46:53 +0800 + +ug-image-viewer-efl (1.0-62) unstable; urgency=low + + * Add error handler + * Git: 165.213.180.234:/git/slp/pkgs/ug-image-viewer-efl + * Tag: ug-image-viewer-efl_1.0-62 + + -- Li Suxia Mon, 25 Oct 2010 18:06:55 +0800 + +ug-image-viewer-efl (1.0-61) unstable; urgency=low + + * Reupload with media svc change. + * Git: 165.213.180.234:/git/slp/pkgs/ug-image-viewer-efl + * Tag: ug-image-viewer-efl_1.0-61 + + -- Hyunjun Ko Sat, 23 Oct 2010 14:00:12 +0800 + +ug-image-viewer-efl (1.0-60) unstable; urgency=low + + * Upload with media svc change. + * Git: 165.213.180.234:/git/slp/pkgs/ug-image-viewer-efl + * Tag: ug-image-viewer-efl_1.0-60 + + -- Tang Feng Sat, 23 Oct 2010 12:45:36 +0800 + +ug-image-viewer-efl (1.0-59) unstable; urgency=low + + * Fix BS temp on free folder list. + * Git: 165.213.180.234:/git/slp/pkgs/ug-image-viewer-efl + * Tag: ug-image-viewer-efl_1.0-59 + + -- Li Suxia Fri, 22 Oct 2010 17:42:36 +0800 + +ug-image-viewer-efl (1.0-58) unstable; urgency=low + + * Support add to home in videoplayer + * Git: 165.213.180.234:/git/slp/pkgs/ug-image-viewer-efl + * Tag: ug-image-viewer-efl_1.0-58 + + -- Li Suxia Fri, 22 Oct 2010 16:39:25 +0800 + +ug-image-viewer-efl (1.0-57) unstable; urgency=low + + * Add pre/next function for video + * Git: 165.213.180.234:/git/slp/pkgs/ug-image-viewer-efl + * Tag: ug-image-viewer-efl_1.0-57 + + -- Li Wen Wed, 21 Oct 2010 17:15:22 +0800 + +ug-image-viewer-efl (1.0-56) unstable; urgency=low + + * Add support for git&wbmp + * Git: 165.213.180.234:/git/slp/pkgs/ug-image-viewer-efl + * Tag: ug-image-viewer-efl_1.0-56 + + -- Li Suxia Wed, 20 Oct 2010 17:45:22 +0800 + +ug-image-viewer-efl (1.0-55) unstable; urgency=low + + * Add sort type support & aul launch not mime-based + * Git: 165.213.180.234:/git/slp/pkgs/ug-image-viewer-efl + * Tag: ug-image-viewer-efl_1.0-55 + + -- Li Suxia Wed, 20 Oct 2010 10:47:31 +0800 + +ug-image-viewer-efl (1.0-54) unstable; urgency=low + + * Remove media-browser-svc completely + * Git: 165.213.180.234:/git/slp/pkgs/ug-image-viewer-efl + * Tag: ug-image-viewer-efl_1.0-54 + + -- Li Wen Tue, 20 Oct 2010 09:56:02 +0800 + +ug-image-viewer-efl (1.0-53) unstable; urgency=low + + * Fix slideshow timer BS and indicator issue & build break + * Git: 165.213.180.234:/git/slp/pkgs/ug-image-viewer-efl + * Tag: ug-image-viewer-efl_1.0-53 + + -- Li Suxia Tue, 19 Oct 2010 15:56:02 +0800 + +ug-image-viewer-efl (1.0-52) unstable; urgency=low + + * Modified to use new api in media-svc + * Git: 165.213.180.234:/git/slp/pkgs/ug-image-viewer-efl + * Tag: ug-image-viewer-efl_1.0-52 + + -- Hyunjun Ko Mon, 18 Oct 2010 22:40:12 +0800 + +ug-image-viewer-efl (1.0-51) unstable; urgency=low + + * Fix album edit bug + * Git: 165.213.180.234:/git/slp/pkgs/ug-image-viewer-efl + * Tag: ug-image-viewer-efl_1.0-51 + + -- Li Suxia Mon, 18 Oct 2010 16:31:13 +0800 + +ug-image-viewer-efl (1.0-50) unstable; urgency=low + + * Fix thumbpath for video file + * Git: 165.213.180.234:/git/slp/pkgs/ug-image-viewer-efl + * Tag: ug-image-viewer-efl_1.0-49 + + -- Li Suxia Fri, 15 Oct 2010 16:44:42 +0800 + +ug-image-viewer-efl (1.0-49) unstable; urgency=low + + * Add places view. + * Git: 165.213.180.234:/git/slp/pkgs/ug-image-viewer-efl + * Tag: ug-image-viewer-efl_1.0-49 + + -- Sangjin Han Thu, 14 Oct 2010 15:39:00 +0900 + +ug-image-viewer-efl (1.0-48) unstable; urgency=low + + * Remove FM-SVC dependency + * Git: 165.213.180.234:/git/slp/pkgs/ug-image-viewer-efl + * Tag: ug-image-viewer-efl_1.0-48 + + -- Li Suxia Wed, 13 Oct 2010 18:22:51 +0800 + +ug-image-viewer-efl (1.0-47) unstable; urgency=low + + * Enable to use new media-svc + * Git: 165.213.180.234:/git/slp/pkgs/ug-image-viewer-efl + * Tag: ug-image-viewer-efl_1.0-47 + + -- Hyunjun Ko Tue, 12 Oct 2010 20:33:12 +0800 + +ug-image-viewer-efl (1.0-46) unstable; urgency=low + + * Fix drm path issue & support landscape for videoplayer + * Git: 165.213.180.234:/git/slp/pkgs/ug-image-viewer-efl + * Tag: ug-image-viewer-efl_1.0-46 + + -- Li Suxia Mon, 11 Oct 2010 18:17:12 +0800 + +ug-image-viewer-efl (1.0-45) unstable; urgency=low + + * Fix flicking issue during zoom & merge video-player + * Git: 165.213.180.234:/git/slp/pkgs/ug-image-viewer-efl + * Tag: ug-image-viewer-efl_1.0-45 + + -- Li Suxia Mon, 11 Oct 2010 10:12:14 +0800 + +ug-image-viewer-efl (1.0-44) unstable; urgency=low + * Adjust Copy feature & Fix grab key issue + * Git: 165.213.180.234:/git/slp/pkgs/ug-image-viewer-efl + * Tag: ug-image-viewer-efl_1.0-44 + + -- Li Suxia Fri, 08 Oct 2010 16:43:48 +0800 + +ug-image-viewer-efl (1.0-43) unstable; urgency=low + + * Fix some CMakeLists.txt for the new build system. + * Git: 165.213.180.234:/git/slp/pkgs/ug-image-viewer-efl + * Tag: ug-image-viewer-efl_1.0-43 + + -- Sangjin Han Wed, 06 Oct 2010 18:09:00 +0900 + +ug-image-viewer-efl (1.0-42) unstable; urgency=low + + * Add USE_MEDIA_SVC define + * Git: 165.213.180.234:/git/slp/pkgs/ug-image-viewer-efl + * Tag: ug-image-viewer-efl_1.0-42 + + -- Sangjin Han Fri, 01 Oct 2010 16:55:20 +0900 + +ug-image-viewer-efl (1.0-41) unstable; urgency=low + + * Change sound header file & remove libcommunities dependency + * Git: 165.213.180.234:/git/slp/pkgs/ug-image-viewer-efl + * Tag: ug-image-viewer-efl_1.0-41 + + -- Byungwook Jang Thu, 30 Sep 2010 14:52:44 +0900 + +ug-image-viewer-efl (1.0-40) unstable; urgency=low + + * Implement aul & Fix favor icon issue + * Git: 165.213.180.234:/git/slp/pkgs/ug-image-viewer-efl + * Tag: ug-image-viewer-efl_1.0-40 + + -- Li Suxia Wed, 29 Sep 2010 15:53:04 +0800 + +ug-image-viewer-efl (1.0-39) unstable; urgency=low + + * Replace navigation bar by navi-ext for 3 buttons + * Git: 165.213.180.234:/git/slp/pkgs/ug-image-viewer-efl + * Tag: ug-image-viewer-efl_1.0-39 + + -- Li Suxia Tue, 28 Sep 2010 17:47:40 +0800 + +ug-image-viewer-efl (1.0-38) unstable; urgency=low + + * Fix BS for Home&End key + * Git: 165.213.180.234:/git/slp/pkgs/ug-image-viewer-efl + * Tag: ug-image-viewer-efl_1.0-38 + + -- Li Suxia Mon, 27 Sep 2010 18:27:42 +0800 + +ug-image-viewer-efl (1.0-37) unstable; urgency=low + + * Adjust set as process & video-player for scalable UI + * Git: 165.213.180.234:/git/slp/pkgs/ug-image-viewer-efl + * Tag: ug-image-viewer-efl_1.0-37 + + -- Li Suxia Mon, 27 Sep 2010 17:26:16 +0800 + +ug-image-viewer-efl (1.0-36) unstable; urgency=low + + * Fix indicator issue(hide video indicator) + * Git: 165.213.180.234:/git/slp/pkgs/ug-image-viewer-efl + * Tag: ug-image-viewer-efl_1.0-36 + + -- Li Wen Sun, 26 Sep 2010 19:40:18 +0800 + +ug-image-viewer-efl (1.0-35) unstable; urgency=low + + * Fix indicator issue(hide video indicator) + * Git: 165.213.180.234:/git/slp/pkgs/ug-image-viewer-efl + * Tag: ug-image-viewer-efl_1.0-35 + + -- Li Suxia Sun, 26 Sep 2010 18:40:18 +0800 + +ug-image-viewer-efl (1.0-34) unstable; urgency=low + + * Fix slide show for video-image + * Git: 165.213.180.234:/git/slp/pkgs/ug-image-viewer-efl + * Tag: ug-image-viewer-efl_1.0-34 + + -- Li Suxia Sun, 26 Sep 2010 17:43:44 +0800 + +ug-image-viewer-efl (1.0-33) unstable; urgency=low + + * Fix flick not smooth issue + * Git: 165.213.180.234:/git/slp/pkgs/ug-image-viewer-efl + * Tag: ug-image-viewer-efl_1.0-33 + + -- Li Suxia Sat, 25 Sep 2010 19:58:22 +0800 + +ug-image-viewer-efl (1.0-32) unstable; urgency=low + + * Fix video-image slideshow + * Git: 165.213.180.234:/git/slp/pkgs/ug-image-viewer-efl + * Tag: ug-image-viewer-efl_1.0-32 + + -- Li Suxia Tue, 21 Sep 2010 18:13:48 +0800 + +ug-image-viewer-efl (1.0-31) unstable; urgency=low + + * Fix slideshow for video-image + * Git: 165.213.180.234:/git/slp/pkgs/ug-image-viewer-efl + * Tag: ug-image-viewer-efl_1.0-31 + + -- Li Suxia Mon, 20 Sep 2010 17:39:13 +0800 + +ug-image-viewer-efl (1.0-30) unstable; urgency=low + + * Enable navibar cb in video-player & for upload + * Git: 165.213.180.234:/git/slp/pkgs/ug-image-viewer-efl + * Tag: ug-image-viewer-efl_1.0-30 + + -- Li Suxia Mon, 20 Sep 2010 13:08:59 +0800 + +ug-image-viewer-efl (1.0-29) unstable; urgency=low + + * Fix pinch zoom flick issue. + * Git: 165.213.180.234:/git/slp/pkgs/ug-image-viewer-efl + * Tag: ug-image-viewer-efl_1.0-29 + + -- Li Suxia Fri, 17 Sep 2010 17:28:36 +0800 + +ug-image-viewer-efl (1.0-28) unstable; urgency=low + + * Fix pinch zoom flick issue. + * Git: 165.213.180.234:/git/slp/pkgs/ug-image-viewer-efl + * Tag: ug-image-viewer-efl_1.0-28 + + -- Li Suxia Thu, 16 Sep 2010 17:37:33 +0800 + +ug-image-viewer-efl (1.0-27) unstable; urgency=low + + * Fix repeat-event issue + * Git: 165.213.180.234:/git/slp/pkgs/ug-image-viewer-efl + * Tag: ug-image-viewer-efl_1.0-27 + + -- Li Suxia Wed, 15 Sep 2010 11:33:23 +0800 + +ug-image-viewer-efl (1.0-26) unstable; urgency=low + + * Fix rotate issue + * Git: 165.213.180.234:/git/slp/pkgs/ug-image-viewer-efl + * Tag: ug-image-viewer-efl_1.0-26 + + -- Li Suxia Tue, 14 Sep 2010 17:32:51 +0800 + +ug-image-viewer-efl (1.0-25) unstable; urgency=low + + * Enable Set_as feature + * Git: 165.213.180.234:/git/slp/pkgs/ug-image-viewer-efl + * Tag: ug-image-viewer-efl_1.0-25 + + -- Li Suxia Tue, 14 Sep 2010 09:46:24 +0800 + +ug-image-viewer-efl (1.0-24) unstable; urgency=low + + * Reupload for EFL upgrade + * Git: 165.213.180.234:/git/slp/pkgs/ug-image-viewer-efl + * Tag: ug-image-viewer-efl_1.0-24 + + -- Li Suxia Sat, 11 Sep 2010 16:37:21 +0800 + +ug-image-viewer-efl (1.0-23) unstable; urgency=low + + * Upload for EFL upgrade + * Git: 165.213.180.234:/git/slp/pkgs/ug-image-viewer-efl + * Tag: ug-image-viewer-efl_1.0-23 + + -- Li Suxia Sat, 10 Sep 2010 16:31:55 +0800 + +ug-image-viewer-efl (1.0-22) unstable; urgency=low + + * Enable pinch zoom & adjust video slide. + * Git: 165.213.180.234:/git/slp/pkgs/ug-image-viewer-efl + * Tag: ug-image-viewer-efl_1.0-22 + + -- Li Suxia Thu, 09 Sep 2010 20:15:55 +0800 + +ug-image-viewer-efl (1.0-21) unstable; urgency=low + + * fix the bug of favorites + * Git: 165.213.180.234:/git/slp/pkgs/ug-image-viewer-efl + * Tag: ug-image-viewer-efl_1.0-21 + + -- Gao Wei Tue, 08 Sep 2010 08:15:18 +0800 + +ug-image-viewer-efl (1.0-19) unstable; urgency=low + + *Fix language issue for myfile + * Git: 165.213.180.234:/git/slp/pkgs/ug-image-viewer-efl + * Tag: ug-image-viewer-efl_1.0-19 + + -- Li Suxia Tue, 07 Sep 2010 13:15:18 +0800 + +ug-image-viewer-efl (1.0-18) unstable; urgency=low + + * Fix issue related with camera. + * Git: 165.213.180.234:/git/slp/pkgs/ug-image-viewer-efl + * Tag: ug-image-viewer-efl_1.0-18 + + -- Li Suxia Mon, 06 Sep 2010 15:30:17 +0800 + +ug-image-viewer-efl (1.0-17) unstable; urgency=low + + * Fix indicator & disable pinch zoom. + * Git: 165.213.180.234:/git/slp/pkgs/ug-image-viewer-efl + * Tag: ug-image-viewer-efl_1.0-17 + + -- Li Suxia Sat, 04 Sep 2010 17:32:32 +0800 + +ug-image-viewer-efl (1.0-16) unstable; urgency=low + + * Fix context popup issue, enable image-editor & set as wallpaper. + * Git: 165.213.180.234:/git/slp/pkgs/ug-image-viewer-efl + * Tag: ug-image-viewer-efl_1.0-16 + + -- Li Suxia Fri, 03 Sep 2010 08:35:01 +0800 + +ug-image-viewer-efl (1.0-15) unstable; urgency=low + + * Fix issue related with image-editor launch. + * Git: 165.213.180.234:/git/slp/pkgs/ug-image-viewer-efl + * Tag: ug-image-viewer-efl_1.0-15 + + -- Li Suxia Wed, 01 Sep 2010 17:44:31 +0800 + +ug-image-viewer-efl (1.0-14) unstable; urgency=low + + * Fix rotate issue. + * Git: 165.213.180.234:/git/slp/pkgs/ug-image-viewer-efl + * Tag: ug-image-viewer-efl_1.0-14 + + -- Li Suxia Wed, 01 Sep 2010 08:13:29 +0800 + +ug-image-viewer-efl (1.0-13) unstable; urgency=low + + * Fix landscape issue for quick view. + * Git: 165.213.180.234:/git/slp/pkgs/ug-image-viewer-efl + * Tag: ug-image-viewer-efl_1.0-13 + + -- Li Suxia Mon, 30 Aug 2010 17:48:42 +0800 + +ug-image-viewer-efl (1.0-12) unstable; urgency=low + + * fix build error in i686 + * Git: 165.213.180.234:/git/slp/pkgs/ug-image-viewer-efl + * Tag: ug-image-viewer-efl_1.0-12 + + -- Gao Wei Fri, 27 Aug 2010 16:15:25 +0800 + +ug-image-viewer-efl (1.0-10) unstable; urgency=low + + * change mouse policy for UG_IVa + * remove common.h from db_handler.h + * Fix landscape bug. + * merge video codes into image viewera + * Git: 165.213.180.234:/git/slp/pkgs/ug-image-viewer-efl + * Tag: ug-image-viewer-efl_1.0-10 + + -- Gao Wei Fri, 27 Aug 2010 09:15:25 +0800 + +ug-image-viewer-efl (1.0-8) unstable; urgency=low + + * enable gallery to use IV_UG + * Git: 165.213.180.234:/git/slp/pkgs/ug-image-viewer-efl + * Tag: ug-image-viewer-efl_1.0-8 + + -- Gao Wei Wed, 25 Aug 2010 09:15:25 +0800 + +ug-image-viewer-efl (1.0-7) unstable; urgency=low + + * Update param parse and integrat videoplayer ug + * Git: 165.213.180.234:/git/slp/pkgs/ug-image-viewer-efl + * Tag: ug-image-viewer-efl_1.0-7 + + -- Li Suxia Tue, 24 Aug 2010 17:03:49 +0800 + +ug-image-viewer-efl (1.0-6) unstable; urgency=low + + * ug will not cluster gallery's db + * Git: 165.213.180.234:/git/slp/pkgs/ug-image-viewer-efl + * Tag: ug-image-viewer-efl_1.0-6 + + -- Gao Wei Thu, 23 Aug 2010 14:15:25 +0800 + +ug-image-viewer-efl (1.0-5) unstable; urgency=low + + * lay the evas_object_image under ly_standard + * Update parse param. + * Fix context popup position. + * Git: 165.213.180.234:/git/slp/pkgs/ug-image-viewer-efl + * Tag: ug-image-viewer-efl_1.0-5 + + -- Gao Wei Thu, 21 Aug 2010 11:15:25 +0800 + +ug-image-viewer-efl (1.0-4) unstable; urgency=low + + * Upload initial version: image view, slide show + * Git: 165.213.180.234:/git/slp/pkgs/ug-image-viewer-efl + * Tag: ug-image-viewer-efl_1.0-4 + + -- Li Suxia Thu, 19 Aug 2010 11:15:25 +0800 + +ug-image-viewer-efl (1.0-1) unstable; urgency=low + + * Upload initial version: image view, slide show + * Git: 165.213.180.234:/git/slp/pkgs/ug-image-viewer-efl + * Tag: ug-image-viewer-efl_1.0-1 + + -- Li Suxia Thu, 19 Aug 2010 10:09:25 +0800 + +ug-image-viewer-efl (1.0-0) unstable; urgency=low + + * Initial version + + -- Li Suxia Mon, 16 Aug 2010 14:00:29 +0900 diff --git a/res/images/T01_Nocontents_broken.png b/res/images/T01_Nocontents_broken.png new file mode 100755 index 0000000000000000000000000000000000000000..9326d0a5be19bea8add45169d1c4c03f40b54bec GIT binary patch literal 4880 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 literal 0 HcmV?d00001 diff --git a/res/manifest/ug-image-viewer-efl.xml b/res/manifest/ug-image-viewer-efl.xml new file mode 100755 index 0000000..0b8cf38 --- /dev/null +++ b/res/manifest/ug-image-viewer-efl.xml @@ -0,0 +1,26 @@ + + + + Jisung Ahn + Hyunwoo Kim + Image viewer Application + + ug-image-viewer-efl.png + + + + + + + + + + + + + + + + + + diff --git a/slideshow/CMakeLists.txt b/slideshow/CMakeLists.txt new file mode 100755 index 0000000..a6bfa40 --- /dev/null +++ b/slideshow/CMakeLists.txt @@ -0,0 +1,82 @@ +CMAKE_MINIMUM_REQUIRED(VERSION 2.6) +PROJECT(ivug_slideshow C CXX) + +SET(PREFIX ${CMAKE_INSTALL_PREFIX}) +SET(VERSION 0.1.0) + +SET(SRCS +# Effect files + src/ivug-slideshow.cpp + src/effect/ivug-xcapture.c + src/effect/ivug-blind.c + src/effect/ivug-iris.c + src/effect/ivug-fade.c + src/effect/ivug-dissolve.c + src/effect/ivug-effect.c + src/effect/ivug-slide.c + src/effect/ivug-anim.c +) + + +INCLUDE_DIRECTORIES( + ${CMAKE_SOURCE_DIR}/include + ${IVUG_SOURCE_WIDGET_DIR}/include + ${IVUG_SOURCE_COMMON_DIR}/include + ${IVUG_SOURCE_MEDIA_DIR}/include + ${IVUG_SOURCE_FEATURE_DIR}/include + include + src/effect/include +) + +MESSAGE("Checking " ${PROJECT_NAME} ) + +INCLUDE(FindPkgConfig) +pkg_check_modules(${PROJECT_NAME}_pkgs REQUIRED + elementary + ecore + ecore-evas + edje + eina + evas + dlog + ecore-x + xext + xcomposite + vconf + ui-gadget-1 + glib-2.0 + capi-system-power + capi-appfw-application +) + +FOREACH(flag ${${PROJECT_NAME}_pkgs_CFLAGS}) + SET(EXTRA_CXXFLAGS "${EXTRA_CXXFLAGS} ${flag}") +ENDFOREACH(flag) + +SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${EXTRA_CXXFLAGS} -Wall") +SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${CMAKE_CXX_FLAGS}") + +ADD_DEFINITIONS("-DPREFIX=\"${CMAKE_INSTALL_PREFIX}\"") +ADD_DEFINITIONS("-DLOG_LVL=DBG_MSG_LVL_HIGH") +ADD_DEFINITIONS("-DLOG_CAT=\"IV-WIDGET\"") + +ADD_LIBRARY(${PROJECT_NAME} SHARED ${SRCS}) + +SET_TARGET_PROPERTIES(${PROJECT_NAME} PROPERTIES SOVERSION ${VERSION} ) +SET_TARGET_PROPERTIES(${PROJECT_NAME} PROPERTIES INSTALL_RPATH ${CMAKE_INSTALL_PREFIX}/lib) + +TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${${PROJECT_NAME}_pkgs_LDFLAGS} + ivug_common ivug_medialist ivug_widget ivug_feature +) + +#install resouce files. +# Lack of a trailing slash means install this directory, trailing slash means +# install everything in this directory. + +BUILD_EDJ(ivug-ss-ly.edc ivug-ss-ly.edj res/layout icons) + +# Install image files. +INSTALL(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/res/images/ DESTINATION ${CMAKE_INSTALL_PREFIX}/res/images/${IVUG_PACKAGE_NAME}) + +INSTALL(TARGETS ${PROJECT_NAME} DESTINATION lib) + diff --git a/slideshow/include/ivug-slideshow.h b/slideshow/include/ivug-slideshow.h new file mode 100755 index 0000000..1c90f5f --- /dev/null +++ b/slideshow/include/ivug-slideshow.h @@ -0,0 +1,137 @@ +/* + * Copyright 2012 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.tizenopensource.org/license + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +// Slide Show + +/* + Start slide show. + + if bSlideFirst == EINA_TRUE, slide and then wait interval time + if bSlideFirst == EINA_FALSE, wait interval time and then slide +*/ +#include +#include +#include + +#include "ivug-medialist.h" +#include "ivug-config.h" +#include "ivug-effect.h" + +#define DATA_PATH DATADIR"/"PACKAGE + +typedef void (*ivug_slideshow_finish_cb)(Media_Data *cur_sd, void* user_data); + +typedef enum { + SLIDE_SHOW_STOPPED = 0x00, + SLIDE_SHOW_INTERRUPTED, + SLIDE_SHOW_RUNNING, + SLIDE_SHOW_PAUSE, +} slideshow_state_t; + +typedef struct +{ + void *pSlideshow; //SlideShow * + Evas_Object *layout; + Evas_Object *photocam; + Evas_Object *thumbnail; + + Media_Item *mitem; + + int x; // Need?? + int y; + +} Slide_Layout; + +typedef struct _SlideShow +{ + Evas_Object *obj; // Slide show view. + Evas_Object *event; // Mouse event + +/* slide show setting */ + double ss_interval_time; + slide_show_mode ss_mode; + +/* slide show effect*/ + Effect_Type effect_type; + Effect_Engine* effect_engine; + +//slider show. + slideshow_state_t state; + + Ecore_Timer *ss_timer; //slide show timer + Ecore_Timer *click_timer; + ivug_slideshow_finish_cb ss_func; // Callback for slide show finished + void* ss_user_data; + Eina_Bool bSS_StopFlag; /* request slide show stop flag */ + +// Data + Media_List *media_list; + Media_Item *ss_Header; // Start point + +// Layout. + int sCurrent; // 0 or 1 + Slide_Layout sLayout[2]; + +// State variables. + int screen_w; + int screen_h; + + + Ecore_Idler *load_idler; +}SlideShow; + +SlideShow * +ivug_ss_create(Evas_Object *parent); + +bool +ivug_ss_start(SlideShow *pSlideShow , Media_Item *current, Media_List *list, Eina_Bool bSlideFirst); + +bool +ivug_ss_resume(SlideShow *pSlideShow); + +bool +ivug_ss_pause(SlideShow *pSlideShow); + +bool +ivug_ss_stop(SlideShow *pSlideShow); + +void +ivug_ss_delete(SlideShow *pSlideShow); + +void +ivug_ss_resize(SlideShow *pSlideShow); + +Media_Item * +ivug_ss_item_get(SlideShow *pSlideShow); + +Evas_Object * +ivug_ss_object_get(SlideShow *pSlideShow); + +bool +ivug_ss_set_music(SlideShow *pSlideShow, const char *path); + +void +ivug_ss_get_screen_size(int *width, int *height); + +Media_Item * +ivug_ss_get_next_item(Media_List *mList, + Media_Item *header, + Media_Item *current, + slide_show_mode mode); + + diff --git a/slideshow/res/images/T01_Noise.png b/slideshow/res/images/T01_Noise.png new file mode 100755 index 0000000000000000000000000000000000000000..d76dbfad42fe2e39485ca524eecbfd399ba0ff94 GIT binary patch literal 7937 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

~Y r?MER#Psokm@3yN}!}%|*e`9RM&0{%>$V<~LFR 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 HnScHdLKhRd literal 0 HcmV?d00001 diff --git a/slideshow/res/layout/ivug-ss-ly.edc b/slideshow/res/layout/ivug-ss-ly.edc new file mode 100755 index 0000000..6018b80 --- /dev/null +++ b/slideshow/res/layout/ivug-ss-ly.edc @@ -0,0 +1,146 @@ +/* + * Copyright 2012 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.tizenopensource.org/license + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +collections { + group { + name: "view.slideshow"; + parts { + part { name: "bg"; + type: RECT; + scale: 1; + mouse_events: 1; + repeat_events: 1; + description { + state: "default" 0.0; + color: 0 0 0 255; + visible: 1; + rel1 { relative: 0.0 0.0;} + rel2 { relative: 1.0 1.0;} + } + } + } + + } +} + + +collections { + group { + name: "slayout"; + images { + image: "T01_btn_play.png" COMP; + } + parts { + /* add bg to unsend events to slider layer */ + part { name: "bg"; + type: RECT; + scale: 1; + mouse_events: 1; + //repeat_events: 1; + description { + state: "default" 0.0; + visible: 1; + color: 0 0 0 255; + rel1 { relative: 0.0 0.0;} + rel2 { relative: 1.0 1.0;} + } + } + part { name: "content"; + type: SWALLOW; + scale: 1; + mouse_events: 1; + repeat_events: 1; + description { + state: "default" 0.0; + visible: 1; + rel1 { relative: 0.0 0.0;} + rel2 { relative: 1.0 1.0;} + } + } + part { name: "thumbnail"; + type: SWALLOW; + mouse_events: 1; + scale: 1; + description { + state: "default" 0.0; + align: 0.5 0.5; + visible: 0; + rel1 { relative: 0.0 0.0; } + rel2 { relative: 1.0 1.0; } + } + + description { + state: "show" 0.0; + inherit: "default" 0.0; + visible: 1; + } + } + part { name: "play.icon"; + type: IMAGE; + mouse_events: 1; + scale: 1; + description { + state: "default" 0.0; + align: 0.5 0.5; + visible: 0; + fixed: 1 1; + max: 72 72; + rel1 { relative: 0.0 0.0; } + rel2 { relative: 1.0 1.0; } + image.normal: "T01_btn_play.png"; + } + + description { + state: "show" 0.0; + inherit: "default" 0.0; + visible: 1; + } + } + } + programs { + program { + name: "show_thumbnail"; + signal: "elm,state,show_thumbnail"; + source: "slideshow"; + action: STATE_SET "show" 0.0; + target: "thumbnail"; + } + + program { + name: "hide_thumbnail"; + signal: "elm,state,hide_thumbnail"; + source: "slideshow"; + action: STATE_SET "default" 0.0; + target: "thumbnail"; + } + program { + name: "show_icon"; + signal: "elm,state,show_play_icon"; + source: "slideshow"; + action: STATE_SET "show" 0.0; + target: "play.icon"; + } + + program { + name: "hide_icon"; + signal: "elm,state,hide_play_icon"; + source: "slideshow"; + action: STATE_SET "default" 0.0; + target: "play.icon"; + } + } + } +} diff --git a/slideshow/src/effect/include/ivug-anim.h b/slideshow/src/effect/include/ivug-anim.h new file mode 100755 index 0000000..1735e4e --- /dev/null +++ b/slideshow/src/effect/include/ivug-anim.h @@ -0,0 +1,64 @@ +/* + * Copyright 2012 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.tizenopensource.org/license + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __IVUG_ANIM_H__ +#define __IVUG_ANIM_H__ + +#include + +typedef enum { + ANIM_TYPE_LINEAR, + ANIM_TYPE_QUARTIC_INOUT, + ANIM_TYPE_QUINTIC_INOUT, + ANIM_TYPE_SINE, +} anim_type_t; + +/* + t: current time b: start time c: change in value d: duration +*/ +typedef double (*anim_transit_func_t) (double t, double b, double c, double d); + +typedef struct { +/* private */ + double duration; + double t_start; + double t_varing; + + anim_transit_func_t transit_func; + + void *user_data; +} anim_handle_t; + +#ifdef __cplusplus +extern "C" { +#endif + +anim_handle_t *create_animation(); + +void delete_animation(anim_handle_t *anim); + +bool update_animation(anim_handle_t *anim, double current, double *value); + +bool set_animation_type(anim_handle_t *anim, anim_type_t type); + +bool set_animation(anim_handle_t *anim, int start, int end, double duration); + +#ifdef __cplusplus +} +#endif + + +#endif diff --git a/slideshow/src/effect/include/ivug-effect.h b/slideshow/src/effect/include/ivug-effect.h new file mode 100755 index 0000000..80e604f --- /dev/null +++ b/slideshow/src/effect/include/ivug-effect.h @@ -0,0 +1,98 @@ +/* + * Copyright 2012 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.tizenopensource.org/license + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __IVUG_EFFECT_H__ +#define __IVUG_EFFECT_H__ + +#include +#include +#include "ivug-anim.h" + +#define EFFECT_LBYTES_ARGB8888(w) (((w) * 4)) +#define MAX_PERCENT (100.0f) +#define MIN_PERCENT (0.0f) + +#ifdef __cplusplus +extern "C" { +#endif + +typedef void *Effect_Data ; + +typedef void (*FuncFinished)(void *data); + +typedef struct { + Effect_Data eng_data; + + FuncFinished pFinishedCB; + void *ClientData; + + double t_base; // start time. + anim_handle_t *anim; + Ecore_Animator *animator; + + struct { + Effect_Data (*init) (Evas_Object *src, Evas_Object *dst); + bool (*set_size) (Effect_Data data, int screen_w, int screen_h, int rotation); + void (*animate) (Effect_Data data, double percent); + void (*pause) (Effect_Data data); /* Not used*/ + void (*resume) (Effect_Data data); /* Not used*/ + void (*finalize) (Effect_Data data); + + double (*get_duration)(Effect_Data data); + } func; + +} Effect_Engine; + +typedef enum _Effect_Type { + EFFECT_NONE, + EFFECT_IRIS, + EFFECT_DISSOLVE, + EFFECT_SLIDE, + EFFECT_DISSOLVE_FADE, + EFFECT_SPLIT, + EFFECT_MAX +} Effect_Type; + + + + + +Effect_Engine *ivug_effect_add(Effect_Type type); + +bool ivug_effect_init(Effect_Engine *engine, Evas_Object *src, Evas_Object *dst); +bool ivug_effect_set_size(Effect_Engine *engine, int w, int h, int rotation); +bool ivug_effect_start(Effect_Engine *engine, FuncFinished pFunc, void *data); +bool ivug_effect_pause(Effect_Engine *engine); +bool ivug_effect_resume(Effect_Engine *engine); +bool ivug_effect_finalize(Effect_Engine *engine); + + +/* + Private function for adding effect. Do not use below functions directly.. +*/ +Effect_Engine *ivug_fade_add(void); +Effect_Engine *ivug_iris_add(void); +Effect_Engine *ivug_dissolve_add(void); +Effect_Engine *ivug_blind_add(void); +Effect_Engine *ivug_slide_add(void); + + +#ifdef __cplusplus +} +#endif + + +#endif /* __IVUG_EFFECT_H__ */ diff --git a/slideshow/src/effect/ivug-anim.c b/slideshow/src/effect/ivug-anim.c new file mode 100755 index 0000000..5c46a87 --- /dev/null +++ b/slideshow/src/effect/ivug-anim.c @@ -0,0 +1,177 @@ +/* + * Copyright 2012 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.tizenopensource.org/license + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +#include /* for NULL */ +#include +#include + +#include "ivug-debug.h" +#include "ivug-anim.h" + +/* + t: current time b: start time c: change in value d: duration +*/ +static double _anim_linear(double t, double b, double c, double d) +{ + if(d != 0.0) + t /= d; + return b + c * (t); +} + +static double _anim_sine(double t, double b, double c, double d) +{ +/* TODO : Consider below table reconstruct. need only 0.0 ~ 1.0 range*/ + static const double const SIN_TABLE[91] = { + 0.0000f, 0.0174f, 0.0349f, 0.0523f, 0.0698f, + 0.0872f, 0.1045f, 0.1219f, 0.1392f, 0.1564f, + 0.1736f, 0.1908f, 0.2079f, 0.2249f, 0.2419f, + 0.2588f, 0.2756f, 0.2924f, 0.3090f, 0.3256f, + 0.3420f, 0.3584f, 0.3746f, 0.3907f, 0.4067f, + 0.4226f, 0.4384f, 0.4540f, 0.4695f, 0.4848f, + 0.5000f, 0.5150f, 0.5299f, 0.5446f, 0.5592f, + 0.5736f, 0.5878f, 0.6018f, 0.6157f, 0.6293f, + 0.6528f, 0.6561f, 0.6691f, 0.6820f, 0.6947f, + 0.7071f, 0.7193f, 0.7314f, 0.7431f, 0.7547f, + 0.7660f, 0.7772f, 0.7880f, 0.7986f, 0.8090f, + 0.8191f, 0.8290f, 0.8387f, 0.8480f, 0.8571f, + 0.8660f, 0.8746f, 0.8829f, 0.8910f, 0.8988f, + 0.9063f, 0.9135f, 0.9205f, 0.9272f, 0.9336f, + 0.9397f, 0.9455f, 0.9511f, 0.9563f, 0.9613f, + 0.9659f, 0.9703f, 0.9744f, 0.9781f, 0.9816f, + 0.9848f, 0.9877f, 0.9903f, 0.9926f, 0.9945f, + 0.9962f, 0.9976f, 0.9986f, 0.9994f, 0.9998f, + 1.0f + }; + + if(d != 0.0) + t /= d; /* normalize */ + + int idx = (int)(90.0 * t); + + return b + c * (SIN_TABLE[idx]); + +} + +static double _anim_ease_inout_quartic(double t, double b, + double c, double d) +{ + if(d != 0.0) + t /= d; + double ts = t * t; + double tc = ts * t; + return b + c * (-2 * tc + 3 * ts); + +} + +static double _anim_ease_inout_quintic(double t, double b, + double c, double d) +{ + if(d != 0.0) + t /= d; + double ts = t * t; + double tc = ts * t; + return b + c * (6 * tc * ts + -15 * ts * ts + 10 * tc); +} + +anim_handle_t *create_animation() +{ + anim_handle_t *anim; + + anim = calloc(1, sizeof(anim_handle_t)); + + if (anim == NULL) { + MSG_IVUG_ERROR("Cannot allocate memory"); + return NULL; + } + + return anim; + +} + +void delete_animation(anim_handle_t *anim) +{ + IV_ASSERT(anim != NULL); + + free(anim); + +} + +bool set_animation_type(anim_handle_t *anim, anim_type_t type) +{ + IV_ASSERT(anim != NULL); + + switch (type) { + case ANIM_TYPE_LINEAR: + anim->transit_func = _anim_linear; + break; + case ANIM_TYPE_QUARTIC_INOUT: + anim->transit_func = _anim_ease_inout_quartic; + break; + + case ANIM_TYPE_QUINTIC_INOUT: + anim->transit_func = _anim_ease_inout_quintic; + break; + + case ANIM_TYPE_SINE: + anim->transit_func = _anim_sine; + break; + default: + MSG_IVUG_ERROR("Invalid transition type=%d", type); + return false; + break; + } + + return true; +} + +bool set_animation(anim_handle_t *anim, int start, int end, double duration) +{ + IV_ASSERT(anim != NULL); + + //MSG_IVUG_HIGH("Set Anim. Start=%d End=%d Dur=%f", start, end, duration); + anim->duration = duration; + anim->t_start = start; + anim->t_varing = end - start; + + return true; +} + +bool update_animation(anim_handle_t *anim, double current, double *value) +{ + //MSG_IVUG_HIGH("update_animation"); + IV_ASSERT(anim != NULL); + IV_ASSERT(anim->transit_func != NULL); + + if (current >= anim->duration) { + *value = anim->t_start + anim->t_varing; + //MSG_IVUG_HIGH("End Start:%f Varing:%f Duration=%f", + //anim->t_start, anim->t_varing, anim->duration); + + //MSG_IVUG_HIGH("End Current=%f Value=%f", current, *value); + + return false; /* End of animation */ + } + + MSG_EFFECT_LOW("Start:%f Varing:%f Duration=%f Current=%f", anim->t_start, anim->t_varing, anim->duration, current); + + *value = anim->transit_func(current, anim->t_start, anim->t_varing, + anim->duration); + + MSG_EFFECT_LOW("Value = %f", *value); + + return true; +} diff --git a/slideshow/src/effect/ivug-blind.c b/slideshow/src/effect/ivug-blind.c new file mode 100755 index 0000000..6d4b533 --- /dev/null +++ b/slideshow/src/effect/ivug-blind.c @@ -0,0 +1,313 @@ +/* + * Copyright 2012 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.tizenopensource.org/license + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "ivug-debug.h" +#include "ivug-xcapture.h" +#include "ivug-effect.h" + +/* Currently only 4 is supported */ +#define DEFAULT_MAP_COUNT (4) +#define DEFAULT_FOCUL_DISTANCE (10000) + +#define DEFAULT_START_ANGLE (0.0f) +#define DEFAULT_END_ANGLE (90.0f) + +#define MAX_BLIND_NUM 8 + +typedef struct _Blind_Rotation Blind_Rotation; + +struct _Blind_Rotation { + bool cw; /* Clockwise rotation */ + float from, to; /* rotate angle: 0 ~ 360 */ +}; + +typedef struct _Blind_Data Blind_Data; + +struct _Blind_Data { + int bx; + int by; + int bw; + int bh; + + Evas_Object * img[MAX_BLIND_NUM]; + + Evas_Object * dst; + + Evas * evas; + + Blind_Rotation rotation; +}; + +static bool +__ivug_blind_image_create(Evas *e, Blind_Data *engine, + int *src_data) +{ + ivug_retvm_if(e == NULL, false, "Evas is NULL"); + ivug_retvm_if(engine == NULL, false, "engine is NULL"); + ivug_retvm_if(src_data == NULL, false, "src_data is NULL"); + + Blind_Data *eng_data = engine; + + ivug_retvm_if((eng_data->bw <= 0 || eng_data->bh <= 0), false, + "bw or bh is 0: [%d, %d]", eng_data->bw, eng_data->bh); + + int index; + int row = 0; + int col = 0; + + int *psrc = src_data; + int *dst_data = NULL; + + for (index = 0; index < MAX_BLIND_NUM; index++) { + eng_data->img[index] = evas_object_image_filled_add(e); + evas_object_image_size_set(eng_data->img[index], eng_data->bw, + eng_data->bh); + evas_object_image_fill_set(eng_data->img[index], 0, 0, + eng_data->bw, eng_data->bh); + evas_object_image_data_update_add(eng_data->img[index], 0, 0, + eng_data->bw, eng_data->bh); + + dst_data = + evas_object_image_data_get(eng_data->img[index], + EINA_TRUE); + + row = eng_data->bw; + col = eng_data->bh; + while (col--) { + while (row--) { + *dst_data++ = *psrc++; + } + + row = eng_data->bw; + } + + evas_object_resize(eng_data->img[index], eng_data->bw, + eng_data->bh); + evas_object_move(eng_data->img[index], eng_data->bx, + eng_data->by + eng_data->bh * index); + evas_object_show(eng_data->img[index]); + } + + return true; +} + +static Effect_Data __ivug_blind_init(Evas_Object *src, Evas_Object *dst) +{ + IV_ASSERT(src != NULL); + + Blind_Data *eng_data = calloc(1, sizeof(Blind_Data)); + if (eng_data == NULL) { + MSG_EFFECT_ERROR("Memory calloc failed"); + return NULL; + } + + eng_data->evas = evas_object_evas_get(src); + + Evas_Coord x, y, w, h; + evas_object_geometry_get(src, &x, &y, &w, &h); + + eng_data->bx = x; + eng_data->by = y; + + eng_data->dst = dst; + + evas_object_stack_below(dst, src); + evas_object_move(dst, 0, 0); + + eng_data->rotation.cw = true; + eng_data->rotation.from = DEFAULT_START_ANGLE; + eng_data->rotation.to = DEFAULT_END_ANGLE; + + /* Need hide the img_object here */ + evas_object_hide(src); + + return (Effect_Data)eng_data; +} + +static bool __ivug_blind_set_size(void *data, int screen_w, int screen_h, int rotation) +{ + IVUG_FUNC_ENTER(); + + ivug_retvm_if((screen_w <= 0 + || screen_h <= 0), false, + "screen_w or screen_h <= 0: [%d, %d]", screen_w, + screen_h); + + Blind_Data *eng_data = (Blind_Data *) data; + + /* Get the data from ecore evas */ + int size = 0; + int *src_data = (int *)ivug_xcapture_screen_data_get(&size, rotation); + ivug_retvm_if(src_data == NULL, false, "screen data is NULL"); + + if (size != screen_h * EFFECT_LBYTES_ARGB8888(screen_w)) { + MSG_EFFECT_ERROR("Screen data size is invalid: %d", size); + + free(src_data); + src_data = NULL; + + return false; + } + + eng_data->bw = screen_w; + eng_data->bh = screen_h / MAX_BLIND_NUM; + + MSG_EFFECT_HIGH("eng_data->bw = %d, eng_data->bh = %d", eng_data->bw, + eng_data->bh); + + int index; + for (index = 0; index < MAX_BLIND_NUM; index++) { + evas_object_del(eng_data->img[index]); + eng_data->img[index] = NULL; + } + + bool ret = __ivug_blind_image_create(eng_data->evas, + eng_data, src_data); + if (ret == false) { + MSG_EFFECT_ERROR("Create effect image failed"); + + free(src_data); + src_data = NULL; + + return false; + } + + free(src_data); + src_data = NULL; + + evas_object_move(eng_data->dst, 0, 0); + + IVUG_FUNC_LEAVE(); + + return true; +} + +static void _ivug_blind_rotation_op(void *data, double frame) +{ + IVUG_FUNC_ENTER(); + + Blind_Data *eng_data = (Blind_Data *) data; + ivug_retm_if(eng_data == NULL, "eng_data is NULL"); + + Blind_Rotation *rotation = &(eng_data->rotation); + + float degree; + + degree = rotation->from + (float)(frame * rotation->to); + + if (!rotation->cw) { + degree *= -1; + } + + MSG_EFFECT_MED("frame = %f, degree = %f", frame, degree); + + int offset = eng_data->bh / 2; + int y; + + Evas_Map *map = NULL; + int index; + for (index = 0; index < MAX_BLIND_NUM; index++) { + map = evas_map_new(DEFAULT_MAP_COUNT); + if (map == NULL) { + MSG_EFFECT_ERROR("Create map failed"); + break; + } + + evas_map_smooth_set(map, EINA_TRUE); + evas_map_util_points_populate_from_object_full(map, + eng_data->img + [index], 0); + + y = index * eng_data->bh + offset; + + evas_map_util_3d_rotate(map, degree, 0, 0, eng_data->bw / 2, y, 0); + evas_map_util_3d_perspective(map, eng_data->bw / 2, y, 0, + DEFAULT_FOCUL_DISTANCE); + + evas_object_map_enable_set(eng_data->img[index], EINA_TRUE); + evas_object_map_set(eng_data->img[index], map); + evas_map_free(map); + } + + IVUG_FUNC_LEAVE(); +} + +static void __ivug_blind_anim(void *data, double percent) +{ +/* IVUG_FUNC_ENTER(); */ + + ivug_retm_if(data == NULL, "data is NULL"); + + Blind_Data *eng_data = (Blind_Data *) data; + + ivug_retm_if((percent < MIN_PERCENT + || percent > MAX_PERCENT), + "Invalide value: percent = [%f]", percent); + + double frame = percent / MAX_PERCENT; + _ivug_blind_rotation_op(eng_data, frame); + +/* IVUG_FUNC_LEAVE(); */ +} + +static void __ivug_blind_pause(void *data) +{ + IVUG_FUNC_ENTER(); + + IVUG_FUNC_LEAVE(); +} + +static void __ivug_blind_resume(void *data) +{ + IVUG_FUNC_ENTER(); + + IVUG_FUNC_LEAVE(); +} + +static void __ivug_blind_finialize(void *data) +{ + IVUG_FUNC_ENTER(); + + ivug_retm_if(data == NULL, "data is NULL"); + + Blind_Data *eng_data = (Blind_Data *) data; + + int index; + for (index = 0; index < MAX_BLIND_NUM; index++) { + evas_object_del(eng_data->img[index]); + eng_data->img[index] = NULL; + } + + free(eng_data); + eng_data = NULL; + + IVUG_FUNC_LEAVE(); +} + +Effect_Engine *ivug_blind_add(void) +{ + Effect_Engine *eng_blind = calloc(1, sizeof(Effect_Engine)); + ivug_retvm_if(eng_blind == NULL, NULL, "calloc failed"); + + eng_blind->func.init = &__ivug_blind_init; + eng_blind->func.set_size = &__ivug_blind_set_size; + eng_blind->func.animate = &__ivug_blind_anim; + eng_blind->func.pause = &__ivug_blind_pause; + eng_blind->func.resume = &__ivug_blind_resume; + eng_blind->func.finalize = &__ivug_blind_finialize; + + return eng_blind; +} diff --git a/slideshow/src/effect/ivug-dissolve.c b/slideshow/src/effect/ivug-dissolve.c new file mode 100755 index 0000000..37f5e57 --- /dev/null +++ b/slideshow/src/effect/ivug-dissolve.c @@ -0,0 +1,369 @@ +/* + * Copyright 2012 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.tizenopensource.org/license + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +#include "ivug-debug.h" + +#include "ivug-xcapture.h" +#include "ivug-effect.h" + +#define BLOCK_ROW_NUM 20 +#define BLOCK_COL_NUM 12 + +#define DISSOLVE_NUM 240 // 20 * 12 + +/* TODO: Optimize the order */ +const int const DISSOLVE_TABLE[DISSOLVE_NUM] = { + 201, 8, 82, 163, 181, 215, 0, 126, 30, 106, + 162, 122, 216, 18, 99, 70, 223, 89, 22, 191, + 103, 235, 154, 230, 50, 231, 14, 135, 60, 10, + 114, 210, 53, 113, 17, 199, 42, 165, 229, 100, + 97, 45, 125, 34, 15, 64, 48, 202, 150, 80, + 130, 2, 61, 86, 159, 239, 207, 95, 164, 168, + 55, 75, 169, 6, 145, 149, 173, 208, 205, 4, + 124, 13, 116, 194, 198, 175, 94, 176, 81, 144, + 184, 180, 187, 66, 72, 206, 24, 225, 220, 59, + 3, 182, 93, 237, 16, 227, 54, 119, 183, 38, + 101, 107, 21, 23, 143, 186, 233, 28, 213, 52, + 136, 31, 179, 228, 7, 129, 185, 123, 147, 131, + 111, 234, 192, 33, 139, 203, 160, 137, 47, 40, + 141, 172, 65, 157, 43, 88, 218, 44, 83, 62, + 217, 178, 193, 109, 189, 151, 115, 39, 91, 19, + 138, 76, 190, 209, 79, 63, 158, 196, 85, 214, + 56, 152, 108, 27, 222, 46, 156, 177, 105, 37, + 71, 96, 26, 87, 221, 68, 110, 117, 78, 112, + 188, 74, 77, 92, 69, 170, 238, 120, 35, 51, + 211, 146, 11, 148, 58, 5, 174, 41, 161, 84, + 12, 121, 171, 25, 1, 226, 166, 195, 134, 153, + 212, 142, 29, 9, 155, 132, 67, 200, 73, 127, + 197, 232, 140, 224, 104, 167, 90, 102, 57, 204, + 133, 128, 49, 118, 32, 219, 20, 236, 36, 98 +}; + +typedef struct _Dissolve_Data Dissolve_Data; + +struct _Dissolve_Data { + int screen_w; + int screen_h; + + int screen_x; + int screen_y; + + int block_w; /* block width*/ + int block_h; /* block height*/ + + int n_row; /* row number*/ + int n_col; /* col number*/ + + Evas_Object **diss_img; + Evas * evas; + Evas_Object *src; + Evas_Object *dst; +}; + +static bool +__ivug_dissolve_image_create(Evas *evas, Dissolve_Data * eng_data, + int *src_data) +{ + ivug_retvm_if(evas == NULL, false, "Evas is NULL"); + ivug_retvm_if(eng_data == NULL, false, "eng_data is NULL"); + ivug_retvm_if(src_data == NULL, false, "src_data is NULL"); + + ivug_retvm_if((eng_data->block_w <= 0 || eng_data->block_h <= 0), false, + "screen_w or screen_h is: [%d, %d]", eng_data->block_w, + eng_data->block_h); + + ivug_retvm_if((eng_data->n_row <= 0 || eng_data->n_col <= 0), false, + "n_row or n_col is: [%d, %d]", eng_data->n_row, + eng_data->n_col); + + int *psrc = NULL; + Evas_Object *img_obj = NULL; + int *dst_data = NULL; + + int i, j; + int start_pos = 0; + int index; + for (i = 0; i < eng_data->n_row; i++) { + for (j = 0; j < eng_data->n_col; j++) { + img_obj = evas_object_image_filled_add(evas); + evas_object_image_size_set(img_obj, eng_data->block_w, + eng_data->block_h); + + /* Locate at the left-top corner*/ + start_pos = + i * eng_data->screen_w * eng_data->block_h + + j * eng_data->block_w; + psrc = src_data + start_pos; +// MSG_EFFECT_HIGH("start_pos is %d", start_pos); + + /* Set the image data*/ + dst_data = evas_object_image_data_get(img_obj, + EINA_TRUE); + int row = eng_data->block_w; + int col = eng_data->block_h; + + while (col--) { + while (row--) { + *dst_data++ = *psrc++; + } + + row = eng_data->block_w; + psrc += (eng_data->n_col - 1) * row; + } + + evas_object_image_alpha_set(img_obj, EINA_TRUE); + evas_object_resize(img_obj, eng_data->block_w, + eng_data->block_h); + + /* Change the position*/ + int pos_x, pos_y; + pos_x = eng_data->screen_x + j * eng_data->block_w; + pos_y = eng_data->screen_y + i * eng_data->block_h; + +// MSG_EFFECT_HIGH("[pos_x, pos_y] is [%d, %d]\n", pos_x, +// pos_y); + evas_object_move(img_obj, pos_x, pos_y); + evas_object_show(img_obj); + + index = i * eng_data->n_col + j; + eng_data->diss_img[index] = img_obj; + } + } + + return true; +} + +static Effect_Data __ivug_dissolve_init(Evas_Object *src, Evas_Object *dst) +{ + IVUG_FUNC_ENTER(); + + IV_ASSERT(src != NULL); + + Dissolve_Data *eng_data = calloc(1, sizeof(Dissolve_Data)); + if (eng_data == NULL) { + MSG_EFFECT_ERROR("calloc for eng_data failed"); + return NULL; + } + + eng_data->evas = evas_object_evas_get(src); + + eng_data->src = src; + eng_data->dst = dst; + + evas_object_stack_below(dst, src); + evas_object_move(dst, 0, 0); + + /* Need hide the img_object here*/ + evas_object_hide(src); + + IVUG_FUNC_LEAVE(); + + return (Effect_Data)eng_data; +} + +static bool __ivug_dissolve_set_size(void *data, int screen_w, int screen_h, int rotation) +{ + IVUG_FUNC_ENTER(); + + IV_ASSERT(data != NULL); + + ivug_retvm_if((screen_w <= 0 + || screen_h <= 0), false, + "screen_w or screen_h <= 0: [%d, %d]", screen_w, + screen_h); + + MSG_EFFECT_HIGH("[screen_w, screen_h] = [%d, %d]", screen_w, screen_h); + + Dissolve_Data *eng_data = (Dissolve_Data *) data; + + /* Get the data from ecore evas*/ + int size = 0; + char *src_data = ivug_xcapture_screen_data_get(&size, rotation); + ivug_retvm_if(src_data == NULL, false, "screen data is NULL"); + + if (size != screen_h * EFFECT_LBYTES_ARGB8888(screen_w)) { + MSG_EFFECT_ERROR("Screen data size is invalid: %d", size); + + free(src_data); + src_data = NULL; + + return false; + } + + Evas_Coord x, y, w, h; + evas_object_geometry_get(eng_data->src, &x, &y, &w, &h); + eng_data->screen_x = x; + eng_data->screen_y = y; + eng_data->screen_w = w; + eng_data->screen_h = h; + + if(rotation == 0 || rotation == 180) + { + eng_data->n_row = BLOCK_ROW_NUM; + eng_data->n_col = BLOCK_COL_NUM; + } + else + { + eng_data->n_row = BLOCK_COL_NUM; + eng_data->n_col = BLOCK_ROW_NUM; + } + eng_data->block_h = eng_data->screen_h / eng_data->n_row; + eng_data->block_w = eng_data->screen_w / eng_data->n_col; + + MSG_EFFECT_HIGH("[n_row, n_col] is [%d, %d]", eng_data->n_row, + eng_data->n_col); + MSG_EFFECT_HIGH("[block_h, block_w] is [%d, %d]", eng_data->block_h, + eng_data->block_w); + + int block_num = eng_data->n_row * eng_data->n_col; + MSG_EFFECT_HIGH("block_num is %d", block_num); + + int i; + if(eng_data->diss_img != NULL) + { + for (i = 0; i < block_num; i++) { + if (eng_data->diss_img[i]) { + evas_object_del(eng_data->diss_img[i]); + } + eng_data->diss_img[i] = NULL; + } + free(eng_data->diss_img); + } + + eng_data->diss_img = (Evas_Object **)calloc(1, block_num * + sizeof(Evas_Object *)); + + bool ret = __ivug_dissolve_image_create(eng_data->evas, eng_data, + (int *)src_data); + if (!ret) { + MSG_EFFECT_ERROR("Create images failed"); + + free(src_data); + src_data = NULL; + + return false; + } + + free(src_data); + src_data = NULL; + + evas_object_move(eng_data->dst, 0, 0); + + IVUG_FUNC_LEAVE(); + + return true; +} + +static void __ivug_dissolve_image_data_clear(Evas_Object *image) +{ + ivug_retm_if(!image, "image object is NULL"); + + int w, h; + evas_object_image_size_get(image, &w, &h); + ivug_retm_if(w <= 0, "image width is less than 0"); + ivug_retm_if(h <= 0, "image height is less than 0"); + + int *data = evas_object_image_data_get(image, EINA_TRUE); + ivug_retm_if(!data, "data is NULL"); + + int size = w * h; + + memset(data, 0x0, size * sizeof(int)); + evas_object_image_data_update_add(image, 0, 0, w, h); +} + +static void __ivug_dissolve_anim(void *data, double percent) +{ +/* IVUG_FUNC_ENTER();*/ + + Dissolve_Data *eng_data = (Dissolve_Data *) data; + + ivug_retm_if(eng_data == NULL, "data is NULL"); + ivug_retm_if(eng_data->diss_img == NULL, "dissolve image is NULL"); + + int count = (eng_data->n_row * eng_data->n_col) * percent / MAX_PERCENT; + MSG_EFFECT_MED("percent = %f, count = %d", percent, count); + + /* TODO: Start from last cleared pos */ + int i; + for (i = 0; i < count; i++) { + MSG_EFFECT_MED("diss_array[%d] = %d", i, DISSOLVE_TABLE[i]); + __ivug_dissolve_image_data_clear(eng_data-> + diss_img[DISSOLVE_TABLE[i]]); + } + +/* IVUG_FUNC_LEAVE();*/ +} + +static void __ivug_dissolve_pause(void *data) +{ + IVUG_FUNC_ENTER(); + + IVUG_FUNC_LEAVE(); +} + +static void __ivug_dissolve_resume(void *data) +{ + IVUG_FUNC_ENTER(); + + IVUG_FUNC_LEAVE(); +} + +static void __ivug_dissolve_finialize(void *data) +{ + IVUG_FUNC_ENTER(); + + ivug_retm_if(data == NULL, "data is NULL"); + + Dissolve_Data *eng_data = (Dissolve_Data *) data; + + if (eng_data->diss_img) { + int block_num = eng_data->n_row * eng_data->n_col; + int i; + + for (i = 0; i < block_num; i++) { + if (eng_data->diss_img[i]) { + evas_object_del(eng_data->diss_img[i]); + } + + eng_data->diss_img[i] = NULL; + } + + free(eng_data->diss_img); + eng_data->diss_img = NULL; + } + + free(eng_data); + eng_data = NULL; + + IVUG_FUNC_LEAVE(); +} + +Effect_Engine *ivug_dissolve_add(void) +{ + Effect_Engine *eng_dissolve = calloc(1, sizeof(Effect_Engine)); + ivug_retvm_if(eng_dissolve == NULL, NULL, "calloc failed"); + + eng_dissolve->func.init = &__ivug_dissolve_init; + eng_dissolve->func.set_size = &__ivug_dissolve_set_size; + eng_dissolve->func.animate = &__ivug_dissolve_anim; + eng_dissolve->func.pause = &__ivug_dissolve_pause; + eng_dissolve->func.resume = &__ivug_dissolve_resume; + eng_dissolve->func.finalize = &__ivug_dissolve_finialize; + + return eng_dissolve; +} diff --git a/slideshow/src/effect/ivug-effect.c b/slideshow/src/effect/ivug-effect.c new file mode 100755 index 0000000..4ac07b3 --- /dev/null +++ b/slideshow/src/effect/ivug-effect.c @@ -0,0 +1,233 @@ +/* + * Copyright 2012 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.tizenopensource.org/license + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "ivug-debug.h" +#include "ivug-effect.h" + +#define SIN_TABLE_NUM 91 + +/* Animation acceleration table */ +static const float const EFFECT_SIN_TABLE[SIN_TABLE_NUM] = { + 0.0000f, 0.0174f, 0.0349f, 0.0523f, 0.0698f, + 0.0872f, 0.1045f, 0.1219f, 0.1392f, 0.1564f, + 0.1736f, 0.1908f, 0.2079f, 0.2249f, 0.2419f, + 0.2588f, 0.2756f, 0.2924f, 0.3090f, 0.3256f, + 0.3420f, 0.3584f, 0.3746f, 0.3907f, 0.4067f, + 0.4226f, 0.4384f, 0.4540f, 0.4695f, 0.4848f, + 0.5000f, 0.5150f, 0.5299f, 0.5446f, 0.5592f, + 0.5736f, 0.5878f, 0.6018f, 0.6157f, 0.6293f, + 0.6528f, 0.6561f, 0.6691f, 0.6820f, 0.6947f, + 0.7071f, 0.7193f, 0.7314f, 0.7431f, 0.7547f, + 0.7660f, 0.7772f, 0.7880f, 0.7986f, 0.8090f, + 0.8191f, 0.8290f, 0.8387f, 0.8480f, 0.8571f, + 0.8660f, 0.8746f, 0.8829f, 0.8910f, 0.8988f, + 0.9063f, 0.9135f, 0.9205f, 0.9272f, 0.9336f, + 0.9397f, 0.9455f, 0.9511f, 0.9563f, 0.9613f, + 0.9659f, 0.9703f, 0.9744f, 0.9781f, 0.9816f, + 0.9848f, 0.9877f, 0.9903f, 0.9926f, 0.9945f, + 0.9962f, 0.9976f, 0.9986f, 0.9994f, 0.9998f, + 1.0f +}; + +#define SLIDESHOW_ANI_TIME (1.0f) + + +static Eina_Bool +_on_effect_animator(void *data) +{ + IV_ASSERT( data != NULL); + Effect_Engine *engine = data; + + double value = 0.0; + + if (update_animation(engine->anim, ecore_loop_time_get() - engine->t_base, &value) == false ) // If last frame + { + engine->animator = NULL; + + MSG_EFFECT_HIGH("Last effect frame. value=%f", value); + + engine->func.animate(engine->eng_data, value); // Draw last frame. + // Inform to user. + if ( engine->pFinishedCB ) + { + engine->pFinishedCB(engine->ClientData); + } + + return ECORE_CALLBACK_CANCEL; + } + + engine->func.animate(engine->eng_data, value); + + return ECORE_CALLBACK_RENEW; +} + + +bool ivug_effect_init(Effect_Engine *engine, Evas_Object *src, Evas_Object *dst) +{ + IV_ASSERT(engine != NULL ); + + void *data = engine->func.init(src, dst); + if (data == NULL) { + MSG_EFFECT_ERROR("init returned data is NULL"); + + return false; + } + + engine->eng_data = data; + + engine->anim = create_animation(); + return true; +} + +bool ivug_effect_set_size(Effect_Engine *engine, int w, int h, int rotation) +{ + IV_ASSERT(engine != NULL ); + IV_ASSERT(engine->eng_data != NULL); + + if (engine->func.set_size == NULL) + { + MSG_EFFECT_ERROR("engine->func.set_size is NULL"); + return false; + } + + MSG_EFFECT_HIGH("set size. WH(%d,%d) Rotation(%d)", w, h, rotation); + return engine->func.set_size(engine->eng_data, w, h, rotation); +} + + +bool ivug_effect_start(Effect_Engine *engine, FuncFinished pFunc, void *data) +{ + ivug_retvm_if(engine == NULL, false, "engine is NULL"); + + IV_ASSERT(engine->func.animate != NULL); + IV_ASSERT(engine->eng_data != NULL); + +// Set up slide show animator + engine->t_base = ecore_loop_time_get(); + + double duration = SLIDESHOW_ANI_TIME; + + if (engine->func.get_duration ) + { + duration = engine->func.get_duration(engine->eng_data); + } + + set_animation_type(engine->anim, ANIM_TYPE_LINEAR); + set_animation(engine->anim, 0, 100, duration); // 0~100% during 1 seconds + + engine->pFinishedCB = pFunc; + engine->ClientData = data; + + if (engine->animator == NULL) + { + engine->animator = ecore_animator_add(_on_effect_animator, engine); + } + + return true; +} + +bool ivug_effect_pause(Effect_Engine *engine) +{ +/* Unused. */ + return true; +} + +bool ivug_effect_resume(Effect_Engine *engine) +{ +/* Unused. */ + return true; +} + +bool ivug_effect_finalize(Effect_Engine *engine) +{ + ivug_retvm_if(engine == NULL, false, "engine is NULL"); + + if ( engine->animator ) + { + ecore_animator_del(engine->animator); + engine->animator = NULL; + } + + if (engine->eng_data) + { + if (engine->func.finalize) + { + MSG_EFFECT_HIGH("finalize"); + engine->func.finalize(engine->eng_data); + } + else + { + MSG_EFFECT_ERROR("engine->func.finalize is NULL"); + } + + engine->eng_data = NULL; + } + else + { + MSG_EFFECT_ERROR("engine->eng_data is NULL"); + } + + if ( engine->anim ) + { + delete_animation(engine->anim); + } + + free(engine); + engine = NULL; + + return true; +} + +Effect_Engine *ivug_effect_add(Effect_Type type) +{ + Effect_Engine *eng = NULL; + + switch (type) { + case EFFECT_DISSOLVE_FADE: + eng = ivug_fade_add(); + break; + + case EFFECT_SPLIT: + eng = ivug_blind_add(); + break; + + case EFFECT_IRIS: + eng = ivug_iris_add(); + break; + + case EFFECT_DISSOLVE: + eng = ivug_dissolve_add(); + break; + + case EFFECT_SLIDE: + eng = ivug_slide_add(); + break; + + default: + MSG_EFFECT_ERROR("Unknown effect type=%d", type); + /*Default effect, keeping with gallery setting*/ + eng = ivug_slide_add(); + break; + } + + if (eng == NULL) + { + MSG_EFFECT_ERROR("Cannot create effect enigne. type=%d", type); + return NULL; + } + + return eng; +} diff --git a/slideshow/src/effect/ivug-fade.c b/slideshow/src/effect/ivug-fade.c new file mode 100755 index 0000000..725dbf5 --- /dev/null +++ b/slideshow/src/effect/ivug-fade.c @@ -0,0 +1,160 @@ +/* + * Copyright 2012 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.tizenopensource.org/license + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "ivug-debug.h" +#include "ivug-effect.h" + +typedef struct _Fade_Data Fade_Data; + +struct _Fade_Data { + Evas_Object *src; + Evas_Object *dst; + + Evas_Object *object; + Evas_Object *orig_cliper; + + Evas_Object *cliper; + + Evas * evas; + + int screen_w; + int screen_h; +}; + +static void *__ivug_fade_init(Evas_Object *src, Evas_Object *dst) +{ + IVUG_FUNC_ENTER(); + + Fade_Data *eng_data = calloc(1, sizeof(Fade_Data)); + ivug_retvm_if(eng_data == NULL, NULL, "calloc return NULL"); + + eng_data->evas = evas_object_evas_get(src); + + eng_data->src = src; + eng_data->dst = dst; + +// Move object to 0,0 + evas_object_stack_below(dst, src); + + evas_object_move(dst, 0, 0); + evas_object_move(src, 0, 0); + + Evas_Object *orig_cliper = evas_object_clip_get(src); + eng_data->orig_cliper = orig_cliper; + + IVUG_FUNC_LEAVE(); + + return (Effect_Data)eng_data; +} + +static bool __ivug_fade_set_size(void *data, int screen_w, int screen_h, int rotation) +{ + IVUG_FUNC_ENTER(); + + ivug_retvm_if(data == NULL, false, "data is NULL"); + + Fade_Data *eng_data = (Fade_Data *) data; + + Evas_Coord x, y, w, h; + evas_object_geometry_get(eng_data->src, &x, &y, &w, &h); + + eng_data->screen_w = screen_w; + eng_data->screen_h = screen_h; + + if (eng_data->cliper) { + evas_object_clip_unset(eng_data->src); + evas_object_del(eng_data->cliper); + eng_data->cliper = NULL; + } + + Evas_Object *clip = evas_object_rectangle_add(eng_data->evas); + evas_object_color_set(clip, 255, 255, 255, 255); + evas_object_resize(clip, screen_w, screen_h); + evas_object_move(clip, x, y); + evas_object_show(clip); + + evas_object_clip_set(eng_data->src, clip); + eng_data->cliper = clip; + + evas_object_move(eng_data->dst, 0, 0); + + IVUG_FUNC_LEAVE(); + + return true; +} + +static void __ivug_fade_anim(void *data, double percent) +{ + Fade_Data *eng_data = (Fade_Data *) data; + + ivug_retm_if(eng_data == NULL, "data is NULL"); + ivug_retm_if(eng_data->cliper == NULL, "cliper is NULL"); + + int alpha = 255 * (MAX_PERCENT - percent) / MAX_PERCENT; + evas_object_color_set(eng_data->cliper, alpha, alpha, alpha, alpha); + + MSG_EFFECT_MED("alpha = %d", alpha); +} + +static void __ivug_fade_pause(void *data) +{ + MSG_EFFECT_HIGH("Fade paused"); +} + +static void __ivug_fade_resume(void *data) +{ + MSG_EFFECT_HIGH("Fade resumed"); +} + +static void __ivug_fade_finialize(void *data) +{ + MSG_EFFECT_HIGH("Fade destroy"); + + ivug_retm_if(data == NULL, "data is NULL"); + + Fade_Data *eng_data = (Fade_Data *) data; + + if (eng_data->cliper) { + evas_object_clip_unset(eng_data->src); + evas_object_del(eng_data->cliper); + eng_data->cliper = NULL; + } + + if (eng_data->src && eng_data->orig_cliper) + { + evas_object_clip_set(eng_data->src, eng_data->orig_cliper); + } + + free(eng_data); + eng_data = NULL; + +} + +Effect_Engine *ivug_fade_add(void) +{ + Effect_Engine *eng_fade = calloc(1, sizeof(Effect_Engine)); + ivug_retvm_if(eng_fade == NULL, NULL, "calloc failed"); + + eng_fade->func.init = &__ivug_fade_init; + eng_fade->func.set_size = &__ivug_fade_set_size; + eng_fade->func.animate = &__ivug_fade_anim; + eng_fade->func.pause = &__ivug_fade_pause; + eng_fade->func.resume = &__ivug_fade_resume; + eng_fade->func.finalize = &__ivug_fade_finialize; + + return eng_fade; +} + diff --git a/slideshow/src/effect/ivug-iris.c b/slideshow/src/effect/ivug-iris.c new file mode 100755 index 0000000..904305e --- /dev/null +++ b/slideshow/src/effect/ivug-iris.c @@ -0,0 +1,178 @@ +/* + * Copyright 2012 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.tizenopensource.org/license + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "ivug-debug.h" +#include "ivug-effect.h" + + +typedef struct _Iris_Data Iris_Data; + +struct _Iris_Data { + Evas_Object *src; + Evas_Object *dst; + + Evas_Object *orig_cliper; + + Evas_Object *cliper; + + Evas * evas; + + int screen_w; + int screen_h; +}; + +static Effect_Data __ivug_iris_init(Evas_Object *src, Evas_Object *dst) +{ + IVUG_FUNC_ENTER(); + + Iris_Data *eng_data = calloc(1, sizeof(Iris_Data)); + ivug_retvm_if(eng_data == NULL, NULL, "calloc return NULL"); + + eng_data->evas = evas_object_evas_get(src); + ivug_retvm_if(eng_data->evas == NULL, NULL, "Get evas is NULL"); + + eng_data->src = src; + eng_data->dst = dst; + + Evas_Object *orig_cliper = evas_object_clip_get(src); + eng_data->orig_cliper = orig_cliper; + + evas_object_stack_below(dst, src); + evas_object_move(dst, 0, 0); + + IVUG_FUNC_LEAVE(); + + return (Effect_Data)eng_data; +} + +static bool __ivug_iris_set_size(void *data, int screen_w, int screen_h, int rotation) +{ + IVUG_FUNC_ENTER(); + + ivug_retvm_if((screen_w <= 0 + || screen_h <= 0), false, + "screen_w or screen_h <= 0: [%d, %d]", screen_w, + screen_h); + + Iris_Data *eng_data = (Iris_Data *) data; + + Evas_Coord x, y, w, h; + evas_object_geometry_get(eng_data->src, &x, &y, &w, &h); + eng_data->screen_w = screen_w; + eng_data->screen_h = screen_h; + + if (eng_data->cliper) { + evas_object_del(eng_data->cliper); + eng_data->cliper = NULL; + } + + Evas_Object *clip = evas_object_rectangle_add(eng_data->evas); + evas_object_resize(clip, screen_w, screen_h); + evas_object_move(clip, x, y); + evas_object_show(clip); + evas_object_clip_set(eng_data->src, clip); + eng_data->cliper = clip; + + evas_object_move(eng_data->dst, 0, 0); + + IVUG_FUNC_LEAVE(); + + return true; + +} + +static void __ivug_iris_anim(void *data, double percent) +{ +/* IVUG_FUNC_ENTER(); */ + + Iris_Data *eng_data = (Iris_Data *) data; + + ivug_retm_if(eng_data == NULL, "data is NULL"); + ivug_retm_if(eng_data->cliper == NULL, "cliper is NULL"); + + int w = eng_data->screen_w; + int h = eng_data->screen_h; + int x, y; + + w = w * (MAX_PERCENT - percent) / MAX_PERCENT; + h = h * (MAX_PERCENT - percent) / MAX_PERCENT; + + x = (eng_data->screen_w - w) / 2; + y = (eng_data->screen_h - h) / 2; + + MSG_EFFECT_MED("percent=%f, [x, y, w, h] = [%d, %d, %d, %d]", percent, x, y, w, h); + + evas_object_resize(eng_data->cliper, w, h); + evas_object_move(eng_data->cliper, x, y); + +/* IVUG_FUNC_LEAVE(); */ +} + +static void __ivug_iris_pause(void *data) +{ + IVUG_FUNC_ENTER(); + + IVUG_FUNC_LEAVE(); +} + +static void __ivug_iris_resume(void *data) +{ + IVUG_FUNC_ENTER(); + + IVUG_FUNC_LEAVE(); +} + +static void __ivug_iris_finialize(void *data) +{ + IVUG_FUNC_ENTER(); + + ivug_retm_if(data == NULL, "data is NULL"); + + Iris_Data *eng_data = (Iris_Data *) data; + + if (eng_data->cliper) { + evas_object_del(eng_data->cliper); + eng_data->cliper = NULL; + } + + if (eng_data->src && eng_data->orig_cliper) { + evas_object_clip_set(eng_data->src, eng_data->orig_cliper); + } + + free(eng_data); + eng_data = NULL; + + IVUG_FUNC_LEAVE(); +} + +Effect_Engine *ivug_iris_add(void) +{ + IVUG_FUNC_ENTER(); + + Effect_Engine *eng_iris = calloc(1, sizeof(Effect_Engine)); + ivug_retvm_if(eng_iris == NULL, NULL, "calloc failed"); + + eng_iris->func.init = &__ivug_iris_init; + eng_iris->func.set_size = &__ivug_iris_set_size; + eng_iris->func.animate = &__ivug_iris_anim; + eng_iris->func.pause = &__ivug_iris_pause; + eng_iris->func.resume = &__ivug_iris_resume; + eng_iris->func.finalize = &__ivug_iris_finialize; + + IVUG_FUNC_LEAVE(); + + return eng_iris; +} diff --git a/slideshow/src/effect/ivug-slide.c b/slideshow/src/effect/ivug-slide.c new file mode 100755 index 0000000..d7958f8 --- /dev/null +++ b/slideshow/src/effect/ivug-slide.c @@ -0,0 +1,148 @@ +/* + * Copyright 2012 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.tizenopensource.org/license + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "ivug-debug.h" +#include "ivug-effect.h" +#include +#include +#include + + +typedef struct { + Evas_Object *src; + Evas_Object *dst; + + int screen_w; + int screen_h; +} Priv_Data; + +#define IMAGE_BETWEEN_MARGIN (30) + +static Effect_Data __ivug_slide_init(Evas_Object *src, Evas_Object *dst) +{ + Priv_Data *pData = calloc(1, sizeof(Priv_Data)); + IV_ASSERT(pData != NULL); + + pData->src = src; + pData->dst = dst; + + evas_object_stack_below(dst, src); + + evas_object_move(pData->src, 0, 0); + + return (Effect_Data)pData; +} + +static bool __ivug_slide_set_size(void *data, int screen_w, int screen_h, int rotation) +{ + Priv_Data *pData = (Priv_Data *)data; + IV_ASSERT(pData != NULL); + + pData->screen_w = screen_w; + pData->screen_h = screen_h; + + return true; +} + +static void _ivug_slide_get_screen_dimension(int *width, int *height) +{ + int rotation = elm_win_rotation_get((Evas_Object *)ug_get_window()); + + int screen_w = 0; + int screen_h = 0; + ecore_x_window_size_get(ecore_x_window_root_first_get(), &screen_w, &screen_h); + if(rotation == 0 || rotation == 180) + { + *width = screen_w; + *height = screen_h; + } + else if(rotation == 90 || rotation == 270) + { + *width = screen_h; + *height = screen_w; + } +} + +static void __ivug_slide_anim(Effect_Data data, double percent) +{ + Priv_Data *pData = (Priv_Data *)data; + + int first = 0; + int last = -pData->screen_w -IMAGE_BETWEEN_MARGIN; + //MSG_EFFECT_HIGH("pData->screen_w is %d", pData->screen_w); + //MSG_EFFECT_HIGH("last is %d", last); + int value = (double)first * (1.0f - percent / 100.0f) + (double)last * (percent / 100.0f); + + //MSG_EFFECT_HIGH("Slide animation. Value=%d %f", value, percent); + + Evas_Coord ow, oh; + /* + * during animation between 2 images, after rotation, 'w' gotten is 0 + * it's wrong, so let's use _ivug_slide_get_screen_dimension() to update + *pData->screen_w and pData->screen_h + */ + _ivug_slide_get_screen_dimension(&pData->screen_w, &pData->screen_h); + + ow = pData->screen_w; + oh = pData->screen_h; + //MSG_EFFECT_HIGH("in __ivug_slide_anim, pData->screen_w, pData->screen_h is %d, %d\n", ow, oh); + //MSG_EFFECT_HIGH("src des pos x is %d, %d\n", value ,oy); + //MSG_EFFECT_HIGH("dst des pos x is %d, %d\n", value + ow + IMAGE_BETWEEN_MARGIN ,oy); + evas_object_move(pData->src, value, 0); + evas_object_move(pData->dst, value + ow + IMAGE_BETWEEN_MARGIN, 0); + +} + +static void __ivug_slide_pause(Effect_Data data) +{ + +} + +static void __ivug_slide_resume(Effect_Data data) +{ + +} + +static void __ivug_slide_finialize(Effect_Data data) +{ + Priv_Data *pData = (Priv_Data *)data; + + free(pData); + +} + +static double __ivug_slide_get_duration(Effect_Data data) +{ + return 0.2f; +} + + + +Effect_Engine *ivug_slide_add(void) +{ + Effect_Engine *eng_slide = calloc(1, sizeof(Effect_Engine)); + ivug_retvm_if(eng_slide == NULL, NULL, "calloc failed"); + + eng_slide->func.init = __ivug_slide_init; + eng_slide->func.set_size = __ivug_slide_set_size; + eng_slide->func.animate = __ivug_slide_anim; + eng_slide->func.pause = __ivug_slide_pause; + eng_slide->func.resume = __ivug_slide_resume; + eng_slide->func.finalize = __ivug_slide_finialize; + eng_slide->func.get_duration = __ivug_slide_get_duration; + + return eng_slide; +} diff --git a/slideshow/src/effect/ivug-xcapture.c b/slideshow/src/effect/ivug-xcapture.c new file mode 100755 index 0000000..9de815d --- /dev/null +++ b/slideshow/src/effect/ivug-xcapture.c @@ -0,0 +1,339 @@ +/* + * Copyright 2012 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.tizenopensource.org/license + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "ivug-debug.h" + +#define MAX_ERROR_MSG_LEN 256 + +struct xcapture_t { + XImage *xim; + XShmSegmentInfo si; + int size; + Pixmap pix; +}; + +static int __ivug_xcapture_get_window_attribute(Window id, + int *depth, Visual **visual, + int *width, int *height) +{ + IV_ASSERT(id); + XWindowAttributes attr; + + if (!XGetWindowAttributes(ecore_x_display_get(), id, &attr)) { + MSG_EFFECT_ERROR("XGetWindowAttributes failed\n"); + return -1; + } + + if (attr.map_state == IsViewable && attr.class == InputOutput) { + *depth = attr.depth; + *width = attr.width; + *height = attr.height; + *visual = attr.visual; + } + + return 0; +} + +static struct xcapture_t *__ivug_xcapture(unsigned long id) +{ + IV_ASSERT(id); + + struct xcapture_t *handle = NULL; + int depth = 0; + int width = 0; + int height = 0; + Visual *visual = NULL; + char error_msg[MAX_ERROR_MSG_LEN] = { 0, }; + + handle = malloc(sizeof(struct xcapture_t)); + if (!handle) { + MSG_EFFECT_ERROR + ("Failed to allocate memory for __ivug_xcapture\n"); + return NULL; + } + + MSG_EFFECT_MED("Window : 0x%lX\n", id); + if (__ivug_xcapture_get_window_attribute + (id, &depth, &visual, &width, &height) < 0) { + MSG_EFFECT_ERROR("Failed to get the attributes from 0x%x\n", + (unsigned int)id); + free(handle); + return NULL; + } + + MSG_EFFECT_MED("WxH : %dx%d\n", width, height); + MSG_EFFECT_MED("Depth : %d\n", depth >> 3); + + /* NOTE: just add one more depth.... */ + handle->si.shmid = shmget(IPC_PRIVATE, + width * height * ((depth >> 3) + 1), + IPC_CREAT | 0666); + if (handle->si.shmid < 0) { + MSG_EFFECT_ERROR("Failed to get SHM %s\n", + strerror_r(errno, error_msg, + sizeof(error_msg))); + free(handle); + return NULL; + } + + handle->si.readOnly = False; + handle->si.shmaddr = shmat(handle->si.shmid, NULL, 0); + if (handle->si.shmaddr == (char *)-1) { + MSG_EFFECT_ERROR("Failed to attach shm %s\n", + strerror_r(errno, error_msg, + sizeof(error_msg))); + + shmctl(handle->si.shmid, IPC_RMID, 0); + free(handle); + return NULL; + } + + handle->xim = XShmCreateImage(ecore_x_display_get(), visual, depth, + ZPixmap, NULL, &handle->si, width, + height); + if (!handle->xim) { + MSG_EFFECT_ERROR("Failed create an image %s\n", + strerror_r(errno, error_msg, + sizeof(error_msg))); + + shmdt(handle->si.shmaddr); + shmctl(handle->si.shmid, IPC_RMID, 0); + free(handle); + return NULL; + } + + handle->size = handle->xim->bytes_per_line * handle->xim->height; + handle->xim->data = handle->si.shmaddr; + + handle->pix = XCompositeNameWindowPixmap(ecore_x_display_get(), id); + + if (XShmAttach(ecore_x_display_get(), &handle->si) == False) { + MSG_EFFECT_ERROR("Failed to attach\n"); + } + + if (XShmGetImage(ecore_x_display_get(), id, handle->xim, 0, 0, + 0xFFFFFFFF) == False) { + MSG_EFFECT_ERROR("Failed to get image\n"); + } + + XSync(ecore_x_display_get(), False); + return handle; +} + +static void __ivug_xcapture_destroy(struct xcapture_t *handle) +{ + ivug_retm_if(!handle, "handle is NULL"); + + XShmDetach(ecore_x_display_get(), &handle->si); + XFreePixmap(ecore_x_display_get(), handle->pix); + XDestroyImage(handle->xim); + + shmdt(handle->si.shmaddr); + shmctl(handle->si.shmid, IPC_RMID, 0); + + free(handle); +} + +static inline void *__ivug_xcapture_get_data(struct xcapture_t *handle, + int *size) +{ + ivug_retvm_if(!handle, NULL, "handle is NULL"); + + if (size) { + *size = handle->size; + } + + return handle->xim->data; +} + + +// TODO : Will rotate using pixman.. refer x11-server-utils-ex +static void __ivug_xcapture_data_rotate_180cw(unsigned int **dst, + unsigned int *src, int width, + int height) +{ + ivug_retm_if(!src, "src is NULL"); + + unsigned int *p1, *p2, tmp; + int x, hw; + + /* memcpy */ + *dst = malloc(width * height * sizeof(unsigned int)); + memcpy(*dst, src, width * height * sizeof(unsigned int)); + + /* set width, height */ + hw = width * height; + x = (hw / 2); + p1 = *dst; + p2 = *dst + hw - 1; + for (; --x > 0;) { + tmp = *p1; + *p1 = *p2; + *p2 = tmp; + p1++; + p2--; + } +} + +static void __ivug_xcapture_data_rotate_90cw(unsigned int **dst, + unsigned int *src, int width, + int height) +{ + ivug_retm_if(!src, "src is NULL"); + + unsigned int *to = NULL, *from = NULL; + int x, y, w, hw; + + /* memcpy */ + *dst = malloc(width * height * sizeof(unsigned int)); + memcpy(*dst, src, width * height * sizeof(unsigned int)); + + /* set width, height */ + w = height; + height = width; + width = w; + hw = width * height; + + to = *dst + w - 1; + hw = -hw - 1; + from = src; + + for (x = width; --x >= 0;) { + for (y = height; --y >= 0;) { + *to = *from; + from++; + to += w; + } + + to += hw; + } +} + +static void __ivug_xcapture_data_rotate_270cw(unsigned int **dst, + unsigned int *src, int width, + int height) +{ + ivug_retm_if(!src, "src is NULL"); + + unsigned int *to, *from; + int x, y, w, hw; + + /* memcpy */ + *dst = malloc(width * height * sizeof(unsigned int)); + memcpy(*dst, src, width * height * sizeof(unsigned int)); + + /* set width, height */ + w = height; + height = width; + width = w; + + hw = width * height; + + to = *dst + hw - w; + w = -w; + hw = hw + 1; + from = src; + + for (x = width; --x >= 0;) { + for (y = height; --y >= 0;) { + *to = *from; + from++; + to += w; + } + + to += hw; + } +} + +static char *__ivug_xcapture_data_get(Ecore_X_Window win, int *size, + int rotation) +{ + struct xcapture_t *handle = NULL; + + handle = __ivug_xcapture(win); + if (!handle) { + MSG_EFFECT_ERROR("__ivug_xcapture failed"); + return NULL; + } + + int data_size = 0; + char *image = __ivug_xcapture_get_data(handle, &data_size); + if (!image || data_size == 0) { + MSG_EFFECT_ERROR("__ivug_xcapture_get_data failed"); + + __ivug_xcapture_destroy(handle); + return NULL; + } + + MSG_EFFECT_MED("handle->xim: width = %d, height = %d\n", + handle->xim->width, handle->xim->height); + + /* Free the data when unused */ + int width = 0; + int height = 0; + char *data = NULL; + + width = handle->xim->bytes_per_line / sizeof(int); + height = handle->xim->height; + + if (rotation == 180) { + __ivug_xcapture_data_rotate_180cw((unsigned int **)&data, + (unsigned int *)image, width, + height); + } else if (rotation == 90) { + __ivug_xcapture_data_rotate_90cw((unsigned int **)&data, + (unsigned int *)image, width, + height); + } else if (rotation == 270) { + __ivug_xcapture_data_rotate_270cw((unsigned int **)&data, + (unsigned int *)image, width, + height); + } else { /* all other cases treated as angle 0 */ + + data = (char *)calloc(1, data_size); + memcpy(data, image, data_size); + } + + __ivug_xcapture_destroy(handle); + + if (size) { + *size = data_size; + } + + return data; +} + +char *ivug_xcapture_screen_data_get(int *size, int rotation) +{ + Ecore_X_Window root; + root = ecore_x_window_focus_get(); + + /* Free the memory allocated when unused */ + return __ivug_xcapture_data_get(root, size, rotation); +} diff --git a/slideshow/src/effect/ivug-xcapture.h b/slideshow/src/effect/ivug-xcapture.h new file mode 100755 index 0000000..30a3bc9 --- /dev/null +++ b/slideshow/src/effect/ivug-xcapture.h @@ -0,0 +1,30 @@ +/* + * Copyright 2012 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.tizenopensource.org/license + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __IVUG_XCAPTURE_H__ +#define __IVUG_XCAPTURE_H__ + +#ifdef __cplusplus +extern "C" { +#endif + + char *ivug_xcapture_screen_data_get(int *size, int rotation); + +#ifdef __cplusplus +} +#endif + +#endif /* __IVUG_XCAPTURE_H__ */ diff --git a/slideshow/src/effect/template.c b/slideshow/src/effect/template.c new file mode 100755 index 0000000..656d041 --- /dev/null +++ b/slideshow/src/effect/template.c @@ -0,0 +1,82 @@ +/* + * Copyright 2012 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.tizenopensource.org/license + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "ivug-common.h" +#include "ivug-effect.h" + + +typedef struct { + Evas_Object *src; + Evas_Object *dst; + + Evas_Object *object; + Evas_Object *orig_cliper; + + Evas_Object *cliper; + + int screen_w; + int screen_h; +} effect_data; + + +static Effect_Data __ivug_init(Evas_Object *src, Evas_Object *dst, int screen_w, int screen_h, int rotation) +{ + IVUG_FUNC_ENTER(); + + IVUG_FUNC_LEAVE(); +} + +static void __ivug_anim(Effect_Data data, double percent) +{ +/* IVUG_FUNC_ENTER(); */ + +/* IVUG_FUNC_LEAVE(); */ +} + +static void __ivug_pause(Effect_Data data) +{ + IVUG_FUNC_ENTER(); + + IVUG_FUNC_LEAVE(); +} + +static void __ivug_resume(Effect_Data data) +{ + IVUG_FUNC_ENTER(); + + IVUG_FUNC_LEAVE(); +} + +static void __ivug_spin_finialize(Effect_Data data) +{ + IVUG_FUNC_ENTER(); + + IVUG_FUNC_LEAVE(); +} + +Effect_Engine *ivug_xxx_add(void) +{ + Effect_Engine *eng_spin = calloc(1, sizeof(Effect_Engine)); + ivug_retvm_if(eng_spin == NULL, NULL, "calloc failed"); + + eng_spin->func.init = &__ivug_init; + eng_spin->func.animate = &__ivug_anim; + eng_spin->func.pause = &__ivug_pause; + eng_spin->func.resume = &__ivug_resume; + eng_spin->func.finalize = &__ivug_finialize; + + return eng_spin; +} diff --git a/slideshow/src/ivug-slideshow.cpp b/slideshow/src/ivug-slideshow.cpp new file mode 100755 index 0000000..2b14f35 --- /dev/null +++ b/slideshow/src/ivug-slideshow.cpp @@ -0,0 +1,1002 @@ +/* + * Copyright 2012 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.tizenopensource.org/license + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include "ivug-anim.h" +#include "ivug-slideshow.h" +#include "ivug-debug.h" + +#include "ivug-config.h" +#include "ivug-define.h" +#include "ivug-datatypes.h" +#include "ivug-uuid.h" +#include "ivug-util.h" + +#include "ivug-image.h" + +#include +#include + +#include "statistics.h" + +#include "EFLUtil.h" + +#undef USE_IVUG_IMAGE + +#undef LOG_LVL +#define LOG_LVL DBG_MSG_LVL_MED + +#undef LOG_CAT +#define LOG_CAT "IV-SLIDESHOW" + +/* + Basic functionality is implemented. + but codes have many bugs. plz check this. + + TODO: + Resize is not handled. + Mouse routine is not handled. + Decoding faied is not processed. + + Not test except slide effect. + +*/ +#define EDJ_PATH PREFIX"/res/edje/"PACKAGE +#define IVUG_SS_LY_EDJ_PATH EDJ_PATH"/ivug-ss-ly.edj" + +#define IVUG_IMAGE_BETWEEN_MARGIN (30) +#define IVUG_IMAGE_MOVE_MARGIN ((int)IVUG_IMAGE_BETWEEN_MARGIN*0.8) +#define IVUG_IMAGE_SCROLL_MARGIN (5) + +#define _EDJ(o) elm_layout_edje_get(o) + +void ivug_ss_get_screen_size(int *width, int *height) +{ + int rotation = elm_win_rotation_get((Evas_Object *)ug_get_window()); + + int screen_w = 0; + int screen_h = 0; + ecore_x_window_size_get(ecore_x_window_root_first_get(), &screen_w, &screen_h); + if(rotation == 0 || rotation == 180) + { + *width = screen_w; + *height = screen_h; + } + else if(rotation == 90 || rotation == 270) + { + *width = screen_h; + *height = screen_w; + } +} + +Media_Item *ivug_ss_get_next_item(Media_List *mList, + Media_Item *header, + Media_Item *current, + slide_show_mode mode) +{ + Media_Item *item = NULL; + + MSG_HIGH("Get Next Item : Header=0x%08x Current=0x%08x", header, current); + + MSG_HIGH("Get Next : Header=0x%08x Current=0x%08x", + header, current); + switch(mode) + { + case SLIDE_SHOW_MODE_REPEAT: + item = ivug_medialist_get_next(mList, current); + if ( item == NULL ) + { + item = ivug_medialist_get_first(mList); + } + break; + + case SLIDE_SHOW_MODE_NORMAL: + item = ivug_medialist_get_next(mList, current); + break; + + case SLIDE_SHOW_MODE_SHUFFLE_REPEAT: + item = ivug_medialist_get_shuffle_item(mList, current); + if ( item == NULL ) + { + MSG_ERROR("Never touch here"); + } + break; + + case SLIDE_SHOW_MODE_SHUFFLE: + item = ivug_medialist_get_shuffle_item(mList, current); + if ( item == header ) + { + MSG_ERROR("Reach end"); + return NULL; + } + break; + + default: + MSG_ERROR("Unknown mode : %d", mode); + item = NULL; + break; + } + + return item; + +} + + +static void +_moved(void *data, Evas *evas, Evas_Object *obj, void *event_info) +{ + SlideShow *pSlideShow = (SlideShow *)data; + + Evas_Coord ox, oy, ow, oh; + evas_object_geometry_get(obj, &ox, &oy, &ow, &oh); + + MSG_HIGH("Moved (%d,%d,%d,%d)", ox, oy, ow, oh); + + evas_object_move(pSlideShow->event, ox, oy); +} + +static void +_resized(void *data, Evas *evas, Evas_Object *obj, void *event_info) +{ + SlideShow *pSlideShow = (SlideShow *)data; + + Evas_Coord ox, oy, ow, oh; + evas_object_geometry_get(obj, &ox, &oy, &ow, &oh); + + MSG_HIGH("Resized (%d,%d,%d,%d)", ox, oy, ow, oh); + + evas_object_resize(pSlideShow->event, ow, oh); + + evas_object_resize(pSlideShow->sLayout[pSlideShow->sCurrent].layout, ow, oh); + evas_object_resize(pSlideShow->sLayout[(pSlideShow->sCurrent + 1) % 2].layout, ow, oh); +} + +static void +_shown(void *data, Evas *evas, Evas_Object *obj, void *event_info) +{ + MSG_HIGH("SlideShow is Shown"); +} + +static void +_hidden(void *data, Evas *evas, Evas_Object *obj, void *event_info) +{ + MSG_HIGH("SlideShow is Hidden"); +} + + +static void +_shown1(void *data, Evas *evas, Evas_Object *obj, void *event_info) +{ + MSG_HIGH("%s is Shown", evas_object_name_get(obj)); +} + +static void +_hidden1(void *data, Evas *evas, Evas_Object *obj, void *event_info) +{ + MSG_HIGH("%s is Hidden", evas_object_name_get(obj)); +} + +static bool _ivug_ss_set_content(Slide_Layout *pSlide, Media_Item *item) +{ + Media_Data *mdata; + int ret = EVAS_LOAD_ERROR_NONE; + + pSlide->mitem = item; + + if(pSlide->mitem == NULL) + { + MSG_ERROR("Mitem is NULL"); + return false; + } + + mdata = ivug_medialist_get_data(item); + IV_ASSERT(mdata != NULL); + + MSG_HIGH("Start Loading : %s", mdata->filepath); + + if(mdata->slide_type == SLIDE_TYPE_VIDEO || mdata->slide_type == SLIDE_TYPE_STREAMING) + { + /* Display play icon */ + edje_object_signal_emit(elm_layout_edje_get(pSlide->layout), + "elm,state,show_play_icon", + "slideshow"); + + +#ifdef USE_IVUG_IMAGE + ret = ivug_image_file_set(pSlide->photocam, mdata->thumbnail_path, NULL); +#else + ret = elm_photocam_file_set(pSlide->photocam, mdata->thumbnail_path); +#endif + if(EVAS_LOAD_ERROR_NONE != ret) { + MSG_HIGH("elm_photocam_file_set failed"); + return false; + } + } + else + { + /* Hide play icon */ + edje_object_signal_emit(elm_layout_edje_get(pSlide->layout), + "elm,state,hide_play_icon", + "slideshow"); +#ifdef USE_IVUG_IMAGE + ret = ivug_image_file_set(pSlide->photocam, mdata->filepath, NULL); +#else + ret = elm_photocam_file_set(pSlide->photocam, mdata->filepath); +#endif + if(EVAS_LOAD_ERROR_NONE != ret) { + MSG_HIGH("elm_photocam_file_set failed"); + return false; + } + + if (elm_icon_file_set(pSlide->thumbnail, mdata->thumbnail_path, NULL) == EINA_FALSE) + { + MSG_ERROR("Cannot load thumbnail : %s", mdata->thumbnail_path); + } + else + { + edje_object_signal_emit(_EDJ(pSlide->layout), "elm,state,show_thumbnail", "slideshow"); + } + } + MSG_HIGH("Load : %s", mdata->filepath); + elm_photocam_zoom_mode_set(pSlide->photocam, ELM_PHOTOCAM_ZOOM_MODE_AUTO_FIT); + elm_photocam_paused_set(pSlide->photocam, true); + evas_object_size_hint_weight_set(pSlide->photocam, EVAS_HINT_EXPAND, + EVAS_HINT_EXPAND); + + return true; +} + + +static void _ivug_ss_update_pos(SlideShow *pSlideShow, Evas_Coord x, Evas_Coord y) +{ + IV_ASSERT(pSlideShow != NULL); + + MSG_HIGH("Update Pos(%d,%d) sCurrent=%d", x, y, pSlideShow->sCurrent); + +// x = x - 360; + + Slide_Layout *sLyCurrent = &pSlideShow->sLayout[pSlideShow->sCurrent]; + Slide_Layout *sLyNext = &pSlideShow->sLayout[(pSlideShow->sCurrent + 1) % 2]; + + evas_object_move(sLyCurrent->layout, x, y); + evas_object_move(sLyNext->layout, + x + pSlideShow->screen_w + IVUG_IMAGE_BETWEEN_MARGIN , + y); +} +static bool _ivug_ss_load_next_image(SlideShow *pSlideShow) +{ + ivug_retv_if(!pSlideShow, false); + MSG_HIGH(""); + + Slide_Layout* sLyCurrent = &pSlideShow->sLayout[pSlideShow->sCurrent]; + Slide_Layout* sLy = &pSlideShow->sLayout[(pSlideShow->sCurrent + 1) % 2]; + + Media_Item *next = NULL; + Media_Item *current = sLyCurrent->mitem; + do { + next = ivug_ss_get_next_item(pSlideShow->media_list, + pSlideShow->ss_Header, + current, + pSlideShow->ss_mode); + + if(next == NULL) { + sLy->mitem = NULL; + return false; + } + current = next; + }while(!_ivug_ss_set_content(sLy, next)); + + if(next) { + evas_object_show(sLy->layout); + } + + return true; +} + +void _ivug_ss_effect_finished(void *data) +{ + ivug_ret_if(!data); + SlideShow *pSlideShow = (SlideShow *) data; + MSG_HIGH("slideshow Effect ended"); + + if(pSlideShow->effect_engine) + { + MSG_HIGH("ivug_effect_finalize"); + ivug_effect_finalize(pSlideShow->effect_engine); + pSlideShow->effect_engine = NULL; + } + + /* Increse current index */ + pSlideShow->sCurrent = (pSlideShow->sCurrent + 1) % 2; + _ivug_ss_update_pos(pSlideShow, 0, 0); // Reset position + + Slide_Layout *sLyCurrent = &pSlideShow->sLayout[pSlideShow->sCurrent]; + Slide_Layout *sLyNext = &pSlideShow->sLayout[(pSlideShow->sCurrent + 1) % 2]; + + Media_Item *next = NULL; + + next = ivug_ss_get_next_item(pSlideShow->media_list, + pSlideShow->ss_Header, + sLyCurrent->mitem, + pSlideShow->ss_mode); + + if(next == NULL) { + sLyNext->mitem = NULL; + MSG_ERROR("Cannot find next item"); + return; + } + + _ivug_ss_set_content(sLyNext, next); + +// Reset visibilaty because effect can hide layout + evas_object_show(sLyCurrent->layout); + evas_object_show(sLyNext->layout); + + MSG_HIGH("pSlideShow->bSS_StopFlag = %d", pSlideShow->bSS_StopFlag); + + if(pSlideShow->bSS_StopFlag == EINA_TRUE) + { + pSlideShow->state = SLIDE_SHOW_STOPPED; + pSlideShow->ss_Header = NULL; + evas_object_smart_callback_call(ivug_ss_object_get(pSlideShow), "slideshow,finished", (void *)SLIDE_SHOW_STOPPED); +// ivug_ss_delete(pSlideShow); + + pSlideShow->bSS_StopFlag = EINA_FALSE; + } + //EFL::dump_obj(pSlideShow->obj, 0); +} + +Evas_Object *_ivug_ss_create_layout(Evas_Object *parent, const char *edj_path, const char *group) +{ + MSG_ASSERT(parent != NULL); + MSG_ASSERT(edj_path != NULL); + MSG_ASSERT(group != NULL); + + Evas_Object *ly = NULL; + ly = elm_layout_add(parent); + + ivug_retv_if(!ly, NULL); + + if (elm_layout_file_set(ly , edj_path, group ) == EINA_FALSE) + { + MSG_ERROR("Cannot create layout. %s %s", edj_path, group); + evas_object_del(ly); + return NULL; + } + evas_object_size_hint_weight_set(ly, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + evas_object_size_hint_align_set(ly, EVAS_HINT_FILL, EVAS_HINT_FILL); + + evas_object_show(ly); + return ly; +} + +// Slide Show related functions. +static Eina_Bool _ivug_ss_on_slide_interval(void *data) +{ + MSG_ASSERT(data != NULL); + + SlideShow *pSlideShow = (SlideShow*)data; + + MSG_HIGH("On Slide Interval"); + /* stopped by other operation */ + if (pSlideShow->state == SLIDE_SHOW_STOPPED) + { + pSlideShow->ss_timer = NULL; + MSG_ERROR("Slide show already stopped"); + return ECORE_CALLBACK_CANCEL; + } + + Slide_Layout *sLyCurrent = &pSlideShow->sLayout[pSlideShow->sCurrent]; + Slide_Layout *sLyNext = &pSlideShow->sLayout[(pSlideShow->sCurrent + 1) % 2]; + + /* Next item is NULL */ + if(sLyNext->mitem == NULL) + { + MSG_HIGH("Next item is NULL"); + pSlideShow->ss_timer = NULL; + pSlideShow->ss_Header = NULL; + /* exit slide show after whole animation is over */ + ivug_ss_stop(pSlideShow); + + return ECORE_CALLBACK_CANCEL; + } + + /* Slideshow Effect */ + Effect_Engine *eng = ivug_effect_add(pSlideShow->effect_type); + MSG_ASSERT(eng != NULL); + + pSlideShow->effect_engine = eng; + + ivug_effect_init(pSlideShow->effect_engine, sLyCurrent->layout, sLyNext->layout); + + int rotation = elm_win_rotation_get((Evas_Object *)ug_get_window()); + ivug_ss_get_screen_size(&pSlideShow->screen_w, &pSlideShow->screen_h); + + if(ivug_effect_set_size(pSlideShow->effect_engine, pSlideShow->screen_w, pSlideShow->screen_h, rotation) == false) + { + pSlideShow->ss_timer = NULL; + ivug_effect_finalize(pSlideShow->effect_engine); + return ECORE_CALLBACK_CANCEL; + } + +// EFL::dump_obj(pSlideShow->obj, 0); + + ivug_effect_start(pSlideShow->effect_engine, _ivug_ss_effect_finished, pSlideShow); + + return ECORE_CALLBACK_RENEW; +} + + + +static Effect_Type _ivug_ss_get_trans_effect(ivug_effect_type type) +{ + MSG_MED("type %d", type); + switch(type) + { + case IVUG_EFFECT_TYPE_SLIDE: + return EFFECT_SLIDE; + case IVUG_EFFECT_TYPE_IRIS: + return EFFECT_IRIS; + case IVUG_EFFECT_TYPE_DISSOLVE: + return EFFECT_DISSOLVE; + case IVUG_EFFECT_TYPE_DISSOLVE_FADE: + return EFFECT_DISSOLVE_FADE; + case IVUG_EFFECT_TYPE_SPLIT: + return EFFECT_SPLIT; + default: + break; + } + return EFFECT_NONE; +} + + + + +void _ivug_ss_on_mouse_down(void *data, Evas *e, + Evas_Object *obj, void *event_info) +{ + SlideShow *pSlideShow = (SlideShow *) data; + + MSG_HIGH("_ivug_ss_on_mouse_down, state is %d", pSlideShow->state); + + if (pSlideShow->click_timer) { + ecore_timer_del(pSlideShow->click_timer); + pSlideShow->click_timer = NULL; + } + + if(pSlideShow->ss_timer) { + ecore_timer_del(pSlideShow->ss_timer); + pSlideShow->ss_timer = NULL; + } +} + +void _ivug_ss_on_mouse_move(void *data, Evas *e, + Evas_Object *obj, void *event_info) +{ + MSG_LOW("_ivug_ss_on_mouse_move"); + return; +} + +static Eina_Bool _ivug_ss_clicked_timer_cb(void *data) +{ + SlideShow *pSlideShow = (SlideShow *)data; + if (NULL == pSlideShow) { + return ECORE_CALLBACK_CANCEL; + } + + if(pSlideShow->click_timer) + { + ecore_timer_del(pSlideShow->click_timer); + pSlideShow->click_timer = NULL; + } + + if(pSlideShow->state == SLIDE_SHOW_RUNNING) { + ivug_ss_stop(pSlideShow); + //EFL::dump_obj(pSlideShow->obj, 0); + return ECORE_CALLBACK_CANCEL; + } + + MSG_HIGH("-------------_ivug_ss_clicked_timer_cb--------------"); + + pSlideShow->state = SLIDE_SHOW_INTERRUPTED; + evas_object_smart_callback_call(ivug_ss_object_get(pSlideShow), "slideshow,finished", (void *)SLIDE_SHOW_INTERRUPTED); + + return ECORE_CALLBACK_CANCEL; +} +void _ivug_ss_on_mouse_up(void *data, Evas *e, + Evas_Object *obj, void *event_info) +{ + SlideShow *pSlideShow = (SlideShow *)data; + if (NULL == pSlideShow) { + return; + } + MSG_HIGH("_ivug_ss_on_mouse_up, pSlideShow->v is %d", pSlideShow->state); + + if(pSlideShow->click_timer) + { + ecore_timer_del(pSlideShow->click_timer); + pSlideShow->click_timer = NULL; + } + pSlideShow->click_timer = ecore_timer_add(0.3f, _ivug_ss_clicked_timer_cb, data); + +} + +static Eina_Bool +_ivug_ss_auto_finish_timer_cb(void *data) +{ + ivug_retv_if(!data, ECORE_CALLBACK_CANCEL); + + SlideShow *pSlideShow = (SlideShow*)data; + /* exit slide show after whole animation is over */ + ivug_ss_stop(pSlideShow); + return ECORE_CALLBACK_CANCEL; +} + + +static void +_ivug_ss_photocam_loaded_cb(void *data, Evas_Object *obj, void *event_info) +{ + IV_ASSERT(data != NULL); + + Slide_Layout* sLy = static_cast(data); + SlideShow *pSlideShow = (SlideShow *)sLy->pSlideshow; + + if ( sLy->mitem == NULL) + { + MSG_ERROR("Debug Me! Data item is NULL."); + return; + } + + Media_Data* mdata = ivug_medialist_get_data(sLy->mitem); + if(mdata == NULL) + { + MSG_ERROR("ivug_medialist_get_data failed."); + return; + } + + Evas_Load_Error error = static_cast(reinterpret_cast(event_info)); + if ( error != EVAS_LOAD_ERROR_NONE ) + { + MSG_ERROR("Image loading failed. Error=%d File=%s", error, mdata->filepath); + + Slide_Layout *sLyCurrent = &pSlideShow->sLayout[pSlideShow->sCurrent]; + Slide_Layout *sLyNext = &pSlideShow->sLayout[(pSlideShow->sCurrent + 1) % 2]; + + Media_Item *next = NULL; + + next = ivug_ss_get_next_item(pSlideShow->media_list, + pSlideShow->ss_Header, + sLyCurrent->mitem, + pSlideShow->ss_mode); + + _ivug_ss_set_content(sLyNext, next); + return; + + MSG_HIGH("Photocam Pre-loaded. File=%s", ivug_get_filename(mdata->filepath)); + MSG_SITEM_ERROR("Image loading failed. Error=%d File=%s", + error, mdata->filepath); + _ivug_ss_load_next_image((SlideShow *)sLy->pSlideshow); + return; + } + edje_object_signal_emit(_EDJ(pSlideShow->sLayout[pSlideShow->sCurrent].layout), "elm,state,hide_thumbnail", "slideshow"); + + MSG_SITEM_HIGH("Photocam Pre-loaded. File=%s", + ivug_get_filename(mdata->filepath)); + + return; +} + +static bool _ivug_ss_create_image_layout(Evas_Object *parent, Slide_Layout *sLayout) +{ + /* Create Layout for the current item */ + sLayout->layout = _ivug_ss_create_layout(parent, IVUG_SS_LY_EDJ_PATH, "slayout"); + + if(sLayout->layout == NULL) { + MSG_ERROR("Cannot create current layout"); + return false; + } +#ifdef USE_IVUG_IMAGE + sLayout->photocam = ivug_image_create(sLayout->layout); +#else + sLayout->photocam = elm_photocam_add(sLayout->layout); +#endif + evas_object_size_hint_expand_set(sLayout->photocam, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + evas_object_size_hint_align_set(sLayout->photocam, EVAS_HINT_FILL, EVAS_HINT_FILL); + + elm_object_part_content_set(sLayout->layout, "content", sLayout->photocam); + + sLayout->thumbnail = elm_icon_add(sLayout->layout); + evas_object_name_set(sLayout->thumbnail, "Thumbnail"); + elm_object_part_content_set(sLayout->layout, "thumbnail", sLayout->thumbnail); + +#ifdef USE_IVUG_IMAGE +#else + elm_photocam_zoom_mode_set(sLayout->photocam, ELM_PHOTOCAM_ZOOM_MODE_AUTO_FIT); + elm_photocam_paused_set(sLayout->photocam, EINA_TRUE); +#endif + + evas_object_smart_callback_add(sLayout->photocam, + "loaded", + _ivug_ss_photocam_loaded_cb, + sLayout); + + evas_object_smart_member_add(sLayout->photocam, sLayout->layout); + evas_object_smart_member_add(sLayout->thumbnail, sLayout->layout); + + evas_object_show(sLayout->photocam); + evas_object_show(sLayout->layout); + + return true; +} + +SlideShow *ivug_ss_create(Evas_Object *parent) +{ + SlideShow *pSlideShow = NULL; + MSG_IVUG_HIGH("ivug_ss_create"); + pSlideShow = (SlideShow*)calloc(1,sizeof(SlideShow)); + if (pSlideShow == NULL) { + return NULL; + } + pSlideShow->state = SLIDE_SHOW_STOPPED; + + pSlideShow->obj = _ivug_ss_create_layout(parent, IVUG_SS_LY_EDJ_PATH, "view.slideshow"); + MSG_ASSERT(pSlideShow->obj != NULL); + + evas_object_name_set(pSlideShow->obj, "slideshow"); + pSlideShow->obj = _ivug_ss_create_layout(parent, IVUG_SS_LY_EDJ_PATH, + "view.slideshow"); + evas_object_name_set(pSlideShow->obj, "slideshow"); + + + /* Create Layout for the current item */ + if ( _ivug_ss_create_image_layout(pSlideShow->obj, &pSlideShow->sLayout[0]) == false) + { + MSG_ERROR("Cannot create current layout"); + free(pSlideShow); + return NULL; + } + pSlideShow->sLayout[0].pSlideshow = pSlideShow; + evas_object_name_set(pSlideShow->sLayout[0].layout, "Layout 0"); + + /* Create Layout for the next item */ + if ( _ivug_ss_create_image_layout(pSlideShow->obj, &pSlideShow->sLayout[1]) == false) + { + MSG_ERROR("Cannot create current layout"); + elm_object_part_content_unset(pSlideShow->sLayout[0].layout, "content"); + evas_object_del(pSlideShow->sLayout[0].photocam); + evas_object_del(pSlideShow->sLayout[0].layout); + free(pSlideShow); + return NULL; + } + + pSlideShow->sLayout[1].pSlideshow = pSlideShow; + evas_object_name_set(pSlideShow->sLayout[1].layout, "Layout 1"); + + evas_object_event_callback_add(pSlideShow->sLayout[0].layout, EVAS_CALLBACK_SHOW, _shown1, NULL); + evas_object_event_callback_add(pSlideShow->sLayout[0].layout, EVAS_CALLBACK_HIDE, _hidden1, NULL); + + evas_object_event_callback_add(pSlideShow->sLayout[1].layout, EVAS_CALLBACK_SHOW, _shown1, NULL); + evas_object_event_callback_add(pSlideShow->sLayout[1].layout, EVAS_CALLBACK_HIDE, _hidden1, NULL); + + /* Event rect */ + pSlideShow->event = evas_object_rectangle_add(evas_object_evas_get(parent)); + evas_object_name_set(pSlideShow->event, "ss_event"); + evas_object_color_set(pSlideShow->event, 0,0,0,0); + + evas_object_show(pSlideShow->event); + + //EFL::dump_obj(pSlideShow->obj, 0); + + evas_object_event_callback_add(pSlideShow->obj, EVAS_CALLBACK_MOVE, _moved, pSlideShow); + evas_object_event_callback_add(pSlideShow->obj, EVAS_CALLBACK_RESIZE, _resized, pSlideShow); + evas_object_event_callback_add(pSlideShow->obj, EVAS_CALLBACK_SHOW, _shown, pSlideShow); + evas_object_event_callback_add(pSlideShow->obj, EVAS_CALLBACK_HIDE, _hidden, pSlideShow); + +// Event + evas_object_event_callback_add(pSlideShow->event, EVAS_CALLBACK_MOUSE_DOWN, _ivug_ss_on_mouse_down, pSlideShow); + evas_object_event_callback_add(pSlideShow->event, EVAS_CALLBACK_MOUSE_MOVE, _ivug_ss_on_mouse_move, pSlideShow); + evas_object_event_callback_add(pSlideShow->event, EVAS_CALLBACK_MOUSE_UP, _ivug_ss_on_mouse_up, pSlideShow); + + return pSlideShow; +} + + +bool ivug_ss_start(SlideShow *pSlideShow , Media_Item *current, Media_List *list, Eina_Bool bSlideFirst) +{ + MSG_ASSERT(pSlideShow != NULL); + + ivug_effect_type ivug_effect = IVUG_EFFECT_TYPE_SLIDE; + + ivug_config_get_slideshow_setting(&(pSlideShow->ss_mode), &(pSlideShow->ss_interval_time), &ivug_effect); + + ivug_config_get_slideshow_setting(&(pSlideShow->ss_mode), + &(pSlideShow->ss_interval_time), &ivug_effect); + MSG_HIGH("Start slide show. Interval=%f Effect=%d ", + pSlideShow->ss_interval_time, ivug_effect); + + ivug_ss_get_screen_size(&pSlideShow->screen_w, &pSlideShow->screen_h); + + MSG_HIGH("Start slide show. Interval=%f Effect=%d Screen(%d,%d)", pSlideShow->ss_interval_time, ivug_effect, pSlideShow->screen_w, pSlideShow->screen_h); + + if(pSlideShow->ss_interval_time < 0) + { + MSG_ERROR("slide show interval time is invalid !!!"); + return false; + } + + if (pSlideShow->state == SLIDE_SHOW_RUNNING ) + { + MSG_ERROR("Debug me!!! Slide show is running. remove previous one."); + ivug_ss_stop(pSlideShow); + } + + if (pSlideShow->effect_engine != NULL ) + { + MSG_FATAL("Debug Me!!!"); + return false; + } + + pSlideShow->sCurrent = 0; + pSlideShow->bSS_StopFlag = EINA_FALSE; + pSlideShow->ss_Header = current; + pSlideShow->effect_type = _ivug_ss_get_trans_effect(ivug_effect); + pSlideShow->media_list = list; + + MSG_ASSERT(pSlideShow->obj != NULL); + evas_object_move(pSlideShow->obj, 0,0); + evas_object_resize(pSlideShow->obj, pSlideShow->screen_w, pSlideShow->screen_h); + + _ivug_ss_update_pos(pSlideShow, 0, 0); + + Slide_Layout *sLyCurrent = &pSlideShow->sLayout[pSlideShow->sCurrent]; + Slide_Layout *sLyNext = &pSlideShow->sLayout[(pSlideShow->sCurrent + 1) % 2]; + + _ivug_ss_set_content(sLyCurrent, current); + + Media_Item *next = NULL; + + next = ivug_ss_get_next_item(pSlideShow->media_list, + pSlideShow->ss_Header, + sLyCurrent->mitem, + pSlideShow->ss_mode); + + if(next == NULL) + { + /* if last image is tapped, then after some time, back to main view directly */ + pSlideShow->ss_timer = NULL; + pSlideShow->ss_Header = NULL; + pSlideShow->state = SLIDE_SHOW_RUNNING; + + pSlideShow->ss_timer = ecore_timer_add(pSlideShow->ss_interval_time, _ivug_ss_auto_finish_timer_cb, pSlideShow); + return false; + } + + _ivug_ss_set_content(sLyNext, next); + + pSlideShow->state = SLIDE_SHOW_RUNNING; + +#if 0 + if(_ivug_ss_on_slide_interval(pSlideShow) == false) + { + pSlideShow->ss_timer = NULL; + pSlideShow->ss_Header = NULL; + + /* exit slide show after whole animation is over */ + ivug_ss_stop(pSlideShow); + return false; + } +#endif +// EFL::dump_obj(pSlideShow->obj, 0); + + pSlideShow->ss_timer = ecore_timer_add(pSlideShow->ss_interval_time, _ivug_ss_on_slide_interval, pSlideShow); + + MSG_HIGH("Slide show started!"); + + return true; +} + + +bool ivug_ss_stop(SlideShow *pSlideShow) +{ + MSG_ASSERT(pSlideShow != NULL); + + MSG_HIGH("Slide show stopping"); + + if (pSlideShow->state != SLIDE_SHOW_RUNNING) + { + MSG_HIGH("pSlideShow->state != SLIDE_SHOW_RUNNING"); + return true; + } + + pSlideShow->bSS_StopFlag = EINA_TRUE; + + //delete timmer + if(pSlideShow->ss_timer) { + ecore_timer_del(pSlideShow->ss_timer); + pSlideShow->ss_timer = NULL; + } + + if(pSlideShow->click_timer) { + ecore_timer_del(pSlideShow->click_timer); + pSlideShow->click_timer = NULL; + } + if(pSlideShow->event) { + evas_object_del(pSlideShow->event); + pSlideShow->event = NULL; + } + if(pSlideShow->effect_engine == NULL) + { + MSG_HIGH("Slide effect_engine = NULL"); + pSlideShow->state = SLIDE_SHOW_STOPPED; + pSlideShow->ss_Header = NULL; + // TODO : Mis-implementation + evas_object_smart_callback_call(ivug_ss_object_get(pSlideShow), "slideshow,finished", (void *)SLIDE_SHOW_STOPPED); + pSlideShow->bSS_StopFlag = EINA_FALSE; + } + //MSG_HIGH("Stop slide show. but not run state"); + + return true; +} + +bool ivug_ss_resume(SlideShow *pSlideShow) +{ + MSG_HIGH("Slide show Resume"); + MSG_ASSERT(pSlideShow != NULL); + + if(pSlideShow->ss_timer) + { + ecore_timer_thaw(pSlideShow->ss_timer); + } + + pSlideShow->state = SLIDE_SHOW_RUNNING; + //MSG_HIGH("ivug_resume_slideshow"); + + return true; +} + +bool ivug_ss_pause(SlideShow *pSlideShow) +{ + MSG_HIGH("Slide show Pause"); + + MSG_ASSERT(pSlideShow != NULL); + + if(pSlideShow->ss_timer) + { + ecore_timer_freeze(pSlideShow->ss_timer); + } + + pSlideShow->state = SLIDE_SHOW_PAUSE; + + return true; +} + +Media_Item * ivug_ss_item_get(SlideShow *pSlideShow) +{ + MSG_ASSERT(pSlideShow != NULL); + + return pSlideShow->sLayout[(pSlideShow->sCurrent) % 2].mitem; +} + +void ivug_ss_delete(SlideShow *pSlideShow) +{ + MSG_HIGH("Slide show Delete"); + + if(!pSlideShow) + { + MSG_ERROR("Already deleted!!"); + return; + } + + evas_object_event_callback_del(pSlideShow->event, EVAS_CALLBACK_MOUSE_DOWN, _ivug_ss_on_mouse_down); + evas_object_event_callback_del(pSlideShow->event, EVAS_CALLBACK_MOUSE_MOVE, _ivug_ss_on_mouse_move); + evas_object_event_callback_del(pSlideShow->event, EVAS_CALLBACK_MOUSE_UP, _ivug_ss_on_mouse_up); + + if(pSlideShow->effect_engine) + ivug_effect_finalize(pSlideShow->effect_engine); + + if(pSlideShow->ss_timer) { + ecore_timer_del(pSlideShow->ss_timer); + pSlideShow->ss_timer = NULL; + } + if(pSlideShow->click_timer) { + ecore_timer_del(pSlideShow->click_timer); + pSlideShow->click_timer = NULL; + } + + + for ( int i = 0 ; i < 2; i++) + { + if(pSlideShow->sLayout[i].photocam) { + evas_object_del(pSlideShow->sLayout[i].photocam); + pSlideShow->sLayout[i].photocam = NULL; + } + if(pSlideShow->sLayout[(pSlideShow->sCurrent) % 2].layout) + pSlideShow->sLayout[(pSlideShow->sCurrent) % 2].photocam = + elm_object_part_content_unset(pSlideShow->sLayout[(pSlideShow->sCurrent) % 2].layout, + "content"); + + if(pSlideShow->sLayout[(pSlideShow->sCurrent) % 2].photocam) { + evas_object_del(pSlideShow->sLayout[(pSlideShow->sCurrent) % 2].photocam); + pSlideShow->sLayout[(pSlideShow->sCurrent) % 2].photocam = NULL; + } + if(pSlideShow->sLayout[(pSlideShow->sCurrent + 1) % 2].layout) + pSlideShow->sLayout[(pSlideShow->sCurrent + 1) % 2].photocam = + elm_object_part_content_unset(pSlideShow->sLayout[(pSlideShow->sCurrent + 1) % 2].layout, + "content"); + + if(pSlideShow->sLayout[i].layout) { + evas_object_del(pSlideShow->sLayout[i].layout); + pSlideShow->sLayout[i].layout = NULL; + } + + } + + if ( pSlideShow->event ) + { + evas_object_del(pSlideShow->event); + pSlideShow->event = NULL; + } + + if ( pSlideShow->obj ) + { + evas_object_del(pSlideShow->obj); + pSlideShow->obj = NULL; + } + + if(pSlideShow) + { + free(pSlideShow); + pSlideShow = NULL; + } + return; +} + +void ivug_ss_resize(SlideShow *pSlideShow) +{ + /* resize slide show layout and move them to right pos after rotation */ + if(pSlideShow && pSlideShow->obj && pSlideShow->event) { + ivug_ss_get_screen_size(&pSlideShow->screen_w, &pSlideShow->screen_h); + evas_object_resize(pSlideShow->obj, pSlideShow->screen_w, pSlideShow->screen_h); + Evas_Coord ox, oy, ow, oh; + evas_object_geometry_get(pSlideShow->obj, &ox, &oy, &ow, &oh); + + //MSG_HIGH("Moved (%d,%d,%d,%d)", ox, oy, ow, oh); + if(pSlideShow->event) + { + evas_object_move(pSlideShow->event, ox, oy); + } + + if(pSlideShow->sLayout[pSlideShow->sCurrent].layout) + { + evas_object_move(pSlideShow->sLayout[pSlideShow->sCurrent].layout, ox, oy); + } + if(pSlideShow->sLayout[(pSlideShow->sCurrent + 1) % 2].layout) + { + evas_object_move(pSlideShow->sLayout[(pSlideShow->sCurrent + 1) % 2].layout, ox + pSlideShow->screen_w + IVUG_IMAGE_BETWEEN_MARGIN, oy); + } + //MSG_HIGH("_ivug_ss_resize_obj, Moved (%d,%d,%d,%d)", ox, oy, ow, oh); + } +} + + + +Evas_Object *ivug_ss_object_get(SlideShow *pSlideShow) +{ + MSG_ASSERT(pSlideShow != NULL); + return pSlideShow->obj; +} + diff --git a/widget/CMakeLists.txt b/widget/CMakeLists.txt new file mode 100755 index 0000000..556afa4 --- /dev/null +++ b/widget/CMakeLists.txt @@ -0,0 +1,79 @@ +CMAKE_MINIMUM_REQUIRED(VERSION 2.6) +PROJECT(ivug_widget C CXX) + +SET(PREFIX ${CMAKE_INSTALL_PREFIX}) +SET(VERSION 0.1.0) + +SET(SRCS +# Helper files + src/common/Scroller.cpp + src/common/Primitives.cpp + src/util/EFLUtil.cpp + src/util/ivug-listpopup.c + +#Image + src/image/ivug-image-photocam.cpp + +# ScissorBox + src/scissorbox/ScissorBox.cpp + src/scissorbox/ivug-scissorbox.cpp +) + +INCLUDE_DIRECTORIES( + ${IVUG_SOURCE_COMMON_DIR}/include + ${IVUG_SOURCE_FEATURE_DIR}/include + include + src/common + src/animation + src/image + src/thumblist + src/scissorbox +) + +MESSAGE("Checking " ${PROJECT_NAME} ) + +INCLUDE(FindPkgConfig) +pkg_check_modules(${PROJECT_NAME}_pkgs REQUIRED + elementary + ecore + ecore-evas + edje + eina + evas + dlog +) + +FOREACH(flag ${${PROJECT_NAME}_pkgs_CFLAGS}) + SET(EXTRA_CXXFLAGS "${EXTRA_CXXFLAGS} ${flag}") +ENDFOREACH(flag) + +SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${EXTRA_CXXFLAGS} -Wall") +SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${CMAKE_CXX_FLAGS}") + +ADD_DEFINITIONS("-DPREFIX=\"${CMAKE_INSTALL_PREFIX}\"") +ADD_DEFINITIONS("-DLOG_LVL=DBG_MSG_LVL_HIGH") +ADD_DEFINITIONS("-DLOG_CAT=\"IV-WIDGET\"") + +ADD_LIBRARY(${PROJECT_NAME} SHARED ${SRCS}) + +SET_TARGET_PROPERTIES(${PROJECT_NAME} PROPERTIES SOVERSION ${VERSION} ) +SET_TARGET_PROPERTIES(${PROJECT_NAME} PROPERTIES INSTALL_RPATH ${CMAKE_INSTALL_PREFIX}/lib) + +TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${${PROJECT_NAME}_pkgs_LDFLAGS} + ivug_common ivug_feature +) + +BUILD_EDJ(ivug-scroller.edc ivug-scroller.edj res/layout images) + +#install resouce files. +# Lack of a trailing slash means install this directory, trailing slash means +# install everything in this directory. + +# Install image files. +INSTALL(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/res/images/ DESTINATION ${CMAKE_INSTALL_PREFIX}/res/images/${IVUG_PACKAGE_NAME}) + + +INSTALL(TARGETS ${PROJECT_NAME} DESTINATION lib) + + + diff --git a/widget/include/Animation.h b/widget/include/Animation.h new file mode 100755 index 0000000..7730935 --- /dev/null +++ b/widget/include/Animation.h @@ -0,0 +1,114 @@ +/* + * Copyright 2012 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.tizenopensource.org/license + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include +#include "Transit.h" + +#include +#include "Exception.h" + +using namespace std; + +// Composite pattern +class CAnimator +{ +public: + CAnimator() {}; + + virtual ~CAnimator() {}; + + virtual void Update(double delta_t) = 0; + virtual bool IsFinished() = 0; + + virtual void AddAnimator(CAnimator *animator) { + throw new CException(CException::IO_ERROR); + }; + +protected: +}; + + +class CSingleAnimator : public CAnimator +{ +private: + CSingleAnimator() {}; +public: +// TODO. Using factory + CSingleAnimator(double first, double last, double duration, TranstionFunc transition, AnimationCB callback, void *data) { + m_actor = new CActor(first, last, duration, transition, callback, data); + }; + + virtual ~CSingleAnimator() { delete m_actor;}; + +// Overrides + void Update(double delta_t) { + m_actor->Update(delta_t); + }; + + bool IsFinished() { return m_actor->IsFinished(); }; + +private: + CActor *m_actor; +}; + +class CGroupAnimator : public CAnimator { +public: + CGroupAnimator() {}; + virtual ~CGroupAnimator() { ClearAll(); }; + + void AddAnimator(CAnimator *animator) { + m_actorlist.push_back(animator); + + m_actorlist.back()->Update(0); + }; + + void ClearAll() { + for ( list::iterator iter = m_actorlist.begin(); iter != m_actorlist.end(); iter++ ) + { + delete *iter; + } + + m_actorlist.clear(); + + }; + + bool IsFinished() { + return m_actorlist.empty(); + }; + + void Update(double delta_t) { + for ( list::iterator iter = m_actorlist.begin(); iter != m_actorlist.end(); ) + { + (*iter)->Update(delta_t); + + if ( (*iter)->IsFinished() == true ) + { + iter = m_actorlist.erase(iter); + } + else + { + iter++; + } + } + }; + +private: + list m_actorlist; + +}; + diff --git a/widget/include/ECoreAnimator.h b/widget/include/ECoreAnimator.h new file mode 100755 index 0000000..74bed7b --- /dev/null +++ b/widget/include/ECoreAnimator.h @@ -0,0 +1,124 @@ +/* + * Copyright 2012 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.tizenopensource.org/license + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +typedef bool (*CallbackFUNC)(double delta, void *data); + +#if 0 +template +struct func_bind +{ + static T obj; + static bool call(double value) { return (obj.*callback)(value); }; +}; + +template +T func_bind::obj; +#else + +template +class UserMemFunctor +{ +public: + UserMemFunctor(ObjType& obj, FunType fun) : m_obj(obj), m_func(fun) {} + void operator()(ParmType& p) { (m_obj.*m_func)(p); } +private: + ObjType& m_obj; + FunType m_func; +}; +#endif + +// TODO : Implement using Functor. + +class ECoreAnimator { + static Eina_Bool _on_anim(void *data) + { + ECoreAnimator *thiz = static_cast(data); + + return thiz->OnAnimation(); + } + +public: + ECoreAnimator() : m_animator(NULL), m_bStarted(false) {}; + ~ECoreAnimator() { + Stop(); + }; + + void Start(CallbackFUNC cb, void *data) + { + m_cb = cb; + m_data = data; + + m_count = 0; + m_animator = ecore_animator_add(_on_anim, this); + m_bStarted = true; + } + + void Stop() { + if ( m_bStarted ) + { + m_bStarted = false; + ecore_animator_del(m_animator); + m_animator = NULL; + } + }; + + Eina_Bool OnAnimation() { + double current; + + if ( m_count == 0 ) + { + current = m_prev = ecore_loop_time_get(); + } + else + { + current = ecore_loop_time_get(); + } + + m_count++; + + if ( m_cb(current - m_prev, m_data) == false) + { + Stop(); + return ECORE_CALLBACK_CANCEL; + } + + m_prev = current; + return ECORE_CALLBACK_RENEW; + }; + + bool IsRunning() const { + return m_bStarted; + }; + +private: + Ecore_Animator *m_animator; + +// template +// func_bind m_f; + CallbackFUNC m_cb; + void *m_data; + + double m_prev; + bool m_bStarted; + + int m_count; + +}; + + + diff --git a/widget/include/EFLUtil.h b/widget/include/EFLUtil.h new file mode 100755 index 0000000..72fb218 --- /dev/null +++ b/widget/include/EFLUtil.h @@ -0,0 +1,61 @@ +/* + * Copyright 2012 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.tizenopensource.org/license + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include + +namespace EFL { + void get_evas_geometry(Evas_Object *obj, const char *prefix); + + Evas_Object *create_gesture(Evas_Object *parent); + + Evas_Object *create_rect(Evas_Object *parent); + + Evas_Object *create_clipper(Evas_Object *parent); + + Evas_Object *create_layout(Evas_Object *parent, const char *edj, const char *group); + + Evas_Object *create_button(Evas_Object *parent, const char *style, const char *icon, const char *caption); + + void dump_obj(Evas_Object *obj, int lvl = 0); + + // Returned value Should be freed after using + char * current_render_method(Evas *e); + + Evas_Object *create_window(const char *title, int w, int h); + +}; + +namespace util { + typedef enum { + eImageCodec_JPEG, + eImageCodec_GIF, + eImageCodec_PNG, + eImageCodec_IMAGE, // tif.. other image files + eImageCodec_UNKNOWN, + } Image_Codec_Type; + + Image_Codec_Type + get_codec_type(const unsigned char *buffer, unsigned int size); + + Image_Codec_Type + get_codec_type(const char *filename); + + bool is_openGL_enabled(Evas *e); +}; + + diff --git a/widget/include/EvasSmartObj.h b/widget/include/EvasSmartObj.h new file mode 100755 index 0000000..4fd5fc4 --- /dev/null +++ b/widget/include/EvasSmartObj.h @@ -0,0 +1,168 @@ +/* + * Copyright 2012 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.tizenopensource.org/license + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include +#include "Primitives.h" +#include "ivug-debug.h" + +template +class CEvasSmartObject { +protected: + static const Evas_Smart_Cb_Description _signals[]; + +public: + CEvasSmartObject() : m_obj(NULL) {}; + virtual ~CEvasSmartObject() { + if ( m_obj ) + evas_object_del(m_obj); + m_obj= NULL; + }; + + static void SetClassName(const char *classname) + { + if (_smart_ == NULL ) + { // Damm buggy! Implement using template + const char* name = eina_stringshare_add(classname); + MSG_HIGH("Create smart class name=%s", name); + static Evas_Smart_Class sc = + { + NULL, + EVAS_SMART_CLASS_VERSION, + NULL, + _del, + _move, + _resize, + _show, + _hide, + _color_set, + _clip_set, + _clip_unset, + _calculate, + NULL, + NULL, + NULL, // Parent + NULL, + NULL, + NULL + }; //Evas_smart_Class + sc.name = name; + _smart_ = evas_smart_class_new(&sc); + } + } + + virtual Evas_Object *CreateObject(Evas_Object *parent) + { + m_obj = evas_object_smart_add(evas_object_evas_get(parent), _smart_); //create smart object. + evas_object_smart_data_set(m_obj, this); + + MSG_ASSERT(m_obj != NULL); + + return m_obj; + } + +private: + static void _del(Evas_Object * obj) + { + CEvasSmartObject *thiz = static_cast(evas_object_smart_data_get(obj)); + + thiz->remove(); + }; + + static void _move(Evas_Object *obj, Evas_Coord x, Evas_Coord y) + { + CEvasSmartObject *thiz = static_cast(evas_object_smart_data_get(obj)); + thiz->move(x, y); + }; + + static void _resize(Evas_Object *obj, Evas_Coord w, Evas_Coord h) + { + CEvasSmartObject *thiz = static_cast(evas_object_smart_data_get(obj)); + thiz->resize(w, h); + }; + + static void _show(Evas_Object *obj) + { + CEvasSmartObject *thiz = static_cast(evas_object_smart_data_get(obj)); + thiz->show(); + }; + + static void _hide(Evas_Object *obj) + { + CEvasSmartObject *thiz = static_cast(evas_object_smart_data_get(obj)); + thiz->hide(); + }; + + static void _calculate(Evas_Object *obj) + { + CEvasSmartObject *thiz = static_cast(evas_object_smart_data_get(obj)); + thiz->draw(); + }; + + static void _color_set(Evas_Object *obj, int r, int g, int b, int a) + { + CEvasSmartObject *thiz = static_cast(evas_object_smart_data_get(obj)); + thiz->color_set(r,g,b,a); + }; + + static void _clip_set(Evas_Object *obj, Evas_Object * clip) + { + CEvasSmartObject *thiz = static_cast(evas_object_smart_data_get(obj)); + thiz->clip_set(clip); + }; + + static void _clip_unset(Evas_Object *obj) + { + CEvasSmartObject *thiz = static_cast(evas_object_smart_data_get(obj)); + thiz->clip_unset(); + }; + +protected: + virtual void move(int x, int y) { + m_rect.Left(x); + m_rect.Top(y); + }; + + virtual void resize(int w, int h) { + m_rect.Width(w); + m_rect.Height(h); + }; + + virtual void remove() {}; + virtual void show() {}; + virtual void hide() {}; + virtual void draw() {}; + virtual void color_set(int r, int g, int b, int a) {}; + virtual void clip_set(Evas_Object *clipper) {}; + virtual void clip_unset() {}; + +public: + Evas_Object *GetObject() const { return m_obj; }; + + const CRect GetGeometry() const { return m_rect; }; + +public: + CRect m_rect; + + Evas_Object *m_obj; + + static Evas_Smart *_smart_; + +}; + +template Evas_Smart *CEvasSmartObject::_smart_ = NULL; + diff --git a/widget/include/Exception.h b/widget/include/Exception.h new file mode 100755 index 0000000..6e324da --- /dev/null +++ b/widget/include/Exception.h @@ -0,0 +1,33 @@ +/* + * Copyright 2012 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.tizenopensource.org/license + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +class CException { +public: + typedef enum { + IO_ERROR, + } error_code; + + CException(error_code err) : m_err(err) {}; + ~CException() {}; + +private: + error_code m_err; +}; + + + diff --git a/widget/include/Object.h b/widget/include/Object.h new file mode 100755 index 0000000..0da15bb --- /dev/null +++ b/widget/include/Object.h @@ -0,0 +1,33 @@ +/* + * Copyright 2012 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.tizenopensource.org/license + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + + +#include "EvasSmartObj.h" + +class CObject : public CEvasSmartObject { + +public: + CObject() : CEvasSmartObject() { + CEvasSmartObject::SetClassName("CObject"); + }; + + virtual ~CObject() {}; + + +}; + diff --git a/widget/include/Primitives.h b/widget/include/Primitives.h new file mode 100755 index 0000000..300815c --- /dev/null +++ b/widget/include/Primitives.h @@ -0,0 +1,272 @@ +/* + * Copyright 2012 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.tizenopensource.org/license + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include + +class CSize { +public: + static const CSize Zero; + + CSize(int _w = 0, int _h = 0) { + w = _w; + h = _h; + }; + + CSize(const CSize &rhs) { + SetSize(rhs.w, rhs.h); + }; + + void GetSize(int &w, int &h) const { + w = this->w; + h = this->h; + }; + + void SetSize(int _w, int _h) { + w = _w; + h = _h; + }; + + const CSize operator *(double mul) const { + return CSize(w * mul, h *mul); + } + + const CSize operator /(double mul) const { + return CSize(w / mul, h / mul); + } + + const CSize operator +(const CSize &rhs) const { + return CSize(w + rhs.Width(), h + rhs.Height()); + } + + int Width() const { return w;}; + int Height() const { return h;}; + + void Width(int _w) { w = _w; }; + void Height(int _h) { h = _h; }; + + void Swap() { std::swap(w,h); }; + +private: + int w, h; +}; + + +class CPoint { +public: + static const CPoint Zero; + + CPoint(int _x = 0, int _y = 0) { + x = _x; + y = _y; + }; + + void GetPoint(int &x, int &y) const { + x = this->x; + y = this->y; + }; + + void MoveTo(int x_, int y_) { + x = x_; + y = y_; + }; + + void MoveBy(int x_, int y_) { + x += x_; + y += y_; + }; + + const CPoint operator -(const CPoint &rhs) const { + return CPoint(x - rhs.X(), y - rhs.Y()); + }; + + const CPoint operator +(const CPoint &rhs) const { + return CPoint(x + rhs.X(), y + rhs.Y()); + }; + + const CPoint operator +(const CSize &rhs) const { + return CPoint(x + rhs.Width(), y + rhs.Height()); + }; + + bool operator !=(const CPoint &rhs) const { + return (y != rhs.Y()) || (y != rhs.Y()) ; + }; + + + int X() const { return x; }; + int Y() const { return y; }; + + void X(int _x) { x = _x; }; + void Y(int _y) { y = _y; }; + +private: + int x, y; +}; + + + +class CRect { +public: + static const CRect Zero; +// with north-west gravity default. +public: + + CRect(int _x = 0, int _y = 0, int _w = 0, int _h = 0) { + SetRect(_x, _y, _w, _h); + }; + + CRect(const CRect &rhs) { + SetRect(rhs.Left(), rhs.Top(), rhs.Width(), rhs.Height()); + } + + CRect(const CPoint &_topleft, const CSize &_size) { + SetRect(_topleft.X(), _topleft.Y(), _size.Width(), _size.Height()); + } + + CRect(const CPoint &_topleft, const CPoint &_bottomright) { + topleft = _topleft; + bottomright = _bottomright; + } + + ~CRect() {}; + + const CRect operator /(double mul) const { + return CRect(Left(), Top(), Width() / mul, Height() / mul); + } + + bool operator !=(const CRect &rhs) const { + return ( topleft.X() != rhs.Left() ) || ( topleft.Y() != rhs.Top() ) || + ( bottomright.X() != rhs.Right() ) || ( bottomright.Y() != rhs.Bottom() ); + }; + + + void SetRect(int _x, int _y, int _w, int _h) { + topleft.X(_x); + topleft.Y(_y); + + SetSize(_w,_h); + }; + + void MoveTo(const CPoint &_topleft) + { + CSize cSize = GetSize(); + + topleft = _topleft; + SetSize(cSize); + } + + void MoveTo(int _x, int _y) + { + CSize cSize = GetSize(); + + topleft = CPoint(_x,_y); + SetSize(cSize); + } + + void MoveBy(const CPoint &_dpoint) // Difference move + { + topleft = topleft + _dpoint; + bottomright = bottomright + _dpoint; + } + + void MoveBy(int dx, int dy) // Difference move + { + topleft = topleft + CPoint(dx, dy); + bottomright = bottomright + CPoint(dx, dy); + } + + void Resize(int _w, int _h) + { + SetSize(_w, _h); + } + + const CPoint GetCenter() const { return CPoint(topleft.X() + Width() / 2, topleft.Y() + Height() / 2); }; +// Getter + const CSize GetSize() const { return CSize(Width() , Height() ); }; + + int Left() const { return topleft.X(); }; + int Right() const { return bottomright.X(); }; + int Top() const { return topleft.Y(); }; + int Bottom() const { return bottomright.Y(); }; + + const CPoint &TopLeft() const { return topleft; }; + const CPoint &BottomRight() const { return bottomright; }; + + bool IsValid() { + return !( Width() < 0 || Height() < 0 ); + }; + +// Setter + void SetSize(const CSize &newsize) { + Width(newsize.Width()); + Height(newsize.Height()); + }; + + void SetSize(int w, int h) { + Width(w); + Height(h); + }; + + void Left(int _V) { int W = Width(); topleft.X(_V); bottomright.X(_V + W); }; + void Right(int _V) { int W = Width(); bottomright.X(_V); topleft.X(_V - W); }; + void Top(int _V) { int H = Height(); topleft.Y(_V); bottomright.Y(_V + H); }; + void Bottom(int _V) { int H = Height(); bottomright.Y(_V); topleft.Y(_V - H);}; + + + int Width() const { return bottomright.X() - topleft.X(); }; + int Height() const { return bottomright.Y() - topleft.Y(); }; + void Width(int _W) { bottomright.X(topleft.X() + _W); }; + void Height(int _H) { bottomright.Y(topleft.Y() + _H); }; + + bool Intersect(const CRect &rhs) const { + return ( ( Left() < rhs.Right() ) && ( Top() < rhs.Bottom() ) && ( Right() > rhs.Left() ) && ( Bottom() > rhs.Top() )); + }; + + void Inflate(int x1, int y1, int x2, int y2) { + topleft.X( topleft.X() + x1); + topleft.Y( topleft.Y() + y1); + + bottomright.X( bottomright.X() + x2); + bottomright.Y( bottomright.Y() + y2); + }; + + friend CRect UnionRect(const CRect &rect1, const CRect &rect2); + friend CRect IntersectRect(const CRect &rect1, const CRect &rect2); + + bool Inside(const CPoint &rhs) const { + return (Left() < rhs.X()) && (rhs.X() < Left() + Width() ) && (Top() < rhs.Y()) && (rhs.Y() < Top() + Height() ); + }; + + bool Inside(const CRect &rhs) const { + return (Left() <= rhs.Left()) && (rhs.Right() <= Right() ) && (Top() <= rhs.Top()) && (rhs.Bottom() <= Bottom() ); + }; + + void Scale(double ratio_x, double ratio_y) { + topleft.X( topleft.X() * ratio_x); + bottomright.X( bottomright.X() * ratio_x); + + + topleft.Y( topleft.Y() * ratio_y); + bottomright.Y( bottomright.Y() * ratio_y); + }; + +private: + CPoint topleft; + CPoint bottomright; +}; + + diff --git a/widget/include/ScrollerClient.h b/widget/include/ScrollerClient.h new file mode 100755 index 0000000..e033f1c --- /dev/null +++ b/widget/include/ScrollerClient.h @@ -0,0 +1,122 @@ +/* + * Copyright 2012 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.tizenopensource.org/license + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include +#include "Object.h" + +#include "Scroller.h" + +#undef DISABLE_ORIGIN + +class CScrollerClient : public CObject { + friend class CScroller; +public: + CScrollerClient(Evas_Object *parent) : m_zoom(0.0f), m_size(0,0), m_update(0), m_origin(0,0), m_scroller(NULL) { + CreateObject(parent); + }; + + virtual ~CScrollerClient(){ + MSG_HIGH("CScrollerClient destructor"); + }; + +public: + const CRect GetClientRect() const { + // Returns window rect(LCD coordinate) + return CRect(topleft, m_extent); + }; + + virtual void Move(int x, int y) { topleft.MoveTo(x,y); }; + virtual void MoveBy(int dx, int dy) { topleft.MoveBy(dx,dy); }; + + virtual void PanX(int x) { topleft.X(x); }; + virtual void PanY(int y) { topleft.Y(y); }; + + virtual void Draw() { MSG_HIGH("Scroller client Draw"); }; + + virtual void BeginUpdate() { + m_update++; + + MSG_HIGH("Begin update. Count=%d", m_update); + }; + virtual void EndUpdate() { + m_update--; + + MSG_HIGH("End update. Count=%d", m_update); + }; + +#ifndef DISABLE_ORIGIN + virtual void SetOrigin(int x, int y) { + MSG_LOW("Set Origin (%d,%d)", x, y); + m_origin = CPoint(x,y); + }; + + const CPoint &GetOrigin() const { + return m_origin; + }; + +#endif + // Scroller client original size + virtual void SetSize(const CSize &size) { + MSG_HIGH("CScrollerClient SetSize(%d,%d)", size.Width(), size.Height()); + + m_size = size; + }; + virtual const CSize &GetClientSize() const { return m_size; }; + virtual double Zoom() const { return m_zoom; }; + virtual void Zoom(double zoom) { + m_zoom = zoom; + + m_extent = m_size * m_zoom; + + MSG_LOW("Set Zoom=%f", m_zoom); + }; + + void Changed() { + m_scroller->OnChanged(this); + }; + +private: + void SetScroller(CScroller *scroller) { + m_scroller = scroller; + }; + + void UnSetScroller() { + m_scroller = NULL; + }; + +// Need OnResized?? +protected: + double m_zoom; + + CPoint topleft; + CSize m_size; // original size + + int m_update; + +private: + +#ifndef DISABLE_ORIGIN + CPoint m_origin; +#endif + CSize m_extent; // display size + + CScroller *m_scroller; + +}; + + diff --git a/widget/include/Transit.h b/widget/include/Transit.h new file mode 100755 index 0000000..d0ef0eb --- /dev/null +++ b/widget/include/Transit.h @@ -0,0 +1,176 @@ +/* + * Copyright 2012 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.tizenopensource.org/license + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include + +typedef double (*TranstionFunc)(double t); +typedef void (*AnimationCB)(double value, void *data); + + +class CTranstionFunc { +// Normalied transition fuctions. +public: + static double ConstTransit(double t) { + return 0; + }; + + static double LinearTransit(double t) { + return t; + }; + + static double SineTransit(double t) { + static const double SIN_TABLE[91] = { + 0.0000f, 0.0174f, 0.0349f, 0.0523f, 0.0698f, + 0.0872f, 0.1045f, 0.1219f, 0.1392f, 0.1564f, + 0.1736f, 0.1908f, 0.2079f, 0.2249f, 0.2419f, + 0.2588f, 0.2756f, 0.2924f, 0.3090f, 0.3256f, + 0.3420f, 0.3584f, 0.3746f, 0.3907f, 0.4067f, + 0.4226f, 0.4384f, 0.4540f, 0.4695f, 0.4848f, + 0.5000f, 0.5150f, 0.5299f, 0.5446f, 0.5592f, + 0.5736f, 0.5878f, 0.6018f, 0.6157f, 0.6293f, + 0.6528f, 0.6561f, 0.6691f, 0.6820f, 0.6947f, + 0.7071f, 0.7193f, 0.7314f, 0.7431f, 0.7547f, + 0.7660f, 0.7772f, 0.7880f, 0.7986f, 0.8090f, + 0.8191f, 0.8290f, 0.8387f, 0.8480f, 0.8571f, + 0.8660f, 0.8746f, 0.8829f, 0.8910f, 0.8988f, + 0.9063f, 0.9135f, 0.9205f, 0.9272f, 0.9336f, + 0.9397f, 0.9455f, 0.9511f, 0.9563f, 0.9613f, + 0.9659f, 0.9703f, 0.9744f, 0.9781f, 0.9816f, + 0.9848f, 0.9877f, 0.9903f, 0.9926f, 0.9945f, + 0.9962f, 0.9976f, 0.9986f, 0.9994f, 0.9998f, + 1.0f + }; + + int idx = (int)(90.0 * t); + + return (SIN_TABLE[idx]); + }; + + static double EaseInoutTransit(double t) { + double ts = t * t; + double tc = ts * t; + return (-2 * tc + 3 * ts); + } + +}; + + +class CTransit { +public: + CTransit(double first, double last, double duration , TranstionFunc transition) : m_duration(duration), m_current(0), m_start(first), m_last(last), + m_transition(transition) { + }; + + + CTransit() : m_duration(1.0f), m_current(0), m_transition(CTranstionFunc::ConstTransit) { + }; + + ~CTransit() { + }; + + void SetTransitFunction(TranstionFunc transition ) { + m_transition = transition; + m_current = 0.0f; + }; + + void SetDuration(double duration) // X variations(time) + { + m_duration = m_duration; + m_current = 0.0f; + } + + void SetInit(double first) // Y variationns + { + m_start = first; + m_current = 0.0f; + } + + void SetEnd(double last) // Y variationns + { + m_last = last; + m_current = 0.0f; + } + + double Update(double dt) { + double reminant = std::min(m_duration - m_current, dt ); + + m_current += reminant; + + return m_start + m_transition( m_current/m_duration ) * ( m_last - m_start); + + }; + + bool IsFinished() { + return m_current >= m_duration; + }; + +private: + double m_duration; + double m_current; + + double m_start; + double m_last; + + TranstionFunc m_transition; +}; + + + +class CActor { +public: + CActor() { + m_tween = new CTransit(); + }; +// TODO : Using functor! + CActor(double first, double last, double duration, TranstionFunc transition, AnimationCB callback, void *data) : m_callback(callback), m_data(data) { + m_tween = new CTransit(first, last, duration, transition); + }; + + ~CActor() { + delete m_tween; + m_tween = NULL; + }; + + void SetCallback(AnimationCB callback, void *data) { + m_callback = callback; + m_data = data; + }; + + void SetConfig(double first, double last, double duration, TranstionFunc transition) + { + m_tween->SetTransitFunction(transition); + m_tween->SetInit(first); + m_tween->SetEnd(last); + m_tween->SetDuration(duration); + } + + void Update(double delta_t) + { + double value = m_tween->Update(delta_t); + + m_callback(value, m_data); + } + + bool IsFinished() const { return m_tween->IsFinished(); }; +private: + AnimationCB m_callback; + void *m_data; + + CTransit *m_tween; +}; + diff --git a/widget/include/ivug-image.h b/widget/include/ivug-image.h new file mode 100755 index 0000000..bd0aba4 --- /dev/null +++ b/widget/include/ivug-image.h @@ -0,0 +1,119 @@ +/* + * Copyright 2012 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.tizenopensource.org/license + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __IVUG_IMAGE_H__ +#define __IVUG_IMAGE_H__ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + + +Evas_Object * +ivug_image_create(Evas_Object *parent); + + +/* + Load & Unload image file +*/ +Evas_Load_Error +ivug_image_file_set(Evas_Object *obj, const char *file, const char *key); + +Evas_Load_Error +ivug_image_mem_set(Evas_Object *obj, const char *buffer, unsigned int size, const char *key); + +Evas_Load_Error +ivug_image_unset(Evas_Object *obj); + +/* + Configuration +*/ +void +ivug_image_hold_set(const Evas_Object *obj, Eina_Bool hold); // If set HOLD, all events including mouse is ignored. + +void +ivug_image_animated_set(const Evas_Object *obj, Eina_Bool bAnimation); // Determine whether AGIF is animated or not + +/* + Showing +*/ +void +ivug_image_zoom_set(Evas_Object *obj, double zoom, Evas_Point *pCenter); + +double +ivug_image_zoom_get(const Evas_Object *obj); + +void +ivug_image_zoom_reset(Evas_Object *obj, Evas_Point *pCenter); + + +void +ivug_image_rotate_set(Evas_Object *obj, int degree); + +int +ivug_image_rotate_get(Evas_Object *obj); + + + +/* + Get image's original size. +*/ +void +ivug_image_image_size_get(const Evas_Object *obj, int *w, int *h); + +Evas_Object * +ivug_image_internal_image_get(Evas_Object *obj); + +void +ivug_image_decoded_size_get(const Evas_Object *obj, int *w, int *h); + +unsigned char * +ivug_image_decoded_buffer_get(const Evas_Object *obj); + + +/* + Get display geometry. + x,y,w,h is LCD corrdinate +*/ +void +ivug_image_region_get(const Evas_Object *obj, int *x, int *y, int *w, int *h); // Geometry of internal image + +/* + Crop image and return cropped image as Evas_Object. + x,y,w,h is LCD corrdinate +*/ +Evas_Object * +ivug_image_region_image_get(Evas_Object *obj, int x, int y, int w, int h ); + + +/* + +*/ +void ivug_image_coordinate_lcd_to_image(Evas_Object *photocam, int lcd_x, int lcd_y, int *img_x, int *img_y); +void ivug_image_coordinate_image_to_lcd(Evas_Object *photocam, int img_x, int img_y, int *lcd_x, int *lcd_y); + + +#ifdef __cplusplus +} +#endif + + + + +#endif // __IVUG_IMAGE_H__ + diff --git a/widget/include/ivug-listpopup.h b/widget/include/ivug-listpopup.h new file mode 100755 index 0000000..8147603 --- /dev/null +++ b/widget/include/ivug-listpopup.h @@ -0,0 +1,71 @@ +/* + * Copyright 2012 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.tizenopensource.org/license + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __IVUG_LISTPOPUP_H__ +#define __IVUG_LISTPOPUP_H__ + + +typedef void Ivug_ListPopup_Item; + +#ifdef __cplusplus +extern "C" { +#endif + +#include +/* + Signals + "popup,selected" event_info contains Ivug_ListPopup_Item which is used when append/prepend + "popup,dismissed" closed button pressed, in case of contextual, no dismised callback + +*/ + +Evas_Object *ivug_listpopup_add(Evas_Object *parent); + +Ivug_ListPopup_Item *ivug_listpopup_item_append(Evas_Object *obj, const char *iconpath, const char *caption, void *data); +Ivug_ListPopup_Item *ivug_listpopup_item_prepend(Evas_Object *obj, const char *iconpath, const char *caption, void *data); + +/* + Eina list includes (Ivug_ListPopup_Item *) - (Ivug_ListPopup_Item *) - (Ivug_ListPopup_Item *) .... +*/ +Eina_List *ivug_listpopup_items_get(Evas_Object *obj); + +/* + Valid only when genlist style popup +*/ +void ivug_listpopup_button_set(Evas_Object *obj, const char* caption); +void ivug_listpopup_title_set(Evas_Object *obj, const char* title); + + +void *ivug_listpopup_item_get_data(Ivug_ListPopup_Item *item); +void ivug_listpopup_item_disabled_set(Ivug_ListPopup_Item *item); +void ivug_listpopup_item_enabled_set(Ivug_ListPopup_Item *item); +const char *ivug_listpopup_item_get_text(Ivug_ListPopup_Item *item); + + +/* + Show Time! +*/ +bool ivug_listpopup_popup_show(Evas_Object *obj); +bool ivug_listpopup_context_show(Evas_Object *obj, Evas_Object *hover, int x, int y); + + +#ifdef __cplusplus +} +#endif + + +#endif // __IVUG_LISTPOPUP_H__ + diff --git a/widget/include/ivug-scissorbox.h b/widget/include/ivug-scissorbox.h new file mode 100755 index 0000000..ba06621 --- /dev/null +++ b/widget/include/ivug-scissorbox.h @@ -0,0 +1,54 @@ +/* + * Copyright 2012 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.tizenopensource.org/license + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __IVUG_SCISSORBOX_H__ +#define __IVUG_SCISSORBOX_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum { + SCISSOR_BOX_TYPE_1, //. Image view + SCISSOR_BOX_TYPE_2, // Image edit +} eScissorBoxType; + + +Evas_Object *ivug_scissorbox_add(Evas_Object *parent); + +void ivug_scissorbox_type_set(Evas_Object *obj, eScissorBoxType type); + +void ivug_scissorbox_attach(Evas_Object *obj, Evas_Object *pObj); + +void ivug_scissorbox_region_set(Evas_Object *obj, int x, int y, int w, int h); +void ivug_scissorbox_region_get(Evas_Object *obj, int *x, int *y, int *w, int *h); + + +void ivug_scissorbox_boundary_set(Evas_Object *obj, int x, int y, int w, int h); + + +/*DEFAULT_RATIO_FIX = EINA_TRUE */ +void ivug_scissorbox_ratio_fix(Evas_Object *obj, Eina_Bool bFix); + +/* Default value is bOpaque = true */ +void ivug_scissorbox_set_opaque(Evas_Object *obj, Eina_Bool bOpaque); + +#ifdef __cplusplus +} +#endif + +#endif /* __IVUG_SCISSORBOX_H__*/ + diff --git a/widget/res/images/crop/T06_selection.png b/widget/res/images/crop/T06_selection.png new file mode 100755 index 0000000000000000000000000000000000000000..52c7886ef15b167ef8f7beb48c77045f1c4d8042 GIT binary patch literal 3259 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 literal 0 HcmV?d00001 diff --git a/widget/res/images/crop/T06_selection_Resizing_V.png b/widget/res/images/crop/T06_selection_Resizing_V.png new file mode 100755 index 0000000000000000000000000000000000000000..967937b79d61d8308b1deeff0863c205bc0d214a GIT binary patch literal 5852 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 literal 0 HcmV?d00001 diff --git a/widget/res/images/crop/T06_selection_Rotate.png b/widget/res/images/crop/T06_selection_Rotate.png new file mode 100755 index 0000000000000000000000000000000000000000..1709767041c741b059eedfe500a29b024300a60b GIT binary patch literal 7466 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 literal 0 HcmV?d00001 diff --git a/widget/res/images/scissorbox/T01_CallerID_hold.png b/widget/res/images/scissorbox/T01_CallerID_hold.png new file mode 100755 index 0000000000000000000000000000000000000000..b31bc39afc7566dc8a6b18d62a568d3268b2ee4c GIT binary patch literal 2881 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 literal 0 HcmV?d00001 diff --git a/widget/res/images/scissorbox/T01_CallerID_line_W.png b/widget/res/images/scissorbox/T01_CallerID_line_W.png new file mode 100755 index 0000000000000000000000000000000000000000..f436338d3c7ca770aae38ebf85006c768140bfe7 GIT binary patch literal 2802 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 KMNUMnLSTX*mo!fR literal 0 HcmV?d00001 diff --git a/widget/res/images/scissorbox/T01_CallerID_line_h.png b/widget/res/images/scissorbox/T01_CallerID_line_h.png new file mode 100755 index 0000000000000000000000000000000000000000..587a6da86ce2bd3bbfd75b72699739f10b00b501 GIT binary patch literal 2807 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 JPDHLkV1nguFbMzv literal 0 HcmV?d00001 diff --git a/widget/res/images/scissorbox/T01_CallerID_normal.png b/widget/res/images/scissorbox/T01_CallerID_normal.png new file mode 100755 index 0000000000000000000000000000000000000000..1787cdeb03ad7922b25d710bc9645a0032e2ccbd GIT binary patch literal 2879 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 literal 0 HcmV?d00001 diff --git a/widget/res/layout/ivug-scroller.edc b/widget/res/layout/ivug-scroller.edc new file mode 100755 index 0000000..935f10b --- /dev/null +++ b/widget/res/layout/ivug-scroller.edc @@ -0,0 +1,40 @@ +/* + * Copyright 2012 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.tizenopensource.org/license + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +collections { + group { + name: "scroller"; + + parts { + part { + name: "elm.rect.bg"; + type: RECT; + scale: 1; + mouse_events: 0; + description { + state: "default" 0.0; + visible: 1; + rel1 { relative: 0.0 0.0; } + rel2 { relative: 1.0 1.0; } + color: 0 0 0 0; + } + } + + } // End of parts + } +} + + diff --git a/widget/src/common/BufferCanvas.h b/widget/src/common/BufferCanvas.h new file mode 100755 index 0000000..fce37a6 --- /dev/null +++ b/widget/src/common/BufferCanvas.h @@ -0,0 +1,54 @@ +/* + * Copyright 2012 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.tizenopensource.org/license + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +class CBufferCanvas { +public: + CBufferCanvas() : m_ee(NULL), m_evas(NULL) {}; + ~CBufferCanvas() { + if ( m_ee) + ecore_evas_free(m_ee); + } + + void Create(int w, int h) { + m_ee = ecore_evas_buffer_new(w,h); + MSG_ASSERT(m_ee != NULL); + + m_evas = ecore_evas_get(m_ee); + }; + + Evas *GetCanvas() const { + return m_evas; + }; + + const void *GetPixels() const { + return ecore_evas_buffer_pixels_get(m_ee); + }; + + void Render() const { + ecore_evas_manual_render(m_ee); + }; + + +private: + +private: + Ecore_Evas *m_ee; + Evas *m_evas; + + +}; diff --git a/widget/src/common/Primitives.cpp b/widget/src/common/Primitives.cpp new file mode 100755 index 0000000..cfe3b5f --- /dev/null +++ b/widget/src/common/Primitives.cpp @@ -0,0 +1,61 @@ +/* + * Copyright 2012 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.tizenopensource.org/license + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "Primitives.h" +#include + + +using namespace std; + + +const CRect CRect::Zero = CRect(0,0,0,0); +const CSize CSize::Zero = CSize(0,0); +const CPoint CPoint::Zero = CPoint(0,0); + + + +CRect UnionRect(const CRect &rect1, const CRect &rect2) +{ + return CRect( + CPoint( min(rect1.Left(), rect2.Left()), + min(rect1.Top(), rect2.Top()) ), + + CPoint( max(rect1.Right(), rect2.Right()), + max(rect1.Bottom(), rect2.Bottom()) ) + ); +} + + +CRect IntersectRect(const CRect &rect1, const CRect &rect2) +{ + CRect rect( + CPoint( max(rect1.Left(), rect2.Left()), + max(rect1.Top(), rect2.Top()) ), + + CPoint( min(rect1.Right(), rect2.Right()), + min(rect1.Bottom(), rect2.Bottom()) ) + ); + + if ( rect.IsValid() == false) + { + rect = CRect::Zero; + } + + return rect; +} + + + diff --git a/widget/src/common/Scroller.cpp b/widget/src/common/Scroller.cpp new file mode 100755 index 0000000..01d8100 --- /dev/null +++ b/widget/src/common/Scroller.cpp @@ -0,0 +1,1386 @@ +/* + * Copyright 2012 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.tizenopensource.org/license + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "Scroller.h" + +#include "ivug-debug.h" +#include + +#include "EFLUtil.h" +#include "Animation.h" +#include "ECoreAnimator.h" +#include "ScrollerClient.h" + +#define EDJ_PATH PREFIX"/res/edje/"PACKAGE + +#undef LOG_LVL +#define LOG_LVL DBG_MSG_LVL_HIGH + +#undef LOG_CAT +#define LOG_CAT "IV-SCROLLER" + +#define ENABLE_CLIPPER + +// 100 pixel ´ç 100 ms °É¸®µµ·Ï ¿òÁ÷ÀδÙ. +#define MIN_ZOOM_RATIO (0.85f) + +#define SCR_VELOCITY(dist, v) ((((dist) > 0 ? (dist) : -(dist)) *0.1f) / 100) + +CScroller::CScroller(const char *name) : CObject(), m_clipper(NULL), m_gesture(NULL), m_event(NULL), m_client(NULL), m_nFinger(0), m_ani(NULL), m_freeze(false), m_resized(false), m_calcjob(NULL) +{ + MSG_HIGH("Scroller added : %s", name); + + m_name = name; + m_ani_zoom = new ECoreAnimator(); +}; + +CScroller::~CScroller() +{ + MSG_HIGH("Scroller removed"); + delete m_ani_zoom; + m_ani_zoom= NULL; + + if ( m_calcjob ) + { + ecore_job_del(m_calcjob); + m_calcjob = NULL; + } + + UnsetClient(); + + if ( m_obj ) // Scroller itself is removed! + { + evas_object_del(m_obj); + } + m_obj = NULL; + + +}; + +Evas_Event_Flags CScroller::_zoom_start(void *data, void *event_info) +{ + Elm_Gesture_Zoom_Info *p = (Elm_Gesture_Zoom_Info *) event_info; + MSG_LOW("zoom start <%d,%d> <%f>", p->x, p->y, p->zoom); + + CScroller *thiz = static_cast(data); + + thiz->zoom_start(CPoint(p->x, p->y), p->zoom); + + return EVAS_EVENT_FLAG_NONE; +} + +Evas_Event_Flags CScroller::_zoom_move(void *data, void *event_info) +{ + Elm_Gesture_Zoom_Info *p = (Elm_Gesture_Zoom_Info *) event_info; + MSG_LOW("zoom move <%d,%d> <%f>", p->x, p->y, p->zoom); + + CScroller *thiz = static_cast(data); + + thiz->zoom_move(CPoint(p->x, p->y), p->zoom); + + return EVAS_EVENT_FLAG_NONE; +} + +Evas_Event_Flags CScroller::_zoom_end(void *data, void *event_info) +{ + Elm_Gesture_Zoom_Info *p = (Elm_Gesture_Zoom_Info *) event_info; + MSG_LOW("zoom end <%d,%d> <%f>", p->x, p->y, p->zoom); + + CScroller *thiz = static_cast(data); + + thiz->zoom_end(CPoint(p->x, p->y), p->zoom); + + return EVAS_EVENT_FLAG_NONE; +} + +Evas_Event_Flags CScroller::_zoom_abort(void *data, void *event_info) +{ + Elm_Gesture_Zoom_Info *p = (Elm_Gesture_Zoom_Info *) event_info; + MSG_LOW("zoom abort <%d,%d> <%f>", p->x, p->y, p->zoom); + + CScroller *thiz = static_cast(data); + + thiz->zoom_abort(CPoint(p->x, p->y), p->zoom); + + return EVAS_EVENT_FLAG_NONE; +} + +Evas_Event_Flags CScroller::_momentum_start(void *data, void *event_info) +{ + Elm_Gesture_Momentum_Info *p = (Elm_Gesture_Momentum_Info *) event_info; + MSG_LOW("momentum_start <%d,%d>", p->x2, p->y2); + + if ( p->n != 1 ) return EVAS_EVENT_FLAG_NONE; + + CScroller *thiz = static_cast(data); + + thiz->momentum_start(CPoint(p->x1, p->y1), CPoint(p->x2, p->y2), CSize(p->mx, p->my) ); + + return EVAS_EVENT_FLAG_NONE; +} + +Evas_Event_Flags CScroller::_momentum_move(void *data, void *event_info) +{ + Elm_Gesture_Momentum_Info *p = (Elm_Gesture_Momentum_Info *) event_info; + MSG_LOW("momentum move <%d,%d>", p->x2, p->y2); + + if ( p->n != 1 ) return EVAS_EVENT_FLAG_NONE; + + CScroller *thiz = static_cast(data); + + thiz->momentum_move(CPoint(p->x1, p->y1), CPoint(p->x2, p->y2), CSize(p->mx, p->my) ); + + return EVAS_EVENT_FLAG_NONE; +} + +Evas_Event_Flags CScroller::_momentum_end(void *data, void *event_info) +{ + Elm_Gesture_Momentum_Info *p = (Elm_Gesture_Momentum_Info *) event_info; + MSG_LOW("momentum end <%d,%d> <%d,%d>", p->x2, p->y2, p->mx, p->my); + + if ( p->n != 1 ) return EVAS_EVENT_FLAG_NONE; + + CScroller *thiz = static_cast(data); + + thiz->momentum_end(CPoint(p->x1, p->y1), CPoint(p->x2, p->y2), CSize(p->mx, p->my) ); + + return EVAS_EVENT_FLAG_NONE; +} + +Evas_Event_Flags CScroller::_momentum_abort(void *data, void *event_info) +{ + Elm_Gesture_Momentum_Info *p = (Elm_Gesture_Momentum_Info *) event_info; + MSG_LOW("momentum abort <%d,%d> <%d,%d>", p->x2, p->y2, p->mx, p->my); + + if ( p->n != 1 ) return EVAS_EVENT_FLAG_NONE; + + CScroller *thiz = static_cast(data); + + thiz->momentum_abort(CPoint(p->x1, p->y1), CPoint(p->x2, p->y2), CSize(p->mx, p->my) ); + + return EVAS_EVENT_FLAG_NONE; +} + +Evas_Event_Flags CScroller::_dbl_click_start(void *data , void *event_info) +{ + Elm_Gesture_Taps_Info *p = (Elm_Gesture_Taps_Info *) event_info; + + MSG_HIGH("Double click start"); + + if ( p->n != 1 ) return EVAS_EVENT_FLAG_NONE; + + return EVAS_EVENT_FLAG_ON_HOLD; +} + +Evas_Event_Flags CScroller::_dbl_click_end(void *data , void *event_info) +{ + Elm_Gesture_Taps_Info *p = (Elm_Gesture_Taps_Info *) event_info; + + MSG_HIGH("Double click end"); + + if ( p->n != 1 ) return EVAS_EVENT_FLAG_NONE; + + CScroller *thiz = static_cast(data); + + thiz->double_click(CPoint(p->x, p->y)); + + return EVAS_EVENT_FLAG_ON_HOLD; +} + +Evas_Event_Flags CScroller::_dbl_click_abort(void *data , void *event_info) +{ + Elm_Gesture_Taps_Info *p = (Elm_Gesture_Taps_Info *) event_info; + + MSG_HIGH("Double click abort"); + + if ( p->n != 1 ) return EVAS_EVENT_FLAG_NONE; + + return EVAS_EVENT_FLAG_ON_HOLD; +} + +bool CScroller::SetClient(CScrollerClient *client) +{ + MSG_HIGH("[%s] Set client.", m_name.c_str()); + + if ( client == m_client ) return true; + + if ( m_client != NULL ) + { + // Removing old client first. + UnsetClient(); + } + + m_client = client; + + m_client->SetScroller(this); + + evas_object_smart_member_add(m_client->GetObject(), GetObject()); + evas_object_stack_below(m_client->GetObject(), m_event); + +#ifdef ENABLE_CLIPPER + evas_object_clip_set(m_client->GetObject(), m_clipper); + evas_object_show(m_clipper); +#endif + + evas_object_pass_events_set(m_event, EINA_FALSE); + evas_object_pass_events_set(m_client->GetObject(), EINA_FALSE); + + CSize img = m_client->GetClientSize(); + + if ( img.Width() == 0 || img.Height() == 0 ) + { + MSG_WARN("Not ready to dump client"); + return true; + } + + m_zoom_autofit = GetAutoFitZoom(); + m_rect_autofit = GetAutoFitGeometry(); + + MSG_HIGH("[%s] Set client. AutoFitZoom(%f) Rect(%d,%d,%d,%d)", m_name.c_str(), m_zoom_autofit, m_rect_autofit.Left(), m_rect_autofit.Top(), m_rect_autofit.Width(), m_rect_autofit.Height()); + + DoAutoFit(); + + return true; +}; + +bool CScroller::UnsetClient() +{ + if ( m_client == NULL ) return true; + + MSG_HIGH("[%s] Unset client.", m_name.c_str()); + + evas_object_pass_events_set(m_event, EINA_TRUE); + +#ifdef ENABLE_CLIPPER + evas_object_clip_unset(m_client->GetObject()); + evas_object_hide(m_clipper); +#endif + + evas_object_smart_member_del(m_client->GetObject()); + + m_client->UnSetScroller(); + m_client = NULL; + + return true; +}; + +void CScroller::OnChanged(CScrollerClient *client) +{ + MSG_HIGH("[%s] Client changed!", m_name.c_str()); + + m_zoom_autofit = GetAutoFitZoom(); + m_rect_autofit = GetAutoFitGeometry(); + + DoAutoFit(); +} + +void CScroller::DisableEvent() { + MSG_LOW("Disable events"); + + m_freeze = true; + +// evas_object_freeze_events_set(m_event, EINA_TRUE); +// elm_object_disabled_set(m_gesture, EINA_TRUE); +}; + +void CScroller::EnableEvent() { + MSG_LOW("Enable events"); + +// elm_object_disabled_set(m_gesture, EINA_FALSE); +// evas_object_freeze_events_set(m_event, EINA_FALSE); + + m_freeze = false; + +}; + + +/* (lcd size * BASE_OF_BIG_SIZE_IMAGE) define big size image */ +#define BASE_OF_BIG_SIZE_IMAGE (5) + +/* d_size_percent is for bouncing size rate */ +/* return base_size(width or height)/limit_size */ +static double _calc_limit_zoom(int org_w, int org_h, + int img_w, int img_h, int lcd_w, int lcd_h) +{ + + int img_base = 0; + int lcd_base = 0; + int org_base = 0; + int limit = 0; + + MSG_LOW("org w, h = %d, %d, img w, h = %d, %d, lcd w, h = %d, %d", + org_w, org_h, img_w, img_h, lcd_w, lcd_h); + + double lcd_ratio = (double)lcd_h/lcd_w; + double org_ratio = (double)org_h/org_w; + + if ( org_ratio > lcd_ratio ) + { + img_base = img_h; + lcd_base = lcd_h; + org_base = org_h; + } + else + { + img_base = img_w; + lcd_base = lcd_w; + org_base = org_w; + } + +#if 0 + /* img region is smaller than lcd region for min zoom */ + if (img_base < lcd_base) + { + return (double)(img_base/lcd_base); + } +#else + /* (img region*(1-d_size_rate)) is smaller than lcd region for min zoom */ + if (img_base*(1.2) < lcd_base) + { + return (double)(img_base*(1.2)/lcd_base); + } + else + { + /* (img region*(1+d_size_rate)) for max zoom bouncing */ + img_base *= (0.8); + } +#endif + + if(lcd_base*BASE_OF_BIG_SIZE_IMAGE < org_base) /* original img size is larger than (lcd size*3) */ + { + limit = org_base; /* 1:1 */ + } + else if(lcd_base < org_base) /* original img size is larger than lcd size */ + { + limit = MAX(org_base*(BASE_OF_BIG_SIZE_IMAGE-1), lcd_base*BASE_OF_BIG_SIZE_IMAGE); + } + else /* original img size is smaller than lcd size */ + { + limit = lcd_base*BASE_OF_BIG_SIZE_IMAGE; + } + if(img_base > limit) + { + return (double)img_base/limit; + } + return 1.0; +} + +void CScroller::Zoom(const CPoint ¢er, double zoom) +{ + CPoint topleft; + CPoint newCenter; + + topleft = m_client->GetClientRect().TopLeft(); + newCenter = center - topleft; // Get Image local coordinate center. + + { + CSize zoomed = m_client->GetClientSize(); + CRect rect = m_client->GetClientRect(); +// ScreenToClient(rect); + + zoomed = zoomed * zoom; + + MSG_LOW("Current Geo XYWH(%d,%d,%d,%d)", rect.Left(), rect.Top(), rect.Width(), rect.Height()); + MSG_LOW("Origianl size WH(%d,%d)", m_extent.Width(), m_extent.Height()); + MSG_LOW("Zoomed size WH(%d,%d) Zoom=%f", zoomed.Width() , zoomed.Height(), zoom); + + MSG_LOW("Zoom %f %f", m_extent.Width() * zoom, m_extent.Height() * zoom); + CPoint moved; + + moved.X(newCenter.X() * zoomed.Width() / (double)rect.Width()); + moved.Y(newCenter.Y() * zoomed.Height() / (double)rect.Height()); + + MSG_LOW("Center XY(%d,%d)", center.X() , center.Y()); + MSG_LOW("Moved XY(%d,%d)", moved.X() , moved.Y()); + + CPoint dMove = moved - newCenter; + + MSG_LOW("New Moved XY(%d,%d)", dMove.X() , dMove.Y()); + + MSG_LOW("New Geo XYWH(%d,%d,%d,%d)", rect.Left() - dMove.X(), rect.Top() - dMove.Y(), zoomed.Width(), zoomed.Height()); + + m_client->Move(rect.Left() - dMove.X(), rect.Top() - dMove.Y()); + m_client->Zoom(zoom); + } + + UpdateClient(); +} + + +static void _on_event_mouse_down(void *data, Evas *evas, Evas_Object *obj, void *event_info) +{ + MSG_HIGH("Event layer clicked : %s Layer=%d", evas_object_name_get(obj), evas_object_layer_get(obj)); +} + +void CScroller::move(int x, int y) +{ + MSG_MED("[%s] Move Scroller to XY(%d,%d)", m_name.c_str(), x, y); + + m_origin.MoveTo(x,y); // Origin + + if ( m_calcjob ) + { + ecore_job_del(m_calcjob); + m_calcjob = NULL; + } + + m_calcjob = ecore_job_add(_CalcJob, this); +} + +void CScroller::resize(int w, int h) +{ + if ( m_extent.Width() == w && m_extent.Height() == h) return; + + MSG_HIGH("[%s] Resize Scroller to WH(%d,%d)", m_name.c_str(), w, h); + + m_extent.SetSize(w,h); + m_resized = true; + + if ( m_calcjob ) + { + ecore_job_del(m_calcjob); + m_calcjob = NULL; + } + + m_calcjob = ecore_job_add(_CalcJob, this); + + +} + +void CScroller::show() +{ + MSG_HIGH("[%s] Scroller show", m_name.c_str()); + + evas_object_show(m_edje); + evas_object_show(m_event); + + if ( m_client ) + evas_object_show(m_client->GetObject()); + +} + +void CScroller::hide() +{ + MSG_HIGH("[%s] Scroller hide", m_name.c_str()); + + if ( m_client ) + evas_object_hide(m_client->GetObject()); + + evas_object_hide(m_edje); + evas_object_hide(m_event); +} + +void CScroller::draw() +{ + if ( m_client == NULL ) + { + MSG_HIGH("[%s] Client NULL", m_name.c_str()); + return; + } + + if ( m_extent.Width() == 0 || m_extent.Height() == 0) + { + MSG_HIGH("Extent is abnormal"); + return; + } + + UpdateClient(); + +// EFL::dump_obj(GetObject(), 0); +} + +void CScroller::UpdateClient() +{ + const CRect &sRect = m_client->GetClientRect(); +// ScreenToClient(sRect); + MSG_MED("[%s] Draw. Origin(%d,%d) XYWH(%d,%d,%d,%d)", m_name.c_str(), m_origin.X(), m_origin.Y(), sRect.Left(), sRect.Top(), sRect.Width(), sRect.Height() ); + + m_client->SetOrigin(m_origin.X(), m_origin.Y()); + m_client->Draw(); + +} + + +CRect CScroller::GetAutoFitGeometry() +{ + CSize img = m_client->GetClientSize(); + + MSG_LOW("Client size : WH(%d,%d", m_extent.Width(), m_extent.Height()); + MSG_LOW("Image size : WH(%d,%d)", img.Width(), img.Height()); + + int ph, pw; + + ph = (img.Height() * m_extent.Width()) / img.Width(); + + if (ph > m_extent.Height()) + { + pw = (img.Width() * m_extent.Height()) / img.Height(); + ph = m_extent.Height(); + } + else + { + pw = m_extent.Width(); + } + +// Calculate XY + int px, py; + + px = (m_extent.Width() - pw ) / 2; + py = (m_extent.Height() - ph ) / 2; + + CRect rect(px, py, pw, ph); + + return rect; +} + +double CScroller::GetAutoFitZoom() +{ + double zoom; + + CSize img = m_client->GetClientSize(); + + MSG_LOW("Client size : WH(%d,%d)", m_extent.Width(), m_extent.Height()); + MSG_LOW("Image size : WH(%d,%d)", img.Width(), img.Height()); + + if ( img.Width() == 0 || img.Height() == 0 ) + { + MSG_ERROR("Invalid img. ImgWH(%d,%d)", img.Width(), img.Height()); + return 0.0f; + } + + int ph, pw; + + ph = (img.Height() * m_extent.Width()) / img.Width(); + + if (ph > m_extent.Height()) + { + pw = (img.Width() * m_extent.Height()) / img.Height(); + ph = m_extent.Height(); + } + else + { + pw = m_extent.Width(); + } + + if ( img.Width() > img.Height()) + { + zoom = (double)pw / img.Width(); + } + else + { + zoom = (double)ph / img.Height(); + } + + return zoom; +} + +void CScroller::DoAutoFit() +{ + if ( m_client == NULL ) + { + MSG_LOW("Client is NULL. DoAutoFit()"); + return; + } + + if ( m_extent.Width() <= 1 || m_extent.Height() <= 1 ) // Damm EFL!!! object resized to (1,115) first and then enlarge up to screen size. + { + MSG_ERROR("Rect is not configured (%d,%d)", m_extent.Width(), m_extent.Height()); + return ; + } + + if ( m_rect_autofit.Width() == 0 || m_rect_autofit.Height() == 0 ) + { + MSG_ERROR("Rect is not configured"); + return ; + } + +// Stop animation + m_ani_zoom->Stop(); + if ( m_ani ) delete m_ani; + m_ani = NULL; + + m_client->Move(m_rect_autofit.Left(), m_rect_autofit.Top()); + m_client->Zoom(m_zoom_autofit); + + MSG_HIGH("[%s] DoAutofit : XY(%d,%d,%d,%d) Zoom=%f", m_name.c_str(), m_rect_autofit.Left(), m_rect_autofit.Top(), m_rect_autofit.Width(), m_rect_autofit.Height(), m_zoom_autofit); + MSG_LOW("[%s] Origin XY(%d,%d)", m_name.c_str(), m_origin.X(), m_origin.Y()); + + UpdateClient(); + + m_client->EndUpdate(); +} + +Evas_Object *CScroller::CreateObject(Evas_Object *parent) +{ + CObject::CreateObject(parent); + evas_object_name_set(GetObject(), "Scroller"); + + m_edje = edje_object_add(evas_object_evas_get(GetObject())); + if (!m_edje) + { + MSG_ERROR("could not create edje object!"); + return false; + } + + if (!edje_object_file_set(m_edje, EDJ_PATH"/ivug-scroller.edj", "scroller")) + { + Edje_Load_Error err = edje_object_load_error_get(m_edje); + const char *errmsg = edje_load_error_str(err); + MSG_ERROR("could not load 'ivug-scroller' from %s: %s",EDJ_PATH"ivug-scroller.edj", errmsg); + + evas_object_del(m_edje); + return false; + } + + evas_object_name_set(m_edje, "Scroller:Edje"); + evas_object_event_callback_add( m_edje, EVAS_CALLBACK_MOUSE_DOWN, _on_event_mouse_down, NULL); + + evas_object_smart_member_add(m_edje, GetObject()); + +// Get Event rect + m_event = EFL::create_rect(m_edje); + evas_object_name_set(m_event, "Scroller:Event"); + + evas_object_pass_events_set(m_event, EINA_TRUE); + + if ( m_event == NULL ) + { + MSG_ERROR("Cannot found event rect"); + evas_object_del(m_edje); + return false; + } + evas_object_event_callback_add(m_event, EVAS_CALLBACK_MOUSE_DOWN, _on_event_mouse_down, NULL); + + evas_object_smart_member_add(m_event, GetObject()); + + m_gesture = EFL::create_gesture(m_event); + elm_gesture_layer_hold_events_set(m_gesture, EINA_TRUE); + + elm_gesture_layer_cb_set(m_gesture, ELM_GESTURE_ZOOM, ELM_GESTURE_STATE_START, _zoom_start, this); + elm_gesture_layer_cb_set(m_gesture, ELM_GESTURE_ZOOM, ELM_GESTURE_STATE_MOVE, _zoom_move, this); + elm_gesture_layer_cb_set(m_gesture, ELM_GESTURE_ZOOM, ELM_GESTURE_STATE_END, _zoom_end, this); + elm_gesture_layer_cb_set(m_gesture, ELM_GESTURE_ZOOM, ELM_GESTURE_STATE_ABORT, _zoom_abort, this); + elm_gesture_layer_cb_set(m_gesture, ELM_GESTURE_MOMENTUM, ELM_GESTURE_STATE_START, _momentum_start, this); + elm_gesture_layer_cb_set(m_gesture, ELM_GESTURE_MOMENTUM, ELM_GESTURE_STATE_MOVE, _momentum_move, this); + elm_gesture_layer_cb_set(m_gesture, ELM_GESTURE_MOMENTUM, ELM_GESTURE_STATE_END, _momentum_end, this); + elm_gesture_layer_cb_set(m_gesture, ELM_GESTURE_MOMENTUM, ELM_GESTURE_STATE_ABORT, _momentum_abort, this); + + elm_gesture_layer_cb_set(m_gesture, ELM_GESTURE_N_DOUBLE_TAPS, ELM_GESTURE_STATE_START, _dbl_click_start, this); + elm_gesture_layer_cb_set(m_gesture, ELM_GESTURE_N_DOUBLE_TAPS, ELM_GESTURE_STATE_END, _dbl_click_end, this); + elm_gesture_layer_cb_set(m_gesture, ELM_GESTURE_N_DOUBLE_TAPS, ELM_GESTURE_STATE_ABORT, _dbl_click_abort, this); + + if ( elm_gesture_layer_attach(m_gesture, m_event) == EINA_FALSE) + { + MSG_ERROR("Cannot attach event rect"); + evas_object_del(m_edje); + return false; + } + + evas_object_name_set(m_gesture, "Scroller:Getsture"); + + evas_object_event_callback_add( m_gesture, EVAS_CALLBACK_MOUSE_DOWN, _on_event_mouse_down, NULL); + +// Do not add m_gesture as smart member. this makes event broken!. +// evas_object_smart_member_add(m_gesture, GetObject()); +#ifdef ENABLE_CLIPPER + m_clipper = EFL::create_clipper(m_edje); + evas_object_name_set(m_clipper, "Scroller:Clipper"); + evas_object_event_callback_add( m_clipper, EVAS_CALLBACK_MOUSE_DOWN, _on_event_mouse_down, NULL); + + evas_object_smart_member_add(m_clipper, GetObject()); +#endif + + evas_object_repeat_events_set(GetObject(), EINA_FALSE); + + MSG_HIGH("Scroller is created."); + + return GetObject(); +} + +void CScroller::CalcJob() +{ + MSG_MED("[%s] Draw job!!! (%d,%d,%d,%d)", m_name.c_str(), m_origin.X(), m_origin.Y(), m_extent.Width(), m_extent.Height()); + + m_calcjob = NULL; + + evas_object_move(m_edje, m_origin.X(), m_origin.Y()); + evas_object_move(m_event, m_origin.X(), m_origin.Y()); + +#ifdef ENABLE_CLIPPER + evas_object_move(m_clipper, m_origin.X(), m_origin.Y()); +#endif + + if ( m_client) + { + m_client->SetOrigin(m_origin.X(), m_origin.Y()); + } + + evas_object_resize(m_edje, m_extent.Width(), m_extent.Height()); + evas_object_resize(m_event, m_extent.Width(), m_extent.Height()); + +#ifdef ENABLE_CLIPPER + evas_object_resize(m_clipper, m_extent.Width(), m_extent.Height()); +#endif + + if ( m_resized == true && m_client ) + { + m_zoom_autofit = GetAutoFitZoom(); + m_rect_autofit = GetAutoFitGeometry(); + + DoAutoFit(); + + m_resized = false; + } + + evas_object_smart_changed(GetObject()); + +} + +void CScroller::del() +{ + if ( m_edje ) + { + evas_object_del(m_edje); + } + m_edje = NULL; + + if ( m_event ) + { + evas_object_del(m_event); + } + m_event = NULL; + + if ( m_gesture ) + { + evas_object_del(m_gesture); + } + m_gesture = NULL; + +#ifdef ENABLE_CLIPPER + if ( m_clipper ) + { + evas_object_del(m_clipper); + } + m_clipper = NULL; +#endif + + +} + +void CScroller::DoAnim() +{ + // Get current rect; + CRect sRect = m_client->GetClientRect(); + ScreenToClient(sRect); + + const CSize &img = m_client->GetClientSize(); + + int ph, pw; + + ph = (img.Height() * m_extent.Width()) / img.Width(); + + if (ph > m_extent.Height()) + { + pw = (img.Width() * m_extent.Height()) / img.Height(); + ph = m_extent.Height(); + } + else + { + pw = m_extent.Width(); + } + + CRect dRect = sRect; // Destination rect in local coord + + double zoom = m_client->Zoom(); + + if ( img.Width() > img.Height()) + { + if ( sRect.Width() < pw ) + { + MSG_HIGH("Need resize W"); + zoom = (double)pw / img.Width(); + dRect.Width(pw); + dRect.Height(ph); + } + } + else + { + if ( sRect.Height() < ph ) + { + MSG_HIGH("Need resize H"); + zoom = (double)ph / img.Height(); + dRect.Width(pw); + dRect.Height(ph); + } + } + +// Go Center + if ( dRect.Width() < m_extent.Width() ) + { + // Center align + dRect.Left( (m_extent.Width() - dRect.Width()) / 2); + + MSG_HIGH("H align %d, %d", dRect.Width(), m_extent.Width()); + } + else + { + if ( dRect.Right() < m_extent.Width() ) // If reach to edge + { + dRect.Right(m_extent.Width()); + } + + if ( dRect.Left() > 0 ) // If reach to edge + { + dRect.Left(0); + } + } + + if ( dRect.Height() < m_extent.Height() ) + { + dRect.Top( (m_extent.Height() - dRect.Height()) / 2); + + MSG_HIGH("V align %d, %d", dRect.Height(), m_extent.Height()); + } + else + { + if ( dRect.Bottom() < m_extent.Height() ) + { + dRect.Bottom(m_extent.Height()); + } + + if ( dRect.Top() > 0 ) // If reach edge + { + dRect.Top(0); + } + } + + m_ani_zoom->Stop(); + m_client->EndUpdate(); + + if ( m_ani ) delete m_ani; + m_ani = new CGroupAnimator(); + + if ( zoom != m_client->Zoom() ) // smaller than screen + { + m_ani->AddAnimator(new CSingleAnimator(m_client->Zoom(), zoom, 0.3f, CTranstionFunc::LinearTransit, CScroller::_on_ani_zoom, this)); + } + + double t1 = 0.3f; + + if ( sRect.Left() != dRect.Left() ) + { + m_ani->AddAnimator(new CSingleAnimator(sRect.Left(), dRect.Left(), t1 , CTranstionFunc::LinearTransit, CScroller::_on_ani_panX, this)); + } + + double t2 = 0.3f; + + if ( dRect.Top() != sRect.Top() ) + { + m_ani->AddAnimator(new CSingleAnimator(sRect.Top(), dRect.Top() , t2, CTranstionFunc::LinearTransit, CScroller::_on_ani_panY, this)); + } + + m_client->BeginUpdate(); + m_ani_zoom->Start(CScroller::_on_anim, (void *)this); + + MSG_HIGH("Momentum end Animation started. Ani1=(%d~%d,%f) Ani2=(%d~%d,%f)", sRect.Left(), dRect.Left(), t1, sRect.Top(), dRect.Top(), t2); + + + +} + + +bool CScroller::OnAnimation(double delta) { + if ( m_ani->IsFinished() ) + { + MSG_HIGH("animation ended"); + m_client->EndUpdate(); + m_freeze = false; + + evas_object_smart_callback_call(GetObject(), "scroll,animate,end", NULL); + return false; + } + + MSG_LOW("On Animaion. %f ", delta); + + m_ani->Update(delta); + + UpdateClient(); + + evas_object_smart_callback_call(GetObject(), "scroll,animate", NULL); + + return true; +} + +bool CScroller::OnAnimationZoom(double value) { + MSG_LOW("OnAnimationZoom. %f", value); + + m_client->Zoom(value); + + return true; +} + +bool CScroller::OnAnimationPanX(double value) { + MSG_LOW("OnAnimationPanX. %f", value); + + m_client->PanX(value); + + return true; +} + +bool CScroller::OnAnimationPanY(double value) { + MSG_LOW("OnAnimationPanY. %f", value); + + m_client->PanY(value); + + return true; +} + +void CScroller::zoom_start(const CPoint ¢er, double zoom) +{ + m_nFinger = 2; + + MSG_HIGH("Zoom started. Current=%f Finger=%d", m_client->Zoom(), m_nFinger); + m_prev = center; + + m_zoom = m_client->Zoom(); + m_prevzoom = zoom; +} + +void CScroller::zoom_move(const CPoint ¢er, double zoom) +{ + if ( m_freeze == true) { + MSG_LOW("MFreeze is true"); + return; + } + + CPoint dmove = center - m_prev; + + MSG_MED("Zoom move center(%d,%d) zoom=%f Move(%d,%d)", center, zoom, dmove.X(), dmove.Y()); + + m_client->MoveBy(dmove.X(), dmove.Y()); + m_prev = center; + m_prevzoom = zoom; + + double fzoom = m_zoom * zoom; + + CSize zoomed = m_client->GetClientSize(); + CRect rect = m_client->GetClientRect(); + + MSG_MED("1. Rect (%d,%d,%d,%d)", rect.Left(), rect.Right(), rect.Width(), rect.Height() ); + + double limit_zoom = _calc_limit_zoom(zoomed.Width(), zoomed.Height(), + rect.Width(), rect.Height(), m_extent.Width(), m_extent.Height()); + + if(limit_zoom != 1.0) // Zoom level is allowed. + { + if(limit_zoom < 1.0) /* ZOOM_MIN_LIMITED */ + { + MSG_MED("ZOOM_MIN_LIMITED"); + if(m_prevfzoom > fzoom) + { + UpdateClient(); + return; + } + } + else /* ZOOM_MAX_LIMITED */ + { + MSG_MED("ZOOM_MAX_LIMITED"); + if(m_prevfzoom < fzoom) + { + UpdateClient(); + return; + } + } + } + + Zoom(center, fzoom); + + m_prevfzoom = fzoom; +} + +void CScroller::zoom_end(const CPoint ¢er, double zoom) +{ + m_nFinger = 0; + + MSG_HIGH("Zoom ended %d", m_nFinger); + + if ( m_freeze == true) return; + + m_zoom = 0.0f; + + DoAnim(); + m_freeze = true; + + MSG_HIGH("Zoom ended. Animation started."); +} + +void CScroller::zoom_abort(const CPoint ¢er, double zoom) +{ + m_nFinger = 0; + + MSG_HIGH("Zoom aborted %d", m_nFinger); + + if ( m_freeze == true) return; + + m_zoom = 0.0f; + + DoAnim(); + m_freeze = true; + + MSG_HIGH("Zoom ended. Animation started."); + +} + + +void CScroller::momentum_start(const CPoint &from, const CPoint &to, const CSize &momentum) +{ + m_nFinger = 1; + + MSG_MED("MStart : From XY(%d,%d) To XY(%d,%d) %d", from.X(), from.Y(), to.X(), to.Y(), m_nFinger); + + m_prev = from; + + if ( m_freeze == true) return; + + if ( m_client->Zoom() >= m_zoom_autofit) // If zoom anim is progressing + { + m_ani_zoom->Stop(); + m_client->EndUpdate(); + + if ( m_ani ) delete m_ani; + m_ani = NULL; + } +} + +void CScroller::momentum_move(const CPoint &from, const CPoint &to, const CSize &momentum) +{ + if ( m_freeze == true) return; + + CPoint dmove = to - m_prev; + + MSG_MED("MMove : From XY(%d,%d) To XY(%d,%d). DMove(%d,%d)", from.X(), from.Y(), to.X(), to.Y(), dmove.X(), dmove.Y()); + +// Able to scroll? + CRect sRect = m_client->GetClientRect(); + ScreenToClient(sRect); + + if ( dmove.X() ) + { + if ( sRect.Width() <= m_extent.Width() ) + { + MSG_MED("Case 0 SRect(%d) MSize(%d)", sRect.Width() , m_extent.Width() ); + dmove.X(0); + } + else + { + if ( dmove.X() < 0 && sRect.Right() + dmove.X() <= m_extent.Width() ) // Mouse <----- + { + MSG_MED("Case1. dmove.X()=%d Right=%d", dmove.X(), sRect.Right()); + dmove.X(m_extent.Width() - sRect.Right()); + } + else if ( dmove.X() > 0 && sRect.Left() + dmove.X() >= 0 ) + { + MSG_MED("Case2. dmove.X()=%d Left=%d MSizeLeft=%d", dmove.X(), sRect.Left(), 0); + dmove.X(0 - sRect.Left()); + } + } + } + + if ( dmove.Y() ) + { + if ( sRect.Height() <= m_extent.Height() ) + { + MSG_MED("Case 3 SRect(%d) MSize(%d)", sRect.Height() , m_extent.Height() ); + dmove.Y(0); + } + else + { + if ( dmove.Y() < 0 && sRect.Bottom() + dmove.Y() <= m_extent.Height() ) + { + MSG_MED("Case4. dmove.X()=%d Right=%d", dmove.Y(), sRect.Bottom()); + dmove.Y(m_extent.Height() - sRect.Bottom()); + } + else if ( dmove.Y() > 0 && sRect.Top() + dmove.Y() >= 0 ) + { + MSG_MED("Case5. dmove.X()=%d Left=%d MSizeLeft=%d", dmove.X(), sRect.Top(), 0); + dmove.Y(0 - sRect.Top()); + } + } + } + + m_client->MoveBy(dmove.X(), dmove.Y()); + + UpdateClient(); + + m_prev = to; +} + +void CScroller::momentum_end(const CPoint &from, const CPoint &to, const CSize &momentum) +{ + m_nFinger = 0; + + MSG_HIGH("MEnd : From XY(%d,%d) To XY(%d,%d) Momentum=(%d,%d) %d", from.X(), from.Y(), to.X(), to.Y(), momentum.Width(), momentum.Height(), m_nFinger); + + if ( m_freeze == true) return; + + CSize nor_momentum = momentum; + + CRect sRect = m_client->GetClientRect(); + ScreenToClient(sRect); + + CRect dRect = sRect; + + MSG_HIGH("MoveTo %d,%d,%d,%d", dRect.Left(), dRect.Top(), dRect.Right(), dRect.Bottom()); + + double zoom = m_zoom_autofit; + + if ( zoom > m_client->Zoom() ) + { + DoAnim(); + + MSG_HIGH("Momentum end. Zoom Anim. %f->%f", m_client->Zoom(), zoom ); + return ; + } + + if ( dRect.Width() > m_extent.Width() ) + { + dRect.Left(sRect.Left() + nor_momentum.Width() ); + if ( nor_momentum.Width() < 0 ) // Finger <<------ + { + if ( dRect.Right() < m_extent.Width() ) // If reach to edge + { + dRect.Right(m_extent.Width()); + MSG_LOW("Case 1a %d,%d dstX(%d)", dRect.Right() , m_extent.Width(), dRect.Left()); + } + else + { + MSG_LOW("Case 2a %d dstX(%d)", dRect.Right() , m_extent.Width(), dRect.Left()); + } + } + else if ( nor_momentum.Width() > 0 ) // Finger ----->>> + { + if ( dRect.Left() > 0 ) // If reach to edge + { + dRect.Left(0); + MSG_LOW("Case 3a %d,%d dstX(%d)", dRect.Left() , 0, dRect.Left()); + } + else + { + MSG_LOW("Case 4a %d dstX(%d)", dRect.Left() , 0, dRect.Left()); + } + } + } + else + { + dRect.Left( (m_extent.Width() - dRect.Width()) / 2); + } + + MSG_HIGH("X Anim from %d to %d", sRect.Left(), dRect.Left()); + + if ( dRect.Height() > m_extent.Height() ) + { + dRect.Top(sRect.Top() + nor_momentum.Height() ); + if ( nor_momentum.Height() < 0 ) // finger ^ + { + if ( dRect.Bottom() < m_extent.Height() ) // If reach to edge + { + dRect.Bottom( m_extent.Height()); + MSG_LOW("Case 1b %d,%d dstX(%d)", dRect.Bottom() , m_extent.Height(), sRect.Top()); + } + else + { + MSG_LOW("Case 2b %d dstX(%d) %d", dRect.Bottom() , m_extent.Height(), sRect.Top()); + } + + } + else if ( nor_momentum.Height() > 0 ) // Finger goes downward + { + if ( dRect.Top() > 0 ) // If reach edge + { + dRect.Top(0); + MSG_LOW("Case 3b %d,%d dstX(%d)", dRect.Top() , 0, sRect.Top()); + } + else + { + MSG_LOW("Case 4d %d dstX(%d) %d", dRect.Top() , 0, sRect.Top()); + } + } + } + else + { + // Center align + dRect.Top((m_extent.Height() - dRect.Height()) / 2); + } + + MSG_HIGH("Y Anim from %d to %d", sRect.Top(), dRect.Top()); + + m_ani_zoom->Stop(); + m_client->EndUpdate(); + + if ( m_ani ) delete m_ani; + m_ani = new CGroupAnimator(); + + double t1 = (dRect.Left() - sRect.Left()) / (double)momentum.Width(); + + if ( sRect.Left() != dRect.Left() ) + { + m_ani->AddAnimator(new CSingleAnimator(sRect.Left(), dRect.Left(), t1 , CTranstionFunc::LinearTransit, CScroller::_on_ani_panX, this)); + } + + double t2 = (dRect.Top() - sRect.Top()) / (double)momentum.Height(); + + if ( dRect.Top() != sRect.Top() ) + { + m_ani->AddAnimator(new CSingleAnimator(sRect.Top(), dRect.Top() , t2, CTranstionFunc::LinearTransit, CScroller::_on_ani_panY, this)); + } + + m_client->BeginUpdate(); + m_ani_zoom->Start(CScroller::_on_anim, (void *)this); + + MSG_HIGH("Momentum end Animation started. Ani1=(%d~%d,%f) Ani2=(%d~%d,%f)", sRect.Left(), dRect.Left(), t1, sRect.Top(), dRect.Top(), t2); + MSG_HIGH("Momentum WH(%d,%d)", momentum.Width(), momentum.Height()); +} + + +void CScroller::momentum_abort(const CPoint &from, const CPoint &to, const CSize &momentum) +{ + m_nFinger = 0; + + MSG_HIGH("momentum Aborted %d", m_nFinger); +} + +void CScroller::double_click(const CPoint ¢er) +{ + m_ani_zoom->Stop(); + m_client->EndUpdate(); + + double src = m_client->Zoom(); + double dst; + + CRect sRect = m_client->GetClientRect(); + ScreenToClient(sRect); + + CRect dRect; + + if ( m_extent.Width() < sRect.Width()) + { + // To autofit + dst = m_zoom_autofit; + dRect = m_rect_autofit; + MSG_HIGH("AAAAAAA %d, %d", m_extent.Width(), sRect.Width()); + } + else + { + dst = m_client->Zoom() * 4.0f; + + { + CPoint topleft; + CPoint newCenter; + + topleft = m_client->GetClientRect().TopLeft(); + newCenter = center - topleft; // Get Image local coordinate center. + + CSize zoomed = m_client->GetClientSize(); + CRect rect = m_client->GetClientRect(); + ScreenToClient(rect); + + zoomed = zoomed * dst; + + MSG_LOW("Current Geo XYWH(%d,%d,%d,%d)", rect.Left(), rect.Top(), rect.Width(), rect.Height()); + MSG_LOW("Origianl size WH(%d,%d)", m_extent.Width(), m_extent.Height()); + MSG_LOW("Zoomed size WH(%d,%d) Zoom=%f", zoomed.Width() , zoomed.Height(), dst); + + MSG_LOW("%f %f", m_extent.Width() * dst, m_extent.Height() * dst); + CPoint moved; + + moved.X(newCenter.X() * zoomed.Width() / (double)rect.Width()); + moved.Y(newCenter.Y() * zoomed.Height() / (double)rect.Height()); + + MSG_LOW("Center XY(%d,%d)", center.X() , center.Y()); + MSG_LOW("Moved XY(%d,%d)", moved.X() , moved.Y()); + + CPoint dMove = moved - newCenter; + + MSG_LOW("New Moved XY(%d,%d)", dMove.X() , dMove.Y()); + + MSG_LOW("New Geo XYWH(%d,%d,%d,%d)", rect.Left() - dMove.X(), rect.Top() - dMove.Y(), zoomed.Width(), zoomed.Height()); + + dRect.MoveBy(-dMove.X(), -dMove.Y()); + dRect.Width(zoomed.Width()); + dRect.Height(zoomed.Height()); + } + + MSG_LOW("DRect(%d,%d,%d,%d) ViewPort(%d,%d)", dRect.Left(), dRect.Top(), dRect.Width(), dRect.Height(), m_extent.Width(), m_extent.Height()); + + if ( dRect.Width() < m_extent.Width() ) + { + // Center align + dRect.Left( (m_extent.Width() - dRect.Width()) / 2); + + MSG_HIGH("H align %d, %d", dRect.Width(), m_extent.Width()); + } + else + { + if ( dRect.Right() < m_extent.Width() ) // If reach to edge + { + dRect.Right(m_extent.Width()); + } + + if ( dRect.Left() > 0 ) // If reach to edge + { + dRect.Left(0); + } + } + + if ( dRect.Height() < m_extent.Height() ) + { + dRect.Top( (m_extent.Height() - dRect.Height()) / 2); + + MSG_HIGH("V align %d, %d", dRect.Height(), m_extent.Height()); + } + else + { + if ( dRect.Bottom() < m_extent.Height() ) + { + dRect.Bottom(m_extent.Height()); + } + + if ( dRect.Top() > 0 ) // If reach edge + { + dRect.Top(0); + } + } + + m_freeze = false; + } + + if ( m_ani ) delete m_ani; + m_ani = new CGroupAnimator(); + + double duration = abs(sRect.Width() - dRect.Width()) / 10000.0f; + + m_ani->AddAnimator(new CSingleAnimator(src, dst, duration, CTranstionFunc::LinearTransit, CScroller::_on_ani_zoom, this)); + m_ani->AddAnimator(new CSingleAnimator(sRect.Left() , dRect.Left(), duration, CTranstionFunc::LinearTransit, CScroller::_on_ani_panX, this)); + m_ani->AddAnimator(new CSingleAnimator(sRect.Top() , dRect.Top(), duration, CTranstionFunc::LinearTransit, CScroller::_on_ani_panY, this)); + + m_client->BeginUpdate(); + m_ani_zoom->Start(CScroller::_on_anim, (void *)this); + + MSG_HIGH("Double click animation started. Ani1=(%d~%d,%f) Ani2=(%d~%d,%f) Ani3(%f~%f,%f))", sRect.Left(), dRect.Left(), duration, sRect.Top(), dRect.Top(), duration, src, dst, duration); + +}; + + diff --git a/widget/src/common/Scroller.h b/widget/src/common/Scroller.h new file mode 100755 index 0000000..99f35b2 --- /dev/null +++ b/widget/src/common/Scroller.h @@ -0,0 +1,197 @@ +/* + * Copyright 2012 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.tizenopensource.org/license + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include + +#include "ivug-debug.h" + +#include "Primitives.h" +#include "Object.h" + +#include + +using namespace std; + +class ECoreAnimator; +class CAnimator; +class CScrollerClient; + +class CScroller : public CObject { + + static void _CalcJob(void *data) { + CScroller *thiz = static_cast(data); + + thiz->CalcJob(); + + }; +public: + +// Public APIs + + CScroller(const char *name); + ~CScroller(); + + Evas_Object *CreateObject(Evas_Object *parent); + + bool SetClient(CScrollerClient *client); + + bool UnsetClient(); + + void Zoom(const CPoint ¢er, double zoom); + + void DisableEvent(); + + void EnableEvent(); + + void Draw() { + MSG_HIGH("Scroller draw"); + }; + + void ScreenToClient(CRect &rect) { + rect.MoveBy(-m_origin.X(), -m_origin.Y()); + }; + + void OnChanged(CScrollerClient *client); + +private: + static Evas_Event_Flags _momentum_end(void *data, void *event_info); + static Evas_Event_Flags _momentum_move(void *data, void *event_info); + static Evas_Event_Flags _momentum_start(void *data, void *event_info); + static Evas_Event_Flags _momentum_abort(void *data, void *event_info); + + static Evas_Event_Flags _zoom_end(void *data, void *event_info); + static Evas_Event_Flags _zoom_move(void *data, void *event_info); + static Evas_Event_Flags _zoom_start(void *data, void *event_info); + static Evas_Event_Flags _zoom_abort(void *data, void *event_info); + + static Evas_Event_Flags _dbl_click_start(void *data , void *event_info); + static Evas_Event_Flags _dbl_click_end(void *data , void *event_info); + static Evas_Event_Flags _dbl_click_abort(void *data , void *event_info); + + static bool _on_anim(double value, void *pData) { + CScroller *thiz = static_cast(pData); + + return thiz->OnAnimation(value); + }; + + static void _on_ani_zoom(double value, void *pData) { + CScroller *thiz = static_cast(pData); + + thiz->OnAnimationZoom(value); + }; + + static void _on_ani_panX(double value, void *pData) { + CScroller *thiz = static_cast(pData); + + thiz->OnAnimationPanX(value); + }; + + + static void _on_ani_panY(double value, void *pData) { + CScroller *thiz = static_cast(pData); + + thiz->OnAnimationPanY(value); + }; + + void CalcJob(); + + bool OnAnimationZoom(double value); + bool OnAnimationPanX(double value); + bool OnAnimationPanY(double value); + + bool OnAnimation(double value); + + void move(int x, int y); + void resize(int w, int h); + void show(); + void hide(); + void draw(); + void del(); + + CRect GetAutoFitGeometry(); + double GetAutoFitZoom(); + +// Mouse events + void zoom_start(const CPoint ¢er, double zoom); + void zoom_move(const CPoint ¢er, double zoom); + void zoom_end(const CPoint ¢er, double zoom); + void zoom_abort(const CPoint ¢er, double zoom); + + void momentum_start(const CPoint &from, const CPoint &to, const CSize &momentum); + void momentum_move(const CPoint &from, const CPoint &to, const CSize &momentum); + void momentum_end(const CPoint &from, const CPoint &to, const CSize &momentum); + void momentum_abort(const CPoint &from, const CPoint &to, const CSize &momentum); + + void double_click(const CPoint ¢er); + + bool NeedResize(); + + void UpdateClient(); + +public: + void DoAutoFit(); + void DoAnim(); + + void Test1() { + Zoom(CPoint(360,540), 3.6f); + }; + + +private: + Evas_Object *m_edje; + + Evas_Object *m_clipper; + + Evas_Object *m_gesture; // Gesture detect + Evas_Object *m_event; + +// Client related + CScrollerClient *m_client; + string m_name; + +private: + CPoint m_origin; // LCD coordinate. + CSize m_extent; + +private: // Mouse related + double m_zoom; + CPoint m_prev; // Previous point for mouse move + double m_prevzoom; + int m_nFinger; // Count of touched finger; + double m_prevfzoom; + +// Animation class +private: + CAnimator *m_ani; + + ECoreAnimator *m_ani_zoom; + ECoreAnimator *m_ani_accel; + +private: + double m_zoom_autofit; + CRect m_rect_autofit; + +// Status +private: + bool m_freeze; + bool m_resized; + + Ecore_Job *m_calcjob; + +}; + diff --git a/widget/src/image/ivug-image-photocam.cpp b/widget/src/image/ivug-image-photocam.cpp new file mode 100755 index 0000000..f2331c0 --- /dev/null +++ b/widget/src/image/ivug-image-photocam.cpp @@ -0,0 +1,487 @@ +/* + * Copyright 2012 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.tizenopensource.org/license + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "ivug-image.h" +#include "Scroller.h" +#include "errno.h" + +#include "debug.h" + + +static Evas_Object *_crop_image(const char *file, int /* image coord */crop_x, int crop_y, int crop_w, int crop_h, int final_w, int final_h) +{ +// TODO : Should implement no-region image cropping (bmp or gif ) + MSG_HIGH("Crop image XYWH(%d,%d,%d,%d) Dimension(%d,%d)", crop_x, crop_y, crop_w, crop_h, final_w, final_h); + +// 1. Load source image into buffer canvas. + Ecore_Evas *m_ee; + m_ee = ecore_evas_buffer_new(final_w, final_h); + MSG_ASSERT(m_ee != NULL); + + Evas *evas = ecore_evas_get(m_ee); + + Evas_Object *img; + + img = evas_object_image_filled_add(evas); + + evas_object_image_file_set(img, file, NULL); + + Evas_Load_Error err = evas_object_image_load_error_get(img); + if (err != EVAS_LOAD_ERROR_NONE) + { + MSG_ERROR("could not load image '%s'. error string is \"%s\"", file, evas_load_error_str(err)); + return NULL; + } + + Eina_Bool bRegion = evas_object_image_region_support_get(img); + + evas_object_image_file_set(img, NULL, NULL); + + if ( bRegion == EINA_TRUE) + { + MSG_HIGH("Region supported"); + evas_object_image_load_orientation_set(img, EINA_TRUE); + evas_object_image_load_region_set(img, crop_x, crop_y, crop_w, crop_h); + + evas_object_image_file_set(img, file, NULL); + + Evas_Load_Error err = evas_object_image_load_error_get(img); + if (err != EVAS_LOAD_ERROR_NONE) + { + MSG_ERROR("could not load image '%s'. error string is \"%s\"", file, evas_load_error_str(err)); + return NULL; + } + } + else + { + MSG_HIGH("Region not supported."); + +// Load full image + Evas_Object *src; + + src = evas_object_image_add(evas); + + evas_object_image_file_set(src, file, NULL); + + Evas_Load_Error err = evas_object_image_load_error_get(src); + if (err != EVAS_LOAD_ERROR_NONE) + { + MSG_ERROR("could not load image '%s'. error string is \"%s\"", file, evas_load_error_str(err)); + return NULL; + } + + int w,h; + evas_object_image_size_get(src, &w, &h); + + MSG_HIGH("Image WH(%d,%d)", w, h); + +// Setup cropped buffer + evas_object_image_size_set(img, crop_w, crop_h); + evas_object_image_fill_set(img, 0, 0, crop_w, crop_h); + +// Copy image from src to img. + int *Src = (int *)evas_object_image_data_get(src, EINA_FALSE); // ImgBuffer's size is same as original image + MSG_ASSERT(Src != NULL); + + int *Dest = (int *)evas_object_image_data_get(img, EINA_TRUE); + MSG_ASSERT(Dest != NULL); + + int *Tmp = Dest; + + int ImgW = w; + int *pRow = Src + (crop_y * ImgW /* stride */ + crop_x) ; // Src begin buffer + + int nRow = crop_h; + int nCol = crop_w; + + MSG_HIGH("Crop(%d,%d,%d,%d) Stride=%d nRow=%d nCol=%d", crop_x, crop_y, crop_w, crop_h, ImgW, nRow, nCol); + + while(nRow--) + { + while(nCol--) + { + // ELM_MSG_HIGH("nRow=%d, nCol=%d, Src=0x%08x Dst=0x%08x", nRow, nCol, pRow , Dest); + *Tmp++ = *pRow++; + } + + nCol = crop_w; + pRow = pRow + (ImgW - crop_w /* stride */ ); + } + evas_object_image_data_set(src, (void *)Src); // Unref + evas_object_del(src); + + evas_object_image_data_set(img, (void *)Dest); + } + + int cw, ch; + + cw = crop_w; + ch = crop_h; + + int ph, pw; + int px, py; + +// Auto fit. why???????. Used when set wallpaper(image size is smaller than LCD) + ph = (ch * final_w) / cw; + + if (ph > final_h) + { + pw = (cw * final_h) / ch; + ph = final_h; + } + else + { + pw = final_w; + } + +// Calculate XY + px = (final_w - pw ) / 2; + py = (final_h - ph ) / 2; + + MSG_HIGH("CenterPut XYWH(%d,%d,%d,%d) in Buf(%d,%d)", px, py, pw, ph, final_w, final_h); + + evas_object_move(img, px, py); + evas_object_resize(img, pw, ph); // set object size which you want to scale + + evas_object_show(img); + +// evas_object_image_save(img, "/opt/ug/data/ug-image-viewer-efl/tt.jpg", NULL, NULL); + +// Copy Buffer canvas data to image object in current evas + const void *data = ecore_evas_buffer_pixels_get(m_ee); + MSG_ASSERT(data != NULL); + + Evas_Object *result; + result = evas_object_image_filled_add(evas); + + evas_object_image_size_set(result, final_w, final_h); + evas_object_image_data_set(result, const_cast(data)); + evas_object_image_data_update_add(result, 0, 0, final_w, final_h); + + MSG_HIGH("Cropped image is created. obj=0x%08x", result); + return result; +}; + + + +// APIs +EAPI Evas_Object *ivug_image_create(Evas_Object *parent) +{ + Evas_Object *obj; + + obj = elm_photocam_add(parent); + + elm_photocam_paused_set(obj, EINA_TRUE); + elm_photocam_zoom_mode_set(obj, ELM_PHOTOCAM_ZOOM_MODE_AUTO_FIT); + + MSG_HIGH("Create photocam object. obj=0x%08x", obj); + return obj; +} + +EAPI Evas_Load_Error ivug_image_file_set(Evas_Object *obj, const char *file, const char *key) +{ + Evas_Load_Error err = EVAS_LOAD_ERROR_NONE; + + err = elm_photocam_file_set(obj, file); + + MSG_HIGH("photocam file set. %s error=%d", file, err); + + if ( err != EVAS_LOAD_ERROR_NONE) + { + MSG_ERROR("Photocam file set error! err=%d", err); + } + + return err; +} + +EAPI Evas_Load_Error ivug_image_mem_set(Evas_Object *obj, const unsigned char *buffer, unsigned int size, const char *key) +{ + MSG_ERROR("%s is not supported", __func__); + + return EVAS_LOAD_ERROR_GENERIC; +} + + +EAPI Evas_Load_Error ivug_image_unset(Evas_Object *obj) +{ + Evas_Load_Error err = EVAS_LOAD_ERROR_NONE; + + MSG_HIGH("photocam file unset. %s", elm_photocam_file_get(obj)); + + err = elm_photocam_file_set(obj, NULL); + return err; +} + +EAPI void ivug_image_zoom_set(Evas_Object *obj, double zoom, Evas_Point *pCenter) +{ + //elm_photocam_paused_set(obj, EINA_FALSE); //stop photocam animation + elm_photocam_zoom_mode_set(obj, ELM_PHOTOCAM_ZOOM_MODE_MANUAL); + elm_photocam_zoom_set(obj, zoom); +} + +EAPI double ivug_image_zoom_get(const Evas_Object *obj) +{ + + return elm_photocam_zoom_get(obj); +} + +EAPI void ivug_image_image_size_get(const Evas_Object *obj, int *w, int *h) +{ +// Return original image size + elm_photocam_image_size_get(obj, w, h); + + MSG_HIGH("Image size XYWH(%d,%d)", *w, *h); + +} + +EAPI void ivug_image_region_get(const Evas_Object *obj, int *x, int *y, int *w, int *h) +{ + Evas_Object *image; + + image = elm_photocam_internal_image_get(obj); + + if ( image == NULL ) + { + if(x) *x = 0; + if(y) *y = 0; + if(w) *w = 0; + if(h) *h = 0; + + return; + } + + evas_object_geometry_get(image, x ,y, w, h); +// elm_photocam_image_region_get(obj, x ,y, w, h); + + MSG_HIGH("Region size XYWH(%d,%d,%d,%d)", *x, *y, *w, *h); +} + +EAPI void ivug_image_decoded_size_get(const Evas_Object *obj, int *w, int *h) +{ + Evas_Object *image = NULL; + + image = elm_photocam_internal_image_get(obj); + + if ( image == NULL ) + { + if(w) *w = 0; + if(h) *h = 0; + + return; + } + + int iw, ih; + + elm_photocam_image_size_get(obj, &iw, &ih); + + int scale = evas_object_image_load_scale_down_get(obj); + + if(w) *w = iw / scale; + if(h) *h = ih / scale; +}; + + +EAPI unsigned char *ivug_image_decoded_buffer_get(const Evas_Object *obj) +{ + Evas_Object *image = NULL; + + image = elm_photocam_internal_image_get(obj); + + if ( image == NULL ) + { + return NULL; + } + + return (unsigned char *)evas_object_image_data_get(image, EINA_FALSE /* Get for reading Only*/ ); +} + +EAPI void ivug_image_hold_set(const Evas_Object *obj, Eina_Bool hold) +{ + MSG_ERROR("%s is not supported", __func__); +} + +EAPI void ivug_image_zoom_reset(Evas_Object *obj, Evas_Point *pCenter) +{ + Eina_Bool bPaused = elm_photocam_paused_get(obj); + + elm_photocam_paused_set(obj, EINA_TRUE); + elm_photocam_zoom_mode_set(obj, ELM_PHOTOCAM_ZOOM_MODE_AUTO_FIT); + elm_photocam_paused_set(obj, bPaused); + +} + +EAPI Evas_Object *ivug_image_region_image_get(Evas_Object *obj, int /* LCD coord */ x, int y, int w, int h ) +{ + MSG_HIGH("Region (%d,%d,%d,%d)", x, y, w, h); + + Evas_Object *image; + + image = elm_photocam_internal_image_get(obj); + + int ix, iy, iw, ih; + + evas_object_geometry_get(image, &ix, &iy, &iw, &ih); + + MSG_HIGH("Image geometry get : (%d,%d,%d,%d)", ix, iy, iw, ih); + + int ow, oh; + evas_object_image_size_get(image, &ow, &oh); + + ow = ow * evas_object_image_load_scale_down_get(image); + oh = oh * evas_object_image_load_scale_down_get(image); + + MSG_HIGH("Original image size(%d,%d)", ow, oh); + + int cx, cy, cw, ch; + +// Get intersect rect between xywh and ixywh + cx = ix; + if ( x > ix ) cx = x; + + cy = iy; + if ( y > iy ) cy = y; + + cw = w; + if ( x + w > ix + iw ) cw = iw; + + ch = h; + if ( y + h > iy + ih ) ch = ih; + + MSG_HIGH("Cropped XWYH(%d,%d,%d,%d)", cx, cy, cw, ch); + +// Get rect on image. + int gx, gy, gw, gh; + + gx = ( cx - ix ) * (double)ow/iw;; + gy = ( cy - iy ) * (double)ow/iw; + + gw = cw * (double)ow/iw; + gh = ch * (double)oh/ih; + + MSG_HIGH("On image rect : (%d,%d,%d,%d) Scale=%d", gx, gy, gw, gh, evas_object_image_load_scale_down_get(image)); + + const char *file = NULL; + const char *key = NULL; + + evas_object_image_file_get(image, &file, &key); + + if ( file == NULL ) + { + MSG_ERROR("File is not loaded"); + return NULL; + } + + MSG_HIGH("File = %s %s", file, key ); + + MSG_HIGH("Image size get : (%d,%d)", ow, oh); + + Evas_Object *result = _crop_image(file, gx, gy, gw, gh, w, h); + + return result; +} + + +EAPI Evas_Object * +ivug_image_internal_image_get(Evas_Object *obj) +{ + return elm_photocam_internal_image_get(obj); +} + + +EAPI void ivug_image_animated_set(const Evas_Object *obj, Eina_Bool bAnimation) +{ + MSG_ERROR("%s is not supported", __func__); +} + +EAPI void ivug_image_rotate_set(Evas_Object *obj, int degree) +{ + MSG_ERROR("%s is not supported", __func__); +} + +EAPI int ivug_image_rotate_get(Evas_Object *obj) +{ + MSG_ERROR("%s is not supported", __func__); + + return 0; +} + +EAPI void ivug_image_coordinate_lcd_to_image(Evas_Object *photocam, int lcd_x, int lcd_y, int *img_x, int *img_y) +{ + MSG_ASSERT(photocam != NULL); + + int image_w, image_h; + + ivug_image_image_size_get(photocam, &image_w, &image_h); // Get original image size. + + MSG_UTIL_HIGH("size w=%d, h=%d", image_w, image_h); + + ivug_ret_if(image_w <= 0 || image_h <= 0); + + int gx, gy, gw, gh; + + ivug_image_region_get(photocam, &gx, &gy, &gw, &gh); + + MSG_UTIL_HIGH("region x=%d, y=%d, w=%d, h=%d", gx, gy, gw, gh); + + int image_x, image_y; + + image_x = lcd_x - gx; + image_y = lcd_y - gy; + + image_x = image_x*image_w/gw; + image_y = image_y*image_h/gh; + + MSG_UTIL_HIGH("changed x=%d, y=%d", image_x, image_y); + + *img_x = image_x; + *img_y = image_y; +} + +EAPI void ivug_image_coordinate_image_to_lcd(Evas_Object *photocam, int img_x, int img_y, int *lcd_x, int *lcd_y) +{ + MSG_ASSERT(photocam != NULL); + + int image_w, image_h; + + ivug_ret_if(photocam == NULL); + + ivug_image_image_size_get(photocam, &image_w, &image_h); // Get original image size. + + MSG_UTIL_HIGH("size w=%d, h=%d", image_w, image_h); + + ivug_ret_if(image_w <= 0 || image_h <= 0); + + int gx, gy, gw, gh; + + ivug_image_region_get(photocam, &gx, &gy, &gw, &gh); + + MSG_UTIL_HIGH("region x=%d, y=%d, w=%d, h=%d", gx, gy, gw, gh); + + int scr_x, scr_y; + + scr_x = img_x*gw/image_w; + scr_y = img_y*gh/image_h; + + scr_x = scr_x+gx; + scr_y = scr_y+gy; + + MSG_UTIL_HIGH("changed x=%d, y=%d", scr_x, scr_y); + + *lcd_x = scr_x; + *lcd_y = scr_y; +} + + diff --git a/widget/src/scissorbox/ScissorBox.cpp b/widget/src/scissorbox/ScissorBox.cpp new file mode 100755 index 0000000..6472842 --- /dev/null +++ b/widget/src/scissorbox/ScissorBox.cpp @@ -0,0 +1,1727 @@ +/* + * Copyright 2012 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.tizenopensource.org/license + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "ScissorBox.h" + +#undef LOG_LVL +#define LOG_LVL DBG_MSG_LVL_HIGH + +#undef LOG_CAT +#define LOG_CAT "IV-SCISSOR" + +#define IMAGE_PATH PREFIX"/res/images/"PACKAGE + +#define CROP_POT_PATH IMAGE_PATH"/scissorbox/T01_CallerID_normal.png" +#define CROP_POT_HOLD_PATH IMAGE_PATH"/scissorbox/T01_CallerID_hold.png" +#define CROP_POT_PRESS_PATH IMAGE_PATH"/scissorbox/T01_CallerID_press.png" + +#define CROP_LINEW_PATH IMAGE_PATH"/scissorbox/T01_CallerID_line_W.png" +#define CROP_LINEH_PATH IMAGE_PATH"/scissorbox/T01_CallerID_line_h.png" +#define CROP_LINEW_PRESS_PATH IMAGE_PATH"/scissorbox/T01_CallerID_line_W_press.png" +#define CROP_LINEH_PRESS_PATH IMAGE_PATH"/scissorbox/T01_CallerID_line_h_press.png" + +#define DEFAULT_POT_NUM (4) +#define DEFAULT_DIM_BG_ALPHA (102) + +#undef ALLOW_RECT_TRACE + +class CSelectBox { +public: + enum eState { + NORMAL, + HOLD, + PRESS, + }; + + enum eGripType { + GRIP_LEFT = (1 << 0), + GRIP_RIGHT = (1 << 1), + GRIP_TOP = (1 << 2), + GRIP_BOTTOM = (1 << 3), + }; + +public: + CSelectBox() : m_state(NORMAL), m_ratio(0.0f), m_bPreserve(false), m_rect(), m_bound(0,0,720,1280) + { + }; + + virtual ~CSelectBox() {}; + + virtual void Create(Evas_Object *obj) {}; + + virtual void Move(int x, int y) { + m_rect.Left(x); + m_rect.Top(y); + }; + + virtual void Resize(int w, int h){ + MSG_HIGH("Box resized %dx%d ratio=%f", w, h, m_ratio); + + m_rect.Width(w); + + if ( m_bPreserve == true ) + { + m_rect.Height(w * m_ratio); + } + else + { + m_rect.Height(h); + } + }; + + virtual void SetState(eState state) { + m_state = state; + }; + + virtual eState GetState() const { + return m_state; + }; + + virtual void SetRatio(double ratio) { + m_bPreserve = true; + + m_ratio = ratio; // h / w + }; + + virtual double GetRatio() const { + if ( m_bPreserve == true ) + return m_ratio; + + return 0.0f; + }; + + virtual void SetBound(const CRect &rect) + { + m_bound = rect; + } + + virtual const CRect &GetBound() const { return m_bound; }; + virtual const CRect &GetRegion() const { return m_rect; }; + + virtual void Draw() = 0; +private: + eState m_state; + double m_ratio; + bool m_bPreserve; + +protected: + CRect m_rect; + CRect m_bound; +}; + + +class CBox : public CSelectBox { +public: + const int SHADOW_DEPTH; + const int EVENT_GRIP_SIZE; + const CSize POT_SIZE; + + static void _line_mouse_down(void *data, Evas *e, Evas_Object *obj, void *event_info) {}; + static void _line_mouse_up(void *data, Evas *e, Evas_Object *obj, void *event_info) {}; + + static void _pot_mouse_down(void *data, Evas *e, Evas_Object *obj, void *event_info) { + CBox *pBox = (CBox *)data; + +// Evas_Event_Mouse_Down *ev = (Evas_Event_Mouse_Down *) event_info; + + pBox->OnGripMouseDown(); + }; + static void _pot_mouse_move(void *data, Evas *e, Evas_Object *obj, void *event_info) + { + CBox *pBox = (CBox *)data; + + Evas_Event_Mouse_Move *ev = (Evas_Event_Mouse_Move *) event_info; + + eGripType grip = static_cast (reinterpret_cast (evas_object_data_get(obj, "grip_type"))); + + if ( ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD ) + { + MSG_HIGH("On Hold"); + } + + if ( ev->event_flags & EVAS_EVENT_FLAG_ON_SCROLL ) + { + MSG_HIGH("On Scroller"); + } + + pBox->OnGripMouseMove(grip, ev->prev.output.x, ev->prev.output.y, ev->cur.output.x, ev->cur.output.y); + }; + + static void _pot_mouse_up(void *data, Evas *e, Evas_Object *obj, void *event_info) { + CBox *pBox = (CBox *)data; + +// Evas_Event_Mouse_Up *ev = (Evas_Event_Mouse_Up *) event_info; + + pBox->OnGripMouseUp(); + }; + + + static void _selector_mouse_down(void *data, Evas *e, Evas_Object *obj, void *event_info) { + CBox *pBox = (CBox *)data; + + Evas_Event_Mouse_Down *ev = (Evas_Event_Mouse_Down *) event_info; + + pBox->OnMouseDown(ev->output.x, ev->output.y); + + }; + + static void _selector_mouse_move(void *data, Evas *e, Evas_Object *obj, void *event_info) { + CBox *pBox = (CBox *)data; + + Evas_Event_Mouse_Move *ev = (Evas_Event_Mouse_Move *) event_info; + + MSG_LOW("(%d,%d) --> (%d,%d)", ev->cur.output.x, ev->cur.output.y, ev->prev.output.x, ev->prev.output.y); + pBox->OnMouseMove(ev->prev.output.x, ev->prev.output.y, ev->cur.output.x, ev->cur.output.y); + }; + + static void _selector_mouse_up(void *data, Evas *e, Evas_Object *obj, void *event_info) { + CBox *pBox = (CBox *)data; + + Evas_Event_Mouse_Up *ev = (Evas_Event_Mouse_Up *) event_info; + + pBox->OnMouseUp(ev->output.x, ev->output.y); + }; + +public: + CBox() : CSelectBox(), SHADOW_DEPTH(4), EVENT_GRIP_SIZE(60), POT_SIZE(18,18), m_bMouseDown(false), m_bGripMouseDown(false) { }; + + virtual ~CBox() { + MSG_HIGH("Remove CBox"); + + for (int i = 0; i < DEFAULT_POT_NUM; i++) + { + evas_object_del(selector_line[i]); + evas_object_del(selector_pot[i]); + evas_object_del(event_pot[i]); + } + + evas_object_del(center); + }; + + void OnMouseDown(int x, int y) + { + MSG_HIGH("Mouse down XY(%d,%d)", x, y); + + SetState(PRESS); + m_bMouseDown = true; + } + + void OnMouseMove(int px, int py, int cx, int cy) + { + // Inform changes to parent. + if ( m_bMouseDown == false ) return; + + int dx, dy; + + dx = cx - px; + dy = cy - py; + + MSG_HIGH("Mouse move XY(%d,%d) -> XY(%d,%d)", px, py, cx, cy); + + if ( dx == 0 && dy == 0) { + return; + }; + + if ( m_rect.Left() + dx < m_bound.Left() ) + { + MSG_HIGH("Left bound"); + dx = m_bound.Left() - m_rect.Left(); + } + + if ( m_rect.Right() + dx > m_bound.Right() ) + { + MSG_HIGH("Right bound"); + dx = m_bound.Right() - m_rect.Right(); + } + + if ( m_rect.Top() + dy < m_bound.Top() ) + { + MSG_HIGH("Top bound"); + dy = m_bound.Top() - m_rect.Top(); + } + + if ( m_rect.Bottom() + dy > m_bound.Bottom() ) + { + MSG_HIGH("Bottom bound"); + dy = m_bound.Bottom() - m_rect.Bottom(); + } + + // Move rect + m_rect.MoveBy(dx, dy); + + evas_object_smart_changed(evas_object_smart_parent_get(center)); + + } + + void OnMouseUp(int x, int y) + { + MSG_HIGH("Mouse up XY(%d,%d)", x, y); + SetState(NORMAL); + + m_bMouseDown = false; +// evas_object_smart_callback_call(sd->obj, SIG_CHANGED, NULL); + } + + void OnGripMouseUp() + { + m_bGripMouseDown = false; + SetState(NORMAL); + } + + void OnGripMouseDown() + { + m_bGripMouseDown = true; + SetState(HOLD); + } + + void OnGripMouseMove(eGripType grip, int px, int py, int cx, int cy) + { + if ( m_bGripMouseDown == false ) return; + + int dx = cx - px; + int dy = cy - py; + + if ( dx == 0 && dy == 0) { + return; + }; + + if ( GetRatio() != 0.0f ) + { + _GripMovePreserve(grip, dx, dy); + } + else + { + _GripMove(grip, dx, dy); + } + + MSG_HIGH("New Rect %d,%d,%d,%d", m_rect.Left(), m_rect.Top(), m_rect.Width(), m_rect.Height()); + + evas_object_smart_changed(evas_object_smart_parent_get(center)); + } + + virtual void SetState(eState state) { + CSelectBox::SetState(state); + + _LoadImage(); + }; + +private: + void _GripMove(eGripType grip, int dx, int dy) { + const int min_size = EVENT_GRIP_SIZE; + CRect rect = m_rect; + + int X1 = rect.Left(), Y1 = rect.Top() ,X2 = rect.Right(), Y2 = rect.Bottom(); + + if ( grip & GRIP_LEFT ) + { + X1 = rect.Left() + dx; + + if ( X1 < m_bound.Left() ) + { + MSG_HIGH("Left bound"); + X1 = m_bound.Left(); + } + + if ( rect.Width() - dx < min_size ) + { + X1 = rect.Right() - min_size; + + MSG_HIGH("X1 = %d (%d,%d)", X1, rect.Left(), rect.Right()); + } + } + + if ( grip & GRIP_TOP ) + { + Y1 = rect.Top() + dy; + + if ( Y1 < m_bound.Top() ) + { + MSG_HIGH("Top bound"); + Y1 = m_bound.Top(); + } + + if ( rect.Height() - dy < min_size ) + { + Y1 = rect.Bottom() - min_size; + + MSG_HIGH("Y1 = %d B=%d", Y1, rect.Bottom()); + } + } + + if ( grip & GRIP_RIGHT ) + { + X2 = rect.Right() + dx; + + if ( X2 > m_bound.Right() ) + { + MSG_HIGH("Right bound"); + X2 = m_bound.Right() ; + } + + if ( rect.Width() + dx < min_size ) + { + X2 = rect.Left() + min_size; + } + } + + if ( grip & GRIP_BOTTOM ) + { + Y2 = rect.Bottom() + dy; + + if ( Y2 > m_bound.Bottom() ) + { + MSG_HIGH("Bottom bound"); + Y2 = m_bound.Bottom(); + } + + if ( rect.Height() + dy < min_size ) + { + Y2 = rect.Top() + min_size; + } + } + + m_rect = CRect(X1, Y1, X2 - X1, Y2 - Y1); + + }; + + void _GripMovePreserve(eGripType grip, int dx, int dy) { + const int min_size = EVENT_GRIP_SIZE; + CRect rect = m_rect; + + int X,Y,W,H; + + double ratio = GetRatio(); + + MSG_HIGH("Dx=%d Dy=%d Ratio=%f", dx, dy, ratio); + + enum eDominantDirection + { + Direction_X, + Direction_Y + } ; + + eDominantDirection dir = Direction_X; + int mov_dist; + if(abs(dx) < abs(dy)) + { + dir = Direction_Y; + mov_dist = dy; + } + else + { + mov_dist = dx; + } + + if ( (grip & GRIP_LEFT) && (grip & GRIP_TOP) ) + { + MSG_HIGH("LEFT,TOP"); + + if ( dir == Direction_X ) + { + W = rect.Width() - mov_dist; + H = W * ratio; + + X = m_rect.Right() - W; + Y = m_rect.Bottom() - H; + } + else + { + H = rect.Height() - mov_dist; + W = H / ratio; + + X = m_rect.Right() - W; + Y = m_rect.Bottom() - H; + } + + + } + + if ( (grip & GRIP_RIGHT) && (grip & GRIP_TOP) ) + { + MSG_HIGH("RIGHT,TOP"); + + if ( dir == Direction_X ) + { + W = rect.Width() + mov_dist; + H = W * ratio; + + X = m_rect.Left(); + Y = m_rect.Bottom() - H; + } + else + { + H = rect.Height() - mov_dist; + W = H / ratio; + + X = m_rect.Left(); + Y = m_rect.Bottom() - H; + } + + } + + if ( (grip & GRIP_RIGHT) && (grip & GRIP_BOTTOM) ) + { + MSG_HIGH("RIGHT,BOTTOM"); + if ( dir == Direction_X ) + { + W = rect.Width() + mov_dist; + H = W * ratio; + + X = m_rect.Left(); + Y = m_rect.Top(); + } + else + { + H = rect.Height() + mov_dist; + W = H / ratio; + + X = m_rect.Left(); + Y = m_rect.Top(); + + } + + } + + if ( (grip & GRIP_LEFT) && (grip & GRIP_BOTTOM) ) + { + MSG_HIGH("LEFT,BOTTOM"); + + if ( dir == Direction_X ) + { + W = rect.Width() - mov_dist; + H = W * ratio; + + X = m_rect.Right() - W; + Y = m_rect.Top(); + } + else + { + H = rect.Height() + mov_dist; + W = H / ratio; + + X = m_rect.Right() - W; + Y = m_rect.Top(); + } + + } + + if ( W < min_size || H < min_size) + { + return; + } + + if ( X < m_bound.Left() || Y < m_bound.Top() || + X + W > m_bound.Right() || Y+H > m_bound.Bottom() ) + { + return; + } + + m_rect = CRect(X,Y,W,H); + + } + + void _LoadImage() { + const char *line_w; + const char *line_h; + const char *pot; + + if ( GetState() == NORMAL ) + { + line_w = CROP_LINEW_PATH; + line_h = CROP_LINEH_PATH; + + pot = CROP_POT_PATH; + } + else if ( GetState() == PRESS ) + { + line_w = CROP_LINEW_PRESS_PATH; + line_h = CROP_LINEH_PRESS_PATH; + + pot = CROP_POT_PRESS_PATH; + } + else if ( GetState() == HOLD ) + { + line_w = CROP_LINEW_PATH; + line_h = CROP_LINEH_PATH; + + pot = CROP_POT_HOLD_PATH; + } + else + { + MSG_FATAL("Invalid state"); + return; + } + + Evas_Load_Error err; + + for (int i = 0; i < DEFAULT_POT_NUM; i++) + { + if(i % 2) // 1, 3 + { + evas_object_image_file_set(selector_line[i], line_w, NULL); + err = evas_object_image_load_error_get(selector_line[i]); + if (err != EVAS_LOAD_ERROR_NONE) + { + MSG_ERROR("could not load image '%s'. %s", line_w, evas_load_error_str(err)); + } + } + else // 0, 2 + { + evas_object_image_file_set(selector_line[i], line_h, NULL); + err = evas_object_image_load_error_get(selector_line[i]); + if (err != EVAS_LOAD_ERROR_NONE) + { + MSG_ERROR("could not load image '%s'. %s", line_h, evas_load_error_str(err)); + } + } + + evas_object_show(selector_line[i]); + + } + + for (int i = 0; i < DEFAULT_POT_NUM; i++) + { + evas_object_image_file_set(selector_pot[i], pot, NULL); + + err = evas_object_image_load_error_get(selector_line[i]); + if (err != EVAS_LOAD_ERROR_NONE) + { + MSG_ERROR("could not load image '%s'. %s", pot, evas_load_error_str(err)); + } + + evas_object_image_scale_hint_set(selector_pot[i], EVAS_IMAGE_SCALE_HINT_STATIC); + + evas_object_show(selector_pot[i]); + } + }; + +public: + + void Create(Evas_Object *obj) { + Evas *e = evas_object_evas_get(obj); + + center = evas_object_rectangle_add(e); + evas_object_color_set(center, 0, 0, 0, 0); + + evas_object_event_callback_add(center, EVAS_CALLBACK_MOUSE_DOWN, _selector_mouse_down, this); + evas_object_event_callback_add(center, EVAS_CALLBACK_MOUSE_UP, _selector_mouse_up, this); + evas_object_event_callback_add(center, EVAS_CALLBACK_MOUSE_MOVE, _selector_mouse_move, this); + + evas_object_smart_member_add(center, obj); + + evas_object_show(center); + + for (int i = 0; i < DEFAULT_POT_NUM; i++) + { + selector_line[i] = evas_object_image_filled_add(e); + + evas_object_event_callback_add(selector_line[i], EVAS_CALLBACK_MOUSE_DOWN, _line_mouse_down, this); + evas_object_event_callback_add(selector_line[i], EVAS_CALLBACK_MOUSE_UP, _line_mouse_up, this); + + evas_object_smart_member_add(selector_line[i], obj); + } + + for (int i = 0; i < DEFAULT_POT_NUM; i++) + { + /* Create image icon (pot) */ + selector_pot[i] = evas_object_image_filled_add(e); + + evas_object_image_scale_hint_set(selector_pot[i], EVAS_IMAGE_SCALE_HINT_STATIC); + + evas_object_smart_member_add(selector_pot[i], obj); + + /* Create event object above image icon (pot) */ + event_pot[i] = evas_object_rectangle_add(e); + evas_object_color_set(event_pot[i], 0, 0, 0, 0); + + evas_object_event_callback_add(event_pot[i], EVAS_CALLBACK_MOUSE_DOWN, _pot_mouse_down, this); + evas_object_event_callback_add(event_pot[i], EVAS_CALLBACK_MOUSE_UP, _pot_mouse_up, this); + evas_object_event_callback_add(event_pot[i], EVAS_CALLBACK_MOUSE_MOVE, _pot_mouse_move, this); + + evas_object_resize(event_pot[i], EVENT_GRIP_SIZE, EVENT_GRIP_SIZE); + + evas_object_smart_member_add(event_pot[i], obj); + + evas_object_show(event_pot[i]); + } + + evas_object_data_set(event_pot[0], "grip_type",(void *)(GRIP_LEFT | GRIP_TOP)); + evas_object_data_set(event_pot[1], "grip_type",(void *)(GRIP_RIGHT | GRIP_TOP)); + evas_object_data_set(event_pot[2], "grip_type",(void *)(GRIP_RIGHT | GRIP_BOTTOM)); + evas_object_data_set(event_pot[3], "grip_type",(void *)(GRIP_LEFT | GRIP_BOTTOM)); + + _LoadImage(); + }; + + void Draw() { +// Check bound. + if ( m_bound.Inside(m_rect) == false ) + { + MSG_ERROR("Out of bound region. Rect(%d,%d,%d,%d) Bound(%d,%d,%d,%d)", m_rect.Left(), m_rect.Top(), m_rect.Width(), m_rect.Height(), + m_bound.Left(), m_bound.Top(), m_bound.Width(), m_bound.Height()); + + // Reset Rect + } + + evas_object_move(center, m_rect.Left(), m_rect.Top()); + evas_object_resize(center, m_rect.Width(), m_rect.Height()); + // Horizontal + evas_object_move(selector_line[0], m_rect.Left(), m_rect.Top()); + evas_object_resize(selector_line[0], m_rect.Width() , 8); + + evas_object_move(selector_line[2], m_rect.Left(), m_rect.Bottom() - (SHADOW_DEPTH / 2)); + evas_object_resize(selector_line[2], m_rect.Width() , 8); + + // Vertical + evas_object_move(selector_line[1], m_rect.Left(), m_rect.Top()); + evas_object_resize(selector_line[1], 8, m_rect.Height() ); + + evas_object_move(selector_line[3], m_rect.Right() - (SHADOW_DEPTH / 2), m_rect.Top()); + evas_object_resize(selector_line[3], 8, m_rect.Height()); + + evas_object_move(event_pot[0], m_rect.Left() - ( EVENT_GRIP_SIZE / 2), m_rect.Top() - ( EVENT_GRIP_SIZE / 2)); + evas_object_move(event_pot[1], m_rect.Right() - ( EVENT_GRIP_SIZE / 2), m_rect.Top() - ( EVENT_GRIP_SIZE / 2)); + evas_object_move(event_pot[2], m_rect.Right() - ( EVENT_GRIP_SIZE / 2), m_rect.Bottom() - ( EVENT_GRIP_SIZE / 2)); + evas_object_move(event_pot[3], m_rect.Left() - ( EVENT_GRIP_SIZE / 2), m_rect.Bottom() - ( EVENT_GRIP_SIZE / 2)); + + // Pot + int w, h; + + w = POT_SIZE.Width(); + h = POT_SIZE.Height(); + + evas_object_move(selector_pot[0], m_rect.Left() - 4, m_rect.Top() - 4 ); + evas_object_resize(selector_pot[0], w, h); + + evas_object_move(selector_pot[1], m_rect.Right() - 8, m_rect.Top() - 4 ); + evas_object_resize(selector_pot[1], w, h); + + evas_object_move(selector_pot[2], m_rect.Right() - 8, m_rect.Bottom() - 8); + evas_object_resize(selector_pot[2], w, h); + + evas_object_move(selector_pot[3], m_rect.Left() - 4, m_rect.Bottom() - 8); + evas_object_resize(selector_pot[3], w, h); + + }; + +private: + Evas_Object *selector_line[4]; + Evas_Object *event_pot[4]; + Evas_Object *selector_pot[4]; + + Evas_Object *center; + + bool m_bMouseDown; + bool m_bGripMouseDown; + +}; + + +#define CROP_SELECT_PATH IMAGE_PATH"/crop/T06_selection.png" + +#define CROP_RESIZE_H_PATH IMAGE_PATH"/crop/T06_selection_Resizing_h.png" +#define CROP_RESIZE_W_PATH IMAGE_PATH"/crop/T06_selection_Resizing_V.png" + +#define CROP_ROTATE_PATH IMAGE_PATH"/crop/T06_selection_Rotate.png" + +class CBox1 : public CSelectBox { +public: + const int EVENT_GRIP_SIZE; + const CSize POT_SIZE; + + static void _line_mouse_down(void *data, Evas *e, Evas_Object *obj, void *event_info) {}; + static void _line_mouse_up(void *data, Evas *e, Evas_Object *obj, void *event_info) {}; + + static void _pot_mouse_down(void *data, Evas *e, Evas_Object *obj, void *event_info) { + CBox1 *pBox = (CBox1 *)data; + +// Evas_Event_Mouse_Down *ev = (Evas_Event_Mouse_Down *) event_info; + + pBox->OnGripMouseDown(); + }; + static void _pot_mouse_move(void *data, Evas *e, Evas_Object *obj, void *event_info) + { + CBox1 *pBox = (CBox1 *)data; + + Evas_Event_Mouse_Move *ev = (Evas_Event_Mouse_Move *) event_info; + + eGripType grip = static_cast (reinterpret_cast (evas_object_data_get(obj, "grip_type"))); + + if ( ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD ) + { + MSG_HIGH("On Hold"); + } + + if ( ev->event_flags & EVAS_EVENT_FLAG_ON_SCROLL ) + { + MSG_HIGH("On Scroller"); + } + + pBox->OnGripMouseMove(grip, ev->prev.output.x, ev->prev.output.y, ev->cur.output.x, ev->cur.output.y); + }; + + static void _pot_mouse_up(void *data, Evas *e, Evas_Object *obj, void *event_info) { + CBox1 *pBox = (CBox1 *)data; + +// Evas_Event_Mouse_Up *ev = (Evas_Event_Mouse_Up *) event_info; + + pBox->OnGripMouseUp(); + }; + + + static void _selector_mouse_down(void *data, Evas *e, Evas_Object *obj, void *event_info) { + CBox1 *pBox = (CBox1 *)data; + + Evas_Event_Mouse_Down *ev = (Evas_Event_Mouse_Down *) event_info; + + pBox->OnMouseDown(ev->output.x, ev->output.y); + + }; + + static void _selector_mouse_move(void *data, Evas *e, Evas_Object *obj, void *event_info) { + CBox1 *pBox = (CBox1 *)data; + + Evas_Event_Mouse_Move *ev = (Evas_Event_Mouse_Move *) event_info; + + MSG_LOW("(%d,%d) --> (%d,%d)", ev->cur.output.x, ev->cur.output.y, ev->prev.output.x, ev->prev.output.y); + pBox->OnMouseMove(ev->prev.output.x, ev->prev.output.y, ev->cur.output.x, ev->cur.output.y); + }; + + static void _selector_mouse_up(void *data, Evas *e, Evas_Object *obj, void *event_info) { + CBox1 *pBox = (CBox1 *)data; + + Evas_Event_Mouse_Up *ev = (Evas_Event_Mouse_Up *) event_info; + + pBox->OnMouseUp(ev->output.x, ev->output.y); + }; + +public: + CBox1() : CSelectBox(), EVENT_GRIP_SIZE(60), POT_SIZE(56,56), m_bMouseDown(false), m_bGripMouseDown(false) { }; + + virtual ~CBox1() { + MSG_HIGH("Remove CBox1"); + + for (int i = 0; i < DEFAULT_POT_NUM; i++) + { + evas_object_del(selector_pot[i]); + evas_object_del(event_pot[i]); + } + + evas_object_del(this->sel_rotate); + evas_object_del(select_rect); + }; + + void OnMouseDown(int x, int y) + { + MSG_HIGH("Mouse down XY(%d,%d)", x, y); + + SetState(PRESS); + m_bMouseDown = true; + } + + void OnMouseMove(int px, int py, int cx, int cy) + { + // Inform changes to parent. + if ( m_bMouseDown == false ) return; + + int dx, dy; + + dx = cx - px; + dy = cy - py; + + MSG_HIGH("Mouse move XY(%d,%d) -> XY(%d,%d)", px, py, cx, cy); + + if ( dx == 0 && dy == 0) { + return; + }; + + if ( m_rect.Left() + dx < m_bound.Left() ) + { + MSG_HIGH("Left bound"); + dx = m_bound.Left() - m_rect.Left(); + } + + if ( m_rect.Right() + dx > m_bound.Right() ) + { + MSG_HIGH("Right bound"); + dx = m_bound.Right() - m_rect.Right(); + } + + if ( m_rect.Top() + dy < m_bound.Top() ) + { + MSG_HIGH("Top bound"); + dy = m_bound.Top() - m_rect.Top(); + } + + if ( m_rect.Bottom() + dy > m_bound.Bottom() ) + { + MSG_HIGH("Bottom bound"); + dy = m_bound.Bottom() - m_rect.Bottom(); + } + + // Move rect + m_rect.MoveBy(dx, dy); + + evas_object_smart_changed(evas_object_smart_parent_get(select_rect)); + + } + + void OnMouseUp(int x, int y) + { + MSG_HIGH("Mouse up XY(%d,%d)", x, y); + SetState(NORMAL); + + m_bMouseDown = false; +// evas_object_smart_callback_call(sd->obj, SIG_CHANGED, NULL); + } + + void OnGripMouseUp() + { + m_bGripMouseDown = false; + SetState(NORMAL); + } + + void OnGripMouseDown() + { + m_bGripMouseDown = true; + SetState(HOLD); + } + + void OnGripMouseMove(eGripType grip, int px, int py, int cx, int cy) + { + if ( m_bGripMouseDown == false ) return; + + int dx = cx - px; + int dy = cy - py; + + if ( dx == 0 && dy == 0) { + return; + }; + + if ( GetRatio() != 0.0f ) + { + _GripMovePreserve(grip, dx, dy); + } + else + { + _GripMove(grip, dx, dy); + } + + MSG_HIGH("New Rect %d,%d,%d,%d", m_rect.Left(), m_rect.Top(), m_rect.Width(), m_rect.Height()); + + evas_object_smart_changed(evas_object_smart_parent_get(select_rect)); + } + +private: + void _GripMove(eGripType grip, int dx, int dy) { + const int min_size = EVENT_GRIP_SIZE; + CRect rect = m_rect; + + int X1 = rect.Left(), Y1 = rect.Top() ,X2 = rect.Right(), Y2 = rect.Bottom(); + + if ( grip & GRIP_LEFT ) + { + X1 = rect.Left() + dx; + + if ( X1 < m_bound.Left() ) + { + MSG_HIGH("Left bound"); + X1 = m_bound.Left(); + } + + if ( rect.Width() - dx < min_size ) + { + X1 = rect.Right() - min_size; + + MSG_HIGH("X1 = %d (%d,%d)", X1, rect.Left(), rect.Right()); + } + } + + if ( grip & GRIP_TOP ) + { + Y1 = rect.Top() + dy; + + if ( Y1 < m_bound.Top() ) + { + MSG_HIGH("Top bound"); + Y1 = m_bound.Top(); + } + + if ( rect.Height() - dy < min_size ) + { + Y1 = rect.Bottom() - min_size; + + MSG_HIGH("Y1 = %d B=%d", Y1, rect.Bottom()); + } + } + + if ( grip & GRIP_RIGHT ) + { + X2 = rect.Right() + dx; + + if ( X2 > m_bound.Right() ) + { + MSG_HIGH("Right bound"); + X2 = m_bound.Right() ; + } + + if ( rect.Width() + dx < min_size ) + { + X2 = rect.Left() + min_size; + } + } + + if ( grip & GRIP_BOTTOM ) + { + Y2 = rect.Bottom() + dy; + + if ( Y2 > m_bound.Bottom() ) + { + MSG_HIGH("Bottom bound"); + Y2 = m_bound.Bottom(); + } + + if ( rect.Height() + dy < min_size ) + { + Y2 = rect.Top() + min_size; + } + } + + m_rect = CRect(X1, Y1, X2 - X1, Y2 - Y1); + + }; + + void _GripMovePreserve(eGripType grip, int dx, int dy) { + const int min_size = EVENT_GRIP_SIZE; + CRect rect = m_rect; + + int X,Y,W,H; + + double ratio = GetRatio(); + + MSG_HIGH("Dx=%d Dy=%d Ratio=%f", dx, dy, ratio); + + enum eDominantDirection + { + Direction_X, + Direction_Y + } ; + + eDominantDirection dir = Direction_X; + int mov_dist; + if(abs(dx) < abs(dy)) + { + dir = Direction_Y; + mov_dist = dy; + } + else + { + mov_dist = dx; + } + + if ( (grip & GRIP_LEFT) || (grip & GRIP_TOP) ) + { + MSG_HIGH("LEFT,TOP"); + + if ( dir == Direction_X ) + { + W = rect.Width() - mov_dist; + H = W * ratio; + + X = m_rect.Right() - W; + Y = m_rect.Bottom() - H; + } + else + { + H = rect.Height() - mov_dist; + W = H / ratio; + + X = m_rect.Right() - W; + Y = m_rect.Bottom() - H; + } + + + } + + + if ( (grip & GRIP_RIGHT) || (grip & GRIP_BOTTOM) ) + { + MSG_HIGH("RIGHT,BOTTOM"); + if ( dir == Direction_X ) + { + W = rect.Width() + mov_dist; + H = W * ratio; + + X = m_rect.Left(); + Y = m_rect.Top(); + } + else + { + H = rect.Height() + mov_dist; + W = H / ratio; + + X = m_rect.Left(); + Y = m_rect.Top(); + + } + + } + + +#if 0 + if ( (grip & GRIP_RIGHT) && (grip & GRIP_TOP) ) + { + MSG_HIGH("RIGHT,TOP"); + + if ( dir == Direction_X ) + { + W = rect.Width() + mov_dist; + H = W * m_ratio; + + X = m_rect.Left(); + Y = m_rect.Bottom() - H; + } + else + { + H = rect.Height() - mov_dist; + W = H / m_ratio; + + X = m_rect.Left(); + Y = m_rect.Bottom() - H; + } + + } + + if ( (grip & GRIP_LEFT) && (grip & GRIP_BOTTOM) ) + { + MSG_HIGH("LEFT,BOTTOM"); + + if ( dir == Direction_X ) + { + W = rect.Width() - mov_dist; + H = W * m_ratio; + + X = m_rect.Right() - W; + Y = m_rect.Top(); + } + else + { + H = rect.Height() + mov_dist; + W = H / m_ratio; + + X = m_rect.Right() - W; + Y = m_rect.Top(); + } + + } +#endif + + if ( W < min_size || H < min_size) + { + return; + } + + if ( X < m_bound.Left() || Y < m_bound.Top() || + X + W > m_bound.Right() || Y+H > m_bound.Bottom() ) + { + return; + } + + m_rect = CRect(X,Y,W,H); + + } + + void _LoadImage() { + + Evas_Load_Error err; + + evas_object_image_file_set(select_rect, CROP_SELECT_PATH, NULL); + err = evas_object_image_load_error_get(select_rect); + if (err != EVAS_LOAD_ERROR_NONE) + { + MSG_ERROR("could not load image '%s'. %s", CROP_SELECT_PATH, evas_load_error_str(err)); + } + + evas_object_image_border_set(select_rect, 19, 18, 18, 18); + evas_object_show(select_rect); + + const char *szPot[] = { + CROP_RESIZE_H_PATH, + CROP_RESIZE_H_PATH, + CROP_RESIZE_W_PATH, + CROP_RESIZE_W_PATH + }; + + for (int i = 0; i < DEFAULT_POT_NUM; i++) + { + evas_object_image_file_set(selector_pot[i], szPot[i], NULL); + + err = evas_object_image_load_error_get(selector_pot[i]); + if (err != EVAS_LOAD_ERROR_NONE) + { + MSG_ERROR("could not load image '%s'. %s", szPot[i], evas_load_error_str(err)); + } + + evas_object_image_scale_hint_set(selector_pot[i], EVAS_IMAGE_SCALE_HINT_STATIC); + + evas_object_show(selector_pot[i]); + } + + /*evas_object_image_file_set(sel_rotate, CROP_ROTATE_PATH, NULL); + + err = evas_object_image_load_error_get(sel_rotate); + if (err != EVAS_LOAD_ERROR_NONE) + { + MSG_ERROR("could not load image '%s'. %s", CROP_ROTATE_PATH, evas_load_error_str(err)); + } + + evas_object_image_scale_hint_set(sel_rotate, EVAS_IMAGE_SCALE_HINT_STATIC); + + evas_object_show(sel_rotate);*/ + + }; + +public: + virtual void SetState(eState state) { + CSelectBox::SetState(state); + + _LoadImage(); + }; + + void Create(Evas_Object *obj) { + Evas *e = evas_object_evas_get(obj); + + select_rect = evas_object_image_filled_add(e); + + evas_object_event_callback_add(select_rect, EVAS_CALLBACK_MOUSE_DOWN, _selector_mouse_down, this); + evas_object_event_callback_add(select_rect, EVAS_CALLBACK_MOUSE_UP, _selector_mouse_up, this); + evas_object_event_callback_add(select_rect, EVAS_CALLBACK_MOUSE_MOVE, _selector_mouse_move, this); + + evas_object_smart_member_add(select_rect, obj); + + for (int i = 0; i < DEFAULT_POT_NUM; i++) + { + /* Create image icon (pot) */ + selector_pot[i] = evas_object_image_filled_add(e); + + evas_object_image_scale_hint_set(selector_pot[i], EVAS_IMAGE_SCALE_HINT_STATIC); + + evas_object_smart_member_add(selector_pot[i], obj); + + /* Create event object above image icon (pot) */ + event_pot[i] = evas_object_rectangle_add(e); + evas_object_color_set(event_pot[i], 0, 0, 0, 0); + + evas_object_event_callback_add(event_pot[i], EVAS_CALLBACK_MOUSE_DOWN, _pot_mouse_down, this); + evas_object_event_callback_add(event_pot[i], EVAS_CALLBACK_MOUSE_UP, _pot_mouse_up, this); + evas_object_event_callback_add(event_pot[i], EVAS_CALLBACK_MOUSE_MOVE, _pot_mouse_move, this); + + evas_object_smart_member_add(event_pot[i], obj); + + evas_object_show(event_pot[i]); + } + + + evas_object_data_set(event_pot[0], "grip_type",(void *)GRIP_LEFT); + evas_object_data_set(event_pot[1], "grip_type",(void *)GRIP_RIGHT); + evas_object_data_set(event_pot[2], "grip_type",(void *)GRIP_TOP); + evas_object_data_set(event_pot[3], "grip_type",(void *)GRIP_BOTTOM); + + sel_rotate = evas_object_image_filled_add(e); + evas_object_smart_member_add(sel_rotate, obj); + + _LoadImage(); + }; + + void Draw() { +// Check bound. + if ( m_bound.Inside(m_rect) == false ) + { + MSG_ERROR("Out of bound region. Rect(%d,%d,%d,%d) Bound(%d,%d,%d,%d)", m_rect.Left(), m_rect.Top(), m_rect.Width(), m_rect.Height(), + m_bound.Left(), m_bound.Top(), m_bound.Width(), m_bound.Height()); + } + + MSG_HIGH("Rect. %d,%d,%d,%d", m_rect.Left(), m_rect.Top(), m_rect.Width(), m_rect.Height()); + + const int margin_l = -10; + const int margin_r = -1; + const int margin_t = -1; + const int margin_b = -9; + + int mx, my, mw, mh; + + mx = m_rect.Left() + margin_l; + my = m_rect.Top() + margin_t; + mw = m_rect.Width() - margin_l - margin_r; + mh = m_rect.Height() - margin_t - margin_b; + + evas_object_move(select_rect, mx, my); + evas_object_resize(select_rect, mw, mh); + +// Event handle. + evas_object_resize(event_pot[0], EVENT_GRIP_SIZE, EVENT_GRIP_SIZE * 2); + evas_object_move(event_pot[0], m_rect.Left() - ( EVENT_GRIP_SIZE / 2), m_rect.Top() + m_rect.Height() / 2 - ( EVENT_GRIP_SIZE )); // Left + + evas_object_resize(event_pot[1], EVENT_GRIP_SIZE, EVENT_GRIP_SIZE * 2); + evas_object_move(event_pot[1], m_rect.Right() - ( EVENT_GRIP_SIZE / 2), m_rect.Top() + m_rect.Height() / 2 - ( EVENT_GRIP_SIZE )); // Right + + evas_object_resize(event_pot[2], EVENT_GRIP_SIZE * 2, EVENT_GRIP_SIZE); + evas_object_move(event_pot[2], m_rect.Left() + m_rect.Width() / 2 - ( EVENT_GRIP_SIZE ), m_rect.Top() - ( EVENT_GRIP_SIZE / 2)); // Top + + evas_object_resize(event_pot[3], EVENT_GRIP_SIZE * 2, EVENT_GRIP_SIZE); + evas_object_move(event_pot[3], m_rect.Left() + m_rect.Width() / 2 - ( EVENT_GRIP_SIZE ), m_rect.Bottom() - ( EVENT_GRIP_SIZE / 2)); // Bottom + + // Pot + const int lw = 4; + const int lh = 4; + + int w, h; + + w = POT_SIZE.Width(); + h = POT_SIZE.Height(); +// L + evas_object_resize(selector_pot[0], w, h); + evas_object_move(selector_pot[0], m_rect.Left() - w / 2 + lw, m_rect.Top() + m_rect.Height() / 2 - h / 2 ); +// R + evas_object_move(selector_pot[1], m_rect.Right() - w / 2 -lw, m_rect.Top() + m_rect.Height() / 2 - h / 2 ); + evas_object_resize(selector_pot[1], w, h); +// T + evas_object_move(selector_pot[2], m_rect.Left() + m_rect.Width() / 2 - w / 2 , m_rect.Top() - h / 2 + lh); + evas_object_resize(selector_pot[2], w, h); +// B + evas_object_move(selector_pot[3], m_rect.Left() + m_rect.Width() / 2 - w / 2, m_rect.Bottom() - h / 2 - lh); + evas_object_resize(selector_pot[3], w, h); + + evas_object_move(sel_rotate, m_rect.Right() - w / 2 - lw , m_rect.Top() - h / 2 + lh); + evas_object_resize(sel_rotate, w, h); + + }; + +private: + Evas_Object *select_rect; // Center rect + + Evas_Object *event_pot[4]; + Evas_Object *selector_pot[4]; + + Evas_Object *sel_rotate; + + bool m_bMouseDown; + bool m_bGripMouseDown; +}; + + +template<> +const Evas_Smart_Cb_Description CEvasSmartObject::_signals[] = { + {NULL, NULL}, +}; + +Evas_Object *CScissorBox::CreateObject(Evas_Object *parent) { + CEvasSmartObject::CreateObject(parent); + + evas_object_smart_callbacks_descriptions_set(GetObject(), _signals); + + for (int i = 0; i < DEFAULT_POT_NUM; i++) + { + m_opaque[i] = evas_object_rectangle_add(evas_object_evas_get(parent)); + + evas_object_color_set(m_opaque[i], 0, 0, 0, DEFAULT_DIM_BG_ALPHA); + evas_object_smart_member_add(m_opaque[i], GetObject()); + evas_object_repeat_events_set(m_opaque[i], EINA_TRUE); + } + + m_box = new CBox(); + + m_box->Create( GetObject() ); + + m_parent = parent; + + MSG_HIGH("Scissorbox created"); + return GetObject(); +}; + +void CScissorBox::remove() +{ + MSG_HIGH("Destroy ScissorBox. m_box=0x%08x", m_box); + + if ( m_target ) + { + UnRegisterCB(); + m_target = NULL; + } + + m_parent = NULL; + + for (int i = 0; i < DEFAULT_POT_NUM; i++) + { + evas_object_hide(m_opaque[i]); + evas_object_del(m_opaque[i]); + } + + if ( m_job ) + { + ecore_job_del(m_job); + m_job = NULL; + } + + delete m_box; + + delete this; +} + + +void CScissorBox::SetOpaque(bool bOpaque) +{ +#if 0 + // Determine whether BG is drawn or not. + if ( bOpaque == m_bOpaque ) + { + return; + } +#endif + + +/* +m_rect +------------------------------ +| m_opaque[0] | +| ___________________________ | +| ---- | +| m_opaque[3] |bg | m_opaque[1] | +|_______________----___________ | +| | +| m_opaque[2] | +------------------------------ +*/ + if ( bOpaque == true ) + { + evas_object_show(m_opaque[0]); + evas_object_show(m_opaque[1]); + evas_object_show(m_opaque[2]); + evas_object_show(m_opaque[3]); + } + else + { + evas_object_hide(m_opaque[0]); + evas_object_hide(m_opaque[1]); + evas_object_hide(m_opaque[2]); + evas_object_hide(m_opaque[3]); + } + + m_bOpaque = bOpaque; + +} + + +void CScissorBox::SetPreserveRatio(bool bPreserveRatio) +{ + m_bPreserveRatio = bPreserveRatio; + + if ( m_bPreserveRatio == true ) + { + CRect rect = m_box->GetRegion(); + + if ( rect.Width() != 0 ) + { + MSG_HIGH("Set to preserve ratio"); + m_box->SetRatio((double)rect.Height() / rect.Width()); + } + } + +} + +void CScissorBox::SetRegion(int x, int y, int w, int h) +{ + MSG_HIGH("Set Region(%d,%d,%d,%d)", x, y, w, h); + + m_box->Move(x,y); + + if ( m_bPreserveRatio == true ) + { + m_box->SetRatio((double)h / w); + } + + m_box->Resize(w,h); + m_bSetRegion = true; + + evas_object_smart_changed(GetObject()); +} + +void CScissorBox::SetBound(int x, int y, int w, int h) +{ + MSG_HIGH("Set Bound(%d,%d,%d,%d)", x, y, w, h); + + CRect rect(x, y, w, h); + m_box->SetBound(rect); + + + evas_object_smart_changed(GetObject()); +} + +void CScissorBox::SetBoxType(eType type) +{ +// Remove old one and reload + if ( m_boxtype != type ) + { + // Load again + if ( m_box ) + { + const CRect &bound = m_box->GetBound(); + const CRect ®ion = m_box->GetRegion(); + double ratio = m_box->GetRatio(); + + delete m_box; + m_box = NULL; + + if ( type == IMAGE_VIEW ) + { + m_box = new CBox; + } + else + { + m_box = new CBox1; + } + + m_box->Create( GetObject() ); + + m_box->SetBound(bound); + m_box->Move(region.Left(), region.Top()); + m_box->Resize(region.Width(), region.Height()); + + if ( m_bPreserveRatio == true ) + { + m_box->SetRatio(ratio); + } + + } + } + + m_boxtype = type; +} + + +const CRect &CScissorBox::GetRegion() const +{ + return m_box->GetRegion(); +} + + +void CScissorBox::Attach(Evas_Object *obj) +{ + MSG_HIGH("Attach client! obj=%s", evas_object_type_get(obj)); + + if ( m_target ) + UnRegisterCB(); + + m_target = obj; + + RegisterCB(); + + SetOpaque(true); + + OnTargetChanged(); +} + + +void CScissorBox::draw() +{ + if ( m_box == NULL ) return; + + if ( m_bOpaque == true) + { + const CRect &box_rect = m_box->GetRegion(); + + if ( box_rect != CRect::Zero ) + { + int x, y, w, h; + evas_output_viewport_get(evas_object_evas_get(GetObject()), &x, &y, &w, &h); + + MSG_LOW("Evas View port Output : %d,%d,%d,%d", x,y,w, h); + + evas_object_move(m_opaque[0], x, y); + evas_object_resize(m_opaque[0], w, box_rect.Top()); + + evas_object_move(m_opaque[1], box_rect.Right(), box_rect.Top()); + evas_object_resize(m_opaque[1], w - box_rect.Right() , box_rect.Height() ); + + evas_object_move(m_opaque[2], x, box_rect.Bottom()); + evas_object_resize(m_opaque[2], w , h - box_rect.Bottom() ); + + evas_object_move(m_opaque[3], x, box_rect.Top()); + evas_object_resize(m_opaque[3], box_rect.Left() , box_rect.Height() ); + } + } + + m_box->Draw(); +} + +void CScissorBox::OnTargetChanged() +{ + if ( m_job ) + { + ecore_job_del(m_job); + } + + m_job = ecore_job_add(_OnChangedJob, this); + +} + +void CScissorBox::ApplyChanges() +{ + int x, y, w, h; + + int lcd_x, lcd_y, lcd_w, lcd_h; + + evas_object_geometry_get(m_parent, &lcd_x, &lcd_y, &lcd_w, &lcd_h); + MSG_HIGH("LCD size (%d,%d,%d,%d)", lcd_x, lcd_y, lcd_w, lcd_h); + + double lcd_ratio = (double)lcd_h/lcd_w; + + if ( m_target == NULL ) + { + x = 0; + y = 0; + w = lcd_w; + h = lcd_h; + } + else + { + evas_object_geometry_get(m_target, &x, &y, &w, &h); + } + + // evas_object_geometry_get is not corret when image loaded before show effect ended + if(lcd_ratio > (double)h/w) + { + x = 0; + } + else + { + x = (lcd_w - w)/2; + } + + MSG_HIGH("Target Changed (%d,%d,%d,%d)->(%d,%d,%d,%d)", tRect.Left(), tRect.Top(), tRect.Width(), tRect.Height(), x, y, w, h); + + if ( w == 0 || h == 0 ) + { + MSG_WARN("Size does not changed"); + return; + } + + CRect bound(x,y,w,h); // Boundary size is same as target + m_box->SetBound(bound); + + MSG_HIGH("Set Bound rect(%d,%d,%d,%d)", bound.Left(), bound.Top(), bound.Width(), bound.Height() ); + + if ( m_bSetRegion == false ) + { + int nW = w / 2; + int nH = h / 2; + + m_box->Move(x + (w - nW) / 2, y + (h - nH) / 2 ); + m_box->Resize(nW, nH); + + MSG_HIGH("Region is not set yet. BoxRegion(%d,%d,%d,%d)", x + (w - nW) / 2, y + (h - nH) / 2, nW, nH); + evas_object_smart_changed(GetObject()); + + return; + } + +#ifdef ALLOW_RECT_TRACE + if ( tRect.Width() == 0 || tRect.Height() == 0 ) + { + MSG_WARN("First time"); + tRect = CRect(x,y,w,h); + return; + } + + double zRatio = (double)w / tRect.Width(); + + const CRect &box_rect = m_box->GetRegion(); + +// Convert to rect on image; + int ix = box_rect.Left() - tRect.Left(); + int iy = box_rect.Top() - tRect.Top(); + + int rx = ix * zRatio; + int ry = iy * zRatio; + int rw = box_rect.Width() * zRatio; + int rh = box_rect.Height() * zRatio; + + m_box->Move(rx + x, ry + y); + m_box->Resize(rw, rh); + + MSG_HIGH("%d,%d %d,%d,%d,%d", ix, iy, rx, ry, rw, rh); +#endif + tRect = CRect(x,y,w,h); + +#ifndef ALLOW_RECT_TRACE + const CRect &box_rect = m_box->GetRegion(); + + if ( bound.Inside(box_rect) == false ) + { + MSG_ERROR("Out of bound region. Rect(%d,%d,%d,%d) Bound(%d,%d,%d,%d)", box_rect.Left(), box_rect.Top(), box_rect.Width(), box_rect.Height(), + bound.Left(), bound.Top(), bound.Width(), bound.Height()); + + int ph, pw; + + ph = (box_rect.Height() * bound.Width()) / box_rect.Width(); + + if (ph > bound.Height()) + { + pw = (box_rect.Width() * bound.Height()) / box_rect.Height(); + ph = bound.Height(); + } + else + { + pw = bound.Width(); + } + + pw = pw / 2; + ph = ph / 2; + + MSG_ERROR("New WH(%d,%d)", pw, ph); + + m_box->Move(bound.Left() + (bound.Width() - pw ) / 2, bound.Top() + (bound.Height() - ph) / 2 ); + m_box->Resize(pw , ph); + +#if 0 + // Reset Rect + int nW = bound.Width() / 2; + int nH = bound.Height() / 2; + + if ( nW > nH ) + { + nW = bound.Width() / 2; + nH = bound.Height() / 2; + } + else + { + nW = bound.Width() / 2; + nH = bound.Height() / 2; + } + + m_box->Move(bound.Left() + (bound.Width() - nW) / 2, bound.Top() + (bound.Height() - nH) / 2 ); + m_box->Resize(nW, nH); +#endif + + } + +#endif // ALLOW_RECT_TRACE + + evas_object_smart_changed(GetObject()); + +} + + diff --git a/widget/src/scissorbox/ScissorBox.h b/widget/src/scissorbox/ScissorBox.h new file mode 100755 index 0000000..08b3c9e --- /dev/null +++ b/widget/src/scissorbox/ScissorBox.h @@ -0,0 +1,118 @@ +/* + * Copyright 2012 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.tizenopensource.org/license + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include "ivug-debug.h" +#include "EvasSmartObj.h" +#include "Ecore.h" + +using namespace std; + +class CSelectBox; + +class CScissorBox : public CEvasSmartObject { +public: + enum eType { + IMAGE_VIEW, + IMAGE_EDIT, + }; + +public: + CScissorBox() : CEvasSmartObject(), m_box(NULL), m_boxtype(IMAGE_VIEW), m_bOpaque(false), m_target(NULL), m_bPreserveRatio(false), m_bSetRegion(false), m_job(NULL) { + CEvasSmartObject::SetClassName("ScissorBox"); + }; + + virtual ~CScissorBox() { + MSG_HIGH("~CScissorBox freed"); + }; + + Evas_Object *CreateObject(Evas_Object *parent); + + void SetOpaque(bool bOpaque); + void SetRegion(int x, int y, int w, int h); + void SetBound(int x, int y, int w, int h); + void SetPreserveRatio(bool bPreserveRatio); + void SetBoxType(eType type); + + void Attach(Evas_Object *image); + + const CRect &GetRegion() const; + + void draw(); + void remove(); + void resize(int w, int h) { + MSG_HIGH("Scissor box resized. WH(%d,%d)", w, h); + }; + + static void _on_resize(void *data, Evas *e, Evas_Object *obj, void *event_info) + { + //CScissorBox *scissorbox = (CScissorBox *)data; + + //scissorbox->OnTargetChanged(); + }; + + static void _on_move(void *data, Evas *e, Evas_Object *obj, void *event_info) { + // CScissorBox *scissorbox = (CScissorBox *)data; + + //scissorbox->OnTargetChanged(); + }; + + static void _OnChangedJob(void *data) { + CScissorBox *scissorbox = (CScissorBox *)data; + + scissorbox->ApplyChanges(); + } + + void OnTargetChanged(); + void ApplyChanges(); + +private: + void RegisterCB() { + MSG_ASSERT(m_target != NULL); + + evas_object_event_callback_add(m_target, EVAS_CALLBACK_RESIZE, _on_resize, this); + evas_object_event_callback_add(m_target, EVAS_CALLBACK_MOVE, _on_move, this); + + } + + void UnRegisterCB() { + evas_object_event_callback_del_full(m_target, EVAS_CALLBACK_RESIZE, _on_resize, this); + evas_object_event_callback_del_full(m_target, EVAS_CALLBACK_MOVE, _on_move, this); + }; + + +private: + CSelectBox *m_box; + + eType m_boxtype; + + bool m_bOpaque; + Evas_Object *m_opaque[4]; + + Evas_Object *m_target; + + bool m_bPreserveRatio; + bool m_bSetRegion; // If region is set already, + Ecore_Job *m_job; + + CRect tRect; // Target rectangle + + Evas_Object *m_parent; // parent_layout +}; + + + diff --git a/widget/src/scissorbox/ivug-scissorbox.cpp b/widget/src/scissorbox/ivug-scissorbox.cpp new file mode 100755 index 0000000..1091ab7 --- /dev/null +++ b/widget/src/scissorbox/ivug-scissorbox.cpp @@ -0,0 +1,122 @@ +/* + * Copyright 2012 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.tizenopensource.org/license + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include + +#include "ivug-scissorbox.h" +#include "ivug-debug.h" + +#include "ScissorBox.h" + +#define SCISSORBOX_CLASS(obj) \ + static_cast(evas_object_data_get((obj), "CScissorBox")) + + +EAPI Evas_Object *ivug_scissorbox_add(Evas_Object *parent) +{ + CScissorBox *scissorbox = new CScissorBox; + + Evas_Object *obj = scissorbox->CreateObject(parent); + MSG_ASSERT(obj != NULL); + + evas_object_data_set(obj, "CScissorBox", scissorbox); + + MSG_HIGH("Create scissorBox object. class=0x%08x obj=0x%08x", scissorbox, obj); + return obj; +} + +EAPI void ivug_scissorbox_type_set(Evas_Object *obj, eScissorBoxType type) +{ + CScissorBox *scissorbox = SCISSORBOX_CLASS(obj); + MSG_ASSERT(obj != NULL); + + if ( type == SCISSOR_BOX_TYPE_1 ) + { + scissorbox->SetBoxType(CScissorBox::IMAGE_VIEW); + } + else + { + scissorbox->SetBoxType(CScissorBox::IMAGE_EDIT); + } + +} + +EAPI void ivug_scissorbox_attach(Evas_Object *obj, Evas_Object *pObj) +{ + CScissorBox *scissorbox = SCISSORBOX_CLASS(obj); + MSG_ASSERT(pObj != NULL); + + scissorbox->Attach(pObj); +} + +EAPI void ivug_scissorbox_region_get(Evas_Object *obj, int *x, int *y, int *w, int *h) +{ + CScissorBox *scissorbox = SCISSORBOX_CLASS(obj); + + const CRect ®ion = scissorbox->GetRegion(); + + if ( x ) *x = region.Left(); + if ( y ) *y = region.Top(); + if ( w ) *w = region.Width(); + if ( h ) *h = region.Height(); + +} + +EAPI void ivug_scissorbox_region_set(Evas_Object *obj, int x, int y, int w, int h) +{ + CScissorBox *scissorbox = SCISSORBOX_CLASS(obj); + + scissorbox->SetRegion(x,y,w,h); +} + +EAPI void ivug_scissorbox_boundary_set(Evas_Object *obj, int x, int y, int w, int h) +{ + CScissorBox *scissorbox = SCISSORBOX_CLASS(obj); + + scissorbox->SetBound(x,y,w,h); +} + + +EAPI void ivug_scissorbox_ratio_fix(Evas_Object *obj, Eina_Bool bFix) +{ + CScissorBox *scissorbox = SCISSORBOX_CLASS(obj); + + if ( bFix == EINA_TRUE ) + { + scissorbox->SetPreserveRatio(true); + } + else + { + scissorbox->SetPreserveRatio(false); + } + +} + +EAPI void ivug_scissorbox_set_opaque(Evas_Object *obj, Eina_Bool bOpaque) +{ + CScissorBox *scissorbox = SCISSORBOX_CLASS(obj); + + if ( bOpaque == EINA_TRUE ) + { + scissorbox->SetOpaque(true); + } + else + { + scissorbox->SetOpaque(false); + } +} + + diff --git a/widget/src/util/EFLUtil.cpp b/widget/src/util/EFLUtil.cpp new file mode 100755 index 0000000..923173c --- /dev/null +++ b/widget/src/util/EFLUtil.cpp @@ -0,0 +1,355 @@ +/* + * Copyright 2012 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.tizenopensource.org/license + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include "EFLUtil.h" +#include "ivug-debug.h" + +#undef LOG_LVL +#define LOG_LVL DBG_MSG_LVL_HIGH +#undef LOG_CAT +#define LOG_CAT "IV-UTIL" + +namespace EFL { + +void get_evas_geometry(Evas_Object *obj, const char *prefix) +{ + int x, y, w, h; + + evas_object_geometry_get(obj, &x, &y, &w, &h); + + MSG_HIGH("%s XYWH(%d,%d,%d,%d)", prefix); +} + +Evas_Object *create_gesture(Evas_Object *parent) +{ + Evas_Object *gesture; + + gesture = elm_gesture_layer_add(parent); + + return gesture; +} + +Evas_Object *create_rect(Evas_Object *parent) +{ + Evas_Object *obj; + + obj = evas_object_rectangle_add(evas_object_evas_get(parent)); + + evas_object_size_hint_expand_set(obj, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + evas_object_size_hint_fill_set(obj, EVAS_HINT_FILL, EVAS_HINT_FILL); + evas_object_color_set(obj, 0,0,0,0); + + return obj; +} + +Evas_Object *create_clipper(Evas_Object *parent) +{ + Evas_Object *obj; + + obj = evas_object_rectangle_add(evas_object_evas_get(parent)); + + evas_object_size_hint_expand_set(obj, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + evas_object_size_hint_fill_set(obj, EVAS_HINT_FILL, EVAS_HINT_FILL); + evas_object_color_set(obj, 255,255,255,255); + + return obj; +} + + +Evas_Object *create_layout(Evas_Object *parent, const char *edj, const char *group) +{ + MSG_ASSERT(parent != NULL); + + Evas_Object *layout; + layout = elm_layout_add(parent); + + if ( layout == NULL ) + { + MSG_ERROR("Cannot create layout"); + return NULL; + } + + if ( elm_layout_file_set(layout, edj, group) == EINA_FALSE) + { + MSG_ERROR("Layout file set failed! %s in %s", group, edj); + evas_object_del(layout); + return NULL; + } + + evas_object_size_hint_expand_set( layout, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + evas_object_size_hint_fill_set(layout, EVAS_HINT_FILL, EVAS_HINT_FILL ); + + evas_object_show(layout); + return layout; +} + +Evas_Object *create_button(Evas_Object *parent, const char *style, const char *icon, const char *caption) +{ + Evas_Object *btn = NULL; + + btn = elm_button_add(parent); + elm_object_style_set(btn, style); + + if ( icon ) + { + Evas_Object *ic = NULL; + ic = elm_icon_add(btn); + elm_icon_file_set(ic, icon, NULL); + evas_object_size_hint_aspect_set(ic, EVAS_ASPECT_CONTROL_VERTICAL, 1, 1); + elm_icon_resizable_set(ic, EINA_TRUE, EINA_TRUE); + elm_object_part_content_set(btn, "icon", ic); + } + + if ( caption ) + { + elm_object_text_set(btn, caption); + } + + return btn; +} + + +void dump_obj(Evas_Object *obj, int lvl) +{ + Eina_List *list = evas_object_smart_members_get(obj); + + if ( lvl == 0 ) + { + int x, y, w, h; + + evas_object_geometry_get(obj, &x, &y, &w, &h); + Eina_Bool repeat = evas_object_repeat_events_get(obj); + Eina_Bool pass = evas_object_pass_events_get(obj); + Eina_Bool visible = evas_object_visible_get(obj); + Eina_Bool propagate = evas_object_propagate_events_get(obj); + + MSG_HIGH("Obj=%s(%s,0x%08x) (%d,%d,%d,%d) P%d|R%d|V%d|E%d", evas_object_name_get(obj), evas_object_type_get(obj), obj, x, y, w, h, pass, repeat, visible, propagate); + lvl++; + } + + Evas_Object *data; + Eina_List *l; + + for (l = list, data = (Evas_Object *)eina_list_data_get(l); l; l = eina_list_next(l), data = (Evas_Object *)eina_list_data_get(l)) + { + int x, y, w, h; + + evas_object_geometry_get(data, &x, &y, &w, &h); + Eina_Bool repeat = evas_object_repeat_events_get(data); + Eina_Bool pass = evas_object_pass_events_get(data); + Eina_Bool visible = evas_object_visible_get(data); + Eina_Bool propagate = evas_object_propagate_events_get(data); + + if ( lvl == 0 ) + { + MSG_HIGH("Obj=%s(%s,0x%08x) (%d,%d,%d,%d) P%d|R%d|V%d|E%d", evas_object_name_get(data), evas_object_type_get(data), data, x, y, w, h, pass, repeat, visible, propagate); + } + else + { + char *space = new char[lvl*2+1]; + + for ( int i = 0; i < lvl*2; i++) + { + space[i] = ' '; + } + + space[lvl*2] = '\0'; + + MSG_HIGH("%sObj=%s(%s,0x%08x) (%d,%d,%d,%d) P%d|R%d|V%d|E%d", space, evas_object_name_get(data), evas_object_type_get(data), data, x, y, w, h, pass, repeat, visible, propagate); + + delete[] space; + } + + dump_obj(data, lvl+1); + + } +} + +char * current_render_method(Evas *e) +{ + char *szRet = NULL; + + //get render list that usable + Eina_List *engine_list = evas_render_method_list(); + + //id of rendering method + int current_id = evas_output_method_get(e); + + //check rendering method same + Eina_List *l; + + const char *engine_name; + + for (l = engine_list, engine_name = (const char *)eina_list_data_get(l); l; l = eina_list_next(l),engine_name = (const char *)eina_list_data_get(l)) + { + //id value of specific rendering method + int engine_id = evas_render_method_lookup(engine_name); + + //"software_x11", "gl_x11" + if (engine_id == current_id) + { + MSG_HIGH("current render method is %s!", engine_name); + szRet = strdup(engine_name); + break; + } + } + + evas_render_method_list_free(engine_list); + + return szRet; +} + +Evas_Object *create_window(const char *title, int w, int h) +{ + Evas_Object *win; + + win = elm_win_add(NULL, "main", ELM_WIN_BASIC); + elm_win_title_set(win, title); + + evas_object_resize(win, w, h); + evas_object_show(win); + + return win; +} + + + +}; + + +namespace util { + +Image_Codec_Type +get_codec_type(const unsigned char *buffer, unsigned int size) +{ + if ( size < 8 ) + { + MSG_ERROR("To small buffer size : %d", size); + return eImageCodec_UNKNOWN; + } + + if ( buffer[0] == 0xff && buffer[1] == 0xd8) // JPEG + { + return eImageCodec_JPEG; + } + else if(buffer[0] == 0x89 && buffer[1] == 0x50 && buffer[2] == 0x4e && buffer[3] == 0x47 && + buffer[4] == 0x0d && buffer[5] == 0x0a && buffer[6] == 0x1a && buffer[7] == 0x0a ) + { + return eImageCodec_PNG; + } + else + { + // ("GIF87a" or "GIF89a") + + if ( memcmp(buffer, "GIF8", 4) == 0 ) + { + if (buffer[4] == '9' || buffer[4] == '7' ) + { + if ( buffer[5] == 'a') + { + return eImageCodec_GIF; + } + } + } + } + + return eImageCodec_IMAGE; +} + +Image_Codec_Type +get_codec_type(const char *filename) +{ + FILE *fp = NULL; + + fp = fopen(filename, "rb"); + + if ( fp == NULL ) + { + char error_msg[256]; + MSG_ERROR("Cannot find %s", filename); + MSG_ERROR("Cannot open file : %s", strerror_r(errno, error_msg, sizeof(error_msg)) ); + + return eImageCodec_UNKNOWN; + } + + unsigned char buffer[8]; + int readcnt = 0; + + readcnt = fread(&buffer, 1, sizeof(buffer), fp); + + if ( readcnt != sizeof(buffer) ) + { + if(feof(fp)) + { + MSG_ERROR("End Of File"); + } + if(ferror(fp)) + { + perror("fread ERROR"); + } + MSG_ERROR("Read Error. file = %s, readcnt = %d", filename, readcnt); + + fclose(fp); + return eImageCodec_UNKNOWN; + } + + fclose(fp); + + MSG_LOW("ReadCount=%d", readcnt); + return get_codec_type(buffer, readcnt); + +} + + +bool is_openGL_enabled(Evas *e) +{ + MSG_ASSERT(e != NULL ); + + Eina_List *engines, *l; + int cur_id; + int id; + void *data; + + engines = evas_render_method_list (); + if (!engines) { + MSG_ERROR("No engine is specified"); + return false; + } + + cur_id = evas_output_method_get (e); + + EINA_LIST_FOREACH (engines, l, data) { + const char *name = (char *)data; + + id = evas_render_method_lookup (name); + if (name && id == cur_id) + { + if (!strcmp (name, "gl_x11")) { + return true; + } + break; + } + } + + return false; + +} + + +}; + + diff --git a/widget/src/util/ivug-listpopup.c b/widget/src/util/ivug-listpopup.c new file mode 100755 index 0000000..6fbdc98 --- /dev/null +++ b/widget/src/util/ivug-listpopup.c @@ -0,0 +1,483 @@ +/* + * Copyright 2012 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.tizenopensource.org/license + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "ivug-debug.h" + +#include +#include "ivug-listpopup.h" + +#undef LOG_LVL +#define LOG_LVL DBG_MSG_LVL_HIGH + +#undef LOG_CAT +#define LOG_CAT "IV-POPUP" + +typedef struct { + Evas_Object *obj; + + Evas_Object *popup; + Evas_Object *parent; + Eina_List *list; + + const char *title; + const char *caption; +} ListPopup; + + +typedef struct { + Evas_Object *obj; // This object + + Elm_Object_Item *item; + + const char *iconpath; + const char *caption; + void *data; + + bool bDisabled; + +} ListPopupItem; + +#define IV_LISTPOPUP(obj) \ + (ListPopup *)(evas_object_data_get((obj), "LISTPOPUP")) + +static char * +_on_label_set(void *data, Evas_Object *obj, const char *part) +{ + IV_ASSERT( data != NULL); + + ListPopupItem *item = (ListPopupItem *)data; + + return strdup(item->caption); //dump +} + + +static void +_on_genlist_selected(void *data, Evas_Object *obj, void *event_info) +{ + MSG_ASSERT(data != NULL); + + ListPopupItem *item = data; +// ListPopup *pListPopup = IV_LISTPOPUP(item->obj); + + MSG_HIGH("Genlist item selected"); + + evas_object_smart_callback_call(item->obj, "popup,selected", item); + +} + + +static void +_on_ctxpopup_selected(void *data, Evas_Object *obj, void *event_info) +{ + MSG_ASSERT(data != NULL); + +// +// Elm_Object_Item *item = (Elm_Object_Item *)event_info; + ListPopupItem *item = data; +// ListPopup *pListPopup = IV_LISTPOPUP(item->obj); + + MSG_HIGH("Ctxpopup item selected. obj=0x%08x", item->obj); + + evas_object_smart_callback_call(item->obj, "popup,selected", item); + +} + + +static void _on_item_del(void *data, Evas_Object *obj) +{ + MSG_ASSERT(data != NULL); + + ListPopupItem *item = data; + + MSG_HIGH("Remove item"); + + if ( item->caption ) + eina_stringshare_del(item->caption); + + item->caption = NULL; + + if ( item->iconpath ) + eina_stringshare_del(item->iconpath); + item->iconpath = NULL; + + free(item); +} + + +static void +_on_popup_close(void *data, Evas_Object *obj, void *event_info) +{ + MSG_ASSERT(data != NULL); + + ListPopup *pListPopup = data; + + MSG_HIGH("Genlist Popup Dismissed"); + + evas_object_smart_callback_call(pListPopup->obj, "popup,dismissed", NULL); +} + +static void _on_genpopup_deleted(void * data, Evas * e, Evas_Object * obj, void * event_info) +{ + MSG_HIGH("Remove genlist popup"); + + ListPopup *pListPopup = data; + + if ( pListPopup->title ) + eina_stringshare_del(pListPopup->title); + + pListPopup->title = NULL; + + if ( pListPopup->popup ) + { + evas_object_del(pListPopup->popup); + } + + + free(pListPopup); +} + + +static void _on_ctxpopup_deleted(void * data, Evas * e, Evas_Object * obj, void * event_info) +{ + MSG_HIGH("Remove ctx popup"); + + ListPopup *pListPopup = data; + + if ( pListPopup->title ) + eina_stringshare_del(pListPopup->title); + + pListPopup->title = NULL; + + EINA_LIST_FREE(pListPopup->list, data) + { + _on_item_del(data, NULL); + } + + pListPopup->list = NULL; + + if ( pListPopup->popup ) + { + evas_object_del(pListPopup->popup); + } + + + free(pListPopup); +} + +static void _on_dismissed_cb(void *data, Evas_Object *obj, void *event_info) +{ + ListPopup *pListPopup = data; + + MSG_HIGH("Ctx Popup Dismissed"); + evas_object_smart_callback_call(pListPopup->obj, "popup,dismissed", NULL); +} + + +Evas_Object *ivug_listpopup_add(Evas_Object *parent) +{ + Evas_Object *obj = NULL; + +// Creating dummy object because we cannot + obj = elm_box_add(parent); + + ListPopup *pListPopup = (ListPopup *)calloc(1, sizeof(ListPopup)); + + pListPopup->parent = parent; + + pListPopup->list = NULL; + pListPopup->obj = obj; + pListPopup->title = NULL; + pListPopup->caption = NULL; + evas_object_data_set(obj, "LISTPOPUP", (void *)pListPopup); + + MSG_HIGH("List popup is added. obj=0x%08x", obj); + + return obj; +} + + +Ivug_ListPopup_Item *ivug_listpopup_item_append(Evas_Object *obj, const char *iconpath, const char *caption, void *data) +{ + ListPopup *pListPopup = IV_LISTPOPUP(obj); + + ListPopupItem *item = calloc(1,sizeof(ListPopupItem)); + + item->obj = obj; + + if (iconpath ) + { + item->iconpath = eina_stringshare_add(iconpath); + } + + if ( caption ) + { + item->caption = eina_stringshare_add(caption); + } + + item->bDisabled = false; + item->data = data; + + MSG_HIGH("Item append: %s", caption); + + pListPopup->list = eina_list_append(pListPopup->list, item); + + return item; +} + + +Ivug_ListPopup_Item *ivug_listpopup_item_prepend(Evas_Object *obj, const char *iconpath, const char *caption, void *data) +{ + ListPopup *pListPopup = IV_LISTPOPUP(obj); + + ListPopupItem *item = malloc(sizeof(ListPopupItem)); + + item->obj = obj; + item->iconpath = eina_stringshare_add(item->iconpath); + item->caption = eina_stringshare_add(item->caption); + item->bDisabled = false; + item->data = data; + + MSG_HIGH("Item prepend: %s", caption); + + pListPopup->list = eina_list_prepend(pListPopup->list, item); + + return item; +} + + +Eina_List *ivug_listpopup_items_get(Evas_Object *obj) +{ + ListPopup *pListPopup = IV_LISTPOPUP(obj); + + return pListPopup->list; +} + + +void ivug_listpopup_item_disabled_set(Ivug_ListPopup_Item *item) +{ + ListPopupItem *item_ = item; + + item_->bDisabled = true; +} + +void ivug_listpopup_item_enabled_set(Ivug_ListPopup_Item *item) +{ + ListPopupItem *item_ = item; + + item_->bDisabled = false; + +} + +void *ivug_listpopup_item_get_data(Ivug_ListPopup_Item *item) +{ + ListPopupItem *item_ = (Ivug_ListPopup_Item *)item; + + return item_->data; +} + +const char *ivug_listpopup_item_get_text(Ivug_ListPopup_Item *item) +{ + ListPopupItem *item_ = (Ivug_ListPopup_Item *)item; + + return item_->caption; +} + + +void ivug_listpopup_title_set(Evas_Object *obj, const char* title) +{ + ListPopup *pListPopup = IV_LISTPOPUP(obj); + + MSG_ASSERT(title != NULL); + + pListPopup->title = eina_stringshare_add(title); + + MSG_MED("Popup title set : %s", title); +} + +void ivug_listpopup_button_set(Evas_Object *obj, const char* caption) +{ + ListPopup *pListPopup = IV_LISTPOPUP(obj); + + MSG_ASSERT(caption != NULL); + + pListPopup->caption = eina_stringshare_add(caption); + + MSG_MED("Popup caption set : %s", caption); +} + +bool ivug_listpopup_popup_show(Evas_Object *obj) +{ + ListPopup *pListPopup = IV_LISTPOPUP(obj); + + if ( pListPopup->popup ) + { + MSG_WARN("Previous popup is remained"); + } + + Evas_Object *popup; +// create popup + popup = elm_popup_add(pListPopup->parent); + + if (!popup) + { + MSG_ERROR("Error : popup create failed."); + return false; + } + + pListPopup->popup = popup; + + elm_object_style_set(popup, "min_menustyle"); + elm_object_part_text_set(popup, "title,text", pListPopup->title); + + evas_object_size_hint_weight_set(popup, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + evas_object_size_hint_weight_set(popup, EVAS_HINT_FILL, EVAS_HINT_FILL); + + Evas_Object *btn_close = NULL; + + if ( pListPopup->caption ) + { + btn_close = elm_button_add(popup); + elm_object_text_set(btn_close, pListPopup->caption); + elm_object_part_content_set(popup, "button1", btn_close); + } + +// create genlist + Evas_Object *genlist; + static Elm_Genlist_Item_Class itc = {0,}; + + genlist = elm_genlist_add(popup); + + itc.version = ELM_GENLIST_ITEM_CLASS_VERSION; + itc.item_style = "1text"; + itc.func.text_get = _on_label_set; + itc.func.content_get = NULL; + itc.func.state_get = NULL; + itc.func.del = _on_item_del; + + evas_object_size_hint_weight_set(genlist, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + evas_object_size_hint_align_set(genlist, EVAS_HINT_FILL, EVAS_HINT_FILL); + + int count = eina_list_count(pListPopup->list); + + ListPopupItem *pItem = NULL; + Eina_List *tmp; + Elm_Object_Item *gItem; + + EINA_LIST_FOREACH(pListPopup->list, tmp, pItem) + { + MSG_MED("Add popup item. %s", pItem->caption); + gItem = elm_genlist_item_append(genlist, &itc, pItem, NULL /* parent */, ELM_GENLIST_ITEM_NONE, _on_genlist_selected, pItem); + pItem->item = gItem; + + elm_object_item_disabled_set(gItem, pItem->bDisabled); + } + + +// Put together + +#define GET_POPUP_HEIGHT(icnt) (((113*icnt-1) > 408) ? (408) : (113*icnt-1)) +#define GET_POPUP_WIDTH(icnt) (614) + + Evas_Object *box; + box = elm_box_add(popup); + evas_object_size_hint_min_set(box, GET_POPUP_WIDTH(count) * elm_config_scale_get(), GET_POPUP_HEIGHT(count) * elm_config_scale_get()); + evas_object_show(genlist); + elm_box_pack_end(box, genlist); + elm_object_content_set(popup, box); + + if ( btn_close ) + { + evas_object_smart_callback_add(btn_close, "clicked", _on_popup_close, pListPopup); + } + + evas_object_event_callback_add(pListPopup->obj, EVAS_CALLBACK_DEL, _on_genpopup_deleted, pListPopup); + + MSG_HIGH("Show Genlist Popup"); + + evas_object_show(popup); + + return true; +} + + +bool ivug_listpopup_context_show(Evas_Object *obj, Evas_Object *hover, int x, int y) +{ + ListPopup *pListPopup = IV_LISTPOPUP(obj); + + if ( pListPopup->popup ) + { + MSG_WARN("Previous popup is remained"); + } + + Evas_Object* ctxpopup = NULL; + ctxpopup = elm_ctxpopup_add(obj); + + if (!ctxpopup) + { + MSG_ERROR("Error : popup create failed."); + return false; + } + + pListPopup->popup = ctxpopup; + + elm_ctxpopup_hover_parent_set(ctxpopup, hover); + + elm_ctxpopup_direction_priority_set(ctxpopup, ELM_CTXPOPUP_DIRECTION_DOWN, + ELM_CTXPOPUP_DIRECTION_RIGHT, + ELM_CTXPOPUP_DIRECTION_LEFT, + ELM_CTXPOPUP_DIRECTION_UP); + + + ListPopupItem *pItem = NULL; + Eina_List *tmp; + Elm_Object_Item *gItem; + + Evas_Object *icon; + + EINA_LIST_FOREACH(pListPopup->list, tmp, pItem) + { + MSG_MED("Add popup item. %s", pItem->caption); + + if ( pItem->iconpath ) + { + icon = elm_icon_add(ctxpopup); + elm_icon_file_set(icon, pItem->iconpath, NULL); + } + else + { + icon = NULL; + } + + gItem = elm_ctxpopup_item_append(ctxpopup, pItem->caption, icon, _on_ctxpopup_selected, pItem); + pItem->item = gItem; + + elm_object_item_disabled_set(gItem, pItem->bDisabled); + } + + evas_object_event_callback_add(pListPopup->obj, EVAS_CALLBACK_DEL, _on_ctxpopup_deleted, pListPopup); + + evas_object_smart_callback_add(ctxpopup, "dismissed", _on_dismissed_cb, pListPopup); + + evas_object_move(ctxpopup, x, y); + + MSG_HIGH("Show Context Popup(%d,%d)", x, y); + + evas_object_show(ctxpopup); + + return true; +} + + -- 2.7.4