Select Git revision
button_grid.h

David Huss authored
The Arduino IDE wants things to be in a folder that has the same name as the ino. Lets do that then.
button_grid.h 5.56 KiB
#ifndef Buttongrid_h
#define Buttongrid_h
#include "Adafruit_SH110X.h"
#include "Adafruit_GFX.h"
#include "potentiometers.h"
#include "buttons.h"
#include "ui.h"
extern Potentiometer pot_1, pot_2, pot_3, pot_4, pot_5, pot_6, pot_7;
extern Button button_1, button_2, button_3, button_4, button_5, button_6;
extern Adafruit_SH1106G display;
// Represents the different types of GridButtons in the UI
enum ButtonType {
BUTTON_TYPE_SIMPLE, // Simple Button that can be pressed
BUTTON_TYPE_TOGGLE, // Toggles between two values (name needs to have a break "\n")
BUTTON_TYPE_MULTITOGGLE, // Toggles between two or more values (name needs to have a break "\n")
BUTTON_TYPE_ENUM, // Toggles between a group of buttons
BUTTON_TYPE_LAST
};
// A Gridbutton is a single button within the Ui-Button Grid
// The name can have multiple lines, delimited by "\n" which
// will be used to represent different states for buttons of
// the type BUTTON_TYPE_TOGGLE or BUTTON_TYPE_MULTITOGGLE
// is_home tells us if this is the home button (and thus should
// be rendered inverted)
class GridButton {
public:
const char* name;
const char* description;
GridButton(const char* name, Button *button, bool is_home=false, ButtonType type=BUTTON_TYPE_SIMPLE, int default_value=0, const char* description="")
:
name(name),
button(button),
is_home(is_home),
type(type),
active(default_value),
description(description)
{
// Count the number of lines in the name
for(int i = 0; name[i] != '\0'; i++) {
if(name[i] == '\n')
++lines;
}
}
Button *button;
ButtonType type;
bool is_home;
bool should_render_description = false;
int active;
int lines = 0;
// Go to the next option
void next() {
active++;
if (active > lines) {
active = 0;
}
}
void renderDescription() {
if (should_render_description) {
display.setTextWrap(true);
display.clearDisplay();
display.setCursor(0,0);
display.setTextColor(SH110X_WHITE);
display.print(description);
display.setTextWrap(false);
}
}
};
// The ButtonGrid is a grid of 2×3 = 6 buttons
class ButtonGrid {
public:
ButtonGrid(int home_mode, const GridButton (&grid_buttons)[6])
: grid_buttons_{
grid_buttons[0],
grid_buttons[1],
grid_buttons[2],
grid_buttons[3],
grid_buttons[4],
grid_buttons[5]
},
ui_mode(home_mode)
{}
GridButton grid_buttons_[6];
int ui_mode;
void setup() {
for (int n=0; n<6; n++) {
if (!grid_buttons_[n].is_home) {
// Not a home button, display help on long hold and hide on release
// grid_buttons_[n].button->onLongHold([this, n](){
// grid_buttons_[n].should_render_description = true;
// });
// grid_buttons_[n].button->onReleased([this, n](){
// grid_buttons_[n].should_render_description = false;
// });
}
}
}
int homeButtonIndex() {
for (int i=0; i<6; i++) {
if (grid_buttons_[i].is_home) {
return i;
}
}
return -1;
}
void hideAllDescriptions() {
for (int i=0; i<6; i++) {
grid_buttons_[i].should_render_description = false;
}
}
void render(int button_enum) {
int width = display.width();
int height = display.height();
int box_width = int(width/3.0f);
int box_height= int(height/2.0f);
int i = 0;
// Draw boxes (2 rows, 3 columns)
for (int box_y=0; box_y<2; box_y++) {
for (int box_x=0; box_x<3; box_x++) {
// Get the current buttons name
const char* name = grid_buttons_[i].name;
// Prepare colors
uint16_t bg_color = SH110X_BLACK;
uint16_t text_color = SH110X_WHITE;
// Home-Buttons have a inverted color scheme
if (grid_buttons_[i].is_home) {
bg_color = SH110X_WHITE;
text_color = SH110X_BLACK;
}
// Position variables
uint16_t x = box_x * box_width;
uint16_t y = box_y * box_height;
uint16_t xc = x + box_width/2;
uint16_t yc = y + box_height/2;
// Fill Background
display.fillRect(x, y, box_width, box_height, bg_color);
// Render the different button types
if (grid_buttons_[i].type == BUTTON_TYPE_TOGGLE) {
centeredTextMarkMulti(name, xc, yc, text_color, grid_buttons_[i].active, 12);
} else if (grid_buttons_[i].type == BUTTON_TYPE_MULTITOGGLE) {
button_multi(name, xc, yc, text_color, grid_buttons_[i].active, grid_buttons_[i].lines);
} else if (grid_buttons_[i].type == BUTTON_TYPE_ENUM) {
bool active = i == button_enum;
centeredTextMark(name, xc, yc, text_color, active);
} else {
centeredText(name, xc, yc, text_color);
}
// Increase ounter for the index of the button
i++;
}
}
// Draw divider lines
display.drawFastVLine(box_width, 0, height, SH110X_WHITE);
display.drawFastVLine(box_width*2, 0, height, SH110X_WHITE);
display.drawFastHLine(0, box_height, width, SH110X_WHITE);
// Render Descriptions on top (hence another loop)
i = 0;
// Draw boxes (2 rows, 3 columns)
for (int box_y=0; box_y<2; box_y++) {
for (int box_x=0; box_x<3; box_x++) {
grid_buttons_[i].renderDescription();
i++;
}
}
}
};
#endif