Implement submenus for parts (or at least the ability to have those).

This commit is contained in:
Jan-Henrik 2020-02-22 23:42:31 +01:00
parent ce461733b0
commit 2e43ebf110
12 changed files with 199 additions and 67 deletions

3
midi2cv/config.h Normal file
View file

@ -0,0 +1,3 @@
#pragma once
#define PART_COUNT (4)

View file

@ -39,10 +39,11 @@ UPLOAD_COMMAND = upload_combo_jtag
# Packages to build # Packages to build
TARGET = midi2cv TARGET = midi2cv
PACKAGES = midi2cv \ PACKAGES = midi2cv \
midi2cv/drivers \ midi2cv/drivers \
midi2cv/menu \ midi2cv/menu \
stmlib/utils \ midi2cv/ui \
stmlib/system stmlib/utils \
stmlib/system
RESOURCES = midi2cv/resources RESOURCES = midi2cv/resources
TOOLCHAIN_PATH ?= /usr/local/arm-4.8.3/ TOOLCHAIN_PATH ?= /usr/local/arm-4.8.3/

View file

@ -22,7 +22,7 @@ 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);
if(editing) { if (editing) {
u8g2_DrawFrame(u8g2_, xStart, yPosition, width, MENU_ITEM_HEIGHT); u8g2_DrawFrame(u8g2_, xStart, yPosition, width, MENU_ITEM_HEIGHT);
} else if (selected) { } else if (selected) {
u8g2_DrawBox(u8g2_, xStart, yPosition, width, MENU_ITEM_HEIGHT); u8g2_DrawBox(u8g2_, xStart, yPosition, width, MENU_ITEM_HEIGHT);
@ -69,11 +69,22 @@ void Menu::down()
} }
} }
void Menu::enter() bool Menu::enter()
{ {
if (this->currentEditingItem >= 0) { if (this->currentEditingItem >= 0) {
this->currentEditingItem = -1; this->currentEditingItem = -1;
return; return true;
} }
this->currentEditingItem = this->selectedItem; this->currentEditingItem = this->selectedItem;
return false;
} }
bool Menu::back()
{
if (this->currentEditingItem >= 0) {
this->currentEditingItem = -1;
return false;
}
return true;
}

View file

@ -25,7 +25,8 @@ class Menu {
void up(); void up();
void down(); void down();
void enter(); bool back(); // returns true true if nothing happened here and the action can be delegated to up
bool enter(); // returns true if it wants to give up control
void add_item(AbstractMenuItem* item) void add_item(AbstractMenuItem* item)
{ {

View file

@ -8,6 +8,7 @@
#include "part.h" #include "part.h"
#include "stmlib/system/system_clock.h" #include "stmlib/system/system_clock.h"
#include "ui.h" #include "ui.h"
#include "config.h"
using namespace stmlib; using namespace stmlib;

View file

@ -3,8 +3,6 @@
#include <inttypes.h> #include <inttypes.h>
#define PART_COUNT 4
#define TOTAL_COLUMN_COUNT 4 #define TOTAL_COLUMN_COUNT 4
typedef enum { MIDI_THRU_OFF, typedef enum { MIDI_THRU_OFF,

View file

@ -1,4 +1,5 @@
#include "ui.h" #include "ui.h"
#include "ui/main_menu.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.h"
@ -12,28 +13,11 @@ using namespace stmlib;
#define HEADER_HEIGHT 14 #define HEADER_HEIGHT 14
const uint32_t kEncoderLongPressTime = 600; const uint32_t kEncoderLongPressTime = 600;
const char part_names[4][2] = { "A", "B", "C", "D" }; MainMenu mainMenu;
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);
FloatMenuItem item7("ralle4", 0, 0, 100, .25f);
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()
@ -67,44 +51,11 @@ void UI::Draw()
{ {
u8g2_ClearBuffer(display.u8g2()); u8g2_ClearBuffer(display.u8g2());
switch (current_menu) { mainMenu.render(display.u8g2(), 0, 0, DISPLAY_WIDTH, DISPLAY_HEIGHT);
case MENU_PART_1:
case MENU_PART_2:
case MENU_PART_3:
case MENU_PART_4:
DrawHeader();
//DrawPartMenu(current_menu);
menu.render(display.u8g2(), 0, 15, 128, 64 - 15);
break;
default:
break;
}
display.Swap(); display.Swap();
} }
void UI::DrawHeader()
{
u8g2_SetFont(display.u8g2(), u8g2_font_6x12_tf);
for (int i = 0; i < PART_COUNT; i++) {
u8g2_SetFontMode(display.u8g2(), 1);
u8g2_SetDrawColor(display.u8g2(), 1);
if (current_menu == i)
u8g2_DrawBox(display.u8g2(), i * (DISPLAY_WIDTH / PART_COUNT), 0, (DISPLAY_WIDTH / PART_COUNT) - 1, HEADER_HEIGHT);
else
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, 0 + 10, part_names[i]);
u8g2_SetDrawColor(display.u8g2(), 1);
}
}
void UI::DrawPartMenu(Menu_t menu)
{
}
void UI::Flush() void UI::Flush()
{ {
display.Flush(); display.Flush();
@ -139,18 +90,19 @@ bool UI::DoEvents()
void UI::OnClick() void UI::OnClick()
{ {
menu.enter(); mainMenu.enter();
} }
void UI::OnLongClick() void UI::OnLongClick()
{ {
mainMenu.back();
} }
void UI::OnIncrement(Event& e) void UI::OnIncrement(Event& e)
{ {
if (e.data > 0) if (e.data > 0)
menu.down(); mainMenu.down();
else else
menu.up(); mainMenu.up();
//current_menu = (Menu_t) (((uint32_t)current_menu + e.data) % MENU_COUNT); //current_menu = (Menu_t) (((uint32_t)current_menu + e.data) % MENU_COUNT);
} }

View file

@ -32,8 +32,6 @@ class UI {
uint32_t encoder_press_time_; uint32_t encoder_press_time_;
void Draw(); void Draw();
void DrawHeader();
void DrawPartMenu(Menu_t menu);
void OnClick(); void OnClick();
void OnLongClick(); void OnLongClick();

70
midi2cv/ui/main_menu.cc Normal file
View file

@ -0,0 +1,70 @@
#include "main_menu.h"
#include "stmlib/stmlib.h"
#include <u8g2.h>
const int kHeaderHeight = 13;
const char* kPartNames[] = { "A", "B", "C", "D" };
void MainMenu::back()
{
if (this->activePartMenu >= 0) {
if (this->partMenus[this->activePartMenu].back())
this->activePartMenu = -1;
}
}
void MainMenu::enter()
{
if (this->activePartMenu >= 0) {
if (this->partMenus[this->activePartMenu].enter())
this->activePartMenu = -1;
} else {
this->activePartMenu = this->selectedPart;
}
}
void MainMenu::up()
{
if (this->activePartMenu >= 0) {
this->partMenus[this->activePartMenu].up();
} else {
this->selectedPart--;
CONSTRAIN(this->selectedPart, 0, PART_COUNT - 1);
}
}
void MainMenu::down()
{
if (this->activePartMenu >= 0) {
this->partMenus[this->activePartMenu].down();
} else {
this->selectedPart++;
CONSTRAIN(this->selectedPart, 0, PART_COUNT - 1);
}
}
void MainMenu::render(u8g2_t* u8g2, int x, int y, int width, int height)
{
u8g2_SetFont(u8g2, /*u8g2_font_5x8_tf*/ u8g2_font_pcsenior_8u);
for (int i = 0; i < PART_COUNT; i++) {
u8g2_SetFontMode(u8g2, 1);
u8g2_SetDrawColor(u8g2, 1);
if (this->selectedPart == i) {
if (this->activePartMenu == i) {
u8g2_DrawBox(u8g2, x + 1 + i * (width / PART_COUNT), y + 1, (width / PART_COUNT) - 3, kHeaderHeight - 2);
} else {
u8g2_DrawFrame(u8g2, x + 1 + i * (width / PART_COUNT), y + 1, (width / PART_COUNT) - 3, kHeaderHeight - 2);
u8g2_DrawFrame(u8g2, x + i * (width / PART_COUNT), y, (width / PART_COUNT) - 1, kHeaderHeight);
}
} else {
u8g2_DrawFrame(u8g2, x + 1 + i * (width / PART_COUNT), y + 1, (width / PART_COUNT) - 3, kHeaderHeight - 2);
}
u8g2_SetDrawColor(u8g2, 2);
u8g2_DrawStr(u8g2, x + i * (width / PART_COUNT) + 5, y + 9, kPartNames[i]);
u8g2_SetDrawColor(u8g2, 1);
}
this->partMenus[this->selectedPart].render(u8g2, x, y + kHeaderHeight, width, height - kHeaderHeight);
}

25
midi2cv/ui/main_menu.h Normal file
View file

@ -0,0 +1,25 @@
#pragma once
#include "../config.h"
#include "part_menu.h"
#include <u8g2.h>
class MainMenu {
public:
void back();
void enter();
void up();
void down();
void render(u8g2_t* u8g2, int x, int y, int width, int height);
MainMenu()
: activePartMenu(-1)
, selectedPart(0) {};
private:
PartMenu partMenus[PART_COUNT];
int activePartMenu;
int selectedPart;
};

47
midi2cv/ui/part_menu.cc Normal file
View file

@ -0,0 +1,47 @@
#include "part_menu.h"
#include "../menu/menu.h"
#include "../menu/menu_items.h"
#include <u8g2.h>
PartMenu::PartMenu()
: menu(128, 64)
, item1("wolle", 0, 0, 100, 1)
, item2("petry", 0, 0, 100, 1)
, item3("schale", 0, 0, 100, 1)
, item4("eine", 0, 0, 100, 1)
, item5("schale?", 0, 0, 100, 1)
{
this->menu.add_item(&this->item1);
this->menu.add_item(&this->item2);
this->menu.add_item(&this->item3);
this->menu.add_item(&this->item4);
this->menu.add_item(&this->item5);
}
void PartMenu::up()
{
menu.up();
}
void PartMenu::down()
{
menu.down();
}
bool PartMenu::back()
{
if (menu.back())
return true;
return false;
}
bool PartMenu::enter()
{
menu.enter();
return false;
}
void PartMenu::render(u8g2_t* u8g2, int x, int y, int width, int height)
{
menu.render(u8g2, x, y, width, height);
}

25
midi2cv/ui/part_menu.h Normal file
View file

@ -0,0 +1,25 @@
#pragma once
#include "../menu/menu.h"
#include "../menu/menu_items.h"
#include <u8g2.h>
class PartMenu {
public:
PartMenu();
bool enter();
bool back();
void up();
void down();
void render(u8g2_t* u8g2, int x, int y, int width, int height);
private:
Menu menu;
UIntMenuItem item1;
UIntMenuItem item2;
UIntMenuItem item3;
UIntMenuItem item4;
UIntMenuItem item5;
};