DeskControl/src/lib/screen/baseheightentry.cpp

162 lines
4.0 KiB
C++

#include "./calibrate.h"
#include "./home.h"
#include "include/metrics.h"
#include "lib/settings.h"
void BaseHeightEntryScreen::onShow()
{
this->display->setFont(Metrics::LargeFont);
this->display->setTextSize(Metrics::LargeFontTextSize);
this->display->fillScreen(Config::ColorHomeBackground);
this->drawTitle();
this->initHeights();
this->drawArrowUp(Metrics::ArrowMargin, Metrics::LargeTextLineHeight + Metrics::LargeTextLineVArrowYOffset, Config::ColorCalibrateIndicators);
this->drawArrowRight(Metrics::ArrowMargin, Metrics::MiddleLargeTextLineY + Metrics::LargeTextLineHArrowYOffset, Config::ColorCalibrateIndicators);
this->display->setTextColor(Config::ColorCalibrateIndicators);
this->display->setCursor(Metrics::ArrowMargin, Config::DisplayHeight - Metrics::LargeTextLineHeight + Metrics::LargeTextLineYOffset);
this->display->print("OK");
this->drawSetHeight();
}
// Credit: https://stackoverflow.com/questions/101439/the-most-efficient-way-to-implement-an-integer-based-power-function-powint-int
uint16_t ipow(uint16_t base, uint8_t exp)
{
int result = 1;
for (;;)
{
if (exp & 1)
result *= base;
exp >>= 1;
if (!exp)
break;
base *= base;
}
return result;
}
void BaseHeightEntryScreen::onButton(Button button)
{
switch (button)
{
case Button::Top:
{
uint16_t height = this->getHeight();
uint16_t increment = ipow(10, 3 - this->editingDigit);
uint16_t modulus = increment * 10;
uint16_t remainder = height % modulus;
uint16_t offset = height - remainder;
height = offset + ((remainder + increment) % modulus);
if (height > 1999)
height %= 2000;
this->setHeight(height);
this->drawSetHeight();
break;
}
case Button::Middle:
{
this->editingDigit++;
if (this->editingDigit > 3)
this->editingDigit = 0;
this->drawSetHeight();
break;
}
case Button::Bottom:
{
if (!this->isValidHeight())
return;
if (this->nextPage())
{
this->editingDigit = 0;
this->drawTitle();
this->drawSetHeight();
}
break;
}
}
}
void BaseHeightEntryScreen::onTick()
{
}
void BaseHeightEntryScreen::drawTitle()
{
this->drawLargeTextLineCentered(this->getTitle(), 0, Config::ColorMenuHeaderText, Config::ColorMenuHeaderBackground);
}
void BaseHeightEntryScreen::drawSetHeight()
{
char heightText[7];
uint16_t height = this->getHeight();
if (height > 999)
heightText[0] = '0' + ((height / 1000) % 10);
else
heightText[0] = '0';
heightText[1] = '.';
heightText[2] = '0' + ((height / 100) % 10);
heightText[3] = '0' + ((height / 10) % 10);
heightText[4] = '0' + (height % 10);
heightText[5] = 'm';
heightText[6] = 0;
int16_t textX;
int16_t textY;
uint16_t textW;
uint16_t textH;
this->display->getTextBounds(&heightText[0], 0, 0, &textX, &textY, &textW, &textH);
textX = (Config::DisplayWidth - textW) / 2;
uint8_t editingChar = this->editingDigit;
// Skip the dot
if (editingChar > 0)
editingChar++;
if (this->lastTextWidth > 0)
this->display->fillRect((Config::DisplayWidth - this->lastTextWidth) / 2, Metrics::MiddleLargeTextLineY, this->lastTextWidth, Metrics::LargeTextLineHeight, Config::ColorCalibrateBackground);
this->lastTextWidth = textW;
this->display->setTextColor(this->isValidHeight() ? Config::ColorCalibrateValue : Config::ColorCalibrateInvalidValue);
this->display->setCursor(textX, Metrics::MiddleLargeTextLineY + Metrics::LargeTextLineYOffset);
// Draw each character ourselves so we can keep track of where the line should be drawn
for (uint8_t i = 0; i < sizeof(heightText); i++)
{
int16_t cursorStart = this->display->getCursorX();
this->display->print(heightText[i]);
if (i == editingChar)
this->display->drawFastHLine(cursorStart, Metrics::MiddleLargeTextLineY + Metrics::LargeTextLineHeight - 1, this->display->getCursorX() - cursorStart, Config::ColorCalibrateDigitMarker);
}
}