37 uint8_t ssd1306_printFixed(uint8_t xpos, uint8_t y,
const char *ch,
EFontStyle style)
40 uint8_t text_index = 0;
41 uint8_t page_offset = 0;
44 ssd1306_lcd.set_block(xpos, y, ssd1306_lcd.width - xpos);
48 if ( (x > ssd1306_lcd.width - s_fixedFont.h.width) || (ch[j] ==
'\0') )
52 if (y >= (ssd1306_lcd.height >> 3))
57 if (page_offset == s_fixedFont.pages)
71 ssd1306_lcd.set_block(xpos, y, ssd1306_lcd.width - xpos);
76 unicode = ssd1306_unicode16FromUtf8(ch[j]);
80 ssd1306_getCharBitmap(unicode, &char_info);
83 if (char_info.
height > page_offset * 8)
85 char_info.
glyph += page_offset * char_info.
width;
86 for( i = char_info.
width; i>0; i--)
89 if ( style == STYLE_NORMAL )
91 data = pgm_read_byte(&char_info.
glyph[0]);
93 else if ( style == STYLE_BOLD )
95 uint8_t temp = pgm_read_byte(&char_info.
glyph[0]);
101 uint8_t temp = pgm_read_byte(&char_info.
glyph[1]);
102 data = (temp & 0xF0) | ldata;
103 ldata = (temp & 0x0F);
105 ssd1306_lcd.send_pixels1(data^s_ssd1306_invertByte);
113 for (i = 0; i < char_info.
spacing; i++)
114 ssd1306_lcd.send_pixels1(s_ssd1306_invertByte);
120 uint8_t ssd1306_printFixed_oldStyle(uint8_t xpos, uint8_t y,
const char *ch,
EFontStyle style)
123 uint8_t text_index = 0;
124 uint8_t page_offset = 0;
127 ssd1306_lcd.set_block(xpos, y, ssd1306_lcd.width - xpos);
133 if( (x > ssd1306_lcd.width - s_fixedFont.h.width) || (ch[j] ==
'\0') )
137 if (y >= (ssd1306_lcd.height >> 3))
142 if (page_offset == s_fixedFont.pages)
156 ssd1306_lcd.set_block(xpos, y, ssd1306_lcd.width - xpos);
159 if ( c >= s_fixedFont.h.ascii_offset )
161 c -= s_fixedFont.h.ascii_offset;
164 offset = (c * s_fixedFont.pages + page_offset) * s_fixedFont.h.width;
165 for( i=s_fixedFont.h.width; i>0; i--)
168 if ( style == STYLE_NORMAL )
170 data = pgm_read_byte(&s_fixedFont.primary_table[offset]);
172 else if ( style == STYLE_BOLD )
174 uint8_t temp = pgm_read_byte(&s_fixedFont.primary_table[offset]);
180 uint8_t temp = pgm_read_byte(&s_fixedFont.primary_table[offset + 1]);
181 data = (temp & 0xF0) | ldata;
182 ldata = (temp & 0x0F);
184 ssd1306_lcd.send_pixels1(data^s_ssd1306_invertByte);
187 x += s_fixedFont.h.width;
194 uint8_t ssd1306_printFixed2x(uint8_t xpos, uint8_t y,
const char ch[],
EFontStyle style)
197 uint8_t text_index = 0;
198 uint8_t page_offset = 0;
201 ssd1306_lcd.set_block(xpos, y, ssd1306_lcd.width - xpos);
207 if( (x > ssd1306_lcd.width - (s_fixedFont.h.width << 1)) || (ch[j] ==
'\0') )
211 if (y >= (ssd1306_lcd.height >> 3))
216 if (page_offset == (s_fixedFont.pages << 1))
230 ssd1306_lcd.set_block(xpos, y, ssd1306_lcd.width - xpos);
238 offset = (c * s_fixedFont.pages + (page_offset >> 1)) * s_fixedFont.h.width;
239 for( i=s_fixedFont.h.width; i>0; i--)
242 if ( style == STYLE_NORMAL )
244 data = pgm_read_byte(&s_fixedFont.primary_table[offset]);
246 else if ( style == STYLE_BOLD )
248 uint8_t temp = pgm_read_byte(&s_fixedFont.primary_table[offset]);
254 uint8_t temp = pgm_read_byte(&s_fixedFont.primary_table[offset + 1]);
255 data = (temp & 0xF0) | ldata;
256 ldata = (temp & 0x0F);
258 if (page_offset & 1) data >>= 4;
259 data = ((data & 0x01) ? 0x03: 0x00) |
260 ((data & 0x02) ? 0x0C: 0x00) |
261 ((data & 0x04) ? 0x30: 0x00) |
262 ((data & 0x08) ? 0xC0: 0x00);
263 ssd1306_lcd.send_pixels1(data^s_ssd1306_invertByte);
264 ssd1306_lcd.send_pixels1(data^s_ssd1306_invertByte);
267 x += (s_fixedFont.h.width << 1);
275 uint8_t ssd1306_printFixedN(uint8_t xpos, uint8_t y,
const char ch[],
EFontStyle style, uint8_t factor)
278 uint8_t text_index = 0;
279 uint8_t page_offset = 0;
282 ssd1306_lcd.set_block(xpos, y, ssd1306_lcd.width - xpos);
286 if( (x > ssd1306_lcd.width - (s_fixedFont.h.width << factor)) || (ch[j] ==
'\0') )
290 if (y >= (ssd1306_lcd.height >> 3))
295 if (page_offset == (s_fixedFont.pages << factor))
309 ssd1306_lcd.set_block(xpos, y, ssd1306_lcd.width - xpos);
314 unicode = ssd1306_unicode16FromUtf8(ch[j]);
318 ssd1306_getCharBitmap(unicode, &char_info);
321 if (char_info.
height > (page_offset >> factor) * 8)
323 char_info.
glyph += (page_offset >> factor) * char_info.
width;
324 for( i=char_info.
width; i>0; i--)
327 if ( style == STYLE_NORMAL )
329 data = pgm_read_byte(char_info.
glyph);
331 else if ( style == STYLE_BOLD )
333 uint8_t temp = pgm_read_byte(char_info.
glyph);
339 uint8_t temp = pgm_read_byte(char_info.
glyph+1);
340 data = (temp & 0xF0) | ldata;
341 ldata = (temp & 0x0F);
346 uint8_t mask = ~((0xFF) << (1<<factor));
351 data >>= ((page_offset & ((1<<factor) - 1))<<(3-factor));
352 for (uint8_t idx = 0; idx < 1<<(3-factor); idx++)
354 accum |= (((data>>idx) & 0x01) ? (mask<<(idx<<factor)) : 0);
358 for (uint8_t z=(1<<factor); z>0; z--)
360 ssd1306_lcd.send_pixels1(data^s_ssd1306_invertByte);
369 for (i = 0; i < (char_info.
spacing << factor); i++)
370 ssd1306_lcd.send_pixels1(s_ssd1306_invertByte);
376 void ssd1306_putPixel_delayed(uint8_t x, uint8_t y, uint8_t complete)
378 static uint8_t lx = 0, ly = 0xFF;
379 static uint8_t pixels = 0;
380 if ((lx != x) || ((ly & 0xF8) != (y & 0xF8)) || (complete))
384 ssd1306_putPixels( lx, ly, pixels );
391 pixels |= (1 << (y & 0x07));
396 void ssd1306_drawLine(uint8_t x1, uint8_t y1, uint8_t x2, uint8_t y2)
398 lcduint_t dx = x1 > x2 ? (x1 - x2): (x2 - x1);
399 lcduint_t dy = y1 > y2 ? (y1 - y2): (y2 - y1);
414 x1 < x2 ? x1++: x1--;
416 ssd1306_putPixel_delayed( x1, y1, 0 );
418 ssd1306_putPixel_delayed( 0, 0, 1 );
433 if (y1 < y2) y1++;
else y1--;
435 ssd1306_putPixel( x1, y1 );
443 ssd1306_lcd.set_block(x, y >> 3, w);
444 for(j=(h >> 3); j>0; j--)
446 ssd1306_lcd.send_pixels_buffer1(buf,w);
448 ssd1306_lcd.next_page();
456 uint8_t offset = y & 0x07;
457 uint8_t complexFlag = 0;
458 uint8_t mainFlag = 1;
463 if (y >= (
lcdint_t)ssd1306_lcd.height)
return;
465 if (x >= (
lcdint_t)ssd1306_lcd.width)
return;
479 max_pages = (
lcduint_t)(h + 15 - offset) >> 3;
488 pages = ((y + h - 1) >> 3) - (y >> 3) + 1;
490 ssd1306_lcd.set_block(x, y >> 3, w);
491 for(j=0; j < pages; j++)
493 if ( j == (
lcduint_t)(max_pages - 1) ) mainFlag = !offset;
494 for( i=w; i > 0; i--)
497 if ( mainFlag ) data |= (pgm_read_byte(buf) << offset);
498 if ( complexFlag ) data |= (pgm_read_byte(buf - origin_width) >> (8 - offset));
500 ssd1306_lcd.send_pixels1(s_ssd1306_invertByte^data);
502 buf += origin_width - w;
503 complexFlag = offset;
504 ssd1306_lcd.next_page();
510 void ssd1306_setFont6x8(
const uint8_t * progmemFont)
512 s_font6x8 = progmemFont + 4;
523 template <
class O,
class I>
526 this->putPixel(p.
x, p.
y);
529 template <
class O,
class I>
532 this->drawHLine(x1, y1, x2);
533 this->drawHLine(x1, y2, x2);
534 this->drawVLine(x1, y1, y2);
535 this->drawVLine(x2, y1, y2);
538 template <
class O,
class I>
541 this->drawRect(rect.
p1.
x, rect.
p1.
y, rect.
p2.
x, rect.
p2.
y);
544 template <
class O,
class I>
547 lcduint_t dx = x1 > x2 ? (x1 - x2): (x2 - x1);
548 lcduint_t dy = y1 > y2 ? (y1 - y2): (y2 - y1);
563 x1 < x2 ? x1++: x1--;
565 this->putPixel( x1, y1 );
581 if (y1 < y2) y1++;
else y1--;
583 this->putPixel( x1, y1 );
588 template <
class O,
class I>
591 this->drawLine(rect.
p1.
x, rect.
p1.
y, rect.
p2.
x, rect.
p2.
y);
594 template <
class O,
class I>
597 this->fillRect(rect.
p1.
x, rect.
p1.
y, rect.
p2.
x, rect.
p2.
y);
600 template <
class O,
class I>
603 this->m_fontStyle = style;
604 this->m_cursorX = xpos;
608 char c = pgm_read_byte(ch);
616 #define min(x,y) ((x)<(y)?(x):(y)) 620 #define max(x,y) ((x)>(y)?(x):(y)) 623 template <
class O,
class I>
626 return (display.height() - 16) / display.getFont().getHeader().height;
629 template <
class O,
class I>
632 if ( selection < menu->scrollPosition )
636 else if ( selection - menu->
scrollPosition > getMaxScreenItems<O,I>(display) - 1)
638 return selection - getMaxScreenItems<O,I>(display) + 1;
643 template <
class O,
class I>
648 display.negativeMode();
652 display.positiveMode();
655 display.printFixed(8, item_top,
656 menu->
items[index], STYLE_NORMAL );
657 display.positiveMode();
660 template <
class O,
class I>
665 display.negativeMode();
669 display.positiveMode();
672 display.setColor( 0x0000 );
673 display.
fillRect( 8 + display.getFont().getTextSize(menu->
items[index]), item_top,
674 display.width() - 9, item_top + display.getFont().getHeader().height - 1 );
675 display.setColor( 0xFFFF );
676 display.printFixed(8, item_top,
677 menu->
items[index], STYLE_NORMAL );
678 display.positiveMode();
681 template <
class O,
class I>
691 template <
class O,
class I>
694 drawRect(4, 4, this->m_w - 5, this->m_h - 5);
696 for (uint8_t i = menu->scrollPosition; i <
min(menu->count, (menu->scrollPosition + getMaxScreenItems<O,I>( *
this ))); i++)
698 drawMenuItem<O,I>(*
this, menu, i);
700 menu->oldSelection = menu->selection;
703 template <
class O,
class I>
706 drawRect(4, 4, this->m_w - 5, this->m_h - 5);
708 for (uint8_t i = menu->scrollPosition; i <
min(menu->count, (menu->scrollPosition + getMaxScreenItems<O,I>( *
this ))); i++)
710 drawMenuItemSmooth<O,I>(*
this, menu, i);
712 menu->oldSelection = menu->selection;
715 template <
class O,
class I>
720 uint8_t scrollPosition = calculateScrollPosition<O,I>( *
this, menu, menu->
selection );
721 if ( scrollPosition != menu->scrollPosition )
728 drawMenuItem<O,I>( *
this, menu, menu->oldSelection);
729 drawMenuItem<O,I>( *
this, menu, menu->selection);
730 menu->oldSelection = menu->selection;
735 template <
class O,
class I>
740 uint8_t scrollPosition = calculateScrollPosition<O,I>( *
this, menu, menu->
selection );
741 if ( scrollPosition != menu->scrollPosition )
743 showMenuSmooth(menu);
747 drawMenuItemSmooth<O,I>( *
this, menu, menu->oldSelection);
748 drawMenuItemSmooth<O,I>( *
this, menu, menu->selection);
749 menu->oldSelection = menu->selection;
754 template <
class O,
class I>
760 template <
class O,
class I>
773 template <
class O,
class I>
786 template <
class O,
class I>
792 template <
class O,
class I>
798 template <
class O,
class I>
804 template <
class O,
class I>
810 template <
class O,
class I>
815 char str[5] =
"100%";
816 if ( progress < 100 )
819 str[1] = progress / 10 +
'0';
820 str[2] = progress % 10 +
'0';
823 if ( this->m_font !=
nullptr )
825 width = this->getFont().getTextSize( str, &height );
827 lcdint_t middle = this->height() / 2;
828 lcdint_t progress_pos = 8 + (int16_t)(this->width() - 16) * progress / 100;
829 uint16_t color = this->m_color;
830 this->m_color = 0x0000;
831 this->fillRect( progress_pos, middle, this->width() - 8, middle + height );
832 this->m_color = color;
833 this->drawRect( progress_pos, middle, this->width() - 8, middle + height );
834 this->fillRect( 8, middle, progress_pos, middle + height );
835 if ( this->m_font !=
nullptr )
837 this->printFixed( this->width() / 2 - width / 2, middle - height, str );
841 template <
class O,
class I>
844 const char *caption,
bool blank)
846 if ( width == 0 ) { width = this->width() - 8; x = 4; }
847 if ( height == 0 ) { height = this->height() - 4; y = 0; }
850 uint16_t color = this->m_color;
851 this->m_color = 0x0000;
852 this->fillRect( x, y, x + width - 1, y + height - 1 );
853 this->m_color = color;
857 y += this->getFont().getHeader().height / 2;
858 height -= this->getFont().getHeader().height / 2;
860 this->drawRect( x, y, x + width - 1, y + height - 1 );
864 lcduint_t twidth = this->getFont().getTextSize( caption, &theight );
865 this->printFixed( x + (width - twidth)/2, y - theight/2, caption );
uint8_t height
char height in pixels
void menuUp(SAppMenu *menu)
void drawRect(lcdint_t x1, lcdint_t y1, lcdint_t x2, lcdint_t y2)
uint8_t menuSelection(SAppMenu *menu)
#define SSD1306_MORE_CHARS_REQUIRED
void putPixel(const NanoPoint &p)
void drawCanvas(lcdint_t x, lcdint_t y, NanoCanvasOps< 1 > &canvas) __attribute__((noinline))
void drawLine(lcdint_t x1, lcdint_t y1, lcdint_t x2, lcdint_t y2)
void updateMenuSmooth(SAppMenu *menu)
void updateMenu(SAppMenu *menu)
ssd1306_interface_t ssd1306_intf
void showMenuSmooth(SAppMenu *menu)
uint8_t width
char width in pixels
void showMenu(SAppMenu *menu)
void fillRect(const NanoRect &rect)
const uint8_t * glyph
char data, located in progmem.
void drawProgressBar(int8_t progress)
void createMenu(SAppMenu *menu, const char **items, uint8_t count)
void printFixedPgm(lcdint_t xpos, lcdint_t y, const char *ch, EFontStyle style=STYLE_NORMAL) __attribute__((noinline))
uint8_t spacing
additional spaces after char in pixels
void drawWindow(lcdint_t x, lcdint_t y, lcduint_t width, lcduint_t height, const char *caption, bool blank)
#define ssd1306_swap_data(a, b, type)
void menuDown(SAppMenu *menu)