From 76ea9d89727ffd88cd4f78e289837119d61a7c6d Mon Sep 17 00:00:00 2001 From: t-moe Date: Thu, 30 Apr 2015 23:22:30 +0200 Subject: [PATCH] Added num up down support. --- common/app/screen_guitest.c | 20 +++++- common/gui/numupdown.c | 121 ++++++++++++++++++++++++++++++++++++ common/gui/numupdown.h | 22 +++++++ common/tft/tft.c | 12 +++- common/tft/tft.h | 1 + 5 files changed, 170 insertions(+), 6 deletions(-) create mode 100644 common/gui/numupdown.c create mode 100644 common/gui/numupdown.h diff --git a/common/app/screen_guitest.c b/common/app/screen_guitest.c index f4f40cd..d2d93e3 100644 --- a/common/app/screen_guitest.c +++ b/common/app/screen_guitest.c @@ -2,11 +2,12 @@ #include "button.h" #include "tft.h" #include "checkbox.h" - +#include "numupdown.h" static BUTTON_STRUCT b_back; static TOUCH_AREA_STRUCT a_area; static CHECKBOX_STRUCT c_cbox; +static NUMUPDOWN_STRUCT n_updown; static void checkboxCB(void *checkbox, bool checked) { printf("Checkbox %s\n",(checked?"checked":"unchecked")); @@ -16,6 +17,10 @@ static void b_back_cb(void* button) { gui_screen_back(); } +static void n_updown_cb(void* numupdown, int16_t value) { + printf("New NumUpDown Value %d\n",value); +} + static void touchCB(void* touchArea, TOUCH_ACTION triggeredAction) { switch(triggeredAction) { @@ -87,15 +92,24 @@ static void enter(void* screen) { c_cbox.checked = true; c_cbox.callback = checkboxCB; gui_checkbox_add(&c_cbox); + - - + //Num up down test + n_updown.x=200; + n_updown.y=120; + n_updown.fgcolor=RED; + n_updown.value = -3; + n_updown.max=11; + n_updown.min =-5; + n_updown.callback=n_updown_cb; + gui_numupdown_add(&n_updown); } static void leave(void* screen) { gui_button_remove(&b_back); gui_checkbox_remove(&c_cbox); + gui_numupdown_remove(&n_updown); touch_unregister_area(&a_area); } diff --git a/common/gui/numupdown.c b/common/gui/numupdown.c new file mode 100644 index 0000000..15ea0a8 --- /dev/null +++ b/common/gui/numupdown.c @@ -0,0 +1,121 @@ +#include "tft.h" +#include "touch.h" +#include "button.h" +#include "numupdown.h" +#include //for sprintf +#include //for offsetof macro +#include //for abs + + +#define BASE_COLOR RGB(90,90,90) +void button_up_cb(void* button) +{ + NUMUPDOWN_STRUCT* element = button-offsetof(NUMUPDOWN_STRUCT,buttonUp); + if(element->valuemax) { + element->value++; + gui_numupdown_update(element); + if(element->callback!=NULL) { + element->callback(element,element->value); + } + } +} + +void button_down_cb(void* button) +{ + NUMUPDOWN_STRUCT* element = button-offsetof(NUMUPDOWN_STRUCT,buttonDown); + if(element->value>element->min) { + element->value--; + gui_numupdown_update(element); + if(element->callback!=NULL) { + element->callback(element,element->value); + } + } +} + + +static uint8_t calc_text_width(int16_t val) { + uint8_t width = 1 + (val<0); //1 if positive, 2 if negative (to let space for sign) + val=abs(val); + while(val>=10) { + val/=10; + width++; + } + return width; +} + + +bool gui_numupdown_add(NUMUPDOWN_STRUCT* numupdown) +{ + if(touch_have_empty(2)) //We require 2 TouchAreas (for Buttons) + { + if(numupdown->min > numupdown->max) return false; + + if(numupdown->value > numupdown->max) { + numupdown->value = numupdown->max; + } + if(numupdown->value < numupdown->min) { + numupdown->value = numupdown->min; + } else if(numupdown->value > numupdown->max) { + numupdown->value = numupdown->max; + } + + uint8_t tw1 = calc_text_width(numupdown->max); + uint8_t tw2 = calc_text_width(numupdown->min); + if(tw2 > tw1) tw1 = tw2; + uint8_t width= tft_font_width(0)*(tw1+1); + + numupdown->buttonUp.base.x1=numupdown->x; + numupdown->buttonUp.base.y1=numupdown->y; + numupdown->buttonUp.base.x2=numupdown->x+width; + numupdown->buttonUp.base.y2=AUTO; + numupdown->buttonUp.text="+"; + numupdown->buttonUp.font=0; + numupdown->buttonUp.bgcolor=BASE_COLOR; + numupdown->buttonUp.txtcolor=WHITE; + numupdown->buttonUp.callback = button_up_cb; + gui_button_add(&numupdown->buttonUp); + numupdown->buttonDown.base.x1=numupdown->x; + numupdown->buttonDown.base.y1=numupdown->buttonUp.base.y2+2*tft_font_height(0); + numupdown->buttonDown.base.x2=numupdown->x+width; + numupdown->buttonDown.base.y2=AUTO; + numupdown->buttonDown.text="-"; + numupdown->buttonDown.font=0; + numupdown->buttonDown.bgcolor=BASE_COLOR; + numupdown->buttonDown.txtcolor=WHITE; + numupdown->buttonDown.callback = button_down_cb; + gui_button_add(&numupdown->buttonDown); + + tft_fill_rectangle(numupdown->x,numupdown->buttonUp.base.y2+1,numupdown->x+width,numupdown->buttonDown.base.y1-1,BASE_COLOR); + tft_print_formatted(numupdown->x+tft_font_width(0)/2,numupdown->buttonUp.base.y2+tft_font_height(0)/2,numupdown->fgcolor,BASE_COLOR,0,"%*d",tw1,numupdown->value); + + return true; + } + return false; + } + +void gui_numupdown_remove(NUMUPDOWN_STRUCT* numupdown) + { + gui_button_remove(&numupdown->buttonUp); + gui_button_remove(&numupdown->buttonDown); + } + +void gui_numupdown_update(NUMUPDOWN_STRUCT* numupdown) + { + + + uint8_t tw1 = calc_text_width(numupdown->max); + uint8_t tw2 = calc_text_width(numupdown->min); + if(tw2 > tw1) tw1 = tw2; + uint8_t width= tft_font_width(0)*(tw1+1); + + + tft_fill_rectangle(numupdown->x,numupdown->buttonUp.base.y2+1,numupdown->x+width,numupdown->buttonDown.base.y1-1,BASE_COLOR); + tft_print_formatted(numupdown->x+tft_font_width(0)/2,numupdown->buttonUp.base.y2+tft_font_height(0)/2,numupdown->fgcolor,BASE_COLOR,0,"%*d",tw1,numupdown->value); + } + + void gui_numupdown_redraw(NUMUPDOWN_STRUCT* numupdown) + { + gui_button_redraw(&numupdown->buttonUp); + gui_button_redraw(&numupdown->buttonDown); + gui_numupdown_update(numupdown); + } diff --git a/common/gui/numupdown.h b/common/gui/numupdown.h new file mode 100644 index 0000000..09a4abb --- /dev/null +++ b/common/gui/numupdown.h @@ -0,0 +1,22 @@ +#include "button.h" + +typedef void (*NUMUPDOWN_CALLBACK)(void *numupdown, int16_t value); //!< Function pointer used... +typedef struct { + uint16_t x; + uint16_t y; + uint16_t fgcolor; + int16_t value; + int16_t min; + int16_t max; + NUMUPDOWN_CALLBACK callback; //Callback + + //Internally used: + BUTTON_STRUCT buttonUp; + BUTTON_STRUCT buttonDown; +} NUMUPDOWN_STRUCT; + + +bool gui_numupdown_add(NUMUPDOWN_STRUCT* numupdown); +void gui_numupdown_remove(NUMUPDOWN_STRUCT* numupdown); +void gui_numupdown_update(NUMUPDOWN_STRUCT* numupdown); +void gui_numupdown_redraw(NUMUPDOWN_STRUCT* numupdown); diff --git a/common/tft/tft.c b/common/tft/tft.c index 4522a20..67fc977 100644 --- a/common/tft/tft.c +++ b/common/tft/tft.c @@ -1,9 +1,7 @@ #include "tft.h" #include "ll_tft.h" #include - - -//it might seems pointless to forward all the functions but we might also introduce functions which have some logic here +#include bool tft_init() { return ll_tft_init(); @@ -60,3 +58,11 @@ void tft_print_line(uint16_t x, uint16_t y, uint16_t color, uint16_t bgcolor, ui } } +void tft_print_formatted(uint16_t x, uint16_t y, uint16_t color, uint16_t bgcolor, uint8_t font, const char* format, ...) { + static char buffer[256]; //not sure if that's the best solution. It would propbably better to implement putchar and use vprintf + va_list args; + va_start (args, format); + vsprintf(buffer,format,args); + tft_print_line(x,y,color,bgcolor,font,buffer); + va_end(args); +} diff --git a/common/tft/tft.h b/common/tft/tft.h index 558f88e..42484a8 100644 --- a/common/tft/tft.h +++ b/common/tft/tft.h @@ -26,3 +26,4 @@ uint8_t tft_num_fonts(); uint8_t tft_font_height(uint8_t fontnum); uint8_t tft_font_width(uint8_t fontnum); void tft_print_line(uint16_t x, uint16_t y, uint16_t color, uint16_t bgcolor, uint8_t font, const char* text); +void tft_print_formatted(uint16_t x, uint16_t y, uint16_t color, uint16_t bgcolor, uint8_t font, const char* format, ...);