From: Aleksandr Sapozhnik Date: Wed, 25 Jan 2017 15:14:52 +0000 (+0200) Subject: Add the lib-apps-common from external repository X-Git-Tag: submit/tizen/20170728.112814^2~7 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=refs%2Fchanges%2F58%2F112058%2F1;p=profile%2Fmobile%2Fapps%2Fnative%2Fphone-contacts.git Add the lib-apps-common from external repository Change-Id: I5a0c5a415107d34f6c586d5bf4149ecb6d957463 Signed-off-by: Aleksandr Sapozhnik --- diff --git a/lib-apps-common/.cproject b/lib-apps-common/.cproject new file mode 100644 index 0000000..5f8aa87 --- /dev/null +++ b/lib-apps-common/.cproject @@ -0,0 +1,640 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/lib-apps-common/.project b/lib-apps-common/.project new file mode 100644 index 0000000..64ec448 --- /dev/null +++ b/lib-apps-common/.project @@ -0,0 +1,61 @@ + + + lib-apps-common + + + + + + org.tizen.nativecore.apichecker.apicheckerbuilder + + + + + org.eclipse.cdt.managedbuilder.core.genmakebuilder + + + + + org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder + full,incremental, + + + + + + org.eclipse.cdt.core.cnature + org.eclipse.cdt.core.ccnature + org.eclipse.cdt.managedbuilder.core.managedBuildNature + org.eclipse.cdt.managedbuilder.core.ScannerConfigNature + org.tizen.nativecore.apichecker.apicheckernature + + + + 1456218244303 + + 26 + + org.eclipse.ui.ide.multiFilter + 1.0-projectRelativePath-matches-false-false-*/.tpk + + + + 1456218244316 + + 6 + + org.eclipse.ui.ide.multiFilter + 1.0-name-matches-false-false-project_def.prop + + + + 1456218244318 + + 22 + + org.eclipse.ui.ide.multiFilter + 1.0-name-matches-false-false-CMakeLists.txt + + + + diff --git a/lib-apps-common/.tproject b/lib-apps-common/.tproject new file mode 100644 index 0000000..56660b2 --- /dev/null +++ b/lib-apps-common/.tproject @@ -0,0 +1,12 @@ + + + + + mobile-3.0 + + + + + + + diff --git a/lib-apps-common/Build/appendix.mk b/lib-apps-common/Build/appendix.mk new file mode 100644 index 0000000..2e06c34 --- /dev/null +++ b/lib-apps-common/Build/appendix.mk @@ -0,0 +1 @@ +# Appendix diff --git a/lib-apps-common/Build/basedef.mk b/lib-apps-common/Build/basedef.mk new file mode 100644 index 0000000..a762983 --- /dev/null +++ b/lib-apps-common/Build/basedef.mk @@ -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/lib-apps-common/Build/build_c.mk b/lib-apps-common/Build/build_c.mk new file mode 100644 index 0000000..d818ab6 --- /dev/null +++ b/lib-apps-common/Build/build_c.mk @@ -0,0 +1,110 @@ +# 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 +CONVERT_ESC_EXT_TO_O = $(addprefix $(2)/,$(call CONVERT_4MAKE_TO_OUT,$(patsubst %.$(3),%.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)) : $(call DECODE_4MAKE,$(1)) $(7) + @echo ' Building file: $$<' + @echo ' Invoking: $(3) Compiler' + $$(call MAKEDIRS,$$(@D)) + $(5) -c "$$<" -o "$$@" $(6) -Wp,@$(7) + @echo ' Finished building: $$<' +$(8) += $(call CONVERT_ESC_EXT_TO_O,$(1),$(2),$(4)) +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) + +$$(foreach var,$$(_ENC_SRCS),$$(eval $$(call C_BUILD_PROC_RAW,$$(var),$$(_OUTPUT_DIR),$$(_EXT_TITLE),$$(_EXT),$$(_COMPILER),$$(_DEFS),$$(_OPT_FILE),$(12)))) + +endif # (_(strip _(_ALL_SRCS)),) + +endif # (_(strip _(_SRCS)),) + + +endef diff --git a/lib-apps-common/Build/build_edc.mk b/lib-apps-common/Build/build_edc.mk new file mode 100644 index 0000000..2270b84 --- /dev/null +++ b/lib-apps-common/Build/build_edc.mk @@ -0,0 +1,81 @@ +# EDC build script + + +FUNC_EDC2EDJ = $(patsubst %.edc,%.edj,$(1)) + +# parameter : +# $(1) - C/C++ soruce file +# $(2) - output path +CONVERT_ESC_EDC_TO_EDJ = $(2)/$(call CONVERT_4MAKE_TO_OUT,$(call FUNC_EDC2EDJ,$(1))) + + +# 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/lib-apps-common/Build/build_po.mk b/lib-apps-common/Build/build_po.mk new file mode 100644 index 0000000..514116b --- /dev/null +++ b/lib-apps-common/Build/build_po.mk @@ -0,0 +1,64 @@ +# PO build script + + +_FUNC_PO2MO = $(patsubst %.po,res/locale/%/LC_MESSAGES/$(2).mo,$(notdir $(1))) + + +# parameter : +# $(1) - C/C++ soruce file +# $(2) - output path +# $(3) - app name +CONVERT_ESC_PO_TO_MO = $(2)/$(call CONVERT_4MAKE_TO_OUT,$(call _FUNC_PO2MO,$(1),$(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/lib-apps-common/Build/flags.mk b/lib-apps-common/Build/flags.mk new file mode 100644 index 0000000..efd9ba7 --- /dev/null +++ b/lib-apps-common/Build/flags.mk @@ -0,0 +1,16 @@ + +DEBUG_OP = +CPP_DEBUG_OP = -g3 + +OPTIMIZATION_OP = +CPP_OPTIMIZATION_OP = -O0 + +COMPILE_FLAGS = $(DEBUG_OP) $(OPTIMIZATION_OP) + +CPP_COMPILE_FLAGS = $(CPP_DEBUG_OP) $(CPP_OPTIMIZATION_OP) -std=c++11 -Wall -c -fmessage-length=0 -Wno-unused-function -Wno-extern-c-compat -fPIC + +LINK_FLAGS = -shared -Wl,--no-undefined + +AR_FLAGS = + +EDC_COMPILE_FLAGS = \ No newline at end of file diff --git a/lib-apps-common/Build/funcs.mk b/lib-apps-common/Build/funcs.mk new file mode 100644 index 0000000..8297d18 --- /dev/null +++ b/lib-apps-common/Build/funcs.mk @@ -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/lib-apps-common/Build/makefile b/lib-apps-common/Build/makefile new file mode 100644 index 0000000..3c3f61e --- /dev/null +++ b/lib-apps-common/Build/makefile @@ -0,0 +1,35 @@ +# +# Usege : make -f /Build/makefile -C +# + +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 = . +PROJ_PATH ?= .# +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) -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/lib-apps-common/Build/makefile.mk b/lib-apps-common/Build/makefile.mk new file mode 100644 index 0000000..fd5349d --- /dev/null +++ b/lib-apps-common/Build/makefile.mk @@ -0,0 +1,199 @@ +# +# Usege : make -f /Build/makefile -C +# + +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_BASE ?= $(PROJ_ROOT) +#OUTPUT_DIR ?= $(OUTPUT_BASE)/$(BUILD_CONFIG)/$(BUILD_ARCH) +OUTPUT_DIR ?= $(OUTPUT_BASE)/$(BUILD_CONFIG) +OUTPUT_DIR := $(call BSLASH2SLASH,$(OUTPUT_DIR)) +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/lib-apps-common/Build/platform.mk b/lib-apps-common/Build/platform.mk new file mode 100644 index 0000000..294a38a --- /dev/null +++ b/lib-apps-common/Build/platform.mk @@ -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/lib-apps-common/Build/prepost.mk b/lib-apps-common/Build/prepost.mk new file mode 100644 index 0000000..a8a4d87 --- /dev/null +++ b/lib-apps-common/Build/prepost.mk @@ -0,0 +1,7 @@ +# Add pre/post build process + +PREBUILD_COMMAND = +PREBUILD_DESC = + +POSTBUILD_COMMAND = +POSTBUILD_DESC = diff --git a/lib-apps-common/Build/tooldef.mk b/lib-apps-common/Build/tooldef.mk new file mode 100644 index 0000000..fded35b --- /dev/null +++ b/lib-apps-common/Build/tooldef.mk @@ -0,0 +1,63 @@ +# 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 diff --git a/lib-apps-common/CMakeLists.txt b/lib-apps-common/CMakeLists.txt new file mode 100644 index 0000000..b94a7be --- /dev/null +++ b/lib-apps-common/CMakeLists.txt @@ -0,0 +1,15 @@ +cmake_minimum_required(VERSION 2.6) +project(apps-common CXX) + +file(GLOB_RECURSE SOURCES src/*.cpp) +include_directories( + ${CMAKE_CURRENT_SOURCE_DIR}/inc + ${CMAKE_CURRENT_SOURCE_DIR}/res/apps-common/edje +) + +add_library(${PROJECT_NAME} SHARED ${SOURCES}) +target_link_libraries(${PROJECT_NAME} ${LIBRARIES}) + +install(TARGETS ${PROJECT_NAME} DESTINATION ${LIB_DIR}) + +add_subdirectory(res/apps-common) diff --git a/lib-apps-common/build_def.prop b/lib-apps-common/build_def.prop new file mode 100644 index 0000000..6bb5e2f --- /dev/null +++ b/lib-apps-common/build_def.prop @@ -0,0 +1,6 @@ + +# Add pre/post build process +PREBUILD_DESC = +PREBUILD_COMMAND = +POSTBUILD_DESC = +POSTBUILD_COMMAND = diff --git a/lib-apps-common/edje/apps-common/images/contacts_caller_id_default_02.png b/lib-apps-common/edje/apps-common/images/contacts_caller_id_default_02.png new file mode 100644 index 0000000..8b3c3d3 Binary files /dev/null and b/lib-apps-common/edje/apps-common/images/contacts_caller_id_default_02.png differ diff --git a/lib-apps-common/edje/apps-common/images/contacts_caller_id_default_04.png b/lib-apps-common/edje/apps-common/images/contacts_caller_id_default_04.png new file mode 100644 index 0000000..bcbb6a7 Binary files /dev/null and b/lib-apps-common/edje/apps-common/images/contacts_caller_id_default_04.png differ diff --git a/lib-apps-common/edje/apps-common/images/contacts_caller_id_default_05.png b/lib-apps-common/edje/apps-common/images/contacts_caller_id_default_05.png new file mode 100644 index 0000000..b882ab2 Binary files /dev/null and b/lib-apps-common/edje/apps-common/images/contacts_caller_id_default_05.png differ diff --git a/lib-apps-common/edje/apps-common/images/contacts_caller_id_default_bg_02.png b/lib-apps-common/edje/apps-common/images/contacts_caller_id_default_bg_02.png new file mode 100644 index 0000000..5f5fa3d Binary files /dev/null and b/lib-apps-common/edje/apps-common/images/contacts_caller_id_default_bg_02.png differ diff --git a/lib-apps-common/edje/apps-common/images/contacts_caller_id_default_bg_04.png b/lib-apps-common/edje/apps-common/images/contacts_caller_id_default_bg_04.png new file mode 100644 index 0000000..f1c2c1c Binary files /dev/null and b/lib-apps-common/edje/apps-common/images/contacts_caller_id_default_bg_04.png differ diff --git a/lib-apps-common/edje/apps-common/images/contacts_caller_id_default_bg_05.png b/lib-apps-common/edje/apps-common/images/contacts_caller_id_default_bg_05.png new file mode 100644 index 0000000..0a9c947 Binary files /dev/null and b/lib-apps-common/edje/apps-common/images/contacts_caller_id_default_bg_05.png differ diff --git a/lib-apps-common/edje/apps-common/images/contacts_caller_id_default_masking_02.png b/lib-apps-common/edje/apps-common/images/contacts_caller_id_default_masking_02.png new file mode 100644 index 0000000..c53e6f9 Binary files /dev/null and b/lib-apps-common/edje/apps-common/images/contacts_caller_id_default_masking_02.png differ diff --git a/lib-apps-common/edje/apps-common/images/contacts_caller_id_default_masking_04.png b/lib-apps-common/edje/apps-common/images/contacts_caller_id_default_masking_04.png new file mode 100644 index 0000000..d233123 Binary files /dev/null and b/lib-apps-common/edje/apps-common/images/contacts_caller_id_default_masking_04.png differ diff --git a/lib-apps-common/edje/apps-common/images/contacts_caller_id_default_masking_05.png b/lib-apps-common/edje/apps-common/images/contacts_caller_id_default_masking_05.png new file mode 100644 index 0000000..e243aa4 Binary files /dev/null and b/lib-apps-common/edje/apps-common/images/contacts_caller_id_default_masking_05.png differ diff --git a/lib-apps-common/edje/apps-common/images/widget_no_contents_bg.#.png b/lib-apps-common/edje/apps-common/images/widget_no_contents_bg.#.png new file mode 100644 index 0000000..4c51c13 Binary files /dev/null and b/lib-apps-common/edje/apps-common/images/widget_no_contents_bg.#.png differ diff --git a/lib-apps-common/edje/apps-common/images/widget_no_contents_bg_stroke.#.png b/lib-apps-common/edje/apps-common/images/widget_no_contents_bg_stroke.#.png new file mode 100644 index 0000000..dea69c7 Binary files /dev/null and b/lib-apps-common/edje/apps-common/images/widget_no_contents_bg_stroke.#.png differ diff --git a/lib-apps-common/inc/App/AppControl.h b/lib-apps-common/inc/App/AppControl.h new file mode 100644 index 0000000..2fb86d6 --- /dev/null +++ b/lib-apps-common/inc/App/AppControl.h @@ -0,0 +1,101 @@ +/* + * Copyright 2016 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.1 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://floralicense.org/license/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef APP_APP_CONTROL_H +#define APP_APP_CONTROL_H + +#include + +namespace App +{ + class EXPORT_API AppControl + { + public: + /** + * @brief Create empty app control wrapper. The wrapper doesn't contain any + * value it can only be assigned to. + */ + AppControl(); + + /** + * @brief Create a direct app control request + * + * @see app_control_set_app_id() + */ + explicit AppControl(const char *appId); + + /** + * @brief Create app control request + * + * @see app_control_set_operation() + * @see app_control_set_mime() + * @see app_control_set_uri() + */ + AppControl(const char *operation, + const char *mime, + const char *uri = nullptr); + + AppControl(const AppControl&) = delete; + AppControl(AppControl&&); + ~AppControl(); + + /** + * @return Stored app control handle + */ + app_control_h getHandle() const; + + /** + * @see app_control_add_extra_data() + */ + void addExtra(const char *key, const char *value); + + /** + * @see app_control_add_extra_data_array() + */ + void addExtra(const char *key, const char **array, int length); + + /** + * @brief Launch app control request + * @return App Control launch result + * + * @see app_control_set_launch_mode() + * @see app_control_send_launch_request() + */ + int launch(app_control_reply_cb replyCallback = nullptr, void *userData = nullptr, + bool groupMode = true); + + /** + * @see app_control_send_terminate_request() + */ + void terminate(); + + /** + * @brief Prevent app control termination on destruction. + */ + void detach(); + + AppControl &operator=(const AppControl&) = delete; + AppControl &operator=(AppControl&&); + + private: + void reset(); + + app_control_h m_AppControl; + bool m_AutoTerminate; + }; +} + +#endif /* APP_APP_CONTROL_H */ diff --git a/lib-apps-common/inc/App/AppControlRequest.h b/lib-apps-common/inc/App/AppControlRequest.h new file mode 100644 index 0000000..c2b093d --- /dev/null +++ b/lib-apps-common/inc/App/AppControlRequest.h @@ -0,0 +1,176 @@ +/* + * Copyright 2016 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.1 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://floralicense.org/license/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef APP_APP_CONTROL_REQUEST_H +#define APP_APP_CONTROL_REQUEST_H + +#include "App/AppControl.h" +#include "App/AppControlUtils.h" +#include "Utils/Range.h" + +#define APP_CONTROL_OPERATION_SETTING_CALL "http://tizen.org/appcontrol/operation/setting/call" + +#define APP_CONTROL_MIME_CONTACT "application/vnd.tizen.contact" +#define APP_CONTROL_MIME_IMAGE "image/*" +#define APP_CONTROL_MIME_VCARD "text/vcard" + +#define APP_CONTROL_URI_SCHEME_FILE "file://" + +#define APP_CONTROL_SELECT_SINGLE "single" +#define APP_CONTROL_SELECT_MULTIPLE "multiple" + +#define APP_CONTROL_RESULT_ID "id" +#define APP_CONTROL_RESULT_PHONE "phone" +#define APP_CONTROL_RESULT_EMAIL "email" +#define APP_CONTROL_RESULT_VCARD "vcf" +#define APP_CONTROL_RESULT_ACTION "action" +#define APP_CONTROL_RESULT_CALL "call" +#define APP_CONTROL_RESULT_MESSAGE "message" + +#define APP_CONTROL_RINGTONE_IS_DEFAULT "is_default" +#define APP_CONTROL_RINGTONE_TRUE "true" + +namespace App +{ + /** + * @brief Request contact creation operation + * @param[in] number Phone number to save to the new contact + * @return AppControl wrapper + */ + AppControl EXPORT_API requestContactCreate(const char *number); + + /** + * @brief Request contact view operation + * @param[in] personId ID of person to view + * @return AppControl wrapper + */ + AppControl EXPORT_API requestContactDetails(int personId); + + /** + * @brief Request contact edit operation + * @param[in] personId ID of person to edit or 0 to launch pick first + * @param[in] number Phone number to add to the edited contact + * @return AppControl wrapper + */ + AppControl EXPORT_API requestContactEdit(int personId, const char *number); + + /** + * @brief Request contact pick operation + * @param[in] selectionMode One of APP_CONTROL_SELECT_* values + * @param[in] resultType One of APP_CONTROL_RESULT_* values + * @return AppControl wrapper + */ + AppControl EXPORT_API requestContactPick(const char *selectionMode, const char *resultType); + + /** + * @brief Request telephony call + * @param[in] number Number to call + * @return AppControl wrapper + */ + AppControl EXPORT_API requestTelephonyCall(const char *number); + + /** + * @brief Request launch call settings + * @return AppControl wrapper + */ + AppControl EXPORT_API requestCallSettings(); + + /** + * @brief Request message or email composer for single recipient. + * @param[in] scheme URI scheme (e.g. sms: or mmsto: for message, mailto: for email) + * @param[in] to Recipient + * @param[in] subject Subject + * @param[in] text Text + * @return AppControl wrapper + */ + AppControl EXPORT_API requestComposer(const char *scheme, const char *to, + const char *subject = nullptr, const char *text = nullptr); + + /** + * @brief Request message or email composer for multiple recipients. + * @param[in] scheme URI scheme (e.g. sms: or mmsto: for message, mailto: for email) + * @param[in] recipients Multiple recipients + * @param[in] subject Subject + * @param[in] text Text + * @return AppControl wrapper + */ + AppControl EXPORT_API requestComposer(const char *scheme, Utils::Range recipients, + const char *subject = nullptr, const char *text = nullptr); + + /** + * @brief Request camera image capture + * @return AppControl wrapper + */ + AppControl EXPORT_API requestCameraImage(); + + /** + * @brief Request pick image from gallery + * @return AppControl wrapper + */ + AppControl EXPORT_API requestGalleryImage(); + + /** + * @brief Request view image + * @param[in] path Path to image file + * @return AppControl wrapper + */ + AppControl EXPORT_API requestViewImage(const char *path); + + /** + * @brief Request share contact via other application + * @param[in] personId Contact's person ID + * @return AppControl wrapper + */ + AppControl EXPORT_API requestShareContact(int personId); + + /** + * @brief Request share text to other application + * @param[in] text Information in text representation + * @return AppControl wrapper + */ + AppControl EXPORT_API requestShareText(const char *text); + + /** + * @brief Request share "My Profile" via other application + * @param[in] recordId "My Profile" record ID + * @return AppControl wrapper + */ + AppControl EXPORT_API requestShareMyProfile(int recordId); + + /** + * @brief Request share of multiple contacts via other application + * @param[in] personIds Contact's person IDs + * @param[in] count Person IDs count + * @return AppControl wrapper + */ + AppControl EXPORT_API requestMultiShareContacts(const char **personIds, int count); + + /** + * @brief Request pick vcard(s) from filesystem + * @param[in] path Path of storage from where files should be picked + * @return AppControl wrapper + */ + AppControl EXPORT_API requestPickVcard(const char *path); + + /** + * @brief Request pick ringtone from Settings + * @param[in] selectedPath Path of currently selected ringtone + * @return AppControl wrapper + */ + AppControl EXPORT_API requestPickRingtone(const char *selectedPath = nullptr); +} + +#endif /* APP_APP_CONTROL_REQUEST_H */ diff --git a/lib-apps-common/inc/App/AppControlUtils.h b/lib-apps-common/inc/App/AppControlUtils.h new file mode 100644 index 0000000..5fb4976 --- /dev/null +++ b/lib-apps-common/inc/App/AppControlUtils.h @@ -0,0 +1,70 @@ +/* + * Copyright 2016 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.1 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://floralicense.org/license/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef APP_APP_CONTROL_UTILS_H +#define APP_APP_CONTROL_UTILS_H + +#include +#include +#include + +namespace App +{ + /** + * @brief Get single first string from App Control array extra data. + * @param[in] appControl App Control handle + * @param[in] key Extra data array key + * @return First string from array on success, otherwise empty string. + */ + std::string EXPORT_API getSingleExtraData(app_control_h appControl, const char *key); + + /** + * @brief Get integer value from App Control extra data. + * @param[in] appControl App Control handle + * @param[in] key Extra data key + * @return Integer value. + */ + int EXPORT_API getIntExtraData(app_control_h appControl, const char *key); + + /** + * @brief Get string value from App Control extra data. + * @param[in] appControl App Control handle + * @param[in] key Extra data key + * @return String value. + */ + std::string EXPORT_API getStringExtraData(app_control_h appControl, const char *key); + + /** + * @brief Get vector of integer values from App Control array extra data. + * @param[in] appControl App Control handle + * @param[in] key Extra data array key + * @return Vector of integer values on success, otherwise empty vector. + */ + std::vector EXPORT_API getIntExtraDataArray(app_control_h appControl, const char *key); + + /** + * @brief Create array of strings of equal size. + * @details Both array and strings are created in a contiguous memory + * so it can be released all at once. + * @param[in] dataSize Maximum size of array element + * @param[in] count Number of array elements + * @remark Array elements MUST NOT be released. + * @return Array of pointers to strings, MUST be released using free(). + */ + EXPORT_API char **createExtraDataArray(size_t dataSize, size_t count); +} + +#endif /* APP_APP_CONTROL_UTILS_H */ diff --git a/lib-apps-common/inc/App/Application.h b/lib-apps-common/inc/App/Application.h new file mode 100644 index 0000000..ce1d6c6 --- /dev/null +++ b/lib-apps-common/inc/App/Application.h @@ -0,0 +1,103 @@ +/* + * Copyright 2016 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.1 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://floralicense.org/license/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef APP_APPLICATION_H +#define APP_APPLICATION_H + +#include + +namespace Ui +{ + class Naviframe; + class Window; +} + +namespace App +{ + class OperationController; + + /** + * @brief UI Application lifecycle controller. + */ + class EXPORT_API Application + { + public: + Application(); + virtual ~Application() { } + + /** + * @brief Run application main loop. + * @param[in] argc argc parameter received in main() + * @param[in] argv argv parameter received in main() + */ + int run(int argc, char **argv); + + protected: + /** + * @brief Create corresponding controller for requested operation. + * @param[in] operation Requested operation + * @return Controller to handle the operation. + */ + virtual OperationController *createController(const char *operation) = 0; + + /** + * @brief Called when application is created. + * @return true on success, otherwise false. + */ + virtual bool onCreate(); + + /** + * @brief Called when application is terminated. + */ + virtual void onTerminate(); + + /** + * @brief Called when application is paused. + */ + virtual void onPause(); + + /** + * @brief Called when application is resumed. + */ + virtual void onResume(); + + /** + * @brief Called when application receives App Control request. + * @param request App Control request + */ + virtual void onAppControl(app_control_h request); + + /** + * @return Main application Window. + */ + Ui::Window *getWindow() const; + + /** + * @return Main application Navigator. + */ + Ui::Naviframe *getNavigator() const; + + private: + static void onLanguageChanged(app_event_info_h event, void *data); + static void updateLanguage(); + + Ui::Window *m_Window; + Ui::Naviframe *m_Navigator; + OperationController *m_Controller; + }; +} + +#endif /* APP_APPLICATION_H */ diff --git a/lib-apps-common/inc/App/OperationController.h b/lib-apps-common/inc/App/OperationController.h new file mode 100644 index 0000000..2502f45 --- /dev/null +++ b/lib-apps-common/inc/App/OperationController.h @@ -0,0 +1,112 @@ +/* + * Copyright 2016 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.1 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://floralicense.org/license/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef APP_OPERATION_CONTROLLER_H +#define APP_OPERATION_CONTROLLER_H + +#include +#include + +namespace Ui +{ + class Navigator; + class Window; +} + +namespace App +{ + /** + * @brief Handles operations requested through App Control. + */ + class EXPORT_API OperationController + { + public: + /** + * @brief Create operation controller. + * @param[in] isMinimizable Whether application can be minimized + */ + OperationController(bool isMinimizable = false); + virtual ~OperationController(); + + /** + * @brief Create operation controller. + * @param[in] window Main application Window + * @param[in] navigator Main application Navigator + */ + void create(Ui::Window *window, Ui::Navigator *navigator); + + /** + * @brief Request the controller to handle the operation. + * @param[in] operation Requested operation + * @param[in] request App Control request + */ + void request(const char *operation, app_control_h request); + + protected: + /** + * @brief Called after create() is called. + */ + virtual void onCreate() { } + + /** + * @brief Called when application receives pause event. + */ + virtual void onPause() { } + + /** + * @brief Called when application receives resume event. + */ + virtual void onResume() { } + + /** + * @brief Called after request() is called. + */ + virtual void onRequest(const char *operation, app_control_h request) = 0; + + /** + * @return Main application Window. + */ + Ui::Window *getWindow() const; + + /** + * @return Main application Navigator. + */ + Ui::Navigator *getNavigator() const; + + /** + * @return Last received request. + */ + app_control_h getRequest() const; + + /** + * @brief Get URI without prefix (if present). + * @param[in] scheme Scheme prefix to remove (e.g. tel: or file://) + * @return URI without scheme. + */ + std::string getUrn(const char *scheme) const; + + private: + friend class Application; + + app_control_h m_Request; + bool m_IsMinimizable; + + Ui::Window *m_Window; + Ui::Navigator *m_Navigator; + }; +} + +#endif /* APP_OPERATION_CONTROLLER_H */ diff --git a/lib-apps-common/inc/App/Path.h b/lib-apps-common/inc/App/Path.h new file mode 100644 index 0000000..fd9f2ed --- /dev/null +++ b/lib-apps-common/inc/App/Path.h @@ -0,0 +1,48 @@ +/* + * Copyright 2016 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.1 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://floralicense.org/license/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef APP_PATH_H +#define APP_PATH_H + +#include +#include + +namespace App +{ + /** + * @return Localization files directory path. + */ + EXPORT_API const std::string &getLocaleDir(); + + /** + * @return Data directory path. + */ + EXPORT_API const std::string &getDataDir(); + + /** + * @return Resource directory path. + */ + EXPORT_API const std::string &getResourceDir(); + + /** + * @brief Get resource file path. + * @param[in] relativePath File path relative to resource directory + * @return Absolute file path. + */ + EXPORT_API std::string getResourcePath(const char *relativePath); +} + +#endif /* APP_PATH_H */ diff --git a/lib-apps-common/inc/App/Widget.h b/lib-apps-common/inc/App/Widget.h new file mode 100644 index 0000000..5f82547 --- /dev/null +++ b/lib-apps-common/inc/App/Widget.h @@ -0,0 +1,126 @@ +/* + * Copyright 2016 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.1 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://floralicense.org/license/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef APP_WIDGET_H +#define APP_WIDGET_H + +#include +#include + +namespace Ui +{ + class Window; +} + +namespace App +{ + /** + * @brief Homescreen widget base class. + */ + class EXPORT_API Widget + { + public: + Widget(); + virtual ~Widget(); + + /** + * @brief Create widget. + * @param[in] context Widget context + * @param[in] content Widget content bundle + */ + void create(widget_context_h context, bundle *content); + + /** + * @brief Resize widget. + * @param[in] width Widget new width + * @param[in] height Widget new height + */ + void resize(int width, int height); + + /** + * @return Widget width. + */ + int getWidth() const; + + /** + * @return Widget height. + */ + int getHeight() const; + + /** + * @return Widget type. + * @see widget_size_type_e + */ + widget_size_type_e getType() const; + + /** + * @return Widget window. + */ + Ui::Window *getWindow() const; + + protected: + /** + * @brief Save widget content bundle. + * @param[in] content Content to save + */ + void saveContent(bundle *content); + + /** + * @brief Called when widget is created. + * @param[in] content Widget content bundle + */ + virtual void onCreate(bundle *content) { } + + /** + * @brief Called when widget is destroyed. + * @param[in] reason Reason for destruction + */ + virtual void onDestroy(widget_app_destroy_type_e reason) { } + + /** + * @brief Called when widget is paused. + */ + virtual void onPause() { } + + /** + * @brief Called when widget is resumed. + */ + virtual void onResume() { } + + /** + * @brief Called when widget is resized. + * @param[in] width Widget new width + * @param[in] height Widget new height + */ + virtual void onResize(int width, int height) { } + + /** + * @brief Called when widget is updated. + * @param[in] force Whether widget was forcefully updated + */ + virtual void onUpdate(int force) { } + + private: + friend class WidgetApplication; + + widget_context_h m_Context; + int m_Width; + int m_Height; + Ui::Window *m_Window; + }; +} + +#endif /* APP_WIDGET_H */ diff --git a/lib-apps-common/inc/App/WidgetApplication.h b/lib-apps-common/inc/App/WidgetApplication.h new file mode 100644 index 0000000..c79bd58 --- /dev/null +++ b/lib-apps-common/inc/App/WidgetApplication.h @@ -0,0 +1,81 @@ +/* + * Copyright 2016 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.1 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://floralicense.org/license/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef APP_WIDGET_APPLICATION_H +#define APP_WIDGET_APPLICATION_H + +#include + +namespace App +{ + class Widget; + + /** + * @brief Widget application lifecycle controller. + */ + class EXPORT_API WidgetApplication + { + public: + /** + * @brief Run application main loop. + * @param[in] argc argc parameter received in main() + * @param[in] argv argv parameter received in main() + */ + int run(int argc, char **argv); + + protected: + virtual ~WidgetApplication() { } + + /** + * @brief Called when application is created. + * @return Whether application is created successfully. + */ + virtual bool onCreate(); + + /** + * @brief Called when application is terminated. + */ + virtual void onTerminate() { } + + /** + * @return Create widget instance. + */ + virtual Widget *createWidget() = 0; + + private: + widget_class_h onWidgetClassCreate(); + + static Widget *getWidget(widget_context_h context); + + static int onWidgetCreate(widget_context_h context, + bundle *content, int width, int height, void *data); + static int onWidgetDestroy(widget_context_h context, + widget_app_destroy_type_e reason, bundle *content, void *data); + + static int onWidgetPause(widget_context_h context, void *data); + static int onWidgetResume(widget_context_h context, void *data); + + static int onWidgetResize(widget_context_h context, + int width, int height, void *data); + static int onWidgetUpdate(widget_context_h context, + bundle *content, int force, void *data); + + static void onLanguageChanged(app_event_info_h event, void *data); + static void updateLanguage(); + }; +} + +#endif /* APP_WIDGET_APPLICATION_H */ diff --git a/lib-apps-common/inc/App/WidgetWindow.h b/lib-apps-common/inc/App/WidgetWindow.h new file mode 100644 index 0000000..cd5d5f5 --- /dev/null +++ b/lib-apps-common/inc/App/WidgetWindow.h @@ -0,0 +1,45 @@ +/* + * Copyright 2016 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.1 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://floralicense.org/license/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef APP_WIDGET_WINDOW_H +#define APP_WIDGET_WINDOW_H + +#include "Ui/Window.h" +#include + +namespace App +{ + class EXPORT_API WidgetWindow : public Ui::Window + { + public: + /** + * @brief Create WidgetWindow. + * @param[in] context Widget context + */ + WidgetWindow(widget_context_h context); + + protected: + /** + * @see Window::onWindowCreate() + */ + virtual Evas_Object *onWindowCreate(); + + private: + widget_context_h m_Context; + }; +} + +#endif /* APP_WIDGET_WINDOW_H */ diff --git a/lib-apps-common/inc/I18n/Collator.h b/lib-apps-common/inc/I18n/Collator.h new file mode 100644 index 0000000..f7ef85b --- /dev/null +++ b/lib-apps-common/inc/I18n/Collator.h @@ -0,0 +1,65 @@ +/* + * Copyright 2016 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.1 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://floralicense.org/license/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef I18N_COLLATOR_H +#define I18N_COLLATOR_H + +#include "I18n/UniString.h" +#include + +namespace I18n +{ + /** + * @brief Provides locale-dependent string comparison. + */ + class EXPORT_API Collator + { + public: + /** + * @brief Create collator. + * @param[in] strength Collation strength + * @see i18n_ucollator_strength_e + */ + explicit Collator(i18n_ucollator_strength_e strength = I18N_UCOLLATOR_PRIMARY); + Collator(const Collator &that) = delete; + Collator(Collator &&that); + ~Collator(); + + Collator &operator=(const Collator &that) = delete; + Collator &operator=(Collator &&that); + + /** + * @brief Initialize the collator with current locale. + * @remark Can be called several times. + */ + void initialize(); + + /** + * @brief Compare two strings. + * @pre Should be initialized by calling initialize(). + * @param[in] str1 First string + * @param[in] str2 Second string + * @return 0 if equal, -1 if str1 < str2, otherwise 1. + */ + int compare(const UniString &str1, const UniString &str2); + + private: + i18n_ucollator_strength_e m_Strength; + i18n_ucollator_h m_Handle; + }; +} + +#endif /* I18N_COLLATOR_H */ diff --git a/lib-apps-common/inc/I18n/UniString.h b/lib-apps-common/inc/I18n/UniString.h new file mode 100644 index 0000000..7c7ad91 --- /dev/null +++ b/lib-apps-common/inc/I18n/UniString.h @@ -0,0 +1,75 @@ +/* + * Copyright 2016 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.1 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://floralicense.org/license/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef I18N_UNI_STRING_H +#define I18N_UNI_STRING_H + +#include +#include + +namespace I18n +{ + /** + * @brief Class wrapper for convenient work with multibyte UTF8 unicode string + */ + class EXPORT_API UniString + { + public: + /** + * @brief Instantiation of the basic_string class template, + * that uses i18n_uchar as its character type + */ + typedef std::basic_string I18nString; + + UniString() = default; + /** + * @brief Create new object, based on @a utf8Str string + * @param[in] utf8Str UTF8 multibyte unicode string + */ + UniString(const char *utf8Str); + + bool operator<(const UniString &that) const; + bool operator>(const UniString &that) const; + bool operator==(const UniString &that) const; + bool operator!=(const UniString &that) const; + bool operator<=(const UniString &that) const; + bool operator>=(const UniString &that) const; + + /** + * @return I18n string + */ + const I18nString &getI18nStr() const; + + /** + * @return UTF8 multibyte string + */ + const std::string &getUtf8Str() const; + + /** + * @brief Erases the contents of the string + */ + void clear(); + + private: + static std::string toUtf8(const I18nString &ustring); + static I18nString fromUtf8(const std::string &utf8Str); + + mutable std::string m_Utf8Str; + I18nString m_UniStr; + }; +} + +#endif /* I18N_UNI_STRING_H */ diff --git a/lib-apps-common/inc/Model/DataItem.h b/lib-apps-common/inc/Model/DataItem.h new file mode 100644 index 0000000..f2c7b2a --- /dev/null +++ b/lib-apps-common/inc/Model/DataItem.h @@ -0,0 +1,83 @@ +/* + * Copyright 2016 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.1 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://floralicense.org/license/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef MODEL_DATA_ITEM_H +#define MODEL_DATA_ITEM_H + +#include +#include + +namespace Model +{ + class EXPORT_API DataItem + { + public: + /** + * @brief Change callback + * @param[in] Changed info + */ + typedef std::function UpdateCallback; + + /** + * @brief Delete callback + */ + typedef std::function DeleteCallback; + + virtual ~DataItem() { } + + /** + * @brief Set update callback + * @param[in] callback Update callback + */ + void setUpdateCallback(UpdateCallback callback); + + /** + * @brief Unset update callback + */ + void unsetUpdateCallback(); + + /** + * @brief Set delete callback + * @param[in] callback Delete callback + */ + void setDeleteCallback(DeleteCallback callback); + + /** + * @brief Unset delete callback + */ + void unsetDeleteCallback(); + + protected: + /** + * @brief ContactData updated callback + * @param[in] changes Changed info + */ + void onUpdated(int changes); + + /** + * @brief ContactData deleted callback + */ + void onDeleted(); + + private: + UpdateCallback m_OnUpdated; + DeleteCallback m_OnDeleted; + }; +} + + + +#endif /* MODEL_DATA_ITEM_H */ diff --git a/lib-apps-common/inc/Model/DataProvider.h b/lib-apps-common/inc/Model/DataProvider.h new file mode 100644 index 0000000..c126d59 --- /dev/null +++ b/lib-apps-common/inc/Model/DataProvider.h @@ -0,0 +1,113 @@ +/* + * Copyright 2016 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.1 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://floralicense.org/license/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef MODEL_DATA_PROVIDER_H +#define MODEL_DATA_PROVIDER_H + +#include "Model/DataItem.h" + +#include + +namespace Model +{ + class EXPORT_API DataProvider + { + public: + typedef std::list DataList; + + /** + * @brief Called once initialization is finished. + */ + typedef std::function InitializeCallback; + + /** + * @brief Insert callback + * @param[in] data + */ + typedef std::function InsertCallback; + + /** + * @brief Called when provider has finished updating its items. + */ + typedef std::function UpdateFinishedCallback; + + virtual ~DataProvider() { } + + /** + * @brief Initialize provider data. + * @remark Should be called before retrieving the data. + * @param[in] callback Initialization finished callback + */ + void initialize(InitializeCallback callback); + + /** + * @return Data list + */ + virtual const DataList &getDataList() = 0; + + /** + * @brief Set insert callback + * @param[in] callback Create callback + */ + void setInsertCallback(InsertCallback callback); + + /** + * @brief Unset insert callback + */ + void unsetInsertCallback(); + + /** + * @brief Set update finished callback + * @param[in] callback Update finished callback + */ + void setUpdateFinishedCallback(UpdateFinishedCallback callback); + + /** + * @brief Unset update finished callback + */ + void unsetUpdateFinishedCallback(); + + protected: + /** + * @brief Called after initialize() to initialize provider data. + * @post onInitialized() should be called when initialization is finished. + */ + virtual void onInitialize(); + + /** + * @brief Should be called to notify that initialization is finished. + */ + void onInitialized(); + + /** + * @brief DataItem inserted callback + * @param[in] dataItem Data item + */ + void onInserted(DataItem &dataItem); + + /** + * @brief Should be called to notify that update is finished. + */ + void onUpdateFinished(); + + private: + InitializeCallback m_OnInitialized; + InsertCallback m_OnInserted; + UpdateFinishedCallback m_OnUpdateFinished; + }; +} + +#endif /* MODEL_DATA_PROVIDER_H */ diff --git a/lib-apps-common/inc/Model2/DataItem.h b/lib-apps-common/inc/Model2/DataItem.h new file mode 100644 index 0000000..43dcee1 --- /dev/null +++ b/lib-apps-common/inc/Model2/DataItem.h @@ -0,0 +1,116 @@ +/* + * Copyright 2016 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.1 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://floralicense.org/license/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef MODEL2_DATA_ITEM_H +#define MODEL2_DATA_ITEM_H + +#include +#include "Utils/CallbackManager.h" + +/* FIXME: Rename once transition to new model is complete */ +namespace Model2 +{ + /** + * @brief Change types. + */ + enum ChangeType + { + ChangeNone, + ChangeInsert, + ChangeUpdate, + ChangeDelete + }; + + class EXPORT_API DataItem + { + public: + /** + * @brief Called after item was updated. + * @param[in] Which item data was updated (depends on the specific item). + */ + typedef Utils::CallbackManager UpdateCallback; + + /** + * @brief Called before item is deleted. + */ + typedef Utils::CallbackManager<> DeleteCallback; + + DataItem(); + DataItem(const DataItem &); + virtual ~DataItem() { } + + /** + * @brief Update item with new data. + * @param[in] data New item data. + */ + void update(void *data); + + /** + * @return Whether is standalone (not managed by DataProvider). + */ + bool isStandalone() const; + + /** + * @brief Set whether item is standalone or managed by DataProvider. + * @param[in] isStandalone Whether item is standalone + */ + void setStandalone(bool isStandalone); + + /** + * @brief Add/remove update callback. + */ + UpdateCallback &onUpdated(); + + /** + * @brief Add/remove delete callback. + */ + DeleteCallback &onDeleted(); + + protected: + /** + * @brief Mark item as changed with specified change type. + * @param[in] changeType Item change type + * @param[in] changes Which item data was updated if type is ChangeUpdate + */ + void setChanged(ChangeType changeType, int changes = 0); + + /** + * @brief Called after setStandalone() to change item standalone state. + * @param[in] isStandalone Whether item is standalone + */ + virtual void onStandalone(bool isStandalone) { } + + /** + * @brief Called after update() to update item data. + * @param[in] data New item data + * @return Mask specifying which item data was updated. + */ + virtual int onUpdate(void *data) { return 0; } + + private: + friend class DataProvider; + void finishUpdate(); + + bool m_IsStandalone; + int m_Changes; + ChangeType m_ChangeType; + + UpdateCallback m_OnUpdated; + DeleteCallback m_OnDeleted; + }; +} + +#endif /* MODEL2_DATA_ITEM_H */ diff --git a/lib-apps-common/inc/Model2/DataProvider.h b/lib-apps-common/inc/Model2/DataProvider.h new file mode 100644 index 0000000..e2c2378 --- /dev/null +++ b/lib-apps-common/inc/Model2/DataProvider.h @@ -0,0 +1,151 @@ +/* + * Copyright 2016 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.1 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://floralicense.org/license/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef MODEL2_DATA_PROVIDER_H +#define MODEL2_DATA_PROVIDER_H + +#include "Model2/DataItem.h" + +#include + +/* FIXME: Rename once transition to new model is complete */ +namespace Model2 +{ + class EXPORT_API DataProvider + { + public: + typedef std::list DataList; + + /** + * @brief Called once initialization is finished. + */ + typedef std::function InitializeCallback; + + /** + * @brief Called when provider has started or finished updating its items. + */ + typedef Utils::CallbackManager<> UpdateCallback; + + /** + * @brief Called after item was inserted. + * @param[in] Inserted item + */ + typedef Utils::CallbackManager InsertCallback; + + DataProvider(); + virtual ~DataProvider(); + + /** + * @return Provider data list. + */ + const DataList &getDataList(); + + /** + * @brief Initialize provider data. + * @remark Should be called before retrieving the data. + * @param[in] callback Initialization finished callback + */ + void initialize(InitializeCallback callback); + + /** + * @brief Update provider data. + * @details If update is disabled or is already in progress + * the update is postponed. + */ + void update(); + + /** + * @brief Destroy dynamically allocated provider safely. + * @details If provider is currently busy the destruction is postponed. + * @remark No callbacks will be called after this method is called. + */ + void destroy(); + + /** + * @brief Set whether to start update immediately when update() is called. + * @param[in] isEnabled Whether data update is enabled + */ + void setUpdateEnabled(bool isEnabled); + + /** + * @brief Add/remove insert callback. + */ + InsertCallback &onInserted(); + + /** + * @brief Add/remove update start callback. + */ + UpdateCallback &onUpdateStarted(); + + /** + * @brief Add/remove update finish callback. + */ + UpdateCallback &onUpdateFinished(); + + protected: + /** + * @brief Called after initialize() to initialize provider data. + * @post finishInit() should be called when initialization is finished. + */ + virtual void startInit() = 0; + + /** + * @brief Called after update() to update provider data. + * @post finishUpdate() should be called when update is finished. + */ + virtual void startUpdate() = 0; + + /** + * @brief Insert new DataItem into the list. + * @param[in] dataItem New data item + */ + void insertDataItem(DataItem *dataItem); + + /** + * @brief Delete DataItem from the list. + * @param[in] dataItem Data item to be deleted + */ + void deleteDataItem(DataItem &dataItem); + + /** + * @brief Should be called when initialization is finished. + * @param[in] dataList Initialized data list + */ + void finishInit(DataList dataList); + + /** + * @brief Should be called when update is finished. + * @details Notifies clients about changes and removes deleted items from the list. + */ + void finishUpdate(); + + private: + bool m_IsBusy; + bool m_IsInitialized; + bool m_IsUpdateEnabled; + bool m_IsUpdatePending; + bool m_IsDestroyPending; + + InitializeCallback m_OnInitialized; + InsertCallback m_OnInserted; + UpdateCallback m_OnUpdateStarted; + UpdateCallback m_OnUpdateFinished; + + DataList m_DataList; + }; +} + +#endif /* MODEL2_DATA_PROVIDER_H */ diff --git a/lib-apps-common/inc/Model2/SearchData.h b/lib-apps-common/inc/Model2/SearchData.h new file mode 100644 index 0000000..a92d6ae --- /dev/null +++ b/lib-apps-common/inc/Model2/SearchData.h @@ -0,0 +1,77 @@ +/* + * Copyright 2016 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.1 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://floralicense.org/license/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef MODEL_SEARCH_DATA_H +#define MODEL_SEARCH_DATA_H + +#include "Model2/DataItem.h" +#include "Model2/SearchResult.h" + +namespace Model2 +{ + class EXPORT_API SearchData : public DataItem + { + public: + /** + * @brief Called when SearchResult is changed. + * @param[in] Search result + */ + typedef std::function ChangeCallback; + + /** + * @brief Create SearchData object. + * @param[in] dataItem Data item reference + */ + explicit SearchData(DataItem &dataItem); + + /** + * @return DataItem reference. + */ + DataItem &getDataItem(); + + /** + * @return DataItem reference. + */ + const DataItem &getDataItem() const; + + /** + * @return Search result. + */ + const SearchResult *getSearchResult() const; + + /** + * @brief Set search result. + * @param[in] searchResult Search result + */ + void setSearchResult(SearchResult *searchResult); + + /** + * @brief Set change callback. + * @param[in] callback @see ChangeCallback + */ + void setChangeCallback(ChangeCallback callback); + + protected: + virtual int onUpdate(void *data) override; + + private: + DataItem &m_DataItem; + SearchResult *m_SearchResult; + ChangeCallback m_OnChanged; + }; +} + +#endif /* MODEL_SEARCH_DATA_H */ diff --git a/lib-apps-common/inc/Model2/SearchEngine.h b/lib-apps-common/inc/Model2/SearchEngine.h new file mode 100644 index 0000000..6b6776c --- /dev/null +++ b/lib-apps-common/inc/Model2/SearchEngine.h @@ -0,0 +1,107 @@ +/* + * Copyright 2016 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.1 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://floralicense.org/license/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef MODEL_SEARCH_ENGINE_H +#define MODEL_SEARCH_ENGINE_H + +#include "Model2/SearchResult.h" +#include "Model2/DataProvider.h" + +#include +#include + +namespace Model2 +{ + class SearchData; + + /** + * @brief This is a callable object which provides match logic + * @param[in] Search data + * @param[in] Query + * @return Search result + */ + typedef std::function SearchComparator; + + /** + * @brief This class provides incremental search logic + */ + class EXPORT_API SearchEngine + { + public: + typedef DataProvider::DataList DataList; + + /** + * @brief Create search engine + * @param[in] dataList ContactData list + * @param[in] comparator Callable match comparator + */ + explicit SearchEngine(const DataList &dataList, SearchComparator comparator); + + /** + * @brief Perform incremental search + * @param[in] query Value to find + */ + void search(std::string query); + + /** + * @return true if there is no results, otherwise false + */ + bool empty() const; + + /**@{*/ + /** + * @brief Notify engine that SearchData was Inserted/Updated/Deleted + * @param[in] searchData SearchData object + */ + void insertSearchData(SearchData *searchData); + void updateSearchData(SearchData *searchData); + void deleteSearchData(SearchData *searchData); + /**@}*/ + + private: + typedef std::pair SearchResultItem; + typedef std::list ResultList; + typedef std::vector SearchHistory; + typedef std::function HistoryForFn; + + bool needSearch(const std::string &query); + template + void incrementalSearch(const List &list, const std::string &query); + + SearchData *getSearchData(DataItem *data); + SearchData *getSearchData(const SearchResultItem &searchItem); + + void updateSearchResult(ResultList &list); + void resetSearchResult(); + void clear(); + + SearchHistory::iterator getMatch(const std::string &query); + SearchHistory::iterator skipEmptyResults(size_t offset); + + void historyFor(HistoryForFn function); + static ResultList::iterator findSearchData(ResultList &list, SearchData *searchData); + + std::string m_Query; + SearchHistory m_History; + int m_LastFoundIndex; + + const DataList &m_DataList; + + SearchComparator m_Comparator; + }; +} + +#endif /* MODEL_SEARCH_ENGINE_H */ diff --git a/lib-apps-common/inc/Model2/SearchProvider.h b/lib-apps-common/inc/Model2/SearchProvider.h new file mode 100644 index 0000000..b5bcd80 --- /dev/null +++ b/lib-apps-common/inc/Model2/SearchProvider.h @@ -0,0 +1,64 @@ +/* + * Copyright 2016 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.1 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://floralicense.org/license/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef MODEL_SEARCH_PROVIDER_H +#define MODEL_SEARCH_PROVIDER_H + +#include "Model2/SearchEngine.h" +#include "Model2/DataProvider.h" + +namespace Model2 +{ + class SearchData; + + class EXPORT_API SearchProvider : public DataProvider + { + public: + + /** + * @brief Create SearchProvider + * @param[in] provider DataProvider + * @param[in] comparator Callable match comparator + */ + explicit SearchProvider(DataProvider &provider, SearchComparator comparator); + virtual ~SearchProvider() override; + + /** + * @brief Invoke search + * @param[in] query Passed search string + */ + void search(const char *query); + + /** + * @return Whether there is no results for the current query. + */ + bool empty() const; + + private: + virtual void startInit() override; + virtual void startUpdate() override { } + + SearchData *createSearchData(DataItem &dataItem); + void onItemInserted(DataItem &dataItem); + void onItemUpdated(SearchData &searchData, int changes); + void onItemDeleted(SearchData &searchData); + + DataProvider &m_Provider; + SearchEngine m_SearchEngine; + }; +} + +#endif /* MODEL_SEARCH_PROVIDER_H */ diff --git a/lib-apps-common/inc/Model2/SearchResult.h b/lib-apps-common/inc/Model2/SearchResult.h new file mode 100644 index 0000000..e89781f --- /dev/null +++ b/lib-apps-common/inc/Model2/SearchResult.h @@ -0,0 +1,68 @@ +/* + * Copyright 2016 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.1 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://floralicense.org/license/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef MODEL_SEARCH_RESULT_H +#define MODEL_SEARCH_RESULT_H + +#include +#include +#include "Utils/Range.h" + +namespace Model2 +{ + class EXPORT_API SearchResult + { + public: + /** + * @brief Represents substring of matched string. + */ + typedef Utils::Range Substring; + + SearchResult(); + + /** + * @brief Create SearchResult object. + * @param[in] fieldId Field ID matched with query + * @param[in] str Matched string + * @param[in] substr Matched substring + */ + SearchResult(int fieldId, const char *str, Substring substr); + + /** + * @return Field ID matched with query. + */ + int getMatchedField() const; + + /** + * @return Matched string. + */ + const char *getMatchedString() const; + + /** + * @return Matched substring. + */ + const Substring &getMatchedSubstring() const; + + private: + int m_MatchedField; + const char *m_MatchedString; + Substring m_MatchedSubstring; + }; + + typedef std::unique_ptr SearchResultPtr; +} + +#endif /* MODEL_SEARCH_RESULT_H */ diff --git a/lib-apps-common/inc/System/Settings.h b/lib-apps-common/inc/System/Settings.h new file mode 100644 index 0000000..f73d089 --- /dev/null +++ b/lib-apps-common/inc/System/Settings.h @@ -0,0 +1,41 @@ +/* + * Copyright 2016 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.1 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://floralicense.org/license/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef SYSTEM_SETTINGS_H +#define SYSTEM_SETTINGS_H + +#include +#include "Utils/CallbackManager.h" + +namespace System +{ + namespace Settings + { + typedef Utils::CallbackManager CallbackManager; + + /** + * @see system_settings_set_changed_cb() + */ + EXPORT_API void addCallback(system_settings_key_e key, CallbackManager::Callback callback); + + /** + * @see system_settings_unset_changed_cb() + */ + EXPORT_API void removeCallback(system_settings_key_e key, void *subscriber); + }; +} + +#endif /* SYSTEM_SETTINGS_H */ diff --git a/lib-apps-common/inc/Ui/Button.h b/lib-apps-common/inc/Ui/Button.h new file mode 100644 index 0000000..be6d868 --- /dev/null +++ b/lib-apps-common/inc/Ui/Button.h @@ -0,0 +1,66 @@ +/* + * Copyright 2016 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.1 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://floralicense.org/license/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef UI_BUTTON_H +#define UI_BUTTON_H + +#include "Ui/Control.h" +#include + +namespace Ui +{ + /** + * @brief Provides convenient press and longpress events handling. + */ + class EXPORT_API Button : public Control + { + public: + Button(); + virtual ~Button() override; + + /** + * @brief Set press-event callback. + */ + void setPressedCallback(std::function callback); + + /** + * @brief Set longpress-event callback. + * @details Callback should return true if the event was handled. + * If callback returns false onPressed event will be delivered + * as well when the button is released. + */ + void setLongpressedCallback(std::function callback); + + private: + virtual Evas_Object *onCreate(Evas_Object *parent) override; + virtual void onCreated() override; + + void onMouseDown(Evas *evas, Evas_Object *obj, void *eventInfo); + void onMouseUp(Evas *evas, Evas_Object *obj, void *eventInfo); + void onMouseOut(Evas *evas, Evas_Object *obj, void *eventInfo); + + void resetTimer(); + Eina_Bool onTimeout(); + + Ecore_Timer *m_Timer; + bool m_IsLongpressed; + + std::function m_OnPressed; + std::function m_OnLongpressed; + }; +} + +#endif /* UI_BUTTON_H */ diff --git a/lib-apps-common/inc/Ui/CheckItem.h b/lib-apps-common/inc/Ui/CheckItem.h new file mode 100644 index 0000000..8f95e1b --- /dev/null +++ b/lib-apps-common/inc/Ui/CheckItem.h @@ -0,0 +1,104 @@ +/* + * Copyright 2016 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.1 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://floralicense.org/license/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef UI_CHECK_ITEM +#define UI_CHECK_ITEM + +#include "Ui/GenItem.h" + +namespace Ui +{ + /** + * @brief GenContainer check item + */ + class EXPORT_API CheckItem : public Ui::GenItem + { + public: + /** + * @brief Item check callback. + * @param[in] Whether item is checked + * @return Whether item's state should be changed. + */ + typedef std::function CheckCallback; + + CheckItem(GenContainer::Type type = GenContainer::TypeGenlist); + virtual ~CheckItem() override; + + /** + * @return Whether the item is checked. + */ + bool isChecked() const; + + /** + * @brief Set item check state. + * @param[in] isChecked Whether item is checked + * @return Whether the state was changed successfully. + */ + bool setChecked(bool isChecked); + + /** + * @brief Set item check callback. + * @param[in] callback Callback to be called when item is checked/unchecked + */ + void setCheckCallback(CheckCallback callback); + + /** + * @brief Set item which "checked" state should be synchronized with this item. + * @param[in] item Item to link with + */ + void setLinkedItem(CheckItem *item); + + /** + * @brief Unset linked item. + */ + void unsetLinkedItem(); + + protected: + /** + * @brief Update the part containing check component. + */ + void updateCheckPart(); + + /** + * @see GenItem::getContent() + * @remark Use it in derived class to create check component + */ + virtual Evas_Object *getContent(Evas_Object *parent, const char *part) override; + + /** + * @see GenItem::onSelected() + */ + virtual void onSelected() override; + + /** + * @brief Called when item's "checked" state changes. + * @param[in] isChecked Whether item is checked + * @return Whether item's state should be changed. + */ + virtual bool onChecked(bool isChecked) { return true; } + + private: + bool notifyCheck(); + + std::string m_CheckPart; + Eina_Bool m_IsChecked; + bool m_IsChecking; + CheckCallback m_OnChecked; + CheckItem *m_LinkedItem; + }; +} + +#endif /* UI_CHECK_ITEM */ diff --git a/lib-apps-common/inc/Ui/Control.h b/lib-apps-common/inc/Ui/Control.h new file mode 100644 index 0000000..725a009 --- /dev/null +++ b/lib-apps-common/inc/Ui/Control.h @@ -0,0 +1,158 @@ +/* + * Copyright 2016 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.1 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://floralicense.org/license/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef UI_CONTROL_H +#define UI_CONTROL_H + +#include +#include +#include + +/** + * @brief Define class type so it can be detected from a more derived class instance. + * @details Overrides hasType() method by checking against the given static type + * and all base types recursively. + */ +#define DEFINE_CLASS_TYPE(classType, baseClassType) \ + virtual bool hasType(const std::type_info &type) const override \ + { \ + return typeid(classType) == type || baseClassType::hasType(type); \ + } + +namespace Ui +{ + /** + * @brief Evas_Object wrapper. + * @details Ties the lifetime of this object to the underlying Evas_Object. + * @remark Should always be allocated with operator "new". + */ + class EXPORT_API Control + { + public: + Control(); + Control(const Control &that) = delete; + virtual ~Control(); + + Control &operator=(const Control &that) = delete; + + /** + * @brief Create underlying Evas_Object by calling onCreate() + * @param[in] parent Parent Evas_Object + * @return Created Evas_Object on success, otherwise nullptr + */ + Evas_Object *create(Evas_Object *parent); + + /** + * @brief Set delay between onCreate() and onCreated(). + * @param[in] time Delay time + */ + void setCreateTimer(double time); + + /** + * @brief Remove delay between onCreate() and onCreated(). + * @remark If timer is currently running onCreated() will be called immediately. + */ + void resetCreateTimer(); + + /** + * @return Underlying Evas_Object. + */ + Evas_Object *getEvasObject() const; + + /**@{*/ + /** + * @brief Get Control object from Evas_Object by type. + * @remark The specified type should be either the most derived class or + * should be defined using DEFINE_CLASS_TYPE macro in the respective class. + * @param[in] object Evas_Object that belongs to some Control + * @return Control of the specified type tied to Evas_Object or nullptr if none. + */ + template + static ControlType *getControl(Evas_Object *object); + static Control *getControl(Evas_Object *object, const std::type_info &type); + /**@}*/ + + /**@{*/ + /** + * @brief Find closest parent Control by type. + * @see Control::getControl() + */ + static Control *findParent(Evas_Object *object, const std::type_info &type); + template + static ControlType *findParent(Evas_Object *object); + template + ControlType *findParent() const; + /**@}*/ + + /** + * @brief Check if the object has a specified type or is derived from it. + * @details A base class MUST override this method using DEFINE_CLASS_TYPE macro + * to allow detecting it from a more derived class instance. + * @param[in] type Type info to check against + * @return Whether the object has a specified type. + */ + virtual bool hasType(const std::type_info &type) const { return typeid(Control) == type; } + + protected: + /** + * @brief Called after create() is called + * @param[in] parent Parent Evas_Object + * @return Created Evas_Object on success, otherwise nullptr + */ + virtual Evas_Object *onCreate(Evas_Object *parent) = 0; + + /** + * @brief Called after onCreate() has returned + */ + virtual void onCreated() { } + + /** + * @brief Called before Control is destroyed. + */ + virtual void onDestroy() { } + + private: + void setEvasObject(Evas_Object *object); + Evas_Object *resetEvasObject(); + void destroyEvasObject(); + + void onTypeCheck(Evas_Object *obj, void *eventInfo); + void onDestroyed(Evas *e, Evas_Object *obj, void *eventInfo); + + Evas_Object *m_Object; + Ecore_Timer *m_CreateTimer; + }; + + template + ControlType *Control::getControl(Evas_Object *object) + { + return static_cast(getControl(object, typeid(ControlType))); + } + + template + ControlType *Control::findParent(Evas_Object *object) + { + return static_cast(findParent(object, typeid(ControlType))); + } + + template + ControlType *Control::findParent() const + { + return findParent(m_Object); + } +} + +#endif /* UI_CONTROL_H */ diff --git a/lib-apps-common/inc/Ui/Editfield.h b/lib-apps-common/inc/Ui/Editfield.h new file mode 100644 index 0000000..a8d3e8d --- /dev/null +++ b/lib-apps-common/inc/Ui/Editfield.h @@ -0,0 +1,106 @@ +/* + * Copyright 2016 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.1 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://floralicense.org/license/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef UI_EDITFIELD_H +#define UI_EDITFIELD_H + +#include "Ui/Control.h" + +namespace Ui +{ + /** + * @brief Editfield layout with entry and "clear" button + */ + class EXPORT_API Editfield : public Control + { + public: + Editfield(); + + /** + * @brief Allows method overload instead of shadowing + */ + using Control::create; + + /** + * @brief Create editfield with guide text. + * @param[in] parent Editfield parent + * @param[in] guideText Text to be displayed when entry is empty + * @return Created editfield. + */ + static Editfield *create(Evas_Object *parent, const char *guideText); + + /** + * @brief Set entry multiline state. + * @param[in] isMultiline Whether entry is multiline + */ + void setMultiline(bool isMultiline); + + /** + * @brief Set entry guide text. + * @param[in] guideText Text to be displayed when entry is empty + */ + void setGuideText(const char *guideText); + + /** + * @return Contained entry. + */ + Evas_Object *getEntry(); + + /** + * @return Clear button. + */ + Evas_Object *getClearButton(); + + /** + * @brief Set whether entry is enabled or not. + * @param[in] isEnabled Whether input will be inserted in the entry + */ + void setEnabled(bool isEnabled); + + /** + * @brief Set Clear button visibility. + * @param[in] isVisible Whether Clear button is visible + */ + void setClearButtonVisible(bool isVisible); + + /** + * @brief Set limit of characters to be entered + * Relative toast popup will be shown on reach of the limit + * @param[in] limit The limit count of characters + */ + void setTextLimit(int limit); + + /** + * @brief Set the text of the limit toast popup + * @param[in] text The text + */ + void setLimitToastText(const char *text); + + private: + virtual Evas_Object *onCreate(Evas_Object *parent) override; + + static void onChanged(Editfield *editfield, Evas_Object *entry, void *eventInfo); + static void onFocused(Evas_Object *layout, Evas_Object *entry, void *eventInfo); + static void onUnfocused(Evas_Object *layout, Evas_Object *entry, void *eventInfo); + static void onClearPressed(Evas_Object *entry, Evas_Object *button, void *eventInfo); + static void onMaxLengthReached(Editfield *editfield, Evas_Object *button, void *eventInfo); + + Elm_Entry_Filter_Limit_Size m_TextLimitFilter; + const char *m_LimitToastText; + }; +} + +#endif /* UI_EDITFIELD_H */ diff --git a/lib-apps-common/inc/Ui/GenContainer.h b/lib-apps-common/inc/Ui/GenContainer.h new file mode 100644 index 0000000..918d123 --- /dev/null +++ b/lib-apps-common/inc/Ui/GenContainer.h @@ -0,0 +1,103 @@ +/* + * Copyright 2016 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.1 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://floralicense.org/license/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef UI_GEN_CONTAINER_H +#define UI_GEN_CONTAINER_H + +#include "Ui/Control.h" +#include "Ui/GenIterator.h" + +namespace Ui +{ + class EXPORT_API GenContainer : public Control + { + public: + DEFINE_CLASS_TYPE(GenContainer, Control) + + enum Type + { + TypeGenlist, + TypeGengrid + }; + + enum Position + { + Before, + After + }; + + /** + * @brief Create GenContainer. + * @param[in] type Container type. + */ + GenContainer(Type type); + + /** + * @return First Item. + */ + GenItem *getFirstItem() const; + + /** + * @return Last Item. + */ + GenItem *getLastItem() const; + + /** + * @return Begin iterator. + */ + GenIterator begin() const; + + /** + * @return End iterator. + */ + GenIterator end() const; + + /** + * @brief Insert item at specified position. + * @param[in] item Item to insert + * @param[in] parent Parent item + * @param[in] sibling Sibling item + * @param[in] position Insert before/after @a sibling + * @remarks Inserting item BEFORE nullptr (@a sibling) + * actually means that there is no items after it (i.e. item is appended). + * Same goes for inserting AFTER nullptr (i.e. item is prepended). + * This might seem like a counter-intuitive behavior but it supports + * commonly used pattern. + */ + void insert(GenItem *item, GenItem *parent = nullptr, GenItem *sibling = nullptr, + Position position = Before); + + /** + * @brief Update specific parts of realized items. + * @param[in] parts The name of item parts + * @param[in] type The type of item parts + * @see Elm_Genlist_Item_Field_Type or Elm_Gengrid_Item_Field_Type + */ + void update(const char *parts, int type); + + private: + virtual Evas_Object *onCreate(Evas_Object *parent) override; + + static void onItemSelected(void *data, Evas_Object *obj, Elm_Object_Item *objectItem); + static void onItemLongpressed(void *data, Evas_Object *obj, Elm_Object_Item *objectItem); + static void onItemRealized(void *data, Evas_Object *obj, Elm_Object_Item *objectItem); + static void onItemUnrealized(void *data, Evas_Object *obj, Elm_Object_Item *objectItem); + + const struct GenContainerApi *m_Api; + }; +} + +#endif /* UI_GEN_CONTAINER_H */ diff --git a/lib-apps-common/inc/Ui/GenGroupItem.h b/lib-apps-common/inc/Ui/GenGroupItem.h new file mode 100644 index 0000000..c5279ff --- /dev/null +++ b/lib-apps-common/inc/Ui/GenGroupItem.h @@ -0,0 +1,142 @@ +/* + * Copyright 2016 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.1 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://floralicense.org/license/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef UI_GEN_GROUP_ITEM_H +#define UI_GEN_GROUP_ITEM_H + +#include "Ui/GenContainer.h" +#include "Ui/GenItem.h" + +#include +#include + +namespace Ui +{ + class EXPORT_API GenGroupItem : virtual public GenItem + { + public: + /** + * @brief Create group item. + * @param[in] title Item title (can be translatable) + */ + explicit GenGroupItem(const char *title = nullptr); + virtual ~GenGroupItem() override; + + /** + * @return Group first child Item. + */ + GenItem *getFirstItem() const; + + /** + * @return Group last child Item. + */ + GenItem *getLastItem() const; + + /** + * @return Group begin iterator. + */ + GenIterator begin(); + + /** + * @return Group end iterator. + */ + GenIterator end(); + + /** + * @return Child items count. + */ + size_t getItemCount() const; + + /** + * @return Whether the group has no items (i.e. GroupItem has no subitems). + */ + bool isEmpty() const; + + /** + * @return Whether subitems are shown. + */ + bool isExpanded() const; + + /** + * @return Group item of the next group or nullptr if none. + */ + GenGroupItem *getNextGroupItem() const; + + /** + * @return Group item of the previous group or nullptr if none. + */ + GenGroupItem *getPrevGroupItem() const; + + /** + * @brief Insert sub item to the group. + * @details If group item is not yet inserted itself, sub item is cached + * and inserted into container when it's parent is inserted. + * @see GenContainer::insert() + */ + void insertSubItem(GenItem *item, GenItem *sibling = nullptr, + GenContainer::Position position = GenContainer::Before); + + protected: + /** + * @see GenItem::isGroupItem() + */ + virtual bool isGroupItem() const override { return true; } + + /** + * @see GenItem::getType() + */ + virtual Elm_Genlist_Item_Type getType() const override { return ELM_GENLIST_ITEM_GROUP; } + + /** + * @see GenItem::getItemClass() + */ + virtual Elm_Gen_Item_Class *getItemClass() const override; + + /** + * @brief Sets item title into "elm.text" part. + * @see GenItem::getText() + */ + virtual char *getText(Evas_Object *parent, const char *part) override; + + /** + * @brief Inserts all subitems. + * @see GenItem::onInserted() + */ + virtual void onInserted() override; + + /** + * @brief Pops all subitems. + * @see GenItem::onPop() + */ + virtual void onPop() override; + + /** + * @brief Called when tree item is expanded or contracted. + */ + virtual void onExpanded(bool isExpanded); + + private: + friend class Genlist; + + void insertSubItems(); + void popSubItems(); + + std::string m_Title; + std::vector m_ItemsCache; + }; +} + +#endif /* UI_GEN_GROUP_ITEM_H */ diff --git a/lib-apps-common/inc/Ui/GenItem.h b/lib-apps-common/inc/Ui/GenItem.h new file mode 100644 index 0000000..8e4917e --- /dev/null +++ b/lib-apps-common/inc/Ui/GenItem.h @@ -0,0 +1,269 @@ +/* + * Copyright 2016 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.1 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://floralicense.org/license/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef UI_GEN_ITEM_H +#define UI_GEN_ITEM_H + +#include "Ui/GenContainer.h" +#include "Utils/String.h" + +#include +#include + +namespace Ui +{ + class GenItem; + class GenGroupItem; + typedef std::weak_ptr GenItemPtr; + + class EXPORT_API GenItem + { + public: + /** + * @brief Called when item is selected. + */ + typedef std::function SelectCallback; + + /** + * @brief Called before item is destroyed. + */ + typedef std::function DestroyCallback; + + /** + * @brief Create generic container item. + * @param[in] type Parent container type + */ + GenItem(GenContainer::Type type = GenContainer::TypeGenlist); + virtual ~GenItem(); + + /** + * @return Whether the item is realized. + */ + bool isRealized() const; + + /** + * @return Whether the item is inserted into container. + */ + bool isInserted() const; + + /** + * @return Whether the item is visible. + */ + bool isVisible() const; + + /** + * @return Whether the item is a group item. + */ + virtual bool isGroupItem() const { return false; } + + /** + * @return Whether the item can receive focus. + */ + virtual bool isFocusable() const { return false; } + + /** + * @return Item type. + */ + virtual Elm_Genlist_Item_Type getType() const { return ELM_GENLIST_ITEM_NONE; } + + /** + * @return Container object item. + */ + Elm_Object_Item *getObjectItem() const; + + /** + * @return Parent container. + */ + GenContainer *getParent() const; + + /** + * @return Parent group item or nullptr if none. + */ + GenGroupItem *getParentItem() const; + + /** + * @return Next item in container or nullptr if none. + */ + GenItem *getNextItem() const; + + /** + * @return Previous item in container or nullptr if none. + */ + GenItem *getPrevItem() const; + + /** + * @return GenItem weak pointer for safe referencing. + */ + GenItemPtr getWeakPtr(); + + /** + * @brief Set item selection callback. + * @param[in] callback Callback to be called when item is selected + */ + void setSelectCallback(SelectCallback callback); + + /** + * @brief Set item destruction callback. + * @param[in] callback Callback to be called before item is destroyed + */ + void setDestroyCallback(DestroyCallback callback); + + /** + * @brief Scroll to the item. + * @param[in] position Item position on screen + * @param[in] isAnimated Whether scrolling is animated or immediate + * @see Elm_Genlist_Item_Scrollto_Type or Elm_Gengrid_Item_Scrollto_Type + */ + void scrollTo(int position = ELM_GENLIST_ITEM_SCROLLTO_IN, + bool isAnimated = false); + + /** + * @brief Scroll to the item and give it focus. + * @see GenItem::scrollTo() + */ + void focus(Elm_Genlist_Item_Scrollto_Type position = ELM_GENLIST_ITEM_SCROLLTO_IN, + bool isAnimated = false); + + /** + * @brief Update item part. + * @see elm_gelist_item_fields_update or elm_gengrid_item_fields_update + */ + void update(const char *parts, int partType); + + /** + * @brief Remove item from genlist without destroying it. + */ + void pop(); + + protected: + /** + * @brief Create statically allocated item class + */ + static Elm_Gen_Item_Class createItemClass(const char *style, + const char *decorateStyle = nullptr, + const char *editStyle = nullptr); + + /** + * @return Generic item class of this item. + */ + virtual Elm_Gen_Item_Class *getItemClass() const; + + /** + * @brief Called whenever any item's text part needs to be updated. + * @param[in] parent Parent genlist + * @param[in] part Name of the part + * @return Allocated string with text for a specified part, + * it will be deallocated with free() by genlist. + */ + virtual char *getText(Evas_Object *parent, const char *part) { return nullptr; } + + /** + * @brief Called whenever any item's content part needs to be updated. + * @param[in] parent Parent genlist + * @param[in] part Name of the part + * @return Content for a specified part. + */ + virtual Evas_Object *getContent(Evas_Object *parent, const char *part) { return nullptr; } + + /** + * @brief Called whenever any item's state part needs to be updated + * @details Genlist will emit signal "elm,state,x,active" or "elm,state,x,passive" + * with part's name instead of 'x'. + * @param[in] parent Parent genlist + * @param[in] part Name of the part + * @return EINA_TRUE for active, EINA_FALSE for passive + */ + virtual Eina_Bool getState(Evas_Object *parent, const char *part) { return EINA_FALSE; } + + /** + * @brief Called when genlist filter is set using elm_genlist_filter_set(). + * @param[in] filter Filter to compare with + * @return Whether the item satisfies the filter. + */ + virtual bool compare(void *filter) { return true; } + + /** + * @brief Called after item was inserted into genlist. + */ + virtual void onInserted() { } + + /** + * @brief Called before item is popped. + */ + virtual void onPop() { } + + /** + * @brief Called when item visibility changes via pop() or compare() or + * insertion into container. + */ + virtual void onVisibilityChanged(bool isVisible) { } + + /** + * @brief Called when item is selected. + */ + virtual void onSelected() { } + + /** + * @brief Called when item is longpressed. + * @return Whether event is handled and onSelected() shouldn't be called. + */ + virtual bool onLongpressed() { return false; } + + /** + * @brief Called when item is realized (its content is created). + */ + virtual void onRealized() { } + + /** + * @brief Called when item is unrealized and its text and content are + * deleted until it is realized again. + */ + virtual void onUnrealized() { } + + /** + * @brief Called when item is focused by calling focus(). + */ + virtual void onFocused() { } + + private: + void updateVisibility(); + + friend class GenContainer; + void onInserted(Elm_Object_Item *item); + Eina_Bool onFiltered(Evas_Object *parent, void *filter); + void onDestroy(Evas_Object *genlist); + + void onSelected(Elm_Object_Item *item); + void onLongpressed(Elm_Object_Item *item); + void onRealized(Elm_Object_Item *item); + void onUnrealized(Elm_Object_Item *item); + + Elm_Object_Item *m_Item; + bool m_Preserve; + bool m_IsMatching; + bool m_IsRealized; + bool m_IsVisible; + bool m_IsFocusPending; + bool m_IsLongpressed; + + std::shared_ptr m_SelfPtr; + SelectCallback m_OnSelected; + DestroyCallback m_OnDestroy; + const struct GenItemApi *m_Api; + }; +} + +#endif /* UI_GEN_ITEM_H */ diff --git a/lib-apps-common/inc/Ui/GenIterator.h b/lib-apps-common/inc/Ui/GenIterator.h new file mode 100644 index 0000000..09e0c16 --- /dev/null +++ b/lib-apps-common/inc/Ui/GenIterator.h @@ -0,0 +1,67 @@ +/* + * Copyright 2016 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.1 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://floralicense.org/license/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef UI_GEN_ITERATOR_H +#define UI_GEN_ITERATOR_H + +#include +#include + +namespace Ui +{ + class GenItem; + + /** + * @brief GenContainer items iterator. + */ + class EXPORT_API GenIterator : + public std::iterator + { + public: + /** + * @brief Create iterator + * @param[in] item Item pointed by iterator + */ + GenIterator(GenItem *item = nullptr); + + /** + * @brief Increment iterator. + */ + GenIterator &operator++(); + GenIterator operator++(int); + + /** + * @brief Decrement iterator. + */ + GenIterator &operator--(); + GenIterator operator--(int); + + /** + * @brief Dereference iterator. + */ + GenItem *operator*() const; + + /** + * @brief Compare iterators for inequality. + */ + bool operator!=(const GenIterator &that) const; + + private: + GenItem *m_Item; + }; +} + +#endif /* UI_GEN_ITERATOR_H */ diff --git a/lib-apps-common/inc/Ui/Gengrid.h b/lib-apps-common/inc/Ui/Gengrid.h new file mode 100644 index 0000000..0643258 --- /dev/null +++ b/lib-apps-common/inc/Ui/Gengrid.h @@ -0,0 +1,36 @@ +/* + * Copyright 2016 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.1 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://floralicense.org/license/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef UI_GENGRID_H +#define UI_GENGRID_H + +#include "Ui/GenContainer.h" + +namespace Ui +{ + class EXPORT_API Gengrid : public GenContainer + { + public: + Gengrid(); + + /** + * @see GenContainer::insert() + */ + void insert(GenItem *item, GenItem *sibling = nullptr, Position position = Before); + }; +} + +#endif /* UI_GENGRID_H */ diff --git a/lib-apps-common/inc/Ui/Genlist.h b/lib-apps-common/inc/Ui/Genlist.h new file mode 100644 index 0000000..bbfdc39 --- /dev/null +++ b/lib-apps-common/inc/Ui/Genlist.h @@ -0,0 +1,38 @@ +/* + * Copyright 2016 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.1 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://floralicense.org/license/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef UI_GENLIST_H +#define UI_GENLIST_H + +#include "Ui/GenContainer.h" + +namespace Ui +{ + class EXPORT_API Genlist : public GenContainer + { + public: + Genlist(); + + protected: + virtual void onCreated() override; + + private: + static void onItemExpanded(void *data, Evas_Object *obj, Elm_Object_Item *objectItem); + static void onItemContracted(void *data, Evas_Object *obj, Elm_Object_Item *objectItem); + }; +} + +#endif /* UI_GENLIST_H */ diff --git a/lib-apps-common/inc/Ui/Hoversel.h b/lib-apps-common/inc/Ui/Hoversel.h new file mode 100644 index 0000000..3f62df7 --- /dev/null +++ b/lib-apps-common/inc/Ui/Hoversel.h @@ -0,0 +1,71 @@ +/* + * Copyright 2016 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.1 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://floralicense.org/license/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef UI_HOVERSEL_H +#define UI_HOVERSEL_H + +#include "Ui/Selector.h" + +namespace Ui +{ + class View; + + class EXPORT_API Hoversel : public Selector + { + public: + Hoversel(); + virtual ~Hoversel() override; + + /** + * @brief Add item with text. + * @param[in] text Item text + * @param[in] value Item data + * @return Added item on success, otherwise nullptr. + * @see Selector::addItem() + */ + Elm_Object_Item *addItem(const char *text, void *data); + + /** + * @see Selector::addItem() + */ + virtual Elm_Object_Item *addItem(void *data) override; + + /** + * @brief Set text of currently selected item. + * @param[in] text Text to be displayed in hoversel button + */ + void setText(const char *text); + + /** + * @see Selector::setSelectedItem() + */ + virtual void setSelectedItem(Elm_Object_Item *item) override; + + protected: + virtual Evas_Object *onCreate(Evas_Object *parent) override; + + private: + void onViewNavigation(Evas_Object *obj, void *eventInfo); + void onSelected(Evas_Object *hoversel, Elm_Object_Item *item); + static void onExpanded(void *data, Evas_Object *hoversel, void *eventInfo); + static void onDismissed(void *data, Evas_Object *hoversel, void *eventInfo); + static void onBackPressed(void *data, Evas_Object *hoversel, void *eventInfo); + + View *m_View; + }; +} + +#endif /* UI_HOVERSEL_H */ diff --git a/lib-apps-common/inc/Ui/ListPopup.h b/lib-apps-common/inc/Ui/ListPopup.h new file mode 100644 index 0000000..e99f172 --- /dev/null +++ b/lib-apps-common/inc/Ui/ListPopup.h @@ -0,0 +1,117 @@ +/* + * Copyright 2016 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.1 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://floralicense.org/license/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef UI_LIST_POPUP_H +#define UI_LIST_POPUP_H + +#include "Ui/Popup.h" + +namespace Ui +{ + class EXPORT_API ListPopup : public Popup + { + public: + /** + * @brief Specific item selection callback. + */ + typedef std::function ItemSelectCallback; + + /** + * @brief Any item selection callback. + * @param[in] Item data + */ + typedef std::function SelectCallback; + + /** + * @brief Create list popup + * @param[in] itemStyle Genlist item style + */ + ListPopup(const char *itemStyle = "type1"); + virtual ~ListPopup() override; + + /** + * @brief Add ListPopup item + * @param[in] text Main text of the item + * @param[in] data Data associated with the item + * @param[in] callback Callback to be called when item is selected + * @return Added item on success, otherwise nullptr + */ + Elm_Object_Item *addItem(std::string text, void *data, ItemSelectCallback callback = nullptr); + Elm_Object_Item *addItem(std::string text, ItemSelectCallback callback = nullptr); + Elm_Object_Item *addItem(void *data, ItemSelectCallback callback = nullptr); + + /** + * @brief Set item selection callback. + * @param[in] callback Callback to be called when any item is selected + */ + void setSelectCallback(SelectCallback callback); + + protected: + /** + * @see Control::onCreate() + */ + virtual Evas_Object *onCreate(Evas_Object *parent) override; + + /** + * @brief Create genlist + */ + Evas_Object *createGenlist(Evas_Object *parent); + + /** + * @brief Called when item's text part needs to be updated. + * @details If "elm.text" part is not handled in this function then it will + * contain the text specified in ListPopup::addItem(). + * @see Elm_Gen_Item_Text_Get_Cb. + */ + virtual char *getItemText(void *data, const char *part) { return nullptr; } + + /** + * @brief Called when item's content part needs to be updated. + * @see Elm_Gen_Item_Content_Get_Cb. + */ + virtual Evas_Object *getItemContent(void *data, const char *part) { return nullptr; } + + /** + * @brief Called when any item is selected. + * @param[in] data Item data + */ + virtual void onItemSelected(void *data) { } + + private: + struct ItemData; + + static char *getText(ItemData *itemData, Evas_Object *genlist, const char *part); + static Evas_Object *getContent(ItemData *itemData, Evas_Object *genlist, const char *part); + static void onSelected(ListPopup *popup, Evas_Object *genlist, Elm_Object_Item *item); + + void updateGenlistHeight(); + void updateMaxHeight(); + + void onGenlistResized(Evas *e, Evas_Object *genlist, void *eventInfo); + void onWindowResized(Evas *e, Evas_Object *window, void *eventInfo); + + Evas_Coord_Size m_GenlistSize; + int m_MaxHeight; + bool m_IsResizing; + + Evas_Object *m_Window; + Evas_Object *m_Genlist; + Elm_Genlist_Item_Class *m_ItemClass; + SelectCallback m_OnSelected; + }; +} + +#endif /* UI_LIST_POPUP_H */ diff --git a/lib-apps-common/inc/Ui/Menu.h b/lib-apps-common/inc/Ui/Menu.h new file mode 100644 index 0000000..5b8a773 --- /dev/null +++ b/lib-apps-common/inc/Ui/Menu.h @@ -0,0 +1,68 @@ +/* + * Copyright 2016 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.1 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://floralicense.org/license/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef UI_MENU_H +#define UI_MENU_H + +#include "Ui/Control.h" +#include + +namespace Ui +{ + class View; + class Window; + + class EXPORT_API Menu : public Control + { + public: + /** + * @brief Item selection callback + */ + typedef std::function ItemCallback; + + Menu(); + virtual ~Menu() override; + + /** + * @brief Add menu item + * @param[in] text Item text + * @param[in] callback Item selection callback + * @return Added item on success, otherwise nullptr + */ + Elm_Object_Item *addItem(const char *text, ItemCallback callback); + + /** + * @brief Show menu at the bottom of application window. + */ + void show(); + + protected: + virtual Evas_Object *onCreate(Evas_Object *parent) override; + + private: + void onViewNavigation(Evas_Object *obj, void *eventInfo); + void onWindowResized(Evas *e, Evas_Object *obj, void *eventInfo); + + static void onItemSelect(void *data, Evas_Object *obj, void *item); + static void onItemDestroy(void *data, Evas_Object *obj, void *item); + void onDismissed(Evas_Object *obj, void *eventInfo); + + View *m_View; + Window *m_Window; + }; +} + +#endif /* UI_MENU_H */ diff --git a/lib-apps-common/inc/Ui/Naviframe.h b/lib-apps-common/inc/Ui/Naviframe.h new file mode 100644 index 0000000..de7c2a2 --- /dev/null +++ b/lib-apps-common/inc/Ui/Naviframe.h @@ -0,0 +1,65 @@ +/* + * Copyright 2016 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.1 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://floralicense.org/license/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef UI_NAVIFRAME_H +#define UI_NAVIFRAME_H + +#include "Ui/Navigator.h" +#include "Ui/NaviframePage.h" +#include + +namespace Ui +{ + /** + * @brief Naviframe wrapper + */ + class EXPORT_API Naviframe : public Navigator + { + public: + DEFINE_CLASS_TYPE(Naviframe, Navigator) + + Naviframe(); + + /** + * @brief Set visibility of Previous button in first page. + * @param[in] isVisible Whether Previous button is visible + */ + void setFirstPagePrevButton(bool isVisible); + + protected: + virtual Evas_Object *onCreate(Evas_Object *parent) override; + virtual bool onBackPressed() override; + + virtual NaviframePage *addPage(View *view) override; + virtual bool removePage(NavigatorPage *page) override; + virtual void navigateToPage(NavigatorPage *page) override; + + private: + NaviframePage *getFirstPage() const; + NaviframePage *getLastPage() const; + + Eina_Bool onItemPop(Elm_Object_Item *item); + void onTransition(Evas_Object *obj, void *eventInfo); + void onFirstPagePushed(); + void updateCurrentPage(); + + Ecore_Job *m_Job; + bool m_IsFirstPagePrevButtonVisible; + std::vector m_PagesToRemove; + }; +} + +#endif /* UI_NAVIFRAME_H */ diff --git a/lib-apps-common/inc/Ui/NaviframePage.h b/lib-apps-common/inc/Ui/NaviframePage.h new file mode 100644 index 0000000..2b16a5f --- /dev/null +++ b/lib-apps-common/inc/Ui/NaviframePage.h @@ -0,0 +1,74 @@ +/* + * Copyright 2016 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.1 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://floralicense.org/license/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef UI_NAVIFRAME_PAGE_H +#define UI_NAVIFRAME_PAGE_H + +#include "Ui/NavigatorPage.h" + +namespace Ui +{ + class EXPORT_API NaviframePage : public NavigatorPage + { + public: + /** + * @brief Create naviframe page + * @param[in] naviItem Naviframe item + */ + NaviframePage(Elm_Object_Item *naviItem); + + /** + * @see NavigatorPage::setTitle() + */ + virtual void setTitle(const char *title) override; + + /** + * @see NavigatorPage::setSubtitle() + */ + virtual void setSubtitle(const char *subtitle) override; + + /** + * @see NavigatorPage::setTitleVisibility() + */ + virtual void setTitleVisibility(bool isVisible) override; + + /** + * @see NavigatorPage::setStyle() + */ + virtual void setStyle(const char *style) override; + + /** + * @see NavigatorPage::setContent() + */ + virtual void setContent(const char *part, Evas_Object *content) override; + + /** + * @brief Set visibility of Previous button. + * @param[in] isVisible Whether Previous button is visible + */ + void setPrevButtonVisibility(bool isVisible); + + private: + friend class Naviframe; + + void onDestroy(Evas_Object *obj, void *eventInfo); + void onPrevPressed(Evas_Object *obj, void *eventInfo); + + Elm_Object_Item *m_NaviItem; + }; +} + +#endif /* UI_NAVIFRAME_PAGE_H */ diff --git a/lib-apps-common/inc/Ui/Navigator.h b/lib-apps-common/inc/Ui/Navigator.h new file mode 100644 index 0000000..57d060c --- /dev/null +++ b/lib-apps-common/inc/Ui/Navigator.h @@ -0,0 +1,138 @@ +/* + * Copyright 2016 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.1 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://floralicense.org/license/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef UI_NAVIGATOR_H +#define UI_NAVIGATOR_H + +#include "Ui/View.h" +#include + +namespace Ui +{ + class NavigatorPage; + + /** + * @brief Navigator base class. + */ + class EXPORT_API Navigator : public View + { + public: + /** + * @brief Called when the navigator is about to navigate away + * from it's last remaining page. + * @return Whether to navigate from the last page. + */ + typedef std::function LastPageCallback; + + Navigator(); + + /** + * @return Currently displayed page. + */ + NavigatorPage *getCurrentPage() const; + + /** + * @brief Add view to navigator. + * @details Adding a view may also result in navigating to it + * if it's a first view or this is a #StackNavigator. + * @param[in] view View to add + */ + void addView(View *view); + + /** + * @brief Remove the view from the navigator. + * @details If the removed view is a current view then the navigation + * will occur to the nearest view. + * @param[in] view View to remove + * @return Whether the view was removed. + */ + bool removeView(View *view); + + /** + * @brief Navigate to existing or new View. + * @param[in] view View to navigate to + */ + void navigateTo(View *view); + + /** + * @brief Set last page callback. + * @param[in] callback Last page navigation callback. + */ + void setLastPageCallback(LastPageCallback callback); + + /** + * @brief Unset last page callback. + */ + void unsetLastPageCallback(); + + protected: + /** + * @brief Create new page for a view. + * @param[in] view View to add page for + * @return NavigatorPage for the view. + */ + virtual NavigatorPage *addPage(View *view) = 0; + + /** + * @brief Remove the page. + * @param[in] page Page to remove + * @return Whether the page was removed. + */ + virtual bool removePage(NavigatorPage *page) = 0; + + /** + * @brief Navigate to page. + * @param[in] page Page to navigate to + * @remark The page is guaranteed to be different from the current page. + */ + virtual void navigateToPage(NavigatorPage *page) = 0; + + /** + * @brief Set current page and notify pages about navigation. + * @param[in] page New current page + */ + void setCurrentPage(NavigatorPage *page); + + /** + * @see View::onNavigation() + */ + virtual void onNavigation(bool isCurrent) override; + + /** + * @see View::onRotationChanged() + */ + virtual void onRotationChanged(int degree) override; + + /** + * @see View::onBackPressed() + */ + virtual bool onBackPressed() override; + + /** + * @see View::onMenuPressed() + */ + virtual void onMenuPressed() override; + + private: + void notifyNavigation(NavigatorPage *page, bool isCurrent); + + friend class NavigatorPage; + NavigatorPage *m_CurrentPage; + LastPageCallback m_OnLastPage; + }; +} + +#endif /* UI_NAVIGATOR_H */ diff --git a/lib-apps-common/inc/Ui/NavigatorPage.h b/lib-apps-common/inc/Ui/NavigatorPage.h new file mode 100644 index 0000000..5282e39 --- /dev/null +++ b/lib-apps-common/inc/Ui/NavigatorPage.h @@ -0,0 +1,113 @@ +/* + * Copyright 2016 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.1 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://floralicense.org/license/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef UI_NAVIGATOR_PAGE_H +#define UI_NAVIGATOR_PAGE_H + +#include +#include + +namespace Ui +{ + class Navigator; + class View; + + enum ButtonPosition + { + ButtonLeft, + ButtonRight + }; + + /** + * @brief Navigator page base class. + */ + class EXPORT_API NavigatorPage + { + public: + NavigatorPage(); + virtual ~NavigatorPage() { } + + /** + * @return Parent navigator. + */ + Navigator *getNavigator() const; + + /** + * @return Contained view. + */ + View *getView() const; + + /** + * @brief Add button to page title. + * @param[in] position Button position + * @param[in] text Button translatable text + * @param[in] callback Button click callback + * @param[in] data Click callback data + * @return Added button. + */ + Evas_Object *addTitleButton(ButtonPosition position, const char *text, + Evas_Smart_Cb callback, void *data); + + /** + * @brief Set page title. + * @param[in] title Page title + */ + virtual void setTitle(const char *title) = 0; + + /** + * @brief Set page subtitle. + * @param[in] subtitle Page subtitle + */ + virtual void setSubtitle(const char *subtitle) = 0; + + /** + * @brief Set whether to show the page title. + * @param[in] isVisible Whether page title is visible + */ + virtual void setTitleVisibility(bool isVisible) = 0; + + /** + * @brief Set page style. + * @param[in] style Page style + */ + virtual void setStyle(const char *style) = 0; + + /** + * @brief Set page part content. + * @param[in] content Content to set to page part + */ + virtual void setContent(const char *part, Evas_Object *content) = 0; + + /** + * @brief Set whether to show page's title instead of navigator's. + */ + virtual void setExpanded(bool isExpanded); + + /** + * @brief Close the page and destroy its content. + */ + void close(); + + private: + friend class Navigator; + void onNavigatorAttached(Navigator *navigator, View *view); + + Navigator *m_Navigator; + View *m_View; + }; +} + +#endif /* UI_NAVIGATOR_PAGE_H */ diff --git a/lib-apps-common/inc/Ui/Popup.h b/lib-apps-common/inc/Ui/Popup.h new file mode 100644 index 0000000..6737117 --- /dev/null +++ b/lib-apps-common/inc/Ui/Popup.h @@ -0,0 +1,124 @@ +/* + * Copyright 2016 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.1 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://floralicense.org/license/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef UI_POPUP_H +#define UI_POPUP_H + +#include "Ui/Control.h" +#include + +namespace Ui +{ + class View; + class Window; + + class EXPORT_API Popup : public Control + { + public: + /** + * @brief Popup button press callback. + * @return Whether to close the popup. + */ + typedef std::function ButtonCallback; + + Popup(); + virtual ~Popup() override; + + /** + * @brief Allows method overload instead of shadowing. + */ + using Control::create; + + /** + * @brief Create popup with title, text and close button. + * @param[in] parent Popup parent + * @param[in] title Popup title + * @param[in] text Popup text + * @param[in] buttonText Text for close button + * @return Created popup. + */ + static Popup *create(Evas_Object *parent, const char *title, + const char *text, const char *buttonText); + + /** + * @brief Set Popup title. + * @param[in] title Popup title + */ + void setTitle(const char *title); + + /** + * @brief Set Popup text. + * @param[in] text Popup text + */ + void setText(const char *text); + + /** + * @brief Set Popup content. + * @param[in] content Popup content + */ + void setContent(Evas_Object *content); + + /** + * @brief Set callback to be called when Popup is canceled. + * @param[in] callback Cancel callback + */ + void setCancelCallback(ButtonCallback callback); + + /** + * @brief Add Popup button. + * @param[in] text Button text + * @param[in] callback Button click callback + * @return Added button on success, otherwise nullptr. + */ + Evas_Object *addButton(const char *text, ButtonCallback callback = nullptr); + + /** + * @brief Show popup with animation. + */ + void show(); + + /** + * @brief Close popup with animation. + */ + void close(); + + protected: + /** + * @see Control::onCreate() + */ + virtual Evas_Object *onCreate(Evas_Object *parent) override; + + private: + void onCanceled(); + + void onViewNavigation(Evas_Object *obj, void *eventInfo); + void onViewDestroy(Evas *e, Evas_Object *obj, void *eventInfo); + + void onButtonPressed(Evas_Object *obj, void *eventInfo); + void onButtonDestroy(Evas *e, Evas_Object *obj, void *eventInfo); + void onBackPressed(Evas_Object *obj, void *eventInfo); + void onBlockPressed(Evas_Object *obj, void *eventInfo); + void onDismissed(Evas_Object *obj, void *eventInfo); + + size_t m_ButtonCount; + ButtonCallback m_OnCanceled; + + View *m_View; + Window *m_Window; + }; +} + +#endif /* UI_POPUP_H */ diff --git a/lib-apps-common/inc/Ui/ProcessPopup.h b/lib-apps-common/inc/Ui/ProcessPopup.h new file mode 100644 index 0000000..75254ba --- /dev/null +++ b/lib-apps-common/inc/Ui/ProcessPopup.h @@ -0,0 +1,84 @@ +/* + * Copyright 2016 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.1 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://floralicense.org/license/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef UI_PROCESS_POPUP_H +#define UI_PROCESS_POPUP_H + +#include "Ui/Popup.h" + +namespace Ui +{ + class EXPORT_API ProcessPopup : public Popup + { + public: + enum Size + { + SizeSmall, + SizeMedium + }; + + /** + * @brief Create popup. + * @param[in] size Popup size + * @param[in] showDelayTime Delay before showing popup + * @param[in] showMinTime Minimum time popup should be shown + */ + explicit ProcessPopup(Size size = SizeMedium, + double showDelayTime = 0.2, double showMinTime = 1.0); + virtual ~ProcessPopup() override; + + /** + * @brief Allows method overload instead of shadowing + */ + using Control::create; + + /** + * @brief Create process popup with text. + * @param[in] parent Popup parent + * @param[in] text Popup text + * @param[in] size Popup size + * @return Created popup + */ + static ProcessPopup *create(Evas_Object *parent, const char *text, Size size = SizeMedium); + + /** + * @brief Set Popup text. + * @param[in] text Popup text + */ + void setText(const char *text); + + /** + * @brief Close the popup once minimum show time has elapsed. + */ + void close(); + + protected: + virtual Evas_Object *onCreate(Evas_Object *parent) override; + + private: + Eina_Bool onShowDelayElapsed(); + Eina_Bool onShowMinElapsed(); + + Size m_Size; + Evas_Object *m_Layout; + + Ecore_Timer *m_ShowDelayTimer; + Ecore_Timer *m_ShowMinTimer; + bool m_IsDestroyPending; + }; +} + +#endif /* UI_PROCESS_POPUP_H */ diff --git a/lib-apps-common/inc/Ui/ProgressController.h b/lib-apps-common/inc/Ui/ProgressController.h new file mode 100644 index 0000000..5980706 --- /dev/null +++ b/lib-apps-common/inc/Ui/ProgressController.h @@ -0,0 +1,137 @@ +/* + * Copyright 2016 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.1 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://floralicense.org/license/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef PROGRESS_CONTROLLER_H +#define PROGRESS_CONTROLLER_H + +#include +#include +#include +#include + +namespace Ui +{ + class ProgressPopup; + + /** + * @brief Controller for ProgressPopup + */ + class EXPORT_API ProgressController + { + public: + /** + * @brief Finish progress callback. + */ + typedef std::function FinishCallback; + + /** + * @brief Cancel progress callback. + */ + typedef std::function CancelCallback; + + /** + * @brief Create controller for ProgressPopup. + * @param[in] parent Parent object + * @param[in] title Progress popup title + * @param[in] maxValue max value of progress popup + */ + ProgressController(Evas_Object *parent, const char *title, int maxValue); + ProgressController(const ProgressController &that) = delete; + virtual ~ProgressController(); + + ProgressController & operator=(const ProgressController &that) = delete; + + /** + * @brief Run progress. + */ + void run(); + + /** + * @brief Cancel the thread in which progress is running. + */ + void cancel(); + + /** + * @brief Set finish function which is called when the progress is over. + * @param[in] callback Finish function + */ + void setFinishCallback(FinishCallback callback); + + /** + * @brief Set function which is called on progress cancellation + * @param[in] callback Cancel function + */ + void setCancelCallback(CancelCallback callback); + + /** + * @return Total count of progressed items + */ + virtual size_t getTotalCount() const = 0; + + protected: + /** + * @brief Called from another thread when progress starts. + */ + virtual void onStart() = 0; + + /** + * @brief Called from main loop if the running progress is canceled or failed to start. + */ + virtual void onCanceled() { } + + /** + * @brief Called when user cancels the progress. + * @return true for further cancellation of progress's thread, false - do nothing. + */ + virtual bool onCancel(); + + /** + * @brief Set progress value. + * @remark Should be called from onStart(). + * @param[in] value The value that will be set to progress. + * @return false if progress's thread is pending cancellation, otherwise - true. + */ + bool onProgress(size_t value); + + /** + * @brief Set max value for progress popup + * @param[in] value Progress total count value + */ + void setTotalCount(size_t value); + + private: + void createProgressPopup(Evas_Object *parent, const char *title, int maxValue); + + static void onStart(void *data, Ecore_Thread *thread); + static void onNotify(void *data, Ecore_Thread *thread, void *msgData); + static void onFinish(void *data, Ecore_Thread *thread); + static void onCanceled(void *data, Ecore_Thread *thread); + + private: + bool m_IsPopupUpdating; + FinishCallback m_OnFinish; + CancelCallback m_OnCancel; + + std::condition_variable m_ContinueCondition; + Ecore_Thread *m_MainThread; + Ecore_Thread *m_Thread; + + ProgressPopup *m_ProgressPopup; + Evas_Object *m_CancelButton; + }; +} + +#endif /* PROGRESS_CONTROLLER_H */ diff --git a/lib-apps-common/inc/Ui/ProgressPopup.h b/lib-apps-common/inc/Ui/ProgressPopup.h new file mode 100644 index 0000000..08e841a --- /dev/null +++ b/lib-apps-common/inc/Ui/ProgressPopup.h @@ -0,0 +1,60 @@ +/* + * Copyright 2016 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.1 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://floralicense.org/license/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef UI_PROGRESS_POPUP_H +#define UI_PROGRESS_POPUP_H + +#include "Ui/Popup.h" + +namespace Ui +{ + class EXPORT_API ProgressPopup : public Popup + { + public: + /** + * @brief Create progress popup. + * @param[in] maxValue Max value of progressbar + */ + explicit ProgressPopup(size_t maxValue = 0); + + /** + * @brief Set progress of the progressbar + * @param[in] value Progress value + */ + void setProgress(size_t value); + + /** + * @brief Set max value of progressbar + * @param[in] maxValue Max value of progressbar + */ + void setMaxValue(size_t maxValue); + + /** + * @return Max value of progressbar + */ + size_t getMaxValue() const; + + private: + virtual Evas_Object *onCreate(Evas_Object *parent) override; + void updateTotalText(); + + size_t m_CurrentValue; + size_t m_MaxValue; + Evas_Object *m_Progressbar; + }; +} + +#endif /* UI_PROGRESS_POPUP_H */ diff --git a/lib-apps-common/inc/Ui/RadioPopup.h b/lib-apps-common/inc/Ui/RadioPopup.h new file mode 100644 index 0000000..90822dd --- /dev/null +++ b/lib-apps-common/inc/Ui/RadioPopup.h @@ -0,0 +1,47 @@ +/* + * Copyright 2016 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.1 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://floralicense.org/license/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef UI_RADIO_POPUP_H +#define UI_RADIO_POPUP_H + +#include "Ui/ListPopup.h" +#include + +namespace Ui +{ + /** + * @brief Radio popup + */ + class EXPORT_API RadioPopup : public ListPopup + { + public: + RadioPopup(); + + /** + * @brief Set selected item + * @param[in] value Selected item value + */ + void setSelectedItem(int value); + + private: + virtual Evas_Object *onCreate(Evas_Object *parent) override; + virtual Evas_Object *getItemContent(void *data, const char *part) override; + virtual void onItemSelected(void *data) override; + + Evas_Object *m_RadioGroup; + }; +} +#endif /* UI_RADIO_POPUP_H */ diff --git a/lib-apps-common/inc/Ui/Scale.h b/lib-apps-common/inc/Ui/Scale.h new file mode 100644 index 0000000..8fdcf38 --- /dev/null +++ b/lib-apps-common/inc/Ui/Scale.h @@ -0,0 +1,34 @@ +/* + * Copyright 2016 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.1 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://floralicense.org/license/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef UI_SCALE_H +#define UI_SCALE_H + +#include + +#define UI_BASE_SCALE 2.6 + +namespace Ui +{ + /** + * @brief Scale the value using application base scale and device config scale + * @param[in] value Value to scale (usually pixels) + * @return Value multiplied by scale factor + */ + EXPORT_API int getScaledValue(int value); +} + +#endif /* UI_SCALE_H */ diff --git a/lib-apps-common/inc/Ui/ScrollNavigator.h b/lib-apps-common/inc/Ui/ScrollNavigator.h new file mode 100644 index 0000000..b17e2e7 --- /dev/null +++ b/lib-apps-common/inc/Ui/ScrollNavigator.h @@ -0,0 +1,66 @@ +/* + * Copyright 2016 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.1 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://floralicense.org/license/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef UI_SCROLL_NAVIGATOR_H +#define UI_SCROLL_NAVIGATOR_H + +#include "Ui/TabNavigator.h" +#include "Ui/ScrollPage.h" +#include + +namespace Ui +{ + /** + * @brief Scrollable page navigator. + */ + class EXPORT_API ScrollNavigator : public TabNavigator + { + public: + /** + * @see TabNavigator::TabNavigator() + */ + explicit ScrollNavigator(Selector *selector = nullptr); + + /** + * @brief Set whether navigation is allowed either by user or by calling navigateTo(). + * @param[in] isEnabled Whether navigation is enabled + */ + void setNavigationEnabled(bool isEnabled); + + protected: + virtual Evas_Object *onCreate(Evas_Object *parent) override; + virtual ScrollPage *addPage(View *view) override; + virtual ScrollPage *createPage(View *view, Elm_Object_Item *item) override; + virtual void changePage(TabPage *page) override; + + private: + size_t getPageIndex(TabPage *page) const; + TabPage *getPageByIndex(size_t index) const; + + void onPageChanged(Evas_Object *obj, void *eventInfo); + void onResize(Evas *e, Evas_Object *obj, void *eventInfo); + + Evas_Object *m_Scroller; + Evas_Object *m_Box; + + Evas_Coord m_Width; + Evas_Coord m_Height; + + bool m_IsNavigationEnabled; + }; +} + +#endif /* UI_SCROLL_NAVIGATOR_H */ diff --git a/lib-apps-common/inc/Ui/ScrollPage.h b/lib-apps-common/inc/Ui/ScrollPage.h new file mode 100644 index 0000000..b47bad7 --- /dev/null +++ b/lib-apps-common/inc/Ui/ScrollPage.h @@ -0,0 +1,49 @@ +/* + * Copyright 2016 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.1 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://floralicense.org/license/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef UI_SCROLL_PAGE_H +#define UI_SCROLL_PAGE_H + +#include "Ui/TabPage.h" + +namespace Ui +{ + /** + * @brief ScrollNavigator page. + */ + class EXPORT_API ScrollPage : public TabPage + { + public: + /** + * @brief Create page. + * @param[in] tabItem Selector control item + */ + ScrollPage(Elm_Object_Item *tabItem); + + /** + * @see NavigatorPage::setExpanded() + */ + virtual void setExpanded(bool isExpanded) override; + + private: + friend class ScrollNavigator; + virtual Evas_Object *onCreate(Evas_Object *parent) override; + + Evas_Object *m_Sizer; + }; +} + +#endif /* UI_SCROLL_PAGE_H */ diff --git a/lib-apps-common/inc/Ui/Selector.h b/lib-apps-common/inc/Ui/Selector.h new file mode 100644 index 0000000..8589d7d --- /dev/null +++ b/lib-apps-common/inc/Ui/Selector.h @@ -0,0 +1,74 @@ +/* + * Copyright 2016 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.1 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://floralicense.org/license/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef UI_SELECTOR_H +#define UI_SELECTOR_H + +#include "Ui/Control.h" +#include + +namespace Ui +{ + /** + * @brief Interface for controls that provide item selection functionality. + */ + class EXPORT_API Selector : public Control + { + public: + /** + * @brief Item selection callback. + * @param[in] Item data + * @return Whether to perform the default action if any. + */ + typedef std::function SelectCallback; + + /** + * @brief Add item. + * @param[in] value Item data which will be passed to SelectedCallback + * @return Added item on success, otherwise nullptr. + */ + virtual Elm_Object_Item *addItem(void *data) = 0; + + /** + * @brief Set whether selection is enabled. + * @param[in] isEnabled Whether selection is enabled + */ + virtual void setSelectEnabled(bool isEnabled); + + /** + * @brief Set which item is currently selected. + * @param[in] item Item to be selected + */ + virtual void setSelectedItem(Elm_Object_Item *item) = 0; + + /** + * @brief Set item selection callback. + * @param[in] callback Callback to be called after item was selected + */ + void setSelectCallback(SelectCallback callback); + + protected: + /** + * @brief Item selection callback. + * @param[in] item Selected item + */ + bool onSelected(Elm_Object_Item *item); + + SelectCallback m_OnSelected; + }; +} + +#endif /* UI_SELECTOR_H */ diff --git a/lib-apps-common/inc/Ui/TabNavigator.h b/lib-apps-common/inc/Ui/TabNavigator.h new file mode 100644 index 0000000..348fa84 --- /dev/null +++ b/lib-apps-common/inc/Ui/TabNavigator.h @@ -0,0 +1,104 @@ +/* + * Copyright 2016 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.1 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://floralicense.org/license/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef UI_TAB_NAVIGATOR_H +#define UI_TAB_NAVIGATOR_H + +#include "Ui/Navigator.h" +#include "Ui/TabPage.h" +#include + +namespace Ui +{ + class Selector; + + /** + * @brief Basic tab navigator with optional selector control. + */ + class EXPORT_API TabNavigator : public Navigator + { + public: + /** + * @brief Create TabNavigator. + * @param[in] selector Selector control to use for navigation + */ + explicit TabNavigator(Selector *selector = nullptr); + + protected: + /** + * @brief Navigator's pages. + */ + typedef std::vector Pages; + + /** + * @see Control::onCreate() + */ + virtual Evas_Object *onCreate(Evas_Object *parent) override; + + /** + * @brief Sets page style and inserts selector. + * @see View::onPageAttached() + */ + virtual void onPageAttached(NavigatorPage *page) override; + + /** + * @return Selector control used for navigation. + */ + Selector *getSelector() const; + + /** + * @return Navigator's pages. + */ + const Pages &getPages() const; + + /** + * @see Navigator::addPage() + */ + virtual TabPage *addPage(View *view) override; + + /** + * @see Navigator::removePage() + */ + virtual bool removePage(NavigatorPage *page) override; + + /** + * @see Navigator::navigateToPage() + */ + virtual void navigateToPage(NavigatorPage *page) override; + + /** + * @brief Create page specific to the navigator. + * @param[in] view View to create page for + * @param[in] item Selector item associated with the page + * @return New navigator page. + */ + virtual TabPage *createPage(View *view, Elm_Object_Item *item); + + /** + * @brief Switch from current page to another page. + * @param[in] page Page to show + */ + virtual void changePage(TabPage *page); + + private: + bool onSelected(void *data); + + Selector *m_Selector; + Pages m_Pages; + }; +} + +#endif /* UI_TAB_NAVIGATOR_H */ diff --git a/lib-apps-common/inc/Ui/TabPage.h b/lib-apps-common/inc/Ui/TabPage.h new file mode 100644 index 0000000..b478b0b --- /dev/null +++ b/lib-apps-common/inc/Ui/TabPage.h @@ -0,0 +1,96 @@ +/* + * Copyright 2016 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.1 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://floralicense.org/license/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef UI_TAB_PAGE_H +#define UI_TAB_PAGE_H + +#include "Ui/Control.h" +#include "Ui/NavigatorPage.h" + +namespace Ui +{ + /** + * @brief TabNavigator page. + */ + class EXPORT_API TabPage : public Control, public NavigatorPage + { + public: + /** + * @brief Create page. + * @param[in] tabItem Selector control item associated with the page + */ + TabPage(Elm_Object_Item *tabItem); + virtual ~TabPage() override; + + /** + * @brief Set tab item title to be different from page title. + * @param[in] title Tab item title text + */ + void setTabTitle(const char *title); + + /** + * @brief Set tab item title to be the same as page title. + */ + void unsetTabTitle(); + + /** + * @see NavigatorPage::setTitle() + */ + virtual void setTitle(const char *title) override; + + /** + * @see NavigatorPage::setSubtitle() + */ + virtual void setSubtitle(const char *subtitle) override; + + /** + * @see NavigatorPage::setTitleVisibility() + */ + virtual void setTitleVisibility(bool isVisible) override; + + /** + * @see NavigatorPage::setStyle() + */ + virtual void setStyle(const char *style) override; + + /** + * @see NavigatorPage::setContent() + */ + virtual void setContent(const char *part, Evas_Object *content) override; + + protected: + /** + * @return Selector control item associated with the page. + */ + Elm_Object_Item *getTabItem() const; + + /** + * @brief Creates page layout. + * @see Control::onCreate() + */ + virtual Evas_Object *onCreate(Evas_Object *parent) override; + + private: + friend class TabNavigator; + void onTabItemDestroy(Evas_Object *obj, void *eventInfo); + + Elm_Object_Item *m_TabItem; + Evas_Object *m_Page; + bool m_HasTabTitle; + }; +} + +#endif /* UI_TAB_PAGE_H */ diff --git a/lib-apps-common/inc/Ui/Tabbar.h b/lib-apps-common/inc/Ui/Tabbar.h new file mode 100644 index 0000000..584a9ad --- /dev/null +++ b/lib-apps-common/inc/Ui/Tabbar.h @@ -0,0 +1,56 @@ +/* + * Copyright 2016 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.1 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://floralicense.org/license/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef UI_TABBAR_H +#define UI_TABBAR_H + +#include "Ui/Selector.h" + +namespace Ui +{ + /** + * @brief Selector control for switching between tabs. + */ + class EXPORT_API Tabbar : public Selector + { + public: + /** + * @see Selector::addItem() + */ + virtual Elm_Object_Item *addItem(void *data) override; + + /** + * @see Selector::setSelectEnabled() + */ + virtual void setSelectEnabled(bool isEnabled) override; + + /** + * @see Selector::setSelectedItem() + */ + virtual void setSelectedItem(Elm_Object_Item *item) override; + + protected: + /** + * @see Control::onCreate() + */ + virtual Evas_Object *onCreate(Evas_Object *parent) override; + + private: + void onSelected(Evas_Object *tabbar, Elm_Object_Item *item); + }; +} + +#endif /* UI_TABBAR_H */ diff --git a/lib-apps-common/inc/Ui/Thumbnail.h b/lib-apps-common/inc/Ui/Thumbnail.h new file mode 100644 index 0000000..e869919 --- /dev/null +++ b/lib-apps-common/inc/Ui/Thumbnail.h @@ -0,0 +1,80 @@ +/* + * Copyright 2016 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.1 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://floralicense.org/license/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef UI_THUMBNAIL_H +#define UI_THUMBNAIL_H + +#include "Ui/Control.h" + +namespace Ui +{ + class EXPORT_API Thumbnail : public Control + { + public: + enum Size + { + SizeSmall, + SizeMedium, + SizeLarge + }; + + /** + * @brief Create thumbnail + * @param[in] size Thumbnail size + */ + Thumbnail(Size size); + + /** + * @brief Allows method overload instead of shadowing + */ + using Control::create; + + /** + * @brief Create thumbnail + * @param[in] parent Thumbnail parent + * @param[in] size Thumbnail size + * @param[in] path Thumbnail Image path or nullptr for default image + * @return Created thumbnail + */ + static Thumbnail *create(Evas_Object *parent, Size size, const char *path = nullptr); + + /** + * @return Thumbnail image object. + */ + Evas_Object *getImage() const; + + /** + * @brief Set thumbnail image path + * @param[in] path Image path or nullptr for default image + */ + void setImagePath(const char *path); + + /** + * @brief Set whether minimal size hint is set for image + * @param[in] isSet Whether to set image size hint + */ + void setSizeHint(bool isSet); + + protected: + virtual Evas_Object *onCreate(Evas_Object *parent) override; + + private: + Size m_Size; + Evas_Object *m_Image; + }; +} + +#endif /* UI_THUMBNAIL_H */ diff --git a/lib-apps-common/inc/Ui/View.h b/lib-apps-common/inc/Ui/View.h new file mode 100644 index 0000000..dde0428 --- /dev/null +++ b/lib-apps-common/inc/Ui/View.h @@ -0,0 +1,103 @@ +/* + * Copyright 2016 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.1 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://floralicense.org/license/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef UI_VIEW_H +#define UI_VIEW_H + +#include "Ui/Control.h" +#include "Ui/NavigatorPage.h" + +#define EVENT_VIEW_NAVIGATION "navigation" + +namespace Ui +{ + class Navigator; + + /** + * @brief Represents content of a Window or Navigator page + */ + class EXPORT_API View : public Control + { + public: + DEFINE_CLASS_TYPE(View, Control) + + View(); + + /** + * @brief Get parent Navigator + * @param[in] type Navigator type + * @return Innermost parent Naviframe. + */ + Navigator *getNavigator() const; + + /** + * @return NavigatorPage of this View + */ + NavigatorPage *getPage() const; + + /** + * @return Whether the view is currently displayed in parent Navigator. + */ + bool isCurrent() const; + + /** + * @return Rotation degree. + */ + int getRotation() const; + + protected: + /** + * @brief Called after Navigator has navigated to or from this View + * @param[in] isCurrent Specifies the new state of this View + */ + virtual void onNavigation(bool isCurrent) { } + + /** + * @brief Called when device orientation is changed + * @param[in] degree Rotation angle + */ + virtual void onRotationChanged(int degree) { } + + /** + * @brief Called when NavigatorPage is attached to this View + */ + virtual void onPageAttached(NavigatorPage *page) { } + + /** + * @brief Called when "back" button is pressed + * @return true to navigate to the previous view, otherwise false + */ + virtual bool onBackPressed() { return true; } + + /** + * @brief Called when "menu" button is pressed + */ + virtual void onMenuPressed() { } + + private: + friend class Window; + friend class Navigator; + void onNavigatorAttached(NavigatorPage *page); + void onNavigation(bool isCurrent, int degree); + void onRotation(int degree); + + NavigatorPage *m_Page; + bool m_IsCurrent; + int m_Rotation; + }; +} + +#endif /* UI_VIEW_H */ diff --git a/lib-apps-common/inc/Ui/Window.h b/lib-apps-common/inc/Ui/Window.h new file mode 100644 index 0000000..6e134d3 --- /dev/null +++ b/lib-apps-common/inc/Ui/Window.h @@ -0,0 +1,82 @@ +/* + * Copyright 2016 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.1 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://floralicense.org/license/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef UI_WINDOW_H +#define UI_WINDOW_H + +#include "Ui/Control.h" +#include + +namespace Ui +{ + class View; + + /** + * @brief Application main window + */ + class EXPORT_API Window : public Control + { + public: + Window(); + + /** + * @return Conformant Evas_Object. + */ + Evas_Object *getConformant() const; + + /** + * @return Basic Window layout Evas_Object. + */ + Evas_Object *getBaseLayout() const; + + /** + * @brief Set whether windows supports rotation. + * @param[in] isEnabled Whether rotation is enabled + */ + void setRotationEnabled(bool isEnabled); + + /** + * @brief Attach main View to be displayed in the Window. + * @param[in] view Window main View + */ + void attachView(View *view); + + protected: + /** + * @see Control::onCreate() + */ + virtual Evas_Object *onCreate(Evas_Object *parent) override; + + /** + * @brief Called to create window Evas_Object. + * @return Window Evas_Object. + */ + virtual Evas_Object *onWindowCreate(); + + private: + void onFocused(Evas_Object *obj, void *eventInfo); + void onUnfocused(Evas_Object *obj, void *eventInfo); + void onRotationChanged(Evas_Object *obj, void *eventInfo); + void onBackPressed(Evas_Object *obj, void *eventInfo); + void onMenuPressed(Evas_Object *obj, void *eventInfo); + + Evas_Object *m_Conform; + Evas_Object *m_Layout; + View *m_MainView; + }; +} + +#endif /* UI_WINDOW_H */ diff --git a/lib-apps-common/inc/Utils/Callback.h b/lib-apps-common/inc/Utils/Callback.h new file mode 100644 index 0000000..98fe147 --- /dev/null +++ b/lib-apps-common/inc/Utils/Callback.h @@ -0,0 +1,56 @@ +/* + * Copyright 2016 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.1 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://floralicense.org/license/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef UTILS_CALLBACK_H +#define UTILS_CALLBACK_H + +#include "Utils/CallbackImpl.h" + +/** + * @brief Make C-style callback from non-static class method with object as first parameter. + * @details Generates static member function by adding void* first parameter. + * Generated function forwards calls to specified method on object passed as first parameter. + * @par example + * @code + * + * class SomeView : public View + * { + * ... + * private: + * void onButtonPressed(Evas_Object *obj, void *eventInfo); + * } + * + * void SomeView::someMethod(Evas_Object *parent) + * { + * Evas_Object *button = elm_button_add(parent); + * evas_object_smart_callback_add(button, "clicked", + * makeCallback(&SomeView::onButtonPressed), this); + * ... + * } + * + * @endcode + */ +#define makeCallback(method) \ + ::Utils::Callback::makeWithFirstParam() + +/** + * @brief Make C-style callback from non-static class method with object as last parameter. + * @see makeCallback() + */ +#define makeCallbackWithLastParam(method) \ + ::Utils::Callback::makeWithLastParam() + +#endif /* UTILS_CALLBACK_H */ diff --git a/lib-apps-common/inc/Utils/CallbackImpl.h b/lib-apps-common/inc/Utils/CallbackImpl.h new file mode 100644 index 0000000..ed25438 --- /dev/null +++ b/lib-apps-common/inc/Utils/CallbackImpl.h @@ -0,0 +1,63 @@ +/* + * Copyright 2016 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.1 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://floralicense.org/license/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef CALLBACK_IMPL_H +#define CALLBACK_IMPL_H + +namespace Utils +{ + template + class Callback; + + template + class Callback + { + public: + template + static R stubWithFirstParam(void *object, A... args) + { + return (static_cast(object)->*Method)(args...); + } + + template + static R stubWithLastParam(A... args, void *object) + { + return (static_cast(object)->*Method)(args...); + } + }; + + template + class Callback + { + public: + typedef R(*WithFirstParam)(void*, A...); + typedef R(*WithLastParam)(A..., void*); + + template + static WithFirstParam makeWithFirstParam() + { + return &Callback::template stubWithFirstParam; + } + + template + static WithLastParam makeWithLastParam() + { + return &Callback::template stubWithLastParam; + } + }; +} + +#endif /* CALLBACK_IMPL_H */ diff --git a/lib-apps-common/inc/Utils/CallbackManager.h b/lib-apps-common/inc/Utils/CallbackManager.h new file mode 100644 index 0000000..eaa11fa --- /dev/null +++ b/lib-apps-common/inc/Utils/CallbackManager.h @@ -0,0 +1,79 @@ +/* + * Copyright 2016 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.1 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://floralicense.org/license/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef UTILS_CALLBACK_MANAGER_H +#define UTILS_CALLBACK_MANAGER_H + +#include +#include + +namespace Utils +{ + /** + * @brief Provides possibility to store and invoke several callbacks at once. + * @param[in] Args Callback arguments types + */ + template + class CallbackManager + { + public: + /** + * @brief Callback prototype. + */ + typedef std::function CallbackType; + + /** + * @brief Callback and subscriber pair. + */ + typedef std::pair Callback; + + CallbackManager(); + + /** + * @return Whether there are any added callbacks. + */ + explicit operator bool() const; + + /** + * @brief Add new callback. + * @param[in] callback Callback and subscriber pair. + * @remark Subscriber can be any value by which the callback can be + * identified when removing it. However it is most convenient + * to identify it by the pointer to the object that receives it. + */ + void operator+=(Callback callback); + + /** + * @brief Remove added callback. + * @param[in] subscriber Callback subscriber. + */ + void operator-=(void *subscriber); + + /** + * @brief Invoke all added callbacks. + */ + void operator()(Args... args); + + private: + typedef std::vector Callbacks; + Callbacks m_Callbacks; + int m_Index; + }; +} + +#include "Utils/CallbackManagerImpl.h" + +#endif /* UTILS_CALLBACK_MANAGER_H */ diff --git a/lib-apps-common/inc/Utils/CallbackManagerImpl.h b/lib-apps-common/inc/Utils/CallbackManagerImpl.h new file mode 100644 index 0000000..70af5d4 --- /dev/null +++ b/lib-apps-common/inc/Utils/CallbackManagerImpl.h @@ -0,0 +1,75 @@ +/* + * Copyright 2016 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.1 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://floralicense.org/license/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef UTILS_CALLBACK_MANAGER_IMPL_H +#define UTILS_CALLBACK_MANAGER_IMPL_H + +#include "Utils/CallbackManager.h" + +/* -1 is a possible index if the first callback is removed during notification */ +#define INVALID_CALLBACK_INDEX -2 + +namespace Utils +{ + template + CallbackManager::CallbackManager() + : m_Index(INVALID_CALLBACK_INDEX) + { } + + template + CallbackManager::operator bool() const + { + return !m_Callbacks.empty(); + } + + template + void CallbackManager::operator+=(Callback callback) + { + m_Callbacks.push_back(std::move(callback)); + } + + template + void CallbackManager::operator-=(void *subscriber) + { + for (int i = 0; i < (int) m_Callbacks.size(); ++i) { + if (m_Callbacks[i].second == subscriber) { + if (i <= m_Index) { + --m_Index; + } + m_Callbacks.erase(m_Callbacks.begin() + i); + break; + } + } + } + + template + void CallbackManager::operator()(Args... args) + { + if (m_Index > INVALID_CALLBACK_INDEX) { + return; + } + + for (m_Index = 0; m_Index < (int) m_Callbacks.size(); ++m_Index) { + Callback &callback = m_Callbacks[m_Index]; + if (callback.first) { + callback.first(args...); + } + } + m_Index = INVALID_CALLBACK_INDEX; + } +} + +#endif /* UTILS_CALLBACK_MANAGER_IMPL_H */ diff --git a/lib-apps-common/inc/Utils/CallbackPair.h b/lib-apps-common/inc/Utils/CallbackPair.h new file mode 100644 index 0000000..5f65972 --- /dev/null +++ b/lib-apps-common/inc/Utils/CallbackPair.h @@ -0,0 +1,111 @@ +/* + * Copyright 2016 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.1 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://floralicense.org/license/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef UTILS_CALLBACK_PAIR_H +#define UTILS_CALLBACK_PAIR_H + +#include + +namespace Utils +{ + /** + * @brief Represents two callbacks to be called subsequently. + * @details Next callback is called each time when operator() is used. + */ + class CallbackPair + { + public: + typedef std::function Callback; + + /** + * @brief Create callback pair. + * @param[in] first First callback + * @param[in] second Second callback + */ + CallbackPair(Callback first, Callback second) + : m_Callbacks{ std::move(first), std::move(second) }, m_IsFirst(true) + { + } + + /** + * @brief Call next callback. + */ + void operator()() + { + if (m_IsFirst) { + m_Callbacks.first(); + } else { + m_Callbacks.second(); + } + m_IsFirst = !m_IsFirst; + } + + private: + std::pair m_Callbacks; + bool m_IsFirst; + }; + + /** + * @brief Provides possibility to pass a result from first callback to the second. + * @see CallbackPair. + */ + template + class CallbackPairWithResult + { + public: + /** + * @brief First callback. + * @return Result to pass to the second callback. + */ + typedef std::function FirstCallback; + + /** + * @brief Second callback. + * @param[in] Result received from the first callback. + */ + typedef std::function SecondCallback; + + /** + * @brief Create callback pair. + * @param[in] first First callback + * @param[in] second Second callback + */ + CallbackPairWithResult(FirstCallback first, SecondCallback second) + : m_Callbacks{ std::move(first), std::move(second) }, m_IsFirst(true) + { + } + + /** + * @brief Call next callback. + */ + void operator()() + { + if (m_IsFirst) { + m_Result = m_Callbacks.first(); + } else { + m_Callbacks.second(std::move(m_Result)); + } + m_IsFirst = !m_IsFirst; + } + + private: + std::pair m_Callbacks; + ResultType m_Result; + bool m_IsFirst; + }; +} + +#endif /* UTILS_CALLBACK_PAIR_H */ diff --git a/lib-apps-common/inc/Utils/EcoreUtils.h b/lib-apps-common/inc/Utils/EcoreUtils.h new file mode 100644 index 0000000..7d3151d --- /dev/null +++ b/lib-apps-common/inc/Utils/EcoreUtils.h @@ -0,0 +1,39 @@ +/* + * Copyright 2016 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.1 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://floralicense.org/license/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef UTILS_ECORE_UTILS_H +#define UTILS_ECORE_UTILS_H + +#include +#include +#include + +namespace Utils +{ + /** + * @brief Job to be executed in main loop. + */ + typedef std::function Job; + + /** + * @brief Execute a functional object in main loop. + * @param[in] job Job to execute + * @return Ecore job handle. + */ + EXPORT_API Ecore_Job *createJob(Job job); +} + +#endif /* UTILS_ECORE_UTILS_H */ diff --git a/lib-apps-common/inc/Utils/Iterator.h b/lib-apps-common/inc/Utils/Iterator.h new file mode 100644 index 0000000..31bab19 --- /dev/null +++ b/lib-apps-common/inc/Utils/Iterator.h @@ -0,0 +1,83 @@ +/* + * Copyright 2016 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.1 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://floralicense.org/license/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef UTILS_ITERATOR_H +#define UTILS_ITERATOR_H + +#include +#include + +namespace Utils +{ + /** + * @brief Base class for index-based iterators. + * @details CRTP (Curiously Recurring Template Pattern) is used to generate + * operators that return or use derived type. + */ + template + class IndexIterator : + public std::iterator + { + public: + /** + * @brief Create iterator from index. + * @param[in] index Current position of iterator + */ + IndexIterator(size_t index = 0) + : m_Index(index) { } + + /** + * @brief Dereference iterator. + */ + Pointer operator->() const { return &*getDerived(); } + + /** + * @brief Increment iterator. + */ + DerivedIterator &operator++() { ++m_Index; return getDerived(); } + DerivedIterator operator++(int) { auto it(getDerived()); ++*this; return it; } + + /** + * @brief Decrement iterator. + */ + DerivedIterator &operator--() { --m_Index; return getDerived(); } + DerivedIterator operator--(int) { auto it(getDerived()); --*this; return it; } + + /** + * @brief Compare iterators. + */ + bool operator==(const IndexIterator &that) { return m_Index == that.m_Index; } + bool operator!=(const IndexIterator &that) { return m_Index != that.m_Index; } + + protected: + /** + * @return Current index. + */ + size_t getIndex() const { return m_Index; } + + private: + DerivedIterator &getDerived() { return static_cast(*this); } + const DerivedIterator &getDerived() const { return static_cast(*this); } + + size_t m_Index; + }; +} + +#endif /* UTILS_ITERATOR_H */ diff --git a/lib-apps-common/inc/Utils/Logger.h b/lib-apps-common/inc/Utils/Logger.h new file mode 100644 index 0000000..904b347 --- /dev/null +++ b/lib-apps-common/inc/Utils/Logger.h @@ -0,0 +1,74 @@ +/* + * Copyright 2016 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.1 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://floralicense.org/license/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef UTILS_LOGGER_H +#define UTILS_LOGGER_H + +#include +#include + +namespace Utils +{ + /** + * @brief Sets the log tag + * @param[in] logTag The log tag + */ + EXPORT_API void setLogTag(const char *logTag); + + /** + * @brief Returns the log tag + * @return The log tag + */ + EXPORT_API const char *getLogTag(); +} + +#define __MODULE__ (strrchr(__FILE__, '/') ? strrchr(__FILE__, '/') + 1 : __FILE__) + +#include "Utils/Tracer.h" +#define TRACE ::Utils::Tracer tracer(::Utils::getLogTag(), __MODULE__, __func__, __LINE__) + +#define DLOG(prio, fmt, arg...) dlog_print(prio, ::Utils::getLogTag(), "%s: %s(%d) > " fmt, __MODULE__, __func__, __LINE__, ##arg) +#define DBG(fmt, arg...) DLOG(DLOG_DEBUG, fmt, ##arg) +#define ERR(fmt, arg...) DLOG(DLOG_ERROR, fmt, ##arg) + +#define LOG_IF(expr, action, fmt, arg...) \ +if (expr) { \ + ERR(fmt, ##arg); \ + action; \ +} + +#define LOG_IF_ERR(code, action, fmt, arg...) \ +LOG_IF(code != TIZEN_ERROR_NONE, action, fmt " %s.", ##arg, get_error_message(code)) + +#define WARN_IF(expr, fmt, arg...) \ +LOG_IF(expr, , fmt, ##arg) + +#define WARN_IF_ERR(code, fmt, arg...) \ +LOG_IF_ERR(code, , fmt, ##arg) + +#define RETM_IF(expr, fmt, arg...) \ +LOG_IF(expr, return, fmt, ##arg) + +#define RETM_IF_ERR(code, fmt, arg...) \ +LOG_IF_ERR(code, return, fmt, ##arg) + +#define RETVM_IF(expr, val, fmt, arg...) \ +LOG_IF(expr, return val, fmt, ##arg) + +#define RETVM_IF_ERR(code, val, fmt, arg...) \ +LOG_IF_ERR(code, return val, fmt, ##arg) + +#endif /* UTILS_LOGGER_H */ diff --git a/lib-apps-common/inc/Utils/Range.h b/lib-apps-common/inc/Utils/Range.h new file mode 100644 index 0000000..22bc6d0 --- /dev/null +++ b/lib-apps-common/inc/Utils/Range.h @@ -0,0 +1,163 @@ +/* + * Copyright 2016 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.1 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://floralicense.org/license/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef UTILS_RANGE_H +#define UTILS_RANGE_H + +#include + +namespace Utils +{ + /** + * @brief Convenience wrapper around std::advance. + * @param[in] iterator Input iterator + * @param[in] distance Distance to advance iterator + * @return New iterator at @a distance from @a iterator. + */ + template + inline Iter advance(Iter iterator, Distance distance) + { + std::advance(iterator, distance); + return iterator; + } + + /** + * @brief Convenience wrapper for iterator pair. + */ + template + class Range + { + public: + typedef typename std::iterator_traits::reference reference; + + Range() = default; + + /** + * @brief Create iterator range from static array. + * @param[in] array Static array + */ + template + Range(T(&array)[N]) + : m_Begin(array), m_End(array + N) { } + + /** + * @brief Create iterator range from begin iterator and element count + * @param[in] begin Begin iterator + * @param[in] count Count of elements until range's end + */ + Range(Iter begin, size_t count) + : m_Begin(std::move(begin)), m_End(advance(m_Begin, count)) { } + + /** + * @brief Create iterator range from pair of iterators + * @param[in] begin Begin iterator + * @param[in] end End iterator + */ + Range(Iter begin, Iter end) + : m_Begin(std::move(begin)), m_End(std::move(end)) { } + + /** + * @return Whether range is empty (i. e. begin() == end()). + */ + bool empty() const { return !(m_Begin != m_End); } + + /** + * @return Range element count. + */ + size_t count() const { return std::distance(m_Begin, m_End); } + + /** + * @return Range begin iterator. + */ + Iter &begin() { return m_Begin; } + + /** + * @return Range end iterator. + */ + Iter &end() { return m_End; } + + /** + * @return Range begin iterator. + */ + const Iter &begin() const { return m_Begin; } + + /** + * @return Range end iterator. + */ + const Iter &end() const { return m_End; } + + /** + * @see empty() + */ + explicit operator bool() const { return !empty(); } + + /** + * @brief Get range element by index. + * @param[in] index Element index + * @return Range element reference. + */ + reference operator[](size_t index) const { return *advance(m_Begin, index); } + + private: + Iter m_Begin; + Iter m_End; + }; + + /** + * @brief Create iterator range from static array. + */ + template + inline Range makeRange(T(&array)[N]) + { + return { array }; + } + + /** + * @brief Create iterator range from two iterators. + */ + template ::type> + inline Range makeRange(Iter1 &&begin, Iter2 &&end) + { + return { std::forward(begin), std::forward(end) }; + } + + /** + * @brief Get static array element count. + * @param[in] array Static array + * @return Array element count. + */ + template + inline size_t count(T(&array)[N]) + { + return N; + } + + /** + * @brief Get element by index from static array or a default value if out of bounds. + * @param[in] array Static array + * @param[in] index Element index + * @param[in] value Default value + * @return Array element or @a value. Array element is always copied. + */ + template + inline T at(T(&array)[N], size_t index, T value = T()) + { + return index < N ? array[index] : value; + } +} + +#endif /* UTILS_RANGE_H */ diff --git a/lib-apps-common/inc/Utils/String.h b/lib-apps-common/inc/Utils/String.h new file mode 100644 index 0000000..ef0cc41 --- /dev/null +++ b/lib-apps-common/inc/Utils/String.h @@ -0,0 +1,64 @@ +/* + * Copyright 2016 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.1 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://floralicense.org/license/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef UTILS_STRING_H +#define UTILS_STRING_H + +#include +#include + +namespace Utils +{ + /** + * @brief Compare strings for equality allowing null-pointers. + * @param[in] str1 First string + * @param[in] str2 Second string + * @return Whether strings are equal. + */ + inline bool safeCmp(const char *str1, const char *str2) + { + return (str1 && str2) ? (strcmp(str1, str2) == 0) : (str1 == str2); + } + + /** + * @brief Safely duplicate the string. + * @see strdup() + */ + inline char *safeDup(const char *str) + { + return str ? strdup(str) : nullptr; + } + + /** + * @brief Check whether string is empty or contains only whitespaces. + * @param[in] str String to check + * @return Whether string is empty. + */ + inline bool isStrEmpty(const char *str) + { + if (str) { + for (; *str; ++str) { + if (!isspace(*str)) { + return false; + } + } + } + + return true; + } +} + +#endif /* UTILS_STRING_H */ diff --git a/lib-apps-common/inc/Utils/Thread.h b/lib-apps-common/inc/Utils/Thread.h new file mode 100644 index 0000000..163b8bd --- /dev/null +++ b/lib-apps-common/inc/Utils/Thread.h @@ -0,0 +1,53 @@ +/* + * Copyright 2016 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.1 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://floralicense.org/license/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef UTILS_THREAD_H +#define UTILS_THREAD_H + +#include +#include +#include "Utils/CallbackPair.h" + +namespace Utils +{ + class EXPORT_API Thread + { + public: + typedef std::function Callback; + + /** + * @brief Create and start a thread. + * @param[in] callbackPair Task and finish callbacks + * @see Utils::CallbackPair + */ + explicit Thread(Callback callbackPair); + + /** + * @brief Create and start a thread. + * @param[in] task Task to be executed in the thread + * @param[in] finishCallback Callback to be called when thread is finished + */ + Thread(Callback task, Callback finishCallback); + + private: + void onStart(Ecore_Thread *thread); + void onFinished(Ecore_Thread *thread); + + Callback m_Callback; + }; +} + +#endif /* UTILS_THREAD_H */ diff --git a/lib-apps-common/inc/Utils/Tracer.h b/lib-apps-common/inc/Utils/Tracer.h new file mode 100644 index 0000000..c021597 --- /dev/null +++ b/lib-apps-common/inc/Utils/Tracer.h @@ -0,0 +1,49 @@ +/* + * Copyright 2016 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.1 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://floralicense.org/license/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef UTILS_TRACER_H +#define UTILS_TRACER_H + +#include +#include + +namespace Utils +{ + /** + * @brief Code block logger. Writes logs when created and destroyed. Outputs elapsed time. + */ + class EXPORT_API Tracer + { + public: + /** + * @brief Create tracer and write entry log. + * @param[in] tag Log tag + * @param[in] file Current source file + * @param[in] func Current function + * @param[in] line Current source line + */ + Tracer(const char *tag, const char *file, const char *func, int line); + ~Tracer(); + + private: + const char *m_Tag; + const char *m_File; + const char *m_Func; + timespec m_startTime; + }; +} + +#endif /* UTILS_TRACER_H */ diff --git a/lib-apps-common/inc/Ux/DatePopup.h b/lib-apps-common/inc/Ux/DatePopup.h new file mode 100644 index 0000000..3c1a81d --- /dev/null +++ b/lib-apps-common/inc/Ux/DatePopup.h @@ -0,0 +1,91 @@ +/* + * Copyright 2016 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.1 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://floralicense.org/license/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef UX_DATE_POPUP_H +#define UX_DATE_POPUP_H + +#include "Ui/Popup.h" +#include + +namespace Ux +{ + /** + * @brief Popup with date picker. + */ + class EXPORT_API DatePopup : public Ui::Popup + { + public: + /** + * @brief Date input result callback. + * @param[in] Inputed date + */ + typedef std::function ResultCallback; + + /** + * @brief Translatable strings table for popup elements. + */ + struct Strings + { + const char *popupTitle; /**< Popup title */ + const char *buttonDone; /**< "Done" button text */ + const char *buttonCancel; /**< "Cancel" button text */ + }; + + /** + * @brief Create date popup. + * @param[in] format Data format for elm_datetime_format_set() + * @param[in] date Initial date value + */ + DatePopup(const char *format, tm date); + + /** + * @brief Set translatable strings for popup. + * @remark Should be called before create(). + * @param[in] strings Translatable strings table + */ + void setStrings(Strings strings); + + /** + * @brief Set date input result callback. + * @param[in] callback Callback to be called when user confirmed inputed date + */ + void setResultCallback(ResultCallback callback); + + /** + * @return Contained date picker. + */ + Evas_Object *getDatePicker() const; + + protected: + /** + * @brief Creates date picker and popup buttons. + * @see Control::onCreate() + */ + virtual void onCreated() override; + + private: + bool onDonePressed(); + + std::string m_Format; + tm m_Date; + + Evas_Object *m_DatePicker; + ResultCallback m_OnResult; + Strings m_Strings; + }; +} + +#endif /* UX_DATE_POPUP_H */ diff --git a/lib-apps-common/inc/Ux/EditfieldPopup.h b/lib-apps-common/inc/Ux/EditfieldPopup.h new file mode 100644 index 0000000..3bee698 --- /dev/null +++ b/lib-apps-common/inc/Ux/EditfieldPopup.h @@ -0,0 +1,92 @@ +/* + * Copyright 2016 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.1 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://floralicense.org/license/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef UX_EDITFIELD_POPUP_H +#define UX_EDITFIELD_POPUP_H + +#include "Ui/Popup.h" + +namespace Ui +{ + class Editfield; +} + +namespace Ux +{ + /** + * @brief Popup with editfield. + */ + class EXPORT_API EditfieldPopup : public Ui::Popup + { + public: + /** + * @brief Called when user confirmation button is pressed. + * @param[in] Inputed text + * @return Whether to destroy the popup. + */ + typedef std::function ResultCallback; + + /** + * @brief Translatable strings table for popup elements. + */ + struct Strings + { + const char *popupTitle; /**< Popup title */ + const char *guideText; /**< Entry guide text */ + const char *buttonDone; /**< "Done" button text */ + const char *buttonCancel; /**< "Cancel" button text */ + const char *limitToastText; /**< Text of toast shown on reach of entry text limit */ + }; + + EditfieldPopup(); + + /** + * @brief Set translatable strings for popup. + * @remark Should be called before create(). + * @param[in] strings Translatable strings table + */ + void setStrings(Strings strings); + + /** + * @brief Set result callback. + * @param[in] callback Result callback + */ + void setResultCallback(ResultCallback callback); + + /** + * @return Contained editfield. + */ + Ui::Editfield *getEditfield() const; + + protected: + /** + * @brief Creates editfield and popup buttons. + * @see Control::onCreated() + */ + virtual void onCreated() override; + + private: + bool onDoneButtonPressed(); + void onDoneKeyPressed(Evas_Object *entry, void *eventInfo); + static void onEntryChanged(Evas_Object *button, Evas_Object *entry, void *eventInfo); + + Ui::Editfield *m_Editfield; + ResultCallback m_OnResult; + Strings m_Strings; + }; +} + +#endif /* UX_EDITFIELD_POPUP_H */ diff --git a/lib-apps-common/inc/Ux/SelectAllItem.h b/lib-apps-common/inc/Ux/SelectAllItem.h new file mode 100644 index 0000000..91ca06f --- /dev/null +++ b/lib-apps-common/inc/Ux/SelectAllItem.h @@ -0,0 +1,62 @@ +/* + * Copyright 2016 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.1 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://floralicense.org/license/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef UX_SELECT_ALL_ITEM_H +#define UX_SELECT_ALL_ITEM_H + +#include "Ui/CheckItem.h" + +namespace Ux +{ + /** + * @brief "Select all" genlist item + */ + class EXPORT_API SelectAllItem : public Ui::CheckItem + { + public: + /** + * @brief Create "Select all" item. + * @param[in] text Item text + */ + SelectAllItem(const char *text); + + protected: + /** + * @see GenItem::getItemClass() + */ + virtual Elm_Gen_Item_Class *getItemClass() const override; + + /** + * @see GenItem::getText() + */ + virtual char *getText(Evas_Object *parent, const char *part) override; + + /** + * @see GenItem::getContent() + */ + virtual Evas_Object *getContent(Evas_Object *parent, const char *part) override; + + /** + * @see GenItem::onInserted() + */ + virtual void onInserted() override; + + private: + std::string m_Text; + }; +} + +#endif /* UX_SELECT_ALL_ITEM_H */ diff --git a/lib-apps-common/inc/Ux/SelectItem.h b/lib-apps-common/inc/Ux/SelectItem.h new file mode 100644 index 0000000..cb7766f --- /dev/null +++ b/lib-apps-common/inc/Ux/SelectItem.h @@ -0,0 +1,119 @@ +/* + * Copyright 2016 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.1 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://floralicense.org/license/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef UX_SELECT_ITEM_H +#define UX_SELECT_ITEM_H + +#include "Ui/CheckItem.h" +#include "Ux/SelectTypes.h" + +namespace Ux +{ + class SelectView; + + /** + * @brief GenContainer item for SelectView that supports selection mode switching. + */ + class EXPORT_API SelectItem : public Ui::CheckItem + { + public: + SelectItem(Ui::GenContainer::Type type = Ui::GenContainer::TypeGenlist); + + /** + * @return Whether item is excluded from multiple selection. + */ + bool isExcluded() const; + + /** + * @brief Set item exclusion. + * @param[in] isExcluded Whether item is excluded from multiple selection + */ + void setExcluded(bool isExcluded); + + /** + * @return Item selection mode. + */ + SelectMode getSelectMode() const; + + /** + * @brief Set item selection mode. + */ + void setSelectMode(SelectMode selectMode); + + /** + * @return Selection result associated with the item. + */ + SelectResult getSelectResult() const; + + /** + * @return Whether item has custom selection result. + */ + bool hasCustomResult() const; + + /** + * @brief Set custom selection result to override the default result. + */ + void setCustomResult(SelectResult result); + + /** + * @brief Unset custom selection result to use default result. + */ + void unsetCustomResult(); + + protected: + /** + * @return Default selection result associated with the item. + */ + virtual SelectResult getDefaultResult() const = 0; + + /** + * @see GenItem::getContent() + */ + virtual Evas_Object *getContent(Evas_Object *parent, const char *part) override; + + /** + * @GenItem::onVisibilityChanged() + */ + virtual void onVisibilityChanged(bool isVisible) override; + + /** + * @see GenItem::onSelected() + */ + virtual void onSelected() override; + + /** + * @see CheckItem::onChecked() + */ + virtual bool onChecked(bool isChecked) override; + + /** + * @brief Called when selection mode was changed. + * @param[in] selectMode New selection mode + */ + virtual void onSelectModeChanged(SelectMode selectMode) { } + + private: + friend class SelectView; + + SelectView *m_SelectView; + SelectMode m_SelectMode; + SelectResult m_CustomResult; + bool m_HasCustomResult; + bool m_IsExcluded; + }; +} + +#endif /* UX_SELECT_ITEM_H */ diff --git a/lib-apps-common/inc/Ux/SelectTypes.h b/lib-apps-common/inc/Ux/SelectTypes.h new file mode 100644 index 0000000..be7b4cd --- /dev/null +++ b/lib-apps-common/inc/Ux/SelectTypes.h @@ -0,0 +1,69 @@ +/* + * Copyright 2016 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.1 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://floralicense.org/license/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef UX_SELECT_TYPES_H +#define UX_SELECT_TYPES_H + +#include +#include + +namespace Ux +{ + /** + * @brief Determines how items can be selected. + */ + enum SelectMode + { + SelectNone, /**< Selection is disabled */ + SelectSingle, /**< Only one item can be selected */ + SelectMulti /**< Multiple items can be selected */ + }; + + /** + * @brief Selection result. + */ + struct SelectResult + { + unsigned type; /**< Result type (depends on result source) */ + union Value + { + Value(void *data) : data(data) { } + Value(int id) : id(id) { } + void *data; /**< Result data */ + int id; /**< Result data ID */ + } value; /**< Result value (depends on type) */ + }; + + /** + * @brief Range of consecutive selection results. + */ + typedef std::vector SelectResults; + + /** + * @brief Callback to be called when selection is done. + * @param[in] Selection results + * @return Whether the component that provided the selection should be destroyed. + */ + typedef std::function SelectCallback; + + /** + * @brief Callback to be called when cancel is pressed. + * @return Whether the component that provided the selection should be destroyed. + */ + typedef std::function CancelCallback; +} + +#endif /* UX_SELECT_TYPES_H */ diff --git a/lib-apps-common/inc/Ux/SelectView.h b/lib-apps-common/inc/Ux/SelectView.h new file mode 100644 index 0000000..ebd700a --- /dev/null +++ b/lib-apps-common/inc/Ux/SelectView.h @@ -0,0 +1,270 @@ +/* + * Copyright 2016 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.1 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://floralicense.org/license/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef UX_SELECT_VIEW_H +#define UX_SELECT_VIEW_H + +#include "Ui/View.h" +#include "Ux/SelectAllItem.h" +#include "Ux/SelectTypes.h" + +#include + +namespace Ui +{ + class GenItem; +} + +namespace Ux +{ + class SelectItem; + + /** + * @brief Base class for a view that support single and multiple selection modes. + */ + class EXPORT_API SelectView : public Ui::View + { + public: + /** + * @brief Translatable strings table for view elements. + */ + struct Strings + { + const char *selectAll; /**< "Select all" item text. */ + const char *buttonDone; /**< "Done" button text. */ + const char *buttonCancel; /**< "Cancel" button text. */ + const char *titleDefault; /**< Title for #SelectNone mode. */ + const char *titleSingle; /**< Title for #SelectSingle mode */ + const char *titleMulti; /**< Title for #SelectMulti mode */ + const char *titleWithCount; /**< Title for #SelectMulti mode with selection count. + Can contain one integer format specifier. */ + const char *titleWithLimit; /**< Title for #SelectMulti mode with limit. + Can contain two integer format specifiers. */ + const char *popupLimit; /**< Selection limit reached popup text. + Can contain one integer format specifiers. */ + }; + + /** + * @brief Called when item's "checked" state changed in #SelectMulti mode. + * @param[in] item Changed item + * @param[in] isChecked Whether item is checked + * @param[in] isMultiChecked Whether item is being checked via "Select All" + * @return Whether item's state should be changed. + */ + typedef std::function CheckCallback; + + /** + * @brief Called when selection limit is reached. + * @return Whether limit popup should be shown. + */ + typedef std::function LimitCallback; + + /** + * @brief Array of selectable items. + */ + typedef std::vector SelectItems; + + SelectView(); + virtual ~SelectView() override; + + /** + * @return View selection mode. + */ + SelectMode getSelectMode() const; + + /** + * @return Current selection limit. + */ + size_t getSelectLimit() const; + + /** + * @return Current selected items count. + */ + size_t getSelectCount() const; + + /** + * @return Selectable items managed by the view. + */ + const SelectItems &getSelectItems() const; + + /** + * @brief Set translatable strings for the view. + * @remark Should be called before create(). + * @param[in] strings Translatable strings table + */ + void setStrings(const Strings &strings); + + /** + * @brief Set selection mode. + * @param[in] selectMode Selection mode + */ + void setSelectMode(SelectMode selectMode); + + /** + * @brief Set item selection limit. + * @param[in] selectLimit Maximum selectable items count + */ + void setSelectLimit(size_t selectLimit); + + /** + * @brief Enable active Done button despite number of selections. + * @param[in] isAllowed True - Done button should be enabled, otherwise false + */ + void setEmptyResultAllowed(bool isAllowed); + + /** + * @brief Set selection callback. + * @param[in] callback Selection callback + */ + void setSelectCallback(SelectCallback callback); + + /** + * @brief Set cancel callback. + * @param[in] callback Cancel callback + */ + void setCancelCallback(CancelCallback callback); + + /** + * @brief Set item check callback. + * @param[in] callback Check callback + */ + void setCheckCallback(CheckCallback callback); + + /** + * @brief Set limit callback. + * @param[in] callback Limit callback + */ + void setLimitCallback(LimitCallback callback); + + protected: + /** + * @brief Add selectable item to be managed by the view. + * @param[in] item Item to add + */ + void addSelectItem(SelectItem *item); + + /** + * @brief Remove selectable item. + * @param[in] item Item to remove + */ + void removeSelectItem(SelectItem *item); + + /** + * @brief Creates "Done" and "Cancel" buttons in #SelectMulti mode. + * @see View::onPageAttached() + */ + virtual void onPageAttached(Ui::NavigatorPage *page) override; + + /** + * @brief Calls cancel callback if it exists. + * @see View::onBackPressed() + */ + virtual bool onBackPressed() override; + + /** + * @brief Called when title was changed. + * @param[in] title Title + */ + virtual void onTitleChanged(const char *title); + + /** + * @brief Called when "Select All" item should be inserted. + * @param[in] item "Select All" genlist item + */ + virtual void onSelectAllInsert(Ui::GenItem *item) { } + + /** + * @brief Called when selection mode was changed. + * @param[in] selectMode New selection mode + */ + virtual void onSelectModeChanged(SelectMode selectMode) { } + + /** + * @brief Called when selection limit was changed. + * @param[in] selectLimit New selection limit + */ + virtual void onSelectLimitChanged(size_t selectLimit) { } + + /** + * @brief Called when selection count was changed. + * @param[in] selectCount New selection count + */ + virtual void onSelectCountChanged(size_t selectCount) { } + + private: + friend class SelectItem; + + enum CountChange + { + CountIncrement, + CountDecrement + }; + + size_t getSelectMax() const; + bool isLimitReached() const; + bool isMaxSelected() const; + + void updatePageTitle(); + void updatePageButtons(); + void updateSelectAllItem(); + + void updateDoneButtonState(); + void updateSelectAllState(); + + void updateTotalCount(CountChange change, SelectItem *item); + void updateTotalSelectCount(CountChange change, SelectItem *item); + + void updateVisibleCount(CountChange change, SelectItem *item); + void updateVisibleSelectCount(CountChange change, SelectItem *item); + + void createPageButtons(Ui::NavigatorPage *page); + void destroyPageButtons(); + + void onItemExcluded(SelectItem *item, bool isExcluded); + void onItemVisibilityChanged(SelectItem *item, bool isVisible); + void onItemSelected(SelectItem *item); + bool onItemChecked(SelectItem *item, bool isChecked); + bool onSelectAllChecked(bool isChecked); + + void onDonePressed(Evas_Object *button, void *eventInfo); + void onCancelPressed(Evas_Object *button, void *eventInfo); + void onLimitReached(); + + Ui::GenItemPtr m_SelectAllItem; + SelectItems m_Items; + + Evas_Object *m_DoneButton; + Evas_Object *m_CancelButton; + + bool m_IsMultiChecking; + size_t m_TotalCount; + size_t m_TotalSelectCount; + size_t m_VisibleCount; + size_t m_VisibleSelectCount; + size_t m_SelectLimit; + bool m_IsEmptyResultAllowed; + + SelectMode m_SelectMode; + SelectCallback m_OnSelected; + CheckCallback m_OnChecked; + CancelCallback m_OnCanceled; + LimitCallback m_OnLimitReached; + + Strings m_Strings; + }; +} + +#endif /* UX_SELECT_VIEW_H */ diff --git a/lib-apps-common/project_def.prop b/lib-apps-common/project_def.prop new file mode 100644 index 0000000..b670601 --- /dev/null +++ b/lib-apps-common/project_def.prop @@ -0,0 +1,62 @@ + +# Project Name +APPNAME = apps-common + +# Project Type +type = sharedLib + +# Project Profile +profile = mobile-3.0 + +# C/CPP Sources +USER_SRCS = src/*/*.cpp + +# EDC Sources +USER_EDCS = + +# PO Sources +USER_POS = + +# User Defines +USER_DEFS = +USER_CPP_DEFS = + +# 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 res/apps-common/edje +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 = edje +USER_EDCS_SOUND_DIRS = edje +USER_EDCS_FONT_DIRS = edje + +# EDC Flags +USER_EXT_EDC_KEYS = EDC0 + +USER_EXT_EDC0_EDCS = res/*/edje/*.edc +USER_EXT_EDC0_EDCS_IMAGE_DIRS = edje +USER_EXT_EDC0_EDCS_SOUND_DIRS = edje +USER_EXT_EDC0_EDCS_FONT_DIRS = edje + +# Resource Filter +USER_RES_INCLUDE = +USER_RES_EXCLUDE = diff --git a/lib-apps-common/res/apps-common/CMakeLists.txt b/lib-apps-common/res/apps-common/CMakeLists.txt new file mode 100644 index 0000000..18685fa --- /dev/null +++ b/lib-apps-common/res/apps-common/CMakeLists.txt @@ -0,0 +1,15 @@ +set(EDCFILES apps-common-buttons.edc apps-common-popup.edc apps-common-thumbnail.edc apps-common-widget.edc) +set(EDJDIR "${RES_DIR}/apps-common/edje") + +foreach(EDCFILE ${EDCFILES}) + get_filename_component(EDJFILE ${EDCFILE} NAME_WE) + set(EDJFILE ${EDJFILE}.edj) + + add_custom_target(${EDJFILE} + COMMAND edje_cc -id ${PROJECT_SOURCE_DIR}/edje edje/${EDCFILE} ${EDJFILE} + DEPENDS edje/${EDCFILE} + ) + + add_dependencies(${PROJECT_NAME} ${EDJFILE}) + install(FILES ${EDJFILE} DESTINATION ${EDJDIR}) +endforeach(${EDCFILE}) diff --git a/lib-apps-common/res/apps-common/edje/AppsCommonButtons.h b/lib-apps-common/res/apps-common/edje/AppsCommonButtons.h new file mode 100644 index 0000000..4b87c9c --- /dev/null +++ b/lib-apps-common/res/apps-common/edje/AppsCommonButtons.h @@ -0,0 +1,36 @@ +/* + * Copyright 2016 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.1 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://floralicense.org/license/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef APPS_COMMON_BUTTONS_H +#define APPS_COMMON_BUTTONS_H + +#include "AppsCommonPath.h" + +#define APPS_COMMON_BUTTONS_EDJ APPS_COMMON_EDJ_DIR"apps-common-buttons.edj" + +#define STYLE_BUTTON_CUSTOM_DEFAULT "custom_default" +#define STYLE_BUTTON_CUSTOM_SMALL "custom_small" +#define STYLE_BUTTON_CUSTOM_CIRCLE "custom_circle" +#define STYLE_BUTTON_CUSTOM_CIRCLE_NO_BG "custom_circle/no_bg" + +#define BUTTON_TEXT_CLASS "button_text" +#define BUTTON_COLOR_CLASS_NORMAL "button_normal" +#define BUTTON_COLOR_CLASS_PRESSED "button_pressed" +#define BUTTON_COLOR_CLASS_UNPRESSED "button_unpressed" +#define BUTTON_COLOR_CLASS_ICON_NORMAL "button_icon_normal" +#define BUTTON_COLOR_CLASS_ICON_PRESSED "button_icon_pressed" + +#endif /* APPS_COMMON_BUTTONS_H */ diff --git a/lib-apps-common/res/apps-common/edje/AppsCommonPath.h b/lib-apps-common/res/apps-common/edje/AppsCommonPath.h new file mode 100644 index 0000000..ce7cb9b --- /dev/null +++ b/lib-apps-common/res/apps-common/edje/AppsCommonPath.h @@ -0,0 +1,23 @@ +/* + * Copyright 2016 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.1 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://floralicense.org/license/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef APPS_COMMON_PATH_H +#define APPS_COMMON_PATH_H + +#define APPS_COMMON_IMG_DIR "apps-common/images/" +#define APPS_COMMON_EDJ_DIR "apps-common/edje/" + +#endif /* APPS_COMMON_PATH_H */ diff --git a/lib-apps-common/res/apps-common/edje/AppsCommonPopup.h b/lib-apps-common/res/apps-common/edje/AppsCommonPopup.h new file mode 100644 index 0000000..d362fb1 --- /dev/null +++ b/lib-apps-common/res/apps-common/edje/AppsCommonPopup.h @@ -0,0 +1,28 @@ +/* + * Copyright 2016 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.1 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://floralicense.org/license/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef APPS_COMMON_POPUP_H +#define APPS_COMMON_POPUP_H + +#include "AppsCommonPath.h" + +#define APPS_COMMON_POPUP_EDJ APPS_COMMON_EDJ_DIR"apps-common-popup.edj" + +#define LAYOUT_PROGRESS "progress" +#define LAYOUT_PROCESS_SMALL "process_small" +#define LAYOUT_PROCESS_MEDIUM "process_medium" + +#endif /* APPS_COMMON_POPUP_H */ diff --git a/lib-apps-common/res/apps-common/edje/AppsCommonThumbnail.h b/lib-apps-common/res/apps-common/edje/AppsCommonThumbnail.h new file mode 100644 index 0000000..7842b82 --- /dev/null +++ b/lib-apps-common/res/apps-common/edje/AppsCommonThumbnail.h @@ -0,0 +1,48 @@ +/* + * Copyright 2016 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.1 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://floralicense.org/license/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef APPS_COMMON_THUMBNAIL_H +#define APPS_COMMON_THUMBNAIL_H + +#include "AppsCommonPath.h" + +#define APPS_COMMON_THUMBNAIL_EDJ APPS_COMMON_EDJ_DIR"apps-common-thumbnail.edj" + +#define THUMBNAIL_DEFAULT_SMALL APPS_COMMON_IMG_DIR"contacts_caller_id_default_02.png" +#define THUMBNAIL_DEFAULT_MEDIUM APPS_COMMON_IMG_DIR"contacts_caller_id_default_05.png" +#define THUMBNAIL_DEFAULT_LARGE APPS_COMMON_IMG_DIR"contacts_caller_id_default_04.png" + +#define THUMBNAIL_BG_SMALL APPS_COMMON_IMG_DIR"contacts_caller_id_default_bg_02.png" +#define THUMBNAIL_BG_MEDIUM APPS_COMMON_IMG_DIR"contacts_caller_id_default_bg_05.png" +#define THUMBNAIL_BG_LARGE APPS_COMMON_IMG_DIR"contacts_caller_id_default_bg_04.png" + +#define THUMBNAIL_MASK_SMALL APPS_COMMON_IMG_DIR"contacts_caller_id_default_masking_02.png" +#define THUMBNAIL_MASK_MEDIUM APPS_COMMON_IMG_DIR"contacts_caller_id_default_masking_05.png" +#define THUMBNAIL_MASK_LARGE APPS_COMMON_IMG_DIR"contacts_caller_id_default_masking_04.png" + +#define LAYOUT_THUMBNAIL_SMALL "thumbnail_small" +#define LAYOUT_THUMBNAIL_MEDIUM "thumbnail_medium" +#define LAYOUT_THUMBNAIL_LARGE "thumbnail_large" + +#define LAYOUT_THUMBNAIL_DEFAULT_SMALL "default_thumbnail_small" +#define LAYOUT_THUMBNAIL_DEFAULT_MEDIUM "default_thumbnail_medium" +#define LAYOUT_THUMBNAIL_DEFAULT_LARGE "default_thumbnail_large" + +#define THUMBNAIL_SMALL_SIZE 98 +#define THUMBNAIL_MEDIUM_SIZE 180 +#define THUMBNAIL_LARGE_SIZE 270 + +#endif /* APPS_COMMON_THUMBNAIL_H */ diff --git a/lib-apps-common/res/apps-common/edje/AppsCommonWidget.h b/lib-apps-common/res/apps-common/edje/AppsCommonWidget.h new file mode 100644 index 0000000..7aa82f4 --- /dev/null +++ b/lib-apps-common/res/apps-common/edje/AppsCommonWidget.h @@ -0,0 +1,33 @@ +/* + * Copyright 2016 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.1 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://floralicense.org/license/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef APPS_COMMON_WIDGET_H +#define APPS_COMMON_WIDGET_H + +#include "AppsCommonPath.h" + +#define APPS_COMMON_WIDGET_EDJ APPS_COMMON_EDJ_DIR"apps-common-widget.edj" + +#define NO_CONTENTS_BG APPS_COMMON_IMG_DIR"widget_no_contents_bg.#.png" +#define NO_CONTENTS_BORDER APPS_COMMON_IMG_DIR"widget_no_contents_bg_stroke.#.png" + +#define LAYOUT_NO_CONTENTS "no_contents" +#define LAYOUT_CONTENT "content" + +#define PART_BUTTON "swallow.button" +#define PART_CONTENT "swallow.content" + +#endif /* APPS_COMMON_WIDGET_H */ diff --git a/lib-apps-common/res/apps-common/edje/apps-common-buttons.edc b/lib-apps-common/res/apps-common/edje/apps-common-buttons.edc new file mode 100644 index 0000000..8665770 --- /dev/null +++ b/lib-apps-common/res/apps-common/edje/apps-common-buttons.edc @@ -0,0 +1,328 @@ +/* + * Copyright 2016 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.1 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://floralicense.org/license/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "AppsCommonButtons.h" +#include "apps-common-utils.edc" + +#define BUTTON_CORNER_RADIUS "39" +#define BUTTON_DEFAULT_H 78 +#define BUTTON_DEFAULT_TEXT_LR 32 + +#define BUTTON_SMALL_CORNER_RADIUS "25" +#define BUTTOM_SMALL_H 50 +#define BUTTON_SMALL_TEXT_LR 24 + +#define BUTTON_CIRCLE_WH 98 +#define BUTTON_CIRCLE_CONTENT_WH 60 +#define BUTTON_CIRCLE_NO_BG_WH 80 + +styles { + style { + name: "button_main"; + base: "font=Tizen:style=Light font_size=40 align=center color=#fafafa text_class="BUTTON_TEXT_CLASS; + } +} + +color_classes { + color_class { + name: BUTTON_COLOR_CLASS_NORMAL; + color: 82 198 216 255; + } + color_class { + name: BUTTON_COLOR_CLASS_PRESSED; + color: 0 0 0 77; + } + color_class { + name: BUTTON_COLOR_CLASS_UNPRESSED; + color: 0 0 0 0; + } + color_class { + name: BUTTON_COLOR_CLASS_ICON_NORMAL; + color: 250 250 250 255; + } + color_class { + name: BUTTON_COLOR_CLASS_ICON_PRESSED; + color: 250 250 250 255; + } +} + +collections { + base_scale: 2.6; + + plugins { + plugin { + name: "touch_sound"; + source: "feedback"; + param: "FEEDBACK_TYPE_SOUND FEEDBACK_PATTERN_TAP"; + } + } + + group { "elm/button/base/custom"; + script { + FUNCTION_SCALE_PART + public effect_scale; + } + parts { + swallow { "tizen_vg_shape"; scale; + clip_to: "rect.bg"; + } + rect { "rect.bg"; scale; + desc { "default"; + rel1.to: "tizen_vg_shape"; + rel2.to: "tizen_vg_shape"; + color_class: BUTTON_COLOR_CLASS_NORMAL; + } + } + swallow { "tizen_vg_shape2"; scale; + clip_to: "rect.effect_bg"; + } + rect { "rect.effect_bg"; scale; + desc { "default"; + rel1.to: "tizen_vg_shape2"; + rel2.to: "tizen_vg_shape2"; + color_class: BUTTON_COLOR_CLASS_UNPRESSED; + } + desc { "pressed"; + rel1.to: "tizen_vg_shape2"; + rel2.to: "tizen_vg_shape2"; + color_class: BUTTON_COLOR_CLASS_PRESSED; + } + } + } + programs { + program { + name: "loaded"; + signal: "load"; + source: "*"; + script { + set_float(effect_scale, 0.7); + } + } + program { + name: "pressed"; + signal: "mouse,down,*"; + source: "*"; + script { + scale_part(PART:"tizen_vg_shape2", "default", get_float(effect_scale)); + set_state(PART:"rect.effect_bg", "pressed", 0.0); + } + after: "pressed_effect"; + } + program { + name: "unpressed"; + signal: "mouse,up,*"; + source: "*"; + script { + new r, g, b, a; + get_color_class(BUTTON_COLOR_CLASS_PRESSED, r, g, b, a); + set_color_class(BUTTON_COLOR_CLASS_UNPRESSED, r, g, b, 0); + } + after: "unpressed_effect"; + } + program { + name: "pressed_effect"; + action: STATE_SET "default" 0.0; + target: "tizen_vg_shape2"; + transition: TRANSITION_GLIDE(0.15); + } + program { + name: "unpressed_effect"; + action: STATE_SET "default" 0.0; + target: "rect.effect_bg"; + transition: TRANSITION_GLIDE(0.45); + } + program { + name: "touch_sound"; + signal: "mouse,clicked,*"; + source: "*"; + action: RUN_PLUGIN "touch_sound"; + } + program { + name: "clicked"; + signal: "mouse,clicked,*"; + source: "*"; + action: SIGNAL_EMIT "elm,action,click" ""; + } + } + } + + group { "elm/button/base/"STYLE_BUTTON_CUSTOM_DEFAULT; + inherit: "elm/button/base/custom"; + data.item: "vector_ux" "default"; + data.item: "corner_radius" BUTTON_CORNER_RADIUS; + + parts { + spacer { "spacer.base"; scale; + desc { "default"; + min: 0 BUTTON_DEFAULT_H; + } + } + spacer { "spacer.left"; scale; + desc { "default"; + fixed: 1 0; + min: BUTTON_DEFAULT_TEXT_LR 0; + align: 0.0 0.5; + rel1.relative: 0.0 0.0; + rel2.relative: 0.0 1.0; + } + } + spacer { "spacer.right"; scale; + desc { "default"; + fixed: 1 0; + min: BUTTON_DEFAULT_TEXT_LR 0; + align: 1.0 0.5; + rel1.relative: 1.0 0.0; + rel2.relative: 1.0 1.0; + } + } + textblock { "elm.text"; scale; + desc { "default"; + align: 0.0 0.5; + rel1 { relative: 1.0 0.0; to_x: "spacer.left"; } + rel2 { relative: 0.0 1.0; to_x: "spacer.right"; } + text { + align: 0.5 0.5; + min: 1 0; + ellipsis: -1; + style: "button_main"; + } + } + } + } + } + + group { "elm/button/base/"STYLE_BUTTON_CUSTOM_SMALL; + inherit: "elm/button/base/"STYLE_BUTTON_CUSTOM_DEFAULT; + data.item: "vector_ux" "default"; + data.item: "corner_radius" BUTTON_SMALL_CORNER_RADIUS; + + parts { + spacer { "spacer.base"; scale; + desc { "default"; + min: 0 BUTTOM_SMALL_H; + } + } + spacer { "spacer.left"; scale; + desc { "default"; + min: BUTTON_SMALL_TEXT_LR 0; + } + } + spacer { "spacer.right"; scale; + desc { "default"; + min: BUTTON_SMALL_TEXT_LR 0; + } + } + } + programs { + program { + name: "loaded"; + signal: "load"; + source: "*"; + script { + set_float(effect_scale, 0.7); + set_color_class(BUTTON_COLOR_CLASS_NORMAL, 0, 0, 0, 90); + set_text_class(BUTTON_TEXT_CLASS, "font=Tizen:style=Regular", 32); + } + } + } + } + + group { "elm/button/base/"STYLE_BUTTON_CUSTOM_CIRCLE; + inherit: "elm/button/base/custom"; + data.item: "vector_ux" "circle"; + + parts { + spacer { "spacer.base"; scale; + desc { "default"; + min: BUTTON_CIRCLE_WH BUTTON_CIRCLE_WH; + } + } + swallow { "elm.swallow.content"; scale; nomouse; + clip_to: "rect.icon_bg"; + desc { "default"; + fixed: 1 1; + min: BUTTON_CIRCLE_CONTENT_WH BUTTON_CIRCLE_CONTENT_WH; + rel1.relative: 0.5 0.5; + rel2.relative: 0.5 0.5; + } + } + rect { "rect.icon_bg"; scale; + desc { "default"; + color_class: BUTTON_COLOR_CLASS_ICON_NORMAL; + } + desc { "pressed"; + color_class: BUTTON_COLOR_CLASS_ICON_PRESSED; + } + } + } + programs { + program { + name: "icon_pressed"; + signal: "mouse,down,*"; + source: "*"; + action: STATE_SET "pressed" 0.0; + target: "rect.icon_bg"; + } + program { + name: "icon_unpressed"; + signal: "mouse,up,*"; + source: "*"; + action: STATE_SET "default" 0.0; + target: "rect.icon_bg"; + transition: TRANSITION_GLIDE(0.45); + } + } + } + + group { "elm/button/base/"STYLE_BUTTON_CUSTOM_CIRCLE_NO_BG; + inherit: "elm/button/base/"STYLE_BUTTON_CUSTOM_CIRCLE; + data.item: "vector_ux" "circle"; + + parts { + spacer { "spacer.base"; scale; + desc { "default"; + min: BUTTON_CIRCLE_NO_BG_WH BUTTON_CIRCLE_NO_BG_WH; + } + } + swallow { "tizen_vg_shape2"; scale; + desc { "default"; + rel1.relative: -0.15 -0.15; + rel2.relative: 1.15 1.15; + } + } + swallow { "elm.swallow.content"; scale; + desc { "default"; + rel1.relative: 0.0 0.0; + rel2.relative: 1.0 1.0; + } + } + } + programs { + program { + name: "loaded"; + signal: "load"; + source: "*"; + script { + set_float(effect_scale, 1.0); + set_color_class(BUTTON_COLOR_CLASS_NORMAL, 0, 0, 0, 0); + set_color_class(BUTTON_COLOR_CLASS_PRESSED, 61, 185, 204, 77); + set_color_class(BUTTON_COLOR_CLASS_ICON_NORMAL, 61, 185, 204, 255); + set_color_class(BUTTON_COLOR_CLASS_ICON_PRESSED, 34, 104, 115, 255); + } + } + } + } +} diff --git a/lib-apps-common/res/apps-common/edje/apps-common-popup.edc b/lib-apps-common/res/apps-common/edje/apps-common-popup.edc new file mode 100644 index 0000000..cc17f8c --- /dev/null +++ b/lib-apps-common/res/apps-common/edje/apps-common-popup.edc @@ -0,0 +1,156 @@ +/* + * Copyright 2016 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.1 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://floralicense.org/license/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "AppsCommonPopup.h" + +#define PROGRESS_LR 32 +#define PROGRESS_TB 17 + +#define PROCESS_SMALL_POPUP_H 78 +#define PROCESS_SMALL_PROGRESS_LR 32 +#define PROCESS_SMALL_PROGRESS_WH 44 +#define PROCESS_SMALL_TEXT_SIZE 40 + +#define PROCESS_MEDIUM_POPUP_H 120 +#define PROCESS_MEDIUM_PROGRESS_LR 32 +#define PROCESS_MEDIUM_PROGRESS_W 56 +#define PROCESS_MEDIUM_TEXT_SIZE 40 + +styles { + style { + name: "process_small"; + base: "font=Tizen:style=Light font_size="PROCESS_SMALL_TEXT_SIZE" align=right color=#3db9ccff"; + } + style { + name: "process_medium"; + base: "font=Tizen:style=Light font_size="PROCESS_MEDIUM_TEXT_SIZE" align=left color=#000000ff"; + } +} + +collections { + base_scale: 2.6; + + group { LAYOUT_PROGRESS; + parts { + spacer { "spacer.left_top"; scale; + desc { "default"; + min: PROGRESS_LR PROGRESS_TB; + align: 0.0 0.0; + rel1.relative: 0.0 0.0; + rel2.relative: 0.0 0.0; + } + } + spacer { "spacer.right_bottom"; scale; + desc { "default"; + min: PROGRESS_LR PROGRESS_TB; + align: 1.0 1.0; + rel1.relative: 1.0 1.0; + rel2.relative: 1.0 1.0; + } + } + swallow { "elm.swallow.content"; scale; + desc { "default"; + rel1 { relative: 1.0 1.0; to: "spacer.left_top"; } + rel2 { relative: 0.0 0.0; to: "spacer.right_bottom"; } + } + } + } + } + + group { LAYOUT_PROCESS_SMALL; + parts { + spacer { "spacer.base"; scale; + desc { "default"; + min: 0 PROCESS_SMALL_POPUP_H; + } + } + spacer { "spacer.progress_right"; scale; + desc { "default"; + min: PROCESS_SMALL_PROGRESS_LR 0; + align: 1.0 0.5; + rel1.relative: 1.0 0.0; + rel2.relative: 1.0 1.0; + } + } + swallow { "elm.swallow.content"; scale; + desc { "default"; + min: PROCESS_SMALL_PROGRESS_WH PROCESS_SMALL_PROGRESS_WH; + align: 1.0 0.5; + rel1 { relative: 0.0 0.5; to_x: "spacer.progress_right"; } + rel2 { relative: 0.0 0.5; to_x: "spacer.progress_right"; } + } + } + spacer { "spacer.text_right"; scale; + desc { "default"; + min: PROCESS_SMALL_PROGRESS_LR 0; + align: 1.0 0.5; + rel1 { relative: 0.0 0.0; to_x: "elm.swallow.content"; } + rel2 { relative: 0.0 1.0; to_x: "elm.swallow.content"; } + } + } + textblock { "elm.text"; scale; + desc { "default"; + align: 0.0 0.5; + rel1 { relative: 0.0 0.0; } + rel2 { relative: 0.0 1.0; to_x: "spacer.text_right"; } + text.style: "process_small"; + } + } + } + } + + group { LAYOUT_PROCESS_MEDIUM; + parts { + spacer { "spacer.base"; scale; + desc { "default"; + min: 0 PROCESS_MEDIUM_POPUP_H; + } + } + spacer { "spacer.progress_left"; scale; + desc { "default"; + min: PROCESS_MEDIUM_PROGRESS_LR 0; + align: 0.0 0.5; + rel1.relative: 0.0 0.0; + rel2.relative: 0.0 1.0; + } + } + swallow { "elm.swallow.content"; scale; + desc { "default"; + min: PROCESS_MEDIUM_PROGRESS_W 0; + align: 0.0 0.5; + rel1 { relative: 1.0 0.5; to_x: "spacer.progress_left"; } + rel2 { relative: 1.0 0.5; to_x: "spacer.progress_left"; } + } + } + spacer { "spacer.text_left"; scale; + desc { "default"; + min: PROCESS_MEDIUM_PROGRESS_LR 0; + align: 0.0 0.5; + rel1 { relative: 1.0 0.0; to_x: "elm.swallow.content"; } + rel2 { relative: 1.0 1.0; to_x: "elm.swallow.content"; } + } + } + textblock { "elm.text"; scale; + desc { "default"; + align: 0.0 0.5; + rel1 { relative: 1.0 0.0; to_x: "spacer.text_left"; } + rel2 { relative: 1.0 1.0; } + text.style: "process_medium"; + } + } + } + } +} diff --git a/lib-apps-common/res/apps-common/edje/apps-common-thumbnail.edc b/lib-apps-common/res/apps-common/edje/apps-common-thumbnail.edc new file mode 100644 index 0000000..a5822e5 --- /dev/null +++ b/lib-apps-common/res/apps-common/edje/apps-common-thumbnail.edc @@ -0,0 +1,39 @@ +/* + * Copyright 2016 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.1 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://floralicense.org/license/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "AppsCommonThumbnail.h" +#include "apps-common-utils.edc" + +color_classes { + color_class { //A03O003 + name: "thumbnail_bg"; + color: 255 255 255 255; + } + color_class { //A03O003L1 + name: "thumbnail_default"; + color: 61 185 204 128; + } +} + +collections { + IMAGE_WITH_MASK(LAYOUT_THUMBNAIL_SMALL, THUMBNAIL_MASK_SMALL) + IMAGE_WITH_MASK(LAYOUT_THUMBNAIL_MEDIUM, THUMBNAIL_MASK_MEDIUM) + IMAGE_WITH_MASK(LAYOUT_THUMBNAIL_LARGE, THUMBNAIL_MASK_LARGE) + + IMAGE_WITH_COLOR_AND_BG(LAYOUT_THUMBNAIL_DEFAULT_SMALL, THUMBNAIL_DEFAULT_SMALL, "thumbnail_default", THUMBNAIL_BG_SMALL, "thumbnail_bg") + IMAGE_WITH_COLOR_AND_BG(LAYOUT_THUMBNAIL_DEFAULT_MEDIUM, THUMBNAIL_DEFAULT_MEDIUM, "thumbnail_default", THUMBNAIL_BG_MEDIUM, "thumbnail_bg") + IMAGE_WITH_COLOR_AND_BG(LAYOUT_THUMBNAIL_DEFAULT_LARGE, THUMBNAIL_DEFAULT_LARGE, "thumbnail_default", THUMBNAIL_BG_LARGE, "thumbnail_bg") +} diff --git a/lib-apps-common/res/apps-common/edje/apps-common-utils.edc b/lib-apps-common/res/apps-common/edje/apps-common-utils.edc new file mode 100644 index 0000000..490cd42 --- /dev/null +++ b/lib-apps-common/res/apps-common/edje/apps-common-utils.edc @@ -0,0 +1,165 @@ +/* + * Copyright 2016 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.1 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://floralicense.org/license/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#define TRANSITION_GLIDE(duration) CUBIC_BEZIER (duration) 0.25 0.46 0.45 1.0 +#define FUNCTION_SCALE_PART \ + public scale_part(part_id, state[], Float:ratio) { \ + new x, y, w, h; \ + get_geometry(part_id, x, y, w, h); \ + new Float:offset = (w < h ? w : h) * (1.0 - ratio) / 2; \ + new Float:rel_w = offset / w; \ + new Float:rel_h = offset / h; \ +\ + custom_state(part_id, state, 0.0); \ + set_state_val(part_id, STATE_REL1, rel_w, rel_h); \ + set_state_val(part_id, STATE_REL2, 1.0 - rel_w, 1.0 - rel_h); \ + set_state(part_id, "custom", 0.0); \ + } + +#define IMAGE_WITH_COLOR(GROUP_NAME, IMAGE_PATH, COLOR_CLASS) \ + group { GROUP_NAME; \ + images.image: IMAGE_PATH COMP; \ + parts { \ + image { "image"; \ + desc { "default"; \ + image.normal: IMAGE_PATH; \ + color_class: COLOR_CLASS; \ + aspect: 1 1; \ + aspect_preference: SOURCE; \ + } \ + } \ + } \ + } + +#define IMAGE_WITH_COLOR_AND_BG(GROUP_NAME, IMAGE_PATH, COLOR_CLASS, BG_IMAGE_PATH, BG_COLOR_CLASS) \ + group { GROUP_NAME; \ + images { \ + image: BG_IMAGE_PATH COMP; \ + image: IMAGE_PATH COMP; \ + } \ + parts { \ + image { "image.bg"; \ + desc { "default"; \ + image.normal: BG_IMAGE_PATH; \ + color_class: BG_COLOR_CLASS; \ + aspect: 1 1; \ + aspect_preference: SOURCE; \ + } \ + } \ + } \ + parts { \ + image { "image"; \ + desc { "default"; \ + image.normal: IMAGE_PATH; \ + color_class: COLOR_CLASS; \ + aspect: 1 1; \ + aspect_preference: SOURCE; \ + } \ + } \ + } \ + } + +#define IMAGE_WITH_MASK(GROUP_NAME, MASK_PATH) \ + group { GROUP_NAME; \ + images.image: MASK_PATH COMP; \ + parts { \ + image { "image.mask"; \ + precise_is_inside: 1; \ + desc { "default"; \ + image.normal: MASK_PATH; \ + aspect: 1.0 1.0; \ + aspect_preference: SOURCE; \ + } \ + } \ + } \ + parts { \ + swallow { "elm.swallow.content"; \ + clip_to: "image.mask"; \ + } \ + } \ + } + +#define IMAGE_WITH_COLOR_AND_TOUCH(GROUP_NAME, IMAGE_PATH, COLOR_CLASS, PRESSED_COLOR_CLASS) \ + group { GROUP_NAME; \ + images.image: IMAGE_PATH COMP; \ + parts { \ + image { "image"; \ + desc { "default"; \ + image.normal: IMAGE_PATH; \ + color_class: COLOR_CLASS; \ + aspect: 1 1; \ + aspect_preference: SOURCE; \ + } \ + desc { "pressed"; \ + inherit: "default" 0.0; \ + color_class: PRESSED_COLOR_CLASS; \ + } \ + } \ + } \ + programs { \ + program { \ + name: "pressed"; \ + signal: "mouse,down,*"; \ + source: "*"; \ + action: STATE_SET "pressed" 0.0; \ + target: "image"; \ + } \ + program { \ + name: "unpressed"; \ + signal: "mouse,up,*"; \ + source: "*"; \ + action: STATE_SET "default" 0.0; \ + target: "image"; \ + } \ + } \ + } + +#define IMAGE_WITH_TOUCH(GROUP_NAME, IMAGE_PATH, PRESSED_IMAGE_PATH) \ + group { GROUP_NAME; \ + images { \ + image: IMAGE_PATH COMP; \ + image: PRESSED_IMAGE_PATH COMP; \ + } \ + parts { \ + image { "image"; \ + desc { "default"; \ + image.normal: IMAGE_PATH; \ + aspect: 1 1; \ + aspect_preference: SOURCE; \ + } \ + desc { "pressed"; \ + inherit: "default" 0.0; \ + image.normal: PRESSED_IMAGE_PATH; \ + } \ + } \ + } \ + programs { \ + program { \ + name: "pressed"; \ + signal: "mouse,down,*"; \ + source: "*"; \ + action: STATE_SET "pressed" 0.0; \ + target: "image"; \ + } \ + program { \ + name: "unpressed"; \ + signal: "mouse,up,*"; \ + source: "*"; \ + action: STATE_SET "default" 0.0; \ + target: "image"; \ + } \ + } \ + } diff --git a/lib-apps-common/res/apps-common/edje/apps-common-widget.edc b/lib-apps-common/res/apps-common/edje/apps-common-widget.edc new file mode 100644 index 0000000..6a53969 --- /dev/null +++ b/lib-apps-common/res/apps-common/edje/apps-common-widget.edc @@ -0,0 +1,168 @@ +/* + * Copyright 2016 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.1 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://floralicense.org/license/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "AppsCommonWidget.h" +#include "apps-common-utils.edc" + +#define TEXT_H 107 +#define TEXT_T 72 +#define TEXT_SIZE 80 + +#define HELP_H 52 +#define HELP_T 15 +#define HELP_TEXT_SIZE 38 + +#define BUTTON_R 14 +#define CONTENT_T 10 + +styles { + style { + name: "no_contents_text"; + base: "font=Tizen:style=Condensed font_size="TEXT_SIZE" align=center color=#fafafa style=shadow,bottom_right shadow_color=#00000066"; + } + style { + name: "no_contents_help"; + base: "font=Tizen:style=Regular font_size="HELP_TEXT_SIZE" align=center color=#fafafa style=shadow,bottom_right shadow_color=#00000066"; + } +} + +color_classes { + color_class { //AO003 + name: "no_contents_bg"; + color: 0 0 0 13; + } + color_class { + name: "no_contents_bg_pressed"; + color: 0 0 0 77; + } + color_class { //AO003L1 + name: "no_contents_border"; + color: 250 250 250 77; + } +} + +collections { + base_scale: 2.6; + + group { LAYOUT_NO_CONTENTS; + images { + image: NO_CONTENTS_BG COMP; + image: NO_CONTENTS_BORDER COMP; + } + parts { + image { "image.bg"; + desc { "default"; + image.normal: NO_CONTENTS_BG; + color_class: "no_contents_bg"; + } + desc { "pressed"; + image.normal: NO_CONTENTS_BG; + color_class: "no_contents_bg_pressed"; + } + } + image { "image.border"; + desc { "default"; + color_class: "no_contents_border"; + image.normal: NO_CONTENTS_BORDER; + } + } + spacer { "spacer.text.top"; scale; + desc { "default"; + min: 0 TEXT_T; + align: 0.5 0.0; + rel2.relative: 1.0 0.0; + } + } + textblock { "elm.text"; scale; + desc { "default"; + min: 0 TEXT_H; + align: 0.5 0.0; + rel1 { relative: 0.0 1.0; to_y: "spacer.text.top"; } + rel2 { relative: 1.0 1.0; to_y: "spacer.text.top"; } + text.style: "no_contents_text"; + } + } + spacer { "spacer.help.top"; scale; + desc { "default"; + min: 0 HELP_T; + align: 0.5 0.0; + rel1 { relative: 0.0 1.0; to_y: "elm.text"; } + rel2 { relative: 1.0 1.0; to_y: "elm.text"; } + } + } + textblock { "elm.help.text"; scale; + desc { "default"; + min: 0 HELP_H; + align: 0.5 0.0; + rel1 { relative: 0.0 1.0; to_y: "spacer.help.top"; } + rel2 { relative: 1.0 1.0; to_y: "spacer.help.top"; } + text.style: "no_contents_help"; + } + } + programs { + program { + name: "pressed"; + signal: "mouse,down,*"; + source: "*"; + action: STATE_SET "pressed" 0.0; + target: "image.bg"; + transition: TRANSITION_GLIDE(0.15); + } + program { + name: "unpressed"; + signal: "mouse,up,*"; + source: "*"; + action: STATE_SET "default" 0.0; + target: "image.bg"; + transition: TRANSITION_GLIDE(0.45); + } + } + } + } + + group { LAYOUT_CONTENT; + parts { + spacer { "spacer.button.right"; scale; + desc { "default"; + min: BUTTON_R 0; + align: 1.0 0.5; + rel1.relative: 1.0 0.0; + } + } + swallow { PART_BUTTON; + desc { "default"; + align: 1.0 0.0; + rel1 { relative: 0.0 0.0; to_x: "spacer.button.right"; } + rel2 { relative: 0.0 0.0; to_x: "spacer.button.right"; } + } + } + spacer { "spacer.content.top"; scale; + desc { "default"; + min: 0 CONTENT_T; + align: 0.5 0.0; + rel1 { relative: 0.0 1.0; to_y: PART_BUTTON; } + rel2 { relative: 1.0 1.0; to_y: PART_BUTTON; } + } + } + swallow { PART_CONTENT; + desc { "default"; + align: 0.5 0.0; + rel1 { relative: 0.0 1.0; to_y: "spacer.content.top"; } + } + } + } + } +} diff --git a/lib-apps-common/src/App/AppControl.cpp b/lib-apps-common/src/App/AppControl.cpp new file mode 100644 index 0000000..f864915 --- /dev/null +++ b/lib-apps-common/src/App/AppControl.cpp @@ -0,0 +1,112 @@ +/* + * Copyright 2016 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.1 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://floralicense.org/license/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "App/AppControl.h" +#include "Utils/Logger.h" + +using namespace App; + +AppControl::AppControl() + : m_AppControl(nullptr), m_AutoTerminate(true) +{ +} + +AppControl::AppControl(const char *appId) + : AppControl() +{ + app_control_create(&m_AppControl); + app_control_set_app_id(m_AppControl, appId); +} + +AppControl::AppControl(const char *operation, const char *mime, const char *uri) + : AppControl() +{ + app_control_create(&m_AppControl); + app_control_set_operation(m_AppControl, operation); + app_control_set_mime(m_AppControl, mime); + app_control_set_uri(m_AppControl, uri); +} + +AppControl::AppControl(AppControl &&that) + : m_AppControl(that.m_AppControl), m_AutoTerminate(that.m_AutoTerminate) +{ + that.m_AppControl = nullptr; +} + +AppControl::~AppControl() +{ + reset(); +} + +app_control_h AppControl::getHandle() const +{ + return m_AppControl; +} + +void AppControl::addExtra(const char *key, const char *value) +{ + app_control_add_extra_data(m_AppControl, key, value); +} + +void AppControl::addExtra(const char *key, const char **array, int length) +{ + app_control_add_extra_data_array(m_AppControl, key, array, length); +} + +int AppControl::launch(app_control_reply_cb replyCallback, void *userData, + bool groupMode) +{ + if (groupMode) { + app_control_set_launch_mode(m_AppControl, APP_CONTROL_LAUNCH_MODE_GROUP); + } + + int result = app_control_send_launch_request(m_AppControl, replyCallback, userData); + WARN_IF_ERR(result, "app_control_send_launch_request() failed."); + + return result; +} + +void AppControl::terminate() +{ + m_AutoTerminate = true; + reset(); +} + +void AppControl::detach() +{ + m_AutoTerminate = false; +} + +AppControl &AppControl::operator=(AppControl &&that) +{ + reset(); + m_AppControl = that.m_AppControl; + m_AutoTerminate = that.m_AutoTerminate; + that.m_AppControl = nullptr; + + return *this; +} + +void AppControl::reset() +{ + if (m_AppControl) { + if (m_AutoTerminate) { + app_control_send_terminate_request(m_AppControl); + } + app_control_destroy(m_AppControl); + m_AppControl = nullptr; + } +} diff --git a/lib-apps-common/src/App/AppControlRequest.cpp b/lib-apps-common/src/App/AppControlRequest.cpp new file mode 100644 index 0000000..307ba5c --- /dev/null +++ b/lib-apps-common/src/App/AppControlRequest.cpp @@ -0,0 +1,147 @@ +/* + * Copyright 2016 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.1 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://floralicense.org/license/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "App/AppControlRequest.h" + +using namespace App; + +AppControl App::requestContactCreate(const char *number) +{ + AppControl request(APP_CONTROL_OPERATION_ADD, APP_CONTROL_MIME_CONTACT); + request.addExtra(APP_CONTROL_DATA_PHONE, number); + return request; +} + +AppControl App::requestContactDetails(int personId) +{ + AppControl request(APP_CONTROL_OPERATION_VIEW, APP_CONTROL_MIME_CONTACT); + request.addExtra(APP_CONTROL_DATA_ID, std::to_string(personId).c_str()); + return request; +} + +AppControl App::requestContactEdit(int personId, const char *number) +{ + AppControl request(APP_CONTROL_OPERATION_EDIT, APP_CONTROL_MIME_CONTACT); + if (personId > 0) { + request.addExtra(APP_CONTROL_DATA_ID, std::to_string(personId).c_str()); + } + + request.addExtra(APP_CONTROL_DATA_PHONE, number); + return request; +} + +AppControl App::requestContactPick(const char *selectionMode, const char *resultType) +{ + AppControl request(APP_CONTROL_OPERATION_PICK, APP_CONTROL_MIME_CONTACT); + request.addExtra(APP_CONTROL_DATA_SELECTION_MODE, selectionMode); + request.addExtra(APP_CONTROL_DATA_TYPE, resultType); + return request; +} + +AppControl App::requestTelephonyCall(const char *number) +{ + return AppControl(APP_CONTROL_OPERATION_CALL, nullptr, + std::string("tel:").append(number).c_str()); +} + +AppControl App::requestCallSettings() +{ + return AppControl(APP_CONTROL_OPERATION_SETTING_CALL, nullptr); +} + +AppControl App::requestComposer(const char *scheme, const char *to, + const char *subject, const char *text) +{ + std::string uri = scheme; + if (to) { + uri.append(to); + } + AppControl request(APP_CONTROL_OPERATION_COMPOSE, nullptr, uri.c_str()); + request.addExtra(APP_CONTROL_DATA_TITLE, subject); + request.addExtra(APP_CONTROL_DATA_TEXT, text); + return request; +} + +AppControl App::requestComposer(const char *scheme, Utils::Range recipients, + const char *subject, const char *text) +{ + AppControl request = requestComposer(scheme, nullptr, subject, text); + request.addExtra(APP_CONTROL_DATA_TO, recipients.begin(), recipients.count()); + return request; +} + +AppControl App::requestCameraImage() +{ + return AppControl(APP_CONTROL_OPERATION_CREATE_CONTENT, APP_CONTROL_MIME_IMAGE); +} + +AppControl App::requestGalleryImage() +{ + AppControl request(APP_CONTROL_OPERATION_PICK, APP_CONTROL_MIME_IMAGE); + app_control_set_app_id(request.getHandle(), "org.tizen.ug-gallery-efl"); + return request; +} + +AppControl App::requestViewImage(const char *path) +{ + return AppControl(APP_CONTROL_OPERATION_VIEW, APP_CONTROL_MIME_IMAGE, + std::string(APP_CONTROL_URI_SCHEME_FILE).append(path).c_str()); +} + +AppControl App::requestShareContact(int personId) +{ + AppControl request(APP_CONTROL_OPERATION_SHARE, APP_CONTROL_MIME_CONTACT); + request.addExtra(APP_CONTROL_DATA_ID, std::to_string(personId).c_str()); + return request; +} + +AppControl App::requestShareText(const char *text) +{ + AppControl request(APP_CONTROL_OPERATION_SHARE_TEXT, nullptr); + request.addExtra(APP_CONTROL_DATA_TEXT, text); + return request; +} + +AppControl App::requestShareMyProfile(int recordId) +{ + AppControl request = requestShareContact(recordId); + request.addExtra(APP_CONTROL_DATA_TYPE, "my_profile"); + return request; +} + +AppControl App::requestMultiShareContacts(const char **personIds, int count) +{ + AppControl request(APP_CONTROL_OPERATION_MULTI_SHARE, APP_CONTROL_MIME_CONTACT); + request.addExtra(APP_CONTROL_DATA_ID, personIds, count); + return request; +} + +AppControl App::requestPickVcard(const char *path) +{ + AppControl request(APP_CONTROL_OPERATION_PICK, APP_CONTROL_MIME_VCARD, + std::string(APP_CONTROL_URI_SCHEME_FILE).append(path).c_str()); + request.addExtra(APP_CONTROL_DATA_SELECTION_MODE, APP_CONTROL_SELECT_MULTIPLE); + return request; +} + +AppControl App::requestPickRingtone(const char *selectedPath) +{ + AppControl request("org.tizen.setting-ringtone"); + if (selectedPath) { + request.addExtra(APP_CONTROL_DATA_SELECTED, &selectedPath, 1); + } + return request; +} diff --git a/lib-apps-common/src/App/AppControlUtils.cpp b/lib-apps-common/src/App/AppControlUtils.cpp new file mode 100644 index 0000000..02f3037 --- /dev/null +++ b/lib-apps-common/src/App/AppControlUtils.cpp @@ -0,0 +1,107 @@ +/* + * Copyright 2016 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.1 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://floralicense.org/license/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "App/AppControlUtils.h" +#include "Utils/Logger.h" + +using namespace App; + +std::string App::getSingleExtraData(app_control_h appControl, const char *key) +{ + std::string result; + char **array = nullptr; + int count = 0; + + int err = app_control_get_extra_data_array(appControl, key, &array, &count); + RETVM_IF_ERR(err, result, "app_control_get_extra_data_array() failed."); + + if (array && array[0]) { + result = array[0]; + } + + for (int i = 0; i < count; ++i) { + free(array[i]); + } + free(array); + + return result; +} + +int App::getIntExtraData(app_control_h appControl, const char *key) +{ + int result = 0; + char *resultStr = nullptr; + + int err = app_control_get_extra_data(appControl, key, &resultStr); + RETVM_IF_ERR(err, result, "app_control_get_extra_data() failed."); + + if (resultStr) { + result = atoi(resultStr); + free(resultStr); + } + + return result; +} + +std::string App::getStringExtraData(app_control_h appControl, const char *key) +{ + std::string result; + char *resultStr = nullptr; + + int err = app_control_get_extra_data(appControl, key, &resultStr); + RETVM_IF_ERR(err, result, "app_control_get_extra_data() failed."); + + if (resultStr) { + result = resultStr; + free(resultStr); + } + + return result; +} + +std::vector App::getIntExtraDataArray(app_control_h appControl, const char *key) +{ + std::vector result; + char **array = nullptr; + int count = 0; + + int err = app_control_get_extra_data_array(appControl, key, &array, &count); + RETVM_IF_ERR(err, result, "app_control_get_extra_data_array() failed."); + result.reserve(count); + + for (int i = 0; i < count; ++i) { + int value = atoi(array[i]); + result.push_back(value); + free(array[i]); + } + free(array); + + return result; +} + +char **App::createExtraDataArray(size_t dataSize, size_t count) +{ + typedef char ExtraData[dataSize]; + + char **array = (char **) malloc((sizeof(char *) + dataSize) * count); + ExtraData *extraData = (ExtraData *) (array + count); + + for (size_t i = 0; i < count; ++i) { + array[i] = extraData[i]; + } + + return array; +} diff --git a/lib-apps-common/src/App/Application.cpp b/lib-apps-common/src/App/Application.cpp new file mode 100644 index 0000000..b9932e5 --- /dev/null +++ b/lib-apps-common/src/App/Application.cpp @@ -0,0 +1,129 @@ +/* + * Copyright 2016 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.1 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://floralicense.org/license/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "App/Application.h" +#include "App/OperationController.h" +#include "Ui/Naviframe.h" +#include "Ui/Scale.h" +#include "Ui/Window.h" +#include "Utils/Callback.h" + +#include +#include + +using namespace App; + +Application::Application() + : m_Window(nullptr), m_Navigator(nullptr), m_Controller(nullptr) +{ +} + +int Application::run(int argc, char **argv) +{ + ui_app_lifecycle_callback_s cbs; + cbs.create = makeCallback(&Application::onCreate); + cbs.terminate = makeCallback(&Application::onTerminate); + cbs.pause = makeCallback(&Application::onPause); + cbs.resume = makeCallback(&Application::onResume); + cbs.app_control = makeCallbackWithLastParam(&Application::onAppControl); + + return ui_app_main(argc, argv, &cbs, this); +} + +bool Application::onCreate() +{ + updateLanguage(); + + app_event_handler_h handle = nullptr; + ui_app_add_event_handler(&handle, APP_EVENT_LANGUAGE_CHANGED, + &Application::onLanguageChanged, this); + elm_app_base_scale_set(UI_BASE_SCALE); + + m_Window = new Ui::Window(); + m_Window->create(nullptr); + + m_Navigator = new Ui::Naviframe(); + m_Window->attachView(m_Navigator); + + return true; +} + +void Application::onTerminate() +{ + delete m_Controller; + m_Controller = nullptr; +} + +void Application::onPause() +{ + if (m_Controller) { + m_Controller->onPause(); + } +} + +void Application::onResume() +{ + if (m_Controller) { + m_Controller->onResume(); + } +} + +void Application::onAppControl(app_control_h request) +{ + char *operation = nullptr; + app_control_get_operation(request, &operation); + + if (!m_Controller) { + m_Controller = createController(operation); + if (m_Controller) { + m_Controller->create(m_Window, m_Navigator); + } + } + + if (m_Controller) { + m_Controller->request(operation, request); + } + + free(operation); +} + +Ui::Window *Application::getWindow() const +{ + return m_Window; +} + +Ui::Naviframe *Application::getNavigator() const +{ + return m_Navigator; +} + +void Application::onLanguageChanged(app_event_info_h event, void *data) +{ + updateLanguage(); +} + +void Application::updateLanguage() +{ + char *lang = nullptr; + system_settings_get_value_string(SYSTEM_SETTINGS_KEY_LOCALE_LANGUAGE, &lang); + + i18n_ulocale_layout_type_e layout = I18N_ULOCALE_LAYOUT_UNKNOWN; + i18n_ulocale_get_character_orientation(lang, &layout); + + elm_language_set(lang); + elm_config_mirrored_set(layout == I18N_ULOCALE_LAYOUT_RTL); + free(lang); +} diff --git a/lib-apps-common/src/App/OperationController.cpp b/lib-apps-common/src/App/OperationController.cpp new file mode 100644 index 0000000..41d39c4 --- /dev/null +++ b/lib-apps-common/src/App/OperationController.cpp @@ -0,0 +1,90 @@ +/* + * Copyright 2016 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.1 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://floralicense.org/license/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "App/OperationController.h" +#include "Ui/Navigator.h" +#include "Ui/Window.h" + +using namespace App; + +OperationController::OperationController(bool isMinimizable) + : m_Request(nullptr), m_IsMinimizable(isMinimizable), + m_Window(nullptr), m_Navigator(nullptr) +{ +} + +OperationController::~OperationController() +{ + app_control_destroy(m_Request); +} + +void OperationController::create(Ui::Window *window, Ui::Navigator *navigator) +{ + m_Window = window; + m_Navigator = navigator; + + if (!m_IsMinimizable) { + m_Navigator->setLastPageCallback([] { + ui_app_exit(); + return false; + }); + } + + onCreate(); +} + +void OperationController::request(const char *operation, app_control_h request) +{ + app_control_destroy(m_Request); + app_control_clone(&m_Request, request); + onRequest(operation, m_Request); +} + +Ui::Window *OperationController::getWindow() const +{ + return m_Window; +} + +Ui::Navigator *OperationController::getNavigator() const +{ + return m_Navigator; +} + +app_control_h OperationController::getRequest() const +{ + return m_Request; +} + +std::string OperationController::getUrn(const char *scheme) const +{ + char *uri = nullptr; + app_control_get_uri(m_Request, &uri); + if (!uri) { + return { }; + } + + const char *urn = nullptr; + if (scheme) { + size_t length = strlen(scheme); + if (strncmp(uri, scheme, length) == 0) { + urn = uri + length; + } + } + + std::string path = urn ? urn : uri; + free(uri); + return path; +} diff --git a/lib-apps-common/src/App/Path.cpp b/lib-apps-common/src/App/Path.cpp new file mode 100644 index 0000000..6004525 --- /dev/null +++ b/lib-apps-common/src/App/Path.cpp @@ -0,0 +1,78 @@ +/* + * Copyright 2016 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.1 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://floralicense.org/license/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "App/Path.h" + +#include + +const std::string &App::getLocaleDir() +{ + static std::string localeDir; + if (localeDir.empty()) { + #ifdef LOCALE_DIR + localeDir = LOCALE_DIR; + #else + localeDir = getResourcePath("locale/"); + #endif + } + + return localeDir; +} + +const std::string &App::getDataDir() +{ + static std::string dataDir; + if (dataDir.empty()) { + #ifdef DATA_DIR + dataDir = DATA_DIR; + #else + char *path = app_get_data_path(); + if (path) { + dataDir = path; + free(path); + } + #endif + } + + return dataDir; +} + +const std::string &App::getResourceDir() +{ + static std::string resDir; + if (resDir.empty()) { + #ifdef RES_DIR + resDir = RES_DIR; + #else + char *path = app_get_resource_path(); + if (path) { + resDir = path; + free(path); + } + #endif + } + + return resDir; +} + +std::string App::getResourcePath(const char *relativePath) +{ + std::string path = getResourceDir(); + if (relativePath) { + path.append(relativePath); + } + return path; +} diff --git a/lib-apps-common/src/App/Widget.cpp b/lib-apps-common/src/App/Widget.cpp new file mode 100644 index 0000000..5d1bf0d --- /dev/null +++ b/lib-apps-common/src/App/Widget.cpp @@ -0,0 +1,76 @@ +/* + * Copyright 2016 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.1 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://floralicense.org/license/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "App/Widget.h" +#include "App/WidgetWindow.h" + +using namespace App; + +Widget::Widget() + : m_Context(nullptr), m_Width(0), m_Height(0), m_Window(nullptr) +{ +} + +Widget::~Widget() +{ + delete m_Window; +} + +void Widget::create(widget_context_h context, bundle *content) +{ + m_Context = context; + m_Window = new WidgetWindow(m_Context); + m_Window->create(nullptr); + onCreate(content); +} + +void Widget::resize(int width, int height) +{ + m_Width = width; + m_Height = height; + + evas_object_resize(m_Window->getEvasObject(), m_Width, m_Height); + evas_object_resize(m_Window->getBaseLayout(), m_Width, m_Height); + + onResize(m_Width, m_Height); +} + +int Widget::getWidth() const +{ + return m_Width; +} + +int Widget::getHeight() const +{ + return m_Height; +} + +widget_size_type_e Widget::getType() const +{ + widget_size_type_e type = WIDGET_SIZE_TYPE_UNKNOWN; + widget_service_get_size_type(m_Width, m_Height, &type); + return type; +} + +Ui::Window *Widget::getWindow() const +{ + return m_Window; +} + +void Widget::saveContent(bundle *content) +{ + widget_app_context_set_content_info(m_Context, content); +} diff --git a/lib-apps-common/src/App/WidgetApplication.cpp b/lib-apps-common/src/App/WidgetApplication.cpp new file mode 100644 index 0000000..49cd12b --- /dev/null +++ b/lib-apps-common/src/App/WidgetApplication.cpp @@ -0,0 +1,138 @@ +/* + * Copyright 2016 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.1 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://floralicense.org/license/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "App/WidgetApplication.h" +#include "App/Widget.h" +#include "Ui/Scale.h" +#include "Utils/Callback.h" + +#include +#include +#include + +using namespace App; + +int WidgetApplication::run(int argc, char **argv) +{ + widget_app_lifecycle_callback_s cbs; + cbs.create = makeCallback(&WidgetApplication::onWidgetClassCreate); + cbs.terminate = makeCallback(&WidgetApplication::onTerminate); + + return widget_app_main(argc, argv, &cbs, this); +} + +bool WidgetApplication::onCreate() +{ + updateLanguage(); + + app_event_handler_h handle = nullptr; + widget_app_add_event_handler(&handle, APP_EVENT_LANGUAGE_CHANGED, + &WidgetApplication::onLanguageChanged, this); + + elm_app_base_scale_set(UI_BASE_SCALE); + return true; +} + +widget_class_h WidgetApplication::onWidgetClassCreate() +{ + widget_instance_lifecycle_callback_s cbs; + cbs.create = &WidgetApplication::onWidgetCreate; + cbs.destroy = &WidgetApplication::onWidgetDestroy; + cbs.pause = &WidgetApplication::onWidgetPause; + cbs.resume = &WidgetApplication::onWidgetResume; + cbs.resize = &WidgetApplication::onWidgetResize; + cbs.update = &WidgetApplication::onWidgetUpdate; + + if (!onCreate()) { + return nullptr; + } + return widget_app_class_create(cbs, this); +} + +Widget *App::WidgetApplication::getWidget(widget_context_h context) +{ + Widget *widget = nullptr; + widget_app_context_get_tag(context, (void **) &widget); + return widget; +} + +int WidgetApplication::onWidgetCreate(widget_context_h context, + bundle *content, int width, int height, void *data) +{ + WidgetApplication *app = (WidgetApplication *) data; + Widget *widget = app->createWidget(); + if (!widget) { + return WIDGET_ERROR_FAULT; + } + + widget_app_context_set_tag(context, widget); + widget->create(context, content); + widget->resize(width, height); + return WIDGET_ERROR_NONE; +} + +int WidgetApplication::onWidgetDestroy(widget_context_h context, + widget_app_destroy_type_e reason, bundle *content, void *data) +{ + Widget *widget = getWidget(context); + widget->onDestroy(reason); + delete widget; + return WIDGET_ERROR_NONE; +} + +int WidgetApplication::onWidgetPause(widget_context_h context, void *data) +{ + getWidget(context)->onPause(); + return WIDGET_ERROR_NONE; +} + +int WidgetApplication::onWidgetResume(widget_context_h context, void *data) +{ + getWidget(context)->onResume(); + return WIDGET_ERROR_NONE; +} + +int WidgetApplication::onWidgetResize(widget_context_h context, + int width, int height, void *data) +{ + getWidget(context)->resize(width, height); + return WIDGET_ERROR_NONE; +} + +int WidgetApplication::onWidgetUpdate(widget_context_h context, + bundle *content, int force, void *data) +{ + getWidget(context)->onUpdate(force); + return WIDGET_ERROR_NONE; +} + +void WidgetApplication::onLanguageChanged(app_event_info_h event, void *data) +{ + updateLanguage(); +} + +void WidgetApplication::updateLanguage() +{ + char *lang = nullptr; + system_settings_get_value_string(SYSTEM_SETTINGS_KEY_LOCALE_LANGUAGE, &lang); + + i18n_ulocale_layout_type_e layout = I18N_ULOCALE_LAYOUT_UNKNOWN; + i18n_ulocale_get_character_orientation(lang, &layout); + + elm_language_set(lang); + elm_config_mirrored_set(layout == I18N_ULOCALE_LAYOUT_RTL); + free(lang); +} diff --git a/lib-apps-common/src/App/WidgetWindow.cpp b/lib-apps-common/src/App/WidgetWindow.cpp new file mode 100644 index 0000000..57a223b --- /dev/null +++ b/lib-apps-common/src/App/WidgetWindow.cpp @@ -0,0 +1,33 @@ +/* + * Copyright 2016 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.1 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://floralicense.org/license/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "App/WidgetWindow.h" +#include + +using namespace App; + +WidgetWindow::WidgetWindow(widget_context_h context) + : m_Context(context) +{ +} + +Evas_Object *WidgetWindow::onWindowCreate() +{ + Evas_Object *window = nullptr; + widget_app_get_elm_win(m_Context, &window); + evas_object_show(window); + return window; +} diff --git a/lib-apps-common/src/I18n/Collator.cpp b/lib-apps-common/src/I18n/Collator.cpp new file mode 100644 index 0000000..e7d05ec --- /dev/null +++ b/lib-apps-common/src/I18n/Collator.cpp @@ -0,0 +1,69 @@ +/* + * Copyright 2016 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.1 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://floralicense.org/license/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "I18n/Collator.h" +#include + +using namespace I18n; + +Collator::Collator(i18n_ucollator_strength_e strength) + : m_Strength(strength), m_Handle(nullptr) +{ +} + +Collator::Collator(Collator &&that) + : m_Strength(that.m_Strength), m_Handle(that.m_Handle) +{ + that.m_Handle = nullptr; +} + +Collator::~Collator() +{ + i18n_ucollator_destroy(m_Handle); +} + +Collator &Collator::operator=(Collator &&that) +{ + i18n_ucollator_destroy(m_Handle); + m_Strength = that.m_Strength; + m_Handle = that.m_Handle; + that.m_Handle = nullptr; + return *this; +} + +void Collator::initialize() +{ + if (m_Handle) { + i18n_ucollator_destroy(m_Handle); + m_Handle = nullptr; + } + + char *lang = nullptr; + system_settings_get_value_string(SYSTEM_SETTINGS_KEY_LOCALE_LANGUAGE, &lang); + i18n_ucollator_create(lang, &m_Handle); + i18n_ucollator_set_strength(m_Handle, m_Strength); + free(lang); +} + +int Collator::compare(const UniString& str1, const UniString &str2) +{ + int result = 0; + i18n_ucollator_str_collator(m_Handle, + str1.getI18nStr().c_str(), -1, + str2.getI18nStr().c_str(), -1, + (i18n_ucollator_result_e *) &result); + return result; +} diff --git a/lib-apps-common/src/I18n/UniString.cpp b/lib-apps-common/src/I18n/UniString.cpp new file mode 100644 index 0000000..93f2aab --- /dev/null +++ b/lib-apps-common/src/I18n/UniString.cpp @@ -0,0 +1,103 @@ +/* + * Copyright 2016 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.1 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://floralicense.org/license/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "I18n/UniString.h" + +using namespace I18n; + +UniString::UniString(const char *utf8Str) +{ + if (utf8Str) { + m_Utf8Str = utf8Str; + } + m_UniStr = fromUtf8(m_Utf8Str); +} + +bool UniString::operator<(const UniString &that) const +{ + return i18n_ustring_compare_code_point_order(m_UniStr.c_str(), that.m_UniStr.c_str()) < 0; +} + +bool UniString::operator>(const UniString &that) const +{ + return i18n_ustring_compare_code_point_order(m_UniStr.c_str(), that.m_UniStr.c_str()) > 0; +} + +bool UniString::operator==(const UniString &that) const +{ + return i18n_ustring_compare_code_point_order(m_UniStr.c_str(), that.m_UniStr.c_str()) == 0; +} + +bool UniString::operator!=(const UniString &that) const +{ + return i18n_ustring_compare_code_point_order(m_UniStr.c_str(), that.m_UniStr.c_str()) != 0; +} + +bool UniString::operator<=(const UniString &that) const +{ + return i18n_ustring_compare_code_point_order(m_UniStr.c_str(), that.m_UniStr.c_str()) <= 0; +} + +bool UniString::operator>=(const UniString &that) const +{ + return i18n_ustring_compare_code_point_order(m_UniStr.c_str(), that.m_UniStr.c_str()) >= 0; +} + +const UniString::I18nString &UniString::getI18nStr() const +{ + return m_UniStr; +} + +const std::string &UniString::getUtf8Str() const +{ + if (m_Utf8Str.empty() && !m_UniStr.empty()) { + m_Utf8Str = toUtf8(m_UniStr); + } + + return m_Utf8Str; +} + +void UniString::clear() +{ + m_Utf8Str.clear(); + m_UniStr.clear(); +} + +std::string UniString::toUtf8(const I18nString &ustring) +{ + char fakeValue; + int length = 0; + i18n_error_code_e err = I18N_ERROR_NONE; + i18n_ustring_to_UTF8(&fakeValue, 1, &length, ustring.c_str(), -1, &err); + + std::string retVal(length + 1, 0); + i18n_ustring_to_UTF8(&retVal[0], length + 1, &length, ustring.c_str(), -1, &err); + + return retVal; +} + +UniString::I18nString UniString::fromUtf8(const std::string &utf8Str) +{ + i18n_uchar fakeValue; + int length = 0; + i18n_error_code_e err = I18N_ERROR_NONE; + i18n_ustring_from_UTF8(&fakeValue, 1, &length, utf8Str.c_str(), -1, &err); + + I18nString retVal(length + 1, 0); + i18n_ustring_from_UTF8(&retVal[0], length + 1, &length, utf8Str.c_str(), -1, &err); + + return retVal; +} diff --git a/lib-apps-common/src/Model/DataItem.cpp b/lib-apps-common/src/Model/DataItem.cpp new file mode 100644 index 0000000..f23b591 --- /dev/null +++ b/lib-apps-common/src/Model/DataItem.cpp @@ -0,0 +1,53 @@ +/* + * Copyright 2016 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.1 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://floralicense.org/license/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "Model/DataItem.h" + +using namespace Model; + +void DataItem::setUpdateCallback(UpdateCallback callback) +{ + m_OnUpdated = std::move(callback); +} + +void DataItem::unsetUpdateCallback() +{ + m_OnUpdated = nullptr; +} + +void DataItem::setDeleteCallback(DeleteCallback callback) +{ + m_OnDeleted = std::move(callback); +} + +void DataItem::unsetDeleteCallback() +{ + m_OnDeleted = nullptr; +} + +void DataItem::onUpdated(int changes) +{ + if (m_OnUpdated) { + m_OnUpdated(changes); + } +} + +void DataItem::onDeleted() +{ + if (m_OnDeleted) { + m_OnDeleted(); + } +} diff --git a/lib-apps-common/src/Model/DataProvider.cpp b/lib-apps-common/src/Model/DataProvider.cpp new file mode 100644 index 0000000..6d2cb67 --- /dev/null +++ b/lib-apps-common/src/Model/DataProvider.cpp @@ -0,0 +1,71 @@ +/* + * Copyright 2016 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.1 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://floralicense.org/license/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "Model/DataProvider.h" + +using namespace Model; + +void DataProvider::initialize(InitializeCallback callback) +{ + m_OnInitialized = std::move(callback); + onInitialize(); +} + +void DataProvider::setInsertCallback(InsertCallback callback) +{ + m_OnInserted = std::move(callback); +} + +void DataProvider::unsetInsertCallback() +{ + m_OnInserted = nullptr; +} + +void DataProvider::setUpdateFinishedCallback(UpdateFinishedCallback callback) +{ + m_OnUpdateFinished = std::move(callback); +} + +void DataProvider::unsetUpdateFinishedCallback() +{ + m_OnUpdateFinished = nullptr; +} + +void DataProvider::onInitialize() +{ + onInitialized(); +} + +void DataProvider::onInitialized() +{ + if (m_OnInitialized) { + m_OnInitialized(); + } +} + +void DataProvider::onInserted(DataItem &dataItem) +{ + if (m_OnInserted) { + m_OnInserted(dataItem); + } +} + +void DataProvider::onUpdateFinished() +{ + if (m_OnUpdateFinished) { + m_OnUpdateFinished(); + } +} diff --git a/lib-apps-common/src/Model2/DataItem.cpp b/lib-apps-common/src/Model2/DataItem.cpp new file mode 100644 index 0000000..4cca705 --- /dev/null +++ b/lib-apps-common/src/Model2/DataItem.cpp @@ -0,0 +1,95 @@ +/* + * Copyright 2016 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.1 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://floralicense.org/license/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "Model2/DataItem.h" + +using namespace Model2; + +DataItem::DataItem() + : m_IsStandalone(false), m_Changes(0), m_ChangeType(ChangeNone) +{ +} + +DataItem::DataItem(const DataItem &that) + : DataItem() +{ +} + +void DataItem::update(void *data) +{ + m_Changes |= onUpdate(data); + m_ChangeType = ChangeUpdate; + + if (m_IsStandalone) { + finishUpdate(); + } +} + +bool DataItem::isStandalone() const +{ + return m_IsStandalone; +} + +void DataItem::setStandalone(bool isStandalone) +{ + if (m_IsStandalone != isStandalone) { + m_IsStandalone = isStandalone; + onStandalone(m_IsStandalone); + } +} + +DataItem::UpdateCallback &DataItem::onUpdated() +{ + return m_OnUpdated; +} + +DataItem::DeleteCallback &DataItem::onDeleted() +{ + return m_OnDeleted; +} + +void DataItem::setChanged(ChangeType changeType, int changes) +{ + if (m_ChangeType == ChangeNone) { + m_ChangeType = changeType; + } + if (changeType == ChangeUpdate) { + m_Changes |= changes; + } + + if (m_IsStandalone) { + finishUpdate(); + } +} + +void DataItem::finishUpdate() +{ + switch (m_ChangeType) { + case ChangeUpdate: + if (m_Changes) { + m_OnUpdated(m_Changes); + } + break; + case ChangeDelete: + m_OnDeleted(); + break; + default: + break; + } + + m_Changes = 0; + m_ChangeType = ChangeNone; +} diff --git a/lib-apps-common/src/Model2/DataProvider.cpp b/lib-apps-common/src/Model2/DataProvider.cpp new file mode 100644 index 0000000..f138fc1 --- /dev/null +++ b/lib-apps-common/src/Model2/DataProvider.cpp @@ -0,0 +1,160 @@ +/* + * Copyright 2016 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.1 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://floralicense.org/license/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "Model2/DataProvider.h" + +using namespace Model2; + +DataProvider::DataProvider() + : m_IsBusy(false), m_IsInitialized(false), + m_IsUpdateEnabled(true), m_IsUpdatePending(false), + m_IsDestroyPending(false) +{ +} + +DataProvider::~DataProvider() +{ + for (auto &&dataItem : m_DataList) { + delete dataItem; + } +} + +const DataProvider::DataList &DataProvider::getDataList() +{ + return m_DataList; +} + +void DataProvider::initialize(InitializeCallback callback) +{ + if (m_IsInitialized || m_IsBusy) { + return; + } + + m_IsBusy = true; + m_OnInitialized = std::move(callback); + + startInit(); +} + +void DataProvider::update() +{ + if (!m_IsInitialized) { + return; + } + + if (!m_IsUpdateEnabled || m_IsBusy) { + m_IsUpdatePending = true; + return; + } + + m_IsBusy = true; + m_IsUpdatePending = false; + m_OnUpdateStarted(); + + startUpdate(); +} + +void DataProvider::destroy() +{ + if (m_IsBusy) { + m_IsDestroyPending = true; + } else { + delete this; + } +} + +void DataProvider::setUpdateEnabled(bool isEnabled) +{ + m_IsUpdateEnabled = isEnabled; + if (m_IsUpdateEnabled && m_IsUpdatePending) { + update(); + } +} + +DataProvider::InsertCallback &DataProvider::onInserted() +{ + return m_OnInserted; +} + +DataProvider::UpdateCallback &DataProvider::onUpdateStarted() +{ + return m_OnUpdateStarted; +} + +DataProvider::UpdateCallback &DataProvider::onUpdateFinished() +{ + return m_OnUpdateFinished; +} + +void DataProvider::insertDataItem(DataItem *dataItem) +{ + dataItem->m_ChangeType = ChangeInsert; + m_DataList.push_back(dataItem); +} + +void DataProvider::deleteDataItem(DataItem &dataItem) +{ + dataItem.m_ChangeType = ChangeDelete; +} + +void DataProvider::finishInit(DataList dataList) +{ + if (m_IsDestroyPending) { + delete this; + return; + } + + m_DataList = std::move(dataList); + m_IsInitialized = true; + + if (m_OnInitialized) { + m_OnInitialized(); + m_OnInitialized = nullptr; + } + + m_IsBusy = false; +} + +void DataProvider::finishUpdate() +{ + if (m_IsDestroyPending) { + delete this; + return; + } + + for (auto it = m_DataList.begin(); it != m_DataList.end(); ) { + auto changeType = (*it)->m_ChangeType; + (*it)->finishUpdate(); + + if (changeType == ChangeInsert) { + if (m_OnInserted) { + m_OnInserted(**it); + } + } else if (changeType == ChangeDelete) { + delete *it; + it = m_DataList.erase(it); + continue; + } + + ++it; + } + m_OnUpdateFinished(); + + m_IsBusy = false; + if (m_IsUpdatePending) { + update(); + } +} diff --git a/lib-apps-common/src/Model2/SearchData.cpp b/lib-apps-common/src/Model2/SearchData.cpp new file mode 100644 index 0000000..4db50a5 --- /dev/null +++ b/lib-apps-common/src/Model2/SearchData.cpp @@ -0,0 +1,59 @@ +/* + * Copyright 2016 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.1 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://floralicense.org/license/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "Model2/SearchData.h" + +using namespace Model2; + +SearchData::SearchData(DataItem &dataItem) + : m_DataItem(dataItem), + m_SearchResult(nullptr) +{ +} + +DataItem &SearchData::getDataItem() +{ + return m_DataItem; +} + +const DataItem &SearchData::getDataItem() const +{ + return m_DataItem; +} + +const SearchResult *SearchData::getSearchResult() const +{ + return m_SearchResult; +} + +void SearchData::setSearchResult(SearchResult *searchResult) +{ + m_SearchResult = searchResult; + + if (m_OnChanged) { + m_OnChanged(m_SearchResult); + } +} + +void SearchData::setChangeCallback(ChangeCallback callback) +{ + m_OnChanged = std::move(callback); +} + +int SearchData::onUpdate(void *data) +{ + return (long) data; +} diff --git a/lib-apps-common/src/Model2/SearchEngine.cpp b/lib-apps-common/src/Model2/SearchEngine.cpp new file mode 100644 index 0000000..95dc2b1 --- /dev/null +++ b/lib-apps-common/src/Model2/SearchEngine.cpp @@ -0,0 +1,226 @@ +/* + * Copyright 2016 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.1 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://floralicense.org/license/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "Model2/SearchEngine.h" +#include "Model2/SearchData.h" + +#include +#include + +using namespace Model2; +using namespace std::placeholders; + +SearchEngine::SearchEngine(const DataList &dataList, SearchComparator comparator) + : m_LastFoundIndex(-1), + m_DataList(dataList), + m_Comparator(std::move(comparator)) +{ +} + +void SearchEngine::search(std::string query) +{ + if (query.empty()) { + clear(); + if (!m_Query.empty()) { + resetSearchResult(); + } + } else { + if (!needSearch(query)) { + return; + } + + auto matchIt = getMatch(query); + size_t matchPos = matchIt - m_History.begin(); + bool nothingFound = matchIt == m_History.end(); + + m_History.erase(nothingFound ? m_History.begin() : (matchIt + 1), m_History.end()); + m_History.resize(query.size()); + + if (m_Query.empty() || nothingFound) { + incrementalSearch(m_DataList, query); + } else if (matchPos == m_History.size()) { + updateSearchResult(m_History.back()); + } else { + incrementalSearch(m_History[matchPos], query); + } + } + + m_Query = std::move(query); +} + +bool SearchEngine::empty() const +{ + return m_History.empty() || m_History.back().empty(); +} + +void SearchEngine::insertSearchData(SearchData *searchData) +{ + SearchResult *lastResult = nullptr; + + historyFor([searchData, &lastResult, this](const std::string &query, ResultList &list) { + SearchResultPtr searchResult = m_Comparator(*searchData, query); + lastResult = searchResult.get(); + + if (searchResult) { + list.emplace_back(searchData, std::move(searchResult)); + return true; + } + + return false; + }); + + searchData->setSearchResult(lastResult); +} + +void SearchEngine::updateSearchData(SearchData *searchData) +{ + SearchResult *lastResult = nullptr; + + historyFor([searchData, &lastResult, this](const std::string &query, ResultList &list) { + auto it = findSearchData(list, searchData); + if (it != list.end()) { + SearchResultPtr searchResult = m_Comparator(*searchData, query); + lastResult = searchResult.get(); + + if (searchResult) { + it->second = std::move(searchResult); + } else { + list.erase(it); + } + } + + return true; + }); + + searchData->setSearchResult(lastResult); +} + +void SearchEngine::deleteSearchData(SearchData *searchData) +{ + for (auto &&list : m_History) { + auto it = findSearchData(list, searchData); + if (it != list.end()) { + list.erase(it); + } + } +} + +bool SearchEngine::needSearch(const std::string &query) +{ + if (query.size() >= m_Query.size() + &&(int)(m_History.size() - 1) > m_LastFoundIndex) { + return false; + } + + return true; +} + +template +void SearchEngine::incrementalSearch(const List &list, const std::string &query) +{ + ResultList resultList; + for (auto &&data : list) { + SearchData *searchData = getSearchData(data); + SearchResultPtr searchResult = m_Comparator(*searchData, query); + searchData->setSearchResult(searchResult.get()); + + if (searchResult) { + resultList.emplace_back(searchData, std::move(searchResult)); + } + } + + if (!resultList.empty()) { + m_LastFoundIndex = m_History.size() - 1; + m_History.back() = std::move(resultList); + } +} + +SearchData *SearchEngine::getSearchData(DataItem *data) +{ + return static_cast(data); +} + +SearchData *SearchEngine::getSearchData(const SearchResultItem &resultItem) +{ + return resultItem.first; +} + +void SearchEngine::updateSearchResult(ResultList &list) +{ + for (auto &&resultItem : list) { + resultItem.first->setSearchResult(resultItem.second.get()); + } +} + +void SearchEngine::resetSearchResult() +{ + for (auto &&data : m_DataList) { + SearchData *searchData = static_cast(data); + searchData->setSearchResult(nullptr); + } +} + +void SearchEngine::clear() +{ + m_History.clear(); + m_LastFoundIndex = -1; +} + +SearchEngine::SearchHistory::iterator SearchEngine::getMatch(const std::string &query) +{ + size_t minSize = std::min(m_Query.size(), query.size()); + auto itPair = std::mismatch(m_Query.begin(), m_Query.begin() + minSize, query.begin()); + + return skipEmptyResults(itPair.first - m_Query.begin()); +} + +SearchEngine::SearchHistory::iterator SearchEngine::skipEmptyResults(size_t offset) +{ + auto rIt = std::reverse_iterator(m_History.begin() + offset); + + while (rIt != m_History.rend() && rIt->empty()) { + ++rIt; + } + + return rIt == m_History.rend() ? m_History.end() : rIt.base() - 1; +} + +void SearchEngine::historyFor(HistoryForFn function) +{ + std::string query; + query.reserve(m_Query.size()); + + for (size_t i = 0; i < m_History.size(); ++i) { + auto &list = m_History[i]; + query.append(1, m_Query[i]); + + if ((int) i < m_LastFoundIndex && list.empty()) { + continue; + } + + if (!function(query, list)) { + break; + } + } +} + +SearchEngine::ResultList::iterator SearchEngine::findSearchData(ResultList &list, SearchData *searchData) +{ + return std::find_if(list.begin(), list.end(), + [searchData](const SearchResultItem &item) { + return item.first == searchData; + }); +} diff --git a/lib-apps-common/src/Model2/SearchProvider.cpp b/lib-apps-common/src/Model2/SearchProvider.cpp new file mode 100644 index 0000000..5208c04 --- /dev/null +++ b/lib-apps-common/src/Model2/SearchProvider.cpp @@ -0,0 +1,85 @@ +/* + * Copyright 2016 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.1 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://floralicense.org/license/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "Model2/SearchProvider.h" +#include "Model2/SearchData.h" + +using namespace Model2; +using namespace std::placeholders; + +SearchProvider::SearchProvider(DataProvider &provider, SearchComparator comparator) + : m_Provider(provider), m_SearchEngine(getDataList(), std::move(comparator)) +{ + m_Provider.onInserted() += { std::bind(&SearchProvider::onItemInserted, this, _1), this }; + m_Provider.onUpdateStarted() += { std::bind(&SearchProvider::update, this), this }; + m_Provider.onUpdateFinished() += { std::bind(&SearchProvider::finishUpdate, this), this }; +} + +SearchProvider::~SearchProvider() +{ + m_Provider.onInserted() -= this; + m_Provider.onUpdateStarted() -= this; + m_Provider.onUpdateFinished() -= this; +} + +void SearchProvider::search(const char *query) +{ + m_SearchEngine.search(query ? query : ""); +} + +bool SearchProvider::empty() const +{ + return m_SearchEngine.empty(); +} + +void SearchProvider::startInit() +{ + m_Provider.initialize([this] { + DataList dataList; + for (auto &&dataItem : m_Provider.getDataList()) { + dataList.push_back(createSearchData(*dataItem)); + } + + finishInit(std::move(dataList)); + }); +} + +SearchData *SearchProvider::createSearchData(DataItem &dataItem) +{ + auto searchData = new SearchData(dataItem); + dataItem.onUpdated() += { std::bind(&SearchProvider::onItemUpdated, this, std::ref(*searchData), _1), searchData }; + dataItem.onDeleted() += { std::bind(&SearchProvider::onItemDeleted, this, std::ref(*searchData)), searchData }; + return searchData; +} + +void SearchProvider::onItemInserted(DataItem &dataItem) +{ + SearchData *searchData = createSearchData(dataItem); + insertDataItem(searchData); + m_SearchEngine.insertSearchData(searchData); +} + +void SearchProvider::onItemUpdated(SearchData &searchData, int changes) +{ + searchData.update((void *)(long) changes); + m_SearchEngine.updateSearchData(&searchData); +} + +void SearchProvider::onItemDeleted(SearchData &searchData) +{ + m_SearchEngine.deleteSearchData(&searchData); + deleteDataItem(searchData); +} diff --git a/lib-apps-common/src/Model2/SearchResult.cpp b/lib-apps-common/src/Model2/SearchResult.cpp new file mode 100644 index 0000000..e040815 --- /dev/null +++ b/lib-apps-common/src/Model2/SearchResult.cpp @@ -0,0 +1,47 @@ +/* + * Copyright 2016 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.1 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://floralicense.org/license/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "Model2/SearchResult.h" + +using namespace Model2; + +SearchResult::SearchResult() + : m_MatchedField(-1), + m_MatchedString(nullptr) +{ +} + +SearchResult::SearchResult(int fieldId, const char *str, Substring substr) + : m_MatchedField(fieldId), + m_MatchedString(str), + m_MatchedSubstring(substr) +{ +} + +int SearchResult::getMatchedField() const +{ + return m_MatchedField; +} + +const char *SearchResult::getMatchedString() const +{ + return m_MatchedString; +} + +const SearchResult::Substring &SearchResult::getMatchedSubstring() const +{ + return m_MatchedSubstring; +} diff --git a/lib-apps-common/src/System/Settings.cpp b/lib-apps-common/src/System/Settings.cpp new file mode 100644 index 0000000..7ecdd8f --- /dev/null +++ b/lib-apps-common/src/System/Settings.cpp @@ -0,0 +1,76 @@ +/* + * Copyright 2016 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.1 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://floralicense.org/license/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "System/Settings.h" +#include "Utils/Callback.h" + +#include +#include + +using namespace System::Settings; + +namespace +{ + class KeyManager : public CallbackManager + { + public: + explicit KeyManager(system_settings_key_e key) + : m_Key(key) + { + system_settings_set_changed_cb(m_Key, + makeCallbackWithLastParam(&KeyManager::operator()), this); + } + + ~KeyManager() + { + system_settings_unset_changed_cb(m_Key); + } + + bool operator==(system_settings_key_e key) const + { + return m_Key == key; + } + + private: + system_settings_key_e m_Key; + }; + + std::list keyManagers; +} + +void System::Settings::addCallback(system_settings_key_e key, KeyManager::Callback callback) +{ + auto manager = std::find(keyManagers.begin(), keyManagers.end(), key); + if (manager == keyManagers.end()) { + keyManagers.emplace_back(key); + manager = --keyManagers.end(); + } + + (*manager) += (callback); +} + +void System::Settings::removeCallback(system_settings_key_e key, void *subscriber) +{ + auto manager = std::find(keyManagers.begin(), keyManagers.end(), key); + if (manager == keyManagers.end()) { + return; + } + + (*manager) -= subscriber; + if (!*manager) { + keyManagers.erase(manager); + } +} diff --git a/lib-apps-common/src/Ui/Button.cpp b/lib-apps-common/src/Ui/Button.cpp new file mode 100644 index 0000000..8e92054 --- /dev/null +++ b/lib-apps-common/src/Ui/Button.cpp @@ -0,0 +1,105 @@ +/* + * Copyright 2016 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.1 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://floralicense.org/license/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "Ui/Button.h" +#include "Utils/Callback.h" + +#include + +using namespace Ui; + +Button::Button() + : m_Timer(nullptr), m_IsLongpressed(false) +{ +} + +Button::~Button() +{ + resetTimer(); +} + +void Button::setPressedCallback(std::function callback) +{ + m_OnPressed = std::move(callback); +} + +void Button::setLongpressedCallback(std::function callback) +{ + m_OnLongpressed = std::move(callback); +} + +Evas_Object *Button::onCreate(Evas_Object *parent) +{ + Evas_Object *button = elm_button_add(parent); + return button; +} + +void Button::onCreated() +{ + evas_object_event_callback_add(getEvasObject(), EVAS_CALLBACK_MOUSE_DOWN, + makeCallback(&Button::onMouseDown), this); + evas_object_event_callback_add(getEvasObject(), EVAS_CALLBACK_MOUSE_UP, + makeCallback(&Button::onMouseUp), this); + evas_object_event_callback_add(getEvasObject(), EVAS_CALLBACK_MOUSE_OUT, + makeCallback(&Button::onMouseOut), this); +} + +void Button::onMouseDown(Evas *evas, Evas_Object *obj, void *eventInfo) +{ + m_IsLongpressed = false; + m_Timer = ecore_timer_add(elm_config_longpress_timeout_get(), + makeCallback(&Button::onTimeout), this); +} + +void Button::onMouseUp(Evas *evas, Evas_Object *obj, void *eventInfo) +{ + Evas_Event_Mouse_Up *e = (Evas_Event_Mouse_Up *) eventInfo; + + if (!m_IsLongpressed) { + int x = 0, y = 0, w = 0, h = 0; + evas_object_geometry_get(obj, &x, &y, &w, &h); + + if (m_OnPressed) { + if (e->output.x >= x && e->output.x <= x + w + && e->output.y >= y && e->output.x <= y + h) { + m_OnPressed(*this); + } + } + + resetTimer(); + } +} + +void Button::onMouseOut(Evas *evas, Evas_Object *obj, void *eventInfo) +{ + resetTimer(); +} + +void Button::resetTimer() +{ + ecore_timer_del(m_Timer); + m_Timer = nullptr; +} + +Eina_Bool Button::onTimeout() +{ + if (m_OnLongpressed) { + m_IsLongpressed = m_OnLongpressed(*this); + } + + resetTimer(); + return ECORE_CALLBACK_CANCEL; +} diff --git a/lib-apps-common/src/Ui/CheckItem.cpp b/lib-apps-common/src/Ui/CheckItem.cpp new file mode 100644 index 0000000..f6f187b --- /dev/null +++ b/lib-apps-common/src/Ui/CheckItem.cpp @@ -0,0 +1,130 @@ +/* + * Copyright 2016 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.1 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://floralicense.org/license/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "Ui/CheckItem.h" +#include "Utils/Callback.h" + +using namespace Ui; + +CheckItem::CheckItem(GenContainer::Type type) + : GenItem(type), + m_CheckPart("*"), m_IsChecked(false), m_IsChecking(false), + m_LinkedItem(nullptr) +{ +} + +CheckItem::~CheckItem() +{ + unsetLinkedItem(); +} + +bool CheckItem::isChecked() const +{ + return m_IsChecked; +} + +bool CheckItem::setChecked(bool isChecked) +{ + if (isChecked == m_IsChecked) { + return true; + } + + m_IsChecked = isChecked; + if (!notifyCheck()) { + m_IsChecked = !m_IsChecked; + return false; + } + + Evas_Object *check = elm_object_item_part_content_get(getObjectItem(), m_CheckPart.c_str()); + if (check) { + /* Enable animation */ + elm_object_signal_emit(check, m_IsChecked + ? "elm,activate,check,on" : "elm,activate,check,off", "elm"); + elm_check_state_set(check, m_IsChecked); + } + + return true; +} + +void CheckItem::setCheckCallback(CheckCallback callback) +{ + m_OnChecked = std::move(callback); +} + +void CheckItem::setLinkedItem(CheckItem *item) +{ + if (!item) { + return; + } + + unsetLinkedItem(); + item->unsetLinkedItem(); + + item->setChecked(m_IsChecked); + item->m_LinkedItem = this; + m_LinkedItem = item; +} + +void CheckItem::unsetLinkedItem() +{ + if (m_LinkedItem) { + m_LinkedItem->m_LinkedItem = nullptr; + m_LinkedItem = nullptr; + } +} + +void CheckItem::updateCheckPart() +{ + update(m_CheckPart.c_str(), ELM_GENLIST_ITEM_FIELD_CONTENT); +} + +Evas_Object *CheckItem::getContent(Evas_Object *parent, const char *part) +{ + m_CheckPart = part; + + Elm_Check *check = elm_check_add(parent); + elm_check_state_set(check, m_IsChecked); + elm_check_state_pointer_set(check, &m_IsChecked); + elm_object_signal_emit(check, "elm,event,pass,enabled", "elm"); + + return check; +} + +void CheckItem::onSelected() +{ + setChecked(!m_IsChecked); +} + +bool CheckItem::notifyCheck() +{ + if (m_IsChecking) { + return false; + } + + bool isAllowed = false; + m_IsChecking = true; + + if (onChecked(m_IsChecked)) { + if (!m_OnChecked || m_OnChecked(m_IsChecked)) { + if (!m_LinkedItem || m_LinkedItem->setChecked(m_IsChecked)) { + isAllowed = true; + } + } + } + + m_IsChecking = false; + return isAllowed; +} diff --git a/lib-apps-common/src/Ui/Control.cpp b/lib-apps-common/src/Ui/Control.cpp new file mode 100644 index 0000000..0d1d866 --- /dev/null +++ b/lib-apps-common/src/Ui/Control.cpp @@ -0,0 +1,158 @@ +/* + * Copyright 2016 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.1 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://floralicense.org/license/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "Ui/Control.h" +#include "Utils/Callback.h" + +#define EVENT_TYPE_CHECK "type_check" + +using namespace Ui; + +namespace +{ + struct TypeCheckInfo + { + const std::type_info &type; + Control *object; + }; +} + +Control::Control() + : m_Object(nullptr), m_CreateTimer(nullptr) +{ +} + +Control::~Control() +{ + if (m_CreateTimer) { + ecore_timer_del(m_CreateTimer); + } + + destroyEvasObject(); +} + +Evas_Object *Control::create(Evas_Object *parent) +{ + if (!m_Object) { + setEvasObject(onCreate(parent)); + if (!m_CreateTimer) { + onCreated(); + } else { + ecore_timer_thaw(m_CreateTimer); + } + } + + return m_Object; +} + +void Control::setCreateTimer(double time) +{ + if (m_CreateTimer) { + ecore_timer_del(m_CreateTimer); + } + + m_CreateTimer = ecore_timer_add(time, [](void *data) { + Control *control = (Control *) data; + control->m_CreateTimer = nullptr; + control->onCreated(); + return EINA_FALSE; + }, this); + ecore_timer_freeze(m_CreateTimer); +} + +void Control::resetCreateTimer() +{ + if (m_CreateTimer) { + ecore_timer_del(m_CreateTimer); + m_CreateTimer = nullptr; + + if (m_Object) { + onCreated(); + } + } +} + +Evas_Object *Control::getEvasObject() const +{ + return m_Object; +} + +Control *Control::getControl(Evas_Object *object, const std::type_info &type) +{ + TypeCheckInfo checkInfo = { type, nullptr }; + evas_object_smart_callback_call(object, EVENT_TYPE_CHECK, &checkInfo); + return checkInfo.object; +} + +Control *Control::findParent(Evas_Object *object, const std::type_info &type) +{ + while (object) { + if (auto control = getControl(object, type)) { + return control; + } + object = elm_object_parent_widget_get(object); + } + + return nullptr; +} + +void Control::setEvasObject(Evas_Object *object) +{ + m_Object = object; + evas_object_smart_callback_add(m_Object, EVENT_TYPE_CHECK, + makeCallback(&Control::onTypeCheck), this); + evas_object_event_callback_add(m_Object, EVAS_CALLBACK_DEL, + (Evas_Object_Event_Cb) makeCallback(&Control::onDestroy), this); + evas_object_event_callback_add(m_Object, EVAS_CALLBACK_FREE, + makeCallback(&Control::onDestroyed), this); +} + +Evas_Object *Control::resetEvasObject() +{ + Evas_Object *object = m_Object; + evas_object_smart_callback_del_full(m_Object, EVENT_TYPE_CHECK, + makeCallback(&Control::onTypeCheck), this); + evas_object_event_callback_del_full(m_Object, EVAS_CALLBACK_DEL, + (Evas_Object_Event_Cb) makeCallback(&Control::onDestroy), this); + evas_object_event_callback_del_full(m_Object, EVAS_CALLBACK_FREE, + makeCallback(&Control::onDestroyed), this); + m_Object = nullptr; + return object; +} + +void Control::destroyEvasObject() +{ + if (m_Object) { + onDestroy(); + evas_object_del(resetEvasObject()); + } +} + +void Control::onTypeCheck(Evas_Object *obj, void *eventInfo) +{ + auto checkInfo = (TypeCheckInfo *) eventInfo; + if (!checkInfo->object) { + if (typeid(*this) == checkInfo->type || hasType(checkInfo->type)) { + checkInfo->object = this; + } + } +} + +void Control::onDestroyed(Evas *e, Evas_Object *obj, void *eventInfo) +{ + m_Object = nullptr; + delete this; +} diff --git a/lib-apps-common/src/Ui/Editfield.cpp b/lib-apps-common/src/Ui/Editfield.cpp new file mode 100644 index 0000000..7a38245 --- /dev/null +++ b/lib-apps-common/src/Ui/Editfield.cpp @@ -0,0 +1,151 @@ +/* + * Copyright 2016 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.1 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://floralicense.org/license/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "Ui/Editfield.h" + +#include +#include +#include + +#define DEFAULT_TEXT_LIMIT 0 +#define BUFFER_SIZE 256 + +using namespace Ui; + + +Editfield::Editfield() + : m_TextLimitFilter{DEFAULT_TEXT_LIMIT, DEFAULT_TEXT_LIMIT}, + m_LimitToastText(nullptr) +{ +} + +Editfield *Editfield::create(Evas_Object *parent, const char *guideText) +{ + Editfield *editfield = new Editfield(); + editfield->create(parent); + editfield->setGuideText(guideText); + return editfield; +} + +Evas_Object *Editfield::onCreate(Evas_Object *parent) +{ + Evas_Object *layout = elm_layout_add(parent); + elm_layout_theme_set(layout, "layout", "editfield", "singleline"); + + Evas_Object *entry = elm_entry_add(parent); + elm_entry_single_line_set(entry, EINA_TRUE); + elm_entry_scrollable_set(entry, EINA_TRUE); + elm_object_part_content_set(layout, "elm.swallow.content", entry); + elm_entry_markup_filter_append(entry, elm_entry_filter_limit_size, &m_TextLimitFilter); + + evas_object_smart_callback_add(entry, "changed", (Evas_Smart_Cb) onChanged, this); + evas_object_smart_callback_add(entry, "focused", (Evas_Smart_Cb) onFocused, layout); + evas_object_smart_callback_add(entry, "unfocused", (Evas_Smart_Cb) onUnfocused, layout); + evas_object_smart_callback_add(entry, "maxlength,reached", (Evas_Smart_Cb) onMaxLengthReached, this); + + Evas_Object *button = elm_button_add(parent); + elm_object_style_set(button, "editfield_clear"); + elm_object_focus_allow_set(button, EINA_FALSE); + elm_object_part_content_set(layout, "elm.swallow.button", button); + evas_object_smart_callback_add(button, "clicked", (Evas_Smart_Cb) onClearPressed, entry); + + return layout; +} + +void Editfield::setMultiline(bool isMultiline) +{ + elm_entry_single_line_set(getEntry(), !isMultiline); + elm_entry_scrollable_set(getEntry(), !isMultiline); + elm_entry_line_wrap_set(getEntry(), isMultiline ? ELM_WRAP_MIXED : ELM_WRAP_NONE); +} + +void Editfield::setGuideText(const char *guideText) +{ + elm_object_translatable_part_text_set(getEntry(), "elm.guide", guideText); +} + +Evas_Object *Editfield::getEntry() +{ + return elm_object_part_content_get(getEvasObject(), "elm.swallow.content"); +} + +Evas_Object *Editfield::getClearButton() +{ + return elm_object_part_content_get(getEvasObject(), "elm.swallow.button"); +} + +void Editfield::setEnabled(bool isEnabled) +{ + elm_object_disabled_set(getEntry(), !isEnabled); + setClearButtonVisible(isEnabled); +} + +void Editfield::setClearButtonVisible(bool isVisible) +{ + if (isVisible) { + elm_object_signal_emit(getEvasObject(), "elm,action,show,button", ""); + } else { + elm_object_signal_emit(getEvasObject(), "elm,action,hide,button", ""); + } +} + +void Editfield::setTextLimit(int limit) +{ + if (m_TextLimitFilter.max_char_count == limit) { + return; + } + + elm_entry_markup_filter_remove(getEntry(), elm_entry_filter_limit_size, &m_TextLimitFilter); + m_TextLimitFilter.max_char_count = limit; + elm_entry_markup_filter_append(getEntry(), elm_entry_filter_limit_size, &m_TextLimitFilter); +} + +void Editfield::setLimitToastText(const char *text) +{ + m_LimitToastText = text; +} + +void Editfield::onChanged(Editfield *editfield, Evas_Object *entry, void *eventInfo) +{ + if (!elm_object_disabled_get(entry)) { + editfield->setClearButtonVisible(!elm_entry_is_empty(entry)); + } +} + +void Editfield::onFocused(Evas_Object *layout, Evas_Object *entry, void *eventInfo) +{ + elm_object_signal_emit(layout, "elm,state,focused", ""); +} + +void Editfield::onUnfocused(Evas_Object *layout, Evas_Object *entry, void *eventInfo) +{ + elm_object_signal_emit(layout, "elm,state,unfocused", ""); +} + +void Editfield::onClearPressed(Evas_Object *entry, Evas_Object *button, void *eventInfo) +{ + elm_entry_entry_set(entry, ""); + elm_object_focus_set(entry, EINA_TRUE); +} + +void Editfield::onMaxLengthReached(Editfield *editfield, Evas_Object *button, void *eventInfo) +{ + if (editfield->m_LimitToastText) { + char buffer[BUFFER_SIZE]; + snprintf(buffer, sizeof(buffer), _(editfield->m_LimitToastText), editfield->m_TextLimitFilter.max_char_count); + notification_status_message_post(buffer); + } +} diff --git a/lib-apps-common/src/Ui/GenContainer.cpp b/lib-apps-common/src/Ui/GenContainer.cpp new file mode 100644 index 0000000..24c67fa --- /dev/null +++ b/lib-apps-common/src/Ui/GenContainer.cpp @@ -0,0 +1,181 @@ +/* + * Copyright 2016 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.1 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://floralicense.org/license/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "Ui/GenContainer.h" +#include "Ui/GenItem.h" + +using namespace Ui; + +#define INSERTER_PARAMS Evas_Object *obj, const Elm_Gen_Item_Class *itc, const void *data, \ + Elm_Object_Item *parent, Elm_Object_Item *sibling, int type, \ + Evas_Smart_Cb func, const void *func_data + +typedef Elm_Object_Item *(*Inserter)(INSERTER_PARAMS); +typedef void (*Updater)(Elm_Genlist_Item *obj, const char *parts, int type); + +struct Ui::GenContainerApi +{ + Evas_Object *(*create)(Evas_Object *parent); + Elm_Object_Item *(*getFirstItem)(const Evas_Object *obj); + Elm_Object_Item *(*getLastItem)(const Evas_Object *obj); + Eina_List *(*getRealizedItems)(const Evas_Object *obj); + Updater updateItemFields; + + Inserter appendItem; + Inserter prependItem; + Inserter insertAfter; + Inserter insertBefore; +}; + +namespace +{ + const GenContainerApi api[] = { + { + elm_genlist_add, + elm_genlist_first_item_get, + elm_genlist_last_item_get, + elm_genlist_realized_items_get, + (Updater) elm_genlist_item_fields_update, + + [](INSERTER_PARAMS) { return elm_genlist_item_append(obj, itc, data, parent, Elm_Genlist_Item_Type(type), func, func_data); }, + [](INSERTER_PARAMS) { return elm_genlist_item_prepend(obj, itc, data, parent, Elm_Genlist_Item_Type(type), func, func_data); }, + (Inserter) elm_genlist_item_insert_after, + (Inserter) elm_genlist_item_insert_before + }, + { + elm_gengrid_add, + elm_gengrid_first_item_get, + elm_gengrid_last_item_get, + elm_gengrid_realized_items_get, + (Updater) elm_gengrid_item_fields_update, + + [](INSERTER_PARAMS) { return elm_gengrid_item_append(obj, itc, data, func, func_data); }, + [](INSERTER_PARAMS) { return elm_gengrid_item_prepend(obj, itc, data, func, func_data); }, + [](INSERTER_PARAMS) { return elm_gengrid_item_insert_after(obj, itc, data, sibling, func, func_data); }, + [](INSERTER_PARAMS) { return elm_gengrid_item_insert_before(obj, itc, data, sibling, func, func_data); }, + } + }; +} + +GenContainer::GenContainer(Type type) + : m_Api(&api[type]) +{ +} + +Evas_Object *GenContainer::onCreate(Evas_Object *parent) +{ + Evas_Object *obj = m_Api->create(parent); + + evas_object_smart_callback_add(obj, "selected", + (Evas_Smart_Cb) &GenContainer::onItemSelected, this); + evas_object_smart_callback_add(obj, "longpressed", + (Evas_Smart_Cb) &GenContainer::onItemLongpressed, this); + evas_object_smart_callback_add(obj, "realized", + (Evas_Smart_Cb) &GenContainer::onItemRealized, this); + evas_object_smart_callback_add(obj, "unrealized", + (Evas_Smart_Cb) &GenContainer::onItemUnrealized, this); + return obj; +} + +GenItem *GenContainer::getFirstItem() const +{ + Elm_Object_Item *item = m_Api->getFirstItem(getEvasObject()); + return (GenItem *) elm_object_item_data_get(item); +} + +GenItem *GenContainer::getLastItem() const +{ + Elm_Object_Item *item = m_Api->getLastItem(getEvasObject()); + return (GenItem *) elm_object_item_data_get(item); +} + +GenIterator GenContainer::begin() const +{ + return getFirstItem(); +} + +GenIterator GenContainer::end() const +{ + return nullptr; +} + +void GenContainer::insert(GenItem *item, GenItem *parent, GenItem *sibling, Position position) +{ + if (!item) { + return; + } + + if (item->isInserted()) { + item->pop(); + } + + Elm_Object_Item *parentItem = parent ? parent->getObjectItem() : nullptr; + Elm_Object_Item *siblingItem = sibling ? sibling->getObjectItem() : nullptr; + + Inserter insert = nullptr; + if (siblingItem) { + insert = (position == Before) ? m_Api->insertBefore : m_Api->insertAfter; + } else { + insert = (position == Before) ? m_Api->appendItem : m_Api->prependItem; + } + + item->onInserted(insert(getEvasObject(), item->getItemClass(), item, + parentItem, siblingItem, item->getType(), nullptr, nullptr)); +} + +void GenContainer::update(const char *parts, int type) +{ + Eina_List *list = m_Api->getRealizedItems(getEvasObject()); + Eina_List *node = nullptr; + void *item = nullptr; + EINA_LIST_FOREACH(list, node, item) { + m_Api->updateItemFields((Elm_Object_Item *) item, parts, type); + } + + eina_list_free(list); +} + +void GenContainer::onItemSelected(void *data, Evas_Object *obj, Elm_Object_Item *objectItem) +{ + GenItem *item = (GenItem *) elm_object_item_data_get(objectItem); + if (item) { + item->onSelected(objectItem); + } +} + +void GenContainer::onItemLongpressed(void *data, Evas_Object *obj, Elm_Object_Item *objectItem) +{ + GenItem *item = (GenItem *) elm_object_item_data_get(objectItem); + if (item) { + item->onLongpressed(objectItem); + } +} + +void GenContainer::onItemRealized(void *data, Evas_Object *obj, Elm_Object_Item *objectItem) +{ + GenItem *item = (GenItem *) elm_object_item_data_get(objectItem); + if (item) { + item->onRealized(objectItem); + } +} + +void GenContainer::onItemUnrealized(void *data, Evas_Object *obj, Elm_Object_Item *objectItem) +{ + GenItem *item = (GenItem *) elm_object_item_data_get(objectItem); + if (item) { + item->onUnrealized(objectItem); + } +} diff --git a/lib-apps-common/src/Ui/GenGroupItem.cpp b/lib-apps-common/src/Ui/GenGroupItem.cpp new file mode 100644 index 0000000..7fced77 --- /dev/null +++ b/lib-apps-common/src/Ui/GenGroupItem.cpp @@ -0,0 +1,224 @@ +/* + * Copyright 2016 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.1 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://floralicense.org/license/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "Ui/GenGroupItem.h" +#include +#include + +using namespace Ui; + +GenGroupItem::GenGroupItem(const char *title) +{ + if (title) { + m_Title = title; + } +} + +GenGroupItem::~GenGroupItem() +{ + for (auto &&itemPtr : m_ItemsCache) { + if (auto item = itemPtr.lock()) { + delete item.get(); + } + } +} + +GenItem *GenGroupItem::getFirstItem() const +{ + if (!m_ItemsCache.empty()) { + return m_ItemsCache.front().lock().get(); + } + + const Eina_List *subitems = elm_genlist_item_subitems_get(getObjectItem()); + Elm_Object_Item *item = (Elm_Object_Item *) eina_list_data_get(subitems); + return (GenItem *) elm_object_item_data_get(item); +} + +GenItem *GenGroupItem::getLastItem() const +{ + if (!m_ItemsCache.empty()) { + return m_ItemsCache.back().lock().get(); + } + + const Eina_List *subitems = elm_genlist_item_subitems_get(getObjectItem()); + Elm_Object_Item *item = (Elm_Object_Item *) eina_list_last_data_get(subitems); + return (GenItem *) elm_object_item_data_get(item); +} + +GenIterator GenGroupItem::begin() +{ + return getFirstItem(); +} + +GenIterator GenGroupItem::end() +{ + GenItem *lastItem = getLastItem(); + return lastItem ? lastItem->getNextItem() : nullptr; +} + +size_t GenGroupItem::getItemCount() const +{ + if (!m_ItemsCache.empty()) { + return std::count_if(m_ItemsCache.begin(), m_ItemsCache.end(), + [](const GenItemPtr &itemPtr) { + return !itemPtr.expired(); + }); + } + + const Eina_List *subitems = elm_genlist_item_subitems_get(getObjectItem()); + return eina_list_count(subitems); +} + +bool GenGroupItem::isEmpty() const +{ + return getItemCount() == 0; +} + +bool GenGroupItem::isExpanded() const +{ + Elm_Object_Item *item = getObjectItem(); + if (!item) { + return false; + } + + if (getType() == ELM_GENLIST_ITEM_TREE) { + return elm_genlist_item_expanded_get(item); + } + + return true; +} + +GenGroupItem *GenGroupItem::getNextGroupItem() const +{ + GenItem *lastItem = getLastItem(); + GenItem *item = lastItem ? lastItem->getNextItem() : getNextItem(); + if (item && item->isGroupItem()) { + return dynamic_cast(item); + } + + return nullptr; +} + +GenGroupItem *GenGroupItem::getPrevGroupItem() const +{ + GenItem *item = getPrevItem(); + if (item) { + if (item->isGroupItem()) { + return dynamic_cast(item); + } else { + return item->getParentItem(); + } + } + + return nullptr; +} + +void GenGroupItem::insertSubItem(GenItem *item, GenItem *sibling, + GenContainer::Position position) +{ + if (!item) { + return; + } + + GenContainer *container = getParent(); + if (container && isExpanded()) { + container->insert(item, this, sibling, position); + } else { + auto pos = m_ItemsCache.end(); + if (sibling) { + pos = std::find_if(m_ItemsCache.begin(), m_ItemsCache.end(), + [sibling](GenItemPtr &itemPtr) { + if (auto item = itemPtr.lock()) { + return item.get() == sibling; + } + return false; + }); + } + + if (pos != m_ItemsCache.end()) { + if (position == GenContainer::After) { + ++pos; + } + } else { + if (position == GenContainer::After) { + pos = m_ItemsCache.begin(); + } + } + + m_ItemsCache.insert(pos, item->getWeakPtr()); + } +} + +Elm_Gen_Item_Class *GenGroupItem::getItemClass() const +{ + static Elm_Gen_Item_Class itc = createItemClass("group_index"); + return &itc; +} + +char *GenGroupItem::getText(Evas_Object *parent, const char *part) +{ + if (strcmp(part, "elm.text") == 0) { + return strdup(_(m_Title.c_str())); + } + + return nullptr; +} + +void GenGroupItem::onInserted() +{ + if (getType() == ELM_GENLIST_ITEM_GROUP) { + elm_genlist_item_select_mode_set(getObjectItem(), ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY); + } + if (isExpanded()) { + insertSubItems(); + } +} + +void GenGroupItem::onPop() +{ + popSubItems(); +} + +void GenGroupItem::onExpanded(bool isExpanded) +{ + if (isExpanded) { + insertSubItems(); + } else { + popSubItems(); + } +} + +void GenGroupItem::insertSubItems() +{ + GenContainer *container = getParent(); + if (container) { + for (auto &&itemPtr : m_ItemsCache) { + if (auto item = itemPtr.lock()) { + container->insert(item.get(), this); + } + } + m_ItemsCache.clear(); + } +} + +void GenGroupItem::popSubItems() +{ + for (auto it = begin(), endIt = end(); it != endIt; ) { + GenItem *item = *it++; + item->pop(); + m_ItemsCache.push_back(item->getWeakPtr()); + } +} diff --git a/lib-apps-common/src/Ui/GenItem.cpp b/lib-apps-common/src/Ui/GenItem.cpp new file mode 100644 index 0000000..9708e18 --- /dev/null +++ b/lib-apps-common/src/Ui/GenItem.cpp @@ -0,0 +1,267 @@ +/* + * Copyright 2016 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.1 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://floralicense.org/license/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "Ui/GenItem.h" +#include "Ui/GenContainer.h" +#include "Ui/GenGroupItem.h" +#include "Utils/Callback.h" + +using namespace Ui; + +typedef void(*ScrollFunc)(Elm_Object_Item *item, int type); +typedef void(*UpdateFieldsFunc)(Elm_Object_Item *item, const char *parts, int fieldType); + +struct Ui::GenItemApi +{ + Elm_Object_Item *(*getParent)(const Elm_Object_Item *item); + Elm_Object_Item *(*getNext)(const Elm_Object_Item *item); + Elm_Object_Item *(*getPrev)(const Elm_Object_Item *item); + ScrollFunc bringIn; + ScrollFunc show; + void(*setSelected)(Elm_Object_Item *item, Eina_Bool selected); + UpdateFieldsFunc updateFields; +}; + +namespace +{ + const GenItemApi api[] = { + { elm_genlist_item_parent_get, + elm_genlist_item_next_get, + elm_genlist_item_prev_get, + (ScrollFunc) elm_genlist_item_bring_in, + (ScrollFunc) elm_genlist_item_show, + elm_genlist_item_selected_set, + (UpdateFieldsFunc) elm_genlist_item_fields_update }, + + { [](const Elm_Object_Item *item) -> Elm_Object_Item * { return nullptr; }, + elm_gengrid_item_next_get, + elm_gengrid_item_prev_get, + (ScrollFunc) elm_gengrid_item_bring_in, + (ScrollFunc) elm_gengrid_item_show, + elm_gengrid_item_selected_set, + (UpdateFieldsFunc) elm_gengrid_item_fields_update } + }; +} + +GenItem::GenItem(GenContainer::Type type) + : m_Item(nullptr), m_Preserve(false), + m_IsMatching(true), m_IsRealized(false), m_IsVisible(false), + m_IsFocusPending(false), m_IsLongpressed(false), + m_Api(&api[type]) +{ +} + +GenItem::~GenItem() +{ + if (m_OnDestroy) { + m_OnDestroy(); + } + + if (m_Item) { + pop(); + } +} + +bool GenItem::isRealized() const +{ + return m_IsRealized; +} + +bool GenItem::isInserted() const +{ + return m_Item != nullptr; +} + +bool GenItem::isVisible() const +{ + return m_IsVisible; +} + +Elm_Object_Item *GenItem::getObjectItem() const +{ + return m_Item; +} + +GenGroupItem *GenItem::getParentItem() const +{ + Elm_Object_Item *objectItem = m_Api->getParent(getObjectItem()); + GenItem *item = (GenItem *) elm_object_item_data_get(objectItem); + return dynamic_cast(item); +} + +GenContainer *GenItem::getParent() const +{ + Evas_Object *genlist = elm_object_item_widget_get(getObjectItem()); + return Control::getControl(genlist); +} + +GenItem *GenItem::getNextItem() const +{ + Elm_Object_Item *item = m_Api->getNext(getObjectItem()); + return (GenItem *) elm_object_item_data_get(item); +} + +GenItem *GenItem::getPrevItem() const +{ + Elm_Object_Item *item = m_Api->getPrev(getObjectItem()); + return (GenItem *) elm_object_item_data_get(item); +} + +GenItemPtr GenItem::getWeakPtr() +{ + if (!m_SelfPtr) { + m_SelfPtr.reset(this, [](GenItem *){ }); + } + + return m_SelfPtr; +} + +void GenItem::setSelectCallback(SelectCallback callback) +{ + m_OnSelected = std::move(callback); +} + +void GenItem::setDestroyCallback(DestroyCallback callback) +{ + m_OnDestroy = std::move(callback); +} + +void GenItem::scrollTo(int position, bool isAnimated) +{ + auto scroll = isAnimated ? m_Api->bringIn : m_Api->show; + scroll(getObjectItem(), position); +} + +void GenItem::focus(Elm_Genlist_Item_Scrollto_Type position, bool isAnimated) +{ + scrollTo(position, isAnimated); + if (isRealized()) { + onFocused(); + } else { + m_IsFocusPending = true; + } +} + +void GenItem::update(const char *parts, int partType) +{ + m_Api->updateFields(m_Item, parts, partType); +} + +void GenItem::pop() +{ + onPop(); + + m_Preserve = true; + elm_object_item_del(m_Item); + m_Preserve = false; +} + +Elm_Gen_Item_Class GenItem::createItemClass(const char *style, + const char *decorateStyle, const char *editStyle) +{ + Elm_Gen_Item_Class itc = { ELM_GEN_ITEM_CLASS_HEADER, 0 }; + itc.item_style = style; + itc.decorate_item_style = decorateStyle; + itc.decorate_all_item_style = editStyle; + itc.func.text_get = makeCallback(&GenItem::getText); + itc.func.content_get = makeCallback(&GenItem::getContent); + itc.func.state_get = makeCallback(&GenItem::getState); + itc.func.filter_get = makeCallback(&GenItem::onFiltered); + itc.func.del = makeCallback(&GenItem::onDestroy); + + return itc; +} + +Elm_Gen_Item_Class *GenItem::getItemClass() const +{ + static Elm_Gen_Item_Class itc = createItemClass("type1"); + return &itc; +} + +void GenItem::updateVisibility() +{ + bool isVisible = isInserted() && m_IsMatching; + if (m_IsVisible != isVisible) { + m_IsVisible = isVisible; + onVisibilityChanged(m_IsVisible); + } +} + +void GenItem::onInserted(Elm_Object_Item *item) +{ + m_Item = item; + onInserted(); + updateVisibility(); +} + +Eina_Bool GenItem::onFiltered(Evas_Object *parent, void *filter) +{ + m_IsMatching = compare(filter); + updateVisibility(); + return m_IsMatching; +} + +void GenItem::onDestroy(Evas_Object *genlist) +{ + m_Item = nullptr; + if (!m_Preserve) { + delete this; + } else { + m_IsMatching = true; + updateVisibility(); + } +} + +void GenItem::onSelected(Elm_Object_Item *item) +{ + m_Api->setSelected(item, EINA_FALSE); + if (m_IsLongpressed) { + m_IsLongpressed = false; + return; + } + + onSelected(); + + if (m_OnSelected) { + m_OnSelected(); + } +} + +void GenItem::onLongpressed(Elm_Object_Item *item) +{ + m_IsLongpressed = onLongpressed(); +} + +void GenItem::onRealized(Elm_Object_Item *item) +{ + if (!m_Item) { + m_Item = item; + } + + m_IsRealized = true; + if (m_IsFocusPending) { + m_IsFocusPending = false; + onFocused(); + } + + onRealized(); +} + +void GenItem::onUnrealized(Elm_Object_Item *item) +{ + m_IsRealized = false; + onUnrealized(); +} diff --git a/lib-apps-common/src/Ui/GenIterator.cpp b/lib-apps-common/src/Ui/GenIterator.cpp new file mode 100644 index 0000000..602da5a --- /dev/null +++ b/lib-apps-common/src/Ui/GenIterator.cpp @@ -0,0 +1,65 @@ +/* + * Copyright 2016 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.1 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://floralicense.org/license/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "Ui/GenIterator.h" +#include "Ui/GenItem.h" + +using namespace Ui; + +GenIterator::GenIterator(GenItem *item) + : m_Item(item) +{ +} + +GenIterator &GenIterator::operator++() +{ + if (m_Item) { + m_Item = m_Item->getNextItem(); + } + return *this; +} + +GenIterator GenIterator::operator++(int) +{ + auto it(*this); + ++*this; + return it; +} + +GenIterator &GenIterator::operator--() +{ + if (m_Item) { + m_Item = m_Item->getPrevItem(); + } + return *this; +} + +GenIterator GenIterator::operator--(int) +{ + auto it(*this); + --*this; + return it; +} + +GenItem *GenIterator::operator*() const +{ + return m_Item; +} + +bool GenIterator::operator!=(const GenIterator &that) const +{ + return m_Item != that.m_Item; +} diff --git a/lib-apps-common/src/Ui/Gengrid.cpp b/lib-apps-common/src/Ui/Gengrid.cpp new file mode 100644 index 0000000..aa62fa3 --- /dev/null +++ b/lib-apps-common/src/Ui/Gengrid.cpp @@ -0,0 +1,29 @@ +/* + * Copyright 2016 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.1 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://floralicense.org/license/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "Ui/Gengrid.h" + +using namespace Ui; + +Gengrid::Gengrid() + : GenContainer(TypeGengrid) +{ +} + +void Gengrid::insert(GenItem *item, GenItem *sibling, Position position) +{ + GenContainer::insert(item, nullptr, sibling, position); +} diff --git a/lib-apps-common/src/Ui/Genlist.cpp b/lib-apps-common/src/Ui/Genlist.cpp new file mode 100644 index 0000000..c19a166 --- /dev/null +++ b/lib-apps-common/src/Ui/Genlist.cpp @@ -0,0 +1,59 @@ +/* + * Copyright 2016 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.1 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://floralicense.org/license/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "Ui/Genlist.h" +#include "Ui/GenGroupItem.h" + +using namespace Ui; + +Genlist::Genlist() + : GenContainer(TypeGenlist) +{ +} + +void Genlist::onCreated() +{ + Evas_Object *genlist = getEvasObject(); + elm_genlist_mode_set(genlist, ELM_LIST_COMPRESS); + elm_genlist_homogeneous_set(genlist, EINA_TRUE); + + evas_object_smart_callback_add(genlist, "expanded", + (Evas_Smart_Cb) &Genlist::onItemExpanded, this); + evas_object_smart_callback_add(genlist, "contracted", + (Evas_Smart_Cb) &Genlist::onItemContracted, this); +} + +void Genlist::onItemExpanded(void *data, Evas_Object *obj, Elm_Object_Item *objectItem) +{ + GenItem *item = (GenItem *) elm_object_item_data_get(objectItem); + if (item && item->isGroupItem()) { + GenGroupItem *groupItem = dynamic_cast(item); + if (groupItem) { + groupItem->onExpanded(true); + } + } +} + +void Genlist::onItemContracted(void *data, Evas_Object *obj, Elm_Object_Item *objectItem) +{ + GenItem *item = (GenItem *) elm_object_item_data_get(objectItem); + if (item && item->isGroupItem()) { + GenGroupItem *groupItem = dynamic_cast(item); + if (groupItem) { + groupItem->onExpanded(false); + } + } +} diff --git a/lib-apps-common/src/Ui/Hoversel.cpp b/lib-apps-common/src/Ui/Hoversel.cpp new file mode 100644 index 0000000..8f78ca7 --- /dev/null +++ b/lib-apps-common/src/Ui/Hoversel.cpp @@ -0,0 +1,115 @@ +/* + * Copyright 2016 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.1 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://floralicense.org/license/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "Ui/Hoversel.h" +#include "Ui/View.h" +#include "Ui/Window.h" +#include "Utils/Callback.h" + +#include + +using namespace Ui; + +Hoversel::Hoversel() + : m_View(nullptr) +{ +} + +Hoversel::~Hoversel() +{ + if (m_View) { + evas_object_smart_callback_del_full(m_View->getEvasObject(), EVENT_VIEW_NAVIGATION, + makeCallback(&Hoversel::onViewNavigation), this); + } +} + +Elm_Object_Item *Hoversel::addItem(const char *text, void *data) +{ + Elm_Object_Item *item = elm_hoversel_item_add(getEvasObject(), text, + nullptr, ELM_ICON_NONE, nullptr, data); + elm_object_item_text_translatable_set(item, EINA_TRUE); + return item; +} + +Elm_Object_Item *Hoversel::addItem(void *data) +{ + return addItem(nullptr, data); +} + +void Hoversel::setText(const char *text) +{ + elm_object_translatable_text_set(getEvasObject(), text); +} + +void Hoversel::setSelectedItem(Elm_Object_Item *item) +{ + setText(elm_object_item_translatable_text_get(item)); +} + +Evas_Object *Hoversel::onCreate(Evas_Object *parent) +{ + Evas_Object *hoversel = elm_hoversel_add(parent); + evas_object_smart_callback_add(hoversel, "selected", + (Evas_Smart_Cb) makeCallback(&Hoversel::onSelected), this); + evas_object_smart_callback_add(hoversel, "expanded", + &Hoversel::onExpanded, this); + evas_object_smart_callback_add(hoversel, "dismissed", + &Hoversel::onDismissed, this); + + m_View = findParent(parent); + if (m_View) { + evas_object_smart_callback_add(m_View->getEvasObject(), EVENT_VIEW_NAVIGATION, + makeCallback(&Hoversel::onViewNavigation), this); + } + + auto window = findParent(parent); + if (window) { + elm_hoversel_hover_parent_set(hoversel, window->getEvasObject()); + } + + return hoversel; +} + +void Hoversel::onViewNavigation(Evas_Object *obj, void *eventInfo) +{ + if (!eventInfo) { + elm_hoversel_hover_end(getEvasObject()); + } +} + +void Hoversel::onSelected(Evas_Object *hoversel, Elm_Object_Item *item) +{ + if (Selector::onSelected(item)) { + setSelectedItem(item); + } +} + +void Hoversel::onExpanded(void *data, Evas_Object *hoversel, void *eventInfo) +{ + eext_object_event_callback_add(hoversel, EEXT_CALLBACK_BACK, + &Hoversel::onBackPressed, nullptr); +} + +void Hoversel::onDismissed(void *data, Evas_Object *hoversel, void *eventInfo) +{ + eext_object_event_callback_del(hoversel, EEXT_CALLBACK_BACK, + &Hoversel::onBackPressed); +} + +void Hoversel::onBackPressed(void *data, Evas_Object *hoversel, void *eventInfo) +{ + elm_hoversel_hover_end(hoversel); +} diff --git a/lib-apps-common/src/Ui/ListPopup.cpp b/lib-apps-common/src/Ui/ListPopup.cpp new file mode 100644 index 0000000..b276f39 --- /dev/null +++ b/lib-apps-common/src/Ui/ListPopup.cpp @@ -0,0 +1,172 @@ +/* + * Copyright 2016 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.1 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://floralicense.org/license/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "Ui/ListPopup.h" +#include "Utils/Callback.h" +#include + +#define POPUP_HEIGHT_RATIO 0.75 + +using namespace Ui; + +struct ListPopup::ItemData +{ + std::string text; + void *userData; + ItemSelectCallback callback; +}; + +ListPopup::ListPopup(const char *itemStyle) + : m_GenlistSize{0}, m_MaxHeight(0), m_IsResizing(false), + m_Window(nullptr), m_Genlist(nullptr) +{ + m_ItemClass = elm_genlist_item_class_new(); + m_ItemClass->item_style = itemStyle; + m_ItemClass->func.text_get = (Elm_Gen_Item_Text_Get_Cb) &ListPopup::getText; + m_ItemClass->func.content_get = (Elm_Gen_Item_Content_Get_Cb) &ListPopup::getContent; + m_ItemClass->func.del = [](void *data, Evas_Object *obj) { + delete (ItemData *) data; + }; +} + +ListPopup::~ListPopup() +{ + evas_object_event_callback_del_full(m_Window, EVAS_CALLBACK_RESIZE, + makeCallback(&ListPopup::onWindowResized), this); + elm_genlist_item_class_free(m_ItemClass); +} + +Elm_Object_Item *ListPopup::addItem(std::string text, void *data, ItemSelectCallback callback) +{ + ItemData *itemData = new ItemData{ std::move(text), data, std::move(callback) }; + return elm_genlist_item_append(m_Genlist, m_ItemClass, itemData, + nullptr, ELM_GENLIST_ITEM_NONE, nullptr, nullptr); +} + +Elm_Object_Item *ListPopup::addItem(std::string text, ItemSelectCallback callback) +{ + return addItem(std::move(text), nullptr, std::move(callback)); +} + +Elm_Object_Item *ListPopup::addItem(void *data, ItemSelectCallback callback) +{ + return addItem("", data, std::move(callback)); +} + +void ListPopup::setSelectCallback(SelectCallback callback) +{ + m_OnSelected = std::move(callback); +} + +Evas_Object *ListPopup::onCreate(Evas_Object *parent) +{ + Evas_Object *popup = Popup::onCreate(parent); + elm_object_style_set(popup, "theme_bg"); + elm_object_part_content_set(popup, "elm.swallow.content", createGenlist(popup)); + + m_Window = elm_object_top_widget_get(popup); + evas_object_event_callback_add(m_Window, EVAS_CALLBACK_RESIZE, + makeCallback(&ListPopup::onWindowResized), this); + updateMaxHeight(); + + return popup; +} + +Evas_Object *ListPopup::createGenlist(Evas_Object *parent) +{ + m_Genlist = elm_genlist_add(parent); + elm_genlist_homogeneous_set(m_Genlist, EINA_TRUE); + elm_genlist_mode_set(m_Genlist, ELM_LIST_EXPAND); + evas_object_event_callback_add(m_Genlist, EVAS_CALLBACK_CHANGED_SIZE_HINTS, + makeCallback(&ListPopup::onGenlistResized), this); + + evas_object_smart_data_set(m_Genlist, this); + evas_object_smart_callback_add(m_Genlist, "selected", + (Evas_Smart_Cb) &ListPopup::onSelected, this); + return m_Genlist; +} + +char *ListPopup::getText(ItemData *itemData, Evas_Object *genlist, const char *part) +{ + ListPopup *popup = (ListPopup *) evas_object_smart_data_get(genlist); + char *text = popup->getItemText(itemData->userData, part); + if (!text && strcmp(part, "elm.text") == 0) { + text = strdup(_(itemData->text.c_str())); + } + + return text; +} + +Evas_Object *ListPopup::getContent(ItemData *itemData, Evas_Object *genlist, const char *part) +{ + ListPopup *popup = (ListPopup *) evas_object_smart_data_get(genlist); + return popup->getItemContent(itemData->userData, part); +} + +void ListPopup::onSelected(ListPopup *popup, Evas_Object *genlist, Elm_Object_Item *item) +{ + ItemData *itemData = (ItemData *) elm_object_item_data_get(item); + popup->onItemSelected(itemData->userData); + + if (itemData->callback) { + itemData->callback(); + } + + if (popup->m_OnSelected) { + popup->m_OnSelected(itemData->userData); + } + + elm_genlist_item_selected_set(item, EINA_FALSE); + popup->close(); +} + +void ListPopup::updateGenlistHeight() +{ + if (m_GenlistSize.h > m_MaxHeight) { + int itemHeight = 0; + int count = elm_genlist_items_count(m_Genlist); + if (count > 0) { + itemHeight = m_GenlistSize.h / count; + } + + if (itemHeight) { + m_IsResizing = true; + int genlistHeight = m_MaxHeight - m_MaxHeight % itemHeight; + evas_object_size_hint_min_set(m_Genlist, m_GenlistSize.w, genlistHeight); + m_IsResizing = false; + } + } +} + +void ListPopup::updateMaxHeight() +{ + evas_object_geometry_get(m_Window, nullptr, nullptr, nullptr, &m_MaxHeight); + m_MaxHeight *= POPUP_HEIGHT_RATIO; +} + +void ListPopup::onGenlistResized(Evas *e, Evas_Object *genlist, void *eventInfo) +{ + if (!m_IsResizing) { + evas_object_size_hint_min_get(m_Genlist, &m_GenlistSize.w, &m_GenlistSize.h); + updateGenlistHeight(); + } +} + +void ListPopup::onWindowResized(Evas *e, Evas_Object *window, void *eventInfo) +{ + updateMaxHeight(); + updateGenlistHeight(); +} diff --git a/lib-apps-common/src/Ui/Menu.cpp b/lib-apps-common/src/Ui/Menu.cpp new file mode 100644 index 0000000..92781a3 --- /dev/null +++ b/lib-apps-common/src/Ui/Menu.cpp @@ -0,0 +1,123 @@ +/* + * Copyright 2016 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.1 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://floralicense.org/license/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "Ui/Menu.h" +#include "Ui/View.h" +#include "Ui/Window.h" +#include "Utils/Callback.h" + +#include + +using namespace Ui; + +Menu::Menu() + : m_View(nullptr), m_Window(nullptr) +{ +} + +Menu::~Menu() +{ + if (m_View) { + evas_object_smart_callback_del_full(m_View->getEvasObject(), EVENT_VIEW_NAVIGATION, + makeCallback(&Menu::onViewNavigation), this); + } + if (m_Window) { + evas_object_event_callback_del_full(m_Window->getEvasObject(), EVAS_CALLBACK_RESIZE, + makeCallback(&Menu::onWindowResized), this); + } +} + +Elm_Object_Item *Menu::addItem(const char *text, ItemCallback callback) +{ + Elm_Object_Item *item = elm_ctxpopup_item_append(getEvasObject(), text, nullptr, + &Menu::onItemSelect, new ItemCallback(std::move(callback))); + elm_object_item_text_translatable_set(item, EINA_TRUE); + elm_object_item_del_cb_set(item, &Menu::onItemDestroy); + return item; +} + +void Menu::show() +{ + Evas_Coord y = 0, w = 0, h = 0; + Evas_Object *parent = elm_ctxpopup_hover_parent_get(getEvasObject()); + evas_object_geometry_get(parent, nullptr, &y, &w, &h); + + Evas_Object *menu = getEvasObject(); + int menuWidth = 0; + evas_object_geometry_get(menu, nullptr, nullptr, &menuWidth, nullptr); + evas_object_move(menu, w / 2 - menuWidth / 2, y + h); + evas_object_show(menu); +} + +Evas_Object *Menu::onCreate(Evas_Object *parent) +{ + Evas_Object *menu = elm_ctxpopup_add(parent); + elm_object_style_set(menu, "more/default"); + + evas_object_smart_callback_add(menu, "dismissed", + makeCallback(&Menu::onDismissed), this); + eext_object_event_callback_add(menu, EEXT_CALLBACK_BACK, + eext_ctxpopup_back_cb, nullptr); + eext_object_event_callback_add(menu, EEXT_CALLBACK_MORE, + eext_ctxpopup_back_cb, nullptr); + + m_View = findParent(parent); + if (m_View) { + evas_object_smart_callback_add(m_View->getEvasObject(), EVENT_VIEW_NAVIGATION, + makeCallback(&Menu::onViewNavigation), this); + } + + m_Window = findParent(parent); + if (m_Window) { + elm_ctxpopup_hover_parent_set(menu, m_Window->getEvasObject()); + evas_object_event_callback_add(m_Window->getEvasObject(), EVAS_CALLBACK_RESIZE, + makeCallback(&Menu::onWindowResized), this); + } + + return menu; +} + +void Menu::onViewNavigation(Evas_Object *obj, void *eventInfo) +{ + if (!eventInfo) { + elm_ctxpopup_dismiss(getEvasObject()); + } +} + +void Menu::onWindowResized(Evas *e, Evas_Object *obj, void *eventInfo) +{ + show(); +} + +void Menu::onItemSelect(void *data, Evas_Object *obj, void *item) +{ + ItemCallback &callback = *(ItemCallback *) data; + if (callback) { + callback(); + } + + elm_ctxpopup_dismiss(obj); +} + +void Menu::onItemDestroy(void *data, Evas_Object *obj, void *item) +{ + delete (ItemCallback *) data; +} + +void Menu::onDismissed(Evas_Object *obj, void *eventInfo) +{ + delete this; +} diff --git a/lib-apps-common/src/Ui/Naviframe.cpp b/lib-apps-common/src/Ui/Naviframe.cpp new file mode 100644 index 0000000..36e20cf --- /dev/null +++ b/lib-apps-common/src/Ui/Naviframe.cpp @@ -0,0 +1,159 @@ +/* + * Copyright 2016 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.1 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://floralicense.org/license/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "Ui/Naviframe.h" +#include "Utils/Callback.h" + +using namespace Ui; + +namespace Ui +{ + template <> + Navigator *Control::findParent(Evas_Object *object) + { + return findParent(object); + } +} + +Naviframe::Naviframe() + : m_Job(nullptr), + m_IsFirstPagePrevButtonVisible(false) +{ +} + +void Naviframe::setFirstPagePrevButton(bool isVisible) +{ + if (m_IsFirstPagePrevButtonVisible == isVisible) { + return; + } + m_IsFirstPagePrevButtonVisible = isVisible; + + if (auto page = getFirstPage()) { + page->setPrevButtonVisibility(m_IsFirstPagePrevButtonVisible); + } +} + +Evas_Object *Naviframe::onCreate(Evas_Object *parent) +{ + Evas_Object *naviframe = elm_naviframe_add(parent); + evas_object_smart_callback_add(naviframe, "transition,finished", + makeCallback(&Naviframe::onTransition), this); + + return naviframe; +} + +bool Naviframe::onBackPressed() +{ + if (!Navigator::onBackPressed()) { + return false; + } + + auto page = getCurrentPage(); + if (page && removeView(page->getView())) { + return false; + } + + return true; +} + +NaviframePage *Naviframe::addPage(View *view) +{ + Elm_Object_Item *naviItem = elm_naviframe_item_push(getEvasObject(), nullptr, + nullptr, nullptr, view->create(getEvasObject()), nullptr); + elm_naviframe_item_pop_cb_set(naviItem, makeCallback(&Naviframe::onItemPop), this); + + NaviframePage *page = new NaviframePage(naviItem); + + setCurrentPage(nullptr); + if (naviItem == elm_naviframe_bottom_item_get(getEvasObject())) { + page->setPrevButtonVisibility(m_IsFirstPagePrevButtonVisible); + m_Job = ecore_job_add(makeCallback(&Naviframe::onFirstPagePushed), this); + } else if (m_Job) { + ecore_job_del(m_Job); + m_Job = nullptr; + } + + return page; +} + +bool Naviframe::removePage(NavigatorPage *page) +{ + /* Postpone removal if transition in progress */ + if (getCurrentPage() == nullptr) { + m_PagesToRemove.push_back(page); + return true; + } + + Elm_Object_Item *naviItem = static_cast(page)->m_NaviItem; + if (naviItem == elm_naviframe_top_item_get(getEvasObject())) { + if (naviItem == elm_naviframe_bottom_item_get(getEvasObject())) { + return false; + } + elm_naviframe_item_pop(getEvasObject()); + } else { + elm_object_item_del(naviItem); + } + + if (!m_IsFirstPagePrevButtonVisible) { + getFirstPage()->setPrevButtonVisibility(false); + } + + return true; +} + +void Naviframe::navigateToPage(NavigatorPage *page) +{ + Elm_Object_Item *naviItem = static_cast(page)->m_NaviItem; + elm_naviframe_item_pop_to(naviItem); +} + +NaviframePage *Naviframe::getFirstPage() const +{ + Elm_Object_Item *item = elm_naviframe_bottom_item_get(getEvasObject()); + return (NaviframePage *) elm_object_item_data_get(item); +} + +NaviframePage *Naviframe::getLastPage() const +{ + Elm_Object_Item *item = elm_naviframe_top_item_get(getEvasObject()); + return (NaviframePage *) elm_object_item_data_get(item); +} + +Eina_Bool Naviframe::onItemPop(Elm_Object_Item *item) +{ + setCurrentPage(nullptr); + return EINA_TRUE; +} + +void Naviframe::onTransition(Evas_Object *obj, void *eventInfo) +{ + updateCurrentPage(); + for (auto &&page : m_PagesToRemove) { + removeView(page->getView()); + } + m_PagesToRemove.clear(); +} + +void Naviframe::onFirstPagePushed() +{ + updateCurrentPage(); + m_Job = nullptr; +} + +void Naviframe::updateCurrentPage() +{ + setCurrentPage(getLastPage()); +} diff --git a/lib-apps-common/src/Ui/NaviframePage.cpp b/lib-apps-common/src/Ui/NaviframePage.cpp new file mode 100644 index 0000000..f2a4943 --- /dev/null +++ b/lib-apps-common/src/Ui/NaviframePage.cpp @@ -0,0 +1,76 @@ +/* + * Copyright 2016 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.1 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://floralicense.org/license/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "Ui/NaviframePage.h" + +#include "Ui/Navigator.h" +#include "Utils/Callback.h" + +using namespace Ui; + +NaviframePage::NaviframePage(Elm_Object_Item *naviItem) + : m_NaviItem(naviItem) +{ + elm_object_item_data_set(m_NaviItem, this); + elm_object_item_del_cb_set(m_NaviItem, makeCallback(&NaviframePage::onDestroy)); + + Evas_Object *button = elm_button_add(elm_object_item_widget_get(naviItem)); + elm_object_style_set(button, "naviframe/back_btn/default"); + evas_object_smart_callback_add(button, "clicked", + makeCallback(&NaviframePage::onPrevPressed), this); + elm_object_item_part_content_set(naviItem, "elm.swallow.prev_btn", button); +} + +void NaviframePage::setTitle(const char *title) +{ + elm_object_item_translatable_part_text_set(m_NaviItem, "elm.text.title", title); +} + +void NaviframePage::setSubtitle(const char *subtitle) +{ + elm_object_item_translatable_part_text_set(m_NaviItem, "elm.text.subtitle", subtitle); +} + +void NaviframePage::setTitleVisibility(bool isVisible) +{ + elm_naviframe_item_title_enabled_set(m_NaviItem, isVisible, EINA_TRUE); +} + +void NaviframePage::setStyle(const char *style) +{ + elm_naviframe_item_style_set(m_NaviItem, style); +} + +void NaviframePage::setContent(const char *part, Evas_Object *content) +{ + elm_object_item_part_content_set(m_NaviItem, part, content); +} + +void NaviframePage::setPrevButtonVisibility(bool isVisible) +{ + elm_object_item_signal_emit(m_NaviItem, + isVisible ? "elm,state,prev_btn,show" : "elm,state,prev_btn,hide", "elm"); +} + +void NaviframePage::onDestroy(Evas_Object *obj, void *eventInfo) +{ + delete this; +} + +void NaviframePage::onPrevPressed(Evas_Object *obj, void *eventInfo) +{ + close(); +} diff --git a/lib-apps-common/src/Ui/Navigator.cpp b/lib-apps-common/src/Ui/Navigator.cpp new file mode 100644 index 0000000..ec581ad --- /dev/null +++ b/lib-apps-common/src/Ui/Navigator.cpp @@ -0,0 +1,136 @@ +/* + * Copyright 2016 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.1 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://floralicense.org/license/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "Ui/Navigator.h" +#include "Ui/NavigatorPage.h" + +using namespace Ui; + +Navigator::Navigator() + : m_CurrentPage(nullptr) +{ +} + +NavigatorPage *Navigator::getCurrentPage() const +{ + return m_CurrentPage; +} + +void Navigator::addView(View *view) +{ + if (!view) { + return; + } + + NavigatorPage *page = addPage(view); + page->onNavigatorAttached(this, view); + view->onNavigatorAttached(page); + + if (!m_CurrentPage) { + navigateTo(view); + } +} + +bool Navigator::removeView(View *view) +{ + if (!view) { + return false; + } + + if (removePage(view->getPage())) { + return true; + } + + if (!m_OnLastPage || m_OnLastPage()) { + if (NavigatorPage *page = getPage()) { + page->close(); + return true; + } + } + + return false; +} + +void Navigator::navigateTo(View *view) +{ + if (!view) { + return; + } + + NavigatorPage *page = view->getPage(); + if (!page) { + addView(view); + page = view->getPage(); + } + + if (page != m_CurrentPage) { + navigateToPage(page); + } +} + +void Navigator::setLastPageCallback(LastPageCallback callback) +{ + m_OnLastPage = std::move(callback); +} + +void Navigator::unsetLastPageCallback() +{ + m_OnLastPage = nullptr; +} + +void Navigator::setCurrentPage(NavigatorPage *page) +{ + if (page == m_CurrentPage) { + return; + } + + std::swap(m_CurrentPage, page); + if (isCurrent()) { + notifyNavigation(page, false); + notifyNavigation(m_CurrentPage, true); + } +} + +void Navigator::onNavigation(bool isCurrent) +{ + notifyNavigation(m_CurrentPage, isCurrent); +} + +void Navigator::onRotationChanged(int degree) +{ + if (m_CurrentPage) { + m_CurrentPage->getView()->onRotation(degree); + } +} + +bool Navigator::onBackPressed() +{ + return m_CurrentPage ? m_CurrentPage->getView()->onBackPressed() : true; +} + +void Navigator::onMenuPressed() +{ + if (m_CurrentPage) { + m_CurrentPage->getView()->onMenuPressed(); + } +} + +void Navigator::notifyNavigation(NavigatorPage *page, bool isCurrent) +{ + if (page) { + page->getView()->onNavigation(isCurrent, getRotation()); + } +} diff --git a/lib-apps-common/src/Ui/NavigatorPage.cpp b/lib-apps-common/src/Ui/NavigatorPage.cpp new file mode 100644 index 0000000..157f071 --- /dev/null +++ b/lib-apps-common/src/Ui/NavigatorPage.cpp @@ -0,0 +1,75 @@ +/* + * Copyright 2016 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.1 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://floralicense.org/license/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "Ui/NavigatorPage.h" +#include "Ui/Navigator.h" + +using namespace Ui; + +NavigatorPage::NavigatorPage() + : m_Navigator(nullptr), m_View(nullptr) +{ +} + +Navigator *NavigatorPage::getNavigator() const +{ + return m_Navigator; +} + +View *NavigatorPage::getView() const +{ + return m_View; +} + +Evas_Object *NavigatorPage::addTitleButton(ButtonPosition position, const char *text, + Evas_Smart_Cb callback, void *data) +{ + static const struct { + const char *style; + const char *part; + } buttons[] = { + /* ButtonLeft = */ { "naviframe/title_left", "title_left_btn" }, + /* ButtonRight = */ { "naviframe/title_right", "title_right_btn" } + }; + + Evas_Object *button = elm_button_add(getView()->getEvasObject()); + elm_object_style_set(button, buttons[position].style); + elm_object_translatable_text_set(button, text); + evas_object_smart_callback_add(button, "clicked", + callback, data); + setContent(buttons[position].part, button); + + return button; +} + +void NavigatorPage::setExpanded(bool isExpanded) +{ + setTitleVisibility(isExpanded); + if (m_Navigator && m_Navigator->getPage()) { + m_Navigator->getPage()->setTitleVisibility(!isExpanded); + } +} + +void NavigatorPage::close() +{ + m_Navigator->removeView(m_View); +} + +void NavigatorPage::onNavigatorAttached(Navigator *navigator, View *view) +{ + m_Navigator = navigator; + m_View = view; +} diff --git a/lib-apps-common/src/Ui/Popup.cpp b/lib-apps-common/src/Ui/Popup.cpp new file mode 100644 index 0000000..3489c3f --- /dev/null +++ b/lib-apps-common/src/Ui/Popup.cpp @@ -0,0 +1,189 @@ +/* + * Copyright 2016 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.1 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://floralicense.org/license/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "Ui/Popup.h" +#include "Ui/View.h" +#include "Ui/Window.h" +#include "Utils/Callback.h" +#include "Utils/Range.h" + +#include + +#define BUTTON_DATA_KEY "callback" + +using namespace Ui; + +Popup::Popup() + : m_ButtonCount(0), m_View(nullptr), m_Window(nullptr) +{ +} + +Popup::~Popup() +{ + if (m_View) { + evas_object_smart_callback_del_full(m_View->getEvasObject(), EVENT_VIEW_NAVIGATION, + makeCallback(&Popup::onViewNavigation), this); + evas_object_event_callback_del_full(m_View->getEvasObject(), EVAS_CALLBACK_DEL, + makeCallback(&Popup::onViewDestroy), this); + } +} + +Popup *Popup::create(Evas_Object *parent, const char *title, + const char *text, const char *buttonText) +{ + Popup *popup = new Popup(); + popup->create(parent); + popup->setTitle(title); + popup->setText(text); + popup->addButton(buttonText); + return popup; +} + +void Popup::setTitle(const char *title) +{ + elm_object_translatable_part_text_set(getEvasObject(), "title,text", title); +} + +void Popup::setText(const char *text) +{ + elm_object_translatable_text_set(getEvasObject(), text); +} + +void Popup::setContent(Evas_Object *content) +{ + elm_object_part_content_set(getEvasObject(), "elm.swallow.content", content); +} + +void Popup::setCancelCallback(ButtonCallback callback) +{ + m_OnCanceled = std::move(callback); +} + +Evas_Object *Popup::addButton(const char *text, ButtonCallback callback) +{ + static const char *parts[] = { "button1", "button2", "button3" }; + const char *part = Utils::at(parts, m_ButtonCount); + if (!part) { + return nullptr; + } + + Evas_Object *button = elm_button_add(getEvasObject()); + elm_object_style_set(button, "bottom"); + elm_object_translatable_text_set(button, text); + elm_object_part_content_set(getEvasObject(), part, button); + + evas_object_data_set(button, BUTTON_DATA_KEY, new ButtonCallback(std::move(callback))); + evas_object_event_callback_add(button, EVAS_CALLBACK_DEL, + makeCallback(&Popup::onButtonDestroy), this); + evas_object_smart_callback_add(button, "clicked", + makeCallback(&Popup::onButtonPressed), this); + + ++m_ButtonCount; + return button; +} + +void Popup::show() +{ + evas_object_show(getEvasObject()); +} + +void Popup::close() +{ + elm_popup_dismiss(getEvasObject()); +} + +Evas_Object *Popup::onCreate(Evas_Object *parent) +{ + m_View = findParent(parent); + if (m_View) { + evas_object_smart_callback_add(m_View->getEvasObject(), EVENT_VIEW_NAVIGATION, + makeCallback(&Popup::onViewNavigation), this); + evas_object_event_callback_add(m_View->getEvasObject(), EVAS_CALLBACK_DEL, + makeCallback(&Popup::onViewDestroy), this); + } + + m_Window = findParent(parent); + if (m_Window) { + parent = m_Window->getBaseLayout(); + } + + Evas_Object *popup = elm_popup_add(parent); + elm_popup_align_set(popup, ELM_NOTIFY_ALIGN_FILL, 1.0); + evas_object_smart_callback_add(popup, "dismissed", + makeCallback(&Popup::onDismissed), this); + evas_object_smart_callback_add(popup, "block,clicked", + makeCallback(&Popup::onBlockPressed), this); + eext_object_event_callback_add(popup, EEXT_CALLBACK_BACK, + makeCallback(&Popup::onBackPressed), this); + + return popup; +} + +void Popup::onCanceled() +{ + if (!m_OnCanceled || m_OnCanceled()) { + close(); + } +} + +void Popup::onViewNavigation(Evas_Object *obj, void *eventInfo) +{ + if (!eventInfo) { + /* Don't close the popup if navigation is caused by window losing focus */ + if (!m_Window || elm_win_focus_get(m_Window->getEvasObject())) { + onCanceled(); + } + } +} + +void Popup::onViewDestroy(Evas *e, Evas_Object *obj, void *eventInfo) +{ + m_View = nullptr; +} + +void Popup::onButtonPressed(Evas_Object *obj, void *eventInfo) +{ + ButtonCallback *callback = (ButtonCallback *) evas_object_data_get(obj, BUTTON_DATA_KEY); + if (!(*callback)) { + callback = &m_OnCanceled; + } + if (!(*callback) || (*callback)()) { + close(); + } +} + +void Popup::onButtonDestroy(Evas *e, Evas_Object *obj, void *eventInfo) +{ + ButtonCallback *callback = (ButtonCallback *) evas_object_data_get(obj, BUTTON_DATA_KEY); + delete callback; +} + +void Popup::onBlockPressed(Evas_Object *obj, void *eventInfo) +{ + if (m_ButtonCount == 0) { + onCanceled(); + } +} + +void Popup::onBackPressed(Evas_Object *obj, void *eventInfo) +{ + onCanceled(); +} + +void Popup::onDismissed(Evas_Object *obj, void *eventInfo) +{ + delete this; +} diff --git a/lib-apps-common/src/Ui/ProcessPopup.cpp b/lib-apps-common/src/Ui/ProcessPopup.cpp new file mode 100644 index 0000000..65dee29 --- /dev/null +++ b/lib-apps-common/src/Ui/ProcessPopup.cpp @@ -0,0 +1,116 @@ +/* + * Copyright 2016 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.1 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://floralicense.org/license/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "Ui/ProcessPopup.h" +#include "Ui/Window.h" + +#include "App/Path.h" +#include "Utils/Callback.h" +#include "AppsCommonPopup.h" + +using namespace Ui; + +ProcessPopup::ProcessPopup(Size size, double showDelayTime, double showMinTime) + : m_Size(size), m_Layout(nullptr), + m_ShowDelayTimer(nullptr), m_ShowMinTimer(nullptr), + m_IsDestroyPending(false) +{ + m_ShowDelayTimer = ecore_timer_add(showDelayTime, + makeCallback(&ProcessPopup::onShowDelayElapsed), this); + ecore_timer_freeze(m_ShowDelayTimer); + m_ShowMinTimer = ecore_timer_add(showMinTime, + makeCallback(&ProcessPopup::onShowMinElapsed), this); + ecore_timer_freeze(m_ShowMinTimer); + + setCancelCallback([this] { + return false; + }); +} + +ProcessPopup::~ProcessPopup() +{ + ecore_timer_del(m_ShowDelayTimer); + ecore_timer_del(m_ShowMinTimer); +} + +ProcessPopup *ProcessPopup::create(Evas_Object *parent, const char *text, Size size) +{ + ProcessPopup *popup = new ProcessPopup(size); + popup->create(parent); + popup->setText(text); + return popup; +} + +void ProcessPopup::setText(const char *text) +{ + elm_object_translatable_part_text_set(m_Layout, "elm.text", text); +} + +void ProcessPopup::close() +{ + if (m_ShowDelayTimer) { + delete this; + } else if (m_ShowMinTimer) { + m_IsDestroyPending = true; + } else { + Popup::close(); + } +} + +Evas_Object *ProcessPopup::onCreate(Evas_Object *parent) +{ + static struct { + const char *layout; + const char *progress; + } styles[] = { + /* SizeSmall = */ { LAYOUT_PROCESS_SMALL, "process_small" }, + /* SizeMedium = */ { LAYOUT_PROCESS_MEDIUM, "process_medium" } + }; + + Evas_Object *popup = Popup::onCreate(parent); + auto &style = styles[m_Size]; + + m_Layout = elm_layout_add(popup); + elm_layout_file_set(m_Layout, App::getResourcePath(APPS_COMMON_POPUP_EDJ).c_str(), style.layout); + elm_object_content_set(popup, m_Layout); + + Evas_Object *progressbar = elm_progressbar_add(m_Layout); + elm_object_style_set(progressbar, style.progress); + elm_progressbar_pulse_set(progressbar, EINA_TRUE); + elm_progressbar_pulse(progressbar, EINA_TRUE); + elm_object_content_set(m_Layout, progressbar); + + ecore_timer_thaw(m_ShowDelayTimer); + return popup; +} + +Eina_Bool ProcessPopup::onShowDelayElapsed() +{ + evas_object_show(getEvasObject()); + ecore_timer_thaw(m_ShowMinTimer); + + m_ShowDelayTimer = nullptr; + return EINA_FALSE; +} + +Eina_Bool ProcessPopup::onShowMinElapsed() +{ + m_ShowMinTimer = nullptr; + if (m_IsDestroyPending) { + Popup::close(); + } + return EINA_FALSE; +} diff --git a/lib-apps-common/src/Ui/ProgressController.cpp b/lib-apps-common/src/Ui/ProgressController.cpp new file mode 100644 index 0000000..b610506 --- /dev/null +++ b/lib-apps-common/src/Ui/ProgressController.cpp @@ -0,0 +1,151 @@ +/* + * Copyright 2016 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.1 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://floralicense.org/license/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +#include "Ui/ProgressController.h" +#include "Ui/ProgressPopup.h" +#include "Utils/Logger.h" + +#define PROGRESS_VALUE_LIMIT 10 + +using namespace Ui; + +ProgressController::ProgressController(Evas_Object *parent, const char *title, int maxValue) + : m_IsPopupUpdating(false), + m_MainThread(nullptr), m_Thread(nullptr), + m_ProgressPopup(nullptr), m_CancelButton(nullptr) +{ + createProgressPopup(parent, title, maxValue); +} + +ProgressController::~ProgressController() +{ + m_ProgressPopup->close(); +} + +void ProgressController::run() +{ + m_MainThread = ecore_thread_feedback_run(onStart, onNotify, onFinish, onCanceled, this, EINA_FALSE); + + if (m_ProgressPopup->getMaxValue() > PROGRESS_VALUE_LIMIT) { + m_ProgressPopup->show(); + } +} + +void ProgressController::setFinishCallback(FinishCallback callback) +{ + m_OnFinish = std::move(callback); +} + +void ProgressController::setCancelCallback(CancelCallback callback) +{ + m_OnCancel = std::move(callback); +} + +bool ProgressController::onCancel() +{ + return true; +} + +void ProgressController::cancel() +{ + ecore_thread_cancel(m_MainThread); + elm_object_disabled_set(m_CancelButton, EINA_TRUE); +} + +bool ProgressController::onProgress(size_t value) +{ + ecore_thread_feedback(m_Thread, (void *)value); + m_IsPopupUpdating = true; + + std::mutex condVariableMutex; + std::unique_lock locker(condVariableMutex); + m_ContinueCondition.wait(locker, [this]{ + return !m_IsPopupUpdating; + }); + + return !ecore_thread_check(m_Thread); +} + +void ProgressController::setTotalCount(size_t value) +{ + m_ProgressPopup->setMaxValue(value); +} + +void ProgressController::createProgressPopup(Evas_Object *parent, const char *title, int maxValue) +{ + m_ProgressPopup = new Ui::ProgressPopup(maxValue); + RETM_IF(!m_ProgressPopup, "m_ProgressPopup is NULL"); + + m_ProgressPopup->create(parent); + m_ProgressPopup->setTitle(title); + + m_CancelButton = m_ProgressPopup->addButton("IDS_PB_BUTTON_CANCEL"); + m_ProgressPopup->setCancelCallback([this] { + if (!ecore_thread_check(m_MainThread)) { + if (onCancel()) { + cancel(); + } + } + return false; + }); +} + +void ProgressController::onStart(void *data, Ecore_Thread *thread) +{ + RETM_IF(!data, "invalid data"); + + ProgressController *controller = (ProgressController *)data; + controller->m_Thread = thread; + controller->onStart(); +} + +void ProgressController::onNotify(void *data, Ecore_Thread *thread, void *msgData) +{ + RETM_IF(!data || !msgData, "invalid data"); + ProgressController *controller = (ProgressController *)data; + + if (!ecore_thread_check(thread)) { + controller->m_ProgressPopup->setProgress((size_t)msgData); + } + + controller->m_IsPopupUpdating = false; + controller->m_ContinueCondition.notify_one(); +} + +void ProgressController::onFinish(void *data, Ecore_Thread *thread) +{ + RETM_IF(!data, "invalid data"); + ProgressController *controller = (ProgressController *)data; + if (controller->m_OnFinish) { + controller->m_OnFinish(); + } + + delete controller; +} + +void ProgressController::onCanceled(void *data, Ecore_Thread *thread) +{ + RETM_IF(!data, "invalid data"); + ProgressController *controller = (ProgressController *)data; + controller->onCanceled(); + + if (controller->m_OnCancel) { + controller->m_OnCancel(); + } + + delete controller; +} diff --git a/lib-apps-common/src/Ui/ProgressPopup.cpp b/lib-apps-common/src/Ui/ProgressPopup.cpp new file mode 100644 index 0000000..2fef52a --- /dev/null +++ b/lib-apps-common/src/Ui/ProgressPopup.cpp @@ -0,0 +1,89 @@ +/* + * Copyright 2016 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.1 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://floralicense.org/license/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "App/Path.h" +#include "Ui/ProgressPopup.h" +#include "Utils/Logger.h" + +#include "AppsCommonPopup.h" + +#define BUFFER_SIZE 64 + +#define ZERO_PROGRESS "0%" + +using namespace Ui; + +namespace +{ + const std::string layoutFilePath = App::getResourcePath(APPS_COMMON_POPUP_EDJ); +} + +ProgressPopup::ProgressPopup(size_t maxValue) + : m_CurrentValue(0), m_MaxValue(maxValue), m_Progressbar(nullptr) +{ +} + +void ProgressPopup::setProgress(size_t value) +{ + RETM_IF(value > m_MaxValue, "value is bigger than max value"); + m_CurrentValue = value; + double progressValue = (double)value / m_MaxValue; + + char progress[BUFFER_SIZE] = { 0, }; + snprintf(progress, sizeof(progress), "%d%%", (int)(100.0 * progressValue)); + + elm_progressbar_value_set(m_Progressbar, progressValue); + elm_object_part_text_set(m_Progressbar, "elm.text.bottom.left", progress); + + updateTotalText(); +} + +void ProgressPopup::setMaxValue(size_t maxValue) +{ + m_MaxValue = maxValue; + updateTotalText(); +} + +size_t ProgressPopup::getMaxValue() const +{ + return m_MaxValue; +} + +Evas_Object *ProgressPopup::onCreate(Evas_Object *parent) +{ + Evas_Object *popup = Popup::onCreate(parent); + + Evas_Object *layout = elm_layout_add(popup); + elm_layout_file_set(layout, layoutFilePath.c_str(), LAYOUT_PROGRESS); + + m_Progressbar = elm_progressbar_add(layout); + elm_progressbar_pulse(m_Progressbar, EINA_TRUE); + + elm_object_part_text_set(m_Progressbar, "elm.text.bottom.left", ZERO_PROGRESS); + updateTotalText(); + + elm_object_content_set(layout, m_Progressbar); + elm_object_content_set(popup, layout); + + return popup; +} + +void ProgressPopup::updateTotalText() +{ + char total[BUFFER_SIZE] = { 0, }; + snprintf(total, sizeof(total), "%zu/%zu", m_CurrentValue, m_MaxValue); + elm_object_part_text_set(m_Progressbar, "elm.text.bottom.right", total); +} diff --git a/lib-apps-common/src/Ui/RadioPopup.cpp b/lib-apps-common/src/Ui/RadioPopup.cpp new file mode 100644 index 0000000..9f52882 --- /dev/null +++ b/lib-apps-common/src/Ui/RadioPopup.cpp @@ -0,0 +1,57 @@ +/* + * Copyright 2016 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.1 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://floralicense.org/license/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "Ui/RadioPopup.h" + +using namespace Ui; + +RadioPopup::RadioPopup() + : m_RadioGroup(nullptr) +{ +} + +void RadioPopup::setSelectedItem(int value) +{ + elm_radio_value_set(m_RadioGroup, value); +} + +Evas_Object *RadioPopup::onCreate(Evas_Object *parent) +{ + Evas_Object *popup = ListPopup::onCreate(parent); + + m_RadioGroup = elm_radio_add(popup); + elm_radio_state_value_set(m_RadioGroup, -1); + + return popup; +} + +Evas_Object *RadioPopup::getItemContent(void *data, const char *part) +{ + if (strcmp(part, "elm.swallow.end") == 0) { + Evas_Object *radio = elm_radio_add(getEvasObject()); + elm_radio_group_add(radio, m_RadioGroup); + elm_radio_state_value_set(radio, (long) data); + elm_object_signal_emit(radio, "elm,event,pass,enabled", "elm"); + return radio; + } + + return nullptr; +} + +void RadioPopup::onItemSelected(void *data) +{ + setSelectedItem((long) data); +} diff --git a/lib-apps-common/src/Ui/Scale.cpp b/lib-apps-common/src/Ui/Scale.cpp new file mode 100644 index 0000000..0d2f1dd --- /dev/null +++ b/lib-apps-common/src/Ui/Scale.cpp @@ -0,0 +1,25 @@ +/* + * Copyright 2016 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.1 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://floralicense.org/license/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "Ui/Scale.h" + +#include + +int Ui::getScaledValue(int value) +{ + static double factor = elm_config_scale_get() / elm_app_base_scale_get(); + return round(value * factor); +} diff --git a/lib-apps-common/src/Ui/ScrollNavigator.cpp b/lib-apps-common/src/Ui/ScrollNavigator.cpp new file mode 100644 index 0000000..0c0a832 --- /dev/null +++ b/lib-apps-common/src/Ui/ScrollNavigator.cpp @@ -0,0 +1,131 @@ +/* + * Copyright 2016 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.1 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://floralicense.org/license/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "Ui/ScrollNavigator.h" +#include "Ui/ScrollPage.h" +#include "Ui/Selector.h" +#include "Utils/Callback.h" + +using namespace Ui; + +ScrollNavigator::ScrollNavigator(Selector *selector) + : TabNavigator(selector), + m_Scroller(nullptr), m_Box(nullptr), + m_Width(0), m_Height(0), + m_IsNavigationEnabled(true) +{ +} + +void ScrollNavigator::setNavigationEnabled(bool isEnabled) +{ + m_IsNavigationEnabled = isEnabled; + getSelector()->setSelectEnabled(isEnabled); + elm_scroller_movement_block_set(getEvasObject(), + isEnabled ? ELM_SCROLLER_MOVEMENT_NO_BLOCK : ELM_SCROLLER_MOVEMENT_BLOCK_HORIZONTAL); +} + +Evas_Object *ScrollNavigator::onCreate(Evas_Object *parent) +{ + m_Scroller = elm_scroller_add(parent); + elm_scroller_page_relative_set(m_Scroller, 1.0, 0.0); + elm_scroller_page_scroll_limit_set(m_Scroller, 1, 0); + elm_scroller_loop_set(m_Scroller, EINA_FALSE, EINA_FALSE); + elm_scroller_policy_set(m_Scroller, ELM_SCROLLER_POLICY_OFF, ELM_SCROLLER_POLICY_OFF); + elm_object_scroll_lock_y_set(m_Scroller, EINA_TRUE); + + evas_object_event_callback_add(m_Scroller, EVAS_CALLBACK_RESIZE, + makeCallback(&ScrollNavigator::onResize), this); + evas_object_smart_callback_add(m_Scroller, "scroll,page,changed", + makeCallback(&ScrollNavigator::onPageChanged), this); + + m_Box = elm_box_add(m_Scroller); + elm_box_horizontal_set(m_Box, EINA_TRUE); + elm_object_content_set(m_Scroller, m_Box); + + return m_Scroller; +} + +ScrollPage *ScrollNavigator::addPage(View *view) +{ + auto page = static_cast(TabNavigator::addPage(view)); + evas_object_size_hint_min_set(page->m_Sizer, m_Width, m_Height); + elm_box_pack_end(m_Box, page->getEvasObject()); + evas_object_show(page->getEvasObject()); + return page; +} + +ScrollPage *ScrollNavigator::createPage(View *view, Elm_Object_Item *item) +{ + return new ScrollPage(item); +} + +void ScrollNavigator::changePage(TabPage *page) +{ + size_t pageIndex = getPageIndex(page); + size_t currentIndex = 0; + elm_scroller_current_page_get(m_Scroller, (int *) ¤tIndex, nullptr); + + if (currentIndex != pageIndex) { + elm_scroller_page_show(m_Scroller, pageIndex, 0); + } +} + +size_t ScrollNavigator::getPageIndex(TabPage *page) const +{ + Eina_List *list = elm_box_children_get(m_Box); + size_t index = eina_list_data_idx(list, page->getEvasObject()); + eina_list_free(list); + return index; +} + +TabPage *ScrollNavigator::getPageByIndex(size_t index) const +{ + Eina_List *list = elm_box_children_get(m_Box); + + Evas_Object *obj = (Evas_Object *) eina_list_nth(list, index); + eina_list_free(list); + return static_cast(Control::getControl(obj)); +} + +void ScrollNavigator::onPageChanged(Evas_Object *obj, void *eventInfo) +{ + /* Page count might be invalid until scroller is properly resized, + so we cannot reliably use page index at that point */ + size_t count = 0; + elm_scroller_last_page_get(m_Scroller, (int *) &count, nullptr); + if (count + 1 != getPages().size()) { + return; + } + + size_t index = 0; + elm_scroller_current_page_get(m_Scroller, (int *) &index, nullptr); + if (auto page = getPageByIndex(index)) { + navigateTo(page->getView()); + } +} + +void ScrollNavigator::onResize(Evas *e, Evas_Object *obj, void *eventInfo) +{ + evas_object_geometry_get(obj, nullptr, nullptr, &m_Width, &m_Height); + for (auto &&page : getPages()) { + auto scrollPage = static_cast(page); + evas_object_size_hint_min_set(scrollPage->m_Sizer, m_Width, m_Height); + } + + if (auto page = static_cast(getCurrentPage())) { + elm_scroller_page_show(m_Scroller, getPageIndex(page), 0); + } +} diff --git a/lib-apps-common/src/Ui/ScrollPage.cpp b/lib-apps-common/src/Ui/ScrollPage.cpp new file mode 100644 index 0000000..ed22760 --- /dev/null +++ b/lib-apps-common/src/Ui/ScrollPage.cpp @@ -0,0 +1,45 @@ +/* + * Copyright 2016 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.1 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://floralicense.org/license/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "Ui/ScrollPage.h" +#include "Ui/ScrollNavigator.h" + +using namespace Ui; + +ScrollPage::ScrollPage(Elm_Object_Item *tabItem) + : TabPage(tabItem), m_Sizer(nullptr) +{ +} + +Evas_Object *ScrollPage::onCreate(Evas_Object *parent) +{ + m_Sizer = evas_object_rectangle_add(evas_object_evas_get(parent)); + evas_object_color_set(m_Sizer, 0, 0, 0, 0); + + Evas_Object *layout = elm_layout_add(parent); + elm_layout_theme_set(layout, "layout", "application", "default"); + elm_object_part_content_set(layout, "elm.swallow.bg", m_Sizer); + elm_object_part_content_set(layout, "elm.swallow.content", TabPage::onCreate(layout)); + + return layout; +} + +void ScrollPage::setExpanded(bool isExpanded) +{ + auto navigator = static_cast(getNavigator()); + navigator->setNavigationEnabled(!isExpanded); + NavigatorPage::setExpanded(isExpanded); +} diff --git a/lib-apps-common/src/Ui/Selector.cpp b/lib-apps-common/src/Ui/Selector.cpp new file mode 100644 index 0000000..ab02ba7 --- /dev/null +++ b/lib-apps-common/src/Ui/Selector.cpp @@ -0,0 +1,35 @@ +/* + * Copyright 2016 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.1 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://floralicense.org/license/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "Ui/Selector.h" + +using namespace Ui; + +void Selector::setSelectEnabled(bool isEnabled) +{ + elm_object_disabled_set(getEvasObject(), !isEnabled); +} + +void Selector::setSelectCallback(SelectCallback callback) +{ + m_OnSelected = std::move(callback); +} + +bool Selector::onSelected(Elm_Object_Item *item) +{ + void *data = elm_object_item_data_get(item); + return !m_OnSelected || m_OnSelected(data); +} diff --git a/lib-apps-common/src/Ui/TabNavigator.cpp b/lib-apps-common/src/Ui/TabNavigator.cpp new file mode 100644 index 0000000..d776654 --- /dev/null +++ b/lib-apps-common/src/Ui/TabNavigator.cpp @@ -0,0 +1,121 @@ +/* + * Copyright 2016 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.1 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://floralicense.org/license/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "Ui/TabNavigator.h" +#include "Ui/TabPage.h" +#include "Ui/Tabbar.h" +#include "Utils/Logger.h" + +#include + +using namespace Ui; +using namespace std::placeholders; + +TabNavigator::TabNavigator(Selector *selector) + : m_Selector(selector) +{ + if (m_Selector) { + m_Selector->setSelectCallback(std::bind(&TabNavigator::onSelected, this, _1)); + } +} + +Evas_Object *TabNavigator::onCreate(Evas_Object *parent) +{ + Evas_Object *layout = elm_layout_add(parent); + elm_layout_theme_set(layout, "layout", "application", "default"); + return layout; +} + +void TabNavigator::onPageAttached(NavigatorPage *page) +{ + page->setStyle("tabbar/notitle"); + if (m_Selector) { + page->setContent("tabbar", m_Selector->create(getEvasObject())); + } +} + +Selector *TabNavigator::getSelector() const +{ + return m_Selector; +} + +const TabNavigator::Pages &TabNavigator::getPages() const +{ + return m_Pages; +} + +TabPage *TabNavigator::addPage(View *view) +{ + TabPage *page = createPage(view, m_Selector ? m_Selector->addItem(nullptr) : nullptr); + m_Pages.push_back(page); + + Evas_Object *layout = page->create(getEvasObject()); + page->setContent("elm.swallow.content", view->create(layout)); + + return page; +} + +bool TabNavigator::removePage(NavigatorPage *page) +{ + if (m_Pages.size() == 1) { + return false; + } + + auto it = std::find(m_Pages.begin(), m_Pages.end(), page); + if (page == getCurrentPage()) { + if (page != m_Pages.back()) { + navigateTo((*++it)->getView()); + } else if (page != m_Pages.front()) { + navigateTo((*--it)->getView()); + } + } + + m_Pages.erase(it); + delete page; + return true; +} + +void TabNavigator::navigateToPage(NavigatorPage *page) +{ + TabPage *tabPage = static_cast(page); + setCurrentPage(tabPage); + changePage(tabPage); + + if (m_Selector) { + m_Selector->setSelectedItem(tabPage->getTabItem()); + } +} + +TabPage *TabNavigator::createPage(View *view, Elm_Object_Item *item) +{ + return new TabPage(item); +} + +void TabNavigator::changePage(TabPage *page) +{ + evas_object_hide(elm_object_content_unset(getEvasObject())); + elm_object_content_set(getEvasObject(), page->getEvasObject()); +} + +bool TabNavigator::onSelected(void *data) +{ + TabPage *page = (TabPage *) data; + if (page) { + navigateTo(page->getView()); + } + + return true; +} diff --git a/lib-apps-common/src/Ui/TabPage.cpp b/lib-apps-common/src/Ui/TabPage.cpp new file mode 100644 index 0000000..3678e08 --- /dev/null +++ b/lib-apps-common/src/Ui/TabPage.cpp @@ -0,0 +1,100 @@ +/* + * Copyright 2016 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.1 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://floralicense.org/license/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "Ui/TabPage.h" +#include "Utils/Callback.h" + +#define BUFFER_SIZE 64 + +using namespace Ui; + +TabPage::TabPage(Elm_Object_Item *tabItem) + : m_TabItem(tabItem), m_Page(nullptr), m_HasTabTitle(false) +{ + elm_object_item_data_set(tabItem, this); + elm_object_item_del_cb_set(tabItem, makeCallback(&TabPage::onTabItemDestroy)); +} + +TabPage::~TabPage() +{ + elm_object_item_del(m_TabItem); +} + +void TabPage::setTabTitle(const char *title) +{ + elm_object_item_translatable_text_set(m_TabItem, title); + m_HasTabTitle = true; +} + +void TabPage::unsetTabTitle() +{ + const char *title = elm_object_translatable_part_text_get(m_Page, "elm.text.title"); + elm_object_item_translatable_text_set(m_TabItem, title); + m_HasTabTitle = false; +} + +void TabPage::setTitle(const char *title) +{ + if (!m_HasTabTitle) { + elm_object_item_translatable_text_set(m_TabItem, title); + } + elm_object_translatable_part_text_set(m_Page, "elm.text.title", title); +} + +void TabPage::setSubtitle(const char *subtitle) +{ + elm_object_translatable_part_text_set(m_Page, "elm.text.subtitle", subtitle); +} + +void TabPage::setTitleVisibility(bool isVisible) +{ + elm_layout_signal_emit(m_Page, isVisible ? "elm,state,title,show" : "elm,state,title,hide", "elm"); +} + +void TabPage::setStyle(const char *style) +{ + char buffer[BUFFER_SIZE]; + snprintf(buffer, sizeof(buffer), "%s/default", style); + elm_layout_theme_set(m_Page, "naviframe", "item", buffer); +} + +void TabPage::setContent(const char *part, Evas_Object *content) +{ + char buffer[BUFFER_SIZE]; + snprintf(buffer, sizeof(buffer), "elm,state,%s,%s", part, content ? "show" : "hide"); + elm_layout_signal_emit(m_Page, buffer, "elm"); + elm_object_part_content_set(m_Page, part, content); +} + +Elm_Object_Item *TabPage::getTabItem() const +{ + return m_TabItem; +} + +Evas_Object *TabPage::onCreate(Evas_Object *parent) +{ + m_Page = elm_layout_add(parent); + elm_layout_theme_set(m_Page, "naviframe", "item", "basic/default"); + elm_layout_signal_emit(m_Page, "elm,state,title,hide", "elm"); + elm_layout_signal_emit(m_Page, "elm,state,toolbar,hide", "elm"); + + return m_Page; +} + +void TabPage::onTabItemDestroy(Evas_Object *obj, void *eventInfo) +{ + m_TabItem = nullptr; +} diff --git a/lib-apps-common/src/Ui/Tabbar.cpp b/lib-apps-common/src/Ui/Tabbar.cpp new file mode 100644 index 0000000..6be14f1 --- /dev/null +++ b/lib-apps-common/src/Ui/Tabbar.cpp @@ -0,0 +1,52 @@ +/* + * Copyright 2016 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.1 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://floralicense.org/license/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "Ui/Tabbar.h" +#include "Utils/Callback.h" + +using namespace Ui; + +Elm_Object_Item *Tabbar::addItem(void *data) +{ + return elm_toolbar_item_append(getEvasObject(), nullptr, nullptr, nullptr, data); +} + +void Tabbar::setSelectEnabled(bool isEnabled) +{ + elm_toolbar_select_mode_set(getEvasObject(), + isEnabled ? ELM_OBJECT_SELECT_MODE_ALWAYS : ELM_OBJECT_SELECT_MODE_NONE); +} + +void Tabbar::setSelectedItem(Elm_Object_Item *item) +{ + elm_toolbar_item_selected_set(item, EINA_TRUE); +} + +Evas_Object *Tabbar::onCreate(Evas_Object *parent) +{ + Evas_Object *tabbar = elm_toolbar_add(parent); + elm_toolbar_shrink_mode_set(tabbar, ELM_TOOLBAR_SHRINK_EXPAND); + elm_toolbar_select_mode_set(tabbar, ELM_OBJECT_SELECT_MODE_ALWAYS); + elm_toolbar_transverse_expanded_set(tabbar, EINA_TRUE); + evas_object_smart_callback_add(tabbar, "selected", + (Evas_Smart_Cb) makeCallback(&Tabbar::onSelected), this); + return tabbar; +} + +void Tabbar::onSelected(Evas_Object *tabbar, Elm_Object_Item *item) +{ + Selector::onSelected(item); +} diff --git a/lib-apps-common/src/Ui/Thumbnail.cpp b/lib-apps-common/src/Ui/Thumbnail.cpp new file mode 100644 index 0000000..b2cf883 --- /dev/null +++ b/lib-apps-common/src/Ui/Thumbnail.cpp @@ -0,0 +1,90 @@ +/* + * Copyright 2016 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.1 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://floralicense.org/license/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "Ui/Thumbnail.h" +#include "Ui/Scale.h" + +#include "App/Path.h" +#include "AppsCommonThumbnail.h" + +using namespace Ui; + +namespace +{ + const struct + { + int size; + const char *groupMask; + const char *groupDefault; + } params[] = { + { THUMBNAIL_SMALL_SIZE, LAYOUT_THUMBNAIL_SMALL, LAYOUT_THUMBNAIL_DEFAULT_SMALL }, + { THUMBNAIL_MEDIUM_SIZE, LAYOUT_THUMBNAIL_MEDIUM, LAYOUT_THUMBNAIL_DEFAULT_MEDIUM }, + { THUMBNAIL_LARGE_SIZE, LAYOUT_THUMBNAIL_LARGE, LAYOUT_THUMBNAIL_DEFAULT_LARGE } + }; + + const std::string layoutPath = App::getResourcePath(APPS_COMMON_THUMBNAIL_EDJ); +} + +Thumbnail::Thumbnail(Size size) + : m_Size(size), m_Image(nullptr) +{ +} + +Thumbnail *Thumbnail::create(Evas_Object *parent, Size size, const char *path) +{ + Thumbnail *thumbnail = new Thumbnail(size); + thumbnail->create(parent); + thumbnail->setImagePath(path); + return thumbnail; +} + +Evas_Object *Thumbnail::getImage() const +{ + return m_Image; +} + +void Thumbnail::setImagePath(const char *path) +{ + if (path && *path) { + elm_image_file_set(m_Image, path, nullptr); + } else { + elm_image_file_set(m_Image, layoutPath.c_str(), params[m_Size].groupDefault); + } +} + +void Thumbnail::setSizeHint(bool isSet) +{ + int size = 0; + if (isSet) { + size = getScaledValue(params[m_Size].size); + } + + evas_object_size_hint_min_set(m_Image, size, size); +} + +Evas_Object *Thumbnail::onCreate(Evas_Object *parent) +{ + Evas_Object *layout = elm_layout_add(parent); + elm_layout_file_set(layout, layoutPath.c_str(), params[m_Size].groupMask); + + m_Image = elm_image_add(layout); + elm_image_prescale_set(m_Image, getScaledValue(params[m_Size].size) * 2); + elm_image_aspect_fixed_set(m_Image, EINA_TRUE); + elm_image_fill_outside_set(m_Image, EINA_TRUE); + elm_object_part_content_set(layout, "elm.swallow.content", m_Image); + + return layout; +} diff --git a/lib-apps-common/src/Ui/View.cpp b/lib-apps-common/src/Ui/View.cpp new file mode 100644 index 0000000..0d48579 --- /dev/null +++ b/lib-apps-common/src/Ui/View.cpp @@ -0,0 +1,73 @@ +/* + * Copyright 2016 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.1 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://floralicense.org/license/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "Ui/View.h" +#include "Ui/Navigator.h" + +using namespace Ui; + +View::View() + : m_Page(nullptr), + m_IsCurrent(false), m_Rotation(-1) +{ +} + +Navigator *View::getNavigator() const +{ + Evas_Object *parent = elm_object_parent_widget_get(getEvasObject()); + return findParent(parent); +} + +NavigatorPage *View::getPage() const +{ + return m_Page; +} + +bool View::isCurrent() const +{ + return m_IsCurrent; +} + +int View::getRotation() const +{ + return m_Rotation; +} + +void View::onNavigatorAttached(NavigatorPage *page) +{ + m_Page = page; + onPageAttached(m_Page); +} + +void View::onNavigation(bool isCurrent, int degree) +{ + m_IsCurrent = isCurrent; + if (m_IsCurrent) { + resetCreateTimer(); + onRotation(degree); + } + + onNavigation(m_IsCurrent); + evas_object_smart_callback_call(getEvasObject(), EVENT_VIEW_NAVIGATION, (void *) (long) m_IsCurrent); +} + +void View::onRotation(int degree) +{ + if (m_Rotation != degree) { + m_Rotation = degree; + onRotationChanged(degree); + } +} diff --git a/lib-apps-common/src/Ui/Window.cpp b/lib-apps-common/src/Ui/Window.cpp new file mode 100644 index 0000000..618af40 --- /dev/null +++ b/lib-apps-common/src/Ui/Window.cpp @@ -0,0 +1,146 @@ +/* + * Copyright 2016 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.1 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://floralicense.org/license/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "Ui/Window.h" +#include "Ui/View.h" +#include "Utils/Callback.h" +#include "Utils/Range.h" + +#include + +using namespace Ui; + +namespace Ui +{ + template <> + Window *Control::findParent(Evas_Object *object) + { + return getControl(elm_object_top_widget_get(object)); + } +} + +Window::Window() + : m_Conform(nullptr), m_Layout(nullptr), m_MainView(nullptr) +{ +} + +Evas_Object *Window::getConformant() const +{ + return m_Conform; +} + +Evas_Object *Window::getBaseLayout() const +{ + return m_Layout; +} + +void Window::setRotationEnabled(bool isEnabled) +{ + if (isEnabled) { + int rotations[] = { 0, 90, 180, 270 }; + elm_win_wm_rotation_available_rotations_set(getEvasObject(), rotations, Utils::count(rotations)); + } else { + int rotations[] = { 0 }; + elm_win_wm_rotation_available_rotations_set(getEvasObject(), rotations, Utils::count(rotations)); + } +} + +void Window::attachView(View *view) +{ + m_MainView = view; + elm_object_part_content_set(m_Layout, "elm.swallow.content", m_MainView->create(m_Layout)); + if (elm_win_focus_get(getEvasObject())) { + m_MainView->onNavigation(true, elm_win_rotation_get(getEvasObject())); + } +} + +Evas_Object *Window::onCreate(Evas_Object *parent) +{ + Evas_Object *window = onWindowCreate(); + + m_Conform = elm_conformant_add(window); + evas_object_size_hint_weight_set(m_Conform, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + elm_win_resize_object_add(window, m_Conform); + evas_object_show(m_Conform); + + m_Layout = elm_layout_add(m_Conform); + elm_layout_theme_set(m_Layout, "layout", "application", "default"); + evas_object_size_hint_weight_set(m_Layout, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + elm_object_content_set(m_Conform, m_Layout); + evas_object_show(m_Layout); + + Evas_Object *bg = elm_bg_add(m_Layout); + evas_object_color_set(bg, 255, 255, 255, 0); + evas_object_show(bg); + elm_object_part_content_set(m_Layout, "elm.swallow.bg", bg); + + evas_object_smart_callback_add(window, "focused", + makeCallback(&Window::onFocused), this); + evas_object_smart_callback_add(window, "unfocused", + makeCallback(&Window::onUnfocused), this); + evas_object_smart_callback_add(window, "rotation,changed", + makeCallback(&Window::onRotationChanged), this); + + eext_object_event_callback_add(m_Layout, EEXT_CALLBACK_BACK, + makeCallback(&Window::onBackPressed), this); + eext_object_event_callback_add(m_Layout, EEXT_CALLBACK_MORE, + makeCallback(&Window::onMenuPressed), this); + + return window; +} + +Evas_Object *Window::onWindowCreate() +{ + Evas_Object *window = elm_win_add(nullptr, nullptr, ELM_WIN_BASIC); + elm_win_indicator_mode_set(window, ELM_WIN_INDICATOR_SHOW); + elm_win_indicator_opacity_set(window, ELM_WIN_INDICATOR_OPAQUE); + elm_win_conformant_set(window, EINA_TRUE); + evas_object_show(window); + return window; +} + +void Window::onFocused(Evas_Object *obj, void *eventInfo) +{ + if (m_MainView) { + m_MainView->onNavigation(true, elm_win_rotation_get(getEvasObject())); + } +} + +void Window::onUnfocused(Evas_Object *obj, void *eventInfo) +{ + if (m_MainView) { + m_MainView->onNavigation(false, elm_win_rotation_get(getEvasObject())); + } +} + +void Window::onRotationChanged(Evas_Object *obj, void *eventInfo) +{ + m_MainView->onRotation(elm_win_rotation_get(obj)); +} + +void Window::onBackPressed(Evas_Object *obj, void *eventInfo) +{ + if (!m_MainView || m_MainView->onBackPressed()) { + elm_win_lower(getEvasObject()); + } +} + +void Window::onMenuPressed(Evas_Object *obj, void *eventInfo) +{ + if (m_MainView) { + m_MainView->onMenuPressed(); + } +} diff --git a/lib-apps-common/src/Utils/EcoreUtils.cpp b/lib-apps-common/src/Utils/EcoreUtils.cpp new file mode 100644 index 0000000..eb5e797 --- /dev/null +++ b/lib-apps-common/src/Utils/EcoreUtils.cpp @@ -0,0 +1,28 @@ +/* + * Copyright 2016 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.1 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://floralicense.org/license/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "Utils/EcoreUtils.h" + +using namespace Utils; + +Ecore_Job *Utils::createJob(Job job) +{ + return ecore_job_add([](void *data) { + Job *job = (Job *) data; + (*job)(); + delete job; + }, new Job(std::move(job))); +} diff --git a/lib-apps-common/src/Utils/Logger.cpp b/lib-apps-common/src/Utils/Logger.cpp new file mode 100644 index 0000000..f66d099 --- /dev/null +++ b/lib-apps-common/src/Utils/Logger.cpp @@ -0,0 +1,30 @@ +/* + * Copyright 2016 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.1 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://floralicense.org/license/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "Utils/Logger.h" +#include + +static char appsCommonLogTag[64] = "DefaultLogTag"; + +void Utils::setLogTag(const char *logTag) +{ + snprintf(appsCommonLogTag, sizeof(appsCommonLogTag), "%s", logTag); +} + +const char *Utils::getLogTag() +{ + return appsCommonLogTag; +} diff --git a/lib-apps-common/src/Utils/Thread.cpp b/lib-apps-common/src/Utils/Thread.cpp new file mode 100644 index 0000000..5ae5de3 --- /dev/null +++ b/lib-apps-common/src/Utils/Thread.cpp @@ -0,0 +1,49 @@ +/* + * Copyright 2016 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.1 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://floralicense.org/license/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "Utils/Thread.h" +#include "Utils/Callback.h" + +using namespace Utils; + + +Thread::Thread(Callback callbackPair) + : m_Callback(std::move(callbackPair)) +{ + ecore_thread_run(makeCallback(&Thread::onStart), makeCallback(&Thread::onFinished), + nullptr, this); +} + +Thread::Thread(Callback task, Callback finishCallback) + : Thread(CallbackPair(std::move(task), std::move(finishCallback))) +{ +} + +void Thread::onStart(Ecore_Thread *thread) +{ + if (m_Callback) { + m_Callback(); + } +} + +void Thread::onFinished(Ecore_Thread *thread) +{ + if (m_Callback) { + m_Callback(); + } + + delete this; +} diff --git a/lib-apps-common/src/Utils/Tracer.cpp b/lib-apps-common/src/Utils/Tracer.cpp new file mode 100644 index 0000000..a6dc590 --- /dev/null +++ b/lib-apps-common/src/Utils/Tracer.cpp @@ -0,0 +1,52 @@ +/* + * Copyright 2016 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.1 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://floralicense.org/license/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "Utils/Tracer.h" +#include + +using namespace Utils; + +void subtractTime(const timespec &a, const timespec &b, timespec &res) +{ + static const size_t ratio(1000000000); + + res.tv_sec = b.tv_sec - a.tv_sec; + res.tv_nsec = b.tv_nsec - a.tv_nsec; + if (res.tv_nsec < 0) + { + --res.tv_sec; + res.tv_nsec += ratio; + } +} + +Tracer::Tracer(const char *tag, const char *file, const char *func, int line) + : m_Tag(tag), m_File(file), m_Func(func) +{ + dlog_print(DLOG_DEBUG, m_Tag, "%s: %s(%d) <<< called", m_File, m_Func, line); + clock_gettime(CLOCK_REALTIME, &m_startTime); +} + +Tracer::~Tracer() +{ + timespec endTime; + clock_gettime(CLOCK_REALTIME, &endTime); + + timespec res; + subtractTime(m_startTime, endTime, res); + + dlog_print(DLOG_DEBUG, m_Tag, "%s: %s >>> returned in %d.%03d seconds", + m_File, m_Func, res.tv_sec, res.tv_nsec / 1000000); +} diff --git a/lib-apps-common/src/Ux/DatePopup.cpp b/lib-apps-common/src/Ux/DatePopup.cpp new file mode 100644 index 0000000..ade9c52 --- /dev/null +++ b/lib-apps-common/src/Ux/DatePopup.cpp @@ -0,0 +1,62 @@ +/* + * Copyright 2016 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.1 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://floralicense.org/license/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "Ux/DatePopup.h" + +using namespace Ux; + +DatePopup::DatePopup(const char *format, tm date) + : m_Format(format ? format : ""), m_Date(date), + m_DatePicker(nullptr), m_Strings{ nullptr } +{ +} + +void DatePopup::setStrings(Strings strings) +{ + m_Strings = strings; +} + +void DatePopup::setResultCallback(ResultCallback callback) +{ + m_OnResult = std::move(callback); +} + +Evas_Object *DatePopup::getDatePicker() const +{ + return m_DatePicker; +} + +void DatePopup::onCreated() +{ + setTitle(m_Strings.popupTitle); + addButton(m_Strings.buttonCancel); + addButton(m_Strings.buttonDone, std::bind(&DatePopup::onDonePressed, this)); + + m_DatePicker = elm_datetime_add(getEvasObject()); + elm_datetime_format_set(m_DatePicker, m_Format.c_str()); + elm_datetime_value_set(m_DatePicker, &m_Date); + setContent(m_DatePicker); +} + +bool DatePopup::onDonePressed() +{ + if (m_OnResult) { + elm_datetime_value_get(m_DatePicker, &m_Date); + m_OnResult(m_Date); + } + + return true; +} diff --git a/lib-apps-common/src/Ux/EditfieldPopup.cpp b/lib-apps-common/src/Ux/EditfieldPopup.cpp new file mode 100644 index 0000000..47395e8 --- /dev/null +++ b/lib-apps-common/src/Ux/EditfieldPopup.cpp @@ -0,0 +1,94 @@ +/* + * Copyright 2016 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.1 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://floralicense.org/license/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "Ux/EditfieldPopup.h" +#include "Ui/Editfield.h" +#include "Utils/Callback.h" +#include "Utils/String.h" + +using namespace Ui; +using namespace Ux; + +EditfieldPopup::EditfieldPopup() + : m_Editfield(nullptr), m_Strings{ nullptr } +{ +} + +void EditfieldPopup::setStrings(Strings strings) +{ + m_Strings = strings; +} + +void EditfieldPopup::setResultCallback(ResultCallback callback) +{ + m_OnResult = std::move(callback); +} + +Editfield *EditfieldPopup::getEditfield() const +{ + return m_Editfield; +} + +void EditfieldPopup::onCreated() +{ + m_Editfield = Editfield::create(getEvasObject(), m_Strings.guideText); + m_Editfield->setLimitToastText(m_Strings.limitToastText); + + setTitle(m_Strings.popupTitle); + setContent(m_Editfield->getEvasObject()); + addButton(m_Strings.buttonCancel); + + Evas_Object *button = addButton(m_Strings.buttonDone, std::bind(&EditfieldPopup::onDoneButtonPressed, this)); + elm_object_focus_allow_set(button, EINA_FALSE); + + Evas_Object *entry = m_Editfield->getEntry(); + elm_entry_input_panel_return_key_type_set(entry, ELM_INPUT_PANEL_RETURN_KEY_TYPE_DONE); + elm_entry_input_panel_return_key_disabled_set(entry, EINA_TRUE); + + evas_object_smart_callback_add(entry, "changed", + (Evas_Smart_Cb) &EditfieldPopup::onEntryChanged, button); + evas_object_smart_callback_add(entry, "activated", + makeCallback(&EditfieldPopup::onDoneKeyPressed), this); + + elm_object_disabled_set(button, EINA_TRUE); + elm_object_focus_set(entry, EINA_TRUE); +} + +bool EditfieldPopup::onDoneButtonPressed() +{ + bool shouldClose = true; + if (m_OnResult) { + char *text = elm_entry_markup_to_utf8(elm_entry_entry_get(m_Editfield->getEntry())); + shouldClose = m_OnResult(text); + free(text); + } + + return shouldClose; +} + +void EditfieldPopup::onDoneKeyPressed(Evas_Object *entry, void *eventInfo) +{ + if (onDoneButtonPressed()) { + close(); + } +} + +void EditfieldPopup::onEntryChanged(Evas_Object *button, Evas_Object *entry, void *eventInfo) +{ + bool isEmpty = Utils::isStrEmpty(elm_entry_entry_get(entry)); + elm_object_disabled_set(button, isEmpty); + elm_entry_input_panel_return_key_disabled_set(entry, isEmpty); +} diff --git a/lib-apps-common/src/Ux/SelectAllItem.cpp b/lib-apps-common/src/Ux/SelectAllItem.cpp new file mode 100644 index 0000000..dac3a3a --- /dev/null +++ b/lib-apps-common/src/Ux/SelectAllItem.cpp @@ -0,0 +1,59 @@ +/* + * Copyright 2016 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.1 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://floralicense.org/license/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "Ux/SelectAllItem.h" +#include + +#define TEXT_COLOR 61, 185, 204, 255 + +using namespace Ux; + +SelectAllItem::SelectAllItem(const char *text) +{ + if (text) { + m_Text = text; + } +} + +Elm_Gen_Item_Class *SelectAllItem::getItemClass() const +{ + static Elm_Gen_Item_Class itc = createItemClass("end_icon"); + return &itc; +} + +char *SelectAllItem::getText(Evas_Object *parent, const char *part) +{ + if (strcmp(part, "elm.text") == 0) { + return strdup(_(m_Text.c_str())); + } + + return nullptr; +} + +Evas_Object *SelectAllItem::getContent(Evas_Object *parent, const char *part) +{ + if (strcmp(part, "elm.swallow.end") == 0) { + return CheckItem::getContent(parent, part); + } + + return nullptr; +} + +void SelectAllItem::onInserted() +{ + elm_object_item_color_class_color_set(getObjectItem(), "text", TEXT_COLOR); + elm_object_item_color_class_color_set(getObjectItem(), "text_pressed", TEXT_COLOR); +} diff --git a/lib-apps-common/src/Ux/SelectItem.cpp b/lib-apps-common/src/Ux/SelectItem.cpp new file mode 100644 index 0000000..bf4db54 --- /dev/null +++ b/lib-apps-common/src/Ux/SelectItem.cpp @@ -0,0 +1,117 @@ +/* + * Copyright 2016 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.1 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://floralicense.org/license/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "Ux/SelectItem.h" +#include "Ux/SelectView.h" + +using namespace Ux; +using namespace Ui; + +SelectItem::SelectItem(GenContainer::Type type) + : CheckItem(type), + m_SelectView(nullptr), m_SelectMode(SelectNone), + m_CustomResult{ 0, 0 }, m_HasCustomResult(false), + m_IsExcluded(false) +{ +} + +bool SelectItem::isExcluded() const +{ + return m_IsExcluded; +} + +void SelectItem::setExcluded(bool isExcluded) +{ + if (m_IsExcluded == isExcluded) { + return; + } + + m_IsExcluded = isExcluded; + if (m_SelectView) { + m_SelectView->onItemExcluded(this, m_IsExcluded); + } +} + +SelectMode SelectItem::getSelectMode() const +{ + return m_SelectMode; +} + +void SelectItem::setSelectMode(SelectMode selectMode) +{ + m_SelectMode = selectMode; + + setChecked(false); + updateCheckPart(); + onSelectModeChanged(m_SelectMode); +} + +SelectResult SelectItem::getSelectResult() const +{ + return m_HasCustomResult ? m_CustomResult : getDefaultResult(); +} + +bool SelectItem::hasCustomResult() const +{ + return m_HasCustomResult; +} + +void SelectItem::setCustomResult(SelectResult result) +{ + m_CustomResult = result; + m_HasCustomResult = true; +} + +void SelectItem::unsetCustomResult() +{ + m_HasCustomResult = false; +} + +Evas_Object *SelectItem::getContent(Evas_Object *parent, const char *part) +{ + if (m_SelectMode == SelectMulti) { + return CheckItem::getContent(parent, part); + } + + return nullptr; +} + +void SelectItem::onVisibilityChanged(bool isVisible) +{ + if (m_SelectView && !m_IsExcluded) { + return m_SelectView->onItemVisibilityChanged(this, isVisible); + } +} + +void SelectItem::onSelected() +{ + if (m_SelectMode == SelectSingle) { + if (m_SelectView) { + m_SelectView->onItemSelected(this); + } + } else if (m_SelectMode == SelectMulti) { + CheckItem::onSelected(); + } +} + +bool SelectItem::onChecked(bool isChecked) +{ + if (m_SelectView && !m_IsExcluded) { + return m_SelectView->onItemChecked(this, isChecked); + } + + return true; +} diff --git a/lib-apps-common/src/Ux/SelectView.cpp b/lib-apps-common/src/Ux/SelectView.cpp new file mode 100644 index 0000000..414b567 --- /dev/null +++ b/lib-apps-common/src/Ux/SelectView.cpp @@ -0,0 +1,453 @@ +/* + * Copyright 2016 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.1 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://floralicense.org/license/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "Ux/SelectView.h" +#include "Ux/SelectItem.h" + +#include "Ui/Genlist.h" +#include "Utils/Callback.h" + +#include +#include +#include + +#define TITLE_BUFFER_SIZE 64 +#define POPUP_BUFFER_SIZE 256 + +using namespace Ux; +using namespace std::placeholders; + +SelectView::SelectView() + : m_DoneButton(nullptr), m_CancelButton(nullptr), m_IsMultiChecking(false), + m_TotalCount(0), m_TotalSelectCount(0), + m_VisibleCount(0), m_VisibleSelectCount(0), + m_SelectLimit(0), m_IsEmptyResultAllowed(false), m_SelectMode(SelectNone), + m_Strings{ nullptr } +{ +} + +SelectView::~SelectView() +{ + if (auto item = m_SelectAllItem.lock()) { + delete item.get(); + } +} + +SelectMode SelectView::getSelectMode() const +{ + return m_SelectMode; +} + +size_t SelectView::getSelectLimit() const +{ + return m_SelectLimit; +} + +size_t SelectView::getSelectCount() const +{ + return m_TotalSelectCount; +} + +const SelectView::SelectItems &SelectView::getSelectItems() const +{ + return m_Items; +} + +void SelectView::setStrings(const Strings &strings) +{ + m_Strings = strings; +} + +void SelectView::setSelectMode(SelectMode selectMode) +{ + if (m_SelectMode != selectMode) { + m_SelectMode = selectMode; + + updatePageTitle(); + updatePageButtons(); + updateSelectAllItem(); + + for (auto &&item : m_Items) { + item->setSelectMode(m_SelectMode); + } + + onSelectModeChanged(m_SelectMode); + } +} + +void SelectView::setSelectLimit(size_t selectLimit) +{ + if (m_SelectLimit != selectLimit) { + m_SelectLimit = selectLimit; + + if (m_SelectLimit) { + m_IsMultiChecking = true; + for (size_t i = m_Items.size() - 1; m_TotalSelectCount > m_SelectLimit; --i) { + if (!m_Items[i]->isExcluded()) { + m_Items[i]->setChecked(false); + } + } + + m_IsMultiChecking = false; + } + + updateSelectAllState(); + updateDoneButtonState(); + updatePageTitle(); + + onSelectLimitChanged(m_SelectLimit); + } +} + +void SelectView::setEmptyResultAllowed(bool isAllowed) +{ + if (m_IsEmptyResultAllowed != isAllowed) { + m_IsEmptyResultAllowed = isAllowed; + updateDoneButtonState(); + } +} + +void SelectView::setSelectCallback(SelectCallback callback) +{ + m_OnSelected = std::move(callback); +} + +void SelectView::setCancelCallback(CancelCallback callback) +{ + m_OnCanceled = std::move(callback); +} + +void SelectView::setCheckCallback(CheckCallback callback) +{ + m_OnChecked = std::move(callback); +} + +void SelectView::setLimitCallback(LimitCallback callback) +{ + m_OnLimitReached = std::move(callback); +} + +void SelectView::addSelectItem(SelectItem *item) +{ + item->m_SelectView = this; + item->setSelectMode(m_SelectMode); + m_Items.push_back(item); + + if (!item->isExcluded()) { + updateTotalCount(CountIncrement, item); + } +} + +void SelectView::removeSelectItem(SelectItem *item) +{ + auto it = std::find(m_Items.begin(), m_Items.end(), item); + if (it == m_Items.end()) { + return; + } + + m_Items.erase(it); + if (!item->isExcluded()) { + updateTotalCount(CountDecrement, item); + } + item->m_SelectView = nullptr; +} + +void SelectView::onPageAttached(Ui::NavigatorPage *page) +{ + updatePageTitle(); + updatePageButtons(); + + evas_object_smart_callback_add(getEvasObject(), "language,changed", + [](void *data, Evas_Object *, void *) { + ((SelectView *) data)->updatePageTitle(); + }, this); +} + +bool SelectView::onBackPressed() +{ + if (m_SelectMode != SelectNone) { + if (m_OnCanceled && !m_OnCanceled()) { + return false; + } + } + + return true; +} + +void SelectView::onTitleChanged(const char *title) +{ + if (auto page = getPage()) { + page->setTitle(title); + } +} + +size_t SelectView::getSelectMax() const +{ + if (m_SelectLimit && m_SelectLimit < m_VisibleCount) { + return m_SelectLimit; + } + + return m_VisibleCount; +} + +bool SelectView::isLimitReached() const +{ + return m_SelectLimit && m_TotalSelectCount == m_SelectLimit; +} + +bool SelectView::isMaxSelected() const +{ + return m_VisibleSelectCount == getSelectMax(); +} + +void SelectView::updatePageTitle() +{ + char buffer[TITLE_BUFFER_SIZE]; + const char *title = nullptr; + + switch (m_SelectMode) { + case SelectNone: + title = m_Strings.titleDefault; + break; + case SelectSingle: + title = m_Strings.titleSingle; + break; + case SelectMulti: + if (m_SelectLimit) { + snprintf(buffer, sizeof(buffer), _(m_Strings.titleWithLimit), m_TotalSelectCount, m_SelectLimit); + title = buffer; + } else if (m_TotalSelectCount) { + snprintf(buffer, sizeof(buffer), _(m_Strings.titleWithCount), m_TotalSelectCount); + title = buffer; + } else { + title = m_Strings.titleMulti; + } + break; + } + + onTitleChanged(title); +} + +void SelectView::updatePageButtons() +{ + Ui::NavigatorPage *page = getPage(); + if (!page) { + return; + } + + switch (m_SelectMode) { + case SelectNone: + case SelectSingle: + if (m_DoneButton) { + destroyPageButtons(); + } + break; + + case SelectMulti: + if (!m_DoneButton) { + createPageButtons(page); + } + updateDoneButtonState(); + break; + } +} + +void SelectView::updateSelectAllItem() +{ + if (m_SelectMode == SelectMulti && m_VisibleCount) { + if (m_SelectAllItem.expired()) { + SelectAllItem *item = new SelectAllItem(m_Strings.selectAll); + item->setCheckCallback(std::bind(&SelectView::onSelectAllChecked, this, _1)); + + m_SelectAllItem = item->getWeakPtr(); + onSelectAllInsert(item); + } + + updateSelectAllState(); + } else { + if (auto item = m_SelectAllItem.lock()) { + delete item.get(); + } + } +} + +void SelectView::updateDoneButtonState() +{ + elm_object_disabled_set(m_DoneButton, + m_IsEmptyResultAllowed ? m_TotalCount == 0 : m_TotalSelectCount == 0); +} + +void SelectView::updateSelectAllState() +{ + if (auto item = m_SelectAllItem.lock()) { + auto selectAllItem = static_cast(item.get()); + selectAllItem->setChecked(isMaxSelected()); + } +} + +void SelectView::updateTotalCount(CountChange change, SelectItem *item) +{ + (change == CountIncrement) ? ++m_TotalCount : --m_TotalCount; + + updateDoneButtonState(); + if (item->isChecked()) { + updateTotalSelectCount(change, item); + } + if (item->isVisible()) { + updateVisibleCount(change, item); + } +} + +void SelectView::updateTotalSelectCount(CountChange change, SelectItem *item) +{ + (change == CountIncrement) ? ++m_TotalSelectCount : --m_TotalSelectCount; + onSelectCountChanged(m_TotalSelectCount); + + if (m_SelectLimit && m_TotalSelectCount > m_SelectLimit) { + item->setChecked(false); + return; + } + + updateDoneButtonState(); + /* Prevent updating if multiple checking is in progress (performance optimization) */ + if (!m_IsMultiChecking) { + updatePageTitle(); + } +} + +void SelectView::updateVisibleCount(CountChange change, SelectItem *item) +{ + (change == CountIncrement) ? ++m_VisibleCount : --m_VisibleCount; + + if (item->isChecked()) { + updateVisibleSelectCount(change, item); + } + + updateSelectAllItem(); +} + +void SelectView::updateVisibleSelectCount(CountChange change, SelectItem *item) +{ + (change == CountIncrement) ? ++m_VisibleSelectCount : --m_VisibleSelectCount; + updateSelectAllState(); +} + +void SelectView::createPageButtons(Ui::NavigatorPage *page) +{ + m_DoneButton = page->addTitleButton(Ui::ButtonRight, m_Strings.buttonDone, + makeCallback(&SelectView::onDonePressed), this); + + m_CancelButton = page->addTitleButton(Ui::ButtonLeft, m_Strings.buttonCancel, + makeCallback(&SelectView::onCancelPressed), this); +} + +void SelectView::destroyPageButtons() +{ + evas_object_del(m_DoneButton); + evas_object_del(m_CancelButton); + + m_DoneButton = nullptr; + m_CancelButton = nullptr; +} + +void SelectView::onItemExcluded(SelectItem *item, bool isExcluded) +{ + updateTotalCount(isExcluded ? CountDecrement : CountIncrement, item); +} + +void SelectView::onItemVisibilityChanged(SelectItem *item, bool isVisible) +{ + updateVisibleCount(isVisible ? CountIncrement : CountDecrement, item); +} + +void SelectView::onItemSelected(SelectItem *item) +{ + if (m_SelectMode == SelectSingle) { + SelectResult result = item->getSelectResult(); + if (m_OnSelected && m_OnSelected({ result })) { + getPage()->close(); + } + } +} + +bool SelectView::onItemChecked(SelectItem *item, bool isChecked) +{ + if (isChecked && isLimitReached()) { + onLimitReached(); + return false; + } + + if (m_OnChecked && !m_OnChecked(item, isChecked, m_IsMultiChecking)) { + return false; + } + + CountChange change = isChecked ? CountIncrement : CountDecrement; + updateTotalSelectCount(change, item); + if (item->isVisible()) { + updateVisibleSelectCount(change, item); + } + return true; +} + +bool SelectView::onSelectAllChecked(bool isChecked) +{ + if (isChecked == isMaxSelected()) { + return true; + } + + m_IsMultiChecking = true; + for (auto &&item : m_Items) { + if (!item->isExcluded() && item->isVisible()) { + if (!item->setChecked(isChecked)) { + break; + } + } + } + + m_IsMultiChecking = false; + updatePageTitle(); + return isChecked == isMaxSelected(); +} + +void SelectView::onDonePressed(Evas_Object *button, void *eventInfo) +{ + std::vector results; + for (auto &&item : m_Items) { + if (!item->isExcluded() && item->isChecked()) { + results.push_back(item->getSelectResult()); + } + } + + if (m_OnSelected && m_OnSelected(std::move(results))) { + getPage()->close(); + } +} + +void SelectView::onCancelPressed(Evas_Object *button, void *eventInfo) +{ + if (!m_OnCanceled || m_OnCanceled()) { + getPage()->close(); + } +} + +void SelectView::onLimitReached() +{ + if (!m_OnLimitReached || m_OnLimitReached()) { + char buffer[POPUP_BUFFER_SIZE]; + snprintf(buffer, sizeof(buffer), _(m_Strings.popupLimit), m_SelectLimit); + notification_status_message_post(buffer); + } +}