unsigned char menu(void){
struct menu_pos *pos;
unsigned char i;
unsigned int k;
struct menu_struct *curr;
unsigned char have_checkbox = 0;
unsigned char menu_offset = 0, max_offset = 0;
curr = menu_get();
max_offset = curr->num/9;
for(i=0;i<curr->num;i++){
if(curr->list[i].type == M_CHECKBOX){
have_checkbox = 1;
break;
}
}
if(!curr->notnew) GLCD_Clear(); //jak !ind to duże prawdopodobieństwo że to świeże menu
curr->notnew = 1;
while(curr->list[curr->ind].type == 0 && curr->ind < curr->num-1) curr->ind++; //type==0 czyli to tylko pozycja opisowa i nic w niej nie robimy
tick = 1;
for(;;){
k = klawiatura();
if(!k && !get_tick()) continue; //wyświetl resztę menu tylko co 100 przejść funkcji, albo, gdy coś naciśnięto
wdt_reset();
cursor(4, 0); //wyświetlanie tytułu
blackbg = 2;
puttext_P(curr->title);
blackbg = 0;
switch(k){ //naciśnięcia klaw. wspólne dla wszystkich pozycji
case K_U:
do { //znajdź najbliższą type!=0 w górę
curr->ind--;
if(curr->ind<0) curr->ind=curr->num-1;
} while(!curr->list[curr->ind].type);
break;
case K_D:
do { //... w dół
curr->ind++;
if(curr->ind >= curr->num) curr->ind = 0;
} while(!curr->list[curr->ind].type);
break;
case K_ESC: menu_pop(); GLCD_Clear(); tick = 1; return 0;
}
if(max_offset){
if(curr->ind > menu_offset*9 + 8){ // nie mieścimy się, wychodzimy poza koniec ekranu
menu_offset++;
}
if(curr->ind < menu_offset*9){ // poza początek
menu_offset--;
}
}
/*cursor(0,8);
disp_num(curr->ind); clearline();*/ // pokazuj numer bieżącej pozycji w wierszu 8
i = menu_offset * 9;
pos = curr->list + menu_offset * 9;
unsigned char max_i;
if(menu_offset < max_offset){
max_i = 9;
} else {
max_i = curr->num;
}
for(;i < max_i; i++){
if(i==curr->ind) switch(k){ //naciśnięcia klaw. dla konkretnej pozycji
case K_L:
if(func_table[pos->type].ch_func){
func_table[pos->type].ch_func(pos, 0);
return 1;
}
break;
case K_R:
if(func_table[pos->type].ch_func){
func_table[pos->type].ch_func(pos, 1);
return 1;
}
break;
case K_OK:
if(func_table[pos->type].ok_func){
func_table[pos->type].ok_func(pos);
return 1;
}
break;
}
unsigned char y_ind = i+1-menu_offset*9;
cursor(0, y_ind);
if(have_checkbox
&& pos
->type
!= M_CHECKBOX
){ putchar(' '); }
if(func_table[pos->type].disp_func) func_table[pos->type].disp_func(pos, i==curr->ind); //funkcja wyświetlająca dla pozycji
clear_to(X_MAX-1);
if(menu_offset && y_ind == 1){
} else if(menu_offset < max_offset && y_ind == 9){
} else {
}
pos++;
}
for(; i<menu_offset*9 + 9; i++){
cursor(0, i+1-menu_offset*9);
clearline();
}
}
}