dogm_lcd_implementation.h 20.1 KB
Newer Older
MagoKimbra's avatar
MagoKimbra committed
1 2 3 4 5 6 7 8 9 10 11 12 13
/**
 * dogm_lcd_implementation.h
 *
 * Graphics LCD implementation for 128x64 pixel LCDs by STB for ErikZalm/Marlin
 * Demonstrator: http://www.reprap.org/wiki/STB_Electronics
 * License: http://opensource.org/licenses/BSD-3-Clause
 *
 * With the use of:
 * u8glib by Oliver Kraus
 * http://code.google.com/p/u8glib/
 * License: http://opensource.org/licenses/BSD-3-Clause
 */

MagoKimbra's avatar
MagoKimbra committed
14
#include "../../base.h"
15

MagoKimbra's avatar
MagoKimbra committed
16 17 18 19 20 21 22
#ifndef DOGM_LCD_IMPLEMENTATION_H
#define DOGM_LCD_IMPLEMENTATION_H

/**
 * Implementation of the LCD display routines for a DOGM128 graphic display. These are common LCD 128x64 pixel graphic displays.
 */

MagoKimbra's avatar
MagoKimbra committed
23
#if ENABLED(ULTIPANEL)
MagoKimbra's avatar
MagoKimbra committed
24 25 26 27 28 29
  #define BLEN_A 0
  #define BLEN_B 1
  #define BLEN_C 2
  #define EN_A BIT(BLEN_A)
  #define EN_B BIT(BLEN_B)
  #define EN_C BIT(BLEN_C)
MagoKimbra's avatar
MagoKimbra committed
30 31 32 33 34
  #if ENABLED(INVERT_CLICK_BUTTON)
    #define LCD_CLICKED !(buttons&EN_C)
  #else
    #define LCD_CLICKED (buttons&EN_C)
  #endif
MagoKimbra's avatar
MagoKimbra committed
35 36 37
#endif

#include <U8glib.h>
MagoKimbra's avatar
MagoKimbra committed
38
#include "dogm_bitmaps.h"
MagoKimbra's avatar
MagoKimbra committed
39 40 41 42

#include "ultralcd.h"
#include "ultralcd_st7920_u8glib_rrd.h"

MagoKimbra's avatar
MagoKimbra committed
43
#if DISABLED(MAPPER_C2C3) && DISABLED(MAPPER_NON) && ENABLED(USE_BIG_EDIT_FONT)
MagoKimbra's avatar
MagoKimbra committed
44
  #undef USE_BIG_EDIT_FONT
MagoKimbra's avatar
MagoKimbra committed
45 46
#endif

MagoKimbra's avatar
MagoKimbra committed
47

MagoKimbra's avatar
MagoKimbra committed
48
#if ENABLED(USE_SMALL_INFOFONT)
MagoKimbra's avatar
MagoKimbra committed
49 50 51 52 53 54 55 56 57
  #include "dogm_font_data_6x9_marlin.h"
  #define FONT_STATUSMENU_NAME u8g_font_6x9
#else
  #define FONT_STATUSMENU_NAME FONT_MENU_NAME
#endif

#include "dogm_font_data_Marlin_symbols.h"   // The Marlin special symbols
#define FONT_SPECIAL_NAME Marlin_symbols

MagoKimbra's avatar
MagoKimbra committed
58 59
#if DISABLED(SIMULATE_ROMFONT)
  #if ENABLED(DISPLAY_CHARSET_ISO10646_1)
MagoKimbra's avatar
MagoKimbra committed
60 61
    #include "dogm_font_data_ISO10646_1.h"
    #define FONT_MENU_NAME ISO10646_1_5x7
MagoKimbra's avatar
MagoKimbra committed
62
  #elif ENABLED(DISPLAY_CHARSET_ISO10646_5)
MagoKimbra's avatar
MagoKimbra committed
63 64
    #include "dogm_font_data_ISO10646_5_Cyrillic.h"
    #define FONT_MENU_NAME ISO10646_5_Cyrillic_5x7
MagoKimbra's avatar
MagoKimbra committed
65
  #elif ENABLED(DISPLAY_CHARSET_ISO10646_KANA)
MagoKimbra's avatar
MagoKimbra committed
66 67
    #include "dogm_font_data_ISO10646_Kana.h"
    #define FONT_MENU_NAME ISO10646_Kana_5x7
MagoKimbra's avatar
MagoKimbra committed
68
  #elif ENABLED(DISPLAY_CHARSET_ISO10646_CN)
MagoKimbra's avatar
MagoKimbra committed
69 70 71
    #include "dogm_font_data_ISO10646_CN.h"
    #define FONT_MENU_NAME ISO10646_CN
    #define TALL_FONT_CORRECTION 1
MagoKimbra's avatar
MagoKimbra committed
72 73 74 75 76
  #else // fall-back
    #include "dogm_font_data_ISO10646_1.h"
    #define FONT_MENU_NAME ISO10646_1_5x7
  #endif
#else // SIMULATE_ROMFONT
MagoKimbra's avatar
MagoKimbra committed
77
  #if ENABLED(DISPLAY_CHARSET_HD44780_JAPAN)
MagoKimbra's avatar
MagoKimbra committed
78 79
    #include "dogm_font_data_HD44780_J.h"
    #define FONT_MENU_NAME HD44780_J_5x7
MagoKimbra's avatar
MagoKimbra committed
80
  #elif ENABLED(DISPLAY_CHARSET_HD44780_WESTERN)
MagoKimbra's avatar
MagoKimbra committed
81 82
    #include "dogm_font_data_HD44780_W.h"
    #define FONT_MENU_NAME HD44780_W_5x7
MagoKimbra's avatar
MagoKimbra committed
83
  #elif ENABLED(DISPLAY_CHARSET_HD44780_CYRILLIC)
MagoKimbra's avatar
MagoKimbra committed
84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101
    #include "dogm_font_data_HD44780_C.h"
    #define FONT_MENU_NAME HD44780_C_5x7
  #else // fall-back
    #include "dogm_font_data_ISO10646_1.h"
    #define FONT_MENU_NAME ISO10646_1_5x7
  #endif
#endif // SIMULATE_ROMFONT

//#define FONT_STATUSMENU_NAME FONT_MENU_NAME

#define FONT_STATUSMENU 1
#define FONT_SPECIAL 2
#define FONT_MENU_EDIT 3
#define FONT_MENU 4

// DOGM parameters (size in pixels)
#define DOG_CHAR_WIDTH         6
#define DOG_CHAR_HEIGHT        12
MagoKimbra's avatar
MagoKimbra committed
102
#if ENABLED(USE_BIG_EDIT_FONT)
MagoKimbra's avatar
MagoKimbra committed
103 104 105 106 107 108 109 110 111 112 113
  #define FONT_MENU_EDIT_NAME u8g_font_9x18
  #define DOG_CHAR_WIDTH_EDIT  9
  #define DOG_CHAR_HEIGHT_EDIT 18
  #define LCD_WIDTH_EDIT       14
#else
  #define FONT_MENU_EDIT_NAME FONT_MENU_NAME
  #define DOG_CHAR_WIDTH_EDIT  6
  #define DOG_CHAR_HEIGHT_EDIT 12
  #define LCD_WIDTH_EDIT       22
#endif

Simone Primarosa's avatar
Simone Primarosa committed
114
#if DISABLED(TALL_FONT_CORRECTION)
MagoKimbra's avatar
MagoKimbra committed
115 116 117
  #define TALL_FONT_CORRECTION 0
#endif

MagoKimbra's avatar
MagoKimbra committed
118 119 120
#define START_ROW              0

// LCD selection
MagoKimbra's avatar
MagoKimbra committed
121
#if ENABLED(U8GLIB_ST7920)
MagoKimbra's avatar
MagoKimbra committed
122
  U8GLIB_ST7920_128X64_RRD u8g(0);
MagoKimbra's avatar
MagoKimbra committed
123
#elif ENABLED(MAKRPANEL)
MagoKimbra's avatar
MagoKimbra committed
124 125
  // The MaKrPanel display, ST7565 controller as well
  U8GLIB_NHD_C12864 u8g(DOGLCD_CS, DOGLCD_A0);
MagoKimbra's avatar
MagoKimbra committed
126
#elif ENABLED(VIKI2) || ENABLED(miniVIKI)
MagoKimbra's avatar
MagoKimbra committed
127 128
  // Mini Viki and Viki 2.0 LCD, ST7565 controller as well
  U8GLIB_NHD_C12864 u8g(DOGLCD_CS, DOGLCD_A0);
MagoKimbra's avatar
MagoKimbra committed
129
#elif ENABLED(U8GLIB_LM6059_AF)
MagoKimbra's avatar
MagoKimbra committed
130 131
  // Based on the Adafruit ST7565 (http://www.adafruit.com/products/250)
  U8GLIB_LM6059 u8g(DOGLCD_CS, DOGLCD_A0);
MagoKimbra's avatar
MagoKimbra committed
132
#elif ENABLED(U8GLIB_SSD1306)
MagoKimbra's avatar
MagoKimbra committed
133 134
  // Generic support for SSD1306 OLED I2C LCDs
  U8GLIB_SSD1306_128X64 u8g(U8G_I2C_OPT_NONE);
MagoKimbra's avatar
MagoKimbra committed
135
#elif ENABLED(MINIPANEL)
MagoKimbra's avatar
MagoKimbra committed
136 137
  // The MINIPanel display
  U8GLIB_MINI12864 u8g(DOGLCD_CS, DOGLCD_A0);
MagoKimbra's avatar
MagoKimbra committed
138
#else
MagoKimbra's avatar
MagoKimbra committed
139 140
  // for regular DOGM128 display with HW-SPI
  U8GLIB_DOGM128 u8g(DOGLCD_CS, DOGLCD_A0);  // HW-SPI Com: CS, A0
MagoKimbra's avatar
MagoKimbra committed
141 142
#endif

Simone Primarosa's avatar
Simone Primarosa committed
143
#if DISABLED(LCD_PIXEL_WIDTH)
MagoKimbra's avatar
MagoKimbra committed
144 145
  #define LCD_PIXEL_WIDTH 128
#endif
Simone Primarosa's avatar
Simone Primarosa committed
146
#if DISABLED(LCD_PIXEL_HEIGHT)
MagoKimbra's avatar
MagoKimbra committed
147 148 149
  #define LCD_PIXEL_HEIGHT 64
#endif

MagoKimbra's avatar
MagoKimbra committed
150 151 152
#include "utf_mapper.h"

int lcd_contrast;
MagoKimbra's avatar
MagoKimbra committed
153
static unsigned char blink = 0; // Variable for visualization of fan rotation in GLCD
MagoKimbra's avatar
MagoKimbra committed
154 155 156
static char currentfont = 0;

static void lcd_setFont(char font_nr) {
MagoKimbra's avatar
MagoKimbra committed
157
  switch (font_nr) {
MagoKimbra's avatar
MagoKimbra committed
158 159 160 161
    case FONT_STATUSMENU : {u8g.setFont(FONT_STATUSMENU_NAME); currentfont = FONT_STATUSMENU;}; break;
    case FONT_MENU       : {u8g.setFont(FONT_MENU_NAME); currentfont = FONT_MENU;}; break;
    case FONT_SPECIAL    : {u8g.setFont(FONT_SPECIAL_NAME); currentfont = FONT_SPECIAL;}; break;
    case FONT_MENU_EDIT  : {u8g.setFont(FONT_MENU_EDIT_NAME); currentfont = FONT_MENU_EDIT;}; break;
MagoKimbra's avatar
MagoKimbra committed
162 163 164 165 166 167 168 169 170 171
    break;
  }
}

char lcd_print(char c) {
  if ((c > 0) && (c <= LCD_STR_SPECIAL_MAX)) {
    u8g.setFont(FONT_SPECIAL_NAME);
    u8g.print(c);
    lcd_setFont(currentfont);
    return 1;
MagoKimbra's avatar
MagoKimbra committed
172 173
  }
  else
MagoKimbra's avatar
MagoKimbra committed
174 175 176 177 178 179 180
    return charset_mapper(c);
}

char lcd_print(char* str) {
  char c;
  int i = 0;
  char n = 0;
MagoKimbra's avatar
MagoKimbra committed
181
  while ((c = str[i++])) {
MagoKimbra's avatar
MagoKimbra committed
182
    n += lcd_print(c);
MagoKimbra's avatar
MagoKimbra committed
183
  }
MagoKimbra's avatar
MagoKimbra committed
184 185 186 187 188 189 190
  return n;
}

/* Arduino < 1.0.0 is missing a function to print PROGMEM strings, so we need to implement our own */
char lcd_printPGM(const char* str) {
  char c;
  char n = 0;
MagoKimbra's avatar
MagoKimbra committed
191
  while ((c = pgm_read_byte(str++))) {
MagoKimbra's avatar
MagoKimbra committed
192
    n += lcd_print(c);
MagoKimbra's avatar
MagoKimbra committed
193
  }
MagoKimbra's avatar
MagoKimbra committed
194 195 196
  return n;
}

MagoKimbra's avatar
MagoKimbra committed
197 198 199
#if ENABLED(SHOW_BOOTSCREEN)
  static bool show_bootscreen = true;
#endif
MagoKimbra's avatar
MagoKimbra committed
200

MagoKimbra's avatar
MagoKimbra committed
201
/* Warning: This function is called from interrupt context */
MagoKimbra's avatar
MagoKimbra committed
202
static void lcd_implementation_init() {
MagoKimbra's avatar
MagoKimbra committed
203 204 205 206 207 208 209 210 211 212 213 214 215 216 217

  #if ENABLED(LCD_PIN_BL) && LCD_PIN_BL > -1 // Enable LCD backlight
    pinMode(LCD_PIN_BL, OUTPUT);
    digitalWrite(LCD_PIN_BL, HIGH);
  #endif

  #if ENABLED(LCD_PIN_RESET) && LCD_PIN_RESET > -1
    pinMode(LCD_PIN_RESET, OUTPUT);
    digitalWrite(LCD_PIN_RESET, HIGH);
  #endif

  #if DISABLED(MINIPANEL) // setContrast not working for Mini Panel
    u8g.setContrast(lcd_contrast);
  #endif

MagoKimbra's avatar
MagoKimbra committed
218
  // FIXME: remove this workaround
MagoKimbra's avatar
MagoKimbra committed
219
  // Uncomment this if you have the first generation (V1.10) of STBs board
MagoKimbra's avatar
MagoKimbra committed
220
  // pinMode(17, OUTPUT); // Enable LCD backlight
MagoKimbra's avatar
MagoKimbra committed
221
  // digitalWrite(17, HIGH);
MagoKimbra's avatar
MagoKimbra committed
222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255

  #if ENABLED(LCD_SCREEN_ROT_90)
    u8g.setRot90();   // Rotate screen by 90°
  #elif ENABLED(LCD_SCREEN_ROT_180)
    u8g.setRot180();  // Rotate screen by 180°
  #elif ENABLED(LCD_SCREEN_ROT_270)
    u8g.setRot270();  // Rotate screen by 270°
  #endif

  #if ENABLED(SHOW_BOOTSCREEN)
    int offx = (u8g.getWidth() - START_BMPWIDTH) / 2;
    #if ENABLED(START_BMPHIGH)
      int offy = 0;
    #else
      int offy = DOG_CHAR_HEIGHT;
    #endif

    int txt1X = (u8g.getWidth() - (sizeof(STRING_SPLASH_LINE1) - 1) * DOG_CHAR_WIDTH) / 2;

    u8g.firstPage();
    do {
      if (show_bootscreen) {
        u8g.drawBitmapP(offx, offy, START_BMPBYTEWIDTH, START_BMPHEIGHT, start_bmp);
        lcd_setFont(FONT_MENU);
        #if DISABLED(STRING_SPLASH_LINE2)
          u8g.drawStr(txt1X, u8g.getHeight() - DOG_CHAR_HEIGHT, STRING_SPLASH_LINE1);
        #else
          int txt2X = (u8g.getWidth() - (sizeof(STRING_SPLASH_LINE2) - 1) * DOG_CHAR_WIDTH) / 2;
          u8g.drawStr(txt1X, u8g.getHeight() - DOG_CHAR_HEIGHT * 3 / 2, STRING_SPLASH_LINE1);
          u8g.drawStr(txt2X, u8g.getHeight() - DOG_CHAR_HEIGHT * 1 / 2, STRING_SPLASH_LINE2);
        #endif
      }
    } while (u8g.nextPage());

MagoKimbra's avatar
MagoKimbra committed
256
    if (show_bootscreen) {
MagoKimbra's avatar
MagoKimbra committed
257 258
      delay(SPLASH_SCREEN_DURATION);
      show_bootscreen = false;
MagoKimbra's avatar
MagoKimbra committed
259
    }
MagoKimbra's avatar
MagoKimbra committed
260
  #endif
MagoKimbra's avatar
MagoKimbra committed
261 262 263 264 265 266 267
}

static void lcd_implementation_clear() { } // Automatically cleared by Picture Loop

static void _draw_heater_status(int x, int heater) {
  bool isBed = heater < 0;
  int y = 17 + (isBed ? 1 : 0);
MagoKimbra's avatar
MagoKimbra committed
268

MagoKimbra's avatar
MagoKimbra committed
269
  lcd_setFont(FONT_STATUSMENU);
MagoKimbra's avatar
MagoKimbra committed
270
  u8g.setPrintPos(x, 7);
MagoKimbra's avatar
MagoKimbra committed
271 272
  lcd_print(itostr3(int((heater >= 0 ? degTargetHotend(heater) : degTargetBed()) + 0.5)));
  lcd_printPGM(PSTR(LCD_STR_DEGREE " "));
MagoKimbra's avatar
MagoKimbra committed
273
  u8g.setPrintPos(x, 28);
MagoKimbra's avatar
MagoKimbra committed
274
  lcd_print(itostr3(int(heater >= 0 ? degHotend(heater) : degBed()) + 0.5));
MagoKimbra's avatar
MagoKimbra committed
275

MagoKimbra's avatar
MagoKimbra committed
276
  lcd_printPGM(PSTR(LCD_STR_DEGREE " "));
MagoKimbra's avatar
MagoKimbra committed
277
  if (heater >= 0 ? !isHeatingHotend(heater) : !isHeatingBed()) {
MagoKimbra's avatar
MagoKimbra committed
278
    u8g.drawBox(x + 7, y, 2, 2);
MagoKimbra's avatar
MagoKimbra committed
279
  }
MagoKimbra's avatar
MagoKimbra committed
280 281
  else {
    u8g.setColorIndex(0); // white on black
MagoKimbra's avatar
MagoKimbra committed
282
    u8g.drawBox(x + 7, y, 2, 2);
MagoKimbra's avatar
MagoKimbra committed
283 284 285 286 287 288
    u8g.setColorIndex(1); // black on white
  }
}

static void lcd_implementation_status_screen() {
  u8g.setColorIndex(1); // black on white
MagoKimbra's avatar
MagoKimbra committed
289

MagoKimbra's avatar
MagoKimbra committed
290
  // Symbols menu graphics, animated fan
MagoKimbra's avatar
MagoKimbra committed
291
  u8g.drawBitmapP(9, 1, STATUS_SCREENBYTEWIDTH, STATUS_SCREENHEIGHT, (blink % 2) && fanSpeed ? status_screen0_bmp : status_screen1_bmp);
MagoKimbra's avatar
MagoKimbra committed
292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308

  #if ENABLED(SDSUPPORT)
    // SD Card Symbol
    u8g.drawBox(42, 42 - TALL_FONT_CORRECTION, 8, 7);
    u8g.drawBox(50, 44 - TALL_FONT_CORRECTION, 2, 5);
    u8g.drawFrame(42, 49 - TALL_FONT_CORRECTION, 10, 4);
    u8g.drawPixel(50, 43 - TALL_FONT_CORRECTION);

    // Progress bar frame
    u8g.drawFrame(54, 49, 73, 4 - TALL_FONT_CORRECTION);

    // SD Card Progress bar and clock
    lcd_setFont(FONT_STATUSMENU);

    if (IS_SD_PRINTING) {
      // Progress bar solid part
      u8g.drawBox(55, 50, (unsigned int)(71.f * card.percentDone() / 100.f), 2 - TALL_FONT_CORRECTION);
MagoKimbra's avatar
MagoKimbra committed
309
    }
MagoKimbra's avatar
MagoKimbra committed
310 311 312 313 314 315 316 317 318 319 320 321

    u8g.setPrintPos(80, 48);
    if (print_job_start_ms != 0) {
      #if HAS(LCD_POWER_SENSOR)
        if (millis() < print_millis + 1000) {
          uint16_t time = (millis() - print_job_start_ms) / 60000;
          lcd_print(itostr2(time/60));
          lcd_print(':');
          lcd_print(itostr2(time%60));
        }
        else {
          lcd_print(itostr4(power_consumption_hour-startpower));
MagoKimbra's avatar
MagoKimbra committed
322
          lcd_print((char*)"Wh");
MagoKimbra's avatar
MagoKimbra committed
323 324 325 326 327 328 329 330 331 332 333 334 335
        }
      #else
        uint16_t time = (millis() - print_job_start_ms) / 60000;
        lcd_print(itostr2(time / 60));
        lcd_print(':');
        lcd_print(itostr2(time % 60));
      #endif
    }
    else {
      lcd_printPGM(PSTR("--:--"));
    }
  #endif

MagoKimbra's avatar
MagoKimbra committed
336 337
  // Hotends
  for (int i = 0; i < HOTENDS; i++) _draw_heater_status(6 + i * 25, i);
MagoKimbra's avatar
MagoKimbra committed
338

MagoKimbra's avatar
MagoKimbra committed
339
  // Heatbed
MagoKimbra's avatar
MagoKimbra committed
340
  if (HOTENDS < 4) _draw_heater_status(81, -1);
MagoKimbra's avatar
MagoKimbra committed
341

MagoKimbra's avatar
MagoKimbra committed
342 343
  // Fan
  lcd_setFont(FONT_STATUSMENU);
MagoKimbra's avatar
MagoKimbra committed
344
  u8g.setPrintPos(104, 27);
MagoKimbra's avatar
MagoKimbra committed
345 346 347 348 349 350 351 352 353 354 355 356
  #if HAS(FAN)
    int per = ((fanSpeed + 1) * 100) / 256;
    if (per) {
      lcd_print(itostr3(per));
      lcd_print('%');
    }
    else
  #endif
    {
      lcd_printPGM(PSTR("---"));
    }

MagoKimbra's avatar
MagoKimbra committed
357
  // X, Y, Z-Coordinates
MagoKimbra's avatar
MagoKimbra committed
358
  #define XYZ_BASELINE 38
MagoKimbra's avatar
MagoKimbra committed
359
  lcd_setFont(FONT_STATUSMENU);
MagoKimbra's avatar
MagoKimbra committed
360 361 362 363 364 365

  #if ENABLED(USE_SMALL_INFOFONT)
    u8g.drawBox(0, 30, LCD_PIXEL_WIDTH, 10);
  #else
    u8g.drawBox(0, 30, LCD_PIXEL_WIDTH, 9);
  #endif
MagoKimbra's avatar
MagoKimbra committed
366
  u8g.setColorIndex(0); // white on black
MagoKimbra's avatar
MagoKimbra committed
367
  u8g.setPrintPos(2, XYZ_BASELINE);
MagoKimbra's avatar
MagoKimbra committed
368
  lcd_print('X');
MagoKimbra's avatar
MagoKimbra committed
369 370 371
  u8g.drawPixel(8, XYZ_BASELINE - 5);
  u8g.drawPixel(8, XYZ_BASELINE - 3);
  u8g.setPrintPos(10, XYZ_BASELINE);
MagoKimbra's avatar
MagoKimbra committed
372 373 374 375
  if (axis_known_position[X_AXIS])
    lcd_print(ftostr31ns(current_position[X_AXIS]));
  else
    lcd_printPGM(PSTR("---"));
MagoKimbra's avatar
MagoKimbra committed
376
  u8g.setPrintPos(43, XYZ_BASELINE);
MagoKimbra's avatar
MagoKimbra committed
377
  lcd_print('Y');
MagoKimbra's avatar
MagoKimbra committed
378 379 380
  u8g.drawPixel(49, XYZ_BASELINE - 5);
  u8g.drawPixel(49, XYZ_BASELINE - 3);
  u8g.setPrintPos(51, XYZ_BASELINE);
MagoKimbra's avatar
MagoKimbra committed
381 382 383 384
  if (axis_known_position[Y_AXIS])
    lcd_print(ftostr31ns(current_position[Y_AXIS]));
  else
    lcd_printPGM(PSTR("---"));
MagoKimbra's avatar
MagoKimbra committed
385
  u8g.setPrintPos(83, XYZ_BASELINE);
MagoKimbra's avatar
MagoKimbra committed
386
  lcd_print('Z');
MagoKimbra's avatar
MagoKimbra committed
387 388 389
  u8g.drawPixel(89, XYZ_BASELINE - 5);
  u8g.drawPixel(89, XYZ_BASELINE - 3);
  u8g.setPrintPos(91, XYZ_BASELINE);
MagoKimbra's avatar
MagoKimbra committed
390 391 392 393
  if (axis_known_position[Z_AXIS])
    lcd_print(ftostr32sp(current_position[Z_AXIS]));
  else
    lcd_printPGM(PSTR("---.--"));
MagoKimbra's avatar
MagoKimbra committed
394
  u8g.setColorIndex(1); // black on white
MagoKimbra's avatar
MagoKimbra committed
395

MagoKimbra's avatar
MagoKimbra committed
396 397
  // Feedrate
  lcd_setFont(FONT_MENU);
MagoKimbra's avatar
MagoKimbra committed
398
  u8g.setPrintPos(3, 49);
MagoKimbra's avatar
MagoKimbra committed
399 400
  lcd_print(LCD_STR_FEEDRATE[0]);
  lcd_setFont(FONT_STATUSMENU);
MagoKimbra's avatar
MagoKimbra committed
401
  u8g.setPrintPos(12, 49);
MagoKimbra's avatar
MagoKimbra committed
402
  lcd_print(itostr3(feedrate_multiplier));
MagoKimbra's avatar
MagoKimbra committed
403
  lcd_print('%');
MagoKimbra's avatar
MagoKimbra committed
404

MagoKimbra's avatar
MagoKimbra committed
405 406
  // Status line
  lcd_setFont(FONT_STATUSMENU);
MagoKimbra's avatar
MagoKimbra committed
407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438
  #if ENABLED(USE_SMALL_INFOFONT)
    u8g.setPrintPos(0, 62);
  #else
    u8g.setPrintPos(0, 63);
  #endif
  #if HAS(LCD_FILAMENT_SENSOR) || HAS(LCD_POWER_SENSOR)
    if (millis() < previous_lcd_status_ms + 5000)  //Display both Status message line and Filament display on the last line
      lcd_print(lcd_status_message);
    #if HAS(LCD_POWER_SENSOR)
      #if HAS(LCD_FILAMENT_SENSOR)
        else if (millis() < previous_lcd_status_ms + 10000)
      #else
        else
      #endif
        {
          lcd_printPGM(PSTR("P:"));
          lcd_print(ftostr31(power_consumption_meas));
          lcd_printPGM(PSTR("W C:"));
          lcd_print(ltostr7(power_consumption_hour));
          lcd_printPGM(PSTR("Wh"));
        }
    #endif
    #if HAS(LCD_FILAMENT_SENSOR)
      else {
        lcd_printPGM(PSTR("dia:"));
        lcd_print(ftostr12ns(filament_width_meas));
        lcd_printPGM(PSTR(" factor:"));
        lcd_print(itostr3(100.0 * volumetric_multiplier[FILAMENT_SENSOR_EXTRUDER_NUM]));
        lcd_print('%');
      }
    #endif
  #else
MagoKimbra's avatar
MagoKimbra committed
439
    lcd_print(lcd_status_message);
MagoKimbra's avatar
MagoKimbra committed
440
  #endif
MagoKimbra's avatar
MagoKimbra committed
441 442 443 444 445
}

static void lcd_implementation_mark_as_selected(uint8_t row, bool isSelected) {
  if (isSelected) {
    u8g.setColorIndex(1);  // black on white
MagoKimbra's avatar
MagoKimbra committed
446
    u8g.drawBox(0, row * DOG_CHAR_HEIGHT + 3 - TALL_FONT_CORRECTION, LCD_PIXEL_WIDTH, DOG_CHAR_HEIGHT);
MagoKimbra's avatar
MagoKimbra committed
447
    u8g.setColorIndex(0);  // following text must be white on black
MagoKimbra's avatar
MagoKimbra committed
448 449
  }
  else {
MagoKimbra's avatar
MagoKimbra committed
450 451 452 453 454 455 456 457
    u8g.setColorIndex(1); // unmarked text is black on white
  }
  u8g.setPrintPos(START_ROW * DOG_CHAR_WIDTH, (row + 1) * DOG_CHAR_HEIGHT);
}

static void lcd_implementation_drawmenu_generic(bool isSelected, uint8_t row, const char* pstr, char pre_char, char post_char) {
  char c;
  uint8_t n = LCD_WIDTH - 2;
MagoKimbra's avatar
MagoKimbra committed
458

MagoKimbra's avatar
MagoKimbra committed
459
  lcd_implementation_mark_as_selected(row, isSelected);
MagoKimbra's avatar
MagoKimbra committed
460

MagoKimbra's avatar
MagoKimbra committed
461 462 463 464 465
  while (c = pgm_read_byte(pstr)) {
    n -= lcd_print(c);
    pstr++;
  }
  while (n--) lcd_print(' ');
MagoKimbra's avatar
MagoKimbra committed
466
  lcd_print(pre_char);
MagoKimbra's avatar
MagoKimbra committed
467
  u8g.setPrintPos(LCD_PIXEL_WIDTH - DOG_CHAR_WIDTH, (row + 1) * DOG_CHAR_HEIGHT);
MagoKimbra's avatar
MagoKimbra committed
468 469 470 471 472 473
  lcd_print(post_char);
  lcd_print(' ');
}

static void _drawmenu_setting_edit_generic(bool isSelected, uint8_t row, const char* pstr, const char* data, bool pgm) {
  char c;
MagoKimbra's avatar
MagoKimbra committed
474 475
  uint8_t vallen = (pgm ? lcd_strlen_P(data) : (lcd_strlen((char*)data)));
  uint8_t n = LCD_WIDTH - 2 - vallen;
MagoKimbra's avatar
MagoKimbra committed
476

MagoKimbra's avatar
MagoKimbra committed
477
  lcd_implementation_mark_as_selected(row, isSelected);
MagoKimbra's avatar
MagoKimbra committed
478

MagoKimbra's avatar
MagoKimbra committed
479 480 481 482 483 484
  while (c = pgm_read_byte(pstr)) {
    n -= lcd_print(c);
    pstr++;
  }
  lcd_print(':');
  while (n--) lcd_print(' ');
MagoKimbra's avatar
MagoKimbra committed
485
  u8g.setPrintPos(LCD_PIXEL_WIDTH - DOG_CHAR_WIDTH * vallen, (row + 1) * DOG_CHAR_HEIGHT);
MagoKimbra's avatar
MagoKimbra committed
486
  if (pgm)  lcd_printPGM(data);  else  lcd_print((char*)data);
MagoKimbra's avatar
MagoKimbra committed
487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516
}

#define lcd_implementation_drawmenu_setting_edit_generic(sel, row, pstr, data) _drawmenu_setting_edit_generic(sel, row, pstr, data, false)
#define lcd_implementation_drawmenu_setting_edit_generic_P(sel, row, pstr, data) _drawmenu_setting_edit_generic(sel, row, pstr, data, true)

#define lcd_implementation_drawmenu_setting_edit_int3(sel, row, pstr, pstr2, data, minValue, maxValue) lcd_implementation_drawmenu_setting_edit_generic(sel, row, pstr, itostr3(*(data)))
#define lcd_implementation_drawmenu_setting_edit_float3(sel, row, pstr, pstr2, data, minValue, maxValue) lcd_implementation_drawmenu_setting_edit_generic(sel, row, pstr, ftostr3(*(data)))
#define lcd_implementation_drawmenu_setting_edit_float32(sel, row, pstr, pstr2, data, minValue, maxValue) lcd_implementation_drawmenu_setting_edit_generic(sel, row, pstr, ftostr32(*(data)))
#define lcd_implementation_drawmenu_setting_edit_float43(sel, row, pstr, pstr2, data, minValue, maxValue) lcd_implementation_drawmenu_setting_edit_generic(sel, row, pstr, ftostr43(*(data)))
#define lcd_implementation_drawmenu_setting_edit_float5(sel, row, pstr, pstr2, data, minValue, maxValue) lcd_implementation_drawmenu_setting_edit_generic(sel, row, pstr, ftostr5(*(data)))
#define lcd_implementation_drawmenu_setting_edit_float52(sel, row, pstr, pstr2, data, minValue, maxValue) lcd_implementation_drawmenu_setting_edit_generic(sel, row, pstr, ftostr52(*(data)))
#define lcd_implementation_drawmenu_setting_edit_float51(sel, row, pstr, pstr2, data, minValue, maxValue) lcd_implementation_drawmenu_setting_edit_generic(sel, row, pstr, ftostr51(*(data)))
#define lcd_implementation_drawmenu_setting_edit_long5(sel, row, pstr, pstr2, data, minValue, maxValue) lcd_implementation_drawmenu_setting_edit_generic(sel, row, pstr, ftostr5(*(data)))
#define lcd_implementation_drawmenu_setting_edit_bool(sel, row, pstr, pstr2, data) lcd_implementation_drawmenu_setting_edit_generic_P(sel, row, pstr, (*(data))?PSTR(MSG_ON):PSTR(MSG_OFF))

//Add version for callback functions
#define lcd_implementation_drawmenu_setting_edit_callback_int3(sel, row, pstr, pstr2, data, minValue, maxValue, callback) lcd_implementation_drawmenu_setting_edit_generic(sel, row, pstr, itostr3(*(data)))
#define lcd_implementation_drawmenu_setting_edit_callback_float3(sel, row, pstr, pstr2, data, minValue, maxValue, callback) lcd_implementation_drawmenu_setting_edit_generic(sel, row, pstr, ftostr3(*(data)))
#define lcd_implementation_drawmenu_setting_edit_callback_float32(sel, row, pstr, pstr2, data, minValue, maxValue, callback) lcd_implementation_drawmenu_setting_edit_generic(sel, row, pstr, ftostr32(*(data)))
#define lcd_implementation_drawmenu_setting_edit_callback_float43(sel, row, pstr, pstr2, data, minValue, maxValue, callback) lcd_implementation_drawmenu_setting_edit_generic(sel, row, pstr, ftostr43(*(data)))
#define lcd_implementation_drawmenu_setting_edit_callback_float5(sel, row, pstr, pstr2, data, minValue, maxValue, callback) lcd_implementation_drawmenu_setting_edit_generic(sel, row, pstr, ftostr5(*(data)))
#define lcd_implementation_drawmenu_setting_edit_callback_float52(sel, row, pstr, pstr2, data, minValue, maxValue, callback) lcd_implementation_drawmenu_setting_edit_generic(sel, row, pstr, ftostr52(*(data)))
#define lcd_implementation_drawmenu_setting_edit_callback_float51(sel, row, pstr, pstr2, data, minValue, maxValue, callback) lcd_implementation_drawmenu_setting_edit_generic(sel, row, pstr, ftostr51(*(data)))
#define lcd_implementation_drawmenu_setting_edit_callback_long5(sel, row, pstr, pstr2, data, minValue, maxValue, callback) lcd_implementation_drawmenu_setting_edit_generic(sel, row, pstr, ftostr5(*(data)))
#define lcd_implementation_drawmenu_setting_edit_callback_bool(sel, row, pstr, pstr2, data, callback) lcd_implementation_drawmenu_setting_edit_generic_P(sel, row, pstr, (*(data))?PSTR(MSG_ON):PSTR(MSG_OFF))

void lcd_implementation_drawedit(const char* pstr, char* value) {
  uint8_t rows = 1;
  uint8_t lcd_width = LCD_WIDTH, char_width = DOG_CHAR_WIDTH;
  uint8_t vallen = lcd_strlen(value);
MagoKimbra's avatar
MagoKimbra committed
517 518 519 520 521 522 523 524 525 526 527 528 529

  #if ENABLED(USE_BIG_EDIT_FONT)
    if (lcd_strlen_P(pstr) <= LCD_WIDTH_EDIT - 1) {
      lcd_setFont(FONT_MENU_EDIT);
      lcd_width = LCD_WIDTH_EDIT + 1;
      char_width = DOG_CHAR_WIDTH_EDIT;
      if (lcd_strlen_P(pstr) >= LCD_WIDTH_EDIT - vallen) rows = 2;
    }
    else {
      lcd_setFont(FONT_MENU);
    }
  #endif

MagoKimbra's avatar
MagoKimbra committed
530
  if (lcd_strlen_P(pstr) > LCD_WIDTH - 2 - vallen) rows = 2;
MagoKimbra's avatar
MagoKimbra committed
531

MagoKimbra's avatar
MagoKimbra committed
532 533
  const float kHalfChar = DOG_CHAR_HEIGHT_EDIT / 2;
  float rowHeight = u8g.getHeight() / (rows + 1); // 1/(rows+1) = 1/2 or 1/3
MagoKimbra's avatar
MagoKimbra committed
534

MagoKimbra's avatar
MagoKimbra committed
535 536 537 538 539 540 541
  u8g.setPrintPos(0, rowHeight + kHalfChar);
  lcd_printPGM(pstr);
  lcd_print(':');
  u8g.setPrintPos((lcd_width - 1 - vallen) * char_width, rows * rowHeight + kHalfChar);
  lcd_print(value);
}

MagoKimbra's avatar
MagoKimbra committed
542
#if ENABLED(SDSUPPORT)
MagoKimbra's avatar
MagoKimbra committed
543
  static void _drawmenu_sd(bool isSelected, uint8_t row, const char* pstr, const char* longFilename, bool isDir) {
MagoKimbra's avatar
MagoKimbra committed
544 545 546 547 548 549
    char c;
    uint8_t n = LCD_WIDTH - 1;

    lcd_implementation_mark_as_selected(row, isSelected);

    if (isDir) lcd_print(LCD_STR_FOLDER[0]);
MagoKimbra's avatar
MagoKimbra committed
550
    while ((c = *longFilename)) {
MagoKimbra's avatar
MagoKimbra committed
551
      n -= lcd_print(c);
MagoKimbra's avatar
MagoKimbra committed
552
      longFilename++;
MagoKimbra's avatar
MagoKimbra committed
553 554
    }
    while (n--) lcd_print(' ');
MagoKimbra's avatar
MagoKimbra committed
555 556
  }

MagoKimbra's avatar
MagoKimbra committed
557 558
  #define lcd_implementation_drawmenu_sdfile(sel, row, pstr, longFilename) _drawmenu_sd(sel, row, pstr, longFilename, false)
  #define lcd_implementation_drawmenu_sddirectory(sel, row, pstr, longFilename) _drawmenu_sd(sel, row, pstr, longFilename, true)
MagoKimbra's avatar
MagoKimbra committed
559

MagoKimbra's avatar
MagoKimbra committed
560 561
#endif //SDSUPPORT

MagoKimbra's avatar
MagoKimbra committed
562 563 564 565 566 567
#define lcd_implementation_drawmenu_back(sel, row, pstr, data) lcd_implementation_drawmenu_generic(sel, row, pstr, LCD_STR_UPLEVEL[0], LCD_STR_UPLEVEL[0])
#define lcd_implementation_drawmenu_submenu(sel, row, pstr, data) lcd_implementation_drawmenu_generic(sel, row, pstr, '>', LCD_STR_ARROW_RIGHT[0])
#define lcd_implementation_drawmenu_gcode(sel, row, pstr, gcode) lcd_implementation_drawmenu_generic(sel, row, pstr, '>', ' ')
#define lcd_implementation_drawmenu_function(sel, row, pstr, data) lcd_implementation_drawmenu_generic(sel, row, pstr, '>', ' ')

#endif //__DOGM_LCD_IMPLEMENTATION_H