#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(); } 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); } }