You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
376 lines
11 KiB
376 lines
11 KiB
/*************************
|
|
* 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"
|
|
#include "../screens.h"
|
|
|
|
#ifdef FTDI_BIO_STATUS_SCREEN
|
|
|
|
#if ENABLED(TOUCH_UI_PORTRAIT)
|
|
#include "ui_portrait.h"
|
|
#else
|
|
#include "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(F("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));
|
|
|
|
// The LulzBot Bio shows the temperature for
|
|
// the bed.
|
|
|
|
#if ENABLED(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);
|
|
|
|
#if ENABLED(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));
|
|
cmd.font(font_medium);
|
|
|
|
#if ENABLED(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
|
|
}
|
|
}
|
|
|
|
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 = TERN1(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 = 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) {
|
|
ui.button(7, POLY(e_neg), style);
|
|
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(
|
|
#if ENABLED(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 (fill_rgb);
|
|
ui.button_stroke(stroke_rgb, 28);
|
|
ui.button_shadow(shadow_rgb, shadow_depth);
|
|
|
|
constexpr uint8_t style = 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
|
|
#if ENABLED(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(F("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;
|
|
case 13: GOTO_SCREEN(BioConfirmHomeE); break;
|
|
case 14: SpinnerDialogBox::enqueueAndWait(F("G28Z")); 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(FSTR_P pstr) {
|
|
BioPrintingDialogBox::setStatusMessage(pstr);
|
|
}
|
|
|
|
void StatusScreen::setStatusMessage(const char * const str) {
|
|
BioPrintingDialogBox::setStatusMessage(str);
|
|
}
|
|
|
|
void StatusScreen::onIdle() {
|
|
reset_menu_timeout();
|
|
if (refresh_timer.elapsed(STATUS_UPDATE_INTERVAL)) {
|
|
if (!EventLoop::is_touch_held())
|
|
onRefresh();
|
|
if (isPrintingFromMedia())
|
|
BioPrintingDialogBox::show();
|
|
refresh_timer.start();
|
|
}
|
|
}
|
|
|
|
#endif // FTDI_BIO_STATUS_SCREEN
|
|
|