/*************************************** * cocoapress/preheat_timer_screen.cpp * ***************************************/ /**************************************************************************** * Written By Marcio Teixeira 2019 - Cocoa Press * * * * This program is free software: you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation, either version 3 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * To view a copy of the GNU General Public License, go to the following * * location: . * ****************************************************************************/ #include "../config.h" #include "../screens.h" #include "../screen_data.h" #ifdef COCOA_PREHEAT_SCREEN using namespace FTDI; using namespace ExtUI; using namespace Theme; constexpr static PreheatTimerScreenData &mydata = screen_data.PreheatTimerScreen; #define GRID_COLS 2 #define GRID_ROWS 8 #define HEADER_POS BTN_POS(2,1), BTN_SIZE(1,2) #define NOZZLE_ADJ_POS BTN_POS(2,3), BTN_SIZE(1,2) #define BODY_ADJ_POS BTN_POS(2,5), BTN_SIZE(1,2) #define CHAMBER_ADJ_POS BTN_POS(2,7), BTN_SIZE(1,2) #define PROGRESS_POS BTN_POS(1,1), BTN_SIZE(1,7) #define BACK_POS BTN_POS(1,8), BTN_SIZE(1,1) void PreheatTimerScreen::draw_message(draw_mode_t what) { if (what & BACKGROUND) { CommandProcessor cmd; cmd.cmd(CLEAR_COLOR_RGB(bg_color)) .cmd(CLEAR(true,true,true)) .cmd(COLOR_RGB(bg_text_enabled)) .tag(0); draw_text_box(cmd, HEADER_POS, GET_TEXT_F(MSG_HEATING), OPT_CENTER, font_large); } } uint16_t PreheatTimerScreen::secondsRemaining() { const uint32_t elapsed_sec = (millis() - mydata.start_ms) / 1000; return (COCOA_PRESS_PREHEAT_SECONDS > elapsed_sec) ? COCOA_PRESS_PREHEAT_SECONDS - elapsed_sec : 0; } void PreheatTimerScreen::draw_time_remaining(draw_mode_t what) { if (what & FOREGROUND) { const uint16_t elapsed_sec = secondsRemaining(); const uint8_t min = elapsed_sec / 60, sec = elapsed_sec % 60; char str[10]; sprintf_P(str, PSTR("%02d:%02d"), min, sec); CommandProcessor cmd; cmd.font(font_xlarge); draw_circular_progress(cmd, PROGRESS_POS, float(secondsRemaining()) * 100 / COCOA_PRESS_PREHEAT_SECONDS, str, theme_dark, theme_darkest); } } void PreheatTimerScreen::draw_interaction_buttons(draw_mode_t what) { if (what & FOREGROUND) { CommandProcessor cmd; cmd.colors(normal_btn) .font(font_medium) .tag(1).button(BACK_POS, GET_TEXT_F(MSG_BACK)); } } void PreheatTimerScreen::draw_adjuster(draw_mode_t what, uint8_t tag, progmem_str label, float value, int16_t x, int16_t y, int16_t w, int16_t h) { #define SUB_COLS 9 #define SUB_ROWS 2 #define SUB_GRID_W(W) ((W)*w/SUB_COLS) #define SUB_GRID_H(H) ((H)*h/SUB_ROWS) #define SUB_GRID_X(X) (SUB_GRID_W((X)-1) + x) #define SUB_GRID_Y(Y) (SUB_GRID_H((Y)-1) + y) #define SUB_X(X) (SUB_GRID_X(X) + MARGIN_L) #define SUB_Y(Y) (SUB_GRID_Y(Y) + MARGIN_T) #define SUB_W(W) (SUB_GRID_W(W) - MARGIN_L - MARGIN_R) #define SUB_H(H) (SUB_GRID_H(H) - MARGIN_T - MARGIN_B) #define SUB_POS(X,Y) SUB_X(X), SUB_Y(Y) #define SUB_SIZE(W,H) SUB_W(W), SUB_H(H) CommandProcessor cmd; cmd.tag(0) .font(font_small); if (what & BACKGROUND) { cmd.text( SUB_POS(1,1), SUB_SIZE(9,1), label) .button(SUB_POS(1,2), SUB_SIZE(5,1), F(""), OPT_FLAT); } if (what & FOREGROUND) { char str[32]; dtostrf(value, 5, 1, str); strcat_P(str, PSTR(" ")); strcat_P(str, (const char*) GET_TEXT_F(MSG_UNITS_C)); cmd.text(SUB_POS(1,2), SUB_SIZE(5,1), str) .font(font_medium) .tag(tag ).button(SUB_POS(6,2), SUB_SIZE(2,1), F("-")) .tag(tag+1).button(SUB_POS(8,2), SUB_SIZE(2,1), F("+")); } } void PreheatTimerScreen::onEntry() { mydata.start_ms = millis(); } void PreheatTimerScreen::onRedraw(draw_mode_t what) { draw_message(what); draw_time_remaining(what); draw_interaction_buttons(what); draw_adjuster(what, 2, GET_TEXT_F(MSG_NOZZLE), getTargetTemp_celsius(E0), NOZZLE_ADJ_POS); draw_adjuster(what, 4, GET_TEXT_F(MSG_BODY), getTargetTemp_celsius(E1), BODY_ADJ_POS); draw_adjuster(what, 6, GET_TEXT_F(MSG_CHAMBER), getTargetTemp_celsius(CHAMBER), CHAMBER_ADJ_POS); } bool PreheatTimerScreen::onTouchHeld(uint8_t tag) { const float increment = (tag == 6 || tag == 7) ? 1 : 0.1; switch (tag) { case 2: UI_DECREMENT(TargetTemp_celsius, E0); break; case 3: UI_INCREMENT(TargetTemp_celsius, E0); break; case 4: UI_DECREMENT(TargetTemp_celsius, E1); break; case 5: UI_INCREMENT(TargetTemp_celsius, E1); break; case 6: UI_DECREMENT(TargetTemp_celsius, CHAMBER); break; case 7: UI_INCREMENT(TargetTemp_celsius, CHAMBER); break; default: return false; } return true; } bool PreheatTimerScreen::onTouchEnd(uint8_t tag) { switch (tag) { case 1: GOTO_PREVIOUS(); return true; default: return current_screen.onTouchHeld(tag); } return false; } void PreheatTimerScreen::onIdle() { if (secondsRemaining() == 0) { AlertDialogBox::show(GET_TEXT_F(MSG_PREHEAT_FINISHED)); // Remove SaveSettingsDialogBox from the stack // so the alert box doesn't return to me. current_screen.forget(); } reset_menu_timeout(); if (refresh_timer.elapsed(STATUS_UPDATE_INTERVAL)) { onRefresh(); refresh_timer.start(); } BaseScreen::onIdle(); } #endif // COCOA_PREHEAT_SCREEN