mirror of
https://github.com/jhbruhn/eurorack.git
synced 2025-03-15 02:55:49 +00:00
Implement editing of values in menus
This commit is contained in:
parent
8f90701c7a
commit
43b75dd2ab
5 changed files with 71 additions and 26 deletions
|
@ -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) {
|
||||
|
@ -58,4 +66,14 @@ void Menu::down()
|
|||
|
||||
this->selectedItem++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Menu::enter()
|
||||
{
|
||||
if (this->currentEditingItem >= 0) {
|
||||
this->currentEditingItem = -1;
|
||||
return;
|
||||
}
|
||||
this->currentEditingItem = this->selectedItem;
|
||||
}
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -23,17 +23,21 @@ 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);
|
||||
|
||||
void OnClick();
|
||||
void OnLongClick();
|
||||
void OnIncrement(stmlib::Event &e);
|
||||
void OnIncrement(stmlib::Event& e);
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(UI);
|
||||
};
|
||||
|
|
Loading…
Reference in a new issue