From 7f565f419a2f42fcbfd329c709b67477a81a5d4a Mon Sep 17 00:00:00 2001 From: Paul Peavyhouse Date: Wed, 18 Sep 2019 11:48:31 -0700 Subject: [PATCH 01/12] 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/12] 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/12] 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/12] 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/12] 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/12] 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/12] 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/12] 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/12] 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/12] 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/12] 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/12] 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) {