DIGILIGHT
menu.c
См. документацию.
1 
14 #include <avr/io.h>
15 #include <avr/eeprom.h>
16 #include "avr_helper.h"
17 #include <stdlib.h>
18 #include "setup.h"
19 #include "global.h"
20 #include "menu.h"
21 #include "lcd.h"
22 #include "lcd_show.h"
23 #include "control.h"
24 #include "power_control.h"
25 
26 __flash const menu_t *current_menu = &main_menu;
27 static uint16_t menu_timeout = MENU_TIMEOUT;
28 
29 void reset_menu_timeout(void){
30  menu_timeout = MENU_TIMEOUT;
31 }
32 
33 uint8_t lock_current_menu_item = 0;
34 
35 void show_press_encoder_msg(int32_t d){
36  show_rpad_str_p(1, PSTR("PUSH ENCODER"));
37 }
38 
39 static void paint_menu_item(uint8_t mi){
40  int32_t tmp;
41 
42  show_rpad_str_p(0, current_menu->items[mi].name);
43  switch(current_menu->items[mi].type){
44  case MI_SCALE:
45  show_scale(1, *(current_menu->items[mi].u8));
46  break;
47  case MI_ONOFF:
48  show_rpad_str_p(1, *(current_menu->items[mi].onoff) == 0 ? PSTR("OFF") : PSTR("ON"));
49  break;
50  case MI_U8:
51  tmp = *(current_menu->items[mi].u8);
52  show_number(tmp);
53  break;
54  case MI_S8:
55  tmp = *(current_menu->items[mi].s8);
56  show_number(tmp);
57  break;
58  case MI_U16:
59  tmp = *(current_menu->items[mi].u16);
60  show_number(tmp);
61  break;
62  case MI_S16:
63  tmp = *(current_menu->items[mi].s16);
64  show_number(tmp);
65  break;
66  case MI_SUBMENU:
67  show_press_encoder_msg(0);
68  break;
69  case MI_USER:
70  if(current_menu->items[mi].paint != NULL){
71  current_menu->items[mi].paint(current_menu->items[mi].data);
72  break;
73  }
74  default:
75  center_str(1, "");
76  }
77 }
78 
79 static void edit_menu_item(uint8_t mi, int8_t delta){
80  int16_t tmp;
81  switch(current_menu->items[mi].type){
82  case MI_SCALE:
83  case MI_U8:
84  tmp = *(current_menu->items[mi].u8);
85  tmp += delta * current_menu->items[mi].step;
86  if(tmp > current_menu->items[mi].u8_max)
87  tmp = current_menu->items[mi].u8_max;
88  if(tmp < current_menu->items[mi].u8_min)
89  tmp = current_menu->items[mi].u8_min;
90  *(current_menu->items[mi].u8) = tmp;
91  break;
92  case MI_S8:
93  tmp = *(current_menu->items[mi].s8);
94  tmp += delta * current_menu->items[mi].step;
95  if(tmp > current_menu->items[mi].s8_max)
96  tmp = current_menu->items[mi].s8_max;
97  if(tmp < current_menu->items[mi].s8_min)
98  tmp = current_menu->items[mi].s8_min;
99  *(current_menu->items[mi].s8) = tmp;
100  break;
101  case MI_U16:
102  tmp = *(current_menu->items[mi].u16);
103  tmp += delta * current_menu->items[mi].step;
104  if(tmp > current_menu->items[mi].u16_max)
105  tmp = current_menu->items[mi].u16_max;
106  if(tmp < current_menu->items[mi].u16_min)
107  tmp = current_menu->items[mi].u16_min;
108  *(current_menu->items[mi].u16) = tmp;
109  break;
110  case MI_S16:
111  tmp = *(current_menu->items[mi].s16);
112  tmp += delta * current_menu->items[mi].step;
113  if(tmp > current_menu->items[mi].s16_max)
114  tmp = current_menu->items[mi].s16_max;
115  if(tmp < current_menu->items[mi].s16_min)
116  tmp = current_menu->items[mi].s16_min;
117  *(current_menu->items[mi].s16) = tmp;
118  break;
119  case MI_ONOFF:
120  *(current_menu->items[mi].onoff) = ! *(current_menu->items[mi].onoff);
121  break;
122  case MI_USER:
123  if(current_menu->items[mi].edit != NULL){
124  current_menu->items[mi].edit(delta, current_menu->items[mi].data);
125  }
126  break;
127  default:
128  break;
129  }
130 }
131 
137  static uint8_t menu_item;
138  uint8_t handled = 1;
139  menu_result_t result = MENU_CONTINUE;
140 
141  paint_menu_item(menu_item);
142 
143  control_t ctrl = get_control();
144 
145  switch(ctrl){
146  case CTRL_ENC_BTN:
147  // Действие
148  if(current_menu->items[menu_item].type == MI_USER){
149  if(current_menu->items[menu_item].action != NULL){
150  result = current_menu->items[menu_item].action(current_menu->items[menu_item].data);
151  if(result == MENU_CONTINUE)
152  break;
153  else
154  goto exit_menu;
155  }
156  } else if(current_menu->items[menu_item].type == MI_SUBMENU){
157  if(current_menu->items[menu_item].submenu != NULL){
158  current_menu = current_menu->items[menu_item].submenu;
159  menu_item = 0;
160  }
161  break;
162  }
163  result = MENU_DONE;
164  goto exit_menu;
165  case CTRL_ENC_UP:
166  edit_menu_item(menu_item, 1);
167  break;
168  case CTRL_ENC_DN:
169  edit_menu_item(menu_item, -1);
170  break;
171  case CTRL_BTN_SET:
172  if(lock_current_menu_item) break;
173  menu_item++;
174  if(menu_item >= current_menu->item_count) menu_item = 0;
175  break;
176  default:
177  handled = 0;
178  if(!--menu_timeout){
179  // выход из меню по таймауту
180  result = MENU_DONE;
181  exit_menu:
182  update_config();
183  menu_timeout = MENU_TIMEOUT;
184  menu_item = 0;
185  current_menu = &main_menu;
187  }
188  }
189 
190  if(handled) menu_timeout = MENU_TIMEOUT;
191  return result;
192 }
uint8_t * u8
для байта без знака - ссылка на переменную
Definition: menu.h:54
item_t type
всегда - вариант пункта
Definition: menu.h:43
void center_str(uint8_t row, char *src)
вывод строки по центру дисплея
Definition: lcd_show.c:123
uint16_t * u16
для int без знака - ссылка на переменную
Definition: menu.h:60
control_t get_control(void)
получение управляющей команды
Definition: control.c:133
void(* edit)(int8_t d, uint16_t data)
для пользовательского - изменяет, что хочет
Definition: menu.h:80
void show_scale(uint8_t row, uint8_t val)
отображение псевдографической горизонтальной шкалы
Definition: lcd_show.c:201
Вспомогательные эффекты ЖКИ
Общие описания
int16_t * s16
для int - ссылка на переменную
Definition: menu.h:72
menu_result_t(* action)(uint16_t d)
для пользовательского - вернет 0, если надо закончить меню
Definition: menu.h:82
__flash const void * submenu
для субменю - ссылка на субменю
Definition: menu.h:46
void reset_power_timeout(void)
сброс таймаута автоотключения питания
Definition: power_control.c:49
uint16_t u16_min
для int без знака - допустимый минимум
Definition: menu.h:61
Управление питанием
uint16_t data
для пользовательского - дополнительные данные
Definition: menu.h:83
int8_t s8_min
для байта - допустимый минимум
Definition: menu.h:67
uint16_t u16_max
для int без знака - допустимый максимум
Definition: menu.h:62
uint8_t * onoff
для флажка - ссылка на флаг
Definition: menu.h:48
Настройки цветомузыки
void(* paint)(int32_t d)
для пользовательского - выводит 2-ю строку
Definition: menu.h:81
uint8_t u8_min
для байта без знака - допустимый минимум
Definition: menu.h:55
int16_t s16_max
для int - допустимый максимум
Definition: menu.h:74
uint8_t step
для чисел и шкалы - шаг изменения при редактировании
Definition: menu.h:51
__flash const char * name
всегда - название пункта
Definition: menu.h:42
int8_t * s8
для байта - ссылка на переменную
Definition: menu.h:66
описания урганов управления
меню
Definition: menu.h:102
uint8_t u8_max
для байта без знака - допустимый максимум
Definition: menu.h:56
int16_t s16_min
для int - допустимый минимум
Definition: menu.h:73
void update_config(void)
обновление EEPROM с параметрами настройки
Definition: setup.c:87
int8_t s8_max
для байта - допустимый максимум
Definition: menu.h:68
void show_number(int32_t num)
вывод десятичного числа
Definition: lcd_show.c:100
void show_rpad_str_p(uint8_t line, const char *src)
вывод строки из flash с очисткой дисплея справа
Definition: lcd_show.c:135