DreherTankController/src/display/myU8g2changes.cpp

363 lines
12 KiB
C++

/*
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 <U8g2lib.h>
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"