From fafc9acd0ed7fcdb98cb80cd007021f28d65b0a7 Mon Sep 17 00:00:00 2001 From: Reed Nightingale Date: Sun, 26 Apr 2020 17:30:19 -0700 Subject: [PATCH] Create quicklist menu --- menu_quicklist.cpp | 91 ++++++++++++++++++++++++ menu_quicklist.h | 2 + menu_quicklist_buttons.cpp | 137 +++++++++++++++++++++++++++++++++++++ menu_quicklist_buttons.h | 11 +++ 4 files changed, 241 insertions(+) create mode 100644 menu_quicklist.cpp create mode 100644 menu_quicklist.h create mode 100644 menu_quicklist_buttons.cpp create mode 100644 menu_quicklist_buttons.h diff --git a/menu_quicklist.cpp b/menu_quicklist.cpp new file mode 100644 index 0000000..8cc00a2 --- /dev/null +++ b/menu_quicklist.cpp @@ -0,0 +1,91 @@ +#include "menu_quicklist.h" +#include "menu_quicklist_buttons.h" + +#include +#include //F() + +#include "color_theme.h" +#include "menu_utils.h" +#include "nano_gui.h" +#include "scratch_space.h" + +void initQuickList(void); +MenuReturn_e runQuickList(const ButtonPress_e tuner_button, + const ButtonPress_e touch_button, + const Point touch_point, + const int16_t knob); +Menu_t quickList_menu = { + initQuickList, + runQuickList, + nullptr +}; + +Menu_t *const quickListMenu = &quickList_menu; + +int16_t quickListMenuSelectedItemRaw = 0;//Allow negative only for easier checks on wrap around + +void drawQuickList(void) +{ + displayFillrect(0,47,320,200,COLOR_BACKGROUND); + Button button; + Button* bp; + for(uint8_t i = 0; i < QUICKLIST_MENU_NUM_BUTTONS; ++i){ + memcpy_P(&bp, &(quickListMenuButtons[i]), sizeof(bp)); + memcpy_P(&button,bp,sizeof(button)); + drawButton(&button); + } + strncpy_P(b,(const char*)F("Short press = load\nLong press = save"),sizeof(b)); + displayText(b,10,47,170,200,COLOR_TEXT,COLOR_BACKGROUND,COLOR_BACKGROUND); +} + +void initQuickList(void) +{ + quickListSelectionMode = ButtonPress_e::ShortPress;//Anything except NotPressed + drawQuickList(); + initSelector(&quickListMenuSelectedItemRaw, + quickListMenuButtons, + QUICKLIST_MENU_NUM_BUTTONS, + MorsePlaybackType_e::PlayChar); +} + +MenuReturn_e runQuickList(const ButtonPress_e tuner_button, + const ButtonPress_e touch_button, + const Point touch_point, + const int16_t knob) +{ + if(ButtonPress_e::NotPressed != tuner_button){ + uint8_t menu_index = quickListMenuSelectedItemRaw/MENU_KNOB_COUNTS_PER_ITEM; + Button button; + Button* bp; + memcpy_P(&bp,&(quickListMenuButtons[menu_index]),sizeof(bp)); + memcpy_P(&button,bp,sizeof(button)); + quickListSelectionMode = tuner_button; + button.on_select(); + }//tuner_button + + else if(ButtonPress_e::NotPressed != touch_button){ + Button button; + if(findPressedButton(quickListMenuButtons,QUICKLIST_MENU_NUM_BUTTONS,&button,touch_point)){ + quickListSelectionMode = touch_button; + button.on_select(); + } + else{ + //Touch detected, but not on our buttons, so ignore + } + }//touch_button + + else{//Neither button input type found, so handle the knob + adjustSelector(&quickListMenuSelectedItemRaw, + knob, + quickListMenuButtons, + QUICKLIST_MENU_NUM_BUTTONS, + MorsePlaybackType_e::PlayChar); + } + + if(ButtonPress_e::NotPressed == quickListSelectionMode){ + return MenuReturn_e::ExitedRedraw; + } + else{ + return MenuReturn_e::StillActive; + } +} \ No newline at end of file diff --git a/menu_quicklist.h b/menu_quicklist.h new file mode 100644 index 0000000..62fcbc0 --- /dev/null +++ b/menu_quicklist.h @@ -0,0 +1,2 @@ +#include "menu.h" +extern Menu_t* const quickListMenu; diff --git a/menu_quicklist_buttons.cpp b/menu_quicklist_buttons.cpp new file mode 100644 index 0000000..5b4fdfa --- /dev/null +++ b/menu_quicklist_buttons.cpp @@ -0,0 +1,137 @@ +#include "menu_quicklist_buttons.h" + +#include +#include //F() + +#include "color_theme.h" +#include "nano_gui.h" +#include "scratch_space.h" +#include "settings.h" +#include "utils.h" + +static const unsigned int LAYOUT_BUTTON_X = 180; +static const unsigned int LAYOUT_BUTTON_Y = 47; +static const unsigned int LAYOUT_BUTTON_WIDTH = 140; +static const unsigned int LAYOUT_BUTTON_HEIGHT = 36; +static const unsigned int LAYOUT_BUTTON_PITCH_X = LAYOUT_BUTTON_WIDTH + 1; +static const unsigned int LAYOUT_BUTTON_PITCH_Y = 40; + +ButtonPress_e quickListSelectionMode; + +#define D_STRINGIFY(x) #x +#define D_STRING(x) D_STRINGIFY(x) +#define QUICKLIST_BUTTON_GENERATE(number) \ + void toQL##number(char* text_out, const uint16_t max_text_size);\ + void osQL##number();\ + constexpr Button bQL##number PROGMEM = {\ + LAYOUT_BUTTON_X,\ + LAYOUT_BUTTON_Y + number*LAYOUT_BUTTON_PITCH_Y,\ + LAYOUT_BUTTON_WIDTH,\ + LAYOUT_BUTTON_HEIGHT,\ + nullptr,\ + toQL##number,\ + bsQuickList,\ + osQL##number,\ + '0'+number\ + } + +ButtonStatus_e bsQuickList(void){ + return ButtonStatus_e::Stateless; +} + +//Unfortunately there's no easy way to auto-generate NUM_QUICKLIST_SETTINGS copies of this +QUICKLIST_BUTTON_GENERATE(0); +QUICKLIST_BUTTON_GENERATE(1); +QUICKLIST_BUTTON_GENERATE(2); +QUICKLIST_BUTTON_GENERATE(3); + +constexpr char txtQLCancel [] PROGMEM = "Can"; +void osQLCancel(); +constexpr Button bQLCancel PROGMEM = { + LAYOUT_BUTTON_X, + LAYOUT_BUTTON_Y + 4*LAYOUT_BUTTON_PITCH_Y, + LAYOUT_BUTTON_WIDTH, + LAYOUT_BUTTON_HEIGHT, + txtQLCancel, + nullptr, + bsQuickList, + osQLCancel, + 'C' +}; + +//Declare in menu select order, not graphical order +const Button* const quickListMenuButtons [] PROGMEM = { + &bQL0, &bQL1, &bQL2, &bQL3, &bQLCancel +}; +const uint8_t QUICKLIST_MENU_NUM_BUTTONS = sizeof(quickListMenuButtons)/sizeof(quickListMenuButtons[0]); + +void osQuickListRecall(uint8_t index) +{ + SetActiveVfoFreq(globalSettings.quickList[index].frequency); + SetActiveVfoMode(globalSettings.quickList[index].mode); +} + +void osQuickListSave(uint8_t index) +{ + globalSettings.quickList[index].frequency = GetActiveVfoFreq(); + globalSettings.quickList[index].mode = GetActiveVfoMode(); + SaveSettingsToEeprom(); +} + +void osQuickList(uint8_t index) +{ + if(ButtonPress_e::ShortPress == quickListSelectionMode){ + osQuickListRecall(index); + } + else if(ButtonPress_e::LongPress == quickListSelectionMode){ + osQuickListSave(index); + } + quickListSelectionMode = ButtonPress_e::NotPressed;//Selection was made. Exit. +} + +#define QUICKLIST_ONSELECT_GENERATE(number) \ + void osQL##number(void){\ + osQuickList(number);\ + } + +//Unfortunately there's no easy way to auto-generate NUM_QUICKLIST_SETTINGS copies of this +QUICKLIST_ONSELECT_GENERATE(0); +QUICKLIST_ONSELECT_GENERATE(1); +QUICKLIST_ONSELECT_GENERATE(2); +QUICKLIST_ONSELECT_GENERATE(3); + +#define QUICKLIST_TEXTOVERRIDE_GENERATE(number) \ + void toQL##number(char* text_out, const uint16_t max_text_size){\ + toQuickList(number, text_out, max_text_size);\ + } + +void toQuickList(uint8_t index, char* text_out, const uint16_t max_text_size) +{ + + 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 + text_out[0] = '0'+index;//Assume a 1-digit number for now + text_out[1] = ':'; + text_out[2] = ' '; + formatFreq(globalSettings.quickList[index].frequency, text_out+3, max_text_size-3, 10); +} + +//Unfortunately there's no easy way to auto-generate NUM_QUICKLIST_SETTINGS copies of this +QUICKLIST_TEXTOVERRIDE_GENERATE(0); +QUICKLIST_TEXTOVERRIDE_GENERATE(1); +QUICKLIST_TEXTOVERRIDE_GENERATE(2); +QUICKLIST_TEXTOVERRIDE_GENERATE(3); + +void osQLCancel() +{ + quickListSelectionMode = ButtonPress_e::NotPressed; +} diff --git a/menu_quicklist_buttons.h b/menu_quicklist_buttons.h new file mode 100644 index 0000000..d03017c --- /dev/null +++ b/menu_quicklist_buttons.h @@ -0,0 +1,11 @@ +#pragma once + +#include + +#include "button.h" +#include "button_press_e.h" + +extern const Button* const quickListMenuButtons[]; +extern const uint8_t QUICKLIST_MENU_NUM_BUTTONS; + +extern ButtonPress_e quickListSelectionMode;//NotPressed means exit menu. Other press types are consumed by selectors