✨ MarlinUI for Ender 3 v2 DWIN LCD (#22594)
Co-Authored-By: Taylor Talkington <taylor.talkington@gmail.com>
This commit is contained in:
		
				
					committed by
					
						 Scott Lahteine
						Scott Lahteine
					
				
			
			
				
	
			
			
			
						parent
						
							d51e70083d
						
					
				
				
					commit
					73ef26a106
				
			| @@ -2746,6 +2746,12 @@ | ||||
| // | ||||
| //#define DWIN_CREALITY_LCD | ||||
|  | ||||
| // | ||||
| // MarlinUI for Creality's DWIN display (and others) | ||||
| // | ||||
| //#define DWIN_MARLINUI_PORTRAIT | ||||
| //#define DWIN_MARLINUI_LANDSCAPE | ||||
|  | ||||
| // | ||||
| // Touch Screen Settings | ||||
| // | ||||
|   | ||||
| @@ -1306,7 +1306,7 @@ | ||||
|  | ||||
| // LCD Print Progress options | ||||
| #if EITHER(SDSUPPORT, LCD_SET_PROGRESS_MANUALLY) | ||||
|   #if ANY(HAS_MARLINUI_U8GLIB, EXTENSIBLE_UI, HAS_MARLINUI_HD44780, IS_TFTGLCD_PANEL) | ||||
|   #if ANY(HAS_MARLINUI_U8GLIB, EXTENSIBLE_UI, HAS_MARLINUI_HD44780, IS_TFTGLCD_PANEL, IS_DWIN_MARLINUI) | ||||
|     //#define SHOW_REMAINING_TIME         // Display estimated time to completion | ||||
|     #if ENABLED(SHOW_REMAINING_TIME) | ||||
|       //#define USE_M73_REMAINING_TIME    // Use remaining time from M73 command instead of estimation | ||||
| @@ -1579,16 +1579,10 @@ | ||||
|  * printing performance versus fast display updates. | ||||
|  */ | ||||
| #if HAS_MARLINUI_U8GLIB | ||||
|   // Show SD percentage next to the progress bar | ||||
|   //#define SHOW_SD_PERCENT | ||||
|  | ||||
|   // Save many cycles by drawing a hollow frame or no frame on the Info Screen | ||||
|   //#define XYZ_NO_FRAME | ||||
|   #define XYZ_HOLLOW_FRAME | ||||
|  | ||||
|   // Enable to save many cycles by drawing a hollow frame on Menu Screens | ||||
|   #define MENU_HOLLOW_FRAME | ||||
|  | ||||
|   // A bigger font is available for edit items. Costs 3120 bytes of PROGMEM. | ||||
|   // Western only. Not available for Cyrillic, Kana, Turkish, Greek, or Chinese. | ||||
|   //#define USE_BIG_EDIT_FONT | ||||
| @@ -1597,9 +1591,6 @@ | ||||
|   // Western only. Not available for Cyrillic, Kana, Turkish, Greek, or Chinese. | ||||
|   //#define USE_SMALL_INFOFONT | ||||
|  | ||||
|   // Swap the CW/CCW indicators in the graphics overlay | ||||
|   //#define OVERLAY_GFX_REVERSE | ||||
|  | ||||
|   /** | ||||
|    * ST7920-based LCDs can emulate a 16 x 4 character display using | ||||
|    * the ST7920 character-generator for very fast screen updates. | ||||
| @@ -1651,6 +1642,17 @@ | ||||
|  | ||||
| #endif // HAS_MARLINUI_U8GLIB | ||||
|  | ||||
| #if HAS_MARLINUI_U8GLIB || IS_DWIN_MARLINUI | ||||
|   // Show SD percentage next to the progress bar | ||||
|   //#define SHOW_SD_PERCENT | ||||
|  | ||||
|   // Enable to save many cycles by drawing a hollow frame on Menu Screens | ||||
|   #define MENU_HOLLOW_FRAME | ||||
|  | ||||
|   // Swap the CW/CCW indicators in the graphics overlay | ||||
|   //#define OVERLAY_GFX_REVERSE | ||||
| #endif | ||||
|  | ||||
| // | ||||
| // Additional options for DGUS / DWIN displays | ||||
| // | ||||
| @@ -1716,7 +1718,7 @@ | ||||
| // | ||||
| // Specify additional languages for the UI. Default specified by LCD_LANGUAGE. | ||||
| // | ||||
| #if ANY(DOGLCD, TFT_COLOR_UI, TOUCH_UI_FTDI_EVE) | ||||
| #if ANY(DOGLCD, TFT_COLOR_UI, TOUCH_UI_FTDI_EVE, IS_DWIN_MARLINUI) | ||||
|   //#define LCD_LANGUAGE_2 fr | ||||
|   //#define LCD_LANGUAGE_3 de | ||||
|   //#define LCD_LANGUAGE_4 es | ||||
|   | ||||
| @@ -238,8 +238,8 @@ bool load_filament(const_float_t slow_load_length/*=0*/, const_float_t fast_load | ||||
|  | ||||
|     if (show_lcd) ui.pause_show_message(PAUSE_MESSAGE_PURGE); | ||||
|  | ||||
|     TERN_(EXTENSIBLE_UI, ExtUI::onUserConfirmRequired_P(PSTR("Filament Purging..."))); | ||||
|     TERN_(HOST_PROMPT_SUPPORT, host_prompt_do(PROMPT_USER_CONTINUE, PSTR("Filament Purging..."), CONTINUE_STR)); | ||||
|     TERN_(EXTENSIBLE_UI, ExtUI::onUserConfirmRequired_P(GET_TEXT(MSG_FILAMENT_CHANGE_PURGE))); | ||||
|     TERN_(HOST_PROMPT_SUPPORT, host_prompt_do(PROMPT_USER_CONTINUE, GET_TEXT(MSG_FILAMENT_CHANGE_PURGE), CONTINUE_STR)); | ||||
|     wait_for_user = true; // A click or M108 breaks the purge_length loop | ||||
|     for (float purge_count = purge_length; purge_count > 0 && wait_for_user; --purge_count) | ||||
|       unscaled_e_move(1, ADVANCED_PAUSE_PURGE_FEEDRATE); | ||||
|   | ||||
| @@ -488,7 +488,10 @@ | ||||
|     #define HAS_MARLINUI_U8GLIB 1 | ||||
|   #elif IS_TFTGLCD_PANEL | ||||
|     // Neither DOGM nor HD44780. Fully customized interface. | ||||
|   #elif DISABLED(HAS_GRAPHICAL_TFT) | ||||
|   #elif IS_DWIN_MARLINUI | ||||
|     // Since HAS_MARLINUI_U8GLIB refers to U8G displays | ||||
|     // the DWIN display can define its own flags | ||||
|   #elif !HAS_GRAPHICAL_TFT | ||||
|     #define HAS_MARLINUI_HD44780 1 | ||||
|   #endif | ||||
| #endif | ||||
| @@ -1087,7 +1090,7 @@ | ||||
|   #define HAS_ETHERNET 1 | ||||
| #endif | ||||
|  | ||||
| #if ENABLED(DWIN_CREALITY_LCD) | ||||
| #if EITHER(DWIN_CREALITY_LCD, IS_DWIN_MARLINUI) | ||||
|   #define SERIAL_CATCHALL 0 | ||||
|   #ifndef LCD_SERIAL_PORT | ||||
|     #if MB(BTT_SKR_MINI_E3_V1_0, BTT_SKR_MINI_E3_V1_2, BTT_SKR_MINI_E3_V2_0, BTT_SKR_E3_TURBO) | ||||
|   | ||||
| @@ -461,7 +461,7 @@ | ||||
|  | ||||
| #endif | ||||
|  | ||||
| #if ANY(HAS_GRAPHICAL_TFT, LCD_USE_DMA_FSMC, HAS_FSMC_GRAPHICAL_TFT, HAS_SPI_GRAPHICAL_TFT) || !PIN_EXISTS(SD_DETECT) | ||||
| #if ANY(HAS_GRAPHICAL_TFT, LCD_USE_DMA_FSMC, HAS_FSMC_GRAPHICAL_TFT, HAS_SPI_GRAPHICAL_TFT, IS_DWIN_MARLINUI) || !PIN_EXISTS(SD_DETECT) | ||||
|   #define NO_LCD_REINIT 1  // Suppress LCD re-initialization | ||||
| #endif | ||||
|  | ||||
| @@ -3258,6 +3258,8 @@ | ||||
|   #ifndef LCD_WIDTH | ||||
|     #if HAS_MARLINUI_U8GLIB | ||||
|       #define LCD_WIDTH 21 | ||||
|     #elif IS_DWIN_MARLINUI | ||||
|       // Defined by header | ||||
|     #else | ||||
|       #define LCD_WIDTH TERN(IS_ULTIPANEL, 20, 16) | ||||
|     #endif | ||||
| @@ -3265,6 +3267,8 @@ | ||||
|   #ifndef LCD_HEIGHT | ||||
|     #if HAS_MARLINUI_U8GLIB | ||||
|       #define LCD_HEIGHT 5 | ||||
|     #elif IS_DWIN_MARLINUI | ||||
|       // Defined by header | ||||
|     #else | ||||
|       #define LCD_HEIGHT TERN(IS_ULTIPANEL, 4, 2) | ||||
|     #endif | ||||
|   | ||||
| @@ -798,8 +798,8 @@ static_assert(Y_MAX_LENGTH >= Y_BED_SIZE, "Movement bounds (Y_MIN_POS, Y_MAX_POS | ||||
|     #error "PROGRESS_MSG_EXPIRE must be greater than or equal to 0." | ||||
|   #endif | ||||
| #elif ENABLED(LCD_SET_PROGRESS_MANUALLY) | ||||
|   #if NONE(HAS_MARLINUI_U8GLIB, HAS_GRAPHICAL_TFT, HAS_MARLINUI_HD44780, EXTENSIBLE_UI) | ||||
|     #error "LCD_SET_PROGRESS_MANUALLY requires LCD_PROGRESS_BAR, Character LCD, Graphical LCD, TFT, or EXTENSIBLE_UI." | ||||
|   #if NONE(HAS_MARLINUI_U8GLIB, HAS_GRAPHICAL_TFT, HAS_MARLINUI_HD44780, EXTENSIBLE_UI, IS_DWIN_MARLINUI) | ||||
|     #error "LCD_SET_PROGRESS_MANUALLY requires LCD_PROGRESS_BAR, Character LCD, Graphical LCD, TFT, EXTENSIBLE_UI, OR DWIN MarlinUI." | ||||
|   #endif | ||||
| #endif | ||||
|  | ||||
| @@ -1721,7 +1721,7 @@ static_assert(Y_MAX_LENGTH >= Y_BED_SIZE, "Movement bounds (Y_MIN_POS, Y_MAX_POS | ||||
|   #endif | ||||
| #endif | ||||
|  | ||||
| #if ENABLED(MESH_EDIT_GFX_OVERLAY) && !BOTH(AUTO_BED_LEVELING_UBL, HAS_MARLINUI_U8GLIB) | ||||
| #if ENABLED(MESH_EDIT_GFX_OVERLAY) && !(ENABLED(AUTO_BED_LEVELING_UBL) && EITHER(HAS_MARLINUI_U8GLIB, IS_DWIN_MARLINUI)) | ||||
|   #error "MESH_EDIT_GFX_OVERLAY requires AUTO_BED_LEVELING_UBL and a Graphical LCD." | ||||
| #endif | ||||
|  | ||||
| @@ -2640,6 +2640,7 @@ static_assert(Y_MAX_LENGTH >= Y_BED_SIZE, "Movement bounds (Y_MIN_POS, Y_MAX_POS | ||||
|   + COUNT_ENABLED(ANYCUBIC_LCD_I3MEGA, ANYCUBIC_LCD_CHIRON, ANYCUBIC_TFT35) \ | ||||
|   + COUNT_ENABLED(DGUS_LCD_UI_ORIGIN, DGUS_LCD_UI_FYSETC, DGUS_LCD_UI_HIPRECY, DGUS_LCD_UI_MKS) \ | ||||
|   + COUNT_ENABLED(ENDER2_STOCKDISPLAY, CR10_STOCKDISPLAY, DWIN_CREALITY_LCD) \ | ||||
|   + COUNT_ENABLED(DWIN_MARLINUI_PORTRAIT, DWIN_MARLINUI_LANDSCAPE) \ | ||||
|   + COUNT_ENABLED(FYSETC_MINI_12864_X_X, FYSETC_MINI_12864_1_2, FYSETC_MINI_12864_2_0, FYSETC_MINI_12864_2_1, FYSETC_GENERIC_12864_1_1) \ | ||||
|   + COUNT_ENABLED(LCD_SAINSMART_I2C_1602, LCD_SAINSMART_I2C_2004) \ | ||||
|   + COUNT_ENABLED(MKS_12864OLED, MKS_12864OLED_SSD1306) \ | ||||
|   | ||||
							
								
								
									
										470
									
								
								Marlin/src/lcd/e3v2/marlinui/dwin_lcd.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										470
									
								
								Marlin/src/lcd/e3v2/marlinui/dwin_lcd.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,470 @@ | ||||
| /** | ||||
|  * Marlin 3D Printer Firmware | ||||
|  * Copyright (c) 2021 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] | ||||
|  * | ||||
|  * Based on Sprinter and grbl. | ||||
|  * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm | ||||
|  * | ||||
|  * 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. | ||||
|  * | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with this program.  If not, see <https://www.gnu.org/licenses/>. | ||||
|  * | ||||
|  */ | ||||
|  | ||||
| /******************************************************************************** | ||||
|  * @file     lcd/e3v2/marlinui/dwin_lcd.cpp | ||||
|  * @brief    DWIN screen control functions | ||||
|  ********************************************************************************/ | ||||
|  | ||||
| #include "../../../inc/MarlinConfigPre.h" | ||||
|  | ||||
| #if IS_DWIN_MARLINUI | ||||
|  | ||||
| #include "../../../inc/MarlinConfig.h" | ||||
|  | ||||
| #include "dwin_lcd.h" | ||||
| #include <string.h> // for memset | ||||
|  | ||||
| //#define DEBUG_OUT 1 | ||||
| #include "../../../core/debug_out.h" | ||||
|  | ||||
| // Make sure DWIN_SendBuf is large enough to hold the largest string plus draw command and tail. | ||||
| // Assume the narrowest (6 pixel) font and 2-byte gb2312-encoded characters. | ||||
| uint8_t DWIN_SendBuf[11 + DWIN_WIDTH / 6 * 2] = { 0xAA }; | ||||
| uint8_t DWIN_BufTail[4] = { 0xCC, 0x33, 0xC3, 0x3C }; | ||||
| uint8_t databuf[26] = { 0 }; | ||||
| uint8_t receivedType; | ||||
|  | ||||
| int recnum = 0; | ||||
|  | ||||
| inline void DWIN_Byte(size_t &i, const uint16_t bval) { | ||||
|   DWIN_SendBuf[++i] = bval; | ||||
| } | ||||
|  | ||||
| inline void DWIN_Word(size_t &i, const uint16_t wval) { | ||||
|   DWIN_SendBuf[++i] = wval >> 8; | ||||
|   DWIN_SendBuf[++i] = wval & 0xFF; | ||||
| } | ||||
|  | ||||
| inline void DWIN_Long(size_t &i, const uint32_t lval) { | ||||
|   DWIN_SendBuf[++i] = (lval >> 24) & 0xFF; | ||||
|   DWIN_SendBuf[++i] = (lval >> 16) & 0xFF; | ||||
|   DWIN_SendBuf[++i] = (lval >>  8) & 0xFF; | ||||
|   DWIN_SendBuf[++i] = lval & 0xFF; | ||||
| } | ||||
|  | ||||
| inline void DWIN_String(size_t &i, char * const string) { | ||||
|   const size_t len = _MIN(sizeof(DWIN_SendBuf) - i, strlen(string)); | ||||
|   memcpy(&DWIN_SendBuf[i+1], string, len); | ||||
|   i += len; | ||||
| } | ||||
|  | ||||
| inline void DWIN_String(size_t &i, const __FlashStringHelper * string) { | ||||
|   if (!string) return; | ||||
|   const size_t len = strlen_P((PGM_P)string); // cast it to PGM_P, which is basically const char *, and measure it using the _P version of strlen. | ||||
|   if (len == 0) return; | ||||
|   memcpy(&DWIN_SendBuf[i+1], string, len); | ||||
|   i += len; | ||||
| } | ||||
|  | ||||
| // Send the data in the buffer and the packet end | ||||
| inline void DWIN_Send(size_t &i) { | ||||
|   ++i; | ||||
|   LOOP_L_N(n, i) { LCD_SERIAL.write(DWIN_SendBuf[n]); delayMicroseconds(1); } | ||||
|   LOOP_L_N(n, 4) { LCD_SERIAL.write(DWIN_BufTail[n]); delayMicroseconds(1); } | ||||
| } | ||||
|  | ||||
| /*-------------------------------------- System variable function --------------------------------------*/ | ||||
|  | ||||
| // Handshake (1: Success, 0: Fail) | ||||
| bool DWIN_Handshake(void) { | ||||
|   #ifndef LCD_BAUDRATE | ||||
|     #define LCD_BAUDRATE 115200 | ||||
|   #endif | ||||
|   LCD_SERIAL.begin(LCD_BAUDRATE); | ||||
|   const millis_t serial_connect_timeout = millis() + 1000UL; | ||||
|   while (!LCD_SERIAL.connected() && PENDING(millis(), serial_connect_timeout)) { /*nada*/ } | ||||
|  | ||||
|   size_t i = 0; | ||||
|   DWIN_Byte(i, 0x00); | ||||
|   DWIN_Send(i); | ||||
|  | ||||
|   while (LCD_SERIAL.available() > 0 && recnum < (signed)sizeof(databuf)) { | ||||
|     databuf[recnum] = LCD_SERIAL.read(); | ||||
|     // ignore the invalid data | ||||
|     if (databuf[0] != FHONE) { // prevent the program from running. | ||||
|       if (recnum > 0) { | ||||
|         recnum = 0; | ||||
|         ZERO(databuf); | ||||
|       } | ||||
|       continue; | ||||
|     } | ||||
|     delay(10); | ||||
|     recnum++; | ||||
|   } | ||||
|  | ||||
|   return ( recnum >= 3 | ||||
|         && databuf[0] == FHONE | ||||
|         && databuf[1] == '\0' | ||||
|         && databuf[2] == 'O' | ||||
|         && databuf[3] == 'K' ); | ||||
| } | ||||
|  | ||||
| void DWIN_Startup(void) { | ||||
|   DEBUG_ECHOPGM("\r\nDWIN handshake "); | ||||
|   delay(750);   // Delay here or init later in the boot process | ||||
|   const bool success = DWIN_Handshake(); | ||||
|   if (success) DEBUG_ECHOLNPGM("ok."); else DEBUG_ECHOLNPGM("error."); | ||||
|   DWIN_Frame_SetDir(TERN(DWIN_MARLINUI_LANDSCAPE, 0, 1)); | ||||
|   DWIN_Frame_Clear(Color_Bg_Black); // MarlinUI handles the bootscreen so just clear here | ||||
|   DWIN_UpdateLCD(); | ||||
| } | ||||
|  | ||||
| // Set the backlight luminance | ||||
| //  luminance: (0x00-0xFF) | ||||
| void DWIN_Backlight_SetLuminance(const uint8_t luminance) { | ||||
|   size_t i = 0; | ||||
|   DWIN_Byte(i, 0x30); | ||||
|   DWIN_Byte(i, _MAX(luminance, 0x1F)); | ||||
|   DWIN_Send(i); | ||||
| } | ||||
|  | ||||
| // Set screen display direction | ||||
| //  dir: 0=0°, 1=90°, 2=180°, 3=270° | ||||
| void DWIN_Frame_SetDir(uint8_t dir) { | ||||
|   size_t i = 0; | ||||
|   DWIN_Byte(i, 0x34); | ||||
|   DWIN_Byte(i, 0x5A); | ||||
|   DWIN_Byte(i, 0xA5); | ||||
|   DWIN_Byte(i, dir); | ||||
|   DWIN_Send(i); | ||||
| } | ||||
|  | ||||
| // Update display | ||||
| void DWIN_UpdateLCD(void) { | ||||
|   size_t i = 0; | ||||
|   DWIN_Byte(i, 0x3D); | ||||
|   DWIN_Send(i); | ||||
| } | ||||
|  | ||||
| /*---------------------------------------- Drawing functions ----------------------------------------*/ | ||||
|  | ||||
| // Clear screen | ||||
| //  color: Clear screen color | ||||
| void DWIN_Frame_Clear(const uint16_t color) { | ||||
|   size_t i = 0; | ||||
|   DWIN_Byte(i, 0x01); | ||||
|   DWIN_Word(i, color); | ||||
|   DWIN_Send(i); | ||||
| } | ||||
|  | ||||
| // Draw a point | ||||
| //  width: point width   0x01-0x0F | ||||
| //  height: point height 0x01-0x0F | ||||
| //  x,y: upper left point | ||||
| void DWIN_Draw_Point(uint16_t color, uint8_t width, uint8_t height, uint16_t x, uint16_t y) { | ||||
|   size_t i = 0; | ||||
|   DWIN_Byte(i, 0x02); | ||||
|   DWIN_Word(i, color); | ||||
|   DWIN_Byte(i, width); | ||||
|   DWIN_Byte(i, height); | ||||
|   DWIN_Word(i, x); | ||||
|   DWIN_Word(i, y); | ||||
|   DWIN_Send(i); | ||||
| } | ||||
|  | ||||
| // Draw a line | ||||
| //  color: Line segment color | ||||
| //  xStart/yStart: Start point | ||||
| //  xEnd/yEnd: End point | ||||
| void DWIN_Draw_Line(uint16_t color, uint16_t xStart, uint16_t yStart, uint16_t xEnd, uint16_t yEnd) { | ||||
|   size_t i = 0; | ||||
|   DWIN_Byte(i, 0x03); | ||||
|   DWIN_Word(i, color); | ||||
|   DWIN_Word(i, xStart); | ||||
|   DWIN_Word(i, yStart); | ||||
|   DWIN_Word(i, xEnd); | ||||
|   DWIN_Word(i, yEnd); | ||||
|   DWIN_Send(i); | ||||
| } | ||||
|  | ||||
| // Draw a rectangle | ||||
| //  mode: 0=frame, 1=fill, 2=XOR fill | ||||
| //  color: Rectangle color | ||||
| //  xStart/yStart: upper left point | ||||
| //  xEnd/yEnd: lower right point | ||||
| void DWIN_Draw_Rectangle(uint8_t mode, uint16_t color, | ||||
|                          uint16_t xStart, uint16_t yStart, uint16_t xEnd, uint16_t yEnd) { | ||||
|   size_t i = 0; | ||||
|   DWIN_Byte(i, 0x05); | ||||
|   DWIN_Byte(i, mode); | ||||
|   DWIN_Word(i, color); | ||||
|   DWIN_Word(i, xStart); | ||||
|   DWIN_Word(i, yStart); | ||||
|   DWIN_Word(i, xEnd); | ||||
|   DWIN_Word(i, yEnd); | ||||
|   DWIN_Send(i); | ||||
| } | ||||
|  | ||||
| // Move a screen area | ||||
| //  mode: 0, circle shift; 1, translation | ||||
| //  dir: 0=left, 1=right, 2=up, 3=down | ||||
| //  dis: Distance | ||||
| //  color: Fill color | ||||
| //  xStart/yStart: upper left point | ||||
| //  xEnd/yEnd: bottom right point | ||||
| void DWIN_Frame_AreaMove(uint8_t mode, uint8_t dir, uint16_t dis, | ||||
|                          uint16_t color, uint16_t xStart, uint16_t yStart, uint16_t xEnd, uint16_t yEnd) { | ||||
|   size_t i = 0; | ||||
|   DWIN_Byte(i, 0x09); | ||||
|   DWIN_Byte(i, (mode << 7) | dir); | ||||
|   DWIN_Word(i, dis); | ||||
|   DWIN_Word(i, color); | ||||
|   DWIN_Word(i, xStart); | ||||
|   DWIN_Word(i, yStart); | ||||
|   DWIN_Word(i, xEnd); | ||||
|   DWIN_Word(i, yEnd); | ||||
|   DWIN_Send(i); | ||||
| } | ||||
|  | ||||
| /*---------------------------------------- Text related functions ----------------------------------------*/ | ||||
|  | ||||
| // Draw a string | ||||
| //  bShow: true=display background color; false=don't display background color | ||||
| //  size: Font size | ||||
| //  color: Character color | ||||
| //  bColor: Background color | ||||
| //  x/y: Upper-left coordinate of the string | ||||
| //  *string: The string | ||||
| void DWIN_Draw_String(bool bShow, uint8_t size, uint16_t color, uint16_t bColor, uint16_t x, uint16_t y, char *string) { | ||||
|   uint8_t widthAdjust = 0; | ||||
|   size_t i = 0; | ||||
|   DWIN_Byte(i, 0x11); | ||||
|   // Bit 7: widthAdjust | ||||
|   // Bit 6: bShow | ||||
|   // Bit 5-4: Unused (0) | ||||
|   // Bit 3-0: size | ||||
|   DWIN_Byte(i, (widthAdjust * 0x80) | (bShow * 0x40) | size); | ||||
|   DWIN_Word(i, color); | ||||
|   DWIN_Word(i, bColor); | ||||
|   DWIN_Word(i, x); | ||||
|   DWIN_Word(i, y); | ||||
|   DWIN_String(i, string); | ||||
|   DWIN_Send(i); | ||||
| } | ||||
|  | ||||
| // Draw a positive integer | ||||
| //  bShow: true=display background color; false=don't display background color | ||||
| //  zeroFill: true=zero fill; false=no zero fill | ||||
| //  zeroMode: 1=leading 0 displayed as 0; 0=leading 0 displayed as a space | ||||
| //  size: Font size | ||||
| //  color: Character color | ||||
| //  bColor: Background color | ||||
| //  iNum: Number of digits | ||||
| //  x/y: Upper-left coordinate | ||||
| //  value: Integer value | ||||
| void DWIN_Draw_IntValue(uint8_t bShow, bool zeroFill, uint8_t zeroMode, uint8_t size, uint16_t color, | ||||
|                           uint16_t bColor, uint8_t iNum, uint16_t x, uint16_t y, uint16_t value) { | ||||
|   size_t i = 0; | ||||
|   DWIN_Byte(i, 0x14); | ||||
|   // Bit 7: bshow | ||||
|   // Bit 6: 1 = signed; 0 = unsigned number; | ||||
|   // Bit 5: zeroFill | ||||
|   // Bit 4: zeroMode | ||||
|   // Bit 3-0: size | ||||
|   DWIN_Byte(i, (bShow * 0x80) | (zeroFill * 0x20) | (zeroMode * 0x10) | size); | ||||
|   DWIN_Word(i, color); | ||||
|   DWIN_Word(i, bColor); | ||||
|   DWIN_Byte(i, iNum); | ||||
|   DWIN_Byte(i, 0); // fNum | ||||
|   DWIN_Word(i, x); | ||||
|   DWIN_Word(i, y); | ||||
|   #if 0 | ||||
|     for (char count = 0; count < 8; count++) { | ||||
|       DWIN_Byte(i, value); | ||||
|       value >>= 8; | ||||
|       if (!(value & 0xFF)) break; | ||||
|     } | ||||
|   #else | ||||
|     // Write a big-endian 64 bit integer | ||||
|     const size_t p = i + 1; | ||||
|     for (char count = 8; count--;) { // 7..0 | ||||
|       ++i; | ||||
|       DWIN_SendBuf[p + count] = value; | ||||
|       value >>= 8; | ||||
|     } | ||||
|   #endif | ||||
|  | ||||
|   DWIN_Send(i); | ||||
| } | ||||
|  | ||||
| // Draw a floating point number | ||||
| //  bShow: true=display background color; false=don't display background color | ||||
| //  zeroFill: true=zero fill; false=no zero fill | ||||
| //  zeroMode: 1=leading 0 displayed as 0; 0=leading 0 displayed as a space | ||||
| //  size: Font size | ||||
| //  color: Character color | ||||
| //  bColor: Background color | ||||
| //  iNum: Number of whole digits | ||||
| //  fNum: Number of decimal digits | ||||
| //  x/y: Upper-left point | ||||
| //  value: Float value | ||||
| void DWIN_Draw_FloatValue(uint8_t bShow, bool zeroFill, uint8_t zeroMode, uint8_t size, uint16_t color, | ||||
|                             uint16_t bColor, uint8_t iNum, uint8_t fNum, uint16_t x, uint16_t y, long value) { | ||||
|   //uint8_t *fvalue = (uint8_t*)&value; | ||||
|   size_t i = 0; | ||||
|   DWIN_Byte(i, 0x14); | ||||
|   DWIN_Byte(i, (bShow * 0x80) | (zeroFill * 0x20) | (zeroMode * 0x10) | size); | ||||
|   DWIN_Word(i, color); | ||||
|   DWIN_Word(i, bColor); | ||||
|   DWIN_Byte(i, iNum); | ||||
|   DWIN_Byte(i, fNum); | ||||
|   DWIN_Word(i, x); | ||||
|   DWIN_Word(i, y); | ||||
|   DWIN_Long(i, value); | ||||
|   /* | ||||
|   DWIN_Byte(i, fvalue[3]); | ||||
|   DWIN_Byte(i, fvalue[2]); | ||||
|   DWIN_Byte(i, fvalue[1]); | ||||
|   DWIN_Byte(i, fvalue[0]); | ||||
|   */ | ||||
|   DWIN_Send(i); | ||||
| } | ||||
|  | ||||
| /*---------------------------------------- Picture related functions ----------------------------------------*/ | ||||
|  | ||||
| // Draw JPG and cached in #0 virtual display area | ||||
| // id: Picture ID | ||||
| void DWIN_JPG_ShowAndCache(const uint8_t id) { | ||||
|   size_t i = 0; | ||||
|   DWIN_Word(i, 0x2200); | ||||
|   DWIN_Byte(i, id); | ||||
|   DWIN_Send(i);     // AA 23 00 00 00 00 08 00 01 02 03 CC 33 C3 3C | ||||
| } | ||||
|  | ||||
| // Draw an Icon | ||||
| //  libID: Icon library ID | ||||
| //  picID: Icon ID | ||||
| //  x/y: Upper-left point | ||||
| void DWIN_ICON_Show(uint8_t libID, uint8_t picID, uint16_t x, uint16_t y) { | ||||
|   NOMORE(x, DWIN_WIDTH - 1); | ||||
|   NOMORE(y, DWIN_HEIGHT - 1); // -- ozy -- srl | ||||
|   size_t i = 0; | ||||
|   DWIN_Byte(i, 0x23); | ||||
|   DWIN_Word(i, x); | ||||
|   DWIN_Word(i, y); | ||||
|   DWIN_Byte(i, 0x80 | libID); | ||||
|   //DWIN_Byte(i, libID); | ||||
|   DWIN_Byte(i, picID); | ||||
|   DWIN_Send(i); | ||||
| } | ||||
|  | ||||
| // Unzip the JPG picture to a virtual display area | ||||
| //  n: Cache index | ||||
| //  id: Picture ID | ||||
| void DWIN_JPG_CacheToN(uint8_t n, uint8_t id) { | ||||
|   size_t i = 0; | ||||
|   DWIN_Byte(i, 0x25); | ||||
|   DWIN_Byte(i, n); | ||||
|   DWIN_Byte(i, id); | ||||
|   DWIN_Send(i); | ||||
| } | ||||
|  | ||||
| // Copy area from virtual display area to current screen | ||||
| //  cacheID: virtual area number | ||||
| //  xStart/yStart: Upper-left of virtual area | ||||
| //  xEnd/yEnd: Lower-right of virtual area | ||||
| //  x/y: Screen paste point | ||||
| void DWIN_Frame_AreaCopy(uint8_t cacheID, uint16_t xStart, uint16_t yStart, | ||||
|                          uint16_t xEnd, uint16_t yEnd, uint16_t x, uint16_t y) { | ||||
|   size_t i = 0; | ||||
|   DWIN_Byte(i, 0x27); | ||||
|   DWIN_Byte(i, 0x80 | cacheID); | ||||
|   DWIN_Word(i, xStart); | ||||
|   DWIN_Word(i, yStart); | ||||
|   DWIN_Word(i, xEnd); | ||||
|   DWIN_Word(i, yEnd); | ||||
|   DWIN_Word(i, x); | ||||
|   DWIN_Word(i, y); | ||||
|   DWIN_Send(i); | ||||
| } | ||||
|  | ||||
| // Animate a series of icons | ||||
| //  animID: Animation ID; 0x00-0x0F | ||||
| //  animate: true on; false off; | ||||
| //  libID: Icon library ID | ||||
| //  picIDs: Icon starting ID | ||||
| //  picIDe: Icon ending ID | ||||
| //  x/y: Upper-left point | ||||
| //  interval: Display time interval, unit 10mS | ||||
| void DWIN_ICON_Animation(uint8_t animID, bool animate, uint8_t libID, uint8_t picIDs, uint8_t picIDe, uint16_t x, uint16_t y, uint16_t interval) { | ||||
|   NOMORE(x, DWIN_WIDTH - 1); | ||||
|   NOMORE(y, DWIN_HEIGHT - 1); // -- ozy -- srl | ||||
|   size_t i = 0; | ||||
|   DWIN_Byte(i, 0x28); | ||||
|   DWIN_Word(i, x); | ||||
|   DWIN_Word(i, y); | ||||
|   // Bit 7: animation on or off | ||||
|   // Bit 6: start from begin or end | ||||
|   // Bit 5-4: unused (0) | ||||
|   // Bit 3-0: animID | ||||
|   DWIN_Byte(i, (animate * 0x80) | 0x40 | animID); | ||||
|   DWIN_Byte(i, libID); | ||||
|   DWIN_Byte(i, picIDs); | ||||
|   DWIN_Byte(i, picIDe); | ||||
|   DWIN_Byte(i, interval); | ||||
|   DWIN_Send(i); | ||||
| } | ||||
|  | ||||
| // Animation Control | ||||
| //  state: 16 bits, each bit is the state of an animation id | ||||
| void DWIN_ICON_AnimationControl(uint16_t state) { | ||||
|   size_t i = 0; | ||||
|   DWIN_Byte(i, 0x29); | ||||
|   DWIN_Word(i, state); | ||||
|   DWIN_Send(i); | ||||
| } | ||||
|  | ||||
| /*---------------------------------------- Memory functions ----------------------------------------*/ | ||||
| // The LCD has an additional 32KB SRAM and 16KB Flash | ||||
|  | ||||
| // Data can be written to the sram and save to one of the jpeg page files | ||||
|  | ||||
| // Write Data Memory | ||||
| //  command 0x31 | ||||
| //  Type: Write memory selection; 0x5A=SRAM; 0xA5=Flash | ||||
| //  Address: Write data memory address; 0x000-0x7FFF for SRAM; 0x000-0x3FFF for Flash | ||||
| //  Data: data | ||||
| // | ||||
| //  Flash writing returns 0xA5 0x4F 0x4B | ||||
|  | ||||
| // Read Data Memory | ||||
| //  command 0x32 | ||||
| //  Type: Read memory selection; 0x5A=SRAM; 0xA5=Flash | ||||
| //  Address: Read data memory address; 0x000-0x7FFF for SRAM; 0x000-0x3FFF for Flash | ||||
| //  Length: leangth of data to read; 0x01-0xF0 | ||||
| // | ||||
| //  Response: | ||||
| //    Type, Address, Length, Data | ||||
|  | ||||
| // Write Picture Memory | ||||
| //  Write the contents of the 32KB SRAM data memory into the designated image memory space | ||||
| //  Issued: 0x5A, 0xA5, PIC_ID | ||||
| //  Response: 0xA5 0x4F 0x4B | ||||
| // | ||||
| //  command 0x33 | ||||
| //  0x5A, 0xA5 | ||||
| //  PicId: Picture Memory location, 0x00-0x0F | ||||
| // | ||||
| //  Flash writing returns 0xA5 0x4F 0x4B | ||||
|  | ||||
| #endif // IS_DWIN_MARLINUI | ||||
							
								
								
									
										302
									
								
								Marlin/src/lcd/e3v2/marlinui/dwin_lcd.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										302
									
								
								Marlin/src/lcd/e3v2/marlinui/dwin_lcd.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,302 @@ | ||||
| /** | ||||
|  * Marlin 3D Printer Firmware | ||||
|  * Copyright (c) 2021 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] | ||||
|  * | ||||
|  * Based on Sprinter and grbl. | ||||
|  * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm | ||||
|  * | ||||
|  * 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. | ||||
|  * | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with this program.  If not, see <https://www.gnu.org/licenses/>. | ||||
|  * | ||||
|  */ | ||||
| #pragma once | ||||
|  | ||||
| /******************************************************************************** | ||||
|  * @file     lcd/e3v2/marlinui/dwin_lcd.h | ||||
|  * @brief    DWIN screen control functions | ||||
|  ********************************************************************************/ | ||||
|  | ||||
| #include <stdint.h> | ||||
|  | ||||
| #define RECEIVED_NO_DATA         0x00 | ||||
| #define RECEIVED_SHAKE_HAND_ACK  0x01 | ||||
|  | ||||
| #define FHONE                    0xAA | ||||
|  | ||||
| #define DWIN_SCROLL_UP   2 | ||||
| #define DWIN_SCROLL_DOWN 3 | ||||
|  | ||||
| #if DISABLED(DWIN_MARLINUI_LANDSCAPE) | ||||
|   #define DWIN_WIDTH  272 | ||||
|   #define DWIN_HEIGHT 480 | ||||
| #else | ||||
|   #define DWIN_WIDTH  480 | ||||
|   #define DWIN_HEIGHT 272 | ||||
| #endif | ||||
|  | ||||
| // Picture ID | ||||
| #define DWIN_Boot_Horiz      0 | ||||
| #define DWIN_Boot_Vert       1 | ||||
| #define DWIN_MarlinUI_Assets 2 | ||||
|  | ||||
| /** | ||||
|  * 3-.0:The font size, 0x00-0x09, corresponds to the font size below: | ||||
|  * 0x00=6*12   0x01=8*16   0x02=10*20  0x03=12*24  0x04=14*28 | ||||
|  * 0x05=16*32  0x06=20*40  0x07=24*48  0x08=28*56  0x09=32*64 | ||||
|  */ | ||||
| #define font6x12  0x00 | ||||
| #define font8x16  0x01 | ||||
| #define font10x20 0x02 | ||||
| #define font12x24 0x03 | ||||
| #define font14x28 0x04 | ||||
| #define font16x32 0x05 | ||||
| #define font20x40 0x06 | ||||
| #define font24x48 0x07 | ||||
| #define font28x56 0x08 | ||||
| #define font32x64 0x09 | ||||
|  | ||||
| #define DWIN_FONT_MENU  font10x20 | ||||
| #define DWIN_FONT_STAT  font14x28 | ||||
| #define DWIN_FONT_HEAD  font10x20 | ||||
| #define DWIN_FONT_ALERT font14x28 | ||||
|  | ||||
| // Color | ||||
| #define Color_White       0xFFFF | ||||
| #define Color_Yellow      0xFF0F | ||||
| #define Color_Error_Red   0xB000  // Error! | ||||
| #define Color_Bg_Red      0xF00F  // Red background color | ||||
| #define Color_Bg_Window   0x31E8  // Popup background color | ||||
| #define Color_Bg_Heading  0x3344  // Static Heading | ||||
| #define Color_Bg_Blue     0x1125  // Dark blue background color | ||||
| #define Color_Bg_Black    0x0841  // Black background color | ||||
| #define Color_IconBlue    0x45FA  // Lighter blue that matches icons/accents | ||||
| #define Popup_Text_Color  0xD6BA  // Popup font background color | ||||
| #define Line_Color        0x3A6A  // Split line color | ||||
| #define Rectangle_Color   0xEE2F  // Blue square cursor color | ||||
| #define Percent_Color     0xFE29  // Percentage color | ||||
| #define BarFill_Color     0x10E4  // Fill color of progress bar | ||||
| #define Select_Color      0x33BB  // Selected color | ||||
|  | ||||
| // Character matrix width x height | ||||
| //#define LCD_WIDTH ((DWIN_WIDTH) / 8) | ||||
| //#define LCD_HEIGHT ((DWIN_HEIGHT) / 12) | ||||
|  | ||||
| // ICON ID | ||||
| #define BOOT_ICON           3 // Icon set file 3.ICO | ||||
| #define ICON                4 // Icon set file 4.ICO | ||||
|  | ||||
| // MarlinUI Boot Icons | ||||
| #define ICON_MarlinBoot            0 | ||||
| #define ICON_OpenSource            1 | ||||
| #define ICON_GitHubURL             2 | ||||
| #define ICON_MarlinURL             3 | ||||
| #define ICON_Copyright             4 | ||||
|  | ||||
| // MarlinUI Icons | ||||
| #define ICON_LOGO_Marlin           0 | ||||
| #define ICON_HotendOff             1 | ||||
| #define ICON_HotendOn              2 | ||||
| #define ICON_BedOff                3 | ||||
| #define ICON_BedOn                 4 | ||||
| #define ICON_Fan0                  5 | ||||
| #define ICON_Fan1                  6 | ||||
| #define ICON_Fan2                  7 | ||||
| #define ICON_Fan3                  8 | ||||
| #define ICON_Halted                9 | ||||
| #define ICON_Question             10 | ||||
| #define ICON_Alert                11 | ||||
| #define ICON_RotateCW             12 | ||||
| #define ICON_RotateCCW            13 | ||||
| #define ICON_UpArrow              14 | ||||
| #define ICON_DownArrow            15 | ||||
| #define ICON_BedLine              16 | ||||
|  | ||||
| #define ICON_AdvSet               ICON_Language | ||||
| #define ICON_HomeOff              ICON_AdvSet | ||||
| #define ICON_HomeOffX             ICON_StepX | ||||
| #define ICON_HomeOffY             ICON_StepY | ||||
| #define ICON_HomeOffZ             ICON_StepZ | ||||
| #define ICON_ProbeOff             ICON_AdvSet | ||||
| #define ICON_ProbeOffX            ICON_StepX | ||||
| #define ICON_ProbeOffY            ICON_StepY | ||||
| #define ICON_PIDNozzle            ICON_SetEndTemp | ||||
| #define ICON_PIDbed               ICON_SetBedTemp | ||||
|  | ||||
| /*-------------------------------------- System variable function --------------------------------------*/ | ||||
|  | ||||
| // Handshake (1: Success, 0: Fail) | ||||
| bool DWIN_Handshake(void); | ||||
|  | ||||
| // Common DWIN startup | ||||
| void DWIN_Startup(void); | ||||
|  | ||||
| // Set the backlight luminance | ||||
| //  luminance: (0x00-0xFF) | ||||
| void DWIN_Backlight_SetLuminance(const uint8_t luminance); | ||||
|  | ||||
| // Set screen display direction | ||||
| //  dir: 0=0°, 1=90°, 2=180°, 3=270° | ||||
| void DWIN_Frame_SetDir(uint8_t dir); | ||||
|  | ||||
| // Update display | ||||
| void DWIN_UpdateLCD(void); | ||||
|  | ||||
| /*---------------------------------------- Drawing functions ----------------------------------------*/ | ||||
|  | ||||
| // Clear screen | ||||
| //  color: Clear screen color | ||||
| void DWIN_Frame_Clear(const uint16_t color); | ||||
|  | ||||
| // Draw a point | ||||
| //  color: point color | ||||
| //  width: point width   0x01-0x0F | ||||
| //  height: point height 0x01-0x0F | ||||
| //  x,y: upper left point | ||||
| void DWIN_Draw_Point(uint16_t color, uint8_t width, uint8_t height, uint16_t x, uint16_t y); | ||||
|  | ||||
| // Draw a line | ||||
| //  color: Line segment color | ||||
| //  xStart/yStart: Start point | ||||
| //  xEnd/yEnd: End point | ||||
| void DWIN_Draw_Line(uint16_t color, uint16_t xStart, uint16_t yStart, uint16_t xEnd, uint16_t yEnd); | ||||
|  | ||||
| // Draw a Horizontal line | ||||
| //  color: Line segment color | ||||
| //  xStart/yStart: Start point | ||||
| //  xLength: Line Length | ||||
| inline void DWIN_Draw_HLine(uint16_t color, uint16_t xStart, uint16_t yStart, uint16_t xLength) { | ||||
|   DWIN_Draw_Line(color, xStart, yStart, xStart + xLength - 1, yStart); | ||||
| } | ||||
|  | ||||
| // Draw a Vertical line | ||||
| //  color: Line segment color | ||||
| //  xStart/yStart: Start point | ||||
| //  yLength: Line Length | ||||
| inline void DWIN_Draw_VLine(uint16_t color, uint16_t xStart, uint16_t yStart, uint16_t yLength) { | ||||
|   DWIN_Draw_Line(color, xStart, yStart, xStart, yStart + yLength - 1); | ||||
| } | ||||
|  | ||||
| // Draw a rectangle | ||||
| //  mode: 0=frame, 1=fill, 2=XOR fill | ||||
| //  color: Rectangle color | ||||
| //  xStart/yStart: upper left point | ||||
| //  xEnd/yEnd: lower right point | ||||
| void DWIN_Draw_Rectangle(uint8_t mode, uint16_t color, | ||||
|                          uint16_t xStart, uint16_t yStart, uint16_t xEnd, uint16_t yEnd); | ||||
|  | ||||
| // Draw a box | ||||
| //  mode: 0=frame, 1=fill, 2=XOR fill | ||||
| //  color: Rectangle color | ||||
| //  xStart/yStart: upper left point | ||||
| //  xSize/ySize: box size | ||||
| inline void DWIN_Draw_Box(uint8_t mode, uint16_t color, uint16_t xStart, uint16_t yStart, uint16_t xSize, uint16_t ySize) { | ||||
|   DWIN_Draw_Rectangle(mode, color, xStart, yStart, xStart + xSize - 1, yStart + ySize - 1); | ||||
| } | ||||
|  | ||||
| // Move a screen area | ||||
| //  mode: 0, circle shift; 1, translation | ||||
| //  dir: 0=left, 1=right, 2=up, 3=down | ||||
| //  dis: Distance | ||||
| //  color: Fill color | ||||
| //  xStart/yStart: upper left point | ||||
| //  xEnd/yEnd: bottom right point | ||||
| void DWIN_Frame_AreaMove(uint8_t mode, uint8_t dir, uint16_t dis, | ||||
|                          uint16_t color, uint16_t xStart, uint16_t yStart, uint16_t xEnd, uint16_t yEnd); | ||||
|  | ||||
| /*---------------------------------------- Text related functions ----------------------------------------*/ | ||||
|  | ||||
| // Draw a string | ||||
| //  bShow: true=display background color; false=don't display background color | ||||
| //  size: Font size | ||||
| //  color: Character color | ||||
| //  bColor: Background color | ||||
| //  x/y: Upper-left coordinate of the string | ||||
| //  *string: The string | ||||
| void DWIN_Draw_String(bool bShow, uint8_t size, uint16_t color, uint16_t bColor, uint16_t x, uint16_t y, char *string); | ||||
|  | ||||
| class __FlashStringHelper; | ||||
|  | ||||
| inline void DWIN_Draw_String(bool bShow, uint8_t size, uint16_t color, uint16_t bColor, uint16_t x, uint16_t y, const __FlashStringHelper *title) { | ||||
|   DWIN_Draw_String(bShow, size, color, bColor, x, y, (char *)title); | ||||
| } | ||||
|  | ||||
| // Draw a positive integer | ||||
| //  bShow: true=display background color; false=don't display background color | ||||
| //  zeroFill: true=zero fill; false=no zero fill | ||||
| //  zeroMode: 1=leading 0 displayed as 0; 0=leading 0 displayed as a space | ||||
| //  size: Font size | ||||
| //  color: Character color | ||||
| //  bColor: Background color | ||||
| //  iNum: Number of digits | ||||
| //  x/y: Upper-left coordinate | ||||
| //  value: Integer value | ||||
| void DWIN_Draw_IntValue(uint8_t bShow, bool zeroFill, uint8_t zeroMode, uint8_t size, uint16_t color, | ||||
|                           uint16_t bColor, uint8_t iNum, uint16_t x, uint16_t y, uint16_t value); | ||||
|  | ||||
| // Draw a floating point number | ||||
| //  bShow: true=display background color; false=don't display background color | ||||
| //  zeroFill: true=zero fill; false=no zero fill | ||||
| //  zeroMode: 1=leading 0 displayed as 0; 0=leading 0 displayed as a space | ||||
| //  size: Font size | ||||
| //  color: Character color | ||||
| //  bColor: Background color | ||||
| //  iNum: Number of whole digits | ||||
| //  fNum: Number of decimal digits | ||||
| //  x/y: Upper-left point | ||||
| //  value: Float value | ||||
| void DWIN_Draw_FloatValue(uint8_t bShow, bool zeroFill, uint8_t zeroMode, uint8_t size, uint16_t color, | ||||
|                             uint16_t bColor, uint8_t iNum, uint8_t fNum, uint16_t x, uint16_t y, long value); | ||||
|  | ||||
| /*---------------------------------------- Picture related functions ----------------------------------------*/ | ||||
|  | ||||
| // Draw JPG and cached in #0 virtual display area | ||||
| // id: Picture ID | ||||
| void DWIN_JPG_ShowAndCache(const uint8_t id); | ||||
|  | ||||
| // Draw an Icon | ||||
| //  libID: Icon library ID | ||||
| //  picID: Icon ID | ||||
| //  x/y: Upper-left point | ||||
| void DWIN_ICON_Show(uint8_t libID, uint8_t picID, uint16_t x, uint16_t y); | ||||
|  | ||||
| // Unzip the JPG picture to a virtual display area | ||||
| //  n: Cache index | ||||
| //  id: Picture ID | ||||
| void DWIN_JPG_CacheToN(uint8_t n, uint8_t id); | ||||
|  | ||||
| // Unzip the JPG picture to virtual display area #1 | ||||
| //  id: Picture ID | ||||
| inline void DWIN_JPG_CacheTo1(uint8_t id) { DWIN_JPG_CacheToN(1, id); } | ||||
|  | ||||
| // Copy area from virtual display area to current screen | ||||
| //  cacheID: virtual area number | ||||
| //  xStart/yStart: Upper-left of virtual area | ||||
| //  xEnd/yEnd: Lower-right of virtual area | ||||
| //  x/y: Screen paste point | ||||
| void DWIN_Frame_AreaCopy(uint8_t cacheID, uint16_t xStart, uint16_t yStart, | ||||
|                          uint16_t xEnd, uint16_t yEnd, uint16_t x, uint16_t y); | ||||
|  | ||||
| // Animate a series of icons | ||||
| //  animID: Animation ID  up to 16 | ||||
| //  animate: animation on or off | ||||
| //  libID: Icon library ID | ||||
| //  picIDs: Icon starting ID | ||||
| //  picIDe: Icon ending ID | ||||
| //  x/y: Upper-left point | ||||
| //  interval: Display time interval, unit 10mS | ||||
| void DWIN_ICON_Animation(uint8_t animID, bool animate, uint8_t libID, uint8_t picIDs, | ||||
|                          uint8_t picIDe, uint16_t x, uint16_t y, uint16_t interval); | ||||
|  | ||||
| // Animation Control | ||||
| //  state: 16 bits, each bit is the state of an animation id | ||||
| void DWIN_ICON_AnimationControl(uint16_t state); | ||||
							
								
								
									
										180
									
								
								Marlin/src/lcd/e3v2/marlinui/dwin_string.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										180
									
								
								Marlin/src/lcd/e3v2/marlinui/dwin_string.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,180 @@ | ||||
| /** | ||||
|  * Marlin 3D Printer Firmware | ||||
|  * Copyright (c) 2021 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] | ||||
|  * | ||||
|  * Based on Sprinter and grbl. | ||||
|  * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm | ||||
|  * | ||||
|  * 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. | ||||
|  * | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with this program.  If not, see <https://www.gnu.org/licenses/>. | ||||
|  * | ||||
|  */ | ||||
|  | ||||
| #include "../../../inc/MarlinConfig.h" | ||||
|  | ||||
| #if IS_DWIN_MARLINUI | ||||
|  | ||||
| #include "dwin_string.h" | ||||
| //#include "../../fontutils.h" | ||||
|  | ||||
| uint8_t DWIN_String::data[]; | ||||
| uint16_t DWIN_String::span; | ||||
| uint8_t DWIN_String::len; | ||||
|  | ||||
| void DWIN_String::set() { | ||||
|   //*data = 0x00; | ||||
|   memset(data, 0x00, sizeof(data)); | ||||
|   span = 0; | ||||
|   len = 0; | ||||
| } | ||||
|  | ||||
| uint8_t read_byte(uint8_t *byte) { return *byte; } | ||||
|  | ||||
| /** | ||||
|  * Add a string, applying substitutions for the following characters: | ||||
|  * | ||||
|  *   = displays  '0'....'10' for indexes 0 - 10 | ||||
|  *   ~ displays  '1'....'11' for indexes 0 - 10 | ||||
|  *   * displays 'E1'...'E11' for indexes 0 - 10 (By default. Uses LCD_FIRST_TOOL) | ||||
|  */ | ||||
| void DWIN_String::add(uint8_t *string, int8_t index, uint8_t *itemString) { | ||||
|   wchar_t wchar; | ||||
|  | ||||
|   while (*string) { | ||||
|     string = get_utf8_value_cb(string, read_byte, &wchar); | ||||
|     if (wchar > 255) wchar |= 0x0080; | ||||
|     uint8_t ch = uint8_t(wchar & 0x00FF); | ||||
|  | ||||
|     if (ch == '=' || ch == '~' || ch == '*') { | ||||
|       if (index >= 0) { | ||||
|         int8_t inum = index + ((ch == '=') ? 0 : LCD_FIRST_TOOL); | ||||
|         if (ch == '*') add_character('E'); | ||||
|         if (inum >= 10) { add_character('0' + (inum / 10)); inum %= 10; } | ||||
|         add_character('0' + inum); | ||||
|       } | ||||
|       else { | ||||
|         add(index == -2 ? GET_TEXT(MSG_CHAMBER) : GET_TEXT(MSG_BED)); | ||||
|       } | ||||
|       continue; | ||||
|     } | ||||
|     else if (ch == '$' && itemString) { | ||||
|       add(itemString); | ||||
|       continue; | ||||
|     } | ||||
|  | ||||
|     add_character(ch); | ||||
|   } | ||||
|   eol(); | ||||
| } | ||||
|  | ||||
| void DWIN_String::add(uint8_t *string, uint8_t max_len) { | ||||
|   wchar_t wchar; | ||||
|   while (*string && max_len) { | ||||
|     string = get_utf8_value_cb(string, read_byte, &wchar); | ||||
|     /* | ||||
|     if (wchar > 255) wchar |= 0x0080; | ||||
|     uint8_t ch = uint8_t(wchar & 0x00FF); | ||||
|     add_character(ch); | ||||
|     */ | ||||
|     add(wchar); | ||||
|     max_len--; | ||||
|   } | ||||
|   eol(); | ||||
| } | ||||
|  | ||||
| void DWIN_String::add(wchar_t character) { | ||||
|   int ret; | ||||
|   size_t idx = 0; | ||||
|   dwin_charmap_t pinval; | ||||
|   dwin_charmap_t *copy_address = nullptr; | ||||
|   pinval.uchar = character; | ||||
|   pinval.idx = -1; | ||||
|  | ||||
|   // For 8-bit ASCII just print the single character | ||||
|   char str[] = { '?', 0 }; | ||||
|   if (character < 255) { | ||||
|     str[0] = (char)character; | ||||
|   } | ||||
|   else { | ||||
|     copy_address = nullptr; | ||||
|     ret = pf_bsearch_r((void *)g_dwin_charmap_device, COUNT(g_dwin_charmap_device), pf_bsearch_cb_comp_dwinmap_pgm, (void *)&pinval, &idx); | ||||
|     if (ret >= 0) { | ||||
|       copy_address = (dwin_charmap_t*)(g_dwin_charmap_device + idx); | ||||
|     } | ||||
|     else { | ||||
|       ret = pf_bsearch_r((void *)g_dwin_charmap_common, COUNT(g_dwin_charmap_common), pf_bsearch_cb_comp_dwinmap_pgm, (void *)&pinval, &idx); | ||||
|       if (ret >= 0) | ||||
|         copy_address = (dwin_charmap_t*)(g_dwin_charmap_common + idx); | ||||
|     } | ||||
|     if (ret >= 0) { | ||||
|       dwin_charmap_t localval; | ||||
|       memcpy_P(&localval, copy_address, sizeof(localval)); | ||||
|       str[0] = localval.idx; | ||||
|       str[1] = localval.idx2; | ||||
|     } | ||||
|   } | ||||
|   if (str[0]) add_character(str[0]); | ||||
|   if (str[1]) add_character(str[1]); | ||||
| } | ||||
|  | ||||
| void DWIN_String::add_character(uint8_t character) { | ||||
|   if (len < MAX_STRING_LENGTH) { | ||||
|     data[len] = character; | ||||
|     len++; | ||||
|     //span += glyph(character)->DWidth; | ||||
|   } | ||||
| } | ||||
|  | ||||
| void DWIN_String::rtrim(uint8_t character) { | ||||
|   while (len) { | ||||
|     if (data[len - 1] == 0x20 || data[len - 1] == character) { | ||||
|       len--; | ||||
|       //span -= glyph(data[length])->DWidth; | ||||
|       eol(); | ||||
|     } | ||||
|     else | ||||
|       break; | ||||
|   } | ||||
| } | ||||
|  | ||||
| void DWIN_String::ltrim(uint8_t character) { | ||||
|   uint16_t i, j; | ||||
|   for (i = 0; (i < len) && (data[i] == 0x20 || data[i] == character); i++) { | ||||
|     //span -= glyph(data[i])->DWidth; | ||||
|   } | ||||
|   if (i == 0) return; | ||||
|   for (j = 0; i < len; data[j++] = data[i++]); | ||||
|   len = j; | ||||
|   eol(); | ||||
| } | ||||
|  | ||||
| void DWIN_String::trim(uint8_t character) { | ||||
|   rtrim(character); | ||||
|   ltrim(character); | ||||
| } | ||||
|  | ||||
| /* return v1 - v2 */ | ||||
| int dwin_charmap_compare(dwin_charmap_t *v1, dwin_charmap_t *v2) { | ||||
|   return (v1->uchar < v2->uchar) ? -1 : (v1->uchar > v2->uchar) ? 1 : 0; | ||||
| } | ||||
|  | ||||
| int pf_bsearch_cb_comp_dwinmap_pgm(void *userdata, size_t idx, void * data_pin) { | ||||
|   dwin_charmap_t localval; | ||||
|   dwin_charmap_t *p_dwin_charmap = (dwin_charmap_t *)userdata; | ||||
|   memcpy_P(&localval, p_dwin_charmap + idx, sizeof(localval)); | ||||
|   return dwin_charmap_compare(&localval, (dwin_charmap_t *)data_pin); | ||||
| } | ||||
|  | ||||
| DWIN_String dwin_string; | ||||
|  | ||||
| #endif // IS_DWIN_MARLINUI | ||||
							
								
								
									
										1007
									
								
								Marlin/src/lcd/e3v2/marlinui/dwin_string.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1007
									
								
								Marlin/src/lcd/e3v2/marlinui/dwin_string.h
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										193
									
								
								Marlin/src/lcd/e3v2/marlinui/lcdprint_dwin.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										193
									
								
								Marlin/src/lcd/e3v2/marlinui/lcdprint_dwin.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,193 @@ | ||||
| /** | ||||
|  * Marlin 3D Printer Firmware | ||||
|  * Copyright (c) 2021 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] | ||||
|  * | ||||
|  * Based on Sprinter and grbl. | ||||
|  * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm | ||||
|  * | ||||
|  * 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. | ||||
|  * | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with this program.  If not, see <http://www.gnu.org/licenses/>. | ||||
|  * | ||||
|  */ | ||||
|  | ||||
| /** | ||||
|  * lcd/e3v2/marlinui/lcdprint_dwin.cpp | ||||
|  * | ||||
|  * Due to DWIN hardware limitations simplified characters are used | ||||
|  */ | ||||
|  | ||||
| #include "../../../inc/MarlinConfigPre.h" | ||||
|  | ||||
| #if IS_DWIN_MARLINUI | ||||
|  | ||||
| #include "lcdprint_dwin.h" | ||||
| #include "dwin_lcd.h" | ||||
| #include "dwin_string.h" | ||||
|  | ||||
| #include "../../marlinui.h" | ||||
| #include "../../../MarlinCore.h" | ||||
|  | ||||
| #include <string.h> | ||||
|  | ||||
| cursor_t cursor; | ||||
|  | ||||
| extern dwin_font_t dwin_font; | ||||
|  | ||||
| void lcd_moveto_xy(const lcd_uint_t x, const lcd_uint_t y) { cursor.x = x; cursor.y = y; } | ||||
|  | ||||
| void lcd_moveto(const lcd_uint_t col, const lcd_uint_t row) { | ||||
|   cursor.x = col * dwin_font.width; | ||||
|   cursor.y = (row * (dwin_font.height + EXTRA_ROW_HEIGHT)) + (EXTRA_ROW_HEIGHT / 2); | ||||
| } | ||||
|  | ||||
| inline void lcd_advance_cursor() { cursor.x += dwin_font.width; } | ||||
|  | ||||
| void lcd_put_int(const int i) { | ||||
|   // TODO: Draw an int at the cursor position, advance the cursor | ||||
| } | ||||
|  | ||||
| int lcd_put_dwin_string() { | ||||
|   DWIN_Draw_String(dwin_font.solid, dwin_font.index, dwin_font.fg, dwin_font.bg, cursor.x, cursor.y, (char*)dwin_string.string()); | ||||
|   cursor.x += dwin_string.length() * dwin_font.width; | ||||
|   return dwin_string.length(); | ||||
| } | ||||
|  | ||||
| // return < 0 on error | ||||
| // return the advanced cols | ||||
| int lcd_put_wchar_max(wchar_t c, pixel_len_t max_length) { | ||||
|   dwin_string.set(); | ||||
|   dwin_string.add(c); | ||||
|   dwin_string.truncate(max_length); | ||||
|   // Draw the char(s) at the cursor and advance the cursor | ||||
|   DWIN_Draw_String(dwin_font.solid, dwin_font.index, dwin_font.fg, dwin_font.bg, cursor.x, cursor.y, (char*)dwin_string.string()); | ||||
|   cursor.x += dwin_string.length() * dwin_font.width; | ||||
|   return dwin_string.length(); | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * @brief Draw a UTF-8 string | ||||
|  * | ||||
|  * @param utf8_str : the UTF-8 string | ||||
|  * @param cb_read_byte : the callback function to read one byte from the utf8_str (from RAM or ROM) | ||||
|  * @param max_length : the pixel length of the string allowed (or number of slots in HD44780) | ||||
|  * | ||||
|  * @return the number of pixels advanced | ||||
|  * | ||||
|  * Draw a UTF-8 string | ||||
|  */ | ||||
| static int lcd_put_u8str_max_cb(const char * utf8_str, uint8_t (*cb_read_byte)(uint8_t * str), pixel_len_t max_length) { | ||||
|   uint8_t *p = (uint8_t *)utf8_str; | ||||
|   dwin_string.set(); | ||||
|   while (dwin_string.length() < max_length) { | ||||
|     wchar_t ch = 0; | ||||
|     p = get_utf8_value_cb(p, cb_read_byte, &ch); | ||||
|     if (!ch) break; | ||||
|     dwin_string.add(ch); | ||||
|   } | ||||
|   DWIN_Draw_String(dwin_font.solid, dwin_font.index, dwin_font.fg, dwin_font.bg, cursor.x, cursor.y, (char*)dwin_string.string()); | ||||
|   cursor.x += dwin_string.length() * dwin_font.width; | ||||
|   return dwin_string.length(); | ||||
| } | ||||
|  | ||||
| int lcd_put_u8str_max(const char * utf8_str, pixel_len_t max_length) { | ||||
|   return lcd_put_u8str_max_cb(utf8_str, read_byte_ram, max_length); | ||||
| } | ||||
|  | ||||
| int lcd_put_u8str_max_P(PGM_P utf8_str_P, pixel_len_t max_length) { | ||||
|   return lcd_put_u8str_max_cb(utf8_str_P, read_byte_rom, max_length); | ||||
| } | ||||
|  | ||||
| lcd_uint_t lcd_put_u8str_ind_P(PGM_P const pstr, const int8_t ind, PGM_P const inStr/*=nullptr*/, const lcd_uint_t maxlen/*=LCD_WIDTH*/) { | ||||
|   dwin_string.set(); | ||||
|   dwin_string.add((uint8_t*)pstr, ind, (uint8_t*)inStr); | ||||
|   dwin_string.truncate(maxlen); | ||||
|   DWIN_Draw_String(dwin_font.solid, dwin_font.index, dwin_font.fg, dwin_font.bg, cursor.x, cursor.y, (char*)dwin_string.string()); | ||||
|   cursor.x += dwin_string.length() * dwin_font.width; | ||||
|   return dwin_string.length(); | ||||
| } | ||||
|  | ||||
| #if ENABLED(DEBUG_LCDPRINT) | ||||
|  | ||||
|   int test_dwin_charmap(dwin_charmap_t *data, size_t size, char *name, char flg_show_contents) { | ||||
|     int ret; | ||||
|     size_t idx = 0; | ||||
|     dwin_charmap_t preval = { 0, 0, 0 }; | ||||
|     dwin_charmap_t pinval = { 0, 0, 0 }; | ||||
|     char flg_error = 0; | ||||
|  | ||||
|     int i; | ||||
|  | ||||
|     TRACE("Test %s\n", name); | ||||
|  | ||||
|     for (i = 0; i < size; i ++) { | ||||
|       memcpy_P(&pinval, &(data[i]), sizeof(pinval)); | ||||
|  | ||||
|       if (flg_show_contents) { | ||||
|         #if 1 | ||||
|           TRACE("[% 4d] % 6" PRIu32 "(0x%04" PRIX32 ") --> 0x%02X,0x%02X%s\n", i, pinval.uchar, pinval.uchar, (unsigned int)(pinval.idx), (unsigned int)(pinval.idx2), (preval.uchar < pinval.uchar?"":" <--- ERROR")); | ||||
|         #else | ||||
|           TRACE("[% 4d]", i); | ||||
|           TRACE("% 6" PRIu32 "(0x%04" PRIX32 "),", pinval.uchar, pinval.uchar); | ||||
|           TRACE("0x%02X,", (unsigned int)(pinval.idx)); | ||||
|           TRACE("0x%02X,", (unsigned int)(pinval.idx2)); | ||||
|           TRACE("%s", (preval.uchar < pinval.uchar?"":" <--- ERROR")); | ||||
|         #endif | ||||
|       } | ||||
|       if (preval.uchar >= pinval.uchar) { | ||||
|         flg_error = 1; | ||||
|         //TRACE("Error: out of order in array %s: idx=%d, val=%d(0x%x)\n", name, i, pinval.uchar, pinval.uchar); | ||||
|         //return -1; | ||||
|       } | ||||
|       memcpy(&preval, &pinval, sizeof(pinval)); | ||||
|  | ||||
|       ret = pf_bsearch_r((void *)data, size, pf_bsearch_cb_comp_dwinmap_pgm, (void *)&pinval, &idx); | ||||
|       if (ret < 0) { | ||||
|         flg_error = 1; | ||||
|         TRACE("Error: not found item in array %s: idx=%d, val=%d(0x%x)\n", name, i, pinval.uchar, pinval.uchar); | ||||
|         //return -1; | ||||
|       } | ||||
|       if (idx != i) { | ||||
|         flg_error = 1; | ||||
|         TRACE("Error: wrong index found item in array %s: idx=%d, val=%d(0x%x)\n", name, i, pinval.uchar, pinval.uchar); | ||||
|         //return -1; | ||||
|       } | ||||
|     } | ||||
|     if (flg_error) { | ||||
|       TRACE("\nError: in array %s\n\n", name); | ||||
|       return -1; | ||||
|     } | ||||
|     TRACE("\nPASS array %s\n\n", name); | ||||
|     return 0; | ||||
|   } | ||||
|  | ||||
|   int test_dwin_charmap_all() { | ||||
|     int flg_error = 0; | ||||
|     if (test_dwin_charmap(g_dwin_charmap_device, COUNT(g_dwin_charmap_device), "g_dwin_charmap_device", 0) < 0) { | ||||
|       flg_error = 1; | ||||
|       test_dwin_charmap(g_dwin_charmap_device, COUNT(g_dwin_charmap_device), "g_dwin_charmap_device", 1); | ||||
|     } | ||||
|     if (test_dwin_charmap(g_dwin_charmap_common, COUNT(g_dwin_charmap_common), "g_dwin_charmap_common", 0) < 0) { | ||||
|       flg_error = 1; | ||||
|       test_dwin_charmap(g_dwin_charmap_common, COUNT(g_dwin_charmap_common), "g_dwin_charmap_common", 1); | ||||
|     } | ||||
|     if (flg_error) { | ||||
|       TRACE("\nFAILED in dwin tests!\n"); | ||||
|       return -1; | ||||
|     } | ||||
|     TRACE("\nPASS in dwin tests.\n"); | ||||
|     return 0; | ||||
|   } | ||||
|  | ||||
| #endif // DEBUG_LCDPRINT | ||||
|  | ||||
| #endif // IS_DWIN_MARLINUI | ||||
							
								
								
									
										30
									
								
								Marlin/src/lcd/e3v2/marlinui/lcdprint_dwin.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										30
									
								
								Marlin/src/lcd/e3v2/marlinui/lcdprint_dwin.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,30 @@ | ||||
| /** | ||||
|  * Marlin 3D Printer Firmware | ||||
|  * Copyright (c) 2021 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] | ||||
|  * | ||||
|  * Based on Sprinter and grbl. | ||||
|  * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm | ||||
|  * | ||||
|  * 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. | ||||
|  * | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with this program.  If not, see <https://www.gnu.org/licenses/>. | ||||
|  * | ||||
|  */ | ||||
| #pragma once | ||||
|  | ||||
| #include "../../lcdprint.h" | ||||
|  | ||||
| typedef struct { int16_t x, y; } cursor_t; | ||||
| extern cursor_t cursor; | ||||
|  | ||||
| int lcd_put_dwin_string(); | ||||
| void lcd_moveto_xy(const lcd_uint_t, const lcd_uint_t); | ||||
							
								
								
									
										146
									
								
								Marlin/src/lcd/e3v2/marlinui/marlinui_dwin.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										146
									
								
								Marlin/src/lcd/e3v2/marlinui/marlinui_dwin.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,146 @@ | ||||
| /** | ||||
|  * Marlin 3D Printer Firmware | ||||
|  * Copyright (c) 2021 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] | ||||
|  * | ||||
|  * Based on Sprinter and grbl. | ||||
|  * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm | ||||
|  * | ||||
|  * 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. | ||||
|  * | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with this program.  If not, see <http://www.gnu.org/licenses/>. | ||||
|  * | ||||
|  */ | ||||
| #pragma once | ||||
|  | ||||
| /** | ||||
|  * lcd/e3v2/marlinui/lcdprint_dwin.h | ||||
|  */ | ||||
|  | ||||
| #include "../../../inc/MarlinConfigPre.h" | ||||
| #include "dwin_lcd.h" | ||||
|  | ||||
| typedef uint16_t dwin_coord_t;  // Screen can be pretty big | ||||
| typedef uint16_t lcd_uint_t; | ||||
| typedef int16_t lcd_int_t; | ||||
|  | ||||
| typedef struct { | ||||
|   uint8_t index, width, height; | ||||
|   uint16_t fg, bg; | ||||
|   bool solid; | ||||
| } dwin_font_t; | ||||
|  | ||||
| extern dwin_font_t dwin_font; | ||||
|  | ||||
| // Only Western languages support big / small fonts | ||||
| //#if DISABLED(DISPLAY_CHARSET_ISO10646_1) | ||||
| //  #undef USE_BIG_EDIT_FONT | ||||
| //  #undef USE_SMALL_INFOFONT | ||||
| //#endif | ||||
|  | ||||
| #if ENABLED(USE_BIG_EDIT_FONT) | ||||
|   #define DWIN_FONT_EDIT font10x20 | ||||
| #else | ||||
|   #define DWIN_FONT_EDIT font8x16 | ||||
| #endif | ||||
|  | ||||
| #define DWIN_FONT_INFO font8x16 | ||||
|  | ||||
| #if DWIN_FONT_MENU == font6x12 | ||||
|   #define MENU_FONT_WIDTH    6 | ||||
|   #define MENU_FONT_ASCENT  10 | ||||
|   #define MENU_FONT_DESCENT  2 | ||||
| #elif DWIN_FONT_MENU == font8x16 | ||||
|   #define MENU_FONT_WIDTH    8 | ||||
|   #define MENU_FONT_ASCENT  13 | ||||
|   #define MENU_FONT_DESCENT  3 | ||||
| #elif DWIN_FONT_MENU == font10x20 | ||||
|   #define MENU_FONT_WIDTH   10 | ||||
|   #define MENU_FONT_ASCENT  16 | ||||
|   #define MENU_FONT_DESCENT  4 | ||||
| #endif | ||||
| #define MENU_FONT_HEIGHT (MENU_FONT_ASCENT + MENU_FONT_DESCENT) | ||||
|  | ||||
| #define EXTRA_ROW_HEIGHT 8 | ||||
| #define MENU_LINE_HEIGHT (MENU_FONT_HEIGHT + EXTRA_ROW_HEIGHT) | ||||
|  | ||||
| #if DWIN_FONT_EDIT == font6x12 | ||||
|   #define EDIT_FONT_WIDTH    6 | ||||
|   #define EDIT_FONT_ASCENT  10 | ||||
|   #define EDIT_FONT_DESCENT  2 | ||||
| #elif DWIN_FONT_EDIT == font8x16 | ||||
|   #define EDIT_FONT_WIDTH    8 | ||||
|   #define EDIT_FONT_ASCENT  13 | ||||
|   #define EDIT_FONT_DESCENT  3 | ||||
| #elif DWIN_FONT_EDIT == font10x20 | ||||
|   #define EDIT_FONT_WIDTH   10 | ||||
|   #define EDIT_FONT_ASCENT  16 | ||||
|   #define EDIT_FONT_DESCENT  4 | ||||
| #endif | ||||
| #define EDIT_FONT_HEIGHT (EDIT_FONT_ASCENT + EDIT_FONT_DESCENT) | ||||
|  | ||||
| #if DWIN_FONT_INFO == font6x12 | ||||
|   #define INFO_FONT_WIDTH    6 | ||||
|   #define INFO_FONT_ASCENT  10 | ||||
|   #define INFO_FONT_DESCENT  2 | ||||
| #elif DWIN_FONT_INFO == font8x16 | ||||
|   #define INFO_FONT_WIDTH    8 | ||||
|   #define INFO_FONT_ASCENT  13 | ||||
|   #define INFO_FONT_DESCENT  3 | ||||
| #elif DWIN_FONT_INFO == font10x20 | ||||
|   #define INFO_FONT_WIDTH   10 | ||||
|   #define INFO_FONT_ASCENT  16 | ||||
|   #define INFO_FONT_DESCENT  4 | ||||
| #endif | ||||
| #define INFO_FONT_HEIGHT (INFO_FONT_ASCENT + INFO_FONT_DESCENT) | ||||
|  | ||||
| #if DWIN_FONT_STAT == font6x12 | ||||
|   #define STAT_FONT_WIDTH    6 | ||||
|   #define STAT_FONT_ASCENT  10 | ||||
|   #define STAT_FONT_DESCENT  2 | ||||
| #elif DWIN_FONT_STAT == font8x16 | ||||
|   #define STAT_FONT_WIDTH    8 | ||||
|   #define STAT_FONT_ASCENT  13 | ||||
|   #define STAT_FONT_DESCENT  3 | ||||
| #elif DWIN_FONT_STAT == font10x20 | ||||
|   #define STAT_FONT_WIDTH   10 | ||||
|   #define STAT_FONT_ASCENT  16 | ||||
|   #define STAT_FONT_DESCENT  4 | ||||
| #elif DWIN_FONT_STAT == font12x24 | ||||
|   #define STAT_FONT_WIDTH   12 | ||||
|   #define STAT_FONT_ASCENT  19 | ||||
|   #define STAT_FONT_DESCENT  5 | ||||
| #elif DWIN_FONT_STAT == font14x28 | ||||
|   #define STAT_FONT_WIDTH   14 | ||||
|   #define STAT_FONT_ASCENT  22 | ||||
|   #define STAT_FONT_DESCENT  6 | ||||
| #elif DWIN_FONT_STAT == font16x32 | ||||
|   #define STAT_FONT_WIDTH   16 | ||||
|   #define STAT_FONT_ASCENT  26 | ||||
|   #define STAT_FONT_DESCENT  6 | ||||
| #elif DWIN_FONT_STAT == font20x40 | ||||
|   #define STAT_FONT_WIDTH   20 | ||||
|   #define STAT_FONT_ASCENT  32 | ||||
|   #define STAT_FONT_DESCENT  8 | ||||
| #elif DWIN_FONT_STAT == font24x48 | ||||
|   #define STAT_FONT_WIDTH   24 | ||||
|   #define STAT_FONT_ASCENT  38 | ||||
|   #define STAT_FONT_DESCENT 10 | ||||
| #elif DWIN_FONT_STAT == font28x56 | ||||
|   #define STAT_FONT_WIDTH   28 | ||||
|   #define STAT_FONT_ASCENT  44 | ||||
|   #define STAT_FONT_DESCENT 12 | ||||
| #elif DWIN_FONT_STAT == font32x64 | ||||
|   #define STAT_FONT_WIDTH   32 | ||||
|   #define STAT_FONT_ASCENT  50 | ||||
|   #define STAT_FONT_DESCENT 14 | ||||
| #endif | ||||
| #define STAT_FONT_HEIGHT (STAT_FONT_ASCENT + STAT_FONT_DESCENT) | ||||
							
								
								
									
										595
									
								
								Marlin/src/lcd/e3v2/marlinui/ui_common.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										595
									
								
								Marlin/src/lcd/e3v2/marlinui/ui_common.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,595 @@ | ||||
| /** | ||||
|  * Marlin 3D Printer Firmware | ||||
|  * Copyright (c) 2021 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] | ||||
|  * | ||||
|  * Based on Sprinter and grbl. | ||||
|  * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm | ||||
|  * | ||||
|  * 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. | ||||
|  * | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with this program.  If not, see <http://www.gnu.org/licenses/>. | ||||
|  * | ||||
|  */ | ||||
|  | ||||
| #include "../../../inc/MarlinConfigPre.h" | ||||
|  | ||||
| #if IS_DWIN_MARLINUI | ||||
|  | ||||
| #include "marlinui_dwin.h" | ||||
| #include "dwin_lcd.h" | ||||
| #include "dwin_string.h" | ||||
|  | ||||
| //#include "../../lcdprint.h" | ||||
| #include "lcdprint_dwin.h" | ||||
| #include "../../fontutils.h" | ||||
| #include "../../../libs/numtostr.h" | ||||
| #include "../../marlinui.h" | ||||
|  | ||||
| #include "../../../sd/cardreader.h" | ||||
| #include "../../../module/motion.h" | ||||
| #include "../../../module/temperature.h" | ||||
| #include "../../../module/printcounter.h" | ||||
|  | ||||
| #if ENABLED(SDSUPPORT) | ||||
|   #include "../../../libs/duration_t.h" | ||||
| #endif | ||||
|  | ||||
| #if ENABLED(AUTO_BED_LEVELING_UBL) | ||||
|   #include "../../../feature/bedlevel/bedlevel.h" | ||||
| #endif | ||||
|  | ||||
| // DWIN printing specifies the font on each string operation | ||||
| // but we'll make the font modal for Marlin | ||||
| dwin_font_t dwin_font = { font8x16, 8, 16, Color_White, Color_Bg_Black, true }; | ||||
| void MarlinUI::set_font(const uint8_t font_nr) { | ||||
|   if (font_nr != dwin_font.index) { | ||||
|     dwin_font.index = font_nr; | ||||
|     uint8_t w, h; | ||||
|     switch (font_nr) { | ||||
|       default: | ||||
|       case font6x12:  w =  6; h = 12; break; | ||||
|       case font8x16:  w =  8; h = 16; break; | ||||
|       case font10x20: w = 10; h = 20; break; | ||||
|       case font12x24: w = 12; h = 24; break; | ||||
|       case font14x28: w = 14; h = 28; break; | ||||
|       case font16x32: w = 16; h = 32; break; | ||||
|       case font20x40: w = 20; h = 40; break; | ||||
|       case font24x48: w = 24; h = 48; break; | ||||
|       case font28x56: w = 28; h = 56; break; | ||||
|       case font32x64: w = 32; h = 64; break; | ||||
|     } | ||||
|     dwin_font.width = w; | ||||
|     dwin_font.height = h; | ||||
|     // TODO: Array with dimensions, auto fit menu items, | ||||
|     // update char width / height of the screen based on | ||||
|     // new (fixed-width) font size. | ||||
|   } | ||||
| } | ||||
|  | ||||
| // This display is always detected | ||||
| bool MarlinUI::detected() { return true; } | ||||
|  | ||||
| // Initialize or re-initialize the LCD | ||||
| void MarlinUI::init_lcd() { | ||||
|   DWIN_Startup(); | ||||
|  | ||||
|   // Load the assets JPG (currently just the status screen 'icon') | ||||
|   DWIN_JPG_CacheToN(1, DWIN_MarlinUI_Assets); | ||||
| } | ||||
|  | ||||
| // This LCD should clear where it will draw anew | ||||
| void MarlinUI::clear_lcd() { | ||||
|   DWIN_ICON_AnimationControl(0x0000); // disable all icon animations | ||||
|   DWIN_Frame_Clear(Color_Bg_Black); | ||||
|   DWIN_UpdateLCD(); | ||||
|  | ||||
|   did_first_redraw = false; | ||||
| } | ||||
|  | ||||
| #if ENABLED(SHOW_BOOTSCREEN) | ||||
|  | ||||
|   void MarlinUI::show_bootscreen() { | ||||
|     clear_lcd(); | ||||
|     dwin_string.set(F(SHORT_BUILD_VERSION)); | ||||
|  | ||||
|     #if ENABLED(DWIN_MARLINUI_PORTRAIT) | ||||
|       #define LOGO_CENTER ((LCD_PIXEL_WIDTH) / 2) | ||||
|       #define INFO_CENTER LOGO_CENTER | ||||
|       #define VERSION_Y   330 | ||||
|       DWIN_ICON_Show(BOOT_ICON, ICON_MarlinBoot, LOGO_CENTER - 266 / 2,  15); | ||||
|       DWIN_ICON_Show(BOOT_ICON, ICON_OpenSource, LOGO_CENTER - 174 / 2, 280); | ||||
|       DWIN_ICON_Show(BOOT_ICON, ICON_GitHubURL,  LOGO_CENTER - 180 / 2, 420); | ||||
|       DWIN_ICON_Show(BOOT_ICON, ICON_MarlinURL,  LOGO_CENTER - 100 / 2, 440); | ||||
|       DWIN_ICON_Show(BOOT_ICON, ICON_Copyright,  LOGO_CENTER - 126 / 2, 460); | ||||
|     #else | ||||
|       #define LOGO_CENTER (280 / 2) | ||||
|       #define INFO_CENTER ((LCD_PIXEL_WIDTH) - 200 / 2) | ||||
|       #define VERSION_Y   84 | ||||
|       DWIN_ICON_Show(BOOT_ICON, ICON_MarlinBoot, LOGO_CENTER - 266 / 2,  15); | ||||
|       DWIN_ICON_Show(BOOT_ICON, ICON_OpenSource, INFO_CENTER - 174 / 2,  60); | ||||
|       DWIN_ICON_Show(BOOT_ICON, ICON_GitHubURL,  INFO_CENTER - 180 / 2, 130); | ||||
|       DWIN_ICON_Show(BOOT_ICON, ICON_MarlinURL,  INFO_CENTER - 100 / 2, 152); | ||||
|       DWIN_ICON_Show(BOOT_ICON, ICON_Copyright,  INFO_CENTER - 126 / 2, 200); | ||||
|     #endif | ||||
|  | ||||
|     DWIN_Draw_String(false, font10x20, Color_Yellow, Color_Bg_Black, INFO_CENTER - (dwin_string.length() * 10) / 2, VERSION_Y, S(dwin_string.string())); | ||||
|     DWIN_UpdateLCD(); | ||||
|   } | ||||
|  | ||||
|   void MarlinUI::bootscreen_completion(const millis_t sofar) { | ||||
|     if ((BOOTSCREEN_TIMEOUT) > sofar) safe_delay((BOOTSCREEN_TIMEOUT) - sofar); | ||||
|     clear_lcd(); | ||||
|   } | ||||
|  | ||||
| #endif | ||||
|  | ||||
| // The kill screen is displayed for unrecoverable conditions | ||||
| void MarlinUI::draw_kill_screen() { | ||||
|   set_font(DWIN_FONT_ALERT); | ||||
|   DWIN_Frame_Clear(Color_Bg_Black); | ||||
|   dwin_font.fg = Color_Error_Red; | ||||
|   dwin_font.solid = false; | ||||
|   DWIN_Draw_Rectangle(1, Color_Bg_Window, 20, 20, LCD_PIXEL_WIDTH - 20, LCD_PIXEL_HEIGHT - 20); | ||||
|   // make the frame a few pixels thick | ||||
|   DWIN_Draw_Rectangle(0, Color_Yellow, 20, 20, LCD_PIXEL_WIDTH - 20, LCD_PIXEL_HEIGHT - 20); | ||||
|   DWIN_Draw_Rectangle(0, Color_Yellow, 21, 21, LCD_PIXEL_WIDTH - 21, LCD_PIXEL_HEIGHT - 21); | ||||
|   DWIN_Draw_Rectangle(0, Color_Yellow, 22, 22, LCD_PIXEL_WIDTH - 22, LCD_PIXEL_HEIGHT - 22); | ||||
|  | ||||
|   uint8_t cx = (LCD_PIXEL_WIDTH / dwin_font.width / 2), | ||||
|           cy = (LCD_PIXEL_HEIGHT / dwin_font.height / 2); | ||||
|  | ||||
|   #if ENABLED(DWIN_MARLINUI_LANDSCAPE) | ||||
|     cx += (96 / 2 / dwin_font.width); | ||||
|     DWIN_ICON_Show(ICON, ICON_Halted, 40, (LCD_PIXEL_HEIGHT - 96) / 2); | ||||
|   #else | ||||
|     DWIN_ICON_Show(ICON, ICON_Halted, (LCD_PIXEL_WIDTH - 96) / 2, 40); | ||||
|   #endif | ||||
|  | ||||
|   uint8_t slen = utf8_strlen(status_message); | ||||
|   lcd_moveto(cx - (slen / 2), cy - 1); | ||||
|   lcd_put_u8str(status_message); | ||||
|  | ||||
|   slen = utf8_strlen(S(GET_TEXT_F(MSG_HALTED))); | ||||
|   lcd_moveto(cx - (slen / 2), cy); | ||||
|   lcd_put_u8str_P((const char*)GET_TEXT_F(MSG_HALTED)); | ||||
|  | ||||
|   slen = utf8_strlen(S(GET_TEXT_F(MSG_HALTED))); | ||||
|   lcd_moveto(cx - (slen / 2), cy + 1); | ||||
|   lcd_put_u8str_P((const char*)GET_TEXT_F(MSG_HALTED)); | ||||
| } | ||||
|  | ||||
| // | ||||
| // Status Message | ||||
| // | ||||
| void MarlinUI::draw_status_message(const bool blink) { | ||||
|   set_font(DWIN_FONT_STAT); | ||||
|   dwin_font.solid = true; | ||||
|   dwin_font.fg = Color_White; | ||||
|   dwin_font.bg = Color_Bg_Black; | ||||
|   lcd_moveto_xy(0, LCD_PIXEL_HEIGHT - (STAT_FONT_HEIGHT) - 1); | ||||
|  | ||||
|   constexpr uint8_t max_status_chars = (LCD_PIXEL_WIDTH) / (STAT_FONT_WIDTH); | ||||
|  | ||||
|   auto status_changed = []{ | ||||
|     static uint16_t old_hash = 0x0000; | ||||
|     uint16_t hash = 0x0000; | ||||
|     for (uint8_t i = 0; i < MAX_MESSAGE_LENGTH; i++) { | ||||
|       const char c = ui.status_message[i]; | ||||
|       if (!c) break; | ||||
|       hash = ((hash << 1) | (hash >> 15)) ^ c; | ||||
|     } | ||||
|     const bool hash_changed = hash != old_hash; | ||||
|     old_hash = hash; | ||||
|     return hash_changed || !ui.did_first_redraw; | ||||
|   }; | ||||
|  | ||||
|   #if ENABLED(STATUS_MESSAGE_SCROLLING) | ||||
|     static bool last_blink = false; | ||||
|  | ||||
|     // Get the UTF8 character count of the string | ||||
|     uint8_t slen = utf8_strlen(status_message); | ||||
|  | ||||
|     // If the string fits into the LCD, just print it and do not scroll it | ||||
|     if (slen <= max_status_chars) { | ||||
|  | ||||
|       if (status_changed()) { | ||||
|  | ||||
|         // The string isn't scrolling and may not fill the screen | ||||
|         lcd_put_u8str(status_message); | ||||
|  | ||||
|         // Fill the rest with spaces | ||||
|         while (slen < max_status_chars) { lcd_put_wchar(' '); ++slen; } | ||||
|       } | ||||
|     } | ||||
|     else { | ||||
|       // String is larger than the available line space | ||||
|  | ||||
|       // Get a pointer to the next valid UTF8 character | ||||
|       // and the string remaining length | ||||
|       uint8_t rlen; | ||||
|       const char *stat = status_and_len(rlen); | ||||
|       lcd_put_u8str_max(stat, max_status_chars); | ||||
|  | ||||
|       // If the string doesn't completely fill the line... | ||||
|       if (rlen < max_status_chars) { | ||||
|         lcd_put_wchar('.');                   // Always at 1+ spaces left, draw a dot | ||||
|         uint8_t chars = max_status_chars - rlen;  // Amount of space left in characters | ||||
|         if (--chars) {                        // Draw a second dot if there's space | ||||
|           lcd_put_wchar('.'); | ||||
|           if (--chars) | ||||
|             lcd_put_u8str_max(status_message, chars); // Print a second copy of the message | ||||
|         } | ||||
|       } | ||||
|  | ||||
|       if (last_blink != blink) { | ||||
|         last_blink = blink; | ||||
|         advance_status_scroll(); | ||||
|       } | ||||
|     } | ||||
|  | ||||
|   #else | ||||
|  | ||||
|     UNUSED(blink); | ||||
|  | ||||
|     if (status_changed()) { | ||||
|       // Get the UTF8 character count of the string | ||||
|       uint8_t slen = utf8_strlen(status_message); | ||||
|  | ||||
|       // Just print the string to the LCD | ||||
|       lcd_put_u8str_max(status_message, max_status_chars); | ||||
|  | ||||
|       // Fill the rest with spaces if there are missing spaces | ||||
|       while (slen < max_status_chars) { lcd_put_wchar(' '); ++slen; } | ||||
|     } | ||||
|  | ||||
|   #endif | ||||
| } | ||||
|  | ||||
| #if HAS_LCD_MENU | ||||
|  | ||||
|   #include "../../menu/menu.h" | ||||
|  | ||||
|   #if ENABLED(ADVANCED_PAUSE_FEATURE) | ||||
|  | ||||
|     void MarlinUI::draw_hotend_status(const uint8_t row, const uint8_t extruder) { | ||||
|  | ||||
|       dwin_font.solid = false; | ||||
|       dwin_font.fg = Color_White; | ||||
|       dwin_string.set("E"); | ||||
|       dwin_string.add('1' + extruder); | ||||
|       dwin_string.add(' '); | ||||
|       dwin_string.add(i16tostr3rj(thermalManager.degHotend(extruder))); | ||||
|       dwin_string.add('/'); | ||||
|       if (get_blink() || !thermalManager.heater_idle[thermalManager.idle_index_for_id(extruder)].timed_out) | ||||
|         dwin_string.add(i16tostr3rj(thermalManager.degTargetHotend(extruder))); | ||||
|       else | ||||
|         dwin_string.add(PSTR("    ")); | ||||
|  | ||||
|       lcd_moveto(LCD_WIDTH - dwin_string.length(), row); | ||||
|       lcd_put_dwin_string(); | ||||
|     } | ||||
|  | ||||
|   #endif | ||||
|  | ||||
|   // Set the colors for a menu item based on whether it is selected | ||||
|   static bool mark_as_selected(const uint8_t row, const bool sel, const bool is_static=false) { | ||||
|     const dwin_coord_t y = row * (MENU_LINE_HEIGHT) + 1; | ||||
|     if (y >= LCD_PIXEL_HEIGHT) return false; | ||||
|  | ||||
|     if (is_static && sel) | ||||
|       DWIN_Draw_Box(1, Color_Bg_Heading, 0, y, LCD_PIXEL_WIDTH, MENU_LINE_HEIGHT - 1); | ||||
|     else { | ||||
|       #if ENABLED(MENU_HOLLOW_FRAME) | ||||
|                  DWIN_Draw_Box(1, Color_Bg_Black, 0, y, LCD_PIXEL_WIDTH, MENU_LINE_HEIGHT - 1); | ||||
|         if (sel) DWIN_Draw_Box(0, Select_Color,   0, y, LCD_PIXEL_WIDTH, MENU_LINE_HEIGHT - 1); | ||||
|       #else | ||||
|         DWIN_Draw_Box(1, sel ? Select_Color : Color_Bg_Black, 0, y, LCD_PIXEL_WIDTH, MENU_LINE_HEIGHT - 1); | ||||
|       #endif | ||||
|     } | ||||
|  | ||||
|     return true; | ||||
|   } | ||||
|  | ||||
|   // Draw a static line of text in the same idiom as a menu item | ||||
|  | ||||
|   void MenuItem_static::draw(const uint8_t row, PGM_P const pstr, const uint8_t style/*=SS_DEFAULT*/, const char * const vstr/*=nullptr*/) { | ||||
|     // Call mark_as_selected to draw a bigger selection box | ||||
|     // and draw the text without a background | ||||
|     if (mark_as_selected(row, (bool)(style & SS_INVERT), true)) { | ||||
|       ui.set_font(DWIN_FONT_MENU); | ||||
|       dwin_font.solid = false; | ||||
|       dwin_font.fg = Color_White; | ||||
|  | ||||
|       dwin_string.set(); | ||||
|       const int8_t plen = pstr ? utf8_strlen_P(pstr) : 0, | ||||
|                    vlen = vstr ? utf8_strlen(vstr) : 0; | ||||
|       if (style & SS_CENTER) { | ||||
|         int8_t pad = (LCD_WIDTH - 1 - plen - vlen) / 2; | ||||
|         while (--pad) dwin_string.add(' '); | ||||
|       } | ||||
|  | ||||
|       if (plen) dwin_string.add((uint8_t*)pstr, itemIndex, (uint8_t*)itemString); | ||||
|       if (vlen) dwin_string.add((uint8_t*)vstr); | ||||
|       if (style & SS_CENTER) { | ||||
|         int8_t pad = (LCD_WIDTH - 1 - plen - vlen) / 2; | ||||
|         while (--pad) dwin_string.add(' '); | ||||
|       } | ||||
|  | ||||
|       lcd_moveto(1, row); | ||||
|       lcd_put_dwin_string(); | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   // Draw a generic menu item | ||||
|   void MenuItemBase::_draw(const bool sel, const uint8_t row, PGM_P const pstr, const char, const char post_char) { | ||||
|     if (mark_as_selected(row, sel)) { | ||||
|       ui.set_font(DWIN_FONT_MENU); | ||||
|       dwin_font.solid = false; | ||||
|       dwin_font.fg = Color_White; | ||||
|  | ||||
|       dwin_string.set(pstr, itemIndex, itemString); | ||||
|  | ||||
|       pixel_len_t n = LCD_WIDTH - 1 - dwin_string.length(); | ||||
|       while (--n > 1) dwin_string.add(' '); | ||||
|  | ||||
|       dwin_string.add(post_char); | ||||
|  | ||||
|       lcd_moveto(1, row); | ||||
|       lcd_put_dwin_string(); | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   // | ||||
|   // Draw a menu item with an editable value | ||||
|   // | ||||
|   void MenuEditItemBase::draw(const bool sel, const uint8_t row, PGM_P const pstr, const char* const data, const bool pgm) { | ||||
|     if (mark_as_selected(row, sel)) { | ||||
|       ui.set_font(DWIN_FONT_MENU); | ||||
|       dwin_font.solid = false; | ||||
|       dwin_font.fg = Color_White; | ||||
|  | ||||
|       const uint8_t vallen = (pgm ? utf8_strlen_P(data) : utf8_strlen(S(data))); | ||||
|  | ||||
|       dwin_string.set(pstr, itemIndex, itemString); | ||||
|       if (vallen) dwin_string.add(':'); | ||||
|  | ||||
|       lcd_moveto(1, row); | ||||
|       lcd_put_dwin_string(); | ||||
|  | ||||
|       if (vallen) { | ||||
|         dwin_font.fg = Color_Yellow; | ||||
|         dwin_string.set(data); | ||||
|         lcd_moveto(LCD_WIDTH - vallen - 1, row); | ||||
|         lcd_put_dwin_string(); | ||||
|       } | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   // | ||||
|   // Draw an edit screen with label and current value | ||||
|   // | ||||
|   void MenuEditItemBase::draw_edit_screen(PGM_P const pstr, const char* const value/*=nullptr*/) { | ||||
|     ui.encoder_direction_normal(); | ||||
|  | ||||
|     const dwin_coord_t labellen = utf8_strlen_P(pstr), vallen = utf8_strlen(value); | ||||
|  | ||||
|     dwin_string.set(); | ||||
|     dwin_string.add((uint8_t*)pstr, itemIndex); | ||||
|     if (vallen) dwin_string.add(':');  // If a value is included, add a colon | ||||
|  | ||||
|     // Assume the label is alpha-numeric (with a descender) | ||||
|     const uint16_t row = (LCD_HEIGHT / 2) - 1; | ||||
|  | ||||
|     dwin_font.fg = Color_White; | ||||
|     dwin_font.solid = true; | ||||
|     lcd_moveto((LCD_WIDTH - labellen + !!vallen) / 2, row); | ||||
|     lcd_put_dwin_string(); | ||||
|  | ||||
|     // If a value is included, print the value in larger text below the label | ||||
|     if (vallen) { | ||||
|       dwin_string.set(); | ||||
|       dwin_string.add(value); | ||||
|  | ||||
|       const dwin_coord_t by = (row * MENU_LINE_HEIGHT) + MENU_FONT_HEIGHT + EXTRA_ROW_HEIGHT / 2; | ||||
|       DWIN_Draw_String(true, font16x32, Color_Yellow, Color_Bg_Black, (LCD_PIXEL_WIDTH - vallen * 16) / 2, by, S(dwin_string.string())); | ||||
|  | ||||
|       extern screenFunc_t _manual_move_func_ptr; | ||||
|       if (ui.currentScreen != _manual_move_func_ptr && !ui.external_control) { | ||||
|  | ||||
|         const dwin_coord_t slider_length = LCD_PIXEL_WIDTH - TERN(DWIN_MARLINUI_LANDSCAPE, 120, 20), | ||||
|                            slider_height = 16, | ||||
|                            slider_x = (LCD_PIXEL_WIDTH - slider_length) / 2, | ||||
|                            slider_y = by + 32 + 4, | ||||
|                            amount = ui.encoderPosition * slider_length / maxEditValue; | ||||
|  | ||||
|         DWIN_Draw_Rectangle(1, Color_Bg_Window, slider_x - 1, slider_y - 1, slider_x - 1 + slider_length + 2 - 1, slider_y - 1 + slider_height + 2 - 1); | ||||
|         if (amount > 0) | ||||
|           DWIN_Draw_Box(1, BarFill_Color, slider_x, slider_y, amount, slider_height); | ||||
|         if (amount < slider_length) | ||||
|           DWIN_Draw_Box(1, Color_Bg_Black, slider_x + amount, slider_y, slider_length - amount, slider_height); | ||||
|       } | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   inline void draw_boxed_string(const bool yesopt, PGM_P const pstr, const bool inv) { | ||||
|     const uint8_t len = utf8_strlen_P(pstr), | ||||
|                   mar = TERN(DWIN_MARLINUI_PORTRAIT, 1, 4), | ||||
|                   col = yesopt ? LCD_WIDTH - mar - len : mar, | ||||
|                   row = (LCD_HEIGHT >= 8 ? LCD_HEIGHT / 2 + 3 : LCD_HEIGHT - 1); | ||||
|     lcd_moveto(col, row); | ||||
|     DWIN_Draw_Box(1, inv ? Select_Color : Color_Bg_Black, cursor.x - dwin_font.width, cursor.y + 1, dwin_font.width * (len + 2), dwin_font.height + 2); | ||||
|     lcd_put_u8str_P(col, row, pstr); | ||||
|   } | ||||
|  | ||||
|   void MenuItem_confirm::draw_select_screen( | ||||
|     PGM_P const yes, PGM_P const no, const bool yesno, | ||||
|     PGM_P const pref, const char * const string/*=nullptr*/, PGM_P const suff/*=nullptr*/ | ||||
|   ) { | ||||
|     ui.set_font(DWIN_FONT_MENU); | ||||
|     dwin_font.solid = false; | ||||
|     dwin_font.fg = Color_White; | ||||
|     ui.draw_select_screen_prompt(pref, string, suff); | ||||
|     draw_boxed_string(false, no, !yesno); | ||||
|     draw_boxed_string(true, yes,  yesno); | ||||
|   } | ||||
|  | ||||
|   #if ENABLED(SDSUPPORT) | ||||
|  | ||||
|     void MenuItem_sdbase::draw(const bool sel, const uint8_t row, PGM_P const, CardReader &theCard, const bool isDir) { | ||||
|       if (mark_as_selected(row, sel)) { | ||||
|         dwin_string.set(); | ||||
|  | ||||
|         uint8_t maxlen = LCD_WIDTH - 1; | ||||
|         if (isDir) { | ||||
|           dwin_string.add(LCD_STR_FOLDER " "); | ||||
|           maxlen -= 2; | ||||
|         } | ||||
|  | ||||
|         dwin_string.add((uint8_t*)ui.scrolled_filename(theCard, maxlen, row, sel), maxlen); | ||||
|         uint8_t n = maxlen - dwin_string.length(); | ||||
|         while (n > 0) { dwin_string.add(' '); --n; } | ||||
|         lcd_moveto(1, row); | ||||
|         lcd_put_dwin_string(); | ||||
|       } | ||||
|     } | ||||
|  | ||||
|   #endif // SDSUPPORT | ||||
|  | ||||
|   #if ENABLED(AUTO_BED_LEVELING_UBL) | ||||
|  | ||||
|     /** | ||||
|      * UBL LCD "radar" map data | ||||
|      */ | ||||
|     #define MAP_UPPER_LEFT_CORNER_X   5  // These probably should be moved to the .h file  But for now, | ||||
|     #define MAP_UPPER_LEFT_CORNER_Y   5  // it is easier to play with things having them here | ||||
|     #define MAP_MAX_PIXELS_X        262  // 272 - 10 | ||||
|     #define MAP_MAX_PIXELS_Y        262 | ||||
|  | ||||
|     void MarlinUI::ubl_plot(const uint8_t x_plot, const uint8_t y_plot) { | ||||
|       // Scale the box pixels appropriately | ||||
|       dwin_coord_t x_map_pixels = ((MAP_MAX_PIXELS_X - 4) / (GRID_MAX_POINTS_X)) * (GRID_MAX_POINTS_X), | ||||
|                    y_map_pixels = ((MAP_MAX_PIXELS_Y - 4) / (GRID_MAX_POINTS_Y)) * (GRID_MAX_POINTS_Y), | ||||
|  | ||||
|               pixels_per_x_mesh_pnt = x_map_pixels / (GRID_MAX_POINTS_X), | ||||
|               pixels_per_y_mesh_pnt = y_map_pixels / (GRID_MAX_POINTS_Y), | ||||
|  | ||||
|               x_offset = MAP_UPPER_LEFT_CORNER_X + 1 + (MAP_MAX_PIXELS_X - x_map_pixels - 2) / 2, | ||||
|               y_offset = MAP_UPPER_LEFT_CORNER_Y + 1 + (MAP_MAX_PIXELS_Y - y_map_pixels - 2) / 2; | ||||
|  | ||||
|       // Clear the Mesh Map | ||||
|  | ||||
|       // First draw the bigger box in White so we have a border around the mesh map box | ||||
|       DWIN_Draw_Rectangle(1, Color_White, x_offset - 2, y_offset - 2, x_offset + 2 + x_map_pixels, y_offset + 2 + y_map_pixels); | ||||
|       // Now actually clear the mesh map box | ||||
|       DWIN_Draw_Rectangle(1, Color_Bg_Black, x_offset, y_offset, x_offset + x_map_pixels, y_offset + y_map_pixels); | ||||
|  | ||||
|       // Fill in the Specified Mesh Point | ||||
|  | ||||
|       const uint8_t y_plot_inv = (GRID_MAX_POINTS_Y - 1) - y_plot;  // The origin is typically in the lower right corner.  We need to | ||||
|                                                                     // invert the Y to get it to plot in the right location. | ||||
|  | ||||
|       const dwin_coord_t by = y_offset + y_plot_inv * pixels_per_y_mesh_pnt; | ||||
|       DWIN_Draw_Rectangle(1, Select_Color, | ||||
|         x_offset + (x_plot * pixels_per_x_mesh_pnt), by, | ||||
|         x_offset + (x_plot * pixels_per_x_mesh_pnt) + pixels_per_x_mesh_pnt, by + pixels_per_y_mesh_pnt | ||||
|       ); | ||||
|  | ||||
|       // Display Mesh Point Locations | ||||
|       const dwin_coord_t sx = x_offset + pixels_per_x_mesh_pnt / 2; | ||||
|             dwin_coord_t  y = y_offset + pixels_per_y_mesh_pnt / 2; | ||||
|       for (uint8_t j = 0; j < GRID_MAX_POINTS_Y; j++, y += pixels_per_y_mesh_pnt) | ||||
|         for (uint8_t i = 0, x = sx; i < GRID_MAX_POINTS_X; i++, x += pixels_per_x_mesh_pnt) | ||||
|           DWIN_Draw_Point(Color_White, 1, 1, x, y); | ||||
|  | ||||
|       // Put Relevant Text on Display | ||||
|  | ||||
|       // Show X and Y positions at top of screen | ||||
|       dwin_font.fg = Color_White; | ||||
|       dwin_font.solid = true; | ||||
|       const xy_pos_t pos = { ubl.mesh_index_to_xpos(x_plot), ubl.mesh_index_to_ypos(y_plot) }, | ||||
|                      lpos = pos.asLogical(); | ||||
|  | ||||
|       lcd_moveto( | ||||
|         TERN(DWIN_MARLINUI_LANDSCAPE, ((x_offset + x_map_pixels) / MENU_FONT_WIDTH) + 2, 1), | ||||
|         TERN(DWIN_MARLINUI_LANDSCAPE, 1, ((y_offset + y_map_pixels) / MENU_LINE_HEIGHT) + 1) | ||||
|       ); | ||||
|       lcd_put_u8str_P(X_LBL); | ||||
|       lcd_put_u8str(ftostr52(lpos.x)); | ||||
|       lcd_moveto( | ||||
|         TERN(DWIN_MARLINUI_LANDSCAPE, ((x_offset + x_map_pixels) / MENU_FONT_WIDTH) + 2, 1), | ||||
|         TERN(DWIN_MARLINUI_LANDSCAPE, 3, ((y_offset + y_map_pixels) / MENU_LINE_HEIGHT) + 2) | ||||
|       ); | ||||
|       lcd_put_u8str_P(Y_LBL); | ||||
|       lcd_put_u8str(ftostr52(lpos.y)); | ||||
|  | ||||
|       // Print plot position | ||||
|       dwin_string.set("("); | ||||
|       dwin_string.add(i8tostr3rj(x_plot)); | ||||
|       dwin_string.add(","); | ||||
|       dwin_string.add(i8tostr3rj(y_plot)); | ||||
|       dwin_string.add(")"); | ||||
|       lcd_moveto( | ||||
|         TERN(DWIN_MARLINUI_LANDSCAPE, ((x_offset + x_map_pixels) / MENU_FONT_WIDTH) + 2, LCD_WIDTH - dwin_string.length()), | ||||
|         TERN(DWIN_MARLINUI_LANDSCAPE, LCD_HEIGHT - 2, ((y_offset + y_map_pixels) / MENU_LINE_HEIGHT) + 1) | ||||
|       ); | ||||
|       lcd_put_dwin_string(); | ||||
|  | ||||
|       // Show the location value | ||||
|       dwin_string.set(Z_LBL); | ||||
|       if (!isnan(ubl.z_values[x_plot][y_plot])) | ||||
|         dwin_string.add(ftostr43sign(ubl.z_values[x_plot][y_plot])); | ||||
|       else | ||||
|         dwin_string.add(PSTR(" -----")); | ||||
|       lcd_moveto( | ||||
|         TERN(DWIN_MARLINUI_LANDSCAPE, ((x_offset + x_map_pixels) / MENU_FONT_WIDTH) + 2, LCD_WIDTH - dwin_string.length()), | ||||
|         TERN(DWIN_MARLINUI_LANDSCAPE, LCD_HEIGHT - 1, ((y_offset + y_map_pixels) / MENU_LINE_HEIGHT) + 2) | ||||
|       ); | ||||
|       lcd_put_dwin_string(); | ||||
|     } | ||||
|  | ||||
|   #endif // AUTO_BED_LEVELING_UBL | ||||
|  | ||||
|   #if ANY(BABYSTEP_ZPROBE_GFX_OVERLAY, MESH_EDIT_GFX_OVERLAY, BABYSTEP_GFX_OVERLAY) | ||||
|  | ||||
|     void _lcd_zoffset_overlay_gfx(const float zvalue) { | ||||
|       // Determine whether the user is raising or lowering the nozzle. | ||||
|       static int8_t dir; | ||||
|       static float old_zvalue; | ||||
|       if (zvalue != old_zvalue) { | ||||
|         dir = zvalue ? zvalue < old_zvalue ? -1 : 1 : 0; | ||||
|         old_zvalue = zvalue; | ||||
|       } | ||||
|  | ||||
|       const int rot_up = TERN(OVERLAY_GFX_REVERSE, ICON_RotateCCW, ICON_RotateCW), | ||||
|                 rot_down = TERN(OVERLAY_GFX_REVERSE, ICON_RotateCW, ICON_RotateCCW); | ||||
|  | ||||
|       const int nozzle = (LCD_PIXEL_WIDTH / 2) - 20; | ||||
|  | ||||
|       // Draw a representation of the nozzle | ||||
|       DWIN_Draw_Box(1, Color_Bg_Black, nozzle + 3, 8, 48, 52); // 'clear' the area where the nozzle is drawn in case it was moved up/down | ||||
|       DWIN_ICON_Show(ICON, ICON_HotendOff, nozzle + 3, 10 - dir); | ||||
|       DWIN_ICON_Show(ICON, ICON_BedLine, nozzle, 10 + 36); | ||||
|  | ||||
|       // Draw cw/ccw indicator and up/down arrows | ||||
|       const int arrow_y = LCD_PIXEL_HEIGHT / 2 - 24; | ||||
|       DWIN_ICON_Show(ICON, ICON_DownArrow, 0, arrow_y - dir); | ||||
|       DWIN_ICON_Show(ICON, rot_down, 48, arrow_y); | ||||
|  | ||||
|       DWIN_ICON_Show(ICON, ICON_UpArrow, LCD_PIXEL_WIDTH - 10 - (48*2), arrow_y - dir); | ||||
|       DWIN_ICON_Show(ICON, rot_up, LCD_PIXEL_WIDTH - 10 - 48, arrow_y); | ||||
|     } | ||||
|  | ||||
|   #endif // BABYSTEP_ZPROBE_GFX_OVERLAY || MESH_EDIT_GFX_OVERLAY | ||||
|  | ||||
| #endif // HAS_LCD_MENU | ||||
|  | ||||
| #endif // IS_DWIN_MARLINUI | ||||
							
								
								
									
										391
									
								
								Marlin/src/lcd/e3v2/marlinui/ui_status_480x272.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										391
									
								
								Marlin/src/lcd/e3v2/marlinui/ui_status_480x272.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,391 @@ | ||||
| /** | ||||
|  * Marlin 3D Printer Firmware | ||||
|  * Copyright (c) 2021 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] | ||||
|  * | ||||
|  * Based on Sprinter and grbl. | ||||
|  * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm | ||||
|  * | ||||
|  * 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. | ||||
|  * | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with this program.  If not, see <http://www.gnu.org/licenses/>. | ||||
|  * | ||||
|  */ | ||||
|  | ||||
| #include "../../../inc/MarlinConfigPre.h" | ||||
|  | ||||
| #if IS_DWIN_MARLINUI | ||||
|  | ||||
| #include "marlinui_dwin.h" | ||||
| #include "dwin_lcd.h" | ||||
| #include "dwin_string.h" | ||||
| #include "lcdprint_dwin.h" | ||||
|  | ||||
| #include "../../fontutils.h" | ||||
| #include "../../../libs/numtostr.h" | ||||
| #include "../../marlinui.h" | ||||
|  | ||||
| #include "../../../sd/cardreader.h" | ||||
| #include "../../../module/motion.h" | ||||
| #include "../../../module/temperature.h" | ||||
| #include "../../../module/printcounter.h" | ||||
|  | ||||
| #if ENABLED(SDSUPPORT) | ||||
|   #include "../../../libs/duration_t.h" | ||||
| #endif | ||||
|  | ||||
| #if ENABLED(LCD_SHOW_E_TOTAL) | ||||
|   #include "../../../MarlinCore.h" // for printingIsActive | ||||
| #endif | ||||
|  | ||||
| #define STATUS_HEATERS_X      15 | ||||
| #define STATUS_HEATERS_Y      56 | ||||
| #define STATUS_HEATERS_XSPACE 64 | ||||
| #define STATUS_FAN_WIDTH      48 | ||||
| #define STATUS_FAN_HEIGHT     48 | ||||
| #define STATUS_FAN_Y          STATUS_HEATERS_Y + 22 | ||||
| #define STATUS_CHR_WIDTH      14 | ||||
| #define STATUS_CHR_HEIGHT     28 | ||||
|  | ||||
| // | ||||
| // Before homing, blink '123' <-> '???'. | ||||
| // Homed but unknown... '123' <-> '   '. | ||||
| // Homed and known, display constantly. | ||||
| // | ||||
| FORCE_INLINE void _draw_axis_value(const AxisEnum axis, const char *value, const bool blink, const uint16_t x, const uint16_t y) { | ||||
|   uint8_t vallen = utf8_strlen(value); | ||||
|  | ||||
|   if (!ui.did_first_redraw) { | ||||
|     dwin_string.set(); | ||||
|     dwin_string.add('X' + axis); | ||||
|     DWIN_Draw_String(true, font16x32, Color_IconBlue, Color_Bg_Black, x + (vallen * 14 - 14) / 2, y + 2, S(dwin_string.string())); | ||||
|   } | ||||
|  | ||||
|   dwin_string.set(); | ||||
|   if (blink) | ||||
|     dwin_string.add(value); | ||||
|   else { | ||||
|     if (!TEST(axis_homed, axis)) | ||||
|       while (const char c = *value++) dwin_string.add(c <= '.' ? c : '?'); | ||||
|     else { | ||||
|       #if NONE(HOME_AFTER_DEACTIVATE, DISABLE_REDUCED_ACCURACY_WARNING) | ||||
|         if (!TEST(axis_trusted, axis)) | ||||
|           dwin_string.add(TERN1(DWIN_MARLINUI_PORTRAIT, axis == Z_AXIS) ? PSTR("       ") : PSTR("    ")); | ||||
|         else | ||||
|       #endif | ||||
|           dwin_string.add(value); | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   // For E_TOTAL there may be some characters to cover up | ||||
|   if (BOTH(DWIN_MARLINUI_PORTRAIT, LCD_SHOW_E_TOTAL) && axis == X_AXIS) | ||||
|     dwin_string.add("   "); | ||||
|  | ||||
|   DWIN_Draw_String(true, font14x28, Color_White, Color_Bg_Black, x, y + 32, S(dwin_string.string())); | ||||
| } | ||||
|  | ||||
| #if ENABLED(LCD_SHOW_E_TOTAL) | ||||
|  | ||||
|   FORCE_INLINE void _draw_e_value(const_float_t value, const uint16_t x, const uint16_t y) { | ||||
|     const uint8_t scale = value >= 100000.0f ? 10 : 1; // show cm after 99,999mm | ||||
|  | ||||
|     if (!ui.did_first_redraw) { | ||||
|       // Extra spaces so we don't have to clear the 'Y' label separately | ||||
|       dwin_string.set("E         "); | ||||
|       DWIN_Draw_String(true, font16x32, Color_IconBlue, Color_Bg_Black, x + (4 * 14 / 2) - 7, y + 2, S(dwin_string.string())); | ||||
|     } | ||||
|  | ||||
|     dwin_string.set(ui16tostr5rj(value / scale)); | ||||
|     DWIN_Draw_String(true, font14x28, Color_White, Color_Bg_Black, x, y + 32, S(dwin_string.string())); | ||||
|  | ||||
|     // Extra spaces so we don't have to clear out the Y value separately | ||||
|     DWIN_Draw_String(true, font14x28, Color_IconBlue, Color_Bg_Black, x + (5 * 14), y + 32, S(scale == 1 ? "mm      " : "cm      ")); | ||||
|   } | ||||
|  | ||||
| #endif | ||||
|  | ||||
| // | ||||
| // Fan Icon and Percentage | ||||
| // | ||||
| FORCE_INLINE void _draw_fan_status(const uint16_t x, const uint16_t y) { | ||||
|   const uint16_t fanx = (4 * STATUS_CHR_WIDTH - STATUS_FAN_WIDTH) / 2; | ||||
|   const uint8_t fan_pct = thermalManager.scaledFanSpeedPercent(0); | ||||
|   const bool fan_on = !!fan_pct; | ||||
|   if (fan_on) { | ||||
|     DWIN_ICON_Animation(0, fan_on, ICON, ICON_Fan0, ICON_Fan3, x + fanx, y, 25); | ||||
|     dwin_string.set(i8tostr3rj(fan_pct)); | ||||
|     dwin_string.add('%'); | ||||
|     DWIN_Draw_String(true, font14x28, Color_White, Color_Bg_Black, x, y + STATUS_FAN_HEIGHT, S(dwin_string.string())); | ||||
|   } | ||||
|   else { | ||||
|     DWIN_ICON_Show(ICON, ICON_Fan0, x + fanx, y); | ||||
|     dwin_string.set(PSTR("    ")); | ||||
|     DWIN_Draw_String(true, font14x28, Color_White, Color_Bg_Black, x, y + STATUS_FAN_HEIGHT, S(dwin_string.string())); | ||||
|   } | ||||
| } | ||||
|  | ||||
| #if HOTENDS > 2 | ||||
|   #define HOTEND_STATS 3 | ||||
| #elif HOTENDS > 1 | ||||
|   #define HOTEND_STATS 2 | ||||
| #elif HAS_HOTEND | ||||
|   #define HOTEND_STATS 1 | ||||
| #endif | ||||
|  | ||||
| /** | ||||
|  * Draw a single heater icon with current and target temperature, at the given XY | ||||
|  */ | ||||
| FORCE_INLINE void _draw_heater_status(const heater_id_t heater, const uint16_t x, const uint16_t y) { | ||||
|  | ||||
|   #if HAS_HOTEND | ||||
|     static celsius_t old_temp[HOTEND_STATS] = ARRAY_N_1(HOTEND_STATS, 500), | ||||
|                      old_target[HOTEND_STATS] = ARRAY_N_1(HOTEND_STATS, 500); | ||||
|     static bool old_on[HOTEND_STATS] = ARRAY_N_1(HOTEND_STATS, false); | ||||
|   #endif | ||||
|  | ||||
|   #if HAS_HEATED_BED | ||||
|     static celsius_t old_bed_temp = 500, old_bed_target = 500; | ||||
|     static bool old_bed_on = false; | ||||
|   #endif | ||||
|  | ||||
|   #if HAS_HOTEND && HAS_HEATED_BED | ||||
|     const bool isBed = heater < 0; | ||||
|     const float tc = (isBed ? thermalManager.degBed()       : thermalManager.degHotend(heater)), | ||||
|                 tt = (isBed ? thermalManager.degTargetBed() : thermalManager.degTargetHotend(heater)); | ||||
|     const uint8_t ta = isBed ? thermalManager.isHeatingBed() : thermalManager.isHeatingHotend(heater); | ||||
|     const bool c_draw = tc != (isBed ? old_bed_temp : old_temp[heater]), | ||||
|                t_draw = tt != (isBed ? old_bed_target : old_target[heater]), | ||||
|                i_draw = ta != (isBed ? old_bed_on : old_on[heater]); | ||||
|     if (isBed) { old_bed_temp = tc; old_bed_target = tt; old_bed_on = ta; } | ||||
|     else { old_temp[heater] = tc; old_target[heater] = tt; old_on[heater] = ta; } | ||||
|   #elif HAS_HOTEND | ||||
|     constexpr bool isBed = false; | ||||
|     const float tc = thermalManager.degHotend(heater), tt = thermalManager.degTargetHotend(heater); | ||||
|     const uint8_t ta = thermalManager.isHeatingHotend(heater); | ||||
|     const bool c_draw = tc != old_bed_temp, t_draw = tt != old_bed_target, i_draw = ta != old_bed_on; | ||||
|     old_temp[heater] = tc; old_target[heater] = tt; old_on[heater] = ta; | ||||
|   #elif HAS_HEATED_BED | ||||
|     constexpr bool isBed = true; | ||||
|     const float tc = thermalManager.degBed(), tt = thermalManager.degTargetBed(); | ||||
|     const uint8_t ta = thermalManager.isHeatingBed(); | ||||
|     const bool c_draw = tc != old_temp[heater], t_draw = tt != old_target[heater], i_draw = ta != old_on[heater]; | ||||
|     old_bed_temp = tc; old_bed_target = tt; old_bed_on = ta; | ||||
|   #endif | ||||
|  | ||||
|   if (!ui.did_first_redraw || t_draw) { | ||||
|     dwin_string.set(i16tostr3rj(tt + 0.5)); | ||||
|     dwin_string.add(LCD_STR_DEGREE); | ||||
|     DWIN_Draw_String(true, font14x28, Color_White, Color_Bg_Black, x, y, S(dwin_string.string())); | ||||
|   } | ||||
|  | ||||
|   if (!ui.did_first_redraw || i_draw) | ||||
|     DWIN_ICON_Show(ICON, (isBed ? ICON_BedOff : ICON_HotendOff) + ta, x, y + STATUS_CHR_HEIGHT + 2); | ||||
|  | ||||
|   if (!ui.did_first_redraw || c_draw) { | ||||
|     dwin_string.set(i16tostr3rj(tc + 0.5)); | ||||
|     dwin_string.add(LCD_STR_DEGREE); | ||||
|     DWIN_Draw_String(true, font14x28, Color_White, Color_Bg_Black, x, y + 70, S(dwin_string.string())); | ||||
|   } | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * Draw the current "feed rate" percentage preceded by the >> character | ||||
|  */ | ||||
| FORCE_INLINE void _draw_feedrate_status(const char *value, uint16_t x, uint16_t y) { | ||||
|   if (!ui.did_first_redraw) { | ||||
|     dwin_string.set(LCD_STR_FEEDRATE); | ||||
|     DWIN_Draw_String(true, font14x28, Color_IconBlue, Color_Bg_Black, x, y, S(dwin_string.string())); | ||||
|   } | ||||
|  | ||||
|   dwin_string.set(value); | ||||
|   dwin_string.add(PSTR("%")); | ||||
|   DWIN_Draw_String(true, font14x28, Color_White, Color_Bg_Black, x + 14, y, S(dwin_string.string())); | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * Draw the MarlinUI Status Screen for Ender 3 V2 | ||||
|  */ | ||||
| void MarlinUI::draw_status_screen() { | ||||
|   const bool blink = get_blink(); | ||||
|  | ||||
|   // Draw elements that never change | ||||
|   if (!ui.did_first_redraw) { | ||||
|     // Logo/Status Icon | ||||
|     #define STATUS_LOGO_WIDTH  128 | ||||
|     #define STATUS_LOGO_HEIGHT  40 | ||||
|     DWIN_ICON_Show(ICON, ICON_LOGO_Marlin, (LCD_PIXEL_WIDTH - (STATUS_LOGO_WIDTH)) / 2, ((STATUS_HEATERS_Y - 4) - (STATUS_LOGO_HEIGHT)) / 2); | ||||
|  | ||||
|     // Draw a frame around the x/y/z values | ||||
|     #if ENABLED(DWIN_MARLINUI_PORTRAIT) | ||||
|       DWIN_Draw_Rectangle(0, Select_Color, 0, 193, LCD_PIXEL_WIDTH, 260); | ||||
|     #else | ||||
|       //DWIN_Draw_Rectangle(0, Select_Color, LCD_PIXEL_WIDTH - 106, 50, LCD_PIXEL_WIDTH - 1, 230); | ||||
|     #endif | ||||
|   } | ||||
|  | ||||
|   uint16_t hx = STATUS_HEATERS_X; | ||||
|   #if HAS_HOTEND | ||||
|     _draw_heater_status(H_E0, hx, STATUS_HEATERS_Y); | ||||
|     hx += STATUS_HEATERS_XSPACE; | ||||
|   #endif | ||||
|   #if HAS_MULTI_HOTEND | ||||
|     _draw_heater_status(H_E1, hx, STATUS_HEATERS_Y); | ||||
|     hx += STATUS_HEATERS_XSPACE; | ||||
|   #endif | ||||
|   #if HAS_HEATED_BED | ||||
|     _draw_heater_status(H_BED, hx, STATUS_HEATERS_Y); | ||||
|   #endif | ||||
|  | ||||
|   #if HAS_FAN | ||||
|     // Fan display, pinned to the right side | ||||
|     #if ENABLED(DWIN_MARLINUI_PORTRAIT) | ||||
|       _draw_fan_status(LCD_PIXEL_WIDTH - STATUS_CHR_WIDTH * 4, STATUS_FAN_Y); | ||||
|     #else | ||||
|       _draw_fan_status(212, STATUS_FAN_Y); | ||||
|     #endif | ||||
|   #endif | ||||
|  | ||||
|   // Axis values | ||||
|   const xyz_pos_t lpos = current_position.asLogical(); | ||||
|   const bool show_e_total = TERN0(LCD_SHOW_E_TOTAL, printingIsActive()); UNUSED(show_e_total); | ||||
|   #if ENABLED(DWIN_MARLINUI_PORTRAIT) | ||||
|     constexpr int16_t cpy = 195; | ||||
|     if (show_e_total) { | ||||
|       TERN_(LCD_SHOW_E_TOTAL, _draw_e_value(e_move_accumulator, 6, cpy)); | ||||
|     } | ||||
|     else { | ||||
|                         _draw_axis_value(X_AXIS, ftostr4sign(lpos.x), blink,  6, cpy); | ||||
|       TERN_(HAS_Y_AXIS, _draw_axis_value(Y_AXIS, ftostr4sign(lpos.y), blink, 95, cpy)); | ||||
|     } | ||||
|     TERN_(HAS_Z_AXIS, _draw_axis_value(Z_AXIS, ftostr52sp(lpos.z), blink, 165, cpy)); | ||||
|   #else | ||||
|     constexpr int16_t cpx = LCD_PIXEL_WIDTH - 104; | ||||
|                       _draw_axis_value(X_AXIS, ftostr52sp(lpos.x), blink, cpx, STATUS_HEATERS_Y); | ||||
|     TERN_(HAS_Y_AXIS, _draw_axis_value(Y_AXIS, ftostr52sp(lpos.y), blink, cpx, STATUS_HEATERS_Y + 59)); | ||||
|     TERN_(HAS_Z_AXIS, _draw_axis_value(Z_AXIS, ftostr52sp(lpos.z), blink, cpx, STATUS_HEATERS_Y + 118)); | ||||
|   #endif | ||||
|  | ||||
|   // Feedrate | ||||
|   static uint16_t old_fp = 0; | ||||
|   if (!ui.did_first_redraw || old_fp != feedrate_percentage) { | ||||
|     old_fp = feedrate_percentage; | ||||
|     _draw_feedrate_status(i16tostr3rj(feedrate_percentage), | ||||
|       #if ENABLED(DWIN_MARLINUI_PORTRAIT) | ||||
|         5, 290 | ||||
|       #else | ||||
|         294, STATUS_HEATERS_Y | ||||
|       #endif | ||||
|     ); | ||||
|   } | ||||
|  | ||||
|   // | ||||
|   // Elapsed time | ||||
|   // | ||||
|   char buffer[14]; | ||||
|   duration_t time; | ||||
|  | ||||
|   #if ENABLED(DWIN_MARLINUI_PORTRAIT) | ||||
|  | ||||
|     // Portrait mode only shows one value at a time, and will rotate if ROTATE_PROGRESS_DISPLAY | ||||
|     dwin_string.set(); | ||||
|     char prefix = ' '; | ||||
|     #if ENABLED(SHOW_REMAINING_TIME) | ||||
|       if (TERN1(ROTATE_PROGRESS_DISPLAY, blink) && print_job_timer.isRunning()) { | ||||
|         time = get_remaining_time(); | ||||
|         prefix = 'R'; | ||||
|       } | ||||
|       else | ||||
|     #endif | ||||
|         time = print_job_timer.duration(); | ||||
|  | ||||
|     time.toDigital(buffer); | ||||
|     dwin_string.add(prefix); | ||||
|     dwin_string.add(buffer); | ||||
|     DWIN_Draw_String(true, font14x28, Color_White, Color_Bg_Black, (LCD_PIXEL_WIDTH - ((dwin_string.length() + 1) * 14)), 290, S(dwin_string.string())); | ||||
|  | ||||
|   #else | ||||
|  | ||||
|     // landscape mode shows both elapsed and remaining (if SHOW_REMAINING_TIME) | ||||
|     time = print_job_timer.duration(); | ||||
|     time.toDigital(buffer); | ||||
|     dwin_string.set(" "); | ||||
|     dwin_string.add(buffer); | ||||
|     DWIN_Draw_String(true, font14x28, Color_White, Color_Bg_Black, 280, 100, S(dwin_string.string())); | ||||
|  | ||||
|     #if ENABLED(LCD_SHOW_E_TOTAL) | ||||
|       if (show_e_total && TERN1(SHOW_REMAINING_TIME, !blink)) { // if SHOW_REMAINING_TIME is also | ||||
|         const uint8_t escale = e_move_accumulator >= 100000.0f ? 10 : 1; // show cm after 99,000mm | ||||
|  | ||||
|         DWIN_Draw_String(true, font14x28, Color_IconBlue, Color_Bg_Black, 249, 135, S("E")); | ||||
|         dwin_string.set(ui16tostr5rj(e_move_accumulator * escale)); | ||||
|         DWIN_Draw_String(true, font14x28, Color_White, Color_Bg_Black, 263, 135, S(dwin_string.string())); | ||||
|         DWIN_Draw_String(true, font14x28, Color_IconBlue, Color_Bg_Black, 333, 135, S(escale==1 ? "mm" : "cm")); | ||||
|       } | ||||
|     #endif | ||||
|     #if ENABLED(SHOW_REMAINING_TIME) | ||||
|       if (!show_e_total || blink) { | ||||
|         DWIN_Draw_String(true, font14x28, Color_IconBlue, Color_Bg_Black, 249, 135, S(" R ")); | ||||
|         time = get_remaining_time(); | ||||
|         time.toDigital(buffer); | ||||
|         dwin_string.set(buffer); | ||||
|         DWIN_Draw_String(true, font14x28, Color_White, Color_Bg_Black, 291, 135, S(dwin_string.string())); | ||||
|       } | ||||
|     #endif | ||||
|   #endif | ||||
|  | ||||
|   // | ||||
|   // Progress Bar | ||||
|   // | ||||
|   constexpr int16_t pb_margin = 5, pb_left = pb_margin, pb_height = 60, | ||||
|                     pb_right = LCD_PIXEL_WIDTH - TERN(DWIN_MARLINUI_PORTRAIT, 0, 107) - pb_margin, | ||||
|                     pb_bottom = TERN(DWIN_MARLINUI_PORTRAIT, 410, 230), | ||||
|                     pb_top = pb_bottom - pb_height, | ||||
|                     pb_width = pb_right - pb_left; | ||||
|  | ||||
|   const progress_t progress = TERN(HAS_PRINT_PROGRESS_PERMYRIAD, get_progress_permyriad, get_progress_percent)(); | ||||
|  | ||||
|   if (!ui.did_first_redraw) | ||||
|     DWIN_Draw_Rectangle(0, Select_Color, pb_left, pb_top, pb_right, pb_bottom);   // Outline | ||||
|  | ||||
|   static uint16_t old_solid = 50; | ||||
|   const uint16_t pb_solid = (pb_width - 2) * (progress / (PROGRESS_SCALE)) * 0.01f; | ||||
|   const bool p_draw = !ui.did_first_redraw || old_solid != pb_solid; | ||||
|  | ||||
|   if (p_draw) { | ||||
|     //if (pb_solid) | ||||
|       DWIN_Draw_Rectangle(1, Select_Color, pb_left + 1, pb_top + 1, pb_left + pb_solid, pb_bottom - 1); // Fill the solid part | ||||
|  | ||||
|     //if (pb_solid < old_solid) | ||||
|       DWIN_Draw_Rectangle(1, Color_Bg_Black, pb_left + 1 + pb_solid, pb_top + 1, pb_right - 1, pb_bottom - 1); // Erase the rest | ||||
|  | ||||
|     #if ENABLED(SHOW_SD_PERCENT) | ||||
|       dwin_string.set(TERN(PRINT_PROGRESS_SHOW_DECIMALS, permyriadtostr4(progress), ui8tostr3rj(progress / (PROGRESS_SCALE)))); | ||||
|       dwin_string.add(PSTR("%")); | ||||
|       DWIN_Draw_String( | ||||
|         false, font16x32, Percent_Color, Color_Bg_Black, | ||||
|         pb_left + (pb_width - dwin_string.length() * 16) / 2, | ||||
|         pb_top + (pb_height - 32) / 2, | ||||
|         S(dwin_string.string()) | ||||
|       ); | ||||
|     #endif | ||||
|  | ||||
|     old_solid = pb_solid; | ||||
|   } | ||||
|  | ||||
|   // | ||||
|   // Status Message | ||||
|   // | ||||
|   draw_status_message(blink); | ||||
|  | ||||
|   ui.did_first_redraw = true; | ||||
| } | ||||
|  | ||||
| #endif // IS_DWIN_MARLINUI | ||||
| @@ -26,7 +26,7 @@ | ||||
|  | ||||
| #include "../inc/MarlinConfigPre.h" | ||||
|  | ||||
| #if HAS_WIRED_LCD && !HAS_GRAPHICAL_TFT | ||||
| #if HAS_WIRED_LCD && !HAS_GRAPHICAL_TFT && !IS_DWIN_MARLINUI | ||||
|  | ||||
| #include "marlinui.h" | ||||
| #include "lcdprint.h" | ||||
|   | ||||
| @@ -34,7 +34,21 @@ | ||||
|  | ||||
| #include "../inc/MarlinConfig.h" | ||||
|  | ||||
| #if HAS_MARLINUI_U8GLIB | ||||
| #if IS_DWIN_MARLINUI | ||||
|  | ||||
|   #include "e3v2/marlinui/marlinui_dwin.h" | ||||
|  | ||||
|   #define LCD_PIXEL_WIDTH     DWIN_WIDTH | ||||
|   #define LCD_PIXEL_HEIGHT    DWIN_HEIGHT | ||||
|   #define LCD_WIDTH           ((LCD_PIXEL_WIDTH)  / (MENU_FONT_WIDTH)) | ||||
|   #define LCD_HEIGHT          ((LCD_PIXEL_HEIGHT) / (MENU_LINE_HEIGHT)) | ||||
|  | ||||
|   // The DWIN lcd_moveto function uses row / column, not pixels | ||||
|   #define LCD_COL_X(col)    (col) | ||||
|   #define LCD_ROW_Y(row)    (row) | ||||
|   #define LCD_COL_X_RJ(len) (LCD_WIDTH - LCD_COL_X(len)) | ||||
|  | ||||
| #elif HAS_MARLINUI_U8GLIB | ||||
|  | ||||
|   #include "dogm/u8g_fontutf8.h" | ||||
|   typedef u8g_uint_t lcd_uint_t; | ||||
| @@ -105,7 +119,10 @@ | ||||
|   #define MENU_LINE_HEIGHT MENU_FONT_HEIGHT | ||||
| #endif | ||||
|  | ||||
| #define LCD_COL_X_RJ(len)      (LCD_PIXEL_WIDTH - LCD_COL_X(len)) | ||||
| #ifndef LCD_COL_X_RJ | ||||
|   #define LCD_COL_X_RJ(len)    (LCD_PIXEL_WIDTH - LCD_COL_X(len)) | ||||
| #endif | ||||
|  | ||||
| #define SETCURSOR(col, row)    lcd_moveto(LCD_COL_X(col), LCD_ROW_Y(row)) | ||||
| #define SETCURSOR_RJ(len, row) lcd_moveto(LCD_COL_X_RJ(len), LCD_ROW_Y(row)) | ||||
| #define SETCURSOR_X(col)       SETCURSOR(col, _lcdLineNr) | ||||
|   | ||||
| @@ -202,6 +202,10 @@ constexpr uint8_t epps = ENCODER_PULSES_PER_STEP; | ||||
|     bool MarlinUI::drawing_screen, MarlinUI::first_page; // = false | ||||
|   #endif | ||||
|  | ||||
|   #if IS_DWIN_MARLINUI | ||||
|     bool MarlinUI::did_first_redraw; | ||||
|   #endif | ||||
|  | ||||
|   // Encoder Handling | ||||
|   #if HAS_ENCODER_ACTION | ||||
|     uint32_t MarlinUI::encoderPosition; | ||||
| @@ -335,6 +339,7 @@ constexpr uint8_t epps = ENCODER_PULSES_PER_STEP; | ||||
|           col = (LCD_WIDTH - plen - slen) / 2; | ||||
|           row = LCD_HEIGHT > 3 ? 1 : 0; | ||||
|         } | ||||
|         if (LCD_HEIGHT >= 8) row = LCD_HEIGHT / 2 - 2; | ||||
|         wrap_string_P(col, row, pref, true); | ||||
|         if (string) { | ||||
|           if (col) { col = 0; row++; } // Move to the start of the next line | ||||
| @@ -1073,6 +1078,9 @@ constexpr uint8_t epps = ENCODER_PULSES_PER_STEP; | ||||
|  | ||||
|           run_current_screen(); | ||||
|  | ||||
|           // Apply all DWIN drawing after processing | ||||
|           TERN_(IS_DWIN_MARLINUI, DWIN_UpdateLCD()); | ||||
|  | ||||
|         #endif | ||||
|  | ||||
|         TERN_(HAS_LCD_MENU, lcd_clicked = false); | ||||
|   | ||||
| @@ -387,22 +387,22 @@ public: | ||||
|       #endif | ||||
|  | ||||
|       #if HAS_MARLINUI_U8GLIB | ||||
|  | ||||
|         static void set_font(const MarlinFont font_nr); | ||||
|       #elif IS_DWIN_MARLINUI | ||||
|         static void set_font(const uint8_t font_nr); | ||||
|       #endif | ||||
|  | ||||
|       #else | ||||
|  | ||||
|       #if HAS_MARLINUI_HD44780 | ||||
|         static void set_custom_characters(const HD44780CharSet screen_charset=CHARSET_INFO); | ||||
|       #endif | ||||
|  | ||||
|         #if ENABLED(LCD_PROGRESS_BAR) | ||||
|           static millis_t progress_bar_ms;  // Start time for the current progress bar cycle | ||||
|           static void draw_progress_bar(const uint8_t percent); | ||||
|           #if PROGRESS_MSG_EXPIRE > 0 | ||||
|             static millis_t expire_status_ms; // = 0 | ||||
|             FORCE_INLINE static void reset_progress_bar_timeout() { expire_status_ms = 0; } | ||||
|           #endif | ||||
|       #if ENABLED(LCD_PROGRESS_BAR) && !HAS_MARLINUI_U8GLIB | ||||
|         static millis_t progress_bar_ms;  // Start time for the current progress bar cycle | ||||
|         static void draw_progress_bar(const uint8_t percent); | ||||
|         #if PROGRESS_MSG_EXPIRE > 0 | ||||
|           static millis_t expire_status_ms; // = 0 | ||||
|           FORCE_INLINE static void reset_progress_bar_timeout() { expire_status_ms = 0; } | ||||
|         #endif | ||||
|  | ||||
|       #endif | ||||
|  | ||||
|       static uint8_t lcd_status_update_delay; | ||||
| @@ -447,6 +447,10 @@ public: | ||||
|       static constexpr bool drawing_screen = false, first_page = true; | ||||
|     #endif | ||||
|  | ||||
|     #if IS_DWIN_MARLINUI | ||||
|       static bool did_first_redraw; | ||||
|     #endif | ||||
|  | ||||
|     static bool get_blink(); | ||||
|     static void kill_screen(PGM_P const lcd_error, PGM_P const lcd_component); | ||||
|     static void draw_kill_screen(); | ||||
|   | ||||
| @@ -179,6 +179,8 @@ bool printer_busy() { | ||||
| void MarlinUI::goto_screen(screenFunc_t screen, const uint16_t encoder/*=0*/, const uint8_t top/*=0*/, const uint8_t items/*=0*/) { | ||||
|   if (currentScreen != screen) { | ||||
|  | ||||
|     TERN_(IS_DWIN_MARLINUI, did_first_redraw = false); | ||||
|  | ||||
|     TERN_(HAS_TOUCH_BUTTONS, repeat_delay = BUTTON_DELAY_MENU); | ||||
|  | ||||
|     TERN_(LCD_SET_PROGRESS_MANUALLY, progress_reset()); | ||||
|   | ||||
| @@ -39,7 +39,7 @@ typedef void (*selectFunc_t)(); | ||||
| #define SS_INVERT  0x02 | ||||
| #define SS_DEFAULT SS_CENTER | ||||
|  | ||||
| #if HAS_MARLINUI_U8GLIB && EITHER(BABYSTEP_ZPROBE_GFX_OVERLAY, MESH_EDIT_GFX_OVERLAY) | ||||
| #if EITHER(HAS_MARLINUI_U8GLIB, IS_DWIN_MARLINUI) && EITHER(BABYSTEP_ZPROBE_GFX_OVERLAY, MESH_EDIT_GFX_OVERLAY) | ||||
|   void _lcd_zoffset_overlay_gfx(const_float_t zvalue); | ||||
| #endif | ||||
|  | ||||
|   | ||||
| @@ -184,7 +184,7 @@ | ||||
|   #define BTN_EN1                           PB10 | ||||
|   #define BTN_EN2                           PA6 | ||||
|  | ||||
| #elif ENABLED(DWIN_CREALITY_LCD) | ||||
| #elif EITHER(DWIN_CREALITY_LCD, IS_DWIN_MARLINUI) | ||||
|  | ||||
|   // RET6 DWIN ENCODER LCD | ||||
|   #define BTN_ENC                           PB14 | ||||
| @@ -194,7 +194,7 @@ | ||||
|   //#define LCD_LED_PIN                     PB2 | ||||
|   #ifndef BEEPER_PIN | ||||
|     #define BEEPER_PIN                      PB13 | ||||
|     #undef SPEAKER | ||||
|     //#undef SPEAKER | ||||
|   #endif | ||||
|  | ||||
| #elif ENABLED(DWIN_VET6_CREALITY_LCD) | ||||
|   | ||||
							
								
								
									
										64
									
								
								buildroot/share/fonts/buildhzk.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										64
									
								
								buildroot/share/fonts/buildhzk.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,64 @@ | ||||
| # Generate a 'HZK' font file for the T5UIC1 DWIN LCD | ||||
| # from multiple bdf font files. | ||||
| # Note: the 16x16 glyphs are not produced | ||||
| # Author: Taylor Talkington | ||||
| # License: GPL | ||||
|  | ||||
| import bdflib.reader | ||||
| import math | ||||
|  | ||||
| def glyph_bits(size_x, size_y, font, glyph_ord): | ||||
|     asc = font[b'FONT_ASCENT'] | ||||
|     desc = font[b'FONT_DESCENT'] | ||||
|     bits = [0 for y in range(size_y)] | ||||
|  | ||||
|     glyph_bytes = math.ceil(size_x / 8) | ||||
|     try: | ||||
|         glyph = font[glyph_ord] | ||||
|         for y, row in enumerate(glyph.data): | ||||
|             v = row | ||||
|             rpad = size_x - glyph.bbW | ||||
|             if rpad < 0: rpad = 0 | ||||
|             if glyph.bbW > size_x: v = v >> (glyph.bbW - size_x) # some glyphs are actually too wide to fit! | ||||
|             v = v << (glyph_bytes * 8) - size_x + rpad | ||||
|             v = v >> glyph.bbX | ||||
|             bits[y + desc + glyph.bbY] |= v | ||||
|     except KeyError: | ||||
|         pass | ||||
|  | ||||
|     bits.reverse() | ||||
|     return bits | ||||
|  | ||||
| def marlin_font_hzk(): | ||||
|     fonts = [ | ||||
|         [6,12,'marlin-6x12-3.bdf'], | ||||
|         [8,16,'marlin-8x16.bdf'], | ||||
|         [10,20,'marlin-10x20.bdf'], | ||||
|         [12,24,'marlin-12x24.bdf'], | ||||
|         [14,28,'marlin-14x28.bdf'], | ||||
|         [16,32,'marlin-16x32.bdf'], | ||||
|         [20,40,'marlin-20x40.bdf'], | ||||
|         [24,48,'marlin-24x48.bdf'], | ||||
|         [28,56,'marlin-28x56.bdf'], | ||||
|         [32,64,'marlin-32x64.bdf'] | ||||
|     ] | ||||
|  | ||||
|     with open('marlin_fixed.hzk','wb') as output: | ||||
|         for f in fonts: | ||||
|             with open(f[2], 'rb') as file: | ||||
|                 print(f'{f[0]}x{f[1]}') | ||||
|                 font = bdflib.reader.read_bdf(file) | ||||
|                 for glyph in range(128): | ||||
|                     bits = glyph_bits(f[0], f[1], font, glyph) | ||||
|                     glyph_bytes = math.ceil(f[0]/8) | ||||
|  | ||||
|                     for b in bits: | ||||
|                         try: | ||||
|                             z = b.to_bytes(glyph_bytes, 'big') | ||||
|                             output.write(z) | ||||
|                         except OverflowError: | ||||
|                             print('Overflow') | ||||
|                             print(f'{glyph}') | ||||
|                             print(font[glyph]) | ||||
|                             for b in bits: print(f'{b:0{f[0]}b}') | ||||
|                             return | ||||
							
								
								
									
										4104
									
								
								buildroot/share/fonts/marlin-10x20.bdf
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										4104
									
								
								buildroot/share/fonts/marlin-10x20.bdf
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										4558
									
								
								buildroot/share/fonts/marlin-12x24.bdf
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										4558
									
								
								buildroot/share/fonts/marlin-12x24.bdf
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										5078
									
								
								buildroot/share/fonts/marlin-14x28.bdf
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5078
									
								
								buildroot/share/fonts/marlin-14x28.bdf
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										5492
									
								
								buildroot/share/fonts/marlin-16x32.bdf
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5492
									
								
								buildroot/share/fonts/marlin-16x32.bdf
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										6458
									
								
								buildroot/share/fonts/marlin-20x40.bdf
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										6458
									
								
								buildroot/share/fonts/marlin-20x40.bdf
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										6462
									
								
								buildroot/share/fonts/marlin-24x48.bdf
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										6462
									
								
								buildroot/share/fonts/marlin-24x48.bdf
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										7311
									
								
								buildroot/share/fonts/marlin-28x56.bdf
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										7311
									
								
								buildroot/share/fonts/marlin-28x56.bdf
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										9870
									
								
								buildroot/share/fonts/marlin-32x64.bdf
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9870
									
								
								buildroot/share/fonts/marlin-32x64.bdf
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										3701
									
								
								buildroot/share/fonts/marlin-8x16.bdf
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3701
									
								
								buildroot/share/fonts/marlin-8x16.bdf
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @@ -13,11 +13,9 @@ use_example_configs "Creality/Ender-3 V2/CrealityUI" | ||||
| opt_enable MARLIN_DEV_MODE BUFFER_MONITORING | ||||
| exec_test $1 $2 "Ender 3 v2 with CrealityUI" "$3" | ||||
|  | ||||
| use_example_configs "Creality/Ender-3 V2/CrealityUI" | ||||
| opt_disable CLASSIC_JERK | ||||
| use_example_configs "Creality/Ender-3 V2/MarlinUI" | ||||
| opt_add SDCARD_EEPROM_EMULATION | ||||
| opt_set TEMP_SENSOR_BED 0 | ||||
| exec_test $1 $2 "Ender 3 v2, SD EEPROM, no CLASSIC_JERK, no Bed" "$3" | ||||
| exec_test $1 $2 "Ender 3 v2 with MarlinUI" "$3" | ||||
|  | ||||
| restore_configs | ||||
| opt_set MOTHERBOARD BOARD_CREALITY_V452 SERIAL_PORT 1 | ||||
|   | ||||
| @@ -45,6 +45,7 @@ I2C_EEPROM                             = src_filter=+<src/HAL/shared/eeprom_if_i | ||||
| SOFT_I2C_EEPROM                        = SlowSoftI2CMaster, SlowSoftWire=https://github.com/felias-fogg/SlowSoftWire/archive/master.zip | ||||
| SPI_EEPROM                             = src_filter=+<src/HAL/shared/eeprom_if_spi.cpp> | ||||
| DWIN_CREALITY_LCD                      = src_filter=+<src/lcd/e3v2/creality> | ||||
| DWIN_MARLINUI_.+                       = src_filter=+<src/lcd/e3v2/marlinui> | ||||
| HAS_GRAPHICAL_TFT                      = src_filter=+<src/lcd/tft> | ||||
| IS_TFTGLCD_PANEL                       = src_filter=+<src/lcd/TFTGLCD> | ||||
| HAS_TOUCH_BUTTONS                      = src_filter=+<src/lcd/touch/touch_buttons.cpp> | ||||
|   | ||||
| @@ -48,7 +48,8 @@ extra_scripts      = | ||||
|   post:buildroot/share/PlatformIO/scripts/common-dependencies-post.py | ||||
| lib_deps           = | ||||
| default_src_filter = +<src/*> -<src/config> -<src/HAL> +<src/HAL/shared> | ||||
|   -<src/lcd/HD44780> -<src/lcd/TFTGLCD> -<src/lcd/e3v2/creality> -<src/lcd/dogm> -<src/lcd/tft> -<src/lcd/tft_io> | ||||
|   -<src/lcd/HD44780> -<src/lcd/TFTGLCD> -<src/lcd/dogm> -<src/lcd/tft> -<src/lcd/tft_io> | ||||
|   -<src/lcd/e3v2/creality> -<src/lcd/e3v2/marlinui> | ||||
|   -<src/HAL/STM32/tft> -<src/HAL/STM32F1/tft> | ||||
|   -<src/lcd/menu> | ||||
|   -<src/lcd/menu/game/game.cpp> -<src/lcd/menu/game/brickout.cpp> -<src/lcd/menu/game/invaders.cpp> | ||||
|   | ||||
		Reference in New Issue
	
	Block a user