master_clock/src/DisplayHandler.cpp

262 lines
6.1 KiB
C++

// DisplayHandler.cpp
#include "pico/stdlib.h"
#include "DisplayHandler.h"
#include "globals.h"
#include <string>
#include <cstdlib>
#include "hardware/i2c.h"
#include "pico-ssd1306/ssd1306.h"
#include "pico-ssd1306/shapeRenderer/ShapeRenderer.h"
#include "pico-ssd1306/textRenderer/TextRenderer.h"
pico_ssd1306::SSD1306* display = nullptr;
extern void update_BPM(bool up);
DisplayHandler::DisplayHandler(Gate* outputs[]) {
this->outputs = outputs;
currentScreen = 0;
currentOut = -1;
updateScreen = 1;
cursorPosition = 0;
mainMaxCursorPosition = 8;
outMaxCursorPosition = std::size(out_pages) - 1;
cursorClick = 0;
}
void DisplayHandler::setup() {
i2c_init(i2c1, 400 * 1000);
gpio_set_function(SCREEN_SDA_PIN, GPIO_FUNC_I2C);
gpio_set_function(SCREEN_SCL_PIN, GPIO_FUNC_I2C);
gpio_pull_up(SCREEN_SDA_PIN);
gpio_pull_up(SCREEN_SCL_PIN);
display = new pico_ssd1306::SSD1306(i2c1, 0x3C, pico_ssd1306::Size::W128xH64);
display->setOrientation(0);
}
void DisplayHandler::moveCursor(bool dir) {
if (onOutScreen) {
if (cursorClick == 0) {
if (dir == 1) {
cursorPosition++;
currentScreen++;
} else {
cursorPosition--;
currentScreen--;
}
if (cursorPosition > outMaxCursorPosition) {
cursorPosition = 0;
currentScreen = 0;
}
if (cursorPosition < 0) {
cursorPosition = outMaxCursorPosition;
currentScreen = outMaxCursorPosition;
}
} else { // click = 1
if (currentScreen == 1) { // mod screen
outputs[currentOut]->editing = 1;
if (dir == 1) {
outputs[currentOut]->modifierSelectionIndex++;
} else {
outputs[currentOut]->modifierSelectionIndex--;
}
if (outputs[currentOut]->modifierSelectionIndex < 0) {
outputs[currentOut]->modifierSelectionIndex = 0;
}
if (outputs[currentOut]->modifierSelectionIndex > std::size(MOD_TYPES) - 1) {
outputs[currentOut]->modifierSelectionIndex = std::size(MOD_TYPES) - 1;
}
} else if (currentScreen == 2) { // width control
outputs[currentOut]->editing = 1;
if (dir == 1) {
outputs[currentOut]->width++;
} else {
outputs[currentOut]->width--;
}
if (outputs[currentOut]->width > 100) {
outputs[currentOut]->width = 100;
}
if (outputs[currentOut]->width < 1) {
outputs[currentOut]->width = 1;
}
outputs[currentOut]->setWidth(outputs[currentOut]->width);
} else if (currentScreen == 3) {
outputs[currentOut]->editing = 1;
if (dir == 1) {
outputs[currentOut]->p++;
} else {
outputs[currentOut]->p--;
}
if (outputs[currentOut]->p > 100) {
outputs[currentOut]->p = 100;
}
if (outputs[currentOut]->p < 0) {
outputs[currentOut]->p = 0;
}
}
}
} else {
if (cursorPosition == 0 && cursorClick == 1) { // Engage BPM on Main Screen
update_BPM(dir);
} else {
if (dir == 1) {
cursorPosition++;
} else {
cursorPosition--;
}
if (cursorPosition > mainMaxCursorPosition) {
cursorPosition = 0;
}
if (cursorPosition < 0) {
cursorPosition = mainMaxCursorPosition;
}
}
}
updateScreen = 1;
}
void DisplayHandler::handleClick() {
cursorClick ^= true;
if (onOutScreen) {
if (currentScreen == 0) { // exit screen
cursorPosition = currentOut + 1;
currentOut = -1;
currentScreen = 0;
onOutScreen = 0;
cursorClick = false;
}
if (currentScreen == 1 && outputs[currentOut]->editing == 1) {
outputs[currentOut]->setDiv(outputs[currentOut]->modifierSelectionIndex);
outputs[currentOut]->editing = 0;
cursorClick = false;
}
} else {
if (currentScreen == 0) { // on main screen
if (cursorPosition == 0) { // Change BPM
} else if (cursorPosition > 0 && cursorPosition < 9) { // go to out screen
currentOut = cursorPosition - 1;
cursorPosition = 1;
currentScreen = 1;
onOutScreen = 1;
cursorClick = 0;
}
}
}
updateScreen = 1;
}
void DisplayHandler::render() {
if (updateScreen) {
display->clear();
if (currentScreen == 0 && currentOut == -1) { // main screen
renderMainPage();
} else if (currentOut != -1) {
renderOutPage();
}
display->sendBuffer();
updateScreen = 0;
}
}
void DisplayHandler::renderMainPage() {
std::string bpm_string = "BPM: " + std::to_string(BPM);
if (cursorPosition == 0) {
if (cursorClick == 1) {
pico_ssd1306::fillRect(display, 0, 0, 100, 18);
pico_ssd1306::drawText(display, font_12x16, bpm_string.c_str(), 1, 2, pico_ssd1306::WriteMode::SUBTRACT);
} else {
pico_ssd1306::drawRect(display, 0, 0, 100, 18, pico_ssd1306::WriteMode::ADD);
pico_ssd1306::drawText(display, font_12x16, bpm_string.c_str(), 1, 2);
}
} else {
pico_ssd1306::drawText(display, font_12x16, bpm_string.c_str(), 1, 2);
}
uint8_t cursor_x = 2;
uint8_t cursor_y = 25;
for (uint8_t i = 1; i < 9; i++) {
if (i == 5) {
cursor_x = 2;
cursor_y += 20;
}
if (cursorPosition == i) {
pico_ssd1306::drawRect(display, cursor_x - 2, cursor_y - 4, cursor_x + 14, cursor_y + 16, pico_ssd1306::WriteMode::ADD);
}
pico_ssd1306::drawText(display, font_12x16, std::to_string(i).c_str(), cursor_x, cursor_y);
cursor_x += 30;
}
}
void DisplayHandler::renderOutPage() {
uint8_t visualOut = currentOut + 1;
std::string title = std::to_string(visualOut) + "| " + out_pages[currentScreen];
pico_ssd1306::drawText(display, font_12x16, title.c_str(), 1, 2);
std::string param_string;
if (currentScreen == 0) { // exit screen
param_string = "<--";
} else if (currentScreen == 1) { // modifier screen
uint8_t modifier_selection_index = outputs[currentOut]->modifierSelectionIndex;
param_string = MODIFIER_STRINGS[modifier_selection_index];
} else if (currentScreen == 2) { // Width screen
param_string = std::to_string(outputs[currentOut]->width) + "%";
} else if (currentScreen == 3) { // Probability screen
param_string = std::to_string(outputs[currentOut]->p) + "%";
}
if (cursorClick) {
pico_ssd1306::fillRect(display, 1, 42, 50, 60);
pico_ssd1306::drawText(display, font_12x16, param_string.c_str(), 1, 45, pico_ssd1306::WriteMode::SUBTRACT);
} else {
pico_ssd1306::drawText(display, font_12x16, param_string.c_str(), 1, 45);
}
}