123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256 |
- /*
- * menu.c
- *
- * Created on: 1 февр. 2022 г.
- * Author: radioman
- */
- #include <stdlib.h>
- #include <stdio.h>
- #include <string.h>
- #include "menu.h"
- #include "ssd1306.h"
- #include "preferences.h"
- static const char *menu_template[] = {\
- "A, 0, 0, Dose rate",
- "A, 0, 0, Total dose",
- "A, 0, 0, Up time",
- "A, 0, 0, Debug",
- "D, 0, 0, Settings",
- "D, 0, 1, Sound",
- "P, 1, 2, Volume",
- "P, 2, 2, Tone",
- "P, 3, 2, Buttons",
- "B, 0, 2, Back",
- "D, 0, 1, Alarm",
- "D, 0, 2, Dose rate alarm",
- "R, 4, 3, OFF",
- "R, 4, 3, 0.5 uSv/h",
- "R, 4, 3, 1 uSv/h",
- "R, 4, 3, 10 uSv/h",
- "R, 4, 3, 100 uSv/h",
- "R, 4, 3, 1 mSv/h",
- "R, 4, 3, 10 mSv/h",
- "R, 4, 3, 100 mSv/h",
- "R, 4, 3, 1 Sv/h",
- "B, 0, 3, Back",
- "D, 0, 2, Total dose alarm",
- "R, 5, 3, OFF",
- "R, 5, 3, 1 uSv",
- "R, 5, 3, 10 uSv",
- "R, 5, 3, 100 uSv",
- "R, 5, 3, 1 mSv",
- "R, 5, 3, 10 uSv",
- "R, 5, 3, 100 uSv",
- "R, 5, 3, 1 Sv",
- "R, 5, 3, 10 Sv",
- "R, 5, 3, 100 Sv",
- "B, 0, 3, Back",
- "P, 6, 2, Sound type",
- "P, 7, 2, Volume",
- "B, 0, 2, Back",
- "D, 0, 1, Energy saving",
- "P, 8, 2, Brightness",
- "P, 9, 2, Disp.off min",
- "P, 10, 2, Shutdown min",
- "B, 0, 2, Back",
- "B, 0, 1, Back",
- "A, 0, 0, Info" };
- static menu_td menu_items[sizeof(menu_template) / sizeof(char*)];
- static menu_td *menu = &menu_items[0];
- static uint8_t scroll = 0;
- extern uint8_t screen;
- char * capstring(char *dest, const char *source)
- {
- while(*source)
- {
- unsigned char c = *source++;
- // ASCII & CP1251 Cyrillic
- if((c >= 'a' && c <= 'z') || (c >= 0xe0 && c <= 0xff))
- c -= 32;
- *dest++ = c;
- }
- *dest = 0;
- return dest;
- }
- void MenuInit()
- {
- uint8_t items_total = sizeof(menu_template) / sizeof(char*);
- char type;
- int max_level = 0;
- for(int i = 0; i < items_total; i++)
- {
- menu_items[i].id = i;
- sscanf(menu_template[i], "%c, %hhu, %hhu, %[^\n]",
- &type, &(menu_items[i].pref), &(menu_items[i].level), menu_items[i].title);
- menu_items[i].type = (entry_type)type;
- if(menu_items[i].level > max_level)
- max_level = menu_items[i].level;
- }
- /* Iterating through menu levels (complicated algorithm)*/
- for(int lvl = 0; lvl <= max_level; lvl++)
- {
- /* prev - previous entry ID on current level,
- * first - ID of first entry on current level */
- int prev = 0, first = -1;
- for(int i = 0; i < items_total; i++)
- {
- if(menu_items[i].level == lvl)
- {
- if(first < 0)
- {
- prev = first = i;
- }
- else
- {
- menu_items[prev].next = &menu_items[i];
- menu_items[i].prev = &menu_items[prev];
- prev = i;
- }
- /* At levels higher than 0 we assign parent and child pointers
- * All children have the same parent at one level
- * Parent always is the closest entry on lower level */
- if(lvl > 0)
- {
- menu_items[i].parent = &menu_items[first - 1];
- menu_items[first - 1].child = &menu_items[first];
- }
- }
- /* When we reaching entry that have lower level than our last entry
- * we need to close scroll loop by assigning 'next' pointer of last entry
- * to first entry on current level and reset 'first' variable
- * Also we need to do this if it is the last cycle of whole loop */
- if((first >= 0) && ((menu_items[i].level < menu_items[prev].level) || (i == (items_total - 1))))
- {
- menu_items[first].prev = &menu_items[prev];
- menu_items[prev].next = &menu_items[first];
- first = -1;
- }
- }
- }
- }
- void MenuScroll()
- {
- scroll = 1;
- menu = menu->next;
- }
- void MenuEnter()
- {
- switch(menu->type)
- {
- case ENTRY_DIR:
- menu = menu->child;
- break;
- case ENTRY_ACTION:
- screen = menu->id;
- //PrefSetValue(menu->pref, menu->id);
- //*(prefs[menu->pref].prefptr) = menu->id;
- break;
- case ENTRY_PREF:
- PrefIncValue(menu->pref);
- // *(prefs[menu->pref].prefptr) = (*(prefs[menu->pref].prefptr) +
- // prefs[menu->pref].step) % (prefs[menu->pref].max_val + 1);
- break;
- case ENTRY_BACK:
- menu = menu->parent;
- break;
- case ENTRY_CHECK:
- PrefSetValue(menu->pref, PrefGetValue(menu->pref) ^ 1);
- //*(prefs[menu->pref].prefptr) ^= 1;
- break;
- case ENTRY_RADIO:
- PrefSetValue(menu->pref, menu->id - menu->parent->child->id);
- //*(prefs[menu->pref].prefptr) = menu->id - menu->parent->child->id;
- break;
- }
- }
- void PrintMenuHeader()
- {
- char tempstr[30];
- if(menu->parent == NULL)
- strcpy(tempstr, "MAIN MENU");
- else
- capstring(tempstr, menu->parent->title);
- ssd1306_Line(0, 0, 127, 0, White);
- ssd1306_SetCursor(0, 1);
- ssd1306_WriteString(" ", Font_7x10, Black);
- ssd1306_SetCursor(64 - ((strlen(tempstr) * 7) / 2), 1);
- ssd1306_WriteString(tempstr, Font_7x10, Black);
- ssd1306_Line(0, 10, 127, 10, Black);
- }
- char * FormatEntryText(menu_td *mn, char * buf)
- {
- if(mn->type == ENTRY_PREF)
- {
- sprintf(buf, "%-12s -%.2d-", mn->title, PrefGetValue(mn->pref));
- }
- else if(mn->type == ENTRY_RADIO)
- {
- if(PrefGetValue(mn->pref) == (mn->id - mn->parent->child->id))
- sprintf(buf, "[%s]", mn->title);
- else
- sprintf(buf, "%s", mn->title);
- }
- else
- {
- strcpy(buf, mn->title);
- }
- return buf;
- }
- void MenuShow()
- {
- static int x = 0, y = 0, an_steps = 0;
- char tempstr[30];
- ssd1306_Fill(Black);
- /*
- ssd1306_SetCursor(1, 1);
- menu = &menu_items[1];
- sprintf(tempstr, "id: %s", menu->next->title);
- ssd1306_WriteString(tempstr, Font_7x10, White);
- */
- if(scroll)
- {
- y = 11;
- an_steps = 5;
- scroll = 0;
- }
- if(an_steps > 0)
- {
- an_steps--;
- y = (an_steps * 11) / 5;
- }
- ssd1306_SetCursor(x + 8, y + 1);
- ssd1306_WriteString(FormatEntryText(menu->prev, tempstr), Font_7x10, White);
- ssd1306_SetCursor(x + 8, y + 12);
- ssd1306_WriteString(FormatEntryText(menu, tempstr), Font_7x10, White);
- ssd1306_SetCursor(x + 8, y + 23);
- ssd1306_WriteString(FormatEntryText(menu->next, tempstr), Font_7x10, White);
- ssd1306_SetCursor(0, 12);
- if(menu->type == ENTRY_BACK)
- ssd1306_WriteChar('<', Font_7x10, White);
- else
- ssd1306_WriteChar('>', Font_7x10, White);
- PrintMenuHeader();
- ssd1306_UpdateScreen();
- }
|