DeskControl/src/lib/screen/calibrate.cpp

205 lines
5.2 KiB
C++

#include "./calibrate.h"
#include "./home.h"
#include "include/metrics.h"
#include "lib/settings.h"
void CalibrateScreen::onShow()
{
this->display->setFont(Metrics::LargeFont);
this->display->setTextSize(Metrics::LargeFontTextSize);
this->display->fillScreen(Config::ColorHomeBackground);
this->drawTitle();
this->height[CalibrateStepCurrent] = Control.getCurrentHeight() + Settings.Height.Offset;
this->height[CalibrateStepMax] = 1969; // TODO: read min/max from settings
this->height[CalibrateStepMin] = 0;
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 CalibrateScreen::onButton(Button button)
{
switch (button)
{
case Button::Top:
{
uint16_t height = this->height[this->step];
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->height[this->step] = 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;
this->step = (CalibrateStep)(this->step + 1);
if (this->step == CalibrateStepCount)
{
// TODO: store new settings
this->screenManager->show<HomeScreen>();
}
else
{
this->drawTitle();
this->drawSetHeight();
}
break;
}
}
}
void CalibrateScreen::onTick()
{
}
bool CalibrateScreen::isValidHeight()
{
switch (this->step)
{
case CalibrateStepCurrent:
return this->height[CalibrateStepCurrent] >= Control.getCurrentHeight();
case CalibrateStepMin:
return this->height[CalibrateStepMin] <= this->height[CalibrateStepCurrent];
case CalibrateStepMax:
return
this->height[CalibrateStepMax] > this->height[CalibrateStepMin] &&
this->height[CalibrateStepMax] >= this->height[CalibrateStepCurrent];
default:
return true;
}
}
void CalibrateScreen::drawTitle()
{
switch (this->step)
{
case CalibrateStepCurrent:
this->drawLargeTextLineCentered("Calibrate", 0, Config::ColorMenuHeaderText, Config::ColorMenuHeaderBackground);
break;
case CalibrateStepMin:
this->drawLargeTextLineCentered("Minimum", 0, Config::ColorMenuHeaderText, Config::ColorMenuHeaderBackground);
break;
case CalibrateStepMax:
this->drawLargeTextLineCentered("Maximum", 0, Config::ColorMenuHeaderText, Config::ColorMenuHeaderBackground);
break;
default:
break;
}
}
void CalibrateScreen::drawSetHeight()
{
char heightText[7];
uint16_t height = this->height[this->step];
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);
}
}