change colors
[aversive.git] / modules / ihm / menu / menu.h
1 /*  
2  *  Copyright Droids Corporation, Microb Technology, Eirbot (2005)
3  * 
4  *  This program is free software; you can redistribute it and/or modify
5  *  it under the terms of the GNU General Public License as published by
6  *  the Free Software Foundation; either version 2 of the License, or
7  *  (at your option) any later version.
8  *
9  *  This program is distributed in the hope that it will be useful,
10  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  *  GNU General Public License for more details.
13  *
14  *  You should have received a copy of the GNU General Public License
15  *  along with this program; if not, write to the Free Software
16  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
17  *
18  *  Revision : $Id: menu.h,v 1.3.4.2 2007-05-23 17:18:15 zer0 Exp $
19  *
20  */
21
22 /**
23  *
24  * This is the documentation of the menu module.
25  * 
26  * RESUME
27  * ======
28  * 
29  * The aim of this module is to provide some simple functions to use a
30  * tree-based menu in a program. The displaying of the menu can be done
31  * in several ways: uart, lcd, ... This module tries to be independant of
32  * the way it is displayed.
33  * 
34  * MAIN FUNCTIONS
35  * ==============
36  * 
37  * The main functions that can be used are : menu_left(), menu_right(),
38  * menu_up() and menu_down(). they are used to browse the menu. Each of
39  * these functions take a pointer to a menu as an argument and return
40  * another one. The directions correspond to (one of) the natural
41  * representation of a tree.
42  * 
43  * 
44  * root ----- submenu1 ----- leaf1
45  *       |              |
46  *       |              |--- leaf2
47  *       |              |
48  *       |              |--- submenu2 ----- leaf3
49  *       |                             |
50  *       |                             |--- leaf4
51  *       |
52  *       ---- leaf5
53  * 
54  * Left goes to the parent.
55  * Right goes to the first son
56  * Up goes to the menu before, on the same level.
57  * Down goes to the menu after, on the same level.
58  * 
59  * These functions try to be tolerant : for example, doing a menu_left()
60  * on the root menu return the root menu. Doing a menu_down() on the last
61  * menu of a level returns the first menu on the same level.
62  * 
63  * The module provide one function for displaying a menu and another to
64  * do an action depending on a character. These functions can be
65  * reimplemented by the user to be more adapted to his application.
66  * 
67  * The default display function clear the screen, print the parent of the
68  * menu, then all other menus on the same level, highlighting the menu
69  * given in parameter. 
70  * 
71  * The default menu_update() function takes a character as parameter. 
72  *   - 'n' (next) is equivalent to menu_right. 
73  *   - 'p' (previous) is equivalent to menu_left. 
74  *   - 'f' (forward) is equivalent to menu_down.
75  *   - 'b' (backward) is equivalent to menu_up.
76  *   - '0', '1', ..., '9' selects the menu n on the same level.
77  * 
78  * 
79  * IMPLEMENTATION
80  * ==============
81  * 
82  * A menu is a static table of a menu element. Each menu element is a
83  * struct menu : 
84  * 
85  * struct menu {
86  *     uint8_t type;
87  *     void * data;
88  * }
89  * 
90  * An element type can be : MENU_TYPE_ROOT if the element is the root of
91  * the menu, MENU_TYPE_MENU if it is a submenu under the root,
92  * MENU_TYPE_FCT_HDR, MENU_TYPE_FCT_PTR, MENU_TYPE_FCT_DATA, to declare a
93  * leaf that executes a function, or MENU_TYPE_END to mark the end of a
94  * submenu or the end of the root menu.
95  * 
96  * For each of these types, the data field points to different things :
97  *  MENU_TYPE_ROOT     data -> (char *) title of the menu
98  *  MENU_TYPE_MENU     data -> (char *) title of the menu
99  *  MENU_TYPE_FCT_HDR  data -> (char *) title of the menu
100  *  MENU_TYPE_FCT_PTR  data -> void (*f)(void *) function that will be called
101  *  MENU_TYPE_FCT_DATA data -> (void *) parameter of this function
102  *  MENU_TYPE_END      data -> NULL
103  * 
104  * 
105  * Here is an exemple :
106  * 
107  * root ----- submenu1 ----- leaf1
108  *       |              |
109  *       |              |--- leaf2
110  *       |              |
111  *       |              |--- submenu2 ----- leaf3
112  *       |                             |
113  *       |                             |--- leaf4
114  *       |
115  *       ---- leaf5
116  * 
117  * will be represented as :
118  * 
119  *  MENU_TYPE_ROOT, "root"
120  *  MENU_TYPE_MENU, "submenu1"
121  *  MENU_TYPE_FCT_HDR, "leaf1"
122  *  MENU_TYPE_FCT_PTR, fct_leaf1
123  *  MENU_TYPE_FCT_DATA, leaf1_data
124  *  MENU_TYPE_FCT_HDR, "leaf2"
125  *  MENU_TYPE_FCT_PTR, fct_leaf2
126  *  MENU_TYPE_FCT_DATA, leaf2_data
127  *  MENU_TYPE_MENU, "submenu2"
128  *  MENU_TYPE_FCT_HDR, "leaf3"
129  *  MENU_TYPE_FCT_PTR, fct_leaf3
130  *  MENU_TYPE_FCT_DATA, leaf3_data
131  *  MENU_TYPE_FCT_HDR, "leaf4"
132  *  MENU_TYPE_FCT_PTR, fct_leaf4
133  *  MENU_TYPE_FCT_DATA, leaf4_data
134  *  MENU_TYPE_END, NULL
135  *  MENU_TYPE_END, NULL
136  *  MENU_TYPE_FCT_HDR, "leaf5"
137  *  MENU_TYPE_FCT_PTR, fct_leaf5
138  *  MENU_TYPE_FCT_DATA, leaf5_data
139  *  MENU_TYPE_END, NULL
140  * 
141  * For AVR version, all is stored in program memory. (TODO : store the
142  * menu table in program memory, currently only text is stored there)
143  */
144
145 /* Olivier MATZ, Droids-corp 2004 - 2006
146  * Implementation of a static menu
147  */
148
149 #include <aversive.h>
150
151 /**
152  * The structure that defines a menu element. 
153  * A menu is composed of several struct a this type, see the
154  * documentation for more informations 
155  */
156 struct menu {
157     uint8_t type;
158     void * data;
159 };
160
161 /* ************************************************************* */
162
163 /* Functions that you should use to move in a menu, they try
164    to never return NULL, except if param is NULL */
165
166 /** get the parent of the menu - never return NULL except if param is null */
167 struct menu * menu_left(struct menu * m);
168
169 /** get the first son number self if it does not exist, try to call
170    the fonction if it exists, never return NULL except if param is
171    null */
172 struct menu * menu_right(struct menu * m);
173
174 /** return the next menu on same level (if it is the last, go back to
175     beginning,  never return NULL except if param is null */
176 struct menu * menu_down(struct menu * m);
177
178 /** return the next menu on same level (if it is the first, go back to
179     the end, never return NULL except if param is null */
180 struct menu * menu_up(struct menu * m);
181
182
183 /* ************************************************************* */
184
185 /* Functions used to interact with the user (in and out : keyboard 
186  * and display)
187  * These functions can be reimplemented by the user to change the
188  * manner that the menu is displayed or the manner that the user
189  * moves in the menu.
190  */
191
192
193 /** move in the menu, depending on the action (the character c) */
194 struct menu * menu_default_update(struct menu * m, char c);
195
196 /** default function to display a menu, you can reimplement it */
197 void menu_default_display(struct menu * m);
198      
199
200 /* ************************************************************* */
201
202 /* Functions that can be usefull, but warning : some of these return
203  * a NULL pointer, that need to be handled */
204
205 /** return name of a menu, if the type is correct */
206 char * menu_get_name(struct menu * m);
207
208 /** return type of a menu */
209 uint8_t menu_get_type(struct menu * m);
210
211 /** call the function described by the menu, and return 0 on
212     success */
213 uint8_t menu_call_fct(struct menu * m);
214
215 /** get previous menu on same level, return NULL if no one */
216 struct menu * menu_get_previous(struct menu * m);
217
218 /** get next menu on same level, return NULL if no one */
219 struct menu * menu_get_next(struct menu * m);
220
221 /** get the parent of the menu - return NULL if no parent */
222 struct menu * menu_get_parent(struct menu * m);
223
224 /** return first son or NULL if there is no son */
225 struct menu * menu_get_first_son(struct menu * m);
226
227 /** get the submenu 'num' -> can return NULL if does not exist */
228 struct menu * menu_get_sub(struct menu * m, uint8_t num);
229
230 /** return number of submenus in a menu */
231 uint8_t menu_get_sub_howmany(struct menu * m);
232
233
234 /* ************************************************************* */
235
236 /* macros used to declare a menu */
237
238 #define MENU_TYPE_ROOT      0
239 #define MENU_TYPE_MENU      1
240 #define MENU_TYPE_FCT_HDR   2
241 #define MENU_TYPE_FCT_PTR   3
242 #define MENU_TYPE_FCT_DATA  4
243 #define MENU_TYPE_END       5
244 #define MENU_TYPE_UNKNOWN 255 
245
246 #define MENU_ROOT(text) { MENU_TYPE_ROOT, (void *)text }
247
248 #define MENU_START(text) { MENU_TYPE_MENU, (void *)text }
249
250 #define MENU_END() { MENU_TYPE_END, NULL }
251
252 #define MENU_FCT(text, f, data)       \
253  { MENU_TYPE_FCT_HDR, (void *)text }, \
254  { MENU_TYPE_FCT_PTR, (void *)f },    \
255  { MENU_TYPE_FCT_DATA, (void *)data }
256
257