6581a5f2a4
Numerous changes updating modes, rig, config, everything... don't think this ones gonna work first time through...
300 lines
7.2 KiB
C++
300 lines
7.2 KiB
C++
//======================================================================
|
|
// menu.h
|
|
//======================================================================
|
|
|
|
#ifndef __menu_h__
|
|
#define __menu_h__
|
|
|
|
//#include "etl_profile.h"
|
|
//#include <ArduinoSTL.h>
|
|
#include "etl/array.h"
|
|
#include "etl/cstring.h"
|
|
#include "etl/delegate.h"
|
|
//#include <vector>
|
|
#include <initializer_list>
|
|
#include "rig.h"
|
|
|
|
// 16 characters on display
|
|
const int MAX_TEXT_LEN = 16;
|
|
const int max_text_len = 16;
|
|
const char MENU_SELECTED_CHAR = '>';
|
|
const char menu_selection_char = '>';
|
|
|
|
const char blankLine[17] = " ";
|
|
|
|
typedef etl::string<max_text_len> Menu_string;
|
|
|
|
//======================================================================
|
|
// Menu_item
|
|
//======================================================================
|
|
|
|
class Menu_item {
|
|
public:
|
|
Menu_item(): parent_link(nullptr) {}
|
|
virtual ~Menu_item() {}
|
|
|
|
virtual const Menu_string& title() const = 0;
|
|
virtual void get_title(Menu_string& outstr) const = 0;
|
|
virtual void get_text(Menu_string& outstr) const = 0;
|
|
|
|
virtual Menu_item* select() = 0;
|
|
virtual Menu_item* altSelect() = 0;
|
|
virtual Menu_item* exit() = 0;
|
|
virtual Menu_item* prev() = 0;
|
|
virtual Menu_item* next() = 0;
|
|
|
|
void set_parent(Menu_item* item) {
|
|
parent_link = item;
|
|
}
|
|
|
|
const Menu_item* parent() const {
|
|
return parent_link;
|
|
}
|
|
|
|
private:
|
|
Menu_item* parent_link;
|
|
};
|
|
|
|
//======================================================================
|
|
// List_menu
|
|
//======================================================================
|
|
|
|
const int MAX_LISTMENU_TITLE_LEN = 15;
|
|
|
|
//const int max_size_of_list_menu = 20; // arbitrary...
|
|
|
|
template <const size_t SIZE>
|
|
class List_menu : public Menu_item {
|
|
public:
|
|
List_menu(const char* title, etl::array<const Menu_item*, SIZE> items):
|
|
Menu_item(), list_title(title), list_items(items), index(0) {
|
|
for (auto element : list_items) {
|
|
element->set_parent(this);
|
|
}
|
|
}
|
|
|
|
virtual const Menu_string& title() const {
|
|
return list_title;
|
|
}
|
|
|
|
virtual void get_title(Menu_string& outstr) const {
|
|
outstr.assign(list_title);
|
|
}
|
|
|
|
virtual void get_text(Menu_string& outstr) const {
|
|
list_items[index]->get_text(outstr);
|
|
}
|
|
|
|
virtual Menu_item* select()
|
|
{
|
|
return list_items[index];
|
|
}
|
|
|
|
virtual Menu_item* altSelect()
|
|
{
|
|
return this;
|
|
}
|
|
|
|
virtual Menu_item* exit()
|
|
{
|
|
return parent();
|
|
}
|
|
|
|
virtual Menu_item* prev()
|
|
{
|
|
if (--index < 0) {
|
|
index += list_items.size();
|
|
}
|
|
return this;
|
|
}
|
|
|
|
virtual Menu_item* next()
|
|
{
|
|
index = ++index % list_items.size();
|
|
return this;
|
|
}
|
|
|
|
private:
|
|
Menu_string list_title;
|
|
etl::array<const Menu_item*, SIZE> list_items;
|
|
int index;
|
|
};
|
|
|
|
//======================================================================
|
|
// Config_parm
|
|
//======================================================================
|
|
|
|
typedef etl::delegate<void(void)> Update_func;
|
|
|
|
template<typename T>
|
|
class Config_parm : public Menu_item {
|
|
public:
|
|
Config_parm(const char* title, T& parm, T min, T max, T step, Update_func f):
|
|
Menu_item(), parm_title(title), parameter(parm), min_val(min), max_val(max), step_val(step), on_update(f) {}
|
|
|
|
virtual const Menu_string& title() const {
|
|
return parm_title;
|
|
}
|
|
|
|
virtual void get_title(Menu_string& outstr) const {
|
|
outstr.assign(parm_title);
|
|
}
|
|
|
|
virtual void get_text(Menu_string& outstr) const = 0;
|
|
|
|
virtual Menu_item* select() {
|
|
on_update();
|
|
return parent();
|
|
}
|
|
|
|
virtual Menu_item* altSelect() {
|
|
on_update();
|
|
return this;
|
|
}
|
|
|
|
virtual Menu_item* exit() {
|
|
return parent();
|
|
}
|
|
|
|
virtual Menu_item* prev() {
|
|
parameter -= step_val;
|
|
if (parameter < min_val) {
|
|
parameter = min_val;
|
|
}
|
|
return this;
|
|
}
|
|
|
|
virtual Menu_item* next() {
|
|
parameter += step_val;
|
|
if (parameter > max_val) {
|
|
parameter = max_val;
|
|
}
|
|
return this;
|
|
}
|
|
|
|
const T& value() const {
|
|
return parameter;
|
|
}
|
|
|
|
private:
|
|
Menu_string parm_title;
|
|
T& parameter;
|
|
T min_val;
|
|
T max_val;
|
|
T step_val;
|
|
Update_func on_update;
|
|
};
|
|
|
|
class Parm_uint8 : public Config_parm<uint8_t> {
|
|
public:
|
|
Parm_uint8(const char* title, uint8_t& parm, uint8_t min, uint8_t max, uint8_t step, Update_func f):
|
|
Config_parm<uint8_t>(title, parm, min, max, step, f) {}
|
|
|
|
virtual void get_text(Menu_string& outstr) const {
|
|
snprintf(outstr.data(), max_text_len+1, "%-*.*s %3d", max_text_len-4, max_text_len-4, title().data(), value());
|
|
}
|
|
};
|
|
|
|
class Parm_float : public Config_parm<float> {
|
|
public:
|
|
Parm_float(const char* title, float& parm, float min, float max, float step, Update_func f):
|
|
Config_parm<float>(title, parm, min, max, step, f) {}
|
|
|
|
virtual void get_text(Menu_string& outstr) const {
|
|
snprintf(outstr.data(), max_text_len+1, "%-*.*s %5.2f", max_text_len-6, max_text_len-6, title().data(), value());
|
|
}
|
|
};
|
|
|
|
//======================================================================
|
|
|
|
const char modeID[] = {'s', 'S', 'c', 'C', 'd', 'D', 't', 'T'};
|
|
const char* const filterID[static_cast<int>(rig_mode::count)][static_cast<int>(rx_filter::count)] = {
|
|
{"2.8", "2.4", "1.8"}, // SSB
|
|
{"1.0", "500", "250"}, // CW
|
|
{"2.8", "2.4", "500"}, // DIG
|
|
};
|
|
|
|
//======================================================================
|
|
// Top_menu
|
|
//======================================================================
|
|
|
|
|
|
class Main_menu : public Menu_item {
|
|
public:
|
|
Main_menu(basic_rig& rig): menu_title("Main Menu"), rig_(rig), adjust_tx(false) {}
|
|
|
|
virtual const Menu_string& title() const {
|
|
return menu_title;
|
|
}
|
|
|
|
virtual void get_title(Menu_string& outstr) const {
|
|
outstr.assign(menu_title);
|
|
}
|
|
|
|
virtual void get_text(Menu_string& outstr) const {
|
|
char text[max_text_len+1];
|
|
sprintf(text, "%1cR:%3s %1cT:%3s ",
|
|
adjust_tx ? ' ' : menu_selection_char,
|
|
filterID[static_cast<size_t>(rig_.get_rig_mode())][static_cast<size_t>(rig_.get_rx_filter())],
|
|
adjust_tx ? menu_selection_char : ' ',
|
|
rig_.is_ssb_mode() && rig_.config().ssb.comp.enabled ? "CMP" : " ");
|
|
outstr.assign(text);
|
|
}
|
|
|
|
virtual Menu_item* select() {
|
|
adjust_tx = !adjust_tx;
|
|
return this;
|
|
}
|
|
|
|
virtual Menu_item* altSelect() {
|
|
return this;
|
|
}
|
|
|
|
virtual Menu_item* exit() {
|
|
return nullptr;
|
|
}
|
|
|
|
virtual Menu_item* prev() {
|
|
if (adjust_tx) {
|
|
if (rig_.is_ssb_mode()) {
|
|
rig_.config().ssb.comp.enabled = !rig_.config().ssb.comp.enabled;
|
|
if (rig_.config().ssb.comp.enabled)
|
|
rig_.enable_comp();
|
|
else
|
|
rig_.disable_comp();
|
|
}
|
|
} else {
|
|
rig_.prev_rx_filter();
|
|
}
|
|
return this;
|
|
}
|
|
|
|
virtual Menu_item* next() {
|
|
if (adjust_tx) {
|
|
if (rig_.is_ssb_mode()) {
|
|
rig_.config().ssb.comp.enabled = !rig_.config().ssb.comp.enabled;
|
|
if (rig_.config().ssb.comp.enabled)
|
|
rig_.enable_comp();
|
|
else
|
|
rig_.disable_comp();
|
|
}
|
|
} else {
|
|
rig_.next_rx_filter();
|
|
}
|
|
return this;
|
|
}
|
|
|
|
private:
|
|
Menu_string menu_title;
|
|
basic_rig& rig_;
|
|
bool adjust_tx;
|
|
};
|
|
|
|
extern const Menu_item* audio_config_menu;
|
|
|
|
#endif
|
|
|
|
//======================================================================
|
|
// EOF
|
|
//======================================================================
|