Skip to content

Commit 55639a3

Browse files
committed
2.30.1
1 parent 30293e4 commit 55639a3

File tree

11 files changed

+935
-107
lines changed

11 files changed

+935
-107
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,5 +8,5 @@ Description: https://github.com/olikraus/u8g2/wiki
88

99
Issue Tracker: https://github.com/olikraus/u8g2/issues
1010

11-
Download (2.29.11): https://github.com/olikraus/U8g2_Arduino/archive/master.zip
11+
Download (2.30.1): https://github.com/olikraus/U8g2_Arduino/archive/master.zip
1212

examples/page_buffer/ButtonEmoticon/ButtonEmoticon.ino

Lines changed: 372 additions & 0 deletions
Large diffs are not rendered by default.

extras/ChangeLog

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -258,7 +258,7 @@ https://github.com/olikraus/u8g2 ChangeLog
258258
* U8g2 16 Bit Mode enabled by default for ARM and ESP Systems (issue 1222)
259259
2021-09-03 v2.29.11 [email protected]
260260
* Update for getStrWidth/getUTF8Width: The new return value might be little bit larger (issue 1561)
261-
* New draw procedure drawButtonUTF8: (issue 1577)
261+
* New draw procedure drawButtonUTF8 (issue 1577)
262262
* Added vertical mirror option U8G2_MIRROR_VERTICAL for u8g2 ([email protected], issue 1474).
263263
* Added support for UC1638 based 196x96 display (issue 371)
264264
* Added support for HD44102 and T7932 displays (issue 1492)
@@ -267,3 +267,5 @@ https://github.com/olikraus/u8g2 ChangeLog
267267
* Added support for SSD1306 EA OLEDS102 (issue 1493)
268268
* Added support for UC1601 128x64 (issue 1501)
269269
* Font Wiki page splitted into four sub-pages to avoid the GitHub 'abuse' message.
270+
2021-09-07 v2.30.1 [email protected]
271+
* Bugfix drawButtonUTF8 (added C++ code, issue 1577)

library.properties

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
name=U8g2
2-
version=2.29.11
2+
version=2.30.1
33
author=oliver <[email protected]>
44
maintainer=oliver <[email protected]>
55
sentence=Monochrome LCD, OLED and eInk Library. Display controller: SSD1305, SSD1306, SSD1309, SSD1316, SSD1320, SSD1322, SSD1325, SSD1327, SSD1329, SSD1606, SSD1607, SH1106, SH1107, SH1108, SH1122, T6963, RA8835, LC7981, PCD8544, PCF8812, HX1230, UC1601, UC1604, UC1608, UC1610, UC1611, UC1617, UC1638, UC1701, ST7511, ST7528, ST7565, ST7567, ST7571, ST7586, ST7588, ST75256, ST75320, NT7534, ST7920, IST3020, IST7920, LD7032, KS0108, KS0713, HD44102, T7932, SED1520, SBN1661, IL3820, MAX7219. Interfaces: I2C, SPI, Parallel.

src/U8g2lib.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -222,7 +222,11 @@ class U8G2 : public Print
222222
void drawRFrame(u8g2_uint_t x, u8g2_uint_t y, u8g2_uint_t w, u8g2_uint_t h, u8g2_uint_t r) { u8g2_DrawRFrame(&u8g2, x, y, w, h,r); }
223223
void drawBox(u8g2_uint_t x, u8g2_uint_t y, u8g2_uint_t w, u8g2_uint_t h) { u8g2_DrawBox(&u8g2, x, y, w, h); }
224224
void drawRBox(u8g2_uint_t x, u8g2_uint_t y, u8g2_uint_t w, u8g2_uint_t h, u8g2_uint_t r) { u8g2_DrawRBox(&u8g2, x, y, w, h,r); }
225-
225+
226+
/* u8g2_button.c */
227+
void drawButtonUTF8(u8g2_uint_t x, u8g2_uint_t y, u8g2_uint_t flags, u8g2_uint_t width, u8g2_uint_t padding_h, u8g2_uint_t padding_v, const char *text) {
228+
u8g2_DrawButtonUTF8(&u8g2, x, y, flags, width, padding_h, padding_v, text); }
229+
226230
/* u8g2_circle.c */
227231
void drawCircle(u8g2_uint_t x0, u8g2_uint_t y0, u8g2_uint_t rad, uint8_t opt = U8G2_DRAW_ALL) { u8g2_DrawCircle(&u8g2, x0, y0, rad, opt); }
228232
void drawDisc(u8g2_uint_t x0, u8g2_uint_t y0, u8g2_uint_t rad, uint8_t opt = U8G2_DRAW_ALL) { u8g2_DrawDisc(&u8g2, x0, y0, rad, opt); }

src/clib/mui.c

Lines changed: 102 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
77
Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/)
88
9-
Copyright (c) 2016, [email protected]
9+
Copyright (c) 2021, [email protected]
1010
All rights reserved.
1111
1212
Redistribution and use in source and binary forms, with or without modification,
@@ -80,7 +80,9 @@
8080

8181
//#define mui_get_fds_char(s) ((uint8_t)(*s))
8282

83-
83+
//#include <stdio.h>
84+
//#define MUI_DEBUG(...) printf(__VA_ARGS__)
85+
#define MUI_DEBUG(...)
8486

8587
uint8_t mui_get_fds_char(fds_t *s)
8688
{
@@ -92,8 +94,8 @@ uint8_t mui_get_fds_char(fds_t *s)
9294
/*
9395
s must point to a valid command within FDS
9496
*/
95-
static size_t mui_fds_get_cmd_size_without_text(mui_t *ui, fds_t *s) MUI_NOINLINE;
96-
static size_t mui_fds_get_cmd_size_without_text(mui_t *ui, fds_t *s)
97+
static size_t mui_fds_get_cmd_size_without_text(fds_t *s) MUI_NOINLINE;
98+
static size_t mui_fds_get_cmd_size_without_text(fds_t *s)
9799
{
98100
uint8_t c = mui_get_fds_char(s);
99101
c &= 0xdf; /* consider upper and lower case */
@@ -180,7 +182,7 @@ static size_t mui_fds_parse_text(mui_t *ui, fds_t *s)
180182
uint8_t mui_fds_first_token(mui_t *ui)
181183
{
182184
ui->token = ui->fds;
183-
ui->token += mui_fds_get_cmd_size_without_text(ui, ui->fds);
185+
ui->token += mui_fds_get_cmd_size_without_text(ui->fds);
184186
ui->delimiter = mui_get_fds_char(ui->token);
185187
ui->token++; // place ui->token on the first char of the token
186188
return mui_fds_next_token(ui);
@@ -271,7 +273,7 @@ uint8_t mui_fds_get_token_cnt(mui_t *ui)
271273
static size_t mui_fds_get_cmd_size(mui_t *ui, fds_t *s) MUI_NOINLINE;
272274
static size_t mui_fds_get_cmd_size(mui_t *ui, fds_t *s)
273275
{
274-
size_t l = mui_fds_get_cmd_size_without_text(ui, s);
276+
size_t l = mui_fds_get_cmd_size_without_text(s);
275277
uint8_t c = mui_get_fds_char(s);
276278
ui->text[0] = '\0' ; /* always reset the text buffer */
277279
if ( mui_fds_is_text(c) )
@@ -298,7 +300,7 @@ void mui_Init(mui_t *ui, void *graphics_data, fds_t *fds, muif_t *muif_tlist, si
298300

299301
int mui_find_uif(mui_t *ui, uint8_t id0, uint8_t id1)
300302
{
301-
int i;
303+
size_t i;
302304
for( i = 0; i < ui->muif_tcnt; i++ )
303305
{
304306
/*
@@ -321,7 +323,8 @@ int mui_find_uif(mui_t *ui, uint8_t id0, uint8_t id1)
321323
will return 1 if the field id was found.
322324
will return 0 if the field id was not found in uif or if ui->fds points to something else than a field
323325
*/
324-
uint8_t mui_prepare_current_field(mui_t *ui)
326+
static uint8_t mui_prepare_current_field(mui_t *ui) MUI_NOINLINE;
327+
static uint8_t mui_prepare_current_field(mui_t *ui)
325328
{
326329
int muif_tidx;
327330

@@ -338,7 +341,7 @@ uint8_t mui_prepare_current_field(mui_t *ui)
338341

339342
/* get the command and check whether end of form is reached */
340343
ui->cmd = mui_get_fds_char(ui->fds);
341-
//printf("mui_prepare_current_field cmd='%c'\n", ui->cmd);
344+
//printf("mui_prepare_current_field cmd='%c' len=%d\n", ui->cmd, ui->len);
342345

343346
/* Copy the cmd also to second id value. This is required for some commands, others will overwrite this below */
344347
ui->id1 = ui->cmd;
@@ -384,6 +387,9 @@ uint8_t mui_prepare_current_field(mui_t *ui)
384387
ui->arg = mui_get_fds_char(ui->fds+3);
385388
}
386389
}
390+
391+
//MUI_DEBUG("mui_prepare_current_field cmd='%c' len=%d arg=%d\n", ui->cmd, ui->len, ui->arg);
392+
387393

388394
/* find the field */
389395
muif_tidx = mui_find_uif(ui, ui->id0, ui->id1);
@@ -404,10 +410,12 @@ uint8_t mui_prepare_current_field(mui_t *ui)
404410
405411
*/
406412

407-
void mui_inner_loop_over_form(mui_t *ui, uint8_t (*task)(mui_t *ui)) MUI_NOINLINE;
408-
void mui_inner_loop_over_form(mui_t *ui, uint8_t (*task)(mui_t *ui))
413+
static void mui_inner_loop_over_form(mui_t *ui, uint8_t (*task)(mui_t *ui)) MUI_NOINLINE;
414+
static void mui_inner_loop_over_form(mui_t *ui, uint8_t (*task)(mui_t *ui))
409415
{
410416
uint8_t cmd;
417+
418+
//MUI_DEBUG("mui_inner_loop_over_form start %p\n", task);
411419

412420
ui->fds += mui_fds_get_cmd_size(ui, ui->fds); // skip the first entry, it is U always
413421
for(;;)
@@ -419,13 +427,18 @@ void mui_inner_loop_over_form(mui_t *ui, uint8_t (*task)(mui_t *ui))
419427
break;
420428
if ( mui_prepare_current_field(ui) )
421429
if ( task(ui) ) /* call the task, which was provided as argument to this function */
430+
{
431+
//MUI_DEBUG("mui_inner_loop_over_form break by task\n");
422432
break;
433+
}
423434
ui->fds += ui->len;
424435
}
425-
//printf("mui_loop_over_form ended\n");
436+
437+
//MUI_DEBUG("mui_inner_loop_over_form end %p\n", task);
426438
}
427439

428-
void mui_loop_over_form(mui_t *ui, uint8_t (*task)(mui_t *ui))
440+
static void mui_loop_over_form(mui_t *ui, uint8_t (*task)(mui_t *ui)) MUI_NOINLINE;
441+
static void mui_loop_over_form(mui_t *ui, uint8_t (*task)(mui_t *ui))
429442
{
430443
if ( mui_IsFormActive(ui) == 0 )
431444
return;
@@ -486,10 +499,20 @@ uint8_t mui_task_form_end(mui_t *ui)
486499
return 0; /* continue with the loop */
487500
}
488501

502+
static uint8_t mui_uif_is_cursor_selectable(mui_t *ui) MUI_NOINLINE;
503+
static uint8_t mui_uif_is_cursor_selectable(mui_t *ui)
504+
{
505+
if ( muif_get_cflags(ui->uif) & MUIF_CFLAG_IS_CURSOR_SELECTABLE )
506+
{
507+
return 1;
508+
}
509+
return 0;
510+
}
489511

490512
uint8_t mui_task_find_prev_cursor_uif(mui_t *ui)
491513
{
492-
if ( muif_get_cflags(ui->uif) & MUIF_CFLAG_IS_CURSOR_SELECTABLE )
514+
//if ( muif_get_cflags(ui->uif) & MUIF_CFLAG_IS_CURSOR_SELECTABLE )
515+
if ( mui_uif_is_cursor_selectable(ui) )
493516
{
494517
if ( ui->fds == ui->cursor_focus_fds )
495518
{
@@ -503,7 +526,8 @@ uint8_t mui_task_find_prev_cursor_uif(mui_t *ui)
503526

504527
uint8_t mui_task_find_first_cursor_uif(mui_t *ui)
505528
{
506-
if ( muif_get_cflags(ui->uif) & MUIF_CFLAG_IS_CURSOR_SELECTABLE )
529+
//if ( muif_get_cflags(ui->uif) & MUIF_CFLAG_IS_CURSOR_SELECTABLE )
530+
if ( mui_uif_is_cursor_selectable(ui) )
507531
{
508532
// if ( ui->target_fds == NULL )
509533
// {
@@ -516,7 +540,8 @@ uint8_t mui_task_find_first_cursor_uif(mui_t *ui)
516540

517541
uint8_t mui_task_find_last_cursor_uif(mui_t *ui)
518542
{
519-
if ( muif_get_cflags(ui->uif) & MUIF_CFLAG_IS_CURSOR_SELECTABLE )
543+
//if ( muif_get_cflags(ui->uif) & MUIF_CFLAG_IS_CURSOR_SELECTABLE )
544+
if ( mui_uif_is_cursor_selectable(ui) )
520545
{
521546
//ui->cursor_focus_position++;
522547
ui->target_fds = ui->fds;
@@ -526,7 +551,8 @@ uint8_t mui_task_find_last_cursor_uif(mui_t *ui)
526551

527552
uint8_t mui_task_find_next_cursor_uif(mui_t *ui)
528553
{
529-
if ( muif_get_cflags(ui->uif) & MUIF_CFLAG_IS_CURSOR_SELECTABLE )
554+
//if ( muif_get_cflags(ui->uif) & MUIF_CFLAG_IS_CURSOR_SELECTABLE )
555+
if ( mui_uif_is_cursor_selectable(ui) )
530556
{
531557
if ( ui->tmp_fds != NULL )
532558
{
@@ -544,7 +570,8 @@ uint8_t mui_task_find_next_cursor_uif(mui_t *ui)
544570

545571
uint8_t mui_task_get_current_cursor_focus_position(mui_t *ui)
546572
{
547-
if ( muif_get_cflags(ui->uif) & MUIF_CFLAG_IS_CURSOR_SELECTABLE )
573+
//if ( muif_get_cflags(ui->uif) & MUIF_CFLAG_IS_CURSOR_SELECTABLE )
574+
if ( mui_uif_is_cursor_selectable(ui) )
548575
{
549576
if ( ui->fds == ui->cursor_focus_fds )
550577
return 1; /* stop looping */
@@ -553,9 +580,10 @@ uint8_t mui_task_get_current_cursor_focus_position(mui_t *ui)
553580
return 0; /* continue with the loop */
554581
}
555582

556-
uint8_t mui_task_read_nth_seleectable_field(mui_t *ui)
583+
uint8_t mui_task_read_nth_selectable_field(mui_t *ui)
557584
{
558-
if ( muif_get_cflags(ui->uif) & MUIF_CFLAG_IS_CURSOR_SELECTABLE )
585+
//if ( muif_get_cflags(ui->uif) & MUIF_CFLAG_IS_CURSOR_SELECTABLE )
586+
if ( mui_uif_is_cursor_selectable(ui) )
559587
{
560588
if ( ui->tmp8 == 0 )
561589
return 1; /* stop looping */
@@ -567,14 +595,16 @@ uint8_t mui_task_read_nth_seleectable_field(mui_t *ui)
567595

568596
/* === utility functions for the user API === */
569597

570-
void mui_send_cursor_msg(mui_t *ui, uint8_t msg)
598+
static uint8_t mui_send_cursor_msg(mui_t *ui, uint8_t msg) MUI_NOINLINE;
599+
static uint8_t mui_send_cursor_msg(mui_t *ui, uint8_t msg)
571600
{
572601
if ( ui->cursor_focus_fds )
573602
{
574603
ui->fds = ui->cursor_focus_fds;
575604
if ( mui_prepare_current_field(ui) )
576-
muif_get_cb(ui->uif)(ui, msg);
605+
return muif_get_cb(ui->uif)(ui, msg);
577606
}
607+
return 0; /* not called, msg not handled */
578608
}
579609

580610
/* === user API === */
@@ -626,7 +656,8 @@ void mui_GetSelectableFieldTextOption(mui_t *ui, uint8_t form_id, uint8_t cursor
626656

627657
// use the inner_loop procedure, because ui->fds has been assigned already
628658
ui->tmp8 = cursor_position; // maybe we should also backup tmp8, but at the moment tmp8 is only used by mui_task_get_current_cursor_focus_position
629-
mui_inner_loop_over_form(ui, mui_task_read_nth_seleectable_field);
659+
//MUI_DEBUG("mui_GetSelectableFieldTextOption\n");
660+
mui_inner_loop_over_form(ui, mui_task_read_nth_selectable_field);
630661
// at this point ui->fds contains the field which was selected from above
631662

632663
// now get the opion string out of the text field. nth_token can be 0 if this is no opion string
@@ -637,6 +668,42 @@ void mui_GetSelectableFieldTextOption(mui_t *ui, uint8_t form_id, uint8_t cursor
637668
// result is stored in ui->text
638669
}
639670

671+
/*
672+
this function will overwrite the ui field related member variables
673+
return the number of options in the referenced field
674+
*/
675+
uint8_t mui_GetSelectableFieldOptionCnt(mui_t *ui, uint8_t form_id, uint8_t cursor_position)
676+
{
677+
fds_t *fds = ui->fds; // backup the current fds, so that this function can be called inside a task loop
678+
int len = ui->len; // backup length of the current command
679+
uint8_t cnt = 0;
680+
681+
ui->fds = mui_find_form(ui, form_id); // search for the target form and overwrite the current fds
682+
683+
// use the inner_loop procedure, because ui->fds has been assigned already
684+
ui->tmp8 = cursor_position; // maybe we should also backup tmp8, but at the moment tmp8 is only used by mui_task_get_current_cursor_focus_position
685+
//MUI_DEBUG("mui_GetSelectableFieldOptionCnt\n");
686+
mui_inner_loop_over_form(ui, mui_task_read_nth_selectable_field);
687+
// at this point ui->fds contains the field which was selected from above
688+
689+
// now get the opion string out of the text field. nth_token can be 0 if this is no opion string
690+
cnt = mui_fds_get_token_cnt(ui);
691+
692+
ui->fds = fds; // restore the previous fds position
693+
ui->len = len;
694+
// result is stored in ui->text
695+
return cnt;
696+
}
697+
698+
699+
700+
//static void mui_send_cursor_enter_msg(mui_t *ui) MUI_NOINLINE;
701+
static void mui_send_cursor_enter_msg(mui_t *ui)
702+
{
703+
ui->is_mud = 0;
704+
mui_send_cursor_msg(ui, MUIF_MSG_CURSOR_ENTER);
705+
}
706+
640707
/*
641708
if called from a field function, then the current field variables are destroyed, so that call should be the last call in the field callback.
642709
mui_EnterForm is similar to mui_GotoForm and differes only in the second argument (which is the form id instead of the fds pointer)
@@ -654,19 +721,22 @@ void mui_EnterForm(mui_t *ui, fds_t *fds, uint8_t initial_cursor_position)
654721
ui->current_form_fds = fds;
655722

656723
/* inform all fields that we start a new form */
724+
MUI_DEBUG("mui_EnterForm: form_start\n");
657725
mui_loop_over_form(ui, mui_task_form_start);
658726

659727
/* assign initional cursor focus */
728+
MUI_DEBUG("mui_EnterForm: find_first_cursor_uif\n");
660729
mui_loop_over_form(ui, mui_task_find_first_cursor_uif);
661730
ui->cursor_focus_fds = ui->target_fds; // NULL is ok
731+
MUI_DEBUG("mui_EnterForm: find_first_cursor_uif target_fds=%p\n", ui->target_fds);
662732

663733
while( initial_cursor_position > 0 )
664734
{
665-
mui_next_field(ui);
735+
mui_NextField(ui); // mui_next_field(ui) is not sufficient in case of scrolling
666736
initial_cursor_position--;
667737
}
668738

669-
mui_send_cursor_msg(ui, MUIF_MSG_CURSOR_ENTER);
739+
mui_send_cursor_enter_msg(ui);
670740
}
671741

672742
/* input: current_form_fds */
@@ -682,6 +752,7 @@ void mui_LeaveForm(mui_t *ui)
682752
ui->cursor_focus_fds = NULL;
683753

684754
/* inform all fields that we leave the form */
755+
MUI_DEBUG("mui_LeaveForm: form_end\n");
685756
mui_loop_over_form(ui, mui_task_form_end);
686757
ui->current_form_fds = NULL;
687758
}
@@ -725,9 +796,11 @@ void mui_RestoreForm(mui_t *ui)
725796
*/
726797
void mui_NextField(mui_t *ui)
727798
{
799+
if ( mui_send_cursor_msg(ui, MUIF_MSG_EVENT_NEXT) )
800+
return;
728801
mui_send_cursor_msg(ui, MUIF_MSG_CURSOR_LEAVE);
729802
mui_next_field(ui);
730-
mui_send_cursor_msg(ui, MUIF_MSG_CURSOR_ENTER);
803+
mui_send_cursor_enter_msg(ui);
731804
}
732805

733806
/*
@@ -738,6 +811,8 @@ void mui_NextField(mui_t *ui)
738811
*/
739812
void mui_PrevField(mui_t *ui)
740813
{
814+
if ( mui_send_cursor_msg(ui, MUIF_MSG_EVENT_PREV) )
815+
return;
741816
mui_send_cursor_msg(ui, MUIF_MSG_CURSOR_LEAVE);
742817

743818
mui_loop_over_form(ui, mui_task_find_prev_cursor_uif);
@@ -750,7 +825,7 @@ void mui_PrevField(mui_t *ui)
750825
ui->cursor_focus_fds = ui->target_fds; // NULL is ok
751826
}
752827

753-
mui_send_cursor_msg(ui, MUIF_MSG_CURSOR_ENTER);
828+
mui_send_cursor_enter_msg(ui);
754829
}
755830

756831

0 commit comments

Comments
 (0)