125 lines
3.1 KiB
C
125 lines
3.1 KiB
C
|
// device liquid crystal display menu
|
||
|
//
|
||
|
// Date: 2024-01-31
|
||
|
//
|
||
|
// Keyboard layout: Four buttons
|
||
|
//
|
||
|
// Enter - to access current selection
|
||
|
//
|
||
|
// Up - to select previous item
|
||
|
//
|
||
|
// Down - to select next item
|
||
|
//
|
||
|
// Stop - to stop scanning right now
|
||
|
#pragma once
|
||
|
|
||
|
#include <base/utils.h>
|
||
|
#include <functional>
|
||
|
#include <string>
|
||
|
#include <vector>
|
||
|
#include <map>
|
||
|
#include <memory>
|
||
|
#include <thread>
|
||
|
|
||
|
#define MENU_ID_RETURN -1 // ID of menu item that return to parent
|
||
|
#define LINK_DEFINE(x, y) x##y
|
||
|
#define MEMNU_CMD_HANDLER_PARAM dev_menu* menu, int id
|
||
|
#define MENU_CMD_HANDLER_RET void
|
||
|
#define MENU_CMD_CALLBACK std::function<MENU_CMD_HANDLER_RET(MEMNU_CMD_HANDLER_PARAM)>
|
||
|
|
||
|
class dev_menu : public refer
|
||
|
{
|
||
|
dev_menu* parent_ = nullptr;
|
||
|
|
||
|
typedef struct _menu_item
|
||
|
{
|
||
|
std::string text;
|
||
|
bool leaf;
|
||
|
union
|
||
|
{
|
||
|
int id; // valid on leaf
|
||
|
dev_menu *child; // valid on !leaf
|
||
|
};
|
||
|
}MITEM;
|
||
|
std::vector<MITEM> items_;
|
||
|
int cur_ = 0;
|
||
|
|
||
|
int find_item(const char* text);
|
||
|
|
||
|
public:
|
||
|
dev_menu();
|
||
|
|
||
|
protected:
|
||
|
virtual ~dev_menu();
|
||
|
|
||
|
void set_parent(dev_menu* parent);
|
||
|
|
||
|
public:
|
||
|
bool add_menu(const char* text, int id);
|
||
|
bool add_menu(const char* text, dev_menu* submenu);
|
||
|
bool remove_menu(const char* text);
|
||
|
bool move_to(bool next); // true - move to next, false - move to previous. if at end position of move direction, return false
|
||
|
bool select(const char* txt);
|
||
|
void reset_pos(void);
|
||
|
|
||
|
// Function: access current menu
|
||
|
//
|
||
|
// Parameter: id - to receive ID of current menu item if leaf, fill '-1' if a submenu
|
||
|
//
|
||
|
// Return: current menu, user should call 'release' after use
|
||
|
dev_menu* enter(int* id);
|
||
|
|
||
|
// Function: get all menus text
|
||
|
//
|
||
|
// Parameter: text - to receive the menu text
|
||
|
//
|
||
|
// Return: current menu index
|
||
|
int get_menu_text(std::vector<std::string>& text);
|
||
|
};
|
||
|
|
||
|
|
||
|
class KeyMonitor;
|
||
|
class Lcd;
|
||
|
class ui_mgr : public refer
|
||
|
{
|
||
|
dev_menu* root_ = nullptr;
|
||
|
dev_menu* cur_ = nullptr;
|
||
|
volatile bool menu_mode_ = false; // whether LCD is displaying menu
|
||
|
volatile bool run_ = true;
|
||
|
SIZE font_size_ = {16, 16};
|
||
|
|
||
|
std::map<int, MENU_CMD_CALLBACK> handler_;
|
||
|
std::unique_ptr<Lcd> lcd_;
|
||
|
std::unique_ptr<KeyMonitor> keyboard_;
|
||
|
|
||
|
void do_menu_command(int cmd);
|
||
|
void init(void);
|
||
|
void clear(void);
|
||
|
void refresh_lcd(bool cur_at_top);
|
||
|
void move_to(bool next);
|
||
|
void enter(void);
|
||
|
int get_string_font(const char* text, uint8_t** ptr);
|
||
|
|
||
|
typedef struct _disp_data
|
||
|
{
|
||
|
uint8_t x;
|
||
|
uint8_t y;
|
||
|
uint8_t rows;
|
||
|
uint8_t cols;
|
||
|
uint8_t cnt; // 0 to clear
|
||
|
uint8_t mask;
|
||
|
uint8_t *ptr[16];
|
||
|
}DISPDATA;
|
||
|
safe_fifo<DISPDATA> disp_data_;
|
||
|
std::unique_ptr<std::thread> disp_thrd_;
|
||
|
void thread_display(void);
|
||
|
|
||
|
public:
|
||
|
ui_mgr();
|
||
|
protected:
|
||
|
virtual ~ui_mgr();
|
||
|
|
||
|
public:
|
||
|
void key_event(int key);
|
||
|
};
|