Revert "Rough pass at button grids"

This reverts commit 1f97be3263.
This commit is contained in:
Reed Nightingale 2020-04-25 19:47:02 -07:00
parent 1f97be3263
commit 9b9a1610c2
12 changed files with 295 additions and 344 deletions

44
button.cpp Normal file
View File

@ -0,0 +1,44 @@
#include "button.h"
#include <avr/pgmspace.h>
#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);
}

20
button.h Normal file
View File

@ -0,0 +1,20 @@
#pragma once
#include <stdint.h>
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);

View File

@ -1,90 +0,0 @@
#include "button_grid.h"
#include <Arduino.h>
#include <avr/pgmspace.h>
#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);
}
}

View File

@ -1,33 +0,0 @@
#pragma once
#include <stdint.h>
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);

View File

@ -4,7 +4,7 @@
#include <avr/pgmspace.h>
#include <Arduino.h>
#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{

View File

@ -5,7 +5,7 @@
#include <WString.h>//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);

View File

@ -2,12 +2,12 @@
#include <stdint.h>
#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();

View File

@ -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);
}

View File

@ -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)
{

View File

@ -2,9 +2,10 @@
#include <stdint.h>
#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;

View File

@ -2,80 +2,40 @@
#include <avr/pgmspace.h>
#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);
}

View File

@ -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);