diff --git a/media/code_c/tutorial/menu/menu.c b/media/code_c/tutorial/menu/menu.c new file mode 100644 index 000000000..247190fa4 --- /dev/null +++ b/media/code_c/tutorial/menu/menu.c @@ -0,0 +1,273 @@ +#include +#include "structure_menu.h" + +#define MAINVIEW "view/main" +#define MAINMENU "menu/main" +#define SIDEMENU "menu/side" +#define ICON_DIR "" + +//to handle the key down events +static Eina_Bool +keydown_cb(void *data , int type , void *event) +{ + Menu *me = data; + Ecore_Event_Key *ev = event; + if (!strcmp(ev->keyname, "XF86Send")) + { + if (me->sdmenu_up == EINA_TRUE) + { + // If the menu is visible send a "hide,sidemenu" signal + elm_object_signal_emit(me->layout, "hide,sidemenu", "MenuButton"); + // Store the new menu status (hidden). + me->sdmenu_up = EINA_FALSE; + } + else + { + // If the menu is visible send a "hide,sidemenu" signal + elm_object_signal_emit(me->layout, "show,sidemenu", "MenuButton"); + // Store the new menu status (hidden). + me->sdmenu_up = EINA_TRUE; + } + } + return ECORE_CALLBACK_PASS_ON; +} + +//create the views +static void +_build_main_view(Menu *me) +{ + Mainview *view = me->main_view; + char buf[PATH_MAX]; + + //Main box + view->box = elm_box_add(me->nf); + elm_box_horizontal_set(view->box, EINA_FALSE); + elm_box_homogeneous_set(view->box, EINA_TRUE); + + view->img = elm_image_add(view->box); + evas_object_size_hint_weight_set(view->img, EVAS_HINT_FILL, EVAS_HINT_FILL); + evas_object_size_hint_align_set(view->img, 0.5, 0.5); + evas_object_size_hint_min_set(view->img, 25, 25); + snprintf(buf, sizeof(buf), "%s/%s", ICON_DIR, "icon.png"); + if (!elm_image_file_set(view->img, buf, NULL)) + elm_object_text_set(view->lb_day, "Problem loading image"); + elm_box_pack_start(view->box, view->img); + evas_object_show(view->img); + + view->lb_day = elm_label_add(view->box); + elm_object_text_set(view->lb_day, "Main view"); + evas_object_size_hint_weight_set(view->lb_day, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + elm_box_pack_end(view->box, view->lb_day); + evas_object_show(view->lb_day); +} + +static void +_build_calendar_view(Menu *me) +{ + Calview *view = me->cal_view; + + view->box = elm_box_add(me->nf); + elm_box_horizontal_set(view->box, EINA_FALSE); + elm_box_homogeneous_set(view->box, EINA_TRUE); + + view->calendar = elm_calendar_add(me->nf); + evas_object_size_hint_weight_set(view->calendar, EVAS_HINT_FILL, EVAS_HINT_FILL); + evas_object_size_hint_align_set(view->calendar, 0.5, 0.5); + elm_box_pack_end(view->box, view->calendar); + evas_object_show(view->calendar); + + view->lb_cal = elm_label_add(view->box); + elm_object_text_set(view->lb_cal, "The calendar view"); + evas_object_size_hint_weight_set(view->lb_cal, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + elm_box_pack_end(view->box, view->lb_cal); + evas_object_show(view->lb_cal); +} // End of_build_calendar_view + +static void +_build_date_view(Menu *me) +{ + Dateview *view = me->date_view; + + view->box = elm_box_add(me->nf); + elm_box_horizontal_set(view->box, EINA_FALSE); + elm_box_homogeneous_set(view->box, EINA_TRUE); + + view->datetime = elm_datetime_add(me->nf); + evas_object_size_hint_weight_set(view->datetime, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + evas_object_size_hint_align_set(view->datetime, EVAS_HINT_FILL, 0.5); + elm_box_pack_end(view->box, view->datetime); + evas_object_show(view->datetime); + + view->lb_date = elm_label_add(view->box); + elm_object_text_set(view->lb_date, "The calendar view"); + evas_object_size_hint_weight_set(view->lb_date, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + elm_box_pack_end(view->box, view->lb_date); + evas_object_show(view->lb_date); +} // End of_build_calendar_view + +static void +_build_settings_view(Menu *me) +{ + Setview *view = me->settings_view; + + view->box = elm_box_add(me->nf); + elm_box_horizontal_set(view->box, EINA_FALSE); + elm_box_homogeneous_set(view->box, EINA_TRUE); + + view->lb = elm_label_add(view->box); + elm_object_text_set(view->lb, "The settings view"); + evas_object_size_hint_weight_set(view->lb, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + elm_box_pack_end(view->box, view->lb); + evas_object_show(view->lb); +} // End of_build_calendar_view + +static void +_menu_item_selected_cb(void *data, Evas_Object *obj, void *event_info) +{ + Elm_Object_Item *it = (Elm_Object_Item*) event_info; + Menu * me = (Menu *)data; + Evas_Object *view; + + // Get the menu item text + const char *str = elm_object_item_text_get(it); + + // Comparing with the possible view names + if (!strcmp(str, "Calendar")) + { + // Build the "Calendar View" + _build_calendar_view(me); + // Set the view from the application data + view = me->cal_view->box; + } + else if (!strcmp(str, "Date")) + { + // Build the "Date View" + _build_date_view(data); + // Set the view from the application data + view = me->date_view->box; + } + else if (!strcmp(str, "Home")) + { + // Build the "Home or main View" + _build_main_view(me); + // Set the view from the application data + view = me->main_view->box; + } + else if (!strcmp(str, "Settings")) + { + // Build the "Settings" view + _build_settings_view(data); + // Set the view from the application data + view = me->settings_view->box; + } + else if (!strcmp(str, "Clock")) + { + // Build the "Date View" + _build_date_view(me); + // Set the view from the application data + view = me->date_view->box; + } + else return; + + // Show the view in the naviframe + elm_layout_content_set(me->layout, MAINVIEW, view); +} + +//main menu +static void +_build_main_menu(Menu *me, Evas_Object *win) +{ + //Memory allocation for the main menu function. + Tbarmenu *menu = calloc(1, sizeof(Tbarmenu)); + //Putting the "main" menu in the application data. + me->menu = menu; + + // Creation of the "Menu" toolbar + menu->tb = elm_toolbar_add(win); + + // Setting the "Menu" Toolbar properties + elm_toolbar_shrink_mode_set(menu->tb, ELM_TOOLBAR_SHRINK_NONE); + elm_toolbar_transverse_expanded_set(menu->tb, EINA_TRUE); + elm_toolbar_homogeneous_set(menu->tb, EINA_FALSE); + + // Adding menu items to the "Menu" toolbar + elm_toolbar_item_append(menu->tb, ICON_DIR"home.svg", "Home", _menu_item_selected_cb, me); + elm_toolbar_item_append(menu->tb, ICON_DIR"calendar.svg", "Calendar", _menu_item_selected_cb, me); + elm_toolbar_item_append(menu->tb, ICON_DIR"clock.svg", "Date", _menu_item_selected_cb, me); + elm_toolbar_item_append(menu->tb, ICON_DIR"settings.svg", "Settings", _menu_item_selected_cb, me); + + // Showing the widget + evas_object_show(menu->tb); + + // Adding the widget to the "menu/main" SWALLOW container defined in the .edc theme file. + elm_layout_content_set(me->layout, "menu/main", menu->tb); + + // Set the default view + elm_toolbar_item_selected_set(elm_toolbar_first_item_get(menu->tb), EINA_TRUE); +} + +//side menu not visible at default +static void _build_side_menu(Menu *me, Evas_Object *win) +{ + Tbarmenu *sidemenu = calloc(1, sizeof(Tbarmenu)); + me->sidemenu = sidemenu; + + sidemenu->tb = elm_toolbar_add(win); + + elm_toolbar_shrink_mode_set(sidemenu->tb, ELM_TOOLBAR_SHRINK_EXPAND); + elm_toolbar_transverse_expanded_set(sidemenu->tb, EINA_TRUE); + + elm_toolbar_item_append(sidemenu->tb, ICON_DIR"/home.svg", "Home", _menu_item_selected_cb, me); + elm_toolbar_item_append(sidemenu->tb, ICON_DIR"/account.svg", "Account", NULL, NULL); + elm_toolbar_item_append(sidemenu->tb, ICON_DIR"/contact.svg", "Friends", NULL, NULL); + elm_toolbar_item_append(sidemenu->tb, ICON_DIR"/clock.svg", "Clock", _menu_item_selected_cb, me); + elm_toolbar_homogeneous_set(sidemenu->tb, EINA_FALSE); + evas_object_show(sidemenu->tb); + elm_object_part_content_set(me->layout, "menu/side", sidemenu->tb); + elm_toolbar_horizontal_set(sidemenu->tb, EINA_FALSE); + elm_toolbar_item_selected_set(elm_toolbar_first_item_get(sidemenu->tb), EINA_TRUE); +} + +EAPI_MAIN int +elm_main(int argc, char **argv) +{ + Evas_Object *win; + char buf[PATH_MAX]; + win = elm_win_util_standard_add("Menu", "Menu Tutorial"); + elm_policy_set(ELM_POLICY_QUIT, ELM_POLICY_QUIT_LAST_WINDOW_CLOSED); + elm_win_autodel_set(win, EINA_TRUE); + + // Memory allocation + Menu *me = calloc(1, sizeof(Menu)); + me->main_view = calloc(1, sizeof(Mainview)); // Allocating memory for the main view + me->cal_view = calloc(1, sizeof(Calview)); // Allocating memory for the calendar view + me->date_view = calloc(1, sizeof(Dateview)); // allocating memory for the date view + me->settings_view = calloc(1, sizeof(Setview)); // allocating memory for the date view + me->sdmenu_up = EINA_FALSE; + + me->layout = elm_layout_add(win); + evas_object_resize(me->layout, 400, 400); + + elm_layout_file_set(me->layout, "menu.edj", "my_layout"); + + me->nf = elm_naviframe_add(win); + _build_main_menu(me, win); + _build_side_menu(me, win); + + evas_object_show(me->layout); + ecore_event_handler_add(ECORE_EVENT_KEY_DOWN, keydown_cb, me); + evas_object_smart_callback_add(win, "delete,request", _free_menu_cb, me); + //win 400x400 px + evas_object_resize(win, 400, 400); + evas_object_show(win); + elm_run(); + free(me->menu); + free(me->sidemenu); + free(me->main_view); + free(me->cal_view); + free(me->settings_view); + free(me); + elm_shutdown(); + return 0; +} +ELM_MAIN() diff --git a/media/code_c/tutorial/menu/menu.edc b/media/code_c/tutorial/menu/menu.edc new file mode 100644 index 000000000..687dad023 --- /dev/null +++ b/media/code_c/tutorial/menu/menu.edc @@ -0,0 +1,102 @@ +collections { + group { + name: "my_layout"; + parts { + part + { + name: "menu/main"; + type: SWALLOW; + description + { + state: "default" 0.0; + rel1.relative: 1.0 0.0; + rel2.relative: 1.0 1.0; + } + description + { + state: "up" 0.0; + rel1.relative: 0.0 0.01; + rel2.relative: 1.0 0.18; + + } + } //End menu/main + part + { + name: "view/main"; + type: SWALLOW; + description + { + state: "default" 0.0; + rel1.relative: 1.0 1.0; + rel2.relative: 1.0 1.0; + } + description + { + state: "up" 0.0; + rel1.relative: 0.0 1.01; + rel1.to: "menu/main"; + rel2.relative: 1.0 1.0; + color: 0 255 0 255; + } + } // END view/main + part + { + name: "menu/side"; + type: SWALLOW; + description + { + state: "default" 0.0; + rel1.relative: -0.3 0.0; + rel2.relative: -0.3 1.0; + color: 255 0 0 255; + } + description + { + state: "up" 0.0; + rel1.relative: 0.0 0.2; + rel2.relative: 0.10 1.0; + color: 255 0 0 255; + } + } //END menu/side + } + programs { + program + { + name: "animation,menu_main"; + source: ""; + signal: "load"; + action: STATE_SET "up" 1.0; + target: "menu/main"; + transition: LINEAR 0.5; + } // END animation,menu_main + program + { + name: "animation,view_main"; + source: ""; + signal: "load"; + action: STATE_SET "up" 1.0; + target: "view/main"; + transition: LINEAR 0.2; + } //END animation,view_mainĀ² + program + { + name: "animation,menu_side,hide"; + source: "MenuButton"; + signal: "hide,sidemenu"; + action: STATE_SET "default" 1.0; + target: "menu/side"; + transition: LINEAR 0.2; + } //END animation,menu_side,hide + + program + { + name: "animation,menu_side"; + source: "MenuButton"; + signal: "show,sidemenu"; + action: STATE_SET "up" 1.0; + target: "menu/side"; + transition: LINEAR 0.2; + } //END animation,menu_side + } + } +} diff --git a/media/code_c/tutorial/menu/structure_menu.h b/media/code_c/tutorial/menu/structure_menu.h new file mode 100644 index 000000000..f5fe649e0 --- /dev/null +++ b/media/code_c/tutorial/menu/structure_menu.h @@ -0,0 +1,51 @@ +#ifndef __STRUCTURE_MENU_ +#define __STRUCTURE_MENU_ + +typedef struct _Mainview +{ + Evas_Object *box; //The main container of the view + Evas_Object *img; //An image + Evas_Object *lb_day; //A label +} Mainview; + +typedef struct _Dateview +{ + Evas_Object *box; //The main container of the view + Evas_Object *datetime; //A datetime widget + Evas_Object *lb_date; //A label +} Dateview; + +typedef struct _Calview +{ + Evas_Object *box; //The main container of the view + Evas_Object *calendar; //A calendar widget + Evas_Object *lb_cal; //A label widget +} Calview; + +typedef struct _Setview +{ + Evas_Object *box; //The main container of the view + Evas_Object *lb; //A label widget +} Setview; + +typedef struct _Tbarmenu +{ + Evas_Object *tb; //The toolbar + Elm_Object_Item *submenu; //The submenu item +} Tbarmenu; + +typedef struct _Menu +{ + Evas_Object* layout; // The "edje" layout + Evas_Object *nf; // The Naviframe to handle the views + Tbarmenu *menu; // The main menu + Tbarmenu *sidemenu; // The side menu + Mainview *main_view; // The main view + Calview *cal_view; // The calendar view + Dateview *date_view; // The date and time view + Setview *settings_view; //The settin view + + Eina_Bool sdmenu_up; // A bool variable to keep the side menu status +} Menu; + +#endif diff --git a/media/menu.png b/media/menu.png new file mode 100644 index 000000000..e309554c6 Binary files /dev/null and b/media/menu.png differ diff --git a/media/menu_skeleton.png b/media/menu_skeleton.png new file mode 100644 index 000000000..d9612dffa Binary files /dev/null and b/media/menu_skeleton.png differ diff --git a/media/view_main.png b/media/view_main.png new file mode 100644 index 000000000..510e3fa45 Binary files /dev/null and b/media/view_main.png differ diff --git a/pages/docs.txt b/pages/docs.txt index 0aaa6e7c7..9126b2e55 100644 --- a/pages/docs.txt +++ b/pages/docs.txt @@ -45,6 +45,7 @@ Go check the current available version of EFL on each distro/platform: * [[tutorial/genlist_tutorial|Genlist Tutorial]] * [[tutorial/panes_tutorial|Panes Tutorial]] * [[tutorial/form_tutorial|Form Tutorial]] + * [[tutorial/menu_tutorial|Menu Tutorial]] * [[tutorial/naviframe_tutorial|Naviframe Tutorial]] * [[tutorial/popup_tutorial|Popup Tutorial]] diff --git a/pages/tutorial/menu/basic_ui.txt b/pages/tutorial/menu/basic_ui.txt new file mode 100644 index 000000000..0a35e08f7 --- /dev/null +++ b/pages/tutorial/menu/basic_ui.txt @@ -0,0 +1,296 @@ +~~Title: Basic UI Menu~~ +//**__previous__: **//[[/tutorial/menu/theme|Defining the Application Theme]] +==== Creating the Basic UI ==== + +The view container ''view/main'' is structured like this: + +{{ :view_main.png?direct |View main}} + +The naviframe contains and manages the boxes. For more information, see the +[[/coming_soon|Container programming guide]]. This widget handle views. In +this example each view is contained in a box and the box is contained in the +naviframe. + +Create the naviframe in the ''elm_main'' function and allocate the memory to +handle the views and menus of the application. + + +// Memory allocation +Menu *me = calloc(1, sizeof(Menu)); +me->main_view = calloc(1, sizeof(Mainview)); // Allocating memory for the main view +me->cal_view = calloc(1, sizeof(Calview)); // Allocating memory for the calendar view +me->date_view = calloc(1, sizeof(Dateview)); // allocating memory for the date view +me->settings_view = calloc(1, sizeof(Setview); //Allocating memory for the settings view +me->sdmenu_up = EINA_FALSE; + + +Use ''_free_menu_cb'' callback function to free the memory: + + +evas_object_smart_callback_add(win, "delete,request", _free_menu_cb, me); + + + +static void +_free_menu_cb(void *data, Evas_Object *obj, void *event_info) +{ + Menu *me = (Menu *)data; + + free(me->menu); + free(me->sidemenu); + free(me->main_view); + free(me->cal_view); + free(me->settings_view); + free(me); + evas_object_del(obj); + elm_exit(); +} + + +Create the naviframe: + +Create the main menu after most of the containers are created. First create a +new ''_build_main_menu'' function, it takes an ''Menu'' and the ''win'' as a parameter. This +function is called by ''elm_main''. + + + +static void +_build_main_menu(Menu *me, Evas_Object *win) +{ + //Memory allocation for the main menu function. + Tbarmenu *menu = calloc(1, sizeof(Tbarmenu)); + //Putting the "main" menu in the application data. + me->menu = menu; + + // Creation of the "Menu" toolbar + menu->tb = elm_toolbar_add(win); + + // Setting the "Menu" Toolbar properties + elm_toolbar_shrink_mode_set(menu->tb, ELM_TOOLBAR_SHRINK_NONE); + elm_toolbar_transverse_expanded_set(menu->tb, EINA_TRUE); + elm_toolbar_homogeneous_set(menu->tb, EINA_FALSE); + + // Adding menu items to the "Menu" toolbar + elm_toolbar_item_append(menu->tb, ICON_DIR"home.svg", "Home", _menu_item_selected_cb, me); + elm_toolbar_item_append(menu->tb, ICON_DIR"calendar.svg", "Calendar", _menu_item_selected_cb, me); + elm_toolbar_item_append(menu->tb, ICON_DIR"clock.svg", "Date", _menu_item_selected_cb, me); + elm_toolbar_item_append(menu->tb, ICON_DIR"settings.svg", "Settings", _menu_item_selected_cb, me); + + // Showing the widget + evas_object_show(menu->tb); + + // Adding the widget to the "menu/main" SWALLOW container defined in the .edc theme file. + //elm_object_part_content_set(me->layout, "menu/main", menu->tb); + elm_layout_content_set(me->layout, "menu/main", menu->tb); + + // Set the default view + elm_toolbar_item_selected_set(elm_toolbar_first_item_get(menu->tb), EINA_TRUE); +} + + +Create a toolbar with ''elm_toolbar_add''. This toolbar is a child of the main +window so set ''win'' as parameter. + +Setup the behavior of the toolbar, the display mode is set by using +''elm_toolbar_shrink_mode_set''. The toolbar does not scroll under +''#ELM_TOOLBAR_SHRINK_NONE'' mode, but it enforces a minimum size, so that all +the items fit inside it. It does not scroll or show the items that do not fit +under ''#ELM_TOOLBAR_SHRINK_HIDE'' mode. Finally, it scrolls under +''#ELM_TOOLBAR_SHRINK_SCROLL'' mode, and it creates a button to aggregate +items which did not fit with the ''#ELM_TOOLBAR_SHRINK_MENU'' mode. + +In this example, there is only a limited number of menu elements and thus +''ELM_TOOLBAR_SHRINK_NONE'' is used. + +Expand the transverse length of the item according the transverse length of +the toolbar, giving ''EINA_TRUE'' as second parameter of +''elm_toolbar_transverse_expanded_set''. + +Make the menu items have the same size by setting ''EINA_TRUE'' to +''elm_toolbar_homogeneous_set''. This activates the homogeneous mode of the +toolbar. + +Add menu items to the toolbar using ''elm_toolbar_item_append''. This function +takes 4 parameters: + * the target toolbar + * the icon path for the menu item + * the item label + * the function to camm when the item is clicked + * the data to assciate with the item for related callbacks + +For the icons, add some images in a directory and define a macro to contain +the path to the directory. + + +#define ICON_DIR "" + + +The item label is very important, it is used in the item callback function. + +In this example, only one callback is created to manage all the items but +there can be several callback functions. Pass the application data to the +callback. + +This callback is an ''Evas_Smart_Cb'', it must have this prototype: + + +_mycallback(void *data, Evas_Object *obj, void *event_info) + + +In this example, the aim of the callback is to create the view which the user +has requested. It is named ''_menu_item_selected_cb'', and in this function we +recover the calling object text to call the correct view creation function. + + +static void +_menu_item_selected_cb(void *data, Evas_Object *obj, void *event_info) +{ + Elm_Object_Item *it = (Elm_Object_Item*) event_info; + Menu * me = (Menu *)data; + Evas_Object *view; + + // Get the menu item text + const char *str = elm_object_item_text_get(it); + + // Comparing with the possible view names + if (!strcmp(str, "Calendar")) + { + // Build the "Calendar View" + _build_calendar_view(me); + // Set the view from the application data + view = me->cal_view->box; + } + else if (!strcmp(str, "Date")) + { + // Build the "Date View" + _build_date_view(data); + // Set the view from the application data + view = me->date_view->box; + } + else if (!strcmp(str, "Home")) + { + // Build the "Home or main View" + _build_main_view(me); + // Set the view from the application data + view = me->main_view->box; + } + else if (!strcmp(str, "Settings")) + { + // Build the "Settings" view + _build_settings_view(data); + // Set the view from the application data + view = data->settings_view->box; + } + else if (!strcmp(str, "Clock")) + { + // Build the "Date View" + _build_date_view(me); + // Set the view from the application data + view = me->date_view->box; + } + // Show the view in the naviframe + elm_object_content_set(me->nf, view); +} + + +The menu has views, Calendar, Date, Settings, and Home (main view). The view +names are stored in the menu item label, to get the label compare the returned +string with the view names. When the name matches, the view is built by +calling the correct function. Store the view in the application data and set +up a new content to the naviframe before exit. + +This way when the user clicks a menu item, the view changes. The naviframe +widget destroys its content on each call of ''elm_object_content_set''. That is +why the content must be built again on each item click. + +Create the functions which create the views. + + +static void +_build_main_view(Menu *me) +{ + Mainview *view = me->main_view; + char buf[PATH_MAX]; + + //Main box + view->box = elm_box_add(me->nf); + elm_box_horizontal_set(view->box, EINA_FALSE); + elm_box_homogeneous_set(view->box, EINA_TRUE); + + view->img = elm_image_add(view->box); + evas_object_size_hint_weight_set(view->img, EVAS_HINT_FILL, EVAS_HINT_FILL); + evas_object_size_hint_align_set(view->img, 0.5, 0.5); + evas_object_size_hint_min_set(view->img, 25, 25); + snprintf(buf, sizeof(buf), "%s/%s", ICON_DIR, "icon.png"); + if (!elm_image_file_set(view->img, buf, NULL)) + elm_object_text_set(view->lb_day, "Problem loading image"); + elm_box_pack_start(view->box, view->img); + evas_object_show(view->img); + + view->lb_day = elm_label_add(view->box); + elm_object_text_set(view->lb_day, "Main view"); + evas_object_size_hint_weight_set(view->lb_day, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + elm_box_pack_end(view->box, view->lb_day); + evas_object_show(view->lb_day); + + elm_layout_content_set(me->layout, MAINVIEW, view->box); +} + +static void +_build_calendar_view(Menu *me) +{ + Calview *view = me->cal_view; + + //Main box image = elm_image_add(win); + + view->box = elm_box_add(me->nf); + elm_box_horizontal_set(view->box, EINA_FALSE); + elm_box_homogeneous_set(view->box, EINA_TRUE); + + view->calendar = elm_calendar_add(me->nf); + evas_object_size_hint_weight_set(view->calendar, EVAS_HINT_FILL, EVAS_HINT_FILL); + evas_object_size_hint_align_set(view->calendar, 0.5, 0.5); + elm_box_pack_end(view->box, view->calendar); + evas_object_show(view->calendar); + + view->lb_cal = elm_label_add(view->box); + elm_object_text_set(view->lb_cal, "The calendar view"); + evas_object_size_hint_weight_set(view->lb_cal, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + elm_box_pack_end(view->box, view->lb_cal); + evas_object_show(view->lb_cal); + + elm_layout_content_set(me->layout, MAINVIEW, view->box); +} // End of_build_calendar_view + +static void +_build_date_view(Menu *me) +{ + Dateview *view = me->date_view; + + //Main box image = elm_image_add(win); + + view->box = elm_box_add(me->nf); + elm_box_horizontal_set(view->box, EINA_FALSE); + elm_box_homogeneous_set(view->box, EINA_TRUE); + + view->datetime = elm_datetime_add(me->nf); + //evas_object_size_hint_weight_set(view->datetime, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + evas_object_size_hint_align_set(view->datetime, EVAS_HINT_FILL, 0.5); + elm_box_pack_end(view->box, view->datetime); + evas_object_show(view->datetime); + + view->lb_date = elm_label_add(view->box); + elm_object_text_set(view->lb_date, "The calendar view"); + evas_object_size_hint_weight_set(view->lb_date, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + elm_box_pack_end(view->box, view->lb_date); + evas_object_show(view->lb_date); + + elm_layout_content_set(me->layout, MAINVIEW, view->box); +} // End of_build_calendar_view + + + +Each function creates a view and stores it in the application data. +\\ +//**__next__: **//[[/tutorial/menu/hidden_menu|Creating the Hidden Menu]] diff --git a/pages/tutorial/menu/hidden_menu.txt b/pages/tutorial/menu/hidden_menu.txt new file mode 100644 index 000000000..7565ca4e6 --- /dev/null +++ b/pages/tutorial/menu/hidden_menu.txt @@ -0,0 +1,94 @@ +~~Title: Hidden Menu Tutorial~~ +//**__previous__: **//[[/tutorial/menu/basic_ui|Creating the Basic UI]] +==== Creating a Hidden Menu ==== + +Add a new function called ''_build_side_menu'' to create the side Menu toolbar and +add some items to it. This function takes the application data as parameter +and stores the built menu in the sidemenu attribute of the structure. + + +static void _build_side_menu(Menu *me, Evas_Object *win) +{ + Tbarmenu *sidemenu = calloc(1, sizeof(Tbarmenu)); + me->sidemenu = sidemenu; + + sidemenu->tb = elm_toolbar_add(win); + + elm_toolbar_shrink_mode_set(sidemenu->tb, ELM_TOOLBAR_SHRINK_EXPAND); + elm_toolbar_transverse_expanded_set(sidemenu->tb, EINA_TRUE); + + elm_toolbar_item_append(sidemenu->tb, ICON_DIR"/home.svg", "Home", _menu_item_selected_cb, me); + elm_toolbar_item_append(sidemenu->tb, ICON_DIR"/account.svg", "Account", NULL, NULL); + elm_toolbar_item_append(sidemenu->tb, ICON_DIR"/contact.svg", "Friends", NULL, NULL); + elm_toolbar_item_append(sidemenu->tb, ICON_DIR"/clock.svg", "Clock", _menu_item_selected_cb, me); + elm_toolbar_homogeneous_set(sidemenu->tb, EINA_FALSE); + evas_object_show(sidemenu->tb); + elm_object_part_content_set(me->layout, "menu/side", sidemenu->tb); + elm_toolbar_horizontal_set(sidemenu->tb, EINA_FALSE); + elm_toolbar_item_selected_set(elm_toolbar_first_item_get(sidemenu->tb), EINA_TRUE); +} + + +The side menu is created but hidden by default, to make it appear the user must +click Home button. + +By default the Basic EDC UI application creates a function ''keydown_cb'' to +handle the key down events. In ''elm_main'' an ''ecore_event_handler_add'' +function is called with the ''ECORE_EVENT_KEY_DOWN'' macro and with +''keydown_cb'' as callback. In this callback, the ''KEY_END'' event puts the +window on the lower state. + + +keydown_cb(void *data , int type , void *event) +{ + Evas_Object *win = data; + Ecore_Event_Key *ev = event; + if (!strcmp(ev->keyname, KEY_END)) + { + /* Let window go to hide state. */ + elm_win_lower(win); + } + + return ECORE_CALLBACK_DONE; +} + + +The key name of menu button is ''XF86Send''. Add the menu button key press +handling to the ''keydown_cb''. The menu is shown on the first press and +hidden it on the second press. Use ''Eina_Bool sdmenu_up'' on the application +data to store the menu status during the application execution. If +''me->sdmenu_up'' is ''EINA_TRUE'' the menu is visible. + +A program ''animation,menu_side'' is defined in the ''.edc'' theme file. This +program is run when the signal ''show,sidemenu'' is received with the source +''MenuButton''. Also the program who hides the side menu is defined and is +called ''animation,menu_side,hide'' which start on signal ''hide,sidemenu''. + +Test side menu status by sending the signals using ''elm_object_signal_emit'' + + +static Eina_Bool +keydown_cb(void *data , int type , void *event) +{ + Menu *me = data; + Ecore_Event_Key *ev = event; + if (!strcmp(ev->keyname, "XF86Send")) + { + if (me->sdmenu_up == EINA_TRUE) + { + // If the menu is visible send a "hide,sidemenu" signal + elm_object_signal_emit(me->layout, "hide,sidemenu", "MenuButton"); + // Store the new menu status (hidden). + me->sdmenu_up = EINA_FALSE; + } + else + { + // If the menu is not visible send a "show,sidemenu" signal + elm_object_signal_emit(me->layout, "show,sidemenu", "MenuButton"); + // Store the new menu status (hidden). + me->sdmenu_up = EINA_TRUE; + } + } + return ECORE_CALLBACK_DONE; +} + diff --git a/pages/tutorial/menu/structure.txt b/pages/tutorial/menu/structure.txt new file mode 100644 index 000000000..4a9000bb1 --- /dev/null +++ b/pages/tutorial/menu/structure.txt @@ -0,0 +1,74 @@ +~~Title: Application "Structure" Menu Tutorial~~ +==== Defining the Application "Structure" ==== + +Define the structure of the menu application: + + +typedef struct _Menu +{ + Evas_Object* layout; // The "edje" layout + Evas_Object *nf; // The Naviframe to handle the views + Tbarmenu *menu; // The main menu + Tbarmenu *sidemenu; // The side menu + Mainview *main_view; // The main view + Calview *cal_view; // The calendar view + Dateview *date_view; // The date and time view + Setview *settings_view; //The settings view + + Eina_Bool sdmenu_up; // A bool variable to keep the side menu status +} Menu; + + +This structure contains some specific variables for the views and the menus. + +Define the main view by using the structure ''mainview'', it is composed of a +''box'' (the main container), an image img, and a label ''lb_main''. + + +typedef struct _Mainview +{ + Evas_Object *box; //The main container of the view + Evas_Object *img; //An image + Evas_Object *lb_day; //A label +} Mainview; + + +The date view is very similar, it contains a ''box'', a ''datetime'' widget +and a label ''lb_date''. + + +typedef struct _Dateview +{ + Evas_Object *box; //The main container of the view + Evas_Object *datetime; //A datetime widget + Evas_Object *lb_date; //A label +} Dateview; + + +The last view is the calendar, it contains a ''box'', a ''calendar'' and a +label ''lb_cal''. + + +typedef struct _Calview +{ + Evas_Object *box; //The main container of the view + Evas_Object *calendar; //A calendar widget + Evas_Object *lb_cal; //A label widget +} Calview; + + +The last members of the application structure are the 2 menus. The main menu +is fixed and visible, and the side menu is hidden on application starts. These +menus are represented by the ''Tbarmenu'' structure. + + +typedef struct _Tbarmenu +{ + Evas_Object *tb; //The toolbar + Elm_Object_Item *submenu; //The submenu item +} Tbarmenu; + +\\ +//**__The whole code__ : **// {{/code_c/tutorial/menu/structure_menu.h}} +\\ +//**__next__: **//[[/tutorial/menu/theme|Defining the Application Theme]] diff --git a/pages/tutorial/menu/theme.txt b/pages/tutorial/menu/theme.txt new file mode 100644 index 000000000..0c2712814 --- /dev/null +++ b/pages/tutorial/menu/theme.txt @@ -0,0 +1,170 @@ +~~Title: Application Theme Menu Tutorial~~ +//**__previous__: **//[[/tutorial/menu/structure|Defining the Application "Structure"]] +==== Defining the Application Theme ==== + +After the structure is defined, define the UI. In this tutorial, Basic EDC UI +Application is used. + +This application structure is based on this skeleton: + + +{{ :menu_skeleton.png?direct&193 |Menu skeleton }} + +The window and the layout are set by the Basic EDC UI Application skeleton. +Setup the containers for widgets and views. + +Create the ''menu/main'' ''SWALLOW'' part in the ''.edc'' file. + + +part +{ + name: "menu/main"; + type: SWALLOW; + description + { + state: "default" 0.0; + rel1.relative: 1.0 0.0; + rel2.relative: 1.0 1.0; + } + description + { + state: "up" 0.0; + rel1.relative: 0.0 0.01; + rel2.relative: 1.0 0.19; + + } +} //End menu/main + + +This part has two descriptions, one for the real position named ''up'' and +another out of the screen as the default position. Create these states to +animate the menu on application start. The animation is run by +''animation,menu_main''. + + +program +{ + name: "animation,menu_main"; + source: ""; + signal: "load"; + action: STATE_SET "up" 1.0; + target: "menu/main"; + transition: LINEAR 0.5; +} // END animation,menu_main + + +For more information about animations, see the [[/coming_soon|Effects tutorial]]. + +Create another container for the views. This container is also a "SWALLOW" +part. + + +part +{ + name: "view/main"; + type: SWALLOW; + description + { + state: "default" 0.0; + rel1.relative: 1.0 1.0; + rel2.relative: 1.0 1.0; + } + description + { + state: "up" 0.0; + rel1.relative: 0.0 1.01; + rel1.to: "menu/main"; + rel2.relative: 1.0 1.0; + color: 0 255 0 255; + } +} // END view/main + + +This part has also two descriptions for animation purpose, like the main_menu +part. + +The program: + +program +{ + name: "animation,view_main"; + source: ""; + signal: "load"; + action: STATE_SET "up" 1.0; + target: "view/main"; + transition: LINEAR 0.2; +} //END animation,view_mainĀ² + + +The last container is the side menu called ''menu/side''. + + +part +{ + name: "menu/side"; + type: SWALLOW; + description + { + state: "default" 0.0; + rel1.relative: -0.3 0.0; + rel2.relative: -0.3 1.0; + color: 255 0 0 255; + } + description + { + state: "up" 0.0; + rel1.relative: 0.0 0.2; + rel2.relative: 0.10 1.0; + color: 255 0 0 255; + } +} //END menu/side + + +By default, this container is hidden. Clicking menu button makes it appear. +The second description places the container on the left of the screen. Here is +the program to run animation: + + +program +{ + name: "animation,menu_side"; + source: "MenuButton"; + signal: "show,sidemenu"; + action: STATE_SET "up" 1.0; + target: "menu/side"; + transition: LINEAR 0.2; +} //END animation,menu_side + + +This program runs when it receives an event called ''show,sidemenu'' from +''MenuButton'' source. + +Create a program that does the opposite and starts when it receives a signal +called ''hide,menu_side'' from ''MenuButton'' source. + + +program +{ + name: "animation,menu_side,hide"; + source: "MenuButton"; + signal: "hide,sidemenu"; + action: STATE_SET "default" 1.0; + target: "menu/side"; + transition: LINEAR 0.2; +} //END animation,menu_side,hide + +program +{ + name: "animation,menu_side"; + source: "MenuButton"; + signal: "show,sidemenu"; + action: STATE_SET "up" 1.0; + target: "menu/side"; + transition: LINEAR 0.2; +} //END animation,menu_side + + +\\ +//**__The whole code__ : **// {{/code_c/tutorial/menu/menu.edc}} +\\ +//**__next__: **//[[/tutorial/menu/basic_ui|Creating the Basic UI]] diff --git a/pages/tutorial/menu_tutorial.txt b/pages/tutorial/menu_tutorial.txt new file mode 100644 index 000000000..f83e5182a --- /dev/null +++ b/pages/tutorial/menu_tutorial.txt @@ -0,0 +1,20 @@ +~~Title: Menu Tutorial~~ +==== Menu Tutorial ==== + +This tutorial shows how to add menus to the application. The example code +creates an application with 3 views, these views are showed by an interaction +with a menu bar, placed on the top of the application. The application has +also a hidden menu that appears only when the menu button is pressed. + +=== Table of contents === + + * [[/tutorial/menu/structure|Defining the Application "Structure"]] + * [[/tutorial/menu/theme|Defining the Application Theme]] + * [[/tutorial/menu/basic_ui|Creating the Basic UI]] + * [[/tutorial/menu/hidden_menu|Creating the Hidden Menu]] + +Menu example : + +{{ :menu.png?direct }} +\\ +//**__The whole code__: **//{{/code_c/tutorial/menu/structure.h}} {{/code_c/tutorial/menu/menu.edc}} {{/code_c/tutorial/menu/menu.c}}