diff --git a/lv_objx/lv_spinbox.c b/lv_objx/lv_spinbox.c index 13e19de7a..726121e59 100644 --- a/lv_objx/lv_spinbox.c +++ b/lv_objx/lv_spinbox.c @@ -10,6 +10,7 @@ #if USE_LV_SPINBOX != 0 #include "../lv_themes/lv_theme.h" +#include "../lv_misc/lv_math.h" /********************* * DEFINES @@ -64,12 +65,12 @@ lv_obj_t * lv_spinbox_create(lv_obj_t * par, const lv_obj_t * copy) /*Initialize the allocated 'ext'*/ ext->ta.one_line = 1; ext->ta.pwd_mode = 0; - ext->ta.accapted_chars = "1234567890+-."; + ext->ta.accapted_chars = "1234567890+-. "; ext->value = 0; ext->dec_point_pos = 0; - ext->digit_count = 5; - ext->digit_padding_left = 0; + ext->digit_count = 8; + ext->digit_padding_left = 2; ext->step = 1; ext->range_max = 99999; ext->range_min = -99999; @@ -188,13 +189,11 @@ void lv_spinbox_set_range(lv_obj_t * spinbox, int32_t range_min, int32_t range_m ext->range_max = range_max; ext->range_min = range_min; - if(ext->value > ext->range_max) - { + if(ext->value > ext->range_max) { ext->value = ext->range_max; lv_obj_invalidate(spinbox); } - if(ext->value < ext->range_min) - { + if(ext->value < ext->range_min) { ext->value = ext->range_min; lv_obj_invalidate(spinbox); } @@ -251,11 +250,9 @@ void lv_spinbox_step_next(lv_obj_t * spinbox) { lv_spinbox_ext_t * ext = lv_obj_get_ext_attr(spinbox); - - if((ext->step / 10) < ext->range_max && (ext->step / 10) > ext->range_min && (ext->step / 10) > 0) - { - ext->step /= 10; - } + int32_t new_step = ext->step / 10; + if((new_step) > 0) ext->step = new_step; + else ext->step = 1; lv_spinbox_updatevalue(spinbox); } @@ -268,11 +265,8 @@ void lv_spinbox_step_previous(lv_obj_t * spinbox) { lv_spinbox_ext_t * ext = lv_obj_get_ext_attr(spinbox); - - if((ext->step * 10) <= ext->range_max && (ext->step * 10) > ext->range_min && (ext->step * 10) > 0) - { - ext->step *= 10; - } + int32_t new_step = ext->step * 10; + if(new_step <= ext->range_max) ext->step = new_step; lv_spinbox_updatevalue(spinbox); } @@ -285,20 +279,16 @@ void lv_spinbox_increment(lv_obj_t * spinbox) { lv_spinbox_ext_t * ext = lv_obj_get_ext_attr(spinbox); - if(ext->value + ext->step <= ext->range_max) - { + if(ext->value + ext->step <= ext->range_max) { /*Special mode when zero crossing*/ - if((ext->value + ext->step) > 0 && ext->value < 0) - { - ext->value = -ext->value; - }/*end special mode*/ + if((ext->value + ext->step) > 0 && ext->value < 0) ext->value = -ext->value; ext->value += ext->step; - if(ext->value_changed_cb != NULL) - { - ext->value_changed_cb(spinbox, ext->value); - } + } else { + ext->value = ext->range_max; } + + if(ext->value_changed_cb != NULL) ext->value_changed_cb(spinbox, ext->value); lv_spinbox_updatevalue(spinbox); } @@ -310,20 +300,15 @@ void lv_spinbox_decrement(lv_obj_t * spinbox) { lv_spinbox_ext_t * ext = lv_obj_get_ext_attr(spinbox); - if(ext->value - ext->step >= ext->range_min) - { + if(ext->value - ext->step >= ext->range_min) { /*Special mode when zero crossing*/ - if((ext->value - ext->step) < 0 && ext->value > 0) - { - ext->value = -ext->value; - }/*end special mode*/ + if((ext->value - ext->step) < 0 && ext->value > 0) ext->value = -ext->value; ext->value -= ext->step; - - if(ext->value_changed_cb != NULL) - { - ext->value_changed_cb(spinbox, ext->value); - } + } else { + ext->value = ext->range_min; } + + if(ext->value_changed_cb != NULL) ext->value_changed_cb(spinbox, ext->value); lv_spinbox_updatevalue(spinbox); } @@ -365,137 +350,121 @@ static lv_res_t lv_spinbox_signal(lv_obj_t * spinbox, lv_signal_t sign, void * p if(buf->type[i] == NULL) break; } buf->type[i] = "lv_spinbox"; - }else if(sign == LV_SIGNAL_CONTROLL) - { + } + else if(sign == LV_SIGNAL_CONTROLL) { lv_hal_indev_type_t indev_type = lv_indev_get_type(lv_indev_get_act()); uint32_t c = *((uint32_t *)param); /*uint32_t because can be UTF-8*/ - if(c == LV_GROUP_KEY_RIGHT) - { - if(indev_type == LV_INDEV_TYPE_ENCODER) - { - lv_spinbox_increment(spinbox); - } - else - { - lv_spinbox_step_next(spinbox); - } + if(c == LV_GROUP_KEY_RIGHT) { + if(indev_type == LV_INDEV_TYPE_ENCODER) lv_spinbox_increment(spinbox); + else lv_spinbox_step_next(spinbox); } - else if(c == LV_GROUP_KEY_LEFT) - { - if(indev_type == LV_INDEV_TYPE_ENCODER) - { - lv_spinbox_decrement(spinbox); - } - else - { + else if(c == LV_GROUP_KEY_LEFT) { + if(indev_type == LV_INDEV_TYPE_ENCODER) lv_spinbox_decrement(spinbox); + else lv_spinbox_step_previous(spinbox); + } + else if(c == LV_GROUP_KEY_UP) { + lv_spinbox_increment(spinbox); + } + else if(c == LV_GROUP_KEY_DOWN) { + lv_spinbox_decrement(spinbox); + } + else if(c == LV_GROUP_KEY_ENTER) { + + if(ext->step > 1) { + lv_spinbox_step_next(spinbox); + } else { + /*Restart from the MSB*/ + ext->step = 1; + uint32_t i; + for(i = 0; i < ext->digit_count; i++) { + int32_t new_step = ext->step * 10; + if(new_step >= ext->range_max) break; + ext->step = new_step; + } lv_spinbox_step_previous(spinbox); } } - else if(c == LV_GROUP_KEY_UP) - { - lv_spinbox_increment(spinbox); - } - else if(c == LV_GROUP_KEY_DOWN) - { - lv_spinbox_decrement(spinbox); - } - else - { - if(c == LV_GROUP_KEY_ENTER) - { - int p = lv_ta_get_cursor_pos(spinbox); - if(p == (1 + ext->digit_padding_left + ext->digit_count)) - { - for(int i = 0; i < ext->digit_count; i++) - lv_spinbox_step_previous(spinbox); - } else - { - lv_spinbox_step_next(spinbox); - } - - - lv_spinbox_updatevalue(spinbox); - } - else - { - lv_ta_add_char(spinbox, c); - } + else { + lv_ta_add_char(spinbox, c); } } - return res; } static void lv_spinbox_updatevalue(lv_obj_t * spinbox) { lv_spinbox_ext_t * ext = lv_obj_get_ext_attr(spinbox); - int32_t v = ext->value; - int32_t intDigits, decDigits; - uint8_t dc = ext->digit_count; - intDigits = (ext->dec_point_pos==0) ? ext->digit_count : ext->dec_point_pos; - decDigits = ext->digit_count - intDigits; + char buf[LV_SPINBOX_MAX_DIGIT_COUNT + 8]; + memset(buf, 0, sizeof(buf)); + char * buf_p = buf; - ext->digits[0] = v>=0 ? '+' : '-'; + /*Add the sign*/ + (*buf_p) = ext->value >= 0 ? '+' : '-'; + buf_p++; - int pl; /*padding left*/ - for(pl = 0; pl < ext->digit_padding_left; pl++) - { - ext->digits[1 + pl] = ' '; + int i; + /*padding left*/ + for(i = 0; i < ext->digit_padding_left; i++) { + (*buf_p) = ' '; + buf_p++; } - int i = 0; - uint8_t digits[16]; + char digits[64]; + /*Convert the numbers to string (the sign is already handled so always covert positive number)*/ + lv_math_num_to_str(ext->value < 0 ? -ext->value : ext->value, digits); - if(v < 0) v = -v; - - for(i = 0; i < dc; i++) - { - digits[i] = v%10; - v = v/10; + /*Add leading zeros*/ + int lz_cnt = ext->digit_count - (int)strlen(digits); + if(lz_cnt > 0) { + for(i = strlen(digits); i >= 0; i--) { + digits[i + lz_cnt] = digits[i]; + } + for(i = 0; i < lz_cnt; i++) { + digits[i] = '0'; + } } - int k; - for(k = 0; k < intDigits; k++) - { - ext->digits[1 + pl + k] = '0' + digits[--i]; + int32_t intDigits; + intDigits = (ext->dec_point_pos == 0) ? ext->digit_count : ext->dec_point_pos; + + /*Add the decimal part*/ + for(i = 0; i < intDigits && digits[i] != '\0'; i++) { + (*buf_p) = digits[i]; + buf_p++; } if(ext->dec_point_pos != 0) { - ext->digits[1 + pl + intDigits] = '.'; + /*Insert the decimal point*/ + (*buf_p) = '.'; + buf_p++; - int d; - - for(d = 0; d < decDigits; d++) - { - ext->digits[1 + pl + intDigits + 1 + d] = '0' + digits[--i]; + for(/*Leave i*/ ;i < ext->digit_count && digits[i] != '\0'; i++) { + (*buf_p) = digits[i]; + buf_p++; } - - ext->digits[1 + pl + intDigits + 1 + decDigits] = '\0'; - } else { - ext->digits[1 + pl + intDigits] = '\0'; - } + /*Refresh the text*/ + lv_ta_set_text(spinbox, (char*)buf); - lv_ta_set_text(spinbox, (char*)ext->digits); + /*Set the cursor position*/ int32_t step = ext->step; - uint8_t cPos = ext->digit_count + pl; + uint8_t cur_pos = ext->digit_count; while(step >= 10) { step /= 10; - cPos--; + cur_pos--; } - if(cPos > pl + intDigits ) - { - cPos ++; - } + if(cur_pos > intDigits ) cur_pos ++; /*Skip teh decimal point*/ - lv_ta_set_cursor_pos(spinbox, cPos); + cur_pos += ext->digit_padding_left; + + lv_ta_set_cursor_pos(spinbox, cur_pos); } #endif diff --git a/lv_objx/lv_spinbox.h b/lv_objx/lv_spinbox.h index c2956d055..ca5761487 100644 --- a/lv_objx/lv_spinbox.h +++ b/lv_objx/lv_spinbox.h @@ -50,11 +50,9 @@ typedef struct { int32_t range_max; int32_t range_min; int32_t step; - uint8_t digit_count:4; - uint8_t dec_point_pos:4; /*if 0, there is no separator and the number is an integer*/ - uint8_t digit_padding_left:4; - uint8_t digit_padding_right:4; - uint8_t digits[1+1+LV_SPINBOX_MAX_DIGIT_COUNT]; /*1 sign, 1 point, 16 num digits*/ + uint16_t digit_count:4; + uint16_t dec_point_pos:4; /*if 0, there is no separator and the number is an integer*/ + uint16_t digit_padding_left:4; lv_spinbox_value_changed_cb_t value_changed_cb; } lv_spinbox_ext_t;