My Marlin configs for Fabrikator Mini and CTC i3 Pro B
Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

dwinui.cpp 14KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453
  1. /**
  2. * Marlin 3D Printer Firmware
  3. * Copyright (c) 2021 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
  4. *
  5. * Based on Sprinter and grbl.
  6. * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
  7. *
  8. * This program is free software: you can redistribute it and/or modify
  9. * it under the terms of the GNU General Public License as published by
  10. * the Free Software Foundation, either version 3 of the License, or
  11. * (at your option) any later version.
  12. *
  13. * This program is distributed in the hope that it will be useful,
  14. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. * GNU General Public License for more details.
  17. *
  18. * You should have received a copy of the GNU General Public License
  19. * along with this program. If not, see <https://www.gnu.org/licenses/>.
  20. *
  21. */
  22. /**
  23. * DWIN UI Enhanced implementation
  24. * Author: Miguel A. Risco-Castillo
  25. * Version: 3.6.3
  26. * Date: 2021/09/08
  27. */
  28. #include "../../../inc/MarlinConfigPre.h"
  29. #if ENABLED(DWIN_CREALITY_LCD_ENHANCED)
  30. #include "../../../inc/MarlinConfig.h"
  31. #include "dwin_lcd.h"
  32. #include "dwinui.h"
  33. //#define DEBUG_OUT 1
  34. #include "../../../core/debug_out.h"
  35. uint8_t MenuItemTotal = 0;
  36. uint8_t MenuItemCount = 0;
  37. MenuItemClass** MenuItems = nullptr;
  38. MenuClass *CurrentMenu = nullptr;
  39. MenuClass *PreviousMenu = nullptr;
  40. xy_int_t DWINUI::cursor = { 0 };
  41. uint16_t DWINUI::pencolor = Color_White;
  42. uint16_t DWINUI::textcolor = Def_Text_Color;
  43. uint16_t DWINUI::backcolor = Def_Background_Color;
  44. uint8_t DWINUI::font = font8x16;
  45. void (*DWINUI::onCursorErase)(uint8_t line)=nullptr;
  46. void (*DWINUI::onCursorDraw)(uint8_t line)=nullptr;
  47. void (*DWINUI::onTitleDraw)(TitleClass* title)=nullptr;
  48. void (*DWINUI::onMenuDraw)(MenuClass* menu)=nullptr;
  49. void DWINUI::init() {
  50. DEBUG_ECHOPGM("\r\nDWIN handshake ");
  51. delay(750); // Delay here or init later in the boot process
  52. const bool success = DWIN_Handshake();
  53. if (success) DEBUG_ECHOLNPGM("ok."); else DEBUG_ECHOLNPGM("error.");
  54. DWIN_Frame_SetDir(1);
  55. TERN(SHOW_BOOTSCREEN,,DWIN_Frame_Clear(Color_Bg_Black));
  56. DWIN_UpdateLCD();
  57. cursor.x = 0;
  58. cursor.y = 0;
  59. pencolor = Color_White;
  60. textcolor = Def_Text_Color;
  61. backcolor = Def_Background_Color;
  62. font = font8x16;
  63. }
  64. // Set text/number font
  65. void DWINUI::setFont(uint8_t cfont) {
  66. font = cfont;
  67. }
  68. // Get font character width
  69. uint8_t DWINUI::fontWidth(uint8_t cfont) {
  70. switch (cfont) {
  71. case font6x12 : return 6;
  72. case font8x16 : return 8;
  73. case font10x20: return 10;
  74. case font12x24: return 12;
  75. case font14x28: return 14;
  76. case font16x32: return 16;
  77. case font20x40: return 20;
  78. case font24x48: return 24;
  79. case font28x56: return 28;
  80. case font32x64: return 32;
  81. default: return 0;
  82. }
  83. }
  84. // Get font character heigh
  85. uint8_t DWINUI::fontHeight(uint8_t cfont) {
  86. switch (cfont) {
  87. case font6x12 : return 12;
  88. case font8x16 : return 16;
  89. case font10x20: return 20;
  90. case font12x24: return 24;
  91. case font14x28: return 28;
  92. case font16x32: return 32;
  93. case font20x40: return 40;
  94. case font24x48: return 48;
  95. case font28x56: return 56;
  96. case font32x64: return 64;
  97. default: return 0;
  98. }
  99. }
  100. // Get screen x coodinates from text column
  101. uint16_t DWINUI::ColToX(uint8_t col) {
  102. return col * fontWidth(font);
  103. }
  104. // Get screen y coodinates from text row
  105. uint16_t DWINUI::RowToY(uint8_t row) {
  106. return row * fontHeight(font);
  107. }
  108. // Set text/number color
  109. void DWINUI::SetColors(uint16_t fgcolor, uint16_t bgcolor) {
  110. textcolor = fgcolor;
  111. backcolor = bgcolor;
  112. }
  113. void DWINUI::SetTextColor(uint16_t fgcolor) {
  114. textcolor = fgcolor;
  115. }
  116. void DWINUI::SetBackgroundColor(uint16_t bgcolor) {
  117. backcolor = bgcolor;
  118. }
  119. // Moves cursor to point
  120. // x: abscissa of the display
  121. // y: ordinate of the display
  122. // point: xy coordinate
  123. void DWINUI::MoveTo(int16_t x, int16_t y) {
  124. cursor.x = x;
  125. cursor.y = y;
  126. }
  127. void DWINUI::MoveTo(xy_int_t point) {
  128. cursor = point;
  129. }
  130. // Moves cursor relative to the actual position
  131. // x: abscissa of the display
  132. // y: ordinate of the display
  133. // point: xy coordinate
  134. void DWINUI::MoveBy(int16_t x, int16_t y) {
  135. cursor.x += x;
  136. cursor.y += y;
  137. }
  138. void DWINUI::MoveBy(xy_int_t point) {
  139. cursor += point;
  140. }
  141. // Draw a Centered string using DWIN_WIDTH
  142. void DWINUI::Draw_CenteredString(bool bShow, uint8_t size, uint16_t color, uint16_t bColor, uint16_t y, const char * const string) {
  143. const int8_t x = _MAX(0U, DWIN_WIDTH - strlen_P(string) * fontWidth(size)) / 2 - 1;
  144. DWIN_Draw_String(bShow, size, color, bColor, x, y, string);
  145. }
  146. // Draw a char at cursor position
  147. void DWINUI::Draw_Char(const char c) {
  148. const char string[2] = { c, 0};
  149. DWIN_Draw_String(false, font, textcolor, backcolor, cursor.x, cursor.y, string, 1);
  150. MoveBy(fontWidth(font), 0);
  151. }
  152. // Draw a string at cursor position
  153. // color: Character color
  154. // *string: The string
  155. // rlimit: For draw less chars than string length use rlimit
  156. void DWINUI::Draw_String(const char * const string, uint16_t rlimit) {
  157. DWIN_Draw_String(false, font, textcolor, backcolor, cursor.x, cursor.y, string, rlimit);
  158. MoveBy(strlen(string) * fontWidth(font), 0);
  159. }
  160. void DWINUI::Draw_String(uint16_t color, const char * const string, uint16_t rlimit) {
  161. DWIN_Draw_String(false, font, color, backcolor, cursor.x, cursor.y, string, rlimit);
  162. MoveBy(strlen(string) * fontWidth(font), 0);
  163. }
  164. // Draw a signed floating point number
  165. // bShow: true=display background color; false=don't display background color
  166. // zeroFill: true=zero fill; false=no zero fill
  167. // zeroMode: 1=leading 0 displayed as 0; 0=leading 0 displayed as a space
  168. // size: Font size
  169. // bColor: Background color
  170. // iNum: Number of whole digits
  171. // fNum: Number of decimal digits
  172. // x/y: Upper-left point
  173. // value: Float value
  174. 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) {
  175. DWIN_Draw_FloatValue(bShow, zeroFill, zeroMode, size, color, bColor, iNum, fNum, x, y, value < 0 ? -value : value);
  176. DWIN_Draw_String(bShow, size, color, bColor, x - 6, y, value < 0 ? F("-") : F(" "));
  177. }
  178. // Draw a circle
  179. // color: circle color
  180. // x: the abscissa of the center of the circle
  181. // y: ordinate of the center of the circle
  182. // r: circle radius
  183. void DWINUI::Draw_Circle(uint16_t color, uint16_t x, uint16_t y, uint8_t r) {
  184. int a = 0, b = 0;
  185. while (a <= b) {
  186. b = SQRT(sq(r) - sq(a));
  187. if (a == 0) b--;
  188. DWIN_Draw_Point(color, 1, 1, x + a, y + b); // Draw some sector 1
  189. DWIN_Draw_Point(color, 1, 1, x + b, y + a); // Draw some sector 2
  190. DWIN_Draw_Point(color, 1, 1, x + b, y - a); // Draw some sector 3
  191. DWIN_Draw_Point(color, 1, 1, x + a, y - b); // Draw some sector 4
  192. DWIN_Draw_Point(color, 1, 1, x - a, y - b); // Draw some sector 5
  193. DWIN_Draw_Point(color, 1, 1, x - b, y - a); // Draw some sector 6
  194. DWIN_Draw_Point(color, 1, 1, x - b, y + a); // Draw some sector 7
  195. DWIN_Draw_Point(color, 1, 1, x - a, y + b); // Draw some sector 8
  196. a++;
  197. }
  198. }
  199. // Draw a circle filled with color
  200. // bcolor: fill color
  201. // x: the abscissa of the center of the circle
  202. // y: ordinate of the center of the circle
  203. // r: circle radius
  204. void DWINUI::Draw_FillCircle(uint16_t bcolor, uint16_t x,uint16_t y,uint8_t r) {
  205. int a = 0, b = 0;
  206. while (a <= b) {
  207. b = SQRT(sq(r) - sq(a)); // b=sqrt(r*r-a*a);
  208. if (a == 0) b--;
  209. DWIN_Draw_Line(bcolor, x-b,y-a,x+b,y-a);
  210. DWIN_Draw_Line(bcolor, x-a,y-b,x+a,y-b);
  211. DWIN_Draw_Line(bcolor, x-b,y+a,x+b,y+a);
  212. DWIN_Draw_Line(bcolor, x-a,y+b,x+a,y+b);
  213. a++;
  214. }
  215. }
  216. // Color Interpolator
  217. // val : Interpolator minv..maxv
  218. // minv : Minimum value
  219. // maxv : Maximum value
  220. // color1 : Start color
  221. // color2 : End color
  222. uint16_t DWINUI::ColorInt(int16_t val, int16_t minv, int16_t maxv, uint16_t color1, uint16_t color2) {
  223. uint8_t B,G,R;
  224. float n;
  225. n = (float)(val-minv)/(maxv-minv);
  226. R = (1-n)*GetRColor(color1) + n*GetRColor(color2);
  227. G = (1-n)*GetGColor(color1) + n*GetGColor(color2);
  228. B = (1-n)*GetBColor(color1) + n*GetBColor(color2);
  229. return RGB(R,G,B);
  230. }
  231. // Color Interpolator through Red->Yellow->Green->Blue
  232. // val : Interpolator minv..maxv
  233. // minv : Minimum value
  234. // maxv : Maximum value
  235. uint16_t DWINUI::RainbowInt(int16_t val, int16_t minv, int16_t maxv) {
  236. uint8_t B,G,R;
  237. const uint8_t maxB = 28;
  238. const uint8_t maxR = 28;
  239. const uint8_t maxG = 38;
  240. const int16_t limv = _MAX(abs(minv), abs(maxv));
  241. float n;
  242. if (minv>=0) {
  243. n = (float)(val-minv)/(maxv-minv);
  244. } else {
  245. n = (float)val/limv;
  246. }
  247. n = _MIN(1, n);
  248. n = _MAX(-1, n);
  249. if (n < 0) {
  250. R = 0;
  251. G = (1+n)*maxG;
  252. B = (-n)*maxB;
  253. } else if (n < 0.5) {
  254. R = maxR*n*2;
  255. G = maxG;
  256. B = 0;
  257. } else {
  258. R = maxR;
  259. G = maxG*(1-n);
  260. B = 0;
  261. }
  262. return RGB(R,G,B);
  263. }
  264. // Draw a checkbox
  265. // Color: frame color
  266. // bColor: Background color
  267. // x/y: Upper-left point
  268. // mode : 0 : unchecked, 1 : checked
  269. void DWINUI::Draw_Checkbox(uint16_t color, uint16_t bcolor, uint16_t x, uint16_t y, bool checked=false) {
  270. DWIN_Draw_String(true, font8x16, color, bcolor, x + 4, y, checked ? F("x") : F(" "));
  271. DWIN_Draw_Rectangle(0, color, x + 2, y + 2, x + 17, y + 17);
  272. }
  273. // Clear Menu by filling the menu area with background color
  274. void DWINUI::ClearMenuArea() {
  275. DWIN_Draw_Rectangle(1, backcolor, 0, TITLE_HEIGHT, DWIN_WIDTH - 1, STATUS_Y - 1);
  276. }
  277. void DWINUI::MenuItemsClear() {
  278. if (MenuItems == nullptr) return;
  279. for (uint8_t i = 0; i < MenuItemCount; i++) delete MenuItems[i];
  280. delete[] MenuItems;
  281. MenuItems = nullptr;
  282. MenuItemCount = 0;
  283. MenuItemTotal = 0;
  284. }
  285. void DWINUI::MenuItemsPrepare(uint8_t totalitems) {
  286. MenuItemsClear();
  287. MenuItemTotal = totalitems;
  288. MenuItems = new MenuItemClass*[totalitems];
  289. }
  290. MenuItemClass* DWINUI::MenuItemsAdd(MenuItemClass* menuitem) {
  291. if (MenuItemCount < MenuItemTotal) {
  292. MenuItems[MenuItemCount] = menuitem;
  293. menuitem->pos = MenuItemCount++;
  294. return menuitem;
  295. }
  296. else {
  297. delete menuitem;
  298. return nullptr;
  299. }
  300. }
  301. /* Title Class ==============================================================*/
  302. TitleClass Title;
  303. void TitleClass::draw() {
  304. if (DWINUI::onTitleDraw != nullptr) (*DWINUI::onTitleDraw)(this);
  305. }
  306. void TitleClass::SetCaption(const char * const title) {
  307. frameid = 0;
  308. if ( caption == title ) return;
  309. const uint8_t len = _MIN(sizeof(caption) - 1, strlen(title));
  310. memcpy(&caption[0], title, len);
  311. caption[len] = '\0';
  312. }
  313. void TitleClass::ShowCaption(const char * const title) {
  314. SetCaption(title);
  315. draw();
  316. }
  317. void TitleClass::SetFrame(uint8_t id, uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2) {
  318. caption[0] = '\0';
  319. frameid = id;
  320. frame = { x1, y1, x2, y2 };
  321. }
  322. void TitleClass::SetFrame(uint16_t x, uint16_t y, uint16_t w, uint16_t h) {
  323. SetFrame(1, x, y, x + w - 1, y + h - 1);
  324. }
  325. void TitleClass::FrameCopy(uint8_t id, uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2) {
  326. SetFrame(id, x1, y1, x2, y2);
  327. draw();
  328. }
  329. void TitleClass::FrameCopy(uint16_t x, uint16_t y, uint16_t w, uint16_t h) {
  330. FrameCopy(1, x, y, x + w - 1, y + h - 1);
  331. }
  332. /* Menu Class ===============================================================*/
  333. MenuClass::MenuClass() {
  334. selected = 0;
  335. topline = 0;
  336. }
  337. void MenuClass::draw() {
  338. MenuTitle.draw();
  339. if (DWINUI::onMenuDraw != nullptr) (*DWINUI::onMenuDraw)(this);
  340. for (uint8_t i = 0; i < MenuItemCount; i++)
  341. MenuItems[i]->draw(i - topline);
  342. if (DWINUI::onCursorDraw != nullptr) DWINUI::onCursorDraw(line());
  343. DWIN_UpdateLCD();
  344. }
  345. void MenuClass::onScroll(bool dir) {
  346. int8_t sel = selected;
  347. if (dir) sel++; else sel--;
  348. LIMIT(sel, 0, MenuItemCount - 1);
  349. if (sel != selected) {
  350. if (DWINUI::onCursorErase != nullptr) DWINUI::onCursorErase(line());
  351. if ((sel - topline) == TROWS) {
  352. DWIN_Frame_AreaMove(1, DWIN_SCROLL_UP, MLINE, DWINUI::backcolor, 0, TITLE_HEIGHT + 1, DWIN_WIDTH, STATUS_Y - 1);
  353. topline++;
  354. MenuItems[sel]->draw(TROWS - 1);
  355. }
  356. if ((sel < topline)) {
  357. DWIN_Frame_AreaMove(1, DWIN_SCROLL_DOWN, MLINE, DWINUI::backcolor, 0, TITLE_HEIGHT + 1, DWIN_WIDTH, STATUS_Y - 1);
  358. topline--;
  359. MenuItems[sel]->draw(0);
  360. }
  361. selected = sel;
  362. if (DWINUI::onCursorDraw != nullptr) DWINUI::onCursorDraw(line());
  363. DWIN_UpdateLCD();
  364. }
  365. }
  366. void MenuClass::onClick() {
  367. if (MenuItems[selected]->onClick != nullptr) (*MenuItems[selected]->onClick)();
  368. }
  369. MenuItemClass *MenuClass::SelectedItem() {
  370. return MenuItems[selected];
  371. }
  372. /* MenuItem Class ===========================================================*/
  373. MenuItemClass::MenuItemClass(uint8_t cicon, const char * const text, void (*ondraw)(MenuItemClass* menuitem, int8_t line), void (*onclick)()) {
  374. icon = cicon;
  375. onClick = onclick;
  376. onDraw = ondraw;
  377. const uint8_t len = _MIN(sizeof(caption) - 1, strlen(text));
  378. memcpy(&caption[0], text, len);
  379. caption[len] = '\0';
  380. }
  381. 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)()) {
  382. icon = cicon;
  383. onClick = onclick;
  384. onDraw = ondraw;
  385. caption[0] = '\0';
  386. frameid = id;
  387. frame = { x1, y1, x2, y2 };
  388. }
  389. void MenuItemClass::SetFrame(uint8_t id, uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2) {
  390. caption[0] = '\0';
  391. frameid = id;
  392. frame = { x1, y1, x2, y2 };
  393. }
  394. void MenuItemClass::draw(int8_t line) {
  395. if (line < 0 || line >= TROWS) return;
  396. if (onDraw != nullptr) (*onDraw)(this, line);
  397. };
  398. 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) {
  399. value = val;
  400. };
  401. #endif // DWIN_CREALITY_LCD_ENHANCED