My Marlin configs for Fabrikator Mini and CTC i3 Pro B
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

bio_status_screen.cpp 9.3KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323
  1. /*************************
  2. * bio_status_screen.cpp *
  3. *************************/
  4. /****************************************************************************
  5. * Written By Mark Pelletier 2017 - Aleph Objects, Inc. *
  6. * Written By Marcio Teixeira 2018 - Aleph Objects, Inc. *
  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. * To view a copy of the GNU General Public License, go to the following *
  19. * location: <http://www.gnu.org/licenses/>. *
  20. ****************************************************************************/
  21. #include "../config.h"
  22. #if ENABLED(LULZBOT_TOUCH_UI) && defined(LULZBOT_USE_BIOPRINTER_UI)
  23. #include "screens.h"
  24. #include "../ftdi_eve_lib/extras/poly_ui.h"
  25. #include "bio_printer_ui.h"
  26. #define E_TRAVEL_LIMIT 60
  27. #define GRID_COLS 2
  28. #define GRID_ROWS 9
  29. #define POLY(A) PolyUI::poly_reader_t(A, sizeof(A)/sizeof(A[0]))
  30. const uint8_t shadow_depth = 5;
  31. using namespace FTDI;
  32. using namespace Theme;
  33. using namespace ExtUI;
  34. float StatusScreen::increment;
  35. bool StatusScreen::jog_xy;
  36. bool StatusScreen::fine_motion;
  37. void StatusScreen::unlockMotors() {
  38. injectCommands_P(PSTR("M84 XY"));
  39. jog_xy = false;
  40. }
  41. void StatusScreen::draw_temperature(draw_mode_t what) {
  42. CommandProcessor cmd;
  43. PolyUI ui(cmd, what);
  44. int16_t x, y, h, v;
  45. cmd.tag(15);
  46. if (what & BACKGROUND) {
  47. cmd.cmd(COLOR_RGB(bg_color));
  48. // Draw touch surfaces
  49. ui.bounds(POLY(target_temp), x, y, h, v);
  50. cmd.rectangle(x, y, h, v);
  51. ui.bounds(POLY(actual_temp), x, y, h, v);
  52. cmd.rectangle(x, y, h, v);
  53. ui.bounds(POLY(bed_icon), x, y, h, v);
  54. cmd.rectangle(x, y, h, v);
  55. // Draw bed icon
  56. cmd.cmd(BITMAP_SOURCE(Bed_Heat_Icon_Info))
  57. .cmd(BITMAP_LAYOUT(Bed_Heat_Icon_Info))
  58. .cmd(BITMAP_SIZE (Bed_Heat_Icon_Info))
  59. .cmd(COLOR_RGB(shadow_rgb))
  60. .icon (x + 2, y + 2, h, v, Bed_Heat_Icon_Info, icon_scale * 2)
  61. .cmd(COLOR_RGB(bg_text_enabled))
  62. .icon (x, y, h, v, Bed_Heat_Icon_Info, icon_scale * 2);
  63. #ifdef TOUCH_UI_USE_UTF8
  64. load_utf8_bitmaps(cmd); // Restore font bitmap handles
  65. #endif
  66. }
  67. if (what & FOREGROUND) {
  68. char bed_str[15];
  69. cmd.font(font_xlarge)
  70. .cmd(COLOR_RGB(bg_text_enabled));
  71. if (!isHeaterIdle(BED) && getTargetTemp_celsius(BED) > 0) {
  72. format_temp(bed_str, getTargetTemp_celsius(BED));
  73. ui.bounds(POLY(target_temp), x, y, h, v);
  74. cmd.text(x, y, h, v, bed_str);
  75. }
  76. format_temp(bed_str, getActualTemp_celsius(BED));
  77. ui.bounds(POLY(actual_temp), x, y, h, v);
  78. cmd.text(x, y, h, v, bed_str);
  79. }
  80. }
  81. void StatusScreen::draw_syringe(draw_mode_t what) {
  82. int16_t x, y, h, v;
  83. const float fill_level = 1.0 - min(1.0, max(0.0, getAxisPosition_mm(E0) / E_TRAVEL_LIMIT));
  84. const bool e_homed = isAxisPositionKnown(E0);
  85. CommandProcessor cmd;
  86. PolyUI ui(cmd, what);
  87. if (what & BACKGROUND) {
  88. // Paint the shadow for the syringe
  89. ui.color(shadow_rgb);
  90. ui.shadow(POLY(syringe_outline), shadow_depth);
  91. }
  92. if (what & FOREGROUND && e_homed) {
  93. // Paint the syringe icon
  94. ui.color(syringe_rgb);
  95. ui.fill(POLY(syringe_outline));
  96. ui.color(fill_rgb);
  97. ui.bounds(POLY(syringe_fluid), x, y, h, v);
  98. cmd.cmd(SAVE_CONTEXT());
  99. cmd.cmd(SCISSOR_XY(x,y + v * (1.0 - fill_level)));
  100. cmd.cmd(SCISSOR_SIZE(h, v * fill_level));
  101. ui.fill(POLY(syringe_fluid), false);
  102. cmd.cmd(RESTORE_CONTEXT());
  103. ui.color(stroke_rgb);
  104. ui.fill(POLY(syringe));
  105. }
  106. }
  107. void StatusScreen::draw_arrows(draw_mode_t what) {
  108. const bool e_homed = isAxisPositionKnown(E0);
  109. const bool z_homed = isAxisPositionKnown(Z);
  110. CommandProcessor cmd;
  111. PolyUI ui(cmd, what);
  112. ui.button_fill (fill_rgb);
  113. ui.button_stroke(stroke_rgb, 28);
  114. ui.button_shadow(shadow_rgb, shadow_depth);
  115. if ((what & BACKGROUND) || jog_xy) {
  116. ui.button(1, POLY(x_neg));
  117. ui.button(2, POLY(x_pos));
  118. ui.button(3, POLY(y_neg));
  119. ui.button(4, POLY(y_pos));
  120. }
  121. if ((what & BACKGROUND) || z_homed) {
  122. ui.button(5, POLY(z_neg));
  123. ui.button(6, POLY(z_pos));
  124. }
  125. if ((what & BACKGROUND) || e_homed) {
  126. ui.button(7, POLY(e_neg));
  127. ui.button(8, POLY(e_pos));
  128. }
  129. }
  130. void StatusScreen::draw_fine_motion(draw_mode_t what) {
  131. int16_t x, y, h, v;
  132. CommandProcessor cmd;
  133. PolyUI ui(cmd, what);
  134. cmd.font(font_medium)
  135. .tag(16);
  136. if (what & BACKGROUND) {
  137. ui.bounds(POLY(fine_label), x, y, h, v);
  138. cmd.cmd(COLOR_RGB(bg_text_enabled))
  139. .text(x, y, h, v, GET_TEXTF(FINE_MOTION));
  140. }
  141. if (what & FOREGROUND) {
  142. ui.bounds(POLY(fine_toggle), x, y, h, v);
  143. cmd.colors(ui_toggle)
  144. .toggle2(x, y, h, v, GET_TEXTF(NO), GET_TEXTF(YES), fine_motion);
  145. }
  146. }
  147. void StatusScreen::draw_overlay_icons(draw_mode_t what) {
  148. const bool e_homed = isAxisPositionKnown(E0);
  149. const bool z_homed = isAxisPositionKnown(Z);
  150. CommandProcessor cmd;
  151. PolyUI ui(cmd, what);
  152. if (what & FOREGROUND) {
  153. ui.button_fill (fill_rgb);
  154. ui.button_stroke(stroke_rgb, 28);
  155. ui.button_shadow(shadow_rgb, shadow_depth);
  156. if (!jog_xy) ui.button(12, POLY(padlock));
  157. if (!e_homed) ui.button(13, POLY(home_e));
  158. if (!z_homed) ui.button(14, POLY(home_z));
  159. }
  160. }
  161. void StatusScreen::draw_buttons(draw_mode_t) {
  162. const bool has_media = isMediaInserted() && !isPrintingFromMedia();
  163. CommandProcessor cmd;
  164. cmd.font(font_medium)
  165. .colors(normal_btn)
  166. .enabled(has_media)
  167. .colors(has_media ? action_btn : normal_btn)
  168. .tag(9).button(BTN_POS(1,9), BTN_SIZE(1,1),
  169. isPrintingFromMedia() ?
  170. GET_TEXTF(PRINTING) :
  171. GET_TEXTF(MEDIA)
  172. );
  173. cmd.colors(!has_media ? action_btn : normal_btn).tag(10).button(BTN_POS(2,9), BTN_SIZE(1,1), GET_TEXTF(MENU));
  174. }
  175. void StatusScreen::loadBitmaps() {
  176. // Load the bitmaps for the status screen
  177. constexpr uint32_t base = ftdi_memory_map::RAM_G;
  178. CLCD::mem_write_pgm(base + Bed_Heat_Icon_Info.RAMG_offset, Bed_Heat_Icon, sizeof(Bed_Heat_Icon));
  179. // Load fonts for internationalization
  180. #ifdef TOUCH_UI_USE_UTF8
  181. load_utf8_data(base + UTF8_FONT_OFFSET);
  182. #endif
  183. }
  184. void StatusScreen::onRedraw(draw_mode_t what) {
  185. if (what & BACKGROUND) {
  186. CommandProcessor cmd;
  187. cmd.cmd(CLEAR_COLOR_RGB(bg_color));
  188. cmd.cmd(CLEAR(true,true,true));
  189. }
  190. draw_syringe(what);
  191. draw_temperature(what);
  192. draw_arrows(what);
  193. draw_overlay_icons(what);
  194. draw_buttons(what);
  195. draw_fine_motion(what);
  196. }
  197. bool StatusScreen::onTouchStart(uint8_t) {
  198. increment = fine_motion ? 0.25 : 1;
  199. return true;
  200. }
  201. bool StatusScreen::onTouchEnd(uint8_t tag) {
  202. switch (tag) {
  203. case 1:
  204. case 2:
  205. case 3:
  206. case 4:
  207. case 12:
  208. if (!jog_xy) {
  209. jog_xy = true;
  210. injectCommands_P(PSTR("M17"));
  211. }
  212. break;
  213. case 9: GOTO_SCREEN(FilesScreen); break;
  214. case 10: GOTO_SCREEN(MainMenu); break;
  215. case 13: SpinnerDialogBox::enqueueAndWait_P(F("G112")); break;
  216. case 14: SpinnerDialogBox::enqueueAndWait_P(F("G28 Z")); break;
  217. case 15: GOTO_SCREEN(TemperatureScreen); break;
  218. case 16: fine_motion = !fine_motion; break;
  219. default: return false;
  220. }
  221. // If a passcode is enabled, the LockScreen will prevent the
  222. // user from proceeding.
  223. LockScreen::check_passcode();
  224. return true;
  225. }
  226. bool StatusScreen::onTouchHeld(uint8_t tag) {
  227. if (tag >= 1 && tag <= 4 && !jog_xy) return false;
  228. if (ExtUI::isMoving()) return false; // Don't allow moves to accumulate
  229. #define UI_INCREMENT_AXIS(axis) MoveAxisScreen::setManualFeedrate(axis, increment); UI_INCREMENT(AxisPosition_mm, axis);
  230. #define UI_DECREMENT_AXIS(axis) MoveAxisScreen::setManualFeedrate(axis, increment); UI_DECREMENT(AxisPosition_mm, axis);
  231. switch (tag) {
  232. case 1: UI_DECREMENT_AXIS(X); break;
  233. case 2: UI_INCREMENT_AXIS(X); break;
  234. case 4: UI_DECREMENT_AXIS(Y); break; // NOTE: Y directions inverted because bed rather than needle moves
  235. case 3: UI_INCREMENT_AXIS(Y); break;
  236. case 5: UI_DECREMENT_AXIS(Z); break;
  237. case 6: UI_INCREMENT_AXIS(Z); break;
  238. case 7: UI_DECREMENT_AXIS(E0); break;
  239. case 8: UI_INCREMENT_AXIS(E0); break;
  240. default: return false;
  241. }
  242. #undef UI_DECREMENT_AXIS
  243. #undef UI_INCREMENT_AXIS
  244. if (increment < 10 && !fine_motion)
  245. increment += 0.5;
  246. current_screen.onRefresh();
  247. return false;
  248. }
  249. void StatusScreen::setStatusMessage(progmem_str pstr) {
  250. BioPrintingDialogBox::setStatusMessage(pstr);
  251. }
  252. void StatusScreen::setStatusMessage(const char * const str) {
  253. BioPrintingDialogBox::setStatusMessage(str);
  254. }
  255. void StatusScreen::onIdle() {
  256. if (isPrintingFromMedia())
  257. BioPrintingDialogBox::show();
  258. if (refresh_timer.elapsed(STATUS_UPDATE_INTERVAL)) {
  259. onRefresh();
  260. refresh_timer.start();
  261. }
  262. }
  263. #endif // LULZBOT_TOUCH_UI