mirror of
https://codeberg.org/mclemens/ubitxv6.git
synced 2024-11-02 05:27:38 -04:00
550 lines
12 KiB
C++
550 lines
12 KiB
C++
#include "menu_main_buttons.h"
|
|
|
|
#include <avr/pgmspace.h>
|
|
#include <string.h>
|
|
#include <WString.h>//F()
|
|
|
|
#include "bands.h"
|
|
#include "button.h"
|
|
#include "color_theme.h"
|
|
#include "nano_gui.h"
|
|
#include "settings.h"
|
|
#include "ubitx.h"//setFrequency
|
|
#include "utils.h"
|
|
|
|
static const unsigned int LAYOUT_VFO_LABEL_X = 0;
|
|
static const unsigned int LAYOUT_VFO_LABEL_Y = 10;
|
|
static const unsigned int LAYOUT_VFO_LABEL_WIDTH = 159;
|
|
static const unsigned int LAYOUT_VFO_LABEL_HEIGHT = 36;
|
|
static const unsigned int LAYOUT_VFO_LABEL_PITCH_X = 160;
|
|
|
|
static const unsigned int LAYOUT_MODE_TEXT_X = 0;
|
|
static const unsigned int LAYOUT_MODE_TEXT_Y = LAYOUT_VFO_LABEL_Y + LAYOUT_VFO_LABEL_HEIGHT + 1;
|
|
static const unsigned int LAYOUT_MODE_TEXT_WIDTH = 320;
|
|
static const unsigned int LAYOUT_MODE_TEXT_HEIGHT = 36;
|
|
|
|
static const unsigned int LAYOUT_BUTTON_X = 2;
|
|
static const unsigned int LAYOUT_BUTTON_Y = LAYOUT_MODE_TEXT_Y + LAYOUT_MODE_TEXT_HEIGHT + 1;
|
|
static const unsigned int LAYOUT_BUTTON_WIDTH = 60;
|
|
static const unsigned int LAYOUT_BUTTON_HEIGHT = 36;
|
|
static const unsigned int LAYOUT_BUTTON_PITCH_X = 64;
|
|
static const unsigned int LAYOUT_BUTTON_PITCH_Y = 40;
|
|
|
|
static const unsigned int LAYOUT_CW_TEXT_X = 0;
|
|
static const unsigned int LAYOUT_CW_TEXT_Y = LAYOUT_BUTTON_Y + 3*LAYOUT_BUTTON_PITCH_Y + 1;
|
|
static const unsigned int LAYOUT_CW_TEXT_WIDTH = 220;
|
|
static const unsigned int LAYOUT_CW_TEXT_HEIGHT = 36;
|
|
|
|
static const unsigned int LAYOUT_VERSION_TEXT_X = LAYOUT_CW_TEXT_X + LAYOUT_CW_TEXT_WIDTH + 1;
|
|
static const unsigned int LAYOUT_VERSION_TEXT_Y = LAYOUT_CW_TEXT_Y;
|
|
static const unsigned int LAYOUT_VERSION_TEXT_WIDTH = 320 - LAYOUT_CW_TEXT_WIDTH - 1;
|
|
static const unsigned int LAYOUT_VERSION_TEXT_HEIGHT = LAYOUT_CW_TEXT_HEIGHT;
|
|
|
|
static const unsigned int LAYOUT_TX_X = 280;
|
|
static const unsigned int LAYOUT_TX_Y = LAYOUT_MODE_TEXT_Y;
|
|
static const unsigned int LAYOUT_TX_WIDTH = 40;
|
|
static const unsigned int LAYOUT_TX_HEIGHT = 36;
|
|
|
|
void toVfoA(char* text_out, const uint16_t max_text_size);
|
|
ButtonStatus_e bsVfoA();
|
|
void osVfoA();
|
|
constexpr Button bVfoA PROGMEM = {
|
|
LAYOUT_VFO_LABEL_X + 0*LAYOUT_VFO_LABEL_PITCH_X,
|
|
LAYOUT_VFO_LABEL_Y,
|
|
LAYOUT_VFO_LABEL_WIDTH,
|
|
LAYOUT_VFO_LABEL_HEIGHT,
|
|
nullptr,
|
|
toVfoA,
|
|
bsVfoA,
|
|
osVfoA,
|
|
'A'
|
|
};
|
|
|
|
void toVfoB(char* text_out, const uint16_t max_text_size);
|
|
ButtonStatus_e bsVfoB();
|
|
void osVfoB();
|
|
constexpr Button bVfoB PROGMEM = {
|
|
LAYOUT_VFO_LABEL_X + 1*LAYOUT_VFO_LABEL_PITCH_X,
|
|
LAYOUT_VFO_LABEL_Y,
|
|
LAYOUT_VFO_LABEL_WIDTH,
|
|
LAYOUT_VFO_LABEL_HEIGHT,
|
|
nullptr,
|
|
toVfoB,
|
|
bsVfoB,
|
|
osVfoB,
|
|
'B'
|
|
};
|
|
|
|
constexpr char txtRit [] PROGMEM = "RIT";
|
|
ButtonStatus_e bsRit();
|
|
void osRit();
|
|
constexpr Button bRit PROGMEM = {
|
|
LAYOUT_BUTTON_X + 0*LAYOUT_BUTTON_PITCH_X,
|
|
LAYOUT_BUTTON_Y + 0*LAYOUT_BUTTON_PITCH_Y,
|
|
LAYOUT_BUTTON_WIDTH,
|
|
LAYOUT_BUTTON_HEIGHT,
|
|
txtRit,
|
|
nullptr,
|
|
bsRit,
|
|
osRit,
|
|
'R'
|
|
};
|
|
|
|
constexpr char txtUsb [] PROGMEM = "USB";
|
|
ButtonStatus_e bsUsb();
|
|
void osUsb();
|
|
constexpr Button bUsb PROGMEM = {
|
|
LAYOUT_BUTTON_X + 1*LAYOUT_BUTTON_PITCH_X,
|
|
LAYOUT_BUTTON_Y + 0*LAYOUT_BUTTON_PITCH_Y,
|
|
LAYOUT_BUTTON_WIDTH,
|
|
LAYOUT_BUTTON_HEIGHT,
|
|
txtUsb,
|
|
nullptr,
|
|
bsUsb,
|
|
osUsb,
|
|
'U'
|
|
};
|
|
|
|
constexpr char txtLsb [] PROGMEM = "LSB";
|
|
ButtonStatus_e bsLsb();
|
|
void osLsb();
|
|
constexpr Button bLsb PROGMEM = {
|
|
LAYOUT_BUTTON_X + 2*LAYOUT_BUTTON_PITCH_X,
|
|
LAYOUT_BUTTON_Y + 0*LAYOUT_BUTTON_PITCH_Y,
|
|
LAYOUT_BUTTON_WIDTH,
|
|
LAYOUT_BUTTON_HEIGHT,
|
|
txtLsb,
|
|
nullptr,
|
|
bsLsb,
|
|
osLsb,
|
|
'L'
|
|
};
|
|
|
|
constexpr char txtCw [] PROGMEM = "CW";
|
|
ButtonStatus_e bsCw();
|
|
void osCw();
|
|
constexpr Button bCw PROGMEM = {
|
|
LAYOUT_BUTTON_X + 3*LAYOUT_BUTTON_PITCH_X,
|
|
LAYOUT_BUTTON_Y + 0*LAYOUT_BUTTON_PITCH_Y,
|
|
LAYOUT_BUTTON_WIDTH,
|
|
LAYOUT_BUTTON_HEIGHT,
|
|
txtCw,
|
|
nullptr,
|
|
bsCw,
|
|
osCw,
|
|
'C'
|
|
};
|
|
|
|
constexpr char txtSpl [] PROGMEM = "SPL";
|
|
ButtonStatus_e bsSpl();
|
|
void osSpl();
|
|
constexpr Button bSpl PROGMEM = {
|
|
LAYOUT_BUTTON_X + 4*LAYOUT_BUTTON_PITCH_X,
|
|
LAYOUT_BUTTON_Y + 0*LAYOUT_BUTTON_PITCH_Y,
|
|
LAYOUT_BUTTON_WIDTH,
|
|
LAYOUT_BUTTON_HEIGHT,
|
|
txtSpl,
|
|
nullptr,
|
|
bsSpl,
|
|
osSpl,
|
|
'S'
|
|
};
|
|
|
|
constexpr char txt80 [] PROGMEM = "80";
|
|
ButtonStatus_e bs80();
|
|
void os80();
|
|
constexpr Button b80 PROGMEM = {
|
|
LAYOUT_BUTTON_X + 0*LAYOUT_BUTTON_PITCH_X,
|
|
LAYOUT_BUTTON_Y + 1*LAYOUT_BUTTON_PITCH_Y,
|
|
LAYOUT_BUTTON_WIDTH,
|
|
LAYOUT_BUTTON_HEIGHT,
|
|
txt80,
|
|
nullptr,
|
|
bs80,
|
|
os80,
|
|
'8'
|
|
};
|
|
|
|
constexpr char txt40 [] PROGMEM = "40";
|
|
ButtonStatus_e bs40();
|
|
void os40();
|
|
constexpr Button b40 PROGMEM = {
|
|
LAYOUT_BUTTON_X + 1*LAYOUT_BUTTON_PITCH_X,
|
|
LAYOUT_BUTTON_Y + 1*LAYOUT_BUTTON_PITCH_Y,
|
|
LAYOUT_BUTTON_WIDTH,
|
|
LAYOUT_BUTTON_HEIGHT,
|
|
txt40,
|
|
nullptr,
|
|
bs40,
|
|
os40,
|
|
'4'
|
|
};
|
|
|
|
constexpr char txt30 [] PROGMEM = "30";
|
|
ButtonStatus_e bs30();
|
|
void os30();
|
|
constexpr Button b30 PROGMEM = {
|
|
LAYOUT_BUTTON_X + 2*LAYOUT_BUTTON_PITCH_X,
|
|
LAYOUT_BUTTON_Y + 1*LAYOUT_BUTTON_PITCH_Y,
|
|
LAYOUT_BUTTON_WIDTH,
|
|
LAYOUT_BUTTON_HEIGHT,
|
|
txt30,
|
|
nullptr,
|
|
bs30,
|
|
os30,
|
|
'3'
|
|
};
|
|
|
|
constexpr char txt20 [] PROGMEM = "20";
|
|
ButtonStatus_e bs20();
|
|
void os20();
|
|
constexpr Button b20 PROGMEM = {
|
|
LAYOUT_BUTTON_X + 3*LAYOUT_BUTTON_PITCH_X,
|
|
LAYOUT_BUTTON_Y + 1*LAYOUT_BUTTON_PITCH_Y,
|
|
LAYOUT_BUTTON_WIDTH,
|
|
LAYOUT_BUTTON_HEIGHT,
|
|
txt20,
|
|
nullptr,
|
|
bs20,
|
|
os20,
|
|
'2'
|
|
};
|
|
|
|
constexpr char txt17 [] PROGMEM = "17";
|
|
ButtonStatus_e bs17();
|
|
void os17();
|
|
constexpr Button b17 PROGMEM = {
|
|
LAYOUT_BUTTON_X + 4*LAYOUT_BUTTON_PITCH_X,
|
|
LAYOUT_BUTTON_Y + 1*LAYOUT_BUTTON_PITCH_Y,
|
|
LAYOUT_BUTTON_WIDTH,
|
|
LAYOUT_BUTTON_HEIGHT,
|
|
txt17,
|
|
nullptr,
|
|
bs17,
|
|
os17,
|
|
'7'
|
|
};
|
|
|
|
constexpr char txt15 [] PROGMEM = "15";
|
|
ButtonStatus_e bs15();
|
|
void os15();
|
|
constexpr Button b15 PROGMEM = {
|
|
LAYOUT_BUTTON_X + 0*LAYOUT_BUTTON_PITCH_X,
|
|
LAYOUT_BUTTON_Y + 2*LAYOUT_BUTTON_PITCH_Y,
|
|
LAYOUT_BUTTON_WIDTH,
|
|
LAYOUT_BUTTON_HEIGHT,
|
|
txt15,
|
|
nullptr,
|
|
bs15,
|
|
os15,
|
|
'5'
|
|
};
|
|
|
|
constexpr char txt10 [] PROGMEM = "10";
|
|
ButtonStatus_e bs10();
|
|
void os10();
|
|
constexpr Button b10 PROGMEM = {
|
|
LAYOUT_BUTTON_X + 1*LAYOUT_BUTTON_PITCH_X,
|
|
LAYOUT_BUTTON_Y + 2*LAYOUT_BUTTON_PITCH_Y,
|
|
LAYOUT_BUTTON_WIDTH,
|
|
LAYOUT_BUTTON_HEIGHT,
|
|
txt10,
|
|
nullptr,
|
|
bs10,
|
|
os10,
|
|
'1'
|
|
};
|
|
|
|
constexpr char txtMenu [] PROGMEM = "\x7F";//gear icon
|
|
ButtonStatus_e bsIgnore();
|
|
void osMenu();
|
|
constexpr Button bMenu = {
|
|
LAYOUT_BUTTON_X + 3*LAYOUT_BUTTON_PITCH_X,
|
|
LAYOUT_BUTTON_Y + 2*LAYOUT_BUTTON_PITCH_Y,
|
|
LAYOUT_BUTTON_WIDTH,
|
|
LAYOUT_BUTTON_HEIGHT,
|
|
txtMenu,
|
|
nullptr,
|
|
bsIgnore,
|
|
osMenu,
|
|
'M'
|
|
};
|
|
|
|
constexpr char txtNumpad [] PROGMEM = "FRQ";
|
|
ButtonStatus_e bsIgnore();
|
|
void osNumpad();
|
|
constexpr Button bNumpad = {
|
|
LAYOUT_BUTTON_X + 4*LAYOUT_BUTTON_PITCH_X,
|
|
LAYOUT_BUTTON_Y + 2*LAYOUT_BUTTON_PITCH_Y,
|
|
LAYOUT_BUTTON_WIDTH,
|
|
LAYOUT_BUTTON_HEIGHT,
|
|
txtNumpad,
|
|
nullptr,
|
|
bsIgnore,
|
|
osNumpad,
|
|
'F'
|
|
};
|
|
|
|
static constexpr const Button *const buttons[] PROGMEM = {
|
|
&bVfoA, &bVfoB,
|
|
|
|
&bRit, &bUsb, &bLsb, &bCw, &bSpl,
|
|
&b80, &b40, &b30, &b20, &b17,
|
|
&b15, &b10, &bMenu, &bNumpad
|
|
|
|
};
|
|
|
|
const Button* const* mainMenuButtons = buttons;
|
|
const uint8_t MAIN_MENU_NUM_BUTTONS = sizeof(buttons) / sizeof(buttons[0]);
|
|
|
|
|
|
void toVfo(char* text_out, const uint16_t max_text_size, const Vfo_e vfo)
|
|
{
|
|
if(max_text_size < 2){
|
|
return;//Can't do much with that space
|
|
}
|
|
if(max_text_size < (3+10+1)){
|
|
//Give an indicator that's debuggable
|
|
text_out[0] = 'X';
|
|
text_out[1] = '\0';
|
|
return;
|
|
}
|
|
|
|
//Normal operation
|
|
if (globalSettings.splitOn){
|
|
if(vfo == globalSettings.activeVfo){
|
|
text_out[0] = 'R';
|
|
}
|
|
else{
|
|
text_out[0] = 'T';
|
|
}
|
|
}
|
|
else{
|
|
if(VFO_A == vfo){
|
|
text_out[0] = 'A';
|
|
}
|
|
else if(VFO_B == vfo){
|
|
text_out[0] = 'B';
|
|
}
|
|
else{
|
|
text_out[0] = '?';
|
|
}
|
|
}
|
|
text_out[1] = ':';
|
|
text_out[2] = ' ';
|
|
if(VFO_A == vfo){
|
|
formatFreq(globalSettings.vfoA.frequency, text_out+3, max_text_size-3, 10);
|
|
}
|
|
else if(VFO_B == vfo){
|
|
formatFreq(globalSettings.vfoB.frequency, text_out+3, max_text_size-3, 10);
|
|
}
|
|
else{
|
|
text_out[3] = '?';
|
|
text_out[4] = '\0';
|
|
}
|
|
}
|
|
|
|
ButtonStatus_e bsVfo(const Vfo_e vfo){
|
|
return (vfo == globalSettings.activeVfo) ? ButtonStatus_e::Active : ButtonStatus_e::Inactive;
|
|
}
|
|
|
|
void osVfo(const Vfo_e vfo){
|
|
globalSettings.activeVfo = vfo;
|
|
}
|
|
|
|
void toVfoA(char* text_out, const uint16_t max_text_size){
|
|
toVfo(text_out,max_text_size,Vfo_e::VFO_A);
|
|
}
|
|
ButtonStatus_e bsVfoA(){
|
|
return bsVfo(Vfo_e::VFO_A);
|
|
}
|
|
void osVfoA(){
|
|
osVfo(Vfo_e::VFO_A);
|
|
}
|
|
|
|
void toVfoB(char* text_out, const uint16_t max_text_size){
|
|
toVfo(text_out,max_text_size,Vfo_e::VFO_B);
|
|
}
|
|
ButtonStatus_e bsVfoB(){
|
|
return bsVfo(Vfo_e::VFO_B);
|
|
}
|
|
void osVfoB(){
|
|
osVfo(Vfo_e::VFO_B);
|
|
}
|
|
|
|
ButtonStatus_e bsRit(){
|
|
return globalSettings.ritOn ? ButtonStatus_e::Active : ButtonStatus_e::Inactive;
|
|
}
|
|
void osRit(){
|
|
Button button;
|
|
if(!globalSettings.ritOn){
|
|
globalSettings.ritOn = true;
|
|
globalSettings.ritFrequency = GetActiveVfoFreq();
|
|
|
|
strncpy_P(b,(const char*)F("TX: "),sizeof(b));
|
|
formatFreq(globalSettings.ritFrequency, b + strlen(b), sizeof(b)-strlen(b));
|
|
if (VFO_A == globalSettings.activeVfo){
|
|
displayText(b, LAYOUT_VFO_LABEL_X + 0*LAYOUT_VFO_LABEL_PITCH_X, LAYOUT_MODE_TEXT_Y, LAYOUT_VFO_LABEL_WIDTH, LAYOUT_MODE_TEXT_HEIGHT, COLOR_TEXT, COLOR_BACKGROUND, COLOR_BACKGROUND);
|
|
}
|
|
else{
|
|
displayText(b, LAYOUT_VFO_LABEL_X + 1*LAYOUT_VFO_LABEL_PITCH_X, LAYOUT_MODE_TEXT_Y, LAYOUT_VFO_LABEL_WIDTH, LAYOUT_MODE_TEXT_HEIGHT, COLOR_TEXT, COLOR_BACKGROUND, COLOR_BACKGROUND);
|
|
}
|
|
}
|
|
else{
|
|
globalSettings.ritOn = false;
|
|
setFrequency(globalSettings.ritFrequency);
|
|
|
|
displayFillrect(LAYOUT_MODE_TEXT_X,LAYOUT_MODE_TEXT_Y,LAYOUT_MODE_TEXT_WIDTH,LAYOUT_MODE_TEXT_HEIGHT, COLOR_BACKGROUND);
|
|
if(Vfo_e::VFO_A == globalSettings.activeVfo){
|
|
memcpy_P(&button,&bVfoA,sizeof(button));
|
|
drawButton(&button);
|
|
}
|
|
else{
|
|
memcpy_P(&button,&bVfoB,sizeof(button));
|
|
drawButton(&button);
|
|
}
|
|
}
|
|
|
|
memcpy_P(&button,&bRit,sizeof(button));
|
|
drawButton(&button);
|
|
}
|
|
|
|
void osSidebandMode(VfoMode_e mode){
|
|
SetActiveVfoMode(mode);
|
|
|
|
Button button;
|
|
memcpy_P(&button,&bUsb,sizeof(button));
|
|
drawButton(&button);
|
|
memcpy_P(&button,&bLsb,sizeof(button));
|
|
drawButton(&button);
|
|
}
|
|
|
|
ButtonStatus_e bsUsb(){
|
|
return (VfoMode_e::VFO_MODE_USB == GetActiveVfoMode()) ? ButtonStatus_e::Active : ButtonStatus_e::Inactive;
|
|
}
|
|
|
|
void osUsb(){
|
|
osSidebandMode(VfoMode_e::VFO_MODE_USB);
|
|
}
|
|
|
|
ButtonStatus_e bsLsb(){
|
|
return (VfoMode_e::VFO_MODE_LSB == GetActiveVfoMode()) ? ButtonStatus_e::Active : ButtonStatus_e::Inactive;
|
|
}
|
|
|
|
void osLsb(){
|
|
osSidebandMode(VfoMode_e::VFO_MODE_LSB);
|
|
}
|
|
|
|
ButtonStatus_e bsCw(){
|
|
return (TuningMode_e::TUNE_CW == globalSettings.tuningMode) ? ButtonStatus_e::Active : ButtonStatus_e::Inactive;
|
|
}
|
|
|
|
void osCw(){
|
|
if(TuningMode_e::TUNE_CW != globalSettings.tuningMode){
|
|
globalSettings.tuningMode = TuningMode_e::TUNE_CW;
|
|
}
|
|
else{
|
|
globalSettings.tuningMode = TuningMode_e::TUNE_SSB;
|
|
}
|
|
|
|
Button button;
|
|
memcpy_P(&button,&bCw,sizeof(button));
|
|
drawButton(&button);
|
|
}
|
|
|
|
ButtonStatus_e bsSpl(){
|
|
return globalSettings.splitOn ? ButtonStatus_e::Active : ButtonStatus_e::Inactive;
|
|
}
|
|
|
|
void osSpl(){
|
|
globalSettings.splitOn = !globalSettings.splitOn;
|
|
|
|
Button button;
|
|
memcpy_P(&button,&bSpl,sizeof(button));
|
|
drawButton(&button);
|
|
memcpy_P(&button,&bVfoA,sizeof(button));
|
|
drawButton(&button);
|
|
memcpy_P(&button,&bVfoB,sizeof(button));
|
|
drawButton(&button);
|
|
}
|
|
|
|
ButtonStatus_e bsBand(const uint8_t band){
|
|
return isFreqInBand(GetActiveVfoFreq(),band) ? ButtonStatus_e::Active : ButtonStatus_e::Inactive;
|
|
}
|
|
|
|
void osBand(const uint8_t band){
|
|
SetActiveVfoFreq(getFreqInBand(GetActiveVfoFreq(),band));
|
|
}
|
|
|
|
ButtonStatus_e bs80(){
|
|
return bsBand(80);
|
|
}
|
|
|
|
void os80(){
|
|
osBand(80);
|
|
}
|
|
|
|
ButtonStatus_e bs40(){
|
|
return bsBand(40);
|
|
}
|
|
|
|
void os40(){
|
|
osBand(40);
|
|
}
|
|
|
|
ButtonStatus_e bs30(){
|
|
return bsBand(30);
|
|
}
|
|
|
|
void os30(){
|
|
osBand(30);
|
|
}
|
|
|
|
ButtonStatus_e bs20(){
|
|
return bsBand(20);
|
|
}
|
|
|
|
void os20(){
|
|
osBand(20);
|
|
}
|
|
|
|
ButtonStatus_e bs17(){
|
|
return bsBand(17);
|
|
}
|
|
|
|
void os17(){
|
|
osBand(17);
|
|
}
|
|
|
|
ButtonStatus_e bs15(){
|
|
return bsBand(15);
|
|
}
|
|
|
|
void os15(){
|
|
osBand(15);
|
|
}
|
|
|
|
ButtonStatus_e bs10(){
|
|
return bsBand(10);
|
|
}
|
|
|
|
void os10(){
|
|
osBand(10);
|
|
}
|
|
|
|
ButtonStatus_e bsIgnore(){
|
|
return ButtonStatus_e::Stateless;
|
|
}
|
|
|
|
void osMenu(){
|
|
//TODO
|
|
//rootSettingsMenu->initMenu();
|
|
//mainmenu.active_submenu = rootSettingsMenu;
|
|
}
|
|
|
|
void osNumpad(){
|
|
//TODO
|
|
//numpadMenu->initMenu();
|
|
//mainMenu.active_submenu = numpadMenu;
|
|
}
|