From 7f565f419a2f42fcbfd329c709b67477a81a5d4a Mon Sep 17 00:00:00 2001 From: Paul Peavyhouse Date: Wed, 18 Sep 2019 11:48:31 -0700 Subject: [PATCH 01/82] Initial commit of porting @AloyseTech's color picker from lvgl v5 to v6 --- lvgl.h | 1 + src/lv_draw/lv_draw_arc.c | 3 +- src/lv_draw/lv_draw_triangle.c | 14 + src/lv_misc/lv_math.c | 104 ++ src/lv_misc/lv_math.h | 15 + src/lv_objx/lv_cpicker.c | 1907 ++++++++++++++++++++++++++++++++ src/lv_objx/lv_cpicker.h | 233 ++++ src/lv_objx/lv_objx.mk | 1 + 8 files changed, 2276 insertions(+), 2 deletions(-) create mode 100644 src/lv_objx/lv_cpicker.c create mode 100644 src/lv_objx/lv_cpicker.h diff --git a/lvgl.h b/lvgl.h index b6e29b61b..0b8bec129 100644 --- a/lvgl.h +++ b/lvgl.h @@ -45,6 +45,7 @@ extern "C" { #include "src/lv_objx/lv_chart.h" #include "src/lv_objx/lv_table.h" #include "src/lv_objx/lv_cb.h" +#include "src/lv_objx/lv_cpicker.h" #include "src/lv_objx/lv_bar.h" #include "src/lv_objx/lv_slider.h" #include "src/lv_objx/lv_led.h" diff --git a/src/lv_draw/lv_draw_arc.c b/src/lv_draw/lv_draw_arc.c index 306249256..ca3c7ddbc 100644 --- a/src/lv_draw/lv_draw_arc.c +++ b/src/lv_draw/lv_draw_arc.c @@ -20,7 +20,6 @@ /********************** * STATIC PROTOTYPES **********************/ -static uint16_t fast_atan2(int x, int y); static void ver_line(lv_coord_t x, lv_coord_t y, const lv_area_t * mask, lv_coord_t len, lv_color_t color, lv_opa_t opa); static void hor_line(lv_coord_t x, lv_coord_t y, const lv_area_t * mask, lv_coord_t len, lv_color_t color, @@ -100,7 +99,7 @@ void lv_draw_arc(lv_coord_t center_x, lv_coord_t center_y, uint16_t radius, cons uint32_t r_act_sqr = xi * xi + yi * yi; if(r_act_sqr > r_out_sqr) continue; - deg_base = fast_atan2(xi, yi) - 180; + deg_base = lv_atan2(xi, yi) - 180; deg = 180 + deg_base; if(deg_test(deg, start_angle, end_angle)) { diff --git a/src/lv_draw/lv_draw_triangle.c b/src/lv_draw/lv_draw_triangle.c index e06af2b18..0b9d6536b 100644 --- a/src/lv_draw/lv_draw_triangle.c +++ b/src/lv_draw/lv_draw_triangle.c @@ -136,7 +136,21 @@ void tri_draw_flat(const lv_point_t * points, const lv_area_t * mask, const lv_s if(tri[1].y < tri[0].y) point_swap(&tri[1], &tri[0]); if(tri[2].y < tri[1].y) point_swap(&tri[2], &tri[1]); if(tri[1].y < tri[0].y) point_swap(&tri[1], &tri[0]); +/* LVGLv5 + /*Return is the triangle is degenerated* / + if(tri[0].x == tri[1].x && tri[0].y == tri[1].y) return; + if(tri[1].x == tri[2].x && tri[1].y == tri[2].y) return; + if(tri[0].x == tri[2].x && tri[0].y == tri[2].y) return; + if(tri[0].x == tri[1].x && tri[1].x == tri[2].x) return; + if(tri[0].y == tri[1].y && tri[1].y == tri[2].y) return; + + /*Chech out of mask* / + if(tri[0].x < mask->x1 && tri[1].x < mask->x1 && tri[2].x < mask->x1) return; /*Out of the mask on the left* / + if(tri[0].x > mask->x2 && tri[1].x > mask->x2 && tri[2].x > mask->x2) return; /*Out of the mask on the right* / + if(tri[0].y < mask->y1 && tri[1].y < mask->y1 && tri[2].y < mask->y1) return; /*Out of the mask on the top* / + if(tri[0].y > mask->y2 && tri[1].y > mask->y2 && tri[2].y > mask->y2) return; /*Out of the mask on the bottom* / +*/ /*Draw the triangle*/ lv_point_t edge1; lv_coord_t dx1 = LV_MATH_ABS(tri[0].x - tri[1].x); diff --git a/src/lv_misc/lv_math.c b/src/lv_misc/lv_math.c index ea332b61b..d1bd51228 100644 --- a/src/lv_misc/lv_math.c +++ b/src/lv_misc/lv_math.c @@ -94,6 +94,110 @@ int32_t lv_bezier3(uint32_t t, int32_t u0, int32_t u1, int32_t u2, int32_t u3) return v1 + v2 + v3 + v4; } +/** + * Calculate the atan2 of a vector. + * @param x + * @param y + * @return the angle in degree calculated from the given parameters in range of [0..360] + */ +uint16_t lv_atan2(int x, int y) +{ + // Fast XY vector to integer degree algorithm - Jan 2011 www.RomanBlack.com + // Converts any XY values including 0 to a degree value that should be + // within +/- 1 degree of the accurate value without needing + // large slow trig functions like ArcTan() or ArcCos(). + // NOTE! at least one of the X or Y values must be non-zero! + // This is the full version, for all 4 quadrants and will generate + // the angle in integer degrees from 0-360. + // Any values of X and Y are usable including negative values provided + // they are between -1456 and 1456 so the 16bit multiply does not overflow. + + unsigned char negflag; + unsigned char tempdegree; + unsigned char comp; + unsigned int degree; // this will hold the result + //signed int x; // these hold the XY vector at the start + //signed int y; // (and they will be destroyed) + unsigned int ux; + unsigned int uy; + + // Save the sign flags then remove signs and get XY as unsigned ints + negflag = 0; + if(x < 0) { + negflag += 0x01; // x flag bit + x = (0 - x); // is now + + } + ux = x; // copy to unsigned var before multiply + if(y < 0) { + negflag += 0x02; // y flag bit + y = (0 - y); // is now + + } + uy = y; // copy to unsigned var before multiply + + // 1. Calc the scaled "degrees" + if(ux > uy) { + degree = (uy * 45) / ux; // degree result will be 0-45 range + negflag += 0x10; // octant flag bit + } else { + degree = (ux * 45) / uy; // degree result will be 0-45 range + } + + // 2. Compensate for the 4 degree error curve + comp = 0; + tempdegree = degree; // use an unsigned char for speed! + if(tempdegree > 22) { // if top half of range + if(tempdegree <= 44) comp++; + if(tempdegree <= 41) comp++; + if(tempdegree <= 37) comp++; + if(tempdegree <= 32) comp++; // max is 4 degrees compensated + } else { // else is lower half of range + if(tempdegree >= 2) comp++; + if(tempdegree >= 6) comp++; + if(tempdegree >= 10) comp++; + if(tempdegree >= 15) comp++; // max is 4 degrees compensated + } + degree += comp; // degree is now accurate to +/- 1 degree! + + // Invert degree if it was X>Y octant, makes 0-45 into 90-45 + if(negflag & 0x10) degree = (90 - degree); + + // 3. Degree is now 0-90 range for this quadrant, + // need to invert it for whichever quadrant it was in + if(negflag & 0x02) { // if -Y + if(negflag & 0x01) // if -Y -X + degree = (180 + degree); + else // else is -Y +X + degree = (180 - degree); + } else { // else is +Y + if(negflag & 0x01) // if +Y -X + degree = (360 - degree); + } + return degree; +} + +/** + * Calculate the sqrt of an integer. + * @param x + * @return the sqrt of x + */ +uint16_t lv_sqrt(uint32_t x) +{ + uint16_t res=0; + uint16_t add= 0x8000; + int i; + for(i=0;i<16;i++) + { + uint16_t temp=res | add; + uint32_t g2=temp*temp; + if (x>=g2) + { + res=temp; + } + add>>=1; + } + return res; +} + /********************** * STATIC FUNCTIONS **********************/ diff --git a/src/lv_misc/lv_math.h b/src/lv_misc/lv_math.h index 83ace3a54..2b1cd6888 100644 --- a/src/lv_misc/lv_math.h +++ b/src/lv_misc/lv_math.h @@ -54,6 +54,21 @@ int16_t lv_trigo_sin(int16_t angle); */ int32_t lv_bezier3(uint32_t t, int32_t u0, int32_t u1, int32_t u2, int32_t u3); +/** + * Calculate the atan2 of a vector. + * @param x + * @param y + * @return the angle in degree calculated from the given parameters in range of [0..360] + */ +uint16_t lv_atan2(int x, int y); + +/** + * Calculate the sqrt of an integer. + * @param x + * @return the sqrt of x + */ +uint16_t lv_sqrt(uint32_t x); + /********************** * MACROS **********************/ diff --git a/src/lv_objx/lv_cpicker.c b/src/lv_objx/lv_cpicker.c new file mode 100644 index 000000000..e9e817510 --- /dev/null +++ b/src/lv_objx/lv_cpicker.c @@ -0,0 +1,1907 @@ +/** + * @file lv_cpicker.c + * + */ + +/* TODO Remove these instructions + * Search an replace: color_picker -> object normal name with lower case (e.g. button, label etc.) + * cpicker -> object short name with lower case(e.g. btn, label etc) + * CPICKER -> object short name with upper case (e.g. BTN, LABEL etc.) + * + */ + +/********************* + * INCLUDES + *********************/ +#include "lv_cpicker.h" +#include "../lv_misc/lv_math.h" +#include "../lv_draw/lv_draw_arc.h" +#include "../lv_themes/lv_theme.h" +#include "../lv_core/lv_indev.h" +#include "../lv_core/lv_refr.h" + +#if LV_USE_CPICKER != 0 + +/********************* + * DEFINES + *********************/ +#ifndef LV_CPICKER_DEF_TYPE +#define LV_CPICKER_DEF_TYPE LV_CPICKER_TYPE_DISC +#endif + +#ifndef LV_CPICKER_DEF_HUE +#define LV_CPICKER_DEF_HUE 0 +#endif + +#ifndef LV_CPICKER_DEF_SAT +#define LV_CPICKER_DEF_SAT 100 +#endif + +#ifndef LV_CPICKER_DEF_VAL +#define LV_CPICKER_DEF_VAL 100 +#endif + +#ifndef LV_CPICKER_DEF_IND_TYPE +#define LV_CPICKER_DEF_IND_TYPE LV_CPICKER_IND_CIRCLE +#endif + +#ifndef LV_CPICKER_DEF_QF /*quantization factor*/ +#define LV_CPICKER_DEF_QF 1 +#endif + +/*for rectangular mode the QF can be down to 1*/ +/* +#define LV_CPICKER_MINIMUM_QF 4 +#if LV_CPICKER_DEF_QF < LV_CPICKER_MINIMUM_QF +#undef LV_CPICKER_DEF_QF +#define LV_CPICKER_DEF_QF LV_CPICKER_MINIMUM_QF +#endif + */ + +#ifndef LV_CPICKER_USE_TRI /*Use triangle approximation instead of arc*/ +#define LV_CPICKER_USE_TRI 1 +#endif + +#define TRI_OFFSET 4 + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * STATIC PROTOTYPES + **********************/ +static bool lv_cpicker_disc_design(lv_obj_t * cpicker, const lv_area_t * mask, lv_design_mode_t mode); +static lv_res_t lv_cpicker_disc_signal(lv_obj_t * cpicker, lv_signal_t sign, void * param); + +static bool lv_cpicker_rect_design(lv_obj_t * cpicker, const lv_area_t * mask, lv_design_mode_t mode); +static lv_res_t lv_cpicker_rect_signal(lv_obj_t * cpicker, lv_signal_t sign, void * param); + +static void lv_cpicker_invalidate_indicator(lv_obj_t * cpicker); + +/********************** + * STATIC VARIABLES + **********************/ +//LVGLv5 static lv_signal_func_t ancestor_signal; +//LVGLv5 static lv_design_func_t ancestor_design; + +/********************** + * MACROS + **********************/ + +/********************** + * GLOBAL FUNCTIONS + **********************/ + +/** + * Create a color_picker object + * @param par pointer to an object, it will be the parent of the new color_picker + * @param copy pointer to a color_picker object, if not NULL then the new object will be copied from it + * @return pointer to the created color_picker + */ +lv_obj_t * lv_cpicker_create(lv_obj_t * par, const lv_obj_t * copy) +{ + LV_LOG_TRACE("color_picker create started"); + + /*Create the ancestor of color_picker*/ + /*TODO modify it to the ancestor create function */ + lv_obj_t * new_cpicker = lv_obj_create(par, copy); + lv_mem_assert(new_cpicker); + if(new_cpicker == NULL) return NULL; + + /*Allocate the colorpicker type specific extended data*/ + lv_cpicker_ext_t * ext = lv_obj_allocate_ext_attr(new_cpicker, sizeof(lv_cpicker_ext_t)); + lv_mem_assert(ext); + if(ext == NULL) return NULL; + //LVGLv5 if(ancestor_signal == NULL) ancestor_signal = lv_obj_get_signal_func(new_cpicker); + //LVGLv5 if(ancestor_design == NULL) ancestor_design = lv_obj_get_design_func(new_cpicker); + + /*Initialize the allocated 'ext' */ + ext->hue = LV_CPICKER_DEF_HUE; + ext->prev_hue = ext->hue; + ext->saturation = LV_CPICKER_DEF_SAT; + ext->value = LV_CPICKER_DEF_VAL; + ext->ind.style = &lv_style_plain; + ext->ind.type = LV_CPICKER_DEF_IND_TYPE; + //LVGLv5 ext->value_changed = NULL; + ext->wheel_mode = LV_CPICKER_WHEEL_HUE; + ext->wheel_fixed = 0; + ext->last_clic = 0; + ext->type = LV_CPICKER_DEF_TYPE; + + /*The signal and design functions are not copied so set them here*/ + if(ext->type == LV_CPICKER_TYPE_DISC) + { + //LVGLv5 lv_obj_set_signal_func(new_cpicker, lv_cpicker_disc_signal); + //LVGLv5 lv_obj_set_design_func(new_cpicker, lv_cpicker_disc_design); + } + else if(ext->type == LV_CPICKER_TYPE_RECT) + { + //LVGLv5 lv_obj_set_signal_func(new_cpicker, lv_cpicker_rect_signal); + //LVGLv5 lv_obj_set_design_func(new_cpicker, lv_cpicker_rect_design); + } + + /*Init the new cpicker color_picker*/ + if(copy == NULL) { + + /*Set the default styles*/ + lv_theme_t * th = lv_theme_get_current(); + if(th) { + lv_cpicker_set_style(new_cpicker, LV_CPICKER_STYLE_MAIN, th->style.bg); + } else { + lv_cpicker_set_style(new_cpicker, LV_CPICKER_STYLE_MAIN, &lv_style_plain); + } + } + + /*Copy an existing color_picker*/ + else { + lv_cpicker_ext_t * copy_ext = lv_obj_get_ext_attr(copy); + + /*Refresh the style with new signal function*/ + lv_obj_refresh_style(new_cpicker); + } + + LV_LOG_INFO("colorpicker created"); + + return new_cpicker; +} + +/*====================== + * Add/remove functions + *=====================*/ + +/* + * New object specific "add" or "remove" functions come here + */ + + +/*===================== + * Setter functions + *====================*/ + +/* + * New object specific "set" functions come here + */ + + +/** + * Set a style of a color_picker. + * @param cpicker pointer to color_picker object + * @param type which style should be set + * @param style pointer to a style + */ +void lv_cpicker_set_style(lv_obj_t * cpicker, lv_cpicker_style_t type, lv_style_t * style) +{ + lv_cpicker_ext_t * ext = lv_obj_get_ext_attr(cpicker); + + switch(type) { + case LV_CPICKER_STYLE_MAIN: + lv_obj_set_style(cpicker, style); + break; + case LV_CPICKER_STYLE_IND: + ext->ind.style = style; + lv_obj_invalidate(cpicker); + break; + } +} + +/** + * Set a type of a colorpicker indicator. + * @param cpicker pointer to colorpicker object + * @param type indicator type + */ +void lv_cpicker_set_ind_type(lv_obj_t * cpicker, lv_cpicker_ind_type_t type) +{ + lv_cpicker_ext_t * ext = lv_obj_get_ext_attr(cpicker); + ext->ind.type = type; + lv_obj_invalidate(cpicker); +} + +/** + * Set the current hue of a colorpicker. + * @param cpicker pointer to colorpicker object + * @param hue current selected hue [0..360] + */ +void lv_cpicker_set_hue(lv_obj_t * cpicker, uint16_t hue) +{ + lv_cpicker_ext_t * ext = lv_obj_get_ext_attr(cpicker); + + ext->hue = hue % 360; + + lv_obj_invalidate(cpicker); +} + +/** + * Set the current saturation of a colorpicker. + * @param cpicker pointer to colorpicker object + * @param sat current selected saturation [0..100] + */ +void lv_cpicker_set_saturation(lv_obj_t * cpicker, uint16_t sat) +{ + lv_cpicker_ext_t * ext = lv_obj_get_ext_attr(cpicker); + + ext->saturation = sat % 100; + + lv_obj_invalidate(cpicker); +} + +/** + * Set the current value of a colorpicker. + * @param cpicker pointer to colorpicker object + * @param val current selected value [0..100] + */ +void lv_cpicker_set_value(lv_obj_t * cpicker, uint16_t val) +{ + lv_cpicker_ext_t * ext = lv_obj_get_ext_attr(cpicker); + + ext->value = val % 100; + + lv_obj_invalidate(cpicker); +} + +/** + * Set the current color of a colorpicker. + * @param cpicker pointer to colorpicker object + * @param color current selected color + */ +void lv_cpicker_set_color(lv_obj_t * cpicker, lv_color_t color) +{ + lv_cpicker_ext_t * ext = lv_obj_get_ext_attr(cpicker); + + lv_color_hsv_t hsv = lv_color_rgb_to_hsv(color.ch.red, color.ch.green, color.ch.blue); + ext->hue = hsv.h; + + lv_obj_invalidate(cpicker); +} + +/** + * Set the action callback on value change event. + * @param cpicker pointer to colorpicker object + * @param action callback function + */ +/* LVGLv5 +void lv_cpicker_set_action(lv_obj_t * cpicker, lv_action_t action) +{ + lv_cpicker_ext_t * ext = lv_obj_get_ext_attr(cpicker); + + ext->value_changed = action; +} +*/ + +/** + * Set the current wheel mode. + * @param cpicker pointer to colorpicker object + * @param mode wheel mode (hue/sat/val) + */ +void lv_cpicker_set_wheel_mode(lv_obj_t * cpicker, lv_cpicker_wheel_mode_t mode) +{ + lv_cpicker_ext_t * ext = lv_obj_get_ext_attr(cpicker); + + ext->wheel_mode = mode; +} + +/** + * Set if the wheel mode is changed on long press on center + * @param cpicker pointer to colorpicker object + * @param fixed_mode mode cannot be changed if set + */ +void lv_cpicker_set_wheel_fixed(lv_obj_t * cpicker, bool fixed_mode) +{ + lv_cpicker_ext_t * ext = lv_obj_get_ext_attr(cpicker); + + ext->wheel_fixed = fixed_mode; +} + +/*===================== + * Getter functions + *====================*/ + +/* + * New object specific "get" functions come here + */ + +/** + * Get style of a color_picker. + * @param cpicker pointer to color_picker object + * @param type which style should be get + * @return style pointer to the style + */ +lv_style_t * lv_cpicker_get_style(const lv_obj_t * cpicker, lv_cpicker_style_t type) +{ + lv_cpicker_ext_t * ext = lv_obj_get_ext_attr(cpicker); + + switch(type) { + case LV_CPICKER_STYLE_MAIN: + return lv_obj_get_style(cpicker); + case LV_CPICKER_STYLE_IND: + return ext->ind.style; + default: + return NULL; + } + + /*To avoid warning*/ + return NULL; +} + +/** + * Get the current hue of a colorpicker. + * @param cpicker pointer to colorpicker object + * @return hue current selected hue + */ +uint16_t lv_cpicker_get_hue(lv_obj_t * cpicker) +{ + lv_cpicker_ext_t * ext = lv_obj_get_ext_attr(cpicker); + + return ext->hue; +} + +/** + * Get the current selected color of a colorpicker. + * @param cpicker pointer to colorpicker object + * @return color current selected color + */ +lv_color_t lv_cpicker_get_color(lv_obj_t * cpicker) +{ + lv_cpicker_ext_t * ext = lv_obj_get_ext_attr(cpicker); + + return lv_color_hsv_to_rgb(ext->hue, ext->saturation, ext->value); +} + +/** + * Get the action callback called on value change event. + * @param cpicker pointer to colorpicker object + * @return action callback function + */ +/* LVGLv5 +lv_action_t lv_cpicker_get_action(lv_obj_t * cpicker) +{ + lv_cpicker_ext_t * ext = lv_obj_get_ext_attr(cpicker); + + return ext->value_changed; +} +*/ + +/*===================== + * Other functions + *====================*/ + +/* + * New object specific "other" functions come here + */ + +/********************** + * STATIC FUNCTIONS + **********************/ + +/** + * Handle the drawing related tasks of the color_pickerwhen when wheel type + * @param cpicker pointer to an object + * @param mask the object will be drawn only in this area + * @param mode LV_DESIGN_COVER_CHK: only check if the object fully covers the 'mask_p' area + * (return 'true' if yes) + * LV_DESIGN_DRAW: draw the object (always return 'true') + * LV_DESIGN_DRAW_POST: drawing after every children are drawn + * @param return true/false, depends on 'mode' + */ +static bool lv_cpicker_disc_design(lv_obj_t * cpicker, const lv_area_t * mask, lv_design_mode_t mode) +{ + /*Return false if the object is not covers the mask_p area*/ + if(mode == LV_DESIGN_COVER_CHK) { + return false; + } + /*Draw the object*/ + else if(mode == LV_DESIGN_DRAW_MAIN) { + + lv_cpicker_ext_t * ext = lv_obj_get_ext_attr(cpicker); + lv_style_t * style = lv_cpicker_get_style(cpicker, LV_CPICKER_STYLE_MAIN); + + static lv_style_t styleCopy; + lv_style_copy(&styleCopy, style); + + lv_coord_t r = (LV_MATH_MIN(lv_obj_get_width(cpicker), lv_obj_get_height(cpicker))) / 2; + lv_coord_t x = cpicker->coords.x1 + lv_obj_get_width(cpicker) / 2; + lv_coord_t y = cpicker->coords.y1 + lv_obj_get_height(cpicker) / 2; + lv_opa_t opa_scale = lv_obj_get_opa_scale(cpicker); + + uint8_t redraw_wheel = 0; + + lv_area_t center_ind_area; + + uint32_t rin = r - styleCopy.line.width; + //the square area (a and b being sides) should fit into the center of diameter d + //we have: + //a^2+b^2<=d^2 + //2a^2 <= d^2 + //a^2<=(d^2)/2 + //a <= sqrt((d^2)/2) + uint16_t radius = lv_sqrt((4*rin*rin)/2)/2 - style->body.padding.inner; + + center_ind_area.x1 = x - radius; + center_ind_area.y1 = y - radius; + center_ind_area.x2 = x + radius; + center_ind_area.y2 = y + radius; + + /*redraw the wheel only if the mask intersect with the wheel*/ + if(mask->x1 < center_ind_area.x1 || mask->x2 > center_ind_area.x2 + || mask->y1 < center_ind_area.y1 || mask->y2 > center_ind_area.y2) + { + redraw_wheel = 1; + } + + lv_point_t triangle_points[3]; + + int16_t start_angle, end_angle; + start_angle = 0; //Default + end_angle = 360 - LV_CPICKER_DEF_QF; //Default + + if(redraw_wheel) + { + /*if the mask does not include the center of the object + * redrawing all the wheel is not necessary; + * only a given angular range + */ + lv_point_t center = {x, y}; + if(!lv_area_is_point_on(mask, ¢er) + /* + && (mask->x1 != cpicker->coords.x1 || mask->x2 != cpicker->coords.x2 + || mask->y1 != cpicker->coords.y1 || mask->y2 != cpicker->coords.y2) + */ + ) + { + /*get angle from center of object to each corners of the area*/ + int16_t dr, ur, ul, dl; + dr = lv_atan2(mask->x2 - x, mask->y2 - y); + ur = lv_atan2(mask->x2 - x, mask->y1 - y); + ul = lv_atan2(mask->x1 - x, mask->y1 - y); + dl = lv_atan2(mask->x1 - x, mask->y2 - y); + + /* check area position from object axis*/ + uint8_t left = (mask->x2 < x && mask->x1 < x); + uint8_t onYaxis = (mask->x2 > x && mask->x1 < x); + uint8_t right = (mask->x2 > x && mask->x1 > x); + uint8_t top = (mask->y2 < y && mask->y1 < y); + uint8_t onXaxis = (mask->y2 > y && mask->y1 < y); + uint8_t bottom = (mask->y2 > y && mask->y1 > x); + + /*store angular range*/ + if(right && bottom) + { + start_angle = dl; + end_angle = ur; + } + else if(right && onXaxis) + { + start_angle = dl; + end_angle = ul; + } + else if(right && top) + { + start_angle = dr; + end_angle = ul; + } + else if(onYaxis && top) + { + start_angle = dr; + end_angle = dl; + } + else if(left && top) + { + start_angle = ur; + end_angle = dl; + } + else if(left && onXaxis) + { + start_angle = ur; + end_angle = dr; + } + else if(left && bottom) + { + start_angle = ul; + end_angle = dr; + } + else if(onYaxis && bottom) + { + start_angle = ul; + end_angle = ur; + } + + /*rollover angle*/ + if(start_angle > end_angle) + { + end_angle += 360; + } + + /*round to QF factor*/ + start_angle = start_angle/LV_CPICKER_DEF_QF*LV_CPICKER_DEF_QF; + end_angle = end_angle/LV_CPICKER_DEF_QF*LV_CPICKER_DEF_QF;; + + /*shift angle if necessary before adding offset*/ + if((start_angle - LV_CPICKER_DEF_QF) < 0) + { + start_angle += 360; + end_angle += 360; + } + + /*ensure overlapping by adding offset*/ + start_angle -= LV_CPICKER_DEF_QF; + end_angle += LV_CPICKER_DEF_QF; + } + + if(ext->wheel_mode == LV_CPICKER_WHEEL_HUE) + { + for(uint16_t i = start_angle; i <= end_angle; i+= LV_CPICKER_DEF_QF) + { + styleCopy.line.color = lv_color_hsv_to_rgb(i%360, ext->saturation, ext->value); + + triangle_points[0].x = x; + triangle_points[0].y = y; + + triangle_points[1].x = x + (r * lv_trigo_sin(i) >> LV_TRIGO_SHIFT); + triangle_points[1].y = y + (r * lv_trigo_sin(i + 90) >> LV_TRIGO_SHIFT); + + + if(i == end_angle || i == (360 - LV_CPICKER_DEF_QF)) + { + /*the last triangle is drawn without additional overlapping pixels*/ + triangle_points[2].x = x + (r * lv_trigo_sin(i + LV_CPICKER_DEF_QF) >> LV_TRIGO_SHIFT); + triangle_points[2].y = y + (r * lv_trigo_sin(i + LV_CPICKER_DEF_QF + 90) >> LV_TRIGO_SHIFT); + + } + else + { + triangle_points[2].x = x + (r * lv_trigo_sin(i + LV_CPICKER_DEF_QF + TRI_OFFSET) >> LV_TRIGO_SHIFT); + triangle_points[2].y = y + (r * lv_trigo_sin(i + LV_CPICKER_DEF_QF + TRI_OFFSET + 90) >> LV_TRIGO_SHIFT); + + } + + lv_draw_triangle(triangle_points, mask, &styleCopy, LV_OPA_COVER); + } + } + else if(ext->wheel_mode == LV_CPICKER_WHEEL_SAT) + { + for(uint16_t i = start_angle; i <= end_angle; i += LV_CPICKER_DEF_QF) + { + styleCopy.line.color = lv_color_hsv_to_rgb(ext->hue, (i%360)*100/360, ext->value); + + triangle_points[0].x = x; + triangle_points[0].y = y; + + triangle_points[1].x = x + (r * lv_trigo_sin(i) >> LV_TRIGO_SHIFT); + triangle_points[1].y = y + (r * lv_trigo_sin(i + 90) >> LV_TRIGO_SHIFT); + + if(i == end_angle || i == (360 - LV_CPICKER_DEF_QF)) + { + /*the last triangle is drawn without additional overlapping pixels*/ + triangle_points[2].x = x + (r * lv_trigo_sin(i + LV_CPICKER_DEF_QF) >> LV_TRIGO_SHIFT); + triangle_points[2].y = y + (r * lv_trigo_sin(i + LV_CPICKER_DEF_QF + 90) >> LV_TRIGO_SHIFT); + } + else + { + triangle_points[2].x = x + (r * lv_trigo_sin(i + LV_CPICKER_DEF_QF + TRI_OFFSET) >> LV_TRIGO_SHIFT); + triangle_points[2].y = y + (r * lv_trigo_sin(i + LV_CPICKER_DEF_QF + TRI_OFFSET + 90) >> LV_TRIGO_SHIFT); + } + + lv_draw_triangle(triangle_points, mask, &styleCopy, LV_OPA_COVER); + } + } + else if(ext->wheel_mode == LV_CPICKER_WHEEL_VAL) + { + for(uint16_t i = start_angle; i <= end_angle; i += LV_CPICKER_DEF_QF) + { + styleCopy.line.color = lv_color_hsv_to_rgb(ext->hue, ext->saturation, (i%360)*100/360); + + triangle_points[0].x = x; + triangle_points[0].y = y; + + triangle_points[1].x = x + (r * lv_trigo_sin(i) >> LV_TRIGO_SHIFT); + triangle_points[1].y = y + (r * lv_trigo_sin(i + 90) >> LV_TRIGO_SHIFT); + + if(i == end_angle || i == (360 - LV_CPICKER_DEF_QF)) + { + /*the last triangle is drawn without additional overlapping pixels*/ + triangle_points[2].x = x + (r * lv_trigo_sin(i + LV_CPICKER_DEF_QF) >> LV_TRIGO_SHIFT); + triangle_points[2].y = y + (r * lv_trigo_sin(i + LV_CPICKER_DEF_QF + 90) >> LV_TRIGO_SHIFT); + + } + else + { + triangle_points[2].x = x + (r * lv_trigo_sin(i + LV_CPICKER_DEF_QF + TRI_OFFSET) >> LV_TRIGO_SHIFT); + triangle_points[2].y = y + (r * lv_trigo_sin(i + LV_CPICKER_DEF_QF + TRI_OFFSET + 90) >> LV_TRIGO_SHIFT); + } + + lv_draw_triangle(triangle_points, mask, &styleCopy, LV_OPA_COVER); + } + } + } + + //draw center background + lv_area_t center_area; + uint16_t wradius = r - styleCopy.line.width; + center_area.x1 = x - wradius; + center_area.y1 = y - wradius; + center_area.x2 = x + wradius; + center_area.y2 = y + wradius; + styleCopy.body.grad_color = styleCopy.body.main_color; + styleCopy.body.radius = LV_RADIUS_CIRCLE; + lv_draw_rect(¢er_area, mask, &styleCopy, opa_scale); + + //draw the center color indicator + styleCopy.body.main_color = lv_color_hsv_to_rgb(ext->hue, ext->saturation, ext->value); + styleCopy.body.grad_color = styleCopy.body.main_color; + styleCopy.body.radius = LV_RADIUS_CIRCLE; + lv_draw_rect(¢er_ind_area, mask, &styleCopy, opa_scale); + + //Draw the current hue indicator + switch(ext->ind.type) + { + case LV_CPICKER_IND_NONE: + break; + case LV_CPICKER_IND_LINE: + { + lv_point_t start; + lv_point_t end; + + uint16_t angle; + + switch(ext->wheel_mode) + { + default: + case LV_CPICKER_WHEEL_HUE: + angle = ext->hue; + break; + case LV_CPICKER_WHEEL_SAT: + angle = ext->saturation * 360 / 100; + break; + case LV_CPICKER_WHEEL_VAL: + angle = ext->value * 360 / 100; + break; + } + + /*save the angle to refresh the area later*/ + ext->prev_pos = angle; + + start.x = x + ((r - style->line.width + ext->ind.style->body.padding.inner + ext->ind.style->line.width/2) * lv_trigo_sin(angle) >> LV_TRIGO_SHIFT); + start.y = y + ((r - style->line.width + ext->ind.style->body.padding.inner + ext->ind.style->line.width/2) * lv_trigo_sin(angle + 90) >> LV_TRIGO_SHIFT); + + end.x = x + ((r - ext->ind.style->body.padding.inner - ext->ind.style->line.width/2) * lv_trigo_sin(angle) >> LV_TRIGO_SHIFT); + end.y = y + ((r - ext->ind.style->body.padding.inner - ext->ind.style->line.width/2) * lv_trigo_sin(angle + 90) >> LV_TRIGO_SHIFT); + + lv_draw_line(&start, &end, mask, ext->ind.style, opa_scale); + if(ext->ind.style->line.rounded) + { + lv_area_t circle_area; + circle_area.x1 = start.x - ((ext->ind.style->line.width - 1) >> 1) - ((ext->ind.style->line.width - 1) & 0x1); + circle_area.y1 = start.y - ((ext->ind.style->line.width - 1) >> 1) - ((ext->ind.style->line.width - 1) & 0x1); + circle_area.x2 = start.x + ((ext->ind.style->line.width - 1) >> 1); + circle_area.y2 = start.y + ((ext->ind.style->line.width - 1) >> 1); + lv_draw_rect(&circle_area, mask, ext->ind.style, opa_scale); + + circle_area.x1 = end.x - ((ext->ind.style->line.width - 1) >> 1) - ((ext->ind.style->line.width - 1) & 0x1); + circle_area.y1 = end.y - ((ext->ind.style->line.width - 1) >> 1) - ((ext->ind.style->line.width - 1) & 0x1); + circle_area.x2 = end.x + ((ext->ind.style->line.width - 1) >> 1); + circle_area.y2 = end.y + ((ext->ind.style->line.width - 1) >> 1); + lv_draw_rect(&circle_area, mask, ext->ind.style, opa_scale); + } + break; + } + case LV_CPICKER_IND_CIRCLE: + { + lv_area_t circle_area; + uint32_t cx, cy; + + uint16_t angle; + + switch(ext->wheel_mode) + { + default: + case LV_CPICKER_WHEEL_HUE: + angle = ext->hue; + break; + case LV_CPICKER_WHEEL_SAT: + angle = ext->saturation * 360 / 100; + break; + case LV_CPICKER_WHEEL_VAL: + angle = ext->value * 360 / 100; + break; + } + + /*save the angle to refresh the area later*/ + ext->prev_pos = angle; + + cx = x + ((r - style->line.width/2) * lv_trigo_sin(angle) >> LV_TRIGO_SHIFT); + cy = y + ((r - style->line.width/2) * lv_trigo_sin(angle + 90) >> LV_TRIGO_SHIFT); + + circle_area.x1 = cx - style->line.width/2; + circle_area.y1 = cy - style->line.width/2; + circle_area.x2 = cx + style->line.width/2; + circle_area.y2 = cy + style->line.width/2; + + ext->ind.style->body.radius = LV_RADIUS_CIRCLE; + lv_draw_rect(&circle_area, mask, ext->ind.style, opa_scale); + break; + } + case LV_CPICKER_IND_IN: + { + lv_area_t circle_area; + uint32_t cx, cy; + + uint16_t angle; + + switch(ext->wheel_mode) + { + default: + case LV_CPICKER_WHEEL_HUE: + angle = ext->hue; + break; + case LV_CPICKER_WHEEL_SAT: + angle = ext->saturation * 360 / 100; + break; + case LV_CPICKER_WHEEL_VAL: + angle = ext->value * 360 / 100; + break; + } + + /*save the angle to refresh the area later*/ + ext->prev_pos = angle; + + uint16_t ind_radius = lv_sqrt((4*rin*rin)/2)/2 + 1 - style->body.padding.inner; + ind_radius = (ind_radius + rin) / 2; + + cx = x + ((ind_radius) * lv_trigo_sin(angle) >> LV_TRIGO_SHIFT); + cy = y + ((ind_radius) * lv_trigo_sin(angle + 90) >> LV_TRIGO_SHIFT); + + circle_area.x1 = cx - ext->ind.style->line.width/2; + circle_area.y1 = cy - ext->ind.style->line.width/2; + circle_area.x2 = cx + ext->ind.style->line.width/2; + circle_area.y2 = cy + ext->ind.style->line.width/2; + + ext->ind.style->body.radius = LV_RADIUS_CIRCLE; + lv_draw_rect(&circle_area, mask, ext->ind.style, opa_scale); + break; + } + } + + + /* + //code to color the drawn area + static uint32_t c = 0; + lv_style_t style2; + lv_style_copy(&style2, &lv_style_plain); + style2.body.main_color.full = c; + style2.body.grad_color.full = c; + c += 0x123445678; + lv_draw_rect(mask, mask, &style2, opa_scale); + */ + } + /*Post draw when the children are drawn*/ + else if(mode == LV_DESIGN_DRAW_POST) { + + } + + return true; +} + +/** + * Handle the drawing related tasks of the color_pickerwhen of rectangle type + * @param cpicker pointer to an object + * @param mask the object will be drawn only in this area + * @param mode LV_DESIGN_COVER_CHK: only check if the object fully covers the 'mask_p' area + * (return 'true' if yes) + * LV_DESIGN_DRAW: draw the object (always return 'true') + * LV_DESIGN_DRAW_POST: drawing after every children are drawn + * @param return true/false, depends on 'mode' + */ +static bool lv_cpicker_rect_design(lv_obj_t * cpicker, const lv_area_t * mask, lv_design_mode_t mode) +{ + /*Return false if the object is not covers the mask_p area*/ + if(mode == LV_DESIGN_COVER_CHK) { + return false; + } + /*Draw the object*/ + else if(mode == LV_DESIGN_DRAW_MAIN) { + + lv_cpicker_ext_t * ext = lv_obj_get_ext_attr(cpicker); + lv_style_t * style = lv_cpicker_get_style(cpicker, LV_CPICKER_STYLE_MAIN); + + static lv_style_t styleCopy; + lv_style_copy(&styleCopy, style); + + lv_coord_t w = lv_obj_get_width(cpicker); + lv_coord_t h = lv_obj_get_height(cpicker); + + lv_coord_t gradient_w, gradient_h; + lv_area_t gradient_area; + + lv_coord_t x1 = cpicker->coords.x1; + lv_coord_t y1 = cpicker->coords.y1; + lv_coord_t x2 = cpicker->coords.x2; + lv_coord_t y2 = cpicker->coords.y2; + lv_opa_t opa_scale = lv_obj_get_opa_scale(cpicker); + + + /* prepare the color preview area */ + uint16_t preview_offset = style->line.width; + lv_area_t preview_area; + uint16_t style_body_padding_ver = style->body.padding.top + style->body.padding.bottom; + uint16_t style_body_padding_hor = style->body.padding.left + style->body.padding.right; + if(style_body_padding_ver == 0) + { + /* draw the color preview rect to the side of the gradient*/ + if(style_body_padding_hor >= 0) + { + /*draw the preview to the right*/ + gradient_w = w - preview_offset - (LV_MATH_ABS(style_body_padding_hor) - 1); + gradient_h = y2 - y1; + gradient_area.x1 = x1; + gradient_area.x2 = gradient_area.x1 + gradient_w; + gradient_area.y1 = y1; + gradient_area.y2 = y2; + + preview_area.x1 = x2 - preview_offset; + preview_area.y1 = y1; + preview_area.x2 = x2 ; + preview_area.y2 = y2; + } + else + { + /*draw the preview to the left*/ + gradient_w = w - preview_offset - (LV_MATH_ABS(style_body_padding_hor) - 1); + gradient_h = y2 - y1; + gradient_area.x1 = x2 - gradient_w; + gradient_area.x2 = x2; + gradient_area.y1 = y1; + gradient_area.y2 = y2; + + preview_area.x1 = x1; + preview_area.y1 = y1; + preview_area.x2 = x1 + preview_offset; + preview_area.y2 = y2; + } + } + else + { + /* draw the color preview rect on top or below the gradient*/ + if(style_body_padding_ver >= 0) + { + /*draw the preview on top*/ + gradient_w = w; + gradient_h = (y2 - y1) - preview_offset - (LV_MATH_ABS(style_body_padding_ver) - 1); + gradient_area.x1 = x1; + gradient_area.x2 = x2; + gradient_area.y1 = y2 - gradient_h; + gradient_area.y2 = y2; + + preview_area.x1 = x1; + preview_area.y1 = y1; + preview_area.x2 = x2; + preview_area.y2 = y1 + preview_offset; + } + else + { + /*draw the preview below the gradient*/ + gradient_w = w; + gradient_h = (y2 - y1) - preview_offset - (LV_MATH_ABS(style_body_padding_ver) - 1); + gradient_area.x1 = x1; + gradient_area.x2 = x2; + gradient_area.y1 = y1; + gradient_area.y2 = y1 + gradient_h; + + preview_area.x1 = x1; + preview_area.y1 = y2 - preview_offset; + preview_area.x2 = x2; + preview_area.y2 = y2; + } + } + + if(style->line.rounded) + { + + /*draw rounded edges to the gradient*/ + lv_area_t rounded_edge_area; + rounded_edge_area.x1 = gradient_area.x1; + rounded_edge_area.x2 = gradient_area.x1 + gradient_h; + rounded_edge_area.y1 = gradient_area.y1; + rounded_edge_area.y2 = gradient_area.y2; + + gradient_area.x1 += gradient_h/2; + gradient_area.x2 -= gradient_h/2; + gradient_w -= gradient_h; + + switch(ext->wheel_mode) + { + default: + case LV_CPICKER_WHEEL_HUE: + styleCopy.body.main_color = lv_color_hsv_to_rgb(0, ext->saturation, ext->value); + break; + case LV_CPICKER_WHEEL_SAT: + styleCopy.body.main_color = lv_color_hsv_to_rgb(ext->hue, 0, ext->value); + break; + case LV_CPICKER_WHEEL_VAL: + styleCopy.body.main_color = lv_color_hsv_to_rgb(ext->hue, ext->saturation, 0); + break; + } + styleCopy.body.grad_color = styleCopy.body.main_color; + + styleCopy.body.radius = LV_RADIUS_CIRCLE; + + lv_draw_rect(&rounded_edge_area, mask, &styleCopy, opa_scale); + + rounded_edge_area.x1 += gradient_w - 1; + rounded_edge_area.x2 += gradient_w - 1; + + switch(ext->wheel_mode) + { + default: + case LV_CPICKER_WHEEL_HUE: + styleCopy.body.main_color = lv_color_hsv_to_rgb(360, ext->saturation, ext->value); + break; + case LV_CPICKER_WHEEL_SAT: + styleCopy.body.main_color = lv_color_hsv_to_rgb(ext->hue, 100, ext->value); + break; + case LV_CPICKER_WHEEL_VAL: + styleCopy.body.main_color = lv_color_hsv_to_rgb(ext->hue, ext->saturation, 100); + break; + } + styleCopy.body.grad_color = styleCopy.body.main_color; + + lv_draw_rect(&rounded_edge_area, mask, &styleCopy, opa_scale); + } + + for(uint16_t i = 0; i < 360; i += LV_MATH_MAX(LV_CPICKER_DEF_QF, 360/gradient_w)) + { + switch(ext->wheel_mode) + { + default: + case LV_CPICKER_WHEEL_HUE: + styleCopy.body.main_color = lv_color_hsv_to_rgb(i%360, ext->saturation, ext->value); + break; + case LV_CPICKER_WHEEL_SAT: + styleCopy.body.main_color = lv_color_hsv_to_rgb(ext->hue, (i%360)*100/360, ext->value); + break; + case LV_CPICKER_WHEEL_VAL: + styleCopy.body.main_color = lv_color_hsv_to_rgb(ext->hue, ext->saturation, (i%360)*100/360); + break; + } + + styleCopy.body.grad_color = styleCopy.body.main_color; + + /*the following attribute might need changing between index to add border, shadow, radius etc*/ + styleCopy.body.radius = 0; + styleCopy.body.border.width = 0; + styleCopy.body.shadow.width = 0; + styleCopy.body.opa = LV_OPA_COVER; + + lv_area_t rect_area; + + /*scale angle (hue/sat/val) to linear coordinate*/ + lv_coord_t xi = i*gradient_w/360; + + rect_area.x1 = LV_MATH_MIN(gradient_area.x1 + xi, gradient_area.x1 + gradient_w - LV_MATH_MAX(LV_CPICKER_DEF_QF, 360/gradient_w)); + rect_area.y1 = gradient_area.y1; + rect_area.x2 = rect_area.x1 + LV_MATH_MAX(LV_CPICKER_DEF_QF, 360/gradient_w); + rect_area.y2 = gradient_area.y2; + + lv_draw_rect(&rect_area, mask, &styleCopy, opa_scale); + } + + if(style->line.rounded) + { + /*Restore gradient area to take rounded end in account*/ + gradient_area.x1 -= gradient_h/2; + gradient_area.x2 += gradient_h/2; + //gradient_w += gradient_h; + } + + /*draw the color preview indicator*/ + styleCopy.body.main_color = lv_cpicker_get_color(cpicker); + styleCopy.body.grad_color = styleCopy.body.main_color; + if(style->line.rounded && style_body_padding_hor == 0) + { + styleCopy.body.radius = gradient_h; + } + lv_draw_rect(&preview_area, mask, &styleCopy, opa_scale); + + /* + styleCopy.line.color = styleCopy.body.main_color; + styleCopy.line.width = 10; + lv_draw_arc(cpicker->coords.x1 + 3*gradient_h/2, cpicker->coords.y1 + gradient_h/2, gradient_h / 2 + styleCopy.line.width + 2, mask, 180, 360, &styleCopy, opa_scale); + //lv_draw_arc(cpicker->coords.x1 + gradient_w - gradient_h/2, cpicker->coords.y1 + gradient_h/2, gradient_h / 2 + styleCopy.line.width + 2, mask, 0, 180, &styleCopy, opa_scale); + */ + + /*draw the color position indicator*/ + lv_coord_t ind_pos = style->line.rounded ? gradient_h / 2 : 0; + switch(ext->wheel_mode) + { + default: + case LV_CPICKER_WHEEL_HUE: + ind_pos += ext->hue * gradient_w /360; + break; + case LV_CPICKER_WHEEL_SAT: + ind_pos += ext->saturation * gradient_w / 100 ; + break; + case LV_CPICKER_WHEEL_VAL: + ind_pos += ext->value * gradient_w / 100; + break; + } + + switch(ext->ind.type) + { + case LV_CPICKER_IND_NONE: + /*no indicator*/ + break; + case LV_CPICKER_IND_LINE: + { + lv_point_t p1, p2; + p1.x = gradient_area.x1 + ind_pos; + p2.x = p1.x; + p1.y = gradient_area.y1; + p2.y = gradient_area.y2; + + lv_draw_line(&p1, &p2, &gradient_area, ext->ind.style, opa_scale); + break; + } + case LV_CPICKER_IND_CIRCLE: + { + lv_area_t circle_ind_area; + circle_ind_area.x1 = gradient_area.x1 + ind_pos - gradient_h/2; + circle_ind_area.x2 = circle_ind_area.x1 + gradient_h; + circle_ind_area.y1 = gradient_area.y1; + circle_ind_area.y2 = gradient_area.y2; + + lv_style_copy(&styleCopy, ext->ind.style); + styleCopy.body.radius = LV_RADIUS_CIRCLE; + + lv_draw_rect(&circle_ind_area, mask, &styleCopy, opa_scale); + break; + } + case LV_CPICKER_IND_IN: + { + /*draw triangle under the gradient*/ + lv_point_t triangle_points[3]; + + triangle_points[0].x = ind_pos + gradient_area.x1; + triangle_points[0].y = gradient_area.y2 - (gradient_h/3); + + triangle_points[1].x = triangle_points[0].x - ext->ind.style->line.width / 3; + triangle_points[1].y = gradient_area.y2; + + triangle_points[2].x = triangle_points[0].x + ext->ind.style->line.width / 3; + triangle_points[2].y = gradient_area.y2; + + lv_draw_triangle(triangle_points, &gradient_area, ext->ind.style, LV_OPA_COVER); + + triangle_points[0].y = gradient_area.y1 + (gradient_h/3); + triangle_points[1].y = gradient_area.y1 - 1; + triangle_points[2].y = gradient_area.y1 - 1; + lv_draw_triangle(triangle_points, &gradient_area, ext->ind.style, LV_OPA_COVER); + break; + } + default: + break; + } + } + /*Post draw when the children are drawn*/ + else if(mode == LV_DESIGN_DRAW_POST) { + + } + + return true; +} + +/** + * Signal function of the color_picker of wheel type + * @param cpicker pointer to a color_picker object + * @param sign a signal type from lv_signal_t enum + * @param param pointer to a signal specific variable + * @return LV_RES_OK: the object is not deleted in the function; LV_RES_INV: the object is deleted + */ +static lv_res_t lv_cpicker_disc_signal(lv_obj_t * cpicker, lv_signal_t sign, void * param) +{ + lv_cpicker_ext_t * ext = lv_obj_get_ext_attr(cpicker); + + lv_res_t res; + + /* Include the ancient signal function */ + res = ancestor_signal(cpicker, sign, param); + if(res != LV_RES_OK) return res; + + lv_style_t * style = lv_cpicker_get_style(cpicker, LV_CPICKER_STYLE_MAIN); + + lv_coord_t r_out = (LV_MATH_MIN(lv_obj_get_width(cpicker), lv_obj_get_height(cpicker))) / 2; + lv_coord_t r_in = r_out - style->line.width - style->body.padding.inner; + + lv_coord_t x = cpicker->coords.x1 + lv_obj_get_width(cpicker) / 2; + lv_coord_t y = cpicker->coords.y1 + lv_obj_get_height(cpicker) / 2; + + + + if(sign == LV_SIGNAL_CLEANUP) { + /*Nothing to cleanup. (No dynamically allocated memory in 'ext')*/ + } else if(sign == LV_SIGNAL_GET_TYPE) { + lv_obj_type_t * buf = param; + uint8_t i; + for(i = 0; i < LV_MAX_ANCESTOR_NUM - 1; i++) { /*Find the last set data*/ + if(buf->type[i] == NULL) break; + } + buf->type[i] = "lv_cpicker"; + } + else if(sign == LV_SIGNAL_PRESSED) + { + switch(ext->wheel_mode) + { + case LV_CPICKER_WHEEL_HUE: + ext->prev_hue = ext->hue; + break; + case LV_CPICKER_WHEEL_SAT: + ext->prev_saturation = ext->saturation; + break; + case LV_CPICKER_WHEEL_VAL: + ext->prev_value = ext->value; + break; + } + + lv_indev_t * indev = param; + lv_coord_t xp = indev->proc.types.pointer.act_point.x - x; + lv_coord_t yp = indev->proc.types.pointer.act_point.y - y; + + if((xp*xp + yp*yp) < (r_in*r_in)) + { + if(lv_tick_elaps(ext->last_clic) < 400) + { + switch(ext->wheel_mode) + { + case LV_CPICKER_WHEEL_HUE: + ext->hue = 0; + ext->prev_hue = ext->hue; + break; + case LV_CPICKER_WHEEL_SAT: + ext->saturation = 100; + ext->prev_saturation = ext->saturation; + break; + case LV_CPICKER_WHEEL_VAL: + ext->value = 100; + ext->prev_value = ext->value; + break; + } + //lv_cpicker_invalidate_indicator(cpicker); + } + ext->last_clic = lv_tick_get(); + } + } + else if(sign == LV_SIGNAL_PRESSING) + { + lv_indev_t * indev = param; + lv_coord_t xp = indev->proc.types.pointer.act_point.x - x; + lv_coord_t yp = indev->proc.types.pointer.act_point.y - y; + + if((xp*xp + yp*yp) < (r_out*r_out) && (xp*xp + yp*yp) >= (r_in*r_in)) + { + switch(ext->wheel_mode) + { + case LV_CPICKER_WHEEL_HUE: + ext->hue = lv_atan2(xp, yp); + ext->prev_hue = ext->hue; + break; + case LV_CPICKER_WHEEL_SAT: + ext->saturation = lv_atan2(xp, yp) * 100.0 / 360.0; + ext->prev_saturation = ext->saturation; + break; + case LV_CPICKER_WHEEL_VAL: + ext->value = lv_atan2(xp, yp) * 100.0 / 360.0; + ext->prev_value = ext->value; + break; + } + + lv_cpicker_invalidate_indicator(cpicker); + + } + } + else if(sign == LV_SIGNAL_PRESS_LOST) + { + switch(ext->wheel_mode) + { + case LV_CPICKER_WHEEL_HUE: + ext->prev_hue = ext->hue; + break; + case LV_CPICKER_WHEEL_SAT: + ext->prev_saturation = ext->saturation; + break; + case LV_CPICKER_WHEEL_VAL: + ext->prev_value = ext->value; + break; + } + lv_cpicker_invalidate_indicator(cpicker); + } + else if(sign == LV_SIGNAL_RELEASED) + { + lv_indev_t * indev = param; + lv_coord_t xp = indev->proc.types.pointer.act_point.x - x; + lv_coord_t yp = indev->proc.types.pointer.act_point.y - y; + + if((xp*xp + yp*yp) < (r_out*r_out) && (xp*xp + yp*yp) >= (r_in*r_in)) + { + switch(ext->wheel_mode) + { + case LV_CPICKER_WHEEL_HUE: + ext->hue = lv_atan2(xp, yp); + ext->prev_hue = ext->hue; + break; + case LV_CPICKER_WHEEL_SAT: + ext->saturation = lv_atan2(xp, yp) * 100.0 / 360.0; + ext->prev_saturation = ext->saturation; + break; + case LV_CPICKER_WHEEL_VAL: + ext->value = lv_atan2(xp, yp) * 100.0 / 360.0; + ext->prev_value = ext->value; + break; + } + + lv_cpicker_invalidate_indicator(cpicker); + + //LVGLv5 if(ext->value_changed != NULL) + //LVGLv5 ext->value_changed(cpicker); + } + } + else if(sign == LV_SIGNAL_LONG_PRESS) + { + if(!ext->wheel_fixed) + { + lv_indev_t * indev = param; + lv_coord_t xp = indev->proc.types.pointer.act_point.x - x; + lv_coord_t yp = indev->proc.types.pointer.act_point.y - y; + + if((xp*xp + yp*yp) < (r_in*r_in)) + { + switch(ext->wheel_mode) + { + case LV_CPICKER_WHEEL_HUE: + ext->prev_hue = ext->hue; + break; + case LV_CPICKER_WHEEL_SAT: + ext->prev_saturation = ext->saturation; + break; + case LV_CPICKER_WHEEL_VAL: + ext->prev_value = ext->value; + break; + } + + ext->wheel_mode = (ext->wheel_mode + 1) % 3; + + lv_obj_invalidate(cpicker); + } + } + } + else if(sign == LV_SIGNAL_CONTROL) + { + /* LVGLv5 + uint32_t c = *((uint32_t *)param); /*uint32_t because can be UTF-8* / + if(c == LV_GROUP_KEY_RIGHT) + { + switch(ext->wheel_mode) + { + case LV_CPICKER_WHEEL_HUE: + ext->hue = (ext->hue + 1) % 360; + break; + case LV_CPICKER_WHEEL_SAT: + ext->saturation = (ext->saturation + 1) % 100; + break; + case LV_CPICKER_WHEEL_VAL: + ext->value = (ext->value + 1) % 100; + break; + } + + lv_cpicker_invalidate_indicator(cpicker); + + if(ext->value_changed != NULL) + ext->value_changed(cpicker); + } + else if(c == LV_GROUP_KEY_LEFT) + { + switch(ext->wheel_mode) + { + case LV_CPICKER_WHEEL_HUE: + ext->hue = ext->hue > 0?(ext->hue - 1):360; + break; + case LV_CPICKER_WHEEL_SAT: + ext->saturation = ext->saturation > 0?(ext->saturation - 1):100; + break; + case LV_CPICKER_WHEEL_VAL: + ext->value = ext->value > 0?(ext->value - 1):100; + break; + } + + lv_cpicker_invalidate_indicator(cpicker); + + if(ext->value_changed != NULL) + ext->value_changed(cpicker); + } + else if(c == LV_GROUP_KEY_UP) + { + switch(ext->wheel_mode) + { + case LV_CPICKER_WHEEL_HUE: + ext->hue = (ext->hue + 1) % 360; + break; + case LV_CPICKER_WHEEL_SAT: + ext->saturation = (ext->saturation + 1) % 100; + break; + case LV_CPICKER_WHEEL_VAL: + ext->value = (ext->value + 1) % 100; + break; + } + + lv_cpicker_invalidate_indicator(cpicker); + + if(ext->value_changed != NULL) + ext->value_changed(cpicker); + } + else if(c == LV_GROUP_KEY_DOWN) + { + switch(ext->wheel_mode) + { + case LV_CPICKER_WHEEL_HUE: + ext->hue = ext->hue > 0?(ext->hue - 1):360; + break; + case LV_CPICKER_WHEEL_SAT: + ext->saturation = ext->saturation > 0?(ext->saturation - 1):100; + break; + case LV_CPICKER_WHEEL_VAL: + ext->value = ext->value > 0?(ext->value - 1):100; + break; + } + + lv_cpicker_invalidate_indicator(cpicker); + + if(ext->value_changed != NULL) + ext->value_changed(cpicker); + } + */ + } + + return LV_RES_OK; +} + +/** + * Signal function of the color_picker of rectangle type + * @param cpicker pointer to a color_picker object + * @param sign a signal type from lv_signal_t enum + * @param param pointer to a signal specific variable + * @return LV_RES_OK: the object is not deleted in the function; LV_RES_INV: the object is deleted + */ +static lv_res_t lv_cpicker_rect_signal(lv_obj_t * cpicker, lv_signal_t sign, void * param) +{ + lv_cpicker_ext_t * ext = lv_obj_get_ext_attr(cpicker); + + lv_res_t res; + + /* Include the ancient signal function */ + res = ancestor_signal(cpicker, sign, param); + if(res != LV_RES_OK) return res; + + lv_style_t * style = lv_cpicker_get_style(cpicker, LV_CPICKER_STYLE_MAIN); + + lv_coord_t r_out = (LV_MATH_MIN(lv_obj_get_width(cpicker), lv_obj_get_height(cpicker))) / 2; + lv_coord_t r_in = r_out - style->line.width - style->body.padding.inner; + + lv_coord_t x = cpicker->coords.x1 + lv_obj_get_width(cpicker) / 2; + lv_coord_t y = cpicker->coords.y1 + lv_obj_get_height(cpicker) / 2; + + + + if(sign == LV_SIGNAL_CLEANUP) { + /*Nothing to cleanup. (No dynamically allocated memory in 'ext')*/ + } else if(sign == LV_SIGNAL_GET_TYPE) { + lv_obj_type_t * buf = param; + uint8_t i; + for(i = 0; i < LV_MAX_ANCESTOR_NUM - 1; i++) { /*Find the last set data*/ + if(buf->type[i] == NULL) break; + } + buf->type[i] = "lv_cpicker"; + } + else if(sign == LV_SIGNAL_PRESSED) + { + switch(ext->wheel_mode) + { + case LV_CPICKER_WHEEL_HUE: + ext->prev_hue = ext->hue; + break; + case LV_CPICKER_WHEEL_SAT: + ext->prev_saturation = ext->saturation; + break; + case LV_CPICKER_WHEEL_VAL: + ext->prev_value = ext->value; + break; + } + + lv_indev_t * indev = param; + lv_coord_t xp = indev->proc.types.pointer.act_point.x - x; + lv_coord_t yp = indev->proc.types.pointer.act_point.y - y; + + lv_area_t colorIndArea; + //todo : set the area to the color indicator area + if(lv_area_is_point_on(&colorIndArea, &indev->proc.types.pointer.act_point)) + { + if(lv_tick_elaps(ext->last_clic) < 400) + { + switch(ext->wheel_mode) + { + case LV_CPICKER_WHEEL_HUE: + ext->hue = 0; + ext->prev_hue = ext->hue; + break; + case LV_CPICKER_WHEEL_SAT: + ext->saturation = 100; + ext->prev_saturation = ext->saturation; + break; + case LV_CPICKER_WHEEL_VAL: + ext->value = 100; + ext->prev_value = ext->value; + break; + } + lv_obj_invalidate(cpicker); + } + ext->last_clic = lv_tick_get(); + } + } + else if(sign == LV_SIGNAL_PRESSING) + { + lv_indev_t * indev = param; + lv_coord_t xp = indev->proc.types.pointer.act_point.x - x; + lv_coord_t yp = indev->proc.types.pointer.act_point.y - y; + + lv_area_t colorGradientArea; + //todo : set the area to the color gradient area + if(lv_area_is_point_on(&colorGradientArea, &indev->proc.types.pointer.act_point)) + { + switch(ext->wheel_mode) + { + case LV_CPICKER_WHEEL_HUE: + ext->hue = lv_atan2(xp, yp); + ext->prev_hue = ext->hue; + break; + case LV_CPICKER_WHEEL_SAT: + ext->saturation = lv_atan2(xp, yp) * 100.0 / 360.0; + ext->prev_saturation = ext->saturation; + break; + case LV_CPICKER_WHEEL_VAL: + ext->value = lv_atan2(xp, yp) * 100.0 / 360.0; + ext->prev_value = ext->value; + break; + } + lv_obj_invalidate(cpicker); + } + } + else if(sign == LV_SIGNAL_PRESS_LOST) + { + switch(ext->wheel_mode) + { + case LV_CPICKER_WHEEL_HUE: + ext->prev_hue = ext->hue; + break; + case LV_CPICKER_WHEEL_SAT: + ext->prev_saturation = ext->saturation; + break; + case LV_CPICKER_WHEEL_VAL: + ext->prev_value = ext->value; + break; + } + lv_obj_invalidate(cpicker); + } + else if(sign == LV_SIGNAL_RELEASED) + { + lv_indev_t * indev = param; + lv_coord_t xp = indev->proc.types.pointer.act_point.x - x; + lv_coord_t yp = indev->proc.types.pointer.act_point.y - y; + + lv_area_t colorGradientArea; + //todo : set th area to the color gradient area + if(lv_area_is_point_on(&colorGradientArea, &indev->proc.types.pointer.act_point)) + { + switch(ext->wheel_mode) + { + case LV_CPICKER_WHEEL_HUE: + ext->hue = lv_atan2(xp, yp); + ext->prev_hue = ext->hue; + break; + case LV_CPICKER_WHEEL_SAT: + ext->saturation = lv_atan2(xp, yp) * 100.0 / 360.0; + ext->prev_saturation = ext->saturation; + break; + case LV_CPICKER_WHEEL_VAL: + ext->value = lv_atan2(xp, yp) * 100.0 / 360.0; + ext->prev_value = ext->value; + break; + } + + lv_obj_invalidate(cpicker); + + //LVGLv5 if(ext->value_changed != NULL) + //LVGLv5 ext->value_changed(cpicker); + } + } + else if(sign == LV_SIGNAL_LONG_PRESS) + { + if(!ext->wheel_fixed) + { + lv_indev_t * indev = param; + lv_coord_t xp = indev->proc.types.pointer.act_point.x - x; + lv_coord_t yp = indev->proc.types.pointer.act_point.y - y; + + lv_area_t colorIndArea; + //todo : set the area to the color indicator area + if(lv_area_is_point_on(&colorIndArea, &indev->proc.types.pointer.act_point)) + { + switch(ext->wheel_mode) + { + case LV_CPICKER_WHEEL_HUE: + ext->prev_hue = ext->hue; + break; + case LV_CPICKER_WHEEL_SAT: + ext->prev_saturation = ext->saturation; + break; + case LV_CPICKER_WHEEL_VAL: + ext->prev_value = ext->value; + break; + } + + ext->wheel_mode = (ext->wheel_mode + 1) % 3; + lv_obj_invalidate(cpicker); + } + } + } + else if(sign == LV_SIGNAL_CONTROL) + { + /* LVGLv5 + uint32_t c = *((uint32_t *)param); /*uint32_t because can be UTF-8* / + if(c == LV_GROUP_KEY_RIGHT) + { + switch(ext->wheel_mode) + { + case LV_CPICKER_WHEEL_HUE: + ext->hue = (ext->hue + 1) % 360; + break; + case LV_CPICKER_WHEEL_SAT: + ext->saturation = (ext->saturation + 1) % 100; + break; + case LV_CPICKER_WHEEL_VAL: + ext->value = (ext->value + 1) % 100; + break; + } + lv_obj_invalidate(cpicker); + if(ext->value_changed != NULL) + ext->value_changed(cpicker); + } + else if(c == LV_GROUP_KEY_LEFT) + { + switch(ext->wheel_mode) + { + case LV_CPICKER_WHEEL_HUE: + ext->hue = ext->hue > 0?(ext->hue - 1):360; + break; + case LV_CPICKER_WHEEL_SAT: + ext->saturation = ext->saturation > 0?(ext->saturation - 1):100; + break; + case LV_CPICKER_WHEEL_VAL: + ext->value = ext->value > 0?(ext->value - 1):100; + break; + } + lv_obj_invalidate(cpicker); + if(ext->value_changed != NULL) + ext->value_changed(cpicker); + } + else if(c == LV_GROUP_KEY_UP) + { + switch(ext->wheel_mode) + { + case LV_CPICKER_WHEEL_HUE: + ext->hue = (ext->hue + 1) % 360; + break; + case LV_CPICKER_WHEEL_SAT: + ext->saturation = (ext->saturation + 1) % 100; + break; + case LV_CPICKER_WHEEL_VAL: + ext->value = (ext->value + 1) % 100; + break; + } + lv_obj_invalidate(cpicker); + if(ext->value_changed != NULL) + ext->value_changed(cpicker); + } + else if(c == LV_GROUP_KEY_DOWN) + { + switch(ext->wheel_mode) + { + case LV_CPICKER_WHEEL_HUE: + ext->hue = ext->hue > 0?(ext->hue - 1):360; + break; + case LV_CPICKER_WHEEL_SAT: + ext->saturation = ext->saturation > 0?(ext->saturation - 1):100; + break; + case LV_CPICKER_WHEEL_VAL: + ext->value = ext->value > 0?(ext->value - 1):100; + break; + } + lv_obj_invalidate(cpicker); + if(ext->value_changed != NULL) + ext->value_changed(cpicker); + } + */ + } + + return LV_RES_OK; +} + +static void lv_cpicker_invalidate_indicator(lv_obj_t * cpicker) +{ + lv_cpicker_ext_t * ext = lv_obj_get_ext_attr(cpicker); + lv_style_t * style = lv_cpicker_get_style(cpicker, LV_CPICKER_STYLE_MAIN); + + static lv_style_t styleCopy; + lv_style_copy(&styleCopy, style); + + lv_coord_t r = (LV_MATH_MIN(lv_obj_get_width(cpicker), lv_obj_get_height(cpicker))) / 2; + lv_coord_t x = cpicker->coords.x1 + lv_obj_get_width(cpicker) / 2; + lv_coord_t y = cpicker->coords.y1 + lv_obj_get_height(cpicker) / 2; + + if(ext->type == LV_CPICKER_TYPE_DISC) + { + /*invalidate center*/ + lv_area_t center_col_area; + + uint32_t rin = r - styleCopy.line.width; + + uint16_t radius = lv_sqrt((4*rin*rin)/2)/2 + 1 - style->body.padding.inner; + + center_col_area.x1 = x - radius; + center_col_area.y1 = y - radius; + center_col_area.x2 = x + radius; + center_col_area.y2 = y + radius; + + lv_inv_area(¢er_col_area, NULL); + + switch(ext->ind.type) + { + case LV_CPICKER_IND_LINE: + { + lv_area_t line_area; + lv_point_t point1, point2; + lv_coord_t x1, y1, x2, y2; + uint16_t angle; + + switch(ext->wheel_mode) + { + default: + case LV_CPICKER_WHEEL_HUE: + angle = ext->hue; + break; + case LV_CPICKER_WHEEL_SAT: + angle = ext->saturation * 360 / 100; + break; + case LV_CPICKER_WHEEL_VAL: + angle = ext->value * 360 / 100; + break; + } + + x1 = x + ((r - style->line.width + ext->ind.style->body.padding.inner + ext->ind.style->line.width/2) * lv_trigo_sin(angle) >> LV_TRIGO_SHIFT); + y1 = y + ((r - style->line.width + ext->ind.style->body.padding.inner + ext->ind.style->line.width/2) * lv_trigo_sin(angle + 90) >> LV_TRIGO_SHIFT); + x2 = x + ((r - ext->ind.style->body.padding.inner - ext->ind.style->line.width/2) * lv_trigo_sin(angle) >> LV_TRIGO_SHIFT); + y2 = y + ((r - ext->ind.style->body.padding.inner - ext->ind.style->line.width/2) * lv_trigo_sin(angle + 90) >> LV_TRIGO_SHIFT); + + point1.x = x1; + point1.y = y1; + point2.x = x2; + point2.y = y2; + + //if(LV_MATH_ABS(point1.x - point2.x) > LV_MATH_ABS(point1.y - point2.y)) + //{ + /*Steps less in y then x -> rather horizontal*/ + if(point1.x < point2.x) { + line_area.x1 = point1.x; + //line_area.y1 = point1.y; + line_area.x2 = point2.x; + //line_area.y2 = point2.y; + } else { + line_area.x1 = point2.x; + //line_area.y1 = point2.y; + line_area.x2 = point1.x; + //line_area.y2 = point1.y; + } + //} else { + /*Steps less in x then y -> rather vertical*/ + if(point1.y < point2.y) { + //line_area.x1 = point1.x; + line_area.y1 = point1.y; + //line_area.x2 = point2.x; + line_area.y2 = point2.y; + } else { + //line_area.x1 = point2.x; + line_area.y1 = point2.y; + line_area.x2 = point1.x; + //line_area.y2 = point1.y; + } + //} + + line_area.x1 -= 2*ext->ind.style->line.width; + line_area.y1 -= 2*ext->ind.style->line.width; + line_area.x2 += 2*ext->ind.style->line.width; + line_area.y2 += 2*ext->ind.style->line.width; + + lv_inv_area(&line_area, NULL); + + + angle = ext->prev_pos; + + x1 = x + ((r - style->line.width + ext->ind.style->body.padding.inner + ext->ind.style->line.width/2) * lv_trigo_sin(angle) >> LV_TRIGO_SHIFT); + y1 = y + ((r - style->line.width + ext->ind.style->body.padding.inner + ext->ind.style->line.width/2) * lv_trigo_sin(angle + 90) >> LV_TRIGO_SHIFT); + + x2 = x + ((r - ext->ind.style->body.padding.inner - ext->ind.style->line.width/2) * lv_trigo_sin(angle) >> LV_TRIGO_SHIFT); + y2 = y + ((r - ext->ind.style->body.padding.inner - ext->ind.style->line.width/2) * lv_trigo_sin(angle + 90) >> LV_TRIGO_SHIFT); + + point1.x = x1; + point1.y = y1; + point2.x = x2; + point2.y = y2; + + //if(LV_MATH_ABS(point1.x - point2.x) > LV_MATH_ABS(point1.y - point2.y)) + //{ + /*rather horizontal*/ + if(point1.x < point2.x) { + line_area.x1 = point1.x; + //line_area.y1 = point1.y; + line_area.x2 = point2.x; + //line_area.y2 = point2.y; + } else { + line_area.x1 = point2.x; + //line_area.y1 = point2.y; + line_area.x2 = point1.x; + //line_area.y2 = point1.y; + } + //} else { + /*rather vertical*/ + if(point1.y < point2.y) { + //line_area.x1 = point1.x; + line_area.y1 = point1.y; + //line_area.x2 = point2.x; + line_area.y2 = point2.y; + } else { + //line_area.x1 = point2.x; + line_area.y1 = point2.y; + //line_area.x2 = point1.x; + line_area.y2 = point1.y; + } + //} + + line_area.x1 -= 2*ext->ind.style->line.width; + line_area.y1 -= 2*ext->ind.style->line.width; + line_area.x2 += 2*ext->ind.style->line.width; + line_area.y2 += 2*ext->ind.style->line.width; + + lv_inv_area(&line_area, NULL); + + break; + } + case LV_CPICKER_IND_CIRCLE: + { + lv_area_t circle_ind_area; + uint32_t cx, cy; + + uint16_t angle; + + switch(ext->wheel_mode) + { + default: + case LV_CPICKER_WHEEL_HUE: + angle = ext->hue; + break; + case LV_CPICKER_WHEEL_SAT: + angle = ext->saturation * 360 / 100; + break; + case LV_CPICKER_WHEEL_VAL: + angle = ext->value * 360 / 100; + break; + } + + cx = x + ((r - style->line.width/2) * lv_trigo_sin(angle) >> LV_TRIGO_SHIFT); + cy = y + ((r - style->line.width/2) * lv_trigo_sin(angle + 90) >> LV_TRIGO_SHIFT); + + circle_ind_area.x1 = cx - style->line.width/2; + circle_ind_area.y1 = cy - style->line.width/2; + circle_ind_area.x2 = cx + style->line.width/2; + circle_ind_area.y2 = cy + style->line.width/2; + + lv_inv_area(&circle_ind_area, NULL); + + + /* invalidate last position*/ + angle = ext->prev_pos; + + cx = x + ((r - style->line.width/2) * lv_trigo_sin(angle) >> LV_TRIGO_SHIFT); + cy = y + ((r - style->line.width/2) * lv_trigo_sin(angle + 90) >> LV_TRIGO_SHIFT); + + circle_ind_area.x1 = cx - style->line.width/2; + circle_ind_area.y1 = cy - style->line.width/2; + circle_ind_area.x2 = cx + style->line.width/2; + circle_ind_area.y2 = cy + style->line.width/2; + + lv_inv_area(&circle_ind_area, NULL); + break; + } + case LV_CPICKER_IND_IN: + { + lv_area_t circle_ind_area; + uint32_t cx, cy; + + uint16_t angle; + + switch(ext->wheel_mode) + { + default: + case LV_CPICKER_WHEEL_HUE: + angle = ext->hue; + break; + case LV_CPICKER_WHEEL_SAT: + angle = ext->saturation * 360 / 100; + break; + case LV_CPICKER_WHEEL_VAL: + angle = ext->value * 360 / 100; + break; + } + + uint16_t ind_radius = lv_sqrt((4*rin*rin)/2)/2 + 1 - style->body.padding.inner; + ind_radius = (ind_radius + rin) / 2; + + cx = x + ((ind_radius) * lv_trigo_sin(angle) >> LV_TRIGO_SHIFT); + cy = y + ((ind_radius) * lv_trigo_sin(angle + 90) >> LV_TRIGO_SHIFT); + + circle_ind_area.x1 = cx - ext->ind.style->line.width/2; + circle_ind_area.y1 = cy - ext->ind.style->line.width/2; + circle_ind_area.x2 = cx + ext->ind.style->line.width/2; + circle_ind_area.y2 = cy + ext->ind.style->line.width/2; + + lv_inv_area(&circle_ind_area, NULL); + + + /* invalidate last position*/ + angle = ext->prev_pos; + + cx = x + ((ind_radius) * lv_trigo_sin(angle) >> LV_TRIGO_SHIFT); + cy = y + ((ind_radius) * lv_trigo_sin(angle + 90) >> LV_TRIGO_SHIFT); + + circle_ind_area.x1 = cx - ext->ind.style->line.width/2; + circle_ind_area.y1 = cy - ext->ind.style->line.width/2; + circle_ind_area.x2 = cx + ext->ind.style->line.width/2; + circle_ind_area.y2 = cy + ext->ind.style->line.width/2; + + lv_inv_area(&circle_ind_area, NULL); + break; + } + } + } + else if(ext->type == LV_CPICKER_TYPE_RECT) + { + + } +} + + +#endif diff --git a/src/lv_objx/lv_cpicker.h b/src/lv_objx/lv_cpicker.h new file mode 100644 index 000000000..93587d48d --- /dev/null +++ b/src/lv_objx/lv_cpicker.h @@ -0,0 +1,233 @@ +/** + * @file lv_cpicker.h + * + */ + +#ifndef LV_CPICKER_H +#define LV_CPICKER_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ +#ifdef LV_CONF_INCLUDE_SIMPLE +#include "lv_conf.h" +#else +#include "../../../lv_conf.h" +#endif + +#if LV_USE_CPICKER != 0 + +#include "../lv_core/lv_obj.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ +/*Data of colorpicker*/ +typedef struct { + /*New data for this type */ + uint16_t hue; + uint8_t saturation; + uint8_t value; + struct + { + lv_style_t * style; + uint8_t type; + }ind; + //LVGLv5 lv_action_t value_changed; + uint16_t prev_hue; + uint16_t prev_saturation; + uint16_t prev_value; + uint16_t prev_pos; + uint8_t wheel_mode:2; + uint8_t wheel_fixed:1; + uint8_t type:1; + uint32_t last_clic; + lv_color_t ring_color; +} lv_cpicker_ext_t; + + +/*Styles*/ +enum { + LV_CPICKER_STYLE_MAIN, + LV_CPICKER_STYLE_IND, +}; +typedef uint8_t lv_cpicker_style_t; + +enum { + LV_CPICKER_IND_NONE, + LV_CPICKER_IND_LINE, + LV_CPICKER_IND_CIRCLE, + LV_CPICKER_IND_IN +}; +typedef uint8_t lv_cpicker_ind_type_t; + +enum { + LV_CPICKER_TYPE_RECT, + LV_CPICKER_TYPE_DISC, +}; +typedef uint8_t lv_cpicker_type_t; + +enum { + LV_CPICKER_WHEEL_HUE, + LV_CPICKER_WHEEL_SAT, + LV_CPICKER_WHEEL_VAL +}; +typedef uint8_t lv_cpicker_wheel_mode_t; + + + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/** + * Create a colorpicker objects + * @param par pointer to an object, it will be the parent of the new colorpicker + * @param copy pointer to a colorpicker object, if not NULL then the new object will be copied from it + * @return pointer to the created colorpicker + */ +lv_obj_t * lv_cpicker_create(lv_obj_t * par, const lv_obj_t * copy); + +/*====================== + * Add/remove functions + *=====================*/ + + +/*===================== + * Setter functions + *====================*/ + +/** + * Set a style of a colorpicker. + * @param cpicker pointer to colorpicker object + * @param type which style should be set + * @param style pointer to a style + */ +void lv_cpicker_set_style(lv_obj_t * cpicker, lv_cpicker_style_t type, lv_style_t *style); + +/** + * Set a type of a colorpicker indicator. + * @param cpicker pointer to colorpicker object + * @param type indicator type + */ +void lv_cpicker_set_ind_type(lv_obj_t * cpicker, lv_cpicker_ind_type_t type); + +/** + * Set the current hue of a colorpicker. + * @param cpicker pointer to colorpicker object + * @param hue current selected hue + */ +void lv_cpicker_set_hue(lv_obj_t * cpicker, uint16_t hue); + +/** + * Set the ring color of a colorpicker. + * @param cpicker pointer to colorpicker object + * @param ring_color new ring color + */ +void lv_cpicker_set_ring_color(lv_obj_t * cpicker, lv_color_t ring_color); + +/** + * Set the current saturation of a colorpicker. + * @param cpicker pointer to colorpicker object + * @param sat current selected saturation + */ +void lv_cpicker_set_saturation(lv_obj_t * cpicker, uint16_t sat); + +/** + * Set the current value of a colorpicker. + * @param cpicker pointer to colorpicker object + * @param val current selected value + */ +void lv_cpicker_set_value(lv_obj_t * cpicker, uint16_t val); + +/** + * Set the current color of a colorpicker. + * @param cpicker pointer to colorpicker object + * @param color current selected color + */ +void lv_cpicker_set_color(lv_obj_t * cpicker, lv_color_t color); + +/** + * Set the action callback on value change event. + * @param cpicker pointer to colorpicker object + * @param action callback function + */ +//LVGLv5 void lv_cpicker_set_action(lv_obj_t * cpicker, lv_action_t action); + +/** + * Set the current wheel mode. + * @param cpicker pointer to colorpicker object + * @param mode wheel mode (hue/sat/val) + */ +void lv_cpicker_set_wheel_mode(lv_obj_t * cpicker, lv_cpicker_wheel_mode_t mode); + +/** + * Set if the wheel mode is changed on long press on center + * @param cpicker pointer to colorpicker object + * @param fixed_mode mode cannot be changed if set + */ +void lv_cpicker_set_wheel_fixed(lv_obj_t * cpicker, bool fixed_mode); + +/*===================== + * Getter functions + *====================*/ + +/** + * Get style of a colorpicker. + * @param cpicker pointer to colorpicker object + * @param type which style should be get + * @return style pointer to the style + */ +lv_style_t * lv_cpicker_get_style(const lv_obj_t * cpicker, lv_cpicker_style_t type); + +/** + * Get the ring color of a colorpicker. + * @param cpicker pointer to colorpicker object + * @return current ring color + */ +lv_color_t lv_cpicker_get_ring_color(const lv_obj_t * cpicker); + +/** + * Get the current hue of a colorpicker. + * @param cpicker pointer to colorpicker object + * @return hue current selected hue + */ +uint16_t lv_cpicker_get_hue(lv_obj_t * cpicker); + +/** + * Get the current selected color of a colorpicker. + * @param cpicker pointer to colorpicker object + * @return color current selected color + */ +lv_color_t lv_cpicker_get_color(lv_obj_t * cpicker); + +/** + * Get the action callback called on value change event. + * @param cpicker pointer to colorpicker object + * @return action callback function + */ +//LVGLv5 lv_action_t lv_cpicker_get_action(lv_obj_t * cpicker); + +/*===================== + * Other functions + *====================*/ + +/********************** + * MACROS + **********************/ + +#endif /*USE_LV_CPICKER*/ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /*LV_CPICKER_H*/ diff --git a/src/lv_objx/lv_objx.mk b/src/lv_objx/lv_objx.mk index 45b3e2ad3..fde2ac77f 100644 --- a/src/lv_objx/lv_objx.mk +++ b/src/lv_objx/lv_objx.mk @@ -1,6 +1,7 @@ CSRCS += lv_arc.c CSRCS += lv_bar.c CSRCS += lv_cb.c +CSRCS += lv_cpicker.c CSRCS += lv_ddlist.c CSRCS += lv_kb.c CSRCS += lv_line.c From 12ee870e2c9f9de9a9da67709e576325a43aeb5f Mon Sep 17 00:00:00 2001 From: Paul Peavyhouse Date: Wed, 18 Sep 2019 15:14:23 -0700 Subject: [PATCH 02/82] Got the center button to draw, albeit seems like the wrong color --- src/lv_objx/lv_cpicker.c | 64 ++++++++++++++-------------------------- src/lv_objx/lv_cpicker.h | 10 +------ 2 files changed, 23 insertions(+), 51 deletions(-) diff --git a/src/lv_objx/lv_cpicker.c b/src/lv_objx/lv_cpicker.c index e9e817510..290bfde3b 100644 --- a/src/lv_objx/lv_cpicker.c +++ b/src/lv_objx/lv_cpicker.c @@ -3,24 +3,17 @@ * */ -/* TODO Remove these instructions - * Search an replace: color_picker -> object normal name with lower case (e.g. button, label etc.) - * cpicker -> object short name with lower case(e.g. btn, label etc) - * CPICKER -> object short name with upper case (e.g. BTN, LABEL etc.) - * - */ - /********************* * INCLUDES *********************/ #include "lv_cpicker.h" -#include "../lv_misc/lv_math.h" +#if LV_USE_CPICKER != 0 + #include "../lv_draw/lv_draw_arc.h" #include "../lv_themes/lv_theme.h" #include "../lv_core/lv_indev.h" #include "../lv_core/lv_refr.h" - -#if LV_USE_CPICKER != 0 +#include "../lv_misc/lv_math.h" /********************* * DEFINES @@ -82,8 +75,8 @@ static void lv_cpicker_invalidate_indicator(lv_obj_t * cpicker); /********************** * STATIC VARIABLES **********************/ -//LVGLv5 static lv_signal_func_t ancestor_signal; -//LVGLv5 static lv_design_func_t ancestor_design; +static lv_signal_cb_t ancestor_signal; +static lv_design_cb_t ancestor_design; /********************** * MACROS @@ -103,18 +96,19 @@ lv_obj_t * lv_cpicker_create(lv_obj_t * par, const lv_obj_t * copy) { LV_LOG_TRACE("color_picker create started"); - /*Create the ancestor of color_picker*/ - /*TODO modify it to the ancestor create function */ - lv_obj_t * new_cpicker = lv_obj_create(par, copy); + lv_obj_t * new_cpicker; + + new_cpicker = lv_obj_create(par, copy); lv_mem_assert(new_cpicker); if(new_cpicker == NULL) return NULL; - /*Allocate the colorpicker type specific extended data*/ + if(ancestor_signal == NULL) ancestor_signal = lv_obj_get_signal_cb(new_cpicker); + if(ancestor_design == NULL) ancestor_design = lv_obj_get_design_cb(new_cpicker); + + /*Allocate the extended data*/ lv_cpicker_ext_t * ext = lv_obj_allocate_ext_attr(new_cpicker, sizeof(lv_cpicker_ext_t)); lv_mem_assert(ext); if(ext == NULL) return NULL; - //LVGLv5 if(ancestor_signal == NULL) ancestor_signal = lv_obj_get_signal_func(new_cpicker); - //LVGLv5 if(ancestor_design == NULL) ancestor_design = lv_obj_get_design_func(new_cpicker); /*Initialize the allocated 'ext' */ ext->hue = LV_CPICKER_DEF_HUE; @@ -132,19 +126,18 @@ lv_obj_t * lv_cpicker_create(lv_obj_t * par, const lv_obj_t * copy) /*The signal and design functions are not copied so set them here*/ if(ext->type == LV_CPICKER_TYPE_DISC) { - //LVGLv5 lv_obj_set_signal_func(new_cpicker, lv_cpicker_disc_signal); - //LVGLv5 lv_obj_set_design_func(new_cpicker, lv_cpicker_disc_design); + lv_obj_set_signal_cb(new_cpicker, lv_cpicker_disc_signal); + lv_obj_set_design_cb(new_cpicker, lv_cpicker_disc_design); } else if(ext->type == LV_CPICKER_TYPE_RECT) { - //LVGLv5 lv_obj_set_signal_func(new_cpicker, lv_cpicker_rect_signal); - //LVGLv5 lv_obj_set_design_func(new_cpicker, lv_cpicker_rect_design); + lv_obj_set_signal_cb(new_cpicker, lv_cpicker_rect_signal); + lv_obj_set_design_cb(new_cpicker, lv_cpicker_rect_design); } - /*Init the new cpicker color_picker*/ + /*If no copy do the basic initialization*/ if(copy == NULL) { - /*Set the default styles*/ lv_theme_t * th = lv_theme_get_current(); if(th) { lv_cpicker_set_style(new_cpicker, LV_CPICKER_STYLE_MAIN, th->style.bg); @@ -152,8 +145,7 @@ lv_obj_t * lv_cpicker_create(lv_obj_t * par, const lv_obj_t * copy) lv_cpicker_set_style(new_cpicker, LV_CPICKER_STYLE_MAIN, &lv_style_plain); } } - - /*Copy an existing color_picker*/ + /*Copy 'copy'*/ else { lv_cpicker_ext_t * copy_ext = lv_obj_get_ext_attr(copy); @@ -161,20 +153,11 @@ lv_obj_t * lv_cpicker_create(lv_obj_t * par, const lv_obj_t * copy) lv_obj_refresh_style(new_cpicker); } - LV_LOG_INFO("colorpicker created"); + LV_LOG_INFO("color_picker created"); return new_cpicker; } -/*====================== - * Add/remove functions - *=====================*/ - -/* - * New object specific "add" or "remove" functions come here - */ - - /*===================== * Setter functions *====================*/ @@ -183,7 +166,6 @@ lv_obj_t * lv_cpicker_create(lv_obj_t * par, const lv_obj_t * copy) * New object specific "set" functions come here */ - /** * Set a style of a color_picker. * @param cpicker pointer to color_picker object @@ -641,7 +623,7 @@ static bool lv_cpicker_disc_design(lv_obj_t * cpicker, const lv_area_t * mask, l center_area.y1 = y - wradius; center_area.x2 = x + wradius; center_area.y2 = y + wradius; - styleCopy.body.grad_color = styleCopy.body.main_color; + styleCopy.body.grad_color = styleCopy.body.main_color; styleCopy.body.radius = LV_RADIUS_CIRCLE; lv_draw_rect(¢er_area, mask, &styleCopy, opa_scale); @@ -779,8 +761,7 @@ static bool lv_cpicker_disc_design(lv_obj_t * cpicker, const lv_area_t * mask, l lv_draw_rect(&circle_area, mask, ext->ind.style, opa_scale); break; } - } - + } // switch /* //code to color the drawn area @@ -791,7 +772,7 @@ static bool lv_cpicker_disc_design(lv_obj_t * cpicker, const lv_area_t * mask, l style2.body.grad_color.full = c; c += 0x123445678; lv_draw_rect(mask, mask, &style2, opa_scale); - */ + */ } /*Post draw when the children are drawn*/ else if(mode == LV_DESIGN_DRAW_POST) { @@ -838,7 +819,6 @@ static bool lv_cpicker_rect_design(lv_obj_t * cpicker, const lv_area_t * mask, l lv_coord_t y2 = cpicker->coords.y2; lv_opa_t opa_scale = lv_obj_get_opa_scale(cpicker); - /* prepare the color preview area */ uint16_t preview_offset = style->line.width; lv_area_t preview_area; diff --git a/src/lv_objx/lv_cpicker.h b/src/lv_objx/lv_cpicker.h index 93587d48d..d3d61f62a 100644 --- a/src/lv_objx/lv_cpicker.h +++ b/src/lv_objx/lv_cpicker.h @@ -53,7 +53,6 @@ typedef struct { lv_color_t ring_color; } lv_cpicker_ext_t; - /*Styles*/ enum { LV_CPICKER_STYLE_MAIN, @@ -82,8 +81,6 @@ enum { }; typedef uint8_t lv_cpicker_wheel_mode_t; - - /********************** * GLOBAL PROTOTYPES **********************/ @@ -96,11 +93,6 @@ typedef uint8_t lv_cpicker_wheel_mode_t; */ lv_obj_t * lv_cpicker_create(lv_obj_t * par, const lv_obj_t * copy); -/*====================== - * Add/remove functions - *=====================*/ - - /*===================== * Setter functions *====================*/ @@ -224,7 +216,7 @@ lv_color_t lv_cpicker_get_color(lv_obj_t * cpicker); * MACROS **********************/ -#endif /*USE_LV_CPICKER*/ +#endif /*LV_USE_CPICKER*/ #ifdef __cplusplus } /* extern "C" */ From b67f40ed39d3c4c97852fbaf32f2f692a4b3025d Mon Sep 17 00:00:00 2001 From: Paul Peavyhouse Date: Wed, 18 Sep 2019 17:22:16 -0700 Subject: [PATCH 03/82] Got the gradient to draw and background honor theme --- README.md | 4 ++-- src/lv_draw/lv_draw_triangle.c | 17 +---------------- src/lv_objx/lv_cpicker.c | 32 ++++++++++++++------------------ 3 files changed, 17 insertions(+), 36 deletions(-) diff --git a/README.md b/README.md index d07a5b680..837e77628 100644 --- a/README.md +++ b/README.md @@ -188,8 +188,8 @@ Styles can be assigned to the objects to changed their appearance. A style descr You can create a new style like this: ```c -static lv_style_t style1; /*Declare a new style. Should be `static`*/ -lv_style_copy(&style1, &lv_style_plain); /*Copy a buil-in style*/ +static lv_style_t style1; /*Declare a new style. Should be `static`*/ +lv_style_copy(&style1, &lv_style_plain); /*Copy a built-in style*/ style1.body.main_color = LV_COLOR_RED; /*Main color*/ style1.body.grad_color = lv_color_hex(0xffd83c) /*Gradient color (orange)*/ style1.body.radius = 3; diff --git a/src/lv_draw/lv_draw_triangle.c b/src/lv_draw/lv_draw_triangle.c index 0b9d6536b..1c8939ad7 100644 --- a/src/lv_draw/lv_draw_triangle.c +++ b/src/lv_draw/lv_draw_triangle.c @@ -45,8 +45,7 @@ static void point_swap(lv_point_t * p1, lv_point_t * p2); */ void lv_draw_triangle(const lv_point_t * points, const lv_area_t * mask, const lv_style_t * style, lv_opa_t opa_scale) { - - /*Return is the triangle is degenerated*/ + /*Return if the triangle is degenerated*/ if(points[0].x == points[1].x && points[0].y == points[1].y) return; if(points[1].x == points[2].x && points[1].y == points[2].y) return; if(points[0].x == points[2].x && points[0].y == points[2].y) return; @@ -136,21 +135,7 @@ void tri_draw_flat(const lv_point_t * points, const lv_area_t * mask, const lv_s if(tri[1].y < tri[0].y) point_swap(&tri[1], &tri[0]); if(tri[2].y < tri[1].y) point_swap(&tri[2], &tri[1]); if(tri[1].y < tri[0].y) point_swap(&tri[1], &tri[0]); -/* LVGLv5 - /*Return is the triangle is degenerated* / - if(tri[0].x == tri[1].x && tri[0].y == tri[1].y) return; - if(tri[1].x == tri[2].x && tri[1].y == tri[2].y) return; - if(tri[0].x == tri[2].x && tri[0].y == tri[2].y) return; - if(tri[0].x == tri[1].x && tri[1].x == tri[2].x) return; - if(tri[0].y == tri[1].y && tri[1].y == tri[2].y) return; - - /*Chech out of mask* / - if(tri[0].x < mask->x1 && tri[1].x < mask->x1 && tri[2].x < mask->x1) return; /*Out of the mask on the left* / - if(tri[0].x > mask->x2 && tri[1].x > mask->x2 && tri[2].x > mask->x2) return; /*Out of the mask on the right* / - if(tri[0].y < mask->y1 && tri[1].y < mask->y1 && tri[2].y < mask->y1) return; /*Out of the mask on the top* / - if(tri[0].y > mask->y2 && tri[1].y > mask->y2 && tri[2].y > mask->y2) return; /*Out of the mask on the bottom* / -*/ /*Draw the triangle*/ lv_point_t edge1; lv_coord_t dx1 = LV_MATH_ABS(tri[0].x - tri[1].x); diff --git a/src/lv_objx/lv_cpicker.c b/src/lv_objx/lv_cpicker.c index 290bfde3b..0af29b27b 100644 --- a/src/lv_objx/lv_cpicker.c +++ b/src/lv_objx/lv_cpicker.c @@ -400,6 +400,14 @@ static bool lv_cpicker_disc_design(lv_obj_t * cpicker, const lv_area_t * mask, l static lv_style_t styleCopy; lv_style_copy(&styleCopy, style); + static lv_style_t styleCenterBackground; + lv_theme_t * th = lv_theme_get_current(); + if (th) { + lv_style_copy(&styleCenterBackground, th->style.bg); + } else { + lv_style_copy(&styleCenterBackground, &lv_style_plain); + } + lv_coord_t r = (LV_MATH_MIN(lv_obj_get_width(cpicker), lv_obj_get_height(cpicker))) / 2; lv_coord_t x = cpicker->coords.x1 + lv_obj_get_width(cpicker) / 2; lv_coord_t y = cpicker->coords.y1 + lv_obj_get_height(cpicker) / 2; @@ -533,7 +541,7 @@ static bool lv_cpicker_disc_design(lv_obj_t * cpicker, const lv_area_t * mask, l { for(uint16_t i = start_angle; i <= end_angle; i+= LV_CPICKER_DEF_QF) { - styleCopy.line.color = lv_color_hsv_to_rgb(i%360, ext->saturation, ext->value); + styleCopy.body.main_color = lv_color_hsv_to_rgb(i%360, ext->saturation, ext->value); triangle_points[0].x = x; triangle_points[0].y = y; @@ -563,7 +571,7 @@ static bool lv_cpicker_disc_design(lv_obj_t * cpicker, const lv_area_t * mask, l { for(uint16_t i = start_angle; i <= end_angle; i += LV_CPICKER_DEF_QF) { - styleCopy.line.color = lv_color_hsv_to_rgb(ext->hue, (i%360)*100/360, ext->value); + styleCopy.body.main_color = lv_color_hsv_to_rgb(ext->hue, (i%360)*100/360, ext->value); triangle_points[0].x = x; triangle_points[0].y = y; @@ -590,7 +598,7 @@ static bool lv_cpicker_disc_design(lv_obj_t * cpicker, const lv_area_t * mask, l { for(uint16_t i = start_angle; i <= end_angle; i += LV_CPICKER_DEF_QF) { - styleCopy.line.color = lv_color_hsv_to_rgb(ext->hue, ext->saturation, (i%360)*100/360); + styleCopy.body.main_color = lv_color_hsv_to_rgb(ext->hue, ext->saturation, (i%360)*100/360); triangle_points[0].x = x; triangle_points[0].y = y; @@ -623,9 +631,8 @@ static bool lv_cpicker_disc_design(lv_obj_t * cpicker, const lv_area_t * mask, l center_area.y1 = y - wradius; center_area.x2 = x + wradius; center_area.y2 = y + wradius; - styleCopy.body.grad_color = styleCopy.body.main_color; - styleCopy.body.radius = LV_RADIUS_CIRCLE; - lv_draw_rect(¢er_area, mask, &styleCopy, opa_scale); + styleCenterBackground.body.radius = LV_RADIUS_CIRCLE; + lv_draw_rect(¢er_area, mask, &styleCenterBackground, opa_scale); //draw the center color indicator styleCopy.body.main_color = lv_color_hsv_to_rgb(ext->hue, ext->saturation, ext->value); @@ -1002,11 +1009,10 @@ static bool lv_cpicker_rect_design(lv_obj_t * cpicker, const lv_area_t * mask, l lv_draw_rect(&preview_area, mask, &styleCopy, opa_scale); /* - styleCopy.line.color = styleCopy.body.main_color; styleCopy.line.width = 10; lv_draw_arc(cpicker->coords.x1 + 3*gradient_h/2, cpicker->coords.y1 + gradient_h/2, gradient_h / 2 + styleCopy.line.width + 2, mask, 180, 360, &styleCopy, opa_scale); //lv_draw_arc(cpicker->coords.x1 + gradient_w - gradient_h/2, cpicker->coords.y1 + gradient_h/2, gradient_h / 2 + styleCopy.line.width + 2, mask, 0, 180, &styleCopy, opa_scale); - */ + */ /*draw the color position indicator*/ lv_coord_t ind_pos = style->line.rounded ? gradient_h / 2 : 0; @@ -1113,8 +1119,6 @@ static lv_res_t lv_cpicker_disc_signal(lv_obj_t * cpicker, lv_signal_t sign, voi lv_coord_t x = cpicker->coords.x1 + lv_obj_get_width(cpicker) / 2; lv_coord_t y = cpicker->coords.y1 + lv_obj_get_height(cpicker) / 2; - - if(sign == LV_SIGNAL_CLEANUP) { /*Nothing to cleanup. (No dynamically allocated memory in 'ext')*/ } else if(sign == LV_SIGNAL_GET_TYPE) { @@ -1191,9 +1195,7 @@ static lv_res_t lv_cpicker_disc_signal(lv_obj_t * cpicker, lv_signal_t sign, voi ext->prev_value = ext->value; break; } - lv_cpicker_invalidate_indicator(cpicker); - } } else if(sign == LV_SIGNAL_PRESS_LOST) @@ -1386,8 +1388,6 @@ static lv_res_t lv_cpicker_rect_signal(lv_obj_t * cpicker, lv_signal_t sign, voi lv_coord_t x = cpicker->coords.x1 + lv_obj_get_width(cpicker) / 2; lv_coord_t y = cpicker->coords.y1 + lv_obj_get_height(cpicker) / 2; - - if(sign == LV_SIGNAL_CLEANUP) { /*Nothing to cleanup. (No dynamically allocated memory in 'ext')*/ } else if(sign == LV_SIGNAL_GET_TYPE) { @@ -1728,7 +1728,6 @@ static void lv_cpicker_invalidate_indicator(lv_obj_t * cpicker) lv_inv_area(&line_area, NULL); - angle = ext->prev_pos; x1 = x + ((r - style->line.width + ext->ind.style->body.padding.inner + ext->ind.style->line.width/2) * lv_trigo_sin(angle) >> LV_TRIGO_SHIFT); @@ -1811,7 +1810,6 @@ static void lv_cpicker_invalidate_indicator(lv_obj_t * cpicker) lv_inv_area(&circle_ind_area, NULL); - /* invalidate last position*/ angle = ext->prev_pos; @@ -1860,7 +1858,6 @@ static void lv_cpicker_invalidate_indicator(lv_obj_t * cpicker) lv_inv_area(&circle_ind_area, NULL); - /* invalidate last position*/ angle = ext->prev_pos; @@ -1883,5 +1880,4 @@ static void lv_cpicker_invalidate_indicator(lv_obj_t * cpicker) } } - #endif From fc1b5c682de37f21c02858b385181cde057f5fa0 Mon Sep 17 00:00:00 2001 From: Paul Peavyhouse Date: Wed, 18 Sep 2019 21:23:56 -0700 Subject: [PATCH 04/82] Mostly working except for [I think] invalidation; refactoring a bit --- src/lv_objx/lv_cpicker.c | 618 ++++++++++++++++++++------------------- src/lv_objx/lv_cpicker.h | 111 ++++--- 2 files changed, 365 insertions(+), 364 deletions(-) diff --git a/src/lv_objx/lv_cpicker.c b/src/lv_objx/lv_cpicker.c index 0af29b27b..b33ff4295 100644 --- a/src/lv_objx/lv_cpicker.c +++ b/src/lv_objx/lv_cpicker.c @@ -26,16 +26,16 @@ #define LV_CPICKER_DEF_HUE 0 #endif -#ifndef LV_CPICKER_DEF_SAT -#define LV_CPICKER_DEF_SAT 100 +#ifndef LV_CPICKER_DEF_SATURATION +#define LV_CPICKER_DEF_SATURATION 100 #endif -#ifndef LV_CPICKER_DEF_VAL -#define LV_CPICKER_DEF_VAL 100 +#ifndef LV_CPICKER_DEF_VALUE +#define LV_CPICKER_DEF_VALUE 100 #endif -#ifndef LV_CPICKER_DEF_IND_TYPE -#define LV_CPICKER_DEF_IND_TYPE LV_CPICKER_IND_CIRCLE +#ifndef LV_CPICKER_DEF_INDICATOR_TYPE +#define LV_CPICKER_DEF_INDICATOR_TYPE LV_CPICKER_INDICATOR_CIRCLE #endif #ifndef LV_CPICKER_DEF_QF /*quantization factor*/ @@ -96,9 +96,7 @@ lv_obj_t * lv_cpicker_create(lv_obj_t * par, const lv_obj_t * copy) { LV_LOG_TRACE("color_picker create started"); - lv_obj_t * new_cpicker; - - new_cpicker = lv_obj_create(par, copy); + lv_obj_t * new_cpicker = lv_obj_create(par, copy); lv_mem_assert(new_cpicker); if(new_cpicker == NULL) return NULL; @@ -113,14 +111,13 @@ lv_obj_t * lv_cpicker_create(lv_obj_t * par, const lv_obj_t * copy) /*Initialize the allocated 'ext' */ ext->hue = LV_CPICKER_DEF_HUE; ext->prev_hue = ext->hue; - ext->saturation = LV_CPICKER_DEF_SAT; - ext->value = LV_CPICKER_DEF_VAL; - ext->ind.style = &lv_style_plain; - ext->ind.type = LV_CPICKER_DEF_IND_TYPE; - //LVGLv5 ext->value_changed = NULL; - ext->wheel_mode = LV_CPICKER_WHEEL_HUE; - ext->wheel_fixed = 0; - ext->last_clic = 0; + ext->saturation = LV_CPICKER_DEF_SATURATION; + ext->value = LV_CPICKER_DEF_VALUE; + ext->indicator.style = &lv_style_plain; + ext->indicator.type = LV_CPICKER_DEF_INDICATOR_TYPE; + ext->color_mode = LV_CPICKER_COLOR_MODE_HUE; + ext->color_mode_fixed = 0; + ext->last_click = 0; ext->type = LV_CPICKER_DEF_TYPE; /*The signal and design functions are not copied so set them here*/ @@ -137,7 +134,6 @@ lv_obj_t * lv_cpicker_create(lv_obj_t * par, const lv_obj_t * copy) /*If no copy do the basic initialization*/ if(copy == NULL) { - lv_theme_t * th = lv_theme_get_current(); if(th) { lv_cpicker_set_style(new_cpicker, LV_CPICKER_STYLE_MAIN, th->style.bg); @@ -162,13 +158,9 @@ lv_obj_t * lv_cpicker_create(lv_obj_t * par, const lv_obj_t * copy) * Setter functions *====================*/ -/* - * New object specific "set" functions come here - */ - /** - * Set a style of a color_picker. - * @param cpicker pointer to color_picker object + * Set a style of a colorpicker. + * @param cpicker pointer to colorpicker object * @param type which style should be set * @param style pointer to a style */ @@ -180,8 +172,8 @@ void lv_cpicker_set_style(lv_obj_t * cpicker, lv_cpicker_style_t type, lv_style_ case LV_CPICKER_STYLE_MAIN: lv_obj_set_style(cpicker, style); break; - case LV_CPICKER_STYLE_IND: - ext->ind.style = style; + case LV_CPICKER_STYLE_INDICATOR: + ext->indicator.style = style; lv_obj_invalidate(cpicker); break; } @@ -192,10 +184,10 @@ void lv_cpicker_set_style(lv_obj_t * cpicker, lv_cpicker_style_t type, lv_style_ * @param cpicker pointer to colorpicker object * @param type indicator type */ -void lv_cpicker_set_ind_type(lv_obj_t * cpicker, lv_cpicker_ind_type_t type) +void lv_cpicker_set_indicator_type(lv_obj_t * cpicker, lv_cpicker_indicator_type_t type) { lv_cpicker_ext_t * ext = lv_obj_get_ext_attr(cpicker); - ext->ind.type = type; + ext->indicator.type = type; lv_obj_invalidate(cpicker); } @@ -216,13 +208,13 @@ void lv_cpicker_set_hue(lv_obj_t * cpicker, uint16_t hue) /** * Set the current saturation of a colorpicker. * @param cpicker pointer to colorpicker object - * @param sat current selected saturation [0..100] + * @param saturation current selected saturation [0..100] */ -void lv_cpicker_set_saturation(lv_obj_t * cpicker, uint16_t sat) +void lv_cpicker_set_saturation(lv_obj_t * cpicker, uint8_t saturation) { lv_cpicker_ext_t * ext = lv_obj_get_ext_attr(cpicker); - ext->saturation = sat % 100; + ext->saturation = saturation % 100; lv_obj_invalidate(cpicker); } @@ -232,7 +224,7 @@ void lv_cpicker_set_saturation(lv_obj_t * cpicker, uint16_t sat) * @param cpicker pointer to colorpicker object * @param val current selected value [0..100] */ -void lv_cpicker_set_value(lv_obj_t * cpicker, uint16_t val) +void lv_cpicker_set_value(lv_obj_t * cpicker, uint8_t val) { lv_cpicker_ext_t * ext = lv_obj_get_ext_attr(cpicker); @@ -257,50 +249,56 @@ void lv_cpicker_set_color(lv_obj_t * cpicker, lv_color_t color) } /** - * Set the action callback on value change event. + * Set the current color mode. * @param cpicker pointer to colorpicker object - * @param action callback function + * @param mode color mode (hue/sat/val) */ -/* LVGLv5 -void lv_cpicker_set_action(lv_obj_t * cpicker, lv_action_t action) +void lv_cpicker_set_color_mode(lv_obj_t * cpicker, lv_cpicker_color_mode_t mode) { lv_cpicker_ext_t * ext = lv_obj_get_ext_attr(cpicker); - ext->value_changed = action; -} -*/ - -/** - * Set the current wheel mode. - * @param cpicker pointer to colorpicker object - * @param mode wheel mode (hue/sat/val) - */ -void lv_cpicker_set_wheel_mode(lv_obj_t * cpicker, lv_cpicker_wheel_mode_t mode) -{ - lv_cpicker_ext_t * ext = lv_obj_get_ext_attr(cpicker); - - ext->wheel_mode = mode; + ext->color_mode = mode; } /** - * Set if the wheel mode is changed on long press on center + * Set if the color mode is changed on long press on center * @param cpicker pointer to colorpicker object - * @param fixed_mode mode cannot be changed if set + * @param fixed color mode cannot be changed on long press */ -void lv_cpicker_set_wheel_fixed(lv_obj_t * cpicker, bool fixed_mode) +void lv_cpicker_set_color_mode_fixed(lv_obj_t * cpicker, bool fixed) { lv_cpicker_ext_t * ext = lv_obj_get_ext_attr(cpicker); - ext->wheel_fixed = fixed_mode; + ext->color_mode_fixed = fixed; } /*===================== * Getter functions *====================*/ -/* - * New object specific "get" functions come here +/** + * Get the current color mode. + * @param cpicker pointer to colorpicker object + * @return color mode (hue/sat/val) */ +lv_cpicker_color_mode_t lv_cpicker_get_color_mode(lv_obj_t * cpicker) +{ + lv_cpicker_ext_t * ext = lv_obj_get_ext_attr(cpicker); + + return ext->color_mode; +} + +/** + * Get if the color mode is changed on long press on center + * @param cpicker pointer to colorpicker object + * @return mode cannot be changed on long press + */ +bool lv_cpicker_get_color_mode_fixed(lv_obj_t * cpicker) +{ + lv_cpicker_ext_t * ext = lv_obj_get_ext_attr(cpicker); + + return ext->color_mode_fixed; +} /** * Get style of a color_picker. @@ -315,8 +313,8 @@ lv_style_t * lv_cpicker_get_style(const lv_obj_t * cpicker, lv_cpicker_style_t t switch(type) { case LV_CPICKER_STYLE_MAIN: return lv_obj_get_style(cpicker); - case LV_CPICKER_STYLE_IND: - return ext->ind.style; + case LV_CPICKER_STYLE_INDICATOR: + return ext->indicator.style; default: return NULL; } @@ -337,6 +335,30 @@ uint16_t lv_cpicker_get_hue(lv_obj_t * cpicker) return ext->hue; } +/** + * Get the current saturation of a colorpicker. + * @param cpicker pointer to colorpicker object + * @return current selected saturation + */ +uint8_t lv_cpicker_get_saturation(lv_obj_t * cpicker) +{ + lv_cpicker_ext_t * ext = lv_obj_get_ext_attr(cpicker); + + return ext->saturation; +} + +/** + * Get the current hue of a colorpicker. + * @param cpicker pointer to colorpicker object + * @return current selected value + */ +uint8_t lv_cpicker_get_value(lv_obj_t * cpicker) +{ + lv_cpicker_ext_t * ext = lv_obj_get_ext_attr(cpicker); + + return ext->value; +} + /** * Get the current selected color of a colorpicker. * @param cpicker pointer to colorpicker object @@ -349,20 +371,6 @@ lv_color_t lv_cpicker_get_color(lv_obj_t * cpicker) return lv_color_hsv_to_rgb(ext->hue, ext->saturation, ext->value); } -/** - * Get the action callback called on value change event. - * @param cpicker pointer to colorpicker object - * @return action callback function - */ -/* LVGLv5 -lv_action_t lv_cpicker_get_action(lv_obj_t * cpicker) -{ - lv_cpicker_ext_t * ext = lv_obj_get_ext_attr(cpicker); - - return ext->value_changed; -} -*/ - /*===================== * Other functions *====================*/ @@ -537,7 +545,7 @@ static bool lv_cpicker_disc_design(lv_obj_t * cpicker, const lv_area_t * mask, l end_angle += LV_CPICKER_DEF_QF; } - if(ext->wheel_mode == LV_CPICKER_WHEEL_HUE) + if(ext->color_mode == LV_CPICKER_COLOR_MODE_HUE) { for(uint16_t i = start_angle; i <= end_angle; i+= LV_CPICKER_DEF_QF) { @@ -567,7 +575,7 @@ static bool lv_cpicker_disc_design(lv_obj_t * cpicker, const lv_area_t * mask, l lv_draw_triangle(triangle_points, mask, &styleCopy, LV_OPA_COVER); } } - else if(ext->wheel_mode == LV_CPICKER_WHEEL_SAT) + else if(ext->color_mode == LV_CPICKER_COLOR_MODE_SATURATION) { for(uint16_t i = start_angle; i <= end_angle; i += LV_CPICKER_DEF_QF) { @@ -594,7 +602,7 @@ static bool lv_cpicker_disc_design(lv_obj_t * cpicker, const lv_area_t * mask, l lv_draw_triangle(triangle_points, mask, &styleCopy, LV_OPA_COVER); } } - else if(ext->wheel_mode == LV_CPICKER_WHEEL_VAL) + else if(ext->color_mode == LV_CPICKER_COLOR_MODE_VALUE) { for(uint16_t i = start_angle; i <= end_angle; i += LV_CPICKER_DEF_QF) { @@ -641,27 +649,27 @@ static bool lv_cpicker_disc_design(lv_obj_t * cpicker, const lv_area_t * mask, l lv_draw_rect(¢er_ind_area, mask, &styleCopy, opa_scale); //Draw the current hue indicator - switch(ext->ind.type) + switch(ext->indicator.type) { - case LV_CPICKER_IND_NONE: + case LV_CPICKER_INDICATOR_NONE: break; - case LV_CPICKER_IND_LINE: + case LV_CPICKER_INDICATOR_LINE: { lv_point_t start; lv_point_t end; uint16_t angle; - switch(ext->wheel_mode) + switch(ext->color_mode) { default: - case LV_CPICKER_WHEEL_HUE: + case LV_CPICKER_COLOR_MODE_HUE: angle = ext->hue; break; - case LV_CPICKER_WHEEL_SAT: + case LV_CPICKER_COLOR_MODE_SATURATION: angle = ext->saturation * 360 / 100; break; - case LV_CPICKER_WHEEL_VAL: + case LV_CPICKER_COLOR_MODE_VALUE: angle = ext->value * 360 / 100; break; } @@ -669,47 +677,47 @@ static bool lv_cpicker_disc_design(lv_obj_t * cpicker, const lv_area_t * mask, l /*save the angle to refresh the area later*/ ext->prev_pos = angle; - start.x = x + ((r - style->line.width + ext->ind.style->body.padding.inner + ext->ind.style->line.width/2) * lv_trigo_sin(angle) >> LV_TRIGO_SHIFT); - start.y = y + ((r - style->line.width + ext->ind.style->body.padding.inner + ext->ind.style->line.width/2) * lv_trigo_sin(angle + 90) >> LV_TRIGO_SHIFT); + start.x = x + ((r - style->line.width + ext->indicator.style->body.padding.inner + ext->indicator.style->line.width/2) * lv_trigo_sin(angle) >> LV_TRIGO_SHIFT); + start.y = y + ((r - style->line.width + ext->indicator.style->body.padding.inner + ext->indicator.style->line.width/2) * lv_trigo_sin(angle + 90) >> LV_TRIGO_SHIFT); - end.x = x + ((r - ext->ind.style->body.padding.inner - ext->ind.style->line.width/2) * lv_trigo_sin(angle) >> LV_TRIGO_SHIFT); - end.y = y + ((r - ext->ind.style->body.padding.inner - ext->ind.style->line.width/2) * lv_trigo_sin(angle + 90) >> LV_TRIGO_SHIFT); + end.x = x + ((r - ext->indicator.style->body.padding.inner - ext->indicator.style->line.width/2) * lv_trigo_sin(angle) >> LV_TRIGO_SHIFT); + end.y = y + ((r - ext->indicator.style->body.padding.inner - ext->indicator.style->line.width/2) * lv_trigo_sin(angle + 90) >> LV_TRIGO_SHIFT); - lv_draw_line(&start, &end, mask, ext->ind.style, opa_scale); - if(ext->ind.style->line.rounded) + lv_draw_line(&start, &end, mask, ext->indicator.style, opa_scale); + if(ext->indicator.style->line.rounded) { lv_area_t circle_area; - circle_area.x1 = start.x - ((ext->ind.style->line.width - 1) >> 1) - ((ext->ind.style->line.width - 1) & 0x1); - circle_area.y1 = start.y - ((ext->ind.style->line.width - 1) >> 1) - ((ext->ind.style->line.width - 1) & 0x1); - circle_area.x2 = start.x + ((ext->ind.style->line.width - 1) >> 1); - circle_area.y2 = start.y + ((ext->ind.style->line.width - 1) >> 1); - lv_draw_rect(&circle_area, mask, ext->ind.style, opa_scale); + circle_area.x1 = start.x - ((ext->indicator.style->line.width - 1) >> 1) - ((ext->indicator.style->line.width - 1) & 0x1); + circle_area.y1 = start.y - ((ext->indicator.style->line.width - 1) >> 1) - ((ext->indicator.style->line.width - 1) & 0x1); + circle_area.x2 = start.x + ((ext->indicator.style->line.width - 1) >> 1); + circle_area.y2 = start.y + ((ext->indicator.style->line.width - 1) >> 1); + lv_draw_rect(&circle_area, mask, ext->indicator.style, opa_scale); - circle_area.x1 = end.x - ((ext->ind.style->line.width - 1) >> 1) - ((ext->ind.style->line.width - 1) & 0x1); - circle_area.y1 = end.y - ((ext->ind.style->line.width - 1) >> 1) - ((ext->ind.style->line.width - 1) & 0x1); - circle_area.x2 = end.x + ((ext->ind.style->line.width - 1) >> 1); - circle_area.y2 = end.y + ((ext->ind.style->line.width - 1) >> 1); - lv_draw_rect(&circle_area, mask, ext->ind.style, opa_scale); + circle_area.x1 = end.x - ((ext->indicator.style->line.width - 1) >> 1) - ((ext->indicator.style->line.width - 1) & 0x1); + circle_area.y1 = end.y - ((ext->indicator.style->line.width - 1) >> 1) - ((ext->indicator.style->line.width - 1) & 0x1); + circle_area.x2 = end.x + ((ext->indicator.style->line.width - 1) >> 1); + circle_area.y2 = end.y + ((ext->indicator.style->line.width - 1) >> 1); + lv_draw_rect(&circle_area, mask, ext->indicator.style, opa_scale); } break; } - case LV_CPICKER_IND_CIRCLE: + case LV_CPICKER_INDICATOR_CIRCLE: { lv_area_t circle_area; uint32_t cx, cy; uint16_t angle; - switch(ext->wheel_mode) + switch(ext->color_mode) { default: - case LV_CPICKER_WHEEL_HUE: + case LV_CPICKER_COLOR_MODE_HUE: angle = ext->hue; break; - case LV_CPICKER_WHEEL_SAT: + case LV_CPICKER_COLOR_MODE_SATURATION: angle = ext->saturation * 360 / 100; break; - case LV_CPICKER_WHEEL_VAL: + case LV_CPICKER_COLOR_MODE_VALUE: angle = ext->value * 360 / 100; break; } @@ -725,27 +733,27 @@ static bool lv_cpicker_disc_design(lv_obj_t * cpicker, const lv_area_t * mask, l circle_area.x2 = cx + style->line.width/2; circle_area.y2 = cy + style->line.width/2; - ext->ind.style->body.radius = LV_RADIUS_CIRCLE; - lv_draw_rect(&circle_area, mask, ext->ind.style, opa_scale); + ext->indicator.style->body.radius = LV_RADIUS_CIRCLE; + lv_draw_rect(&circle_area, mask, ext->indicator.style, opa_scale); break; } - case LV_CPICKER_IND_IN: + case LV_CPICKER_INDICATOR_IN: { lv_area_t circle_area; uint32_t cx, cy; uint16_t angle; - switch(ext->wheel_mode) + switch(ext->color_mode) { default: - case LV_CPICKER_WHEEL_HUE: + case LV_CPICKER_COLOR_MODE_HUE: angle = ext->hue; break; - case LV_CPICKER_WHEEL_SAT: + case LV_CPICKER_COLOR_MODE_SATURATION: angle = ext->saturation * 360 / 100; break; - case LV_CPICKER_WHEEL_VAL: + case LV_CPICKER_COLOR_MODE_VALUE: angle = ext->value * 360 / 100; break; } @@ -759,13 +767,13 @@ static bool lv_cpicker_disc_design(lv_obj_t * cpicker, const lv_area_t * mask, l cx = x + ((ind_radius) * lv_trigo_sin(angle) >> LV_TRIGO_SHIFT); cy = y + ((ind_radius) * lv_trigo_sin(angle + 90) >> LV_TRIGO_SHIFT); - circle_area.x1 = cx - ext->ind.style->line.width/2; - circle_area.y1 = cy - ext->ind.style->line.width/2; - circle_area.x2 = cx + ext->ind.style->line.width/2; - circle_area.y2 = cy + ext->ind.style->line.width/2; + circle_area.x1 = cx - ext->indicator.style->line.width/2; + circle_area.y1 = cy - ext->indicator.style->line.width/2; + circle_area.x2 = cx + ext->indicator.style->line.width/2; + circle_area.y2 = cy + ext->indicator.style->line.width/2; - ext->ind.style->body.radius = LV_RADIUS_CIRCLE; - lv_draw_rect(&circle_area, mask, ext->ind.style, opa_scale); + ext->indicator.style->body.radius = LV_RADIUS_CIRCLE; + lv_draw_rect(&circle_area, mask, ext->indicator.style, opa_scale); break; } } // switch @@ -914,16 +922,16 @@ static bool lv_cpicker_rect_design(lv_obj_t * cpicker, const lv_area_t * mask, l gradient_area.x2 -= gradient_h/2; gradient_w -= gradient_h; - switch(ext->wheel_mode) + switch(ext->color_mode) { default: - case LV_CPICKER_WHEEL_HUE: + case LV_CPICKER_COLOR_MODE_HUE: styleCopy.body.main_color = lv_color_hsv_to_rgb(0, ext->saturation, ext->value); break; - case LV_CPICKER_WHEEL_SAT: + case LV_CPICKER_COLOR_MODE_SATURATION: styleCopy.body.main_color = lv_color_hsv_to_rgb(ext->hue, 0, ext->value); break; - case LV_CPICKER_WHEEL_VAL: + case LV_CPICKER_COLOR_MODE_VALUE: styleCopy.body.main_color = lv_color_hsv_to_rgb(ext->hue, ext->saturation, 0); break; } @@ -936,16 +944,16 @@ static bool lv_cpicker_rect_design(lv_obj_t * cpicker, const lv_area_t * mask, l rounded_edge_area.x1 += gradient_w - 1; rounded_edge_area.x2 += gradient_w - 1; - switch(ext->wheel_mode) + switch(ext->color_mode) { default: - case LV_CPICKER_WHEEL_HUE: + case LV_CPICKER_COLOR_MODE_HUE: styleCopy.body.main_color = lv_color_hsv_to_rgb(360, ext->saturation, ext->value); break; - case LV_CPICKER_WHEEL_SAT: + case LV_CPICKER_COLOR_MODE_SATURATION: styleCopy.body.main_color = lv_color_hsv_to_rgb(ext->hue, 100, ext->value); break; - case LV_CPICKER_WHEEL_VAL: + case LV_CPICKER_COLOR_MODE_VALUE: styleCopy.body.main_color = lv_color_hsv_to_rgb(ext->hue, ext->saturation, 100); break; } @@ -956,16 +964,16 @@ static bool lv_cpicker_rect_design(lv_obj_t * cpicker, const lv_area_t * mask, l for(uint16_t i = 0; i < 360; i += LV_MATH_MAX(LV_CPICKER_DEF_QF, 360/gradient_w)) { - switch(ext->wheel_mode) + switch(ext->color_mode) { default: - case LV_CPICKER_WHEEL_HUE: + case LV_CPICKER_COLOR_MODE_HUE: styleCopy.body.main_color = lv_color_hsv_to_rgb(i%360, ext->saturation, ext->value); break; - case LV_CPICKER_WHEEL_SAT: + case LV_CPICKER_COLOR_MODE_SATURATION: styleCopy.body.main_color = lv_color_hsv_to_rgb(ext->hue, (i%360)*100/360, ext->value); break; - case LV_CPICKER_WHEEL_VAL: + case LV_CPICKER_COLOR_MODE_VALUE: styleCopy.body.main_color = lv_color_hsv_to_rgb(ext->hue, ext->saturation, (i%360)*100/360); break; } @@ -1016,26 +1024,26 @@ static bool lv_cpicker_rect_design(lv_obj_t * cpicker, const lv_area_t * mask, l /*draw the color position indicator*/ lv_coord_t ind_pos = style->line.rounded ? gradient_h / 2 : 0; - switch(ext->wheel_mode) + switch(ext->color_mode) { default: - case LV_CPICKER_WHEEL_HUE: + case LV_CPICKER_COLOR_MODE_HUE: ind_pos += ext->hue * gradient_w /360; break; - case LV_CPICKER_WHEEL_SAT: + case LV_CPICKER_COLOR_MODE_SATURATION: ind_pos += ext->saturation * gradient_w / 100 ; break; - case LV_CPICKER_WHEEL_VAL: + case LV_CPICKER_COLOR_MODE_VALUE: ind_pos += ext->value * gradient_w / 100; break; } - switch(ext->ind.type) + switch(ext->indicator.type) { - case LV_CPICKER_IND_NONE: + case LV_CPICKER_INDICATOR_NONE: /*no indicator*/ break; - case LV_CPICKER_IND_LINE: + case LV_CPICKER_INDICATOR_LINE: { lv_point_t p1, p2; p1.x = gradient_area.x1 + ind_pos; @@ -1043,10 +1051,10 @@ static bool lv_cpicker_rect_design(lv_obj_t * cpicker, const lv_area_t * mask, l p1.y = gradient_area.y1; p2.y = gradient_area.y2; - lv_draw_line(&p1, &p2, &gradient_area, ext->ind.style, opa_scale); + lv_draw_line(&p1, &p2, &gradient_area, ext->indicator.style, opa_scale); break; } - case LV_CPICKER_IND_CIRCLE: + case LV_CPICKER_INDICATOR_CIRCLE: { lv_area_t circle_ind_area; circle_ind_area.x1 = gradient_area.x1 + ind_pos - gradient_h/2; @@ -1054,13 +1062,13 @@ static bool lv_cpicker_rect_design(lv_obj_t * cpicker, const lv_area_t * mask, l circle_ind_area.y1 = gradient_area.y1; circle_ind_area.y2 = gradient_area.y2; - lv_style_copy(&styleCopy, ext->ind.style); + lv_style_copy(&styleCopy, ext->indicator.style); styleCopy.body.radius = LV_RADIUS_CIRCLE; lv_draw_rect(&circle_ind_area, mask, &styleCopy, opa_scale); break; } - case LV_CPICKER_IND_IN: + case LV_CPICKER_INDICATOR_IN: { /*draw triangle under the gradient*/ lv_point_t triangle_points[3]; @@ -1068,18 +1076,18 @@ static bool lv_cpicker_rect_design(lv_obj_t * cpicker, const lv_area_t * mask, l triangle_points[0].x = ind_pos + gradient_area.x1; triangle_points[0].y = gradient_area.y2 - (gradient_h/3); - triangle_points[1].x = triangle_points[0].x - ext->ind.style->line.width / 3; + triangle_points[1].x = triangle_points[0].x - ext->indicator.style->line.width / 3; triangle_points[1].y = gradient_area.y2; - triangle_points[2].x = triangle_points[0].x + ext->ind.style->line.width / 3; + triangle_points[2].x = triangle_points[0].x + ext->indicator.style->line.width / 3; triangle_points[2].y = gradient_area.y2; - lv_draw_triangle(triangle_points, &gradient_area, ext->ind.style, LV_OPA_COVER); + lv_draw_triangle(triangle_points, &gradient_area, ext->indicator.style, LV_OPA_COVER); triangle_points[0].y = gradient_area.y1 + (gradient_h/3); triangle_points[1].y = gradient_area.y1 - 1; triangle_points[2].y = gradient_area.y1 - 1; - lv_draw_triangle(triangle_points, &gradient_area, ext->ind.style, LV_OPA_COVER); + lv_draw_triangle(triangle_points, &gradient_area, ext->indicator.style, LV_OPA_COVER); break; } default: @@ -1131,15 +1139,15 @@ static lv_res_t lv_cpicker_disc_signal(lv_obj_t * cpicker, lv_signal_t sign, voi } else if(sign == LV_SIGNAL_PRESSED) { - switch(ext->wheel_mode) + switch(ext->color_mode) { - case LV_CPICKER_WHEEL_HUE: + case LV_CPICKER_COLOR_MODE_HUE: ext->prev_hue = ext->hue; break; - case LV_CPICKER_WHEEL_SAT: + case LV_CPICKER_COLOR_MODE_SATURATION: ext->prev_saturation = ext->saturation; break; - case LV_CPICKER_WHEEL_VAL: + case LV_CPICKER_COLOR_MODE_VALUE: ext->prev_value = ext->value; break; } @@ -1150,26 +1158,26 @@ static lv_res_t lv_cpicker_disc_signal(lv_obj_t * cpicker, lv_signal_t sign, voi if((xp*xp + yp*yp) < (r_in*r_in)) { - if(lv_tick_elaps(ext->last_clic) < 400) + if(lv_tick_elaps(ext->last_click) < 400) { - switch(ext->wheel_mode) + switch(ext->color_mode) { - case LV_CPICKER_WHEEL_HUE: + case LV_CPICKER_COLOR_MODE_HUE: ext->hue = 0; ext->prev_hue = ext->hue; break; - case LV_CPICKER_WHEEL_SAT: + case LV_CPICKER_COLOR_MODE_SATURATION: ext->saturation = 100; ext->prev_saturation = ext->saturation; break; - case LV_CPICKER_WHEEL_VAL: + case LV_CPICKER_COLOR_MODE_VALUE: ext->value = 100; ext->prev_value = ext->value; break; } //lv_cpicker_invalidate_indicator(cpicker); } - ext->last_clic = lv_tick_get(); + ext->last_click = lv_tick_get(); } } else if(sign == LV_SIGNAL_PRESSING) @@ -1180,17 +1188,17 @@ static lv_res_t lv_cpicker_disc_signal(lv_obj_t * cpicker, lv_signal_t sign, voi if((xp*xp + yp*yp) < (r_out*r_out) && (xp*xp + yp*yp) >= (r_in*r_in)) { - switch(ext->wheel_mode) + switch(ext->color_mode) { - case LV_CPICKER_WHEEL_HUE: + case LV_CPICKER_COLOR_MODE_HUE: ext->hue = lv_atan2(xp, yp); ext->prev_hue = ext->hue; break; - case LV_CPICKER_WHEEL_SAT: + case LV_CPICKER_COLOR_MODE_SATURATION: ext->saturation = lv_atan2(xp, yp) * 100.0 / 360.0; ext->prev_saturation = ext->saturation; break; - case LV_CPICKER_WHEEL_VAL: + case LV_CPICKER_COLOR_MODE_VALUE: ext->value = lv_atan2(xp, yp) * 100.0 / 360.0; ext->prev_value = ext->value; break; @@ -1200,15 +1208,15 @@ static lv_res_t lv_cpicker_disc_signal(lv_obj_t * cpicker, lv_signal_t sign, voi } else if(sign == LV_SIGNAL_PRESS_LOST) { - switch(ext->wheel_mode) + switch(ext->color_mode) { - case LV_CPICKER_WHEEL_HUE: + case LV_CPICKER_COLOR_MODE_HUE: ext->prev_hue = ext->hue; break; - case LV_CPICKER_WHEEL_SAT: + case LV_CPICKER_COLOR_MODE_SATURATION: ext->prev_saturation = ext->saturation; break; - case LV_CPICKER_WHEEL_VAL: + case LV_CPICKER_COLOR_MODE_VALUE: ext->prev_value = ext->value; break; } @@ -1222,17 +1230,17 @@ static lv_res_t lv_cpicker_disc_signal(lv_obj_t * cpicker, lv_signal_t sign, voi if((xp*xp + yp*yp) < (r_out*r_out) && (xp*xp + yp*yp) >= (r_in*r_in)) { - switch(ext->wheel_mode) + switch(ext->color_mode) { - case LV_CPICKER_WHEEL_HUE: + case LV_CPICKER_COLOR_MODE_HUE: ext->hue = lv_atan2(xp, yp); ext->prev_hue = ext->hue; break; - case LV_CPICKER_WHEEL_SAT: + case LV_CPICKER_COLOR_MODE_SATURATION: ext->saturation = lv_atan2(xp, yp) * 100.0 / 360.0; ext->prev_saturation = ext->saturation; break; - case LV_CPICKER_WHEEL_VAL: + case LV_CPICKER_COLOR_MODE_VALUE: ext->value = lv_atan2(xp, yp) * 100.0 / 360.0; ext->prev_value = ext->value; break; @@ -1240,13 +1248,13 @@ static lv_res_t lv_cpicker_disc_signal(lv_obj_t * cpicker, lv_signal_t sign, voi lv_cpicker_invalidate_indicator(cpicker); - //LVGLv5 if(ext->value_changed != NULL) - //LVGLv5 ext->value_changed(cpicker); + res = lv_event_send(cpicker, LV_EVENT_VALUE_CHANGED, NULL); + if(res != LV_RES_OK) return res; } } else if(sign == LV_SIGNAL_LONG_PRESS) { - if(!ext->wheel_fixed) + if(!ext->color_mode_fixed) { lv_indev_t * indev = param; lv_coord_t xp = indev->proc.types.pointer.act_point.x - x; @@ -1254,20 +1262,20 @@ static lv_res_t lv_cpicker_disc_signal(lv_obj_t * cpicker, lv_signal_t sign, voi if((xp*xp + yp*yp) < (r_in*r_in)) { - switch(ext->wheel_mode) + switch(ext->color_mode) { - case LV_CPICKER_WHEEL_HUE: + case LV_CPICKER_COLOR_MODE_HUE: ext->prev_hue = ext->hue; break; - case LV_CPICKER_WHEEL_SAT: + case LV_CPICKER_COLOR_MODE_SATURATION: ext->prev_saturation = ext->saturation; break; - case LV_CPICKER_WHEEL_VAL: + case LV_CPICKER_COLOR_MODE_VALUE: ext->prev_value = ext->value; break; } - ext->wheel_mode = (ext->wheel_mode + 1) % 3; + ext->color_mode = (ext->color_mode + 1) % 3; lv_obj_invalidate(cpicker); } @@ -1275,92 +1283,90 @@ static lv_res_t lv_cpicker_disc_signal(lv_obj_t * cpicker, lv_signal_t sign, voi } else if(sign == LV_SIGNAL_CONTROL) { - /* LVGLv5 - uint32_t c = *((uint32_t *)param); /*uint32_t because can be UTF-8* / - if(c == LV_GROUP_KEY_RIGHT) + uint32_t c = *((uint32_t *)param); /*uint32_t because can be UTF-8*/ + if(c == LV_KEY_RIGHT) { - switch(ext->wheel_mode) + switch(ext->color_mode) { - case LV_CPICKER_WHEEL_HUE: + case LV_CPICKER_COLOR_MODE_HUE: ext->hue = (ext->hue + 1) % 360; break; - case LV_CPICKER_WHEEL_SAT: + case LV_CPICKER_COLOR_MODE_SATURATION: ext->saturation = (ext->saturation + 1) % 100; break; - case LV_CPICKER_WHEEL_VAL: + case LV_CPICKER_COLOR_MODE_VALUE: ext->value = (ext->value + 1) % 100; break; } lv_cpicker_invalidate_indicator(cpicker); - if(ext->value_changed != NULL) - ext->value_changed(cpicker); + res = lv_event_send(cpicker, LV_EVENT_VALUE_CHANGED, NULL); + if(res != LV_RES_OK) return res; } - else if(c == LV_GROUP_KEY_LEFT) + else if(c == LV_KEY_LEFT) { - switch(ext->wheel_mode) + switch(ext->color_mode) { - case LV_CPICKER_WHEEL_HUE: + case LV_CPICKER_COLOR_MODE_HUE: ext->hue = ext->hue > 0?(ext->hue - 1):360; break; - case LV_CPICKER_WHEEL_SAT: + case LV_CPICKER_COLOR_MODE_SATURATION: ext->saturation = ext->saturation > 0?(ext->saturation - 1):100; break; - case LV_CPICKER_WHEEL_VAL: + case LV_CPICKER_COLOR_MODE_VALUE: ext->value = ext->value > 0?(ext->value - 1):100; break; } lv_cpicker_invalidate_indicator(cpicker); - if(ext->value_changed != NULL) - ext->value_changed(cpicker); + res = lv_event_send(cpicker, LV_EVENT_VALUE_CHANGED, NULL); + if(res != LV_RES_OK) return res; } - else if(c == LV_GROUP_KEY_UP) + else if(c == LV_KEY_UP) { - switch(ext->wheel_mode) + switch(ext->color_mode) { - case LV_CPICKER_WHEEL_HUE: + case LV_CPICKER_COLOR_MODE_HUE: ext->hue = (ext->hue + 1) % 360; break; - case LV_CPICKER_WHEEL_SAT: + case LV_CPICKER_COLOR_MODE_SATURATION: ext->saturation = (ext->saturation + 1) % 100; break; - case LV_CPICKER_WHEEL_VAL: + case LV_CPICKER_COLOR_MODE_VALUE: ext->value = (ext->value + 1) % 100; break; } lv_cpicker_invalidate_indicator(cpicker); - if(ext->value_changed != NULL) - ext->value_changed(cpicker); + res = lv_event_send(cpicker, LV_EVENT_VALUE_CHANGED, NULL); + if(res != LV_RES_OK) return res; } - else if(c == LV_GROUP_KEY_DOWN) + else if(c == LV_KEY_DOWN) { - switch(ext->wheel_mode) + switch(ext->color_mode) { - case LV_CPICKER_WHEEL_HUE: + case LV_CPICKER_COLOR_MODE_HUE: ext->hue = ext->hue > 0?(ext->hue - 1):360; break; - case LV_CPICKER_WHEEL_SAT: + case LV_CPICKER_COLOR_MODE_SATURATION: ext->saturation = ext->saturation > 0?(ext->saturation - 1):100; break; - case LV_CPICKER_WHEEL_VAL: + case LV_CPICKER_COLOR_MODE_VALUE: ext->value = ext->value > 0?(ext->value - 1):100; break; } lv_cpicker_invalidate_indicator(cpicker); - if(ext->value_changed != NULL) - ext->value_changed(cpicker); + res = lv_event_send(cpicker, LV_EVENT_VALUE_CHANGED, NULL); + if(res != LV_RES_OK) return res; } - */ } - return LV_RES_OK; + return res; } /** @@ -1400,15 +1406,15 @@ static lv_res_t lv_cpicker_rect_signal(lv_obj_t * cpicker, lv_signal_t sign, voi } else if(sign == LV_SIGNAL_PRESSED) { - switch(ext->wheel_mode) + switch(ext->color_mode) { - case LV_CPICKER_WHEEL_HUE: + case LV_CPICKER_COLOR_MODE_HUE: ext->prev_hue = ext->hue; break; - case LV_CPICKER_WHEEL_SAT: + case LV_CPICKER_COLOR_MODE_SATURATION: ext->prev_saturation = ext->saturation; break; - case LV_CPICKER_WHEEL_VAL: + case LV_CPICKER_COLOR_MODE_VALUE: ext->prev_value = ext->value; break; } @@ -1421,26 +1427,26 @@ static lv_res_t lv_cpicker_rect_signal(lv_obj_t * cpicker, lv_signal_t sign, voi //todo : set the area to the color indicator area if(lv_area_is_point_on(&colorIndArea, &indev->proc.types.pointer.act_point)) { - if(lv_tick_elaps(ext->last_clic) < 400) + if(lv_tick_elaps(ext->last_click) < 400) { - switch(ext->wheel_mode) + switch(ext->color_mode) { - case LV_CPICKER_WHEEL_HUE: + case LV_CPICKER_COLOR_MODE_HUE: ext->hue = 0; ext->prev_hue = ext->hue; break; - case LV_CPICKER_WHEEL_SAT: + case LV_CPICKER_COLOR_MODE_SATURATION: ext->saturation = 100; ext->prev_saturation = ext->saturation; break; - case LV_CPICKER_WHEEL_VAL: + case LV_CPICKER_COLOR_MODE_VALUE: ext->value = 100; ext->prev_value = ext->value; break; } lv_obj_invalidate(cpicker); } - ext->last_clic = lv_tick_get(); + ext->last_click = lv_tick_get(); } } else if(sign == LV_SIGNAL_PRESSING) @@ -1453,17 +1459,17 @@ static lv_res_t lv_cpicker_rect_signal(lv_obj_t * cpicker, lv_signal_t sign, voi //todo : set the area to the color gradient area if(lv_area_is_point_on(&colorGradientArea, &indev->proc.types.pointer.act_point)) { - switch(ext->wheel_mode) + switch(ext->color_mode) { - case LV_CPICKER_WHEEL_HUE: + case LV_CPICKER_COLOR_MODE_HUE: ext->hue = lv_atan2(xp, yp); ext->prev_hue = ext->hue; break; - case LV_CPICKER_WHEEL_SAT: + case LV_CPICKER_COLOR_MODE_SATURATION: ext->saturation = lv_atan2(xp, yp) * 100.0 / 360.0; ext->prev_saturation = ext->saturation; break; - case LV_CPICKER_WHEEL_VAL: + case LV_CPICKER_COLOR_MODE_VALUE: ext->value = lv_atan2(xp, yp) * 100.0 / 360.0; ext->prev_value = ext->value; break; @@ -1473,15 +1479,15 @@ static lv_res_t lv_cpicker_rect_signal(lv_obj_t * cpicker, lv_signal_t sign, voi } else if(sign == LV_SIGNAL_PRESS_LOST) { - switch(ext->wheel_mode) + switch(ext->color_mode) { - case LV_CPICKER_WHEEL_HUE: + case LV_CPICKER_COLOR_MODE_HUE: ext->prev_hue = ext->hue; break; - case LV_CPICKER_WHEEL_SAT: + case LV_CPICKER_COLOR_MODE_SATURATION: ext->prev_saturation = ext->saturation; break; - case LV_CPICKER_WHEEL_VAL: + case LV_CPICKER_COLOR_MODE_VALUE: ext->prev_value = ext->value; break; } @@ -1497,17 +1503,17 @@ static lv_res_t lv_cpicker_rect_signal(lv_obj_t * cpicker, lv_signal_t sign, voi //todo : set th area to the color gradient area if(lv_area_is_point_on(&colorGradientArea, &indev->proc.types.pointer.act_point)) { - switch(ext->wheel_mode) + switch(ext->color_mode) { - case LV_CPICKER_WHEEL_HUE: + case LV_CPICKER_COLOR_MODE_HUE: ext->hue = lv_atan2(xp, yp); ext->prev_hue = ext->hue; break; - case LV_CPICKER_WHEEL_SAT: + case LV_CPICKER_COLOR_MODE_SATURATION: ext->saturation = lv_atan2(xp, yp) * 100.0 / 360.0; ext->prev_saturation = ext->saturation; break; - case LV_CPICKER_WHEEL_VAL: + case LV_CPICKER_COLOR_MODE_VALUE: ext->value = lv_atan2(xp, yp) * 100.0 / 360.0; ext->prev_value = ext->value; break; @@ -1515,13 +1521,13 @@ static lv_res_t lv_cpicker_rect_signal(lv_obj_t * cpicker, lv_signal_t sign, voi lv_obj_invalidate(cpicker); - //LVGLv5 if(ext->value_changed != NULL) - //LVGLv5 ext->value_changed(cpicker); + res = lv_event_send(cpicker, LV_EVENT_VALUE_CHANGED, NULL); + if(res != LV_RES_OK) return res; } } else if(sign == LV_SIGNAL_LONG_PRESS) { - if(!ext->wheel_fixed) + if(!ext->color_mode_fixed) { lv_indev_t * indev = param; lv_coord_t xp = indev->proc.types.pointer.act_point.x - x; @@ -1531,104 +1537,102 @@ static lv_res_t lv_cpicker_rect_signal(lv_obj_t * cpicker, lv_signal_t sign, voi //todo : set the area to the color indicator area if(lv_area_is_point_on(&colorIndArea, &indev->proc.types.pointer.act_point)) { - switch(ext->wheel_mode) + switch(ext->color_mode) { - case LV_CPICKER_WHEEL_HUE: + case LV_CPICKER_COLOR_MODE_HUE: ext->prev_hue = ext->hue; break; - case LV_CPICKER_WHEEL_SAT: + case LV_CPICKER_COLOR_MODE_SATURATION: ext->prev_saturation = ext->saturation; break; - case LV_CPICKER_WHEEL_VAL: + case LV_CPICKER_COLOR_MODE_VALUE: ext->prev_value = ext->value; break; } - ext->wheel_mode = (ext->wheel_mode + 1) % 3; + ext->color_mode = (ext->color_mode + 1) % 3; lv_obj_invalidate(cpicker); } } } else if(sign == LV_SIGNAL_CONTROL) { - /* LVGLv5 - uint32_t c = *((uint32_t *)param); /*uint32_t because can be UTF-8* / - if(c == LV_GROUP_KEY_RIGHT) + uint32_t c = *((uint32_t *)param); /*uint32_t because can be UTF-8*/ + if(c == LV_KEY_RIGHT) { - switch(ext->wheel_mode) + switch(ext->color_mode) { - case LV_CPICKER_WHEEL_HUE: + case LV_CPICKER_COLOR_MODE_HUE: ext->hue = (ext->hue + 1) % 360; break; - case LV_CPICKER_WHEEL_SAT: + case LV_CPICKER_COLOR_MODE_SATURATION: ext->saturation = (ext->saturation + 1) % 100; break; - case LV_CPICKER_WHEEL_VAL: + case LV_CPICKER_COLOR_MODE_VALUE: ext->value = (ext->value + 1) % 100; break; } lv_obj_invalidate(cpicker); - if(ext->value_changed != NULL) - ext->value_changed(cpicker); + res = lv_event_send(cpicker, LV_EVENT_VALUE_CHANGED, NULL); + if(res != LV_RES_OK) return res; } - else if(c == LV_GROUP_KEY_LEFT) + else if(c == LV_KEY_LEFT) { - switch(ext->wheel_mode) + switch(ext->color_mode) { - case LV_CPICKER_WHEEL_HUE: + case LV_CPICKER_COLOR_MODE_HUE: ext->hue = ext->hue > 0?(ext->hue - 1):360; break; - case LV_CPICKER_WHEEL_SAT: + case LV_CPICKER_COLOR_MODE_SATURATION: ext->saturation = ext->saturation > 0?(ext->saturation - 1):100; break; - case LV_CPICKER_WHEEL_VAL: + case LV_CPICKER_COLOR_MODE_VALUE: ext->value = ext->value > 0?(ext->value - 1):100; break; } lv_obj_invalidate(cpicker); - if(ext->value_changed != NULL) - ext->value_changed(cpicker); + res = lv_event_send(cpicker, LV_EVENT_VALUE_CHANGED, NULL); + if(res != LV_RES_OK) return res; } - else if(c == LV_GROUP_KEY_UP) + else if(c == LV_KEY_UP) { - switch(ext->wheel_mode) + switch(ext->color_mode) { - case LV_CPICKER_WHEEL_HUE: + case LV_CPICKER_COLOR_MODE_HUE: ext->hue = (ext->hue + 1) % 360; break; - case LV_CPICKER_WHEEL_SAT: + case LV_CPICKER_COLOR_MODE_SATURATION: ext->saturation = (ext->saturation + 1) % 100; break; - case LV_CPICKER_WHEEL_VAL: + case LV_CPICKER_COLOR_MODE_VALUE: ext->value = (ext->value + 1) % 100; break; } lv_obj_invalidate(cpicker); - if(ext->value_changed != NULL) - ext->value_changed(cpicker); + res = lv_event_send(cpicker, LV_EVENT_VALUE_CHANGED, NULL); + if(res != LV_RES_OK) return res; } - else if(c == LV_GROUP_KEY_DOWN) + else if(c == LV_KEY_DOWN) { - switch(ext->wheel_mode) + switch(ext->color_mode) { - case LV_CPICKER_WHEEL_HUE: + case LV_CPICKER_COLOR_MODE_HUE: ext->hue = ext->hue > 0?(ext->hue - 1):360; break; - case LV_CPICKER_WHEEL_SAT: + case LV_CPICKER_COLOR_MODE_SATURATION: ext->saturation = ext->saturation > 0?(ext->saturation - 1):100; break; - case LV_CPICKER_WHEEL_VAL: + case LV_CPICKER_COLOR_MODE_VALUE: ext->value = ext->value > 0?(ext->value - 1):100; break; } lv_obj_invalidate(cpicker); - if(ext->value_changed != NULL) - ext->value_changed(cpicker); + res = lv_event_send(cpicker, LV_EVENT_VALUE_CHANGED, NULL); + if(res != LV_RES_OK) return res; } - */ } - return LV_RES_OK; + return res; } static void lv_cpicker_invalidate_indicator(lv_obj_t * cpicker) @@ -1659,33 +1663,33 @@ static void lv_cpicker_invalidate_indicator(lv_obj_t * cpicker) lv_inv_area(¢er_col_area, NULL); - switch(ext->ind.type) + switch(ext->indicator.type) { - case LV_CPICKER_IND_LINE: + case LV_CPICKER_INDICATOR_LINE: { lv_area_t line_area; lv_point_t point1, point2; lv_coord_t x1, y1, x2, y2; uint16_t angle; - switch(ext->wheel_mode) + switch(ext->color_mode) { default: - case LV_CPICKER_WHEEL_HUE: + case LV_CPICKER_COLOR_MODE_HUE: angle = ext->hue; break; - case LV_CPICKER_WHEEL_SAT: + case LV_CPICKER_COLOR_MODE_SATURATION: angle = ext->saturation * 360 / 100; break; - case LV_CPICKER_WHEEL_VAL: + case LV_CPICKER_COLOR_MODE_VALUE: angle = ext->value * 360 / 100; break; } - x1 = x + ((r - style->line.width + ext->ind.style->body.padding.inner + ext->ind.style->line.width/2) * lv_trigo_sin(angle) >> LV_TRIGO_SHIFT); - y1 = y + ((r - style->line.width + ext->ind.style->body.padding.inner + ext->ind.style->line.width/2) * lv_trigo_sin(angle + 90) >> LV_TRIGO_SHIFT); - x2 = x + ((r - ext->ind.style->body.padding.inner - ext->ind.style->line.width/2) * lv_trigo_sin(angle) >> LV_TRIGO_SHIFT); - y2 = y + ((r - ext->ind.style->body.padding.inner - ext->ind.style->line.width/2) * lv_trigo_sin(angle + 90) >> LV_TRIGO_SHIFT); + x1 = x + ((r - style->line.width + ext->indicator.style->body.padding.inner + ext->indicator.style->line.width/2) * lv_trigo_sin(angle) >> LV_TRIGO_SHIFT); + y1 = y + ((r - style->line.width + ext->indicator.style->body.padding.inner + ext->indicator.style->line.width/2) * lv_trigo_sin(angle + 90) >> LV_TRIGO_SHIFT); + x2 = x + ((r - ext->indicator.style->body.padding.inner - ext->indicator.style->line.width/2) * lv_trigo_sin(angle) >> LV_TRIGO_SHIFT); + y2 = y + ((r - ext->indicator.style->body.padding.inner - ext->indicator.style->line.width/2) * lv_trigo_sin(angle + 90) >> LV_TRIGO_SHIFT); point1.x = x1; point1.y = y1; @@ -1721,20 +1725,20 @@ static void lv_cpicker_invalidate_indicator(lv_obj_t * cpicker) } //} - line_area.x1 -= 2*ext->ind.style->line.width; - line_area.y1 -= 2*ext->ind.style->line.width; - line_area.x2 += 2*ext->ind.style->line.width; - line_area.y2 += 2*ext->ind.style->line.width; + line_area.x1 -= 2*ext->indicator.style->line.width; + line_area.y1 -= 2*ext->indicator.style->line.width; + line_area.x2 += 2*ext->indicator.style->line.width; + line_area.y2 += 2*ext->indicator.style->line.width; lv_inv_area(&line_area, NULL); angle = ext->prev_pos; - x1 = x + ((r - style->line.width + ext->ind.style->body.padding.inner + ext->ind.style->line.width/2) * lv_trigo_sin(angle) >> LV_TRIGO_SHIFT); - y1 = y + ((r - style->line.width + ext->ind.style->body.padding.inner + ext->ind.style->line.width/2) * lv_trigo_sin(angle + 90) >> LV_TRIGO_SHIFT); + x1 = x + ((r - style->line.width + ext->indicator.style->body.padding.inner + ext->indicator.style->line.width/2) * lv_trigo_sin(angle) >> LV_TRIGO_SHIFT); + y1 = y + ((r - style->line.width + ext->indicator.style->body.padding.inner + ext->indicator.style->line.width/2) * lv_trigo_sin(angle + 90) >> LV_TRIGO_SHIFT); - x2 = x + ((r - ext->ind.style->body.padding.inner - ext->ind.style->line.width/2) * lv_trigo_sin(angle) >> LV_TRIGO_SHIFT); - y2 = y + ((r - ext->ind.style->body.padding.inner - ext->ind.style->line.width/2) * lv_trigo_sin(angle + 90) >> LV_TRIGO_SHIFT); + x2 = x + ((r - ext->indicator.style->body.padding.inner - ext->indicator.style->line.width/2) * lv_trigo_sin(angle) >> LV_TRIGO_SHIFT); + y2 = y + ((r - ext->indicator.style->body.padding.inner - ext->indicator.style->line.width/2) * lv_trigo_sin(angle + 90) >> LV_TRIGO_SHIFT); point1.x = x1; point1.y = y1; @@ -1770,32 +1774,32 @@ static void lv_cpicker_invalidate_indicator(lv_obj_t * cpicker) } //} - line_area.x1 -= 2*ext->ind.style->line.width; - line_area.y1 -= 2*ext->ind.style->line.width; - line_area.x2 += 2*ext->ind.style->line.width; - line_area.y2 += 2*ext->ind.style->line.width; + line_area.x1 -= 2*ext->indicator.style->line.width; + line_area.y1 -= 2*ext->indicator.style->line.width; + line_area.x2 += 2*ext->indicator.style->line.width; + line_area.y2 += 2*ext->indicator.style->line.width; lv_inv_area(&line_area, NULL); break; } - case LV_CPICKER_IND_CIRCLE: + case LV_CPICKER_INDICATOR_CIRCLE: { lv_area_t circle_ind_area; uint32_t cx, cy; uint16_t angle; - switch(ext->wheel_mode) + switch(ext->color_mode) { default: - case LV_CPICKER_WHEEL_HUE: + case LV_CPICKER_COLOR_MODE_HUE: angle = ext->hue; break; - case LV_CPICKER_WHEEL_SAT: + case LV_CPICKER_COLOR_MODE_SATURATION: angle = ext->saturation * 360 / 100; break; - case LV_CPICKER_WHEEL_VAL: + case LV_CPICKER_COLOR_MODE_VALUE: angle = ext->value * 360 / 100; break; } @@ -1824,23 +1828,23 @@ static void lv_cpicker_invalidate_indicator(lv_obj_t * cpicker) lv_inv_area(&circle_ind_area, NULL); break; } - case LV_CPICKER_IND_IN: + case LV_CPICKER_INDICATOR_IN: { lv_area_t circle_ind_area; uint32_t cx, cy; uint16_t angle; - switch(ext->wheel_mode) + switch(ext->color_mode) { default: - case LV_CPICKER_WHEEL_HUE: + case LV_CPICKER_COLOR_MODE_HUE: angle = ext->hue; break; - case LV_CPICKER_WHEEL_SAT: + case LV_CPICKER_COLOR_MODE_SATURATION: angle = ext->saturation * 360 / 100; break; - case LV_CPICKER_WHEEL_VAL: + case LV_CPICKER_COLOR_MODE_VALUE: angle = ext->value * 360 / 100; break; } @@ -1851,10 +1855,10 @@ static void lv_cpicker_invalidate_indicator(lv_obj_t * cpicker) cx = x + ((ind_radius) * lv_trigo_sin(angle) >> LV_TRIGO_SHIFT); cy = y + ((ind_radius) * lv_trigo_sin(angle + 90) >> LV_TRIGO_SHIFT); - circle_ind_area.x1 = cx - ext->ind.style->line.width/2; - circle_ind_area.y1 = cy - ext->ind.style->line.width/2; - circle_ind_area.x2 = cx + ext->ind.style->line.width/2; - circle_ind_area.y2 = cy + ext->ind.style->line.width/2; + circle_ind_area.x1 = cx - ext->indicator.style->line.width/2; + circle_ind_area.y1 = cy - ext->indicator.style->line.width/2; + circle_ind_area.x2 = cx + ext->indicator.style->line.width/2; + circle_ind_area.y2 = cy + ext->indicator.style->line.width/2; lv_inv_area(&circle_ind_area, NULL); @@ -1864,10 +1868,10 @@ static void lv_cpicker_invalidate_indicator(lv_obj_t * cpicker) cx = x + ((ind_radius) * lv_trigo_sin(angle) >> LV_TRIGO_SHIFT); cy = y + ((ind_radius) * lv_trigo_sin(angle + 90) >> LV_TRIGO_SHIFT); - circle_ind_area.x1 = cx - ext->ind.style->line.width/2; - circle_ind_area.y1 = cy - ext->ind.style->line.width/2; - circle_ind_area.x2 = cx + ext->ind.style->line.width/2; - circle_ind_area.y2 = cy + ext->ind.style->line.width/2; + circle_ind_area.x1 = cx - ext->indicator.style->line.width/2; + circle_ind_area.y1 = cy - ext->indicator.style->line.width/2; + circle_ind_area.x2 = cx + ext->indicator.style->line.width/2; + circle_ind_area.y2 = cy + ext->indicator.style->line.width/2; lv_inv_area(&circle_ind_area, NULL); break; diff --git a/src/lv_objx/lv_cpicker.h b/src/lv_objx/lv_cpicker.h index d3d61f62a..43429c92c 100644 --- a/src/lv_objx/lv_cpicker.h +++ b/src/lv_objx/lv_cpicker.h @@ -32,7 +32,6 @@ extern "C" { **********************/ /*Data of colorpicker*/ typedef struct { - /*New data for this type */ uint16_t hue; uint8_t saturation; uint8_t value; @@ -40,33 +39,31 @@ typedef struct { { lv_style_t * style; uint8_t type; - }ind; - //LVGLv5 lv_action_t value_changed; + } indicator; uint16_t prev_hue; - uint16_t prev_saturation; - uint16_t prev_value; + uint8_t prev_saturation; + uint8_t prev_value; uint16_t prev_pos; - uint8_t wheel_mode:2; - uint8_t wheel_fixed:1; + uint8_t color_mode:2; + uint8_t color_mode_fixed:1; uint8_t type:1; - uint32_t last_clic; - lv_color_t ring_color; + uint32_t last_click; } lv_cpicker_ext_t; /*Styles*/ enum { LV_CPICKER_STYLE_MAIN, - LV_CPICKER_STYLE_IND, + LV_CPICKER_STYLE_INDICATOR, }; typedef uint8_t lv_cpicker_style_t; enum { - LV_CPICKER_IND_NONE, - LV_CPICKER_IND_LINE, - LV_CPICKER_IND_CIRCLE, - LV_CPICKER_IND_IN + LV_CPICKER_INDICATOR_NONE, + LV_CPICKER_INDICATOR_LINE, + LV_CPICKER_INDICATOR_CIRCLE, + LV_CPICKER_INDICATOR_IN }; -typedef uint8_t lv_cpicker_ind_type_t; +typedef uint8_t lv_cpicker_indicator_type_t; enum { LV_CPICKER_TYPE_RECT, @@ -75,11 +72,11 @@ enum { typedef uint8_t lv_cpicker_type_t; enum { - LV_CPICKER_WHEEL_HUE, - LV_CPICKER_WHEEL_SAT, - LV_CPICKER_WHEEL_VAL + LV_CPICKER_COLOR_MODE_HUE, + LV_CPICKER_COLOR_MODE_SATURATION, + LV_CPICKER_COLOR_MODE_VALUE }; -typedef uint8_t lv_cpicker_wheel_mode_t; +typedef uint8_t lv_cpicker_color_mode_t; /********************** * GLOBAL PROTOTYPES @@ -110,7 +107,7 @@ void lv_cpicker_set_style(lv_obj_t * cpicker, lv_cpicker_style_t type, lv_style_ * @param cpicker pointer to colorpicker object * @param type indicator type */ -void lv_cpicker_set_ind_type(lv_obj_t * cpicker, lv_cpicker_ind_type_t type); +void lv_cpicker_set_indicator_type(lv_obj_t * cpicker, lv_cpicker_indicator_type_t type); /** * Set the current hue of a colorpicker. @@ -119,26 +116,19 @@ void lv_cpicker_set_ind_type(lv_obj_t * cpicker, lv_cpicker_ind_type_t type); */ void lv_cpicker_set_hue(lv_obj_t * cpicker, uint16_t hue); -/** - * Set the ring color of a colorpicker. - * @param cpicker pointer to colorpicker object - * @param ring_color new ring color - */ -void lv_cpicker_set_ring_color(lv_obj_t * cpicker, lv_color_t ring_color); - /** * Set the current saturation of a colorpicker. * @param cpicker pointer to colorpicker object - * @param sat current selected saturation + * @param saturation current selected saturation */ -void lv_cpicker_set_saturation(lv_obj_t * cpicker, uint16_t sat); +void lv_cpicker_set_saturation(lv_obj_t * cpicker, uint8_t saturation); /** * Set the current value of a colorpicker. * @param cpicker pointer to colorpicker object * @param val current selected value */ -void lv_cpicker_set_value(lv_obj_t * cpicker, uint16_t val); +void lv_cpicker_set_value(lv_obj_t * cpicker, uint8_t val); /** * Set the current color of a colorpicker. @@ -148,30 +138,37 @@ void lv_cpicker_set_value(lv_obj_t * cpicker, uint16_t val); void lv_cpicker_set_color(lv_obj_t * cpicker, lv_color_t color); /** - * Set the action callback on value change event. + * Set the current color mode. * @param cpicker pointer to colorpicker object - * @param action callback function + * @param mode color mode (hue/sat/val) */ -//LVGLv5 void lv_cpicker_set_action(lv_obj_t * cpicker, lv_action_t action); +void lv_cpicker_set_color_mode(lv_obj_t * cpicker, lv_cpicker_color_mode_t mode); /** - * Set the current wheel mode. + * Set if the color mode is changed on long press on center * @param cpicker pointer to colorpicker object - * @param mode wheel mode (hue/sat/val) + * @param fixed color mode cannot be changed on long press */ -void lv_cpicker_set_wheel_mode(lv_obj_t * cpicker, lv_cpicker_wheel_mode_t mode); - -/** - * Set if the wheel mode is changed on long press on center - * @param cpicker pointer to colorpicker object - * @param fixed_mode mode cannot be changed if set - */ -void lv_cpicker_set_wheel_fixed(lv_obj_t * cpicker, bool fixed_mode); +void lv_cpicker_set_color_mode_fixed(lv_obj_t * cpicker, bool fixed); /*===================== * Getter functions *====================*/ +/** + * Get the current color mode. + * @param cpicker pointer to colorpicker object + * @return color mode (hue/sat/val) + */ +lv_cpicker_color_mode_t lv_cpicker_get_color_mode(lv_obj_t * cpicker); + +/** + * Get if the color mode is changed on long press on center + * @param cpicker pointer to colorpicker object + * @return mode cannot be changed on long press + */ +bool lv_cpicker_get_color_mode_fixed(lv_obj_t * cpicker); + /** * Get style of a colorpicker. * @param cpicker pointer to colorpicker object @@ -180,13 +177,6 @@ void lv_cpicker_set_wheel_fixed(lv_obj_t * cpicker, bool fixed_mode); */ lv_style_t * lv_cpicker_get_style(const lv_obj_t * cpicker, lv_cpicker_style_t type); -/** - * Get the ring color of a colorpicker. - * @param cpicker pointer to colorpicker object - * @return current ring color - */ -lv_color_t lv_cpicker_get_ring_color(const lv_obj_t * cpicker); - /** * Get the current hue of a colorpicker. * @param cpicker pointer to colorpicker object @@ -194,6 +184,20 @@ lv_color_t lv_cpicker_get_ring_color(const lv_obj_t * cpicker); */ uint16_t lv_cpicker_get_hue(lv_obj_t * cpicker); +/** + * Get the current saturation of a colorpicker. + * @param cpicker pointer to colorpicker object + * @return current selected saturation + */ +uint8_t lv_cpicker_get_saturation(lv_obj_t * cpicker); + +/** + * Get the current hue of a colorpicker. + * @param cpicker pointer to colorpicker object + * @return current selected value + */ +uint8_t lv_cpicker_get_value(lv_obj_t * cpicker); + /** * Get the current selected color of a colorpicker. * @param cpicker pointer to colorpicker object @@ -201,13 +205,6 @@ uint16_t lv_cpicker_get_hue(lv_obj_t * cpicker); */ lv_color_t lv_cpicker_get_color(lv_obj_t * cpicker); -/** - * Get the action callback called on value change event. - * @param cpicker pointer to colorpicker object - * @return action callback function - */ -//LVGLv5 lv_action_t lv_cpicker_get_action(lv_obj_t * cpicker); - /*===================== * Other functions *====================*/ From 305ac5ff692cefb2e3c42f726446c6282765e06d Mon Sep 17 00:00:00 2001 From: Paul Peavyhouse Date: Wed, 18 Sep 2019 21:37:18 -0700 Subject: [PATCH 05/82] Got invalidation working --- src/lv_objx/lv_cpicker.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/src/lv_objx/lv_cpicker.c b/src/lv_objx/lv_cpicker.c index b33ff4295..9ac0f1df0 100644 --- a/src/lv_objx/lv_cpicker.c +++ b/src/lv_objx/lv_cpicker.c @@ -1637,6 +1637,8 @@ static lv_res_t lv_cpicker_rect_signal(lv_obj_t * cpicker, lv_signal_t sign, voi static void lv_cpicker_invalidate_indicator(lv_obj_t * cpicker) { + lv_disp_t * disp = lv_disp_get_default(); + lv_cpicker_ext_t * ext = lv_obj_get_ext_attr(cpicker); lv_style_t * style = lv_cpicker_get_style(cpicker, LV_CPICKER_STYLE_MAIN); @@ -1661,7 +1663,7 @@ static void lv_cpicker_invalidate_indicator(lv_obj_t * cpicker) center_col_area.x2 = x + radius; center_col_area.y2 = y + radius; - lv_inv_area(¢er_col_area, NULL); + lv_inv_area(disp, ¢er_col_area); switch(ext->indicator.type) { @@ -1730,7 +1732,7 @@ static void lv_cpicker_invalidate_indicator(lv_obj_t * cpicker) line_area.x2 += 2*ext->indicator.style->line.width; line_area.y2 += 2*ext->indicator.style->line.width; - lv_inv_area(&line_area, NULL); + lv_inv_area(disp, &line_area); angle = ext->prev_pos; @@ -1779,7 +1781,7 @@ static void lv_cpicker_invalidate_indicator(lv_obj_t * cpicker) line_area.x2 += 2*ext->indicator.style->line.width; line_area.y2 += 2*ext->indicator.style->line.width; - lv_inv_area(&line_area, NULL); + lv_inv_area(disp, &line_area); break; } @@ -1812,7 +1814,7 @@ static void lv_cpicker_invalidate_indicator(lv_obj_t * cpicker) circle_ind_area.x2 = cx + style->line.width/2; circle_ind_area.y2 = cy + style->line.width/2; - lv_inv_area(&circle_ind_area, NULL); + lv_inv_area(disp, &circle_ind_area); /* invalidate last position*/ angle = ext->prev_pos; @@ -1825,7 +1827,7 @@ static void lv_cpicker_invalidate_indicator(lv_obj_t * cpicker) circle_ind_area.x2 = cx + style->line.width/2; circle_ind_area.y2 = cy + style->line.width/2; - lv_inv_area(&circle_ind_area, NULL); + lv_inv_area(disp, &circle_ind_area); break; } case LV_CPICKER_INDICATOR_IN: @@ -1860,7 +1862,7 @@ static void lv_cpicker_invalidate_indicator(lv_obj_t * cpicker) circle_ind_area.x2 = cx + ext->indicator.style->line.width/2; circle_ind_area.y2 = cy + ext->indicator.style->line.width/2; - lv_inv_area(&circle_ind_area, NULL); + lv_inv_area(disp, &circle_ind_area); /* invalidate last position*/ angle = ext->prev_pos; @@ -1873,7 +1875,7 @@ static void lv_cpicker_invalidate_indicator(lv_obj_t * cpicker) circle_ind_area.x2 = cx + ext->indicator.style->line.width/2; circle_ind_area.y2 = cy + ext->indicator.style->line.width/2; - lv_inv_area(&circle_ind_area, NULL); + lv_inv_area(disp, &circle_ind_area); break; } } From a7dc9e852c00c4cafe38ed4738b764a9e5c1988d Mon Sep 17 00:00:00 2001 From: Paul Peavyhouse Date: Tue, 24 Sep 2019 13:48:41 -0700 Subject: [PATCH 06/82] Fix Rect by using persisted gradient & preview area in touch calculation --- src/lv_objx/lv_cpicker.c | 174 ++++++++++++++++++--------------------- src/lv_objx/lv_cpicker.h | 2 + 2 files changed, 80 insertions(+), 96 deletions(-) diff --git a/src/lv_objx/lv_cpicker.c b/src/lv_objx/lv_cpicker.c index 9ac0f1df0..4aff17954 100644 --- a/src/lv_objx/lv_cpicker.c +++ b/src/lv_objx/lv_cpicker.c @@ -826,7 +826,6 @@ static bool lv_cpicker_rect_design(lv_obj_t * cpicker, const lv_area_t * mask, l lv_coord_t h = lv_obj_get_height(cpicker); lv_coord_t gradient_w, gradient_h; - lv_area_t gradient_area; lv_coord_t x1 = cpicker->coords.x1; lv_coord_t y1 = cpicker->coords.y1; @@ -836,7 +835,6 @@ static bool lv_cpicker_rect_design(lv_obj_t * cpicker, const lv_area_t * mask, l /* prepare the color preview area */ uint16_t preview_offset = style->line.width; - lv_area_t preview_area; uint16_t style_body_padding_ver = style->body.padding.top + style->body.padding.bottom; uint16_t style_body_padding_hor = style->body.padding.left + style->body.padding.right; if(style_body_padding_ver == 0) @@ -847,30 +845,30 @@ static bool lv_cpicker_rect_design(lv_obj_t * cpicker, const lv_area_t * mask, l /*draw the preview to the right*/ gradient_w = w - preview_offset - (LV_MATH_ABS(style_body_padding_hor) - 1); gradient_h = y2 - y1; - gradient_area.x1 = x1; - gradient_area.x2 = gradient_area.x1 + gradient_w; - gradient_area.y1 = y1; - gradient_area.y2 = y2; + ext->rect_gradient_area.x1 = x1; + ext->rect_gradient_area.x2 = ext->rect_gradient_area.x1 + gradient_w; + ext->rect_gradient_area.y1 = y1; + ext->rect_gradient_area.y2 = y2; - preview_area.x1 = x2 - preview_offset; - preview_area.y1 = y1; - preview_area.x2 = x2 ; - preview_area.y2 = y2; + ext->rect_preview_area.x1 = x2 - preview_offset; + ext->rect_preview_area.y1 = y1; + ext->rect_preview_area.x2 = x2 ; + ext->rect_preview_area.y2 = y2; } else { /*draw the preview to the left*/ gradient_w = w - preview_offset - (LV_MATH_ABS(style_body_padding_hor) - 1); gradient_h = y2 - y1; - gradient_area.x1 = x2 - gradient_w; - gradient_area.x2 = x2; - gradient_area.y1 = y1; - gradient_area.y2 = y2; + ext->rect_gradient_area.x1 = x2 - gradient_w; + ext->rect_gradient_area.x2 = x2; + ext->rect_gradient_area.y1 = y1; + ext->rect_gradient_area.y2 = y2; - preview_area.x1 = x1; - preview_area.y1 = y1; - preview_area.x2 = x1 + preview_offset; - preview_area.y2 = y2; + ext->rect_preview_area.x1 = x1; + ext->rect_preview_area.y1 = y1; + ext->rect_preview_area.x2 = x1 + preview_offset; + ext->rect_preview_area.y2 = y2; } } else @@ -881,30 +879,30 @@ static bool lv_cpicker_rect_design(lv_obj_t * cpicker, const lv_area_t * mask, l /*draw the preview on top*/ gradient_w = w; gradient_h = (y2 - y1) - preview_offset - (LV_MATH_ABS(style_body_padding_ver) - 1); - gradient_area.x1 = x1; - gradient_area.x2 = x2; - gradient_area.y1 = y2 - gradient_h; - gradient_area.y2 = y2; + ext->rect_gradient_area.x1 = x1; + ext->rect_gradient_area.x2 = x2; + ext->rect_gradient_area.y1 = y2 - gradient_h; + ext->rect_gradient_area.y2 = y2; - preview_area.x1 = x1; - preview_area.y1 = y1; - preview_area.x2 = x2; - preview_area.y2 = y1 + preview_offset; + ext->rect_preview_area.x1 = x1; + ext->rect_preview_area.y1 = y1; + ext->rect_preview_area.x2 = x2; + ext->rect_preview_area.y2 = y1 + preview_offset; } else { /*draw the preview below the gradient*/ gradient_w = w; gradient_h = (y2 - y1) - preview_offset - (LV_MATH_ABS(style_body_padding_ver) - 1); - gradient_area.x1 = x1; - gradient_area.x2 = x2; - gradient_area.y1 = y1; - gradient_area.y2 = y1 + gradient_h; + ext->rect_gradient_area.x1 = x1; + ext->rect_gradient_area.x2 = x2; + ext->rect_gradient_area.y1 = y1; + ext->rect_gradient_area.y2 = y1 + gradient_h; - preview_area.x1 = x1; - preview_area.y1 = y2 - preview_offset; - preview_area.x2 = x2; - preview_area.y2 = y2; + ext->rect_preview_area.x1 = x1; + ext->rect_preview_area.y1 = y2 - preview_offset; + ext->rect_preview_area.x2 = x2; + ext->rect_preview_area.y2 = y2; } } @@ -913,13 +911,13 @@ static bool lv_cpicker_rect_design(lv_obj_t * cpicker, const lv_area_t * mask, l /*draw rounded edges to the gradient*/ lv_area_t rounded_edge_area; - rounded_edge_area.x1 = gradient_area.x1; - rounded_edge_area.x2 = gradient_area.x1 + gradient_h; - rounded_edge_area.y1 = gradient_area.y1; - rounded_edge_area.y2 = gradient_area.y2; + rounded_edge_area.x1 = ext->rect_gradient_area.x1; + rounded_edge_area.x2 = ext->rect_gradient_area.x1 + gradient_h; + rounded_edge_area.y1 = ext->rect_gradient_area.y1; + rounded_edge_area.y2 = ext->rect_gradient_area.y2; - gradient_area.x1 += gradient_h/2; - gradient_area.x2 -= gradient_h/2; + ext->rect_gradient_area.x1 += gradient_h/2; + ext->rect_gradient_area.x2 -= gradient_h/2; gradient_w -= gradient_h; switch(ext->color_mode) @@ -991,10 +989,10 @@ static bool lv_cpicker_rect_design(lv_obj_t * cpicker, const lv_area_t * mask, l /*scale angle (hue/sat/val) to linear coordinate*/ lv_coord_t xi = i*gradient_w/360; - rect_area.x1 = LV_MATH_MIN(gradient_area.x1 + xi, gradient_area.x1 + gradient_w - LV_MATH_MAX(LV_CPICKER_DEF_QF, 360/gradient_w)); - rect_area.y1 = gradient_area.y1; + rect_area.x1 = LV_MATH_MIN(ext->rect_gradient_area.x1 + xi, ext->rect_gradient_area.x1 + gradient_w - LV_MATH_MAX(LV_CPICKER_DEF_QF, 360/gradient_w)); + rect_area.y1 = ext->rect_gradient_area.y1; rect_area.x2 = rect_area.x1 + LV_MATH_MAX(LV_CPICKER_DEF_QF, 360/gradient_w); - rect_area.y2 = gradient_area.y2; + rect_area.y2 = ext->rect_gradient_area.y2; lv_draw_rect(&rect_area, mask, &styleCopy, opa_scale); } @@ -1002,8 +1000,8 @@ static bool lv_cpicker_rect_design(lv_obj_t * cpicker, const lv_area_t * mask, l if(style->line.rounded) { /*Restore gradient area to take rounded end in account*/ - gradient_area.x1 -= gradient_h/2; - gradient_area.x2 += gradient_h/2; + ext->rect_gradient_area.x1 -= gradient_h/2; + ext->rect_gradient_area.x2 += gradient_h/2; //gradient_w += gradient_h; } @@ -1014,7 +1012,7 @@ static bool lv_cpicker_rect_design(lv_obj_t * cpicker, const lv_area_t * mask, l { styleCopy.body.radius = gradient_h; } - lv_draw_rect(&preview_area, mask, &styleCopy, opa_scale); + lv_draw_rect(&(ext->rect_preview_area), mask, &styleCopy, opa_scale); /* styleCopy.line.width = 10; @@ -1028,10 +1026,10 @@ static bool lv_cpicker_rect_design(lv_obj_t * cpicker, const lv_area_t * mask, l { default: case LV_CPICKER_COLOR_MODE_HUE: - ind_pos += ext->hue * gradient_w /360; + ind_pos += ext->hue * gradient_w / 360; break; case LV_CPICKER_COLOR_MODE_SATURATION: - ind_pos += ext->saturation * gradient_w / 100 ; + ind_pos += ext->saturation * gradient_w / 100; break; case LV_CPICKER_COLOR_MODE_VALUE: ind_pos += ext->value * gradient_w / 100; @@ -1046,21 +1044,21 @@ static bool lv_cpicker_rect_design(lv_obj_t * cpicker, const lv_area_t * mask, l case LV_CPICKER_INDICATOR_LINE: { lv_point_t p1, p2; - p1.x = gradient_area.x1 + ind_pos; + p1.x = ext->rect_gradient_area.x1 + ind_pos; p2.x = p1.x; - p1.y = gradient_area.y1; - p2.y = gradient_area.y2; + p1.y = ext->rect_gradient_area.y1; + p2.y = ext->rect_gradient_area.y2; - lv_draw_line(&p1, &p2, &gradient_area, ext->indicator.style, opa_scale); + lv_draw_line(&p1, &p2, &(ext->rect_gradient_area), ext->indicator.style, opa_scale); break; } case LV_CPICKER_INDICATOR_CIRCLE: { lv_area_t circle_ind_area; - circle_ind_area.x1 = gradient_area.x1 + ind_pos - gradient_h/2; + circle_ind_area.x1 = ext->rect_gradient_area.x1 + ind_pos - gradient_h/2; circle_ind_area.x2 = circle_ind_area.x1 + gradient_h; - circle_ind_area.y1 = gradient_area.y1; - circle_ind_area.y2 = gradient_area.y2; + circle_ind_area.y1 = ext->rect_gradient_area.y1; + circle_ind_area.y2 = ext->rect_gradient_area.y2; lv_style_copy(&styleCopy, ext->indicator.style); styleCopy.body.radius = LV_RADIUS_CIRCLE; @@ -1073,21 +1071,21 @@ static bool lv_cpicker_rect_design(lv_obj_t * cpicker, const lv_area_t * mask, l /*draw triangle under the gradient*/ lv_point_t triangle_points[3]; - triangle_points[0].x = ind_pos + gradient_area.x1; - triangle_points[0].y = gradient_area.y2 - (gradient_h/3); + triangle_points[0].x = ind_pos + ext->rect_gradient_area.x1; + triangle_points[0].y = ext->rect_gradient_area.y2 - (gradient_h/3); triangle_points[1].x = triangle_points[0].x - ext->indicator.style->line.width / 3; - triangle_points[1].y = gradient_area.y2; + triangle_points[1].y = ext->rect_gradient_area.y2; triangle_points[2].x = triangle_points[0].x + ext->indicator.style->line.width / 3; - triangle_points[2].y = gradient_area.y2; + triangle_points[2].y = ext->rect_gradient_area.y2; - lv_draw_triangle(triangle_points, &gradient_area, ext->indicator.style, LV_OPA_COVER); + lv_draw_triangle(triangle_points, &(ext->rect_gradient_area), ext->indicator.style, LV_OPA_COVER); - triangle_points[0].y = gradient_area.y1 + (gradient_h/3); - triangle_points[1].y = gradient_area.y1 - 1; - triangle_points[2].y = gradient_area.y1 - 1; - lv_draw_triangle(triangle_points, &gradient_area, ext->indicator.style, LV_OPA_COVER); + triangle_points[0].y = ext->rect_gradient_area.y1 + (gradient_h/3); + triangle_points[1].y = ext->rect_gradient_area.y1 - 1; + triangle_points[2].y = ext->rect_gradient_area.y1 - 1; + lv_draw_triangle(triangle_points, &(ext->rect_gradient_area), ext->indicator.style, LV_OPA_COVER); break; } default: @@ -1388,12 +1386,6 @@ static lv_res_t lv_cpicker_rect_signal(lv_obj_t * cpicker, lv_signal_t sign, voi lv_style_t * style = lv_cpicker_get_style(cpicker, LV_CPICKER_STYLE_MAIN); - lv_coord_t r_out = (LV_MATH_MIN(lv_obj_get_width(cpicker), lv_obj_get_height(cpicker))) / 2; - lv_coord_t r_in = r_out - style->line.width - style->body.padding.inner; - - lv_coord_t x = cpicker->coords.x1 + lv_obj_get_width(cpicker) / 2; - lv_coord_t y = cpicker->coords.y1 + lv_obj_get_height(cpicker) / 2; - if(sign == LV_SIGNAL_CLEANUP) { /*Nothing to cleanup. (No dynamically allocated memory in 'ext')*/ } else if(sign == LV_SIGNAL_GET_TYPE) { @@ -1420,12 +1412,8 @@ static lv_res_t lv_cpicker_rect_signal(lv_obj_t * cpicker, lv_signal_t sign, voi } lv_indev_t * indev = param; - lv_coord_t xp = indev->proc.types.pointer.act_point.x - x; - lv_coord_t yp = indev->proc.types.pointer.act_point.y - y; - lv_area_t colorIndArea; - //todo : set the area to the color indicator area - if(lv_area_is_point_on(&colorIndArea, &indev->proc.types.pointer.act_point)) + if(lv_area_is_point_on(&(ext->rect_preview_area), &indev->proc.types.pointer.act_point)) { if(lv_tick_elaps(ext->last_click) < 400) { @@ -1452,25 +1440,24 @@ static lv_res_t lv_cpicker_rect_signal(lv_obj_t * cpicker, lv_signal_t sign, voi else if(sign == LV_SIGNAL_PRESSING) { lv_indev_t * indev = param; - lv_coord_t xp = indev->proc.types.pointer.act_point.x - x; - lv_coord_t yp = indev->proc.types.pointer.act_point.y - y; - lv_area_t colorGradientArea; - //todo : set the area to the color gradient area - if(lv_area_is_point_on(&colorGradientArea, &indev->proc.types.pointer.act_point)) + if(lv_area_is_point_on(&(ext->rect_gradient_area), &indev->proc.types.pointer.act_point)) { + uint16_t width = ext->rect_gradient_area.x2 - ext->rect_gradient_area.x1; + uint16_t distance = indev->proc.types.pointer.act_point.x - ext->rect_gradient_area.x1; + float percent = distance / (float) width; switch(ext->color_mode) { case LV_CPICKER_COLOR_MODE_HUE: - ext->hue = lv_atan2(xp, yp); + ext->hue = percent * 360; ext->prev_hue = ext->hue; break; case LV_CPICKER_COLOR_MODE_SATURATION: - ext->saturation = lv_atan2(xp, yp) * 100.0 / 360.0; + ext->saturation = percent * 100.0; ext->prev_saturation = ext->saturation; break; case LV_CPICKER_COLOR_MODE_VALUE: - ext->value = lv_atan2(xp, yp) * 100.0 / 360.0; + ext->value = percent * 100.0; ext->prev_value = ext->value; break; } @@ -1496,25 +1483,24 @@ static lv_res_t lv_cpicker_rect_signal(lv_obj_t * cpicker, lv_signal_t sign, voi else if(sign == LV_SIGNAL_RELEASED) { lv_indev_t * indev = param; - lv_coord_t xp = indev->proc.types.pointer.act_point.x - x; - lv_coord_t yp = indev->proc.types.pointer.act_point.y - y; - lv_area_t colorGradientArea; - //todo : set th area to the color gradient area - if(lv_area_is_point_on(&colorGradientArea, &indev->proc.types.pointer.act_point)) + if(lv_area_is_point_on(&(ext->rect_gradient_area), &indev->proc.types.pointer.act_point)) { + uint16_t width = ext->rect_gradient_area.x2 - ext->rect_gradient_area.x1; + uint16_t distance = indev->proc.types.pointer.act_point.x - ext->rect_gradient_area.x1; + float percent = distance / (float) width; switch(ext->color_mode) { case LV_CPICKER_COLOR_MODE_HUE: - ext->hue = lv_atan2(xp, yp); + ext->hue = percent * 360; ext->prev_hue = ext->hue; break; case LV_CPICKER_COLOR_MODE_SATURATION: - ext->saturation = lv_atan2(xp, yp) * 100.0 / 360.0; + ext->saturation = percent * 100; ext->prev_saturation = ext->saturation; break; case LV_CPICKER_COLOR_MODE_VALUE: - ext->value = lv_atan2(xp, yp) * 100.0 / 360.0; + ext->value = percent * 100; ext->prev_value = ext->value; break; } @@ -1530,12 +1516,8 @@ static lv_res_t lv_cpicker_rect_signal(lv_obj_t * cpicker, lv_signal_t sign, voi if(!ext->color_mode_fixed) { lv_indev_t * indev = param; - lv_coord_t xp = indev->proc.types.pointer.act_point.x - x; - lv_coord_t yp = indev->proc.types.pointer.act_point.y - y; - lv_area_t colorIndArea; - //todo : set the area to the color indicator area - if(lv_area_is_point_on(&colorIndArea, &indev->proc.types.pointer.act_point)) + if(lv_area_is_point_on(&(ext->rect_preview_area), &indev->proc.types.pointer.act_point)) { switch(ext->color_mode) { diff --git a/src/lv_objx/lv_cpicker.h b/src/lv_objx/lv_cpicker.h index 43429c92c..a31aa55b1 100644 --- a/src/lv_objx/lv_cpicker.h +++ b/src/lv_objx/lv_cpicker.h @@ -48,6 +48,8 @@ typedef struct { uint8_t color_mode_fixed:1; uint8_t type:1; uint32_t last_click; + lv_area_t rect_preview_area; + lv_area_t rect_gradient_area; } lv_cpicker_ext_t; /*Styles*/ From 0b4e7629b8d9c523b7e0d0e1214e981de15925fa Mon Sep 17 00:00:00 2001 From: Paul Peavyhouse Date: Tue, 24 Sep 2019 18:00:39 -0700 Subject: [PATCH 07/82] Got most modes fully working; Rect invalidation not optimized. --- src/lv_objx/lv_cpicker.c | 222 +++++++++++++++++++-------------------- src/lv_objx/lv_cpicker.h | 2 +- 2 files changed, 111 insertions(+), 113 deletions(-) diff --git a/src/lv_objx/lv_cpicker.c b/src/lv_objx/lv_cpicker.c index 4aff17954..0ed005899 100644 --- a/src/lv_objx/lv_cpicker.c +++ b/src/lv_objx/lv_cpicker.c @@ -70,7 +70,7 @@ static lv_res_t lv_cpicker_disc_signal(lv_obj_t * cpicker, lv_signal_t sign, voi static bool lv_cpicker_rect_design(lv_obj_t * cpicker, const lv_area_t * mask, lv_design_mode_t mode); static lv_res_t lv_cpicker_rect_signal(lv_obj_t * cpicker, lv_signal_t sign, void * param); -static void lv_cpicker_invalidate_indicator(lv_obj_t * cpicker); +static void lv_cpicker_invalidate(lv_obj_t * cpicker, bool all); /********************** * STATIC VARIABLES @@ -675,7 +675,7 @@ static bool lv_cpicker_disc_design(lv_obj_t * cpicker, const lv_area_t * mask, l } /*save the angle to refresh the area later*/ - ext->prev_pos = angle; + ext->prev_angle = angle; start.x = x + ((r - style->line.width + ext->indicator.style->body.padding.inner + ext->indicator.style->line.width/2) * lv_trigo_sin(angle) >> LV_TRIGO_SHIFT); start.y = y + ((r - style->line.width + ext->indicator.style->body.padding.inner + ext->indicator.style->line.width/2) * lv_trigo_sin(angle + 90) >> LV_TRIGO_SHIFT); @@ -703,7 +703,7 @@ static bool lv_cpicker_disc_design(lv_obj_t * cpicker, const lv_area_t * mask, l } case LV_CPICKER_INDICATOR_CIRCLE: { - lv_area_t circle_area; + lv_area_t circle_ind_area; uint32_t cx, cy; uint16_t angle; @@ -723,23 +723,25 @@ static bool lv_cpicker_disc_design(lv_obj_t * cpicker, const lv_area_t * mask, l } /*save the angle to refresh the area later*/ - ext->prev_pos = angle; + ext->prev_angle = angle; cx = x + ((r - style->line.width/2) * lv_trigo_sin(angle) >> LV_TRIGO_SHIFT); cy = y + ((r - style->line.width/2) * lv_trigo_sin(angle + 90) >> LV_TRIGO_SHIFT); - circle_area.x1 = cx - style->line.width/2; - circle_area.y1 = cy - style->line.width/2; - circle_area.x2 = cx + style->line.width/2; - circle_area.y2 = cy + style->line.width/2; + circle_ind_area.x1 = cx - style->line.width/2; + circle_ind_area.y1 = cy - style->line.width/2; + circle_ind_area.x2 = cx + style->line.width/2; + circle_ind_area.y2 = cy + style->line.width/2; - ext->indicator.style->body.radius = LV_RADIUS_CIRCLE; - lv_draw_rect(&circle_area, mask, ext->indicator.style, opa_scale); + lv_style_copy(&styleCopy, ext->indicator.style); + styleCopy.body.radius = LV_RADIUS_CIRCLE; + + lv_draw_rect(&circle_ind_area, mask, &styleCopy, opa_scale); break; } case LV_CPICKER_INDICATOR_IN: { - lv_area_t circle_area; + lv_area_t circle_ind_area; uint32_t cx, cy; uint16_t angle; @@ -759,7 +761,7 @@ static bool lv_cpicker_disc_design(lv_obj_t * cpicker, const lv_area_t * mask, l } /*save the angle to refresh the area later*/ - ext->prev_pos = angle; + ext->prev_angle = angle; uint16_t ind_radius = lv_sqrt((4*rin*rin)/2)/2 + 1 - style->body.padding.inner; ind_radius = (ind_radius + rin) / 2; @@ -767,13 +769,15 @@ static bool lv_cpicker_disc_design(lv_obj_t * cpicker, const lv_area_t * mask, l cx = x + ((ind_radius) * lv_trigo_sin(angle) >> LV_TRIGO_SHIFT); cy = y + ((ind_radius) * lv_trigo_sin(angle + 90) >> LV_TRIGO_SHIFT); - circle_area.x1 = cx - ext->indicator.style->line.width/2; - circle_area.y1 = cy - ext->indicator.style->line.width/2; - circle_area.x2 = cx + ext->indicator.style->line.width/2; - circle_area.y2 = cy + ext->indicator.style->line.width/2; + circle_ind_area.x1 = cx - ((wradius - radius) / 3); + circle_ind_area.y1 = cy - ((wradius - radius) / 3); + circle_ind_area.x2 = cx + ((wradius - radius) / 3); + circle_ind_area.y2 = cy + ((wradius - radius) / 3); - ext->indicator.style->body.radius = LV_RADIUS_CIRCLE; - lv_draw_rect(&circle_area, mask, ext->indicator.style, opa_scale); + lv_style_copy(&styleCopy, ext->indicator.style); + styleCopy.body.radius = LV_RADIUS_CIRCLE; + + lv_draw_rect(&circle_ind_area, mask, &styleCopy, opa_scale); break; } } // switch @@ -908,7 +912,6 @@ static bool lv_cpicker_rect_design(lv_obj_t * cpicker, const lv_area_t * mask, l if(style->line.rounded) { - /*draw rounded edges to the gradient*/ lv_area_t rounded_edge_area; rounded_edge_area.x1 = ext->rect_gradient_area.x1; @@ -1045,11 +1048,11 @@ static bool lv_cpicker_rect_design(lv_obj_t * cpicker, const lv_area_t * mask, l { lv_point_t p1, p2; p1.x = ext->rect_gradient_area.x1 + ind_pos; - p2.x = p1.x; p1.y = ext->rect_gradient_area.y1; + p2.x = p1.x; p2.y = ext->rect_gradient_area.y2; - lv_draw_line(&p1, &p2, &(ext->rect_gradient_area), ext->indicator.style, opa_scale); + lv_draw_line(&p1, &p2, mask, ext->indicator.style, opa_scale); break; } case LV_CPICKER_INDICATOR_CIRCLE: @@ -1071,21 +1074,21 @@ static bool lv_cpicker_rect_design(lv_obj_t * cpicker, const lv_area_t * mask, l /*draw triangle under the gradient*/ lv_point_t triangle_points[3]; - triangle_points[0].x = ind_pos + ext->rect_gradient_area.x1; + triangle_points[0].x = ext->rect_gradient_area.x1 + ind_pos; triangle_points[0].y = ext->rect_gradient_area.y2 - (gradient_h/3); - triangle_points[1].x = triangle_points[0].x - ext->indicator.style->line.width / 3; + triangle_points[1].x = triangle_points[0].x - ext->indicator.style->line.width * 3; triangle_points[1].y = ext->rect_gradient_area.y2; - triangle_points[2].x = triangle_points[0].x + ext->indicator.style->line.width / 3; - triangle_points[2].y = ext->rect_gradient_area.y2; + triangle_points[2].x = triangle_points[0].x + ext->indicator.style->line.width * 3; + triangle_points[2].y = triangle_points[1].y; - lv_draw_triangle(triangle_points, &(ext->rect_gradient_area), ext->indicator.style, LV_OPA_COVER); + lv_draw_triangle(triangle_points, mask, ext->indicator.style, LV_OPA_COVER); triangle_points[0].y = ext->rect_gradient_area.y1 + (gradient_h/3); triangle_points[1].y = ext->rect_gradient_area.y1 - 1; - triangle_points[2].y = ext->rect_gradient_area.y1 - 1; - lv_draw_triangle(triangle_points, &(ext->rect_gradient_area), ext->indicator.style, LV_OPA_COVER); + triangle_points[2].y = triangle_points[1].y; + lv_draw_triangle(triangle_points, mask, ext->indicator.style, LV_OPA_COVER); break; } default: @@ -1173,7 +1176,7 @@ static lv_res_t lv_cpicker_disc_signal(lv_obj_t * cpicker, lv_signal_t sign, voi ext->prev_value = ext->value; break; } - //lv_cpicker_invalidate_indicator(cpicker); + //lv_cpicker_invalidate(cpicker, false); } ext->last_click = lv_tick_get(); } @@ -1201,7 +1204,7 @@ static lv_res_t lv_cpicker_disc_signal(lv_obj_t * cpicker, lv_signal_t sign, voi ext->prev_value = ext->value; break; } - lv_cpicker_invalidate_indicator(cpicker); + lv_cpicker_invalidate(cpicker, false); } } else if(sign == LV_SIGNAL_PRESS_LOST) @@ -1218,7 +1221,7 @@ static lv_res_t lv_cpicker_disc_signal(lv_obj_t * cpicker, lv_signal_t sign, voi ext->prev_value = ext->value; break; } - lv_cpicker_invalidate_indicator(cpicker); + lv_cpicker_invalidate(cpicker, false); } else if(sign == LV_SIGNAL_RELEASED) { @@ -1244,7 +1247,7 @@ static lv_res_t lv_cpicker_disc_signal(lv_obj_t * cpicker, lv_signal_t sign, voi break; } - lv_cpicker_invalidate_indicator(cpicker); + lv_cpicker_invalidate(cpicker, false); res = lv_event_send(cpicker, LV_EVENT_VALUE_CHANGED, NULL); if(res != LV_RES_OK) return res; @@ -1275,7 +1278,7 @@ static lv_res_t lv_cpicker_disc_signal(lv_obj_t * cpicker, lv_signal_t sign, voi ext->color_mode = (ext->color_mode + 1) % 3; - lv_obj_invalidate(cpicker); + lv_cpicker_invalidate(cpicker, true); } } } @@ -1297,7 +1300,7 @@ static lv_res_t lv_cpicker_disc_signal(lv_obj_t * cpicker, lv_signal_t sign, voi break; } - lv_cpicker_invalidate_indicator(cpicker); + lv_cpicker_invalidate(cpicker, false); res = lv_event_send(cpicker, LV_EVENT_VALUE_CHANGED, NULL); if(res != LV_RES_OK) return res; @@ -1317,7 +1320,7 @@ static lv_res_t lv_cpicker_disc_signal(lv_obj_t * cpicker, lv_signal_t sign, voi break; } - lv_cpicker_invalidate_indicator(cpicker); + lv_cpicker_invalidate(cpicker, false); res = lv_event_send(cpicker, LV_EVENT_VALUE_CHANGED, NULL); if(res != LV_RES_OK) return res; @@ -1337,7 +1340,7 @@ static lv_res_t lv_cpicker_disc_signal(lv_obj_t * cpicker, lv_signal_t sign, voi break; } - lv_cpicker_invalidate_indicator(cpicker); + lv_cpicker_invalidate(cpicker, false); res = lv_event_send(cpicker, LV_EVENT_VALUE_CHANGED, NULL); if(res != LV_RES_OK) return res; @@ -1357,7 +1360,7 @@ static lv_res_t lv_cpicker_disc_signal(lv_obj_t * cpicker, lv_signal_t sign, voi break; } - lv_cpicker_invalidate_indicator(cpicker); + lv_cpicker_invalidate(cpicker, false); res = lv_event_send(cpicker, LV_EVENT_VALUE_CHANGED, NULL); if(res != LV_RES_OK) return res; @@ -1432,7 +1435,7 @@ static lv_res_t lv_cpicker_rect_signal(lv_obj_t * cpicker, lv_signal_t sign, voi ext->prev_value = ext->value; break; } - lv_obj_invalidate(cpicker); + //lv_cpicker_invalidate(cpicker, false); } ext->last_click = lv_tick_get(); } @@ -1461,7 +1464,7 @@ static lv_res_t lv_cpicker_rect_signal(lv_obj_t * cpicker, lv_signal_t sign, voi ext->prev_value = ext->value; break; } - lv_obj_invalidate(cpicker); + lv_cpicker_invalidate(cpicker, false); } } else if(sign == LV_SIGNAL_PRESS_LOST) @@ -1478,7 +1481,7 @@ static lv_res_t lv_cpicker_rect_signal(lv_obj_t * cpicker, lv_signal_t sign, voi ext->prev_value = ext->value; break; } - lv_obj_invalidate(cpicker); + lv_cpicker_invalidate(cpicker, false); } else if(sign == LV_SIGNAL_RELEASED) { @@ -1505,7 +1508,7 @@ static lv_res_t lv_cpicker_rect_signal(lv_obj_t * cpicker, lv_signal_t sign, voi break; } - lv_obj_invalidate(cpicker); + lv_cpicker_invalidate(cpicker, false); res = lv_event_send(cpicker, LV_EVENT_VALUE_CHANGED, NULL); if(res != LV_RES_OK) return res; @@ -1533,7 +1536,8 @@ static lv_res_t lv_cpicker_rect_signal(lv_obj_t * cpicker, lv_signal_t sign, voi } ext->color_mode = (ext->color_mode + 1) % 3; - lv_obj_invalidate(cpicker); + + lv_cpicker_invalidate(cpicker, true); } } } @@ -1554,7 +1558,9 @@ static lv_res_t lv_cpicker_rect_signal(lv_obj_t * cpicker, lv_signal_t sign, voi ext->value = (ext->value + 1) % 100; break; } - lv_obj_invalidate(cpicker); + + lv_cpicker_invalidate(cpicker, false); + res = lv_event_send(cpicker, LV_EVENT_VALUE_CHANGED, NULL); if(res != LV_RES_OK) return res; } @@ -1572,7 +1578,9 @@ static lv_res_t lv_cpicker_rect_signal(lv_obj_t * cpicker, lv_signal_t sign, voi ext->value = ext->value > 0?(ext->value - 1):100; break; } - lv_obj_invalidate(cpicker); + + lv_cpicker_invalidate(cpicker, false); + res = lv_event_send(cpicker, LV_EVENT_VALUE_CHANGED, NULL); if(res != LV_RES_OK) return res; } @@ -1590,7 +1598,9 @@ static lv_res_t lv_cpicker_rect_signal(lv_obj_t * cpicker, lv_signal_t sign, voi ext->value = (ext->value + 1) % 100; break; } - lv_obj_invalidate(cpicker); + + lv_cpicker_invalidate(cpicker, false); + res = lv_event_send(cpicker, LV_EVENT_VALUE_CHANGED, NULL); if(res != LV_RES_OK) return res; } @@ -1608,7 +1618,9 @@ static lv_res_t lv_cpicker_rect_signal(lv_obj_t * cpicker, lv_signal_t sign, voi ext->value = ext->value > 0?(ext->value - 1):100; break; } - lv_obj_invalidate(cpicker); + + lv_cpicker_invalidate(cpicker, false); + res = lv_event_send(cpicker, LV_EVENT_VALUE_CHANGED, NULL); if(res != LV_RES_OK) return res; } @@ -1617,8 +1629,17 @@ static lv_res_t lv_cpicker_rect_signal(lv_obj_t * cpicker, lv_signal_t sign, voi return res; } -static void lv_cpicker_invalidate_indicator(lv_obj_t * cpicker) +/** + * Indicator points need to match those set in lv_cpicker_disc_design/lv_cpicker_rect_design + */ +static void lv_cpicker_invalidate(lv_obj_t * cpicker, bool all) { + if (all) + { + lv_obj_invalidate(cpicker); + return; + } + lv_disp_t * disp = lv_disp_get_default(); lv_cpicker_ext_t * ext = lv_obj_get_ext_attr(cpicker); @@ -1627,36 +1648,34 @@ static void lv_cpicker_invalidate_indicator(lv_obj_t * cpicker) static lv_style_t styleCopy; lv_style_copy(&styleCopy, style); - lv_coord_t r = (LV_MATH_MIN(lv_obj_get_width(cpicker), lv_obj_get_height(cpicker))) / 2; - lv_coord_t x = cpicker->coords.x1 + lv_obj_get_width(cpicker) / 2; - lv_coord_t y = cpicker->coords.y1 + lv_obj_get_height(cpicker) / 2; + lv_coord_t w = lv_obj_get_width(cpicker); + lv_coord_t h = lv_obj_get_height(cpicker); if(ext->type == LV_CPICKER_TYPE_DISC) { - /*invalidate center*/ - lv_area_t center_col_area; + lv_coord_t r = LV_MATH_MIN(w, h) / 2; + lv_coord_t x = cpicker->coords.x1 + w / 2; + lv_coord_t y = cpicker->coords.y1 + h / 2; + + /*invalidate center color area*/ + lv_area_t center_color_area; uint32_t rin = r - styleCopy.line.width; uint16_t radius = lv_sqrt((4*rin*rin)/2)/2 + 1 - style->body.padding.inner; - center_col_area.x1 = x - radius; - center_col_area.y1 = y - radius; - center_col_area.x2 = x + radius; - center_col_area.y2 = y + radius; + center_color_area.x1 = x - radius; + center_color_area.y1 = y - radius; + center_color_area.x2 = x + radius; + center_color_area.y2 = y + radius; - lv_inv_area(disp, ¢er_col_area); + lv_inv_area(disp, ¢er_color_area); - switch(ext->indicator.type) - { - case LV_CPICKER_INDICATOR_LINE: - { - lv_area_t line_area; - lv_point_t point1, point2; - lv_coord_t x1, y1, x2, y2; - uint16_t angle; + /*invalidate indicator*/ - switch(ext->color_mode) + uint16_t angle; + + switch(ext->color_mode) { default: case LV_CPICKER_COLOR_MODE_HUE: @@ -1667,8 +1686,16 @@ static void lv_cpicker_invalidate_indicator(lv_obj_t * cpicker) break; case LV_CPICKER_COLOR_MODE_VALUE: angle = ext->value * 360 / 100; - break; - } + break; + } + + switch(ext->indicator.type) + { + case LV_CPICKER_INDICATOR_LINE: + { + lv_area_t line_area; + lv_point_t point1, point2; + lv_coord_t x1, y1, x2, y2; x1 = x + ((r - style->line.width + ext->indicator.style->body.padding.inner + ext->indicator.style->line.width/2) * lv_trigo_sin(angle) >> LV_TRIGO_SHIFT); y1 = y + ((r - style->line.width + ext->indicator.style->body.padding.inner + ext->indicator.style->line.width/2) * lv_trigo_sin(angle + 90) >> LV_TRIGO_SHIFT); @@ -1716,7 +1743,8 @@ static void lv_cpicker_invalidate_indicator(lv_obj_t * cpicker) lv_inv_area(disp, &line_area); - angle = ext->prev_pos; + /* invalidate last postion */ + angle = ext->prev_angle; x1 = x + ((r - style->line.width + ext->indicator.style->body.padding.inner + ext->indicator.style->line.width/2) * lv_trigo_sin(angle) >> LV_TRIGO_SHIFT); y1 = y + ((r - style->line.width + ext->indicator.style->body.padding.inner + ext->indicator.style->line.width/2) * lv_trigo_sin(angle + 90) >> LV_TRIGO_SHIFT); @@ -1772,22 +1800,6 @@ static void lv_cpicker_invalidate_indicator(lv_obj_t * cpicker) lv_area_t circle_ind_area; uint32_t cx, cy; - uint16_t angle; - - switch(ext->color_mode) - { - default: - case LV_CPICKER_COLOR_MODE_HUE: - angle = ext->hue; - break; - case LV_CPICKER_COLOR_MODE_SATURATION: - angle = ext->saturation * 360 / 100; - break; - case LV_CPICKER_COLOR_MODE_VALUE: - angle = ext->value * 360 / 100; - break; - } - cx = x + ((r - style->line.width/2) * lv_trigo_sin(angle) >> LV_TRIGO_SHIFT); cy = y + ((r - style->line.width/2) * lv_trigo_sin(angle + 90) >> LV_TRIGO_SHIFT); @@ -1799,7 +1811,7 @@ static void lv_cpicker_invalidate_indicator(lv_obj_t * cpicker) lv_inv_area(disp, &circle_ind_area); /* invalidate last position*/ - angle = ext->prev_pos; + angle = ext->prev_angle; cx = x + ((r - style->line.width/2) * lv_trigo_sin(angle) >> LV_TRIGO_SHIFT); cy = y + ((r - style->line.width/2) * lv_trigo_sin(angle + 90) >> LV_TRIGO_SHIFT); @@ -1814,48 +1826,34 @@ static void lv_cpicker_invalidate_indicator(lv_obj_t * cpicker) } case LV_CPICKER_INDICATOR_IN: { + uint16_t wradius = r - style->line.width; + lv_area_t circle_ind_area; uint32_t cx, cy; - uint16_t angle; - - switch(ext->color_mode) - { - default: - case LV_CPICKER_COLOR_MODE_HUE: - angle = ext->hue; - break; - case LV_CPICKER_COLOR_MODE_SATURATION: - angle = ext->saturation * 360 / 100; - break; - case LV_CPICKER_COLOR_MODE_VALUE: - angle = ext->value * 360 / 100; - break; - } - uint16_t ind_radius = lv_sqrt((4*rin*rin)/2)/2 + 1 - style->body.padding.inner; ind_radius = (ind_radius + rin) / 2; cx = x + ((ind_radius) * lv_trigo_sin(angle) >> LV_TRIGO_SHIFT); cy = y + ((ind_radius) * lv_trigo_sin(angle + 90) >> LV_TRIGO_SHIFT); - circle_ind_area.x1 = cx - ext->indicator.style->line.width/2; - circle_ind_area.y1 = cy - ext->indicator.style->line.width/2; - circle_ind_area.x2 = cx + ext->indicator.style->line.width/2; - circle_ind_area.y2 = cy + ext->indicator.style->line.width/2; + circle_ind_area.x1 = cx - ((wradius - radius) / 3); + circle_ind_area.y1 = cy - ((wradius - radius) / 3); + circle_ind_area.x2 = cx + ((wradius - radius) / 3); + circle_ind_area.y2 = cy + ((wradius - radius) / 3); lv_inv_area(disp, &circle_ind_area); /* invalidate last position*/ - angle = ext->prev_pos; + angle = ext->prev_angle; cx = x + ((ind_radius) * lv_trigo_sin(angle) >> LV_TRIGO_SHIFT); cy = y + ((ind_radius) * lv_trigo_sin(angle + 90) >> LV_TRIGO_SHIFT); - circle_ind_area.x1 = cx - ext->indicator.style->line.width/2; - circle_ind_area.y1 = cy - ext->indicator.style->line.width/2; - circle_ind_area.x2 = cx + ext->indicator.style->line.width/2; - circle_ind_area.y2 = cy + ext->indicator.style->line.width/2; + circle_ind_area.x1 = cx - ((wradius - radius) / 3); + circle_ind_area.y1 = cy - ((wradius - radius) / 3); + circle_ind_area.x2 = cx + ((wradius - radius) / 3); + circle_ind_area.y2 = cy + ((wradius - radius) / 3); lv_inv_area(disp, &circle_ind_area); break; @@ -1864,7 +1862,7 @@ static void lv_cpicker_invalidate_indicator(lv_obj_t * cpicker) } else if(ext->type == LV_CPICKER_TYPE_RECT) { - + lv_obj_invalidate(cpicker); } } diff --git a/src/lv_objx/lv_cpicker.h b/src/lv_objx/lv_cpicker.h index a31aa55b1..926824bc3 100644 --- a/src/lv_objx/lv_cpicker.h +++ b/src/lv_objx/lv_cpicker.h @@ -43,7 +43,7 @@ typedef struct { uint16_t prev_hue; uint8_t prev_saturation; uint8_t prev_value; - uint16_t prev_pos; + uint16_t prev_angle; uint8_t color_mode:2; uint8_t color_mode_fixed:1; uint8_t type:1; From 93cef9e1219d5ceb00abc1bc1bf86d9cb1afd346 Mon Sep 17 00:00:00 2001 From: Paul Peavyhouse Date: Tue, 24 Sep 2019 18:48:57 -0700 Subject: [PATCH 08/82] Checkpoint of only **partially** working optimized invalidation :/ --- src/lv_objx/lv_cpicker.c | 166 ++++++++++++++++++++++++++++++++++++--- src/lv_objx/lv_cpicker.h | 2 +- 2 files changed, 156 insertions(+), 12 deletions(-) diff --git a/src/lv_objx/lv_cpicker.c b/src/lv_objx/lv_cpicker.c index 0ed005899..0d86cc523 100644 --- a/src/lv_objx/lv_cpicker.c +++ b/src/lv_objx/lv_cpicker.c @@ -675,7 +675,7 @@ static bool lv_cpicker_disc_design(lv_obj_t * cpicker, const lv_area_t * mask, l } /*save the angle to refresh the area later*/ - ext->prev_angle = angle; + ext->prev_pos = angle; start.x = x + ((r - style->line.width + ext->indicator.style->body.padding.inner + ext->indicator.style->line.width/2) * lv_trigo_sin(angle) >> LV_TRIGO_SHIFT); start.y = y + ((r - style->line.width + ext->indicator.style->body.padding.inner + ext->indicator.style->line.width/2) * lv_trigo_sin(angle + 90) >> LV_TRIGO_SHIFT); @@ -723,7 +723,7 @@ static bool lv_cpicker_disc_design(lv_obj_t * cpicker, const lv_area_t * mask, l } /*save the angle to refresh the area later*/ - ext->prev_angle = angle; + ext->prev_pos = angle; cx = x + ((r - style->line.width/2) * lv_trigo_sin(angle) >> LV_TRIGO_SHIFT); cy = y + ((r - style->line.width/2) * lv_trigo_sin(angle + 90) >> LV_TRIGO_SHIFT); @@ -761,7 +761,7 @@ static bool lv_cpicker_disc_design(lv_obj_t * cpicker, const lv_area_t * mask, l } /*save the angle to refresh the area later*/ - ext->prev_angle = angle; + ext->prev_pos = angle; uint16_t ind_radius = lv_sqrt((4*rin*rin)/2)/2 + 1 - style->body.padding.inner; ind_radius = (ind_radius + rin) / 2; @@ -1039,6 +1039,9 @@ static bool lv_cpicker_rect_design(lv_obj_t * cpicker, const lv_area_t * mask, l break; } + /*save to refresh the area later*/ + ext->prev_pos = ind_pos; + switch(ext->indicator.type) { case LV_CPICKER_INDICATOR_NONE: @@ -1075,18 +1078,18 @@ static bool lv_cpicker_rect_design(lv_obj_t * cpicker, const lv_area_t * mask, l lv_point_t triangle_points[3]; triangle_points[0].x = ext->rect_gradient_area.x1 + ind_pos; - triangle_points[0].y = ext->rect_gradient_area.y2 - (gradient_h/3); + triangle_points[0].y = ext->rect_gradient_area.y1 + (gradient_h/3); triangle_points[1].x = triangle_points[0].x - ext->indicator.style->line.width * 3; - triangle_points[1].y = ext->rect_gradient_area.y2; + triangle_points[1].y = ext->rect_gradient_area.y1 - 1; triangle_points[2].x = triangle_points[0].x + ext->indicator.style->line.width * 3; triangle_points[2].y = triangle_points[1].y; lv_draw_triangle(triangle_points, mask, ext->indicator.style, LV_OPA_COVER); - triangle_points[0].y = ext->rect_gradient_area.y1 + (gradient_h/3); - triangle_points[1].y = ext->rect_gradient_area.y1 - 1; + triangle_points[0].y = ext->rect_gradient_area.y2 - (gradient_h/3); + triangle_points[1].y = ext->rect_gradient_area.y2; triangle_points[2].y = triangle_points[1].y; lv_draw_triangle(triangle_points, mask, ext->indicator.style, LV_OPA_COVER); break; @@ -1744,7 +1747,7 @@ static void lv_cpicker_invalidate(lv_obj_t * cpicker, bool all) lv_inv_area(disp, &line_area); /* invalidate last postion */ - angle = ext->prev_angle; + angle = ext->prev_pos; x1 = x + ((r - style->line.width + ext->indicator.style->body.padding.inner + ext->indicator.style->line.width/2) * lv_trigo_sin(angle) >> LV_TRIGO_SHIFT); y1 = y + ((r - style->line.width + ext->indicator.style->body.padding.inner + ext->indicator.style->line.width/2) * lv_trigo_sin(angle + 90) >> LV_TRIGO_SHIFT); @@ -1811,7 +1814,7 @@ static void lv_cpicker_invalidate(lv_obj_t * cpicker, bool all) lv_inv_area(disp, &circle_ind_area); /* invalidate last position*/ - angle = ext->prev_angle; + angle = ext->prev_pos; cx = x + ((r - style->line.width/2) * lv_trigo_sin(angle) >> LV_TRIGO_SHIFT); cy = y + ((r - style->line.width/2) * lv_trigo_sin(angle + 90) >> LV_TRIGO_SHIFT); @@ -1845,7 +1848,7 @@ static void lv_cpicker_invalidate(lv_obj_t * cpicker, bool all) lv_inv_area(disp, &circle_ind_area); /* invalidate last position*/ - angle = ext->prev_angle; + angle = ext->prev_pos; cx = x + ((ind_radius) * lv_trigo_sin(angle) >> LV_TRIGO_SHIFT); cy = y + ((ind_radius) * lv_trigo_sin(angle + 90) >> LV_TRIGO_SHIFT); @@ -1862,7 +1865,148 @@ static void lv_cpicker_invalidate(lv_obj_t * cpicker, bool all) } else if(ext->type == LV_CPICKER_TYPE_RECT) { - lv_obj_invalidate(cpicker); + /*invalidate color preview area*/ + lv_inv_area(disp, &ext->rect_preview_area); + + lv_coord_t gradient_w, gradient_h; + + lv_coord_t x1 = cpicker->coords.x1; + lv_coord_t y1 = cpicker->coords.y1; + lv_coord_t x2 = cpicker->coords.x2; + lv_coord_t y2 = cpicker->coords.y2; + + uint16_t preview_offset = style->line.width; + + uint16_t style_body_padding_ver = style->body.padding.top + style->body.padding.bottom; + uint16_t style_body_padding_hor = style->body.padding.left + style->body.padding.right; + if(style_body_padding_ver == 0) + { + if(style_body_padding_hor >= 0) + { + gradient_w = w - preview_offset - (LV_MATH_ABS(style_body_padding_hor) - 1); + gradient_h = y2 - y1; + } + else + { + gradient_w = w - preview_offset - (LV_MATH_ABS(style_body_padding_hor) - 1); + gradient_h = y2 - y1; + } + } + else + { + if(style_body_padding_ver >= 0) + { + gradient_w = w; + gradient_h = (y2 - y1) - preview_offset - (LV_MATH_ABS(style_body_padding_ver) - 1); + } + else + { + gradient_w = w; + gradient_h = (y2 - y1) - preview_offset - (LV_MATH_ABS(style_body_padding_ver) - 1); + } + } + + lv_coord_t ind_pos = style->line.rounded ? gradient_h / 2 : 0; + switch(ext->color_mode) + { + default: + case LV_CPICKER_COLOR_MODE_HUE: + ind_pos += ext->hue * gradient_w / 360; + break; + case LV_CPICKER_COLOR_MODE_SATURATION: + ind_pos += ext->saturation * gradient_w / 100; + break; + case LV_CPICKER_COLOR_MODE_VALUE: + ind_pos += ext->value * gradient_w / 100; + break; + } + lv_coord_t prev_pos = ext->prev_pos; + + switch(ext->indicator.type) + { + case LV_CPICKER_INDICATOR_LINE: + { + lv_area_t line_area; + + lv_point_t p1, p2; + p1.x = ext->rect_gradient_area.x1 + ind_pos; + p1.y = ext->rect_gradient_area.y1; + p2.x = p1.x; + p2.y = ext->rect_gradient_area.y2; + + line_area.x1 = p1.x; + line_area.y1 = p1.y; + line_area.x2 = p2.x; + line_area.y2 = p2.x; + + line_area.x1 -= 2*ext->indicator.style->line.width; + line_area.y1 -= 2*ext->indicator.style->line.width; + line_area.x2 += 2*ext->indicator.style->line.width; + line_area.y2 += 2*ext->indicator.style->line.width; + + lv_inv_area(disp, &line_area); + + /* invalidate last postion */ + p1.x = ext->rect_gradient_area.x1 + prev_pos; + //p1.y = ext->rect_gradient_area.y1; + p2.x = p1.x; + //p2.y = ext->rect_gradient_area.y2; + + line_area.x1 = p1.x; + line_area.y1 = p1.y; + line_area.x2 = p2.x; + line_area.y2 = p2.x; + + line_area.x1 -= 2*ext->indicator.style->line.width; + line_area.y1 -= 2*ext->indicator.style->line.width; + line_area.x2 += 2*ext->indicator.style->line.width; + line_area.y2 += 2*ext->indicator.style->line.width; + + lv_inv_area(disp, &line_area); + break; + } + case LV_CPICKER_INDICATOR_CIRCLE: + { + lv_area_t circle_ind_area; + + circle_ind_area.x1 = ext->rect_gradient_area.x1 + ind_pos - gradient_h/2; + circle_ind_area.x2 = circle_ind_area.x1 + gradient_h; + circle_ind_area.y1 = ext->rect_gradient_area.y1; + circle_ind_area.y2 = ext->rect_gradient_area.y2; + + lv_inv_area(disp, &circle_ind_area); + + /* invalidate last postion */ + circle_ind_area.x1 = ext->rect_gradient_area.x1 + prev_pos - gradient_h/2; + circle_ind_area.x2 = circle_ind_area.x1 + gradient_h; + //circle_ind_area.y1 = ext->rect_gradient_area.y1; + //circle_ind_area.y2 = ext->rect_gradient_area.y2; + + lv_inv_area(disp, &circle_ind_area); + break; + } + case LV_CPICKER_INDICATOR_IN: + { + lv_coord_t center; + lv_area_t ind_area; + + center = ext->rect_gradient_area.x1 + ind_pos; + ind_area.x1 = center - ext->indicator.style->line.width * 3; + ind_area.y1 = ext->rect_gradient_area.y1 - 1; + ind_area.x2 = center + ext->indicator.style->line.width * 3; + ind_area.y2 = ext->rect_gradient_area.y2; + lv_inv_area(disp, &ind_area); + + /* invalidate last postion */ + center = ext->rect_gradient_area.x1 + prev_pos; + ind_area.x1 = center - ext->indicator.style->line.width * 3; + //ind_area.y1 = ext->rect_gradient_area.y1 - 1; + ind_area.x2 = center + ext->indicator.style->line.width * 3; + //ind_area.y2 = ext->rect_gradient_area.y2; + lv_inv_area(disp, &ind_area); + break; + } + } } } diff --git a/src/lv_objx/lv_cpicker.h b/src/lv_objx/lv_cpicker.h index 926824bc3..a31aa55b1 100644 --- a/src/lv_objx/lv_cpicker.h +++ b/src/lv_objx/lv_cpicker.h @@ -43,7 +43,7 @@ typedef struct { uint16_t prev_hue; uint8_t prev_saturation; uint8_t prev_value; - uint16_t prev_angle; + uint16_t prev_pos; uint8_t color_mode:2; uint8_t color_mode_fixed:1; uint8_t type:1; From c4e9f698681c6de1895ed127671d48a9fca05664 Mon Sep 17 00:00:00 2001 From: Paul Peavyhouse Date: Tue, 24 Sep 2019 21:06:51 -0700 Subject: [PATCH 09/82] Adding lv_cpicker_set_type --- src/lv_objx/lv_cpicker.c | 38 +++++++++++++++++++++++++++----------- src/lv_objx/lv_cpicker.h | 7 +++++++ 2 files changed, 34 insertions(+), 11 deletions(-) diff --git a/src/lv_objx/lv_cpicker.c b/src/lv_objx/lv_cpicker.c index 0d86cc523..1306ce5f0 100644 --- a/src/lv_objx/lv_cpicker.c +++ b/src/lv_objx/lv_cpicker.c @@ -118,19 +118,9 @@ lv_obj_t * lv_cpicker_create(lv_obj_t * par, const lv_obj_t * copy) ext->color_mode = LV_CPICKER_COLOR_MODE_HUE; ext->color_mode_fixed = 0; ext->last_click = 0; - ext->type = LV_CPICKER_DEF_TYPE; /*The signal and design functions are not copied so set them here*/ - if(ext->type == LV_CPICKER_TYPE_DISC) - { - lv_obj_set_signal_cb(new_cpicker, lv_cpicker_disc_signal); - lv_obj_set_design_cb(new_cpicker, lv_cpicker_disc_design); - } - else if(ext->type == LV_CPICKER_TYPE_RECT) - { - lv_obj_set_signal_cb(new_cpicker, lv_cpicker_rect_signal); - lv_obj_set_design_cb(new_cpicker, lv_cpicker_rect_design); - } + lv_cpicker_set_type(new_cpicker, LV_CPICKER_DEF_TYPE); /*If no copy do the basic initialization*/ if(copy == NULL) { @@ -158,6 +148,32 @@ lv_obj_t * lv_cpicker_create(lv_obj_t * par, const lv_obj_t * copy) * Setter functions *====================*/ +/** + * Set a new type for a cpicker + * @param cpicker pointer to a cpicker object + * @param type new type of the cpicker (from 'lv_cpicker_type_t' enum) + */ +void lv_cpicker_set_type(lv_obj_t * cpicker, lv_cpicker_type_t type) +{ + lv_cpicker_ext_t * ext = lv_obj_get_ext_attr(cpicker); + if(ext->type == type) return; + + ext->type = type; + + if(ext->type == LV_CPICKER_TYPE_DISC) + { + lv_obj_set_signal_cb(cpicker, lv_cpicker_disc_signal); + lv_obj_set_design_cb(cpicker, lv_cpicker_disc_design); + } + else if(ext->type == LV_CPICKER_TYPE_RECT) + { + lv_obj_set_signal_cb(cpicker, lv_cpicker_rect_signal); + lv_obj_set_design_cb(cpicker, lv_cpicker_rect_design); + } + + lv_obj_invalidate(cpicker); +} + /** * Set a style of a colorpicker. * @param cpicker pointer to colorpicker object diff --git a/src/lv_objx/lv_cpicker.h b/src/lv_objx/lv_cpicker.h index a31aa55b1..46847496e 100644 --- a/src/lv_objx/lv_cpicker.h +++ b/src/lv_objx/lv_cpicker.h @@ -96,6 +96,13 @@ lv_obj_t * lv_cpicker_create(lv_obj_t * par, const lv_obj_t * copy); * Setter functions *====================*/ +/** + * Set a new type for a colorpicker + * @param cpicker pointer to a colorpicker object + * @param type new type of the colorpicker (from 'lv_cpicker_type_t' enum) + */ +void lv_cpicker_set_type(lv_obj_t * chart, lv_cpicker_type_t type); + /** * Set a style of a colorpicker. * @param cpicker pointer to colorpicker object From 53a1188f7cabedea0f3ebb8c13a237447bdfc965 Mon Sep 17 00:00:00 2001 From: Paul Peavyhouse Date: Tue, 24 Sep 2019 21:10:23 -0700 Subject: [PATCH 10/82] Fixing `create` bug --- src/lv_objx/lv_cpicker.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/lv_objx/lv_cpicker.c b/src/lv_objx/lv_cpicker.c index 1306ce5f0..cd713de63 100644 --- a/src/lv_objx/lv_cpicker.c +++ b/src/lv_objx/lv_cpicker.c @@ -120,7 +120,16 @@ lv_obj_t * lv_cpicker_create(lv_obj_t * par, const lv_obj_t * copy) ext->last_click = 0; /*The signal and design functions are not copied so set them here*/ - lv_cpicker_set_type(new_cpicker, LV_CPICKER_DEF_TYPE); + if(ext->type == LV_CPICKER_TYPE_DISC) + { + lv_obj_set_signal_cb(new_cpicker, lv_cpicker_disc_signal); + lv_obj_set_design_cb(new_cpicker, lv_cpicker_disc_design); + } + else if(ext->type == LV_CPICKER_TYPE_RECT) + { + lv_obj_set_signal_cb(new_cpicker, lv_cpicker_rect_signal); + lv_obj_set_design_cb(new_cpicker, lv_cpicker_rect_design); + } /*If no copy do the basic initialization*/ if(copy == NULL) { From e9941eaf4c1848c34334e3c1a4b415f1c1f1cff9 Mon Sep 17 00:00:00 2001 From: Paul Peavyhouse Date: Wed, 25 Sep 2019 20:39:56 -0700 Subject: [PATCH 11/82] Persist gradient_w & gradient_h to ext Thought was that it would help invalidating, but it did not. Still, it helps to clean up the code a tad. --- src/lv_objx/lv_cpicker.c | 202 ++++++++++++++++++--------------------- src/lv_objx/lv_cpicker.h | 2 + 2 files changed, 97 insertions(+), 107 deletions(-) diff --git a/src/lv_objx/lv_cpicker.c b/src/lv_objx/lv_cpicker.c index cd713de63..eab301c7b 100644 --- a/src/lv_objx/lv_cpicker.c +++ b/src/lv_objx/lv_cpicker.c @@ -692,10 +692,10 @@ static bool lv_cpicker_disc_design(lv_obj_t * cpicker, const lv_area_t * mask, l angle = ext->hue; break; case LV_CPICKER_COLOR_MODE_SATURATION: - angle = ext->saturation * 360 / 100; + angle = ext->saturation / 100.0 * 360.0; break; case LV_CPICKER_COLOR_MODE_VALUE: - angle = ext->value * 360 / 100; + angle = ext->value / 100.0 * 360.0; break; } @@ -740,10 +740,10 @@ static bool lv_cpicker_disc_design(lv_obj_t * cpicker, const lv_area_t * mask, l angle = ext->hue; break; case LV_CPICKER_COLOR_MODE_SATURATION: - angle = ext->saturation * 360 / 100; + angle = ext->saturation / 100.0 * 360.0; break; case LV_CPICKER_COLOR_MODE_VALUE: - angle = ext->value * 360 / 100; + angle = ext->value / 100.0 * 360.0; break; } @@ -778,10 +778,10 @@ static bool lv_cpicker_disc_design(lv_obj_t * cpicker, const lv_area_t * mask, l angle = ext->hue; break; case LV_CPICKER_COLOR_MODE_SATURATION: - angle = ext->saturation * 360 / 100; + angle = ext->saturation / 100.0 * 360.0; break; case LV_CPICKER_COLOR_MODE_VALUE: - angle = ext->value * 360 / 100; + angle = ext->value / 100.0 * 360.0; break; } @@ -854,8 +854,6 @@ static bool lv_cpicker_rect_design(lv_obj_t * cpicker, const lv_area_t * mask, l lv_coord_t w = lv_obj_get_width(cpicker); lv_coord_t h = lv_obj_get_height(cpicker); - lv_coord_t gradient_w, gradient_h; - lv_coord_t x1 = cpicker->coords.x1; lv_coord_t y1 = cpicker->coords.y1; lv_coord_t x2 = cpicker->coords.x2; @@ -872,10 +870,10 @@ static bool lv_cpicker_rect_design(lv_obj_t * cpicker, const lv_area_t * mask, l if(style_body_padding_hor >= 0) { /*draw the preview to the right*/ - gradient_w = w - preview_offset - (LV_MATH_ABS(style_body_padding_hor) - 1); - gradient_h = y2 - y1; + ext->rect_gradient_w = w - preview_offset - (LV_MATH_ABS(style_body_padding_hor) - 1); + ext->rect_gradient_h = y2 - y1; ext->rect_gradient_area.x1 = x1; - ext->rect_gradient_area.x2 = ext->rect_gradient_area.x1 + gradient_w; + ext->rect_gradient_area.x2 = ext->rect_gradient_area.x1 + ext->rect_gradient_w; ext->rect_gradient_area.y1 = y1; ext->rect_gradient_area.y2 = y2; @@ -887,9 +885,9 @@ static bool lv_cpicker_rect_design(lv_obj_t * cpicker, const lv_area_t * mask, l else { /*draw the preview to the left*/ - gradient_w = w - preview_offset - (LV_MATH_ABS(style_body_padding_hor) - 1); - gradient_h = y2 - y1; - ext->rect_gradient_area.x1 = x2 - gradient_w; + ext->rect_gradient_w = w - preview_offset - (LV_MATH_ABS(style_body_padding_hor) - 1); + ext->rect_gradient_h = y2 - y1; + ext->rect_gradient_area.x1 = x2 - ext->rect_gradient_w; ext->rect_gradient_area.x2 = x2; ext->rect_gradient_area.y1 = y1; ext->rect_gradient_area.y2 = y2; @@ -906,11 +904,11 @@ static bool lv_cpicker_rect_design(lv_obj_t * cpicker, const lv_area_t * mask, l if(style_body_padding_ver >= 0) { /*draw the preview on top*/ - gradient_w = w; - gradient_h = (y2 - y1) - preview_offset - (LV_MATH_ABS(style_body_padding_ver) - 1); + ext->rect_gradient_w = w; + ext->rect_gradient_h = (y2 - y1) - preview_offset - (LV_MATH_ABS(style_body_padding_ver) - 1); ext->rect_gradient_area.x1 = x1; ext->rect_gradient_area.x2 = x2; - ext->rect_gradient_area.y1 = y2 - gradient_h; + ext->rect_gradient_area.y1 = y2 - ext->rect_gradient_h; ext->rect_gradient_area.y2 = y2; ext->rect_preview_area.x1 = x1; @@ -921,12 +919,12 @@ static bool lv_cpicker_rect_design(lv_obj_t * cpicker, const lv_area_t * mask, l else { /*draw the preview below the gradient*/ - gradient_w = w; - gradient_h = (y2 - y1) - preview_offset - (LV_MATH_ABS(style_body_padding_ver) - 1); + ext->rect_gradient_w = w; + ext->rect_gradient_h = (y2 - y1) - preview_offset - (LV_MATH_ABS(style_body_padding_ver) - 1); ext->rect_gradient_area.x1 = x1; ext->rect_gradient_area.x2 = x2; ext->rect_gradient_area.y1 = y1; - ext->rect_gradient_area.y2 = y1 + gradient_h; + ext->rect_gradient_area.y2 = y1 + ext->rect_gradient_h; ext->rect_preview_area.x1 = x1; ext->rect_preview_area.y1 = y2 - preview_offset; @@ -940,13 +938,13 @@ static bool lv_cpicker_rect_design(lv_obj_t * cpicker, const lv_area_t * mask, l /*draw rounded edges to the gradient*/ lv_area_t rounded_edge_area; rounded_edge_area.x1 = ext->rect_gradient_area.x1; - rounded_edge_area.x2 = ext->rect_gradient_area.x1 + gradient_h; + rounded_edge_area.x2 = ext->rect_gradient_area.x1 + ext->rect_gradient_h; rounded_edge_area.y1 = ext->rect_gradient_area.y1; rounded_edge_area.y2 = ext->rect_gradient_area.y2; - ext->rect_gradient_area.x1 += gradient_h/2; - ext->rect_gradient_area.x2 -= gradient_h/2; - gradient_w -= gradient_h; + ext->rect_gradient_area.x1 += ext->rect_gradient_h/2; + ext->rect_gradient_area.x2 -= ext->rect_gradient_h/2; + ext->rect_gradient_w -= ext->rect_gradient_h; switch(ext->color_mode) { @@ -967,8 +965,8 @@ static bool lv_cpicker_rect_design(lv_obj_t * cpicker, const lv_area_t * mask, l lv_draw_rect(&rounded_edge_area, mask, &styleCopy, opa_scale); - rounded_edge_area.x1 += gradient_w - 1; - rounded_edge_area.x2 += gradient_w - 1; + rounded_edge_area.x1 += ext->rect_gradient_w - 1; + rounded_edge_area.x2 += ext->rect_gradient_w - 1; switch(ext->color_mode) { @@ -988,7 +986,7 @@ static bool lv_cpicker_rect_design(lv_obj_t * cpicker, const lv_area_t * mask, l lv_draw_rect(&rounded_edge_area, mask, &styleCopy, opa_scale); } - for(uint16_t i = 0; i < 360; i += LV_MATH_MAX(LV_CPICKER_DEF_QF, 360/gradient_w)) + for(uint16_t i = 0; i < 360; i += LV_MATH_MAX(LV_CPICKER_DEF_QF, 360/ext->rect_gradient_w)) { switch(ext->color_mode) { @@ -1015,11 +1013,11 @@ static bool lv_cpicker_rect_design(lv_obj_t * cpicker, const lv_area_t * mask, l lv_area_t rect_area; /*scale angle (hue/sat/val) to linear coordinate*/ - lv_coord_t xi = i*gradient_w/360; + lv_coord_t xi = i / 360.0 * ext->rect_gradient_w; - rect_area.x1 = LV_MATH_MIN(ext->rect_gradient_area.x1 + xi, ext->rect_gradient_area.x1 + gradient_w - LV_MATH_MAX(LV_CPICKER_DEF_QF, 360/gradient_w)); + rect_area.x1 = LV_MATH_MIN(ext->rect_gradient_area.x1 + xi, ext->rect_gradient_area.x1 + ext->rect_gradient_w - LV_MATH_MAX(LV_CPICKER_DEF_QF, 360/ext->rect_gradient_w)); rect_area.y1 = ext->rect_gradient_area.y1; - rect_area.x2 = rect_area.x1 + LV_MATH_MAX(LV_CPICKER_DEF_QF, 360/gradient_w); + rect_area.x2 = rect_area.x1 + LV_MATH_MAX(LV_CPICKER_DEF_QF, 360/ext->rect_gradient_w); rect_area.y2 = ext->rect_gradient_area.y2; lv_draw_rect(&rect_area, mask, &styleCopy, opa_scale); @@ -1028,9 +1026,9 @@ static bool lv_cpicker_rect_design(lv_obj_t * cpicker, const lv_area_t * mask, l if(style->line.rounded) { /*Restore gradient area to take rounded end in account*/ - ext->rect_gradient_area.x1 -= gradient_h/2; - ext->rect_gradient_area.x2 += gradient_h/2; - //gradient_w += gradient_h; + ext->rect_gradient_area.x1 -= ext->rect_gradient_h/2; + ext->rect_gradient_area.x2 += ext->rect_gradient_h/2; + //ext->rect_gradient_w += ext->rect_gradient_h; } /*draw the color preview indicator*/ @@ -1038,29 +1036,29 @@ static bool lv_cpicker_rect_design(lv_obj_t * cpicker, const lv_area_t * mask, l styleCopy.body.grad_color = styleCopy.body.main_color; if(style->line.rounded && style_body_padding_hor == 0) { - styleCopy.body.radius = gradient_h; + styleCopy.body.radius = ext->rect_gradient_h; } lv_draw_rect(&(ext->rect_preview_area), mask, &styleCopy, opa_scale); /* styleCopy.line.width = 10; - lv_draw_arc(cpicker->coords.x1 + 3*gradient_h/2, cpicker->coords.y1 + gradient_h/2, gradient_h / 2 + styleCopy.line.width + 2, mask, 180, 360, &styleCopy, opa_scale); - //lv_draw_arc(cpicker->coords.x1 + gradient_w - gradient_h/2, cpicker->coords.y1 + gradient_h/2, gradient_h / 2 + styleCopy.line.width + 2, mask, 0, 180, &styleCopy, opa_scale); + lv_draw_arc(cpicker->coords.x1 + 3*ext->rect_gradient_h/2, cpicker->coords.y1 + ext->rect_gradient_h/2, ext->rect_gradient_h / 2 + styleCopy.line.width + 2, mask, 180, 360, &styleCopy, opa_scale); + //lv_draw_arc(cpicker->coords.x1 + ext->rect_gradient_w - ext->rect_gradient_h/2, cpicker->coords.y1 + ext->rect_gradient_h/2, ext->rect_gradient_h / 2 + styleCopy.line.width + 2, mask, 0, 180, &styleCopy, opa_scale); */ /*draw the color position indicator*/ - lv_coord_t ind_pos = style->line.rounded ? gradient_h / 2 : 0; + lv_coord_t ind_pos = style->line.rounded ? ext->rect_gradient_h / 2 : 0; switch(ext->color_mode) { default: case LV_CPICKER_COLOR_MODE_HUE: - ind_pos += ext->hue * gradient_w / 360; + ind_pos += ext->hue * ext->rect_gradient_w / 360.0; break; case LV_CPICKER_COLOR_MODE_SATURATION: - ind_pos += ext->saturation * gradient_w / 100; + ind_pos += ext->saturation * ext->rect_gradient_w / 100.0; break; case LV_CPICKER_COLOR_MODE_VALUE: - ind_pos += ext->value * gradient_w / 100; + ind_pos += ext->value * ext->rect_gradient_w / 100.0; break; } @@ -1086,8 +1084,8 @@ static bool lv_cpicker_rect_design(lv_obj_t * cpicker, const lv_area_t * mask, l case LV_CPICKER_INDICATOR_CIRCLE: { lv_area_t circle_ind_area; - circle_ind_area.x1 = ext->rect_gradient_area.x1 + ind_pos - gradient_h/2; - circle_ind_area.x2 = circle_ind_area.x1 + gradient_h; + circle_ind_area.x1 = ext->rect_gradient_area.x1 + ind_pos - ext->rect_gradient_h/2; + circle_ind_area.x2 = circle_ind_area.x1 + ext->rect_gradient_h; circle_ind_area.y1 = ext->rect_gradient_area.y1; circle_ind_area.y2 = ext->rect_gradient_area.y2; @@ -1103,7 +1101,7 @@ static bool lv_cpicker_rect_design(lv_obj_t * cpicker, const lv_area_t * mask, l lv_point_t triangle_points[3]; triangle_points[0].x = ext->rect_gradient_area.x1 + ind_pos; - triangle_points[0].y = ext->rect_gradient_area.y1 + (gradient_h/3); + triangle_points[0].y = ext->rect_gradient_area.y1 + (ext->rect_gradient_h/3); triangle_points[1].x = triangle_points[0].x - ext->indicator.style->line.width * 3; triangle_points[1].y = ext->rect_gradient_area.y1 - 1; @@ -1113,7 +1111,7 @@ static bool lv_cpicker_rect_design(lv_obj_t * cpicker, const lv_area_t * mask, l lv_draw_triangle(triangle_points, mask, ext->indicator.style, LV_OPA_COVER); - triangle_points[0].y = ext->rect_gradient_area.y2 - (gradient_h/3); + triangle_points[0].y = ext->rect_gradient_area.y2 - (ext->rect_gradient_h/3); triangle_points[1].y = ext->rect_gradient_area.y2; triangle_points[2].y = triangle_points[1].y; lv_draw_triangle(triangle_points, mask, ext->indicator.style, LV_OPA_COVER); @@ -1217,24 +1215,48 @@ static lv_res_t lv_cpicker_disc_signal(lv_obj_t * cpicker, lv_signal_t sign, voi if((xp*xp + yp*yp) < (r_out*r_out) && (xp*xp + yp*yp) >= (r_in*r_in)) { + bool changed = false; + uint16_t hsv; switch(ext->color_mode) { case LV_CPICKER_COLOR_MODE_HUE: - ext->hue = lv_atan2(xp, yp); - ext->prev_hue = ext->hue; + hsv = lv_atan2(xp, yp); + changed = hsv != ext->hue; + if (changed) + { + ext->hue = hsv; + ext->prev_hue = ext->hue; + } break; case LV_CPICKER_COLOR_MODE_SATURATION: - ext->saturation = lv_atan2(xp, yp) * 100.0 / 360.0; - ext->prev_saturation = ext->saturation; + hsv = lv_atan2(xp, yp) * 100.0 / 360.0; + changed = hsv != ext->hue; + if (changed) + { + ext->saturation = hsv; + ext->prev_saturation = ext->saturation; + } break; case LV_CPICKER_COLOR_MODE_VALUE: - ext->value = lv_atan2(xp, yp) * 100.0 / 360.0; - ext->prev_value = ext->value; + hsv = lv_atan2(xp, yp) * 100.0 / 360.0; + changed = hsv != ext->hue; + if (changed) + { + ext->value = hsv; + ext->prev_value = ext->value; + } break; } + + if (changed) + { lv_cpicker_invalidate(cpicker, false); + + res = lv_event_send(cpicker, LV_EVENT_VALUE_CHANGED, NULL); + if(res != LV_RES_OK) return res; } } + } else if(sign == LV_SIGNAL_PRESS_LOST) { switch(ext->color_mode) @@ -1480,7 +1502,7 @@ static lv_res_t lv_cpicker_rect_signal(lv_obj_t * cpicker, lv_signal_t sign, voi switch(ext->color_mode) { case LV_CPICKER_COLOR_MODE_HUE: - ext->hue = percent * 360; + ext->hue = percent * 360.0; ext->prev_hue = ext->hue; break; case LV_CPICKER_COLOR_MODE_SATURATION: @@ -1492,7 +1514,11 @@ static lv_res_t lv_cpicker_rect_signal(lv_obj_t * cpicker, lv_signal_t sign, voi ext->prev_value = ext->value; break; } + lv_cpicker_invalidate(cpicker, false); + + res = lv_event_send(cpicker, LV_EVENT_VALUE_CHANGED, NULL); + if(res != LV_RES_OK) return res; } } else if(sign == LV_SIGNAL_PRESS_LOST) @@ -1523,15 +1549,15 @@ static lv_res_t lv_cpicker_rect_signal(lv_obj_t * cpicker, lv_signal_t sign, voi switch(ext->color_mode) { case LV_CPICKER_COLOR_MODE_HUE: - ext->hue = percent * 360; + ext->hue = percent * 360.0; ext->prev_hue = ext->hue; break; case LV_CPICKER_COLOR_MODE_SATURATION: - ext->saturation = percent * 100; + ext->saturation = percent * 100.0; ext->prev_saturation = ext->saturation; break; case LV_CPICKER_COLOR_MODE_VALUE: - ext->value = percent * 100; + ext->value = percent * 100.0; ext->prev_value = ext->value; break; } @@ -1707,13 +1733,13 @@ static void lv_cpicker_invalidate(lv_obj_t * cpicker, bool all) { default: case LV_CPICKER_COLOR_MODE_HUE: - angle = ext->hue; - break; - case LV_CPICKER_COLOR_MODE_SATURATION: - angle = ext->saturation * 360 / 100; - break; - case LV_CPICKER_COLOR_MODE_VALUE: - angle = ext->value * 360 / 100; + angle = ext->hue; + break; + case LV_CPICKER_COLOR_MODE_SATURATION: + angle = ext->saturation / 100.0 * 360.0; + break; + case LV_CPICKER_COLOR_MODE_VALUE: + angle = ext->value / 100.0 * 360.0; break; } @@ -1893,56 +1919,18 @@ static void lv_cpicker_invalidate(lv_obj_t * cpicker, bool all) /*invalidate color preview area*/ lv_inv_area(disp, &ext->rect_preview_area); - lv_coord_t gradient_w, gradient_h; - - lv_coord_t x1 = cpicker->coords.x1; - lv_coord_t y1 = cpicker->coords.y1; - lv_coord_t x2 = cpicker->coords.x2; - lv_coord_t y2 = cpicker->coords.y2; - - uint16_t preview_offset = style->line.width; - - uint16_t style_body_padding_ver = style->body.padding.top + style->body.padding.bottom; - uint16_t style_body_padding_hor = style->body.padding.left + style->body.padding.right; - if(style_body_padding_ver == 0) - { - if(style_body_padding_hor >= 0) - { - gradient_w = w - preview_offset - (LV_MATH_ABS(style_body_padding_hor) - 1); - gradient_h = y2 - y1; - } - else - { - gradient_w = w - preview_offset - (LV_MATH_ABS(style_body_padding_hor) - 1); - gradient_h = y2 - y1; - } - } - else - { - if(style_body_padding_ver >= 0) - { - gradient_w = w; - gradient_h = (y2 - y1) - preview_offset - (LV_MATH_ABS(style_body_padding_ver) - 1); - } - else - { - gradient_w = w; - gradient_h = (y2 - y1) - preview_offset - (LV_MATH_ABS(style_body_padding_ver) - 1); - } - } - - lv_coord_t ind_pos = style->line.rounded ? gradient_h / 2 : 0; + lv_coord_t ind_pos = style->line.rounded ? ext->rect_gradient_h / 2 : 0; switch(ext->color_mode) { default: case LV_CPICKER_COLOR_MODE_HUE: - ind_pos += ext->hue * gradient_w / 360; + ind_pos += ext->hue / 360.0 * ext->rect_gradient_w; break; case LV_CPICKER_COLOR_MODE_SATURATION: - ind_pos += ext->saturation * gradient_w / 100; + ind_pos += ext->saturation / 100.0 * ext->rect_gradient_w; break; case LV_CPICKER_COLOR_MODE_VALUE: - ind_pos += ext->value * gradient_w / 100; + ind_pos += ext->value / 100.0 * ext->rect_gradient_w; break; } lv_coord_t prev_pos = ext->prev_pos; @@ -1994,16 +1982,16 @@ static void lv_cpicker_invalidate(lv_obj_t * cpicker, bool all) { lv_area_t circle_ind_area; - circle_ind_area.x1 = ext->rect_gradient_area.x1 + ind_pos - gradient_h/2; - circle_ind_area.x2 = circle_ind_area.x1 + gradient_h; + circle_ind_area.x1 = ext->rect_gradient_area.x1 + ind_pos - ext->rect_gradient_h/2; + circle_ind_area.x2 = circle_ind_area.x1 + ext->rect_gradient_h; circle_ind_area.y1 = ext->rect_gradient_area.y1; circle_ind_area.y2 = ext->rect_gradient_area.y2; lv_inv_area(disp, &circle_ind_area); /* invalidate last postion */ - circle_ind_area.x1 = ext->rect_gradient_area.x1 + prev_pos - gradient_h/2; - circle_ind_area.x2 = circle_ind_area.x1 + gradient_h; + circle_ind_area.x1 = ext->rect_gradient_area.x1 + prev_pos - ext->rect_gradient_h/2; + circle_ind_area.x2 = circle_ind_area.x1 + ext->rect_gradient_h; //circle_ind_area.y1 = ext->rect_gradient_area.y1; //circle_ind_area.y2 = ext->rect_gradient_area.y2; diff --git a/src/lv_objx/lv_cpicker.h b/src/lv_objx/lv_cpicker.h index 46847496e..406322579 100644 --- a/src/lv_objx/lv_cpicker.h +++ b/src/lv_objx/lv_cpicker.h @@ -50,6 +50,8 @@ typedef struct { uint32_t last_click; lv_area_t rect_preview_area; lv_area_t rect_gradient_area; + lv_coord_t rect_gradient_w; + lv_coord_t rect_gradient_h; } lv_cpicker_ext_t; /*Styles*/ From 46dead9ab9e02525d00845bfa1a98e47ea4353c7 Mon Sep 17 00:00:00 2001 From: Paul Peavyhouse Date: Wed, 25 Sep 2019 22:02:06 -0700 Subject: [PATCH 12/82] Consolidating all angle2color/color2angle calculations --- src/lv_objx/lv_cpicker.c | 154 +++++++++++++-------------------------- 1 file changed, 51 insertions(+), 103 deletions(-) diff --git a/src/lv_objx/lv_cpicker.c b/src/lv_objx/lv_cpicker.c index eab301c7b..b56693cb8 100644 --- a/src/lv_objx/lv_cpicker.c +++ b/src/lv_objx/lv_cpicker.c @@ -408,6 +408,44 @@ lv_color_t lv_cpicker_get_color(lv_obj_t * cpicker) * STATIC FUNCTIONS **********************/ +static lv_color_t angle_to_mode_color(lv_cpicker_ext_t * ext, uint16_t angle) +{ + lv_color_t color; + switch(ext->color_mode) + { + default: + case LV_CPICKER_COLOR_MODE_HUE: + color = lv_color_hsv_to_rgb(angle%360, ext->saturation, ext->value); + break; + case LV_CPICKER_COLOR_MODE_SATURATION: + color = lv_color_hsv_to_rgb(ext->hue, (angle%360)/360.0*100.0, ext->value); + break; + case LV_CPICKER_COLOR_MODE_VALUE: + color = lv_color_hsv_to_rgb(ext->hue, ext->saturation, (angle%360)/360.0*100.0); + break; + } + return color; +} + +static uint16_t mode_color_to_angle(lv_cpicker_ext_t * ext) +{ + uint16_t angle; + switch(ext->color_mode) + { + default: + case LV_CPICKER_COLOR_MODE_HUE: + angle = ext->hue; + break; + case LV_CPICKER_COLOR_MODE_SATURATION: + angle = ext->saturation / 100.0 * 360.0; + break; + case LV_CPICKER_COLOR_MODE_VALUE: + angle = ext->value / 100.0 * 360.0; + break; + } + return angle; +} + /** * Handle the drawing related tasks of the color_pickerwhen when wheel type * @param cpicker pointer to an object @@ -574,7 +612,8 @@ static bool lv_cpicker_disc_design(lv_obj_t * cpicker, const lv_area_t * mask, l { for(uint16_t i = start_angle; i <= end_angle; i+= LV_CPICKER_DEF_QF) { - styleCopy.body.main_color = lv_color_hsv_to_rgb(i%360, ext->saturation, ext->value); + styleCopy.body.main_color = angle_to_mode_color(ext, i); + styleCopy.body.grad_color = styleCopy.body.main_color; triangle_points[0].x = x; triangle_points[0].y = y; @@ -604,7 +643,8 @@ static bool lv_cpicker_disc_design(lv_obj_t * cpicker, const lv_area_t * mask, l { for(uint16_t i = start_angle; i <= end_angle; i += LV_CPICKER_DEF_QF) { - styleCopy.body.main_color = lv_color_hsv_to_rgb(ext->hue, (i%360)*100/360, ext->value); + styleCopy.body.main_color = angle_to_mode_color(ext, i); + styleCopy.body.grad_color = styleCopy.body.main_color; triangle_points[0].x = x; triangle_points[0].y = y; @@ -631,7 +671,8 @@ static bool lv_cpicker_disc_design(lv_obj_t * cpicker, const lv_area_t * mask, l { for(uint16_t i = start_angle; i <= end_angle; i += LV_CPICKER_DEF_QF) { - styleCopy.body.main_color = lv_color_hsv_to_rgb(ext->hue, ext->saturation, (i%360)*100/360); + styleCopy.body.main_color = angle_to_mode_color(ext, i); + styleCopy.body.grad_color = styleCopy.body.main_color; triangle_points[0].x = x; triangle_points[0].y = y; @@ -683,21 +724,7 @@ static bool lv_cpicker_disc_design(lv_obj_t * cpicker, const lv_area_t * mask, l lv_point_t start; lv_point_t end; - uint16_t angle; - - switch(ext->color_mode) - { - default: - case LV_CPICKER_COLOR_MODE_HUE: - angle = ext->hue; - break; - case LV_CPICKER_COLOR_MODE_SATURATION: - angle = ext->saturation / 100.0 * 360.0; - break; - case LV_CPICKER_COLOR_MODE_VALUE: - angle = ext->value / 100.0 * 360.0; - break; - } + uint16_t angle = mode_color_to_angle(ext); /*save the angle to refresh the area later*/ ext->prev_pos = angle; @@ -731,21 +758,7 @@ static bool lv_cpicker_disc_design(lv_obj_t * cpicker, const lv_area_t * mask, l lv_area_t circle_ind_area; uint32_t cx, cy; - uint16_t angle; - - switch(ext->color_mode) - { - default: - case LV_CPICKER_COLOR_MODE_HUE: - angle = ext->hue; - break; - case LV_CPICKER_COLOR_MODE_SATURATION: - angle = ext->saturation / 100.0 * 360.0; - break; - case LV_CPICKER_COLOR_MODE_VALUE: - angle = ext->value / 100.0 * 360.0; - break; - } + uint16_t angle = mode_color_to_angle(ext); /*save the angle to refresh the area later*/ ext->prev_pos = angle; @@ -769,21 +782,7 @@ static bool lv_cpicker_disc_design(lv_obj_t * cpicker, const lv_area_t * mask, l lv_area_t circle_ind_area; uint32_t cx, cy; - uint16_t angle; - - switch(ext->color_mode) - { - default: - case LV_CPICKER_COLOR_MODE_HUE: - angle = ext->hue; - break; - case LV_CPICKER_COLOR_MODE_SATURATION: - angle = ext->saturation / 100.0 * 360.0; - break; - case LV_CPICKER_COLOR_MODE_VALUE: - angle = ext->value / 100.0 * 360.0; - break; - } + uint16_t angle = mode_color_to_angle(ext); /*save the angle to refresh the area later*/ ext->prev_pos = angle; @@ -946,19 +945,7 @@ static bool lv_cpicker_rect_design(lv_obj_t * cpicker, const lv_area_t * mask, l ext->rect_gradient_area.x2 -= ext->rect_gradient_h/2; ext->rect_gradient_w -= ext->rect_gradient_h; - switch(ext->color_mode) - { - default: - case LV_CPICKER_COLOR_MODE_HUE: - styleCopy.body.main_color = lv_color_hsv_to_rgb(0, ext->saturation, ext->value); - break; - case LV_CPICKER_COLOR_MODE_SATURATION: - styleCopy.body.main_color = lv_color_hsv_to_rgb(ext->hue, 0, ext->value); - break; - case LV_CPICKER_COLOR_MODE_VALUE: - styleCopy.body.main_color = lv_color_hsv_to_rgb(ext->hue, ext->saturation, 0); - break; - } + styleCopy.body.main_color = angle_to_mode_color(ext, 0); styleCopy.body.grad_color = styleCopy.body.main_color; styleCopy.body.radius = LV_RADIUS_CIRCLE; @@ -968,19 +955,7 @@ static bool lv_cpicker_rect_design(lv_obj_t * cpicker, const lv_area_t * mask, l rounded_edge_area.x1 += ext->rect_gradient_w - 1; rounded_edge_area.x2 += ext->rect_gradient_w - 1; - switch(ext->color_mode) - { - default: - case LV_CPICKER_COLOR_MODE_HUE: - styleCopy.body.main_color = lv_color_hsv_to_rgb(360, ext->saturation, ext->value); - break; - case LV_CPICKER_COLOR_MODE_SATURATION: - styleCopy.body.main_color = lv_color_hsv_to_rgb(ext->hue, 100, ext->value); - break; - case LV_CPICKER_COLOR_MODE_VALUE: - styleCopy.body.main_color = lv_color_hsv_to_rgb(ext->hue, ext->saturation, 100); - break; - } + styleCopy.body.main_color = angle_to_mode_color(ext, 360); styleCopy.body.grad_color = styleCopy.body.main_color; lv_draw_rect(&rounded_edge_area, mask, &styleCopy, opa_scale); @@ -988,20 +963,7 @@ static bool lv_cpicker_rect_design(lv_obj_t * cpicker, const lv_area_t * mask, l for(uint16_t i = 0; i < 360; i += LV_MATH_MAX(LV_CPICKER_DEF_QF, 360/ext->rect_gradient_w)) { - switch(ext->color_mode) - { - default: - case LV_CPICKER_COLOR_MODE_HUE: - styleCopy.body.main_color = lv_color_hsv_to_rgb(i%360, ext->saturation, ext->value); - break; - case LV_CPICKER_COLOR_MODE_SATURATION: - styleCopy.body.main_color = lv_color_hsv_to_rgb(ext->hue, (i%360)*100/360, ext->value); - break; - case LV_CPICKER_COLOR_MODE_VALUE: - styleCopy.body.main_color = lv_color_hsv_to_rgb(ext->hue, ext->saturation, (i%360)*100/360); - break; - } - + styleCopy.body.main_color = angle_to_mode_color(ext, i); styleCopy.body.grad_color = styleCopy.body.main_color; /*the following attribute might need changing between index to add border, shadow, radius etc*/ @@ -1727,21 +1689,7 @@ static void lv_cpicker_invalidate(lv_obj_t * cpicker, bool all) /*invalidate indicator*/ - uint16_t angle; - - switch(ext->color_mode) - { - default: - case LV_CPICKER_COLOR_MODE_HUE: - angle = ext->hue; - break; - case LV_CPICKER_COLOR_MODE_SATURATION: - angle = ext->saturation / 100.0 * 360.0; - break; - case LV_CPICKER_COLOR_MODE_VALUE: - angle = ext->value / 100.0 * 360.0; - break; - } + uint16_t angle = mode_color_to_angle(ext); switch(ext->indicator.type) { From 8dcb1ff21c7c6138198a7673dcf5172229c5d104 Mon Sep 17 00:00:00 2001 From: Gabor Kiss-Vamosi Date: Thu, 26 Sep 2019 07:23:23 +0200 Subject: [PATCH 13/82] cpicker: fix line indicator artifact --- src/lv_objx/lv_cpicker.c | 50 +++++++++++----------------------------- 1 file changed, 14 insertions(+), 36 deletions(-) diff --git a/src/lv_objx/lv_cpicker.c b/src/lv_objx/lv_cpicker.c index b56693cb8..9cccfa13e 100644 --- a/src/lv_objx/lv_cpicker.c +++ b/src/lv_objx/lv_cpicker.c @@ -815,7 +815,7 @@ static bool lv_cpicker_disc_design(lv_obj_t * cpicker, const lv_area_t * mask, l style2.body.grad_color.full = c; c += 0x123445678; lv_draw_rect(mask, mask, &style2, opa_scale); - */ + */ } /*Post draw when the children are drawn*/ else if(mode == LV_DESIGN_DRAW_POST) { @@ -1006,7 +1006,7 @@ static bool lv_cpicker_rect_design(lv_obj_t * cpicker, const lv_area_t * mask, l styleCopy.line.width = 10; lv_draw_arc(cpicker->coords.x1 + 3*ext->rect_gradient_h/2, cpicker->coords.y1 + ext->rect_gradient_h/2, ext->rect_gradient_h / 2 + styleCopy.line.width + 2, mask, 180, 360, &styleCopy, opa_scale); //lv_draw_arc(cpicker->coords.x1 + ext->rect_gradient_w - ext->rect_gradient_h/2, cpicker->coords.y1 + ext->rect_gradient_h/2, ext->rect_gradient_h / 2 + styleCopy.line.width + 2, mask, 0, 180, &styleCopy, opa_scale); - */ + */ /*draw the color position indicator*/ lv_coord_t ind_pos = style->line.rounded ? ext->rect_gradient_h / 2 : 0; @@ -1212,13 +1212,13 @@ static lv_res_t lv_cpicker_disc_signal(lv_obj_t * cpicker, lv_signal_t sign, voi if (changed) { - lv_cpicker_invalidate(cpicker, false); + lv_cpicker_invalidate(cpicker, false); res = lv_event_send(cpicker, LV_EVENT_VALUE_CHANGED, NULL); if(res != LV_RES_OK) return res; + } } } - } else if(sign == LV_SIGNAL_PRESS_LOST) { switch(ext->color_mode) @@ -1672,7 +1672,7 @@ static void lv_cpicker_invalidate(lv_obj_t * cpicker, bool all) lv_coord_t r = LV_MATH_MIN(w, h) / 2; lv_coord_t x = cpicker->coords.x1 + w / 2; lv_coord_t y = cpicker->coords.y1 + h / 2; - + /*invalidate center color area*/ lv_area_t center_color_area; @@ -1889,39 +1889,17 @@ static void lv_cpicker_invalidate(lv_obj_t * cpicker, bool all) { lv_area_t line_area; - lv_point_t p1, p2; - p1.x = ext->rect_gradient_area.x1 + ind_pos; - p1.y = ext->rect_gradient_area.y1; - p2.x = p1.x; - p2.y = ext->rect_gradient_area.y2; - - line_area.x1 = p1.x; - line_area.y1 = p1.y; - line_area.x2 = p2.x; - line_area.y2 = p2.x; - - line_area.x1 -= 2*ext->indicator.style->line.width; - line_area.y1 -= 2*ext->indicator.style->line.width; - line_area.x2 += 2*ext->indicator.style->line.width; - line_area.y2 += 2*ext->indicator.style->line.width; + /*Invalidate the current position*/ + line_area.x1 = ext->rect_gradient_area.x1 + ind_pos - ext->indicator.style->line.width; + line_area.x2 = ext->rect_gradient_area.x1 + ind_pos + ext->indicator.style->line.width; + line_area.y1 = ext->rect_gradient_area.y1; + line_area.y2 = ext->rect_gradient_area.y2; lv_inv_area(disp, &line_area); - /* invalidate last postion */ - p1.x = ext->rect_gradient_area.x1 + prev_pos; - //p1.y = ext->rect_gradient_area.y1; - p2.x = p1.x; - //p2.y = ext->rect_gradient_area.y2; - - line_area.x1 = p1.x; - line_area.y1 = p1.y; - line_area.x2 = p2.x; - line_area.y2 = p2.x; - - line_area.x1 -= 2*ext->indicator.style->line.width; - line_area.y1 -= 2*ext->indicator.style->line.width; - line_area.x2 += 2*ext->indicator.style->line.width; - line_area.y2 += 2*ext->indicator.style->line.width; + /* Invalidate last position */ + line_area.x1 = ext->rect_gradient_area.x1 + prev_pos - ext->indicator.style->line.width; + line_area.x2 = ext->rect_gradient_area.x1 + prev_pos + ext->indicator.style->line.width; lv_inv_area(disp, &line_area); break; @@ -1950,7 +1928,7 @@ static void lv_cpicker_invalidate(lv_obj_t * cpicker, bool all) { lv_coord_t center; lv_area_t ind_area; - + center = ext->rect_gradient_area.x1 + ind_pos; ind_area.x1 = center - ext->indicator.style->line.width * 3; ind_area.y1 = ext->rect_gradient_area.y1 - 1; From 4d44d16b2e8097121e0c2bc58c413c5cb9de984a Mon Sep 17 00:00:00 2001 From: Paul Peavyhouse Date: Wed, 25 Sep 2019 23:16:12 -0700 Subject: [PATCH 14/82] Changing QF from 1 to 3 --- src/lv_objx/lv_cpicker.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lv_objx/lv_cpicker.c b/src/lv_objx/lv_cpicker.c index 9cccfa13e..a4198b1de 100644 --- a/src/lv_objx/lv_cpicker.c +++ b/src/lv_objx/lv_cpicker.c @@ -39,7 +39,7 @@ #endif #ifndef LV_CPICKER_DEF_QF /*quantization factor*/ -#define LV_CPICKER_DEF_QF 1 +#define LV_CPICKER_DEF_QF 3 #endif /*for rectangular mode the QF can be down to 1*/ From 8e7bd571afee07c67c12cfe10a74a6ab5526576c Mon Sep 17 00:00:00 2001 From: Paul Peavyhouse Date: Wed, 25 Sep 2019 23:38:27 -0700 Subject: [PATCH 15/82] Syncing... --- src/lv_objx/lv_cpicker.c | 57 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 57 insertions(+) diff --git a/src/lv_objx/lv_cpicker.c b/src/lv_objx/lv_cpicker.c index a4198b1de..fc7977902 100644 --- a/src/lv_objx/lv_cpicker.c +++ b/src/lv_objx/lv_cpicker.c @@ -446,6 +446,63 @@ static uint16_t mode_color_to_angle(lv_cpicker_ext_t * ext) return angle; } +static void draw_disk_indicator_line(lv_cpicker_ext_t * ext, lv_style_t * style, lv_area_t * mask, lv_opa_t opa_scale, + lv_coord_t r, lv_coord_t x, lv_coord_t y) +{ +} + +static void draw_disk_indicator_circle(lv_cpicker_ext_t * ext, lv_style_t * style, lv_area_t * mask, lv_opa_t opa_scale, + lv_coord_t r, lv_coord_t x, lv_coord_t y) +{ +} + +static void draw_disk_indicator_in(lv_cpicker_ext_t * ext, lv_style_t * style, lv_area_t * mask, lv_opa_t opa_scale, + lv_coord_t rin, lv_coord_t x, lv_coord_t y) +{ +} + +static void draw_disk_indicator(lv_cpicker_ext_t * ext, lv_style_t * style, lv_area_t * mask, lv_opa_t opa_scale, + lv_coord_t r, lv_coord_t x, lv_coord_t y, uint32_t rin) +{ +} + +static void draw_disk_spectrum(lv_cpicker_ext_t * ext, lv_style_t * style, lv_area_t * mask, lv_opa_t opa_scale, + lv_coord_t r, lv_coord_t x, lv_coord_t y) +{ +} + +static void draw_rect_indicator_line(lv_cpicker_ext_t * ext, lv_style_t * style, lv_area_t * mask, lv_opa_t opa_scale, + lv_coord_t gradient_w, lv_coord_t gradient_h, lv_area_t gradient_area, lv_coord_t ind_pos) +{ +} + +static void draw_rect_indicator_circle(lv_cpicker_ext_t * ext, lv_style_t * style, lv_area_t * mask, lv_opa_t opa_scale, + lv_coord_t gradient_w, lv_coord_t gradient_h, lv_area_t gradient_area, lv_coord_t ind_pos) +{ +} + +static void draw_rect_indicator_in(lv_cpicker_ext_t * ext, lv_style_t * style, lv_area_t * mask, lv_opa_t opa_scale, + lv_coord_t gradient_w, lv_coord_t gradient_h, lv_area_t gradient_area, lv_coord_t ind_pos) +{ +} + +static void draw_rect_indicator(lv_cpicker_ext_t * ext, lv_style_t * style, lv_area_t * mask, lv_opa_t opa_scale, + lv_coord_t gradient_w, lv_coord_t gradient_h, lv_area_t gradient_area) +{ +} + +static void calculate_preview_area(lv_style_t * style, + lv_coord_t * gradient_w, lv_coord_t * gradient_h, lv_area_t * gradient_area, lv_area_t * preview_area, + uint16_t * style_body_padding_ver, uint16_t * style_body_padding_hor, + lv_coord_t w, lv_coord_t h, lv_coord_t x1, lv_coord_t y1, lv_coord_t x2, lv_coord_t y2) +{ +} + +static void draw_rect_spectrum(lv_cpicker_ext_t * ext, lv_style_t * style, lv_area_t * mask, lv_opa_t opa_scale, + lv_coord_t w, lv_coord_t h, lv_coord_t x1, lv_coord_t y1, lv_coord_t x2, lv_coord_t y2) +{ +} + /** * Handle the drawing related tasks of the color_pickerwhen when wheel type * @param cpicker pointer to an object From d3962fc26c4273cf559b839e3f2194292ab507a2 Mon Sep 17 00:00:00 2001 From: Paul Peavyhouse Date: Thu, 26 Sep 2019 10:50:34 -0700 Subject: [PATCH 16/82] [Still] working cleanup checkpoint --- src/lv_objx/lv_cpicker.c | 481 +++++++++++++++++++-------------------- 1 file changed, 232 insertions(+), 249 deletions(-) diff --git a/src/lv_objx/lv_cpicker.c b/src/lv_objx/lv_cpicker.c index fc7977902..da1af94bc 100644 --- a/src/lv_objx/lv_cpicker.c +++ b/src/lv_objx/lv_cpicker.c @@ -64,11 +64,8 @@ /********************** * STATIC PROTOTYPES **********************/ -static bool lv_cpicker_disc_design(lv_obj_t * cpicker, const lv_area_t * mask, lv_design_mode_t mode); -static lv_res_t lv_cpicker_disc_signal(lv_obj_t * cpicker, lv_signal_t sign, void * param); - -static bool lv_cpicker_rect_design(lv_obj_t * cpicker, const lv_area_t * mask, lv_design_mode_t mode); -static lv_res_t lv_cpicker_rect_signal(lv_obj_t * cpicker, lv_signal_t sign, void * param); +static bool lv_cpicker_design(lv_obj_t * cpicker, const lv_area_t * mask, lv_design_mode_t mode); +static lv_res_t lv_cpicker_signal(lv_obj_t * cpicker, lv_signal_t sign, void * param); static void lv_cpicker_invalidate(lv_obj_t * cpicker, bool all); @@ -120,16 +117,8 @@ lv_obj_t * lv_cpicker_create(lv_obj_t * par, const lv_obj_t * copy) ext->last_click = 0; /*The signal and design functions are not copied so set them here*/ - if(ext->type == LV_CPICKER_TYPE_DISC) - { - lv_obj_set_signal_cb(new_cpicker, lv_cpicker_disc_signal); - lv_obj_set_design_cb(new_cpicker, lv_cpicker_disc_design); - } - else if(ext->type == LV_CPICKER_TYPE_RECT) - { - lv_obj_set_signal_cb(new_cpicker, lv_cpicker_rect_signal); - lv_obj_set_design_cb(new_cpicker, lv_cpicker_rect_design); - } + lv_obj_set_signal_cb(new_cpicker, lv_cpicker_signal); + lv_obj_set_design_cb(new_cpicker, lv_cpicker_design); /*If no copy do the basic initialization*/ if(copy == NULL) { @@ -169,17 +158,6 @@ void lv_cpicker_set_type(lv_obj_t * cpicker, lv_cpicker_type_t type) ext->type = type; - if(ext->type == LV_CPICKER_TYPE_DISC) - { - lv_obj_set_signal_cb(cpicker, lv_cpicker_disc_signal); - lv_obj_set_design_cb(cpicker, lv_cpicker_disc_design); - } - else if(ext->type == LV_CPICKER_TYPE_RECT) - { - lv_obj_set_signal_cb(cpicker, lv_cpicker_rect_signal); - lv_obj_set_design_cb(cpicker, lv_cpicker_rect_design); - } - lv_obj_invalidate(cpicker); } @@ -503,17 +481,22 @@ static void draw_rect_spectrum(lv_cpicker_ext_t * ext, lv_style_t * style, lv_ar { } +static bool lv_cpicker_disc_design(lv_obj_t * cpicker, const lv_area_t * mask, lv_design_mode_t mode, + lv_cpicker_ext_t * ext, lv_style_t * style); +static bool lv_cpicker_rect_design(lv_obj_t * cpicker, const lv_area_t * mask, lv_design_mode_t mode, + lv_cpicker_ext_t * ext, lv_style_t * style); + /** - * Handle the drawing related tasks of the color_pickerwhen when wheel type + * Handle the drawing related tasks of the color_picker * @param cpicker pointer to an object * @param mask the object will be drawn only in this area * @param mode LV_DESIGN_COVER_CHK: only check if the object fully covers the 'mask_p' area * (return 'true' if yes) * LV_DESIGN_DRAW: draw the object (always return 'true') * LV_DESIGN_DRAW_POST: drawing after every children are drawn - * @param return true/false, depends on 'mode' + * @return true/false, depends on 'mode' */ -static bool lv_cpicker_disc_design(lv_obj_t * cpicker, const lv_area_t * mask, lv_design_mode_t mode) +static bool lv_cpicker_design(lv_obj_t * cpicker, const lv_area_t * mask, lv_design_mode_t mode) { /*Return false if the object is not covers the mask_p area*/ if(mode == LV_DESIGN_COVER_CHK) { @@ -528,27 +511,47 @@ static bool lv_cpicker_disc_design(lv_obj_t * cpicker, const lv_area_t * mask, l static lv_style_t styleCopy; lv_style_copy(&styleCopy, style); - static lv_style_t styleCenterBackground; - lv_theme_t * th = lv_theme_get_current(); - if (th) { - lv_style_copy(&styleCenterBackground, th->style.bg); - } else { - lv_style_copy(&styleCenterBackground, &lv_style_plain); + if(ext->type == LV_CPICKER_TYPE_DISC) + { + return lv_cpicker_disc_design(cpicker, mask, mode, ext, &styleCopy); } + else if(ext->type == LV_CPICKER_TYPE_RECT) + { + return lv_cpicker_rect_design(cpicker, mask, mode, ext, &styleCopy); + } + } + /*Post draw when the children are drawn*/ + else if(mode == LV_DESIGN_DRAW_POST) { - lv_coord_t r = (LV_MATH_MIN(lv_obj_get_width(cpicker), lv_obj_get_height(cpicker))) / 2; - lv_coord_t x = cpicker->coords.x1 + lv_obj_get_width(cpicker) / 2; - lv_coord_t y = cpicker->coords.y1 + lv_obj_get_height(cpicker) / 2; - lv_opa_t opa_scale = lv_obj_get_opa_scale(cpicker); + } - uint8_t redraw_wheel = 0; + return true; +} - lv_area_t center_ind_area; +static bool lv_cpicker_disc_design(lv_obj_t * cpicker, const lv_area_t * mask, lv_design_mode_t mode, + lv_cpicker_ext_t * ext, lv_style_t * style) +{ + static lv_style_t styleCenterBackground; + lv_theme_t * th = lv_theme_get_current(); + if (th) { + lv_style_copy(&styleCenterBackground, th->style.bg); + } else { + lv_style_copy(&styleCenterBackground, &lv_style_plain); + } - uint32_t rin = r - styleCopy.line.width; - //the square area (a and b being sides) should fit into the center of diameter d - //we have: - //a^2+b^2<=d^2 + lv_coord_t r = (LV_MATH_MIN(lv_obj_get_width(cpicker), lv_obj_get_height(cpicker))) / 2; + lv_coord_t x = cpicker->coords.x1 + lv_obj_get_width(cpicker) / 2; + lv_coord_t y = cpicker->coords.y1 + lv_obj_get_height(cpicker) / 2; + lv_opa_t opa_scale = lv_obj_get_opa_scale(cpicker); + + uint8_t redraw_wheel = 0; + + lv_area_t center_ind_area; + + uint32_t rin = r - style->line.width; + //the square area (a and b being sides) should fit into the center of diameter d + //we have: + //a^2+b^2<=d^2 //2a^2 <= d^2 //a^2<=(d^2)/2 //a <= sqrt((d^2)/2) @@ -666,14 +669,14 @@ static bool lv_cpicker_disc_design(lv_obj_t * cpicker, const lv_area_t * mask, l } if(ext->color_mode == LV_CPICKER_COLOR_MODE_HUE) + { + for(uint16_t i = start_angle; i <= end_angle; i+= LV_CPICKER_DEF_QF) { - for(uint16_t i = start_angle; i <= end_angle; i+= LV_CPICKER_DEF_QF) - { - styleCopy.body.main_color = angle_to_mode_color(ext, i); - styleCopy.body.grad_color = styleCopy.body.main_color; + style->body.main_color = angle_to_mode_color(ext, i); + style->body.grad_color = style->body.main_color; - triangle_points[0].x = x; - triangle_points[0].y = y; + triangle_points[0].x = x; + triangle_points[0].y = y; triangle_points[1].x = x + (r * lv_trigo_sin(i) >> LV_TRIGO_SHIFT); triangle_points[1].y = y + (r * lv_trigo_sin(i + 90) >> LV_TRIGO_SHIFT); @@ -691,88 +694,88 @@ static bool lv_cpicker_disc_design(lv_obj_t * cpicker, const lv_area_t * mask, l triangle_points[2].x = x + (r * lv_trigo_sin(i + LV_CPICKER_DEF_QF + TRI_OFFSET) >> LV_TRIGO_SHIFT); triangle_points[2].y = y + (r * lv_trigo_sin(i + LV_CPICKER_DEF_QF + TRI_OFFSET + 90) >> LV_TRIGO_SHIFT); - } - - lv_draw_triangle(triangle_points, mask, &styleCopy, LV_OPA_COVER); } - } - else if(ext->color_mode == LV_CPICKER_COLOR_MODE_SATURATION) - { - for(uint16_t i = start_angle; i <= end_angle; i += LV_CPICKER_DEF_QF) - { - styleCopy.body.main_color = angle_to_mode_color(ext, i); - styleCopy.body.grad_color = styleCopy.body.main_color; - triangle_points[0].x = x; - triangle_points[0].y = y; - - triangle_points[1].x = x + (r * lv_trigo_sin(i) >> LV_TRIGO_SHIFT); - triangle_points[1].y = y + (r * lv_trigo_sin(i + 90) >> LV_TRIGO_SHIFT); - - if(i == end_angle || i == (360 - LV_CPICKER_DEF_QF)) - { - /*the last triangle is drawn without additional overlapping pixels*/ - triangle_points[2].x = x + (r * lv_trigo_sin(i + LV_CPICKER_DEF_QF) >> LV_TRIGO_SHIFT); - triangle_points[2].y = y + (r * lv_trigo_sin(i + LV_CPICKER_DEF_QF + 90) >> LV_TRIGO_SHIFT); - } - else - { - triangle_points[2].x = x + (r * lv_trigo_sin(i + LV_CPICKER_DEF_QF + TRI_OFFSET) >> LV_TRIGO_SHIFT); - triangle_points[2].y = y + (r * lv_trigo_sin(i + LV_CPICKER_DEF_QF + TRI_OFFSET + 90) >> LV_TRIGO_SHIFT); - } - - lv_draw_triangle(triangle_points, mask, &styleCopy, LV_OPA_COVER); - } - } - else if(ext->color_mode == LV_CPICKER_COLOR_MODE_VALUE) - { - for(uint16_t i = start_angle; i <= end_angle; i += LV_CPICKER_DEF_QF) - { - styleCopy.body.main_color = angle_to_mode_color(ext, i); - styleCopy.body.grad_color = styleCopy.body.main_color; - - triangle_points[0].x = x; - triangle_points[0].y = y; - - triangle_points[1].x = x + (r * lv_trigo_sin(i) >> LV_TRIGO_SHIFT); - triangle_points[1].y = y + (r * lv_trigo_sin(i + 90) >> LV_TRIGO_SHIFT); - - if(i == end_angle || i == (360 - LV_CPICKER_DEF_QF)) - { - /*the last triangle is drawn without additional overlapping pixels*/ - triangle_points[2].x = x + (r * lv_trigo_sin(i + LV_CPICKER_DEF_QF) >> LV_TRIGO_SHIFT); - triangle_points[2].y = y + (r * lv_trigo_sin(i + LV_CPICKER_DEF_QF + 90) >> LV_TRIGO_SHIFT); - - } - else - { - triangle_points[2].x = x + (r * lv_trigo_sin(i + LV_CPICKER_DEF_QF + TRI_OFFSET) >> LV_TRIGO_SHIFT); - triangle_points[2].y = y + (r * lv_trigo_sin(i + LV_CPICKER_DEF_QF + TRI_OFFSET + 90) >> LV_TRIGO_SHIFT); - } - - lv_draw_triangle(triangle_points, mask, &styleCopy, LV_OPA_COVER); - } + lv_draw_triangle(triangle_points, mask, style, LV_OPA_COVER); } } + else if(ext->color_mode == LV_CPICKER_COLOR_MODE_SATURATION) + { + for(uint16_t i = start_angle; i <= end_angle; i += LV_CPICKER_DEF_QF) + { + style->body.main_color = angle_to_mode_color(ext, i); + style->body.grad_color = style->body.main_color; - //draw center background - lv_area_t center_area; - uint16_t wradius = r - styleCopy.line.width; - center_area.x1 = x - wradius; - center_area.y1 = y - wradius; - center_area.x2 = x + wradius; + triangle_points[0].x = x; + triangle_points[0].y = y; + + triangle_points[1].x = x + (r * lv_trigo_sin(i) >> LV_TRIGO_SHIFT); + triangle_points[1].y = y + (r * lv_trigo_sin(i + 90) >> LV_TRIGO_SHIFT); + + if(i == end_angle || i == (360 - LV_CPICKER_DEF_QF)) + { + /*the last triangle is drawn without additional overlapping pixels*/ + triangle_points[2].x = x + (r * lv_trigo_sin(i + LV_CPICKER_DEF_QF) >> LV_TRIGO_SHIFT); + triangle_points[2].y = y + (r * lv_trigo_sin(i + LV_CPICKER_DEF_QF + 90) >> LV_TRIGO_SHIFT); + } + else + { + triangle_points[2].x = x + (r * lv_trigo_sin(i + LV_CPICKER_DEF_QF + TRI_OFFSET) >> LV_TRIGO_SHIFT); + triangle_points[2].y = y + (r * lv_trigo_sin(i + LV_CPICKER_DEF_QF + TRI_OFFSET + 90) >> LV_TRIGO_SHIFT); + } + + lv_draw_triangle(triangle_points, mask, style, LV_OPA_COVER); + } + } + else if(ext->color_mode == LV_CPICKER_COLOR_MODE_VALUE) + { + for(uint16_t i = start_angle; i <= end_angle; i += LV_CPICKER_DEF_QF) + { + style->body.main_color = angle_to_mode_color(ext, i); + style->body.grad_color = style->body.main_color; + + triangle_points[0].x = x; + triangle_points[0].y = y; + + triangle_points[1].x = x + (r * lv_trigo_sin(i) >> LV_TRIGO_SHIFT); + triangle_points[1].y = y + (r * lv_trigo_sin(i + 90) >> LV_TRIGO_SHIFT); + + if(i == end_angle || i == (360 - LV_CPICKER_DEF_QF)) + { + /*the last triangle is drawn without additional overlapping pixels*/ + triangle_points[2].x = x + (r * lv_trigo_sin(i + LV_CPICKER_DEF_QF) >> LV_TRIGO_SHIFT); + triangle_points[2].y = y + (r * lv_trigo_sin(i + LV_CPICKER_DEF_QF + 90) >> LV_TRIGO_SHIFT); + + } + else + { + triangle_points[2].x = x + (r * lv_trigo_sin(i + LV_CPICKER_DEF_QF + TRI_OFFSET) >> LV_TRIGO_SHIFT); + triangle_points[2].y = y + (r * lv_trigo_sin(i + LV_CPICKER_DEF_QF + TRI_OFFSET + 90) >> LV_TRIGO_SHIFT); + } + + lv_draw_triangle(triangle_points, mask, style, LV_OPA_COVER); + } + } + } + + //draw center background + lv_area_t center_area; + uint16_t wradius = r - style->line.width; + center_area.x1 = x - wradius; + center_area.y1 = y - wradius; + center_area.x2 = x + wradius; center_area.y2 = y + wradius; styleCenterBackground.body.radius = LV_RADIUS_CIRCLE; - lv_draw_rect(¢er_area, mask, &styleCenterBackground, opa_scale); + lv_draw_rect(¢er_area, mask, &styleCenterBackground, opa_scale); - //draw the center color indicator - styleCopy.body.main_color = lv_color_hsv_to_rgb(ext->hue, ext->saturation, ext->value); - styleCopy.body.grad_color = styleCopy.body.main_color; - styleCopy.body.radius = LV_RADIUS_CIRCLE; - lv_draw_rect(¢er_ind_area, mask, &styleCopy, opa_scale); + //draw the center color indicator + style->body.main_color = lv_color_hsv_to_rgb(ext->hue, ext->saturation, ext->value); + style->body.grad_color = style->body.main_color; + style->body.radius = LV_RADIUS_CIRCLE; + lv_draw_rect(¢er_ind_area, mask, style, opa_scale); - //Draw the current hue indicator - switch(ext->indicator.type) + //Draw the current hue indicator + switch(ext->indicator.type) { case LV_CPICKER_INDICATOR_NONE: break; @@ -825,11 +828,12 @@ static bool lv_cpicker_disc_design(lv_obj_t * cpicker, const lv_area_t * mask, l circle_ind_area.x1 = cx - style->line.width/2; circle_ind_area.y1 = cy - style->line.width/2; - circle_ind_area.x2 = cx + style->line.width/2; - circle_ind_area.y2 = cy + style->line.width/2; + circle_ind_area.x2 = cx + style->line.width/2; + circle_ind_area.y2 = cy + style->line.width/2; - lv_style_copy(&styleCopy, ext->indicator.style); - styleCopy.body.radius = LV_RADIUS_CIRCLE; + lv_style_t styleCopy; + lv_style_copy(&styleCopy, ext->indicator.style); + styleCopy.body.radius = LV_RADIUS_CIRCLE; lv_draw_rect(&circle_ind_area, mask, &styleCopy, opa_scale); break; @@ -852,11 +856,12 @@ static bool lv_cpicker_disc_design(lv_obj_t * cpicker, const lv_area_t * mask, l circle_ind_area.x1 = cx - ((wradius - radius) / 3); circle_ind_area.y1 = cy - ((wradius - radius) / 3); - circle_ind_area.x2 = cx + ((wradius - radius) / 3); - circle_ind_area.y2 = cy + ((wradius - radius) / 3); + circle_ind_area.x2 = cx + ((wradius - radius) / 3); + circle_ind_area.y2 = cy + ((wradius - radius) / 3); - lv_style_copy(&styleCopy, ext->indicator.style); - styleCopy.body.radius = LV_RADIUS_CIRCLE; + lv_style_t styleCopy; + lv_style_copy(&styleCopy, ext->indicator.style); + styleCopy.body.radius = LV_RADIUS_CIRCLE; lv_draw_rect(&circle_ind_area, mask, &styleCopy, opa_scale); break; @@ -870,45 +875,18 @@ static bool lv_cpicker_disc_design(lv_obj_t * cpicker, const lv_area_t * mask, l lv_style_copy(&style2, &lv_style_plain); style2.body.main_color.full = c; style2.body.grad_color.full = c; - c += 0x123445678; - lv_draw_rect(mask, mask, &style2, opa_scale); - */ - } - /*Post draw when the children are drawn*/ - else if(mode == LV_DESIGN_DRAW_POST) { - - } - + c += 0x123445678; + lv_draw_rect(mask, mask, &style2, opa_scale); + */ + return true; } -/** - * Handle the drawing related tasks of the color_pickerwhen of rectangle type - * @param cpicker pointer to an object - * @param mask the object will be drawn only in this area - * @param mode LV_DESIGN_COVER_CHK: only check if the object fully covers the 'mask_p' area - * (return 'true' if yes) - * LV_DESIGN_DRAW: draw the object (always return 'true') - * LV_DESIGN_DRAW_POST: drawing after every children are drawn - * @param return true/false, depends on 'mode' - */ -static bool lv_cpicker_rect_design(lv_obj_t * cpicker, const lv_area_t * mask, lv_design_mode_t mode) +static bool lv_cpicker_rect_design(lv_obj_t * cpicker, const lv_area_t * mask, lv_design_mode_t mode, + lv_cpicker_ext_t * ext, lv_style_t * style) { - /*Return false if the object is not covers the mask_p area*/ - if(mode == LV_DESIGN_COVER_CHK) { - return false; - } - /*Draw the object*/ - else if(mode == LV_DESIGN_DRAW_MAIN) { - - lv_cpicker_ext_t * ext = lv_obj_get_ext_attr(cpicker); - lv_style_t * style = lv_cpicker_get_style(cpicker, LV_CPICKER_STYLE_MAIN); - - static lv_style_t styleCopy; - lv_style_copy(&styleCopy, style); - - lv_coord_t w = lv_obj_get_width(cpicker); - lv_coord_t h = lv_obj_get_height(cpicker); + lv_coord_t w = lv_obj_get_width(cpicker); + lv_coord_t h = lv_obj_get_height(cpicker); lv_coord_t x1 = cpicker->coords.x1; lv_coord_t y1 = cpicker->coords.y1; @@ -999,68 +977,68 @@ static bool lv_cpicker_rect_design(lv_obj_t * cpicker, const lv_area_t * mask, l rounded_edge_area.y2 = ext->rect_gradient_area.y2; ext->rect_gradient_area.x1 += ext->rect_gradient_h/2; - ext->rect_gradient_area.x2 -= ext->rect_gradient_h/2; - ext->rect_gradient_w -= ext->rect_gradient_h; + ext->rect_gradient_area.x2 -= ext->rect_gradient_h/2; + ext->rect_gradient_w -= ext->rect_gradient_h; - styleCopy.body.main_color = angle_to_mode_color(ext, 0); - styleCopy.body.grad_color = styleCopy.body.main_color; + style->body.main_color = angle_to_mode_color(ext, 0); + style->body.grad_color = style->body.main_color; - styleCopy.body.radius = LV_RADIUS_CIRCLE; + style->body.radius = LV_RADIUS_CIRCLE; - lv_draw_rect(&rounded_edge_area, mask, &styleCopy, opa_scale); + lv_draw_rect(&rounded_edge_area, mask, style, opa_scale); - rounded_edge_area.x1 += ext->rect_gradient_w - 1; - rounded_edge_area.x2 += ext->rect_gradient_w - 1; + rounded_edge_area.x1 += ext->rect_gradient_w - 1; + rounded_edge_area.x2 += ext->rect_gradient_w - 1; - styleCopy.body.main_color = angle_to_mode_color(ext, 360); - styleCopy.body.grad_color = styleCopy.body.main_color; + style->body.main_color = angle_to_mode_color(ext, 360); + style->body.grad_color = style->body.main_color; - lv_draw_rect(&rounded_edge_area, mask, &styleCopy, opa_scale); - } + lv_draw_rect(&rounded_edge_area, mask, style, opa_scale); + } - for(uint16_t i = 0; i < 360; i += LV_MATH_MAX(LV_CPICKER_DEF_QF, 360/ext->rect_gradient_w)) - { - styleCopy.body.main_color = angle_to_mode_color(ext, i); - styleCopy.body.grad_color = styleCopy.body.main_color; + for(uint16_t i = 0; i < 360; i += LV_MATH_MAX(LV_CPICKER_DEF_QF, 360/ext->rect_gradient_w)) + { + style->body.main_color = angle_to_mode_color(ext, i); + style->body.grad_color = style->body.main_color; - /*the following attribute might need changing between index to add border, shadow, radius etc*/ - styleCopy.body.radius = 0; - styleCopy.body.border.width = 0; - styleCopy.body.shadow.width = 0; - styleCopy.body.opa = LV_OPA_COVER; + /*the following attribute might need changing between index to add border, shadow, radius etc*/ + style->body.radius = 0; + style->body.border.width = 0; + style->body.shadow.width = 0; + style->body.opa = LV_OPA_COVER; - lv_area_t rect_area; + lv_area_t rect_area; /*scale angle (hue/sat/val) to linear coordinate*/ lv_coord_t xi = i / 360.0 * ext->rect_gradient_w; rect_area.x1 = LV_MATH_MIN(ext->rect_gradient_area.x1 + xi, ext->rect_gradient_area.x1 + ext->rect_gradient_w - LV_MATH_MAX(LV_CPICKER_DEF_QF, 360/ext->rect_gradient_w)); rect_area.y1 = ext->rect_gradient_area.y1; - rect_area.x2 = rect_area.x1 + LV_MATH_MAX(LV_CPICKER_DEF_QF, 360/ext->rect_gradient_w); - rect_area.y2 = ext->rect_gradient_area.y2; + rect_area.x2 = rect_area.x1 + LV_MATH_MAX(LV_CPICKER_DEF_QF, 360/ext->rect_gradient_w); + rect_area.y2 = ext->rect_gradient_area.y2; - lv_draw_rect(&rect_area, mask, &styleCopy, opa_scale); - } + lv_draw_rect(&rect_area, mask, style, opa_scale); + } - if(style->line.rounded) + if(style->line.rounded) { /*Restore gradient area to take rounded end in account*/ ext->rect_gradient_area.x1 -= ext->rect_gradient_h/2; ext->rect_gradient_area.x2 += ext->rect_gradient_h/2; //ext->rect_gradient_w += ext->rect_gradient_h; - } + } - /*draw the color preview indicator*/ - styleCopy.body.main_color = lv_cpicker_get_color(cpicker); - styleCopy.body.grad_color = styleCopy.body.main_color; - if(style->line.rounded && style_body_padding_hor == 0) - { - styleCopy.body.radius = ext->rect_gradient_h; - } - lv_draw_rect(&(ext->rect_preview_area), mask, &styleCopy, opa_scale); + /*draw the color preview indicator*/ + style->body.main_color = lv_cpicker_get_color(cpicker); + style->body.grad_color = style->body.main_color; + if(style->line.rounded && style_body_padding_hor == 0) + { + style->body.radius = ext->rect_gradient_h; + } + lv_draw_rect(&(ext->rect_preview_area), mask, style, opa_scale); - /* - styleCopy.line.width = 10; + /* + styleCopy.line.width = 10; lv_draw_arc(cpicker->coords.x1 + 3*ext->rect_gradient_h/2, cpicker->coords.y1 + ext->rect_gradient_h/2, ext->rect_gradient_h / 2 + styleCopy.line.width + 2, mask, 180, 360, &styleCopy, opa_scale); //lv_draw_arc(cpicker->coords.x1 + ext->rect_gradient_w - ext->rect_gradient_h/2, cpicker->coords.y1 + ext->rect_gradient_h/2, ext->rect_gradient_h / 2 + styleCopy.line.width + 2, mask, 0, 180, &styleCopy, opa_scale); */ @@ -1105,16 +1083,16 @@ static bool lv_cpicker_rect_design(lv_obj_t * cpicker, const lv_area_t * mask, l lv_area_t circle_ind_area; circle_ind_area.x1 = ext->rect_gradient_area.x1 + ind_pos - ext->rect_gradient_h/2; circle_ind_area.x2 = circle_ind_area.x1 + ext->rect_gradient_h; - circle_ind_area.y1 = ext->rect_gradient_area.y1; - circle_ind_area.y2 = ext->rect_gradient_area.y2; + circle_ind_area.y1 = ext->rect_gradient_area.y1; + circle_ind_area.y2 = ext->rect_gradient_area.y2; - lv_style_copy(&styleCopy, ext->indicator.style); - styleCopy.body.radius = LV_RADIUS_CIRCLE; + lv_style_copy(style, ext->indicator.style); + style->body.radius = LV_RADIUS_CIRCLE; - lv_draw_rect(&circle_ind_area, mask, &styleCopy, opa_scale); - break; - } - case LV_CPICKER_INDICATOR_IN: + lv_draw_rect(&circle_ind_area, mask, style, opa_scale); + break; + } + case LV_CPICKER_INDICATOR_IN: { /*draw triangle under the gradient*/ lv_point_t triangle_points[3]; @@ -1138,41 +1116,28 @@ static bool lv_cpicker_rect_design(lv_obj_t * cpicker, const lv_area_t * mask, l } default: break; - } - } - /*Post draw when the children are drawn*/ - else if(mode == LV_DESIGN_DRAW_POST) { - } return true; } + +static lv_res_t lv_cpicker_disc_signal(lv_obj_t * cpicker, lv_signal_t sign, void * param); +static lv_res_t lv_cpicker_rect_signal(lv_obj_t * cpicker, lv_signal_t sign, void * param); + /** - * Signal function of the color_picker of wheel type + * Signal function of the color_picker * @param cpicker pointer to a color_picker object * @param sign a signal type from lv_signal_t enum * @param param pointer to a signal specific variable * @return LV_RES_OK: the object is not deleted in the function; LV_RES_INV: the object is deleted */ -static lv_res_t lv_cpicker_disc_signal(lv_obj_t * cpicker, lv_signal_t sign, void * param) +static lv_res_t lv_cpicker_signal(lv_obj_t * cpicker, lv_signal_t sign, void * param) { - lv_cpicker_ext_t * ext = lv_obj_get_ext_attr(cpicker); - - lv_res_t res; - /* Include the ancient signal function */ - res = ancestor_signal(cpicker, sign, param); + lv_res_t res = ancestor_signal(cpicker, sign, param); if(res != LV_RES_OK) return res; - lv_style_t * style = lv_cpicker_get_style(cpicker, LV_CPICKER_STYLE_MAIN); - - lv_coord_t r_out = (LV_MATH_MIN(lv_obj_get_width(cpicker), lv_obj_get_height(cpicker))) / 2; - lv_coord_t r_in = r_out - style->line.width - style->body.padding.inner; - - lv_coord_t x = cpicker->coords.x1 + lv_obj_get_width(cpicker) / 2; - lv_coord_t y = cpicker->coords.y1 + lv_obj_get_height(cpicker) / 2; - if(sign == LV_SIGNAL_CLEANUP) { /*Nothing to cleanup. (No dynamically allocated memory in 'ext')*/ } else if(sign == LV_SIGNAL_GET_TYPE) { @@ -1182,8 +1147,40 @@ static lv_res_t lv_cpicker_disc_signal(lv_obj_t * cpicker, lv_signal_t sign, voi if(buf->type[i] == NULL) break; } buf->type[i] = "lv_cpicker"; + } else { + lv_cpicker_ext_t * ext = lv_obj_get_ext_attr(cpicker); + lv_style_t * style = lv_cpicker_get_style(cpicker, LV_CPICKER_STYLE_MAIN); + + if(ext->type == LV_CPICKER_TYPE_DISC) + { + res = lv_cpicker_disc_signal(cpicker, sign, param); + if(res != LV_RES_OK) return res; + } + else if(ext->type == LV_CPICKER_TYPE_RECT) + { + res = lv_cpicker_rect_signal(cpicker, sign, param); + if(res != LV_RES_OK) return res; + } } - else if(sign == LV_SIGNAL_PRESSED) + + return res; +} + +static lv_res_t lv_cpicker_disc_signal(lv_obj_t * cpicker, lv_signal_t sign, void * param) +{ + lv_cpicker_ext_t * ext = lv_obj_get_ext_attr(cpicker); + + lv_res_t res; + + lv_style_t * style = lv_cpicker_get_style(cpicker, LV_CPICKER_STYLE_MAIN); + + lv_coord_t r_out = (LV_MATH_MIN(lv_obj_get_width(cpicker), lv_obj_get_height(cpicker))) / 2; + lv_coord_t r_in = r_out - style->line.width - style->body.padding.inner; + + lv_coord_t x = cpicker->coords.x1 + lv_obj_get_width(cpicker) / 2; + lv_coord_t y = cpicker->coords.y1 + lv_obj_get_height(cpicker) / 2; + + if(sign == LV_SIGNAL_PRESSED) { switch(ext->color_mode) { @@ -1452,23 +1449,9 @@ static lv_res_t lv_cpicker_rect_signal(lv_obj_t * cpicker, lv_signal_t sign, voi lv_res_t res; - /* Include the ancient signal function */ - res = ancestor_signal(cpicker, sign, param); - if(res != LV_RES_OK) return res; - lv_style_t * style = lv_cpicker_get_style(cpicker, LV_CPICKER_STYLE_MAIN); - if(sign == LV_SIGNAL_CLEANUP) { - /*Nothing to cleanup. (No dynamically allocated memory in 'ext')*/ - } else if(sign == LV_SIGNAL_GET_TYPE) { - lv_obj_type_t * buf = param; - uint8_t i; - for(i = 0; i < LV_MAX_ANCESTOR_NUM - 1; i++) { /*Find the last set data*/ - if(buf->type[i] == NULL) break; - } - buf->type[i] = "lv_cpicker"; - } - else if(sign == LV_SIGNAL_PRESSED) + if(sign == LV_SIGNAL_PRESSED) { switch(ext->color_mode) { From 25d4991683543ee04752e647a015fa61a0f22bf1 Mon Sep 17 00:00:00 2001 From: Paul Peavyhouse Date: Thu, 26 Sep 2019 11:24:47 -0700 Subject: [PATCH 17/82] Whitespace changes --- src/lv_objx/lv_cpicker.c | 732 +++++++++++++++++++-------------------- 1 file changed, 366 insertions(+), 366 deletions(-) diff --git a/src/lv_objx/lv_cpicker.c b/src/lv_objx/lv_cpicker.c index da1af94bc..068d6b2a5 100644 --- a/src/lv_objx/lv_cpicker.c +++ b/src/lv_objx/lv_cpicker.c @@ -552,123 +552,123 @@ static bool lv_cpicker_disc_design(lv_obj_t * cpicker, const lv_area_t * mask, l //the square area (a and b being sides) should fit into the center of diameter d //we have: //a^2+b^2<=d^2 - //2a^2 <= d^2 - //a^2<=(d^2)/2 - //a <= sqrt((d^2)/2) - uint16_t radius = lv_sqrt((4*rin*rin)/2)/2 - style->body.padding.inner; + //2a^2 <= d^2 + //a^2<=(d^2)/2 + //a <= sqrt((d^2)/2) + uint16_t radius = lv_sqrt((4*rin*rin)/2)/2 - style->body.padding.inner; - center_ind_area.x1 = x - radius; - center_ind_area.y1 = y - radius; - center_ind_area.x2 = x + radius; - center_ind_area.y2 = y + radius; + center_ind_area.x1 = x - radius; + center_ind_area.y1 = y - radius; + center_ind_area.x2 = x + radius; + center_ind_area.y2 = y + radius; - /*redraw the wheel only if the mask intersect with the wheel*/ - if(mask->x1 < center_ind_area.x1 || mask->x2 > center_ind_area.x2 - || mask->y1 < center_ind_area.y1 || mask->y2 > center_ind_area.y2) - { - redraw_wheel = 1; - } + /*redraw the wheel only if the mask intersect with the wheel*/ + if(mask->x1 < center_ind_area.x1 || mask->x2 > center_ind_area.x2 + || mask->y1 < center_ind_area.y1 || mask->y2 > center_ind_area.y2) + { + redraw_wheel = 1; + } - lv_point_t triangle_points[3]; + lv_point_t triangle_points[3]; - int16_t start_angle, end_angle; - start_angle = 0; //Default - end_angle = 360 - LV_CPICKER_DEF_QF; //Default + int16_t start_angle, end_angle; + start_angle = 0; //Default + end_angle = 360 - LV_CPICKER_DEF_QF; //Default - if(redraw_wheel) - { - /*if the mask does not include the center of the object - * redrawing all the wheel is not necessary; - * only a given angular range + if(redraw_wheel) + { + /*if the mask does not include the center of the object + * redrawing all the wheel is not necessary; + * only a given angular range + */ + lv_point_t center = {x, y}; + if(!lv_area_is_point_on(mask, ¢er) + /* + && (mask->x1 != cpicker->coords.x1 || mask->x2 != cpicker->coords.x2 + || mask->y1 != cpicker->coords.y1 || mask->y2 != cpicker->coords.y2) */ - lv_point_t center = {x, y}; - if(!lv_area_is_point_on(mask, ¢er) - /* - && (mask->x1 != cpicker->coords.x1 || mask->x2 != cpicker->coords.x2 - || mask->y1 != cpicker->coords.y1 || mask->y2 != cpicker->coords.y2) - */ - ) + ) + { + /*get angle from center of object to each corners of the area*/ + int16_t dr, ur, ul, dl; + dr = lv_atan2(mask->x2 - x, mask->y2 - y); + ur = lv_atan2(mask->x2 - x, mask->y1 - y); + ul = lv_atan2(mask->x1 - x, mask->y1 - y); + dl = lv_atan2(mask->x1 - x, mask->y2 - y); + + /* check area position from object axis*/ + uint8_t left = (mask->x2 < x && mask->x1 < x); + uint8_t onYaxis = (mask->x2 > x && mask->x1 < x); + uint8_t right = (mask->x2 > x && mask->x1 > x); + uint8_t top = (mask->y2 < y && mask->y1 < y); + uint8_t onXaxis = (mask->y2 > y && mask->y1 < y); + uint8_t bottom = (mask->y2 > y && mask->y1 > x); + + /*store angular range*/ + if(right && bottom) { - /*get angle from center of object to each corners of the area*/ - int16_t dr, ur, ul, dl; - dr = lv_atan2(mask->x2 - x, mask->y2 - y); - ur = lv_atan2(mask->x2 - x, mask->y1 - y); - ul = lv_atan2(mask->x1 - x, mask->y1 - y); - dl = lv_atan2(mask->x1 - x, mask->y2 - y); - - /* check area position from object axis*/ - uint8_t left = (mask->x2 < x && mask->x1 < x); - uint8_t onYaxis = (mask->x2 > x && mask->x1 < x); - uint8_t right = (mask->x2 > x && mask->x1 > x); - uint8_t top = (mask->y2 < y && mask->y1 < y); - uint8_t onXaxis = (mask->y2 > y && mask->y1 < y); - uint8_t bottom = (mask->y2 > y && mask->y1 > x); - - /*store angular range*/ - if(right && bottom) - { - start_angle = dl; - end_angle = ur; - } - else if(right && onXaxis) - { - start_angle = dl; - end_angle = ul; - } - else if(right && top) - { - start_angle = dr; - end_angle = ul; - } - else if(onYaxis && top) - { - start_angle = dr; - end_angle = dl; - } - else if(left && top) - { - start_angle = ur; - end_angle = dl; - } - else if(left && onXaxis) - { - start_angle = ur; - end_angle = dr; - } - else if(left && bottom) - { - start_angle = ul; - end_angle = dr; - } - else if(onYaxis && bottom) - { - start_angle = ul; - end_angle = ur; - } - - /*rollover angle*/ - if(start_angle > end_angle) - { - end_angle += 360; - } - - /*round to QF factor*/ - start_angle = start_angle/LV_CPICKER_DEF_QF*LV_CPICKER_DEF_QF; - end_angle = end_angle/LV_CPICKER_DEF_QF*LV_CPICKER_DEF_QF;; - - /*shift angle if necessary before adding offset*/ - if((start_angle - LV_CPICKER_DEF_QF) < 0) - { - start_angle += 360; - end_angle += 360; - } - - /*ensure overlapping by adding offset*/ - start_angle -= LV_CPICKER_DEF_QF; - end_angle += LV_CPICKER_DEF_QF; + start_angle = dl; + end_angle = ur; + } + else if(right && onXaxis) + { + start_angle = dl; + end_angle = ul; + } + else if(right && top) + { + start_angle = dr; + end_angle = ul; + } + else if(onYaxis && top) + { + start_angle = dr; + end_angle = dl; + } + else if(left && top) + { + start_angle = ur; + end_angle = dl; + } + else if(left && onXaxis) + { + start_angle = ur; + end_angle = dr; + } + else if(left && bottom) + { + start_angle = ul; + end_angle = dr; + } + else if(onYaxis && bottom) + { + start_angle = ul; + end_angle = ur; } - if(ext->color_mode == LV_CPICKER_COLOR_MODE_HUE) + /*rollover angle*/ + if(start_angle > end_angle) + { + end_angle += 360; + } + + /*round to QF factor*/ + start_angle = start_angle/LV_CPICKER_DEF_QF*LV_CPICKER_DEF_QF; + end_angle = end_angle/LV_CPICKER_DEF_QF*LV_CPICKER_DEF_QF;; + + /*shift angle if necessary before adding offset*/ + if((start_angle - LV_CPICKER_DEF_QF) < 0) + { + start_angle += 360; + end_angle += 360; + } + + /*ensure overlapping by adding offset*/ + start_angle -= LV_CPICKER_DEF_QF; + end_angle += LV_CPICKER_DEF_QF; + } + + if(ext->color_mode == LV_CPICKER_COLOR_MODE_HUE) { for(uint16_t i = start_angle; i <= end_angle; i+= LV_CPICKER_DEF_QF) { @@ -678,21 +678,21 @@ static bool lv_cpicker_disc_design(lv_obj_t * cpicker, const lv_area_t * mask, l triangle_points[0].x = x; triangle_points[0].y = y; - triangle_points[1].x = x + (r * lv_trigo_sin(i) >> LV_TRIGO_SHIFT); - triangle_points[1].y = y + (r * lv_trigo_sin(i + 90) >> LV_TRIGO_SHIFT); + triangle_points[1].x = x + (r * lv_trigo_sin(i) >> LV_TRIGO_SHIFT); + triangle_points[1].y = y + (r * lv_trigo_sin(i + 90) >> LV_TRIGO_SHIFT); - if(i == end_angle || i == (360 - LV_CPICKER_DEF_QF)) - { - /*the last triangle is drawn without additional overlapping pixels*/ - triangle_points[2].x = x + (r * lv_trigo_sin(i + LV_CPICKER_DEF_QF) >> LV_TRIGO_SHIFT); - triangle_points[2].y = y + (r * lv_trigo_sin(i + LV_CPICKER_DEF_QF + 90) >> LV_TRIGO_SHIFT); + if(i == end_angle || i == (360 - LV_CPICKER_DEF_QF)) + { + /*the last triangle is drawn without additional overlapping pixels*/ + triangle_points[2].x = x + (r * lv_trigo_sin(i + LV_CPICKER_DEF_QF) >> LV_TRIGO_SHIFT); + triangle_points[2].y = y + (r * lv_trigo_sin(i + LV_CPICKER_DEF_QF + 90) >> LV_TRIGO_SHIFT); - } - else - { - triangle_points[2].x = x + (r * lv_trigo_sin(i + LV_CPICKER_DEF_QF + TRI_OFFSET) >> LV_TRIGO_SHIFT); - triangle_points[2].y = y + (r * lv_trigo_sin(i + LV_CPICKER_DEF_QF + TRI_OFFSET + 90) >> LV_TRIGO_SHIFT); + } + else + { + triangle_points[2].x = x + (r * lv_trigo_sin(i + LV_CPICKER_DEF_QF + TRI_OFFSET) >> LV_TRIGO_SHIFT); + triangle_points[2].y = y + (r * lv_trigo_sin(i + LV_CPICKER_DEF_QF + TRI_OFFSET + 90) >> LV_TRIGO_SHIFT); } @@ -709,18 +709,18 @@ static bool lv_cpicker_disc_design(lv_obj_t * cpicker, const lv_area_t * mask, l triangle_points[0].x = x; triangle_points[0].y = y; - triangle_points[1].x = x + (r * lv_trigo_sin(i) >> LV_TRIGO_SHIFT); - triangle_points[1].y = y + (r * lv_trigo_sin(i + 90) >> LV_TRIGO_SHIFT); + triangle_points[1].x = x + (r * lv_trigo_sin(i) >> LV_TRIGO_SHIFT); + triangle_points[1].y = y + (r * lv_trigo_sin(i + 90) >> LV_TRIGO_SHIFT); - if(i == end_angle || i == (360 - LV_CPICKER_DEF_QF)) - { - /*the last triangle is drawn without additional overlapping pixels*/ - triangle_points[2].x = x + (r * lv_trigo_sin(i + LV_CPICKER_DEF_QF) >> LV_TRIGO_SHIFT); - triangle_points[2].y = y + (r * lv_trigo_sin(i + LV_CPICKER_DEF_QF + 90) >> LV_TRIGO_SHIFT); - } - else - { - triangle_points[2].x = x + (r * lv_trigo_sin(i + LV_CPICKER_DEF_QF + TRI_OFFSET) >> LV_TRIGO_SHIFT); + if(i == end_angle || i == (360 - LV_CPICKER_DEF_QF)) + { + /*the last triangle is drawn without additional overlapping pixels*/ + triangle_points[2].x = x + (r * lv_trigo_sin(i + LV_CPICKER_DEF_QF) >> LV_TRIGO_SHIFT); + triangle_points[2].y = y + (r * lv_trigo_sin(i + LV_CPICKER_DEF_QF + 90) >> LV_TRIGO_SHIFT); + } + else + { + triangle_points[2].x = x + (r * lv_trigo_sin(i + LV_CPICKER_DEF_QF + TRI_OFFSET) >> LV_TRIGO_SHIFT); triangle_points[2].y = y + (r * lv_trigo_sin(i + LV_CPICKER_DEF_QF + TRI_OFFSET + 90) >> LV_TRIGO_SHIFT); } @@ -737,19 +737,19 @@ static bool lv_cpicker_disc_design(lv_obj_t * cpicker, const lv_area_t * mask, l triangle_points[0].x = x; triangle_points[0].y = y; - triangle_points[1].x = x + (r * lv_trigo_sin(i) >> LV_TRIGO_SHIFT); - triangle_points[1].y = y + (r * lv_trigo_sin(i + 90) >> LV_TRIGO_SHIFT); + triangle_points[1].x = x + (r * lv_trigo_sin(i) >> LV_TRIGO_SHIFT); + triangle_points[1].y = y + (r * lv_trigo_sin(i + 90) >> LV_TRIGO_SHIFT); - if(i == end_angle || i == (360 - LV_CPICKER_DEF_QF)) - { - /*the last triangle is drawn without additional overlapping pixels*/ - triangle_points[2].x = x + (r * lv_trigo_sin(i + LV_CPICKER_DEF_QF) >> LV_TRIGO_SHIFT); - triangle_points[2].y = y + (r * lv_trigo_sin(i + LV_CPICKER_DEF_QF + 90) >> LV_TRIGO_SHIFT); + if(i == end_angle || i == (360 - LV_CPICKER_DEF_QF)) + { + /*the last triangle is drawn without additional overlapping pixels*/ + triangle_points[2].x = x + (r * lv_trigo_sin(i + LV_CPICKER_DEF_QF) >> LV_TRIGO_SHIFT); + triangle_points[2].y = y + (r * lv_trigo_sin(i + LV_CPICKER_DEF_QF + 90) >> LV_TRIGO_SHIFT); - } - else - { - triangle_points[2].x = x + (r * lv_trigo_sin(i + LV_CPICKER_DEF_QF + TRI_OFFSET) >> LV_TRIGO_SHIFT); + } + else + { + triangle_points[2].x = x + (r * lv_trigo_sin(i + LV_CPICKER_DEF_QF + TRI_OFFSET) >> LV_TRIGO_SHIFT); triangle_points[2].y = y + (r * lv_trigo_sin(i + LV_CPICKER_DEF_QF + TRI_OFFSET + 90) >> LV_TRIGO_SHIFT); } @@ -758,76 +758,76 @@ static bool lv_cpicker_disc_design(lv_obj_t * cpicker, const lv_area_t * mask, l } } - //draw center background + /*draw center background*/ lv_area_t center_area; uint16_t wradius = r - style->line.width; center_area.x1 = x - wradius; center_area.y1 = y - wradius; center_area.x2 = x + wradius; - center_area.y2 = y + wradius; - styleCenterBackground.body.radius = LV_RADIUS_CIRCLE; + center_area.y2 = y + wradius; + styleCenterBackground.body.radius = LV_RADIUS_CIRCLE; lv_draw_rect(¢er_area, mask, &styleCenterBackground, opa_scale); - //draw the center color indicator + /*draw the center color indicator*/ style->body.main_color = lv_color_hsv_to_rgb(ext->hue, ext->saturation, ext->value); style->body.grad_color = style->body.main_color; style->body.radius = LV_RADIUS_CIRCLE; lv_draw_rect(¢er_ind_area, mask, style, opa_scale); - //Draw the current hue indicator + /*draw the current hue indicator*/ switch(ext->indicator.type) + { + case LV_CPICKER_INDICATOR_NONE: + break; + case LV_CPICKER_INDICATOR_LINE: + { + lv_point_t start; + lv_point_t end; + + uint16_t angle = mode_color_to_angle(ext); + + /*save the angle to refresh the area later*/ + ext->prev_pos = angle; + + start.x = x + ((r - style->line.width + ext->indicator.style->body.padding.inner + ext->indicator.style->line.width/2) * lv_trigo_sin(angle) >> LV_TRIGO_SHIFT); + start.y = y + ((r - style->line.width + ext->indicator.style->body.padding.inner + ext->indicator.style->line.width/2) * lv_trigo_sin(angle + 90) >> LV_TRIGO_SHIFT); + + end.x = x + ((r - ext->indicator.style->body.padding.inner - ext->indicator.style->line.width/2) * lv_trigo_sin(angle) >> LV_TRIGO_SHIFT); + end.y = y + ((r - ext->indicator.style->body.padding.inner - ext->indicator.style->line.width/2) * lv_trigo_sin(angle + 90) >> LV_TRIGO_SHIFT); + + lv_draw_line(&start, &end, mask, ext->indicator.style, opa_scale); + if(ext->indicator.style->line.rounded) { - case LV_CPICKER_INDICATOR_NONE: - break; - case LV_CPICKER_INDICATOR_LINE: - { - lv_point_t start; - lv_point_t end; + lv_area_t circle_area; + circle_area.x1 = start.x - ((ext->indicator.style->line.width - 1) >> 1) - ((ext->indicator.style->line.width - 1) & 0x1); + circle_area.y1 = start.y - ((ext->indicator.style->line.width - 1) >> 1) - ((ext->indicator.style->line.width - 1) & 0x1); + circle_area.x2 = start.x + ((ext->indicator.style->line.width - 1) >> 1); + circle_area.y2 = start.y + ((ext->indicator.style->line.width - 1) >> 1); + lv_draw_rect(&circle_area, mask, ext->indicator.style, opa_scale); - uint16_t angle = mode_color_to_angle(ext); - - /*save the angle to refresh the area later*/ - ext->prev_pos = angle; - - start.x = x + ((r - style->line.width + ext->indicator.style->body.padding.inner + ext->indicator.style->line.width/2) * lv_trigo_sin(angle) >> LV_TRIGO_SHIFT); - start.y = y + ((r - style->line.width + ext->indicator.style->body.padding.inner + ext->indicator.style->line.width/2) * lv_trigo_sin(angle + 90) >> LV_TRIGO_SHIFT); - - end.x = x + ((r - ext->indicator.style->body.padding.inner - ext->indicator.style->line.width/2) * lv_trigo_sin(angle) >> LV_TRIGO_SHIFT); - end.y = y + ((r - ext->indicator.style->body.padding.inner - ext->indicator.style->line.width/2) * lv_trigo_sin(angle + 90) >> LV_TRIGO_SHIFT); - - lv_draw_line(&start, &end, mask, ext->indicator.style, opa_scale); - if(ext->indicator.style->line.rounded) - { - lv_area_t circle_area; - circle_area.x1 = start.x - ((ext->indicator.style->line.width - 1) >> 1) - ((ext->indicator.style->line.width - 1) & 0x1); - circle_area.y1 = start.y - ((ext->indicator.style->line.width - 1) >> 1) - ((ext->indicator.style->line.width - 1) & 0x1); - circle_area.x2 = start.x + ((ext->indicator.style->line.width - 1) >> 1); - circle_area.y2 = start.y + ((ext->indicator.style->line.width - 1) >> 1); - lv_draw_rect(&circle_area, mask, ext->indicator.style, opa_scale); - - circle_area.x1 = end.x - ((ext->indicator.style->line.width - 1) >> 1) - ((ext->indicator.style->line.width - 1) & 0x1); - circle_area.y1 = end.y - ((ext->indicator.style->line.width - 1) >> 1) - ((ext->indicator.style->line.width - 1) & 0x1); - circle_area.x2 = end.x + ((ext->indicator.style->line.width - 1) >> 1); - circle_area.y2 = end.y + ((ext->indicator.style->line.width - 1) >> 1); - lv_draw_rect(&circle_area, mask, ext->indicator.style, opa_scale); - } - break; + circle_area.x1 = end.x - ((ext->indicator.style->line.width - 1) >> 1) - ((ext->indicator.style->line.width - 1) & 0x1); + circle_area.y1 = end.y - ((ext->indicator.style->line.width - 1) >> 1) - ((ext->indicator.style->line.width - 1) & 0x1); + circle_area.x2 = end.x + ((ext->indicator.style->line.width - 1) >> 1); + circle_area.y2 = end.y + ((ext->indicator.style->line.width - 1) >> 1); + lv_draw_rect(&circle_area, mask, ext->indicator.style, opa_scale); } - case LV_CPICKER_INDICATOR_CIRCLE: - { - lv_area_t circle_ind_area; - uint32_t cx, cy; + break; + } + case LV_CPICKER_INDICATOR_CIRCLE: + { + lv_area_t circle_ind_area; + uint32_t cx, cy; - uint16_t angle = mode_color_to_angle(ext); + uint16_t angle = mode_color_to_angle(ext); - /*save the angle to refresh the area later*/ - ext->prev_pos = angle; + /*save the angle to refresh the area later*/ + ext->prev_pos = angle; - cx = x + ((r - style->line.width/2) * lv_trigo_sin(angle) >> LV_TRIGO_SHIFT); - cy = y + ((r - style->line.width/2) * lv_trigo_sin(angle + 90) >> LV_TRIGO_SHIFT); + cx = x + ((r - style->line.width/2) * lv_trigo_sin(angle) >> LV_TRIGO_SHIFT); + cy = y + ((r - style->line.width/2) * lv_trigo_sin(angle + 90) >> LV_TRIGO_SHIFT); - circle_ind_area.x1 = cx - style->line.width/2; - circle_ind_area.y1 = cy - style->line.width/2; + circle_ind_area.x1 = cx - style->line.width/2; + circle_ind_area.y1 = cy - style->line.width/2; circle_ind_area.x2 = cx + style->line.width/2; circle_ind_area.y2 = cy + style->line.width/2; @@ -835,27 +835,27 @@ static bool lv_cpicker_disc_design(lv_obj_t * cpicker, const lv_area_t * mask, l lv_style_copy(&styleCopy, ext->indicator.style); styleCopy.body.radius = LV_RADIUS_CIRCLE; - lv_draw_rect(&circle_ind_area, mask, &styleCopy, opa_scale); - break; - } - case LV_CPICKER_INDICATOR_IN: - { - lv_area_t circle_ind_area; - uint32_t cx, cy; + lv_draw_rect(&circle_ind_area, mask, &styleCopy, opa_scale); + break; + } + case LV_CPICKER_INDICATOR_IN: + { + lv_area_t circle_ind_area; + uint32_t cx, cy; - uint16_t angle = mode_color_to_angle(ext); + uint16_t angle = mode_color_to_angle(ext); - /*save the angle to refresh the area later*/ - ext->prev_pos = angle; + /*save the angle to refresh the area later*/ + ext->prev_pos = angle; - uint16_t ind_radius = lv_sqrt((4*rin*rin)/2)/2 + 1 - style->body.padding.inner; - ind_radius = (ind_radius + rin) / 2; + uint16_t ind_radius = lv_sqrt((4*rin*rin)/2)/2 + 1 - style->body.padding.inner; + ind_radius = (ind_radius + rin) / 2; - cx = x + ((ind_radius) * lv_trigo_sin(angle) >> LV_TRIGO_SHIFT); - cy = y + ((ind_radius) * lv_trigo_sin(angle + 90) >> LV_TRIGO_SHIFT); + cx = x + ((ind_radius) * lv_trigo_sin(angle) >> LV_TRIGO_SHIFT); + cy = y + ((ind_radius) * lv_trigo_sin(angle + 90) >> LV_TRIGO_SHIFT); - circle_ind_area.x1 = cx - ((wradius - radius) / 3); - circle_ind_area.y1 = cy - ((wradius - radius) / 3); + circle_ind_area.x1 = cx - ((wradius - radius) / 3); + circle_ind_area.y1 = cy - ((wradius - radius) / 3); circle_ind_area.x2 = cx + ((wradius - radius) / 3); circle_ind_area.y2 = cy + ((wradius - radius) / 3); @@ -863,21 +863,21 @@ static bool lv_cpicker_disc_design(lv_obj_t * cpicker, const lv_area_t * mask, l lv_style_copy(&styleCopy, ext->indicator.style); styleCopy.body.radius = LV_RADIUS_CIRCLE; - lv_draw_rect(&circle_ind_area, mask, &styleCopy, opa_scale); - break; - } - } // switch + lv_draw_rect(&circle_ind_area, mask, &styleCopy, opa_scale); + break; + } + } /* switch */ - /* - //code to color the drawn area - static uint32_t c = 0; - lv_style_t style2; - lv_style_copy(&style2, &lv_style_plain); - style2.body.main_color.full = c; - style2.body.grad_color.full = c; + /* + //code to color the drawn area + static uint32_t c = 0; + lv_style_t style2; + lv_style_copy(&style2, &lv_style_plain); + style2.body.main_color.full = c; + style2.body.grad_color.full = c; c += 0x123445678; lv_draw_rect(mask, mask, &style2, opa_scale); - */ + */ return true; } @@ -888,95 +888,95 @@ static bool lv_cpicker_rect_design(lv_obj_t * cpicker, const lv_area_t * mask, l lv_coord_t w = lv_obj_get_width(cpicker); lv_coord_t h = lv_obj_get_height(cpicker); - lv_coord_t x1 = cpicker->coords.x1; - lv_coord_t y1 = cpicker->coords.y1; - lv_coord_t x2 = cpicker->coords.x2; - lv_coord_t y2 = cpicker->coords.y2; - lv_opa_t opa_scale = lv_obj_get_opa_scale(cpicker); + lv_coord_t x1 = cpicker->coords.x1; + lv_coord_t y1 = cpicker->coords.y1; + lv_coord_t x2 = cpicker->coords.x2; + lv_coord_t y2 = cpicker->coords.y2; + lv_opa_t opa_scale = lv_obj_get_opa_scale(cpicker); - /* prepare the color preview area */ - uint16_t preview_offset = style->line.width; - uint16_t style_body_padding_ver = style->body.padding.top + style->body.padding.bottom; - uint16_t style_body_padding_hor = style->body.padding.left + style->body.padding.right; - if(style_body_padding_ver == 0) + /*prepare the color preview area*/ + uint16_t preview_offset = style->line.width; + uint16_t style_body_padding_ver = style->body.padding.top + style->body.padding.bottom; + uint16_t style_body_padding_hor = style->body.padding.left + style->body.padding.right; + if(style_body_padding_ver == 0) + { + /*draw the color preview rect to the side of the gradient*/ + if(style_body_padding_hor >= 0) { - /* draw the color preview rect to the side of the gradient*/ - if(style_body_padding_hor >= 0) - { - /*draw the preview to the right*/ - ext->rect_gradient_w = w - preview_offset - (LV_MATH_ABS(style_body_padding_hor) - 1); - ext->rect_gradient_h = y2 - y1; - ext->rect_gradient_area.x1 = x1; - ext->rect_gradient_area.x2 = ext->rect_gradient_area.x1 + ext->rect_gradient_w; - ext->rect_gradient_area.y1 = y1; - ext->rect_gradient_area.y2 = y2; + /*draw the preview to the right*/ + ext->rect_gradient_w = w - preview_offset - (LV_MATH_ABS(style_body_padding_hor) - 1); + ext->rect_gradient_h = y2 - y1; + ext->rect_gradient_area.x1 = x1; + ext->rect_gradient_area.x2 = ext->rect_gradient_area.x1 + ext->rect_gradient_w; + ext->rect_gradient_area.y1 = y1; + ext->rect_gradient_area.y2 = y2; - ext->rect_preview_area.x1 = x2 - preview_offset; - ext->rect_preview_area.y1 = y1; - ext->rect_preview_area.x2 = x2 ; - ext->rect_preview_area.y2 = y2; - } - else - { - /*draw the preview to the left*/ - ext->rect_gradient_w = w - preview_offset - (LV_MATH_ABS(style_body_padding_hor) - 1); - ext->rect_gradient_h = y2 - y1; - ext->rect_gradient_area.x1 = x2 - ext->rect_gradient_w; - ext->rect_gradient_area.x2 = x2; - ext->rect_gradient_area.y1 = y1; - ext->rect_gradient_area.y2 = y2; - - ext->rect_preview_area.x1 = x1; - ext->rect_preview_area.y1 = y1; - ext->rect_preview_area.x2 = x1 + preview_offset; - ext->rect_preview_area.y2 = y2; - } + ext->rect_preview_area.x1 = x2 - preview_offset; + ext->rect_preview_area.y1 = y1; + ext->rect_preview_area.x2 = x2 ; + ext->rect_preview_area.y2 = y2; } else { - /* draw the color preview rect on top or below the gradient*/ - if(style_body_padding_ver >= 0) - { - /*draw the preview on top*/ - ext->rect_gradient_w = w; - ext->rect_gradient_h = (y2 - y1) - preview_offset - (LV_MATH_ABS(style_body_padding_ver) - 1); - ext->rect_gradient_area.x1 = x1; - ext->rect_gradient_area.x2 = x2; - ext->rect_gradient_area.y1 = y2 - ext->rect_gradient_h; - ext->rect_gradient_area.y2 = y2; + /*draw the preview to the left*/ + ext->rect_gradient_w = w - preview_offset - (LV_MATH_ABS(style_body_padding_hor) - 1); + ext->rect_gradient_h = y2 - y1; + ext->rect_gradient_area.x1 = x2 - ext->rect_gradient_w; + ext->rect_gradient_area.x2 = x2; + ext->rect_gradient_area.y1 = y1; + ext->rect_gradient_area.y2 = y2; - ext->rect_preview_area.x1 = x1; - ext->rect_preview_area.y1 = y1; - ext->rect_preview_area.x2 = x2; - ext->rect_preview_area.y2 = y1 + preview_offset; - } - else - { - /*draw the preview below the gradient*/ - ext->rect_gradient_w = w; - ext->rect_gradient_h = (y2 - y1) - preview_offset - (LV_MATH_ABS(style_body_padding_ver) - 1); - ext->rect_gradient_area.x1 = x1; - ext->rect_gradient_area.x2 = x2; - ext->rect_gradient_area.y1 = y1; - ext->rect_gradient_area.y2 = y1 + ext->rect_gradient_h; - - ext->rect_preview_area.x1 = x1; - ext->rect_preview_area.y1 = y2 - preview_offset; - ext->rect_preview_area.x2 = x2; - ext->rect_preview_area.y2 = y2; - } + ext->rect_preview_area.x1 = x1; + ext->rect_preview_area.y1 = y1; + ext->rect_preview_area.x2 = x1 + preview_offset; + ext->rect_preview_area.y2 = y2; } - - if(style->line.rounded) + } + else + { + /*draw the color preview rect on top or below the gradient*/ + if(style_body_padding_ver >= 0) { - /*draw rounded edges to the gradient*/ - lv_area_t rounded_edge_area; - rounded_edge_area.x1 = ext->rect_gradient_area.x1; - rounded_edge_area.x2 = ext->rect_gradient_area.x1 + ext->rect_gradient_h; - rounded_edge_area.y1 = ext->rect_gradient_area.y1; - rounded_edge_area.y2 = ext->rect_gradient_area.y2; + /*draw the preview on top*/ + ext->rect_gradient_w = w; + ext->rect_gradient_h = (y2 - y1) - preview_offset - (LV_MATH_ABS(style_body_padding_ver) - 1); + ext->rect_gradient_area.x1 = x1; + ext->rect_gradient_area.x2 = x2; + ext->rect_gradient_area.y1 = y2 - ext->rect_gradient_h; + ext->rect_gradient_area.y2 = y2; - ext->rect_gradient_area.x1 += ext->rect_gradient_h/2; + ext->rect_preview_area.x1 = x1; + ext->rect_preview_area.y1 = y1; + ext->rect_preview_area.x2 = x2; + ext->rect_preview_area.y2 = y1 + preview_offset; + } + else + { + /*draw the preview below the gradient*/ + ext->rect_gradient_w = w; + ext->rect_gradient_h = (y2 - y1) - preview_offset - (LV_MATH_ABS(style_body_padding_ver) - 1); + ext->rect_gradient_area.x1 = x1; + ext->rect_gradient_area.x2 = x2; + ext->rect_gradient_area.y1 = y1; + ext->rect_gradient_area.y2 = y1 + ext->rect_gradient_h; + + ext->rect_preview_area.x1 = x1; + ext->rect_preview_area.y1 = y2 - preview_offset; + ext->rect_preview_area.x2 = x2; + ext->rect_preview_area.y2 = y2; + } + } + + if(style->line.rounded) + { + /*draw rounded edges to the gradient*/ + lv_area_t rounded_edge_area; + rounded_edge_area.x1 = ext->rect_gradient_area.x1; + rounded_edge_area.x2 = ext->rect_gradient_area.x1 + ext->rect_gradient_h; + rounded_edge_area.y1 = ext->rect_gradient_area.y1; + rounded_edge_area.y2 = ext->rect_gradient_area.y2; + + ext->rect_gradient_area.x1 += ext->rect_gradient_h/2; ext->rect_gradient_area.x2 -= ext->rect_gradient_h/2; ext->rect_gradient_w -= ext->rect_gradient_h; @@ -1009,11 +1009,11 @@ static bool lv_cpicker_rect_design(lv_obj_t * cpicker, const lv_area_t * mask, l lv_area_t rect_area; - /*scale angle (hue/sat/val) to linear coordinate*/ - lv_coord_t xi = i / 360.0 * ext->rect_gradient_w; + /*scale angle (hue/sat/val) to linear coordinate*/ + lv_coord_t xi = i / 360.0 * ext->rect_gradient_w; - rect_area.x1 = LV_MATH_MIN(ext->rect_gradient_area.x1 + xi, ext->rect_gradient_area.x1 + ext->rect_gradient_w - LV_MATH_MAX(LV_CPICKER_DEF_QF, 360/ext->rect_gradient_w)); - rect_area.y1 = ext->rect_gradient_area.y1; + rect_area.x1 = LV_MATH_MIN(ext->rect_gradient_area.x1 + xi, ext->rect_gradient_area.x1 + ext->rect_gradient_w - LV_MATH_MAX(LV_CPICKER_DEF_QF, 360/ext->rect_gradient_w)); + rect_area.y1 = ext->rect_gradient_area.y1; rect_area.x2 = rect_area.x1 + LV_MATH_MAX(LV_CPICKER_DEF_QF, 360/ext->rect_gradient_w); rect_area.y2 = ext->rect_gradient_area.y2; @@ -1021,11 +1021,11 @@ static bool lv_cpicker_rect_design(lv_obj_t * cpicker, const lv_area_t * mask, l } if(style->line.rounded) - { - /*Restore gradient area to take rounded end in account*/ - ext->rect_gradient_area.x1 -= ext->rect_gradient_h/2; - ext->rect_gradient_area.x2 += ext->rect_gradient_h/2; - //ext->rect_gradient_w += ext->rect_gradient_h; + { + /*Restore gradient area to take rounded end in account*/ + ext->rect_gradient_area.x1 -= ext->rect_gradient_h/2; + ext->rect_gradient_area.x2 += ext->rect_gradient_h/2; + //ext->rect_gradient_w += ext->rect_gradient_h; } /*draw the color preview indicator*/ @@ -1039,50 +1039,50 @@ static bool lv_cpicker_rect_design(lv_obj_t * cpicker, const lv_area_t * mask, l /* styleCopy.line.width = 10; - lv_draw_arc(cpicker->coords.x1 + 3*ext->rect_gradient_h/2, cpicker->coords.y1 + ext->rect_gradient_h/2, ext->rect_gradient_h / 2 + styleCopy.line.width + 2, mask, 180, 360, &styleCopy, opa_scale); - //lv_draw_arc(cpicker->coords.x1 + ext->rect_gradient_w - ext->rect_gradient_h/2, cpicker->coords.y1 + ext->rect_gradient_h/2, ext->rect_gradient_h / 2 + styleCopy.line.width + 2, mask, 0, 180, &styleCopy, opa_scale); - */ + lv_draw_arc(cpicker->coords.x1 + 3*ext->rect_gradient_h/2, cpicker->coords.y1 + ext->rect_gradient_h/2, ext->rect_gradient_h / 2 + styleCopy.line.width + 2, mask, 180, 360, &styleCopy, opa_scale); + //lv_draw_arc(cpicker->coords.x1 + ext->rect_gradient_w - ext->rect_gradient_h/2, cpicker->coords.y1 + ext->rect_gradient_h/2, ext->rect_gradient_h / 2 + styleCopy.line.width + 2, mask, 0, 180, &styleCopy, opa_scale); + */ - /*draw the color position indicator*/ - lv_coord_t ind_pos = style->line.rounded ? ext->rect_gradient_h / 2 : 0; - switch(ext->color_mode) - { - default: - case LV_CPICKER_COLOR_MODE_HUE: - ind_pos += ext->hue * ext->rect_gradient_w / 360.0; - break; - case LV_CPICKER_COLOR_MODE_SATURATION: - ind_pos += ext->saturation * ext->rect_gradient_w / 100.0; - break; - case LV_CPICKER_COLOR_MODE_VALUE: - ind_pos += ext->value * ext->rect_gradient_w / 100.0; - break; - } + /*draw the color position indicator*/ + lv_coord_t ind_pos = style->line.rounded ? ext->rect_gradient_h / 2 : 0; + switch(ext->color_mode) + { + default: + case LV_CPICKER_COLOR_MODE_HUE: + ind_pos += ext->hue * ext->rect_gradient_w / 360.0; + break; + case LV_CPICKER_COLOR_MODE_SATURATION: + ind_pos += ext->saturation * ext->rect_gradient_w / 100.0; + break; + case LV_CPICKER_COLOR_MODE_VALUE: + ind_pos += ext->value * ext->rect_gradient_w / 100.0; + break; + } - /*save to refresh the area later*/ - ext->prev_pos = ind_pos; + /*save to refresh the area later*/ + ext->prev_pos = ind_pos; - switch(ext->indicator.type) - { - case LV_CPICKER_INDICATOR_NONE: - /*no indicator*/ - break; - case LV_CPICKER_INDICATOR_LINE: - { - lv_point_t p1, p2; - p1.x = ext->rect_gradient_area.x1 + ind_pos; - p1.y = ext->rect_gradient_area.y1; - p2.x = p1.x; - p2.y = ext->rect_gradient_area.y2; + switch(ext->indicator.type) + { + case LV_CPICKER_INDICATOR_NONE: + /*no indicator*/ + break; + case LV_CPICKER_INDICATOR_LINE: + { + lv_point_t p1, p2; + p1.x = ext->rect_gradient_area.x1 + ind_pos; + p1.y = ext->rect_gradient_area.y1; + p2.x = p1.x; + p2.y = ext->rect_gradient_area.y2; - lv_draw_line(&p1, &p2, mask, ext->indicator.style, opa_scale); - break; - } - case LV_CPICKER_INDICATOR_CIRCLE: - { - lv_area_t circle_ind_area; - circle_ind_area.x1 = ext->rect_gradient_area.x1 + ind_pos - ext->rect_gradient_h/2; - circle_ind_area.x2 = circle_ind_area.x1 + ext->rect_gradient_h; + lv_draw_line(&p1, &p2, mask, ext->indicator.style, opa_scale); + break; + } + case LV_CPICKER_INDICATOR_CIRCLE: + { + lv_area_t circle_ind_area; + circle_ind_area.x1 = ext->rect_gradient_area.x1 + ind_pos - ext->rect_gradient_h/2; + circle_ind_area.x2 = circle_ind_area.x1 + ext->rect_gradient_h; circle_ind_area.y1 = ext->rect_gradient_area.y1; circle_ind_area.y2 = ext->rect_gradient_area.y2; @@ -1093,29 +1093,29 @@ static bool lv_cpicker_rect_design(lv_obj_t * cpicker, const lv_area_t * mask, l break; } case LV_CPICKER_INDICATOR_IN: - { - /*draw triangle under the gradient*/ - lv_point_t triangle_points[3]; + { + /*draw triangle under the gradient*/ + lv_point_t triangle_points[3]; - triangle_points[0].x = ext->rect_gradient_area.x1 + ind_pos; - triangle_points[0].y = ext->rect_gradient_area.y1 + (ext->rect_gradient_h/3); + triangle_points[0].x = ext->rect_gradient_area.x1 + ind_pos; + triangle_points[0].y = ext->rect_gradient_area.y1 + (ext->rect_gradient_h/3); - triangle_points[1].x = triangle_points[0].x - ext->indicator.style->line.width * 3; - triangle_points[1].y = ext->rect_gradient_area.y1 - 1; + triangle_points[1].x = triangle_points[0].x - ext->indicator.style->line.width * 3; + triangle_points[1].y = ext->rect_gradient_area.y1 - 1; - triangle_points[2].x = triangle_points[0].x + ext->indicator.style->line.width * 3; - triangle_points[2].y = triangle_points[1].y; + triangle_points[2].x = triangle_points[0].x + ext->indicator.style->line.width * 3; + triangle_points[2].y = triangle_points[1].y; - lv_draw_triangle(triangle_points, mask, ext->indicator.style, LV_OPA_COVER); + lv_draw_triangle(triangle_points, mask, ext->indicator.style, LV_OPA_COVER); - triangle_points[0].y = ext->rect_gradient_area.y2 - (ext->rect_gradient_h/3); - triangle_points[1].y = ext->rect_gradient_area.y2; - triangle_points[2].y = triangle_points[1].y; - lv_draw_triangle(triangle_points, mask, ext->indicator.style, LV_OPA_COVER); - break; - } - default: - break; + triangle_points[0].y = ext->rect_gradient_area.y2 - (ext->rect_gradient_h/3); + triangle_points[1].y = ext->rect_gradient_area.y2; + triangle_points[2].y = triangle_points[1].y; + lv_draw_triangle(triangle_points, mask, ext->indicator.style, LV_OPA_COVER); + break; + } + default: + break; } return true; From 847669273137827be28b45537266326485d0f024 Mon Sep 17 00:00:00 2001 From: Paul Peavyhouse Date: Thu, 26 Sep 2019 12:32:05 -0700 Subject: [PATCH 18/82] [Still] working cleanup checkpoint --- src/lv_objx/lv_cpicker.c | 277 ++++++++++++++++++--------------------- 1 file changed, 131 insertions(+), 146 deletions(-) diff --git a/src/lv_objx/lv_cpicker.c b/src/lv_objx/lv_cpicker.c index 068d6b2a5..c4c91ce74 100644 --- a/src/lv_objx/lv_cpicker.c +++ b/src/lv_objx/lv_cpicker.c @@ -425,23 +425,125 @@ static uint16_t mode_color_to_angle(lv_cpicker_ext_t * ext) } static void draw_disk_indicator_line(lv_cpicker_ext_t * ext, lv_style_t * style, lv_area_t * mask, lv_opa_t opa_scale, - lv_coord_t r, lv_coord_t x, lv_coord_t y) + lv_coord_t x, lv_coord_t y, uint16_t r, uint16_t angle) { + lv_point_t start; + lv_point_t end; + start.x = x + ((r - style->line.width + ext->indicator.style->body.padding.inner + ext->indicator.style->line.width/2) * lv_trigo_sin(angle) >> LV_TRIGO_SHIFT); + start.y = y + ((r - style->line.width + ext->indicator.style->body.padding.inner + ext->indicator.style->line.width/2) * lv_trigo_sin(angle + 90) >> LV_TRIGO_SHIFT); + end.x = x + ((r - ext->indicator.style->body.padding.inner - ext->indicator.style->line.width/2) * lv_trigo_sin(angle) >> LV_TRIGO_SHIFT); + end.y = y + ((r - ext->indicator.style->body.padding.inner - ext->indicator.style->line.width/2) * lv_trigo_sin(angle + 90) >> LV_TRIGO_SHIFT); + + lv_draw_line(&start, &end, mask, ext->indicator.style, opa_scale); + + if(ext->indicator.style->line.rounded) + { + lv_area_t circle_area; + circle_area.x1 = start.x - ((ext->indicator.style->line.width - 1) >> 1) - ((ext->indicator.style->line.width - 1) & 0x1); + circle_area.y1 = start.y - ((ext->indicator.style->line.width - 1) >> 1) - ((ext->indicator.style->line.width - 1) & 0x1); + circle_area.x2 = start.x + ((ext->indicator.style->line.width - 1) >> 1); + circle_area.y2 = start.y + ((ext->indicator.style->line.width - 1) >> 1); + lv_draw_rect(&circle_area, mask, ext->indicator.style, opa_scale); + + circle_area.x1 = end.x - ((ext->indicator.style->line.width - 1) >> 1) - ((ext->indicator.style->line.width - 1) & 0x1); + circle_area.y1 = end.y - ((ext->indicator.style->line.width - 1) >> 1) - ((ext->indicator.style->line.width - 1) & 0x1); + circle_area.x2 = end.x + ((ext->indicator.style->line.width - 1) >> 1); + circle_area.y2 = end.y + ((ext->indicator.style->line.width - 1) >> 1); + lv_draw_rect(&circle_area, mask, ext->indicator.style, opa_scale); + } } static void draw_disk_indicator_circle(lv_cpicker_ext_t * ext, lv_style_t * style, lv_area_t * mask, lv_opa_t opa_scale, - lv_coord_t r, lv_coord_t x, lv_coord_t y) + lv_coord_t x, lv_coord_t y, uint16_t r, uint16_t angle) { + uint32_t cx, cy; + cx = x + ((r - style->line.width/2) * lv_trigo_sin(angle) >> LV_TRIGO_SHIFT); + cy = y + ((r - style->line.width/2) * lv_trigo_sin(angle + 90) >> LV_TRIGO_SHIFT); + + lv_area_t circle_ind_area; + circle_ind_area.x1 = cx - style->line.width/2; + circle_ind_area.y1 = cy - style->line.width/2; + circle_ind_area.x2 = cx + style->line.width/2; + circle_ind_area.y2 = cy + style->line.width/2; + + lv_style_t styleCopy; + lv_style_copy(&styleCopy, ext->indicator.style); + styleCopy.body.radius = LV_RADIUS_CIRCLE; + + lv_draw_rect(&circle_ind_area, mask, &styleCopy, opa_scale); } static void draw_disk_indicator_in(lv_cpicker_ext_t * ext, lv_style_t * style, lv_area_t * mask, lv_opa_t opa_scale, - lv_coord_t rin, lv_coord_t x, lv_coord_t y) + lv_coord_t x, lv_coord_t y, uint16_t r, uint16_t angle, + uint16_t rin) { + uint16_t ind_radius = lv_sqrt((4*rin*rin)/2)/2 + 1 - style->body.padding.inner; + ind_radius = (ind_radius + rin) / 2; + + uint32_t cx = x + ((ind_radius) * lv_trigo_sin(angle) >> LV_TRIGO_SHIFT); + uint32_t cy = y + ((ind_radius) * lv_trigo_sin(angle + 90) >> LV_TRIGO_SHIFT); + + lv_area_t circle_ind_area; + circle_ind_area.x1 = cx - r; + circle_ind_area.y1 = cy - r; + circle_ind_area.x2 = cx + r; + circle_ind_area.y2 = cy + r; + + lv_style_t styleCopy; + lv_style_copy(&styleCopy, ext->indicator.style); + styleCopy.body.radius = LV_RADIUS_CIRCLE; + + lv_draw_rect(&circle_ind_area, mask, &styleCopy, opa_scale); } static void draw_disk_indicator(lv_cpicker_ext_t * ext, lv_style_t * style, lv_area_t * mask, lv_opa_t opa_scale, - lv_coord_t r, lv_coord_t x, lv_coord_t y, uint32_t rin) + lv_coord_t x, lv_coord_t y, lv_coord_t r, uint16_t angle, + uint16_t rin, uint16_t radius, lv_area_t center_ind_area) { + /*draw center background*/ + static lv_style_t styleCenterBackground; + lv_theme_t * th = lv_theme_get_current(); + if (th) { + lv_style_copy(&styleCenterBackground, th->style.bg); + } else { + lv_style_copy(&styleCenterBackground, &lv_style_plain); + } + + lv_area_t center_area; + center_area.x1 = x - rin; + center_area.y1 = y - rin; + center_area.x2 = x + rin; + center_area.y2 = y + rin; + styleCenterBackground.body.radius = LV_RADIUS_CIRCLE; + lv_draw_rect(¢er_area, mask, &styleCenterBackground, opa_scale); + + /*draw the center color indicator*/ + style->body.main_color = lv_color_hsv_to_rgb(ext->hue, ext->saturation, ext->value); + style->body.grad_color = style->body.main_color; + style->body.radius = LV_RADIUS_CIRCLE; + lv_draw_rect(¢er_ind_area, mask, style, opa_scale); + + /*draw the current hue indicator*/ + switch(ext->indicator.type) + { + case LV_CPICKER_INDICATOR_NONE: + break; + case LV_CPICKER_INDICATOR_LINE: + { + draw_disk_indicator_line(ext, style, mask, opa_scale, x, y, r, angle); + break; + } + case LV_CPICKER_INDICATOR_CIRCLE: + { + draw_disk_indicator_circle(ext, style, mask, opa_scale, x, y, r, angle); + break; + } + case LV_CPICKER_INDICATOR_IN: + { + draw_disk_indicator_in(ext, style, mask, opa_scale, x, y, (rin - radius) / 3, angle, rin); + break; + } + } } static void draw_disk_spectrum(lv_cpicker_ext_t * ext, lv_style_t * style, lv_area_t * mask, lv_opa_t opa_scale, @@ -481,10 +583,10 @@ static void draw_rect_spectrum(lv_cpicker_ext_t * ext, lv_style_t * style, lv_ar { } -static bool lv_cpicker_disc_design(lv_obj_t * cpicker, const lv_area_t * mask, lv_design_mode_t mode, - lv_cpicker_ext_t * ext, lv_style_t * style); -static bool lv_cpicker_rect_design(lv_obj_t * cpicker, const lv_area_t * mask, lv_design_mode_t mode, - lv_cpicker_ext_t * ext, lv_style_t * style); +static void lv_cpicker_disc_design(lv_obj_t * cpicker, const lv_area_t * mask, lv_style_t * style, lv_opa_t opa_scale, + lv_cpicker_ext_t * ext, lv_coord_t w, lv_coord_t h); +static void lv_cpicker_rect_design(lv_obj_t * cpicker, const lv_area_t * mask, lv_style_t * style, lv_opa_t opa_scale, + lv_cpicker_ext_t * ext, lv_coord_t w, lv_coord_t h); /** * Handle the drawing related tasks of the color_picker @@ -511,13 +613,18 @@ static bool lv_cpicker_design(lv_obj_t * cpicker, const lv_area_t * mask, lv_des static lv_style_t styleCopy; lv_style_copy(&styleCopy, style); + lv_opa_t opa_scale = lv_obj_get_opa_scale(cpicker); + + lv_coord_t w = lv_obj_get_width(cpicker); + lv_coord_t h = lv_obj_get_height(cpicker); + if(ext->type == LV_CPICKER_TYPE_DISC) { - return lv_cpicker_disc_design(cpicker, mask, mode, ext, &styleCopy); + lv_cpicker_disc_design(cpicker, mask, &styleCopy, opa_scale, ext, w, h); } else if(ext->type == LV_CPICKER_TYPE_RECT) { - return lv_cpicker_rect_design(cpicker, mask, mode, ext, &styleCopy); + lv_cpicker_rect_design(cpicker, mask, &styleCopy, opa_scale, ext, w, h); } } /*Post draw when the children are drawn*/ @@ -528,27 +635,15 @@ static bool lv_cpicker_design(lv_obj_t * cpicker, const lv_area_t * mask, lv_des return true; } -static bool lv_cpicker_disc_design(lv_obj_t * cpicker, const lv_area_t * mask, lv_design_mode_t mode, - lv_cpicker_ext_t * ext, lv_style_t * style) +static void lv_cpicker_disc_design(lv_obj_t * cpicker, const lv_area_t * mask, lv_style_t * style, lv_opa_t opa_scale, + lv_cpicker_ext_t * ext, lv_coord_t w, lv_coord_t h) { - static lv_style_t styleCenterBackground; - lv_theme_t * th = lv_theme_get_current(); - if (th) { - lv_style_copy(&styleCenterBackground, th->style.bg); - } else { - lv_style_copy(&styleCenterBackground, &lv_style_plain); - } + lv_coord_t x = cpicker->coords.x1 + w / 2; + lv_coord_t y = cpicker->coords.y1 + h / 2; - lv_coord_t r = (LV_MATH_MIN(lv_obj_get_width(cpicker), lv_obj_get_height(cpicker))) / 2; - lv_coord_t x = cpicker->coords.x1 + lv_obj_get_width(cpicker) / 2; - lv_coord_t y = cpicker->coords.y1 + lv_obj_get_height(cpicker) / 2; - lv_opa_t opa_scale = lv_obj_get_opa_scale(cpicker); + uint16_t r = LV_MATH_MIN(w, h) / 2; - uint8_t redraw_wheel = 0; - - lv_area_t center_ind_area; - - uint32_t rin = r - style->line.width; + uint16_t rin = r - style->line.width; //the square area (a and b being sides) should fit into the center of diameter d //we have: //a^2+b^2<=d^2 @@ -557,12 +652,14 @@ static bool lv_cpicker_disc_design(lv_obj_t * cpicker, const lv_area_t * mask, l //a <= sqrt((d^2)/2) uint16_t radius = lv_sqrt((4*rin*rin)/2)/2 - style->body.padding.inner; + lv_area_t center_ind_area; center_ind_area.x1 = x - radius; center_ind_area.y1 = y - radius; center_ind_area.x2 = x + radius; center_ind_area.y2 = y + radius; /*redraw the wheel only if the mask intersect with the wheel*/ + uint8_t redraw_wheel = 0; if(mask->x1 < center_ind_area.x1 || mask->x2 > center_ind_area.x2 || mask->y1 < center_ind_area.y1 || mask->y2 > center_ind_area.y2) { @@ -758,115 +855,11 @@ static bool lv_cpicker_disc_design(lv_obj_t * cpicker, const lv_area_t * mask, l } } - /*draw center background*/ - lv_area_t center_area; - uint16_t wradius = r - style->line.width; - center_area.x1 = x - wradius; - center_area.y1 = y - wradius; - center_area.x2 = x + wradius; - center_area.y2 = y + wradius; - styleCenterBackground.body.radius = LV_RADIUS_CIRCLE; - lv_draw_rect(¢er_area, mask, &styleCenterBackground, opa_scale); + uint16_t angle = mode_color_to_angle(ext); + /*save the angle to refresh the area later*/ + ext->prev_pos = angle; - /*draw the center color indicator*/ - style->body.main_color = lv_color_hsv_to_rgb(ext->hue, ext->saturation, ext->value); - style->body.grad_color = style->body.main_color; - style->body.radius = LV_RADIUS_CIRCLE; - lv_draw_rect(¢er_ind_area, mask, style, opa_scale); - - /*draw the current hue indicator*/ - switch(ext->indicator.type) - { - case LV_CPICKER_INDICATOR_NONE: - break; - case LV_CPICKER_INDICATOR_LINE: - { - lv_point_t start; - lv_point_t end; - - uint16_t angle = mode_color_to_angle(ext); - - /*save the angle to refresh the area later*/ - ext->prev_pos = angle; - - start.x = x + ((r - style->line.width + ext->indicator.style->body.padding.inner + ext->indicator.style->line.width/2) * lv_trigo_sin(angle) >> LV_TRIGO_SHIFT); - start.y = y + ((r - style->line.width + ext->indicator.style->body.padding.inner + ext->indicator.style->line.width/2) * lv_trigo_sin(angle + 90) >> LV_TRIGO_SHIFT); - - end.x = x + ((r - ext->indicator.style->body.padding.inner - ext->indicator.style->line.width/2) * lv_trigo_sin(angle) >> LV_TRIGO_SHIFT); - end.y = y + ((r - ext->indicator.style->body.padding.inner - ext->indicator.style->line.width/2) * lv_trigo_sin(angle + 90) >> LV_TRIGO_SHIFT); - - lv_draw_line(&start, &end, mask, ext->indicator.style, opa_scale); - if(ext->indicator.style->line.rounded) - { - lv_area_t circle_area; - circle_area.x1 = start.x - ((ext->indicator.style->line.width - 1) >> 1) - ((ext->indicator.style->line.width - 1) & 0x1); - circle_area.y1 = start.y - ((ext->indicator.style->line.width - 1) >> 1) - ((ext->indicator.style->line.width - 1) & 0x1); - circle_area.x2 = start.x + ((ext->indicator.style->line.width - 1) >> 1); - circle_area.y2 = start.y + ((ext->indicator.style->line.width - 1) >> 1); - lv_draw_rect(&circle_area, mask, ext->indicator.style, opa_scale); - - circle_area.x1 = end.x - ((ext->indicator.style->line.width - 1) >> 1) - ((ext->indicator.style->line.width - 1) & 0x1); - circle_area.y1 = end.y - ((ext->indicator.style->line.width - 1) >> 1) - ((ext->indicator.style->line.width - 1) & 0x1); - circle_area.x2 = end.x + ((ext->indicator.style->line.width - 1) >> 1); - circle_area.y2 = end.y + ((ext->indicator.style->line.width - 1) >> 1); - lv_draw_rect(&circle_area, mask, ext->indicator.style, opa_scale); - } - break; - } - case LV_CPICKER_INDICATOR_CIRCLE: - { - lv_area_t circle_ind_area; - uint32_t cx, cy; - - uint16_t angle = mode_color_to_angle(ext); - - /*save the angle to refresh the area later*/ - ext->prev_pos = angle; - - cx = x + ((r - style->line.width/2) * lv_trigo_sin(angle) >> LV_TRIGO_SHIFT); - cy = y + ((r - style->line.width/2) * lv_trigo_sin(angle + 90) >> LV_TRIGO_SHIFT); - - circle_ind_area.x1 = cx - style->line.width/2; - circle_ind_area.y1 = cy - style->line.width/2; - circle_ind_area.x2 = cx + style->line.width/2; - circle_ind_area.y2 = cy + style->line.width/2; - - lv_style_t styleCopy; - lv_style_copy(&styleCopy, ext->indicator.style); - styleCopy.body.radius = LV_RADIUS_CIRCLE; - - lv_draw_rect(&circle_ind_area, mask, &styleCopy, opa_scale); - break; - } - case LV_CPICKER_INDICATOR_IN: - { - lv_area_t circle_ind_area; - uint32_t cx, cy; - - uint16_t angle = mode_color_to_angle(ext); - - /*save the angle to refresh the area later*/ - ext->prev_pos = angle; - - uint16_t ind_radius = lv_sqrt((4*rin*rin)/2)/2 + 1 - style->body.padding.inner; - ind_radius = (ind_radius + rin) / 2; - - cx = x + ((ind_radius) * lv_trigo_sin(angle) >> LV_TRIGO_SHIFT); - cy = y + ((ind_radius) * lv_trigo_sin(angle + 90) >> LV_TRIGO_SHIFT); - - circle_ind_area.x1 = cx - ((wradius - radius) / 3); - circle_ind_area.y1 = cy - ((wradius - radius) / 3); - circle_ind_area.x2 = cx + ((wradius - radius) / 3); - circle_ind_area.y2 = cy + ((wradius - radius) / 3); - - lv_style_t styleCopy; - lv_style_copy(&styleCopy, ext->indicator.style); - styleCopy.body.radius = LV_RADIUS_CIRCLE; - - lv_draw_rect(&circle_ind_area, mask, &styleCopy, opa_scale); - break; - } - } /* switch */ + draw_disk_indicator(ext, style, mask, opa_scale, x, y, r, angle, rin, radius, center_ind_area); /* //code to color the drawn area @@ -878,21 +871,15 @@ static bool lv_cpicker_disc_design(lv_obj_t * cpicker, const lv_area_t * mask, l c += 0x123445678; lv_draw_rect(mask, mask, &style2, opa_scale); */ - - return true; } -static bool lv_cpicker_rect_design(lv_obj_t * cpicker, const lv_area_t * mask, lv_design_mode_t mode, - lv_cpicker_ext_t * ext, lv_style_t * style) +static void lv_cpicker_rect_design(lv_obj_t * cpicker, const lv_area_t * mask, lv_style_t * style, lv_opa_t opa_scale, + lv_cpicker_ext_t * ext, lv_coord_t w, lv_coord_t h) { - lv_coord_t w = lv_obj_get_width(cpicker); - lv_coord_t h = lv_obj_get_height(cpicker); - lv_coord_t x1 = cpicker->coords.x1; lv_coord_t y1 = cpicker->coords.y1; lv_coord_t x2 = cpicker->coords.x2; lv_coord_t y2 = cpicker->coords.y2; - lv_opa_t opa_scale = lv_obj_get_opa_scale(cpicker); /*prepare the color preview area*/ uint16_t preview_offset = style->line.width; @@ -1117,8 +1104,6 @@ static bool lv_cpicker_rect_design(lv_obj_t * cpicker, const lv_area_t * mask, l default: break; } - - return true; } From 280c291db7880fd9767244201ae4afdb6d2022da Mon Sep 17 00:00:00 2001 From: Paul Peavyhouse Date: Thu, 26 Sep 2019 15:27:12 -0700 Subject: [PATCH 19/82] Cleaned up and ready for [hopefully] final code review! --- src/lv_objx/lv_cpicker.c | 2179 ++++++++++++++++++-------------------- 1 file changed, 1008 insertions(+), 1171 deletions(-) diff --git a/src/lv_objx/lv_cpicker.c b/src/lv_objx/lv_cpicker.c index c4c91ce74..9889c248e 100644 --- a/src/lv_objx/lv_cpicker.c +++ b/src/lv_objx/lv_cpicker.c @@ -67,8 +67,6 @@ static bool lv_cpicker_design(lv_obj_t * cpicker, const lv_area_t * mask, lv_design_mode_t mode); static lv_res_t lv_cpicker_signal(lv_obj_t * cpicker, lv_signal_t sign, void * param); -static void lv_cpicker_invalidate(lv_obj_t * cpicker, bool all); - /********************** * STATIC VARIABLES **********************/ @@ -386,6 +384,67 @@ lv_color_t lv_cpicker_get_color(lv_obj_t * cpicker) * STATIC FUNCTIONS **********************/ +static void lv_cpicker_disc_design(lv_obj_t * cpicker, + lv_area_t * mask, lv_style_t * style, lv_opa_t opa_scale, + lv_cpicker_ext_t * ext, + lv_coord_t w, lv_coord_t h, + lv_coord_t cx, lv_coord_t cy, uint16_t r); +static void lv_cpicker_rect_design(lv_obj_t * cpicker, + lv_area_t * mask, lv_style_t * style, lv_opa_t opa_scale, + lv_cpicker_ext_t * ext, + lv_coord_t w, lv_coord_t h); + +/** + * Handle the drawing related tasks of the color_picker + * @param cpicker pointer to an object + * @param mask the object will be drawn only in this area + * @param mode LV_DESIGN_COVER_CHK: only check if the object fully covers the 'mask_p' area + * (return 'true' if yes) + * LV_DESIGN_DRAW: draw the object (always return 'true') + * LV_DESIGN_DRAW_POST: drawing after every children are drawn + * @return true/false, depends on 'mode' + */ +static bool lv_cpicker_design(lv_obj_t * cpicker, const lv_area_t * mask, lv_design_mode_t mode) +{ + /*Return false if the object is not covers the mask_p area*/ + if(mode == LV_DESIGN_COVER_CHK) + { + return false; + } + /*Draw the object*/ + else if(mode == LV_DESIGN_DRAW_MAIN) + { + lv_cpicker_ext_t * ext = lv_obj_get_ext_attr(cpicker); + lv_style_t * style = lv_cpicker_get_style(cpicker, LV_CPICKER_STYLE_MAIN); + + static lv_style_t styleCopy; + lv_style_copy(&styleCopy, style); + + lv_opa_t opa_scale = lv_obj_get_opa_scale(cpicker); + + lv_coord_t w = lv_obj_get_width(cpicker); + lv_coord_t h = lv_obj_get_height(cpicker); + + if(ext->type == LV_CPICKER_TYPE_DISC) + { + lv_coord_t cx = cpicker->coords.x1 + (w / 2); + lv_coord_t cy = cpicker->coords.y1 + (h / 2); + uint16_t r = LV_MATH_MIN(w, h) / 2; + lv_cpicker_disc_design(cpicker, mask, &styleCopy, opa_scale, ext, w, h, cx, cy, r); + } + else if(ext->type == LV_CPICKER_TYPE_RECT) + { + lv_cpicker_rect_design(cpicker, mask, &styleCopy, opa_scale, ext, w, h); + } + } + /*Post draw when the children are drawn*/ + else if(mode == LV_DESIGN_DRAW_POST) + { + } + + return true; +} + static lv_color_t angle_to_mode_color(lv_cpicker_ext_t * ext, uint16_t angle) { lv_color_t color; @@ -393,13 +452,13 @@ static lv_color_t angle_to_mode_color(lv_cpicker_ext_t * ext, uint16_t angle) { default: case LV_CPICKER_COLOR_MODE_HUE: - color = lv_color_hsv_to_rgb(angle%360, ext->saturation, ext->value); + color = lv_color_hsv_to_rgb(angle % 360, ext->saturation, ext->value); break; case LV_CPICKER_COLOR_MODE_SATURATION: - color = lv_color_hsv_to_rgb(ext->hue, (angle%360)/360.0*100.0, ext->value); + color = lv_color_hsv_to_rgb(ext->hue, (angle % 360) / 360.0 * 100.0, ext->value); break; case LV_CPICKER_COLOR_MODE_VALUE: - color = lv_color_hsv_to_rgb(ext->hue, ext->saturation, (angle%360)/360.0*100.0); + color = lv_color_hsv_to_rgb(ext->hue, ext->saturation, (angle % 360) / 360.0 * 100.0); break; } return color; @@ -424,15 +483,39 @@ static uint16_t mode_color_to_angle(lv_cpicker_ext_t * ext) return angle; } -static void draw_disk_indicator_line(lv_cpicker_ext_t * ext, lv_style_t * style, lv_area_t * mask, lv_opa_t opa_scale, - lv_coord_t x, lv_coord_t y, uint16_t r, uint16_t angle) +static lv_coord_t lv_cpicker_get_indicator_coord(lv_style_t * style, lv_cpicker_ext_t * ext) +{ + lv_coord_t ind_pos = style->line.rounded ? ext->rect_gradient_h / 2 : 0; + switch(ext->color_mode) + { + default: + case LV_CPICKER_COLOR_MODE_HUE: + ind_pos += ext->hue / 360.0 * ext->rect_gradient_w; + break; + case LV_CPICKER_COLOR_MODE_SATURATION: + ind_pos += ext->saturation / 100.0 * ext->rect_gradient_w; + break; + case LV_CPICKER_COLOR_MODE_VALUE: + ind_pos += ext->value / 100.0 * ext->rect_gradient_w; + break; + } + return ind_pos; +} + +/** + * Should roughly match up with `lv_cpicker_invalidate_disc_indicator_line` + */ +static void lv_cpicker_draw_disc_indicator_line(lv_area_t * mask, lv_style_t * style, lv_opa_t opa_scale, + lv_cpicker_ext_t * ext, + lv_coord_t cx, lv_coord_t cy, uint16_t r, + uint16_t angle) { lv_point_t start; lv_point_t end; - start.x = x + ((r - style->line.width + ext->indicator.style->body.padding.inner + ext->indicator.style->line.width/2) * lv_trigo_sin(angle) >> LV_TRIGO_SHIFT); - start.y = y + ((r - style->line.width + ext->indicator.style->body.padding.inner + ext->indicator.style->line.width/2) * lv_trigo_sin(angle + 90) >> LV_TRIGO_SHIFT); - end.x = x + ((r - ext->indicator.style->body.padding.inner - ext->indicator.style->line.width/2) * lv_trigo_sin(angle) >> LV_TRIGO_SHIFT); - end.y = y + ((r - ext->indicator.style->body.padding.inner - ext->indicator.style->line.width/2) * lv_trigo_sin(angle + 90) >> LV_TRIGO_SHIFT); + start.x = cx + ((r - style->line.width + ext->indicator.style->body.padding.inner + ext->indicator.style->line.width/2) * lv_trigo_sin(angle) >> LV_TRIGO_SHIFT); + start.y = cy + ((r - style->line.width + ext->indicator.style->body.padding.inner + ext->indicator.style->line.width/2) * lv_trigo_sin(angle + 90) >> LV_TRIGO_SHIFT); + end.x = cx + ((r - ext->indicator.style->body.padding.inner - ext->indicator.style->line.width/2) * lv_trigo_sin(angle) >> LV_TRIGO_SHIFT); + end.y = cy + ((r - ext->indicator.style->body.padding.inner - ext->indicator.style->line.width/2) * lv_trigo_sin(angle + 90) >> LV_TRIGO_SHIFT); lv_draw_line(&start, &end, mask, ext->indicator.style, opa_scale); @@ -453,52 +536,61 @@ static void draw_disk_indicator_line(lv_cpicker_ext_t * ext, lv_style_t * style, } } -static void draw_disk_indicator_circle(lv_cpicker_ext_t * ext, lv_style_t * style, lv_area_t * mask, lv_opa_t opa_scale, - lv_coord_t x, lv_coord_t y, uint16_t r, uint16_t angle) +/** + * Should roughly match up with `lv_cpicker_invalidate_disc_indicator_circle` + */ +static void lv_cpicker_draw_disc_indicator_circle(lv_area_t * mask, lv_style_t * style, lv_opa_t opa_scale, + lv_cpicker_ext_t * ext, + lv_coord_t cx, lv_coord_t cy, uint16_t r, + uint16_t angle) { - uint32_t cx, cy; - cx = x + ((r - style->line.width/2) * lv_trigo_sin(angle) >> LV_TRIGO_SHIFT); - cy = y + ((r - style->line.width/2) * lv_trigo_sin(angle + 90) >> LV_TRIGO_SHIFT); + uint32_t ind_cx = cx + ((r - style->line.width/2) * lv_trigo_sin(angle) >> LV_TRIGO_SHIFT); + uint32_t ind_cy = cy + ((r - style->line.width/2) * lv_trigo_sin(angle + 90) >> LV_TRIGO_SHIFT); - lv_area_t circle_ind_area; - circle_ind_area.x1 = cx - style->line.width/2; - circle_ind_area.y1 = cy - style->line.width/2; - circle_ind_area.x2 = cx + style->line.width/2; - circle_ind_area.y2 = cy + style->line.width/2; + lv_area_t ind_area; + ind_area.x1 = ind_cx - style->line.width/2; + ind_area.y1 = ind_cy - style->line.width/2; + ind_area.x2 = ind_cx + style->line.width/2; + ind_area.y2 = ind_cy + style->line.width/2; lv_style_t styleCopy; lv_style_copy(&styleCopy, ext->indicator.style); styleCopy.body.radius = LV_RADIUS_CIRCLE; - lv_draw_rect(&circle_ind_area, mask, &styleCopy, opa_scale); + lv_draw_rect(&ind_area, mask, &styleCopy, opa_scale); } -static void draw_disk_indicator_in(lv_cpicker_ext_t * ext, lv_style_t * style, lv_area_t * mask, lv_opa_t opa_scale, - lv_coord_t x, lv_coord_t y, uint16_t r, uint16_t angle, - uint16_t rin) +/** + * Should roughly match up with `lv_cpicker_invalidate_disc_indicator_in` + */ +static void lv_cpicker_draw_disc_indicator_in(lv_area_t * mask, lv_style_t * style, lv_opa_t opa_scale, + lv_cpicker_ext_t * ext, + lv_coord_t cx, lv_coord_t cy, uint16_t r, + uint16_t rin, uint16_t angle) { uint16_t ind_radius = lv_sqrt((4*rin*rin)/2)/2 + 1 - style->body.padding.inner; ind_radius = (ind_radius + rin) / 2; - uint32_t cx = x + ((ind_radius) * lv_trigo_sin(angle) >> LV_TRIGO_SHIFT); - uint32_t cy = y + ((ind_radius) * lv_trigo_sin(angle + 90) >> LV_TRIGO_SHIFT); + uint32_t ind_cx = cx + ((ind_radius) * lv_trigo_sin(angle) >> LV_TRIGO_SHIFT); + uint32_t ind_cy = cy + ((ind_radius) * lv_trigo_sin(angle + 90) >> LV_TRIGO_SHIFT); - lv_area_t circle_ind_area; - circle_ind_area.x1 = cx - r; - circle_ind_area.y1 = cy - r; - circle_ind_area.x2 = cx + r; - circle_ind_area.y2 = cy + r; + lv_area_t ind_area; + ind_area.x1 = ind_cx - r; + ind_area.y1 = ind_cy - r; + ind_area.x2 = ind_cx + r; + ind_area.y2 = ind_cy + r; lv_style_t styleCopy; lv_style_copy(&styleCopy, ext->indicator.style); styleCopy.body.radius = LV_RADIUS_CIRCLE; - lv_draw_rect(&circle_ind_area, mask, &styleCopy, opa_scale); + lv_draw_rect(&ind_area, mask, &styleCopy, opa_scale); } -static void draw_disk_indicator(lv_cpicker_ext_t * ext, lv_style_t * style, lv_area_t * mask, lv_opa_t opa_scale, - lv_coord_t x, lv_coord_t y, lv_coord_t r, uint16_t angle, - uint16_t rin, uint16_t radius, lv_area_t center_ind_area) +static void lv_cpicker_draw_disc_indicator(lv_area_t * mask, lv_style_t * style, lv_opa_t opa_scale, + lv_cpicker_ext_t * ext, + lv_coord_t cx, lv_coord_t cy, lv_coord_t r, + uint16_t rin, uint16_t radius, lv_area_t center_ind_area) { /*draw center background*/ static lv_style_t styleCenterBackground; @@ -510,10 +602,10 @@ static void draw_disk_indicator(lv_cpicker_ext_t * ext, lv_style_t * style, lv_a } lv_area_t center_area; - center_area.x1 = x - rin; - center_area.y1 = y - rin; - center_area.x2 = x + rin; - center_area.y2 = y + rin; + center_area.x1 = cx - rin; + center_area.y1 = cy - rin; + center_area.x2 = cx + rin; + center_area.y2 = cy + rin; styleCenterBackground.body.radius = LV_RADIUS_CIRCLE; lv_draw_rect(¢er_area, mask, &styleCenterBackground, opa_scale); @@ -523,343 +615,248 @@ static void draw_disk_indicator(lv_cpicker_ext_t * ext, lv_style_t * style, lv_a style->body.radius = LV_RADIUS_CIRCLE; lv_draw_rect(¢er_ind_area, mask, style, opa_scale); - /*draw the current hue indicator*/ - switch(ext->indicator.type) - { - case LV_CPICKER_INDICATOR_NONE: - break; - case LV_CPICKER_INDICATOR_LINE: - { - draw_disk_indicator_line(ext, style, mask, opa_scale, x, y, r, angle); - break; - } - case LV_CPICKER_INDICATOR_CIRCLE: - { - draw_disk_indicator_circle(ext, style, mask, opa_scale, x, y, r, angle); - break; - } - case LV_CPICKER_INDICATOR_IN: - { - draw_disk_indicator_in(ext, style, mask, opa_scale, x, y, (rin - radius) / 3, angle, rin); - break; - } - } -} - -static void draw_disk_spectrum(lv_cpicker_ext_t * ext, lv_style_t * style, lv_area_t * mask, lv_opa_t opa_scale, - lv_coord_t r, lv_coord_t x, lv_coord_t y) -{ -} - -static void draw_rect_indicator_line(lv_cpicker_ext_t * ext, lv_style_t * style, lv_area_t * mask, lv_opa_t opa_scale, - lv_coord_t gradient_w, lv_coord_t gradient_h, lv_area_t gradient_area, lv_coord_t ind_pos) -{ -} - -static void draw_rect_indicator_circle(lv_cpicker_ext_t * ext, lv_style_t * style, lv_area_t * mask, lv_opa_t opa_scale, - lv_coord_t gradient_w, lv_coord_t gradient_h, lv_area_t gradient_area, lv_coord_t ind_pos) -{ -} - -static void draw_rect_indicator_in(lv_cpicker_ext_t * ext, lv_style_t * style, lv_area_t * mask, lv_opa_t opa_scale, - lv_coord_t gradient_w, lv_coord_t gradient_h, lv_area_t gradient_area, lv_coord_t ind_pos) -{ -} - -static void draw_rect_indicator(lv_cpicker_ext_t * ext, lv_style_t * style, lv_area_t * mask, lv_opa_t opa_scale, - lv_coord_t gradient_w, lv_coord_t gradient_h, lv_area_t gradient_area) -{ -} - -static void calculate_preview_area(lv_style_t * style, - lv_coord_t * gradient_w, lv_coord_t * gradient_h, lv_area_t * gradient_area, lv_area_t * preview_area, - uint16_t * style_body_padding_ver, uint16_t * style_body_padding_hor, - lv_coord_t w, lv_coord_t h, lv_coord_t x1, lv_coord_t y1, lv_coord_t x2, lv_coord_t y2) -{ -} - -static void draw_rect_spectrum(lv_cpicker_ext_t * ext, lv_style_t * style, lv_area_t * mask, lv_opa_t opa_scale, - lv_coord_t w, lv_coord_t h, lv_coord_t x1, lv_coord_t y1, lv_coord_t x2, lv_coord_t y2) -{ -} - -static void lv_cpicker_disc_design(lv_obj_t * cpicker, const lv_area_t * mask, lv_style_t * style, lv_opa_t opa_scale, - lv_cpicker_ext_t * ext, lv_coord_t w, lv_coord_t h); -static void lv_cpicker_rect_design(lv_obj_t * cpicker, const lv_area_t * mask, lv_style_t * style, lv_opa_t opa_scale, - lv_cpicker_ext_t * ext, lv_coord_t w, lv_coord_t h); - -/** - * Handle the drawing related tasks of the color_picker - * @param cpicker pointer to an object - * @param mask the object will be drawn only in this area - * @param mode LV_DESIGN_COVER_CHK: only check if the object fully covers the 'mask_p' area - * (return 'true' if yes) - * LV_DESIGN_DRAW: draw the object (always return 'true') - * LV_DESIGN_DRAW_POST: drawing after every children are drawn - * @return true/false, depends on 'mode' - */ -static bool lv_cpicker_design(lv_obj_t * cpicker, const lv_area_t * mask, lv_design_mode_t mode) -{ - /*Return false if the object is not covers the mask_p area*/ - if(mode == LV_DESIGN_COVER_CHK) { - return false; - } - /*Draw the object*/ - else if(mode == LV_DESIGN_DRAW_MAIN) { - - lv_cpicker_ext_t * ext = lv_obj_get_ext_attr(cpicker); - lv_style_t * style = lv_cpicker_get_style(cpicker, LV_CPICKER_STYLE_MAIN); - - static lv_style_t styleCopy; - lv_style_copy(&styleCopy, style); - - lv_opa_t opa_scale = lv_obj_get_opa_scale(cpicker); - - lv_coord_t w = lv_obj_get_width(cpicker); - lv_coord_t h = lv_obj_get_height(cpicker); - - if(ext->type == LV_CPICKER_TYPE_DISC) - { - lv_cpicker_disc_design(cpicker, mask, &styleCopy, opa_scale, ext, w, h); - } - else if(ext->type == LV_CPICKER_TYPE_RECT) - { - lv_cpicker_rect_design(cpicker, mask, &styleCopy, opa_scale, ext, w, h); - } - } - /*Post draw when the children are drawn*/ - else if(mode == LV_DESIGN_DRAW_POST) { - - } - - return true; -} - -static void lv_cpicker_disc_design(lv_obj_t * cpicker, const lv_area_t * mask, lv_style_t * style, lv_opa_t opa_scale, - lv_cpicker_ext_t * ext, lv_coord_t w, lv_coord_t h) -{ - lv_coord_t x = cpicker->coords.x1 + w / 2; - lv_coord_t y = cpicker->coords.y1 + h / 2; - - uint16_t r = LV_MATH_MIN(w, h) / 2; - - uint16_t rin = r - style->line.width; - //the square area (a and b being sides) should fit into the center of diameter d - //we have: - //a^2+b^2<=d^2 - //2a^2 <= d^2 - //a^2<=(d^2)/2 - //a <= sqrt((d^2)/2) - uint16_t radius = lv_sqrt((4*rin*rin)/2)/2 - style->body.padding.inner; - - lv_area_t center_ind_area; - center_ind_area.x1 = x - radius; - center_ind_area.y1 = y - radius; - center_ind_area.x2 = x + radius; - center_ind_area.y2 = y + radius; - - /*redraw the wheel only if the mask intersect with the wheel*/ - uint8_t redraw_wheel = 0; - if(mask->x1 < center_ind_area.x1 || mask->x2 > center_ind_area.x2 - || mask->y1 < center_ind_area.y1 || mask->y2 > center_ind_area.y2) - { - redraw_wheel = 1; - } - - lv_point_t triangle_points[3]; - - int16_t start_angle, end_angle; - start_angle = 0; //Default - end_angle = 360 - LV_CPICKER_DEF_QF; //Default - - if(redraw_wheel) - { - /*if the mask does not include the center of the object - * redrawing all the wheel is not necessary; - * only a given angular range - */ - lv_point_t center = {x, y}; - if(!lv_area_is_point_on(mask, ¢er) - /* - && (mask->x1 != cpicker->coords.x1 || mask->x2 != cpicker->coords.x2 - || mask->y1 != cpicker->coords.y1 || mask->y2 != cpicker->coords.y2) - */ - ) - { - /*get angle from center of object to each corners of the area*/ - int16_t dr, ur, ul, dl; - dr = lv_atan2(mask->x2 - x, mask->y2 - y); - ur = lv_atan2(mask->x2 - x, mask->y1 - y); - ul = lv_atan2(mask->x1 - x, mask->y1 - y); - dl = lv_atan2(mask->x1 - x, mask->y2 - y); - - /* check area position from object axis*/ - uint8_t left = (mask->x2 < x && mask->x1 < x); - uint8_t onYaxis = (mask->x2 > x && mask->x1 < x); - uint8_t right = (mask->x2 > x && mask->x1 > x); - uint8_t top = (mask->y2 < y && mask->y1 < y); - uint8_t onXaxis = (mask->y2 > y && mask->y1 < y); - uint8_t bottom = (mask->y2 > y && mask->y1 > x); - - /*store angular range*/ - if(right && bottom) - { - start_angle = dl; - end_angle = ur; - } - else if(right && onXaxis) - { - start_angle = dl; - end_angle = ul; - } - else if(right && top) - { - start_angle = dr; - end_angle = ul; - } - else if(onYaxis && top) - { - start_angle = dr; - end_angle = dl; - } - else if(left && top) - { - start_angle = ur; - end_angle = dl; - } - else if(left && onXaxis) - { - start_angle = ur; - end_angle = dr; - } - else if(left && bottom) - { - start_angle = ul; - end_angle = dr; - } - else if(onYaxis && bottom) - { - start_angle = ul; - end_angle = ur; - } - - /*rollover angle*/ - if(start_angle > end_angle) - { - end_angle += 360; - } - - /*round to QF factor*/ - start_angle = start_angle/LV_CPICKER_DEF_QF*LV_CPICKER_DEF_QF; - end_angle = end_angle/LV_CPICKER_DEF_QF*LV_CPICKER_DEF_QF;; - - /*shift angle if necessary before adding offset*/ - if((start_angle - LV_CPICKER_DEF_QF) < 0) - { - start_angle += 360; - end_angle += 360; - } - - /*ensure overlapping by adding offset*/ - start_angle -= LV_CPICKER_DEF_QF; - end_angle += LV_CPICKER_DEF_QF; - } - - if(ext->color_mode == LV_CPICKER_COLOR_MODE_HUE) - { - for(uint16_t i = start_angle; i <= end_angle; i+= LV_CPICKER_DEF_QF) - { - style->body.main_color = angle_to_mode_color(ext, i); - style->body.grad_color = style->body.main_color; - - triangle_points[0].x = x; - triangle_points[0].y = y; - - triangle_points[1].x = x + (r * lv_trigo_sin(i) >> LV_TRIGO_SHIFT); - triangle_points[1].y = y + (r * lv_trigo_sin(i + 90) >> LV_TRIGO_SHIFT); - - - if(i == end_angle || i == (360 - LV_CPICKER_DEF_QF)) - { - /*the last triangle is drawn without additional overlapping pixels*/ - triangle_points[2].x = x + (r * lv_trigo_sin(i + LV_CPICKER_DEF_QF) >> LV_TRIGO_SHIFT); - triangle_points[2].y = y + (r * lv_trigo_sin(i + LV_CPICKER_DEF_QF + 90) >> LV_TRIGO_SHIFT); - - } - else - { - triangle_points[2].x = x + (r * lv_trigo_sin(i + LV_CPICKER_DEF_QF + TRI_OFFSET) >> LV_TRIGO_SHIFT); - triangle_points[2].y = y + (r * lv_trigo_sin(i + LV_CPICKER_DEF_QF + TRI_OFFSET + 90) >> LV_TRIGO_SHIFT); - - } - - lv_draw_triangle(triangle_points, mask, style, LV_OPA_COVER); - } - } - else if(ext->color_mode == LV_CPICKER_COLOR_MODE_SATURATION) - { - for(uint16_t i = start_angle; i <= end_angle; i += LV_CPICKER_DEF_QF) - { - style->body.main_color = angle_to_mode_color(ext, i); - style->body.grad_color = style->body.main_color; - - triangle_points[0].x = x; - triangle_points[0].y = y; - - triangle_points[1].x = x + (r * lv_trigo_sin(i) >> LV_TRIGO_SHIFT); - triangle_points[1].y = y + (r * lv_trigo_sin(i + 90) >> LV_TRIGO_SHIFT); - - if(i == end_angle || i == (360 - LV_CPICKER_DEF_QF)) - { - /*the last triangle is drawn without additional overlapping pixels*/ - triangle_points[2].x = x + (r * lv_trigo_sin(i + LV_CPICKER_DEF_QF) >> LV_TRIGO_SHIFT); - triangle_points[2].y = y + (r * lv_trigo_sin(i + LV_CPICKER_DEF_QF + 90) >> LV_TRIGO_SHIFT); - } - else - { - triangle_points[2].x = x + (r * lv_trigo_sin(i + LV_CPICKER_DEF_QF + TRI_OFFSET) >> LV_TRIGO_SHIFT); - triangle_points[2].y = y + (r * lv_trigo_sin(i + LV_CPICKER_DEF_QF + TRI_OFFSET + 90) >> LV_TRIGO_SHIFT); - } - - lv_draw_triangle(triangle_points, mask, style, LV_OPA_COVER); - } - } - else if(ext->color_mode == LV_CPICKER_COLOR_MODE_VALUE) - { - for(uint16_t i = start_angle; i <= end_angle; i += LV_CPICKER_DEF_QF) - { - style->body.main_color = angle_to_mode_color(ext, i); - style->body.grad_color = style->body.main_color; - - triangle_points[0].x = x; - triangle_points[0].y = y; - - triangle_points[1].x = x + (r * lv_trigo_sin(i) >> LV_TRIGO_SHIFT); - triangle_points[1].y = y + (r * lv_trigo_sin(i + 90) >> LV_TRIGO_SHIFT); - - if(i == end_angle || i == (360 - LV_CPICKER_DEF_QF)) - { - /*the last triangle is drawn without additional overlapping pixels*/ - triangle_points[2].x = x + (r * lv_trigo_sin(i + LV_CPICKER_DEF_QF) >> LV_TRIGO_SHIFT); - triangle_points[2].y = y + (r * lv_trigo_sin(i + LV_CPICKER_DEF_QF + 90) >> LV_TRIGO_SHIFT); - - } - else - { - triangle_points[2].x = x + (r * lv_trigo_sin(i + LV_CPICKER_DEF_QF + TRI_OFFSET) >> LV_TRIGO_SHIFT); - triangle_points[2].y = y + (r * lv_trigo_sin(i + LV_CPICKER_DEF_QF + TRI_OFFSET + 90) >> LV_TRIGO_SHIFT); - } - - lv_draw_triangle(triangle_points, mask, style, LV_OPA_COVER); - } - } - } - uint16_t angle = mode_color_to_angle(ext); /*save the angle to refresh the area later*/ ext->prev_pos = angle; - draw_disk_indicator(ext, style, mask, opa_scale, x, y, r, angle, rin, radius, center_ind_area); + /*draw the current hue indicator*/ + switch(ext->indicator.type) + { + case LV_CPICKER_INDICATOR_NONE: + /*no indicator*/ + break; + case LV_CPICKER_INDICATOR_LINE: + lv_cpicker_draw_disc_indicator_line(mask, style, opa_scale, ext, cx, cy, r, angle); + break; + case LV_CPICKER_INDICATOR_CIRCLE: + lv_cpicker_draw_disc_indicator_circle(mask, style, opa_scale, ext, cx, cy, r, angle); + break; + case LV_CPICKER_INDICATOR_IN: + lv_cpicker_draw_disc_indicator_in(mask, style, opa_scale, ext, cx, cy, (rin - radius) / 3, rin, angle); + break; + } +} + +static void lv_cpicker_draw_disc_gradient(lv_area_t * mask, lv_style_t * style, lv_opa_t opa_scale, + lv_cpicker_ext_t * ext, + lv_coord_t cx, lv_coord_t cy, uint16_t r) +{ + int16_t start_angle = 0; /*Default*/ + int16_t end_angle = 360 - LV_CPICKER_DEF_QF; /*Default*/ + + /*if the mask does not include the center of the object + * redrawing all the wheel is not necessary; + * only a given angular range + */ + lv_point_t center = {cx, cy}; + if(!lv_area_is_point_on(mask, ¢er) + /* + && (mask->x1 != cpicker->coords.x1 || mask->x2 != cpicker->coords.x2 + || mask->y1 != cpicker->coords.y1 || mask->y2 != cpicker->coords.y2) + */ + ) + { + /*get angle from center of object to each corners of the area*/ + int16_t dr, ur, ul, dl; + dr = lv_atan2(mask->x2 - cx, mask->y2 - cy); + ur = lv_atan2(mask->x2 - cx, mask->y1 - cy); + ul = lv_atan2(mask->x1 - cx, mask->y1 - cy); + dl = lv_atan2(mask->x1 - cx, mask->y2 - cy); + + /*check area position from object axis*/ + uint8_t left = (mask->x2 < cx && mask->x1 < cx); + uint8_t onYaxis = (mask->x2 > cx && mask->x1 < cx); + uint8_t right = (mask->x2 > cx && mask->x1 > cx); + uint8_t top = (mask->y2 < cy && mask->y1 < cy); + uint8_t onXaxis = (mask->y2 > cy && mask->y1 < cy); + uint8_t bottom = (mask->y2 > cy && mask->y1 > cy); + + /*store angular range*/ + if(right && bottom) + { + start_angle = dl; + end_angle = ur; + } + else if(right && onXaxis) + { + start_angle = dl; + end_angle = ul; + } + else if(right && top) + { + start_angle = dr; + end_angle = ul; + } + else if(onYaxis && top) + { + start_angle = dr; + end_angle = dl; + } + else if(left && top) + { + start_angle = ur; + end_angle = dl; + } + else if(left && onXaxis) + { + start_angle = ur; + end_angle = dr; + } + else if(left && bottom) + { + start_angle = ul; + end_angle = dr; + } + else if(onYaxis && bottom) + { + start_angle = ul; + end_angle = ur; + } + + /*rollover angle*/ + if(start_angle > end_angle) + { + end_angle += 360; + } + + /*round to QF factor*/ + start_angle = start_angle/LV_CPICKER_DEF_QF*LV_CPICKER_DEF_QF; + end_angle = end_angle/LV_CPICKER_DEF_QF*LV_CPICKER_DEF_QF;; + + /*shift angle if necessary before adding offset*/ + if((start_angle - LV_CPICKER_DEF_QF) < 0) + { + start_angle += 360; + end_angle += 360; + } + + /*ensure overlapping by adding offset*/ + start_angle -= LV_CPICKER_DEF_QF; + end_angle += LV_CPICKER_DEF_QF; + } + + lv_point_t triangle_points[3]; + + if(ext->color_mode == LV_CPICKER_COLOR_MODE_HUE) + { + for(uint16_t i = start_angle; i <= end_angle; i+= LV_CPICKER_DEF_QF) + { + style->body.main_color = angle_to_mode_color(ext, i); + style->body.grad_color = style->body.main_color; + + triangle_points[0].x = cx; + triangle_points[0].y = cy; + + triangle_points[1].x = cx + (r * lv_trigo_sin(i) >> LV_TRIGO_SHIFT); + triangle_points[1].y = cy + (r * lv_trigo_sin(i + 90) >> LV_TRIGO_SHIFT); + + if(i == end_angle || i == (360 - LV_CPICKER_DEF_QF)) + { + /*the last triangle is drawn without additional overlapping pixels*/ + triangle_points[2].x = cx + (r * lv_trigo_sin(i + LV_CPICKER_DEF_QF) >> LV_TRIGO_SHIFT); + triangle_points[2].y = cy + (r * lv_trigo_sin(i + LV_CPICKER_DEF_QF + 90) >> LV_TRIGO_SHIFT); + } + else + { + triangle_points[2].x = cx + (r * lv_trigo_sin(i + LV_CPICKER_DEF_QF + TRI_OFFSET) >> LV_TRIGO_SHIFT); + triangle_points[2].y = cy + (r * lv_trigo_sin(i + LV_CPICKER_DEF_QF + TRI_OFFSET + 90) >> LV_TRIGO_SHIFT); + } + + lv_draw_triangle(triangle_points, mask, style, LV_OPA_COVER); + } + } + else if(ext->color_mode == LV_CPICKER_COLOR_MODE_SATURATION) + { + for(uint16_t i = start_angle; i <= end_angle; i += LV_CPICKER_DEF_QF) + { + style->body.main_color = angle_to_mode_color(ext, i); + style->body.grad_color = style->body.main_color; + + triangle_points[0].x = cx; + triangle_points[0].y = cy; + + triangle_points[1].x = cx + (r * lv_trigo_sin(i) >> LV_TRIGO_SHIFT); + triangle_points[1].y = cy + (r * lv_trigo_sin(i + 90) >> LV_TRIGO_SHIFT); + + if(i == end_angle || i == (360 - LV_CPICKER_DEF_QF)) + { + /*the last triangle is drawn without additional overlapping pixels*/ + triangle_points[2].x = cx + (r * lv_trigo_sin(i + LV_CPICKER_DEF_QF) >> LV_TRIGO_SHIFT); + triangle_points[2].y = cy + (r * lv_trigo_sin(i + LV_CPICKER_DEF_QF + 90) >> LV_TRIGO_SHIFT); + } + else + { + triangle_points[2].x = cx + (r * lv_trigo_sin(i + LV_CPICKER_DEF_QF + TRI_OFFSET) >> LV_TRIGO_SHIFT); + triangle_points[2].y = cy + (r * lv_trigo_sin(i + LV_CPICKER_DEF_QF + TRI_OFFSET + 90) >> LV_TRIGO_SHIFT); + } + + lv_draw_triangle(triangle_points, mask, style, LV_OPA_COVER); + } + } + else if(ext->color_mode == LV_CPICKER_COLOR_MODE_VALUE) + { + for(uint16_t i = start_angle; i <= end_angle; i += LV_CPICKER_DEF_QF) + { + style->body.main_color = angle_to_mode_color(ext, i); + style->body.grad_color = style->body.main_color; + + triangle_points[0].x = cx; + triangle_points[0].y = cy; + + triangle_points[1].x = cx + (r * lv_trigo_sin(i) >> LV_TRIGO_SHIFT); + triangle_points[1].y = cy + (r * lv_trigo_sin(i + 90) >> LV_TRIGO_SHIFT); + + if(i == end_angle || i == (360 - LV_CPICKER_DEF_QF)) + { + /*the last triangle is drawn without additional overlapping pixels*/ + triangle_points[2].x = cx + (r * lv_trigo_sin(i + LV_CPICKER_DEF_QF) >> LV_TRIGO_SHIFT); + triangle_points[2].y = cy + (r * lv_trigo_sin(i + LV_CPICKER_DEF_QF + 90) >> LV_TRIGO_SHIFT); + } + else + { + triangle_points[2].x = cx + (r * lv_trigo_sin(i + LV_CPICKER_DEF_QF + TRI_OFFSET) >> LV_TRIGO_SHIFT); + triangle_points[2].y = cy + (r * lv_trigo_sin(i + LV_CPICKER_DEF_QF + TRI_OFFSET + 90) >> LV_TRIGO_SHIFT); + } + + lv_draw_triangle(triangle_points, mask, style, LV_OPA_COVER); + } + } +} + +/** + * Should roughly match up with `lv_cpicker_invalidate_disc` + */ +static void lv_cpicker_disc_design(lv_obj_t * cpicker, + lv_area_t * mask, lv_style_t * style, lv_opa_t opa_scale, + lv_cpicker_ext_t * ext, + lv_coord_t w, lv_coord_t h, + lv_coord_t cx, lv_coord_t cy, uint16_t r) +{ + uint16_t rin = r - style->line.width; + /* + the square area (a and b being sides) should fit into the center of diameter d + we have: + a^2+b^2<=d^2 + 2a^2 <= d^2 + a^2<=(d^2)/2 + a <= sqrt((d^2)/2) + */ + uint16_t radius = lv_sqrt((4*rin*rin)/2)/2 - style->body.padding.inner; + + lv_area_t center_ind_area; + center_ind_area.x1 = cx - radius; + center_ind_area.y1 = cy - radius; + center_ind_area.x2 = cx + radius; + center_ind_area.y2 = cy + radius; + + /*redraw the wheel only if the mask intersect with the wheel*/ + if(mask->x1 < center_ind_area.x1 || mask->x2 > center_ind_area.x2 + || mask->y1 < center_ind_area.y1 || mask->y2 > center_ind_area.y2) + { + lv_cpicker_draw_disc_gradient(mask, style, opa_scale, ext, cx, cy, r); + } + + lv_cpicker_draw_disc_indicator(mask, style, opa_scale, ext, cx, cy, r, rin, radius, center_ind_area); /* //code to color the drawn area @@ -870,11 +867,13 @@ static void lv_cpicker_disc_design(lv_obj_t * cpicker, const lv_area_t * mask, l style2.body.grad_color.full = c; c += 0x123445678; lv_draw_rect(mask, mask, &style2, opa_scale); - */ + */ } -static void lv_cpicker_rect_design(lv_obj_t * cpicker, const lv_area_t * mask, lv_style_t * style, lv_opa_t opa_scale, - lv_cpicker_ext_t * ext, lv_coord_t w, lv_coord_t h) +static uint16_t lv_cpicker_calculate_rect_preview_area(lv_obj_t * cpicker, + lv_style_t * style, + lv_cpicker_ext_t * ext, + lv_coord_t w) { lv_coord_t x1 = cpicker->coords.x1; lv_coord_t y1 = cpicker->coords.y1; @@ -954,6 +953,116 @@ static void lv_cpicker_rect_design(lv_obj_t * cpicker, const lv_area_t * mask, l } } + return style_body_padding_hor; +} + +/** + * Should roughly match up with `lv_cpicker_invalidate_rect_indicator_line` + */ +static void lv_cpicker_draw_rect_indicator_line(lv_area_t * mask, lv_opa_t opa_scale, + lv_cpicker_ext_t * ext, lv_coord_t ind_pos) +{ + lv_point_t p1, p2; + p1.x = ext->rect_gradient_area.x1 + ind_pos; + p1.y = ext->rect_gradient_area.y1; + p2.x = p1.x; + p2.y = ext->rect_gradient_area.y2; + + lv_draw_line(&p1, &p2, mask, ext->indicator.style, opa_scale); +} + +/** + * Should roughly match up with `lv_cpicker_invalidate_rect_indicator_circle` + */ +static void lv_cpicker_draw_rect_indicator_circle(lv_area_t * mask, lv_opa_t opa_scale, + lv_cpicker_ext_t * ext, lv_coord_t ind_pos) +{ + lv_area_t circle_ind_area; + circle_ind_area.x1 = ext->rect_gradient_area.x1 + ind_pos - ext->rect_gradient_h/2; + circle_ind_area.x2 = circle_ind_area.x1 + ext->rect_gradient_h; + circle_ind_area.y1 = ext->rect_gradient_area.y1; + circle_ind_area.y2 = ext->rect_gradient_area.y2; + + lv_style_t styleCopy; + lv_style_copy(&styleCopy, ext->indicator.style); + styleCopy.body.radius = LV_RADIUS_CIRCLE; + + lv_draw_rect(&circle_ind_area, mask, &styleCopy, opa_scale); +} + +/** + * Should roughly match up with `lv_cpicker_invalidate_rect_indicator_in` + */ +static void lv_cpicker_draw_rect_indicator_in(lv_area_t * mask, lv_opa_t opa_scale, + lv_cpicker_ext_t * ext, lv_coord_t ind_pos) +{ + /*draw triangle at top and bottom of gradient*/ + lv_point_t triangle_points[3]; + + triangle_points[0].x = ext->rect_gradient_area.x1 + ind_pos; + triangle_points[0].y = ext->rect_gradient_area.y1 + (ext->rect_gradient_h/3); + + triangle_points[1].x = triangle_points[0].x - ext->indicator.style->line.width * 3; + triangle_points[1].y = ext->rect_gradient_area.y1 - 1; + + triangle_points[2].x = triangle_points[0].x + ext->indicator.style->line.width * 3; + triangle_points[2].y = triangle_points[1].y; + + lv_draw_triangle(triangle_points, mask, ext->indicator.style, LV_OPA_COVER); + + triangle_points[0].y = ext->rect_gradient_area.y2 - (ext->rect_gradient_h/3); + triangle_points[1].y = ext->rect_gradient_area.y2; + triangle_points[2].y = triangle_points[1].y; + lv_draw_triangle(triangle_points, mask, ext->indicator.style, LV_OPA_COVER); +} + +static void lv_cpicker_draw_rect_indicator(lv_obj_t * cpicker, + lv_area_t * mask, lv_style_t * style, lv_opa_t opa_scale, + lv_cpicker_ext_t * ext, + uint16_t style_body_padding_hor) +{ + /*draw the color preview indicator*/ + style->body.main_color = lv_cpicker_get_color(cpicker); + style->body.grad_color = style->body.main_color; + if(style->line.rounded && style_body_padding_hor == 0) + { + style->body.radius = ext->rect_gradient_h; + } + lv_draw_rect(&(ext->rect_preview_area), mask, style, opa_scale); + + /* + styleCopy.line.width = 10; + lv_draw_arc(cpicker->coords.x1 + 3*ext->rect_gradient_h/2, cpicker->coords.y1 + ext->rect_gradient_h/2, ext->rect_gradient_h / 2 + styleCopy.line.width + 2, mask, 180, 360, &styleCopy, opa_scale); + //lv_draw_arc(cpicker->coords.x1 + ext->rect_gradient_w - ext->rect_gradient_h/2, cpicker->coords.y1 + ext->rect_gradient_h/2, ext->rect_gradient_h / 2 + styleCopy.line.width + 2, mask, 0, 180, &styleCopy, opa_scale); + */ + + /*draw the color position indicator*/ + lv_coord_t ind_pos = lv_cpicker_get_indicator_coord(style, ext); + /*save to refresh the area later*/ + ext->prev_pos = ind_pos; + + switch(ext->indicator.type) + { + case LV_CPICKER_INDICATOR_NONE: + /*no indicator*/ + break; + case LV_CPICKER_INDICATOR_LINE: + lv_cpicker_draw_rect_indicator_line(mask, opa_scale, ext, ind_pos); + break; + case LV_CPICKER_INDICATOR_CIRCLE: + lv_cpicker_draw_rect_indicator_circle(mask, opa_scale, ext, ind_pos); + break; + case LV_CPICKER_INDICATOR_IN: + lv_cpicker_draw_rect_indicator_in(mask, opa_scale, ext, ind_pos); + break; + default: + break; + } +} + +static void lv_cpicker_draw_rect_gradient(lv_area_t * mask, lv_style_t * style, lv_opa_t opa_scale, + lv_cpicker_ext_t * ext) +{ if(style->line.rounded) { /*draw rounded edges to the gradient*/ @@ -1014,101 +1123,31 @@ static void lv_cpicker_rect_design(lv_obj_t * cpicker, const lv_area_t * mask, l ext->rect_gradient_area.x2 += ext->rect_gradient_h/2; //ext->rect_gradient_w += ext->rect_gradient_h; } +} - /*draw the color preview indicator*/ - style->body.main_color = lv_cpicker_get_color(cpicker); - style->body.grad_color = style->body.main_color; - if(style->line.rounded && style_body_padding_hor == 0) - { - style->body.radius = ext->rect_gradient_h; - } - lv_draw_rect(&(ext->rect_preview_area), mask, style, opa_scale); +/** + * Should roughly match up with `lv_cpicker_invalidate_rect` + */ +static void lv_cpicker_rect_design(lv_obj_t * cpicker, + lv_area_t * mask, lv_style_t * style, lv_opa_t opa_scale, + lv_cpicker_ext_t * ext, + lv_coord_t w, lv_coord_t h) +{ + uint16_t style_body_padding_hor = lv_cpicker_calculate_rect_preview_area(cpicker, style, ext, w); - /* - styleCopy.line.width = 10; - lv_draw_arc(cpicker->coords.x1 + 3*ext->rect_gradient_h/2, cpicker->coords.y1 + ext->rect_gradient_h/2, ext->rect_gradient_h / 2 + styleCopy.line.width + 2, mask, 180, 360, &styleCopy, opa_scale); - //lv_draw_arc(cpicker->coords.x1 + ext->rect_gradient_w - ext->rect_gradient_h/2, cpicker->coords.y1 + ext->rect_gradient_h/2, ext->rect_gradient_h / 2 + styleCopy.line.width + 2, mask, 0, 180, &styleCopy, opa_scale); - */ + lv_cpicker_draw_rect_gradient(mask, style, opa_scale, ext); - /*draw the color position indicator*/ - lv_coord_t ind_pos = style->line.rounded ? ext->rect_gradient_h / 2 : 0; - switch(ext->color_mode) - { - default: - case LV_CPICKER_COLOR_MODE_HUE: - ind_pos += ext->hue * ext->rect_gradient_w / 360.0; - break; - case LV_CPICKER_COLOR_MODE_SATURATION: - ind_pos += ext->saturation * ext->rect_gradient_w / 100.0; - break; - case LV_CPICKER_COLOR_MODE_VALUE: - ind_pos += ext->value * ext->rect_gradient_w / 100.0; - break; - } - - /*save to refresh the area later*/ - ext->prev_pos = ind_pos; - - switch(ext->indicator.type) - { - case LV_CPICKER_INDICATOR_NONE: - /*no indicator*/ - break; - case LV_CPICKER_INDICATOR_LINE: - { - lv_point_t p1, p2; - p1.x = ext->rect_gradient_area.x1 + ind_pos; - p1.y = ext->rect_gradient_area.y1; - p2.x = p1.x; - p2.y = ext->rect_gradient_area.y2; - - lv_draw_line(&p1, &p2, mask, ext->indicator.style, opa_scale); - break; - } - case LV_CPICKER_INDICATOR_CIRCLE: - { - lv_area_t circle_ind_area; - circle_ind_area.x1 = ext->rect_gradient_area.x1 + ind_pos - ext->rect_gradient_h/2; - circle_ind_area.x2 = circle_ind_area.x1 + ext->rect_gradient_h; - circle_ind_area.y1 = ext->rect_gradient_area.y1; - circle_ind_area.y2 = ext->rect_gradient_area.y2; - - lv_style_copy(style, ext->indicator.style); - style->body.radius = LV_RADIUS_CIRCLE; - - lv_draw_rect(&circle_ind_area, mask, style, opa_scale); - break; - } - case LV_CPICKER_INDICATOR_IN: - { - /*draw triangle under the gradient*/ - lv_point_t triangle_points[3]; - - triangle_points[0].x = ext->rect_gradient_area.x1 + ind_pos; - triangle_points[0].y = ext->rect_gradient_area.y1 + (ext->rect_gradient_h/3); - - triangle_points[1].x = triangle_points[0].x - ext->indicator.style->line.width * 3; - triangle_points[1].y = ext->rect_gradient_area.y1 - 1; - - triangle_points[2].x = triangle_points[0].x + ext->indicator.style->line.width * 3; - triangle_points[2].y = triangle_points[1].y; - - lv_draw_triangle(triangle_points, mask, ext->indicator.style, LV_OPA_COVER); - - triangle_points[0].y = ext->rect_gradient_area.y2 - (ext->rect_gradient_h/3); - triangle_points[1].y = ext->rect_gradient_area.y2; - triangle_points[2].y = triangle_points[1].y; - lv_draw_triangle(triangle_points, mask, ext->indicator.style, LV_OPA_COVER); - break; - } - default: - break; - } + lv_cpicker_draw_rect_indicator(cpicker, mask, style, opa_scale, ext, style_body_padding_hor); } -static lv_res_t lv_cpicker_disc_signal(lv_obj_t * cpicker, lv_signal_t sign, void * param); -static lv_res_t lv_cpicker_rect_signal(lv_obj_t * cpicker, lv_signal_t sign, void * param); +static void lv_cpicker_invalidate(lv_obj_t * cpicker, bool all); + +static lv_res_t lv_cpicker_disc_signal(lv_obj_t * cpicker, lv_signal_t sign, void * param, + lv_style_t * style, lv_cpicker_ext_t * ext, + lv_coord_t r_out, lv_coord_t r_in, lv_coord_t x, lv_coord_t y); +static lv_res_t lv_cpicker_rect_signal(lv_obj_t * cpicker, lv_signal_t sign, void * param, + lv_style_t * style, lv_cpicker_ext_t * ext); /** * Signal function of the color_picker @@ -1134,173 +1173,290 @@ static lv_res_t lv_cpicker_signal(lv_obj_t * cpicker, lv_signal_t sign, void * p buf->type[i] = "lv_cpicker"; } else { lv_cpicker_ext_t * ext = lv_obj_get_ext_attr(cpicker); - lv_style_t * style = lv_cpicker_get_style(cpicker, LV_CPICKER_STYLE_MAIN); - if(ext->type == LV_CPICKER_TYPE_DISC) - { - res = lv_cpicker_disc_signal(cpicker, sign, param); - if(res != LV_RES_OK) return res; - } - else if(ext->type == LV_CPICKER_TYPE_RECT) - { - res = lv_cpicker_rect_signal(cpicker, sign, param); - if(res != LV_RES_OK) return res; + if(sign == LV_SIGNAL_CONTROL) { + uint32_t c = *((uint32_t *)param); /*uint32_t because can be UTF-8*/ + if(c == LV_KEY_RIGHT) + { + switch(ext->color_mode) + { + case LV_CPICKER_COLOR_MODE_HUE: + ext->hue = (ext->hue + 1) % 360; + break; + case LV_CPICKER_COLOR_MODE_SATURATION: + ext->saturation = (ext->saturation + 1) % 100; + break; + case LV_CPICKER_COLOR_MODE_VALUE: + ext->value = (ext->value + 1) % 100; + break; + } + + lv_cpicker_invalidate(cpicker, false); + + res = lv_event_send(cpicker, LV_EVENT_VALUE_CHANGED, NULL); + if(res != LV_RES_OK) return res; + } + else if(c == LV_KEY_LEFT) + { + switch(ext->color_mode) + { + case LV_CPICKER_COLOR_MODE_HUE: + ext->hue = ext->hue > 0?(ext->hue - 1):360; + break; + case LV_CPICKER_COLOR_MODE_SATURATION: + ext->saturation = ext->saturation > 0?(ext->saturation - 1):100; + break; + case LV_CPICKER_COLOR_MODE_VALUE: + ext->value = ext->value > 0?(ext->value - 1):100; + break; + } + + lv_cpicker_invalidate(cpicker, false); + + res = lv_event_send(cpicker, LV_EVENT_VALUE_CHANGED, NULL); + if(res != LV_RES_OK) return res; + } + else if(c == LV_KEY_UP) + { + switch(ext->color_mode) + { + case LV_CPICKER_COLOR_MODE_HUE: + ext->hue = (ext->hue + 1) % 360; + break; + case LV_CPICKER_COLOR_MODE_SATURATION: + ext->saturation = (ext->saturation + 1) % 100; + break; + case LV_CPICKER_COLOR_MODE_VALUE: + ext->value = (ext->value + 1) % 100; + break; + } + + lv_cpicker_invalidate(cpicker, false); + + res = lv_event_send(cpicker, LV_EVENT_VALUE_CHANGED, NULL); + if(res != LV_RES_OK) return res; + } + else if(c == LV_KEY_DOWN) + { + switch(ext->color_mode) + { + case LV_CPICKER_COLOR_MODE_HUE: + ext->hue = ext->hue > 0?(ext->hue - 1):360; + break; + case LV_CPICKER_COLOR_MODE_SATURATION: + ext->saturation = ext->saturation > 0?(ext->saturation - 1):100; + break; + case LV_CPICKER_COLOR_MODE_VALUE: + ext->value = ext->value > 0?(ext->value - 1):100; + break; + } + + lv_cpicker_invalidate(cpicker, false); + + res = lv_event_send(cpicker, LV_EVENT_VALUE_CHANGED, NULL); + if(res != LV_RES_OK) return res; + } + } else { + lv_style_t * style = lv_cpicker_get_style(cpicker, LV_CPICKER_STYLE_MAIN); + + if(ext->type == LV_CPICKER_TYPE_DISC) + { + lv_coord_t r_out = (LV_MATH_MIN(lv_obj_get_width(cpicker), lv_obj_get_height(cpicker))) / 2; + lv_coord_t r_in = r_out - style->line.width - style->body.padding.inner; + lv_coord_t x = cpicker->coords.x1 + lv_obj_get_width(cpicker) / 2; + lv_coord_t y = cpicker->coords.y1 + lv_obj_get_height(cpicker) / 2; + res = lv_cpicker_disc_signal(cpicker, sign, param, style, ext, r_out, r_in, x, y); + if(res != LV_RES_OK) return res; + } + else if(ext->type == LV_CPICKER_TYPE_RECT) + { + res = lv_cpicker_rect_signal(cpicker, sign, param, style, ext); + if(res != LV_RES_OK) return res; + } } } return res; } -static lv_res_t lv_cpicker_disc_signal(lv_obj_t * cpicker, lv_signal_t sign, void * param) +static void lv_cpicker_prev_hsv_save(lv_cpicker_ext_t * ext) { - lv_cpicker_ext_t * ext = lv_obj_get_ext_attr(cpicker); + switch(ext->color_mode) + { + case LV_CPICKER_COLOR_MODE_HUE: + ext->prev_hue = ext->hue; + break; + case LV_CPICKER_COLOR_MODE_SATURATION: + ext->prev_saturation = ext->saturation; + break; + case LV_CPICKER_COLOR_MODE_VALUE: + ext->prev_value = ext->value; + break; + } +} - lv_res_t res; +static void lv_cpicker_prev_hsv_restore(lv_obj_t * cpicker, + lv_cpicker_ext_t * ext) +{ + switch(ext->color_mode) + { + case LV_CPICKER_COLOR_MODE_HUE: + ext->prev_hue = ext->hue; + break; + case LV_CPICKER_COLOR_MODE_SATURATION: + ext->prev_saturation = ext->saturation; + break; + case LV_CPICKER_COLOR_MODE_VALUE: + ext->prev_value = ext->value; + break; + } + lv_cpicker_invalidate(cpicker, false); +} - lv_style_t * style = lv_cpicker_get_style(cpicker, LV_CPICKER_STYLE_MAIN); - - lv_coord_t r_out = (LV_MATH_MIN(lv_obj_get_width(cpicker), lv_obj_get_height(cpicker))) / 2; - lv_coord_t r_in = r_out - style->line.width - style->body.padding.inner; - - lv_coord_t x = cpicker->coords.x1 + lv_obj_get_width(cpicker) / 2; - lv_coord_t y = cpicker->coords.y1 + lv_obj_get_height(cpicker) / 2; - - if(sign == LV_SIGNAL_PRESSED) - { - switch(ext->color_mode) - { - case LV_CPICKER_COLOR_MODE_HUE: - ext->prev_hue = ext->hue; - break; - case LV_CPICKER_COLOR_MODE_SATURATION: - ext->prev_saturation = ext->saturation; - break; - case LV_CPICKER_COLOR_MODE_VALUE: - ext->prev_value = ext->value; - break; - } - - lv_indev_t * indev = param; - lv_coord_t xp = indev->proc.types.pointer.act_point.x - x; - lv_coord_t yp = indev->proc.types.pointer.act_point.y - y; - - if((xp*xp + yp*yp) < (r_in*r_in)) - { - if(lv_tick_elaps(ext->last_click) < 400) - { - switch(ext->color_mode) - { - case LV_CPICKER_COLOR_MODE_HUE: - ext->hue = 0; - ext->prev_hue = ext->hue; - break; - case LV_CPICKER_COLOR_MODE_SATURATION: - ext->saturation = 100; - ext->prev_saturation = ext->saturation; - break; - case LV_CPICKER_COLOR_MODE_VALUE: - ext->value = 100; - ext->prev_value = ext->value; - break; - } - //lv_cpicker_invalidate(cpicker, false); - } - ext->last_click = lv_tick_get(); - } - } - else if(sign == LV_SIGNAL_PRESSING) - { - lv_indev_t * indev = param; - lv_coord_t xp = indev->proc.types.pointer.act_point.x - x; - lv_coord_t yp = indev->proc.types.pointer.act_point.y - y; - - if((xp*xp + yp*yp) < (r_out*r_out) && (xp*xp + yp*yp) >= (r_in*r_in)) - { - bool changed = false; - uint16_t hsv; - switch(ext->color_mode) - { - case LV_CPICKER_COLOR_MODE_HUE: - hsv = lv_atan2(xp, yp); - changed = hsv != ext->hue; - if (changed) - { - ext->hue = hsv; - ext->prev_hue = ext->hue; - } - break; - case LV_CPICKER_COLOR_MODE_SATURATION: - hsv = lv_atan2(xp, yp) * 100.0 / 360.0; - changed = hsv != ext->hue; - if (changed) - { - ext->saturation = hsv; - ext->prev_saturation = ext->saturation; - } - break; - case LV_CPICKER_COLOR_MODE_VALUE: - hsv = lv_atan2(xp, yp) * 100.0 / 360.0; - changed = hsv != ext->hue; - if (changed) - { - ext->value = hsv; - ext->prev_value = ext->value; - } - break; - } - - if (changed) - { - lv_cpicker_invalidate(cpicker, false); - - res = lv_event_send(cpicker, LV_EVENT_VALUE_CHANGED, NULL); - if(res != LV_RES_OK) return res; - } - } - } - else if(sign == LV_SIGNAL_PRESS_LOST) +static void lv_cpicker_reset_hsv_if_double_clicked(lv_obj_t * cpicker, + lv_cpicker_ext_t * ext) +{ + if(lv_tick_elaps(ext->last_click) < 400) { switch(ext->color_mode) { case LV_CPICKER_COLOR_MODE_HUE: + ext->hue = 0; ext->prev_hue = ext->hue; break; case LV_CPICKER_COLOR_MODE_SATURATION: + ext->saturation = 100; ext->prev_saturation = ext->saturation; break; case LV_CPICKER_COLOR_MODE_VALUE: + ext->value = 100; ext->prev_value = ext->value; break; } lv_cpicker_invalidate(cpicker, false); } + ext->last_click = lv_tick_get(); +} + +static void lv_cpicker_set_next_color_mode(lv_obj_t * cpicker, + lv_cpicker_ext_t * ext) +{ + switch(ext->color_mode) + { + case LV_CPICKER_COLOR_MODE_HUE: + ext->prev_hue = ext->hue; + break; + case LV_CPICKER_COLOR_MODE_SATURATION: + ext->prev_saturation = ext->saturation; + break; + case LV_CPICKER_COLOR_MODE_VALUE: + ext->prev_value = ext->value; + break; + } + + ext->color_mode = (ext->color_mode + 1) % 3; + + lv_cpicker_invalidate(cpicker, true); +} + +static lv_res_t lv_cpicker_set_hsv_percent(lv_obj_t * cpicker, + lv_cpicker_ext_t * ext, + float percent) +{ + lv_res_t res; + + bool changed = false; + uint16_t hsv; + switch(ext->color_mode) + { + case LV_CPICKER_COLOR_MODE_HUE: + hsv = percent * 360.0; + changed = hsv != ext->hue; + if (changed) + { + ext->hue = hsv; + ext->prev_hue = ext->hue; + } + break; + case LV_CPICKER_COLOR_MODE_SATURATION: + hsv = percent * 100.0; + changed = hsv != ext->saturation; + if (changed) + { + ext->saturation = hsv; + ext->prev_saturation = ext->saturation; + } + break; + case LV_CPICKER_COLOR_MODE_VALUE: + hsv = percent * 100.0; + changed = hsv != ext->value; + if (changed) + { + ext->value = hsv; + ext->prev_value = ext->value; + } + break; + } + + if (changed) + { + lv_cpicker_invalidate(cpicker, false); + + res = lv_event_send(cpicker, LV_EVENT_VALUE_CHANGED, NULL); + if(res != LV_RES_OK) return res; + } + + return res; +} + +static lv_res_t lv_cpicker_disc_signal(lv_obj_t * cpicker, lv_signal_t sign, void * param, + lv_style_t * style, lv_cpicker_ext_t * ext, + lv_coord_t r_out, lv_coord_t r_in, lv_coord_t x, lv_coord_t y) +{ + lv_res_t res; + + if(sign == LV_SIGNAL_PRESSED) + { + lv_cpicker_prev_hsv_save(ext); + + lv_indev_t * indev = param; + + lv_coord_t xp = indev->proc.types.pointer.act_point.x - x; + lv_coord_t yp = indev->proc.types.pointer.act_point.y - y; + if((xp*xp + yp*yp) < (r_in*r_in)) + { + lv_cpicker_reset_hsv_if_double_clicked(cpicker, ext); + } + } + else if(sign == LV_SIGNAL_PRESSING) + { + lv_indev_t * indev = param; + + lv_coord_t xp = indev->proc.types.pointer.act_point.x - x; + lv_coord_t yp = indev->proc.types.pointer.act_point.y - y; + if((xp*xp + yp*yp) < (r_out*r_out) && (xp*xp + yp*yp) >= (r_in*r_in)) + { + float percent = lv_atan2(xp, yp) / 360.0; + + res = lv_cpicker_set_hsv_percent(cpicker, ext, percent); + if(res != LV_RES_OK) return res; + } + } + else if(sign == LV_SIGNAL_PRESS_LOST) + { + lv_cpicker_prev_hsv_restore(cpicker, ext); + } else if(sign == LV_SIGNAL_RELEASED) { lv_indev_t * indev = param; + lv_coord_t xp = indev->proc.types.pointer.act_point.x - x; lv_coord_t yp = indev->proc.types.pointer.act_point.y - y; - if((xp*xp + yp*yp) < (r_out*r_out) && (xp*xp + yp*yp) >= (r_in*r_in)) { - switch(ext->color_mode) - { - case LV_CPICKER_COLOR_MODE_HUE: - ext->hue = lv_atan2(xp, yp); - ext->prev_hue = ext->hue; - break; - case LV_CPICKER_COLOR_MODE_SATURATION: - ext->saturation = lv_atan2(xp, yp) * 100.0 / 360.0; - ext->prev_saturation = ext->saturation; - break; - case LV_CPICKER_COLOR_MODE_VALUE: - ext->value = lv_atan2(xp, yp) * 100.0 / 360.0; - ext->prev_value = ext->value; - break; - } + float percent = lv_atan2(xp, yp) / 360.0; - lv_cpicker_invalidate(cpicker, false); - - res = lv_event_send(cpicker, LV_EVENT_VALUE_CHANGED, NULL); + res = lv_cpicker_set_hsv_percent(cpicker, ext, percent); if(res != LV_RES_OK) return res; } } @@ -1309,172 +1465,33 @@ static lv_res_t lv_cpicker_disc_signal(lv_obj_t * cpicker, lv_signal_t sign, voi if(!ext->color_mode_fixed) { lv_indev_t * indev = param; + lv_coord_t xp = indev->proc.types.pointer.act_point.x - x; lv_coord_t yp = indev->proc.types.pointer.act_point.y - y; - if((xp*xp + yp*yp) < (r_in*r_in)) { - switch(ext->color_mode) - { - case LV_CPICKER_COLOR_MODE_HUE: - ext->prev_hue = ext->hue; - break; - case LV_CPICKER_COLOR_MODE_SATURATION: - ext->prev_saturation = ext->saturation; - break; - case LV_CPICKER_COLOR_MODE_VALUE: - ext->prev_value = ext->value; - break; - } - - ext->color_mode = (ext->color_mode + 1) % 3; - - lv_cpicker_invalidate(cpicker, true); + lv_cpicker_set_next_color_mode(cpicker, ext); } } } - else if(sign == LV_SIGNAL_CONTROL) - { - uint32_t c = *((uint32_t *)param); /*uint32_t because can be UTF-8*/ - if(c == LV_KEY_RIGHT) - { - switch(ext->color_mode) - { - case LV_CPICKER_COLOR_MODE_HUE: - ext->hue = (ext->hue + 1) % 360; - break; - case LV_CPICKER_COLOR_MODE_SATURATION: - ext->saturation = (ext->saturation + 1) % 100; - break; - case LV_CPICKER_COLOR_MODE_VALUE: - ext->value = (ext->value + 1) % 100; - break; - } - - lv_cpicker_invalidate(cpicker, false); - - res = lv_event_send(cpicker, LV_EVENT_VALUE_CHANGED, NULL); - if(res != LV_RES_OK) return res; - } - else if(c == LV_KEY_LEFT) - { - switch(ext->color_mode) - { - case LV_CPICKER_COLOR_MODE_HUE: - ext->hue = ext->hue > 0?(ext->hue - 1):360; - break; - case LV_CPICKER_COLOR_MODE_SATURATION: - ext->saturation = ext->saturation > 0?(ext->saturation - 1):100; - break; - case LV_CPICKER_COLOR_MODE_VALUE: - ext->value = ext->value > 0?(ext->value - 1):100; - break; - } - - lv_cpicker_invalidate(cpicker, false); - - res = lv_event_send(cpicker, LV_EVENT_VALUE_CHANGED, NULL); - if(res != LV_RES_OK) return res; - } - else if(c == LV_KEY_UP) - { - switch(ext->color_mode) - { - case LV_CPICKER_COLOR_MODE_HUE: - ext->hue = (ext->hue + 1) % 360; - break; - case LV_CPICKER_COLOR_MODE_SATURATION: - ext->saturation = (ext->saturation + 1) % 100; - break; - case LV_CPICKER_COLOR_MODE_VALUE: - ext->value = (ext->value + 1) % 100; - break; - } - - lv_cpicker_invalidate(cpicker, false); - - res = lv_event_send(cpicker, LV_EVENT_VALUE_CHANGED, NULL); - if(res != LV_RES_OK) return res; - } - else if(c == LV_KEY_DOWN) - { - switch(ext->color_mode) - { - case LV_CPICKER_COLOR_MODE_HUE: - ext->hue = ext->hue > 0?(ext->hue - 1):360; - break; - case LV_CPICKER_COLOR_MODE_SATURATION: - ext->saturation = ext->saturation > 0?(ext->saturation - 1):100; - break; - case LV_CPICKER_COLOR_MODE_VALUE: - ext->value = ext->value > 0?(ext->value - 1):100; - break; - } - - lv_cpicker_invalidate(cpicker, false); - - res = lv_event_send(cpicker, LV_EVENT_VALUE_CHANGED, NULL); - if(res != LV_RES_OK) return res; - } - } return res; } -/** - * Signal function of the color_picker of rectangle type - * @param cpicker pointer to a color_picker object - * @param sign a signal type from lv_signal_t enum - * @param param pointer to a signal specific variable - * @return LV_RES_OK: the object is not deleted in the function; LV_RES_INV: the object is deleted - */ -static lv_res_t lv_cpicker_rect_signal(lv_obj_t * cpicker, lv_signal_t sign, void * param) +static lv_res_t lv_cpicker_rect_signal(lv_obj_t * cpicker, lv_signal_t sign, void * param, + lv_style_t * style, lv_cpicker_ext_t * ext) { - lv_cpicker_ext_t * ext = lv_obj_get_ext_attr(cpicker); - lv_res_t res; - lv_style_t * style = lv_cpicker_get_style(cpicker, LV_CPICKER_STYLE_MAIN); - if(sign == LV_SIGNAL_PRESSED) { - switch(ext->color_mode) - { - case LV_CPICKER_COLOR_MODE_HUE: - ext->prev_hue = ext->hue; - break; - case LV_CPICKER_COLOR_MODE_SATURATION: - ext->prev_saturation = ext->saturation; - break; - case LV_CPICKER_COLOR_MODE_VALUE: - ext->prev_value = ext->value; - break; - } + lv_cpicker_prev_hsv_save(ext); lv_indev_t * indev = param; if(lv_area_is_point_on(&(ext->rect_preview_area), &indev->proc.types.pointer.act_point)) { - if(lv_tick_elaps(ext->last_click) < 400) - { - switch(ext->color_mode) - { - case LV_CPICKER_COLOR_MODE_HUE: - ext->hue = 0; - ext->prev_hue = ext->hue; - break; - case LV_CPICKER_COLOR_MODE_SATURATION: - ext->saturation = 100; - ext->prev_saturation = ext->saturation; - break; - case LV_CPICKER_COLOR_MODE_VALUE: - ext->value = 100; - ext->prev_value = ext->value; - break; - } - //lv_cpicker_invalidate(cpicker, false); - } - ext->last_click = lv_tick_get(); + lv_cpicker_reset_hsv_if_double_clicked(cpicker, ext); } } else if(sign == LV_SIGNAL_PRESSING) @@ -1486,43 +1503,14 @@ static lv_res_t lv_cpicker_rect_signal(lv_obj_t * cpicker, lv_signal_t sign, voi uint16_t width = ext->rect_gradient_area.x2 - ext->rect_gradient_area.x1; uint16_t distance = indev->proc.types.pointer.act_point.x - ext->rect_gradient_area.x1; float percent = distance / (float) width; - switch(ext->color_mode) - { - case LV_CPICKER_COLOR_MODE_HUE: - ext->hue = percent * 360.0; - ext->prev_hue = ext->hue; - break; - case LV_CPICKER_COLOR_MODE_SATURATION: - ext->saturation = percent * 100.0; - ext->prev_saturation = ext->saturation; - break; - case LV_CPICKER_COLOR_MODE_VALUE: - ext->value = percent * 100.0; - ext->prev_value = ext->value; - break; - } - lv_cpicker_invalidate(cpicker, false); - - res = lv_event_send(cpicker, LV_EVENT_VALUE_CHANGED, NULL); + res = lv_cpicker_set_hsv_percent(cpicker, ext, percent); if(res != LV_RES_OK) return res; } } else if(sign == LV_SIGNAL_PRESS_LOST) { - switch(ext->color_mode) - { - case LV_CPICKER_COLOR_MODE_HUE: - ext->prev_hue = ext->hue; - break; - case LV_CPICKER_COLOR_MODE_SATURATION: - ext->prev_saturation = ext->saturation; - break; - case LV_CPICKER_COLOR_MODE_VALUE: - ext->prev_value = ext->value; - break; - } - lv_cpicker_invalidate(cpicker, false); + lv_cpicker_prev_hsv_restore(cpicker, ext); } else if(sign == LV_SIGNAL_RELEASED) { @@ -1533,25 +1521,8 @@ static lv_res_t lv_cpicker_rect_signal(lv_obj_t * cpicker, lv_signal_t sign, voi uint16_t width = ext->rect_gradient_area.x2 - ext->rect_gradient_area.x1; uint16_t distance = indev->proc.types.pointer.act_point.x - ext->rect_gradient_area.x1; float percent = distance / (float) width; - switch(ext->color_mode) - { - case LV_CPICKER_COLOR_MODE_HUE: - ext->hue = percent * 360.0; - ext->prev_hue = ext->hue; - break; - case LV_CPICKER_COLOR_MODE_SATURATION: - ext->saturation = percent * 100.0; - ext->prev_saturation = ext->saturation; - break; - case LV_CPICKER_COLOR_MODE_VALUE: - ext->value = percent * 100.0; - ext->prev_value = ext->value; - break; - } - lv_cpicker_invalidate(cpicker, false); - - res = lv_event_send(cpicker, LV_EVENT_VALUE_CHANGED, NULL); + res = lv_cpicker_set_hsv_percent(cpicker, ext, percent); if(res != LV_RES_OK) return res; } } @@ -1563,113 +1534,23 @@ static lv_res_t lv_cpicker_rect_signal(lv_obj_t * cpicker, lv_signal_t sign, voi if(lv_area_is_point_on(&(ext->rect_preview_area), &indev->proc.types.pointer.act_point)) { - switch(ext->color_mode) - { - case LV_CPICKER_COLOR_MODE_HUE: - ext->prev_hue = ext->hue; - break; - case LV_CPICKER_COLOR_MODE_SATURATION: - ext->prev_saturation = ext->saturation; - break; - case LV_CPICKER_COLOR_MODE_VALUE: - ext->prev_value = ext->value; - break; - } - - ext->color_mode = (ext->color_mode + 1) % 3; - - lv_cpicker_invalidate(cpicker, true); + lv_cpicker_set_next_color_mode(cpicker, ext); } } } - else if(sign == LV_SIGNAL_CONTROL) - { - uint32_t c = *((uint32_t *)param); /*uint32_t because can be UTF-8*/ - if(c == LV_KEY_RIGHT) - { - switch(ext->color_mode) - { - case LV_CPICKER_COLOR_MODE_HUE: - ext->hue = (ext->hue + 1) % 360; - break; - case LV_CPICKER_COLOR_MODE_SATURATION: - ext->saturation = (ext->saturation + 1) % 100; - break; - case LV_CPICKER_COLOR_MODE_VALUE: - ext->value = (ext->value + 1) % 100; - break; - } - - lv_cpicker_invalidate(cpicker, false); - - res = lv_event_send(cpicker, LV_EVENT_VALUE_CHANGED, NULL); - if(res != LV_RES_OK) return res; - } - else if(c == LV_KEY_LEFT) - { - switch(ext->color_mode) - { - case LV_CPICKER_COLOR_MODE_HUE: - ext->hue = ext->hue > 0?(ext->hue - 1):360; - break; - case LV_CPICKER_COLOR_MODE_SATURATION: - ext->saturation = ext->saturation > 0?(ext->saturation - 1):100; - break; - case LV_CPICKER_COLOR_MODE_VALUE: - ext->value = ext->value > 0?(ext->value - 1):100; - break; - } - - lv_cpicker_invalidate(cpicker, false); - - res = lv_event_send(cpicker, LV_EVENT_VALUE_CHANGED, NULL); - if(res != LV_RES_OK) return res; - } - else if(c == LV_KEY_UP) - { - switch(ext->color_mode) - { - case LV_CPICKER_COLOR_MODE_HUE: - ext->hue = (ext->hue + 1) % 360; - break; - case LV_CPICKER_COLOR_MODE_SATURATION: - ext->saturation = (ext->saturation + 1) % 100; - break; - case LV_CPICKER_COLOR_MODE_VALUE: - ext->value = (ext->value + 1) % 100; - break; - } - - lv_cpicker_invalidate(cpicker, false); - - res = lv_event_send(cpicker, LV_EVENT_VALUE_CHANGED, NULL); - if(res != LV_RES_OK) return res; - } - else if(c == LV_KEY_DOWN) - { - switch(ext->color_mode) - { - case LV_CPICKER_COLOR_MODE_HUE: - ext->hue = ext->hue > 0?(ext->hue - 1):360; - break; - case LV_CPICKER_COLOR_MODE_SATURATION: - ext->saturation = ext->saturation > 0?(ext->saturation - 1):100; - break; - case LV_CPICKER_COLOR_MODE_VALUE: - ext->value = ext->value > 0?(ext->value - 1):100; - break; - } - - lv_cpicker_invalidate(cpicker, false); - - res = lv_event_send(cpicker, LV_EVENT_VALUE_CHANGED, NULL); - if(res != LV_RES_OK) return res; - } - } return res; } + +static void lv_cpicker_invalidate_disc(lv_disp_t * disp, lv_style_t * style, + lv_cpicker_ext_t * ext, + lv_coord_t w, lv_coord_t h, + lv_coord_t cx, lv_coord_t cy, uint16_t r); +static void lv_cpicker_invalidate_rect(lv_disp_t * disp, lv_style_t * style, + lv_cpicker_ext_t * ext, + lv_coord_t w, lv_coord_t h); + /** * Indicator points need to match those set in lv_cpicker_disc_design/lv_cpicker_rect_design */ @@ -1681,12 +1562,11 @@ static void lv_cpicker_invalidate(lv_obj_t * cpicker, bool all) return; } - lv_disp_t * disp = lv_disp_get_default(); - + lv_disp_t * disp = lv_obj_get_disp(cpicker); lv_cpicker_ext_t * ext = lv_obj_get_ext_attr(cpicker); lv_style_t * style = lv_cpicker_get_style(cpicker, LV_CPICKER_STYLE_MAIN); - static lv_style_t styleCopy; + lv_style_t styleCopy; lv_style_copy(&styleCopy, style); lv_coord_t w = lv_obj_get_width(cpicker); @@ -1694,284 +1574,241 @@ static void lv_cpicker_invalidate(lv_obj_t * cpicker, bool all) if(ext->type == LV_CPICKER_TYPE_DISC) { - lv_coord_t r = LV_MATH_MIN(w, h) / 2; - lv_coord_t x = cpicker->coords.x1 + w / 2; - lv_coord_t y = cpicker->coords.y1 + h / 2; - - /*invalidate center color area*/ - lv_area_t center_color_area; - - uint32_t rin = r - styleCopy.line.width; - - uint16_t radius = lv_sqrt((4*rin*rin)/2)/2 + 1 - style->body.padding.inner; - - center_color_area.x1 = x - radius; - center_color_area.y1 = y - radius; - center_color_area.x2 = x + radius; - center_color_area.y2 = y + radius; - - lv_inv_area(disp, ¢er_color_area); - - /*invalidate indicator*/ - - uint16_t angle = mode_color_to_angle(ext); - - switch(ext->indicator.type) - { - case LV_CPICKER_INDICATOR_LINE: - { - lv_area_t line_area; - lv_point_t point1, point2; - lv_coord_t x1, y1, x2, y2; - - x1 = x + ((r - style->line.width + ext->indicator.style->body.padding.inner + ext->indicator.style->line.width/2) * lv_trigo_sin(angle) >> LV_TRIGO_SHIFT); - y1 = y + ((r - style->line.width + ext->indicator.style->body.padding.inner + ext->indicator.style->line.width/2) * lv_trigo_sin(angle + 90) >> LV_TRIGO_SHIFT); - x2 = x + ((r - ext->indicator.style->body.padding.inner - ext->indicator.style->line.width/2) * lv_trigo_sin(angle) >> LV_TRIGO_SHIFT); - y2 = y + ((r - ext->indicator.style->body.padding.inner - ext->indicator.style->line.width/2) * lv_trigo_sin(angle + 90) >> LV_TRIGO_SHIFT); - - point1.x = x1; - point1.y = y1; - point2.x = x2; - point2.y = y2; - - //if(LV_MATH_ABS(point1.x - point2.x) > LV_MATH_ABS(point1.y - point2.y)) - //{ - /*Steps less in y then x -> rather horizontal*/ - if(point1.x < point2.x) { - line_area.x1 = point1.x; - //line_area.y1 = point1.y; - line_area.x2 = point2.x; - //line_area.y2 = point2.y; - } else { - line_area.x1 = point2.x; - //line_area.y1 = point2.y; - line_area.x2 = point1.x; - //line_area.y2 = point1.y; - } - //} else { - /*Steps less in x then y -> rather vertical*/ - if(point1.y < point2.y) { - //line_area.x1 = point1.x; - line_area.y1 = point1.y; - //line_area.x2 = point2.x; - line_area.y2 = point2.y; - } else { - //line_area.x1 = point2.x; - line_area.y1 = point2.y; - line_area.x2 = point1.x; - //line_area.y2 = point1.y; - } - //} - - line_area.x1 -= 2*ext->indicator.style->line.width; - line_area.y1 -= 2*ext->indicator.style->line.width; - line_area.x2 += 2*ext->indicator.style->line.width; - line_area.y2 += 2*ext->indicator.style->line.width; - - lv_inv_area(disp, &line_area); - - /* invalidate last postion */ - angle = ext->prev_pos; - - x1 = x + ((r - style->line.width + ext->indicator.style->body.padding.inner + ext->indicator.style->line.width/2) * lv_trigo_sin(angle) >> LV_TRIGO_SHIFT); - y1 = y + ((r - style->line.width + ext->indicator.style->body.padding.inner + ext->indicator.style->line.width/2) * lv_trigo_sin(angle + 90) >> LV_TRIGO_SHIFT); - - x2 = x + ((r - ext->indicator.style->body.padding.inner - ext->indicator.style->line.width/2) * lv_trigo_sin(angle) >> LV_TRIGO_SHIFT); - y2 = y + ((r - ext->indicator.style->body.padding.inner - ext->indicator.style->line.width/2) * lv_trigo_sin(angle + 90) >> LV_TRIGO_SHIFT); - - point1.x = x1; - point1.y = y1; - point2.x = x2; - point2.y = y2; - - //if(LV_MATH_ABS(point1.x - point2.x) > LV_MATH_ABS(point1.y - point2.y)) - //{ - /*rather horizontal*/ - if(point1.x < point2.x) { - line_area.x1 = point1.x; - //line_area.y1 = point1.y; - line_area.x2 = point2.x; - //line_area.y2 = point2.y; - } else { - line_area.x1 = point2.x; - //line_area.y1 = point2.y; - line_area.x2 = point1.x; - //line_area.y2 = point1.y; - } - //} else { - /*rather vertical*/ - if(point1.y < point2.y) { - //line_area.x1 = point1.x; - line_area.y1 = point1.y; - //line_area.x2 = point2.x; - line_area.y2 = point2.y; - } else { - //line_area.x1 = point2.x; - line_area.y1 = point2.y; - //line_area.x2 = point1.x; - line_area.y2 = point1.y; - } - //} - - line_area.x1 -= 2*ext->indicator.style->line.width; - line_area.y1 -= 2*ext->indicator.style->line.width; - line_area.x2 += 2*ext->indicator.style->line.width; - line_area.y2 += 2*ext->indicator.style->line.width; - - lv_inv_area(disp, &line_area); - - break; - } - case LV_CPICKER_INDICATOR_CIRCLE: - { - lv_area_t circle_ind_area; - uint32_t cx, cy; - - cx = x + ((r - style->line.width/2) * lv_trigo_sin(angle) >> LV_TRIGO_SHIFT); - cy = y + ((r - style->line.width/2) * lv_trigo_sin(angle + 90) >> LV_TRIGO_SHIFT); - - circle_ind_area.x1 = cx - style->line.width/2; - circle_ind_area.y1 = cy - style->line.width/2; - circle_ind_area.x2 = cx + style->line.width/2; - circle_ind_area.y2 = cy + style->line.width/2; - - lv_inv_area(disp, &circle_ind_area); - - /* invalidate last position*/ - angle = ext->prev_pos; - - cx = x + ((r - style->line.width/2) * lv_trigo_sin(angle) >> LV_TRIGO_SHIFT); - cy = y + ((r - style->line.width/2) * lv_trigo_sin(angle + 90) >> LV_TRIGO_SHIFT); - - circle_ind_area.x1 = cx - style->line.width/2; - circle_ind_area.y1 = cy - style->line.width/2; - circle_ind_area.x2 = cx + style->line.width/2; - circle_ind_area.y2 = cy + style->line.width/2; - - lv_inv_area(disp, &circle_ind_area); - break; - } - case LV_CPICKER_INDICATOR_IN: - { - uint16_t wradius = r - style->line.width; - - lv_area_t circle_ind_area; - uint32_t cx, cy; - - uint16_t ind_radius = lv_sqrt((4*rin*rin)/2)/2 + 1 - style->body.padding.inner; - ind_radius = (ind_radius + rin) / 2; - - cx = x + ((ind_radius) * lv_trigo_sin(angle) >> LV_TRIGO_SHIFT); - cy = y + ((ind_radius) * lv_trigo_sin(angle + 90) >> LV_TRIGO_SHIFT); - - circle_ind_area.x1 = cx - ((wradius - radius) / 3); - circle_ind_area.y1 = cy - ((wradius - radius) / 3); - circle_ind_area.x2 = cx + ((wradius - radius) / 3); - circle_ind_area.y2 = cy + ((wradius - radius) / 3); - - lv_inv_area(disp, &circle_ind_area); - - /* invalidate last position*/ - angle = ext->prev_pos; - - cx = x + ((ind_radius) * lv_trigo_sin(angle) >> LV_TRIGO_SHIFT); - cy = y + ((ind_radius) * lv_trigo_sin(angle + 90) >> LV_TRIGO_SHIFT); - - circle_ind_area.x1 = cx - ((wradius - radius) / 3); - circle_ind_area.y1 = cy - ((wradius - radius) / 3); - circle_ind_area.x2 = cx + ((wradius - radius) / 3); - circle_ind_area.y2 = cy + ((wradius - radius) / 3); - - lv_inv_area(disp, &circle_ind_area); - break; - } - } + lv_coord_t cx = cpicker->coords.x1 + w / 2; + lv_coord_t cy = cpicker->coords.y1 + h / 2; + uint16_t r = LV_MATH_MIN(w, h) / 2; + lv_cpicker_invalidate_disc(disp, &styleCopy, ext, w, h, cx, cy, r); } else if(ext->type == LV_CPICKER_TYPE_RECT) { - /*invalidate color preview area*/ - lv_inv_area(disp, &ext->rect_preview_area); - - lv_coord_t ind_pos = style->line.rounded ? ext->rect_gradient_h / 2 : 0; - switch(ext->color_mode) - { - default: - case LV_CPICKER_COLOR_MODE_HUE: - ind_pos += ext->hue / 360.0 * ext->rect_gradient_w; - break; - case LV_CPICKER_COLOR_MODE_SATURATION: - ind_pos += ext->saturation / 100.0 * ext->rect_gradient_w; - break; - case LV_CPICKER_COLOR_MODE_VALUE: - ind_pos += ext->value / 100.0 * ext->rect_gradient_w; - break; - } - lv_coord_t prev_pos = ext->prev_pos; - - switch(ext->indicator.type) - { - case LV_CPICKER_INDICATOR_LINE: - { - lv_area_t line_area; - - /*Invalidate the current position*/ - line_area.x1 = ext->rect_gradient_area.x1 + ind_pos - ext->indicator.style->line.width; - line_area.x2 = ext->rect_gradient_area.x1 + ind_pos + ext->indicator.style->line.width; - line_area.y1 = ext->rect_gradient_area.y1; - line_area.y2 = ext->rect_gradient_area.y2; - - lv_inv_area(disp, &line_area); - - /* Invalidate last position */ - line_area.x1 = ext->rect_gradient_area.x1 + prev_pos - ext->indicator.style->line.width; - line_area.x2 = ext->rect_gradient_area.x1 + prev_pos + ext->indicator.style->line.width; - - lv_inv_area(disp, &line_area); - break; - } - case LV_CPICKER_INDICATOR_CIRCLE: - { - lv_area_t circle_ind_area; - - circle_ind_area.x1 = ext->rect_gradient_area.x1 + ind_pos - ext->rect_gradient_h/2; - circle_ind_area.x2 = circle_ind_area.x1 + ext->rect_gradient_h; - circle_ind_area.y1 = ext->rect_gradient_area.y1; - circle_ind_area.y2 = ext->rect_gradient_area.y2; - - lv_inv_area(disp, &circle_ind_area); - - /* invalidate last postion */ - circle_ind_area.x1 = ext->rect_gradient_area.x1 + prev_pos - ext->rect_gradient_h/2; - circle_ind_area.x2 = circle_ind_area.x1 + ext->rect_gradient_h; - //circle_ind_area.y1 = ext->rect_gradient_area.y1; - //circle_ind_area.y2 = ext->rect_gradient_area.y2; - - lv_inv_area(disp, &circle_ind_area); - break; - } - case LV_CPICKER_INDICATOR_IN: - { - lv_coord_t center; - lv_area_t ind_area; - - center = ext->rect_gradient_area.x1 + ind_pos; - ind_area.x1 = center - ext->indicator.style->line.width * 3; - ind_area.y1 = ext->rect_gradient_area.y1 - 1; - ind_area.x2 = center + ext->indicator.style->line.width * 3; - ind_area.y2 = ext->rect_gradient_area.y2; - lv_inv_area(disp, &ind_area); - - /* invalidate last postion */ - center = ext->rect_gradient_area.x1 + prev_pos; - ind_area.x1 = center - ext->indicator.style->line.width * 3; - //ind_area.y1 = ext->rect_gradient_area.y1 - 1; - ind_area.x2 = center + ext->indicator.style->line.width * 3; - //ind_area.y2 = ext->rect_gradient_area.y2; - lv_inv_area(disp, &ind_area); - break; - } - } + lv_cpicker_invalidate_rect(disp, &styleCopy, ext, w, h); } } -#endif +/** + * Should roughly match up with `lv_cpicker_draw_disc_indicator_line` + */ +static void lv_cpicker_invalidate_disc_indicator_line(lv_disp_t * disp, lv_style_t * style, + lv_cpicker_ext_t * ext, + lv_coord_t cx, lv_coord_t cy, uint16_t r, + uint16_t angle) +{ + lv_coord_t x1 = cx + ((r - style->line.width + ext->indicator.style->body.padding.inner + ext->indicator.style->line.width/2) * lv_trigo_sin(angle) >> LV_TRIGO_SHIFT); + lv_coord_t y1 = cy + ((r - style->line.width + ext->indicator.style->body.padding.inner + ext->indicator.style->line.width/2) * lv_trigo_sin(angle + 90) >> LV_TRIGO_SHIFT); + lv_coord_t x2 = cx + ((r - ext->indicator.style->body.padding.inner - ext->indicator.style->line.width/2) * lv_trigo_sin(angle) >> LV_TRIGO_SHIFT); + lv_coord_t y2 = cy + ((r - ext->indicator.style->body.padding.inner - ext->indicator.style->line.width/2) * lv_trigo_sin(angle + 90) >> LV_TRIGO_SHIFT); + + lv_point_t point1, point2; + point1.x = x1; + point1.y = y1; + point2.x = x2; + point2.y = y2; + + lv_area_t line_area; + //if(LV_MATH_ABS(point1.x - point2.x) > LV_MATH_ABS(point1.y - point2.y)) + //{ + /*Steps less in y than x -> rather horizontal*/ + if(point1.x < point2.x) { + line_area.x1 = point1.x; + //line_area.y1 = point1.y; + line_area.x2 = point2.x; + //line_area.y2 = point2.y; + } else { + line_area.x1 = point2.x; + //line_area.y1 = point2.y; + line_area.x2 = point1.x; + //line_area.y2 = point1.y; + } + //} else { + /*Steps less in x than y -> rather vertical*/ + if(point1.y < point2.y) { + //line_area.x1 = point1.x; + line_area.y1 = point1.y; + //line_area.x2 = point2.x; + line_area.y2 = point2.y; + } else { + //line_area.x1 = point2.x; + line_area.y1 = point2.y; + //line_area.x2 = point1.x; + line_area.y2 = point1.y; + } + //} + + line_area.x1 -= 2*ext->indicator.style->line.width; + line_area.y1 -= 2*ext->indicator.style->line.width; + line_area.x2 += 2*ext->indicator.style->line.width; + line_area.y2 += 2*ext->indicator.style->line.width; + + lv_inv_area(disp, &line_area); +} + +/** + * Should roughly match up with `lv_cpicker_draw_disc_indicator_circle` + */ +static void lv_cpicker_invalidate_disc_indicator_circle(lv_disp_t * disp, lv_style_t * style, + lv_cpicker_ext_t * ext, + lv_coord_t cx, lv_coord_t cy, uint16_t r, + uint16_t angle) +{ + uint32_t ind_cx = cx + ((r - style->line.width/2) * lv_trigo_sin(angle) >> LV_TRIGO_SHIFT); + uint32_t ind_cy = cy + ((r - style->line.width/2) * lv_trigo_sin(angle + 90) >> LV_TRIGO_SHIFT); + + lv_area_t ind_area; + ind_area.x1 = ind_cx - style->line.width/2; + ind_area.y1 = ind_cy - style->line.width/2; + ind_area.x2 = ind_cx + style->line.width/2; + ind_area.y2 = ind_cy + style->line.width/2; + + lv_inv_area(disp, &ind_area); +} + +/** + * Should roughly match up with `lv_cpicker_draw_disc_indicator_in` + */ +static void lv_cpicker_invalidate_disc_indicator_in(lv_disp_t * disp, lv_style_t * style, + lv_cpicker_ext_t * ext, + lv_coord_t x, lv_coord_t y, uint16_t r, + uint16_t rin, uint16_t angle) +{ + uint16_t ind_radius = lv_sqrt((4*rin*rin)/2)/2 + 1 - style->body.padding.inner; + ind_radius = (ind_radius + rin) / 2; + + uint16_t ind_cx = x + ((ind_radius) * lv_trigo_sin(angle) >> LV_TRIGO_SHIFT); + uint16_t ind_cy = y + ((ind_radius) * lv_trigo_sin(angle + 90) >> LV_TRIGO_SHIFT); + + lv_area_t ind_area; + ind_area.x1 = ind_cx - r; + ind_area.y1 = ind_cy - r; + ind_area.x2 = ind_cx + r; + ind_area.y2 = ind_cy + r; + + lv_inv_area(disp, &ind_area); +} + +/** + * Should roughly match up with `lv_cpicker_disc_design` + */ +static void lv_cpicker_invalidate_disc(lv_disp_t * disp, lv_style_t * style, + lv_cpicker_ext_t * ext, + lv_coord_t w, lv_coord_t h, + lv_coord_t cx, lv_coord_t cy, uint16_t r) +{ + /*invalidate center color area*/ + uint16_t rin = r - style->line.width; + /* + the square area (a and b being sides) should fit into the center of diameter d + we have: + a^2+b^2<=d^2 + 2a^2 <= d^2 + a^2<=(d^2)/2 + a <= sqrt((d^2)/2) + */ + uint16_t radius = lv_sqrt((4*rin*rin)/2)/2 + 1 - style->body.padding.inner; + + lv_area_t center_color_area; + center_color_area.x1 = cx - radius; + center_color_area.y1 = cy - radius; + center_color_area.x2 = cx + radius; + center_color_area.y2 = cy + radius; + + lv_inv_area(disp, ¢er_color_area); + + /*invalidate indicator*/ + uint16_t angle = mode_color_to_angle(ext); + switch(ext->indicator.type) + { + case LV_CPICKER_INDICATOR_LINE: + lv_cpicker_invalidate_disc_indicator_line(disp, style, ext, cx, cy, r, angle); + lv_cpicker_invalidate_disc_indicator_line(disp, style, ext, cx, cy, r, ext->prev_pos); + break; + case LV_CPICKER_INDICATOR_CIRCLE: + lv_cpicker_invalidate_disc_indicator_circle(disp, style, ext, cx, cy, r, angle); + lv_cpicker_invalidate_disc_indicator_circle(disp, style, ext, cx, cy, r, ext->prev_pos); + break; + case LV_CPICKER_INDICATOR_IN: + lv_cpicker_invalidate_disc_indicator_in(disp, style, ext, cx, cy, (rin - radius) / 3, rin, angle); + lv_cpicker_invalidate_disc_indicator_in(disp, style, ext, cx, cy, (rin - radius) / 3, rin, ext->prev_pos); + break; + } +} + +/** + * Should roughly match up with `lv_cpicker_draw_rect_indicator_line` + */ +static void lv_cpicker_invalidate_rect_indicator_line(lv_disp_t * disp, + lv_cpicker_ext_t * ext, + lv_coord_t ind_pos) +{ + lv_area_t line_area; + line_area.x1 = ext->rect_gradient_area.x1 + ind_pos - ext->indicator.style->line.width; + line_area.y1 = ext->rect_gradient_area.y1; + line_area.x2 = ext->rect_gradient_area.x1 + ind_pos + ext->indicator.style->line.width; + line_area.y2 = ext->rect_gradient_area.y2; + + lv_inv_area(disp, &line_area); +} + +/** + * Should roughly match up with `lv_cpicker_draw_rect_indicator_circle` + */ +static void lv_cpicker_invalidate_rect_indicator_circle(lv_disp_t * disp, + lv_cpicker_ext_t * ext, + lv_coord_t ind_pos) +{ + lv_area_t circle_ind_area; + circle_ind_area.x1 = ext->rect_gradient_area.x1 + ind_pos - ext->rect_gradient_h/2; + circle_ind_area.x2 = circle_ind_area.x1 + ext->rect_gradient_h; + circle_ind_area.y1 = ext->rect_gradient_area.y1; + circle_ind_area.y2 = ext->rect_gradient_area.y2; + + lv_inv_area(disp, &circle_ind_area); +} + +/** + * Should roughly match up with `lv_cpicker_draw_rect_indicator_in` + */ +static void lv_cpicker_invalidate_rect_indicator_in(lv_disp_t * disp, + lv_cpicker_ext_t * ext, + lv_coord_t ind_pos) +{ + lv_coord_t center = ext->rect_gradient_area.x1 + ind_pos; + + lv_area_t ind_area; + ind_area.x1 = center - ext->indicator.style->line.width * 3; + ind_area.y1 = ext->rect_gradient_area.y1 - 1; + ind_area.x2 = center + ext->indicator.style->line.width * 3; + ind_area.y2 = ext->rect_gradient_area.y2; + + lv_inv_area(disp, &ind_area); +} + +/** + * Should roughly match up with `lv_cpicker_rect_design` + */ +static void lv_cpicker_invalidate_rect(lv_disp_t * disp, lv_style_t * style, + lv_cpicker_ext_t * ext, + lv_coord_t w, lv_coord_t h) +{ + /*invalidate color preview indicator*/ + lv_inv_area(disp, &ext->rect_preview_area); + + /*invalidate indicator*/ + lv_coord_t ind_pos = lv_cpicker_get_indicator_coord(style, ext); + switch(ext->indicator.type) + { + case LV_CPICKER_INDICATOR_LINE: + lv_cpicker_invalidate_rect_indicator_line(disp, ext, ind_pos); + lv_cpicker_invalidate_rect_indicator_line(disp, ext, ext->prev_pos); + break; + case LV_CPICKER_INDICATOR_CIRCLE: + lv_cpicker_invalidate_rect_indicator_circle(disp, ext, ind_pos); + lv_cpicker_invalidate_rect_indicator_circle(disp, ext, ext->prev_pos); + break; + case LV_CPICKER_INDICATOR_IN: + lv_cpicker_invalidate_rect_indicator_in(disp, ext, ind_pos); + lv_cpicker_invalidate_rect_indicator_in(disp, ext, ext->prev_pos); + break; + } +} + +#endif /* LV_USE_CPICKER != 0 */ From 7ac2aff9824efe2f6eda4c534fdc033302ac9395 Mon Sep 17 00:00:00 2001 From: Paul Peavyhouse Date: Thu, 26 Sep 2019 22:35:41 -0700 Subject: [PATCH 20/82] Using #define defaults instead of hard-coded numbers --- src/lv_objx/lv_cpicker.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/lv_objx/lv_cpicker.c b/src/lv_objx/lv_cpicker.c index 9889c248e..6615397c7 100644 --- a/src/lv_objx/lv_cpicker.c +++ b/src/lv_objx/lv_cpicker.c @@ -1321,15 +1321,15 @@ static void lv_cpicker_reset_hsv_if_double_clicked(lv_obj_t * cpicker, switch(ext->color_mode) { case LV_CPICKER_COLOR_MODE_HUE: - ext->hue = 0; + ext->hue = LV_CPICKER_DEF_HUE; ext->prev_hue = ext->hue; break; case LV_CPICKER_COLOR_MODE_SATURATION: - ext->saturation = 100; + ext->saturation = LV_CPICKER_DEF_SATURATION; ext->prev_saturation = ext->saturation; break; case LV_CPICKER_COLOR_MODE_VALUE: - ext->value = 100; + ext->value = LV_CPICKER_DEF_VALUE; ext->prev_value = ext->value; break; } From 1a3d61e074213fa3387e483fe37f414049c8cac2 Mon Sep 17 00:00:00 2001 From: Paul Peavyhouse Date: Sat, 28 Sep 2019 01:41:26 -0700 Subject: [PATCH 21/82] Consolidate separate h, s, & v vars in to single lv_color_hsv_t var --- src/lv_objx/lv_cpicker.c | 197 +++++++++++++++++---------------------- src/lv_objx/lv_cpicker.h | 28 ++++-- 2 files changed, 105 insertions(+), 120 deletions(-) diff --git a/src/lv_objx/lv_cpicker.c b/src/lv_objx/lv_cpicker.c index 6615397c7..c16fe61a5 100644 --- a/src/lv_objx/lv_cpicker.c +++ b/src/lv_objx/lv_cpicker.c @@ -9,6 +9,7 @@ #include "lv_cpicker.h" #if LV_USE_CPICKER != 0 +#include "../lv_core/lv_debug.h" #include "../lv_draw/lv_draw_arc.h" #include "../lv_themes/lv_theme.h" #include "../lv_core/lv_indev.h" @@ -34,6 +35,10 @@ #define LV_CPICKER_DEF_VALUE 100 #endif +#ifndef LV_CPICKER_DEF_HSV +#define LV_CPICKER_DEF_HSV ((lv_color_hsv_t){LV_CPICKER_DEF_HUE, LV_CPICKER_DEF_SATURATION, LV_CPICKER_DEF_VALUE}) +#endif + #ifndef LV_CPICKER_DEF_INDICATOR_TYPE #define LV_CPICKER_DEF_INDICATOR_TYPE LV_CPICKER_INDICATOR_CIRCLE #endif @@ -92,7 +97,7 @@ lv_obj_t * lv_cpicker_create(lv_obj_t * par, const lv_obj_t * copy) LV_LOG_TRACE("color_picker create started"); lv_obj_t * new_cpicker = lv_obj_create(par, copy); - lv_mem_assert(new_cpicker); + LV_ASSERT_MEM(new_cpicker); if(new_cpicker == NULL) return NULL; if(ancestor_signal == NULL) ancestor_signal = lv_obj_get_signal_cb(new_cpicker); @@ -100,14 +105,12 @@ lv_obj_t * lv_cpicker_create(lv_obj_t * par, const lv_obj_t * copy) /*Allocate the extended data*/ lv_cpicker_ext_t * ext = lv_obj_allocate_ext_attr(new_cpicker, sizeof(lv_cpicker_ext_t)); - lv_mem_assert(ext); + LV_ASSERT_MEM(ext); if(ext == NULL) return NULL; /*Initialize the allocated 'ext' */ - ext->hue = LV_CPICKER_DEF_HUE; - ext->prev_hue = ext->hue; - ext->saturation = LV_CPICKER_DEF_SATURATION; - ext->value = LV_CPICKER_DEF_VALUE; + ext->hsv = LV_CPICKER_DEF_HSV; + ext->prev_hsv = ext->hsv; ext->indicator.style = &lv_style_plain; ext->indicator.type = LV_CPICKER_DEF_INDICATOR_TYPE; ext->color_mode = LV_CPICKER_COLOR_MODE_HUE; @@ -201,7 +204,7 @@ void lv_cpicker_set_hue(lv_obj_t * cpicker, uint16_t hue) { lv_cpicker_ext_t * ext = lv_obj_get_ext_attr(cpicker); - ext->hue = hue % 360; + ext->hsv.h = hue % 360; lv_obj_invalidate(cpicker); } @@ -215,7 +218,7 @@ void lv_cpicker_set_saturation(lv_obj_t * cpicker, uint8_t saturation) { lv_cpicker_ext_t * ext = lv_obj_get_ext_attr(cpicker); - ext->saturation = saturation % 100; + ext->hsv.s = saturation % 100; lv_obj_invalidate(cpicker); } @@ -229,7 +232,21 @@ void lv_cpicker_set_value(lv_obj_t * cpicker, uint8_t val) { lv_cpicker_ext_t * ext = lv_obj_get_ext_attr(cpicker); - ext->value = val % 100; + ext->hsv.v = val % 100; + + lv_obj_invalidate(cpicker); +} + +/** + * Set the current hsv of a colorpicker. + * @param cpicker pointer to colorpicker object + * @param color current selected hsv + */ +void lv_cpicker_set_hsv(lv_obj_t * cpicker, lv_color_hsv_t hsv) +{ + lv_cpicker_ext_t * ext = lv_obj_get_ext_attr(cpicker); + + ext->hsv = hsv; lv_obj_invalidate(cpicker); } @@ -241,12 +258,7 @@ void lv_cpicker_set_value(lv_obj_t * cpicker, uint8_t val) */ void lv_cpicker_set_color(lv_obj_t * cpicker, lv_color_t color) { - lv_cpicker_ext_t * ext = lv_obj_get_ext_attr(cpicker); - - lv_color_hsv_t hsv = lv_color_rgb_to_hsv(color.ch.red, color.ch.green, color.ch.blue); - ext->hue = hsv.h; - - lv_obj_invalidate(cpicker); + lv_cpicker_set_hsv(cpicker, lv_color_rgb_to_hsv(color.ch.red, color.ch.green, color.ch.blue)); } /** @@ -325,7 +337,7 @@ lv_style_t * lv_cpicker_get_style(const lv_obj_t * cpicker, lv_cpicker_style_t t } /** - * Get the current hue of a colorpicker. + * Get the current selected hue of a colorpicker. * @param cpicker pointer to colorpicker object * @return hue current selected hue */ @@ -333,11 +345,11 @@ uint16_t lv_cpicker_get_hue(lv_obj_t * cpicker) { lv_cpicker_ext_t * ext = lv_obj_get_ext_attr(cpicker); - return ext->hue; + return ext->hsv.h; } /** - * Get the current saturation of a colorpicker. + * Get the current selected saturation of a colorpicker. * @param cpicker pointer to colorpicker object * @return current selected saturation */ @@ -345,11 +357,11 @@ uint8_t lv_cpicker_get_saturation(lv_obj_t * cpicker) { lv_cpicker_ext_t * ext = lv_obj_get_ext_attr(cpicker); - return ext->saturation; + return ext->hsv.s; } /** - * Get the current hue of a colorpicker. + * Get the current selected hue of a colorpicker. * @param cpicker pointer to colorpicker object * @return current selected value */ @@ -357,7 +369,19 @@ uint8_t lv_cpicker_get_value(lv_obj_t * cpicker) { lv_cpicker_ext_t * ext = lv_obj_get_ext_attr(cpicker); - return ext->value; + return ext->hsv.v; +} + +/** + * Get the current selected hsv of a colorpicker. + * @param cpicker pointer to colorpicker object + * @return current selected hsv + */ +lv_color_hsv_t lv_cpicker_get_hsv(lv_obj_t * cpicker) +{ + lv_cpicker_ext_t * ext = lv_obj_get_ext_attr(cpicker); + + return ext->hsv; } /** @@ -369,7 +393,7 @@ lv_color_t lv_cpicker_get_color(lv_obj_t * cpicker) { lv_cpicker_ext_t * ext = lv_obj_get_ext_attr(cpicker); - return lv_color_hsv_to_rgb(ext->hue, ext->saturation, ext->value); + return lv_color_hsv_to_rgb(ext->hsv.h, ext->hsv.s, ext->hsv.v); } /*===================== @@ -452,13 +476,13 @@ static lv_color_t angle_to_mode_color(lv_cpicker_ext_t * ext, uint16_t angle) { default: case LV_CPICKER_COLOR_MODE_HUE: - color = lv_color_hsv_to_rgb(angle % 360, ext->saturation, ext->value); + color = lv_color_hsv_to_rgb(angle % 360, ext->hsv.s, ext->hsv.v); break; case LV_CPICKER_COLOR_MODE_SATURATION: - color = lv_color_hsv_to_rgb(ext->hue, (angle % 360) / 360.0 * 100.0, ext->value); + color = lv_color_hsv_to_rgb(ext->hsv.h, (angle % 360) / 360.0 * 100.0, ext->hsv.v); break; case LV_CPICKER_COLOR_MODE_VALUE: - color = lv_color_hsv_to_rgb(ext->hue, ext->saturation, (angle % 360) / 360.0 * 100.0); + color = lv_color_hsv_to_rgb(ext->hsv.h, ext->hsv.s, (angle % 360) / 360.0 * 100.0); break; } return color; @@ -471,13 +495,13 @@ static uint16_t mode_color_to_angle(lv_cpicker_ext_t * ext) { default: case LV_CPICKER_COLOR_MODE_HUE: - angle = ext->hue; + angle = ext->hsv.h; break; case LV_CPICKER_COLOR_MODE_SATURATION: - angle = ext->saturation / 100.0 * 360.0; + angle = ext->hsv.s / 100.0 * 360.0; break; case LV_CPICKER_COLOR_MODE_VALUE: - angle = ext->value / 100.0 * 360.0; + angle = ext->hsv.v / 100.0 * 360.0; break; } return angle; @@ -490,13 +514,13 @@ static lv_coord_t lv_cpicker_get_indicator_coord(lv_style_t * style, lv_cpicker_ { default: case LV_CPICKER_COLOR_MODE_HUE: - ind_pos += ext->hue / 360.0 * ext->rect_gradient_w; + ind_pos += ext->hsv.h / 360.0 * ext->rect_gradient_w; break; case LV_CPICKER_COLOR_MODE_SATURATION: - ind_pos += ext->saturation / 100.0 * ext->rect_gradient_w; + ind_pos += ext->hsv.s / 100.0 * ext->rect_gradient_w; break; case LV_CPICKER_COLOR_MODE_VALUE: - ind_pos += ext->value / 100.0 * ext->rect_gradient_w; + ind_pos += ext->hsv.v / 100.0 * ext->rect_gradient_w; break; } return ind_pos; @@ -610,7 +634,7 @@ static void lv_cpicker_draw_disc_indicator(lv_area_t * mask, lv_style_t * style, lv_draw_rect(¢er_area, mask, &styleCenterBackground, opa_scale); /*draw the center color indicator*/ - style->body.main_color = lv_color_hsv_to_rgb(ext->hue, ext->saturation, ext->value); + style->body.main_color = lv_color_hsv_to_rgb(ext->hsv.h, ext->hsv.s, ext->hsv.v); style->body.grad_color = style->body.main_color; style->body.radius = LV_RADIUS_CIRCLE; lv_draw_rect(¢er_ind_area, mask, style, opa_scale); @@ -1181,13 +1205,13 @@ static lv_res_t lv_cpicker_signal(lv_obj_t * cpicker, lv_signal_t sign, void * p switch(ext->color_mode) { case LV_CPICKER_COLOR_MODE_HUE: - ext->hue = (ext->hue + 1) % 360; + ext->hsv.h = (ext->hsv.h + 1) % 360; break; case LV_CPICKER_COLOR_MODE_SATURATION: - ext->saturation = (ext->saturation + 1) % 100; + ext->hsv.s = (ext->hsv.s + 1) % 100; break; case LV_CPICKER_COLOR_MODE_VALUE: - ext->value = (ext->value + 1) % 100; + ext->hsv.v = (ext->hsv.v + 1) % 100; break; } @@ -1201,13 +1225,13 @@ static lv_res_t lv_cpicker_signal(lv_obj_t * cpicker, lv_signal_t sign, void * p switch(ext->color_mode) { case LV_CPICKER_COLOR_MODE_HUE: - ext->hue = ext->hue > 0?(ext->hue - 1):360; + ext->hsv.h = ext->hsv.h > 0?(ext->hsv.h - 1):360; break; case LV_CPICKER_COLOR_MODE_SATURATION: - ext->saturation = ext->saturation > 0?(ext->saturation - 1):100; + ext->hsv.s = ext->hsv.s > 0?(ext->hsv.s - 1):100; break; case LV_CPICKER_COLOR_MODE_VALUE: - ext->value = ext->value > 0?(ext->value - 1):100; + ext->hsv.v = ext->hsv.v > 0?(ext->hsv.v - 1):100; break; } @@ -1221,13 +1245,13 @@ static lv_res_t lv_cpicker_signal(lv_obj_t * cpicker, lv_signal_t sign, void * p switch(ext->color_mode) { case LV_CPICKER_COLOR_MODE_HUE: - ext->hue = (ext->hue + 1) % 360; + ext->hsv.h = (ext->hsv.h + 1) % 360; break; case LV_CPICKER_COLOR_MODE_SATURATION: - ext->saturation = (ext->saturation + 1) % 100; + ext->hsv.s = (ext->hsv.s + 1) % 100; break; case LV_CPICKER_COLOR_MODE_VALUE: - ext->value = (ext->value + 1) % 100; + ext->hsv.v = (ext->hsv.v + 1) % 100; break; } @@ -1241,13 +1265,13 @@ static lv_res_t lv_cpicker_signal(lv_obj_t * cpicker, lv_signal_t sign, void * p switch(ext->color_mode) { case LV_CPICKER_COLOR_MODE_HUE: - ext->hue = ext->hue > 0?(ext->hue - 1):360; + ext->hsv.h = ext->hsv.h > 0?(ext->hsv.h - 1):360; break; case LV_CPICKER_COLOR_MODE_SATURATION: - ext->saturation = ext->saturation > 0?(ext->saturation - 1):100; + ext->hsv.s = ext->hsv.s > 0?(ext->hsv.s - 1):100; break; case LV_CPICKER_COLOR_MODE_VALUE: - ext->value = ext->value > 0?(ext->value - 1):100; + ext->hsv.v = ext->hsv.v > 0?(ext->hsv.v - 1):100; break; } @@ -1279,40 +1303,6 @@ static lv_res_t lv_cpicker_signal(lv_obj_t * cpicker, lv_signal_t sign, void * p return res; } -static void lv_cpicker_prev_hsv_save(lv_cpicker_ext_t * ext) -{ - switch(ext->color_mode) - { - case LV_CPICKER_COLOR_MODE_HUE: - ext->prev_hue = ext->hue; - break; - case LV_CPICKER_COLOR_MODE_SATURATION: - ext->prev_saturation = ext->saturation; - break; - case LV_CPICKER_COLOR_MODE_VALUE: - ext->prev_value = ext->value; - break; - } -} - -static void lv_cpicker_prev_hsv_restore(lv_obj_t * cpicker, - lv_cpicker_ext_t * ext) -{ - switch(ext->color_mode) - { - case LV_CPICKER_COLOR_MODE_HUE: - ext->prev_hue = ext->hue; - break; - case LV_CPICKER_COLOR_MODE_SATURATION: - ext->prev_saturation = ext->saturation; - break; - case LV_CPICKER_COLOR_MODE_VALUE: - ext->prev_value = ext->value; - break; - } - lv_cpicker_invalidate(cpicker, false); -} - static void lv_cpicker_reset_hsv_if_double_clicked(lv_obj_t * cpicker, lv_cpicker_ext_t * ext) { @@ -1321,18 +1311,16 @@ static void lv_cpicker_reset_hsv_if_double_clicked(lv_obj_t * cpicker, switch(ext->color_mode) { case LV_CPICKER_COLOR_MODE_HUE: - ext->hue = LV_CPICKER_DEF_HUE; - ext->prev_hue = ext->hue; + ext->hsv.h = LV_CPICKER_DEF_HSV.h; break; case LV_CPICKER_COLOR_MODE_SATURATION: - ext->saturation = LV_CPICKER_DEF_SATURATION; - ext->prev_saturation = ext->saturation; + ext->hsv.s = LV_CPICKER_DEF_HSV.s; break; case LV_CPICKER_COLOR_MODE_VALUE: - ext->value = LV_CPICKER_DEF_VALUE; - ext->prev_value = ext->value; + ext->hsv.v = LV_CPICKER_DEF_HSV.v; break; } + ext->prev_hsv = ext->hsv; lv_cpicker_invalidate(cpicker, false); } ext->last_click = lv_tick_get(); @@ -1341,21 +1329,8 @@ static void lv_cpicker_reset_hsv_if_double_clicked(lv_obj_t * cpicker, static void lv_cpicker_set_next_color_mode(lv_obj_t * cpicker, lv_cpicker_ext_t * ext) { - switch(ext->color_mode) - { - case LV_CPICKER_COLOR_MODE_HUE: - ext->prev_hue = ext->hue; - break; - case LV_CPICKER_COLOR_MODE_SATURATION: - ext->prev_saturation = ext->saturation; - break; - case LV_CPICKER_COLOR_MODE_VALUE: - ext->prev_value = ext->value; - break; - } - + ext->prev_hsv = ext->hsv; ext->color_mode = (ext->color_mode + 1) % 3; - lv_cpicker_invalidate(cpicker, true); } @@ -1371,32 +1346,30 @@ static lv_res_t lv_cpicker_set_hsv_percent(lv_obj_t * cpicker, { case LV_CPICKER_COLOR_MODE_HUE: hsv = percent * 360.0; - changed = hsv != ext->hue; + changed = hsv != ext->hsv.h; if (changed) { - ext->hue = hsv; - ext->prev_hue = ext->hue; + ext->hsv.h = hsv; } break; case LV_CPICKER_COLOR_MODE_SATURATION: hsv = percent * 100.0; - changed = hsv != ext->saturation; + changed = hsv != ext->hsv.s; if (changed) { - ext->saturation = hsv; - ext->prev_saturation = ext->saturation; + ext->hsv.s = hsv; } break; case LV_CPICKER_COLOR_MODE_VALUE: hsv = percent * 100.0; - changed = hsv != ext->value; + changed = hsv != ext->hsv.v; if (changed) { - ext->value = hsv; - ext->prev_value = ext->value; + ext->hsv.v = hsv; } break; } + ext->prev_hsv = ext->hsv; if (changed) { @@ -1417,7 +1390,7 @@ static lv_res_t lv_cpicker_disc_signal(lv_obj_t * cpicker, lv_signal_t sign, voi if(sign == LV_SIGNAL_PRESSED) { - lv_cpicker_prev_hsv_save(ext); + ext->prev_hsv = ext->hsv; lv_indev_t * indev = param; @@ -1444,7 +1417,8 @@ static lv_res_t lv_cpicker_disc_signal(lv_obj_t * cpicker, lv_signal_t sign, voi } else if(sign == LV_SIGNAL_PRESS_LOST) { - lv_cpicker_prev_hsv_restore(cpicker, ext); + ext->prev_hsv = ext->hsv; + lv_cpicker_invalidate(cpicker, false); } else if(sign == LV_SIGNAL_RELEASED) { @@ -1485,7 +1459,7 @@ static lv_res_t lv_cpicker_rect_signal(lv_obj_t * cpicker, lv_signal_t sign, voi if(sign == LV_SIGNAL_PRESSED) { - lv_cpicker_prev_hsv_save(ext); + ext->prev_hsv = ext->hsv; lv_indev_t * indev = param; @@ -1510,7 +1484,8 @@ static lv_res_t lv_cpicker_rect_signal(lv_obj_t * cpicker, lv_signal_t sign, voi } else if(sign == LV_SIGNAL_PRESS_LOST) { - lv_cpicker_prev_hsv_restore(cpicker, ext); + ext->prev_hsv = ext->hsv; + lv_cpicker_invalidate(cpicker, false); } else if(sign == LV_SIGNAL_RELEASED) { diff --git a/src/lv_objx/lv_cpicker.h b/src/lv_objx/lv_cpicker.h index 406322579..987800e85 100644 --- a/src/lv_objx/lv_cpicker.h +++ b/src/lv_objx/lv_cpicker.h @@ -32,17 +32,13 @@ extern "C" { **********************/ /*Data of colorpicker*/ typedef struct { - uint16_t hue; - uint8_t saturation; - uint8_t value; + lv_color_hsv_t hsv; struct { lv_style_t * style; uint8_t type; } indicator; - uint16_t prev_hue; - uint8_t prev_saturation; - uint8_t prev_value; + lv_color_hsv_t prev_hsv; uint16_t prev_pos; uint8_t color_mode:2; uint8_t color_mode_fixed:1; @@ -141,6 +137,13 @@ void lv_cpicker_set_saturation(lv_obj_t * cpicker, uint8_t saturation); */ void lv_cpicker_set_value(lv_obj_t * cpicker, uint8_t val); +/** + * Set the current hsv of a colorpicker. + * @param cpicker pointer to colorpicker object + * @param hsv current selected hsv + */ +void lv_cpicker_set_hsv(lv_obj_t * cpicker, lv_color_hsv_t hsv); + /** * Set the current color of a colorpicker. * @param cpicker pointer to colorpicker object @@ -184,14 +187,14 @@ bool lv_cpicker_get_color_mode_fixed(lv_obj_t * cpicker); * Get style of a colorpicker. * @param cpicker pointer to colorpicker object * @param type which style should be get - * @return style pointer to the style + * @return pointer to the style */ lv_style_t * lv_cpicker_get_style(const lv_obj_t * cpicker, lv_cpicker_style_t type); /** * Get the current hue of a colorpicker. * @param cpicker pointer to colorpicker object - * @return hue current selected hue + * @return current selected hue */ uint16_t lv_cpicker_get_hue(lv_obj_t * cpicker); @@ -209,10 +212,17 @@ uint8_t lv_cpicker_get_saturation(lv_obj_t * cpicker); */ uint8_t lv_cpicker_get_value(lv_obj_t * cpicker); +/** + * Get the current selected hsv of a colorpicker. + * @param cpicker pointer to colorpicker object + * @return current selected hsv + */ +lv_color_hsv_t lv_cpicker_get_hsv(lv_obj_t * cpicker); + /** * Get the current selected color of a colorpicker. * @param cpicker pointer to colorpicker object - * @return color current selected color + * @return current selected color */ lv_color_t lv_cpicker_get_color(lv_obj_t * cpicker); From ab2114e4e773daa57147f33c7cb64871f8ebc68f Mon Sep 17 00:00:00 2001 From: Paul Peavyhouse Date: Sat, 28 Sep 2019 01:54:10 -0700 Subject: [PATCH 22/82] Eventing LV_EVENT_VALUE_CHANGED when double-clicked --- src/lv_objx/lv_cpicker.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/src/lv_objx/lv_cpicker.c b/src/lv_objx/lv_cpicker.c index c16fe61a5..9aebc2157 100644 --- a/src/lv_objx/lv_cpicker.c +++ b/src/lv_objx/lv_cpicker.c @@ -1303,9 +1303,11 @@ static lv_res_t lv_cpicker_signal(lv_obj_t * cpicker, lv_signal_t sign, void * p return res; } -static void lv_cpicker_reset_hsv_if_double_clicked(lv_obj_t * cpicker, - lv_cpicker_ext_t * ext) +static lv_res_t lv_cpicker_reset_hsv_if_double_clicked(lv_obj_t * cpicker, + lv_cpicker_ext_t * ext) { + lv_res_t res; + if(lv_tick_elaps(ext->last_click) < 400) { switch(ext->color_mode) @@ -1322,8 +1324,12 @@ static void lv_cpicker_reset_hsv_if_double_clicked(lv_obj_t * cpicker, } ext->prev_hsv = ext->hsv; lv_cpicker_invalidate(cpicker, false); + + res = lv_event_send(cpicker, LV_EVENT_VALUE_CHANGED, NULL); } ext->last_click = lv_tick_get(); + + return res; } static void lv_cpicker_set_next_color_mode(lv_obj_t * cpicker, @@ -1398,7 +1404,8 @@ static lv_res_t lv_cpicker_disc_signal(lv_obj_t * cpicker, lv_signal_t sign, voi lv_coord_t yp = indev->proc.types.pointer.act_point.y - y; if((xp*xp + yp*yp) < (r_in*r_in)) { - lv_cpicker_reset_hsv_if_double_clicked(cpicker, ext); + res = lv_cpicker_reset_hsv_if_double_clicked(cpicker, ext); + if(res != LV_RES_OK) return res; } } else if(sign == LV_SIGNAL_PRESSING) @@ -1465,7 +1472,8 @@ static lv_res_t lv_cpicker_rect_signal(lv_obj_t * cpicker, lv_signal_t sign, voi if(lv_area_is_point_on(&(ext->rect_preview_area), &indev->proc.types.pointer.act_point)) { - lv_cpicker_reset_hsv_if_double_clicked(cpicker, ext); + res = lv_cpicker_reset_hsv_if_double_clicked(cpicker, ext); + if(res != LV_RES_OK) return res; } } else if(sign == LV_SIGNAL_PRESSING) From 3a5293fa3222a90fd2e7d5c19744c6a43c040110 Mon Sep 17 00:00:00 2001 From: Paul Peavyhouse Date: Sun, 29 Sep 2019 20:56:05 -0700 Subject: [PATCH 23/82] Tiny consolidation of identical LV_SIGNAL_PRESS_LOST code --- src/lv_objx/lv_cpicker.c | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/src/lv_objx/lv_cpicker.c b/src/lv_objx/lv_cpicker.c index 9aebc2157..1c3e701a2 100644 --- a/src/lv_objx/lv_cpicker.c +++ b/src/lv_objx/lv_cpicker.c @@ -1280,6 +1280,9 @@ static lv_res_t lv_cpicker_signal(lv_obj_t * cpicker, lv_signal_t sign, void * p res = lv_event_send(cpicker, LV_EVENT_VALUE_CHANGED, NULL); if(res != LV_RES_OK) return res; } + } else if(sign == LV_SIGNAL_PRESS_LOST) { + ext->prev_hsv = ext->hsv; + lv_cpicker_invalidate(cpicker, false); } else { lv_style_t * style = lv_cpicker_get_style(cpicker, LV_CPICKER_STYLE_MAIN); @@ -1422,11 +1425,6 @@ static lv_res_t lv_cpicker_disc_signal(lv_obj_t * cpicker, lv_signal_t sign, voi if(res != LV_RES_OK) return res; } } - else if(sign == LV_SIGNAL_PRESS_LOST) - { - ext->prev_hsv = ext->hsv; - lv_cpicker_invalidate(cpicker, false); - } else if(sign == LV_SIGNAL_RELEASED) { lv_indev_t * indev = param; @@ -1490,11 +1488,6 @@ static lv_res_t lv_cpicker_rect_signal(lv_obj_t * cpicker, lv_signal_t sign, voi if(res != LV_RES_OK) return res; } } - else if(sign == LV_SIGNAL_PRESS_LOST) - { - ext->prev_hsv = ext->hsv; - lv_cpicker_invalidate(cpicker, false); - } else if(sign == LV_SIGNAL_RELEASED) { lv_indev_t * indev = param; From bf9ed06bac67baf97127102362be5e62d2348f6a Mon Sep 17 00:00:00 2001 From: Paul Peavyhouse Date: Sun, 29 Sep 2019 21:00:00 -0700 Subject: [PATCH 24/82] Consolidating identical LV_KEY_RIGHT/UP and LV_KEY_LEFT/DOWN code --- src/lv_objx/lv_cpicker.c | 44 ++-------------------------------------- 1 file changed, 2 insertions(+), 42 deletions(-) diff --git a/src/lv_objx/lv_cpicker.c b/src/lv_objx/lv_cpicker.c index 1c3e701a2..fcdd0d626 100644 --- a/src/lv_objx/lv_cpicker.c +++ b/src/lv_objx/lv_cpicker.c @@ -1200,7 +1200,7 @@ static lv_res_t lv_cpicker_signal(lv_obj_t * cpicker, lv_signal_t sign, void * p if(sign == LV_SIGNAL_CONTROL) { uint32_t c = *((uint32_t *)param); /*uint32_t because can be UTF-8*/ - if(c == LV_KEY_RIGHT) + if(c == LV_KEY_RIGHT || c == LV_KEY_UP) { switch(ext->color_mode) { @@ -1220,47 +1220,7 @@ static lv_res_t lv_cpicker_signal(lv_obj_t * cpicker, lv_signal_t sign, void * p res = lv_event_send(cpicker, LV_EVENT_VALUE_CHANGED, NULL); if(res != LV_RES_OK) return res; } - else if(c == LV_KEY_LEFT) - { - switch(ext->color_mode) - { - case LV_CPICKER_COLOR_MODE_HUE: - ext->hsv.h = ext->hsv.h > 0?(ext->hsv.h - 1):360; - break; - case LV_CPICKER_COLOR_MODE_SATURATION: - ext->hsv.s = ext->hsv.s > 0?(ext->hsv.s - 1):100; - break; - case LV_CPICKER_COLOR_MODE_VALUE: - ext->hsv.v = ext->hsv.v > 0?(ext->hsv.v - 1):100; - break; - } - - lv_cpicker_invalidate(cpicker, false); - - res = lv_event_send(cpicker, LV_EVENT_VALUE_CHANGED, NULL); - if(res != LV_RES_OK) return res; - } - else if(c == LV_KEY_UP) - { - switch(ext->color_mode) - { - case LV_CPICKER_COLOR_MODE_HUE: - ext->hsv.h = (ext->hsv.h + 1) % 360; - break; - case LV_CPICKER_COLOR_MODE_SATURATION: - ext->hsv.s = (ext->hsv.s + 1) % 100; - break; - case LV_CPICKER_COLOR_MODE_VALUE: - ext->hsv.v = (ext->hsv.v + 1) % 100; - break; - } - - lv_cpicker_invalidate(cpicker, false); - - res = lv_event_send(cpicker, LV_EVENT_VALUE_CHANGED, NULL); - if(res != LV_RES_OK) return res; - } - else if(c == LV_KEY_DOWN) + else if(c == LV_KEY_LEFT || c == LV_KEY_DOWN) { switch(ext->color_mode) { From 1339d92ccd65e5d32230768e20f7f9c8b02d067c Mon Sep 17 00:00:00 2001 From: Paul Peavyhouse Date: Sun, 29 Sep 2019 21:02:12 -0700 Subject: [PATCH 25/82] Code formatting --- src/lv_objx/lv_cpicker.c | 25 ++++++++++++++++++------- 1 file changed, 18 insertions(+), 7 deletions(-) diff --git a/src/lv_objx/lv_cpicker.c b/src/lv_objx/lv_cpicker.c index fcdd0d626..4abbff739 100644 --- a/src/lv_objx/lv_cpicker.c +++ b/src/lv_objx/lv_cpicker.c @@ -1186,19 +1186,26 @@ static lv_res_t lv_cpicker_signal(lv_obj_t * cpicker, lv_signal_t sign, void * p lv_res_t res = ancestor_signal(cpicker, sign, param); if(res != LV_RES_OK) return res; - if(sign == LV_SIGNAL_CLEANUP) { + if(sign == LV_SIGNAL_CLEANUP) + { /*Nothing to cleanup. (No dynamically allocated memory in 'ext')*/ - } else if(sign == LV_SIGNAL_GET_TYPE) { + } + else if(sign == LV_SIGNAL_GET_TYPE) + { lv_obj_type_t * buf = param; uint8_t i; - for(i = 0; i < LV_MAX_ANCESTOR_NUM - 1; i++) { /*Find the last set data*/ + for(i = 0; i < LV_MAX_ANCESTOR_NUM - 1; i++) /*Find the last set data*/ + { if(buf->type[i] == NULL) break; } buf->type[i] = "lv_cpicker"; - } else { + } + else + { lv_cpicker_ext_t * ext = lv_obj_get_ext_attr(cpicker); - if(sign == LV_SIGNAL_CONTROL) { + if(sign == LV_SIGNAL_CONTROL) + { uint32_t c = *((uint32_t *)param); /*uint32_t because can be UTF-8*/ if(c == LV_KEY_RIGHT || c == LV_KEY_UP) { @@ -1240,10 +1247,14 @@ static lv_res_t lv_cpicker_signal(lv_obj_t * cpicker, lv_signal_t sign, void * p res = lv_event_send(cpicker, LV_EVENT_VALUE_CHANGED, NULL); if(res != LV_RES_OK) return res; } - } else if(sign == LV_SIGNAL_PRESS_LOST) { + } + else if(sign == LV_SIGNAL_PRESS_LOST) + { ext->prev_hsv = ext->hsv; lv_cpicker_invalidate(cpicker, false); - } else { + } + else + { lv_style_t * style = lv_cpicker_get_style(cpicker, LV_CPICKER_STYLE_MAIN); if(ext->type == LV_CPICKER_TYPE_DISC) From 93d2d422b804baeb10322ce749e40c24fc482d94 Mon Sep 17 00:00:00 2001 From: Paul Peavyhouse Date: Sun, 29 Sep 2019 21:11:53 -0700 Subject: [PATCH 26/82] Not emitting LV_EVENT_VALUE_CHANGED if double-click doesn't change value --- src/lv_objx/lv_cpicker.c | 31 ++++++++++++++++++++++++------- 1 file changed, 24 insertions(+), 7 deletions(-) diff --git a/src/lv_objx/lv_cpicker.c b/src/lv_objx/lv_cpicker.c index 4abbff739..ad138d126 100644 --- a/src/lv_objx/lv_cpicker.c +++ b/src/lv_objx/lv_cpicker.c @@ -1280,29 +1280,46 @@ static lv_res_t lv_cpicker_signal(lv_obj_t * cpicker, lv_signal_t sign, void * p static lv_res_t lv_cpicker_reset_hsv_if_double_clicked(lv_obj_t * cpicker, lv_cpicker_ext_t * ext) { - lv_res_t res; + bool changed = false; if(lv_tick_elaps(ext->last_click) < 400) { switch(ext->color_mode) { case LV_CPICKER_COLOR_MODE_HUE: - ext->hsv.h = LV_CPICKER_DEF_HSV.h; + changed = ext->hsv.h != LV_CPICKER_DEF_HSV.h; + if (changed) + { + ext->hsv.h = LV_CPICKER_DEF_HSV.h; + } break; case LV_CPICKER_COLOR_MODE_SATURATION: - ext->hsv.s = LV_CPICKER_DEF_HSV.s; + changed = ext->hsv.s != LV_CPICKER_DEF_HSV.s; + if (changed) + { + ext->hsv.s = LV_CPICKER_DEF_HSV.s; + } break; case LV_CPICKER_COLOR_MODE_VALUE: - ext->hsv.v = LV_CPICKER_DEF_HSV.v; + changed = ext->hsv.v != LV_CPICKER_DEF_HSV.v; + if (changed) + { + ext->hsv.v = LV_CPICKER_DEF_HSV.v; + } break; } ext->prev_hsv = ext->hsv; - lv_cpicker_invalidate(cpicker, false); - - res = lv_event_send(cpicker, LV_EVENT_VALUE_CHANGED, NULL); } ext->last_click = lv_tick_get(); + lv_res_t res = LV_RES_OK; + if (changed) + { + lv_cpicker_invalidate(cpicker, false); + + res = lv_event_send(cpicker, LV_EVENT_VALUE_CHANGED, NULL); + if(res != LV_RES_OK) return res; + } return res; } From 333812ba7aa2d522a5c43074eb21d16308d9e8bb Mon Sep 17 00:00:00 2001 From: Paul Peavyhouse Date: Mon, 30 Sep 2019 07:00:34 -0700 Subject: [PATCH 27/82] Improvements to color picker (#1208) --- src/lv_objx/lv_cpicker.c | 290 +++++++++++++++++---------------------- src/lv_objx/lv_cpicker.h | 28 ++-- 2 files changed, 146 insertions(+), 172 deletions(-) diff --git a/src/lv_objx/lv_cpicker.c b/src/lv_objx/lv_cpicker.c index 6615397c7..ad138d126 100644 --- a/src/lv_objx/lv_cpicker.c +++ b/src/lv_objx/lv_cpicker.c @@ -9,6 +9,7 @@ #include "lv_cpicker.h" #if LV_USE_CPICKER != 0 +#include "../lv_core/lv_debug.h" #include "../lv_draw/lv_draw_arc.h" #include "../lv_themes/lv_theme.h" #include "../lv_core/lv_indev.h" @@ -34,6 +35,10 @@ #define LV_CPICKER_DEF_VALUE 100 #endif +#ifndef LV_CPICKER_DEF_HSV +#define LV_CPICKER_DEF_HSV ((lv_color_hsv_t){LV_CPICKER_DEF_HUE, LV_CPICKER_DEF_SATURATION, LV_CPICKER_DEF_VALUE}) +#endif + #ifndef LV_CPICKER_DEF_INDICATOR_TYPE #define LV_CPICKER_DEF_INDICATOR_TYPE LV_CPICKER_INDICATOR_CIRCLE #endif @@ -92,7 +97,7 @@ lv_obj_t * lv_cpicker_create(lv_obj_t * par, const lv_obj_t * copy) LV_LOG_TRACE("color_picker create started"); lv_obj_t * new_cpicker = lv_obj_create(par, copy); - lv_mem_assert(new_cpicker); + LV_ASSERT_MEM(new_cpicker); if(new_cpicker == NULL) return NULL; if(ancestor_signal == NULL) ancestor_signal = lv_obj_get_signal_cb(new_cpicker); @@ -100,14 +105,12 @@ lv_obj_t * lv_cpicker_create(lv_obj_t * par, const lv_obj_t * copy) /*Allocate the extended data*/ lv_cpicker_ext_t * ext = lv_obj_allocate_ext_attr(new_cpicker, sizeof(lv_cpicker_ext_t)); - lv_mem_assert(ext); + LV_ASSERT_MEM(ext); if(ext == NULL) return NULL; /*Initialize the allocated 'ext' */ - ext->hue = LV_CPICKER_DEF_HUE; - ext->prev_hue = ext->hue; - ext->saturation = LV_CPICKER_DEF_SATURATION; - ext->value = LV_CPICKER_DEF_VALUE; + ext->hsv = LV_CPICKER_DEF_HSV; + ext->prev_hsv = ext->hsv; ext->indicator.style = &lv_style_plain; ext->indicator.type = LV_CPICKER_DEF_INDICATOR_TYPE; ext->color_mode = LV_CPICKER_COLOR_MODE_HUE; @@ -201,7 +204,7 @@ void lv_cpicker_set_hue(lv_obj_t * cpicker, uint16_t hue) { lv_cpicker_ext_t * ext = lv_obj_get_ext_attr(cpicker); - ext->hue = hue % 360; + ext->hsv.h = hue % 360; lv_obj_invalidate(cpicker); } @@ -215,7 +218,7 @@ void lv_cpicker_set_saturation(lv_obj_t * cpicker, uint8_t saturation) { lv_cpicker_ext_t * ext = lv_obj_get_ext_attr(cpicker); - ext->saturation = saturation % 100; + ext->hsv.s = saturation % 100; lv_obj_invalidate(cpicker); } @@ -229,7 +232,21 @@ void lv_cpicker_set_value(lv_obj_t * cpicker, uint8_t val) { lv_cpicker_ext_t * ext = lv_obj_get_ext_attr(cpicker); - ext->value = val % 100; + ext->hsv.v = val % 100; + + lv_obj_invalidate(cpicker); +} + +/** + * Set the current hsv of a colorpicker. + * @param cpicker pointer to colorpicker object + * @param color current selected hsv + */ +void lv_cpicker_set_hsv(lv_obj_t * cpicker, lv_color_hsv_t hsv) +{ + lv_cpicker_ext_t * ext = lv_obj_get_ext_attr(cpicker); + + ext->hsv = hsv; lv_obj_invalidate(cpicker); } @@ -241,12 +258,7 @@ void lv_cpicker_set_value(lv_obj_t * cpicker, uint8_t val) */ void lv_cpicker_set_color(lv_obj_t * cpicker, lv_color_t color) { - lv_cpicker_ext_t * ext = lv_obj_get_ext_attr(cpicker); - - lv_color_hsv_t hsv = lv_color_rgb_to_hsv(color.ch.red, color.ch.green, color.ch.blue); - ext->hue = hsv.h; - - lv_obj_invalidate(cpicker); + lv_cpicker_set_hsv(cpicker, lv_color_rgb_to_hsv(color.ch.red, color.ch.green, color.ch.blue)); } /** @@ -325,7 +337,7 @@ lv_style_t * lv_cpicker_get_style(const lv_obj_t * cpicker, lv_cpicker_style_t t } /** - * Get the current hue of a colorpicker. + * Get the current selected hue of a colorpicker. * @param cpicker pointer to colorpicker object * @return hue current selected hue */ @@ -333,11 +345,11 @@ uint16_t lv_cpicker_get_hue(lv_obj_t * cpicker) { lv_cpicker_ext_t * ext = lv_obj_get_ext_attr(cpicker); - return ext->hue; + return ext->hsv.h; } /** - * Get the current saturation of a colorpicker. + * Get the current selected saturation of a colorpicker. * @param cpicker pointer to colorpicker object * @return current selected saturation */ @@ -345,11 +357,11 @@ uint8_t lv_cpicker_get_saturation(lv_obj_t * cpicker) { lv_cpicker_ext_t * ext = lv_obj_get_ext_attr(cpicker); - return ext->saturation; + return ext->hsv.s; } /** - * Get the current hue of a colorpicker. + * Get the current selected hue of a colorpicker. * @param cpicker pointer to colorpicker object * @return current selected value */ @@ -357,7 +369,19 @@ uint8_t lv_cpicker_get_value(lv_obj_t * cpicker) { lv_cpicker_ext_t * ext = lv_obj_get_ext_attr(cpicker); - return ext->value; + return ext->hsv.v; +} + +/** + * Get the current selected hsv of a colorpicker. + * @param cpicker pointer to colorpicker object + * @return current selected hsv + */ +lv_color_hsv_t lv_cpicker_get_hsv(lv_obj_t * cpicker) +{ + lv_cpicker_ext_t * ext = lv_obj_get_ext_attr(cpicker); + + return ext->hsv; } /** @@ -369,7 +393,7 @@ lv_color_t lv_cpicker_get_color(lv_obj_t * cpicker) { lv_cpicker_ext_t * ext = lv_obj_get_ext_attr(cpicker); - return lv_color_hsv_to_rgb(ext->hue, ext->saturation, ext->value); + return lv_color_hsv_to_rgb(ext->hsv.h, ext->hsv.s, ext->hsv.v); } /*===================== @@ -452,13 +476,13 @@ static lv_color_t angle_to_mode_color(lv_cpicker_ext_t * ext, uint16_t angle) { default: case LV_CPICKER_COLOR_MODE_HUE: - color = lv_color_hsv_to_rgb(angle % 360, ext->saturation, ext->value); + color = lv_color_hsv_to_rgb(angle % 360, ext->hsv.s, ext->hsv.v); break; case LV_CPICKER_COLOR_MODE_SATURATION: - color = lv_color_hsv_to_rgb(ext->hue, (angle % 360) / 360.0 * 100.0, ext->value); + color = lv_color_hsv_to_rgb(ext->hsv.h, (angle % 360) / 360.0 * 100.0, ext->hsv.v); break; case LV_CPICKER_COLOR_MODE_VALUE: - color = lv_color_hsv_to_rgb(ext->hue, ext->saturation, (angle % 360) / 360.0 * 100.0); + color = lv_color_hsv_to_rgb(ext->hsv.h, ext->hsv.s, (angle % 360) / 360.0 * 100.0); break; } return color; @@ -471,13 +495,13 @@ static uint16_t mode_color_to_angle(lv_cpicker_ext_t * ext) { default: case LV_CPICKER_COLOR_MODE_HUE: - angle = ext->hue; + angle = ext->hsv.h; break; case LV_CPICKER_COLOR_MODE_SATURATION: - angle = ext->saturation / 100.0 * 360.0; + angle = ext->hsv.s / 100.0 * 360.0; break; case LV_CPICKER_COLOR_MODE_VALUE: - angle = ext->value / 100.0 * 360.0; + angle = ext->hsv.v / 100.0 * 360.0; break; } return angle; @@ -490,13 +514,13 @@ static lv_coord_t lv_cpicker_get_indicator_coord(lv_style_t * style, lv_cpicker_ { default: case LV_CPICKER_COLOR_MODE_HUE: - ind_pos += ext->hue / 360.0 * ext->rect_gradient_w; + ind_pos += ext->hsv.h / 360.0 * ext->rect_gradient_w; break; case LV_CPICKER_COLOR_MODE_SATURATION: - ind_pos += ext->saturation / 100.0 * ext->rect_gradient_w; + ind_pos += ext->hsv.s / 100.0 * ext->rect_gradient_w; break; case LV_CPICKER_COLOR_MODE_VALUE: - ind_pos += ext->value / 100.0 * ext->rect_gradient_w; + ind_pos += ext->hsv.v / 100.0 * ext->rect_gradient_w; break; } return ind_pos; @@ -610,7 +634,7 @@ static void lv_cpicker_draw_disc_indicator(lv_area_t * mask, lv_style_t * style, lv_draw_rect(¢er_area, mask, &styleCenterBackground, opa_scale); /*draw the center color indicator*/ - style->body.main_color = lv_color_hsv_to_rgb(ext->hue, ext->saturation, ext->value); + style->body.main_color = lv_color_hsv_to_rgb(ext->hsv.h, ext->hsv.s, ext->hsv.v); style->body.grad_color = style->body.main_color; style->body.radius = LV_RADIUS_CIRCLE; lv_draw_rect(¢er_ind_area, mask, style, opa_scale); @@ -1162,32 +1186,39 @@ static lv_res_t lv_cpicker_signal(lv_obj_t * cpicker, lv_signal_t sign, void * p lv_res_t res = ancestor_signal(cpicker, sign, param); if(res != LV_RES_OK) return res; - if(sign == LV_SIGNAL_CLEANUP) { + if(sign == LV_SIGNAL_CLEANUP) + { /*Nothing to cleanup. (No dynamically allocated memory in 'ext')*/ - } else if(sign == LV_SIGNAL_GET_TYPE) { + } + else if(sign == LV_SIGNAL_GET_TYPE) + { lv_obj_type_t * buf = param; uint8_t i; - for(i = 0; i < LV_MAX_ANCESTOR_NUM - 1; i++) { /*Find the last set data*/ + for(i = 0; i < LV_MAX_ANCESTOR_NUM - 1; i++) /*Find the last set data*/ + { if(buf->type[i] == NULL) break; } buf->type[i] = "lv_cpicker"; - } else { + } + else + { lv_cpicker_ext_t * ext = lv_obj_get_ext_attr(cpicker); - if(sign == LV_SIGNAL_CONTROL) { + if(sign == LV_SIGNAL_CONTROL) + { uint32_t c = *((uint32_t *)param); /*uint32_t because can be UTF-8*/ - if(c == LV_KEY_RIGHT) + if(c == LV_KEY_RIGHT || c == LV_KEY_UP) { switch(ext->color_mode) { case LV_CPICKER_COLOR_MODE_HUE: - ext->hue = (ext->hue + 1) % 360; + ext->hsv.h = (ext->hsv.h + 1) % 360; break; case LV_CPICKER_COLOR_MODE_SATURATION: - ext->saturation = (ext->saturation + 1) % 100; + ext->hsv.s = (ext->hsv.s + 1) % 100; break; case LV_CPICKER_COLOR_MODE_VALUE: - ext->value = (ext->value + 1) % 100; + ext->hsv.v = (ext->hsv.v + 1) % 100; break; } @@ -1196,18 +1227,18 @@ static lv_res_t lv_cpicker_signal(lv_obj_t * cpicker, lv_signal_t sign, void * p res = lv_event_send(cpicker, LV_EVENT_VALUE_CHANGED, NULL); if(res != LV_RES_OK) return res; } - else if(c == LV_KEY_LEFT) + else if(c == LV_KEY_LEFT || c == LV_KEY_DOWN) { switch(ext->color_mode) { case LV_CPICKER_COLOR_MODE_HUE: - ext->hue = ext->hue > 0?(ext->hue - 1):360; + ext->hsv.h = ext->hsv.h > 0?(ext->hsv.h - 1):360; break; case LV_CPICKER_COLOR_MODE_SATURATION: - ext->saturation = ext->saturation > 0?(ext->saturation - 1):100; + ext->hsv.s = ext->hsv.s > 0?(ext->hsv.s - 1):100; break; case LV_CPICKER_COLOR_MODE_VALUE: - ext->value = ext->value > 0?(ext->value - 1):100; + ext->hsv.v = ext->hsv.v > 0?(ext->hsv.v - 1):100; break; } @@ -1216,47 +1247,14 @@ static lv_res_t lv_cpicker_signal(lv_obj_t * cpicker, lv_signal_t sign, void * p res = lv_event_send(cpicker, LV_EVENT_VALUE_CHANGED, NULL); if(res != LV_RES_OK) return res; } - else if(c == LV_KEY_UP) - { - switch(ext->color_mode) - { - case LV_CPICKER_COLOR_MODE_HUE: - ext->hue = (ext->hue + 1) % 360; - break; - case LV_CPICKER_COLOR_MODE_SATURATION: - ext->saturation = (ext->saturation + 1) % 100; - break; - case LV_CPICKER_COLOR_MODE_VALUE: - ext->value = (ext->value + 1) % 100; - break; - } - - lv_cpicker_invalidate(cpicker, false); - - res = lv_event_send(cpicker, LV_EVENT_VALUE_CHANGED, NULL); - if(res != LV_RES_OK) return res; - } - else if(c == LV_KEY_DOWN) - { - switch(ext->color_mode) - { - case LV_CPICKER_COLOR_MODE_HUE: - ext->hue = ext->hue > 0?(ext->hue - 1):360; - break; - case LV_CPICKER_COLOR_MODE_SATURATION: - ext->saturation = ext->saturation > 0?(ext->saturation - 1):100; - break; - case LV_CPICKER_COLOR_MODE_VALUE: - ext->value = ext->value > 0?(ext->value - 1):100; - break; - } - - lv_cpicker_invalidate(cpicker, false); - - res = lv_event_send(cpicker, LV_EVENT_VALUE_CHANGED, NULL); - if(res != LV_RES_OK) return res; - } - } else { + } + else if(sign == LV_SIGNAL_PRESS_LOST) + { + ext->prev_hsv = ext->hsv; + lv_cpicker_invalidate(cpicker, false); + } + else + { lv_style_t * style = lv_cpicker_get_style(cpicker, LV_CPICKER_STYLE_MAIN); if(ext->type == LV_CPICKER_TYPE_DISC) @@ -1279,83 +1277,57 @@ static lv_res_t lv_cpicker_signal(lv_obj_t * cpicker, lv_signal_t sign, void * p return res; } -static void lv_cpicker_prev_hsv_save(lv_cpicker_ext_t * ext) +static lv_res_t lv_cpicker_reset_hsv_if_double_clicked(lv_obj_t * cpicker, + lv_cpicker_ext_t * ext) { - switch(ext->color_mode) - { - case LV_CPICKER_COLOR_MODE_HUE: - ext->prev_hue = ext->hue; - break; - case LV_CPICKER_COLOR_MODE_SATURATION: - ext->prev_saturation = ext->saturation; - break; - case LV_CPICKER_COLOR_MODE_VALUE: - ext->prev_value = ext->value; - break; - } -} + bool changed = false; -static void lv_cpicker_prev_hsv_restore(lv_obj_t * cpicker, - lv_cpicker_ext_t * ext) -{ - switch(ext->color_mode) - { - case LV_CPICKER_COLOR_MODE_HUE: - ext->prev_hue = ext->hue; - break; - case LV_CPICKER_COLOR_MODE_SATURATION: - ext->prev_saturation = ext->saturation; - break; - case LV_CPICKER_COLOR_MODE_VALUE: - ext->prev_value = ext->value; - break; - } - lv_cpicker_invalidate(cpicker, false); -} - -static void lv_cpicker_reset_hsv_if_double_clicked(lv_obj_t * cpicker, - lv_cpicker_ext_t * ext) -{ if(lv_tick_elaps(ext->last_click) < 400) { switch(ext->color_mode) { case LV_CPICKER_COLOR_MODE_HUE: - ext->hue = LV_CPICKER_DEF_HUE; - ext->prev_hue = ext->hue; + changed = ext->hsv.h != LV_CPICKER_DEF_HSV.h; + if (changed) + { + ext->hsv.h = LV_CPICKER_DEF_HSV.h; + } break; case LV_CPICKER_COLOR_MODE_SATURATION: - ext->saturation = LV_CPICKER_DEF_SATURATION; - ext->prev_saturation = ext->saturation; + changed = ext->hsv.s != LV_CPICKER_DEF_HSV.s; + if (changed) + { + ext->hsv.s = LV_CPICKER_DEF_HSV.s; + } break; case LV_CPICKER_COLOR_MODE_VALUE: - ext->value = LV_CPICKER_DEF_VALUE; - ext->prev_value = ext->value; + changed = ext->hsv.v != LV_CPICKER_DEF_HSV.v; + if (changed) + { + ext->hsv.v = LV_CPICKER_DEF_HSV.v; + } break; } - lv_cpicker_invalidate(cpicker, false); + ext->prev_hsv = ext->hsv; } ext->last_click = lv_tick_get(); + + lv_res_t res = LV_RES_OK; + if (changed) + { + lv_cpicker_invalidate(cpicker, false); + + res = lv_event_send(cpicker, LV_EVENT_VALUE_CHANGED, NULL); + if(res != LV_RES_OK) return res; + } + return res; } static void lv_cpicker_set_next_color_mode(lv_obj_t * cpicker, lv_cpicker_ext_t * ext) { - switch(ext->color_mode) - { - case LV_CPICKER_COLOR_MODE_HUE: - ext->prev_hue = ext->hue; - break; - case LV_CPICKER_COLOR_MODE_SATURATION: - ext->prev_saturation = ext->saturation; - break; - case LV_CPICKER_COLOR_MODE_VALUE: - ext->prev_value = ext->value; - break; - } - + ext->prev_hsv = ext->hsv; ext->color_mode = (ext->color_mode + 1) % 3; - lv_cpicker_invalidate(cpicker, true); } @@ -1371,32 +1343,30 @@ static lv_res_t lv_cpicker_set_hsv_percent(lv_obj_t * cpicker, { case LV_CPICKER_COLOR_MODE_HUE: hsv = percent * 360.0; - changed = hsv != ext->hue; + changed = hsv != ext->hsv.h; if (changed) { - ext->hue = hsv; - ext->prev_hue = ext->hue; + ext->hsv.h = hsv; } break; case LV_CPICKER_COLOR_MODE_SATURATION: hsv = percent * 100.0; - changed = hsv != ext->saturation; + changed = hsv != ext->hsv.s; if (changed) { - ext->saturation = hsv; - ext->prev_saturation = ext->saturation; + ext->hsv.s = hsv; } break; case LV_CPICKER_COLOR_MODE_VALUE: hsv = percent * 100.0; - changed = hsv != ext->value; + changed = hsv != ext->hsv.v; if (changed) { - ext->value = hsv; - ext->prev_value = ext->value; + ext->hsv.v = hsv; } break; } + ext->prev_hsv = ext->hsv; if (changed) { @@ -1417,7 +1387,7 @@ static lv_res_t lv_cpicker_disc_signal(lv_obj_t * cpicker, lv_signal_t sign, voi if(sign == LV_SIGNAL_PRESSED) { - lv_cpicker_prev_hsv_save(ext); + ext->prev_hsv = ext->hsv; lv_indev_t * indev = param; @@ -1425,7 +1395,8 @@ static lv_res_t lv_cpicker_disc_signal(lv_obj_t * cpicker, lv_signal_t sign, voi lv_coord_t yp = indev->proc.types.pointer.act_point.y - y; if((xp*xp + yp*yp) < (r_in*r_in)) { - lv_cpicker_reset_hsv_if_double_clicked(cpicker, ext); + res = lv_cpicker_reset_hsv_if_double_clicked(cpicker, ext); + if(res != LV_RES_OK) return res; } } else if(sign == LV_SIGNAL_PRESSING) @@ -1442,10 +1413,6 @@ static lv_res_t lv_cpicker_disc_signal(lv_obj_t * cpicker, lv_signal_t sign, voi if(res != LV_RES_OK) return res; } } - else if(sign == LV_SIGNAL_PRESS_LOST) - { - lv_cpicker_prev_hsv_restore(cpicker, ext); - } else if(sign == LV_SIGNAL_RELEASED) { lv_indev_t * indev = param; @@ -1485,13 +1452,14 @@ static lv_res_t lv_cpicker_rect_signal(lv_obj_t * cpicker, lv_signal_t sign, voi if(sign == LV_SIGNAL_PRESSED) { - lv_cpicker_prev_hsv_save(ext); + ext->prev_hsv = ext->hsv; lv_indev_t * indev = param; if(lv_area_is_point_on(&(ext->rect_preview_area), &indev->proc.types.pointer.act_point)) { - lv_cpicker_reset_hsv_if_double_clicked(cpicker, ext); + res = lv_cpicker_reset_hsv_if_double_clicked(cpicker, ext); + if(res != LV_RES_OK) return res; } } else if(sign == LV_SIGNAL_PRESSING) @@ -1508,10 +1476,6 @@ static lv_res_t lv_cpicker_rect_signal(lv_obj_t * cpicker, lv_signal_t sign, voi if(res != LV_RES_OK) return res; } } - else if(sign == LV_SIGNAL_PRESS_LOST) - { - lv_cpicker_prev_hsv_restore(cpicker, ext); - } else if(sign == LV_SIGNAL_RELEASED) { lv_indev_t * indev = param; diff --git a/src/lv_objx/lv_cpicker.h b/src/lv_objx/lv_cpicker.h index 406322579..987800e85 100644 --- a/src/lv_objx/lv_cpicker.h +++ b/src/lv_objx/lv_cpicker.h @@ -32,17 +32,13 @@ extern "C" { **********************/ /*Data of colorpicker*/ typedef struct { - uint16_t hue; - uint8_t saturation; - uint8_t value; + lv_color_hsv_t hsv; struct { lv_style_t * style; uint8_t type; } indicator; - uint16_t prev_hue; - uint8_t prev_saturation; - uint8_t prev_value; + lv_color_hsv_t prev_hsv; uint16_t prev_pos; uint8_t color_mode:2; uint8_t color_mode_fixed:1; @@ -141,6 +137,13 @@ void lv_cpicker_set_saturation(lv_obj_t * cpicker, uint8_t saturation); */ void lv_cpicker_set_value(lv_obj_t * cpicker, uint8_t val); +/** + * Set the current hsv of a colorpicker. + * @param cpicker pointer to colorpicker object + * @param hsv current selected hsv + */ +void lv_cpicker_set_hsv(lv_obj_t * cpicker, lv_color_hsv_t hsv); + /** * Set the current color of a colorpicker. * @param cpicker pointer to colorpicker object @@ -184,14 +187,14 @@ bool lv_cpicker_get_color_mode_fixed(lv_obj_t * cpicker); * Get style of a colorpicker. * @param cpicker pointer to colorpicker object * @param type which style should be get - * @return style pointer to the style + * @return pointer to the style */ lv_style_t * lv_cpicker_get_style(const lv_obj_t * cpicker, lv_cpicker_style_t type); /** * Get the current hue of a colorpicker. * @param cpicker pointer to colorpicker object - * @return hue current selected hue + * @return current selected hue */ uint16_t lv_cpicker_get_hue(lv_obj_t * cpicker); @@ -209,10 +212,17 @@ uint8_t lv_cpicker_get_saturation(lv_obj_t * cpicker); */ uint8_t lv_cpicker_get_value(lv_obj_t * cpicker); +/** + * Get the current selected hsv of a colorpicker. + * @param cpicker pointer to colorpicker object + * @return current selected hsv + */ +lv_color_hsv_t lv_cpicker_get_hsv(lv_obj_t * cpicker); + /** * Get the current selected color of a colorpicker. * @param cpicker pointer to colorpicker object - * @return color current selected color + * @return current selected color */ lv_color_t lv_cpicker_get_color(lv_obj_t * cpicker); From 974e4a245eec65dba335d673f181187c9c2747a3 Mon Sep 17 00:00:00 2001 From: Paul Peavyhouse Date: Mon, 30 Sep 2019 15:43:02 -0700 Subject: [PATCH 28/82] Consolidating Disc and Rect lv_cpicker_signal --- src/lv_objx/lv_cpicker.c | 357 ++++++++++++++++++--------------------- 1 file changed, 167 insertions(+), 190 deletions(-) diff --git a/src/lv_objx/lv_cpicker.c b/src/lv_objx/lv_cpicker.c index ad138d126..7250f7689 100644 --- a/src/lv_objx/lv_cpicker.c +++ b/src/lv_objx/lv_cpicker.c @@ -1167,11 +1167,22 @@ static void lv_cpicker_rect_design(lv_obj_t * cpicker, static void lv_cpicker_invalidate(lv_obj_t * cpicker, bool all); -static lv_res_t lv_cpicker_disc_signal(lv_obj_t * cpicker, lv_signal_t sign, void * param, - lv_style_t * style, lv_cpicker_ext_t * ext, - lv_coord_t r_out, lv_coord_t r_in, lv_coord_t x, lv_coord_t y); -static lv_res_t lv_cpicker_rect_signal(lv_obj_t * cpicker, lv_signal_t sign, void * param, - lv_style_t * style, lv_cpicker_ext_t * ext); +static bool lv_cpicker_preview_hit_test(lv_obj_t * cpicker, lv_signal_t sign, lv_indev_t * indev, + lv_cpicker_ext_t * ext); + +static bool lv_cpicker_gradient_hit_test(lv_obj_t * cpicker, lv_signal_t sign, lv_indev_t * indev, + lv_cpicker_ext_t * ext, + float * percent); + +static lv_res_t lv_cpicker_reset_hsv_if_double_clicked(lv_obj_t * cpicker, + lv_cpicker_ext_t * ext); + +static lv_res_t lv_cpicker_set_hsv_percent(lv_obj_t * cpicker, + lv_cpicker_ext_t * ext, + float percent); + +static void lv_cpicker_set_next_color_mode(lv_obj_t * cpicker, + lv_cpicker_ext_t * ext); /** * Signal function of the color_picker @@ -1200,76 +1211,106 @@ static lv_res_t lv_cpicker_signal(lv_obj_t * cpicker, lv_signal_t sign, void * p } buf->type[i] = "lv_cpicker"; } - else + else if(sign == LV_SIGNAL_CONTROL) { lv_cpicker_ext_t * ext = lv_obj_get_ext_attr(cpicker); - if(sign == LV_SIGNAL_CONTROL) + uint32_t c = *((uint32_t *)param); /*uint32_t because can be UTF-8*/ + if(c == LV_KEY_RIGHT || c == LV_KEY_UP) { - uint32_t c = *((uint32_t *)param); /*uint32_t because can be UTF-8*/ - if(c == LV_KEY_RIGHT || c == LV_KEY_UP) + switch(ext->color_mode) { - switch(ext->color_mode) - { - case LV_CPICKER_COLOR_MODE_HUE: - ext->hsv.h = (ext->hsv.h + 1) % 360; - break; - case LV_CPICKER_COLOR_MODE_SATURATION: - ext->hsv.s = (ext->hsv.s + 1) % 100; - break; - case LV_CPICKER_COLOR_MODE_VALUE: - ext->hsv.v = (ext->hsv.v + 1) % 100; - break; - } - - lv_cpicker_invalidate(cpicker, false); - - res = lv_event_send(cpicker, LV_EVENT_VALUE_CHANGED, NULL); - if(res != LV_RES_OK) return res; + case LV_CPICKER_COLOR_MODE_HUE: + ext->hsv.h = (ext->hsv.h + 1) % 360; + break; + case LV_CPICKER_COLOR_MODE_SATURATION: + ext->hsv.s = (ext->hsv.s + 1) % 100; + break; + case LV_CPICKER_COLOR_MODE_VALUE: + ext->hsv.v = (ext->hsv.v + 1) % 100; + break; } - else if(c == LV_KEY_LEFT || c == LV_KEY_DOWN) - { - switch(ext->color_mode) - { - case LV_CPICKER_COLOR_MODE_HUE: - ext->hsv.h = ext->hsv.h > 0?(ext->hsv.h - 1):360; - break; - case LV_CPICKER_COLOR_MODE_SATURATION: - ext->hsv.s = ext->hsv.s > 0?(ext->hsv.s - 1):100; - break; - case LV_CPICKER_COLOR_MODE_VALUE: - ext->hsv.v = ext->hsv.v > 0?(ext->hsv.v - 1):100; - break; - } - lv_cpicker_invalidate(cpicker, false); - - res = lv_event_send(cpicker, LV_EVENT_VALUE_CHANGED, NULL); - if(res != LV_RES_OK) return res; - } - } - else if(sign == LV_SIGNAL_PRESS_LOST) - { - ext->prev_hsv = ext->hsv; lv_cpicker_invalidate(cpicker, false); - } - else - { - lv_style_t * style = lv_cpicker_get_style(cpicker, LV_CPICKER_STYLE_MAIN); - if(ext->type == LV_CPICKER_TYPE_DISC) + res = lv_event_send(cpicker, LV_EVENT_VALUE_CHANGED, NULL); + if(res != LV_RES_OK) return res; + } + else if(c == LV_KEY_LEFT || c == LV_KEY_DOWN) + { + switch(ext->color_mode) { - lv_coord_t r_out = (LV_MATH_MIN(lv_obj_get_width(cpicker), lv_obj_get_height(cpicker))) / 2; - lv_coord_t r_in = r_out - style->line.width - style->body.padding.inner; - lv_coord_t x = cpicker->coords.x1 + lv_obj_get_width(cpicker) / 2; - lv_coord_t y = cpicker->coords.y1 + lv_obj_get_height(cpicker) / 2; - res = lv_cpicker_disc_signal(cpicker, sign, param, style, ext, r_out, r_in, x, y); - if(res != LV_RES_OK) return res; + case LV_CPICKER_COLOR_MODE_HUE: + ext->hsv.h = ext->hsv.h > 0?(ext->hsv.h - 1):360; + break; + case LV_CPICKER_COLOR_MODE_SATURATION: + ext->hsv.s = ext->hsv.s > 0?(ext->hsv.s - 1):100; + break; + case LV_CPICKER_COLOR_MODE_VALUE: + ext->hsv.v = ext->hsv.v > 0?(ext->hsv.v - 1):100; + break; } - else if(ext->type == LV_CPICKER_TYPE_RECT) + + lv_cpicker_invalidate(cpicker, false); + + res = lv_event_send(cpicker, LV_EVENT_VALUE_CHANGED, NULL); + if(res != LV_RES_OK) return res; + } + } + else if(sign == LV_SIGNAL_PRESSED) + { + lv_indev_t * indev = param; + lv_cpicker_ext_t * ext = lv_obj_get_ext_attr(cpicker); + + ext->prev_hsv = ext->hsv; + + if(lv_cpicker_preview_hit_test(cpicker, sign, indev, ext)) + { + res = lv_cpicker_reset_hsv_if_double_clicked(cpicker, ext); + if(res != LV_RES_OK) return res; + } + } + else if(sign == LV_SIGNAL_PRESSING) + { + lv_indev_t * indev = param; + lv_cpicker_ext_t * ext = lv_obj_get_ext_attr(cpicker); + + float percent; + if(lv_cpicker_gradient_hit_test(cpicker, sign, indev, ext, &percent)) + { + res = lv_cpicker_set_hsv_percent(cpicker, ext, percent); + if(res != LV_RES_OK) return res; + } + } + else if(sign == LV_SIGNAL_PRESS_LOST) + { + lv_cpicker_ext_t * ext = lv_obj_get_ext_attr(cpicker); + + ext->prev_hsv = ext->hsv; + lv_cpicker_invalidate(cpicker, false); + } + else if(sign == LV_SIGNAL_RELEASED) + { + lv_indev_t * indev = param; + lv_cpicker_ext_t * ext = lv_obj_get_ext_attr(cpicker); + + float percent; + if(lv_cpicker_gradient_hit_test(cpicker, sign, indev, ext, &percent)) + { + res = lv_cpicker_set_hsv_percent(cpicker, ext, percent); + if(res != LV_RES_OK) return res; + } + } + else if(sign == LV_SIGNAL_LONG_PRESS) + { + lv_indev_t * indev = param; + lv_cpicker_ext_t * ext = lv_obj_get_ext_attr(cpicker); + + if(!ext->color_mode_fixed) + { + if(lv_cpicker_preview_hit_test(cpicker, sign, indev, ext)) { - res = lv_cpicker_rect_signal(cpicker, sign, param, style, ext); - if(res != LV_RES_OK) return res; + lv_cpicker_set_next_color_mode(cpicker, ext); } } } @@ -1277,6 +1318,69 @@ static lv_res_t lv_cpicker_signal(lv_obj_t * cpicker, lv_signal_t sign, void * p return res; } +static bool lv_cpicker_preview_hit_test(lv_obj_t * cpicker, lv_signal_t sign, lv_indev_t * indev, + lv_cpicker_ext_t * ext) +{ + bool hit = false; + if(ext->type == LV_CPICKER_TYPE_DISC) + { + lv_coord_t w = lv_obj_get_width(cpicker); + lv_coord_t h = lv_obj_get_height(cpicker); + lv_style_t * style = lv_cpicker_get_style(cpicker, LV_CPICKER_STYLE_MAIN); + lv_coord_t r_out = (LV_MATH_MIN(w, h)) / 2; + lv_coord_t r_in = r_out - style->line.width - style->body.padding.inner; + lv_point_t center; + center.x = cpicker->coords.x1 + w / 2; + center.y = cpicker->coords.y1 + h / 2; + lv_coord_t xp = indev->proc.types.pointer.act_point.x - center.x; + lv_coord_t yp = indev->proc.types.pointer.act_point.y - center.y; + + hit = (xp*xp + yp*yp) < (r_in*r_in); + } + else if(ext->type == LV_CPICKER_TYPE_RECT) + { + hit = lv_area_is_point_on(&(ext->rect_preview_area), &indev->proc.types.pointer.act_point); + } + return hit; +} + +static bool lv_cpicker_gradient_hit_test(lv_obj_t * cpicker, lv_signal_t sign, lv_indev_t * indev, + lv_cpicker_ext_t * ext, + float * percent) +{ + bool hit; + if(ext->type == LV_CPICKER_TYPE_DISC) + { + lv_coord_t w = lv_obj_get_width(cpicker); + lv_coord_t h = lv_obj_get_height(cpicker); + lv_style_t * style = lv_cpicker_get_style(cpicker, LV_CPICKER_STYLE_MAIN); + lv_coord_t r_out = (LV_MATH_MIN(w, h)) / 2; + lv_coord_t r_in = r_out - style->line.width - style->body.padding.inner; + lv_point_t center; + center.x = cpicker->coords.x1 + w / 2; + center.y = cpicker->coords.y1 + h / 2; + lv_coord_t xp = indev->proc.types.pointer.act_point.x - center.x; + lv_coord_t yp = indev->proc.types.pointer.act_point.y - center.y; + + hit = (xp*xp + yp*yp) < (r_out*r_out) && (xp*xp + yp*yp) >= (r_in*r_in); + if (hit) + { + *percent = lv_atan2(xp, yp) / 360.0; + } + } + else if(ext->type == LV_CPICKER_TYPE_RECT) + { + hit = lv_area_is_point_on(&(ext->rect_gradient_area), &indev->proc.types.pointer.act_point); + if (hit) + { + uint16_t width = ext->rect_gradient_area.x2 - ext->rect_gradient_area.x1; + uint16_t distance = indev->proc.types.pointer.act_point.x - ext->rect_gradient_area.x1; + *percent = distance / (float) width; + } + } + return hit; +} + static lv_res_t lv_cpicker_reset_hsv_if_double_clicked(lv_obj_t * cpicker, lv_cpicker_ext_t * ext) { @@ -1379,133 +1483,6 @@ static lv_res_t lv_cpicker_set_hsv_percent(lv_obj_t * cpicker, return res; } -static lv_res_t lv_cpicker_disc_signal(lv_obj_t * cpicker, lv_signal_t sign, void * param, - lv_style_t * style, lv_cpicker_ext_t * ext, - lv_coord_t r_out, lv_coord_t r_in, lv_coord_t x, lv_coord_t y) -{ - lv_res_t res; - - if(sign == LV_SIGNAL_PRESSED) - { - ext->prev_hsv = ext->hsv; - - lv_indev_t * indev = param; - - lv_coord_t xp = indev->proc.types.pointer.act_point.x - x; - lv_coord_t yp = indev->proc.types.pointer.act_point.y - y; - if((xp*xp + yp*yp) < (r_in*r_in)) - { - res = lv_cpicker_reset_hsv_if_double_clicked(cpicker, ext); - if(res != LV_RES_OK) return res; - } - } - else if(sign == LV_SIGNAL_PRESSING) - { - lv_indev_t * indev = param; - - lv_coord_t xp = indev->proc.types.pointer.act_point.x - x; - lv_coord_t yp = indev->proc.types.pointer.act_point.y - y; - if((xp*xp + yp*yp) < (r_out*r_out) && (xp*xp + yp*yp) >= (r_in*r_in)) - { - float percent = lv_atan2(xp, yp) / 360.0; - - res = lv_cpicker_set_hsv_percent(cpicker, ext, percent); - if(res != LV_RES_OK) return res; - } - } - else if(sign == LV_SIGNAL_RELEASED) - { - lv_indev_t * indev = param; - - lv_coord_t xp = indev->proc.types.pointer.act_point.x - x; - lv_coord_t yp = indev->proc.types.pointer.act_point.y - y; - if((xp*xp + yp*yp) < (r_out*r_out) && (xp*xp + yp*yp) >= (r_in*r_in)) - { - float percent = lv_atan2(xp, yp) / 360.0; - - res = lv_cpicker_set_hsv_percent(cpicker, ext, percent); - if(res != LV_RES_OK) return res; - } - } - else if(sign == LV_SIGNAL_LONG_PRESS) - { - if(!ext->color_mode_fixed) - { - lv_indev_t * indev = param; - - lv_coord_t xp = indev->proc.types.pointer.act_point.x - x; - lv_coord_t yp = indev->proc.types.pointer.act_point.y - y; - if((xp*xp + yp*yp) < (r_in*r_in)) - { - lv_cpicker_set_next_color_mode(cpicker, ext); - } - } - } - - return res; -} - -static lv_res_t lv_cpicker_rect_signal(lv_obj_t * cpicker, lv_signal_t sign, void * param, - lv_style_t * style, lv_cpicker_ext_t * ext) -{ - lv_res_t res; - - if(sign == LV_SIGNAL_PRESSED) - { - ext->prev_hsv = ext->hsv; - - lv_indev_t * indev = param; - - if(lv_area_is_point_on(&(ext->rect_preview_area), &indev->proc.types.pointer.act_point)) - { - res = lv_cpicker_reset_hsv_if_double_clicked(cpicker, ext); - if(res != LV_RES_OK) return res; - } - } - else if(sign == LV_SIGNAL_PRESSING) - { - lv_indev_t * indev = param; - - if(lv_area_is_point_on(&(ext->rect_gradient_area), &indev->proc.types.pointer.act_point)) - { - uint16_t width = ext->rect_gradient_area.x2 - ext->rect_gradient_area.x1; - uint16_t distance = indev->proc.types.pointer.act_point.x - ext->rect_gradient_area.x1; - float percent = distance / (float) width; - - res = lv_cpicker_set_hsv_percent(cpicker, ext, percent); - if(res != LV_RES_OK) return res; - } - } - else if(sign == LV_SIGNAL_RELEASED) - { - lv_indev_t * indev = param; - - if(lv_area_is_point_on(&(ext->rect_gradient_area), &indev->proc.types.pointer.act_point)) - { - uint16_t width = ext->rect_gradient_area.x2 - ext->rect_gradient_area.x1; - uint16_t distance = indev->proc.types.pointer.act_point.x - ext->rect_gradient_area.x1; - float percent = distance / (float) width; - - res = lv_cpicker_set_hsv_percent(cpicker, ext, percent); - if(res != LV_RES_OK) return res; - } - } - else if(sign == LV_SIGNAL_LONG_PRESS) - { - if(!ext->color_mode_fixed) - { - lv_indev_t * indev = param; - - if(lv_area_is_point_on(&(ext->rect_preview_area), &indev->proc.types.pointer.act_point)) - { - lv_cpicker_set_next_color_mode(cpicker, ext); - } - } - } - - return res; -} - static void lv_cpicker_invalidate_disc(lv_disp_t * disp, lv_style_t * style, lv_cpicker_ext_t * ext, From af7b2857eeefc4f7ff039d5d80548051c039e559 Mon Sep 17 00:00:00 2001 From: Paul Peavyhouse Date: Mon, 30 Sep 2019 15:51:18 -0700 Subject: [PATCH 29/82] Moving a method --- src/lv_objx/lv_cpicker.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/lv_objx/lv_cpicker.c b/src/lv_objx/lv_cpicker.c index 7250f7689..a99ea6ac4 100644 --- a/src/lv_objx/lv_cpicker.c +++ b/src/lv_objx/lv_cpicker.c @@ -1427,14 +1427,6 @@ static lv_res_t lv_cpicker_reset_hsv_if_double_clicked(lv_obj_t * cpicker, return res; } -static void lv_cpicker_set_next_color_mode(lv_obj_t * cpicker, - lv_cpicker_ext_t * ext) -{ - ext->prev_hsv = ext->hsv; - ext->color_mode = (ext->color_mode + 1) % 3; - lv_cpicker_invalidate(cpicker, true); -} - static lv_res_t lv_cpicker_set_hsv_percent(lv_obj_t * cpicker, lv_cpicker_ext_t * ext, float percent) @@ -1483,6 +1475,14 @@ static lv_res_t lv_cpicker_set_hsv_percent(lv_obj_t * cpicker, return res; } +static void lv_cpicker_set_next_color_mode(lv_obj_t * cpicker, + lv_cpicker_ext_t * ext) +{ + ext->prev_hsv = ext->hsv; + ext->color_mode = (ext->color_mode + 1) % 3; + lv_cpicker_invalidate(cpicker, true); +} + static void lv_cpicker_invalidate_disc(lv_disp_t * disp, lv_style_t * style, lv_cpicker_ext_t * ext, From 8cb508dfec1e7c2e016cadb23e33d5ea4a2ba54c Mon Sep 17 00:00:00 2001 From: Gabor Kiss-Vamosi Date: Tue, 1 Oct 2019 05:20:20 +0200 Subject: [PATCH 30/82] cpicker minor renames --- src/lv_objx/lv_cpicker.c | 97 ++++++++++++++-------------------------- src/lv_objx/lv_cpicker.h | 57 ++++++++++++----------- 2 files changed, 64 insertions(+), 90 deletions(-) diff --git a/src/lv_objx/lv_cpicker.c b/src/lv_objx/lv_cpicker.c index ad138d126..ec0c727a6 100644 --- a/src/lv_objx/lv_cpicker.c +++ b/src/lv_objx/lv_cpicker.c @@ -72,6 +72,15 @@ static bool lv_cpicker_design(lv_obj_t * cpicker, const lv_area_t * mask, lv_design_mode_t mode); static lv_res_t lv_cpicker_signal(lv_obj_t * cpicker, lv_signal_t sign, void * param); +static void lv_cpicker_disc_design(lv_obj_t * cpicker, + lv_area_t * mask, lv_style_t * style, lv_opa_t opa_scale, + lv_cpicker_ext_t * ext, + lv_coord_t w, lv_coord_t h, + lv_coord_t cx, lv_coord_t cy, uint16_t r); +static void lv_cpicker_rect_design(lv_obj_t * cpicker, + lv_area_t * mask, lv_style_t * style, lv_opa_t opa_scale, + lv_cpicker_ext_t * ext, + lv_coord_t w, lv_coord_t h); /********************** * STATIC VARIABLES **********************/ @@ -115,7 +124,7 @@ lv_obj_t * lv_cpicker_create(lv_obj_t * par, const lv_obj_t * copy) ext->indicator.type = LV_CPICKER_DEF_INDICATOR_TYPE; ext->color_mode = LV_CPICKER_COLOR_MODE_HUE; ext->color_mode_fixed = 0; - ext->last_click = 0; + ext->last_click_time = 0; /*The signal and design functions are not copied so set them here*/ lv_obj_set_signal_cb(new_cpicker, lv_cpicker_signal); @@ -408,15 +417,6 @@ lv_color_t lv_cpicker_get_color(lv_obj_t * cpicker) * STATIC FUNCTIONS **********************/ -static void lv_cpicker_disc_design(lv_obj_t * cpicker, - lv_area_t * mask, lv_style_t * style, lv_opa_t opa_scale, - lv_cpicker_ext_t * ext, - lv_coord_t w, lv_coord_t h, - lv_coord_t cx, lv_coord_t cy, uint16_t r); -static void lv_cpicker_rect_design(lv_obj_t * cpicker, - lv_area_t * mask, lv_style_t * style, lv_opa_t opa_scale, - lv_cpicker_ext_t * ext, - lv_coord_t w, lv_coord_t h); /** * Handle the drawing related tasks of the color_picker @@ -431,13 +431,11 @@ static void lv_cpicker_rect_design(lv_obj_t * cpicker, static bool lv_cpicker_design(lv_obj_t * cpicker, const lv_area_t * mask, lv_design_mode_t mode) { /*Return false if the object is not covers the mask_p area*/ - if(mode == LV_DESIGN_COVER_CHK) - { + if(mode == LV_DESIGN_COVER_CHK) { return false; } /*Draw the object*/ - else if(mode == LV_DESIGN_DRAW_MAIN) - { + else if(mode == LV_DESIGN_DRAW_MAIN) { lv_cpicker_ext_t * ext = lv_obj_get_ext_attr(cpicker); lv_style_t * style = lv_cpicker_get_style(cpicker, LV_CPICKER_STYLE_MAIN); @@ -449,21 +447,17 @@ static bool lv_cpicker_design(lv_obj_t * cpicker, const lv_area_t * mask, lv_des lv_coord_t w = lv_obj_get_width(cpicker); lv_coord_t h = lv_obj_get_height(cpicker); - if(ext->type == LV_CPICKER_TYPE_DISC) - { + if(ext->type == LV_CPICKER_TYPE_DISC) { lv_coord_t cx = cpicker->coords.x1 + (w / 2); lv_coord_t cy = cpicker->coords.y1 + (h / 2); uint16_t r = LV_MATH_MIN(w, h) / 2; lv_cpicker_disc_design(cpicker, mask, &styleCopy, opa_scale, ext, w, h, cx, cy, r); - } - else if(ext->type == LV_CPICKER_TYPE_RECT) - { + } else if(ext->type == LV_CPICKER_TYPE_RECT) { lv_cpicker_rect_design(cpicker, mask, &styleCopy, opa_scale, ext, w, h); } } /*Post draw when the children are drawn*/ - else if(mode == LV_DESIGN_DRAW_POST) - { + else if(mode == LV_DESIGN_DRAW_POST) { } return true; @@ -479,10 +473,10 @@ static lv_color_t angle_to_mode_color(lv_cpicker_ext_t * ext, uint16_t angle) color = lv_color_hsv_to_rgb(angle % 360, ext->hsv.s, ext->hsv.v); break; case LV_CPICKER_COLOR_MODE_SATURATION: - color = lv_color_hsv_to_rgb(ext->hsv.h, (angle % 360) / 360.0 * 100.0, ext->hsv.v); + color = lv_color_hsv_to_rgb(ext->hsv.h, ((angle % 360) * 100) / 360, ext->hsv.v); break; case LV_CPICKER_COLOR_MODE_VALUE: - color = lv_color_hsv_to_rgb(ext->hsv.h, ext->hsv.s, (angle % 360) / 360.0 * 100.0); + color = lv_color_hsv_to_rgb(ext->hsv.h, ext->hsv.s, ((angle % 360) * 100) / 360); break; } return color; @@ -498,10 +492,10 @@ static uint16_t mode_color_to_angle(lv_cpicker_ext_t * ext) angle = ext->hsv.h; break; case LV_CPICKER_COLOR_MODE_SATURATION: - angle = ext->hsv.s / 100.0 * 360.0; + angle = (ext->hsv.s / 100) * 360.0; break; case LV_CPICKER_COLOR_MODE_VALUE: - angle = ext->hsv.v / 100.0 * 360.0; + angle = (ext->hsv.v / 100) * 360.0; break; } return angle; @@ -514,13 +508,13 @@ static lv_coord_t lv_cpicker_get_indicator_coord(lv_style_t * style, lv_cpicker_ { default: case LV_CPICKER_COLOR_MODE_HUE: - ind_pos += ext->hsv.h / 360.0 * ext->rect_gradient_w; + ind_pos += (ext->hsv.h * ext->rect_gradient_w) / 360.0; break; case LV_CPICKER_COLOR_MODE_SATURATION: - ind_pos += ext->hsv.s / 100.0 * ext->rect_gradient_w; + ind_pos += (ext->hsv.s * ext->rect_gradient_w) / 100; break; case LV_CPICKER_COLOR_MODE_VALUE: - ind_pos += ext->hsv.v / 100.0 * ext->rect_gradient_w; + ind_pos += (ext->hsv.v * ext->rect_gradient_w) / 100; break; } return ind_pos; @@ -673,12 +667,7 @@ static void lv_cpicker_draw_disc_gradient(lv_area_t * mask, lv_style_t * style, * only a given angular range */ lv_point_t center = {cx, cy}; - if(!lv_area_is_point_on(mask, ¢er) - /* - && (mask->x1 != cpicker->coords.x1 || mask->x2 != cpicker->coords.x2 - || mask->y1 != cpicker->coords.y1 || mask->y2 != cpicker->coords.y2) - */ - ) + if(!lv_area_is_point_on(mask, ¢er)) { /*get angle from center of object to each corners of the area*/ int16_t dr, ur, ul, dl; @@ -688,12 +677,12 @@ static void lv_cpicker_draw_disc_gradient(lv_area_t * mask, lv_style_t * style, dl = lv_atan2(mask->x1 - cx, mask->y2 - cy); /*check area position from object axis*/ - uint8_t left = (mask->x2 < cx && mask->x1 < cx); - uint8_t onYaxis = (mask->x2 > cx && mask->x1 < cx); - uint8_t right = (mask->x2 > cx && mask->x1 > cx); - uint8_t top = (mask->y2 < cy && mask->y1 < cy); - uint8_t onXaxis = (mask->y2 > cy && mask->y1 < cy); - uint8_t bottom = (mask->y2 > cy && mask->y1 > cy); + bool left = (mask->x2 < cx && mask->x1 < cx) ? true : false; + bool onYaxis = (mask->x2 > cx && mask->x1 < cx) ? true : false; + bool right = (mask->x2 > cx && mask->x1 > cx) ? true : false; + bool top = (mask->y2 < cy && mask->y1 < cy) ? true : false; + bool onXaxis = (mask->y2 > cy && mask->y1 < cy) ? true : false; + bool bottom = (mask->y2 > cy && mask->y1 > cy) ? true : false; /*store angular range*/ if(right && bottom) @@ -744,8 +733,8 @@ static void lv_cpicker_draw_disc_gradient(lv_area_t * mask, lv_style_t * style, } /*round to QF factor*/ - start_angle = start_angle/LV_CPICKER_DEF_QF*LV_CPICKER_DEF_QF; - end_angle = end_angle/LV_CPICKER_DEF_QF*LV_CPICKER_DEF_QF;; + start_angle = (start_angle/LV_CPICKER_DEF_QF) * LV_CPICKER_DEF_QF; + end_angle = (end_angle / LV_CPICKER_DEF_QF) * LV_CPICKER_DEF_QF; /*shift angle if necessary before adding offset*/ if((start_angle - LV_CPICKER_DEF_QF) < 0) @@ -883,7 +872,6 @@ static void lv_cpicker_disc_design(lv_obj_t * cpicker, lv_cpicker_draw_disc_indicator(mask, style, opa_scale, ext, cx, cy, r, rin, radius, center_ind_area); /* - //code to color the drawn area static uint32_t c = 0; lv_style_t style2; lv_style_copy(&style2, &lv_style_plain); @@ -1054,12 +1042,6 @@ static void lv_cpicker_draw_rect_indicator(lv_obj_t * cpicker, } lv_draw_rect(&(ext->rect_preview_area), mask, style, opa_scale); - /* - styleCopy.line.width = 10; - lv_draw_arc(cpicker->coords.x1 + 3*ext->rect_gradient_h/2, cpicker->coords.y1 + ext->rect_gradient_h/2, ext->rect_gradient_h / 2 + styleCopy.line.width + 2, mask, 180, 360, &styleCopy, opa_scale); - //lv_draw_arc(cpicker->coords.x1 + ext->rect_gradient_w - ext->rect_gradient_h/2, cpicker->coords.y1 + ext->rect_gradient_h/2, ext->rect_gradient_h / 2 + styleCopy.line.width + 2, mask, 0, 180, &styleCopy, opa_scale); - */ - /*draw the color position indicator*/ lv_coord_t ind_pos = lv_cpicker_get_indicator_coord(style, ext); /*save to refresh the area later*/ @@ -1282,7 +1264,7 @@ static lv_res_t lv_cpicker_reset_hsv_if_double_clicked(lv_obj_t * cpicker, { bool changed = false; - if(lv_tick_elaps(ext->last_click) < 400) + if(lv_tick_elaps(ext->last_click_time) < 400) { switch(ext->color_mode) { @@ -1310,7 +1292,7 @@ static lv_res_t lv_cpicker_reset_hsv_if_double_clicked(lv_obj_t * cpicker, } ext->prev_hsv = ext->hsv; } - ext->last_click = lv_tick_get(); + ext->last_click_time = lv_tick_get(); lv_res_t res = LV_RES_OK; if (changed) @@ -1569,34 +1551,23 @@ static void lv_cpicker_invalidate_disc_indicator_line(lv_disp_t * disp, lv_style point2.y = y2; lv_area_t line_area; - //if(LV_MATH_ABS(point1.x - point2.x) > LV_MATH_ABS(point1.y - point2.y)) - //{ /*Steps less in y than x -> rather horizontal*/ if(point1.x < point2.x) { line_area.x1 = point1.x; - //line_area.y1 = point1.y; line_area.x2 = point2.x; - //line_area.y2 = point2.y; } else { line_area.x1 = point2.x; - //line_area.y1 = point2.y; line_area.x2 = point1.x; - //line_area.y2 = point1.y; } - //} else { + /*Steps less in x than y -> rather vertical*/ if(point1.y < point2.y) { - //line_area.x1 = point1.x; line_area.y1 = point1.y; - //line_area.x2 = point2.x; line_area.y2 = point2.y; } else { - //line_area.x1 = point2.x; line_area.y1 = point2.y; - //line_area.x2 = point1.x; line_area.y2 = point1.y; } - //} line_area.x1 -= 2*ext->indicator.style->line.width; line_area.y1 -= 2*ext->indicator.style->line.width; diff --git a/src/lv_objx/lv_cpicker.h b/src/lv_objx/lv_cpicker.h index 987800e85..5a542dd02 100644 --- a/src/lv_objx/lv_cpicker.h +++ b/src/lv_objx/lv_cpicker.h @@ -30,33 +30,6 @@ extern "C" { /********************** * TYPEDEFS **********************/ -/*Data of colorpicker*/ -typedef struct { - lv_color_hsv_t hsv; - struct - { - lv_style_t * style; - uint8_t type; - } indicator; - lv_color_hsv_t prev_hsv; - uint16_t prev_pos; - uint8_t color_mode:2; - uint8_t color_mode_fixed:1; - uint8_t type:1; - uint32_t last_click; - lv_area_t rect_preview_area; - lv_area_t rect_gradient_area; - lv_coord_t rect_gradient_w; - lv_coord_t rect_gradient_h; -} lv_cpicker_ext_t; - -/*Styles*/ -enum { - LV_CPICKER_STYLE_MAIN, - LV_CPICKER_STYLE_INDICATOR, -}; -typedef uint8_t lv_cpicker_style_t; - enum { LV_CPICKER_INDICATOR_NONE, LV_CPICKER_INDICATOR_LINE, @@ -78,6 +51,36 @@ enum { }; typedef uint8_t lv_cpicker_color_mode_t; + + +/*Data of colorpicker*/ +typedef struct { + lv_color_hsv_t hsv; + lv_color_hsv_t prev_hsv; + struct + { + lv_style_t * style; + lv_cpicker_indicator_type_t type; + } indicator; + uint32_t last_click_time; + lv_area_t rect_preview_area; + lv_area_t rect_gradient_area; + lv_coord_t rect_gradient_w; + lv_coord_t rect_gradient_h; + uint16_t prev_pos; + lv_cpicker_color_mode_t color_mode:2; + uint8_t color_mode_fixed:1; + lv_cpicker_type_t type:1; +} lv_cpicker_ext_t; + +/*Styles*/ +enum { + LV_CPICKER_STYLE_MAIN, + LV_CPICKER_STYLE_INDICATOR, +}; +typedef uint8_t lv_cpicker_style_t; + + /********************** * GLOBAL PROTOTYPES **********************/ From 2600c1c3d97f0d879b7440d9f1251c6724d450b0 Mon Sep 17 00:00:00 2001 From: Gabor Kiss-Vamosi Date: Tue, 1 Oct 2019 21:16:30 +0200 Subject: [PATCH 31/82] cpicker: rework --- src/lv_objx/lv_cpicker.c | 1891 ++++++++++++-------------------------- src/lv_objx/lv_cpicker.h | 52 +- 2 files changed, 601 insertions(+), 1342 deletions(-) diff --git a/src/lv_objx/lv_cpicker.c b/src/lv_objx/lv_cpicker.c index ec0c727a6..6c97f61a0 100644 --- a/src/lv_objx/lv_cpicker.c +++ b/src/lv_objx/lv_cpicker.c @@ -19,6 +19,8 @@ /********************* * DEFINES *********************/ +#define LV_OBJX_NAME "lv_cpicker" + #ifndef LV_CPICKER_DEF_TYPE #define LV_CPICKER_DEF_TYPE LV_CPICKER_TYPE_DISC #endif @@ -39,28 +41,11 @@ #define LV_CPICKER_DEF_HSV ((lv_color_hsv_t){LV_CPICKER_DEF_HUE, LV_CPICKER_DEF_SATURATION, LV_CPICKER_DEF_VALUE}) #endif -#ifndef LV_CPICKER_DEF_INDICATOR_TYPE -#define LV_CPICKER_DEF_INDICATOR_TYPE LV_CPICKER_INDICATOR_CIRCLE -#endif - #ifndef LV_CPICKER_DEF_QF /*quantization factor*/ #define LV_CPICKER_DEF_QF 3 #endif -/*for rectangular mode the QF can be down to 1*/ -/* -#define LV_CPICKER_MINIMUM_QF 4 -#if LV_CPICKER_DEF_QF < LV_CPICKER_MINIMUM_QF -#undef LV_CPICKER_DEF_QF -#define LV_CPICKER_DEF_QF LV_CPICKER_MINIMUM_QF -#endif - */ - -#ifndef LV_CPICKER_USE_TRI /*Use triangle approximation instead of arc*/ -#define LV_CPICKER_USE_TRI 1 -#endif - -#define TRI_OFFSET 4 +#define TRI_OFFSET 2 /********************** * TYPEDEFS @@ -72,15 +57,17 @@ static bool lv_cpicker_design(lv_obj_t * cpicker, const lv_area_t * mask, lv_design_mode_t mode); static lv_res_t lv_cpicker_signal(lv_obj_t * cpicker, lv_signal_t sign, void * param); -static void lv_cpicker_disc_design(lv_obj_t * cpicker, - lv_area_t * mask, lv_style_t * style, lv_opa_t opa_scale, - lv_cpicker_ext_t * ext, - lv_coord_t w, lv_coord_t h, - lv_coord_t cx, lv_coord_t cy, uint16_t r); -static void lv_cpicker_rect_design(lv_obj_t * cpicker, - lv_area_t * mask, lv_style_t * style, lv_opa_t opa_scale, - lv_cpicker_ext_t * ext, - lv_coord_t w, lv_coord_t h); +static void invalidate_indic(lv_obj_t * cpicker); +static void draw_rect_grad(lv_obj_t * cpicker, const lv_area_t * mask, lv_opa_t opa_scale); +static void draw_disc_grad(lv_obj_t * cpicker, const lv_area_t * mask, lv_opa_t opa_scale); +static void draw_indic(lv_obj_t * cpicker, const lv_area_t * mask, lv_opa_t opa_scale); + +static void next_color_mode(lv_obj_t * cpicker); +static lv_res_t double_click_reset(lv_obj_t * cpicker); +static void refr_indic_pos(lv_obj_t * cpicker); +static lv_color_t angle_to_mode_color(lv_obj_t * cpicker, uint16_t angle); +static uint16_t get_angle(lv_obj_t * cpicker); + /********************** * STATIC VARIABLES **********************/ @@ -119,9 +106,8 @@ lv_obj_t * lv_cpicker_create(lv_obj_t * par, const lv_obj_t * copy) /*Initialize the allocated 'ext' */ ext->hsv = LV_CPICKER_DEF_HSV; - ext->prev_hsv = ext->hsv; - ext->indicator.style = &lv_style_plain; - ext->indicator.type = LV_CPICKER_DEF_INDICATOR_TYPE; + ext->indic.style = &lv_style_plain; + ext->indic.colored = 1; ext->color_mode = LV_CPICKER_COLOR_MODE_HUE; ext->color_mode_fixed = 0; ext->last_click_time = 0; @@ -132,6 +118,8 @@ lv_obj_t * lv_cpicker_create(lv_obj_t * par, const lv_obj_t * copy) /*If no copy do the basic initialization*/ if(copy == NULL) { + lv_obj_set_protect(new_cpicker, LV_PROTECT_PRESS_LOST); + refr_indic_pos(new_cpicker); lv_theme_t * th = lv_theme_get_current(); if(th) { lv_cpicker_set_style(new_cpicker, LV_CPICKER_STYLE_MAIN, th->style.bg); @@ -142,10 +130,17 @@ lv_obj_t * lv_cpicker_create(lv_obj_t * par, const lv_obj_t * copy) /*Copy 'copy'*/ else { lv_cpicker_ext_t * copy_ext = lv_obj_get_ext_attr(copy); + ext->type = copy_ext->type; + ext->color_mode = copy_ext->color_mode; + ext->color_mode_fixed = copy_ext->color_mode_fixed; + ext->hsv = copy_ext->hsv; + ext->indic.colored = copy_ext->indic.colored; + ext->indic.style = copy_ext->indic.style; /*Refresh the style with new signal function*/ lv_obj_refresh_style(new_cpicker); } + refr_indic_pos(new_cpicker); LV_LOG_INFO("color_picker created"); @@ -163,10 +158,14 @@ lv_obj_t * lv_cpicker_create(lv_obj_t * par, const lv_obj_t * copy) */ void lv_cpicker_set_type(lv_obj_t * cpicker, lv_cpicker_type_t type) { + LV_ASSERT_OBJ(cpicker, LV_OBJX_NAME); + lv_cpicker_ext_t * ext = lv_obj_get_ext_attr(cpicker); if(ext->type == type) return; ext->type = type; + lv_obj_refresh_ext_draw_pad(cpicker); + refr_indic_pos(cpicker); lv_obj_invalidate(cpicker); } @@ -179,6 +178,8 @@ void lv_cpicker_set_type(lv_obj_t * cpicker, lv_cpicker_type_t type) */ void lv_cpicker_set_style(lv_obj_t * cpicker, lv_cpicker_style_t type, lv_style_t * style) { + LV_ASSERT_OBJ(cpicker, LV_OBJX_NAME); + lv_cpicker_ext_t * ext = lv_obj_get_ext_attr(cpicker); switch(type) { @@ -186,24 +187,12 @@ void lv_cpicker_set_style(lv_obj_t * cpicker, lv_cpicker_style_t type, lv_style_ lv_obj_set_style(cpicker, style); break; case LV_CPICKER_STYLE_INDICATOR: - ext->indicator.style = style; + ext->indic.style = style; lv_obj_invalidate(cpicker); break; } } -/** - * Set a type of a colorpicker indicator. - * @param cpicker pointer to colorpicker object - * @param type indicator type - */ -void lv_cpicker_set_indicator_type(lv_obj_t * cpicker, lv_cpicker_indicator_type_t type) -{ - lv_cpicker_ext_t * ext = lv_obj_get_ext_attr(cpicker); - ext->indicator.type = type; - lv_obj_invalidate(cpicker); -} - /** * Set the current hue of a colorpicker. * @param cpicker pointer to colorpicker object @@ -211,11 +200,13 @@ void lv_cpicker_set_indicator_type(lv_obj_t * cpicker, lv_cpicker_indicator_type */ void lv_cpicker_set_hue(lv_obj_t * cpicker, uint16_t hue) { + LV_ASSERT_OBJ(cpicker, LV_OBJX_NAME); + lv_cpicker_ext_t * ext = lv_obj_get_ext_attr(cpicker); ext->hsv.h = hue % 360; - lv_obj_invalidate(cpicker); + if(ext->color_mode_fixed == LV_CPICKER_COLOR_MODE_HUE) refr_indic_pos(cpicker); } /** @@ -225,11 +216,13 @@ void lv_cpicker_set_hue(lv_obj_t * cpicker, uint16_t hue) */ void lv_cpicker_set_saturation(lv_obj_t * cpicker, uint8_t saturation) { + LV_ASSERT_OBJ(cpicker, LV_OBJX_NAME); + lv_cpicker_ext_t * ext = lv_obj_get_ext_attr(cpicker); ext->hsv.s = saturation % 100; - lv_obj_invalidate(cpicker); + if(ext->color_mode_fixed == LV_CPICKER_COLOR_MODE_SATURATION) refr_indic_pos(cpicker); } /** @@ -239,11 +232,13 @@ void lv_cpicker_set_saturation(lv_obj_t * cpicker, uint8_t saturation) */ void lv_cpicker_set_value(lv_obj_t * cpicker, uint8_t val) { + LV_ASSERT_OBJ(cpicker, LV_OBJX_NAME); + lv_cpicker_ext_t * ext = lv_obj_get_ext_attr(cpicker); ext->hsv.v = val % 100; - lv_obj_invalidate(cpicker); + if(ext->color_mode_fixed == LV_CPICKER_COLOR_MODE_VALUE) refr_indic_pos(cpicker); } /** @@ -253,10 +248,13 @@ void lv_cpicker_set_value(lv_obj_t * cpicker, uint8_t val) */ void lv_cpicker_set_hsv(lv_obj_t * cpicker, lv_color_hsv_t hsv) { + LV_ASSERT_OBJ(cpicker, LV_OBJX_NAME); + lv_cpicker_ext_t * ext = lv_obj_get_ext_attr(cpicker); ext->hsv = hsv; + refr_indic_pos(cpicker); lv_obj_invalidate(cpicker); } @@ -267,6 +265,8 @@ void lv_cpicker_set_hsv(lv_obj_t * cpicker, lv_color_hsv_t hsv) */ void lv_cpicker_set_color(lv_obj_t * cpicker, lv_color_t color) { + LV_ASSERT_OBJ(cpicker, LV_OBJX_NAME); + lv_cpicker_set_hsv(cpicker, lv_color_rgb_to_hsv(color.ch.red, color.ch.green, color.ch.blue)); } @@ -277,9 +277,13 @@ void lv_cpicker_set_color(lv_obj_t * cpicker, lv_color_t color) */ void lv_cpicker_set_color_mode(lv_obj_t * cpicker, lv_cpicker_color_mode_t mode) { + LV_ASSERT_OBJ(cpicker, LV_OBJX_NAME); + lv_cpicker_ext_t * ext = lv_obj_get_ext_attr(cpicker); ext->color_mode = mode; + refr_indic_pos(cpicker); + lv_obj_invalidate(cpicker); } /** @@ -289,11 +293,27 @@ void lv_cpicker_set_color_mode(lv_obj_t * cpicker, lv_cpicker_color_mode_t mode) */ void lv_cpicker_set_color_mode_fixed(lv_obj_t * cpicker, bool fixed) { + LV_ASSERT_OBJ(cpicker, LV_OBJX_NAME); + lv_cpicker_ext_t * ext = lv_obj_get_ext_attr(cpicker); ext->color_mode_fixed = fixed; } +/** + * Make the indicator to be colored to the current color + * @param cpicker pointer to colorpicker object + * @param en true: color the indicator; false: not color the indicator + */ +void lv_cpicker_set_indic_colored(lv_obj_t * cpicker, bool en) +{ + LV_ASSERT_OBJ(cpicker, LV_OBJX_NAME); + + lv_cpicker_ext_t * ext = lv_obj_get_ext_attr(cpicker); + ext->indic.colored = en ? 1 : 0; + invalidate_indic(cpicker); +} + /*===================== * Getter functions *====================*/ @@ -305,6 +325,8 @@ void lv_cpicker_set_color_mode_fixed(lv_obj_t * cpicker, bool fixed) */ lv_cpicker_color_mode_t lv_cpicker_get_color_mode(lv_obj_t * cpicker) { + LV_ASSERT_OBJ(cpicker, LV_OBJX_NAME); + lv_cpicker_ext_t * ext = lv_obj_get_ext_attr(cpicker); return ext->color_mode; @@ -317,6 +339,8 @@ lv_cpicker_color_mode_t lv_cpicker_get_color_mode(lv_obj_t * cpicker) */ bool lv_cpicker_get_color_mode_fixed(lv_obj_t * cpicker) { + LV_ASSERT_OBJ(cpicker, LV_OBJX_NAME); + lv_cpicker_ext_t * ext = lv_obj_get_ext_attr(cpicker); return ext->color_mode_fixed; @@ -328,15 +352,17 @@ bool lv_cpicker_get_color_mode_fixed(lv_obj_t * cpicker) * @param type which style should be get * @return style pointer to the style */ -lv_style_t * lv_cpicker_get_style(const lv_obj_t * cpicker, lv_cpicker_style_t type) +const lv_style_t * lv_cpicker_get_style(const lv_obj_t * cpicker, lv_cpicker_style_t type) { + LV_ASSERT_OBJ(cpicker, LV_OBJX_NAME); + lv_cpicker_ext_t * ext = lv_obj_get_ext_attr(cpicker); switch(type) { case LV_CPICKER_STYLE_MAIN: return lv_obj_get_style(cpicker); case LV_CPICKER_STYLE_INDICATOR: - return ext->indicator.style; + return ext->indic.style; default: return NULL; } @@ -352,6 +378,8 @@ lv_style_t * lv_cpicker_get_style(const lv_obj_t * cpicker, lv_cpicker_style_t t */ uint16_t lv_cpicker_get_hue(lv_obj_t * cpicker) { + LV_ASSERT_OBJ(cpicker, LV_OBJX_NAME); + lv_cpicker_ext_t * ext = lv_obj_get_ext_attr(cpicker); return ext->hsv.h; @@ -364,6 +392,8 @@ uint16_t lv_cpicker_get_hue(lv_obj_t * cpicker) */ uint8_t lv_cpicker_get_saturation(lv_obj_t * cpicker) { + LV_ASSERT_OBJ(cpicker, LV_OBJX_NAME); + lv_cpicker_ext_t * ext = lv_obj_get_ext_attr(cpicker); return ext->hsv.s; @@ -376,6 +406,8 @@ uint8_t lv_cpicker_get_saturation(lv_obj_t * cpicker) */ uint8_t lv_cpicker_get_value(lv_obj_t * cpicker) { + LV_ASSERT_OBJ(cpicker, LV_OBJX_NAME); + lv_cpicker_ext_t * ext = lv_obj_get_ext_attr(cpicker); return ext->hsv.v; @@ -388,6 +420,8 @@ uint8_t lv_cpicker_get_value(lv_obj_t * cpicker) */ lv_color_hsv_t lv_cpicker_get_hsv(lv_obj_t * cpicker) { + LV_ASSERT_OBJ(cpicker, LV_OBJX_NAME); + lv_cpicker_ext_t * ext = lv_obj_get_ext_attr(cpicker); return ext->hsv; @@ -400,19 +434,31 @@ lv_color_hsv_t lv_cpicker_get_hsv(lv_obj_t * cpicker) */ lv_color_t lv_cpicker_get_color(lv_obj_t * cpicker) { + LV_ASSERT_OBJ(cpicker, LV_OBJX_NAME); + lv_cpicker_ext_t * ext = lv_obj_get_ext_attr(cpicker); return lv_color_hsv_to_rgb(ext->hsv.h, ext->hsv.s, ext->hsv.v); } +/** + * Whether the indicator is colored to the current color or not + * @param cpicker pointer to colorpicker object + * @return true: color the indicator; false: not color the indicator + */ +bool lv_cpicker_get_indic_colored(lv_obj_t * cpicker) +{ + LV_ASSERT_OBJ(cpicker, LV_OBJX_NAME); + + lv_cpicker_ext_t * ext = lv_obj_get_ext_attr(cpicker); + + return ext->indic.colored ? true : false; +} + /*===================== * Other functions *====================*/ -/* - * New object specific "other" functions come here - */ - /********************** * STATIC FUNCTIONS **********************/ @@ -437,24 +483,15 @@ static bool lv_cpicker_design(lv_obj_t * cpicker, const lv_area_t * mask, lv_des /*Draw the object*/ else if(mode == LV_DESIGN_DRAW_MAIN) { lv_cpicker_ext_t * ext = lv_obj_get_ext_attr(cpicker); - lv_style_t * style = lv_cpicker_get_style(cpicker, LV_CPICKER_STYLE_MAIN); - - static lv_style_t styleCopy; - lv_style_copy(&styleCopy, style); - lv_opa_t opa_scale = lv_obj_get_opa_scale(cpicker); - lv_coord_t w = lv_obj_get_width(cpicker); - lv_coord_t h = lv_obj_get_height(cpicker); - if(ext->type == LV_CPICKER_TYPE_DISC) { - lv_coord_t cx = cpicker->coords.x1 + (w / 2); - lv_coord_t cy = cpicker->coords.y1 + (h / 2); - uint16_t r = LV_MATH_MIN(w, h) / 2; - lv_cpicker_disc_design(cpicker, mask, &styleCopy, opa_scale, ext, w, h, cx, cy, r); + draw_disc_grad(cpicker, mask, opa_scale); } else if(ext->type == LV_CPICKER_TYPE_RECT) { - lv_cpicker_rect_design(cpicker, mask, &styleCopy, opa_scale, ext, w, h); + draw_rect_grad(cpicker, mask, opa_scale); } + + draw_indic(cpicker, mask, opa_scale); } /*Post draw when the children are drawn*/ else if(mode == LV_DESIGN_DRAW_POST) { @@ -463,8 +500,478 @@ static bool lv_cpicker_design(lv_obj_t * cpicker, const lv_area_t * mask, lv_des return true; } -static lv_color_t angle_to_mode_color(lv_cpicker_ext_t * ext, uint16_t angle) +static void draw_disc_grad(lv_obj_t * cpicker, const lv_area_t * mask, lv_opa_t opa_scale) { + int16_t start_angle = 0; /*Default*/ + int16_t end_angle = 360 - LV_CPICKER_DEF_QF; /*Default*/ + + lv_coord_t w = lv_obj_get_width(cpicker); + lv_coord_t h = lv_obj_get_height(cpicker); + lv_coord_t cx = cpicker->coords.x1 + w / 2; + lv_coord_t cy = cpicker->coords.y1 + h / 2; + lv_coord_t r = w / 2; + + /*if the mask does not include the center of the object + * redrawing all the wheel is not necessary; + * only a given angular range + */ + lv_point_t center = {cx, cy}; + if(!lv_area_is_point_on(mask, ¢er)) + { + /*get angle from center of object to each corners of the area*/ + int16_t dr, ur, ul, dl; + dr = lv_atan2(mask->x2 - cx, mask->y2 - cy); + ur = lv_atan2(mask->x2 - cx, mask->y1 - cy); + ul = lv_atan2(mask->x1 - cx, mask->y1 - cy); + dl = lv_atan2(mask->x1 - cx, mask->y2 - cy); + + /*check area position from object axis*/ + bool left = (mask->x2 < cx && mask->x1 < cx) ? true : false; + bool onYaxis = (mask->x2 > cx && mask->x1 < cx) ? true : false; + bool right = (mask->x2 > cx && mask->x1 > cx) ? true : false; + bool top = (mask->y2 < cy && mask->y1 < cy) ? true : false; + bool onXaxis = (mask->y2 > cy && mask->y1 < cy) ? true : false; + bool bottom = (mask->y2 > cy && mask->y1 > cy) ? true : false; + + /*store angular range*/ + if(right && bottom) { + start_angle = dl; + end_angle = ur; + } + else if(right && onXaxis) { + start_angle = dl; + end_angle = ul; + } + else if(right && top) { + start_angle = dr; + end_angle = ul; + } + else if(onYaxis && top) { + start_angle = dr; + end_angle = dl; + } + else if(left && top) { + start_angle = ur; + end_angle = dl; + } + else if(left && onXaxis) { + start_angle = ur; + end_angle = dr; + } + else if(left && bottom) { + start_angle = ul; + end_angle = dr; + } + else if(onYaxis && bottom) { + start_angle = ul; + end_angle = ur; + } + + /*rollover angle*/ + if(start_angle > end_angle) end_angle += 360; + + /*round to QF factor*/ + start_angle = (start_angle/LV_CPICKER_DEF_QF) * LV_CPICKER_DEF_QF; + end_angle = (end_angle / LV_CPICKER_DEF_QF) * LV_CPICKER_DEF_QF; + + /*shift angle if necessary before adding offset*/ + if((start_angle - LV_CPICKER_DEF_QF) < 0) + { + start_angle += 360; + end_angle += 360; + } + + /*ensure overlapping by adding offset*/ + start_angle -= LV_CPICKER_DEF_QF; + end_angle += LV_CPICKER_DEF_QF; + } + + lv_point_t triangle_points[3]; + lv_style_t style; + lv_style_copy(&style, &lv_style_plain); + for(uint16_t i = start_angle; i <= end_angle; i+= LV_CPICKER_DEF_QF) + { + style.body.main_color = angle_to_mode_color(cpicker, i); + style.body.grad_color = style.body.main_color; + + triangle_points[0].x = cx; + triangle_points[0].y = cy; + + triangle_points[1].x = cx + (r * lv_trigo_sin(i) >> LV_TRIGO_SHIFT); + triangle_points[1].y = cy + (r * lv_trigo_sin(i + 90) >> LV_TRIGO_SHIFT); + + if(i == end_angle || i == (360 - LV_CPICKER_DEF_QF)) { + /*the last triangle is drawn without additional overlapping pixels*/ + triangle_points[2].x = cx + (r * lv_trigo_sin(i + LV_CPICKER_DEF_QF) >> LV_TRIGO_SHIFT); + triangle_points[2].y = cy + (r * lv_trigo_sin(i + LV_CPICKER_DEF_QF + 90) >> LV_TRIGO_SHIFT); + } + else { + triangle_points[2].x = cx + (r * lv_trigo_sin(i + LV_CPICKER_DEF_QF + TRI_OFFSET) >> LV_TRIGO_SHIFT); + triangle_points[2].y = cy + (r * lv_trigo_sin(i + LV_CPICKER_DEF_QF + TRI_OFFSET + 90) >> LV_TRIGO_SHIFT); + } + + lv_draw_triangle(triangle_points, mask, &style, LV_OPA_COVER); + } + + /*Mask out the center area*/ + const lv_style_t * style_main = lv_cpicker_get_style(cpicker, LV_CPICKER_STYLE_MAIN); + lv_style_copy(&style, style_main); + style.body.radius = LV_RADIUS_CIRCLE; + lv_area_t area_mid; + lv_area_copy(&area_mid, &cpicker->coords); + area_mid.x1 += style_main->line.width; + area_mid.y1 += style_main->line.width; + area_mid.x2 -= style_main->line.width; + area_mid.y2 -= style_main->line.width; + + lv_draw_rect(&area_mid, mask, &style, opa_scale); +} + +static void draw_rect_grad(lv_obj_t * cpicker, const lv_area_t * mask, lv_opa_t opa_scale) +{ + lv_style_t style; + lv_style_copy(&style, lv_cpicker_get_style(cpicker, LV_CPICKER_STYLE_MAIN)); + + lv_area_t grad_area; + lv_obj_get_coords(cpicker, &grad_area); + + if(style.body.radius) { + lv_coord_t h = lv_obj_get_height(cpicker); + lv_coord_t r = style.body.radius; + if(r > h / 2) r = h / 2; + /*Make the gradient area smaller with a half circle on both ends*/ + grad_area.x1 += r; + grad_area.x2 -= r; + + /*Draw the left rounded end*/ + lv_area_t rounded_edge_area; + lv_obj_get_coords(cpicker, &rounded_edge_area); + rounded_edge_area.x2 = rounded_edge_area.x1 + 2 * r; + + style.body.main_color = angle_to_mode_color(cpicker, 0); + style.body.grad_color = style.body.main_color; + + lv_draw_rect(&rounded_edge_area, mask, &style, opa_scale); + + /*Draw the right rounded end*/ + lv_obj_get_coords(cpicker, &rounded_edge_area); + rounded_edge_area.x1 = rounded_edge_area.x2 - 2 * r; + + style.body.main_color = angle_to_mode_color(cpicker, 359); + style.body.grad_color = style.body.main_color; + + lv_draw_rect(&rounded_edge_area, mask, &style, opa_scale); + } + + lv_coord_t grad_w = lv_area_get_width(&grad_area); + uint16_t i_step = LV_MATH_MAX(LV_CPICKER_DEF_QF, 360 / grad_w); + style.body.radius = 0; + style.body.border.width = 0; + style.body.shadow.width = 0; + style.body.opa = LV_OPA_COVER; + + for(uint16_t i = 0; i < 360; i += i_step) { + style.body.main_color = angle_to_mode_color(cpicker, i); + style.body.grad_color = style.body.main_color; + + /*the following attribute might need changing between index to add border, shadow, radius etc*/ + lv_area_t rect_area; + + /*scale angle (hue/sat/val) to linear coordinate*/ + lv_coord_t xi = (i * grad_w) / 360; + + rect_area.x1 = LV_MATH_MIN(grad_area.x1 + xi, grad_area.x1 + grad_w - i_step); + rect_area.y1 = grad_area.y1; + rect_area.x2 = rect_area.x1 + i_step; + rect_area.y2 = grad_area.y2; + + lv_draw_rect(&rect_area, mask, &style, opa_scale); + } +} +/** + * Should roughly match up with `lv_cpicker_invalidate_disc_indicator_circle` + */ +static void draw_indic(lv_obj_t * cpicker, const lv_area_t * mask, lv_opa_t opa_scale) +{ + lv_cpicker_ext_t * ext = lv_obj_get_ext_attr(cpicker); + const lv_style_t * style_main = lv_cpicker_get_style(cpicker, LV_CPICKER_STYLE_MAIN); + const lv_style_t * style_indic = lv_cpicker_get_style(cpicker, LV_CPICKER_STYLE_INDICATOR); + + lv_coord_t h = lv_obj_get_height(cpicker); + uint16_t r; + if(ext->type == LV_CPICKER_TYPE_DISC) r = style_main->line.width / 2; + else if(ext->type == LV_CPICKER_TYPE_RECT) r = h / 2; + + lv_area_t ind_area; + ind_area.x1 = cpicker->coords.x1 + ext->indic.pos.x - r - style_indic->body.padding.left; + ind_area.y1 = cpicker->coords.y1 + ext->indic.pos.y - r - style_indic->body.padding.right; + ind_area.x2 = cpicker->coords.x1 + ext->indic.pos.x + r + style_indic->body.padding.top; + ind_area.y2 = cpicker->coords.y1 + ext->indic.pos.y + r + style_indic->body.padding.bottom; + + lv_style_t style_cir; + lv_style_copy(&style_cir, ext->indic.style); + style_cir.body.radius = LV_RADIUS_CIRCLE; + + if(ext->indic.colored) { + style_cir.body.main_color = lv_cpicker_get_color(cpicker); + style_cir.body.grad_color = style_cir.body.main_color; + } + + + lv_draw_rect(&ind_area, mask, &style_cir, opa_scale); +} + +/** + * Signal function of the color_picker + * @param cpicker pointer to a color_picker object + * @param sign a signal type from lv_signal_t enum + * @param param pointer to a signal specific variable + * @return LV_RES_OK: the object is not deleted in the function; LV_RES_INV: the object is deleted + */ +static lv_res_t lv_cpicker_signal(lv_obj_t * cpicker, lv_signal_t sign, void * param) +{ + /* Include the ancient signal function */ + lv_res_t res = ancestor_signal(cpicker, sign, param); + if(res != LV_RES_OK) return res; + if(sign == LV_SIGNAL_GET_TYPE) return lv_obj_handle_get_type_signal(param, LV_OBJX_NAME); + + lv_cpicker_ext_t * ext = lv_obj_get_ext_attr(cpicker); + + if(sign == LV_SIGNAL_CLEANUP) { + /*Nothing to cleanup. (No dynamically allocated memory in 'ext')*/ + } else if(sign == LV_SIGNAL_REFR_EXT_DRAW_PAD) { + const lv_style_t * style_indic = lv_cpicker_get_style(cpicker, LV_CPICKER_STYLE_INDICATOR); + lv_coord_t indic_pad = LV_MATH_MAX(style_indic->body.padding.left, style_indic->body.padding.right); + indic_pad = LV_MATH_MAX(indic_pad, style_indic->body.padding.top); + indic_pad = LV_MATH_MAX(indic_pad, style_indic->body.padding.bottom); + + if(ext->type == LV_CPICKER_TYPE_RECT) indic_pad += LV_MATH_MAX(indic_pad, lv_obj_get_height(cpicker) / 2); + + cpicker->ext_draw_pad = LV_MATH_MAX(cpicker->ext_draw_pad, indic_pad); + } else if(sign == LV_SIGNAL_CORD_CHG) { + /*Refresh extended draw area to make knob visible*/ + if(lv_obj_get_width(cpicker) != lv_area_get_width(param) || + lv_obj_get_height(cpicker) != lv_area_get_height(param)) + { + lv_obj_refresh_ext_draw_pad(cpicker); + refr_indic_pos(cpicker); + } + } else if(sign == LV_SIGNAL_STYLE_CHG) { + /*Refresh extended draw area to make knob visible*/ + lv_obj_refresh_ext_draw_pad(cpicker); + refr_indic_pos(cpicker); + } + else if(sign == LV_SIGNAL_CONTROL) { + uint32_t c = *((uint32_t *)param); /*uint32_t because can be UTF-8*/ + if(c == LV_KEY_RIGHT || c == LV_KEY_UP) { + lv_color_hsv_t hsv_cur; + hsv_cur = ext->hsv; + + switch(ext->color_mode) { + case LV_CPICKER_COLOR_MODE_HUE: + hsv_cur.h = (ext->hsv.h + 1) % 360; + break; + case LV_CPICKER_COLOR_MODE_SATURATION: + hsv_cur.s = (ext->hsv.s + 1) % 100; + break; + case LV_CPICKER_COLOR_MODE_VALUE: + hsv_cur.v = (ext->hsv.v + 1) % 100; + break; + } + + lv_cpicker_set_hsv(cpicker, hsv_cur); + + res = lv_event_send(cpicker, LV_EVENT_VALUE_CHANGED, NULL); + if(res != LV_RES_OK) return res; + } + else if(c == LV_KEY_LEFT || c == LV_KEY_DOWN) { + lv_color_hsv_t hsv_cur; + hsv_cur = ext->hsv; + + switch(ext->color_mode) { + case LV_CPICKER_COLOR_MODE_HUE: + hsv_cur.h = ext->hsv.h > 0?(ext->hsv.h - 1) : 360; + break; + case LV_CPICKER_COLOR_MODE_SATURATION: + hsv_cur.s = ext->hsv.s > 0?(ext->hsv.s - 1) : 100; + break; + case LV_CPICKER_COLOR_MODE_VALUE: + hsv_cur.v = ext->hsv.v > 0?(ext->hsv.v - 1) : 100; + break; + } + + lv_cpicker_set_hsv(cpicker, hsv_cur); + + res = lv_event_send(cpicker, LV_EVENT_VALUE_CHANGED, NULL); + if(res != LV_RES_OK) return res; + } + } + else if(sign == LV_SIGNAL_PRESSED) { + res = double_click_reset(cpicker); + ext->last_change_time = lv_tick_get(); + if(res != LV_RES_OK) return res; + } else if(sign == LV_SIGNAL_PRESSING){ + lv_indev_t * indev = lv_indev_get_act(); + lv_point_t p; + lv_indev_get_point(indev, &p); + p.x -= cpicker->coords.x1; + p.y -= cpicker->coords.y1; + + /*Ignore pressing in the inner area*/ + uint16_t w = lv_obj_get_width(cpicker); + + int16_t angle = 0; + + if(ext->type == LV_CPICKER_TYPE_RECT) { + angle = (p.x * 360) / w; + if(angle < 0) angle = 0; + if(angle >= 360) angle = 359; + + } else if(ext->type == LV_CPICKER_TYPE_DISC) { + const lv_style_t * style_main = lv_cpicker_get_style(cpicker, LV_CPICKER_STYLE_MAIN); + lv_coord_t r = w / 2; + p.x -= r; + p.y -= r; + r -= style_main->line.width; + if(p.x * p.x + p.y * p.y < r * r) return res; + + angle = lv_atan2(p.x, p.y) % 360; + } + + bool changed = false; + switch(ext->color_mode) { + case LV_CPICKER_COLOR_MODE_HUE: + if(ext->hsv.h != angle) { + lv_cpicker_set_hue(cpicker, angle); + changed = true; + } + break; + case LV_CPICKER_COLOR_MODE_SATURATION: + angle = (angle * 100) / 360; + if(ext->hsv.s != angle) { + lv_cpicker_set_saturation(cpicker, angle); + changed = true; + } + break; + case LV_CPICKER_COLOR_MODE_VALUE: + angle = (angle * 100) / 360; + if(ext->hsv.v != angle) { + lv_cpicker_set_value(cpicker, angle); + changed = true; + } + break; + } + + refr_indic_pos(cpicker); + + uint32_t diff = lv_tick_elaps(ext->last_change_time); + if(diff > indev->driver.long_press_time * 2 && !ext->color_mode_fixed) { + next_color_mode(cpicker); + lv_indev_wait_release(lv_indev_get_act()); + } + + if(changed) { + ext->last_change_time = lv_tick_get(); + } + + res = lv_event_send(cpicker, LV_EVENT_VALUE_CHANGED, NULL); + if(res != LV_RES_OK) return res; + } + + return res; +} + +static void next_color_mode(lv_obj_t * cpicker ) +{ + lv_cpicker_ext_t * ext = lv_obj_get_ext_attr(cpicker); + ext->color_mode = (ext->color_mode + 1) % 3; + refr_indic_pos(cpicker); + lv_obj_invalidate(cpicker); +} + + +/** + * Indicator points need to match those set in lv_cpicker_disc_design/lv_cpicker_rect_design + */ +static void invalidate_indic(lv_obj_t * cpicker) +{ + lv_cpicker_ext_t * ext = lv_obj_get_ext_attr(cpicker); + const lv_style_t * style_main = lv_cpicker_get_style(cpicker, LV_CPICKER_STYLE_MAIN); + const lv_style_t * style_indic = lv_cpicker_get_style(cpicker, LV_CPICKER_STYLE_INDICATOR); + + lv_coord_t h = lv_obj_get_height(cpicker); + + uint16_t r; + if(ext->type == LV_CPICKER_TYPE_DISC) r = style_main->line.width / 2; + else if(ext->type == LV_CPICKER_TYPE_RECT) r = h / 2; + + lv_area_t indic_area; + indic_area.x1 = cpicker->coords.x1 + ext->indic.pos.x - r - style_indic->body.padding.left; + indic_area.y1 = cpicker->coords.x1 + ext->indic.pos.y - r - style_indic->body.padding.top; + indic_area.x2 = cpicker->coords.x1 + ext->indic.pos.x + r + style_indic->body.padding.right; + indic_area.y2 = cpicker->coords.y1 + ext->indic.pos.y + r + style_indic->body.padding.bottom; + + lv_inv_area(lv_obj_get_disp(cpicker), &indic_area); +} + +static void refr_indic_pos(lv_obj_t * cpicker) +{ + invalidate_indic(cpicker); + + lv_cpicker_ext_t * ext = lv_obj_get_ext_attr(cpicker); + lv_coord_t w = lv_obj_get_width(cpicker); + lv_coord_t h = lv_obj_get_height(cpicker); + + if(ext->type == LV_CPICKER_TYPE_RECT) { + lv_coord_t ind_pos = 0; + switch(ext->color_mode) { + case LV_CPICKER_COLOR_MODE_HUE: + ind_pos += (ext->hsv.h * w) / 360; + break; + case LV_CPICKER_COLOR_MODE_SATURATION: + ind_pos += (ext->hsv.s * w) / 100; + break; + case LV_CPICKER_COLOR_MODE_VALUE: + ind_pos += (ext->hsv.v * w) / 100; + break; + } + + ext->indic.pos.x = ind_pos; + ext->indic.pos.y = h / 2; + } + if(ext->type == LV_CPICKER_TYPE_DISC) { + const lv_style_t * style_main = lv_cpicker_get_style(cpicker, LV_CPICKER_STYLE_MAIN); + lv_coord_t r = w / 2 - style_main->line.width / 2; + uint16_t angle = get_angle(cpicker); + ext->indic.pos.x = (((int32_t)r * lv_trigo_sin(angle)) >> LV_TRIGO_SHIFT); + ext->indic.pos.y = (((int32_t)r * lv_trigo_sin(angle + 90)) >> LV_TRIGO_SHIFT); + ext->indic.pos.x = ext->indic.pos.x + w / 2; + ext->indic.pos.y = ext->indic.pos.y + w / 2; + } + + invalidate_indic(cpicker); +} + +static lv_res_t double_click_reset(lv_obj_t * cpicker) +{ + lv_cpicker_ext_t * ext = lv_obj_get_ext_attr(cpicker); + lv_indev_t * indev = lv_indev_get_act(); + /*Double clicked? Use long press time as double click time out*/ + if(lv_tick_elaps(ext->last_click_time) < indev->driver.long_press_time) { + lv_cpicker_set_hsv(cpicker, LV_CPICKER_DEF_HSV); + + lv_res_t res; + res = lv_event_send(cpicker, LV_EVENT_VALUE_CHANGED, NULL); + if(res != LV_RES_OK) return res; + } + ext->last_click_time = lv_tick_get(); + + return LV_RES_OK; +} + +static lv_color_t angle_to_mode_color(lv_obj_t * cpicker, uint16_t angle) +{ + lv_cpicker_ext_t * ext = lv_obj_get_ext_attr(cpicker); lv_color_t color; switch(ext->color_mode) { @@ -482,8 +989,9 @@ static lv_color_t angle_to_mode_color(lv_cpicker_ext_t * ext, uint16_t angle) return color; } -static uint16_t mode_color_to_angle(lv_cpicker_ext_t * ext) +static uint16_t get_angle(lv_obj_t * cpicker) { + lv_cpicker_ext_t * ext = lv_obj_get_ext_attr(cpicker); uint16_t angle; switch(ext->color_mode) { @@ -492,1258 +1000,13 @@ static uint16_t mode_color_to_angle(lv_cpicker_ext_t * ext) angle = ext->hsv.h; break; case LV_CPICKER_COLOR_MODE_SATURATION: - angle = (ext->hsv.s / 100) * 360.0; + angle = (ext->hsv.s * 360) / 100; break; case LV_CPICKER_COLOR_MODE_VALUE: - angle = (ext->hsv.v / 100) * 360.0; + angle = (ext->hsv.v * 360) / 100 ; break; } return angle; } -static lv_coord_t lv_cpicker_get_indicator_coord(lv_style_t * style, lv_cpicker_ext_t * ext) -{ - lv_coord_t ind_pos = style->line.rounded ? ext->rect_gradient_h / 2 : 0; - switch(ext->color_mode) - { - default: - case LV_CPICKER_COLOR_MODE_HUE: - ind_pos += (ext->hsv.h * ext->rect_gradient_w) / 360.0; - break; - case LV_CPICKER_COLOR_MODE_SATURATION: - ind_pos += (ext->hsv.s * ext->rect_gradient_w) / 100; - break; - case LV_CPICKER_COLOR_MODE_VALUE: - ind_pos += (ext->hsv.v * ext->rect_gradient_w) / 100; - break; - } - return ind_pos; -} - -/** - * Should roughly match up with `lv_cpicker_invalidate_disc_indicator_line` - */ -static void lv_cpicker_draw_disc_indicator_line(lv_area_t * mask, lv_style_t * style, lv_opa_t opa_scale, - lv_cpicker_ext_t * ext, - lv_coord_t cx, lv_coord_t cy, uint16_t r, - uint16_t angle) -{ - lv_point_t start; - lv_point_t end; - start.x = cx + ((r - style->line.width + ext->indicator.style->body.padding.inner + ext->indicator.style->line.width/2) * lv_trigo_sin(angle) >> LV_TRIGO_SHIFT); - start.y = cy + ((r - style->line.width + ext->indicator.style->body.padding.inner + ext->indicator.style->line.width/2) * lv_trigo_sin(angle + 90) >> LV_TRIGO_SHIFT); - end.x = cx + ((r - ext->indicator.style->body.padding.inner - ext->indicator.style->line.width/2) * lv_trigo_sin(angle) >> LV_TRIGO_SHIFT); - end.y = cy + ((r - ext->indicator.style->body.padding.inner - ext->indicator.style->line.width/2) * lv_trigo_sin(angle + 90) >> LV_TRIGO_SHIFT); - - lv_draw_line(&start, &end, mask, ext->indicator.style, opa_scale); - - if(ext->indicator.style->line.rounded) - { - lv_area_t circle_area; - circle_area.x1 = start.x - ((ext->indicator.style->line.width - 1) >> 1) - ((ext->indicator.style->line.width - 1) & 0x1); - circle_area.y1 = start.y - ((ext->indicator.style->line.width - 1) >> 1) - ((ext->indicator.style->line.width - 1) & 0x1); - circle_area.x2 = start.x + ((ext->indicator.style->line.width - 1) >> 1); - circle_area.y2 = start.y + ((ext->indicator.style->line.width - 1) >> 1); - lv_draw_rect(&circle_area, mask, ext->indicator.style, opa_scale); - - circle_area.x1 = end.x - ((ext->indicator.style->line.width - 1) >> 1) - ((ext->indicator.style->line.width - 1) & 0x1); - circle_area.y1 = end.y - ((ext->indicator.style->line.width - 1) >> 1) - ((ext->indicator.style->line.width - 1) & 0x1); - circle_area.x2 = end.x + ((ext->indicator.style->line.width - 1) >> 1); - circle_area.y2 = end.y + ((ext->indicator.style->line.width - 1) >> 1); - lv_draw_rect(&circle_area, mask, ext->indicator.style, opa_scale); - } -} - -/** - * Should roughly match up with `lv_cpicker_invalidate_disc_indicator_circle` - */ -static void lv_cpicker_draw_disc_indicator_circle(lv_area_t * mask, lv_style_t * style, lv_opa_t opa_scale, - lv_cpicker_ext_t * ext, - lv_coord_t cx, lv_coord_t cy, uint16_t r, - uint16_t angle) -{ - uint32_t ind_cx = cx + ((r - style->line.width/2) * lv_trigo_sin(angle) >> LV_TRIGO_SHIFT); - uint32_t ind_cy = cy + ((r - style->line.width/2) * lv_trigo_sin(angle + 90) >> LV_TRIGO_SHIFT); - - lv_area_t ind_area; - ind_area.x1 = ind_cx - style->line.width/2; - ind_area.y1 = ind_cy - style->line.width/2; - ind_area.x2 = ind_cx + style->line.width/2; - ind_area.y2 = ind_cy + style->line.width/2; - - lv_style_t styleCopy; - lv_style_copy(&styleCopy, ext->indicator.style); - styleCopy.body.radius = LV_RADIUS_CIRCLE; - - lv_draw_rect(&ind_area, mask, &styleCopy, opa_scale); -} - -/** - * Should roughly match up with `lv_cpicker_invalidate_disc_indicator_in` - */ -static void lv_cpicker_draw_disc_indicator_in(lv_area_t * mask, lv_style_t * style, lv_opa_t opa_scale, - lv_cpicker_ext_t * ext, - lv_coord_t cx, lv_coord_t cy, uint16_t r, - uint16_t rin, uint16_t angle) -{ - uint16_t ind_radius = lv_sqrt((4*rin*rin)/2)/2 + 1 - style->body.padding.inner; - ind_radius = (ind_radius + rin) / 2; - - uint32_t ind_cx = cx + ((ind_radius) * lv_trigo_sin(angle) >> LV_TRIGO_SHIFT); - uint32_t ind_cy = cy + ((ind_radius) * lv_trigo_sin(angle + 90) >> LV_TRIGO_SHIFT); - - lv_area_t ind_area; - ind_area.x1 = ind_cx - r; - ind_area.y1 = ind_cy - r; - ind_area.x2 = ind_cx + r; - ind_area.y2 = ind_cy + r; - - lv_style_t styleCopy; - lv_style_copy(&styleCopy, ext->indicator.style); - styleCopy.body.radius = LV_RADIUS_CIRCLE; - - lv_draw_rect(&ind_area, mask, &styleCopy, opa_scale); -} - -static void lv_cpicker_draw_disc_indicator(lv_area_t * mask, lv_style_t * style, lv_opa_t opa_scale, - lv_cpicker_ext_t * ext, - lv_coord_t cx, lv_coord_t cy, lv_coord_t r, - uint16_t rin, uint16_t radius, lv_area_t center_ind_area) -{ - /*draw center background*/ - static lv_style_t styleCenterBackground; - lv_theme_t * th = lv_theme_get_current(); - if (th) { - lv_style_copy(&styleCenterBackground, th->style.bg); - } else { - lv_style_copy(&styleCenterBackground, &lv_style_plain); - } - - lv_area_t center_area; - center_area.x1 = cx - rin; - center_area.y1 = cy - rin; - center_area.x2 = cx + rin; - center_area.y2 = cy + rin; - styleCenterBackground.body.radius = LV_RADIUS_CIRCLE; - lv_draw_rect(¢er_area, mask, &styleCenterBackground, opa_scale); - - /*draw the center color indicator*/ - style->body.main_color = lv_color_hsv_to_rgb(ext->hsv.h, ext->hsv.s, ext->hsv.v); - style->body.grad_color = style->body.main_color; - style->body.radius = LV_RADIUS_CIRCLE; - lv_draw_rect(¢er_ind_area, mask, style, opa_scale); - - uint16_t angle = mode_color_to_angle(ext); - /*save the angle to refresh the area later*/ - ext->prev_pos = angle; - - /*draw the current hue indicator*/ - switch(ext->indicator.type) - { - case LV_CPICKER_INDICATOR_NONE: - /*no indicator*/ - break; - case LV_CPICKER_INDICATOR_LINE: - lv_cpicker_draw_disc_indicator_line(mask, style, opa_scale, ext, cx, cy, r, angle); - break; - case LV_CPICKER_INDICATOR_CIRCLE: - lv_cpicker_draw_disc_indicator_circle(mask, style, opa_scale, ext, cx, cy, r, angle); - break; - case LV_CPICKER_INDICATOR_IN: - lv_cpicker_draw_disc_indicator_in(mask, style, opa_scale, ext, cx, cy, (rin - radius) / 3, rin, angle); - break; - } -} - -static void lv_cpicker_draw_disc_gradient(lv_area_t * mask, lv_style_t * style, lv_opa_t opa_scale, - lv_cpicker_ext_t * ext, - lv_coord_t cx, lv_coord_t cy, uint16_t r) -{ - int16_t start_angle = 0; /*Default*/ - int16_t end_angle = 360 - LV_CPICKER_DEF_QF; /*Default*/ - - /*if the mask does not include the center of the object - * redrawing all the wheel is not necessary; - * only a given angular range - */ - lv_point_t center = {cx, cy}; - if(!lv_area_is_point_on(mask, ¢er)) - { - /*get angle from center of object to each corners of the area*/ - int16_t dr, ur, ul, dl; - dr = lv_atan2(mask->x2 - cx, mask->y2 - cy); - ur = lv_atan2(mask->x2 - cx, mask->y1 - cy); - ul = lv_atan2(mask->x1 - cx, mask->y1 - cy); - dl = lv_atan2(mask->x1 - cx, mask->y2 - cy); - - /*check area position from object axis*/ - bool left = (mask->x2 < cx && mask->x1 < cx) ? true : false; - bool onYaxis = (mask->x2 > cx && mask->x1 < cx) ? true : false; - bool right = (mask->x2 > cx && mask->x1 > cx) ? true : false; - bool top = (mask->y2 < cy && mask->y1 < cy) ? true : false; - bool onXaxis = (mask->y2 > cy && mask->y1 < cy) ? true : false; - bool bottom = (mask->y2 > cy && mask->y1 > cy) ? true : false; - - /*store angular range*/ - if(right && bottom) - { - start_angle = dl; - end_angle = ur; - } - else if(right && onXaxis) - { - start_angle = dl; - end_angle = ul; - } - else if(right && top) - { - start_angle = dr; - end_angle = ul; - } - else if(onYaxis && top) - { - start_angle = dr; - end_angle = dl; - } - else if(left && top) - { - start_angle = ur; - end_angle = dl; - } - else if(left && onXaxis) - { - start_angle = ur; - end_angle = dr; - } - else if(left && bottom) - { - start_angle = ul; - end_angle = dr; - } - else if(onYaxis && bottom) - { - start_angle = ul; - end_angle = ur; - } - - /*rollover angle*/ - if(start_angle > end_angle) - { - end_angle += 360; - } - - /*round to QF factor*/ - start_angle = (start_angle/LV_CPICKER_DEF_QF) * LV_CPICKER_DEF_QF; - end_angle = (end_angle / LV_CPICKER_DEF_QF) * LV_CPICKER_DEF_QF; - - /*shift angle if necessary before adding offset*/ - if((start_angle - LV_CPICKER_DEF_QF) < 0) - { - start_angle += 360; - end_angle += 360; - } - - /*ensure overlapping by adding offset*/ - start_angle -= LV_CPICKER_DEF_QF; - end_angle += LV_CPICKER_DEF_QF; - } - - lv_point_t triangle_points[3]; - - if(ext->color_mode == LV_CPICKER_COLOR_MODE_HUE) - { - for(uint16_t i = start_angle; i <= end_angle; i+= LV_CPICKER_DEF_QF) - { - style->body.main_color = angle_to_mode_color(ext, i); - style->body.grad_color = style->body.main_color; - - triangle_points[0].x = cx; - triangle_points[0].y = cy; - - triangle_points[1].x = cx + (r * lv_trigo_sin(i) >> LV_TRIGO_SHIFT); - triangle_points[1].y = cy + (r * lv_trigo_sin(i + 90) >> LV_TRIGO_SHIFT); - - if(i == end_angle || i == (360 - LV_CPICKER_DEF_QF)) - { - /*the last triangle is drawn without additional overlapping pixels*/ - triangle_points[2].x = cx + (r * lv_trigo_sin(i + LV_CPICKER_DEF_QF) >> LV_TRIGO_SHIFT); - triangle_points[2].y = cy + (r * lv_trigo_sin(i + LV_CPICKER_DEF_QF + 90) >> LV_TRIGO_SHIFT); - } - else - { - triangle_points[2].x = cx + (r * lv_trigo_sin(i + LV_CPICKER_DEF_QF + TRI_OFFSET) >> LV_TRIGO_SHIFT); - triangle_points[2].y = cy + (r * lv_trigo_sin(i + LV_CPICKER_DEF_QF + TRI_OFFSET + 90) >> LV_TRIGO_SHIFT); - } - - lv_draw_triangle(triangle_points, mask, style, LV_OPA_COVER); - } - } - else if(ext->color_mode == LV_CPICKER_COLOR_MODE_SATURATION) - { - for(uint16_t i = start_angle; i <= end_angle; i += LV_CPICKER_DEF_QF) - { - style->body.main_color = angle_to_mode_color(ext, i); - style->body.grad_color = style->body.main_color; - - triangle_points[0].x = cx; - triangle_points[0].y = cy; - - triangle_points[1].x = cx + (r * lv_trigo_sin(i) >> LV_TRIGO_SHIFT); - triangle_points[1].y = cy + (r * lv_trigo_sin(i + 90) >> LV_TRIGO_SHIFT); - - if(i == end_angle || i == (360 - LV_CPICKER_DEF_QF)) - { - /*the last triangle is drawn without additional overlapping pixels*/ - triangle_points[2].x = cx + (r * lv_trigo_sin(i + LV_CPICKER_DEF_QF) >> LV_TRIGO_SHIFT); - triangle_points[2].y = cy + (r * lv_trigo_sin(i + LV_CPICKER_DEF_QF + 90) >> LV_TRIGO_SHIFT); - } - else - { - triangle_points[2].x = cx + (r * lv_trigo_sin(i + LV_CPICKER_DEF_QF + TRI_OFFSET) >> LV_TRIGO_SHIFT); - triangle_points[2].y = cy + (r * lv_trigo_sin(i + LV_CPICKER_DEF_QF + TRI_OFFSET + 90) >> LV_TRIGO_SHIFT); - } - - lv_draw_triangle(triangle_points, mask, style, LV_OPA_COVER); - } - } - else if(ext->color_mode == LV_CPICKER_COLOR_MODE_VALUE) - { - for(uint16_t i = start_angle; i <= end_angle; i += LV_CPICKER_DEF_QF) - { - style->body.main_color = angle_to_mode_color(ext, i); - style->body.grad_color = style->body.main_color; - - triangle_points[0].x = cx; - triangle_points[0].y = cy; - - triangle_points[1].x = cx + (r * lv_trigo_sin(i) >> LV_TRIGO_SHIFT); - triangle_points[1].y = cy + (r * lv_trigo_sin(i + 90) >> LV_TRIGO_SHIFT); - - if(i == end_angle || i == (360 - LV_CPICKER_DEF_QF)) - { - /*the last triangle is drawn without additional overlapping pixels*/ - triangle_points[2].x = cx + (r * lv_trigo_sin(i + LV_CPICKER_DEF_QF) >> LV_TRIGO_SHIFT); - triangle_points[2].y = cy + (r * lv_trigo_sin(i + LV_CPICKER_DEF_QF + 90) >> LV_TRIGO_SHIFT); - } - else - { - triangle_points[2].x = cx + (r * lv_trigo_sin(i + LV_CPICKER_DEF_QF + TRI_OFFSET) >> LV_TRIGO_SHIFT); - triangle_points[2].y = cy + (r * lv_trigo_sin(i + LV_CPICKER_DEF_QF + TRI_OFFSET + 90) >> LV_TRIGO_SHIFT); - } - - lv_draw_triangle(triangle_points, mask, style, LV_OPA_COVER); - } - } -} - -/** - * Should roughly match up with `lv_cpicker_invalidate_disc` - */ -static void lv_cpicker_disc_design(lv_obj_t * cpicker, - lv_area_t * mask, lv_style_t * style, lv_opa_t opa_scale, - lv_cpicker_ext_t * ext, - lv_coord_t w, lv_coord_t h, - lv_coord_t cx, lv_coord_t cy, uint16_t r) -{ - uint16_t rin = r - style->line.width; - /* - the square area (a and b being sides) should fit into the center of diameter d - we have: - a^2+b^2<=d^2 - 2a^2 <= d^2 - a^2<=(d^2)/2 - a <= sqrt((d^2)/2) - */ - uint16_t radius = lv_sqrt((4*rin*rin)/2)/2 - style->body.padding.inner; - - lv_area_t center_ind_area; - center_ind_area.x1 = cx - radius; - center_ind_area.y1 = cy - radius; - center_ind_area.x2 = cx + radius; - center_ind_area.y2 = cy + radius; - - /*redraw the wheel only if the mask intersect with the wheel*/ - if(mask->x1 < center_ind_area.x1 || mask->x2 > center_ind_area.x2 - || mask->y1 < center_ind_area.y1 || mask->y2 > center_ind_area.y2) - { - lv_cpicker_draw_disc_gradient(mask, style, opa_scale, ext, cx, cy, r); - } - - lv_cpicker_draw_disc_indicator(mask, style, opa_scale, ext, cx, cy, r, rin, radius, center_ind_area); - - /* - static uint32_t c = 0; - lv_style_t style2; - lv_style_copy(&style2, &lv_style_plain); - style2.body.main_color.full = c; - style2.body.grad_color.full = c; - c += 0x123445678; - lv_draw_rect(mask, mask, &style2, opa_scale); - */ -} - -static uint16_t lv_cpicker_calculate_rect_preview_area(lv_obj_t * cpicker, - lv_style_t * style, - lv_cpicker_ext_t * ext, - lv_coord_t w) -{ - lv_coord_t x1 = cpicker->coords.x1; - lv_coord_t y1 = cpicker->coords.y1; - lv_coord_t x2 = cpicker->coords.x2; - lv_coord_t y2 = cpicker->coords.y2; - - /*prepare the color preview area*/ - uint16_t preview_offset = style->line.width; - uint16_t style_body_padding_ver = style->body.padding.top + style->body.padding.bottom; - uint16_t style_body_padding_hor = style->body.padding.left + style->body.padding.right; - if(style_body_padding_ver == 0) - { - /*draw the color preview rect to the side of the gradient*/ - if(style_body_padding_hor >= 0) - { - /*draw the preview to the right*/ - ext->rect_gradient_w = w - preview_offset - (LV_MATH_ABS(style_body_padding_hor) - 1); - ext->rect_gradient_h = y2 - y1; - ext->rect_gradient_area.x1 = x1; - ext->rect_gradient_area.x2 = ext->rect_gradient_area.x1 + ext->rect_gradient_w; - ext->rect_gradient_area.y1 = y1; - ext->rect_gradient_area.y2 = y2; - - ext->rect_preview_area.x1 = x2 - preview_offset; - ext->rect_preview_area.y1 = y1; - ext->rect_preview_area.x2 = x2 ; - ext->rect_preview_area.y2 = y2; - } - else - { - /*draw the preview to the left*/ - ext->rect_gradient_w = w - preview_offset - (LV_MATH_ABS(style_body_padding_hor) - 1); - ext->rect_gradient_h = y2 - y1; - ext->rect_gradient_area.x1 = x2 - ext->rect_gradient_w; - ext->rect_gradient_area.x2 = x2; - ext->rect_gradient_area.y1 = y1; - ext->rect_gradient_area.y2 = y2; - - ext->rect_preview_area.x1 = x1; - ext->rect_preview_area.y1 = y1; - ext->rect_preview_area.x2 = x1 + preview_offset; - ext->rect_preview_area.y2 = y2; - } - } - else - { - /*draw the color preview rect on top or below the gradient*/ - if(style_body_padding_ver >= 0) - { - /*draw the preview on top*/ - ext->rect_gradient_w = w; - ext->rect_gradient_h = (y2 - y1) - preview_offset - (LV_MATH_ABS(style_body_padding_ver) - 1); - ext->rect_gradient_area.x1 = x1; - ext->rect_gradient_area.x2 = x2; - ext->rect_gradient_area.y1 = y2 - ext->rect_gradient_h; - ext->rect_gradient_area.y2 = y2; - - ext->rect_preview_area.x1 = x1; - ext->rect_preview_area.y1 = y1; - ext->rect_preview_area.x2 = x2; - ext->rect_preview_area.y2 = y1 + preview_offset; - } - else - { - /*draw the preview below the gradient*/ - ext->rect_gradient_w = w; - ext->rect_gradient_h = (y2 - y1) - preview_offset - (LV_MATH_ABS(style_body_padding_ver) - 1); - ext->rect_gradient_area.x1 = x1; - ext->rect_gradient_area.x2 = x2; - ext->rect_gradient_area.y1 = y1; - ext->rect_gradient_area.y2 = y1 + ext->rect_gradient_h; - - ext->rect_preview_area.x1 = x1; - ext->rect_preview_area.y1 = y2 - preview_offset; - ext->rect_preview_area.x2 = x2; - ext->rect_preview_area.y2 = y2; - } - } - - return style_body_padding_hor; -} - -/** - * Should roughly match up with `lv_cpicker_invalidate_rect_indicator_line` - */ -static void lv_cpicker_draw_rect_indicator_line(lv_area_t * mask, lv_opa_t opa_scale, - lv_cpicker_ext_t * ext, lv_coord_t ind_pos) -{ - lv_point_t p1, p2; - p1.x = ext->rect_gradient_area.x1 + ind_pos; - p1.y = ext->rect_gradient_area.y1; - p2.x = p1.x; - p2.y = ext->rect_gradient_area.y2; - - lv_draw_line(&p1, &p2, mask, ext->indicator.style, opa_scale); -} - -/** - * Should roughly match up with `lv_cpicker_invalidate_rect_indicator_circle` - */ -static void lv_cpicker_draw_rect_indicator_circle(lv_area_t * mask, lv_opa_t opa_scale, - lv_cpicker_ext_t * ext, lv_coord_t ind_pos) -{ - lv_area_t circle_ind_area; - circle_ind_area.x1 = ext->rect_gradient_area.x1 + ind_pos - ext->rect_gradient_h/2; - circle_ind_area.x2 = circle_ind_area.x1 + ext->rect_gradient_h; - circle_ind_area.y1 = ext->rect_gradient_area.y1; - circle_ind_area.y2 = ext->rect_gradient_area.y2; - - lv_style_t styleCopy; - lv_style_copy(&styleCopy, ext->indicator.style); - styleCopy.body.radius = LV_RADIUS_CIRCLE; - - lv_draw_rect(&circle_ind_area, mask, &styleCopy, opa_scale); -} - -/** - * Should roughly match up with `lv_cpicker_invalidate_rect_indicator_in` - */ -static void lv_cpicker_draw_rect_indicator_in(lv_area_t * mask, lv_opa_t opa_scale, - lv_cpicker_ext_t * ext, lv_coord_t ind_pos) -{ - /*draw triangle at top and bottom of gradient*/ - lv_point_t triangle_points[3]; - - triangle_points[0].x = ext->rect_gradient_area.x1 + ind_pos; - triangle_points[0].y = ext->rect_gradient_area.y1 + (ext->rect_gradient_h/3); - - triangle_points[1].x = triangle_points[0].x - ext->indicator.style->line.width * 3; - triangle_points[1].y = ext->rect_gradient_area.y1 - 1; - - triangle_points[2].x = triangle_points[0].x + ext->indicator.style->line.width * 3; - triangle_points[2].y = triangle_points[1].y; - - lv_draw_triangle(triangle_points, mask, ext->indicator.style, LV_OPA_COVER); - - triangle_points[0].y = ext->rect_gradient_area.y2 - (ext->rect_gradient_h/3); - triangle_points[1].y = ext->rect_gradient_area.y2; - triangle_points[2].y = triangle_points[1].y; - lv_draw_triangle(triangle_points, mask, ext->indicator.style, LV_OPA_COVER); -} - -static void lv_cpicker_draw_rect_indicator(lv_obj_t * cpicker, - lv_area_t * mask, lv_style_t * style, lv_opa_t opa_scale, - lv_cpicker_ext_t * ext, - uint16_t style_body_padding_hor) -{ - /*draw the color preview indicator*/ - style->body.main_color = lv_cpicker_get_color(cpicker); - style->body.grad_color = style->body.main_color; - if(style->line.rounded && style_body_padding_hor == 0) - { - style->body.radius = ext->rect_gradient_h; - } - lv_draw_rect(&(ext->rect_preview_area), mask, style, opa_scale); - - /*draw the color position indicator*/ - lv_coord_t ind_pos = lv_cpicker_get_indicator_coord(style, ext); - /*save to refresh the area later*/ - ext->prev_pos = ind_pos; - - switch(ext->indicator.type) - { - case LV_CPICKER_INDICATOR_NONE: - /*no indicator*/ - break; - case LV_CPICKER_INDICATOR_LINE: - lv_cpicker_draw_rect_indicator_line(mask, opa_scale, ext, ind_pos); - break; - case LV_CPICKER_INDICATOR_CIRCLE: - lv_cpicker_draw_rect_indicator_circle(mask, opa_scale, ext, ind_pos); - break; - case LV_CPICKER_INDICATOR_IN: - lv_cpicker_draw_rect_indicator_in(mask, opa_scale, ext, ind_pos); - break; - default: - break; - } -} - -static void lv_cpicker_draw_rect_gradient(lv_area_t * mask, lv_style_t * style, lv_opa_t opa_scale, - lv_cpicker_ext_t * ext) -{ - if(style->line.rounded) - { - /*draw rounded edges to the gradient*/ - lv_area_t rounded_edge_area; - rounded_edge_area.x1 = ext->rect_gradient_area.x1; - rounded_edge_area.x2 = ext->rect_gradient_area.x1 + ext->rect_gradient_h; - rounded_edge_area.y1 = ext->rect_gradient_area.y1; - rounded_edge_area.y2 = ext->rect_gradient_area.y2; - - ext->rect_gradient_area.x1 += ext->rect_gradient_h/2; - ext->rect_gradient_area.x2 -= ext->rect_gradient_h/2; - ext->rect_gradient_w -= ext->rect_gradient_h; - - style->body.main_color = angle_to_mode_color(ext, 0); - style->body.grad_color = style->body.main_color; - - style->body.radius = LV_RADIUS_CIRCLE; - - lv_draw_rect(&rounded_edge_area, mask, style, opa_scale); - - rounded_edge_area.x1 += ext->rect_gradient_w - 1; - rounded_edge_area.x2 += ext->rect_gradient_w - 1; - - style->body.main_color = angle_to_mode_color(ext, 360); - style->body.grad_color = style->body.main_color; - - lv_draw_rect(&rounded_edge_area, mask, style, opa_scale); - } - - for(uint16_t i = 0; i < 360; i += LV_MATH_MAX(LV_CPICKER_DEF_QF, 360/ext->rect_gradient_w)) - { - style->body.main_color = angle_to_mode_color(ext, i); - style->body.grad_color = style->body.main_color; - - /*the following attribute might need changing between index to add border, shadow, radius etc*/ - style->body.radius = 0; - style->body.border.width = 0; - style->body.shadow.width = 0; - style->body.opa = LV_OPA_COVER; - - lv_area_t rect_area; - - /*scale angle (hue/sat/val) to linear coordinate*/ - lv_coord_t xi = i / 360.0 * ext->rect_gradient_w; - - rect_area.x1 = LV_MATH_MIN(ext->rect_gradient_area.x1 + xi, ext->rect_gradient_area.x1 + ext->rect_gradient_w - LV_MATH_MAX(LV_CPICKER_DEF_QF, 360/ext->rect_gradient_w)); - rect_area.y1 = ext->rect_gradient_area.y1; - rect_area.x2 = rect_area.x1 + LV_MATH_MAX(LV_CPICKER_DEF_QF, 360/ext->rect_gradient_w); - rect_area.y2 = ext->rect_gradient_area.y2; - - lv_draw_rect(&rect_area, mask, style, opa_scale); - } - - if(style->line.rounded) - { - /*Restore gradient area to take rounded end in account*/ - ext->rect_gradient_area.x1 -= ext->rect_gradient_h/2; - ext->rect_gradient_area.x2 += ext->rect_gradient_h/2; - //ext->rect_gradient_w += ext->rect_gradient_h; - } -} - -/** - * Should roughly match up with `lv_cpicker_invalidate_rect` - */ -static void lv_cpicker_rect_design(lv_obj_t * cpicker, - lv_area_t * mask, lv_style_t * style, lv_opa_t opa_scale, - lv_cpicker_ext_t * ext, - lv_coord_t w, lv_coord_t h) -{ - uint16_t style_body_padding_hor = lv_cpicker_calculate_rect_preview_area(cpicker, style, ext, w); - - lv_cpicker_draw_rect_gradient(mask, style, opa_scale, ext); - - lv_cpicker_draw_rect_indicator(cpicker, mask, style, opa_scale, ext, style_body_padding_hor); -} - - -static void lv_cpicker_invalidate(lv_obj_t * cpicker, bool all); - -static lv_res_t lv_cpicker_disc_signal(lv_obj_t * cpicker, lv_signal_t sign, void * param, - lv_style_t * style, lv_cpicker_ext_t * ext, - lv_coord_t r_out, lv_coord_t r_in, lv_coord_t x, lv_coord_t y); -static lv_res_t lv_cpicker_rect_signal(lv_obj_t * cpicker, lv_signal_t sign, void * param, - lv_style_t * style, lv_cpicker_ext_t * ext); - -/** - * Signal function of the color_picker - * @param cpicker pointer to a color_picker object - * @param sign a signal type from lv_signal_t enum - * @param param pointer to a signal specific variable - * @return LV_RES_OK: the object is not deleted in the function; LV_RES_INV: the object is deleted - */ -static lv_res_t lv_cpicker_signal(lv_obj_t * cpicker, lv_signal_t sign, void * param) -{ - /* Include the ancient signal function */ - lv_res_t res = ancestor_signal(cpicker, sign, param); - if(res != LV_RES_OK) return res; - - if(sign == LV_SIGNAL_CLEANUP) - { - /*Nothing to cleanup. (No dynamically allocated memory in 'ext')*/ - } - else if(sign == LV_SIGNAL_GET_TYPE) - { - lv_obj_type_t * buf = param; - uint8_t i; - for(i = 0; i < LV_MAX_ANCESTOR_NUM - 1; i++) /*Find the last set data*/ - { - if(buf->type[i] == NULL) break; - } - buf->type[i] = "lv_cpicker"; - } - else - { - lv_cpicker_ext_t * ext = lv_obj_get_ext_attr(cpicker); - - if(sign == LV_SIGNAL_CONTROL) - { - uint32_t c = *((uint32_t *)param); /*uint32_t because can be UTF-8*/ - if(c == LV_KEY_RIGHT || c == LV_KEY_UP) - { - switch(ext->color_mode) - { - case LV_CPICKER_COLOR_MODE_HUE: - ext->hsv.h = (ext->hsv.h + 1) % 360; - break; - case LV_CPICKER_COLOR_MODE_SATURATION: - ext->hsv.s = (ext->hsv.s + 1) % 100; - break; - case LV_CPICKER_COLOR_MODE_VALUE: - ext->hsv.v = (ext->hsv.v + 1) % 100; - break; - } - - lv_cpicker_invalidate(cpicker, false); - - res = lv_event_send(cpicker, LV_EVENT_VALUE_CHANGED, NULL); - if(res != LV_RES_OK) return res; - } - else if(c == LV_KEY_LEFT || c == LV_KEY_DOWN) - { - switch(ext->color_mode) - { - case LV_CPICKER_COLOR_MODE_HUE: - ext->hsv.h = ext->hsv.h > 0?(ext->hsv.h - 1):360; - break; - case LV_CPICKER_COLOR_MODE_SATURATION: - ext->hsv.s = ext->hsv.s > 0?(ext->hsv.s - 1):100; - break; - case LV_CPICKER_COLOR_MODE_VALUE: - ext->hsv.v = ext->hsv.v > 0?(ext->hsv.v - 1):100; - break; - } - - lv_cpicker_invalidate(cpicker, false); - - res = lv_event_send(cpicker, LV_EVENT_VALUE_CHANGED, NULL); - if(res != LV_RES_OK) return res; - } - } - else if(sign == LV_SIGNAL_PRESS_LOST) - { - ext->prev_hsv = ext->hsv; - lv_cpicker_invalidate(cpicker, false); - } - else - { - lv_style_t * style = lv_cpicker_get_style(cpicker, LV_CPICKER_STYLE_MAIN); - - if(ext->type == LV_CPICKER_TYPE_DISC) - { - lv_coord_t r_out = (LV_MATH_MIN(lv_obj_get_width(cpicker), lv_obj_get_height(cpicker))) / 2; - lv_coord_t r_in = r_out - style->line.width - style->body.padding.inner; - lv_coord_t x = cpicker->coords.x1 + lv_obj_get_width(cpicker) / 2; - lv_coord_t y = cpicker->coords.y1 + lv_obj_get_height(cpicker) / 2; - res = lv_cpicker_disc_signal(cpicker, sign, param, style, ext, r_out, r_in, x, y); - if(res != LV_RES_OK) return res; - } - else if(ext->type == LV_CPICKER_TYPE_RECT) - { - res = lv_cpicker_rect_signal(cpicker, sign, param, style, ext); - if(res != LV_RES_OK) return res; - } - } - } - - return res; -} - -static lv_res_t lv_cpicker_reset_hsv_if_double_clicked(lv_obj_t * cpicker, - lv_cpicker_ext_t * ext) -{ - bool changed = false; - - if(lv_tick_elaps(ext->last_click_time) < 400) - { - switch(ext->color_mode) - { - case LV_CPICKER_COLOR_MODE_HUE: - changed = ext->hsv.h != LV_CPICKER_DEF_HSV.h; - if (changed) - { - ext->hsv.h = LV_CPICKER_DEF_HSV.h; - } - break; - case LV_CPICKER_COLOR_MODE_SATURATION: - changed = ext->hsv.s != LV_CPICKER_DEF_HSV.s; - if (changed) - { - ext->hsv.s = LV_CPICKER_DEF_HSV.s; - } - break; - case LV_CPICKER_COLOR_MODE_VALUE: - changed = ext->hsv.v != LV_CPICKER_DEF_HSV.v; - if (changed) - { - ext->hsv.v = LV_CPICKER_DEF_HSV.v; - } - break; - } - ext->prev_hsv = ext->hsv; - } - ext->last_click_time = lv_tick_get(); - - lv_res_t res = LV_RES_OK; - if (changed) - { - lv_cpicker_invalidate(cpicker, false); - - res = lv_event_send(cpicker, LV_EVENT_VALUE_CHANGED, NULL); - if(res != LV_RES_OK) return res; - } - return res; -} - -static void lv_cpicker_set_next_color_mode(lv_obj_t * cpicker, - lv_cpicker_ext_t * ext) -{ - ext->prev_hsv = ext->hsv; - ext->color_mode = (ext->color_mode + 1) % 3; - lv_cpicker_invalidate(cpicker, true); -} - -static lv_res_t lv_cpicker_set_hsv_percent(lv_obj_t * cpicker, - lv_cpicker_ext_t * ext, - float percent) -{ - lv_res_t res; - - bool changed = false; - uint16_t hsv; - switch(ext->color_mode) - { - case LV_CPICKER_COLOR_MODE_HUE: - hsv = percent * 360.0; - changed = hsv != ext->hsv.h; - if (changed) - { - ext->hsv.h = hsv; - } - break; - case LV_CPICKER_COLOR_MODE_SATURATION: - hsv = percent * 100.0; - changed = hsv != ext->hsv.s; - if (changed) - { - ext->hsv.s = hsv; - } - break; - case LV_CPICKER_COLOR_MODE_VALUE: - hsv = percent * 100.0; - changed = hsv != ext->hsv.v; - if (changed) - { - ext->hsv.v = hsv; - } - break; - } - ext->prev_hsv = ext->hsv; - - if (changed) - { - lv_cpicker_invalidate(cpicker, false); - - res = lv_event_send(cpicker, LV_EVENT_VALUE_CHANGED, NULL); - if(res != LV_RES_OK) return res; - } - - return res; -} - -static lv_res_t lv_cpicker_disc_signal(lv_obj_t * cpicker, lv_signal_t sign, void * param, - lv_style_t * style, lv_cpicker_ext_t * ext, - lv_coord_t r_out, lv_coord_t r_in, lv_coord_t x, lv_coord_t y) -{ - lv_res_t res; - - if(sign == LV_SIGNAL_PRESSED) - { - ext->prev_hsv = ext->hsv; - - lv_indev_t * indev = param; - - lv_coord_t xp = indev->proc.types.pointer.act_point.x - x; - lv_coord_t yp = indev->proc.types.pointer.act_point.y - y; - if((xp*xp + yp*yp) < (r_in*r_in)) - { - res = lv_cpicker_reset_hsv_if_double_clicked(cpicker, ext); - if(res != LV_RES_OK) return res; - } - } - else if(sign == LV_SIGNAL_PRESSING) - { - lv_indev_t * indev = param; - - lv_coord_t xp = indev->proc.types.pointer.act_point.x - x; - lv_coord_t yp = indev->proc.types.pointer.act_point.y - y; - if((xp*xp + yp*yp) < (r_out*r_out) && (xp*xp + yp*yp) >= (r_in*r_in)) - { - float percent = lv_atan2(xp, yp) / 360.0; - - res = lv_cpicker_set_hsv_percent(cpicker, ext, percent); - if(res != LV_RES_OK) return res; - } - } - else if(sign == LV_SIGNAL_RELEASED) - { - lv_indev_t * indev = param; - - lv_coord_t xp = indev->proc.types.pointer.act_point.x - x; - lv_coord_t yp = indev->proc.types.pointer.act_point.y - y; - if((xp*xp + yp*yp) < (r_out*r_out) && (xp*xp + yp*yp) >= (r_in*r_in)) - { - float percent = lv_atan2(xp, yp) / 360.0; - - res = lv_cpicker_set_hsv_percent(cpicker, ext, percent); - if(res != LV_RES_OK) return res; - } - } - else if(sign == LV_SIGNAL_LONG_PRESS) - { - if(!ext->color_mode_fixed) - { - lv_indev_t * indev = param; - - lv_coord_t xp = indev->proc.types.pointer.act_point.x - x; - lv_coord_t yp = indev->proc.types.pointer.act_point.y - y; - if((xp*xp + yp*yp) < (r_in*r_in)) - { - lv_cpicker_set_next_color_mode(cpicker, ext); - } - } - } - - return res; -} - -static lv_res_t lv_cpicker_rect_signal(lv_obj_t * cpicker, lv_signal_t sign, void * param, - lv_style_t * style, lv_cpicker_ext_t * ext) -{ - lv_res_t res; - - if(sign == LV_SIGNAL_PRESSED) - { - ext->prev_hsv = ext->hsv; - - lv_indev_t * indev = param; - - if(lv_area_is_point_on(&(ext->rect_preview_area), &indev->proc.types.pointer.act_point)) - { - res = lv_cpicker_reset_hsv_if_double_clicked(cpicker, ext); - if(res != LV_RES_OK) return res; - } - } - else if(sign == LV_SIGNAL_PRESSING) - { - lv_indev_t * indev = param; - - if(lv_area_is_point_on(&(ext->rect_gradient_area), &indev->proc.types.pointer.act_point)) - { - uint16_t width = ext->rect_gradient_area.x2 - ext->rect_gradient_area.x1; - uint16_t distance = indev->proc.types.pointer.act_point.x - ext->rect_gradient_area.x1; - float percent = distance / (float) width; - - res = lv_cpicker_set_hsv_percent(cpicker, ext, percent); - if(res != LV_RES_OK) return res; - } - } - else if(sign == LV_SIGNAL_RELEASED) - { - lv_indev_t * indev = param; - - if(lv_area_is_point_on(&(ext->rect_gradient_area), &indev->proc.types.pointer.act_point)) - { - uint16_t width = ext->rect_gradient_area.x2 - ext->rect_gradient_area.x1; - uint16_t distance = indev->proc.types.pointer.act_point.x - ext->rect_gradient_area.x1; - float percent = distance / (float) width; - - res = lv_cpicker_set_hsv_percent(cpicker, ext, percent); - if(res != LV_RES_OK) return res; - } - } - else if(sign == LV_SIGNAL_LONG_PRESS) - { - if(!ext->color_mode_fixed) - { - lv_indev_t * indev = param; - - if(lv_area_is_point_on(&(ext->rect_preview_area), &indev->proc.types.pointer.act_point)) - { - lv_cpicker_set_next_color_mode(cpicker, ext); - } - } - } - - return res; -} - - -static void lv_cpicker_invalidate_disc(lv_disp_t * disp, lv_style_t * style, - lv_cpicker_ext_t * ext, - lv_coord_t w, lv_coord_t h, - lv_coord_t cx, lv_coord_t cy, uint16_t r); -static void lv_cpicker_invalidate_rect(lv_disp_t * disp, lv_style_t * style, - lv_cpicker_ext_t * ext, - lv_coord_t w, lv_coord_t h); - -/** - * Indicator points need to match those set in lv_cpicker_disc_design/lv_cpicker_rect_design - */ -static void lv_cpicker_invalidate(lv_obj_t * cpicker, bool all) -{ - if (all) - { - lv_obj_invalidate(cpicker); - return; - } - - lv_disp_t * disp = lv_obj_get_disp(cpicker); - lv_cpicker_ext_t * ext = lv_obj_get_ext_attr(cpicker); - lv_style_t * style = lv_cpicker_get_style(cpicker, LV_CPICKER_STYLE_MAIN); - - lv_style_t styleCopy; - lv_style_copy(&styleCopy, style); - - lv_coord_t w = lv_obj_get_width(cpicker); - lv_coord_t h = lv_obj_get_height(cpicker); - - if(ext->type == LV_CPICKER_TYPE_DISC) - { - lv_coord_t cx = cpicker->coords.x1 + w / 2; - lv_coord_t cy = cpicker->coords.y1 + h / 2; - uint16_t r = LV_MATH_MIN(w, h) / 2; - lv_cpicker_invalidate_disc(disp, &styleCopy, ext, w, h, cx, cy, r); - } - else if(ext->type == LV_CPICKER_TYPE_RECT) - { - lv_cpicker_invalidate_rect(disp, &styleCopy, ext, w, h); - } -} - -/** - * Should roughly match up with `lv_cpicker_draw_disc_indicator_line` - */ -static void lv_cpicker_invalidate_disc_indicator_line(lv_disp_t * disp, lv_style_t * style, - lv_cpicker_ext_t * ext, - lv_coord_t cx, lv_coord_t cy, uint16_t r, - uint16_t angle) -{ - lv_coord_t x1 = cx + ((r - style->line.width + ext->indicator.style->body.padding.inner + ext->indicator.style->line.width/2) * lv_trigo_sin(angle) >> LV_TRIGO_SHIFT); - lv_coord_t y1 = cy + ((r - style->line.width + ext->indicator.style->body.padding.inner + ext->indicator.style->line.width/2) * lv_trigo_sin(angle + 90) >> LV_TRIGO_SHIFT); - lv_coord_t x2 = cx + ((r - ext->indicator.style->body.padding.inner - ext->indicator.style->line.width/2) * lv_trigo_sin(angle) >> LV_TRIGO_SHIFT); - lv_coord_t y2 = cy + ((r - ext->indicator.style->body.padding.inner - ext->indicator.style->line.width/2) * lv_trigo_sin(angle + 90) >> LV_TRIGO_SHIFT); - - lv_point_t point1, point2; - point1.x = x1; - point1.y = y1; - point2.x = x2; - point2.y = y2; - - lv_area_t line_area; - /*Steps less in y than x -> rather horizontal*/ - if(point1.x < point2.x) { - line_area.x1 = point1.x; - line_area.x2 = point2.x; - } else { - line_area.x1 = point2.x; - line_area.x2 = point1.x; - } - - /*Steps less in x than y -> rather vertical*/ - if(point1.y < point2.y) { - line_area.y1 = point1.y; - line_area.y2 = point2.y; - } else { - line_area.y1 = point2.y; - line_area.y2 = point1.y; - } - - line_area.x1 -= 2*ext->indicator.style->line.width; - line_area.y1 -= 2*ext->indicator.style->line.width; - line_area.x2 += 2*ext->indicator.style->line.width; - line_area.y2 += 2*ext->indicator.style->line.width; - - lv_inv_area(disp, &line_area); -} - -/** - * Should roughly match up with `lv_cpicker_draw_disc_indicator_circle` - */ -static void lv_cpicker_invalidate_disc_indicator_circle(lv_disp_t * disp, lv_style_t * style, - lv_cpicker_ext_t * ext, - lv_coord_t cx, lv_coord_t cy, uint16_t r, - uint16_t angle) -{ - uint32_t ind_cx = cx + ((r - style->line.width/2) * lv_trigo_sin(angle) >> LV_TRIGO_SHIFT); - uint32_t ind_cy = cy + ((r - style->line.width/2) * lv_trigo_sin(angle + 90) >> LV_TRIGO_SHIFT); - - lv_area_t ind_area; - ind_area.x1 = ind_cx - style->line.width/2; - ind_area.y1 = ind_cy - style->line.width/2; - ind_area.x2 = ind_cx + style->line.width/2; - ind_area.y2 = ind_cy + style->line.width/2; - - lv_inv_area(disp, &ind_area); -} - -/** - * Should roughly match up with `lv_cpicker_draw_disc_indicator_in` - */ -static void lv_cpicker_invalidate_disc_indicator_in(lv_disp_t * disp, lv_style_t * style, - lv_cpicker_ext_t * ext, - lv_coord_t x, lv_coord_t y, uint16_t r, - uint16_t rin, uint16_t angle) -{ - uint16_t ind_radius = lv_sqrt((4*rin*rin)/2)/2 + 1 - style->body.padding.inner; - ind_radius = (ind_radius + rin) / 2; - - uint16_t ind_cx = x + ((ind_radius) * lv_trigo_sin(angle) >> LV_TRIGO_SHIFT); - uint16_t ind_cy = y + ((ind_radius) * lv_trigo_sin(angle + 90) >> LV_TRIGO_SHIFT); - - lv_area_t ind_area; - ind_area.x1 = ind_cx - r; - ind_area.y1 = ind_cy - r; - ind_area.x2 = ind_cx + r; - ind_area.y2 = ind_cy + r; - - lv_inv_area(disp, &ind_area); -} - -/** - * Should roughly match up with `lv_cpicker_disc_design` - */ -static void lv_cpicker_invalidate_disc(lv_disp_t * disp, lv_style_t * style, - lv_cpicker_ext_t * ext, - lv_coord_t w, lv_coord_t h, - lv_coord_t cx, lv_coord_t cy, uint16_t r) -{ - /*invalidate center color area*/ - uint16_t rin = r - style->line.width; - /* - the square area (a and b being sides) should fit into the center of diameter d - we have: - a^2+b^2<=d^2 - 2a^2 <= d^2 - a^2<=(d^2)/2 - a <= sqrt((d^2)/2) - */ - uint16_t radius = lv_sqrt((4*rin*rin)/2)/2 + 1 - style->body.padding.inner; - - lv_area_t center_color_area; - center_color_area.x1 = cx - radius; - center_color_area.y1 = cy - radius; - center_color_area.x2 = cx + radius; - center_color_area.y2 = cy + radius; - - lv_inv_area(disp, ¢er_color_area); - - /*invalidate indicator*/ - uint16_t angle = mode_color_to_angle(ext); - switch(ext->indicator.type) - { - case LV_CPICKER_INDICATOR_LINE: - lv_cpicker_invalidate_disc_indicator_line(disp, style, ext, cx, cy, r, angle); - lv_cpicker_invalidate_disc_indicator_line(disp, style, ext, cx, cy, r, ext->prev_pos); - break; - case LV_CPICKER_INDICATOR_CIRCLE: - lv_cpicker_invalidate_disc_indicator_circle(disp, style, ext, cx, cy, r, angle); - lv_cpicker_invalidate_disc_indicator_circle(disp, style, ext, cx, cy, r, ext->prev_pos); - break; - case LV_CPICKER_INDICATOR_IN: - lv_cpicker_invalidate_disc_indicator_in(disp, style, ext, cx, cy, (rin - radius) / 3, rin, angle); - lv_cpicker_invalidate_disc_indicator_in(disp, style, ext, cx, cy, (rin - radius) / 3, rin, ext->prev_pos); - break; - } -} - -/** - * Should roughly match up with `lv_cpicker_draw_rect_indicator_line` - */ -static void lv_cpicker_invalidate_rect_indicator_line(lv_disp_t * disp, - lv_cpicker_ext_t * ext, - lv_coord_t ind_pos) -{ - lv_area_t line_area; - line_area.x1 = ext->rect_gradient_area.x1 + ind_pos - ext->indicator.style->line.width; - line_area.y1 = ext->rect_gradient_area.y1; - line_area.x2 = ext->rect_gradient_area.x1 + ind_pos + ext->indicator.style->line.width; - line_area.y2 = ext->rect_gradient_area.y2; - - lv_inv_area(disp, &line_area); -} - -/** - * Should roughly match up with `lv_cpicker_draw_rect_indicator_circle` - */ -static void lv_cpicker_invalidate_rect_indicator_circle(lv_disp_t * disp, - lv_cpicker_ext_t * ext, - lv_coord_t ind_pos) -{ - lv_area_t circle_ind_area; - circle_ind_area.x1 = ext->rect_gradient_area.x1 + ind_pos - ext->rect_gradient_h/2; - circle_ind_area.x2 = circle_ind_area.x1 + ext->rect_gradient_h; - circle_ind_area.y1 = ext->rect_gradient_area.y1; - circle_ind_area.y2 = ext->rect_gradient_area.y2; - - lv_inv_area(disp, &circle_ind_area); -} - -/** - * Should roughly match up with `lv_cpicker_draw_rect_indicator_in` - */ -static void lv_cpicker_invalidate_rect_indicator_in(lv_disp_t * disp, - lv_cpicker_ext_t * ext, - lv_coord_t ind_pos) -{ - lv_coord_t center = ext->rect_gradient_area.x1 + ind_pos; - - lv_area_t ind_area; - ind_area.x1 = center - ext->indicator.style->line.width * 3; - ind_area.y1 = ext->rect_gradient_area.y1 - 1; - ind_area.x2 = center + ext->indicator.style->line.width * 3; - ind_area.y2 = ext->rect_gradient_area.y2; - - lv_inv_area(disp, &ind_area); -} - -/** - * Should roughly match up with `lv_cpicker_rect_design` - */ -static void lv_cpicker_invalidate_rect(lv_disp_t * disp, lv_style_t * style, - lv_cpicker_ext_t * ext, - lv_coord_t w, lv_coord_t h) -{ - /*invalidate color preview indicator*/ - lv_inv_area(disp, &ext->rect_preview_area); - - /*invalidate indicator*/ - lv_coord_t ind_pos = lv_cpicker_get_indicator_coord(style, ext); - switch(ext->indicator.type) - { - case LV_CPICKER_INDICATOR_LINE: - lv_cpicker_invalidate_rect_indicator_line(disp, ext, ind_pos); - lv_cpicker_invalidate_rect_indicator_line(disp, ext, ext->prev_pos); - break; - case LV_CPICKER_INDICATOR_CIRCLE: - lv_cpicker_invalidate_rect_indicator_circle(disp, ext, ind_pos); - lv_cpicker_invalidate_rect_indicator_circle(disp, ext, ext->prev_pos); - break; - case LV_CPICKER_INDICATOR_IN: - lv_cpicker_invalidate_rect_indicator_in(disp, ext, ind_pos); - lv_cpicker_invalidate_rect_indicator_in(disp, ext, ext->prev_pos); - break; - } -} - #endif /* LV_USE_CPICKER != 0 */ diff --git a/src/lv_objx/lv_cpicker.h b/src/lv_objx/lv_cpicker.h index 5a542dd02..a5fe5239a 100644 --- a/src/lv_objx/lv_cpicker.h +++ b/src/lv_objx/lv_cpicker.h @@ -30,13 +30,6 @@ extern "C" { /********************** * TYPEDEFS **********************/ -enum { - LV_CPICKER_INDICATOR_NONE, - LV_CPICKER_INDICATOR_LINE, - LV_CPICKER_INDICATOR_CIRCLE, - LV_CPICKER_INDICATOR_IN -}; -typedef uint8_t lv_cpicker_indicator_type_t; enum { LV_CPICKER_TYPE_RECT, @@ -56,21 +49,17 @@ typedef uint8_t lv_cpicker_color_mode_t; /*Data of colorpicker*/ typedef struct { lv_color_hsv_t hsv; - lv_color_hsv_t prev_hsv; - struct - { + struct { lv_style_t * style; - lv_cpicker_indicator_type_t type; - } indicator; + lv_point_t pos; + uint8_t colored :1; + + } indic; uint32_t last_click_time; - lv_area_t rect_preview_area; - lv_area_t rect_gradient_area; - lv_coord_t rect_gradient_w; - lv_coord_t rect_gradient_h; - uint16_t prev_pos; - lv_cpicker_color_mode_t color_mode:2; - uint8_t color_mode_fixed:1; - lv_cpicker_type_t type:1; + uint32_t last_change_time; + lv_cpicker_color_mode_t color_mode :2; + uint8_t color_mode_fixed :1; + lv_cpicker_type_t type :1; } lv_cpicker_ext_t; /*Styles*/ @@ -112,13 +101,6 @@ void lv_cpicker_set_type(lv_obj_t * chart, lv_cpicker_type_t type); */ void lv_cpicker_set_style(lv_obj_t * cpicker, lv_cpicker_style_t type, lv_style_t *style); -/** - * Set a type of a colorpicker indicator. - * @param cpicker pointer to colorpicker object - * @param type indicator type - */ -void lv_cpicker_set_indicator_type(lv_obj_t * cpicker, lv_cpicker_indicator_type_t type); - /** * Set the current hue of a colorpicker. * @param cpicker pointer to colorpicker object @@ -168,6 +150,13 @@ void lv_cpicker_set_color_mode(lv_obj_t * cpicker, lv_cpicker_color_mode_t mode) */ void lv_cpicker_set_color_mode_fixed(lv_obj_t * cpicker, bool fixed); +/** + * Make the indicator to be colored to the current color + * @param cpicker pointer to colorpicker object + * @param en true: color the indicator; false: not color the indicator + */ +void lv_cpicker_set_indic_colored(lv_obj_t * cpicker, bool en); + /*===================== * Getter functions *====================*/ @@ -192,7 +181,7 @@ bool lv_cpicker_get_color_mode_fixed(lv_obj_t * cpicker); * @param type which style should be get * @return pointer to the style */ -lv_style_t * lv_cpicker_get_style(const lv_obj_t * cpicker, lv_cpicker_style_t type); +const lv_style_t * lv_cpicker_get_style(const lv_obj_t * cpicker, lv_cpicker_style_t type); /** * Get the current hue of a colorpicker. @@ -229,6 +218,13 @@ lv_color_hsv_t lv_cpicker_get_hsv(lv_obj_t * cpicker); */ lv_color_t lv_cpicker_get_color(lv_obj_t * cpicker); +/** + * Whether the indicator is colored to the current color or not + * @param cpicker pointer to colorpicker object + * @return true: color the indicator; false: not color the indicator + */ +bool lv_cpicker_get_indic_colored(lv_obj_t * cpicker); + /*===================== * Other functions *====================*/ From eda607d82466a5f3316c0c24c6cd60525ffe58a4 Mon Sep 17 00:00:00 2001 From: Gabor Kiss-Vamosi Date: Tue, 1 Oct 2019 22:00:23 +0200 Subject: [PATCH 32/82] cpicker: minor fixes --- src/lv_objx/lv_cpicker.c | 71 ++++++++++++++++++++++------------------ src/lv_objx/lv_cpicker.h | 1 + 2 files changed, 41 insertions(+), 31 deletions(-) diff --git a/src/lv_objx/lv_cpicker.c b/src/lv_objx/lv_cpicker.c index 6c97f61a0..dae87bff8 100644 --- a/src/lv_objx/lv_cpicker.c +++ b/src/lv_objx/lv_cpicker.c @@ -107,7 +107,7 @@ lv_obj_t * lv_cpicker_create(lv_obj_t * par, const lv_obj_t * copy) /*Initialize the allocated 'ext' */ ext->hsv = LV_CPICKER_DEF_HSV; ext->indic.style = &lv_style_plain; - ext->indic.colored = 1; + ext->indic.colored = 0; ext->color_mode = LV_CPICKER_COLOR_MODE_HUE; ext->color_mode_fixed = 0; ext->last_click_time = 0; @@ -807,13 +807,24 @@ static lv_res_t lv_cpicker_signal(lv_obj_t * cpicker, lv_signal_t sign, void * p } } else if(sign == LV_SIGNAL_PRESSED) { - res = double_click_reset(cpicker); ext->last_change_time = lv_tick_get(); + lv_indev_get_point(lv_indev_get_act(), &ext->last_press_point); + res = double_click_reset(cpicker); if(res != LV_RES_OK) return res; } else if(sign == LV_SIGNAL_PRESSING){ lv_indev_t * indev = lv_indev_get_act(); + if(indev == NULL) return res; + lv_point_t p; lv_indev_get_point(indev, &p); + + if((LV_MATH_ABS(p.x - ext->last_press_point.x) > indev->driver.drag_limit / 2) || + (LV_MATH_ABS(p.y - ext->last_press_point.y) > indev->driver.drag_limit / 2)) { + ext->last_change_time = lv_tick_get(); + ext->last_press_point.x = p.x; + ext->last_press_point.y = p.y; + } + p.x -= cpicker->coords.x1; p.y -= cpicker->coords.y1; @@ -823,57 +834,54 @@ static lv_res_t lv_cpicker_signal(lv_obj_t * cpicker, lv_signal_t sign, void * p int16_t angle = 0; if(ext->type == LV_CPICKER_TYPE_RECT) { + /*If pressed long enough without change go to next color mode*/ + uint32_t diff = lv_tick_elaps(ext->last_change_time); + if(diff > indev->driver.long_press_time * 2 && !ext->color_mode_fixed) { + next_color_mode(cpicker); + lv_indev_wait_release(lv_indev_get_act()); + return res; + } + angle = (p.x * 360) / w; if(angle < 0) angle = 0; if(angle >= 360) angle = 359; } else if(ext->type == LV_CPICKER_TYPE_DISC) { const lv_style_t * style_main = lv_cpicker_get_style(cpicker, LV_CPICKER_STYLE_MAIN); - lv_coord_t r = w / 2; - p.x -= r; - p.y -= r; - r -= style_main->line.width; - if(p.x * p.x + p.y * p.y < r * r) return res; + lv_coord_t r_in = w / 2; + p.x -= r_in; + p.y -= r_in; + r_in -= style_main->line.width * 2; /* *2 to let some sensitive space inside*/ + + /*If the inner area is being pressed, go to the next color mode on long press*/ + if(p.x * p.x + p.y * p.y < r_in * r_in) { + uint32_t diff = lv_tick_elaps(ext->last_change_time); + if(diff > indev->driver.long_press_time * 2 && !ext->color_mode_fixed) { + next_color_mode(cpicker); + lv_indev_wait_release(lv_indev_get_act()); + } + return res; + } angle = lv_atan2(p.x, p.y) % 360; } - bool changed = false; switch(ext->color_mode) { case LV_CPICKER_COLOR_MODE_HUE: - if(ext->hsv.h != angle) { - lv_cpicker_set_hue(cpicker, angle); - changed = true; - } + if(ext->hsv.h != angle) lv_cpicker_set_hue(cpicker, angle); break; case LV_CPICKER_COLOR_MODE_SATURATION: angle = (angle * 100) / 360; - if(ext->hsv.s != angle) { - lv_cpicker_set_saturation(cpicker, angle); - changed = true; - } + if(ext->hsv.s != angle) lv_cpicker_set_saturation(cpicker, angle); break; case LV_CPICKER_COLOR_MODE_VALUE: angle = (angle * 100) / 360; - if(ext->hsv.v != angle) { - lv_cpicker_set_value(cpicker, angle); - changed = true; - } + if(ext->hsv.v != angle) lv_cpicker_set_value(cpicker, angle); break; } refr_indic_pos(cpicker); - uint32_t diff = lv_tick_elaps(ext->last_change_time); - if(diff > indev->driver.long_press_time * 2 && !ext->color_mode_fixed) { - next_color_mode(cpicker); - lv_indev_wait_release(lv_indev_get_act()); - } - - if(changed) { - ext->last_change_time = lv_tick_get(); - } - res = lv_event_send(cpicker, LV_EVENT_VALUE_CHANGED, NULL); if(res != LV_RES_OK) return res; } @@ -895,6 +903,7 @@ static void next_color_mode(lv_obj_t * cpicker ) */ static void invalidate_indic(lv_obj_t * cpicker) { + lv_cpicker_ext_t * ext = lv_obj_get_ext_attr(cpicker); const lv_style_t * style_main = lv_cpicker_get_style(cpicker, LV_CPICKER_STYLE_MAIN); const lv_style_t * style_indic = lv_cpicker_get_style(cpicker, LV_CPICKER_STYLE_INDICATOR); @@ -907,7 +916,7 @@ static void invalidate_indic(lv_obj_t * cpicker) lv_area_t indic_area; indic_area.x1 = cpicker->coords.x1 + ext->indic.pos.x - r - style_indic->body.padding.left; - indic_area.y1 = cpicker->coords.x1 + ext->indic.pos.y - r - style_indic->body.padding.top; + indic_area.y1 = cpicker->coords.y1 + ext->indic.pos.y - r - style_indic->body.padding.top; indic_area.x2 = cpicker->coords.x1 + ext->indic.pos.x + r + style_indic->body.padding.right; indic_area.y2 = cpicker->coords.y1 + ext->indic.pos.y + r + style_indic->body.padding.bottom; diff --git a/src/lv_objx/lv_cpicker.h b/src/lv_objx/lv_cpicker.h index a5fe5239a..0e6bea594 100644 --- a/src/lv_objx/lv_cpicker.h +++ b/src/lv_objx/lv_cpicker.h @@ -57,6 +57,7 @@ typedef struct { } indic; uint32_t last_click_time; uint32_t last_change_time; + lv_point_t last_press_point; lv_cpicker_color_mode_t color_mode :2; uint8_t color_mode_fixed :1; lv_cpicker_type_t type :1; From 10d90a8baa36f0fc2da68492b4c9c34891bdcd88 Mon Sep 17 00:00:00 2001 From: Gabor Kiss-Vamosi Date: Tue, 1 Oct 2019 22:08:14 +0200 Subject: [PATCH 33/82] cpicker: minor fixes --- src/lv_objx/lv_cpicker.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/lv_objx/lv_cpicker.c b/src/lv_objx/lv_cpicker.c index dae87bff8..23dbd6a30 100644 --- a/src/lv_objx/lv_cpicker.c +++ b/src/lv_objx/lv_cpicker.c @@ -851,12 +851,18 @@ static lv_res_t lv_cpicker_signal(lv_obj_t * cpicker, lv_signal_t sign, void * p lv_coord_t r_in = w / 2; p.x -= r_in; p.y -= r_in; - r_in -= style_main->line.width * 2; /* *2 to let some sensitive space inside*/ + r_in -= style_main->line.width; + + if(r_in > LV_DPI / 2) { + r_in -= style_main->line.width; /* to let some sensitive space inside*/ + + if(r_in < LV_DPI / 2) r_in = LV_DPI / 2; + } /*If the inner area is being pressed, go to the next color mode on long press*/ if(p.x * p.x + p.y * p.y < r_in * r_in) { uint32_t diff = lv_tick_elaps(ext->last_change_time); - if(diff > indev->driver.long_press_time * 2 && !ext->color_mode_fixed) { + if(diff > indev->driver.long_press_time && !ext->color_mode_fixed) { next_color_mode(cpicker); lv_indev_wait_release(lv_indev_get_act()); } From 11d5fcb9ae7a1900337841f239a0422e84620ace Mon Sep 17 00:00:00 2001 From: Gabor Kiss-Vamosi Date: Wed, 2 Oct 2019 08:32:10 +0200 Subject: [PATCH 34/82] cpicker: on double click reset only the current color mode --- src/lv_objx/lv_cpicker.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/lv_objx/lv_cpicker.c b/src/lv_objx/lv_cpicker.c index 23dbd6a30..0e3749556 100644 --- a/src/lv_objx/lv_cpicker.c +++ b/src/lv_objx/lv_cpicker.c @@ -973,7 +973,17 @@ static lv_res_t double_click_reset(lv_obj_t * cpicker) lv_indev_t * indev = lv_indev_get_act(); /*Double clicked? Use long press time as double click time out*/ if(lv_tick_elaps(ext->last_click_time) < indev->driver.long_press_time) { - lv_cpicker_set_hsv(cpicker, LV_CPICKER_DEF_HSV); + switch(ext->color_mode) { + case LV_CPICKER_COLOR_MODE_HUE: + lv_cpicker_set_hue(cpicker, LV_CPICKER_DEF_HUE); + break; + case LV_CPICKER_COLOR_MODE_SATURATION: + lv_cpicker_set_hue(cpicker, LV_CPICKER_DEF_SATURATION); + break; + case LV_CPICKER_COLOR_MODE_VALUE: + lv_cpicker_set_hue(cpicker, LV_CPICKER_DEF_VALUE); + break; + } lv_res_t res; res = lv_event_send(cpicker, LV_EVENT_VALUE_CHANGED, NULL); From e8625aaf65e5f212c630a060247bec102a7113a1 Mon Sep 17 00:00:00 2001 From: Gabor Kiss-Vamosi Date: Wed, 2 Oct 2019 09:02:43 +0200 Subject: [PATCH 35/82] add cpicker to lv_conf_template.h --- lv_conf_template.h | 3 +++ src/lv_conf_checker.h | 5 +++++ 2 files changed, 8 insertions(+) diff --git a/lv_conf_template.h b/lv_conf_template.h index f1f06fe07..c67e1fad6 100644 --- a/lv_conf_template.h +++ b/lv_conf_template.h @@ -411,6 +411,9 @@ typedef void * lv_obj_user_data_t; /*Container (dependencies: -*/ #define LV_USE_CONT 1 +/*Color picker (dependencies: -*/ +#define LV_USE_CPICKER 1 + /*Drop down list (dependencies: lv_page, lv_label, lv_symbol_def.h)*/ #define LV_USE_DDLIST 1 #if LV_USE_DDLIST != 0 diff --git a/src/lv_conf_checker.h b/src/lv_conf_checker.h index 7accfd259..87905400c 100644 --- a/src/lv_conf_checker.h +++ b/src/lv_conf_checker.h @@ -579,6 +579,11 @@ #define LV_USE_CONT 1 #endif +/*Color picker (dependencies: -*/ +#ifndef LV_USE_CPICKER +#define LV_USE_CPICKER 1 +#endif + /*Drop down list (dependencies: lv_page, lv_label, lv_symbol_def.h)*/ #ifndef LV_USE_DDLIST #define LV_USE_DDLIST 1 From d4196c75349fedc495a0ab26c485308e67ef562b Mon Sep 17 00:00:00 2001 From: Gabor Kiss-Vamosi Date: Wed, 2 Oct 2019 16:47:08 +0200 Subject: [PATCH 36/82] cpicker: add preview feature --- src/lv_objx/lv_cpicker.c | 44 ++++++++++++++++++++++++++++++++++++++++ src/lv_objx/lv_cpicker.h | 15 ++++++++++++++ 2 files changed, 59 insertions(+) diff --git a/src/lv_objx/lv_cpicker.c b/src/lv_objx/lv_cpicker.c index 0e3749556..d7e30d5d5 100644 --- a/src/lv_objx/lv_cpicker.c +++ b/src/lv_objx/lv_cpicker.c @@ -110,7 +110,9 @@ lv_obj_t * lv_cpicker_create(lv_obj_t * par, const lv_obj_t * copy) ext->indic.colored = 0; ext->color_mode = LV_CPICKER_COLOR_MODE_HUE; ext->color_mode_fixed = 0; + ext->preview = 0; ext->last_click_time = 0; + ext->last_change_time = 0; /*The signal and design functions are not copied so set them here*/ lv_obj_set_signal_cb(new_cpicker, lv_cpicker_signal); @@ -133,6 +135,7 @@ lv_obj_t * lv_cpicker_create(lv_obj_t * par, const lv_obj_t * copy) ext->type = copy_ext->type; ext->color_mode = copy_ext->color_mode; ext->color_mode_fixed = copy_ext->color_mode_fixed; + ext->preview = copy_ext->preview; ext->hsv = copy_ext->hsv; ext->indic.colored = copy_ext->indic.colored; ext->indic.style = copy_ext->indic.style; @@ -314,6 +317,19 @@ void lv_cpicker_set_indic_colored(lv_obj_t * cpicker, bool en) invalidate_indic(cpicker); } +/** + * Add a color preview in the middle of the DISC type color picker + * @param cpicker pointer to colorpicker object + * @param en true: enable preview; false: disable preview + */ +void lv_cpicker_set_preview(lv_obj_t * cpicker, bool en) +{ + LV_ASSERT_OBJ(cpicker, LV_OBJX_NAME); + + lv_cpicker_ext_t * ext = lv_obj_get_ext_attr(cpicker); + ext->preview = en ? 1 : 0; + lv_obj_invalidate(cpicker); +} /*===================== * Getter functions *====================*/ @@ -455,6 +471,21 @@ bool lv_cpicker_get_indic_colored(lv_obj_t * cpicker) return ext->indic.colored ? true : false; } +/** + * Whether the preview is enabled or not + * @param cpicker pointer to colorpicker object + * @return en true: preview is enabled; false: preview is disabled + */ +bool lv_cpicker_get_preview(lv_obj_t * cpicker) +{ + LV_ASSERT_OBJ(cpicker, LV_OBJX_NAME); + + lv_cpicker_ext_t * ext = lv_obj_get_ext_attr(cpicker); + + return ext->preview ? true : false; +} + + /*===================== * Other functions *====================*/ @@ -502,6 +533,7 @@ static bool lv_cpicker_design(lv_obj_t * cpicker, const lv_area_t * mask, lv_des static void draw_disc_grad(lv_obj_t * cpicker, const lv_area_t * mask, lv_opa_t opa_scale) { + lv_cpicker_ext_t * ext = lv_obj_get_ext_attr(cpicker); int16_t start_angle = 0; /*Default*/ int16_t end_angle = 360 - LV_CPICKER_DEF_QF; /*Default*/ @@ -625,6 +657,18 @@ static void draw_disc_grad(lv_obj_t * cpicker, const lv_area_t * mask, lv_opa_t area_mid.y2 -= style_main->line.width; lv_draw_rect(&area_mid, mask, &style, opa_scale); + + if(ext->preview) { + lv_color_t color = lv_cpicker_get_color(cpicker); + style.body.main_color = color; + style.body.grad_color = color; + area_mid.x1 += style_main->line.width; + area_mid.y1 += style_main->line.width; + area_mid.x2 -= style_main->line.width; + area_mid.y2 -= style_main->line.width; + + lv_draw_rect(&area_mid, mask, &style, opa_scale); + } } static void draw_rect_grad(lv_obj_t * cpicker, const lv_area_t * mask, lv_opa_t opa_scale) diff --git a/src/lv_objx/lv_cpicker.h b/src/lv_objx/lv_cpicker.h index 0e6bea594..7bce0fec8 100644 --- a/src/lv_objx/lv_cpicker.h +++ b/src/lv_objx/lv_cpicker.h @@ -61,6 +61,7 @@ typedef struct { lv_cpicker_color_mode_t color_mode :2; uint8_t color_mode_fixed :1; lv_cpicker_type_t type :1; + uint8_t preview :1; } lv_cpicker_ext_t; /*Styles*/ @@ -158,6 +159,13 @@ void lv_cpicker_set_color_mode_fixed(lv_obj_t * cpicker, bool fixed); */ void lv_cpicker_set_indic_colored(lv_obj_t * cpicker, bool en); +/** + * Add a color preview in the middle of the DISC type color picker + * @param cpicker pointer to colorpicker object + * @param en true: enable preview; false: disable preview + */ +void lv_cpicker_set_preview(lv_obj_t * cpicker, bool en); + /*===================== * Getter functions *====================*/ @@ -226,6 +234,13 @@ lv_color_t lv_cpicker_get_color(lv_obj_t * cpicker); */ bool lv_cpicker_get_indic_colored(lv_obj_t * cpicker); +/** + * Whether the preview is enabled or not + * @param cpicker pointer to colorpicker object + * @return en true: preview is enabled; false: preview is disabled + */ +bool lv_cpicker_get_preview(lv_obj_t * cpicker); + /*===================== * Other functions *====================*/ From 434ef7e667b359188e5b5ef4278b3b8bf2de61ba Mon Sep 17 00:00:00 2001 From: Gabor Kiss-Vamosi Date: Wed, 2 Oct 2019 16:58:41 +0200 Subject: [PATCH 37/82] cpicker: minor fixes --- src/lv_objx/lv_cpicker.c | 27 +++++++++++++++++++-------- 1 file changed, 19 insertions(+), 8 deletions(-) diff --git a/src/lv_objx/lv_cpicker.c b/src/lv_objx/lv_cpicker.c index d7e30d5d5..467c62ee2 100644 --- a/src/lv_objx/lv_cpicker.c +++ b/src/lv_objx/lv_cpicker.c @@ -209,7 +209,11 @@ void lv_cpicker_set_hue(lv_obj_t * cpicker, uint16_t hue) ext->hsv.h = hue % 360; - if(ext->color_mode_fixed == LV_CPICKER_COLOR_MODE_HUE) refr_indic_pos(cpicker); + if(ext->color_mode == LV_CPICKER_COLOR_MODE_HUE) refr_indic_pos(cpicker); + + if(ext->preview && ext->type == LV_CPICKER_TYPE_DISC) { + lv_obj_invalidate(cpicker); + } } /** @@ -223,9 +227,13 @@ void lv_cpicker_set_saturation(lv_obj_t * cpicker, uint8_t saturation) lv_cpicker_ext_t * ext = lv_obj_get_ext_attr(cpicker); - ext->hsv.s = saturation % 100; + ext->hsv.s = saturation > 100 ? 100 : saturation; - if(ext->color_mode_fixed == LV_CPICKER_COLOR_MODE_SATURATION) refr_indic_pos(cpicker); + if(ext->color_mode == LV_CPICKER_COLOR_MODE_SATURATION) refr_indic_pos(cpicker); + + if(ext->preview && ext->type == LV_CPICKER_TYPE_DISC) { + lv_obj_invalidate(cpicker); + } } /** @@ -239,9 +247,13 @@ void lv_cpicker_set_value(lv_obj_t * cpicker, uint8_t val) lv_cpicker_ext_t * ext = lv_obj_get_ext_attr(cpicker); - ext->hsv.v = val % 100; + ext->hsv.v = val > 100 ? 100 : val; - if(ext->color_mode_fixed == LV_CPICKER_COLOR_MODE_VALUE) refr_indic_pos(cpicker); + if(ext->color_mode == LV_CPICKER_COLOR_MODE_VALUE) refr_indic_pos(cpicker); + + if(ext->preview && ext->type == LV_CPICKER_TYPE_DISC) { + lv_obj_invalidate(cpicker); + } } /** @@ -256,7 +268,6 @@ void lv_cpicker_set_hsv(lv_obj_t * cpicker, lv_color_hsv_t hsv) lv_cpicker_ext_t * ext = lv_obj_get_ext_attr(cpicker); ext->hsv = hsv; - refr_indic_pos(cpicker); lv_obj_invalidate(cpicker); } @@ -1022,10 +1033,10 @@ static lv_res_t double_click_reset(lv_obj_t * cpicker) lv_cpicker_set_hue(cpicker, LV_CPICKER_DEF_HUE); break; case LV_CPICKER_COLOR_MODE_SATURATION: - lv_cpicker_set_hue(cpicker, LV_CPICKER_DEF_SATURATION); + lv_cpicker_set_saturation(cpicker, LV_CPICKER_DEF_SATURATION); break; case LV_CPICKER_COLOR_MODE_VALUE: - lv_cpicker_set_hue(cpicker, LV_CPICKER_DEF_VALUE); + lv_cpicker_set_value(cpicker, LV_CPICKER_DEF_VALUE); break; } From 994057b578e4de6df752bed4acae02695c398a0e Mon Sep 17 00:00:00 2001 From: Paul Peavyhouse Date: Wed, 2 Oct 2019 15:25:25 -0700 Subject: [PATCH 38/82] Removing extra indentation --- src/lv_objx/lv_cpicker.c | 242 +++++++++++++++++++-------------------- 1 file changed, 121 insertions(+), 121 deletions(-) diff --git a/src/lv_objx/lv_cpicker.c b/src/lv_objx/lv_cpicker.c index 467c62ee2..3d367e9b5 100644 --- a/src/lv_objx/lv_cpicker.c +++ b/src/lv_objx/lv_cpicker.c @@ -544,142 +544,142 @@ static bool lv_cpicker_design(lv_obj_t * cpicker, const lv_area_t * mask, lv_des static void draw_disc_grad(lv_obj_t * cpicker, const lv_area_t * mask, lv_opa_t opa_scale) { - lv_cpicker_ext_t * ext = lv_obj_get_ext_attr(cpicker); - int16_t start_angle = 0; /*Default*/ - int16_t end_angle = 360 - LV_CPICKER_DEF_QF; /*Default*/ + lv_cpicker_ext_t * ext = lv_obj_get_ext_attr(cpicker); + int16_t start_angle = 0; /*Default*/ + int16_t end_angle = 360 - LV_CPICKER_DEF_QF; /*Default*/ - lv_coord_t w = lv_obj_get_width(cpicker); - lv_coord_t h = lv_obj_get_height(cpicker); - lv_coord_t cx = cpicker->coords.x1 + w / 2; - lv_coord_t cy = cpicker->coords.y1 + h / 2; - lv_coord_t r = w / 2; + lv_coord_t w = lv_obj_get_width(cpicker); + lv_coord_t h = lv_obj_get_height(cpicker); + lv_coord_t cx = cpicker->coords.x1 + w / 2; + lv_coord_t cy = cpicker->coords.y1 + h / 2; + lv_coord_t r = w / 2; - /*if the mask does not include the center of the object - * redrawing all the wheel is not necessary; - * only a given angular range - */ - lv_point_t center = {cx, cy}; - if(!lv_area_is_point_on(mask, ¢er)) - { - /*get angle from center of object to each corners of the area*/ - int16_t dr, ur, ul, dl; - dr = lv_atan2(mask->x2 - cx, mask->y2 - cy); - ur = lv_atan2(mask->x2 - cx, mask->y1 - cy); - ul = lv_atan2(mask->x1 - cx, mask->y1 - cy); - dl = lv_atan2(mask->x1 - cx, mask->y2 - cy); + /*if the mask does not include the center of the object + * redrawing all the wheel is not necessary; + * only a given angular range + */ + lv_point_t center = {cx, cy}; + if(!lv_area_is_point_on(mask, ¢er)) + { + /*get angle from center of object to each corners of the area*/ + int16_t dr, ur, ul, dl; + dr = lv_atan2(mask->x2 - cx, mask->y2 - cy); + ur = lv_atan2(mask->x2 - cx, mask->y1 - cy); + ul = lv_atan2(mask->x1 - cx, mask->y1 - cy); + dl = lv_atan2(mask->x1 - cx, mask->y2 - cy); - /*check area position from object axis*/ - bool left = (mask->x2 < cx && mask->x1 < cx) ? true : false; - bool onYaxis = (mask->x2 > cx && mask->x1 < cx) ? true : false; - bool right = (mask->x2 > cx && mask->x1 > cx) ? true : false; - bool top = (mask->y2 < cy && mask->y1 < cy) ? true : false; - bool onXaxis = (mask->y2 > cy && mask->y1 < cy) ? true : false; - bool bottom = (mask->y2 > cy && mask->y1 > cy) ? true : false; + /*check area position from object axis*/ + bool left = (mask->x2 < cx && mask->x1 < cx) ? true : false; + bool onYaxis = (mask->x2 > cx && mask->x1 < cx) ? true : false; + bool right = (mask->x2 > cx && mask->x1 > cx) ? true : false; + bool top = (mask->y2 < cy && mask->y1 < cy) ? true : false; + bool onXaxis = (mask->y2 > cy && mask->y1 < cy) ? true : false; + bool bottom = (mask->y2 > cy && mask->y1 > cy) ? true : false; - /*store angular range*/ - if(right && bottom) { - start_angle = dl; - end_angle = ur; - } - else if(right && onXaxis) { - start_angle = dl; - end_angle = ul; - } - else if(right && top) { - start_angle = dr; - end_angle = ul; - } - else if(onYaxis && top) { - start_angle = dr; - end_angle = dl; - } - else if(left && top) { - start_angle = ur; - end_angle = dl; - } - else if(left && onXaxis) { - start_angle = ur; - end_angle = dr; - } - else if(left && bottom) { - start_angle = ul; - end_angle = dr; - } - else if(onYaxis && bottom) { - start_angle = ul; - end_angle = ur; - } - - /*rollover angle*/ - if(start_angle > end_angle) end_angle += 360; - - /*round to QF factor*/ - start_angle = (start_angle/LV_CPICKER_DEF_QF) * LV_CPICKER_DEF_QF; - end_angle = (end_angle / LV_CPICKER_DEF_QF) * LV_CPICKER_DEF_QF; - - /*shift angle if necessary before adding offset*/ - if((start_angle - LV_CPICKER_DEF_QF) < 0) - { - start_angle += 360; - end_angle += 360; - } - - /*ensure overlapping by adding offset*/ - start_angle -= LV_CPICKER_DEF_QF; - end_angle += LV_CPICKER_DEF_QF; + /*store angular range*/ + if(right && bottom) { + start_angle = dl; + end_angle = ur; + } + else if(right && onXaxis) { + start_angle = dl; + end_angle = ul; + } + else if(right && top) { + start_angle = dr; + end_angle = ul; + } + else if(onYaxis && top) { + start_angle = dr; + end_angle = dl; + } + else if(left && top) { + start_angle = ur; + end_angle = dl; + } + else if(left && onXaxis) { + start_angle = ur; + end_angle = dr; + } + else if(left && bottom) { + start_angle = ul; + end_angle = dr; + } + else if(onYaxis && bottom) { + start_angle = ul; + end_angle = ur; } - lv_point_t triangle_points[3]; - lv_style_t style; - lv_style_copy(&style, &lv_style_plain); - for(uint16_t i = start_angle; i <= end_angle; i+= LV_CPICKER_DEF_QF) + /*rollover angle*/ + if(start_angle > end_angle) end_angle += 360; + + /*round to QF factor*/ + start_angle = (start_angle/LV_CPICKER_DEF_QF) * LV_CPICKER_DEF_QF; + end_angle = (end_angle / LV_CPICKER_DEF_QF) * LV_CPICKER_DEF_QF; + + /*shift angle if necessary before adding offset*/ + if((start_angle - LV_CPICKER_DEF_QF) < 0) { - style.body.main_color = angle_to_mode_color(cpicker, i); - style.body.grad_color = style.body.main_color; - - triangle_points[0].x = cx; - triangle_points[0].y = cy; - - triangle_points[1].x = cx + (r * lv_trigo_sin(i) >> LV_TRIGO_SHIFT); - triangle_points[1].y = cy + (r * lv_trigo_sin(i + 90) >> LV_TRIGO_SHIFT); - - if(i == end_angle || i == (360 - LV_CPICKER_DEF_QF)) { - /*the last triangle is drawn without additional overlapping pixels*/ - triangle_points[2].x = cx + (r * lv_trigo_sin(i + LV_CPICKER_DEF_QF) >> LV_TRIGO_SHIFT); - triangle_points[2].y = cy + (r * lv_trigo_sin(i + LV_CPICKER_DEF_QF + 90) >> LV_TRIGO_SHIFT); - } - else { - triangle_points[2].x = cx + (r * lv_trigo_sin(i + LV_CPICKER_DEF_QF + TRI_OFFSET) >> LV_TRIGO_SHIFT); - triangle_points[2].y = cy + (r * lv_trigo_sin(i + LV_CPICKER_DEF_QF + TRI_OFFSET + 90) >> LV_TRIGO_SHIFT); - } - - lv_draw_triangle(triangle_points, mask, &style, LV_OPA_COVER); + start_angle += 360; + end_angle += 360; } - /*Mask out the center area*/ - const lv_style_t * style_main = lv_cpicker_get_style(cpicker, LV_CPICKER_STYLE_MAIN); - lv_style_copy(&style, style_main); - style.body.radius = LV_RADIUS_CIRCLE; - lv_area_t area_mid; - lv_area_copy(&area_mid, &cpicker->coords); + /*ensure overlapping by adding offset*/ + start_angle -= LV_CPICKER_DEF_QF; + end_angle += LV_CPICKER_DEF_QF; + } + + lv_point_t triangle_points[3]; + lv_style_t style; + lv_style_copy(&style, &lv_style_plain); + for(uint16_t i = start_angle; i <= end_angle; i+= LV_CPICKER_DEF_QF) + { + style.body.main_color = angle_to_mode_color(cpicker, i); + style.body.grad_color = style.body.main_color; + + triangle_points[0].x = cx; + triangle_points[0].y = cy; + + triangle_points[1].x = cx + (r * lv_trigo_sin(i) >> LV_TRIGO_SHIFT); + triangle_points[1].y = cy + (r * lv_trigo_sin(i + 90) >> LV_TRIGO_SHIFT); + + if(i == end_angle || i == (360 - LV_CPICKER_DEF_QF)) { + /*the last triangle is drawn without additional overlapping pixels*/ + triangle_points[2].x = cx + (r * lv_trigo_sin(i + LV_CPICKER_DEF_QF) >> LV_TRIGO_SHIFT); + triangle_points[2].y = cy + (r * lv_trigo_sin(i + LV_CPICKER_DEF_QF + 90) >> LV_TRIGO_SHIFT); + } + else { + triangle_points[2].x = cx + (r * lv_trigo_sin(i + LV_CPICKER_DEF_QF + TRI_OFFSET) >> LV_TRIGO_SHIFT); + triangle_points[2].y = cy + (r * lv_trigo_sin(i + LV_CPICKER_DEF_QF + TRI_OFFSET + 90) >> LV_TRIGO_SHIFT); + } + + lv_draw_triangle(triangle_points, mask, &style, LV_OPA_COVER); + } + + /*Mask out the center area*/ + const lv_style_t * style_main = lv_cpicker_get_style(cpicker, LV_CPICKER_STYLE_MAIN); + lv_style_copy(&style, style_main); + style.body.radius = LV_RADIUS_CIRCLE; + lv_area_t area_mid; + lv_area_copy(&area_mid, &cpicker->coords); + area_mid.x1 += style_main->line.width; + area_mid.y1 += style_main->line.width; + area_mid.x2 -= style_main->line.width; + area_mid.y2 -= style_main->line.width; + + lv_draw_rect(&area_mid, mask, &style, opa_scale); + + if(ext->preview) { + lv_color_t color = lv_cpicker_get_color(cpicker); + style.body.main_color = color; + style.body.grad_color = color; area_mid.x1 += style_main->line.width; area_mid.y1 += style_main->line.width; area_mid.x2 -= style_main->line.width; area_mid.y2 -= style_main->line.width; lv_draw_rect(&area_mid, mask, &style, opa_scale); - - if(ext->preview) { - lv_color_t color = lv_cpicker_get_color(cpicker); - style.body.main_color = color; - style.body.grad_color = color; - area_mid.x1 += style_main->line.width; - area_mid.y1 += style_main->line.width; - area_mid.x2 -= style_main->line.width; - area_mid.y2 -= style_main->line.width; - - lv_draw_rect(&area_mid, mask, &style, opa_scale); - } + } } static void draw_rect_grad(lv_obj_t * cpicker, const lv_area_t * mask, lv_opa_t opa_scale) From b49edd91a2eb7462a384902de4413f7a9c9bf6d5 Mon Sep 17 00:00:00 2001 From: Paul Peavyhouse Date: Wed, 2 Oct 2019 16:21:44 -0700 Subject: [PATCH 39/82] All color setters use lv_cpicker_set_hsv and return bool for change --- src/lv_objx/lv_cpicker.c | 126 +++++++++++++++++++-------------------- src/lv_objx/lv_cpicker.h | 21 ++++--- 2 files changed, 74 insertions(+), 73 deletions(-) diff --git a/src/lv_objx/lv_cpicker.c b/src/lv_objx/lv_cpicker.c index 3d367e9b5..937b1b4c3 100644 --- a/src/lv_objx/lv_cpicker.c +++ b/src/lv_objx/lv_cpicker.c @@ -200,88 +200,79 @@ void lv_cpicker_set_style(lv_obj_t * cpicker, lv_cpicker_style_t type, lv_style_ * Set the current hue of a colorpicker. * @param cpicker pointer to colorpicker object * @param hue current selected hue [0..360] + * @return true if changed, otherwise false */ -void lv_cpicker_set_hue(lv_obj_t * cpicker, uint16_t hue) +bool lv_cpicker_set_hue(lv_obj_t * cpicker, uint16_t hue) { - LV_ASSERT_OBJ(cpicker, LV_OBJX_NAME); - - lv_cpicker_ext_t * ext = lv_obj_get_ext_attr(cpicker); - - ext->hsv.h = hue % 360; - - if(ext->color_mode == LV_CPICKER_COLOR_MODE_HUE) refr_indic_pos(cpicker); - - if(ext->preview && ext->type == LV_CPICKER_TYPE_DISC) { - lv_obj_invalidate(cpicker); - } + lv_color_hsv_t hsv = lv_cpicker_get_hsv(cpicker); + hsv.h = hue; + return lv_cpicker_set_hsv(cpicker, hsv); } /** * Set the current saturation of a colorpicker. * @param cpicker pointer to colorpicker object * @param saturation current selected saturation [0..100] + * @return true if changed, otherwise false */ -void lv_cpicker_set_saturation(lv_obj_t * cpicker, uint8_t saturation) +bool lv_cpicker_set_saturation(lv_obj_t * cpicker, uint8_t saturation) { - LV_ASSERT_OBJ(cpicker, LV_OBJX_NAME); - - lv_cpicker_ext_t * ext = lv_obj_get_ext_attr(cpicker); - - ext->hsv.s = saturation > 100 ? 100 : saturation; - - if(ext->color_mode == LV_CPICKER_COLOR_MODE_SATURATION) refr_indic_pos(cpicker); - - if(ext->preview && ext->type == LV_CPICKER_TYPE_DISC) { - lv_obj_invalidate(cpicker); - } + lv_color_hsv_t hsv = lv_cpicker_get_hsv(cpicker); + hsv.s = saturation; + return lv_cpicker_set_hsv(cpicker, hsv); } /** * Set the current value of a colorpicker. * @param cpicker pointer to colorpicker object * @param val current selected value [0..100] + * @return true if changed, otherwise false */ -void lv_cpicker_set_value(lv_obj_t * cpicker, uint8_t val) +bool lv_cpicker_set_value(lv_obj_t * cpicker, uint8_t val) { - LV_ASSERT_OBJ(cpicker, LV_OBJX_NAME); - - lv_cpicker_ext_t * ext = lv_obj_get_ext_attr(cpicker); - - ext->hsv.v = val > 100 ? 100 : val; - - if(ext->color_mode == LV_CPICKER_COLOR_MODE_VALUE) refr_indic_pos(cpicker); - - if(ext->preview && ext->type == LV_CPICKER_TYPE_DISC) { - lv_obj_invalidate(cpicker); - } + lv_color_hsv_t hsv = lv_cpicker_get_hsv(cpicker); + hsv.v = val; + return lv_cpicker_set_hsv(cpicker, hsv); } /** * Set the current hsv of a colorpicker. * @param cpicker pointer to colorpicker object * @param color current selected hsv + * @return true if changed, otherwise false */ -void lv_cpicker_set_hsv(lv_obj_t * cpicker, lv_color_hsv_t hsv) +bool lv_cpicker_set_hsv(lv_obj_t * cpicker, lv_color_hsv_t hsv) { LV_ASSERT_OBJ(cpicker, LV_OBJX_NAME); + if (hsv.h > 360) hsv.h %= 360; + if (hsv.s > 100) hsv.s = 100; + if (hsv.v > 100) hsv.v = 100; + lv_cpicker_ext_t * ext = lv_obj_get_ext_attr(cpicker); + if (ext->hsv.h == hsv.h && ext->hsv.s == hsv.s && ext->hsv.v == hsv.v) return false; + ext->hsv = hsv; + refr_indic_pos(cpicker); - lv_obj_invalidate(cpicker); + + if (ext->preview && ext->type == LV_CPICKER_TYPE_DISC) { + lv_obj_invalidate(cpicker); + } + + return true; } /** * Set the current color of a colorpicker. * @param cpicker pointer to colorpicker object * @param color current selected color + * @return true if changed, otherwise false */ -void lv_cpicker_set_color(lv_obj_t * cpicker, lv_color_t color) +bool lv_cpicker_set_color(lv_obj_t * cpicker, lv_color_t color) { - LV_ASSERT_OBJ(cpicker, LV_OBJX_NAME); - - lv_cpicker_set_hsv(cpicker, lv_color_rgb_to_hsv(color.ch.red, color.ch.green, color.ch.blue)); + return lv_cpicker_set_hsv(cpicker, lv_color_rgb_to_hsv(color.ch.red, color.ch.green, color.ch.blue)); } /** @@ -834,10 +825,10 @@ static lv_res_t lv_cpicker_signal(lv_obj_t * cpicker, lv_signal_t sign, void * p break; } - lv_cpicker_set_hsv(cpicker, hsv_cur); - - res = lv_event_send(cpicker, LV_EVENT_VALUE_CHANGED, NULL); - if(res != LV_RES_OK) return res; + if (lv_cpicker_set_hsv(cpicker, hsv_cur)) { + res = lv_event_send(cpicker, LV_EVENT_VALUE_CHANGED, NULL); + if(res != LV_RES_OK) return res; + } } else if(c == LV_KEY_LEFT || c == LV_KEY_DOWN) { lv_color_hsv_t hsv_cur; @@ -855,10 +846,10 @@ static lv_res_t lv_cpicker_signal(lv_obj_t * cpicker, lv_signal_t sign, void * p break; } - lv_cpicker_set_hsv(cpicker, hsv_cur); - - res = lv_event_send(cpicker, LV_EVENT_VALUE_CHANGED, NULL); - if(res != LV_RES_OK) return res; + if (lv_cpicker_set_hsv(cpicker, hsv_cur)) { + res = lv_event_send(cpicker, LV_EVENT_VALUE_CHANGED, NULL); + if(res != LV_RES_OK) return res; + } } } else if(sign == LV_SIGNAL_PRESSED) { @@ -927,24 +918,25 @@ static lv_res_t lv_cpicker_signal(lv_obj_t * cpicker, lv_signal_t sign, void * p angle = lv_atan2(p.x, p.y) % 360; } + lv_color_hsv_t hsv_cur; + hsv_cur = ext->hsv; + switch(ext->color_mode) { case LV_CPICKER_COLOR_MODE_HUE: - if(ext->hsv.h != angle) lv_cpicker_set_hue(cpicker, angle); + hsv_cur.h = angle; break; case LV_CPICKER_COLOR_MODE_SATURATION: - angle = (angle * 100) / 360; - if(ext->hsv.s != angle) lv_cpicker_set_saturation(cpicker, angle); + hsv_cur.s = (angle * 100) / 360; break; case LV_CPICKER_COLOR_MODE_VALUE: - angle = (angle * 100) / 360; - if(ext->hsv.v != angle) lv_cpicker_set_value(cpicker, angle); + hsv_cur.v = (angle * 100) / 360; break; } - refr_indic_pos(cpicker); - - res = lv_event_send(cpicker, LV_EVENT_VALUE_CHANGED, NULL); - if(res != LV_RES_OK) return res; + if (lv_cpicker_set_hsv(cpicker, hsv_cur)) { + res = lv_event_send(cpicker, LV_EVENT_VALUE_CHANGED, NULL); + if(res != LV_RES_OK) return res; + } } return res; @@ -1028,21 +1020,25 @@ static lv_res_t double_click_reset(lv_obj_t * cpicker) lv_indev_t * indev = lv_indev_get_act(); /*Double clicked? Use long press time as double click time out*/ if(lv_tick_elaps(ext->last_click_time) < indev->driver.long_press_time) { + lv_color_hsv_t hsv_cur; + hsv_cur = ext->hsv; + switch(ext->color_mode) { case LV_CPICKER_COLOR_MODE_HUE: - lv_cpicker_set_hue(cpicker, LV_CPICKER_DEF_HUE); + hsv_cur.h = LV_CPICKER_DEF_HUE; break; case LV_CPICKER_COLOR_MODE_SATURATION: - lv_cpicker_set_saturation(cpicker, LV_CPICKER_DEF_SATURATION); + hsv_cur.s = LV_CPICKER_DEF_SATURATION; break; case LV_CPICKER_COLOR_MODE_VALUE: - lv_cpicker_set_value(cpicker, LV_CPICKER_DEF_VALUE); + hsv_cur.v = LV_CPICKER_DEF_VALUE; break; } - lv_res_t res; - res = lv_event_send(cpicker, LV_EVENT_VALUE_CHANGED, NULL); - if(res != LV_RES_OK) return res; + if (lv_cpicker_set_hsv(cpicker, hsv_cur)) { + lv_res_t res = lv_event_send(cpicker, LV_EVENT_VALUE_CHANGED, NULL); + if(res != LV_RES_OK) return res; + } } ext->last_click_time = lv_tick_get(); diff --git a/src/lv_objx/lv_cpicker.h b/src/lv_objx/lv_cpicker.h index 7bce0fec8..8ca26dacd 100644 --- a/src/lv_objx/lv_cpicker.h +++ b/src/lv_objx/lv_cpicker.h @@ -106,37 +106,42 @@ void lv_cpicker_set_style(lv_obj_t * cpicker, lv_cpicker_style_t type, lv_style_ /** * Set the current hue of a colorpicker. * @param cpicker pointer to colorpicker object - * @param hue current selected hue + * @param hue current selected hue [0..360] + * @return true if changed, otherwise false */ -void lv_cpicker_set_hue(lv_obj_t * cpicker, uint16_t hue); +bool lv_cpicker_set_hue(lv_obj_t * cpicker, uint16_t hue); /** * Set the current saturation of a colorpicker. * @param cpicker pointer to colorpicker object - * @param saturation current selected saturation + * @param saturation current selected saturation [0..100] + * @return true if changed, otherwise false */ -void lv_cpicker_set_saturation(lv_obj_t * cpicker, uint8_t saturation); +bool lv_cpicker_set_saturation(lv_obj_t * cpicker, uint8_t saturation); /** * Set the current value of a colorpicker. * @param cpicker pointer to colorpicker object - * @param val current selected value + * @param val current selected value [0..100] + * @return true if changed, otherwise false */ -void lv_cpicker_set_value(lv_obj_t * cpicker, uint8_t val); +bool lv_cpicker_set_value(lv_obj_t * cpicker, uint8_t val); /** * Set the current hsv of a colorpicker. * @param cpicker pointer to colorpicker object * @param hsv current selected hsv + * @return true if changed, otherwise false */ -void lv_cpicker_set_hsv(lv_obj_t * cpicker, lv_color_hsv_t hsv); +bool lv_cpicker_set_hsv(lv_obj_t * cpicker, lv_color_hsv_t hsv); /** * Set the current color of a colorpicker. * @param cpicker pointer to colorpicker object * @param color current selected color + * @return true if changed, otherwise false */ -void lv_cpicker_set_color(lv_obj_t * cpicker, lv_color_t color); +bool lv_cpicker_set_color(lv_obj_t * cpicker, lv_color_t color); /** * Set the current color mode. From c74e6a6207b9f4c02410cf25e592c224f90f477f Mon Sep 17 00:00:00 2001 From: Paul Peavyhouse Date: Wed, 2 Oct 2019 21:14:28 -0700 Subject: [PATCH 40/82] Shrinking the gap between outer ring and inner preview a little --- src/lv_misc/lv_area.c | 13 +++++++++++++ src/lv_misc/lv_area.h | 7 +++++++ src/lv_objx/lv_cpicker.c | 10 ++-------- 3 files changed, 22 insertions(+), 8 deletions(-) diff --git a/src/lv_misc/lv_area.c b/src/lv_misc/lv_area.c index 025e1733e..de649c5b0 100644 --- a/src/lv_misc/lv_area.c +++ b/src/lv_misc/lv_area.c @@ -192,6 +192,19 @@ bool lv_area_is_in(const lv_area_t * ain_p, const lv_area_t * aholder_p) return is_in; } +/** + * Increment or decrement an area's size by a single amount + * @param a_p pointer to an area to grow + * @param amount amount to increment the area, or negative to decrement + */ +void lv_area_increment(lv_area_t * a_p, const lv_coord_t amount) +{ + a_p->x1 -= amount; + a_p->y1 -= amount; + a_p->x2 += amount; + a_p->y2 += amount; +} + /********************** * STATIC FUNCTIONS **********************/ diff --git a/src/lv_misc/lv_area.h b/src/lv_misc/lv_area.h index 30b62cbec..3f8e8446a 100644 --- a/src/lv_misc/lv_area.h +++ b/src/lv_misc/lv_area.h @@ -165,6 +165,13 @@ bool lv_area_is_on(const lv_area_t * a1_p, const lv_area_t * a2_p); */ bool lv_area_is_in(const lv_area_t * ain_p, const lv_area_t * aholder_p); +/** + * Increment or decrement an area's size by a single amount + * @param a_p pointer to an area to grow + * @param amount amount to increment the area, or negative to decrement + */ +void lv_area_increment(lv_area_t * a_p, const lv_coord_t amount); + /********************** * MACROS **********************/ diff --git a/src/lv_objx/lv_cpicker.c b/src/lv_objx/lv_cpicker.c index 937b1b4c3..d4c259148 100644 --- a/src/lv_objx/lv_cpicker.c +++ b/src/lv_objx/lv_cpicker.c @@ -653,10 +653,7 @@ static void draw_disc_grad(lv_obj_t * cpicker, const lv_area_t * mask, lv_opa_t style.body.radius = LV_RADIUS_CIRCLE; lv_area_t area_mid; lv_area_copy(&area_mid, &cpicker->coords); - area_mid.x1 += style_main->line.width; - area_mid.y1 += style_main->line.width; - area_mid.x2 -= style_main->line.width; - area_mid.y2 -= style_main->line.width; + lv_area_increment(&area_mid, -style_main->line.width); lv_draw_rect(&area_mid, mask, &style, opa_scale); @@ -664,10 +661,7 @@ static void draw_disc_grad(lv_obj_t * cpicker, const lv_area_t * mask, lv_opa_t lv_color_t color = lv_cpicker_get_color(cpicker); style.body.main_color = color; style.body.grad_color = color; - area_mid.x1 += style_main->line.width; - area_mid.y1 += style_main->line.width; - area_mid.x2 -= style_main->line.width; - area_mid.y2 -= style_main->line.width; + lv_area_increment(&area_mid, -style_main->line.width / 2); lv_draw_rect(&area_mid, mask, &style, opa_scale); } From ca9c4c8fda5183715596f54e3cc96c422d4c2080 Mon Sep 17 00:00:00 2001 From: Paul Peavyhouse Date: Thu, 3 Oct 2019 03:11:38 -0700 Subject: [PATCH 41/82] Code formatting --- src/lv_objx/lv_cpicker.c | 49 +++++++++++++++------------------------- 1 file changed, 18 insertions(+), 31 deletions(-) diff --git a/src/lv_objx/lv_cpicker.c b/src/lv_objx/lv_cpicker.c index d4c259148..898982142 100644 --- a/src/lv_objx/lv_cpicker.c +++ b/src/lv_objx/lv_cpicker.c @@ -571,46 +571,38 @@ static void draw_disc_grad(lv_obj_t * cpicker, const lv_area_t * mask, lv_opa_t if(right && bottom) { start_angle = dl; end_angle = ur; - } - else if(right && onXaxis) { + } else if(right && onXaxis) { start_angle = dl; end_angle = ul; - } - else if(right && top) { + } else if(right && top) { start_angle = dr; end_angle = ul; - } - else if(onYaxis && top) { + } else if(onYaxis && top) { start_angle = dr; end_angle = dl; - } - else if(left && top) { + } else if(left && top) { start_angle = ur; end_angle = dl; - } - else if(left && onXaxis) { + } else if(left && onXaxis) { start_angle = ur; end_angle = dr; - } - else if(left && bottom) { + } else if(left && bottom) { start_angle = ul; end_angle = dr; - } - else if(onYaxis && bottom) { + } else if(onYaxis && bottom) { start_angle = ul; end_angle = ur; } /*rollover angle*/ - if(start_angle > end_angle) end_angle += 360; + if(start_angle > end_angle) end_angle += 360; /*round to QF factor*/ start_angle = (start_angle/LV_CPICKER_DEF_QF) * LV_CPICKER_DEF_QF; end_angle = (end_angle / LV_CPICKER_DEF_QF) * LV_CPICKER_DEF_QF; /*shift angle if necessary before adding offset*/ - if((start_angle - LV_CPICKER_DEF_QF) < 0) - { + if((start_angle - LV_CPICKER_DEF_QF) < 0) { start_angle += 360; end_angle += 360; } @@ -623,8 +615,7 @@ static void draw_disc_grad(lv_obj_t * cpicker, const lv_area_t * mask, lv_opa_t lv_point_t triangle_points[3]; lv_style_t style; lv_style_copy(&style, &lv_style_plain); - for(uint16_t i = start_angle; i <= end_angle; i+= LV_CPICKER_DEF_QF) - { + for(uint16_t i = start_angle; i <= end_angle; i+= LV_CPICKER_DEF_QF) { style.body.main_color = angle_to_mode_color(cpicker, i); style.body.grad_color = style.body.main_color; @@ -638,8 +629,7 @@ static void draw_disc_grad(lv_obj_t * cpicker, const lv_area_t * mask, lv_opa_t /*the last triangle is drawn without additional overlapping pixels*/ triangle_points[2].x = cx + (r * lv_trigo_sin(i + LV_CPICKER_DEF_QF) >> LV_TRIGO_SHIFT); triangle_points[2].y = cy + (r * lv_trigo_sin(i + LV_CPICKER_DEF_QF + 90) >> LV_TRIGO_SHIFT); - } - else { + } else { triangle_points[2].x = cx + (r * lv_trigo_sin(i + LV_CPICKER_DEF_QF + TRI_OFFSET) >> LV_TRIGO_SHIFT); triangle_points[2].y = cy + (r * lv_trigo_sin(i + LV_CPICKER_DEF_QF + TRI_OFFSET + 90) >> LV_TRIGO_SHIFT); } @@ -728,8 +718,9 @@ static void draw_rect_grad(lv_obj_t * cpicker, const lv_area_t * mask, lv_opa_t lv_draw_rect(&rect_area, mask, &style, opa_scale); } } + /** - * Should roughly match up with `lv_cpicker_invalidate_disc_indicator_circle` + * Should roughly match up with `invalidate_indic` */ static void draw_indic(lv_obj_t * cpicker, const lv_area_t * mask, lv_opa_t opa_scale) { @@ -757,7 +748,6 @@ static void draw_indic(lv_obj_t * cpicker, const lv_area_t * mask, lv_opa_t opa_ style_cir.body.grad_color = style_cir.body.main_color; } - lv_draw_rect(&ind_area, mask, &style_cir, opa_scale); } @@ -791,8 +781,7 @@ static lv_res_t lv_cpicker_signal(lv_obj_t * cpicker, lv_signal_t sign, void * p } else if(sign == LV_SIGNAL_CORD_CHG) { /*Refresh extended draw area to make knob visible*/ if(lv_obj_get_width(cpicker) != lv_area_get_width(param) || - lv_obj_get_height(cpicker) != lv_area_get_height(param)) - { + lv_obj_get_height(cpicker) != lv_area_get_height(param)) { lv_obj_refresh_ext_draw_pad(cpicker); refr_indic_pos(cpicker); } @@ -851,7 +840,7 @@ static lv_res_t lv_cpicker_signal(lv_obj_t * cpicker, lv_signal_t sign, void * p lv_indev_get_point(lv_indev_get_act(), &ext->last_press_point); res = double_click_reset(cpicker); if(res != LV_RES_OK) return res; - } else if(sign == LV_SIGNAL_PRESSING){ + } else if(sign == LV_SIGNAL_PRESSING) { lv_indev_t * indev = lv_indev_get_act(); if(indev == NULL) return res; @@ -936,7 +925,7 @@ static lv_res_t lv_cpicker_signal(lv_obj_t * cpicker, lv_signal_t sign, void * p return res; } -static void next_color_mode(lv_obj_t * cpicker ) +static void next_color_mode(lv_obj_t * cpicker) { lv_cpicker_ext_t * ext = lv_obj_get_ext_attr(cpicker); ext->color_mode = (ext->color_mode + 1) % 3; @@ -946,11 +935,10 @@ static void next_color_mode(lv_obj_t * cpicker ) /** - * Indicator points need to match those set in lv_cpicker_disc_design/lv_cpicker_rect_design + * Should roughly match up with `draw_indic` */ static void invalidate_indic(lv_obj_t * cpicker) { - lv_cpicker_ext_t * ext = lv_obj_get_ext_attr(cpicker); const lv_style_t * style_main = lv_cpicker_get_style(cpicker, LV_CPICKER_STYLE_MAIN); const lv_style_t * style_indic = lv_cpicker_get_style(cpicker, LV_CPICKER_STYLE_INDICATOR); @@ -994,8 +982,7 @@ static void refr_indic_pos(lv_obj_t * cpicker) ext->indic.pos.x = ind_pos; ext->indic.pos.y = h / 2; - } - if(ext->type == LV_CPICKER_TYPE_DISC) { + } else if(ext->type == LV_CPICKER_TYPE_DISC) { const lv_style_t * style_main = lv_cpicker_get_style(cpicker, LV_CPICKER_STYLE_MAIN); lv_coord_t r = w / 2 - style_main->line.width / 2; uint16_t angle = get_angle(cpicker); From 61dfb5664868ecb33bcce6f276fd45026af6fc0c Mon Sep 17 00:00:00 2001 From: Paul Peavyhouse Date: Thu, 3 Oct 2019 04:02:38 -0700 Subject: [PATCH 42/82] Consolidating common indicator_area calculation code --- src/lv_objx/lv_cpicker.c | 78 +++++++++++++++++++--------------------- 1 file changed, 37 insertions(+), 41 deletions(-) diff --git a/src/lv_objx/lv_cpicker.c b/src/lv_objx/lv_cpicker.c index 898982142..7cb21610a 100644 --- a/src/lv_objx/lv_cpicker.c +++ b/src/lv_objx/lv_cpicker.c @@ -57,10 +57,11 @@ static bool lv_cpicker_design(lv_obj_t * cpicker, const lv_area_t * mask, lv_design_mode_t mode); static lv_res_t lv_cpicker_signal(lv_obj_t * cpicker, lv_signal_t sign, void * param); -static void invalidate_indic(lv_obj_t * cpicker); static void draw_rect_grad(lv_obj_t * cpicker, const lv_area_t * mask, lv_opa_t opa_scale); static void draw_disc_grad(lv_obj_t * cpicker, const lv_area_t * mask, lv_opa_t opa_scale); static void draw_indic(lv_obj_t * cpicker, const lv_area_t * mask, lv_opa_t opa_scale); +static void invalidate_indic(lv_obj_t * cpicker); +static lv_area_t get_indic_area(lv_obj_t * cpicker, const lv_style_t * style_main, const lv_style_t * style_indic, lv_cpicker_ext_t * ext); static void next_color_mode(lv_obj_t * cpicker); static lv_res_t double_click_reset(lv_obj_t * cpicker); @@ -719,25 +720,13 @@ static void draw_rect_grad(lv_obj_t * cpicker, const lv_area_t * mask, lv_opa_t } } -/** - * Should roughly match up with `invalidate_indic` - */ static void draw_indic(lv_obj_t * cpicker, const lv_area_t * mask, lv_opa_t opa_scale) { lv_cpicker_ext_t * ext = lv_obj_get_ext_attr(cpicker); const lv_style_t * style_main = lv_cpicker_get_style(cpicker, LV_CPICKER_STYLE_MAIN); const lv_style_t * style_indic = lv_cpicker_get_style(cpicker, LV_CPICKER_STYLE_INDICATOR); - lv_coord_t h = lv_obj_get_height(cpicker); - uint16_t r; - if(ext->type == LV_CPICKER_TYPE_DISC) r = style_main->line.width / 2; - else if(ext->type == LV_CPICKER_TYPE_RECT) r = h / 2; - - lv_area_t ind_area; - ind_area.x1 = cpicker->coords.x1 + ext->indic.pos.x - r - style_indic->body.padding.left; - ind_area.y1 = cpicker->coords.y1 + ext->indic.pos.y - r - style_indic->body.padding.right; - ind_area.x2 = cpicker->coords.x1 + ext->indic.pos.x + r + style_indic->body.padding.top; - ind_area.y2 = cpicker->coords.y1 + ext->indic.pos.y + r + style_indic->body.padding.bottom; + lv_area_t indic_area = get_indic_area(cpicker, style_main, style_indic, ext); lv_style_t style_cir; lv_style_copy(&style_cir, ext->indic.style); @@ -748,7 +737,39 @@ static void draw_indic(lv_obj_t * cpicker, const lv_area_t * mask, lv_opa_t opa_ style_cir.body.grad_color = style_cir.body.main_color; } - lv_draw_rect(&ind_area, mask, &style_cir, opa_scale); + lv_draw_rect(&indic_area, mask, &style_cir, opa_scale); +} + +static void invalidate_indic(lv_obj_t * cpicker) +{ + lv_cpicker_ext_t * ext = lv_obj_get_ext_attr(cpicker); + const lv_style_t * style_main = lv_cpicker_get_style(cpicker, LV_CPICKER_STYLE_MAIN); + const lv_style_t * style_indic = lv_cpicker_get_style(cpicker, LV_CPICKER_STYLE_INDICATOR); + + lv_area_t indic_area = get_indic_area(cpicker, style_main, style_indic, ext); + + lv_inv_area(lv_obj_get_disp(cpicker), &indic_area); +} + +static lv_area_t get_indic_area(lv_obj_t * cpicker, + const lv_style_t * style_main, + const lv_style_t * style_indic, + const lv_cpicker_ext_t * ext) +{ + uint16_t r; + if(ext->type == LV_CPICKER_TYPE_DISC) r = style_main->line.width / 2; + else if(ext->type == LV_CPICKER_TYPE_RECT) { + lv_coord_t h = lv_obj_get_height(cpicker); + r = h / 2; + } + + lv_area_t indic_area; + indic_area.x1 = cpicker->coords.x1 + ext->indic.pos.x - r - style_indic->body.padding.left; + indic_area.y1 = cpicker->coords.y1 + ext->indic.pos.y - r - style_indic->body.padding.right; + indic_area.x2 = cpicker->coords.x1 + ext->indic.pos.x + r + style_indic->body.padding.top; + indic_area.y2 = cpicker->coords.y1 + ext->indic.pos.y + r + style_indic->body.padding.bottom; + + return indic_area; } /** @@ -933,31 +954,6 @@ static void next_color_mode(lv_obj_t * cpicker) lv_obj_invalidate(cpicker); } - -/** - * Should roughly match up with `draw_indic` - */ -static void invalidate_indic(lv_obj_t * cpicker) -{ - lv_cpicker_ext_t * ext = lv_obj_get_ext_attr(cpicker); - const lv_style_t * style_main = lv_cpicker_get_style(cpicker, LV_CPICKER_STYLE_MAIN); - const lv_style_t * style_indic = lv_cpicker_get_style(cpicker, LV_CPICKER_STYLE_INDICATOR); - - lv_coord_t h = lv_obj_get_height(cpicker); - - uint16_t r; - if(ext->type == LV_CPICKER_TYPE_DISC) r = style_main->line.width / 2; - else if(ext->type == LV_CPICKER_TYPE_RECT) r = h / 2; - - lv_area_t indic_area; - indic_area.x1 = cpicker->coords.x1 + ext->indic.pos.x - r - style_indic->body.padding.left; - indic_area.y1 = cpicker->coords.y1 + ext->indic.pos.y - r - style_indic->body.padding.top; - indic_area.x2 = cpicker->coords.x1 + ext->indic.pos.x + r + style_indic->body.padding.right; - indic_area.y2 = cpicker->coords.y1 + ext->indic.pos.y + r + style_indic->body.padding.bottom; - - lv_inv_area(lv_obj_get_disp(cpicker), &indic_area); -} - static void refr_indic_pos(lv_obj_t * cpicker) { invalidate_indic(cpicker); @@ -989,7 +985,7 @@ static void refr_indic_pos(lv_obj_t * cpicker) ext->indic.pos.x = (((int32_t)r * lv_trigo_sin(angle)) >> LV_TRIGO_SHIFT); ext->indic.pos.y = (((int32_t)r * lv_trigo_sin(angle + 90)) >> LV_TRIGO_SHIFT); ext->indic.pos.x = ext->indic.pos.x + w / 2; - ext->indic.pos.y = ext->indic.pos.y + w / 2; + ext->indic.pos.y = ext->indic.pos.y + h / 2; } invalidate_indic(cpicker); From 68c39030a6c73703dc248257bac4e92e9201860b Mon Sep 17 00:00:00 2001 From: Paul Peavyhouse Date: Thu, 3 Oct 2019 04:04:27 -0700 Subject: [PATCH 43/82] Missed a line! --- src/lv_objx/lv_cpicker.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/lv_objx/lv_cpicker.c b/src/lv_objx/lv_cpicker.c index 7cb21610a..d0061ae2c 100644 --- a/src/lv_objx/lv_cpicker.c +++ b/src/lv_objx/lv_cpicker.c @@ -61,7 +61,10 @@ static void draw_rect_grad(lv_obj_t * cpicker, const lv_area_t * mask, lv_opa_t static void draw_disc_grad(lv_obj_t * cpicker, const lv_area_t * mask, lv_opa_t opa_scale); static void draw_indic(lv_obj_t * cpicker, const lv_area_t * mask, lv_opa_t opa_scale); static void invalidate_indic(lv_obj_t * cpicker); -static lv_area_t get_indic_area(lv_obj_t * cpicker, const lv_style_t * style_main, const lv_style_t * style_indic, lv_cpicker_ext_t * ext); +static lv_area_t get_indic_area(lv_obj_t * cpicker, + const lv_style_t * style_main, + const lv_style_t * style_indic, + const lv_cpicker_ext_t * ext); static void next_color_mode(lv_obj_t * cpicker); static lv_res_t double_click_reset(lv_obj_t * cpicker); From 34faac98a734c73a3be6ee46bd897f267924a349 Mon Sep 17 00:00:00 2001 From: Paul Peavyhouse Date: Thu, 3 Oct 2019 23:35:57 -0700 Subject: [PATCH 44/82] Cleaner calls to `get_indic_area` --- src/lv_objx/lv_cpicker.c | 35 ++++++++++++----------------------- src/lv_objx/lv_cpicker.h | 2 +- 2 files changed, 13 insertions(+), 24 deletions(-) diff --git a/src/lv_objx/lv_cpicker.c b/src/lv_objx/lv_cpicker.c index d0061ae2c..459d37213 100644 --- a/src/lv_objx/lv_cpicker.c +++ b/src/lv_objx/lv_cpicker.c @@ -61,10 +61,7 @@ static void draw_rect_grad(lv_obj_t * cpicker, const lv_area_t * mask, lv_opa_t static void draw_disc_grad(lv_obj_t * cpicker, const lv_area_t * mask, lv_opa_t opa_scale); static void draw_indic(lv_obj_t * cpicker, const lv_area_t * mask, lv_opa_t opa_scale); static void invalidate_indic(lv_obj_t * cpicker); -static lv_area_t get_indic_area(lv_obj_t * cpicker, - const lv_style_t * style_main, - const lv_style_t * style_indic, - const lv_cpicker_ext_t * ext); +static lv_area_t get_indic_area(lv_obj_t * cpicker); static void next_color_mode(lv_obj_t * cpicker); static lv_res_t double_click_reset(lv_obj_t * cpicker); @@ -125,7 +122,6 @@ lv_obj_t * lv_cpicker_create(lv_obj_t * par, const lv_obj_t * copy) /*If no copy do the basic initialization*/ if(copy == NULL) { lv_obj_set_protect(new_cpicker, LV_PROTECT_PRESS_LOST); - refr_indic_pos(new_cpicker); lv_theme_t * th = lv_theme_get_current(); if(th) { lv_cpicker_set_style(new_cpicker, LV_CPICKER_STYLE_MAIN, th->style.bg); @@ -550,9 +546,9 @@ static void draw_disc_grad(lv_obj_t * cpicker, const lv_area_t * mask, lv_opa_t lv_coord_t r = w / 2; /*if the mask does not include the center of the object - * redrawing all the wheel is not necessary; - * only a given angular range - */ + * redrawing all the wheel is not necessary; + * only a given angular range + */ lv_point_t center = {cx, cy}; if(!lv_area_is_point_on(mask, ¢er)) { @@ -726,10 +722,6 @@ static void draw_rect_grad(lv_obj_t * cpicker, const lv_area_t * mask, lv_opa_t static void draw_indic(lv_obj_t * cpicker, const lv_area_t * mask, lv_opa_t opa_scale) { lv_cpicker_ext_t * ext = lv_obj_get_ext_attr(cpicker); - const lv_style_t * style_main = lv_cpicker_get_style(cpicker, LV_CPICKER_STYLE_MAIN); - const lv_style_t * style_indic = lv_cpicker_get_style(cpicker, LV_CPICKER_STYLE_INDICATOR); - - lv_area_t indic_area = get_indic_area(cpicker, style_main, style_indic, ext); lv_style_t style_cir; lv_style_copy(&style_cir, ext->indic.style); @@ -740,25 +732,24 @@ static void draw_indic(lv_obj_t * cpicker, const lv_area_t * mask, lv_opa_t opa_ style_cir.body.grad_color = style_cir.body.main_color; } + lv_area_t indic_area = get_indic_area(cpicker); + lv_draw_rect(&indic_area, mask, &style_cir, opa_scale); } static void invalidate_indic(lv_obj_t * cpicker) { - lv_cpicker_ext_t * ext = lv_obj_get_ext_attr(cpicker); - const lv_style_t * style_main = lv_cpicker_get_style(cpicker, LV_CPICKER_STYLE_MAIN); - const lv_style_t * style_indic = lv_cpicker_get_style(cpicker, LV_CPICKER_STYLE_INDICATOR); - - lv_area_t indic_area = get_indic_area(cpicker, style_main, style_indic, ext); + lv_area_t indic_area = get_indic_area(cpicker); lv_inv_area(lv_obj_get_disp(cpicker), &indic_area); } -static lv_area_t get_indic_area(lv_obj_t * cpicker, - const lv_style_t * style_main, - const lv_style_t * style_indic, - const lv_cpicker_ext_t * ext) +static lv_area_t get_indic_area(lv_obj_t * cpicker) { + lv_cpicker_ext_t * ext = lv_obj_get_ext_attr(cpicker); + const lv_style_t * style_main = lv_cpicker_get_style(cpicker, LV_CPICKER_STYLE_MAIN); + const lv_style_t * style_indic = lv_cpicker_get_style(cpicker, LV_CPICKER_STYLE_INDICATOR); + uint16_t r; if(ext->type == LV_CPICKER_TYPE_DISC) r = style_main->line.width / 2; else if(ext->type == LV_CPICKER_TYPE_RECT) { @@ -959,8 +950,6 @@ static void next_color_mode(lv_obj_t * cpicker) static void refr_indic_pos(lv_obj_t * cpicker) { - invalidate_indic(cpicker); - lv_cpicker_ext_t * ext = lv_obj_get_ext_attr(cpicker); lv_coord_t w = lv_obj_get_width(cpicker); lv_coord_t h = lv_obj_get_height(cpicker); diff --git a/src/lv_objx/lv_cpicker.h b/src/lv_objx/lv_cpicker.h index 8ca26dacd..a9feee5ae 100644 --- a/src/lv_objx/lv_cpicker.h +++ b/src/lv_objx/lv_cpicker.h @@ -93,7 +93,7 @@ lv_obj_t * lv_cpicker_create(lv_obj_t * par, const lv_obj_t * copy); * @param cpicker pointer to a colorpicker object * @param type new type of the colorpicker (from 'lv_cpicker_type_t' enum) */ -void lv_cpicker_set_type(lv_obj_t * chart, lv_cpicker_type_t type); +void lv_cpicker_set_type(lv_obj_t * cpicker, lv_cpicker_type_t type); /** * Set a style of a colorpicker. From 3264af9f0ea7cd7101f26590db61bc2e48379dc9 Mon Sep 17 00:00:00 2001 From: Paul Peavyhouse Date: Mon, 21 Oct 2019 15:27:57 -0700 Subject: [PATCH 45/82] Fixing failure to invalidate indicator --- src/lv_objx/lv_cpicker.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/lv_objx/lv_cpicker.c b/src/lv_objx/lv_cpicker.c index 459d37213..d2bc62523 100644 --- a/src/lv_objx/lv_cpicker.c +++ b/src/lv_objx/lv_cpicker.c @@ -950,6 +950,8 @@ static void next_color_mode(lv_obj_t * cpicker) static void refr_indic_pos(lv_obj_t * cpicker) { + invalidate_indic(cpicker); + lv_cpicker_ext_t * ext = lv_obj_get_ext_attr(cpicker); lv_coord_t w = lv_obj_get_width(cpicker); lv_coord_t h = lv_obj_get_height(cpicker); From 6aff9f65ed8790ac0dd8f302e6d872363bd710fb Mon Sep 17 00:00:00 2001 From: Paul Peavyhouse Date: Tue, 22 Oct 2019 13:02:31 -0700 Subject: [PATCH 46/82] Floating point fix for RGB to HSV Test code at https://github.com/paulpv/lv_examples/blob/master/lv_tests/lv_test_misc/lv_test_color/lv_test_color.ino --- src/lv_misc/lv_color.c | 45 +++++++++++++++++++++++++++++------------- src/lv_misc/lv_color.h | 2 ++ src/lv_misc/lv_log.c | 1 + 3 files changed, 34 insertions(+), 14 deletions(-) diff --git a/src/lv_misc/lv_color.c b/src/lv_misc/lv_color.c index f5bec62bb..3a9c0f8a6 100644 --- a/src/lv_misc/lv_color.c +++ b/src/lv_misc/lv_color.c @@ -105,39 +105,56 @@ lv_color_t lv_color_hsv_to_rgb(uint16_t h, uint8_t s, uint8_t v) } /** - * Convert an RGB color to HSV + * Convert an 32-bit RGB color to HSV * @param r red * @param g green * @param b blue * @return the given RGB color n HSV */ -lv_color_hsv_t lv_color_rgb_to_hsv(uint8_t r, uint8_t g, uint8_t b) +lv_color_hsv_t lv_color_rgb_to_hsv(uint8_t r8, uint8_t g8, uint8_t b8) { + float r = r8 / 255.0; + float g = g8 / 255.0; + float b = b8 / 255.0; + + float min = r < g ? (r < b ? r : b) : (g < b ? g : b); + float max = r > g ? (r > b ? r : b) : (g > b ? g : b); + lv_color_hsv_t hsv; - uint8_t rgbMin, rgbMax; - rgbMin = r < g ? (r < b ? r : b) : (g < b ? g : b); - rgbMax = r > g ? (r > b ? r : b) : (g > b ? g : b); + // https://en.wikipedia.org/wiki/HSL_and_HSV#Lightness + hsv.v = max * 100 + 0.5; - hsv.v = rgbMax; - if(hsv.v == 0) { + float delta = max - min; + if (fabs(delta) < 0.009) { hsv.h = 0; hsv.s = 0; return hsv; } - hsv.s = 255 * (long)(rgbMax - rgbMin) / hsv.v; + // https://en.wikipedia.org/wiki/HSL_and_HSV#Saturation + hsv.s = delta / max * 100 + 0.5; if(hsv.s == 0) { hsv.h = 0; return hsv; } - if(rgbMax == r) - hsv.h = 0 + 43 * (g - b) / (rgbMax - rgbMin); - else if(rgbMax == g) - hsv.h = 85 + 43 * (b - r) / (rgbMax - rgbMin); - else - hsv.h = 171 + 43 * (r - g) / (rgbMax - rgbMin); + // https://en.wikipedia.org/wiki/HSL_and_HSV#Hue_and_chroma + float h; + if(max == r) h = (g - b) / delta + (g < b ? 6 : 0); // between yellow & magenta + else if(max == g) h = (b - r) / delta + 2; // between cyan & yellow + else if(max == b) h = (r - g) / delta + 4; // between magenta & cyan + else h = 0; + h *= 60; + if (h < 0) h += 360; + hsv.h = h + 0.5; return hsv; } + +lv_color_hsv_t lv_color_to_hsv(lv_color_t color) +{ + lv_color32_t color32; + color32.full = lv_color_to32(color); + return lv_color_rgb_to_hsv(color32.ch.red, color32.ch.green, color32.ch.blue); +} \ No newline at end of file diff --git a/src/lv_misc/lv_color.h b/src/lv_misc/lv_color.h index 4f994e2ef..35c2301f1 100644 --- a/src/lv_misc/lv_color.h +++ b/src/lv_misc/lv_color.h @@ -471,6 +471,8 @@ lv_color_t lv_color_hsv_to_rgb(uint16_t h, uint8_t s, uint8_t v); */ lv_color_hsv_t lv_color_rgb_to_hsv(uint8_t r, uint8_t g, uint8_t b); +lv_color_hsv_t lv_color_to_hsv(lv_color_t color); + /********************** * MACROS **********************/ diff --git a/src/lv_misc/lv_log.c b/src/lv_misc/lv_log.c index 2d12da4e1..acbdfb732 100644 --- a/src/lv_misc/lv_log.c +++ b/src/lv_misc/lv_log.c @@ -12,6 +12,7 @@ #if LV_LOG_PRINTF #include #endif + /********************* * DEFINES *********************/ From 69d7d5376889d5d3bbc100f74b86118e06695f19 Mon Sep 17 00:00:00 2001 From: Paul Peavyhouse Date: Tue, 22 Oct 2019 13:07:01 -0700 Subject: [PATCH 47/82] Documenting code --- src/lv_misc/lv_color.c | 15 ++++++++++----- src/lv_misc/lv_color.h | 17 +++++++++++------ 2 files changed, 21 insertions(+), 11 deletions(-) diff --git a/src/lv_misc/lv_color.c b/src/lv_misc/lv_color.c index 3a9c0f8a6..547dcc298 100644 --- a/src/lv_misc/lv_color.c +++ b/src/lv_misc/lv_color.c @@ -105,11 +105,11 @@ lv_color_t lv_color_hsv_to_rgb(uint16_t h, uint8_t s, uint8_t v) } /** - * Convert an 32-bit RGB color to HSV - * @param r red - * @param g green - * @param b blue - * @return the given RGB color n HSV + * Convert a 32-bit RGB color to HSV + * @param r8 8-bit red + * @param g8 8-bit green + * @param b8 8-bit blue + * @return the given RGB color in HSV */ lv_color_hsv_t lv_color_rgb_to_hsv(uint8_t r8, uint8_t g8, uint8_t b8) { @@ -152,6 +152,11 @@ lv_color_hsv_t lv_color_rgb_to_hsv(uint8_t r8, uint8_t g8, uint8_t b8) return hsv; } +/** + * Convert a color to HSV + * @param color color + * @return the given color in HSV + */ lv_color_hsv_t lv_color_to_hsv(lv_color_t color) { lv_color32_t color32; diff --git a/src/lv_misc/lv_color.h b/src/lv_misc/lv_color.h index 35c2301f1..7e7ad1def 100644 --- a/src/lv_misc/lv_color.h +++ b/src/lv_misc/lv_color.h @@ -463,14 +463,19 @@ static inline lv_color_t lv_color_hex3(uint32_t c) lv_color_t lv_color_hsv_to_rgb(uint16_t h, uint8_t s, uint8_t v); /** - * Convert an RGB color to HSV - * @param r red - * @param g green - * @param b blue - * @return the given RGB color n HSV + * Convert a 32-bit RGB color to HSV + * @param r8 8-bit red + * @param g8 8-bit green + * @param b8 8-bit blue + * @return the given RGB color in HSV */ -lv_color_hsv_t lv_color_rgb_to_hsv(uint8_t r, uint8_t g, uint8_t b); +lv_color_hsv_t lv_color_rgb_to_hsv(uint8_t r8, uint8_t g8, uint8_t b8); +/** + * Convert a color to HSV + * @param color color + * @return the given color in HSV + */ lv_color_hsv_t lv_color_to_hsv(lv_color_t color); /********************** From 65252024bf3703005be2ccad616a98f2ea5982c2 Mon Sep 17 00:00:00 2001 From: Paul Peavyhouse Date: Tue, 22 Oct 2019 13:17:53 -0700 Subject: [PATCH 48/82] Formatting --- src/lv_misc/lv_color.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/lv_misc/lv_color.c b/src/lv_misc/lv_color.c index 547dcc298..8ff816061 100644 --- a/src/lv_misc/lv_color.c +++ b/src/lv_misc/lv_color.c @@ -141,10 +141,14 @@ lv_color_hsv_t lv_color_rgb_to_hsv(uint8_t r8, uint8_t g8, uint8_t b8) // https://en.wikipedia.org/wiki/HSL_and_HSV#Hue_and_chroma float h; - if(max == r) h = (g - b) / delta + (g < b ? 6 : 0); // between yellow & magenta - else if(max == g) h = (b - r) / delta + 2; // between cyan & yellow - else if(max == b) h = (r - g) / delta + 4; // between magenta & cyan - else h = 0; + if(max == r) + h = (g - b) / delta + (g < b ? 6 : 0); // between yellow & magenta + else if(max == g) + h = (b - r) / delta + 2; // between cyan & yellow + else if(max == b) + h = (r - g) / delta + 4; // between magenta & cyan + else + h = 0; h *= 60; if (h < 0) h += 360; From a572d8a648fd74387b0707175a8151126918fcda Mon Sep 17 00:00:00 2001 From: Paul Peavyhouse Date: Tue, 22 Oct 2019 13:19:22 -0700 Subject: [PATCH 49/82] Keeping some original variable names --- src/lv_misc/lv_color.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/lv_misc/lv_color.c b/src/lv_misc/lv_color.c index 8ff816061..ecb710aa9 100644 --- a/src/lv_misc/lv_color.c +++ b/src/lv_misc/lv_color.c @@ -117,15 +117,15 @@ lv_color_hsv_t lv_color_rgb_to_hsv(uint8_t r8, uint8_t g8, uint8_t b8) float g = g8 / 255.0; float b = b8 / 255.0; - float min = r < g ? (r < b ? r : b) : (g < b ? g : b); - float max = r > g ? (r > b ? r : b) : (g > b ? g : b); + float rgbMin = r < g ? (r < b ? r : b) : (g < b ? g : b); + float rgbMax = r > g ? (r > b ? r : b) : (g > b ? g : b); lv_color_hsv_t hsv; // https://en.wikipedia.org/wiki/HSL_and_HSV#Lightness - hsv.v = max * 100 + 0.5; + hsv.v = rgbMax * 100 + 0.5; - float delta = max - min; + float delta = rgbMax - rgbMin; if (fabs(delta) < 0.009) { hsv.h = 0; hsv.s = 0; @@ -133,7 +133,7 @@ lv_color_hsv_t lv_color_rgb_to_hsv(uint8_t r8, uint8_t g8, uint8_t b8) } // https://en.wikipedia.org/wiki/HSL_and_HSV#Saturation - hsv.s = delta / max * 100 + 0.5; + hsv.s = delta / rgbMax * 100 + 0.5; if(hsv.s == 0) { hsv.h = 0; return hsv; @@ -141,11 +141,11 @@ lv_color_hsv_t lv_color_rgb_to_hsv(uint8_t r8, uint8_t g8, uint8_t b8) // https://en.wikipedia.org/wiki/HSL_and_HSV#Hue_and_chroma float h; - if(max == r) + if(rgbMax == r) h = (g - b) / delta + (g < b ? 6 : 0); // between yellow & magenta - else if(max == g) + else if(rgbMax == g) h = (b - r) / delta + 2; // between cyan & yellow - else if(max == b) + else if(rgbMax == b) h = (r - g) / delta + 4; // between magenta & cyan else h = 0; From ddd7c1d30cadfd93db2a36ea3c886c2fbbcc5576 Mon Sep 17 00:00:00 2001 From: Paul Peavyhouse Date: Tue, 22 Oct 2019 13:29:38 -0700 Subject: [PATCH 50/82] Adding ending newline --- src/lv_misc/lv_color.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lv_misc/lv_color.c b/src/lv_misc/lv_color.c index ecb710aa9..808b9d968 100644 --- a/src/lv_misc/lv_color.c +++ b/src/lv_misc/lv_color.c @@ -166,4 +166,4 @@ lv_color_hsv_t lv_color_to_hsv(lv_color_t color) lv_color32_t color32; color32.full = lv_color_to32(color); return lv_color_rgb_to_hsv(color32.ch.red, color32.ch.green, color32.ch.blue); -} \ No newline at end of file +} From 372b133b18f3f06fd7db7102ad95c465a2017dd3 Mon Sep 17 00:00:00 2001 From: Paul Peavyhouse Date: Thu, 24 Oct 2019 16:46:30 -0700 Subject: [PATCH 51/82] Converting to integer based math --- src/lv_misc/lv_color.c | 31 ++++++++++++++++--------------- 1 file changed, 16 insertions(+), 15 deletions(-) diff --git a/src/lv_misc/lv_color.c b/src/lv_misc/lv_color.c index 808b9d968..8835c0747 100644 --- a/src/lv_misc/lv_color.c +++ b/src/lv_misc/lv_color.c @@ -113,46 +113,47 @@ lv_color_t lv_color_hsv_to_rgb(uint16_t h, uint8_t s, uint8_t v) */ lv_color_hsv_t lv_color_rgb_to_hsv(uint8_t r8, uint8_t g8, uint8_t b8) { - float r = r8 / 255.0; - float g = g8 / 255.0; - float b = b8 / 255.0; + uint16_t r = ((uint32_t)r8 << 10) / 255; + uint16_t g = ((uint32_t)g8 << 10) / 255; + uint16_t b = ((uint32_t)b8 << 10) / 255; - float rgbMin = r < g ? (r < b ? r : b) : (g < b ? g : b); - float rgbMax = r > g ? (r > b ? r : b) : (g > b ? g : b); + uint16_t rgbMin = r < g ? (r < b ? r : b) : (g < b ? g : b); + uint16_t rgbMax = r > g ? (r > b ? r : b) : (g > b ? g : b); lv_color_hsv_t hsv; // https://en.wikipedia.org/wiki/HSL_and_HSV#Lightness - hsv.v = rgbMax * 100 + 0.5; + hsv.v = (100 * rgbMax) >> 10; - float delta = rgbMax - rgbMin; - if (fabs(delta) < 0.009) { + int32_t delta = rgbMax - rgbMin; + if (abs(delta) < 3) { hsv.h = 0; hsv.s = 0; return hsv; } // https://en.wikipedia.org/wiki/HSL_and_HSV#Saturation - hsv.s = delta / rgbMax * 100 + 0.5; - if(hsv.s == 0) { + hsv.s = 100 * delta / rgbMax; + if(hsv.s < 3) { hsv.h = 0; return hsv; } // https://en.wikipedia.org/wiki/HSL_and_HSV#Hue_and_chroma - float h; + int32_t h; if(rgbMax == r) - h = (g - b) / delta + (g < b ? 6 : 0); // between yellow & magenta + h = (((g - b) << 10) / delta) + (g < b ? (6 << 10) : 0); // between yellow & magenta else if(rgbMax == g) - h = (b - r) / delta + 2; // between cyan & yellow + h = (((b - r) << 10) / delta) + (2 << 10); // between cyan & yellow else if(rgbMax == b) - h = (r - g) / delta + 4; // between magenta & cyan + h = (((r - g) << 10) / delta) + (4 << 10); // between magenta & cyan else h = 0; h *= 60; + h >>= 10; if (h < 0) h += 360; - hsv.h = h + 0.5; + hsv.h = h; return hsv; } From 6df1fe190a6bc7a09bc901360fe14c693c134063 Mon Sep 17 00:00:00 2001 From: Paul Peavyhouse Date: Thu, 24 Oct 2019 20:13:03 -0700 Subject: [PATCH 52/82] #include and use LV_MATH_ABS --- src/lv_misc/lv_color.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/lv_misc/lv_color.c b/src/lv_misc/lv_color.c index 8835c0747..cd4825dfe 100644 --- a/src/lv_misc/lv_color.c +++ b/src/lv_misc/lv_color.c @@ -7,6 +7,7 @@ * INCLUDES *********************/ #include "lv_color.h" +#include "lv_math.h" /********************* * DEFINES @@ -126,7 +127,7 @@ lv_color_hsv_t lv_color_rgb_to_hsv(uint8_t r8, uint8_t g8, uint8_t b8) hsv.v = (100 * rgbMax) >> 10; int32_t delta = rgbMax - rgbMin; - if (abs(delta) < 3) { + if (LV_MATH_ABS(delta) < 3) { hsv.h = 0; hsv.s = 0; return hsv; From 8fe92bcd9aa735a88ec19410ea2fc58621000575 Mon Sep 17 00:00:00 2001 From: Gabor Kiss-Vamosi Date: Mon, 28 Oct 2019 06:24:47 +0100 Subject: [PATCH 53/82] lv_task: rename task_handler_mutex to already_running. Fixes #1238 --- src/lv_misc/lv_task.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/lv_misc/lv_task.c b/src/lv_misc/lv_task.c index c0656f408..af0c95aa6 100644 --- a/src/lv_misc/lv_task.c +++ b/src/lv_misc/lv_task.c @@ -68,16 +68,16 @@ LV_ATTRIBUTE_TASK_HANDLER void lv_task_handler(void) LV_LOG_TRACE("lv_task_handler started"); /*Avoid concurrent running of the task handler*/ - static bool task_handler_mutex = false; - if(task_handler_mutex) return; - task_handler_mutex = true; + static bool already_running = false; + if(already_running) return; + already_running = true; static uint32_t idle_period_start = 0; static uint32_t handler_start = 0; static uint32_t busy_time = 0; if(lv_task_run == false) { - task_handler_mutex = false; /*Release mutex*/ + already_running = false; /*Release mutex*/ return; } @@ -154,7 +154,7 @@ LV_ATTRIBUTE_TASK_HANDLER void lv_task_handler(void) idle_period_start = lv_tick_get(); } - task_handler_mutex = false; /*Release the mutex*/ + already_running = false; /*Release the mutex*/ LV_LOG_TRACE("lv_task_handler ready"); } From dd100e5e07c8ae18c6e885d97d9c5938049fff44 Mon Sep 17 00:00:00 2001 From: Gabor Kiss-Vamosi Date: Tue, 29 Oct 2019 14:33:59 +0100 Subject: [PATCH 54/82] ta: fix place holder alignment. Fixes #1241 --- src/lv_objx/lv_ta.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/lv_objx/lv_ta.c b/src/lv_objx/lv_ta.c index fa44a105c..08208f5a5 100644 --- a/src/lv_objx/lv_ta.c +++ b/src/lv_objx/lv_ta.c @@ -744,12 +744,14 @@ void lv_ta_set_text_align(lv_obj_t * ta, lv_label_align_t align) lv_obj_t * label = lv_ta_get_label(ta); if(!ext->one_line) { lv_label_set_align(label, align); + if(ext->placeholder) lv_label_set_align(ext->placeholder, align); } else { /*Normal left align. Just let the text expand*/ if(align == LV_LABEL_ALIGN_LEFT) { lv_label_set_long_mode(label, LV_LABEL_LONG_EXPAND); lv_page_set_scrl_fit2(ta, LV_FIT_TIGHT, LV_FIT_FLOOD); lv_label_set_align(label, align); + if(ext->placeholder) lv_label_set_align(ext->placeholder, align); } /*Else use fix label width equal to the Text area width*/ @@ -757,6 +759,7 @@ void lv_ta_set_text_align(lv_obj_t * ta, lv_label_align_t align) lv_label_set_long_mode(label, LV_LABEL_LONG_CROP); lv_page_set_scrl_fit2(ta, LV_FIT_FLOOD, LV_FIT_FLOOD); lv_label_set_align(label, align); + if(ext->placeholder) lv_label_set_align(ext->placeholder, align); lv_obj_set_width(label, lv_page_get_fit_width(ta)); } From 38ba12a866708c643ac9236492d62893517626ef Mon Sep 17 00:00:00 2001 From: Gabor Kiss-Vamosi Date: Wed, 30 Oct 2019 06:32:58 +0100 Subject: [PATCH 55/82] imgbtn fix --- src/lv_objx/lv_imgbtn.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/lv_objx/lv_imgbtn.c b/src/lv_objx/lv_imgbtn.c index e1c4c0309..a1420e357 100644 --- a/src/lv_objx/lv_imgbtn.c +++ b/src/lv_objx/lv_imgbtn.c @@ -309,18 +309,18 @@ static bool lv_imgbtn_design(lv_obj_t * imgbtn, const lv_area_t * mask, lv_desig lv_draw_img(&imgbtn->coords, mask, src, style, opa_scale); } #else + const void * src; + src = ext->img_src_left[state]; if(lv_img_src_get_type(src) == LV_IMG_SRC_SYMBOL) { LV_LOG_WARN("lv_imgbtn_design: SYMBOLS are not supported in tiled mode") - return; + return true; } - const void * src; lv_img_header_t header; lv_area_t coords; lv_coord_t left_w = 0; lv_coord_t right_w = 0; - src = ext->img_src_left[state]; if(src) { lv_img_decoder_get_info(src, &header); left_w = header.w; From cfb72d5b6938d20db73ed884cf8150b639a8b1ec Mon Sep 17 00:00:00 2001 From: Gabor Kiss-Vamosi Date: Wed, 30 Oct 2019 06:49:21 +0100 Subject: [PATCH 56/82] fix text recolor processing --- src/lv_misc/lv_txt.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/lv_misc/lv_txt.c b/src/lv_misc/lv_txt.c index 5632c5ad8..f89671518 100644 --- a/src/lv_misc/lv_txt.c +++ b/src/lv_misc/lv_txt.c @@ -186,6 +186,9 @@ static uint16_t lv_txt_get_next_word(const char * txt, const lv_font_t * font, /*Handle the recolor command*/ if((flag & LV_TXT_FLAG_RECOLOR) != 0) { if(lv_txt_is_cmd(&cmd_state, letter) != false) { + i = i_next; + i_next = i_next_next; + letter = letter_next; continue; /*Skip the letter is it is part of a command*/ } } From c86e2722bd185fc57b97c04f46ff9d6b1b70af27 Mon Sep 17 00:00:00 2001 From: Gabor Kiss-Vamosi Date: Wed, 30 Oct 2019 10:16:06 +0100 Subject: [PATCH 57/82] lv_draw_label: fix warning with txt_sel by adding lv_draw_label_txt_sel_t parameter --- src/lv_draw/lv_draw_img.c | 7 +++--- src/lv_draw/lv_draw_label.c | 28 +++++++++++++----------- src/lv_draw/lv_draw_label.h | 11 ++++++++-- src/lv_objx/lv_btnm.c | 2 +- src/lv_objx/lv_calendar.c | 10 ++++----- src/lv_objx/lv_canvas.c | 3 +-- src/lv_objx/lv_chart.c | 4 ++-- src/lv_objx/lv_ddlist.c | 4 ++-- src/lv_objx/lv_gauge.c | 2 +- src/lv_objx/lv_img.c | 2 +- src/lv_objx/lv_imgbtn.c | 2 +- src/lv_objx/lv_label.c | 17 ++++++++------- src/lv_objx/lv_label.h | 1 - src/lv_objx/lv_roller.c | 2 +- src/lv_objx/lv_ta.c | 43 ++++++++++++++++++------------------- src/lv_objx/lv_ta.h | 3 +-- src/lv_objx/lv_table.c | 2 +- 17 files changed, 74 insertions(+), 69 deletions(-) diff --git a/src/lv_draw/lv_draw_img.c b/src/lv_draw/lv_draw_img.c index eacaa2d23..2bb8c95b5 100644 --- a/src/lv_draw/lv_draw_img.c +++ b/src/lv_draw/lv_draw_img.c @@ -51,7 +51,7 @@ void lv_draw_img(const lv_area_t * coords, const lv_area_t * mask, const void * if(src == NULL) { LV_LOG_WARN("Image draw: src is NULL"); lv_draw_rect(coords, mask, &lv_style_plain, LV_OPA_COVER); - lv_draw_label(coords, mask, &lv_style_plain, LV_OPA_COVER, "No\ndata", LV_TXT_FLAG_NONE, NULL, -1, -1, NULL); + lv_draw_label(coords, mask, &lv_style_plain, LV_OPA_COVER, "No\ndata", LV_TXT_FLAG_NONE, NULL, NULL, NULL); return; } @@ -61,7 +61,7 @@ void lv_draw_img(const lv_area_t * coords, const lv_area_t * mask, const void * if(res == LV_RES_INV) { LV_LOG_WARN("Image draw error"); lv_draw_rect(coords, mask, &lv_style_plain, LV_OPA_COVER); - lv_draw_label(coords, mask, &lv_style_plain, LV_OPA_COVER, "No\ndata", LV_TXT_FLAG_NONE, NULL, -1, -1, NULL); + lv_draw_label(coords, mask, &lv_style_plain, LV_OPA_COVER, "No\ndata", LV_TXT_FLAG_NONE, NULL, NULL, NULL); return; } } @@ -562,8 +562,7 @@ static lv_res_t lv_img_draw_core(const lv_area_t * coords, const lv_area_t * mas if(cdsc->dec_dsc.error_msg != NULL) { LV_LOG_WARN("Image draw error"); lv_draw_rect(coords, mask, &lv_style_plain, LV_OPA_COVER); - lv_draw_label(coords, mask, &lv_style_plain, LV_OPA_COVER, cdsc->dec_dsc.error_msg, LV_TXT_FLAG_NONE, NULL, -1, - -1, NULL); + lv_draw_label(coords, mask, &lv_style_plain, LV_OPA_COVER, cdsc->dec_dsc.error_msg, LV_TXT_FLAG_NONE, NULL, NULL, NULL); } /* The decoder open could open the image and gave the entire uncompressed image. * Just draw it!*/ diff --git a/src/lv_draw/lv_draw_label.c b/src/lv_draw/lv_draw_label.c index 23c660396..ba4ce341b 100644 --- a/src/lv_draw/lv_draw_label.c +++ b/src/lv_draw/lv_draw_label.c @@ -51,11 +51,10 @@ static uint8_t hex_char_to_num(char hex); * @param txt 0 terminated text to write * @param flag settings for the text from 'txt_flag_t' enum * @param offset text offset in x and y direction (NULL if unused) - * @param sel_start start index of selected area (`LV_LABEL_TXT_SEL_OFF` if none) - * @param sel_end end index of selected area (`LV_LABEL_TXT_SEL_OFF` if none) + * @param sel make the text selected in the range by drawing a background there */ void lv_draw_label(const lv_area_t * coords, const lv_area_t * mask, const lv_style_t * style, lv_opa_t opa_scale, - const char * txt, lv_txt_flag_t flag, lv_point_t * offset, uint16_t sel_start, uint16_t sel_end, + const char * txt, lv_txt_flag_t flag, lv_point_t * offset, lv_draw_label_txt_sel_t * sel, lv_draw_label_hint_t * hint) { const lv_font_t * font = style->text.font; @@ -212,18 +211,21 @@ void lv_draw_label(const lv_area_t * coords, const lv_area_t * mask, const lv_st letter_w = lv_font_get_glyph_width(font, letter, letter_next); - if(sel_start != 0xFFFF && sel_end != 0xFFFF) { - int char_ind = lv_encoded_get_char_id(txt, i); - /*Do not draw the rectangle on the character at `sel_start`.*/ - if(char_ind > sel_start && char_ind <= sel_end) { - lv_area_t sel_coords; - sel_coords.x1 = pos.x; - sel_coords.y1 = pos.y; - sel_coords.x2 = pos.x + letter_w + style->text.letter_space - 1; - sel_coords.y2 = pos.y + line_height - 1; - lv_draw_rect(&sel_coords, mask, &sel_style, opa); + if(sel) { + if(sel->start != 0xFFFF && sel->end != 0xFFFF) { + int char_ind = lv_encoded_get_char_id(txt, i); + /*Do not draw the rectangle on the character at `sel_start`.*/ + if(char_ind > sel->start && char_ind <= sel->end) { + lv_area_t sel_coords; + sel_coords.x1 = pos.x; + sel_coords.y1 = pos.y; + sel_coords.x2 = pos.x + letter_w + style->text.letter_space - 1; + sel_coords.y2 = pos.y + line_height - 1; + lv_draw_rect(&sel_coords, mask, &sel_style, opa); + } } } + lv_draw_letter(&pos, mask, font, letter, color, opa); if(letter_w > 0) { diff --git a/src/lv_draw/lv_draw_label.h b/src/lv_draw/lv_draw_label.h index 2328aa2b3..d1a77948e 100644 --- a/src/lv_draw/lv_draw_label.h +++ b/src/lv_draw/lv_draw_label.h @@ -18,11 +18,19 @@ extern "C" { /********************* * DEFINES *********************/ +#define LV_DRAW_LABEL_NO_TXT_SEL (0xFFFF) /********************** * TYPEDEFS **********************/ +typedef struct +{ + uint16_t start; + uint16_t end; +}lv_draw_label_txt_sel_t; + + /** Store some info to speed up drawing of very large texts * It takes a lot of time to get the first visible character because * all the previous characters needs to be checked to calculate the positions. @@ -54,10 +62,9 @@ typedef struct { * @param flag settings for the text from 'txt_flag_t' enum * @param offset text offset in x and y direction (NULL if unused) * @param sel_start start index of selected area (`LV_LABEL_TXT_SEL_OFF` if none) - * @param sel_end end index of selected area (`LV_LABEL_TXT_SEL_OFF` if none) */ void lv_draw_label(const lv_area_t * coords, const lv_area_t * mask, const lv_style_t * style, lv_opa_t opa_scale, - const char * txt, lv_txt_flag_t flag, lv_point_t * offset, uint16_t sel_start, uint16_t sel_end, + const char * txt, lv_txt_flag_t flag, lv_point_t * offset, lv_draw_label_txt_sel_t * sel, lv_draw_label_hint_t * hint); /********************** diff --git a/src/lv_objx/lv_btnm.c b/src/lv_objx/lv_btnm.c index 8421d1197..eff4b0e68 100644 --- a/src/lv_objx/lv_btnm.c +++ b/src/lv_objx/lv_btnm.c @@ -734,7 +734,7 @@ static bool lv_btnm_design(lv_obj_t * btnm, const lv_area_t * mask, lv_design_mo area_tmp.x2 = area_tmp.x1 + txt_size.x; area_tmp.y2 = area_tmp.y1 + txt_size.y; - lv_draw_label(&area_tmp, mask, btn_style, opa_scale, ext->map_p[txt_i], txt_flag, NULL, -1, -1, NULL); + lv_draw_label(&area_tmp, mask, btn_style, opa_scale, ext->map_p[txt_i], txt_flag, NULL, NULL, NULL); } } return true; diff --git a/src/lv_objx/lv_calendar.c b/src/lv_objx/lv_calendar.c index e33eccf10..1e340a1e3 100644 --- a/src/lv_objx/lv_calendar.c +++ b/src/lv_objx/lv_calendar.c @@ -687,19 +687,19 @@ static void draw_header(lv_obj_t * calendar, const lv_area_t * mask) txt_buf[5] = '\0'; strcpy(&txt_buf[5], get_month_name(calendar, ext->showed_date.month)); header_area.y1 += ext->style_header->body.padding.top; - lv_draw_label(&header_area, mask, ext->style_header, opa_scale, txt_buf, LV_TXT_FLAG_CENTER, NULL, -1, -1, NULL); + lv_draw_label(&header_area, mask, ext->style_header, opa_scale, txt_buf, LV_TXT_FLAG_CENTER, NULL, NULL, NULL); /*Add the left arrow*/ const lv_style_t * arrow_style = ext->btn_pressing < 0 ? ext->style_header_pr : ext->style_header; header_area.x1 += ext->style_header->body.padding.left; - lv_draw_label(&header_area, mask, arrow_style, opa_scale, LV_SYMBOL_LEFT, LV_TXT_FLAG_NONE, NULL, -1, -1, NULL); + lv_draw_label(&header_area, mask, arrow_style, opa_scale, LV_SYMBOL_LEFT, LV_TXT_FLAG_NONE, NULL, NULL, NULL); /*Add the right arrow*/ arrow_style = ext->btn_pressing > 0 ? ext->style_header_pr : ext->style_header; header_area.x1 = header_area.x2 - ext->style_header->body.padding.right - lv_txt_get_width(LV_SYMBOL_RIGHT, strlen(LV_SYMBOL_RIGHT), arrow_style->text.font, arrow_style->text.line_space, LV_TXT_FLAG_NONE); - lv_draw_label(&header_area, mask, arrow_style, opa_scale, LV_SYMBOL_RIGHT, LV_TXT_FLAG_NONE, NULL, -1, -1, NULL); + lv_draw_label(&header_area, mask, arrow_style, opa_scale, LV_SYMBOL_RIGHT, LV_TXT_FLAG_NONE, NULL, NULL, NULL); } /** @@ -724,7 +724,7 @@ static void draw_day_names(lv_obj_t * calendar, const lv_area_t * mask) label_area.x1 = calendar->coords.x1 + (w * i) / 7 + l_pad; label_area.x2 = label_area.x1 + box_w - 1; lv_draw_label(&label_area, mask, ext->style_day_names, opa_scale, get_day_name(calendar, i), LV_TXT_FLAG_CENTER, - NULL, -1, -1, NULL); + NULL, NULL, NULL); } } @@ -853,7 +853,7 @@ static void draw_days(lv_obj_t * calendar, const lv_area_t * mask) /*Write the day's number*/ lv_utils_num_to_str(day_cnt, buf); - lv_draw_label(&label_area, mask, final_style, opa_scale, buf, LV_TXT_FLAG_CENTER, NULL, -1, -1, NULL); + lv_draw_label(&label_area, mask, final_style, opa_scale, buf, LV_TXT_FLAG_CENTER, NULL, NULL, NULL); /*Go to the next day*/ day_cnt++; diff --git a/src/lv_objx/lv_canvas.c b/src/lv_objx/lv_canvas.c index 855e2bcad..453b06a86 100644 --- a/src/lv_objx/lv_canvas.c +++ b/src/lv_objx/lv_canvas.c @@ -585,8 +585,7 @@ void lv_canvas_draw_text(lv_obj_t * canvas, lv_coord_t x, lv_coord_t y, lv_coord default: flag = LV_TXT_FLAG_NONE; break; } - lv_draw_label(&coords, &mask, style, LV_OPA_COVER, txt, flag, NULL, LV_LABEL_TEXT_SEL_OFF, LV_LABEL_TEXT_SEL_OFF, - NULL); + lv_draw_label(&coords, &mask, style, LV_OPA_COVER, txt, flag, NULL, NULL, NULL); lv_refr_set_disp_refreshing(refr_ori); } diff --git a/src/lv_objx/lv_chart.c b/src/lv_objx/lv_chart.c index c326c8c6b..b99aa4241 100644 --- a/src/lv_objx/lv_chart.c +++ b/src/lv_objx/lv_chart.c @@ -1379,7 +1379,7 @@ static void lv_chart_draw_y_ticks(lv_obj_t * chart, const lv_area_t * mask, uint a.x2 = p2.x + size.x + LV_CHART_AXIS_TO_LABEL_DISTANCE; } - lv_draw_label(&a, mask, style, opa_scale, buf, LV_TXT_FLAG_CENTER, NULL, -1, -1, NULL); + lv_draw_label(&a, mask, style, opa_scale, buf, LV_TXT_FLAG_CENTER, NULL, NULL, NULL); } } @@ -1465,7 +1465,7 @@ static void lv_chart_draw_x_ticks(lv_obj_t * chart, const lv_area_t * mask) /* set the area at some distance of the major tick len under of the tick */ lv_area_t a = {(p2.x - size.x / 2), (p2.y + LV_CHART_AXIS_TO_LABEL_DISTANCE), (p2.x + size.x / 2), (p2.y + size.y + LV_CHART_AXIS_TO_LABEL_DISTANCE)}; - lv_draw_label(&a, mask, style, opa_scale, buf, LV_TXT_FLAG_CENTER, NULL, -1, -1, NULL); + lv_draw_label(&a, mask, style, opa_scale, buf, LV_TXT_FLAG_CENTER, NULL, NULL, NULL); } } } diff --git a/src/lv_objx/lv_ddlist.c b/src/lv_objx/lv_ddlist.c index 65c5eeba0..870a3917d 100644 --- a/src/lv_objx/lv_ddlist.c +++ b/src/lv_objx/lv_ddlist.c @@ -597,7 +597,7 @@ static bool lv_ddlist_design(lv_obj_t * ddlist, const lv_area_t * mask, lv_desig new_style.text.opa = sel_style->text.opa; lv_txt_flag_t flag = lv_ddlist_get_txt_flag(ddlist); lv_draw_label(&ext->label->coords, &mask_sel, &new_style, opa_scale, lv_label_get_text(ext->label), - flag, NULL, -1, -1, NULL); + flag, NULL, NULL, NULL); } } @@ -631,7 +631,7 @@ static bool lv_ddlist_design(lv_obj_t * ddlist, const lv_area_t * mask, lv_desig area_ok = lv_area_intersect(&mask_arrow, mask, &area_arrow); if(area_ok) { lv_draw_label(&area_arrow, &mask_arrow, &new_style, opa_scale, LV_SYMBOL_DOWN, LV_TXT_FLAG_NONE, - NULL, -1, -1, NULL); /*Use a down arrow in ddlist, you can replace it with your + NULL, NULL, NULL); /*Use a down arrow in ddlist, you can replace it with your custom symbol*/ } } diff --git a/src/lv_objx/lv_gauge.c b/src/lv_objx/lv_gauge.c index aedb63c2a..f5ecc198f 100644 --- a/src/lv_objx/lv_gauge.c +++ b/src/lv_objx/lv_gauge.c @@ -389,7 +389,7 @@ static void lv_gauge_draw_scale(lv_obj_t * gauge, const lv_area_t * mask) label_cord.x2 = label_cord.x1 + label_size.x; label_cord.y2 = label_cord.y1 + label_size.y; - lv_draw_label(&label_cord, mask, style, opa_scale, scale_txt, LV_TXT_FLAG_NONE, NULL, -1, -1, NULL); + lv_draw_label(&label_cord, mask, style, opa_scale, scale_txt, LV_TXT_FLAG_NONE, NULL, NULL, NULL); } } /** diff --git a/src/lv_objx/lv_img.c b/src/lv_objx/lv_img.c index 302891ac3..8252b4bb8 100644 --- a/src/lv_objx/lv_img.c +++ b/src/lv_objx/lv_img.c @@ -384,7 +384,7 @@ static bool lv_img_design(lv_obj_t * img, const lv_area_t * mask, lv_design_mode lv_style_t style_mod; lv_style_copy(&style_mod, style); style_mod.text.color = style->image.color; - lv_draw_label(&coords, mask, &style_mod, opa_scale, ext->src, LV_TXT_FLAG_NONE, NULL, -1, -1, NULL); + lv_draw_label(&coords, mask, &style_mod, opa_scale, ext->src, LV_TXT_FLAG_NONE, NULL, NULL, NULL); } else { /*Trigger the error handler of image drawer*/ LV_LOG_WARN("lv_img_design: image source type is unknown"); diff --git a/src/lv_objx/lv_imgbtn.c b/src/lv_objx/lv_imgbtn.c index a1420e357..9f90009a6 100644 --- a/src/lv_objx/lv_imgbtn.c +++ b/src/lv_objx/lv_imgbtn.c @@ -304,7 +304,7 @@ static bool lv_imgbtn_design(lv_obj_t * imgbtn, const lv_area_t * mask, lv_desig #if LV_IMGBTN_TILED == 0 const void * src = ext->img_src[state]; if(lv_img_src_get_type(src) == LV_IMG_SRC_SYMBOL) { - lv_draw_label(&imgbtn->coords, mask, style, opa_scale, src, LV_TXT_FLAG_NONE, NULL, LV_LABEL_TEXT_SEL_OFF, LV_LABEL_TEXT_SEL_OFF, NULL); + lv_draw_label(&imgbtn->coords, mask, style, opa_scale, src, LV_TXT_FLAG_NONE, NULL, NULL, NULL); } else { lv_draw_img(&imgbtn->coords, mask, src, style, opa_scale); } diff --git a/src/lv_objx/lv_label.c b/src/lv_objx/lv_label.c index 8ee2654a8..b52f06052 100644 --- a/src/lv_objx/lv_label.c +++ b/src/lv_objx/lv_label.c @@ -108,8 +108,8 @@ lv_obj_t * lv_label_create(lv_obj_t * par, const lv_obj_t * copy) #endif #if LV_LABEL_TEXT_SEL - ext->txt_sel_start = LV_LABEL_TEXT_SEL_OFF; - ext->txt_sel_end = LV_LABEL_TEXT_SEL_OFF; + ext->txt_sel_start = LV_DRAW_LABEL_NO_TXT_SEL; + ext->txt_sel_end = LV_DRAW_LABEL_NO_TXT_SEL; #endif ext->dot.tmp_ptr = NULL; ext->dot_tmp_alloc = 0; @@ -977,8 +977,11 @@ static bool lv_label_design(lv_obj_t * label, const lv_area_t * mask, lv_design_ /*Just for compatibility*/ lv_draw_label_hint_t * hint = NULL; #endif - lv_draw_label(&coords, mask, style, opa_scale, ext->text, flag, &ext->offset, - lv_label_get_text_sel_start(label), lv_label_get_text_sel_end(label), hint); + lv_draw_label_txt_sel_t sel; + + sel.start = lv_label_get_text_sel_start(label); + sel.end = lv_label_get_text_sel_end(label); + lv_draw_label(&coords, mask, style, opa_scale, ext->text, flag, &ext->offset, &sel, hint); if(ext->long_mode == LV_LABEL_LONG_SROLL_CIRC) { @@ -994,16 +997,14 @@ static bool lv_label_design(lv_obj_t * label, const lv_area_t * mask, lv_design_ lv_font_get_glyph_width(style->text.font, ' ', ' ') * LV_LABEL_WAIT_CHAR_COUNT; ofs.y = ext->offset.y; - lv_draw_label(&coords, mask, style, opa_scale, ext->text, flag, &ofs, - lv_label_get_text_sel_start(label), lv_label_get_text_sel_end(label), NULL); + lv_draw_label(&coords, mask, style, opa_scale, ext->text, flag, &ofs, &sel, NULL); } /*Draw the text again below the original to make an circular effect */ if(size.y > lv_obj_get_height(label)) { ofs.x = ext->offset.x; ofs.y = ext->offset.y + size.y + lv_font_get_line_height(style->text.font); - lv_draw_label(&coords, mask, style, opa_scale, ext->text, flag, &ofs, - lv_label_get_text_sel_start(label), lv_label_get_text_sel_end(label), NULL); + lv_draw_label(&coords, mask, style, opa_scale, ext->text, flag, &ofs, &sel, NULL); } } } diff --git a/src/lv_objx/lv_label.h b/src/lv_objx/lv_label.h index 2de59cdf0..25277ed2d 100644 --- a/src/lv_objx/lv_label.h +++ b/src/lv_objx/lv_label.h @@ -33,7 +33,6 @@ extern "C" { *********************/ #define LV_LABEL_DOT_NUM 3 #define LV_LABEL_POS_LAST 0xFFFF -#define LV_LABEL_TEXT_SEL_OFF 0xFFFF LV_EXPORT_CONST_INT(LV_LABEL_DOT_NUM); LV_EXPORT_CONST_INT(LV_LABEL_POS_LAST); diff --git a/src/lv_objx/lv_roller.c b/src/lv_objx/lv_roller.c index 75eb9cf74..618192516 100644 --- a/src/lv_objx/lv_roller.c +++ b/src/lv_objx/lv_roller.c @@ -397,7 +397,7 @@ static bool lv_roller_design(lv_obj_t * roller, const lv_area_t * mask, lv_desig new_style.text.color = sel_style->text.color; new_style.text.opa = sel_style->text.opa; lv_draw_label(&ext->ddlist.label->coords, &mask_sel, &new_style, opa_scale, - lv_label_get_text(ext->ddlist.label), txt_align, NULL, -1, -1, NULL); + lv_label_get_text(ext->ddlist.label), txt_align, NULL, NULL, NULL); } } diff --git a/src/lv_objx/lv_ta.c b/src/lv_objx/lv_ta.c index b3da2abf4..8eb81c082 100644 --- a/src/lv_objx/lv_ta.c +++ b/src/lv_objx/lv_ta.c @@ -1131,8 +1131,8 @@ bool lv_ta_text_is_selected(const lv_obj_t * ta) #if LV_LABEL_TEXT_SEL lv_ta_ext_t * ext = lv_obj_get_ext_attr(ta); - if((lv_label_get_text_sel_start(ext->label) == LV_LABEL_TEXT_SEL_OFF || - lv_label_get_text_sel_end(ext->label) == LV_LABEL_TEXT_SEL_OFF)) { + if((lv_label_get_text_sel_start(ext->label) == LV_DRAW_LABEL_NO_TXT_SEL || + lv_label_get_text_sel_end(ext->label) == LV_DRAW_LABEL_NO_TXT_SEL)) { return true; } else { return false; @@ -1203,10 +1203,10 @@ void lv_ta_clear_selection(lv_obj_t * ta) #if LV_LABEL_TEXT_SEL lv_ta_ext_t * ext = lv_obj_get_ext_attr(ta); - if(lv_label_get_text_sel_start(ext->label) != LV_LABEL_TEXT_SEL_OFF || - lv_label_get_text_sel_end(ext->label) != LV_LABEL_TEXT_SEL_OFF) { - lv_label_set_text_sel_start(ext->label, LV_LABEL_TEXT_SEL_OFF); - lv_label_set_text_sel_end(ext->label, LV_LABEL_TEXT_SEL_OFF); + if(lv_label_get_text_sel_start(ext->label) != LV_DRAW_LABEL_NO_TXT_SEL || + lv_label_get_text_sel_end(ext->label) != LV_DRAW_LABEL_NO_TXT_SEL) { + lv_label_set_text_sel_start(ext->label, LV_DRAW_LABEL_NO_TXT_SEL); + lv_label_set_text_sel_end(ext->label, LV_DRAW_LABEL_NO_TXT_SEL); } #else (void)ta; /*Unused*/ @@ -1385,8 +1385,7 @@ static bool lv_ta_scrollable_design(lv_obj_t * scrl, const lv_area_t * mask, lv_ cur_area.x1 += cur_style.body.padding.left; cur_area.y1 += cur_style.body.padding.top; - lv_draw_label(&cur_area, mask, &cur_style, opa_scale, letter_buf, LV_TXT_FLAG_NONE, 0, - LV_LABEL_TEXT_SEL_OFF, LV_LABEL_TEXT_SEL_OFF, NULL); + lv_draw_label(&cur_area, mask, &cur_style, opa_scale, letter_buf, LV_TXT_FLAG_NONE, NULL, NULL, NULL); } else if(ext->cursor.type == LV_CURSOR_OUTLINE) { cur_style.body.opa = LV_OPA_TRANSP; @@ -1878,13 +1877,13 @@ static void update_cursor_position_on_click(lv_obj_t * ta, lv_signal_t sign, lv_ if(ext->text_sel_en) { if(!ext->text_sel_in_prog && !click_outside_label && sign == LV_SIGNAL_PRESSED) { /*Input device just went down. Store the selection start position*/ - ext->tmp_sel_start = index_of_char_at_position; - ext->tmp_sel_end = LV_LABEL_TEXT_SEL_OFF; + ext->sel.start = index_of_char_at_position; + ext->sel.end = LV_DRAW_LABEL_NO_TXT_SEL; ext->text_sel_in_prog = 1; lv_obj_set_drag(lv_page_get_scrl(ta), false); } else if(ext->text_sel_in_prog && sign == LV_SIGNAL_PRESSING) { /*Input device may be moving. Store the end position */ - ext->tmp_sel_end = index_of_char_at_position; + ext->sel.end = index_of_char_at_position; } else if(ext->text_sel_in_prog && (sign == LV_SIGNAL_PRESS_LOST || sign == LV_SIGNAL_RELEASED)) { /*Input device is released. Check if anything was selected.*/ lv_obj_set_drag(lv_page_get_scrl(ta), true); @@ -1897,22 +1896,22 @@ static void update_cursor_position_on_click(lv_obj_t * ta, lv_signal_t sign, lv_ /*If the selected area has changed then update the real values and*/ /*invalidate the text area.*/ - if(ext->tmp_sel_start > ext->tmp_sel_end) { - if(ext_label->txt_sel_start != ext->tmp_sel_end || ext_label->txt_sel_end != ext->tmp_sel_start) { - ext_label->txt_sel_start = ext->tmp_sel_end; - ext_label->txt_sel_end = ext->tmp_sel_start; + if(ext->sel.start > ext->sel.end) { + if(ext_label->txt_sel_start != ext->sel.end || ext_label->txt_sel_end != ext->sel.start) { + ext_label->txt_sel_start = ext->sel.end; + ext_label->txt_sel_end = ext->sel.start; lv_obj_invalidate(ta); } - } else if(ext->tmp_sel_start < ext->tmp_sel_end) { - if(ext_label->txt_sel_start != ext->tmp_sel_start || ext_label->txt_sel_end != ext->tmp_sel_end) { - ext_label->txt_sel_start = ext->tmp_sel_start; - ext_label->txt_sel_end = ext->tmp_sel_end; + } else if(ext->sel.start < ext->sel.end) { + if(ext_label->txt_sel_start != ext->sel.start || ext_label->txt_sel_end != ext->sel.end) { + ext_label->txt_sel_start = ext->sel.start; + ext_label->txt_sel_end = ext->sel.end; lv_obj_invalidate(ta); } } else { - if(ext_label->txt_sel_start != LV_LABEL_TEXT_SEL_OFF || ext_label->txt_sel_end != LV_LABEL_TEXT_SEL_OFF) { - ext_label->txt_sel_start = LV_LABEL_TEXT_SEL_OFF; - ext_label->txt_sel_end = LV_LABEL_TEXT_SEL_OFF; + if(ext_label->txt_sel_start != LV_DRAW_LABEL_NO_TXT_SEL || ext_label->txt_sel_end != LV_DRAW_LABEL_NO_TXT_SEL) { + ext_label->txt_sel_start = LV_DRAW_LABEL_NO_TXT_SEL; + ext_label->txt_sel_end = LV_DRAW_LABEL_NO_TXT_SEL; lv_obj_invalidate(ta); } } diff --git a/src/lv_objx/lv_ta.h b/src/lv_objx/lv_ta.h index ec2854e49..afbb94bc2 100644 --- a/src/lv_objx/lv_ta.h +++ b/src/lv_objx/lv_ta.h @@ -82,8 +82,7 @@ typedef struct uint8_t click_pos : 1; /*1: Enable positioning the cursor by clicking the text area*/ } cursor; #if LV_LABEL_TEXT_SEL - uint16_t tmp_sel_start; /*Temporary value*/ - uint16_t tmp_sel_end; /*Temporary value*/ + lv_draw_label_txt_sel_t sel; /*Temporary values for text selection*/ uint8_t text_sel_in_prog : 1; /*User is in process of selecting */ uint8_t text_sel_en : 1; /*Text can be selected on this text area*/ #endif diff --git a/src/lv_objx/lv_table.c b/src/lv_objx/lv_table.c index b99c055f1..cedd7d65d 100644 --- a/src/lv_objx/lv_table.c +++ b/src/lv_objx/lv_table.c @@ -729,7 +729,7 @@ static bool lv_table_design(lv_obj_t * table, const lv_area_t * mask, lv_design_ label_mask_ok = lv_area_intersect(&label_mask, mask, &cell_area); if(label_mask_ok) { lv_draw_label(&txt_area, &label_mask, cell_style, opa_scale, ext->cell_data[cell] + 1, - txt_flags, NULL, -1, -1, NULL); + txt_flags, NULL, NULL, NULL); } /*Draw lines after '\n's*/ lv_point_t p1; From 9baef1ef962726bdcf1288c42cfa89ef3e5a631a Mon Sep 17 00:00:00 2001 From: Themba Dube Date: Wed, 30 Oct 2019 11:31:24 -0400 Subject: [PATCH 58/82] Add missing definition of LV_LABEL_TEXT_SEL_OFF --- src/lv_objx/lv_label.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/lv_objx/lv_label.h b/src/lv_objx/lv_label.h index 25277ed2d..6d93c2278 100644 --- a/src/lv_objx/lv_label.h +++ b/src/lv_objx/lv_label.h @@ -33,6 +33,7 @@ extern "C" { *********************/ #define LV_LABEL_DOT_NUM 3 #define LV_LABEL_POS_LAST 0xFFFF +#define LV_LABEL_TEXT_SEL_OFF 0 LV_EXPORT_CONST_INT(LV_LABEL_DOT_NUM); LV_EXPORT_CONST_INT(LV_LABEL_POS_LAST); From 3da868a0905ccbdafb4bbbf9c301d4f66eb2cf86 Mon Sep 17 00:00:00 2001 From: George Slater Date: Wed, 30 Oct 2019 17:03:56 -0500 Subject: [PATCH 59/82] lv_color1_t: Add 'ch' struct to union to fix 1bit color compilation error. lv_color.h: Updated lv_color1_t union to include 'ch' structure. This fixes compilation errors when configured for 1bit color. --- src/lv_misc/lv_color.h | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/lv_misc/lv_color.h b/src/lv_misc/lv_color.h index 4f994e2ef..f2aadccaa 100644 --- a/src/lv_misc/lv_color.h +++ b/src/lv_misc/lv_color.h @@ -96,10 +96,13 @@ enum { typedef union { - uint8_t blue : 1; - uint8_t green : 1; - uint8_t red : 1; - uint8_t full : 1; + struct + { + uint8_t blue : 1; + uint8_t green : 1; + uint8_t red : 1; + } ch; + uint8_t full; } lv_color1_t; typedef union From da7e67b3814f964f6bd1330cd4e583e004c2c890 Mon Sep 17 00:00:00 2001 From: Gabor Kiss-Vamosi Date: Thu, 31 Oct 2019 14:14:08 +0100 Subject: [PATCH 60/82] fix lv_cb_is_inactive --- src/lv_objx/lv_cb.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lv_objx/lv_cb.h b/src/lv_objx/lv_cb.h index 5fa598b7b..a6b1e74ad 100644 --- a/src/lv_objx/lv_cb.h +++ b/src/lv_objx/lv_cb.h @@ -149,7 +149,7 @@ static inline bool lv_cb_is_checked(const lv_obj_t * cb) */ static inline bool lv_cb_is_inactive(const lv_obj_t * cb) { - return lv_btn_get_state(cb) == LV_BTN_STATE_INA ? false : true; + return lv_btn_get_state(cb) == LV_BTN_STATE_INA ? true :false; } /** From fb9fb8d09e25189c0208e75b96607de9a72219f4 Mon Sep 17 00:00:00 2001 From: Gabor Kiss-Vamosi Date: Thu, 31 Oct 2019 19:24:41 +0100 Subject: [PATCH 61/82] add LV_LABEL_TEXT_SEL_OFF again --- src/lv_objx/lv_label.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/lv_objx/lv_label.h b/src/lv_objx/lv_label.h index 25277ed2d..a5eafd48f 100644 --- a/src/lv_objx/lv_label.h +++ b/src/lv_objx/lv_label.h @@ -33,6 +33,7 @@ extern "C" { *********************/ #define LV_LABEL_DOT_NUM 3 #define LV_LABEL_POS_LAST 0xFFFF +#define LV_LABEL_TEXT_SEL_OFF LV_DRAW_LABEL_NO_TXT_SEL LV_EXPORT_CONST_INT(LV_LABEL_DOT_NUM); LV_EXPORT_CONST_INT(LV_LABEL_POS_LAST); From 982e2036cf068c7e3e2378bc395acd5ac940d329 Mon Sep 17 00:00:00 2001 From: Themba Dube Date: Thu, 31 Oct 2019 20:18:50 -0400 Subject: [PATCH 62/82] Fix inconsistency between lv_debug.c and lv_debug.h --- src/lv_core/lv_debug.c | 3 ++- src/lv_core/lv_debug.h | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/lv_core/lv_debug.c b/src/lv_core/lv_debug.c index 28d09d1da..f5b02d541 100644 --- a/src/lv_core/lv_debug.c +++ b/src/lv_core/lv_debug.c @@ -7,6 +7,7 @@ * INCLUDES *********************/ #include "lv_obj.h" +#include "lv_debug.h" #if LV_USE_DEBUG @@ -126,7 +127,7 @@ bool lv_debug_check_str(const void * str) return false; } -void lv_debug_log_error(const char * msg, unsigned long int value) +void lv_debug_log_error(const char * msg, uint64_t value) { static const char hex[] = "0123456789ABCDEF"; diff --git a/src/lv_core/lv_debug.h b/src/lv_core/lv_debug.h index f66fb65b4..f9b8082dd 100644 --- a/src/lv_core/lv_debug.h +++ b/src/lv_core/lv_debug.h @@ -34,7 +34,7 @@ bool lv_debug_check_obj_type(const lv_obj_t * obj, const char * obj_type); bool lv_debug_check_obj_valid(const lv_obj_t * obj); -bool lv_debug_check_style(const void * str); +bool lv_debug_check_style(const lv_style_t * style); bool lv_debug_check_str(const void * str); From 8db8470a6089ef11abd6d24bb64cc1dc3221428e Mon Sep 17 00:00:00 2001 From: Gabor Kiss-Vamosi Date: Sat, 2 Nov 2019 21:34:41 +0100 Subject: [PATCH 63/82] lv_ta_set_placeholder_text: fix placholder align --- src/lv_objx/lv_ta.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/lv_objx/lv_ta.c b/src/lv_objx/lv_ta.c index 08208f5a5..0bcda4c9a 100644 --- a/src/lv_objx/lv_ta.c +++ b/src/lv_objx/lv_ta.c @@ -541,6 +541,9 @@ void lv_ta_set_placeholder_text(lv_obj_t * ta, const char * txt) lv_label_set_text(ext->placeholder, txt); + /*Refresh the placeholder's align*/ + lv_ta_set_text_align(ta, lv_label_get_align(ext->label)); + placeholder_update(ta); } From 5222bf92c4e234f18a0a67687dd55f4ad588230d Mon Sep 17 00:00:00 2001 From: Gabor Kiss-Vamosi Date: Sat, 2 Nov 2019 23:33:25 +0100 Subject: [PATCH 64/82] kb: use LV_SYMBOL_NEW_LINE as new line --- src/lv_objx/lv_kb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lv_objx/lv_kb.c b/src/lv_objx/lv_kb.c index 1229ffa8b..1c896ba6a 100644 --- a/src/lv_objx/lv_kb.c +++ b/src/lv_objx/lv_kb.c @@ -395,7 +395,7 @@ void lv_kb_def_event_cb(lv_obj_t * kb, lv_event_t event) /*Add the characters to the text area if set*/ if(ext->ta == NULL) return; - if(strcmp(txt, "Enter") == 0) + if(strcmp(txt, "Enter") == 0 || strcmp(txt, LV_SYMBOL_NEW_LINE) == 0) lv_ta_add_char(ext->ta, '\n'); else if(strcmp(txt, LV_SYMBOL_LEFT) == 0) lv_ta_cursor_left(ext->ta); From f6829a17b22f0f89917197957e120f951b2585a4 Mon Sep 17 00:00:00 2001 From: Amir Gonnen Date: Mon, 4 Nov 2019 01:31:54 +0200 Subject: [PATCH 65/82] WIP: Bidi pos_conv --- src/lv_draw/lv_draw_label.c | 2 +- src/lv_misc/lv_bidi.c | 152 +++++++++++++++++++++++++++--------- src/lv_misc/lv_bidi.h | 2 +- 3 files changed, 116 insertions(+), 40 deletions(-) diff --git a/src/lv_draw/lv_draw_label.c b/src/lv_draw/lv_draw_label.c index 86b486002..5bd0592c5 100644 --- a/src/lv_draw/lv_draw_label.c +++ b/src/lv_draw/lv_draw_label.c @@ -169,7 +169,7 @@ void lv_draw_label(const lv_area_t * coords, const lv_area_t * mask, const lv_st while(i < line_end - line_start) { #if LV_USE_BIDI char *bidi_txt = lv_draw_get_buf(line_end - line_start + 1); - lv_bidi_process_paragraph(txt + line_start, bidi_txt, line_end - line_start, bidi_dir); + lv_bidi_process_paragraph(txt + line_start, bidi_txt, line_end - line_start, bidi_dir, NULL, 0); #else const char *bidi_txt = txt + line_start; #endif diff --git a/src/lv_misc/lv_bidi.c b/src/lv_misc/lv_bidi.c index 634e1f896..1d962c64a 100644 --- a/src/lv_misc/lv_bidi.c +++ b/src/lv_misc/lv_bidi.c @@ -29,10 +29,11 @@ typedef struct /********************** * STATIC PROTOTYPES **********************/ -static lv_bidi_dir_t get_next_run(const char * txt, lv_bidi_dir_t base_dir, uint32_t max_len, uint32_t * len); -static void rtl_reverse(char * dest, const char * src, uint32_t len); +static lv_bidi_dir_t get_next_run(const char * txt, lv_bidi_dir_t base_dir, uint32_t max_len, uint32_t * len, uint16_t * pos_conv_len); +static void rtl_reverse(char * dest, const char * src, uint32_t len, uint16_t *pos_conv_out, uint16_t pos_conv_rd_base, uint16_t pos_conv_len); static uint32_t char_change_to_pair(uint32_t letter); static lv_bidi_dir_t bracket_process(const char * txt, uint32_t next_pos, uint32_t len, uint32_t letter, lv_bidi_dir_t base_dir); +static void fill_pos_conv(uint16_t * out, uint16_t len, uint16_t index); /********************** * STATIC VARIABLES @@ -64,7 +65,7 @@ void lv_bidi_process(const char * str_in, char * str_out, lv_bidi_dir_t base_dir while(str_in[par_start] != '\0') { par_len = lv_bidi_get_next_paragraph(&str_in[par_start]); - lv_bidi_process_paragraph(&str_in[par_start], &str_out[par_start], par_len, base_dir); + lv_bidi_process_paragraph(&str_in[par_start], &str_out[par_start], par_len, base_dir, NULL, 0); par_start += par_len; while(str_in[par_start] == '\n' || str_in[par_start] == '\r') { @@ -137,23 +138,27 @@ bool lv_bidi_letter_is_neutral(uint32_t letter) return false; } - -/********************** - * STATIC FUNCTIONS - **********************/ - -void lv_bidi_process_paragraph(const char * str_in, char * str_out, uint32_t len, lv_bidi_dir_t base_dir) +void lv_bidi_process_paragraph(const char * str_in, char * str_out, uint32_t len, lv_bidi_dir_t base_dir, uint16_t *pos_conv_out, uint16_t pos_conv_len) { uint32_t run_len = 0; lv_bidi_dir_t run_dir; uint32_t rd = 0; uint32_t wr; + uint16_t pos_conv_run_len = 0; + uint16_t pos_conv_rd = 0; + uint16_t pos_conv_wr; if(base_dir == LV_BIDI_DIR_AUTO) base_dir = lv_bidi_detect_base_dir(str_in); - if(base_dir == LV_BIDI_DIR_RTL) wr = len; - else wr = 0; + if(base_dir == LV_BIDI_DIR_RTL) { + wr = len; + pos_conv_wr = pos_conv_len; + } + else { + wr = 0; + pos_conv_wr = 0; + } - str_out[len] = '\0'; + if (str_out) str_out[len] = '\0'; lv_bidi_dir_t dir = base_dir; @@ -163,39 +168,59 @@ void lv_bidi_process_paragraph(const char * str_in, char * str_out, uint32_t len /*Process neutral chars in the beginning*/ while(rd < len) { uint32_t letter = lv_txt_encoded_next(str_in, &rd); + pos_conv_rd++; dir = lv_bidi_get_letter_dir(letter); if(dir == LV_BIDI_DIR_NEUTRAL) dir = bracket_process(str_in, rd, len, letter, base_dir); - if(dir != LV_BIDI_DIR_NEUTRAL && dir != LV_BIDI_DIR_WEAK) break; } - if(rd && str_in[rd] != '\0') lv_txt_encoded_prev(str_in, &rd); + if(rd && str_in[rd] != '\0') { + lv_txt_encoded_prev(str_in, &rd); + pos_conv_rd--; + } if(rd) { if(base_dir == LV_BIDI_DIR_LTR) { - memcpy(&str_out[wr], str_in, rd); - wr += rd; + if (str_out) { + memcpy(&str_out[wr], str_in, rd); + wr += rd; + } + if (pos_conv_out) { + fill_pos_conv(&pos_conv_out[pos_conv_wr], pos_conv_rd, 0); + pos_conv_wr += pos_conv_rd; + } } else { wr -= rd; - rtl_reverse(&str_out[wr], str_in, rd); + pos_conv_wr -= pos_conv_rd; + rtl_reverse(str_out? &str_out[wr]: NULL, str_in, rd, pos_conv_out? &pos_conv_out[pos_conv_wr]: NULL, 0, pos_conv_rd); } } /*Get and process the runs*/ + while(rd < len) { - run_dir = get_next_run(&str_in[rd], base_dir, len - rd, &run_len); + run_dir = get_next_run(&str_in[rd], base_dir, len - rd, &run_len, &pos_conv_run_len); if(base_dir == LV_BIDI_DIR_LTR) { - if(run_dir == LV_BIDI_DIR_LTR) memcpy(&str_out[wr], &str_in[rd], run_len); - else rtl_reverse(&str_out[wr], &str_in[rd], run_len); + if(run_dir == LV_BIDI_DIR_LTR) { + if (str_out) memcpy(&str_out[wr], &str_in[rd], run_len); + if (pos_conv_out) fill_pos_conv(&pos_conv_out[pos_conv_wr], pos_conv_run_len, pos_conv_rd); + } + else rtl_reverse(str_out? &str_out[wr]: NULL, &str_in[rd], run_len, pos_conv_out? &pos_conv_out[pos_conv_wr] : NULL, pos_conv_rd, pos_conv_run_len); wr += run_len; + pos_conv_wr += pos_conv_run_len; } else { wr -= run_len; - if(run_dir == LV_BIDI_DIR_LTR) memcpy(&str_out[wr], &str_in[rd], run_len); - else rtl_reverse(&str_out[wr], &str_in[rd], run_len); + pos_conv_wr -= pos_conv_run_len; + if(run_dir == LV_BIDI_DIR_LTR) { + if (str_out) memcpy(&str_out[wr], &str_in[rd], run_len); + if (pos_conv_out) fill_pos_conv(&pos_conv_out[pos_conv_wr], pos_conv_run_len, pos_conv_rd); + } + else rtl_reverse(str_out? &str_out[wr]: NULL, &str_in[rd], run_len, pos_conv_out? &pos_conv_out[pos_conv_wr] : NULL, pos_conv_rd, pos_conv_run_len); } rd += run_len; + pos_conv_rd += pos_conv_run_len; } } @@ -212,24 +237,40 @@ uint32_t lv_bidi_get_next_paragraph(const char * txt) return i; } -static lv_bidi_dir_t get_next_run(const char * txt, lv_bidi_dir_t base_dir, uint32_t max_len, uint32_t * len) +/********************** + * STATIC FUNCTIONS + **********************/ + +static void fill_pos_conv(uint16_t * out, uint16_t len, uint16_t index) +{ + for (uint16_t i = 0; i < len; i++) + { + out[i] = index; + index++; + } +} + +static lv_bidi_dir_t get_next_run(const char * txt, lv_bidi_dir_t base_dir, uint32_t max_len, uint32_t * len, uint16_t * pos_conv_len) { uint32_t i = 0; uint32_t letter; + uint16_t pos_conv_i = 0; + letter = lv_txt_encoded_next(txt, NULL); lv_bidi_dir_t dir = lv_bidi_get_letter_dir(letter); if(dir == LV_BIDI_DIR_NEUTRAL) dir = bracket_process(txt, 0, max_len, letter, base_dir); - /*Find the first strong char. Skip the neutrals*/ while(dir == LV_BIDI_DIR_NEUTRAL || dir == LV_BIDI_DIR_WEAK) { letter = lv_txt_encoded_next(txt, &i); + pos_conv_i++; dir = lv_bidi_get_letter_dir(letter); if(dir == LV_BIDI_DIR_NEUTRAL) dir = bracket_process(txt, i, max_len, letter, base_dir); if(i >= max_len || txt[i] == '\0' || txt[i] == '\n' || txt[i] == '\r') { *len = i; + *pos_conv_len = pos_conv_i; return base_dir; } } @@ -238,84 +279,119 @@ static lv_bidi_dir_t get_next_run(const char * txt, lv_bidi_dir_t base_dir, uint uint32_t i_prev = i; uint32_t i_last_strong = i; + uint16_t pos_conv_i_prev = pos_conv_i; + uint16_t pos_conv_i_last_strong = pos_conv_i; /*Find the next char which has different direction*/ lv_bidi_dir_t next_dir = base_dir; while(i_prev < max_len && txt[i] != '\0' && txt[i] != '\n' && txt[i] != '\r') { letter = lv_txt_encoded_next(txt, &i); + pos_conv_i++; next_dir = lv_bidi_get_letter_dir(letter); if(next_dir == LV_BIDI_DIR_NEUTRAL) next_dir = bracket_process(txt, i, max_len, letter, base_dir); /*New dir found?*/ if((next_dir == LV_BIDI_DIR_RTL || next_dir == LV_BIDI_DIR_LTR) && next_dir != run_dir) { /*Include neutrals if `run_dir == base_dir` */ - if(run_dir == base_dir) *len = i_prev; + if(run_dir == base_dir) { + *len = i_prev; + *pos_conv_len = pos_conv_i_prev; + } /*Exclude neutrals if `run_dir != base_dir` */ - else *len = i_last_strong; + else { + *len = i_last_strong; + *pos_conv_len = pos_conv_i_last_strong; + } return run_dir; } - if(next_dir != LV_BIDI_DIR_NEUTRAL) i_last_strong = i; + if(next_dir != LV_BIDI_DIR_NEUTRAL) { + i_last_strong = i; + pos_conv_i_last_strong = pos_conv_i; + } i_prev = i; + pos_conv_i_prev = pos_conv_i; } - /*Handle end of of string. Apply `base_dir` on trailing neutrals*/ /*Include neutrals if `run_dir == base_dir` */ - if(run_dir == base_dir) *len = i_prev; + if(run_dir == base_dir) { + *len = i_prev; + *pos_conv_len = pos_conv_i_prev; + } /*Exclude neutrals if `run_dir != base_dir` */ - else *len = i_last_strong; + else { + *len = i_last_strong; + *pos_conv_len = pos_conv_i_last_strong; + } return run_dir; - } -static void rtl_reverse(char * dest, const char * src, uint32_t len) +static void rtl_reverse(char * dest, const char * src, uint32_t len, uint16_t *pos_conv_out, uint16_t pos_conv_rd_base, uint16_t pos_conv_len) { uint32_t i = len; uint32_t wr = 0; + uint16_t pos_conv_i = pos_conv_len; + uint16_t pos_conv_wr = 0; while(i) { uint32_t letter = lv_txt_encoded_prev(src, &i); + uint16_t pos_conv_letter = --pos_conv_i; /*Keep weak letters (numbers) as LTR*/ if(lv_bidi_letter_is_weak(letter)) { uint32_t last_weak = i; uint32_t first_weak = i; + uint16_t pos_conv_last_weak = pos_conv_i; + uint16_t pos_conv_first_weak = pos_conv_i; while(i) { letter = lv_txt_encoded_prev(src, &i); + pos_conv_letter = --pos_conv_i; + /*No need to call `char_change_to_pair` because there not such chars here*/ /*Finish on non-weak char */ /*but treat number and currency related chars as weak*/ - if(lv_bidi_letter_is_weak(letter) == false && letter != '.' && letter != ',' && letter != '$' && letter != '%') { + if (lv_bidi_letter_is_weak(letter) == false && letter != '.' && letter != ',' && letter != '$' && letter != '%') { lv_txt_encoded_next(src, &i); /*Rewind one letter*/ + pos_conv_i++; first_weak = i; + pos_conv_first_weak = pos_conv_i; break; } } - if(i == 0) first_weak = 0; + if(i == 0) { + first_weak = 0; + pos_conv_first_weak = 0; + } - memcpy(&dest[wr], &src[first_weak], last_weak - first_weak + 1); + if (dest) memcpy(&dest[wr], &src[first_weak], last_weak - first_weak + 1); + if (pos_conv_out) fill_pos_conv(&pos_conv_out[pos_conv_wr], pos_conv_last_weak - pos_conv_first_weak + 1, pos_conv_rd_base + pos_conv_first_weak); wr += last_weak - first_weak + 1; - + pos_conv_wr += pos_conv_last_weak - pos_conv_first_weak + 1; } + /*Simply store in reversed order*/ else { uint32_t letter_size = lv_txt_encoded_size((const char *)&src[i]); /*Swap arithmetical symbols*/ if(letter_size == 1) { uint32_t new_letter = letter = char_change_to_pair(letter); - dest[wr] = (uint8_t)new_letter; + if (dest) dest[wr] = (uint8_t)new_letter; + if (pos_conv_out) pos_conv_out[pos_conv_wr] = pos_conv_rd_base + pos_conv_letter; wr += 1; + pos_conv_wr += 1; } /*Just store the letter*/ else { - memcpy(&dest[wr], &src[i], letter_size); + if (dest) memcpy(&dest[wr], &src[i], letter_size); + if (pos_conv_out) pos_conv_out[pos_conv_wr] = pos_conv_rd_base + pos_conv_i; wr += letter_size; + pos_conv_wr++; } } } diff --git a/src/lv_misc/lv_bidi.h b/src/lv_misc/lv_bidi.h index 9ce0fffa1..4d586e570 100644 --- a/src/lv_misc/lv_bidi.h +++ b/src/lv_misc/lv_bidi.h @@ -53,7 +53,7 @@ typedef uint8_t lv_bidi_dir_t; #if LV_USE_BIDI void lv_bidi_process(const char * str_in, char * str_out, lv_bidi_dir_t base_dir); -void lv_bidi_process_paragraph(const char * str_in, char * str_out, uint32_t len, lv_bidi_dir_t base_dir); +void lv_bidi_process_paragraph(const char * str_in, char * str_out, uint32_t len, lv_bidi_dir_t base_dir, uint16_t *pos_conv_out, uint16_t pos_conv_len); uint32_t lv_bidi_get_next_paragraph(const char * txt); lv_bidi_dir_t lv_bidi_detect_base_dir(const char * txt); lv_bidi_dir_t lv_bidi_get_letter_dir(uint32_t letter); From c7a7d1adca367fdccc86dd690e77a581229247ec Mon Sep 17 00:00:00 2001 From: Amir Gonnen Date: Mon, 4 Nov 2019 09:26:52 +0200 Subject: [PATCH 66/82] WIP: pos_conv add lv_bidi_get_logical/visual_pos functions --- src/lv_misc/lv_bidi.c | 36 ++++++++++++++++++++++++++++++++---- src/lv_misc/lv_bidi.h | 2 ++ 2 files changed, 34 insertions(+), 4 deletions(-) diff --git a/src/lv_misc/lv_bidi.c b/src/lv_misc/lv_bidi.c index 1d962c64a..fcb2f7b7c 100644 --- a/src/lv_misc/lv_bidi.c +++ b/src/lv_misc/lv_bidi.c @@ -6,9 +6,10 @@ /********************* * INCLUDES *********************/ -#include "lv_bidi.h" #include +#include "lv_bidi.h" #include "lv_txt.h" +#include "../lv_draw/lv_draw.h" #if LV_USE_BIDI @@ -34,6 +35,7 @@ static void rtl_reverse(char * dest, const char * src, uint32_t len, uint16_t *p static uint32_t char_change_to_pair(uint32_t letter); static lv_bidi_dir_t bracket_process(const char * txt, uint32_t next_pos, uint32_t len, uint32_t letter, lv_bidi_dir_t base_dir); static void fill_pos_conv(uint16_t * out, uint16_t len, uint16_t index); +static uint32_t get_txt_len(const char * txt, uint32_t max_len); /********************** * STATIC VARIABLES @@ -138,6 +140,19 @@ bool lv_bidi_letter_is_neutral(uint32_t letter) return false; } +uint16_t lv_bidi_get_logical_pos(const char * str_in, uint16_t len, lv_bidi_dir_t base_dir, uint32_t visual_pos) +{ + return 0; // TODO +} + +uint16_t lv_bidi_get_visual_pos(const char * str_in, uint16_t len, lv_bidi_dir_t base_dir, uint32_t logical_pos) +{ + uint32_t pos_conv_len = get_txt_len(str_in, len) * sizeof(uint16_t); + uint16_t *pos_conv_buf = lv_draw_get_buf(pos_conv_len); + lv_bidi_process_paragraph(str_in, NULL, len, base_dir, pos_conv_buf, pos_conv_len); + return pos_conv_buf[logical_pos]; +} + void lv_bidi_process_paragraph(const char * str_in, char * str_out, uint32_t len, lv_bidi_dir_t base_dir, uint16_t *pos_conv_out, uint16_t pos_conv_len) { uint32_t run_len = 0; @@ -192,7 +207,7 @@ void lv_bidi_process_paragraph(const char * str_in, char * str_out, uint32_t len } else { wr -= rd; pos_conv_wr -= pos_conv_rd; - rtl_reverse(str_out? &str_out[wr]: NULL, str_in, rd, pos_conv_out? &pos_conv_out[pos_conv_wr]: NULL, 0, pos_conv_rd); + rtl_reverse(str_out? &str_out[wr]: NULL, str_in, rd, pos_conv_out? &pos_conv_out[pos_conv_rd]: NULL, 0, pos_conv_rd); } } @@ -206,7 +221,7 @@ void lv_bidi_process_paragraph(const char * str_in, char * str_out, uint32_t len if (str_out) memcpy(&str_out[wr], &str_in[rd], run_len); if (pos_conv_out) fill_pos_conv(&pos_conv_out[pos_conv_wr], pos_conv_run_len, pos_conv_rd); } - else rtl_reverse(str_out? &str_out[wr]: NULL, &str_in[rd], run_len, pos_conv_out? &pos_conv_out[pos_conv_wr] : NULL, pos_conv_rd, pos_conv_run_len); + else rtl_reverse(str_out? &str_out[wr]: NULL, &str_in[rd], run_len, pos_conv_out? &pos_conv_out[pos_conv_rd] : NULL, pos_conv_rd, pos_conv_run_len); wr += run_len; pos_conv_wr += pos_conv_run_len; } else { @@ -216,7 +231,7 @@ void lv_bidi_process_paragraph(const char * str_in, char * str_out, uint32_t len if (str_out) memcpy(&str_out[wr], &str_in[rd], run_len); if (pos_conv_out) fill_pos_conv(&pos_conv_out[pos_conv_wr], pos_conv_run_len, pos_conv_rd); } - else rtl_reverse(str_out? &str_out[wr]: NULL, &str_in[rd], run_len, pos_conv_out? &pos_conv_out[pos_conv_wr] : NULL, pos_conv_rd, pos_conv_run_len); + else rtl_reverse(str_out? &str_out[wr]: NULL, &str_in[rd], run_len, pos_conv_out? &pos_conv_out[pos_conv_rd] : NULL, pos_conv_rd, pos_conv_run_len); } rd += run_len; @@ -241,6 +256,19 @@ uint32_t lv_bidi_get_next_paragraph(const char * txt) * STATIC FUNCTIONS **********************/ +static uint32_t get_txt_len(const char * txt, uint32_t max_len) +{ + uint32_t len = 0; + uint32_t i = 0; + + while(i < max_len && txt[i] != '\0') { + lv_txt_encoded_next(txt, &i); + len++; + } + + return len; +} + static void fill_pos_conv(uint16_t * out, uint16_t len, uint16_t index) { for (uint16_t i = 0; i < len; i++) diff --git a/src/lv_misc/lv_bidi.h b/src/lv_misc/lv_bidi.h index 4d586e570..d5129c4cc 100644 --- a/src/lv_misc/lv_bidi.h +++ b/src/lv_misc/lv_bidi.h @@ -60,6 +60,8 @@ lv_bidi_dir_t lv_bidi_get_letter_dir(uint32_t letter); bool lv_bidi_letter_is_weak(uint32_t letter); bool lv_bidi_letter_is_rtl(uint32_t letter); bool lv_bidi_letter_is_neutral(uint32_t letter); +uint16_t lv_bidi_get_logical_pos(const char * str_in, uint16_t len, lv_bidi_dir_t base_dir, uint32_t visual_pos); +uint16_t lv_bidi_get_visual_pos(const char * str_in, uint16_t len, lv_bidi_dir_t base_dir, uint32_t logical_pos); /********************** * MACROS From 769c1a8f8ac94b45ce5e57b81d12c443daa8549a Mon Sep 17 00:00:00 2001 From: Gabor Kiss-Vamosi Date: Mon, 4 Nov 2019 20:35:47 +0100 Subject: [PATCH 67/82] define empty LV_DEBUG_ASSERT if LV_USE_DEBUG is 0 --- src/lv_core/lv_debug.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/lv_core/lv_debug.h b/src/lv_core/lv_debug.h index f9b8082dd..f225f766a 100644 --- a/src/lv_core/lv_debug.h +++ b/src/lv_core/lv_debug.h @@ -136,6 +136,8 @@ void lv_debug_log_error(const char * msg, uint64_t value); #else /* LV_USE_DEBUG == 0 */ +#define LV_DEBUG_ASSERT(expr, msg, value) do{}while(0) + #define LV_ASSERT_NULL(p) true #define LV_ASSERT_MEM(p) true #define LV_ASSERT_STR(p) true From 6f57de051b35486ee219674d3a5ac8786257476f Mon Sep 17 00:00:00 2001 From: Amir Gonnen Date: Tue, 5 Nov 2019 01:03:40 +0200 Subject: [PATCH 68/82] WIP: pos_conv, bugfixes, use in lv_label --- src/lv_misc/lv_bidi.c | 35 +++++++++++++++++++---------- src/lv_misc/lv_bidi.h | 4 ++-- src/lv_objx/lv_label.c | 50 ++++++++++++++++++++++++++++++++---------- 3 files changed, 63 insertions(+), 26 deletions(-) diff --git a/src/lv_misc/lv_bidi.c b/src/lv_misc/lv_bidi.c index fcb2f7b7c..c52e3212a 100644 --- a/src/lv_misc/lv_bidi.c +++ b/src/lv_misc/lv_bidi.c @@ -140,17 +140,28 @@ bool lv_bidi_letter_is_neutral(uint32_t letter) return false; } -uint16_t lv_bidi_get_logical_pos(const char * str_in, uint16_t len, lv_bidi_dir_t base_dir, uint32_t visual_pos) +uint16_t lv_bidi_get_logical_pos(const char * str_in, char **bidi_txt, uint32_t len, lv_bidi_dir_t base_dir, uint32_t visual_pos) { - return 0; // TODO + uint32_t pos_conv_len = get_txt_len(str_in, len); + void *buf = lv_draw_get_buf(len + pos_conv_len * sizeof(uint16_t)); + if (bidi_txt) *bidi_txt = buf; + uint16_t *pos_conv_buf = (uint16_t*) ((char*)buf + len); + lv_bidi_process_paragraph(str_in, bidi_txt? *bidi_txt: NULL, len, base_dir, pos_conv_buf, pos_conv_len); + return pos_conv_buf[visual_pos]; } -uint16_t lv_bidi_get_visual_pos(const char * str_in, uint16_t len, lv_bidi_dir_t base_dir, uint32_t logical_pos) +uint16_t lv_bidi_get_visual_pos(const char * str_in, char **bidi_txt, uint16_t len, lv_bidi_dir_t base_dir, uint32_t logical_pos) { - uint32_t pos_conv_len = get_txt_len(str_in, len) * sizeof(uint16_t); - uint16_t *pos_conv_buf = lv_draw_get_buf(pos_conv_len); - lv_bidi_process_paragraph(str_in, NULL, len, base_dir, pos_conv_buf, pos_conv_len); - return pos_conv_buf[logical_pos]; + uint32_t pos_conv_len = get_txt_len(str_in, len); + void *buf = lv_draw_get_buf(len + pos_conv_len * sizeof(uint16_t)); + if (bidi_txt) *bidi_txt = buf; + uint16_t *pos_conv_buf = (uint16_t*) ((char*)buf + len); + lv_bidi_process_paragraph(str_in, bidi_txt? *bidi_txt: NULL, len, base_dir, pos_conv_buf, pos_conv_len); + for (uint16_t i = 0; i < pos_conv_len; i++){ + if (pos_conv_buf[i] == logical_pos) + return i; + } + return (uint16_t) -1; } void lv_bidi_process_paragraph(const char * str_in, char * str_out, uint32_t len, lv_bidi_dir_t base_dir, uint16_t *pos_conv_out, uint16_t pos_conv_len) @@ -207,7 +218,7 @@ void lv_bidi_process_paragraph(const char * str_in, char * str_out, uint32_t len } else { wr -= rd; pos_conv_wr -= pos_conv_rd; - rtl_reverse(str_out? &str_out[wr]: NULL, str_in, rd, pos_conv_out? &pos_conv_out[pos_conv_rd]: NULL, 0, pos_conv_rd); + rtl_reverse(str_out? &str_out[wr]: NULL, str_in, rd, pos_conv_out? &pos_conv_out[pos_conv_wr]: NULL, 0, pos_conv_rd); } } @@ -221,7 +232,7 @@ void lv_bidi_process_paragraph(const char * str_in, char * str_out, uint32_t len if (str_out) memcpy(&str_out[wr], &str_in[rd], run_len); if (pos_conv_out) fill_pos_conv(&pos_conv_out[pos_conv_wr], pos_conv_run_len, pos_conv_rd); } - else rtl_reverse(str_out? &str_out[wr]: NULL, &str_in[rd], run_len, pos_conv_out? &pos_conv_out[pos_conv_rd] : NULL, pos_conv_rd, pos_conv_run_len); + else rtl_reverse(str_out? &str_out[wr]: NULL, &str_in[rd], run_len, pos_conv_out? &pos_conv_out[pos_conv_wr] : NULL, pos_conv_rd, pos_conv_run_len); wr += run_len; pos_conv_wr += pos_conv_run_len; } else { @@ -231,7 +242,7 @@ void lv_bidi_process_paragraph(const char * str_in, char * str_out, uint32_t len if (str_out) memcpy(&str_out[wr], &str_in[rd], run_len); if (pos_conv_out) fill_pos_conv(&pos_conv_out[pos_conv_wr], pos_conv_run_len, pos_conv_rd); } - else rtl_reverse(str_out? &str_out[wr]: NULL, &str_in[rd], run_len, pos_conv_out? &pos_conv_out[pos_conv_rd] : NULL, pos_conv_rd, pos_conv_run_len); + else rtl_reverse(str_out? &str_out[wr]: NULL, &str_in[rd], run_len, pos_conv_out? &pos_conv_out[pos_conv_wr] : NULL, pos_conv_rd, pos_conv_run_len); } rd += run_len; @@ -411,8 +422,8 @@ static void rtl_reverse(char * dest, const char * src, uint32_t len, uint16_t *p uint32_t new_letter = letter = char_change_to_pair(letter); if (dest) dest[wr] = (uint8_t)new_letter; if (pos_conv_out) pos_conv_out[pos_conv_wr] = pos_conv_rd_base + pos_conv_letter; - wr += 1; - pos_conv_wr += 1; + wr++; + pos_conv_wr++; } /*Just store the letter*/ else { diff --git a/src/lv_misc/lv_bidi.h b/src/lv_misc/lv_bidi.h index d5129c4cc..09bb04efd 100644 --- a/src/lv_misc/lv_bidi.h +++ b/src/lv_misc/lv_bidi.h @@ -60,8 +60,8 @@ lv_bidi_dir_t lv_bidi_get_letter_dir(uint32_t letter); bool lv_bidi_letter_is_weak(uint32_t letter); bool lv_bidi_letter_is_rtl(uint32_t letter); bool lv_bidi_letter_is_neutral(uint32_t letter); -uint16_t lv_bidi_get_logical_pos(const char * str_in, uint16_t len, lv_bidi_dir_t base_dir, uint32_t visual_pos); -uint16_t lv_bidi_get_visual_pos(const char * str_in, uint16_t len, lv_bidi_dir_t base_dir, uint32_t logical_pos); +uint16_t lv_bidi_get_logical_pos(const char * str_in, char **bidi_txt, uint32_t len, lv_bidi_dir_t base_dir, uint32_t visual_pos); +uint16_t lv_bidi_get_visual_pos(const char * str_in, char **bidi_txt, uint16_t len, lv_bidi_dir_t base_dir, uint32_t logical_pos); /********************** * MACROS diff --git a/src/lv_objx/lv_label.c b/src/lv_objx/lv_label.c index 46cc451c4..bbf6a8469 100644 --- a/src/lv_objx/lv_label.c +++ b/src/lv_objx/lv_label.c @@ -593,6 +593,8 @@ void lv_label_get_letter_pos(const lv_obj_t * label, uint16_t index, lv_point_t uint8_t letter_height = lv_font_get_line_height(font); lv_coord_t y = 0; lv_txt_flag_t flag = LV_TXT_FLAG_NONE; + uint16_t visual_pos; + char *bidi_txt; if(ext->recolor != 0) flag |= LV_TXT_FLAG_RECOLOR; if(ext->expand != 0) flag |= LV_TXT_FLAG_EXPAND; @@ -626,19 +628,27 @@ void lv_label_get_letter_pos(const lv_obj_t * label, uint16_t index, lv_point_t } } +#if LV_USE_BIDI + /*Handle Bidi*/ + visual_pos = lv_bidi_get_visual_pos(&txt[line_start], &bidi_txt, new_line_start - line_start, lv_obj_get_base_dir(label), index - line_start); +#else + visual_pos = index - line_start; + bidi_txt = &txt[line_start]; +#endif + /*Calculate the x coordinate*/ - lv_coord_t x = lv_txt_get_width(&txt[line_start], index - line_start, font, style->text.letter_space, flag); + lv_coord_t x = lv_txt_get_width(bidi_txt, visual_pos, font, style->text.letter_space, flag); if(index != line_start) x += style->text.letter_space; if(align == LV_LABEL_ALIGN_CENTER) { lv_coord_t line_w; - line_w = lv_txt_get_width(&txt[line_start], new_line_start - line_start, font, style->text.letter_space, flag); + line_w = lv_txt_get_width(bidi_txt, new_line_start - line_start, font, style->text.letter_space, flag); x += lv_obj_get_width(label) / 2 - line_w / 2; } else if(align == LV_LABEL_ALIGN_RIGHT) { lv_coord_t line_w; - line_w = lv_txt_get_width(&txt[line_start], new_line_start - line_start, font, style->text.letter_space, flag); + line_w = lv_txt_get_width(bidi_txt, new_line_start - line_start, font, style->text.letter_space, flag); x += lv_obj_get_width(label) - line_w; } @@ -668,6 +678,8 @@ uint16_t lv_label_get_letter_on(const lv_obj_t * label, lv_point_t * pos) uint8_t letter_height = lv_font_get_line_height(font); lv_coord_t y = 0; lv_txt_flag_t flag = LV_TXT_FLAG_NONE; + uint16_t logical_pos; + char *bidi_txt; if(ext->recolor != 0) flag |= LV_TXT_FLAG_RECOLOR; if(ext->expand != 0) flag |= LV_TXT_FLAG_EXPAND; @@ -691,37 +703,44 @@ uint16_t lv_label_get_letter_on(const lv_obj_t * label, lv_point_t * pos) line_start = new_line_start; } +#if LV_USE_BIDI + bidi_txt = lv_draw_get_buf(new_line_start - line_start + 1); + lv_bidi_process_paragraph(txt + line_start, bidi_txt, new_line_start - line_start, lv_obj_get_base_dir(label), NULL, 0); +#else + bidi_txt = txt + line_start; +#endif + /*Calculate the x coordinate*/ lv_coord_t x = 0; if(align == LV_LABEL_ALIGN_CENTER) { lv_coord_t line_w; - line_w = lv_txt_get_width(&txt[line_start], new_line_start - line_start, font, style->text.letter_space, flag); + line_w = lv_txt_get_width(bidi_txt, new_line_start - line_start, font, style->text.letter_space, flag); x += lv_obj_get_width(label) / 2 - line_w / 2; } else if(align == LV_LABEL_ALIGN_RIGHT) { lv_coord_t line_w; - line_w = lv_txt_get_width(&txt[line_start], new_line_start - line_start, font, style->text.letter_space, flag); + line_w = lv_txt_get_width(bidi_txt, new_line_start - line_start, font, style->text.letter_space, flag); x += lv_obj_get_width(label) - line_w; } lv_txt_cmd_state_t cmd_state = LV_TXT_CMD_STATE_WAIT; - uint32_t i = line_start; + uint32_t i = 0; uint32_t i_act = i; uint32_t letter; uint32_t letter_next; if(new_line_start > 0) { - while(i < new_line_start) { + while(i + line_start < new_line_start) { /* Get the current letter.*/ - letter = lv_txt_encoded_next(txt, &i); + letter = lv_txt_encoded_next(bidi_txt, &i); /*Get the next letter too for kerning*/ - letter_next = lv_txt_encoded_next(&txt[i], NULL); + letter_next = lv_txt_encoded_next(&bidi_txt[i], NULL); /*Handle the recolor command*/ if((flag & LV_TXT_FLAG_RECOLOR) != 0) { - if(lv_txt_is_cmd(&cmd_state, txt[i]) != false) { + if(lv_txt_is_cmd(&cmd_state, bidi_txt[i]) != false) { continue; /*Skip the letter is it is part of a command*/ } } @@ -729,7 +748,7 @@ uint16_t lv_label_get_letter_on(const lv_obj_t * label, lv_point_t * pos) x += lv_font_get_glyph_width(font, letter, letter_next); /*Finish if the x position or the last char of the line is reached*/ - if(pos->x < x || i == new_line_start) { + if(pos->x < x || i + line_start == new_line_start) { i = i_act; break; } @@ -738,7 +757,14 @@ uint16_t lv_label_get_letter_on(const lv_obj_t * label, lv_point_t * pos) } } - return lv_encoded_get_char_id(txt, i); +#if LV_USE_BIDI + /*Handle Bidi*/ + logical_pos = lv_bidi_get_logical_pos(&txt[line_start], NULL, new_line_start - line_start, lv_obj_get_base_dir(label), lv_encoded_get_char_id(bidi_txt, i)); +#else + logical_pos = lv_encoded_get_char_id(bidi_txt, i); +#endif + + return logical_pos; } /** From 5d5a8b4894f54988bf0f904b389284c23417d4d3 Mon Sep 17 00:00:00 2001 From: Gabor Kiss-Vamosi Date: Tue, 5 Nov 2019 16:00:32 +0100 Subject: [PATCH 69/82] convert lv_bidi_get_visual_pos to byteindex --- src/lv_objx/lv_label.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/lv_objx/lv_label.c b/src/lv_objx/lv_label.c index bbf6a8469..7427e69a7 100644 --- a/src/lv_objx/lv_label.c +++ b/src/lv_objx/lv_label.c @@ -631,11 +631,16 @@ void lv_label_get_letter_pos(const lv_obj_t * label, uint16_t index, lv_point_t #if LV_USE_BIDI /*Handle Bidi*/ visual_pos = lv_bidi_get_visual_pos(&txt[line_start], &bidi_txt, new_line_start - line_start, lv_obj_get_base_dir(label), index - line_start); + + printf("vp:%d, ", visual_pos); + visual_pos = lv_txt_encoded_get_byte_id(bidi_txt, visual_pos); + printf("vpb:%d, ", visual_pos); #else visual_pos = index - line_start; bidi_txt = &txt[line_start]; #endif + /*Calculate the x coordinate*/ lv_coord_t x = lv_txt_get_width(bidi_txt, visual_pos, font, style->text.letter_space, flag); From 5441cf9998aadb7393d09e451130c6f6b26d6bae Mon Sep 17 00:00:00 2001 From: Gabor Kiss-Vamosi Date: Wed, 6 Nov 2019 05:19:06 +0100 Subject: [PATCH 70/82] bidi fixes + add missing prefix to lv_encoded_get_char_id --- src/lv_draw/lv_draw_label.c | 2 +- src/lv_misc/lv_txt.c | 4 ++-- src/lv_misc/lv_txt.h | 2 +- src/lv_objx/lv_label.c | 29 +++++++++++++---------------- 4 files changed, 17 insertions(+), 20 deletions(-) diff --git a/src/lv_draw/lv_draw_label.c b/src/lv_draw/lv_draw_label.c index 5bd0592c5..d7650690c 100644 --- a/src/lv_draw/lv_draw_label.c +++ b/src/lv_draw/lv_draw_label.c @@ -220,7 +220,7 @@ void lv_draw_label(const lv_area_t * coords, const lv_area_t * mask, const lv_st letter_w = lv_font_get_glyph_width(font, letter, letter_next); if(sel_start != 0xFFFF && sel_end != 0xFFFF) { - int char_ind = lv_encoded_get_char_id(bidi_txt, i); + int char_ind = lv_txt_encoded_get_char_id(bidi_txt, i); /*Do not draw the rectangle on the character at `sel_start`.*/ if(char_ind > sel_start && char_ind <= sel_end) { lv_area_t sel_coords; diff --git a/src/lv_misc/lv_txt.c b/src/lv_misc/lv_txt.c index d18e456b0..0c4027761 100644 --- a/src/lv_misc/lv_txt.c +++ b/src/lv_misc/lv_txt.c @@ -56,7 +56,7 @@ uint32_t (*lv_txt_encoded_conv_wc)(uint32_t) = lv_txt_utf8_con uint32_t (*lv_txt_encoded_next)(const char *, uint32_t *) = lv_txt_utf8_next; uint32_t (*lv_txt_encoded_prev)(const char *, uint32_t *) = lv_txt_utf8_prev; uint32_t (*lv_txt_encoded_get_byte_id)(const char *, uint32_t) = lv_txt_utf8_get_byte_id; -uint32_t (*lv_encoded_get_char_id)(const char *, uint32_t) = lv_txt_utf8_get_char_id; +uint32_t (*lv_txt_encoded_get_char_id)(const char *, uint32_t) = lv_txt_utf8_get_char_id; uint32_t (*lv_txt_get_encoded_length)(const char *) = lv_txt_utf8_get_length; #elif LV_TXT_ENC == LV_TXT_ENC_ASCII uint8_t (*lv_txt_encoded_size)(const char *) = lv_txt_iso8859_1_size; @@ -65,7 +65,7 @@ uint32_t (*lv_txt_encoded_conv_wc)(uint32_t) = lv_txt_iso8859_ uint32_t (*lv_txt_encoded_next)(const char *, uint32_t *) = lv_txt_iso8859_1_next; uint32_t (*lv_txt_encoded_prev)(const char *, uint32_t *) = lv_txt_iso8859_1_prev; uint32_t (*lv_txt_encoded_get_byte_id)(const char *, uint32_t) = lv_txt_iso8859_1_get_byte_id; -uint32_t (*lv_encoded_get_char_id)(const char *, uint32_t) = lv_txt_iso8859_1_get_char_id; +uint32_t (*lv_txt_encoded_get_char_id)(const char *, uint32_t) = lv_txt_iso8859_1_get_char_id; uint32_t (*lv_txt_get_encoded_length)(const char *) = lv_txt_iso8859_1_get_length; #endif diff --git a/src/lv_misc/lv_txt.h b/src/lv_misc/lv_txt.h index 6fc6e4a63..865e2c97c 100644 --- a/src/lv_misc/lv_txt.h +++ b/src/lv_misc/lv_txt.h @@ -188,7 +188,7 @@ extern uint32_t (*lv_txt_encoded_get_byte_id)(const char *, uint32_t); * @param byte_id byte index * @return character index of the letter at 'byte_id'th position */ -extern uint32_t (*lv_encoded_get_char_id)(const char *, uint32_t); +extern uint32_t (*lv_txt_encoded_get_char_id)(const char *, uint32_t); /** * Get the number of characters (and NOT bytes) in a string. diff --git a/src/lv_objx/lv_label.c b/src/lv_objx/lv_label.c index 7427e69a7..3bdfd04a8 100644 --- a/src/lv_objx/lv_label.c +++ b/src/lv_objx/lv_label.c @@ -578,7 +578,7 @@ uint16_t lv_label_get_anim_speed(const lv_obj_t * label) * index (different in UTF-8) * @param pos store the result here (E.g. index = 0 gives 0;0 coordinates) */ -void lv_label_get_letter_pos(const lv_obj_t * label, uint16_t index, lv_point_t * pos) +void lv_label_get_letter_pos(const lv_obj_t * label, uint16_t char_id, lv_point_t * pos) { LV_ASSERT_OBJ(label, LV_OBJX_NAME); LV_ASSERT_NULL(pos); @@ -593,8 +593,6 @@ void lv_label_get_letter_pos(const lv_obj_t * label, uint16_t index, lv_point_t uint8_t letter_height = lv_font_get_line_height(font); lv_coord_t y = 0; lv_txt_flag_t flag = LV_TXT_FLAG_NONE; - uint16_t visual_pos; - char *bidi_txt; if(ext->recolor != 0) flag |= LV_TXT_FLAG_RECOLOR; if(ext->expand != 0) flag |= LV_TXT_FLAG_EXPAND; @@ -608,12 +606,12 @@ void lv_label_get_letter_pos(const lv_obj_t * label, uint16_t index, lv_point_t max_w = LV_COORD_MAX; } - index = lv_txt_encoded_get_byte_id(txt, index); + uint16_t byte_id = lv_txt_encoded_get_byte_id(txt, char_id); /*Search the line of the index letter */; while(txt[new_line_start] != '\0') { new_line_start += lv_txt_get_next_line(&txt[line_start], font, style->text.letter_space, max_w, flag); - if(index < new_line_start || txt[new_line_start] == '\0') + if(byte_id < new_line_start || txt[new_line_start] == '\0') break; /*The line of 'index' letter begins at 'line_start'*/ y += letter_height + style->text.line_space; @@ -621,30 +619,29 @@ void lv_label_get_letter_pos(const lv_obj_t * label, uint16_t index, lv_point_t } /*If the last character is line break then go to the next line*/ - if(index > 0) { - if((txt[index - 1] == '\n' || txt[index - 1] == '\r') && txt[index] == '\0') { + if(byte_id > 0) { + if((txt[byte_id - 1] == '\n' || txt[byte_id - 1] == '\r') && txt[byte_id] == '\0') { y += letter_height + style->text.line_space; - line_start = index; + line_start = byte_id; } } + char *bidi_txt; #if LV_USE_BIDI /*Handle Bidi*/ - visual_pos = lv_bidi_get_visual_pos(&txt[line_start], &bidi_txt, new_line_start - line_start, lv_obj_get_base_dir(label), index - line_start); + uint16_t line_char_id = lv_txt_encoded_get_char_id(&txt[line_start], byte_id - line_start); - printf("vp:%d, ", visual_pos); - visual_pos = lv_txt_encoded_get_byte_id(bidi_txt, visual_pos); - printf("vpb:%d, ", visual_pos); + uint16_t visual_char_pos = lv_bidi_get_visual_pos(&txt[line_start], &bidi_txt, new_line_start - line_start, lv_obj_get_base_dir(label), line_char_id); + uint16_t visual_byte_pos = lv_txt_encoded_get_byte_id(bidi_txt, visual_char_pos); #else - visual_pos = index - line_start; bidi_txt = &txt[line_start]; #endif /*Calculate the x coordinate*/ - lv_coord_t x = lv_txt_get_width(bidi_txt, visual_pos, font, style->text.letter_space, flag); + lv_coord_t x = lv_txt_get_width(bidi_txt, visual_byte_pos, font, style->text.letter_space, flag); - if(index != line_start) x += style->text.letter_space; + if(char_id != line_start) x += style->text.letter_space; if(align == LV_LABEL_ALIGN_CENTER) { lv_coord_t line_w; @@ -764,7 +761,7 @@ uint16_t lv_label_get_letter_on(const lv_obj_t * label, lv_point_t * pos) #if LV_USE_BIDI /*Handle Bidi*/ - logical_pos = lv_bidi_get_logical_pos(&txt[line_start], NULL, new_line_start - line_start, lv_obj_get_base_dir(label), lv_encoded_get_char_id(bidi_txt, i)); + logical_pos = lv_bidi_get_logical_pos(&txt[line_start], NULL, new_line_start - line_start, lv_obj_get_base_dir(label), lv_txt_encoded_get_char_id(bidi_txt, i)); #else logical_pos = lv_encoded_get_char_id(bidi_txt, i); #endif From 86f44c974d24d950ed83666a30c8c3f73e6ae796 Mon Sep 17 00:00:00 2001 From: Gabor Kiss-Vamosi Date: Wed, 6 Nov 2019 05:32:42 +0100 Subject: [PATCH 71/82] cpicker: set default type --- src/lv_objx/lv_cpicker.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/lv_objx/lv_cpicker.c b/src/lv_objx/lv_cpicker.c index d2bc62523..ae3d68cd3 100644 --- a/src/lv_objx/lv_cpicker.c +++ b/src/lv_objx/lv_cpicker.c @@ -106,6 +106,7 @@ lv_obj_t * lv_cpicker_create(lv_obj_t * par, const lv_obj_t * copy) if(ext == NULL) return NULL; /*Initialize the allocated 'ext' */ + ext->type = LV_CPICKER_DEF_TYPE; ext->hsv = LV_CPICKER_DEF_HSV; ext->indic.style = &lv_style_plain; ext->indic.colored = 0; @@ -121,6 +122,7 @@ lv_obj_t * lv_cpicker_create(lv_obj_t * par, const lv_obj_t * copy) /*If no copy do the basic initialization*/ if(copy == NULL) { + lv_obj_set_size(new_cpicker, LV_DPI * 2, LV_DPI * 2); lv_obj_set_protect(new_cpicker, LV_PROTECT_PRESS_LOST); lv_theme_t * th = lv_theme_get_current(); if(th) { From 45c6dbab6290b96165e431cc9ac6e4bea853c4b3 Mon Sep 17 00:00:00 2001 From: embeddedt <42941056+embeddedt@users.noreply.github.com> Date: Wed, 6 Nov 2019 08:11:58 -0500 Subject: [PATCH 72/82] lv_cpicker: credit @AloyseTech and @paulpv --- src/lv_objx/lv_cpicker.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/lv_objx/lv_cpicker.c b/src/lv_objx/lv_cpicker.c index ae3d68cd3..cf1f1a129 100644 --- a/src/lv_objx/lv_cpicker.c +++ b/src/lv_objx/lv_cpicker.c @@ -1,6 +1,7 @@ /** * @file lv_cpicker.c * + * From @AloyseTech and @paulpv. */ /********************* From a3a326c2ffaffeefd1d5ad6faa33031b497a0fb8 Mon Sep 17 00:00:00 2001 From: Gabor Kiss-Vamosi Date: Fri, 8 Nov 2019 13:49:52 +0100 Subject: [PATCH 73/82] fix lv_label_get_letter_on in case of multi-line texts --- src/lv_objx/lv_label.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lv_objx/lv_label.c b/src/lv_objx/lv_label.c index 3bdfd04a8..ab81f4a24 100644 --- a/src/lv_objx/lv_label.c +++ b/src/lv_objx/lv_label.c @@ -766,7 +766,7 @@ uint16_t lv_label_get_letter_on(const lv_obj_t * label, lv_point_t * pos) logical_pos = lv_encoded_get_char_id(bidi_txt, i); #endif - return logical_pos; + return logical_pos + line_start; } /** From 0130f3e5f2606388d466d5476fdd1c4c80810b8c Mon Sep 17 00:00:00 2001 From: Amir Gonnen Date: Sat, 9 Nov 2019 01:02:51 +0200 Subject: [PATCH 74/82] Add RTL indication to pos_conv When getting visual/logical pos, also get whether this pos is RTL (was reversed) --- src/lv_misc/lv_bidi.c | 22 +++++++++++++++------- src/lv_misc/lv_bidi.h | 4 ++-- src/lv_objx/lv_label.c | 8 ++++++-- 3 files changed, 23 insertions(+), 11 deletions(-) diff --git a/src/lv_misc/lv_bidi.c b/src/lv_misc/lv_bidi.c index c52e3212a..0f1153b52 100644 --- a/src/lv_misc/lv_bidi.c +++ b/src/lv_misc/lv_bidi.c @@ -18,6 +18,11 @@ *********************/ #define LV_BIDI_BRACKLET_DEPTH 4 +// Highest bit of the 16-bit pos_conv value specifies whether this pos is RTL or not +#define GET_POS(x) ((x) & 0x7FFF) +#define IS_RTL_POS(x) (((x) & 0x8000) != 0) +#define SET_RTL_POS(x, is_rtl) (GET_POS(x) | ((is_rtl)? 0x8000: 0)) + /********************** * TYPEDEFS **********************/ @@ -140,17 +145,18 @@ bool lv_bidi_letter_is_neutral(uint32_t letter) return false; } -uint16_t lv_bidi_get_logical_pos(const char * str_in, char **bidi_txt, uint32_t len, lv_bidi_dir_t base_dir, uint32_t visual_pos) +uint16_t lv_bidi_get_logical_pos(const char * str_in, char **bidi_txt, uint32_t len, lv_bidi_dir_t base_dir, uint32_t visual_pos, bool *is_rtl) { uint32_t pos_conv_len = get_txt_len(str_in, len); void *buf = lv_draw_get_buf(len + pos_conv_len * sizeof(uint16_t)); if (bidi_txt) *bidi_txt = buf; uint16_t *pos_conv_buf = (uint16_t*) ((char*)buf + len); lv_bidi_process_paragraph(str_in, bidi_txt? *bidi_txt: NULL, len, base_dir, pos_conv_buf, pos_conv_len); - return pos_conv_buf[visual_pos]; + if (is_rtl) *is_rtl = IS_RTL_POS(pos_conv_buf[visual_pos]); + return GET_POS(pos_conv_buf[visual_pos]); } -uint16_t lv_bidi_get_visual_pos(const char * str_in, char **bidi_txt, uint16_t len, lv_bidi_dir_t base_dir, uint32_t logical_pos) +uint16_t lv_bidi_get_visual_pos(const char * str_in, char **bidi_txt, uint16_t len, lv_bidi_dir_t base_dir, uint32_t logical_pos, bool *is_rtl) { uint32_t pos_conv_len = get_txt_len(str_in, len); void *buf = lv_draw_get_buf(len + pos_conv_len * sizeof(uint16_t)); @@ -158,8 +164,10 @@ uint16_t lv_bidi_get_visual_pos(const char * str_in, char **bidi_txt, uint16_t l uint16_t *pos_conv_buf = (uint16_t*) ((char*)buf + len); lv_bidi_process_paragraph(str_in, bidi_txt? *bidi_txt: NULL, len, base_dir, pos_conv_buf, pos_conv_len); for (uint16_t i = 0; i < pos_conv_len; i++){ - if (pos_conv_buf[i] == logical_pos) + if (GET_POS(pos_conv_buf[i]) == logical_pos){ + if (is_rtl) *is_rtl = IS_RTL_POS(pos_conv_buf[i]); return i; + } } return (uint16_t) -1; } @@ -284,7 +292,7 @@ static void fill_pos_conv(uint16_t * out, uint16_t len, uint16_t index) { for (uint16_t i = 0; i < len; i++) { - out[i] = index; + out[i] = SET_RTL_POS(index, false); index++; } } @@ -421,14 +429,14 @@ static void rtl_reverse(char * dest, const char * src, uint32_t len, uint16_t *p if(letter_size == 1) { uint32_t new_letter = letter = char_change_to_pair(letter); if (dest) dest[wr] = (uint8_t)new_letter; - if (pos_conv_out) pos_conv_out[pos_conv_wr] = pos_conv_rd_base + pos_conv_letter; + if (pos_conv_out) pos_conv_out[pos_conv_wr] = SET_RTL_POS(pos_conv_rd_base + pos_conv_letter, true); wr++; pos_conv_wr++; } /*Just store the letter*/ else { if (dest) memcpy(&dest[wr], &src[i], letter_size); - if (pos_conv_out) pos_conv_out[pos_conv_wr] = pos_conv_rd_base + pos_conv_i; + if (pos_conv_out) pos_conv_out[pos_conv_wr] = SET_RTL_POS(pos_conv_rd_base + pos_conv_i, true); wr += letter_size; pos_conv_wr++; } diff --git a/src/lv_misc/lv_bidi.h b/src/lv_misc/lv_bidi.h index 09bb04efd..215727aa7 100644 --- a/src/lv_misc/lv_bidi.h +++ b/src/lv_misc/lv_bidi.h @@ -60,8 +60,8 @@ lv_bidi_dir_t lv_bidi_get_letter_dir(uint32_t letter); bool lv_bidi_letter_is_weak(uint32_t letter); bool lv_bidi_letter_is_rtl(uint32_t letter); bool lv_bidi_letter_is_neutral(uint32_t letter); -uint16_t lv_bidi_get_logical_pos(const char * str_in, char **bidi_txt, uint32_t len, lv_bidi_dir_t base_dir, uint32_t visual_pos); -uint16_t lv_bidi_get_visual_pos(const char * str_in, char **bidi_txt, uint16_t len, lv_bidi_dir_t base_dir, uint32_t logical_pos); +uint16_t lv_bidi_get_logical_pos(const char * str_in, char **bidi_txt, uint32_t len, lv_bidi_dir_t base_dir, uint32_t visual_pos, bool *is_rtl); +uint16_t lv_bidi_get_visual_pos(const char * str_in, char **bidi_txt, uint16_t len, lv_bidi_dir_t base_dir, uint32_t logical_pos, bool *is_rtl); /********************** * MACROS diff --git a/src/lv_objx/lv_label.c b/src/lv_objx/lv_label.c index ab81f4a24..de3874fe4 100644 --- a/src/lv_objx/lv_label.c +++ b/src/lv_objx/lv_label.c @@ -631,7 +631,9 @@ void lv_label_get_letter_pos(const lv_obj_t * label, uint16_t char_id, lv_point_ /*Handle Bidi*/ uint16_t line_char_id = lv_txt_encoded_get_char_id(&txt[line_start], byte_id - line_start); - uint16_t visual_char_pos = lv_bidi_get_visual_pos(&txt[line_start], &bidi_txt, new_line_start - line_start, lv_obj_get_base_dir(label), line_char_id); + bool is_rtl; + uint16_t visual_char_pos = lv_bidi_get_visual_pos(&txt[line_start], &bidi_txt, new_line_start - line_start, lv_obj_get_base_dir(label), line_char_id, &is_rtl); + if (is_rtl) visual_char_pos++; uint16_t visual_byte_pos = lv_txt_encoded_get_byte_id(bidi_txt, visual_char_pos); #else bidi_txt = &txt[line_start]; @@ -761,7 +763,9 @@ uint16_t lv_label_get_letter_on(const lv_obj_t * label, lv_point_t * pos) #if LV_USE_BIDI /*Handle Bidi*/ - logical_pos = lv_bidi_get_logical_pos(&txt[line_start], NULL, new_line_start - line_start, lv_obj_get_base_dir(label), lv_txt_encoded_get_char_id(bidi_txt, i)); + bool is_rtl; + logical_pos = lv_bidi_get_logical_pos(&txt[line_start], NULL, new_line_start - line_start, lv_obj_get_base_dir(label), lv_txt_encoded_get_char_id(bidi_txt, i), &is_rtl); + if (is_rtl) logical_pos++; #else logical_pos = lv_encoded_get_char_id(bidi_txt, i); #endif From 96b9114a5afbe06b5d37b8c83d3cbd9135248241 Mon Sep 17 00:00:00 2001 From: Gabor Kiss-Vamosi Date: Sat, 9 Nov 2019 01:53:02 +0100 Subject: [PATCH 75/82] bidi fixes for multi line text handling --- src/lv_draw/lv_draw_label.c | 5 +++-- src/lv_objx/lv_label.c | 4 ++-- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/lv_draw/lv_draw_label.c b/src/lv_draw/lv_draw_label.c index d7650690c..2a5b22903 100644 --- a/src/lv_draw/lv_draw_label.c +++ b/src/lv_draw/lv_draw_label.c @@ -166,13 +166,14 @@ void lv_draw_label(const lv_area_t * coords, const lv_area_t * mask, const lv_st i = 0; uint32_t letter; uint32_t letter_next; - while(i < line_end - line_start) { #if LV_USE_BIDI char *bidi_txt = lv_draw_get_buf(line_end - line_start + 1); lv_bidi_process_paragraph(txt + line_start, bidi_txt, line_end - line_start, bidi_dir, NULL, 0); #else const char *bidi_txt = txt + line_start; #endif + while(i < line_end - line_start) { + letter = lv_txt_encoded_next(bidi_txt, &i); letter_next = lv_txt_encoded_next(&bidi_txt[i], NULL); @@ -220,7 +221,7 @@ void lv_draw_label(const lv_area_t * coords, const lv_area_t * mask, const lv_st letter_w = lv_font_get_glyph_width(font, letter, letter_next); if(sel_start != 0xFFFF && sel_end != 0xFFFF) { - int char_ind = lv_txt_encoded_get_char_id(bidi_txt, i); + int char_ind = lv_txt_encoded_get_char_id(bidi_txt, i + line_start); /*Do not draw the rectangle on the character at `sel_start`.*/ if(char_ind > sel_start && char_ind <= sel_end) { lv_area_t sel_coords; diff --git a/src/lv_objx/lv_label.c b/src/lv_objx/lv_label.c index de3874fe4..cd02a0ed0 100644 --- a/src/lv_objx/lv_label.c +++ b/src/lv_objx/lv_label.c @@ -767,10 +767,10 @@ uint16_t lv_label_get_letter_on(const lv_obj_t * label, lv_point_t * pos) logical_pos = lv_bidi_get_logical_pos(&txt[line_start], NULL, new_line_start - line_start, lv_obj_get_base_dir(label), lv_txt_encoded_get_char_id(bidi_txt, i), &is_rtl); if (is_rtl) logical_pos++; #else - logical_pos = lv_encoded_get_char_id(bidi_txt, i); + logical_pos = lv_txt_encoded_get_char_id(bidi_txt, i); #endif - return logical_pos + line_start; + return logical_pos + lv_txt_encoded_get_char_id(txt, line_start) ; } /** From 6f762bb7c776894ca49f8143cf28dade4099d988 Mon Sep 17 00:00:00 2001 From: Gabor Kiss-Vamosi Date: Sun, 10 Nov 2019 10:45:49 +0100 Subject: [PATCH 76/82] fix lv_cpicker_set_color with 16 bit color depth and byte swap Fixes #1257 --- src/lv_objx/lv_cpicker.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/lv_objx/lv_cpicker.c b/src/lv_objx/lv_cpicker.c index cf1f1a129..73197d374 100644 --- a/src/lv_objx/lv_cpicker.c +++ b/src/lv_objx/lv_cpicker.c @@ -275,7 +275,12 @@ bool lv_cpicker_set_hsv(lv_obj_t * cpicker, lv_color_hsv_t hsv) */ bool lv_cpicker_set_color(lv_obj_t * cpicker, lv_color_t color) { +#if LV_COLOR_DEPTH == 16 && LV_COLOR_16_SWAP != 0 + uint8_t green = (color.ch.green_h << 3) + color.ch.green_l; + return lv_cpicker_set_hsv(cpicker, lv_color_rgb_to_hsv(color.ch.red, green, color.ch.blue)); +#else return lv_cpicker_set_hsv(cpicker, lv_color_rgb_to_hsv(color.ch.red, color.ch.green, color.ch.blue)); +#endif } /** From 8dfcba6aa864f3aeb66139c815c8b7e44b3e7db0 Mon Sep 17 00:00:00 2001 From: Gabor Kiss-Vamosi Date: Sun, 10 Nov 2019 10:52:49 +0100 Subject: [PATCH 77/82] text sel fixes with bidi --- src/lv_draw/lv_draw_label.c | 21 +++++++++++++++++++-- src/lv_objx/lv_label.c | 2 +- 2 files changed, 20 insertions(+), 3 deletions(-) diff --git a/src/lv_draw/lv_draw_label.c b/src/lv_draw/lv_draw_label.c index 2a5b22903..ae6470ab8 100644 --- a/src/lv_draw/lv_draw_label.c +++ b/src/lv_draw/lv_draw_label.c @@ -113,6 +113,24 @@ void lv_draw_label(const lv_area_t * coords, const lv_area_t * mask, const lv_st pos.y += hint->y; } + if(sel_start != 0xFFFF) { + sel_start = lv_bidi_get_visual_pos(txt, NULL, strlen(txt), bidi_dir, sel_start, NULL); + sel_start = lv_txt_encoded_get_byte_id(txt, sel_start); + } + + if(sel_end != 0xFFFF) { + sel_end = lv_bidi_get_visual_pos(txt, NULL, strlen(txt), bidi_dir, sel_end, NULL); + sel_end = lv_txt_encoded_get_byte_id(txt, sel_end); + } + + if(sel_start > sel_end) { + uint16_t tmp = sel_start; + sel_start = sel_end; + sel_end = tmp; + } + + + uint32_t line_end = line_start + lv_txt_get_next_line(&txt[line_start], font, style->text.letter_space, w, flag); /*Go the first visible line*/ @@ -221,9 +239,8 @@ void lv_draw_label(const lv_area_t * coords, const lv_area_t * mask, const lv_st letter_w = lv_font_get_glyph_width(font, letter, letter_next); if(sel_start != 0xFFFF && sel_end != 0xFFFF) { - int char_ind = lv_txt_encoded_get_char_id(bidi_txt, i + line_start); /*Do not draw the rectangle on the character at `sel_start`.*/ - if(char_ind > sel_start && char_ind <= sel_end) { + if(i + line_start > sel_start && i + line_start <= sel_end) { lv_area_t sel_coords; sel_coords.x1 = pos.x; sel_coords.y1 = pos.y; diff --git a/src/lv_objx/lv_label.c b/src/lv_objx/lv_label.c index cd02a0ed0..004da981b 100644 --- a/src/lv_objx/lv_label.c +++ b/src/lv_objx/lv_label.c @@ -770,7 +770,7 @@ uint16_t lv_label_get_letter_on(const lv_obj_t * label, lv_point_t * pos) logical_pos = lv_txt_encoded_get_char_id(bidi_txt, i); #endif - return logical_pos + lv_txt_encoded_get_char_id(txt, line_start) ; + return logical_pos + lv_txt_encoded_get_char_id(txt, line_start); } /** From 6eaf8dd6d3eefc87455ad856999295bbe92b812d Mon Sep 17 00:00:00 2001 From: Gabor Kiss-Vamosi Date: Sun, 10 Nov 2019 11:03:19 +0100 Subject: [PATCH 78/82] text sel fix, if start > end --- src/lv_objx/lv_label.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/lv_objx/lv_label.c b/src/lv_objx/lv_label.c index 004da981b..40d2cead5 100644 --- a/src/lv_objx/lv_label.c +++ b/src/lv_objx/lv_label.c @@ -831,10 +831,11 @@ bool lv_label_is_char_under_pos(const lv_obj_t * label, lv_point_t * pos) uint8_t letter_height = lv_font_get_line_height(font); lv_coord_t y = 0; lv_txt_flag_t flag = LV_TXT_FLAG_NONE; + lv_label_align_t align = lv_label_get_align(label); if(ext->recolor != 0) flag |= LV_TXT_FLAG_RECOLOR; if(ext->expand != 0) flag |= LV_TXT_FLAG_EXPAND; - if(ext->align == LV_LABEL_ALIGN_CENTER) flag |= LV_TXT_FLAG_CENTER; + if(align == LV_LABEL_ALIGN_CENTER) flag |= LV_TXT_FLAG_CENTER; /*If the width will be expanded set the max length to very big */ if(ext->long_mode == LV_LABEL_LONG_EXPAND) { @@ -854,11 +855,16 @@ bool lv_label_is_char_under_pos(const lv_obj_t * label, lv_point_t * pos) /*Calculate the x coordinate*/ lv_coord_t x = 0; lv_coord_t last_x = 0; - if(ext->align == LV_LABEL_ALIGN_CENTER) { + if(align == LV_LABEL_ALIGN_CENTER) { lv_coord_t line_w; line_w = lv_txt_get_width(&txt[line_start], new_line_start - line_start, font, style->text.letter_space, flag); x += lv_obj_get_width(label) / 2 - line_w / 2; } + else if(align == LV_LABEL_ALIGN_RIGHT) { + lv_coord_t line_w; + line_w = lv_txt_get_width(&txt[line_start], new_line_start - line_start, font, style->text.letter_space, flag); + x += lv_obj_get_width(label) - line_w; + } lv_txt_cmd_state_t cmd_state = LV_TXT_CMD_STATE_WAIT; From 57e2a6d983e101e3e022912afae76fd984caac71 Mon Sep 17 00:00:00 2001 From: Brian Pugh Date: Sun, 10 Nov 2019 21:44:27 -0800 Subject: [PATCH 79/82] fix 1bit lv_color compilation warnings/errors introduced by 3da868a0905ccbdafb4bbbf9c301d4f66eb2cf86 --- src/lv_misc/lv_color.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/lv_misc/lv_color.h b/src/lv_misc/lv_color.h index 04551fe7f..95542afb6 100644 --- a/src/lv_misc/lv_color.h +++ b/src/lv_misc/lv_color.h @@ -392,10 +392,10 @@ static inline uint8_t lv_color_brightness(lv_color_t color) /* The most simple macro to create a color from R,G and B values */ #if LV_COLOR_DEPTH == 1 -#define LV_COLOR_MAKE(r8, g8, b8) ((lv_color_t){(b8 >> 7 | g8 >> 7 | r8 >> 7)}) +#define LV_COLOR_MAKE(r8, g8, b8) ((lv_color_t){.full = (b8 >> 7 | g8 >> 7 | r8 >> 7)}) static inline lv_color_t lv_color_make(int r8, int g8, int b8) { - lv_color_t color; + lv_color_t color = { 0 }; color.full = (b8 >> 7 | g8 >> 7 | r8 >> 7); return color; } From 183d849e8429afd66ad284919ffc019c78344a71 Mon Sep 17 00:00:00 2001 From: Brian Pugh Date: Sun, 10 Nov 2019 23:16:54 -0800 Subject: [PATCH 80/82] Fix cursor wrapping described in https://github.com/littlevgl/lvgl/issues/1256 --- src/lv_misc/lv_txt.c | 20 ++++++++--------- src/lv_objx/lv_label.c | 50 +++++++++++++++++++++++------------------- 2 files changed, 37 insertions(+), 33 deletions(-) diff --git a/src/lv_misc/lv_txt.c b/src/lv_misc/lv_txt.c index f89671518..b7570b1cb 100644 --- a/src/lv_misc/lv_txt.c +++ b/src/lv_misc/lv_txt.c @@ -266,6 +266,9 @@ static uint16_t lv_txt_get_next_word(const char * txt, const lv_font_t * font, /** * Get the next line of text. Check line length and break chars too. + * + * A line of txt includes the \n character. + * * @param txt a '\0' terminated string * @param font pointer to a font * @param letter_space letter space @@ -295,18 +298,13 @@ uint16_t lv_txt_get_next_line(const char * txt, const lv_font_t * font, i += advance; - if(txt[i] == '\n') break; - } + if(txt[0] == '\n') break; + + if(txt[i] == '\n'){ + i++; /* Include the following newline in the current line */ + break; + } - /* If this is the last of the string, make sure pointer is at NULL-terminator. - * This catches the case, for example of a string ending in "\n" */ - if(txt[i] != '\0'){ - uint32_t i_next = i; - int tmp; - uint32_t letter_next = lv_txt_encoded_next(txt, &i_next); /*Gets current character*/ - tmp = i_next; - letter_next = lv_txt_encoded_next(txt, &i_next); /*Gets subsequent character*/ - if(letter_next == '\0') i = tmp; } /*Always step at least one to avoid infinite loops*/ diff --git a/src/lv_objx/lv_label.c b/src/lv_objx/lv_label.c index b52f06052..c9f3b81a1 100644 --- a/src/lv_objx/lv_label.c +++ b/src/lv_objx/lv_label.c @@ -661,7 +661,15 @@ uint16_t lv_label_get_letter_on(const lv_obj_t * label, lv_point_t * pos) while(txt[line_start] != '\0') { new_line_start += lv_txt_get_next_line(&txt[line_start], font, style->text.letter_space, max_w, flag); - if(pos->y <= y + letter_height) break; /*The line is found (stored in 'line_start')*/ + if(pos->y <= y + letter_height) { + /*The line is found (stored in 'line_start')*/ + /* Include the NULL terminator in the last line */ + uint32_t tmp = new_line_start; + uint32_t letter; + letter = lv_txt_encoded_prev(txt, &tmp); + if(letter != '\n' && txt[new_line_start] == '\0' ) new_line_start++; + break; + } y += letter_height + style->text.line_space; line_start = new_line_start; @@ -682,31 +690,29 @@ uint16_t lv_label_get_letter_on(const lv_obj_t * label, lv_point_t * pos) uint32_t letter; uint32_t letter_next; - if(new_line_start > 0) { - while(i < new_line_start) { - /* Get the current letter.*/ - letter = lv_txt_encoded_next(txt, &i); + while(i < new_line_start) { + /* Get the current letter.*/ + letter = lv_txt_encoded_next(txt, &i); - /*Get the next letter too for kerning*/ - letter_next = lv_txt_encoded_next(&txt[i], NULL); + /*Get the next letter too for kerning*/ + letter_next = lv_txt_encoded_next(&txt[i], NULL); - /*Handle the recolor command*/ - if((flag & LV_TXT_FLAG_RECOLOR) != 0) { - if(lv_txt_is_cmd(&cmd_state, txt[i]) != false) { - continue; /*Skip the letter is it is part of a command*/ - } + /*Handle the recolor command*/ + if((flag & LV_TXT_FLAG_RECOLOR) != 0) { + if(lv_txt_is_cmd(&cmd_state, txt[i]) != false) { + continue; /*Skip the letter is it is part of a command*/ } - - x += lv_font_get_glyph_width(font, letter, letter_next); - - /*Finish if the x position or the last char of the line is reached*/ - if(pos->x < x || i == new_line_start) { - i = i_act; - break; - } - x += style->text.letter_space; - i_act = i; } + + x += lv_font_get_glyph_width(font, letter, letter_next); + + /*Finish if the x position or the last char of the line is reached*/ + if(pos->x < x || i == new_line_start) { + i = i_act; + break; + } + x += style->text.letter_space; + i_act = i; } return lv_encoded_get_char_id(txt, i); From c4f8d8cd5bbe267cada86d3817d59ec3fd097875 Mon Sep 17 00:00:00 2001 From: Gabor Kiss-Vamosi Date: Mon, 11 Nov 2019 11:10:01 +0100 Subject: [PATCH 81/82] bidi: txt_sel fixes --- src/lv_draw/lv_draw_label.c | 63 ++++++++++++++++++------------------- 1 file changed, 30 insertions(+), 33 deletions(-) diff --git a/src/lv_draw/lv_draw_label.c b/src/lv_draw/lv_draw_label.c index ae6470ab8..4990d3e13 100644 --- a/src/lv_draw/lv_draw_label.c +++ b/src/lv_draw/lv_draw_label.c @@ -56,8 +56,8 @@ static uint8_t hex_char_to_num(char hex); * @param sel_end end index of selected area (`LV_LABEL_TXT_SEL_OFF` if none) */ void lv_draw_label(const lv_area_t * coords, const lv_area_t * mask, const lv_style_t * style, lv_opa_t opa_scale, - const char * txt, lv_txt_flag_t flag, lv_point_t * offset, uint16_t sel_start, uint16_t sel_end, - lv_draw_label_hint_t * hint, lv_bidi_dir_t bidi_dir) + const char * txt, lv_txt_flag_t flag, lv_point_t * offset, uint16_t sel_start, uint16_t sel_end, + lv_draw_label_hint_t * hint, lv_bidi_dir_t bidi_dir) { const lv_font_t * font = style->text.font; lv_coord_t w; @@ -75,7 +75,7 @@ void lv_draw_label(const lv_area_t * coords, const lv_area_t * mask, const lv_st /*If EXAPND is enabled then not limit the text's width to the object's width*/ lv_point_t p; lv_txt_get_size(&p, txt, style->text.font, style->text.letter_space, style->text.line_space, LV_COORD_MAX, - flag); + flag); w = p.x; } @@ -113,23 +113,6 @@ void lv_draw_label(const lv_area_t * coords, const lv_area_t * mask, const lv_st pos.y += hint->y; } - if(sel_start != 0xFFFF) { - sel_start = lv_bidi_get_visual_pos(txt, NULL, strlen(txt), bidi_dir, sel_start, NULL); - sel_start = lv_txt_encoded_get_byte_id(txt, sel_start); - } - - if(sel_end != 0xFFFF) { - sel_end = lv_bidi_get_visual_pos(txt, NULL, strlen(txt), bidi_dir, sel_end, NULL); - sel_end = lv_txt_encoded_get_byte_id(txt, sel_end); - } - - if(sel_start > sel_end) { - uint16_t tmp = sel_start; - sel_start = sel_end; - sel_end = tmp; - } - - uint32_t line_end = line_start + lv_txt_get_next_line(&txt[line_start], font, style->text.letter_space, w, flag); @@ -165,6 +148,12 @@ void lv_draw_label(const lv_area_t * coords, const lv_area_t * mask, const lv_st lv_opa_t opa = opa_scale == LV_OPA_COVER ? style->text.opa : (uint16_t)((uint16_t)style->text.opa * opa_scale) >> 8; + if(sel_start > sel_end) { + uint16_t tmp = sel_start; + sel_start = sel_end; + sel_end = tmp; + } + cmd_state_t cmd_state = CMD_STATE_WAIT; uint32_t i; uint16_t par_start = 0; @@ -185,16 +174,24 @@ void lv_draw_label(const lv_area_t * coords, const lv_area_t * mask, const lv_st uint32_t letter; uint32_t letter_next; #if LV_USE_BIDI - char *bidi_txt = lv_draw_get_buf(line_end - line_start + 1); - lv_bidi_process_paragraph(txt + line_start, bidi_txt, line_end - line_start, bidi_dir, NULL, 0); + char *bidi_txt = lv_draw_get_buf(line_end - line_start + 1); + lv_bidi_process_paragraph(txt + line_start, bidi_txt, line_end - line_start, bidi_dir, NULL, 0); #else - const char *bidi_txt = txt + line_start; + const char *bidi_txt = txt + line_start; #endif + while(i < line_end - line_start) { + uint16_t logical_char_pos = 0; + if(sel_start != 0xFFFF && sel_end != 0xFFFF) { + logical_char_pos = lv_txt_encoded_get_char_id(txt, line_start); + uint16_t t = lv_txt_encoded_get_char_id(bidi_txt, i); + logical_char_pos += lv_bidi_get_logical_pos(bidi_txt, NULL, line_end - line_start, bidi_dir, t, NULL); + } letter = lv_txt_encoded_next(bidi_txt, &i); letter_next = lv_txt_encoded_next(&bidi_txt[i], NULL); + /*Handle the re-color command*/ if((flag & LV_TXT_FLAG_RECOLOR) != 0) { if(letter == (uint32_t)LV_TXT_COLOR_CMD[0]) { @@ -240,7 +237,7 @@ void lv_draw_label(const lv_area_t * coords, const lv_area_t * mask, const lv_st if(sel_start != 0xFFFF && sel_end != 0xFFFF) { /*Do not draw the rectangle on the character at `sel_start`.*/ - if(i + line_start > sel_start && i + line_start <= sel_end) { + if(logical_char_pos > sel_start && logical_char_pos <= sel_end) { lv_area_t sel_coords; sel_coords.x1 = pos.x; sel_coords.y1 = pos.y; @@ -263,7 +260,7 @@ void lv_draw_label(const lv_area_t * coords, const lv_area_t * mask, const lv_st /*Align to middle*/ if(flag & LV_TXT_FLAG_CENTER) { line_width = - lv_txt_get_width(&txt[line_start], line_end - line_start, font, style->text.letter_space, flag); + lv_txt_get_width(&txt[line_start], line_end - line_start, font, style->text.letter_space, flag); pos.x += (lv_area_get_width(coords) - line_width) / 2; @@ -271,7 +268,7 @@ void lv_draw_label(const lv_area_t * coords, const lv_area_t * mask, const lv_st /*Align to the right*/ else if(flag & LV_TXT_FLAG_RIGHT) { line_width = - lv_txt_get_width(&txt[line_start], line_end - line_start, font, style->text.letter_space, flag); + lv_txt_get_width(&txt[line_start], line_end - line_start, font, style->text.letter_space, flag); pos.x += lv_area_get_width(coords) - line_width; } @@ -301,13 +298,13 @@ static uint8_t hex_char_to_num(char hex) if(hex >= 'a') hex -= 'a' - 'A'; /*Convert to upper case*/ switch(hex) { - case 'A': result = 10; break; - case 'B': result = 11; break; - case 'C': result = 12; break; - case 'D': result = 13; break; - case 'E': result = 14; break; - case 'F': result = 15; break; - default: result = 0; break; + case 'A': result = 10; break; + case 'B': result = 11; break; + case 'C': result = 12; break; + case 'D': result = 13; break; + case 'E': result = 14; break; + case 'F': result = 15; break; + default: result = 0; break; } } From 23b58d598de37bf5e6ede52671a5b128b46791d7 Mon Sep 17 00:00:00 2001 From: Amir Gonnen Date: Mon, 11 Nov 2019 22:43:12 +0200 Subject: [PATCH 82/82] bugfixes Prevent infinite loop when reaching end of string on get_next_run Prevent warning about conversion to non const bidi_txt --- src/lv_misc/lv_bidi.c | 2 +- src/lv_objx/lv_label.c | 6 ++++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/lv_misc/lv_bidi.c b/src/lv_misc/lv_bidi.c index 0f1153b52..bde752071 100644 --- a/src/lv_misc/lv_bidi.c +++ b/src/lv_misc/lv_bidi.c @@ -232,7 +232,7 @@ void lv_bidi_process_paragraph(const char * str_in, char * str_out, uint32_t len /*Get and process the runs*/ - while(rd < len) { + while(rd < len && str_in[rd]) { run_dir = get_next_run(&str_in[rd], base_dir, len - rd, &run_len, &pos_conv_run_len); if(base_dir == LV_BIDI_DIR_LTR) { diff --git a/src/lv_objx/lv_label.c b/src/lv_objx/lv_label.c index 29fae15b0..bd99c10c8 100644 --- a/src/lv_objx/lv_label.c +++ b/src/lv_objx/lv_label.c @@ -626,7 +626,7 @@ void lv_label_get_letter_pos(const lv_obj_t * label, uint16_t char_id, lv_point_ } } - char *bidi_txt; + const char *bidi_txt; uint16_t visual_byte_pos; #if LV_USE_BIDI /*Handle Bidi*/ @@ -638,7 +638,9 @@ void lv_label_get_letter_pos(const lv_obj_t * label, uint16_t char_id, lv_point_ uint16_t line_char_id = lv_txt_encoded_get_char_id(&txt[line_start], byte_id - line_start); bool is_rtl; - uint16_t visual_char_pos = lv_bidi_get_visual_pos(&txt[line_start], &bidi_txt, new_line_start - line_start, lv_obj_get_base_dir(label), line_char_id, &is_rtl); + char *mutable_bidi_txt; + uint16_t visual_char_pos = lv_bidi_get_visual_pos(&txt[line_start], &mutable_bidi_txt, new_line_start - line_start, lv_obj_get_base_dir(label), line_char_id, &is_rtl); + bidi_txt = mutable_bidi_txt; if (is_rtl) visual_char_pos++; visual_byte_pos = lv_txt_encoded_get_byte_id(bidi_txt, visual_char_pos); }