/* myU8g2changes.cpp This file contains brunotified (modified ;-) ) functions of the following original files: U8g2/src/clib/u8g2_message.c U8g2/src/clib/u8g2_selection_list.c U8g2/src/clib/u8g2_input_value.c U8g2/src/clib/u8g2_debounce.c |---------------- | ORIGINAL TEXT: |---------------- Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/) Copyright (c) 2016, olikraus@gmail.com All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include extern "C" { #define SPACE_BETWEEN_BUTTONS_IN_PIXEL 6 #define SPACE_BETWEEN_TEXT_AND_BUTTONS_IN_PIXEL 3 static uint8_t my_draw_button_line(u8g2_t *u8g2, u8g2_uint_t y, u8g2_uint_t w, uint8_t cursor, const char *s) { u8g2_uint_t button_line_width; uint8_t i; uint8_t cnt; uint8_t is_invert; u8g2_uint_t d; u8g2_uint_t x; cnt = u8x8_GetStringLineCnt(s); /* calculate the width of the button line */ button_line_width = 0; for( i = 0; i < cnt; i++ ) { button_line_width += u8g2_GetUTF8Width(u8g2, u8x8_GetStringLineStart(i, s)); } button_line_width += (cnt-1)*SPACE_BETWEEN_BUTTONS_IN_PIXEL; /* add some space between the buttons */ /* calculate the left offset */ d = 0; if ( button_line_width < w ) { d = w; d -= button_line_width; d /= 2; } /* draw the buttons */ x = d; for( i = 0; i < cnt; i++ ) { is_invert = 0; if ( i == cursor ) is_invert = 1; u8g2_DrawUTF8Line(u8g2, x, y, 0, u8x8_GetStringLineStart(i, s), 1, is_invert); x += u8g2_GetUTF8Width(u8g2, u8x8_GetStringLineStart(i, s)); x += SPACE_BETWEEN_BUTTONS_IN_PIXEL; } /* return the number of buttons */ return cnt; } /* title1: Multiple lines,separated by '\n' title2: A single line/string which is terminated by '\0' or '\n' . "title2" accepts the return value from u8x8_GetStringLineStart() title3: Multiple lines,separated by '\n' buttons: one more more buttons separated by '\n' and terminated with '\0' cursor: highlighted cursor position returns the number of buttons side effects: u8g2_SetFontDirection(u8g2, 0); u8g2_SetFontPosBaseline(u8g2); */ uint8_t my_UserInterfaceMessage(u8g2_t *u8g2, const char *title1, const char *title2, const char *title3, const char *buttons, uint8_t cursor) { uint8_t height; uint8_t line_height; u8g2_uint_t pixel_height; u8g2_uint_t y, yy; uint8_t button_cnt; /* only horizontal strings are supported, so force this here */ u8g2_SetFontDirection(u8g2, 0); /* force baseline position */ u8g2_SetFontPosBaseline(u8g2); /* calculate line height */ line_height = u8g2_GetAscent(u8g2); line_height -= u8g2_GetDescent(u8g2); /* calculate overall height of the message box in lines*/ height = 1; /* button line */ height += u8x8_GetStringLineCnt(title1); if ( title2 != NULL ) height++; height += u8x8_GetStringLineCnt(title3); /* calculate the height in pixel */ pixel_height = height; pixel_height *= line_height; /* ... and add the space between the text and the buttons */ pixel_height += SPACE_BETWEEN_TEXT_AND_BUTTONS_IN_PIXEL; /* calculate offset from top */ y = 0; if ( pixel_height < u8g2_GetDisplayHeight(u8g2) ) { y = u8g2_GetDisplayHeight(u8g2); y -= pixel_height; y /= 2; } y += u8g2_GetAscent(u8g2); u8g2_FirstPage(u8g2); do { yy = y; /* draw message box */ yy += u8g2_DrawUTF8Lines(u8g2, 0, yy, u8g2_GetDisplayWidth(u8g2), line_height, title1); if ( title2 != NULL ) { u8g2_DrawUTF8Line(u8g2, 0, yy, u8g2_GetDisplayWidth(u8g2), title2, 0, 0); yy+=line_height; } yy += u8g2_DrawUTF8Lines(u8g2, 0, yy, u8g2_GetDisplayWidth(u8g2), line_height, title3); yy += SPACE_BETWEEN_TEXT_AND_BUTTONS_IN_PIXEL; button_cnt = my_draw_button_line(u8g2, yy, u8g2_GetDisplayWidth(u8g2), cursor, buttons); } while( u8g2_NextPage(u8g2) ); return button_cnt; } #define MY_BORDER_SIZE 1 /* selection list with string line returns line height */ // static u8g2_uint_t my_draw_selection_list_line(u8g2_t *u8g2, u8sl_t *u8sl, u8g2_uint_t y, uint8_t idx, const char *s) U8G2_NOINLINE; static u8g2_uint_t my_draw_selection_list_line(u8g2_t *u8g2, u8sl_t *u8sl, u8g2_uint_t y, uint8_t idx, const char *s) { u8g2_uint_t yy; uint8_t border_size = 0; uint8_t is_invert = 0; u8g2_uint_t line_height = u8g2_GetAscent(u8g2) - u8g2_GetDescent(u8g2) + MY_BORDER_SIZE; /* calculate offset from display upper border */ yy = idx; yy -= u8sl->first_pos; yy *= line_height; yy += y; /* check whether this is the current cursor line */ if ( idx == u8sl->current_pos ) { border_size = MY_BORDER_SIZE; is_invert = 1; } /* get the line from the array */ s = u8x8_GetStringLineStart(idx, s); /* draw the line */ if ( s == NULL ) s = ""; u8g2_DrawUTF8Line(u8g2, MY_BORDER_SIZE, y, u8g2_GetDisplayWidth(u8g2) - 2 * MY_BORDER_SIZE, s, border_size, is_invert); return line_height; } static void my_DrawSelectionList(u8g2_t *u8g2, u8sl_t *u8sl, u8g2_uint_t y, const char *s) { uint8_t i; for( i = 0; i < u8sl->visible; i++ ) { y += my_draw_selection_list_line(u8g2, u8sl, y, i + u8sl->first_pos, s); } } /* title: NULL for no title, valid str for title line. Can contain mutliple lines, separated by '\n' start_pos: default position for the cursor, first line is 1. sl: string list (list of strings separated by \n) returns the number of options (depending on sl) side effects: u8g2_SetFontDirection(u8g2, 0); u8g2_SetFontPosBaseline(u8g2); */ uint8_t my_UserInterfaceSelectionList(u8g2_t *u8g2, const char *title, uint8_t start_pos, const char *sl) { u8sl_t u8sl; u8g2_uint_t yy; u8g2_uint_t line_height = u8g2_GetAscent(u8g2) - u8g2_GetDescent(u8g2) + MY_BORDER_SIZE; uint8_t title_lines = u8x8_GetStringLineCnt(title); uint8_t display_lines; // if ( start_pos > 0 ) /* issue 112 */ // start_pos--; /* issue 112 */ if ( title_lines > 0 ) { display_lines = (u8g2_GetDisplayHeight(u8g2) - 3) / line_height; u8sl.visible = display_lines; u8sl.visible -= title_lines; } else { display_lines = u8g2_GetDisplayHeight(u8g2) / line_height; u8sl.visible = display_lines; } u8sl.total = u8x8_GetStringLineCnt(sl); u8sl.first_pos = 0; u8sl.current_pos = start_pos; if ( u8sl.current_pos >= u8sl.total ) u8sl.current_pos = u8sl.total - 1; if ( u8sl.first_pos + u8sl.visible <= u8sl.current_pos ) u8sl.first_pos = u8sl.current_pos - u8sl.visible + 1; u8g2_SetFontPosBaseline(u8g2); u8g2_FirstPage(u8g2); do { yy = u8g2_GetAscent(u8g2); if ( title_lines > 0 ) { yy += u8g2_DrawUTF8Lines(u8g2, 0, yy, u8g2_GetDisplayWidth(u8g2), line_height, title); u8g2_DrawHLine(u8g2, 0, yy-line_height- u8g2_GetDescent(u8g2) + 1, u8g2_GetDisplayWidth(u8g2)); yy += 3; } my_DrawSelectionList(u8g2, &u8sl, yy, sl); } while( u8g2_NextPage(u8g2) ); return u8sl.total; } void my_UserInterfaceInputValueString(u8g2_t *u8g2, const char *title, const char *sub, const char *text) { uint8_t line_height; uint8_t height; u8g2_uint_t pixel_height; u8g2_uint_t x, y, yy; u8g2_uint_t pixel_width; /* only horizontal strings are supported, so force this here */ u8g2_SetFontDirection(u8g2, 0); /* force baseline position */ u8g2_SetFontPosBaseline(u8g2); /* calculate line height */ line_height = u8g2_GetAscent(u8g2); line_height -= u8g2_GetDescent(u8g2); /* calculate overall height of the input value box */ height = 1; /* value input line */ height += u8x8_GetStringLineCnt(title); height += u8x8_GetStringLineCnt(sub); /* calculate the height in pixel */ pixel_height = height; pixel_height *= line_height; /* calculate offset from top */ y = 0; if ( pixel_height < u8g2_GetDisplayHeight(u8g2) ) { y = u8g2_GetDisplayHeight(u8g2); y -= pixel_height; y /= 2; } /* calculate offset from left for the label */ x = 0; pixel_width = u8g2_GetUTF8Width(u8g2, text); if ( pixel_width < u8g2_GetDisplayWidth(u8g2) ) { x = u8g2_GetDisplayWidth(u8g2); x -= pixel_width; x /= 2; } u8g2_FirstPage(u8g2); do { yy = y; yy += u8g2_DrawUTF8Lines(u8g2, 0, yy, u8g2_GetDisplayWidth(u8g2), line_height, title); yy += u8g2_DrawUTF8Lines(u8g2, 0, yy, u8g2_GetDisplayWidth(u8g2), line_height, sub); u8g2_DrawUTF8(u8g2, x, yy, text); } while( u8g2_NextPage(u8g2) ); } // void my_UserInterfaceInputValue(u8g2_t *u8g2, const char *title, const char *pre, uint8_t value, uint8_t digits, const char *post) // { // uint8_t line_height; // uint8_t height; // u8g2_uint_t pixel_height; // u8g2_uint_t y, yy; // u8g2_uint_t pixel_width; // u8g2_uint_t x, xx; // /* only horizontal strings are supported, so force this here */ // u8g2_SetFontDirection(u8g2, 0); // /* force baseline position */ // u8g2_SetFontPosBaseline(u8g2); // /* calculate line height */ // line_height = u8g2_GetAscent(u8g2); // line_height -= u8g2_GetDescent(u8g2); // /* calculate overall height of the input value box */ // height = 1; /* value input line */ // height += u8x8_GetStringLineCnt(title); // /* calculate the height in pixel */ // pixel_height = height; // pixel_height *= line_height; // /* calculate offset from top */ // y = 0; // if ( pixel_height < u8g2_GetDisplayHeight(u8g2) ) // { // y = u8g2_GetDisplayHeight(u8g2); // y -= pixel_height; // y /= 2; // } // /* calculate offset from left for the label */ // x = 0; // pixel_width = u8g2_GetUTF8Width(u8g2, pre); // pixel_width += u8g2_GetUTF8Width(u8g2, "0") * digits; // pixel_width += u8g2_GetUTF8Width(u8g2, post); // if ( pixel_width < u8g2_GetDisplayWidth(u8g2) ) { // x = u8g2_GetDisplayWidth(u8g2); // x -= pixel_width; // x /= 2; // } // u8g2_FirstPage(u8g2); // do { // yy = y; // yy += u8g2_DrawUTF8Lines(u8g2, 0, yy, u8g2_GetDisplayWidth(u8g2), line_height, title); // xx = x; // xx += u8g2_DrawUTF8(u8g2, xx, yy, pre); // xx += u8g2_DrawUTF8(u8g2, xx, yy, u8x8_u8toa(value, digits)); // u8g2_DrawUTF8(u8g2, xx, yy, post); // } while( u8g2_NextPage(u8g2) ); // } // original u8x8_read_pin_state(), aber nicht static uint8_t my_read_pin_state(u8x8_t *u8x8) { uint8_t i; uint8_t pin_state; pin_state = 255; /* be compatible with the setup of the default pin setup, which is 255 */ for( i = 0; i < U8X8_PIN_INPUT_CNT; i++ ) { pin_state <<= 1; /* the callback function should put the return value into this variable */ u8x8->gpio_result = 1; u8x8_gpio_call(u8x8, U8X8_MSG_GPIO(i+U8X8_PIN_OUTPUT_CNT), 0); pin_state |= u8x8->gpio_result & 1; } return pin_state; } } //extern "C"