diff options
author | Adarsh Shree Ram <adarsh.ram@samsung.com> | 2016-04-21 16:10:26 +0530 |
---|---|---|
committer | Adarsh Shree Ram <adarsh.ram@samsung.com> | 2016-04-21 16:10:26 +0530 |
commit | ae6816792628b053e5dafb4e7b16e351327d7657 (patch) | |
tree | 4564b904be1f0dc19a154ceebfd8b455081601a4 /src/main.c | |
parent | 9fd312c4434f2b05f5e3ce5b360f514716ba84c5 (diff) | |
download | alarm-ae6816792628b053e5dafb4e7b16e351327d7657.tar.gz alarm-ae6816792628b053e5dafb4e7b16e351327d7657.tar.bz2 alarm-ae6816792628b053e5dafb4e7b16e351327d7657.zip |
Adding initial native alarm app code.
Tested with emulator 3.0.
Change-Id: I99bd4a3288f66f8093758e2b674d3effa8149014
Diffstat (limited to 'src/main.c')
-rw-r--r-- | src/main.c | 625 |
1 files changed, 625 insertions, 0 deletions
diff --git a/src/main.c b/src/main.c new file mode 100644 index 0000000..9632dda --- /dev/null +++ b/src/main.c @@ -0,0 +1,625 @@ +/* + * Copyright (c) 2015 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.h> +#include <app_alarm.h> +#include <efl_extension.h> +#include <dlog.h> +#include <system_settings.h> + +#include "alarm.h" +#include "data.h" +#include "view.h" + +static struct main_info { + Elm_Object_Item *padding_item; +} s_info = { + .padding_item = NULL, +}; + +static Evas_Object *_create_layout_no_alarmlist(Evas_Object *parent, const char *edje_path, const char *group_name); +static void _set_layout_exist_alarmlist(Evas_Object *layout); +static Evas_Object *_create_layout_set_time(Evas_Object *parent); +static void _create_layout_ring_alarm(Evas_Object *parent, struct tm *saved_time); +static Eina_Bool _naviframe_pop_cb(void *data, Elm_Object_Item *it); +static void _no_alarm_down_cb(void *data, Evas *e, Evas_Object *obj, void *event_info); +static void _no_alarm_up_cb(void *data, Evas *e, Evas_Object *obj, void *event_info); +static void _no_alarm_clicked_cb(void *data, Evas_Object *obj, void *event_info); +static void _add_clicked_cb(void *data, Evas_Object *obj, void *event_info); +static void _set_clicked_cb(void *data, Evas_Object *obj, void *event_info); +static void _dismiss_clicked_cb(void *data, Evas_Object *obj, void *event_info); + + +/* + * @brief: Hook to take necessary actions before main event loop starts + * Initialize UI resources and application's data + * If this function returns true, the main loop of application starts + * If this function returns false, the application is terminated + */ +static bool app_create(void *user_data) +{ + Evas_Object *layout = NULL; + Evas_Object *nf = NULL; + char edje_path[BUF_LEN] = {0, }; + + dlog_print(DLOG_INFO, LOG_TAG, "App create"); + + data_initialize(); + + /* + * Create base GUI. + */ + view_create(); + + /* + * Create GUI for alarm application. + */ + view_alarm_create(); + + /* + * Create a layout when there is no alarm list. + */ + data_get_resource_path("edje/main.edj", edje_path, sizeof(edje_path)); + + nf = view_get_naviframe(); + layout = _create_layout_no_alarmlist(nf, edje_path, "base_alarm"); + if (layout == NULL) { + dlog_print(DLOG_ERROR, LOG_TAG, "failed to create a layout of no alarm."); + view_destroy(); + return false; + } + + /* + * Create a layout that shows alarm lists when user sets the alarm. + */ + _set_layout_exist_alarmlist(layout); + + /* + * Hide the layout that exists alarm list before user sets the alarm. + */ + view_send_signal_to_edje(layout, "genlist.hide", "alarm"); + + /* + * Push the layout at a naviframe. + */ + view_push_item_to_naviframe(nf, layout, _naviframe_pop_cb, NULL); + + /* + * Save base layout. + */ + view_set_base_layout(layout); + + return true; +} + +/* + * @brief: This callback function is called when another application + * sends the launch request to the application + */ +static void app_control(app_control_h app_control, void *user_data) +{ + char *operation = NULL; + char *alarm_id = NULL; + Elm_Object_Item *item = NULL; + Evas_Object *genlist = NULL; + Evas_Object *nf = NULL; + struct genlist_item_data *gendata = NULL; + struct tm *saved_time = NULL; + int ret; + + dlog_print(DLOG_INFO, LOG_TAG, "App control"); + /* + * When it comes time to sound alarm that has set alarm_schedule_at_date(), + * alarm API calls app_control(), with operation that has set by app_control_set_operation() in advance. + */ + app_control_get_operation(app_control, &operation); + dlog_print(DLOG_INFO, LOG_TAG, "operation = %s", operation); + + if (!strncmp(APP_CONTROL_OPERATION_ALARM_ONTIME, operation, strlen(APP_CONTROL_OPERATION_ALARM_ONTIME))) { + + ret = app_control_get_extra_data(app_control, APP_CONTROL_DATA_ALARM_ID, &alarm_id); + if (ret != APP_CONTROL_ERROR_NONE) { + dlog_print(DLOG_ERROR, LOG_TAG, "Failed to app_control_get_extra_data(). Can't get extra data."); + free(operation); + return; + } + + /* + * Remove bundle that has alarm id as bundle's key. + */ + data_delete_bundle(alarm_id); + + /* + * Find genlist's item that is consistent with alarm id. + */ + genlist = view_get_genlist(); + item = view_alarm_find_item_from_genlist(genlist, alarm_id); + if (item == NULL) { + dlog_print(DLOG_ERROR, LOG_TAG, "genlist's item is NULL."); + return; + } + + gendata = elm_object_item_data_get(item); + if (gendata == NULL) { + dlog_print(DLOG_ERROR, LOG_TAG, "Failed at elm_object_item_data_get(). Gendata is NULL."); + return; + } + + /* + * Create a layout when the alarm sounds. + */ + saved_time = data_get_saved_time_from_gendata(gendata); + nf = view_get_naviframe(); + _create_layout_ring_alarm(nf, saved_time); + + /* + * Remove genlist's item that is consistent with alarm id. + */ + elm_object_item_del(item); + } + + free(operation); +} + +/* + * @brief: This callback function is called each time + * the application is completely obscured by another application + * and becomes invisible to the user + */ +static void app_pause(void *user_data) +{ + /* Take necessary actions when application becomes invisible. */ + dlog_print(DLOG_INFO, LOG_TAG, "App pause"); +} + +/* + * @brief: This callback function is called each time + * the application becomes visible to the user + */ +static void app_resume(void *user_data) +{ + /* Take necessary actions when application becomes visible. */ + dlog_print(DLOG_INFO, LOG_TAG, "App resume"); +} + +/* + * @brief: This callback function is called once after the main loop of the application exits + */ +static void app_terminate(void *user_data) +{ + /* + * Release all resources. + */ + dlog_print(DLOG_INFO, LOG_TAG, "App terminate"); + + if (ALARM_ERROR_NONE != alarm_cancel_all()) { + dlog_print(DLOG_ERROR, LOG_TAG, "Failed to cancel all scheduled alarms."); + } + + view_alarm_destroy(); + + view_destroy(); + + data_finalize(); +} + +/* + * @brief: This function will be called when the language is changed + */ +static void ui_app_lang_changed(app_event_info_h event_info, void *user_data) +{ + /*APP_EVENT_LANGUAGE_CHANGED*/ + char *locale = NULL; + + system_settings_get_value_string(SYSTEM_SETTINGS_KEY_LOCALE_LANGUAGE, &locale); + + if (locale != NULL) { + elm_language_set(locale); + free(locale); + } + return; +} + +/* + * @brief: main function of the application + */ +int main(int argc, char *argv[]) +{ + int ret; + + ui_app_lifecycle_callback_s event_callback = {0, }; + app_event_handler_h handlers[5] = {NULL, }; + + event_callback.create = app_create; + event_callback.terminate = app_terminate; + event_callback.pause = app_pause; + event_callback.resume = app_resume; + event_callback.app_control = app_control; + + /* + * If you want to handling more events, + * Please check the application lifecycle guide + */ + ui_app_add_event_handler(&handlers[APP_EVENT_LANGUAGE_CHANGED], APP_EVENT_LANGUAGE_CHANGED, ui_app_lang_changed, NULL); + + ret = ui_app_main(argc, argv, &event_callback, NULL); + if (ret != APP_ERROR_NONE) { + dlog_print(DLOG_ERROR, LOG_TAG, "ui_app_main() is failed. err = %d", ret); + } + + return ret; +} + +/* + * @note + * Below functions are static functions. + */ + +/* + * @brief: Create layout for the first page of the alarm application when there is no alarm list + * @param[parent]: Object to which you want to add this layout + * @param[edje_path]: Path of EDJ + * @param[group_name]: Name of group in EDJ you want to set to + */ +static Evas_Object *_create_layout_no_alarmlist(Evas_Object *parent, const char *edje_path, const char *group_name) +{ + Evas_Object *layout = NULL; + + if (parent == NULL) { + dlog_print(DLOG_ERROR, LOG_TAG, "failed to get parent."); + } + + layout = view_create_layout(parent, edje_path, "base_alarm", NULL, NULL); + if (layout == NULL) { + dlog_print(DLOG_ERROR, LOG_TAG, "failed to create a layout of base alarm."); + return NULL; + } + + view_set_text(layout, "no_alarm.title", "Alarm"); + + view_set_button(layout, "swallow.no_alarm.button", "focus", NULL, NULL, + _no_alarm_down_cb, _no_alarm_up_cb, _no_alarm_clicked_cb, layout); + + view_set_text(layout, "no_alarm.text", "Add alarm"); + + return layout; +} + +/* + * @brief: Set layout to given layout for the first page that shows alarm lists when user set the alarm + * @param[layout]: Layout will be shown the alarm lists + */ +static void _set_layout_exist_alarmlist(Evas_Object *layout) +{ + Evas_Object *genlist = NULL; + + if (!layout) { + dlog_print(DLOG_ERROR, LOG_TAG, "failed to get layout."); + return; + } + + genlist = view_create_circle_genlist(layout); + if (genlist == NULL) { + dlog_print(DLOG_ERROR, LOG_TAG, "failed to create a genlist of saving alarm."); + return; + } + + /* + * Append a genlist's item as a title. + */ + view_append_item_to_genlist(genlist, "title", NULL, NULL, NULL); + + /* + * Create a genlist's item as a padding item. + * Padding item makes genlist's items is located at the middle of the screen. + */ + s_info.padding_item = view_append_item_to_genlist(genlist, "padding", NULL, NULL, NULL); + if (s_info.padding_item == NULL) { + dlog_print(DLOG_ERROR, LOG_TAG, "failed to create padding item of genlist."); + return; + } + + view_set_content_to_part(layout, "swallow.genlist", genlist); + + view_set_button(layout, "swallow.genlist.button", "bottom", NULL, "Add", + NULL, NULL, _add_clicked_cb, NULL); + + view_set_genlist(genlist); +} + +/* + * @brief: Create layout for setting time + * @param[parent]: Object to which you want to add this layout + */ +static Evas_Object *_create_layout_set_time(Evas_Object *parent) +{ + Evas_Object *layout = NULL; + char image_path[BUF_LEN] = {0, }; + + if (!parent) { + dlog_print(DLOG_ERROR, LOG_TAG, "failed to get parent."); + return NULL; + } + + /* + * Create a layout that is able to set time. + */ + layout = view_create_layout_by_theme(parent, "layout", "circle", "datetime"); + + /* + * Set the title of the layout. + */ + view_set_text(layout, "elm.text", "Set alarm"); + + /* + * Set bottom button attached check image. + * The button can set the alarm when it is pressed. + */ + data_get_resource_path("images/ic_popup_btn_check.png", image_path, sizeof(image_path)); + + view_set_button(layout, "elm.swallow.btn", "bottom", image_path, NULL, NULL, NULL, _set_clicked_cb, NULL); + + /* + * Create datetime. + */ + view_create_datetime(layout, "timepicker/circle"); + + return layout; +} + +/* + * @brief: Create layout for a page that shows when the alarm sounds + * @param[parent]: Object to which you want to add this layout + * @param[saved_time]: Time that sound the alarm + */ +static void _create_layout_ring_alarm(Evas_Object *parent, struct tm *saved_time) +{ + Evas_Object *layout = NULL; + char buf[BUF_LEN] = {0, }; + char file_path[BUF_LEN] = {0, }; + + if (parent == NULL) { + dlog_print(DLOG_ERROR, LOG_TAG, "failed to get parent."); + return; + } + + /* + * Create a layout that shows when the alarm sounds. + */ + data_get_resource_path("edje/main.edj", file_path, sizeof(file_path)); + + layout = view_create_layout(parent, file_path, "ringing_alarm", NULL, NULL); + if (layout == NULL) { + dlog_print(DLOG_ERROR, LOG_TAG, "failed to create a layout."); + return; + } + + if (saved_time) { + strftime(buf, sizeof(buf) - 1, "%l:%M %p", saved_time); + view_set_text(layout, "ringing_alarm.text", buf); + } + + /* + * Set bottom button. + * The button can dismiss the alarm when it is pressed. + */ + view_set_button(layout, "swallow.button", "bottom", NULL, "Dismiss", + NULL, NULL, _dismiss_clicked_cb, NULL); + + view_push_item_to_naviframe(parent, layout, NULL, NULL); +} + +/* + * @brief: This function will be operated when the first item of the naviframe is going to popped. + * @param[data]: Data needed in this function + * @param[it]: Item of naviframe + */ +static Eina_Bool _naviframe_pop_cb(void *data, Elm_Object_Item *it) +{ + ui_app_exit(); + + return EINA_FALSE; +} + +/* + * @brief: This function will be operated when the button is pressed + * @param[data]: Data will be the same value passed to evas_object_event_callback_add() as the data parameter + * @param[e]: The e lets the user know what evas canvas the event occurred on + * @param[obj]: Object handles on which the event occurred + * @param[event_info]: Event_info is a pointer to a data structure about event + */ +static void _no_alarm_down_cb(void *data, Evas *e, Evas_Object *obj, void *event_info) +{ + Evas_Object *layout = data; + + if (layout == NULL) { + dlog_print(DLOG_ERROR, LOG_TAG, "Failed to get layout."); + } + + view_send_signal_to_edje(layout, "mouse.down", "button"); +} + +/* + * @brief: This function will be operated when the button is released + * @param[data]: Data will be the same value passed to evas_object_event_callback_add() as the data parameter + * @param[e]: The e lets the user know what evas canvas the event occurred on + * @param[obj]: Object handles on which the event occurred + * @param[event_info]: Event_info is a pointer to a data structure about event + */ +static void _no_alarm_up_cb(void *data, Evas *e, Evas_Object *obj, void *event_info) +{ + Evas_Object *layout = data; + + if (layout == NULL) { + dlog_print(DLOG_ERROR, LOG_TAG, "Failed to get layout."); + } + + view_send_signal_to_edje(layout, "mouse.up", "button"); +} + +/* + * @brief: This function will be operated when the button is clicked. + * @param[data]: Data has the same value passed to evas_object_smart_callback_add() as the data parameter + * @param[obj]: The obj is a handle to the object on which the event occurred + * @param[event_info]: A pointer to data which is totally dependent on the smart object's implementation and semantic for the given event + */ +static void _no_alarm_clicked_cb(void *data, Evas_Object *obj, void *event_info) +{ + Evas_Object *nf = NULL; + Evas_Object *layout = NULL; + + /* + * Add layout that is able to set time to naviframe. + */ + nf = view_get_naviframe(); + + layout = _create_layout_set_time(nf); + if (layout == NULL) { + dlog_print(DLOG_ERROR, LOG_TAG, "failed to create a layout of setting time."); + return; + } + + view_push_item_to_naviframe(nf, layout, NULL, NULL); +} + +/* + * @brief: This function will be operated when the button is clicked. + * @param[data]: Data has the same value passed to evas_object_smart_callback_add() as the data parameter + * @param[obj]: The obj is a handle to the object on which the event occurred + * @param[event_info]: A pointer to data which is totally dependent on the smart object's implementation and semantic for the given event + */ +static void _add_clicked_cb(void *data, Evas_Object *obj, void *event_info) +{ + Evas_Object *nf = NULL; + Evas_Object *layout = NULL; + + /* + * Add layout that is able to set time to naviframe. + */ + nf = view_get_naviframe(); + + layout = _create_layout_set_time(nf); + if (layout == NULL) { + dlog_print(DLOG_ERROR, LOG_TAG, "failed to create a layout of setting time."); + return; + } + + view_push_item_to_naviframe(nf, layout, NULL, NULL); +} + +/* + * @brief: This function will be operated when the button is clicked. + * @param[data]: Data has the same value passed to evas_object_smart_callback_add() as the data parameter + * @param[obj]: The obj is a handle to the object on which the event occurred + * @param[event_info]: A pointer to data which is totally dependent on the smart object's implementation and semantic for the given event + */ +static void _set_clicked_cb(void *data, Evas_Object *obj, void *event_info) +{ + Evas_Object *layout = NULL; + struct genlist_item_data *gendata; + Evas_Object *genlist = NULL; + Evas_Object *nf = NULL; + int alarm_id = 0; + struct tm *saved_time = NULL; + char *popup_text = NULL; + char buf[BUF_LEN] = {0, }; + + /* + * Do the following steps when press set button. + * 1. Allocate gendata memory. + * 2. Set alarm by using alarm API. + * 3. Store the alarm id in bundle. + * 4. Create popup that shows how much time left before the alarm rings. + * 5. Append the alarm to genlist as a item. + * 6. Pop the current layout from naviframe. + */ + + /* + * Allocate gendata memory. + */ + gendata = data_alarm_create_genlist_item_data(); + + /* + * Set alarm by using alarm API. + */ + view_alarm_schedule_alarm(gendata); + + /* + * Store the alarm id in bundle. + */ + alarm_id = data_get_alarm_id_from_gendata(gendata); + snprintf(buf, sizeof(buf), "%d", alarm_id); + data_add_bundle_by_str(buf, buf); + + /* + * Create popup that shows how much time left before the alarm rings. + */ + layout = view_get_base_layout(); + saved_time = data_get_saved_time_from_gendata(gendata); + + popup_text = data_get_popup_text(saved_time); + view_create_text_popup(layout, 2.0, popup_text); + if (popup_text) { + free(popup_text); + } + + /* + * Append the alarm to genlist as a item. + */ + elm_object_item_del(s_info.padding_item); + if (s_info.padding_item) { + s_info.padding_item = NULL; + } + + nf = view_get_naviframe(); + genlist = view_get_genlist(); + + view_append_item_to_genlist(genlist, "1text.1icon.1", (void *)gendata, NULL, NULL); + view_send_signal_to_edje(layout, "genlist.show", "alarm"); + s_info.padding_item = view_append_item_to_genlist(genlist, "padding", NULL, NULL, NULL); + + /* + * Pop the current layout from naviframe. + */ + elm_naviframe_item_pop(nf); +} + +/* + * @brief: This function will be operated when the button is clicked. + * @param[data]: Data has the same value passed to evas_object_smart_callback_add() as the data parameter + * @param[obj]: The obj is a handle to the object on which the event occurred + * @param[event_info]: A pointer to data which is totally dependent on the smart object's implementation and semantic for the given event + */ +static void _dismiss_clicked_cb(void *data, Evas_Object *obj, void *event_info) +{ + Evas_Object *layout = NULL; + Evas_Object *nf = NULL; + Evas_Object *genlist = NULL; + int count = 0; + + genlist = view_get_genlist(); + count = elm_genlist_items_count(genlist); + + if (count < 3) { + layout = view_get_base_layout(); + view_send_signal_to_edje(layout, "genlist.hide", "alarm"); + } + + nf = view_get_naviframe(); + elm_naviframe_item_pop(nf); +} + +/* End of files */ |