262 lines
6.1 KiB
C++
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);
|
|
}
|
|
|
|
}
|