summaryrefslogtreecommitdiff
path: root/pages/develop/legacy/tutorial/menu/basic_ui.txt
blob: 8b8d10acb47fd6fe3ea2884543ba364aab7badef (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
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
[[/develop/legacy/program_guide/containers_pg|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.

<code c>
// 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;
</code>

Use ''_free_menu_cb'' callback function to free the memory:

<code c>
evas_object_smart_callback_add(win, "delete,request", _free_menu_cb, me);
</code>

<code c>
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();
}
</code>

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''.


<code c>
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);
}
</code>

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.

<code c>
#define ICON_DIR "<path_to_icon_directory>"
</code>

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:

<code c>
_mycallback(void *data, Evas_Object *obj, void *event_info)
</code>

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.

<code c>
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);
}
</code>

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.

<code c>
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

</code>

Each function creates a view and stores it in the application data.
\\
//**__next__: **//[[/tutorial/menu/hidden_menu|Creating the Hidden Menu]]