Upload initial code 11/141111/3
authorsungwook79.park <sungwook79.park@samsung.com>
Fri, 28 Jul 2017 07:23:41 +0000 (16:23 +0900)
committersungwook79.park <sungwook79.park@samsung.com>
Fri, 28 Jul 2017 07:40:51 +0000 (16:40 +0900)
Change-Id: I6af96280a49f83334e164edc661066f8af2cc2fc
Signed-off-by: sungwook79.park <sungwook79.park@samsung.com>
215 files changed:
Build/appendix.mk [new file with mode: 0644]
Build/basedef.mk [new file with mode: 0644]
Build/build_c.mk [new file with mode: 0644]
Build/build_edc.mk [new file with mode: 0644]
Build/build_po.mk [new file with mode: 0644]
Build/flags.mk [new file with mode: 0644]
Build/funcs.mk [new file with mode: 0644]
Build/makefile [new file with mode: 0644]
Build/makefile.mk [new file with mode: 0644]
Build/platform.mk [new file with mode: 0644]
Build/tooldef.mk [new file with mode: 0644]
build_def.prop [new file with mode: 0644]
edje_images/b_ic_press_full_circle_bg.png [new file with mode: 0755]
edje_images/gear_tutorial_bg.png [new file with mode: 0755]
edje_images/gear_tutorial_bg_focus.png [new file with mode: 0755]
edje_images/gear_tutorial_bt_cancel_normal.png [new file with mode: 0755]
edje_images/gear_tutorial_bt_cancel_press.png [new file with mode: 0755]
edje_images/gear_tutorial_rotate_ccw.png [new file with mode: 0755]
edje_images/gear_tutorial_rotate_cw.png [new file with mode: 0755]
edje_images/wi_more_option_bg.png [new file with mode: 0755]
inc/DrDebug.h [new file with mode: 0755]
inc/DrDefine.h [new file with mode: 0755]
inc/app-assist-efl/IWWindowController.h [new file with mode: 0755]
inc/app-assist-efl/WApp.h [new file with mode: 0755]
inc/app-assist-efl/WAppEventHandler.h [new file with mode: 0755]
inc/app-assist-efl/WContentViewController.h [new file with mode: 0755]
inc/app-assist-efl/WDebugBase.h [new file with mode: 0755]
inc/app-assist-efl/WDefine.h [new file with mode: 0755]
inc/app-assist-efl/WEvasObject.h [new file with mode: 0755]
inc/app-assist-efl/WGengridItem.h [new file with mode: 0755]
inc/app-assist-efl/WGenlistItem.h [new file with mode: 0755]
inc/app-assist-efl/WMenuPopupController.h [new file with mode: 0755]
inc/app-assist-efl/WNaviframeController.h [new file with mode: 0755]
inc/app-assist-efl/WPageSlideViewController.h [new file with mode: 0755]
inc/app-assist-efl/WPopupController.h [new file with mode: 0755]
inc/app-assist-efl/WSignal.h [new file with mode: 0755]
inc/app-assist-efl/WSignalIdGenerator.h [new file with mode: 0755]
inc/app-assist-efl/WSignalImpl.h [new file with mode: 0755]
inc/app-assist-efl/WUiThread.h [new file with mode: 0755]
inc/app-assist-efl/WUiTimer.h [new file with mode: 0755]
inc/app-assist-efl/WViewController.h [new file with mode: 0755]
inc/app-assist-efl/WWindowController.h [new file with mode: 0755]
packaging/projects.list [new file with mode: 0755]
project_def.prop [new file with mode: 0644]
res/edje/animations2circle.edc [new file with mode: 0755]
res/edje/btneffect.edc [new file with mode: 0755]
res/edje/drawing_layout.edc [new file with mode: 0755]
res/edje/drawing_popup.edc [new file with mode: 0755]
res/edje/drawing_stroke.edc [new file with mode: 0755]
res/images/b_ic_press_full_circle_bg_a.png [new file with mode: 0755]
res/images/b_more_option_icon_bg.png [new file with mode: 0755]
res/images/b_more_option_icon_select_bg.png [new file with mode: 0755]
res/images/b_slider_icon_minus.png [new file with mode: 0755]
res/images/b_slider_icon_plus.png [new file with mode: 0755]
res/images/drawing_popup_btn_check.png [new file with mode: 0755]
res/images/drawing_popup_btn_delete.png [new file with mode: 0755]
res/images/wear_comm_stroke_option.png [new file with mode: 0755]
res/images/wi_drawing_bg_01.png [new file with mode: 0755]
res/images/wi_drawing_bg_02.png [new file with mode: 0755]
res/images/wi_drawing_bg_03.png [new file with mode: 0755]
res/images/wi_drawing_bg_04.png [new file with mode: 0755]
res/images/wi_drawing_bg_pattern.png [new file with mode: 0755]
res/images/wi_drawing_bg_pattern_negative.png [new file with mode: 0644]
res/images/wi_drawing_more_options_erase.png [new file with mode: 0755]
res/images/wi_drawing_more_options_icon.png [new file with mode: 0755]
res/images/wi_drawing_select_button_center.png [new file with mode: 0755]
res/po/ar.po [new file with mode: 0755]
res/po/as.po [new file with mode: 0755]
res/po/az.po [new file with mode: 0755]
res/po/be_BY.po [new file with mode: 0755]
res/po/bg.po [new file with mode: 0755]
res/po/bn.po [new file with mode: 0755]
res/po/bn_BD.po [new file with mode: 0755]
res/po/bs_BA.po [new file with mode: 0755]
res/po/ca.po [new file with mode: 0755]
res/po/cs.po [new file with mode: 0755]
res/po/da.po [new file with mode: 0755]
res/po/de.po [new file with mode: 0755]
res/po/el_GR.po [new file with mode: 0755]
res/po/en.po [new file with mode: 0755]
res/po/en_PH.po [new file with mode: 0755]
res/po/en_US.po [new file with mode: 0755]
res/po/es_ES.po [new file with mode: 0755]
res/po/es_US.po [new file with mode: 0755]
res/po/et.po [new file with mode: 0755]
res/po/eu.po [new file with mode: 0755]
res/po/fa.po [new file with mode: 0755]
res/po/fi.po [new file with mode: 0755]
res/po/fr.po [new file with mode: 0755]
res/po/fr_CA.po [new file with mode: 0755]
res/po/ga.po [new file with mode: 0755]
res/po/gl.po [new file with mode: 0755]
res/po/gu.po [new file with mode: 0755]
res/po/he.po [new file with mode: 0755]
res/po/hi.po [new file with mode: 0755]
res/po/hr.po [new file with mode: 0755]
res/po/hu.po [new file with mode: 0755]
res/po/hy.po [new file with mode: 0755]
res/po/id.po [new file with mode: 0755]
res/po/is.po [new file with mode: 0755]
res/po/it_IT.po [new file with mode: 0755]
res/po/ja_JP.po [new file with mode: 0755]
res/po/ka.po [new file with mode: 0755]
res/po/kk.po [new file with mode: 0755]
res/po/km.po [new file with mode: 0755]
res/po/kn.po [new file with mode: 0755]
res/po/ko_KR.po [new file with mode: 0755]
res/po/ky_KG.po [new file with mode: 0755]
res/po/lo.po [new file with mode: 0755]
res/po/lt.po [new file with mode: 0755]
res/po/lv.po [new file with mode: 0755]
res/po/mk.po [new file with mode: 0755]
res/po/ml.po [new file with mode: 0755]
res/po/mn_MN.po [new file with mode: 0755]
res/po/mr.po [new file with mode: 0755]
res/po/ms.po [new file with mode: 0755]
res/po/my_MM.po [new file with mode: 0755]
res/po/my_ZG.po [new file with mode: 0755]
res/po/nb.po [new file with mode: 0755]
res/po/ne.po [new file with mode: 0755]
res/po/nl.po [new file with mode: 0755]
res/po/or.po [new file with mode: 0755]
res/po/pa.po [new file with mode: 0755]
res/po/pl.po [new file with mode: 0755]
res/po/pl_SP.po [new file with mode: 0755]
res/po/pt_BR.po [new file with mode: 0755]
res/po/pt_PT.po [new file with mode: 0755]
res/po/ro.po [new file with mode: 0755]
res/po/ru_RU.po [new file with mode: 0755]
res/po/si.po [new file with mode: 0755]
res/po/sk.po [new file with mode: 0755]
res/po/sl.po [new file with mode: 0755]
res/po/sq.po [new file with mode: 0755]
res/po/sr.po [new file with mode: 0755]
res/po/sv.po [new file with mode: 0755]
res/po/ta.po [new file with mode: 0755]
res/po/te.po [new file with mode: 0755]
res/po/tg_TJ.po [new file with mode: 0755]
res/po/th.po [new file with mode: 0755]
res/po/tk_TM.po [new file with mode: 0755]
res/po/tl.po [new file with mode: 0755]
res/po/tr_TR.po [new file with mode: 0755]
res/po/uk.po [new file with mode: 0755]
res/po/ur.po [new file with mode: 0755]
res/po/uz.po [new file with mode: 0755]
res/po/vi.po [new file with mode: 0755]
res/po/zh_CN.po [new file with mode: 0755]
res/po/zh_HK.po [new file with mode: 0755]
res/po/zh_TW.po [new file with mode: 0755]
shared/res/org.tizen.sketch.png [new file with mode: 0755]
shared/res/tables/org.tizen.w-drawing_color.xml [new file with mode: 0755]
shared/res/tables/org.tizen.w-drawing_font.xml [new file with mode: 0755]
src/CDrUtil.cpp [new file with mode: 0644]
src/CDrUtil.h [new file with mode: 0644]
src/EventManager/CDrEvent.h [new file with mode: 0755]
src/EventManager/CDrEventListener.h [new file with mode: 0755]
src/EventManager/CDrEventManager.cpp [new file with mode: 0644]
src/EventManager/CDrEventManager.h [new file with mode: 0755]
src/EventManager/CDrSingleton.h [new file with mode: 0755]
src/MediaDB/CDrMediaContent.cpp [new file with mode: 0755]
src/MediaDB/CDrMediaContent.h [new file with mode: 0755]
src/Singleton.h [new file with mode: 0644]
src/View/CDrMainView.cpp [new file with mode: 0755]
src/View/CDrMainView.h [new file with mode: 0755]
src/View/CDrStrokeView.cpp [new file with mode: 0755]
src/View/CDrStrokeView.h [new file with mode: 0755]
src/app-assist-efl/WApp.cpp [new file with mode: 0644]
src/app-assist-efl/WAppEventHandler.cpp [new file with mode: 0644]
src/app-assist-efl/WContentViewController.cpp [new file with mode: 0644]
src/app-assist-efl/WContentViewControllerImpl.cpp [new file with mode: 0644]
src/app-assist-efl/WEvasObject.cpp [new file with mode: 0644]
src/app-assist-efl/WGengridItem.cpp [new file with mode: 0644]
src/app-assist-efl/WGenlistItem.cpp [new file with mode: 0644]
src/app-assist-efl/WMenuPopupController.cpp [new file with mode: 0644]
src/app-assist-efl/WMenuPopupControllerImpl.cpp [new file with mode: 0644]
src/app-assist-efl/WNaviframeController.cpp [new file with mode: 0644]
src/app-assist-efl/WPageSlideViewController.cpp [new file with mode: 0644]
src/app-assist-efl/WPopupController.cpp [new file with mode: 0644]
src/app-assist-efl/WSignalIdGenerator.cpp [new file with mode: 0644]
src/app-assist-efl/WUiThread.cpp [new file with mode: 0644]
src/app-assist-efl/WUiTimer.cpp [new file with mode: 0644]
src/app-assist-efl/WUiTimerImpl.cpp [new file with mode: 0644]
src/app-assist-efl/WUiTimerImpl.h [new file with mode: 0644]
src/app-assist-efl/WVersion.cpp [new file with mode: 0644]
src/app-assist-efl/WViewController.cpp [new file with mode: 0644]
src/app-assist-efl/WViewControllerImpl.cpp [new file with mode: 0644]
src/app-assist-efl/WViewControllerImpl.h [new file with mode: 0644]
src/app-assist-efl/WWindowController.cpp [new file with mode: 0644]
src/app-assist-efl/inc/WContentViewControllerImpl.h [new file with mode: 0644]
src/app-assist-efl/inc/WDebugInternal.h [new file with mode: 0755]
src/app-assist-efl/inc/WDefineInternal.h [new file with mode: 0755]
src/app-assist-efl/inc/WMenuPopupControllerImpl.h [new file with mode: 0644]
src/app/CDrApp.cpp [new file with mode: 0755]
src/app/CDrApp.h [new file with mode: 0755]
src/app/CDrAppData.cpp [new file with mode: 0755]
src/app/CDrAppData.h [new file with mode: 0755]
src/controls/CDrCairoImage.cpp [new file with mode: 0755]
src/controls/CDrCairoImage.h [new file with mode: 0755]
src/controls/CDrControl.h [new file with mode: 0755]
src/controls/CDrControlManager.cpp [new file with mode: 0755]
src/controls/CDrControlManager.h [new file with mode: 0755]
src/controls/CDrDrawingView.cpp [new file with mode: 0755]
src/controls/CDrDrawingView.h [new file with mode: 0755]
src/controls/CDrHistoryControl.cpp [new file with mode: 0755]
src/controls/CDrHistoryControl.h [new file with mode: 0755]
src/controls/CDrTutorialView.cpp [new file with mode: 0755]
src/controls/CDrTutorialView.h [new file with mode: 0755]
src/controls/Drawing.cpp [new file with mode: 0755]
src/controls/Drawing.h [new file with mode: 0755]
src/controls/History.cpp [new file with mode: 0755]
src/controls/History.h [new file with mode: 0755]
src/main.cpp [new file with mode: 0755]
src/popup/CDrClosePopup.cpp [new file with mode: 0755]
src/popup/CDrClosePopup.h [new file with mode: 0755]
tizen-manifest.xml [new file with mode: 0755]

diff --git a/Build/appendix.mk b/Build/appendix.mk
new file mode 100644 (file)
index 0000000..2e06c34
--- /dev/null
@@ -0,0 +1 @@
+# Appendix\r
diff --git a/Build/basedef.mk b/Build/basedef.mk
new file mode 100644 (file)
index 0000000..a762983
--- /dev/null
@@ -0,0 +1,34 @@
+# Add inputs and outputs from these tool invocations to the build variables
+
+
+OS_NAME := $(shell $(UNAME))
+
+
+#ifeq ($(origin BUILD_CONFIG), undefined)
+BUILD_CONFIG ?= Debug
+#endif
+
+#ifeq ($(origin ARCH), undefined)
+ARCH ?= i386
+#endif
+
+#ifeq ($(origin PROJPATH), undefined)
+PROJPATH ?= .
+#endif
+
+
+#ifeq ($(origin PROJ_PATH), undefined)
+PROJ_PATH ?= $(PROJPATH)
+#endif
+
+#ifeq ($(strip $(OUTPUT_DIR)),)
+#OUTPUT_DIR ?= $(PROJ_PATH)/$(BUILD_CONFIG)
+#endif
+
+#ifeq ($(strip $(BUILD_ARCH)),)
+BUILD_ARCH ?= $(ARCH)
+#endif
+
+#ifeq ($(strip $(ENVENTOR_PATH)),)
+ENVENTOR_PATH ?= $(SDK_TOOLPATH)/enventor
+#endif
diff --git a/Build/build_c.mk b/Build/build_c.mk
new file mode 100644 (file)
index 0000000..5fffeea
--- /dev/null
@@ -0,0 +1,113 @@
+# C/C++ build script
+
+
+_FUNC_EXT2O = $(patsubst %.$(3),$(1)/%.o,$(2))
+_FUNC_C2O = $(call _FUNC_EXT2O,$(1),$(2),c)
+_FUNC_CPP2O = $(call _FUNC_EXT2O,$(1),$(2),cpp)
+
+
+# parameter :
+#  $(1) - C/C++ soruce file
+#  $(2) - output path
+#  $(3) - .ext
+#  $(4) - unique id
+CONVERT_ESC_EXT_TO_O = $(addprefix $(2)/,$(notdir $(patsubst %.$(3),%-$(4).o,$(1))))
+
+#CONVERT_ESC_C_TO_O = $(call CONVERT_ESC_EXT_TO_O,$(1),$(2),c)
+#CONVERT_ESC_CPP_TO_O = $(call CONVERT_ESC_EXT_TO_O,$(1),$(2),cpp)
+
+
+# parameter :
+#  $(1) - encoded one C/C++ soruce file
+#  $(2) - output path
+#  $(3) - ext title (C/C++)
+#  $(4) - ext (c/cpp)
+#  $(5) - compiler ($(CC)/$(CXX))
+#  $(6) - build opt
+#  $(7) - build opt file
+# output :
+#  $(8) - output files list
+define C_BUILD_PROC_RAW
+$(call CONVERT_ESC_EXT_TO_O,$(1),$(2),$(4),$(8)) : $(call DECODE_4MAKE,$(1)) $(7)
+       @echo '  Building file: $$<'
+       @echo '  Invoking: $(3) Compiler'
+       $$(call MAKEDIRS,$$(@D))
+       $(5) -c "$$<" -o "$$@" $(6) -Wp,@$(7)
+       @echo '  Finished building: $$<'
+$(9) += $(call CONVERT_ESC_EXT_TO_O,$(1),$(2),$(4),$(8))
+endef
+
+
+# parameter :
+#  $(1) - output paths
+#  $(2) - src paths
+#  $(3) - inc paths
+#  $(4) - inc files
+#  $(5) - Defs
+#  $(6) - UnDefs
+#  $(7) - compiler opt
+#  $(8) - compiler opt file
+#  $(9) - ext title (C/C++)
+#  $(10) - ext (c/cpp)
+#  $(11) - compiler ($(CC)/$(CXX))
+# output :
+#  $(12) - OBJS
+# return :
+#  none
+define C_PROC_RAW
+
+_OUTPUT_DIR := $$(strip $(1))#
+_SRCS := $(2)#
+_INCS := $(3)#
+_INC_FILES := $(4)#
+_DEFS := $(5)#
+_UNDEFS := $(6)#
+
+_OPT := $(7)
+_OPT_FILE := $(8)
+
+_EXT_TITLE := $(9)
+_EXT := $(10)
+_COMPILER := $(11)
+
+#_OUTPUT_FILES := $(12)
+
+_ENC_SRCS := $$(call ENCODE_4MAKE,$$(_SRCS))
+_ENC_SRCS := $$(filter %.$$(_EXT),$$(_ENC_SRCS))
+
+ifneq ($$(strip $$(_SRCS)),)
+
+_NORMAL_SRCS := $$(filter-out %*.$$(_EXT),$$(_ENC_SRCS))
+_WIDLCARD_SRCS := $$(filter %*.$$(_EXT),$$(_ENC_SRCS))
+
+_ALL_SRCS := $$(call DECODE_4MAKE,$$(_NORMAL_SRCS)) \
+             $$(foreach var,$$(_WIDLCARD_SRCS),$$(call FIND_FILES_4MAKE,$$(call DECODE_4MAKE,$$(var))))
+
+ifneq ($$(strip $$(_ALL_SRCS)),)
+
+_ENC_SRCS := $$(call ENCODE_4MAKE,$$(_ALL_SRCS))
+
+_CDEFS := $$(CDEFS)
+_CDEFS += $$(addprefix -D,$$(_DEFS))
+_CDEFS += $$(addprefix -U,$$(_UNDEFS))
+
+_ENC_C_INCS := $$(call ENCODE_4MAKE,$$(_INCS))
+_ENC_C_INCS := $$(addprefix -I,$$(_ENC_C_INCS))
+
+_ENC_INC_FILES := $$(call ENCODE_4MAKE,$$(_INC_FILES))
+_ENC_INC_FILES += $$(addprefix -include,$$(_ENC_INC_FILES))
+
+_C_INCS := $$(call DECODE_4MAKE,$$(_ENC_C_INCS) $$(_ENC_C_INC_FILES))
+
+_DEFS := $$(_CDEFS) $$(_C_INCS) -I"pch" $$(_OPT)
+
+_UNIQUE_ID = $$(firstword $$(shell echo $$(var) | $$(CKSUM)))
+
+$$(foreach var,$$(_ENC_SRCS),$$(eval $$(call C_BUILD_PROC_RAW,$$(var),$$(_OUTPUT_DIR),$$(_EXT_TITLE),$$(_EXT),$$(_COMPILER),$$(_DEFS),$$(_OPT_FILE),$$(_UNIQUE_ID),$(12))))
+
+endif  # (_(strip _(_ALL_SRCS)),)
+
+endif  # (_(strip _(_SRCS)),)
+
+
+endef
diff --git a/Build/build_edc.mk b/Build/build_edc.mk
new file mode 100644 (file)
index 0000000..6f85fdd
--- /dev/null
@@ -0,0 +1,81 @@
+# EDC build script
+
+
+FUNC_EDC2EDJ = $(patsubst %.edc,$(2)/%.edj,$(1))
+
+# parameter :
+#  $(1) - C/C++ soruce file
+#  $(2) - output path
+CONVERT_ESC_EDC_TO_EDJ = $(call CONVERT_4MAKE_TO_OUT,$(call FUNC_EDC2EDJ,$(1),$(2)))
+
+
+# parameter :
+#  $(1) - encoded one C/C++ soruce file
+#  $(2) - output path
+#  $(3) - build opt
+# output :
+#  $(4) - output files list
+define EDJ_BUILD_PROC_RAW
+$(call CONVERT_ESC_EDC_TO_EDJ,$(1),$(2)) : $(call DECODE_4MAKE,$(1))
+       @echo '  Building file: $$<'
+       @echo '  Invoking: EDC Resource Compiler'
+       $$(call MAKEDIRS,$$(@D))
+       $$(EDJE_CC) $(3) "$$<" "$$@"
+       @echo '  Finished building: $$<'
+$(4) += $(call CONVERT_ESC_EDC_TO_EDJ,$(1),$(2))
+endef
+
+
+# parameter :
+#  $(1) - output paths
+#  $(2) - src paths
+#  $(3) - image inc paths
+#  $(4) - sound inc paths
+#  $(5) - font inc paths
+# output :
+#  $(6) - OBJS 
+# return :
+#  none
+define EDJ_PROC_RAW
+
+_OUTPUT_DIR := $$(strip $(1))#
+_SRCS := $(2)# 
+_IMAGE_DIRS := $(3)# 
+_SOUND_DIRS := $(4)# 
+_FONT_DIRS := $(5)# 
+
+ifneq ($$(strip $$(_SRCS)),)
+
+_ENC_SRCS := $$(call ENCODE_4MAKE,$$(_SRCS)) 
+
+_NORMAL_SRCS := $$(filter-out %*.edc,$$(_ENC_SRCS))
+_WIDLCARD_SRCS := $$(filter %*.edc,$$(_ENC_SRCS))
+
+_ALL_SRCS := $$(call DECODE_4MAKE,$$(_NORMAL_SRCS)) \
+             $$(foreach var,$$(_WIDLCARD_SRCS),$$(call FIND_FILES_4MAKE,$$(call DECODE_4MAKE,$$(var))))
+
+ifneq ($$(strip $$(_ALL_SRCS)),)
+
+_ENC_SRCS := $$(call ENCODE_4MAKE,$$(_ALL_SRCS)) 
+
+_COMPILER_FLAGS := -id "$$(ENVENTOR_SHARED_RES_PATH)/images"
+_COMPILER_FLAGS += -sd "$$(ENVENTOR_SHARED_RES_PATH)/sounds"
+_COMPILER_FLAGS += -fd "$$(ENVENTOR_SHARED_RES_PATH)/fonts"
+
+ifneq ($$(strip $$(_IMAGE_DIRS)),)
+_COMPILER_FLAGS += $$(addprefix -id ,$$(_IMAGE_DIRS))
+endif
+ifneq ($$(strip $$(_SOUND_DIRS)),)
+_COMPILER_FLAGS += $$(addprefix -sd ,$$(_SOUND_DIRS))
+endif
+ifneq ($$(strip $$(_FONT_DIRS)),)
+_COMPILER_FLAGS += $$(addprefix -fd ,$$(_FONT_DIRS))
+endif
+
+$$(foreach var,$$(_ENC_SRCS),$$(eval $$(call EDJ_BUILD_PROC_RAW,$$(var),$$(_OUTPUT_DIR),$$(_COMPILER_FLAGS),$(6))))
+
+endif  # (_(strip _(_ALL_SRCS)),)
+
+endif  # (_(strip _(_SRCS)),)
+
+endef
diff --git a/Build/build_po.mk b/Build/build_po.mk
new file mode 100644 (file)
index 0000000..d88d71a
--- /dev/null
@@ -0,0 +1,64 @@
+# PO build script
+
+
+_FUNC_PO2MO = $(patsubst %.po,$(2)/res/locale/%/LC_MESSAGES/$(3).mo,$(notdir $(1)))
+
+
+# parameter :
+#  $(1) - C/C++ soruce file
+#  $(2) - output path
+#  $(3) - app name
+CONVERT_ESC_PO_TO_MO = $(call CONVERT_4MAKE_TO_OUT,$(call _FUNC_PO2MO,$(1),$(2),$(3)))
+
+
+# parameter :
+#  $(1) - encoded one C/C++ soruce file
+#  $(2) - output path
+#  $(3) - app name
+# output :
+#  $(4) - output files list
+define MO_BUILD_PROC_RAW
+$(call CONVERT_ESC_PO_TO_MO,$(1),$(2),$(3)) : $(call DECODE_4MAKE,$(1))
+       @echo '  Building file: $$<'
+       @echo '  Invoking: msgfmt String Formatter'
+       $$(call MAKEDIRS,$$(@D))
+       $$(MSGFMT) -o "$$@" "$$<"
+       @echo '  Finished building: $$<'
+$(4) += $(call CONVERT_ESC_PO_TO_MO,$(1),$(2),$(3))
+endef
+
+# parameter :
+#  $(1) - output dir
+#  $(2) - src paths
+#  $(3) - app name
+# output :
+#  $(4) - OBJS 
+
+define MO_PROC_RAW
+
+_OUTPUT_DIR := $(1)
+_SRCS := $(2)
+_APPNAME := $(3)
+
+ifneq ($$(strip $$(_SRCS)),)
+
+_ENC_SRCS := $$(call ENCODE_4MAKE,$$(_SRCS)) 
+
+_NORMAL_SRCS := $$(filter-out %*.po,$$(_ENC_SRCS))
+_WIDLCARD_SRCS := $$(filter %*.po,$$(_ENC_SRCS))
+
+_ALL_SRCS := $$(call DECODE_4MAKE,$$(_NORMAL_SRCS)) \
+             $$(foreach var,$$(_WIDLCARD_SRCS),$$(call FIND_FILES_4MAKE,$$(call DECODE_4MAKE,$$(var))))
+
+ifneq ($$(strip $$(_ALL_SRCS)),)
+
+_ENC_SRCS := $$(call ENCODE_4MAKE,$$(_ALL_SRCS)) 
+
+$$(foreach var,$$(_ENC_SRCS),$$(eval $$(call MO_BUILD_PROC_RAW,$$(var),$$(_OUTPUT_DIR),$$(_APPNAME),$(4))))
+
+endif  # (_(strip _(_ALL_SRCS)),)
+
+endif  # (_(strip _(_SRCS)),)
+
+endef
diff --git a/Build/flags.mk b/Build/flags.mk
new file mode 100644 (file)
index 0000000..79d154e
--- /dev/null
@@ -0,0 +1,16 @@
+
+DEBUG_OP = -D_DEBUG 
+CPP_DEBUG_OP = -g3 -D_DEBUG 
+
+OPTIMIZATION_OP = 
+CPP_OPTIMIZATION_OP = -O2 
+
+COMPILE_FLAGS = $(DEBUG_OP) $(OPTIMIZATION_OP) 
+
+CPP_COMPILE_FLAGS = $(CPP_DEBUG_OP) $(CPP_OPTIMIZATION_OP) -std=c++0x -c -fmessage-length=0 -fvisibility=hidden -fvisibility-inlines-hidden -c -fmessage-length=0 -fPIC 
+
+LINK_FLAGS = -Xlinker --as-needed -Xlinker -O1 -Xlinker -hash-style=gnu -shared -Wl,--no-undefined 
+
+AR_FLAGS = 
+
+EDC_COMPILE_FLAGS = 
\ No newline at end of file
diff --git a/Build/funcs.mk b/Build/funcs.mk
new file mode 100644 (file)
index 0000000..3ba778b
--- /dev/null
@@ -0,0 +1,50 @@
+
+BSLASH := \\#
+NULL_CHAR := #
+SPACE := \ #
+COLON := :#
+DOTDOT := ..#
+SPACE_ESC := &sp;#
+COLON_ESC := &co;#
+SPACE_OUT := ~sp~#
+COLON_OUT := ~co~#
+DOTDOT_OUT := ~dtdt~#
+
+BSLASH2SLASH = $(subst $(BSLASH),/,$(1))
+
+REMOVE_TAIL = $(patsubst %/,%,$(1))
+
+#LOWER_CASE = $(shell echo translit($(1),[A-Z],[a-z])|$(M4))
+LOWER_CASE = $(shell echo $(1)|$(TR) [A-Z] [a-z])
+
+#ifneq ($(findstring Windows,$(OS)),)
+# ...
+#endif
+
+FIND_FILES = $(shell $(FIND) $(1)/$(2) | $(SED) 's/^$(subst /,$(BSLASH)/,$(1))$(BSLASH)///')
+FIND_FILES_ESC = $(shell $(FIND) $(1)/$(2) | $(SED) 's/^$(subst /,$(BSLASH)/,$(1))$(BSLASH)///' -e 's/:/$(BSLASH)&co;/g' -e 's/$(BSLASH) /$(BSLASH)&sp;/g')
+FIND_FILES_4MAKE = $(shell $(FIND) $(1)/$(2) | $(SED) 's/^$(subst /,$(BSLASH)/,$(1))$(BSLASH)///')
+
+FIND_FILES_ABS = $(shell $(FIND) $(1))
+FIND_FILES_ABS_4MAKE = $(shell $(FIND) $(1) -e 's/$(BSLASH) /$(BSLASH)&sp;/g')
+FIND_FILES_ABS_ESC = $(shell $(FIND) $(1) -e 's/:/$(BSLASH)&co;/g' -e 's/$(BSLASH) /$(BSLASH)&sp;/g')
+
+FIND_FILES_4MAKE = $(shell $(FIND) $(1) | $(SED) 's/ /\\\ /g')
+
+#ENCODE_ESC = $(shell echo $(1) | $(SED) -e 's/:/$(BSLASH)&co;/g' -e 's/$(BSLASH) /$(BSLASH)&sp;/g')
+#DECODE_ESC = $(shell echo $(1) | $(SED) -e 's/$(BSLASH)&co;/:/g' -e 's/$(BSLASH)&sp;/$(BSLASH) / g')
+ENCODE_ESC = $(subst $(SPACE),$(SPACE_ESC),$(subst $(COLON),$(COLON_ESC),$(1)))
+DECODE_ESC = $(subst $(COLON_ESC),$(COLON),$(subst $(SPACE_ESC),$(SPACE),$(1)))
+ENCODE_4MAKE = $(subst $(SPACE),$(SPACE_ESC),$(1))
+DECODE_4MAKE = $(subst $(SPACE_ESC),$(SPACE),$(1))
+
+CONVERT_TO_OUT = $(subst $(DOTDOT),$(DOTDOT_OUT),$(subst $(COLON),$(COLON_OUT),$(subst $(SPACE),$(SPACE_OUT),$(1))))
+CONVERT_ESC_TO_OUT = $(subst $(DOTDOT),$(DOTDOT_OUT),$(subst $(COLON_ESC),$(COLON_OUT),$(subst $(SPACE_ESC),$(SPACE_OUT),$(1))))
+CONVERT_4MAKE_TO_OUT = $(subst $(DOTDOT),$(DOTDOT_OUT),$(subst $(COLON),$(COLON_OUT),$(subst $(SPACE_ESC),$(SPACE_OUT),$(1))))
+
+PROC_NO_EXIST = $(if $(wildcard $(1)),,$(call $(2),$(1)))
+define MAKEDIRS0
+       @echo '  Building directory: $(1)'
+       @$(MKDIR) $(MKDIR_OP) $(subst $(BSLASH),/,$(1))
+endef
+MAKEDIRS = $(call PROC_NO_EXIST,$(1),MAKEDIRS0)
diff --git a/Build/makefile b/Build/makefile
new file mode 100644 (file)
index 0000000..f491b50
--- /dev/null
@@ -0,0 +1,34 @@
+# 
+# Usege : make -f <proj_root>/Build/makefile -C <proj_root> 
+#
+BUILD_SCRIPT_VERSION := 1.1.0
+
+.PHONY : app_version app_build app_clean build_version
+
+
+all : app_build
+
+clean : app_clean
+
+version : build_version
+
+#PROJ_ROOT = .
+BUILD_ROOT := $(PROJ_PATH)/Build#
+
+ifeq ($(MAKE_NAME),mingw32-make)
+ifneq ($(SHELL),)
+OPTIONS += --eval="SHELL=$(SHELL)"
+endif
+endif
+
+app_build :
+       @echo $(MAKE) -f "$(BUILD_ROOT)/makefile.mk"
+       @$(MAKE_BIN) -f "$(BUILD_ROOT)/makefile.mk" -C "$(PROJ_PATH)" $(OPTIONS)
+
+app_clean :
+       @$(MAKE) -f "$(BUILD_ROOT)/makefile.mk" -C "$(PROJ_PATH)" $(OPTIONS) clean
+
+build_version :
+       @echo makefile : $(BUILD_SCRIPT_VERSION)
+       @$(MAKE) -f "$(BUILD_ROOT)/makefile.mk" -C "$(PROJ_PATH)" $(OPTIONS) version
diff --git a/Build/makefile.mk b/Build/makefile.mk
new file mode 100644 (file)
index 0000000..205a3ad
--- /dev/null
@@ -0,0 +1,197 @@
+#
+# Usege : make -f <proj_root>/Build/makefile -C <proj_root>
+#
+
+BUILD_SCRIPT_VERSION := 1.2.3
+
+.PHONY : app_version app_clean build_version
+
+
+all : app_build
+
+clean : app_clean
+
+version : build_version
+
+
+#PROJ_ROOT := $(call BSLASH2SLASH,$(PROJ_PATH))
+PROJ_ROOT := .
+BUILD_ROOT := $(PROJ_ROOT)/Build
+
+include $(BUILD_ROOT)/basedef.mk
+
+include $(PROJ_ROOT)/project_def.prop
+-include $(PROJ_ROOT)/build_def.prop
+
+include $(BUILD_ROOT)/funcs.mk
+
+-include $(BUILD_ROOT)/tooldef.mk
+-include $(BUILD_ROOT)/flags.mk
+-include $(BUILD_ROOT)/platform.mk
+
+
+APPTYPE := $(type)
+
+OUTPUT_DIR := $(PROJ_ROOT)/$(BUILD_CONFIG)
+OBJ_OUTPUT := $(OUTPUT_DIR)/objs
+
+LOWER_APPNAME := $(call LOWER_CASE,$(APPNAME))
+APPID2 := $(subst $(basename $(APPID)).,,$(APPID))
+
+ifeq ($(strip $(APPTYPE)),app)
+APPFILE := $(OUTPUT_DIR)/$(LOWER_APPNAME)
+endif
+ifeq ($(strip $(APPTYPE)),staticLib)
+APPFILE := $(OUTPUT_DIR)/lib$(LOWER_APPNAME).a
+endif
+ifeq ($(strip $(APPTYPE)),sharedLib)
+APPFILE := $(OUTPUT_DIR)/lib$(LOWER_APPNAME).so
+endif
+
+ifneq ($(strip $(PLATFORM_INCS)),)
+PLATFORM_INCS_FILE := $(OBJ_OUTPUT)/platform_incs_file.inc
+endif
+
+include $(BUILD_ROOT)/build_c.mk
+
+
+ifeq ($(strip $(APPTYPE)),app)
+EXT_OP := -fPIE
+endif
+ifeq ($(strip $(APPTYPE)),staticLib)
+EXT_OP := -fPIE
+endif
+ifeq ($(strip $(APPTYPE)),sharedLib)
+EXT_OP := -fPIC
+endif
+
+C_OPT := $(COMPILE_FLAGS) $(TC_COMPILER_MISC) $(RS_COMPILER_MISC) $(EXT_OP) --sysroot="$(SYSROOT)" -Werror-implicit-function-declaration $(M_OPT) $(USER_C_OPTS)
+CPP_OPT := $(CPP_COMPILE_FLAGS) $(TC_COMPILER_MISC) $(RS_COMPILER_MISC) $(EXT_OP) --sysroot="$(SYSROOT)" -Werror-implicit-function-declaration $(M_OPT) $(USER_CPP_OPTS)
+C_OPT_FILE := $(PLATFORM_INCS_FILE)
+
+OBJS := #
+
+# Global C/C++
+ifeq ($(strip $(USER_ROOT)),)
+USER_ROOT := $(PROJ_ROOT)
+endif
+$(eval $(call C_PROC_RAW,$(OBJ_OUTPUT),$(USER_SRCS),$(USER_INC_DIRS),$(USER_INC_FILES),$(USER_DEFS),$(USER_UNDEFS),$(C_OPT),$(C_OPT_FILE),C,c,$(CC),OBJS))
+$(foreach ext,cpp cxx cc c++ C,$(eval $(call C_PROC_RAW,$(OBJ_OUTPUT),$(USER_SRCS),$(USER_INC_DIRS),$(USER_CPP_INC_FILES),$(USER_CPP_DEFS),$(USER_CPP_UNDEFS),$(CPP_OPT),$(C_OPT_FILE),C++,$(ext),$(CXX),OBJS)))
+
+# Individual C/C++
+ifneq ($(strip $(USER_EXT_C_KEYS)),)
+$(foreach var,$(USER_EXT_C_KEYS),$(eval $(call C_PROC_RAW,$(OBJ_OUTPUT),$(USER_EXT_$(var)_SRCS),$(USER_EXT_$(var)_INC_DIRS),$(USER_EXT_$(var)_INC_FILES),$(USER_EXT_$(var)_DEFS),$(USER_EXT_$(var)_UNDEFS),$(C_OPT),$(C_OPT_FILE),C,c,$(CC),OBJS)))
+$(foreach ext,cpp cxx cc c++ C,$(foreach var,$(USER_EXT_C_KEYS),$(eval $(call C_PROC_RAW,$(OBJ_OUTPUT),$(USER_EXT_$(var)_SRCS),$(USER_EXT_$(var)_INC_DIRS),$(USER_EXT_$(var)_CPP_INC_FILES),$(USER_EXT_$(var)_CPP_DEFS),$(USER_EXT_$(var)_CPP_UNDEFS),$(CPP_OPT),$(C_OPT_FILE),C++,$(ext),$(CXX),OBJS))))
+endif
+
+
+ifneq ($(strip $(USER_LIB_DIRS)),)
+_ENC_USER_LIB_DIRS := $(call ENCODE_4MAKE,$(USER_LIB_DIRS))
+_ENC_USER_LIB_DIRS := $(addprefix -L,$(_ENC_USER_LIB_DIRS))
+LIBPATHS := $(call DECODE_4MAKE,$(_ENC_USER_LIB_DIRS))
+endif
+
+LIBS += $(addprefix -l,$(USER_LIBS))
+
+UOBJS += $(USER_OBJS)
+
+M_OPT = -MMD -MP -MF"$(@:%.o=%.d)"
+
+DEPS := $(OBJS:.o=.d)
+
+ifneq ($(strip $(DEPS)),)
+-include $(PROJ_ROOT)/Build/$(DEPS)
+endif
+
+
+ifeq ($(strip $(APPTYPE)),app)
+$(APPFILE) : $(OBJS) $(UOBJS)
+       @echo '  Building target: $@'
+       @echo '  Invoking: C/C++ Linker'
+       $(call MAKEDIRS,$(@D))
+       $(CXX) -o $(APPFILE) $(OBJS) $(UOBJS) $(LIBPATHS) -Xlinker --as-needed $(LIBS) $(LINK_FLAGS) $(TC_LINKER_MISC) $(RS_LINKER_MISC) -pie -lpthread --sysroot="$(SYSROOT)" -Xlinker --version-script="$(PROJ_ROOT)/.exportMap" $(RS_LIB_PATHS) $(RS_LIBRARIES) -Xlinker -rpath="/opt/usr/apps/$(APPID)/lib" -Werror-implicit-function-declaration $(USER_LINK_OPTS)
+       @echo '  Finished building target: $@'
+endif
+ifeq ($(strip $(APPTYPE)),staticLib)
+$(APPFILE) : $(OBJS) $(UOBJS)
+       @echo '  Building target: $@'
+       @echo '  Invoking: Archive utility'
+       $(call MAKEDIRS,$(@D))
+       $(AR) -r $(APPFILE) $(OBJS) $(UOBJS) $(AR_FLAGS) $(USER_LINK_OPTS)
+       @echo '  Finished building target: $@'
+endif
+ifeq ($(strip $(APPTYPE)),sharedLib)
+$(APPFILE) : $(OBJS) $(UOBJS)
+       @echo '  Building target: $@'
+       @echo '  Invoking: C/C++ Linker'
+       $(call MAKEDIRS,$(@D))
+       $(CXX) -o $(APPFILE) $(OBJS) $(UOBJS) $(LIBPATHS) -Xlinker --as-needed $(LIBS) $(LINK_FLAGS) $(TC_LINKER_MISC) $(RS_LINKER_MISC) -shared -lpthread --sysroot="$(SYSROOT)" $(RS_LIB_PATHS) $(RS_LIBRARIES) $(USER_LINK_OPTS)
+       @echo '  Finished building target: $@'
+endif
+
+
+$(OBJ_OUTPUT) :
+       $(call MAKEDIRS,$@)
+
+$(OUTPUT_DIR) :
+       $(call MAKEDIRS,$@)
+
+
+ifneq ($(strip $(PLATFORM_INCS)),)
+$(PLATFORM_INCS_FILE) : $(OBJ_OUTPUT)
+       @echo '  Building inc file: $@'
+ifneq ($(findstring Windows,$(OS)),)
+ifneq ($(findstring 3.82,$(MAKE_VERSION)),)
+       $(file > $@,$(PLATFORM_INCS))
+else
+       @echo $(PLATFORM_INCS) > $@
+endif
+else
+       @echo $(PLATFORM_INCS) > $@
+endif
+endif
+
+
+include $(BUILD_ROOT)/build_edc.mk
+
+#ifeq ($(strip $(ENVENTOR_SHARED_RES_PATH)),)
+ENVENTOR_SHARED_RES_PATH ?= $(ENVENTOR_PATH)/share/enventor
+#endif
+
+EDJ_FILES :=
+
+# Global EDCs
+ifneq ($(strip $(USER_EDCS)),)
+$(eval $(call EDJ_PROC_RAW,$(OUTPUT_DIR),$(USER_EDCS),$(USER_EDCS_IMAGE_DIRS),$(USER_EDCS_SOUND_DIRS),$(USER_EDCS_FONT_DIRS),EDJ_FILES))
+endif
+
+# Individual EDCs
+ifneq ($(strip $(USER_EXT_EDC_KEYS)),)
+$(foreach var,$(USER_EXT_EDC_KEYS),$(eval $(call EDJ_PROC_RAW,$(OUTPUT_DIR),$(USER_EXT_$(var)_EDCS),$(USER_EXT_$(var)_EDCS_IMAGE_DIRS),$(USER_EXT_$(var)_EDCS_SOUND_DIRS),$(USER_EXT_$(var)_EDCS_FONT_DIRS),EDJ_FILES)))
+endif
+
+
+include $(BUILD_ROOT)/build_po.mk
+
+MO_FILES :=
+
+# Global POs
+ifneq ($(strip $(USER_POS)),)
+$(eval $(call MO_PROC_RAW,$(OUTPUT_DIR),$(USER_POS),$(APPID2),MO_FILES))
+endif
+
+
+secondary-outputs : $(EDJ_FILES) $(MO_FILES)
+
+-include appendix.mk
+
+app_build : $(OUTPUT_DIR) $(APPFILE) secondary-outputs
+       @echo ========= done =========
+
+
+app_clean :
+       rm -f $(APPFILE)
+       rm -rf $(OUTPUT_DIR)
+
+build_version :
+       @echo makefile.mk : $(BUILD_SCRIPT_VERSION)
diff --git a/Build/platform.mk b/Build/platform.mk
new file mode 100644 (file)
index 0000000..294a38a
--- /dev/null
@@ -0,0 +1,15 @@
+# Add inputs and outputs from these tool invocations to the build variables
+
+SYSROOT = $(SBI_SYSROOT)
+
+USR_INCS := $(addprefix -I $(SYSROOT),$(PLATFORM_INCS_EX))
+
+ifeq ($(strip $(PLATFORM_LIB_PATHS)),)
+RS_LIB_PATHS := "$(SYSROOT)/usr/lib"
+else
+RS_LIB_PATHS := $(addprefix -L$(SYSROOT),$(PLATFORM_LIB_PATHS))
+endif
+
+RS_LIBRARIES := $(addprefix -l,$(RS_LIBRARIES_EX))
+
+PLATFORM_INCS = $(USR_INCS) -I"$(SDK_PATH)/library"
diff --git a/Build/tooldef.mk b/Build/tooldef.mk
new file mode 100644 (file)
index 0000000..c62243c
--- /dev/null
@@ -0,0 +1,70 @@
+# Add inputs and outputs from these tool invocations to the build variables
+
+ifneq ($(strip $(SHELL_BIN)),)
+SHELL = $(SHELL_BIN)
+else
+SHELL = sh
+endif
+
+ifneq ($(strip $(MKDIR_BIN)),)
+MKDIR = $(MKDIR_BIN)
+MKDIR_OP = -p
+else
+MKDIR = mkdir
+MKDIR_OP = -p
+endif
+
+ifneq ($(strip $(UNAME_BIN)),)
+UNAME = $(UNAME_BIN)
+else
+UNAME = uname
+endif
+
+ifneq ($(strip $(M4_BIN)),)
+M4 = $(M4_BIN)
+else
+M4 = m4
+endif
+
+ifneq ($(strip $(TR_BIN)),)
+TR = $(TR_BIN)
+else
+TR = tr
+endif
+
+ifneq ($(strip $(FIND_BIN)),)
+FIND = $(FIND_BIN)
+else
+FIND = find
+endif
+
+ifneq ($(strip $(SED_BIN)),)
+SED = $(SED_BIN)
+else
+SED = sed
+endif
+
+ifneq ($(strip $(GREP_BIN)),)
+GREP = $(GREP_BIN)
+else
+GREP = grep
+endif
+
+ifneq ($(strip $(EDJE_CC_BIN)),)
+EDJE_CC = $(EDJE_CC_BIN)
+else
+EDJE_CC = edje_cc
+endif
+
+ifneq ($(strip $(MSGFMT_BIN)),)
+MSGFMT = $(MSGFMT_BIN)
+else
+MSGFMT = msgfmt
+endif
+
+ifneq ($(strip $(CKSUM_BIN)),)
+CKSUM = $(CKSUM_BIN)
+else
+CKSUM = cksum
+endif
+
diff --git a/build_def.prop b/build_def.prop
new file mode 100644 (file)
index 0000000..6bb5e2f
--- /dev/null
@@ -0,0 +1,6 @@
+
+# Add pre/post build process
+PREBUILD_DESC = 
+PREBUILD_COMMAND = 
+POSTBUILD_DESC = 
+POSTBUILD_COMMAND = 
diff --git a/edje_images/b_ic_press_full_circle_bg.png b/edje_images/b_ic_press_full_circle_bg.png
new file mode 100755 (executable)
index 0000000..5b9f7e4
Binary files /dev/null and b/edje_images/b_ic_press_full_circle_bg.png differ
diff --git a/edje_images/gear_tutorial_bg.png b/edje_images/gear_tutorial_bg.png
new file mode 100755 (executable)
index 0000000..f9a0646
Binary files /dev/null and b/edje_images/gear_tutorial_bg.png differ
diff --git a/edje_images/gear_tutorial_bg_focus.png b/edje_images/gear_tutorial_bg_focus.png
new file mode 100755 (executable)
index 0000000..10cee53
Binary files /dev/null and b/edje_images/gear_tutorial_bg_focus.png differ
diff --git a/edje_images/gear_tutorial_bt_cancel_normal.png b/edje_images/gear_tutorial_bt_cancel_normal.png
new file mode 100755 (executable)
index 0000000..537d702
Binary files /dev/null and b/edje_images/gear_tutorial_bt_cancel_normal.png differ
diff --git a/edje_images/gear_tutorial_bt_cancel_press.png b/edje_images/gear_tutorial_bt_cancel_press.png
new file mode 100755 (executable)
index 0000000..0f7fee6
Binary files /dev/null and b/edje_images/gear_tutorial_bt_cancel_press.png differ
diff --git a/edje_images/gear_tutorial_rotate_ccw.png b/edje_images/gear_tutorial_rotate_ccw.png
new file mode 100755 (executable)
index 0000000..083cf15
Binary files /dev/null and b/edje_images/gear_tutorial_rotate_ccw.png differ
diff --git a/edje_images/gear_tutorial_rotate_cw.png b/edje_images/gear_tutorial_rotate_cw.png
new file mode 100755 (executable)
index 0000000..0e2699d
Binary files /dev/null and b/edje_images/gear_tutorial_rotate_cw.png differ
diff --git a/edje_images/wi_more_option_bg.png b/edje_images/wi_more_option_bg.png
new file mode 100755 (executable)
index 0000000..6e32370
Binary files /dev/null and b/edje_images/wi_more_option_bg.png differ
diff --git a/inc/DrDebug.h b/inc/DrDebug.h
new file mode 100755 (executable)
index 0000000..137bf4c
--- /dev/null
@@ -0,0 +1,14 @@
+#ifndef _DR_DEBUG_H_
+#define _DR_DEBUG_H_
+
+#ifdef LOG_TAG
+#undef LOG_TAG
+#endif
+
+#define LOG_TAG "W-DRAWING"
+
+#include "WDebugBase.h"
+
+/* TODO : add your own macro */
+
+#endif /* _VE_DEBUG_H_ */
diff --git a/inc/DrDefine.h b/inc/DrDefine.h
new file mode 100755 (executable)
index 0000000..7a794bd
--- /dev/null
@@ -0,0 +1,115 @@
+#ifndef _DR_DEFINE_H_
+#define _DR_DEFINE_H_
+
+#include "DrDebug.h"
+
+
+/*****************************************
+ * package and install related
+ *****************************************/
+#ifndef LOCALE_DOMAIN
+#define LOCALE_DOMAIN "sketch"
+#endif
+
+//#ifndef SKETCH_DRAW_COLORS_CHANGABLE
+//#define SKETCH_DRAW_COLORS_CHANGABLE
+//#endif
+#ifndef SKETCH_DRAW_ENABLE_DRAWING_EFFECT
+#define SKETCH_DRAW_ENABLE_DRAWING_EFFECT
+#endif
+
+
+#define PACKAGE_NAME           "org.tizen.w-drawing"
+#define INSTALLED_PATH         "/opt/usr/apps"
+#define ROOT_INSTALLED_PATH    "/usr/apps"
+#define DATA_DIRECTORY_NAME    "data"
+#define REFERENCE_BASE_SCALE          2.4 //based on z910f device(1280x720)
+#define DRAWING_SYATEM_TERMINATE_APP     "System will terminate video editor due to internal issues, such as low memory,etc."
+#define DRAWING_SAVE_FILE_DIRECTORY     "/opt/usr/media/Images/"
+#define DRAWING_OUTPUT_FILE_FORMAT     ".png"
+#define DRAWING_OUTPUT_FILE_FORMAT_MMS ".jpg"
+
+
+
+/*****************************************
+ * edj
+ *****************************************/
+#define EDJ_FILE                  "edje/animations2circle.edj"
+#define EDJ_THEME_FILE            "edje/btneffect.edj"
+#define EDJ_POPUP_CUSTOM_FILE     "edje/drawing_popup.edj"
+#define DRAWING_LAYOUT_GROUP_NAME "drawing_group"
+#define DRAWING_TUTORIAL_LAYOUT_GROUP_NAME "tutorial_view"
+
+
+#define DRAWING_BUTTON_SAVE_MODE_STYLE   "pallet/savemode_effect"
+#define DRAWING_BUTTON_SEND_MODE_STYLE   "pallet/sendmode_effect"
+
+/*****************************************
+ * image
+ *****************************************/
+#define  CLOSE_POPUP_CANCEL_ICON  "images/drawing_popup_btn_delete.png"
+#define  CLOSE_POPUP_DISCARD_ICON  "images/drawing_popup_btn_check.png"
+#define  DRAWING_MORE_OPTIONS_ICON  "images/wi_drawing_more_options_icon.png"
+#define  DRAWING_STROKE_OPTIONS_ICON  "images/wear_comm_stroke_option.png"
+#define  DRAWING_MORE_OPTION_ICON_BG      "images/b_more_option_icon_bg.png"
+#define  DRAWING_MORE_OPTION_ICON_SELECTED_BG      "images/b_more_option_icon_select_bg.png"
+#define  DRAWING_PALLET_COLOR_PICKER_ERASER_ICON   "images/wi_drawing_more_options_erase.png"
+#define  DRAWING_PALLET_COLOR_PICKER_SELECTOR_ICON   "images/wi_drawing_select_button_center.png"
+#define  DRAWING_STROKE_SLIDER_ICON_MINUS      "images/b_slider_icon_minus.png"
+#define  DRAWING_STROKE_SLIDER_ICON_PLUS      "images/b_slider_icon_plus.png"
+#define  DRAWING_DRAWING_PATTERN_BG    "images/wi_drawing_bg_pattern_negative.png"
+#define  SKETCH_DRAWING_PATTERN_BG "images/wi_drawing_bg_pattern.png"
+#define  SKETCH_DRAWING_COLOR_BG_01 "images/wi_drawing_bg_01.png"
+#define  SKETCH_DRAWING_COLOR_BG_02 "images/wi_drawing_bg_02.png"
+#define  SKETCH_DRAWING_COLOR_BG_03 "images/wi_drawing_bg_03.png"
+#define  SKETCH_DRAWING_COLOR_BG_04 "images/wi_drawing_bg_04.png"
+
+
+
+
+/*****************************************
+ * text
+ *****************************************/
+#define DRAWING_STRING_ID_MMS_TITLE_TEXT  "WDS_MSG_SBODY_MMS_ABB"
+#define DRAWING_STRING_ID_TEXT_SEND         "WDS_IME_ACBUTTON_SEND"
+#define DRAWING_STRING_ID_SEND_DRAW_START_INDICATOR   "WDS_IME_NPBODY_START_DOODLING_YOUR_MESSAGE_ABB"
+#define DRAWING_STRING_ID_SEND_DRAW_START_INDICATOR_ATNT   "WDS_IME_NPBODY_START_DRAWING_YOUR_IMAGE_ABB"
+
+//#define DRAWING_MMS_TITLE_TEXT    "MMS"
+#define DRAWING_TEXT_SAVE         "SAVE"
+//#define DRAWING_TEXT_SEND_DRAW_START_INDICATOR         "Start drawing send to as image"
+#define DRAWING_TEXT_SAVE_DRAW_START_INDICATOR         "Start drawing save to as image"
+#define MORE_OPTION_PALLET_RED          "Red"
+#define MORE_OPTION_PALLET_GREEN          "Green"
+
+
+/* popup */
+#define DRAWING_STRING_ID_POPUP_DISCARD_CONTENT    "WDS_IME_POP_ARE_YOU_SURE_YOU_WANT_TO_DISCARD_YOUR_DRAWING_Q"
+//#define DRAWING_POPUP_DISCARD_CONTENT    "All changes will be discard?"
+#define DRAWING_POPUP_DISCARD_CANCEL_BUTTON    "Cancel"
+#define DRAWING_POPUP_DISCARD_DISCARD_BUTTON      "Discard"
+#define DRAWING_POPUP_DISCARD_TITLE      "Discard"
+#define DRAWING_TUTORIAL_POPUP_TITLE   "WDS_TTRL_HEADER_TIPS_ABB"
+#define DRAWING_TUTORIAL_POPUP_CONTENTS_1  "WDS_TTRL_BODY_TURN_THE_BEZEL_ANTICLOCKWISE_TO_UNDO_A_DOODLE_ABB"
+#define DRAWING_TUTORIAL_POPUP_CONTENTS_2   "WDS_TTRL_BODY_AND_CLOCKWISE_TO_BRING_YOUR_DOODLE_BACK_ABB"
+
+
+#define MMS_MODE_STROKE_LINE_WIDTH      15.0
+#define SAVE_MODE_STROKE_LINE_WIDTH     3.0
+#define MAX_HISTORY                     15
+
+#define MAX_ANIMATION_TIME                             0.5
+#define MIN_ANIMATION_TIME                             0.05
+#define DRAW_POINTS                                            64   //128
+#define DRAW_SPEED                                             128  //320
+
+
+#define PREFERENCE_KEY_TUTORIAL_IS_SHOWED   "tutorial_showed_key"
+#define PREFERENCE_KEY_APP_BG_INDEX         "app_bg_index_key"
+
+typedef enum {
+       DRAWING_SAVE = 0,
+       DRAWING_SEND,
+}LaunchMode;
+
+#endif                                                 /* _VE_DEFINE_H_ */
diff --git a/inc/app-assist-efl/IWWindowController.h b/inc/app-assist-efl/IWWindowController.h
new file mode 100755 (executable)
index 0000000..861c619
--- /dev/null
@@ -0,0 +1,83 @@
+/*
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0
+ *
+ * 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 _APP_ASSIST_IWWINDOW_CONTROLLER_H_
+#define _APP_ASSIST_IWWINDOW_CONTROLLER_H_
+
+#include <Evas.h>
+#include "WDefine.h"
+
+namespace app_assist {
+
+class WViewController;
+
+/**
+* @class       IWWindowController
+* @brief       This class is the interface class for the elements related to the window.
+*
+* The %IWWindowController provides interfaces for evas object related to the window class instance.
+*/
+class WAPP_ASSIST_EXPORT IWWindowController {
+public:
+       /**
+        * Gets the class name.
+        *
+        * @return the class name
+        */
+       virtual const char* getClassName() = 0;
+
+       /**
+        * Gets the evas object of window.
+        *
+        * @return evas object
+        */
+       virtual Evas_Object* getEvasObj() const = 0;
+
+       /**
+        * Gets the base layout evas object
+        *
+        * @return The pointer to the evas object of the layout
+        */
+       virtual Evas_Object* getBaseLayoutEvasObj() = 0;
+
+       /**
+        * Gets the conformant evas object.
+        *
+        * @return The pointer to the evas object of the conformant
+        */
+       virtual Evas_Object* getConformantEvasObj() = 0;
+
+       /**
+        * Gets the base view controller attached.
+        *
+        * @return The pointer to the base view controller
+        * @see attachBaseViewController()
+        */
+       virtual WViewController* getBaseViewController() = 0;
+
+protected:
+       /**
+        * This is the destructor for this class.
+        *
+        */
+       virtual ~IWWindowController() {};
+       //
+};
+
+} // namespace
+
+#endif /* _APP_ASSIST_IWWINDOW_CONTROLLER_H_ */
diff --git a/inc/app-assist-efl/WApp.h b/inc/app-assist-efl/WApp.h
new file mode 100755 (executable)
index 0000000..d485c5c
--- /dev/null
@@ -0,0 +1,137 @@
+/*
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0
+ *
+ * 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 _APP_ASSIST_WAPP_H_
+#define _APP_ASSIST_WAPP_H_
+
+#include <app.h>
+#include "WDefine.h"
+
+namespace app_assist {
+
+// forward declaration
+class WWindowController;
+
+/**
+* @class       WApp
+* @brief       This class is the base class of an application
+*
+*
+* The %WApp class is the base class of an application. An application class must be inherited from this class
+* @code
+*
+* // main.cpp
+* WAPP_ASSIST_EXPORT int main( int argc, char* argv[] )
+* {
+*   MyApp app;
+*   int ret = app.start( argc, argv );
+*   return ret;
+* }
+* @endcode
+*/
+class WAPP_ASSIST_EXPORT WApp {
+public:
+       /**
+        * This is the default constructor for this class.
+        *
+        */
+       WApp();
+
+       /**
+        * This is the destructor for this class.
+        *
+        */
+       virtual ~WApp();
+
+public:
+       /**
+        * Starts the application.
+        *
+        * @param[in]   argc    The argument count
+        * @param[in]   argv    The argument vector
+        *
+        * @return result
+        */
+       int start(int argc, char* argv[]);
+
+protected:
+       /**
+        * Called when the application started
+        *
+        * @param[in]   argc    The argument count
+        * @param[in]   argv    The argument vector
+        *
+        * @return result
+        */
+       virtual int onStart(int argc, char* argv[]);
+
+       /**
+        * Called when the application created
+        *
+        * @return      true if the application created successfully, else false
+        */
+       virtual bool onCreate() { return true; };
+
+       /**
+        * Called when the application is terminated.
+        *
+        */
+       virtual void onTerminate() {};
+
+       /**
+        * Called when the application is paused.
+        *
+        */
+       virtual void onPause() {};
+
+       /**
+        * Called when the application is resumed.
+        *
+        */
+       virtual void onResume() {};
+
+       /**
+        * Called when some request comes to the application
+        *
+        * @param[in]   request handle of request information
+        * @param[in]   firstLaunch     true, if it is called after creation
+        */
+       virtual void onAppControl(app_control_h request, bool firstLaunch);
+
+       /**
+        * Gets the window class instance of the application.
+        *
+        * @return      The pointer to the window
+        */
+       WWindowController* getWindowController();
+
+       /**
+        * Attaches a window to the application.
+        *
+        * @param[in]   win     A pointer to the window to attach
+        * @return      true if the window attached sucessfully, else false
+        */
+       bool attachWindowController(WWindowController* win);
+
+private:
+       WDECLARE_PRIVATE_IMPL(WApp);
+       WDISABLE_COPY_AND_ASSIGN(WApp);
+};
+
+} // namespace
+
+#endif /* _APP_ASSIST_WAPP_H_ */
diff --git a/inc/app-assist-efl/WAppEventHandler.h b/inc/app-assist-efl/WAppEventHandler.h
new file mode 100755 (executable)
index 0000000..1b6eb5a
--- /dev/null
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0
+ *
+ * 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 _APP_ASSIST_WAPP_EVENT_HANDLER_H_
+#define _APP_ASSIST_WAPP_EVENT_HANDLER_H_
+
+#include <functional>
+#include <app.h>
+#include "WDefine.h"
+
+namespace app_assist {
+/**
+* @class       WAppEventHandler
+* @brief       This class is
+*
+*/
+class WAPP_ASSIST_EXPORT WAppEventHandler {
+public:
+       /**
+        * This is the default constructor for this class.
+        *
+        */
+       WAppEventHandler();
+
+       /**
+        * This is the destructor for this class.
+        *
+        */
+       virtual ~WAppEventHandler();
+
+public:
+       /**
+        * Adds application event handler of event type.
+        *
+        * @param[in]   eventType       event type to be handled
+        * @param[in]   handlerFunc     The pointer to handler function
+        * @param[in]   userData        user data pointer to be used in handler function
+        *
+        * @return 0 on success, otherwise error
+        */
+       int addEventHandler(app_event_type_e eventType, const std::function<void(app_event_info_h eventInfo, void* userData)>& handlerFunc, void* userData);
+
+       /**
+        * Removes application event handler
+        *
+        */
+       void removeEventHandler();
+
+protected:
+       /**
+        * Returns the handle of added event handler
+        *
+        * @return the handle
+        *
+        * @see addEventHandler()
+        */
+       app_event_handler_h getHandle();
+
+private:
+       WDECLARE_PRIVATE_IMPL(WAppEventHandler);
+       WDISABLE_COPY_AND_ASSIGN(WAppEventHandler);
+};
+
+} // namespace
+
+#endif /* _APP_ASSIST_WAPP_EVENT_HANDLER_H_ */
diff --git a/inc/app-assist-efl/WContentViewController.h b/inc/app-assist-efl/WContentViewController.h
new file mode 100755 (executable)
index 0000000..85b0a91
--- /dev/null
@@ -0,0 +1,294 @@
+/*
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0
+ *
+ * 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 _APP_ASSIST_WCONTENT_VIEW_CONTROLLER_H_
+#define _APP_ASSIST_WCONTENT_VIEW_CONTROLLER_H_
+
+#include <functional>
+#include <memory>
+#include <Evas.h>
+#include <Elementary.h>
+#include "WViewController.h"
+#include "WNaviframeController.h"
+#include "IWWindowController.h"
+
+namespace app_assist {
+
+/**
+* @class       WContentViewController
+* @brief       This class means the view represented by an evas object, which can be pushed into naviframe elementary.
+*
+* The %WContentViewController class keeps an evas object and provides methods to handle the case when the view is pushed into naviframe.
+*/
+class WAPP_ASSIST_EXPORT WContentViewController : public WViewController {
+public:
+       /**
+        * This is the default constructor for this class.
+        *
+        */
+       WContentViewController();
+
+       /**
+        * Constructor
+        *
+        * @param[in]   name    the instance name to be set
+        */
+       explicit WContentViewController(const char* name);
+
+       /**
+        * Gets the class name.
+        *
+        */
+       virtual const char* getClassName() const; //override;
+
+public:
+       /**
+        * Creates evas object which represents this view.
+        * "onCreate" will be called subsequently.
+        *
+        * @param[in]   parent  parent evas object of the view
+        * @param[in]   viewParam       user data
+        * @see onCreate
+        * @see onCreateView
+        * @see onCreated
+        */
+       bool create(Evas_Object* parent, void* param); //final;
+
+       /**
+        * Destroys the class instance and deletes evas object.
+        * If it has been pushed into naviframe, it will be popped out without onPop method being called.
+        *
+        * @see onDestroy
+        */
+       void destroy(); //final;
+
+public:
+
+       /**
+        * Sets a delegate function. It delegates onPushed handling to delegateFunc.
+        * This is simpler alternative to overriding the virtual method onPushed(), allowing direct use of WContentViewController without sub-classing.
+        * If delegation is used, onPushed() will not be called.
+        *
+        * @param[in]   delegateFunc    The pointer to delegate function
+        * @see onPushed()
+        */
+       void setOnPushed(const std::function<void(Elm_Object_Item* naviItem)>& delegateFunc);
+
+protected:
+
+       /**
+        * Called when create method is called.
+        * It creates a default view.
+        *
+        * @param[in]   parent  parent evas object
+        * @param[in]   viewParam       user data
+        *
+        * @return the most parent evas object created in this method. It will be related to the class instance.
+        */
+       virtual Evas_Object* onCreateView(Evas_Object* parent, void* viewParam); //override;
+
+       /**
+        * Called when the container properties are set by Naviframe or other container views.
+        * Container view should override this method in order to set container properties for any views it contains,
+        * so that those page views can access window and naviframe.
+        *
+        * @param[in]   win             IWWindowController instance
+        * @param[in]   naviframe       WNaviframeController instance
+        * @param[in]   item    navi item pointer of container view which is pushed into naviframe.
+       */
+       virtual void onSetContainerProperties(WNaviframeController* naviframe, Elm_Object_Item* item);
+
+       /**
+        * Called when this view instance evas object should be pushed into naviframe.
+        * Override this method to do something and push the view into naviframe by itself.
+        *
+        * @param[in]   naviFrame       naviframe evas object
+        *
+        * @return navi item resulted from pushing the view to the naviframe.
+        * @see %WNaviframeController::push()
+        * @see onPushed()
+        */
+       virtual Elm_Object_Item* onPushToNaviframe(Evas_Object* naviFrame);
+
+       /**
+        * Called when this view instance evas object is pushed into naviframe.
+        * Override this method to do something with navi item.
+        *
+        * @param[in]   naviItem        navi item resulted from naviframe push
+        * @see %WNaviframeController::push()
+        * @see onPushToNaviframe()
+        */
+       virtual void onPushed(Elm_Object_Item* naviItem);
+
+       /**
+        * Called when the view evas object is popped from naviframe.
+        * Override this method to do something before it is popped out.
+        *
+        * @return false, if you want to keep the view instead of being popped out.
+        */
+       virtual bool onPop();
+
+       /**
+        * Called when the view evas object will be becoming top item on naviframe.
+        * Override this method to do something before it actually become top item.
+        * It is called sequentially after onPop method of the previous top view being popped.
+        */
+       virtual void onBecomeTop();
+
+       /**
+        * Called when this view instance evas object is attached to WPageSlideView.
+        * Override this method to do something with navi item after being attached.
+        *
+        * @param[in]   parentNaviItem  navi item of WPageSlideView object pushed into naviframe
+        * @see onPushed()
+        */
+       virtual void onSetAsPageContent(Elm_Object_Item* parentNaviItem);
+
+
+       /**
+        * Called when setMoreButton method is called to create option menu.
+        * Override this method to create your own option menu.
+        *
+        * @param[in]   naviItem        navi item to add more button
+        * @param[in]   clickedCb       clicked callback function pointer
+        * @param[in]   userData        clicked callback user data parameter
+        * @see onPushed()
+        */
+       virtual void onSetMoreButton(Elm_Object_Item* naviItem, Evas_Smart_Cb clickedCb, void* userData);
+
+       /**
+        * Stores the title string of the view. It is used as title string, when this view is pushed into an WNaviframeController object.
+        *
+        * @param[in]   title   string of the title to be stored
+        *
+        */
+       void setTitle(const char* title);
+
+       /**
+        * Gets the title string stored by the method setTitle.
+        *
+        * @return title string
+        * @see setTitle
+        */
+       const char* getTitle();
+
+       /**
+        * Gets the pointer to the IWWindowController type class instance.
+        * Usually it will be normal window instance, but if the view created on UG module, it will be UG window instance.
+        * Through this returned pointer, you can get window related properties.
+        *
+        * @return The pointer to the IWWindowController type instance.
+        */
+//     IWWindowController* getWindowController();
+
+       /**
+        * Gets the WNaviframeController class instance.
+        *
+        * @return the pointer to the WNaviframeController class instance. If this view instance is not pushed into naviframe, it will be nullptr.
+        */
+       WNaviframeController* getNaviframeController();
+
+       /**
+        * Gets a navi item.
+        *
+        * @return The pointer to navi item. If this view instance is not pushed into naviframe, it will be nullptr.
+        */
+       Elm_Object_Item* getNaviItem();
+
+       /**
+        * Pops out this view instance evas object from naviframe.
+        *
+        * @return true, if succeeded
+        */
+       bool popOut();
+
+       /**
+        * Create more button on navi item.
+        *
+        * @param[in]   naviItem
+        * @param[in]   clickedCb
+        * @param[in]   userData
+        * @see %WNaviframeController::push()
+        * @see onPushed()
+        */
+       bool setMoreButton(Elm_Object_Item* naviItem, Evas_Smart_Cb clickedCb, void* userData);
+
+       //
+protected:
+       /**
+        * This is the destructor for this class.
+        *
+        */
+       virtual ~WContentViewController();
+
+private:
+       WDECLARE_PRIVATE_IMPL(WContentViewController);
+       WDISABLE_COPY_AND_ASSIGN(WContentViewController);
+       friend class WNaviframeController;
+       friend class WPageSlideViewController;
+};
+
+/**
+ * Sets the container class properties to the view.
+ * It will be used only to create your own container view class and set its properties to child views, like WPageSlideView.
+ *
+ * @param[in]  view    WContentViewController instance to set these properties
+ * @param[in]  naviframe       WNaviframeController instance
+ *
+ * @see wcontentviewcontroller_set_container_naviitem_property
+ * @see wcontentviewcontroller_propagate_container_properties_to_childviews
+ */
+WAPP_ASSIST_EXPORT void wcontentviewcontroller_set_container_properties(WContentViewController* view, WNaviframeController* naviframe);
+
+/**
+ * Sets the container class navi item property to the view.
+ * It will be used only to create your own container view class and set its properties to child views, like WPageSlideView.
+ *
+ * @param[in]  view    WContentViewController instance to set these properties
+ * @param[in]  item    navi item pointer of container view which is pushed into naviframe.
+ * @param[in]  isViewNaviItem  If the Elm_Object_Item is for the view itself, set it true.
+ *                              Otherwise if it is a container's Elm_Object_Item, set it false.
+ *
+ * @see wcontentviewcontroller_set_container_properties
+ * @see wcontentviewcontroller_propagate_container_properties_to_childviews
+ */
+WAPP_ASSIST_EXPORT void wcontentviewcontroller_set_container_naviitem_property(WContentViewController* view, Elm_Object_Item* item, bool isViewNaviItem);
+
+
+/**
+ * Propagates container properties (including naviItem property) set on the view to its child views.
+ *
+ * Whenever wcontentviewcontroller_set_container_properties and/or wcontentviewcontroller_set_container_naviitem_property is called for a view,
+ * this function should be called afterwards, so that in case the view is a custom container view,
+ * it will get a chance to propagate the properties it just received to its child views.
+ *
+ * This function invokes virtual method onSetContainerProperties() of the view,
+ * implementation of which should, in turn, set properties for each child views.
+ *
+ * @param[in]  view    WContentViewController instance whose child views to set these properties
+ *
+ * @see wcontentviewcontroller_set_container_properties
+ * @see wcontentviewcontroller_set_container_naviitem_property
+ * @see onSetContainerProperties
+ */
+WAPP_ASSIST_EXPORT void wcontentviewcontroller_propagate_container_properties_to_childviews(WContentViewController* view);
+
+
+} // namespace
+
+
+#endif /* _APP_ASSIST_WCONTENT_VIEW_CONTROLLER_H_ */
diff --git a/inc/app-assist-efl/WDebugBase.h b/inc/app-assist-efl/WDebugBase.h
new file mode 100755 (executable)
index 0000000..9c2960e
--- /dev/null
@@ -0,0 +1,151 @@
+/*
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0
+ *
+ * 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 _APP_ASSIST_WDEBUG_BASE_H_
+#define _APP_ASSIST_WDEBUG_BASE_H_
+
+#ifndef LOG_TAG
+#define LOG_TAG "WAPP"
+#endif
+
+#include <dlog.h>
+#include <string.h>
+#include <assert.h>
+#include "WDefine.h"
+
+// If it is set as 1, assert() is called in WERROR
+#define WENABLE_ASSERT_IN_ERROR (0)
+
+#define WCOLOR_RED "\033[0;31m"
+#define WCOLOR_GREEN "\033[0;32m"
+#define WCOLOR_BROWN "\033[0;33m"
+#define WCOLOR_BLUE "\033[0;34m"
+#define WCOLOR_PURPLE "\033[0;35m"
+#define WCOLOR_CYAN "\033[0;36m"
+#define WCOLOR_LIGHTBLUE "\033[0;37m"
+#define WCOLOR_END             "\033[0;m"
+
+//#ifdef WUSING_PUBLIC_SDK
+// normal log
+#define _WFILE_NAME (strrchr(__FILE__, '/') ? strrchr(__FILE__, '/')+1 : __FILE__)
+
+#define _WDLOG_PRINT(prio, fmt, args...) \
+       dlog_print(prio, LOG_TAG, "%s: %s(%d) > " fmt, _WFILE_NAME, __func__, __LINE__, ##args)
+
+#define WDEBUG(fmt, args...) _WDLOG_PRINT(DLOG_DEBUG, fmt, ##args)
+#define WDEBUG_(fmt, args...) _WDLOG_PRINT(DLOG_DEBUG, WCOLOR_RED fmt WCOLOR_END, ##args) // temporal red-colored text for debugging
+
+#define WVERBOSE(fmt, args...) _WDLOG_PRINT(DLOG_DEBUG, WCOLOR_BROWN fmt WCOLOR_END, ##args)
+#define WINFO(fmt, args...) _WDLOG_PRINT(DLOG_INFO, WCOLOR_GREEN fmt WCOLOR_END, ##args)
+#define WWARNING(fmt, args...) _WDLOG_PRINT(DLOG_WARN, WCOLOR_PURPLE fmt WCOLOR_END, ##args)
+//
+#if (WENABLE_ASSERT_IN_ERROR == 1)
+#define WERROR(fmt, args...) do { \
+                       _WDLOG_PRINT(DLOG_ERROR, WCOLOR_RED "* Critical * " fmt WCOLOR_END, ##args); \
+                       assert(0);      \
+               } while (0)
+#else
+#define WERROR(fmt, args...) _WDLOG_PRINT(DLOG_ERROR, WCOLOR_RED "* Critical * " fmt WCOLOR_END, ##args)
+#endif
+
+#define WHIT() _WDLOG_PRINT(DLOG_DEBUG, WCOLOR_BLUE ">>>HIT<<<" WCOLOR_END)
+#define WHIT_() _WDLOG_PRINT(DLOG_DEBUG, WCOLOR_RED ">>>HIT<<<" WCOLOR_END)
+#define WHITM(fmt, args...) _WDLOG_PRINT(DLOG_DEBUG, WCOLOR_BLUE ">>>HIT<<<" fmt WCOLOR_END, ##args)
+
+#define WENTER() _WDLOG_PRINT(DLOG_DEBUG, WCOLOR_GREEN "BEGIN >>>>" WCOLOR_END)
+#define WLEAVE() _WDLOG_PRINT(DLOG_DEBUG, WCOLOR_GREEN "END <<<<" WCOLOR_END)
+
+// secure log
+#define WSDEBUG(fmt, args...)
+#define WSVERBOSE(fmt, args...)
+#define WSINFO(fmt, args...)
+//
+#define WSERROR(fmt, args...)
+
+/*
+#else // WUSING_PUBLIC_SDK
+// normal log
+#define WDEBUG(fmt, args...) LOGD(fmt, ##args)
+#define WDEBUG_(fmt, args...) LOGD(WCOLOR_RED fmt WCOLOR_END, ##args) // temporal red-colored text for debugging
+
+#define WVERBOSE(fmt, args...) LOGD(WCOLOR_BROWN fmt WCOLOR_END, ##args)
+#define WINFO(fmt, args...) LOGI(WCOLOR_GREEN fmt WCOLOR_END, ##args)
+#define WWARNING(fmt, args...) LOGW(WCOLOR_PURPLE fmt WCOLOR_END, ##args)
+//
+#if (WENABLE_ASSERT_IN_ERROR == 1)
+#define WERROR(fmt, args...) do { \
+                       LOGE(WCOLOR_RED "* Critical * " fmt WCOLOR_END, ##args); \
+                       assert(0);      \
+               } while(0)
+#else
+#define WERROR(fmt, args...) LOGE(WCOLOR_RED "* Critical * " fmt WCOLOR_END, ##args)
+#endif
+
+#define WHIT() LOGD(WCOLOR_BLUE ">>>HIT<<<" WCOLOR_END)
+#define WHIT_() LOGD(WCOLOR_RED ">>>HIT<<<" WCOLOR_END)
+#define WHITM(fmt, args... ) LOGD(WCOLOR_BLUE ">>>HIT<<<" fmt WCOLOR_END, ##args)
+
+#define WENTER() LOGD(WCOLOR_GREEN "BEGIN >>>>" WCOLOR_END)
+#define WLEAVE() LOGD(WCOLOR_GREEN "END <<<<" WCOLOR_END)
+
+// secure log
+#define WSDEBUG(fmt, args...) SECURE_LOGD(fmt, ##args)
+#define WSVERBOSE(fmt, args...) SECURE_LOGD(WCOLOR_BROWN fmt WCOLOR_END, ##args)
+#define WSINFO(fmt, args...) SECURE_LOGI(WCOLOR_GREEN fmt WCOLOR_END, ##args)
+//
+#if (WENABLE_ASSERT_IN_ERROR == 1)
+#define WSERROR(fmt, args...) do { \
+                       SECURE_LOGE(WCOLOR_RED "* Critical * " fmt WCOLOR_END, ##args); \
+                       assert(0);      \
+               } while(0)
+#else
+#define WSERROR(fmt, args...) SECURE_LOGE(WCOLOR_RED "* Critical * " fmt WCOLOR_END, ##args)
+#endif
+
+#endif // WUSING_PUBLIC_SDK
+*/
+#define WPRET_VM(expr, val, fmt, arg...) do { \
+                                       if (expr) { \
+                                               WERROR(fmt, ##arg); \
+                                               return (val); \
+                                               } \
+                                       } while (0)
+
+#define WPRET_M(expr, fmt, arg...) do { \
+                                       if (expr) { \
+                                       WERROR(fmt, ##arg); \
+                                       return; \
+                                       } \
+                               } while (0)
+
+#define WASSERT(expr) do { \
+               if(!(expr)) \
+               {\
+                       WERROR("WASSERT! "#expr);\
+                       assert((expr)); \
+               }\
+       }while(0);
+
+#define WASSERT_EX(expr, fmt, args...) do { \
+               if(!(expr)) \
+               {\
+                       WERROR("WASSERT! " fmt, ##args);\
+                       assert((expr)); \
+               }\
+       }while(0);
+
+#endif /* _APP_ASSIST_WDEBUG_BASE_H_ */
diff --git a/inc/app-assist-efl/WDefine.h b/inc/app-assist-efl/WDefine.h
new file mode 100755 (executable)
index 0000000..8c79ff1
--- /dev/null
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0
+ *
+ * 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 _APP_ASSIST_WDEFINE_H_
+#define _APP_ASSIST_WDEFINE_H_
+
+/**
+* @file        WDefine.h
+* @brief       This file defines version number MACRO and functions.
+*
+*/
+#include <memory>
+
+#define WUSING_SDK_2_3
+
+
+const int WAPP_ASSIST_VERSION_MAJOR    = 2;
+const int WAPP_ASSIST_VERSION_MINOR    = 1;
+const int WAPP_ASSIST_VERSION_PATCH    = 7;
+const char* const WAPP_ASSIST_VERSION_PRE = "";
+
+#define WAPP_ASSIST_EXPORT __attribute__((visibility("default")))
+
+namespace app_assist {
+WAPP_ASSIST_EXPORT int WVersion_getMajor();
+WAPP_ASSIST_EXPORT int WVersion_getMinor();
+WAPP_ASSIST_EXPORT int WVersion_getPatch();
+WAPP_ASSIST_EXPORT const char* WVersion_getPre();
+WAPP_ASSIST_EXPORT const char* WVersion_get();
+
+template<typename T, typename... Ts>
+std::unique_ptr<T> make_unique(Ts&&... params)
+{
+       return std::unique_ptr<T>(new T(std::forward<Ts>(params)...));
+}
+}
+
+#define WDISABLE_COPY_AND_ASSIGN(A) \
+               A( const A& ) = delete; \
+               const A& operator=( const A& ) = delete
+
+#define WDECLARE_PRIVATE_IMPL(A) \
+       class _##A##Impl* __pv; \
+       friend class _##A##Impl
+
+
+
+#endif /* _APP_ASSIST_WDEFINE_H_ */
diff --git a/inc/app-assist-efl/WEvasObject.h b/inc/app-assist-efl/WEvasObject.h
new file mode 100755 (executable)
index 0000000..bae0c4f
--- /dev/null
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0
+ *
+ * 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 _APP_ASSIST_WEVAS_OBJECT_H_
+#define _APP_ASSIST_WEVAS_OBJECT_H_
+
+#include <memory>
+#include <Evas.h>
+#include "WDefine.h"
+
+namespace app_assist {
+
+class IWEvasObject;
+
+typedef std::weak_ptr<IWEvasObject> WEvasObjectPtr;
+
+WAPP_ASSIST_EXPORT WEvasObjectPtr wevasobject_get_weak_ptr(Evas_Object* obj);
+
+class WAPP_ASSIST_EXPORT IWEvasObject {
+protected:
+       virtual ~IWEvasObject() {};
+public:
+       virtual Evas_Object* getEvasObj() = 0;
+};
+
+} // namespace
+
+#endif /* _APP_ASSIST_WEVAS_OBJECT_H_ */
diff --git a/inc/app-assist-efl/WGengridItem.h b/inc/app-assist-efl/WGengridItem.h
new file mode 100755 (executable)
index 0000000..b3cb183
--- /dev/null
@@ -0,0 +1,176 @@
+/*
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0
+ *
+ * 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 _APP_ASSIST_WGENGRID_ITEM_H_
+#define _APP_ASSIST_WGENGRID_ITEM_H_
+
+#include <Evas.h>
+#include <Elementary.h>
+#include <functional>
+#include "WDefine.h"
+
+namespace app_assist {
+
+class WViewController;
+/**
+* @class       WGengridItem
+* @brief       This class is
+*
+*
+* The %WGengridItem is
+*/
+class WAPP_ASSIST_EXPORT WGengridItem {
+public:
+       /**
+        * This is the default constructor for this class.
+        *
+        */
+       WGengridItem();
+
+       /**
+        * This is the destructor for this class.
+        *
+        */
+       virtual ~WGengridItem();
+public:
+       /**
+        * Override this method to create Elm_Gengrid_Item_Class structure.
+        * It is used to append item to the gengrid. Define static Elm_Gengrid_Item_Class variable and return it.
+        *
+        * @return      the pointer of Elm_Gengrid_Item_Class instantiated as static variable.
+        *                      It is not needed to be free.
+        * @see getItemClassNew()
+        */
+       virtual Elm_Gengrid_Item_Class* getItemClassStatic();
+
+       /**
+        * Override this method to create Elm_Gengrid_Item_Class structure.
+        * It is used to append item to the gengrid.
+        *
+        * @return      the pointer of Elm_Gengrid_Item_Class created by elm_gengrid_item_class_new.
+        *                      It should be free by elm_gengrid_item_class_free if it is not used anymore.
+        * @see getItemClassStatic()
+        */
+       virtual Elm_Gengrid_Item_Class* getItemClassNew();
+
+       /**
+        * Gets Elm_Object_Item of this item instance after it is appened to gengrid.
+        *
+        * @return      the Elm_Object_Item
+        * @see setElmObjectItem()
+        */
+       Elm_Object_Item* getElmObjectItem();
+
+       /**
+        * Sets Elm_Object_Item, which is returned when this item is appended to gengrid.
+        * If this Elm_Object_Item is required in your gengrid item implementation, set it by this method.
+        * Then you can get it by getElmObjectItem method.
+        * After calling this method, consequently virtual method onSetElmObjectItem will be called.
+        *
+        * @param[in]   objItem The pointer of Elm_Object_Item
+        *
+        * @see getElmObjectItem()
+        * @see onSetElmObjectItem()
+        */
+       void setElmObjectItem(Elm_Object_Item* objItem);
+
+       /**
+        * Gets static callback function to be used to append item to the gengrid.
+        * Then callback will call onSelect( Elm_Object_Item* item ) method when callback is invoked.
+        *
+        * @see Evas_Smart_Cb
+        * @see onSelect()
+        */
+       static Evas_Smart_Cb getSelectCb();
+
+protected:
+       /**
+        * Override this method to do something when gengrid is selected.
+        * Before this, "selectCb" should be set as select callback of gengrid when this item is appended.
+        *
+        * @param[in]   objItem Elm_Object_Item of this instance
+        *
+        * @see selectCb()
+        */
+       virtual void onSelect(Elm_Object_Item* objItem);
+
+       /**
+        * Override this method to set more properties to Elm_Object_Item of this item.
+        * It is called when setElmObjectItem method is called to set the Elm_Object_Item pointer of this item.
+        *
+        * @param[in]   objItem Elm_Object_Item of this instance
+        *
+        * @see setElmObjectItem()
+        */
+       virtual void onSetElmObjectItem(Elm_Object_Item* objItem);
+
+       /**
+        * Attaches the pop-up to the view, which is the container view of this item.
+        *
+        * @param[in]   popup   The pointer to the pop-up instance to be attached
+        *
+        * @return      true the view is found and it is attached successfully.
+        */
+       bool attachToParentViewController(WViewController* popup);
+
+private:
+       WDECLARE_PRIVATE_IMPL(WGengridItem);
+       WDISABLE_COPY_AND_ASSIGN(WGengridItem);
+};
+
+#define WGENGRID_ITEM_DEL() [](void* data, Evas_Object* obj) \
+               { \
+                       WGengridItem* item = static_cast<WGengridItem*>(data); \
+                       delete item; \
+               }
+
+/**
+ * This is a helper function.
+ * Appends gengrid item to the gengrid. It helps to add gengrid item using WGengridItem class to gengrid.
+ * Internally setElmObjectItem method of the WGengridItem is called to set Elm_Object_Item pointer.
+ * The virtual method onSelect of WGengridItem class will be called when the item is selected.
+ *
+ * @param[in]  gengrid gengrid Evas Object
+ * @param[in]  itc             item class
+ * @param[in]  item    WGengridItem type object pointer to be appended
+ *
+ * @see gengrid_item_append
+ */
+WAPP_ASSIST_EXPORT Elm_Object_Item* wgengrid_item_append(Evas_Object* gengrid, const Elm_Gengrid_Item_Class* itc, WGengridItem* item);
+
+/**
+ * This is a helper function.
+ * Appends gengrid item to the gengrid. It helps to add gengrid item using WGengridItem class to gengrid.
+ * Internally setElmObjectItem method of the WGengridItem is called to set Elm_Object_Item pointer.
+ * When the item is selected, selectCb will be called instead of onSelect virtual method of the WGengridItem class.
+ *
+ * @param[in]  gengrid gengrid Evas Object
+ * @param[in]  itc             item class
+ * @param[in]  item    WGengridItem type object pointer
+ * @param[in]  selectCb        the callback function to be called when the item is selected
+ * @param[in]  userData        select callback function user data pointer
+ *
+ * @see gengrid_item_append
+ * @see wgengrid_item_append
+ */
+WAPP_ASSIST_EXPORT Elm_Object_Item* wgengrid_item_append_with_callback(Evas_Object* gengrid, const Elm_Gengrid_Item_Class* itc, WGengridItem* item, Evas_Smart_Cb selectCb, const void* userData);
+
+} // namespace
+
+
+
+#endif /* _APP_ASSIST_WGENGRID_ITEM_H_ */
diff --git a/inc/app-assist-efl/WGenlistItem.h b/inc/app-assist-efl/WGenlistItem.h
new file mode 100755 (executable)
index 0000000..ce13870
--- /dev/null
@@ -0,0 +1,175 @@
+/*
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0
+ *
+ * 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 _APP_ASSIST_WGENLIST_ITEM_H_
+#define _APP_ASSIST_WGENLIST_ITEM_H_
+
+#include <Evas.h>
+#include <Elementary.h>
+#include <functional>
+#include "WDefine.h"
+
+namespace app_assist {
+
+class WViewController;
+/**
+* @class       WGenlistItem
+* @brief       This class is
+*
+*
+* The %WGenlistItem is
+*/
+class WAPP_ASSIST_EXPORT WGenlistItem {
+public:
+       /**
+        * This is the default constructor for this class.
+        *
+        */
+       WGenlistItem();
+
+       /**
+        * This is the destructor for this class.
+        *
+        */
+       virtual ~WGenlistItem();
+public:
+       /**
+        * Override this method to create Elm_Genlist_Item_Class structure.
+        * It is used to append item to the genlist. Define static Elm_Getnlist_Item_Class variable and return it.
+        *
+        * @return      the pointer of Elm_Genlist_Item_Class instantiated as static variable.
+        *                      It is not needed to be free.
+        * @see getItemClassNew()
+        */
+       virtual Elm_Genlist_Item_Class* getItemClassStatic();
+
+       /**
+        * Override this method to create Elm_Genlist_Item_Class structure.
+        * It is used to append item to the genlist.
+        *
+        * @return      the pointer of Elm_Genlist_Item_Class created by elm_genlist_item_class_new.
+        *                      It should be free by elm_genlist_item_class_free if it is not used anymore.
+        * @see getItemClassStatic()
+        */
+       virtual Elm_Genlist_Item_Class* getItemClassNew();
+
+       /**
+        * Gets Elm_Object_Item of this item instance after it is appened to genlist.
+        *
+        * @return      the Elm_Object_Item
+        * @see setElmObjectItem()
+        */
+       Elm_Object_Item* getElmObjectItem();
+
+       /**
+        * Sets Elm_Object_Item, which is returned when this item is appended to genlist.
+        * If this Elm_Object_Item is required in your genlist item implementation, set it by this method.
+        * Then you can get it by getElmObjectItem method.
+        * After calling this method, consequently virtual method onSetElmObjectItem will be called.
+        *
+        * @param[in]   objItem The pointer of Elm_Object_Item
+        *
+        * @see getElmObjectItem()
+        * @see onSetElmObjectItem()
+        */
+       void setElmObjectItem(Elm_Object_Item* objItem);
+
+       /**
+        * Gets static callback function to be used to append item to the genlist.
+        * Then callback will call onSelect( Elm_Object_Item* item ) method when callback is invoked.
+        *
+        * @see Evas_Smart_Cb
+        * @see onSelect( Elm_Object_Item* item )
+        */
+       static Evas_Smart_Cb getSelectCb();
+
+protected:
+       /**
+        * Override this method to do something when genlist is selected.
+        * Before this, the function pointer returned by getSelectCb method, should be set as select callback of genlist when this item is appended.
+        *
+        * @param[in]   objItem Elm_Object_Item of this instance
+        *
+        * @see getSelectCb()
+        */
+       virtual void onSelect(Elm_Object_Item* objItem);
+
+       /**
+        * Override this method to set more properties to Elm_Object_Item of this item.
+        * It is called when setElmObjectItem method is called to set the Elm_Object_Item pointer of this item.
+        *
+        * @param[in]   objItem Elm_Object_Item of this instance
+        *
+        * @see setElmObjectItem()
+        */
+       virtual void onSetElmObjectItem(Elm_Object_Item* objItem);
+
+       /**
+        * Attaches the pop-up to the view, which is the container view of this item.
+        *
+        * @param[in]   popup   The pointer to the pop-up instance to be attached
+        *
+        * @return      true the view is found and it is attached successfully.
+        */
+       bool attachToParentViewController(WViewController* popup);
+
+private:
+       WDECLARE_PRIVATE_IMPL(WGenlistItem);
+       WDISABLE_COPY_AND_ASSIGN(WGenlistItem);
+};
+
+#define WGENLIST_ITEM_DEL() [](void* data, Evas_Object* obj) \
+               { \
+                       WGenlistItem* item = static_cast<WGenlistItem*>(data); \
+                       delete item; \
+               }
+/**
+ * This is a helper function.
+ * Appends genlist item to the genlist. It helps to add genlist item using WGenlistItem class to genlist.
+ * Internally setElmObjectItem method of the WGenlistItem is called to set Elm_Object_Item pointer.
+ * The virtual method onSelect of WGenlistItem class will be called when the item is selected.
+ *
+ * @param[in]  genlist genlist Evas Object
+ * @param[in]  itc             item class
+ * @param[in]  item    WGenlistItem type object pointer to be appended
+ * @param[in]  type    genlist item type
+ *
+ * @see genlist_item_append
+ */
+WAPP_ASSIST_EXPORT Elm_Object_Item* wgenlist_item_append(Evas_Object* genlist, const Elm_Genlist_Item_Class* itc, WGenlistItem* item, Elm_Genlist_Item_Type type);
+
+/**
+ * This is a helper function.
+ * Appends genlist item to the genlist. It helps to add genlist item using WGenlistItem class to genlist.
+ * Internally setElmObjectItem method of the WGenlistItem is called to set Elm_Object_Item pointer.
+ * When the item is selected, selectCb will be called instead of onSelect virtual method of the WGenlistItem class.
+ *
+ * @param[in]  genlist genlist Evas Object
+ * @param[in]  itc             item class
+ * @param[in]  item    WGenlistItem type object pointer to be appended
+ * @param[in]  type    genlist item type
+ * @param[in]  selectCb        the callback function to be called when the item is selected
+ * @param[in]  userData        select callback function user data pointer
+ *
+ * @see genlist_item_append
+ * @see wgenlist_item_append
+ */
+WAPP_ASSIST_EXPORT Elm_Object_Item* wgenlist_item_append_with_callback(Evas_Object* genlist, const Elm_Genlist_Item_Class* itc, WGenlistItem* item, Elm_Genlist_Item_Type type, Evas_Smart_Cb selectCb, const void* userData);
+
+} // namespace
+
+#endif /* _APP_ASSIST_WGENLIST_ITEM_H_ */
diff --git a/inc/app-assist-efl/WMenuPopupController.h b/inc/app-assist-efl/WMenuPopupController.h
new file mode 100755 (executable)
index 0000000..2bb4e5a
--- /dev/null
@@ -0,0 +1,86 @@
+/*
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0
+ *
+ * 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 _APP_ASSIST_WMENU_POPUP_CONTROLLER_H_
+#define _APP_ASSIST_WMENU_POPUP_CONTROLLER_H_
+
+#include <Evas.h>
+#include <Elementary.h>
+#include <functional>
+#include "WViewController.h"
+
+namespace app_assist {
+/**
+* @class       WMenuPopupController
+* @brief       This class is the menu pop-up class to make easy to manage menus.
+*
+*
+* The %WMenuPopupController is the menu pop-up class.
+*/
+class WAPP_ASSIST_EXPORT WMenuPopupController: public WViewController {
+public:
+       /**
+        * This is the constructor for this class.
+        *
+        */
+       WMenuPopupController();
+public:
+
+       /**
+        * Creates a menu pop-up.
+        *
+        * @param[in]   win                                     parent window evas object
+        * @param[in]   resizableObj            resizable base evas object. According to this size, menu popup will be resized.
+        *
+        * @return true if it is succeeded
+        */
+       bool createMenu(Evas_Object* win, Evas_Object* resizableObj);
+
+       /**
+        * Appends menu items.
+        *
+        * @param[in]   label                   label text of menu item
+        * @param[in]   selectItemCb    callback function object when the item is selected
+        *
+        * @return appended item. nullptr,if failed.
+        */
+       Elm_Object_Item* appendItem(const char* label, const std::function< void()>& selectItemCb);
+
+       /**
+        * Resize and show menu pop-up.
+        *
+        * @return true if it is succeeded
+        */
+       bool showMenu();
+       //
+protected:
+       /**
+        * This is the destructor for this class.
+        *
+        */
+       virtual ~WMenuPopupController();
+private:
+       virtual Evas_Object* onCreateView(Evas_Object* parent, void* param); //override;
+       virtual void onDestroy(); //override;
+private:
+       WDECLARE_PRIVATE_IMPL(WMenuPopupController);
+       WDISABLE_COPY_AND_ASSIGN(WMenuPopupController);
+};
+
+} // namespace
+
+#endif /* _APP_ASSIST_WMENU_POPUP_CONTROLLER_H_ */
diff --git a/inc/app-assist-efl/WNaviframeController.h b/inc/app-assist-efl/WNaviframeController.h
new file mode 100755 (executable)
index 0000000..2664391
--- /dev/null
@@ -0,0 +1,197 @@
+/*
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0
+ *
+ * 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 _APP_ASSIST_WNAVI_FRAME_CONTROLLER_H_
+#define _APP_ASSIST_WNAVI_FRAME_CONTROLLER_H_
+
+#include <functional>
+#include <Evas.h>
+#include <Eina.h>
+#include <Elementary.h>
+#include "WViewController.h"
+#include "IWWindowController.h"
+
+namespace app_assist {
+
+// forward declaration
+class WContentViewController;
+
+/**
+* @class       WNaviframeController
+* @brief       This class is the controller class of naviframe elementary.
+*
+*
+* The %WNaviframeController class is to control naviframe elementary.
+*/
+class WAPP_ASSIST_EXPORT WNaviframeController : public WViewController {
+public:
+       /**
+        * This is the default constructor for this class.
+        *
+        */
+       WNaviframeController();
+
+       /**
+        * Gets the class name.
+        *
+        * @return The class name
+        */
+       virtual const char* getClassName() const; //override;
+
+public:
+       /**
+        * Initializes and creates the evas object.
+        * "onCreate" will be called subsequently.
+        *
+        * @param[in]   parent  the parent evas object
+        * @param[in]   param   user data
+        *
+        * @return      true if the creation is succeeded, else false
+        * @see onCreate()
+        */
+       bool create(Evas_Object* parent, void* param); //final;
+
+       /**
+        * Destroy the instance. "onDestroy" will be called subsequently.
+        * The naviframe elementary will be deleted together.
+        *
+        * @see onDestroy()
+        */
+       void destroy(); //final;
+
+       /**
+        * Pushes the view controller instance into naviframe. "onPushToNaviframe" will be called subsequently.
+        * If the view controller is not yet called "create", it will be called internally.
+        *
+        * @param[in]   vc      the pointer to the view controller instance to be pushed
+        * @param[in]   vcName  the view controller instance name to be set when it is pushed.
+        * @param[in]   vcParam the user data to be passed as parameter of "create" method of the view controller.
+        *
+        * @return      true if succeed, else false
+        * @see onPushToNaviframe
+        */
+       bool push(WContentViewController* vc, const char* vcName, void* vcCreationParam);
+       bool push(WContentViewController* vc, const char* vcName);
+       bool push(WContentViewController* vc);
+
+       /**
+        * Destroy all views stacked on naviframe.
+        *
+        */
+       void destroyAllViewControllers();
+
+       /**
+        * Check if the view of view controller is on top of naviframe.
+        *
+        * @param[in]   vc      the pointer to the view controller instance to be checked
+        *
+        * @return      true if it is top, else false
+        */
+       bool isTopContentViewController(WContentViewController* vc);
+       /**
+        * Get the view controller on top of naviframe.
+        *
+        * @return      WContentViewController pointer related with naviframe item
+        */
+       WContentViewController* getTopContentViewController();
+public:
+
+       /**
+        * Sets a delegate function. It delegates onLastItemPop handling to delegateFunc.
+        * This is simpler alternative to overriding the virtual method onLastItemPop(), allowing direct use of WNaviframeController without sub-classing.
+        * If delegation is used, onLastItemPop() will not be called.
+        *
+        * @param[in]   delegateFunc    The pointer to delegate function
+        * @see onLastItemPop()
+        */
+       void setOnLastItemPop(const std::function<void(bool* popOut)>& delegateFunc);
+protected:
+
+       /**
+        * Override this method to create your own naviframe elementary.
+        *
+        * @param[in]   parent  The pointer to the parent evas object
+        * @param[in]   param   user data
+        * @return The pointer to naviframe evas object created
+        */
+       virtual Evas_Object* onCreateView(Evas_Object* parent, void* param); //override;
+
+       /**
+        * Override this method to do something on this instance deletion.
+        *
+        * @see destroy()
+        */
+       virtual void onDestroy(); //override;
+
+       /**
+        * Override this method to do something before pushing the view to the naviframe.
+        * In the overridden method, WNaviframeController::onPush should be called to do the base operation.
+        *
+        * @param[in]   vc      The pointer to the view controller instance to be pushed
+        * @param[in]   viewParam       user data to be passed from "push". It is passed to the "create" method of the WContentViewController class
+        *
+        * @return result
+        * @see push
+        */
+       virtual bool onPush(WContentViewController* vc, void* viewParam);
+
+       /**
+        * Override this method to do something before popping the view from the naviframe.
+        * If you override this method, call WNaviframeController::onItemPop at the bottom of your method to do the base operations.
+        *
+        * @param[in]   vc      The pointer to the view controller instance to be popped
+        * @param[in]   item    The pointer to the navi item
+        *
+        * @return      true the view will be popped out, false the view will not be popped.
+        * @see onLastItemPop()
+        */
+       virtual bool onItemPop(WContentViewController* vc, Elm_Object_Item* item);
+
+       /**
+        * Override this method to change how the application should work when last view is popped from naviframe.
+        * If you don't override it, the application will go background by default.
+        * Even though onLastItemPop is called, "onItemPop" will be called before.
+        *
+        * @param[out]  popOut  Set true, if you will pop out the last view and end the application. If not, set false before return
+        * @see onItemPop()
+        */
+       virtual void onLastItemPop(bool* popOut);
+
+       /**
+        * Gets the pointer to the IWWindowController type class instance.
+        * Usually it will be normal window instance, but if the naviframe created on UG module, it will be UG window instance.
+        * Through this returned pointer, you can get window related properties.
+        *
+        * @return The pointer to the IWWindowController type instance.
+        */
+//     IWWindowController* getWindowController();
+
+protected:
+       /**
+        * This is the destructor for this class.
+        *
+        */
+       virtual ~WNaviframeController();
+
+private:
+       WDECLARE_PRIVATE_IMPL(WNaviframeController);
+       WDISABLE_COPY_AND_ASSIGN(WNaviframeController);
+};
+
+} // namespace
+
+#endif /* _APP_ASSIST_WNAVI_FRAME_CONTROLLER_H_ */
diff --git a/inc/app-assist-efl/WPageSlideViewController.h b/inc/app-assist-efl/WPageSlideViewController.h
new file mode 100755 (executable)
index 0000000..c895dd3
--- /dev/null
@@ -0,0 +1,250 @@
+/*
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0
+ *
+ * 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 _APP_ASSIST_WPAGE_SLIDE_VIEW_CONTROLLER_H_
+#define _APP_ASSIST_WPAGE_SLIDE_VIEW_CONTROLLER_H_
+
+#include <Elementary.h>
+#include <functional>
+#include "WContentViewController.h"
+
+namespace app_assist {
+
+class IWWindowController;
+class WNaviframeController;
+
+/**
+* @class       WPageSlideViewController
+* @brief       This class provides slide view with pages
+*
+*
+* The %WPageSlideViewController is the class to provide slide page view.
+*/
+class WAPP_ASSIST_EXPORT WPageSlideViewController : public WContentViewController {
+public:
+       /**
+        * This is the default constructor for this class.
+        *
+        */
+       WPageSlideViewController();
+
+       /**
+        * Retuns the class name string
+        *
+        * @return class name
+        */
+       virtual const char* getClassName() const; //override;
+
+public:
+       /**
+        * Attaches WContentViewController ui object as a page
+        *
+        * @param[in]   view    WContentViewController object to be attached.
+        *
+        * @return true if succeeded.
+        * @see WContentViewController::onSetAsPageContent()
+        */
+       bool appendPage(WContentViewController* content);
+
+       /**
+        * Attaches WViewController ui object as a page.
+        *
+        * @param[in]   control WViewController instance to be attached.
+        *
+        * @return true if succeeded.
+        */
+       bool appendPage(WViewController* content);
+
+       /**
+        * Attaches empty ui object as a page
+        *
+        * @return true if succeeded.
+        */
+       bool appendPage();
+
+       /**
+        * Remove the page and delete its content.
+        *
+        * @param[in]   index   the index of the page.If it is out of range, it will fail.
+        *
+        * @return true if succeeded.
+        */
+       bool removePage(int index);
+
+       /**
+        * Resizes the page slide layout.
+        * Call this API when you append or remove pages by some events after creation is finished.
+        * If it is not called, the screen will not be updated.
+        * At the view creation time, you don't need to call this API.
+        *
+        * @see appendPage(), removePage()
+        */
+       void resizePageSlideLayout();
+
+       /**
+        * Sets the page WContentViewController. If the previous page WContentViewController is exist, it returns false.
+        *
+        * @param[in]   index   the index of the page
+        * @param[in]   view    WContentViewController object
+        */
+       bool setPageContent(int index, WContentViewController* view);
+
+       /**
+        * Sets the page WViewController. If the previous page WViewController is exist, it returns false.
+        *
+        * @param[in]   index   the index of the page
+        * @param[in]   control WViewController object
+        */
+       bool setPageContent(int index, WViewController* control);
+
+       /**
+        * Returns the number of page.
+        *
+        * @return the number of page
+        */
+       int getPageCount();
+
+       /**
+        * Gets the page instance.
+        *
+        * @param[in]   index   index of the page
+        *
+        * @return UI object
+        */
+       WViewController* getPageContent(int index);
+
+       /**
+        * Gets the current page index.
+        *
+        * @return The current page index
+        */
+       int getCurrentPageIndex();
+
+       /**
+        * Gets the scroller evas object.
+        *
+        *
+        * @return The pointer to the evas object of the scroller
+        */
+       Evas_Object* getScroller();
+
+       /**
+        * Sets the flag whether the scroller is shown or not.
+        *
+        * @param[in]   show    true if it should be shown.
+        */
+       void setScrollerShowState(bool show);
+
+       /**
+        * Changes to the page
+        *
+        * @param[in]   index                   the index of the page
+        * @param[in]   withAnimation   flag if animation is shown or not.
+        */
+       void showPage(int index, bool withAnimation);
+
+       /**
+        * Changes to the page. The animation effect is off.
+        *
+        * @param[in]   index                   the index of the page
+        */
+       void showPage(int index);
+
+public:
+       /**
+        * Sets a delegate function. It delegates onInitScroller handling to delegateFunc.  it is called when scroller is created.
+        * Use this to set additional property to the scroller.
+        *
+        * @param[in]   delegateFunc    The pointer to delegate function
+        *
+        * @see onInitScroller()
+        */
+       void setOnInitScroller(const std::function<void(Evas_Object* scroller)>& delegateFunc);
+
+       /**
+        * Sets 'scroll animation stop' event handling function.  it is called when scroll animation completed.
+        *
+        * The dir parameter to the handlerFunc tells in which direction the pages moved.
+        * If dir > 0, the page right to the previously shown page is now showing. Page slid from right to left.
+        * if dir < 0, the page left to the previously shown page is now showing. Page slid from left to right.
+        *
+        * @param[in]   handlerFunc     The pointer to handler function
+        */
+       void setOnScrollAnimStop(const std::function<void(int dir)>& handlerFunc);
+
+protected:
+       /**
+        * Unsets the page content. The page content is not deleted.
+        * It should be used with setPageContent method to set the page again.
+        *
+        * @param[in]   index   the index of the page
+        *
+        * @see setPageObject
+        */
+       WViewController* unsetPageContent(int index);
+
+protected:
+       /**
+        * Called when the view is created. It comes from WContentViewController class.
+        *
+        * @param[in]   parent  parent evas object
+        * @param[in]   viewParam       user parameter
+        */
+       virtual Evas_Object* onCreateView(Evas_Object* parent, void* viewParam); //override;
+
+       /**
+        * Called when the container properties are set by Naviframe or other container views.
+        * Sets container properties for any existing page views,
+        * so that those page views can access window and naviframe.
+        *
+        * @param[in]   naviframe       WNaviframe instance
+        * @param[in]   item    navi item pointer of container view which is pushed into naviframe.
+       */
+       virtual void onSetContainerProperties(WNaviframeController* naviframe, Elm_Object_Item* item); //override;
+
+       /**
+        * Called when the layout is created. It comes from WContentViewController class.
+        *
+        * @param[in]   parent  parent evas object
+        *
+        * @return The evas object of layout to be created.
+        */
+       virtual Evas_Object* onCreateLayout(Evas_Object* parent);
+
+       /**
+        * Called when the scroller is created.
+        * Override this to set additional property to the scroller.
+        *
+        * @param[in]   scroller        scroller evas object
+        *
+        * @see setOnInitScroller()
+        */
+       virtual void onInitScroller(Evas_Object* scroller);
+protected:
+       /**
+        * This is the destructor for this class.
+        *
+        */
+       virtual ~WPageSlideViewController();
+private:
+       WDECLARE_PRIVATE_IMPL(WPageSlideViewController);
+       WDISABLE_COPY_AND_ASSIGN(WPageSlideViewController);
+};
+
+} // namespace
+
+#endif /* _APP_ASSIST_WPAGE_SLIDE_VIEW_CONTROLLER_H_ */
diff --git a/inc/app-assist-efl/WPopupController.h b/inc/app-assist-efl/WPopupController.h
new file mode 100755 (executable)
index 0000000..57856f2
--- /dev/null
@@ -0,0 +1,168 @@
+/*
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0
+ *
+ * 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 _APP_ASSIST_WPOPUP_CONTROLLER_H_
+#define _APP_ASSIST_WPOPUP_CONTROLLER_H_
+
+#include "WViewController.h"
+#include <functional>
+
+namespace app_assist {
+/**
+* @class       WPopupController
+* @brief       This class is the pop-up class to make easy to create pop-up.
+*
+*
+* The %WPopupController is the general pop-up class.
+*/
+class WAPP_ASSIST_EXPORT WPopupController : public WViewController {
+public:
+       /**
+        * This is the default constructor for this class.
+        *
+        */
+       WPopupController();
+
+       /**
+        * This is the constructor with title and content string.
+        *
+        */
+       WPopupController(const char* title, const char* textContent);
+public:
+       /**
+        * Sets the title string of the pop-up.
+        *
+        * @param[in]   title   title text string
+        *
+        * @see setContent()
+        */
+       void setTitle(const char* title);
+
+       /**
+        * Sets the content string of the pop-up.
+        *
+        * @param[in]   text    content text string
+        *
+        * @see other setContent()
+        */
+       void setContent(const char* text);
+
+       /**
+        * Sets the content of the pop-up with WViewController instance.
+        * This instance life-time will be attached to WPopupController instance.
+        *
+        * @param[in]   control WViewController instance to be set
+        *
+        * @see other setContent()
+        */
+       void setContent(WViewController* control);
+
+       /**
+        * Sets the creation function of the content Evas Object of the pop-up.
+        *
+        * @param[in]   contentCreator  content creation function object. At this function, create the content evas object and return it.
+        *
+        * @see other setContent()
+        */
+       void setContent(const std::function<Evas_Object* (Evas_Object* parent)>& contentCreator);
+
+
+       /**
+        * Sets the string ID's domain name to be automatically translated on language change.
+        * The text content and title text should be set with string ID.
+        *
+        * @see setTitle( const char* title), setContent( const char* text)
+        */
+       void setTextTranslatable();
+
+       /**
+        * Sets the string ID's domain name to be automatically translated on language change. The text content and title text should be set with string ID.
+        * If you want to use other text domain, use this API exceptionally.
+        *
+        * @param[in]   textDomain      text domain name
+        *
+        * @see setTitle( const char* title), setContent( const char* text)
+        */
+       void setTextTranslatable(const char* textDomain);
+
+       /**
+        * Add buttons with button text string and button pressed callback function.
+        *
+        * @param[in]   buttonText      text string of button
+        * @param[in]   buttonCb        callback function object to be called when button is pressed.
+        *                          At this function, if it returns true, pop-up will be deleted. If not, pop-up will not.
+        * @param[in]   setPropertyCb callback function object.
+        *                            Through this function object, additional properties can be set to the button evas object.
+        *
+        * @return true if succeeded
+        */
+       bool addButton(const char* buttonText, const std::function<void(bool* destroyPopup)>& buttonCb, const std::function<void(Evas_Object* button)>& setPropertyCb);
+       bool addButton(const char* buttonText, const std::function<void(bool* destroyPopup)>& buttonCb);
+
+       /**
+        * Add handler function when back button is pressed.
+        * If it is not set, pop-up will be closed.
+        *
+        * @param[in]   backCb  call back function object.
+        *                      If it returns true, pop-up will be closed, if not, remained.
+        *
+        */
+       void setOnBack(const std::function<void(bool* destroyPopup)>& backCb);
+
+       /**
+        * Add handler function to set more properties of pop-up.
+        * It will be called just after pop-up evas object is created in onCreate method.
+        *
+        * @param[in]   addPropertiesCb callback function object
+        *
+        * @return true if succeeded
+        */
+       void setOnAddProperties(const std::function<void(Evas_Object* popup)>& addPropertiesCb);
+
+protected:
+       /**
+        * Override it, if you want to create your own pop-up. WPopupController::onCreate will be called at the end of that function.
+        * This method comes from WViewController class.
+        *
+        * @param[in]   parent  parent evas object
+        * @param[in]   param   user data
+        *
+        * @return Evas object created
+        */
+       virtual Evas_Object* onCreateView(Evas_Object* parent, void* param); //override;
+
+       /**
+        * It is called when pop-up instance is deleted. This method comes from WViewController class.
+        *
+        * @see onCreate()
+        */
+       virtual void onDestroy(); //override;
+
+protected:
+       /**
+        * This is the destructor for this class.
+        *
+        */
+       virtual ~WPopupController();
+private:
+       WDECLARE_PRIVATE_IMPL(WPopupController);
+       WDISABLE_COPY_AND_ASSIGN(WPopupController);
+};
+
+} // namespace
+
+#endif /* _APP_ASSIST_WPOPUP_CONTROLLER_H_ */
diff --git a/inc/app-assist-efl/WSignal.h b/inc/app-assist-efl/WSignal.h
new file mode 100755 (executable)
index 0000000..19b0c0f
--- /dev/null
@@ -0,0 +1,245 @@
+/*
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0
+ *
+ * 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 _APP_ASSIST_WSIGNAL_H_
+#define _APP_ASSIST_WSIGNAL_H_
+
+#include <functional>
+#include <map>
+#include <list>
+#include <Evas.h>
+#include "WSignalIdGenerator.h"
+#include "WSignalImpl.h"
+#include "WDebugBase.h"
+
+namespace app_assist {
+
+const unsigned int  WSIGNAL_INVALID_ID = 0;
+
+typedef unsigned int WSignal_ListenerId;
+
+/**
+* @class       WSignal
+* @brief       WSignal<Func> is a base template class. WSignal class is to provide the implementation of observer or publish-subscribe patterns.
+*
+*/
+template< typename Func >
+class WSignal {
+};
+
+/**
+* @class       WSignal
+* @brief       WSignal< Ret(Args...) > is template class when a callback function has return type and variadic arguments.
+*           Return type and arguments types and the number of arguments are decided by template parameters.
+*/
+template< typename Ret, typename... Args >
+class WSignal<Ret(Args...)> {
+public:
+       /**
+        * This is the default constructor for this class.
+        *
+        */
+       WSignal() : __guardFlag(false) {};
+
+       /**
+        * This is the destructor for this class.
+        *
+        */
+       virtual ~WSignal() { removeAllListeners(); };
+
+       /**
+        * Adds a listener function object to this signal object to get a signal.
+        *
+        * @param[in]   listener        callback function object
+        * @param[in]   evasObj         optional. evas object related to listener function object.
+        *                          When this evas object is deleted, automatically this listener will be removed from the signal object.
+        *                          Then you don't need to call removeListener method.
+        *                          If it is not set, do not miss call removeListener by yourself.
+        *
+        * @return the added listener id
+        *
+        * @see removeListener
+        */
+       WSignal_ListenerId addListener(const std::function< Ret(Args...) >& listener, Evas_Object* evasObj) { WSIGNAL_IMPL_ADD_LISTENER(listener, evasObj) }
+       WSignal_ListenerId addListener(const std::function< Ret(Args...) >& listener) { WSIGNAL_IMPL_ADD_LISTENER(listener, nullptr) }
+
+       /**
+        * Removes a listener function object from this signal object.
+        *
+        * @param[in]   id    listener id which is returned from addListener
+        *
+        * @see addListener
+        */
+       void removeListener(WSignal_ListenerId& id) { WSIGNAL_IMPL_REMOVE_LISTENER(id) }
+
+       /**
+        * Checks the validity of listener id.
+        *
+        * @param[in]   id    the id of a listener
+        *
+        * @return true, if it is valid.
+        *
+        * @see addListener
+        */
+       bool isValid(WSignal_ListenerId id) { WSIGNAL_IMPL_IS_VALID(id) }
+
+       /**
+        * Emits a signal to all added listeners.
+        *
+        * @param[in]   args    variadic arguments to be given to listeners
+        *
+        */
+       void emit(Args... args) { WSIGNAL_IMPL_EMIT(args) }
+
+       /**
+        * Gets the number of added listeners.
+        *
+        * @return the number of listeners
+        */
+       int getListenerCount() { WSIGNAL_IMPL_GET_LISTENER_COUNT() }
+
+       /**
+        * Removes all added listeners
+        *
+        */
+       void removeAllListeners() { WSIGNAL_IMPL_REMOVE_ALL_LISTENERS() }
+
+protected:
+       /**
+        * Overrides this method and set how to emit signals to listeners and how to handle the return value from listeners.
+        *
+        * @param[in]   args    variadic arguments to be given to listeners
+        */
+       virtual void onEmit(Args... args) = 0;
+protected:
+       WSIGNAL_IMPL_LISTENER_MAP(Ret, Args)
+
+private:
+       static void __listenerEvasObjDelCb(void* data, Evas* evas, Evas_Object* obj, void* event_info) { WSIGNAL_IMPL_LISTENER_EVAS_OBJECT_DEL_CB(data) }
+
+       bool __guardFlag;
+       std::list< std::unique_ptr<ListenerInfo> > __listAddedListeners;
+
+       WDISABLE_COPY_AND_ASSIGN(WSignal);
+};
+
+/**
+* @class       WSignal
+* @brief       WSignal< void(Args...) > is template class when a callback function has no return type and variadic arguments.
+*           Arguments types and the number of arguments are decided by template parameters.
+*
+*/
+template< typename... Args >
+class WSignal<void(Args...)> {
+public:
+       /**
+        * This is the default constructor for this class.
+        *
+        */
+       WSignal() : __guardFlag(false) {};
+       /**
+        * This is the destructor for this class.
+        *
+        */
+       virtual ~WSignal() { removeAllListeners(); };
+
+       /**
+        * Adds a listener function object to this signal object to get a signal.
+        *
+        * @param[in]   listener        callback function object
+        * @param[in]   evasObj         optional. evas object related to listener function object.
+        *                          When this evas object is deleted, automatically this listener will be removed from the signal object.
+        *                          Then you don't need to call removeListener method.
+        *                          If it is not set, do not miss call removeListener by yourself.
+        *
+        * @return the added listener id
+        *
+        * @see removeListener
+        */
+       WSignal_ListenerId addListener(const std::function< void(Args...) >& listener, Evas_Object* evasObj) { WSIGNAL_IMPL_ADD_LISTENER(listener, evasObj) }
+       WSignal_ListenerId addListener(const std::function< void(Args...) >& listener) { WSIGNAL_IMPL_ADD_LISTENER(listener, nullptr) }
+
+       /**
+        * Removes a listener function object from this signal object.
+        *
+        * @param[in]   id    listener id which is returned from addListener
+        *
+        * @see addListener
+        */
+       void removeListener(WSignal_ListenerId& id) { WSIGNAL_IMPL_REMOVE_LISTENER(id) }
+
+       /**
+        * Checks the validity of listener id.
+        *
+        * @param[in]   id    the id of a listener
+        *
+        * @return true, if it is valid.
+        *
+        * @see addListener
+        */
+       bool isValid(WSignal_ListenerId id) { WSIGNAL_IMPL_IS_VALID(id) }
+
+       /**
+        * Emits a signal to all added listeners.
+        *
+        * @param[in]   args    variadic arguments to be given to listeners
+        *
+        */
+       void emit(Args... args) { WSIGNAL_IMPL_EMIT(args) }
+
+       /**
+        * Gets the number of added listeners.
+        *
+        * @return the number of listeners
+        */
+       int getListenerCount() { WSIGNAL_IMPL_GET_LISTENER_COUNT() }
+
+       /**
+        * Removes all added listeners
+        *
+        */
+       void removeAllListeners() { WSIGNAL_IMPL_REMOVE_ALL_LISTENERS() }
+
+protected:
+       /**
+        * Overrides this method to change how to send signals to listeners.
+        * The default implementation is to call listeners' callback sequentially.
+        *
+        * @param[in]   args    variadic arguments to be given to listeners
+        */
+       virtual void onEmit(Args... args)
+        {
+               for ( auto& it : __mapListeners ) {
+                       if (it.second->removed) continue;
+                       it.second->cb(args...);
+               }
+       }
+protected:
+       WSIGNAL_IMPL_LISTENER_MAP(void, Args)
+
+private:
+       static void __listenerEvasObjDelCb(void* data, Evas* evas, Evas_Object* obj, void* event_info) { WSIGNAL_IMPL_LISTENER_EVAS_OBJECT_DEL_CB(data) }
+
+       bool __guardFlag;
+       std::list< std::unique_ptr<ListenerInfo> > __listAddedListeners;
+
+       WDISABLE_COPY_AND_ASSIGN(WSignal);
+};
+
+} // namespace
+
+#endif /* _APP_ASSIST_WSIGNAL_H_ */
diff --git a/inc/app-assist-efl/WSignalIdGenerator.h b/inc/app-assist-efl/WSignalIdGenerator.h
new file mode 100755 (executable)
index 0000000..bb117c6
--- /dev/null
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0
+ *
+ * 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 _APP_ASSIST_WSIGNAL_ID_GENERATOR_H_
+#define _APP_ASSIST_WSIGNAL_ID_GENERATOR_H_
+
+#include "WDefine.h"
+
+namespace app_assist {
+
+class WAPP_ASSIST_EXPORT WSignalIdGenerator {
+public:
+       /**
+        * Gets the unique id for WSignal listener.
+        * WSignal class internal use only
+        *
+        * @return the id
+        *
+        * @see addListener
+        */
+       static unsigned int generate();
+};
+
+} // namespace
+
+#endif /* _APP_ASSIST_WSIGNAL_ID_GENERATOR_H_ */
diff --git a/inc/app-assist-efl/WSignalImpl.h b/inc/app-assist-efl/WSignalImpl.h
new file mode 100755 (executable)
index 0000000..f36fc41
--- /dev/null
@@ -0,0 +1,128 @@
+/*
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0
+ *
+ * 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 _APP_ASSIST_WSIGNAL_IMPL_H_
+#define _APP_ASSIST_WSIGNAL_IMPL_H_
+
+#define WSIGNAL_IMPL_ADD_LISTENER(listener, obj) \
+               WSignal_ListenerId id = WSignalIdGenerator::generate(); \
+               auto l = app_assist::make_unique<ListenerInfo>();               \
+               l->cb = listener;                                                                               \
+               l->evasObj = obj;                                                                       \
+               l->id = id;                                                                                             \
+               l->signal = this;                                                                               \
+               if( __guardFlag )                                                                               \
+               {                                                                                                               \
+                       __listAddedListeners.push_back(std::move(l));           \
+               }                                                                                                               \
+               else                                                                                                    \
+               {                                                                                                               \
+                       __mapListeners[id] = std::move(l);                                      \
+                       if( obj )                                                                               \
+                               evas_object_event_callback_add(obj, EVAS_CALLBACK_DEL, __listenerEvasObjDelCb, __mapListeners[id].get());       \
+               }                                                                                                               \
+               return id;
+
+#define WSIGNAL_IMPL_REMOVE_LISTENER(id) \
+               if( id == WSIGNAL_INVALID_ID ) return;                                  \
+               auto it = __mapListeners.find(id);                                      \
+               if( it != __mapListeners.end() )                                                \
+               {                                                                                                               \
+                       if( it->second->evasObj )                                                       \
+                               evas_object_event_callback_del_full(it->second->evasObj, EVAS_CALLBACK_DEL, __listenerEvasObjDelCb, it->second.get());  \
+                       if( __guardFlag )                                                                       \
+                               it->second->removed = true;                                             \
+                       else                                                                                            \
+                               __mapListeners.erase(id);                                               \
+               }                                                                                                               \
+               else                                                                                                    \
+               {                                                                                                               \
+                       WERROR("Already removed listener! =%d", id);    \
+               }                                                                                                               \
+               id = WSIGNAL_INVALID_ID;
+
+#define WSIGNAL_IMPL_IS_VALID(id) \
+               if( id == WSIGNAL_INVALID_ID ) return false;                    \
+               auto it = __mapListeners.find(id);                                              \
+               if( it != __mapListeners.end() )                                                \
+                       return true;                                                                            \
+               else                                                                                                    \
+                       return false;
+
+#define WSIGNAL_IMPL_EMIT(args) \
+               __guardFlag = true;                                                                             \
+               onEmit(args...);                                                                                \
+               __guardFlag = false;                                                                    \
+               for( auto it = __mapListeners.begin(); it != __mapListeners.end(); )    \
+               {                                                                                                               \
+                       if( it->second->removed )                                                       \
+                               __mapListeners.erase(it++);                                             \
+                       else                                                                                            \
+                               it++;                                                                                   \
+               }                                                                                                               \
+               if( __listAddedListeners.empty() == false )                             \
+               {                                                                                                               \
+                       for( auto& elem : __listAddedListeners )                        \
+                       {                                                                                                       \
+                               WSignal_ListenerId id = elem->id;                               \
+                               __mapListeners[id] = std::move(elem);                   \
+                               if( __mapListeners[id]->evasObj )                               \
+                                       evas_object_event_callback_add(__mapListeners[id]->evasObj, EVAS_CALLBACK_DEL, __listenerEvasObjDelCb, __mapListeners[id].get());       \
+                       }                                                                                                       \
+                       __listAddedListeners.clear();                                           \
+               }
+
+#define WSIGNAL_IMPL_GET_LISTENER_COUNT() \
+               return __mapListeners.size();
+
+
+#define WSIGNAL_IMPL_REMOVE_ALL_LISTENERS() \
+               for( auto& it : __mapListeners )                                                \
+               {                                                                                                               \
+                       if( it.second->evasObj )                                                        \
+                               evas_object_event_callback_del_full(it.second->evasObj, EVAS_CALLBACK_DEL, __listenerEvasObjDelCb, it.second.get());    \
+                       if( __guardFlag)                                                                        \
+                               it.second->removed = true;                                              \
+               }                                                                                                               \
+               if( __guardFlag == false )                                                              \
+                       __mapListeners.clear();
+
+
+#define WSIGNAL_IMPL_LISTENER_MAP(Ret, Args)   \
+       struct ListenerInfo                                                                                     \
+       {                                                                                                                       \
+               ListenerInfo(): evasObj(nullptr), removed(false), id(0), signal(nullptr){}      \
+               ~ListenerInfo(){}                                                                               \
+               std::function< Ret(Args...)> cb;                                                \
+               Evas_Object* evasObj;                                                                   \
+               bool removed;                                                                                   \
+               WSignal_ListenerId id;                                                                  \
+               WSignal<Ret(Args...)>* signal;                                                  \
+       };                                                                                                                      \
+       std::map< WSignal_ListenerId, std::unique_ptr<ListenerInfo> > __mapListeners;
+
+#define WSIGNAL_IMPL_LISTENER_EVAS_OBJECT_DEL_CB(data) \
+               auto li = (ListenerInfo*)(data);                                                \
+               li->evasObj = nullptr;                                                                  \
+               if( li->signal->__guardFlag )                                                   \
+               {                                                                                                               \
+                       li->removed = true;                                                                     \
+                       return;                                                                                         \
+               }                                                                                                               \
+               li->signal->removeListener(li->id);
+
+#endif /* _APP_ASSIST_WSIGNAL_IMPL_H_ */
diff --git a/inc/app-assist-efl/WUiThread.h b/inc/app-assist-efl/WUiThread.h
new file mode 100755 (executable)
index 0000000..13ca6cb
--- /dev/null
@@ -0,0 +1,232 @@
+/*
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0
+ *
+ * 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 _APP_ASSIST_WUI_THREAD_H_
+#define _APP_ASSIST_WUI_THREAD_H_
+
+#include <functional>
+#include <Ecore.h>
+#include "WDefine.h"
+
+namespace app_assist {
+
+/**
+* @class       WUiThread
+* @brief       This class is implemented based on ecore thread module.
+*
+* The %WUiThread is the class managing ecore thread
+*/
+class WAPP_ASSIST_EXPORT WUiThread
+{
+public:
+       WUiThread();
+       virtual ~WUiThread();
+
+public:
+       /**
+       * @class        IStatus
+       * @brief        WUiThread inner class for thread worker function
+       *
+       */
+       class IStatus
+       {
+       public:
+               virtual ~IStatus(){};
+               //
+               /**
+                * Check if cancellation is requested or not.
+                * If it returns true, thread worker function can do exit from the thread.
+                *
+                * @param[in]   thread  the thread pointer given from worker function parameter
+                *
+                * @return true if the cancellation is requested by cancel() method.
+                * @see cancel()
+                * @see ecore_thread_check()
+                */
+               virtual bool isCancelRequested(Ecore_Thread* thread) = 0;
+
+               /**
+                * Gets a integer data sent from the main thread.
+                * After getting this data, this data will be removed from ecore_thread_global_data.
+                *
+                * @return The integer data set by setThreadGlobalDataInt method.
+                *                      If it returns -1, it means that there is no data come.
+                * @see setThreadGlobalDataInt()
+                * @see ecore_thread_global_data_find()
+                */
+               virtual int getThreadGlobalDataInt() = 0;
+
+               /**
+                * Gets a integer data sent from the main thread with a key.
+                * After getting this data, this data and key will be removed from ecore_thread_global_data.
+                *
+                * @return The integer data set by setThreadGlobalDataInt method.
+                *                      If it returns -1, it means that there is no data come.
+                * @see setThreadGlobalDataInt()
+                * @see ecore_thread_global_data_find()
+                */
+               virtual int getThreadGlobalDataInt(const char* key) = 0;
+
+               /**
+                * Sends feedback to main thread.
+                * It leads to call notify callback set by setNotifyCb method. If it is not set, this method will not do anything.
+                *
+                * @param[in]   thread  the thread pointer given from worker function parameter
+                * @param[in]   userData        user data
+                *
+                * @return true if succeeded
+                * @see ecore_thread_feedback()
+                * @see ecore_thread_feedback_run()
+                */
+               virtual bool sendFeedback(Ecore_Thread* thread, void* msgData) = 0;
+       };
+       /**
+        * Sets the thread worker function
+        *
+        * @param[in]   func    the thread worker function
+        *
+        * @return false, if the thread is already created and running
+        * @see ecore_thread_run()
+        * @see ecore_thread_feedback_run()
+        */
+       bool setWorker(const std::function<void(WUiThread::IStatus* threadStatus, Ecore_Thread* thread)>& func);
+
+       /**
+        * Sets the thread end callback function.
+        * It is called in the main thread context, when the thread worker function exits normally without cancellation request.
+        * If the cancellation is requested, the cancel callback will be called instead of this end callback.
+        *
+        * @param[in]   endCb   the thread end callback function
+        *
+        * @return false, if the thread is already created and running
+        * @see setCancelCb()
+        * @see ecore_thread_run()
+        * @see ecore_thread_feedback_run()
+        */
+       bool setEndCb(const std::function<void()>& endCb);
+
+       /**
+        * Sets the thread cancel callback function.
+        * It is called in the main thread context, when the thread worker function exits with cancellation request.
+        * When it becomes to be called, the end callback will not be called.
+        *
+        * @param[in]   cancelCb        the thread cancel callback function
+        *
+        * @return false, if the thread is already created and running
+        * @see setEndCb()
+        * @see ecore_thread_run()
+        * @see ecore_thread_feedback_run()
+        */
+       bool setCancelCb(const std::function<void()>& cancelCb);
+
+       /**
+        * Sets the thread feedback notification callback function.
+        * It is called in the main thread context, when the sendFeedback method is called in the thread worker function.
+        *
+        * @param[in]   notifyCb        the thread feedback notification callback function
+        *
+        * @return false, if the thread is already created and running
+        * @see ecore_thread_feedback_run()
+        */
+       bool setNotifyCb(const std::function<void(WUiThread* thread, void* msgData)>& notifyCb);
+
+public:
+       /**
+        * Starts the thread.
+        *
+        * @return false, if the thread is already created and running or failed.
+        *
+        * @see setWorker()
+        * @see ecore_thread_run()
+        * @see ecore_thread_feedback_run()
+        */
+       bool run();
+
+       /**
+        * Send cancellation message to the thread and wait the thread work function to exit, with timeout timer.
+        * The thread is not cancelled by the framework.
+        * In the your worker function, It should be checked if cancellation is request or not by calling isCancelRequested periodically.
+        * If this checking interval is long, it will be blocked for that much time.
+        * When the thread worker function exits, cancel callback will be called set by setCancelCb method.
+        * In public SDK, time-out is NOT SUPPORTED.So you should wait cancel callback to check the cancellation is completed.
+        *
+        * @param[in] waitSeconds       timeout time in seconds (NOT SUPPORTED in public SDK)
+        *
+        * @return false, if it is timeout.
+        *
+        * @see setCancelCb()
+        * @see isCancelRequested()
+        * @see ecore_thread_cancel()
+        * @see ecore_thread_wait()
+        */
+       bool cancel(double waitSeconds);
+
+       /**
+        * Wait the thread worker function to exit for the time.
+        * This method is NOT SUPPORTED in public SDK!
+        *
+        * @param[in] waitSeconds       timeout time in seconds (NOT SUPPORTED in public SDK)
+        *
+        * @return false, if it is timeout.
+        * @see ecore_thread_wait()
+        */
+       bool wait(double waitSeconds);
+
+       /**
+        * Cancel the thread without calling cancel callback.
+        * It works same as cancel method, but cancel or end callback function will not be called.
+        * In the destructor, this method is called to cancel the running thread.
+        *
+        * @param[in] waitSeconds       timeout time in seconds (NOT SUPPORTED in public SDK)
+        *
+        * @return false, if it is timeout.
+        *
+        * @see cancel()
+        */
+       bool cancelWithoutCallback(double waitSeconds);
+
+       /**
+        * Sets a integer data to be get in the thread.
+        * In the thread worker function, this data can be get by getThreadGlobalDataInt method.
+        *
+        * @param[in] data      a message data
+        *
+        * @see getThreadGlobalDataInt()
+        * @see ecore_thread_global_data_set()
+        */
+       void setThreadGlobalDataInt(int data);
+
+       /**
+        * Sets a integer data with the key to be get in the thread.
+        * In the thread worker function, this data can be get by getThreadGlobalDataInt method.
+        *
+        * @param[in] key       a key of message
+        * @param[in] data      a data message
+        *
+        * @see getThreadGlobalDataInt()
+        * @see ecore_thread_global_data_set()
+        */
+    void setThreadGlobalDataInt(const char* key, int data);
+
+private:
+       WDECLARE_PRIVATE_IMPL(WUiThread);
+       WDISABLE_COPY_AND_ASSIGN(WUiThread);
+};
+
+} // namespace
+
+#endif /* _APP_ASSIST_WUI_THREAD_H_ */
diff --git a/inc/app-assist-efl/WUiTimer.h b/inc/app-assist-efl/WUiTimer.h
new file mode 100755 (executable)
index 0000000..35598b8
--- /dev/null
@@ -0,0 +1,239 @@
+/*
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0
+ *
+ * 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 _APP_ASSIST_WUI_TIMER_H_
+#define _APP_ASSIST_WUI_TIMER_H_
+
+#include <Eina.h>
+#include <Ecore.h>
+#include <Evas.h>
+#include <functional>
+#include "WDefine.h"
+
+namespace app_assist {
+
+class WUiTimer;
+
+typedef std::weak_ptr<WUiTimer> WUiTimerWeakPtr;
+
+/**
+* @class       WUiTimer
+* @brief       This class wraps ecore timer module.
+*
+*
+* The %WUiTimer is the class managing ecore timer
+*/
+class WAPP_ASSIST_EXPORT WUiTimer {
+public:
+       enum class Type {
+               IDLER,          ///< Can be called multiple times with in one rendering cycle, based on system load.
+               ANIMATOR,       ///< Called just once per rendering cycle.
+               TIMER,          ///< Called just once per rendering cycle, if the "set time" is elapsed before next vsync.
+               JOB                     ///< Called just once per registration prior to timer, idler and animator.
+       };
+
+       /**
+        * Returns type of timer.
+        *
+        * @return timer type
+        * @see enum class Type
+        */
+       WUiTimer::Type getType();
+
+       /**
+        * Deletes this instance.
+        * The created timer will be deleted together.
+        *
+        * @param[in,out]       timer   the reference type of weak pointer of WUiTimer instance. timer variable will be reset.
+        *
+        */
+       static void destroy(WUiTimerWeakPtr& timer);
+
+       /**
+        * Creates a IDLER type timer. It uses ecore_idler internally.
+        * It can be called multiple times with in one rendering cycle, based on system load.
+        *
+        * @param[in]   timerFunc       std::function object of worker function
+        * @param[in]   userData        user data
+        * @param[in]   ownerObj        the owner Evas_Object
+        *                                                      When this Evas Object is deleted, the WUiTimer will be deleted together, if it is still alive.
+        *                                                      nullptr is not allowed.
+        *
+        * @return The weak pointer of WUiTimer instance created. The validity of the pointer can be checked with the lock() method.
+        *         If it is failed or invalid when lock() method is called with this weak pointer will return empty shared_ptr.
+        */
+       static WUiTimerWeakPtr addIdler(const std::function<Eina_Bool(void* userData)>& timerFunc, void* userData, Evas_Object* ownerObj);
+
+       /**
+        * Creates a IDLER type timer. It uses ecore_idler internally.
+        * It can be called multiple times with in one rendering cycle, based on system load.
+        *
+        * @param[in]   timerFunc       std::function object of worker function
+        * @param[in]   userData        user data
+        *
+        * @return The weak pointer of WUiTimer instance created. The validity of the pointer can be checked with the lock() method.
+        *         If it is failed or invalid when lock() method is called with this weak pointer will return empty shared_ptr.
+        *         The returned value should be released by WUiTimer::destroy().
+        */
+       static WUiTimerWeakPtr addIdler(const std::function<Eina_Bool(void* userData)>& timerFunc, void* userData);
+
+       /**
+        * Creates a ANIMATOR type timer. It uses ecore_animator internally.
+        * It will be called just once per rendering cycle.
+        *
+        * @param[in]   timerFunc       std::function object of worker function
+        * @param[in]   userData        user data
+        * @param[in]   ownerObj        the owner Evas_Object
+        *                                                      When this Evas Object is deleted, the WUiTimer will be deleted together, if it is still alive.
+        *                                                      nullptr is not allowed.
+        *
+        * @return The weak pointer of WUiTimer instance created. The validity of the pointer can be checked with the lock() method.
+        *         If it is failed or invalid when lock() method is called with this weak pointer will return empty shared_ptr.
+        */
+       static WUiTimerWeakPtr addAnimator(const std::function<Eina_Bool(void* userData)>& timerFunc, void* userData,  Evas_Object* ownerObj);
+
+       /**
+        * Creates a ANIMATOR type timer. It uses ecore_animator internally.
+        * It will be called just once per rendering cycle.
+        *
+        * @param[in]   timerFunc       std::function object of worker function
+        * @param[in]   userData        user data
+        *
+        * @return The weak pointer of WUiTimer instance created. The validity of the pointer can be checked with the lock() method.
+        *         If it is failed or invalid when lock() method is called with this weak pointer will return empty shared_ptr.
+        *         The returned value should be released by WUiTimer::destroy().
+        */
+       static WUiTimerWeakPtr addAnimator(const std::function<Eina_Bool(void* userData)>& timerFunc, void* userData);
+
+       /**
+        * Creates a timer. It uses ecore_timer internally.
+        * It will be called just once per rendering cycle, if the "set time" is elapsed before next vsync.
+        *
+        * @param[in]   interval        The interval in seconds.
+        * @param[in]   timerFunc       std::function object of worker function
+        * @param[in]   userData        user data
+        * @param[in]   ownerObj        the owner Evas_Object
+        *                                                      When this Evas Object is deleted, the WUiTimer will be deleted together, if it is still alive.
+        *                                                      nullptr is not allowed.
+        *
+        * @return The weak pointer of WUiTimer instance created. The validity of the pointer can be checked with the lock() method.
+        *         If it is failed or invalid when lock() method is called with this weak pointer will return empty shared_ptr.
+        */
+       static WUiTimerWeakPtr addTimer(double interval, const std::function<Eina_Bool(void* userData)>& timerFunc, void* userData,  Evas_Object* ownerObj);
+
+       /**
+        * Creates a timer. It uses ecore_timer internally.
+        * It will be called just once per rendering cycle, if the "set time" is elapsed before next vsync.
+        *
+        * @param[in]   interval        The interval in seconds.
+        * @param[in]   timerFunc       std::function object of worker function
+        * @param[in]   userData        user data
+        *
+        * @return The weak pointer of WUiTimer instance created. The validity of the pointer can be checked with the lock() method.
+        *         If it is failed or invalid when lock() method is called with this weak pointer will return empty shared_ptr.
+        *         The returned value should be released by WUiTimer::destroy().
+        */
+       static WUiTimerWeakPtr addTimer(double interval, const std::function<Eina_Bool(void* userData)>& timerFunc, void* userData);
+
+       /**
+        * Creates a JOB type timer. It uses ecore_job internally.
+        * It will be called just once per registration prior to timer, idler and animator.
+        *
+        * @param[in]   timerFunc       std::function object of worker function
+        * @param[in]   userData        user data
+        * @param[in]   ownerObj        the owner Evas_Object
+        *                                                      When this Evas Object is deleted, the WUiTimer will be deleted together, if it is still alive.
+        *                                                      nullptr is not allowed.
+        *
+        * @return The weak pointer of WUiTimer instance created. The validity of the pointer can be checked with the lock() method.
+        *         If it is failed or invalid when lock() method is called with this weak pointer will return empty shared_ptr.
+        */
+       static WUiTimerWeakPtr addJob(const std::function<void(void* userData)>& timerFunc, void* userData,  Evas_Object* ownerObj);
+
+       /**
+        * Creates a JOB type timer. It uses ecore_job internally.
+        * It will be called just once per registration prior to timer, idler and animator.
+        *
+        * @param[in]   timerFunc       std::function object of worker function
+        * @param[in]   userData        user data
+        *
+        * @return The weak pointer of WUiTimer instance created. The validity of the pointer can be checked with the lock() method.
+        *         If it is failed or invalid when lock() method is called with this weak pointer will return empty shared_ptr.
+        *         The returned value should be released by WUiTimer::destroy().
+        */
+       static WUiTimerWeakPtr addJob(const std::function<void(void* userData)>& timerFunc, void* userData);
+private:
+       WUiTimer();
+       ~WUiTimer();
+
+private:
+       WDECLARE_PRIVATE_IMPL(WUiTimer);
+       WDISABLE_COPY_AND_ASSIGN(WUiTimer);
+};
+
+/**
+ * Gets Ecore_Idler handle pointer.
+ * Do not call ecore_idler_del with this returned pointer, because it is internal property of this WUiTimer instance.
+ * To delete the Ecore_Idler, call destroy method of this WUiTimer class.
+ *
+ * @param[in]  uiTimer the reference of WUiTimer weak pointer
+ *
+ * @return Ecore_Idler handle pointer
+ * @see addIder()
+ */
+WAPP_ASSIST_EXPORT Ecore_Idler* wuitimer_get_idler_handle(const WUiTimerWeakPtr& uiTimer);
+
+/**
+ * Gets Ecore_Animator handle pointer.
+ * Do not call ecore_animator_del with this returned pointer, because it is internal property of this WUiTimer instance.
+ * To delete the Ecore_Animator, call destroy method of this WUiTimer class.
+ *
+ * @param[in]  uiTimer the reference of WUiTimer weak pointer
+ *
+ * @return Ecore_Animator handle pointer
+ * @see addAnimator()
+ */
+WAPP_ASSIST_EXPORT Ecore_Animator* wuitimer_get_animator_handle(const WUiTimerWeakPtr& uiTimer);
+
+/**
+ * Gets Ecore_Timer handle pointer.
+ * Do not call ecore_timer_del with this returned pointer, because it is internal property of this WUiTimer instance.
+ * To delete the Ecore_Timer, call destroy method of this WUiTimer class.
+ *
+ * @param[in]  uiTimer the reference of WUiTimer weak pointer
+ *
+ * @return Ecore_Timer handle pointer
+ * @see addTimer()
+ */
+WAPP_ASSIST_EXPORT Ecore_Timer* wuitimer_get_timer_handle(const WUiTimerWeakPtr& uiTimer);
+
+/**
+ * Gets Ecore_Job handle pointer.
+ * Do not call ecore_job_del with this returned pointer, because it is internal property of this WUiTimer instance.
+ * To delete the Ecore_Job, call destroy method of this WUiTimer class.
+ *
+ * @param[in]  uiTimer the reference of WUiTimer weak pointer
+ *
+ * @return Ecore_Job handle pointer
+ * @see addJob()
+ */
+WAPP_ASSIST_EXPORT Ecore_Job* wuitimer_get_job_handle(const WUiTimerWeakPtr& uiTimer);
+
+
+} // namespace
+
+#endif /* _APP_ASSIST_WUI_TIMER_H_ */
diff --git a/inc/app-assist-efl/WViewController.h b/inc/app-assist-efl/WViewController.h
new file mode 100755 (executable)
index 0000000..f9346e8
--- /dev/null
@@ -0,0 +1,222 @@
+/*
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0
+ *
+ * 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 _APP_ASSIST_WVIEW_CONTROLLER_H_
+#define _APP_ASSIST_WVIEW_CONTROLLER_H_
+
+#include <functional>
+#include <memory>
+#include <Evas.h>
+#include "WDefine.h"
+#include "IWWindowController.h"
+
+namespace app_assist {
+
+class WViewController;
+
+typedef std::weak_ptr<WViewController> WViewControllerWeakPtr;
+
+/**
+* @class       WViewController
+* @brief       This class is the UI control class linked with one evas object.
+*
+*
+* The %WViewController is the abstract class managing an evas object
+*/
+class WAPP_ASSIST_EXPORT WViewController {
+public:
+       /**
+        * This is the default constructor for this class.
+        *
+        */
+       WViewController();
+
+       /**
+        * Gets class name
+        *
+        * @return The class name
+        */
+       virtual const char* getClassName() const;
+public:
+
+       /**
+        * Initializes and creates the control. onCreate will be called subsequently
+        *
+        * @param[in]   parent  parent evas object
+        * @param[in]   param   user data
+        *
+        * @return result
+        * @see onCreate()
+        */
+       virtual bool create(Evas_Object* parent, void* param);
+
+       /**
+        * Destroys the control. The linked evas object will be delete together.
+        * "onDestroy" will be called subsequently.
+        *
+        * @see onDestroy()
+        */
+       virtual void destroy();
+
+       /**
+        * Gets evas object of this class.
+        *
+        * @return The pointer to evas object
+        */
+       Evas_Object* getEvasObj() const;
+
+       /**
+        * Sets the name of the instance.
+        *
+        * @param[in]   name    blash
+        */
+       void setName(const char* name);
+
+       /**
+        * Gets the name of the instance.
+        *
+        * @return The control name
+        */
+       const char* getName() const;
+
+       /**
+        * Returns weak pointer of this instance to refer it safe.
+        *
+        * @return weak pointer of this class instance
+        */
+       WViewControllerWeakPtr getWeakPtr();
+
+       /**
+        * Attaches popup to the control.It means that it binds them to have same life-time.
+        * Internally create method of the pop-up will be called, if it is not yet created.
+        * If previous pop-up exists, it will be destroyed.
+        *
+        * @param[in]   popup pop-up instance pointer to be attached
+        *
+        * @see destroyPopup()
+        */
+       void attachPopup(WViewController* popup);
+
+       /**
+        * Destroys pop-up. Use this method when you want to destroy pop-up explicitly.
+        * Pop-up will be deleted when the control is deleted, although this method is not called.
+        *
+        * @see attachPopup()
+        */
+       void destroyPopup();
+public:
+       /**
+        * Sets a delegate function. It delegates onCreate handling to delegateFunc.
+        * This is simpler alternative to overriding the virtual method onCreate(), allowing direct use of WContentViewController without sub-classing.
+        * If delegation is used, onCreateView() will not be called.
+        *
+        * @param[in]   delegateFunc    The pointer to delegate function
+        * @see onCreateView()
+        */
+       void setOnCreateView(const std::function<Evas_Object* (Evas_Object* parent, void* param)>& delegateFunc);
+
+protected:
+       /**
+        * Override this method to initialize this WViewController class.
+        * It is called when create method is called.
+        *
+        * @param[in]   param   user parameter
+        *
+        * @return true if it is succeeded.
+        * @see create()
+        * @see onCreated()
+        */
+       virtual bool onCreate( void* param ) {return true;};
+       /**
+        * Override this method to create evas object of this WViewController class.
+        *
+        * @param[in]   parent  the parent evas object
+        * @param[in]   param   user parameter
+        *
+        * @return The pointer to evas object created, which should be the most parent evas object among them created in this method.
+        * @see create()
+        * @see onCreated()
+        */
+       virtual Evas_Object* onCreateView( Evas_Object* parent, void* param ) {return nullptr;}
+
+       /**
+        * Override this method to do something after evas object is created.
+        *
+        * @see create()
+        * @see onCreate()
+        */
+       virtual void onCreated() {};
+
+       /**
+        * Override this method to do something on this instance deletion.
+        *
+        * @see destroy()
+        */
+       virtual void onDestroy() {};
+
+       /**
+        * Gets the pointer to the IWWindowController type class instance.
+        * Usually it will be normal window instance, but if the view created on UG module, it will be UG window instance.
+        * Through this returned pointer, you can get window related properties.
+        *
+        * @return The pointer to the IWWindowController type instance.
+        */
+       IWWindowController* getWindowController();
+
+protected:
+       /**
+        * This is the destructor for this class.
+        *
+        */
+       virtual ~WViewController();
+
+private:
+       WDECLARE_PRIVATE_IMPL(WViewController);
+       WDISABLE_COPY_AND_ASSIGN(WViewController);
+};
+
+/**
+ * Gets the class instance from evas object
+ *
+ * @param[in]  obj     evas object
+ *
+ * @return The pointer to WViewController class instance. It will be nullptr, if no instance is related.
+ */
+WAPP_ASSIST_EXPORT WViewController* wviewcontroller_get_instance_from_evasobj(Evas_Object* obj);
+
+/**
+ * Get the evas object of window baseLayout related to view.
+ *
+ * @param[in]  view    WViewController instance
+ *
+ * @return nullptr, if this failed to get window baseLayout.
+ */
+WAPP_ASSIST_EXPORT Evas_Object* wviewcontroller_get_window_baselayout_evasobj(WViewController* view);
+
+/**
+ * Get the evas object of window related to view.
+ *
+ * @param[in]  view    WViewController instance
+ *
+ * @return nullptr, if this failed to get window.
+ */
+WAPP_ASSIST_EXPORT Evas_Object* wviewcontroller_get_window_evasobj(WViewController* view);
+
+} // namespace
+
+
+#endif /* _APP_ASSIST_WVIEW_CONTROLLER_H_ */
diff --git a/inc/app-assist-efl/WWindowController.h b/inc/app-assist-efl/WWindowController.h
new file mode 100755 (executable)
index 0000000..344eeb5
--- /dev/null
@@ -0,0 +1,246 @@
+/*
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0
+ *
+ * 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 _APP_ASSIST_WWINDOW_CONTROLLER_H_
+#define _APP_ASSIST_WWINDOW_CONTROLLER_H_
+
+#include <functional>
+#include <Evas.h>
+#include <Elementary.h>
+#include "WDefine.h"
+#include "IWWindowController.h"
+
+namespace app_assist {
+
+class WViewController;
+
+/**
+* @class       WWindowController
+* @brief       This class represents window and base layout evas object.
+*
+* The %WWindowController manages window evas object and common base evas objects.
+*/
+class WAPP_ASSIST_EXPORT WWindowController : public IWWindowController {
+public:
+       WWindowController() = delete;
+       /**
+        * Constructor
+        * Initializes this instance of WWindowController with the specified value.
+        *
+        * @param[in]   name    The window name
+        * @param[in]   winType The type of the window
+        */
+       WWindowController(const char* name, Elm_Win_Type winType);
+
+       /**
+        * Gets the class name of this class
+        *
+        * @return The class name
+        */
+       virtual const char* getClassName(); //override;
+public:
+       /**
+        * Creates the windows
+        * "onCreateWin" and "onCreateBaseLayout" will be called subsequently.
+        *
+        * @return true if the windows created sucessfully, else false
+        * @see onCreateWin()
+        * @see onCreateBaseLayout()
+        */
+       bool create();
+
+       /**
+        * Creates the windows but not be shown
+        * "onCreateWin" and "onCreateBaseLayout" will be called subsequently.
+        *
+        * @return true if the windows created sucessfully, else false
+        * @see create()
+        * @see onCreateWin()
+        * @see onCreateBaseLayout()
+        */
+       bool precreate();
+
+       /**
+        * Destroys the window class instance and delete window evas object.
+        * "onDestroy" will be called subsequently.
+        *
+        * @see onDestroy()
+        */
+       void destroy();
+
+       /**
+        * Gets the evas object of the window
+        *
+        * @return The pointer to the evas object of the window
+        * @see onCreateWin()
+        */
+       virtual Evas_Object* getEvasObj() const; //override;
+
+       /**
+        * Gets the base layout evas object
+        *
+        * @return The pointer to the evas object of the layout
+        * @see onCreateBaseLayout()
+        */
+       virtual Evas_Object* getBaseLayoutEvasObj(); //override;
+
+       /**
+        * Gets the conformant evas object.
+        *
+        * @return The pointer to the evas object of the conformant
+        */
+       virtual Evas_Object* getConformantEvasObj(); //override;
+
+       /**
+        * Gets the base UI object attached.
+        *
+        * @return The pointer to the base ui object
+        * @see attachBaseViewController()
+        */
+       virtual WViewController* getBaseViewController(); //override;
+
+       /**
+        * Attaches base UI object, which can be WViewController instance.
+        *
+        * @param[in]   baseObj WViewController instance to be attached
+        * @param[in]   creationParam   parameter to be passed as parameter of create method of the WViewController class
+        *
+        * @return true if the base ui object attached sucessfully, else false
+        * @see getBaseViewController()
+        */
+       bool attachBaseViewController(WViewController* vc, void* creationParam);
+       bool attachBaseViewController(WViewController* vc);
+
+       /**
+        * Detaches the base UI object.
+        *
+        * @return the base UI object, which should be deleted explicitly later.
+        */
+       WViewController* detachBaseViewController();
+
+       /**
+        * Destroys the base UI object.
+        *
+        */
+       void destroyBaseViewController();
+
+       /**
+        * Gets the window name
+        *
+        * @return The name of the window
+        */
+       const char* getName();
+
+       /**
+        * Gets the type of the window
+        *
+        * @return The type of the window
+        */
+       Elm_Win_Type getWinType();
+
+       /**
+        * Sets a delegate function. It delegates onCreateWin handling to delegateFunc.
+        * This is simpler alternative to overriding the virtual method onCreateWin(), allowing direct use of WWindowController without sub-classing.
+        * If delegation is used, onCreateWin() will not be called.
+        *
+        * @param[in]   delegateFunc     The pointer to delegate function
+        * @see onCreateWin()
+        */
+       void setOnCreateWin(const std::function<Evas_Object* ()>& delegateFunc);
+
+       /**
+        * Sets a delegate function. It delegates onCreateBaseLayout handling to delegateFunc.
+        * This is simpler alternative to overriding the virtual method onCreateBaseLayout(), allowing direct use of WWindowController without sub-classing.
+        * If delegation is used, onCreateBaseLayout() will not be called.
+        *
+        * @param[in]   delegateFunc     The pointer to delegate function
+        * @see onCreateBaseLayout()
+        */
+       void setOnCreateBaseLayout(const std::function<Evas_Object* (Evas_Object* win, Evas_Object** outConformant)>& delegateFunc);
+
+       /**
+        * Sets a back key handler function. It is called when 'back' key is pressed.
+        * Normally it is used for single view controller application without naviframe.
+        *
+        * @param[in]   backHandlerFunc     The pointer to handler function
+        */
+       void setOnBack(const std::function<void()>& backHandlerFunc);
+protected:
+       /**
+        * Called when create method is called to create window
+        * Override this method to create your own window evas object.
+        *
+        * @return The pointer to the evas object of the window created.
+        * @see create()
+        */
+       virtual Evas_Object* onCreateWin();
+
+       /**
+        * Called when create method is called to create base layout.
+        * Override this method to create your own base layout and conformant evas objects.
+        *
+        * @param[in]   win     A pointer to evas object of the window
+        * @param[out]  outConformant The pointer to the evas object of the conformant created.
+        *
+        * @return The pointer to the evas object of base layout created.
+        */
+       virtual Evas_Object* onCreateBaseLayout(Evas_Object* win, Evas_Object** outConformant);
+
+       /**
+        * Called when attachBaseViewController is called.
+        * Default behavior is to set the given base UI object to elm.swallow.content part of the default base layout.
+        * Override this method to add custom behaviors just before attachment, or if the default base layout is not used.
+        *
+        * @param[in]   vc      WViewController instance which is about to be attached
+        *
+        * @see attachBaseViewController()
+        */
+       virtual void onAttachBaseViewController(WViewController* vc);
+
+       /**
+        * Called when detachBaseViewController is called.
+        * Default behavior is to do nothing.
+        * Override this method to add custom behaviors just before detachment.
+        *
+        * @param[in]   vc      WViewController instance which is about to be detached
+        *
+        * @see detachBaseViewController()
+        */
+       virtual void onDetachBaseViewController(WViewController* vc);
+
+       /**
+        * Called when the window is destroyed
+        * Override this method to do something on destruction.
+        *
+        */
+       virtual void onDestroy();
+
+
+protected:
+       /**
+        * This is the destructor for this class.
+        *
+        */
+       virtual ~WWindowController();
+private:
+       WDECLARE_PRIVATE_IMPL(WWindowController);
+       WDISABLE_COPY_AND_ASSIGN(WWindowController);
+};
+
+} // namespace
+
+#endif /* _APP_ASSIST_WWINDOW_CONTROLLER_H_ */
diff --git a/packaging/projects.list b/packaging/projects.list
new file mode 100755 (executable)
index 0000000..fd27234
--- /dev/null
@@ -0,0 +1 @@
+Sketch
diff --git a/project_def.prop b/project_def.prop
new file mode 100644 (file)
index 0000000..9016a51
--- /dev/null
@@ -0,0 +1,63 @@
+
+# Project Name
+APPNAME = sketch
+
+# Project Type
+type = app
+
+# Project Profile
+profile = wearable-4.0
+
+# C/CPP Sources
+USER_SRCS = src/app-assist-efl/WViewControllerImpl.cpp src/app-assist-efl/WViewController.cpp src/app-assist-efl/WApp.cpp src/app-assist-efl/WPopupController.cpp src/controls/CDrCairoImage.cpp src/app-assist-efl/WMenuPopupControllerImpl.cpp src/View/CDrStrokeView.cpp src/app-assist-efl/WNaviframeController.cpp src/controls/CDrDrawingView.cpp src/app/CDrAppData.cpp src/app-assist-efl/WGengridItem.cpp src/app-assist-efl/WUiTimerImpl.cpp src/main.cpp src/controls/CDrHistoryControl.cpp src/controls/History.cpp src/app-assist-efl/WContentViewControllerImpl.cpp src/app/CDrApp.cpp src/EventManager/CDrEventManager.cpp src/CDrUtil.cpp src/app-assist-efl/WPageSlideViewController.cpp src/controls/CDrControlManager.cpp src/app-assist-efl/WVersion.cpp src/app-assist-efl/WAppEventHandler.cpp src/app-assist-efl/WSignalIdGenerator.cpp src/app-assist-efl/WGenlistItem.cpp src/app-assist-efl/WWindowController.cpp src/app-assist-efl/WContentViewController.cpp src/View/CDrMainView.cpp src/app-assist-efl/WEvasObject.cpp src/app-assist-efl/WMenuPopupController.cpp src/popup/CDrClosePopup.cpp src/controls/CDrTutorialView.cpp src/app-assist-efl/WUiThread.cpp src/controls/Drawing.cpp src/MediaDB/CDrMediaContent.cpp src/app-assist-efl/WUiTimer.cpp 
+
+# EDC Sources
+USER_EDCS =  
+
+# PO Sources
+USER_POS = res/po/bg.po res/po/kn.po res/po/mr.po res/po/bs_BA.po res/po/cs.po res/po/fr_CA.po res/po/hr.po res/po/km.po res/po/pl.po res/po/mn_MN.po res/po/uk.po res/po/en_US.po res/po/da.po res/po/en.po res/po/hi.po res/po/ky_KG.po res/po/en_PH.po res/po/lo.po res/po/sr.po res/po/ar.po res/po/hu.po res/po/ta.po res/po/ko_KR.po res/po/is.po res/po/ka.po res/po/sq.po res/po/eu.po res/po/kk.po res/po/ru_RU.po res/po/it_IT.po res/po/sv.po res/po/uz.po res/po/es_US.po res/po/nb.po res/po/pl_SP.po res/po/zh_TW.po res/po/et.po res/po/ne.po res/po/fr.po res/po/az.po res/po/pa.po res/po/tg_TJ.po res/po/zh_HK.po res/po/es_ES.po res/po/my_MM.po res/po/gl.po res/po/hy.po res/po/te.po res/po/ur.po res/po/vi.po res/po/gu.po res/po/mk.po res/po/bn.po res/po/bn_BD.po res/po/tr_TR.po res/po/my_ZG.po res/po/nl.po res/po/tk_TM.po res/po/as.po res/po/ca.po res/po/pt_PT.po res/po/fi.po res/po/id.po res/po/ml.po res/po/fa.po res/po/he.po res/po/el_GR.po res/po/pt_BR.po res/po/zh_CN.po res/po/tl.po res/po/ro.po res/po/ms.po res/po/si.po res/po/be_BY.po res/po/ja_JP.po res/po/lt.po res/po/sl.po res/po/or.po res/po/sk.po res/po/ga.po res/po/lv.po res/po/th.po res/po/de.po 
+
+# User Defines
+USER_DEFS = 
+USER_CPP_DEFS = TIZEN_DEBUG_ENABLE REDO_UNDO SQLITE_HAS_CODEC 
+
+# User Undefines
+USER_UNDEFS = 
+USER_CPP_UNDEFS = 
+
+# User Libraries
+USER_LIBS = 
+
+# User Objects
+USER_OBJS = 
+
+# User Includes
+## C Compiler
+USER_C_INC_DIRS = 
+USER_INC_FILES = 
+## C++ Compiler
+USER_CPP_INC_DIRS = inc src inc/app-assist-efl src/app-assist-efl src/app-assist-efl/inc src/app src/EventManager src/View src/controls src/MediaDB src/popup 
+USER_CPP_INC_FILES = 
+
+USER_INC_DIRS = $(USER_C_INC_DIRS) $(USER_CPP_INC_DIRS)
+
+# User Library Path
+USER_LIB_DIRS = 
+
+# EDC Resource Path
+USER_EDCS_IMAGE_DIRS = ${OUTPUT_DIR} edje_images res/images 
+USER_EDCS_SOUND_DIRS = ${OUTPUT_DIR} edje/sounds 
+USER_EDCS_FONT_DIRS = ${OUTPUT_DIR} edje/fonts 
+
+# EDC Flags
+USER_EXT_EDC_KEYS = EDC0 
+
+USER_EXT_EDC0_EDCS = res/edje/drawing_layout.edc res/edje/btneffect.edc res/edje/animations2circle.edc res/edje/drawing_popup.edc 
+USER_EXT_EDC0_EDCS_IMAGE_DIRS = ${OUTPUT_DIR} edje_images res/images 
+USER_EXT_EDC0_EDCS_SOUND_DIRS = ${OUTPUT_DIR} edje/sounds 
+USER_EXT_EDC0_EDCS_FONT_DIRS = ${OUTPUT_DIR} edje/fonts 
+
+# Resource Filter
+USER_RES_INCLUDE = 
+USER_RES_EXCLUDE = 
+
diff --git a/res/edje/animations2circle.edc b/res/edje/animations2circle.edc
new file mode 100755 (executable)
index 0000000..04466f6
--- /dev/null
@@ -0,0 +1,943 @@
+#define MSG_VALUE 1
+
+collections {
+       base_scale: 1.3;
+       plugins {
+               plugin {
+                       name: "touch_sound";
+                       source: "feedback";
+                       param: "FEEDBACK_TYPE_SOUND FEEDBACK_PATTERN_TAP";
+               }
+       }
+
+       group {
+               script {
+                       public send_mode = 0; //Landscape status
+               }
+               styles {
+                       style { name: "mms_txt_style";
+                               base: "font=Tizen:style=Regular font_size="30" align=center color=#FFFFFF color_class=AT033 ellipsis=1.0 wrap=mixed text_class=AT033";
+                       }
+                       style { name: "indicator_txt_style";
+                               base: "font=Tizen:style=Regular font_size="30" align=center color=#FFFFFF color_class=ATO032 ellipsis=1.0 wrap=mixed text_class=ATO032";
+                       }
+               }
+               name: "bg";
+               parts {
+                       part {
+                               name: "bg";
+                               scale: 1;
+                               type: RECT;
+                               description {
+                                       state: "default" 0.0;
+                                       color_class: "AO0117";
+                               }
+                       }
+                       part {
+                               name: "pre-view";
+                               scale: 1;
+                               type: SWALLOW;
+                               description {
+                                       state: "default" 0.0;
+                               }
+                       }
+                       part {
+                               name: "circle_menu";
+                               scale: 1;
+                               type: SWALLOW;
+                               description {
+                                       state: "default" 0.0;
+                                       visible: 0;
+                               }
+                               description {
+                                       state: "show" 0.0;
+                                       visible: 1;
+                               }
+
+                       }
+                       part {
+                               name: "more_option";
+                               scale: 1;
+                               type: SWALLOW;
+                               description {
+                                       state: "default" 0.0;
+                                       rel1.relative: 0.0 0.0;
+                                       rel2.relative: 1.0 1.0;
+                               }
+                       }
+                       part {
+                               name: "elm.button.padding";
+                               scale: 1;
+                               type: RECT;
+                               mouse_events: 1;
+                               repeat_events: 0;
+                               description {
+                                       state: "default" 0.0;
+                                       rel1 {relative: 1.0 0.5; }
+                                       rel2 {relative: 1.0 0.5; }
+                                       min: 50 10;
+                                       max: 50 10;
+                                       fixed: 1 1;
+                                       align: 1.0 0.5;
+                                       color: 0 0 0 0;
+                               }
+                       }
+                       part {
+                               name: "elm.button.pallet";
+                               scale: 1;
+                               type: SWALLOW;
+                               mouse_events: 1;
+                               repeat_events: 0;
+                               description {
+                                       state: "default" 0.0;
+                                       rel1 {relative: 1.0 0.0; to_y: "elm.button.padding";}
+                                       rel2 {relative: 1.0 0.0; to_y: "elm.button.padding";}
+                                       min: 60 60;
+                                       max: 60 60;
+                                       fixed: 1 1;
+                                       align: 1.0 1.0;
+
+                               }
+                               description {
+                                       state: "send_default" 0.0;
+                                       rel1 {relative: 1.0 0.0; }
+                                       rel2 {relative: 1.0 1.0; }
+                                       min: 150 150;
+                                       max: 150 150;
+                                       fixed: 1 1;
+                                       align: 0.5 0.5;
+
+                               }
+                               description {
+                                       state: "hide" 0.0;
+                                       inherit: "default" 0.0;
+                                       visible: 0;
+                               }
+                       }
+                       part {
+                               name: "elm.button.stroke";
+                               scale: 1;
+                               type: SWALLOW;
+                               mouse_events: 1;
+                               repeat_events: 0;
+                               description {
+                                       state: "default" 0.0;
+                                       rel1 { relative: 1.0 1.0; to_y: "elm.button.padding";}
+                                       rel2 { relative: 1.0 1.0; to_y: "elm.button.padding";}
+                                       min: 60 60;
+                                       max: 60 60;
+                                       fixed: 1 1;
+                                       align: 1.0 0.0;
+                               }
+                               description {
+                                       state: "hide" 0.0;
+                                       inherit: "default" 0.0;
+                                       visible: 0;
+                               }
+                       }
+                       part{
+                               name: "bottom_padding";
+                               scale: 1;
+                               type: SPACER;
+                               description {
+                                       state: "default" 0.0;
+                                       min: 360 8;
+                                       max: 360 8;
+                                       fixed: 1 1;
+                                       rel1 { relative: 0.0 1.0;}
+                                       rel2 { relative: 1.0 1.0;}
+                                       align: 0.0 1.0;
+                               }
+                       }
+                       part {
+                               name: "elm.rect.button_send";
+                               scale: 1;
+                               type: RECT;
+                               description {
+                                       state: "default" 0.0;
+                                       visible: 1;
+                                       min: 66 66;
+                                       max: 66 66;
+                                       fixed: 1 1;
+                                       rel1 { relative: 0.0 1.0; }
+                                       rel2 { relative: 1.0 1.0; }
+                                       align: 0.5 0.0;
+                                       color: 0 0 0 0;
+                               }
+                               description {
+                                       state: "moveup" 0.0;
+                                       min: 66 66;
+                                       max: 66 66;
+                                       fixed: 1 1;
+                                       rel1 { relative: 0.0 0.0; to_y:"bottom_padding";}
+                                       rel2 { relative: 1.0 0.0; to_y:"bottom_padding"; }
+                                       align: 0.5 1.0;
+                                       color: 0 0 0 0;
+                               }
+                       }
+                       part {
+                               name: "elm.button.send";
+                               scale: 1;
+                               type: SWALLOW;
+                               description {
+                                       state: "default" 0.0;
+                                       min: 66 66;
+                                       max: 66 66;
+                                       fixed: 1 1;
+                                       rel1 { relative: 0.0 0.0; to:"elm.rect.button_send";}
+                                       rel2 { relative: 1.0 1.0; to:"elm.rect.button_send"; }
+                                       align: 0.5 0.5;
+                               }
+                       }
+
+
+                       part{
+                               name: "top_padding";
+                               scale: 1;
+                               type: SPACER;
+                               description {
+                                       state: "default" 0.0;
+                                       min: 360 15;
+                                       max: 360 15;
+                                       fixed: 1 1;
+                                       rel1 { relative: 0.0 0.0;}
+                                       rel2 { relative: 1.0 0.0;}
+                                       align: 0.0 0.0;
+                               }
+                       }
+                       part{
+                               name: "elm.txt.indicator";
+                               scale: 1;
+                               type: TEXTBLOCK;
+                               mouse_events: 1;
+                               repeat_events: 1;
+                               description {
+                                       state: "default" 0.0;
+                                       visible: 1;
+                                       max: 360 360;
+                                       fixed: 1 1;
+                                       rel1 {relative: 0.2 0.0; }
+                                       rel2 {relative: 0.8 1.0; }
+                                       align: 0.5 0.5;
+                                       text {
+                                          style: "indicator_txt_style";
+                                          min: 0 1;
+                                       }
+                               }
+                               description {
+                                       state: "hide" 0.0;
+                                       inherit: "default" 0.0;
+                                       visible: 0;
+
+                               }
+                       }
+                       part{
+                               name: "elm.spacer.mms";
+                               type: SPACER;
+                               description {
+                                       state: "default" 0.0;
+                                       rel1 {relative: 0.0 1.0; to_y:"top_padding";}
+                                       rel2 {relative: 1.0 1.0; to_y:"top_padding";}
+                                       align: 0.5 0.0;
+                               }
+                               description{
+                                       state: "hide" 0.0;
+                                       rel1 {relative: 0.0 0.0; }
+                                       rel1.offset: -120 -120;
+                                       rel2 { relative: 1.0 0.0;}
+                                       rel2.offset: 120 120;
+                                       align: 0.5 0.0;
+                               }
+                       }
+
+                       part{
+                               name: "elm.txt.mms";
+                               scale: 1;
+                               type: TEXTBLOCK;
+                               description {
+                                       state: "default" 0.0;
+                                       visible: 1;
+                                       rel1 {relative: 0.0 0.0; to_y:"elm.spacer.mms";}
+                                       rel2 {relative: 1.0 0.0; to_y:"elm.spacer.mms";}
+                                       align: 0.5 0.0;
+                                       text {
+                                          style: "mms_txt_style";
+                                          min: 0 1;
+                                       }
+                               }
+                               description {
+                                       state: "hide" 0.0;
+                                       inherit: "default" 0.0;
+                                       visible: 0;
+
+                               }
+                       }
+                       part{
+                               name: "elm.spacer.index";
+                               type: SPACER;
+                               description {
+                                       state: "default" 0.0;
+                                       align: 0.0 0.0;
+                                       rel1.relative: 0.0 0.0;
+                                       rel2.relative: 1.0 1.0;
+                               }
+                               description{
+                                       state: "hide" 0.0;
+                                       rel1 {relative: 0.0 0.0; }
+                                       rel1.offset: -120 -120;
+                                       rel2 { relative: 1.0 1.0;}
+                                       rel2.offset: 120 120;
+                               }
+                       }
+                       part {
+                               name: "elm.swallow.history.index";
+                               scale: 1;
+                               type: SWALLOW;
+                               description {
+                                       state: "default" 0.0;
+                                       visible: 1;
+                                       align: 0.5 0.5;
+                                       rel1 {relative: 0.0 0.0; to_y:"elm.spacer.index";}
+                                       rel2 {relative: 1.0 1.0; to_y:"elm.spacer.index";}
+                               }
+                               /*
+                               description {
+                                       state: "hide" 0.0;
+                                       inherit: "default" 0.0;
+                                       visible: 0;
+                                       rel1 {relative: 0.0 0.0; to_y:"elm.spacer.index";}
+                                       rel2 {relative: 1.0 1.0; to_y:"elm.spacer.index";}
+                               }*/
+                       }
+                       part {
+                               name: "elm.swallow.tutorial";
+                               scale: 1;
+                               type: SWALLOW;
+                               description {
+                                       state: "default" 0.0;
+                                       visible: 1;
+                                       //align: 0.5 0.5;
+                                       rel1 {relative: 0.0 0.0; to_y:"bg";}
+                                       rel2 {relative: 1.0 1.0; to_y:"bg";}
+                               }
+                               description {
+                                       state: "hide" 0.0;
+                                       inherit: "default" 0.0;
+                                       visible: 0;
+                                       rel1 {relative: 0.0 0.0; to_y:"bg";}
+                                       rel2 {relative: 1.0 1.0; to_y:"bg";}
+                               }
+                       }
+
+               }//parts
+               programs {
+                       program {
+                               name: "pallet.button.sendmode";
+                               signal: "elm.state.pallet.button.sendmode";
+                               source: "*";
+                               script {
+                                       set_state(PART:"elm.button.pallet", "send_default", 0.0);
+                                       set_int(send_mode, 1);
+                               }
+
+                       }
+                       program {
+                               name: "pallet.button.savemode";
+                               signal: "elm.state.pallet.button.savemode";
+                               source: "*";
+                               script {
+                                       set_state(PART:"elm.button.pallet", "default", 0.0);
+                                       set_int(send_mode, 0);
+                               }
+                       }
+                       program {
+                               name: "hide.mms";
+                               signal: "elm.state.hide.mms";
+                               source: "*";
+                               action: STATE_SET "hide" 0.0;
+                               target: "elm.txt.mms";
+                       }
+                       program {
+                               name: "show.mms";
+                               signal: "elm.state.show.mms";
+                               source: "*";
+                               action: STATE_SET "default" 0.0;
+                               target: "elm.txt.mms";
+                       }
+                       program {
+                               name: "hide.index";
+                               signal: "elm.state.hide.index";
+                               source: "*";
+                               script {
+                                       run_program(PROGRAM:"hide_index_animation");
+                               }
+                       }
+                       program {
+                               name: "hide_index_animation";
+                               action: STATE_SET "hide" 0.0;
+                               target: "elm.spacer.index";
+                               target: "elm.spacer.mms";
+                               transition: CUBIC_BEZIER (0.2) 0.45 0.03 0.41 1.0;
+                               //transition: ACCEL 0.5;
+                               //after: "hide_effect2";
+                       }
+                       program { name: "hide_effect2";
+                               script {
+                                       set_state(PART:"elm.swallow.history.index", "hide", 0.0);
+                                       set_state(PART:"elm.txt.mms", "hide", 0.0);
+                               }
+                       }
+                       program {
+                               name: "show.index.mms";
+                               signal: "elm.state.show.index.mms";
+                               source: "*";
+                               script {
+                                       set_state(PART:"elm.spacer.index", "hide", 0.0);
+                                       if (get_int(send_mode)) {
+                                               set_state(PART:"elm.txt.mms", "default", 0.0);
+                                       }
+                                       run_program(PROGRAM:"show_index_mms_animation");
+                               }
+                       }
+                       program {
+                               name: "show_index_mms_animation";
+                               action: STATE_SET "default" 0.0;
+                               target: "elm.spacer.index";
+                               target: "elm.spacer.mms";
+                               transition: CUBIC_BEZIER (0.2) 0.25 0.46 0.45 1.0;
+                               //transition: ACCEL 0.5;
+                               //after: "show_effect2";
+                       }
+                       program { name: "show_effect2";
+                               script {
+                                       set_state(PART:"elm.spacer.index", "default", 0.0);
+                                       set_state(PART:"elm.spacer.mms", "default", 0.0);
+                               }
+                       }
+
+                       program {
+                               name: "show.index";
+                               signal: "elm.state.show.index";
+                               source: "*";
+                               script {
+                                       set_state(PART:"elm.swallow.history.index", "default", 0.0);
+                                       set_state(PART:"elm.txt.mms", "hide", 0.0);
+
+                                       run_program(PROGRAM:"show_index_animation");
+                               }
+                       }
+                       program {
+                               name: "show_index_animation";
+                               action: STATE_SET "default" 0.0;
+                               target: "elm.spacer.index";
+                               transition: CUBIC_BEZIER (0.2) 0.25 0.46 0.45 1.0;
+                               //transition: ACCEL 0.5;
+                       }
+                       program {
+                               name: "hide.btnpallet";
+                               signal: "elm.state.hide.btnpallet";
+                               source: "*";
+                               action: STATE_SET "hide" 0.0;
+                               target: "elm.button.pallet";
+                               target: "elm.button.stroke";
+                       }
+                       program {
+                               name: "show.btnpallet";
+                               signal: "elm.state.show.btnpallet";
+                               source: "*";
+                               script {
+                                       set_state(PART:"elm.button.stroke", "default", 0.0);
+                                       if (get_int(send_mode)) {
+                                               set_state(PART:"elm.button.pallet","send_default", 0.0);
+                                       } else {
+                                               set_state(PART:"elm.button.pallet","default", 0.0);
+                                       }
+                               }
+                       }
+                       program {
+                               name: "hide.indicator";
+                               signal: "elm.state.hide.indicator";
+                               source: "*";
+                               action: STATE_SET "hide" 0.0;
+                               target: "elm.txt.indicator";
+                               target: "elm.button.pallet";
+                               target: "elm.button.stroke";
+                       }
+                       program {
+                               name: "show.indicator";
+                               signal: "elm.state.show.indicator";
+                               source: "*";
+                               script {
+                                       set_state(PART:"elm.button.stroke", "default", 0.0);
+                                       if (get_int(send_mode)) {
+                                               set_state(PART:"elm.button.pallet","send_default", 0.0);
+                                       } else {
+                                               set_state(PART:"elm.button.pallet","default", 0.0);
+                                       }
+                                       set_state(PART:"elm.txt.indicator", "default", 0.0);
+                               }
+                       }
+                       program {
+                           name: "hide.pallet.view";
+                       signal: "hide,pallet,view";
+                       source: "elm";
+                       action: STATE_SET "default" 0.0;
+                           target: "circle_menu";
+                   }
+                   program {
+                           name: "show.pallet.view";
+                       signal: "show,pallet,view";
+                       source: "elm";
+                       action: STATE_SET "show" 0.0;
+                           target: "circle_menu";
+                   }
+                       program { name: "button.send.moveup";
+                               signal: "elm,state,button,send.moveup";
+                               source: "elm";
+                               script {
+                                       set_state(PART:"elm.rect.button_send", "default", 0.0);
+                                       run_program(PROGRAM:"moveup_button_send");
+                               }
+                       }
+                       program {
+                               name: "moveup_button_send";
+                               action: STATE_SET "moveup" 0.0;
+                               target: "elm.rect.button_send";
+                               transition: CUBIC_BEZIER (0.2) 0.25 0.46 0.45 1.0;
+                       }
+                       program {
+                               name: "movedown.button.send";
+                               signal: "movedown,rect,button_send";
+                               source: "elm";
+                               action: STATE_SET "default" 0.0;
+                               target: "elm.rect.button_send";
+                       }
+               }
+       }
+       group {
+               styles {
+                       style { name: "title_txt_style";
+                               base: "font=Tizen:style=Regular font_size="30" align=center color=#FFFFFF color_class=AT011 ellipsis=1.0 wrap=mixed text_class=AT011";
+                       }
+                       style { name: "content_txt_style";
+                               base: "font=Tizen:style=Regular font_size="30" align=center color=#FFFFFF color_class=AT012 ellipsis=1.0 wrap=mixed text_class=AT012";
+                       }
+               }
+               images {
+                       image: "gear_tutorial_bg.png" COMP;
+                       image: "gear_tutorial_rotate_ccw.png" COMP;
+                       image: "gear_tutorial_rotate_cw.png" COMP;
+                       image: "gear_tutorial_bg_focus.png" COMP;
+                       image: "gear_tutorial_bt_cancel_normal.png" COMP;
+                       image: "gear_tutorial_bt_cancel_press.png" COMP;
+               }
+               name: "tutorial_view";
+               parts {
+                       part {
+                               name: "bg";
+                               type: RECT;
+                               scale: 1;
+                               description {
+                                       state: "default" 0.0;
+                                       min: 360 360;
+                                       color: 0 0 0 0;
+                               }
+                       }
+                       part {
+                               name: "bg.image";
+                               type: IMAGE;
+                               mouse_events: 0;
+                               repeat_events: 1;
+                               description {
+                                       state: "default" 0.0;
+                                       rel1 { relative: 0.0 0.0;}
+                                       rel2 { relative: 1.0 1.0;}
+                                       image {
+                                               normal: "gear_tutorial_bg.png";
+                                       }
+                                       visible: 1;
+                               }
+                       }
+                       part {
+                               name: "top.left.padding";
+                               type: SPACER;
+                               scale: 1;
+                               description {
+                                       state: "default" 0.0;
+                                       min: 75 66;
+                                       rel1 {relative: 0.0 0.0; to_y:"bg";}
+                                       rel2 {relative: 0.0 0.0; to_y:"bg";}
+                                       align: 0.0 0.0;
+                                       fixed: 1 1;
+                               }
+                       }
+                       part {
+                               name: "top.right.padding";
+                               type: SPACER;
+                               scale: 1;
+                               description {
+                                       state: "default" 0.0;
+                                       min: 75 66;
+                                       rel1 {relative: 1.0 0.0; to_y:"bg";}
+                                       rel2 {relative: 1.0 0.0; to_y:"bg";}
+                                       align: 1.0 0.0;
+                                       fixed: 1 1;
+                               }
+                       }
+                       part {
+                               name: "clipper";
+                               type: RECT;
+                               mouse_events: 1;
+                               scale: 1;
+                               description {
+                                       state: "default" 0.0;
+                                       rel1.relative: 0.0 0.0;
+                                       rel2.relative: 1.0 1.0;
+                                       fixed: 1 1;
+                                       color: 0 0 0 0;
+                               }
+                               description {
+                                       state: "show" 0.0;
+                                       inherit: "default" 0.0;
+                                       color: 255 255 255 255;
+                               }
+                       }
+                       part {
+                               name: "image.ccw";
+                               type: IMAGE;
+                               //clip_to: "clipper";
+                               mouse_events: 0;
+                               repeat_events: 1;
+                               scale: 1;
+                               description {
+                                       state: "default" 0.0;
+                                       min: 180 180;
+                                       max: 180 180;
+                                       fixed: 1 1;
+                                       rel1 { relative: 0.0 0.0;}
+                                       rel2 { relative: 0.0 0.0;}
+                                       image {
+                                               normal: "gear_tutorial_rotate_ccw.png";
+                                       }
+                                       visible: 0;
+                                       align: 0.0 0.0;
+                               }
+                               description {
+                                       state: "show" 0.0;
+                                       inherit: "default" 0.0;
+                                       visible: 1;
+                               }
+                       }
+                       part {
+                               name: "image.cw";
+                               type: IMAGE;
+                               //clip_to: "clipper";
+                               mouse_events: 0;
+                               repeat_events: 1;
+                               scale: 1;
+                               description {
+                                       state: "default" 0.0;
+                                       min: 180 180;
+                                       max: 180 180;
+                                       fixed: 1 1;
+                                       rel1 { relative: 1.0 0.0;}
+                                       rel2 { relative: 1.0 0.0;}
+                                       image {
+                                               normal: "gear_tutorial_rotate_cw.png";
+                                       }
+                                       visible: 0;
+                                       align: 1.0 0.0;
+                               }
+                               description {
+                                       state: "show" 0.0;
+                                       inherit: "default" 0.0;
+                                       visible: 1;
+                               }
+                       }
+                       part {
+                               name: "image.bg.focus";
+                               type: IMAGE;
+                               clip_to: "clipper";
+                               mouse_events: 0;
+                               repeat_events: 1;
+                               scale: 1;
+                               description {
+                                       state: "default" 0.0;
+                                       min: 360 360;
+                                       max: 360 360;
+                                       fixed: 1 1;
+                                       rel1 { relative: 0.5 0.5;}
+                                       rel2 { relative: 0.5 0.5;}
+                                       image {
+                                               normal: "gear_tutorial_bg_focus.png";
+                                       }
+                                       visible: 0;
+                                       align: 0.5 0.5;
+                               }
+                               description {
+                                       state: "show" 0.0;
+                                       inherit: "default" 0.0;
+                                       visible: 1;
+                               }
+                       }
+
+                       part { name: "elm.text.title.bg";
+                               type: SPACER;
+                               scale: 1;
+                               description { state: "default" 0.0;
+                                       min: 210 41;
+                                       rel1 {
+                                               to: "top.left.padding";
+                                               relative: 1.0 1.0;
+                                       }
+                                       rel2 {
+                                               to: "top.right.padding";
+                                               relative: 0.0 1.0;
+                                       }
+                                       align: 0.5 0.0;
+                                       fixed: 0 1;
+                               }
+                       }
+                       part { name: "elm.text.title";
+                               type: TEXTBLOCK;
+                               scale: 1;
+                               description { state: "default" 0.0;
+                                       rel1 {
+                                               to: "elm.text.title.bg";
+                                               relative: 0.5 0.5;
+                                               }
+                                       rel2 {
+                                               to: "elm.text.title.bg";
+                                               relative: 0.5 0.5;
+                                       }
+                                       fixed: 1 1;
+                                       max: 210 41;
+                                       text {
+                                               style: "title_txt_style";
+                                               min: 1 1;
+                                               max: 0 1;
+                                               ellipsis: -1.0;
+                                               fade_ellipsis: 1.0;
+                                       }
+                               }
+                               description { state: "title_invisible" 0.0;
+                                       inherit: "default" 0.0;
+                                       text.min: 0 0;
+                               }
+                       }
+                       part { name: "title.bottom.padding";
+                               type: SPACER;
+                               scale: 1;
+                               description { state: "default" 0.0;
+                                       min: 0 50;
+                                       rel1 {
+                                          to: "elm.text.title.bg";
+                                          relative: 0.0 1.0;
+                                       }
+                                       rel2.to: "elm.text.title.bg";
+                                       align: 0.5 0.0;
+                                       fixed: 0 1;
+                               }
+                               description { state: "title_invisible" 0.0;
+                                       inherit: "default" 0.0;
+                                       rel1 {
+                                          to: "elm.text.title.bg";
+                                          relative: 0.0 0.0;
+                                       }
+                                       rel2 {
+                                          to: "elm.text.title.bg";
+                                          relative: 1.0 0.0;
+                                       }
+                                       min: 0 0;
+                               }
+                       }
+                       part { name: "text.left.padding";
+                               type: SPACER;
+                               scale: 1;
+                               description { state: "default" 0.0;
+                                       min: 33 18;
+                                       rel1 {relative: 0.0 0.0; to:"bg";}
+                                       rel2 {relative: 0.0 0.0; to:"bg";}
+                                       align: 0.0 0.0;
+                                       fixed: 1 1;
+                               }
+                       }
+                       part { name: "text.right.padding";
+                               type: SPACER;
+                               scale: 1;
+                               description { state: "default" 0.0;
+                                       min: 33 18;
+                                       rel1 {relative: 1.0 0.0; to:"bg";}
+                                       rel2 {relative: 1.0 0.0; to:"bg";}
+                                       align: 1.0 0.0;
+                                       fixed: 1 1;
+                               }
+                       }
+                       part { name: "text.bottom.padding";
+                               type: SPACER;
+                               scale: 1;
+                               description { state: "default" 0.0;
+                                       fixed: 1 1;
+                                       align: 0.5 1.0;
+                                       min: 0 80;
+                                       max: -1 80;
+                                       rel1.relative: 0.0 1.0;
+                               }
+                       }
+                       part { name: "elm.text";
+                               type: TEXTBLOCK;
+                               scale: 1;
+                               description { state: "default" 0.0;
+                                       rel1 {
+                                          to_y: "title.bottom.padding";
+                                          to_x: "text.left.padding";
+                                          relative: 1.0 1.0;
+                                       }
+                                       rel2 {
+                                          to_y: "text.bottom.padding";
+                                          to_x: "text.right.padding";
+                                          relative: 0.0 0.0;
+                                       }
+                                       text {
+                                          style: "content_txt_style";
+                                          align: 0.5 0;
+                                          min: 0 1;
+                                       }
+                               }
+                       }
+                       part { name: "bottom.padding";
+                               type: SPACER;
+                               scale: 1;
+                               description { state: "default" 0.0;
+                                       fixed: 1 1;
+                                       align: 0.5 1.0;
+                                       min: 0 15;
+                                       max: -1 15;
+                                       rel1 {relative: 0.0 1.0; to:"bg";}
+                                       rel2 {relative: 1.0 1.0; to:"bg";}
+                               }
+                       }
+                       part {
+                               name: "elm.image.cancel.button";
+                               type: IMAGE;
+                               scale: 1;
+                               mouse_events: 1;
+                               description { state: "default" 0.0;
+                                       fixed: 1 1;
+                                       align: 0.5 1.0;
+                                       min: 56 56;
+                                       max: 56 56;
+                                       rel1 {relative: 0.0 0.0; to:"bottom.padding";}
+                                       rel2 {relative: 1.0 0.0; to:"bottom.padding";}
+                                       image {
+                                               normal: "gear_tutorial_bt_cancel_normal.png";
+                                       }
+                                       visible: 1;
+                               }
+                               description {
+                                       state: "pressed" 0.0;
+                                       inherit: "default" 0.0;
+                                       image {
+                                               normal: "gear_tutorial_bt_cancel_press.png";
+                                       }
+                                       visible: 1;
+                               }
+                               description {
+                                       state: "hide" 0.0;
+                                       inherit: "default" 0.0;
+                                       image {
+                                               normal: "gear_tutorial_bt_cancel_normal.png";
+                                       }
+                                       visible: 0;
+                               }
+                       }
+                       part{ name: "actionbtn1";
+                               type: SWALLOW;
+                               scale: 1;
+                               mouse_events: 1;
+                               repeat_events: 1;
+                               description { state: "default" 0.0;
+                                       align: 0.0 0.0;
+                                       rel1 { to: "elm.image.cancel.button";}
+                                       rel2 { to: "elm.image.cancel.button";}
+                               }
+                       }
+
+               }//parts
+               programs {
+                       program { name: "play_sound";
+                               action: RUN_PLUGIN "touch_sound";
+                       }
+                       program {
+                               signal: "elm,image,ccw,show";
+                               source: "*";
+                               action: STATE_SET "show" 0.0;
+                               target: "image.ccw";
+                       }
+                       program {
+                               signal: "elm,image,ccw,hide";
+                               source: "*";
+                               action: STATE_SET "default" 0.0;
+                               target: "image.ccw";
+                       }
+                       program {
+                               signal: "elm,image,cw,show";
+                               source: "*";
+                               action: STATE_SET "show" 0.0;
+                               target: "image.cw";
+                       }
+                       program {
+                               signal: "elm,image,cw,hide";
+                               source: "*";
+                               action: STATE_SET "default" 0.0;
+                               target: "image.cw";
+                       }
+                       program {
+                               signal: "elm,image,bg,focus,show";
+                               source: "*";
+                               action: STATE_SET "show" 0.0;
+                               target: "image.bg.focus";
+                       }
+                       program {
+                               signal: "elm,image,bg,focus,hide";
+                               source: "*";
+                               action: STATE_SET "default" 0.0;
+                               target: "image.bg.focus";
+                       }
+                       program {
+                               signal: "mouse,down,1";
+                               source: "elm.image.cancel.button";
+                               action: STATE_SET "pressed" 0.0;
+                               target: "elm.image.cancel.button";
+                       }
+                       program {
+                               signal: "mouse,up,1";
+                               source: "elm.image.cancel.button";
+                               action: STATE_SET "default" 0.0;
+                               target: "elm.image.cancel.button";
+                       }
+                       program {
+                               name:"actionbtn1,sound";
+                               signal: "mouse,clicked,1";
+                               source:"actionbtn1";
+                               script {
+                                       run_program(PROGRAM:"play_sound");
+                                       emit("clicked", "actionbtn1");
+                               }
+                       }
+                       program {
+                               signal: "elm,image,btn,show";
+                               source: "*";
+                               action: STATE_SET "default" 0.0;
+                               target: "elm.image.cancel.button";
+                       }
+                       program {
+                               signal: "elm,image,btn,hide";
+                               source: "*";
+                               action: STATE_SET "hide" 0.0;
+                               target: "elm.image.cancel.button";
+                       }
+               }
+       }
+       #include "drawing_stroke.edc"
+}
diff --git a/res/edje/btneffect.edc b/res/edje/btneffect.edc
new file mode 100755 (executable)
index 0000000..d5575db
--- /dev/null
@@ -0,0 +1,2321 @@
+collections {
+
+#define COLOR_A color: 255 255 255 255
+#define COLOR_B color: 255 255 255 50
+
+#define IMAGE_NAME "b_ic_press_full_circle_bg_a.png"
+
+#define ANIM_TIME 1.0
+
+#define ZOOM_INIT 0.5
+#define ZOOM_END 1.3
+
+#define ZOOM_INIT_INNER 0.5
+#define ZOOM_END_INNER 1.3
+
+
+       group { name: "elm/button/base/myeffect/default";
+          images {
+             image: IMAGE_NAME COMP;
+             image: IMAGE_INVERSE COMP;
+          }
+          script {
+             public mouse_down = 0;
+             public mouse_click = 0;
+             public multi_down = 0;
+             public click_cnt = 0;
+             public timer0(val) {
+               if(val == 1)
+                  run_program(PROGRAM:"change_opacity");
+               else if(val == 2)
+                  run_program(PROGRAM:"change_opacity2");
+               else if(val == 3)
+                  run_program(PROGRAM:"change_opacity3");
+               else
+                  run_program(PROGRAM:"change_opacity4");
+             }
+          }
+          parts {
+             part { name: "base";
+                type: SPACER;
+                scale: 1;
+                description {
+                               state: "default" 0.0;
+                }
+             }
+
+            part { name: "bg";
+                type: SWALLOW;
+                scale: 1;
+                clip_to: "bg_clipper";
+                description { state: "default" 0.0;
+                   rel1.to: "base";
+                   rel2.to: "base";
+                }
+             }
+             part { name: "bg_clipper";
+                scale: 1;
+                description { state: "default" 0.0;
+                   rel1.to: "bg";
+                   rel2.to: "bg";
+                   image.normal: IMAGE_NAME;
+                   color: 255 255 255 255;
+                }
+             }
+
+             part { name: "elm.swallow.content";
+                type: SWALLOW;
+                clip_to: "elm.swallow.content.clip";
+                scale: 1;
+                description { state: "default" 0.0;
+                   rel1.to: "base";
+                   rel2.to: "base";
+                }
+             }
+
+             part { name: "elm.swallow.content.clip";
+                scale: 1;
+                description { state: "default" 0.0;
+                   image.normal: IMAGE_NAME;
+                   color: 255 255 255 255;
+                   rel1.to: "elm.swallow.content";
+                   rel2.to: "elm.swallow.content";
+                }
+                description { state: "pressed" 0.0;
+                   inherit: "default" 0.0;
+                }
+                description { state: "disabled" 0.0;
+                   inherit: "default" 0.0;
+                   color: 0 0 0 0;
+                }
+             }
+
+       // clip_to is not working if clipper uses map
+             part { name: "effect_bg";
+                scale: 1;
+                clip_to: "effect_bg_clip";
+                description { state: "default" 0.0;
+                   rel1.to: "base";
+                   rel2.to: "base";
+                   image.normal: IMAGE_NAME;
+                   COLOR_A;
+                   map.on: 1;
+                }
+                description { state: "pressed" 0.0;
+                   inherit: "default" 0.0;
+                   COLOR_A;
+                   map {
+                      zoom.x: ZOOM_INIT;
+                      zoom.y: ZOOM_INIT;
+                   }
+                }
+                description { state: "disabled" 0.0;
+                   inherit: "default" 0.0;
+                }
+                description { state: "start_persp" 0.0;
+                   inherit: "default" 0.0;
+                   COLOR_B;
+                   map {
+                      zoom.x: ZOOM_END;
+                      zoom.y: ZOOM_END;
+                   }
+                }
+             }
+
+             part { name: "effect_bg_clip";
+                scale: 1;
+                type: RECT;
+                description { state: "default" 0.0;
+                   rel1.to: "base";
+                   rel1.relative: -0.35 -0.35;
+                   rel2.to: "base";
+                   rel2.relative: 1.35 1.35;
+                   color: 255 255 255 0;
+                }
+                description { state: "pressed" 0.0;
+                   inherit: "default" 0.0;
+                   color: 255 255 255 255;
+                }
+                description { state: "disabled" 0.0;
+                   inherit: "default" 0.0;
+                }
+             }
+             part { name: "effect_bg2";
+                scale: 1;
+                clip_to: "effect_bg_clip2";
+                description { state: "default" 0.0;
+                   rel1.to: "base";
+                   rel2.to: "base";
+                   image.normal: IMAGE_NAME;
+                   color_class: "transparent";
+                   map.on: 1;
+                }
+                description { state: "pressed" 0.0;
+                   inherit: "default" 0.0;
+                   COLOR_A;
+                   map {
+                      zoom.x: ZOOM_INIT;
+                      zoom.y: ZOOM_INIT;
+                   }
+                }
+                description { state: "disabled" 0.0;
+                   inherit: "default" 0.0;
+                }
+                description { state: "start_persp" 0.0;
+                   inherit: "default" 0.0;
+                   COLOR_B;
+                   map {
+                      zoom.x: ZOOM_END;
+                      zoom.y: ZOOM_END;
+                   }
+                }
+             }
+             part { name: "effect_bg_clip2";
+                scale: 1;
+                type: RECT;
+                description { state: "default" 0.0;
+                   rel1.to: "base";
+                   rel1.relative: -0.35 -0.35;
+                   rel2.to: "base";
+                   rel2.relative: 1.35 1.35;
+                   color: 255 255 255 0;
+                }
+                description { state: "pressed" 0.0;
+                   inherit: "default" 0.0;
+                   color: 255 255 255 255;
+                }
+                description { state: "disabled" 0.0;
+                   inherit: "default" 0.0;
+                }
+             }
+             part { name: "effect_bg3";
+                scale: 1;
+                clip_to: "effect_bg_clip3";
+                description { state: "default" 0.0;
+                   rel1.to: "base";
+                   rel2.to: "base";
+                   image.normal: IMAGE_NAME;
+                   color_class: "transparent";
+                   map.on: 1;
+                }
+                description { state: "pressed" 0.0;
+                   inherit: "default" 0.0;
+                   COLOR_A;
+                   map {
+                      zoom.x: ZOOM_INIT;
+                      zoom.y: ZOOM_INIT;
+                   }
+                }
+                description { state: "disabled" 0.0;
+                   inherit: "default" 0.0;
+                }
+                description { state: "start_persp" 0.0;
+                   inherit: "default" 0.0;
+                   COLOR_B;
+                   map {
+                      zoom.x: ZOOM_END;
+                      zoom.y: ZOOM_END;
+                   }
+                }
+             }
+             part { name: "effect_bg_clip3";
+                scale: 1;
+                type: RECT;
+                description { state: "default" 0.0;
+                   rel1.to: "base";
+                   rel1.relative: -0.35 -0.35;
+                   rel2.to: "base";
+                   rel2.relative: 1.35 1.35;
+                   color: 255 255 255 0;
+                }
+                description { state: "pressed" 0.0;
+                   inherit: "default" 0.0;
+                   color: 255 255 255 255;
+                }
+                description { state: "disabled" 0.0;
+                   inherit: "default" 0.0;
+                }
+             }
+             part { name: "effect_bg4";
+                scale: 1;
+                clip_to: "effect_bg_clip4";
+                description { state: "default" 0.0;
+                   rel1.to: "base";
+                   rel2.to: "base";
+                   image.normal: IMAGE_NAME;
+                   color_class: "transparent";
+                   map.on: 1;
+                }
+                description { state: "pressed" 0.0;
+                   inherit: "default" 0.0;
+                   COLOR_A;
+                   map {
+                      zoom.x: ZOOM_INIT;
+                      zoom.y: ZOOM_INIT;
+                   }
+                }
+                description { state: "disabled" 0.0;
+                   inherit: "default" 0.0;
+                }
+                description { state: "start_persp" 0.0;
+                   inherit: "default" 0.0;
+                   COLOR_B;
+                   map {
+                      zoom.x: ZOOM_END;
+                      zoom.y: ZOOM_END;
+                   }
+                }
+             }
+             part { name: "effect_bg_clip4";
+                scale: 1;
+                type: RECT;
+                description { state: "default" 0.0;
+                   rel1.to: "base";
+                   rel1.relative: -0.35 -0.35;
+                   rel2.to: "base";
+                   rel2.relative: 1.35 1.35;
+                   color: 255 255 255 0;
+                }
+                description { state: "pressed" 0.0;
+                   inherit: "default" 0.0;
+                   color: 255 255 255 255;
+                }
+                description { state: "disabled" 0.0;
+                   inherit: "default" 0.0;
+                }
+             }
+
+             part { name: "event";
+                type: RECT;
+                scale: 1;
+                description { state: "default" 0.0;
+                   color: 0 0 0 0;
+                   rel1.to: "base";
+                   rel2.to: "base";
+                }
+             }
+          }
+          programs {
+             program { name: "pressed";
+                signal: "effect,mouse,down,1*";
+                source: "event";
+                script {
+                   if ((get_int(multi_down) == 0) && (get_int(mouse_down) == 0))
+                   {
+                      set_int(mouse_down, 1);
+                      run_program(PROGRAM:"button_press1");
+                   }
+                }
+             }
+
+             program { name: "button_press1";
+                script {
+                   new st[31];
+                   new Float:vl;
+                   get_state(PART:"effect_bg", st, 30, vl);
+                   if (strcmp(st, "disabled")) {
+                      set_state(PART:"elm.swallow.content.clip", "pressed", 0.0);
+                      emit("elm,action,press", "");
+                      if(get_int(click_cnt) == 0) {
+                         set_state(PART:"effect_bg", "pressed", 0.0);
+                         set_state(PART:"effect_bg_clip", "pressed", 0.0);
+
+                         run_program(PROGRAM:"start_persp");
+                         timer(0.1, "timer0", 1);
+                      }
+                      else if(get_int(click_cnt) == 1) {
+                         set_state(PART:"effect_bg2", "pressed", 0.0);
+                         set_state(PART:"effect_bg_clip2", "pressed", 0.0);
+                         run_program(PROGRAM:"start_persp2");
+                         timer(0.1, "timer0", 2);
+                      }
+                      else if(get_int(click_cnt) == 2) {
+                         set_state(PART:"effect_bg3", "pressed", 0.0);
+                         set_state(PART:"effect_bg_clip3", "pressed", 0.0);
+                         run_program(PROGRAM:"start_persp3");
+                         timer(0.1, "timer0", 3);
+                      }
+                      else {
+                         set_state(PART:"effect_bg4", "pressed", 0.0);
+                         set_state(PART:"effect_bg_clip4", "pressed", 0.0);
+                         run_program(PROGRAM:"start_persp4");
+                         timer(0.1, "timer0", 4);
+                      }
+                   }
+                }
+             }
+             program { name: "unpressed";
+                signal: "mouse,up,1";
+                source: "event";
+                script {
+                   if (get_int(mouse_down) == 1) {
+                      set_int(mouse_down, 0);
+                      run_program(PROGRAM:"button_unpress1");
+                   }
+                }
+             }
+             program { name: "button_unpress1";
+                script {
+                   new st[31];
+                   new Float:vl;
+                   get_state(PART:"effect_bg", st, 30, vl);
+                   if (strcmp(st, "disabled")) {
+                      set_state(PART:"elm.swallow.content.clip", "default", 0.0);
+                      emit("elm,action,unpress", "");
+                   if(get_int(click_cnt) == 0)
+                      set_int(click_cnt, 1);
+                   else if(get_int(click_cnt) == 1)
+                      set_int(click_cnt, 2);
+                   else if(get_int(click_cnt) == 2)
+                      set_int(click_cnt, 3);
+                   else
+                      set_int(click_cnt, 0);
+                   }
+                }
+             }
+
+             program { name: "play_example";
+                signal: "play,once";
+                source: "event";
+                script {
+                        set_int(click_cnt, 0);
+                         run_program(PROGRAM:"button_press1");
+                }
+             }
+
+
+             program { name: "touch_snd";
+                signal: "mouse,clicked,1";
+                source: "event";
+                script {
+                   new st[31];
+                   new Float:vl;
+                   if (get_int(multi_down) == 0) {
+                      get_state(PART:"effect_bg", st, 30, vl);
+                      if (strcmp(st, "disabled")) {
+                         run_program(PROGRAM:"play_sample");
+                         emit("elm,action,click", "");
+                         set_int(mouse_click, 0);
+                      }
+                   }
+                }
+             }
+             program {
+                name: "play_sample";
+                action: RUN_PLUGIN "touch_sound";
+             }
+             program { name: "disable";
+                signal: "elm,state,disabled";
+                source: "elm";
+                action: STATE_SET "disabled" 0.0;
+                target: "effect_bg";
+                target: "elm.swallow.content.clip";
+             }
+             program { name: "enable";
+                signal: "elm,state,enabled";
+                source: "elm";
+                action: STATE_SET "default" 0.0;
+                target: "effect_bg";
+                target: "elm.swallow.content.clip";
+             }
+             program { name: "multi_down";
+                signal: "elm,action,multi,down";
+                source: "elm";
+                script {
+                   set_int(multi_down, 1);
+                }
+             }
+             program { name: "multi_up";
+                signal: "elm,action,multi,up";
+                source: "elm";
+                script {
+                   set_int(multi_down, 0);
+                }
+             }
+             program { name: "start_persp";
+                action: STATE_SET "start_persp" 0.0;
+                transition: CUBIC_BEZIER ANIM_TIME 0.45 0.03 0.41 1.0;
+                target: "effect_bg";
+             }
+             program { name: "change_opacity";
+                action: STATE_SET "default" 0.0;
+                transition: CUBIC_BEZIER ANIM_TIME 0.39 0.575 0.565 1.0;
+                target: "effect_bg_clip";
+             }
+             program { name: "start_persp2";
+                action: STATE_SET "start_persp" 0.0;
+                transition: CUBIC_BEZIER ANIM_TIME 0.45 0.03 0.41 1.0;
+                target: "effect_bg2";
+             }
+             program { name: "change_opacity2";
+                action: STATE_SET "default" 0.0;
+                transition: CUBIC_BEZIER ANIM_TIME 0.39 0.575 0.565 1.0;
+                target: "effect_bg_clip2";
+             }
+             program { name: "start_persp3";
+                action: STATE_SET "start_persp" 0.0;
+                transition: CUBIC_BEZIER ANIM_TIME 0.45 0.03 0.41 1.0;
+                target: "effect_bg3";
+             }
+             program { name: "change_opacity3";
+                action: STATE_SET "default" 0.0;
+                transition: CUBIC_BEZIER ANIM_TIME 0.39 0.575 0.565 1.0;
+                target: "effect_bg_clip3";
+             }
+             program { name: "start_persp4";
+                action: STATE_SET "start_persp" 0.0;
+                transition: CUBIC_BEZIER ANIM_TIME 0.45 0.03 0.41 1.0;
+                target: "effect_bg4";
+             }
+             program { name: "change_opacity4";
+                action: STATE_SET "default" 0.0;
+                transition: CUBIC_BEZIER ANIM_TIME 0.39 0.575 0.565 1.0;
+                target: "effect_bg_clip4";
+             }
+          }
+       }
+
+       group { name: "elm/button/base/drawing/effect/left";
+               images {
+                 image: "b_ic_press_full_circle_bg.png" COMP;
+               }
+               script {
+                       public mouse_down = 0;
+                       public mouse_click = 0;
+                       public multi_down = 0;
+                       public click_cnt = 0;
+                       public timer0(val) {
+                               if(val == 1)
+                                       run_program(PROGRAM:"change_opacity");
+                               else if(val == 2)
+                                       run_program(PROGRAM:"change_opacity2");
+                               else if(val == 3)
+                                       run_program(PROGRAM:"change_opacity3");
+                               else
+                                       run_program(PROGRAM:"change_opacity4");
+                       }
+               }
+               parts {
+                       part { name: "base";
+                               type: SPACER;
+                               scale: 1;
+                               description { state: "default" 0.0;
+                               }
+                       }
+                       part { name: "bg";
+                               type: SWALLOW;
+                               scale: 1;
+                               clip_to: "bg_clipper";
+                               description { state: "default" 0.0;
+                               rel1.to: "base";
+                               rel2.to: "base";
+                               }
+                       }
+                       part { name: "bg_clipper";
+                               scale: 1;
+                               description { state: "default" 0.0;
+                                       rel1.to: "bg";
+                                       rel2.to: "bg";
+                                       image.normal: "b_ic_press_full_circle_bg.png";
+                                       color: 255 255 255 255;
+                               }
+                       }
+                       part { name: "elm.swallow.content";
+                               type: SWALLOW;
+                               clip_to: "elm.swallow.content.clip";
+                               scale: 1;
+                               mouse_events:0;
+                               description { state: "default" 0.0;
+                                       rel1 {relative: 0.5 0.0; to_x:"base";}
+                                       rel2 {relative: 0.5 1.0; to_x:"base";}
+                                       //rel1.to: "base";
+                                       //rel2.to: "base";
+                                       align: 0.0 0.5;
+                                       min: 36 36 ;
+                                       max: 36 36;
+                                       fixed: 1 1;
+                               }
+                       }
+                       /*
+                       part { name: "elm.swallow.content.clip";
+                               scale: 1;
+                               description { state: "default" 0.0;
+                                       image.normal: "b_ic_press_full_circle_bg.png";
+                                       color: 255 255 255 255;
+                                       rel1.to: "elm.swallow.content";
+                                       rel2.to: "elm.swallow.content";
+                               }
+                               description { state: "pressed" 0.0;
+                                       inherit: "default" 0.0;
+                               }
+                               description { state: "disabled" 0.0;
+                                       inherit: "default" 0.0;
+                                       color: 0 0 0 0;
+                               }
+                       }
+                       */
+                       part { name: "elm.swallow.content.clip";
+                               type: RECT;
+                               scale: 1;
+                               description { state: "default" 0.0;
+                                       color_class: "AO0272";
+                               }
+                               description { state: "pressed" 0.0;
+                                       inherit: "default" 0.0;
+                                       color_class: "AO0272P";
+                               }
+                               description { state: "disabled" 0.0;
+                                       inherit: "default" 0.0;
+                                       color_class: "AO0272D";
+                               }
+                       }
+                       part { name: "effect_bg";
+                               scale: 1;
+                               clip_to: "effect_bg_clip";
+                               description { state: "default" 0.0;
+                                       rel1.to: "base";
+                                       rel2.to: "base";
+                                       image.normal: "b_ic_press_full_circle_bg.png";
+                                       color_class: "B02111";
+                                       map.on: 1;
+                               }
+                               description { state: "pressed" 0.0;
+                                       inherit: "default" 0.0;
+                                       color_class: "B02111";
+                                       map {
+                                          zoom.x: 1.0;
+                                          zoom.y: 1.0;
+                                       }
+                               }
+                               description { state: "disabled" 0.0;
+                                       inherit: "default" 0.0;
+                               }
+                               description { state: "start_persp" 0.0;
+                                       inherit: "default" 0.0;
+                                       color_class: "B02121";
+                                       map {
+                                          zoom.x: 1.2;
+                                          zoom.y: 1.2;
+                                       }
+                               }
+                       }
+                       part { name: "effect_bg_clip";
+                               scale: 1;
+                               type: RECT;
+                               description { state: "default" 0.0;
+                                       rel1.to: "base";
+                                       rel1.relative: -0.35 -0.35;
+                                       // rel1.relative: -0.0 -0.0;
+                                       rel2.to: "base";
+                                       rel2.relative: 2.35 2.35;
+                                       color: 255 255 255 0;
+                               }
+                               description { state: "pressed" 0.0;
+                                       inherit: "default" 0.0;
+                                       color: 255 255 255 255;
+                               }
+                               description { state: "disabled" 0.0;
+                                       inherit: "default" 0.0;
+                               }
+                       }
+                       part { name: "effect_bg2";
+                       scale: 1;
+                               clip_to: "effect_bg_clip2";
+                               description { state: "default" 0.0;
+                                       rel1.to: "base";
+                                       rel2.to: "base";
+                                       // rel2.relative: 2 2;
+                                       image.normal: "b_ic_press_full_circle_bg.png";
+                                       color_class: "transparent";
+                                       map.on: 1;
+                               }
+                               description { state: "pressed" 0.0;
+                                       inherit: "default" 0.0;
+                                       color_class: "B02111";
+                                       map {
+                                          zoom.x: 1.0;
+                                          zoom.y: 1.0;
+                                       }
+                               }
+                               description { state: "disabled" 0.0;
+                                       inherit: "default" 0.0;
+                               }
+                               description { state: "start_persp" 0.0;
+                                       inherit: "default" 0.0;
+                                       color_class: "B02121";
+                                       map {
+                                          zoom.x: 1.2;
+                                          zoom.y: 1.2;
+                                       }
+                               }
+                       }
+                       part { name: "effect_bg_clip2";
+                               scale: 1;
+                               type: RECT;
+                               description { state: "default" 0.0;
+                                       rel1.to: "base";
+                                       rel1.relative: -0.35 -0.35;
+                                       //rel1.relative: -0.0 -0.0;
+                                       rel2.to: "base";
+                                       rel2.relative: 2.35 2.35;
+                                       color: 255 255 255 0;
+                               }
+                               description { state: "pressed" 0.0;
+                                       inherit: "default" 0.0;
+                                       color: 255 255 255 255;
+                               }
+                               description { state: "disabled" 0.0;
+                                       inherit: "default" 0.0;
+                               }
+                       }
+                       part { name: "effect_bg3";
+                               scale: 1;
+                               clip_to: "effect_bg_clip3";
+                               description { state: "default" 0.0;
+                                       rel1.to: "base";
+                                       rel2.to: "base";
+                                       image.normal: "b_ic_press_full_circle_bg.png";
+                                       color_class: "transparent";
+                                       map.on: 1;
+                               }
+                               description { state: "pressed" 0.0;
+                                       inherit: "default" 0.0;
+                                       color_class: "B02111";
+                                       map {
+                                          zoom.x: 1.0;
+                                          zoom.y: 1.0;
+                                       }
+                               }
+                               description { state: "disabled" 0.0;
+                                       inherit: "default" 0.0;
+                               }
+                               description { state: "start_persp" 0.0;
+                                       inherit: "default" 0.0;
+                                       color_class: "B02121";
+                                       map {
+                                          zoom.x: 1.2;
+                                          zoom.y: 1.2;
+                                       }
+                               }
+                       }
+                       part { name: "effect_bg_clip3";
+                               scale: 1;
+                               type: RECT;
+                               description { state: "default" 0.0;
+                                       rel1.to: "base";
+                                        rel1.relative: -0.35 -0.35;
+                                       //      rel1.relative: -0.0 -0.0;
+                                       rel2.to: "base";
+                                       rel2.relative: 2.35 2.35;
+                                       color: 255 255 255 0;
+                               }
+                               description { state: "pressed" 0.0;
+                                       inherit: "default" 0.0;
+                                       color: 255 255 255 255;
+                               }
+                               description { state: "disabled" 0.0;
+                                       inherit: "default" 0.0;
+                               }
+                       }
+                       part { name: "effect_bg4";
+                               scale: 1;
+                               clip_to: "effect_bg_clip4";
+                               description { state: "default" 0.0;
+                                       rel1.to: "base";
+                                       rel2.to: "base";
+                                       image.normal: "b_ic_press_full_circle_bg.png";
+                                       color_class: "transparent";
+                                       map.on: 1;
+                               }
+                               description { state: "pressed" 0.0;
+                                       inherit: "default" 0.0;
+                                       color_class: "B02111";
+                                       map {
+                                          zoom.x: 1.0;
+                                          zoom.y: 1.0;
+                                       }
+                               }
+                               description { state: "disabled" 0.0;
+                                       inherit: "default" 0.0;
+                               }
+                               description { state: "start_persp" 0.0;
+                                       inherit: "default" 0.0;
+                                       color_class: "B02121";
+                                       map {
+                                          zoom.x: 1.2;
+                                          zoom.y: 1.2;
+                                       }
+                               }
+                       }
+                       part { name: "effect_bg_clip4";
+                               scale: 1;
+                               type: RECT;
+                               description { state: "default" 0.0;
+                                       rel1.to: "base";
+                                       rel1.relative: -0.35 -0.35;
+                                       // rel1.relative: -0.0 -0.0;
+                                       rel2.to: "base";
+                                       rel2.relative: 2.35 2.35;
+                                       color: 255 255 255 0;
+                               }
+                               description { state: "pressed" 0.0;
+                                       inherit: "default" 0.0;
+                                       color: 255 255 255 255;
+                               }
+                               description { state: "disabled" 0.0;
+                                       inherit: "default" 0.0;
+                               }
+                       }
+
+                       part { name: "event";
+                               type: RECT;
+                               scale: 1;
+                               description { state: "default" 0.0;
+                                       color: 255 255 0 0;
+                                       rel1 { relative: 0.0 0.0; to: "base"; offset: -25 -32;}
+                                       rel2 { relative: 1.0 1.0; to: "base"; offset: 25 72;}
+                               }
+                       }
+               }
+               programs {
+                       program { name: "pressed";
+                               signal: "mouse,down,1*";
+                               source: "event";
+                               script {
+                               if ((get_int(multi_down) == 0) && (get_int(mouse_down) == 0))
+                               {
+                                       set_int(mouse_down, 1);
+                                       run_program(PROGRAM:"button_press1");
+                               }
+                               }
+                       }
+                       program { name: "button_press1";
+                               script {
+                                       new st[31];
+                                       new Float:vl;
+                                       get_state(PART:"effect_bg", st, 30, vl);
+                                       if (strcmp(st, "disabled")) {
+                                       set_state(PART:"elm.swallow.content.clip", "pressed", 0.0);
+                                       emit("elm,action,press", "");
+                                               if(get_int(click_cnt) == 0) {
+                                                       set_state(PART:"effect_bg", "pressed", 0.0);
+                                                       set_state(PART:"effect_bg_clip", "pressed", 0.0);
+                                                       run_program(PROGRAM:"start_persp");
+                                                       timer(0.2, "timer0", 1);
+                                               }
+                                               else if(get_int(click_cnt) == 1) {
+                                                       set_state(PART:"effect_bg2", "pressed", 0.0);
+                                                       set_state(PART:"effect_bg_clip2", "pressed", 0.0);
+                                                       run_program(PROGRAM:"start_persp2");
+                                                       timer(0.1, "timer0", 2);
+                                               }
+                                               else if(get_int(click_cnt) == 2) {
+                                                       set_state(PART:"effect_bg3", "pressed", 0.0);
+                                                       set_state(PART:"effect_bg_clip3", "pressed", 0.0);
+                                                       run_program(PROGRAM:"start_persp3");
+                                                       timer(0.1, "timer0", 3);
+                                               }
+                                               else {
+                                                       set_state(PART:"effect_bg4", "pressed", 0.0);
+                                                       set_state(PART:"effect_bg_clip4", "pressed", 0.0);
+                                                       run_program(PROGRAM:"start_persp4");
+                                                       timer(0.1, "timer0", 4);
+                                               }
+                                       }
+                               }
+                       }
+                       program { name: "unpressed";
+                               signal: "mouse,up,1";
+                               source: "event";
+                               script {
+                                       if (get_int(mouse_down) == 1) {
+                                               set_int(mouse_down, 0);
+                                               run_program(PROGRAM:"button_unpress1");
+                                       }
+                               }
+                       }
+                       program { name: "button_unpress1";
+                               script {
+                                       new st[31];
+                                       new Float:vl;
+                                       get_state(PART:"effect_bg", st, 30, vl);
+                                       if (strcmp(st, "disabled")) {
+                                               set_state(PART:"elm.swallow.content.clip", "default", 0.0);
+                                               emit("elm,action,unpress", "");
+                                               if(get_int(click_cnt) == 0)
+                                                       set_int(click_cnt, 1);
+                                               else if(get_int(click_cnt) == 1)
+                                                       set_int(click_cnt, 2);
+                                               else if(get_int(click_cnt) == 2)
+                                                       set_int(click_cnt, 3);
+                                               else
+                                                       set_int(click_cnt, 0);
+                                       }
+                               }
+                       }
+                       program { name: "touch_snd";
+                               signal: "mouse,clicked,1";
+                               source: "event";
+                               script {
+                                       new st[31];
+                                       new Float:vl;
+                                       if (get_int(multi_down) == 0) {
+                                               get_state(PART:"effect_bg", st, 30, vl);
+                                               if (strcmp(st, "disabled")) {
+                                                       run_program(PROGRAM:"play_sample");
+                                                       emit("elm,action,click", "");
+                                                       set_int(mouse_click, 0);
+                                               }
+                                       }
+                               }
+                       }
+                       program {
+                               name: "play_sample";
+                               action: RUN_PLUGIN "touch_sound";
+                       }
+                       program { name: "disable";
+                               signal: "elm,state,disabled";
+                               source: "elm";
+                               action: STATE_SET "disabled" 0.0;
+                               target: "effect_bg";
+                               target: "elm.swallow.content.clip";
+                       }
+                       program { name: "enable";
+                               signal: "elm,state,enabled";
+                               source: "elm";
+                               action: STATE_SET "default" 0.0;
+                               target: "effect_bg";
+                               target: "elm.swallow.content.clip";
+                       }
+                       program { name: "multi_down";
+                               signal: "elm,action,multi,down";
+                               source: "elm";
+                               script {
+                               set_int(multi_down, 1);
+                               }
+                       }
+                       program { name: "multi_up";
+                               signal: "elm,action,multi,up";
+                               source: "elm";
+                               script {
+                                       set_int(multi_down, 0);
+                               }
+                       }
+                       program { name: "start_persp";
+                               action: STATE_SET "start_persp" 0.0;
+                               transition: CUBIC_BEZIER 0.3 0.45 0.03 0.41 1.0;
+                               target: "effect_bg";
+                       }
+                       program { name: "change_opacity";
+                               action: STATE_SET "default" 0.0;
+                               transition: CUBIC_BEZIER 0.3 0.39 0.575 0.565 1.0;
+                               target: "effect_bg_clip";
+                       }
+                       program { name: "start_persp2";
+                               action: STATE_SET "start_persp" 0.0;
+                               transition: CUBIC_BEZIER 0.3 0.45 0.03 0.41 1.0;
+                               target: "effect_bg2";
+                       }
+                       program { name: "change_opacity2";
+                               action: STATE_SET "default" 0.0;
+                               transition: CUBIC_BEZIER 0.3 0.39 0.575 0.565 1.0;
+                               target: "effect_bg_clip2";
+                       }
+                       program { name: "start_persp3";
+                               action: STATE_SET "start_persp" 0.0;
+                               transition: CUBIC_BEZIER 0.3 0.45 0.03 0.41 1.0;
+                               target: "effect_bg3";
+                       }
+                       program { name: "change_opacity3";
+                               action: STATE_SET "default" 0.0;
+                               transition: CUBIC_BEZIER 0.3 0.39 0.575 0.565 1.0;
+                               target: "effect_bg_clip3";
+                       }
+                       program { name: "start_persp4";
+                               action: STATE_SET "start_persp" 0.0;
+                               transition: CUBIC_BEZIER 0.3 0.45 0.03 0.41 1.0;
+                               target: "effect_bg4";
+                       }
+                       program { name: "change_opacity4";
+                               action: STATE_SET "default" 0.0;
+                               transition: CUBIC_BEZIER 0.3 0.39 0.575 0.565 1.0;
+                               target: "effect_bg_clip4";
+                       }
+               }
+       }
+       group { name: "elm/button/base/pallet/savemode_effect";
+               images {
+                 image: "b_ic_press_full_circle_bg.png" COMP;
+               }
+               script {
+                       public mouse_down = 0;
+                       public mouse_click = 0;
+                       public multi_down = 0;
+                       public click_cnt = 0;
+                       public timer0(val) {
+                               if(val == 1)
+                                       run_program(PROGRAM:"change_opacity");
+                               else if(val == 2)
+                                       run_program(PROGRAM:"change_opacity2");
+                               else if(val == 3)
+                                       run_program(PROGRAM:"change_opacity3");
+                               else
+                                       run_program(PROGRAM:"change_opacity4");
+                       }
+               }
+               parts {
+                       part { name: "base";
+                               type: SPACER;
+                               scale: 1;
+                               description { state: "default" 0.0;
+                               }
+                       }
+                       part { name: "bg";
+                               type: SWALLOW;
+                               scale: 1;
+                               clip_to: "bg_clipper";
+                               description { state: "default" 0.0;
+                               rel1.to: "base";
+                               rel2.to: "base";
+                               }
+                       }
+                       part { name: "bg_clipper";
+                               scale: 1;
+                               description { state: "default" 0.0;
+                                       rel1.to: "bg";
+                                       rel2.to: "bg";
+                                       image.normal: "b_ic_press_full_circle_bg.png";
+                                       color: 255 255 255 255;
+                               }
+                       }
+                       part { name: "elm.swallow.content";
+                               type: SWALLOW;
+                               clip_to: "elm.swallow.content.clip";
+                               scale: 1;
+                               mouse_events:0;
+                               description { state: "default" 0.0;
+                                       rel1 {relative: 0.0 0.0; to_x:"base";}
+                                       rel2 {relative: 1.0 1.0; to_x:"base";}
+                                       //rel1.to: "base";
+                                       //rel2.to: "base";
+                                       align: 0.5 0.5;
+                                       min: 43 43 ;
+                                       max: 43 43;
+                                       fixed: 1 1;
+                               }
+                       }
+                       /*
+                       part { name: "elm.swallow.content.clip";
+                               scale: 1;
+                               description { state: "default" 0.0;
+                                       image.normal: "b_ic_press_full_circle_bg.png";
+                                       color: 255 255 255 255;
+                                       rel1.to: "elm.swallow.content";
+                                       rel2.to: "elm.swallow.content";
+                               }
+                               description { state: "pressed" 0.0;
+                                       inherit: "default" 0.0;
+                               }
+                               description { state: "disabled" 0.0;
+                                       inherit: "default" 0.0;
+                                       color: 0 0 0 0;
+                               }
+                       }
+                       */
+                       part { name: "elm.swallow.content.clip";
+                               type: RECT;
+                               scale: 1;
+                               description { state: "default" 0.0;
+                                       color_class: "AO0272";
+                               }
+                               description { state: "pressed" 0.0;
+                                       inherit: "default" 0.0;
+                                       color_class: "AO0272P";
+                               }
+                               description { state: "disabled" 0.0;
+                                       inherit: "default" 0.0;
+                                       color_class: "AO0272D";
+                               }
+                       }
+                       part { name: "effect_bg";
+                               scale: 1;
+                               clip_to: "effect_bg_clip";
+                               description { state: "default" 0.0;
+                                       rel1.to: "base";
+                                       rel2.to: "base";
+                                       image.normal: "b_ic_press_full_circle_bg.png";
+                                       color_class: "B02111";
+                                       map.on: 1;
+                               }
+                               description { state: "pressed" 0.0;
+                                       inherit: "default" 0.0;
+                                       color_class: "B02111";
+                                       map {
+                                          zoom.x: 1.0;
+                                          zoom.y: 1.0;
+                                       }
+                               }
+                               description { state: "disabled" 0.0;
+                                       inherit: "default" 0.0;
+                               }
+                               description { state: "start_persp" 0.0;
+                                       inherit: "default" 0.0;
+                                       color_class: "B02121";
+                                       map {
+                                          zoom.x: 1.2;
+                                          zoom.y: 1.2;
+                                       }
+                               }
+                       }
+                       part { name: "effect_bg_clip";
+                               scale: 1;
+                               type: RECT;
+                               description { state: "default" 0.0;
+                                       rel1.to: "base";
+                                       rel1.relative: -0.35 -0.35;
+                                       // rel1.relative: -0.0 -0.0;
+                                       rel2.to: "base";
+                                       rel2.relative: 2.35 2.35;
+                                       color: 255 255 255 0;
+                               }
+                               description { state: "pressed" 0.0;
+                                       inherit: "default" 0.0;
+                                       color: 255 255 255 255;
+                               }
+                               description { state: "disabled" 0.0;
+                                       inherit: "default" 0.0;
+                               }
+                       }
+                       part { name: "effect_bg2";
+                       scale: 1;
+                               clip_to: "effect_bg_clip2";
+                               description { state: "default" 0.0;
+                                       rel1.to: "base";
+                                       rel2.to: "base";
+                                       // rel2.relative: 2 2;
+                                       image.normal: "b_ic_press_full_circle_bg.png";
+                                       color_class: "transparent";
+                                       map.on: 1;
+                               }
+                               description { state: "pressed" 0.0;
+                                       inherit: "default" 0.0;
+                                       color_class: "B02111";
+                                       map {
+                                          zoom.x: 1.0;
+                                          zoom.y: 1.0;
+                                       }
+                               }
+                               description { state: "disabled" 0.0;
+                                       inherit: "default" 0.0;
+                               }
+                               description { state: "start_persp" 0.0;
+                                       inherit: "default" 0.0;
+                                       color_class: "B02121";
+                                       map {
+                                          zoom.x: 1.2;
+                                          zoom.y: 1.2;
+                                       }
+                               }
+                       }
+                       part { name: "effect_bg_clip2";
+                               scale: 1;
+                               type: RECT;
+                               description { state: "default" 0.0;
+                                       rel1.to: "base";
+                                       rel1.relative: -0.35 -0.35;
+                                       //rel1.relative: -0.0 -0.0;
+                                       rel2.to: "base";
+                                       rel2.relative: 2.35 2.35;
+                                       color: 255 255 255 0;
+                               }
+                               description { state: "pressed" 0.0;
+                                       inherit: "default" 0.0;
+                                       color: 255 255 255 255;
+                               }
+                               description { state: "disabled" 0.0;
+                                       inherit: "default" 0.0;
+                               }
+                       }
+                       part { name: "effect_bg3";
+                               scale: 1;
+                               clip_to: "effect_bg_clip3";
+                               description { state: "default" 0.0;
+                                       rel1.to: "base";
+                                       rel2.to: "base";
+                                       image.normal: "b_ic_press_full_circle_bg.png";
+                                       color_class: "transparent";
+                                       map.on: 1;
+                               }
+                               description { state: "pressed" 0.0;
+                                       inherit: "default" 0.0;
+                                       color_class: "B02111";
+                                       map {
+                                          zoom.x: 1.0;
+                                          zoom.y: 1.0;
+                                       }
+                               }
+                               description { state: "disabled" 0.0;
+                                       inherit: "default" 0.0;
+                               }
+                               description { state: "start_persp" 0.0;
+                                       inherit: "default" 0.0;
+                                       color_class: "B02121";
+                                       map {
+                                          zoom.x: 1.2;
+                                          zoom.y: 1.2;
+                                       }
+                               }
+                       }
+                       part { name: "effect_bg_clip3";
+                               scale: 1;
+                               type: RECT;
+                               description { state: "default" 0.0;
+                                       rel1.to: "base";
+                                        rel1.relative: -0.35 -0.35;
+                                       //      rel1.relative: -0.0 -0.0;
+                                       rel2.to: "base";
+                                       rel2.relative: 2.35 2.35;
+                                       color: 255 255 255 0;
+                               }
+                               description { state: "pressed" 0.0;
+                                       inherit: "default" 0.0;
+                                       color: 255 255 255 255;
+                               }
+                               description { state: "disabled" 0.0;
+                                       inherit: "default" 0.0;
+                               }
+                       }
+                       part { name: "effect_bg4";
+                               scale: 1;
+                               clip_to: "effect_bg_clip4";
+                               description { state: "default" 0.0;
+                               rel1.to: "base";
+                               rel2.to: "base";
+                               image.normal: "b_ic_press_full_circle_bg.png";
+                               color_class: "transparent";
+                               map.on: 1;
+                               }
+                               description { state: "pressed" 0.0;
+                                       inherit: "default" 0.0;
+                                       color_class: "B02111";
+                                       map {
+                                          zoom.x: 1.0;
+                                          zoom.y: 1.0;
+                                       }
+                               }
+                               description { state: "disabled" 0.0;
+                                       inherit: "default" 0.0;
+                               }
+                               description { state: "start_persp" 0.0;
+                                       inherit: "default" 0.0;
+                                       color_class: "B02121";
+                                       map {
+                                          zoom.x: 1.2;
+                                          zoom.y: 1.2;
+                                       }
+                               }
+                       }
+                       part { name: "effect_bg_clip4";
+                               scale: 1;
+                               type: RECT;
+                               description { state: "default" 0.0;
+                                       rel1.to: "base";
+                                       rel1.relative: -0.35 -0.35;
+                                       // rel1.relative: -0.0 -0.0;
+                                       rel2.to: "base";
+                                       rel2.relative: 2.35 2.35;
+                                       color: 255 255 255 0;
+                               }
+                               description { state: "pressed" 0.0;
+                                       inherit: "default" 0.0;
+                                       color: 255 255 255 255;
+                               }
+                               description { state: "disabled" 0.0;
+                                       inherit: "default" 0.0;
+                               }
+                       }
+
+                       part { name: "event";
+                               type: RECT;
+                               scale: 1;
+                               description { state: "default" 0.0;
+                                       color: 255 255 0 0;
+                                       rel1 { relative: 0.0 0.0; to: "base"; offset: -25 -32;}
+                                       rel2 { relative: 1.0 1.0; to: "base"; offset: 25 72;}
+                               }
+                       }
+               }
+               programs {
+                       program { name: "pressed";
+                               signal: "mouse,down,1*";
+                               source: "event";
+                               script {
+                               if ((get_int(multi_down) == 0) && (get_int(mouse_down) == 0))
+                               {
+                                       set_int(mouse_down, 1);
+                                       run_program(PROGRAM:"button_press1");
+                               }
+                               }
+                       }
+                       program { name: "button_press1";
+                               script {
+                                       new st[31];
+                                       new Float:vl;
+                                       get_state(PART:"effect_bg", st, 30, vl);
+                                       if (strcmp(st, "disabled")) {
+                                       set_state(PART:"elm.swallow.content.clip", "pressed", 0.0);
+                                       emit("elm,action,press", "");
+                                               if(get_int(click_cnt) == 0) {
+                                                       set_state(PART:"effect_bg", "pressed", 0.0);
+                                                       set_state(PART:"effect_bg_clip", "pressed", 0.0);
+                                                       run_program(PROGRAM:"start_persp");
+                                                       timer(0.2, "timer0", 1);
+                                               }
+                                               else if(get_int(click_cnt) == 1) {
+                                                       set_state(PART:"effect_bg2", "pressed", 0.0);
+                                                       set_state(PART:"effect_bg_clip2", "pressed", 0.0);
+                                                       run_program(PROGRAM:"start_persp2");
+                                                       timer(0.1, "timer0", 2);
+                                               }
+                                               else if(get_int(click_cnt) == 2) {
+                                                       set_state(PART:"effect_bg3", "pressed", 0.0);
+                                                       set_state(PART:"effect_bg_clip3", "pressed", 0.0);
+                                                       run_program(PROGRAM:"start_persp3");
+                                                       timer(0.1, "timer0", 3);
+                                               }
+                                               else {
+                                                       set_state(PART:"effect_bg4", "pressed", 0.0);
+                                                       set_state(PART:"effect_bg_clip4", "pressed", 0.0);
+                                                       run_program(PROGRAM:"start_persp4");
+                                                       timer(0.1, "timer0", 4);
+                                               }
+                                       }
+                               }
+                       }
+                       program { name: "unpressed";
+                               signal: "mouse,up,1";
+                               source: "event";
+                               script {
+                                       if (get_int(mouse_down) == 1) {
+                                               set_int(mouse_down, 0);
+                                               run_program(PROGRAM:"button_unpress1");
+                                       }
+                               }
+                       }
+                       program { name: "button_unpress1";
+                               script {
+                                       new st[31];
+                                       new Float:vl;
+                                       get_state(PART:"effect_bg", st, 30, vl);
+                                       if (strcmp(st, "disabled")) {
+                                               set_state(PART:"elm.swallow.content.clip", "default", 0.0);
+                                               emit("elm,action,unpress", "");
+                                               if(get_int(click_cnt) == 0)
+                                                       set_int(click_cnt, 1);
+                                               else if(get_int(click_cnt) == 1)
+                                                       set_int(click_cnt, 2);
+                                               else if(get_int(click_cnt) == 2)
+                                                       set_int(click_cnt, 3);
+                                               else
+                                                       set_int(click_cnt, 0);
+                                       }
+                               }
+                       }
+                       program { name: "touch_snd";
+                               signal: "mouse,clicked,1";
+                               source: "event";
+                               script {
+                                       new st[31];
+                                       new Float:vl;
+                                       if (get_int(multi_down) == 0) {
+                                               get_state(PART:"effect_bg", st, 30, vl);
+                                               if (strcmp(st, "disabled")) {
+                                                       run_program(PROGRAM:"play_sample");
+                                                       emit("elm,action,click", "");
+                                                       set_int(mouse_click, 0);
+                                               }
+                                       }
+                               }
+                       }
+                       program {
+                               name: "play_sample";
+                               action: RUN_PLUGIN "touch_sound";
+                       }
+                       program { name: "disable";
+                               signal: "elm,state,disabled";
+                               source: "elm";
+                               action: STATE_SET "disabled" 0.0;
+                               target: "effect_bg";
+                               target: "elm.swallow.content.clip";
+                       }
+                       program { name: "enable";
+                               signal: "elm,state,enabled";
+                               source: "elm";
+                               action: STATE_SET "default" 0.0;
+                               target: "effect_bg";
+                               target: "elm.swallow.content.clip";
+                       }
+                       program { name: "multi_down";
+                               signal: "elm,action,multi,down";
+                               source: "elm";
+                               script {
+                               set_int(multi_down, 1);
+                               }
+                       }
+                       program { name: "multi_up";
+                               signal: "elm,action,multi,up";
+                               source: "elm";
+                               script {
+                                       set_int(multi_down, 0);
+                               }
+                       }
+                       program { name: "start_persp";
+                               action: STATE_SET "start_persp" 0.0;
+                               transition: CUBIC_BEZIER 0.3 0.45 0.03 0.41 1.0;
+                               target: "effect_bg";
+                       }
+                       program { name: "change_opacity";
+                               action: STATE_SET "default" 0.0;
+                               transition: CUBIC_BEZIER 0.3 0.39 0.575 0.565 1.0;
+                               target: "effect_bg_clip";
+                       }
+                       program { name: "start_persp2";
+                               action: STATE_SET "start_persp" 0.0;
+                               transition: CUBIC_BEZIER 0.3 0.45 0.03 0.41 1.0;
+                               target: "effect_bg2";
+                       }
+                       program { name: "change_opacity2";
+                               action: STATE_SET "default" 0.0;
+                               transition: CUBIC_BEZIER 0.3 0.39 0.575 0.565 1.0;
+                               target: "effect_bg_clip2";
+                       }
+                       program { name: "start_persp3";
+                               action: STATE_SET "start_persp" 0.0;
+                               transition: CUBIC_BEZIER 0.3 0.45 0.03 0.41 1.0;
+                               target: "effect_bg3";
+                       }
+                       program { name: "change_opacity3";
+                               action: STATE_SET "default" 0.0;
+                               transition: CUBIC_BEZIER 0.3 0.39 0.575 0.565 1.0;
+                               target: "effect_bg_clip3";
+                       }
+                       program { name: "start_persp4";
+                               action: STATE_SET "start_persp" 0.0;
+                               transition: CUBIC_BEZIER 0.3 0.45 0.03 0.41 1.0;
+                               target: "effect_bg4";
+                       }
+                       program { name: "change_opacity4";
+                               action: STATE_SET "default" 0.0;
+                               transition: CUBIC_BEZIER 0.3 0.39 0.575 0.565 1.0;
+                               target: "effect_bg_clip4";
+                       }
+               }
+       }
+       group { name: "elm/button/base/drawing/stroke_effect/default";
+               images {
+                       image: "b_ic_press_full_circle_bg.png" COMP;
+               }
+               script {
+                       public mouse_down = 0;
+                       public mouse_click = 0;
+                       public multi_down = 0;
+                       public click_cnt = 0;
+                       public timer0(val) {
+                               if(val == 1)
+                                  run_program(PROGRAM:"change_opacity");
+                               else if(val == 2)
+                                  run_program(PROGRAM:"change_opacity2");
+                               else if(val == 3)
+                                  run_program(PROGRAM:"change_opacity3");
+                               else
+                                  run_program(PROGRAM:"change_opacity4");
+                       }
+               }
+               parts {
+                       part { name: "base";
+                               type: SPACER;
+                               scale: 1;
+                               description { state: "default" 0.0;
+                               }
+                       }
+                       part { name: "bg";
+                                       type: SWALLOW;
+                                       scale: 1;
+                                       clip_to: "bg_clipper";
+                                       description { state: "default" 0.0;
+                                       rel1.to: "base";
+                                       rel2.to: "base";
+                                       }
+                       }
+                       part { name: "bg_clipper";
+                               scale: 1;
+                               description { state: "default" 0.0;
+                                       rel1.to: "bg";
+                                       rel2.to: "bg";
+                                       image.normal: "b_ic_press_full_circle_bg.png";
+                                       color: 255 255 255 255;
+                                       }
+                       }
+                       part { name: "elm.swallow.content";
+                               type: SWALLOW;
+                               clip_to: "elm.swallow.content.clip";
+                               scale: 1;
+                               description { state: "default" 0.0;
+                                       rel1.to: "base";
+                                       rel2.to: "base";
+                               }
+                       }
+                       part { name: "elm.swallow.content.clip";
+                               scale: 1;
+                               description { state: "default" 0.0;
+                                       image.normal: "b_ic_press_full_circle_bg.png";
+                                       color: 255 255 255 255;
+                                       rel1.to: "elm.swallow.content";
+                                       rel2.to: "elm.swallow.content";
+                               }
+                               description { state: "pressed" 0.0;
+                                       inherit: "default" 0.0;
+                               }
+                               description { state: "disabled" 0.0;
+                                       inherit: "default" 0.0;
+                                       color: 255 255 255 100;
+                               }
+                       }
+                       part { name: "effect_bg";
+                               scale: 1;
+                               clip_to: "effect_bg_clip";
+                               description { state: "default" 0.0;
+                                       rel1.to: "base";
+                                       rel2.to: "base";
+                                       image.normal: "b_ic_press_full_circle_bg.png";
+                                       color_class: "B02111";
+                                       map.on: 1;
+                               }
+                               description { state: "pressed" 0.0;
+                                       inherit: "default" 0.0;
+                                       color_class: "B02111";
+                                       map {
+                                          zoom.x: 1.4;
+                                          zoom.y: 1.4;
+                                       }
+                               }
+                               description { state: "disabled" 0.0;
+                                       inherit: "default" 0.0;
+                               }
+                               description { state: "start_persp" 0.0;
+                                       inherit: "default" 0.0;
+                                       color_class: "B02121";
+                                       //color_class: "B02111";
+                                       map {
+                                          zoom.x: 1.7;
+                                          zoom.y: 1.7;
+                                       }
+                               }
+                       }
+                       part { name: "effect_bg_clip";
+                               scale: 1;
+                               type: RECT;
+                               description { state: "default" 0.0;
+                                       rel1.to: "base";
+                                       rel1.relative: -0.35 -0.35;
+                                       rel2.to: "base";
+                                       rel2.relative: 1.35 1.35;
+                                       color: 255 255 255 0;
+                               }
+                               description { state: "pressed" 0.0;
+                                       inherit: "default" 0.0;
+                                       color: 255 255 255 255;
+                               }
+                               description { state: "disabled" 0.0;
+                                       inherit: "default" 0.0;
+                               }
+                       }
+                       part { name: "effect_bg2";
+                               scale: 1;
+                               clip_to: "effect_bg_clip2";
+                               description { state: "default" 0.0;
+                                       rel1.to: "base";
+                                       rel2.to: "base";
+                                       image.normal: "b_ic_press_full_circle_bg.png";
+                                       color_class: "transparent";
+                                       map.on: 1;
+                               }
+                               description { state: "pressed" 0.0;
+                                       inherit: "default" 0.0;
+                                       color_class: "B02111";
+                                       map {
+                                          zoom.x: 1.4;
+                                          zoom.y: 1.4;
+                                       }
+                               }
+                               description { state: "disabled" 0.0;
+                                       inherit: "default" 0.0;
+                               }
+                               description { state: "start_persp" 0.0;
+                                       inherit: "default" 0.0;
+                                       color_class: "B02121";
+                                       map {
+                                          zoom.x: 1.7;
+                                          zoom.y: 1.7;
+                                       }
+                               }
+                       }
+                       part { name: "effect_bg_clip2";
+                               scale: 1;
+                               type: RECT;
+                               description { state: "default" 0.0;
+                                       rel1.to: "base";
+                                       rel1.relative: -0.35 -0.35;
+                                       rel2.to: "base";
+                                       rel2.relative: 1.35 1.35;
+                                       color: 255 255 255 0;
+                               }
+                               description { state: "pressed" 0.0;
+                                       inherit: "default" 0.0;
+                                       color: 255 255 255 255;
+                               }
+                               description { state: "disabled" 0.0;
+                                       inherit: "default" 0.0;
+                               }
+                       }
+                       part { name: "effect_bg3";
+                               scale: 1;
+                               clip_to: "effect_bg_clip3";
+                               description { state: "default" 0.0;
+                                       rel1.to: "base";
+                                       rel2.to: "base";
+                                       image.normal: "b_ic_press_full_circle_bg.png";
+                                       color_class: "transparent";
+                                       map.on: 1;
+                               }
+                               description { state: "pressed" 0.0;
+                                       inherit: "default" 0.0;
+                                       color_class: "B02111";
+                                       map {
+                                          zoom.x: 1.4;
+                                          zoom.y: 1.4;
+                                       }
+                               }
+                               description { state: "disabled" 0.0;
+                                       inherit: "default" 0.0;
+                               }
+                               description { state: "start_persp" 0.0;
+                                       inherit: "default" 0.0;
+                                       color_class: "B02121";
+                                       map {
+                                          zoom.x: 1.7;
+                                          zoom.y: 1.7;
+                                       }
+                               }
+                       }
+                       part { name: "effect_bg_clip3";
+                               scale: 1;
+                               type: RECT;
+                               description { state: "default" 0.0;
+                                       rel1.to: "base";
+                                       rel1.relative: -0.35 -0.35;
+                                       rel2.to: "base";
+                                       rel2.relative: 1.35 1.35;
+                                       color: 255 255 255 0;
+                               }
+                               description { state: "pressed" 0.0;
+                                       inherit: "default" 0.0;
+                                       color: 255 255 255 255;
+                               }
+                               description { state: "disabled" 0.0;
+                                       inherit: "default" 0.0;
+                               }
+                       }
+                       part { name: "effect_bg4";
+                               scale: 1;
+                               clip_to: "effect_bg_clip4";
+                               description { state: "default" 0.0;
+                                       rel1.to: "base";
+                                       rel2.to: "base";
+                                       image.normal: "b_ic_press_full_circle_bg.png";
+                                       color_class: "transparent";
+                                       map.on: 1;
+                               }
+                               description { state: "pressed" 0.0;
+                                       inherit: "default" 0.0;
+                                       color_class: "B02111";
+                                       map {
+                                          zoom.x: 1.4;
+                                          zoom.y: 1.4;
+                                       }
+                               }
+                               description { state: "disabled" 0.0;
+                                       inherit: "default" 0.0;
+                               }
+                               description { state: "start_persp" 0.0;
+                                       inherit: "default" 0.0;
+                                       color_class: "B02121";
+                                       map {
+                                          zoom.x: 1.7;
+                                          zoom.y: 1.7;
+                                       }
+                               }
+                       }
+                       part { name: "effect_bg_clip4";
+                               scale: 1;
+                               type: RECT;
+                               description { state: "default" 0.0;
+                                       rel1.to: "base";
+                                       rel1.relative: -0.35 -0.35;
+                                       rel2.to: "base";
+                                       rel2.relative: 1.35 1.35;
+                                       color: 255 255 255 0;
+                               }
+                               description { state: "pressed" 0.0;
+                                       inherit: "default" 0.0;
+                                       color: 255 255 255 255;
+                               }
+                               description { state: "disabled" 0.0;
+                                       inherit: "default" 0.0;
+                               }
+                       }
+                       part { name: "event";
+                               type: RECT;
+                               scale: 1;
+                               description { state: "default" 0.0;
+                                       color: 0 0 0 0;
+                                       rel1.to: "base";
+                                       rel2.to: "base";
+                               }
+                       }
+               }
+               programs {
+                       program { name: "pressed";
+                               signal: "mouse,down,1*";
+                               source: "event";
+                               script {
+                                       if ((get_int(multi_down) == 0) && (get_int(mouse_down) == 0))
+                                       {
+                                          set_int(mouse_down, 1);
+                                          run_program(PROGRAM:"button_press1");
+                                       }
+                               }
+                       }
+                       program { name: "button_press1";
+                               script {
+                                       new st[31];
+                                       new Float:vl;
+                                       get_state(PART:"effect_bg", st, 30, vl);
+                                       if (strcmp(st, "disabled")) {
+                                          set_state(PART:"elm.swallow.content.clip", "pressed", 0.0);
+                                          emit("elm,action,press", "");
+                                          if(get_int(click_cnt) == 0) {
+                                             set_state(PART:"effect_bg", "pressed", 0.0);
+                                             set_state(PART:"effect_bg_clip", "pressed", 0.0);
+                                             run_program(PROGRAM:"start_persp");
+                                             timer(0.1, "timer0", 1);
+                                          }
+                                          else if(get_int(click_cnt) == 1) {
+                                             set_state(PART:"effect_bg2", "pressed", 0.0);
+                                             set_state(PART:"effect_bg_clip2", "pressed", 0.0);
+                                             run_program(PROGRAM:"start_persp2");
+                                             timer(0.1, "timer0", 2);
+                                          }
+                                          else if(get_int(click_cnt) == 2) {
+                                             set_state(PART:"effect_bg3", "pressed", 0.0);
+                                             set_state(PART:"effect_bg_clip3", "pressed", 0.0);
+                                             run_program(PROGRAM:"start_persp3");
+                                             timer(0.1, "timer0", 3);
+                                          }
+                                          else {
+                                             set_state(PART:"effect_bg4", "pressed", 0.0);
+                                             set_state(PART:"effect_bg_clip4", "pressed", 0.0);
+                                             run_program(PROGRAM:"start_persp4");
+                                             timer(0.1, "timer0", 4);
+                                          }
+                                       }
+                               }
+                       }
+                       program { name: "unpressed";
+                               signal: "mouse,up,1";
+                               source: "event";
+                               script {
+                                       if (get_int(mouse_down) == 1) {
+                                          set_int(mouse_down, 0);
+                                          run_program(PROGRAM:"button_unpress1");
+                                       }
+                               }
+                       }
+                       program { name: "button_unpress1";
+                               script {
+                                       new st[31];
+                                       new Float:vl;
+                                       get_state(PART:"effect_bg", st, 30, vl);
+                                       if (strcmp(st, "disabled")) {
+                                               set_state(PART:"elm.swallow.content.clip", "default", 0.0);
+                                               emit("elm,action,unpress", "");
+                                               if(get_int(click_cnt) == 0)
+                                                       set_int(click_cnt, 1);
+                                               else if(get_int(click_cnt) == 1)
+                                                       set_int(click_cnt, 2);
+                                               else if(get_int(click_cnt) == 2)
+                                                       set_int(click_cnt, 3);
+                                               else
+                                                       set_int(click_cnt, 0);
+                                       }
+                               }
+                       }
+                       program { name: "touch_snd";
+                               signal: "mouse,clicked,1";
+                               source: "event";
+                               script {
+                                       new st[31];
+                                       new Float:vl;
+                                       if (get_int(multi_down) == 0) {
+                                               get_state(PART:"effect_bg", st, 30, vl);
+                                               if (strcmp(st, "disabled")) {
+                                                       run_program(PROGRAM:"play_sample");
+                                                       emit("elm,action,click", "");
+                                                       set_int(mouse_click, 0);
+                                               }
+                                       }
+                               }
+                       }
+                       program {
+                               name: "play_sample";
+                               action: RUN_PLUGIN "touch_sound";
+                       }
+                       program { name: "disable";
+                               signal: "elm,state,disabled";
+                               source: "elm";
+                               action: STATE_SET "disabled" 0.0;
+                               target: "effect_bg";
+                               target: "elm.swallow.content.clip";
+                       }
+                       program { name: "enable";
+                               signal: "elm,state,enabled";
+                               source: "elm";
+                               action: STATE_SET "default" 0.0;
+                               target: "effect_bg";
+                               target: "elm.swallow.content.clip";
+                       }
+                       program { name: "multi_down";
+                               signal: "elm,action,multi,down";
+                               source: "elm";
+                               script {
+                                       set_int(multi_down, 1);
+                               }
+                       }
+                       program { name: "multi_up";
+                               signal: "elm,action,multi,up";
+                               source: "elm";
+                               script {
+                                       set_int(multi_down, 0);
+                               }
+                       }
+                       program { name: "start_persp";
+                               action: STATE_SET "start_persp" 0.0;
+                               transition: CUBIC_BEZIER 0.3 0.45 0.03 0.41 1.0;
+                               target: "effect_bg";
+                       }
+                       program { name: "change_opacity";
+                               action: STATE_SET "default" 0.0;
+                               transition: CUBIC_BEZIER 0.3 0.39 0.575 0.565 1.0;
+                               target: "effect_bg_clip";
+                       }
+                       program { name: "start_persp2";
+                               action: STATE_SET "start_persp" 0.0;
+                               transition: CUBIC_BEZIER 0.3 0.45 0.03 0.41 1.0;
+                               target: "effect_bg2";
+                       }
+                       program { name: "change_opacity2";
+                               action: STATE_SET "default" 0.0;
+                               transition: CUBIC_BEZIER 0.3 0.39 0.575 0.565 1.0;
+                               target: "effect_bg_clip2";
+                       }
+                       program { name: "start_persp3";
+                               action: STATE_SET "start_persp" 0.0;
+                               transition: CUBIC_BEZIER 0.3 0.45 0.03 0.41 1.0;
+                               target: "effect_bg3";
+                       }
+                       program { name: "change_opacity3";
+                               action: STATE_SET "default" 0.0;
+                               transition: CUBIC_BEZIER 0.3 0.39 0.575 0.565 1.0;
+                               target: "effect_bg_clip3";
+                       }
+                       program { name: "start_persp4";
+                               action: STATE_SET "start_persp" 0.0;
+                               transition: CUBIC_BEZIER 0.3 0.45 0.03 0.41 1.0;
+                               target: "effect_bg4";
+                       }
+                       program { name: "change_opacity4";
+                               action: STATE_SET "default" 0.0;
+                               transition: CUBIC_BEZIER 0.3 0.39 0.575 0.565 1.0;
+                               target: "effect_bg_clip4";
+                       }
+               }
+       }
+       group { name: "elm/button/base/pallet/sendmode_effect";
+               images {
+                 image: "b_ic_press_full_circle_bg.png" COMP;
+               }
+               script {
+                       public mouse_down = 0;
+                       public mouse_click = 0;
+                       public multi_down = 0;
+                       public click_cnt = 0;
+                       public timer0(val) {
+                               if(val == 1)
+                                  run_program(PROGRAM:"change_opacity");
+                               else if(val == 2)
+                                  run_program(PROGRAM:"change_opacity2");
+                               else if(val == 3)
+                                  run_program(PROGRAM:"change_opacity3");
+                               else
+                                  run_program(PROGRAM:"change_opacity4");
+                       }
+               }
+               parts {
+                       part { name: "base";
+                               type: SPACER;
+                               scale: 1;
+                               description { state: "default" 0.0;
+                               }
+                       }
+                       part { name: "bg";
+                               type: SWALLOW;
+                               scale: 1;
+                               clip_to: "bg_clipper";
+                               description { state: "default" 0.0;
+                               rel1.to: "base";
+                               rel2.to: "base";
+                               }
+                       }
+                       part { name: "bg_clipper";
+                               scale: 1;
+                               description { state: "default" 0.0;
+                                       rel1.to: "bg";
+                                       rel2.to: "bg";
+                                       image.normal: "b_ic_press_full_circle_bg.png";
+                                       color: 255 255 255 255;
+                               }
+                       }
+                       part { name: "elm.swallow.content";
+                               type: SWALLOW;
+                               clip_to: "elm.swallow.content.clip";
+                               scale: 1;
+                               mouse_events:0;
+                               description { state: "default" 0.0;
+                                       rel1 {relative: 0.5 0.0; to_x:"base";}
+                                       rel2 {relative: 0.5 1.0; to_x:"base";}
+                                       //rel1.to: "base";
+                                       //rel2.to: "base";
+                                       align: 1.0 0.5;
+                                       min: 36 36 ;
+                                       max: 36 36;
+                                       fixed: 1 1;
+                               }
+                       }
+                       /*
+                       part { name: "elm.swallow.content.clip";
+                               scale: 1;
+                               description { state: "default" 0.0;
+                                       image.normal: "b_ic_press_full_circle_bg.png";
+                                       color: 255 255 255 255;
+                                       rel1.to: "elm.swallow.content";
+                                       rel2.to: "elm.swallow.content";
+                               }
+                               description { state: "pressed" 0.0;
+                                       inherit: "default" 0.0;
+                               }
+                               description { state: "disabled" 0.0;
+                                       inherit: "default" 0.0;
+                                       color: 0 0 0 0;
+                               }
+                       }
+                       */
+                       part { name: "elm.swallow.content.clip";
+                               type: RECT;
+                               scale: 1;
+                               description { state: "default" 0.0;
+                                       color_class: "AO0272";
+                               }
+                               description { state: "pressed" 0.0;
+                                       inherit: "default" 0.0;
+                                       color_class: "AO0272P";
+                               }
+                               description { state: "disabled" 0.0;
+                                       inherit: "default" 0.0;
+                                       color_class: "AO0272D";
+                               }
+                       }
+                       part { name: "effect_bg";
+                               scale: 1;
+                               clip_to: "effect_bg_clip";
+                               description { state: "default" 0.0;
+                                       rel1.to: "base";
+                                       rel2.to: "base";
+                                       image.normal: "b_ic_press_full_circle_bg.png";
+                                       color_class: "B02111";
+                                       map.on: 1;
+                               }
+                               description { state: "pressed" 0.0;
+                                       inherit: "default" 0.0;
+                                       color_class: "B02111";
+                                       map {
+                                          zoom.x: 1.0;
+                                          zoom.y: 1.0;
+                                       }
+                               }
+                               description { state: "disabled" 0.0;
+                                       inherit: "default" 0.0;
+                               }
+                               description { state: "start_persp" 0.0;
+                                       inherit: "default" 0.0;
+                                       color_class: "B02121";
+                                       map {
+                                          zoom.x: 1.2;
+                                          zoom.y: 1.2;
+                                       }
+                               }
+                       }
+                       part { name: "effect_bg_clip";
+                               scale: 1;
+                               type: RECT;
+                               description { state: "default" 0.0;
+                                       rel1.to: "base";
+                                       rel1.relative: -0.35 -0.35;
+                                       // rel1.relative: -0.0 -0.0;
+                                       rel2.to: "base";
+                                       rel2.relative: 2.35 2.35;
+                                       color: 255 255 255 0;
+                               }
+                               description { state: "pressed" 0.0;
+                                       inherit: "default" 0.0;
+                                       color: 255 255 255 255;
+                               }
+                               description { state: "disabled" 0.0;
+                                       inherit: "default" 0.0;
+                               }
+                       }
+                       part { name: "effect_bg2";
+                       scale: 1;
+                               clip_to: "effect_bg_clip2";
+                               description { state: "default" 0.0;
+                                       rel1.to: "base";
+                                       rel2.to: "base";
+                                       // rel2.relative: 2 2;
+                                       image.normal: "b_ic_press_full_circle_bg.png";
+                                       color_class: "transparent";
+                                       map.on: 1;
+                               }
+                               description { state: "pressed" 0.0;
+                                       inherit: "default" 0.0;
+                                       color_class: "B02111";
+                                       map {
+                                          zoom.x: 1.0;
+                                          zoom.y: 1.0;
+                                       }
+                               }
+                               description { state: "disabled" 0.0;
+                                       inherit: "default" 0.0;
+                               }
+                               description { state: "start_persp" 0.0;
+                                       inherit: "default" 0.0;
+                                       color_class: "B02121";
+                                       map {
+                                          zoom.x: 1.2;
+                                          zoom.y: 1.2;
+                                       }
+                               }
+                       }
+                       part { name: "effect_bg_clip2";
+                               scale: 1;
+                               type: RECT;
+                               description { state: "default" 0.0;
+                                       rel1.to: "base";
+                                       rel1.relative: -0.35 -0.35;
+                                       //rel1.relative: -0.0 -0.0;
+                                       rel2.to: "base";
+                                       rel2.relative: 2.35 2.35;
+                                       color: 255 255 255 0;
+                               }
+                               description { state: "pressed" 0.0;
+                                       inherit: "default" 0.0;
+                                       color: 255 255 255 255;
+                               }
+                               description { state: "disabled" 0.0;
+                                       inherit: "default" 0.0;
+                               }
+                       }
+                       part { name: "effect_bg3";
+                               scale: 1;
+                               clip_to: "effect_bg_clip3";
+                               description { state: "default" 0.0;
+                                       rel1.to: "base";
+                                       rel2.to: "base";
+                                       image.normal: "b_ic_press_full_circle_bg.png";
+                                       color_class: "transparent";
+                                       map.on: 1;
+                               }
+                               description { state: "pressed" 0.0;
+                                       inherit: "default" 0.0;
+                                       color_class: "B02111";
+                                       map {
+                                          zoom.x: 1.0;
+                                          zoom.y: 1.0;
+                                       }
+                               }
+                               description { state: "disabled" 0.0;
+                                       inherit: "default" 0.0;
+                               }
+                               description { state: "start_persp" 0.0;
+                                       inherit: "default" 0.0;
+                                       color_class: "B02121";
+                                       map {
+                                          zoom.x: 1.2;
+                                          zoom.y: 1.2;
+                                       }
+                               }
+                       }
+                       part { name: "effect_bg_clip3";
+                               scale: 1;
+                               type: RECT;
+                               description { state: "default" 0.0;
+                                       rel1.to: "base";
+                                        rel1.relative: -0.35 -0.35;
+                                       //      rel1.relative: -0.0 -0.0;
+                                       rel2.to: "base";
+                                       rel2.relative: 2.35 2.35;
+                                       color: 255 255 255 0;
+                               }
+                               description { state: "pressed" 0.0;
+                                       inherit: "default" 0.0;
+                                       color: 255 255 255 255;
+                               }
+                               description { state: "disabled" 0.0;
+                                       inherit: "default" 0.0;
+                               }
+                       }
+                       part { name: "effect_bg4";
+                               scale: 1;
+                               clip_to: "effect_bg_clip4";
+                               description { state: "default" 0.0;
+                               rel1.to: "base";
+                               rel2.to: "base";
+                               image.normal: "b_ic_press_full_circle_bg.png";
+                               color_class: "transparent";
+                               map.on: 1;
+                               }
+                               description { state: "pressed" 0.0;
+                                       inherit: "default" 0.0;
+                                       color_class: "B02111";
+                                       map {
+                                          zoom.x: 1.0;
+                                          zoom.y: 1.0;
+                                       }
+                               }
+                               description { state: "disabled" 0.0;
+                                       inherit: "default" 0.0;
+                               }
+                               description { state: "start_persp" 0.0;
+                                       inherit: "default" 0.0;
+                                       color_class: "B02121";
+                                       map {
+                                          zoom.x: 1.2;
+                                          zoom.y: 1.2;
+                                       }
+                               }
+                       }
+                       part { name: "effect_bg_clip4";
+                               scale: 1;
+                               type: RECT;
+                               description { state: "default" 0.0;
+                                       rel1.to: "base";
+                                       rel1.relative: -0.35 -0.35;
+                                       // rel1.relative: -0.0 -0.0;
+                                       rel2.to: "base";
+                                       rel2.relative: 2.35 2.35;
+                                       color: 255 255 255 0;
+                               }
+                               description { state: "pressed" 0.0;
+                                       inherit: "default" 0.0;
+                                       color: 255 255 255 255;
+                               }
+                               description { state: "disabled" 0.0;
+                                       inherit: "default" 0.0;
+                               }
+                       }
+
+                       part { name: "event";
+                               type: RECT;
+                               scale: 1;
+                               description { state: "default" 0.0;
+                                       color: 255 255 0 0;
+                                       rel1 { relative: 0.0 0.0; to: "base"; offset: -25 -32;}
+                                       rel2 { relative: 1.0 1.0; to: "base"; offset: 25 72;}
+                               }
+                       }
+               }
+               programs {
+                       program { name: "pressed";
+                               signal: "mouse,down,1*";
+                               source: "event";
+                               script {
+                               if ((get_int(multi_down) == 0) && (get_int(mouse_down) == 0))
+                               {
+                                       set_int(mouse_down, 1);
+                                       run_program(PROGRAM:"button_press1");
+                               }
+                               }
+                       }
+                       program { name: "button_press1";
+                               script {
+                                       new st[31];
+                                       new Float:vl;
+                                       get_state(PART:"effect_bg", st, 30, vl);
+                                       if (strcmp(st, "disabled")) {
+                                       set_state(PART:"elm.swallow.content.clip", "pressed", 0.0);
+                                       emit("elm,action,press", "");
+                                               if(get_int(click_cnt) == 0) {
+                                               set_state(PART:"effect_bg", "pressed", 0.0);
+                                               set_state(PART:"effect_bg_clip", "pressed", 0.0);
+                                               run_program(PROGRAM:"start_persp");
+                                               timer(0.2, "timer0", 1);
+                                               }
+                                               else if(get_int(click_cnt) == 1) {
+                                                       set_state(PART:"effect_bg2", "pressed", 0.0);
+                                                       set_state(PART:"effect_bg_clip2", "pressed", 0.0);
+                                                       run_program(PROGRAM:"start_persp2");
+                                                       timer(0.1, "timer0", 2);
+                                               }
+                                               else if(get_int(click_cnt) == 2) {
+                                                       set_state(PART:"effect_bg3", "pressed", 0.0);
+                                                       set_state(PART:"effect_bg_clip3", "pressed", 0.0);
+                                                       run_program(PROGRAM:"start_persp3");
+                                                       timer(0.1, "timer0", 3);
+                                               }
+                                               else {
+                                                       set_state(PART:"effect_bg4", "pressed", 0.0);
+                                                       set_state(PART:"effect_bg_clip4", "pressed", 0.0);
+                                                       run_program(PROGRAM:"start_persp4");
+                                                       timer(0.1, "timer0", 4);
+                                               }
+                                       }
+                               }
+                       }
+                       program { name: "unpressed";
+                               signal: "mouse,up,1";
+                               source: "event";
+                               script {
+                                       if (get_int(mouse_down) == 1) {
+                                               set_int(mouse_down, 0);
+                                               run_program(PROGRAM:"button_unpress1");
+                                       }
+                               }
+                       }
+                       program { name: "button_unpress1";
+                               script {
+                                       new st[31];
+                                       new Float:vl;
+                                       get_state(PART:"effect_bg", st, 30, vl);
+                                       if (strcmp(st, "disabled")) {
+                                               set_state(PART:"elm.swallow.content.clip", "default", 0.0);
+                                               emit("elm,action,unpress", "");
+                                               if(get_int(click_cnt) == 0)
+                                                       set_int(click_cnt, 1);
+                                               else if(get_int(click_cnt) == 1)
+                                                       set_int(click_cnt, 2);
+                                               else if(get_int(click_cnt) == 2)
+                                                       set_int(click_cnt, 3);
+                                               else
+                                                       set_int(click_cnt, 0);
+                                       }
+                               }
+                       }
+                       program { name: "touch_snd";
+                               signal: "mouse,clicked,1";
+                               source: "event";
+                               script {
+                                       new st[31];
+                                       new Float:vl;
+                                       if (get_int(multi_down) == 0) {
+                                               get_state(PART:"effect_bg", st, 30, vl);
+                                               if (strcmp(st, "disabled")) {
+                                                       run_program(PROGRAM:"play_sample");
+                                                       emit("elm,action,click", "");
+                                                       set_int(mouse_click, 0);
+                                               }
+                                       }
+                               }
+                       }
+                       program {
+                               name: "play_sample";
+                               action: RUN_PLUGIN "touch_sound";
+                       }
+                       program { name: "disable";
+                               signal: "elm,state,disabled";
+                               source: "elm";
+                               action: STATE_SET "disabled" 0.0;
+                               target: "effect_bg";
+                               target: "elm.swallow.content.clip";
+                       }
+                       program { name: "enable";
+                               signal: "elm,state,enabled";
+                               source: "elm";
+                               action: STATE_SET "default" 0.0;
+                               target: "effect_bg";
+                               target: "elm.swallow.content.clip";
+                       }
+                       program { name: "multi_down";
+                               signal: "elm,action,multi,down";
+                               source: "elm";
+                               script {
+                               set_int(multi_down, 1);
+                               }
+                       }
+                       program { name: "multi_up";
+                               signal: "elm,action,multi,up";
+                               source: "elm";
+                               script {
+                                       set_int(multi_down, 0);
+                               }
+                       }
+                       program { name: "start_persp";
+                               action: STATE_SET "start_persp" 0.0;
+                               transition: CUBIC_BEZIER 0.3 0.45 0.03 0.41 1.0;
+                               target: "effect_bg";
+                       }
+                       program { name: "change_opacity";
+                               action: STATE_SET "default" 0.0;
+                               transition: CUBIC_BEZIER 0.3 0.39 0.575 0.565 1.0;
+                               target: "effect_bg_clip";
+                       }
+                       program { name: "start_persp2";
+                               action: STATE_SET "start_persp" 0.0;
+                               transition: CUBIC_BEZIER 0.3 0.45 0.03 0.41 1.0;
+                               target: "effect_bg2";
+                       }
+                       program { name: "change_opacity2";
+                               action: STATE_SET "default" 0.0;
+                               transition: CUBIC_BEZIER 0.3 0.39 0.575 0.565 1.0;
+                               target: "effect_bg_clip2";
+                       }
+                       program { name: "start_persp3";
+                               action: STATE_SET "start_persp" 0.0;
+                               transition: CUBIC_BEZIER 0.3 0.45 0.03 0.41 1.0;
+                               target: "effect_bg3";
+                       }
+                       program { name: "change_opacity3";
+                               action: STATE_SET "default" 0.0;
+                               transition: CUBIC_BEZIER 0.3 0.39 0.575 0.565 1.0;
+                               target: "effect_bg_clip3";
+                       }
+                       program { name: "start_persp4";
+                               action: STATE_SET "start_persp" 0.0;
+                               transition: CUBIC_BEZIER 0.3 0.45 0.03 0.41 1.0;
+                               target: "effect_bg4";
+                       }
+                       program { name: "change_opacity4";
+                               action: STATE_SET "default" 0.0;
+                               transition: CUBIC_BEZIER 0.3 0.39 0.575 0.565 1.0;
+                               target: "effect_bg_clip4";
+                       }
+               }
+       }
+}
diff --git a/res/edje/drawing_layout.edc b/res/edje/drawing_layout.edc
new file mode 100755 (executable)
index 0000000..19a0064
--- /dev/null
@@ -0,0 +1,216 @@
+
+collections {
+
+#define MSG_VALUE 1
+#define GC_NAME_PADDING_X 33
+#define GC_NAME_PADDING_Y 55
+#define GC_NAME_PADDING_H 47
+base_scale: 1.3;
+       /* Face view */
+
+       group {
+               name: "drawing_group";
+               max: 360 360;
+               min: 360 360;
+               images {
+                       image: "wi_drawing_bg_pattern_negative.png" COMP;
+                       image: "wi_more_option_bg.png" COMP;
+                       image: "wi_drawing_bg_pattern.png" COMP;
+               }
+               parts{
+                       part {
+                               name: "bg";
+                               scale: 1;
+                               type: RECT;
+                               mouse_events: 1;
+                               description {
+                                       state: "default" 0.0;
+                                       color_class: "AO0117";
+                               }
+                       }
+                       part{
+                               name: "top_padding";
+                               scale: 1;
+                               type: SPACER;
+                               mouse_events: 1;
+                               repeat_events: 1;
+                               description {
+                                       state: "default" 0.0;
+                                       rel1 {relative: 0.0 0.0;}
+                                       rel2 {relative: 1.0 0.0;}
+                                       min: 0 5;
+                                       align: 0.5 0.0;
+                                       fixed: 0 1;
+                               }
+                       }
+                       part{
+                               name: "right_padding";
+                               scale: 1;
+                               type: SPACER;
+                               mouse_events: 1;
+                               repeat_events: 1;
+                               description {
+                                       state: "default" 0.0;
+                                       rel1 {relative: 1.0 0.0;}
+                                       rel2 {relative: 1.0 0.0;}
+                                       min: 2 0;
+                                       align: 1.0 0.5;
+                                       fixed: 1 0;
+                               }
+                       }
+                       part{
+                               name: "bottom_padding";
+                               scale: 1;
+                               type: SPACER;
+                               mouse_events: 1;
+                               repeat_events: 1;
+                               description {
+                                       state: "default" 0.0;
+                                       rel1 {relative: 0.0 1.0;}
+                                       rel2 {relative: 1.0 1.0;}
+                                       min: 0 5;
+                                       align: 0.5 1.0;
+                                       fixed: 0 1;
+                               }
+                       }
+
+                       part{
+                               name: "elm.swallow.bottom.bgimage";
+                               type: SWALLOW;
+                               mouse_events: 1;
+                               repeat_events: 1;
+                               description{
+                                       state: "default" 0.0;
+                                       rel1 { relative:0.0 0.0; to:"bg"; }
+                                       rel2 { relative:1.0 1.0; to:"bg"; }
+                               }
+                       }
+                       part {
+                               name: "bg_pattern_image";
+                               scale: 1;
+                               mouse_events: 1;
+                               repeat_events: 1;
+                               type: IMAGE;
+                               description {
+                                       state: "default" 0.0;
+                                       image.normal: "wi_drawing_bg_pattern.png";
+                                       color_class: "AO051";
+                               }
+                               description {
+                                       state: "hide" 0.0;
+                                       image.normal: "wi_more_option_bg.png";
+                                       color: 0 0 0 0;
+                               }
+                       }
+                       part{
+                               name: "drawing_area";
+                               type: SWALLOW;
+                               mouse_events: 1;
+                               repeat_events: 1;
+                               description{
+                                       state: "default" 0.0;
+                                       rel1 { relative:0.0 0.0; to:"bg"; }
+                                       rel2 { relative:1.0 1.0; to:"bg"; }
+                               }
+                       }
+                       part {
+                               name: "bg_pattern_negative_image";
+                               scale: 1;
+                               mouse_events: 1;
+                               repeat_events: 1;
+                               type: IMAGE;
+                               description {
+                                       state: "default" 0.0;
+                                       image.normal: "wi_drawing_bg_pattern_negative.png";
+                                       //color_class: "AO048";
+                               }
+                               description {
+                                       state: "hide" 0.0;
+                                       image.normal: "wi_more_option_bg.png";
+                                       color: 0 0 0 0;
+                               }
+                       }
+                       part{
+                               name: "part_stage";
+                               type: SPACER;
+                               mouse_events: 1;
+                               repeat_events: 1;
+                               description {
+                                       state: "default" 0.0;
+                                       rel1 {relative: 0.0 0.0; }
+                                       rel1.offset: -125 -125;
+                                       rel2 { relative: 1.0 1.0;}
+                                       rel2.offset: 125 125;
+                               }
+                               description{
+                                       state: "shown" 0.0;
+                                       rel1.relative: 0.0 0.0;
+                                       rel1.offset: 0 0;
+                                       rel2.relative: 1.0 1.0;
+                                       rel2.offset: 0 0;
+                               }
+                       }
+
+                       part { name: "button";
+                          type: SWALLOW;
+                          scale: 1;
+                          mouse_events: 1;
+                          repeat_events: 1;
+                          description {
+                               state: "default" 0.0;
+                               min: 90 90;
+                               max: 90 90;
+                               fixed: 1 1;
+                               align: 0.5 0.5;
+                               rel1.to: "bg";
+                               rel1.relative: 0.0 0.0;
+                               rel2.to: "bg";
+                               rel2.relative: 1.0 1.0;
+                          }
+                       }
+               }
+
+               programs{
+                       program {
+                               name: "stage-default";
+                               action: STATE_SET "default" 0.0;
+                               target: "part_stage";
+                       }
+                       program {
+                               name: "hidden-state";
+                               signal: "stage,hide";
+                               source: "";
+                               action: STATE_SET "default" 0.0;
+                               transition: ACCEL 0.5;
+                               target: "part_stage";
+
+                       }
+                       program {
+                               name: "shown-state";
+                               signal: "stage,show";
+                               source: "";
+                               action: STATE_SET "shown" 0.0;
+                               transition: ACCEL 0.5;
+                               target: "part_stage";
+
+                       }
+                       program {
+                               name: "show.pattern.negative.bg";
+                               signal: "pattern,negative,bg,show";
+                               source: "*";
+                               action: STATE_SET "default" 0.0;
+                               target: "bg_pattern_negative_image";
+                       }
+                       program {
+                               name: "hide.pattern.negative.bg";
+                               signal: "pattern,negative,bg,hide";
+                               source: "*";
+                               action: STATE_SET "hide" 0.0;
+                               target: "bg_pattern_negative_image";
+                       }
+               } //programs
+       }
+}
+
+
+
diff --git a/res/edje/drawing_popup.edc b/res/edje/drawing_popup.edc
new file mode 100755 (executable)
index 0000000..74774b1
--- /dev/null
@@ -0,0 +1,153 @@
+
+#define BG_COLOR       0 0 0 255
+
+#define POPUP_2BUTTON_LEFT_RIGHT_PADDING_WIDTH_INC 68
+#define POPUP_TOP_PADDING_HEIGHT_INC               60
+#define POPUP_TOP_PADDING_NOTITLE_HEIGHT_INC       76
+#define POPUP_BOTTOM_PADDING_HEIGHT_INC            100
+#define POPUP_IMAGE_WIDTH_INC                   224
+#define POPUP_IMAGE_HEIGHT_INC                  100
+#define POPUP_IMAGE_BOTTOM_PADDING_HEIGHT_INC      5
+#define POPUP_CONNECTING_IMAGE_BOTTOM_PADDING_HEIGHT_INC      32
+#define POPUP_TITLE_BOTTOM_PADDING_HEIGHT_INC      8
+#define POPUP_BASE_DEFAULT_MIN_INC             360 360
+#define POPUP_TITLE_TEXT_SIZE_INC              30
+#define POPUP_BODY_TEXT_SIZE_INC               34
+
+#define POPUP_NO_BUTTON_LEFT_RIGHT_PADDING_WIDTH_INC 33
+#define POPUP_NO_BUTTON_BOTTOM_PADDING_HEIGHT_INC 95
+#define POPUP_NO_BUTTON_IMG_BOTTOM_PADDING_HEIGHT_INC 169
+
+collections {
+base_scale: 1.3;
+
+#define PART(TYPE, NAME, DESCRIPION) \
+       part {  \
+               name: NAME; \
+               scale: 1; \
+               type: TYPE; \
+               DESCRIPION \
+       }
+
+
+#define NOBUTTON_BUTTONS2_PROGRAM(program_name, signal_name) \
+       program {  \
+               name: program_name; \
+               signal: signal_name; \
+               source: ""; \
+               script { \
+                       set_state(PART:"top.left.padding", "default", 0.0); \
+                       emit("size,eval", "elm"); \
+               } \
+       } \
+
+       group {
+               name: "close_popup";
+               styles{
+                       style {
+                               name: "popup_title_style";
+                               base: "font=Tizen:style=Bold font_size="POPUP_TITLE_TEXT_SIZE_INC" color=#FFFFFF color_class=T091 align=center ellipsis=1.0 text_class=T091";
+                       }
+                       style {
+                               name: "popup_body_default_font_style";
+                               base: "font=Tizen:style=Regular font_size="POPUP_BODY_TEXT_SIZE_INC" color=#FFFFFF color_class=T092 align=center wrap=mixed text_class=T092";
+                       }
+               }
+
+               limits {
+                       vertical: "content_area" "360";
+               }
+               parts {
+                       part {
+                               name: "bg";
+                               type: SPACER;
+                               scale: 1;
+                               description {
+                                       state: "default" 0.0;
+                                       min: POPUP_BASE_DEFAULT_MIN_INC;
+                               }
+                       }
+                       part {
+                               name: "top.left.padding";
+                               type: SPACER;
+                               scale: 1;
+                               description {
+                                       state: "default" 0.0;
+                                       min: POPUP_2BUTTON_LEFT_RIGHT_PADDING_WIDTH_INC POPUP_TOP_PADDING_NOTITLE_HEIGHT_INC;
+                                       rel1.to: "bg";
+                                       rel2 {
+                                               to: "bg";
+                                               relative: 0.0 0.0;
+                                       }
+                                       align: 0.0 0.0;
+                                       fixed: 1 1;
+                               }
+                       }
+
+                       part {
+                               name: "bottom.right.content.padding";
+                               type: SPACER;
+                               scale: 1;
+                               description {
+                                       state: "default" 0.0;
+                                       min: POPUP_2BUTTON_LEFT_RIGHT_PADDING_WIDTH_INC POPUP_TOP_PADDING_NOTITLE_HEIGHT_INC;
+                                       rel1 {
+                                               to: "bg";
+                                               relative: 1.0 1.0;
+                                       }
+                                       rel2.to: "bg";
+                                       align: 1.0 1.0;
+                                       fixed: 1 1;
+                               }
+                               description {
+                                       state: "center_align" 0.0;
+                                       inherit: "default" 0.0;
+                                       min: POPUP_2BUTTON_LEFT_RIGHT_PADDING_WIDTH_INC POPUP_TOP_PADDING_NOTITLE_HEIGHT_INC;
+                               }
+                       }
+
+                       part {
+                               name: "bottom.right.padding";
+                               type: SPACER;
+                               scale: 1;
+                               description {
+                                       state: "default" 0.0;
+                                       min: POPUP_2BUTTON_LEFT_RIGHT_PADDING_WIDTH_INC POPUP_TOP_PADDING_NOTITLE_HEIGHT_INC;
+                                       rel1 {
+                                       to: "bg";
+                                       relative: 1.0 1.0;
+                                       }
+                                       rel2.to: "bg";
+                                       align: 1.0 1.0;
+                                       fixed: 1 1;
+                               }
+                       }
+
+                       part { name: "discard.text.content";
+                               type: TEXTBLOCK;
+                               scale: 1;
+                               description {
+                                       state: "default" 0.0;
+                                       rel1 {
+                                               to: "top.left.padding";
+                                               relative: 1.0 1.0;
+                                       }
+                                       rel2 {
+                                               to: "bottom.right.padding";
+                                               relative: 0.0 0.0;
+                                       }
+                                       text {
+                                               align: 0.5 0.5;
+                                               style: "popup_body_default_font_style";
+                                               min: 0 1;
+                                       }
+                               }
+                       }
+               }
+               programs {
+                       NOBUTTON_BUTTONS2_PROGRAM("show", "show");
+                       NOBUTTON_BUTTONS2_PROGRAM("content_area,over", "limit,content_area,over");
+                       NOBUTTON_BUTTONS2_PROGRAM("content_area,below", "limit,content_area,below");
+               }
+       }
+}
diff --git a/res/edje/drawing_stroke.edc b/res/edje/drawing_stroke.edc
new file mode 100755 (executable)
index 0000000..a6456ec
--- /dev/null
@@ -0,0 +1,205 @@
+
+/* Circle display */
+group { name: "drawing/stroke_layout/circle";
+       styles{
+               style { name: "circle_title_style";
+                       base: "font=Tizen:style=Light font_size="28" align=center color=""#FFFFFF"" color_class=ATO032 text_class=ATO032";
+                       tag:  "br" "\n";
+                       tag:  "hilight" "+ font_weight=Bold";
+                       tag:  "b" "+ font_weight=Bold";
+                       tag:  "tab" "\t";
+               }
+               style { name: "circle_level_style2";
+                       base: "font=Tizen:style=Regular font_size="40" align=center color=""#FFFFFF"" color_class=ATO032 text_class=ATO032";
+                       tag:  "br" "\n";
+                       tag:  "hilight" "+ font_weight=Bold";
+                       tag:  "b" "+ font_weight=Bold";
+                       tag:  "tab" "\t";
+               }
+               style { name: "circle_level_dim_style";
+                       base: "font=Tizen:style=Regular font_size="40" align=center color=""#808080"" text_class=ATO032";
+                       tag:  "br" "\n";
+                       tag:  "hilight" "+ font_weight=Bold";
+                       tag:  "b" "+ font_weight=Bold";
+                       tag:  "tab" "\t";
+               }
+               style { name: "circle_outdoor_style";
+                       base: "font=Tizen:style=Regular font_size="28" align=center color=""#FFFFFF"" color_class=ATO032 text_class=ATO032";
+                       tag:  "br" "\n";
+                       tag:  "hilight" "+ font_weight=Bold";
+                       tag:  "b" "+ font_weight=Bold";
+                       tag:  "tab" "\t";
+               }
+       }
+
+       parts {
+               part { name: "bg";
+                       type: RECT;
+                       scale: 1;
+                       description { state: "default";
+                               rel1 { relative: 0.0 0.0; }
+                               rel2 { relative: 1.0 1.0; }
+                               color: 0 0 0 0;
+                       }
+               }
+               part { name: "top_padding";
+                       type: SPACER;
+                       scale: 1;
+                       description { state: "default" 0.0;
+                               min: 0 5;
+                               max: -1 5;
+                               fixed: 0 1;
+                               align: 0.5 0.0;
+                               rel2.relative: 1.0 0.0;
+                       }
+               }
+               part { name: "bottom_padding";
+                       type: SPACER;
+                       scale: 1;
+                       description { state: "default" 0.0;
+                               min: 0 28;
+                               max: -1 28;
+                               fixed: 0 1;
+                               align: 0.5 1.0;
+                               rel1.relative: 0.0 1.0;
+                       }
+               }
+               part { name: "left_padding";
+                       type: SPACER;
+                       scale: 1;
+                       description { state: "default" 0.0;
+                               min: 13 0;
+                               max: 13 -1;
+                               fixed: 1 0;
+                               align: 0.0 0.5;
+                               rel2.relative: 0.0 1.0;
+                       }
+               }
+               part { name: "right_padding";
+                       type: SPACER;
+                       scale: 1;
+                       description { state: "default" 0.0;
+                               min: 13 0;
+                               max: 13 -1;
+                               fixed: 1 0;
+                               align: 1.0 0.5;
+                               rel1.relative: 1.0 0.0;
+                       }
+               }
+               part { name: "elm.swallow.content";
+              type: SWALLOW;
+              scale: 1;
+              description { state: "default" 0.0;}
+               }
+               part { name: "elm.text.title";
+                       type: TEXTBLOCK;
+                       scale: 1;
+                       description { state: "default" 0.0;
+                               min: 334 74;
+                               max: -1 74;
+                               align: 0.5 0.0;
+                               rel1 {
+                                       to_x: "left_padding";
+                                       to_y: "left_padding";
+                                       relative: 1 0.5;
+                               }
+                               rel2 {
+                                       to_x: "right_padding";
+                                       to_y: "right_padding";
+                                       relative: 0 0.5;
+                               }
+                               text {
+                                       style: "circle_title_style";
+                                       align: 0.5 0.5;
+                                       min: 1 1;
+                               }
+                       }
+                       description { state: "outdoor" 0.0;
+                               inherit: "default" 0.0;
+                               text {
+                                       style: "circle_title_style";
+                                       align: 0.5 0.0;
+                               }
+                       }
+               }
+               part { name: "elm.text";
+                       type: TEXTBLOCK;
+                       scale: 1;
+                       mouse_events: 0;
+                       description { state: "default" 0.0;
+                               min: 70 52;
+                               max: 70 52;
+                               align: 0.5 1.0;
+                               visible: 1;
+                               rel1 {
+                                to_y: "bg";
+                                relative: 0.5 0.5;
+                               }
+                               rel2 {
+                                to_y: "bg";
+                                relative: 0.5 0.5;
+                               }
+                               text {
+                                style: "circle_level_style2";
+                                //min: 0 1;
+                                align: 0.5 0.5;
+                               }
+                       }
+                       description { state: "outdoor" 0.0;
+                               inherit: "default" 0.0;
+                               text {
+                                       style: "circle_level_dim_style";
+                                       align: 0.5 0.5;
+                               }
+                       }
+               }
+
+               part { name: "btn.minus";
+                       type: SWALLOW;
+                       scale: 1;
+                       description { state: "default" 0.0;
+                       min: 64 64;
+                       max: 64 64;
+                       align: 1.0 0.5;
+                       rel1 {
+                               relative: 0.0 0.0;
+                               to: "elm.text";
+                       }
+                       rel2 {
+                               relative: 0.0 1.0;
+                               to: "elm.text";
+                       }
+                       }
+               }
+
+               part { name: "btn.plus";
+                       type: SWALLOW;
+                       scale: 1;
+                       description { state: "default" 0.0;
+                       min: 64 64;
+                       max: 64 64;
+                       align: 0.0 0.5;
+                       rel1 {
+                               relative: 1.0 0.0;
+                               to: "elm.text";
+                       }
+                       rel2 {
+                               relative: 1.0 1.0;
+                               to: "elm.text";
+                       }
+                       }
+               }
+
+               programs {
+
+                       program {
+                               signal: "elm,state,normal";
+                               source: "*";
+                               action: STATE_SET "default" 0.0;
+                               target: "elm.text.title";
+                               target: "elm.text";
+                       }
+               }
+       }
+}
+
diff --git a/res/images/b_ic_press_full_circle_bg_a.png b/res/images/b_ic_press_full_circle_bg_a.png
new file mode 100755 (executable)
index 0000000..2208b46
Binary files /dev/null and b/res/images/b_ic_press_full_circle_bg_a.png differ
diff --git a/res/images/b_more_option_icon_bg.png b/res/images/b_more_option_icon_bg.png
new file mode 100755 (executable)
index 0000000..4eefe05
Binary files /dev/null and b/res/images/b_more_option_icon_bg.png differ
diff --git a/res/images/b_more_option_icon_select_bg.png b/res/images/b_more_option_icon_select_bg.png
new file mode 100755 (executable)
index 0000000..e59f3c9
Binary files /dev/null and b/res/images/b_more_option_icon_select_bg.png differ
diff --git a/res/images/b_slider_icon_minus.png b/res/images/b_slider_icon_minus.png
new file mode 100755 (executable)
index 0000000..35affbe
Binary files /dev/null and b/res/images/b_slider_icon_minus.png differ
diff --git a/res/images/b_slider_icon_plus.png b/res/images/b_slider_icon_plus.png
new file mode 100755 (executable)
index 0000000..63e81d4
Binary files /dev/null and b/res/images/b_slider_icon_plus.png differ
diff --git a/res/images/drawing_popup_btn_check.png b/res/images/drawing_popup_btn_check.png
new file mode 100755 (executable)
index 0000000..3dce121
Binary files /dev/null and b/res/images/drawing_popup_btn_check.png differ
diff --git a/res/images/drawing_popup_btn_delete.png b/res/images/drawing_popup_btn_delete.png
new file mode 100755 (executable)
index 0000000..58de36c
Binary files /dev/null and b/res/images/drawing_popup_btn_delete.png differ
diff --git a/res/images/wear_comm_stroke_option.png b/res/images/wear_comm_stroke_option.png
new file mode 100755 (executable)
index 0000000..f071d0b
Binary files /dev/null and b/res/images/wear_comm_stroke_option.png differ
diff --git a/res/images/wi_drawing_bg_01.png b/res/images/wi_drawing_bg_01.png
new file mode 100755 (executable)
index 0000000..c1cfc2c
Binary files /dev/null and b/res/images/wi_drawing_bg_01.png differ
diff --git a/res/images/wi_drawing_bg_02.png b/res/images/wi_drawing_bg_02.png
new file mode 100755 (executable)
index 0000000..0470f95
Binary files /dev/null and b/res/images/wi_drawing_bg_02.png differ
diff --git a/res/images/wi_drawing_bg_03.png b/res/images/wi_drawing_bg_03.png
new file mode 100755 (executable)
index 0000000..6b94347
Binary files /dev/null and b/res/images/wi_drawing_bg_03.png differ
diff --git a/res/images/wi_drawing_bg_04.png b/res/images/wi_drawing_bg_04.png
new file mode 100755 (executable)
index 0000000..2a3cefb
Binary files /dev/null and b/res/images/wi_drawing_bg_04.png differ
diff --git a/res/images/wi_drawing_bg_pattern.png b/res/images/wi_drawing_bg_pattern.png
new file mode 100755 (executable)
index 0000000..84ac326
Binary files /dev/null and b/res/images/wi_drawing_bg_pattern.png differ
diff --git a/res/images/wi_drawing_bg_pattern_negative.png b/res/images/wi_drawing_bg_pattern_negative.png
new file mode 100644 (file)
index 0000000..200d8d3
Binary files /dev/null and b/res/images/wi_drawing_bg_pattern_negative.png differ
diff --git a/res/images/wi_drawing_more_options_erase.png b/res/images/wi_drawing_more_options_erase.png
new file mode 100755 (executable)
index 0000000..4a81070
Binary files /dev/null and b/res/images/wi_drawing_more_options_erase.png differ
diff --git a/res/images/wi_drawing_more_options_icon.png b/res/images/wi_drawing_more_options_icon.png
new file mode 100755 (executable)
index 0000000..05f7f67
Binary files /dev/null and b/res/images/wi_drawing_more_options_icon.png differ
diff --git a/res/images/wi_drawing_select_button_center.png b/res/images/wi_drawing_select_button_center.png
new file mode 100755 (executable)
index 0000000..d644411
Binary files /dev/null and b/res/images/wi_drawing_select_button_center.png differ
diff --git a/res/po/ar.po b/res/po/ar.po
new file mode 100755 (executable)
index 0000000..5543730
--- /dev/null
@@ -0,0 +1,33 @@
+msgid "WDS_IME_ACBUTTON_SEND"
+msgstr "إرسال"
+
+msgid "WDS_WNOTI_POP_ALL_CHANGES_WILL_BE_DISCARDED"
+msgstr "سيتم تجاهل كلّ التغييرات."
+
+msgid "WDS_IME_NPBODY_START_DRAWING_M_EMOTICON_ABB"
+msgstr "البدء الرسم"
+
+msgid "WDS_MSG_SBODY_MMS_ABB"
+msgstr "رسالة وسائط متعددة"
+
+msgid "WDS_IME_NPBODY_DRAW_YOUR_OWN_MESSAGE_ABB"
+msgstr "ارسم رسالتك الخاصة"
+
+msgid "WDS_TTRL_BODY_TURN_THE_BEZEL_ANTICLOCKWISE_TO_UNDO_A_DOODLE_ABB"
+msgstr "قم بتدوير الإطار بعكس اتجاه عقارب الساعة للتراجع عن الخربشة."
+
+msgid "WDS_TTRL_HEADER_TIPS_ABB"
+msgstr "تلميحات"
+
+msgid "WDS_TTRL_BODY_AND_CLOCKWISE_TO_BRING_YOUR_DOODLE_BACK_ABB"
+msgstr "وباتجاه عقارب الساعة لإرجاع خربشتك."
+
+msgid "WDS_IME_NPBODY_START_DOODLING_YOUR_MESSAGE_ABB"
+msgstr "ابدأ بخربشة رسالتك"
+
+msgid "WDS_IME_POP_ARE_YOU_SURE_YOU_WANT_TO_DISCARD_YOUR_DRAWING_Q"
+msgstr "هل أنت متأكد من أنك تريد تجاهل رسمك؟"
+
+msgid "WDS_IME_NPBODY_START_DRAWING_YOUR_IMAGE_ABB"
+msgstr "بدء رسم صورتك"
+
diff --git a/res/po/as.po b/res/po/as.po
new file mode 100755 (executable)
index 0000000..99c5e7d
--- /dev/null
@@ -0,0 +1,33 @@
+msgid "WDS_IME_ACBUTTON_SEND"
+msgstr "প্ৰেৰণ কৰক"
+
+msgid "WDS_WNOTI_POP_ALL_CHANGES_WILL_BE_DISCARDED"
+msgstr "সকলো পৰিৱৰ্তন পৰিত্যাগ কৰা হ'ব৷"
+
+msgid "WDS_IME_NPBODY_START_DRAWING_M_EMOTICON_ABB"
+msgstr "আঁকিবলৈ আৰম্ভ কৰক"
+
+msgid "WDS_MSG_SBODY_MMS_ABB"
+msgstr "MMS"
+
+msgid "WDS_IME_NPBODY_DRAW_YOUR_OWN_MESSAGE_ABB"
+msgstr "আপোনাৰ নিজৰ মেচেজ আঁকক"
+
+msgid "WDS_TTRL_BODY_TURN_THE_BEZEL_ANTICLOCKWISE_TO_UNDO_A_DOODLE_ABB"
+msgstr "এটা ডুডল পূৰ্বৰ দৰে কৰিবলৈ বেজেল ঘড়ীৰ বিপৰীতে ঘূৰাওক।"
+
+msgid "WDS_TTRL_HEADER_TIPS_ABB"
+msgstr "আভাস"
+
+msgid "WDS_TTRL_BODY_AND_CLOCKWISE_TO_BRING_YOUR_DOODLE_BACK_ABB"
+msgstr "আৰু আপোনাৰ ডুডল পুনৰ ঘূৰাই আনিবলৈ ঘড়ীৰ অনুসৰি ঘূৰাওক।"
+
+msgid "WDS_IME_NPBODY_START_DOODLING_YOUR_MESSAGE_ABB"
+msgstr "আপোনাৰ মেচেজ ডুডল কৰাটো আৰম্ভ কৰক"
+
+msgid "WDS_IME_POP_ARE_YOU_SURE_YOU_WANT_TO_DISCARD_YOUR_DRAWING_Q"
+msgstr "আপুনি আপোনাৰ অংকন পৰিত্যাগ কৰিব বিচৰাটো নিশ্চিতনে?"
+
+msgid "WDS_IME_NPBODY_START_DRAWING_YOUR_IMAGE_ABB"
+msgstr "আপোনাৰ প্ৰতিচ্ছবিৰ অংকন আৰম্ভ কৰক"
+
diff --git a/res/po/az.po b/res/po/az.po
new file mode 100755 (executable)
index 0000000..09969ee
--- /dev/null
@@ -0,0 +1,33 @@
+msgid "WDS_IME_ACBUTTON_SEND"
+msgstr "GÖNDƏR"
+
+msgid "WDS_WNOTI_POP_ALL_CHANGES_WILL_BE_DISCARDED"
+msgstr "Bütün dəyişikliklər silinəcək."
+
+msgid "WDS_IME_NPBODY_START_DRAWING_M_EMOTICON_ABB"
+msgstr "Çəkməyə başla"
+
+msgid "WDS_MSG_SBODY_MMS_ABB"
+msgstr "MMS"
+
+msgid "WDS_IME_NPBODY_DRAW_YOUR_OWN_MESSAGE_ABB"
+msgstr "Öz mesajını çək"
+
+msgid "WDS_TTRL_BODY_TURN_THE_BEZEL_ANTICLOCKWISE_TO_UNDO_A_DOODLE_ABB"
+msgstr "Qaralamanı sil üçün pan saat ərqəb əksinə çevir."
+
+msgid "WDS_TTRL_HEADER_TIPS_ABB"
+msgstr "Məsləhətlər"
+
+msgid "WDS_TTRL_BODY_AND_CLOCKWISE_TO_BRING_YOUR_DOODLE_BACK_ABB"
+msgstr "Və qaralamanı geri gətir üçün saat əqrəbi istiqam."
+
+msgid "WDS_IME_NPBODY_START_DOODLING_YOUR_MESSAGE_ABB"
+msgstr "Mesaj yazmağa başla"
+
+msgid "WDS_IME_POP_ARE_YOU_SURE_YOU_WANT_TO_DISCARD_YOUR_DRAWING_Q"
+msgstr "Çəkdiyinizi silmək istədiyinizə əminsiniz?"
+
+msgid "WDS_IME_NPBODY_START_DRAWING_YOUR_IMAGE_ABB"
+msgstr "Şəklinizi çəkməyə başlayın"
+
diff --git a/res/po/be_BY.po b/res/po/be_BY.po
new file mode 100755 (executable)
index 0000000..c8a43a0
--- /dev/null
@@ -0,0 +1,33 @@
+msgid "WDS_IME_ACBUTTON_SEND"
+msgstr "АДПРАВІЦЬ"
+
+msgid "WDS_WNOTI_POP_ALL_CHANGES_WILL_BE_DISCARDED"
+msgstr "Усе змены будуць скасаваны."
+
+msgid "WDS_IME_NPBODY_START_DRAWING_M_EMOTICON_ABB"
+msgstr "Пачаць маляваць"
+
+msgid "WDS_MSG_SBODY_MMS_ABB"
+msgstr "MMS"
+
+msgid "WDS_IME_NPBODY_DRAW_YOUR_OWN_MESSAGE_ABB"
+msgstr "Намалюйце сваё ўласнае паведамленне"
+
+msgid "WDS_TTRL_BODY_TURN_THE_BEZEL_ANTICLOCKWISE_TO_UNDO_A_DOODLE_ABB"
+msgstr "Каб адмяніць мал., павярн. шкалу супр. гадз. стр."
+
+msgid "WDS_TTRL_HEADER_TIPS_ABB"
+msgstr "Падказкі"
+
+msgid "WDS_TTRL_BODY_AND_CLOCKWISE_TO_BRING_YOUR_DOODLE_BACK_ABB"
+msgstr "І па гадзіннікавай стрэлцы, каб вярнуць малюнак."
+
+msgid "WDS_IME_NPBODY_START_DOODLING_YOUR_MESSAGE_ABB"
+msgstr "Пачніце маляваць сваё паведамленне"
+
+msgid "WDS_IME_POP_ARE_YOU_SURE_YOU_WANT_TO_DISCARD_YOUR_DRAWING_Q"
+msgstr "Вы ўпэўнены, што хочаце скасаваць малюнак?"
+
+msgid "WDS_IME_NPBODY_START_DRAWING_YOUR_IMAGE_ABB"
+msgstr "Пачніце маляваць выяву"
+
diff --git a/res/po/bg.po b/res/po/bg.po
new file mode 100755 (executable)
index 0000000..d03526f
--- /dev/null
@@ -0,0 +1,33 @@
+msgid "WDS_IME_ACBUTTON_SEND"
+msgstr "ИЗПРАЩАНЕ"
+
+msgid "WDS_WNOTI_POP_ALL_CHANGES_WILL_BE_DISCARDED"
+msgstr "Всички промени ще бъдат отхвърлени."
+
+msgid "WDS_IME_NPBODY_START_DRAWING_M_EMOTICON_ABB"
+msgstr "Старт рисуване"
+
+msgid "WDS_MSG_SBODY_MMS_ABB"
+msgstr "MMS"
+
+msgid "WDS_IME_NPBODY_DRAW_YOUR_OWN_MESSAGE_ABB"
+msgstr "Начертайте собствено съобщение"
+
+msgid "WDS_TTRL_BODY_TURN_THE_BEZEL_ANTICLOCKWISE_TO_UNDO_A_DOODLE_ABB"
+msgstr "Завъртете безела обратно на ч. с. за отм. на драс."
+
+msgid "WDS_TTRL_HEADER_TIPS_ABB"
+msgstr "Съвети"
+
+msgid "WDS_TTRL_BODY_AND_CLOCKWISE_TO_BRING_YOUR_DOODLE_BACK_ABB"
+msgstr "И по посока на ч. с., за да върнете драскулката."
+
+msgid "WDS_IME_NPBODY_START_DOODLING_YOUR_MESSAGE_ABB"
+msgstr "Започнете да пишете съобщението"
+
+msgid "WDS_IME_POP_ARE_YOU_SURE_YOU_WANT_TO_DISCARD_YOUR_DRAWING_Q"
+msgstr "Наистина ли искате да премахнете тази рисунка?"
+
+msgid "WDS_IME_NPBODY_START_DRAWING_YOUR_IMAGE_ABB"
+msgstr "Започнете да рисувате изображението"
+
diff --git a/res/po/bn.po b/res/po/bn.po
new file mode 100755 (executable)
index 0000000..3dd1f9c
--- /dev/null
@@ -0,0 +1,33 @@
+msgid "WDS_IME_ACBUTTON_SEND"
+msgstr "পাঠান"
+
+msgid "WDS_WNOTI_POP_ALL_CHANGES_WILL_BE_DISCARDED"
+msgstr "সমস্ত পরিবর্তন পরিত্যাগ করা হবে।"
+
+msgid "WDS_IME_NPBODY_START_DRAWING_M_EMOTICON_ABB"
+msgstr "অঙ্কন শুরু করুন"
+
+msgid "WDS_MSG_SBODY_MMS_ABB"
+msgstr "MMS"
+
+msgid "WDS_IME_NPBODY_DRAW_YOUR_OWN_MESSAGE_ABB"
+msgstr "আপনার নিজের বার্তাটি আঁকুন"
+
+msgid "WDS_TTRL_BODY_TURN_THE_BEZEL_ANTICLOCKWISE_TO_UNDO_A_DOODLE_ABB"
+msgstr "ডুডল আনডু করতে বেজেলটি ঘড়ির কাঁটার বিপরীতে ঘোরান।"
+
+msgid "WDS_TTRL_HEADER_TIPS_ABB"
+msgstr "টিপস"
+
+msgid "WDS_TTRL_BODY_AND_CLOCKWISE_TO_BRING_YOUR_DOODLE_BACK_ABB"
+msgstr "এবং আপনার ডুডল ফিরিয়ে আনতে ঘড়ির কাঁটার ডানদিকে।"
+
+msgid "WDS_IME_NPBODY_START_DOODLING_YOUR_MESSAGE_ABB"
+msgstr "আপনার বার্তাটি ডুডল করা শুরু করুন"
+
+msgid "WDS_IME_POP_ARE_YOU_SURE_YOU_WANT_TO_DISCARD_YOUR_DRAWING_Q"
+msgstr "আপনার আঁকা যে আপনি প্রত্যাখ্যান করতে চান তা আপনি নিশ্চিত?"
+
+msgid "WDS_IME_NPBODY_START_DRAWING_YOUR_IMAGE_ABB"
+msgstr "আপনার চিত্র আঁকতে শুরু করুন"
+
diff --git a/res/po/bn_BD.po b/res/po/bn_BD.po
new file mode 100755 (executable)
index 0000000..06b5d86
--- /dev/null
@@ -0,0 +1,33 @@
+msgid "WDS_IME_ACBUTTON_SEND"
+msgstr "পাঠান"
+
+msgid "WDS_WNOTI_POP_ALL_CHANGES_WILL_BE_DISCARDED"
+msgstr "সব পরিবর্তন পরিত্যাগ করা হবে।"
+
+msgid "WDS_IME_NPBODY_START_DRAWING_M_EMOTICON_ABB"
+msgstr "আঁকা শুরু করুন"
+
+msgid "WDS_MSG_SBODY_MMS_ABB"
+msgstr "এমএমএস"
+
+msgid "WDS_IME_NPBODY_DRAW_YOUR_OWN_MESSAGE_ABB"
+msgstr "আপনার নিজস্ব মেসেজ আঁকুন"
+
+msgid "WDS_TTRL_BODY_TURN_THE_BEZEL_ANTICLOCKWISE_TO_UNDO_A_DOODLE_ABB"
+msgstr "ডুডল পূর্বাবস্থায় নিতে ফ্রেমটি ঘড়ির কাঁটার বিপরীত দিকে ঘোরান৷"
+
+msgid "WDS_TTRL_HEADER_TIPS_ABB"
+msgstr "পরামর্শ"
+
+msgid "WDS_TTRL_BODY_AND_CLOCKWISE_TO_BRING_YOUR_DOODLE_BACK_ABB"
+msgstr "এবং আপনার ডুডল ফিরিয়ে আনতে ঘড়ির কাঁটার দিকে৷"
+
+msgid "WDS_IME_NPBODY_START_DOODLING_YOUR_MESSAGE_ABB"
+msgstr "আপনার মেসেজ ডুডল করা শুরু করুন"
+
+msgid "WDS_IME_POP_ARE_YOU_SURE_YOU_WANT_TO_DISCARD_YOUR_DRAWING_Q"
+msgstr "আপনি কি নিশ্চিত যে আপনি আপনার ড্রয়িংগুলো মুছে ফেলতে চান?"
+
+msgid "WDS_IME_NPBODY_START_DRAWING_YOUR_IMAGE_ABB"
+msgstr "আপনার ছবি আঁকা শুরু করুন"
+
diff --git a/res/po/bs_BA.po b/res/po/bs_BA.po
new file mode 100755 (executable)
index 0000000..8be067a
--- /dev/null
@@ -0,0 +1,33 @@
+msgid "WDS_IME_ACBUTTON_SEND"
+msgstr "POŠALJI"
+
+msgid "WDS_WNOTI_POP_ALL_CHANGES_WILL_BE_DISCARDED"
+msgstr "All changes will be discarded."
+
+msgid "WDS_IME_NPBODY_START_DRAWING_M_EMOTICON_ABB"
+msgstr "Počni crtati"
+
+msgid "WDS_MSG_SBODY_MMS_ABB"
+msgstr "MMS"
+
+msgid "WDS_IME_NPBODY_DRAW_YOUR_OWN_MESSAGE_ABB"
+msgstr "Nacrtajte vlastitu poruku"
+
+msgid "WDS_TTRL_BODY_TURN_THE_BEZEL_ANTICLOCKWISE_TO_UNDO_A_DOODLE_ABB"
+msgstr "Okr. okv. u sup. smj. od kaz. na s. za vrać. pisk."
+
+msgid "WDS_TTRL_HEADER_TIPS_ABB"
+msgstr "Savjeti"
+
+msgid "WDS_TTRL_BODY_AND_CLOCKWISE_TO_BRING_YOUR_DOODLE_BACK_ABB"
+msgstr "I u smjeru kaz. na satu za povratak piskaranja."
+
+msgid "WDS_IME_NPBODY_START_DOODLING_YOUR_MESSAGE_ABB"
+msgstr "Započnite piskaranje poruke"
+
+msgid "WDS_IME_POP_ARE_YOU_SURE_YOU_WANT_TO_DISCARD_YOUR_DRAWING_Q"
+msgstr "Sigurni ste da želite odbaciti svoj crtež?"
+
+msgid "WDS_IME_NPBODY_START_DRAWING_YOUR_IMAGE_ABB"
+msgstr "Započnite crtanje slike"
+
diff --git a/res/po/ca.po b/res/po/ca.po
new file mode 100755 (executable)
index 0000000..cacda04
--- /dev/null
@@ -0,0 +1,33 @@
+msgid "WDS_IME_ACBUTTON_SEND"
+msgstr "ENVIAR"
+
+msgid "WDS_WNOTI_POP_ALL_CHANGES_WILL_BE_DISCARDED"
+msgstr "Es descartaran tots els canvis."
+
+msgid "WDS_IME_NPBODY_START_DRAWING_M_EMOTICON_ABB"
+msgstr "Començar dibuix"
+
+msgid "WDS_MSG_SBODY_MMS_ABB"
+msgstr "MMS"
+
+msgid "WDS_IME_NPBODY_DRAW_YOUR_OWN_MESSAGE_ABB"
+msgstr "Dibuixi el seu propi missatge"
+
+msgid "WDS_TTRL_BODY_TURN_THE_BEZEL_ANTICLOCKWISE_TO_UNDO_A_DOODLE_ABB"
+msgstr "Giri el bisell a l'esquerra per desfer el gargot."
+
+msgid "WDS_TTRL_HEADER_TIPS_ABB"
+msgstr "Consells"
+
+msgid "WDS_TTRL_BODY_AND_CLOCKWISE_TO_BRING_YOUR_DOODLE_BACK_ABB"
+msgstr "I a la dreta per tornar a refer el gargot."
+
+msgid "WDS_IME_NPBODY_START_DOODLING_YOUR_MESSAGE_ABB"
+msgstr "Començar a fer gargots al missatge"
+
+msgid "WDS_IME_POP_ARE_YOU_SURE_YOU_WANT_TO_DISCARD_YOUR_DRAWING_Q"
+msgstr "Està segur que vol descartar el dibuix?"
+
+msgid "WDS_IME_NPBODY_START_DRAWING_YOUR_IMAGE_ABB"
+msgstr "Començar a dibuixar la imatge"
+
diff --git a/res/po/cs.po b/res/po/cs.po
new file mode 100755 (executable)
index 0000000..084e23e
--- /dev/null
@@ -0,0 +1,33 @@
+msgid "WDS_IME_ACBUTTON_SEND"
+msgstr "ODESLAT"
+
+msgid "WDS_WNOTI_POP_ALL_CHANGES_WILL_BE_DISCARDED"
+msgstr "Všechny změny budou zrušeny."
+
+msgid "WDS_IME_NPBODY_START_DRAWING_M_EMOTICON_ABB"
+msgstr "Začněte kreslit"
+
+msgid "WDS_MSG_SBODY_MMS_ABB"
+msgstr "MMS"
+
+msgid "WDS_IME_NPBODY_DRAW_YOUR_OWN_MESSAGE_ABB"
+msgstr "Nakreslete zprávu"
+
+msgid "WDS_TTRL_BODY_TURN_THE_BEZEL_ANTICLOCKWISE_TO_UNDO_A_DOODLE_ABB"
+msgstr "Otočením rámečku doleva zrušíte kresbu."
+
+msgid "WDS_TTRL_HEADER_TIPS_ABB"
+msgstr "Tipy"
+
+msgid "WDS_TTRL_BODY_AND_CLOCKWISE_TO_BRING_YOUR_DOODLE_BACK_ABB"
+msgstr "A směrem doleva vrátíte kresbu zpět."
+
+msgid "WDS_IME_NPBODY_START_DOODLING_YOUR_MESSAGE_ABB"
+msgstr "Začněte kreslit zprávu"
+
+msgid "WDS_IME_POP_ARE_YOU_SURE_YOU_WANT_TO_DISCARD_YOUR_DRAWING_Q"
+msgstr "Opravdu chcete svou kresbu?"
+
+msgid "WDS_IME_NPBODY_START_DRAWING_YOUR_IMAGE_ABB"
+msgstr "Začněte kreslit obrázek"
+
diff --git a/res/po/da.po b/res/po/da.po
new file mode 100755 (executable)
index 0000000..e1e6878
--- /dev/null
@@ -0,0 +1,33 @@
+msgid "WDS_IME_ACBUTTON_SEND"
+msgstr "SEND"
+
+msgid "WDS_WNOTI_POP_ALL_CHANGES_WILL_BE_DISCARDED"
+msgstr "Alle ændringer bliver kasseret."
+
+msgid "WDS_IME_NPBODY_START_DRAWING_M_EMOTICON_ABB"
+msgstr "Begynd at tegne"
+
+msgid "WDS_MSG_SBODY_MMS_ABB"
+msgstr "Mms"
+
+msgid "WDS_IME_NPBODY_DRAW_YOUR_OWN_MESSAGE_ABB"
+msgstr "Tegn din egen besked"
+
+msgid "WDS_TTRL_BODY_TURN_THE_BEZEL_ANTICLOCKWISE_TO_UNDO_A_DOODLE_ABB"
+msgstr "Drej panelet mod uret for at fortryde krusedulle."
+
+msgid "WDS_TTRL_HEADER_TIPS_ABB"
+msgstr "Tips"
+
+msgid "WDS_TTRL_BODY_AND_CLOCKWISE_TO_BRING_YOUR_DOODLE_BACK_ABB"
+msgstr "Og med uret for at bringe din krusedulle tilbage."
+
+msgid "WDS_IME_NPBODY_START_DOODLING_YOUR_MESSAGE_ABB"
+msgstr "Begynd at skrive besked m. kruseduller"
+
+msgid "WDS_IME_POP_ARE_YOU_SURE_YOU_WANT_TO_DISCARD_YOUR_DRAWING_Q"
+msgstr "Er du sikker på, at du vil kassere din tegning?"
+
+msgid "WDS_IME_NPBODY_START_DRAWING_YOUR_IMAGE_ABB"
+msgstr "Begynd at tegne dit billede"
+
diff --git a/res/po/de.po b/res/po/de.po
new file mode 100755 (executable)
index 0000000..6125f2a
--- /dev/null
@@ -0,0 +1,33 @@
+msgid "WDS_IME_ACBUTTON_SEND"
+msgstr "SENDEN"
+
+msgid "WDS_WNOTI_POP_ALL_CHANGES_WILL_BE_DISCARDED"
+msgstr "Alle Änderungen werden verworfen."
+
+msgid "WDS_IME_NPBODY_START_DRAWING_M_EMOTICON_ABB"
+msgstr "Zeichnen Sie los."
+
+msgid "WDS_MSG_SBODY_MMS_ABB"
+msgstr "MMS"
+
+msgid "WDS_IME_NPBODY_DRAW_YOUR_OWN_MESSAGE_ABB"
+msgstr "Ihre eigene Nachricht zeichnen"
+
+msgid "WDS_TTRL_BODY_TURN_THE_BEZEL_ANTICLOCKWISE_TO_UNDO_A_DOODLE_ABB"
+msgstr "Lünette zum Rückgängigmachen nach links drehen."
+
+msgid "WDS_TTRL_HEADER_TIPS_ABB"
+msgstr "Tipps"
+
+msgid "WDS_TTRL_BODY_AND_CLOCKWISE_TO_BRING_YOUR_DOODLE_BACK_ABB"
+msgstr "Und nach rechts, um die Zeichnung zurückzuholen."
+
+msgid "WDS_IME_NPBODY_START_DOODLING_YOUR_MESSAGE_ABB"
+msgstr "Zeichnen Sie Ihre Nachricht."
+
+msgid "WDS_IME_POP_ARE_YOU_SURE_YOU_WANT_TO_DISCARD_YOUR_DRAWING_Q"
+msgstr "Möchten Sie Ihre Zeichnung wirklich verwerfen?"
+
+msgid "WDS_IME_NPBODY_START_DRAWING_YOUR_IMAGE_ABB"
+msgstr "Jetzt Ihr Bild zeichnen"
+
diff --git a/res/po/el_GR.po b/res/po/el_GR.po
new file mode 100755 (executable)
index 0000000..dce8e9e
--- /dev/null
@@ -0,0 +1,33 @@
+msgid "WDS_IME_ACBUTTON_SEND"
+msgstr "ΑΠΟΣΤΟΛΗ"
+
+msgid "WDS_WNOTI_POP_ALL_CHANGES_WILL_BE_DISCARDED"
+msgstr "Όλες οι αλλαγές θα απορριφθούν."
+
+msgid "WDS_IME_NPBODY_START_DRAWING_M_EMOTICON_ABB"
+msgstr "Έναρξη σχεδίασης"
+
+msgid "WDS_MSG_SBODY_MMS_ABB"
+msgstr "MMS"
+
+msgid "WDS_IME_NPBODY_DRAW_YOUR_OWN_MESSAGE_ABB"
+msgstr "Σχεδιάστε το δικό σας μήνυμα"
+
+msgid "WDS_TTRL_BODY_TURN_THE_BEZEL_ANTICLOCKWISE_TO_UNDO_A_DOODLE_ABB"
+msgstr "Στρέψτε τη στεφ. αριστερ. για αναίρ. του σκίτσου."
+
+msgid "WDS_TTRL_HEADER_TIPS_ABB"
+msgstr "Συμβουλές"
+
+msgid "WDS_TTRL_BODY_AND_CLOCKWISE_TO_BRING_YOUR_DOODLE_BACK_ABB"
+msgstr "Και δεξιόστροφα για να επαναφέρετε το σκίτσο σας."
+
+msgid "WDS_IME_NPBODY_START_DOODLING_YOUR_MESSAGE_ABB"
+msgstr "Ξεκινήστε να σχεδιάζετε το μήνυμά σας"
+
+msgid "WDS_IME_POP_ARE_YOU_SURE_YOU_WANT_TO_DISCARD_YOUR_DRAWING_Q"
+msgstr "Είστε σίγουροι ότι θέλετε να απορρίψετε το σχέδιό σας;"
+
+msgid "WDS_IME_NPBODY_START_DRAWING_YOUR_IMAGE_ABB"
+msgstr "Ξεκινήστε να σχεδιάζετε την εικόνα σας"
+
diff --git a/res/po/en.po b/res/po/en.po
new file mode 100755 (executable)
index 0000000..1142948
--- /dev/null
@@ -0,0 +1,33 @@
+msgid "WDS_IME_ACBUTTON_SEND"
+msgstr "SEND"
+
+msgid "WDS_WNOTI_POP_ALL_CHANGES_WILL_BE_DISCARDED"
+msgstr "All changes will be discarded."
+
+msgid "WDS_IME_NPBODY_START_DRAWING_M_EMOTICON_ABB"
+msgstr "Start drawing"
+
+msgid "WDS_MSG_SBODY_MMS_ABB"
+msgstr "MMS"
+
+msgid "WDS_IME_NPBODY_DRAW_YOUR_OWN_MESSAGE_ABB"
+msgstr "Draw your own message"
+
+msgid "WDS_TTRL_BODY_TURN_THE_BEZEL_ANTICLOCKWISE_TO_UNDO_A_DOODLE_ABB"
+msgstr "Turn the bezel anticlockwise to undo a doodle."
+
+msgid "WDS_TTRL_HEADER_TIPS_ABB"
+msgstr "Tips"
+
+msgid "WDS_TTRL_BODY_AND_CLOCKWISE_TO_BRING_YOUR_DOODLE_BACK_ABB"
+msgstr "And clockwise to bring your doodle back."
+
+msgid "WDS_IME_NPBODY_START_DOODLING_YOUR_MESSAGE_ABB"
+msgstr "Start doodling your message"
+
+msgid "WDS_IME_POP_ARE_YOU_SURE_YOU_WANT_TO_DISCARD_YOUR_DRAWING_Q"
+msgstr "Are you sure you want to discard your drawing?"
+
+msgid "WDS_IME_NPBODY_START_DRAWING_YOUR_IMAGE_ABB"
+msgstr "Start drawing your image"
+
diff --git a/res/po/en_PH.po b/res/po/en_PH.po
new file mode 100755 (executable)
index 0000000..1142948
--- /dev/null
@@ -0,0 +1,33 @@
+msgid "WDS_IME_ACBUTTON_SEND"
+msgstr "SEND"
+
+msgid "WDS_WNOTI_POP_ALL_CHANGES_WILL_BE_DISCARDED"
+msgstr "All changes will be discarded."
+
+msgid "WDS_IME_NPBODY_START_DRAWING_M_EMOTICON_ABB"
+msgstr "Start drawing"
+
+msgid "WDS_MSG_SBODY_MMS_ABB"
+msgstr "MMS"
+
+msgid "WDS_IME_NPBODY_DRAW_YOUR_OWN_MESSAGE_ABB"
+msgstr "Draw your own message"
+
+msgid "WDS_TTRL_BODY_TURN_THE_BEZEL_ANTICLOCKWISE_TO_UNDO_A_DOODLE_ABB"
+msgstr "Turn the bezel anticlockwise to undo a doodle."
+
+msgid "WDS_TTRL_HEADER_TIPS_ABB"
+msgstr "Tips"
+
+msgid "WDS_TTRL_BODY_AND_CLOCKWISE_TO_BRING_YOUR_DOODLE_BACK_ABB"
+msgstr "And clockwise to bring your doodle back."
+
+msgid "WDS_IME_NPBODY_START_DOODLING_YOUR_MESSAGE_ABB"
+msgstr "Start doodling your message"
+
+msgid "WDS_IME_POP_ARE_YOU_SURE_YOU_WANT_TO_DISCARD_YOUR_DRAWING_Q"
+msgstr "Are you sure you want to discard your drawing?"
+
+msgid "WDS_IME_NPBODY_START_DRAWING_YOUR_IMAGE_ABB"
+msgstr "Start drawing your image"
+
diff --git a/res/po/en_US.po b/res/po/en_US.po
new file mode 100755 (executable)
index 0000000..2f0aab8
--- /dev/null
@@ -0,0 +1,33 @@
+msgid "WDS_IME_ACBUTTON_SEND"
+msgstr "SEND"
+
+msgid "WDS_WNOTI_POP_ALL_CHANGES_WILL_BE_DISCARDED"
+msgstr "All changes will be discarded."
+
+msgid "WDS_IME_NPBODY_START_DRAWING_M_EMOTICON_ABB"
+msgstr "Start drawing"
+
+msgid "WDS_MSG_SBODY_MMS_ABB"
+msgstr "MMS"
+
+msgid "WDS_IME_NPBODY_DRAW_YOUR_OWN_MESSAGE_ABB"
+msgstr "Draw your own message"
+
+msgid "WDS_TTRL_BODY_TURN_THE_BEZEL_ANTICLOCKWISE_TO_UNDO_A_DOODLE_ABB"
+msgstr "Turn the bezel counter clockwise to undo a doodle."
+
+msgid "WDS_TTRL_HEADER_TIPS_ABB"
+msgstr "Tips"
+
+msgid "WDS_TTRL_BODY_AND_CLOCKWISE_TO_BRING_YOUR_DOODLE_BACK_ABB"
+msgstr "And clockwise to bring your doodle back."
+
+msgid "WDS_IME_NPBODY_START_DOODLING_YOUR_MESSAGE_ABB"
+msgstr "Start doodling your message"
+
+msgid "WDS_IME_POP_ARE_YOU_SURE_YOU_WANT_TO_DISCARD_YOUR_DRAWING_Q"
+msgstr "Are you sure you want to discard your drawing?"
+
+msgid "WDS_IME_NPBODY_START_DRAWING_YOUR_IMAGE_ABB"
+msgstr "Start drawing your image"
+
diff --git a/res/po/es_ES.po b/res/po/es_ES.po
new file mode 100755 (executable)
index 0000000..a5f2695
--- /dev/null
@@ -0,0 +1,33 @@
+msgid "WDS_IME_ACBUTTON_SEND"
+msgstr "ENVIAR"
+
+msgid "WDS_WNOTI_POP_ALL_CHANGES_WILL_BE_DISCARDED"
+msgstr "Se descartarán todos los cambios."
+
+msgid "WDS_IME_NPBODY_START_DRAWING_M_EMOTICON_ABB"
+msgstr "Comenzar dibujo"
+
+msgid "WDS_MSG_SBODY_MMS_ABB"
+msgstr "MMS"
+
+msgid "WDS_IME_NPBODY_DRAW_YOUR_OWN_MESSAGE_ABB"
+msgstr "Dibuje su propio mensaje"
+
+msgid "WDS_TTRL_BODY_TURN_THE_BEZEL_ANTICLOCKWISE_TO_UNDO_A_DOODLE_ABB"
+msgstr "Gire bisel en sentido antihorario para deshacer."
+
+msgid "WDS_TTRL_HEADER_TIPS_ABB"
+msgstr "Consejos"
+
+msgid "WDS_TTRL_BODY_AND_CLOCKWISE_TO_BRING_YOUR_DOODLE_BACK_ABB"
+msgstr "Y en sentido horario para volver al dibujo."
+
+msgid "WDS_IME_NPBODY_START_DOODLING_YOUR_MESSAGE_ABB"
+msgstr "Comience a dibujar el mensaje"
+
+msgid "WDS_IME_POP_ARE_YOU_SURE_YOU_WANT_TO_DISCARD_YOUR_DRAWING_Q"
+msgstr "¿Seguro que quiere descartar el dibujo?"
+
+msgid "WDS_IME_NPBODY_START_DRAWING_YOUR_IMAGE_ABB"
+msgstr "Comenzar a dibujar la imagen"
+
diff --git a/res/po/es_US.po b/res/po/es_US.po
new file mode 100755 (executable)
index 0000000..01a2352
--- /dev/null
@@ -0,0 +1,33 @@
+msgid "WDS_IME_ACBUTTON_SEND"
+msgstr "ENVIAR"
+
+msgid "WDS_WNOTI_POP_ALL_CHANGES_WILL_BE_DISCARDED"
+msgstr "Se descartarán los cambios."
+
+msgid "WDS_IME_NPBODY_START_DRAWING_M_EMOTICON_ABB"
+msgstr "Comenzar dibujo"
+
+msgid "WDS_MSG_SBODY_MMS_ABB"
+msgstr "MMS"
+
+msgid "WDS_IME_NPBODY_DRAW_YOUR_OWN_MESSAGE_ABB"
+msgstr "Dibuje su propio mensaje"
+
+msgid "WDS_TTRL_BODY_TURN_THE_BEZEL_ANTICLOCKWISE_TO_UNDO_A_DOODLE_ABB"
+msgstr "Gire bisel en sentido antihorario para deshacer."
+
+msgid "WDS_TTRL_HEADER_TIPS_ABB"
+msgstr "Consejos"
+
+msgid "WDS_TTRL_BODY_AND_CLOCKWISE_TO_BRING_YOUR_DOODLE_BACK_ABB"
+msgstr "Y en sentido horario para recuperar el dibujo."
+
+msgid "WDS_IME_NPBODY_START_DOODLING_YOUR_MESSAGE_ABB"
+msgstr "Empiece a dibujar su mensaje"
+
+msgid "WDS_IME_POP_ARE_YOU_SURE_YOU_WANT_TO_DISCARD_YOUR_DRAWING_Q"
+msgstr "¿Está seguro de que desea descartar su dibujo?"
+
+msgid "WDS_IME_NPBODY_START_DRAWING_YOUR_IMAGE_ABB"
+msgstr "Empiece a dibujar su imagen"
+
diff --git a/res/po/et.po b/res/po/et.po
new file mode 100755 (executable)
index 0000000..216911e
--- /dev/null
@@ -0,0 +1,33 @@
+msgid "WDS_IME_ACBUTTON_SEND"
+msgstr "SAADA"
+
+msgid "WDS_WNOTI_POP_ALL_CHANGES_WILL_BE_DISCARDED"
+msgstr "Kõikidest muudatustest loobutakse."
+
+msgid "WDS_IME_NPBODY_START_DRAWING_M_EMOTICON_ABB"
+msgstr "Alustage joonist."
+
+msgid "WDS_MSG_SBODY_MMS_ABB"
+msgstr "MMS"
+
+msgid "WDS_IME_NPBODY_DRAW_YOUR_OWN_MESSAGE_ABB"
+msgstr "Joonistage sõnum ise"
+
+msgid "WDS_TTRL_BODY_TURN_THE_BEZEL_ANTICLOCKWISE_TO_UNDO_A_DOODLE_ABB"
+msgstr "Keerake rõngast vastup., et ennistada kritseldust."
+
+msgid "WDS_TTRL_HEADER_TIPS_ABB"
+msgstr "Näpunäited"
+
+msgid "WDS_TTRL_BODY_AND_CLOCKWISE_TO_BRING_YOUR_DOODLE_BACK_ABB"
+msgstr "Ja päripäeva, et oma kritseldus tagasi tuua."
+
+msgid "WDS_IME_NPBODY_START_DOODLING_YOUR_MESSAGE_ABB"
+msgstr "Hakake oma sõnumit kritseldama"
+
+msgid "WDS_IME_POP_ARE_YOU_SURE_YOU_WANT_TO_DISCARD_YOUR_DRAWING_Q"
+msgstr "Kas olete kindel, et soovite oma joonistusest loobuda?"
+
+msgid "WDS_IME_NPBODY_START_DRAWING_YOUR_IMAGE_ABB"
+msgstr "Hakake oma pilti joonistama"
+
diff --git a/res/po/eu.po b/res/po/eu.po
new file mode 100755 (executable)
index 0000000..d1deb7d
--- /dev/null
@@ -0,0 +1,33 @@
+msgid "WDS_IME_ACBUTTON_SEND"
+msgstr "BIDALI"
+
+msgid "WDS_WNOTI_POP_ALL_CHANGES_WILL_BE_DISCARDED"
+msgstr "Aldaketa guztiak baztertuko dira."
+
+msgid "WDS_IME_NPBODY_START_DRAWING_M_EMOTICON_ABB"
+msgstr "Hasi marrazten"
+
+msgid "WDS_MSG_SBODY_MMS_ABB"
+msgstr "MMS"
+
+msgid "WDS_IME_NPBODY_DRAW_YOUR_OWN_MESSAGE_ABB"
+msgstr "Marraztu zeure mezua"
+
+msgid "WDS_TTRL_BODY_TURN_THE_BEZEL_ANTICLOCKWISE_TO_UNDO_A_DOODLE_ABB"
+msgstr "Biratu ezkerrera zirriborroa desegiteko."
+
+msgid "WDS_TTRL_HEADER_TIPS_ABB"
+msgstr "Aholkuak"
+
+msgid "WDS_TTRL_BODY_AND_CLOCKWISE_TO_BRING_YOUR_DOODLE_BACK_ABB"
+msgstr "Eta eskuinerantz ekintza desegiteko."
+
+msgid "WDS_IME_NPBODY_START_DOODLING_YOUR_MESSAGE_ABB"
+msgstr "Hasi mezua marrazten"
+
+msgid "WDS_IME_POP_ARE_YOU_SURE_YOU_WANT_TO_DISCARD_YOUR_DRAWING_Q"
+msgstr "Ziur zaude marraztutakoa baztertu nahi duzula?"
+
+msgid "WDS_IME_NPBODY_START_DRAWING_YOUR_IMAGE_ABB"
+msgstr "Hasi irudia marrazten"
+
diff --git a/res/po/fa.po b/res/po/fa.po
new file mode 100755 (executable)
index 0000000..2bcc236
--- /dev/null
@@ -0,0 +1,33 @@
+msgid "WDS_IME_ACBUTTON_SEND"
+msgstr "ارسال"
+
+msgid "WDS_WNOTI_POP_ALL_CHANGES_WILL_BE_DISCARDED"
+msgstr "همه تغییرات کنار گذاشته می‌شوند."
+
+msgid "WDS_IME_NPBODY_START_DRAWING_M_EMOTICON_ABB"
+msgstr "شروع طراحی"
+
+msgid "WDS_MSG_SBODY_MMS_ABB"
+msgstr "MMS"
+
+msgid "WDS_IME_NPBODY_DRAW_YOUR_OWN_MESSAGE_ABB"
+msgstr "ترسیم پیام شخصی"
+
+msgid "WDS_TTRL_BODY_TURN_THE_BEZEL_ANTICLOCKWISE_TO_UNDO_A_DOODLE_ABB"
+msgstr "برای واگرد نقاشی بزل را پادساعتگرد بچرخانید."
+
+msgid "WDS_TTRL_HEADER_TIPS_ABB"
+msgstr "توصیه‌ها"
+
+msgid "WDS_TTRL_BODY_AND_CLOCKWISE_TO_BRING_YOUR_DOODLE_BACK_ABB"
+msgstr "و ساعتگرد بچرخانید تا نقاشی را برگردانید."
+
+msgid "WDS_IME_NPBODY_START_DOODLING_YOUR_MESSAGE_ABB"
+msgstr "شروع نقاشی پیام شما"
+
+msgid "WDS_IME_POP_ARE_YOU_SURE_YOU_WANT_TO_DISCARD_YOUR_DRAWING_Q"
+msgstr "واقعاً می‌خواهید نقاشی خود را کنار بگذارید؟"
+
+msgid "WDS_IME_NPBODY_START_DRAWING_YOUR_IMAGE_ABB"
+msgstr "شروع به ترسیم تصویر خود کنید"
+
diff --git a/res/po/fi.po b/res/po/fi.po
new file mode 100755 (executable)
index 0000000..f024da3
--- /dev/null
@@ -0,0 +1,33 @@
+msgid "WDS_IME_ACBUTTON_SEND"
+msgstr "LÄHETÄ"
+
+msgid "WDS_WNOTI_POP_ALL_CHANGES_WILL_BE_DISCARDED"
+msgstr "Kaikki muutokset hylätään."
+
+msgid "WDS_IME_NPBODY_START_DRAWING_M_EMOTICON_ABB"
+msgstr "Ala piirtää"
+
+msgid "WDS_MSG_SBODY_MMS_ABB"
+msgstr "MMS"
+
+msgid "WDS_IME_NPBODY_DRAW_YOUR_OWN_MESSAGE_ABB"
+msgstr "Piirrä oma viestisi"
+
+msgid "WDS_TTRL_BODY_TURN_THE_BEZEL_ANTICLOCKWISE_TO_UNDO_A_DOODLE_ABB"
+msgstr "Kumoa piirros kääntämällä etulevyä vastapäivään."
+
+msgid "WDS_TTRL_HEADER_TIPS_ABB"
+msgstr "Vihjeitä"
+
+msgid "WDS_TTRL_BODY_AND_CLOCKWISE_TO_BRING_YOUR_DOODLE_BACK_ABB"
+msgstr "Käännä myötäpäivään palauttaaksesi piirroksen."
+
+msgid "WDS_IME_NPBODY_START_DOODLING_YOUR_MESSAGE_ABB"
+msgstr "Aloita viestin piirtäminen"
+
+msgid "WDS_IME_POP_ARE_YOU_SURE_YOU_WANT_TO_DISCARD_YOUR_DRAWING_Q"
+msgstr "Haluatko varmasti hylätä piirroksen?"
+
+msgid "WDS_IME_NPBODY_START_DRAWING_YOUR_IMAGE_ABB"
+msgstr "Aloita kuvan piirtäminen"
+
diff --git a/res/po/fr.po b/res/po/fr.po
new file mode 100755 (executable)
index 0000000..68ab01f
--- /dev/null
@@ -0,0 +1,33 @@
+msgid "WDS_IME_ACBUTTON_SEND"
+msgstr "ENVOYER"
+
+msgid "WDS_WNOTI_POP_ALL_CHANGES_WILL_BE_DISCARDED"
+msgstr "Toutes les modifications vont être ignorées."
+
+msgid "WDS_IME_NPBODY_START_DRAWING_M_EMOTICON_ABB"
+msgstr "Commencer dessin"
+
+msgid "WDS_MSG_SBODY_MMS_ABB"
+msgstr "MMS"
+
+msgid "WDS_IME_NPBODY_DRAW_YOUR_OWN_MESSAGE_ABB"
+msgstr "Dessiner votre propre message"
+
+msgid "WDS_TTRL_BODY_TURN_THE_BEZEL_ANTICLOCKWISE_TO_UNDO_A_DOODLE_ABB"
+msgstr "Tournez lunette ds sens inverse pr annuler doodle."
+
+msgid "WDS_TTRL_HEADER_TIPS_ABB"
+msgstr "Astuces"
+
+msgid "WDS_TTRL_BODY_AND_CLOCKWISE_TO_BRING_YOUR_DOODLE_BACK_ABB"
+msgstr "Tournez ds sens horaire pour refaire votre doodle."
+
+msgid "WDS_IME_NPBODY_START_DOODLING_YOUR_MESSAGE_ABB"
+msgstr "Commencer à griffonner votre message"
+
+msgid "WDS_IME_POP_ARE_YOU_SURE_YOU_WANT_TO_DISCARD_YOUR_DRAWING_Q"
+msgstr "Voulez-vous vraiment ignorer votre dessin ?"
+
+msgid "WDS_IME_NPBODY_START_DRAWING_YOUR_IMAGE_ABB"
+msgstr "Commencer à dessiner votre image"
+
diff --git a/res/po/fr_CA.po b/res/po/fr_CA.po
new file mode 100755 (executable)
index 0000000..68ab01f
--- /dev/null
@@ -0,0 +1,33 @@
+msgid "WDS_IME_ACBUTTON_SEND"
+msgstr "ENVOYER"
+
+msgid "WDS_WNOTI_POP_ALL_CHANGES_WILL_BE_DISCARDED"
+msgstr "Toutes les modifications vont être ignorées."
+
+msgid "WDS_IME_NPBODY_START_DRAWING_M_EMOTICON_ABB"
+msgstr "Commencer dessin"
+
+msgid "WDS_MSG_SBODY_MMS_ABB"
+msgstr "MMS"
+
+msgid "WDS_IME_NPBODY_DRAW_YOUR_OWN_MESSAGE_ABB"
+msgstr "Dessiner votre propre message"
+
+msgid "WDS_TTRL_BODY_TURN_THE_BEZEL_ANTICLOCKWISE_TO_UNDO_A_DOODLE_ABB"
+msgstr "Tournez lunette ds sens inverse pr annuler doodle."
+
+msgid "WDS_TTRL_HEADER_TIPS_ABB"
+msgstr "Astuces"
+
+msgid "WDS_TTRL_BODY_AND_CLOCKWISE_TO_BRING_YOUR_DOODLE_BACK_ABB"
+msgstr "Tournez ds sens horaire pour refaire votre doodle."
+
+msgid "WDS_IME_NPBODY_START_DOODLING_YOUR_MESSAGE_ABB"
+msgstr "Commencer à griffonner votre message"
+
+msgid "WDS_IME_POP_ARE_YOU_SURE_YOU_WANT_TO_DISCARD_YOUR_DRAWING_Q"
+msgstr "Voulez-vous vraiment ignorer votre dessin ?"
+
+msgid "WDS_IME_NPBODY_START_DRAWING_YOUR_IMAGE_ABB"
+msgstr "Commencer à dessiner votre image"
+
diff --git a/res/po/ga.po b/res/po/ga.po
new file mode 100755 (executable)
index 0000000..6f10ad8
--- /dev/null
@@ -0,0 +1,33 @@
+msgid "WDS_IME_ACBUTTON_SEND"
+msgstr "SEOL"
+
+msgid "WDS_WNOTI_POP_ALL_CHANGES_WILL_BE_DISCARDED"
+msgstr "Cuileálfar gach athrú."
+
+msgid "WDS_IME_NPBODY_START_DRAWING_M_EMOTICON_ABB"
+msgstr "Tos. ar líníocht"
+
+msgid "WDS_MSG_SBODY_MMS_ABB"
+msgstr "MMS"
+
+msgid "WDS_IME_NPBODY_DRAW_YOUR_OWN_MESSAGE_ABB"
+msgstr "Tarraing do theachtaireacht féin"
+
+msgid "WDS_TTRL_BODY_TURN_THE_BEZEL_ANTICLOCKWISE_TO_UNDO_A_DOODLE_ABB"
+msgstr "Cas an beiséal tuathal le breacaireacht a chealú."
+
+msgid "WDS_TTRL_HEADER_TIPS_ABB"
+msgstr "Leideanna"
+
+msgid "WDS_TTRL_BODY_AND_CLOCKWISE_TO_BRING_YOUR_DOODLE_BACK_ABB"
+msgstr "Agus cas deiseal le filleadh ar do bhreacaireacht."
+
+msgid "WDS_IME_NPBODY_START_DOODLING_YOUR_MESSAGE_ABB"
+msgstr "Déan breacaireacht ar do theachtaireacht"
+
+msgid "WDS_IME_POP_ARE_YOU_SURE_YOU_WANT_TO_DISCARD_YOUR_DRAWING_Q"
+msgstr "An bhfuil tú cinnte gur mian leat do líníocht a chuileáil?"
+
+msgid "WDS_IME_NPBODY_START_DRAWING_YOUR_IMAGE_ABB"
+msgstr "Tosaigh ag tarraingt d'íomhá"
+
diff --git a/res/po/gl.po b/res/po/gl.po
new file mode 100755 (executable)
index 0000000..1879d4c
--- /dev/null
@@ -0,0 +1,33 @@
+msgid "WDS_IME_ACBUTTON_SEND"
+msgstr "ENVIAR"
+
+msgid "WDS_WNOTI_POP_ALL_CHANGES_WILL_BE_DISCARDED"
+msgstr "Descartaranse todos os cambios."
+
+msgid "WDS_IME_NPBODY_START_DRAWING_M_EMOTICON_ABB"
+msgstr "Comezar a debuxar"
+
+msgid "WDS_MSG_SBODY_MMS_ABB"
+msgstr "MMS"
+
+msgid "WDS_IME_NPBODY_DRAW_YOUR_OWN_MESSAGE_ABB"
+msgstr "Debuxa a túa mensaxe"
+
+msgid "WDS_TTRL_BODY_TURN_THE_BEZEL_ANTICLOCKWISE_TO_UNDO_A_DOODLE_ABB"
+msgstr "Xira o bisel á esquerda para desfacer un garabato."
+
+msgid "WDS_TTRL_HEADER_TIPS_ABB"
+msgstr "Consellos"
+
+msgid "WDS_TTRL_BODY_AND_CLOCKWISE_TO_BRING_YOUR_DOODLE_BACK_ABB"
+msgstr "E cara á dereita para volver traer o garabato."
+
+msgid "WDS_IME_NPBODY_START_DOODLING_YOUR_MESSAGE_ABB"
+msgstr "Comezar a debuxar a mensaxe"
+
+msgid "WDS_IME_POP_ARE_YOU_SURE_YOU_WANT_TO_DISCARD_YOUR_DRAWING_Q"
+msgstr "Estás seguro de que queres descartar o teu debuxo?"
+
+msgid "WDS_IME_NPBODY_START_DRAWING_YOUR_IMAGE_ABB"
+msgstr "Comeza a debuxar a imaxe"
+
diff --git a/res/po/gu.po b/res/po/gu.po
new file mode 100755 (executable)
index 0000000..7e1c8a5
--- /dev/null
@@ -0,0 +1,33 @@
+msgid "WDS_IME_ACBUTTON_SEND"
+msgstr "મોકલો"
+
+msgid "WDS_WNOTI_POP_ALL_CHANGES_WILL_BE_DISCARDED"
+msgstr "બધા ફેરફારો કાઢી નાખવામાં આવશે."
+
+msgid "WDS_IME_NPBODY_START_DRAWING_M_EMOTICON_ABB"
+msgstr "ડ્રોઇંગ શરૂ કરો"
+
+msgid "WDS_MSG_SBODY_MMS_ABB"
+msgstr "MMS"
+
+msgid "WDS_IME_NPBODY_DRAW_YOUR_OWN_MESSAGE_ABB"
+msgstr "તમારો પોતાનો સંદેશ દોરો"
+
+msgid "WDS_TTRL_BODY_TURN_THE_BEZEL_ANTICLOCKWISE_TO_UNDO_A_DOODLE_ABB"
+msgstr "ડૂડલને પૂર્વવત્ કરવા માટે બેઝલને ઘડિયાળની વિપરિત દિશામાં ફેરવો."
+
+msgid "WDS_TTRL_HEADER_TIPS_ABB"
+msgstr "ટિપ્સ"
+
+msgid "WDS_TTRL_BODY_AND_CLOCKWISE_TO_BRING_YOUR_DOODLE_BACK_ABB"
+msgstr "અને તમારા ડૂડલને પાછું લાવવા માટે ઘડિયાળની દિશામાં."
+
+msgid "WDS_IME_NPBODY_START_DOODLING_YOUR_MESSAGE_ABB"
+msgstr "તમારા સંદેશને ડૂડલ કરવાનું પ્રારંભ કરો"
+
+msgid "WDS_IME_POP_ARE_YOU_SURE_YOU_WANT_TO_DISCARD_YOUR_DRAWING_Q"
+msgstr "શું તમે ખરેખર તમારું ડ્રોઇંગ કાઢી નાખવા માંગો છો?"
+
+msgid "WDS_IME_NPBODY_START_DRAWING_YOUR_IMAGE_ABB"
+msgstr "તમારી છબી દોરવાનું શરૂ કરો"
+
diff --git a/res/po/he.po b/res/po/he.po
new file mode 100755 (executable)
index 0000000..836d3e8
--- /dev/null
@@ -0,0 +1,33 @@
+msgid "WDS_IME_ACBUTTON_SEND"
+msgstr "שלח"
+
+msgid "WDS_WNOTI_POP_ALL_CHANGES_WILL_BE_DISCARDED"
+msgstr "כל השינויים יושלכו."
+
+msgid "WDS_IME_NPBODY_START_DRAWING_M_EMOTICON_ABB"
+msgstr "התחל לצייר"
+
+msgid "WDS_MSG_SBODY_MMS_ABB"
+msgstr "MMS"
+
+msgid "WDS_IME_NPBODY_DRAW_YOUR_OWN_MESSAGE_ABB"
+msgstr "צייר הודעה משלך"
+
+msgid "WDS_TTRL_BODY_TURN_THE_BEZEL_ANTICLOCKWISE_TO_UNDO_A_DOODLE_ABB"
+msgstr "בטל שרבוט ע״י סיבוב מסגרת החוגה נגד כיוון השעון."
+
+msgid "WDS_TTRL_HEADER_TIPS_ABB"
+msgstr "עצות"
+
+msgid "WDS_TTRL_BODY_AND_CLOCKWISE_TO_BRING_YOUR_DOODLE_BACK_ABB"
+msgstr "ובכיוון השעון כדי להחזיר את השרבוט שלך."
+
+msgid "WDS_IME_NPBODY_START_DOODLING_YOUR_MESSAGE_ABB"
+msgstr "התחל לשרבט את ההודעה"
+
+msgid "WDS_IME_POP_ARE_YOU_SURE_YOU_WANT_TO_DISCARD_YOUR_DRAWING_Q"
+msgstr "האם אתה בטוח שברצונך להשליך את הציור?"
+
+msgid "WDS_IME_NPBODY_START_DRAWING_YOUR_IMAGE_ABB"
+msgstr "התחל לצייר את התמונה"
+
diff --git a/res/po/hi.po b/res/po/hi.po
new file mode 100755 (executable)
index 0000000..041f6af
--- /dev/null
@@ -0,0 +1,33 @@
+msgid "WDS_IME_ACBUTTON_SEND"
+msgstr "भेजें"
+
+msgid "WDS_WNOTI_POP_ALL_CHANGES_WILL_BE_DISCARDED"
+msgstr "सभी बदलाव निरस्त कर दिए जाएँगें।"
+
+msgid "WDS_IME_NPBODY_START_DRAWING_M_EMOTICON_ABB"
+msgstr "चित्रकारी शुरू करें"
+
+msgid "WDS_MSG_SBODY_MMS_ABB"
+msgstr "MMS"
+
+msgid "WDS_IME_NPBODY_DRAW_YOUR_OWN_MESSAGE_ABB"
+msgstr "अपना स्वयं का सन्देश आरेखित करें"
+
+msgid "WDS_TTRL_BODY_TURN_THE_BEZEL_ANTICLOCKWISE_TO_UNDO_A_DOODLE_ABB"
+msgstr "कोई डूडल पूर्ववत करने हेतु घड़ी की विपरीत दिशा में बेजल घुमाएँ।"
+
+msgid "WDS_TTRL_HEADER_TIPS_ABB"
+msgstr "युक्तियाँ"
+
+msgid "WDS_TTRL_BODY_AND_CLOCKWISE_TO_BRING_YOUR_DOODLE_BACK_ABB"
+msgstr "और अपने डूडल को वापस लाने के लिए घड़ी की दिशा में घुमाएँ।"
+
+msgid "WDS_IME_NPBODY_START_DOODLING_YOUR_MESSAGE_ABB"
+msgstr "अपने सन्देश को डूडल करना प्रारंभ करें"
+
+msgid "WDS_IME_POP_ARE_YOU_SURE_YOU_WANT_TO_DISCARD_YOUR_DRAWING_Q"
+msgstr "क्या आप वाकई अपनी चित्रकारी निरस्त करना चाहते हैं?"
+
+msgid "WDS_IME_NPBODY_START_DRAWING_YOUR_IMAGE_ABB"
+msgstr "अपनी छवि आरेखित करना प्रारंभ करें"
+
diff --git a/res/po/hr.po b/res/po/hr.po
new file mode 100755 (executable)
index 0000000..e9576eb
--- /dev/null
@@ -0,0 +1,33 @@
+msgid "WDS_IME_ACBUTTON_SEND"
+msgstr "ŠALJI"
+
+msgid "WDS_WNOTI_POP_ALL_CHANGES_WILL_BE_DISCARDED"
+msgstr "Sve će se promjene odbaciti."
+
+msgid "WDS_IME_NPBODY_START_DRAWING_M_EMOTICON_ABB"
+msgstr "Počnite crtati"
+
+msgid "WDS_MSG_SBODY_MMS_ABB"
+msgstr "MMS"
+
+msgid "WDS_IME_NPBODY_DRAW_YOUR_OWN_MESSAGE_ABB"
+msgstr "Nacrtajte vlastitu poruku"
+
+msgid "WDS_TTRL_BODY_TURN_THE_BEZEL_ANTICLOCKWISE_TO_UNDO_A_DOODLE_ABB"
+msgstr "Zakrenite okvir ulijevo da biste poništili crtež."
+
+msgid "WDS_TTRL_HEADER_TIPS_ABB"
+msgstr "Savjeti"
+
+msgid "WDS_TTRL_BODY_AND_CLOCKWISE_TO_BRING_YOUR_DOODLE_BACK_ABB"
+msgstr "Zakrenite ga udesno da biste vratili crtež."
+
+msgid "WDS_IME_NPBODY_START_DOODLING_YOUR_MESSAGE_ABB"
+msgstr "Počnite crtati svoju poruku"
+
+msgid "WDS_IME_POP_ARE_YOU_SURE_YOU_WANT_TO_DISCARD_YOUR_DRAWING_Q"
+msgstr "Jeste li sigurni da želite odbaciti svoj crtež?"
+
+msgid "WDS_IME_NPBODY_START_DRAWING_YOUR_IMAGE_ABB"
+msgstr "Počnite crtati sliku"
+
diff --git a/res/po/hu.po b/res/po/hu.po
new file mode 100755 (executable)
index 0000000..3aa2d15
--- /dev/null
@@ -0,0 +1,33 @@
+msgid "WDS_IME_ACBUTTON_SEND"
+msgstr "KÜLDÉS"
+
+msgid "WDS_WNOTI_POP_ALL_CHANGES_WILL_BE_DISCARDED"
+msgstr "Minden változtatást elvet."
+
+msgid "WDS_IME_NPBODY_START_DRAWING_M_EMOTICON_ABB"
+msgstr "Kezdjen rajzolni"
+
+msgid "WDS_MSG_SBODY_MMS_ABB"
+msgstr "MMS"
+
+msgid "WDS_IME_NPBODY_DRAW_YOUR_OWN_MESSAGE_ABB"
+msgstr "Rajzoljon saját üzenetet"
+
+msgid "WDS_TTRL_BODY_TURN_THE_BEZEL_ANTICLOCKWISE_TO_UNDO_A_DOODLE_ABB"
+msgstr "Forgassa a keretet balra az irkafirka v.vonásához."
+
+msgid "WDS_TTRL_HEADER_TIPS_ABB"
+msgstr "Tippek"
+
+msgid "WDS_TTRL_BODY_AND_CLOCKWISE_TO_BRING_YOUR_DOODLE_BACK_ABB"
+msgstr "Forgassa jobbra az irkafirka visszahozásához."
+
+msgid "WDS_IME_NPBODY_START_DOODLING_YOUR_MESSAGE_ABB"
+msgstr "Kezdje el lerajzolni üzenetét"
+
+msgid "WDS_IME_POP_ARE_YOU_SURE_YOU_WANT_TO_DISCARD_YOUR_DRAWING_Q"
+msgstr "Valóban elveti a rajzot?"
+
+msgid "WDS_IME_NPBODY_START_DRAWING_YOUR_IMAGE_ABB"
+msgstr "Kezdje el lerajzolni a képet"
+
diff --git a/res/po/hy.po b/res/po/hy.po
new file mode 100755 (executable)
index 0000000..04b042a
--- /dev/null
@@ -0,0 +1,33 @@
+msgid "WDS_IME_ACBUTTON_SEND"
+msgstr "ՈՒՂԱՐԿԵԼ"
+
+msgid "WDS_WNOTI_POP_ALL_CHANGES_WILL_BE_DISCARDED"
+msgstr "Բոլոր փոփոխությունները կանտեսվեն:"
+
+msgid "WDS_IME_NPBODY_START_DRAWING_M_EMOTICON_ABB"
+msgstr "Սկսեք գծագրել"
+
+msgid "WDS_MSG_SBODY_MMS_ABB"
+msgstr "MMS"
+
+msgid "WDS_IME_NPBODY_DRAW_YOUR_OWN_MESSAGE_ABB"
+msgstr "Կազմեք Ձեր սեփական հաղորդագրությունը"
+
+msgid "WDS_TTRL_BODY_TURN_THE_BEZEL_ANTICLOCKWISE_TO_UNDO_A_DOODLE_ABB"
+msgstr "Շրջնկ շրջեք ժամսլաքի հակ. ուղղ.՝ խզբզոց ետարկ. հր:"
+
+msgid "WDS_TTRL_HEADER_TIPS_ABB"
+msgstr "Խորհուրդներ"
+
+msgid "WDS_TTRL_BODY_AND_CLOCKWISE_TO_BRING_YOUR_DOODLE_BACK_ABB"
+msgstr "Եվ ժամ. սլաքի ուղղությամբ՝ խզբզոցը հետ բերելու հր:"
+
+msgid "WDS_IME_NPBODY_START_DOODLING_YOUR_MESSAGE_ABB"
+msgstr "Սկսեք խզբզել Ձեր հաղորդագրությունը"
+
+msgid "WDS_IME_POP_ARE_YOU_SURE_YOU_WANT_TO_DISCARD_YOUR_DRAWING_Q"
+msgstr "Իրո՞ք ուզում եք հեռացնել Ձեր գծագիրը:"
+
+msgid "WDS_IME_NPBODY_START_DRAWING_YOUR_IMAGE_ABB"
+msgstr "Սկսեք նկարել Ձեր պատկերը"
+
diff --git a/res/po/id.po b/res/po/id.po
new file mode 100755 (executable)
index 0000000..691d6ba
--- /dev/null
@@ -0,0 +1,33 @@
+msgid "WDS_IME_ACBUTTON_SEND"
+msgstr "KIRIM"
+
+msgid "WDS_WNOTI_POP_ALL_CHANGES_WILL_BE_DISCARDED"
+msgstr "Semua perubahan akan dibuang."
+
+msgid "WDS_IME_NPBODY_START_DRAWING_M_EMOTICON_ABB"
+msgstr "Mulai menggambar"
+
+msgid "WDS_MSG_SBODY_MMS_ABB"
+msgstr "MMS"
+
+msgid "WDS_IME_NPBODY_DRAW_YOUR_OWN_MESSAGE_ABB"
+msgstr "Gambar pesan Anda sendiri"
+
+msgid "WDS_TTRL_BODY_TURN_THE_BEZEL_ANTICLOCKWISE_TO_UNDO_A_DOODLE_ABB"
+msgstr "Putar bezel melawan arah jam utk batalkan coretan."
+
+msgid "WDS_TTRL_HEADER_TIPS_ABB"
+msgstr "Kiat"
+
+msgid "WDS_TTRL_BODY_AND_CLOCKWISE_TO_BRING_YOUR_DOODLE_BACK_ABB"
+msgstr "Dan searah jam untuk mengembalikan coretan Anda."
+
+msgid "WDS_IME_NPBODY_START_DOODLING_YOUR_MESSAGE_ABB"
+msgstr "Mulai coretkan pesan Anda"
+
+msgid "WDS_IME_POP_ARE_YOU_SURE_YOU_WANT_TO_DISCARD_YOUR_DRAWING_Q"
+msgstr "Yakin ingin membuang gambar?"
+
+msgid "WDS_IME_NPBODY_START_DRAWING_YOUR_IMAGE_ABB"
+msgstr "Mulai membuat gambar"
+
diff --git a/res/po/is.po b/res/po/is.po
new file mode 100755 (executable)
index 0000000..1e460c7
--- /dev/null
@@ -0,0 +1,33 @@
+msgid "WDS_IME_ACBUTTON_SEND"
+msgstr "SENDA"
+
+msgid "WDS_WNOTI_POP_ALL_CHANGES_WILL_BE_DISCARDED"
+msgstr "Öllum breytingum verður fleygt."
+
+msgid "WDS_IME_NPBODY_START_DRAWING_M_EMOTICON_ABB"
+msgstr "Byrjaðu að teikna"
+
+msgid "WDS_MSG_SBODY_MMS_ABB"
+msgstr "MMS"
+
+msgid "WDS_IME_NPBODY_DRAW_YOUR_OWN_MESSAGE_ABB"
+msgstr "Teiknaðu þín eigin skilaboð"
+
+msgid "WDS_TTRL_BODY_TURN_THE_BEZEL_ANTICLOCKWISE_TO_UNDO_A_DOODLE_ABB"
+msgstr "Snúðu skífunni rangsælis til að afturkalla krot."
+
+msgid "WDS_TTRL_HEADER_TIPS_ABB"
+msgstr "Ráð"
+
+msgid "WDS_TTRL_BODY_AND_CLOCKWISE_TO_BRING_YOUR_DOODLE_BACK_ABB"
+msgstr "Og réttsælis til að kalla krotið fram aftur."
+
+msgid "WDS_IME_NPBODY_START_DOODLING_YOUR_MESSAGE_ABB"
+msgstr "Krotaðu skilaboðin þín"
+
+msgid "WDS_IME_POP_ARE_YOU_SURE_YOU_WANT_TO_DISCARD_YOUR_DRAWING_Q"
+msgstr "Ertu viss um að þú viljir fleygja teikningunni?"
+
+msgid "WDS_IME_NPBODY_START_DRAWING_YOUR_IMAGE_ABB"
+msgstr "Byrjaðu að teikna myndina þína"
+
diff --git a/res/po/it_IT.po b/res/po/it_IT.po
new file mode 100755 (executable)
index 0000000..48d76b1
--- /dev/null
@@ -0,0 +1,33 @@
+msgid "WDS_IME_ACBUTTON_SEND"
+msgstr "INVIA"
+
+msgid "WDS_WNOTI_POP_ALL_CHANGES_WILL_BE_DISCARDED"
+msgstr "Ogni modifica sarà annullata."
+
+msgid "WDS_IME_NPBODY_START_DRAWING_M_EMOTICON_ABB"
+msgstr "Inizia a disegnare"
+
+msgid "WDS_MSG_SBODY_MMS_ABB"
+msgstr "MMS"
+
+msgid "WDS_IME_NPBODY_DRAW_YOUR_OWN_MESSAGE_ABB"
+msgstr "Disegnate un messaggio personale"
+
+msgid "WDS_TTRL_BODY_TURN_THE_BEZEL_ANTICLOCKWISE_TO_UNDO_A_DOODLE_ABB"
+msgstr "Per annull. disegno, ruota ghiera in senso antior."
+
+msgid "WDS_TTRL_HEADER_TIPS_ABB"
+msgstr "Suggerimenti"
+
+msgid "WDS_TTRL_BODY_AND_CLOCKWISE_TO_BRING_YOUR_DOODLE_BACK_ABB"
+msgstr "E in senso orario per ripetere il disegno."
+
+msgid "WDS_IME_NPBODY_START_DOODLING_YOUR_MESSAGE_ABB"
+msgstr "Inizia a disegnare il tuo messaggio"
+
+msgid "WDS_IME_POP_ARE_YOU_SURE_YOU_WANT_TO_DISCARD_YOUR_DRAWING_Q"
+msgstr "Scartare il disegno?"
+
+msgid "WDS_IME_NPBODY_START_DRAWING_YOUR_IMAGE_ABB"
+msgstr "Inizia a disegnare la tua immagine"
+
diff --git a/res/po/ja_JP.po b/res/po/ja_JP.po
new file mode 100755 (executable)
index 0000000..bbaccdf
--- /dev/null
@@ -0,0 +1,33 @@
+msgid "WDS_IME_ACBUTTON_SEND"
+msgstr "送信"
+
+msgid "WDS_WNOTI_POP_ALL_CHANGES_WILL_BE_DISCARDED"
+msgstr "全ての変更を破棄します。"
+
+msgid "WDS_IME_NPBODY_START_DRAWING_M_EMOTICON_ABB"
+msgstr "スケッチを開始"
+
+msgid "WDS_MSG_SBODY_MMS_ABB"
+msgstr "MMS"
+
+msgid "WDS_IME_NPBODY_DRAW_YOUR_OWN_MESSAGE_ABB"
+msgstr "気持ちを書き表しましょう"
+
+msgid "WDS_TTRL_BODY_TURN_THE_BEZEL_ANTICLOCKWISE_TO_UNDO_A_DOODLE_ABB"
+msgstr "手書きを取り消すにはベゼルを反時計回りに回します。"
+
+msgid "WDS_TTRL_HEADER_TIPS_ABB"
+msgstr "ヒント"
+
+msgid "WDS_TTRL_BODY_AND_CLOCKWISE_TO_BRING_YOUR_DOODLE_BACK_ABB"
+msgstr "手書きを回復するには時計回りに回します。"
+
+msgid "WDS_IME_NPBODY_START_DOODLING_YOUR_MESSAGE_ABB"
+msgstr "手書きメッセージを開始"
+
+msgid "WDS_IME_POP_ARE_YOU_SURE_YOU_WANT_TO_DISCARD_YOUR_DRAWING_Q"
+msgstr "手書きした内容を破棄しますか?"
+
+msgid "WDS_IME_NPBODY_START_DRAWING_YOUR_IMAGE_ABB"
+msgstr "イメージスケッチを開始"
+
diff --git a/res/po/ka.po b/res/po/ka.po
new file mode 100755 (executable)
index 0000000..fc081ed
--- /dev/null
@@ -0,0 +1,33 @@
+msgid "WDS_IME_ACBUTTON_SEND"
+msgstr "გაგზავნა"
+
+msgid "WDS_WNOTI_POP_ALL_CHANGES_WILL_BE_DISCARDED"
+msgstr "ყველა ცვლილება გაუქმდება."
+
+msgid "WDS_IME_NPBODY_START_DRAWING_M_EMOTICON_ABB"
+msgstr "დაიწყეთ ხატვა"
+
+msgid "WDS_MSG_SBODY_MMS_ABB"
+msgstr "MMS"
+
+msgid "WDS_IME_NPBODY_DRAW_YOUR_OWN_MESSAGE_ABB"
+msgstr "მოხაზეთ საკუთარი შეტყობინება"
+
+msgid "WDS_TTRL_BODY_TURN_THE_BEZEL_ANTICLOCKWISE_TO_UNDO_A_DOODLE_ABB"
+msgstr "მინაწერი გაუქმდება საათის საწინააღმდეგოდ ბრუნვით."
+
+msgid "WDS_TTRL_HEADER_TIPS_ABB"
+msgstr "მინიშნებები"
+
+msgid "WDS_TTRL_BODY_AND_CLOCKWISE_TO_BRING_YOUR_DOODLE_BACK_ABB"
+msgstr "საათის ისრის მიმართულებით დაბრუნდება მინახატი."
+
+msgid "WDS_IME_NPBODY_START_DOODLING_YOUR_MESSAGE_ABB"
+msgstr "შეტყობინებაზე მიხატვის დაწყება"
+
+msgid "WDS_IME_POP_ARE_YOU_SURE_YOU_WANT_TO_DISCARD_YOUR_DRAWING_Q"
+msgstr "დარწმუნებული ხართ, რომ გსურთ ნახატის წაშლა?"
+
+msgid "WDS_IME_NPBODY_START_DRAWING_YOUR_IMAGE_ABB"
+msgstr "დაიწყეთ სურათის დახატვა"
+
diff --git a/res/po/kk.po b/res/po/kk.po
new file mode 100755 (executable)
index 0000000..680c75f
--- /dev/null
@@ -0,0 +1,33 @@
+msgid "WDS_IME_ACBUTTON_SEND"
+msgstr "ЖІБЕРУ"
+
+msgid "WDS_WNOTI_POP_ALL_CHANGES_WILL_BE_DISCARDED"
+msgstr "Барлық өзгерістер алынып тасталады."
+
+msgid "WDS_IME_NPBODY_START_DRAWING_M_EMOTICON_ABB"
+msgstr "Сызуды бастау"
+
+msgid "WDS_MSG_SBODY_MMS_ABB"
+msgstr "MMS"
+
+msgid "WDS_IME_NPBODY_DRAW_YOUR_OWN_MESSAGE_ABB"
+msgstr "Өз хабарыңызды салу"
+
+msgid "WDS_TTRL_BODY_TURN_THE_BEZEL_ANTICLOCKWISE_TO_UNDO_A_DOODLE_ABB"
+msgstr "Сызбаны жою үшін, тұтқышты сағат тіліне қарсы бұр."
+
+msgid "WDS_TTRL_HEADER_TIPS_ABB"
+msgstr "Кеңестер"
+
+msgid "WDS_TTRL_BODY_AND_CLOCKWISE_TO_BRING_YOUR_DOODLE_BACK_ABB"
+msgstr "Сызбаңызды қайтару үшін сағат тілімен бұрыңыз."
+
+msgid "WDS_IME_NPBODY_START_DOODLING_YOUR_MESSAGE_ABB"
+msgstr "Хабарыңызға сурет салуды бастаңыз"
+
+msgid "WDS_IME_POP_ARE_YOU_SURE_YOU_WANT_TO_DISCARD_YOUR_DRAWING_Q"
+msgstr "Сызбаңызды алып тастағыңыз келе ме?"
+
+msgid "WDS_IME_NPBODY_START_DRAWING_YOUR_IMAGE_ABB"
+msgstr "Сурет салуды бастаңыз"
+
diff --git a/res/po/km.po b/res/po/km.po
new file mode 100755 (executable)
index 0000000..c3968a7
--- /dev/null
@@ -0,0 +1,33 @@
+msgid "WDS_IME_ACBUTTON_SEND"
+msgstr "ផ្ញើ"
+
+msgid "WDS_WNOTI_POP_ALL_CHANGES_WILL_BE_DISCARDED"
+msgstr "នឹង​ចោល​ការប្ដូរ​ទាំងអស់។"
+
+msgid "WDS_IME_NPBODY_START_DRAWING_M_EMOTICON_ABB"
+msgstr "ចាប់ផ្ដើម​គូស"
+
+msgid "WDS_MSG_SBODY_MMS_ABB"
+msgstr "MMS"
+
+msgid "WDS_IME_NPBODY_DRAW_YOUR_OWN_MESSAGE_ABB"
+msgstr "គូស​សារ​ផ្ទាល់ខ្លួន​របស់​អ្នក"
+
+msgid "WDS_TTRL_BODY_TURN_THE_BEZEL_ANTICLOCKWISE_TO_UNDO_A_DOODLE_ABB"
+msgstr "បែរ​មុខទេរ​តាម​ទិស​បញ្ច្រាស់​ទ្រនិច​នាឡិកា ដើម្បី​មិន​ធ្វើ​គំនូរ​ខ្វៀក​វិញ។"
+
+msgid "WDS_TTRL_HEADER_TIPS_ABB"
+msgstr "បណ្ណែ"
+
+msgid "WDS_TTRL_BODY_AND_CLOCKWISE_TO_BRING_YOUR_DOODLE_BACK_ABB"
+msgstr "និង ទិស​ទ្រនិច​នាឡិកា​ដើម្បី​នាំយក​គំនូរ​ខ្វៀក​របស់​អ្នក​មក​វិញ។"
+
+msgid "WDS_IME_NPBODY_START_DOODLING_YOUR_MESSAGE_ABB"
+msgstr "ចាប់ផ្ដើម​គូសខ្វៀក​សារ​របស់​អ្នក"
+
+msgid "WDS_IME_POP_ARE_YOU_SURE_YOU_WANT_TO_DISCARD_YOUR_DRAWING_Q"
+msgstr "តើ​អ្នក​ប្រាកដ​ថា​អ្នក​ចង់​ចោល​ការគូស​របស់​អ្នក?"
+
+msgid "WDS_IME_NPBODY_START_DRAWING_YOUR_IMAGE_ABB"
+msgstr "ចាប់ផ្ដើម​គូស​រូប​របស់​អ្នក"
+
diff --git a/res/po/kn.po b/res/po/kn.po
new file mode 100755 (executable)
index 0000000..121f0ae
--- /dev/null
@@ -0,0 +1,33 @@
+msgid "WDS_IME_ACBUTTON_SEND"
+msgstr "ಕಳುಹಿಸಿ"
+
+msgid "WDS_WNOTI_POP_ALL_CHANGES_WILL_BE_DISCARDED"
+msgstr "ಎಲ್ಲ ಬದಲಾವಣೆಗಳನ್ನು ತ್ಯಜಿಸಲಾಗುವುದು."
+
+msgid "WDS_IME_NPBODY_START_DRAWING_M_EMOTICON_ABB"
+msgstr "ಡ್ರಾಯಿಂಗ್ ಪ್ರಾರಂಭಿಸಿ"
+
+msgid "WDS_MSG_SBODY_MMS_ABB"
+msgstr "MMS"
+
+msgid "WDS_IME_NPBODY_DRAW_YOUR_OWN_MESSAGE_ABB"
+msgstr "ನಿಮ್ಮ ಸ್ವಂತ ಸಂದೇಶವನ್ನು ಚಿತ್ರಿಸಿ"
+
+msgid "WDS_TTRL_BODY_TURN_THE_BEZEL_ANTICLOCKWISE_TO_UNDO_A_DOODLE_ABB"
+msgstr "ಡೂಡಲ್ ರದ್ದುಗೊಳಿಸಲು ಆಂಟಿಕ್ಲಾಕ್‍ವೈಸ್ ಆಗಿ ಬೆಜಲ್ ತಿರುಗಿಸಿ."
+
+msgid "WDS_TTRL_HEADER_TIPS_ABB"
+msgstr "ಸಲಹೆಗಳು"
+
+msgid "WDS_TTRL_BODY_AND_CLOCKWISE_TO_BRING_YOUR_DOODLE_BACK_ABB"
+msgstr "ಮತ್ತು ನಿಮ್ಮ ಡೂಡಲ್ ಹಿಂಪಡೆಯಲು ಕ್ಲಾಸ್‍ವೈಸ್ ತಿರುಗಿಸಿ."
+
+msgid "WDS_IME_NPBODY_START_DOODLING_YOUR_MESSAGE_ABB"
+msgstr "ನಿಮ್ಮ ಸಂದೇಶವನ್ನು ಡಾಡಲ್ ಮಾಡುವುದನ್ನು ಪ್ರಾರಂಭಿಸಿ"
+
+msgid "WDS_IME_POP_ARE_YOU_SURE_YOU_WANT_TO_DISCARD_YOUR_DRAWING_Q"
+msgstr "ನೀವು ಖಚಿತವಾಗಿಯೂ ನಿಮ್ಮ ಡ್ರಾಯಿಂಗ್ ತ್ಯಜಿಸಲು ಬಯಸುವಿರಾ?"
+
+msgid "WDS_IME_NPBODY_START_DRAWING_YOUR_IMAGE_ABB"
+msgstr "ನಿಮ್ಮ ಚಿತ್ರದ ಡ್ರಾಯಿಂಗ್ ಪ್ರಾರಂಭಿಸಿ"
+
diff --git a/res/po/ko_KR.po b/res/po/ko_KR.po
new file mode 100755 (executable)
index 0000000..4a90cd4
--- /dev/null
@@ -0,0 +1,33 @@
+msgid "WDS_IME_ACBUTTON_SEND"
+msgstr "보내기"
+
+msgid "WDS_WNOTI_POP_ALL_CHANGES_WILL_BE_DISCARDED"
+msgstr "변경사항을 저장하지 않습니다."
+
+msgid "WDS_IME_NPBODY_START_DRAWING_M_EMOTICON_ABB"
+msgstr "그리기 시작"
+
+msgid "WDS_MSG_SBODY_MMS_ABB"
+msgstr "MMS"
+
+msgid "WDS_IME_NPBODY_DRAW_YOUR_OWN_MESSAGE_ABB"
+msgstr "나만의 메세지를 그려서 보내세요"
+
+msgid "WDS_TTRL_BODY_TURN_THE_BEZEL_ANTICLOCKWISE_TO_UNDO_A_DOODLE_ABB"
+msgstr "그리기를 취소하려면 베젤을 반시계 방향으로 돌리세요."
+
+msgid "WDS_TTRL_HEADER_TIPS_ABB"
+msgstr "도움말"
+
+msgid "WDS_TTRL_BODY_AND_CLOCKWISE_TO_BRING_YOUR_DOODLE_BACK_ABB"
+msgstr "다시 보려면 시계 방향으로 돌리세요."
+
+msgid "WDS_IME_NPBODY_START_DOODLING_YOUR_MESSAGE_ABB"
+msgstr "메시지 그리기를 시작하세요"
+
+msgid "WDS_IME_POP_ARE_YOU_SURE_YOU_WANT_TO_DISCARD_YOUR_DRAWING_Q"
+msgstr "작성 중인 그리기를 취소할까요?"
+
+msgid "WDS_IME_NPBODY_START_DRAWING_YOUR_IMAGE_ABB"
+msgstr "이미지 그리기를 시작하세요"
+
diff --git a/res/po/ky_KG.po b/res/po/ky_KG.po
new file mode 100755 (executable)
index 0000000..0882062
--- /dev/null
@@ -0,0 +1,33 @@
+msgid "WDS_IME_ACBUTTON_SEND"
+msgstr "ЖӨНӨТҮҮ"
+
+msgid "WDS_WNOTI_POP_ALL_CHANGES_WILL_BE_DISCARDED"
+msgstr "Бардык өзгөртүүлөр четке кагылат."
+
+msgid "WDS_IME_NPBODY_START_DRAWING_M_EMOTICON_ABB"
+msgstr "Тартып баштоо"
+
+msgid "WDS_MSG_SBODY_MMS_ABB"
+msgstr "MMS"
+
+msgid "WDS_IME_NPBODY_DRAW_YOUR_OWN_MESSAGE_ABB"
+msgstr "Өзүңүздүн билдирүүңүздү тартыңыз"
+
+msgid "WDS_TTRL_BODY_TURN_THE_BEZEL_ANTICLOCKWISE_TO_UNDO_A_DOODLE_ABB"
+msgstr "Сүрөт. арт. кайт., тегерек. саат. жебе. каршы айлан."
+
+msgid "WDS_TTRL_HEADER_TIPS_ABB"
+msgstr "Жардам"
+
+msgid "WDS_TTRL_BODY_AND_CLOCKWISE_TO_BRING_YOUR_DOODLE_BACK_ABB"
+msgstr "Жана сүрөт. артка кайтаруу үчүн сааттын жебеси м-н."
+
+msgid "WDS_IME_NPBODY_START_DOODLING_YOUR_MESSAGE_ABB"
+msgstr "Билдирүүңүздү чиймелеп баштаңыз"
+
+msgid "WDS_IME_POP_ARE_YOU_SURE_YOU_WANT_TO_DISCARD_YOUR_DRAWING_Q"
+msgstr "Тарткан сүрөтүңүздү четке кагууну каалагандыгыңыз ыраспы?"
+
+msgid "WDS_IME_NPBODY_START_DRAWING_YOUR_IMAGE_ABB"
+msgstr "Сүрөтүңүздү тартууну баштаңыз"
+
diff --git a/res/po/lo.po b/res/po/lo.po
new file mode 100755 (executable)
index 0000000..e81b014
--- /dev/null
@@ -0,0 +1,33 @@
+msgid "WDS_IME_ACBUTTON_SEND"
+msgstr "ສົ່ງ"
+
+msgid "WDS_WNOTI_POP_ALL_CHANGES_WILL_BE_DISCARDED"
+msgstr "ການປ່ຽນແປງທັງໝົດຈະຖືກລຶບ."
+
+msgid "WDS_IME_NPBODY_START_DRAWING_M_EMOTICON_ABB"
+msgstr "ເລີ່ມຕົ້ນແຕ້ມ"
+
+msgid "WDS_MSG_SBODY_MMS_ABB"
+msgstr "MMS"
+
+msgid "WDS_IME_NPBODY_DRAW_YOUR_OWN_MESSAGE_ABB"
+msgstr "ແຕ້ມຂໍ້ຄວາມຂອງທ່ານເອງ"
+
+msgid "WDS_TTRL_BODY_TURN_THE_BEZEL_ANTICLOCKWISE_TO_UNDO_A_DOODLE_ABB"
+msgstr "ໝູນຂອບຕົວເລື່ອນກົງກັນກັບເຂັມໂມງເພື່ອຍົກເລີກເສັ້ນຂີດແຕ້ມ."
+
+msgid "WDS_TTRL_HEADER_TIPS_ABB"
+msgstr "ເຄັດລັບ"
+
+msgid "WDS_TTRL_BODY_AND_CLOCKWISE_TO_BRING_YOUR_DOODLE_BACK_ABB"
+msgstr "ແລະໝູນຕາມເຂັມໂມງເພື່ອນຳເອົາເສັ້ນທີ່ຂີດຂອງທ່ານກັບຄືນມາ."
+
+msgid "WDS_IME_NPBODY_START_DOODLING_YOUR_MESSAGE_ABB"
+msgstr "ເລີ່ມຕົ້ນຂຽນຂໍ້ຄວາມຂອງທ່ານ"
+
+msgid "WDS_IME_POP_ARE_YOU_SURE_YOU_WANT_TO_DISCARD_YOUR_DRAWING_Q"
+msgstr "ທ່ານແນ່ໃຈບໍວ່າທ່ານຕ້ອງການເອົາການແຕ້ມຂອງທ່ານຖິ້ມ?"
+
+msgid "WDS_IME_NPBODY_START_DRAWING_YOUR_IMAGE_ABB"
+msgstr "ເລີ່ມ​ການ​ແຕ້ມ​ຮູບ​ຂອງ​ທ່ານ"
+
diff --git a/res/po/lt.po b/res/po/lt.po
new file mode 100755 (executable)
index 0000000..189c277
--- /dev/null
@@ -0,0 +1,33 @@
+msgid "WDS_IME_ACBUTTON_SEND"
+msgstr "SIŲST"
+
+msgid "WDS_WNOTI_POP_ALL_CHANGES_WILL_BE_DISCARDED"
+msgstr "Visi pakeitimai bus panaikinti."
+
+msgid "WDS_IME_NPBODY_START_DRAWING_M_EMOTICON_ABB"
+msgstr "Pradėkite piešti"
+
+msgid "WDS_MSG_SBODY_MMS_ABB"
+msgstr "MMS"
+
+msgid "WDS_IME_NPBODY_DRAW_YOUR_OWN_MESSAGE_ABB"
+msgstr "Nupieškite savo žinutę"
+
+msgid "WDS_TTRL_BODY_TURN_THE_BEZEL_ANTICLOCKWISE_TO_UNDO_A_DOODLE_ABB"
+msgstr "Sukite rėmelį prieš laik. rod. ir anul. piešinį."
+
+msgid "WDS_TTRL_HEADER_TIPS_ABB"
+msgstr "Patarimai"
+
+msgid "WDS_TTRL_BODY_AND_CLOCKWISE_TO_BRING_YOUR_DOODLE_BACK_ABB"
+msgstr "Pagal laikr. rodyklę, kad vėl grąžintum. piešinį."
+
+msgid "WDS_IME_NPBODY_START_DOODLING_YOUR_MESSAGE_ABB"
+msgstr "Pradėkite rašyti žinutę ranka"
+
+msgid "WDS_IME_POP_ARE_YOU_SURE_YOU_WANT_TO_DISCARD_YOUR_DRAWING_Q"
+msgstr "Ar tikrai norite panaikinti piešinį?"
+
+msgid "WDS_IME_NPBODY_START_DRAWING_YOUR_IMAGE_ABB"
+msgstr "Pradėkite piešti vaizdą"
+
diff --git a/res/po/lv.po b/res/po/lv.po
new file mode 100755 (executable)
index 0000000..02fb372
--- /dev/null
@@ -0,0 +1,33 @@
+msgid "WDS_IME_ACBUTTON_SEND"
+msgstr "SŪTĪT"
+
+msgid "WDS_WNOTI_POP_ALL_CHANGES_WILL_BE_DISCARDED"
+msgstr "Visas izmaiņas tiks atmestas."
+
+msgid "WDS_IME_NPBODY_START_DRAWING_M_EMOTICON_ABB"
+msgstr "Sāciet zīmēt"
+
+msgid "WDS_MSG_SBODY_MMS_ABB"
+msgstr "MMS"
+
+msgid "WDS_IME_NPBODY_DRAW_YOUR_OWN_MESSAGE_ABB"
+msgstr "Uzzīmējiet savu ziņu"
+
+msgid "WDS_TTRL_BODY_TURN_THE_BEZEL_ANTICLOCKWISE_TO_UNDO_A_DOODLE_ABB"
+msgstr "Grieziet apli pa kreisi, lai atsauktu skici."
+
+msgid "WDS_TTRL_HEADER_TIPS_ABB"
+msgstr "Padomi"
+
+msgid "WDS_TTRL_BODY_AND_CLOCKWISE_TO_BRING_YOUR_DOODLE_BACK_ABB"
+msgstr "Un pulksteņrādītāja virzienā, lai atjaunotu skici."
+
+msgid "WDS_IME_NPBODY_START_DOODLING_YOUR_MESSAGE_ABB"
+msgstr "Sāciet zīmēt savu ziņu"
+
+msgid "WDS_IME_POP_ARE_YOU_SURE_YOU_WANT_TO_DISCARD_YOUR_DRAWING_Q"
+msgstr "Vai tiešām vēlaties atmest savu zīmējumu?"
+
+msgid "WDS_IME_NPBODY_START_DRAWING_YOUR_IMAGE_ABB"
+msgstr "Sāciet zīmēt savu attēlu"
+
diff --git a/res/po/mk.po b/res/po/mk.po
new file mode 100755 (executable)
index 0000000..e7befd2
--- /dev/null
@@ -0,0 +1,33 @@
+msgid "WDS_IME_ACBUTTON_SEND"
+msgstr "ПРАТИ"
+
+msgid "WDS_WNOTI_POP_ALL_CHANGES_WILL_BE_DISCARDED"
+msgstr "Сите промени ќе се отфрлат."
+
+msgid "WDS_IME_NPBODY_START_DRAWING_M_EMOTICON_ABB"
+msgstr "Почнете да цртате"
+
+msgid "WDS_MSG_SBODY_MMS_ABB"
+msgstr "MMS"
+
+msgid "WDS_IME_NPBODY_DRAW_YOUR_OWN_MESSAGE_ABB"
+msgstr "Нацртајте сопствена порака"
+
+msgid "WDS_TTRL_BODY_TURN_THE_BEZEL_ANTICLOCKWISE_TO_UNDO_A_DOODLE_ABB"
+msgstr "Свртете го лежиштето налево за да откажете цртеж."
+
+msgid "WDS_TTRL_HEADER_TIPS_ABB"
+msgstr "Совети"
+
+msgid "WDS_TTRL_BODY_AND_CLOCKWISE_TO_BRING_YOUR_DOODLE_BACK_ABB"
+msgstr "И надесно за да се врати Вашиот цртеж."
+
+msgid "WDS_IME_NPBODY_START_DOODLING_YOUR_MESSAGE_ABB"
+msgstr "Започнете да чкрткате на Вашата порака"
+
+msgid "WDS_IME_POP_ARE_YOU_SURE_YOU_WANT_TO_DISCARD_YOUR_DRAWING_Q"
+msgstr "Дали навистина сакате да го отфрлите Вашиот цртеж?"
+
+msgid "WDS_IME_NPBODY_START_DRAWING_YOUR_IMAGE_ABB"
+msgstr "Почнете да ја цртате сликата"
+
diff --git a/res/po/ml.po b/res/po/ml.po
new file mode 100755 (executable)
index 0000000..438bd28
--- /dev/null
@@ -0,0 +1,33 @@
+msgid "WDS_IME_ACBUTTON_SEND"
+msgstr "അയയ്‌ക്കുക"
+
+msgid "WDS_WNOTI_POP_ALL_CHANGES_WILL_BE_DISCARDED"
+msgstr "എല്ലാ മാറ്റങ്ങളും ഒഴിവാക്കപ്പെടും."
+
+msgid "WDS_IME_NPBODY_START_DRAWING_M_EMOTICON_ABB"
+msgstr "ഡ്രോയിംഗ് ആരംഭിക്കുക"
+
+msgid "WDS_MSG_SBODY_MMS_ABB"
+msgstr "MMS"
+
+msgid "WDS_IME_NPBODY_DRAW_YOUR_OWN_MESSAGE_ABB"
+msgstr "നിങ്ങളുടെ സ്വന്തം സന്ദേശം വരയ്ക്കുക"
+
+msgid "WDS_TTRL_BODY_TURN_THE_BEZEL_ANTICLOCKWISE_TO_UNDO_A_DOODLE_ABB"
+msgstr "ഒരു ഡൂഡിൽ വേണ്ടെന്ന് വയ്ക്കുന്നതിന് ബേസൽ അപ്രദക്ഷിണ ദിശയിൽ തിരിക്കുക."
+
+msgid "WDS_TTRL_HEADER_TIPS_ABB"
+msgstr "വിവരശകലങ്ങൾ"
+
+msgid "WDS_TTRL_BODY_AND_CLOCKWISE_TO_BRING_YOUR_DOODLE_BACK_ABB"
+msgstr "ഡൂഡിൽ തിരികെ കൊണ്ടുവരുന്നതിന് പ്രദക്ഷിണ ദിശയിൽ തിരിക്കുക."
+
+msgid "WDS_IME_NPBODY_START_DOODLING_YOUR_MESSAGE_ABB"
+msgstr "നിങ്ങളുടെ സന്ദേശം ഡൂഡിൽ ചെയ്യാനാരംഭിക്കുക"
+
+msgid "WDS_IME_POP_ARE_YOU_SURE_YOU_WANT_TO_DISCARD_YOUR_DRAWING_Q"
+msgstr "നിങ്ങളുടെ ഡ്രോയിംഗ് ഒഴിവാക്കണമെന്ന് നിങ്ങൾക്ക് തീർച്ചയാണോ?"
+
+msgid "WDS_IME_NPBODY_START_DRAWING_YOUR_IMAGE_ABB"
+msgstr "നിങ്ങളുടെ ചിത്രം വരയ്ക്കാനാരംഭിക്കുക"
+
diff --git a/res/po/mn_MN.po b/res/po/mn_MN.po
new file mode 100755 (executable)
index 0000000..0f51e11
--- /dev/null
@@ -0,0 +1,33 @@
+msgid "WDS_IME_ACBUTTON_SEND"
+msgstr "ИЛГЭЭ"
+
+msgid "WDS_WNOTI_POP_ALL_CHANGES_WILL_BE_DISCARDED"
+msgstr "Бүх өөрчлөлт орхигдоно."
+
+msgid "WDS_IME_NPBODY_START_DRAWING_M_EMOTICON_ABB"
+msgstr "Зурж эхлэх"
+
+msgid "WDS_MSG_SBODY_MMS_ABB"
+msgstr "MMS"
+
+msgid "WDS_IME_NPBODY_DRAW_YOUR_OWN_MESSAGE_ABB"
+msgstr "Өөрийн зурвасаа бичих"
+
+msgid "WDS_TTRL_BODY_TURN_THE_BEZEL_ANTICLOCKWISE_TO_UNDO_A_DOODLE_ABB"
+msgstr "Хөвөөг нар буруу эргүүлээд зургийн үйлдэл буцаана."
+
+msgid "WDS_TTRL_HEADER_TIPS_ABB"
+msgstr "Зөвлөмжүүд"
+
+msgid "WDS_TTRL_BODY_AND_CLOCKWISE_TO_BRING_YOUR_DOODLE_BACK_ABB"
+msgstr "Нар зөв эргүүлээд зургаа буцааж авчирна уу."
+
+msgid "WDS_IME_NPBODY_START_DOODLING_YOUR_MESSAGE_ABB"
+msgstr "Зурвасаа гараараа бичнэ үү"
+
+msgid "WDS_IME_POP_ARE_YOU_SURE_YOU_WANT_TO_DISCARD_YOUR_DRAWING_Q"
+msgstr "Та зургаа хадгалахгүй орхих уу?"
+
+msgid "WDS_IME_NPBODY_START_DRAWING_YOUR_IMAGE_ABB"
+msgstr "Зургаа зурж эхэл"
+
diff --git a/res/po/mr.po b/res/po/mr.po
new file mode 100755 (executable)
index 0000000..aa35be4
--- /dev/null
@@ -0,0 +1,33 @@
+msgid "WDS_IME_ACBUTTON_SEND"
+msgstr "पाठवा"
+
+msgid "WDS_WNOTI_POP_ALL_CHANGES_WILL_BE_DISCARDED"
+msgstr "सर्व बदल काढून टाकले जातील."
+
+msgid "WDS_IME_NPBODY_START_DRAWING_M_EMOTICON_ABB"
+msgstr "रेखांकन सुरू करा"
+
+msgid "WDS_MSG_SBODY_MMS_ABB"
+msgstr "MMS"
+
+msgid "WDS_IME_NPBODY_DRAW_YOUR_OWN_MESSAGE_ABB"
+msgstr "आपले स्‍वत:चे संदेश रेखाटा"
+
+msgid "WDS_TTRL_BODY_TURN_THE_BEZEL_ANTICLOCKWISE_TO_UNDO_A_DOODLE_ABB"
+msgstr "डूड्ल पूर्ववत करण्या साठी बेझल अ‍ॅंटीक्लॉकवाइज फिरवा."
+
+msgid "WDS_TTRL_HEADER_TIPS_ABB"
+msgstr "टिपा"
+
+msgid "WDS_TTRL_BODY_AND_CLOCKWISE_TO_BRING_YOUR_DOODLE_BACK_ABB"
+msgstr "आणि आपले डूडल परत आणण्यासाठी साठी क्लॉकवाइज."
+
+msgid "WDS_IME_NPBODY_START_DOODLING_YOUR_MESSAGE_ABB"
+msgstr "आपले संदेश डूडल करणे सुरू करा"
+
+msgid "WDS_IME_POP_ARE_YOU_SURE_YOU_WANT_TO_DISCARD_YOUR_DRAWING_Q"
+msgstr "आपण आपले रेखांकन रद्द करू इच्छित असल्याची आपल्याला खात्री आहे?"
+
+msgid "WDS_IME_NPBODY_START_DRAWING_YOUR_IMAGE_ABB"
+msgstr "आपली प्रतिमा रेखाटण्यास सुरूवात करा"
+
diff --git a/res/po/ms.po b/res/po/ms.po
new file mode 100755 (executable)
index 0000000..2fcd42c
--- /dev/null
@@ -0,0 +1,33 @@
+msgid "WDS_IME_ACBUTTON_SEND"
+msgstr "HANTAR"
+
+msgid "WDS_WNOTI_POP_ALL_CHANGES_WILL_BE_DISCARDED"
+msgstr "Semua perubahan akan dibuang."
+
+msgid "WDS_IME_NPBODY_START_DRAWING_M_EMOTICON_ABB"
+msgstr "Mula melukis"
+
+msgid "WDS_MSG_SBODY_MMS_ABB"
+msgstr "MMS"
+
+msgid "WDS_IME_NPBODY_DRAW_YOUR_OWN_MESSAGE_ABB"
+msgstr "Lukis mesej anda"
+
+msgid "WDS_TTRL_BODY_TURN_THE_BEZEL_ANTICLOCKWISE_TO_UNDO_A_DOODLE_ABB"
+msgstr "Putar bezel lawan arah jam utk buat asal contengan."
+
+msgid "WDS_TTRL_HEADER_TIPS_ABB"
+msgstr "Petua"
+
+msgid "WDS_TTRL_BODY_AND_CLOCKWISE_TO_BRING_YOUR_DOODLE_BACK_ABB"
+msgstr "Dan ikut arah jam untuk kembalikan contengan anda."
+
+msgid "WDS_IME_NPBODY_START_DOODLING_YOUR_MESSAGE_ABB"
+msgstr "Mula mencoret mesej anda"
+
+msgid "WDS_IME_POP_ARE_YOU_SURE_YOU_WANT_TO_DISCARD_YOUR_DRAWING_Q"
+msgstr "Adakah anda pasti anda ingin membuang lukisan anda?"
+
+msgid "WDS_IME_NPBODY_START_DRAWING_YOUR_IMAGE_ABB"
+msgstr "Mula melukis imej anda"
+
diff --git a/res/po/my_MM.po b/res/po/my_MM.po
new file mode 100755 (executable)
index 0000000..ffafe35
--- /dev/null
@@ -0,0 +1,33 @@
+msgid "WDS_IME_ACBUTTON_SEND"
+msgstr "ပို့ပါ"
+
+msgid "WDS_WNOTI_POP_ALL_CHANGES_WILL_BE_DISCARDED"
+msgstr "ပြောင်းလဲမှုများအားလုံးကို ဖယ်ထုတ်သွားမည်။"
+
+msgid "WDS_IME_NPBODY_START_DRAWING_M_EMOTICON_ABB"
+msgstr "ပုံ စဆွဲပါ"
+
+msgid "WDS_MSG_SBODY_MMS_ABB"
+msgstr "MMS"
+
+msgid "WDS_IME_NPBODY_DRAW_YOUR_OWN_MESSAGE_ABB"
+msgstr "သင့်ကိုယ်ပိုင်မက်ဆေ့ချ်ကို ပုံဆွဲပါ"
+
+msgid "WDS_TTRL_BODY_TURN_THE_BEZEL_ANTICLOCKWISE_TO_UNDO_A_DOODLE_ABB"
+msgstr "တောင်ခြစ်မြောက်ခြစ်ပုံကို မလုပ်တော့ရန် ဘီဇယ်ကွင်းကို လက်ဝဲရစ် လှည့်ပါ။"
+
+msgid "WDS_TTRL_HEADER_TIPS_ABB"
+msgstr "အကြံပြုချက်များ"
+
+msgid "WDS_TTRL_BODY_AND_CLOCKWISE_TO_BRING_YOUR_DOODLE_BACK_ABB"
+msgstr "ပြီးလျှင် တောင်ခြစ်မြောက်ခြစ်ပုံသို့ ပြန်သွားရန် လက်ယာရစ်လှည့်ပါ။"
+
+msgid "WDS_IME_NPBODY_START_DOODLING_YOUR_MESSAGE_ABB"
+msgstr "သင့်မက်ဆေ့ချက်ကို ဆွဲပါ"
+
+msgid "WDS_IME_POP_ARE_YOU_SURE_YOU_WANT_TO_DISCARD_YOUR_DRAWING_Q"
+msgstr "သင်ဆွဲထားသော ပုံကို စွန့်ပစ်လိုသည်မှာ သေချာသလား?"
+
+msgid "WDS_IME_NPBODY_START_DRAWING_YOUR_IMAGE_ABB"
+msgstr "သင့်ရုပ်ပုံကို စတင်ရေးဆွဲပါ"
+
diff --git a/res/po/my_ZG.po b/res/po/my_ZG.po
new file mode 100755 (executable)
index 0000000..e4e2a27
--- /dev/null
@@ -0,0 +1,33 @@
+msgid "WDS_IME_ACBUTTON_SEND"
+msgstr "ပို႔ပါ"
+
+msgid "WDS_WNOTI_POP_ALL_CHANGES_WILL_BE_DISCARDED"
+msgstr "ေျပာင္းလဲမႈမ်ားအားလုံးကို ဖယ္ထုတ္သြားမည္။"
+
+msgid "WDS_IME_NPBODY_START_DRAWING_M_EMOTICON_ABB"
+msgstr "ပံု စဆြဲပါ"
+
+msgid "WDS_MSG_SBODY_MMS_ABB"
+msgstr "MMS"
+
+msgid "WDS_IME_NPBODY_DRAW_YOUR_OWN_MESSAGE_ABB"
+msgstr "သင့္ကိုယ္ပိုင္မက္ေဆ့ခ်္ကို ပုံဆြဲပါ"
+
+msgid "WDS_TTRL_BODY_TURN_THE_BEZEL_ANTICLOCKWISE_TO_UNDO_A_DOODLE_ABB"
+msgstr "ေတာင္ျခစ္ေျမာက္ျခစ္ပုံကို မလုပ္ေတာ့ရန္ ဘီဇယ္ကြင္းကို လက္ဝဲရစ္ လွည့္ပါ။"
+
+msgid "WDS_TTRL_HEADER_TIPS_ABB"
+msgstr "အႀကံျပဳခ်က္မ်ား"
+
+msgid "WDS_TTRL_BODY_AND_CLOCKWISE_TO_BRING_YOUR_DOODLE_BACK_ABB"
+msgstr "ၿပီးလွ်င္ ေတာင္ျခစ္ေျမာက္ျခစ္ပုံသို႔ ျပန္သြားရန္ လက္ယာရစ္လွည့္ပါ။"
+
+msgid "WDS_IME_NPBODY_START_DOODLING_YOUR_MESSAGE_ABB"
+msgstr "သင့္မက္ေဆ့ခ်က္ကုိ ဆြဲပါ"
+
+msgid "WDS_IME_POP_ARE_YOU_SURE_YOU_WANT_TO_DISCARD_YOUR_DRAWING_Q"
+msgstr "သင္ဆြဲထားေသာ ပုံကို စြန္႔ပစ္လိုသည္မွာ ေသခ်ာသလား?"
+
+msgid "WDS_IME_NPBODY_START_DRAWING_YOUR_IMAGE_ABB"
+msgstr "သင့္႐ုပ္ပုံကို စတင္ေရးဆြဲပါ"
+
diff --git a/res/po/nb.po b/res/po/nb.po
new file mode 100755 (executable)
index 0000000..b9a5b41
--- /dev/null
@@ -0,0 +1,33 @@
+msgid "WDS_IME_ACBUTTON_SEND"
+msgstr "SEND"
+
+msgid "WDS_WNOTI_POP_ALL_CHANGES_WILL_BE_DISCARDED"
+msgstr "Alle endringer blir forkastet."
+
+msgid "WDS_IME_NPBODY_START_DRAWING_M_EMOTICON_ABB"
+msgstr "Begynn å tegne"
+
+msgid "WDS_MSG_SBODY_MMS_ABB"
+msgstr "MMS"
+
+msgid "WDS_IME_NPBODY_DRAW_YOUR_OWN_MESSAGE_ABB"
+msgstr "Tegn din egen melding"
+
+msgid "WDS_TTRL_BODY_TURN_THE_BEZEL_ANTICLOCKWISE_TO_UNDO_A_DOODLE_ABB"
+msgstr "Vri rammen mot klokken for å angre en krusedull."
+
+msgid "WDS_TTRL_HEADER_TIPS_ABB"
+msgstr "Tips"
+
+msgid "WDS_TTRL_BODY_AND_CLOCKWISE_TO_BRING_YOUR_DOODLE_BACK_ABB"
+msgstr "Og med klokken for å hente tilbake krusedullen."
+
+msgid "WDS_IME_NPBODY_START_DOODLING_YOUR_MESSAGE_ABB"
+msgstr "Begynn å tegne meldingen"
+
+msgid "WDS_IME_POP_ARE_YOU_SURE_YOU_WANT_TO_DISCARD_YOUR_DRAWING_Q"
+msgstr "Er du sikker på at du vil forkaste tegningen?"
+
+msgid "WDS_IME_NPBODY_START_DRAWING_YOUR_IMAGE_ABB"
+msgstr "Begynn å tegne bildet"
+
diff --git a/res/po/ne.po b/res/po/ne.po
new file mode 100755 (executable)
index 0000000..f23b270
--- /dev/null
@@ -0,0 +1,33 @@
+msgid "WDS_IME_ACBUTTON_SEND"
+msgstr "पठाउनुहोस्"
+
+msgid "WDS_WNOTI_POP_ALL_CHANGES_WILL_BE_DISCARDED"
+msgstr "सबै परिवर्तनहरू खारेज गरिनेछ।"
+
+msgid "WDS_IME_NPBODY_START_DRAWING_M_EMOTICON_ABB"
+msgstr "रेखाचित्र सुरु गर्नु"
+
+msgid "WDS_MSG_SBODY_MMS_ABB"
+msgstr "MMS"
+
+msgid "WDS_IME_NPBODY_DRAW_YOUR_OWN_MESSAGE_ABB"
+msgstr "आफ्नो संदेश कोर्नुहोस्"
+
+msgid "WDS_TTRL_BODY_TURN_THE_BEZEL_ANTICLOCKWISE_TO_UNDO_A_DOODLE_ABB"
+msgstr "डुडललाई अनडु गर्न बेजललाई घडीको दिशामा घुमाउनु।"
+
+msgid "WDS_TTRL_HEADER_TIPS_ABB"
+msgstr "सुझावहरू"
+
+msgid "WDS_TTRL_BODY_AND_CLOCKWISE_TO_BRING_YOUR_DOODLE_BACK_ABB"
+msgstr "र आफ्नो डुडललाई फिर्ता ल्याउन घडीको दिशामा।"
+
+msgid "WDS_IME_NPBODY_START_DOODLING_YOUR_MESSAGE_ABB"
+msgstr "आफ्नो संदेश कोर्न सुरु गर्नुहेास्"
+
+msgid "WDS_IME_POP_ARE_YOU_SURE_YOU_WANT_TO_DISCARD_YOUR_DRAWING_Q"
+msgstr "तपाई पक्का आफ्नो रेखाचित्र खारेज गर्न चाहनुहुन्छ?"
+
+msgid "WDS_IME_NPBODY_START_DRAWING_YOUR_IMAGE_ABB"
+msgstr "आफ्नो छवि कोर्न सुरु गर्नुहोस्"
+
diff --git a/res/po/nl.po b/res/po/nl.po
new file mode 100755 (executable)
index 0000000..018749b
--- /dev/null
@@ -0,0 +1,33 @@
+msgid "WDS_IME_ACBUTTON_SEND"
+msgstr "VERZENDEN"
+
+msgid "WDS_WNOTI_POP_ALL_CHANGES_WILL_BE_DISCARDED"
+msgstr "Alle wijzigingen worden verwijderd."
+
+msgid "WDS_IME_NPBODY_START_DRAWING_M_EMOTICON_ABB"
+msgstr "Begin te tekenen"
+
+msgid "WDS_MSG_SBODY_MMS_ABB"
+msgstr "Mms"
+
+msgid "WDS_IME_NPBODY_DRAW_YOUR_OWN_MESSAGE_ABB"
+msgstr "Uw eigen bericht tekenen"
+
+msgid "WDS_TTRL_BODY_TURN_THE_BEZEL_ANTICLOCKWISE_TO_UNDO_A_DOODLE_ABB"
+msgstr "Draai de ring naar links om schets ongedaan te maken."
+
+msgid "WDS_TTRL_HEADER_TIPS_ABB"
+msgstr "Tips"
+
+msgid "WDS_TTRL_BODY_AND_CLOCKWISE_TO_BRING_YOUR_DOODLE_BACK_ABB"
+msgstr "En naar rechts om uw schets terug te brengen."
+
+msgid "WDS_IME_NPBODY_START_DOODLING_YOUR_MESSAGE_ABB"
+msgstr "Begin uw bericht te schetsen"
+
+msgid "WDS_IME_POP_ARE_YOU_SURE_YOU_WANT_TO_DISCARD_YOUR_DRAWING_Q"
+msgstr "Wilt u uw tekening verwijderen?"
+
+msgid "WDS_IME_NPBODY_START_DRAWING_YOUR_IMAGE_ABB"
+msgstr "Begin uw afbeelding te tekenen"
+
diff --git a/res/po/or.po b/res/po/or.po
new file mode 100755 (executable)
index 0000000..8662dd7
--- /dev/null
@@ -0,0 +1,33 @@
+msgid "WDS_IME_ACBUTTON_SEND"
+msgstr "ପ୍ରେରଣ"
+
+msgid "WDS_WNOTI_POP_ALL_CHANGES_WILL_BE_DISCARDED"
+msgstr "ସମସ୍ତ ପରିବର୍ତ୍ତନ ପ୍ରତ୍ୟାଖିତ ହେବ।"
+
+msgid "WDS_IME_NPBODY_START_DRAWING_M_EMOTICON_ABB"
+msgstr "ଚିତ୍ରାଙ୍କନ ଆରମ୍ଭ"
+
+msgid "WDS_MSG_SBODY_MMS_ABB"
+msgstr "MMS"
+
+msgid "WDS_IME_NPBODY_DRAW_YOUR_OWN_MESSAGE_ABB"
+msgstr "ଆପଣଙ୍କ ନିଜ ସନ୍ଦେଶ ଅଙ୍କନ"
+
+msgid "WDS_TTRL_BODY_TURN_THE_BEZEL_ANTICLOCKWISE_TO_UNDO_A_DOODLE_ABB"
+msgstr "ଏକ ଡୁଡ. ପୂର୍ବ. କରି. ବାମ. ବିଜେ. ଘୂର୍ଣ୍ଣ. କରନ୍ତୁ।"
+
+msgid "WDS_TTRL_HEADER_TIPS_ABB"
+msgstr "ଟିପ୍ପଣୀ"
+
+msgid "WDS_TTRL_BODY_AND_CLOCKWISE_TO_BRING_YOUR_DOODLE_BACK_ABB"
+msgstr "ଏବଂ ଆପଣଙ୍କ ଡୁଡ. ଫେରା. ଦକ୍ଷି. ଟର୍ନ୍ କରନ୍ତୁ।"
+
+msgid "WDS_IME_NPBODY_START_DOODLING_YOUR_MESSAGE_ABB"
+msgstr "ଆପଣଙ୍କ ସନ୍ଦେଶ ଡୁଡଲ୍ ଆରମ୍ଭ କରିବା"
+
+msgid "WDS_IME_POP_ARE_YOU_SURE_YOU_WANT_TO_DISCARD_YOUR_DRAWING_Q"
+msgstr "ଆପଣ ଆପଣଙ୍କ ଚିତ୍ରାଙ୍କନ ପ୍ରତ୍ୟାଖ୍ୟାନ କରିବାକୁ ଚାହୁଁଛନ୍ତି ନିଶ୍ଚିତ କି?"
+
+msgid "WDS_IME_NPBODY_START_DRAWING_YOUR_IMAGE_ABB"
+msgstr "ଆପଣଙ୍କ ଫଟୋ ଚିତ୍ରାଙ୍କନ କରିବା ଆରମ୍ଭ"
+
diff --git a/res/po/pa.po b/res/po/pa.po
new file mode 100755 (executable)
index 0000000..0026117
--- /dev/null
@@ -0,0 +1,33 @@
+msgid "WDS_IME_ACBUTTON_SEND"
+msgstr "ਭੇਜੋ"
+
+msgid "WDS_WNOTI_POP_ALL_CHANGES_WILL_BE_DISCARDED"
+msgstr "ਸਭ ਬਦਲਾਵ ਖਾਰਿਜ ਹੋ ਜਾਣਗੇ।"
+
+msgid "WDS_IME_NPBODY_START_DRAWING_M_EMOTICON_ABB"
+msgstr "ਡ੍ਰਾਇੰਗ ਸ਼ੁਰੂ ਕਰੋ"
+
+msgid "WDS_MSG_SBODY_MMS_ABB"
+msgstr "MMS"
+
+msgid "WDS_IME_NPBODY_DRAW_YOUR_OWN_MESSAGE_ABB"
+msgstr "ਆਪਣੇ ਖੁਦ ਦੇ ਸੰਦੇਸ਼ ਬਣਾਉ"
+
+msgid "WDS_TTRL_BODY_TURN_THE_BEZEL_ANTICLOCKWISE_TO_UNDO_A_DOODLE_ABB"
+msgstr "ਡੂਡਲ ਨੂੰ ਰੱਦ ਕਰਨ ਲਈ ਬੇਜ਼ਲ ਨੂੰ ਐਂਟੀਕਲੌਕਵਾਇਜ਼ ਘੁਮਾਉ।"
+
+msgid "WDS_TTRL_HEADER_TIPS_ABB"
+msgstr "ਯੁਕਤੀਆਂ"
+
+msgid "WDS_TTRL_BODY_AND_CLOCKWISE_TO_BRING_YOUR_DOODLE_BACK_ABB"
+msgstr "ਅਤੇ ਆਪਣੇ ਡੂਡਲ ਨੂੰ ਵਾਪਸ ਲਿਆਉਣ ਲਈ ਕਲੌਕਵਾਇਜ਼ ਘੁਮਾਉ।"
+
+msgid "WDS_IME_NPBODY_START_DOODLING_YOUR_MESSAGE_ABB"
+msgstr "ਆਪਣੇ ਸੰਦੇਸ਼ ਨੂੰ ਡੂਡਲ ਕਰਨਾ ਸ਼ੁਰੂ ਕਰੋ"
+
+msgid "WDS_IME_POP_ARE_YOU_SURE_YOU_WANT_TO_DISCARD_YOUR_DRAWING_Q"
+msgstr "ਕੀ ਤੁਹਾਨੂੰ ਯਕੀਨ ਹੈ ਕਿ ਤੁਸੀਂ ਆਪਣੀ ਡ੍ਰਾਇੰਗ ਨੂੰ ਖਾਰਿਜ ਕਰਨਾ ਚਾਹੁੰਦੇ ਹੋ?"
+
+msgid "WDS_IME_NPBODY_START_DRAWING_YOUR_IMAGE_ABB"
+msgstr "ਆਪਣਾ ਚਿੱਤਰ ਡ੍ਰਾਅ ਕਰਨਾ ਸ਼ੁਰੂ ਕਰੋ"
+
diff --git a/res/po/pl.po b/res/po/pl.po
new file mode 100755 (executable)
index 0000000..150257c
--- /dev/null
@@ -0,0 +1,33 @@
+msgid "WDS_IME_ACBUTTON_SEND"
+msgstr "WYŚLIJ"
+
+msgid "WDS_WNOTI_POP_ALL_CHANGES_WILL_BE_DISCARDED"
+msgstr "Wszystkie zmiany zostaną odrzucone."
+
+msgid "WDS_IME_NPBODY_START_DRAWING_M_EMOTICON_ABB"
+msgstr "Rozp. rysowanie"
+
+msgid "WDS_MSG_SBODY_MMS_ABB"
+msgstr "MMS"
+
+msgid "WDS_IME_NPBODY_DRAW_YOUR_OWN_MESSAGE_ABB"
+msgstr "Narysuj własną wiadomość"
+
+msgid "WDS_TTRL_BODY_TURN_THE_BEZEL_ANTICLOCKWISE_TO_UNDO_A_DOODLE_ABB"
+msgstr "Obróć ramkę w lewo, aby anulować rysunek."
+
+msgid "WDS_TTRL_HEADER_TIPS_ABB"
+msgstr "Wskazówki"
+
+msgid "WDS_TTRL_BODY_AND_CLOCKWISE_TO_BRING_YOUR_DOODLE_BACK_ABB"
+msgstr "Natomiast w prawo, aby przywrócić rysunek."
+
+msgid "WDS_IME_NPBODY_START_DOODLING_YOUR_MESSAGE_ABB"
+msgstr "Zacznij rysować wiadomość"
+
+msgid "WDS_IME_POP_ARE_YOU_SURE_YOU_WANT_TO_DISCARD_YOUR_DRAWING_Q"
+msgstr "Czy na pewno chcesz odrzucić rysunek?"
+
+msgid "WDS_IME_NPBODY_START_DRAWING_YOUR_IMAGE_ABB"
+msgstr "Zacznij rysować obraz"
+
diff --git a/res/po/pl_SP.po b/res/po/pl_SP.po
new file mode 100755 (executable)
index 0000000..1827c71
--- /dev/null
@@ -0,0 +1,33 @@
+msgid "WDS_IME_ACBUTTON_SEND"
+msgstr "POŚLIJ"
+
+msgid "WDS_WNOTI_POP_ALL_CHANGES_WILL_BE_DISCARDED"
+msgstr "Wszyjske zmiany ôstanōm ôdciepniynte."
+
+msgid "WDS_IME_NPBODY_START_DRAWING_M_EMOTICON_ABB"
+msgstr "Sztart. szkryflanie"
+
+msgid "WDS_MSG_SBODY_MMS_ABB"
+msgstr "MMS"
+
+msgid "WDS_IME_NPBODY_DRAW_YOUR_OWN_MESSAGE_ABB"
+msgstr "Naszkryflej swoja wiadōmoś"
+
+msgid "WDS_TTRL_BODY_TURN_THE_BEZEL_ANTICLOCKWISE_TO_UNDO_A_DOODLE_ABB"
+msgstr "Zwyrtnij rōmka na lewo, coby pociepać szkryflōnek."
+
+msgid "WDS_TTRL_HEADER_TIPS_ABB"
+msgstr "Dorady"
+
+msgid "WDS_TTRL_BODY_AND_CLOCKWISE_TO_BRING_YOUR_DOODLE_BACK_ABB"
+msgstr "Zajś na prawo, coby dać nazŏd szkryflōnek."
+
+msgid "WDS_IME_NPBODY_START_DOODLING_YOUR_MESSAGE_ABB"
+msgstr "Sztartnij szkryflać wiadōmoś"
+
+msgid "WDS_IME_POP_ARE_YOU_SURE_YOU_WANT_TO_DISCARD_YOUR_DRAWING_Q"
+msgstr "Eli na zicher chcesz ôdciepać szkryflōnek?"
+
+msgid "WDS_IME_NPBODY_START_DRAWING_YOUR_IMAGE_ABB"
+msgstr "Zacznij rysować obraz"
+
diff --git a/res/po/pt_BR.po b/res/po/pt_BR.po
new file mode 100755 (executable)
index 0000000..e106d4f
--- /dev/null
@@ -0,0 +1,33 @@
+msgid "WDS_IME_ACBUTTON_SEND"
+msgstr "ENVIAR"
+
+msgid "WDS_WNOTI_POP_ALL_CHANGES_WILL_BE_DISCARDED"
+msgstr "Todas as alterações serão descartadas."
+
+msgid "WDS_IME_NPBODY_START_DRAWING_M_EMOTICON_ABB"
+msgstr "Iniciar desenho"
+
+msgid "WDS_MSG_SBODY_MMS_ABB"
+msgstr "MMS"
+
+msgid "WDS_IME_NPBODY_DRAW_YOUR_OWN_MESSAGE_ABB"
+msgstr "Desenhar sua própria mensagem"
+
+msgid "WDS_TTRL_BODY_TURN_THE_BEZEL_ANTICLOCKWISE_TO_UNDO_A_DOODLE_ABB"
+msgstr "Gire canto sent. anti-horário p/ desfazer rabisco."
+
+msgid "WDS_TTRL_HEADER_TIPS_ABB"
+msgstr "Dicas"
+
+msgid "WDS_TTRL_BODY_AND_CLOCKWISE_TO_BRING_YOUR_DOODLE_BACK_ABB"
+msgstr "E no sentido horário para refazer o seu rabisco."
+
+msgid "WDS_IME_NPBODY_START_DOODLING_YOUR_MESSAGE_ABB"
+msgstr "Comece a rabiscar sua mensagem"
+
+msgid "WDS_IME_POP_ARE_YOU_SURE_YOU_WANT_TO_DISCARD_YOUR_DRAWING_Q"
+msgstr "Tem certeza de que deseja descartar seu desenho?"
+
+msgid "WDS_IME_NPBODY_START_DRAWING_YOUR_IMAGE_ABB"
+msgstr "Começar a desenhar sua imagem"
+
diff --git a/res/po/pt_PT.po b/res/po/pt_PT.po
new file mode 100755 (executable)
index 0000000..750b112
--- /dev/null
@@ -0,0 +1,33 @@
+msgid "WDS_IME_ACBUTTON_SEND"
+msgstr "ENVIAR"
+
+msgid "WDS_WNOTI_POP_ALL_CHANGES_WILL_BE_DISCARDED"
+msgstr "As alterações serão todas eliminadas."
+
+msgid "WDS_IME_NPBODY_START_DRAWING_M_EMOTICON_ABB"
+msgstr "Começar a desenhar"
+
+msgid "WDS_MSG_SBODY_MMS_ABB"
+msgstr "MMS"
+
+msgid "WDS_IME_NPBODY_DRAW_YOUR_OWN_MESSAGE_ABB"
+msgstr "Desenhe a sua mensagem"
+
+msgid "WDS_TTRL_BODY_TURN_THE_BEZEL_ANTICLOCKWISE_TO_UNDO_A_DOODLE_ABB"
+msgstr "Rode aro para a esquerda para desfazer um rabisco."
+
+msgid "WDS_TTRL_HEADER_TIPS_ABB"
+msgstr "Dicas"
+
+msgid "WDS_TTRL_BODY_AND_CLOCKWISE_TO_BRING_YOUR_DOODLE_BACK_ABB"
+msgstr "E para a direita para refazer o seu rabisco."
+
+msgid "WDS_IME_NPBODY_START_DOODLING_YOUR_MESSAGE_ABB"
+msgstr "Começar a rabiscar a sua mensagem"
+
+msgid "WDS_IME_POP_ARE_YOU_SURE_YOU_WANT_TO_DISCARD_YOUR_DRAWING_Q"
+msgstr "Tem a certeza de que pretende eliminar o seu desenho?"
+
+msgid "WDS_IME_NPBODY_START_DRAWING_YOUR_IMAGE_ABB"
+msgstr "Começar a desenhar a sua imagem"
+
diff --git a/res/po/ro.po b/res/po/ro.po
new file mode 100755 (executable)
index 0000000..eb477ff
--- /dev/null
@@ -0,0 +1,33 @@
+msgid "WDS_IME_ACBUTTON_SEND"
+msgstr "TRIMITERE"
+
+msgid "WDS_WNOTI_POP_ALL_CHANGES_WILL_BE_DISCARDED"
+msgstr "Toate schimbările vor fi anulate."
+
+msgid "WDS_IME_NPBODY_START_DRAWING_M_EMOTICON_ABB"
+msgstr "Încep. să desenați"
+
+msgid "WDS_MSG_SBODY_MMS_ABB"
+msgstr "MMS"
+
+msgid "WDS_IME_NPBODY_DRAW_YOUR_OWN_MESSAGE_ABB"
+msgstr "Desenați propriul mesaj"
+
+msgid "WDS_TTRL_BODY_TURN_THE_BEZEL_ANTICLOCKWISE_TO_UNDO_A_DOODLE_ABB"
+msgstr "Rotiți rama spre stânga pentru a anula un desen."
+
+msgid "WDS_TTRL_HEADER_TIPS_ABB"
+msgstr "Sfaturi"
+
+msgid "WDS_TTRL_BODY_AND_CLOCKWISE_TO_BRING_YOUR_DOODLE_BACK_ABB"
+msgstr "Și spre dreapta pentru a readuce desenul."
+
+msgid "WDS_IME_NPBODY_START_DOODLING_YOUR_MESSAGE_ABB"
+msgstr "Începeți să desenați mesajul"
+
+msgid "WDS_IME_POP_ARE_YOU_SURE_YOU_WANT_TO_DISCARD_YOUR_DRAWING_Q"
+msgstr "Sigur doriţi să anulați desenul?"
+
+msgid "WDS_IME_NPBODY_START_DRAWING_YOUR_IMAGE_ABB"
+msgstr "Începeți să desenați imaginea"
+
diff --git a/res/po/ru_RU.po b/res/po/ru_RU.po
new file mode 100755 (executable)
index 0000000..c165e8c
--- /dev/null
@@ -0,0 +1,33 @@
+msgid "WDS_IME_ACBUTTON_SEND"
+msgstr "ОТПРАВИТЬ"
+
+msgid "WDS_WNOTI_POP_ALL_CHANGES_WILL_BE_DISCARDED"
+msgstr "Все изменения будут отменены."
+
+msgid "WDS_IME_NPBODY_START_DRAWING_M_EMOTICON_ABB"
+msgstr "Начните рисовать"
+
+msgid "WDS_MSG_SBODY_MMS_ABB"
+msgstr "MMS"
+
+msgid "WDS_IME_NPBODY_DRAW_YOUR_OWN_MESSAGE_ABB"
+msgstr "Нарисуйте свое собственное сообщение"
+
+msgid "WDS_TTRL_BODY_TURN_THE_BEZEL_ANTICLOCKWISE_TO_UNDO_A_DOODLE_ABB"
+msgstr "Чтобы удалить рисунок, поверните кольцо против ЧС."
+
+msgid "WDS_TTRL_HEADER_TIPS_ABB"
+msgstr "Советы"
+
+msgid "WDS_TTRL_BODY_AND_CLOCKWISE_TO_BRING_YOUR_DOODLE_BACK_ABB"
+msgstr "И по часовой стрелке, чтобы вернуть ваш рисунок."
+
+msgid "WDS_IME_NPBODY_START_DOODLING_YOUR_MESSAGE_ABB"
+msgstr "Начните рисовать свое сообщение"
+
+msgid "WDS_IME_POP_ARE_YOU_SURE_YOU_WANT_TO_DISCARD_YOUR_DRAWING_Q"
+msgstr "Действительно не сохранять рисунок?"
+
+msgid "WDS_IME_NPBODY_START_DRAWING_YOUR_IMAGE_ABB"
+msgstr "Начните рисовать рисунок"
+
diff --git a/res/po/si.po b/res/po/si.po
new file mode 100755 (executable)
index 0000000..450b1b7
--- /dev/null
@@ -0,0 +1,33 @@
+msgid "WDS_IME_ACBUTTON_SEND"
+msgstr "යවන්න"
+
+msgid "WDS_WNOTI_POP_ALL_CHANGES_WILL_BE_DISCARDED"
+msgstr "වෙනස්කම් සියල්ල බැහැර කෙරෙනු ඇත."
+
+msgid "WDS_IME_NPBODY_START_DRAWING_M_EMOTICON_ABB"
+msgstr "ඇඳීම අරඹන්න"
+
+msgid "WDS_MSG_SBODY_MMS_ABB"
+msgstr "MMS"
+
+msgid "WDS_IME_NPBODY_DRAW_YOUR_OWN_MESSAGE_ABB"
+msgstr "තමාගේ පණිවිඩය අඳින්න"
+
+msgid "WDS_TTRL_BODY_TURN_THE_BEZEL_ANTICLOCKWISE_TO_UNDO_A_DOODLE_ABB"
+msgstr "ඩූඩලයක් පසුගමනය කිරීමට බෙසලය වාමාවර්තව හරවන්න."
+
+msgid "WDS_TTRL_HEADER_TIPS_ABB"
+msgstr "ඉඟි"
+
+msgid "WDS_TTRL_BODY_AND_CLOCKWISE_TO_BRING_YOUR_DOODLE_BACK_ABB"
+msgstr "ඔබේ ඩූඩලය ආපසු ගෙන ඒමට දක්ෂිණාවර්ත කරන්න."
+
+msgid "WDS_IME_NPBODY_START_DOODLING_YOUR_MESSAGE_ABB"
+msgstr "ඔබේ පණිවිඩය කුරුටුගෑම අරඹන්න"
+
+msgid "WDS_IME_POP_ARE_YOU_SURE_YOU_WANT_TO_DISCARD_YOUR_DRAWING_Q"
+msgstr "ඔබට ඔබේ ඇඳීම ඉවත දැමිය යුතු බව විශ්වාස ද?"
+
+msgid "WDS_IME_NPBODY_START_DRAWING_YOUR_IMAGE_ABB"
+msgstr "ඔබේ අනුරුව ඇඳීම අරඹන්න"
+
diff --git a/res/po/sk.po b/res/po/sk.po
new file mode 100755 (executable)
index 0000000..7ecf846
--- /dev/null
@@ -0,0 +1,33 @@
+msgid "WDS_IME_ACBUTTON_SEND"
+msgstr "ODOSLAŤ"
+
+msgid "WDS_WNOTI_POP_ALL_CHANGES_WILL_BE_DISCARDED"
+msgstr "Všetky zmeny sa zahodia."
+
+msgid "WDS_IME_NPBODY_START_DRAWING_M_EMOTICON_ABB"
+msgstr "Začnite kresliť"
+
+msgid "WDS_MSG_SBODY_MMS_ABB"
+msgstr "MMS"
+
+msgid "WDS_IME_NPBODY_DRAW_YOUR_OWN_MESSAGE_ABB"
+msgstr "Nakreslite svoju správu"
+
+msgid "WDS_TTRL_BODY_TURN_THE_BEZEL_ANTICLOCKWISE_TO_UNDO_A_DOODLE_ABB"
+msgstr "Otočením lunety doľava môžete zrušiť kresbu."
+
+msgid "WDS_TTRL_HEADER_TIPS_ABB"
+msgstr "Tipy"
+
+msgid "WDS_TTRL_BODY_AND_CLOCKWISE_TO_BRING_YOUR_DOODLE_BACK_ABB"
+msgstr "A v smere hodinových ručičiek vrátite kresbu späť."
+
+msgid "WDS_IME_NPBODY_START_DOODLING_YOUR_MESSAGE_ABB"
+msgstr "Začnite kresliť správu"
+
+msgid "WDS_IME_POP_ARE_YOU_SURE_YOU_WANT_TO_DISCARD_YOUR_DRAWING_Q"
+msgstr "Naozaj chcete zahodiť túto kresbu?"
+
+msgid "WDS_IME_NPBODY_START_DRAWING_YOUR_IMAGE_ABB"
+msgstr "Začnite kresliť obrázok"
+
diff --git a/res/po/sl.po b/res/po/sl.po
new file mode 100755 (executable)
index 0000000..da6b338
--- /dev/null
@@ -0,0 +1,33 @@
+msgid "WDS_IME_ACBUTTON_SEND"
+msgstr "POŠLJI"
+
+msgid "WDS_WNOTI_POP_ALL_CHANGES_WILL_BE_DISCARDED"
+msgstr "Vse spremembe bodo zavržene."
+
+msgid "WDS_IME_NPBODY_START_DRAWING_M_EMOTICON_ABB"
+msgstr "Začnite risati"
+
+msgid "WDS_MSG_SBODY_MMS_ABB"
+msgstr "MMS"
+
+msgid "WDS_IME_NPBODY_DRAW_YOUR_OWN_MESSAGE_ABB"
+msgstr "Narišite svoje sporočilo"
+
+msgid "WDS_TTRL_BODY_TURN_THE_BEZEL_ANTICLOCKWISE_TO_UNDO_A_DOODLE_ABB"
+msgstr "Za razveljavitev čečkarije zavrtite okvir v levo."
+
+msgid "WDS_TTRL_HEADER_TIPS_ABB"
+msgstr "Nasveti"
+
+msgid "WDS_TTRL_BODY_AND_CLOCKWISE_TO_BRING_YOUR_DOODLE_BACK_ABB"
+msgstr "In v desno, da se vaša čečkarija znova prikaže."
+
+msgid "WDS_IME_NPBODY_START_DOODLING_YOUR_MESSAGE_ABB"
+msgstr "Začnite čečkati svoje sporočilo"
+
+msgid "WDS_IME_POP_ARE_YOU_SURE_YOU_WANT_TO_DISCARD_YOUR_DRAWING_Q"
+msgstr "Ste prepričani, da želite zavreči risanje?"
+
+msgid "WDS_IME_NPBODY_START_DRAWING_YOUR_IMAGE_ABB"
+msgstr "Začnite risati svojo sliko"
+
diff --git a/res/po/sq.po b/res/po/sq.po
new file mode 100755 (executable)
index 0000000..4bb6a97
--- /dev/null
@@ -0,0 +1,33 @@
+msgid "WDS_IME_ACBUTTON_SEND"
+msgstr "DËRGO"
+
+msgid "WDS_WNOTI_POP_ALL_CHANGES_WILL_BE_DISCARDED"
+msgstr "Gjithë ndryshimet do shpërfillen."
+
+msgid "WDS_IME_NPBODY_START_DRAWING_M_EMOTICON_ABB"
+msgstr "Nis të vizatosh"
+
+msgid "WDS_MSG_SBODY_MMS_ABB"
+msgstr "MMS"
+
+msgid "WDS_IME_NPBODY_DRAW_YOUR_OWN_MESSAGE_ABB"
+msgstr "Vizato mesazhin tënd"
+
+msgid "WDS_TTRL_BODY_TURN_THE_BEZEL_ANTICLOCKWISE_TO_UNDO_A_DOODLE_ABB"
+msgstr "Rrotullo unazën në dr. kundërorar për të zhbërë."
+
+msgid "WDS_TTRL_HEADER_TIPS_ABB"
+msgstr "Këshilla"
+
+msgid "WDS_TTRL_BODY_AND_CLOCKWISE_TO_BRING_YOUR_DOODLE_BACK_ABB"
+msgstr "Dhe në drejtim orar për ta rikthyer vizatimin."
+
+msgid "WDS_IME_NPBODY_START_DOODLING_YOUR_MESSAGE_ABB"
+msgstr "Fillo ta shkruash me dorë mesazhin"
+
+msgid "WDS_IME_POP_ARE_YOU_SURE_YOU_WANT_TO_DISCARD_YOUR_DRAWING_Q"
+msgstr "Vërtet dëshiron ta hedhësh tej vizatimin?"
+
+msgid "WDS_IME_NPBODY_START_DRAWING_YOUR_IMAGE_ABB"
+msgstr "Fillo ta vizatosh imazhin"
+
diff --git a/res/po/sr.po b/res/po/sr.po
new file mode 100755 (executable)
index 0000000..b88908f
--- /dev/null
@@ -0,0 +1,33 @@
+msgid "WDS_IME_ACBUTTON_SEND"
+msgstr "ŠALJI"
+
+msgid "WDS_WNOTI_POP_ALL_CHANGES_WILL_BE_DISCARDED"
+msgstr "Sve promene će biti odbačene."
+
+msgid "WDS_IME_NPBODY_START_DRAWING_M_EMOTICON_ABB"
+msgstr "Započni crtež"
+
+msgid "WDS_MSG_SBODY_MMS_ABB"
+msgstr "MMS"
+
+msgid "WDS_IME_NPBODY_DRAW_YOUR_OWN_MESSAGE_ABB"
+msgstr "Nacrtajte ličnu poruku"
+
+msgid "WDS_TTRL_BODY_TURN_THE_BEZEL_ANTICLOCKWISE_TO_UNDO_A_DOODLE_ABB"
+msgstr "Okr. okvir u smeru nalevo i opozovite škrabotinu."
+
+msgid "WDS_TTRL_HEADER_TIPS_ABB"
+msgstr "Saveti"
+
+msgid "WDS_TTRL_BODY_AND_CLOCKWISE_TO_BRING_YOUR_DOODLE_BACK_ABB"
+msgstr "I u smeru nadesno da biste vratili škrabotinu."
+
+msgid "WDS_IME_NPBODY_START_DOODLING_YOUR_MESSAGE_ABB"
+msgstr "Započnite škrabanje svoje poruke"
+
+msgid "WDS_IME_POP_ARE_YOU_SURE_YOU_WANT_TO_DISCARD_YOUR_DRAWING_Q"
+msgstr "Da li zaista želite da odbacite svoj crtež?"
+
+msgid "WDS_IME_NPBODY_START_DRAWING_YOUR_IMAGE_ABB"
+msgstr "Započnite crtanje slike"
+
diff --git a/res/po/sv.po b/res/po/sv.po
new file mode 100755 (executable)
index 0000000..23f6016
--- /dev/null
@@ -0,0 +1,33 @@
+msgid "WDS_IME_ACBUTTON_SEND"
+msgstr "SKICKA"
+
+msgid "WDS_WNOTI_POP_ALL_CHANGES_WILL_BE_DISCARDED"
+msgstr "Alla ändringar ignoreras."
+
+msgid "WDS_IME_NPBODY_START_DRAWING_M_EMOTICON_ABB"
+msgstr "Börja rita"
+
+msgid "WDS_MSG_SBODY_MMS_ABB"
+msgstr "MMS"
+
+msgid "WDS_IME_NPBODY_DRAW_YOUR_OWN_MESSAGE_ABB"
+msgstr "Rita ditt meddelande"
+
+msgid "WDS_TTRL_BODY_TURN_THE_BEZEL_ANTICLOCKWISE_TO_UNDO_A_DOODLE_ABB"
+msgstr "Vrid ramen moturs om du vill ångra ett klotter."
+
+msgid "WDS_TTRL_HEADER_TIPS_ABB"
+msgstr "Tips"
+
+msgid "WDS_TTRL_BODY_AND_CLOCKWISE_TO_BRING_YOUR_DOODLE_BACK_ABB"
+msgstr "Och medurs för att få tillbaka klottret."
+
+msgid "WDS_IME_NPBODY_START_DOODLING_YOUR_MESSAGE_ABB"
+msgstr "Börja klottra meddelandet"
+
+msgid "WDS_IME_POP_ARE_YOU_SURE_YOU_WANT_TO_DISCARD_YOUR_DRAWING_Q"
+msgstr "Vill du verkligen slänga din teckning?"
+
+msgid "WDS_IME_NPBODY_START_DRAWING_YOUR_IMAGE_ABB"
+msgstr "Börja rita bilden"
+
diff --git a/res/po/ta.po b/res/po/ta.po
new file mode 100755 (executable)
index 0000000..92b2177
--- /dev/null
@@ -0,0 +1,33 @@
+msgid "WDS_IME_ACBUTTON_SEND"
+msgstr "அனுப்பவும்"
+
+msgid "WDS_WNOTI_POP_ALL_CHANGES_WILL_BE_DISCARDED"
+msgstr "அனைத்து மாற்றங்களும் தவிர்க்கப்படும்."
+
+msgid "WDS_IME_NPBODY_START_DRAWING_M_EMOTICON_ABB"
+msgstr "வரையத் துவங்கவும்"
+
+msgid "WDS_MSG_SBODY_MMS_ABB"
+msgstr "MMS"
+
+msgid "WDS_IME_NPBODY_DRAW_YOUR_OWN_MESSAGE_ABB"
+msgstr "உங்கள் சொந்த தகவலை வரையவும்"
+
+msgid "WDS_TTRL_BODY_TURN_THE_BEZEL_ANTICLOCKWISE_TO_UNDO_A_DOODLE_ABB"
+msgstr "டூடுலை செயல்தவிர்க்க பெஸலை இடஞ்சுழியாகத் திருப்பவும்."
+
+msgid "WDS_TTRL_HEADER_TIPS_ABB"
+msgstr "குறிப்புகள்"
+
+msgid "WDS_TTRL_BODY_AND_CLOCKWISE_TO_BRING_YOUR_DOODLE_BACK_ABB"
+msgstr "மற்றும் உங்கள் டூடுலை மீண்டும் கொண்டுவர வலஞ்சுழியாக திருப்பவும்."
+
+msgid "WDS_IME_NPBODY_START_DOODLING_YOUR_MESSAGE_ABB"
+msgstr "உங்கள் தகவலை டூடுல் செய்ய துவங்குகள்"
+
+msgid "WDS_IME_POP_ARE_YOU_SURE_YOU_WANT_TO_DISCARD_YOUR_DRAWING_Q"
+msgstr "உறுதியாக நீங்கள் வரைந்ததை தவிர்க்க விரும்புகிறீர்களா?"
+
+msgid "WDS_IME_NPBODY_START_DRAWING_YOUR_IMAGE_ABB"
+msgstr "உங்கள் படத்தை வரையத் துவங்கவும்"
+
diff --git a/res/po/te.po b/res/po/te.po
new file mode 100755 (executable)
index 0000000..cf42d43
--- /dev/null
@@ -0,0 +1,33 @@
+msgid "WDS_IME_ACBUTTON_SEND"
+msgstr "పంపు"
+
+msgid "WDS_WNOTI_POP_ALL_CHANGES_WILL_BE_DISCARDED"
+msgstr "అన్ని మార్పులు విస్మరించబడతాయి."
+
+msgid "WDS_IME_NPBODY_START_DRAWING_M_EMOTICON_ABB"
+msgstr "డ్రా చేయడాన్ని ప్రారంభించండి"
+
+msgid "WDS_MSG_SBODY_MMS_ABB"
+msgstr "MMS"
+
+msgid "WDS_IME_NPBODY_DRAW_YOUR_OWN_MESSAGE_ABB"
+msgstr "మీ స్వంత సందేశాలను గీయండి"
+
+msgid "WDS_TTRL_BODY_TURN_THE_BEZEL_ANTICLOCKWISE_TO_UNDO_A_DOODLE_ABB"
+msgstr "డూడుల్‌ని చర్యరద్దు చేయడానికి బెజెల్‌ని అపసవ్యదిశలో తిప్పండి."
+
+msgid "WDS_TTRL_HEADER_TIPS_ABB"
+msgstr "చిట్కాలు"
+
+msgid "WDS_TTRL_BODY_AND_CLOCKWISE_TO_BRING_YOUR_DOODLE_BACK_ABB"
+msgstr "మరియు మీ డూడుల్‌ని తిరిగి పొందడానికి సవ్యదిశలో తిప్పండి."
+
+msgid "WDS_IME_NPBODY_START_DOODLING_YOUR_MESSAGE_ABB"
+msgstr "మీ సందేశాన్ని డూడుల్ చేయడాన్ని ప్రారంభించండి"
+
+msgid "WDS_IME_POP_ARE_YOU_SURE_YOU_WANT_TO_DISCARD_YOUR_DRAWING_Q"
+msgstr "మీరు మీ డ్రాయింగ్‌ను తప్పక విస్మరించాలా?"
+
+msgid "WDS_IME_NPBODY_START_DRAWING_YOUR_IMAGE_ABB"
+msgstr "మీ చిత్రాన్ని గీయండి"
+
diff --git a/res/po/tg_TJ.po b/res/po/tg_TJ.po
new file mode 100755 (executable)
index 0000000..2034dce
--- /dev/null
@@ -0,0 +1,33 @@
+msgid "WDS_IME_ACBUTTON_SEND"
+msgstr "ФИРИСТОДАН"
+
+msgid "WDS_WNOTI_POP_ALL_CHANGES_WILL_BE_DISCARDED"
+msgstr "Ҳамаи тағйирот бекор карда мешавад."
+
+msgid "WDS_IME_NPBODY_START_DRAWING_M_EMOTICON_ABB"
+msgstr "Расм кашед"
+
+msgid "WDS_MSG_SBODY_MMS_ABB"
+msgstr "MMS"
+
+msgid "WDS_IME_NPBODY_DRAW_YOUR_OWN_MESSAGE_ABB"
+msgstr "Паёми шахсии худро кашед"
+
+msgid "WDS_TTRL_BODY_TURN_THE_BEZEL_ANTICLOCKWISE_TO_UNDO_A_DOODLE_ABB"
+msgstr "Барои расмчаро бекор к, чанбарро ба чап тоб д."
+
+msgid "WDS_TTRL_HEADER_TIPS_ABB"
+msgstr "Маслиҳатҳо"
+
+msgid "WDS_TTRL_BODY_AND_CLOCKWISE_TO_BRING_YOUR_DOODLE_BACK_ABB"
+msgstr "Ва ба тарафи рост барои расмчаро баргардондан."
+
+msgid "WDS_IME_NPBODY_START_DOODLING_YOUR_MESSAGE_ABB"
+msgstr "Навиштани паёми худро оғоз кунед"
+
+msgid "WDS_IME_POP_ARE_YOU_SURE_YOU_WANT_TO_DISCARD_YOUR_DRAWING_Q"
+msgstr "Расмро дар ҳақиқат соқит мекунед?"
+
+msgid "WDS_IME_NPBODY_START_DRAWING_YOUR_IMAGE_ABB"
+msgstr "Кашидани тасвири худро оғоз кунед"
+
diff --git a/res/po/th.po b/res/po/th.po
new file mode 100755 (executable)
index 0000000..7a119f7
--- /dev/null
@@ -0,0 +1,33 @@
+msgid "WDS_IME_ACBUTTON_SEND"
+msgstr "ส่ง"
+
+msgid "WDS_WNOTI_POP_ALL_CHANGES_WILL_BE_DISCARDED"
+msgstr "การ​เปลี่ยน​แปลง​ทั้ง​หมด​ จะ​ถูก​ละทิ้ง"
+
+msgid "WDS_IME_NPBODY_START_DRAWING_M_EMOTICON_ABB"
+msgstr "เริ่มการวาด"
+
+msgid "WDS_MSG_SBODY_MMS_ABB"
+msgstr "MMS"
+
+msgid "WDS_IME_NPBODY_DRAW_YOUR_OWN_MESSAGE_ABB"
+msgstr "วาดข้อความของคุณ"
+
+msgid "WDS_TTRL_BODY_TURN_THE_BEZEL_ANTICLOCKWISE_TO_UNDO_A_DOODLE_ABB"
+msgstr "หมุนขอบหน้าปัดทวนเข็มนาฬิกาเพื่อเลิกทำภาพวาด"
+
+msgid "WDS_TTRL_HEADER_TIPS_ABB"
+msgstr "เคล็ดลับ"
+
+msgid "WDS_TTRL_BODY_AND_CLOCKWISE_TO_BRING_YOUR_DOODLE_BACK_ABB"
+msgstr "และหมุนตามเข็มนาฬิกาเพื่อคืนภาพวาดของคุณ"
+
+msgid "WDS_IME_NPBODY_START_DOODLING_YOUR_MESSAGE_ABB"
+msgstr "เริ่มเขียนข้อความของคุณ"
+
+msgid "WDS_IME_POP_ARE_YOU_SURE_YOU_WANT_TO_DISCARD_YOUR_DRAWING_Q"
+msgstr "คุณแน่ใจหรือไม่ว่าต้องการลบภาพวาดของคุณ"
+
+msgid "WDS_IME_NPBODY_START_DRAWING_YOUR_IMAGE_ABB"
+msgstr "เริ่มวาดภาพของคุณ"
+
diff --git a/res/po/tk_TM.po b/res/po/tk_TM.po
new file mode 100755 (executable)
index 0000000..66e2432
--- /dev/null
@@ -0,0 +1,33 @@
+msgid "WDS_IME_ACBUTTON_SEND"
+msgstr "IBER"
+
+msgid "WDS_WNOTI_POP_ALL_CHANGES_WILL_BE_DISCARDED"
+msgstr "Ähli üýtgetmeler öçüriler."
+
+msgid "WDS_IME_NPBODY_START_DRAWING_M_EMOTICON_ABB"
+msgstr "Çyzyp başla"
+
+msgid "WDS_MSG_SBODY_MMS_ABB"
+msgstr "MMS"
+
+msgid "WDS_IME_NPBODY_DRAW_YOUR_OWN_MESSAGE_ABB"
+msgstr "Öz hatyňy çyz"
+
+msgid "WDS_TTRL_BODY_TURN_THE_BEZEL_ANTICLOCKWISE_TO_UNDO_A_DOODLE_ABB"
+msgstr "Dudly yzyna almak üçin, çarçuwajyk sag. ters aýla."
+
+msgid "WDS_TTRL_HEADER_TIPS_ABB"
+msgstr "Maslahat"
+
+msgid "WDS_TTRL_BODY_AND_CLOCKWISE_TO_BRING_YOUR_DOODLE_BACK_ABB"
+msgstr "Dudluňyzy yza gaýtarmak üçin, sagadyň ugruna."
+
+msgid "WDS_IME_NPBODY_START_DOODLING_YOUR_MESSAGE_ABB"
+msgstr "Hat çyzmaga başlat"
+
+msgid "WDS_IME_POP_ARE_YOU_SURE_YOU_WANT_TO_DISCARD_YOUR_DRAWING_Q"
+msgstr "Çyzgyňyzy aýyrmak isleýäniňiz çynmy?"
+
+msgid "WDS_IME_NPBODY_START_DRAWING_YOUR_IMAGE_ABB"
+msgstr "Suratyňyzy çyzyp başlaň"
+
diff --git a/res/po/tl.po b/res/po/tl.po
new file mode 100755 (executable)
index 0000000..eaf8dcc
--- /dev/null
@@ -0,0 +1,33 @@
+msgid "WDS_IME_ACBUTTON_SEND"
+msgstr "IPADALA"
+
+msgid "WDS_WNOTI_POP_ALL_CHANGES_WILL_BE_DISCARDED"
+msgstr "Idi-discard ang lahat ng pagbabago."
+
+msgid "WDS_IME_NPBODY_START_DRAWING_M_EMOTICON_ABB"
+msgstr "Simulan ang drawing"
+
+msgid "WDS_MSG_SBODY_MMS_ABB"
+msgstr "MMS"
+
+msgid "WDS_IME_NPBODY_DRAW_YOUR_OWN_MESSAGE_ABB"
+msgstr "Iguhit ang sarili mong mensahe"
+
+msgid "WDS_TTRL_BODY_TURN_THE_BEZEL_ANTICLOCKWISE_TO_UNDO_A_DOODLE_ABB"
+msgstr "Ipihit ang bezel pakaliwa para i-undo ang isang doodle."
+
+msgid "WDS_TTRL_HEADER_TIPS_ABB"
+msgstr "Mga tip"
+
+msgid "WDS_TTRL_BODY_AND_CLOCKWISE_TO_BRING_YOUR_DOODLE_BACK_ABB"
+msgstr "At pakanan para ibalik ang doodle mo."
+
+msgid "WDS_IME_NPBODY_START_DOODLING_YOUR_MESSAGE_ABB"
+msgstr "Simulan na i-doodle ang mensahe mo"
+
+msgid "WDS_IME_POP_ARE_YOU_SURE_YOU_WANT_TO_DISCARD_YOUR_DRAWING_Q"
+msgstr "Nakasisiguro ka bang nais mong i-discard ang drawing mo?"
+
+msgid "WDS_IME_NPBODY_START_DRAWING_YOUR_IMAGE_ABB"
+msgstr "Simulan na iguhit ang larawan mo"
+
diff --git a/res/po/tr_TR.po b/res/po/tr_TR.po
new file mode 100755 (executable)
index 0000000..3f58535
--- /dev/null
@@ -0,0 +1,33 @@
+msgid "WDS_IME_ACBUTTON_SEND"
+msgstr "GÖNDER"
+
+msgid "WDS_WNOTI_POP_ALL_CHANGES_WILL_BE_DISCARDED"
+msgstr "Tüm değişiklikler silinecek."
+
+msgid "WDS_IME_NPBODY_START_DRAWING_M_EMOTICON_ABB"
+msgstr "Çizmeye başlayın"
+
+msgid "WDS_MSG_SBODY_MMS_ABB"
+msgstr "MMS"
+
+msgid "WDS_IME_NPBODY_DRAW_YOUR_OWN_MESSAGE_ABB"
+msgstr "Kendi mesajınızı çizin"
+
+msgid "WDS_TTRL_BODY_TURN_THE_BEZEL_ANTICLOCKWISE_TO_UNDO_A_DOODLE_ABB"
+msgstr "Bezeli saatn tersi ynde dndrp karalamayı geri aln."
+
+msgid "WDS_TTRL_HEADER_TIPS_ABB"
+msgstr "İpuçları"
+
+msgid "WDS_TTRL_BODY_AND_CLOCKWISE_TO_BRING_YOUR_DOODLE_BACK_ABB"
+msgstr "Saat yönünde döndürüp karalamanızı geri getirin."
+
+msgid "WDS_IME_NPBODY_START_DOODLING_YOUR_MESSAGE_ABB"
+msgstr "Mesajınızı çizmeye başlayın"
+
+msgid "WDS_IME_POP_ARE_YOU_SURE_YOU_WANT_TO_DISCARD_YOUR_DRAWING_Q"
+msgstr "Çiziminizi silmek istediğinizden emin misiniz?"
+
+msgid "WDS_IME_NPBODY_START_DRAWING_YOUR_IMAGE_ABB"
+msgstr "Resminizi çizmeye başlayın"
+
diff --git a/res/po/uk.po b/res/po/uk.po
new file mode 100755 (executable)
index 0000000..ad57afb
--- /dev/null
@@ -0,0 +1,33 @@
+msgid "WDS_IME_ACBUTTON_SEND"
+msgstr "НАДІСЛАТИ"
+
+msgid "WDS_WNOTI_POP_ALL_CHANGES_WILL_BE_DISCARDED"
+msgstr "Усі зміни буде скасовано."
+
+msgid "WDS_IME_NPBODY_START_DRAWING_M_EMOTICON_ABB"
+msgstr "Почніть малювати"
+
+msgid "WDS_MSG_SBODY_MMS_ABB"
+msgstr "MMS"
+
+msgid "WDS_IME_NPBODY_DRAW_YOUR_OWN_MESSAGE_ABB"
+msgstr "Намалюйте своє власне повідомлення"
+
+msgid "WDS_TTRL_BODY_TURN_THE_BEZEL_ANTICLOCKWISE_TO_UNDO_A_DOODLE_ABB"
+msgstr "Щоб видалити малюнок, поверніть рамку проти ГС."
+
+msgid "WDS_TTRL_HEADER_TIPS_ABB"
+msgstr "Підказки"
+
+msgid "WDS_TTRL_BODY_AND_CLOCKWISE_TO_BRING_YOUR_DOODLE_BACK_ABB"
+msgstr "Та проти год. стрілки, щоб повернути малюнок."
+
+msgid "WDS_IME_NPBODY_START_DOODLING_YOUR_MESSAGE_ABB"
+msgstr "Почніть малювати своє повідомлення"
+
+msgid "WDS_IME_POP_ARE_YOU_SURE_YOU_WANT_TO_DISCARD_YOUR_DRAWING_Q"
+msgstr "Видалити малюнок?"
+
+msgid "WDS_IME_NPBODY_START_DRAWING_YOUR_IMAGE_ABB"
+msgstr "Почніть малювати малюнок"
+
diff --git a/res/po/ur.po b/res/po/ur.po
new file mode 100755 (executable)
index 0000000..27a5bc5
--- /dev/null
@@ -0,0 +1,33 @@
+msgid "WDS_IME_ACBUTTON_SEND"
+msgstr "بھیجیں"
+
+msgid "WDS_WNOTI_POP_ALL_CHANGES_WILL_BE_DISCARDED"
+msgstr "سبھی تبدیلیاں رد کردی جائیں گی۔"
+
+msgid "WDS_IME_NPBODY_START_DRAWING_M_EMOTICON_ABB"
+msgstr "ڈرائنگ شروع کریں"
+
+msgid "WDS_MSG_SBODY_MMS_ABB"
+msgstr "MMS"
+
+msgid "WDS_IME_NPBODY_DRAW_YOUR_OWN_MESSAGE_ABB"
+msgstr "خود کا پیغام بنائیں"
+
+msgid "WDS_TTRL_BODY_TURN_THE_BEZEL_ANTICLOCKWISE_TO_UNDO_A_DOODLE_ABB"
+msgstr "ڈوڈل کو کالعدم کرنے کے لیے بیزل کو مخالف گھڑی وار گھمائیں۔"
+
+msgid "WDS_TTRL_HEADER_TIPS_ABB"
+msgstr "مشورے"
+
+msgid "WDS_TTRL_BODY_AND_CLOCKWISE_TO_BRING_YOUR_DOODLE_BACK_ABB"
+msgstr "اور گھڑی وار آپ کے ڈوڈل کو دوبارہ لانے کے لیے ہے۔"
+
+msgid "WDS_IME_NPBODY_START_DOODLING_YOUR_MESSAGE_ABB"
+msgstr "اپنا ڈوڈل پیغام شروع کریں"
+
+msgid "WDS_IME_POP_ARE_YOU_SURE_YOU_WANT_TO_DISCARD_YOUR_DRAWING_Q"
+msgstr "آپ یقینی طورپر اپنے ڈرائنگ کو ختم کرنا چاہتے ہیں؟"
+
+msgid "WDS_IME_NPBODY_START_DRAWING_YOUR_IMAGE_ABB"
+msgstr "اپنی تصویر بنانا شروع کریں"
+
diff --git a/res/po/uz.po b/res/po/uz.po
new file mode 100755 (executable)
index 0000000..30a0f74
--- /dev/null
@@ -0,0 +1,33 @@
+msgid "WDS_IME_ACBUTTON_SEND"
+msgstr "YUBORISH"
+
+msgid "WDS_WNOTI_POP_ALL_CHANGES_WILL_BE_DISCARDED"
+msgstr "Barcha o‘zgartirishlar bekor qilinadi."
+
+msgid "WDS_IME_NPBODY_START_DRAWING_M_EMOTICON_ABB"
+msgstr "Chizishni boshla"
+
+msgid "WDS_MSG_SBODY_MMS_ABB"
+msgstr "MMS"
+
+msgid "WDS_IME_NPBODY_DRAW_YOUR_OWN_MESSAGE_ABB"
+msgstr "O‘z xabaringizni chizing"
+
+msgid "WDS_TTRL_BODY_TURN_THE_BEZEL_ANTICLOCKWISE_TO_UNDO_A_DOODLE_ABB"
+msgstr "Bekor qil. u-n tig‘ni soat mil-ga qarshi buring."
+
+msgid "WDS_TTRL_HEADER_TIPS_ABB"
+msgstr "Maslahatlar"
+
+msgid "WDS_TTRL_BODY_AND_CLOCKWISE_TO_BRING_YOUR_DOODLE_BACK_ABB"
+msgstr "Va orqaga qaytarish uchun soat mili yo‘nalishida."
+
+msgid "WDS_IME_NPBODY_START_DOODLING_YOUR_MESSAGE_ABB"
+msgstr "Xabar yaratishni boshlash"
+
+msgid "WDS_IME_POP_ARE_YOU_SURE_YOU_WANT_TO_DISCARD_YOUR_DRAWING_Q"
+msgstr "Haqiqatan ham, chizmalaringizni bekor qilmoqchimisiz?"
+
+msgid "WDS_IME_NPBODY_START_DRAWING_YOUR_IMAGE_ABB"
+msgstr "Tasvirni chizishni boshlang"
+
diff --git a/res/po/vi.po b/res/po/vi.po
new file mode 100755 (executable)
index 0000000..60cd2e3
--- /dev/null
@@ -0,0 +1,33 @@
+msgid "WDS_IME_ACBUTTON_SEND"
+msgstr "GỬI"
+
+msgid "WDS_WNOTI_POP_ALL_CHANGES_WILL_BE_DISCARDED"
+msgstr "Mọi thay đổi sẽ không được lưu."
+
+msgid "WDS_IME_NPBODY_START_DRAWING_M_EMOTICON_ABB"
+msgstr "Bắt đầu vẽ"
+
+msgid "WDS_MSG_SBODY_MMS_ABB"
+msgstr "MMS"
+
+msgid "WDS_IME_NPBODY_DRAW_YOUR_OWN_MESSAGE_ABB"
+msgstr "Vẽ nội dung của bạn"
+
+msgid "WDS_TTRL_BODY_TURN_THE_BEZEL_ANTICLOCKWISE_TO_UNDO_A_DOODLE_ABB"
+msgstr "Xoay vòng ngược chiều đồng hồ để hoàn tác hình vẽ."
+
+msgid "WDS_TTRL_HEADER_TIPS_ABB"
+msgstr "Gợi ý"
+
+msgid "WDS_TTRL_BODY_AND_CLOCKWISE_TO_BRING_YOUR_DOODLE_BACK_ABB"
+msgstr "Và theo chiều đồng hồ để đưa hình vẽ trở lại."
+
+msgid "WDS_IME_NPBODY_START_DOODLING_YOUR_MESSAGE_ABB"
+msgstr "Bắt đầu vẽ nội dung tin nhắn của bạn"
+
+msgid "WDS_IME_POP_ARE_YOU_SURE_YOU_WANT_TO_DISCARD_YOUR_DRAWING_Q"
+msgstr "Bạn có chắc muốn hủy bản vẽ của bạn không?"
+
+msgid "WDS_IME_NPBODY_START_DRAWING_YOUR_IMAGE_ABB"
+msgstr "Bắt đầu vẽ hình của bạn"
+
diff --git a/res/po/zh_CN.po b/res/po/zh_CN.po
new file mode 100755 (executable)
index 0000000..fbb6847
--- /dev/null
@@ -0,0 +1,33 @@
+msgid "WDS_IME_ACBUTTON_SEND"
+msgstr "发送"
+
+msgid "WDS_WNOTI_POP_ALL_CHANGES_WILL_BE_DISCARDED"
+msgstr "将放弃全部更改。"
+
+msgid "WDS_IME_NPBODY_START_DRAWING_M_EMOTICON_ABB"
+msgstr "开始绘画"
+
+msgid "WDS_MSG_SBODY_MMS_ABB"
+msgstr "彩信"
+
+msgid "WDS_IME_NPBODY_DRAW_YOUR_OWN_MESSAGE_ABB"
+msgstr "绘出您的专属信息"
+
+msgid "WDS_TTRL_BODY_TURN_THE_BEZEL_ANTICLOCKWISE_TO_UNDO_A_DOODLE_ABB"
+msgstr "逆时针转动表圈可撤消涂鸦。"
+
+msgid "WDS_TTRL_HEADER_TIPS_ABB"
+msgstr "提示"
+
+msgid "WDS_TTRL_BODY_AND_CLOCKWISE_TO_BRING_YOUR_DOODLE_BACK_ABB"
+msgstr "再顺时针转动表圈可恢复已删除的涂鸦。"
+
+msgid "WDS_IME_NPBODY_START_DOODLING_YOUR_MESSAGE_ABB"
+msgstr "开始涂画您的信息"
+
+msgid "WDS_IME_POP_ARE_YOU_SURE_YOU_WANT_TO_DISCARD_YOUR_DRAWING_Q"
+msgstr "是否确定要放弃您的绘画?"
+
+msgid "WDS_IME_NPBODY_START_DRAWING_YOUR_IMAGE_ABB"
+msgstr "开始绘制您的图片"
+
diff --git a/res/po/zh_HK.po b/res/po/zh_HK.po
new file mode 100755 (executable)
index 0000000..7fa4e76
--- /dev/null
@@ -0,0 +1,33 @@
+msgid "WDS_IME_ACBUTTON_SEND"
+msgstr "發送"
+
+msgid "WDS_WNOTI_POP_ALL_CHANGES_WILL_BE_DISCARDED"
+msgstr "將捨棄所有變更。"
+
+msgid "WDS_IME_NPBODY_START_DRAWING_M_EMOTICON_ABB"
+msgstr "開始繪製"
+
+msgid "WDS_MSG_SBODY_MMS_ABB"
+msgstr "多媒體訊息"
+
+msgid "WDS_IME_NPBODY_DRAW_YOUR_OWN_MESSAGE_ABB"
+msgstr "繪製您的專屬訊息"
+
+msgid "WDS_TTRL_BODY_TURN_THE_BEZEL_ANTICLOCKWISE_TO_UNDO_A_DOODLE_ABB"
+msgstr "逆時針旋轉錶圈以復原塗鴉。"
+
+msgid "WDS_TTRL_HEADER_TIPS_ABB"
+msgstr "提示"
+
+msgid "WDS_TTRL_BODY_AND_CLOCKWISE_TO_BRING_YOUR_DOODLE_BACK_ABB"
+msgstr "順時針方向旋轉以還原塗鴉。"
+
+msgid "WDS_IME_NPBODY_START_DOODLING_YOUR_MESSAGE_ABB"
+msgstr "開始塗鴉訊息"
+
+msgid "WDS_IME_POP_ARE_YOU_SURE_YOU_WANT_TO_DISCARD_YOUR_DRAWING_Q"
+msgstr "確定要捨棄您的繪製嗎?"
+
+msgid "WDS_IME_NPBODY_START_DRAWING_YOUR_IMAGE_ABB"
+msgstr "開始繪製您的圖像"
+
diff --git a/res/po/zh_TW.po b/res/po/zh_TW.po
new file mode 100755 (executable)
index 0000000..a248bbe
--- /dev/null
@@ -0,0 +1,33 @@
+msgid "WDS_IME_ACBUTTON_SEND"
+msgstr "傳送"
+
+msgid "WDS_WNOTI_POP_ALL_CHANGES_WILL_BE_DISCARDED"
+msgstr "將捨棄所有變更。"
+
+msgid "WDS_IME_NPBODY_START_DRAWING_M_EMOTICON_ABB"
+msgstr "開始繪圖"
+
+msgid "WDS_MSG_SBODY_MMS_ABB"
+msgstr "多媒體訊息"
+
+msgid "WDS_IME_NPBODY_DRAW_YOUR_OWN_MESSAGE_ABB"
+msgstr "畫出您專屬的訊息"
+
+msgid "WDS_TTRL_BODY_TURN_THE_BEZEL_ANTICLOCKWISE_TO_UNDO_A_DOODLE_ABB"
+msgstr "逆時針轉動錶圈來復原塗鴉。"
+
+msgid "WDS_TTRL_HEADER_TIPS_ABB"
+msgstr "提示"
+
+msgid "WDS_TTRL_BODY_AND_CLOCKWISE_TO_BRING_YOUR_DOODLE_BACK_ABB"
+msgstr "然後順時針旋轉以還原您的塗鴉。"
+
+msgid "WDS_IME_NPBODY_START_DOODLING_YOUR_MESSAGE_ABB"
+msgstr "開始塗鴉您的訊息"
+
+msgid "WDS_IME_POP_ARE_YOU_SURE_YOU_WANT_TO_DISCARD_YOUR_DRAWING_Q"
+msgstr "確定要捨棄您的繪圖嗎?"
+
+msgid "WDS_IME_NPBODY_START_DRAWING_YOUR_IMAGE_ABB"
+msgstr "開始繪製您的圖像"
+
diff --git a/shared/res/org.tizen.sketch.png b/shared/res/org.tizen.sketch.png
new file mode 100755 (executable)
index 0000000..670353e
Binary files /dev/null and b/shared/res/org.tizen.sketch.png differ
diff --git a/shared/res/tables/org.tizen.w-drawing_color.xml b/shared/res/tables/org.tizen.w-drawing_color.xml
new file mode 100755 (executable)
index 0000000..4d9cb15
--- /dev/null
@@ -0,0 +1,166 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ChangeableColorTables>
+       <ChangeableColorTable num="1">
+               <Theme style="Dark">
+                       <ChangeableColorInfo id="AO0151" inputColor="W" hue="0" saturation="0" value="0" alpha="100" />
+                       <ChangeableColorInfo id="AO0151P" inputColor="W" hue="0" saturation="0" value="0" alpha="50" />
+                       <ChangeableColorInfo id="AO0151D" inputColor="W" hue="0" saturation="0" value="0" alpha="20" />
+                       <ChangeableColorInfo id="AO015L2" inputColor="W" hue="0" saturation="0" value="0" alpha="100" />
+                       <ChangeableColorInfo id="AO015L2P" inputColor="W" hue="0" saturation="0" value="0" alpha="50" />
+                       <ChangeableColorInfo id="AO015L2D" inputColor="W" hue="0" saturation="0" value="0" alpha="40" />
+                       <ChangeableColorInfo id="AO015" inputColor="W" hue="0" saturation="0" value="0" alpha="40" />
+                       <ChangeableColorInfo id="AO0153" inputColor="-" hue="41" saturation="100" value="100" alpha="100" />
+                       <ChangeableColorInfo id="AO0153P" inputColor="-" hue="41" saturation="100" value="100" alpha="50" />
+                       <ChangeableColorInfo id="AO0153D" inputColor="-" hue="41" saturation="100" value="100" alpha="40" />
+                       <ChangeableColorInfo id="AO0154" inputColor="-" hue="207" saturation="100" value="100" alpha="100" />
+                       <ChangeableColorInfo id="AO0154P" inputColor="-" hue="207" saturation="100" value="100" alpha="50" />
+                       <ChangeableColorInfo id="AO0154D" inputColor="-" hue="207" saturation="100" value="100" alpha="40" />
+                       <ChangeableColorInfo id="AO01151" inputColor="K" hue="0" saturation="0" value="0" alpha="100" />
+                       <ChangeableColorInfo id="AO01153L1" inputColor="-" hue="207" saturation="100" value="100" alpha="100" />
+                       <ChangeableColorInfo id="AO01153L1P" inputColor="-" hue="207" saturation="100" value="100" alpha="50" />
+                       <ChangeableColorInfo id="AO01153L1D" inputColor="-" hue="207" saturation="100" value="100" alpha="40" />
+                       <ChangeableColorInfo id="AO01154L1" inputColor="-" hue="281" saturation="77" value="79" alpha="100" />
+                       <ChangeableColorInfo id="AO01154L1P" inputColor="-" hue="281" saturation="77" value="79" alpha="50" />
+                       <ChangeableColorInfo id="AO01154L1D" inputColor="-" hue="281" saturation="77" value="79" alpha="40" />
+                       <ChangeableColorInfo id="AO01155L1" inputColor="-" hue="3" saturation="76" value="84" alpha="100" />
+                       <ChangeableColorInfo id="AO01155L1P" inputColor="-" hue="3" saturation="76" value="84" alpha="50" />
+                       <ChangeableColorInfo id="AO01155L1D" inputColor="-" hue="3" saturation="76" value="84" alpha="40" />
+                       <ChangeableColorInfo id="AO01153L3" inputColor="W" hue="0" saturation="0" value="0" alpha="100" />
+                       <ChangeableColorInfo id="AO01153L3P" inputColor="W" hue="0" saturation="0" value="0" alpha="100" />
+                       <ChangeableColorInfo id="AO01153L3D" inputColor="W" hue="0" saturation="0" value="0" alpha="40" />
+                       <ChangeableColorInfo id="AO0116" inputColor="W" hue="0" saturation="0" value="0" alpha="100" />
+                       <ChangeableColorInfo id="AO0116P" inputColor="W" hue="0" saturation="0" value="0" alpha="50" />
+                       <ChangeableColorInfo id="AO0116D" inputColor="W" hue="0" saturation="0" value="0" alpha="30" />
+                       <ChangeableColorInfo id="AO01161" inputColor="K" hue="0" saturation="0" value="25" alpha="100" />
+                       <ChangeableColorInfo id="AO01161P" inputColor="K" hue="0" saturation="0" value="15" alpha="100" />
+                       <ChangeableColorInfo id="AO01161D" inputColor="K" hue="0" saturation="0" value="10" alpha="100" />
+                       <ChangeableColorInfo id="AO0117" inputColor="K" hue="0" saturation="0" value="0" alpha="100" />
+                       <ChangeableColorInfo id="AO0118" inputColor="K" hue="0" saturation="0" value="0" alpha="100" />
+                       <ChangeableColorInfo id="AO0119" inputColor="W" hue="0" saturation="0" value="0" alpha="100" />
+                       <ChangeableColorInfo id="AO0119P" inputColor="W" hue="0" saturation="0" value="0" alpha="100" />
+                       <ChangeableColorInfo id="AO0119D" inputColor="W" hue="0" saturation="0" value="0" alpha="5" />
+                       <ChangeableColorInfo id="AO031" inputColor="4" hue="0" saturation="0" value="0" alpha="100" />
+                       <ChangeableColorInfo id="AO031P" inputColor="4" hue="0" saturation="0" value="0" alpha="40" />
+                       <ChangeableColorInfo id="AO031L1" inputColor="W" hue="0" saturation="0" value="0" alpha="41" />
+                       <ChangeableColorInfo id="AO031L1P" inputColor="W" hue="0" saturation="0" value="0" alpha="70" />
+                       <ChangeableColorInfo id="AO0331" inputColor="W" hue="0" saturation="0" value="0" alpha="50" />
+                       <ChangeableColorInfo id="AO0332" inputColor="W" hue="0" saturation="0" value="0" alpha="100" />
+                       <ChangeableColorInfo id="AO034" inputColor="W" hue="0" saturation="0" value="-40" alpha="100" />
+                       <ChangeableColorInfo id="AO034P" inputColor="W" hue="0" saturation="0" value="0" alpha="100" />
+                       <ChangeableColorInfo id="AO034D" inputColor="W" hue="0" saturation="0" value="0" alpha="30" />
+                       <ChangeableColorInfo id="AO035" inputColor="4" hue="0" saturation="3" value="-51" alpha="100" />
+                       <ChangeableColorInfo id="AO0351" inputColor="W" hue="0" saturation="0" value="0" alpha="15" />
+                       <ChangeableColorInfo id="AO036" inputColor="4" hue="0" saturation="0" value="0" alpha="100" />
+                       <ChangeableColorInfo id="AO0361" inputColor="4" hue="0" saturation="0" value="0" alpha="50" />
+                       <ChangeableColorInfo id="AO038" inputColor="W" hue="0" saturation="0" value="0" alpha="100" />
+                       <ChangeableColorInfo id="AO038P" inputColor="W" hue="0" saturation="0" value="0" alpha="50" />
+                       <ChangeableColorInfo id="AO038D" inputColor="W" hue="0" saturation="0" value="0" alpha="40" />
+                       <ChangeableColorInfo id="AO0391" inputColor="K" hue="0" saturation="0" value="60" alpha="100" />
+                       <ChangeableColorInfo id="AO0391P" inputColor="K" hue="0" saturation="0" value="60" alpha="50" />
+                       <ChangeableColorInfo id="AO0391D" inputColor="K" hue="0" saturation="0" value="60" alpha="40" />
+                       <ChangeableColorInfo id="AO0392" inputColor="W" hue="0" saturation="0" value="0" alpha="100" />
+                       <ChangeableColorInfo id="AO0392P" inputColor="W" hue="0" saturation="0" value="0" alpha="50" />
+                       <ChangeableColorInfo id="AO0392D" inputColor="W" hue="0" saturation="0" value="0" alpha="40" />
+                       <ChangeableColorInfo id="AO040" inputColor="-" hue="150" saturation="100" value="50" alpha="100" />
+                       <ChangeableColorInfo id="AO041" inputColor="-" hue="80" saturation="100" value="75" alpha="100" />
+                       <ChangeableColorInfo id="AO042" inputColor="-" hue="45" saturation="100" value="100" alpha="100" />
+                       <ChangeableColorInfo id="AO043" inputColor="-" hue="30" saturation="100" value="90" alpha="100" />
+                       <ChangeableColorInfo id="AO044" inputColor="-" hue="0" saturation="100" value="85" alpha="100" />
+                       <ChangeableColorInfo id="AO045" inputColor="-" hue="300" saturation="100" value="85" alpha="100" />
+                       <ChangeableColorInfo id="AO046" inputColor="-" hue="260" saturation="80" value="90" alpha="100" />
+                       <ChangeableColorInfo id="AO047" inputColor="-" hue="210" saturation="100" value="90" alpha="100" />
+                       <ChangeableColorInfo id="AO048" inputColor="-" hue="193" saturation="70" value="100" alpha="100" />
+                       <ChangeableColorInfo id="AO049" inputColor="-" hue="0" saturation="0" value="100" alpha="100" />
+                       <ChangeableColorInfo id="AO051" inputColor="K" hue="0" saturation="0" value="0" alpha="50" />
+                       <ChangeableColorInfo id="AT0113" inputColor="4" hue="0" saturation="0" value="0" alpha="100" />
+                       <ChangeableColorInfo id="AT0113P" inputColor="4" hue="0" saturation="0" value="0" alpha="100" />
+                       <ChangeableColorInfo id="AT0113D" inputColor="4" hue="0" saturation="0" value="0" alpha="70" />
+                       <ChangeableColorInfo id="AT0113S" inputColor="4" hue="0" saturation="0" value="0" alpha="100" />
+                       <ChangeableColorInfo id="AT0114" inputColor="W" hue="0" saturation="0" value="0" alpha="100" />
+                       <ChangeableColorInfo id="AT0114D" inputColor="W" hue="0" saturation="0" value="0" alpha="5" />
+                       <ChangeableColorInfo id="AT0116" inputColor="W" hue="0" saturation="0" value="0" alpha="100" />
+                       <ChangeableColorInfo id="AT0117" inputColor="W" hue="0" saturation="0" value="0" alpha="100" />
+                       <ChangeableColorInfo id="AT0118" inputColor="W" hue="0" saturation="0" value="0" alpha="40" />
+                       <ChangeableColorInfo id="AT0115" inputColor="W" hue="0" saturation="0" value="-28" alpha="100" />
+                       <ChangeableColorInfo id="AT0115P" inputColor="W" hue="0" saturation="0" value="-28" alpha="100" />
+                       <ChangeableColorInfo id="AT0115D" inputColor="W" hue="0" saturation="0" value="-28" alpha="40" />
+                       <ChangeableColorInfo id="AT0115S" inputColor="W" hue="0" saturation="0" value="-28" alpha="100" />
+                       <ChangeableColorInfo id="AT02112" inputColor="W" hue="0" saturation="0" value="0" alpha="100" />
+                       <ChangeableColorInfo id="AT02113" inputColor="W" hue="0" saturation="0" value="-36" alpha="100" />
+                       <ChangeableColorInfo id="AT023" inputColor="W" hue="0" saturation="0" value="0" alpha="100" />
+                       <ChangeableColorInfo id="AT023P" inputColor="W" hue="0" saturation="0" value="0" alpha="50" />
+                       <ChangeableColorInfo id="AT023D" inputColor="W" hue="0" saturation="0" value="0" alpha="40" />
+                       <ChangeableColorInfo id="AT031" inputColor="W" hue="0" saturation="0" value="0" alpha="100" />
+                       <ChangeableColorInfo id="AT031D" inputColor="W" hue="0" saturation="0" value="-70" alpha="100" />
+                       <ChangeableColorInfo id="AT032" inputColor="W" hue="0" saturation="0" value="0" alpha="40" />
+                       <ChangeableColorInfo id="AT033" inputColor="W" hue="0" saturation="0" value="0" alpha="40" />
+                       <ChangeableColorInfo id="AT041" inputColor="W" hue="0" saturation="0" value="0" alpha="100" />
+                       <ChangeableColorInfo id="AT041P" inputColor="W" hue="0" saturation="0" value="0" alpha="50" />
+                       <ChangeableColorInfo id="AT041D" inputColor="W" hue="0" saturation="0" value="0" alpha="40" />
+                       <ChangeableColorInfo id="AT042" inputColor="W" hue="0" saturation="0" value="0" alpha="40" />
+                       <ChangeableColorInfo id="AT042D" inputColor="W" hue="0" saturation="0" value="0" alpha="40" />
+               </Theme>
+               <Theme style="Light">
+                       <ChangeableColorInfo id="AO0151" inputColor="W" hue="0" saturation="0" value="-95" alpha="100" />
+                       <ChangeableColorInfo id="AO0151P" inputColor="W" hue="0" saturation="0" value="-95" alpha="50" />
+                       <ChangeableColorInfo id="AO0151D" inputColor="W" hue="0" saturation="0" value="-95" alpha="20" />
+                       <ChangeableColorInfo id="AO015L2" inputColor="W" hue="0" saturation="0" value="-95" alpha="100" />
+                       <ChangeableColorInfo id="AO015L2P" inputColor="W" hue="0" saturation="0" value="-95" alpha="50" />
+                       <ChangeableColorInfo id="AO015L2D" inputColor="W" hue="0" saturation="0" value="-95" alpha="20" />
+                       <ChangeableColorInfo id="AO01151" inputColor="K" hue="0" saturation="0" value="98" alpha="100" fixedHue="true" fixedSaturation="true" fixedValue="true" />
+                       <ChangeableColorInfo id="AO01153L1" inputColor="-" hue="-20" saturation="-19" value="41" alpha="100" />
+                       <ChangeableColorInfo id="AO01153L1P" inputColor="-" hue="-20" saturation="-6" value="8" alpha="100" />
+                       <ChangeableColorInfo id="AO01153L1D" inputColor="-" hue="-20" saturation="-19" value="41" alpha="40" />
+                       <ChangeableColorInfo id="AO01154L1" inputColor="-" hue="72" saturation="-23" value="43" alpha="100" />
+                       <ChangeableColorInfo id="AO01154L1P" inputColor="-" hue="72" saturation="-13" value="16" alpha="100" />
+                       <ChangeableColorInfo id="AO01154L1D" inputColor="-" hue="72" saturation="-23" value="43" alpha="40" />
+                       <ChangeableColorInfo id="AO01155L1" inputColor="-" hue="-206" saturation="-24" value="48" alpha="100" />
+                       <ChangeableColorInfo id="AO01155L1P" inputColor="-" hue="-206" saturation="-18" value="13" alpha="100" />
+                       <ChangeableColorInfo id="AO01155L1D" inputColor="-" hue="-206" saturation="-24" value="48" alpha="40" />
+                       <ChangeableColorInfo id="AO01153L3" inputColor="W" hue="0" saturation="0" value="0" alpha="100" />
+                       <ChangeableColorInfo id="AO01153L3P" inputColor="W" hue="0" saturation="0" value="0" alpha="100" />
+                       <ChangeableColorInfo id="AO01153L3D" inputColor="W" hue="0" saturation="0" value="0" alpha="40" />
+                       <ChangeableColorInfo id="AO0116" inputColor="W" hue="0" saturation="0" value="-95" alpha="100" />
+                       <ChangeableColorInfo id="AO0116P" inputColor="W" hue="0" saturation="0" value="-95" alpha="50" />
+                       <ChangeableColorInfo id="AO0116D" inputColor="W" hue="0" saturation="0" value="-95" alpha="30" />
+                       <ChangeableColorInfo id="AO0117" inputColor="K" hue="0" saturation="0" value="95" alpha="100" />
+                       <ChangeableColorInfo id="AO031" inputColor="4" hue="6" saturation="7" value="0" alpha="100" />
+                       <ChangeableColorInfo id="AO031P" inputColor="4" hue="6" saturation="7" value="0" alpha="40" />
+                       <ChangeableColorInfo id="AO031L1" inputColor="W" hue="0" saturation="0" value="0" alpha="41" />
+                       <ChangeableColorInfo id="AO031L1P" inputColor="W" hue="0" saturation="0" value="0" alpha="70" />
+                       <ChangeableColorInfo id="AO0331" inputColor="W" hue="0" saturation="0" value="-95" alpha="50" />
+                       <ChangeableColorInfo id="AO0332" inputColor="W" hue="0" saturation="0" value="-95" alpha="100" />
+                       <ChangeableColorInfo id="AO034" inputColor="W" hue="0" saturation="0" value="-56" alpha="100" />
+                       <ChangeableColorInfo id="AO034P" inputColor="W" hue="0" saturation="0" value="-95" alpha="100" />
+                       <ChangeableColorInfo id="AO034D" inputColor="W" hue="0" saturation="0" value="-95" alpha="30" />
+                       <ChangeableColorInfo id="AO035" inputColor="4" hue="0" saturation="-17" value="-11" alpha="100" />
+                       <ChangeableColorInfo id="AO0351" inputColor="W" hue="0" saturation="0" value="-95" alpha="15" />
+                       <ChangeableColorInfo id="AO036" inputColor="4" hue="0" saturation="0" value="0" alpha="100" />
+                       <ChangeableColorInfo id="AO0361" inputColor="4" hue="0" saturation="0" value="0" alpha="50" />
+                       <ChangeableColorInfo id="AO038" inputColor="W" hue="0" saturation="0" value="0" alpha="100" />
+                       <ChangeableColorInfo id="AO038P" inputColor="W" hue="0" saturation="0" value="0" alpha="50" />
+                       <ChangeableColorInfo id="AO038D" inputColor="W" hue="0" saturation="0" value="0" alpha="40" />
+                       <ChangeableColorInfo id="AT0113" inputColor="4" hue="198" saturation="97" value="89" alpha="100" fixedHue="true" fixedSaturation="true" fixedValue="true" />
+                       <ChangeableColorInfo id="AT0113P" inputColor="4" hue="198" saturation="97" value="89" alpha="100" fixedHue="true" fixedSaturation="true" fixedValue="true" />
+                       <ChangeableColorInfo id="AT0113D" inputColor="4" hue="198" saturation="97" value="89" alpha="70" fixedHue="true" fixedSaturation="true" fixedValue="true" />
+                       <ChangeableColorInfo id="AT0113S" inputColor="4" hue="198" saturation="97" value="89" alpha="100" fixedHue="true" fixedSaturation="true" fixedValue="true" />
+                       <ChangeableColorInfo id="AT02112" inputColor="W" hue="0" saturation="0" value="-95" alpha="100" />
+                       <ChangeableColorInfo id="AT02113" inputColor="W" hue="0" saturation="0" value="-95" alpha="30" />
+                       <ChangeableColorInfo id="AT023" inputColor="W" hue="0" saturation="0" value="0" alpha="100" />
+                       <ChangeableColorInfo id="AT023P" inputColor="W" hue="0" saturation="0" value="0" alpha="50" />
+                       <ChangeableColorInfo id="AT023D" inputColor="W" hue="0" saturation="0" value="0" alpha="40" />
+               </Theme>
+       </ChangeableColorTable>
+       <ChangeableColorTable num="2">
+               <Theme style="Dark">
+               </Theme>
+               <Theme style="Light">
+               </Theme>
+       </ChangeableColorTable>
+       <ChangeableColorTable num="3">
+               <Theme style="Dark">
+               </Theme>
+               <Theme style="Light">
+               </Theme>
+       </ChangeableColorTable>
+</ChangeableColorTables>
diff --git a/shared/res/tables/org.tizen.w-drawing_font.xml b/shared/res/tables/org.tizen.w-drawing_font.xml
new file mode 100755 (executable)
index 0000000..22978f8
--- /dev/null
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<FontInfoTable>
+       <FontInfo id="AT0113" style="R" size="36" />
+       <FontInfo id="AT0113P" style="R" size="36" />
+       <FontInfo id="AT0113D" style="R" size="36" />
+       <FontInfo id="AT0113S" style="R" size="36" />
+       <FontInfo id="AT0114" style="R" size="24" />
+       <FontInfo id="AT0114D" style="R" size="24" />
+       <FontInfo id="AT0116" style="R" size="32" />
+       <FontInfo id="AT0117" style="R" size="28" />
+       <FontInfo id="AT0118" style="R" size="28" />
+       <FontInfo id="AT0115" style="R" size="24" />
+       <FontInfo id="AT0115P" style="R" size="24" />
+       <FontInfo id="AT0115D" style="R" size="24" />
+       <FontInfo id="AT0115S" style="R" size="24" />
+       <FontInfo id="AT02112" style="R" size="32" />
+       <FontInfo id="AT02113" style="R" size="24" />
+       <FontInfo id="AT023" style="B" size="25" />
+       <FontInfo id="AT023P" style="B" size="25" />
+       <FontInfo id="AT023D" style="B" size="25" />
+       <FontInfo id="AT031" style="R" size="36" />
+       <FontInfo id="AT031D" style="R" size="36" />
+       <FontInfo id="AT032" style="R" size="32" />
+       <FontInfo id="AT033" style="B" size="24" />
+       <FontInfo id="AT041" style="R" size="28" />
+       <FontInfo id="AT041P" style="R" size="28" />
+       <FontInfo id="AT041D" style="R" size="28" />
+       <FontInfo id="AT042" style="B" size="18" />
+       <FontInfo id="AT042D" style="B" size="18" />
+</FontInfoTable>
diff --git a/src/CDrUtil.cpp b/src/CDrUtil.cpp
new file mode 100644 (file)
index 0000000..4378137
--- /dev/null
@@ -0,0 +1,519 @@
+#include <Ecore_File.h>
+#include <message_port.h>
+#include <gio/gio.h>
+#include <string>
+#include <sstream>
+#include <iostream>
+#include <fstream>
+#include <sys/time.h>
+#include <time.h>
+#include <glib.h>
+#include <glib-object.h>
+#include <memory>
+
+#include <metadata_extractor.h>
+//#include <appfw/app_resource_manager.h>
+#include "DrDebug.h"
+#include "CDrUtil.h"
+//#include <vconf.h>
+
+bool
+CDrUtil::_bLockLcdOff = false;
+
+#define DBUS_REPLY_TIMEOUT (120 * 1000)
+
+#define VE_LOW_MEMORY_LIMIT_VALUE   (1048576)
+#define SDMEMORY_FOLDER "/opt/storage/sdcard"
+
+
+bool
+CDrUtil::checkIfLowStorageMem(int usageSize)
+{
+    unsigned long long size = 0;
+    struct statvfs dst_fs;
+    if (storage_get_internal_memory_size (&dst_fs) < 0)
+    {
+        size = 0;
+        WINFO("storage_get_internal_memory_size fail\n");
+        return true;
+    }
+
+    size =
+        ((unsigned long long) (dst_fs.f_bsize) *
+         (unsigned long long) (dst_fs.f_bavail));
+    WINFO("valid storage size is %lld\n", size);
+    if (size < (unsigned long long) usageSize)
+    {
+        return true;
+    }
+    return false;
+}
+
+void
+CDrUtil::timeFormat(int nSeconds, std::string & str)
+{
+    char cText[256];
+    int hour = (int) ((nSeconds) / 3600.0);
+    int min = (int) (((nSeconds - hour * 3600)) / 60.0);
+    int sec = (nSeconds) % 60;
+    snprintf (cText, sizeof (cText), "%.2d:%.2d:%.2d", hour, min, sec);
+    str = cText;
+}
+
+void
+CDrUtil::timeFormat(std::string & sSeconds, std::string & str)
+{
+    /*
+       sSeconds ("15")
+     */
+    int nSeconds = atoi(sSeconds.c_str());
+    timeFormat(nSeconds, str);
+}
+
+int
+CDrUtil::timeToInt(std::string & sTime)
+{
+    /* sTime is 01:02:03
+       sTime.substr(0,2) is hour integer
+       sTime.substr(3,2) is min integer
+       sTime.substr(6,2) is sec integer
+     */
+    int nSeconds =
+        atoi(sTime.substr(0, 2).c_str()) * 3600 +
+        atoi(sTime.substr(3, 2).c_str()) * 60 +
+        atoi(sTime.substr(6, 2).c_str());
+    return nSeconds;
+}
+
+bool
+CDrUtil::makeDir(const char *path)
+{
+    if (path == nullptr)
+    {
+        WERROR("Invalid input path");
+        return false;
+    }
+
+    struct stat st;
+    if (stat(path, &st) < 0)
+    {
+        if (!ecore_file_mkpath (path))
+        {
+            WSERROR("Failed to mkdir[%s]!", path);
+            return false;
+        }
+    }
+    return true;
+}
+
+GDBusMessage *
+CDrUtil::_gdbusInvokeMethodSync(const char *dest, const char *path,
+                                 const char *interface, const char *method,
+                                 GVariant * arg_variant)
+{
+    WENTER();
+
+    GDBusConnection *conn;
+    GDBusMessage *msg;
+    GDBusMessage *reply;
+    GError *error = nullptr;
+
+    conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, nullptr, nullptr);
+    if (conn == nullptr)
+    {
+        WERROR("g_bus_get_sync() is failed.");
+        return nullptr;
+    }
+
+    msg = g_dbus_message_new_method_call(dest, path, interface, method);
+    if (msg == nullptr)
+    {
+        WERROR("g_dbus_message_new_method_call() is failed.");
+        g_object_unref(conn);
+        return nullptr;
+    }
+
+    if (arg_variant)
+    {
+        g_dbus_message_set_body(msg, arg_variant);
+    }
+
+    reply =
+        g_dbus_connection_send_message_with_reply_sync(conn, msg,
+                G_DBUS_SEND_MESSAGE_FLAGS_NONE,
+                DBUS_REPLY_TIMEOUT,
+                nullptr, nullptr, &error);
+    if (reply == nullptr)
+    {
+        WERROR("g_dbus_connection_send_message_with_reply_sync() is failed.");
+    }
+
+    if (error != nullptr)
+    {
+        if (error->message != nullptr) {
+            WERROR("error [%s]", error->message);
+        } else {
+            WERROR("");
+        }
+        g_error_free(error);
+        error = nullptr;
+    }
+
+    g_object_unref(msg);
+    g_object_unref(conn);
+
+    return reply;
+}
+
+void
+CDrUtil::setBlockLcdOff()
+{
+    WENTER();
+    GVariant *gvariant = nullptr;
+    gvariant =
+        g_variant_new("(sssi)", "lcdon", "gotostatenow", "holdkeyblock", 0);
+
+    GDBusMessage *msg = nullptr;
+    msg =
+        _gdbusInvokeMethodSync("org.tizen.system.deviced",
+                                "/Org/Tizen/System/DeviceD/Display",
+                                "org.tizen.system.deviced.display", "lockstate",
+                                gvariant);
+
+    if (!msg) {
+        WERROR("invoke gdbus method failed");
+    } else {
+        g_object_unref(msg);
+        msg = nullptr;
+    }
+    _bLockLcdOff = true;
+    WLEAVE();
+}
+
+void
+CDrUtil::setUnblockLcdOff()
+{
+    WENTER();
+    GVariant *gvariant = nullptr;
+    gvariant = g_variant_new("(ss)", "lcdon", "resettimer");
+
+    GDBusMessage *msg = nullptr;
+    msg =
+        _gdbusInvokeMethodSync("org.tizen.system.deviced",
+                                "/Org/Tizen/System/DeviceD/Display",
+                                "org.tizen.system.deviced.display", "unlockstate",
+                                gvariant);
+
+    if (msg == nullptr) {
+        WERROR("invoke gdbus method failed");
+    } else {
+        g_object_unref(msg);
+        msg = nullptr;
+    }
+    _bLockLcdOff = false;
+    WLEAVE();
+}
+
+bool
+CDrUtil::getLcdState()
+{
+    return _bLockLcdOff;
+}
+
+int
+CDrUtil::getVideoClipRotate(const char *strInputFile)
+{
+    metadata_extractor_h meta_h;
+    int nRet = METADATA_EXTRACTOR_ERROR_NONE;
+    int nRotate = 0;
+    char *szVal = NULL;
+    nRet = metadata_extractor_create(&(meta_h));
+    if (nRet != METADATA_EXTRACTOR_ERROR_NONE)
+    {
+        WERROR("metadata_extractor_create is fail : [0x%x]", nRet);
+        goto FAILED_EXIT;
+    }
+
+    nRet = metadata_extractor_set_path(meta_h, strInputFile);
+    if (nRet != METADATA_EXTRACTOR_ERROR_NONE)
+    {
+        WERROR("metadata_extractor_set_path is fail : [0x%x]", nRet);
+        goto FAILED_EXIT;
+    }
+
+
+    nRet = metadata_extractor_get_metadata(meta_h, METADATA_ROTATE, &szVal);
+    if (nRet != METADATA_EXTRACTOR_ERROR_NONE)
+    {
+        WERROR("metadata_extractor_get_metadata is fail : [0x%x]", nRet);
+    }
+
+    if (szVal == NULL) {
+        nRotate = 0;
+    } else {
+        nRotate = atoi(szVal);
+        free(szVal);
+    }
+
+FAILED_EXIT:
+    nRet = metadata_extractor_destroy(meta_h);
+    if (nRet != METADATA_EXTRACTOR_ERROR_NONE)
+    {
+        WERROR("metadata_extractor_destroy is fail : [0x%x]", nRet);
+    }
+
+    return nRotate;
+}
+
+void
+CDrUtil::initResourceManager()
+{
+#if 0
+    int err = APP_RESOURCE_ERROR_NONE;
+    err = app_resource_manager_init();
+    if (err != APP_RESOURCE_ERROR_NONE)
+    {
+        WERROR("app_resource_manager_init failed[%d]", err);
+    }
+#endif
+}
+
+void
+CDrUtil::releaseResourceManager()
+{
+#if 0
+    int err = APP_RESOURCE_ERROR_NONE;
+    err = app_resource_manager_release();
+    if (err != APP_RESOURCE_ERROR_NONE)
+    {
+        WERROR("app_resource_manager_release failed[%d]", err);
+    }
+#endif
+}
+
+char *
+CDrUtil::getEdjPath(const char *name)
+{
+    char *path = nullptr;
+#if 0
+    int err = APP_RESOURCE_ERROR_NONE;
+
+    err = app_resource_manager_get(APP_RESOURCE_TYPE_LAYOUT, name, &path);
+    if (err != APP_RESOURCE_ERROR_NONE || path == nullptr)
+    {
+        WERROR("app_resource_manager_get failed[%d]", err);
+        if (path != nullptr)
+        {
+            free(path);
+            path = nullptr;
+        }
+        return nullptr;
+    }
+#endif
+    return path;
+}
+
+char *
+CDrUtil::getImagePath(const char *name)
+{
+    char *path = nullptr;
+#if 0
+    int err = APP_RESOURCE_ERROR_NONE;
+
+    err = app_resource_manager_get(APP_RESOURCE_TYPE_IMAGE, name, &path);
+    if (err != APP_RESOURCE_ERROR_NONE || path == nullptr)
+    {
+        WERROR("app_resource_manager_get failed[%d]", err);
+        WSINFO("image file name : [%s]", name);
+        if (path != nullptr)
+        {
+            free(path);
+            path = nullptr;
+        }
+        return nullptr;
+    }
+
+#endif
+    return path;
+}
+
+char *
+CDrUtil::getSharedResPath()
+{
+    char *path = nullptr;
+    path = app_get_shared_resource_path();
+    if (path == nullptr)
+    {
+        WERROR("app_get_shared_resource_path failed");
+    }
+    return path;
+}
+
+char *
+CDrUtil::getResourcePath()
+{
+    char *path = nullptr;
+    path = app_get_resource_path();
+    if (path == nullptr)
+    {
+        WERROR("app_get_resource_path failed");
+    }
+    return path;
+}
+
+void
+CDrUtil::getVideoClipWidthHeight(const char *strInputFile, int &iWidth,
+                                  int &iHeight)
+{
+    metadata_extractor_h meta_h;
+    int nRet = METADATA_EXTRACTOR_ERROR_NONE;
+    char *szVal = NULL;
+    nRet = metadata_extractor_create(&(meta_h));
+    if (nRet != METADATA_EXTRACTOR_ERROR_NONE)
+    {
+        WERROR("metadata_extractor_create is fail : [0x%x]", nRet);
+        goto FAILED_EXIT;
+    }
+
+    nRet = metadata_extractor_set_path(meta_h, strInputFile);
+    if (nRet != METADATA_EXTRACTOR_ERROR_NONE)
+    {
+        WERROR("metadata_extractor_set_path is fail : [0x%x]", nRet);
+        goto FAILED_EXIT;
+    }
+
+    nRet =
+        metadata_extractor_get_metadata(meta_h, METADATA_VIDEO_WIDTH, &szVal);
+    if (nRet != METADATA_EXTRACTOR_ERROR_NONE)
+    {
+        WERROR("metadata_extractor_get_metadata is fail : [0x%x]", nRet);
+        goto FAILED_EXIT;
+    }
+
+    if (szVal == NULL) {
+        iWidth = 0;
+    } else {
+        iWidth = atoi(szVal);
+        free(szVal);
+    }
+
+    nRet =
+        metadata_extractor_get_metadata(meta_h, METADATA_VIDEO_HEIGHT, &szVal);
+    if (nRet != METADATA_EXTRACTOR_ERROR_NONE)
+    {
+        WERROR("metadata_extractor_get_metadata is fail : [0x%x]", nRet);
+        goto FAILED_EXIT;
+    }
+
+    if (szVal == NULL) {
+        iHeight = 0;
+    } else {
+        iHeight = atoi(szVal);
+        free(szVal);
+    }
+
+FAILED_EXIT:
+    nRet = metadata_extractor_destroy(meta_h);
+    if (nRet != METADATA_EXTRACTOR_ERROR_NONE)
+    {
+        WERROR("metadata_extractor_destroy is fail : [0x%x]", nRet);
+    }
+}
+
+
+bool
+CDrUtil::getStorageState(bool bExternal)
+{
+    int ret;
+    struct statvfs info;
+    if (bExternal) {
+        /* it is external memory card */
+        //ret = statvfs(SDMEMORY_FOLDER, &info);
+        ret = storage_get_external_memory_size(&info);
+    } else {
+        /* it is internal memory */
+        ret = storage_get_internal_memory_size(&info);
+    }
+    if (ret < 0)
+    {
+        WERROR("fail to get memory size");
+        return false;
+    }
+
+    if (((info.f_bsize) * info.f_bavail) < VE_LOW_MEMORY_LIMIT_VALUE)
+    {
+        WERROR("Memory is almost full < 1MB");
+        return false;
+    }
+    return true;
+}
+
+void
+CDrUtil::getTimeName(long long time, std::string & strName)
+{
+    std::stringstream ss;
+
+    ss << time;
+
+    strName = ss.str();
+}
+
+long long
+CDrUtil::getTimeStamp()
+{
+    struct timeval times;
+    gettimeofday(&times, NULL);
+    long long interval = times.tv_sec;
+    interval = interval * 1000;
+    interval += times.tv_usec / 1000;
+    return interval;
+}
+
+int
+CDrUtil::atoi(const char *number)
+{
+    if (number == NULL)
+    {
+        WERROR("Input Number is NULL");
+        return 0;
+    }
+
+    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))
+    {
+        WERROR("strtol, val = %d", val);
+        return -1;
+    }
+
+    if (endptr == number)
+    {
+        WERROR("No digits were found, number = %s", number);
+        return -1;
+    }
+
+    return (int)val;
+}
+
+bool
+CDrUtil::isOperator(const char *opCode)
+{
+    char *operator_code = NULL;
+    bool result = false;
+//      operator_code = vconf_get_str(VCONFKEY_CSC_TEXT_STRING_CUSTOMER);
+    if (operator_code != NULL)
+    {
+        if (!strncmp(operator_code, opCode, strlen(operator_code)))
+        {
+            result = true;
+        }
+        free(operator_code);
+    }
+    return result;
+}
diff --git a/src/CDrUtil.h b/src/CDrUtil.h
new file mode 100644 (file)
index 0000000..55f801b
--- /dev/null
@@ -0,0 +1,52 @@
+#ifndef _C_DR_UTIL_H_
+#define _C_DR_UTIL_H_
+
+#include <sys/statvfs.h>
+#include <storage.h>
+#include <stdbool.h>
+#include <string>
+#include <app.h>
+#include <gio/gio.h>
+
+// ***********************************************************
+// declare and define methods which is a little complicated inside class body
+// ***********************************************************
+
+class CDrUtil
+{
+public:
+
+    static bool checkIfLowStorageMem(int usageSize);
+    static void timeFormat(int nSeconds, std::string & str);
+    static void timeFormat(std::string & sSeconds, std::string & str);
+    static int timeToInt(std::string & sTime);
+    static bool makeDir(const char *path);
+    static void setUnblockLcdOff();
+    static void setBlockLcdOff();
+    static bool getLcdState();
+    static int getVideoClipRotate(const char *strInputFile);
+    static void getVideoClipWidthHeight(const char *strInputFile, int &iWidth,
+                                         int &iHeight);
+    static void initResourceManager();
+    static void releaseResourceManager();
+    static char *getEdjPath(const char *name);
+    static char *getImagePath(const char *name);
+    static char *getSharedResPath();
+    static char *getResourcePath();
+    static bool getStorageState(bool bExternal);
+    static void getTimeName(long long time, std::string & strName);
+    static long long getTimeStamp();
+    static int atoi(const char *number);
+    static bool isOperator(const char *opCode);
+
+private:
+    static GDBusMessage *_gdbusInvokeMethodSync(const char *dest,
+            const char *path,
+            const char *interface,
+            const char *method,
+            GVariant * arg_variant);
+private:
+    static bool _bLockLcdOff;
+};
+
+#endif
diff --git a/src/EventManager/CDrEvent.h b/src/EventManager/CDrEvent.h
new file mode 100755 (executable)
index 0000000..04e093e
--- /dev/null
@@ -0,0 +1,50 @@
+#ifndef _CDR_EVENT_H_
+#define _CDR_EVENT_H_
+
+#include "WDefine.h"
+
+class WAPP_ASSIST_EXPORT CDrEvent {
+ public:
+       enum EType {
+               NONE = 0,
+               DB_CHANGED,
+               LANGUAGE_CHANGED,
+               SETTING_CHANGED,
+               WIN_ROTATED,
+               LOW_MEMORY,
+               APP_PAUSED,
+               APP_RESUMED,
+               TYPE_MAX,
+       } mType;
+       enum ESource {
+               LOCAL = 0,
+               REMOTE,
+               SOURCE_MAX,
+       } mSource;
+       void *mData;
+ public:
+        CDrEvent() {
+               mType = NONE;
+               mSource = LOCAL;
+               mData = NULL;
+       };
+       CDrEvent(EType _type, ESource _source, void *_data = NULL):mType(_type), mSource(_source), mData(_data) {
+       };
+       virtual ~CDrEvent() {
+       };
+       CDrEvent(const CDrEvent & obj) {
+               mType = obj.mType;
+               mSource = obj.mSource;
+               mData = obj.mData;
+       };
+       CDrEvent & operator=(const CDrEvent & obj) {
+               if (this != &obj) {
+                       mType = obj.mType;
+                       mSource = obj.mSource;
+                       mData = obj.mData;
+               }
+               return *(CDrEvent *)this;
+       };
+};
+
+#endif                                                 /* _CVE_EVENT_H_ */
diff --git a/src/EventManager/CDrEventListener.h b/src/EventManager/CDrEventListener.h
new file mode 100755 (executable)
index 0000000..37b2457
--- /dev/null
@@ -0,0 +1,12 @@
+#ifndef _CDR_EVENT_LISTENER_H_
+#define _CDR_EVENT_LISTENER_H_
+
+#include "WDefine.h"
+#include "CDrEvent.h"
+
+class WAPP_ASSIST_EXPORT CDrEventListener {
+ public:
+       virtual void onEvent(const CDrEvent & event) = 0;
+};
+
+#endif                                                 //_CVE_EVENT_LISTENER_H_
diff --git a/src/EventManager/CDrEventManager.cpp b/src/EventManager/CDrEventManager.cpp
new file mode 100644 (file)
index 0000000..db7e1e5
--- /dev/null
@@ -0,0 +1,319 @@
+#include "CDrEventManager.h"
+#include "DrDefine.h"
+//#include <vconf.h>
+
+#define CAL_TIMEOUT_MAX 8
+#define CAL_TIMEOUT_MAX_FOR_KIES 2
+
+ CDrEventManager::CDrEventManager():
+ _timerForPeindingEvents(NULL), _timeout(0), _timeoutMax(CAL_TIMEOUT_MAX), _pendingEvents(false), _isSuspended(false)
+{
+       WENTER();
+}
+
+CDrEventManager::~CDrEventManager()
+{
+       WENTER();
+       _removeTimerForPendingEvents();
+       clear();
+}
+
+void CDrEventManager::attach(CDrEventListener * listener)
+{
+       //WENTER();
+       ListenerNode *node = new ListenerNode;
+       node->isBlocked = false;
+       node->listener = listener;
+       _resetEventTable(node);
+       _listenerMap.insert(std::pair < CDrEventListener *, ListenerNode * >(listener, node));
+}
+
+void CDrEventManager::detach(CDrEventListener * listener)
+{
+       //WENTER();
+       auto finder = _listenerMap.find(listener);
+       if (finder == _listenerMap.end()) {
+               //WDEBUG("null");
+               return;
+       }
+       auto node = finder->second;
+       _clearEventTable(node);
+       delete node;
+
+       _listenerMap.erase(finder);
+       WLEAVE();
+}
+
+void CDrEventManager::block(CDrEventListener * listener)
+{
+       WENTER();
+       WDEBUG("%p", listener);
+       auto finder = _listenerMap.find(listener);
+       if (finder == _listenerMap.end()) {
+               WDEBUG("null");
+               return;
+       }
+       auto node = finder->second;
+       node->isBlocked = true;
+}
+
+void CDrEventManager::unblock(CDrEventListener * listener)
+{
+       WENTER();
+       WDEBUG("%p", listener);
+       auto finder = _listenerMap.find(listener);
+       if (finder == _listenerMap.end()) {
+               WDEBUG("null");
+               return;
+       }
+       auto node = finder->second;
+       node->isBlocked = false;
+       _notifyFromEventTable(node);
+}
+
+void CDrEventManager::notify(const CDrEvent & event)
+{
+       WENTER();
+       if (_isSuspended) {
+               for (auto it = _listenerMap.begin(); it != _listenerMap.end();) {
+                       auto node = it->second;
+                       it++;
+                       WINFO("is suspend-addtoEventTable");
+                       _addtoEventTable(node, event);
+               }
+               return;
+       }
+
+       for (auto it = _listenerMap.begin(); it != _listenerMap.end();) {
+               auto node = it->second;
+               it++;
+               if (node->isBlocked) {
+                       WINFO("node->isBlocked EVENT %d", event.mType);
+                       _addtoEventTable(node, event);
+               } else {
+                       if (event.mSource == CDrEvent::REMOTE) {
+                               int timeout = _getTimeoutForTimerForPendingEvents();
+                               WDEBUG("an event from a remote one, timeout = %d", timeout);
+                               /*
+                                  if (timeout == 0) {
+                                  node->listener->onEvent(event);
+                                  } else {
+                                  WINFO("for-addtoEventTable");
+                                  _addtoEventTable(node, event);
+                                  }
+                                */
+                               node->listener->onEvent(event);
+                       } else {
+                               node->listener->onEvent(event);
+                       }
+               }
+       }
+
+       //if (event.mSource == CDrEvent::REMOTE) {
+       //  WINFO("_addTimerForPendingEvents");
+       //_addTimerForPendingEvents();
+       //}
+       WLEAVE();
+}
+
+void CDrEventManager::clear()
+{
+       for (auto it = _listenerMap.begin(); it != _listenerMap.end();) {
+               auto node = it->second;
+               _clearEventTable(node);
+               delete node;
+
+               it = _listenerMap.erase(it);
+       }
+}
+
+void CDrEventManager::suspend()
+{
+       WENTER();
+       _isSuspended = true;
+
+       _removeTimerForPendingEvents();
+}
+
+void CDrEventManager::resume()
+{
+       WENTER();
+       _isSuspended = false;
+
+       for (auto it = _listenerMap.begin(); it != _listenerMap.end();) {
+               auto node = it->second;
+               it++;
+               if (node->isBlocked) {
+                       WDEBUG("node->isBlocked");
+                       continue;
+               } else {
+                       _notifyFromEventTable(node);
+               }
+       }
+}
+
+bool CDrEventManager::isDetached(CDrEventListener * listener)
+{
+       WENTER();
+       auto finder = _listenerMap.find(listener);
+       if (finder == _listenerMap.end())
+               return true;
+       else
+               return false;
+}
+
+void CDrEventManager::_resetEventTable(ListenerNode * node)
+{
+       // reset the event table
+       for (int i = 1; i < CDrEvent::TYPE_MAX; i++) {
+               for (int j = 0; j < CDrEvent::SOURCE_MAX; j++) {
+                       node->eventTable[i][j] = NULL;
+               }
+       }
+}
+
+void CDrEventManager::_addtoEventTable(ListenerNode * node, const CDrEvent & event)
+{
+       // add it to the event table
+       if (node->eventTable[event.mType][event.mSource])
+               delete node->eventTable[event.mType][event.mSource];
+       node->eventTable[event.mType][event.mSource] = new CDrEvent(event);
+}
+
+void CDrEventManager::_notifyFromEventTable(ListenerNode * node)
+{
+       // notify events from the event table
+       for (int i = 1; i < CDrEvent::TYPE_MAX; i++) {
+               for (int j = 0; j < CDrEvent::SOURCE_MAX; j++) {
+                       if (node->eventTable[i][j]) {
+                               CDrEventListener *listener = node->listener;
+                               node->listener->onEvent(*(node->eventTable[i][j]));
+
+                               auto finder = _listenerMap.find(listener);
+                               if (finder == _listenerMap.end()) {
+                                       WDEBUG("null");
+                                       return;
+                               }
+
+                               delete node->eventTable[i][j];
+                               node->eventTable[i][j] = NULL;
+                       }
+               }
+       }
+}
+
+void CDrEventManager::_notifyFromEventTable(ListenerNode * node, CDrEvent::ESource source)
+{
+       // notify events from the event table
+       for (int i = 1; i < CDrEvent::TYPE_MAX; i++) {
+               if (node->eventTable[i][source]) {
+                       CDrEventListener *listener = node->listener;
+                       node->listener->onEvent(*(node->eventTable[i][source]));
+
+                       auto finder = _listenerMap.find(listener);
+                       if (finder == _listenerMap.end()) {
+                               WDEBUG("null");
+                               return;
+                       }
+
+                       delete node->eventTable[i][source];
+                       node->eventTable[i][source] = NULL;
+               }
+       }
+}
+
+void CDrEventManager::_clearEventTable(ListenerNode * node)
+{
+       // clear the event table
+       for (int i = 1; i < CDrEvent::TYPE_MAX; i++) {
+               for (int j = 0; j < CDrEvent::SOURCE_MAX; j++) {
+                       if (node->eventTable[i][j]) {
+                               delete node->eventTable[i][j];
+                               node->eventTable[i][j] = NULL;
+                       }
+               }
+       }
+}
+
+void CDrEventManager::_processTimerForPendingEvents()
+{
+       //WENTER();
+       for (auto it = _listenerMap.begin(); it != _listenerMap.end();) {
+               auto node = it->second;
+               it++;
+               if (node->isBlocked) {
+                       WDEBUG("node->isBlocked");
+                       continue;
+               } else {
+                       _notifyFromEventTable(node, CDrEvent::REMOTE);
+               }
+       }
+       _timerForPeindingEvents = NULL;
+       if (_pendingEvents) {
+               _addTimerForPendingEvents();
+       } else {
+               //WDEBUG("expired");
+               _resetTimeoutForTimerForPendingEvents();
+       }
+}
+
+void CDrEventManager::_addTimerForPendingEvents()
+{
+       //WENTER();
+       if (_timerForPeindingEvents) {
+               //a request before timed out, just set the flag
+               _pendingEvents = true;
+               return;
+       }
+
+       _updateTimeoutForTimerForPendingEvents();
+       int timeout = _getTimeoutForTimerForPendingEvents();
+       WDEBUG("timeout = %d", timeout);
+       _timerForPeindingEvents = ecore_timer_add(timeout, [](void *data) {
+                                                                                          CDrEventManager * self = (CDrEventManager *) data;
+                                                                                          self->_processTimerForPendingEvents();
+                                                                                          self->_timerForPeindingEvents = nullptr;
+                                                                                          return ECORE_CALLBACK_CANCEL;
+                                                                                          }, this);
+}
+
+void CDrEventManager::_removeTimerForPendingEvents()
+{
+       //WENTER();
+       if (_timerForPeindingEvents)
+               ecore_timer_del(_timerForPeindingEvents);
+       _timerForPeindingEvents = nullptr;
+       _resetTimeoutForTimerForPendingEvents();
+}
+
+int CDrEventManager::_getTimeoutForTimerForPendingEvents()
+{
+       //WENTER();
+       // get the timeout for update
+       return _timeout;
+}
+
+void CDrEventManager::_updateTimeoutForTimerForPendingEvents()
+{
+       //WENTER();
+       // check if there is any request before timed out, if it's true, update the next timeout for update (x2)
+       if (_timeout == 0) {
+               _timeout = 2;
+       } else {
+               if (_timeout >= _timeoutMax)
+                       _timeout = _timeoutMax;
+               else
+                       _timeout *= 2;
+       }
+       WDEBUG("The next timeout = %d", _timeout);
+       _pendingEvents = false;
+}
+
+void CDrEventManager::_resetTimeoutForTimerForPendingEvents()
+{
+       //WENTER();
+       // reset the timeout and the pending flag
+       //WDEBUG("timeout(%d) will be reset", _timeout);
+       _timeout = 0;
+       _pendingEvents = false;
+}
diff --git a/src/EventManager/CDrEventManager.h b/src/EventManager/CDrEventManager.h
new file mode 100755 (executable)
index 0000000..c5926e0
--- /dev/null
@@ -0,0 +1,59 @@
+#ifndef _CDR_EVENT_MANAGER_H_
+#define _CDR_EVENT_MANAGER_H_
+
+#include <memory>
+#include <map>
+#include "WDefine.h"
+#include "CDrSingleton.h"
+#include "CDrEvent.h"
+#include "CDrEventListener.h"
+#include <Ecore.h>
+
+class WAPP_ASSIST_EXPORT CDrEventManager:public CDrSingleton < CDrEventManager > {
+ public:
+       void attach(CDrEventListener * listener);
+       void detach(CDrEventListener * listener);
+       bool isDetached(CDrEventListener * listener);
+       void block(CDrEventListener * listener);
+       void unblock(CDrEventListener * listener);
+       void notify(const CDrEvent & event);
+       void clear();                           /*clear all listener */
+       void suspend();
+       void resume();
+
+ protected:
+        friend class CDrSingleton < CDrEventManager >;
+        CDrEventManager();
+       ~CDrEventManager();
+ private:
+
+        WDISABLE_COPY_AND_ASSIGN(CDrEventManager);
+ private:
+       struct ListenerNode {
+               bool isBlocked;
+               CDrEvent *eventTable[CDrEvent::TYPE_MAX][CDrEvent::SOURCE_MAX];
+               CDrEventListener *listener;
+       };
+
+       void _resetEventTable(ListenerNode * node);
+       void _addtoEventTable(ListenerNode * node, const CDrEvent & event);
+       void _notifyFromEventTable(ListenerNode * node);
+       void _notifyFromEventTable(ListenerNode * node, CDrEvent::ESource soruce);
+       void _clearEventTable(ListenerNode * node);
+       void _processTimerForPendingEvents();
+       void _addTimerForPendingEvents();
+       void _removeTimerForPendingEvents();
+       int _getTimeoutForTimerForPendingEvents();
+       void _updateTimeoutForTimerForPendingEvents();
+       void _resetTimeoutForTimerForPendingEvents();
+
+ private:
+       std::map < CDrEventListener *, ListenerNode * >_listenerMap;
+       Ecore_Timer *_timerForPeindingEvents;
+       int _timeout;
+       int _timeoutMax;
+       bool _pendingEvents;
+       bool _isSuspended;
+};
+
+#endif                                                 /* _CVE_EVENT_MANAGER_H_ */
diff --git a/src/EventManager/CDrSingleton.h b/src/EventManager/CDrSingleton.h
new file mode 100755 (executable)
index 0000000..7f4c910
--- /dev/null
@@ -0,0 +1,34 @@
+#ifndef _CVE_SINGLETON_H_
+#define _CVE_SINGLETON_H_
+
+#include "WDefine.h"
+
+template < typename TYPE > class WAPP_ASSIST_EXPORT CDrSingleton {
+ public:
+       static TYPE & getInstance() {
+               if (_instance == NULL)
+                       _instance = new TYPE;
+               return *_instance;
+       };
+       static void destroy() {
+               delete _instance;
+               _instance = NULL;
+       };
+
+ protected:
+       CDrSingleton() {
+       };
+       virtual ~CDrSingleton() {
+       };
+
+ private:
+       CDrSingleton(const CDrSingleton & obj);
+       CDrSingleton & operator=(const CDrSingleton & obj);
+
+ private:
+       static TYPE *_instance;
+};
+
+template < typename TYPE > TYPE * CDrSingleton < TYPE >::_instance = NULL;
+
+#endif                                                 /* _CVE_SINGLETON_H_ */
diff --git a/src/MediaDB/CDrMediaContent.cpp b/src/MediaDB/CDrMediaContent.cpp
new file mode 100755 (executable)
index 0000000..6af5905
--- /dev/null
@@ -0,0 +1,69 @@
+#include "CDrMediaContent.h"
+#include "DrDefine.h"
+#include  <app.h>
+
+CDrMediaContent *CDrMediaContent::_instance = NULL;
+
+CDrMediaContent::CDrMediaContent()
+{
+       _bMediaDBConnect = false;
+       if (!_mediaContentConnect()) {
+               WERROR("media content connnect failed");
+       }
+}
+
+CDrMediaContent::~CDrMediaContent()
+{
+       if (!_mediaContentDisconnect()) {
+               WERROR("media content disconnnect failed");
+       }
+}
+
+CDrMediaContent *CDrMediaContent::getInstance()
+{
+       if (_instance == NULL) {
+               _instance = new CDrMediaContent();
+       }
+
+       return _instance;
+}
+
+void CDrMediaContent::destroyInstance()
+{
+       if (_instance != NULL) {
+               delete _instance;
+               _instance = NULL;
+       }
+}
+
+bool CDrMediaContent::isMediaDbConnect()
+{
+       return _bMediaDBConnect;
+}
+
+bool CDrMediaContent::_mediaContentConnect()
+{
+       int nRet = MEDIA_CONTENT_ERROR_NONE;
+
+       nRet = media_content_connect();
+       if (nRet != MEDIA_CONTENT_ERROR_NONE) {
+               WINFO("media_content_connect is fail : 0x%x", nRet);
+               return false;
+       }
+       _bMediaDBConnect = true;
+       return true;
+}
+
+bool CDrMediaContent::_mediaContentDisconnect()
+{
+       int nRet = MEDIA_CONTENT_ERROR_NONE;
+
+       nRet = media_content_disconnect();
+       if (nRet != MEDIA_CONTENT_ERROR_NONE) {
+               WINFO("media_content_connect is fail : 0x%x", nRet);
+               return false;
+       }
+       _bMediaDBConnect = false;
+       return true;
+}
+
diff --git a/src/MediaDB/CDrMediaContent.h b/src/MediaDB/CDrMediaContent.h
new file mode 100755 (executable)
index 0000000..3677447
--- /dev/null
@@ -0,0 +1,29 @@
+#ifndef _C_DR_MEDIACONTENT_H
+#define _C_DR_MEDIACONTENT_H
+
+#include <media_content.h>
+#include <string>
+
+class CDrMediaContent {
+ public:
+       static CDrMediaContent *getInstance();
+       static void destroyInstance();
+
+ public:
+       bool isMediaDbConnect();
+       //bool moveRenamedFileToDB(const char *szOldFilePath, const char *szNewFilePath);
+       //bool removeFileFromDB(std::string& strFile);
+
+ private:
+        CDrMediaContent();
+       ~CDrMediaContent();
+
+       bool _mediaContentConnect();
+       bool _mediaContentDisconnect();
+
+ private:
+       static CDrMediaContent *_instance;
+       bool _bMediaDBConnect;
+};
+
+#endif
diff --git a/src/Singleton.h b/src/Singleton.h
new file mode 100644 (file)
index 0000000..ba19efe
--- /dev/null
@@ -0,0 +1,51 @@
+
+#ifndef FRSINGLETON_H_
+#define FRSINGLETON_H_
+
+template < typename TYPE > class FRSingleton
+{
+public:
+    static TYPE *getInstance()
+    {
+        if (__instance == NULL)
+            __instance = new TYPE;
+        return __instance;
+    };
+    static void destroy()
+    {
+        if (__instance)
+        {
+            delete __instance;
+        }
+        __instance = NULL;
+    };
+
+    static TYPE *getInstanceWithoutNew()
+    {
+        return __instance;
+    };
+
+    static void setInstanceNULL()
+    {
+        __instance = NULL;
+    };
+
+protected:
+    FRSingleton()
+    {
+    };
+    virtual ~FRSingleton()
+    {
+    };
+
+private:
+    FRSingleton(const FRSingleton & obj);
+    FRSingleton & operator = (const FRSingleton & obj);
+
+private:
+    static TYPE *__instance;
+};
+
+template < typename TYPE > TYPE * FRSingleton < TYPE >::__instance = NULL;
+
+#endif /* FRSINGLETON_H_ */
diff --git a/src/View/CDrMainView.cpp b/src/View/CDrMainView.cpp
new file mode 100755 (executable)
index 0000000..eebbef2
--- /dev/null
@@ -0,0 +1,795 @@
+
+#include <efl_extension.h>
+#include "CDrMainView.h"
+#include "DrDefine.h"
+#include "CDrDrawingView.h"
+#include "CDrAppData.h"
+#include "CDrUtil.h"
+#include "WWindowController.h"
+#include "WNaviframeController.h"
+#include "CDrClosePopup.h"
+#include "WUiTimer.h"
+#include "CDrStrokeView.h"
+#include "CDrTutorialView.h"
+
+
+#define COLOR_BG_SAME_PATH_NUMBER     10
+
+CDrMainView::CDrMainView()
+{
+       _layout = nullptr;
+       _btnPalette = nullptr;
+       _drawingIcon = nullptr;
+       _rotarySelector = nullptr;
+       _animSave = nullptr;
+       _btnStroke = nullptr;
+
+       _bSaveBtnShow = false;
+       _bIndicatorTextShow = true;
+       _bPalletShowed = false;
+       _bPalletButtonShowed = false;
+       _bTutorialShowing = false;
+       _bHistoryCtrlShow = false;
+       _nItemSelected = 8;
+       _dStrokeWidth = SAVE_MODE_STROKE_LINE_WIDTH;
+
+       _palletIconNormalBgPath.push_back(DRAWING_MORE_OPTION_ICON_BG);
+
+       _palletIconSelBgPath.push_back(DRAWING_MORE_OPTION_ICON_SELECTED_BG);
+
+       _palletIconPath.push_back(DRAWING_PALLET_COLOR_PICKER_ERASER_ICON);
+
+       _palletIconCenterPath.push_back(DRAWING_PALLET_COLOR_PICKER_SELECTOR_ICON);
+
+       _palletIconName.push_back("Green");
+       _palletIconName.push_back("Light Green");
+       _palletIconName.push_back("Yellow");
+       _palletIconName.push_back("Orange");
+       _palletIconName.push_back("Red");
+       _palletIconName.push_back("Pink");
+       _palletIconName.push_back("Purple");
+       _palletIconName.push_back("Blue");
+       _palletIconName.push_back("Turquoise");
+       _palletIconName.push_back("White");
+       _palletIconName.push_back("Eraser");
+
+       _palletColorCode.push_back("AO040");
+       _palletColorCode.push_back("AO041");
+       _palletColorCode.push_back("AO042");
+       _palletColorCode.push_back("AO043");
+       _palletColorCode.push_back("AO044");
+       _palletColorCode.push_back("AO045");
+       _palletColorCode.push_back("AO046");
+       _palletColorCode.push_back("AO047");
+       _palletColorCode.push_back("AO048");
+       _palletColorCode.push_back("AO049");
+       _palletColorCode.push_back("");
+}
+
+CDrMainView::~CDrMainView()
+{
+       _stopSaveAnimation();
+       _palletIconNormalBgPath.clear();
+       _palletIconSelBgPath.clear();
+       _palletIconPath.clear();
+       _palletIconName.clear();
+       _palletColorCode.clear();
+       _palletIconCenterPath.clear();
+}
+
+Evas_Object * CDrMainView::onCreateView(Evas_Object * parent, void *viewParam)
+{
+       WENTER();
+
+       char* _path = app_get_resource_path();
+       std::string path(_path);
+       path += EDJ_FILE;
+
+       _layout = elm_layout_add(parent);
+       elm_layout_file_set(_layout, path.c_str(), "bg");
+       free(_path);
+       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);
+       //evas_object_resize(_layout, 360, 360);
+
+       if (CDrAppData::getInstance()->getLaunchMode() == DRAWING_SAVE) {
+               _createPalletButton();
+               _createStrokeButton();
+       } else {
+       #ifdef SKETCH_DRAW_COLORS_CHANGABLE
+               _createPalletButton();
+       #endif
+               elm_object_signal_emit(_layout, "elm.state.pallet.button.sendmode", "*");
+       }
+
+       /* create history index */
+       _cHistoryCtrl.createControl(_layout);
+       _showHistoryIndex(false);
+
+       /* create draw sub view */
+       CDrDrawingView* pDrawView = new (std::nothrow)CDrDrawingView();
+       pDrawView->setHistoryControlHandle(&_cHistoryCtrl);
+       _controlManager.attach(_layout, pDrawView, "pre-view");
+
+       pDrawView->setShowSaveButtonCb([&](bool bShow){
+                       _showSaveButton(bShow);
+       });
+       pDrawView->setDrawedCb([&](){
+                       _hideGuide();
+       });
+       pDrawView->setShowGuideCb([&](){
+                       _showGuide();
+       });
+       pDrawView->setHideGuideCb([&](){
+                       _hideGuide();
+       });
+       pDrawView->setShowHistoryIndexCb([&](bool bShow){
+                       _showHistoryIndex(bShow);
+       });
+       pDrawView->setShowPanelCb([&](){
+                       _showPanel();
+       });
+       pDrawView->setUnRedoCb([&](bool bUndo){
+                       _updateTutorialView(bUndo);
+       });
+       pDrawView->setStrokeWidth(_dStrokeWidth);
+       pDrawView->setColorCode(_palletColorCode[_nItemSelected]);
+
+       if (CDrAppData::getInstance()->getLaunchMode() == DRAWING_SEND) {
+               //elm_object_part_text_set(_layout, "elm.txt.indicator", DRAWING_TEXT_SEND_DRAW_START_INDICATOR);
+               if (CDrUtil::isOperator("ATT")){
+                       elm_object_domain_translatable_part_text_set(_layout, "elm.txt.indicator", LOCALE_DOMAIN, DRAWING_STRING_ID_SEND_DRAW_START_INDICATOR_ATNT);
+               } else {
+                       elm_object_domain_translatable_part_text_set(_layout, "elm.txt.indicator", LOCALE_DOMAIN, DRAWING_STRING_ID_SEND_DRAW_START_INDICATOR);
+               }
+
+               elm_object_domain_translatable_part_text_set(_layout, "elm.txt.mms", LOCALE_DOMAIN, DRAWING_STRING_ID_MMS_TITLE_TEXT);
+       } else {
+               elm_object_part_text_set(_layout, "elm.txt.indicator", DRAWING_TEXT_SAVE_DRAW_START_INDICATOR);
+       }
+
+       _showHistoryIndex(false);
+       elm_object_signal_emit(_layout, "elm.state.show.indicator", "*");
+       _bPalletButtonShowed = true;
+       return _layout;
+}
+
+void CDrMainView::_createPalletButton()
+{
+       char* share_path = app_get_resource_path();
+       std::string drawing_icon_path(share_path);
+       drawing_icon_path += DRAWING_MORE_OPTIONS_ICON;
+
+       _btnPalette = elm_button_add(_layout);
+       if (CDrAppData::getInstance()->getLaunchMode() == DRAWING_SEND) {
+               elm_object_signal_emit(_layout, "elm.state.pallet.button.sendmode", "*");
+               elm_object_style_set(_btnPalette, DRAWING_BUTTON_SEND_MODE_STYLE);
+       } else {
+               elm_object_style_set(_btnPalette, DRAWING_BUTTON_SAVE_MODE_STYLE);
+       }
+
+       _drawingIcon = elm_image_add(_btnPalette);
+       elm_image_resizable_set(_drawingIcon, EINA_TRUE, EINA_TRUE);
+       elm_image_file_set(_drawingIcon, drawing_icon_path.c_str(), NULL);
+       evas_object_size_hint_weight_set(_drawingIcon, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+//     ea_theme_object_color_set(_drawingIcon, _palletColorCode[_nItemSelected].c_str());
+       elm_object_content_set(_btnPalette, _drawingIcon);
+       evas_object_size_hint_fill_set(_btnPalette, EVAS_HINT_FILL, EVAS_HINT_FILL);
+       evas_object_show(_drawingIcon);
+       free(share_path);
+       elm_object_part_content_set(_layout, "elm.button.pallet", _btnPalette);
+       evas_object_smart_callback_add(_btnPalette, "clicked", _onColorPickerBtnClicked, this);
+}
+
+void CDrMainView::_createStrokeButton()
+{
+       char* share_path = app_get_resource_path();
+       std::string drawing_icon_path(share_path);
+       drawing_icon_path += DRAWING_STROKE_OPTIONS_ICON;
+
+       _btnStroke = elm_button_add(_layout);
+       elm_object_style_set(_btnStroke, DRAWING_BUTTON_SAVE_MODE_STYLE);
+
+       //elm_object_style_set(_btnPalette, "fastscroll");
+       Evas_Object *icon = elm_image_add(_btnStroke);
+       elm_image_resizable_set(icon, EINA_TRUE, EINA_TRUE);
+       elm_image_file_set(icon, drawing_icon_path.c_str(), NULL);
+       evas_object_size_hint_weight_set(icon, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+//     ea_theme_object_color_set(icon, _palletColorCode[_nItemSelected].c_str());
+       elm_object_content_set(_btnStroke, icon);
+       evas_object_size_hint_fill_set(_btnStroke, EVAS_HINT_FILL, EVAS_HINT_FILL);
+       evas_object_show(icon);
+       free(share_path);
+       elm_object_part_content_set(_layout, "elm.button.stroke", _btnStroke);
+       evas_object_smart_callback_add(_btnStroke, "clicked", _onStrokeBtnClickCb, this);
+}
+
+void CDrMainView::onCreated()
+{
+}
+
+void CDrMainView::onDestroy()
+{
+       int x, y, w, h;
+       evas_object_geometry_get(_layout, &x, &y, &w, &h);
+       WINFO("x=%d y=%d W=%d H=%d", x, y, w, h);
+}
+
+void CDrMainView::onPushed(Elm_Object_Item * naviItem)
+{
+       eext_object_event_callback_add(getEvasObj(), EEXT_CALLBACK_BACK, _onBackBtnClicked, this);
+}
+
+Elm_Object_Item* CDrMainView::onPushToNaviframe(Evas_Object* naviFrame)
+{
+       Elm_Object_Item* item = elm_naviframe_item_push(naviFrame, getTitle(), nullptr, nullptr,  getEvasObj(), "empty");
+       return item;
+}
+
+void CDrMainView::onEvent(const CDrEvent & event)
+{
+}
+
+void CDrMainView::_showSaveButton(bool bShow)
+{
+       if (bShow && !_bSaveBtnShow && !_bPalletShowed) {
+               CDrDrawingView *pDrawingView = getControlObject < CDrDrawingView* >(_controlManager.find("pre-view"));
+               if (pDrawingView == nullptr) {
+                       WERROR("pDrawingView none");
+                       return;
+               }
+               if (pDrawingView) {
+                       if (pDrawingView->checkIsFirstHistory()) {
+                               return;
+                       }
+               }
+
+               Evas_Object *btn = elm_object_part_content_unset(_layout, "elm.button.send");
+               if (btn != NULL) {
+                       evas_object_del(btn);
+               }
+
+               char* res_path = app_get_resource_path();
+
+               btn = elm_button_add(_layout);
+               //elm_object_style_set(btn, "effect/default");
+               elm_object_style_set(btn, "popup/circle");
+               evas_object_size_hint_weight_set(btn, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+               if (CDrAppData::getInstance()->getLaunchMode() == DRAWING_SEND) {
+                       elm_object_domain_translatable_text_set(btn, LOCALE_DOMAIN, DRAWING_STRING_ID_TEXT_SEND);
+               } else {
+                       elm_object_domain_translatable_text_set(btn, LOCALE_DOMAIN, DRAWING_TEXT_SAVE);
+               }
+
+               evas_object_smart_callback_add(btn, "pressed", _onPressed, this);
+               evas_object_smart_callback_add(btn, "unpressed", _onUnPressed, this);
+
+               elm_object_part_content_set(_layout, "elm.button.send", btn);
+               elm_layout_signal_emit(_layout, "elm,state,button,send.moveup", "elm");
+               evas_object_show(btn);
+               free(res_path);
+               evas_object_smart_callback_add(btn, "clicked", _onSaveBtnClicked, this);
+               _bSaveBtnShow = true;
+
+               /* show tutorial popup */
+               if (pDrawingView && pDrawingView->checkHasHistory() && 0 == CDrAppData::getInstance()->getTutorialStatus()) {
+                       CDrTutorialView *pTutorialView = getControlObject < CDrTutorialView* >(_controlManager.find("elm.swallow.tutorial"));
+                       if (pTutorialView == nullptr) {
+                               CDrTutorialView *pTutorialView = new(std::nothrow) CDrTutorialView();
+                               _controlManager.attach(_layout, pTutorialView, "elm.swallow.tutorial");
+                               if (pTutorialView == NULL) {
+                                       WERROR("CDrTutorialView new failed");
+                                       return;
+                               }
+                               _bTutorialShowing = true;
+                               CDrAppData::getInstance()->setTutorialStatus(1);
+                               pTutorialView->showUndoGuide();
+                               pTutorialView->setOnCancelResult([&] () {
+                                       _bTutorialShowing = false;
+                                       WUiTimer::addJob([&](void *data) {
+                                                WINFO("Add job");
+                                                CDrMainView * pThis = (CDrMainView *) data;
+                                                pThis->_updateTutorialView(false);
+                                                }, this, getEvasObj());
+                                       });
+                       }
+               }
+       } else if (_bSaveBtnShow && !bShow) {
+               //elm_object_signal_emit(_layout, "elm.state.hide.mms", "*");
+               elm_layout_signal_emit(_layout, "movedown,rect,button_send", "elm");
+               Evas_Object *btn = elm_object_part_content_unset(_layout, "elm.button.send");
+               if (btn != nullptr) {
+                       evas_object_del(btn);
+               }
+               _bSaveBtnShow = false;
+       }
+}
+
+void CDrMainView::_onPressed(void *data, Evas_Object * obj, void *event_info)
+{
+       WINFO("OnPressedCb");
+
+       Evas_Object *bg = elm_object_part_content_get(obj, "bg");
+//     uxt_theme_object_set_color(bg, "AO029P");
+
+       Evas_Object *ic = elm_object_content_get(obj);
+//     uxt_theme_object_set_color(ic, "AO031P");
+}
+
+void CDrMainView::_onUnPressed(void *data, Evas_Object * obj, void *event_info)
+{
+       WINFO("OnUnPressedCb");
+
+       Evas_Object *bg = elm_object_part_content_get(obj, "bg");
+//     uxt_theme_object_set_color(bg, "AO029");
+
+       Evas_Object *ic = elm_object_content_get(obj);
+//     uxt_theme_object_set_color(ic, "AO031");
+}
+
+void CDrMainView::_onSaveBtnClicked(void *data, Evas_Object * obj, void *event_info)
+{
+       CDrMainView* pThis = (CDrMainView*)data;
+       WINFO("save");
+       std::string strFilePath;
+
+       if (CDrAppData::getInstance()->getLaunchMode() == DRAWING_SEND) {
+               char* dataPath = app_get_shared_data_path();
+        WINFO("dataPath = %s", dataPath);
+               if (dataPath == nullptr) {
+                       WINFO("DATA path is null");
+                       return;
+               }
+
+               strFilePath = dataPath;
+               free(dataPath);
+
+               std::string strFileName  ;
+               long long time = CDrUtil::getTimeStamp();
+               CDrUtil::getTimeName(time, strFileName);
+               strFilePath += strFileName;
+               strFilePath += DRAWING_OUTPUT_FILE_FORMAT_MMS;
+               /* issue<limitation> when send png thru MMS */
+               //WSINFO("save path %s",strFilePath.c_str());
+       } else {
+               strFilePath = DRAWING_SAVE_FILE_DIRECTORY;
+               std::string strFileName  ;
+               long long time = CDrUtil::getTimeStamp();
+               CDrUtil::getTimeName(time, strFileName);
+               strFilePath += strFileName;
+               strFilePath += DRAWING_OUTPUT_FILE_FORMAT_MMS;
+               //WSINFO("save path %s",strFilePath.c_str());
+       }
+       pThis->_showSaveButton(false);
+       if (pThis->_bPalletShowed) {
+               pThis->_hideOption();
+       }
+       /* fade out animation */
+       pThis->_startSaveAnimation();
+
+       /* save image */
+       CDrDrawingView *pDrawingView = getControlObject < CDrDrawingView* >(pThis->_controlManager.find("pre-view"));
+       if (pDrawingView) {
+               if (CDrAppData::getInstance()->getLaunchMode() == DRAWING_SEND) {
+                       /* Save to temp directory & send it */
+                       pDrawingView->saveImage(strFilePath, false);
+                       pThis->_sendImage(strFilePath);
+               } else {
+                       /* Save on media storage & register file in media db */
+                       pDrawingView->saveImage(strFilePath, true);
+               }
+       }
+}
+
+void CDrMainView::_sendImage(std::string strFilePath)
+{
+       app_control_h reply = NULL;
+       if (app_control_create(&reply) != APP_CONTROL_ERROR_NONE) {
+               WERROR("app_control_create failed!");
+               return;
+       }
+       app_control_h appService = CDrAppData::getInstance()->getAppService();
+
+       int ret = app_control_add_extra_data(reply, APP_CONTROL_DATA_PATH, strFilePath.c_str());
+       if (ret != APP_CONTROL_ERROR_NONE) {
+               WERROR("add return file failed!");
+       }
+       if (strFilePath.empty()) {
+               ret = app_control_reply_to_launch_request(reply, appService,
+                                                       APP_CONTROL_RESULT_FAILED);
+               app_control_destroy(reply);
+       } else {
+               ret = app_control_reply_to_launch_request(reply, appService,
+                                                       APP_CONTROL_RESULT_SUCCEEDED);
+               app_control_destroy(reply);
+       }
+       if (ret != 0) {
+               WERROR("send file failed!");
+       } else {
+               WINFO("send file successfully!");
+       }
+}
+
+void CDrMainView::_hideGuide()
+{
+       if (_bIndicatorTextShow) {
+               elm_object_signal_emit(_layout, "elm.state.hide.indicator", "*");
+               _bIndicatorTextShow = false;
+               _bPalletButtonShowed = false;
+
+               CDrDrawingView *pDrawingView = getControlObject < CDrDrawingView* >(_controlManager.find("pre-view"));
+               if (pDrawingView) {
+                       if (pDrawingView->checkIsFirstHistory() && !pDrawingView->checkHasHistory()) {
+                               _showHistoryIndex(true);
+                       }
+               }
+       }
+}
+
+void CDrMainView::_showGuide()
+{
+       if (!_bIndicatorTextShow) {
+               elm_object_signal_emit(_layout, "elm.state.show.indicator", "*");
+               _bIndicatorTextShow = true;
+               _bPalletButtonShowed = true;
+       }
+}
+
+void CDrMainView::_onBackBtnClicked(void *data, Evas_Object * obj, void *eventInfo)
+{
+       WENTER();
+       CDrMainView *pThis = (CDrMainView *) data;
+       if (pThis->_bPalletShowed) {
+               pThis->_hideOption();
+               return;
+       }
+       if (pThis->_bTutorialShowing) {
+               pThis->_updateTutorialView(false);
+               return;
+       }
+       CDrDrawingView *pDrawingView = getControlObject < CDrDrawingView* >(pThis->_controlManager.find("pre-view"));
+       if (pDrawingView == nullptr) {
+               return;
+       }
+       if (!pDrawingView->checkHasHistory()) {
+               pThis->_exitView();
+               return;
+       }
+
+       CDrClosePopup *pClosePopup = new(std::nothrow) CDrClosePopup();
+       if (pClosePopup == NULL) {
+               WERROR("Close popup new failed");
+               return;
+       }
+       pClosePopup->setCaption(DRAWING_POPUP_DISCARD_TITLE);
+       pClosePopup->setOnDiscardResult([pThis] () {
+                                                                       pThis->_exitView();
+                                                                       });
+       pClosePopup->setOnCancelResult([pThis] () {
+                                                                       CDrDrawingView *pDrawingView = getControlObject < CDrDrawingView* >(pThis->_controlManager.find("pre-view"));
+                                                                       if (pDrawingView) {
+                                                                               pDrawingView->activateUpdateAnimator(true);
+                                                                               pDrawingView->activateUndoRedoRotary(true);
+                                                                       }
+                                                                       });
+       pDrawingView->activateUndoRedoRotary(false);
+       pDrawingView->activateUpdateAnimator(false);
+       pThis->attachPopup(pClosePopup);
+}
+
+void CDrMainView::_exitView()
+{
+       this->popOut();
+}
+
+void CDrMainView::_onColorPickerBtnClicked(void *data, Evas_Object *obj, void *event_info)
+{
+       WINFO("_onColorPickerBtnClicked");
+
+       CDrMainView * pThis = (CDrMainView*)data;
+       pThis->_hideGuide();
+
+       pThis->_showOption();
+}
+
+void CDrMainView::_showOption()
+{
+       elm_object_signal_emit(_layout, "elm.state.hide.btnpallet", "*");
+       elm_object_signal_emit(_layout, "show,pallet,view", "elm");
+
+       if (_rotarySelector == nullptr) {
+               _createOptionLayout();
+       }
+       eext_rotary_object_event_activated_set(_rotarySelector, EINA_TRUE);
+
+       _showSaveButton(false);
+       _bPalletShowed = true;
+       CDrDrawingView *pDrawingView = getControlObject < CDrDrawingView* >(_controlManager.find("pre-view"));
+       if (pDrawingView) {
+               pDrawingView->setColorMenuState(_bPalletShowed);
+       }
+}
+void CDrMainView::_hideOption()
+{
+       elm_object_signal_emit(_layout, "hide,pallet,view", "elm");
+       _bPalletShowed = false;
+       CDrDrawingView *pDrawingView = getControlObject < CDrDrawingView* >(_controlManager.find("pre-view"));
+       if (pDrawingView) {
+               pDrawingView->setColorMenuState(_bPalletShowed);
+       }
+
+       eext_rotary_object_event_activated_set(_rotarySelector, EINA_FALSE);
+}
+
+void CDrMainView::_createOptionLayout()
+{
+       _rotarySelector = eext_rotary_selector_add(_layout);
+       evas_object_size_hint_fill_set(_rotarySelector, EVAS_HINT_FILL, EVAS_HINT_FILL);
+       evas_object_size_hint_weight_set(_rotarySelector, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+
+       evas_object_smart_callback_add(_rotarySelector, "item,selected", _onRotarySelectorItemSelected, this);
+       evas_object_smart_callback_add(_rotarySelector, "item,clicked", _onRotarySelectorItemClicked, this);
+
+       _addSelectorItem();
+       eext_rotary_object_event_activated_set(_rotarySelector, EINA_TRUE);
+
+       evas_object_show(_rotarySelector);
+       WUiTimer::addTimer(0.1, [&](void *data)->Eina_Bool {
+                               const Eina_List *list = eext_rotary_selector_items_get(_rotarySelector);
+                               if (list) {
+                                       Eext_Object_Item *curItem = (Eext_Object_Item *)eina_list_nth(list, _nItemSelected);
+                                       if (curItem) {
+                                               WINFO("set item");
+                                               eext_rotary_selector_selected_item_set(_rotarySelector, curItem);
+                                       }
+                               }
+                               return EINA_FALSE;
+                       }, this);
+
+
+       elm_object_part_content_set(_layout, "circle_menu", _rotarySelector);
+       WLEAVE();
+}
+
+void CDrMainView::_addSelectorItem()
+{
+       char* share_path = app_get_resource_path();
+       std::string iconPath(share_path);
+
+       for (int i = 0; i < _palletColorCode.size(); i++) {
+               Eext_Object_Item *item = eext_rotary_selector_item_append(_rotarySelector);
+
+               // normal item bg img
+               iconPath = share_path;
+               if (i <= COLOR_BG_SAME_PATH_NUMBER) {
+                       iconPath += _palletIconNormalBgPath[0];
+               }
+               WINFO("normal img %s", iconPath.c_str());
+
+               Evas_Object* icon = elm_image_add(_rotarySelector);
+               elm_image_file_set(icon, iconPath.c_str(), NULL);
+
+               int code_r = 0, code_g = 0, code_b = 0, code_a = 255;
+
+               edje_color_class_get(_palletColorCode[i].c_str(), &code_r, &code_g, &code_b, &code_a, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
+               if (i == COLOR_BG_SAME_PATH_NUMBER) {
+                       code_r = 255;
+                       code_g = 255;
+                       code_b = 255;
+                       code_a = 255;
+               }
+
+               WINFO("%d %d %d %d", code_r, code_g, code_b, code_a);
+               evas_object_color_set(icon, code_r, code_g, code_b, code_a);
+               eext_rotary_selector_item_part_content_set(item, "item,bg_image", EEXT_ROTARY_SELECTOR_ITEM_STATE_NORMAL, icon);
+
+               //selected item bg img
+               Evas_Object* iconSelected = elm_image_add(_rotarySelector);
+               iconPath = share_path;
+               if (i <= COLOR_BG_SAME_PATH_NUMBER) {
+                       iconPath += _palletIconSelBgPath[0];
+               }
+               elm_image_file_set(iconSelected, iconPath.c_str(), NULL);
+
+               code_r = 0;
+               code_g = 0;
+               code_b = 0;
+               code_a = 255;
+               edje_color_class_get(_palletColorCode[i].c_str(), &code_r, &code_g, &code_b, &code_a, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
+               if (i == COLOR_BG_SAME_PATH_NUMBER) {
+                       code_r = 255;
+                       code_g = 255;
+                       code_b = 255;
+                       code_a = 255;
+               }
+               evas_object_color_set(iconSelected, code_r, code_g, code_b, code_a);
+               eext_rotary_selector_item_part_content_set(item, "item,bg_image", EEXT_ROTARY_SELECTOR_ITEM_STATE_PRESSED, iconSelected);
+
+               //item icon
+               if (i == COLOR_BG_SAME_PATH_NUMBER) {
+                       Evas_Object* iconEraser = elm_image_add(_rotarySelector);
+                       iconPath = share_path;
+                       iconPath += _palletIconPath[0];
+
+                       elm_image_file_set(iconEraser, iconPath.c_str(), NULL);
+                       eext_rotary_selector_item_part_content_set(item, "item,icon", EEXT_ROTARY_SELECTOR_ITEM_STATE_NORMAL, iconEraser);
+               }
+
+               //center part
+               Evas_Object *img = elm_image_add(_rotarySelector);
+               iconPath = share_path;
+               if (i < COLOR_BG_SAME_PATH_NUMBER) {
+                       iconPath += _palletIconCenterPath[0];
+               }
+               elm_image_file_set(img, iconPath.c_str(), NULL);
+
+               if (i != COLOR_BG_SAME_PATH_NUMBER) {
+                       int code_r = 0, code_g = 0, code_b = 0, code_a = 255;
+                       int r, g, b, a;
+                       edje_color_class_get(_palletColorCode[i].c_str(), &code_r, &code_g, &code_b, &code_a, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
+                       evas_object_color_set(img, code_r, code_g, code_b, code_a);
+                       eext_rotary_selector_item_part_content_set(item, "selector,icon", EEXT_ROTARY_SELECTOR_ITEM_STATE_NORMAL, img);
+               } else {
+                       eext_more_option_item_domain_translatable_part_text_set(item, "selector,main_text", textdomain(NULL), "Eraser");
+               }
+       }
+
+       free(share_path);
+}
+
+void CDrMainView::_onRotarySelectorItemSelected(void *data, Evas_Object *obj, void *event_info)
+{
+       WENTER();
+}
+
+void CDrMainView::_onRotarySelectorItemClicked(void *data, Evas_Object *obj, void *event_info)
+{
+       WENTER();
+       CDrMainView *pThis = (CDrMainView *) data;
+
+       const Eina_List *rotary_selector_list = eext_rotary_selector_items_get(obj);
+
+       int i = 0;
+       Eina_List *l = NULL;
+       void *item = NULL;
+
+       EINA_LIST_FOREACH((Eina_List *)rotary_selector_list, l, item) {
+               if (event_info == item)
+               {
+                       break;
+               }
+               i++;
+       }
+
+       pThis->_nItemSelected = i;
+//     ea_theme_object_color_set(pThis->_drawingIcon, pThis->_palletColorCode[pThis->_nItemSelected].c_str());
+       CDrDrawingView *pDrawingView = getControlObject < CDrDrawingView* >(pThis->_controlManager.find("pre-view"));
+       if (pDrawingView) {
+               pDrawingView->setColorCode(pThis->_palletColorCode[pThis->_nItemSelected]);
+       }
+
+       pThis->_hideOption();
+}
+
+void CDrMainView::_onStrokeBtnClickCb(void *data, Evas_Object *obj, void *event_info)
+{
+       WINFO("strokeButtonClickCb");
+
+       CDrMainView * pThis = (CDrMainView*)data;
+       WNaviframeController *naviframe = (WNaviframeController *) (CDrAppData::getInstance()->getWindowController()->getBaseViewController());
+       if (naviframe == nullptr) {
+               return;
+       }
+       WINFO("stroke width %.1f", pThis->_dStrokeWidth);
+       elm_object_signal_emit(pThis->_layout, "elm.state.hide.btnpallet", "*");
+
+       CDrStrokeView* pView = new CDrStrokeView();
+       pView->setStrokeWidth(pThis->_dStrokeWidth);
+       pView->setStrokeWidthCb([pThis](double dWidth) {
+                       pThis->_dStrokeWidth = dWidth;
+                       WINFO("stroke width %.1f", pThis->_dStrokeWidth);
+
+                       CDrDrawingView *pDrawingView = getControlObject < CDrDrawingView* >(pThis->_controlManager.find("pre-view"));
+                       if (pDrawingView) {
+                               pDrawingView->setStrokeWidth(dWidth);
+                       }
+               });
+       naviframe->push(pView, "StrokeView");
+}
+
+void CDrMainView::_showPanel()
+{
+       WINFO("Panel");
+       if (_btnPalette == nullptr && _btnStroke == nullptr) {
+               return;
+       }
+       if (!_bPalletButtonShowed && !_bPalletShowed) {
+               WINFO("show Panel");
+
+               elm_object_signal_emit(_layout, "elm.state.show.btnpallet", "*");
+
+               _bPalletButtonShowed = true;
+
+       } else if (_bPalletButtonShowed ) {
+               WINFO("hide Panel");
+
+               elm_object_signal_emit(_layout, "elm.state.hide.btnpallet", "*");
+
+               _bPalletButtonShowed = false;
+       }
+}
+
+void CDrMainView::_startSaveAnimation()
+{
+       _stopSaveAnimation();
+
+       ecore_animator_frametime_set(1.0 /60);
+       _animSave = ecore_animator_timeline_add(0.75, _onAnimatorSave, this);
+}
+void CDrMainView::_stopSaveAnimation()
+{
+       if (_animSave) {
+                ecore_animator_del(_animSave);
+            _animSave = nullptr;
+       }
+}
+
+Eina_Bool CDrMainView::_onAnimatorSave(void *data, double pos)
+{
+       CDrMainView *pThis = (CDrMainView *) data;
+
+       if (pos == 1) {
+               CDrDrawingView *pDrawingView = getControlObject < CDrDrawingView* >(pThis->_controlManager.find("pre-view"));
+               if (pDrawingView != nullptr) {
+                       pDrawingView->activateUndoRedoRotary(false);
+               }
+
+               /* animation end,exit app */
+               WINFO("exit ");
+               pThis->_exitView();
+
+               pThis->_animSave = nullptr;
+
+               return ECORE_CALLBACK_DONE;
+       } else {
+               /* update fade out effect */
+               int alpha = 255 * (1 - pos);
+               pThis->_saveAnimationUpdate(alpha);
+
+               return ECORE_CALLBACK_RENEW;
+       }
+}
+
+void CDrMainView::_saveAnimationUpdate(int nStep)
+{
+       CDrDrawingView *pDrawingView = getControlObject < CDrDrawingView* >(_controlManager.find("pre-view"));
+       if (pDrawingView) {
+               pDrawingView->saveAnimationUpdate(nStep);
+       }
+}
+
+void CDrMainView::_showHistoryIndex(bool bShow)
+{
+       if (bShow && !_bHistoryCtrlShow) {
+               elm_object_signal_emit(_layout, "elm.state.show.index.mms", "*");
+               _bHistoryCtrlShow = true;
+       } else if (!bShow && _bHistoryCtrlShow) {
+               elm_object_signal_emit(_layout, "elm.state.hide.index", "*");
+               _bHistoryCtrlShow = false;
+       }
+}
+
+void CDrMainView::_updateTutorialView(bool bUndo)
+{
+       CDrTutorialView *pTutorialView = getControlObject < CDrTutorialView* >(_controlManager.find("elm.swallow.tutorial"));
+       if (pTutorialView != nullptr) {
+               WENTER();
+               if (bUndo) {
+                       pTutorialView->showRedoGuide();
+               } else {
+                       _controlManager.detach(_layout, "elm.swallow.tutorial");
+                       _bTutorialShowing = false;
+               }
+       }
+}
+
diff --git a/src/View/CDrMainView.h b/src/View/CDrMainView.h
new file mode 100755 (executable)
index 0000000..d625c27
--- /dev/null
@@ -0,0 +1,99 @@
+#ifndef _CDR_MAIN_VIEW_H_
+#define _CDR_MAIN_VIEW_H_
+
+
+#include <string>
+#include <cairo.h>
+#include <app.h>
+#include <app_common.h>
+//#include <efl_assist.h>
+#include <Elementary.h>
+//#include <ui_extension.h>
+#include <Ecore.h>
+#include <efl_extension.h>
+#include <vector>
+//#include <Ecore_X.h>
+#include "WContentViewController.h"
+#include "CDrEventListener.h"
+#include "CDrControlManager.h"
+#include "CDrHistoryControl.h"
+
+
+using namespace app_assist;
+
+
+
+class CDrMainView: public WContentViewController, public CDrEventListener {
+public:
+       CDrMainView();
+
+       void onEvent(const CDrEvent & event);
+
+   virtual Evas_Object * onCreateView(Evas_Object * parent, void *viewParam);
+   virtual void onDestroy();
+   virtual void onPushed(Elm_Object_Item * naviItem);
+   virtual Elm_Object_Item* onPushToNaviframe(Evas_Object* naviFrame);
+   void onCreated();
+
+protected:
+
+       virtual ~CDrMainView();
+private:
+       void _showSaveButton(bool bShow);
+
+       static void _onPressed(void *data, Evas_Object * obj, void *event_info);
+       static void _onUnPressed(void *data, Evas_Object * obj, void *event_info);
+       static void _onSaveBtnClicked(void *data, Evas_Object * obj, void *event_info);
+       static void _onBackBtnClicked(void *data, Evas_Object * obj, void *eventInfo);
+       static void _onColorPickerBtnClicked(void *data, Evas_Object *obj, void *event_info);
+       static void _onRotarySelectorItemClicked(void *data, Evas_Object *obj, void *event_info);
+       static void _onRotarySelectorItemSelected(void *data, Evas_Object *obj, void *event_info);
+       static Eina_Bool _onAnimatorSave(void *data, double pos);
+       static void _onStrokeBtnClickCb(void *data, Evas_Object *obj, void *event_info);
+
+       void _sendImage(std::string strFilePath);
+       void _hideGuide();
+       void _showGuide();
+       void _exitView();
+       void _createPalletButton();
+       void _createOptionLayout();
+       void _createStrokeButton();
+       void _addSelectorItem();
+       void _showOption();
+       void _hideOption();
+       void _showPanel();
+       void _startSaveAnimation();
+       void _stopSaveAnimation();
+       void _saveAnimationUpdate(int nStep);
+       void _showHistoryIndex(bool bShow);
+       void _updateTutorialView(bool bUndo);
+
+
+private:
+       Evas_Object *_layout;
+       Evas_Object* _btnPalette;
+       Evas_Object* _drawingIcon;
+       Evas_Object *_rotarySelector;
+       Ecore_Animator *_animSave;
+       Evas_Object *_btnStroke;
+
+       CDrControlManager _controlManager;
+       CDrHistoryControl _cHistoryCtrl;
+       bool _bSaveBtnShow;
+       bool _bIndicatorTextShow;
+       bool _bPalletShowed;
+       bool _bPalletButtonShowed;
+       bool _bTutorialShowing;
+       bool _bHistoryCtrlShow;
+       int  _nItemSelected;
+       double  _dStrokeWidth;
+
+       std::vector<std::string> _palletIconNormalBgPath;
+       std::vector<std::string> _palletIconSelBgPath;
+       std::vector<std::string> _palletIconPath;
+       std::vector<std::string> _palletIconCenterPath;
+       std::vector<std::string> _palletIconName;
+       std::vector<std::string> _palletColorCode;
+};
+#endif /* _CDR_MAIN_VIEW_H_ end */
+
diff --git a/src/View/CDrStrokeView.cpp b/src/View/CDrStrokeView.cpp
new file mode 100755 (executable)
index 0000000..637a4d5
--- /dev/null
@@ -0,0 +1,299 @@
+
+#include <efl_extension.h>
+#include "CDrStrokeView.h"
+#include "DrDefine.h"
+#include "CDrAppData.h"
+#include "CDrUtil.h"
+
+
+#define  STROKE_LINE_WIDTH_LEVEL_MIN     2.0
+#define  STROKE_LINE_WIDTH_LEVEL_MAX     10.0
+
+CDrStrokeView::CDrStrokeView()
+{
+       _layout = nullptr;
+       _strokeSlider = nullptr;
+       _circleSurface = nullptr;
+       _plusButton = nullptr;
+       _minusButton = nullptr;
+       _setStrokeWidthCb = nullptr;
+       _levelIndex = 3.0;
+}
+
+CDrStrokeView::~CDrStrokeView()
+{
+}
+
+Evas_Object * CDrStrokeView::onCreateView(Evas_Object * parent, void *viewParam)
+{
+       WENTER();
+
+       char* _path = app_get_resource_path();
+       std::string path(_path);
+       path += EDJ_FILE;
+
+       _layout = elm_layout_add(parent);
+       elm_layout_file_set(_layout, path.c_str(), "drawing/stroke_layout/circle");
+       free(_path);
+       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);
+
+
+       WNaviframeController *naviframe = (WNaviframeController *) (CDrAppData::getInstance()->getWindowController()->getBaseViewController());
+       if (naviframe == nullptr) {
+               return _layout;
+       }
+       _circleSurface = eext_circle_surface_naviframe_add(naviframe->getEvasObj() );
+
+       _strokeSlider = eext_circle_object_slider_add(_layout, _circleSurface);
+       eext_circle_object_value_min_max_set(_strokeSlider, STROKE_LINE_WIDTH_LEVEL_MIN, STROKE_LINE_WIDTH_LEVEL_MAX);  /* Outdoor mode UI removed temporary(07/07) */
+       eext_circle_object_value_set(_strokeSlider, _levelIndex);
+       eext_rotary_object_event_activated_set(_strokeSlider, EINA_TRUE);
+//     uxt_slider_set_touch_enabled(_strokeSlider, EINA_TRUE);
+       elm_layout_content_set(_layout, "elm.swallow.content", _strokeSlider);
+
+       evas_object_smart_callback_add(_strokeSlider, "value,changed", _strokeRotaryChanged, this);
+
+       evas_object_smart_callback_add(_strokeSlider, "clicked", _strokeSliderClicked, this);
+
+       evas_object_smart_callback_add(_layout, "language,changed", _strokeLanguageChanged, this);
+
+       _createPlusMinusButton();
+
+       std::string strLevel;
+       char text[100];
+       memset(text, 0, 100);
+       snprintf(text, sizeof(text), "%.1f", _levelIndex);
+       strLevel = text;
+       WINFO("%s", strLevel.c_str());
+       elm_object_part_text_set(_layout, "elm.text", strLevel.c_str());
+       elm_object_part_text_set(_layout, "elm.text.title", "stroke width");
+
+       return _layout;
+}
+
+void CDrStrokeView::onCreated()
+{
+}
+
+void CDrStrokeView::onDestroy()
+{
+}
+
+void CDrStrokeView::onPushed(Elm_Object_Item * naviItem)
+{
+       eext_object_event_callback_add(getEvasObj(), EEXT_CALLBACK_BACK, _backButtonClickedCb, this);
+}
+
+Elm_Object_Item* CDrStrokeView::onPushToNaviframe(Evas_Object* naviFrame)
+{
+       Elm_Object_Item* item = elm_naviframe_item_push(naviFrame, getTitle(), nullptr, nullptr,  getEvasObj(), "empty");
+       return item;
+}
+
+void CDrStrokeView::onEvent(const CDrEvent & event)
+{
+}
+
+void CDrStrokeView::setStrokeWidth(double dWidth)
+{
+       _levelIndex = dWidth;
+}
+
+void CDrStrokeView::setStrokeWidthCb(std::function < void(double) > handlerFunc)
+{
+       _setStrokeWidthCb = handlerFunc;
+}
+
+void CDrStrokeView::_backButtonClickedCb(void *data, Evas_Object * obj, void *eventInfo)
+{
+       WENTER();
+       CDrStrokeView *pThis = (CDrStrokeView *) data;
+       pThis->_exitView();
+}
+
+void CDrStrokeView::_exitView()
+{
+       this->popOut();
+}
+
+void CDrStrokeView::_createPlusMinusButton()
+{
+       char* resPath = app_get_resource_path();
+       std::string path(resPath);
+
+       _minusButton = elm_button_add(_layout);
+       elm_object_style_set(_minusButton, "drawing/stroke_effect/default");
+       evas_object_size_hint_weight_set(_minusButton, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+       elm_object_part_content_set(_layout, "btn.minus", _minusButton);
+       evas_object_smart_callback_add(_minusButton, "clicked", _minusButtonCb, this);
+
+       elm_access_info_set(_minusButton, ELM_ACCESS_INFO, "Minus");
+
+       Evas_Object* icon = elm_image_add(_minusButton);
+       elm_image_resizable_set(icon, EINA_FALSE, EINA_FALSE);
+       path += DRAWING_STROKE_SLIDER_ICON_MINUS;
+       elm_image_file_set(icon, path.c_str(), nullptr);
+       evas_object_size_hint_weight_set(icon, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+       elm_object_content_set(_minusButton, icon);
+       evas_object_show(icon);
+
+       _plusButton = elm_button_add(_layout);
+       elm_object_style_set(_plusButton, "drawing/stroke_effect/default");
+       evas_object_size_hint_weight_set(_plusButton, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+       elm_object_part_content_set(_layout, "btn.plus", _plusButton);
+       evas_object_smart_callback_add(_plusButton, "clicked", _plusButtonCb, this);
+
+       elm_access_info_set(_plusButton, ELM_ACCESS_INFO, "Plus");
+
+       Evas_Object* icon2 = elm_image_add(_plusButton);
+       path = resPath;
+       path += DRAWING_STROKE_SLIDER_ICON_PLUS;
+       //WINFO("- PATH %s",path.c_str());
+       elm_image_file_set(icon2, path.c_str(), nullptr);
+       elm_image_resizable_set(icon2, EINA_FALSE, EINA_FALSE);
+       evas_object_size_hint_weight_set(icon2, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+       elm_object_content_set(_plusButton, icon2);
+       evas_object_show(icon2);
+       free(resPath);
+
+       if (_levelIndex == STROKE_LINE_WIDTH_LEVEL_MAX ) {
+               elm_object_disabled_set(_plusButton, EINA_TRUE);
+               //edje_object_signal_emit(elm_layout_edje_get(_layout), "elm,state,disabled", "elm");
+       } else if (_levelIndex == STROKE_LINE_WIDTH_LEVEL_MIN ) {
+               elm_object_disabled_set(_minusButton, EINA_TRUE);
+       }
+}
+
+void CDrStrokeView::_strokeRotaryChanged(void *data, Evas_Object *obj, void *event_info)
+{
+       CDrStrokeView* pThis = (CDrStrokeView*)data;
+
+       double circle_level = eext_circle_object_value_get(obj);
+       WINFO("circle level: %.1f", circle_level);
+
+       /* Update level text */
+       std::string strLevel;
+       char text[100];
+       memset(text, 0, 100);
+       snprintf(text, sizeof(text), "%.1f", circle_level);
+       strLevel = text;
+       elm_object_part_text_set(pThis->_layout, "elm.text", strLevel.c_str());
+
+       if(circle_level == pThis->_levelIndex)
+       {
+               WINFO("same with old value");
+               return;
+       }
+
+       //setting_display_update_brightness_icon(bd->brightness_layout, circle_level);
+       pThis->_levelIndex = circle_level;
+
+       if (pThis->_levelIndex == STROKE_LINE_WIDTH_LEVEL_MIN) {
+               elm_object_disabled_set(pThis->_minusButton, EINA_TRUE);
+               elm_object_disabled_set(pThis->_plusButton, EINA_FALSE);
+       } else if (pThis->_levelIndex == STROKE_LINE_WIDTH_LEVEL_MAX) {
+               elm_object_disabled_set(pThis->_minusButton, EINA_FALSE);
+               elm_object_disabled_set(pThis->_plusButton, EINA_TRUE);
+       } else {
+               elm_object_disabled_set(pThis->_minusButton, EINA_FALSE);
+               elm_object_disabled_set(pThis->_plusButton, EINA_FALSE);
+       }
+       /* set to drawing part */
+       if (pThis->_setStrokeWidthCb) {
+               pThis->_setStrokeWidthCb(pThis->_levelIndex);
+       }
+}
+void CDrStrokeView::_strokeSliderClicked(void *data, Evas_Object *obj, void *event_info)
+{
+}
+void CDrStrokeView::_strokeLanguageChanged(void *data, Evas_Object *obj, void *event_info)
+{
+}
+
+void CDrStrokeView::_plusButtonCb(void* data, Evas_Object* obj, void* event_info)
+{
+       CDrStrokeView* pThis = (CDrStrokeView*)data;
+
+       double level = eext_circle_object_value_get(pThis->_strokeSlider);
+       if(level > STROKE_LINE_WIDTH_LEVEL_MAX) {
+               return;
+       }
+
+       double circle_level = level + 1;
+       /* set to drawing part */
+       if (pThis->_setStrokeWidthCb) {
+               pThis->_setStrokeWidthCb(circle_level);
+       }
+
+       /* Update level text */
+       std::string strLevel;
+       char text[100];
+       memset(text, 0, 100);
+       snprintf(text, sizeof(text), "%.1f", circle_level);
+       strLevel = text;
+       elm_object_part_text_set(pThis->_layout, "elm.text", strLevel.c_str());
+
+       //if(uxt_slider_set_value(pThis->_strokeSlider, (double)(eext_circle_object_value_get(pThis->_strokeSlider) + 1.0), EINA_TRUE) != UXT_ERROR_NONE)
+       {
+               WERROR("uxt_slider_set_value is fail!");
+       }
+
+       //setting_display_update_brightness_icon(bd->brightness_layout, circle_level);
+
+       pThis->_levelIndex = circle_level;
+
+       elm_object_disabled_set(pThis->_minusButton, EINA_FALSE);
+
+       if(pThis->_plusButton)
+       {
+               if(circle_level == STROKE_LINE_WIDTH_LEVEL_MAX)
+                       elm_object_disabled_set(pThis->_plusButton, EINA_TRUE);
+               else
+                       elm_object_disabled_set(pThis->_plusButton, EINA_FALSE);
+       }
+}
+void CDrStrokeView::_minusButtonCb(void* data, Evas_Object* obj, void* event_info)
+{
+       CDrStrokeView* pThis = (CDrStrokeView*)data;
+
+       double level = eext_circle_object_value_get(pThis->_strokeSlider);
+       if(level < STROKE_LINE_WIDTH_LEVEL_MIN) {
+               return;
+       }
+
+       double circle_level = level - 1;
+       /* set to drawing part */
+       if (pThis->_setStrokeWidthCb) {
+               pThis->_setStrokeWidthCb(circle_level);
+       }
+
+       /* Update level text */
+       std::string strLevel;
+       char text[100];
+       memset(text, 0, 100);
+       snprintf(text, sizeof(text), "%.1f", circle_level);
+       strLevel = text;
+       elm_object_part_text_set(pThis->_layout, "elm.text", strLevel.c_str());
+
+       //if(uxt_slider_set_value(pThis->_strokeSlider, (double)(eext_circle_object_value_get(pThis->_strokeSlider) - 1.0), EINA_TRUE) != UXT_ERROR_NONE)
+       {
+               WERROR("uxt_slider_set_value is fail!");
+       }
+
+       //setting_display_update_brightness_icon(bd->brightness_layout, circle_level);
+
+       pThis->_levelIndex = circle_level;
+
+       elm_object_disabled_set(pThis->_plusButton, EINA_FALSE);
+
+       if(pThis->_minusButton)
+       {
+               if(circle_level == STROKE_LINE_WIDTH_LEVEL_MIN)
+                       elm_object_disabled_set(pThis->_minusButton, EINA_TRUE);
+               else
+                       elm_object_disabled_set(pThis->_minusButton, EINA_FALSE);
+       }
+}
+
+
diff --git a/src/View/CDrStrokeView.h b/src/View/CDrStrokeView.h
new file mode 100755 (executable)
index 0000000..5211f8d
--- /dev/null
@@ -0,0 +1,64 @@
+#ifndef _CDR_STROKE_VIEW_H_
+#define _CDR_STROKE_VIEW_H_
+
+
+#include <string>
+#include <cairo.h>
+#include <app.h>
+#include <app_common.h>
+//#include <efl_assist.h>
+#include <Elementary.h>
+//#include <ui_extension.h>
+#include <Ecore.h>
+#include <efl_extension.h>
+#include <vector>
+#include "WContentViewController.h"
+#include "CDrEventListener.h"
+#include "CDrControlManager.h"
+
+
+using namespace app_assist;
+
+
+
+class CDrStrokeView: public WContentViewController, public CDrEventListener {
+public:
+       CDrStrokeView();
+
+       void onEvent(const CDrEvent & event);
+
+       virtual Evas_Object * onCreateView(Evas_Object * parent, void *viewParam);
+       virtual void onDestroy();
+       virtual void onPushed(Elm_Object_Item * naviItem);
+       virtual Elm_Object_Item* onPushToNaviframe(Evas_Object* naviFrame);
+       void onCreated();
+       void setStrokeWidthCb(std::function < void(double) > handlerFunc);
+       void setStrokeWidth(double dWidth);
+
+protected:
+
+       virtual ~CDrStrokeView();
+private:
+       static void _backButtonClickedCb(void *data, Evas_Object * obj, void *eventInfo);
+       static void     _strokeRotaryChanged(void *data, Evas_Object *obj, void *event_info);
+       static void     _strokeSliderClicked(void *data, Evas_Object *obj, void *event_info);
+       static void     _strokeLanguageChanged(void *data, Evas_Object *obj, void *event_info);
+       static void _plusButtonCb(void* data, Evas_Object* obj, void* event_info);
+       static void _minusButtonCb(void* data, Evas_Object* obj, void* event_info);
+       void _exitView();
+       void _createPlusMinusButton();
+
+private:
+       Evas_Object *_layout;
+       Evas_Object* _strokeSlider;
+       Evas_Object* _plusButton;
+       Evas_Object *_minusButton;
+       Eext_Circle_Surface *_circleSurface;
+       CDrControlManager _controlManager;
+
+       double  _levelIndex;
+
+       std::function < void(double) > _setStrokeWidthCb;
+};
+#endif /* _CDR_MAIN_VIEW_H_ end */
+
diff --git a/src/app-assist-efl/WApp.cpp b/src/app-assist-efl/WApp.cpp
new file mode 100644 (file)
index 0000000..dd6e7a5
--- /dev/null
@@ -0,0 +1,149 @@
+/*
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0
+ *
+ * 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 "WApp.h"
+
+#include <memory.h>
+
+#include "WDebugInternal.h"
+#include "WWindowController.h"
+#include "WMenuPopupControllerImpl.h"
+
+using namespace app_assist;
+
+namespace app_assist
+{
+
+class _WAppImpl
+{
+public:
+    _WAppImpl(): __window(nullptr), __firstLaunch(true) {}
+    ~_WAppImpl();
+public:
+    WWindowController* __window;
+    bool __firstLaunch;
+    //
+    static bool __onCreate(void* data);
+    static void __onTerminate(void* data);
+    static void __onPause(void* data);
+    static void __onResume(void* data);
+    static void __onAppControl(app_control_h request, void* data);
+};
+}
+
+_WAppImpl::~_WAppImpl()
+{
+}
+
+bool _WAppImpl::__onCreate(void* data)
+{
+    WHIT();
+
+    auto app = (WApp*)data;
+    return app->onCreate();
+}
+
+void _WAppImpl::__onTerminate(void* data)
+{
+    WHIT();
+
+    auto app = (WApp*)data;
+    app->onTerminate();
+
+    // To reverse destruction order
+    // It will destroy View and then Naviframe instance before the window is destroyed.
+    if (app->__pv->__window)
+        app->__pv->__window->destroyBaseViewController();
+
+    // window evas object "del" callback will be called by system.
+}
+
+void _WAppImpl::__onPause(void* data)
+{
+    WHIT();
+
+    _WMenuPopupControllerImpl::destroyLastMenuPopup();
+
+    auto app = (WApp*)data;
+    app->onPause();
+}
+
+void _WAppImpl::__onResume(void* data)
+{
+    WHIT();
+
+    auto app = (WApp*)data;
+    app->onResume();
+}
+
+void _WAppImpl::__onAppControl(app_control_h request, void* data)
+{
+    WHIT();
+
+    auto app = (WApp*)data;
+    app->onAppControl(request, app->__pv->__firstLaunch);
+    //
+    app->__pv->__firstLaunch = false;
+}
+
+
+WApp::WApp()
+{
+    WDEBUG("app-assist version=%s", WVersion_get());
+
+    __pv = new _WAppImpl();
+}
+
+WApp::~WApp()
+{
+    WHIT();
+    delete __pv;
+}
+
+int WApp::start(int argc, char* argv[])
+{
+    return onStart(argc, argv);
+}
+
+app_assist::WWindowController* WApp::getWindowController()
+{
+    return __pv->__window;
+}
+
+bool WApp::attachWindowController(app_assist::WWindowController* win)
+{
+    WASSERT(__pv->__window == nullptr);
+    __pv->__window = win;
+    return win->create();
+}
+
+void WApp::onAppControl(app_control_h request, bool firstLaunch)
+{
+}
+
+int WApp::onStart(int argc, char* argv[])
+{
+    ui_app_lifecycle_callback_s cb;
+    memset(&cb, 0, sizeof(cb));
+    cb.create = _WAppImpl::__onCreate;
+    cb.terminate = _WAppImpl::__onTerminate;
+    cb.pause = _WAppImpl::__onPause;
+    cb.resume = _WAppImpl::__onResume;
+    cb.app_control = _WAppImpl::__onAppControl;
+
+    return ui_app_main(argc, argv, &cb, this);
+}
diff --git a/src/app-assist-efl/WAppEventHandler.cpp b/src/app-assist-efl/WAppEventHandler.cpp
new file mode 100644 (file)
index 0000000..6b86c41
--- /dev/null
@@ -0,0 +1,104 @@
+/*
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0
+ *
+ * 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 "WAppEventHandler.h"
+#include <app.h>
+#include "WDebugInternal.h"
+#include "WDefineInternal.h"
+
+using namespace app_assist;
+
+namespace app_assist
+{
+
+class _WAppEventHandlerImpl
+{
+public:
+    _WAppEventHandlerImpl();
+    ~_WAppEventHandlerImpl();
+public:
+    //
+    app_event_handler_h __handle;
+    //
+    void* __userData;
+    std::function<void(app_event_info_h, void*)> __eventHandlerFunc;
+
+    static void __eventCb(app_event_info_h eventInfo, void* userData);
+    void __removeEventHandler();
+};
+}
+
+_WAppEventHandlerImpl::_WAppEventHandlerImpl():
+    __handle(nullptr),
+    __userData(nullptr)
+{
+}
+
+_WAppEventHandlerImpl::~_WAppEventHandlerImpl()
+{
+    __removeEventHandler();
+}
+
+
+void _WAppEventHandlerImpl::__eventCb(app_event_info_h eventInfo, void* userData)
+{
+    auto p = (_WAppEventHandlerImpl*)userData;
+    p->__eventHandlerFunc(eventInfo, p->__userData);
+}
+
+void _WAppEventHandlerImpl::__removeEventHandler()
+{
+    if (__handle) {
+        ui_app_remove_event_handler(__handle);
+        __handle = nullptr;
+        __userData = nullptr;
+    }
+}
+
+WAppEventHandler::WAppEventHandler()
+{
+    __pv = new _WAppEventHandlerImpl();
+}
+
+WAppEventHandler::~WAppEventHandler()
+{
+    delete __pv;
+}
+
+
+int WAppEventHandler::addEventHandler(app_event_type_e eventType, const std::function<void(app_event_info_h, void*)>& handlerFunc, void* userData)
+{
+    removeEventHandler();
+
+    __pv->__eventHandlerFunc = handlerFunc;
+    __pv->__userData = userData;
+
+    return ui_app_add_event_handler(&__pv->__handle, eventType, __pv->__eventCb, __pv);
+}
+
+void WAppEventHandler::removeEventHandler()
+{
+    __pv->__removeEventHandler();
+}
+
+app_event_handler_h WAppEventHandler::getHandle()
+{
+    return __pv->__handle;
+}
+
+
diff --git a/src/app-assist-efl/WContentViewController.cpp b/src/app-assist-efl/WContentViewController.cpp
new file mode 100644 (file)
index 0000000..f76bbb4
--- /dev/null
@@ -0,0 +1,228 @@
+/*
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0
+ *
+ * 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 "WContentViewController.h"
+#include <memory.h>
+#include <string>
+#include <app.h>
+#include <Elementary.h>
+#include <efl_extension.h>
+#include "IWWindowController.h"
+#include "WDebugInternal.h"
+#include "WDefineInternal.h"
+#include "WContentViewControllerImpl.h"
+
+using namespace app_assist;
+
+#define _CLASS_NAME    "WContentViewController"
+
+WContentViewController::WContentViewController()
+{
+    WHIT();
+    __pv = new _WContentViewControllerImpl();
+}
+
+WContentViewController::WContentViewController(const char* name) : __pv(new _WContentViewControllerImpl())
+{
+    WHIT();
+    setName(name);
+}
+
+WContentViewController::~WContentViewController()
+{
+    WHIT();
+    delete __pv;
+}
+
+const char* WContentViewController::getClassName() const
+{
+    return _CLASS_NAME;
+}
+
+bool WContentViewController::create(Evas_Object* parent, void* param)
+{
+    return WViewController::create(parent, param);
+}
+
+void WContentViewController::destroy()
+{
+    if (getEvasObj()) {
+        if (__pv->__naviItem && __pv->__isViewNaviItem) {
+            elm_object_item_del(__pv->__naviItem);
+        } else {
+            evas_object_del(getEvasObj());
+        }
+        // Do not leave any code here.
+        // After executing upper statement "evas_object_del", this object will be deleted at evas object deletion callback!
+    } else {
+        onDestroy();
+        delete this;
+    }
+}
+
+void WContentViewController::setTitle(const char* title)
+{
+    if (__pv->__title) {
+        free(__pv->__title);
+        __pv->__title = nullptr;
+    }
+    if (title) {
+        __pv->__title = (char*)malloc(strlen(title) + 1);
+        strcpy(__pv->__title, title);
+    }
+}
+const char* WContentViewController::getTitle()
+{
+    return __pv->__title;
+}
+
+void WContentViewController::setOnPushed(const std::function<void(Elm_Object_Item*)>& delegateFunc)
+{
+    __pv->__pushedDelegate = delegateFunc;
+}
+
+bool WContentViewController::popOut()
+{
+    if (getEvasObj() == nullptr) {
+        WWARNING("Not created view! No Evas Object!");
+        return false;
+    }
+    if (getNaviframeController() == nullptr) {
+        WWARNING("Not pushed to naviframe!");
+        return false;
+    }
+
+    if (__pv->__naviItem != elm_naviframe_top_item_get(getNaviframeController()->getEvasObj())) {
+        WASSERT_EX(0, "This view is not on Top of Naviframe!");
+        return false;
+    }
+
+    destroyPopup(); // Before popping out view, pop-up is destroyed, if it has.Because pop-up is disappeared too late.
+
+    elm_naviframe_item_pop(getNaviframeController()->getEvasObj());
+    return true;
+}
+
+bool WContentViewController::onPop()
+{
+    return true;
+}
+
+void WContentViewController::onBecomeTop()
+{
+}
+
+WNaviframeController* WContentViewController::getNaviframeController()
+{
+    if (__pv->__naviframe == nullptr) {
+        WWARNING("naviframe does not exist!");
+    }
+
+    return __pv->__naviframe;
+}
+
+Elm_Object_Item* WContentViewController::getNaviItem()
+{
+    if (__pv->__naviItem == nullptr) {
+        WWARNING("naviItem does not exist!");
+    }
+
+    return __pv->__naviItem;
+}
+
+void WContentViewController::onPushed(Elm_Object_Item* naviItem)
+{
+}
+
+Elm_Object_Item* WContentViewController::onPushToNaviframe(Evas_Object* naviFrame)
+{
+    return nullptr;
+}
+
+
+Evas_Object* WContentViewController::onCreateView(Evas_Object* parent, void* param)
+{
+    Evas_Object* layout = elm_layout_add(parent);
+    evas_object_size_hint_weight_set(layout, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+
+    char* path = app_get_resource_path();
+    if (path == nullptr) {
+        WERROR("Failed to get resource path=nullptr");
+        return layout;
+    }
+    std::string edjPath(path);
+    free(path);
+    edjPath += "edje/app-assist-efl.edj";
+
+    if (elm_layout_file_set(layout, edjPath.c_str(), "default-view") == EINA_TRUE) {
+        Evas_Object* rect = evas_object_rectangle_add(evas_object_evas_get(layout));
+        evas_object_color_set(rect, rand() % 256, rand() % 256, rand() % 256, 255);
+        evas_object_size_hint_weight_set(rect, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+        evas_object_size_hint_align_set(rect, EVAS_HINT_FILL, EVAS_HINT_FILL);
+
+        elm_object_part_content_set(layout, "rect", rect);
+        if (getName() != nullptr)
+            elm_object_part_text_set(layout, "name", getName());
+
+    } else {
+        WERROR("Fail to set layout. Check EDJ file(%s)", edjPath.c_str());
+    }
+
+    evas_object_show(layout);
+
+    return layout;
+}
+
+void WContentViewController::onSetContainerProperties(WNaviframeController* naviframe, Elm_Object_Item* item)
+{
+}
+
+void WContentViewController::onSetAsPageContent(Elm_Object_Item* parentNaviItem)
+{
+}
+
+void WContentViewController::onSetMoreButton(Elm_Object_Item* naviItem, Evas_Smart_Cb clickedCb, void* userData)
+{
+    eext_object_event_callback_add(getEvasObj(), EEXT_CALLBACK_MORE, clickedCb, userData);
+//     Evas_Object *btn = elm_button_add( getNaviframeController()->getEvasObj() );
+//     elm_object_style_set(btn, "naviframe/more/default");
+//     evas_object_show(btn);
+//     evas_object_smart_callback_add(btn, "clicked", clickedCb, userData);
+//     elm_object_item_part_content_set(naviItem, "toolbar_more_btn", btn);
+}
+
+bool WContentViewController::setMoreButton(Elm_Object_Item* naviItem, Evas_Smart_Cb clickedCb, void* userData)
+{
+    onSetMoreButton(naviItem, clickedCb, userData);
+    return true;
+}
+
+void app_assist::wcontentviewcontroller_set_container_properties(WContentViewController* view, WNaviframeController* naviframe)
+{
+    _WContentViewControllerImpl::setContainerProperties(view, naviframe);
+}
+
+void app_assist::wcontentviewcontroller_set_container_naviitem_property(WContentViewController* view, Elm_Object_Item* item, bool isViewNaviItem)
+{
+    _WContentViewControllerImpl::setContainerNaviitemProperty(view, item, isViewNaviItem);
+}
+
+void app_assist::wcontentviewcontroller_propagate_container_properties_to_childviews(WContentViewController* view)
+{
+    _WContentViewControllerImpl::propagateContainerPropertiesToChildViews(view);
+}
diff --git a/src/app-assist-efl/WContentViewControllerImpl.cpp b/src/app-assist-efl/WContentViewControllerImpl.cpp
new file mode 100644 (file)
index 0000000..562fdcc
--- /dev/null
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0
+ *
+ * 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 "WContentViewControllerImpl.h"
+#include "WContentViewController.h"
+
+using namespace app_assist;
+
+_WContentViewControllerImpl::_WContentViewControllerImpl():
+    __title(nullptr),
+    __naviItem(nullptr),
+    __isViewNaviItem(true),
+    __naviframe(nullptr)
+{
+}
+
+_WContentViewControllerImpl::~_WContentViewControllerImpl()
+{
+    free(__title);
+}
+
+bool _WContentViewControllerImpl::callPushedHandlerFunc(Elm_Object_Item* naviItem)
+{
+    if (__pushedDelegate) {
+        __pushedDelegate(naviItem);
+        return true;
+    }
+    return false;
+}
+
+void _WContentViewControllerImpl::setContainerProperties(WContentViewController* view, WNaviframeController* naviframe)
+{
+    view->__pv->__naviframe = naviframe;
+}
+
+void _WContentViewControllerImpl::setContainerNaviitemProperty(WContentViewController* view, Elm_Object_Item* item, bool isViewNaviItem)
+{
+    view->__pv->__isViewNaviItem = isViewNaviItem;
+    view->__pv->__naviItem = item;
+}
+
+void _WContentViewControllerImpl::propagateContainerPropertiesToChildViews(WContentViewController* view)
+{
+    view->onSetContainerProperties(view->getNaviframeController(), view->getNaviItem());
+}
+
+
diff --git a/src/app-assist-efl/WEvasObject.cpp b/src/app-assist-efl/WEvasObject.cpp
new file mode 100644 (file)
index 0000000..0acde59
--- /dev/null
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0
+ *
+ * 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 "WEvasObject.h"
+#include "WDebugInternal.h"
+
+using namespace app_assist;
+
+namespace app_assist
+{
+
+class _WEvasObjectImpl : public IWEvasObject
+{
+public:
+    _WEvasObjectImpl(Evas_Object* obj): __evasObj(obj) {}
+    _WEvasObjectImpl() = delete;
+
+public:
+    virtual Evas_Object* getEvasObj() {
+        return __evasObj;
+    }
+
+    static void __objDelCb(void* data, Evas* evas, Evas_Object* obj, void* event_info) {
+        auto p = (_WEvasObjectImpl*)data;
+        delete p;
+    }
+
+    std::shared_ptr<IWEvasObject> __selfPtr;
+    Evas_Object* __evasObj;
+};
+}
+
+std::weak_ptr<IWEvasObject> app_assist::wevasobject_get_weak_ptr(Evas_Object* obj)
+{
+    auto pImpl = new _WEvasObjectImpl(obj);
+    std::shared_ptr<IWEvasObject> sp(pImpl, [](IWEvasObject * p) {});
+    pImpl->__selfPtr = sp;
+
+    evas_object_event_callback_add(obj, EVAS_CALLBACK_DEL, _WEvasObjectImpl::__objDelCb, pImpl);
+
+    return std::weak_ptr<IWEvasObject>(pImpl->__selfPtr);
+}
+
diff --git a/src/app-assist-efl/WGengridItem.cpp b/src/app-assist-efl/WGengridItem.cpp
new file mode 100644 (file)
index 0000000..cd54430
--- /dev/null
@@ -0,0 +1,126 @@
+/*
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0
+ *
+ * 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 "WGengridItem.h"
+#include <memory.h>
+#include <Elementary.h>
+#include "WDebugInternal.h"
+#include "WDefineInternal.h"
+#include "WViewController.h"
+
+using namespace app_assist;
+
+namespace app_assist
+{
+
+class _WGengridItemImpl
+{
+public:
+    _WGengridItemImpl(): __objectItem(nullptr) {};
+    ~_WGengridItemImpl() {};
+    static void __selectCb(void *data, Evas_Object *obj, void *event_info);
+public:
+    Elm_Object_Item* __objectItem;
+};
+}
+
+WGengridItem::WGengridItem() : __pv(new _WGengridItemImpl())
+{
+}
+
+WGengridItem::~WGengridItem()
+{
+    delete __pv;
+}
+
+Elm_Gengrid_Item_Class* WGengridItem::getItemClassStatic()
+{
+    return nullptr;
+}
+
+Elm_Gengrid_Item_Class* WGengridItem::getItemClassNew()
+{
+    return nullptr;
+}
+
+void WGengridItem::onSelect(Elm_Object_Item* objItem)
+{
+}
+
+void WGengridItem::onSetElmObjectItem(Elm_Object_Item* objItem)
+{
+}
+
+Elm_Object_Item* WGengridItem::getElmObjectItem()
+{
+    return __pv->__objectItem;
+}
+
+void WGengridItem::setElmObjectItem(Elm_Object_Item* objItem)
+{
+    __pv->__objectItem = objItem;
+    onSetElmObjectItem(objItem);
+}
+
+void _WGengridItemImpl::__selectCb(void *data, Evas_Object *obj, void *event_info)
+{
+    Elm_Object_Item* gengridItem = (Elm_Object_Item*) event_info;
+    elm_gengrid_item_selected_set(gengridItem, EINA_FALSE);
+
+    auto item = (WGengridItem*)data;
+    item->onSelect(gengridItem);
+}
+
+Evas_Smart_Cb WGengridItem::getSelectCb()
+{
+    return _WGengridItemImpl::__selectCb;
+}
+
+bool WGengridItem::attachToParentViewController(WViewController* popup)
+{
+    if (__pv->__objectItem == nullptr) {
+        WERROR("object item is not created!");
+        return false;
+    }
+
+    Evas_Object* obj = elm_object_item_widget_get(__pv->__objectItem);
+    while (obj != nullptr) {
+        WViewController* view = wviewcontroller_get_instance_from_evasobj(obj);
+        if (view != nullptr) {
+            view->attachPopup(popup);
+            return true;
+        }
+        obj = elm_object_parent_widget_get(obj);
+    }
+    WERROR("Can not find view instance!");
+    return false;
+}
+
+Elm_Object_Item* app_assist::wgengrid_item_append(Evas_Object* gengrid, const Elm_Gengrid_Item_Class* itc, app_assist::WGengridItem* item)
+{
+    Elm_Object_Item* obj = elm_gengrid_item_append(gengrid, itc, item, item->getSelectCb(), item);
+    item->setElmObjectItem(obj);
+    return obj;
+}
+
+Elm_Object_Item* app_assist::wgengrid_item_append_with_callback(Evas_Object* gengrid, const Elm_Gengrid_Item_Class* itc, app_assist::WGengridItem* item, Evas_Smart_Cb selectCb, const void* userData)
+{
+    Elm_Object_Item* obj = elm_gengrid_item_append(gengrid, itc, item, selectCb, userData);
+    if (item)
+        item->setElmObjectItem(obj);
+    return obj;
+}
diff --git a/src/app-assist-efl/WGenlistItem.cpp b/src/app-assist-efl/WGenlistItem.cpp
new file mode 100644 (file)
index 0000000..501897d
--- /dev/null
@@ -0,0 +1,128 @@
+/*
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0
+ *
+ * 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 "WGenlistItem.h"
+#include <memory.h>
+#include <Elementary.h>
+#include "WDebugInternal.h"
+#include "WDefineInternal.h"
+#include "WViewController.h"
+
+using namespace app_assist;
+
+namespace app_assist
+{
+
+class _WGenlistItemImpl
+{
+public:
+    _WGenlistItemImpl(): __objectItem(nullptr) {};
+    ~_WGenlistItemImpl() {};
+    static void __selectCb(void *data, Evas_Object *obj, void *event_info);
+public:
+    Elm_Object_Item* __objectItem;
+};
+}
+
+WGenlistItem::WGenlistItem() : __pv(new _WGenlistItemImpl())
+{
+}
+
+WGenlistItem::~WGenlistItem()
+{
+    delete __pv;
+}
+
+Elm_Genlist_Item_Class* WGenlistItem::getItemClassStatic()
+{
+    return nullptr;
+}
+
+Elm_Genlist_Item_Class* WGenlistItem::getItemClassNew()
+{
+    return nullptr;
+}
+
+void WGenlistItem::onSelect(Elm_Object_Item* objItem)
+{
+}
+
+void WGenlistItem::onSetElmObjectItem(Elm_Object_Item* objItem)
+{
+}
+
+Elm_Object_Item* WGenlistItem::getElmObjectItem()
+{
+    return __pv->__objectItem;
+}
+
+void WGenlistItem::setElmObjectItem(Elm_Object_Item* objItem)
+{
+    __pv->__objectItem = objItem;
+    onSetElmObjectItem(objItem);
+}
+
+
+void _WGenlistItemImpl::__selectCb(void *data, Evas_Object *obj, void *event_info)
+{
+    Elm_Object_Item* genlistItem = (Elm_Object_Item*) event_info;
+    elm_genlist_item_selected_set(genlistItem, EINA_FALSE);
+
+    auto item = (WGenlistItem*)data;
+    item->onSelect(genlistItem);
+}
+
+Evas_Smart_Cb WGenlistItem::getSelectCb()
+{
+    return _WGenlistItemImpl::__selectCb;
+}
+
+bool WGenlistItem::attachToParentViewController(WViewController* popup)
+{
+    if (__pv->__objectItem == nullptr) {
+        WERROR("object item has not been set! call setElmObjectItem");
+        return false;
+    }
+
+    Evas_Object* obj = elm_object_item_widget_get(__pv->__objectItem);
+    while (obj != nullptr) {
+        WViewController* view = wviewcontroller_get_instance_from_evasobj(obj);
+        if (view != nullptr) {
+            view->attachPopup(popup);
+            return true;
+        }
+        obj = elm_object_parent_widget_get(obj);
+    }
+    WERROR("Can not find view instance!");
+    return false;
+}
+
+Elm_Object_Item* app_assist::wgenlist_item_append(Evas_Object* genlist, const Elm_Genlist_Item_Class* itc, WGenlistItem* item, Elm_Genlist_Item_Type type)
+{
+    Elm_Object_Item* obj = elm_genlist_item_append(genlist, itc, item, nullptr, type, item->getSelectCb(), item);
+    item->setElmObjectItem(obj);
+    return obj;
+}
+
+Elm_Object_Item* app_assist::wgenlist_item_append_with_callback(Evas_Object* genlist, const Elm_Genlist_Item_Class* itc, WGenlistItem* item, Elm_Genlist_Item_Type type, Evas_Smart_Cb selectCb, const void* userData)
+{
+    Elm_Object_Item* obj = elm_genlist_item_append(genlist, itc, item, nullptr, type, selectCb, userData);
+    if (item)
+        item->setElmObjectItem(obj);
+    return obj;
+}
diff --git a/src/app-assist-efl/WMenuPopupController.cpp b/src/app-assist-efl/WMenuPopupController.cpp
new file mode 100644 (file)
index 0000000..49748cf
--- /dev/null
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0
+ *
+ * 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 "WMenuPopupController.h"
+#include "WMenuPopupControllerImpl.h"
+#include "WDebugInternal.h"
+
+using namespace app_assist;
+
+WMenuPopupController::WMenuPopupController(): __pv(new _WMenuPopupControllerImpl())
+{
+    WHIT();
+}
+
+WMenuPopupController::~WMenuPopupController()
+{
+    WHIT();
+    if (__pv->__resizableBaseObj)
+        evas_object_event_callback_del(__pv->__resizableBaseObj, EVAS_CALLBACK_RESIZE, _WMenuPopupControllerImpl::__popupResizeCb);
+
+    if (__pv->__win)
+        evas_object_smart_callback_del(__pv->__win, "rotation,changed",  _WMenuPopupControllerImpl::__popupWinRotateCb);
+
+    delete __pv;
+}
+
+Elm_Object_Item* WMenuPopupController::appendItem(const char* label, const std::function< void()>& selectCb)
+{
+    if (getEvasObj() == nullptr) {
+        WERROR("Create pop-up first!");
+        return nullptr;
+    }
+
+    __pv->__vSelectItemCb.push_back(selectCb);
+    return elm_ctxpopup_item_append(getEvasObj(), label, nullptr, _WMenuPopupControllerImpl::__popupSelectCb, (void*)(__pv->__vSelectItemCb.size() - 1));
+}
+
+bool WMenuPopupController::createMenu(Evas_Object* win, Evas_Object* resizableObj)
+{
+    __pv->__init(win, resizableObj);
+    return WViewController::create(nullptr, nullptr);
+}
+
+bool WMenuPopupController::showMenu()
+{
+    if (getEvasObj() == nullptr) {
+        WERROR("Pop-up is Not created!");
+        return false;
+    }
+
+    __pv->__popupMove();
+    evas_object_show(getEvasObj());
+    return true;
+}
+
+Evas_Object* WMenuPopupController::onCreateView(Evas_Object* parent, void* param)
+{
+    return __pv->__create();
+}
+
+void WMenuPopupController::onDestroy()
+{
+    WENTER();
+}
+
diff --git a/src/app-assist-efl/WMenuPopupControllerImpl.cpp b/src/app-assist-efl/WMenuPopupControllerImpl.cpp
new file mode 100644 (file)
index 0000000..296f28c
--- /dev/null
@@ -0,0 +1,128 @@
+/*
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0
+ *
+ * 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 "WMenuPopupControllerImpl.h"
+#include <vector>
+#include <efl_extension.h>
+#include "WMenuPopupController.h"
+#include "WDebugInternal.h"
+
+using namespace app_assist;
+
+Evas_Object* _WMenuPopupControllerImpl::__lastMenuPopup = nullptr;
+
+_WMenuPopupControllerImpl::_WMenuPopupControllerImpl():
+    __win(nullptr),
+    __resizableBaseObj(nullptr),
+    __popup(nullptr)
+{
+}
+
+_WMenuPopupControllerImpl::~_WMenuPopupControllerImpl()
+{
+    if (__popup == __lastMenuPopup)
+        __lastMenuPopup = nullptr;
+}
+
+void _WMenuPopupControllerImpl::destroyLastMenuPopup()
+{
+    if (__lastMenuPopup)
+        evas_object_del(__lastMenuPopup);
+    __lastMenuPopup = nullptr;
+}
+
+void _WMenuPopupControllerImpl::__init(Evas_Object* win, Evas_Object* resizableObj)
+{
+    __win = win;
+    __resizableBaseObj = resizableObj;
+}
+
+void _WMenuPopupControllerImpl:: __popupMove()
+{
+    WENTER();
+    int w1, h1;
+    int rotate;
+    //
+    elm_win_screen_size_get(__win, nullptr, nullptr, &w1, &h1);
+    rotate = elm_win_rotation_get(__win);
+
+    if (rotate == 90)
+        evas_object_move(__popup, h1 / 2, w1);
+    else if (rotate == 270)
+        evas_object_move(__popup, h1 / 2, w1);
+    else
+        evas_object_move(__popup, w1 / 2, h1);
+
+    evas_object_show(__popup);
+}
+
+Evas_Object* _WMenuPopupControllerImpl::__create()
+{
+    if (__win == nullptr) {
+        WERROR("Call createMenu first!");
+        return nullptr;
+    }
+    Evas_Object* popup = nullptr;
+    popup = elm_ctxpopup_add(__win);
+    elm_object_style_set(popup, "more/default");
+    elm_ctxpopup_auto_hide_disabled_set(popup, EINA_TRUE);
+
+    eext_object_event_callback_add(popup, EEXT_CALLBACK_BACK, eext_ctxpopup_back_cb, nullptr);
+    eext_object_event_callback_add(popup, EEXT_CALLBACK_MORE, eext_ctxpopup_back_cb, nullptr);
+    evas_object_event_callback_add(__resizableBaseObj, EVAS_CALLBACK_RESIZE, _WMenuPopupControllerImpl::__popupResizeCb, this);
+    evas_object_smart_callback_add(__win, "rotation,changed",  _WMenuPopupControllerImpl::__popupWinRotateCb, this);
+    elm_ctxpopup_direction_priority_set(popup, ELM_CTXPOPUP_DIRECTION_DOWN, ELM_CTXPOPUP_DIRECTION_UP, ELM_CTXPOPUP_DIRECTION_UNKNOWN, ELM_CTXPOPUP_DIRECTION_UNKNOWN);
+    evas_object_smart_callback_add(popup, "dismissed", _WMenuPopupControllerImpl::__popupDismissedCb, this);
+    evas_object_smart_callback_add(popup, "language,changed", _WMenuPopupControllerImpl::__popupDismissedCb, this);
+
+    __popup = popup;
+    __lastMenuPopup = popup;
+
+    return popup;
+}
+
+void _WMenuPopupControllerImpl::__popupSelectCb(void* data, Evas_Object* obj, void* event_info)
+{
+    WENTER();
+    auto p = (WMenuPopupController*)wviewcontroller_get_instance_from_evasobj(obj);
+    const unsigned int itemIndex = (unsigned int)data;
+    p->__pv->__vSelectItemCb[itemIndex]();
+    evas_object_del(obj);
+}
+
+void _WMenuPopupControllerImpl::__popupResizeCb(void* data, Evas* e, Evas_Object* obj, void* event_info)
+{
+    WENTER();
+    auto pImpl = (_WMenuPopupControllerImpl*)data;
+    pImpl->__popupMove();
+}
+
+void _WMenuPopupControllerImpl::__popupWinRotateCb(void* data, Evas_Object* obj, void* event_info)
+{
+    WENTER();
+    auto pImpl = (_WMenuPopupControllerImpl*)data;
+    pImpl->__popupMove();
+}
+
+void _WMenuPopupControllerImpl::__popupDismissedCb(void* data, Evas_Object* obj, void* event_info)
+{
+    WENTER();
+    auto pImpl = (_WMenuPopupControllerImpl*)data;
+    evas_object_del(pImpl->__popup);
+}
+
diff --git a/src/app-assist-efl/WNaviframeController.cpp b/src/app-assist-efl/WNaviframeController.cpp
new file mode 100644 (file)
index 0000000..04c87bb
--- /dev/null
@@ -0,0 +1,245 @@
+/*
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0
+ *
+ * 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 "WNaviframeController.h"
+#include <memory.h>
+#include <efl_extension.h>
+#include "WDebugInternal.h"
+#include "IWWindowController.h"
+#include "WDefineInternal.h"
+#include "WContentViewController.h"
+#include "WContentViewControllerImpl.h"
+//#include "uxt_theme_object.h"
+
+using namespace app_assist;
+
+#define _CLASS_NAME    "WNaviframeController"
+
+namespace app_assist
+{
+
+class _WNaviframeControllerImpl
+{
+public:
+    _WNaviframeControllerImpl() {};
+    ~_WNaviframeControllerImpl() {};
+public:
+
+    std::function<void(bool*)> __lastItemPopDelegate;
+
+    static Eina_Bool __popCb(void* data, Elm_Object_Item* item);
+};
+}
+
+Eina_Bool _WNaviframeControllerImpl::__popCb(void* data, Elm_Object_Item* item)
+{
+    auto vc = (WContentViewController*)data;
+    //
+//     WASSERT( vc->getNaviItem() == item );
+    //
+    Evas_Object* naviObj = elm_object_item_widget_get(item);
+    auto nf = (WNaviframeController*)evas_object_data_get(naviObj, WKEY_FRAME_INSTANCE);
+    //
+    if (nf->onItemPop(vc, item))
+        return EINA_TRUE;
+    else
+        return EINA_FALSE;
+}
+
+WNaviframeController::WNaviframeController() : __pv(new _WNaviframeControllerImpl())
+{
+    WHIT();
+}
+
+WNaviframeController::~WNaviframeController()
+{
+    WHIT();
+    delete __pv;
+}
+
+const char* WNaviframeController::getClassName() const
+{
+    return _CLASS_NAME;
+}
+
+bool WNaviframeController::create(Evas_Object* parent, void* param)
+{
+    if (WViewController::create(parent, param)) {
+        evas_object_data_set(getEvasObj(), WKEY_FRAME_INSTANCE, this);
+        return true;
+    }
+    return false;
+}
+
+void WNaviframeController::destroy()
+{
+    WHIT();
+    if (getEvasObj()) {
+        destroyAllViewControllers();
+        evas_object_del(getEvasObj());
+        // Do not leave any code here.
+        // After executing upper statement "evas_object_del", this object will be deleted at evas object deletion callback!
+    } else {
+        onDestroy();
+        delete this;
+    }
+}
+
+bool WNaviframeController::push(WContentViewController* vc, const char* viewName, void* viewCreationParam)
+{
+    if (viewName)
+        vc->setName(viewName);
+    return onPush(vc, viewCreationParam);
+    //
+}
+
+bool WNaviframeController::push(WContentViewController* vc, const char* viewName)
+{
+    return push(vc, viewName, nullptr);
+}
+
+bool WNaviframeController::push(WContentViewController* vc)
+{
+    return push(vc, nullptr, nullptr);
+}
+
+
+void WNaviframeController::destroyAllViewControllers()
+{
+    WHIT();
+
+    Eina_List* list = elm_naviframe_items_get(getEvasObj());
+    Eina_List* temp = nullptr;
+    void* it = nullptr;
+    EINA_LIST_FOREACH(list, temp, it) {
+        elm_object_item_del((Elm_Object_Item*)it);
+    }
+}
+
+bool WNaviframeController::isTopContentViewController(WContentViewController* vc)
+{
+    if (getEvasObj() == nullptr) return false;
+
+    Elm_Object_Item* item = elm_naviframe_top_item_get(getEvasObj());
+    if (item && vc->getNaviItem() == item)
+        return true;
+    else
+        return false;
+}
+
+WContentViewController* WNaviframeController::getTopContentViewController()
+{
+    if (getEvasObj() == nullptr) return nullptr;
+
+    Elm_Object_Item* item = elm_naviframe_top_item_get(getEvasObj());
+    return (WContentViewController*)elm_object_item_data_get(item);
+}
+
+void WNaviframeController::setOnLastItemPop(const std::function<void(bool*)>& delegateFunc)
+{
+    __pv->__lastItemPopDelegate = delegateFunc;
+}
+
+
+
+Evas_Object* WNaviframeController::onCreateView(Evas_Object* parent, void* param)
+{
+    Evas_Object* obj = elm_naviframe_add(parent);
+//     uxt_theme_object_replace_color(obj, "B012L4", "ATO001");
+    eext_object_event_callback_add(obj, EEXT_CALLBACK_BACK, eext_naviframe_back_cb, nullptr);
+    eext_object_event_callback_add(obj, EEXT_CALLBACK_MORE, eext_naviframe_more_cb, nullptr);
+
+    evas_object_show(obj);
+
+    return obj;
+}
+
+void WNaviframeController::onDestroy()
+{
+}
+
+void WNaviframeController::onLastItemPop(bool* popOut)
+{
+    WHIT();
+    *popOut = false;
+    elm_win_lower(getWindowController()->getEvasObj());
+}
+
+bool WNaviframeController::onPush(WContentViewController* vc, void* viewParam)
+{
+    WASSERT(getEvasObj() != nullptr);
+    //
+    if (vc->create(getEvasObj(), viewParam) == false) {
+        WERROR("Failed to create a vc!");
+        return false;
+    }
+
+    wcontentviewcontroller_set_container_properties(vc, this);
+    //
+    Elm_Object_Item* item = vc->onPushToNaviframe(getEvasObj());
+    if (item == nullptr)
+        item = elm_naviframe_item_push(getEvasObj(), vc->getTitle(), nullptr, nullptr, vc->getEvasObj(), nullptr);
+    //
+    elm_object_item_data_set(item, vc);
+    wcontentviewcontroller_set_container_naviitem_property(vc, item, true);
+    wcontentviewcontroller_propagate_container_properties_to_childviews(vc);
+
+    //
+    if (vc->__pv->callPushedHandlerFunc(item) == false)
+        vc->onPushed(item);
+
+    elm_naviframe_item_pop_cb_set(item, _WNaviframeControllerImpl::__popCb, vc);
+
+    return true;
+}
+
+bool WNaviframeController::onItemPop(WContentViewController* vc, Elm_Object_Item* item)
+{
+    WNaviframeController* nf = vc->getNaviframeController();
+
+    if (item == elm_naviframe_bottom_item_get(nf->getEvasObj())) {
+        if (!vc->onPop())
+            return false;
+
+        bool popOut = true;
+
+        if (nf->__pv->__lastItemPopDelegate)
+            nf->__pv->__lastItemPopDelegate(&popOut);
+        else
+            nf->onLastItemPop(&popOut);
+        return popOut;
+    } else {
+        if (vc->onPop()) {
+            Eina_List* itemList = elm_naviframe_items_get(getEvasObj());
+
+            int nth = eina_list_count(itemList) - 2;
+            if (nth >= 0) {
+                Elm_Object_Item* tempItem = (Elm_Object_Item*)eina_list_nth(itemList, nth);
+                WContentViewController* targetView = (WContentViewController*)elm_object_item_data_get(tempItem);
+                WASSERT(targetView);
+                targetView->onBecomeTop();
+            }
+            eina_list_free(itemList);
+
+            return true;
+        } else {
+            return false;
+        }
+    }
+}
+
diff --git a/src/app-assist-efl/WPageSlideViewController.cpp b/src/app-assist-efl/WPageSlideViewController.cpp
new file mode 100644 (file)
index 0000000..aa51ed8
--- /dev/null
@@ -0,0 +1,528 @@
+/*
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0
+ *
+ * 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 "WPageSlideViewController.h"
+#include <list>
+#include <string>
+#include <app.h>
+#include "WDebugInternal.h"
+#include "WDefineInternal.h"
+#include "WContentViewController.h"
+#include "WUiTimer.h"
+
+using namespace app_assist;
+
+#define _CLASS_NAME    "WPageSlideViewController"
+
+namespace app_assist
+{
+
+class _WPageSlideViewControllerImpl
+{
+public:
+    _WPageSlideViewControllerImpl(WPageSlideViewController* host);
+    _WPageSlideViewControllerImpl() = delete;
+    ~_WPageSlideViewControllerImpl();
+public:
+    WPageSlideViewController* __b;
+    //
+    struct PageContent {
+        WViewController* uiObj;
+        Evas_Object* evasObj;
+        bool isContentView;
+    };
+
+    Evas_Object* __scroller;
+    Evas_Object* __box;
+    int __currentPage;
+    int __previousPage;
+    int __pageWidth;
+    int __pageHeight;
+    std::list<PageContent>* __listPageContent;
+    bool __showScroll;
+    //
+    std::function<void(Evas_Object*)> __initScrollerHandler;
+    std::function<void(int dir)> __scrollAnimStopCb;
+
+    bool __appendPage(WViewController* uiObj, bool isContentView);
+    bool __appendPage();
+    bool __setPageContent(int index, WViewController* uiObj, bool isContentView);
+
+    static void __scrollCallback(void *data, Evas_Object *obj, void *event_info);
+    static void __scrollAnimStartCallback(void *data, Evas_Object *obj, void *event_info);
+    static void __scrollAnimStopCallback(void *data, Evas_Object *obj, void *event_info);
+    static Eina_Bool __onTimer(void* data);
+
+    static void __layoutResizeCallback(void *data, Evas *e, Evas_Object *obj, void *event_info);
+};
+}
+
+static Evas_Object* __createPageBase(Evas_Object* parent)
+{
+    Evas_Object* pageBase = elm_layout_add(parent);
+    evas_object_size_hint_weight_set(pageBase, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+
+    char* path = app_get_resource_path();
+    if (path == nullptr) {
+        WERROR("Failed to get resource path=nullptr!!!");
+        return pageBase;
+    }
+    std::string edjPath(path);
+    free(path);
+    edjPath += "edje/app-assist-efl.edj";
+
+    if (elm_layout_file_set(pageBase, edjPath.c_str(), "page") == EINA_FALSE) {
+        WERROR("Fail to set layout. Check EDJ file(%s)", edjPath.c_str());
+        return pageBase;
+    }
+
+    Evas_Object* rect = evas_object_rectangle_add(evas_object_evas_get(pageBase));
+    evas_object_size_hint_weight_set(rect, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+    evas_object_color_set(rect, 0, 0, 0, 0);  // make it transparent to show bg
+    evas_object_show(rect);
+
+    elm_object_part_content_set(pageBase, "sizer", rect);
+
+    evas_object_show(pageBase);
+    return pageBase;
+}
+
+_WPageSlideViewControllerImpl::_WPageSlideViewControllerImpl(WPageSlideViewController* host):
+    __b(nullptr),
+    __scroller(nullptr),
+    __box(nullptr),
+    __currentPage(0),
+    __previousPage(0),
+    __pageWidth(0),
+    __pageHeight(0),
+    __listPageContent(nullptr),
+    __showScroll(true)
+{
+    __b = host;
+    __listPageContent = new std::list<PageContent>;
+}
+
+_WPageSlideViewControllerImpl::~_WPageSlideViewControllerImpl()
+{
+    delete __listPageContent;
+}
+
+bool _WPageSlideViewControllerImpl::__appendPage(WViewController* uiObj, bool isContentView)
+{
+    if (__scroller == nullptr) {
+        WASSERT("First, create page slide view!");
+        return false;
+    }
+
+    Evas_Object* pageBase = __createPageBase(__box);
+
+    uiObj->create(pageBase, nullptr);
+
+    elm_object_part_content_set(pageBase, "sw", uiObj->getEvasObj());
+
+    elm_box_pack_end(__box, pageBase);
+
+    __listPageContent->push_back(PageContent {uiObj, pageBase, isContentView});
+
+    return true;
+}
+
+bool _WPageSlideViewControllerImpl::__appendPage()
+{
+    if (__scroller == nullptr) {
+        WASSERT("First, create page slide view!");
+        return false;
+    }
+
+    Evas_Object* pageBase = __createPageBase(__box);
+
+    elm_box_pack_end(__box, pageBase);
+
+    __listPageContent->push_back(PageContent {nullptr, pageBase, false});
+
+    return true;
+}
+
+bool _WPageSlideViewControllerImpl::__setPageContent(int index, WViewController* uiObj, bool isContentView)
+{
+    int count = 0;
+    Evas_Object* pageBase = nullptr;
+    for (PageContent& it : *__listPageContent) {
+        if (index == count) {
+            if (it.uiObj) {
+                WERROR("Index is already occupied(index=%d)", index);
+                return false;
+            }
+            it.uiObj = uiObj;
+            it.isContentView = isContentView;
+            pageBase = it.evasObj;
+            break;
+        }
+        count++;
+    }
+
+    if (count != index) {
+        WERROR("Index is not in range(index=%d,count=%d)", index, count);
+        return false;
+    }
+
+    Evas_Object *content = elm_object_part_content_get(pageBase, "sw");
+    if (content == nullptr) {
+        uiObj->create(pageBase, nullptr);
+        elm_object_part_content_set(pageBase, "sw", uiObj->getEvasObj());
+        return true;
+    }
+
+    return false;
+}
+
+
+void _WPageSlideViewControllerImpl::__scrollCallback(void *data, Evas_Object *obj, void *event_info)
+{
+    _WPageSlideViewControllerImpl* pageViewImpl = ((WPageSlideViewController *)data)->__pv;
+    int x;
+
+    evas_object_geometry_get(pageViewImpl->__box, &x, nullptr, nullptr, nullptr);
+
+    if (x % pageViewImpl->__pageWidth == 0) {
+        int page;
+        elm_scroller_current_page_get(obj, &page, nullptr);
+        pageViewImpl->__currentPage = page;
+    }
+}
+
+void _WPageSlideViewControllerImpl::__scrollAnimStartCallback(void *data, Evas_Object *obj, void *event_info)
+{
+    _WPageSlideViewControllerImpl* pageViewImpl = ((WPageSlideViewController *)data)->__pv;
+    pageViewImpl->__previousPage = pageViewImpl->__currentPage;
+}
+
+void _WPageSlideViewControllerImpl::__scrollAnimStopCallback(void *data, Evas_Object *obj, void *event_info)
+{
+    _WPageSlideViewControllerImpl* pageViewImpl = ((WPageSlideViewController *)data)->__pv;
+    if (pageViewImpl->__scrollAnimStopCb)
+        pageViewImpl->__scrollAnimStopCb(pageViewImpl->__currentPage - pageViewImpl->__previousPage);
+}
+
+Eina_Bool _WPageSlideViewControllerImpl::__onTimer(void* data)
+{
+    _WPageSlideViewControllerImpl* pageViewImpl = ((WPageSlideViewController *)data)->__pv;
+    __layoutResizeCallback(data, nullptr, pageViewImpl->__scroller, nullptr);
+    return ECORE_CALLBACK_CANCEL;
+}
+
+
+void _WPageSlideViewControllerImpl::__layoutResizeCallback(void *data, Evas *e, Evas_Object *obj, void *event_info)
+{
+    WHIT();
+
+    WPageSlideViewController* pageView = (WPageSlideViewController *)data;
+    _WPageSlideViewControllerImpl* pv = pageView->__pv;
+    int w, h;
+
+    evas_object_geometry_get(obj, nullptr, nullptr, &w, &h);
+
+    pv->__pageWidth = w;
+    pv->__pageHeight = h;
+
+    for (PageContent& it : *pv->__listPageContent) {
+        Evas_Object* pageBase = it.evasObj;
+        evas_object_size_hint_min_set(elm_object_part_content_get(pageBase, "sizer"), w, h);
+    }
+
+    elm_scroller_page_size_set(pv->__scroller, w, h);
+    elm_scroller_page_show(pv->__scroller, pv->__currentPage, 0);
+
+// sometimes layout resize callback is called when UG is destroyed. so do not use timer! or care the timer handle.
+//     ecore_timer_add(0.0, [](void* data) {
+//             WPageSlideViewController* self = (WPageSlideViewController*)data;
+//             elm_scroller_page_show(self->__pv->__scroller, self->__pv->__currentPage, 0);
+//             return ECORE_CALLBACK_CANCEL;
+//     }, pageView);
+}
+
+
+WPageSlideViewController::WPageSlideViewController()
+{
+    __pv = new _WPageSlideViewControllerImpl(this);
+}
+
+WPageSlideViewController::~WPageSlideViewController()
+{
+    delete __pv;
+}
+
+void WPageSlideViewController::setOnScrollAnimStop(const std::function<void(int dir)>& handlerFunc)
+{
+    __pv->__scrollAnimStopCb = handlerFunc;
+}
+
+const char* WPageSlideViewController::getClassName() const
+{
+    return _CLASS_NAME;
+}
+
+bool WPageSlideViewController::appendPage(WViewController* content)
+{
+    if (__pv->__appendPage(content, false) == false) {
+        WERROR("Fail to attach the page!");
+        return false;
+    }
+
+    return true;
+}
+
+bool WPageSlideViewController::appendPage(WContentViewController* content)
+{
+    if (__pv->__appendPage(content, true) == false) {
+        WERROR("Fail to attach the page!");
+        return false;
+    }
+
+    wcontentviewcontroller_set_container_properties(content, getNaviframeController());
+    wcontentviewcontroller_set_container_naviitem_property(content, getNaviItem(), false);
+    wcontentviewcontroller_propagate_container_properties_to_childviews(content);
+
+    content->onSetAsPageContent(getNaviItem());
+
+    return true;
+}
+
+bool WPageSlideViewController::appendPage()
+{
+    if (__pv->__appendPage() == false) {
+        WERROR("Fail to attach the page!");
+        return false;
+    }
+
+    return true;
+}
+
+bool WPageSlideViewController::removePage(int index)
+{
+    int pageNum = getPageCount();
+    if (index < 0 || index >= pageNum) {
+        WERROR("Out of page number(%d), index=%d", pageNum, index);
+        return false;
+    }
+
+    int cur = 0;
+    for (auto it = __pv->__listPageContent->begin(); it != __pv->__listPageContent->end(); it++) {
+        if (cur == index) {
+            elm_box_unpack(__pv->__box, it->evasObj);
+            evas_object_del(it->evasObj);
+            __pv->__listPageContent->erase(it);
+            return true;
+        }
+        cur++;
+    }
+    return false;
+}
+
+void WPageSlideViewController::resizePageSlideLayout()
+{
+    _WPageSlideViewControllerImpl::__layoutResizeCallback(this, nullptr, __pv->__scroller, nullptr);
+}
+
+bool WPageSlideViewController::setPageContent(int index, WContentViewController* content)
+{
+    if (__pv->__setPageContent(index, content, true) == false) {
+        WERROR("Fail to set page content %d!", index);
+        return false;
+    }
+
+    wcontentviewcontroller_set_container_properties(content, getNaviframeController());
+    wcontentviewcontroller_set_container_naviitem_property(content, getNaviItem(), false);
+    wcontentviewcontroller_propagate_container_properties_to_childviews(content);
+
+    content->onSetAsPageContent(getNaviItem());
+
+    return true;
+}
+
+bool WPageSlideViewController::setPageContent(int index, WViewController* content)
+{
+    if (__pv->__setPageContent(index, content, false) == false) {
+        WERROR("Fail to set page content %d!", index);
+        return false;
+    }
+    return true;
+}
+
+
+int WPageSlideViewController::getPageCount()
+{
+    return __pv->__listPageContent->size();
+}
+
+WViewController* WPageSlideViewController::getPageContent(int index)
+{
+    int count = 0;
+    for (_WPageSlideViewControllerImpl::PageContent& it : *__pv->__listPageContent) {
+        if (count == index)
+            return it.uiObj;
+        count++;
+    }
+
+    return nullptr;
+}
+
+int WPageSlideViewController::getCurrentPageIndex()
+{
+    return __pv->__currentPage;
+}
+
+Evas_Object* WPageSlideViewController::getScroller()
+{
+    return __pv->__scroller;
+}
+
+void WPageSlideViewController::setScrollerShowState(bool show)
+{
+    __pv->__showScroll = show;
+}
+
+void WPageSlideViewController::showPage(int index, bool withAnimation)
+{
+    int pageNum = getPageCount();
+    if (index < 0 || index >= pageNum) {
+        WERROR("Out of page number(%d), index=%d", pageNum, index);
+        return;
+    }
+    __pv->__currentPage = index;
+    if (withAnimation)
+        elm_scroller_page_bring_in(__pv->__scroller, __pv->__currentPage, 0);
+    else
+        elm_scroller_page_show(__pv->__scroller, __pv->__currentPage, 0);
+}
+
+void WPageSlideViewController::showPage(int index)
+{
+    return showPage(index, false);
+}
+
+WViewController* WPageSlideViewController::unsetPageContent(int index)
+{
+    int pageNum = getPageCount();
+    if (index < 0 || index >= pageNum) {
+        WERROR("Out of page number(%d), index=%d", pageNum, index);
+        return nullptr;
+    }
+
+    auto it = __pv->__listPageContent->begin();
+    for (int i = 0; i < index; i++)
+        it++;
+
+    Evas_Object* obj = elm_object_part_content_unset((*it).evasObj, "sw");
+    (*it).uiObj = nullptr;
+    if (obj == nullptr) {
+        WERROR("elm_object_part_content_unset obj is nullptr");
+        return nullptr;
+    } else {
+        WViewController* uiObj = nullptr;
+        if ((uiObj = (WViewController*)evas_object_data_get(obj, WKEY_VIEW_INSTANCE)) != nullptr) {
+            return uiObj;
+        }
+        return nullptr;
+    }
+}
+
+void WPageSlideViewController::setOnInitScroller(const std::function<void(Evas_Object*)>& delegateFunc)
+{
+    __pv->__initScrollerHandler = delegateFunc;
+}
+
+Evas_Object* WPageSlideViewController::onCreateView(Evas_Object* parent, void* viewParam)
+{
+    WHIT();
+
+    Evas_Object* layout = onCreateLayout(parent);
+    Evas_Object* scroller = nullptr;
+    if (layout) {
+        scroller = elm_scroller_add(layout);
+        evas_object_event_callback_add(layout, EVAS_CALLBACK_RESIZE, _WPageSlideViewControllerImpl::__layoutResizeCallback, this);
+    } else {
+        scroller = elm_scroller_add(parent);
+        evas_object_event_callback_add(scroller, EVAS_CALLBACK_RESIZE, _WPageSlideViewControllerImpl::__layoutResizeCallback, this);
+    }
+
+    evas_object_smart_callback_add(scroller, "scroll", _WPageSlideViewControllerImpl::__scrollCallback, this);
+    evas_object_smart_callback_add(scroller, "scroll,anim,start", _WPageSlideViewControllerImpl::__scrollAnimStartCallback, this);
+    evas_object_smart_callback_add(scroller, "scroll,anim,stop", _WPageSlideViewControllerImpl::__scrollAnimStopCallback, this);
+
+    elm_scroller_loop_set(scroller, EINA_FALSE, EINA_FALSE);
+    evas_object_size_hint_weight_set(scroller, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+    evas_object_size_hint_align_set(scroller, EVAS_HINT_FILL, EVAS_HINT_FILL);
+    elm_scroller_page_relative_set(scroller, 1.0, 0.0);
+    elm_scroller_policy_set(scroller,
+                            __pv->__showScroll ? ELM_SCROLLER_POLICY_AUTO : ELM_SCROLLER_POLICY_OFF,
+                            ELM_SCROLLER_POLICY_OFF);
+    elm_scroller_page_scroll_limit_set(scroller, 1, 0);
+    elm_object_scroll_lock_y_set(scroller, EINA_TRUE);
+    elm_scroller_single_direction_set(scroller, ELM_SCROLLER_SINGLE_DIRECTION_HARD);
+    //
+    if (__pv->__initScrollerHandler)
+        __pv->__initScrollerHandler(scroller);
+    else
+        onInitScroller(scroller);
+    //
+    if (layout) {
+        elm_object_part_content_set(layout, "scroller", scroller);
+    }
+
+    Evas_Object* box = elm_box_add(scroller);
+
+    __pv->__scroller = scroller;
+    __pv->__box = box;
+
+    elm_box_horizontal_set(box, EINA_TRUE);
+    elm_object_content_set(scroller, box);
+    evas_object_show(scroller);
+    evas_object_show(box);
+
+
+    if (layout) {
+        WUiTimer::addTimer(0.0, _WPageSlideViewControllerImpl::__onTimer, this, layout);
+        return layout;
+    } else {
+        WUiTimer::addTimer(0.0, _WPageSlideViewControllerImpl::__onTimer, this, scroller);
+        return scroller;
+    }
+}
+
+void WPageSlideViewController::onSetContainerProperties(WNaviframeController* naviframe, Elm_Object_Item* item)
+{
+    for (_WPageSlideViewControllerImpl::PageContent& it : *__pv->__listPageContent) {
+        if (it.uiObj && it.isContentView) {
+            auto view = (WContentViewController*)wviewcontroller_get_instance_from_evasobj(it.uiObj->getEvasObj());
+            wcontentviewcontroller_set_container_properties(view , naviframe);
+            wcontentviewcontroller_set_container_naviitem_property(view, item, false);
+            wcontentviewcontroller_propagate_container_properties_to_childviews(view);
+        }
+    }
+}
+
+void WPageSlideViewController::onInitScroller(Evas_Object* scroller)
+{
+}
+
+Evas_Object* WPageSlideViewController::onCreateLayout(Evas_Object* parent)
+{
+    WHIT();
+    return nullptr;
+}
diff --git a/src/app-assist-efl/WPopupController.cpp b/src/app-assist-efl/WPopupController.cpp
new file mode 100644 (file)
index 0000000..610dca7
--- /dev/null
@@ -0,0 +1,278 @@
+/*
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0
+ *
+ * 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 "WPopupController.h"
+#include <string>
+#include <Evas.h>
+#include <efl_extension.h>
+#include "WDebugInternal.h"
+
+
+using namespace app_assist;
+
+#define _MAX_BUTTON_NUM        3
+
+namespace app_assist
+{
+
+class _WPopupControllerImpl
+{
+public:
+    _WPopupControllerImpl();
+    ~_WPopupControllerImpl();
+public:
+    //
+    std::string __title;
+    std::string __text;
+    std::string __textDomain;
+    WViewController* __content;
+    std::string __listButtonLabel[_MAX_BUTTON_NUM];
+    int __count;
+    bool __isTranslatable;
+
+    std::function<Evas_Object* (Evas_Object* parent)> __contentCreator;
+    std::function<void(Evas_Object* popup)> __addPropertiesCb;
+    std::function<void(bool* destroyPopup)> __backCb;
+
+    std::function<void(bool* destroyPopup)> __vButtonCb[_MAX_BUTTON_NUM];
+    std::function<void(Evas_Object* button)>* buttonPropertyCb[_MAX_BUTTON_NUM];
+
+    void __setTextPart(Evas_Object* obj, const char* part, const char* text);
+};
+}
+
+_WPopupControllerImpl::_WPopupControllerImpl():
+    __content(nullptr),
+    __count(0),
+    __isTranslatable(false)
+{
+    for (int i = 0; i < _MAX_BUTTON_NUM; i++) {
+        buttonPropertyCb[i] = nullptr;
+    }
+}
+
+_WPopupControllerImpl::~_WPopupControllerImpl()
+{
+    for (int i = 0; i < _MAX_BUTTON_NUM; i++) {
+        delete buttonPropertyCb[i];
+    }
+}
+
+void _WPopupControllerImpl::__setTextPart(Evas_Object* obj, const char* part, const char* text)
+{
+    if (!__textDomain.empty()) {
+        elm_object_domain_translatable_part_text_set(obj, part, __textDomain.c_str(), text);
+    } else {
+        if (__isTranslatable)
+            elm_object_translatable_part_text_set(obj, part, text);
+        else
+            elm_object_part_text_set(obj, part, text);
+    }
+}
+
+
+WPopupController::WPopupController() : __pv(new _WPopupControllerImpl())
+{
+    WHIT();
+}
+WPopupController::WPopupController(const char* title, const char* textContent) : __pv(new _WPopupControllerImpl())
+{
+    if (title)
+        __pv->__title = title;
+    if (textContent)
+        __pv->__text = textContent;
+}
+
+WPopupController::~WPopupController()
+{
+    WHIT();
+    delete __pv;
+}
+
+void WPopupController::setTitle(const char* title)
+{
+    if (title)
+        __pv->__title = title;
+    else
+        __pv->__title.clear();
+}
+
+void WPopupController::setContent(const char* text)
+{
+    if (text)
+        __pv->__text = text;
+    else
+        __pv->__text.clear();
+    if (__pv->__content) {
+        __pv->__content->destroy();
+        __pv->__content = nullptr;
+    }
+}
+
+void WPopupController::setContent(WViewController* control)
+{
+    __pv->__text = "";
+    __pv->__content = control;
+}
+
+void WPopupController::setContent(const std::function<Evas_Object* (Evas_Object* parent)>& contentCreateCb)
+{
+    __pv->__text = "";
+    if (__pv->__content) {
+        __pv->__content->destroy();
+        __pv->__content = nullptr;
+    }
+    __pv->__contentCreator = contentCreateCb;
+}
+
+void WPopupController::setTextTranslatable()
+{
+    __pv->__isTranslatable = true;
+}
+
+void WPopupController::setTextTranslatable(const char* textDomain)
+{
+    if (textDomain)
+        __pv->__textDomain = textDomain;
+    else
+        __pv->__textDomain.clear();
+}
+
+// Popup can be destroyed in button callback, so check its validity by calling expired of weak pointer.
+#define BUTTON_CALLBACK(_buttonIndex) \
+[](void* data, Evas_Object* obj, void* eventInfo) {\
+       WPopupController* self = (WPopupController*)data;\
+       if (self->__pv->__vButtonCb[_buttonIndex]) { \
+               bool destroyPopup = true; \
+               auto selfWeakPtr = self->getWeakPtr(); \
+               self->__pv->__vButtonCb[_buttonIndex](&destroyPopup); \
+               if (!selfWeakPtr.expired() && destroyPopup) \
+                       evas_object_del(self->getEvasObj());\
+       }\
+       else \
+               evas_object_del(self->getEvasObj());\
+}
+
+bool WPopupController::addButton(const char* buttonText, const std::function<void(bool* destroyPopup)>& buttonCb, const std::function<void(Evas_Object* button)>& setPropertyCb)
+{
+    if (__pv->__count >= _MAX_BUTTON_NUM) {
+        WERROR("Over the max button number! =%d", __pv->__count);
+        return false;
+    }
+    __pv->__listButtonLabel[__pv->__count] = buttonText;
+    __pv->__vButtonCb[__pv->__count] = buttonCb;
+    if (setPropertyCb)
+        __pv->buttonPropertyCb[__pv->__count] = new std::function<void (Evas_Object* button)>(setPropertyCb);
+
+    __pv->__count++;
+    return true;
+}
+
+bool WPopupController::addButton(const char* buttonText, const std::function<void(bool* destroyPopup)>& buttonCb)
+{
+    return addButton(buttonText, buttonCb, nullptr);
+}
+
+void WPopupController::setOnBack(const std::function<void(bool* destroyPopup)>& backCb)
+{
+    __pv->__backCb = backCb;
+}
+
+void WPopupController::setOnAddProperties(const std::function<void(Evas_Object* popup)>& addPropertiesCb)
+{
+    __pv->__addPropertiesCb = addPropertiesCb;
+}
+
+Evas_Object* WPopupController::onCreateView(Evas_Object* parent, void* param)
+{
+    WHIT();
+
+    Evas_Object* popup = elm_popup_add(parent);
+
+    // It make the width to fit to screen width in portrait mode. 2014.09.30 modified as EFL notice.
+    elm_popup_align_set(popup, ELM_NOTIFY_ALIGN_FILL, 1.0);
+
+    if (__pv->__backCb)
+        eext_object_event_callback_add(popup, EEXT_CALLBACK_BACK, [](void *data, Evas_Object * obj, void *event_info) {
+        WPopupController* self = (WPopupController*)data;
+        bool destroyPopup = true;
+        auto selfWeakPtr = self->getWeakPtr();
+        self->__pv->__backCb(&destroyPopup);
+        if (!selfWeakPtr.expired() && destroyPopup) {
+            self->destroy();
+        }
+    }, this);
+    else
+        eext_object_event_callback_add(popup, EEXT_CALLBACK_BACK, eext_popup_back_cb, nullptr);
+
+    if (__pv->__addPropertiesCb)
+        __pv->__addPropertiesCb(popup);
+
+    if (!__pv->__title.empty()) {
+        __pv->__setTextPart(popup, "title,text", __pv->__title.c_str());
+    }
+
+    if (!__pv->__text.empty()) {
+        __pv->__setTextPart(popup, nullptr, __pv->__text.c_str());
+    } else if (__pv->__content) {
+        __pv->__content->create(popup, nullptr);
+        elm_object_content_set(popup, __pv->__content->getEvasObj());
+    } else if (__pv->__contentCreator) {
+        Evas_Object* obj = __pv->__contentCreator(popup);
+        elm_object_content_set(popup, obj);
+    }
+
+    for (int i = 0; i < __pv->__count; i++) {
+        Evas_Object* button = elm_button_add(popup);
+        elm_object_style_set(button, "popup/circle");
+        if (__pv->buttonPropertyCb[i]) {
+            (*__pv->buttonPropertyCb[i])(button);
+        }
+
+        __pv->__setTextPart(button, nullptr, __pv->__listButtonLabel[i].c_str());
+
+        char partname[100] = {0};
+        snprintf(partname, sizeof(partname) - 1, "button%d", i + 1);
+        elm_object_part_content_set(popup, partname, button);
+        //
+        switch (i) {
+        case 0:
+            evas_object_smart_callback_add(button, "clicked", BUTTON_CALLBACK(0), this);
+            break;
+        case 1:
+            evas_object_smart_callback_add(button, "clicked", BUTTON_CALLBACK(1), this);
+            break;
+        case 2:
+            evas_object_smart_callback_add(button, "clicked", BUTTON_CALLBACK(2), this);
+            break;
+        default:
+            break;
+        }
+
+
+        evas_object_show(button);
+    }
+
+    evas_object_show(popup);
+
+    return popup;
+}
+
+void WPopupController::onDestroy()
+{
+}
diff --git a/src/app-assist-efl/WSignalIdGenerator.cpp b/src/app-assist-efl/WSignalIdGenerator.cpp
new file mode 100644 (file)
index 0000000..f85723c
--- /dev/null
@@ -0,0 +1,27 @@
+/*
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0
+ *
+ * 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 "WSignalIdGenerator.h"
+
+using namespace app_assist;
+
+static unsigned int gid = 0;
+
+unsigned int WSignalIdGenerator::generate()
+{
+    return ++gid;
+}
diff --git a/src/app-assist-efl/WUiThread.cpp b/src/app-assist-efl/WUiThread.cpp
new file mode 100644 (file)
index 0000000..158a528
--- /dev/null
@@ -0,0 +1,330 @@
+/*
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0
+ *
+ * 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 "WUiThread.h"
+#include <Ecore.h>
+#include <Evas.h>
+#include <Eina.h>
+#include "WDebugInternal.h"
+#include "WDefineInternal.h"
+
+const char* const SIGNAL_DATA_KEY_STRING = "__@WSIGNAL_DATA";
+const static int _CANCEL_TIMEOUT = 30; //seconds
+
+using namespace app_assist;
+
+namespace app_assist
+{
+
+class _WUiThreadImpl : public WUiThread::IStatus
+{
+public:
+    _WUiThreadImpl(): __workerThread(nullptr), __stopFlag(false) {};
+    ~_WUiThreadImpl() {};
+public:
+    //
+    Ecore_Thread* __workerThread;
+    bool __stopFlag;
+    Eina_Lock __mutex;
+    Eina_Condition __notifyCbEndCondition;
+
+    std::function<void(WUiThread::IStatus* threadStatus, Ecore_Thread* thread)> __workerFunc;
+    std::function<void()> __workerEndCb;
+    std::function<void()> __workerCancelCb;
+    std::function<void(WUiThread* thread, void* msgData)> __workerNotifyCb;
+    //
+    virtual bool isCancelRequested(Ecore_Thread* thread); //override;
+    virtual int getThreadGlobalDataInt(); //override;
+    virtual int getThreadGlobalDataInt(const char* key); //override;
+    virtual bool sendFeedback(Ecore_Thread* thread, void* msgData); //override;
+
+    void __setThreadGlobalDataInt(int data);
+    void __setThreadGlobalDataInt(const char* key, int data);
+    static void __threadWorkerFunc(void* data, Ecore_Thread* thread);
+    static void __threadEndCb(void* data, Ecore_Thread* thread);
+    static void __threadCancelCb(void* data, Ecore_Thread* thread);
+    static void __threadNotifyCb(void* data, Ecore_Thread* thread, void* msgData);
+};
+}
+
+
+bool _WUiThreadImpl::isCancelRequested(Ecore_Thread* thread)
+{
+    WHIT();
+    if (ecore_thread_check(thread) == EINA_TRUE)
+        return true;
+    else
+        return false;
+}
+int _WUiThreadImpl::getThreadGlobalDataInt()
+{
+    return getThreadGlobalDataInt(SIGNAL_DATA_KEY_STRING);
+}
+
+int _WUiThreadImpl::getThreadGlobalDataInt(const char* key)
+{
+    void* data = ecore_thread_global_data_find(key);
+    if (data == nullptr) {
+        return -1;
+    } else {
+        ecore_thread_global_data_del(key);
+        return (int)data;
+    }
+}
+
+void _WUiThreadImpl::__setThreadGlobalDataInt(int data)
+{
+    __setThreadGlobalDataInt(SIGNAL_DATA_KEY_STRING, data);
+}
+
+void _WUiThreadImpl::__setThreadGlobalDataInt(const char* key, int data)
+{
+    ecore_thread_global_data_set(key, (void*)data, nullptr);
+}
+
+bool _WUiThreadImpl::sendFeedback(Ecore_Thread* thread, void* msgData)
+{
+    if (!__workerNotifyCb) {
+        WERROR("No notify callback was set!");
+        return false;
+    }
+    if (isCancelRequested(thread)) {
+        return false;
+    }
+    WHIT();
+
+    eina_lock_take(&__mutex);
+    Eina_Bool ret = ecore_thread_feedback(thread, msgData);
+    eina_condition_wait(&__notifyCbEndCondition);
+    eina_lock_release(&__mutex);
+
+    if (ret == EINA_TRUE) return true;
+    else return false;
+}
+
+void _WUiThreadImpl::__threadWorkerFunc(void* data, Ecore_Thread* thread)
+{
+    WENTER();
+    auto self = static_cast<WUiThread*>(data);
+    if (self->__pv->__workerFunc) {
+        self->__pv->__workerFunc(self->__pv, thread);
+    } else {
+        WERROR("No worker function was set!");
+    }
+    WLEAVE();
+}
+
+void _WUiThreadImpl::__threadEndCb(void* data, Ecore_Thread* thread)
+{
+    WHIT();
+    auto self = static_cast<WUiThread*>(data);
+    if (self->__pv->__stopFlag == false && self->__pv->__workerEndCb)
+        self->__pv->__workerEndCb();
+
+    if (self->__pv->__workerNotifyCb)  {
+        eina_lock_free(&self->__pv->__mutex);
+        eina_condition_free(&self->__pv->__notifyCbEndCondition);
+    }
+    self->__pv->__workerThread = nullptr;
+}
+
+void _WUiThreadImpl::__threadCancelCb(void* data, Ecore_Thread* thread)
+{
+    WHIT();
+    auto self = static_cast<WUiThread*>(data);
+
+    if (self->__pv->__stopFlag == false && self->__pv->__workerCancelCb)
+        self->__pv->__workerCancelCb();
+
+    if (self->__pv->__workerNotifyCb)  {
+        eina_lock_free(&self->__pv->__mutex);
+        eina_condition_free(&self->__pv->__notifyCbEndCondition);
+    }
+    self->__pv->__workerThread = nullptr;
+}
+
+void _WUiThreadImpl::__threadNotifyCb(void* data, Ecore_Thread* thread, void* msgData)
+{
+    WHIT();
+    auto self = static_cast<WUiThread*>(data);
+    self->__pv->__workerNotifyCb(self, msgData);
+    //
+    eina_lock_take(&self->__pv->__mutex);
+    eina_condition_signal(&self->__pv->__notifyCbEndCondition);
+    eina_lock_release(&self->__pv->__mutex);
+}
+
+WUiThread::WUiThread()
+{
+    WHIT();
+    __pv = new _WUiThreadImpl();
+}
+
+WUiThread::~WUiThread()
+{
+    WHIT();
+    cancelWithoutCallback(_CANCEL_TIMEOUT);
+    delete __pv;
+}
+
+bool WUiThread::setWorker(const std::function<void(WUiThread::IStatus* threadStatus, Ecore_Thread* thread)>& func)
+{
+    if (__pv->__workerThread) {
+        WERROR("Already created thread exists!");
+        return false;
+    }
+    __pv->__workerFunc = func;
+    return true;
+}
+
+bool WUiThread::setEndCb(const std::function<void()>& endCb)
+{
+    if (__pv->__workerThread) {
+        WERROR("Already created thread exists!");
+        return false;
+    }
+    __pv->__workerEndCb = endCb;
+    return true;
+}
+
+bool WUiThread::setCancelCb(const std::function<void()>& cancelCb)
+{
+    if (__pv->__workerThread) {
+        WERROR("Already created thread exists!");
+        return false;
+    }
+    __pv->__workerCancelCb = cancelCb;
+    return true;
+}
+
+bool WUiThread::setNotifyCb(const std::function<void(WUiThread* thread, void* msgData)>& notifyCb)
+{
+    if (__pv->__workerThread) {
+        WERROR("Already created thread exists!");
+        return false;
+    }
+    __pv->__workerNotifyCb = notifyCb;
+    return true;
+}
+
+bool WUiThread::run(void)
+{
+    WHIT();
+
+    if (__pv->__workerThread) {
+        WERROR("Already started!");
+        return false;
+    }
+    if (!__pv->__workerFunc) {
+        WERROR("Set worker function first!");
+        return false;
+    }
+
+    __pv->__stopFlag = false;
+    if (__pv->__workerNotifyCb)        {
+        eina_lock_new(&__pv->__mutex);
+        eina_condition_new(&__pv->__notifyCbEndCondition, &__pv->__mutex);
+        __pv->__workerThread = ecore_thread_feedback_run(_WUiThreadImpl::__threadWorkerFunc, _WUiThreadImpl::__threadNotifyCb, _WUiThreadImpl::__threadEndCb, _WUiThreadImpl::__threadCancelCb, this, EINA_TRUE);
+    } else {
+        __pv->__workerThread = ecore_thread_run(_WUiThreadImpl::__threadWorkerFunc,  _WUiThreadImpl::__threadEndCb, _WUiThreadImpl::__threadCancelCb, this);
+    }
+
+    if (__pv->__workerThread == nullptr) {
+        WERROR("thread create fail");
+        return false;
+    }
+    return true;
+}
+
+bool WUiThread::cancel(double waitSeconds)
+{
+    WHIT();
+    if (__pv->__workerThread == nullptr) {
+        return true;
+    }
+
+    // Synchronize a thread not to call cancel while feedback notify callback is processing!
+    // If ecore_thread_cancel is called, the data pointer parameter of notify callback becomes invalid. 2015.09.09
+    if (__pv->__workerNotifyCb)        {
+        eina_lock_take(&__pv->__mutex);
+        eina_lock_release(&__pv->__mutex);
+    }
+
+    if (ecore_thread_cancel(__pv->__workerThread) == EINA_FALSE) {
+        if (waitSeconds == 0)
+            return false;
+#ifndef WUSING_SDK_2_3
+#ifndef WUSING_PUBLIC_SDK
+        if (ecore_thread_wait(__pv->__workerThread, waitSeconds) == EINA_TRUE) {
+            return true;
+        }
+        WERROR("The thread is not yet canceled! But waiting time(%d ms) is over", waitSeconds);
+#else
+        WERROR("On public SDK, waiting time-out is not supported! Check cancel callback!");
+#endif /* WUSING_PUBLIC_SDK */
+#else
+        WERROR("On 2.3 SDK, waiting time-out is not supported! Check cancel callback!");
+#endif /* WUSING_SDK_2_3 */
+        return false;
+    }
+    return true;
+}
+
+bool WUiThread::wait(double waitSeconds)
+{
+    WHIT();
+    if (__pv->__workerThread == nullptr) {
+        return true;
+    }
+
+#ifndef WUSING_SDK_2_3
+#ifndef WUSING_PUBLIC_SDK
+    if (ecore_thread_wait(__pv->__workerThread, waitSeconds) == EINA_TRUE) {
+        return true;
+    }
+    WERROR("The thread is not yet completed! But waiting time(%d ms) is over", waitSeconds);
+#else
+    WERROR("On public SDK, it is not supported!");
+#endif /* WUSING_PUBLIC_SDK */
+#else
+    WERROR("On 2.3 SDK, it is not supported!");
+#endif /* WUSING_SDK_2_3 */
+
+    return false;
+}
+
+bool WUiThread::cancelWithoutCallback(double waitSeconds)
+{
+    WHIT();
+    __pv->__stopFlag = true;
+    if (cancel(waitSeconds) == false) {
+        WERROR("Failed to cancel!");
+        return false;
+    }
+    return true;
+}
+
+void WUiThread::setThreadGlobalDataInt(int data)
+{
+    __pv->__setThreadGlobalDataInt(data);
+}
+
+void WUiThread::setThreadGlobalDataInt(const char* key, int data)
+{
+    __pv->__setThreadGlobalDataInt(key, data);
+}
diff --git a/src/app-assist-efl/WUiTimer.cpp b/src/app-assist-efl/WUiTimer.cpp
new file mode 100644 (file)
index 0000000..36bd6de
--- /dev/null
@@ -0,0 +1,204 @@
+/*
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0
+ *
+ * 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 "WUiTimer.h"
+#include "WDebugInternal.h"
+#include "WDefineInternal.h"
+#include "WUiTimerImpl.h"
+
+using namespace app_assist;
+
+WUiTimer::WUiTimer()
+{
+    WHIT();
+    __pv = new _WUiTimerImpl();
+}
+
+WUiTimer::~WUiTimer()
+{
+    WHIT();
+    if (__pv->__ownerObj) {
+        evas_object_event_callback_del_full(__pv->__ownerObj, EVAS_CALLBACK_DEL, _WUiTimerImpl::__ownerObjDelCb, this);
+    }
+    delete __pv;
+}
+
+WUiTimer::Type WUiTimer::getType()
+{
+    return __pv->__type;
+}
+
+void WUiTimer::destroy(WUiTimerWeakPtr& timer)
+{
+    if (auto p = timer.lock()) {
+        delete p.get();
+    }
+    timer.reset();
+}
+
+WUiTimerWeakPtr WUiTimer::addIdler(const std::function<Eina_Bool(void*)>& timerFunc, void* userData,  Evas_Object* ownerObj)
+{
+    WASSERT_EX(ownerObj != nullptr, "ownerObj is null.");
+
+    WUiTimerWeakPtr timerPtr = WUiTimer::addIdler(timerFunc, userData);
+    std::shared_ptr<WUiTimer> timer = timerPtr.lock();
+    timer->__pv->__ownerObj = ownerObj;
+
+    evas_object_event_callback_add(ownerObj, EVAS_CALLBACK_DEL, _WUiTimerImpl::__ownerObjDelCb, timer.get());
+
+    timer.reset();
+
+    return timerPtr;
+}
+
+WUiTimerWeakPtr WUiTimer::addIdler(const std::function<Eina_Bool(void*)>& timerFunc, void* userData)
+{
+    WUiTimer* timer = new WUiTimer();
+    timer->__pv->__selfPtr = new std::shared_ptr<WUiTimer>(timer, [](WUiTimer * p) {});
+    timer->__pv->__type = WUiTimer::Type::IDLER;
+    timer->__pv->__timerFunc = timerFunc;
+    timer->__pv->__userData = userData;
+    Ecore_Idler* ecoreIdler = ecore_idler_add(_WUiTimerImpl::__timerCb, timer);
+    if (ecoreIdler == nullptr) {
+        WERROR("failed to add ecore idler!");
+        delete timer;
+        return std::weak_ptr<WUiTimer>();
+    }
+    timer->__pv->__timer = ecoreIdler;
+
+    return std::weak_ptr<WUiTimer>(*timer->__pv->__selfPtr);
+}
+
+WUiTimerWeakPtr WUiTimer::addAnimator(const std::function<Eina_Bool(void*)>& timerFunc, void* userData, Evas_Object* ownerObj)
+{
+    WASSERT_EX(ownerObj != nullptr, "ownerObj is null.");
+
+    WUiTimerWeakPtr timerPtr = WUiTimer::addAnimator(timerFunc, userData);
+    std::shared_ptr<WUiTimer> timer = timerPtr.lock();
+    timer->__pv->__ownerObj = ownerObj;
+
+    evas_object_event_callback_add(ownerObj, EVAS_CALLBACK_DEL, _WUiTimerImpl::__ownerObjDelCb, timer.get());
+
+    timer.reset();
+
+    return timerPtr;
+}
+
+WUiTimerWeakPtr WUiTimer::addAnimator(const std::function<Eina_Bool(void*)>& timerFunc, void* userData)
+{
+    WUiTimer* timer = new WUiTimer();
+    timer->__pv->__selfPtr = new std::shared_ptr<WUiTimer>(timer, [](WUiTimer * p) {});
+    timer->__pv->__type = WUiTimer::Type::ANIMATOR;
+    timer->__pv->__timerFunc = timerFunc;
+    timer->__pv->__userData = userData;
+    Ecore_Animator* ecoreAnimator = ecore_animator_add(_WUiTimerImpl::__timerCb, timer);
+    if (ecoreAnimator == nullptr) {
+        WERROR("failed to add ecore animator!");
+        delete timer;
+        return std::weak_ptr<WUiTimer>();
+    }
+    timer->__pv->__timer = ecoreAnimator;
+
+    return std::weak_ptr<WUiTimer>(*timer->__pv->__selfPtr);
+}
+
+WUiTimerWeakPtr WUiTimer::addTimer(double interval, const std::function<Eina_Bool(void*)>& timerFunc, void* userData, Evas_Object* ownerObj)
+{
+    WASSERT_EX(ownerObj != nullptr, "ownerObj is null.");
+
+    WUiTimerWeakPtr timerPtr = WUiTimer::addTimer(interval, timerFunc, userData);
+    std::shared_ptr<WUiTimer> timer = timerPtr.lock();
+    timer->__pv->__ownerObj = ownerObj;
+
+    evas_object_event_callback_add(ownerObj, EVAS_CALLBACK_DEL, _WUiTimerImpl::__ownerObjDelCb, timer.get());
+
+    timer.reset();
+
+    return timerPtr;
+}
+
+WUiTimerWeakPtr WUiTimer::addTimer(double interval, const std::function<Eina_Bool(void*)>& timerFunc, void* userData)
+{
+    WUiTimer* timer = new WUiTimer();
+    timer->__pv->__selfPtr = new std::shared_ptr<WUiTimer>(timer, [](WUiTimer * p) {});
+    timer->__pv->__type = WUiTimer::Type::TIMER;
+    timer->__pv->__timerFunc = timerFunc;
+    timer->__pv->__userData = userData;
+    Ecore_Timer* ecoreTimer = ecore_timer_add(interval, _WUiTimerImpl::__timerCb, timer);
+    if (ecoreTimer == nullptr) {
+        WERROR("failed to add ecore timer!");
+        delete timer;
+        return std::weak_ptr<WUiTimer>();
+    }
+    timer->__pv->__timer = ecoreTimer;
+
+    return std::weak_ptr<WUiTimer>(*timer->__pv->__selfPtr);
+}
+
+WUiTimerWeakPtr WUiTimer::addJob(const std::function<void(void*)>& timerFunc, void* userData, Evas_Object* ownerObj)
+{
+    WASSERT_EX(ownerObj != nullptr, "ownerObj is null.");
+
+    WUiTimerWeakPtr timerPtr = WUiTimer::addJob(timerFunc, userData);
+    std::shared_ptr<WUiTimer> timer = timerPtr.lock();
+    timer->__pv->__ownerObj = ownerObj;
+
+    evas_object_event_callback_add(ownerObj, EVAS_CALLBACK_DEL, _WUiTimerImpl::__ownerObjDelCb, timer.get());
+
+    timer.reset();
+
+    return timerPtr;
+}
+
+WUiTimerWeakPtr WUiTimer::addJob(const std::function<void(void*)>& timerFunc, void* userData)
+{
+    WUiTimer* timer = new WUiTimer();
+    timer->__pv->__selfPtr = new std::shared_ptr<WUiTimer>(timer, [](WUiTimer * p) {});
+    timer->__pv->__type = WUiTimer::Type::JOB;
+    timer->__pv->__jobFunc = timerFunc;
+    timer->__pv->__userData = userData;
+    Ecore_Job* ecoreJob = ecore_job_add(_WUiTimerImpl::__jobCb, timer);
+    if (ecoreJob == nullptr) {
+        WERROR("failed to add ecore job!");
+        delete timer;
+        return std::weak_ptr<WUiTimer>();
+    }
+    timer->__pv->__timer = ecoreJob;
+
+    return std::weak_ptr<WUiTimer>(*timer->__pv->__selfPtr);
+}
+
+Ecore_Idler* app_assist::wuitimer_get_idler_handle(const WUiTimerWeakPtr& uiTimer)
+{
+    return _WUiTimerImpl::getIdlerHandle(uiTimer);
+}
+
+Ecore_Animator* app_assist::wuitimer_get_animator_handle(const WUiTimerWeakPtr& uiTimer)
+{
+    return _WUiTimerImpl::getAnimatorHandle(uiTimer);
+}
+
+Ecore_Timer* app_assist::wuitimer_get_timer_handle(const WUiTimerWeakPtr& uiTimer)
+{
+    return _WUiTimerImpl::getTimerHandle(uiTimer);
+}
+
+Ecore_Job* app_assist::wuitimer_get_job_handle(const WUiTimerWeakPtr& uiTimer)
+{
+    return _WUiTimerImpl::getJobHandle(uiTimer);
+}
+
diff --git a/src/app-assist-efl/WUiTimerImpl.cpp b/src/app-assist-efl/WUiTimerImpl.cpp
new file mode 100644 (file)
index 0000000..6816458
--- /dev/null
@@ -0,0 +1,145 @@
+/*
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0
+ *
+ * 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 "WUiTimerImpl.h"
+#include <Ecore.h>
+#include "WDefine.h"
+#include "WDebugInternal.h"
+#include "WUiTimer.h"
+
+using namespace app_assist;
+
+_WUiTimerImpl::_WUiTimerImpl():
+    __timer(nullptr),
+    __type(WUiTimer::Type::IDLER),
+    __userData(nullptr),
+    __selfPtr(nullptr),
+    __ownerObj(nullptr)
+{
+}
+
+_WUiTimerImpl::~_WUiTimerImpl()
+{
+    __deleteTimer();
+    delete __selfPtr;
+}
+
+void _WUiTimerImpl::__deleteTimer()
+{
+    if (__timer) {
+        switch (__type) {
+        case WUiTimer::Type::IDLER:
+            ecore_idler_del((Ecore_Idler*)__timer);
+            break;
+        case WUiTimer::Type::ANIMATOR:
+            ecore_animator_del((Ecore_Animator*)__timer);
+            break;
+        case WUiTimer::Type::TIMER:
+            ecore_timer_del((Ecore_Timer*)__timer);
+            break;
+        case WUiTimer::Type::JOB:
+            ecore_job_del((Ecore_Job*)__timer);
+            break;
+        default:
+            break;
+        }
+        __timer = nullptr;
+    }
+}
+
+void _WUiTimerImpl::__ownerObjDelCb(void* data, Evas* evas, Evas_Object* obj, void* event_info)
+{
+    WHIT();
+
+    auto timer = (WUiTimer*)data;
+    timer->__pv->__ownerObj = nullptr;
+    delete timer;
+}
+
+Eina_Bool _WUiTimerImpl::__timerCb(void* data)
+{
+    auto timer = (WUiTimer*)data;
+    std::weak_ptr<WUiTimer> timerWeakPtr(*(timer->__pv->__selfPtr));
+
+    Eina_Bool ret = timer->__pv->__timerFunc(timer->__pv->__userData);
+    if (ret == ECORE_CALLBACK_CANCEL && !timerWeakPtr.expired()) {
+        timer->__pv->__timer = nullptr;
+        delete timer;
+    }
+
+    return ret;
+}
+
+void _WUiTimerImpl::__jobCb(void* data)
+{
+    auto timer = (WUiTimer*)data;
+    std::weak_ptr<WUiTimer> timerWeakPtr(*(timer->__pv->__selfPtr));
+
+    timer->__pv->__jobFunc(timer->__pv->__userData);
+    if (!timerWeakPtr.expired()) {
+        timer->__pv->__timer = nullptr;
+        delete timer;
+    }
+}
+
+Ecore_Idler* _WUiTimerImpl::getIdlerHandle(const WUiTimerWeakPtr& uiTimer)
+{
+    if (auto p = uiTimer.lock()) {
+        if (p->__pv->__type != WUiTimer::Type::IDLER) {
+            WERROR("This is not Idler type timer!");
+            return nullptr;
+        }
+        return (Ecore_Idler*)p->__pv->__timer;
+    }
+    return nullptr;
+}
+
+Ecore_Animator* _WUiTimerImpl::getAnimatorHandle(const WUiTimerWeakPtr& uiTimer)
+{
+    if (auto p = uiTimer.lock()) {
+        if (p->__pv->__type != WUiTimer::Type::ANIMATOR) {
+            WERROR("This is not Animator type timer!");
+            return nullptr;
+        }
+        return (Ecore_Animator*)p->__pv->__timer;
+    }
+    return nullptr;
+}
+
+Ecore_Timer* _WUiTimerImpl::getTimerHandle(const WUiTimerWeakPtr& uiTimer)
+{
+    if (auto p = uiTimer.lock()) {
+        if (p->__pv->__type != WUiTimer::Type::TIMER) {
+            WERROR("This is not Timer type timer!");
+            return nullptr;
+        }
+        return (Ecore_Timer*)p->__pv->__timer;
+    }
+    return nullptr;
+}
+
+Ecore_Job* _WUiTimerImpl::getJobHandle(const WUiTimerWeakPtr& uiTimer)
+{
+    if (auto p = uiTimer.lock()) {
+        if (p->__pv->__type != WUiTimer::Type::JOB) {
+            WERROR("This is not Job type timer!");
+            return nullptr;
+        }
+        return (Ecore_Job*)p->__pv->__timer;
+    }
+    return nullptr;
+}
diff --git a/src/app-assist-efl/WUiTimerImpl.h b/src/app-assist-efl/WUiTimerImpl.h
new file mode 100644 (file)
index 0000000..effb0bb
--- /dev/null
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0
+ *
+ * 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 _APP_ASSIST_WUI_TIMER_IMPL_H_
+#define _APP_ASSIST_WUI_TIMER_IMPL_H_
+
+#include <Ecore.h>
+#include "WUiTimer.h"
+
+namespace app_assist
+{
+
+class _WUiTimerImpl
+{
+public:
+    _WUiTimerImpl();
+    ~_WUiTimerImpl();
+private:
+    //
+    void* __timer;
+    WUiTimer::Type __type;
+
+    void* __userData;
+    std::shared_ptr<WUiTimer>* __selfPtr;
+    Evas_Object* __ownerObj;
+
+    std::function<Eina_Bool(void*)> __timerFunc;
+    std::function<void(void*)> __jobFunc;
+    //
+    void __deleteTimer();
+
+    static void __ownerObjDelCb(void* data, Evas* evas, Evas_Object* obj, void* event_info);
+    static Eina_Bool __timerCb(void* data);
+    static void __jobCb(void* data);
+
+    static Ecore_Idler* getIdlerHandle(const WUiTimerWeakPtr& uiTimer);
+    static Ecore_Animator* getAnimatorHandle(const WUiTimerWeakPtr& uiTimer);
+    static Ecore_Timer* getTimerHandle(const WUiTimerWeakPtr& uiTimer);
+    static Ecore_Job* getJobHandle(const WUiTimerWeakPtr& uiTimer);
+    //
+    friend class WUiTimer;
+    friend Ecore_Idler* wuitimer_get_idler_handle(const WUiTimerWeakPtr& uiTimer);
+    friend Ecore_Animator* wuitimer_get_animator_handle(const WUiTimerWeakPtr& uiTimer);
+    friend Ecore_Timer* wuitimer_get_timer_handle(const WUiTimerWeakPtr& uiTimer);
+    friend Ecore_Job* wuitimer_get_job_handle(const WUiTimerWeakPtr& uiTimer);
+};
+
+} // namespace
+
+#endif /* __APP_ASSIST_WUI_TIMER_IMPL_H__ */
diff --git a/src/app-assist-efl/WVersion.cpp b/src/app-assist-efl/WVersion.cpp
new file mode 100644 (file)
index 0000000..a8052b1
--- /dev/null
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0
+ *
+ * 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 "WDefine.h"
+#include <stdio.h>
+#include <string.h>
+
+int app_assist::WVersion_getMajor()
+{
+    return WAPP_ASSIST_VERSION_MAJOR;
+}
+int app_assist::WVersion_getMinor()
+{
+    return WAPP_ASSIST_VERSION_MINOR;
+}
+int app_assist::WVersion_getPatch()
+{
+    return WAPP_ASSIST_VERSION_PATCH;
+}
+const char* app_assist::WVersion_getPre()
+{
+    return WAPP_ASSIST_VERSION_PRE;
+}
+const char* app_assist::WVersion_get()
+{
+    static char ver[24] = {0, };
+    if (ver[0] == '\0') {
+        if (strlen(WAPP_ASSIST_VERSION_PRE))
+            snprintf(ver, sizeof(ver), "%d.%d.%d.%s", WAPP_ASSIST_VERSION_MAJOR, WAPP_ASSIST_VERSION_MINOR, WAPP_ASSIST_VERSION_PATCH, WAPP_ASSIST_VERSION_PRE);
+        else
+            snprintf(ver, sizeof(ver), "%d.%d.%d", WAPP_ASSIST_VERSION_MAJOR, WAPP_ASSIST_VERSION_MINOR, WAPP_ASSIST_VERSION_PATCH);
+    }
+
+    return ver;
+}
diff --git a/src/app-assist-efl/WViewController.cpp b/src/app-assist-efl/WViewController.cpp
new file mode 100644 (file)
index 0000000..e34d35d
--- /dev/null
@@ -0,0 +1,206 @@
+/*
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0
+ *
+ * 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 "WViewController.h"
+#include <memory.h>
+#include <Elementary.h>
+#include "WDebugInternal.h"
+#include "WDefineInternal.h"
+#include "IWWindowController.h"
+#include "WViewControllerImpl.h"
+
+using namespace app_assist;
+
+#define _CLASS_NAME    "WViewController"
+
+WViewController::WViewController()
+{
+    __pv = new _WViewControllerImpl();
+}
+
+WViewController::~WViewController()
+{
+    if (__pv->__name) {
+        WDEBUG("name=%s", __pv->__name);
+    } else {
+        WHIT();
+    }
+    //
+    delete __pv;
+}
+const char* WViewController::getClassName() const
+{
+    return _CLASS_NAME;
+}
+
+bool WViewController::create(Evas_Object* parent, void* param)
+{
+    if (__pv->__name)
+        WDEBUG("name=%s", __pv->__name);
+    else
+        WHIT();
+
+    if (__pv->__obj) {
+        WDEBUG("Already created!");
+        return true;
+    }
+    if (!onCreate(param)) {
+        WDEBUG("Failed to create!");
+        return false;
+    }
+
+    if (__pv->__createViewDelegate)
+        __pv->__obj = (*__pv->__createViewDelegate)(parent, param);
+    else
+        __pv->__obj = onCreateView(parent, param);
+
+    if (__pv->__obj == nullptr) {
+        WERROR("No view object created!");
+        return false;
+    }
+
+    // get window controller
+    Evas_Object* obj = __pv->__obj;
+    while ((obj = elm_object_parent_widget_get(obj)) != nullptr) {
+        if ((__pv->__windowController = (IWWindowController*)evas_object_data_get(obj, WKEY_WINDOW_INSTANCE)) != nullptr) {
+            break;
+        }
+    }
+    WASSERT_EX(__pv->__windowController != nullptr, "Cannot find window controll.");
+
+    if (__pv->__name) {    // for easy debugging
+        evas_object_name_set(__pv->__obj, __pv->__name);
+    }
+
+    evas_object_data_set(__pv->__obj, WKEY_VIEW_INSTANCE, this);
+    evas_object_event_callback_add(__pv->__obj, EVAS_CALLBACK_DEL, _WViewControllerImpl::__objDelCb, this);
+    //
+    // Do not place this before "evas_object_event_callback_add",
+    // The reason is that if additional del callback is added at child class, it should be called first to keep state the class object is still alive.
+    onCreated();
+
+    return true;
+}
+
+void WViewController::destroy()
+{
+    if (__pv->__obj) {
+        evas_object_del(__pv->__obj);
+        // Do not leave any code here.
+        // After executing upper statement "evas_object_del", this object will be deleted at evas object deletion callback!
+
+    } else {
+        onDestroy();
+        delete this;
+    }
+}
+
+Evas_Object* WViewController::getEvasObj() const
+{
+    return __pv->__obj;
+}
+
+void WViewController::setName(const char* name)
+{
+    if (__pv->__name) {
+        free(__pv->__name);
+        __pv->__name = nullptr;
+    }
+    if (name) {
+        __pv->__name = (char*)malloc(strlen(name) + 1);
+        strcpy(__pv->__name, name);
+    }
+}
+
+const char* WViewController::getName() const
+{
+    return __pv->__name;
+}
+
+void WViewController::setOnCreateView(const std::function<Evas_Object* (Evas_Object*, void*)>& delegateFunc)
+{
+    if (__pv->__createViewDelegate == nullptr)
+        __pv->__createViewDelegate = new std::function<Evas_Object* (Evas_Object*, void*)>;
+    *__pv->__createViewDelegate = delegateFunc;
+}
+
+std::weak_ptr<WViewController> WViewController::getWeakPtr()
+{
+    if (__pv->__selfPtr) {
+        return std::weak_ptr<WViewController>(*__pv->__selfPtr);
+    }
+    __pv->__selfPtr = new std::shared_ptr<WViewController>(this, [](WViewController * p) {});
+    return std::weak_ptr<WViewController>(*__pv->__selfPtr);
+}
+
+void WViewController::attachPopup(WViewController* popup)
+{
+    Evas_Object* parent = nullptr;
+    Evas_Object* obj = getEvasObj();
+    while ((obj = elm_object_parent_widget_get(obj)) != nullptr) {
+        if (evas_object_data_get(obj, WKEY_BASELAYOUT_TAG) != nullptr) {
+            parent = obj;
+            break;
+        }
+    }
+
+    if (parent == nullptr) {
+        WERROR("Cannot find parent View!");
+        // If the pop-up has been already created, the following statement will just return without creating pop-up.
+        popup->create(elm_object_top_widget_get(getEvasObj()), nullptr);
+    } else {
+        // If the pop-up has been already created, the following statement will just return without creating pop-up.
+        popup->create(parent, nullptr);
+    }
+
+    // destroy old popup after new popup created
+    destroyPopup();
+
+    if (__pv->__popupMonitor == nullptr)
+        __pv->__popupMonitor = new std::weak_ptr<WViewController>;
+    *__pv->__popupMonitor = popup->getWeakPtr();
+}
+
+void WViewController::destroyPopup()
+{
+    if (__pv->__popupMonitor == nullptr) return;
+
+    if (auto p = __pv->__popupMonitor->lock()) {
+        p->destroy();
+        __pv->__popupMonitor->reset();
+    }
+}
+
+IWWindowController* WViewController::getWindowController()
+{
+    return __pv->__windowController;
+}
+
+WViewController* app_assist::wviewcontroller_get_instance_from_evasobj(Evas_Object* obj)
+{
+    return (WViewController*)evas_object_data_get(obj, WKEY_VIEW_INSTANCE);
+}
+
+Evas_Object* app_assist::wviewcontroller_get_window_baselayout_evasobj(WViewController* view)
+{
+    return _WViewControllerImpl::getWindowBaseLayoutEvasObj(view);
+}
+
+Evas_Object* app_assist::wviewcontroller_get_window_evasobj(WViewController* view)
+{
+    return _WViewControllerImpl::getWindowEvasObj(view);
+}
diff --git a/src/app-assist-efl/WViewControllerImpl.cpp b/src/app-assist-efl/WViewControllerImpl.cpp
new file mode 100644 (file)
index 0000000..ed28734
--- /dev/null
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0
+ *
+ * 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 "WViewControllerImpl.h"
+#include <memory.h>
+#include "WViewController.h"
+#include "IWWindowController.h"
+#include "WDebugInternal.h"
+
+using namespace app_assist;
+
+_WViewControllerImpl::_WViewControllerImpl():
+    __obj(nullptr),
+    __name(nullptr),
+    __selfPtr(nullptr),
+    __popupMonitor(nullptr),
+    __createViewDelegate(nullptr),
+    __windowController(nullptr)
+{
+}
+
+_WViewControllerImpl::~_WViewControllerImpl()
+{
+    free(__name);
+
+    if (__popupMonitor) {
+        if (auto p = __popupMonitor->lock()) {
+            p->destroy();
+        }
+    }
+    delete __popupMonitor;
+    delete __createViewDelegate;
+    delete __selfPtr;
+}
+
+void _WViewControllerImpl::__objDelCb(void* data, Evas* evas, Evas_Object* obj, void* event_info)
+{
+    auto ctrl = (WViewController*)data;
+    ctrl->onDestroy();
+
+    delete ctrl;
+}
+
+Evas_Object* _WViewControllerImpl::getWindowBaseLayoutEvasObj(WViewController* view)
+{
+    if (view->getWindowController()) {
+        return view->getWindowController()->getBaseLayoutEvasObj();
+    } else {
+        WERROR("Fail to get base layout!");
+        return nullptr;
+    }
+}
+
+Evas_Object* _WViewControllerImpl::getWindowEvasObj(WViewController* view)
+{
+    if (view->getWindowController()) {
+        return view->getWindowController()->getEvasObj();
+    } else {
+        WERROR("Fail to get window evas object!");
+        return nullptr;
+    }
+}
+
diff --git a/src/app-assist-efl/WViewControllerImpl.h b/src/app-assist-efl/WViewControllerImpl.h
new file mode 100644 (file)
index 0000000..17d10a1
--- /dev/null
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0
+ *
+ * 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 _APP_ASSIST_WVIEW_CONTROLLER_IMPL_H_
+#define _APP_ASSIST_WVIEW_CONTROLLER_IMPL_H_
+
+//#include <memory>
+#include <Evas.h>
+#include "IWWindowController.h"
+
+namespace app_assist
+{
+
+class WViewController;
+
+class _WViewControllerImpl
+{
+public:
+    _WViewControllerImpl();
+    ~_WViewControllerImpl();
+private:
+
+    Evas_Object* __obj;
+    char* __name;
+    std::shared_ptr<WViewController>* __selfPtr;
+    std::weak_ptr<WViewController>* __popupMonitor;
+    std::function<Evas_Object* (Evas_Object*, void*)>* __createViewDelegate;
+    IWWindowController* __windowController;
+
+    static void __objDelCb(void* data, Evas* evas, Evas_Object* obj, void* event_info);
+    static Evas_Object* getWindowBaseLayoutEvasObj(WViewController* view);
+    static Evas_Object* getWindowEvasObj(WViewController* view);
+    //
+    friend class WViewController;
+    friend Evas_Object* wviewcontroller_get_window_baselayout_evasobj(WViewController* view);
+    friend Evas_Object* wviewcontroller_get_window_evasobj(WViewController* view);
+};
+
+} // namespace
+
+#endif /* __APP_ASSIST_WVIEW_CONTROLLER_IMPL_H__ */
diff --git a/src/app-assist-efl/WWindowController.cpp b/src/app-assist-efl/WWindowController.cpp
new file mode 100644 (file)
index 0000000..ff8fc53
--- /dev/null
@@ -0,0 +1,366 @@
+/*
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0
+ *
+ * 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 "WWindowController.h"
+#include <Elementary.h>
+#include <efl_extension.h>
+
+#ifndef WUSING_PUBLIC_SDK
+
+//#ifndef WUSING_SDK_2_3
+//#include <app_extension.h>
+//#else
+#include <app.h>
+//#endif
+
+#endif
+
+#include "WViewController.h"
+#include "WDebugInternal.h"
+#include "WDefineInternal.h"
+
+using namespace app_assist;
+
+#ifndef WUSING_PUBLIC_SDK
+#define _USE_PROCESS_POOL      0
+#else
+#define _USE_PROCESS_POOL      0
+#endif
+
+#define _CLASS_NAME    "WWindowController"
+
+namespace app_assist
+{
+
+class _WWindowControllerImpl
+{
+public:
+    _WWindowControllerImpl(const char* inName, Elm_Win_Type inWinType);
+    _WWindowControllerImpl() = delete;
+    ~_WWindowControllerImpl();
+public:
+    //
+    Evas_Object* __win;
+    Evas_Object* __baseLayout;
+    Evas_Object* __conformant;
+    WViewController* __baseViewController;
+    char* __name;
+    Elm_Win_Type __winType;
+    //
+    std::function<Evas_Object* ()> __createWinDelegate;
+    std::function<Evas_Object* (Evas_Object*, Evas_Object**)> __createBaseLayoutDelegate;
+    std::function<void()> __backHandler;
+
+    static void __delReqCb(void* data, Evas_Object* obj, void* event_info);
+    static void __objDelCb(void* data, Evas* evas, Evas_Object* obj, void* event_info);
+};
+}
+
+_WWindowControllerImpl::_WWindowControllerImpl(const char* name, Elm_Win_Type winType):
+    __win(nullptr),
+    __baseLayout(nullptr),
+    __conformant(nullptr),
+    __baseViewController(nullptr),
+    __name(nullptr),
+    __winType(ELM_WIN_BASIC)
+{
+    WASSERT(name);
+    __name = (char*)malloc(strlen(name) + 1);
+    strcpy(__name, name);
+    __winType = winType;
+}
+
+_WWindowControllerImpl::~_WWindowControllerImpl()
+{
+    free(__name);
+}
+
+
+void _WWindowControllerImpl::__delReqCb(void* data, Evas_Object* obj, void* event_info)
+{
+    WHIT();
+    elm_exit();
+}
+void _WWindowControllerImpl::__objDelCb(void* data, Evas* evas, Evas_Object* obj, void* event_info)
+{
+    WHIT();
+
+    auto win = (WWindowController*)data;
+
+    win->onDestroy();
+    delete win;
+}
+
+
+WWindowController::WWindowController(const char* name, Elm_Win_Type winType)
+{
+    __pv = new _WWindowControllerImpl(name, winType);
+}
+
+WWindowController::~WWindowController()
+{
+    WHIT();
+    delete __pv;
+}
+
+const char* WWindowController::getClassName()
+{
+    return _CLASS_NAME;
+}
+
+bool WWindowController::create()
+{
+    if (__pv->__win) {
+        WDEBUG("Already created!");
+        return true;
+    }
+
+    if (precreate()) {
+        evas_object_show(__pv->__win);
+        return true;
+    } else {
+        return false;
+    }
+}
+
+bool WWindowController::precreate()
+{
+    if (__pv->__win) {
+        WDEBUG("Already created!");
+        return true;
+    }
+
+    Evas_Object* win = nullptr;
+    if (__pv->__createWinDelegate)
+        win = __pv->__createWinDelegate();
+    else
+        win = onCreateWin();
+    __pv->__win = win;
+    if (win) {
+        Evas_Object* cf = nullptr;
+        if (__pv->__createBaseLayoutDelegate)
+            __pv->__baseLayout = __pv->__createBaseLayoutDelegate(win, &cf);
+        else
+            __pv->__baseLayout = onCreateBaseLayout(win, &cf);
+        __pv->__conformant = cf;
+        evas_object_data_set(win, WKEY_WINDOW_INSTANCE, this);
+        if (__pv->__baseLayout)
+            evas_object_data_set(__pv->__baseLayout, WKEY_BASELAYOUT_TAG, this);
+        // This callback function is called when 'x' close button on the window at desktop mode. In mobile, it will not be called.
+        evas_object_smart_callback_add(win, "delete,request", _WWindowControllerImpl::__delReqCb, this);
+        evas_object_event_callback_add(win, EVAS_CALLBACK_DEL, _WWindowControllerImpl::__objDelCb, this);
+
+        if (__pv->__backHandler) {
+            eext_object_event_callback_add(win, EEXT_CALLBACK_BACK,
+            [](void *data, Evas_Object *obj, void *event_info)->void {
+                auto wc = (WWindowController*)data;
+                wc->__pv->__backHandler();
+            }, this);
+        }
+
+        return true;
+    } else {
+        return false;
+    }
+}
+
+void WWindowController::destroy()
+{
+    if (__pv->__win) {
+        evas_object_del(__pv->__win);
+        // Do not leave any code here.
+        // After executing upper statement "evas_object_del", this object will be deleted at evas object deletion callback!
+
+    } else {
+        onDestroy();
+        delete this;
+    }
+}
+
+Evas_Object* WWindowController::getEvasObj() const
+{
+    return __pv->__win;
+}
+
+Evas_Object* WWindowController::getBaseLayoutEvasObj()
+{
+    return __pv->__baseLayout;
+}
+
+Evas_Object* WWindowController::getConformantEvasObj()
+{
+    return __pv->__conformant;
+}
+
+bool WWindowController::attachBaseViewController(WViewController* vc, void* creationParam)
+{
+    WASSERT(__pv->__baseViewController == nullptr);
+
+    // If baseLayout is nullptr, the vc should be already created before attaching.
+    if (__pv->__baseLayout) {
+        if (vc->create(__pv->__baseLayout, creationParam) == false) {
+            return false;
+        }
+    }
+
+    onAttachBaseViewController(vc);
+
+    __pv->__baseViewController = vc;
+
+//     evas_object_data_set( vc->getEvasObj(), WKEY_WINDOW_INSTANCE, this );
+
+    return true;
+}
+
+bool WWindowController::attachBaseViewController(WViewController* vc)
+{
+    return attachBaseViewController(vc, nullptr);
+}
+
+WViewController* WWindowController::getBaseViewController()
+{
+    return __pv->__baseViewController;
+}
+
+WViewController* WWindowController::detachBaseViewController()
+{
+    WViewController* vc = __pv->__baseViewController;
+
+    onDetachBaseViewController(vc);
+
+    __pv->__baseViewController = nullptr;
+
+    return vc;
+}
+
+void WWindowController::destroyBaseViewController()
+{
+    if (__pv->__baseViewController)
+        __pv->__baseViewController->destroy();
+
+    __pv->__baseViewController = nullptr;
+}
+
+const char* WWindowController::getName()
+{
+    return __pv->__name;
+}
+Elm_Win_Type WWindowController::getWinType()
+{
+    return __pv->__winType;
+}
+void WWindowController::setOnCreateWin(const std::function<Evas_Object* ()>& delegateFunc)
+{
+    __pv->__createWinDelegate = delegateFunc;
+}
+void WWindowController::setOnCreateBaseLayout(const std::function<Evas_Object* (Evas_Object*, Evas_Object**)>& delegateFunc)
+{
+    __pv->__createBaseLayoutDelegate = delegateFunc;
+}
+
+void WWindowController::setOnBack(const std::function<void()>& backHandlerFunc)
+{
+    __pv->__backHandler = backHandlerFunc;
+}
+
+Evas_Object* WWindowController::onCreateWin()
+{
+#if _USE_PROCESS_POOL == 1
+    Evas_Object* win = (Evas_Object*)app_get_preinitialized_window(getName());   // for launch performance
+    if (win == nullptr) {
+        WDEBUG("Process pool not used");
+        win = elm_win_add(nullptr, getName(), getWinType());
+    } else {
+        WDEBUG("Process pool used");
+    }
+#else
+    Evas_Object* win = elm_win_add(nullptr, getName(), getWinType());
+#endif
+
+    if (win == nullptr) {
+        WERROR("Fail to create win!");
+        return nullptr;
+    }
+
+    elm_win_title_set(win, getName());
+    elm_win_conformant_set(win, EINA_TRUE);
+    elm_win_autodel_set(win, EINA_TRUE);
+    if (elm_win_wm_rotation_supported_get(win)) {
+        int rotation[4] = {0, 90, 180, 270};
+        elm_win_wm_rotation_available_rotations_set(win, (const int*)(&rotation), 4);
+    }
+    elm_win_indicator_mode_set(win, ELM_WIN_INDICATOR_SHOW);
+    elm_win_indicator_opacity_set(win, ELM_WIN_INDICATOR_OPAQUE);
+
+    return win;
+}
+
+Evas_Object* WWindowController::onCreateBaseLayout(Evas_Object* win, Evas_Object** outConformant)
+{
+#if _USE_PROCESS_POOL == 1
+    Evas_Object* bg = (Evas_Object*)app_get_preinitialized_background(); // for launch performance
+    if (bg == nullptr)
+        bg = elm_bg_add(win);
+#else
+    Evas_Object* bg = elm_bg_add(win);
+#endif
+
+    evas_object_size_hint_weight_set(bg, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+    elm_win_resize_object_add(win, bg);
+    evas_object_show(bg);
+
+    // If window has no conformant object, ug creation is failed.
+#if _USE_PROCESS_POOL == 1
+    Evas_Object* cf = (Evas_Object*)app_get_preinitialized_conformant(); // for launch performance
+    if (cf == nullptr)
+        cf = elm_conformant_add(win);
+#else
+    Evas_Object* cf = elm_conformant_add(win);
+#endif
+
+    evas_object_size_hint_weight_set(cf, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+    elm_win_resize_object_add(win, cf);
+    evas_object_show(cf);
+//
+    Evas_Object* layout = elm_layout_add(cf);
+    elm_layout_theme_set(layout, "layout", "application", "default");
+    evas_object_size_hint_weight_set(layout, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+    elm_object_content_set(cf, layout);
+
+    evas_object_show(layout);
+
+    *outConformant = cf;
+
+    return layout;
+}
+
+void WWindowController::onAttachBaseViewController(WViewController* vc)
+{
+    if (getBaseLayoutEvasObj() == nullptr) {
+        WWARNING("base layout does not exist!");
+        return;
+    }
+    elm_object_part_content_set(getBaseLayoutEvasObj(), "elm.swallow.content", vc->getEvasObj());
+}
+
+void WWindowController::onDetachBaseViewController(WViewController* vc)
+{
+}
+
+void WWindowController::onDestroy()
+{
+}
diff --git a/src/app-assist-efl/inc/WContentViewControllerImpl.h b/src/app-assist-efl/inc/WContentViewControllerImpl.h
new file mode 100644 (file)
index 0000000..0f864b3
--- /dev/null
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0
+ *
+ * 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 _APP_ASSIST_WCONTENT_VIEW_CONTROLLER_IMPL_H_
+#define _APP_ASSIST_WCONTENT_VIEW_CONTROLLER_IMPL_H_
+
+#include <functional>
+#include <Elementary.h>
+
+namespace app_assist
+{
+
+class WContentViewController;
+class WNaviframeController;
+
+class _WContentViewControllerImpl
+{
+public:
+    _WContentViewControllerImpl();
+    ~_WContentViewControllerImpl();
+public:
+    bool callPushedHandlerFunc(Elm_Object_Item* naviItem);
+private:
+    //
+    char* __title;
+    Elm_Object_Item* __naviItem;
+    bool __isViewNaviItem;
+    //
+    WNaviframeController* __naviframe;
+    //
+    std::function<void(Elm_Object_Item*)> __pushedDelegate;
+
+    static void setContainerProperties(WContentViewController* view, WNaviframeController* naviframe);
+    static void setContainerNaviitemProperty(WContentViewController* view, Elm_Object_Item* item, bool isViewNaviItem);
+    static void propagateContainerPropertiesToChildViews(WContentViewController* view);
+    //
+    friend class WContentViewController;
+    friend void wcontentviewcontroller_set_container_properties(WContentViewController* view, WNaviframeController* naviframe);
+    friend void wcontentviewcontroller_set_container_naviitem_property(WContentViewController* view, Elm_Object_Item* item, bool isViewNaviItem);
+    friend void wcontentviewcontroller_propagate_container_properties_to_childviews(WContentViewController* view);
+};
+
+} // namespace
+
+#endif /* _APP_ASSIST_WCONTENT_VIEW_CONTROLLER_IMPL_H_ */
diff --git a/src/app-assist-efl/inc/WDebugInternal.h b/src/app-assist-efl/inc/WDebugInternal.h
new file mode 100755 (executable)
index 0000000..3fbc512
--- /dev/null
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0
+ *
+ * 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 _APP_ASSIST_WDEBUG_INTERNAL_H_
+#define _APP_ASSIST_WDEBUG_INTERNAL_H_
+
+#ifdef LOG_TAG
+#undef LOG_TAG
+#endif
+
+#define LOG_TAG "WAPP"
+
+#include "WDebugBase.h"
+
+
+#endif /* _APP_ASSIST_WDEBUG_INTERNAL_H_ */
diff --git a/src/app-assist-efl/inc/WDefineInternal.h b/src/app-assist-efl/inc/WDefineInternal.h
new file mode 100755 (executable)
index 0000000..048f3f5
--- /dev/null
@@ -0,0 +1,27 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0
+ *
+ * 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 _APP_ASSIST_WDEFINE_INTERNAL_H_
+#define _APP_ASSIST_WDEFINE_INTERNAL_H_
+
+
+#define WKEY_WINDOW_INSTANCE "__@WWindowInstance"
+#define WKEY_FRAME_INSTANCE "__@WNaviframeInstance"
+#define WKEY_VIEW_INSTANCE "__@WViewInstance"
+#define WKEY_BASELAYOUT_TAG    "__@WBaselayoutTag"
+
+#endif /*_APP_ASSIST_WDEFINE_INTERNAL_H_ */
diff --git a/src/app-assist-efl/inc/WMenuPopupControllerImpl.h b/src/app-assist-efl/inc/WMenuPopupControllerImpl.h
new file mode 100644 (file)
index 0000000..5c959be
--- /dev/null
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0
+ *
+ * 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 _APP_ASSIST_WMENU_POPUP_CONTROLLER_IMPL_H_
+#define _APP_ASSIST_WMENU_POPUP_CONTROLLER_IMPL_H_
+
+#include <vector>
+#include <functional>
+#include <Evas.h>
+
+namespace app_assist
+{
+
+class _WMenuPopupControllerImpl
+{
+public:
+    _WMenuPopupControllerImpl();
+    ~_WMenuPopupControllerImpl();
+public:
+    static void destroyLastMenuPopup();
+
+private:
+    //
+    static Evas_Object* __lastMenuPopup;
+
+    Evas_Object* __win;
+    Evas_Object* __resizableBaseObj;
+    Evas_Object* __popup;
+    std::vector<std::function< void()>> __vSelectItemCb;
+
+    void __init(Evas_Object* win, Evas_Object* naviframe);
+    void __popupMove();
+    Evas_Object* __create();
+
+    static void __popupSelectCb(void* data, Evas_Object* obj, void* event_info);
+    static void __popupResizeCb(void* data, Evas* e, Evas_Object* obj, void* event_info);
+    static void __popupWinRotateCb(void* data, Evas_Object* obj, void* event_info);
+    static void __popupDismissedCb(void* data, Evas_Object* obj, void* event_info);
+
+    friend class WMenuPopupController;
+};
+
+} // namespace
+
+#endif /* _APP_ASSIST_WMENU_POPUP_CONTROLLER_IMPL_H_ */
diff --git a/src/app/CDrApp.cpp b/src/app/CDrApp.cpp
new file mode 100755 (executable)
index 0000000..17186ae
--- /dev/null
@@ -0,0 +1,315 @@
+#include <runtime_info.h>
+#include <tizen.h>
+#include <system_settings.h>
+#include <app_control.h>
+#include <notification.h>
+#include "CDrApp.h"
+#include "WWindowController.h"
+#include "WNaviframeController.h"
+#include "WContentViewController.h"
+#include "DrDefine.h"
+#include "CDrAppData.h"
+#include "CDrDrawingView.h"
+#include "CDrEventManager.h"
+#include "CDrMainView.h"
+#include "CDrMediaContent.h"
+#include "CDrUtil.h"
+
+
+
+Ecore_Timer *CDrApp::_closeTimer = nullptr;
+
+CDrApp::CDrApp()
+{
+       _appControlOperation = nullptr;
+}
+
+CDrApp::~CDrApp()
+{
+       if (_appControlOperation){
+               free(_appControlOperation);
+               _appControlOperation = nullptr;
+       }
+
+       CDrEventManager::destroy();
+       CDrMediaContent::destroyInstance();
+}
+
+/* *
+ * The basic policy of Tizen applications for OOM case is "silent exit" as Android.
+ * Kernel will send SIGTERM signal (standard unix signal) to background application
+ * when OOM happens.
+ * Application should register SIGTERM handler and silently free every critical resource and exit.
+*/
+void CDrApp::_onSigtermHanlder(int signum)
+{
+       /* do something for signal handling */
+       WINFO("SIGTERM CDrApp ");
+       notification_status_message_post(DRAWING_SYATEM_TERMINATE_APP);
+       _closeTimer = ecore_timer_add(2, _onCloseTimer, nullptr);
+       ui_app_exit();
+}
+
+Eina_Bool CDrApp::_onCloseTimer(void *data)
+{
+       return ECORE_CALLBACK_CANCEL;
+}
+
+bool CDrApp::onCreate()
+{
+       /* regitering sigterm  */
+       if (signal(SIGTERM, CDrApp::_onSigtermHanlder) == SIG_IGN) {
+               WINFO("SIG_IGN SIGTERM");
+               signal(SIGTERM, SIG_IGN);
+       }
+
+       elm_app_base_scale_set(1.3);
+       elm_config_accel_preference_set("opengl");
+
+       char *resPath = app_get_resource_path();
+       if (resPath == nullptr) {
+               WERROR("Failed to get res path");
+               return false;
+       }
+       std::string localeDir(resPath);
+       free(resPath);
+
+       localeDir.append("locale");
+       /* Bind text domain for internalization */
+       bindtextdomain(LOCALE_DOMAIN, localeDir.c_str());
+
+       WDEBUG("init app");
+       CDrEventManager::getInstance();
+
+       _languageChangedHandler.addEventHandler(APP_EVENT_LANGUAGE_CHANGED, [](app_event_info_h eventInfo, void *userData) {
+                                                                                        char *locale = NULL;
+                                                                                        system_settings_get_value_string(SYSTEM_SETTINGS_KEY_LOCALE_LANGUAGE, &locale);
+                                                                                        elm_language_set(locale);
+                                                                                        free(locale);
+                                                                                        CDrEvent event(CDrEvent::LANGUAGE_CHANGED, CDrEvent::REMOTE);
+                                                                                        CDrEventManager::getInstance().notify(event);
+                                                                                        }, this);
+
+       _lowMemoryHandler.addEventHandler(APP_EVENT_LOW_MEMORY, [](app_event_info_h eventInfo, void *userData) {
+                                                                          WINFO("Low memory");
+                                                                          CDrEvent event(CDrEvent::LOW_MEMORY, CDrEvent::REMOTE);
+                                                                          CDrEventManager::getInstance().notify(event);
+                                                                          }, this);
+
+       CDrAppData::getInstance();
+       //Create window
+       WWindowController *win = new WWindowController(PACKAGE_NAME, ELM_WIN_BASIC);
+
+
+/*
+       win->setOnCreateWin([&]()->Evas_Object * {
+               return _createWin();
+       });
+
+       win->setOnCreateBaseLayout( [&](Evas_Object* win, Evas_Object** outConformant)-> Evas_Object*{
+               return _createBaseLayout(win,outConformant);
+       } );
+*/
+
+       attachWindowController(win);
+
+       CDrAppData::getInstance()->setWindow(win);
+       CDrAppData::getInstance()->setTheme();
+       CDrAppData::getInstance()->setColorTable();
+       CDrAppData::getInstance()->setFontTable();
+       CDrMediaContent::getInstance();
+
+       //set property of indicator that is status bar
+       //elm_win_indicator_mode_set(win->getEvasObj(), ELM_WIN_INDICATOR_HIDE);
+       elm_win_indicator_opacity_set(win->getEvasObj(), ELM_WIN_INDICATOR_TRANSPARENT);
+
+       Evas_Object *conformant = win->getConformantEvasObj();
+       elm_object_signal_emit(conformant, "elm,state,indicator,overlap", "");
+       evas_object_data_set(conformant, "overlap", (void *)EINA_TRUE);
+       elm_object_signal_emit(conformant, "elm,state,virtualkeypad,disable", "");
+       elm_object_signal_emit(conformant, "elm,state,clipboard,disable", "");
+
+       WDEBUG("init app");
+
+       WNaviframeController *navi = new WNaviframeController();
+
+       // Add following statements, if you want to terminate application instead of going background
+       navi->setOnLastItemPop([&](bool * popOut) {
+                                                       _appExit(popOut);
+                                                  });
+
+       getWindowController()->attachBaseViewController(navi);
+       evas_object_smart_callback_add(getWindowController()->getEvasObj(), "wm,rotation,changed", _onRotateWin, this);
+
+       CDrAppData::getInstance()->readData();
+       return true;
+}
+
+void CDrApp::onAppControl(app_control_h request, bool firstLaunch)
+{
+       WENTER();
+       if (_appControlOperation){
+               free(_appControlOperation);
+               _appControlOperation = nullptr;
+       }
+       char *caller_id = nullptr;
+       app_control_get_caller(request, &caller_id);
+
+       if (caller_id != nullptr) {
+               if(strcmp(caller_id, "com.samsung.w-home") != 0 && strcmp(caller_id, "com.samsung.w-gallery") != 0)
+                       {
+                       CDrAppData::getInstance()->setAppControlService(request);
+               }
+       }
+
+       app_control_get_operation(request, &_appControlOperation);
+       WINFO("operation [%s]", _appControlOperation);
+
+       if (firstLaunch) {
+               _setTransient(request);
+
+               _getAppControlRequest(request);
+
+       } else {
+               WINFO("not first launch");
+       }
+
+       WApp::onAppControl(request, firstLaunch);
+       WLEAVE();
+}
+
+
+void CDrApp::onTerminate()
+{
+       CDrAppData::getInstance()->writeData();
+
+       if (_closeTimer) {
+               ecore_timer_del(_closeTimer);
+               _closeTimer = nullptr;
+       }
+
+       WENTER();
+       CDrAppData::destroy();
+       WINFO("ON TERMINATE end");
+}
+
+void CDrApp::onPause()
+{
+       WENTER();
+
+       CDrEvent event(CDrEvent::APP_PAUSED, CDrEvent::REMOTE);
+       CDrEventManager::getInstance().notify(event);
+}
+
+void CDrApp::onResume()
+{
+       CDrEvent event(CDrEvent::APP_RESUMED, CDrEvent::REMOTE);
+       CDrEventManager::getInstance().notify(event);
+}
+
+Eina_Bool CDrApp::onCallerDestroy(void *data, int nType, void *pEvent)
+{
+       if (!data) {
+               WERROR("[ERR] No exist pUserData.");
+               return ECORE_CALLBACK_PASS_ON;
+       }
+
+       if (!pEvent) {
+               WERROR("[ERR] No exist pEvent.");
+               return ECORE_CALLBACK_PASS_ON;
+       }
+       WINFO(" ");
+
+       CDrApp* app = (CDrApp*)data;
+
+//     Ecore_X_Event_Window_Destroy *ev = (Ecore_X_Event_Window_Destroy *)pEvent;
+
+//     Ecore_X_Window callerXWin;
+
+       const char *id_str = app->_strWinId.c_str();
+
+
+       if(id_str == NULL){
+               WINFO("window id is not set");
+               return ECORE_CALLBACK_PASS_ON;
+       }
+       WINFO("caller id %s", id_str);
+
+//     callerXWin = (Ecore_X_Window)CDrUtil::atoi(id_str);
+
+//     if (ev->win ==  callerXWin) {
+               /*
+                       If it's from caller win then destroy.
+               */
+//             WINFO("caller window destroyed!. Destroy app. callerXWin=0x%08x",callerXWin);
+//             elm_exit();
+//             return ECORE_CALLBACK_DONE;
+//     }
+
+       return ECORE_CALLBACK_PASS_ON;
+}
+
+
+
+void CDrApp::_setTransient(const app_control_h hCaller)
+{
+       Evas_Object *lWin = getWindowController()->getEvasObj();
+       Ecore_X_Window lXWin = elm_win_xwindow_get(lWin);
+       Ecore_X_Window uXWin;
+
+       char *id_str = NULL;
+       app_control_get_extra_data(hCaller, "WindowID", &id_str);
+
+       if(id_str == NULL){
+               WINFO("window id is not set");
+               return;
+       }
+       this->_strWinId = std::string(id_str);
+       uXWin = (Ecore_X_Window)CDrUtil::atoi(id_str);
+
+       WINFO("Set Transient. Lower: 0x%08x Upper: 0x%08x ", lXWin, uXWin);
+
+       if ( uXWin == 0 )
+       {
+               WERROR("Cannot get upper X-window. cancel transient");
+               return;
+       }
+
+// TODO : Use app_group instead
+//     if(app_control_request_transient_app(hCaller, (unsigned int)lXWin, [](void *data) -> int { return 0;}, this) != APP_CONTROL_ERROR_NONE)         {
+//             WINFO("Failed to transient app_control_request_transient_app failed, use ecore_x to set transient");
+//             ecore_x_icccm_transient_for_set(lXWin, uXWin/* Foreground win*/);
+//             ecore_x_window_client_manage(uXWin);
+//     }
+//     else
+       {
+               WINFO("Set Transient Success.");
+       }
+
+//     CDrAppData::getInstance()->setCallerWinEventHandler(ecore_event_handler_add(ECORE_X_EVENT_WINDOW_DESTROY, onCallerDestroy, this));
+}
+
+
+
+void CDrApp::_getAppControlRequest(app_control_h request)
+{
+       WNaviframeController *frame = (WNaviframeController *) getWindowController()->getBaseViewController();
+       CDrMainView* pView = new CDrMainView();
+       frame->push(pView);
+}
+
+void CDrApp::_onRotateWin(void *data, Evas_Object * obj, void *event_info)
+{
+       int nDegree = -1;
+       nDegree = elm_win_rotation_get(obj);
+
+       CDrEvent event(CDrEvent::WIN_ROTATED, CDrEvent::REMOTE, &nDegree);
+       CDrEventManager::getInstance().notify(event);
+}
+
+void CDrApp::_appExit(bool * popOut)
+{
+       *popOut = true;
+
+       ui_app_exit();
+}
diff --git a/src/app/CDrApp.h b/src/app/CDrApp.h
new file mode 100755 (executable)
index 0000000..9513bf7
--- /dev/null
@@ -0,0 +1,51 @@
+#ifndef _CDR_APP_H_
+#define _CDR_APP_H_
+
+
+#include "WApp.h"
+#include "WAppEventHandler.h"
+#include <vector>
+#include <string>
+#include <Ecore.h>
+#include <Evas.h>
+#include <Elementary.h>
+#include <string>
+#include "DrDefine.h"
+
+
+using namespace app_assist;
+
+
+class CDrApp:public WApp {
+ public:
+       CDrApp();
+       ~CDrApp();
+
+ private:
+       virtual bool onCreate();
+       virtual void onTerminate();
+       virtual void onAppControl(app_control_h request, bool firstLaunch);
+       virtual void onPause();
+       virtual void onResume();
+
+private:
+       static void _onSigtermHanlder(int signum);
+       static Eina_Bool onCallerDestroy(void *data, int nType, void *pEvent);
+       void _getAppControlRequest(app_control_h request);
+       static void _onRotateWin(void *data, Evas_Object * obj, void *event_info);
+       static Eina_Bool _onCloseTimer(void *data);
+       void _appExit(bool * popOut);
+       Evas_Object* _createBaseLayout(Evas_Object* win, Evas_Object** outConformant);
+       Evas_Object* _createWin();
+       void _setTransient(const app_control_h hCaller);
+
+ private:
+       WAppEventHandler _languageChangedHandler;
+       WAppEventHandler _lowMemoryHandler;
+       static Ecore_Timer *_closeTimer;
+       char* _appControlOperation;
+
+       std::string _strWinId;
+};
+
+#endif                                                 // _CVE_APP_H_
diff --git a/src/app/CDrAppData.cpp b/src/app/CDrAppData.cpp
new file mode 100755 (executable)
index 0000000..6198fb9
--- /dev/null
@@ -0,0 +1,226 @@
+
+#include "CDrAppData.h"
+#include <app.h>
+//#include <efl_assist.h>
+#include <string>
+#include <iostream>
+#include <fstream>
+#include <app_preference.h>
+#include "CDrUtil.h"
+
+using namespace std;
+
+CDrAppData *CDrAppData::_instance = NULL;
+
+CDrAppData::CDrAppData():_callerWinEventHandler(NULL),
+                                                       _viewType(VIEW_TYPE_MAIN),
+                                                       _mainWindow(NULL),
+                                                       _colorTable(NULL),
+                                                       _fontTable(NULL),
+                                                       _appService(nullptr),
+                                                       _launchMode(DRAWING_SAVE),
+                                                       _nBgIndex(0),
+                                                       _nTutorialStatus(0)
+{
+       //CDrUtil::initResourceManager();
+}
+
+CDrAppData::~CDrAppData()
+{
+       std::string strEdjPath;
+
+       if ( _callerWinEventHandler )
+               ecore_event_handler_del(_callerWinEventHandler);
+       _callerWinEventHandler = NULL;
+
+
+       char* resPath = app_get_resource_path();
+       std::string path(resPath);
+       path += EDJ_THEME_FILE;
+       if (resPath) {
+               elm_theme_extension_del(NULL, path.c_str());
+               free(resPath);
+       }
+
+       if (_colorTable) {
+//             uxt_theme_delete_color_table(_colorTable);
+               _colorTable = NULL;
+       }
+       if (_fontTable) {
+//             uxt_theme_delete_font_table(_fontTable);
+               _fontTable = NULL;
+       }
+       if (_appService) {
+               app_control_destroy(_appService);
+       }
+       //CDrUtil::releaseResourceManager();
+       WLEAVE();
+}
+
+CDrAppData *CDrAppData::getInstance()
+{
+       if (_instance == NULL) {
+               _instance = new CDrAppData();
+       }
+       return _instance;
+}
+
+void CDrAppData::destroy()
+{
+       if (_instance) {
+               delete _instance;
+               _instance = NULL;
+       }
+}
+
+WWindowController *CDrAppData::getWindowController()
+{
+       return _mainWindow;
+}
+
+void CDrAppData::setWindow(WWindowController * wWindow)
+{
+       _mainWindow = wWindow;
+}
+
+void CDrAppData::setCallerWinEventHandler(Ecore_Event_Handler *h)
+{
+       _callerWinEventHandler = h;
+}
+
+void CDrAppData::setTheme()
+{
+       char* resPath = app_get_resource_path();
+       std::string path(resPath);
+       path += EDJ_THEME_FILE;
+       if (resPath) {
+               WINFO("Theme EDJ : %s", path.c_str());
+               elm_theme_extension_add(NULL, path.c_str());
+               /* Default state is off, need to turn in  on manually */
+//             uxt_theme_set_changeable_ui_enabled(EINA_TRUE);
+               free(resPath);
+       }
+}
+
+Eina_Bool CDrAppData::setColorTable()
+{
+       Eina_Bool bret = EINA_FALSE;
+
+       if (!_colorTable) {
+               char* sharedResPath = app_get_shared_resource_path();
+               if (sharedResPath == nullptr) {
+                       WERROR("sharedResPath is nullptr");
+                       return EINA_FALSE;
+               }
+               std::string colorTablePath(sharedResPath);
+               colorTablePath += "tables/org.tizen.w-drawing_color.xml";
+               //char *codeFile = CDrUtil::getImagePath("tables/org.tizen.w-drawing_color.xml");
+//             _colorTable = uxt_theme_add_color_table(colorTablePath.c_str());
+               WPRET_VM(!_colorTable, bret, "Failed to get color table");
+
+               /* Block redundant API call */
+               // uxt_theme_set_style(UXT_THEME_STYLE_DEFAULT);
+//             bret = uxt_theme_set_color_table(_colorTable);
+               free(sharedResPath);
+       }
+
+       return bret;
+}
+
+Eina_Bool CDrAppData::setFontTable()
+{
+       Eina_Bool bret = EINA_FALSE;
+
+       if (!_fontTable) {
+               char* sharedResPath = app_get_shared_resource_path();
+               if (sharedResPath == nullptr) {
+                       WERROR("sharedResPath is nullptr");
+                       return EINA_FALSE;
+               }
+               std::string fontTablePath(sharedResPath);
+               fontTablePath += "tables/org.tizen.w-drawing_font.xml";
+               //char *fontFile = CDrUtil::getImagePath("tables/org.tizen.w-drawing_font.xml");
+//             _fontTable = uxt_theme_add_font_table(fontTablePath.c_str());
+               WPRET_VM(!_fontTable, bret, "Failed to get font table");
+//             bret = uxt_theme_set_font_table(_fontTable);
+               free(sharedResPath);
+       }
+
+       return bret;
+}
+
+Eina_List *CDrAppData::getColorTable()
+{
+       return _colorTable;
+}
+
+Eina_List *CDrAppData::getFontTable()
+{
+       return _fontTable;
+}
+
+void CDrAppData::setAppControlService(app_control_h hRequest)
+{
+       app_control_clone(&(_appService), hRequest);
+       _launchMode = DRAWING_SEND;
+}
+
+app_control_h CDrAppData::getAppService()
+{
+       return _appService;
+}
+
+LaunchMode CDrAppData::getLaunchMode()
+{
+       return _launchMode;
+}
+
+void CDrAppData::readData()
+{
+       int ret;
+       ret = preference_get_int(PREFERENCE_KEY_APP_BG_INDEX, &_nBgIndex);
+       if (ret != PREFERENCE_ERROR_NONE) {
+               WERROR("get tutorial key failed");
+       }
+       ret = preference_get_int(PREFERENCE_KEY_TUTORIAL_IS_SHOWED, &_nTutorialStatus);
+       if (ret != PREFERENCE_ERROR_NONE) {
+               WERROR("get tutorial key failed");
+       }
+       WINFO("read bg index is %d", _nBgIndex);
+       WINFO("read tutorial status is %d", _nTutorialStatus);
+}
+
+void CDrAppData::writeData()
+{
+       _nBgIndex++;
+       if (_nBgIndex > 3) {
+               _nBgIndex = 0;
+       }
+
+       int ret;
+       ret = preference_set_int(PREFERENCE_KEY_APP_BG_INDEX, _nBgIndex);
+       if (ret != PREFERENCE_ERROR_NONE) {
+               WERROR("set tutorial key failed");
+       }
+       ret = preference_set_int(PREFERENCE_KEY_TUTORIAL_IS_SHOWED, _nTutorialStatus);
+       if (ret != PREFERENCE_ERROR_NONE) {
+               WERROR("set tutorial key failed");
+       }
+       WINFO("write bg index is %d", _nBgIndex);
+       WINFO("write tutorial status is %d", _nTutorialStatus);
+}
+
+int CDrAppData::getBgIndex()
+{
+       return _nBgIndex;
+}
+
+void CDrAppData::setTutorialStatus(int nTutorialShowed)
+{
+       _nTutorialStatus = nTutorialShowed;
+}
+
+int CDrAppData::getTutorialStatus()
+{
+       return _nTutorialStatus;
+}
diff --git a/src/app/CDrAppData.h b/src/app/CDrAppData.h
new file mode 100755 (executable)
index 0000000..1947afe
--- /dev/null
@@ -0,0 +1,82 @@
+/*
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0
+ *
+ * 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 _CDR_APP_DATA_H_
+#define _CDR_APP_DATA_H_
+
+
+//#include <ui_extension.h>
+#include <app_control.h>
+#include "WDefine.h"
+#include "WWindowController.h"
+#include "DrDefine.h"
+
+
+using namespace app_assist;
+
+class CDrAppData {
+ public:
+       static CDrAppData *getInstance();
+       static void destroy();
+
+       void setTheme();
+       Eina_Bool setColorTable();
+       Eina_Bool setFontTable();
+
+       WWindowController *getWindowController();
+       Eina_List *getColorTable();
+       Eina_List *getFontTable();
+       void setAppControlService(app_control_h hRequest);
+       app_control_h getAppService();
+       LaunchMode getLaunchMode();
+
+       void setCallerWinEventHandler(Ecore_Event_Handler *h);
+       void setWindow(WWindowController * wWindow);
+       void readData();
+       void writeData();
+       int  getBgIndex();
+       void setTutorialStatus(int nTutorialShowed);
+       int getTutorialStatus();
+
+ public:
+       typedef enum {
+               VIEW_TYPE_UNKNOWN = 0,
+               VIEW_TYPE_MAIN,
+               VIEW_TYPE_ALARM,
+       } ViewType;
+
+ private:
+        CDrAppData();
+       ~CDrAppData();
+        WDISABLE_COPY_AND_ASSIGN(CDrAppData);
+
+ private:
+       static CDrAppData *_instance;
+
+       ViewType _viewType;
+       WWindowController *_mainWindow;
+       Eina_List *_colorTable;
+       Eina_List *_fontTable;
+       app_control_h  _appService;
+       LaunchMode  _launchMode;
+       int  _nBgIndex;
+       int _nTutorialStatus;
+
+       Ecore_Event_Handler     *_callerWinEventHandler;
+};
+
+#endif                                                 // _CVE_APP_DATA_H_
diff --git a/src/controls/CDrCairoImage.cpp b/src/controls/CDrCairoImage.cpp
new file mode 100755 (executable)
index 0000000..66a8f57
--- /dev/null
@@ -0,0 +1,1459 @@
+#include "Drawing.h"
+#include "CDrDrawingView.h"
+#include "CDrAppData.h"
+#include "WUiTimer.h"
+
+
+
+#define MAX_OPTIMIZED_POINTS_COUNT   4
+#define POINTS_ARRARY_ABANDON_NUM   14  //60
+#define ERASER_LINE_WIDTH     40.0
+#define PATTERN_BG_COLOR_CODE  "AO051"
+#define DRAWING_REFER_POINTS_NUM  2
+
+using namespace std;
+
+
+void DrawingColor::drawingColorSet(std::string colorCode, bool isEraser)
+{
+       WINFO("index is %s, is_eraser: %d", colorCode.c_str(), isEraser);
+
+       int code_r = 0, code_g = 0, code_b = 0, code_a = 255;
+       edje_color_class_get(colorCode.c_str(), &code_r, &code_g, &code_b, &code_a, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
+       is_eraser = isEraser;
+
+       r = code_r/255.0;
+       g = code_g/255.0;
+       b = code_b/255.0;
+       a = code_a/255.0;
+}
+
+CLasso::CLasso()
+{
+       _pointsList[0].reserve(100);
+       _originalPointsList[0].reserve(100);
+       _strokeList[0].reserve(100);
+       _originalStrokeList.reserve(100);
+       _nDrawedIndex = 0;
+       _bMouseUp = true;
+}
+
+CLasso::~CLasso()
+{
+       for(int i = 0; i < MAX_POINTS_LIST_COUNT; i++) {
+               _pointsList[i].clear();
+               _optimizedPointsList[i].clear();
+               _strokeList[i].clear();
+               _originalPointsList[i].clear();
+       }
+       _oldPointsList.clear();
+
+       _oldStrokeList.clear();
+       _originalStrokeList.clear();
+}
+
+void CLasso::AddPoint(const CPoint &pt, int strokeWidth)
+{
+       _pointsList[0].push_back(pt);
+
+       _strokeList[0].push_back(strokeWidth);
+       _originalPointsList[0].push_back(pt);
+       _originalStrokeList.push_back(strokeWidth);
+       /* when first point is added, alos add related alpha value to alpha list  */
+       if (_originalPointsList[0].size() == 1) {
+               WINFO("updateAlphaList add");
+               drawlinesInfo info;
+               info.alpha = 0.5;
+               info.index = GetCount()-1;
+               _alphaList[0].push_back(info);
+       }
+       /* because the first point's stroke width  value has not reference factor,
+       so use default, but when the second point is added, keep same with the second point  */
+       if (_originalStrokeList.size() == 2) {
+               _strokeList[0][0] = strokeWidth;
+               _originalStrokeList[0] = strokeWidth;
+       }
+       _bMouseUp = false;
+}
+
+void CLasso::addEndPoint()
+{
+//     _pointsList[0].push_back(_pointsList[0][_pointsList[0].size()-1]);
+       _bMouseUp = true;
+}
+
+int CLasso::getLastStrokeWidth()
+{
+       int lastStrokeWidth = -1;
+       if (_originalStrokeList.size() > 1) {
+               lastStrokeWidth = _originalStrokeList[_originalStrokeList.size()-1];
+       }
+       return lastStrokeWidth;
+}
+
+int CLasso::GetCount()
+{
+       return _pointsList[0].size();
+}
+
+bool CLasso::IsEmpty()
+{
+       return _pointsList[0].empty();
+}
+
+void CLasso::Clear()
+{
+       _pointsList[0].clear();
+       _strokeList[0].clear();
+       _originalPointsList[0].clear();
+       _originalStrokeList.clear();
+}
+
+void CLasso::increaseListIndex()
+{
+#ifdef SKETCH_DRAW_ENABLE_DRAWING_EFFECT
+       for(int i = MAX_POINTS_LIST_COUNT -1; i > 0; i--) {
+               _pointsList[i].clear();
+               _pointsList[i] = _pointsList[i-1];
+               _alphaList[i].clear();
+               _alphaList[i] = _alphaList[i-1];
+               _optimizedPointsList[i].clear();
+               _optimizedPointsList[i] = _optimizedPointsList[i-1];
+
+               _strokeList[i].clear();
+               _strokeList[i] = _strokeList[i-1];
+
+               _originalPointsList[i].clear();
+               _originalPointsList[i] = _originalPointsList[i-1];
+       }
+#endif
+       _pointsList[0].clear();
+       _alphaList[0].clear();
+       _oldPointsList.clear();
+       _optimizedPointsList[0].clear();
+       _originalPointsList[0].clear();
+       _strokeList[0].clear();
+       _oldStrokeList.clear();
+       _originalStrokeList.clear();
+       _nDrawedIndex = 0;
+}
+
+void CLasso::saveOldPointsList()
+{
+       _oldPointsList.clear();
+       _oldPointsList = _optimizedPointsList[0];
+       _oldStrokeList.clear();
+       _oldStrokeList = _strokeList[0];
+}
+
+std::vector<std::pair<double, double> >* CLasso::GetInterpolatedPoints(int index)
+{
+#ifdef SKETCH_DRAW_ENABLE_DRAWING_EFFECT
+       if (0 == _alphaList[index].size() && _pointsList[index].size() == 0) {
+               WERROR(" ALPHA LIST IS 0 index =%d", index);
+               _optimizedPointsList[index].clear();
+               return &(_optimizedPointsList[index]);
+       }
+
+       if (0 < _alphaList[index].size()) {
+               int i = _alphaList[index].size()-1;
+               if (!_alphaList[index][i].bDraw) {
+                       WERROR(" ALPHA LIST draw done %d", index);
+                       if (index > 0) {
+                               _pointsList[index].clear();
+                               _alphaList[index].clear();
+                       }
+                       _optimizedPointsList[index].clear();
+                       return &(_optimizedPointsList[index]);
+               }
+               /* when moving points are too many, and points are drawed completed, delete them */
+               for (; i >= 0; i--) {
+                       if (_pointsList[index].size() > (POINTS_ARRARY_ABANDON_NUM + MAX_OPTIMIZED_POINTS_COUNT) && _alphaList[index][i].index < POINTS_ARRARY_ABANDON_NUM && (!_alphaList[index][i].bDraw)) {
+                               int nRemoveIndex = _alphaList[index][i].index;
+                               WERROR("remove drawed index %d %d", index, nRemoveIndex);
+                               //WERROR("next first draw value %d",_pointsList[index][nRemoveIndex+1]);
+                               std::vector<CPoint>::iterator iter = _pointsList[index].begin();
+                               _pointsList[index].erase(iter, iter + nRemoveIndex + 1);
+                               std::deque<drawlinesInfo>::iterator iter0 = _alphaList[index].begin();
+                               _alphaList[index].erase(iter0, iter0 + i + 1);
+                               iter0 = _alphaList[index].begin();
+                               for (; iter0 != _alphaList[index].end(); iter0++) {
+                                       (*iter0).index -= nRemoveIndex;
+                               }
+
+                               std::vector<int>::iterator iter1 = _strokeList[index].begin();
+                               _strokeList[index].erase(iter1, iter1 + nRemoveIndex + 1);
+                       }
+               }
+       }
+#else
+       /* when moving points are too many, and points are drawed completed, delete them */
+       if (_pointsList[index].size() > (POINTS_ARRARY_ABANDON_NUM+MAX_OPTIMIZED_POINTS_COUNT) && _nDrawedIndex > POINTS_ARRARY_ABANDON_NUM ) {
+               int nRemoveIndex = POINTS_ARRARY_ABANDON_NUM;
+               WERROR("remove drawed index %d (%d,%d)", nRemoveIndex, _pointsList[index][nRemoveIndex].x, _pointsList[index][nRemoveIndex].y);
+               //WERROR("next first draw value %d",_pointsList[index][nRemoveIndex+1]);
+               std::vector<CPoint>::iterator iter = _pointsList[index].begin();
+               _pointsList[index].erase(iter, iter + nRemoveIndex + 1);
+       }
+#endif
+
+       int nCount = _pointsList[index].size();
+       _optimizedPointsList[index].resize(((nCount +DRAWING_REFER_POINTS_NUM)));
+       int j = 0;
+       for (int i = 0; i < nCount; i++)
+       {
+               if ( i == 0) {
+                               int k = _originalPointsList[index].size() - _pointsList[index].size() -2;
+                               std::pair<double, double>& point = _optimizedPointsList[index][j];
+                               point.first = 0;
+                               point.second = 0;
+                               if ( k >= 0 ) {
+                                       point.first = _originalPointsList[index][k].x;
+                                       point.second = _originalPointsList[index][k].y;
+                                       WINFO("%.1f %.1f", point.first, point.second);
+                               }
+                               j++;
+                               k = _originalPointsList[index].size() - _pointsList[index].size() -1;
+                               std::pair<double, double>& point2 = _optimizedPointsList[index][j];
+                               point2.first = 0;
+                               point2.second = 0;
+                               if ( k >= 0 ) {
+                                       point2.first = _originalPointsList[index][k].x;
+                                       point2.second = _originalPointsList[index][k].y;
+                                       WINFO("%.1f %.1f", point2.first, point2.second);
+                               }
+                               j++;
+                               //WERROR(" use preve pt  j=%d  add two points",j);
+               }
+
+               //
+               std::pair<double, double>& point3 = _optimizedPointsList[index][j];
+               point3.first =  _pointsList[index][i].x;
+               point3.second = _pointsList[index][i].y;
+               j++;
+       }
+#ifndef SKETCH_DRAW_ENABLE_DRAWING_EFFECT
+       _nDrawedIndex = nCount-1-2;
+#endif
+       return &(_optimizedPointsList[index]);
+}
+
+
+
+std::vector<std::pair<double, double> >* CLasso::GetOptimizedPointsList(int nListIndex)
+{
+       return &_optimizedPointsList[nListIndex];
+}
+
+bool CLasso::updateAlphaList()
+{
+       //WINFO("updateAlphaList");
+       /* update alpha */
+       int lastIndex = -1;
+       bool bChanged = false;
+       for(int k = 0;k< MAX_POINTS_LIST_COUNT;k++) {
+               if (0 < _alphaList[k].size()) {
+                       int i = _alphaList[k].size()-1;
+                       if (k == 0) {
+                               lastIndex = _alphaList[k][i].index;
+                       }
+                       for(; i >= 0; i--) {
+                               /*
+                               change 4 times
+                               */
+                               _alphaList[k][i].alpha -= 0.2;
+                               if (_alphaList[k][i].alpha < -0.15) {
+                                       _alphaList[k][i].bDraw = false;
+                               } else {
+                                       bChanged = true;
+                               }
+                               if (_alphaList[k][i].alpha < 0) {
+                                       _alphaList[k][i].alpha = 0;
+                               }
+                       }
+               }
+       }
+       if (lastIndex < (GetCount()-1)) {
+//             WINFO("updateAlphaList add");
+               bChanged = true;
+               drawlinesInfo info;
+               info.alpha = 0.5;
+               info.index = GetCount()-1;
+               _alphaList[0].push_back(info);
+       }
+       return bChanged;
+}
+
+int  CLasso::getAlphaListIndex(int nListIndex, int nDrawIndex, drawlinesInfo& lineInfo)
+{
+       if (0 == _alphaList[nListIndex].size()) {
+               if (nDrawIndex < _strokeList[nListIndex].size()) {
+                       lineInfo.strokeWidth =  _strokeList[nListIndex][nDrawIndex];
+               }
+               return -1;
+       }
+       if (nDrawIndex != 0 &&  nDrawIndex <= lineInfo.index) {
+               /* alpha is not changed */
+               //WINFO("alpha not changed");
+               if (nDrawIndex < _strokeList[nListIndex].size()) {
+                       lineInfo.strokeWidth =  _strokeList[nListIndex][nDrawIndex];
+               }
+               return 0;
+       }
+       for (int i = 0; i <_alphaList[nListIndex].size(); i++) {
+               if ( nDrawIndex <= _alphaList[nListIndex][i].index) {
+                       lineInfo.alpha = _alphaList[nListIndex][i].alpha;
+                       if (nDrawIndex < _strokeList[nListIndex].size()) {
+                               lineInfo.strokeWidth =  _strokeList[nListIndex][nDrawIndex];
+                       }
+                       lineInfo.index = _alphaList[nListIndex][i].index;
+                       return 0;
+               }
+       }
+       if (nDrawIndex < _strokeList[nListIndex].size()) {
+               lineInfo.strokeWidth =  _strokeList[nListIndex][nDrawIndex];
+       }
+       return -1;
+}
+
+int  CLasso::getStrokeWidth(int nListIndex, int nDrawIndex, drawlinesInfo& lineInfo)
+{
+       if (0 == _strokeList[nListIndex].size()) {
+               return -1;
+       }
+
+       if (nDrawIndex < _strokeList[nListIndex].size()) {
+               lineInfo.strokeWidth =  _strokeList[nListIndex][nDrawIndex];
+               return 0;
+       }
+       return -1;
+}
+
+CPoint &CLasso::operator[](int i)
+{
+       return _pointsList[0][i];
+}
+
+void  CLasso::restorePoints(std::vector<std::pair<double, double> > &pt)
+{
+       for(int i = MAX_POINTS_LIST_COUNT-1; i >=0;i--) {
+               _pointsList[i].clear();
+               _alphaList[i].clear();
+               _strokeList[i].clear();
+               _optimizedPointsList[i].clear();
+               _originalPointsList[i].clear();
+       }
+       _oldPointsList.clear();
+       _originalStrokeList.clear();
+}
+/* for undo redo points */
+std::vector<std::pair<double, double> > CLasso::GetOriginalPoints()
+{
+       std::vector<std::pair<double, double> > ret_points;
+       int count = _originalPointsList[0].size();
+       for (int i = 0; i < count; i++)
+       {
+               ret_points.push_back(std::make_pair(_originalPointsList[0][i].x, _originalPointsList[0][i].y));
+       }
+       return ret_points;
+}
+
+std::vector<int>* CLasso::GetOriginalstrokeList()
+{
+       return &_originalStrokeList;
+}
+
+std::vector<std::pair<double, double> > CLasso::GetHistoryPoints(std::vector<std::pair<double, double> > &pt)
+{
+       int nCount = pt.size();
+       std::vector<std::pair<double, double> > ret_points(pt.size()+DRAWING_REFER_POINTS_NUM);
+       int j = 0;
+       for (int i = 0; i < nCount; i++)
+       {
+               if ( i == 0) {
+                       std::pair<double, double>& point = ret_points[j];
+                       point.first = 0;
+                       point.second = 0;
+                       j++;
+                       std::pair<double, double>& point2 = ret_points[j];
+                       point2.first = 0;
+                       point2.second = 0;
+                       j++;
+               }
+               std::pair<double, double>& point3 = ret_points[j];
+               point3.first =  pt[i].first;
+               point3.second = pt[i].second;
+               j++;
+       }
+
+       return ret_points;
+}
+
+std::vector<std::pair<double, double> >* CLasso::getOldPointsList()
+{
+       return &_oldPointsList;
+}
+
+int CLasso::getOldStrokeWidth(int i, double& strokeWidth)
+{
+       if ( i < _oldStrokeList.size()) {
+               strokeWidth = _oldStrokeList[i];
+               return 0;
+       }
+       return -1;
+}
+
+bool CLasso::lineAlphaIsOpacity(int lineIndex)
+{
+       if (0 < _alphaList[lineIndex].size()) {
+               int i = _alphaList[lineIndex].size()-1;
+               if (!_alphaList[lineIndex][i].bDraw) {
+                       return false;
+               }
+               return true;
+       }
+       /*bug: when draw some points and do rotary quickly, these points maybe not be drawed
+       solution: only alphalist array and points list are all empty, and then no need to draw
+       */
+       if (_alphaList[lineIndex].size() == 0 && _pointsList[lineIndex].size() == 0) {
+               WINFO("no draw");
+               return false;
+       }
+       return true;
+}
+
+bool CLasso::isDrawStopped()
+{
+       return _bMouseUp;
+}
+
+bool CLasso::lastBufferIsCompleted()
+{
+       if (0 < _alphaList[2].size()) {
+               if (_alphaList[2][_alphaList[2].size()-1].bDraw) {
+                       WERROR("not done ,delete");
+                       return false;
+               }
+       }
+       return true;
+}
+
+
+
+
+
+
+
+CCairoImage::CCairoImage()
+ : _nWidth(0),
+   _nHeight(0),
+   _strokeWidth(MMS_MODE_STROKE_LINE_WIDTH),
+   _image(nullptr),
+   _imgBuf(nullptr),
+   _tempBuf(nullptr),
+   _surface(nullptr),
+   _cr(nullptr),
+   _evas(nullptr),
+   _BgImgFile(SKETCH_DRAWING_COLOR_BG_01),
+   _bStopNormalDrawing(false)
+{
+}
+
+void CCairoImage::clearImage()
+{
+       cairo_set_source_rgba(_cr, 0, 0, 0, 1);
+       cairo_set_operator(_cr, CAIRO_OPERATOR_SOURCE);
+       cairo_paint(_cr);
+       evas_object_image_data_update_add(_image, 0, 0, 360, 360);
+}
+
+
+void CCairoImage::clearMask()
+{
+       cairo_set_source_rgba(_maskCr, 0, 0, 0, 1);
+       cairo_set_operator(_maskCr, CAIRO_OPERATOR_SOURCE);
+       cairo_paint(_maskCr);
+}
+
+void CCairoImage::clearSource()
+{
+       cairo_set_source_rgba(_sourceCr, 0, 0, 0, 1);
+       cairo_set_operator(_sourceCr, CAIRO_OPERATOR_SOURCE);
+       cairo_paint(_sourceCr);
+}
+
+void CCairoImage::clearBuffer()
+{
+       cairo_set_source_rgba(_bufferCr, 0, 0, 0, 1);
+       cairo_set_operator(_bufferCr, CAIRO_OPERATOR_SOURCE);
+       cairo_paint(_bufferCr);
+}
+
+void CCairoImage::sourceUpdate(drawMode mode)
+{
+       WINFO("");
+       if (mode == REDO_DRAW) {
+               cairo_set_operator(_cr, CAIRO_OPERATOR_SOURCE);
+               cairo_set_source_surface(_cr, _maskSurface, 0, 0);
+               cairo_paint(_cr);
+               evas_object_image_data_update_add(_image, 0, 0, 360, 360);
+       }
+       if (mode == UNDO_DRAW) {
+               cairo_set_operator(_sourceCr, CAIRO_OPERATOR_SOURCE);
+               cairo_set_source_surface(_sourceCr, _maskSurface, 0, 0);
+               cairo_paint(_sourceCr);
+               cairo_save(_sourceCr);
+       }
+}
+
+void CCairoImage::maskUpdate(drawMode mode)
+{
+       WINFO("");
+       if (mode == REDO_DRAW) {
+               cairo_set_operator(_maskCr, CAIRO_OPERATOR_SOURCE);
+               cairo_set_source_surface(_maskCr, _surface, 0, 0);
+               cairo_paint(_maskCr);
+       } else if (mode == UNDO_DRAW) {
+               cairo_set_operator(_maskCr, CAIRO_OPERATOR_SOURCE);
+               cairo_set_source_surface(_maskCr, _bufferSurface, 0, 0);
+               cairo_paint(_maskCr);
+       }
+}
+
+Eina_Bool CCairoImage::animationUpdateImage(void *data, double pos)
+{
+       struct animationData *pAnimationData = (animationData *)data;
+       if (pAnimationData->mode == UNDO_DRAW) {
+               evas_object_color_set(pAnimationData->bgPattern, 0, 0, 0, 255*pos);
+               if (pos == 1) {
+                       pAnimationData->isDrawing = false;
+               }
+       } else if (pAnimationData->mode == REDO_DRAW) {
+               evas_object_color_set(pAnimationData->bgPattern, 0, 0, 0, 255*pos);
+       }
+       pAnimationData->nBgPatternAlpha = 255*pos;
+       return EINA_TRUE;
+}
+
+void CCairoImage::reUpdateImage(cairo_t *cr, cairo_surface_t *maskSurface, cairo_surface_t *sourceSurface, Evas_Object *image)
+{
+       cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE);
+       cairo_set_source_surface(cr, sourceSurface, 0, 0);
+       cairo_paint(cr);
+       evas_object_image_data_update_add(image, 0, 0, 360, 360);
+}
+
+void CCairoImage::updateImage(cairo_t *cr, cairo_surface_t *maskSurface, cairo_surface_t *sourceSurface, Evas_Object *image)
+{
+//     WINFO("");
+       cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE);
+       cairo_set_source_surface(cr, sourceSurface, 0, 0);
+       cairo_mask_surface(cr, maskSurface, 0, 0);
+       cairo_fill(cr);
+       evas_object_image_data_update_add(image, 0, 0, 360, 360);
+}
+
+Evas_Object *CCairoImage::createMaskImage(Evas *evas, int width, int height)
+{
+       _maskImage = evas_object_image_filled_add(evas);
+       evas_object_image_colorspace_set(_maskImage, EVAS_COLORSPACE_ARGB8888);
+       evas_object_image_alpha_set(_maskImage, EINA_TRUE);
+       evas_object_image_size_set(_maskImage, width, height);
+       evas_object_repeat_events_set(_maskImage, EINA_TRUE);
+
+       unsigned char *imgBuf = (unsigned char*)evas_object_image_data_get(_maskImage, EINA_TRUE);
+
+       _maskSurface = cairo_image_surface_create_for_data(imgBuf,
+                               CAIRO_FORMAT_ARGB32, width, height,
+                               cairo_format_stride_for_width(CAIRO_FORMAT_ARGB32, width));
+       WINFO("transparentSurface created");
+       _maskCr = cairo_create(_maskSurface);
+
+       cairo_new_path(_maskCr);
+       cairo_set_source_rgba(_maskCr, 0, 0, 0, 1);
+       cairo_rectangle(_maskCr, 0, 0, width, height);
+       cairo_fill(_maskCr);
+
+       //cairo_set_operator(_maskCr, CAIRO_OPERATOR_SOURCE);
+       return _maskImage;
+}
+
+Evas_Object *CCairoImage::createSource(Evas *evas, int width, int height)
+{
+       _sourceImage = evas_object_image_filled_add(evas);
+       evas_object_image_colorspace_set(_sourceImage, EVAS_COLORSPACE_ARGB8888);
+       evas_object_image_alpha_set(_sourceImage, EINA_TRUE);
+       evas_object_image_size_set(_sourceImage, width, height);
+       evas_object_repeat_events_set(_sourceImage, EINA_TRUE);
+
+       unsigned char *imgBuf = (unsigned char*)evas_object_image_data_get(_sourceImage, EINA_TRUE);
+
+       _sourceSurface = cairo_image_surface_create_for_data(imgBuf,
+                               CAIRO_FORMAT_ARGB32, width, height,
+                               cairo_format_stride_for_width(CAIRO_FORMAT_ARGB32, width));
+       WINFO("transparentSurface created");
+       _sourceCr = cairo_create(_sourceSurface);
+
+       cairo_new_path(_sourceCr);
+       cairo_set_source_rgba(_sourceCr, 0, 0, 0, 1);
+       cairo_rectangle(_sourceCr, 0, 0, width, height);
+       cairo_fill(_sourceCr);
+       return _sourceImage;
+}
+void CCairoImage::createBufferImage(Evas *evas, int width, int height)
+{
+       _bufferImage = evas_object_image_filled_add(evas);
+       evas_object_image_colorspace_set(_bufferImage, EVAS_COLORSPACE_ARGB8888);
+       evas_object_image_alpha_set(_bufferImage, EINA_TRUE);
+       evas_object_image_size_set(_bufferImage, width, height);
+       evas_object_repeat_events_set(_bufferImage, EINA_TRUE);
+
+       unsigned char *imgBuf = (unsigned char*)evas_object_image_data_get(_bufferImage, EINA_TRUE);
+
+       _bufferSurface = cairo_image_surface_create_for_data(imgBuf,
+                               CAIRO_FORMAT_ARGB32, width, height,
+                               cairo_format_stride_for_width(CAIRO_FORMAT_ARGB32, width));
+       _bufferCr = cairo_create(_bufferSurface);
+
+       cairo_new_path(_bufferCr);
+       cairo_set_source_rgba(_bufferCr, 0, 0, 0, 1);
+       cairo_rectangle(_bufferCr, 0, 0, width, height);
+       cairo_fill(_bufferCr);
+       return;
+}
+
+Evas_Object *CCairoImage::CreateImage(Evas *evas, int width, int height)
+{
+       _image = evas_object_image_filled_add(evas);
+       evas_object_image_colorspace_set(_image, EVAS_COLORSPACE_ARGB8888);
+       evas_object_image_alpha_set(_image, EINA_TRUE);
+       evas_object_image_size_set(_image, width, height);
+       evas_object_repeat_events_set(_image, EINA_TRUE);
+
+       _imgBuf = (unsigned char*)evas_object_image_data_get(_image, EINA_TRUE);
+
+       _surface = cairo_image_surface_create_for_data(_imgBuf,
+                               CAIRO_FORMAT_ARGB32, width, height,
+                               cairo_format_stride_for_width(CAIRO_FORMAT_ARGB32, width));
+       WINFO("surface created");
+       _cr = cairo_create(_surface);
+
+       _tempBuf = (unsigned char *)calloc(1, width * height * 4);
+
+       _nWidth = width;
+       _nHeight = height;
+       _evas = evas;
+
+       cairo_set_source_rgba(_cr, 0, 0, 0, 1);
+       cairo_save(_cr);
+       setClip(0, 0, width, height);
+
+       return _image;
+}
+
+void CCairoImage::DeleteImage()
+{
+       if(_image) {
+               cairo_surface_destroy(_surface);
+               cairo_destroy(_cr);
+
+               evas_object_image_data_set(_image, _imgBuf);
+               _imgBuf = NULL;
+               evas_object_del(_image);
+               _image = NULL;
+               free(_tempBuf);
+       }
+
+       if(_maskImage) {
+               cairo_surface_destroy(_maskSurface);
+               cairo_destroy(_maskCr);
+
+               evas_object_del(_maskImage);
+               _maskImage = NULL;
+       }
+
+       if(_sourceImage) {
+               cairo_surface_destroy(_sourceSurface);
+               cairo_destroy(_sourceCr);
+
+               evas_object_del(_sourceImage);
+               _sourceImage = NULL;
+       }
+       if(_bufferImage) {
+               cairo_surface_destroy(_bufferSurface);
+               cairo_destroy(_bufferCr);
+
+               evas_object_del(_bufferImage);
+               _bufferImage = NULL;
+       }
+}
+
+void CCairoImage::MoveImage(int x, int y, int w, int h)
+{
+       evas_object_move(_image, x, y);
+       evas_object_resize(_image, w, h);
+       evas_object_show(_image);
+}
+
+void CCairoImage::saveImageBuffer(int w, int h)
+{
+       WINFO("saveImageBuffer");
+       _imgBuf = (unsigned char*)evas_object_image_data_get(_image, EINA_FALSE);
+       memcpy(_tempBuf, _imgBuf, w * h * 4);
+}
+
+void CCairoImage::setClip(int x, int y, int w, int h)
+{
+       cairo_new_path(_cr);
+       cairo_arc(_cr, x+w/2, y+h/2, w/2+2, 0, 2*M_PI);
+       cairo_clip(_cr);
+
+       cairo_new_path(_cr);
+       //cairo_set_source_rgb(_cr, 0, 1, 0);
+       cairo_rectangle(_cr, 0, 0, w, w);
+       cairo_fill(_cr);
+}
+#ifdef ENABLE_DRAGING
+void CCairoImage::dragImage(int dx, int dy)
+{
+       int x, y, w, h;
+       int fx, fy;
+
+       evas_object_geometry_get(_image, &x, &y, &w, &h);
+       int screen_x = 180;//screen center
+       int screen_y = 180;
+       int screen_radius = 220;//add 40 offset for convenient to drawing edge of screen.
+
+       int cycle_x = x + 360 + dx;
+       int cycle_y = y + 360 + dy;
+
+       double final_cycle_x;
+       double final_cycle_y;
+
+       double dis = sqrt((cycle_x - screen_x)*(cycle_x - screen_x) +
+               (cycle_y - screen_y) * (cycle_y - screen_y));
+
+       if (dis > screen_radius)
+       {
+               final_cycle_x = screen_radius / dis * (cycle_x - screen_x) + screen_x;
+               final_cycle_y = screen_radius / dis * (cycle_y - screen_y) + screen_y;
+
+               fx = (int)final_cycle_x - 360;
+               fy = (int)final_cycle_y - 360;
+       } else {
+               fx = dx + x;
+               fy = dy + y;
+       }
+
+       MoveImage(fx, fy, w, h);
+       return;
+}
+#endif
+
+void CCairoImage::Clear(DrawingColor* pColor)
+{
+       if(_cr) {
+               if (CDrAppData::getInstance()->getLaunchMode() == DRAWING_SEND) {
+                       cairo_restore(_cr);
+                       cairo_paint(_cr);
+                       evas_object_image_data_update_add(_image, 0, 0, _nWidth, _nHeight);
+                       cairo_save(_cr);
+               } else {
+                       cairo_set_operator(_cr, CAIRO_OPERATOR_CLEAR);
+                       cairo_paint(_cr);
+                       evas_object_image_data_update_add(_image, 0, 0, _nWidth, _nHeight);
+               }
+               SetDrawingProperty(pColor);//Revert back default
+       }
+};
+
+void CCairoImage::SetDrawingProperty(DrawingColor* pColor)
+{
+       double lineWidth = _strokeWidth;
+       LaunchMode launchMode = CDrAppData::getInstance()->getLaunchMode();
+
+       if ( pColor->is_eraser == true) {
+               cairo_set_operator(_cr, CAIRO_OPERATOR_CLEAR);
+               lineWidth = ERASER_LINE_WIDTH;
+       } else {
+               cairo_set_operator(_cr, CAIRO_OPERATOR_SOURCE);
+               cairo_set_source_rgba(_cr, pColor->r, pColor->g, pColor->b, pColor->a);
+       }
+
+       if (launchMode == DRAWING_SEND ) {
+               lineWidth = _strokeWidth = MMS_MODE_STROKE_LINE_WIDTH;
+       }
+
+#ifndef SKETCH_DRAW_COLORS_CHANGABLE
+       if (launchMode == DRAWING_SEND ) {
+               if ( pColor->is_eraser == true) {
+                       cairo_set_operator(_cr, CAIRO_OPERATOR_SOURCE);
+                       cairo_set_source_rgba(_cr, 0, 0, 0, 1);
+               } else {
+                       cairo_set_operator(_cr, CAIRO_OPERATOR_SOURCE);
+#ifdef SKETCH_DRAW_ENABLE_DRAWING_EFFECT
+                       cairo_set_source_rgba(_cr, 1, 1, 1, 1);
+#else
+                       cairo_set_source_rgba(_cr, 0, 0, 0, 0);
+#endif
+                       //WINFO("normal draw ,send mode");
+               }
+       }
+#endif
+
+       cairo_set_line_width(_cr, lineWidth);
+       cairo_set_line_cap(_cr, CAIRO_LINE_CAP_ROUND);
+       cairo_set_line_join(_cr, CAIRO_LINE_JOIN_ROUND);
+}
+
+void CCairoImage::SetHistoryDrawingProperty(cairo_t *cr, DrawingColor pColor, double strokeWidth)
+{
+       double lineWidth = strokeWidth;
+       LaunchMode launchMode = CDrAppData::getInstance()->getLaunchMode();
+       cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE);
+       cairo_set_source_rgba(cr, pColor.r, pColor.g, pColor.b, pColor.a);
+#ifndef SKETCH_DRAW_COLORS_CHANGABLE
+       if (launchMode == DRAWING_SEND ) {
+               if ( pColor.is_eraser == true) {
+                       cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE);
+                       cairo_set_source_rgba(cr, 0, 0, 0, 1);
+               } else {
+                       cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE);
+                       cairo_set_source_rgba(cr, 0, 0, 0, 0);
+               }
+       }
+#endif
+
+       cairo_set_line_width(cr, lineWidth);
+       cairo_set_line_cap(cr, CAIRO_LINE_CAP_ROUND);
+       cairo_set_line_join(cr, CAIRO_LINE_JOIN_ROUND);
+}
+
+void CCairoImage::setStrokeWidth(double dWidth)
+{
+       _strokeWidth = dWidth;
+}
+
+double CCairoImage::getStrokeWidth()
+{
+       return _strokeWidth;
+}
+
+void CCairoImage::setBgType(std::string& bgType)
+{
+       _BgImgFile = bgType;
+}
+
+void  CCairoImage::setStrokeAlpha(cairo_t* cr, drawlinesInfo& info)
+{
+       cairo_stroke(cr);
+       //cairo_stroke_preserve(_cr);
+       LaunchMode launchMode = CDrAppData::getInstance()->getLaunchMode();
+
+#ifndef SKETCH_DRAW_COLORS_CHANGABLE
+       if (launchMode == DRAWING_SEND ) {
+                       cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE);
+                       cairo_set_source_rgba(cr, 0.8, 0.8, 0.8, info.alpha);
+       }
+
+#endif
+
+       cairo_set_line_width(cr, info.strokeWidth);
+       cairo_set_line_cap(cr, CAIRO_LINE_CAP_ROUND);
+       cairo_set_line_join(cr, CAIRO_LINE_JOIN_ROUND);
+}
+
+void CCairoImage::eraseDraw(CLasso &lasso, double rw, double rh, int w, int h, int specIndex)
+{
+       WINFO("");
+       int nStartIndex = MAX_POINTS_LIST_COUNT-1;
+       int nEndIndex = 0;
+       if (specIndex != -1) {
+               nStartIndex = specIndex;
+               nEndIndex = nStartIndex;
+       }
+       for(int j =nStartIndex;j>= nEndIndex;j--) {
+               CPoint Min, Max;
+               Min.x = 2*w;
+               Min.y = 2*h;
+               Max.x = -w;
+               Max.y = -h;
+               if (!lasso.lineAlphaIsOpacity(j)) {
+                       continue;
+               }
+               /* must recreate optimized points, maybe previous optimized points are empty or not whole */
+               std::vector<std::pair<double, double>> *pt1 = lasso.GetInterpolatedPoints(j);
+               WINFO("index =%d use new opti,size %d", j, pt1->size());
+
+               std::vector<std::pair<double, double>>::const_iterator iter = pt1->begin();
+
+               if (pt1->size() == 0) {
+                       continue;
+               }
+               WINFO("erase draw");
+               _drawPoints(lasso, NORMAL_DRAW_ERASE_UNCOMPLETED_LINE, j, rw, rh, Min, Max);
+       }
+}
+
+
+void CCairoImage::_eraseOldLine(CLasso &lasso, double rw, double rh, int w, int h)
+{
+       if(_bStopNormalDrawing) {
+               return;
+       }
+       CPoint Min, Max;
+       Min.x = 2*w;
+       Min.y = 2*h;
+       Max.x = -w;
+       Max.y = -h;
+
+       //WINFO("_eraseOldLine ");
+       std::vector<std::pair<double, double>> *ptList = lasso.getOldPointsList();
+       std::vector<std::pair<double, double>>::const_iterator iter = ptList->begin();
+
+       if (ptList->size() == 0) {
+               return;
+       }
+       _drawPoints(lasso, NORMAL_DRAW_ERASE_OLD_LINE, 0, rw, rh, Min, Max);
+}
+
+void CCairoImage::_setStrokeProperty(CLasso &lasso, NormaldrawMode mode, int nLineIndex, int nPointIndex, drawlinesInfo& lineInfo)
+{
+       if (mode == NORMAL_DRAW_TOUCHING) {
+#ifdef SKETCH_DRAW_ENABLE_DRAWING_EFFECT
+#ifndef SKETCH_DRAW_COLORS_CHANGABLE
+               int ret = lasso.getAlphaListIndex(nLineIndex, nPointIndex, lineInfo);
+               if (ret == -1) {
+                       if (nLineIndex != 0) {
+                               lineInfo.alpha = 0;
+                       }
+               }
+               /* multi-draw same points, line will be thin, so use -1 to draw for normal drawing*/
+               if (lineInfo.alpha < 0) {
+                       lineInfo.alpha = 1;
+               }
+               if(lineInfo.alpha > 0.05)  {
+                       lineInfo.strokeWidth -= 2;
+               } else {
+                       lineInfo.strokeWidth -= 1;
+               }
+               if (ret == -1 || lineInfo.oldAlpha != lineInfo.alpha || (lineInfo.dOldStrokeWidth != lineInfo.strokeWidth)) {
+                       setStrokeAlpha(_cr, lineInfo);
+                       cairo_new_path(_cr);
+               }
+#endif
+#endif
+       } else if (mode == NORMAL_DRAW_ERASE_OLD_LINE) {
+               int ret = lasso.getOldStrokeWidth(nPointIndex, lineInfo.strokeWidth);
+               lineInfo.strokeWidth -= 1;
+               if (ret== -1 || lineInfo.dOldStrokeWidth != lineInfo.strokeWidth) {
+                       setStrokeAlpha(_cr, lineInfo);
+                       cairo_new_path(_cr);
+               }
+       } else if (mode == NORMAL_DRAW_ERASE_UNCOMPLETED_LINE) {
+#ifdef SKETCH_DRAW_ENABLE_DRAWING_EFFECT
+#ifndef SKETCH_DRAW_COLORS_CHANGABLE
+                       int ret = lasso.getStrokeWidth(nLineIndex, nPointIndex, lineInfo);
+                       lineInfo.strokeWidth -= 1;
+                       if (ret == -1 || (lineInfo.dOldStrokeWidth != lineInfo.strokeWidth)) {
+                               setStrokeAlpha(_cr, lineInfo);
+                               cairo_new_path(_cr);
+                       }
+#endif
+#endif
+       }
+}
+
+void CCairoImage::_drawPoints(CLasso &lasso, NormaldrawMode mode, int nLineIndex, double rw, double rh, CPoint& ptMin, CPoint& ptMax)
+{
+       std::vector<std::pair<double, double>> *ptList = nullptr;
+
+       if(mode == NORMAL_DRAW_ERASE_OLD_LINE) {
+               ptList = lasso.getOldPointsList();
+       } else if (mode == NORMAL_DRAW_TOUCHING) {
+               ptList = lasso.GetInterpolatedPoints(nLineIndex);
+               if (ptList->size() == 0) {
+                       return;
+               }
+#ifdef SKETCH_DRAW_ENABLE_DRAWING_EFFECT
+               if (nLineIndex == 0) {
+                       if (ptList->size() <= (DRAWING_REFER_POINTS_NUM + 1) && !lasso.isDrawStopped()) {
+                               WINFO("continue index %d", nLineIndex);
+                               return;
+                       }
+                       lasso.saveOldPointsList();
+               }
+#endif
+       } else {
+               ptList = lasso.GetOptimizedPointsList(nLineIndex);
+       }
+       std::vector<std::pair<double, double>>::const_iterator iter = ptList->begin();
+
+       int i = 0;
+       drawlinesInfo lineInfo;
+       lineInfo.index = 0;
+       lineInfo.alpha = -1;
+       lineInfo.strokeWidth = MMS_MODE_STROKE_LINE_WIDTH;
+       CPoint pt0, pt1, pt;
+       CPoint midPt0, prevPt1, midPt2;
+       if (mode == NORMAL_DRAW_ERASE_OLD_LINE) {
+               lineInfo.alpha = 0;
+               lineInfo.strokeWidth = 0;
+       } else if (mode == NORMAL_DRAW_ERASE_UNCOMPLETED_LINE) {
+               lineInfo.alpha = 0;
+               lineInfo.strokeWidth = MMS_MODE_STROKE_LINE_WIDTH - 1;
+       }
+
+       pt0.x = iter->first * rw;
+       pt0.y = iter->second * rh;
+       iter++;
+       pt1.x = (iter)->first * rw;
+       pt1.y = (iter)->second * rh;
+       iter++;
+
+       for (; iter != ptList->end(); iter++)
+       {
+               if(_bStopNormalDrawing && mode != NORMAL_DRAW_ERASE_UNCOMPLETED_LINE) {
+                       WLEAVE();
+                       return;
+               }
+
+               if (mode == NORMAL_DRAW_ERASE_OLD_LINE && i > POINTS_ARRARY_ABANDON_NUM * 2) {
+                       WLEAVE();
+                       break;
+               }
+               pt.x = (iter)->first * rw;
+               pt.y = (iter)->second * rh;
+               if(i == 0) {
+                       cairo_new_path(_cr);
+               }
+               _setStrokeProperty(lasso, mode, nLineIndex, i, lineInfo);
+               //WINFO("strokeWidth=%.1f",lineInfo.strokeWidth);
+
+               midPt0.x = (pt0.x + pt1.x) * 0.5;
+               midPt0.y = (pt0.y + pt1.y) * 0.5;
+               prevPt1 = pt1;
+               midPt2.x = (pt1.x + pt.x) * 0.5;
+               midPt2.y = (pt1.y + pt.y) * 0.5;
+
+               if (pt1.x == 0 && pt1.y == 0) {
+                       midPt0 = pt;
+                       prevPt1 = pt;
+                       midPt2 = pt;
+               } else if (pt0.x == 0 && pt0.y == 0){
+                       midPt0 = prevPt1;
+               }
+
+               cairo_move_to(_cr, midPt0.x, midPt0.y);
+               _pathDrawCurve(_cr, prevPt1.x, prevPt1.y, midPt2.x, midPt2.y);
+
+               ptMin.x =  MIN(ptMin.x, MIN(midPt0.x, MIN(prevPt1.x, MIN(pt.x, midPt2.x))));
+               ptMax.x =  MAX(ptMax.x, MAX(midPt0.x, MAX(prevPt1.x, MAX(pt.x, midPt2.x))));;
+               ptMin.y =  MIN(ptMin.y, MIN(midPt0.y, MIN(prevPt1.y, MIN(pt.y, midPt2.y))));
+               ptMax.y =  MAX(ptMax.y, MAX(midPt0.y, MAX(prevPt1.y, MAX(pt.y, midPt2.y))));
+
+               i++;
+               lineInfo.oldAlpha = lineInfo.alpha;
+               lineInfo.dOldStrokeWidth = lineInfo.strokeWidth;
+               pt0 = pt1;
+               pt1 = pt;
+       }
+       cairo_stroke(_cr);
+}
+
+void CCairoImage::_pathDrawCurve(cairo_t *_cairo, double x1, double y1, double x2, double y2)
+{
+       double x0, y0;
+       cairo_get_current_point(_cairo, &x0, &y0);
+       //WINFO("(%.1f %.1f) (%.1f %.1f) (%.1f %.1f)",x0, y0,x1,y1,x2,y2);
+       cairo_curve_to(_cairo,
+           2.0 / 3.0 * x1 + 1.0 / 3.0 * x0, 2.0 / 3.0 * y1 + 1.0 / 3.0 * y0,
+           2.0 / 3.0 * x1 + 1.0 / 3.0 * x2, 2.0 / 3.0 * y1 + 1.0 / 3.0 * y2,
+           x2, y2);
+}
+
+void CCairoImage::Draw(CLasso &lasso, double rw, double rh, int w, int h)
+{
+       if(_bStopNormalDrawing) {
+               return;
+       }
+       for(int j = MAX_POINTS_LIST_COUNT-1; j >= 0; j--) {
+               CPoint Min, Max;
+               Min.x = 2 * w;
+               Min.y = 2 * h;
+               Max.x = -w;
+               Max.y = -h;
+               if(_bStopNormalDrawing) {
+                       return;
+               }
+
+#ifdef SKETCH_DRAW_ENABLE_DRAWING_EFFECT
+               if (j == 0) {
+                       _eraseOldLine(lasso, rw, rh, w, h);
+               }
+#endif
+
+               _drawPoints(lasso, NORMAL_DRAW_TOUCHING, j, rw, rh, Min, Max);
+
+               Min.x -= _strokeWidth / 2;
+               if (Min.x < 0) {
+                       Min.x = 0;
+               }
+               Min.y -= _strokeWidth / 2;
+               if (Min.y < 0) {
+                       Min.y = 0;
+               }
+               Max.x += _strokeWidth / 2;
+               if ((Max.x - Min.x) > w ) {
+                       Max.x = w + Min.x;
+               }
+               Max.y += _strokeWidth / 2;
+               if ((Max.y - Min.y) > h) {
+                       Max.y = h + Min.y;
+               }
+               if ( Min.x < 0 || Min.y < 0 || Max.x < 0 || Max.y < 0 || (Max.x - Min.x) > w ||  (Max.y - Min.y) >h) {
+                       WERROR("overflow");
+                       evas_object_image_data_update_add(_image, 0, 0, 360, 360);
+               } else {
+                       evas_object_image_data_update_add(_image, Min.x, Min.y, Max.x - Min.x, Max.y - Min.y);
+                       //evas_object_image_data_update_add(_image, 0, 0, 360, 360);
+               }
+       }
+}
+
+
+/* undo /redo drawing */
+void CCairoImage::_animateDrawPoints(CPoint& ptMin, CPoint& ptMax, double pos, void* pData)
+{
+       struct animationData *pAnimationData = (animationData *)pData;
+       int count = (pAnimationData->pt).size();
+       int nStart, nEnd;
+       int i = 0;
+       double alpha = 0;
+       drawlinesInfo info;
+       info.alpha = 0;
+       info.strokeWidth = -1;
+       double dStrokeWidth = 0;
+       CPoint pt0, pt1, pt;
+       CPoint midPt0, prevPt1, midPt2;
+
+       if (pAnimationData->mode == UNDO_DRAW ) {
+               if (pAnimationData->isMaxAnimation) {
+                       nStart = (int)((count - 1) - (int)(DRAW_POINTS * pos));
+                       nEnd = DRAWING_REFER_POINTS_NUM;
+               } else {
+                       nStart = (int)((count - 1 - DRAWING_REFER_POINTS_NUM) * (1 - pos) + DRAWING_REFER_POINTS_NUM);
+                       nEnd = 1;
+               }
+
+               if (nStart -2 < 0 && nStart > nEnd) {
+                       WERROR(" start %d   count %d", nStart, count);
+               }
+               if (nStart < nEnd) {
+                       WERROR(" start %d       nEnd %d", nStart, nEnd);
+               }
+               if (nStart -2 >= 0) {
+                       pt0.x = pAnimationData->pt[nStart-2].first * pAnimationData->rw;
+                       pt0.y = pAnimationData->pt[nStart-2].second * pAnimationData->rh;
+               }
+               if (nStart -1 >= 0) {
+                       pt1.x = pAnimationData->pt[nStart-1].first * pAnimationData->rw;
+                       pt1.y = pAnimationData->pt[nStart-1].second * pAnimationData->rh;
+               }
+               alpha = pos;
+
+       } else if (pAnimationData->mode == REDO_DRAW) {
+               if (pAnimationData->isMaxAnimation) {
+                       nStart = DRAWING_REFER_POINTS_NUM;
+                       nEnd = (int)((pAnimationData->pt.size() - DRAW_POINTS) + (int)(DRAW_POINTS * pos));
+               } else {
+                       nStart = DRAWING_REFER_POINTS_NUM;
+                       nEnd = (int)((pAnimationData->pt.size() - DRAWING_REFER_POINTS_NUM) * pos + DRAWING_REFER_POINTS_NUM);
+               }
+               if (nStart > nEnd) {
+                       WERROR(" start %d       nEnd %d", nStart, nEnd);
+               }
+
+               pt0.x = pAnimationData->pt[0].first * pAnimationData->rw;
+               pt0.y = pAnimationData->pt[0].second * pAnimationData->rh;
+               pt1.x = pAnimationData->pt[1].first * pAnimationData->rw;
+               pt1.y = pAnimationData->pt[1].second * pAnimationData->rh;
+               alpha = 1 - pos;
+       }
+
+       /* draw points */
+       int ix = nStart;
+       while((pAnimationData->mode == UNDO_DRAW && ix > nEnd) || (pAnimationData->mode == REDO_DRAW && ix < nEnd))
+       {
+               pt.x = pAnimationData->pt[ix].first * pAnimationData->rw;
+               pt.y = pAnimationData->pt[ix].second * pAnimationData->rh;
+
+               /*      set stroke width */
+               if ((ix-DRAWING_REFER_POINTS_NUM) < pAnimationData->strokeList.size()) {
+                       dStrokeWidth = pAnimationData->strokeList[(ix-DRAWING_REFER_POINTS_NUM)];
+               } else {
+                       WERROR("not found  %d %d", ix, pAnimationData->strokeList.size());
+               }
+               if (dStrokeWidth != info.strokeWidth) {
+                       info.strokeWidth = dStrokeWidth;
+                       pAnimationData->pCairo->setStrokeAlpha(pAnimationData->sourceCr, info);
+                       cairo_set_source_rgba(pAnimationData->sourceCr, 0, 0, 0, alpha);
+                       cairo_new_path(pAnimationData->sourceCr);
+               }
+
+               midPt0.x = (pt0.x + pt1.x)* 0.5;
+               midPt0.y = (pt0.y + pt1.y)* 0.5;
+               prevPt1 = pt1;
+               midPt2.x = (pt1.x + pt.x) * 0.5;
+               midPt2.y = (pt1.y + pt.y) * 0.5;
+
+               if (pt1.x == 0 && pt1.y == 0) {
+                       midPt0 = pt;
+                       prevPt1 = pt;
+                       midPt2 = pt;
+                       //WINFO("draw point");
+               } else if (pt0.x == 0 && pt0.y == 0){
+                       midPt0 = prevPt1;
+                       //WINFO("draw line");
+               }
+
+               cairo_move_to(pAnimationData->sourceCr, midPt0.x, midPt0.y);
+               _pathDrawCurve(pAnimationData->sourceCr, prevPt1.x, prevPt1.y, midPt2.x, midPt2.y);
+
+               i++;
+               if (pAnimationData->mode == UNDO_DRAW) {
+                       pt1 = pt0;
+                       if (ix - 3 >= 0) {
+                               pt0.x = pAnimationData->pt[ix-3].first * pAnimationData->rw;
+                               pt0.y = pAnimationData->pt[ix-3].second * pAnimationData->rh;
+                       }
+                       ix--;
+               } else if (pAnimationData->mode == REDO_DRAW){
+                       ix++;
+                       pt0 = pt1;
+                       pt1 = pt;
+               }
+       }
+       cairo_stroke(_cr);
+}
+
+Eina_Bool CCairoImage::animationDraw(void *data, double pos)
+{
+       struct animationData *pAnimationData = (animationData *)data;
+       CPoint Min, Max;
+       Min.x = 2 * pAnimationData->w;
+       Min.y = 2 * pAnimationData->h;
+       Max.x = -pAnimationData->w;
+       Max.y = -pAnimationData->h;
+
+       if (pAnimationData->pt.size() == 0) {
+               return EINA_TRUE;
+       }
+
+       cairo_restore(pAnimationData->sourceCr);
+       cairo_paint(pAnimationData->sourceCr);
+       cairo_save(pAnimationData->sourceCr);
+
+       cairo_set_operator(pAnimationData->sourceCr, CAIRO_OPERATOR_SOURCE);
+       cairo_set_line_width(pAnimationData->sourceCr, pAnimationData->strokeWidth);
+       cairo_set_line_cap(pAnimationData->sourceCr, CAIRO_LINE_CAP_ROUND);
+       cairo_set_line_join(pAnimationData->sourceCr, CAIRO_LINE_JOIN_ROUND);
+
+
+       pAnimationData->pCairo->_animateDrawPoints(Min, Max, pos, data);
+       cairo_stroke(pAnimationData->sourceCr);
+
+       updateImage(pAnimationData->cr, pAnimationData->maskSurface, pAnimationData->sourceSurface, pAnimationData->image);
+       if (pos == 1.0) {
+        pAnimationData->isDrawing = false;
+               pAnimationData->drawingAnimator = nullptr;
+               if (pAnimationData->mode == REDO_DRAW) {
+                       //Prevent same path in source and mask composite inconsistent when redo.
+                       reUpdateImage(pAnimationData->cr, pAnimationData->maskSurface, pAnimationData->sourceSurface, pAnimationData->image);
+               }
+               return EINA_FALSE;
+    }
+       return EINA_TRUE;
+}
+void CCairoImage::Draw(cairo_t *cr, std::vector<std::pair<double, double>> &ptList, std::vector<int>& strokeList, double rw, double rh, int w, int h)
+{
+       WINFO("undo draw points");
+
+       std::vector<std::pair<double, double>>::const_iterator iter = ptList.begin();
+
+       cairo_set_source_rgba(cr, 0, 0, 0, 0);
+
+       drawlinesInfo info;
+       info.alpha = 0;
+       info.strokeWidth = -1;
+       double dStrokeWidth = 0;
+       int i = 0;
+       CPoint pt0, pt1, pt;
+       CPoint midPt0, prevPt1, midPt2;
+
+       pt0.x = iter->first *rw;
+       pt0.y = iter->second * rh;
+       iter++;
+       pt1.x = (iter)->first * rw;
+       pt1.y = (iter)->second * rh;
+       iter++;
+
+       for (iter; iter != ptList.end(); iter++)
+       {
+               pt.x = (iter)->first * rw;
+               pt.y = (iter)->second * rh;
+               if(i == 0) {
+                       cairo_new_path(cr);
+               }
+
+               if (i < strokeList.size()) {
+                       dStrokeWidth = strokeList[i];
+               } else {
+                       WERROR("not found");
+               }
+               if (dStrokeWidth != info.strokeWidth) {
+                       info.strokeWidth = dStrokeWidth;
+
+                       setStrokeAlpha(cr, info);
+                       cairo_new_path(cr);
+               }
+               //WINFO("strokeWidth=%.1f", info.strokeWidth);
+
+               midPt0.x = (pt0.x + pt1.x) * 0.5;
+               midPt0.y = (pt0.y + pt1.y) * 0.5;
+               prevPt1 = pt1;
+               midPt2.x = (pt1.x + pt.x) * 0.5;
+               midPt2.y = (pt1.y + pt.y) * 0.5;
+
+               if (pt1.x == 0 && pt1.y == 0) {
+                       midPt0 = pt;
+                       prevPt1 = pt;
+                       midPt2 = pt;
+               } else if (pt0.x == 0 && pt0.y == 0){
+                       midPt0 = prevPt1;
+               }
+
+               cairo_move_to(cr, midPt0.x, midPt0.y);
+               _pathDrawCurve(cr, prevPt1.x, prevPt1.y, midPt2.x, midPt2.y);
+
+               i++;
+               pt0 = pt1;
+               pt1 = pt;
+       }
+       cairo_stroke(cr);
+       ptList.clear();
+       strokeList.clear();
+}
+
+void CCairoImage::GetDimensions(int *width, int *height)
+{
+       *width = _nWidth;
+       *height = _nHeight;
+}
+
+void CCairoImage::SaveDrawingImage(std::string& filePath)
+{
+       if(_image)
+       {
+               WINFO("save smart object to file");
+               if ( CDrAppData::getInstance()->getLaunchMode() == DRAWING_SEND) {
+                       _createSaveCario(filePath);
+               } else {
+                       evas_object_image_save(_image, filePath.c_str(), NULL, NULL);
+               }
+       }
+}
+
+const char *quality_str = "quality=100 compress=9";
+
+void CCairoImage::_createSaveCario(std::string& filePath)
+{
+#ifndef SKETCH_DRAW_COLORS_CHANGABLE
+       char* resPath = app_get_resource_path();
+       std::string bgPath(resPath);
+       bgPath += _BgImgFile.c_str();
+       std::string patternBgPath(resPath);
+       patternBgPath += SKETCH_DRAWING_PATTERN_BG;
+       free(resPath);
+
+       Evas_Object *image;
+       image = evas_object_image_filled_add(_evas);
+       evas_object_image_colorspace_set(image, EVAS_COLORSPACE_ARGB8888);
+       evas_object_image_alpha_set(image, EINA_TRUE);
+       evas_object_image_size_set(image, _nWidth, _nHeight);
+       unsigned char* buf = (unsigned char*)evas_object_image_data_get(image, EINA_TRUE);
+       cairo_surface_t * surface = cairo_image_surface_create_for_data(buf,
+                               CAIRO_FORMAT_ARGB32, _nWidth, _nHeight,
+                               cairo_format_stride_for_width(CAIRO_FORMAT_ARGB32, _nWidth));
+
+       cairo_t* cr = cairo_create(surface);
+       cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE);
+       cairo_surface_t * surface2 = cairo_image_surface_create_from_png(bgPath.c_str());
+
+       cairo_new_path(cr);
+       cairo_arc(cr, 180, 180, 180, 0, 2 * M_PI);
+       cairo_clip(cr);
+       cairo_set_source_surface(cr, surface2, 0, 0);
+       cairo_paint(cr);
+       //cairo_fill(cr);
+       //cairo_set_source_rgba(cr, 0, 0, 0, 1);
+       //cairo_mask_surface(cr, surface2, 0, 0);
+       //cairo_fill(cr);
+
+       int code_r = 0, code_g = 0, code_b = 0, code_a = 255;
+       double r, g, b, a;
+       edje_color_class_get(PATTERN_BG_COLOR_CODE, &code_r, &code_g, &code_b, &code_a, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
+       r = code_r  /255.0;
+       g = code_g / 255.0;
+       b = code_b / 255.0;
+       a = code_a / 255.0;
+       cairo_surface_t * surface3 = cairo_image_surface_create_from_png(patternBgPath.c_str());
+       cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE);
+       cairo_set_source_rgba(cr, r, g, b, a);
+       cairo_mask_surface(cr, surface3, 0, 0);
+       cairo_fill(cr);
+
+       cairo_reset_clip(cr);
+       cairo_set_operator(cr, CAIRO_OPERATOR_ATOP);
+       cairo_set_source_surface(cr, _surface, 0, 0);
+       cairo_paint(cr);
+
+       evas_object_image_save(image, filePath.c_str(), NULL, quality_str);
+
+       WINFO("destroy");
+       cairo_surface_destroy(surface);
+       cairo_surface_destroy(surface2);
+       cairo_surface_destroy(surface3);
+       cairo_destroy(cr);
+       evas_object_del(image);
+#else
+       char* resPath = app_get_resource_path();
+       std::string bgPath(resPath);
+       bgPath += DRAWING_DRAWING_PATTERN_BG;
+       free(resPath);
+
+       cairo_surface_t * surface2 = cairo_image_surface_create_from_png(bgPath.c_str());
+
+       cairo_set_operator(_cr, CAIRO_OPERATOR_ATOP);
+       cairo_set_source_surface(_cr, surface2, 0, 0);
+       cairo_paint(_cr);
+       WINFO("surface paint");
+
+       evas_object_image_save(_image, filePath.c_str(), NULL, quality_str);
+
+       WINFO("destroy");
+       cairo_surface_destroy(surface2);
+#endif
+
+       WLEAVE();
+}
+
+void CCairoImage::setStopNormalDrawing(bool bDoding)
+{
+       _bStopNormalDrawing = bDoding;
+}
+
+bool CCairoImage::getNormalDrawingStatus()
+{
+       return _bStopNormalDrawing;
+}
diff --git a/src/controls/CDrCairoImage.h b/src/controls/CDrCairoImage.h
new file mode 100755 (executable)
index 0000000..cb81a04
--- /dev/null
@@ -0,0 +1,278 @@
+#ifndef __CDRCAIRO_IMAGE_H__
+#define __CDRCAIRO_IMAGE_H__
+
+
+#include <math.h>
+#include <vector>
+#include <deque>
+#include <utility>
+#include <cairo.h>
+#include <Evas.h>
+#include <string>
+#include <functional>
+//#include <Ecore_X.h>
+#include <efl_extension.h>
+#include <pthread.h>
+#include "DrDefine.h"
+
+
+
+#ifndef REDO_UNDO
+#define REDO_UNDO
+#endif
+
+#ifndef ENABLE_DRAGING
+//#define ENABLE_DRAGING
+#endif
+#ifndef ENABLE_ZOOM
+//#define ENABLE_ZOOM
+#endif
+
+
+#define   MAX_POINTS_LIST_COUNT  3
+
+typedef struct _LinesInfo{
+       bool bDraw;
+       int index;
+       double strokeWidth;
+       double alpha;
+       double oldAlpha;
+       double dOldStrokeWidth;
+       _LinesInfo() {
+               bDraw = true;
+               alpha = 0.5;
+               index = 0;
+               strokeWidth = MMS_MODE_STROKE_LINE_WIDTH;
+               oldAlpha = -1;
+               dOldStrokeWidth = 0;
+       }
+}drawlinesInfo;
+
+struct rect {
+               int x;
+               int y;
+               int w;
+               int h;
+} ;
+typedef struct rect Rect;
+typedef enum {
+       NORMAL_DRAW = 0,
+       UNDO_DRAW,
+       REDO_DRAW
+} drawMode;
+
+typedef enum {
+       NORMAL_DRAW_TOUCHING = 0,
+       NORMAL_DRAW_ERASE_OLD_LINE,
+       NORMAL_DRAW_ERASE_UNCOMPLETED_LINE
+} NormaldrawMode;
+
+
+class DrawingColor
+{
+public:
+       DrawingColor() {
+               r = 0.;
+               g = 0.;
+               b = 0.;
+               a = 0.;
+               is_eraser = false;
+       }
+
+       void drawingColorSet(std::string colorCode, bool isEraser);
+
+       double r;
+       double g;
+       double b;
+       double a;
+       bool is_eraser;
+};
+
+class CPoint
+{
+public:
+       CPoint(int _x = 0, int _y = 0) : x(_x), y(_y) {};
+public:
+       int x;
+       int y;
+       CPoint &operator =(const CPoint &rhs) {
+               if (this == &rhs) {
+                       return *this;
+               }
+
+               x = rhs.x;
+               y = rhs.y;
+               return *this;
+       };
+};
+
+class CLasso
+{
+public:
+       CLasso();
+       ~CLasso();
+       void AddPoint(const CPoint &pt, int strokeWidth = MMS_MODE_STROKE_LINE_WIDTH);
+       void addEndPoint();
+       int GetCount();
+       bool IsEmpty();
+       void Clear();
+       int getListCount();
+       std::vector<std::pair<double, double> >* GetInterpolatedPoints(int index);
+       CPoint &operator[](int i);
+       void increaseListIndex();
+       bool updateAlphaList();
+       int  getAlphaListIndex(int nListIndex, int nDrawIndex, drawlinesInfo& lineInfo);
+       int  getStrokeWidth(int nListIndex, int nDrawIndex, drawlinesInfo& lineInfo);
+       std::vector<std::pair<double, double> > GetHistoryPoints(std::vector<std::pair<double, double> > &pt);
+       std::vector<std::pair<double, double> > GetOriginalPoints();
+       void  restorePoints(std::vector<std::pair<double, double> > &pt);
+       std::vector<std::pair<double, double> >* getOldPointsList();
+       std::vector<int>* GetOriginalstrokeList();
+       std::vector<std::pair<double, double> >* GetOptimizedPointsList(int nListIndex);
+       int getOldStrokeWidth(int i, double& strokeWidth);
+       void saveOldPointsList();
+       int getLastStrokeWidth();
+       bool lineAlphaIsOpacity(int lineIndex);
+       bool isDrawStopped();
+       bool lastBufferIsCompleted();
+private:
+       CLasso(const CLasso&) = delete;
+       const CLasso& operator = (const CLasso&) = delete;
+private:
+       int  _nDrawedIndex;  // draw completed index
+       bool _bMouseUp;
+       std::vector<CPoint> _pointsList[MAX_POINTS_LIST_COUNT]; // latest moving points, is part of _originalPointsList
+       std::vector<CPoint> _originalPointsList[MAX_POINTS_LIST_COUNT];  // current moving points
+       std::vector<std::pair<double, double> > _oldPointsList; // last drawed optimized points
+       std::vector<std::pair<double, double> > _optimizedPointsList[MAX_POINTS_LIST_COUNT]; // current optimized points
+       std::deque<drawlinesInfo>  _alphaList[MAX_POINTS_LIST_COUNT];
+       std::vector<int> _strokeList[MAX_POINTS_LIST_COUNT];
+       std::vector<int> _oldStrokeList;
+       std::vector<int> _originalStrokeList;  // current moving points stroke width
+};
+
+class CCairoImage
+{
+public:
+       CCairoImage();
+       Evas_Object *CreateImage(Evas *evas, int width, int height);
+       Evas_Object *createMaskImage(Evas *evas, int width, int height);
+       Evas_Object *createSource(Evas *evas, int width, int height);
+       void createBufferImage(Evas *evas, int width, int height);
+       void sourceUpdate(drawMode mode);
+       void maskUpdate(drawMode mode);
+       void DeleteImage();
+       void MoveImage(int x, int y, int w, int h);
+       void saveImageBuffer(int w, int h);
+       void Clear(DrawingColor* pColor);
+       void SetDrawingProperty(DrawingColor* pColor);
+       /* normal drawing + effect: stroke alpha and strke width changes */
+       void Draw(CLasso &lasso, double rw, double rh, int w, int h);
+       /* animation draw when undoing or redoing */
+       static Eina_Bool animationDraw(void *data, double pos);
+       static Eina_Bool animationUpdateImage(void *data, double pos);
+       void GetDimensions(int *width, int *height);
+       void SaveDrawingImage(std::string& fileName);
+       void setClip(int x, int y, int w, int h);
+       void setProperty(int i, int j);
+       void clearSource();
+       void clearBuffer();
+       void clearMask();
+       void clearImage();
+       /* erase uncompleted white lines when do undo or redo */
+       void eraseDraw(CLasso &lasso, double rw, double rh, int w, int h, int specIndex = -1);
+#ifdef ENABLE_DRAGING
+       void dragImage(int dx, int dy);
+#endif
+
+       void setStrokeWidth(double dWidth);
+       double getStrokeWidth();
+       void setBgType(std::string& bgType);
+       void SetHistoryDrawingProperty(cairo_t *cr, DrawingColor pColor, double strokeWidth);
+       /* normal drawing when undoing or redoing */
+       void Draw(cairo_t *cr, std::vector<std::pair<double, double>> &pt1, std::vector<int>& strokeList, double rw, double rh, int w, int h);
+       void setStopNormalDrawing(bool bDoding);
+       bool getNormalDrawingStatus();
+       static void updateImage(cairo_t *cr, cairo_surface_t *maskSurface, cairo_surface_t *sourceSurface, Evas_Object *image);
+       static void reUpdateImage(cairo_t *cr, cairo_surface_t *maskSurface, cairo_surface_t *sourceSurface, Evas_Object *image);
+
+       Evas_Object *_image;
+       Evas_Object *_maskImage;
+       Evas_Object *_sourceImage;
+       Evas_Object *_bufferImage;
+       double _strokeWidth;
+       cairo_t *_cr;
+       cairo_t *_maskCr;
+       cairo_t *_sourceCr;
+       cairo_t *_bufferCr;
+       cairo_surface_t *_maskSurface;
+       cairo_surface_t *_sourceSurface;
+       cairo_surface_t *_bufferSurface;
+private:
+       void _createSaveCario(std::string& filePath);
+       void  setStrokeAlpha(cairo_t* cr, drawlinesInfo& info);
+       void _eraseOldLine(CLasso &lasso, double rw, double rh, int w, int h);
+       void _drawPoints(CLasso &lasso, NormaldrawMode mode, int nLineIndex, double rw, double rh, CPoint& ptMin, CPoint& ptMax);
+       void _setStrokeProperty(CLasso &lasso, NormaldrawMode mode, int nLineIndex, int nPointIndex, drawlinesInfo& lineInfo);
+       void _pathDrawCurve(cairo_t *_cairo, double x1, double y1, double x2, double y2);
+       void _animateDrawPoints(CPoint& ptMin, CPoint& ptMax, double pos, void* pData);
+
+private:
+       int _nWidth;
+       int _nHeight;
+       bool  _bStopNormalDrawing;
+
+       unsigned char *_imgBuf;
+       unsigned char *_tempBuf;
+       cairo_surface_t *_surface;
+       Evas * _evas;
+       std::string  _BgImgFile;
+       std::vector<std::string> _palletColorCode;
+};
+
+
+
+struct animationUpdateData {
+       Ecore_Animator *updateAnimator;
+       cairo_t *cr;
+       cairo_t *sourceCr;
+       cairo_surface_t *sourceSurface;
+       Evas_Object *image;
+       Evas_Object *bgPattern;
+       drawMode mode;
+       bool isDrawing;
+};
+
+struct animationData {
+    //CLasso lasso;
+       std::vector<std::pair<double, double>> pt;
+       std::vector<int> strokeList;
+       double rw;
+       double rh;
+       double imgUpdatePos;
+       int w;
+       int h;
+       int imgUpdateCount;
+       int nBgPatternAlpha;
+       bool isImgAnimateDraw;
+       drawMode mode;
+       cairo_t *cr;
+       cairo_t *sourceCr;
+       Evas_Object *image;
+       double strokeWidth;
+       DrawingColor pColor;
+       bool isDrawing;
+       bool isMaxAnimation;
+       Ecore_Animator *drawingAnimator;
+       double animationTime;
+       cairo_surface_t *maskSurface;
+       cairo_surface_t *sourceSurface;
+       Evas_Object *bgPattern;
+       CCairoImage* pCairo;
+};
+
+
+
+#endif // __CDRCAIRO_IMAGE_H__
+
+
diff --git a/src/controls/CDrControl.h b/src/controls/CDrControl.h
new file mode 100755 (executable)
index 0000000..a9bbc84
--- /dev/null
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0
+ *
+ * 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 _CVE_CONTROLER_H_
+#define _CVE_CONTROLER_H_
+
+#include <Evas.h>
+#include <Elementary.h>
+#include <functional>
+#include "WViewController.h"
+#include "CDrEventListener.h"
+#include "CDrEvent.h"
+#include "WDefine.h"
+
+
+using namespace app_assist;
+
+
+class CDrControl:public WViewController, public CDrEventListener {
+ public:
+
+       CDrControl() {};
+
+ public:
+       virtual void onEvent(const CDrEvent & event) {};
+
+ protected:
+       virtual ~CDrControl() {};
+
+ private:
+       WDISABLE_COPY_AND_ASSIGN(CDrControl);
+};
+
+#endif                                                 // _CVE_CONTROLER_H_
diff --git a/src/controls/CDrControlManager.cpp b/src/controls/CDrControlManager.cpp
new file mode 100755 (executable)
index 0000000..e056a6f
--- /dev/null
@@ -0,0 +1,145 @@
+#include "CDrControlManager.h"
+#include "DrDebug.h"
+#include <algorithm>
+
+CDrControlManager::CDrControlManager()
+{
+}
+
+CDrControlManager::~CDrControlManager()
+{
+       WDEBUG("size :%d", _mControlsMonitor.size());
+       if (!_mControlsMonitor.empty()) {
+               for_each(_mControlsMonitor.begin(), _mControlsMonitor.end(), [](ControlObjPair controlObj) {
+                                if (controlObj.second) {
+                                    if (auto p = controlObj.second->lock()) {
+                                        p->destroy();
+                                        }
+                                    delete controlObj.second; WDEBUG("Destroy a control");
+                                }
+                                }) ;
+       }
+}
+
+ControlPWPtr CDrControlManager::find(const char *position)
+{
+       auto iter = _mControlsMonitor.find(position);
+       if (iter == _mControlsMonitor.end()) {
+               WERROR("Failed to get control");
+               return nullptr;
+       }
+
+       return (*iter).second;
+}
+
+bool CDrControlManager::isDetached(const char *position)
+{
+       auto iter = _mControlsMonitor.find(position);
+       if (iter == _mControlsMonitor.end()) {
+               return true;
+       } else {
+               return false;
+       }
+}
+
+// create new object and swallow it to layout
+// use this method to set an evasObject to layout
+void CDrControlManager::attach(Evas_Object * parent, CDrControl * control, const char *position, bool isSwallow2Parent, bool bdetach)
+{
+       WENTER();
+
+       // layout of view
+       if (parent == NULL) {
+               WERROR("Parent is NULL! Fail to attach control");
+               return;
+       }
+       // delete old object first
+       if (bdetach) {
+               detach(parent, position);
+       }
+       // Base layout should be parent.
+
+       control->create(parent, NULL);
+       if (isSwallow2Parent) {
+               Evas_Object *controlEvasObj = control->getEvasObj();
+               elm_object_part_content_set(parent, position, controlEvasObj);
+               WINFO("set part %s--", position);
+       }
+       std::string keyString(position);
+       auto iterCur = _mControlsMonitor.find(keyString);
+       std::pair < ControlObjMap::iterator, bool > ret;
+       if (iterCur == _mControlsMonitor.end()) {
+               ret = _mControlsMonitor.insert(std::make_pair(keyString, new WViewControllerWeakPtr));
+               if (ret.second == false) {
+                       WERROR("Failed to insert control to map");
+                       return;
+               } else {
+                       iterCur = ret.first;
+               }
+               WDEBUG("Insert a control");
+       } else {
+               destroy((*iterCur).second);
+       }
+       *((*iterCur).second) = control->getWeakPtr();
+
+       WLEAVE();
+}
+
+// detach swallow content from parent and then destory Control object
+// use this method to unset an evasObject from layout
+void CDrControlManager::detach(Evas_Object * parent, const char *position, bool isSwallow2Parent)
+{
+       //WENTER();
+
+       // layout of view
+       if (parent == NULL) {
+               WERROR("Parent is NULL! Fail to attach control");
+               return;
+       }
+       if (isSwallow2Parent) {
+               Evas_Object *evasObj = elm_object_part_content_unset(parent, position);
+               if (evasObj) {
+                       WDEBUG("Evas Object unset");
+               }
+       }
+
+       std::string keyString(position);
+       auto iterCur = _mControlsMonitor.find(keyString);
+       if (iterCur != _mControlsMonitor.end()) {
+               destroy((*iterCur).second);
+       }
+
+       //WLEAVE();
+}
+
+// destroy control object
+void CDrControlManager::destroy(ControlPWPtr controlMonitor)
+{
+       if (controlMonitor == NULL) {
+               return;
+       }
+
+       if (auto p = controlMonitor->lock()) {
+               p->destroy();
+               controlMonitor->reset();
+       }
+       WDEBUG("Destroy a control");
+}
+
+//refine me with manager
+void CDrControlManager::forEach(std::function < void(ControlPWPtr) > fn)
+{
+       for_each(_mControlsMonitor.begin(), _mControlsMonitor.end(), [&](ControlObjPair controlObj) {
+                        fn(controlObj.second);
+                        });
+}
+
+void CDrControlManager::notify(const CDrEvent & event)
+{
+       for_each(_mControlsMonitor.begin(), _mControlsMonitor.end(), [&](ControlObjPair controlObj) {
+                        CDrControl * control = getControlObject < CDrControl * >(controlObj.second);
+                        if (control) {
+                            control->onEvent(event);
+                        }
+                        }) ;
+}
diff --git a/src/controls/CDrControlManager.h b/src/controls/CDrControlManager.h
new file mode 100755 (executable)
index 0000000..e51fe51
--- /dev/null
@@ -0,0 +1,63 @@
+#ifndef _CDR_CONTROL_MANAGER_H_
+#define _CDR_CONTROL_MANAGER_H_
+
+#include <map>
+#include <string>
+#include "WWindowController.h"
+#include <Evas.h>
+#include <Elementary.h>
+#include <functional>
+#include "CDrControl.h"
+#include "CDrEventListener.h"
+#include "CDrEvent.h"
+#include "WDefine.h"
+#include "DrDebug.h"
+
+
+using namespace app_assist;
+
+typedef WViewControllerWeakPtr *ControlPWPtr;
+typedef std::pair < std::string, ControlPWPtr > ControlObjPair;
+typedef std::map < std::string, ControlPWPtr > ControlObjMap;
+
+template < typename TYPE > TYPE getControlObject(ControlPWPtr monitorObj)
+{
+       if (monitorObj == nullptr || monitorObj->expired()) {
+               //WERROR("Control pointer is expired");
+               return nullptr;
+       }
+
+       Evas_Object *evasObj = NULL;
+       if (auto p = monitorObj->lock()) {
+               evasObj = p->getEvasObj();
+       }
+       if (!evasObj) {
+               //WERROR("Invalid evas object");
+               return nullptr;
+       }
+
+       return dynamic_cast < TYPE > (wviewcontroller_get_instance_from_evasobj(evasObj));
+}
+
+/**
+ * Used to manager Controls derived from CCsControl
+ *
+ */
+class CDrControlManager {
+ public:
+       CDrControlManager();
+       ~CDrControlManager();
+
+       ControlPWPtr find(const char *position);
+       bool isDetached(const char *position);
+       void attach(Evas_Object * parent, CDrControl * control, const char *position, bool isSwallow2Parent = true, bool bdetach = true);
+       void detach(Evas_Object * parent, const char *position, bool isSwallow2Parent = true);
+       void destroy(ControlPWPtr controlMonitor);
+       void forEach(std::function < void(ControlPWPtr) > fn);
+       void notify(const CDrEvent & event);
+
+ private:
+       ControlObjMap _mControlsMonitor;
+};
+
+#endif                                                 // _CVE_CONTROL_MANAGER_H_
diff --git a/src/controls/CDrDrawingView.cpp b/src/controls/CDrDrawingView.cpp
new file mode 100755 (executable)
index 0000000..ebb8a13
--- /dev/null
@@ -0,0 +1,852 @@
+#include <math.h>
+#include <sys/time.h>
+#include <string>
+#include <sstream>
+#include <iostream>
+#include <fstream>
+#include <CDrUtil.h>
+#include <cstdio>
+#include <algorithm>
+#include <system_settings.h>
+#include <media_content.h>
+#include <efl_extension.h>
+#include "CDrAppData.h"
+#include "CDrDrawingView.h"
+#include "DrDefine.h"
+#include "CDrEventManager.h"
+
+CDrDrawingView::CDrDrawingView()
+: _drawingLayout(nullptr),
+  _edjeObj(nullptr),
+  _DrawingSaveTimer(nullptr),
+  _botmBgImg(nullptr),
+  _pDrawing(nullptr),
+#ifdef REDO_UNDO
+  _history(nullptr),
+#endif
+  _pHistoryCtrl(nullptr),
+  _NeedSaveDrawing(false),
+  _bCreateSaveTimer(false),
+  _bEraser(false),
+  _bColorMenuShowed(false),
+  _previousIndex(-1),
+  _colorIndex(0),
+  _showSaveButtonCb(nullptr),
+  _drawedCb(nullptr),
+  _showTimer(nullptr),
+  _showStatus(NONE_SHOW)
+{
+       _botmBgImgType = 0;
+       _colorCode = "";
+       _oldColorCode = "";
+       CDrEventManager::getInstance().attach(this);
+
+       _bgFileList.push_back(SKETCH_DRAWING_COLOR_BG_01);
+       _bgFileList.push_back(SKETCH_DRAWING_COLOR_BG_02);
+       _bgFileList.push_back(SKETCH_DRAWING_COLOR_BG_03);
+       _bgFileList.push_back(SKETCH_DRAWING_COLOR_BG_04);
+       _pDrawing = new Drawing();
+#ifdef REDO_UNDO
+       _history = new History();
+#endif
+}
+
+CDrDrawingView::~CDrDrawingView()
+{
+       WENTER();
+       CDrEventManager::getInstance().detach(this);
+       _bgFileList.clear();
+       if (_pDrawing) {
+               delete _pDrawing;
+       }
+#ifdef REDO_UNDO
+       if (_history) {
+               delete _history;
+       }
+#endif
+       if (_drawingLayout)
+       {
+               evas_object_del(_drawingLayout);
+               _drawingLayout = nullptr;
+       }
+}
+
+#ifdef REDO_UNDO
+Eina_Bool CDrDrawingView::_showIndicator(void *data)
+{
+       CDrDrawingView *pThis = (CDrDrawingView*)data;
+       if(pThis->_showStatus == UNDO_SHOW) {
+               if (pThis->_pDrawing->checkFirstIndexCb) {
+                       if (pThis->_pDrawing->checkFirstIndexCb() && !pThis->_pDrawing->isDrawingStatus()) {
+                               if (pThis->_showGuideCb)
+                               pThis->_showGuideCb();
+                       }
+               }
+               pThis->_showStatus = NONE_SHOW;
+       }
+       pThis->_pDrawing->setStopNormalDrawing(false);
+       pThis->deleteSaveTimer();
+       pThis->addSaveTimer();
+       pThis->setSaveStatus(true);
+
+       return ECORE_CALLBACK_CANCEL;
+}
+
+void CDrDrawingView::_isOnRedoing(void *data, Eext_Rotary_Event_Info *ev) {
+       std::vector<std::pair<double, double>> pt;
+       std::vector<int> strokeList;
+       DrawingColor pColor;
+       double strokeWidth;
+       int undoStart, undoEnd;
+       int redoStart, redoEnd;
+       CDrDrawingView *pThis = (CDrDrawingView*)data;
+       double time;
+       if (ev->direction == EEXT_ROTARY_DIRECTION_CLOCKWISE) {//redo
+               WINFO("CLOCKWISE, redo");
+               if (!pThis->_history->checkLastIndex()) {
+                       pThis->_showStatus = REDO_SHOW;
+                       if (pThis->_pDrawing->pAnimationData->drawingAnimator) {
+                               ecore_animator_del(pThis->_pDrawing->pAnimationData->drawingAnimator);
+                               pThis->_pDrawing->pAnimationData->drawingAnimator = nullptr;
+                       }
+                       pThis->_pDrawing->resetIsDrawing();
+                       if(pThis->_pHistoryCtrl) {
+                               pThis->_pHistoryCtrl->redoItem();
+                       }
+
+                       pThis->_pDrawing->setStopNormalDrawing(true);
+                       pThis->_pDrawing->restorePoints(pt);
+                       pThis->_pDrawing->clearSource();
+                       pThis->_pDrawing->sourceUpdate(REDO_DRAW);
+                       int index = (pThis->_history->getCurIndex())%MAX_HISTORY;
+                       pt.clear();
+                       pThis->_history->_getOutputBuffer(index, pt, strokeList, &pColor, &strokeWidth);
+                       if (!pt.empty()) {
+                               pThis->_pDrawing->updateBuffer(pt, strokeList, pColor, strokeWidth, NORMAL_DRAW);
+                       }
+                       pThis->_pDrawing->sourceUpdate(REDO_DRAW);
+                       pt.clear();
+                       if (pThis->_history->redo(pt, strokeList, &pColor, &strokeWidth)) {
+                               pThis->_pDrawing->updateBuffer(pt, strokeList, pColor, strokeWidth, REDO_DRAW);
+                               if (pThis->_unReDoCb) {
+                                       pThis->_unReDoCb(false);
+                               }
+                       }
+               }
+
+               if (pThis->_pDrawing->checkFirstIndexCb) {
+                       if (!pThis->_pDrawing->checkFirstIndexCb()) {
+                               if (pThis->_hideGuideCb)
+                                       pThis->_hideGuideCb();
+                       }
+               }
+               pThis->_pDrawing->getAnimatorTime(&time);
+               pThis->deleteShowTimer();
+               pThis->addShowTimer(time);
+       } else {
+               WINFO("COUNTER_CLOCKWISE, undo");//undo
+               pThis->_showStatus = UNDO_SHOW;
+
+               if (pThis->_pDrawing->pAnimationData->drawingAnimator) {
+                       ecore_animator_del(pThis->_pDrawing->pAnimationData->drawingAnimator);
+                       pThis->_pDrawing->pAnimationData->drawingAnimator = nullptr;
+               }
+               pThis->_pDrawing->animationUpdateImage(NORMAL_DRAW, nullptr);
+
+               pThis->_pDrawing->resetIsDrawing();
+               if(pThis->_pHistoryCtrl) {
+                       pThis->_pHistoryCtrl->undoItem();
+               }
+
+               pThis->_pDrawing->setStopNormalDrawing(true);
+               pThis->_pDrawing->restorePoints(pt);
+               if (!pThis->_history->undo(&undoStart, &undoEnd) && pThis->_history->getMaxHistory()) {
+                       Evas_Object* bgPattern = pThis->getBgPattern();
+                       pThis->_pDrawing->animationUpdateImage(UNDO_DRAW, bgPattern);
+               } else {
+                       pThis->_pDrawing->clearSource();
+                       pThis->_pDrawing->sourceUpdate(REDO_DRAW);
+               }
+               if (pThis->_unReDoCb) {
+                       pThis->_unReDoCb(true);
+               }
+               pThis->_pDrawing->getAnimatorTime(&time);
+               pThis->deleteShowTimer();
+               pThis->addShowTimer(time);
+       }
+       return;
+}
+
+void CDrDrawingView::_isOnUndoing(void *data, Eext_Rotary_Event_Info *ev) {
+       CDrDrawingView *pThis = (CDrDrawingView*)data;
+       int redoStart, redoEnd;
+       int undoStart, undoEnd;
+       DrawingColor pColor;
+       double strokeWidth;
+       double time;
+       std::vector<std::pair<double, double>> pt;
+       std::vector<int> strokeList;
+       if (ev->direction == EEXT_ROTARY_DIRECTION_CLOCKWISE) {//redo
+               WINFO("CLOCKWISE, redo");
+               pThis->_showStatus = REDO_SHOW;
+               if (pThis->_pDrawing->pAnimationData->drawingAnimator) {
+                       ecore_animator_del(pThis->_pDrawing->pAnimationData->drawingAnimator);
+                       pThis->_pDrawing->pAnimationData->drawingAnimator = nullptr;
+               }
+               pThis->_pDrawing->animationUpdateImage(NORMAL_DRAW, nullptr);
+
+               if (pThis->_pHistoryCtrl) {
+                       pThis->_pHistoryCtrl->redoItem();
+               }
+               pThis->_pDrawing->resetIsDrawing();
+               if (pThis->_pDrawing->checkFirstIndexCb) {
+                       pThis->_pDrawing->setStopNormalDrawing(true);
+                       pThis->_pDrawing->restorePoints(pt);
+                       if (pThis->_history->getMaxHistory() && pThis->_pDrawing->checkFirstIndexCb()) {
+                               Evas_Object* bgPattern = pThis->getBgPattern();
+                               pThis->_pDrawing->animationUpdateImage(REDO_DRAW, bgPattern);
+                               if (pThis->_history->redo(pt, strokeList, &pColor, &strokeWidth)) {
+                                       pThis->_pDrawing->updateBuffer(pt, strokeList, pColor, strokeWidth, REDO_DRAW);
+                                       if (pThis->_unReDoCb) {
+                                               pThis->_unReDoCb(false);
+                                       }
+                               }
+                       } else {
+                               pThis->_pDrawing->clearSource();
+                               pThis->_pDrawing->sourceUpdate(REDO_DRAW);
+                               if (pThis->_history->redo(pt, strokeList, &pColor, &strokeWidth)) {
+                                       pThis->_pDrawing->updateBuffer(pt, strokeList, pColor, strokeWidth, REDO_DRAW);
+                                       if (pThis->_unReDoCb) {
+                                               pThis->_unReDoCb(false);
+                                       }
+                               }
+                       }
+               }
+
+               if (pThis->_pDrawing->checkFirstIndexCb) {
+                       if (!pThis->_pDrawing->checkFirstIndexCb()) {
+                               if (pThis->_hideGuideCb)
+                                       pThis->_hideGuideCb();
+                       }
+               }
+               pThis->_pDrawing->getAnimatorTime(&time);
+               pThis->deleteShowTimer();
+               pThis->addShowTimer(time);
+       } else {
+               WINFO("COUNTER_CLOCKWISE, undo");//undo
+
+               if (pThis->_pDrawing->checkFirstIndexCb && !pThis->_pDrawing->checkFirstIndexCb()) {
+                       pThis->_showStatus = UNDO_SHOW;
+                       if (pThis->_pDrawing->pAnimationData->drawingAnimator) {
+                               WINFO("del timeline anim");
+                               ecore_animator_del(pThis->_pDrawing->pAnimationData->drawingAnimator);
+                               pThis->_pDrawing->pAnimationData->drawingAnimator = nullptr;
+                       }
+                       pThis->_pDrawing->animationUpdateImage(NORMAL_DRAW, nullptr);
+                       pThis->_pDrawing->resetIsDrawing();
+                       if (pThis->_pHistoryCtrl) {
+                               pThis->_pHistoryCtrl->undoItem();
+                       }
+
+            pThis->_pDrawing->setStopNormalDrawing(true);
+            pThis->_pDrawing->restorePoints(pt);
+                       pThis->_pDrawing->clearSource();
+                       pThis->_pDrawing->sourceUpdate(REDO_DRAW);
+
+                       if (pThis->_history->getMaxHistory()) {
+                               pThis->_pDrawing->clearSource();
+                               pThis->_pDrawing->clearMask();
+                               pThis->_pDrawing->maskUpdate(UNDO_DRAW);
+                               if (pThis->_history->undo(&undoStart, &undoEnd)) {
+                                       for (int cnt = undoStart; cnt % MAX_HISTORY != undoEnd % MAX_HISTORY; cnt++) {
+                                               pt.clear();
+                                               pThis->_history->_getOutputBuffer(cnt % MAX_HISTORY, pt, strokeList, &pColor, &strokeWidth);
+                                               if (!pt.empty()) {
+                                                       pThis->_pDrawing->updateBuffer(pt, strokeList, pColor, strokeWidth, NORMAL_DRAW);
+                                               }
+                                       }
+                                       pThis->_pDrawing->sourceUpdate(UNDO_DRAW);
+                                       pt.clear();
+                                       pThis->_history->_getOutputBuffer(undoEnd % MAX_HISTORY, pt, strokeList, &pColor, &strokeWidth);
+                                       if (!pt.empty()) {
+                                               WINFO("undo draw");
+                                               pThis->_pDrawing->updateBuffer(pt, strokeList, pColor, strokeWidth, UNDO_DRAW);
+                                       }
+                               } else {
+                                       Evas_Object* bgPattern = pThis->getBgPattern();
+                                       WINFO("undo draw bg");
+                                       pThis->_pDrawing->animationUpdateImage(UNDO_DRAW, bgPattern);
+                               }
+                       } else {
+                               pThis->_pDrawing->clearSource();
+                               pThis->_pDrawing->clearMask();
+                               if (pThis->_history->undo(&undoStart, &undoEnd)) {
+                                       for (int cnt = undoStart; cnt % MAX_HISTORY != undoEnd % MAX_HISTORY; cnt++) {
+                                               pt.clear();
+                                               pThis->_history->_getOutputBuffer(cnt % MAX_HISTORY, pt, strokeList, &pColor, &strokeWidth);
+                                               if (!pt.empty()) {
+                                                       pThis->_pDrawing->updateBuffer(pt, strokeList, pColor, strokeWidth, NORMAL_DRAW);
+                                               }
+                                       }
+                                       pThis->_pDrawing->sourceUpdate(UNDO_DRAW);
+                                       pt.clear();
+                                       pThis->_history->_getOutputBuffer(undoEnd % MAX_HISTORY, pt, strokeList, &pColor, &strokeWidth);
+                                       if (!pt.empty()) {
+                                               pThis->_pDrawing->updateBuffer(pt, strokeList, pColor, strokeWidth, UNDO_DRAW);
+                                       }
+                               } else {
+                                       WINFO("no did undo");
+                                       pThis->_pDrawing->sourceUpdate(REDO_DRAW);
+                               }
+                       }
+
+                       if (pThis->_unReDoCb) {
+                               pThis->_unReDoCb(true);
+                       }
+               }
+               pThis->_pDrawing->getAnimatorTime(&time);
+               pThis->deleteShowTimer();
+               pThis->addShowTimer(time);
+       }
+       return;
+}
+
+showStatus CDrDrawingView::getDrawStatus()
+{
+       return _showStatus;
+}
+
+Eina_Bool CDrDrawingView::_onRotaryHandler(void *data,  Evas_Object *obj, Eext_Rotary_Event_Info *ev)
+{
+       int cnt = 0;
+       double strokeWidth;
+       int undoStart = 0;
+       int undoEnd = 0;
+       int redoStart = 0;
+       int redoEnd = 0;
+       std::vector<std::pair<double, double>> pt;
+       std::vector<int> strokeList;
+       DrawingColor pColor;
+       double time;
+       CDrDrawingView *pThis = (CDrDrawingView*)data;
+
+       if(pThis->_bColorMenuShowed == true) {
+               WINFO("color menu show, return");
+               return EINA_TRUE;
+       }
+       if (pThis->_pDrawing->isMouseMoving()) {
+               WERROR("isMouseMoving, return");
+               return EINA_FALSE;
+       }
+       pThis->deleteSaveTimer();
+       if (pThis->_pDrawing->getDrawingStatus())
+       {
+               if (pThis->getDrawStatus() == REDO_SHOW) {//redo
+                       _isOnRedoing(data, ev);
+               } else if (pThis->getDrawStatus() == UNDO_SHOW){
+                       _isOnUndoing(data, ev);
+               }
+               return EINA_FALSE;
+       }
+
+       if (pThis->_showHistoryIndexCb) {
+               pThis->_showHistoryIndexCb(true);
+       }
+
+       if (ev->direction == EEXT_ROTARY_DIRECTION_CLOCKWISE) {
+               WINFO("CLOCKWISE");
+               pThis->_pDrawing->animationUpdateImage(NORMAL_DRAW, nullptr);
+               pThis->_showStatus = REDO_SHOW;
+               if(pThis->_pHistoryCtrl) {
+                       pThis->_pHistoryCtrl->redoItem();
+               }
+
+               if (pThis->_pDrawing->checkFirstIndexCb) {
+                       pThis->_pDrawing->setStopNormalDrawing(true);
+                       pThis->_pDrawing->restorePoints(pt);
+
+                       if (pThis->_pDrawing->getPatternBgAlpha() != 0) {
+                               WINFO("bg alpha > 0");
+                               Evas_Object* bgPattern = pThis->getBgPattern();
+                               pThis->_pDrawing->animationUpdateImage(REDO_DRAW, bgPattern);
+                       }
+
+                       if (pThis->_history->getMaxHistory() && pThis->_pDrawing->checkFirstIndexCb()) {
+                               pThis->_pDrawing->clearSource();
+                               pThis->_pDrawing->clearMask();
+                               pThis->_pDrawing->maskUpdate(UNDO_DRAW);
+                               pThis->_pDrawing->sourceUpdate(REDO_DRAW);
+                               if (pThis->_history->redo(pt, strokeList, &pColor, &strokeWidth)) {
+                                       pThis->_pDrawing->updateBuffer(pt, strokeList, pColor, strokeWidth, REDO_DRAW);
+                                       if (pThis->_unReDoCb) {
+                                               pThis->_unReDoCb(false);
+                                       }
+                               }
+                       } else {
+                               pThis->_pDrawing->clearSource();
+                               pThis->_pDrawing->clearMask();
+                               pThis->_pDrawing->maskUpdate(REDO_DRAW);
+                               pThis->_pDrawing->sourceUpdate(REDO_DRAW);
+                               if (pThis->_history->redo(pt, strokeList, &pColor, &strokeWidth)) {
+                                       pThis->_pDrawing->updateBuffer(pt, strokeList, pColor, strokeWidth, REDO_DRAW);
+                                       if (pThis->_unReDoCb) {
+                                               pThis->_unReDoCb(false);
+                                       }
+                               }
+                       }
+               }
+
+               if (pThis->_pDrawing->checkFirstIndexCb) {
+                       if (!pThis->_pDrawing->checkFirstIndexCb()) {
+                               if (pThis->_hideGuideCb)
+                                       pThis->_hideGuideCb();
+                       }
+               }
+               pThis->_pDrawing->getAnimatorTime(&time);
+               pThis->deleteShowTimer();
+               pThis->addShowTimer(time);
+       } else {
+               WINFO("COUNTER_CLOCKWISE");//undo
+               if (pThis->_pDrawing->checkFirstIndexCb && !pThis->_pDrawing->checkFirstIndexCb()) {
+                       pThis->_pDrawing->animationUpdateImage(NORMAL_DRAW, nullptr);
+                       pThis->_showStatus = UNDO_SHOW;
+                       if(pThis->_pHistoryCtrl) {
+                               pThis->_pHistoryCtrl->undoItem();
+                       }
+                       pThis->_pDrawing->setStopNormalDrawing(true);
+                       pThis->_pDrawing->restorePoints(pt);
+                       if (pThis->_history->getMaxHistory()) {
+                               pThis->_pDrawing->clearSource();
+                               pThis->_pDrawing->clearMask();
+                               pThis->_pDrawing->maskUpdate(UNDO_DRAW);
+                               if (pThis->_history->undo(&undoStart, &undoEnd)) {
+                                       for (cnt = undoStart; cnt % MAX_HISTORY != undoEnd % MAX_HISTORY; cnt++) {
+                                               pt.clear();
+                                               pThis->_history->_getOutputBuffer(cnt % MAX_HISTORY, pt, strokeList, &pColor, &strokeWidth);
+                                               if (!pt.empty()) {
+                                                       pThis->_pDrawing->updateBuffer(pt, strokeList, pColor, strokeWidth, NORMAL_DRAW);
+                                               }
+                                       }
+                                       pThis->_pDrawing->sourceUpdate(UNDO_DRAW);
+                                       pt.clear();
+                                       pThis->_history->_getOutputBuffer(undoEnd % MAX_HISTORY, pt, strokeList, &pColor, &strokeWidth);
+                                       if (!pt.empty()) {
+                                       pThis->_pDrawing->updateBuffer(pt, strokeList, pColor, strokeWidth, UNDO_DRAW);
+                                       }
+                               } else {
+                                       WINFO("> max undo to first,change bg");
+                                       Evas_Object* bgPattern = pThis->getBgPattern();
+                                       pThis->_pDrawing->animationUpdateImage(UNDO_DRAW, bgPattern);
+                               }
+                       } else {
+                               pThis->_pDrawing->clearSource();
+                               pThis->_pDrawing->clearMask();
+                               if (pThis->_history->undo(&undoStart, &undoEnd)) {
+                                       for (cnt = undoStart; cnt % MAX_HISTORY != undoEnd % MAX_HISTORY; cnt++) {
+                                               pt.clear();
+                                               pThis->_history->_getOutputBuffer(cnt % MAX_HISTORY, pt, strokeList, &pColor, &strokeWidth);
+                                               if (!pt.empty()) {
+                                                       pThis->_pDrawing->updateBuffer(pt, strokeList, pColor, strokeWidth, NORMAL_DRAW);
+                                               }
+                                       }
+                                       pThis->_pDrawing->sourceUpdate(UNDO_DRAW);
+                                       pt.clear();
+                                       pThis->_history->_getOutputBuffer(undoEnd % MAX_HISTORY, pt, strokeList, &pColor, &strokeWidth);
+                                       if (!pt.empty()) {
+                                               pThis->_pDrawing->updateBuffer(pt, strokeList, pColor, strokeWidth, UNDO_DRAW);
+                                       }
+                               } else {
+                                       WINFO("< max, no did undo");
+                                       pThis->_pDrawing->sourceUpdate(UNDO_DRAW);
+                                       pt.clear();
+                                       pThis->_history->_getOutputBuffer(undoEnd % MAX_HISTORY, pt, strokeList, &pColor, &strokeWidth);
+                                       if (!pt.empty()) {
+                                               pThis->_pDrawing->updateBuffer(pt, strokeList, pColor, strokeWidth, UNDO_DRAW);
+                                       }
+                               }
+                       }
+                       if (pThis->_unReDoCb) {
+                               pThis->_unReDoCb(true);
+                       }
+               }
+
+               pThis->_pDrawing->getAnimatorTime(&time);
+               pThis->deleteShowTimer();
+               pThis->addShowTimer(time);
+       }
+       return EINA_FALSE;
+}
+#endif
+
+Evas_Object * CDrDrawingView::onCreateView(Evas_Object * parent, void *viewParam)
+{
+       WENTER();
+
+       if (!_drawingLayout) {
+               WINFO("create drawing layout");
+               _drawingLayout = elm_layout_add(parent);
+               WASSERT(_drawingLayout);
+
+               char* _path = app_get_resource_path();
+               std::string path(_path);
+               path += "/edje/drawing_layout.edj";
+
+               elm_layout_file_set(_drawingLayout, path.c_str(), DRAWING_LAYOUT_GROUP_NAME);
+               evas_object_size_hint_weight_set(_drawingLayout, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+               evas_object_size_hint_align_set(_drawingLayout, EVAS_HINT_FILL, EVAS_HINT_FILL);
+               evas_object_resize(_drawingLayout, 360, 360);
+               //elm_object_part_content_set(parent, "pre-view", _drawingLayout);
+               evas_object_show(_drawingLayout);
+
+               _edjeObj = (Evas_Object *)elm_layout_edje_get(_drawingLayout);
+               free(_path);
+       }
+       if (CDrAppData::getInstance()->getLaunchMode() == DRAWING_SAVE) {
+               elm_object_signal_emit(_drawingLayout, "pattern,negative,bg,hide", "*");
+       }
+#ifndef SKETCH_DRAW_COLORS_CHANGABLE
+       if (CDrAppData::getInstance()->getLaunchMode() == DRAWING_SEND) {
+               elm_object_signal_emit(_drawingLayout, "pattern,negative,bg,hide", "*");
+               /* create bottom bg image */
+               char* resPath = app_get_resource_path();
+               std::string bgPath(resPath);
+               free(resPath);
+
+               _botmBgImg = elm_image_add(_drawingLayout);
+               _botmBgImgType = CDrAppData::getInstance()->getBgIndex();
+               WINFO("BG %s", _bgFileList[_botmBgImgType].c_str());
+               bgPath +=_bgFileList[_botmBgImgType];
+               elm_image_file_set(_botmBgImg, bgPath.c_str(), NULL);
+               elm_image_no_scale_set(_botmBgImg, EINA_FALSE);
+               elm_object_part_content_set(_drawingLayout, "elm.swallow.bottom.bgimage", _botmBgImg);
+               evas_object_show(_botmBgImg);
+       }
+#endif
+
+#ifdef REDO_UNDO
+       _pDrawing->setSaveBufferCb([&](std::vector<std::pair<double, double>> pt1, std::vector<int>* pStrokeList, DrawingColor* pColor, double strokeWidth, bool increaseIndex){
+               _history->saveBuffer(pt1, pStrokeList, pColor, strokeWidth, increaseIndex);
+               int nCurIndex = _history->getCurIndex();
+               if(_pHistoryCtrl) {
+                       if (increaseIndex) {
+                               _pHistoryCtrl->addItem(_history->getCount());
+                       } else {
+                               _pHistoryCtrl->deleteItem(_history->getCount());
+                       }
+                       WINFO("CNT:%d", _history->getCount());
+               }
+       });
+
+       _pDrawing->setCheckFirstIndexCb([&](void)->bool {
+               return _history->checkFirstIndex();
+       });
+       _pDrawing->setGetBufferCb([&](int curIndex, std::vector<std::pair<double, double>> &buffer, std::vector<int>& strokeList, DrawingColor* pColor, double *width) {
+               _history->_getOutputBuffer(curIndex, buffer, strokeList, pColor, width);
+       });
+#endif
+
+       Evas_Object*  select = _pDrawing->drawingAdd(_drawingLayout);
+       Evas_Object* bg_image = (Evas_Object *)edje_object_part_object_get(_edjeObj, "bg");
+
+#ifdef REDO_UNDO
+//     eext_rotary_event_handler_add(_onRotaryHandler, this);
+#endif
+
+       _pDrawing->drawingAttach(bg_image);
+       _pDrawing->drawingColorSet(_colorCode, _bEraser);
+       elm_object_part_content_set(_drawingLayout, "drawing_area", select);
+
+       evas_object_show(select);
+
+       _pDrawing->setBgType(_bgFileList[_botmBgImgType]);
+
+       _pDrawing->setDeleteSaveTimerCb([&](void){
+               deleteSaveTimer();
+               if (_drawedCb) {
+                       _drawedCb();
+               }
+               deleteHistoryIndexTimer();
+       });
+       _pDrawing->setColorMenuStateCb([&](void)->bool {
+               return _bColorMenuShowed;
+       });
+       _pDrawing->setSaveStateCb([&](bool bState) {
+               setSaveStatus(bState);
+       });
+       _pDrawing->setAddSaveTimerCb([&](void){
+               addSaveTimer();
+       });
+       _history->setClearCb([&](void){
+               _pDrawing->clearImage();
+       });
+
+       _history->setUpdateBufferImageCb([&](int index){
+               _pDrawing->updateBufferImage(index);
+       });
+       _pDrawing->setSetMaxHistoryCb([&](bool status) {
+               _history->setMaxHistory(status);
+       });
+       addSaveTimer();
+       WLEAVE();
+       return _drawingLayout;
+}
+
+void CDrDrawingView::onCreated()
+{
+}
+
+void CDrDrawingView::onDestroy()
+{
+       WENTER();
+       deleteShowTimer();
+       deleteSaveTimer();
+#ifdef REDO_UNDO
+       eext_rotary_object_event_callback_del(_drawingLayout, _onRotaryHandler);
+#endif
+       WLEAVE();
+}
+
+void CDrDrawingView::onEvent(const CDrEvent & event)
+{
+#ifdef REDO_UNDO
+       if (event.mType == CDrEvent::APP_PAUSED) {
+               eext_rotary_object_event_callback_del(_drawingLayout, _onRotaryHandler);
+       } else if (event.mType == CDrEvent::APP_RESUMED) {
+               eext_rotary_object_event_callback_add(_drawingLayout, _onRotaryHandler, this);
+               eext_rotary_object_event_activated_set(_drawingLayout, EINA_TRUE);
+       }
+#endif
+}
+
+void CDrDrawingView::setColorCode(std::string& strColor)
+{
+       _oldColorCode = _colorCode;
+
+       _colorCode = strColor;
+       if (_colorCode ==  "") {
+               _bEraser = true;
+       } else {
+               _bEraser = false;
+       }
+       _pDrawing->drawingColorSet(_colorCode, _bEraser);
+}
+
+
+void CDrDrawingView::deleteSaveTimer()
+{
+       if(_DrawingSaveTimer) {
+               ecore_timer_del(_DrawingSaveTimer);
+               _DrawingSaveTimer = nullptr;
+       }
+       if (_showSaveButtonCb) {
+               _showSaveButtonCb(false);
+       }
+}
+
+void CDrDrawingView::addSaveTimer()
+{
+       WINFO("addSaveTimer");
+
+       if (!_DrawingSaveTimer) {
+               _DrawingSaveTimer = ecore_timer_add(1.0,
+                                                   CDrDrawingView::_onSaveDrawingImage,
+                                                   this);
+       } else {
+               ecore_timer_reset(_DrawingSaveTimer);
+       }
+}
+
+void CDrDrawingView::deleteShowTimer()
+{
+       if(_showTimer) {
+               ecore_timer_del(_showTimer);
+               _showTimer = nullptr;
+       }
+}
+
+void CDrDrawingView::addShowTimer(double time)
+{
+       if (!_showTimer) {
+               _showTimer = ecore_timer_add(time,
+                                                   CDrDrawingView::_showIndicator,
+                                                   this);
+       } else {
+               ecore_timer_reset(_showTimer);
+       }
+}
+
+void CDrDrawingView::deleteHistoryIndexTimer()
+{
+       if ( _showHistoryIndexCb) {
+               _showHistoryIndexCb(false);
+       }
+}
+
+void CDrDrawingView::setSaveStatus(bool need)
+{
+       _NeedSaveDrawing = need;
+}
+
+Eina_Bool CDrDrawingView::_onSaveDrawingImage(void *data)
+{
+       CDrDrawingView *pThis = (CDrDrawingView*)data;
+       //pThis->deleteSaveTimer();
+
+       if(pThis->_NeedSaveDrawing == true)
+       {
+               WINFO("need_save_drawing");
+               pThis->_NeedSaveDrawing = false;
+
+               if (pThis->_showSaveButtonCb) {
+                       pThis->_showSaveButtonCb(true);
+               }
+               if (pThis->_showHistoryIndexCb) {
+                       pThis->_showHistoryIndexCb(true);
+               }
+       }
+       if (pThis->_pDrawing->checkFirstIndexCb) {
+               if (pThis->_pDrawing->checkFirstIndexCb()) {
+                       if (pThis->_hideGuideCb)
+                               pThis->_hideGuideCb();
+               }
+       }
+
+       return EINA_FALSE;
+}
+
+void CDrDrawingView::setShowSaveButtonCb(std::function < void(bool) > handlerFunc)
+{
+       _showSaveButtonCb = handlerFunc;
+}
+
+void CDrDrawingView::saveImage(std::string& strFilePath, const bool media_scan_file)
+{
+       _pDrawing->saveDrawingImage(strFilePath);
+
+       if (media_scan_file == false) return;
+
+       int nRet = MEDIA_CONTENT_ERROR_NONE;
+       nRet = media_content_connect();
+       if (nRet != MEDIA_CONTENT_ERROR_NONE) {
+               WINFO("media_content_connect is fail : 0x%x", nRet);
+               return ;
+       }
+
+       nRet = media_content_scan_file(strFilePath.c_str());
+       if (nRet != MEDIA_CONTENT_ERROR_NONE) {
+               WERROR("Fail to register new edited file to DB : %d", nRet);
+       }
+       nRet = media_content_disconnect();
+       if (nRet != MEDIA_CONTENT_ERROR_NONE) {
+               WINFO("media_content_connect is fail : 0x%x", nRet);
+       }
+}
+
+void CDrDrawingView::setDrawedCb(std::function < void(void) > handlerFunc)
+{
+       _drawedCb = handlerFunc;
+}
+
+void CDrDrawingView::setShowGuideCb(std::function < void(void) > handlerFunc)
+{
+       _showGuideCb = handlerFunc;
+}
+
+void CDrDrawingView::setHideGuideCb(std::function < void(void) > handlerFunc)
+{
+       _hideGuideCb = handlerFunc;
+}
+
+void CDrDrawingView::setShowHistoryIndexCb(std::function < void(bool) > handlerFunc)
+{
+       _showHistoryIndexCb = handlerFunc;
+}
+
+void CDrDrawingView::setColorMenuState(bool bShow)
+{
+       if (!bShow && _bColorMenuShowed) {
+               setSaveStatus(true);
+               addSaveTimer();
+       }
+
+       _bColorMenuShowed = bShow;
+}
+
+void CDrDrawingView::setStrokeWidth(double dStrokeWidth)
+{
+       WINFO("set stroke width");
+       _pDrawing->setStrokeWidth(dStrokeWidth);
+}
+
+void CDrDrawingView::setShowPanelCb(std::function < void(void) > handlerFunc)
+{
+       _pDrawing->setShowPanelCb(handlerFunc);
+}
+
+void CDrDrawingView::saveAnimationUpdate(int nStep)
+{
+#ifndef SKETCH_DRAW_COLORS_CHANGABLE
+       Evas_Object* bgPattern = (Evas_Object *)edje_object_part_object_get(_edjeObj, "bg_pattern_negative_image");
+
+       if (CDrAppData::getInstance()->getLaunchMode() == DRAWING_SEND) {
+               evas_object_color_set(bgPattern, 0, 0, 0, 255 - nStep);
+       } else {
+               evas_object_color_set(_pDrawing->getDrawImgObj(), 255, 255, 255, nStep);
+       }
+#else
+       evas_object_color_set(_pDrawing->getDrawImgObj(), 255, 255, 255, nStep);
+#endif
+}
+
+Evas_Object* CDrDrawingView::getBgPattern()
+{
+       Evas_Object* bgPattern = (Evas_Object *)edje_object_part_object_get(_edjeObj, "bg_pattern_negative_image");
+       return bgPattern;
+}
+
+
+void CDrDrawingView::setHistoryControlHandle(CDrHistoryControl* pHandle)
+{
+       _pHistoryCtrl = pHandle;
+}
+
+bool CDrDrawingView::checkIsFirstHistory()
+{
+#ifdef REDO_UNDO
+       if (_history) {
+               return _history->checkFirstIndex();
+       }
+#endif
+       return false;
+}
+
+bool CDrDrawingView::checkHasHistory()
+{
+#ifdef REDO_UNDO
+       if (_history) {
+               return _history->getCount() == 1 ? false: true;
+       }
+#endif
+       return false;
+}
+
+void CDrDrawingView::activateUndoRedoRotary(bool bActivate)
+{
+#ifdef REDO_UNDO
+       if (bActivate) {
+               eext_rotary_object_event_activated_set(_drawingLayout, EINA_TRUE);
+       } else {
+               eext_rotary_object_event_activated_set(_drawingLayout, EINA_FALSE);
+       }
+#endif
+}
+
+void CDrDrawingView::activateUpdateAnimator(bool bActivate)
+{
+       _pDrawing->activateUpdateAnimator(bActivate);
+}
+
+void CDrDrawingView::setUnRedoCb(std::function < void(bool) > handlerFunc)
+{
+       _unReDoCb = handlerFunc;
+}
diff --git a/src/controls/CDrDrawingView.h b/src/controls/CDrDrawingView.h
new file mode 100755 (executable)
index 0000000..bc228a2
--- /dev/null
@@ -0,0 +1,110 @@
+#ifndef _CDR_DRAWING_VIEW_H_
+#define _CDR_DRAWING_VIEW_H_
+
+//#include "sphysics_pba.h"
+#include <string>
+#include <cairo.h>
+#include <app.h>
+#include <app_common.h>
+//#include <efl_assist.h>
+#include <Elementary.h>
+#include <Ecore.h>
+#include <functional>
+#include "Drawing.h"
+#include "WViewController.h"
+#include "CDrEventListener.h"
+#include "CDrControl.h"
+#include "CDrHistoryControl.h"
+#include "WUiTimer.h"
+
+#ifdef REDO_UNDO
+#include "History.h"
+#endif
+using namespace app_assist;
+
+typedef enum {
+       NONE_SHOW = -1,
+       REDO_SHOW,
+       UNDO_SHOW
+} showStatus;
+
+class CDrDrawingView: public CDrControl {
+public:
+       CDrDrawingView();
+
+       virtual void deleteSaveTimer();
+       virtual void addSaveTimer();
+       void deleteShowTimer();
+       void addShowTimer(double time);
+       void setSaveStatus(bool need);
+       void onEvent(const CDrEvent & event);
+
+       virtual Evas_Object * onCreateView(Evas_Object * parent, void *viewParam);
+       virtual void onDestroy();
+       virtual void onCreated();
+       void setShowSaveButtonCb(std::function < void(bool) > handlerFunc);
+       void setShowPanelCb(std::function < void(void) > handlerFunc);
+       void setShowGuideCb(std::function < void(void) > handlerFunc);
+       void setHideGuideCb(std::function < void(void) > handlerFunc);
+       void setShowHistoryIndexCb(std::function < void(bool) > handlerFunc);
+       void saveImage(std::string& strFilePath, const bool media_scan_file);
+       void setDrawedCb(std::function < void(void) > handlerFunc);
+       void setColorCode(std::string& strColor);
+       void setColorMenuState(bool bShow);
+       void saveAnimationUpdate(int nStep);
+
+       void setStrokeWidth(double dStrokeWidth);
+       void setHistoryControlHandle(CDrHistoryControl* pHandle);
+       void deleteHistoryIndexTimer();
+       bool checkIsFirstHistory();
+       bool checkHasHistory();
+       void activateUndoRedoRotary(bool bActivate);
+       void activateUpdateAnimator(bool bActivate);
+       void setUnRedoCb(std::function < void(bool) > handlerFunc);
+       Evas_Object *getBgPattern();
+       showStatus getDrawStatus();
+
+protected:
+       virtual ~CDrDrawingView();
+
+private:
+       static Eina_Bool _onSaveDrawingImage(void *data);
+#ifdef REDO_UNDO
+       static Eina_Bool _onRotaryHandler(void *data, Evas_Object *obj, Eext_Rotary_Event_Info *ev);
+#endif
+       static Eina_Bool _showIndicator(void *data);
+       static void _isOnRedoing(void *data, Eext_Rotary_Event_Info *ev);
+       static void _isOnUndoing(void *data, Eext_Rotary_Event_Info *ev);
+
+private:
+       Evas_Object *_drawingLayout;
+       Evas_Object *_edjeObj;
+       Ecore_Timer *_DrawingSaveTimer;
+       Ecore_Timer *_showTimer;
+       Evas_Object *_botmBgImg;
+       Drawing *_pDrawing;
+#ifdef REDO_UNDO
+    History * _history;
+#endif
+       showStatus _showStatus;
+       CDrHistoryControl* _pHistoryCtrl;
+       bool _NeedSaveDrawing;
+       bool _bCreateSaveTimer;
+       bool _bEraser;
+       bool _bColorMenuShowed;
+       int _previousIndex;
+       int _colorIndex;
+       int _botmBgImgType;
+
+       std::string _colorCode;
+       std::string _oldColorCode;
+       std::function < void(bool) > _showSaveButtonCb;
+       std::function < void(void) > _drawedCb;
+       std::vector<std::string>  _bgFileList;
+       std::function < void(void) > _showGuideCb;
+       std::function < void(void) > _hideGuideCb;
+       std::function < void(bool) > _showHistoryIndexCb;
+       std::function < void(bool) > _unReDoCb;
+};
+#endif /* _DRAWING_VIEW_H_ end */
+
diff --git a/src/controls/CDrHistoryControl.cpp b/src/controls/CDrHistoryControl.cpp
new file mode 100755 (executable)
index 0000000..de412cc
--- /dev/null
@@ -0,0 +1,233 @@
+#include <math.h>
+#include <sys/time.h>
+#include <string>
+#include <sstream>
+#include <iostream>
+#include <fstream>
+#include <CDrUtil.h>
+#include <cstdio>
+#include <algorithm>
+#include <system_settings.h>
+#include <media_content.h>
+#include <efl_extension.h>
+#include "CDrAppData.h"
+#include "CDrHistoryControl.h"
+#include "DrDefine.h"
+
+#define INDEX_ITEM_START_POS  5
+#define INDEX_ITEM_POS_CENTER  9   //11
+#define INDEX_ITEM_EVEN_POS_CENTER  11   //11
+
+CDrHistoryControl::CDrHistoryControl()
+{
+       _oIndex = nullptr;
+       _parent = nullptr;
+       _nStartIndexPos = INDEX_ITEM_START_POS;
+       _nCurIndex = -1;
+       _nSelectedIndex = 0;
+
+       //_itemOddStyleList.push_back("");
+       _itemOddStyleList.push_back("item/odd_1");
+       _itemOddStyleList.push_back("item/odd_2");
+       _itemOddStyleList.push_back("item/odd_3");
+       _itemOddStyleList.push_back("item/odd_4");
+       _itemOddStyleList.push_back("item/odd_5");
+       _itemOddStyleList.push_back("item/odd_6");
+       _itemOddStyleList.push_back("item/odd_7");
+       _itemOddStyleList.push_back("item/odd_8");
+       _itemOddStyleList.push_back("item/odd_9");
+       _itemOddStyleList.push_back("item/odd_10");
+       _itemOddStyleList.push_back("item/odd_11");
+       _itemOddStyleList.push_back("item/odd_12");
+       _itemOddStyleList.push_back("item/odd_13");
+       _itemOddStyleList.push_back("item/odd_14");
+       _itemOddStyleList.push_back("item/odd_15");
+       _itemOddStyleList.push_back("item/odd_16");
+       _itemOddStyleList.push_back("item/odd_17");
+       _itemOddStyleList.push_back("item/odd_18");
+       _itemOddStyleList.push_back("item/odd_19");
+
+       _itemEvenStyleList.push_back("");
+       _itemEvenStyleList.push_back("");
+       _itemEvenStyleList.push_back("item/even_2");
+       _itemEvenStyleList.push_back("item/even_3");
+       _itemEvenStyleList.push_back("item/even_4");
+       _itemEvenStyleList.push_back("item/even_5");
+       _itemEvenStyleList.push_back("item/even_6");
+       _itemEvenStyleList.push_back("item/even_7");
+       _itemEvenStyleList.push_back("item/even_8");
+       _itemEvenStyleList.push_back("item/even_9");
+       _itemEvenStyleList.push_back("item/even_10");
+       _itemEvenStyleList.push_back("item/even_11");
+       _itemEvenStyleList.push_back("item/even_12");
+       _itemEvenStyleList.push_back("item/even_13");
+       _itemEvenStyleList.push_back("item/even_14");
+       _itemEvenStyleList.push_back("item/even_15");
+       _itemEvenStyleList.push_back("item/even_16");
+       _itemEvenStyleList.push_back("item/even_17");
+       _itemEvenStyleList.push_back("item/even_18");
+       _itemEvenStyleList.push_back("item/even_19");
+       _itemEvenStyleList.push_back("item/even_20");
+}
+
+CDrHistoryControl::~CDrHistoryControl()
+{
+       WENTER();
+       _itemList.clear();
+       _itemOddStyleList.clear();
+       _itemEvenStyleList.clear();
+}
+
+void CDrHistoryControl::createControl(Evas_Object * parent)
+{
+       WENTER();
+       _oIndex = elm_index_add(parent);
+       if (_oIndex == nullptr) {
+               WERROR("create failed");
+       }
+       elm_object_style_set(_oIndex, "circle");
+       evas_object_size_hint_weight_set(_oIndex, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+       evas_object_size_hint_align_set(_oIndex, EVAS_HINT_FILL, EVAS_HINT_FILL);
+       elm_index_horizontal_set(_oIndex, EINA_TRUE);
+       elm_index_autohide_disabled_set(_oIndex, EINA_TRUE);
+       elm_object_part_content_set(parent, "elm.swallow.history.index", _oIndex);
+       _parent = parent;
+}
+void CDrHistoryControl::deleteControl()
+{
+       _itemList.clear();
+       _nStartIndexPos = INDEX_ITEM_START_POS;
+       elm_index_level_go(_oIndex, 0);
+       elm_object_part_content_unset(_parent, "elm.swallow.history.index");
+       if (_oIndex != nullptr) {
+               evas_object_del(_oIndex);
+               _oIndex = nullptr;
+       }
+}
+
+void CDrHistoryControl::addItem(int HistoryCount)
+{
+       Elm_Object_Item* item = nullptr;
+       if (_itemList.size() >= (MAX_HISTORY) && (_nCurIndex+1) >= (MAX_HISTORY)) {
+               WINFO("> max count");
+               return;
+       }
+       if (HistoryCount <= 1) {
+               WINFO("1 dots not create");
+               return;
+       }
+       if (HistoryCount != _itemList.size()) {
+               /* delete item */
+               deleteControl();
+               createControl(_parent);
+               /* add item */
+               _nCurIndex = HistoryCount-1;
+               _nSelectedIndex = _nCurIndex;
+               WINFO("add index %d", _nCurIndex);
+               int nStartIndex = 0;
+               bool bUseOdd = true;
+               if (HistoryCount % 2 == 0) {
+                       nStartIndex = INDEX_ITEM_EVEN_POS_CENTER - (HistoryCount)/2;
+                       bUseOdd = false;
+               } else {
+                       nStartIndex = INDEX_ITEM_POS_CENTER - (HistoryCount)/2;
+               }
+               WINFO("SET start style %d", nStartIndex);
+               for (int i =0; i < HistoryCount; i++) {
+                       item = elm_index_item_append(_oIndex, NULL, NULL, (void *) i);
+                       if (bUseOdd) {
+                               elm_object_item_style_set(item, _itemOddStyleList[nStartIndex++].c_str());
+                       } else {
+                               elm_object_item_style_set(item, _itemEvenStyleList[nStartIndex++].c_str());
+                       }
+
+                       _itemList.push_back(item);
+               }
+       } else {
+               WINFO("history count same");
+               _nCurIndex = HistoryCount-1;
+               _nSelectedIndex = _nCurIndex;
+               item = _itemList[_nCurIndex];
+       }
+
+       elm_index_level_go(_oIndex, 0);
+       elm_index_item_selected_set(item, EINA_TRUE);
+}
+
+void CDrHistoryControl::deleteItem(int HistoryCount)
+{
+       Elm_Object_Item* item = nullptr;
+       if (_itemList.size() >= (MAX_HISTORY) && (_nCurIndex+1) >= (MAX_HISTORY)) {
+               WINFO("> max count");
+               return;
+       }
+
+       /* delete item */
+       deleteControl();
+       createControl(_parent);
+
+       if (HistoryCount <= 1) {
+               WINFO("1 dots not create");
+               return;
+       }
+
+       /* add item */
+       _nCurIndex = HistoryCount-1;
+       _nSelectedIndex = _nCurIndex;
+       WINFO("add index %d", _nCurIndex);
+       int nStartIndex = 0;
+       bool bUseOdd = true;
+       if (HistoryCount % 2 == 0) {
+               nStartIndex = INDEX_ITEM_EVEN_POS_CENTER - (HistoryCount)/2;
+               bUseOdd = false;
+       } else {
+               nStartIndex = INDEX_ITEM_POS_CENTER - (HistoryCount)/2;
+       }
+       WINFO("SET start style %d", nStartIndex);
+       for (int i =0; i < HistoryCount; i++) {
+               item = elm_index_item_append(_oIndex, NULL, NULL, (void *) i);
+               if (bUseOdd) {
+                       elm_object_item_style_set(item, _itemOddStyleList[nStartIndex++].c_str());
+               } else {
+                       elm_object_item_style_set(item, _itemEvenStyleList[nStartIndex++].c_str());
+               }
+
+               _itemList.push_back(item);
+       }
+
+       elm_index_level_go(_oIndex, 0);
+       elm_index_item_selected_set(item, EINA_TRUE);
+}
+
+void CDrHistoryControl::redoItem()
+{
+//     WINFO("redo item %d",_nCurIndex);
+       Elm_Object_Item* item = nullptr;
+
+       if ((_nCurIndex + 1) >= _itemList.size()) {
+               WERROR("%d+1 >= count", _nCurIndex);
+               return;
+       } else {
+               _nCurIndex++;
+               _nSelectedIndex = _nCurIndex;
+               item = _itemList[_nCurIndex];
+       }
+
+       elm_index_item_selected_set(item, EINA_TRUE);
+}
+
+void CDrHistoryControl::undoItem()
+{
+//     WINFO("undo item %d",_nCurIndex);
+       Elm_Object_Item* item = nullptr;
+       if (_nCurIndex -1 < 0) {
+               WERROR("%d-1 < 0", _nCurIndex);
+               return;
+       }
+       item = _itemList[_nCurIndex-1];
+       _nSelectedIndex = _nCurIndex -1;
+       //elm_index_level_go(_oIndex, 0);
+       elm_index_item_selected_set(item, EINA_TRUE);
+       _nCurIndex--;
+}
+
diff --git a/src/controls/CDrHistoryControl.h b/src/controls/CDrHistoryControl.h
new file mode 100755 (executable)
index 0000000..efdc913
--- /dev/null
@@ -0,0 +1,47 @@
+#ifndef _CDR_HISTORY_CONTROL_H_
+#define _CDR_HISTORY_CONTROL_H_
+
+//#include "sphysics_pba.h"
+#include <string>
+#include <cairo.h>
+#include <app.h>
+#include <app_common.h>
+//#include <efl_assist.h>
+#include <Elementary.h>
+#include <deque>
+#include <string>
+#include <functional>
+#include "CDrEventListener.h"
+#ifdef REDO_UNDO
+#include "History.h"
+#endif
+
+
+class CDrHistoryControl {
+public:
+       CDrHistoryControl();
+       virtual ~CDrHistoryControl();
+
+       void createControl(Evas_Object * parent);
+       void deleteControl();
+
+       void redoItem();
+       void undoItem();
+       void addItem(int HistoryCount);
+       void deleteItem(int HistoryCount);
+private:
+       CDrHistoryControl(const CDrHistoryControl&) = delete;
+       const CDrHistoryControl& operator = (const CDrHistoryControl&) = delete;
+
+private:
+       Evas_Object *_oIndex;
+       Evas_Object *_parent;
+       std::deque<Elm_Object_Item*> _itemList;
+       std::deque<std::string> _itemOddStyleList;
+       std::deque<std::string> _itemEvenStyleList;
+       int _nStartIndexPos;
+       int _nCurIndex;
+       int _nSelectedIndex;
+};
+#endif /* _DRAWING_VIEW_H_ end */
+
diff --git a/src/controls/CDrTutorialView.cpp b/src/controls/CDrTutorialView.cpp
new file mode 100755 (executable)
index 0000000..a935e33
--- /dev/null
@@ -0,0 +1,107 @@
+#include <math.h>
+#include <sys/time.h>
+#include <string>
+#include <sstream>
+#include <iostream>
+#include <fstream>
+#include <CDrUtil.h>
+#include <cstdio>
+#include <algorithm>
+#include <system_settings.h>
+#include <media_content.h>
+#include <efl_extension.h>
+#include "CDrAppData.h"
+#include "CDrTutorialView.h"
+#include "DrDefine.h"
+#include "CDrEventManager.h"
+
+
+CDrTutorialView::CDrTutorialView()
+: _layout(nullptr),
+_cancelButton(nullptr)
+{
+}
+
+CDrTutorialView::~CDrTutorialView()
+{
+}
+
+
+Evas_Object * CDrTutorialView::onCreateView(Evas_Object * parent, void *viewParam)
+{
+       WENTER();
+
+       _layout = elm_layout_add(parent);
+
+       char* _path = app_get_resource_path();
+       std::string path(_path);
+       path += EDJ_FILE;
+
+       elm_layout_file_set(_layout, path.c_str(), DRAWING_TUTORIAL_LAYOUT_GROUP_NAME);
+       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);
+       evas_object_resize(_layout, 360, 360);
+       evas_object_show(_layout);
+
+       elm_object_domain_translatable_part_text_set(_layout, "elm.text", LOCALE_DOMAIN, DRAWING_TUTORIAL_POPUP_CONTENTS_1);
+       elm_object_domain_translatable_part_text_set(_layout, "elm.text.title", LOCALE_DOMAIN, DRAWING_TUTORIAL_POPUP_TITLE);
+
+       _cancelButton = elm_button_add(_layout);
+       elm_object_style_set(_cancelButton , "focus");
+
+       elm_object_part_content_set(_layout, "actionbtn1", _cancelButton);
+
+       evas_object_smart_callback_add(_cancelButton, "clicked", _onCancelBtnClicked, this);
+       free(_path);
+
+       WLEAVE();
+       return _layout;
+}
+
+void CDrTutorialView::onCreated()
+{
+}
+
+void CDrTutorialView::onDestroy()
+{
+}
+
+void CDrTutorialView::onEvent(const CDrEvent & event)
+{
+}
+
+void CDrTutorialView::setOnCancelResult(std::function < void() > handlerFunc)
+{
+       _cancelResultHandler = handlerFunc;
+}
+
+void CDrTutorialView::_onCancelBtnClicked(void *data, Evas_Object *obj, void *event_info)
+{
+       CDrTutorialView * pThis = (CDrTutorialView*)data;
+       if (pThis->_cancelResultHandler) {
+               pThis->_cancelResultHandler();
+       }
+}
+
+void CDrTutorialView::showRedoGuide()
+{
+       elm_object_signal_emit(_layout, "elm,image,ccw,hide", "*");
+       elm_object_signal_emit(_layout, "elm,image,cw,show", "*");
+
+       elm_object_domain_translatable_part_text_set(_layout, "elm.text", LOCALE_DOMAIN, DRAWING_TUTORIAL_POPUP_CONTENTS_2);
+       elm_object_domain_translatable_part_text_set(_layout, "elm.text.title", LOCALE_DOMAIN, "");
+       elm_object_part_content_unset(_layout, "actionbtn1");
+       if (_cancelButton != nullptr) {
+               evas_object_del(_cancelButton);
+               _cancelButton = nullptr;
+       }
+       elm_object_signal_emit(_layout, "elm,image,btn,hide", "*");
+}
+void CDrTutorialView::showUndoGuide()
+{
+       elm_object_signal_emit(_layout, "elm,image,ccw,show", "*");
+       elm_object_signal_emit(_layout, "elm,image,cw,hide", "*");
+       elm_object_domain_translatable_part_text_set(_layout, "elm.text", LOCALE_DOMAIN, DRAWING_TUTORIAL_POPUP_CONTENTS_1);
+       elm_object_domain_translatable_part_text_set(_layout, "elm.text.title", LOCALE_DOMAIN, DRAWING_TUTORIAL_POPUP_TITLE);
+}
+
diff --git a/src/controls/CDrTutorialView.h b/src/controls/CDrTutorialView.h
new file mode 100755 (executable)
index 0000000..f9d1cd5
--- /dev/null
@@ -0,0 +1,49 @@
+#ifndef _CDR_TUTORIAL_VIEW_H_
+#define _CDR_TUTORIAL_VIEW_H_
+
+//#include "sphysics_pba.h"
+#include <string>
+#include <cairo.h>
+#include <app.h>
+#include <app_common.h>
+//#include <efl_assist.h>
+#include <Elementary.h>
+#include <Ecore.h>
+#include <functional>
+#include "Drawing.h"
+#include "WViewController.h"
+#include "CDrEventListener.h"
+#include "CDrControl.h"
+#include "CDrHistoryControl.h"
+#include "WUiTimer.h"
+
+#ifdef REDO_UNDO
+#include "History.h"
+#endif
+using namespace app_assist;
+
+
+class CDrTutorialView: public CDrControl {
+public:
+       CDrTutorialView();
+
+       void onEvent(const CDrEvent & event);
+
+       virtual Evas_Object * onCreateView(Evas_Object * parent, void *viewParam);
+       virtual void onDestroy();
+       virtual void onCreated();
+       void setOnCancelResult(std::function < void() > handlerFunc);
+       void showRedoGuide();
+       void showUndoGuide();
+
+protected:
+       static void _onCancelBtnClicked(void *data, Evas_Object *obj, void *event_info);
+       virtual ~CDrTutorialView();
+
+private:
+       Evas_Object *_layout;
+       Evas_Object* _cancelButton;
+       std::function < void() > _cancelResultHandler;
+};
+#endif /* _DRAWING_VIEW_H_ end */
+
diff --git a/src/controls/Drawing.cpp b/src/controls/Drawing.cpp
new file mode 100755 (executable)
index 0000000..99c5aaa
--- /dev/null
@@ -0,0 +1,1324 @@
+#include "Drawing.h"
+#include "CDrDrawingView.h"
+#include "CDrAppData.h"
+#include "WUiTimer.h"
+
+
+#define POINT_SKIP_OFFSET  4
+#define MAX_ZOOM_FACTOR (2)
+#define MAX_ALPHA_ANIMATION_TIMER_COUNT 5   //update animation is 1/60, request alpha animation timer is 1/10,so
+#define STROKE_WIDTH_DRAWING_CHANGES_MIN 6
+
+using namespace std;
+
+const double RESAMPLE_MAX_DELAY = 20;
+
+
+
+int Drawing::_mTouchMode = 0;
+
+Drawing::Drawing()
+       :_pDrawingObj(NULL)
+{
+       _deleteSaveTimerCb = nullptr;
+       _colorMenuStateCb = nullptr;
+       _saveStateCb = nullptr;
+       setMaxHistoryCb = nullptr;
+       _addSaveTimerCb = nullptr;
+       _showPanelCb = nullptr;
+#ifdef REDO_UNDO
+       _saveBufferCb = nullptr;
+       checkFirstIndexCb = nullptr;
+       pAnimationData = nullptr;
+       _getBufferCb = nullptr;
+#endif
+}
+
+Drawing::~Drawing()
+{
+       if (pAnimationData != nullptr) {
+               free(pAnimationData);
+               pAnimationData = nullptr;
+       }
+}
+
+#ifdef ENABLE_ZOOM
+void Drawing::_Draw(void *data, int fx, int fy, int fw, int fh)
+{
+       Drawing *pThis = (Drawing*)data;
+       if (pThis == nullptr) {
+               return;
+       }
+
+       Evas_Object *select = static_cast<Evas_Object *>(pThis->_pDrawingObj);
+       evas_object_resize(pThis->_pDrawingObj, fw, fh);
+       evas_object_move(pThis->_pDrawingObj, fx, fy);
+}
+
+Eina_Bool Drawing::_DoZoom(void *data, double pos)
+{
+       int x, y, w, h;
+       int ix, iy;                     // New center
+       double zoom;
+       Drawing *pThis = (Drawing*)data;
+       if (pThis == nullptr) {
+               return EINA_TRUE;
+       }
+
+       Evas_Object *select = static_cast<Evas_Object *>(pThis->_pDrawingObj);
+       struct Smart_Data *sd = (struct Smart_Data *) evas_object_smart_data_get(select);
+
+       evas_object_geometry_get(sd->img, &x, &y, &w, &h);
+
+       ix = sd->xClick - x;
+       iy = sd->yClick - y;
+       double frame = pos;
+       frame = ecore_animator_pos_map(pos, ECORE_POS_MAP_ACCELERATE, 0, 0);
+       int new_ix, new_iy, rw, rh;             // Resized
+
+       if (sd->isAutofit)
+               zoom = 1 + frame;
+       else
+               zoom = 2 - frame;
+       rw = sd->bufW * zoom;
+       rh = sd->bufH * zoom;
+
+       if(w == 0 || h == 0) return EINA_TRUE;
+
+       new_ix = (ix * rw) / (double)w;         // Moved
+       new_iy = (iy * rh) / (double)h;
+
+       int fx, fy, fw, fh;             // Final position
+
+       fx = sd->xClick - new_ix;
+       fy = sd->yClick - new_iy;
+       fw = rw;
+       fh = rh;
+
+       if (sd->cRect.w < fw)
+       {
+               if (fx > sd->cRect.x)
+               {
+                       fx = sd->cRect.x;
+               }
+
+               if (fw + fx < sd->cRect.x + sd->cRect.w)                // Reach to right side
+               {
+                       fx = sd->cRect.x + sd->cRect.w - fw;
+               }
+       } else {
+               fx = sd->cRect.x + ((sd->cRect.w - fw) / 2);
+       }
+
+       if (sd->cRect.h < fh)
+       {
+           if (fy > sd->cRect.y)               // Reach to Top side
+               {
+                       fy = sd->cRect.y;
+               }
+
+               if( fy + fh < sd->cRect.y + sd->cRect.h)                // Reach to Bottom side
+               {
+                       fy = sd->cRect.y + sd->cRect.h - fh;
+               }
+       } else {
+                       fy = sd->cRect.y + ((sd->cRect.h - fh) / 2);
+       }
+       _Draw(data, fx, fy, fw, fh);
+       return EINA_TRUE;
+}
+
+double Drawing::_getAutoFitZoom(struct Smart_Data *sd)
+{
+       int cw, ch;             // Swallowed Rect
+       WINFO("");
+       cw = sd->cRect.w;
+       ch = sd->cRect.h;
+
+       int width, height;
+
+       width = sd->bufW;
+       height = sd->bufH;
+
+       int ph, pw;
+
+       ph = (height * cw) / width;
+
+       if (ph > ch)
+       {
+               pw = (width * ch) / height;
+               ph = ch;
+       } else {
+               pw = cw;
+       }
+       double zx, zy;
+
+       zx = (double)pw / (double)width;
+       zy = (double)ph / (double)height;
+
+       return zx > zy ? zx : zy;
+}
+
+Evas_Event_Flags Drawing::_onDblClickStart(void *data , void *event_info)
+{
+       Elm_Gesture_Taps_Info *p = (Elm_Gesture_Taps_Info *) event_info;
+       Drawing *pThis = (Drawing*)data;
+       if (pThis == nullptr) {
+               return EVAS_EVENT_FLAG_NONE;
+       }
+
+       Evas_Object *select = static_cast<Evas_Object *>(pThis->_pDrawingObj);
+       struct Smart_Data *sd = (struct Smart_Data *) evas_object_smart_data_get(select);
+
+       sd->isZoomed = EINA_TRUE;
+
+       if (p->n != 1) return EVAS_EVENT_FLAG_NONE;
+
+       return EVAS_EVENT_FLAG_NONE;
+}
+
+Evas_Event_Flags Drawing::_onDblClickEnd(void *data , void *event_info)
+{
+       Elm_Gesture_Taps_Info *p = (Elm_Gesture_Taps_Info *) event_info;
+       Drawing *pThis = (Drawing*)data;
+       if (pThis == nullptr) {
+               return EVAS_EVENT_FLAG_NONE;
+       }
+
+       Evas_Object *select = static_cast<Evas_Object *>(pThis->_pDrawingObj);
+       struct Smart_Data *sd = (struct Smart_Data *) evas_object_smart_data_get(select);
+       double max =  _getAutoFitZoom(sd) * MAX_ZOOM_FACTOR;
+       sd->xClick = p->x;
+       sd->yClick = p->y;
+       if (sd->Zoom > _getAutoFitZoom(sd)) {
+               sd->Zoom = _getAutoFitZoom(sd);
+               sd->isAutofit = false;
+               ecore_animator_timeline_add(0.15, _DoZoom, data);
+       } else  {
+               sd->Zoom = max;
+               sd->isAutofit = true;
+               ecore_animator_timeline_add(0.15, _DoZoom, data);
+       }
+
+       sd->m_selected.Clear();
+       sd->isZoomed = EINA_FALSE;
+
+       return EVAS_EVENT_FLAG_NONE;
+}
+
+Evas_Event_Flags Drawing::_onDblClickAbort(void *data , void *event_info)
+{
+       Elm_Gesture_Taps_Info *p = (Elm_Gesture_Taps_Info *) event_info;
+       Drawing *pThis = (Drawing*)data;
+       if (pThis == nullptr) {
+           return EVAS_EVENT_FLAG_NONE;
+       }
+
+       Evas_Object *select = static_cast<Evas_Object *>(pThis->_pDrawingObj);
+       struct Smart_Data *sd = (struct Smart_Data *) evas_object_smart_data_get(select);
+
+       sd->isZoomed = EINA_FALSE;
+       int x, y, w, h;
+       evas_object_geometry_get(sd->img, &x, &y, &w, &h);
+       //To prevent draw double tap point,only draw point when normal drawing.
+       std::vector<std::pair<double, double>> pt = sd->m_selected.getOldPointsList();
+       sd->m_cairo.Draw(sd->m_selected, sd->m_selected.GetHistoryPoints(pt);,
+                    (double)sd->bufW / (double)w,
+                    (double)sd->bufH / (double)h,
+                    w, h);
+
+       if (pThis->_saveBufferCb)
+       {
+               std::vector<std::pair<double, double>> pt = sd->m_selected.GetOriginalPoints();
+               double strokeWidth = sd->m_cairo.getStrokeWidth();
+               //Save image info when draw point.If draw a line,it will be update when mouse up again.
+               pThis->_saveBufferCb(pt, sd->m_selected.GetOriginalstrokeList(), &(pThis->_cCurrentColor), strokeWidth, true);
+       }
+       if (p->n != 1 ) return EVAS_EVENT_FLAG_NONE;
+       return EVAS_EVENT_FLAG_NONE;
+}
+#endif
+
+Evas_Event_Flags Drawing::_onTapEnd(void *data , void *event_info)
+{
+       if (data == nullptr || event_info == nullptr) {
+               return EVAS_EVENT_FLAG_NONE;
+       }
+
+       Elm_Gesture_Taps_Info *p = (Elm_Gesture_Taps_Info *) event_info;
+       if (p->n != 1) {
+               return EVAS_EVENT_FLAG_NONE;
+       }
+       Drawing *pThis = (Drawing*)data;
+       if (pThis->_showPanelCb) {
+               pThis->_showPanelCb();
+       }
+       return EVAS_EVENT_FLAG_NONE;
+}
+
+#ifdef ENABLE_DRAGING
+void Drawing::_onMultiDown(void *data, Evas *e, Evas_Object *evas_obj, void *event_info)
+{
+       Drawing *pThis = (Drawing*)data;
+       if (pThis == nullptr) {
+               return;
+       }
+
+       Evas_Object *select = static_cast<Evas_Object *>(pThis->_pDrawingObj);
+       struct Smart_Data *sd = (struct Smart_Data *) evas_object_smart_data_get(select);
+       sd->mutilDown = true;
+       _Evas_Event_Multi_Down *ev = (_Evas_Event_Multi_Down *) event_info;
+
+       sd->xMutilPrev = ev->output.x;
+       sd->yMutilPrev = ev->output.y;
+       WLEAVE();
+}
+#endif
+
+void Drawing::_onMultiMove(void *data, Evas *e, Evas_Object *evas_obj, void *event_info)
+{
+       int dx, dy;
+       Drawing *pThis = (Drawing*)data;
+       if (pThis == nullptr) {
+               return;
+       }
+
+       Evas_Object *select = static_cast<Evas_Object *>(pThis->_pDrawingObj);
+       struct Smart_Data *sd = (struct Smart_Data *) evas_object_smart_data_get(select);
+       sd->bMultiMove = true;
+
+#ifdef ENABLE_DRAGING
+       if (!sd->mutilDown)
+       {
+               return;
+       }
+       _Evas_Event_Multi_Move *ev = (_Evas_Event_Multi_Move *) event_info;
+       dx = ev->cur.output.x - sd->xMutilPrev;
+       dy = ev->cur.output.y - sd->yMutilPrev;
+       sd->xMutilPrev = ev->cur.output.x;
+       sd->yMutilPrev = ev->cur.output.y;
+       if (sd->isAutofit)
+       {
+               sd->m_cairo.dragImage(dx, dy);
+       }
+       WLEAVE();
+#endif
+}
+
+void Drawing::_onMultiUp(void *data, Evas *e, Evas_Object *evas_obj, void *event_info)
+{
+       Drawing *pThis = (Drawing*)data;
+       if (pThis == nullptr) {
+               return;
+       }
+       Evas_Object *select = static_cast<Evas_Object *>(pThis->_pDrawingObj);
+       struct Smart_Data *sd = (struct Smart_Data *) evas_object_smart_data_get(select);
+       sd->bMultiMove = false;
+#ifdef ENABLE_DRAGING
+       sd->mutilDown = false;
+       WLEAVE();
+#endif
+}
+
+
+void Drawing::_onMouseDown(void *data, Evas *e, Evas_Object *evas_obj, void *event_info)
+{
+       WINFO("_onMouseDown");
+       Drawing *pThis = (Drawing*)data;
+       if (pThis == nullptr) {
+               return;
+       }
+
+       Drawing::_mTouchMode = 2;
+       if (pThis->_deleteSaveTimerCb) {
+               pThis->_deleteSaveTimerCb();
+       }
+       if (pThis->_colorMenuStateCb) {
+               bool color_menu = pThis->_colorMenuStateCb();
+               if(color_menu == true)
+               {
+                       WINFO("color menu show, return");
+                       return;
+               }
+       }
+
+       Evas_Object *select = static_cast<Evas_Object *>(pThis->_pDrawingObj);
+
+       struct Smart_Data *sd = (struct Smart_Data *) evas_object_smart_data_get(select);
+
+       Evas_Event_Mouse_Down *ev = (Evas_Event_Mouse_Down *) event_info;
+       if (ev->button > 1) {
+               WERROR("> 1");
+               return;
+       }
+
+       int x, y;
+       x = ev->output.x;
+       y = ev->output.y;
+
+       int img_x, img_y;
+       int img_w, img_h;
+
+       evas_object_geometry_get(sd->img, &img_x, &img_y, &img_w, &img_h);
+
+       if(!((x > img_x) && (x < img_x + img_w) &&
+                       (y > img_y) && (y < img_y + img_h))) {
+               WINFO("PRESSED OUTSIDE IMAGE REGION");
+               return;
+       }
+       sd->mouseDownX = abs(x  - img_x);
+       sd->mouseDownY = abs(y  - img_y);
+       //WINFO("mouse down %d %d",sd->mouseDownX,sd->mouseDownY);
+       if (!sd->m_selected.lastBufferIsCompleted()) {
+               sd->m_cairo.eraseDraw(sd->m_selected, (double)sd->bufW / (double)sd->oRect.w,
+                    (double)sd->bufH/ (double)sd->oRect.h,
+                   sd->oRect.w, sd->oRect.h, MAX_POINTS_LIST_COUNT-1);
+       }
+       sd->m_selected.increaseListIndex();
+
+       sd->bMouseDown = true;
+       sd->bFirstMove = true;
+       sd->latestTimestamp = sd->prevTimestamp = ev->timestamp;
+       sd->m_cairo.SetDrawingProperty(&pThis->_cCurrentColor);
+#ifdef REDO_UNDO
+       sd->isMoved = false;
+#endif
+       WLEAVE();
+}
+
+void Drawing::_onMouseMove(void *data, Evas *e, Evas_Object *evas_obj, void *event_info)
+{
+       //WENTER();
+       Drawing *pThis = (Drawing*)data;
+       bool bChange = false;
+       if (pThis == nullptr) {
+               return;
+       }
+
+       if (Drawing::_mTouchMode != 2)
+       {
+               return;
+       }
+       Evas_Object *select = static_cast<Evas_Object *>(pThis->_pDrawingObj);
+       struct Smart_Data *sd = (struct Smart_Data *) evas_object_smart_data_get(select);
+
+#ifdef ENABLE_DRAGING
+       if (sd->mutilDown)
+               return;
+#endif
+// Move event is coming once before down event. we can check useless move event by using m_grasp.
+       Evas_Event_Mouse_Move *ev = (Evas_Event_Mouse_Move *) event_info;
+//     WINFO("Mouse move, dx=%d dy=%d", ev->cur.output.x, ev->cur.output.y);
+       if (ev->buttons > 1) {
+               WERROR("> 1");
+               return;
+       }
+
+       if (!sd->bMouseDown)
+       {
+               // Skip move event before down
+               return;
+       }
+       if (sd->bMultiMove) {
+               WINFO("multi move, stop");
+               return;
+       }
+       if (sd->m_cairo.getNormalDrawingStatus()) {
+               WERROR("doing rotary");
+               return;
+       }
+
+       if (sd->bFirstMove)
+       {
+               //WINFO("x, y: %d %d",sd->mouseDownX,sd->mouseDownY);
+               sd->m_selected.AddPoint(CPoint(sd->mouseDownX, sd->mouseDownY));
+               sd->bFirstMove  = false;
+               if (pThis->_saveStateCb) {
+                       pThis->_saveStateCb(true);
+               }
+               if (pThis->checkFirstIndexCb) {
+                       if ((pThis->checkFirstIndexCb())) {
+                               sd->m_cairo.clearImage();
+                               //sd->m_cairo.clearBuffer();
+                       }
+                       sd->isUndoRedoAnimator = false;
+                       if (pThis->pAnimationData->nBgPatternAlpha != 0) {
+                               evas_object_color_set(pThis->pAnimationData->bgPattern, 0, 0, 0, 0);
+                               pThis->pAnimationData->nBgPatternAlpha = 0;
+                       }
+               }
+               bChange  = true;
+       }
+
+       sd->xPrev = ev->prev.output.x;
+       sd->yPrev = ev->prev.output.y;
+
+       sd->xLatest = ev->cur.output.x;
+       sd->yLatest = ev->cur.output.y;
+
+       sd->prevTimestamp = sd->latestTimestamp;
+       sd->latestTimestamp = ev->timestamp;
+
+       //
+
+       bool bret = pThis->_addDrawPoint();
+       if (bChange || bret) {
+               sd->is_changed = true;
+#ifdef REDO_UNDO
+               sd->isMoved = true;
+#endif
+       }
+       //WLEAVE();
+}
+
+void Drawing::_onMouseUp(void *data, Evas *e,  Evas_Object *evas_obj, void *event_info)
+{
+       WINFO("_onMouseUp");
+       int index = 0;
+       Drawing *pThis = (Drawing*)data;
+       if (pThis == nullptr) {
+               return;
+       }
+
+       if (Drawing::_mTouchMode != 2)
+       {
+               return;
+       }
+       Drawing::_mTouchMode = 0;
+       Evas_Object *select = static_cast<Evas_Object *>(pThis->_pDrawingObj);
+
+       struct Smart_Data *sd = (struct Smart_Data *) evas_object_smart_data_get(select);
+
+       sd->bMouseDown = false;
+       sd->is_changed = false;
+#ifdef REDO_UNDO
+
+#ifdef ENABLE_ZOOM
+       if (!sd->isZoomed)
+#endif
+       {
+               if (sd->isMoved && (sd->m_selected.GetCount() > 0))
+               {
+                       WINFO("drawed");
+                       if (pThis->_saveBufferCb)
+                       {
+                               if (pThis->checkFirstIndexCb) {
+                                       if ((pThis->checkFirstIndexCb())) {
+                                               sd->m_cairo.clearBuffer();
+                                               if (pThis->setMaxHistoryCb) {
+                                                       pThis->setMaxHistoryCb(false);
+                                               }
+                                       }
+                               }
+
+                               std::vector<std::pair<double, double>> pt = sd->m_selected.GetOriginalPoints();
+                               double strokeWidth = sd->m_cairo.getStrokeWidth();
+#ifdef ENABLE_ZOOM
+                               pThis->_saveBufferCb(pt, sd->m_selected.GetOriginalstrokeList(), &(pThis->_cCurrentColor), strokeWidth, false);
+#else
+                               pThis->_saveBufferCb(pt, sd->m_selected.GetOriginalstrokeList(), &(pThis->_cCurrentColor), strokeWidth, true);
+#endif
+                       }
+               }
+               sd->isMoved = false;
+       }
+#endif
+
+       if (sd->bFirstMove) {
+           sd->bFirstMove  = false;
+
+#ifdef REDO_UNDO
+       if (pThis->checkFirstIndexCb) {
+               if (!(pThis->checkFirstIndexCb())) {
+                       if (pThis->_saveStateCb) {
+                               pThis->_saveStateCb(true);
+                       }
+               }
+       }
+#else
+       if (pThis->_saveStateCb) {
+               pThis->_saveStateCb(true);
+       }
+#endif
+       }
+
+       if (pThis->_addSaveTimerCb) {
+           pThis->_addSaveTimerCb();
+       }
+       sd->m_selected.addEndPoint();
+       if (sd->m_selected.GetCount() < 2) {
+               WINFO("refresh only 1 pt");
+               evas_object_smart_changed(sd->obj);
+       }
+}
+
+
+bool Drawing::_addDrawPoint()
+{
+       struct Smart_Data *sd = (struct Smart_Data *) evas_object_smart_data_get(_pDrawingObj);
+       static int xprev = 0, yprev = 0;
+       int resample_x = 0;
+       int resample_y = 0;
+       int img_x, img_y;
+       int img_w, img_h;
+       int x, y;
+       double tx, ty, speedStrokeWidth;
+       int previousStrokeWidth = 0;
+
+       if (xprev == 0 && yprev == 0) {
+               xprev = sd->xPrev;
+               yprev = sd->yPrev;
+       }
+       resample_x = sd->xLatest;
+       resample_y = sd->yLatest;
+
+       evas_object_geometry_get(sd->img, &img_x, &img_y, &img_w, &img_h);
+
+
+       if (sd->m_selected.GetCount() <= 0) {
+               //WINFO("GetCount <= 0");
+               return false;
+       } else {
+               xprev = sd->m_selected[sd->m_selected.GetCount()-1].x + img_x;
+               yprev = sd->m_selected[sd->m_selected.GetCount()-1].y + img_y;
+       }
+       if ( sqrt((resample_x - xprev)*(resample_x - xprev) +(resample_y - yprev)*(resample_y - yprev)) < 12) {
+               WINFO("SKIP Offset %d", 12);
+               return false;
+       }
+
+       if(!((resample_x > img_x) && (resample_x < img_x + img_w) &&
+                       (resample_y > img_y) && (resample_y < img_y + img_h))) {
+               WINFO("PRESSED OUTSIDE IMAGE REGION");
+               return false;
+       }
+
+       x = abs(resample_x  - img_x);
+       y = abs(resample_y  - img_y);
+
+       tx = sd->xLatest-sd->xPrev;
+       ty = sd->yLatest-sd->yPrev;
+       speedStrokeWidth = (int)(6 * asin(-(sqrt(tx*tx + ty*ty))/23+1)+8);
+
+       previousStrokeWidth = sd->m_selected.getLastStrokeWidth();
+       if (previousStrokeWidth != -1) {
+               if (speedStrokeWidth > 1.20 * previousStrokeWidth) {
+                       speedStrokeWidth = 1.20 * previousStrokeWidth;
+               }
+
+               if (speedStrokeWidth < previousStrokeWidth / 1.20) {
+                       speedStrokeWidth = previousStrokeWidth / 1.20;
+               }
+       }
+
+       if (speedStrokeWidth > MMS_MODE_STROKE_LINE_WIDTH) {
+               speedStrokeWidth = MMS_MODE_STROKE_LINE_WIDTH;
+       }
+
+       if (speedStrokeWidth < STROKE_WIDTH_DRAWING_CHANGES_MIN) {
+               speedStrokeWidth = STROKE_WIDTH_DRAWING_CHANGES_MIN;
+       }
+       sd->m_selected.AddPoint(CPoint(x, y), (int) (speedStrokeWidth+0.5));
+       WINFO("add point");
+       return true;
+}
+
+bool Drawing::isMouseMoving()
+{
+       /* bug: mouse moving, and then run rotary event, and then run mouse up event,
+       error: current drawed point are not saved in history
+       solution: terminate current rotary event
+       */
+       struct Smart_Data *sd = (struct Smart_Data *) evas_object_smart_data_get(_pDrawingObj);
+       if (sd->bMouseDown && sd->isMoved) {
+               return true;
+       }
+       return false;
+}
+
+void Drawing::_smartAdd(Evas_Object *obj)
+{
+       WENTER();
+
+       struct Smart_Data *sd = new struct Smart_Data;
+       sd->target = nullptr;
+       sd->bShow = EINA_FALSE;
+
+       evas_object_smart_data_set(obj, sd);
+
+       sd->obj = obj;
+       WLEAVE();
+}
+
+void Drawing::_smartDel(Evas_Object *obj)
+{
+       WENTER();
+       WINFO(" _smartDel called");
+       struct Smart_Data *sd = (struct Smart_Data *) evas_object_smart_data_get(obj);
+
+       evas_object_del(sd->m_event);
+    ecore_animator_del(sd->anim);
+
+       sd->m_selected.Clear();
+       sd->m_cairo.DeleteImage();
+
+       delete sd;
+       WLEAVE();
+}
+
+void Drawing::_smartMove(Evas_Object *obj, Evas_Coord x, Evas_Coord y)
+{
+       struct Smart_Data *sd = (struct Smart_Data *) evas_object_smart_data_get(obj);
+
+       /*  Below line is commetned to enable selection of lasso crop region for the first time, if the code returns from here so called are not called */
+
+       /* if ((sd->cRect.x == x) && (sd->cRect.y == y)) return; */
+
+       WINFO("_smartMove Image Move to XY(%d,%d)", x, y);
+       sd->oRect.x = x;
+       sd->oRect.y = y;
+
+       evas_object_move(sd->m_event, x, y);
+       evas_object_move(sd->img, x, y);
+       evas_object_smart_changed(sd->obj);
+}
+
+void Drawing::_smartResize(Evas_Object *obj, Evas_Coord w, Evas_Coord h)
+{
+       struct Smart_Data *sd = (struct Smart_Data *) evas_object_smart_data_get(obj);
+
+       /*  Below line is commetned to enable selection of lasso crop region for the first time, if the code returns from here so called are not called */
+
+       /* if ((sd->cRect.w == w) && (sd->cRect.h == h))  return;  */
+
+       WINFO("_smartResize Image Resize to WH(%d,%d)", w, h);
+
+       sd->oRect.w = w;
+       sd->oRect.h = h;
+       evas_object_resize(sd->m_event, w, h);
+       evas_object_resize(sd->img, w, h);
+       evas_object_smart_changed(sd->obj);
+}
+
+void Drawing::_smartShow(Evas_Object *obj)
+{
+//     WENTER();
+
+       struct Smart_Data *sd = (struct Smart_Data *) evas_object_smart_data_get(obj);
+
+       if ( sd->bShow == EINA_TRUE) return;
+
+       sd->bShow = EINA_TRUE;
+
+       evas_object_show(sd->m_event);
+//     WLEAVE();
+}
+
+void Drawing::_smartHide(Evas_Object *obj)
+{
+       WENTER();
+
+       struct Smart_Data *sd = (struct Smart_Data *) evas_object_smart_data_get(obj);
+
+       if ( sd->bShow == EINA_FALSE) return;
+
+       sd->bShow = EINA_FALSE;
+
+       evas_object_hide(sd->m_event);
+       WLEAVE();
+}
+
+void Drawing::_smartCalculate(Evas_Object *obj)
+{
+       struct Smart_Data *sd = (struct Smart_Data *) evas_object_smart_data_get(obj);
+       int x, y, w, h;
+       if (sd->target == NULL ) return;
+       evas_object_geometry_get(sd->img, &x, &y, &w, &h);
+       if ( (sd->oRect.w != w) || (sd->oRect.h != h) ) {
+               WINFO(" w,h <%d %d> oRect w ,h <%d %d>", w, h, sd->oRect.w, sd->oRect.h);
+               WINFO(" x,y <%d %d> oRect x,y <%d %d>", x, y, sd->oRect.x, sd->oRect.y);
+               for ( int i = 0; i < sd->m_selected.GetCount(); i++) {
+                       CPoint &pt = sd->m_selected[i];
+                       pt.x = ((pt.x * w) / sd->oRect.w) ;
+                       pt.y = ((pt.y * h) / sd->oRect.h) ;
+                       sd->m_selected[i] = pt;
+               }
+
+               sd->oRect.x = x;
+               sd->oRect.y = y;
+               sd->oRect.w = w;
+               sd->oRect.h = h;
+       }
+       sd->m_cairo.Draw(sd->m_selected,
+                    (double)sd->bufW / (double)w,
+                    (double)sd->bufH/ (double)h,
+                    w, h);
+}
+
+Evas_Smart *Drawing::_smartInit(void)
+{
+       WENTER();
+       static Evas_Smart *smart = NULL;
+       if (smart)
+               return (smart);
+
+       const char* name = eina_stringshare_add("ie-selectlasso");
+       static Evas_Smart_Class sc =
+       {
+               NULL,
+               EVAS_SMART_CLASS_VERSION,
+               _smartAdd,
+               _smartDel,
+               _smartMove,
+               _smartResize,
+               _smartShow,
+               _smartHide,
+               NULL,
+               NULL,
+               NULL,
+               _smartCalculate,
+               NULL,
+               NULL,
+               NULL,
+               NULL,
+               NULL,
+               NULL
+       };      //Evas_smart_Class
+       sc.name = name;
+       smart = evas_smart_class_new(&sc);
+
+       WLEAVE();
+       return smart;
+}
+
+Eina_Bool Drawing::_onAnimatorUpdate(void *data)
+{
+       bool isFirstPoint = false;
+       bool bChange = false;
+       Evas_Object *select = nullptr;
+       struct Smart_Data *sd = nullptr;
+       static int xprev = 0, yprev = 0;
+       int resample_x = 0;
+       int resample_y = 0;
+       int img_x, img_y;
+       int img_w, img_h;
+       int x, y;
+       double tx, ty, speedStrokeWidth;
+       int previousStrokeWidth = 0;
+
+       if(nullptr == data)
+       {
+               return EINA_TRUE;
+       }
+       Drawing *pThis = (Drawing*)data;
+       sd = (struct Smart_Data *) evas_object_smart_data_get(pThis->_pDrawingObj);
+
+       if(nullptr == sd)
+       {
+               return EINA_TRUE;
+       }
+       sd->nAlphaTimer++;
+
+       if (sd->isUndoRedoAnimator) {
+               pThis->pAnimationData->imgUpdatePos = (double)pThis->pAnimationData->imgUpdateCount /(MAX_ANIMATION_TIME *60.0);
+               if (pThis->pAnimationData->imgUpdatePos > 1.0) {
+                       pThis->pAnimationData->imgUpdatePos = 1.0;
+               } else if (pThis->pAnimationData->imgUpdatePos < 0) {
+                       pThis->pAnimationData->imgUpdatePos = 0.0;
+               }
+               sd->m_cairo.animationUpdateImage(pThis->pAnimationData, pThis->pAnimationData->imgUpdatePos);
+               pThis->pAnimationData->imgUpdateCount++;
+               if (pThis->pAnimationData->imgUpdateCount > (pThis->pAnimationData->animationTime *60.0)) {
+                       sd->isUndoRedoAnimator = false;
+               }
+               return EINA_TRUE;
+       }
+
+       /* check moved point */
+       if (!sd->is_changed)
+       {
+               xprev = 0;
+               yprev = 0;
+               goto end;
+       } else {
+               bChange = true;
+       }
+       //WENTER();
+
+#ifdef ENABLE_ZOOM
+       if (sd->isZoomed)
+               bChange = false;
+#endif
+
+end:
+#ifdef SKETCH_DRAW_ENABLE_DRAWING_EFFECT
+       /*  animation for changing stroke color */
+       if(sd->nAlphaTimer >= MAX_ALPHA_ANIMATION_TIMER_COUNT) {
+               int nIndex1 = sd->m_selected.GetCount();
+               if (!sd->m_cairo.getNormalDrawingStatus()) {
+                       if (sd->m_selected.updateAlphaList()) {
+                               bChange = true;
+                       }
+               }
+               sd->nAlphaTimer = 0;
+       }
+#endif
+       if (bChange) {
+               // Draw again
+               evas_object_smart_changed(sd->obj);
+       }
+       return EINA_TRUE;
+}
+
+Evas_Object *Drawing::drawingAdd(Evas_Object *parent)
+{
+       WENTER();
+       Evas_Smart *smart_obj = _smartInit();
+       Evas_Object *obj;
+
+       obj = evas_object_smart_add(evas_object_evas_get(parent), smart_obj);   //create smart object.
+       evas_object_name_set(obj, "SelectLasso");
+       _pDrawingObj = obj;
+
+       WLEAVE();
+       return obj;
+}
+
+void Drawing::drawingAttach(Evas_Object *target)
+{
+       WENTER();
+
+       struct Smart_Data *sd = (struct Smart_Data *) evas_object_smart_data_get(_pDrawingObj);
+
+       if ( target == NULL )
+       {
+               WINFO("Target is NULL");
+               return ;
+       }
+       if ( sd->target != target)
+               sd->target = target;
+
+// Moved from smart add in here to improve the performance
+       WINFO("Creating ie_selectlasso");
+
+       Evas_Coord x, y, w, h;
+       evas_object_geometry_get(sd->target, &x, &y, &w, &h);
+
+       Evas *evas = evas_object_evas_get(_pDrawingObj);
+
+       // Event receiver.
+       sd->cRect.x = x;
+       sd->cRect.y = y;
+       sd->cRect.w = w;
+       sd->cRect.h = h;
+       sd->bufW = w;
+       sd->bufH = h;
+#ifdef ENABLE_ZOOM
+       sd->isZoomed = EINA_FALSE;
+       sd->Zoom = _getAutoFitZoom(sd);
+#endif
+       sd->isAutofit = false;
+       sd->nAlphaTimer = 0;
+
+       sd->maskImg = sd->m_cairo.createMaskImage(evas_object_evas_get(_pDrawingObj), w, h); // Create 360x360 image.
+       sd->img = sd->m_cairo.CreateImage(evas_object_evas_get(_pDrawingObj), w, h); // Create 360x360 image.
+       sd->sourceImg = sd->m_cairo.createSource(evas_object_evas_get(_pDrawingObj), w, h); // Create 360x360 image.
+       sd->m_cairo.createBufferImage(evas_object_evas_get(_pDrawingObj), w, h); // Create 360x360 image.
+
+#ifdef REDO_UNDO
+       if (_saveBufferCb)
+       {
+               std::vector<std::pair<double, double>> pt = sd->m_selected.GetOriginalPoints();
+               double strokeWidth = sd->m_cairo.getStrokeWidth();
+               _saveBufferCb(pt, sd->m_selected.GetOriginalstrokeList(), &(_cCurrentColor), strokeWidth, true);
+       }
+#endif
+#ifdef ENABLE_DRAGING
+       sd->mutilDown = false;
+#endif
+       WINFO(" target x,y w ,h %d %d %d %d", x, y, w, h);
+       evas_object_move(sd->img, x, y);
+       evas_object_resize(sd->img, w, h);
+       evas_object_show(sd->img);
+
+       evas_object_smart_member_add(sd->img, _pDrawingObj);
+
+       sd->m_event = evas_object_rectangle_add(evas);
+       evas_object_color_set(sd->m_event, 0, 0, 0, 0);
+       evas_object_pass_events_set(sd->m_event, EINA_FALSE);
+       evas_object_show(sd->m_event);
+
+       evas_object_smart_member_add(sd->m_event, _pDrawingObj);
+
+       evas_object_event_callback_add(sd->m_event, EVAS_CALLBACK_MOUSE_DOWN, _onMouseDown, this);
+       evas_object_event_callback_add(sd->m_event, EVAS_CALLBACK_MOUSE_UP, _onMouseUp, this);
+       evas_object_event_callback_add(sd->m_event, EVAS_CALLBACK_MOUSE_MOVE, _onMouseMove, this);
+
+#ifdef ENABLE_DRAGING
+       evas_object_event_callback_priority_add(sd->m_event, EVAS_CALLBACK_MULTI_DOWN, -100, _onMultiDown, this);
+#endif
+       evas_object_event_callback_add(sd->m_event, EVAS_CALLBACK_MULTI_MOVE, _onMultiMove, this);
+       evas_object_event_callback_add(sd->m_event, EVAS_CALLBACK_MULTI_UP, _onMultiUp, this);
+
+       sd->gesture = elm_gesture_layer_add(sd->m_event);
+       elm_gesture_layer_hold_events_set(sd->gesture, EINA_FALSE);
+
+#ifdef ENABLE_ZOOM
+       elm_gesture_layer_cb_set(sd->gesture, ELM_GESTURE_N_DOUBLE_TAPS, ELM_GESTURE_STATE_START, _onDblClickStart, this);
+       elm_gesture_layer_cb_set(sd->gesture, ELM_GESTURE_N_DOUBLE_TAPS, ELM_GESTURE_STATE_END, _onDblClickEnd, this);
+       elm_gesture_layer_cb_set(sd->gesture, ELM_GESTURE_N_DOUBLE_TAPS, ELM_GESTURE_STATE_ABORT, _onDblClickAbort, this);
+#endif
+
+       elm_gesture_layer_cb_set(sd->gesture, ELM_GESTURE_N_TAPS, ELM_GESTURE_STATE_END, _onTapEnd, this);
+
+       if (elm_gesture_layer_attach(sd->gesture, sd->m_event) == EINA_FALSE) {
+               WERROR("error to attach");
+       }
+
+       ecore_animator_frametime_set(1.0/60.0);
+       sd->anim = ecore_animator_add(_onAnimatorUpdate, this);
+       pAnimationData = (animationData *)calloc(1, sizeof(animationData));
+       if (pAnimationData == nullptr)
+       {
+               WINFO("Memory Allocation Failed!!");
+               return;
+       }
+       pAnimationData->isDrawing = false;
+       pAnimationData->nBgPatternAlpha = 0;
+       pAnimationData->drawingAnimator = nullptr;
+       sd->isUndoRedoAnimator = false;
+       // Set initial position
+       sd->oRect.x = x ;
+       sd->oRect.y = y;
+       sd->oRect.w = w;
+       sd->oRect.h = h;
+       sd->is_changed = false;
+       sd->bMultiMove = false;
+       evas_object_smart_changed(sd->obj);
+
+       WLEAVE();
+}
+
+void Drawing::clearImage()
+{
+       struct Smart_Data *sd = (struct Smart_Data *) evas_object_smart_data_get(_pDrawingObj);
+       sd->m_cairo.clearImage();
+}
+
+void Drawing::drawingColorSet(std::string colorCode, bool isEraser)
+{
+       WENTER();
+
+       _cCurrentColor.drawingColorSet(colorCode, isEraser);
+       struct Smart_Data *sd = (struct Smart_Data *) evas_object_smart_data_get(_pDrawingObj);
+
+       sd->m_cairo.SetDrawingProperty(&_cCurrentColor);
+       WLEAVE();
+}
+
+DrawingColor Drawing::getCurrentColor()
+{
+       return _cCurrentColor;
+}
+
+void Drawing::saveDrawingImage(std::string& filePath)
+{
+       struct Smart_Data *sd = (struct Smart_Data *) evas_object_smart_data_get(_pDrawingObj);
+
+       sd->m_cairo.SaveDrawingImage(filePath);
+}
+
+void Drawing::addMouseEvent()
+{
+       struct Smart_Data *sd = (struct Smart_Data *) evas_object_smart_data_get(_pDrawingObj);
+
+       WINFO("Remove mouse event");
+       evas_object_event_callback_add(sd->m_event, EVAS_CALLBACK_MOUSE_DOWN, _onMouseDown, this);
+       evas_object_event_callback_add(sd->m_event, EVAS_CALLBACK_MOUSE_UP, _onMouseUp, this);
+       evas_object_event_callback_add(sd->m_event, EVAS_CALLBACK_MOUSE_MOVE, _onMouseMove, this);
+#ifdef ENABLE_DRAGING
+       evas_object_event_callback_priority_add(sd->m_event, EVAS_CALLBACK_MULTI_DOWN, -100, _onMultiDown, this);
+       evas_object_event_callback_add(sd->m_event, EVAS_CALLBACK_MULTI_MOVE, _onMultiMove, this);
+       evas_object_event_callback_add(sd->m_event, EVAS_CALLBACK_MULTI_UP, _onMultiUp, this);
+#endif
+}
+
+void Drawing::delMouseEvent()
+{
+       struct Smart_Data *sd = (struct Smart_Data *) evas_object_smart_data_get(_pDrawingObj);
+
+       WINFO("Remove mouse event");
+       /* Remove Mouse Event Callbacks */
+       evas_object_event_callback_del(sd->m_event, EVAS_CALLBACK_MOUSE_DOWN, _onMouseDown);
+       evas_object_event_callback_del(sd->m_event, EVAS_CALLBACK_MOUSE_UP, _onMouseUp);
+       evas_object_event_callback_del(sd->m_event, EVAS_CALLBACK_MOUSE_MOVE, _onMouseMove);
+#ifdef ENABLE_DRAGING
+       evas_object_event_callback_del(sd->m_event, EVAS_CALLBACK_MULTI_DOWN, _onMultiDown);
+       evas_object_event_callback_del(sd->m_event, EVAS_CALLBACK_MULTI_MOVE, _onMultiMove);
+       evas_object_event_callback_del(sd->m_event, EVAS_CALLBACK_MULTI_UP, _onMultiUp);
+#endif
+}
+
+void Drawing::setDeleteSaveTimerCb(std::function < void(void) > handlerFunc)
+{
+       _deleteSaveTimerCb = handlerFunc;
+}
+
+void Drawing::setColorMenuStateCb(std::function < bool(void) > handlerFunc)
+{
+       _colorMenuStateCb = handlerFunc;
+}
+
+void Drawing::setSaveStateCb(std::function < void(bool) > handlerFunc)
+{
+       _saveStateCb = handlerFunc;
+}
+
+void Drawing::setSetMaxHistoryCb(std::function < void(bool) > handlerFunc)
+{
+       setMaxHistoryCb = handlerFunc;
+}
+
+
+void Drawing::setAddSaveTimerCb(std::function < void(void) > handlerFunc)
+{
+       _addSaveTimerCb = handlerFunc;
+}
+
+void Drawing::setStrokeWidth(double dWidth)
+{
+       struct Smart_Data *sd = (struct Smart_Data *) evas_object_smart_data_get(_pDrawingObj);
+
+       sd->m_cairo.setStrokeWidth(dWidth);
+}
+
+void Drawing::setShowPanelCb(std::function < void(void) > handlerFunc)
+{
+       _showPanelCb = handlerFunc;
+}
+
+void Drawing::setGetBufferCb(std::function < void(int curIndex, std::vector<std::pair<double, double>> &buffer, std::vector<int>& strokeList, DrawingColor* pColor, double *width) > handlerFunc)
+{
+       _getBufferCb = handlerFunc;
+}
+
+#ifdef REDO_UNDO
+void Drawing::setCheckFirstIndexCb(std::function < bool(void) > handlerFunc)
+{
+       checkFirstIndexCb = handlerFunc;
+}
+
+void Drawing::setSaveBufferCb(std::function < void(std::vector<std::pair<double, double>> pt1, std::vector<int>* pStrokeList, DrawingColor* pColor, double strokeWidth, bool increaseIndex) > handlerFunc)
+{
+       _saveBufferCb = handlerFunc;
+}
+
+bool Drawing::getDrawingStatus()
+{
+       return pAnimationData->isDrawing;
+}
+
+drawMode Drawing::getDrawingMode()
+{
+       return pAnimationData->mode;
+}
+
+void Drawing::getAnimatorTime(double *time)
+{
+       *time = pAnimationData->animationTime;
+}
+
+bool Drawing::updateBuffer(std::vector<std::pair<double, double>> &pt1, std::vector<int>& strokeList, DrawingColor pColor, double strokeWidth, drawMode mode)
+{
+       struct Smart_Data *sd = (struct Smart_Data *) evas_object_smart_data_get(_pDrawingObj);
+       int x, y, w, h;
+
+       std::vector<std::pair<double, double>> pt = sd->m_selected.GetHistoryPoints(pt1);
+
+       evas_object_geometry_get(sd->img, &x, &y, &w, &h);
+
+       if (mode == NORMAL_DRAW) {
+               sd->m_cairo.SetHistoryDrawingProperty(sd->m_cairo._maskCr, pColor, strokeWidth);
+               pAnimationData->isDrawing = false;
+           sd->m_cairo.Draw(sd->m_cairo._maskCr, pt, strokeList,
+                    (double)sd->bufW / (double)w,
+                    (double)sd->bufH/ (double)h,
+                    w, h);
+       } else {
+               pAnimationData->rw = (double)sd->bufW / (double)w;
+               pAnimationData->rh = (double)sd->bufH / (double)h;
+               pAnimationData->w = w;
+               pAnimationData->h = h;
+               pAnimationData->cr = sd->m_cairo._cr;
+               pAnimationData->image = sd->m_cairo._image;
+               pAnimationData->strokeWidth = sd->m_cairo._strokeWidth;
+               pAnimationData->pColor = pColor;
+               pAnimationData->pt = pt;
+               pAnimationData->strokeList = strokeList;
+               pAnimationData->mode = mode;
+               pAnimationData->isDrawing = true;
+               pAnimationData->sourceCr = sd->m_cairo._sourceCr;
+               pAnimationData->sourceSurface = sd->m_cairo._sourceSurface;
+               pAnimationData->maskSurface = sd->m_cairo._maskSurface;
+               pAnimationData->pCairo = &sd->m_cairo;
+
+               double drawSpeed = DRAW_SPEED;
+               pAnimationData->animationTime = (double)pt.size() / drawSpeed;
+               sd->m_cairo.SetHistoryDrawingProperty(sd->m_cairo._sourceCr, pColor, strokeWidth);
+               if (pt.size() <= DRAW_POINTS) {
+                       pAnimationData->isMaxAnimation = false;
+                       pAnimationData->animationTime += MIN_ANIMATION_TIME;
+                       pAnimationData->drawingAnimator = ecore_animator_timeline_add(pAnimationData->animationTime, sd->m_cairo.animationDraw, (void *)pAnimationData);
+               } else {
+                       pAnimationData->isMaxAnimation = true;
+                       pAnimationData->animationTime = MAX_ANIMATION_TIME;
+                       pAnimationData->drawingAnimator = ecore_animator_timeline_add(MAX_ANIMATION_TIME, sd->m_cairo.animationDraw, (void *)pAnimationData);
+               }
+       }
+       return true;
+}
+
+#endif
+
+void Drawing::sourceUpdate(drawMode mode)
+{
+       struct Smart_Data *sd = (struct Smart_Data *) evas_object_smart_data_get(_pDrawingObj);
+       sd->m_cairo.sourceUpdate(mode);
+}
+
+void Drawing::maskUpdate(drawMode mode)
+{
+       struct Smart_Data *sd = (struct Smart_Data *) evas_object_smart_data_get(_pDrawingObj);
+       sd->m_cairo.maskUpdate(mode);
+}
+
+void Drawing::clearMask()
+{
+       struct Smart_Data *sd = (struct Smart_Data *) evas_object_smart_data_get(_pDrawingObj);
+       sd->m_cairo.clearMask();
+}
+
+void Drawing::clearSource()
+{
+       struct Smart_Data *sd = (struct Smart_Data *) evas_object_smart_data_get(_pDrawingObj);
+       sd->m_cairo.clearSource();
+}
+
+void Drawing::resetIsDrawing()
+{
+       pAnimationData->isDrawing = false;
+}
+
+void Drawing::animationUpdateImage(drawMode mode, Evas_Object *bgPattern)
+{
+       struct Smart_Data *sd = (struct Smart_Data *) evas_object_smart_data_get(_pDrawingObj);
+
+       if (mode == NORMAL_DRAW) {
+               sd->isUndoRedoAnimator = false;
+               return;
+       }
+
+       pAnimationData->mode = mode;
+       pAnimationData->sourceCr = sd->m_cairo._sourceCr;
+       pAnimationData->sourceSurface = sd->m_cairo._sourceSurface;
+       pAnimationData->cr = sd->m_cairo._cr;
+       pAnimationData->image = sd->m_cairo._image;
+       pAnimationData->bgPattern = bgPattern;
+       if (mode == UNDO_DRAW) {
+               pAnimationData->isDrawing = true;
+               pAnimationData->animationTime = MAX_ANIMATION_TIME;
+               pAnimationData->imgUpdatePos = 0;
+               pAnimationData->imgUpdateCount = 0;
+               pAnimationData->isImgAnimateDraw = true;
+               sd->isUndoRedoAnimator = true;
+               //pAnimationData->drawingAnimator = ecore_animator_timeline_add(MAX_ANIMATION_TIME,sd->m_cairo.animationUpdateImage,pAnimationData);
+       } else if (mode == REDO_DRAW) {
+               sd->isUndoRedoAnimator = false;
+               pAnimationData->isDrawing = false;
+               pAnimationData->animationTime = 0;
+               sd->m_cairo.animationUpdateImage(pAnimationData, 0);
+       }
+}
+
+void Drawing::updateBufferImage(int index)
+{
+       struct Smart_Data *sd = (struct Smart_Data *) evas_object_smart_data_get(_pDrawingObj);
+       std::vector<std::pair<double, double>> pt1;
+       std::vector<int> strokeList;
+       DrawingColor pColor;
+       double strokeWidth;
+       pt1.clear();
+       if (_getBufferCb) {
+               _getBufferCb(index, pt1, strokeList, &pColor, &strokeWidth);
+       }
+       //sd->m_cairo.updateBufferImage(pt1,pColor,strokeWidth,sd);
+       if (!pt1.empty()) {
+               int x, y, w, h;
+               evas_object_geometry_get(sd->img, &x, &y, &w, &h);
+               std::vector<std::pair<double, double>> pt = sd->m_selected.GetHistoryPoints(pt1);
+               sd->m_cairo.SetHistoryDrawingProperty(sd->m_cairo._bufferCr, pColor, strokeWidth);
+               sd->m_cairo.Draw(sd->m_cairo._bufferCr, pt, strokeList,
+                    (double)sd->bufW / (double)w,
+                    (double)sd->bufH / (double)h,
+                    w, h);
+       }
+}
+
+
+Evas_Object* Drawing::getDrawImgObj()
+{
+       struct Smart_Data *sd = (struct Smart_Data *) evas_object_smart_data_get(_pDrawingObj);
+       return sd->img;
+}
+
+void Drawing::setBgType(std::string& bgType)
+{
+       struct Smart_Data *sd = (struct Smart_Data *) evas_object_smart_data_get(_pDrawingObj);
+       sd->m_cairo.setBgType(bgType);
+}
+
+void Drawing::setStopNormalDrawing(bool bDoding)
+{
+       struct Smart_Data *sd = (struct Smart_Data *) evas_object_smart_data_get(_pDrawingObj);
+       sd->m_cairo.setStopNormalDrawing(bDoding);
+}
+
+void  Drawing::restorePoints(std::vector<std::pair<double, double> > &pt)
+{
+       struct Smart_Data *sd = (struct Smart_Data *) evas_object_smart_data_get(_pDrawingObj);
+       /* erase uncompleted white lines */
+       sd->m_cairo.eraseDraw(sd->m_selected, (double)sd->bufW / (double)sd->oRect.w,
+                    (double)sd->bufH / (double)sd->oRect.h,
+                   sd->oRect.w, sd->oRect.h);
+
+       sd->m_selected.restorePoints(pt);
+}
+
+void Drawing::activateUpdateAnimator(bool bActivate)
+{
+       struct Smart_Data *sd = (struct Smart_Data *) evas_object_smart_data_get(_pDrawingObj);
+       if (sd == nullptr) {
+               return;
+       }
+
+       if (!bActivate) {
+               ecore_animator_freeze(sd->anim);
+       } else {
+               ecore_animator_thaw(sd->anim);
+       }
+}
+
+bool Drawing::isDrawingStatus()
+{
+       struct Smart_Data *sd = (struct Smart_Data *) evas_object_smart_data_get(_pDrawingObj);
+       if (sd == nullptr) {
+               return false;
+       }
+       return sd->bMouseDown;
+}
+
+int Drawing::getPatternBgAlpha()
+{
+       return pAnimationData->nBgPatternAlpha;
+}
+
diff --git a/src/controls/Drawing.h b/src/controls/Drawing.h
new file mode 100755 (executable)
index 0000000..d6c31f1
--- /dev/null
@@ -0,0 +1,159 @@
+#ifndef __DRAWING_H__
+#define __DRAWING_H__
+
+
+#include "CDrCairoImage.h"
+
+
+
+
+struct Smart_Data {
+       Evas_Object *obj;               // Smart object itself
+       Evas_Object *target;            // Attached object.
+       Evas_Object *m_event;
+       Evas_Object *gesture;
+       Rect cRect;
+       Rect oRect;
+       Evas_Object *img;
+       Evas_Object *maskImg;
+       Evas_Object *sourceImg;
+#ifdef ENABLE_ZOOM
+       Eina_Bool isZoomed;
+       double Zoom;        // Current zoom level
+       int xClick;
+       int yClick;
+#endif
+       CCairoImage m_cairo;
+       CLasso m_selected;
+       bool bMouseDown;                // Indicator for mouse down
+       bool bFirstMove;
+       bool bShow;
+       bool is_changed;
+       bool isUndoRedoAnimator;
+#ifdef REDO_UNDO
+       bool isMoved;
+#endif
+#ifdef ENABLE_DRAGING
+       bool mutilDown;
+       int xMutilPrev, yMutilPrev;
+#endif
+       bool bMultiMove;
+       int bufW, bufH; // Image buffer size
+       Ecore_Animator *anim;
+       int xPrev, yPrev;
+       int xLatest, yLatest;
+       int mouseDownX, mouseDownY;
+       unsigned int prevTimestamp, latestTimestamp;
+       double vsyncTimestamp;
+       bool isAutofit;
+       int nAlphaTimer;
+};
+
+
+class Drawing
+{
+public:
+       Drawing();
+       ~Drawing();
+       Evas_Object *drawingAdd(Evas_Object *parent);
+       void drawingAttach(Evas_Object *target);
+       void drawingColorSet(std::string colorCode, bool isEraser);
+       DrawingColor getCurrentColor();
+       void saveDrawingImage(std::string& fileName);
+       void addMouseEvent();
+       void delMouseEvent();
+       void setDeleteSaveTimerCb(std::function < void(void) > handlerFunc);
+       void setColorMenuStateCb(std::function < bool(void) > handlerFunc);
+       void setSaveStateCb(std::function < void(bool) > handlerFunc);
+       void setSetMaxHistoryCb(std::function < void(bool) > handlerFunc);
+       void setAddSaveTimerCb(std::function < void(void) > handlerFunc);
+       void setShowPanelCb(std::function < void(void) > handlerFunc);
+       void setGetBufferCb(std::function < void(int curIndex, std::vector<std::pair<double, double>> &buffer, std::vector<int>& strokeList, DrawingColor* pColor, double *width) > handlerFunc);
+       Evas_Object* getDrawImgObj();
+
+       void setStrokeWidth(double dWidth);
+       void setBgType(std::string& bgType);
+       void activateUpdateAnimator(bool bActivate);
+       drawMode getDrawingMode();
+       void getAnimatorTime(double *time);
+       void sourceUpdate(drawMode mode);
+       void maskUpdate(drawMode mode);
+       void clearSource();
+       void clearMask();
+       void updateBufferImage(int index);
+       void resetIsDrawing();
+       bool isDrawingStatus();
+
+       std::function < void(int curIndex, std::vector<std::pair<double, double>> &buffer, std::vector<int>& strokeList, DrawingColor* pColor, double *width) > _getBufferCb;
+#ifdef REDO_UNDO
+       void setSaveBufferCb(std::function < void(std::vector<std::pair<double, double>> pt1, std::vector<int>* pStrokeList, DrawingColor* pColor, double strokeWidth, bool increaseIndex) > handlerFunc);
+       bool updateBuffer(std::vector<std::pair<double, double>> &pt1, std::vector<int>& strokeList, DrawingColor pColor, double strokeWidth, drawMode mode);
+       void setCheckFirstIndexCb(std::function < bool() > handlerFunc);
+       std::function < bool(void) > checkFirstIndexCb;
+       bool getDrawingStatus();
+       bool getAnimationStatus();
+#endif
+       void clearImage();
+
+       void setStopNormalDrawing(bool bDoding);
+       void restorePoints(std::vector<std::pair<double, double> > &pt);
+       void animationUpdateImage(drawMode mode, Evas_Object *bgPattern);
+       int getPatternBgAlpha();
+       bool isMouseMoving();
+
+private:
+       static void _onMouseDown(void *data, Evas *e, Evas_Object *evas_obj, void *event_info);
+       static void _onMouseMove(void *data, Evas *e, Evas_Object *evas_obj, void *event_info);
+       static void _onMouseUp(void *data, Evas *e, Evas_Object *evas_obj, void *event_info);
+       bool _addDrawPoint();
+
+#ifdef ENABLE_ZOOM
+       static Evas_Event_Flags _onDblClickStart(void *data , void *event_info);
+       static Evas_Event_Flags _onDblClickEnd(void *data , void *event_info);
+       static Evas_Event_Flags _onDblClickAbort(void *data , void *event_info);
+#endif
+
+#ifdef ENABLE_DRAGING
+       static void _onMultiDown(void *data, Evas *e, Evas_Object *evas_obj, void *event_info);
+#endif
+       static void _onMultiMove(void *data, Evas *e, Evas_Object *evas_obj, void *event_info);
+       static void _onMultiUp(void *data, Evas *e, Evas_Object *evas_obj, void *event_info);
+       static Evas_Event_Flags _onTapEnd(void *data , void *event_info);
+
+       static void _smartAdd(Evas_Object *obj);
+       static void _smartDel(Evas_Object *obj);
+       static void _smartMove(Evas_Object *obj, Evas_Coord x, Evas_Coord y);
+       static void _smartResize(Evas_Object *obj, Evas_Coord w, Evas_Coord h);
+       static void _smartShow(Evas_Object *obj);
+       static void _smartHide(Evas_Object *obj);
+       static void _smartCalculate(Evas_Object *obj);
+       static Evas_Smart *_smartInit(void);
+       static Eina_Bool _onAnimatorUpdate(void *data);
+
+#ifdef ENABLE_ZOOM
+       static void _Draw(void *data, int fx, int fy, int fw, int fh);
+       static Eina_Bool _DoZoom(void *data, double pos);
+       static double _getAutoFitZoom(struct Smart_Data *sd);
+#endif
+
+public:
+       struct animationData *pAnimationData;
+private:
+       Evas_Object *_pDrawingObj;
+       DrawingColor _cCurrentColor;
+
+       static int _mTouchMode;
+       std::function < void(void) > _deleteSaveTimerCb;
+       std::function < bool(void) > _colorMenuStateCb;
+       std::function < void(bool) > _saveStateCb;
+       std::function < void(bool) > setMaxHistoryCb;
+       std::function < void(void) > _addSaveTimerCb;
+       std::function < void(void) > _showPanelCb;
+#ifdef REDO_UNDO
+       std::function < void(std::vector<std::pair<double, double>> pt1, std::vector<int>* strokeList, DrawingColor* pColor, double strokeWidth, bool increaseIndex) > _saveBufferCb;
+#endif
+};
+
+#endif // __DRAWING_H__
+
+
diff --git a/src/controls/History.cpp b/src/controls/History.cpp
new file mode 100755 (executable)
index 0000000..de790e7
--- /dev/null
@@ -0,0 +1,234 @@
+#include "History.h"
+#include "DrDefine.h"
+#include <stdlib.h>
+
+
+History::History()
+: _pcycleQueue(nullptr),
+  index(-1),
+  isMaxHistory(false),
+  firstIndex(0),
+  _updateBufferImageCb(nullptr)
+{
+       _initBufferPooling();
+}
+
+History::~History()
+{
+       _deleteBufferPooling();
+}
+
+bool History::getMaxHistory()
+{
+       return isMaxHistory;
+}
+
+void History::setMaxHistory(bool status)
+{
+       structImage *intermediateBuffer;
+       isMaxHistory = status;
+       _pcycleQueue->front = index % MAX_HISTORY;
+       firstIndex = _pcycleQueue->front;
+       intermediateBuffer = &(_pcycleQueue->_bufferPooling[_pcycleQueue->front]);
+       intermediateBuffer->point.clear();
+}
+
+bool History::checkFirstIndex()
+{
+       if ((index % MAX_HISTORY == firstIndex) /*|| index  == 0*/) {
+               return true;
+       } else {
+               return false;
+       }
+}
+
+bool History::checkLastIndex()
+{
+       if (((index % MAX_HISTORY)) == _pcycleQueue->rear - 1) {
+               return true;
+       } else {
+               return false;
+       }
+}
+
+
+void History::saveBuffer(std::vector<std::pair<double, double>> &pt1, std::vector<int>* pStrokeList, DrawingColor* pColor, double drawingWidth, bool increaseIndex)
+{
+       structImage *intermediateBuffer;
+
+       if (increaseIndex && _fullQueue())
+       {
+               isMaxHistory = true;
+               if (_updateBufferImageCb) {
+                       _updateBufferImageCb(_pcycleQueue->front);
+               }
+               firstIndex = _pcycleQueue->front;
+               _pcycleQueue->front = (_pcycleQueue->front + 1) % MAX_HISTORY;
+       }
+       if (increaseIndex)
+               index++;
+
+       intermediateBuffer = &(_pcycleQueue->_bufferPooling[index % MAX_HISTORY]);
+       intermediateBuffer->point.clear();
+       _pcycleQueue->rear = (index + 1) % MAX_HISTORY;
+       for (std::vector<std::pair<double, double>>::const_iterator iter = pt1.begin();
+               iter != pt1.end(); ++iter) {
+               intermediateBuffer->point.push_back(std::make_pair(iter->first, iter->second));
+       }
+       intermediateBuffer->strokeWidthList.clear();
+       intermediateBuffer->strokeWidthList = (*pStrokeList);
+
+       intermediateBuffer->_cCurrentColor.r = pColor->r;
+       intermediateBuffer->_cCurrentColor.g = pColor->g;
+       intermediateBuffer->_cCurrentColor.b = pColor->b;
+       intermediateBuffer->_cCurrentColor.a = pColor->a;
+       intermediateBuffer->_cCurrentColor.is_eraser = pColor->is_eraser;
+       intermediateBuffer->strokeWidth = drawingWidth;
+
+       WINFO("Set history front:%d index:%d rear:%d first:%d", _pcycleQueue->front, index, _pcycleQueue->rear, firstIndex);
+}
+
+bool History::redo(std::vector<std::pair<double, double>> &buffer, std::vector<int>& strokeList, DrawingColor* pColor, double *strokeWidth)
+{
+       if (((index + 1) % MAX_HISTORY) == _pcycleQueue->rear) {
+               WINFO("Already in last index,can not redo");
+               return false;
+       }
+       index++;
+       WINFO("Redo index:%d", index);
+       _getOutputBuffer(buffer, strokeList, pColor, strokeWidth);
+       return true;
+}
+
+bool History::undo(int *undoStart, int *undoEnd)
+{
+       if (index % MAX_HISTORY == firstIndex) {
+               WINFO("Already in first index,clear all");
+               return false;
+       }
+       *undoStart = _pcycleQueue->front;
+       *undoEnd = index;
+       index--;
+       WINFO("Undo index:%d", index);
+       if (index % MAX_HISTORY == firstIndex) {
+               WINFO("Already in first index,clear all");
+               return false;
+       }
+       return true;
+}
+
+bool History::_fullQueue()
+{
+       if (_pcycleQueue->front == (index + 2) % MAX_HISTORY)
+               return true;
+       else
+               return false;
+}
+
+void History::_deleteBufferPooling()
+{
+       if (_pcycleQueue == nullptr) {
+               WINFO("Memory Allocation Failed!!");
+               return;
+       }
+
+       free(_pcycleQueue->_bufferPooling);
+       _pcycleQueue->_bufferPooling = nullptr;
+
+       free(_pcycleQueue);
+       _pcycleQueue = nullptr;
+}
+
+void History::_getOutputBuffer(int curIndex, std::vector<std::pair<double, double>> &buffer, std::vector<int>& strokeList, DrawingColor* pColor, double *width)
+{
+       structImage     *lastestSavedImage = nullptr;
+       int num_bytes;
+       lastestSavedImage = &(_pcycleQueue->_bufferPooling[curIndex]);
+       if (lastestSavedImage == nullptr) {
+               WINFO("get buffer failed");
+       }
+       for (std::vector<std::pair<double, double>>::const_iterator iter1 = lastestSavedImage->point.begin();
+               iter1 != lastestSavedImage->point.end(); ++iter1) {
+               buffer.push_back(std::make_pair(iter1->first, iter1->second));
+       }
+       strokeList = lastestSavedImage->strokeWidthList;
+
+       (*pColor).r = lastestSavedImage->_cCurrentColor.r;
+       (*pColor).g = lastestSavedImage->_cCurrentColor.g;
+       (*pColor).b = lastestSavedImage->_cCurrentColor.b;
+       (*pColor).a = lastestSavedImage->_cCurrentColor.a;
+       (*pColor).is_eraser = lastestSavedImage->_cCurrentColor.is_eraser;
+       *width = lastestSavedImage->strokeWidth;
+}
+
+void History::_getOutputBuffer(std::vector<std::pair<double, double>> &buffer, std::vector<int>& strokeList, DrawingColor* pColor, double *width)
+{
+       structImage     *lastestSavedImage = nullptr;
+       int num_bytes;
+       lastestSavedImage = &(_pcycleQueue->_bufferPooling[index % MAX_HISTORY]);
+       if (lastestSavedImage == nullptr) {
+               WINFO("get buffer failed");
+       }
+       for (std::vector<std::pair<double, double>>::const_iterator iter1 = lastestSavedImage->point.begin();
+               iter1 != lastestSavedImage->point.end(); ++iter1) {
+               buffer.push_back(std::make_pair(iter1->first, iter1->second));
+       }
+       strokeList = lastestSavedImage->strokeWidthList;
+
+       (*pColor).r = lastestSavedImage->_cCurrentColor.r;
+       (*pColor).g = lastestSavedImage->_cCurrentColor.g;
+       (*pColor).b = lastestSavedImage->_cCurrentColor.b;
+       (*pColor).a = lastestSavedImage->_cCurrentColor.a;
+       (*pColor).is_eraser = lastestSavedImage->_cCurrentColor.is_eraser;
+       *width = lastestSavedImage->strokeWidth;
+}
+
+void History::_initBufferPooling()
+{
+       _pcycleQueue = (cycleQueue *)calloc(1, sizeof(cycleQueue));
+
+       if (_pcycleQueue == nullptr)
+       {
+               WINFO("Memory Allocation Failed!!");
+               return;
+       }
+
+       _pcycleQueue->_bufferPooling = (structImage *)calloc(1, sizeof(structImage) * MAX_HISTORY);
+       if (_pcycleQueue->_bufferPooling == nullptr)
+       {
+               WINFO("Memory Allocation Failed!!");
+               free(_pcycleQueue);
+               _pcycleQueue = nullptr;
+               return;
+       }
+       _pcycleQueue->front = 0;
+       _pcycleQueue->rear = 0;
+}
+
+void History::setClearCb(std::function < void(void) > handlerFunc)
+{
+       _clearCb = handlerFunc;
+}
+
+void History::setUpdateBufferImageCb(std::function < void(int index) > handlerFunc)
+{
+       _updateBufferImageCb = handlerFunc;
+}
+
+int  History::getCurIndex()
+{
+       return index;
+}
+
+int History::getCount()
+{
+       if (_pcycleQueue == nullptr)
+       {
+               WINFO("Memory Allocation Failed!!");
+               return 0;
+       }
+       if (index % MAX_HISTORY >= firstIndex)
+               return index % MAX_HISTORY - firstIndex + 1;
+       else
+               return MAX_HISTORY - firstIndex + index % MAX_HISTORY + 1;
+}
diff --git a/src/controls/History.h b/src/controls/History.h
new file mode 100755 (executable)
index 0000000..8c638b1
--- /dev/null
@@ -0,0 +1,59 @@
+#ifndef __HISTORY_H__
+#define __HISTORY_H__
+#include <functional>
+#include "Drawing.h"
+
+typedef struct
+{
+       double strokeWidth;
+       DrawingColor _cCurrentColor;
+       std::vector<std::pair<double, double>> point;
+       std::vector<int> strokeWidthList;
+} structImage;
+
+typedef struct
+{
+       structImage *_bufferPooling;
+       int front;
+       int rear;
+}cycleQueue;
+
+class History
+{
+public:
+       History();
+       ~History();
+       void saveBuffer(std::vector<std::pair<double, double>> &pt1, std::vector<int>* pStrokeList, DrawingColor* pColor, double drawingWidth, bool increaseIndex);
+       bool redo(std::vector<std::pair<double, double>> &buffer, std::vector<int>& strokeList, DrawingColor* pColor, double *strokeWidth);
+       bool redo(int *redoStart, int *redoEnd);
+       bool undo(int *undoStart, int *undoEnd);
+
+       bool checkFirstIndex();
+       bool checkLastIndex();
+       void setClearCb(std::function < void(void) > handlerFunc);
+       void setUpdateBufferImageCb(std::function < void(int index) > handlerFunc);
+       int  getCurIndex();
+       int  getCount();
+    void _getOutputBuffer(int curIndex, std::vector<std::pair<double, double>> &buffer, std::vector<int>& strokeList, DrawingColor* pColor, double *width);
+       bool getMaxHistory();
+       void setMaxHistory(bool status);
+
+private:
+       void _initBufferPooling();
+       void _deleteBufferPooling();
+       void _getOutputBuffer(std::vector<std::pair<double, double>> &buffer, std::vector<int>& strokeList, DrawingColor* pColor, double *width);
+       bool _fullQueue();
+       bool isMaxHistory;
+       int firstIndex;
+private:
+       History(const History&) = delete;
+       const History& operator = (const History&) = delete;
+
+       cycleQueue *_pcycleQueue;
+       int index;
+       std::function < void(void) > _clearCb;
+       std::function < void(int index) > _updateBufferImageCb;
+};
+
+#endif // __HISTORY_H__
+
diff --git a/src/main.cpp b/src/main.cpp
new file mode 100755 (executable)
index 0000000..3dccccc
--- /dev/null
@@ -0,0 +1,15 @@
+
+#include "DrDebug.h"
+#include "CDrApp.h"
+
+WAPP_ASSIST_EXPORT int main(int argc, char *argv[])
+{
+       WENTER();
+       CDrApp app;
+       int ret = app.start(argc, argv);
+
+       WDEBUG("app return=%d", ret);
+       WLEAVE();
+       return ret;
+}
+
diff --git a/src/popup/CDrClosePopup.cpp b/src/popup/CDrClosePopup.cpp
new file mode 100755 (executable)
index 0000000..3e1c5d7
--- /dev/null
@@ -0,0 +1,121 @@
+#include <Elementary.h>
+#include <app.h>
+//#include <ui_extension.h>
+#include <Elementary.h>
+#include  "CDrClosePopup.h"
+#include "DrDefine.h"
+#include "DrDebug.h"
+
+CDrClosePopup::CDrClosePopup()
+{
+       _discardResultHandler = nullptr;
+       _cancelResultHandler = nullptr;
+}
+
+CDrClosePopup::~CDrClosePopup()
+{
+}
+
+void CDrClosePopup::setCaption(const char *title)
+{
+       setTitle(title);
+}
+
+void CDrClosePopup::setOnDiscardResult(std::function < void() > handlerFunc)
+{
+       _discardResultHandler = handlerFunc;
+}
+
+void CDrClosePopup::setOnCancelResult(std::function < void() > handlerFunc)
+{
+       _cancelResultHandler = handlerFunc;
+}
+
+
+Evas_Object *CDrClosePopup::onCreateView(Evas_Object * parent, void *viewParam)
+{
+       WENTER();
+       setTextTranslatable(LOCALE_DOMAIN);
+       setContent([this] (Evas_Object * parent)->Evas_Object * {
+                          return _createContent(parent);
+                          }
+       );
+
+       setOnAddProperties([&](Evas_Object* popup){
+               elm_object_style_set(popup, "circle");
+//             uxt_popup_set_rotary_event_enabled(popup, EINA_FALSE);
+               });
+
+       addButton(DRAWING_POPUP_DISCARD_CANCEL_BUTTON, [this] (bool * destroyPopup) {
+                               if (_cancelResultHandler) {
+                                 _cancelResultHandler();
+                               }
+                               *destroyPopup = true;
+                         }, [&](Evas_Object* button) {
+                               elm_object_style_set(button , "popup/circle/left");
+                               Evas_Object* icon = elm_image_add(button);
+                               char* res_path = app_get_resource_path();
+                               std::string strIcon(res_path);
+                               strIcon += CLOSE_POPUP_CANCEL_ICON;
+                               elm_image_file_set(icon, strIcon.c_str(), NULL);
+                               free(res_path);
+                               evas_object_size_hint_weight_set(icon, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+                               elm_object_part_content_set(button, "elm.swallow.content", icon);
+                               evas_object_show(icon);
+                         });
+
+       addButton(DRAWING_POPUP_DISCARD_DISCARD_BUTTON, [&](bool * destroyPopup) {
+                         if (_discardResultHandler) {
+                             _discardResultHandler();
+                         }
+                         *destroyPopup = true;
+                         }, [&](Evas_Object* button) {
+                               elm_object_style_set(button , "popup/circle/right");
+                               Evas_Object* icon = elm_image_add(button);
+                               char* res_path = app_get_resource_path();
+                               std::string strIcon(res_path);
+                               strIcon += CLOSE_POPUP_DISCARD_ICON;
+                               elm_image_file_set(icon, strIcon.c_str(), NULL);
+                               free(res_path);
+                               evas_object_size_hint_weight_set(icon, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+                               elm_object_part_content_set(button, "elm.swallow.content", icon);
+                               evas_object_show(icon);
+                         });
+
+       setOnBack([this] (bool * destroyPopup) {
+                               if (_cancelResultHandler) {
+                                 _cancelResultHandler();
+                               }
+                         *destroyPopup = true;}
+       );
+
+
+       Evas_Object *popup = WPopupController::onCreateView(parent, viewParam);
+
+       return popup;
+}
+
+void CDrClosePopup::onDestroy()
+{
+}
+
+Evas_Object *CDrClosePopup::_createContent(Evas_Object * parent)
+{
+       char* _path = app_get_resource_path();
+       std::string path(_path);
+       path += EDJ_POPUP_CUSTOM_FILE;
+
+       Evas_Object* layout = elm_layout_add(parent);
+       elm_layout_file_set(layout, path.c_str(), "close_popup");
+       free(_path);
+
+       elm_object_domain_translatable_part_text_set(layout, "discard.text.content", LOCALE_DOMAIN, DRAWING_STRING_ID_POPUP_DISCARD_CONTENT);
+       //elm_object_part_text_set(layout, "discard.text.content", DRAWING_POPUP_DISCARD_CONTENT);
+
+       elm_object_content_set(parent, layout);
+
+       evas_object_show(parent);
+
+       return layout;
+}
+
diff --git a/src/popup/CDrClosePopup.h b/src/popup/CDrClosePopup.h
new file mode 100755 (executable)
index 0000000..caf035a
--- /dev/null
@@ -0,0 +1,34 @@
+
+#ifndef _CDR_CLOSE_POPUP_H_
+#define _CDR_CLOSE_POPUP_H_
+#include "WPopupController.h"
+#include <string>
+#include <list>
+#include <functional>
+#include <Ecore.h>
+
+using namespace app_assist;
+
+class CDrClosePopup:public WPopupController {
+ public:
+       CDrClosePopup();
+ protected:
+       ~CDrClosePopup();
+
+ public:
+       void setCaption(const char *title);
+       void setOnDiscardResult(std::function < void() > handlerFunc);
+       void setOnCancelResult(std::function < void() > handlerFunc);
+
+ private:
+       virtual Evas_Object * onCreateView(Evas_Object * parent, void *viewParam);
+       virtual void onDestroy();
+
+       Evas_Object *_createContent(Evas_Object * parent);
+
+ private:
+        std::function < void() > _discardResultHandler;
+        std::function < void() > _cancelResultHandler;
+};
+
+#endif
diff --git a/tizen-manifest.xml b/tizen-manifest.xml
new file mode 100755 (executable)
index 0000000..d66d625
--- /dev/null
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<manifest xmlns="http://tizen.org/ns/packages" api-version="4.0" package="org.tizen.sketch" version="1.0.85">
+    <profile name="wearable"/>
+    <ui-application appid="org.tizen.sketch" effectimage-type="edj-default" exec="sketch" hw-acceleration="on" multiple="true" nodisplay="true" process-pool="true" taskmanage="false" type="capp">
+        <label>sketch</label>
+        <icon>org.tizen.sketch.png</icon>
+    </ui-application>
+    <privileges>
+        <privilege>http://tizen.org/privilege/mediastorage</privilege>
+        <privilege>http://tizen.org/privilege/appmanager.launch</privilege>
+        <privilege>http://tizen.org/privilege/haptic</privilege>
+        <privilege>http://tizen.org/privilege/display</privilege>
+        <privilege>http://tizen.org/privilege/power</privilege>
+        <privilege>http://tizen.org/privilege/content.write</privilege>
+    </privileges>
+
+</manifest>