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