feat(scale): remove float and adding padding handling(#4552)

This commit is contained in:
Carlos Diaz 2023-09-22 00:42:36 -06:00 committed by GitHub
parent c6ab5021cf
commit 2a9c2ede43
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 189 additions and 127 deletions

View File

@ -52,6 +52,11 @@ static void scale_set_arc_properties(lv_obj_t * obj, lv_draw_arc_dsc_t * arc_dsc
static void scale_find_section_tick_idx(lv_obj_t * obj);
static void scale_store_main_line_tick_width_compensation(lv_obj_t * obj, const uint32_t tick_idx,
const bool is_major_tick, const lv_coord_t major_tick_width, const lv_coord_t minor_tick_width);
static void scale_store_section_line_tick_width_compensation(lv_obj_t * obj, const bool is_major_tick,
lv_draw_label_dsc_t * label_dsc, lv_draw_line_dsc_t * major_tick_dsc, lv_draw_line_dsc_t * minor_tick_dsc,
const int32_t tick_value, const uint8_t tick_idx, lv_point_t * tick_point_a);
static void scale_build_custom_label_text(lv_obj_t * obj, lv_draw_label_dsc_t * label_dsc,
const uint16_t major_tick_idx);
/**********************
* STATIC VARIABLES
@ -182,6 +187,12 @@ void lv_scale_set_text_src(lv_obj_t * obj, char * txt_src[])
scale->txt_src = txt_src;
scale->custom_label_cnt = 0;
lv_coord_t idx;
for(idx = 0; txt_src[idx]; ++idx) {
scale->custom_label_cnt++;
}
lv_obj_invalidate(obj);
}
@ -282,6 +293,9 @@ static void lv_scale_constructor(const lv_obj_class_t * class_p, lv_obj_t * obj)
scale->minor_len = 5u;
scale->last_tick_width = 0U;
scale->first_tick_width = 0U;
scale->post_draw = false;
scale->custom_label_cnt = 0U;
scale->txt_src = NULL;
LV_TRACE_OBJ_CREATE("finished");
}
@ -392,6 +406,12 @@ static void scale_draw_indicator(lv_obj_t * obj, lv_event_t * event)
scale_set_line_properties(obj, &minor_tick_dsc, section->items_style, LV_PART_ITEMS);
}
}
else {
/* Tick is not in section, get the proper styles */
lv_obj_init_draw_label_dsc(obj, LV_PART_INDICATOR, &label_dsc);
lv_obj_init_draw_line_dsc(obj, LV_PART_INDICATOR, &major_tick_dsc);
lv_obj_init_draw_line_dsc(obj, LV_PART_ITEMS, &minor_tick_dsc);
}
}
/* The tick is represented by a line. We need two points to draw it */
@ -407,13 +427,7 @@ static void scale_draw_indicator(lv_obj_t * obj, lv_event_t * event)
/* Check if the custom text array has element for this major tick index */
if(scale->txt_src) {
if(scale->txt_src[major_tick_idx - 1U]) {
label_dsc.text = scale->txt_src[major_tick_idx - 1U];
label_dsc.text_local = 0;
}
else {
label_dsc.text = NULL;
}
scale_build_custom_label_text(obj, &label_dsc, major_tick_idx);
}
else { /* Add label with mapped values */
lv_snprintf(text_buffer, sizeof(text_buffer), "%" LV_PRId32, tick_value);
@ -429,72 +443,8 @@ static void scale_draw_indicator(lv_obj_t * obj, lv_event_t * event)
scale_store_main_line_tick_width_compensation(obj, tick_idx, is_major_tick, major_tick_dsc.width, minor_tick_dsc.width);
/* Store the first and last section tick vertical/horizontal position */
_LV_LL_READ_BACK(&scale->section_ll, section) {
if(section->minor_range <= tick_value && section->major_range >= tick_value) {
if(is_major_tick) {
scale_set_indicator_label_properties(obj, &label_dsc, section->indicator_style);
scale_set_line_properties(obj, &major_tick_dsc, section->indicator_style, LV_PART_INDICATOR);
}
else {
scale_set_line_properties(obj, &minor_tick_dsc, section->items_style, LV_PART_ITEMS);
}
}
if(LV_SCALE_MODE_VERTICAL_LEFT == scale->mode || LV_SCALE_MODE_VERTICAL_RIGHT == scale->mode) {
lv_coord_t tmp_width = 0;
if(tick_idx == section->first_tick_idx_in_section) {
if(section->first_tick_idx_is_major) {
tmp_width = major_tick_dsc.width;
}
else {
tmp_width = minor_tick_dsc.width;
}
section->first_tick_in_section.y = tick_point_a.y;
section->first_tick_in_section_width = tmp_width;
}
else if(tick_idx == section->last_tick_idx_in_section) {
if(section->last_tick_idx_is_major) {
tmp_width = major_tick_dsc.width;
}
else {
tmp_width = minor_tick_dsc.width;
}
section->last_tick_in_section.y = tick_point_a.y;
section->last_tick_in_section_width = tmp_width;
}
else { /* Nothing to do */ }
}
else {
lv_coord_t tmp_width = 0;
if(tick_idx == section->first_tick_idx_in_section) {
if(section->first_tick_idx_is_major) {
tmp_width = major_tick_dsc.width;
}
else {
tmp_width = minor_tick_dsc.width;
}
section->first_tick_in_section.x = tick_point_a.x;
section->first_tick_in_section_width = tmp_width;
}
else if(tick_idx == section->last_tick_idx_in_section) {
if(section->last_tick_idx_is_major) {
tmp_width = major_tick_dsc.width;
}
else {
tmp_width = minor_tick_dsc.width;
}
section->last_tick_in_section.x = tick_point_a.x;
section->last_tick_in_section_width = tmp_width;
}
else { /* Nothing to do */ }
}
}
scale_store_section_line_tick_width_compensation(obj, is_major_tick, &label_dsc, &major_tick_dsc, &minor_tick_dsc,
tick_value, tick_idx, &tick_point_a);
if(is_major_tick) {
major_tick_dsc.p1 = tick_point_a;
@ -544,6 +494,12 @@ static void scale_draw_indicator(lv_obj_t * obj, lv_event_t * event)
scale_set_line_properties(obj, &minor_tick_dsc, section->items_style, LV_PART_ITEMS);
}
}
else {
/* Tick is not in section, get the proper styles */
lv_obj_init_draw_label_dsc(obj, LV_PART_INDICATOR, &label_dsc);
lv_obj_init_draw_line_dsc(obj, LV_PART_INDICATOR, &major_tick_dsc);
lv_obj_init_draw_line_dsc(obj, LV_PART_ITEMS, &minor_tick_dsc);
}
}
/* The tick is represented by a line. We need two points to draw it */
@ -559,13 +515,7 @@ static void scale_draw_indicator(lv_obj_t * obj, lv_event_t * event)
/* Check if the custom text array has element for this major tick index */
if(scale->txt_src) {
if(scale->txt_src[major_tick_idx - 1U]) {
label_dsc.text = scale->txt_src[major_tick_idx - 1U];
label_dsc.text_local = 0;
}
else {
label_dsc.text = NULL;
}
scale_build_custom_label_text(obj, &label_dsc, major_tick_idx);
}
else { /* Add label with mapped values */
lv_snprintf(text_buffer, sizeof(text_buffer), "%" LV_PRId32, tick_value);
@ -630,31 +580,29 @@ static void scale_draw_main(lv_obj_t * obj, lv_event_t * event)
/* Get style properties so they can be used in the main line drawing */
const lv_coord_t border_width = lv_obj_get_style_border_width(obj, LV_PART_MAIN);
const lv_coord_t pad_top = lv_obj_get_style_pad_top(obj, LV_PART_MAIN) + lv_obj_get_style_border_width(obj,
LV_PART_MAIN);
const lv_coord_t pad_left = lv_obj_get_style_pad_left(obj, LV_PART_MAIN) + lv_obj_get_style_border_width(obj,
LV_PART_MAIN);
const lv_coord_t scroll_top = lv_obj_get_scroll_top(obj);
const lv_coord_t scroll_left = lv_obj_get_scroll_left(obj);
const lv_coord_t pad_top = lv_obj_get_style_pad_top(obj, LV_PART_MAIN) + border_width;
const lv_coord_t pad_bottom = lv_obj_get_style_pad_bottom(obj, LV_PART_MAIN) + border_width;
const lv_coord_t pad_left = lv_obj_get_style_pad_left(obj, LV_PART_MAIN) + border_width;
const lv_coord_t pad_right = lv_obj_get_style_pad_right(obj, LV_PART_MAIN) + border_width;
lv_coord_t x_ofs = 0U;
lv_coord_t y_ofs = 0U;
if(LV_SCALE_MODE_VERTICAL_LEFT == scale->mode) {
x_ofs = obj->coords.x2 + (line_dsc.width / 2U);
y_ofs = obj->coords.y1 + pad_top + border_width - scroll_top;
x_ofs = obj->coords.x2 + (line_dsc.width / 2U) - pad_right;
y_ofs = obj->coords.y1 + pad_top;
}
else if(LV_SCALE_MODE_VERTICAL_RIGHT == scale->mode) {
x_ofs = obj->coords.x1 + (line_dsc.width / 2U);
y_ofs = obj->coords.y1 + pad_top + border_width - scroll_top;
x_ofs = obj->coords.x1 + (line_dsc.width / 2U) + pad_left;
y_ofs = obj->coords.y1 + pad_top;
}
if(LV_SCALE_MODE_HORIZONTAL_BOTTOM == scale->mode) {
x_ofs = obj->coords.x1 + pad_left - scroll_left;
y_ofs = obj->coords.y1 + (line_dsc.width / 2U);
x_ofs = obj->coords.x1 + pad_right;
y_ofs = obj->coords.y1 + (line_dsc.width / 2U) + pad_top;
}
else if(LV_SCALE_MODE_HORIZONTAL_TOP == scale->mode) {
x_ofs = obj->coords.x1 + pad_left - scroll_left;
y_ofs = obj->coords.y2 + (line_dsc.width / 2U);
x_ofs = obj->coords.x1 + pad_left;
y_ofs = obj->coords.y2 + (line_dsc.width / 2U) - pad_bottom;
}
else { /* Nothing to do */ }
@ -666,7 +614,7 @@ static void scale_draw_main(lv_obj_t * obj, lv_event_t * event)
main_line_point_a.x = x_ofs - 1U;
main_line_point_a.y = y_ofs;
main_line_point_b.x = x_ofs - 1U;
main_line_point_b.y = obj->coords.y2 + pad_left - scroll_top;
main_line_point_b.y = obj->coords.y2 - pad_left;
/* Adjust main line with initial and last tick width */
main_line_point_a.y -= scale->last_tick_width / 2U;
@ -675,7 +623,8 @@ static void scale_draw_main(lv_obj_t * obj, lv_event_t * event)
else {
main_line_point_a.x = x_ofs;
main_line_point_a.y = y_ofs;
main_line_point_b.x = obj->coords.x2 + (pad_left - scroll_left);
/* X of second point starts at the edge of the object minus the left pad */
main_line_point_b.x = obj->coords.x2 - (pad_left);
main_line_point_b.y = y_ofs;
/* Adjust main line with initial and last tick width */
@ -701,23 +650,23 @@ static void scale_draw_main(lv_obj_t * obj, lv_event_t * event)
if(LV_SCALE_MODE_VERTICAL_LEFT == scale->mode || LV_SCALE_MODE_VERTICAL_RIGHT == scale->mode) {
/* Calculate position of the first tick in the section */
main_point_a.x = main_line_point_a.x;
float tmp = (float) section->first_tick_in_section.y + (float)(section->first_tick_in_section_width / 2U);
main_point_a.y = (lv_coord_t) tmp;
lv_coord_t tmp = (lv_coord_t)(section->first_tick_in_section_width / 2U);
main_point_a.y = section->first_tick_in_section.y + tmp;
/* Calculate position of the last tick in the section */
main_point_b.x = main_line_point_a.x;
tmp = (float) section->last_tick_in_section.y - (float)(section->last_tick_in_section_width / 2U);
main_point_b.y = (lv_coord_t) tmp;
tmp = (lv_coord_t)(section->last_tick_in_section_width / 2U);
main_point_b.y = section->last_tick_in_section.y - tmp;
}
else {
/* Calculate position of the first tick in the section */
float tmp = (float) section->first_tick_in_section.x - (float)(section->first_tick_in_section_width / 2U);
main_point_a.x = (lv_coord_t) tmp;
lv_coord_t tmp = (lv_coord_t)(section->first_tick_in_section_width / 2U);
main_point_a.x = section->first_tick_in_section.x - tmp;
main_point_a.y = main_line_point_a.y;
/* Calculate position of the last tick in the section */
tmp = (float) section->last_tick_in_section.x + (float)(section->last_tick_in_section_width / 2U);
main_point_b.x = (lv_coord_t) tmp;
tmp = (lv_coord_t)(section->last_tick_in_section_width / 2U);
main_point_b.x = section->last_tick_in_section.x + tmp;
main_point_b.y = main_line_point_a.y;
}
@ -837,28 +786,33 @@ static void scale_get_tick_points(lv_obj_t * obj, const uint32_t tick_idx, bool
/* Get style properties so they can be used in the tick and label drawing */
const lv_coord_t border_width = lv_obj_get_style_border_width(obj, LV_PART_MAIN);
const lv_coord_t pad_top = lv_obj_get_style_pad_top(obj, LV_PART_MAIN) + lv_obj_get_style_border_width(obj,
LV_PART_MAIN);
const lv_coord_t pad_left = lv_obj_get_style_pad_left(obj, LV_PART_MAIN) + lv_obj_get_style_border_width(obj,
LV_PART_MAIN);
const lv_coord_t pad_top = lv_obj_get_style_pad_top(obj, LV_PART_MAIN) + border_width;
const lv_coord_t pad_bottom = lv_obj_get_style_pad_bottom(obj, LV_PART_MAIN) + border_width;
const lv_coord_t pad_right = lv_obj_get_style_pad_right(obj, LV_PART_MAIN) + border_width;
const lv_coord_t pad_left = lv_obj_get_style_pad_left(obj, LV_PART_MAIN) + border_width;
const lv_coord_t tick_pad_right = lv_obj_get_style_pad_right(obj, LV_PART_TICKS);
const lv_coord_t tick_pad_left = lv_obj_get_style_pad_left(obj, LV_PART_TICKS);
const lv_coord_t tick_pad_top = lv_obj_get_style_pad_top(obj, LV_PART_TICKS);
const lv_coord_t tick_pad_bottom = lv_obj_get_style_pad_bottom(obj, LV_PART_TICKS);
lv_coord_t x_ofs = 0U;
lv_coord_t y_ofs = 0U;
if(LV_SCALE_MODE_VERTICAL_LEFT == scale->mode) {
x_ofs = obj->coords.x2 + (main_line_dsc.width / 2U);
y_ofs = obj->coords.y1 + pad_top + border_width - lv_obj_get_scroll_top(obj);
x_ofs = obj->coords.x2 + (main_line_dsc.width / 2U) - pad_right;
y_ofs = obj->coords.y1 + (pad_top + tick_pad_top);
}
else if(LV_SCALE_MODE_VERTICAL_RIGHT == scale->mode) {
x_ofs = obj->coords.x1 + (main_line_dsc.width / 2U);
y_ofs = obj->coords.y1 + pad_top + border_width - lv_obj_get_scroll_top(obj);
x_ofs = obj->coords.x1 + (main_line_dsc.width / 2U) + pad_left;
y_ofs = obj->coords.y1 + (pad_top + tick_pad_top);
}
else if(LV_SCALE_MODE_HORIZONTAL_BOTTOM == scale->mode) {
x_ofs = obj->coords.x1 + pad_left - lv_obj_get_scroll_left(obj);
y_ofs = obj->coords.y1 + (main_line_dsc.width / 2U);
x_ofs = obj->coords.x1 + (pad_right + tick_pad_right);
y_ofs = obj->coords.y1 + (main_line_dsc.width / 2U) + pad_top;
}
else if(LV_SCALE_MODE_HORIZONTAL_TOP == scale->mode) {
x_ofs = obj->coords.x1 + pad_left - lv_obj_get_scroll_left(obj);
y_ofs = obj->coords.y2 + (main_line_dsc.width / 2U);
x_ofs = obj->coords.x1 + (pad_left + tick_pad_left);
y_ofs = obj->coords.y2 + (main_line_dsc.width / 2U) - pad_bottom;
}
else { /* Nothing to do */ }
@ -877,16 +831,17 @@ static void scale_get_tick_points(lv_obj_t * obj, const uint32_t tick_idx, bool
/* Setup the tick points */
if(LV_SCALE_MODE_VERTICAL_LEFT == scale->mode || LV_SCALE_MODE_VERTICAL_RIGHT == scale->mode) {
/* Vertical position starts at y2 of the scale main line */
lv_coord_t vertical_position = obj->coords.y2;
/* Vertical position starts at y2 of the scale main line, we start at y2 because the ticks are drawn from bottom to top */
lv_coord_t vertical_position = obj->coords.y2 - (pad_bottom + tick_pad_bottom);
if(scale->total_tick_count == tick_idx) {
vertical_position = obj->coords.y1;
vertical_position = y_ofs;
}
/* Increment the tick offset depending of its index */
else if(0 != tick_idx) {
float section = (float) lv_obj_get_height(obj) / (float) scale->total_tick_count;
float offset = section * tick_idx;
vertical_position -= (lv_coord_t) offset;
const lv_coord_t scale_total_height = lv_obj_get_height(obj) - (pad_top + pad_bottom + tick_pad_top + tick_pad_bottom);
lv_coord_t offset = ((lv_coord_t) tick_idx * (lv_coord_t) scale_total_height) / (lv_coord_t) scale->total_tick_count;
vertical_position -= offset;
}
else { /* Nothing to do */ }
@ -897,16 +852,16 @@ static void scale_get_tick_points(lv_obj_t * obj, const uint32_t tick_idx, bool
}
else {
/* Horizontal position starts at x1 of the scale main line */
lv_coord_t horizontal_position = obj->coords.x1;
lv_coord_t horizontal_position = x_ofs;
/* Position the last tick at the x2 scale coordinate */
if(scale->total_tick_count == tick_idx) {
horizontal_position = obj->coords.x2;
horizontal_position = obj->coords.x2 - (pad_left + tick_pad_left);
}
/* Increment the tick offset depending of its index */
else if(0U != tick_idx) {
float section = (float) lv_obj_get_width(obj) / (float) scale->total_tick_count;
float offset = section * tick_idx;
horizontal_position += (lv_coord_t) offset;
const lv_coord_t scale_total_width = lv_obj_get_width(obj) - (pad_right + pad_left + tick_pad_right + tick_pad_left);
lv_coord_t offset = ((lv_coord_t) tick_idx * (lv_coord_t) scale_total_width) / (lv_coord_t) scale->total_tick_count;
horizontal_position += offset;
}
else { /* Nothing to do */ }
@ -1246,4 +1201,110 @@ static void scale_store_main_line_tick_width_compensation(lv_obj_t * obj, const
else { /* Nothing to do */ }
}
/**
* Sets the text of the tick label descriptor when using custom labels
*
* Sets the text pointer when valid custom label is available, otherwise set it to NULL.
*
* @param obj pointer to a scale object
* @param label_dsc pointer to the label descriptor
* @param major_tick_idx index of the current major tick
*/
static void scale_build_custom_label_text(lv_obj_t * obj, lv_draw_label_dsc_t * label_dsc,
const uint16_t major_tick_idx)
{
lv_scale_t * scale = (lv_scale_t *) obj;
/* Check if the scale has valid custom labels available,
* this avoids reading past txt_src array when the scale requires more tick labels than available */
if(major_tick_idx <= scale->custom_label_cnt) {
if(scale->txt_src[major_tick_idx - 1U]) {
label_dsc->text = scale->txt_src[major_tick_idx - 1U];
label_dsc->text_local = 0;
}
else {
label_dsc->text = NULL;
}
}
else {
label_dsc->text = NULL;
}
}
/**
* Stores tick width compensation information for main line sections
*
* @param obj pointer to a scale object
* @param is_major_tick Indicates if tick is major or not
* @param label_dsc pointer to the label descriptor
* @param major_tick_dsc pointer to the major_tick_dsc
* @param minor_tick_dsc pointer to the minor_tick_dsc
* @param tick_value Current tick value, used to know if tick_idx belongs to a section or not
* @param tick_idx Current tick index
* @param tick_point_a Pointer to tick point a
*/
static void scale_store_section_line_tick_width_compensation(lv_obj_t * obj, const bool is_major_tick,
lv_draw_label_dsc_t * label_dsc, lv_draw_line_dsc_t * major_tick_dsc, lv_draw_line_dsc_t * minor_tick_dsc,
const int32_t tick_value, const uint8_t tick_idx, lv_point_t * tick_point_a)
{
lv_scale_t * scale = (lv_scale_t *) obj;
lv_scale_section_t * section;
_LV_LL_READ_BACK(&scale->section_ll, section) {
if(section->minor_range <= tick_value && section->major_range >= tick_value) {
if(is_major_tick) {
scale_set_indicator_label_properties(obj, label_dsc, section->indicator_style);
scale_set_line_properties(obj, major_tick_dsc, section->indicator_style, LV_PART_INDICATOR);
}
else {
scale_set_line_properties(obj, minor_tick_dsc, section->items_style, LV_PART_ITEMS);
}
}
lv_coord_t tmp_width = 0;
if(tick_idx == section->first_tick_idx_in_section) {
if(section->first_tick_idx_is_major) {
tmp_width = major_tick_dsc->width;
}
else {
tmp_width = minor_tick_dsc->width;
}
section->first_tick_in_section.y = tick_point_a->y;
/* Add 1px as adjustment if tmp_width is odd */
if(tmp_width & 0x01U) {
if(LV_SCALE_MODE_VERTICAL_LEFT == scale->mode || LV_SCALE_MODE_VERTICAL_RIGHT == scale->mode) {
tmp_width += 1U;
}
else {
tmp_width -= 1U;
}
}
section->first_tick_in_section_width = tmp_width;
}
else if(tick_idx == section->last_tick_idx_in_section) {
if(section->last_tick_idx_is_major) {
tmp_width = major_tick_dsc->width;
}
else {
tmp_width = minor_tick_dsc->width;
}
section->last_tick_in_section.y = tick_point_a->y;
/* Add 1px as adjustment if tmp_width is odd */
if(tmp_width & 0x01U) {
if(LV_SCALE_MODE_VERTICAL_LEFT == scale->mode || LV_SCALE_MODE_VERTICAL_RIGHT == scale->mode) {
tmp_width -= 1U;
}
else {
tmp_width += 1U;
}
}
section->last_tick_in_section_width = tmp_width;
}
else { /* Nothing to do */ }
}
}
#endif

View File

@ -73,6 +73,7 @@ typedef struct {
lv_obj_t obj;
lv_ll_t section_ll; /**< Linked list for the sections (stores lv_scale_section_t)*/
char ** txt_src;
lv_coord_t custom_label_cnt;
lv_coord_t major_len;
lv_coord_t minor_len;
lv_coord_t range_min;