main/buttons.c

Tue, 02 Jul 2019 12:10:23 +0200

author
Michiel Broek <mbroek@mbse.eu>
date
Tue, 02 Jul 2019 12:10:23 +0200
changeset 56
756d1a63d129
parent 54
7b134c27fadb
child 77
66c77497d86d
permissions
-rw-r--r--

Adjusted more strings for new compiler warnings. There should now be no buffer overflows in the app. Changed the date display on the mainscreen.

/**
 * @file buttons.c
 * @brief The touch buttons.
 */

#include "config.h"


sButton				Buttons[MAXBUTTONS];	///< 40 buttons on a screen.
int				level = 1;		///< Keyboard level.

const char 			*mashTypes[] = { "Infusion", "Temperature", "Decoction" };
const char			*SSR2Types[] = { "Uit", "HLT of MLT", "HLT en MLT", "Idle" };

uint8_t				WS_pressed = 0;		///< Websocket button received
uint16_t			WS_pointer_x = 0;	///< Websocket coordinate x
uint16_t			WS_pointer_y = 0;	///< Websocket coordinate y

#define	EDIT_TYPE_TEXT		0			///< Editor type is text
#define	EDIT_TYPE_INT		1			///< Editor type is integer
#define	EDIT_TYPE_FLOAT		2			///< Editor type is float


/***************************************************************************/


void WaitTouchReleased(void)
{
    int		tx, ty;

    // Do raw reads.
    while (TFT_read_touch(&tx, &ty, 1) == 1) {
	vTaskDelay(50 / portTICK_PERIOD_MS);
    }
}



void Buttons_Clear(void)
{
    int		i;

    for (i = 0; i < MAXBUTTONS; i++) {
	if ((Buttons[i].x != -1) && strlen(Buttons[i].text)) {
	    TFT_fillRect(Buttons[i].x, Buttons[i].y, Buttons[i].w, Buttons[i].h, TFT_BLACK);
	}
	Buttons[i].x = -1;
    }
}



void Buttons_Add(int x, int y, int w, int h, char *txt, int order)
{
    Buttons[order].x = x;
    Buttons[order].y = y;
    Buttons[order].w = w;
    Buttons[order].h = h;
    strncpy(Buttons[order].text, txt, 11);
    Buttons[order].dark = Buttons[order].small = Buttons[order].lock = false;
}



void Buttons_Show(void)
{
    int		i;
    const color_t KEY_NORM        = { 191, 191, 191};
    const color_t KEY_DARK        = {  95,  95,  95};
    const color_t KEY_LOCK        = { 127, 127, 255};

    _fg = TFT_BLACK;

    for (i = 0; i < MAXBUTTONS; i++) {
	if (Buttons[i].x != -1) {

	    if (Buttons[i].lock) {
		_fg = TFT_BLACK;
		TFT_fillRoundRect(Buttons[i].x, Buttons[i].y, Buttons[i].w, Buttons[i].h, 5, KEY_LOCK);
	    } else if (Buttons[i].dark) {
		_fg = TFT_WHITE;
		TFT_fillRoundRect(Buttons[i].x, Buttons[i].y, Buttons[i].w, Buttons[i].h, 5, KEY_DARK);
	    } else {
		_fg = TFT_BLACK;
	    	TFT_fillRoundRect(Buttons[i].x, Buttons[i].y, Buttons[i].w, Buttons[i].h, 5, KEY_NORM);
	    }
	    TFT_drawRoundRect(Buttons[i].x, Buttons[i].y, Buttons[i].w, Buttons[i].h, 5, TFT_LIGHTGREY);
	    if (Buttons[i].small)
		TFT_setFont(DEFAULT_FONT, NULL);	// DEF_SMALL_FONT
	    else
		TFT_setFont(DEJAVU18_FONT, NULL);
	    font_transparent = 1;
	    TFT_print(Buttons[i].text, 
		      Buttons[i].x + ((Buttons[i].w - TFT_getStringWidth(Buttons[i].text)) / 2), 
		      Buttons[i].y + 1 + ((Buttons[i].h - TFT_getfontheight()) / 2));
	}
    }

    font_transparent = 0;
}



int Buttons_Search(int x, int y)
{
    int		i;

    for (i = 0; i < MAXBUTTONS; i++) {
	if (Buttons[i].x != -1) {
	    if ((x >= Buttons[i].x) && (x <= (Buttons[i].x + Buttons[i].w)) &&
		(y >= Buttons[i].y) && (y <= (Buttons[i].y + Buttons[i].h))) {
		return i;
	    }
	}
    }

    return -1;
}



int Buttons_Scan(void)
{
    int		tx, ty, rc;
    static int	ox = -1, oy = -1, vx = -1, vy = -1;
    static bool t_pressed = false, v_pressed = false;

    if (TFT_read_touch(&tx, &ty, 0)) {
	t_pressed = true;
	ox = tx;
	oy = ty;
	return -1;
    } else if (t_pressed) {
	rc = Buttons_Search(ox, oy);
	t_pressed = false;
	ox = oy = -1;
	return rc;
    }

    if (WS_pressed) {
	v_pressed = true;
        vx = WS_pointer_x;
        vy = WS_pointer_y;
	WS_pressed = 0;
        return -1;
    } else if (v_pressed) {
	rc = Buttons_Search(vx, vy);
	v_pressed = false;
	vx = vy = -1;
	return rc;
    }

    return -1;
}



void WS_touched(int x, int y)
{
    WS_pointer_x = x;
    WS_pointer_y = y;
    WS_pressed = 1;
}



static const uint8_t alphalow_tab[] = { 'q','w','e','r','t','y','u','i','o','p',
					'a','s','d','f','g','h','j','k','l',
					'z','x','c','v','b','n','m' };

/**
 * @brief Level 1 keys, lowercase alpha.
 */
void B_AlphaLow(void)
{
    Buttons_Clear();

    Buttons_Add(  2, 80,28,36,(char *)"q", 0);
    Buttons_Add( 34, 80,28,36,(char *)"w", 1);
    Buttons_Add( 66, 80,28,36,(char *)"e", 2);
    Buttons_Add( 98, 80,28,36,(char *)"r", 3);
    Buttons_Add(130, 80,28,36,(char *)"t", 4);
    Buttons_Add(162, 80,28,36,(char *)"y", 5);
    Buttons_Add(194, 80,28,36,(char *)"u", 6);
    Buttons_Add(226, 80,28,36,(char *)"i", 7);
    Buttons_Add(258, 80,28,36,(char *)"o", 8);
    Buttons_Add(290, 80,28,36,(char *)"p", 9);

    Buttons_Add( 18,120,28,36,(char *)"a",10);
    Buttons_Add( 50,120,28,36,(char *)"s",11);
    Buttons_Add( 82,120,28,36,(char *)"d",12);
    Buttons_Add(114,120,28,36,(char *)"f",13);
    Buttons_Add(146,120,28,36,(char *)"g",14);
    Buttons_Add(178,120,28,36,(char *)"h",15);
    Buttons_Add(210,120,28,36,(char *)"j",16);
    Buttons_Add(242,120,28,36,(char *)"k",17);
    Buttons_Add(274,120,28,36,(char *)"l",18);

    Buttons_Add( 50,160,28,36,(char *)"z",19);
    Buttons_Add( 82,160,28,36,(char *)"x",20);
    Buttons_Add(114,160,28,36,(char *)"c",21);
    Buttons_Add(146,160,28,36,(char *)"v",22);
    Buttons_Add(178,160,28,36,(char *)"b",23);
    Buttons_Add(210,160,28,36,(char *)"n",24);
    Buttons_Add(242,160,28,36,(char *)"m",25);

    Buttons_Add(  2,160,42,36,(char *)"caps",26);
    Buttons[26].dark = true;
    Buttons[26].small = true;
    Buttons[26].lock = false;
    Buttons_Add(276,160,42,36,(char *)"del",27);
    Buttons[27].dark = true;
    Buttons[27].small = true;

    Buttons_Add(  2,200,60,36,(char *)"123",28);
    Buttons[28].dark = true;
    Buttons_Add( 72,200,28,36,(char *)"/",29);
    Buttons_Add(108,200,104,36,(char *)" ",30);
    Buttons_Add(220,200,28,36,(char *)".",31);
    Buttons_Add(258,200,60,36,(char *)"Ok",32);
    Buttons[32].dark = true;

    Buttons_Show();
}



static const uint8_t alphacaps_tab[] = { 'Q','W','E','R','T','Y','U','I','O','P',
					 'A','S','D','F','G','H','J','K','L',
					 'Z','X','C','V','B','N','M' };

/**
 * @brief Level 2 and 3 keys, uppercase alpha.
 */
void B_AlphaCaps(int level)
{
    Buttons_Clear();

    Buttons_Add(  2, 80,28,36,(char *)"Q", 0);
    Buttons_Add( 34, 80,28,36,(char *)"W", 1);
    Buttons_Add( 66, 80,28,36,(char *)"E", 2);
    Buttons_Add( 98, 80,28,36,(char *)"R", 3);
    Buttons_Add(130, 80,28,36,(char *)"T", 4);
    Buttons_Add(162, 80,28,36,(char *)"Y", 5);
    Buttons_Add(194, 80,28,36,(char *)"U", 6);
    Buttons_Add(226, 80,28,36,(char *)"I", 7);
    Buttons_Add(258, 80,28,36,(char *)"O", 8);
    Buttons_Add(290, 80,28,36,(char *)"P", 9);

    Buttons_Add( 18,120,28,36,(char *)"A",10);
    Buttons_Add( 50,120,28,36,(char *)"S",11);
    Buttons_Add( 82,120,28,36,(char *)"D",12);
    Buttons_Add(114,120,28,36,(char *)"F",13);
    Buttons_Add(146,120,28,36,(char *)"G",14);
    Buttons_Add(178,120,28,36,(char *)"H",15);
    Buttons_Add(210,120,28,36,(char *)"J",16);
    Buttons_Add(242,120,28,36,(char *)"K",17);
    Buttons_Add(274,120,28,36,(char *)"L",18);

    Buttons_Add( 50,160,28,36,(char *)"Z",19);
    Buttons_Add( 82,160,28,36,(char *)"X",20);
    Buttons_Add(114,160,28,36,(char *)"C",21);
    Buttons_Add(146,160,28,36,(char *)"V",22);
    Buttons_Add(178,160,28,36,(char *)"B",23);
    Buttons_Add(210,160,28,36,(char *)"N",24);
    Buttons_Add(242,160,28,36,(char *)"M",25);

    Buttons_Add(  2,160,42,36,(char *)"caps",26);
    Buttons[26].dark = true;
    Buttons[26].small = true;
    if (level == 3)
	Buttons[26].lock = true;
    else
	Buttons[26].lock = false;
    Buttons_Add(276,160,42,36,(char *)"del",27);
    Buttons[27].dark = true;
    Buttons[27].small = true;

    Buttons_Add(  2,200,60,36,(char *)"123",28);
    Buttons[28].dark = true;
    Buttons_Add( 72,200,28,36,(char *)"/",29);
    Buttons_Add(108,204,100,36,(char *)" ",30);
    Buttons_Add(220,200,28,36,(char *)".",31);
    Buttons_Add(258,200,60,36,(char *)"Ok",32);
    Buttons[32].dark = true;

    Buttons_Show();
}



static const uint8_t nums1_tab[] = { '1','2','3','4','5','6','7','8','9','0', 
				     '!','@','#','$','/','^','&','*','(',')', 
				     '-','\'','\"',':',';',',','?' };

/**
 * @brief Level 4, numeric keys and symbol
 */
void B_Nums1(void)
{
    Buttons_Clear();

    Buttons_Add(  2, 80,28,36,(char *)"1", 0);
    Buttons_Add( 34, 80,28,36,(char *)"2", 1);
    Buttons_Add( 66, 80,28,36,(char *)"3", 2);
    Buttons_Add( 98, 80,28,36,(char *)"4", 3);
    Buttons_Add(130, 80,28,36,(char *)"5", 4);
    Buttons_Add(162, 80,28,36,(char *)"6", 5);
    Buttons_Add(194, 80,28,36,(char *)"7", 6);
    Buttons_Add(226, 80,28,36,(char *)"8", 7);
    Buttons_Add(258, 80,28,36,(char *)"9", 8);
    Buttons_Add(290, 80,28,36,(char *)"0", 9);

    Buttons_Add(  2,120,28,36,(char *)"!",10);
    Buttons_Add( 34,120,28,36,(char *)"@",11);
    Buttons_Add( 66,120,28,36,(char *)"#",12);
    Buttons_Add( 98,120,28,36,(char *)"$",13);
    Buttons_Add(130,120,28,36,(char *)"/",14);
    Buttons_Add(162,120,28,36,(char *)"^",15);
    Buttons_Add(194,120,28,36,(char *)"&",16);
    Buttons_Add(226,120,28,36,(char *)"*",17);
    Buttons_Add(258,120,28,36,(char *)"(",18);
    Buttons_Add(290,120,28,36,(char *)")",19);

    Buttons_Add( 50,160,28,36,(char *)"-",20);
    Buttons_Add( 82,160,28,36,(char *)"'",21);
    Buttons_Add(114,160,28,36,(char *)"\"",22);
    Buttons_Add(146,160,28,36,(char *)":",23);
    Buttons_Add(178,160,28,36,(char *)";",24);
    Buttons_Add(210,160,28,36,(char *)",",25);
    Buttons_Add(242,160,28,36,(char *)"?",26);

    Buttons_Add(  2,160,42,36,(char *)"1/2",27);
    Buttons[27].dark = true;
    Buttons_Add(276,160,42,36,(char *)"del",28);
    Buttons[28].dark = true;
    Buttons[28].small = true;

    Buttons_Add(  2,200,60,36,(char *)"ABC",29);
    Buttons[29].dark = true;
    Buttons_Add( 72,200,28,36,(char *)"/",30);
    Buttons_Add(108,204,100,36,(char *)" ",31);
    Buttons_Add(220,200,28,36,(char *)".",32);
    Buttons_Add(258,200,60,36,(char *)"Ok",33);
    Buttons[33].dark = true;

    Buttons_Show();
}


static const uint8_t nums2_tab[] = { '+','*','/','=','<','>','{','}','[',']',
	                             ' ',' ',' ',' ','%','~','`',' ',' ',' ',
				     '_','\\','|',' ',' ',' ',' ' };

/**
 * @brief Level 5, symbol keys
 */
void B_Nums2(void)
{
    Buttons_Clear();

    Buttons_Add(  2, 80,28,36,(char *)"+", 0);
    Buttons_Add( 34, 80,28,36,(char *)"*", 1);
    Buttons_Add( 66, 80,28,36,(char *)"/", 2);
    Buttons_Add( 98, 80,28,36,(char *)"=", 3);
    Buttons_Add(130, 80,28,36,(char *)"<", 4);
    Buttons_Add(162, 80,28,36,(char *)">", 5);
    Buttons_Add(194, 80,28,36,(char *)"{", 6);
    Buttons_Add(226, 80,28,36,(char *)"}", 7);
    Buttons_Add(258, 80,28,36,(char *)"[", 8);
    Buttons_Add(290, 80,28,36,(char *)"]", 9);

    Buttons_Add(  2,120,28,36,(char *)" ",10);
    Buttons_Add( 34,120,28,36,(char *)" ",11);
    Buttons_Add( 66,120,28,36,(char *)" ",12);
    Buttons_Add( 98,120,28,36,(char *)" ",13);
    Buttons_Add(130,120,28,36,(char *)"%",14);
    Buttons_Add(162,120,28,36,(char *)"~",15);
    Buttons_Add(194,120,28,36,(char *)"`",16);
    Buttons_Add(226,120,28,36,(char *)" ",17);
    Buttons_Add(258,120,28,36,(char *)" ",18);
    Buttons_Add(290,120,28,36,(char *)" ",19);

    Buttons_Add( 50,160,28,36,(char *)"_",20);
    Buttons_Add( 82,160,28,36,(char *)"\\",21);
    Buttons_Add(114,160,28,36,(char *)"|",22);
    Buttons_Add(146,160,28,36,(char *)" ",23);
    Buttons_Add(178,160,28,36,(char *)" ",24);
    Buttons_Add(210,160,28,36,(char *)" ",25);
    Buttons_Add(242,160,28,36,(char *)" ",26);

    Buttons_Add(  2,160,42,36,(char *)"2/2",27);
    Buttons[27].dark = true;
    Buttons_Add(276,160,42,36,(char *)"del",28);
    Buttons[28].dark = true;
    Buttons[28].small = true;

    Buttons_Add(  2,200,60,36,(char *)"ABC",29);
    Buttons[29].dark = true;
    Buttons_Add( 72,200,28,36,(char *)"/",30);
    Buttons_Add(108,204,100,36,(char *)" ",31);
    Buttons_Add(220,200,28,36,(char *)".",32);
    Buttons_Add(258,200,60,36,(char *)"Ok",33);
    Buttons[33].dark = true;

    Buttons_Show();
}


static const uint8_t digits_tab[] = { '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '+', '-', '.' };

/**
 * @brief A small nummeric keyboard
 */
void B_Digits(void)
{
    Buttons_Clear();

    Buttons_Add( 61,200,147,36,(char *)"0", 9);

    Buttons_Add( 61,160,47,36,(char *)"1", 0);
    Buttons_Add(111,160,47,36,(char *)"2", 1);
    Buttons_Add(161,160,47,36,(char *)"3", 2);
    Buttons_Add(211,160,47,36,(char *)"+",10);
    Buttons[10].dark = true;

    Buttons_Add( 61,120,47,36,(char *)"4", 3);
    Buttons_Add(111,120,47,36,(char *)"5", 4);
    Buttons_Add(161,120,47,36,(char *)"6", 5);
    Buttons_Add(211,120,47,36,(char *)"-",11);
    Buttons[11].dark = true;

    Buttons_Add( 61, 80,47,36,(char *)"7", 6);
    Buttons_Add(111, 80,47,36,(char *)"8", 7);
    Buttons_Add(161, 80,47,36,(char *)"9", 8);
    Buttons_Add(211, 80,47,36,(char *)".",12);
    Buttons[12].dark = true;

    Buttons_Add(211,200,47,36,(char *)"del",13);
    Buttons[13].dark = true;
    Buttons[13].small = true;

    Buttons_Add(271,200,47,36,(char *)"Ok",14);
    Buttons[14].dark = true;

    Buttons_Show();
}



int KeyBoardAll(void)
{
    int		key;

    key = Buttons_Scan();
    if (key == -1)
	return -1;

    switch (level) {
	    case 1:	if (key >= 0 && key <= 25) {
			    key = alphalow_tab[key];
	    		} else if (key == 26) {
			    level = 2;
			    B_AlphaCaps(level);
			} else if (key == 27) {
			    key = 127;
			} else if (key == 28) {
			    level = 4;
			    B_Nums1();
			} else if (key == 29) {
			    key = '/';
			} else if (key == 30) {
			    key = ' ';
			} else if (key == 31) {
			    key = '.';
			} else if (key == 32) {
			    key = 0;
			}
			break;
	    case 2:
	    case 3:	if (key >= 0 && key <= 25) {
			    key = alphacaps_tab[key];
			    if (level == 2) {
				level = 1;
				B_AlphaLow();
			    }
			} else if (key == 26 && level == 3) {
			    level = 1;
			    B_AlphaLow();
			} else if (key == 26 && level == 2) {
			    level = 3;
			    B_AlphaCaps(level);
			} else if (key == 27) {
			    key = 127;
			} else if (key == 28) {
			    level = 4;
			    B_Nums1();
			} else if (key == 29) {
			    key = '/';
			} else if (key == 30) {
			    key = ' ';
			} else if (key == 31) {
			    key = '.';
			} else if (key == 32) {
			    key = 0;
			}
			break;
	    case 4:	if (key >= 0 && key <= 26) {
			    key = nums1_tab[key];
			} else if (key == 27) {
			    level = 5;
			    B_Nums2();
			} else if (key == 28) {
			    key = 127;
			} else if (key == 29) {
			    level = 1;
			    B_AlphaLow();
			} else if (key == 30) {
			    key = '/';
			} else if (key == 31) {
			    key = ' ';
			} else if (key == 32) {
			    key = '.';
			} else if (key == 33) {
			    key = 0;
			}
			break;
	    case 5:	if (key >= 0 && key <= 26) {
			    key = nums2_tab[key];
			} else if (key == 27) {
			    level = 4;
			    B_Nums1();
			} else if (key == 28) {
			    key = 127;
			} else if (key == 29) {
			    level = 1;
			    B_AlphaLow();
			} else if (key == 30) {
			    key = '/';
			} else if (key == 31) {
			    key = ' ';
			} else if (key == 32) {
			    key = '.';
			} else if (key == 33) {
			    key = 0;
			}
			break;
    }

    return key;
}


int KeyBoardDigits(void)
{
    int         key;

    key = Buttons_Scan();
    if (key == -1)
	return -1;

    if (key >= 0 && key <= 12) {
	key = digits_tab[key];
    } else if (key == 13) {
	key = 127;
    } else if  (key == 14) {
	key = 0;
    }

    return key;
}



/**************************************************************************/
/*
 *  Data show and edit functions.
 */

void ShowText(uint16_t x, uint16_t y, char *label, char *txt)
{
    _fg = TFT_LIGHTGREY;
    TFT_print(label, x, y);
    _fg = TFT_YELLOW;
    TFT_print((char *)" ", LASTX, LASTY);
    TFT_print(txt, LASTX, LASTY);
}



void ShowInteger(uint16_t x, uint16_t y, char *label, char *suffix, int val)
{
    char        tmp[32];

    _fg = TFT_LIGHTGREY;
    TFT_print(label, x, y);
    _fg = TFT_YELLOW;
   sprintf(tmp, " %d", val);
   TFT_print(tmp, LASTX, LASTY);
   if (suffix) {
        _fg = TFT_LIGHTGREY;
        TFT_print(suffix, LASTX, LASTY);
   }
}



void ShowBool(uint16_t x, uint16_t y, char *label, bool val)
{
    _fg = TFT_LIGHTGREY;
    TFT_print(label, x, y);
    _fg = TFT_YELLOW;
    if (val)
        TFT_print((char *)" J", LASTX, LASTY);
    else
        TFT_print((char *)" N", LASTX, LASTY);
}



void ShowSSR2(uint16_t x, uint16_t y, int val)
{
    _fg = TFT_LIGHTGREY;
    TFT_print((char *)"SSR2 ", x, y);
    _fg = TFT_YELLOW;
    TFT_clearStringRect(TFT_X, TFT_Y, (char *)"HLT en MLT");
    TFT_print((char *)SSR2Types[val], LASTX, LASTY);
}



void ShowFloat(uint16_t x, uint16_t y, char *label, char *suffix, float val, int decimals)
{
    char        tmp[32];

    _fg = TFT_LIGHTGREY;
    TFT_print(label, x, y);
    _fg = TFT_YELLOW;
    sprintf(tmp, " %.*f", decimals, val);
    TFT_print(tmp, LASTX, LASTY);
    if (suffix) {
        _fg = TFT_LIGHTGREY;
        TFT_print(suffix, LASTX, LASTY);
    }
}



void ShowDouble(uint16_t x, uint16_t y, char *label, char *suffix, double val, int decimals)
{
    char        tmp[32];

    _fg = TFT_LIGHTGREY;
    TFT_print(label, x, y);
    _fg = TFT_YELLOW;
    sprintf(tmp, " %.*f", decimals, val);
    TFT_print(tmp, LASTX, LASTY);
    if (suffix) {
	_fg = TFT_LIGHTGREY;
	TFT_print(suffix, LASTX, LASTY);
    }
}



void Editer(char *label, char *txt, char *errmsg, int len, int type)
{
    int		key;

    _bg = TFT_BLACK;
    TFT_fillScreen(_bg);
    TFT_resetclipwin();
    TopMessage((char *)"Wijzigen");
    _fg = TFT_LIGHTGREY;
    TFT_setFont(DEFAULT_FONT, NULL);
    TFT_print(label, 2, 28);
    if (strlen(errmsg)) {
	_fg = TFT_RED;
	TFT_print(errmsg, 2, 60);
    }
    TFT_fillRect(2, 40, 10 * len, 14, TFT_BLUE);
    _fg = TFT_YELLOW;
    _bg = TFT_BLUE;
    TFT_print(txt, 2, 41);
    TFT_fillRect(TFT_X, 50, 10, 4, TFT_GREEN);

    switch(type) {
	case EDIT_TYPE_INT:	
			B_Digits();
			break;

	default:	level = 1;
			B_AlphaLow();
			break;
    }

    while (1) {
	switch (type) {
	   case  EDIT_TYPE_INT:
		   	key = KeyBoardDigits();
			break;

	    default:	key = KeyBoardAll();
			break;
	}

	if (key != -1) {

	    if (key >= 32 && key <= 126 && strlen(txt) < len) {
	    	// Append key
		txt[strlen(txt) + 1] = '\0';
	    	txt[strlen(txt)] = key;
	    } else if (key == 127 && strlen(txt)) {
	    	// Delete key
	    	txt[strlen(txt) - 1] = '\0';
	    }

	    _fg = TFT_YELLOW;
	    _bg = TFT_BLACK;
	    TFT_setFont(DEFAULT_FONT, NULL);
	    TFT_fillRect(2, 40, 10 * len, 14, TFT_BLUE);
	    TFT_print(txt, 2, 41);
	    TFT_fillRect(TFT_X, 50, 10, 4, TFT_GREEN);
	}

	if (key == 0)
	    break;

	vTaskDelay(20 / portTICK_PERIOD_MS);
    }
}



void EditText(char *label, char *txt, int len)
{
    char		errmsg[40];

    errmsg[0] = '\0';
    while (1) {
    	Editer(label, txt, errmsg, len, EDIT_TYPE_TEXT);
	if (strlen(txt))
	    break;
	sprintf(errmsg, "Tekst veld mag niet leeg zijn");
    }
}



void EditTextMin(char *label, char *txt, int len, int min)
{
    char                errmsg[40];

    errmsg[0] = '\0';
    while (1) {
	Editer(label, txt, errmsg, len, EDIT_TYPE_TEXT);
	if (strlen(txt) >= min)
	    break;
	sprintf(errmsg, "Tekst veld moet tussen %d en %d lang zijn", min, len);
    }
}



void EditInt(char *label, int *val, int min, int max)
{
    char	*valstr, errmsg[40];
    int		newval;

    errmsg[0] = '\0';
    valstr = malloc(20);
    sprintf(valstr, "%d", *val);

    while (1) {
	Editer(label, valstr, errmsg, 8, EDIT_TYPE_INT);
	newval = atoi(valstr);
	if (newval < min || newval > max) {
	    sprintf(errmsg, "De waarde moet tussen %d en %d zijn.", min, max);
	} else {
	    break;
	}
    }

    *val = newval;
    free(valstr);
}



void EditUint8(char *label, uint8_t *val, uint8_t min, uint8_t max)
{
    char        *valstr, errmsg[40];
    uint8_t	newval;

    errmsg[0] = '\0';
    valstr = malloc(20);
    sprintf(valstr, "%d", *val);

    while (1) {
	Editer(label, valstr, errmsg, 5, EDIT_TYPE_INT);
	newval = atoi(valstr);
	if (newval < min || newval > max) {
	    sprintf(errmsg, "De waarde moet tussen %d en %d zijn.", min, max);
	} else {
	    break;
	}
    }

    *val = newval;
    free(valstr);
}



void EditUint16(char *label, uint16_t *val, uint16_t min, uint16_t max)
{   
    char        *valstr, errmsg[64];
    uint16_t     newval;

    errmsg[0] = '\0';
    valstr = malloc(20);
    sprintf(valstr, "%d", *val);

    while (1) {
	Editer(label, valstr, errmsg, 5, EDIT_TYPE_INT);
	newval = atoi(valstr);
	if (newval < min || newval > max) {
	    sprintf(errmsg, "De waarde moet tussen %d en %d zijn.", min, max);
	} else {
	    break;
	}
    }

    *val = newval;
    free(valstr);
}



void EditFloat(char *label, float *val, float min, float max, int decimals)
{
    char        *valstr, errmsg[672];
    float	newval;

    errmsg[0] = '\0';
    valstr = malloc(30);
    sprintf(valstr, " %.*f", decimals, *val);

    while (1) {
	Editer(label, valstr, errmsg, 25, EDIT_TYPE_INT);
	newval = atof(valstr);
	if (newval < min || newval > max) {
	    sprintf(errmsg, "De waarde moet tussen %.2f en %.2f zijn.", min, max);
	} else {
	    break;
	}
    }

    *val = newval;
    free(valstr);
}



void EditDouble(char *label, double *val, double min, double max, int decimals)
{
    char        *valstr, errmsg[672];
    double	newval;

    errmsg[0] = '\0';
    valstr = malloc(30);
    sprintf(valstr, " %.*f", decimals, *val);

    while (1) {
	Editer(label, valstr, errmsg, 25, EDIT_TYPE_INT);
	newval = atof(valstr);
	if (newval < min || newval > max) {
	    sprintf(errmsg, "De waarde moet tussen %.2f en %.2f zijn.", min, max);
	} else {
	    break;
	}
    }

    *val = newval;
    free(valstr);
}



void EditBool(char *label, bool *val)
{
    bool	loop = true, value = *val;
    int		curpos;

    _bg = TFT_BLACK;
    TFT_fillScreen(_bg);
    TFT_resetclipwin();
    TopMessage((char *)"Wijzigen");
    _fg = TFT_LIGHTGREY;
    TFT_setFont(DEFAULT_FONT, NULL);
    TFT_print(label, 2, 28);
    curpos = TFT_X;
    _fg = TFT_YELLOW;
    (value) ? TFT_print((char *)" J ", curpos, 28) : TFT_print((char *)" N ", curpos, 28);

    Buttons_Clear();
    Buttons_Add( 40, 100, 80, 40, (char *)"J/N", 0);
    Buttons_Add(200, 100, 80, 40, (char *)"Ok",  1);
    Buttons_Show();

    while (loop) {
	switch (Buttons_Scan()) {
	    case 0:	TFT_setFont(DEFAULT_FONT, NULL);
			_fg = TFT_YELLOW;
		    	if (value) {
			    value = false;
			    TFT_print((char *)" N ", curpos, 28);
			} else {
			    value = true;
			    TFT_print((char *)" J ", curpos, 28);
			}
			break;

	    case 1:	loop = false;
			break;

	    default:	break;
	}
	vTaskDelay(20 / portTICK_PERIOD_MS);
    }
    *val = value;
}



void EditSSR2(int *val)
{
    bool        loop = true;
    int		value = *val;
    int		key;

    _bg = TFT_BLACK;
    TFT_fillScreen(_bg);
    TFT_resetclipwin();
    TopMessage((char *)"Wijzigen");

    Buttons_Clear();
    Buttons_Add( 20,  60,120, 40, (char *)SSR2Types[0], 0);
    Buttons_Add(180,  60,120, 40, (char *)SSR2Types[1], 1);
    Buttons_Add( 20, 130,120, 40, (char *)SSR2Types[2], 2);
    Buttons_Add(180, 130,120, 40, (char *)SSR2Types[3], 3);
    Buttons_Add(120, 200, 80, 40, (char *)"Ok",  4);
    Buttons[4].dark = true;
    Buttons[value].lock = true;
    Buttons_Show();

    while (loop) {
	key = Buttons_Scan();

	if (key >= 0 && key <= 3) {
	    Buttons[value].lock = false;
	    value = key;
	    Buttons[value].lock = true;
	    Buttons_Show();
	} else if (key == 4) {
	    loop = false;
	}
        vTaskDelay(20 / portTICK_PERIOD_MS);
    }
    *val = value;
}



void EditMashType(uint8_t *val)
{
    bool        loop = true;
    int		value = (int)*val;
    int         key;

    _bg = TFT_BLACK;
    TFT_fillScreen(_bg);
    TFT_resetclipwin();
    TopMessage((char *)"Wijzigen");

    Buttons_Clear();
    Buttons_Add( 80,  40,160, 40, (char *)mashTypes[0], 0);
    Buttons_Add( 80,  90,160, 40, (char *)mashTypes[1], 1);
    Buttons_Add( 80, 140,160, 40, (char *)mashTypes[2], 2);
    Buttons_Add(120, 200, 80, 40, (char *)"Ok",  3);
    Buttons[3].dark = true;
    Buttons[value].lock = true;
    Buttons_Show();

    while (loop) {
	key = Buttons_Scan();

	if (key >= 0 && key <= 2) {
	    Buttons[value].lock = false;
	    value = key;
	    Buttons[value].lock = true;
	    Buttons_Show();
	} else if (key == 3) {
	    loop = false;
	}
	vTaskDelay(20 / portTICK_PERIOD_MS);
    }
    Buttons[value].lock = false;
    *val = (uint8_t)value;
}



int Confirm(char *top, char *ack, char *nak)
{
    int		rc = false;
    bool	loop = true;

    TFT_fillScreen(TFT_BLACK);
    TopMessage(top);
    Buttons_Clear();
    Buttons_Add( 40, 100, 80, 40, ack, 0);
    Buttons_Add(200, 100, 80, 40, nak, 1);
    Buttons_Show();
    SoundPlay(SOUND_Prompt);

    while (loop) {
	switch (Buttons_Scan()) {
	    case 0:	loop = false;
			rc = true;
			break;

	    case 1:	loop = false;
			rc = false;
			break;

	    default:
			break;
	}
	vTaskDelay(50 / portTICK_PERIOD_MS);
    }

    Buttons_Clear();
    return rc;
}

mercurial