diff --git a/button.cpp b/button.cpp new file mode 100644 index 0000000..ac221ac --- /dev/null +++ b/button.cpp @@ -0,0 +1,44 @@ +#include "button.h" + +#include + +#include "color_theme.h" +#include "nano_gui.h" +#include "scratch_space.h" + +void drawButton(Button* button) +{ + uint16_t tc = COLOR_INACTIVE_TEXT; + uint16_t bgc = COLOR_INACTIVE_BACKGROUND; + const uint16_t bdc = COLOR_INACTIVE_BORDER; + switch(button->status()) + { + case ButtonStatus_e::Stateless://Fallthrough intended + case ButtonStatus_e::Inactive://Fallthrough intended + default: + { + //Colors are initialized for this, so we're done + break; + } + case ButtonStatus_e::Active: + { + tc = COLOR_ACTIVE_TEXT; + bgc = COLOR_ACTIVE_BACKGROUND; + break; + } + } + + + if(nullptr != button->text){ + strncpy_P(b,button->text,sizeof(b)); + } + else if(nullptr != button->text_override){ + button->text_override(b,sizeof(b)); + } + else{ + //Something's messed up + //Serial.println(F("No text for button!")); + return; + } + displayText(b, button->x, button->y, button->w, button->h, tc, bgc, bdc); +} diff --git a/button.h b/button.h new file mode 100644 index 0000000..6aba532 --- /dev/null +++ b/button.h @@ -0,0 +1,20 @@ +#pragma once + +#include + +enum ButtonStatus_e : uint8_t { + Stateless, + Inactive, + Active +}; + +struct Button { + int16_t x, y, w, h; + const char* text;//nullptr if text_override should be used + void (*text_override)(char* text_out, const uint16_t max_text_size);//nullptr if text should be used + ButtonStatus_e (*status)();//Used for coloring and morse menu + void (*on_select)();//Action to take when selected + char morse; +}; + +void drawButton(Button* button); diff --git a/button_grid.cpp b/button_grid.cpp deleted file mode 100644 index 337621c..0000000 --- a/button_grid.cpp +++ /dev/null @@ -1,90 +0,0 @@ -#include "button_grid.h" - -#include -#include - -#include "color_theme.h" -#include "nano_gui.h" -#include "scratch_space.h" - -void drawButton(const ButtonGrid_t *const button_grid_P, - const Button *const button_P) -{ - uint16_t tc = COLOR_INACTIVE_TEXT; - uint16_t bgc = COLOR_INACTIVE_BACKGROUND; - const uint16_t bdc = COLOR_INACTIVE_BORDER; - - Button button; - memcpy_P(&button,button_P,sizeof(button)); - switch(button.status()) - { - case ButtonStatus_e::Stateless://Fallthrough intended - case ButtonStatus_e::Inactive://Fallthrough intended - default: - { - //Colors are initialized for this, so we're done - break; - } - case ButtonStatus_e::Active: - { - tc = COLOR_ACTIVE_TEXT; - bgc = COLOR_ACTIVE_BACKGROUND; - break; - } - } - - if(nullptr != button.text){ - strncpy_P(b,button.text,sizeof(b)); - } - else if(nullptr != button.text_override){ - button.text_override(b,sizeof(b)); - } - else{ - //Something's messed up - //Serial.println(F("No text for button!")); - return; - } - - ButtonGrid_t button_grid; - memcpy_P(&button_grid,button_grid_P,sizeof(button_grid)); - - uint8_t button_col = 0; - uint8_t button_row = 0; - bool found_it = false; - for(button_col = 0; button_col < button_grid.num_button_cols && !found_it; ++button_col){ - for(button_row = 0; button_row < button_grid.num_button_rows && !found_it; ++button_row){ - Button* bp; - memcpy_P(&bp,&(button_grid.buttons_P[button_row*button_grid.num_button_cols + button_col]),sizeof(bp)); - if(bp == button_P){ - found_it = true; - break; - } - } - if(found_it){ - break; - } - } - - Serial.print(button_col);Serial.print(",");Serial.print(button_row);Serial.print(" ");Serial.println(b); - displayText(b, - button_col * button_grid.button_pitch_x + button_grid.top_left_x, - button_row * button_grid.button_pitch_y + button_grid.top_left_y, - button_grid.button_width, - button_grid.button_height, - tc, bgc, bdc); -} - -void drawButtonGrid(const ButtonGrid_t *const button_grid_P) -{ - ButtonGrid_t button_grid; - memcpy_P(&button_grid,button_grid_P,sizeof(button_grid)); - - Button* bp; - for(uint8_t i = 0; i < button_grid.num_button_rows * button_grid.num_button_cols; ++i){ - memcpy_P(&bp, &(button_grid.buttons_P[i]), sizeof(bp)); - if(nullptr == bp){ - continue; - } - drawButton(button_grid_P,bp); - } -} diff --git a/button_grid.h b/button_grid.h deleted file mode 100644 index 7b27e3e..0000000 --- a/button_grid.h +++ /dev/null @@ -1,33 +0,0 @@ -#pragma once - -#include - -enum ButtonStatus_e : uint8_t { - Stateless, - Inactive, - Active -}; - -struct Button { - const char* text;//nullptr if text_override should be used - void (*text_override)(char* text_out, const uint16_t max_text_size);//nullptr if text should be used - ButtonStatus_e (*status)();//Used for coloring and morse menu - void (*on_select)();//Action to take when selected - char morse; -}; - -struct ButtonGrid_t { - int16_t top_left_x; - int16_t top_left_y; - uint16_t button_width; - uint16_t button_height; - uint16_t button_pitch_x; - uint16_t button_pitch_y; - uint8_t num_button_rows; - uint8_t num_button_cols; - const Button* const* buttons_P;//Expected to be in progmem -}; - -void drawButton(const ButtonGrid_t *const button_grid_P, - const Button *const button_P); -void drawButtonGrid(const ButtonGrid_t *const button_grid_P); diff --git a/menu_main.cpp b/menu_main.cpp index 34b68ca..8eb010b 100644 --- a/menu_main.cpp +++ b/menu_main.cpp @@ -4,7 +4,7 @@ #include #include -#include "button_grid.h" +#include "button.h" #include "color_theme.h" #include "menu_utils.h" #include "morse.h" @@ -33,9 +33,13 @@ int16_t mainMenuSelectedItemRaw = 0;//Allow negative only for easier checks on w void drawMainMenu(void) { displayClear(COLOR_BACKGROUND); - - drawButtonGrid(&mainMenuGrid); - + Button button; + Button* bp; + for(uint8_t i = 0; i < MAIN_MENU_NUM_BUTTONS; ++i){ + memcpy_P(&bp, &(mainMenuButtons[i]), sizeof(bp)); + memcpy_P(&button,bp,sizeof(button)); + drawButton(&button); + } ltoa(GetActiveVfoFreq(),b,10); morseText(b); } @@ -61,13 +65,14 @@ void mainMenuTune(int16_t knob) const uint32_t old_freq = current_freq; current_freq = new_freq; + Button button; if(Vfo_e::VFO_A == globalSettings.activeVfo){ - drawButton(&mainMenuVfoGrid,&bVfoA); + memcpy_P(&button,&bVfoA,sizeof(button)); } else{ - drawButton(&mainMenuVfoGrid,&bVfoB); + memcpy_P(&button,&bVfoB,sizeof(button)); } - + drawButton(&button); updateBandButtons(old_freq); } @@ -89,17 +94,17 @@ MenuReturn_e runMainMenu(const ButtonPress_e tuner_button, { if(mainMenuSelecting){ uint8_t menu_index = mainMenuSelectedItemRaw/MENU_KNOB_COUNTS_PER_ITEM; - endSelector(mainMenuSelectedItemRaw,&mainMenuGrid); - Button button; Button* bp; - memcpy_P(&bp,&(mainMenuGrid.buttons_P[menu_index]),sizeof(bp)); + memcpy_P(&bp,&(mainMenuButtons[menu_index]),sizeof(bp)); memcpy_P(&button,bp,sizeof(button)); + endSelector(&button); button.on_select(); } else{ initSelector(&mainMenuSelectedItemRaw, - &mainMenuGrid, + mainMenuButtons, + MAIN_MENU_NUM_BUTTONS, MorsePlaybackType_e::PlayChar); } mainMenuSelecting = !mainMenuSelecting; @@ -129,7 +134,7 @@ MenuReturn_e runMainMenu(const ButtonPress_e tuner_button, else if(ButtonPress_e::NotPressed != touch_button){ //We treat long and short presses the same, so no need to have a switch Button button; - if(findPressedButton(&mainMenuGrid,&button,touch_point)){ + if(findPressedButton(mainMenuButtons,MAIN_MENU_NUM_BUTTONS,&button,touch_point)){ button.on_select(); } else{ @@ -141,7 +146,8 @@ MenuReturn_e runMainMenu(const ButtonPress_e tuner_button, if(mainMenuSelecting){ adjustSelector(&mainMenuSelectedItemRaw, knob, - &mainMenuGrid, + mainMenuButtons, + MAIN_MENU_NUM_BUTTONS, MorsePlaybackType_e::PlayChar); } else{ diff --git a/menu_main_buttons.cpp b/menu_main_buttons.cpp index a8e396d..75fcd89 100644 --- a/menu_main_buttons.cpp +++ b/menu_main_buttons.cpp @@ -5,7 +5,7 @@ #include //F() #include "bands.h" -#include "button_grid.h" +#include "button.h" #include "color_theme.h" #include "menu_main.h" #include "menu_numpad.h" @@ -54,6 +54,10 @@ 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, @@ -65,6 +69,10 @@ 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, @@ -76,6 +84,10 @@ 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, @@ -87,6 +99,10 @@ 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, @@ -98,6 +114,10 @@ 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, @@ -109,6 +129,10 @@ 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, @@ -120,6 +144,10 @@ 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, @@ -131,6 +159,10 @@ 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, @@ -142,6 +174,10 @@ 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, @@ -153,6 +189,10 @@ 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, @@ -164,6 +204,10 @@ 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, @@ -175,6 +219,10 @@ 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, @@ -186,6 +234,10 @@ 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, @@ -197,6 +249,10 @@ 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, @@ -208,6 +264,10 @@ constexpr char txtMenu [] PROGMEM = "\x7F";//gear icon ButtonStatus_e bsIgnore(); void osMenu(); constexpr Button bMenu PROGMEM = { + 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, @@ -219,6 +279,10 @@ constexpr char txtNumpad [] PROGMEM = "FRQ"; ButtonStatus_e bsIgnore(); void osNumpad(); constexpr Button bNumpad PROGMEM = { + 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, @@ -226,39 +290,15 @@ constexpr Button bNumpad PROGMEM = { 'F' }; -const Button* const mainMenuVfoButtons [] PROGMEM = { - &bVfoA, &bVfoB -}; - -const ButtonGrid_t mainMenuVfoGrid PROGMEM = { - LAYOUT_VFO_LABEL_X, - LAYOUT_VFO_LABEL_Y, - LAYOUT_VFO_LABEL_WIDTH, - LAYOUT_VFO_LABEL_HEIGHT, - LAYOUT_VFO_LABEL_PITCH_X, - 0,//not used, since it's just one row - 1,//rows - 2,//cols - mainMenuVfoButtons -}; - const Button* const mainMenuButtons [] PROGMEM = { - &bRit, &bUsb, &bLsb, &bCw, &bSpl, - &b80, &b40, &b30, &b20, &b17, - &b15, &b10, nullptr, &bMenu, &bNumpad + &bVfoA, &bVfoB, + + &bRit, &bUsb, &bLsb, &bCw, &bSpl, + &b80, &b40, &b30, &b20, &b17, + &b15, &b10, &bMenu, &bNumpad }; -const ButtonGrid_t mainMenuGrid PROGMEM = { - LAYOUT_BUTTON_X, - LAYOUT_BUTTON_Y, - LAYOUT_BUTTON_WIDTH, - LAYOUT_BUTTON_HEIGHT, - LAYOUT_BUTTON_PITCH_X, - LAYOUT_BUTTON_PITCH_Y, - 3,//rows - 5,//cols - mainMenuButtons -}; +const uint8_t MAIN_MENU_NUM_BUTTONS = sizeof(mainMenuButtons) / sizeof(mainMenuButtons[0]); void updateBandButtons(const uint32_t old_freq) { @@ -270,7 +310,7 @@ void updateBandButtons(const uint32_t old_freq) for(uint8_t i = 0; i < sizeof(bands)/sizeof(bands[0]); ++i){ if(isFreqInBand(old_freq,bands[i]) != isFreqInBand(curr_freq,bands[i])){ memcpy_P(&button,band_buttons[i],sizeof(button)); - drawButton(&mainMenuGrid,band_buttons[i]); + drawButton(&button); morseBool(ButtonStatus_e::Active == button.status()); } } @@ -334,8 +374,11 @@ void osVfo(const Vfo_e vfo){ ltoa(GetActiveVfoFreq(),b,10); morseText(b); - drawButton(&mainMenuGrid,&bVfoA); - drawButton(&mainMenuGrid,&bVfoB); + Button button; + memcpy_P(&button,&bVfoA,sizeof(button)); + drawButton(&button); + memcpy_P(&button,&bVfoB,sizeof(button)); + drawButton(&button); updateBandButtons(old_freq); } @@ -363,6 +406,7 @@ 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(); @@ -382,14 +426,17 @@ void osRit(){ 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){ - drawButton(&mainMenuVfoGrid,&bVfoA); + memcpy_P(&button,&bVfoA,sizeof(button)); + drawButton(&button); } else{ - drawButton(&mainMenuVfoGrid,&bVfoB); + memcpy_P(&button,&bVfoB,sizeof(button)); + drawButton(&button); } } - drawButton(&mainMenuGrid,&bRit); + memcpy_P(&button,&bRit,sizeof(button)); + drawButton(&button); } void osSidebandMode(VfoMode_e mode){ @@ -397,8 +444,11 @@ void osSidebandMode(VfoMode_e mode){ setFrequency(GetActiveVfoFreq()); SaveSettingsToEeprom(); - drawButton(&mainMenuGrid,&bUsb); - drawButton(&mainMenuGrid,&bLsb); + Button button; + memcpy_P(&button,&bUsb,sizeof(button)); + drawButton(&button); + memcpy_P(&button,&bLsb,sizeof(button)); + drawButton(&button); } void updateSidebandButtons() @@ -436,7 +486,9 @@ void osCw(){ setFrequency(GetActiveVfoFreq()); - drawButton(&mainMenuGrid,&bCw); + Button button; + memcpy_P(&button,&bCw,sizeof(button)); + drawButton(&button); } ButtonStatus_e bsSpl(){ @@ -446,9 +498,13 @@ ButtonStatus_e bsSpl(){ void osSpl(){ globalSettings.splitOn = !globalSettings.splitOn; - drawButton(&mainMenuGrid,&bSpl); - drawButton(&mainMenuVfoGrid,&bVfoA); - drawButton(&mainMenuVfoGrid,&bVfoB); + 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){ @@ -462,11 +518,14 @@ void osBand(const uint8_t band){ updateSidebandButtons(); } + Button button; if(Vfo_e::VFO_A == globalSettings.activeVfo){ - drawButton(&mainMenuVfoGrid,&bVfoA); + memcpy_P(&button,&bVfoA,sizeof(button)); + drawButton(&button); } else if(Vfo_e::VFO_B == globalSettings.activeVfo){ - drawButton(&mainMenuVfoGrid,&bVfoB); + memcpy_P(&button,&bVfoB,sizeof(button)); + drawButton(&button); } updateBandButtons(old_freq); diff --git a/menu_main_buttons.h b/menu_main_buttons.h index 631e411..0e7febd 100644 --- a/menu_main_buttons.h +++ b/menu_main_buttons.h @@ -2,12 +2,12 @@ #include -#include "button_grid.h" +#include "button.h" + +extern const Button* const mainMenuButtons[]; +extern const uint8_t MAIN_MENU_NUM_BUTTONS; -extern const ButtonGrid_t mainMenuVfoGrid; -extern const ButtonGrid_t mainMenuGrid; extern const Button bVfoA; extern const Button bVfoB; - void updateBandButtons(const uint32_t old_freq); void updateSidebandButtons(); diff --git a/menu_numpad.cpp b/menu_numpad.cpp index 08e602f..847fb2e 100644 --- a/menu_numpad.cpp +++ b/menu_numpad.cpp @@ -25,7 +25,13 @@ int16_t numpadMenuSelectedItemRaw = 0;//Allow negative only for easier checks on void drawNumpad(void) { displayFillrect(0,47,320,200,COLOR_BACKGROUND); - drawButtonGrid(&numpadMenuGrid); + Button button; + Button* bp; + for(uint8_t i = 0; i < NUMPAD_MENU_NUM_BUTTONS; ++i){ + memcpy_P(&bp, &(numpadMenuButtons[i]), sizeof(bp)); + memcpy_P(&button,bp,sizeof(button)); + drawButton(&button); + } } void initNumpad(void) @@ -33,7 +39,8 @@ void initNumpad(void) numpadMenuFrequency = 0; drawNumpad(); initSelector(&numpadMenuSelectedItemRaw, - &numpadMenuGrid, + numpadMenuButtons, + NUMPAD_MENU_NUM_BUTTONS, MorsePlaybackType_e::PlayChar); } @@ -44,25 +51,18 @@ MenuReturn_e runNumpad(const ButtonPress_e tuner_button, { if(ButtonPress_e::NotPressed != tuner_button){ //We treat long and short presses the same, so no need to have a switch - - ButtonGrid_t button_grid; - memcpy_P(&button_grid,&numpadMenuGrid,sizeof(button_grid)); - uint8_t menu_index = numpadMenuSelectedItemRaw/MENU_KNOB_COUNTS_PER_ITEM; + Button button; Button* bp; - memcpy_P(&bp,&(button_grid.buttons_P[menu_index]),sizeof(bp)); - - if(nullptr != bp){ - Button button; - memcpy_P(&button,bp,sizeof(button)); - button.on_select(); - } + memcpy_P(&bp,&(numpadMenuButtons[menu_index]),sizeof(bp)); + memcpy_P(&button,bp,sizeof(button)); + button.on_select(); }//tuner_button else if(ButtonPress_e::NotPressed != touch_button){ //We treat long and short presses the same, so no need to have a switch Button button; - if(findPressedButton(&numpadMenuGrid,&button,touch_point)){ + if(findPressedButton(numpadMenuButtons,NUMPAD_MENU_NUM_BUTTONS,&button,touch_point)){ button.on_select(); } else{ @@ -73,7 +73,8 @@ MenuReturn_e runNumpad(const ButtonPress_e tuner_button, else{//Neither button input type found, so handle the knob adjustSelector(&numpadMenuSelectedItemRaw, knob, - &numpadMenuGrid, + numpadMenuButtons, + NUMPAD_MENU_NUM_BUTTONS, MorsePlaybackType_e::PlayChar); } diff --git a/menu_numpad_buttons.cpp b/menu_numpad_buttons.cpp index 2946fdd..252eaa6 100644 --- a/menu_numpad_buttons.cpp +++ b/menu_numpad_buttons.cpp @@ -27,11 +27,15 @@ uint32_t numpadMenuFrequency; #define D_STRINGIFY(x) #x #define D_STRING(x) D_STRINGIFY(x) -#define NUMBER_BUTTON_GENERATE(number) \ +#define NUMBER_BUTTON_GENERATE(number,x,y) \ constexpr char txt##number [] PROGMEM = "" D_STRING(number);\ ButtonStatus_e bs##number();\ void os##number();\ constexpr Button b##number PROGMEM = {\ + LAYOUT_BUTTON_X + x*LAYOUT_BUTTON_PITCH_X,\ + LAYOUT_BUTTON_Y + y*LAYOUT_BUTTON_PITCH_Y,\ + LAYOUT_BUTTON_WIDTH,\ + LAYOUT_BUTTON_HEIGHT,\ txt##number,\ nullptr,\ bsNumpad,\ @@ -43,20 +47,28 @@ ButtonStatus_e bsNumpad(void){ return ButtonStatus_e::Stateless; } -NUMBER_BUTTON_GENERATE(1); -NUMBER_BUTTON_GENERATE(2); -NUMBER_BUTTON_GENERATE(3); -NUMBER_BUTTON_GENERATE(4); -NUMBER_BUTTON_GENERATE(5); -NUMBER_BUTTON_GENERATE(6); -NUMBER_BUTTON_GENERATE(7); -NUMBER_BUTTON_GENERATE(8); -NUMBER_BUTTON_GENERATE(9); -NUMBER_BUTTON_GENERATE(0); + +// 1 2 3 Ok +// 4 5 6 0 <- +// 7 8 9 Can +NUMBER_BUTTON_GENERATE(1,0,0); +NUMBER_BUTTON_GENERATE(2,1,0); +NUMBER_BUTTON_GENERATE(3,2,0); +NUMBER_BUTTON_GENERATE(4,0,1); +NUMBER_BUTTON_GENERATE(5,1,1); +NUMBER_BUTTON_GENERATE(6,2,1); +NUMBER_BUTTON_GENERATE(7,0,2); +NUMBER_BUTTON_GENERATE(8,1,2); +NUMBER_BUTTON_GENERATE(9,2,2); +NUMBER_BUTTON_GENERATE(0,3,1); constexpr char txtOk [] PROGMEM = "OK"; void osOk(); constexpr Button bOk PROGMEM = { + LAYOUT_BUTTON_X + 4*LAYOUT_BUTTON_PITCH_X, + LAYOUT_BUTTON_Y + 0*LAYOUT_BUTTON_PITCH_Y, + LAYOUT_BUTTON_WIDTH, + LAYOUT_BUTTON_HEIGHT, txtOk, nullptr, bsNumpad, @@ -67,6 +79,10 @@ constexpr Button bOk PROGMEM = { constexpr char txtBackspace [] PROGMEM = "<-"; void osBackspace(); constexpr Button bBackspace PROGMEM = { + LAYOUT_BUTTON_X + 4*LAYOUT_BUTTON_PITCH_X, + LAYOUT_BUTTON_Y + 1*LAYOUT_BUTTON_PITCH_Y, + LAYOUT_BUTTON_WIDTH, + LAYOUT_BUTTON_HEIGHT, txtBackspace, nullptr, bsNumpad, @@ -77,6 +93,10 @@ constexpr Button bBackspace PROGMEM = { constexpr char txtCancel [] PROGMEM = "Can"; void osCancel(); constexpr Button bCancel PROGMEM = { + LAYOUT_BUTTON_X + 4*LAYOUT_BUTTON_PITCH_X, + LAYOUT_BUTTON_Y + 2*LAYOUT_BUTTON_PITCH_Y, + LAYOUT_BUTTON_WIDTH, + LAYOUT_BUTTON_HEIGHT, txtCancel, nullptr, bsNumpad, @@ -86,22 +106,10 @@ constexpr Button bCancel PROGMEM = { //Declare in menu select order, not graphical order const Button* const numpadMenuButtons [] PROGMEM = { - &b1, &b2, &b3, nullptr, &bOk, - &b4, &b5, &b6, &b0, &bBackspace, - &b7, &b8, &b9, nullptr, &bCancel -}; - -const ButtonGrid_t numpadMenuGrid PROGMEM = { - LAYOUT_BUTTON_X, - LAYOUT_BUTTON_Y, - LAYOUT_BUTTON_WIDTH, - LAYOUT_BUTTON_HEIGHT, - LAYOUT_BUTTON_PITCH_X, - LAYOUT_BUTTON_PITCH_Y, - 3,//rows - 5,//cols - numpadMenuButtons + &b1, &b2, &b3, &b4, &b5, &b6, &b7, &b8, &b9, &b0, + &bOk, &bBackspace, &bCancel }; +const uint8_t NUMPAD_MENU_NUM_BUTTONS = sizeof(numpadMenuButtons)/sizeof(numpadMenuButtons[0]); void updateCurrentEnteredFrequency(void) { diff --git a/menu_numpad_buttons.h b/menu_numpad_buttons.h index c813437..a7d555e 100644 --- a/menu_numpad_buttons.h +++ b/menu_numpad_buttons.h @@ -2,9 +2,10 @@ #include -#include "button_grid.h" +#include "button.h" -extern const ButtonGrid_t numpadMenuGrid; +extern const Button* const numpadMenuButtons[]; +extern const uint8_t NUMPAD_MENU_NUM_BUTTONS; extern const uint32_t NUMPAD_MENU_EXIT_FREQ; extern uint32_t numpadMenuFrequency; diff --git a/menu_utils.cpp b/menu_utils.cpp index dfda9e2..d5fcf6e 100644 --- a/menu_utils.cpp +++ b/menu_utils.cpp @@ -2,80 +2,40 @@ #include -#include "button_grid.h" +#include "button.h" #include "color_theme.h" #include "morse.h" #include "nano_gui.h" #include "utils.h" -bool findPressedButton(const ButtonGrid_t *const button_grid_P, +bool findPressedButton(const Button* const* buttons, + const uint8_t num_buttons, Button *const button_out, const Point touch_point) { - ButtonGrid_t button_grid; - memcpy_P(&button_grid,button_grid_P,sizeof(button_grid)); - - if((touch_point.x < button_grid.top_left_x) - ||(touch_point.y < button_grid.top_left_y) - ||(touch_point.x > (int16_t)button_grid.button_pitch_x * button_grid.num_button_cols) - ||(touch_point.y > (int16_t)button_grid.button_pitch_y * button_grid.num_button_rows)){ - //touch point was outside the button grid - return false; - } - - uint8_t row = (touch_point.x - button_grid.top_left_x) / button_grid.button_pitch_x; - uint8_t col = (touch_point.y - button_grid.top_left_y) / button_grid.button_pitch_y; - int16_t x_max = (col * button_grid.button_pitch_x) + button_grid.button_width; - int16_t y_max = (row * button_grid.button_pitch_y) + button_grid.button_height; - if((touch_point.x > x_max) - ||(touch_point.y > y_max)){ - //touch point was outside of the button - return false; - } - Button* bp; - memcpy_P(&bp,&(button_grid.buttons_P[row * button_grid.num_button_cols + col]),sizeof(bp)); - if(nullptr == bp){ - //no button there - return false; + for(uint16_t i = 0; i < num_buttons; ++i){ + memcpy_P(&bp,&(buttons[i]),sizeof(bp)); + memcpy_P(button_out,bp,sizeof(*button_out)); + if((button_out->x <= touch_point.x) + &&(touch_point.x <= button_out->x + button_out->w) + &&(button_out->y <= touch_point.y) + &&(touch_point.y <= button_out->y + button_out->h)){ + return true; + } } - memcpy_P(button_out,bp,sizeof(*button_out)); - return true; + return false; } -void indexToRowCol(const ButtonGrid_t *const button_grid, - const int8_t index, - uint8_t *const row_out, - uint8_t *const col_out) +void movePuck(const Button *const b_old, + const Button *const b_new) { - *row_out = index / button_grid->num_button_cols; - *col_out = index % button_grid->num_button_cols; -} - -void movePuck(const ButtonGrid_t *const button_grid, - const int8_t old_index, - const int8_t new_index) -{ - if(-1 != old_index){ - uint8_t row; - uint8_t col; - indexToRowCol(button_grid,old_index,&row,&col); - displayRect(button_grid->top_left_x + button_grid->button_pitch_x * col, - button_grid->top_left_y + button_grid->button_pitch_y * row, - button_grid->button_width, - button_grid->button_height, - COLOR_INACTIVE_BORDER); + if(nullptr != b_old){ + displayRect(b_old->x,b_old->y,b_old->w,b_old->h,COLOR_INACTIVE_BORDER); } - if(-1 != new_index){ - uint8_t row; - uint8_t col; - indexToRowCol(button_grid,new_index,&row,&col); - displayRect(button_grid->top_left_x + button_grid->button_pitch_x * col, - button_grid->top_left_y + button_grid->button_pitch_y * row, - button_grid->button_width, - button_grid->button_height, - COLOR_ACTIVE_BORDER); + if(nullptr != b_new){ + displayRect(b_new->x,b_new->y,b_new->w,b_new->h,COLOR_ACTIVE_BORDER); } } @@ -99,72 +59,45 @@ void playButtonMorse(const Button *const button, } void initSelector(int16_t *const raw_select_val_in_out, - const ButtonGrid_t *const button_grid_P, + const Button* const* buttons, + const uint8_t num_buttons, const MorsePlaybackType_e play_type) { - ButtonGrid_t button_grid; - memcpy_P(&button_grid,button_grid_P,sizeof(button_grid)); - *raw_select_val_in_out = 0; - - if(0 < button_grid.num_button_rows * button_grid.num_button_cols){ + if(0 < num_buttons){ Button button; Button* bp; - memcpy_P(&bp,&(button_grid.buttons_P[0]),sizeof(bp)); + memcpy_P(&bp,&(buttons[0]),sizeof(bp)); memcpy_P(&button,bp,sizeof(button)); - movePuck(&button_grid,-1,0); + movePuck(nullptr,&button); playButtonMorse(&button,play_type); } } void adjustSelector(int16_t *const raw_select_val_in_out, - int16_t knob, - const ButtonGrid_t *const button_grid_P, + const int16_t knob, + const Button* const* buttons, + const uint8_t num_buttons, const MorsePlaybackType_e play_type) { - ButtonGrid_t button_grid; - memcpy_P(&button_grid,button_grid_P,sizeof(button_grid)); - - const uint8_t num_buttons = button_grid.num_button_rows * button_grid.num_button_cols; const uint8_t prev_select = (*raw_select_val_in_out)/MENU_KNOB_COUNTS_PER_ITEM; - *raw_select_val_in_out += knob; - bool keep_trying = true; - while(keep_trying){ - *raw_select_val_in_out = LIMIT(*raw_select_val_in_out,0,num_buttons*MENU_KNOB_COUNTS_PER_ITEM - 1); - const uint8_t new_select = (*raw_select_val_in_out)/MENU_KNOB_COUNTS_PER_ITEM; - if(prev_select != new_select){ - Button* bp; - memcpy_P(&bp,&(button_grid.buttons_P[new_select]),sizeof(bp)); - if(nullptr == bp){ - if(new_select > prev_select){ - *raw_select_val_in_out += MENU_KNOB_COUNTS_PER_ITEM; - } - else{ - *raw_select_val_in_out -= MENU_KNOB_COUNTS_PER_ITEM; - } - if((*raw_select_val_in_out <= 0) - ||(*raw_select_val_in_out >= num_buttons*MENU_KNOB_COUNTS_PER_ITEM - 1)){ - keep_trying = false; - } - continue; - } + *raw_select_val_in_out = LIMIT((*raw_select_val_in_out)+knob,0,num_buttons*MENU_KNOB_COUNTS_PER_ITEM - 1); + const uint8_t new_select = (*raw_select_val_in_out)/MENU_KNOB_COUNTS_PER_ITEM; + if(prev_select != new_select){ + Button prev_button; + Button* bp; + memcpy_P(&bp,&(buttons[prev_select]),sizeof(bp)); + memcpy_P(&prev_button,bp,sizeof(prev_button)); + Button new_button; + memcpy_P(&bp,&(buttons[new_select]),sizeof(bp)); + memcpy_P(&new_button,bp,sizeof(new_button)); - Button new_button; - memcpy_P(&new_button,bp,sizeof(new_button)); - - movePuck(&button_grid,prev_select,new_select); - playButtonMorse(&new_button,play_type); - } + movePuck(&prev_button,&new_button); + playButtonMorse(&new_button,play_type); } } -void endSelector(const int16_t raw_select, - const ButtonGrid_t *const button_grid_P) +void endSelector(const Button *const button) { - ButtonGrid_t button_grid; - memcpy_P(&button_grid,button_grid_P,sizeof(button_grid)); - - uint8_t index = raw_select/MENU_KNOB_COUNTS_PER_ITEM; - - movePuck(&button_grid,index,-1); + movePuck(button,nullptr); } diff --git a/menu_utils.h b/menu_utils.h index 0a6f55c..d84be30 100644 --- a/menu_utils.h +++ b/menu_utils.h @@ -1,10 +1,11 @@ #pragma once -#include "button_grid.h" +#include "button.h" #include "menu.h" //Returns true if button was found, false otherwise -bool findPressedButton(const ButtonGrid_t *const button_grid_P, +bool findPressedButton(const Button* const* buttons, + const uint8_t num_buttons, Button *const button_out, const Point touch_point); @@ -13,13 +14,14 @@ enum MorsePlaybackType_e : uint8_t { PlayText }; void initSelector(int16_t *const raw_select_val_in_out, - const ButtonGrid_t *const button_grid_P, - const MorsePlaybackType_e play_type); + const Button* const* buttons, + const uint8_t num_buttons, + const MorsePlaybackType_e); void adjustSelector(int16_t *const raw_select_val_in_out, int16_t knob, - const ButtonGrid_t *const button_grid_P, - const MorsePlaybackType_e play_type); + const Button* const* buttons, + const uint8_t num_buttons, + const MorsePlaybackType_e); -void endSelector(const int16_t raw_select, - const ButtonGrid_t *const button_grid_P); +void endSelector(const Button *const button);