123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454 |
- /**
- * 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/>.
- *
- */
-
- /**
- * DWIN UI Enhanced implementation
- * Author: Miguel A. Risco-Castillo
- * Version: 3.6.3
- * Date: 2021/09/08
- */
-
- #include "../../../inc/MarlinConfigPre.h"
-
- #if ENABLED(DWIN_CREALITY_LCD_ENHANCED)
-
- #include "../../../inc/MarlinConfig.h"
- #include "../../../core/macros.h"
- #include "dwin_lcd.h"
- #include "dwinui.h"
-
- //#define DEBUG_OUT 1
- #include "../../../core/debug_out.h"
-
- uint8_t MenuItemTotal = 0;
- uint8_t MenuItemCount = 0;
- MenuItemClass** MenuItems = nullptr;
- MenuClass *CurrentMenu = nullptr;
- MenuClass *PreviousMenu = nullptr;
-
- xy_int_t DWINUI::cursor = { 0 };
- uint16_t DWINUI::pencolor = Color_White;
- uint16_t DWINUI::textcolor = Def_Text_Color;
- uint16_t DWINUI::backcolor = Def_Background_Color;
- uint8_t DWINUI::font = font8x16;
-
- void (*DWINUI::onCursorErase)(uint8_t line)=nullptr;
- void (*DWINUI::onCursorDraw)(uint8_t line)=nullptr;
- void (*DWINUI::onTitleDraw)(TitleClass* title)=nullptr;
- void (*DWINUI::onMenuDraw)(MenuClass* menu)=nullptr;
-
- void DWINUI::init() {
- 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(1);
- TERN(SHOW_BOOTSCREEN,,DWIN_Frame_Clear(Color_Bg_Black));
- DWIN_UpdateLCD();
- cursor.x = 0;
- cursor.y = 0;
- pencolor = Color_White;
- textcolor = Def_Text_Color;
- backcolor = Def_Background_Color;
- font = font8x16;
- }
-
- // Set text/number font
- void DWINUI::setFont(uint8_t cfont) {
- font = cfont;
- }
-
- // Get font character width
- uint8_t DWINUI::fontWidth(uint8_t cfont) {
- switch (cfont) {
- case font6x12 : return 6;
- case font8x16 : return 8;
- case font10x20: return 10;
- case font12x24: return 12;
- case font14x28: return 14;
- case font16x32: return 16;
- case font20x40: return 20;
- case font24x48: return 24;
- case font28x56: return 28;
- case font32x64: return 32;
- default: return 0;
- }
- }
-
- // Get font character heigh
- uint8_t DWINUI::fontHeight(uint8_t cfont) {
- switch (cfont) {
- case font6x12 : return 12;
- case font8x16 : return 16;
- case font10x20: return 20;
- case font12x24: return 24;
- case font14x28: return 28;
- case font16x32: return 32;
- case font20x40: return 40;
- case font24x48: return 48;
- case font28x56: return 56;
- case font32x64: return 64;
- default: return 0;
- }
- }
-
- // Get screen x coodinates from text column
- uint16_t DWINUI::ColToX(uint8_t col) {
- return col * fontWidth(font);
- }
-
- // Get screen y coodinates from text row
- uint16_t DWINUI::RowToY(uint8_t row) {
- return row * fontHeight(font);
- }
-
- // Set text/number color
- void DWINUI::SetColors(uint16_t fgcolor, uint16_t bgcolor) {
- textcolor = fgcolor;
- backcolor = bgcolor;
- }
- void DWINUI::SetTextColor(uint16_t fgcolor) {
- textcolor = fgcolor;
- }
- void DWINUI::SetBackgroundColor(uint16_t bgcolor) {
- backcolor = bgcolor;
- }
-
- // Moves cursor to point
- // x: abscissa of the display
- // y: ordinate of the display
- // point: xy coordinate
- void DWINUI::MoveTo(int16_t x, int16_t y) {
- cursor.x = x;
- cursor.y = y;
- }
- void DWINUI::MoveTo(xy_int_t point) {
- cursor = point;
- }
-
- // Moves cursor relative to the actual position
- // x: abscissa of the display
- // y: ordinate of the display
- // point: xy coordinate
- void DWINUI::MoveBy(int16_t x, int16_t y) {
- cursor.x += x;
- cursor.y += y;
- }
- void DWINUI::MoveBy(xy_int_t point) {
- cursor += point;
- }
-
- // Draw a Centered string using DWIN_WIDTH
- void DWINUI::Draw_CenteredString(bool bShow, uint8_t size, uint16_t color, uint16_t bColor, uint16_t y, const char * const string) {
- const int8_t x = _MAX(0U, DWIN_WIDTH - strlen_P(string) * fontWidth(size)) / 2 - 1;
- DWIN_Draw_String(bShow, size, color, bColor, x, y, string);
- }
-
- // Draw a char at cursor position
- void DWINUI::Draw_Char(const char c) {
- const char string[2] = { c, 0};
- DWIN_Draw_String(false, font, textcolor, backcolor, cursor.x, cursor.y, string, 1);
- MoveBy(fontWidth(font), 0);
- }
-
- // Draw a string at cursor position
- // color: Character color
- // *string: The string
- // rlimit: For draw less chars than string length use rlimit
- void DWINUI::Draw_String(const char * const string, uint16_t rlimit) {
- DWIN_Draw_String(false, font, textcolor, backcolor, cursor.x, cursor.y, string, rlimit);
- MoveBy(strlen(string) * fontWidth(font), 0);
- }
- void DWINUI::Draw_String(uint16_t color, const char * const string, uint16_t rlimit) {
- DWIN_Draw_String(false, font, color, backcolor, cursor.x, cursor.y, string, rlimit);
- MoveBy(strlen(string) * fontWidth(font), 0);
- }
-
- // Draw a signed 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
- // bColor: Background color
- // iNum: Number of whole digits
- // fNum: Number of decimal digits
- // x/y: Upper-left point
- // value: Float value
- void DWINUI::Draw_Signed_Float(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, float value) {
- DWIN_Draw_FloatValue(bShow, zeroFill, zeroMode, size, color, bColor, iNum, fNum, x, y, value < 0 ? -value : value);
- DWIN_Draw_String(bShow, size, color, bColor, x - 6, y, value < 0 ? F("-") : F(" "));
- }
-
- // Draw a circle
- // color: circle color
- // x: the abscissa of the center of the circle
- // y: ordinate of the center of the circle
- // r: circle radius
- void DWINUI::Draw_Circle(uint16_t color, uint16_t x, uint16_t y, uint8_t r) {
- int a = 0, b = 0;
- while (a <= b) {
- b = SQRT(sq(r) - sq(a));
- if (a == 0) b--;
- DWIN_Draw_Point(color, 1, 1, x + a, y + b); // Draw some sector 1
- DWIN_Draw_Point(color, 1, 1, x + b, y + a); // Draw some sector 2
- DWIN_Draw_Point(color, 1, 1, x + b, y - a); // Draw some sector 3
- DWIN_Draw_Point(color, 1, 1, x + a, y - b); // Draw some sector 4
- DWIN_Draw_Point(color, 1, 1, x - a, y - b); // Draw some sector 5
- DWIN_Draw_Point(color, 1, 1, x - b, y - a); // Draw some sector 6
- DWIN_Draw_Point(color, 1, 1, x - b, y + a); // Draw some sector 7
- DWIN_Draw_Point(color, 1, 1, x - a, y + b); // Draw some sector 8
- a++;
- }
- }
-
- // Draw a circle filled with color
- // bcolor: fill color
- // x: the abscissa of the center of the circle
- // y: ordinate of the center of the circle
- // r: circle radius
- void DWINUI::Draw_FillCircle(uint16_t bcolor, uint16_t x,uint16_t y,uint8_t r) {
- int a = 0, b = 0;
- while (a <= b) {
- b = SQRT(sq(r) - sq(a)); // b=sqrt(r*r-a*a);
- if (a == 0) b--;
- DWIN_Draw_Line(bcolor, x-b,y-a,x+b,y-a);
- DWIN_Draw_Line(bcolor, x-a,y-b,x+a,y-b);
- DWIN_Draw_Line(bcolor, x-b,y+a,x+b,y+a);
- DWIN_Draw_Line(bcolor, x-a,y+b,x+a,y+b);
- a++;
- }
- }
-
- // Color Interpolator
- // val : Interpolator minv..maxv
- // minv : Minimum value
- // maxv : Maximum value
- // color1 : Start color
- // color2 : End color
- uint16_t DWINUI::ColorInt(int16_t val, int16_t minv, int16_t maxv, uint16_t color1, uint16_t color2) {
- uint8_t B,G,R;
- float n;
- n = (float)(val-minv)/(maxv-minv);
- R = (1-n)*GetRColor(color1) + n*GetRColor(color2);
- G = (1-n)*GetGColor(color1) + n*GetGColor(color2);
- B = (1-n)*GetBColor(color1) + n*GetBColor(color2);
- return RGB(R,G,B);
- }
-
- // Color Interpolator through Red->Yellow->Green->Blue
- // val : Interpolator minv..maxv
- // minv : Minimum value
- // maxv : Maximum value
- uint16_t DWINUI::RainbowInt(int16_t val, int16_t minv, int16_t maxv) {
- uint8_t B,G,R;
- const uint8_t maxB = 28;
- const uint8_t maxR = 28;
- const uint8_t maxG = 38;
- const int16_t limv = _MAX(abs(minv), abs(maxv));
- float n;
- if (minv>=0) {
- n = (float)(val-minv)/(maxv-minv);
- } else {
- n = (float)val/limv;
- }
- n = _MIN(1, n);
- n = _MAX(-1, n);
- if (n < 0) {
- R = 0;
- G = (1+n)*maxG;
- B = (-n)*maxB;
- } else if (n < 0.5) {
- R = maxR*n*2;
- G = maxG;
- B = 0;
- } else {
- R = maxR;
- G = maxG*(1-n);
- B = 0;
- }
- return RGB(R,G,B);
- }
-
- // Draw a checkbox
- // Color: frame color
- // bColor: Background color
- // x/y: Upper-left point
- // mode : 0 : unchecked, 1 : checked
- void DWINUI::Draw_Checkbox(uint16_t color, uint16_t bcolor, uint16_t x, uint16_t y, bool checked=false) {
- DWIN_Draw_String(true, font8x16, color, bcolor, x + 4, y, checked ? F("x") : F(" "));
- DWIN_Draw_Rectangle(0, color, x + 2, y + 2, x + 17, y + 17);
- }
-
- // Clear Menu by filling the menu area with background color
- void DWINUI::ClearMenuArea() {
- DWIN_Draw_Rectangle(1, backcolor, 0, TITLE_HEIGHT, DWIN_WIDTH - 1, STATUS_Y - 1);
- }
-
- void DWINUI::MenuItemsClear() {
- if (MenuItems == nullptr) return;
- for (uint8_t i = 0; i < MenuItemCount; i++) delete MenuItems[i];
- delete[] MenuItems;
- MenuItems = nullptr;
- MenuItemCount = 0;
- MenuItemTotal = 0;
- }
-
- void DWINUI::MenuItemsPrepare(uint8_t totalitems) {
- MenuItemsClear();
- MenuItemTotal = totalitems;
- MenuItems = new MenuItemClass*[totalitems];
- }
-
- MenuItemClass* DWINUI::MenuItemsAdd(MenuItemClass* menuitem) {
- if (MenuItemCount < MenuItemTotal) {
- MenuItems[MenuItemCount] = menuitem;
- menuitem->pos = MenuItemCount++;
- return menuitem;
- }
- else {
- delete menuitem;
- return nullptr;
- }
- }
-
- /* Title Class ==============================================================*/
-
- TitleClass Title;
-
- void TitleClass::draw() {
- if (DWINUI::onTitleDraw != nullptr) (*DWINUI::onTitleDraw)(this);
- }
-
- void TitleClass::SetCaption(const char * const title) {
- frameid = 0;
- if ( caption == title ) return;
- const uint8_t len = _MIN(sizeof(caption) - 1, strlen(title));
- memcpy(&caption[0], title, len);
- caption[len] = '\0';
- }
-
- void TitleClass::ShowCaption(const char * const title) {
- SetCaption(title);
- draw();
- }
-
- void TitleClass::SetFrame(uint8_t id, uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2) {
- caption[0] = '\0';
- frameid = id;
- frame = { x1, y1, x2, y2 };
- }
-
- void TitleClass::SetFrame(uint16_t x, uint16_t y, uint16_t w, uint16_t h) {
- SetFrame(1, x, y, x + w - 1, y + h - 1);
- }
-
- void TitleClass::FrameCopy(uint8_t id, uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2) {
- SetFrame(id, x1, y1, x2, y2);
- draw();
- }
-
- void TitleClass::FrameCopy(uint16_t x, uint16_t y, uint16_t w, uint16_t h) {
- FrameCopy(1, x, y, x + w - 1, y + h - 1);
- }
-
- /* Menu Class ===============================================================*/
-
- MenuClass::MenuClass() {
- selected = 0;
- topline = 0;
- }
-
- void MenuClass::draw() {
- MenuTitle.draw();
- if (DWINUI::onMenuDraw != nullptr) (*DWINUI::onMenuDraw)(this);
- for (uint8_t i = 0; i < MenuItemCount; i++)
- MenuItems[i]->draw(i - topline);
- if (DWINUI::onCursorDraw != nullptr) DWINUI::onCursorDraw(line());
- DWIN_UpdateLCD();
- }
-
- void MenuClass::onScroll(bool dir) {
- int8_t sel = selected;
- if (dir) sel++; else sel--;
- LIMIT(sel, 0, MenuItemCount - 1);
- if (sel != selected) {
- if (DWINUI::onCursorErase != nullptr) DWINUI::onCursorErase(line());
- if ((sel - topline) == TROWS) {
- DWIN_Frame_AreaMove(1, DWIN_SCROLL_UP, MLINE, DWINUI::backcolor, 0, TITLE_HEIGHT + 1, DWIN_WIDTH, STATUS_Y - 1);
- topline++;
- MenuItems[sel]->draw(TROWS - 1);
- }
- if ((sel < topline)) {
- DWIN_Frame_AreaMove(1, DWIN_SCROLL_DOWN, MLINE, DWINUI::backcolor, 0, TITLE_HEIGHT + 1, DWIN_WIDTH, STATUS_Y - 1);
- topline--;
- MenuItems[sel]->draw(0);
- }
- selected = sel;
- if (DWINUI::onCursorDraw != nullptr) DWINUI::onCursorDraw(line());
- DWIN_UpdateLCD();
- }
- }
-
- void MenuClass::onClick() {
- if (MenuItems[selected]->onClick != nullptr) (*MenuItems[selected]->onClick)();
- }
-
- MenuItemClass *MenuClass::SelectedItem() {
- return MenuItems[selected];
- }
-
- /* MenuItem Class ===========================================================*/
-
- MenuItemClass::MenuItemClass(uint8_t cicon, const char * const text, void (*ondraw)(MenuItemClass* menuitem, int8_t line), void (*onclick)()) {
- icon = cicon;
- onClick = onclick;
- onDraw = ondraw;
- const uint8_t len = _MIN(sizeof(caption) - 1, strlen(text));
- memcpy(&caption[0], text, len);
- caption[len] = '\0';
- }
-
- MenuItemClass::MenuItemClass(uint8_t cicon, uint8_t id, uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, void (*ondraw)(MenuItemClass* menuitem, int8_t line), void (*onclick)()) {
- icon = cicon;
- onClick = onclick;
- onDraw = ondraw;
- caption[0] = '\0';
- frameid = id;
- frame = { x1, y1, x2, y2 };
- }
-
- void MenuItemClass::SetFrame(uint8_t id, uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2) {
- caption[0] = '\0';
- frameid = id;
- frame = { x1, y1, x2, y2 };
- }
-
- void MenuItemClass::draw(int8_t line) {
- if (line < 0 || line >= TROWS) return;
- if (onDraw != nullptr) (*onDraw)(this, line);
- };
-
- MenuItemPtrClass::MenuItemPtrClass(uint8_t cicon, const char * const text, void (*ondraw)(MenuItemClass* menuitem, int8_t line), void (*onclick)(), void* val) : MenuItemClass(cicon, text, ondraw, onclick) {
- value = val;
- };
-
- #endif // DWIN_CREALITY_LCD_ENHANCED
|