mirror of
				https://github.com/jhbruhn/eurorack.git
				synced 2025-10-30 02:46:01 +00:00 
			
		
		
		
	Menu Item Implementation fixes, rendering improvements, implement menu scrolling
This commit is contained in:
		
							parent
							
								
									54c4538a7a
								
							
						
					
					
						commit
						94e5c21f77
					
				
					 4 changed files with 49 additions and 35 deletions
				
			
		|  | @ -2,7 +2,7 @@ | ||||||
| #include <algorithm> | #include <algorithm> | ||||||
| #include <u8g2.h> | #include <u8g2.h> | ||||||
| 
 | 
 | ||||||
| #define MENU_ITEM_HEIGHT 8 | #define MENU_ITEM_HEIGHT 12 | ||||||
| 
 | 
 | ||||||
| void Menu::render(u8g2_t* u8g2_, uint8_t xStart, uint8_t yStart, uint8_t width, uint8_t height) | void Menu::render(u8g2_t* u8g2_, uint8_t xStart, uint8_t yStart, uint8_t width, uint8_t height) | ||||||
| { | { | ||||||
|  | @ -12,7 +12,7 @@ void Menu::render(u8g2_t* u8g2_, uint8_t xStart, uint8_t yStart, uint8_t width, | ||||||
|   uint8_t maxVisibleItems = height / MENU_ITEM_HEIGHT; |   uint8_t maxVisibleItems = height / MENU_ITEM_HEIGHT; | ||||||
| 
 | 
 | ||||||
|   uint8_t itemsToRender = std::min(maxVisibleItems, uint8_t(this->itemCount - currentScrollStart)); |   uint8_t itemsToRender = std::min(maxVisibleItems, uint8_t(this->itemCount - currentScrollStart)); | ||||||
| 
 |   u8g2_SetFont(u8g2_, u8g2_font_6x12_tf); | ||||||
|   for (uint8_t i = 0; i < itemsToRender; i++) { |   for (uint8_t i = 0; i < itemsToRender; i++) { | ||||||
|     bool selected = this->selectedItem == (i + this->currentScrollStart); |     bool selected = this->selectedItem == (i + this->currentScrollStart); | ||||||
|     uint8_t yPosition = yStart + i * MENU_ITEM_HEIGHT; |     uint8_t yPosition = yStart + i * MENU_ITEM_HEIGHT; | ||||||
|  | @ -26,10 +26,10 @@ void Menu::render(u8g2_t* u8g2_, uint8_t xStart, uint8_t yStart, uint8_t width, | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     u8g2_SetDrawColor(u8g2_, !selected ? 1 : 0); |     u8g2_SetDrawColor(u8g2_, !selected ? 1 : 0); | ||||||
|     u8g2_DrawStr(u8g2_, xStart + 0, yPosition + MENU_ITEM_HEIGHT, item->get_label()); |     u8g2_DrawStr(u8g2_, xStart + 2, yPosition + MENU_ITEM_HEIGHT - 4, item->get_label()); | ||||||
| 
 | 
 | ||||||
|     uint8_t valueStringWidth = u8g2_GetStrWidth(u8g2_, item->get_string_representation()); |     uint8_t valueStringWidth = u8g2_GetStrWidth(u8g2_, item->get_string_representation()); | ||||||
|     u8g2_DrawStr(u8g2_, xStart + width - valueStringWidth, yPosition + MENU_ITEM_HEIGHT, item->get_string_representation()); |     u8g2_DrawStr(u8g2_, xStart + width - valueStringWidth - 2, yPosition + MENU_ITEM_HEIGHT - 4, item->get_string_representation()); | ||||||
|   } |   } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -52,14 +52,10 @@ void Menu::down() | ||||||
| { | { | ||||||
|   uint8_t maxVisibleItems = height / MENU_ITEM_HEIGHT; |   uint8_t maxVisibleItems = height / MENU_ITEM_HEIGHT; | ||||||
|   if (this->selectedItem < this->itemCount - 1) { |   if (this->selectedItem < this->itemCount - 1) { | ||||||
|     if (this->selectedItem - this->currentScrollStart == maxVisibleItems - 1) { |     if (this->selectedItem - this->currentScrollStart == maxVisibleItems - 2 && this->itemCount - this->currentScrollStart > maxVisibleItems) { | ||||||
|       this->currentScrollStart++; |       this->currentScrollStart++; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     this->selectedItem++; |     this->selectedItem++; | ||||||
| 
 |  | ||||||
|     if (this->selectedItem >= this->itemCount - 1 - maxVisibleItems) { // last item
 |  | ||||||
|       this->currentScrollStart = this->itemCount - 1 - maxVisibleItems; |  | ||||||
|     } |  | ||||||
|   } |   } | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -94,7 +94,10 @@ class UIntMenuItem : public NumberMenuItem<uint32_t> { | ||||||
| 
 | 
 | ||||||
|   public: |   public: | ||||||
|   UIntMenuItem(const char* _label, uint32_t _initialValue, uint32_t _minimumValue, uint32_t _maximumValue, uint32_t _step) |   UIntMenuItem(const char* _label, uint32_t _initialValue, uint32_t _minimumValue, uint32_t _maximumValue, uint32_t _step) | ||||||
|       : NumberMenuItem(_label, _initialValue, _minimumValue, _maximumValue, _step) {}; |       : NumberMenuItem(_label, _initialValue, _minimumValue, _maximumValue, _step) | ||||||
|  |   { | ||||||
|  |     this->set_value(_initialValue); | ||||||
|  |   }; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| class IntMenuItem : public NumberMenuItem<int32_t> { | class IntMenuItem : public NumberMenuItem<int32_t> { | ||||||
|  |  | ||||||
|  | @ -3,8 +3,8 @@ | ||||||
| #include "drivers/display.h" | #include "drivers/display.h" | ||||||
| #include "drivers/encoder.h" | #include "drivers/encoder.h" | ||||||
| #include "drivers/gpio.h" | #include "drivers/gpio.h" | ||||||
| #include "menu/menu_items.h" |  | ||||||
| #include "menu/menu.h" | #include "menu/menu.h" | ||||||
|  | #include "menu/menu_items.h" | ||||||
| #include "part.h" | #include "part.h" | ||||||
| #include "stmlib/system/system_clock.h" | #include "stmlib/system/system_clock.h" | ||||||
| #include "ui.h" | #include "ui.h" | ||||||
|  | @ -18,12 +18,6 @@ Encoder encoder; | ||||||
| UI ui; | UI ui; | ||||||
| Part part[PART_COUNT]; | Part part[PART_COUNT]; | ||||||
| 
 | 
 | ||||||
| UIntMenuItem item("peda", 0, 0, 42, 1); |  | ||||||
| FloatMenuItem item2("peda", 0, 0, 42, 1); |  | ||||||
| FloatMenuItem item3("peda", 0, 0, 42, 1); |  | ||||||
| Menu menu; |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| // Default interrupt handlers.
 | // Default interrupt handlers.
 | ||||||
| extern "C" { | extern "C" { | ||||||
| void NMI_Handler() {} | void NMI_Handler() {} | ||||||
|  | @ -68,8 +62,12 @@ void TIM2_IRQHandler(void) | ||||||
| 
 | 
 | ||||||
|   // this will get called with 8kHz (foof)
 |   // this will get called with 8kHz (foof)
 | ||||||
|   // which still is a lot (60fps would be enough tbh)
 |   // which still is a lot (60fps would be enough tbh)
 | ||||||
| 
 |   static uint8_t count = 0; | ||||||
|  |   count++; | ||||||
|  |   if (count % (192 * 2) == 0) { | ||||||
|     ui.Flush(); |     ui.Flush(); | ||||||
|  |     count = 0; | ||||||
|  |   } | ||||||
| 
 | 
 | ||||||
|   // write audiodac1
 |   // write audiodac1
 | ||||||
|   // write audiodac2
 |   // write audiodac2
 | ||||||
|  | @ -82,7 +80,7 @@ void InitTimers(void) | ||||||
| { | { | ||||||
|   RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); |   RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); | ||||||
|   TIM_TimeBaseInitTypeDef timer_init; |   TIM_TimeBaseInitTypeDef timer_init; | ||||||
|   timer_init.TIM_Period = F_CPU / (8000) - 1; // 192 kHz, 48kHz for each audio DAC
 |   timer_init.TIM_Period = F_CPU / (48000 * 4) - 1; | ||||||
|   timer_init.TIM_Prescaler = 0; |   timer_init.TIM_Prescaler = 0; | ||||||
|   timer_init.TIM_ClockDivision = TIM_CKD_DIV1; |   timer_init.TIM_ClockDivision = TIM_CKD_DIV1; | ||||||
|   timer_init.TIM_CounterMode = TIM_CounterMode_Up; |   timer_init.TIM_CounterMode = TIM_CounterMode_Up; | ||||||
|  | @ -113,9 +111,9 @@ void Init(void) | ||||||
| 
 | 
 | ||||||
|   system_clock.Init(); |   system_clock.Init(); | ||||||
|   SysTick_Config(F_CPU / 8000); |   SysTick_Config(F_CPU / 8000); | ||||||
|   IWDG_Enable(); | 
 | ||||||
|  |   //IWDG_Enable();
 | ||||||
|   gpio.Init(); |   gpio.Init(); | ||||||
|   // asm("bkpt #0");
 |  | ||||||
|   display.Init(); |   display.Init(); | ||||||
|   encoder.Init(); |   encoder.Init(); | ||||||
|   ui.Init(); |   ui.Init(); | ||||||
|  | @ -126,14 +124,6 @@ int main(void) | ||||||
| { | { | ||||||
|   Init(); |   Init(); | ||||||
| 
 | 
 | ||||||
|   menu.add_item(&item); |  | ||||||
|   menu.add_item(&item2); |  | ||||||
|   menu.add_item(&item3); |  | ||||||
|   menu.render(0, 0, 0, 0, 0); |  | ||||||
| 
 |  | ||||||
|   item.increase(); |  | ||||||
|   item2.increase(); |  | ||||||
|   item3.increase(); |  | ||||||
|   while (1) { |   while (1) { | ||||||
|     // In this loop we do things that dont depend on any timing, but that have to be done.
 |     // In this loop we do things that dont depend on any timing, but that have to be done.
 | ||||||
|     // you should not write on spi here because that should happen in the TIM2 interrupt
 |     // you should not write on spi here because that should happen in the TIM2 interrupt
 | ||||||
|  |  | ||||||
|  | @ -1,6 +1,8 @@ | ||||||
| #include "ui.h" | #include "ui.h" | ||||||
| #include "drivers/display.h" | #include "drivers/display.h" | ||||||
| #include "midi2cv/drivers/encoder.h" | #include "midi2cv/drivers/encoder.h" | ||||||
|  | #include "midi2cv/menu/menu.h" | ||||||
|  | #include "midi2cv/menu/menu_items.h" | ||||||
| #include "part.h" | #include "part.h" | ||||||
| #include "stmlib/utils/random.h" | #include "stmlib/utils/random.h" | ||||||
| #include <u8g2.h> | #include <u8g2.h> | ||||||
|  | @ -11,9 +13,26 @@ using namespace stmlib; | ||||||
| 
 | 
 | ||||||
| const char part_names[4][2] = { "A", "B", "C", "D" }; | const char part_names[4][2] = { "A", "B", "C", "D" }; | ||||||
| 
 | 
 | ||||||
|  | Menu menu(128, 64); | ||||||
|  | UIntMenuItem item1("wolfgang", 0, 0, 100, 1); | ||||||
|  | UIntMenuItem item2("joerg", 0, 0, 100, 1); | ||||||
|  | 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); | ||||||
|  | 
 | ||||||
| void UI::Init() | void UI::Init() | ||||||
| { | { | ||||||
|   input_queue.Init(); |   input_queue.Init(); | ||||||
|  | 
 | ||||||
|  |   menu.add_item((AbstractMenuItem*)&item1); | ||||||
|  |   menu.add_item((AbstractMenuItem*)&item2); | ||||||
|  |   menu.add_item((AbstractMenuItem*)&item3); | ||||||
|  |   menu.add_item((AbstractMenuItem*)&item4); | ||||||
|  |   menu.add_item((AbstractMenuItem*)&item5); | ||||||
|  |   menu.add_item((AbstractMenuItem*)&item6); | ||||||
|  |   menu.add_item((AbstractMenuItem*)&item7); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void UI::Poll() | void UI::Poll() | ||||||
|  | @ -25,7 +44,8 @@ void UI::Poll() | ||||||
|   } |   } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void UI::Draw() { | void UI::Draw() | ||||||
|  | { | ||||||
|   u8g2_ClearBuffer(display.u8g2()); |   u8g2_ClearBuffer(display.u8g2()); | ||||||
| 
 | 
 | ||||||
|   switch (current_menu) { |   switch (current_menu) { | ||||||
|  | @ -33,8 +53,9 @@ void UI::Draw() { | ||||||
|   case MENU_PART_2: |   case MENU_PART_2: | ||||||
|   case MENU_PART_3: |   case MENU_PART_3: | ||||||
|   case MENU_PART_4: |   case MENU_PART_4: | ||||||
|     DrawHeader(); |     //DrawHeader();
 | ||||||
|     DrawPartMenu(current_menu); |     //DrawPartMenu(current_menu);
 | ||||||
|  |     menu.render(display.u8g2(), 0, 0, 128, 64); | ||||||
|     break; |     break; | ||||||
|   default: |   default: | ||||||
| 
 | 
 | ||||||
|  | @ -107,5 +128,9 @@ void UI::OnLongClick() | ||||||
| 
 | 
 | ||||||
| void UI::OnIncrement(Event& e) | void UI::OnIncrement(Event& e) | ||||||
| { | { | ||||||
|   current_menu = (Menu_t) (((uint32_t)current_menu + e.data) % MENU_COUNT); |   if (e.data > 0) | ||||||
|  |     menu.down(); | ||||||
|  |   else | ||||||
|  |     menu.up(); | ||||||
|  |   //current_menu = (Menu_t) (((uint32_t)current_menu + e.data) % MENU_COUNT);
 | ||||||
| } | } | ||||||
|  |  | ||||||
		Loading…
	
		Reference in a new issue