Skip to content
Snippets Groups Projects
Select Git revision
  • b36d3d76de0a2003b1d917cbf90a47eb6b306ebc
  • main default protected
  • fix-buffer
  • feature-individual-lfos
  • feature-individual-volume
  • 1.3.0
  • 1.2.0
  • 1.1.0
  • 1.0.1
  • 1.0.0
10 results

button_grid.h

Blame
  • David Huss's avatar
    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.
    b36d3d76
    History
    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