summaryrefslogtreecommitdiff
path: root/src/main.c
diff options
context:
space:
mode:
authorAdarsh Shree Ram <adarsh.ram@samsung.com>2016-04-21 16:10:26 +0530
committerAdarsh Shree Ram <adarsh.ram@samsung.com>2016-04-21 16:10:26 +0530
commitae6816792628b053e5dafb4e7b16e351327d7657 (patch)
tree4564b904be1f0dc19a154ceebfd8b455081601a4 /src/main.c
parent9fd312c4434f2b05f5e3ce5b360f514716ba84c5 (diff)
downloadalarm-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.c625
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 */