123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462 |
- /*************************
- * bio_status_screen.cpp *
- *************************/
-
- /****************************************************************************
- * Written By Mark Pelletier 2017 - Aleph Objects, Inc. *
- * Written By Marcio Teixeira 2018 - Aleph Objects, Inc. *
- * 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: <https://www.gnu.org/licenses/>. *
- ****************************************************************************/
-
- #include "../config.h"
-
- #if ENABLED(TOUCH_UI_FTDI_EVE) && ANY(TOUCH_UI_LULZBOT_BIO, TOUCH_UI_COCOA_PRESS)
-
- #include "screens.h"
-
- #include "../ftdi_eve_lib/extras/poly_ui.h"
-
- #if ENABLED(TOUCH_UI_COCOA_PRESS)
- #include "cocoa_press_ui.h"
- #elif ENABLED(TOUCH_UI_PORTRAIT)
- #include "bio_printer_ui_portrait.h"
- #else
- #include "bio_printer_ui_landscape.h"
- #endif
-
- #define GRID_COLS 2
- #define GRID_ROWS 9
-
- #define POLY(A) PolyUI::poly_reader_t(A, sizeof(A)/sizeof(A[0]))
-
- const uint8_t shadow_depth = 5;
- const float max_speed = 1.00;
- const float min_speed = 0.02;
- const float emax_speed = 2.00;
- const float emin_speed = 0.70;
-
- using namespace FTDI;
- using namespace Theme;
- using namespace ExtUI;
-
- float StatusScreen::increment;
- bool StatusScreen::jog_xy;
- bool StatusScreen::fine_motion;
-
- void StatusScreen::unlockMotors() {
- injectCommands_P(PSTR("M84 XY"));
- jog_xy = false;
- }
-
- void StatusScreen::draw_temperature(draw_mode_t what) {
- CommandProcessor cmd;
- PolyUI ui(cmd, what);
-
- int16_t x, y, h, v;
-
- cmd.tag(15);
-
- if (what & BACKGROUND) {
- cmd.cmd(COLOR_RGB(bg_color));
-
- #if ENABLED(TOUCH_UI_LULZBOT_BIO)
- // The LulzBot Bio shows the temperature for
- // the bed.
-
- #ifdef TOUCH_UI_PORTRAIT
- // Draw touch surfaces
- ui.bounds(POLY(target_temp), x, y, h, v);
- cmd.rectangle(x, y, h, v);
- ui.bounds(POLY(actual_temp), x, y, h, v);
- cmd.rectangle(x, y, h, v);
- #else
- ui.bounds(POLY(bed_temp), x, y, h, v);
- cmd.rectangle(x, y, h, v);
- #endif
- ui.bounds(POLY(bed_icon), x, y, h, v);
- cmd.rectangle(x, y, h, v);
-
- // Draw bed icon
- cmd.cmd(BITMAP_SOURCE(Bed_Heat_Icon_Info))
- .cmd(BITMAP_LAYOUT(Bed_Heat_Icon_Info))
- .cmd(BITMAP_SIZE (Bed_Heat_Icon_Info))
- .cmd(COLOR_RGB(shadow_rgb))
- .icon (x + 2, y + 2, h, v, Bed_Heat_Icon_Info, icon_scale * 2)
- .cmd(COLOR_RGB(bg_text_enabled))
- .icon (x, y, h, v, Bed_Heat_Icon_Info, icon_scale * 2);
- #elif ENABLED(TOUCH_UI_COCOA_PRESS) && DISABLED(TOUCH_UI_PORTRAIT)
- // The CocoaPress shows the temperature for two
- // heating zones, but has no bed temperature
-
- cmd.cmd(COLOR_RGB(bg_text_enabled));
- cmd.font(font_xsmall);
-
- ui.bounds(POLY(h0_label), x, y, h, v);
- cmd.text(x, y, h, v, GET_TEXT_F(MSG_ZONE_1));
-
- ui.bounds(POLY(h1_label), x, y, h, v);
- cmd.text(x, y, h, v, GET_TEXT_F(MSG_ZONE_2));
-
- ui.bounds(POLY(h2_label), x, y, h, v);
- cmd.text(x, y, h, v, GET_TEXT_F(MSG_ZONE_3));
-
- ui.bounds(POLY(h3_label), x, y, h, v);
- cmd.text(x, y, h, v, GET_TEXT_F(MSG_CHAMBER));
- #else
- UNUSED(x);
- UNUSED(y);
- UNUSED(h);
- UNUSED(v);
- #endif
-
- #ifdef TOUCH_UI_USE_UTF8
- load_utf8_bitmaps(cmd); // Restore font bitmap handles
- #endif
- }
-
- if (what & FOREGROUND) {
- char str[15];
- cmd.cmd(COLOR_RGB(bg_text_enabled));
- #if ENABLED(TOUCH_UI_LULZBOT_BIO)
- cmd.font(font_medium);
-
- #ifdef TOUCH_UI_PORTRAIT
- if (!isHeaterIdle(BED) && getTargetTemp_celsius(BED) > 0)
- format_temp(str, getTargetTemp_celsius(BED));
- else
- strcpy_P(str, GET_TEXT(MSG_BED));
-
- ui.bounds(POLY(target_temp), x, y, h, v);
- cmd.text(x, y, h, v, str);
-
- format_temp(str, getActualTemp_celsius(BED));
- ui.bounds(POLY(actual_temp), x, y, h, v);
- cmd.text(x, y, h, v, str);
- #else
- if (!isHeaterIdle(BED) && getTargetTemp_celsius(BED) > 0)
- format_temp_and_temp(str, getActualTemp_celsius(BED), getTargetTemp_celsius(BED));
- else
- format_temp_and_idle(str, getActualTemp_celsius(BED));
-
- ui.bounds(POLY(bed_temp), x, y, h, v);
- cmd.text(x, y, h, v, str);
- #endif
-
- #elif ENABLED(TOUCH_UI_COCOA_PRESS) && DISABLED(TOUCH_UI_PORTRAIT)
- // The CocoaPress shows the temperature for two
- // heating zones, but has no bed temperature
-
- cmd.font(font_large);
-
- if (!isHeaterIdle(E0) && getTargetTemp_celsius(E0) > 0)
- format_temp_and_temp(str, getActualTemp_celsius(E0), getTargetTemp_celsius(E0));
- else
- format_temp_and_idle(str, getActualTemp_celsius(E0));
-
- ui.bounds(POLY(h0_temp), x, y, h, v);
- cmd.text(x, y, h, v, str);
-
- if (!isHeaterIdle(E1) && getTargetTemp_celsius(E1) > 0)
- format_temp_and_temp(str, getActualTemp_celsius(E1), getTargetTemp_celsius(E1));
- else
- format_temp_and_idle(str, getActualTemp_celsius(E1));
-
- ui.bounds(POLY(h1_temp), x, y, h, v);
- cmd.text(x, y, h, v, str);
-
- if (!isHeaterIdle(E2) && getTargetTemp_celsius(E2) > 0)
- format_temp_and_temp(str, getActualTemp_celsius(E2), getTargetTemp_celsius(E2));
- else
- format_temp_and_idle(str, getActualTemp_celsius(E2));
-
- ui.bounds(POLY(h2_temp), x, y, h, v);
- cmd.text(x, y, h, v, str);
-
- if (!isHeaterIdle(CHAMBER) && getTargetTemp_celsius(CHAMBER) > 0)
- format_temp_and_temp(str, getActualTemp_celsius(CHAMBER), getTargetTemp_celsius(CHAMBER));
- else
- format_temp_and_idle(str, getActualTemp_celsius(CHAMBER));
-
- ui.bounds(POLY(h3_temp), x, y, h, v);
- cmd.text(x, y, h, v, str);
- #else
- UNUSED(str);
- #endif
- }
- }
-
- void StatusScreen::draw_syringe(draw_mode_t what) {
- int16_t x, y, h, v;
- const float fill_level = (
- #ifdef E_MAX_POS
- 1.0 - min(1.0, max(0.0, getAxisPosition_mm(E0) / E_MAX_POS))
- #else
- 0.75
- #endif
- );
- const bool e_homed = TERN0(TOUCH_UI_LULZBOT_BIO, isAxisPositionKnown(E0));
-
- CommandProcessor cmd;
- PolyUI ui(cmd, what);
-
- if (what & BACKGROUND) {
- // Paint the shadow for the syringe
- ui.color(shadow_rgb);
- ui.shadow(POLY(syringe_outline), shadow_depth);
- }
-
- if (what & FOREGROUND && e_homed) {
- // Paint the syringe icon
- ui.color(syringe_rgb);
- ui.fill(POLY(syringe_outline));
-
- ui.color(fluid_rgb);
- ui.bounds(POLY(syringe_fluid), x, y, h, v);
- cmd.cmd(SAVE_CONTEXT());
- cmd.cmd(SCISSOR_XY(x,y + v * (1.0 - fill_level)));
- cmd.cmd(SCISSOR_SIZE(h, v * fill_level));
- ui.fill(POLY(syringe_fluid), false);
- cmd.cmd(RESTORE_CONTEXT());
-
- ui.color(stroke_rgb);
- ui.fill(POLY(syringe));
- }
- }
-
- void StatusScreen::draw_arrows(draw_mode_t what) {
- const bool e_homed = TERN1(TOUCH_UI_LULZBOT_BIO, isAxisPositionKnown(E0)),
- z_homed = isAxisPositionKnown(Z);
-
- CommandProcessor cmd;
- PolyUI ui(cmd, what);
-
- ui.button_fill (fill_rgb);
- ui.button_stroke(stroke_rgb, 28);
- ui.button_shadow(shadow_rgb, shadow_depth);
-
- constexpr uint8_t style = TERN(TOUCH_UI_COCOA_PRESS, PolyUI::FILL | PolyUI::SHADOW, PolyUI::REGULAR);
-
- if ((what & BACKGROUND) || jog_xy) {
- ui.button(1, POLY(x_neg), style);
- ui.button(2, POLY(x_pos), style);
- ui.button(3, POLY(y_neg), style);
- ui.button(4, POLY(y_pos), style);
- }
-
- if ((what & BACKGROUND) || z_homed) {
- ui.button(5, POLY(z_neg), style);
- ui.button(6, POLY(z_pos), style);
- }
-
- if ((what & BACKGROUND) || e_homed) {
- #if DISABLED(TOUCH_UI_COCOA_PRESS)
- ui.button(7, POLY(e_neg), style);
- #endif
- ui.button(8, POLY(e_pos), style);
- }
- }
-
- void StatusScreen::draw_fine_motion(draw_mode_t what) {
- int16_t x, y, h, v;
- CommandProcessor cmd;
- PolyUI ui(cmd, what);
-
- cmd.font(
- #ifdef TOUCH_UI_PORTRAIT
- font_medium
- #else
- font_small
- #endif
- )
- .tag(16);
-
- if (what & BACKGROUND) {
- ui.bounds(POLY(fine_label), x, y, h, v);
- cmd.cmd(COLOR_RGB(bg_text_enabled))
- .text(x, y, h, v, GET_TEXT_F(MSG_FINE_MOTION));
- }
-
- if (what & FOREGROUND) {
- ui.bounds(POLY(fine_toggle), x, y, h, v);
- cmd.colors(ui_toggle)
- .toggle2(x, y, h, v, GET_TEXT_F(MSG_NO), GET_TEXT_F(MSG_YES), fine_motion);
- }
- }
-
- void StatusScreen::draw_overlay_icons(draw_mode_t what) {
- const bool e_homed = TERN1(TOUCH_UI_LULZBOT_BIO, isAxisPositionKnown(E0)),
- z_homed = isAxisPositionKnown(Z);
-
- CommandProcessor cmd;
- PolyUI ui(cmd, what);
-
- if (what & FOREGROUND) {
- ui.button_fill (TERN(TOUCH_UI_COCOA_PRESS, stroke_rgb, fill_rgb));
- ui.button_stroke(stroke_rgb, 28);
- ui.button_shadow(shadow_rgb, shadow_depth);
-
- constexpr uint8_t style = TERN(TOUCH_UI_COCOA_PRESS, PolyUI::FILL | PolyUI::SHADOW, PolyUI::REGULAR);
- if (!jog_xy) ui.button(12, POLY(padlock), style);
- if (!e_homed) ui.button(13, POLY(home_e), style);
- if (!z_homed) ui.button(14, POLY(home_z), style);
- }
- }
-
- void StatusScreen::draw_buttons(draw_mode_t what) {
- int16_t x, y, h, v;
-
- const bool has_media = isMediaInserted() && !isPrintingFromMedia();
-
- CommandProcessor cmd;
- PolyUI ui(cmd, what);
-
- ui.bounds(POLY(usb_btn), x, y, h, v);
- cmd.font(font_medium)
- .colors(normal_btn)
- .enabled(has_media)
- .colors(has_media ? action_btn : normal_btn)
- .tag(9).button(x, y, h, v,
- isPrintingFromMedia() ?
- GET_TEXT_F(MSG_PRINTING) :
- GET_TEXT_F(MSG_BUTTON_MEDIA)
- );
-
- ui.bounds(POLY(menu_btn), x, y, h, v);
- cmd.colors(!has_media ? action_btn : normal_btn).tag(10).button(x, y, h, v, GET_TEXT_F(MSG_BUTTON_MENU));
- }
-
- void StatusScreen::loadBitmaps() {
- // Load the bitmaps for the status screen
- constexpr uint32_t base = ftdi_memory_map::RAM_G;
- CLCD::mem_write_pgm(base + Bed_Heat_Icon_Info.RAMG_offset, Bed_Heat_Icon, sizeof(Bed_Heat_Icon));
-
- // Load fonts for internationalization
- #ifdef TOUCH_UI_USE_UTF8
- load_utf8_data(base + UTF8_FONT_OFFSET);
- #endif
- }
-
- void StatusScreen::onRedraw(draw_mode_t what) {
- if (what & BACKGROUND) {
- CommandProcessor cmd;
- cmd.cmd(CLEAR_COLOR_RGB(bg_color))
- .cmd(CLEAR(true,true,true))
- .tag(0);
- }
-
- draw_syringe(what);
- draw_temperature(what);
- draw_arrows(what);
- draw_overlay_icons(what);
- draw_buttons(what);
- draw_fine_motion(what);
- }
-
- bool StatusScreen::onTouchStart(uint8_t) {
- increment = 0;
- return true;
- }
-
- bool StatusScreen::onTouchEnd(uint8_t tag) {
- switch (tag) {
- case 1:
- case 2:
- case 3:
- case 4:
- case 12:
- if (!jog_xy) {
- jog_xy = true;
- injectCommands_P(PSTR("M17"));
- }
- jog({ 0, 0, 0 });
- break;
- case 5:
- case 6:
- jog({ 0, 0, 0 });
- break;
- case 9: GOTO_SCREEN(FilesScreen); break;
- case 10: GOTO_SCREEN(MainMenu); break;
- #if ENABLED(TOUCH_UI_LULZBOT_BIO)
- case 13: GOTO_SCREEN(BioConfirmHomeE); break;
- #endif
- case 14: SpinnerDialogBox::enqueueAndWait_P(F("G28 Z")); break;
- case 15: GOTO_SCREEN(TemperatureScreen); break;
- case 16: fine_motion = !fine_motion; break;
- default: return false;
- }
- // If a passcode is enabled, the LockScreen will prevent the
- // user from proceeding.
- LockScreen::check_passcode();
- return true;
- }
-
- bool StatusScreen::onTouchHeld(uint8_t tag) {
- if (tag >= 1 && tag <= 4 && !jog_xy) return false;
- const float s = min_speed + (fine_motion ? 0 : (max_speed - min_speed) * sq(increment));
- switch (tag) {
- case 1: jog({-s, 0, 0}); break;
- case 2: jog({ s, 0, 0}); break;
- case 4: jog({ 0, -s, 0}); break; // NOTE: Y directions inverted because bed rather than needle moves
- case 3: jog({ 0, s, 0}); break;
- case 5: jog({ 0, 0, -s}); break;
- case 6: jog({ 0, 0, s}); break;
- case 7: case 8:
- {
- if (ExtUI::isMoving()) return false;
- const feedRate_t feedrate = emin_speed + (fine_motion ? 0 : (emax_speed - emin_speed) * sq(increment));
- const float increment = 0.25 * feedrate * (tag == 7 ? -1 : 1);
- MoveAxisScreen::setManualFeedrate(E0, feedrate);
- UI_INCREMENT(AxisPosition_mm, E0);
- current_screen.onRefresh();
- break;
- }
- default:
- return false;
- }
- increment = min(1.0f, increment + 0.1f);
- return false;
- }
-
- void StatusScreen::setStatusMessage(progmem_str pstr) {
- #ifdef TOUCH_UI_LULZBOT_BIO
- BioPrintingDialogBox::setStatusMessage(pstr);
- #else
- UNUSED(pstr);
- #endif
- }
-
- void StatusScreen::setStatusMessage(const char * const str) {
- #ifdef TOUCH_UI_LULZBOT_BIO
- BioPrintingDialogBox::setStatusMessage(str);
- #else
- UNUSED(str);
- #endif
- }
-
- void StatusScreen::onIdle() {
- reset_menu_timeout();
- if (refresh_timer.elapsed(STATUS_UPDATE_INTERVAL)) {
- if (!EventLoop::is_touch_held())
- onRefresh();
- #ifdef TOUCH_UI_LULZBOT_BIO
- if (isPrintingFromMedia())
- BioPrintingDialogBox::show();
- #endif
- refresh_timer.start();
- }
- }
-
- #endif // TOUCH_UI_FTDI_EVE
|