✨ 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 | //#define DWIN_CREALITY_LCD | ||||||
|  |  | ||||||
|  | // | ||||||
|  | // MarlinUI for Creality's DWIN display (and others) | ||||||
|  | // | ||||||
|  | //#define DWIN_MARLINUI_PORTRAIT | ||||||
|  | //#define DWIN_MARLINUI_LANDSCAPE | ||||||
|  |  | ||||||
| // | // | ||||||
| // Touch Screen Settings | // Touch Screen Settings | ||||||
| // | // | ||||||
|   | |||||||
| @@ -1306,7 +1306,7 @@ | |||||||
|  |  | ||||||
| // LCD Print Progress options | // LCD Print Progress options | ||||||
| #if EITHER(SDSUPPORT, LCD_SET_PROGRESS_MANUALLY) | #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 |     //#define SHOW_REMAINING_TIME         // Display estimated time to completion | ||||||
|     #if ENABLED(SHOW_REMAINING_TIME) |     #if ENABLED(SHOW_REMAINING_TIME) | ||||||
|       //#define USE_M73_REMAINING_TIME    // Use remaining time from M73 command instead of estimation |       //#define USE_M73_REMAINING_TIME    // Use remaining time from M73 command instead of estimation | ||||||
| @@ -1579,16 +1579,10 @@ | |||||||
|  * printing performance versus fast display updates. |  * printing performance versus fast display updates. | ||||||
|  */ |  */ | ||||||
| #if HAS_MARLINUI_U8GLIB | #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 |   // Save many cycles by drawing a hollow frame or no frame on the Info Screen | ||||||
|   //#define XYZ_NO_FRAME |   //#define XYZ_NO_FRAME | ||||||
|   #define XYZ_HOLLOW_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. |   // A bigger font is available for edit items. Costs 3120 bytes of PROGMEM. | ||||||
|   // Western only. Not available for Cyrillic, Kana, Turkish, Greek, or Chinese. |   // Western only. Not available for Cyrillic, Kana, Turkish, Greek, or Chinese. | ||||||
|   //#define USE_BIG_EDIT_FONT |   //#define USE_BIG_EDIT_FONT | ||||||
| @@ -1597,9 +1591,6 @@ | |||||||
|   // Western only. Not available for Cyrillic, Kana, Turkish, Greek, or Chinese. |   // Western only. Not available for Cyrillic, Kana, Turkish, Greek, or Chinese. | ||||||
|   //#define USE_SMALL_INFOFONT |   //#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 |    * ST7920-based LCDs can emulate a 16 x 4 character display using | ||||||
|    * the ST7920 character-generator for very fast screen updates. |    * the ST7920 character-generator for very fast screen updates. | ||||||
| @@ -1651,6 +1642,17 @@ | |||||||
|  |  | ||||||
| #endif // HAS_MARLINUI_U8GLIB | #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 | // Additional options for DGUS / DWIN displays | ||||||
| // | // | ||||||
| @@ -1716,7 +1718,7 @@ | |||||||
| // | // | ||||||
| // Specify additional languages for the UI. Default specified by LCD_LANGUAGE. | // 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_2 fr | ||||||
|   //#define LCD_LANGUAGE_3 de |   //#define LCD_LANGUAGE_3 de | ||||||
|   //#define LCD_LANGUAGE_4 es |   //#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); |     if (show_lcd) ui.pause_show_message(PAUSE_MESSAGE_PURGE); | ||||||
|  |  | ||||||
|     TERN_(EXTENSIBLE_UI, ExtUI::onUserConfirmRequired_P(PSTR("Filament Purging..."))); |     TERN_(EXTENSIBLE_UI, ExtUI::onUserConfirmRequired_P(GET_TEXT(MSG_FILAMENT_CHANGE_PURGE))); | ||||||
|     TERN_(HOST_PROMPT_SUPPORT, host_prompt_do(PROMPT_USER_CONTINUE, PSTR("Filament Purging..."), CONTINUE_STR)); |     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 |     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) |     for (float purge_count = purge_length; purge_count > 0 && wait_for_user; --purge_count) | ||||||
|       unscaled_e_move(1, ADVANCED_PAUSE_PURGE_FEEDRATE); |       unscaled_e_move(1, ADVANCED_PAUSE_PURGE_FEEDRATE); | ||||||
|   | |||||||
| @@ -488,7 +488,10 @@ | |||||||
|     #define HAS_MARLINUI_U8GLIB 1 |     #define HAS_MARLINUI_U8GLIB 1 | ||||||
|   #elif IS_TFTGLCD_PANEL |   #elif IS_TFTGLCD_PANEL | ||||||
|     // Neither DOGM nor HD44780. Fully customized interface. |     // 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 |     #define HAS_MARLINUI_HD44780 1 | ||||||
|   #endif |   #endif | ||||||
| #endif | #endif | ||||||
| @@ -1087,7 +1090,7 @@ | |||||||
|   #define HAS_ETHERNET 1 |   #define HAS_ETHERNET 1 | ||||||
| #endif | #endif | ||||||
|  |  | ||||||
| #if ENABLED(DWIN_CREALITY_LCD) | #if EITHER(DWIN_CREALITY_LCD, IS_DWIN_MARLINUI) | ||||||
|   #define SERIAL_CATCHALL 0 |   #define SERIAL_CATCHALL 0 | ||||||
|   #ifndef LCD_SERIAL_PORT |   #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) |     #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 | #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 |   #define NO_LCD_REINIT 1  // Suppress LCD re-initialization | ||||||
| #endif | #endif | ||||||
|  |  | ||||||
| @@ -3258,6 +3258,8 @@ | |||||||
|   #ifndef LCD_WIDTH |   #ifndef LCD_WIDTH | ||||||
|     #if HAS_MARLINUI_U8GLIB |     #if HAS_MARLINUI_U8GLIB | ||||||
|       #define LCD_WIDTH 21 |       #define LCD_WIDTH 21 | ||||||
|  |     #elif IS_DWIN_MARLINUI | ||||||
|  |       // Defined by header | ||||||
|     #else |     #else | ||||||
|       #define LCD_WIDTH TERN(IS_ULTIPANEL, 20, 16) |       #define LCD_WIDTH TERN(IS_ULTIPANEL, 20, 16) | ||||||
|     #endif |     #endif | ||||||
| @@ -3265,6 +3267,8 @@ | |||||||
|   #ifndef LCD_HEIGHT |   #ifndef LCD_HEIGHT | ||||||
|     #if HAS_MARLINUI_U8GLIB |     #if HAS_MARLINUI_U8GLIB | ||||||
|       #define LCD_HEIGHT 5 |       #define LCD_HEIGHT 5 | ||||||
|  |     #elif IS_DWIN_MARLINUI | ||||||
|  |       // Defined by header | ||||||
|     #else |     #else | ||||||
|       #define LCD_HEIGHT TERN(IS_ULTIPANEL, 4, 2) |       #define LCD_HEIGHT TERN(IS_ULTIPANEL, 4, 2) | ||||||
|     #endif |     #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." |     #error "PROGRESS_MSG_EXPIRE must be greater than or equal to 0." | ||||||
|   #endif |   #endif | ||||||
| #elif ENABLED(LCD_SET_PROGRESS_MANUALLY) | #elif ENABLED(LCD_SET_PROGRESS_MANUALLY) | ||||||
|   #if NONE(HAS_MARLINUI_U8GLIB, HAS_GRAPHICAL_TFT, HAS_MARLINUI_HD44780, 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, or EXTENSIBLE_UI." |     #error "LCD_SET_PROGRESS_MANUALLY requires LCD_PROGRESS_BAR, Character LCD, Graphical LCD, TFT, EXTENSIBLE_UI, OR DWIN MarlinUI." | ||||||
|   #endif |   #endif | ||||||
| #endif | #endif | ||||||
|  |  | ||||||
| @@ -1721,7 +1721,7 @@ static_assert(Y_MAX_LENGTH >= Y_BED_SIZE, "Movement bounds (Y_MIN_POS, Y_MAX_POS | |||||||
|   #endif |   #endif | ||||||
| #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." |   #error "MESH_EDIT_GFX_OVERLAY requires AUTO_BED_LEVELING_UBL and a Graphical LCD." | ||||||
| #endif | #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(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(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(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(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(LCD_SAINSMART_I2C_1602, LCD_SAINSMART_I2C_2004) \ | ||||||
|   + COUNT_ENABLED(MKS_12864OLED, MKS_12864OLED_SSD1306) \ |   + 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" | #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 "marlinui.h" | ||||||
| #include "lcdprint.h" | #include "lcdprint.h" | ||||||
|   | |||||||
| @@ -34,7 +34,21 @@ | |||||||
|  |  | ||||||
| #include "../inc/MarlinConfig.h" | #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" |   #include "dogm/u8g_fontutf8.h" | ||||||
|   typedef u8g_uint_t lcd_uint_t; |   typedef u8g_uint_t lcd_uint_t; | ||||||
| @@ -105,7 +119,10 @@ | |||||||
|   #define MENU_LINE_HEIGHT MENU_FONT_HEIGHT |   #define MENU_LINE_HEIGHT MENU_FONT_HEIGHT | ||||||
| #endif | #endif | ||||||
|  |  | ||||||
|  | #ifndef LCD_COL_X_RJ | ||||||
|   #define LCD_COL_X_RJ(len)    (LCD_PIXEL_WIDTH - LCD_COL_X(len)) |   #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(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_RJ(len, row) lcd_moveto(LCD_COL_X_RJ(len), LCD_ROW_Y(row)) | ||||||
| #define SETCURSOR_X(col)       SETCURSOR(col, _lcdLineNr) | #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 |     bool MarlinUI::drawing_screen, MarlinUI::first_page; // = false | ||||||
|   #endif |   #endif | ||||||
|  |  | ||||||
|  |   #if IS_DWIN_MARLINUI | ||||||
|  |     bool MarlinUI::did_first_redraw; | ||||||
|  |   #endif | ||||||
|  |  | ||||||
|   // Encoder Handling |   // Encoder Handling | ||||||
|   #if HAS_ENCODER_ACTION |   #if HAS_ENCODER_ACTION | ||||||
|     uint32_t MarlinUI::encoderPosition; |     uint32_t MarlinUI::encoderPosition; | ||||||
| @@ -335,6 +339,7 @@ constexpr uint8_t epps = ENCODER_PULSES_PER_STEP; | |||||||
|           col = (LCD_WIDTH - plen - slen) / 2; |           col = (LCD_WIDTH - plen - slen) / 2; | ||||||
|           row = LCD_HEIGHT > 3 ? 1 : 0; |           row = LCD_HEIGHT > 3 ? 1 : 0; | ||||||
|         } |         } | ||||||
|  |         if (LCD_HEIGHT >= 8) row = LCD_HEIGHT / 2 - 2; | ||||||
|         wrap_string_P(col, row, pref, true); |         wrap_string_P(col, row, pref, true); | ||||||
|         if (string) { |         if (string) { | ||||||
|           if (col) { col = 0; row++; } // Move to the start of the next line |           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(); |           run_current_screen(); | ||||||
|  |  | ||||||
|  |           // Apply all DWIN drawing after processing | ||||||
|  |           TERN_(IS_DWIN_MARLINUI, DWIN_UpdateLCD()); | ||||||
|  |  | ||||||
|         #endif |         #endif | ||||||
|  |  | ||||||
|         TERN_(HAS_LCD_MENU, lcd_clicked = false); |         TERN_(HAS_LCD_MENU, lcd_clicked = false); | ||||||
|   | |||||||
| @@ -387,14 +387,16 @@ public: | |||||||
|       #endif |       #endif | ||||||
|  |  | ||||||
|       #if HAS_MARLINUI_U8GLIB |       #if HAS_MARLINUI_U8GLIB | ||||||
|  |  | ||||||
|         static void set_font(const MarlinFont font_nr); |         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); |         static void set_custom_characters(const HD44780CharSet screen_charset=CHARSET_INFO); | ||||||
|  |       #endif | ||||||
|  |  | ||||||
|         #if ENABLED(LCD_PROGRESS_BAR) |       #if ENABLED(LCD_PROGRESS_BAR) && !HAS_MARLINUI_U8GLIB | ||||||
|         static millis_t progress_bar_ms;  // Start time for the current progress bar cycle |         static millis_t progress_bar_ms;  // Start time for the current progress bar cycle | ||||||
|         static void draw_progress_bar(const uint8_t percent); |         static void draw_progress_bar(const uint8_t percent); | ||||||
|         #if PROGRESS_MSG_EXPIRE > 0 |         #if PROGRESS_MSG_EXPIRE > 0 | ||||||
| @@ -403,8 +405,6 @@ public: | |||||||
|         #endif |         #endif | ||||||
|       #endif |       #endif | ||||||
|  |  | ||||||
|       #endif |  | ||||||
|  |  | ||||||
|       static uint8_t lcd_status_update_delay; |       static uint8_t lcd_status_update_delay; | ||||||
|  |  | ||||||
|       #if HAS_LCD_CONTRAST |       #if HAS_LCD_CONTRAST | ||||||
| @@ -447,6 +447,10 @@ public: | |||||||
|       static constexpr bool drawing_screen = false, first_page = true; |       static constexpr bool drawing_screen = false, first_page = true; | ||||||
|     #endif |     #endif | ||||||
|  |  | ||||||
|  |     #if IS_DWIN_MARLINUI | ||||||
|  |       static bool did_first_redraw; | ||||||
|  |     #endif | ||||||
|  |  | ||||||
|     static bool get_blink(); |     static bool get_blink(); | ||||||
|     static void kill_screen(PGM_P const lcd_error, PGM_P const lcd_component); |     static void kill_screen(PGM_P const lcd_error, PGM_P const lcd_component); | ||||||
|     static void draw_kill_screen(); |     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*/) { | 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) { |   if (currentScreen != screen) { | ||||||
|  |  | ||||||
|  |     TERN_(IS_DWIN_MARLINUI, did_first_redraw = false); | ||||||
|  |  | ||||||
|     TERN_(HAS_TOUCH_BUTTONS, repeat_delay = BUTTON_DELAY_MENU); |     TERN_(HAS_TOUCH_BUTTONS, repeat_delay = BUTTON_DELAY_MENU); | ||||||
|  |  | ||||||
|     TERN_(LCD_SET_PROGRESS_MANUALLY, progress_reset()); |     TERN_(LCD_SET_PROGRESS_MANUALLY, progress_reset()); | ||||||
|   | |||||||
| @@ -39,7 +39,7 @@ typedef void (*selectFunc_t)(); | |||||||
| #define SS_INVERT  0x02 | #define SS_INVERT  0x02 | ||||||
| #define SS_DEFAULT SS_CENTER | #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); |   void _lcd_zoffset_overlay_gfx(const_float_t zvalue); | ||||||
| #endif | #endif | ||||||
|  |  | ||||||
|   | |||||||
| @@ -184,7 +184,7 @@ | |||||||
|   #define BTN_EN1                           PB10 |   #define BTN_EN1                           PB10 | ||||||
|   #define BTN_EN2                           PA6 |   #define BTN_EN2                           PA6 | ||||||
|  |  | ||||||
| #elif ENABLED(DWIN_CREALITY_LCD) | #elif EITHER(DWIN_CREALITY_LCD, IS_DWIN_MARLINUI) | ||||||
|  |  | ||||||
|   // RET6 DWIN ENCODER LCD |   // RET6 DWIN ENCODER LCD | ||||||
|   #define BTN_ENC                           PB14 |   #define BTN_ENC                           PB14 | ||||||
| @@ -194,7 +194,7 @@ | |||||||
|   //#define LCD_LED_PIN                     PB2 |   //#define LCD_LED_PIN                     PB2 | ||||||
|   #ifndef BEEPER_PIN |   #ifndef BEEPER_PIN | ||||||
|     #define BEEPER_PIN                      PB13 |     #define BEEPER_PIN                      PB13 | ||||||
|     #undef SPEAKER |     //#undef SPEAKER | ||||||
|   #endif |   #endif | ||||||
|  |  | ||||||
| #elif ENABLED(DWIN_VET6_CREALITY_LCD) | #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 | opt_enable MARLIN_DEV_MODE BUFFER_MONITORING | ||||||
| exec_test $1 $2 "Ender 3 v2 with CrealityUI" "$3" | exec_test $1 $2 "Ender 3 v2 with CrealityUI" "$3" | ||||||
|  |  | ||||||
| use_example_configs "Creality/Ender-3 V2/CrealityUI" | use_example_configs "Creality/Ender-3 V2/MarlinUI" | ||||||
| opt_disable CLASSIC_JERK |  | ||||||
| opt_add SDCARD_EEPROM_EMULATION | opt_add SDCARD_EEPROM_EMULATION | ||||||
| opt_set TEMP_SENSOR_BED 0 | exec_test $1 $2 "Ender 3 v2 with MarlinUI" "$3" | ||||||
| exec_test $1 $2 "Ender 3 v2, SD EEPROM, no CLASSIC_JERK, no Bed" "$3" |  | ||||||
|  |  | ||||||
| restore_configs | restore_configs | ||||||
| opt_set MOTHERBOARD BOARD_CREALITY_V452 SERIAL_PORT 1 | 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 | 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> | SPI_EEPROM                             = src_filter=+<src/HAL/shared/eeprom_if_spi.cpp> | ||||||
| DWIN_CREALITY_LCD                      = src_filter=+<src/lcd/e3v2/creality> | 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> | HAS_GRAPHICAL_TFT                      = src_filter=+<src/lcd/tft> | ||||||
| IS_TFTGLCD_PANEL                       = src_filter=+<src/lcd/TFTGLCD> | IS_TFTGLCD_PANEL                       = src_filter=+<src/lcd/TFTGLCD> | ||||||
| HAS_TOUCH_BUTTONS                      = src_filter=+<src/lcd/touch/touch_buttons.cpp> | 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 |   post:buildroot/share/PlatformIO/scripts/common-dependencies-post.py | ||||||
| lib_deps           = | lib_deps           = | ||||||
| default_src_filter = +<src/*> -<src/config> -<src/HAL> +<src/HAL/shared> | 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/HAL/STM32/tft> -<src/HAL/STM32F1/tft> | ||||||
|   -<src/lcd/menu> |   -<src/lcd/menu> | ||||||
|   -<src/lcd/menu/game/game.cpp> -<src/lcd/menu/game/brickout.cpp> -<src/lcd/menu/game/invaders.cpp> |   -<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