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.
2191 lines
69 KiB
2191 lines
69 KiB
/****************************************************************************
|
|
* Written By Mark Pelletier 2018 - Aleph Objects, Inc. *
|
|
* Written By Marcio Teixeira 2018 - Aleph Objects, Inc. *
|
|
* *
|
|
* 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: <http://www.gnu.org/licenses/>. *
|
|
****************************************************************************/
|
|
|
|
#define DISPLAY_UPDATE_INTERVAL 1000
|
|
#define TOUCH_REPEATS_PER_SECOND 4
|
|
#define DEBOUNCE_PERIOD 100
|
|
|
|
// To save MCU RAM, the status message is "baked" in to the status screen
|
|
// cache, so we reserve a large chunk of memory for the DL cache
|
|
|
|
#define STATUS_SCREEN_DL_SIZE 2048
|
|
#define DIALOG_BOX_DL_SIZE 3072
|
|
|
|
#define N_ELEMENTS(a) (sizeof(a)/sizeof(a[0]))
|
|
|
|
/**************************** GRID LAYOUT MACROS **************************/
|
|
|
|
/* The grid layout macros allow buttons to be arranged on a grid so
|
|
* that their locations become independent of the display size. The
|
|
* layout model is similar to that of HTML TABLEs.
|
|
*
|
|
* These macros are meant to be evaluated into constants at compile
|
|
* time, so resolution independence can be as efficient as using
|
|
* hard-coded coordinates.
|
|
*/
|
|
|
|
// Margin defines the margin (in pixels) on each side of a button in
|
|
// the layout
|
|
|
|
#if defined(LCD_800x480)
|
|
#define MARGIN_L 5
|
|
#define MARGIN_R 5
|
|
#define MARGIN_T 5
|
|
#define MARGIN_B 5
|
|
#else
|
|
#define MARGIN_L 3
|
|
#define MARGIN_R 3
|
|
#define MARGIN_T 3
|
|
#define MARGIN_B 3
|
|
#endif
|
|
|
|
// EDGE_R adds some black space on the right edge of the display
|
|
// This shifts some of the screens left to visually center them.
|
|
|
|
#define EDGE_R 0
|
|
|
|
// GRID_X and GRID_Y computes the positions of the divisions on
|
|
// the layout grid.
|
|
#if defined(LCD_PORTRAIT)
|
|
#define GRID_X(x) ((x)*(Vsize-EDGE_R)/GRID_COLS)
|
|
#define GRID_Y(y) ((y)*Hsize/GRID_ROWS)
|
|
#else
|
|
#define GRID_X(x) ((x)*(Hsize-EDGE_R)/GRID_COLS)
|
|
#define GRID_Y(y) ((y)*Vsize/GRID_ROWS)
|
|
#endif
|
|
|
|
// BTN_X, BTN_Y, BTN_W and BTN_X returns the top-left and width
|
|
// and height of a button, taking into account the button margins.
|
|
|
|
#define BTN_X(x) (GRID_X(x-1) + MARGIN_L)
|
|
#define BTN_Y(y) (GRID_Y(y-1) + MARGIN_T)
|
|
#define BTN_W(w) (GRID_X(w) - MARGIN_L - MARGIN_R)
|
|
#define BTN_H(h) (GRID_Y(h) - MARGIN_T - MARGIN_B)
|
|
|
|
// Abbreviations for common phrases, to allow a button to be
|
|
// defined in one line of source.
|
|
#define BTN_POS(x,y) BTN_X(x), BTN_Y(y)
|
|
#define BTN_SIZE(w,h) BTN_W(w), BTN_H(h)
|
|
#define BTN cmd.Cmd_Draw_Button
|
|
#define BTX cmd.Cmd_Draw_Button_Text
|
|
#define BTI cmd.Cmd_Draw_Button_Icon
|
|
#define BTN_TAG(t) cmd.Cmd_Set_Tag(t);
|
|
#define RGB(rgb) cmd.Cmd_Set_Foreground_Color(rgb);
|
|
#define THEME(color) cmd.Cmd_Set_Foreground_Color(Theme::color);
|
|
#define BTN_ENABLED(en) if(en) { \
|
|
cmd.Cmd_Set_Color(Theme::btn_rgb_enabled); \
|
|
cmd.Cmd_Set_Foreground_Color(Theme::btn_fg_enabled); \
|
|
} else { \
|
|
cmd.Cmd_Set_Color(Theme::btn_rgb_disabled); \
|
|
cmd.Cmd_Set_Foreground_Color(Theme::btn_fg_disabled); \
|
|
cmd.Cmd_Set_Tag(0); \
|
|
}
|
|
|
|
#define FONT_SML Theme::font_small
|
|
#define FONT_MED Theme::font_medium
|
|
#define FONT_LRG Theme::font_large
|
|
|
|
#define MENU_BTN_STYLE Theme::font_medium, OPT_3D
|
|
|
|
#define EXEC_GCODE(cmd) Marlin_LCD_API::runGCode(cmd)
|
|
|
|
/****************************** SCREEN STATIC DATA *************************/
|
|
|
|
// To save RAM, store state information related to a particular screen
|
|
// in a union. The values should be initialized in the onEntry method.
|
|
|
|
static union {
|
|
struct {uint8_t increment;} ValueAdjusters;
|
|
struct {uint8_t page, selected_tag;} FilesScreen;
|
|
} screen_data;
|
|
|
|
/************************* MENU SCREEN DECLARATIONS *************************/
|
|
|
|
class BootScreen : public UIScreen {
|
|
public:
|
|
static void onRefresh();
|
|
static void onIdle();
|
|
};
|
|
|
|
class AboutScreen : public UIScreen {
|
|
public:
|
|
static void onEntry();
|
|
static void onRefresh();
|
|
static bool onTouchStart(uint8_t tag);
|
|
};
|
|
|
|
class KillScreen {
|
|
// The KillScreen is behaves differently than the
|
|
// others, so we do not bother extending UIScreen.
|
|
public:
|
|
static void show(progmem_str msg);
|
|
};
|
|
|
|
class DialogBoxBaseClass : public UIScreen {
|
|
protected:
|
|
static void show(const progmem_str message[], size_t lines, progmem_str btn1, progmem_str btn2 );
|
|
static void onRefresh();
|
|
public:
|
|
static bool onTouchStart(uint8_t tag);
|
|
};
|
|
|
|
class AlertBoxScreen : public DialogBoxBaseClass {
|
|
public:
|
|
static void onRefresh();
|
|
static void show(const progmem_str line1, const progmem_str line2 = 0, const progmem_str line3 = 0);
|
|
};
|
|
|
|
class RestoreFailsafeScreen : public DialogBoxBaseClass {
|
|
public:
|
|
static void onRefresh();
|
|
static void onEntry();
|
|
static bool onTouchStart(uint8_t tag);
|
|
};
|
|
|
|
class ConfirmAbortPrint : public DialogBoxBaseClass {
|
|
public:
|
|
static void onRefresh();
|
|
static void onEntry();
|
|
static bool onTouchStart(uint8_t tag);
|
|
};
|
|
|
|
class StatusScreen : public UIScreen {
|
|
private:
|
|
static void static_axis_position();
|
|
static void static_temperature();
|
|
static void static_progress();
|
|
static void static_media_button();
|
|
static void static_interaction_buttons();
|
|
static void static_status_message(const char * const message);
|
|
|
|
static void dynamic_axis_position();
|
|
static void dynamic_temperature();
|
|
static void dynamic_progress();
|
|
static void dynamic_interaction_buttons();
|
|
|
|
public:
|
|
static void setStatusMessage(const char * message);
|
|
static void onRefresh();
|
|
static void onStartup();
|
|
static void onEntry();
|
|
static void onIdle();
|
|
static bool onTouchStart(uint8_t tag);
|
|
};
|
|
|
|
class MenuScreen : public UIScreen {
|
|
public:
|
|
static void onRefresh();
|
|
static bool onTouchStart(uint8_t tag);
|
|
};
|
|
|
|
class TuneScreen : public UIScreen {
|
|
public:
|
|
static void onRefresh();
|
|
static bool onTouchStart(uint8_t tag);
|
|
};
|
|
|
|
class CalibrationScreen : public UIScreen {
|
|
public:
|
|
static void onEntry();
|
|
static void onRefresh();
|
|
static void onIdle();
|
|
};
|
|
|
|
class CalibrationRegistersScreen : public UIScreen {
|
|
public:
|
|
static void onRefresh();
|
|
static bool onTouchStart(uint8_t tag);
|
|
};
|
|
|
|
class AdvancedSettingsScreen : public UIScreen {
|
|
public:
|
|
static void onRefresh();
|
|
static bool onTouchStart(uint8_t tag);
|
|
};
|
|
|
|
class ValueAdjusters : public UIScreen {
|
|
private:
|
|
static void draw_increment_btn(uint8_t line, const uint8_t tag, uint8_t decimals);
|
|
protected:
|
|
struct stacker_t {
|
|
uint8_t line;
|
|
|
|
void static_parts();
|
|
void dynamic_parts();
|
|
};
|
|
|
|
struct heading_t {
|
|
const char *label;
|
|
|
|
void static_parts(stacker_t &s) const;
|
|
void dynamic_parts(stacker_t &s) const;
|
|
};
|
|
|
|
struct adjuster_t {
|
|
uint8_t tag;
|
|
const char *label;
|
|
const char *units;
|
|
uint32_t color;
|
|
uint8_t decimals;
|
|
|
|
void static_parts(stacker_t &s) const;
|
|
void dynamic_parts(stacker_t &s,float value) const;
|
|
};
|
|
|
|
struct increment_t {
|
|
const uint8_t decimals;
|
|
|
|
void static_parts(stacker_t &s) const;
|
|
void dynamic_parts(stacker_t &s) const;
|
|
};
|
|
|
|
static float getIncrement();
|
|
public:
|
|
static void onEntry();
|
|
static bool onTouchStart(uint8_t tag);
|
|
};
|
|
|
|
class MoveAxisScreen : public ValueAdjusters {
|
|
public:
|
|
static void onRefresh();
|
|
static bool onTouchHeld(uint8_t tag);
|
|
};
|
|
|
|
class StepsScreen : public ValueAdjusters {
|
|
public:
|
|
static void onRefresh();
|
|
static bool onTouchHeld(uint8_t tag);
|
|
};
|
|
|
|
class ZOffsetScreen : public ValueAdjusters {
|
|
public:
|
|
static void onRefresh();
|
|
static bool onTouchHeld(uint8_t tag);
|
|
};
|
|
|
|
class FeedrateScreen : public ValueAdjusters {
|
|
public:
|
|
static void onRefresh();
|
|
static bool onTouchHeld(uint8_t tag);
|
|
};
|
|
|
|
class TemperatureScreen : public ValueAdjusters {
|
|
public:
|
|
static void onRefresh();
|
|
static bool onTouchHeld(uint8_t tag);
|
|
};
|
|
|
|
class FilesScreen : public UIScreen {
|
|
private:
|
|
static const char *getSelectedShortFilename();
|
|
static uint8_t getTagForIndex(uint16_t index);
|
|
static uint16_t getIndexForTag(uint8_t tag);
|
|
public:
|
|
static void onEntry();
|
|
static void onRefresh();
|
|
static bool onTouchStart(uint8_t tag);
|
|
};
|
|
|
|
/******************************* MENU SCREEN TABLE ******************************/
|
|
|
|
SCREEN_TABLE {
|
|
DECL_SCREEN(BootScreen),
|
|
DECL_SCREEN(AboutScreen),
|
|
DECL_SCREEN(AlertBoxScreen),
|
|
DECL_SCREEN(RestoreFailsafeScreen),
|
|
DECL_SCREEN(ConfirmAbortPrint),
|
|
DECL_SCREEN(CalibrationScreen),
|
|
DECL_SCREEN(StatusScreen),
|
|
DECL_SCREEN(MenuScreen),
|
|
DECL_SCREEN(TuneScreen),
|
|
DECL_SCREEN(MoveAxisScreen),
|
|
DECL_SCREEN(AdvancedSettingsScreen),
|
|
DECL_SCREEN(StepsScreen),
|
|
DECL_SCREEN(ZOffsetScreen),
|
|
DECL_SCREEN(FeedrateScreen),
|
|
DECL_SCREEN(TemperatureScreen),
|
|
DECL_SCREEN(CalibrationRegistersScreen),
|
|
DECL_SCREEN(FilesScreen),
|
|
};
|
|
|
|
SCREEN_TABLE_POST
|
|
|
|
/********************************* DL CACHE SLOTS ******************************/
|
|
|
|
// In order to reduce SPI traffic, we cache display lists (DL) in RAMG. This
|
|
// is done using the CLCD::DLCache class, which takes a unique ID for each
|
|
// cache location. These IDs are defined here:
|
|
|
|
enum {
|
|
STATUS_SCREEN_CACHE,
|
|
MENU_SCREEN_CACHE,
|
|
TUNE_SCREEN_CACHE,
|
|
DIALOG_BOX_CACHE,
|
|
ADVANCED_SETTINGS_SCREEN_CACHE,
|
|
MOVE_AXIS_SCREEN_CACHE,
|
|
TEMPERATURE_SCREEN_CACHE,
|
|
STEPS_SCREEN_CACHE,
|
|
ZOFFSET_SCREEN_CACHE,
|
|
FEEDRATE_SCREEN_CACHE,
|
|
FILES_SCREEN_CACHE
|
|
};
|
|
|
|
/************************************ MENU THEME ********************************/
|
|
|
|
namespace Theme {
|
|
const uint32_t theme_darkest = 0x2A2F0A;
|
|
const uint32_t theme_dark = 0x495212;
|
|
const uint32_t theme_light = 0x8C9D22;
|
|
|
|
const uint32_t background = theme_dark;
|
|
const uint32_t back_btn = theme_light;
|
|
|
|
const uint32_t x_axis = 0x500000;
|
|
const uint32_t y_axis = 0x005000;
|
|
const uint32_t z_axis = 0x000050;
|
|
const uint32_t e_axis = 0x000000;
|
|
const uint32_t feedrate = 0x000000;
|
|
|
|
const uint32_t toggle_on = theme_light;
|
|
const uint32_t toggle_off = theme_darkest;
|
|
|
|
// Disabled vs enabled buttons
|
|
const uint32_t btn_rgb_enabled = 0xFFFFFF;
|
|
const uint32_t btn_fg_enabled = theme_darkest;
|
|
const uint32_t btn_rgb_disabled = theme_dark;
|
|
const uint32_t btn_fg_disabled = theme_dark;
|
|
|
|
// Files screens
|
|
|
|
const uint32_t files_selected = theme_light;
|
|
|
|
// Adjustment Screens
|
|
|
|
const uint32_t incr_btn = theme_darkest;
|
|
|
|
// Status screen
|
|
const uint32_t status_bg = 0x707070;
|
|
const uint32_t status_dark = 0x404040;
|
|
const uint32_t stop_btn = 0xF02020;
|
|
const uint32_t prnt_btn = 0x20D020;
|
|
const uint32_t progress = 0x404040;
|
|
const uint32_t status_msg = 0x404040;
|
|
const uint32_t fan_speed = 0x6060D0;
|
|
const uint32_t temp = 0xD04000;
|
|
const uint32_t axis_label = 0x404040;
|
|
|
|
// Calibration Registers Screen
|
|
const uint32_t transformA = 0x3010D0;
|
|
const uint32_t transformB = 0x4010D0;
|
|
const uint32_t transformC = 0x5010D0;
|
|
const uint32_t transformD = 0x6010D0;
|
|
const uint32_t transformE = 0x7010D0;
|
|
const uint32_t transformF = 0x8010D0;
|
|
const uint32_t transformVal = 0x104010;
|
|
|
|
#if defined(LCD_800x480)
|
|
#if defined(LCD_PORTRAIT)
|
|
const int16_t font_small = 29;
|
|
const int16_t font_medium = 30;
|
|
const int16_t font_large = 30;
|
|
#else
|
|
const int16_t font_small = 30;
|
|
const int16_t font_medium = 30;
|
|
const int16_t font_large = 31;
|
|
#endif
|
|
const float icon_scale = 1.0;
|
|
#else
|
|
#if defined(LCD_PORTRAIT)
|
|
const int16_t font_small = 27;
|
|
const int16_t font_medium = 28;
|
|
const int16_t font_large = 28;
|
|
const float icon_scale = 0.7;
|
|
#else
|
|
const int16_t font_small = 27;
|
|
const int16_t font_medium = 28;
|
|
const int16_t font_large = 30;
|
|
const float icon_scale = 0.6;
|
|
#endif
|
|
#endif
|
|
|
|
const effect_t press_sound = CHACK;
|
|
const effect_t repeat_sound = CHACK;
|
|
const effect_t unpress_sound = POP;
|
|
};
|
|
|
|
/******************************** BOOT SCREEN ****************************/
|
|
|
|
void BootScreen::onRefresh() {
|
|
CLCD::CommandFifo cmd;
|
|
cmd.Cmd(CMD_DLSTART);
|
|
cmd.Cmd_Set_Clear_Color(Theme::background);
|
|
cmd.Cmd_Clear(1,1,1);
|
|
cmd.Cmd(DL_DISPLAY);
|
|
cmd.Cmd(CMD_SWAP);
|
|
cmd.Cmd_Execute();
|
|
cmd.Cmd_Wait_Until_Idle();
|
|
|
|
CLCD::Turn_On_Backlight();
|
|
CLCD::SoundPlayer::setVolume(255);
|
|
}
|
|
|
|
void BootScreen::onIdle() {
|
|
if(CLCD::Is_Touching()) {
|
|
// If the user is touching the screen at startup, then
|
|
// assume the user wants to re-calibrate the screen.
|
|
// This gives the user the ability to recover a
|
|
// miscalibration that has been stored to EEPROM.
|
|
GOTO_SCREEN(CalibrationScreen);
|
|
} else {
|
|
GOTO_SCREEN(StatusScreen);
|
|
}
|
|
}
|
|
|
|
/******************************** ABOUT SCREEN ****************************/
|
|
|
|
CLCD::SoundPlayer sound;
|
|
|
|
void AboutScreen::onEntry() {
|
|
UIScreen::onEntry();
|
|
|
|
CLCD::Mem_Write8(REG_VOL_SOUND, 0xFF);
|
|
sound.play(chimes);
|
|
}
|
|
|
|
void AboutScreen::onRefresh() {
|
|
CLCD::CommandFifo cmd;
|
|
cmd.Cmd(CMD_DLSTART);
|
|
cmd.Cmd_Set_Clear_Color(Theme::background);
|
|
cmd.Cmd_Clear(1,1,1);
|
|
|
|
#define GRID_COLS 4
|
|
#define GRID_ROWS 8
|
|
|
|
BTX( BTN_POS(1,2), BTN_SIZE(4,1), F("Color LCD Interface"), FONT_LRG);
|
|
BTN_TAG(2)
|
|
BTX( BTN_POS(1,3), BTN_SIZE(4,1), F("(c) 2018 Aleph Objects, Inc."), FONT_LRG);
|
|
|
|
BTX( BTN_POS(1,5), BTN_SIZE(4,1), Marlin_LCD_API::getFirmwareName(), FONT_LRG);
|
|
|
|
BTN_TAG(1) BTN_ENABLED(1) BTN( BTN_POS(2,7), BTN_SIZE(2,1), F("Okay"), MENU_BTN_STYLE);
|
|
|
|
cmd.Cmd(DL_DISPLAY);
|
|
cmd.Cmd(CMD_SWAP);
|
|
cmd.Cmd_Execute();
|
|
}
|
|
|
|
bool AboutScreen::onTouchStart(uint8_t tag) {
|
|
switch(tag) {
|
|
case 1: GOTO_PREVIOUS(); return true;
|
|
case 2: GOTO_SCREEN(CalibrationRegistersScreen); return true;
|
|
}
|
|
}
|
|
|
|
/**************************** GENERIC DIALOG BOX SCREEN ****************************/
|
|
|
|
void DialogBoxBaseClass::show(const progmem_str lines[], size_t n_lines, progmem_str btn1, progmem_str btn2 ) {
|
|
CLCD::DLCache dlcache(DIALOG_BOX_CACHE);
|
|
|
|
CLCD::CommandFifo cmd;
|
|
cmd.Cmd(CMD_DLSTART);
|
|
cmd.Cmd_Set_Clear_Color(Theme::background);
|
|
cmd.Cmd_Clear(1,1,1);
|
|
|
|
#define GRID_COLS 2
|
|
#define GRID_ROWS 8
|
|
|
|
for(uint8_t line = 0; line < n_lines; line++) {
|
|
BTX( BTN_POS(1,3-n_lines/2+line), BTN_SIZE(2,1), lines[line], FONT_LRG);
|
|
}
|
|
|
|
if(btn1 && btn2) {
|
|
BTN_TAG(1) BTN_ENABLED(1) BTN( BTN_POS(1,8), BTN_SIZE(1,1), btn1, MENU_BTN_STYLE);
|
|
BTN_TAG(2) BTN_ENABLED(1) BTN( BTN_POS(2,8), BTN_SIZE(1,1), btn2, MENU_BTN_STYLE);
|
|
} else if(btn1) {
|
|
BTN_TAG(1) BTN_ENABLED(1) BTN( BTN_POS(1,8), BTN_SIZE(2,1), btn1, MENU_BTN_STYLE);
|
|
} else if(btn2) {
|
|
BTN_TAG(2) BTN_ENABLED(1) BTN( BTN_POS(1,8), BTN_SIZE(2,1), btn2, MENU_BTN_STYLE);
|
|
}
|
|
|
|
cmd.Cmd(DL_DISPLAY);
|
|
cmd.Cmd(CMD_SWAP);
|
|
cmd.Cmd_Execute();
|
|
|
|
if(!dlcache.store(DIALOG_BOX_DL_SIZE)) {
|
|
#if defined (SERIAL_PROTOCOLLNPAIR)
|
|
SERIAL_PROTOCOLLN("Unable to set the confirmation message, not enough DL cache space");
|
|
#else
|
|
#if defined(UI_FRAMEWORK_DEBUG)
|
|
Serial.print(F("Unable to set the confirmation message, not enough DL cache space"));
|
|
#endif
|
|
#endif
|
|
}
|
|
}
|
|
|
|
void DialogBoxBaseClass::onRefresh() {
|
|
CLCD::DLCache dlcache(DIALOG_BOX_CACHE);
|
|
CLCD::CommandFifo cmd;
|
|
cmd.Cmd(CMD_DLSTART);
|
|
|
|
if(dlcache.hasData()) {
|
|
dlcache.append();
|
|
}
|
|
|
|
cmd.Cmd(DL_DISPLAY);
|
|
cmd.Cmd(CMD_SWAP);
|
|
cmd.Cmd_Execute();
|
|
}
|
|
|
|
bool DialogBoxBaseClass::onTouchStart(uint8_t tag) {
|
|
switch(tag) {
|
|
case 1: GOTO_PREVIOUS(); return true;
|
|
case 2: GOTO_PREVIOUS(); return true;
|
|
}
|
|
}
|
|
|
|
/****************************** ALERT BOX SCREEN *****************************/
|
|
|
|
void AlertBoxScreen::onRefresh() {
|
|
DialogBoxBaseClass::onRefresh();
|
|
}
|
|
|
|
void AlertBoxScreen::show(const progmem_str line1, const progmem_str line2, const progmem_str line3) {
|
|
progmem_str lines[] = {line1, line2, line3};
|
|
|
|
DialogBoxBaseClass::show(lines, line3 ? 3 : line2 ? 2 : 1, F("Okay"), 0);
|
|
sound.play(c_maj_arpeggio);
|
|
GOTO_SCREEN(AlertBoxScreen);
|
|
}
|
|
|
|
/**************************** RESTORE FAILSAFE SCREEN ***************************/
|
|
|
|
void RestoreFailsafeScreen::onEntry() {
|
|
progmem_str lines[] = {
|
|
F("Are you sure?"),
|
|
F("Customizations will be lost.")
|
|
};
|
|
|
|
DialogBoxBaseClass::show(lines, N_ELEMENTS(lines), F("Yes"), F("No"));
|
|
}
|
|
|
|
void RestoreFailsafeScreen::onRefresh() {
|
|
DialogBoxBaseClass::onRefresh();
|
|
}
|
|
|
|
bool RestoreFailsafeScreen::onTouchStart(uint8_t tag) {
|
|
switch(tag) {
|
|
case 1:
|
|
EXEC_GCODE(F("M502\nM500"));
|
|
AlertBoxScreen::show(F("Factory settings restored."));
|
|
// Remove RestoreFailsafeScreen from the stack
|
|
// so the alert box doesn't return to it.
|
|
current_screen.forget();
|
|
return true;
|
|
default:
|
|
return DialogBoxBaseClass::onTouchStart(tag);
|
|
}
|
|
}
|
|
|
|
/**************************** RESTORE FAILSAFE SCREEN ***************************/
|
|
|
|
void ConfirmAbortPrint::onEntry() {
|
|
progmem_str lines[] = {
|
|
F("Are you sure you want"),
|
|
F("to stop the print?")
|
|
};
|
|
|
|
DialogBoxBaseClass::show(lines, N_ELEMENTS(lines), F("Yes"), F("No"));
|
|
}
|
|
|
|
void ConfirmAbortPrint::onRefresh() {
|
|
DialogBoxBaseClass::onRefresh();
|
|
}
|
|
|
|
bool ConfirmAbortPrint::onTouchStart(uint8_t tag) {
|
|
switch(tag) {
|
|
case 1:
|
|
#if defined (SERIAL_PROTOCOLLNPAIR)
|
|
SERIAL_PROTOCOLLN("Abort confirmed");
|
|
#else
|
|
#if defined(UI_FRAMEWORK_DEBUG)
|
|
Serial.print(F("Abort confirmed"));
|
|
#endif
|
|
#endif
|
|
GOTO_PREVIOUS();
|
|
Marlin_LCD_API::stopPrint();
|
|
return true;
|
|
default:
|
|
return DialogBoxBaseClass::onTouchStart(tag);
|
|
}
|
|
}
|
|
|
|
/************************************ KILL SCREEN *******************************/
|
|
|
|
// The kill screen is an oddball that happens after Marlin has killed the events
|
|
// loop. So we only have a show() method rather than onRefresh(). The KillScreen
|
|
// should not be used as a model for other UI screens as it is an exception.
|
|
|
|
void KillScreen::show(progmem_str message) {
|
|
CLCD::CommandFifo cmd;
|
|
|
|
cmd.Cmd(CMD_DLSTART);
|
|
cmd.Cmd_Set_Clear_Color(Theme::background);
|
|
cmd.Cmd_Clear(1,1,1);
|
|
|
|
#define GRID_COLS 4
|
|
#define GRID_ROWS 8
|
|
|
|
BTX( BTN_POS(1,2), BTN_SIZE(4,1), message, FONT_LRG);
|
|
|
|
BTX( BTN_POS(1,3), BTN_SIZE(4,1), F("PRINTER HALTED"), FONT_LRG);
|
|
|
|
BTX( BTN_POS(1,6), BTN_SIZE(4,1), F("Please reset"), FONT_LRG);
|
|
|
|
cmd.Cmd(DL_DISPLAY);
|
|
cmd.Cmd(CMD_SWAP);
|
|
cmd.Cmd_Execute();
|
|
|
|
sound.play(sad_trombone);
|
|
|
|
// Marlin won't call the idle function anymore,
|
|
// so we have to loop here to play the sounds.
|
|
while(sound.hasMoreNotes()) {
|
|
sound.onIdle();
|
|
}
|
|
}
|
|
|
|
/*********************************** STATUS SCREEN ******************************/
|
|
#if defined(LCD_PORTRAIT)
|
|
#define GRID_ROWS 9
|
|
#define GRID_COLS 3
|
|
#else
|
|
#define GRID_ROWS 8
|
|
#define GRID_COLS 3
|
|
#endif
|
|
|
|
void StatusScreen::static_axis_position() {
|
|
CLCD::CommandFifo cmd;
|
|
|
|
BTN_TAG(6)
|
|
#if defined(LCD_PORTRAIT)
|
|
THEME(axis_label) BTN( BTN_POS(1,5), BTN_SIZE(2,1), F(""), FONT_LRG, OPT_FLAT);
|
|
THEME(axis_label) BTN( BTN_POS(1,6), BTN_SIZE(2,1), F(""), FONT_LRG, OPT_FLAT);
|
|
THEME(axis_label) BTN( BTN_POS(1,7), BTN_SIZE(2,1), F(""), FONT_LRG, OPT_FLAT);
|
|
BTX( BTN_POS(1,5), BTN_SIZE(1,1), F("X"), FONT_SML);
|
|
BTX( BTN_POS(1,6), BTN_SIZE(1,1), F("Y"), FONT_SML);
|
|
BTX( BTN_POS(1,7), BTN_SIZE(1,1), F("Z"), FONT_SML);
|
|
THEME(x_axis) BTN( BTN_POS(2,5), BTN_SIZE(2,1), F(""), FONT_MED, OPT_FLAT);
|
|
THEME(y_axis) BTN( BTN_POS(2,6), BTN_SIZE(2,1), F(""), FONT_MED, OPT_FLAT);
|
|
THEME(z_axis) BTN( BTN_POS(2,7), BTN_SIZE(2,1), F(""), FONT_MED, OPT_FLAT);
|
|
#else
|
|
THEME(axis_label) BTN( BTN_POS(1,5), BTN_SIZE(1,2), F(""), FONT_LRG, OPT_FLAT);
|
|
THEME(axis_label) BTN( BTN_POS(2,5), BTN_SIZE(1,2), F(""), FONT_LRG, OPT_FLAT);
|
|
THEME(axis_label) BTN( BTN_POS(3,5), BTN_SIZE(1,2), F(""), FONT_LRG, OPT_FLAT);
|
|
BTX( BTN_POS(1,5), BTN_SIZE(1,1), F("X"), FONT_SML);
|
|
BTX( BTN_POS(2,5), BTN_SIZE(1,1), F("Y"), FONT_SML);
|
|
BTX( BTN_POS(3,5), BTN_SIZE(1,1), F("Z"), FONT_SML);
|
|
THEME(x_axis) BTN( BTN_POS(1,6), BTN_SIZE(1,1), F(""), FONT_MED, OPT_FLAT);
|
|
THEME(y_axis) BTN( BTN_POS(2,6), BTN_SIZE(1,1), F(""), FONT_MED, OPT_FLAT);
|
|
THEME(z_axis) BTN( BTN_POS(3,6), BTN_SIZE(1,1), F(""), FONT_MED, OPT_FLAT);
|
|
#endif
|
|
}
|
|
|
|
void StatusScreen::dynamic_axis_position() {
|
|
CLCD::CommandFifo cmd;
|
|
|
|
char x_str[15];
|
|
char y_str[15];
|
|
char z_str[15];
|
|
|
|
dtostrf(Marlin_LCD_API::getAxisPosition_mm(Marlin_LCD_API::X), 5, 1, x_str);
|
|
dtostrf(Marlin_LCD_API::getAxisPosition_mm(Marlin_LCD_API::Y), 5, 1, y_str);
|
|
dtostrf(Marlin_LCD_API::getAxisPosition_mm(Marlin_LCD_API::Z), 5, 1, z_str);
|
|
|
|
strcat_P(x_str, PSTR(" mm"));
|
|
strcat_P(y_str, PSTR(" mm"));
|
|
strcat_P(z_str, PSTR(" mm"));
|
|
|
|
BTN_TAG(6)
|
|
#if defined(LCD_PORTRAIT)
|
|
BTX( BTN_POS(2,5), BTN_SIZE(2,1), x_str, FONT_MED);
|
|
BTX( BTN_POS(2,6), BTN_SIZE(2,1), y_str, FONT_MED);
|
|
BTX( BTN_POS(2,7), BTN_SIZE(2,1), z_str, FONT_MED);
|
|
#else
|
|
BTX( BTN_POS(1,6), BTN_SIZE(1,1), x_str, FONT_MED);
|
|
BTX( BTN_POS(2,6), BTN_SIZE(1,1), y_str, FONT_MED);
|
|
BTX( BTN_POS(3,6), BTN_SIZE(1,1), z_str, FONT_MED);
|
|
#endif
|
|
|
|
//#define MARGIN_T 5
|
|
}
|
|
|
|
#if defined(LCD_PORTRAIT)
|
|
#define GRID_COLS 8
|
|
#else
|
|
#define GRID_COLS 12
|
|
#endif
|
|
|
|
void StatusScreen::static_temperature() {
|
|
CLCD::CommandFifo cmd;
|
|
|
|
#if defined(LCD_PORTRAIT)
|
|
BTN_TAG(5)
|
|
THEME(temp) BTN( BTN_POS(1,1), BTN_SIZE(4,2), F(""), FONT_SML, OPT_FLAT);
|
|
THEME(temp) BTN( BTN_POS(1,1), BTN_SIZE(8,1), F(""), FONT_SML, OPT_FLAT);
|
|
THEME(fan_speed) BTN( BTN_POS(5,2), BTN_SIZE(4,1), F(""), FONT_SML, OPT_FLAT);
|
|
BTN_TAG(0)
|
|
THEME(progress) BTN( BTN_POS(1,3), BTN_SIZE(4,1), F(""), FONT_SML, OPT_FLAT);
|
|
THEME(progress) BTN( BTN_POS(5,3), BTN_SIZE(4,1), F(""), FONT_SML, OPT_FLAT);
|
|
#else
|
|
BTN_TAG(5)
|
|
THEME(temp) BTN( BTN_POS(1,1), BTN_SIZE(4,2), F(""), FONT_SML, OPT_FLAT);
|
|
THEME(temp) BTN( BTN_POS(1,1), BTN_SIZE(8,1), F(""), FONT_SML, OPT_FLAT);
|
|
THEME(fan_speed) BTN( BTN_POS(5,2), BTN_SIZE(4,1), F(""), FONT_SML, OPT_FLAT);
|
|
BTN_TAG(0)
|
|
THEME(progress) BTN( BTN_POS(9,1), BTN_SIZE(4,1), F(""), FONT_SML, OPT_FLAT);
|
|
THEME(progress) BTN( BTN_POS(9,2), BTN_SIZE(4,1), F(""), FONT_SML, OPT_FLAT);
|
|
#endif
|
|
|
|
// Draw Extruder Bitmap on Extruder Temperature Button
|
|
|
|
cmd.Cmd_Bitmap_Source(Extruder_Icon_Info);
|
|
cmd.Cmd_Bitmap_Layout(Extruder_Icon_Info);
|
|
cmd.Cmd_Bitmap_Size (Extruder_Icon_Info);
|
|
|
|
BTN_TAG(5)
|
|
BTI(BTN_POS(1,1), BTN_SIZE(1,1), Extruder_Icon_Info, Theme::icon_scale);
|
|
BTI(BTN_POS(5,1), BTN_SIZE(1,1), Extruder_Icon_Info, Theme::icon_scale);
|
|
|
|
// Draw Bed Heat Bitmap on Bed Heat Button
|
|
cmd.Cmd_Bitmap_Source(Bed_Heat_Icon_Info);
|
|
cmd.Cmd_Bitmap_Layout(Bed_Heat_Icon_Info);
|
|
cmd.Cmd_Bitmap_Size (Bed_Heat_Icon_Info);
|
|
|
|
BTI(BTN_POS(1,2), BTN_SIZE(1,1), Bed_Heat_Icon_Info, Theme::icon_scale);
|
|
|
|
// Draw Fan Percent Bitmap on Bed Heat Button
|
|
|
|
cmd.Cmd_Bitmap_Source(Fan_Icon_Info);
|
|
cmd.Cmd_Bitmap_Layout(Fan_Icon_Info);
|
|
cmd.Cmd_Bitmap_Size (Fan_Icon_Info);
|
|
|
|
BTI(BTN_POS(5,2), BTN_SIZE(1,1), Fan_Icon_Info, Theme::icon_scale);
|
|
}
|
|
|
|
#define ROUND(val) uint16_t((val)+0.5)
|
|
|
|
void StatusScreen::dynamic_temperature() {
|
|
CLCD::CommandFifo cmd;
|
|
|
|
char e0_str[15];
|
|
char e1_str[15];
|
|
char bed_str[15];
|
|
char fan_str[15];
|
|
|
|
sprintf_P(
|
|
fan_str,
|
|
PSTR("%-3d %%"),
|
|
int8_t(Marlin_LCD_API::getFan_percent(0))
|
|
);
|
|
|
|
sprintf_P(
|
|
bed_str,
|
|
PSTR("%-3d / %-3d " ),
|
|
ROUND(Marlin_LCD_API::getActualTemp_celsius(0)),
|
|
ROUND(Marlin_LCD_API::getTargetTemp_celsius(0))
|
|
);
|
|
|
|
sprintf_P(
|
|
e0_str,
|
|
PSTR("%-3d / %-3d C"),
|
|
ROUND(Marlin_LCD_API::getActualTemp_celsius(1)),
|
|
ROUND(Marlin_LCD_API::getTargetTemp_celsius(1))
|
|
);
|
|
|
|
#if EXTRUDERS == 2
|
|
sprintf_P(
|
|
e1_str,
|
|
PSTR("%-3d / %-3d C"),
|
|
ROUND(Marlin_LCD_API::getActualTemp_celsius(2)),
|
|
ROUND(Marlin_LCD_API::getTargetTemp_celsius(2))
|
|
);
|
|
#else
|
|
strcpy_P(
|
|
e1_str,
|
|
PSTR("-")
|
|
);
|
|
#endif
|
|
|
|
BTN_TAG(5)
|
|
BTX( BTN_POS(2,1), BTN_SIZE(3,1), e0_str, FONT_MED);
|
|
BTX( BTN_POS(6,1), BTN_SIZE(3,1), e1_str, FONT_MED);
|
|
BTX( BTN_POS(2,2), BTN_SIZE(3,1), bed_str, FONT_MED);
|
|
BTX( BTN_POS(6,2), BTN_SIZE(3,1), fan_str, FONT_MED);
|
|
}
|
|
|
|
void StatusScreen::static_progress() {
|
|
CLCD::CommandFifo cmd;
|
|
|
|
BTN_TAG(0)
|
|
#if defined(LCD_PORTRAIT)
|
|
THEME(progress) BTN( BTN_POS(1,3), BTN_SIZE(4,1), F(""), FONT_SML, OPT_FLAT);
|
|
THEME(progress) BTN( BTN_POS(5,3), BTN_SIZE(4,1), F(""), FONT_SML, OPT_FLAT);
|
|
#else
|
|
THEME(progress) BTN( BTN_POS(9,1), BTN_SIZE(4,1), F(""), FONT_SML, OPT_FLAT);
|
|
THEME(progress) BTN( BTN_POS(9,2), BTN_SIZE(4,1), F(""), FONT_SML, OPT_FLAT);
|
|
#endif
|
|
}
|
|
|
|
void StatusScreen::dynamic_progress() {
|
|
CLCD::CommandFifo cmd;
|
|
|
|
const uint32_t elapsed = Marlin_LCD_API::getProgress_seconds_elapsed();
|
|
const uint8_t hrs = elapsed/3600;
|
|
const uint8_t min = (elapsed/60)%60;
|
|
|
|
char time_str[10];
|
|
char progress_str[10];
|
|
|
|
sprintf_P(time_str, PSTR(" %02d : %02d"), hrs, min);
|
|
sprintf_P(progress_str, PSTR("%-3d %%"), Marlin_LCD_API::getProgress_percent() );
|
|
|
|
#if defined(LCD_PORTRAIT)
|
|
BTN_TAG(0)
|
|
BTX( BTN_POS(1,3), BTN_SIZE(4,1), time_str, FONT_MED);
|
|
BTX( BTN_POS(5,3), BTN_SIZE(4,1), progress_str, FONT_MED);
|
|
#else
|
|
BTN_TAG(0)
|
|
BTX( BTN_POS(9,1), BTN_SIZE(4,1), time_str, FONT_MED);
|
|
BTX( BTN_POS(9,2), BTN_SIZE(4,1), progress_str, FONT_MED);
|
|
#endif
|
|
}
|
|
|
|
#define GRID_COLS 4
|
|
|
|
void StatusScreen::static_media_button() {
|
|
CLCD::CommandFifo cmd;
|
|
|
|
if(Marlin_LCD_API::isMediaInserted()) {
|
|
BTN_TAG(3)
|
|
BTN_ENABLED(1)
|
|
} else {
|
|
BTN_TAG(0)
|
|
cmd.Cmd_Set_Color(Theme::status_bg);
|
|
cmd.Cmd_Set_Foreground_Color(Theme::status_bg);
|
|
}
|
|
|
|
#if defined(LCD_PORTRAIT)
|
|
BTN( BTN_POS(1,9), BTN_SIZE(2,1), F(""), MENU_BTN_STYLE);
|
|
#else
|
|
BTN( BTN_POS(3,7), BTN_SIZE(1,2), F(""), MENU_BTN_STYLE);
|
|
#endif
|
|
|
|
if(!Marlin_LCD_API::isMediaInserted()) {
|
|
cmd.Cmd_Set_Color(Theme::status_dark);
|
|
}
|
|
|
|
// Draw Thumb Drive Bitmap on USB Button
|
|
|
|
cmd.Cmd_Bitmap_Source(TD_Icon_Info);
|
|
cmd.Cmd_Bitmap_Layout(TD_Icon_Info);
|
|
cmd.Cmd_Bitmap_Size (TD_Icon_Info);
|
|
|
|
#if defined(LCD_PORTRAIT)
|
|
BTI(BTN_POS(1,9), BTN_SIZE(2,1), TD_Icon_Info, Theme::icon_scale);
|
|
#else
|
|
BTI(BTN_POS(3,7), BTN_SIZE(1,2), TD_Icon_Info, Theme::icon_scale);
|
|
#endif
|
|
}
|
|
|
|
void StatusScreen::static_interaction_buttons() {
|
|
CLCD::CommandFifo cmd;
|
|
|
|
#if defined(LCD_PORTRAIT)
|
|
BTN_TAG(4) BTN_ENABLED(1) BTN( BTN_POS(3,9), BTN_SIZE(2,1), F("MENU"), MENU_BTN_STYLE);
|
|
#else
|
|
BTN_TAG(4) BTN_ENABLED(1) BTN( BTN_POS(4,7), BTN_SIZE(1,2), F("MENU"), MENU_BTN_STYLE);
|
|
#endif
|
|
}
|
|
|
|
void StatusScreen::dynamic_interaction_buttons() {
|
|
CLCD::CommandFifo cmd;
|
|
|
|
if(Marlin_LCD_API::isPrintingFromMedia()) {
|
|
BTN_TAG(1)
|
|
THEME(stop_btn)
|
|
} else {
|
|
BTN_TAG(0)
|
|
cmd.Cmd_Set_Color(Theme::status_bg);
|
|
cmd.Cmd_Set_Foreground_Color(Theme::status_bg);
|
|
}
|
|
|
|
#if defined(LCD_PORTRAIT)
|
|
BTN( BTN_POS(1,8), BTN_SIZE(4,1), F("STOP"), MENU_BTN_STYLE);
|
|
#else
|
|
BTN( BTN_POS(1,7), BTN_SIZE(2,2), F("STOP"), MENU_BTN_STYLE);
|
|
#endif
|
|
}
|
|
|
|
#define GRID_COLS 1
|
|
|
|
void StatusScreen::static_status_message(const char * const message) {
|
|
CLCD::CommandFifo cmd;
|
|
|
|
BTN_TAG(0)
|
|
#if defined(LCD_PORTRAIT)
|
|
THEME(status_msg) BTN( BTN_POS(1,4), BTN_SIZE(1,1), message, FONT_LRG, OPT_FLAT);
|
|
#else
|
|
THEME(status_msg) BTN( BTN_POS(1,3), BTN_SIZE(1,2), message, FONT_LRG, OPT_FLAT);
|
|
#endif
|
|
}
|
|
|
|
void StatusScreen::setStatusMessage(const char * const message) {
|
|
CLCD::DLCache dlcache(STATUS_SCREEN_CACHE);
|
|
|
|
CLCD::CommandFifo cmd;
|
|
cmd.Cmd(CMD_DLSTART);
|
|
|
|
cmd.Cmd_Set_Clear_Color(Theme::status_bg);
|
|
cmd.Cmd_Clear(1,1,1);
|
|
|
|
static_temperature();
|
|
static_progress();
|
|
static_axis_position();
|
|
static_media_button();
|
|
static_interaction_buttons();
|
|
static_status_message(message);
|
|
|
|
if(!dlcache.store(STATUS_SCREEN_DL_SIZE)) {
|
|
#if defined (SERIAL_PROTOCOLLNPAIR)
|
|
SERIAL_PROTOCOLLNPAIR("Unable to set the status message, not enough DL cache space: ",message);
|
|
#else
|
|
#if defined(UI_FRAMEWORK_DEBUG)
|
|
Serial.print(F("Unable to set the status message, not enough DL cache space: "));
|
|
Serial.println(message);
|
|
#endif
|
|
#endif
|
|
}
|
|
|
|
if(current_screen.getType() == current_screen.lookupScreen(StatusScreen::onRefresh)) {
|
|
onRefresh();
|
|
}
|
|
}
|
|
|
|
#if defined(LCD_PORTRAIT)
|
|
#define GRID_COLS 8
|
|
#else
|
|
#define GRID_COLS 12
|
|
#endif
|
|
|
|
void StatusScreen::onStartup() {
|
|
// Load the bitmaps for the status screen
|
|
|
|
CLCD::Flash_Write_RGB332_Bitmap(TD_Icon_Info.RAMG_addr, TD_Icon, sizeof(TD_Icon));
|
|
CLCD::Flash_Write_RGB332_Bitmap(Extruder_Icon_Info.RAMG_addr, Extruder_Icon, sizeof(Extruder_Icon));
|
|
CLCD::Flash_Write_RGB332_Bitmap(Bed_Heat_Icon_Info.RAMG_addr, Bed_Heat_Icon, sizeof(Bed_Heat_Icon));
|
|
CLCD::Flash_Write_RGB332_Bitmap(Fan_Icon_Info.RAMG_addr, Fan_Icon, sizeof(Fan_Icon));
|
|
}
|
|
|
|
void StatusScreen::onRefresh() {
|
|
CLCD::DLCache dlcache(STATUS_SCREEN_CACHE);
|
|
CLCD::CommandFifo cmd;
|
|
cmd.Cmd(CMD_DLSTART);
|
|
|
|
if(dlcache.hasData()) {
|
|
dlcache.append();
|
|
} else {
|
|
// This should not happen, as setStatusMessage will
|
|
// populate the cache.
|
|
}
|
|
|
|
/* Dynamic content, non-cached data follows */
|
|
|
|
dynamic_temperature();
|
|
dynamic_progress();
|
|
dynamic_axis_position();
|
|
dynamic_interaction_buttons();
|
|
|
|
cmd.Cmd(DL_DISPLAY);
|
|
cmd.Cmd(CMD_SWAP);
|
|
cmd.Cmd_Execute();
|
|
}
|
|
|
|
void StatusScreen::onEntry() {
|
|
onRefresh();
|
|
}
|
|
|
|
void StatusScreen::onIdle() {
|
|
onRefresh();
|
|
}
|
|
|
|
bool StatusScreen::onTouchStart(uint8_t tag) {
|
|
switch(tag) {
|
|
case 1:
|
|
#if defined(UI_FRAMEWORK_DEBUG)
|
|
#if defined (SERIAL_PROTOCOLLNPGM)
|
|
SERIAL_PROTOCOLLNPGM("Aborting print");
|
|
#endif
|
|
#endif
|
|
GOTO_SCREEN(ConfirmAbortPrint);
|
|
break;
|
|
case 3: GOTO_SCREEN(FilesScreen); break;
|
|
case 4:
|
|
if(Marlin_LCD_API::isPrinting()) {
|
|
GOTO_SCREEN(TuneScreen);
|
|
} else {
|
|
GOTO_SCREEN(MenuScreen);
|
|
}
|
|
break;
|
|
case 5: GOTO_SCREEN(TemperatureScreen); break;
|
|
case 6:
|
|
if(!Marlin_LCD_API::isPrinting()) {
|
|
GOTO_SCREEN(MoveAxisScreen);
|
|
}
|
|
break;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
/************************************ MENU SCREEN *******************************/
|
|
|
|
#if defined(LCD_PORTRAIT)
|
|
#define GRID_ROWS 7
|
|
#define GRID_COLS 2
|
|
#else
|
|
#define GRID_ROWS 5
|
|
#define GRID_COLS 2
|
|
#endif
|
|
|
|
void MenuScreen::onRefresh() {
|
|
CLCD::DLCache dlcache(MENU_SCREEN_CACHE);
|
|
CLCD::CommandFifo cmd;
|
|
cmd.Cmd(CMD_DLSTART);
|
|
|
|
if(dlcache.hasData()) {
|
|
dlcache.append();
|
|
} else {
|
|
cmd.Cmd_Set_Clear_Color(Theme::background);
|
|
cmd.Cmd_Clear(1,1,1);
|
|
|
|
#if defined(LCD_PORTRAIT)
|
|
BTN_TAG(2) BTN_ENABLED(1) BTN( BTN_POS(1,1), BTN_SIZE(1,1), F("Auto Home"), MENU_BTN_STYLE);
|
|
BTN_TAG(3) BTN_ENABLED(1) BTN( BTN_POS(2,1), BTN_SIZE(1,1), F("Auto Level"), MENU_BTN_STYLE);
|
|
BTN_TAG(4) BTN_ENABLED(1) BTN( BTN_POS(1,2), BTN_SIZE(1,1), F("Move Axis"), MENU_BTN_STYLE);
|
|
BTN_TAG(5) BTN_ENABLED(1) BTN( BTN_POS(2,2), BTN_SIZE(1,1), F("Motors Off"), MENU_BTN_STYLE);
|
|
BTN_TAG(6) BTN_ENABLED(1) BTN( BTN_POS(1,3), BTN_SIZE(2,1), F("Temperature"), MENU_BTN_STYLE);
|
|
BTN_TAG(7) BTN_ENABLED(0) BTN( BTN_POS(1,4), BTN_SIZE(2,1), F("Change Filament"), MENU_BTN_STYLE);
|
|
BTN_TAG(8) BTN_ENABLED(1) BTN( BTN_POS(1,5), BTN_SIZE(2,1), F("Advanced Settings"), MENU_BTN_STYLE);
|
|
BTN_TAG(9) BTN_ENABLED(1) BTN( BTN_POS(1,6), BTN_SIZE(2,1), F("About Firmware"), MENU_BTN_STYLE);
|
|
#else
|
|
BTN_TAG(2) BTN_ENABLED(1) BTN( BTN_POS(1,1), BTN_SIZE(1,1), F("Auto Home"), MENU_BTN_STYLE);
|
|
BTN_TAG(3) BTN_ENABLED(1) BTN( BTN_POS(2,1), BTN_SIZE(1,1), F("Auto Level"), MENU_BTN_STYLE);
|
|
BTN_TAG(4) BTN_ENABLED(1) BTN( BTN_POS(1,2), BTN_SIZE(1,1), F("Move Axis"), MENU_BTN_STYLE);
|
|
BTN_TAG(5) BTN_ENABLED(1) BTN( BTN_POS(2,2), BTN_SIZE(1,1), F("Motors Off"), MENU_BTN_STYLE);
|
|
BTN_TAG(6) BTN_ENABLED(1) BTN( BTN_POS(1,3), BTN_SIZE(1,1), F("Temperature"), MENU_BTN_STYLE);
|
|
BTN_TAG(7) BTN_ENABLED(0) BTN( BTN_POS(2,3), BTN_SIZE(1,1), F("Change Filament"), MENU_BTN_STYLE);
|
|
BTN_TAG(8) BTN_ENABLED(1) BTN( BTN_POS(1,4), BTN_SIZE(1,1), F("Advanced Settings"), MENU_BTN_STYLE);
|
|
BTN_TAG(9) BTN_ENABLED(1) BTN( BTN_POS(2,4), BTN_SIZE(1,1), F("About Firmware"), MENU_BTN_STYLE);
|
|
#endif
|
|
|
|
#if defined(LCD_PORTRAIT)
|
|
#define MARGIN_T 15
|
|
BTN_TAG(1) THEME(back_btn) BTN( BTN_POS(1,7), BTN_SIZE(2,1), F("Back"), MENU_BTN_STYLE);
|
|
#else
|
|
BTN_TAG(1) THEME(back_btn) BTN( BTN_POS(1,5), BTN_SIZE(2,1), F("Back"), MENU_BTN_STYLE);
|
|
#endif
|
|
|
|
#define MARGIN_T 5
|
|
|
|
dlcache.store();
|
|
}
|
|
|
|
cmd.Cmd(DL_DISPLAY);
|
|
cmd.Cmd(CMD_SWAP);
|
|
cmd.Cmd_Execute();
|
|
}
|
|
|
|
bool MenuScreen::onTouchStart(uint8_t tag) {
|
|
switch(tag) {
|
|
case 1: GOTO_PREVIOUS(); break;
|
|
case 2: EXEC_GCODE(F("G28")); break;
|
|
case 3: EXEC_GCODE(F(LULZBOT_MENU_AXIS_LEVELING_GCODE)); break;
|
|
case 4: GOTO_SCREEN(MoveAxisScreen); break;
|
|
case 5: EXEC_GCODE(F("M84")); break;
|
|
case 6: GOTO_SCREEN(TemperatureScreen); break;
|
|
case 8: GOTO_SCREEN(AdvancedSettingsScreen); break;
|
|
case 9: GOTO_SCREEN(AboutScreen); break;
|
|
default:
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
/************************************ TUNE SCREEN *******************************/
|
|
|
|
#if defined(LCD_PORTRAIT)
|
|
#define GRID_ROWS 5
|
|
#define GRID_COLS 2
|
|
#else
|
|
#define GRID_ROWS 3
|
|
#define GRID_COLS 2
|
|
#endif
|
|
|
|
void TuneScreen::onRefresh() {
|
|
CLCD::DLCache dlcache(TUNE_SCREEN_CACHE);
|
|
CLCD::CommandFifo cmd;
|
|
cmd.Cmd(CMD_DLSTART);
|
|
|
|
if(dlcache.hasData()) {
|
|
dlcache.append();
|
|
} else {
|
|
cmd.Cmd_Set_Clear_Color(Theme::background);
|
|
cmd.Cmd_Clear(1,1,1);
|
|
|
|
#if defined(LCD_PORTRAIT)
|
|
BTN_TAG(2) BTN_ENABLED(1) BTN( BTN_POS(1,1), BTN_SIZE(2,1), F("Temperature"), MENU_BTN_STYLE);
|
|
BTN_TAG(3) BTN_ENABLED(0) BTN( BTN_POS(1,2), BTN_SIZE(2,1), F("Change Filament"), MENU_BTN_STYLE);
|
|
BTN_TAG(4) BTN_ENABLED(1) BTN( BTN_POS(1,3), BTN_SIZE(2,1), F("Z Offset"), MENU_BTN_STYLE);
|
|
BTN_TAG(5) BTN_ENABLED(1) BTN( BTN_POS(1,4), BTN_SIZE(2,1), F("Print Speed"), MENU_BTN_STYLE);
|
|
#else
|
|
BTN_TAG(2) BTN_ENABLED(1) BTN( BTN_POS(1,1), BTN_SIZE(1,1), F("Temperature"), MENU_BTN_STYLE);
|
|
BTN_TAG(3) BTN_ENABLED(0) BTN( BTN_POS(1,2), BTN_SIZE(1,1), F("Change Filament"), MENU_BTN_STYLE);
|
|
BTN_TAG(4) BTN_ENABLED(1) BTN( BTN_POS(2,1), BTN_SIZE(1,1), F("Z Offset"), MENU_BTN_STYLE);
|
|
BTN_TAG(5) BTN_ENABLED(1) BTN( BTN_POS(2,2), BTN_SIZE(2,1), F("Print Speed"), MENU_BTN_STYLE);
|
|
#endif
|
|
|
|
#if defined(LCD_PORTRAIT)
|
|
#define MARGIN_T 15
|
|
BTN_TAG(1) THEME(back_btn) BTN( BTN_POS(1,5), BTN_SIZE(2,1), F("Back"), MENU_BTN_STYLE);
|
|
#else
|
|
BTN_TAG(1) THEME(back_btn) BTN( BTN_POS(1,3), BTN_SIZE(2,1), F("Back"), MENU_BTN_STYLE);
|
|
#endif
|
|
|
|
#define MARGIN_T 5
|
|
|
|
dlcache.store();
|
|
}
|
|
|
|
cmd.Cmd(DL_DISPLAY);
|
|
cmd.Cmd(CMD_SWAP);
|
|
cmd.Cmd_Execute();
|
|
}
|
|
|
|
bool TuneScreen::onTouchStart(uint8_t tag) {
|
|
switch(tag) {
|
|
case 1: GOTO_PREVIOUS(); break;
|
|
case 2: GOTO_SCREEN(TemperatureScreen); break;
|
|
case 4: GOTO_SCREEN(ZOffsetScreen); break;
|
|
case 5: GOTO_SCREEN(FeedrateScreen); break;
|
|
default:
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
/******************************* CONFIGURATION SCREEN ****************************/
|
|
|
|
#if defined(LCD_PORTRAIT)
|
|
#define GRID_ROWS 7
|
|
#define GRID_COLS 2
|
|
#else
|
|
#define GRID_ROWS 4
|
|
#define GRID_COLS 2
|
|
#endif
|
|
|
|
void AdvancedSettingsScreen::onRefresh() {
|
|
CLCD::DLCache dlcache(ADVANCED_SETTINGS_SCREEN_CACHE);
|
|
CLCD::CommandFifo cmd;
|
|
cmd.Cmd(CMD_DLSTART);
|
|
|
|
if(dlcache.hasData()) {
|
|
dlcache.append();
|
|
} else {
|
|
cmd.Cmd_Set_Clear_Color(Theme::background);
|
|
cmd.Cmd_Clear(1,1,1);
|
|
|
|
#if defined(LCD_PORTRAIT)
|
|
BTN_TAG(4) BTN_ENABLED(1) BTN( BTN_POS(1,1), BTN_SIZE(1,2), F("Z Offset "), MENU_BTN_STYLE);
|
|
BTN_TAG(5) BTN_ENABLED(1) BTN( BTN_POS(1,3), BTN_SIZE(1,1), F("Steps/mm"), MENU_BTN_STYLE);
|
|
|
|
BTN_TAG(6) BTN_ENABLED(0) BTN( BTN_POS(2,1), BTN_SIZE(1,1), F("Velocity "), MENU_BTN_STYLE);
|
|
BTN_TAG(7) BTN_ENABLED(0) BTN( BTN_POS(2,2), BTN_SIZE(1,1), F("Acceleration"), MENU_BTN_STYLE);
|
|
BTN_TAG(8) BTN_ENABLED(0) BTN( BTN_POS(2,3), BTN_SIZE(1,1), F("Jerk"), MENU_BTN_STYLE);
|
|
BTN_TAG(9) BTN_ENABLED(1) BTN( BTN_POS(1,4), BTN_SIZE(2,1), F("Recalibrate Screen"), MENU_BTN_STYLE);
|
|
BTN_TAG(10) BTN_ENABLED(1) BTN( BTN_POS(1,5), BTN_SIZE(2,1), F("Restore Factory Settings"), MENU_BTN_STYLE);
|
|
BTN_TAG(2) BTN_ENABLED(1) BTN( BTN_POS(1,6), BTN_SIZE(2,1), F("Save As Default"), MENU_BTN_STYLE);
|
|
BTN_TAG(1) THEME(back_btn) BTN( BTN_POS(1,7), BTN_SIZE(2,1), F("Back"), MENU_BTN_STYLE);
|
|
#else
|
|
BTN_TAG(4) BTN_ENABLED(1) BTN( BTN_POS(1,1), BTN_SIZE(1,1), F("Z Offset "), MENU_BTN_STYLE);
|
|
BTN_TAG(5) BTN_ENABLED(1) BTN( BTN_POS(1,2), BTN_SIZE(1,1), F("Steps/mm"), MENU_BTN_STYLE);
|
|
|
|
BTN_TAG(6) BTN_ENABLED(0) BTN( BTN_POS(2,1), BTN_SIZE(1,1), F("Velocity "), MENU_BTN_STYLE);
|
|
BTN_TAG(7) BTN_ENABLED(0) BTN( BTN_POS(2,2), BTN_SIZE(1,1), F("Acceleration"), MENU_BTN_STYLE);
|
|
BTN_TAG(8) BTN_ENABLED(0) BTN( BTN_POS(2,3), BTN_SIZE(1,1), F("Jerk"), MENU_BTN_STYLE);
|
|
BTN_TAG(10) BTN_ENABLED(1) BTN( BTN_POS(1,3), BTN_SIZE(1,1), F("Restore Failsafe"), MENU_BTN_STYLE);
|
|
|
|
BTN_TAG(2) BTN_ENABLED(1) BTN( BTN_POS(1,4), BTN_SIZE(1,1), F("Save"), MENU_BTN_STYLE);
|
|
BTN_TAG(1) THEME(back_btn) BTN( BTN_POS(2,4), BTN_SIZE(1,1), F("Back"), MENU_BTN_STYLE);
|
|
#endif
|
|
|
|
dlcache.store();
|
|
}
|
|
|
|
cmd.Cmd(DL_DISPLAY);
|
|
cmd.Cmd(CMD_SWAP);
|
|
cmd.Cmd_Execute();
|
|
}
|
|
|
|
bool AdvancedSettingsScreen::onTouchStart(uint8_t tag) {
|
|
switch(tag) {
|
|
case 1: GOTO_PREVIOUS(); break;
|
|
case 2:
|
|
current_screen.pop();
|
|
EXEC_GCODE(F("M500"));
|
|
AlertBoxScreen::show(F("Settings saved!"));
|
|
break;
|
|
case 4: GOTO_SCREEN(ZOffsetScreen); break;
|
|
case 5: GOTO_SCREEN(StepsScreen); break;
|
|
case 9: GOTO_SCREEN(CalibrationScreen); break;
|
|
case 10: GOTO_SCREEN(RestoreFailsafeScreen); break;
|
|
default:
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
/******************************** CALIBRATION SCREEN ****************************/
|
|
|
|
#define GRID_COLS 4
|
|
#define GRID_ROWS 16
|
|
|
|
void CalibrationScreen::onEntry() {
|
|
// Clear the display
|
|
CLCD::CommandFifo cmd;
|
|
cmd.Cmd(CMD_DLSTART);
|
|
cmd.Cmd_Set_Clear_Color(Theme::background);
|
|
cmd.Cmd_Clear(1,1,1);
|
|
cmd.Cmd(DL_DISPLAY);
|
|
cmd.Cmd(CMD_SWAP);
|
|
cmd.Cmd_Execute();
|
|
|
|
// Wait for the touch to release before starting,
|
|
// as otherwise the first calibration point could
|
|
// be misinterpreted.
|
|
while(CLCD::Is_Touching()) {
|
|
#if defined(UI_FRAMEWORK_DEBUG)
|
|
#if defined (SERIAL_PROTOCOLLNPGM)
|
|
SERIAL_PROTOCOLLNPGM("Waiting for touch release");
|
|
#endif
|
|
#endif
|
|
}
|
|
UIScreen::onEntry();
|
|
}
|
|
|
|
void CalibrationScreen::onRefresh() {
|
|
CLCD::CommandFifo cmd;
|
|
cmd.Cmd(CMD_DLSTART);
|
|
cmd.Cmd_Set_Clear_Color(Theme::background);
|
|
cmd.Cmd_Clear(1,1,1);
|
|
|
|
#if defined(LCD_PORTRAIT)
|
|
BTX( BTN_POS(1,8), BTN_SIZE(4,1), F("Touch the dots"), FONT_LRG);
|
|
BTX( BTN_POS(1,9), BTN_SIZE(4,1), F("to calibrate"), FONT_LRG);
|
|
#else
|
|
#if defined(LCD_800x480)
|
|
BTX( BTN_POS(1,1), BTN_SIZE(4,16), F("Touch the dots to calibrate"), FONT_LRG);
|
|
#else
|
|
BTX( BTN_POS(1,1), BTN_SIZE(4,16), F("Touch the dots to calibrate"), FONT_MED);
|
|
#endif
|
|
#endif
|
|
|
|
cmd.Cmd(CMD_CALIBRATE);
|
|
cmd.Cmd(DL_DISPLAY);
|
|
cmd.Cmd(CMD_SWAP);
|
|
cmd.Cmd_Execute();
|
|
}
|
|
|
|
void CalibrationScreen::onIdle() {
|
|
if(CLCD::CommandFifo::Cmd_Is_Idle()) {
|
|
#if defined(UI_FRAMEWORK_DEBUG)
|
|
#if defined (SERIAL_PROTOCOLLNPGM)
|
|
SERIAL_PROTOCOLLNPGM("Calibration finished");
|
|
#endif
|
|
#endif
|
|
GOTO_SCREEN(StatusScreen);
|
|
}
|
|
#if defined(UI_FRAMEWORK_DEBUG)
|
|
else {
|
|
#if defined (SERIAL_PROTOCOLLNPGM)
|
|
SERIAL_PROTOCOLLNPGM("Waiting for calibration to finish.");
|
|
#endif
|
|
}
|
|
#endif
|
|
}
|
|
|
|
/***************************** CALIBRATION REGISTERS SCREEN ****************************/
|
|
|
|
#define MARGIN_T 5
|
|
#define GRID_ROWS 7
|
|
#define GRID_COLS 2
|
|
|
|
void CalibrationRegistersScreen::onRefresh() {
|
|
const uint32_t T_Transform_A = CLCD::Mem_Read32(REG_TOUCH_TRANSFORM_A);
|
|
const uint32_t T_Transform_B = CLCD::Mem_Read32(REG_TOUCH_TRANSFORM_B);
|
|
const uint32_t T_Transform_C = CLCD::Mem_Read32(REG_TOUCH_TRANSFORM_C);
|
|
const uint32_t T_Transform_D = CLCD::Mem_Read32(REG_TOUCH_TRANSFORM_D);
|
|
const uint32_t T_Transform_E = CLCD::Mem_Read32(REG_TOUCH_TRANSFORM_E);
|
|
const uint32_t T_Transform_F = CLCD::Mem_Read32(REG_TOUCH_TRANSFORM_F);
|
|
char b[20];
|
|
|
|
CLCD::CommandFifo cmd;
|
|
cmd.Cmd(CMD_DLSTART);
|
|
cmd.Cmd_Set_Clear_Color(Theme::background);
|
|
cmd.Cmd_Clear(1,1,1);
|
|
|
|
BTN_TAG(0)
|
|
THEME(transformA) BTN( BTN_POS(1,1), BTN_SIZE(1,1), F("TOUCH TRANSFORM_A"), 28, OPT_3D);
|
|
THEME(transformB) BTN( BTN_POS(1,2), BTN_SIZE(1,1), F("TOUCH TRANSFORM_B"), 28, OPT_3D);
|
|
THEME(transformC) BTN( BTN_POS(1,3), BTN_SIZE(1,1), F("TOUCH TRANSFORM_C"), 28, OPT_3D);
|
|
THEME(transformD) BTN( BTN_POS(1,4), BTN_SIZE(1,1), F("TOUCH TRANSFORM_D"), 28, OPT_3D);
|
|
THEME(transformE) BTN( BTN_POS(1,5), BTN_SIZE(1,1), F("TOUCH TRANSFORM_E"), 28, OPT_3D);
|
|
THEME(transformF) BTN( BTN_POS(1,6), BTN_SIZE(1,1), F("TOUCH TRANSFORM_F"), 28, OPT_3D);
|
|
|
|
THEME(transformVal) BTN( BTN_POS(2,1), BTN_SIZE(1,1), F(""), 28, OPT_FLAT);
|
|
THEME(transformVal) BTN( BTN_POS(2,2), BTN_SIZE(1,1), F(""), 28, OPT_FLAT);
|
|
THEME(transformVal) BTN( BTN_POS(2,3), BTN_SIZE(1,1), F(""), 28, OPT_FLAT);
|
|
THEME(transformVal) BTN( BTN_POS(2,4), BTN_SIZE(1,1), F(""), 28, OPT_FLAT);
|
|
THEME(transformVal) BTN( BTN_POS(2,5), BTN_SIZE(1,1), F(""), 28, OPT_FLAT);
|
|
THEME(transformVal) BTN( BTN_POS(2,6), BTN_SIZE(1,1), F(""), 28, OPT_FLAT);
|
|
|
|
sprintf_P(b, PSTR("0x%08lX"), T_Transform_A); BTX( BTN_POS(2,1), BTN_SIZE(1,1), b, 28);
|
|
sprintf_P(b, PSTR("0x%08lX"), T_Transform_B); BTX( BTN_POS(2,2), BTN_SIZE(1,1), b, 28);
|
|
sprintf_P(b, PSTR("0x%08lX"), T_Transform_C); BTX( BTN_POS(2,3), BTN_SIZE(1,1), b, 28);
|
|
sprintf_P(b, PSTR("0x%08lX"), T_Transform_D); BTX( BTN_POS(2,4), BTN_SIZE(1,1), b, 28);
|
|
sprintf_P(b, PSTR("0x%08lX"), T_Transform_E); BTX( BTN_POS(2,5), BTN_SIZE(1,1), b, 28);
|
|
sprintf_P(b, PSTR("0x%08lX"), T_Transform_F); BTX( BTN_POS(2,6), BTN_SIZE(1,1), b, 28);
|
|
|
|
#define GRID_COLS 3
|
|
|
|
BTN_TAG(1) THEME(back_btn) BTN( BTN_POS(3,7), BTN_SIZE(1,1), F("Back"), MENU_BTN_STYLE);
|
|
|
|
cmd.Cmd(DL_DISPLAY);
|
|
cmd.Cmd(CMD_SWAP);
|
|
cmd.Cmd_Execute();
|
|
|
|
sound.play(js_bach_joy);
|
|
}
|
|
|
|
bool CalibrationRegistersScreen::onTouchStart(uint8_t tag) {
|
|
switch(tag) {
|
|
case 1: GOTO_PREVIOUS(); break;
|
|
default:
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
/*************************** GENERIC VALUE ADJUSTMENT SCREEN ******************************/
|
|
|
|
#if defined(LCD_PORTRAIT)
|
|
#define GRID_COLS 6
|
|
#define GRID_ROWS 10
|
|
#else
|
|
#define GRID_COLS 9
|
|
#define GRID_ROWS 6
|
|
#endif
|
|
|
|
void ValueAdjusters::stacker_t::static_parts() {
|
|
CLCD::CommandFifo cmd;
|
|
cmd.Cmd_Set_Clear_Color(Theme::background);
|
|
cmd.Cmd_Clear(1,1,1);
|
|
|
|
#if defined(LCD_PORTRAIT)
|
|
BTN_TAG(1) THEME(back_btn) BTN( BTN_POS(1,10), BTN_SIZE(6,1), F("Back"), MENU_BTN_STYLE);
|
|
#else
|
|
BTN_TAG(1) THEME(back_btn) BTN( BTN_POS(8,6), BTN_SIZE(2,1), F("Back"), MENU_BTN_STYLE);
|
|
#endif
|
|
|
|
line = 1;
|
|
}
|
|
|
|
void ValueAdjusters::stacker_t::dynamic_parts() {
|
|
line = 1;
|
|
}
|
|
|
|
void ValueAdjusters::draw_increment_btn(uint8_t line, const uint8_t tag, uint8_t decimals) {
|
|
CLCD::CommandFifo cmd;
|
|
const char *label = PSTR("?");
|
|
uint8_t pos;
|
|
|
|
switch(tag) {
|
|
case 240: label = PSTR( ".001"); pos = decimals - 3; break;
|
|
case 241: label = PSTR( ".01" ); pos = decimals - 2; break;
|
|
case 242: label = PSTR( "0.1" ); pos = decimals - 1; break;
|
|
case 243: label = PSTR( "1" ); pos = decimals + 0; break;
|
|
case 244: label = PSTR( "10" ); pos = decimals + 1; break;
|
|
case 245: label = PSTR("100" ); pos = decimals + 2; break;
|
|
default:
|
|
#if defined(UI_FRAMEWORK_DEBUG)
|
|
#if defined(SERIAL_PROTOCOLLNPAIR)
|
|
SERIAL_PROTOCOLLNPAIR("Unknown tag for increment btn: ", tag);
|
|
#else
|
|
Serial.print(F("Unknown tag for increment btn:"));
|
|
Serial.println(tag);
|
|
#endif
|
|
#endif
|
|
;
|
|
}
|
|
|
|
BTN_TAG(tag)
|
|
switch(pos) {
|
|
#if defined(LCD_PORTRAIT)
|
|
case 0: BTN( BTN_POS(3,line), BTN_SIZE(1,1), progmem_str(label), FONT_SML, OPT_3D); break;
|
|
case 1: BTN( BTN_POS(4,line), BTN_SIZE(1,1), progmem_str(label), FONT_SML, OPT_3D); break;
|
|
case 2: BTN( BTN_POS(5,line), BTN_SIZE(1,1), progmem_str(label), FONT_SML, OPT_3D); break;
|
|
#else
|
|
case 0: BTN( BTN_POS(8,2), BTN_SIZE(2,1), progmem_str(label), FONT_MED, OPT_3D); break;
|
|
case 1: BTN( BTN_POS(8,3), BTN_SIZE(2,1), progmem_str(label), FONT_MED, OPT_3D); break;
|
|
case 2: BTN( BTN_POS(8,4), BTN_SIZE(2,1), progmem_str(label), FONT_MED, OPT_3D); break;
|
|
#endif
|
|
}
|
|
}
|
|
|
|
void ValueAdjusters::increment_t::static_parts(stacker_t &s) const {
|
|
CLCD::CommandFifo cmd;
|
|
|
|
#if defined(LCD_PORTRAIT)
|
|
BTN_TAG(0) THEME(background) BTN( BTN_POS(1, s.line), BTN_SIZE(6,1), F("Increment:"), FONT_MED, OPT_FLAT);
|
|
#else
|
|
BTN_TAG(0) THEME(background) BTN( BTN_POS(8,1), BTN_SIZE(2,1), F("Increment"), FONT_MED, OPT_FLAT);
|
|
#endif
|
|
|
|
// Draw all the buttons in the off state.
|
|
THEME(toggle_off);
|
|
draw_increment_btn(s.line+1, 243 - decimals, decimals);
|
|
draw_increment_btn(s.line+1, 244 - decimals, decimals);
|
|
draw_increment_btn(s.line+1, 245 - decimals, decimals);
|
|
s.line += 2;
|
|
|
|
screen_data.ValueAdjusters.increment = 243 - decimals;
|
|
}
|
|
|
|
void ValueAdjusters::increment_t::dynamic_parts(stacker_t &s) const {
|
|
CLCD::CommandFifo cmd;
|
|
|
|
THEME(toggle_on);
|
|
draw_increment_btn(s.line+1, screen_data.ValueAdjusters.increment, decimals);
|
|
s.line += 2;
|
|
}
|
|
|
|
void ValueAdjusters::heading_t::static_parts(stacker_t &s) const {
|
|
CLCD::CommandFifo cmd;
|
|
|
|
#if defined(LCD_PORTRAIT)
|
|
BTN_TAG(0) THEME(background) BTN( BTN_POS(1, s.line), BTN_SIZE(6,1), (progmem_str) label, FONT_MED, OPT_FLAT);
|
|
#else
|
|
BTN_TAG(0) THEME(background) BTN( BTN_POS(3, s.line), BTN_SIZE(4,1), (progmem_str) label, FONT_MED, OPT_FLAT);
|
|
#endif
|
|
s.line++;
|
|
}
|
|
|
|
void ValueAdjusters::heading_t::dynamic_parts(stacker_t &s) const {
|
|
s.line++;
|
|
}
|
|
|
|
#if defined(LCD_PORTRAIT)
|
|
#if defined(LCD_800x480)
|
|
#define EDGE_R 20
|
|
#else
|
|
#define EDGE_R 10
|
|
#endif
|
|
#else
|
|
#if defined(LCD_800x480)
|
|
#define EDGE_R 40
|
|
#else
|
|
#define EDGE_R 20
|
|
#endif
|
|
#endif
|
|
|
|
void ValueAdjusters::adjuster_t::static_parts(stacker_t &s) const {
|
|
CLCD::CommandFifo cmd;
|
|
progmem_str str = (progmem_str) label;
|
|
BTN_TAG( 0 ) RGB(color) BTN( BTN_POS(3,s.line), BTN_SIZE(2,1), F(""), FONT_SML, OPT_FLAT);
|
|
BTN_TAG( 0 ) THEME(background) BTN( BTN_POS(1,s.line), BTN_SIZE(2,1), str, FONT_SML, OPT_FLAT);
|
|
BTN_TAG(tag ) BTN_ENABLED(1) BTN( BTN_POS(5,s.line), BTN_SIZE(1,1), F("-"), FONT_MED, OPT_3D);
|
|
BTN_TAG(tag + 1) BTN_ENABLED(1) BTN( BTN_POS(6,s.line), BTN_SIZE(1,1), F("+"), FONT_MED, OPT_3D);
|
|
s.line++;
|
|
}
|
|
|
|
void ValueAdjusters::adjuster_t::dynamic_parts(stacker_t &s, float value) const {
|
|
CLCD::CommandFifo cmd;
|
|
char b[32];
|
|
|
|
dtostrf(value, 5, decimals, b);
|
|
strcat_P(b, PSTR(" "));
|
|
strcat_P(b, (const char*) units);
|
|
|
|
BTN_TAG(0)
|
|
BTX( BTN_POS(3,s.line), BTN_SIZE(2,1), b, FONT_SML);
|
|
s.line++;
|
|
}
|
|
|
|
void ValueAdjusters::onEntry() {
|
|
screen_data.ValueAdjusters.increment = 242;
|
|
UIScreen::onEntry();
|
|
}
|
|
|
|
bool ValueAdjusters::onTouchStart(uint8_t tag) {
|
|
switch(tag) {
|
|
case 1: GOTO_PREVIOUS(); return true;
|
|
case 240 ... 245: screen_data.ValueAdjusters.increment = tag; break;
|
|
default: return current_screen.onTouchHeld(tag);
|
|
}
|
|
current_screen.onRefresh();
|
|
return true;
|
|
}
|
|
|
|
float ValueAdjusters::getIncrement() {
|
|
switch(screen_data.ValueAdjusters.increment) {
|
|
case 240: return 0.001;
|
|
case 241: return 0.01;
|
|
case 242: return 0.1;
|
|
case 243: return 1.0;
|
|
case 244: return 10.0;
|
|
case 245: return 100.0;
|
|
}
|
|
}
|
|
|
|
#define EDGE_R 0
|
|
|
|
/******************************** MOVE AXIS SCREEN ******************************/
|
|
|
|
void MoveAxisScreen::onRefresh() {
|
|
CLCD::DLCache dlcache(MOVE_AXIS_SCREEN_CACHE);
|
|
CLCD::CommandFifo cmd;
|
|
cmd.Cmd(CMD_DLSTART);
|
|
|
|
/* Tag Label: Units: Color: Precision: */
|
|
const heading_t h = { PSTR("Move Axis") };
|
|
const adjuster_t x = {2, PSTR("X:"), PSTR("mm"), Theme::x_axis, 1 };
|
|
const adjuster_t y = {4, PSTR("Y:"), PSTR("mm"), Theme::y_axis, 1 };
|
|
const adjuster_t z = {6, PSTR("Z:"), PSTR("mm"), Theme::z_axis, 1 };
|
|
#if EXTRUDERS == 1
|
|
const adjuster_t e0 = {8, PSTR("E:"), PSTR("mm"), Theme::e_axis, 1 };
|
|
#else EXTRUDERS == 2
|
|
const adjuster_t e0 = {8, PSTR("E0:"), PSTR("mm"), Theme::e_axis, 1 };
|
|
const adjuster_t e1 = {10, PSTR("E1:"), PSTR("mm"), Theme::e_axis, 1 };
|
|
#endif
|
|
const increment_t i = { 1 };
|
|
|
|
stacker_t s;
|
|
if(dlcache.hasData()) {
|
|
dlcache.append();
|
|
} else {
|
|
s.static_parts();
|
|
h.static_parts(s);
|
|
x.static_parts(s);
|
|
y.static_parts(s);
|
|
z.static_parts(s);
|
|
e0.static_parts(s);
|
|
#if EXTRUDERS == 2
|
|
e1.static_parts(s);
|
|
#endif
|
|
i.static_parts(s);
|
|
dlcache.store();
|
|
}
|
|
s.dynamic_parts();
|
|
h.dynamic_parts(s);
|
|
x.dynamic_parts(s,Marlin_LCD_API::getAxisPosition_mm(Marlin_LCD_API::X));
|
|
y.dynamic_parts(s,Marlin_LCD_API::getAxisPosition_mm(Marlin_LCD_API::Y));
|
|
z.dynamic_parts(s,Marlin_LCD_API::getAxisPosition_mm(Marlin_LCD_API::Z));
|
|
e0.dynamic_parts(s,Marlin_LCD_API::getAxisPosition_mm(Marlin_LCD_API::E0));
|
|
#if EXTRUDERS == 2
|
|
e1.dynamic_parts(s,Marlin_LCD_API::getAxisPosition_mm(Marlin_LCD_API::E1));
|
|
#endif
|
|
i.dynamic_parts(s);
|
|
|
|
cmd.Cmd(DL_DISPLAY);
|
|
cmd.Cmd(CMD_SWAP);
|
|
cmd.Cmd_Execute();
|
|
}
|
|
|
|
bool MoveAxisScreen::onTouchHeld(uint8_t tag) {
|
|
// We don't want to stack up moves, so wait until the
|
|
// machine is idle before sending another.
|
|
if(Marlin_LCD_API::isMoving()) {
|
|
return false;
|
|
}
|
|
|
|
float inc = getIncrement();
|
|
Marlin_LCD_API::axis_t axis;
|
|
const float feedrate_mm_s = inc * TOUCH_REPEATS_PER_SECOND;
|
|
|
|
switch(tag) {
|
|
case 2: axis = Marlin_LCD_API::X; inc *= -1; break;
|
|
case 3: axis = Marlin_LCD_API::X; inc *= 1; break;
|
|
case 4: axis = Marlin_LCD_API::Y; inc *= -1; break;
|
|
case 5: axis = Marlin_LCD_API::Y; inc *= 1; break;
|
|
case 6: axis = Marlin_LCD_API::Z; inc *= -1; break;
|
|
case 7: axis = Marlin_LCD_API::Z; inc *= 1; break;
|
|
case 8: axis = Marlin_LCD_API::E0; inc *= -1; break;
|
|
case 9: axis = Marlin_LCD_API::E0; inc *= 1; break;
|
|
case 10: axis = Marlin_LCD_API::E1; inc *= -1; break;
|
|
case 11: axis = Marlin_LCD_API::E1; inc *= 1; break;
|
|
default:
|
|
return false;
|
|
}
|
|
Marlin_LCD_API::setAxisPosition_mm(axis, Marlin_LCD_API::getAxisPosition_mm(axis) + inc, feedrate_mm_s);
|
|
onRefresh();
|
|
return true;
|
|
}
|
|
|
|
/******************************* TEMPERATURE SCREEN ******************************/
|
|
|
|
void TemperatureScreen::onRefresh() {
|
|
CLCD::DLCache dlcache(TEMPERATURE_SCREEN_CACHE);
|
|
CLCD::CommandFifo cmd;
|
|
cmd.Cmd(CMD_DLSTART);
|
|
|
|
/* Tag Label: Units: Color: Precision: */
|
|
const heading_t h = { PSTR("Temperature:") };
|
|
#if EXTRUDERS == 1
|
|
const adjuster_t n1 = {2, PSTR("Nozzle:"), PSTR("C"), Theme::temp, 0 };
|
|
#else
|
|
const adjuster_t n1 = {2, PSTR("Nozzle 1:"), PSTR("C"), Theme::temp, 0 };
|
|
const adjuster_t n2 = {4, PSTR("Nozzle 2:"), PSTR("C"), Theme::temp, 0 };
|
|
#endif
|
|
const adjuster_t b = {20, PSTR("Bed:"), PSTR("C"), Theme::temp, 0 };
|
|
const adjuster_t f1 = {10, PSTR("Fan Speed:"), PSTR("%"), Theme::fan_speed, 0 };
|
|
const increment_t i = { 0 };
|
|
|
|
stacker_t s;
|
|
if(dlcache.hasData()) {
|
|
dlcache.append();
|
|
} else {
|
|
s .static_parts();
|
|
h .static_parts(s);
|
|
n1.static_parts(s);
|
|
b .static_parts(s);
|
|
f1.static_parts(s);
|
|
i .static_parts(s);
|
|
dlcache.store();
|
|
}
|
|
s .dynamic_parts();
|
|
h .dynamic_parts(s);
|
|
n1.dynamic_parts(s, Marlin_LCD_API::getTargetTemp_celsius(1));
|
|
b .dynamic_parts(s, Marlin_LCD_API::getTargetTemp_celsius(0));
|
|
f1.dynamic_parts(s, Marlin_LCD_API::getFan_percent(0));
|
|
i .dynamic_parts(s);
|
|
|
|
cmd.Cmd(DL_DISPLAY);
|
|
cmd.Cmd(CMD_SWAP);
|
|
cmd.Cmd_Execute();
|
|
}
|
|
|
|
bool TemperatureScreen::onTouchHeld(uint8_t tag) {
|
|
switch(tag) {
|
|
case 20: Marlin_LCD_API::setTargetTemp_celsius(0, Marlin_LCD_API::getTargetTemp_celsius(0) - getIncrement()); break;
|
|
case 21: Marlin_LCD_API::setTargetTemp_celsius(0, Marlin_LCD_API::getTargetTemp_celsius(0) + getIncrement()); break;
|
|
case 2: Marlin_LCD_API::setTargetTemp_celsius(1, Marlin_LCD_API::getTargetTemp_celsius(1) - getIncrement()); break;
|
|
case 3: Marlin_LCD_API::setTargetTemp_celsius(1, Marlin_LCD_API::getTargetTemp_celsius(1) + getIncrement()); break;
|
|
case 4: Marlin_LCD_API::setTargetTemp_celsius(2, Marlin_LCD_API::getTargetTemp_celsius(2) - getIncrement()); break;
|
|
case 5: Marlin_LCD_API::setTargetTemp_celsius(2, Marlin_LCD_API::getTargetTemp_celsius(2) + getIncrement()); break;
|
|
case 10: Marlin_LCD_API::setFan_percent( 0, Marlin_LCD_API::getFan_percent(0) - getIncrement()); break;
|
|
case 11: Marlin_LCD_API::setFan_percent( 0, Marlin_LCD_API::getFan_percent(0) + getIncrement()); break;
|
|
default:
|
|
return false;
|
|
}
|
|
onRefresh();
|
|
return true;
|
|
}
|
|
|
|
/******************************* STEPS SCREEN ******************************/
|
|
|
|
void StepsScreen::onRefresh() {
|
|
CLCD::DLCache dlcache(STEPS_SCREEN_CACHE);
|
|
CLCD::CommandFifo cmd;
|
|
cmd.Cmd(CMD_DLSTART);
|
|
|
|
/* Tag Label: Units: Color: Precision: */
|
|
const heading_t h = { PSTR("Steps/mm") };
|
|
const adjuster_t x = {2, PSTR("X:"), PSTR(""), Theme::x_axis, 0 };
|
|
const adjuster_t y = {4, PSTR("Y:"), PSTR(""), Theme::y_axis, 0 };
|
|
const adjuster_t z = {6, PSTR("Z:"), PSTR(""), Theme::z_axis, 0 };
|
|
#if EXTRUDERS == 1
|
|
const adjuster_t e0 = {8, PSTR("E:"), PSTR(""), Theme::e_axis, 0 };
|
|
#else
|
|
const adjuster_t e0 = {8, PSTR("E0:"), PSTR(""), Theme::e_axis, 0 };
|
|
const adjuster_t e1 = {10, PSTR("E1:"), PSTR(""), Theme::e_axis, 0 };
|
|
#endif
|
|
const increment_t i = { 0 };
|
|
|
|
stacker_t s;
|
|
if(dlcache.hasData()) {
|
|
dlcache.append();
|
|
} else {
|
|
s.static_parts();
|
|
h.static_parts(s);
|
|
x.static_parts(s);
|
|
y.static_parts(s);
|
|
z.static_parts(s);
|
|
e0.static_parts(s);
|
|
#if EXTRUDERS == 2
|
|
e1.static_parts(s);
|
|
#endif
|
|
i.static_parts(s);
|
|
dlcache.store();
|
|
}
|
|
s.dynamic_parts();
|
|
h.dynamic_parts(s);
|
|
x.dynamic_parts(s,Marlin_LCD_API::getAxisSteps_per_mm(Marlin_LCD_API::X) );
|
|
y.dynamic_parts(s,Marlin_LCD_API::getAxisSteps_per_mm(Marlin_LCD_API::Y) );
|
|
z.dynamic_parts(s,Marlin_LCD_API::getAxisSteps_per_mm(Marlin_LCD_API::Z) );
|
|
e0.dynamic_parts(s,Marlin_LCD_API::getAxisSteps_per_mm(Marlin_LCD_API::E0));
|
|
#if EXTRUDERS == 2
|
|
e1.dynamic_parts(s,Marlin_LCD_API::getAxisSteps_per_mm(Marlin_LCD_API::E1));
|
|
#endif
|
|
i.dynamic_parts(s);
|
|
|
|
cmd.Cmd(DL_DISPLAY);
|
|
cmd.Cmd(CMD_SWAP);
|
|
cmd.Cmd_Execute();
|
|
}
|
|
|
|
bool StepsScreen::onTouchHeld(uint8_t tag) {
|
|
float inc = getIncrement();
|
|
Marlin_LCD_API::axis_t axis;
|
|
|
|
switch(tag) {
|
|
case 2: axis = Marlin_LCD_API::X; inc *= -1; break;
|
|
case 3: axis = Marlin_LCD_API::X; inc *= 1; break;
|
|
case 4: axis = Marlin_LCD_API::Y; inc *= -1; break;
|
|
case 5: axis = Marlin_LCD_API::Y; inc *= 1; break;
|
|
case 6: axis = Marlin_LCD_API::Z; inc *= -1; break;
|
|
case 7: axis = Marlin_LCD_API::Z; inc *= 1; break;
|
|
case 8: axis = Marlin_LCD_API::E0; inc *= -1; break;
|
|
case 9: axis = Marlin_LCD_API::E0; inc *= 1; break;
|
|
#if EXTRUDERS == 2
|
|
case 10: axis = Marlin_LCD_API::E1; inc *= -1; break;
|
|
case 11: axis = Marlin_LCD_API::E1; inc *= 1; break;
|
|
#endif
|
|
default:
|
|
return false;
|
|
}
|
|
|
|
Marlin_LCD_API::setAxisSteps_per_mm(axis, Marlin_LCD_API::getAxisSteps_per_mm(axis) + inc);
|
|
onRefresh();
|
|
return true;
|
|
}
|
|
|
|
/***************************** Z-OFFSET SCREEN ***************************/
|
|
|
|
void ZOffsetScreen::onRefresh() {
|
|
CLCD::DLCache dlcache(ZOFFSET_SCREEN_CACHE);
|
|
CLCD::CommandFifo cmd;
|
|
cmd.Cmd(CMD_DLSTART);
|
|
|
|
/* Tag Label: Units: Color: Precision: */
|
|
const heading_t h = { PSTR("Z Offset") };
|
|
const adjuster_t z = {4, PSTR("Z Offset:"), PSTR("mm"), Theme::z_axis, 3 };
|
|
const increment_t i = { 3 };
|
|
|
|
stacker_t s;
|
|
if(dlcache.hasData()) {
|
|
dlcache.append();
|
|
} else {
|
|
s.static_parts();
|
|
h.static_parts(s);
|
|
z.static_parts(s);
|
|
i.static_parts(s);
|
|
dlcache.store();
|
|
}
|
|
s.dynamic_parts();
|
|
h.dynamic_parts(s);
|
|
z.dynamic_parts(s,Marlin_LCD_API::getZOffset_mm());
|
|
i.dynamic_parts(s);
|
|
|
|
cmd.Cmd(DL_DISPLAY);
|
|
cmd.Cmd(CMD_SWAP);
|
|
cmd.Cmd_Execute();
|
|
}
|
|
|
|
bool ZOffsetScreen::onTouchHeld(uint8_t tag) {
|
|
switch(tag) {
|
|
case 4: Marlin_LCD_API::incrementZOffset_mm(-getIncrement()); break;
|
|
case 5: Marlin_LCD_API::incrementZOffset_mm( getIncrement()); break;
|
|
default:
|
|
return false;
|
|
}
|
|
onRefresh();
|
|
return true;
|
|
}
|
|
|
|
/***************************** FEEDRATE SCREEN ***************************/
|
|
|
|
void FeedrateScreen::onRefresh() {
|
|
CLCD::DLCache dlcache(FEEDRATE_SCREEN_CACHE);
|
|
CLCD::CommandFifo cmd;
|
|
cmd.Cmd(CMD_DLSTART);
|
|
|
|
/* Tag Label: Units: Color: Precision: */
|
|
const heading_t h = { PSTR("Print Speed") };
|
|
const adjuster_t f = {4, PSTR("Speed"), PSTR("%"), Theme::feedrate, 0 };
|
|
const increment_t i = { 0 };
|
|
|
|
stacker_t s;
|
|
if(dlcache.hasData()) {
|
|
dlcache.append();
|
|
} else {
|
|
s.static_parts();
|
|
h.static_parts(s);
|
|
f.static_parts(s);
|
|
i.static_parts(s);
|
|
dlcache.store();
|
|
}
|
|
s.dynamic_parts();
|
|
h.dynamic_parts(s);
|
|
f.dynamic_parts(s,Marlin_LCD_API::getFeedRate_percent());
|
|
i.dynamic_parts(s);
|
|
|
|
cmd.Cmd(DL_DISPLAY);
|
|
cmd.Cmd(CMD_SWAP);
|
|
cmd.Cmd_Execute();
|
|
}
|
|
|
|
bool FeedrateScreen::onTouchHeld(uint8_t tag) {
|
|
float inc = getIncrement();
|
|
switch(tag) {
|
|
case 4: Marlin_LCD_API::setFeedrate_percent(Marlin_LCD_API::getFeedRate_percent() - inc); break;
|
|
case 5: Marlin_LCD_API::setFeedrate_percent(Marlin_LCD_API::getFeedRate_percent() + inc); break;
|
|
default:
|
|
return false;
|
|
}
|
|
onRefresh();
|
|
return true;
|
|
}
|
|
|
|
/***************************** FILES SCREEN ***************************/
|
|
|
|
#if defined(LCD_PORTRAIT)
|
|
#define GRID_COLS 6
|
|
#define GRID_ROWS 14
|
|
#else
|
|
#define GRID_COLS 3
|
|
#define GRID_ROWS 6
|
|
#endif
|
|
|
|
const uint16_t filesPerPage = GRID_ROWS - 4;
|
|
|
|
void FilesScreen::onEntry() {
|
|
screen_data.FilesScreen.page = 0;
|
|
screen_data.FilesScreen.selected_tag = 0xFF;
|
|
UIScreen::onEntry();
|
|
}
|
|
|
|
const char *FilesScreen::getSelectedShortFilename() {
|
|
Marlin_LCD_API::Media_Iterator iterator(getIndexForTag(screen_data.FilesScreen.selected_tag));
|
|
return iterator.shortFilename();
|
|
}
|
|
|
|
uint8_t FilesScreen::getTagForIndex(uint16_t fileIndex) {
|
|
return fileIndex + 1;
|
|
}
|
|
|
|
uint16_t FilesScreen::getIndexForTag(uint8_t tag) {
|
|
return tag - 1;
|
|
}
|
|
|
|
void FilesScreen::onRefresh() {
|
|
CLCD::DLCache dlcache(FILES_SCREEN_CACHE);
|
|
CLCD::CommandFifo cmd;
|
|
cmd.Cmd(CMD_DLSTART);
|
|
|
|
cmd.Cmd_Set_Clear_Color(Theme::background);
|
|
cmd.Cmd_Clear(1,1,1);
|
|
|
|
#define MARGIN_T 0
|
|
#define MARGIN_B 0
|
|
|
|
bool dirSelected = false;
|
|
|
|
Marlin_LCD_API::Media_Iterator iterator(screen_data.FilesScreen.page * filesPerPage);
|
|
if(iterator.count()) {
|
|
do {
|
|
const uint16_t tag = getTagForIndex(iterator.value());
|
|
const bool isDir = iterator.isDirectory();
|
|
|
|
BTN_TAG(tag)
|
|
if(screen_data.FilesScreen.selected_tag == tag) {
|
|
RGB(Theme::files_selected)
|
|
dirSelected = isDir;
|
|
} else {
|
|
RGB(Theme::background)
|
|
}
|
|
BTN( BTN_POS(1,tag+2), BTN_SIZE(6,1), F(""), FONT_SML, OPT_FLAT);
|
|
BTX( BTN_POS(1,tag+2), BTN_SIZE(6,1), iterator.filename(), FONT_LRG, OPT_CENTERY);
|
|
if(isDir) {
|
|
BTX( BTN_POS(1,tag+2), BTN_SIZE(6,1), F("> "), FONT_LRG, OPT_CENTERY | OPT_RIGHTX);
|
|
}
|
|
|
|
iterator.next();
|
|
} while(iterator.hasMore());
|
|
}
|
|
|
|
#define MARGIN_T 5
|
|
#define MARGIN_B 5
|
|
|
|
const uint16_t pageCount = iterator.count() / filesPerPage + 1;
|
|
const bool prevEnabled = screen_data.FilesScreen.page > 0;
|
|
const bool nextEnabled = screen_data.FilesScreen.page < (pageCount - 1);
|
|
const bool itemSelected = screen_data.FilesScreen.selected_tag != 0xFF;
|
|
const uint8_t backTag = Marlin_LCD_API::isAtRootDir() ? 240 : 245;
|
|
|
|
char page_str[15];
|
|
sprintf_P(page_str, PSTR("Page %d of %d"), screen_data.FilesScreen.page + 1, pageCount);
|
|
|
|
#if defined(LCD_PORTRAIT)
|
|
BTN_TAG(0)
|
|
BTX( BTN_POS(1,1), BTN_SIZE(6,1), page_str, FONT_LRG, OPT_CENTER);
|
|
|
|
if(prevEnabled) {BTN_TAG(241); BTN( BTN_POS(1,1), BTN_SIZE(1,2), F("<"), MENU_BTN_STYLE);}
|
|
if(nextEnabled) {BTN_TAG(242); BTN( BTN_POS(6,1), BTN_SIZE(1,2), F(">"), MENU_BTN_STYLE);}
|
|
|
|
#define MARGIN_T 15
|
|
BTN_TAG(backTag) THEME(back_btn) BTN( BTN_POS(5,13), BTN_SIZE(2,2), F("Back"), MENU_BTN_STYLE);
|
|
|
|
BTN_ENABLED(itemSelected)
|
|
if(dirSelected) {
|
|
BTN_TAG(244); BTN( BTN_POS(1,13), BTN_SIZE(4,2), F("Open"), MENU_BTN_STYLE);
|
|
} else {
|
|
BTN_TAG(243); BTN( BTN_POS(1,13), BTN_SIZE(4,2), F("Print"), MENU_BTN_STYLE);
|
|
}
|
|
#else
|
|
BTN_TAG(backTag) THEME(back_btn) BTN( BTN_POS(1,4), BTN_SIZE(1,1), F("Back"), MENU_BTN_STYLE);
|
|
#endif
|
|
|
|
#define MARGIN_T 5
|
|
|
|
cmd.Cmd(DL_DISPLAY);
|
|
cmd.Cmd(CMD_SWAP);
|
|
cmd.Cmd_Execute();
|
|
}
|
|
|
|
bool FilesScreen::onTouchStart(uint8_t tag) {
|
|
switch(tag) {
|
|
case 240: GOTO_PREVIOUS(); return true;
|
|
case 241: screen_data.FilesScreen.page--; break;
|
|
case 242: screen_data.FilesScreen.page++; break;
|
|
case 243:
|
|
Marlin_LCD_API::printFromSDCard(getSelectedShortFilename());
|
|
lcd_setstatusPGM(PSTR("Print Starting"), 0);
|
|
GOTO_SCREEN(StatusScreen);
|
|
sound.play(start_print);
|
|
return true;
|
|
case 244:
|
|
Marlin_LCD_API::changeDir(getSelectedShortFilename());
|
|
break;
|
|
case 245:
|
|
Marlin_LCD_API::upDir();
|
|
break;
|
|
default:
|
|
if(tag < 240) {
|
|
if(screen_data.FilesScreen.selected_tag != tag) {
|
|
screen_data.FilesScreen.selected_tag = tag;
|
|
} else {
|
|
// Double clicked.
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
onRefresh();
|
|
return true;
|
|
}
|
|
|
|
/******************************** MAIN EVENT HANDLER *******************************/
|
|
|
|
void lcd_setstatusPGM(const char * const message, int8_t level = 0);
|
|
|
|
void lcd_init() {
|
|
CLCD::Init();
|
|
CLCD::DLCache::init();
|
|
Marlin_LCD_API::initMedia();
|
|
|
|
lcd_setstatusPGM(PSTR(WELCOME_MSG));
|
|
|
|
current_screen.start();
|
|
}
|
|
|
|
void lcd_update() {
|
|
enum {
|
|
UNPRESSED = 0xFF, //255
|
|
IGNORE_UNPRESS = 0xFE, //254
|
|
DEBOUNCING = 0xFD //253
|
|
};
|
|
static uint8_t pressed_state = UNPRESSED;
|
|
|
|
static tiny_interval_t touch_timer;
|
|
static tiny_interval_t refresh_timer;
|
|
|
|
sound.onIdle();
|
|
|
|
if(refresh_timer.elapsed()) {
|
|
refresh_timer.wait_for(DISPLAY_UPDATE_INTERVAL);
|
|
current_screen.onIdle();
|
|
}
|
|
|
|
Marlin_LCD_API::checkMedia();
|
|
|
|
// If the LCD is processing commands, don't check
|
|
// for tags since they may be changing and could
|
|
// cause spurious events.
|
|
if(!CLCD::CommandFifo::Cmd_Is_Idle()) {
|
|
return;
|
|
}
|
|
|
|
const uint8_t tag = CLCD::Get_Tag();
|
|
|
|
switch(pressed_state) {
|
|
case UNPRESSED:
|
|
if(tag != 0) {
|
|
#if defined(UI_FRAMEWORK_DEBUG)
|
|
#if defined (SERIAL_PROTOCOLLNPAIR)
|
|
SERIAL_PROTOCOLLNPAIR("Touch start: ", tag);
|
|
#else
|
|
Serial.print(F("Touch start: "));
|
|
Serial.println(tag);
|
|
#endif
|
|
#endif
|
|
|
|
// When the user taps on a button, activate the onTouchStart handler
|
|
const uint8_t lastScreen = current_screen.getScreen();
|
|
|
|
if(current_screen.onTouchStart(tag)) {
|
|
touch_timer.wait_for(1000 / TOUCH_REPEATS_PER_SECOND);
|
|
sound.play(Theme::press_sound);
|
|
}
|
|
|
|
if(lastScreen != current_screen.getScreen()) {
|
|
// In the case in which a touch event triggered a new screen to be
|
|
// drawn, we don't issue a touchEnd since it would be sent to the
|
|
// wrong screen.
|
|
pressed_state = IGNORE_UNPRESS;
|
|
#if defined(UI_FRAMEWORK_DEBUG)
|
|
#if defined (SERIAL_PROTOCOLLNPAIR)
|
|
SERIAL_PROTOCOLLNPAIR("Ignoring press", tag);
|
|
#else
|
|
Serial.print(F("Ignoring press"));
|
|
Serial.println(tag);
|
|
#endif
|
|
#endif
|
|
} else {
|
|
pressed_state = tag;
|
|
}
|
|
}
|
|
break;
|
|
case DEBOUNCING:
|
|
if(tag == 0) {
|
|
if(touch_timer.elapsed()) {
|
|
pressed_state = UNPRESSED;
|
|
sound.play(Theme::unpress_sound);
|
|
}
|
|
} else {
|
|
pressed_state = IGNORE_UNPRESS;
|
|
}
|
|
break;
|
|
case IGNORE_UNPRESS:
|
|
if(tag == 0) {
|
|
// Ignore subsequent presses for a while to avoid bouncing
|
|
touch_timer.wait_for(DEBOUNCE_PERIOD);
|
|
pressed_state = DEBOUNCING;
|
|
}
|
|
break;
|
|
default: // PRESSED
|
|
if(tag == pressed_state) {
|
|
// The user is holding down a button.
|
|
if(touch_timer.elapsed() && current_screen.onTouchHeld(tag)) {
|
|
sound.play(Theme::repeat_sound);
|
|
touch_timer.wait_for(1000 / TOUCH_REPEATS_PER_SECOND);
|
|
}
|
|
}
|
|
else if(tag == 0) {
|
|
#if defined(UI_FRAMEWORK_DEBUG)
|
|
#if defined (SERIAL_PROTOCOLLNPAIR)
|
|
SERIAL_PROTOCOLLNPAIR("Touch end: ", pressed_state);
|
|
#else
|
|
Serial.print(F("Touch end: "));
|
|
Serial.println(pressed_state);
|
|
#endif
|
|
#endif
|
|
|
|
current_screen.onTouchEnd(pressed_state);
|
|
// Ignore subsequent presses for a while to avoid bouncing
|
|
touch_timer.wait_for(DEBOUNCE_PERIOD);
|
|
pressed_state = DEBOUNCING;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
inline bool lcd_hasstatus() { return true; }
|
|
|
|
void lcd_setstatus(const char * const message, const bool persist /* = false */) {
|
|
StatusScreen::setStatusMessage(message);
|
|
}
|
|
|
|
void lcd_setstatusPGM(const char * const message, int8_t level /* = 0 */) {
|
|
char buff[64];
|
|
strncpy_P(buff, message, sizeof(buff));
|
|
StatusScreen::setStatusMessage(buff);
|
|
}
|
|
|
|
void lcd_status_printf_P(const uint8_t level, const char * const fmt, ...) {
|
|
char buff[64];
|
|
va_list args;
|
|
va_start(args, fmt);
|
|
vsnprintf_P(buff, sizeof(buff), fmt, args);
|
|
va_end(args);
|
|
StatusScreen::setStatusMessage(buff);
|
|
}
|
|
|
|
void lcd_setalertstatusPGM(const char * const message) {
|
|
lcd_setstatusPGM(message, 1);
|
|
GOTO_SCREEN(StatusScreen);
|
|
}
|
|
|
|
void lcd_buttons_update() {}
|
|
inline void lcd_reset_alert_level() {}
|
|
inline void lcd_refresh() {current_screen.onIdle();}
|
|
|
|
void Marlin_LCD_API::onPrinterKilled(const char* lcd_msg) {
|
|
KillScreen::show(progmem_str(lcd_msg));
|
|
}
|
|
|
|
void Marlin_LCD_API::onCardInserted() {
|
|
lcd_setstatusPGM(PSTR(MSG_SD_INSERTED), 0);
|
|
sound.play(card_inserted);
|
|
}
|
|
|
|
void Marlin_LCD_API::onCardRemoved() {
|
|
lcd_setstatusPGM(PSTR(MSG_SD_REMOVED), 0);
|
|
sound.play(card_removed);
|
|
}
|
|
|
|
void Marlin_LCD_API::onPlayTone(const uint16_t frequency, const uint16_t duration) {
|
|
sound.playTone(frequency, duration);
|
|
}
|