00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #include <stdio.h>
00027 #include <stdlib.h>
00028
00029 #include <aversive.h>
00030
00031 #include "menu.h"
00032
00034 char * menu_get_name(struct menu * m) {
00035 if (!m)
00036 return NULL;
00037
00038 if ( m->type == MENU_TYPE_MENU ||
00039 m->type == MENU_TYPE_ROOT ||
00040 m->type == MENU_TYPE_FCT_HDR )
00041 return (char *)m->data;
00042
00043 return NULL;
00044 }
00045
00047 uint8_t menu_get_type(struct menu * m) {
00048 if (!m)
00049 return MENU_TYPE_UNKNOWN;
00050
00051 return m->type;
00052 }
00053
00054 static uint8_t menu_is_a_submenu(struct menu * m)
00055 {
00056 if (!m)
00057 return 0;
00058
00059 return ( m->type == MENU_TYPE_MENU || m->type == MENU_TYPE_ROOT );
00060 }
00061
00062
00064 uint8_t menu_call_fct(struct menu * m) {
00065 void (*f)(void *);
00066
00067 if (!m)
00068 return 1;
00069
00070 if ( m->type != MENU_TYPE_FCT_HDR )
00071 return 1;
00072
00073 f = (void (*)(void *) )(m+1)->data;
00074
00075 if ( (m+1)->type != MENU_TYPE_FCT_PTR || f == NULL )
00076 return 1;
00077
00078 if ( (m+2)->type != MENU_TYPE_FCT_DATA )
00079 return 1;
00080
00081 f( (m+2)->data );
00082 return 0;
00083 }
00084
00085
00087 struct menu * menu_get_previous(struct menu * m) {
00088 int8_t level = 0;
00089
00090 if (!m)
00091 return NULL;
00092
00093 if(m->type == MENU_TYPE_ROOT)
00094 return NULL;
00095
00096 m --;
00097 while ( level >= 0 ) {
00098
00099 if ( m->type == MENU_TYPE_ROOT ) {
00100 return NULL;
00101 }
00102 if ( m->type == MENU_TYPE_END ) {
00103 level ++;
00104 }
00105 if ( m->type == MENU_TYPE_MENU ) {
00106 level --;
00107 }
00108 if ( level == 0 ) {
00109 if ( m->type == MENU_TYPE_FCT_HDR ||
00110 m->type == MENU_TYPE_MENU ) {
00111 return m;
00112 }
00113 }
00114 m--;
00115 }
00116 return NULL;
00117 }
00118
00120 struct menu * menu_get_next(struct menu * m) {
00121 int8_t level = 0;
00122
00123 if (!m)
00124 return NULL;
00125
00126 if(m->type == MENU_TYPE_ROOT)
00127 return NULL;
00128
00129 if ( m->type == MENU_TYPE_MENU ) {
00130 level ++;
00131 }
00132
00133 m ++;
00134 while ( level >= 0 ) {
00135
00136 if ( level == 0 ) {
00137 if ( m->type == MENU_TYPE_FCT_HDR ||
00138 m->type == MENU_TYPE_MENU ) {
00139 return m;
00140 }
00141 }
00142 if ( m->type == MENU_TYPE_END ) {
00143 level --;
00144 }
00145 if ( m->type == MENU_TYPE_MENU ) {
00146 level ++;
00147 }
00148 m++;
00149 }
00150 return NULL;
00151 }
00152
00154 struct menu * menu_get_parent(struct menu * m)
00155 {
00156 struct menu * ret;
00157
00158 if (!m)
00159 return NULL;
00160
00161
00162 if(m->type == MENU_TYPE_ROOT)
00163 return NULL;
00164
00165 do {
00166 ret = m;
00167 } while ( (m=menu_get_previous(ret)) ) ;
00168
00169
00170 ret--;
00171 if ( menu_is_a_submenu(ret) )
00172 return ret;
00173 else
00174 return NULL;
00175 }
00176
00178 struct menu * menu_get_first_son(struct menu * m)
00179 {
00180 if (!m)
00181 return NULL;
00182
00183 if (menu_is_a_submenu(m)) {
00184 return m+1;
00185 }
00186 else return NULL;
00187 }
00188
00190 struct menu * menu_get_sub(struct menu * m, uint8_t num) {
00191 if (!m)
00192 return NULL;
00193
00194 m = menu_get_first_son(m);
00195 while(m && num) {
00196 num --;
00197 m = menu_get_next(m);
00198 }
00199 return m;
00200 }
00201
00203 uint8_t menu_get_sub_howmany(struct menu * m) {
00204 uint8_t num=0;
00205
00206 if (!m)
00207 return 0;
00208
00209 m = menu_get_first_son(m);
00210 while(m) {
00211 num ++;
00212 m = menu_get_next(m);
00213 }
00214 return num;
00215 }
00216
00217
00219 struct menu * menu_left(struct menu * m)
00220 {
00221 struct menu * ret;
00222
00223 if (!m)
00224 return NULL;
00225
00226 if ( (ret = menu_get_parent(m)) )
00227 return ret;
00228 else
00229 return m;
00230 }
00231
00235 struct menu * menu_right(struct menu * m)
00236 {
00237 struct menu * ret ;
00238 if (!m)
00239 return NULL;
00240
00241 if ( (ret=menu_get_first_son(m)) )
00242 return ret;
00243
00244 menu_call_fct(m);
00245
00246 return m;
00247 }
00248
00250 struct menu * menu_up(struct menu * m)
00251 {
00252 struct menu * ret;
00253
00254 if (!m)
00255 return NULL;
00256
00257
00258 if ( (ret=menu_get_previous(m)) )
00259 return ret;
00260
00261
00262 if ( ! (ret = menu_get_next(m) ) )
00263 return m;
00264
00265
00266 do {
00267 ret = m;
00268 } while ( (m=menu_get_next(ret)) ) ;
00269
00270 return ret;
00271 }
00272
00274 struct menu * menu_down(struct menu * m)
00275 {
00276 struct menu * ret;
00277
00278 if (!m)
00279 return NULL;
00280
00281
00282 if ( (ret=menu_get_next(m)) )
00283 return ret;
00284
00285
00286 if ( ! (ret = menu_get_previous(m) ) )
00287 return m;
00288
00289
00290 do {
00291 ret = m;
00292 } while ( (m=menu_get_previous(ret)) ) ;
00293
00294 return ret;
00295 }
00296
00297
00299 struct menu * menu_default_update(struct menu * m, char c)
00300 {
00301 struct menu * ret;
00302
00303 switch(c) {
00304 case 'b':
00305 return menu_up(m);
00306 case 'f':
00307 return menu_down(m);
00308 case 'n':
00309 return menu_right(m);
00310 case 'p':
00311 return menu_left(m);
00312 default:
00313 if(c >= '0' && c <= '9') {
00314 if ( m->type == MENU_TYPE_ROOT && c == '0' ) {
00315 ret = menu_right(m);
00316 if (ret) return ret;
00317 }
00318 else if ( (ret = menu_right(menu_get_sub(menu_get_parent(m), c-'0'))) ) {
00319 return ret;
00320 }
00321 }
00322 return m;
00323 }
00324 }
00325
00326
00328 void menu_default_display(struct menu * m)
00329 {
00330 struct menu * parent = menu_get_parent(m);
00331 struct menu * son ;
00332 uint8_t i ;
00333
00334
00335 printf("[H[J");
00336
00337 if(parent) {
00338 printf("%s\r\n", menu_get_name(parent));
00339
00340 for (i=0 ; i<menu_get_sub_howmany(parent) ; i++) {
00341 son = menu_get_sub(parent, i);
00342 if( son == m )
00343 printf("> %d: %s", i, menu_get_name(son));
00344 else
00345 printf(" %d: %s", i, menu_get_name(son));
00346 if(menu_is_a_submenu(son))
00347 printf(" -->");
00348 printf("\r\n");
00349 }
00350 }
00351 else {
00352 printf("| 0: %s -->", menu_get_name(m));
00353 }
00354 }
00355