Implement editing of values in menus

This commit is contained in:
Jan-Henrik 2020-02-21 01:39:20 +01:00
parent 8f90701c7a
commit 43b75dd2ab
5 changed files with 71 additions and 26 deletions

View file

@ -15,27 +15,32 @@ void Menu::render(u8g2_t* u8g2_, uint8_t xStart, uint8_t yStart, uint8_t width,
u8g2_SetFont(u8g2_, u8g2_font_6x12_tf);
for (uint8_t i = 0; i < itemsToRender; i++) {
bool selected = this->selectedItem == (i + this->currentScrollStart);
bool editing = this->currentEditingItem == (i + this->currentScrollStart);
uint8_t yPosition = yStart + i * MENU_ITEM_HEIGHT;
AbstractMenuItem* item = this->items[i + this->currentScrollStart];
u8g2_SetDrawColor(u8g2_, selected ? 1 : 0);
if (selected) {
if(editing) {
u8g2_DrawFrame(u8g2_, xStart, yPosition, width, MENU_ITEM_HEIGHT);
} else if (selected) {
u8g2_DrawBox(u8g2_, xStart, yPosition, width, MENU_ITEM_HEIGHT);
}
u8g2_SetDrawColor(u8g2_, !selected ? 1 : 0);
u8g2_DrawStr(u8g2_, xStart + 2, yPosition + MENU_ITEM_HEIGHT - 4, item->get_label());
u8g2_SetDrawColor(u8g2_, editing || !selected ? 1 : 0);
u8g2_DrawStr(u8g2_, xStart + 2, yPosition + MENU_ITEM_HEIGHT - 3, item->get_label());
uint8_t valueStringWidth = u8g2_GetStrWidth(u8g2_, item->get_string_representation());
u8g2_DrawStr(u8g2_, xStart + width - valueStringWidth - 2, yPosition + MENU_ITEM_HEIGHT - 4, item->get_string_representation());
u8g2_DrawStr(u8g2_, xStart + width - valueStringWidth - 2, yPosition + MENU_ITEM_HEIGHT - 3, item->get_string_representation());
}
}
void Menu::up()
{
if (this->selectedItem > 0) {
if (this->currentEditingItem >= 0) {
this->items[this->selectedItem]->decrease();
} else if (this->selectedItem > 0) {
if (this->selectedItem - this->currentScrollStart == 1) { // keep scroll start one up
this->currentScrollStart--;
}
@ -50,6 +55,9 @@ void Menu::up()
void Menu::down()
{
if (this->currentEditingItem >= 0) {
this->items[this->selectedItem]->increase();
} else {
uint8_t maxVisibleItems = height / MENU_ITEM_HEIGHT;
if (this->selectedItem < this->itemCount - 1) {
if (this->selectedItem - this->currentScrollStart == maxVisibleItems - 2 && this->itemCount - this->currentScrollStart > maxVisibleItems) {
@ -59,3 +67,13 @@ void Menu::down()
this->selectedItem++;
}
}
}
void Menu::enter()
{
if (this->currentEditingItem >= 0) {
this->currentEditingItem = -1;
return;
}
this->currentEditingItem = this->selectedItem;
}

View file

@ -8,6 +8,8 @@ class AbstractMenuItem {
public:
virtual const char* get_label();
virtual char* get_string_representation();
virtual void increase();
virtual void decrease();
};
template <class T>
@ -55,15 +57,16 @@ class MenuItem : public AbstractMenuItem {
template <class T>
class NumberMenuItem : public MenuItem<T> {
private:
T step;
T minimumValue;
T maximumValue;
T step;
protected:
NumberMenuItem(const char* _label, T _initialValue, T _minimumValue, T _maximumValue, T _step)
: MenuItem<T>(_label, _initialValue)
, minimumValue(_minimumValue)
, maximumValue(_maximumValue) {};
, maximumValue(_maximumValue)
, step(_step) {};
virtual const char* get_format_string() = 0;
@ -75,13 +78,13 @@ class NumberMenuItem : public MenuItem<T> {
public:
void increase()
{
if (this->get_value() + step <= maximumValue)
if (this->get_value() + step <= maximumValue && this->get_value() + step >= minimumValue)
this->set_value(this->get_value() + step);
};
void decrease()
{
if (this->get_value() - step >= minimumValue)
if (this->get_value() - step >= minimumValue && this->get_value() - step <= maximumValue)
this->set_value(this->get_value() - step);
};
};
@ -117,7 +120,7 @@ class FloatMenuItem : public NumberMenuItem<float> {
protected:
const char* get_format_string()
{
return "%f.2";
return "%.2f";
}
public:

View file

@ -48,9 +48,8 @@ void PendSV_Handler() {}
// called every 1ms
void SysTick_Handler()
{
IWDG_ReloadCounter();
system_clock.Tick();
ui.Poll();
system_clock.Tick();
}
void TIM2_IRQHandler(void)
@ -110,7 +109,7 @@ void Init(void)
RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2, ENABLE);
system_clock.Init();
SysTick_Config(F_CPU / 8000);
SysTick_Config(F_CPU / 1000);
//IWDG_Enable();
gpio.Init();
@ -130,5 +129,6 @@ int main(void)
// do we want to call the watchdog here? it's the only part thats getting interrupted after all
// (next to the interrupts themselves potentially interrupting each other)
ui.DoEvents();
IWDG_ReloadCounter();
}
}

View file

@ -9,7 +9,8 @@
using namespace stmlib;
#define HEADER_HEIGHT 16
#define HEADER_HEIGHT 14
const uint32_t kEncoderLongPressTime = 600;
const char part_names[4][2] = { "A", "B", "C", "D" };
@ -20,7 +21,7 @@ UIntMenuItem item3("ralle", 0, 0, 100, 1);
UIntMenuItem item4("ralle1", 0, 0, 100, 1);
UIntMenuItem item5("ralle2", 0, 0, 100, 1);
UIntMenuItem item6("ralle3", 0, 0, 100, 1);
UIntMenuItem item7("ralle4", 0, 0, 100, 1);
FloatMenuItem item7("ralle4", 0, 0, 100, .25f);
void UI::Init()
{
@ -38,6 +39,24 @@ void UI::Init()
void UI::Poll()
{
encoder.Debounce();
if (encoder.just_pressed()) {
encoder_press_time_ = system_clock.milliseconds();
encoder_long_press_event_sent_ = false;
}
if (!encoder_long_press_event_sent_) {
if (encoder.pressed()) {
uint32_t duration = system_clock.milliseconds() - encoder_press_time_;
if (duration >= kEncoderLongPressTime && !encoder_long_press_event_sent_) {
input_queue.AddEvent(CONTROL_ENCODER_LONG_CLICK, 0, 0);
encoder_long_press_event_sent_ = true;
}
}
if (encoder.released()) {
input_queue.AddEvent(CONTROL_ENCODER_CLICK, 0, 0);
}
}
int32_t increment = encoder.increment();
if (increment != 0) {
input_queue.AddEvent(CONTROL_ENCODER, 0, increment);
@ -53,9 +72,9 @@ void UI::Draw()
case MENU_PART_2:
case MENU_PART_3:
case MENU_PART_4:
//DrawHeader();
DrawHeader();
//DrawPartMenu(current_menu);
menu.render(display.u8g2(), 0, 0, 128, 64);
menu.render(display.u8g2(), 0, 15, 128, 64 - 15);
break;
default:
@ -77,7 +96,7 @@ void UI::DrawHeader()
u8g2_DrawFrame(display.u8g2(), i * (DISPLAY_WIDTH / PART_COUNT), 0, (DISPLAY_WIDTH / PART_COUNT) - 1, HEADER_HEIGHT);
u8g2_SetDrawColor(display.u8g2(), 2);
u8g2_DrawStr(display.u8g2(), i * (DISPLAY_WIDTH / PART_COUNT) + 5, 2 + 10, part_names[i]);
u8g2_DrawStr(display.u8g2(), i * (DISPLAY_WIDTH / PART_COUNT) + 5, 0 + 10, part_names[i]);
u8g2_SetDrawColor(display.u8g2(), 1);
}
}
@ -120,6 +139,7 @@ bool UI::DoEvents()
void UI::OnClick()
{
menu.enter();
}
void UI::OnLongClick()

View file

@ -23,10 +23,14 @@ class UI {
bool DoEvents();
private:
Menu_t current_menu;
stmlib::EventQueue<16> input_queue;
bool long_press_event_sent_;
uint32_t start_stop_press_time_;
bool encoder_long_press_event_sent_;
uint32_t encoder_press_time_;
void Draw();
void DrawHeader();
void DrawPartMenu(Menu_t menu);