2024-02-02 08:53:17 +00:00
|
|
|
// 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
|
2024-02-05 09:57:39 +00:00
|
|
|
#define MENU_CMD_HANDLER_RET bool
|
2024-02-02 08:53:17 +00:00
|
|
|
#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;
|
2024-02-04 02:30:09 +00:00
|
|
|
int sel_ = -1;
|
|
|
|
bool check_item_ = false;
|
|
|
|
bool need_ret_parent_ = true;
|
2024-02-02 08:53:17 +00:00
|
|
|
|
|
|
|
int find_item(const char* text);
|
|
|
|
|
|
|
|
public:
|
2024-02-04 02:30:09 +00:00
|
|
|
dev_menu(bool check_item = false, bool need_ret_parent = true);
|
2024-02-02 08:53:17 +00:00
|
|
|
|
|
|
|
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);
|
2024-02-04 02:30:09 +00:00
|
|
|
void set_need_return_parent(bool need);
|
2024-02-02 08:53:17 +00:00
|
|
|
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
|
|
|
|
//
|
2024-02-04 02:30:09 +00:00
|
|
|
// sel - to receive current setting index
|
|
|
|
//
|
2024-02-02 08:53:17 +00:00
|
|
|
// Return: current menu index
|
2024-02-04 02:30:09 +00:00
|
|
|
int get_menu_text(std::vector<std::string>& text, int& sel);
|
2024-02-02 08:53:17 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
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;
|
2024-02-05 09:57:39 +00:00
|
|
|
volatile bool ready_enable_ = true;
|
2024-02-02 08:53:17 +00:00
|
|
|
SIZE font_size_ = {16, 16};
|
|
|
|
|
|
|
|
std::map<int, MENU_CMD_CALLBACK> handler_;
|
|
|
|
std::unique_ptr<Lcd> lcd_;
|
|
|
|
std::unique_ptr<KeyMonitor> keyboard_;
|
|
|
|
|
2024-02-05 09:57:39 +00:00
|
|
|
bool do_menu_command(int cmd); // return whether should hold UI ?
|
2024-02-02 08:53:17 +00:00
|
|
|
void init(void);
|
|
|
|
void clear(void);
|
|
|
|
void refresh_lcd(bool cur_at_top);
|
|
|
|
void move_to(bool next);
|
|
|
|
void enter(void);
|
2024-02-05 09:57:39 +00:00
|
|
|
int get_string_font(const char* text, uint8_t** ptr, uint8_t* rows, uint8_t* cols);
|
2024-02-02 08:53:17 +00:00
|
|
|
|
|
|
|
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;
|
2024-02-05 09:57:39 +00:00
|
|
|
|
|
|
|
MUTEX ready_lck_;
|
|
|
|
chronograph ready_watch_;
|
|
|
|
DISPDATA ready_;
|
|
|
|
safe_fifo<DISPDATA> disp_data_;
|
2024-02-02 08:53:17 +00:00
|
|
|
std::unique_ptr<std::thread> disp_thrd_;
|
|
|
|
void thread_display(void);
|
2024-02-05 09:57:39 +00:00
|
|
|
void display_ready(void);
|
|
|
|
void set_ready_status_enabled(bool enable);
|
|
|
|
void reset_ready_watch(void);
|
|
|
|
int get_ready_watch_ms(void);
|
2024-02-02 08:53:17 +00:00
|
|
|
|
|
|
|
public:
|
|
|
|
ui_mgr();
|
|
|
|
protected:
|
|
|
|
virtual ~ui_mgr();
|
|
|
|
|
|
|
|
public:
|
|
|
|
void key_event(int key);
|
|
|
|
};
|