From 7f565f419a2f42fcbfd329c709b67477a81a5d4a Mon Sep 17 00:00:00 2001 From: Paul Peavyhouse Date: Wed, 18 Sep 2019 11:48:31 -0700 Subject: [PATCH 01/25] 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/25] 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/25] 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/25] 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/25] 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/25] 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/25] 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/25] 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/25] 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/25] 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/25] 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/25] Consolidating all angle2color/color2angle calculations --- src/lv_objx/lv_cpicker.c | 154 +++++++++++++-------------------------- 1 file changed, 51 insertions(+), 103 deletions(-) diff --git a/src/lv_objx/lv_cpicker.c b/src/lv_objx/lv_cpicker.c index eab301c7b..b56693cb8 100644 --- a/src/lv_objx/lv_cpicker.c +++ b/src/lv_objx/lv_cpicker.c @@ -408,6 +408,44 @@ lv_color_t lv_cpicker_get_color(lv_obj_t * cpicker) * STATIC FUNCTIONS **********************/ +static lv_color_t angle_to_mode_color(lv_cpicker_ext_t * ext, uint16_t angle) +{ + lv_color_t color; + switch(ext->color_mode) + { + default: + case LV_CPICKER_COLOR_MODE_HUE: + color = lv_color_hsv_to_rgb(angle%360, ext->saturation, ext->value); + break; + case LV_CPICKER_COLOR_MODE_SATURATION: + color = lv_color_hsv_to_rgb(ext->hue, (angle%360)/360.0*100.0, ext->value); + break; + case LV_CPICKER_COLOR_MODE_VALUE: + color = lv_color_hsv_to_rgb(ext->hue, ext->saturation, (angle%360)/360.0*100.0); + break; + } + return color; +} + +static uint16_t mode_color_to_angle(lv_cpicker_ext_t * ext) +{ + uint16_t angle; + switch(ext->color_mode) + { + default: + case LV_CPICKER_COLOR_MODE_HUE: + angle = ext->hue; + break; + case LV_CPICKER_COLOR_MODE_SATURATION: + angle = ext->saturation / 100.0 * 360.0; + break; + case LV_CPICKER_COLOR_MODE_VALUE: + angle = ext->value / 100.0 * 360.0; + break; + } + return angle; +} + /** * Handle the drawing related tasks of the color_pickerwhen when wheel type * @param cpicker pointer to an object @@ -574,7 +612,8 @@ static bool lv_cpicker_disc_design(lv_obj_t * cpicker, const lv_area_t * mask, l { for(uint16_t i = start_angle; i <= end_angle; i+= LV_CPICKER_DEF_QF) { - styleCopy.body.main_color = lv_color_hsv_to_rgb(i%360, ext->saturation, ext->value); + styleCopy.body.main_color = angle_to_mode_color(ext, i); + styleCopy.body.grad_color = styleCopy.body.main_color; triangle_points[0].x = x; triangle_points[0].y = y; @@ -604,7 +643,8 @@ static bool lv_cpicker_disc_design(lv_obj_t * cpicker, const lv_area_t * mask, l { for(uint16_t i = start_angle; i <= end_angle; i += LV_CPICKER_DEF_QF) { - styleCopy.body.main_color = lv_color_hsv_to_rgb(ext->hue, (i%360)*100/360, ext->value); + styleCopy.body.main_color = angle_to_mode_color(ext, i); + styleCopy.body.grad_color = styleCopy.body.main_color; triangle_points[0].x = x; triangle_points[0].y = y; @@ -631,7 +671,8 @@ static bool lv_cpicker_disc_design(lv_obj_t * cpicker, const lv_area_t * mask, l { for(uint16_t i = start_angle; i <= end_angle; i += LV_CPICKER_DEF_QF) { - styleCopy.body.main_color = lv_color_hsv_to_rgb(ext->hue, ext->saturation, (i%360)*100/360); + styleCopy.body.main_color = angle_to_mode_color(ext, i); + styleCopy.body.grad_color = styleCopy.body.main_color; triangle_points[0].x = x; triangle_points[0].y = y; @@ -683,21 +724,7 @@ static bool lv_cpicker_disc_design(lv_obj_t * cpicker, const lv_area_t * mask, l lv_point_t start; lv_point_t end; - uint16_t angle; - - switch(ext->color_mode) - { - default: - case LV_CPICKER_COLOR_MODE_HUE: - angle = ext->hue; - break; - case LV_CPICKER_COLOR_MODE_SATURATION: - angle = ext->saturation / 100.0 * 360.0; - break; - case LV_CPICKER_COLOR_MODE_VALUE: - angle = ext->value / 100.0 * 360.0; - break; - } + uint16_t angle = mode_color_to_angle(ext); /*save the angle to refresh the area later*/ ext->prev_pos = angle; @@ -731,21 +758,7 @@ static bool lv_cpicker_disc_design(lv_obj_t * cpicker, const lv_area_t * mask, l lv_area_t circle_ind_area; uint32_t cx, cy; - uint16_t angle; - - switch(ext->color_mode) - { - default: - case LV_CPICKER_COLOR_MODE_HUE: - angle = ext->hue; - break; - case LV_CPICKER_COLOR_MODE_SATURATION: - angle = ext->saturation / 100.0 * 360.0; - break; - case LV_CPICKER_COLOR_MODE_VALUE: - angle = ext->value / 100.0 * 360.0; - break; - } + uint16_t angle = mode_color_to_angle(ext); /*save the angle to refresh the area later*/ ext->prev_pos = angle; @@ -769,21 +782,7 @@ static bool lv_cpicker_disc_design(lv_obj_t * cpicker, const lv_area_t * mask, l lv_area_t circle_ind_area; uint32_t cx, cy; - uint16_t angle; - - switch(ext->color_mode) - { - default: - case LV_CPICKER_COLOR_MODE_HUE: - angle = ext->hue; - break; - case LV_CPICKER_COLOR_MODE_SATURATION: - angle = ext->saturation / 100.0 * 360.0; - break; - case LV_CPICKER_COLOR_MODE_VALUE: - angle = ext->value / 100.0 * 360.0; - break; - } + uint16_t angle = mode_color_to_angle(ext); /*save the angle to refresh the area later*/ ext->prev_pos = angle; @@ -946,19 +945,7 @@ static bool lv_cpicker_rect_design(lv_obj_t * cpicker, const lv_area_t * mask, l ext->rect_gradient_area.x2 -= ext->rect_gradient_h/2; ext->rect_gradient_w -= ext->rect_gradient_h; - switch(ext->color_mode) - { - default: - case LV_CPICKER_COLOR_MODE_HUE: - styleCopy.body.main_color = lv_color_hsv_to_rgb(0, ext->saturation, ext->value); - break; - case LV_CPICKER_COLOR_MODE_SATURATION: - styleCopy.body.main_color = lv_color_hsv_to_rgb(ext->hue, 0, ext->value); - break; - case LV_CPICKER_COLOR_MODE_VALUE: - styleCopy.body.main_color = lv_color_hsv_to_rgb(ext->hue, ext->saturation, 0); - break; - } + styleCopy.body.main_color = angle_to_mode_color(ext, 0); styleCopy.body.grad_color = styleCopy.body.main_color; styleCopy.body.radius = LV_RADIUS_CIRCLE; @@ -968,19 +955,7 @@ static bool lv_cpicker_rect_design(lv_obj_t * cpicker, const lv_area_t * mask, l rounded_edge_area.x1 += ext->rect_gradient_w - 1; rounded_edge_area.x2 += ext->rect_gradient_w - 1; - switch(ext->color_mode) - { - default: - case LV_CPICKER_COLOR_MODE_HUE: - styleCopy.body.main_color = lv_color_hsv_to_rgb(360, ext->saturation, ext->value); - break; - case LV_CPICKER_COLOR_MODE_SATURATION: - styleCopy.body.main_color = lv_color_hsv_to_rgb(ext->hue, 100, ext->value); - break; - case LV_CPICKER_COLOR_MODE_VALUE: - styleCopy.body.main_color = lv_color_hsv_to_rgb(ext->hue, ext->saturation, 100); - break; - } + styleCopy.body.main_color = angle_to_mode_color(ext, 360); styleCopy.body.grad_color = styleCopy.body.main_color; lv_draw_rect(&rounded_edge_area, mask, &styleCopy, opa_scale); @@ -988,20 +963,7 @@ static bool lv_cpicker_rect_design(lv_obj_t * cpicker, const lv_area_t * mask, l for(uint16_t i = 0; i < 360; i += LV_MATH_MAX(LV_CPICKER_DEF_QF, 360/ext->rect_gradient_w)) { - switch(ext->color_mode) - { - default: - case LV_CPICKER_COLOR_MODE_HUE: - styleCopy.body.main_color = lv_color_hsv_to_rgb(i%360, ext->saturation, ext->value); - break; - case LV_CPICKER_COLOR_MODE_SATURATION: - styleCopy.body.main_color = lv_color_hsv_to_rgb(ext->hue, (i%360)*100/360, ext->value); - break; - case LV_CPICKER_COLOR_MODE_VALUE: - styleCopy.body.main_color = lv_color_hsv_to_rgb(ext->hue, ext->saturation, (i%360)*100/360); - break; - } - + styleCopy.body.main_color = angle_to_mode_color(ext, i); styleCopy.body.grad_color = styleCopy.body.main_color; /*the following attribute might need changing between index to add border, shadow, radius etc*/ @@ -1727,21 +1689,7 @@ static void lv_cpicker_invalidate(lv_obj_t * cpicker, bool all) /*invalidate indicator*/ - uint16_t angle; - - switch(ext->color_mode) - { - default: - case LV_CPICKER_COLOR_MODE_HUE: - angle = ext->hue; - break; - case LV_CPICKER_COLOR_MODE_SATURATION: - angle = ext->saturation / 100.0 * 360.0; - break; - case LV_CPICKER_COLOR_MODE_VALUE: - angle = ext->value / 100.0 * 360.0; - break; - } + uint16_t angle = mode_color_to_angle(ext); switch(ext->indicator.type) { From 8dcb1ff21c7c6138198a7673dcf5172229c5d104 Mon Sep 17 00:00:00 2001 From: Gabor Kiss-Vamosi Date: Thu, 26 Sep 2019 07:23:23 +0200 Subject: [PATCH 13/25] cpicker: fix line indicator artifact --- src/lv_objx/lv_cpicker.c | 50 +++++++++++----------------------------- 1 file changed, 14 insertions(+), 36 deletions(-) diff --git a/src/lv_objx/lv_cpicker.c b/src/lv_objx/lv_cpicker.c index b56693cb8..9cccfa13e 100644 --- a/src/lv_objx/lv_cpicker.c +++ b/src/lv_objx/lv_cpicker.c @@ -815,7 +815,7 @@ static bool lv_cpicker_disc_design(lv_obj_t * cpicker, const lv_area_t * mask, l style2.body.grad_color.full = c; c += 0x123445678; lv_draw_rect(mask, mask, &style2, opa_scale); - */ + */ } /*Post draw when the children are drawn*/ else if(mode == LV_DESIGN_DRAW_POST) { @@ -1006,7 +1006,7 @@ static bool lv_cpicker_rect_design(lv_obj_t * cpicker, const lv_area_t * mask, l styleCopy.line.width = 10; lv_draw_arc(cpicker->coords.x1 + 3*ext->rect_gradient_h/2, cpicker->coords.y1 + ext->rect_gradient_h/2, ext->rect_gradient_h / 2 + styleCopy.line.width + 2, mask, 180, 360, &styleCopy, opa_scale); //lv_draw_arc(cpicker->coords.x1 + ext->rect_gradient_w - ext->rect_gradient_h/2, cpicker->coords.y1 + ext->rect_gradient_h/2, ext->rect_gradient_h / 2 + styleCopy.line.width + 2, mask, 0, 180, &styleCopy, opa_scale); - */ + */ /*draw the color position indicator*/ lv_coord_t ind_pos = style->line.rounded ? ext->rect_gradient_h / 2 : 0; @@ -1212,13 +1212,13 @@ static lv_res_t lv_cpicker_disc_signal(lv_obj_t * cpicker, lv_signal_t sign, voi if (changed) { - lv_cpicker_invalidate(cpicker, false); + lv_cpicker_invalidate(cpicker, false); res = lv_event_send(cpicker, LV_EVENT_VALUE_CHANGED, NULL); if(res != LV_RES_OK) return res; + } } } - } else if(sign == LV_SIGNAL_PRESS_LOST) { switch(ext->color_mode) @@ -1672,7 +1672,7 @@ static void lv_cpicker_invalidate(lv_obj_t * cpicker, bool all) lv_coord_t r = LV_MATH_MIN(w, h) / 2; lv_coord_t x = cpicker->coords.x1 + w / 2; lv_coord_t y = cpicker->coords.y1 + h / 2; - + /*invalidate center color area*/ lv_area_t center_color_area; @@ -1889,39 +1889,17 @@ static void lv_cpicker_invalidate(lv_obj_t * cpicker, bool all) { lv_area_t line_area; - lv_point_t p1, p2; - p1.x = ext->rect_gradient_area.x1 + ind_pos; - p1.y = ext->rect_gradient_area.y1; - p2.x = p1.x; - p2.y = ext->rect_gradient_area.y2; - - line_area.x1 = p1.x; - line_area.y1 = p1.y; - line_area.x2 = p2.x; - line_area.y2 = p2.x; - - line_area.x1 -= 2*ext->indicator.style->line.width; - line_area.y1 -= 2*ext->indicator.style->line.width; - line_area.x2 += 2*ext->indicator.style->line.width; - line_area.y2 += 2*ext->indicator.style->line.width; + /*Invalidate the current position*/ + line_area.x1 = ext->rect_gradient_area.x1 + ind_pos - ext->indicator.style->line.width; + line_area.x2 = ext->rect_gradient_area.x1 + ind_pos + ext->indicator.style->line.width; + line_area.y1 = ext->rect_gradient_area.y1; + line_area.y2 = ext->rect_gradient_area.y2; lv_inv_area(disp, &line_area); - /* invalidate last postion */ - p1.x = ext->rect_gradient_area.x1 + prev_pos; - //p1.y = ext->rect_gradient_area.y1; - p2.x = p1.x; - //p2.y = ext->rect_gradient_area.y2; - - line_area.x1 = p1.x; - line_area.y1 = p1.y; - line_area.x2 = p2.x; - line_area.y2 = p2.x; - - line_area.x1 -= 2*ext->indicator.style->line.width; - line_area.y1 -= 2*ext->indicator.style->line.width; - line_area.x2 += 2*ext->indicator.style->line.width; - line_area.y2 += 2*ext->indicator.style->line.width; + /* Invalidate last position */ + line_area.x1 = ext->rect_gradient_area.x1 + prev_pos - ext->indicator.style->line.width; + line_area.x2 = ext->rect_gradient_area.x1 + prev_pos + ext->indicator.style->line.width; lv_inv_area(disp, &line_area); break; @@ -1950,7 +1928,7 @@ static void lv_cpicker_invalidate(lv_obj_t * cpicker, bool all) { lv_coord_t center; lv_area_t ind_area; - + center = ext->rect_gradient_area.x1 + ind_pos; ind_area.x1 = center - ext->indicator.style->line.width * 3; ind_area.y1 = ext->rect_gradient_area.y1 - 1; From 4d44d16b2e8097121e0c2bc58c413c5cb9de984a Mon Sep 17 00:00:00 2001 From: Paul Peavyhouse Date: Wed, 25 Sep 2019 23:16:12 -0700 Subject: [PATCH 14/25] Changing QF from 1 to 3 --- src/lv_objx/lv_cpicker.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lv_objx/lv_cpicker.c b/src/lv_objx/lv_cpicker.c index 9cccfa13e..a4198b1de 100644 --- a/src/lv_objx/lv_cpicker.c +++ b/src/lv_objx/lv_cpicker.c @@ -39,7 +39,7 @@ #endif #ifndef LV_CPICKER_DEF_QF /*quantization factor*/ -#define LV_CPICKER_DEF_QF 1 +#define LV_CPICKER_DEF_QF 3 #endif /*for rectangular mode the QF can be down to 1*/ From 8e7bd571afee07c67c12cfe10a74a6ab5526576c Mon Sep 17 00:00:00 2001 From: Paul Peavyhouse Date: Wed, 25 Sep 2019 23:38:27 -0700 Subject: [PATCH 15/25] Syncing... --- src/lv_objx/lv_cpicker.c | 57 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 57 insertions(+) diff --git a/src/lv_objx/lv_cpicker.c b/src/lv_objx/lv_cpicker.c index a4198b1de..fc7977902 100644 --- a/src/lv_objx/lv_cpicker.c +++ b/src/lv_objx/lv_cpicker.c @@ -446,6 +446,63 @@ static uint16_t mode_color_to_angle(lv_cpicker_ext_t * ext) return angle; } +static void draw_disk_indicator_line(lv_cpicker_ext_t * ext, lv_style_t * style, lv_area_t * mask, lv_opa_t opa_scale, + lv_coord_t r, lv_coord_t x, lv_coord_t y) +{ +} + +static void draw_disk_indicator_circle(lv_cpicker_ext_t * ext, lv_style_t * style, lv_area_t * mask, lv_opa_t opa_scale, + lv_coord_t r, lv_coord_t x, lv_coord_t y) +{ +} + +static void draw_disk_indicator_in(lv_cpicker_ext_t * ext, lv_style_t * style, lv_area_t * mask, lv_opa_t opa_scale, + lv_coord_t rin, lv_coord_t x, lv_coord_t y) +{ +} + +static void draw_disk_indicator(lv_cpicker_ext_t * ext, lv_style_t * style, lv_area_t * mask, lv_opa_t opa_scale, + lv_coord_t r, lv_coord_t x, lv_coord_t y, uint32_t rin) +{ +} + +static void draw_disk_spectrum(lv_cpicker_ext_t * ext, lv_style_t * style, lv_area_t * mask, lv_opa_t opa_scale, + lv_coord_t r, lv_coord_t x, lv_coord_t y) +{ +} + +static void draw_rect_indicator_line(lv_cpicker_ext_t * ext, lv_style_t * style, lv_area_t * mask, lv_opa_t opa_scale, + lv_coord_t gradient_w, lv_coord_t gradient_h, lv_area_t gradient_area, lv_coord_t ind_pos) +{ +} + +static void draw_rect_indicator_circle(lv_cpicker_ext_t * ext, lv_style_t * style, lv_area_t * mask, lv_opa_t opa_scale, + lv_coord_t gradient_w, lv_coord_t gradient_h, lv_area_t gradient_area, lv_coord_t ind_pos) +{ +} + +static void draw_rect_indicator_in(lv_cpicker_ext_t * ext, lv_style_t * style, lv_area_t * mask, lv_opa_t opa_scale, + lv_coord_t gradient_w, lv_coord_t gradient_h, lv_area_t gradient_area, lv_coord_t ind_pos) +{ +} + +static void draw_rect_indicator(lv_cpicker_ext_t * ext, lv_style_t * style, lv_area_t * mask, lv_opa_t opa_scale, + lv_coord_t gradient_w, lv_coord_t gradient_h, lv_area_t gradient_area) +{ +} + +static void calculate_preview_area(lv_style_t * style, + lv_coord_t * gradient_w, lv_coord_t * gradient_h, lv_area_t * gradient_area, lv_area_t * preview_area, + uint16_t * style_body_padding_ver, uint16_t * style_body_padding_hor, + lv_coord_t w, lv_coord_t h, lv_coord_t x1, lv_coord_t y1, lv_coord_t x2, lv_coord_t y2) +{ +} + +static void draw_rect_spectrum(lv_cpicker_ext_t * ext, lv_style_t * style, lv_area_t * mask, lv_opa_t opa_scale, + lv_coord_t w, lv_coord_t h, lv_coord_t x1, lv_coord_t y1, lv_coord_t x2, lv_coord_t y2) +{ +} + /** * Handle the drawing related tasks of the color_pickerwhen when wheel type * @param cpicker pointer to an object From d3962fc26c4273cf559b839e3f2194292ab507a2 Mon Sep 17 00:00:00 2001 From: Paul Peavyhouse Date: Thu, 26 Sep 2019 10:50:34 -0700 Subject: [PATCH 16/25] [Still] working cleanup checkpoint --- src/lv_objx/lv_cpicker.c | 481 +++++++++++++++++++-------------------- 1 file changed, 232 insertions(+), 249 deletions(-) diff --git a/src/lv_objx/lv_cpicker.c b/src/lv_objx/lv_cpicker.c index fc7977902..da1af94bc 100644 --- a/src/lv_objx/lv_cpicker.c +++ b/src/lv_objx/lv_cpicker.c @@ -64,11 +64,8 @@ /********************** * STATIC PROTOTYPES **********************/ -static bool lv_cpicker_disc_design(lv_obj_t * cpicker, const lv_area_t * mask, lv_design_mode_t mode); -static lv_res_t lv_cpicker_disc_signal(lv_obj_t * cpicker, lv_signal_t sign, void * param); - -static bool lv_cpicker_rect_design(lv_obj_t * cpicker, const lv_area_t * mask, lv_design_mode_t mode); -static lv_res_t lv_cpicker_rect_signal(lv_obj_t * cpicker, lv_signal_t sign, void * param); +static bool lv_cpicker_design(lv_obj_t * cpicker, const lv_area_t * mask, lv_design_mode_t mode); +static lv_res_t lv_cpicker_signal(lv_obj_t * cpicker, lv_signal_t sign, void * param); static void lv_cpicker_invalidate(lv_obj_t * cpicker, bool all); @@ -120,16 +117,8 @@ lv_obj_t * lv_cpicker_create(lv_obj_t * par, const lv_obj_t * copy) ext->last_click = 0; /*The signal and design functions are not copied so set them here*/ - if(ext->type == LV_CPICKER_TYPE_DISC) - { - lv_obj_set_signal_cb(new_cpicker, lv_cpicker_disc_signal); - lv_obj_set_design_cb(new_cpicker, lv_cpicker_disc_design); - } - else if(ext->type == LV_CPICKER_TYPE_RECT) - { - lv_obj_set_signal_cb(new_cpicker, lv_cpicker_rect_signal); - lv_obj_set_design_cb(new_cpicker, lv_cpicker_rect_design); - } + lv_obj_set_signal_cb(new_cpicker, lv_cpicker_signal); + lv_obj_set_design_cb(new_cpicker, lv_cpicker_design); /*If no copy do the basic initialization*/ if(copy == NULL) { @@ -169,17 +158,6 @@ void lv_cpicker_set_type(lv_obj_t * cpicker, lv_cpicker_type_t type) ext->type = type; - if(ext->type == LV_CPICKER_TYPE_DISC) - { - lv_obj_set_signal_cb(cpicker, lv_cpicker_disc_signal); - lv_obj_set_design_cb(cpicker, lv_cpicker_disc_design); - } - else if(ext->type == LV_CPICKER_TYPE_RECT) - { - lv_obj_set_signal_cb(cpicker, lv_cpicker_rect_signal); - lv_obj_set_design_cb(cpicker, lv_cpicker_rect_design); - } - lv_obj_invalidate(cpicker); } @@ -503,17 +481,22 @@ static void draw_rect_spectrum(lv_cpicker_ext_t * ext, lv_style_t * style, lv_ar { } +static bool lv_cpicker_disc_design(lv_obj_t * cpicker, const lv_area_t * mask, lv_design_mode_t mode, + lv_cpicker_ext_t * ext, lv_style_t * style); +static bool lv_cpicker_rect_design(lv_obj_t * cpicker, const lv_area_t * mask, lv_design_mode_t mode, + lv_cpicker_ext_t * ext, lv_style_t * style); + /** - * Handle the drawing related tasks of the color_pickerwhen when wheel type + * Handle the drawing related tasks of the color_picker * @param cpicker pointer to an object * @param mask the object will be drawn only in this area * @param mode LV_DESIGN_COVER_CHK: only check if the object fully covers the 'mask_p' area * (return 'true' if yes) * LV_DESIGN_DRAW: draw the object (always return 'true') * LV_DESIGN_DRAW_POST: drawing after every children are drawn - * @param return true/false, depends on 'mode' + * @return true/false, depends on 'mode' */ -static bool lv_cpicker_disc_design(lv_obj_t * cpicker, const lv_area_t * mask, lv_design_mode_t mode) +static bool lv_cpicker_design(lv_obj_t * cpicker, const lv_area_t * mask, lv_design_mode_t mode) { /*Return false if the object is not covers the mask_p area*/ if(mode == LV_DESIGN_COVER_CHK) { @@ -528,27 +511,47 @@ static bool lv_cpicker_disc_design(lv_obj_t * cpicker, const lv_area_t * mask, l static lv_style_t styleCopy; lv_style_copy(&styleCopy, style); - static lv_style_t styleCenterBackground; - lv_theme_t * th = lv_theme_get_current(); - if (th) { - lv_style_copy(&styleCenterBackground, th->style.bg); - } else { - lv_style_copy(&styleCenterBackground, &lv_style_plain); + if(ext->type == LV_CPICKER_TYPE_DISC) + { + return lv_cpicker_disc_design(cpicker, mask, mode, ext, &styleCopy); } + else if(ext->type == LV_CPICKER_TYPE_RECT) + { + return lv_cpicker_rect_design(cpicker, mask, mode, ext, &styleCopy); + } + } + /*Post draw when the children are drawn*/ + else if(mode == LV_DESIGN_DRAW_POST) { - lv_coord_t r = (LV_MATH_MIN(lv_obj_get_width(cpicker), lv_obj_get_height(cpicker))) / 2; - lv_coord_t x = cpicker->coords.x1 + lv_obj_get_width(cpicker) / 2; - lv_coord_t y = cpicker->coords.y1 + lv_obj_get_height(cpicker) / 2; - lv_opa_t opa_scale = lv_obj_get_opa_scale(cpicker); + } - uint8_t redraw_wheel = 0; + return true; +} - lv_area_t center_ind_area; +static bool lv_cpicker_disc_design(lv_obj_t * cpicker, const lv_area_t * mask, lv_design_mode_t mode, + lv_cpicker_ext_t * ext, lv_style_t * style) +{ + static lv_style_t styleCenterBackground; + lv_theme_t * th = lv_theme_get_current(); + if (th) { + lv_style_copy(&styleCenterBackground, th->style.bg); + } else { + lv_style_copy(&styleCenterBackground, &lv_style_plain); + } - uint32_t rin = r - styleCopy.line.width; - //the square area (a and b being sides) should fit into the center of diameter d - //we have: - //a^2+b^2<=d^2 + lv_coord_t r = (LV_MATH_MIN(lv_obj_get_width(cpicker), lv_obj_get_height(cpicker))) / 2; + lv_coord_t x = cpicker->coords.x1 + lv_obj_get_width(cpicker) / 2; + lv_coord_t y = cpicker->coords.y1 + lv_obj_get_height(cpicker) / 2; + lv_opa_t opa_scale = lv_obj_get_opa_scale(cpicker); + + uint8_t redraw_wheel = 0; + + lv_area_t center_ind_area; + + uint32_t rin = r - style->line.width; + //the square area (a and b being sides) should fit into the center of diameter d + //we have: + //a^2+b^2<=d^2 //2a^2 <= d^2 //a^2<=(d^2)/2 //a <= sqrt((d^2)/2) @@ -666,14 +669,14 @@ static bool lv_cpicker_disc_design(lv_obj_t * cpicker, const lv_area_t * mask, l } if(ext->color_mode == LV_CPICKER_COLOR_MODE_HUE) + { + for(uint16_t i = start_angle; i <= end_angle; i+= LV_CPICKER_DEF_QF) { - for(uint16_t i = start_angle; i <= end_angle; i+= LV_CPICKER_DEF_QF) - { - styleCopy.body.main_color = angle_to_mode_color(ext, i); - styleCopy.body.grad_color = styleCopy.body.main_color; + style->body.main_color = angle_to_mode_color(ext, i); + style->body.grad_color = style->body.main_color; - triangle_points[0].x = x; - triangle_points[0].y = y; + triangle_points[0].x = x; + triangle_points[0].y = y; triangle_points[1].x = x + (r * lv_trigo_sin(i) >> LV_TRIGO_SHIFT); triangle_points[1].y = y + (r * lv_trigo_sin(i + 90) >> LV_TRIGO_SHIFT); @@ -691,88 +694,88 @@ static bool lv_cpicker_disc_design(lv_obj_t * cpicker, const lv_area_t * mask, l triangle_points[2].x = x + (r * lv_trigo_sin(i + LV_CPICKER_DEF_QF + TRI_OFFSET) >> LV_TRIGO_SHIFT); triangle_points[2].y = y + (r * lv_trigo_sin(i + LV_CPICKER_DEF_QF + TRI_OFFSET + 90) >> LV_TRIGO_SHIFT); - } - - lv_draw_triangle(triangle_points, mask, &styleCopy, LV_OPA_COVER); } - } - else if(ext->color_mode == LV_CPICKER_COLOR_MODE_SATURATION) - { - for(uint16_t i = start_angle; i <= end_angle; i += LV_CPICKER_DEF_QF) - { - styleCopy.body.main_color = angle_to_mode_color(ext, i); - styleCopy.body.grad_color = styleCopy.body.main_color; - triangle_points[0].x = x; - triangle_points[0].y = y; - - triangle_points[1].x = x + (r * lv_trigo_sin(i) >> LV_TRIGO_SHIFT); - triangle_points[1].y = y + (r * lv_trigo_sin(i + 90) >> LV_TRIGO_SHIFT); - - if(i == end_angle || i == (360 - LV_CPICKER_DEF_QF)) - { - /*the last triangle is drawn without additional overlapping pixels*/ - triangle_points[2].x = x + (r * lv_trigo_sin(i + LV_CPICKER_DEF_QF) >> LV_TRIGO_SHIFT); - triangle_points[2].y = y + (r * lv_trigo_sin(i + LV_CPICKER_DEF_QF + 90) >> LV_TRIGO_SHIFT); - } - else - { - triangle_points[2].x = x + (r * lv_trigo_sin(i + LV_CPICKER_DEF_QF + TRI_OFFSET) >> LV_TRIGO_SHIFT); - triangle_points[2].y = y + (r * lv_trigo_sin(i + LV_CPICKER_DEF_QF + TRI_OFFSET + 90) >> LV_TRIGO_SHIFT); - } - - lv_draw_triangle(triangle_points, mask, &styleCopy, LV_OPA_COVER); - } - } - else if(ext->color_mode == LV_CPICKER_COLOR_MODE_VALUE) - { - for(uint16_t i = start_angle; i <= end_angle; i += LV_CPICKER_DEF_QF) - { - styleCopy.body.main_color = angle_to_mode_color(ext, i); - styleCopy.body.grad_color = styleCopy.body.main_color; - - triangle_points[0].x = x; - triangle_points[0].y = y; - - triangle_points[1].x = x + (r * lv_trigo_sin(i) >> LV_TRIGO_SHIFT); - triangle_points[1].y = y + (r * lv_trigo_sin(i + 90) >> LV_TRIGO_SHIFT); - - if(i == end_angle || i == (360 - LV_CPICKER_DEF_QF)) - { - /*the last triangle is drawn without additional overlapping pixels*/ - triangle_points[2].x = x + (r * lv_trigo_sin(i + LV_CPICKER_DEF_QF) >> LV_TRIGO_SHIFT); - triangle_points[2].y = y + (r * lv_trigo_sin(i + LV_CPICKER_DEF_QF + 90) >> LV_TRIGO_SHIFT); - - } - else - { - triangle_points[2].x = x + (r * lv_trigo_sin(i + LV_CPICKER_DEF_QF + TRI_OFFSET) >> LV_TRIGO_SHIFT); - triangle_points[2].y = y + (r * lv_trigo_sin(i + LV_CPICKER_DEF_QF + TRI_OFFSET + 90) >> LV_TRIGO_SHIFT); - } - - lv_draw_triangle(triangle_points, mask, &styleCopy, LV_OPA_COVER); - } + lv_draw_triangle(triangle_points, mask, style, LV_OPA_COVER); } } + else if(ext->color_mode == LV_CPICKER_COLOR_MODE_SATURATION) + { + for(uint16_t i = start_angle; i <= end_angle; i += LV_CPICKER_DEF_QF) + { + style->body.main_color = angle_to_mode_color(ext, i); + style->body.grad_color = style->body.main_color; - //draw center background - lv_area_t center_area; - uint16_t wradius = r - styleCopy.line.width; - center_area.x1 = x - wradius; - center_area.y1 = y - wradius; - center_area.x2 = x + wradius; + triangle_points[0].x = x; + triangle_points[0].y = y; + + triangle_points[1].x = x + (r * lv_trigo_sin(i) >> LV_TRIGO_SHIFT); + triangle_points[1].y = y + (r * lv_trigo_sin(i + 90) >> LV_TRIGO_SHIFT); + + if(i == end_angle || i == (360 - LV_CPICKER_DEF_QF)) + { + /*the last triangle is drawn without additional overlapping pixels*/ + triangle_points[2].x = x + (r * lv_trigo_sin(i + LV_CPICKER_DEF_QF) >> LV_TRIGO_SHIFT); + triangle_points[2].y = y + (r * lv_trigo_sin(i + LV_CPICKER_DEF_QF + 90) >> LV_TRIGO_SHIFT); + } + else + { + triangle_points[2].x = x + (r * lv_trigo_sin(i + LV_CPICKER_DEF_QF + TRI_OFFSET) >> LV_TRIGO_SHIFT); + triangle_points[2].y = y + (r * lv_trigo_sin(i + LV_CPICKER_DEF_QF + TRI_OFFSET + 90) >> LV_TRIGO_SHIFT); + } + + lv_draw_triangle(triangle_points, mask, style, LV_OPA_COVER); + } + } + else if(ext->color_mode == LV_CPICKER_COLOR_MODE_VALUE) + { + for(uint16_t i = start_angle; i <= end_angle; i += LV_CPICKER_DEF_QF) + { + style->body.main_color = angle_to_mode_color(ext, i); + style->body.grad_color = style->body.main_color; + + triangle_points[0].x = x; + triangle_points[0].y = y; + + triangle_points[1].x = x + (r * lv_trigo_sin(i) >> LV_TRIGO_SHIFT); + triangle_points[1].y = y + (r * lv_trigo_sin(i + 90) >> LV_TRIGO_SHIFT); + + if(i == end_angle || i == (360 - LV_CPICKER_DEF_QF)) + { + /*the last triangle is drawn without additional overlapping pixels*/ + triangle_points[2].x = x + (r * lv_trigo_sin(i + LV_CPICKER_DEF_QF) >> LV_TRIGO_SHIFT); + triangle_points[2].y = y + (r * lv_trigo_sin(i + LV_CPICKER_DEF_QF + 90) >> LV_TRIGO_SHIFT); + + } + else + { + triangle_points[2].x = x + (r * lv_trigo_sin(i + LV_CPICKER_DEF_QF + TRI_OFFSET) >> LV_TRIGO_SHIFT); + triangle_points[2].y = y + (r * lv_trigo_sin(i + LV_CPICKER_DEF_QF + TRI_OFFSET + 90) >> LV_TRIGO_SHIFT); + } + + lv_draw_triangle(triangle_points, mask, style, LV_OPA_COVER); + } + } + } + + //draw center background + lv_area_t center_area; + uint16_t wradius = r - style->line.width; + center_area.x1 = x - wradius; + center_area.y1 = y - wradius; + center_area.x2 = x + wradius; center_area.y2 = y + wradius; styleCenterBackground.body.radius = LV_RADIUS_CIRCLE; - lv_draw_rect(¢er_area, mask, &styleCenterBackground, opa_scale); + lv_draw_rect(¢er_area, mask, &styleCenterBackground, opa_scale); - //draw the center color indicator - styleCopy.body.main_color = lv_color_hsv_to_rgb(ext->hue, ext->saturation, ext->value); - styleCopy.body.grad_color = styleCopy.body.main_color; - styleCopy.body.radius = LV_RADIUS_CIRCLE; - lv_draw_rect(¢er_ind_area, mask, &styleCopy, opa_scale); + //draw the center color indicator + style->body.main_color = lv_color_hsv_to_rgb(ext->hue, ext->saturation, ext->value); + style->body.grad_color = style->body.main_color; + style->body.radius = LV_RADIUS_CIRCLE; + lv_draw_rect(¢er_ind_area, mask, style, opa_scale); - //Draw the current hue indicator - switch(ext->indicator.type) + //Draw the current hue indicator + switch(ext->indicator.type) { case LV_CPICKER_INDICATOR_NONE: break; @@ -825,11 +828,12 @@ static bool lv_cpicker_disc_design(lv_obj_t * cpicker, const lv_area_t * mask, l circle_ind_area.x1 = cx - style->line.width/2; circle_ind_area.y1 = cy - style->line.width/2; - circle_ind_area.x2 = cx + style->line.width/2; - circle_ind_area.y2 = cy + style->line.width/2; + circle_ind_area.x2 = cx + style->line.width/2; + circle_ind_area.y2 = cy + style->line.width/2; - lv_style_copy(&styleCopy, ext->indicator.style); - styleCopy.body.radius = LV_RADIUS_CIRCLE; + lv_style_t styleCopy; + lv_style_copy(&styleCopy, ext->indicator.style); + styleCopy.body.radius = LV_RADIUS_CIRCLE; lv_draw_rect(&circle_ind_area, mask, &styleCopy, opa_scale); break; @@ -852,11 +856,12 @@ static bool lv_cpicker_disc_design(lv_obj_t * cpicker, const lv_area_t * mask, l circle_ind_area.x1 = cx - ((wradius - radius) / 3); circle_ind_area.y1 = cy - ((wradius - radius) / 3); - circle_ind_area.x2 = cx + ((wradius - radius) / 3); - circle_ind_area.y2 = cy + ((wradius - radius) / 3); + circle_ind_area.x2 = cx + ((wradius - radius) / 3); + circle_ind_area.y2 = cy + ((wradius - radius) / 3); - lv_style_copy(&styleCopy, ext->indicator.style); - styleCopy.body.radius = LV_RADIUS_CIRCLE; + lv_style_t styleCopy; + lv_style_copy(&styleCopy, ext->indicator.style); + styleCopy.body.radius = LV_RADIUS_CIRCLE; lv_draw_rect(&circle_ind_area, mask, &styleCopy, opa_scale); break; @@ -870,45 +875,18 @@ static bool lv_cpicker_disc_design(lv_obj_t * cpicker, const lv_area_t * mask, l lv_style_copy(&style2, &lv_style_plain); style2.body.main_color.full = c; style2.body.grad_color.full = c; - c += 0x123445678; - lv_draw_rect(mask, mask, &style2, opa_scale); - */ - } - /*Post draw when the children are drawn*/ - else if(mode == LV_DESIGN_DRAW_POST) { - - } - + c += 0x123445678; + lv_draw_rect(mask, mask, &style2, opa_scale); + */ + return true; } -/** - * Handle the drawing related tasks of the color_pickerwhen of rectangle type - * @param cpicker pointer to an object - * @param mask the object will be drawn only in this area - * @param mode LV_DESIGN_COVER_CHK: only check if the object fully covers the 'mask_p' area - * (return 'true' if yes) - * LV_DESIGN_DRAW: draw the object (always return 'true') - * LV_DESIGN_DRAW_POST: drawing after every children are drawn - * @param return true/false, depends on 'mode' - */ -static bool lv_cpicker_rect_design(lv_obj_t * cpicker, const lv_area_t * mask, lv_design_mode_t mode) +static bool lv_cpicker_rect_design(lv_obj_t * cpicker, const lv_area_t * mask, lv_design_mode_t mode, + lv_cpicker_ext_t * ext, lv_style_t * style) { - /*Return false if the object is not covers the mask_p area*/ - if(mode == LV_DESIGN_COVER_CHK) { - return false; - } - /*Draw the object*/ - else if(mode == LV_DESIGN_DRAW_MAIN) { - - lv_cpicker_ext_t * ext = lv_obj_get_ext_attr(cpicker); - lv_style_t * style = lv_cpicker_get_style(cpicker, LV_CPICKER_STYLE_MAIN); - - static lv_style_t styleCopy; - lv_style_copy(&styleCopy, style); - - lv_coord_t w = lv_obj_get_width(cpicker); - lv_coord_t h = lv_obj_get_height(cpicker); + lv_coord_t w = lv_obj_get_width(cpicker); + lv_coord_t h = lv_obj_get_height(cpicker); lv_coord_t x1 = cpicker->coords.x1; lv_coord_t y1 = cpicker->coords.y1; @@ -999,68 +977,68 @@ static bool lv_cpicker_rect_design(lv_obj_t * cpicker, const lv_area_t * mask, l rounded_edge_area.y2 = ext->rect_gradient_area.y2; ext->rect_gradient_area.x1 += ext->rect_gradient_h/2; - ext->rect_gradient_area.x2 -= ext->rect_gradient_h/2; - ext->rect_gradient_w -= ext->rect_gradient_h; + ext->rect_gradient_area.x2 -= ext->rect_gradient_h/2; + ext->rect_gradient_w -= ext->rect_gradient_h; - styleCopy.body.main_color = angle_to_mode_color(ext, 0); - styleCopy.body.grad_color = styleCopy.body.main_color; + style->body.main_color = angle_to_mode_color(ext, 0); + style->body.grad_color = style->body.main_color; - styleCopy.body.radius = LV_RADIUS_CIRCLE; + style->body.radius = LV_RADIUS_CIRCLE; - lv_draw_rect(&rounded_edge_area, mask, &styleCopy, opa_scale); + lv_draw_rect(&rounded_edge_area, mask, style, opa_scale); - rounded_edge_area.x1 += ext->rect_gradient_w - 1; - rounded_edge_area.x2 += ext->rect_gradient_w - 1; + rounded_edge_area.x1 += ext->rect_gradient_w - 1; + rounded_edge_area.x2 += ext->rect_gradient_w - 1; - styleCopy.body.main_color = angle_to_mode_color(ext, 360); - styleCopy.body.grad_color = styleCopy.body.main_color; + style->body.main_color = angle_to_mode_color(ext, 360); + style->body.grad_color = style->body.main_color; - lv_draw_rect(&rounded_edge_area, mask, &styleCopy, opa_scale); - } + lv_draw_rect(&rounded_edge_area, mask, style, opa_scale); + } - for(uint16_t i = 0; i < 360; i += LV_MATH_MAX(LV_CPICKER_DEF_QF, 360/ext->rect_gradient_w)) - { - styleCopy.body.main_color = angle_to_mode_color(ext, i); - styleCopy.body.grad_color = styleCopy.body.main_color; + for(uint16_t i = 0; i < 360; i += LV_MATH_MAX(LV_CPICKER_DEF_QF, 360/ext->rect_gradient_w)) + { + style->body.main_color = angle_to_mode_color(ext, i); + style->body.grad_color = style->body.main_color; - /*the following attribute might need changing between index to add border, shadow, radius etc*/ - styleCopy.body.radius = 0; - styleCopy.body.border.width = 0; - styleCopy.body.shadow.width = 0; - styleCopy.body.opa = LV_OPA_COVER; + /*the following attribute might need changing between index to add border, shadow, radius etc*/ + style->body.radius = 0; + style->body.border.width = 0; + style->body.shadow.width = 0; + style->body.opa = LV_OPA_COVER; - lv_area_t rect_area; + lv_area_t rect_area; /*scale angle (hue/sat/val) to linear coordinate*/ lv_coord_t xi = i / 360.0 * ext->rect_gradient_w; rect_area.x1 = LV_MATH_MIN(ext->rect_gradient_area.x1 + xi, ext->rect_gradient_area.x1 + ext->rect_gradient_w - LV_MATH_MAX(LV_CPICKER_DEF_QF, 360/ext->rect_gradient_w)); rect_area.y1 = ext->rect_gradient_area.y1; - rect_area.x2 = rect_area.x1 + LV_MATH_MAX(LV_CPICKER_DEF_QF, 360/ext->rect_gradient_w); - rect_area.y2 = ext->rect_gradient_area.y2; + rect_area.x2 = rect_area.x1 + LV_MATH_MAX(LV_CPICKER_DEF_QF, 360/ext->rect_gradient_w); + rect_area.y2 = ext->rect_gradient_area.y2; - lv_draw_rect(&rect_area, mask, &styleCopy, opa_scale); - } + lv_draw_rect(&rect_area, mask, style, opa_scale); + } - if(style->line.rounded) + if(style->line.rounded) { /*Restore gradient area to take rounded end in account*/ ext->rect_gradient_area.x1 -= ext->rect_gradient_h/2; ext->rect_gradient_area.x2 += ext->rect_gradient_h/2; //ext->rect_gradient_w += ext->rect_gradient_h; - } + } - /*draw the color preview indicator*/ - styleCopy.body.main_color = lv_cpicker_get_color(cpicker); - styleCopy.body.grad_color = styleCopy.body.main_color; - if(style->line.rounded && style_body_padding_hor == 0) - { - styleCopy.body.radius = ext->rect_gradient_h; - } - lv_draw_rect(&(ext->rect_preview_area), mask, &styleCopy, opa_scale); + /*draw the color preview indicator*/ + style->body.main_color = lv_cpicker_get_color(cpicker); + style->body.grad_color = style->body.main_color; + if(style->line.rounded && style_body_padding_hor == 0) + { + style->body.radius = ext->rect_gradient_h; + } + lv_draw_rect(&(ext->rect_preview_area), mask, style, opa_scale); - /* - styleCopy.line.width = 10; + /* + styleCopy.line.width = 10; lv_draw_arc(cpicker->coords.x1 + 3*ext->rect_gradient_h/2, cpicker->coords.y1 + ext->rect_gradient_h/2, ext->rect_gradient_h / 2 + styleCopy.line.width + 2, mask, 180, 360, &styleCopy, opa_scale); //lv_draw_arc(cpicker->coords.x1 + ext->rect_gradient_w - ext->rect_gradient_h/2, cpicker->coords.y1 + ext->rect_gradient_h/2, ext->rect_gradient_h / 2 + styleCopy.line.width + 2, mask, 0, 180, &styleCopy, opa_scale); */ @@ -1105,16 +1083,16 @@ static bool lv_cpicker_rect_design(lv_obj_t * cpicker, const lv_area_t * mask, l lv_area_t circle_ind_area; circle_ind_area.x1 = ext->rect_gradient_area.x1 + ind_pos - ext->rect_gradient_h/2; circle_ind_area.x2 = circle_ind_area.x1 + ext->rect_gradient_h; - circle_ind_area.y1 = ext->rect_gradient_area.y1; - circle_ind_area.y2 = ext->rect_gradient_area.y2; + circle_ind_area.y1 = ext->rect_gradient_area.y1; + circle_ind_area.y2 = ext->rect_gradient_area.y2; - lv_style_copy(&styleCopy, ext->indicator.style); - styleCopy.body.radius = LV_RADIUS_CIRCLE; + lv_style_copy(style, ext->indicator.style); + style->body.radius = LV_RADIUS_CIRCLE; - lv_draw_rect(&circle_ind_area, mask, &styleCopy, opa_scale); - break; - } - case LV_CPICKER_INDICATOR_IN: + lv_draw_rect(&circle_ind_area, mask, style, opa_scale); + break; + } + case LV_CPICKER_INDICATOR_IN: { /*draw triangle under the gradient*/ lv_point_t triangle_points[3]; @@ -1138,41 +1116,28 @@ static bool lv_cpicker_rect_design(lv_obj_t * cpicker, const lv_area_t * mask, l } default: break; - } - } - /*Post draw when the children are drawn*/ - else if(mode == LV_DESIGN_DRAW_POST) { - } return true; } + +static lv_res_t lv_cpicker_disc_signal(lv_obj_t * cpicker, lv_signal_t sign, void * param); +static lv_res_t lv_cpicker_rect_signal(lv_obj_t * cpicker, lv_signal_t sign, void * param); + /** - * Signal function of the color_picker of wheel type + * Signal function of the color_picker * @param cpicker pointer to a color_picker object * @param sign a signal type from lv_signal_t enum * @param param pointer to a signal specific variable * @return LV_RES_OK: the object is not deleted in the function; LV_RES_INV: the object is deleted */ -static lv_res_t lv_cpicker_disc_signal(lv_obj_t * cpicker, lv_signal_t sign, void * param) +static lv_res_t lv_cpicker_signal(lv_obj_t * cpicker, lv_signal_t sign, void * param) { - lv_cpicker_ext_t * ext = lv_obj_get_ext_attr(cpicker); - - lv_res_t res; - /* Include the ancient signal function */ - res = ancestor_signal(cpicker, sign, param); + lv_res_t res = ancestor_signal(cpicker, sign, param); if(res != LV_RES_OK) return res; - lv_style_t * style = lv_cpicker_get_style(cpicker, LV_CPICKER_STYLE_MAIN); - - lv_coord_t r_out = (LV_MATH_MIN(lv_obj_get_width(cpicker), lv_obj_get_height(cpicker))) / 2; - lv_coord_t r_in = r_out - style->line.width - style->body.padding.inner; - - lv_coord_t x = cpicker->coords.x1 + lv_obj_get_width(cpicker) / 2; - lv_coord_t y = cpicker->coords.y1 + lv_obj_get_height(cpicker) / 2; - if(sign == LV_SIGNAL_CLEANUP) { /*Nothing to cleanup. (No dynamically allocated memory in 'ext')*/ } else if(sign == LV_SIGNAL_GET_TYPE) { @@ -1182,8 +1147,40 @@ static lv_res_t lv_cpicker_disc_signal(lv_obj_t * cpicker, lv_signal_t sign, voi if(buf->type[i] == NULL) break; } buf->type[i] = "lv_cpicker"; + } else { + lv_cpicker_ext_t * ext = lv_obj_get_ext_attr(cpicker); + lv_style_t * style = lv_cpicker_get_style(cpicker, LV_CPICKER_STYLE_MAIN); + + if(ext->type == LV_CPICKER_TYPE_DISC) + { + res = lv_cpicker_disc_signal(cpicker, sign, param); + if(res != LV_RES_OK) return res; + } + else if(ext->type == LV_CPICKER_TYPE_RECT) + { + res = lv_cpicker_rect_signal(cpicker, sign, param); + if(res != LV_RES_OK) return res; + } } - else if(sign == LV_SIGNAL_PRESSED) + + return res; +} + +static lv_res_t lv_cpicker_disc_signal(lv_obj_t * cpicker, lv_signal_t sign, void * param) +{ + lv_cpicker_ext_t * ext = lv_obj_get_ext_attr(cpicker); + + lv_res_t res; + + lv_style_t * style = lv_cpicker_get_style(cpicker, LV_CPICKER_STYLE_MAIN); + + lv_coord_t r_out = (LV_MATH_MIN(lv_obj_get_width(cpicker), lv_obj_get_height(cpicker))) / 2; + lv_coord_t r_in = r_out - style->line.width - style->body.padding.inner; + + lv_coord_t x = cpicker->coords.x1 + lv_obj_get_width(cpicker) / 2; + lv_coord_t y = cpicker->coords.y1 + lv_obj_get_height(cpicker) / 2; + + if(sign == LV_SIGNAL_PRESSED) { switch(ext->color_mode) { @@ -1452,23 +1449,9 @@ static lv_res_t lv_cpicker_rect_signal(lv_obj_t * cpicker, lv_signal_t sign, voi lv_res_t res; - /* Include the ancient signal function */ - res = ancestor_signal(cpicker, sign, param); - if(res != LV_RES_OK) return res; - lv_style_t * style = lv_cpicker_get_style(cpicker, LV_CPICKER_STYLE_MAIN); - if(sign == LV_SIGNAL_CLEANUP) { - /*Nothing to cleanup. (No dynamically allocated memory in 'ext')*/ - } else if(sign == LV_SIGNAL_GET_TYPE) { - lv_obj_type_t * buf = param; - uint8_t i; - for(i = 0; i < LV_MAX_ANCESTOR_NUM - 1; i++) { /*Find the last set data*/ - if(buf->type[i] == NULL) break; - } - buf->type[i] = "lv_cpicker"; - } - else if(sign == LV_SIGNAL_PRESSED) + if(sign == LV_SIGNAL_PRESSED) { switch(ext->color_mode) { From 25d4991683543ee04752e647a015fa61a0f22bf1 Mon Sep 17 00:00:00 2001 From: Paul Peavyhouse Date: Thu, 26 Sep 2019 11:24:47 -0700 Subject: [PATCH 17/25] Whitespace changes --- src/lv_objx/lv_cpicker.c | 732 +++++++++++++++++++-------------------- 1 file changed, 366 insertions(+), 366 deletions(-) diff --git a/src/lv_objx/lv_cpicker.c b/src/lv_objx/lv_cpicker.c index da1af94bc..068d6b2a5 100644 --- a/src/lv_objx/lv_cpicker.c +++ b/src/lv_objx/lv_cpicker.c @@ -552,123 +552,123 @@ static bool lv_cpicker_disc_design(lv_obj_t * cpicker, const lv_area_t * mask, l //the square area (a and b being sides) should fit into the center of diameter d //we have: //a^2+b^2<=d^2 - //2a^2 <= d^2 - //a^2<=(d^2)/2 - //a <= sqrt((d^2)/2) - uint16_t radius = lv_sqrt((4*rin*rin)/2)/2 - style->body.padding.inner; + //2a^2 <= d^2 + //a^2<=(d^2)/2 + //a <= sqrt((d^2)/2) + uint16_t radius = lv_sqrt((4*rin*rin)/2)/2 - style->body.padding.inner; - center_ind_area.x1 = x - radius; - center_ind_area.y1 = y - radius; - center_ind_area.x2 = x + radius; - center_ind_area.y2 = y + radius; + center_ind_area.x1 = x - radius; + center_ind_area.y1 = y - radius; + center_ind_area.x2 = x + radius; + center_ind_area.y2 = y + radius; - /*redraw the wheel only if the mask intersect with the wheel*/ - if(mask->x1 < center_ind_area.x1 || mask->x2 > center_ind_area.x2 - || mask->y1 < center_ind_area.y1 || mask->y2 > center_ind_area.y2) - { - redraw_wheel = 1; - } + /*redraw the wheel only if the mask intersect with the wheel*/ + if(mask->x1 < center_ind_area.x1 || mask->x2 > center_ind_area.x2 + || mask->y1 < center_ind_area.y1 || mask->y2 > center_ind_area.y2) + { + redraw_wheel = 1; + } - lv_point_t triangle_points[3]; + lv_point_t triangle_points[3]; - int16_t start_angle, end_angle; - start_angle = 0; //Default - end_angle = 360 - LV_CPICKER_DEF_QF; //Default + int16_t start_angle, end_angle; + start_angle = 0; //Default + end_angle = 360 - LV_CPICKER_DEF_QF; //Default - if(redraw_wheel) - { - /*if the mask does not include the center of the object - * redrawing all the wheel is not necessary; - * only a given angular range + if(redraw_wheel) + { + /*if the mask does not include the center of the object + * redrawing all the wheel is not necessary; + * only a given angular range + */ + lv_point_t center = {x, y}; + if(!lv_area_is_point_on(mask, ¢er) + /* + && (mask->x1 != cpicker->coords.x1 || mask->x2 != cpicker->coords.x2 + || mask->y1 != cpicker->coords.y1 || mask->y2 != cpicker->coords.y2) */ - lv_point_t center = {x, y}; - if(!lv_area_is_point_on(mask, ¢er) - /* - && (mask->x1 != cpicker->coords.x1 || mask->x2 != cpicker->coords.x2 - || mask->y1 != cpicker->coords.y1 || mask->y2 != cpicker->coords.y2) - */ - ) + ) + { + /*get angle from center of object to each corners of the area*/ + int16_t dr, ur, ul, dl; + dr = lv_atan2(mask->x2 - x, mask->y2 - y); + ur = lv_atan2(mask->x2 - x, mask->y1 - y); + ul = lv_atan2(mask->x1 - x, mask->y1 - y); + dl = lv_atan2(mask->x1 - x, mask->y2 - y); + + /* check area position from object axis*/ + uint8_t left = (mask->x2 < x && mask->x1 < x); + uint8_t onYaxis = (mask->x2 > x && mask->x1 < x); + uint8_t right = (mask->x2 > x && mask->x1 > x); + uint8_t top = (mask->y2 < y && mask->y1 < y); + uint8_t onXaxis = (mask->y2 > y && mask->y1 < y); + uint8_t bottom = (mask->y2 > y && mask->y1 > x); + + /*store angular range*/ + if(right && bottom) { - /*get angle from center of object to each corners of the area*/ - int16_t dr, ur, ul, dl; - dr = lv_atan2(mask->x2 - x, mask->y2 - y); - ur = lv_atan2(mask->x2 - x, mask->y1 - y); - ul = lv_atan2(mask->x1 - x, mask->y1 - y); - dl = lv_atan2(mask->x1 - x, mask->y2 - y); - - /* check area position from object axis*/ - uint8_t left = (mask->x2 < x && mask->x1 < x); - uint8_t onYaxis = (mask->x2 > x && mask->x1 < x); - uint8_t right = (mask->x2 > x && mask->x1 > x); - uint8_t top = (mask->y2 < y && mask->y1 < y); - uint8_t onXaxis = (mask->y2 > y && mask->y1 < y); - uint8_t bottom = (mask->y2 > y && mask->y1 > x); - - /*store angular range*/ - if(right && bottom) - { - start_angle = dl; - end_angle = ur; - } - else if(right && onXaxis) - { - start_angle = dl; - end_angle = ul; - } - else if(right && top) - { - start_angle = dr; - end_angle = ul; - } - else if(onYaxis && top) - { - start_angle = dr; - end_angle = dl; - } - else if(left && top) - { - start_angle = ur; - end_angle = dl; - } - else if(left && onXaxis) - { - start_angle = ur; - end_angle = dr; - } - else if(left && bottom) - { - start_angle = ul; - end_angle = dr; - } - else if(onYaxis && bottom) - { - start_angle = ul; - end_angle = ur; - } - - /*rollover angle*/ - if(start_angle > end_angle) - { - end_angle += 360; - } - - /*round to QF factor*/ - start_angle = start_angle/LV_CPICKER_DEF_QF*LV_CPICKER_DEF_QF; - end_angle = end_angle/LV_CPICKER_DEF_QF*LV_CPICKER_DEF_QF;; - - /*shift angle if necessary before adding offset*/ - if((start_angle - LV_CPICKER_DEF_QF) < 0) - { - start_angle += 360; - end_angle += 360; - } - - /*ensure overlapping by adding offset*/ - start_angle -= LV_CPICKER_DEF_QF; - end_angle += LV_CPICKER_DEF_QF; + start_angle = dl; + end_angle = ur; + } + else if(right && onXaxis) + { + start_angle = dl; + end_angle = ul; + } + else if(right && top) + { + start_angle = dr; + end_angle = ul; + } + else if(onYaxis && top) + { + start_angle = dr; + end_angle = dl; + } + else if(left && top) + { + start_angle = ur; + end_angle = dl; + } + else if(left && onXaxis) + { + start_angle = ur; + end_angle = dr; + } + else if(left && bottom) + { + start_angle = ul; + end_angle = dr; + } + else if(onYaxis && bottom) + { + start_angle = ul; + end_angle = ur; } - if(ext->color_mode == LV_CPICKER_COLOR_MODE_HUE) + /*rollover angle*/ + if(start_angle > end_angle) + { + end_angle += 360; + } + + /*round to QF factor*/ + start_angle = start_angle/LV_CPICKER_DEF_QF*LV_CPICKER_DEF_QF; + end_angle = end_angle/LV_CPICKER_DEF_QF*LV_CPICKER_DEF_QF;; + + /*shift angle if necessary before adding offset*/ + if((start_angle - LV_CPICKER_DEF_QF) < 0) + { + start_angle += 360; + end_angle += 360; + } + + /*ensure overlapping by adding offset*/ + start_angle -= LV_CPICKER_DEF_QF; + end_angle += LV_CPICKER_DEF_QF; + } + + if(ext->color_mode == LV_CPICKER_COLOR_MODE_HUE) { for(uint16_t i = start_angle; i <= end_angle; i+= LV_CPICKER_DEF_QF) { @@ -678,21 +678,21 @@ static bool lv_cpicker_disc_design(lv_obj_t * cpicker, const lv_area_t * mask, l triangle_points[0].x = x; triangle_points[0].y = y; - triangle_points[1].x = x + (r * lv_trigo_sin(i) >> LV_TRIGO_SHIFT); - triangle_points[1].y = y + (r * lv_trigo_sin(i + 90) >> LV_TRIGO_SHIFT); + triangle_points[1].x = x + (r * lv_trigo_sin(i) >> LV_TRIGO_SHIFT); + triangle_points[1].y = y + (r * lv_trigo_sin(i + 90) >> LV_TRIGO_SHIFT); - if(i == end_angle || i == (360 - LV_CPICKER_DEF_QF)) - { - /*the last triangle is drawn without additional overlapping pixels*/ - triangle_points[2].x = x + (r * lv_trigo_sin(i + LV_CPICKER_DEF_QF) >> LV_TRIGO_SHIFT); - triangle_points[2].y = y + (r * lv_trigo_sin(i + LV_CPICKER_DEF_QF + 90) >> LV_TRIGO_SHIFT); + if(i == end_angle || i == (360 - LV_CPICKER_DEF_QF)) + { + /*the last triangle is drawn without additional overlapping pixels*/ + triangle_points[2].x = x + (r * lv_trigo_sin(i + LV_CPICKER_DEF_QF) >> LV_TRIGO_SHIFT); + triangle_points[2].y = y + (r * lv_trigo_sin(i + LV_CPICKER_DEF_QF + 90) >> LV_TRIGO_SHIFT); - } - else - { - triangle_points[2].x = x + (r * lv_trigo_sin(i + LV_CPICKER_DEF_QF + TRI_OFFSET) >> LV_TRIGO_SHIFT); - triangle_points[2].y = y + (r * lv_trigo_sin(i + LV_CPICKER_DEF_QF + TRI_OFFSET + 90) >> LV_TRIGO_SHIFT); + } + else + { + triangle_points[2].x = x + (r * lv_trigo_sin(i + LV_CPICKER_DEF_QF + TRI_OFFSET) >> LV_TRIGO_SHIFT); + triangle_points[2].y = y + (r * lv_trigo_sin(i + LV_CPICKER_DEF_QF + TRI_OFFSET + 90) >> LV_TRIGO_SHIFT); } @@ -709,18 +709,18 @@ static bool lv_cpicker_disc_design(lv_obj_t * cpicker, const lv_area_t * mask, l triangle_points[0].x = x; triangle_points[0].y = y; - triangle_points[1].x = x + (r * lv_trigo_sin(i) >> LV_TRIGO_SHIFT); - triangle_points[1].y = y + (r * lv_trigo_sin(i + 90) >> LV_TRIGO_SHIFT); + triangle_points[1].x = x + (r * lv_trigo_sin(i) >> LV_TRIGO_SHIFT); + triangle_points[1].y = y + (r * lv_trigo_sin(i + 90) >> LV_TRIGO_SHIFT); - if(i == end_angle || i == (360 - LV_CPICKER_DEF_QF)) - { - /*the last triangle is drawn without additional overlapping pixels*/ - triangle_points[2].x = x + (r * lv_trigo_sin(i + LV_CPICKER_DEF_QF) >> LV_TRIGO_SHIFT); - triangle_points[2].y = y + (r * lv_trigo_sin(i + LV_CPICKER_DEF_QF + 90) >> LV_TRIGO_SHIFT); - } - else - { - triangle_points[2].x = x + (r * lv_trigo_sin(i + LV_CPICKER_DEF_QF + TRI_OFFSET) >> LV_TRIGO_SHIFT); + if(i == end_angle || i == (360 - LV_CPICKER_DEF_QF)) + { + /*the last triangle is drawn without additional overlapping pixels*/ + triangle_points[2].x = x + (r * lv_trigo_sin(i + LV_CPICKER_DEF_QF) >> LV_TRIGO_SHIFT); + triangle_points[2].y = y + (r * lv_trigo_sin(i + LV_CPICKER_DEF_QF + 90) >> LV_TRIGO_SHIFT); + } + else + { + triangle_points[2].x = x + (r * lv_trigo_sin(i + LV_CPICKER_DEF_QF + TRI_OFFSET) >> LV_TRIGO_SHIFT); triangle_points[2].y = y + (r * lv_trigo_sin(i + LV_CPICKER_DEF_QF + TRI_OFFSET + 90) >> LV_TRIGO_SHIFT); } @@ -737,19 +737,19 @@ static bool lv_cpicker_disc_design(lv_obj_t * cpicker, const lv_area_t * mask, l triangle_points[0].x = x; triangle_points[0].y = y; - triangle_points[1].x = x + (r * lv_trigo_sin(i) >> LV_TRIGO_SHIFT); - triangle_points[1].y = y + (r * lv_trigo_sin(i + 90) >> LV_TRIGO_SHIFT); + triangle_points[1].x = x + (r * lv_trigo_sin(i) >> LV_TRIGO_SHIFT); + triangle_points[1].y = y + (r * lv_trigo_sin(i + 90) >> LV_TRIGO_SHIFT); - if(i == end_angle || i == (360 - LV_CPICKER_DEF_QF)) - { - /*the last triangle is drawn without additional overlapping pixels*/ - triangle_points[2].x = x + (r * lv_trigo_sin(i + LV_CPICKER_DEF_QF) >> LV_TRIGO_SHIFT); - triangle_points[2].y = y + (r * lv_trigo_sin(i + LV_CPICKER_DEF_QF + 90) >> LV_TRIGO_SHIFT); + if(i == end_angle || i == (360 - LV_CPICKER_DEF_QF)) + { + /*the last triangle is drawn without additional overlapping pixels*/ + triangle_points[2].x = x + (r * lv_trigo_sin(i + LV_CPICKER_DEF_QF) >> LV_TRIGO_SHIFT); + triangle_points[2].y = y + (r * lv_trigo_sin(i + LV_CPICKER_DEF_QF + 90) >> LV_TRIGO_SHIFT); - } - else - { - triangle_points[2].x = x + (r * lv_trigo_sin(i + LV_CPICKER_DEF_QF + TRI_OFFSET) >> LV_TRIGO_SHIFT); + } + else + { + triangle_points[2].x = x + (r * lv_trigo_sin(i + LV_CPICKER_DEF_QF + TRI_OFFSET) >> LV_TRIGO_SHIFT); triangle_points[2].y = y + (r * lv_trigo_sin(i + LV_CPICKER_DEF_QF + TRI_OFFSET + 90) >> LV_TRIGO_SHIFT); } @@ -758,76 +758,76 @@ static bool lv_cpicker_disc_design(lv_obj_t * cpicker, const lv_area_t * mask, l } } - //draw center background + /*draw center background*/ lv_area_t center_area; uint16_t wradius = r - style->line.width; center_area.x1 = x - wradius; center_area.y1 = y - wradius; center_area.x2 = x + wradius; - center_area.y2 = y + wradius; - styleCenterBackground.body.radius = LV_RADIUS_CIRCLE; + center_area.y2 = y + wradius; + styleCenterBackground.body.radius = LV_RADIUS_CIRCLE; lv_draw_rect(¢er_area, mask, &styleCenterBackground, opa_scale); - //draw the center color indicator + /*draw the center color indicator*/ style->body.main_color = lv_color_hsv_to_rgb(ext->hue, ext->saturation, ext->value); style->body.grad_color = style->body.main_color; style->body.radius = LV_RADIUS_CIRCLE; lv_draw_rect(¢er_ind_area, mask, style, opa_scale); - //Draw the current hue indicator + /*draw the current hue indicator*/ switch(ext->indicator.type) + { + case LV_CPICKER_INDICATOR_NONE: + break; + case LV_CPICKER_INDICATOR_LINE: + { + lv_point_t start; + lv_point_t end; + + uint16_t angle = mode_color_to_angle(ext); + + /*save the angle to refresh the area later*/ + ext->prev_pos = angle; + + start.x = x + ((r - style->line.width + ext->indicator.style->body.padding.inner + ext->indicator.style->line.width/2) * lv_trigo_sin(angle) >> LV_TRIGO_SHIFT); + start.y = y + ((r - style->line.width + ext->indicator.style->body.padding.inner + ext->indicator.style->line.width/2) * lv_trigo_sin(angle + 90) >> LV_TRIGO_SHIFT); + + end.x = x + ((r - ext->indicator.style->body.padding.inner - ext->indicator.style->line.width/2) * lv_trigo_sin(angle) >> LV_TRIGO_SHIFT); + end.y = y + ((r - ext->indicator.style->body.padding.inner - ext->indicator.style->line.width/2) * lv_trigo_sin(angle + 90) >> LV_TRIGO_SHIFT); + + lv_draw_line(&start, &end, mask, ext->indicator.style, opa_scale); + if(ext->indicator.style->line.rounded) { - case LV_CPICKER_INDICATOR_NONE: - break; - case LV_CPICKER_INDICATOR_LINE: - { - lv_point_t start; - lv_point_t end; + lv_area_t circle_area; + circle_area.x1 = start.x - ((ext->indicator.style->line.width - 1) >> 1) - ((ext->indicator.style->line.width - 1) & 0x1); + circle_area.y1 = start.y - ((ext->indicator.style->line.width - 1) >> 1) - ((ext->indicator.style->line.width - 1) & 0x1); + circle_area.x2 = start.x + ((ext->indicator.style->line.width - 1) >> 1); + circle_area.y2 = start.y + ((ext->indicator.style->line.width - 1) >> 1); + lv_draw_rect(&circle_area, mask, ext->indicator.style, opa_scale); - uint16_t angle = mode_color_to_angle(ext); - - /*save the angle to refresh the area later*/ - ext->prev_pos = angle; - - start.x = x + ((r - style->line.width + ext->indicator.style->body.padding.inner + ext->indicator.style->line.width/2) * lv_trigo_sin(angle) >> LV_TRIGO_SHIFT); - start.y = y + ((r - style->line.width + ext->indicator.style->body.padding.inner + ext->indicator.style->line.width/2) * lv_trigo_sin(angle + 90) >> LV_TRIGO_SHIFT); - - end.x = x + ((r - ext->indicator.style->body.padding.inner - ext->indicator.style->line.width/2) * lv_trigo_sin(angle) >> LV_TRIGO_SHIFT); - end.y = y + ((r - ext->indicator.style->body.padding.inner - ext->indicator.style->line.width/2) * lv_trigo_sin(angle + 90) >> LV_TRIGO_SHIFT); - - lv_draw_line(&start, &end, mask, ext->indicator.style, opa_scale); - if(ext->indicator.style->line.rounded) - { - lv_area_t circle_area; - circle_area.x1 = start.x - ((ext->indicator.style->line.width - 1) >> 1) - ((ext->indicator.style->line.width - 1) & 0x1); - circle_area.y1 = start.y - ((ext->indicator.style->line.width - 1) >> 1) - ((ext->indicator.style->line.width - 1) & 0x1); - circle_area.x2 = start.x + ((ext->indicator.style->line.width - 1) >> 1); - circle_area.y2 = start.y + ((ext->indicator.style->line.width - 1) >> 1); - lv_draw_rect(&circle_area, mask, ext->indicator.style, opa_scale); - - circle_area.x1 = end.x - ((ext->indicator.style->line.width - 1) >> 1) - ((ext->indicator.style->line.width - 1) & 0x1); - circle_area.y1 = end.y - ((ext->indicator.style->line.width - 1) >> 1) - ((ext->indicator.style->line.width - 1) & 0x1); - circle_area.x2 = end.x + ((ext->indicator.style->line.width - 1) >> 1); - circle_area.y2 = end.y + ((ext->indicator.style->line.width - 1) >> 1); - lv_draw_rect(&circle_area, mask, ext->indicator.style, opa_scale); - } - break; + circle_area.x1 = end.x - ((ext->indicator.style->line.width - 1) >> 1) - ((ext->indicator.style->line.width - 1) & 0x1); + circle_area.y1 = end.y - ((ext->indicator.style->line.width - 1) >> 1) - ((ext->indicator.style->line.width - 1) & 0x1); + circle_area.x2 = end.x + ((ext->indicator.style->line.width - 1) >> 1); + circle_area.y2 = end.y + ((ext->indicator.style->line.width - 1) >> 1); + lv_draw_rect(&circle_area, mask, ext->indicator.style, opa_scale); } - case LV_CPICKER_INDICATOR_CIRCLE: - { - lv_area_t circle_ind_area; - uint32_t cx, cy; + break; + } + case LV_CPICKER_INDICATOR_CIRCLE: + { + lv_area_t circle_ind_area; + uint32_t cx, cy; - uint16_t angle = mode_color_to_angle(ext); + uint16_t angle = mode_color_to_angle(ext); - /*save the angle to refresh the area later*/ - ext->prev_pos = angle; + /*save the angle to refresh the area later*/ + ext->prev_pos = angle; - cx = x + ((r - style->line.width/2) * lv_trigo_sin(angle) >> LV_TRIGO_SHIFT); - cy = y + ((r - style->line.width/2) * lv_trigo_sin(angle + 90) >> LV_TRIGO_SHIFT); + cx = x + ((r - style->line.width/2) * lv_trigo_sin(angle) >> LV_TRIGO_SHIFT); + cy = y + ((r - style->line.width/2) * lv_trigo_sin(angle + 90) >> LV_TRIGO_SHIFT); - circle_ind_area.x1 = cx - style->line.width/2; - circle_ind_area.y1 = cy - style->line.width/2; + circle_ind_area.x1 = cx - style->line.width/2; + circle_ind_area.y1 = cy - style->line.width/2; circle_ind_area.x2 = cx + style->line.width/2; circle_ind_area.y2 = cy + style->line.width/2; @@ -835,27 +835,27 @@ static bool lv_cpicker_disc_design(lv_obj_t * cpicker, const lv_area_t * mask, l lv_style_copy(&styleCopy, ext->indicator.style); styleCopy.body.radius = LV_RADIUS_CIRCLE; - lv_draw_rect(&circle_ind_area, mask, &styleCopy, opa_scale); - break; - } - case LV_CPICKER_INDICATOR_IN: - { - lv_area_t circle_ind_area; - uint32_t cx, cy; + lv_draw_rect(&circle_ind_area, mask, &styleCopy, opa_scale); + break; + } + case LV_CPICKER_INDICATOR_IN: + { + lv_area_t circle_ind_area; + uint32_t cx, cy; - uint16_t angle = mode_color_to_angle(ext); + uint16_t angle = mode_color_to_angle(ext); - /*save the angle to refresh the area later*/ - ext->prev_pos = angle; + /*save the angle to refresh the area later*/ + ext->prev_pos = angle; - uint16_t ind_radius = lv_sqrt((4*rin*rin)/2)/2 + 1 - style->body.padding.inner; - ind_radius = (ind_radius + rin) / 2; + uint16_t ind_radius = lv_sqrt((4*rin*rin)/2)/2 + 1 - style->body.padding.inner; + ind_radius = (ind_radius + rin) / 2; - cx = x + ((ind_radius) * lv_trigo_sin(angle) >> LV_TRIGO_SHIFT); - cy = y + ((ind_radius) * lv_trigo_sin(angle + 90) >> LV_TRIGO_SHIFT); + cx = x + ((ind_radius) * lv_trigo_sin(angle) >> LV_TRIGO_SHIFT); + cy = y + ((ind_radius) * lv_trigo_sin(angle + 90) >> LV_TRIGO_SHIFT); - circle_ind_area.x1 = cx - ((wradius - radius) / 3); - circle_ind_area.y1 = cy - ((wradius - radius) / 3); + circle_ind_area.x1 = cx - ((wradius - radius) / 3); + circle_ind_area.y1 = cy - ((wradius - radius) / 3); circle_ind_area.x2 = cx + ((wradius - radius) / 3); circle_ind_area.y2 = cy + ((wradius - radius) / 3); @@ -863,21 +863,21 @@ static bool lv_cpicker_disc_design(lv_obj_t * cpicker, const lv_area_t * mask, l lv_style_copy(&styleCopy, ext->indicator.style); styleCopy.body.radius = LV_RADIUS_CIRCLE; - lv_draw_rect(&circle_ind_area, mask, &styleCopy, opa_scale); - break; - } - } // switch + lv_draw_rect(&circle_ind_area, mask, &styleCopy, opa_scale); + break; + } + } /* switch */ - /* - //code to color the drawn area - static uint32_t c = 0; - lv_style_t style2; - lv_style_copy(&style2, &lv_style_plain); - style2.body.main_color.full = c; - style2.body.grad_color.full = c; + /* + //code to color the drawn area + static uint32_t c = 0; + lv_style_t style2; + lv_style_copy(&style2, &lv_style_plain); + style2.body.main_color.full = c; + style2.body.grad_color.full = c; c += 0x123445678; lv_draw_rect(mask, mask, &style2, opa_scale); - */ + */ return true; } @@ -888,95 +888,95 @@ static bool lv_cpicker_rect_design(lv_obj_t * cpicker, const lv_area_t * mask, l lv_coord_t w = lv_obj_get_width(cpicker); lv_coord_t h = lv_obj_get_height(cpicker); - lv_coord_t x1 = cpicker->coords.x1; - lv_coord_t y1 = cpicker->coords.y1; - lv_coord_t x2 = cpicker->coords.x2; - lv_coord_t y2 = cpicker->coords.y2; - lv_opa_t opa_scale = lv_obj_get_opa_scale(cpicker); + lv_coord_t x1 = cpicker->coords.x1; + lv_coord_t y1 = cpicker->coords.y1; + lv_coord_t x2 = cpicker->coords.x2; + lv_coord_t y2 = cpicker->coords.y2; + lv_opa_t opa_scale = lv_obj_get_opa_scale(cpicker); - /* prepare the color preview area */ - uint16_t preview_offset = style->line.width; - uint16_t style_body_padding_ver = style->body.padding.top + style->body.padding.bottom; - uint16_t style_body_padding_hor = style->body.padding.left + style->body.padding.right; - if(style_body_padding_ver == 0) + /*prepare the color preview area*/ + uint16_t preview_offset = style->line.width; + uint16_t style_body_padding_ver = style->body.padding.top + style->body.padding.bottom; + uint16_t style_body_padding_hor = style->body.padding.left + style->body.padding.right; + if(style_body_padding_ver == 0) + { + /*draw the color preview rect to the side of the gradient*/ + if(style_body_padding_hor >= 0) { - /* draw the color preview rect to the side of the gradient*/ - if(style_body_padding_hor >= 0) - { - /*draw the preview to the right*/ - ext->rect_gradient_w = w - preview_offset - (LV_MATH_ABS(style_body_padding_hor) - 1); - ext->rect_gradient_h = y2 - y1; - ext->rect_gradient_area.x1 = x1; - ext->rect_gradient_area.x2 = ext->rect_gradient_area.x1 + ext->rect_gradient_w; - ext->rect_gradient_area.y1 = y1; - ext->rect_gradient_area.y2 = y2; + /*draw the preview to the right*/ + ext->rect_gradient_w = w - preview_offset - (LV_MATH_ABS(style_body_padding_hor) - 1); + ext->rect_gradient_h = y2 - y1; + ext->rect_gradient_area.x1 = x1; + ext->rect_gradient_area.x2 = ext->rect_gradient_area.x1 + ext->rect_gradient_w; + ext->rect_gradient_area.y1 = y1; + ext->rect_gradient_area.y2 = y2; - ext->rect_preview_area.x1 = x2 - preview_offset; - ext->rect_preview_area.y1 = y1; - ext->rect_preview_area.x2 = x2 ; - ext->rect_preview_area.y2 = y2; - } - else - { - /*draw the preview to the left*/ - ext->rect_gradient_w = w - preview_offset - (LV_MATH_ABS(style_body_padding_hor) - 1); - ext->rect_gradient_h = y2 - y1; - ext->rect_gradient_area.x1 = x2 - ext->rect_gradient_w; - ext->rect_gradient_area.x2 = x2; - ext->rect_gradient_area.y1 = y1; - ext->rect_gradient_area.y2 = y2; - - ext->rect_preview_area.x1 = x1; - ext->rect_preview_area.y1 = y1; - ext->rect_preview_area.x2 = x1 + preview_offset; - ext->rect_preview_area.y2 = y2; - } + ext->rect_preview_area.x1 = x2 - preview_offset; + ext->rect_preview_area.y1 = y1; + ext->rect_preview_area.x2 = x2 ; + ext->rect_preview_area.y2 = y2; } else { - /* draw the color preview rect on top or below the gradient*/ - if(style_body_padding_ver >= 0) - { - /*draw the preview on top*/ - ext->rect_gradient_w = w; - ext->rect_gradient_h = (y2 - y1) - preview_offset - (LV_MATH_ABS(style_body_padding_ver) - 1); - ext->rect_gradient_area.x1 = x1; - ext->rect_gradient_area.x2 = x2; - ext->rect_gradient_area.y1 = y2 - ext->rect_gradient_h; - ext->rect_gradient_area.y2 = y2; + /*draw the preview to the left*/ + ext->rect_gradient_w = w - preview_offset - (LV_MATH_ABS(style_body_padding_hor) - 1); + ext->rect_gradient_h = y2 - y1; + ext->rect_gradient_area.x1 = x2 - ext->rect_gradient_w; + ext->rect_gradient_area.x2 = x2; + ext->rect_gradient_area.y1 = y1; + ext->rect_gradient_area.y2 = y2; - ext->rect_preview_area.x1 = x1; - ext->rect_preview_area.y1 = y1; - ext->rect_preview_area.x2 = x2; - ext->rect_preview_area.y2 = y1 + preview_offset; - } - else - { - /*draw the preview below the gradient*/ - ext->rect_gradient_w = w; - ext->rect_gradient_h = (y2 - y1) - preview_offset - (LV_MATH_ABS(style_body_padding_ver) - 1); - ext->rect_gradient_area.x1 = x1; - ext->rect_gradient_area.x2 = x2; - ext->rect_gradient_area.y1 = y1; - ext->rect_gradient_area.y2 = y1 + ext->rect_gradient_h; - - ext->rect_preview_area.x1 = x1; - ext->rect_preview_area.y1 = y2 - preview_offset; - ext->rect_preview_area.x2 = x2; - ext->rect_preview_area.y2 = y2; - } + ext->rect_preview_area.x1 = x1; + ext->rect_preview_area.y1 = y1; + ext->rect_preview_area.x2 = x1 + preview_offset; + ext->rect_preview_area.y2 = y2; } - - if(style->line.rounded) + } + else + { + /*draw the color preview rect on top or below the gradient*/ + if(style_body_padding_ver >= 0) { - /*draw rounded edges to the gradient*/ - lv_area_t rounded_edge_area; - rounded_edge_area.x1 = ext->rect_gradient_area.x1; - rounded_edge_area.x2 = ext->rect_gradient_area.x1 + ext->rect_gradient_h; - rounded_edge_area.y1 = ext->rect_gradient_area.y1; - rounded_edge_area.y2 = ext->rect_gradient_area.y2; + /*draw the preview on top*/ + ext->rect_gradient_w = w; + ext->rect_gradient_h = (y2 - y1) - preview_offset - (LV_MATH_ABS(style_body_padding_ver) - 1); + ext->rect_gradient_area.x1 = x1; + ext->rect_gradient_area.x2 = x2; + ext->rect_gradient_area.y1 = y2 - ext->rect_gradient_h; + ext->rect_gradient_area.y2 = y2; - ext->rect_gradient_area.x1 += ext->rect_gradient_h/2; + ext->rect_preview_area.x1 = x1; + ext->rect_preview_area.y1 = y1; + ext->rect_preview_area.x2 = x2; + ext->rect_preview_area.y2 = y1 + preview_offset; + } + else + { + /*draw the preview below the gradient*/ + ext->rect_gradient_w = w; + ext->rect_gradient_h = (y2 - y1) - preview_offset - (LV_MATH_ABS(style_body_padding_ver) - 1); + ext->rect_gradient_area.x1 = x1; + ext->rect_gradient_area.x2 = x2; + ext->rect_gradient_area.y1 = y1; + ext->rect_gradient_area.y2 = y1 + ext->rect_gradient_h; + + ext->rect_preview_area.x1 = x1; + ext->rect_preview_area.y1 = y2 - preview_offset; + ext->rect_preview_area.x2 = x2; + ext->rect_preview_area.y2 = y2; + } + } + + if(style->line.rounded) + { + /*draw rounded edges to the gradient*/ + lv_area_t rounded_edge_area; + rounded_edge_area.x1 = ext->rect_gradient_area.x1; + rounded_edge_area.x2 = ext->rect_gradient_area.x1 + ext->rect_gradient_h; + rounded_edge_area.y1 = ext->rect_gradient_area.y1; + rounded_edge_area.y2 = ext->rect_gradient_area.y2; + + ext->rect_gradient_area.x1 += ext->rect_gradient_h/2; ext->rect_gradient_area.x2 -= ext->rect_gradient_h/2; ext->rect_gradient_w -= ext->rect_gradient_h; @@ -1009,11 +1009,11 @@ static bool lv_cpicker_rect_design(lv_obj_t * cpicker, const lv_area_t * mask, l lv_area_t rect_area; - /*scale angle (hue/sat/val) to linear coordinate*/ - lv_coord_t xi = i / 360.0 * ext->rect_gradient_w; + /*scale angle (hue/sat/val) to linear coordinate*/ + lv_coord_t xi = i / 360.0 * ext->rect_gradient_w; - rect_area.x1 = LV_MATH_MIN(ext->rect_gradient_area.x1 + xi, ext->rect_gradient_area.x1 + ext->rect_gradient_w - LV_MATH_MAX(LV_CPICKER_DEF_QF, 360/ext->rect_gradient_w)); - rect_area.y1 = ext->rect_gradient_area.y1; + rect_area.x1 = LV_MATH_MIN(ext->rect_gradient_area.x1 + xi, ext->rect_gradient_area.x1 + ext->rect_gradient_w - LV_MATH_MAX(LV_CPICKER_DEF_QF, 360/ext->rect_gradient_w)); + rect_area.y1 = ext->rect_gradient_area.y1; rect_area.x2 = rect_area.x1 + LV_MATH_MAX(LV_CPICKER_DEF_QF, 360/ext->rect_gradient_w); rect_area.y2 = ext->rect_gradient_area.y2; @@ -1021,11 +1021,11 @@ static bool lv_cpicker_rect_design(lv_obj_t * cpicker, const lv_area_t * mask, l } if(style->line.rounded) - { - /*Restore gradient area to take rounded end in account*/ - ext->rect_gradient_area.x1 -= ext->rect_gradient_h/2; - ext->rect_gradient_area.x2 += ext->rect_gradient_h/2; - //ext->rect_gradient_w += ext->rect_gradient_h; + { + /*Restore gradient area to take rounded end in account*/ + ext->rect_gradient_area.x1 -= ext->rect_gradient_h/2; + ext->rect_gradient_area.x2 += ext->rect_gradient_h/2; + //ext->rect_gradient_w += ext->rect_gradient_h; } /*draw the color preview indicator*/ @@ -1039,50 +1039,50 @@ static bool lv_cpicker_rect_design(lv_obj_t * cpicker, const lv_area_t * mask, l /* styleCopy.line.width = 10; - lv_draw_arc(cpicker->coords.x1 + 3*ext->rect_gradient_h/2, cpicker->coords.y1 + ext->rect_gradient_h/2, ext->rect_gradient_h / 2 + styleCopy.line.width + 2, mask, 180, 360, &styleCopy, opa_scale); - //lv_draw_arc(cpicker->coords.x1 + ext->rect_gradient_w - ext->rect_gradient_h/2, cpicker->coords.y1 + ext->rect_gradient_h/2, ext->rect_gradient_h / 2 + styleCopy.line.width + 2, mask, 0, 180, &styleCopy, opa_scale); - */ + lv_draw_arc(cpicker->coords.x1 + 3*ext->rect_gradient_h/2, cpicker->coords.y1 + ext->rect_gradient_h/2, ext->rect_gradient_h / 2 + styleCopy.line.width + 2, mask, 180, 360, &styleCopy, opa_scale); + //lv_draw_arc(cpicker->coords.x1 + ext->rect_gradient_w - ext->rect_gradient_h/2, cpicker->coords.y1 + ext->rect_gradient_h/2, ext->rect_gradient_h / 2 + styleCopy.line.width + 2, mask, 0, 180, &styleCopy, opa_scale); + */ - /*draw the color position indicator*/ - lv_coord_t ind_pos = style->line.rounded ? ext->rect_gradient_h / 2 : 0; - switch(ext->color_mode) - { - default: - case LV_CPICKER_COLOR_MODE_HUE: - ind_pos += ext->hue * ext->rect_gradient_w / 360.0; - break; - case LV_CPICKER_COLOR_MODE_SATURATION: - ind_pos += ext->saturation * ext->rect_gradient_w / 100.0; - break; - case LV_CPICKER_COLOR_MODE_VALUE: - ind_pos += ext->value * ext->rect_gradient_w / 100.0; - break; - } + /*draw the color position indicator*/ + lv_coord_t ind_pos = style->line.rounded ? ext->rect_gradient_h / 2 : 0; + switch(ext->color_mode) + { + default: + case LV_CPICKER_COLOR_MODE_HUE: + ind_pos += ext->hue * ext->rect_gradient_w / 360.0; + break; + case LV_CPICKER_COLOR_MODE_SATURATION: + ind_pos += ext->saturation * ext->rect_gradient_w / 100.0; + break; + case LV_CPICKER_COLOR_MODE_VALUE: + ind_pos += ext->value * ext->rect_gradient_w / 100.0; + break; + } - /*save to refresh the area later*/ - ext->prev_pos = ind_pos; + /*save to refresh the area later*/ + ext->prev_pos = ind_pos; - switch(ext->indicator.type) - { - case LV_CPICKER_INDICATOR_NONE: - /*no indicator*/ - break; - case LV_CPICKER_INDICATOR_LINE: - { - lv_point_t p1, p2; - p1.x = ext->rect_gradient_area.x1 + ind_pos; - p1.y = ext->rect_gradient_area.y1; - p2.x = p1.x; - p2.y = ext->rect_gradient_area.y2; + switch(ext->indicator.type) + { + case LV_CPICKER_INDICATOR_NONE: + /*no indicator*/ + break; + case LV_CPICKER_INDICATOR_LINE: + { + lv_point_t p1, p2; + p1.x = ext->rect_gradient_area.x1 + ind_pos; + p1.y = ext->rect_gradient_area.y1; + p2.x = p1.x; + p2.y = ext->rect_gradient_area.y2; - lv_draw_line(&p1, &p2, mask, ext->indicator.style, opa_scale); - break; - } - case LV_CPICKER_INDICATOR_CIRCLE: - { - lv_area_t circle_ind_area; - circle_ind_area.x1 = ext->rect_gradient_area.x1 + ind_pos - ext->rect_gradient_h/2; - circle_ind_area.x2 = circle_ind_area.x1 + ext->rect_gradient_h; + lv_draw_line(&p1, &p2, mask, ext->indicator.style, opa_scale); + break; + } + case LV_CPICKER_INDICATOR_CIRCLE: + { + lv_area_t circle_ind_area; + circle_ind_area.x1 = ext->rect_gradient_area.x1 + ind_pos - ext->rect_gradient_h/2; + circle_ind_area.x2 = circle_ind_area.x1 + ext->rect_gradient_h; circle_ind_area.y1 = ext->rect_gradient_area.y1; circle_ind_area.y2 = ext->rect_gradient_area.y2; @@ -1093,29 +1093,29 @@ static bool lv_cpicker_rect_design(lv_obj_t * cpicker, const lv_area_t * mask, l break; } case LV_CPICKER_INDICATOR_IN: - { - /*draw triangle under the gradient*/ - lv_point_t triangle_points[3]; + { + /*draw triangle under the gradient*/ + lv_point_t triangle_points[3]; - triangle_points[0].x = ext->rect_gradient_area.x1 + ind_pos; - triangle_points[0].y = ext->rect_gradient_area.y1 + (ext->rect_gradient_h/3); + triangle_points[0].x = ext->rect_gradient_area.x1 + ind_pos; + triangle_points[0].y = ext->rect_gradient_area.y1 + (ext->rect_gradient_h/3); - triangle_points[1].x = triangle_points[0].x - ext->indicator.style->line.width * 3; - triangle_points[1].y = ext->rect_gradient_area.y1 - 1; + triangle_points[1].x = triangle_points[0].x - ext->indicator.style->line.width * 3; + triangle_points[1].y = ext->rect_gradient_area.y1 - 1; - triangle_points[2].x = triangle_points[0].x + ext->indicator.style->line.width * 3; - triangle_points[2].y = triangle_points[1].y; + triangle_points[2].x = triangle_points[0].x + ext->indicator.style->line.width * 3; + triangle_points[2].y = triangle_points[1].y; - lv_draw_triangle(triangle_points, mask, ext->indicator.style, LV_OPA_COVER); + lv_draw_triangle(triangle_points, mask, ext->indicator.style, LV_OPA_COVER); - triangle_points[0].y = ext->rect_gradient_area.y2 - (ext->rect_gradient_h/3); - triangle_points[1].y = ext->rect_gradient_area.y2; - triangle_points[2].y = triangle_points[1].y; - lv_draw_triangle(triangle_points, mask, ext->indicator.style, LV_OPA_COVER); - break; - } - default: - break; + triangle_points[0].y = ext->rect_gradient_area.y2 - (ext->rect_gradient_h/3); + triangle_points[1].y = ext->rect_gradient_area.y2; + triangle_points[2].y = triangle_points[1].y; + lv_draw_triangle(triangle_points, mask, ext->indicator.style, LV_OPA_COVER); + break; + } + default: + break; } return true; From 847669273137827be28b45537266326485d0f024 Mon Sep 17 00:00:00 2001 From: Paul Peavyhouse Date: Thu, 26 Sep 2019 12:32:05 -0700 Subject: [PATCH 18/25] [Still] working cleanup checkpoint --- src/lv_objx/lv_cpicker.c | 277 ++++++++++++++++++--------------------- 1 file changed, 131 insertions(+), 146 deletions(-) diff --git a/src/lv_objx/lv_cpicker.c b/src/lv_objx/lv_cpicker.c index 068d6b2a5..c4c91ce74 100644 --- a/src/lv_objx/lv_cpicker.c +++ b/src/lv_objx/lv_cpicker.c @@ -425,23 +425,125 @@ static uint16_t mode_color_to_angle(lv_cpicker_ext_t * ext) } static void draw_disk_indicator_line(lv_cpicker_ext_t * ext, lv_style_t * style, lv_area_t * mask, lv_opa_t opa_scale, - lv_coord_t r, lv_coord_t x, lv_coord_t y) + lv_coord_t x, lv_coord_t y, uint16_t r, uint16_t angle) { + lv_point_t start; + lv_point_t end; + start.x = x + ((r - style->line.width + ext->indicator.style->body.padding.inner + ext->indicator.style->line.width/2) * lv_trigo_sin(angle) >> LV_TRIGO_SHIFT); + start.y = y + ((r - style->line.width + ext->indicator.style->body.padding.inner + ext->indicator.style->line.width/2) * lv_trigo_sin(angle + 90) >> LV_TRIGO_SHIFT); + end.x = x + ((r - ext->indicator.style->body.padding.inner - ext->indicator.style->line.width/2) * lv_trigo_sin(angle) >> LV_TRIGO_SHIFT); + end.y = y + ((r - ext->indicator.style->body.padding.inner - ext->indicator.style->line.width/2) * lv_trigo_sin(angle + 90) >> LV_TRIGO_SHIFT); + + lv_draw_line(&start, &end, mask, ext->indicator.style, opa_scale); + + if(ext->indicator.style->line.rounded) + { + lv_area_t circle_area; + circle_area.x1 = start.x - ((ext->indicator.style->line.width - 1) >> 1) - ((ext->indicator.style->line.width - 1) & 0x1); + circle_area.y1 = start.y - ((ext->indicator.style->line.width - 1) >> 1) - ((ext->indicator.style->line.width - 1) & 0x1); + circle_area.x2 = start.x + ((ext->indicator.style->line.width - 1) >> 1); + circle_area.y2 = start.y + ((ext->indicator.style->line.width - 1) >> 1); + lv_draw_rect(&circle_area, mask, ext->indicator.style, opa_scale); + + circle_area.x1 = end.x - ((ext->indicator.style->line.width - 1) >> 1) - ((ext->indicator.style->line.width - 1) & 0x1); + circle_area.y1 = end.y - ((ext->indicator.style->line.width - 1) >> 1) - ((ext->indicator.style->line.width - 1) & 0x1); + circle_area.x2 = end.x + ((ext->indicator.style->line.width - 1) >> 1); + circle_area.y2 = end.y + ((ext->indicator.style->line.width - 1) >> 1); + lv_draw_rect(&circle_area, mask, ext->indicator.style, opa_scale); + } } static void draw_disk_indicator_circle(lv_cpicker_ext_t * ext, lv_style_t * style, lv_area_t * mask, lv_opa_t opa_scale, - lv_coord_t r, lv_coord_t x, lv_coord_t y) + lv_coord_t x, lv_coord_t y, uint16_t r, uint16_t angle) { + uint32_t cx, cy; + cx = x + ((r - style->line.width/2) * lv_trigo_sin(angle) >> LV_TRIGO_SHIFT); + cy = y + ((r - style->line.width/2) * lv_trigo_sin(angle + 90) >> LV_TRIGO_SHIFT); + + lv_area_t circle_ind_area; + circle_ind_area.x1 = cx - style->line.width/2; + circle_ind_area.y1 = cy - style->line.width/2; + circle_ind_area.x2 = cx + style->line.width/2; + circle_ind_area.y2 = cy + style->line.width/2; + + lv_style_t styleCopy; + lv_style_copy(&styleCopy, ext->indicator.style); + styleCopy.body.radius = LV_RADIUS_CIRCLE; + + lv_draw_rect(&circle_ind_area, mask, &styleCopy, opa_scale); } static void draw_disk_indicator_in(lv_cpicker_ext_t * ext, lv_style_t * style, lv_area_t * mask, lv_opa_t opa_scale, - lv_coord_t rin, lv_coord_t x, lv_coord_t y) + lv_coord_t x, lv_coord_t y, uint16_t r, uint16_t angle, + uint16_t rin) { + uint16_t ind_radius = lv_sqrt((4*rin*rin)/2)/2 + 1 - style->body.padding.inner; + ind_radius = (ind_radius + rin) / 2; + + uint32_t cx = x + ((ind_radius) * lv_trigo_sin(angle) >> LV_TRIGO_SHIFT); + uint32_t cy = y + ((ind_radius) * lv_trigo_sin(angle + 90) >> LV_TRIGO_SHIFT); + + lv_area_t circle_ind_area; + circle_ind_area.x1 = cx - r; + circle_ind_area.y1 = cy - r; + circle_ind_area.x2 = cx + r; + circle_ind_area.y2 = cy + r; + + lv_style_t styleCopy; + lv_style_copy(&styleCopy, ext->indicator.style); + styleCopy.body.radius = LV_RADIUS_CIRCLE; + + lv_draw_rect(&circle_ind_area, mask, &styleCopy, opa_scale); } static void draw_disk_indicator(lv_cpicker_ext_t * ext, lv_style_t * style, lv_area_t * mask, lv_opa_t opa_scale, - lv_coord_t r, lv_coord_t x, lv_coord_t y, uint32_t rin) + lv_coord_t x, lv_coord_t y, lv_coord_t r, uint16_t angle, + uint16_t rin, uint16_t radius, lv_area_t center_ind_area) { + /*draw center background*/ + static lv_style_t styleCenterBackground; + lv_theme_t * th = lv_theme_get_current(); + if (th) { + lv_style_copy(&styleCenterBackground, th->style.bg); + } else { + lv_style_copy(&styleCenterBackground, &lv_style_plain); + } + + lv_area_t center_area; + center_area.x1 = x - rin; + center_area.y1 = y - rin; + center_area.x2 = x + rin; + center_area.y2 = y + rin; + styleCenterBackground.body.radius = LV_RADIUS_CIRCLE; + lv_draw_rect(¢er_area, mask, &styleCenterBackground, opa_scale); + + /*draw the center color indicator*/ + style->body.main_color = lv_color_hsv_to_rgb(ext->hue, ext->saturation, ext->value); + style->body.grad_color = style->body.main_color; + style->body.radius = LV_RADIUS_CIRCLE; + lv_draw_rect(¢er_ind_area, mask, style, opa_scale); + + /*draw the current hue indicator*/ + switch(ext->indicator.type) + { + case LV_CPICKER_INDICATOR_NONE: + break; + case LV_CPICKER_INDICATOR_LINE: + { + draw_disk_indicator_line(ext, style, mask, opa_scale, x, y, r, angle); + break; + } + case LV_CPICKER_INDICATOR_CIRCLE: + { + draw_disk_indicator_circle(ext, style, mask, opa_scale, x, y, r, angle); + break; + } + case LV_CPICKER_INDICATOR_IN: + { + draw_disk_indicator_in(ext, style, mask, opa_scale, x, y, (rin - radius) / 3, angle, rin); + break; + } + } } static void draw_disk_spectrum(lv_cpicker_ext_t * ext, lv_style_t * style, lv_area_t * mask, lv_opa_t opa_scale, @@ -481,10 +583,10 @@ static void draw_rect_spectrum(lv_cpicker_ext_t * ext, lv_style_t * style, lv_ar { } -static bool lv_cpicker_disc_design(lv_obj_t * cpicker, const lv_area_t * mask, lv_design_mode_t mode, - lv_cpicker_ext_t * ext, lv_style_t * style); -static bool lv_cpicker_rect_design(lv_obj_t * cpicker, const lv_area_t * mask, lv_design_mode_t mode, - lv_cpicker_ext_t * ext, lv_style_t * style); +static void lv_cpicker_disc_design(lv_obj_t * cpicker, const lv_area_t * mask, lv_style_t * style, lv_opa_t opa_scale, + lv_cpicker_ext_t * ext, lv_coord_t w, lv_coord_t h); +static void lv_cpicker_rect_design(lv_obj_t * cpicker, const lv_area_t * mask, lv_style_t * style, lv_opa_t opa_scale, + lv_cpicker_ext_t * ext, lv_coord_t w, lv_coord_t h); /** * Handle the drawing related tasks of the color_picker @@ -511,13 +613,18 @@ static bool lv_cpicker_design(lv_obj_t * cpicker, const lv_area_t * mask, lv_des static lv_style_t styleCopy; lv_style_copy(&styleCopy, style); + lv_opa_t opa_scale = lv_obj_get_opa_scale(cpicker); + + lv_coord_t w = lv_obj_get_width(cpicker); + lv_coord_t h = lv_obj_get_height(cpicker); + if(ext->type == LV_CPICKER_TYPE_DISC) { - return lv_cpicker_disc_design(cpicker, mask, mode, ext, &styleCopy); + lv_cpicker_disc_design(cpicker, mask, &styleCopy, opa_scale, ext, w, h); } else if(ext->type == LV_CPICKER_TYPE_RECT) { - return lv_cpicker_rect_design(cpicker, mask, mode, ext, &styleCopy); + lv_cpicker_rect_design(cpicker, mask, &styleCopy, opa_scale, ext, w, h); } } /*Post draw when the children are drawn*/ @@ -528,27 +635,15 @@ static bool lv_cpicker_design(lv_obj_t * cpicker, const lv_area_t * mask, lv_des return true; } -static bool lv_cpicker_disc_design(lv_obj_t * cpicker, const lv_area_t * mask, lv_design_mode_t mode, - lv_cpicker_ext_t * ext, lv_style_t * style) +static void lv_cpicker_disc_design(lv_obj_t * cpicker, const lv_area_t * mask, lv_style_t * style, lv_opa_t opa_scale, + lv_cpicker_ext_t * ext, lv_coord_t w, lv_coord_t h) { - static lv_style_t styleCenterBackground; - lv_theme_t * th = lv_theme_get_current(); - if (th) { - lv_style_copy(&styleCenterBackground, th->style.bg); - } else { - lv_style_copy(&styleCenterBackground, &lv_style_plain); - } + lv_coord_t x = cpicker->coords.x1 + w / 2; + lv_coord_t y = cpicker->coords.y1 + h / 2; - lv_coord_t r = (LV_MATH_MIN(lv_obj_get_width(cpicker), lv_obj_get_height(cpicker))) / 2; - lv_coord_t x = cpicker->coords.x1 + lv_obj_get_width(cpicker) / 2; - lv_coord_t y = cpicker->coords.y1 + lv_obj_get_height(cpicker) / 2; - lv_opa_t opa_scale = lv_obj_get_opa_scale(cpicker); + uint16_t r = LV_MATH_MIN(w, h) / 2; - uint8_t redraw_wheel = 0; - - lv_area_t center_ind_area; - - uint32_t rin = r - style->line.width; + uint16_t rin = r - style->line.width; //the square area (a and b being sides) should fit into the center of diameter d //we have: //a^2+b^2<=d^2 @@ -557,12 +652,14 @@ static bool lv_cpicker_disc_design(lv_obj_t * cpicker, const lv_area_t * mask, l //a <= sqrt((d^2)/2) uint16_t radius = lv_sqrt((4*rin*rin)/2)/2 - style->body.padding.inner; + lv_area_t center_ind_area; center_ind_area.x1 = x - radius; center_ind_area.y1 = y - radius; center_ind_area.x2 = x + radius; center_ind_area.y2 = y + radius; /*redraw the wheel only if the mask intersect with the wheel*/ + uint8_t redraw_wheel = 0; if(mask->x1 < center_ind_area.x1 || mask->x2 > center_ind_area.x2 || mask->y1 < center_ind_area.y1 || mask->y2 > center_ind_area.y2) { @@ -758,115 +855,11 @@ static bool lv_cpicker_disc_design(lv_obj_t * cpicker, const lv_area_t * mask, l } } - /*draw center background*/ - lv_area_t center_area; - uint16_t wradius = r - style->line.width; - center_area.x1 = x - wradius; - center_area.y1 = y - wradius; - center_area.x2 = x + wradius; - center_area.y2 = y + wradius; - styleCenterBackground.body.radius = LV_RADIUS_CIRCLE; - lv_draw_rect(¢er_area, mask, &styleCenterBackground, opa_scale); + uint16_t angle = mode_color_to_angle(ext); + /*save the angle to refresh the area later*/ + ext->prev_pos = angle; - /*draw the center color indicator*/ - style->body.main_color = lv_color_hsv_to_rgb(ext->hue, ext->saturation, ext->value); - style->body.grad_color = style->body.main_color; - style->body.radius = LV_RADIUS_CIRCLE; - lv_draw_rect(¢er_ind_area, mask, style, opa_scale); - - /*draw the current hue indicator*/ - switch(ext->indicator.type) - { - case LV_CPICKER_INDICATOR_NONE: - break; - case LV_CPICKER_INDICATOR_LINE: - { - lv_point_t start; - lv_point_t end; - - uint16_t angle = mode_color_to_angle(ext); - - /*save the angle to refresh the area later*/ - ext->prev_pos = angle; - - start.x = x + ((r - style->line.width + ext->indicator.style->body.padding.inner + ext->indicator.style->line.width/2) * lv_trigo_sin(angle) >> LV_TRIGO_SHIFT); - start.y = y + ((r - style->line.width + ext->indicator.style->body.padding.inner + ext->indicator.style->line.width/2) * lv_trigo_sin(angle + 90) >> LV_TRIGO_SHIFT); - - end.x = x + ((r - ext->indicator.style->body.padding.inner - ext->indicator.style->line.width/2) * lv_trigo_sin(angle) >> LV_TRIGO_SHIFT); - end.y = y + ((r - ext->indicator.style->body.padding.inner - ext->indicator.style->line.width/2) * lv_trigo_sin(angle + 90) >> LV_TRIGO_SHIFT); - - lv_draw_line(&start, &end, mask, ext->indicator.style, opa_scale); - if(ext->indicator.style->line.rounded) - { - lv_area_t circle_area; - circle_area.x1 = start.x - ((ext->indicator.style->line.width - 1) >> 1) - ((ext->indicator.style->line.width - 1) & 0x1); - circle_area.y1 = start.y - ((ext->indicator.style->line.width - 1) >> 1) - ((ext->indicator.style->line.width - 1) & 0x1); - circle_area.x2 = start.x + ((ext->indicator.style->line.width - 1) >> 1); - circle_area.y2 = start.y + ((ext->indicator.style->line.width - 1) >> 1); - lv_draw_rect(&circle_area, mask, ext->indicator.style, opa_scale); - - circle_area.x1 = end.x - ((ext->indicator.style->line.width - 1) >> 1) - ((ext->indicator.style->line.width - 1) & 0x1); - circle_area.y1 = end.y - ((ext->indicator.style->line.width - 1) >> 1) - ((ext->indicator.style->line.width - 1) & 0x1); - circle_area.x2 = end.x + ((ext->indicator.style->line.width - 1) >> 1); - circle_area.y2 = end.y + ((ext->indicator.style->line.width - 1) >> 1); - lv_draw_rect(&circle_area, mask, ext->indicator.style, opa_scale); - } - break; - } - case LV_CPICKER_INDICATOR_CIRCLE: - { - lv_area_t circle_ind_area; - uint32_t cx, cy; - - uint16_t angle = mode_color_to_angle(ext); - - /*save the angle to refresh the area later*/ - ext->prev_pos = angle; - - cx = x + ((r - style->line.width/2) * lv_trigo_sin(angle) >> LV_TRIGO_SHIFT); - cy = y + ((r - style->line.width/2) * lv_trigo_sin(angle + 90) >> LV_TRIGO_SHIFT); - - circle_ind_area.x1 = cx - style->line.width/2; - circle_ind_area.y1 = cy - style->line.width/2; - circle_ind_area.x2 = cx + style->line.width/2; - circle_ind_area.y2 = cy + style->line.width/2; - - lv_style_t styleCopy; - lv_style_copy(&styleCopy, ext->indicator.style); - styleCopy.body.radius = LV_RADIUS_CIRCLE; - - lv_draw_rect(&circle_ind_area, mask, &styleCopy, opa_scale); - break; - } - case LV_CPICKER_INDICATOR_IN: - { - lv_area_t circle_ind_area; - uint32_t cx, cy; - - uint16_t angle = mode_color_to_angle(ext); - - /*save the angle to refresh the area later*/ - ext->prev_pos = angle; - - uint16_t ind_radius = lv_sqrt((4*rin*rin)/2)/2 + 1 - style->body.padding.inner; - ind_radius = (ind_radius + rin) / 2; - - cx = x + ((ind_radius) * lv_trigo_sin(angle) >> LV_TRIGO_SHIFT); - cy = y + ((ind_radius) * lv_trigo_sin(angle + 90) >> LV_TRIGO_SHIFT); - - circle_ind_area.x1 = cx - ((wradius - radius) / 3); - circle_ind_area.y1 = cy - ((wradius - radius) / 3); - circle_ind_area.x2 = cx + ((wradius - radius) / 3); - circle_ind_area.y2 = cy + ((wradius - radius) / 3); - - lv_style_t styleCopy; - lv_style_copy(&styleCopy, ext->indicator.style); - styleCopy.body.radius = LV_RADIUS_CIRCLE; - - lv_draw_rect(&circle_ind_area, mask, &styleCopy, opa_scale); - break; - } - } /* switch */ + draw_disk_indicator(ext, style, mask, opa_scale, x, y, r, angle, rin, radius, center_ind_area); /* //code to color the drawn area @@ -878,21 +871,15 @@ static bool lv_cpicker_disc_design(lv_obj_t * cpicker, const lv_area_t * mask, l c += 0x123445678; lv_draw_rect(mask, mask, &style2, opa_scale); */ - - return true; } -static bool lv_cpicker_rect_design(lv_obj_t * cpicker, const lv_area_t * mask, lv_design_mode_t mode, - lv_cpicker_ext_t * ext, lv_style_t * style) +static void lv_cpicker_rect_design(lv_obj_t * cpicker, const lv_area_t * mask, lv_style_t * style, lv_opa_t opa_scale, + lv_cpicker_ext_t * ext, lv_coord_t w, lv_coord_t h) { - lv_coord_t w = lv_obj_get_width(cpicker); - lv_coord_t h = lv_obj_get_height(cpicker); - lv_coord_t x1 = cpicker->coords.x1; lv_coord_t y1 = cpicker->coords.y1; lv_coord_t x2 = cpicker->coords.x2; lv_coord_t y2 = cpicker->coords.y2; - lv_opa_t opa_scale = lv_obj_get_opa_scale(cpicker); /*prepare the color preview area*/ uint16_t preview_offset = style->line.width; @@ -1117,8 +1104,6 @@ static bool lv_cpicker_rect_design(lv_obj_t * cpicker, const lv_area_t * mask, l default: break; } - - return true; } From 280c291db7880fd9767244201ae4afdb6d2022da Mon Sep 17 00:00:00 2001 From: Paul Peavyhouse Date: Thu, 26 Sep 2019 15:27:12 -0700 Subject: [PATCH 19/25] Cleaned up and ready for [hopefully] final code review! --- src/lv_objx/lv_cpicker.c | 2179 ++++++++++++++++++-------------------- 1 file changed, 1008 insertions(+), 1171 deletions(-) diff --git a/src/lv_objx/lv_cpicker.c b/src/lv_objx/lv_cpicker.c index c4c91ce74..9889c248e 100644 --- a/src/lv_objx/lv_cpicker.c +++ b/src/lv_objx/lv_cpicker.c @@ -67,8 +67,6 @@ static bool lv_cpicker_design(lv_obj_t * cpicker, const lv_area_t * mask, lv_design_mode_t mode); static lv_res_t lv_cpicker_signal(lv_obj_t * cpicker, lv_signal_t sign, void * param); -static void lv_cpicker_invalidate(lv_obj_t * cpicker, bool all); - /********************** * STATIC VARIABLES **********************/ @@ -386,6 +384,67 @@ lv_color_t lv_cpicker_get_color(lv_obj_t * cpicker) * STATIC FUNCTIONS **********************/ +static void lv_cpicker_disc_design(lv_obj_t * cpicker, + lv_area_t * mask, lv_style_t * style, lv_opa_t opa_scale, + lv_cpicker_ext_t * ext, + lv_coord_t w, lv_coord_t h, + lv_coord_t cx, lv_coord_t cy, uint16_t r); +static void lv_cpicker_rect_design(lv_obj_t * cpicker, + lv_area_t * mask, lv_style_t * style, lv_opa_t opa_scale, + lv_cpicker_ext_t * ext, + lv_coord_t w, lv_coord_t h); + +/** + * Handle the drawing related tasks of the color_picker + * @param cpicker pointer to an object + * @param mask the object will be drawn only in this area + * @param mode LV_DESIGN_COVER_CHK: only check if the object fully covers the 'mask_p' area + * (return 'true' if yes) + * LV_DESIGN_DRAW: draw the object (always return 'true') + * LV_DESIGN_DRAW_POST: drawing after every children are drawn + * @return true/false, depends on 'mode' + */ +static bool lv_cpicker_design(lv_obj_t * cpicker, const lv_area_t * mask, lv_design_mode_t mode) +{ + /*Return false if the object is not covers the mask_p area*/ + if(mode == LV_DESIGN_COVER_CHK) + { + return false; + } + /*Draw the object*/ + else if(mode == LV_DESIGN_DRAW_MAIN) + { + lv_cpicker_ext_t * ext = lv_obj_get_ext_attr(cpicker); + lv_style_t * style = lv_cpicker_get_style(cpicker, LV_CPICKER_STYLE_MAIN); + + static lv_style_t styleCopy; + lv_style_copy(&styleCopy, style); + + lv_opa_t opa_scale = lv_obj_get_opa_scale(cpicker); + + lv_coord_t w = lv_obj_get_width(cpicker); + lv_coord_t h = lv_obj_get_height(cpicker); + + if(ext->type == LV_CPICKER_TYPE_DISC) + { + lv_coord_t cx = cpicker->coords.x1 + (w / 2); + lv_coord_t cy = cpicker->coords.y1 + (h / 2); + uint16_t r = LV_MATH_MIN(w, h) / 2; + lv_cpicker_disc_design(cpicker, mask, &styleCopy, opa_scale, ext, w, h, cx, cy, r); + } + else if(ext->type == LV_CPICKER_TYPE_RECT) + { + lv_cpicker_rect_design(cpicker, mask, &styleCopy, opa_scale, ext, w, h); + } + } + /*Post draw when the children are drawn*/ + else if(mode == LV_DESIGN_DRAW_POST) + { + } + + return true; +} + static lv_color_t angle_to_mode_color(lv_cpicker_ext_t * ext, uint16_t angle) { lv_color_t color; @@ -393,13 +452,13 @@ static lv_color_t angle_to_mode_color(lv_cpicker_ext_t * ext, uint16_t angle) { default: case LV_CPICKER_COLOR_MODE_HUE: - color = lv_color_hsv_to_rgb(angle%360, ext->saturation, ext->value); + color = lv_color_hsv_to_rgb(angle % 360, ext->saturation, ext->value); break; case LV_CPICKER_COLOR_MODE_SATURATION: - color = lv_color_hsv_to_rgb(ext->hue, (angle%360)/360.0*100.0, ext->value); + color = lv_color_hsv_to_rgb(ext->hue, (angle % 360) / 360.0 * 100.0, ext->value); break; case LV_CPICKER_COLOR_MODE_VALUE: - color = lv_color_hsv_to_rgb(ext->hue, ext->saturation, (angle%360)/360.0*100.0); + color = lv_color_hsv_to_rgb(ext->hue, ext->saturation, (angle % 360) / 360.0 * 100.0); break; } return color; @@ -424,15 +483,39 @@ static uint16_t mode_color_to_angle(lv_cpicker_ext_t * ext) return angle; } -static void draw_disk_indicator_line(lv_cpicker_ext_t * ext, lv_style_t * style, lv_area_t * mask, lv_opa_t opa_scale, - lv_coord_t x, lv_coord_t y, uint16_t r, uint16_t angle) +static lv_coord_t lv_cpicker_get_indicator_coord(lv_style_t * style, lv_cpicker_ext_t * ext) +{ + lv_coord_t ind_pos = style->line.rounded ? ext->rect_gradient_h / 2 : 0; + switch(ext->color_mode) + { + default: + case LV_CPICKER_COLOR_MODE_HUE: + ind_pos += ext->hue / 360.0 * ext->rect_gradient_w; + break; + case LV_CPICKER_COLOR_MODE_SATURATION: + ind_pos += ext->saturation / 100.0 * ext->rect_gradient_w; + break; + case LV_CPICKER_COLOR_MODE_VALUE: + ind_pos += ext->value / 100.0 * ext->rect_gradient_w; + break; + } + return ind_pos; +} + +/** + * Should roughly match up with `lv_cpicker_invalidate_disc_indicator_line` + */ +static void lv_cpicker_draw_disc_indicator_line(lv_area_t * mask, lv_style_t * style, lv_opa_t opa_scale, + lv_cpicker_ext_t * ext, + lv_coord_t cx, lv_coord_t cy, uint16_t r, + uint16_t angle) { lv_point_t start; lv_point_t end; - start.x = x + ((r - style->line.width + ext->indicator.style->body.padding.inner + ext->indicator.style->line.width/2) * lv_trigo_sin(angle) >> LV_TRIGO_SHIFT); - start.y = y + ((r - style->line.width + ext->indicator.style->body.padding.inner + ext->indicator.style->line.width/2) * lv_trigo_sin(angle + 90) >> LV_TRIGO_SHIFT); - end.x = x + ((r - ext->indicator.style->body.padding.inner - ext->indicator.style->line.width/2) * lv_trigo_sin(angle) >> LV_TRIGO_SHIFT); - end.y = y + ((r - ext->indicator.style->body.padding.inner - ext->indicator.style->line.width/2) * lv_trigo_sin(angle + 90) >> LV_TRIGO_SHIFT); + start.x = cx + ((r - style->line.width + ext->indicator.style->body.padding.inner + ext->indicator.style->line.width/2) * lv_trigo_sin(angle) >> LV_TRIGO_SHIFT); + start.y = cy + ((r - style->line.width + ext->indicator.style->body.padding.inner + ext->indicator.style->line.width/2) * lv_trigo_sin(angle + 90) >> LV_TRIGO_SHIFT); + end.x = cx + ((r - ext->indicator.style->body.padding.inner - ext->indicator.style->line.width/2) * lv_trigo_sin(angle) >> LV_TRIGO_SHIFT); + end.y = cy + ((r - ext->indicator.style->body.padding.inner - ext->indicator.style->line.width/2) * lv_trigo_sin(angle + 90) >> LV_TRIGO_SHIFT); lv_draw_line(&start, &end, mask, ext->indicator.style, opa_scale); @@ -453,52 +536,61 @@ static void draw_disk_indicator_line(lv_cpicker_ext_t * ext, lv_style_t * style, } } -static void draw_disk_indicator_circle(lv_cpicker_ext_t * ext, lv_style_t * style, lv_area_t * mask, lv_opa_t opa_scale, - lv_coord_t x, lv_coord_t y, uint16_t r, uint16_t angle) +/** + * Should roughly match up with `lv_cpicker_invalidate_disc_indicator_circle` + */ +static void lv_cpicker_draw_disc_indicator_circle(lv_area_t * mask, lv_style_t * style, lv_opa_t opa_scale, + lv_cpicker_ext_t * ext, + lv_coord_t cx, lv_coord_t cy, uint16_t r, + uint16_t angle) { - uint32_t cx, cy; - cx = x + ((r - style->line.width/2) * lv_trigo_sin(angle) >> LV_TRIGO_SHIFT); - cy = y + ((r - style->line.width/2) * lv_trigo_sin(angle + 90) >> LV_TRIGO_SHIFT); + uint32_t ind_cx = cx + ((r - style->line.width/2) * lv_trigo_sin(angle) >> LV_TRIGO_SHIFT); + uint32_t ind_cy = cy + ((r - style->line.width/2) * lv_trigo_sin(angle + 90) >> LV_TRIGO_SHIFT); - lv_area_t circle_ind_area; - circle_ind_area.x1 = cx - style->line.width/2; - circle_ind_area.y1 = cy - style->line.width/2; - circle_ind_area.x2 = cx + style->line.width/2; - circle_ind_area.y2 = cy + style->line.width/2; + lv_area_t ind_area; + ind_area.x1 = ind_cx - style->line.width/2; + ind_area.y1 = ind_cy - style->line.width/2; + ind_area.x2 = ind_cx + style->line.width/2; + ind_area.y2 = ind_cy + style->line.width/2; lv_style_t styleCopy; lv_style_copy(&styleCopy, ext->indicator.style); styleCopy.body.radius = LV_RADIUS_CIRCLE; - lv_draw_rect(&circle_ind_area, mask, &styleCopy, opa_scale); + lv_draw_rect(&ind_area, mask, &styleCopy, opa_scale); } -static void draw_disk_indicator_in(lv_cpicker_ext_t * ext, lv_style_t * style, lv_area_t * mask, lv_opa_t opa_scale, - lv_coord_t x, lv_coord_t y, uint16_t r, uint16_t angle, - uint16_t rin) +/** + * Should roughly match up with `lv_cpicker_invalidate_disc_indicator_in` + */ +static void lv_cpicker_draw_disc_indicator_in(lv_area_t * mask, lv_style_t * style, lv_opa_t opa_scale, + lv_cpicker_ext_t * ext, + lv_coord_t cx, lv_coord_t cy, uint16_t r, + uint16_t rin, uint16_t angle) { uint16_t ind_radius = lv_sqrt((4*rin*rin)/2)/2 + 1 - style->body.padding.inner; ind_radius = (ind_radius + rin) / 2; - uint32_t cx = x + ((ind_radius) * lv_trigo_sin(angle) >> LV_TRIGO_SHIFT); - uint32_t cy = y + ((ind_radius) * lv_trigo_sin(angle + 90) >> LV_TRIGO_SHIFT); + uint32_t ind_cx = cx + ((ind_radius) * lv_trigo_sin(angle) >> LV_TRIGO_SHIFT); + uint32_t ind_cy = cy + ((ind_radius) * lv_trigo_sin(angle + 90) >> LV_TRIGO_SHIFT); - lv_area_t circle_ind_area; - circle_ind_area.x1 = cx - r; - circle_ind_area.y1 = cy - r; - circle_ind_area.x2 = cx + r; - circle_ind_area.y2 = cy + r; + lv_area_t ind_area; + ind_area.x1 = ind_cx - r; + ind_area.y1 = ind_cy - r; + ind_area.x2 = ind_cx + r; + ind_area.y2 = ind_cy + r; lv_style_t styleCopy; lv_style_copy(&styleCopy, ext->indicator.style); styleCopy.body.radius = LV_RADIUS_CIRCLE; - lv_draw_rect(&circle_ind_area, mask, &styleCopy, opa_scale); + lv_draw_rect(&ind_area, mask, &styleCopy, opa_scale); } -static void draw_disk_indicator(lv_cpicker_ext_t * ext, lv_style_t * style, lv_area_t * mask, lv_opa_t opa_scale, - lv_coord_t x, lv_coord_t y, lv_coord_t r, uint16_t angle, - uint16_t rin, uint16_t radius, lv_area_t center_ind_area) +static void lv_cpicker_draw_disc_indicator(lv_area_t * mask, lv_style_t * style, lv_opa_t opa_scale, + lv_cpicker_ext_t * ext, + lv_coord_t cx, lv_coord_t cy, lv_coord_t r, + uint16_t rin, uint16_t radius, lv_area_t center_ind_area) { /*draw center background*/ static lv_style_t styleCenterBackground; @@ -510,10 +602,10 @@ static void draw_disk_indicator(lv_cpicker_ext_t * ext, lv_style_t * style, lv_a } lv_area_t center_area; - center_area.x1 = x - rin; - center_area.y1 = y - rin; - center_area.x2 = x + rin; - center_area.y2 = y + rin; + center_area.x1 = cx - rin; + center_area.y1 = cy - rin; + center_area.x2 = cx + rin; + center_area.y2 = cy + rin; styleCenterBackground.body.radius = LV_RADIUS_CIRCLE; lv_draw_rect(¢er_area, mask, &styleCenterBackground, opa_scale); @@ -523,343 +615,248 @@ static void draw_disk_indicator(lv_cpicker_ext_t * ext, lv_style_t * style, lv_a style->body.radius = LV_RADIUS_CIRCLE; lv_draw_rect(¢er_ind_area, mask, style, opa_scale); - /*draw the current hue indicator*/ - switch(ext->indicator.type) - { - case LV_CPICKER_INDICATOR_NONE: - break; - case LV_CPICKER_INDICATOR_LINE: - { - draw_disk_indicator_line(ext, style, mask, opa_scale, x, y, r, angle); - break; - } - case LV_CPICKER_INDICATOR_CIRCLE: - { - draw_disk_indicator_circle(ext, style, mask, opa_scale, x, y, r, angle); - break; - } - case LV_CPICKER_INDICATOR_IN: - { - draw_disk_indicator_in(ext, style, mask, opa_scale, x, y, (rin - radius) / 3, angle, rin); - break; - } - } -} - -static void draw_disk_spectrum(lv_cpicker_ext_t * ext, lv_style_t * style, lv_area_t * mask, lv_opa_t opa_scale, - lv_coord_t r, lv_coord_t x, lv_coord_t y) -{ -} - -static void draw_rect_indicator_line(lv_cpicker_ext_t * ext, lv_style_t * style, lv_area_t * mask, lv_opa_t opa_scale, - lv_coord_t gradient_w, lv_coord_t gradient_h, lv_area_t gradient_area, lv_coord_t ind_pos) -{ -} - -static void draw_rect_indicator_circle(lv_cpicker_ext_t * ext, lv_style_t * style, lv_area_t * mask, lv_opa_t opa_scale, - lv_coord_t gradient_w, lv_coord_t gradient_h, lv_area_t gradient_area, lv_coord_t ind_pos) -{ -} - -static void draw_rect_indicator_in(lv_cpicker_ext_t * ext, lv_style_t * style, lv_area_t * mask, lv_opa_t opa_scale, - lv_coord_t gradient_w, lv_coord_t gradient_h, lv_area_t gradient_area, lv_coord_t ind_pos) -{ -} - -static void draw_rect_indicator(lv_cpicker_ext_t * ext, lv_style_t * style, lv_area_t * mask, lv_opa_t opa_scale, - lv_coord_t gradient_w, lv_coord_t gradient_h, lv_area_t gradient_area) -{ -} - -static void calculate_preview_area(lv_style_t * style, - lv_coord_t * gradient_w, lv_coord_t * gradient_h, lv_area_t * gradient_area, lv_area_t * preview_area, - uint16_t * style_body_padding_ver, uint16_t * style_body_padding_hor, - lv_coord_t w, lv_coord_t h, lv_coord_t x1, lv_coord_t y1, lv_coord_t x2, lv_coord_t y2) -{ -} - -static void draw_rect_spectrum(lv_cpicker_ext_t * ext, lv_style_t * style, lv_area_t * mask, lv_opa_t opa_scale, - lv_coord_t w, lv_coord_t h, lv_coord_t x1, lv_coord_t y1, lv_coord_t x2, lv_coord_t y2) -{ -} - -static void lv_cpicker_disc_design(lv_obj_t * cpicker, const lv_area_t * mask, lv_style_t * style, lv_opa_t opa_scale, - lv_cpicker_ext_t * ext, lv_coord_t w, lv_coord_t h); -static void lv_cpicker_rect_design(lv_obj_t * cpicker, const lv_area_t * mask, lv_style_t * style, lv_opa_t opa_scale, - lv_cpicker_ext_t * ext, lv_coord_t w, lv_coord_t h); - -/** - * Handle the drawing related tasks of the color_picker - * @param cpicker pointer to an object - * @param mask the object will be drawn only in this area - * @param mode LV_DESIGN_COVER_CHK: only check if the object fully covers the 'mask_p' area - * (return 'true' if yes) - * LV_DESIGN_DRAW: draw the object (always return 'true') - * LV_DESIGN_DRAW_POST: drawing after every children are drawn - * @return true/false, depends on 'mode' - */ -static bool lv_cpicker_design(lv_obj_t * cpicker, const lv_area_t * mask, lv_design_mode_t mode) -{ - /*Return false if the object is not covers the mask_p area*/ - if(mode == LV_DESIGN_COVER_CHK) { - return false; - } - /*Draw the object*/ - else if(mode == LV_DESIGN_DRAW_MAIN) { - - lv_cpicker_ext_t * ext = lv_obj_get_ext_attr(cpicker); - lv_style_t * style = lv_cpicker_get_style(cpicker, LV_CPICKER_STYLE_MAIN); - - static lv_style_t styleCopy; - lv_style_copy(&styleCopy, style); - - lv_opa_t opa_scale = lv_obj_get_opa_scale(cpicker); - - lv_coord_t w = lv_obj_get_width(cpicker); - lv_coord_t h = lv_obj_get_height(cpicker); - - if(ext->type == LV_CPICKER_TYPE_DISC) - { - lv_cpicker_disc_design(cpicker, mask, &styleCopy, opa_scale, ext, w, h); - } - else if(ext->type == LV_CPICKER_TYPE_RECT) - { - lv_cpicker_rect_design(cpicker, mask, &styleCopy, opa_scale, ext, w, h); - } - } - /*Post draw when the children are drawn*/ - else if(mode == LV_DESIGN_DRAW_POST) { - - } - - return true; -} - -static void lv_cpicker_disc_design(lv_obj_t * cpicker, const lv_area_t * mask, lv_style_t * style, lv_opa_t opa_scale, - lv_cpicker_ext_t * ext, lv_coord_t w, lv_coord_t h) -{ - lv_coord_t x = cpicker->coords.x1 + w / 2; - lv_coord_t y = cpicker->coords.y1 + h / 2; - - uint16_t r = LV_MATH_MIN(w, h) / 2; - - uint16_t rin = r - style->line.width; - //the square area (a and b being sides) should fit into the center of diameter d - //we have: - //a^2+b^2<=d^2 - //2a^2 <= d^2 - //a^2<=(d^2)/2 - //a <= sqrt((d^2)/2) - uint16_t radius = lv_sqrt((4*rin*rin)/2)/2 - style->body.padding.inner; - - lv_area_t center_ind_area; - center_ind_area.x1 = x - radius; - center_ind_area.y1 = y - radius; - center_ind_area.x2 = x + radius; - center_ind_area.y2 = y + radius; - - /*redraw the wheel only if the mask intersect with the wheel*/ - uint8_t redraw_wheel = 0; - if(mask->x1 < center_ind_area.x1 || mask->x2 > center_ind_area.x2 - || mask->y1 < center_ind_area.y1 || mask->y2 > center_ind_area.y2) - { - redraw_wheel = 1; - } - - lv_point_t triangle_points[3]; - - int16_t start_angle, end_angle; - start_angle = 0; //Default - end_angle = 360 - LV_CPICKER_DEF_QF; //Default - - if(redraw_wheel) - { - /*if the mask does not include the center of the object - * redrawing all the wheel is not necessary; - * only a given angular range - */ - lv_point_t center = {x, y}; - if(!lv_area_is_point_on(mask, ¢er) - /* - && (mask->x1 != cpicker->coords.x1 || mask->x2 != cpicker->coords.x2 - || mask->y1 != cpicker->coords.y1 || mask->y2 != cpicker->coords.y2) - */ - ) - { - /*get angle from center of object to each corners of the area*/ - int16_t dr, ur, ul, dl; - dr = lv_atan2(mask->x2 - x, mask->y2 - y); - ur = lv_atan2(mask->x2 - x, mask->y1 - y); - ul = lv_atan2(mask->x1 - x, mask->y1 - y); - dl = lv_atan2(mask->x1 - x, mask->y2 - y); - - /* check area position from object axis*/ - uint8_t left = (mask->x2 < x && mask->x1 < x); - uint8_t onYaxis = (mask->x2 > x && mask->x1 < x); - uint8_t right = (mask->x2 > x && mask->x1 > x); - uint8_t top = (mask->y2 < y && mask->y1 < y); - uint8_t onXaxis = (mask->y2 > y && mask->y1 < y); - uint8_t bottom = (mask->y2 > y && mask->y1 > x); - - /*store angular range*/ - if(right && bottom) - { - start_angle = dl; - end_angle = ur; - } - else if(right && onXaxis) - { - start_angle = dl; - end_angle = ul; - } - else if(right && top) - { - start_angle = dr; - end_angle = ul; - } - else if(onYaxis && top) - { - start_angle = dr; - end_angle = dl; - } - else if(left && top) - { - start_angle = ur; - end_angle = dl; - } - else if(left && onXaxis) - { - start_angle = ur; - end_angle = dr; - } - else if(left && bottom) - { - start_angle = ul; - end_angle = dr; - } - else if(onYaxis && bottom) - { - start_angle = ul; - end_angle = ur; - } - - /*rollover angle*/ - if(start_angle > end_angle) - { - end_angle += 360; - } - - /*round to QF factor*/ - start_angle = start_angle/LV_CPICKER_DEF_QF*LV_CPICKER_DEF_QF; - end_angle = end_angle/LV_CPICKER_DEF_QF*LV_CPICKER_DEF_QF;; - - /*shift angle if necessary before adding offset*/ - if((start_angle - LV_CPICKER_DEF_QF) < 0) - { - start_angle += 360; - end_angle += 360; - } - - /*ensure overlapping by adding offset*/ - start_angle -= LV_CPICKER_DEF_QF; - end_angle += LV_CPICKER_DEF_QF; - } - - if(ext->color_mode == LV_CPICKER_COLOR_MODE_HUE) - { - for(uint16_t i = start_angle; i <= end_angle; i+= LV_CPICKER_DEF_QF) - { - style->body.main_color = angle_to_mode_color(ext, i); - style->body.grad_color = style->body.main_color; - - triangle_points[0].x = x; - triangle_points[0].y = y; - - triangle_points[1].x = x + (r * lv_trigo_sin(i) >> LV_TRIGO_SHIFT); - triangle_points[1].y = y + (r * lv_trigo_sin(i + 90) >> LV_TRIGO_SHIFT); - - - if(i == end_angle || i == (360 - LV_CPICKER_DEF_QF)) - { - /*the last triangle is drawn without additional overlapping pixels*/ - triangle_points[2].x = x + (r * lv_trigo_sin(i + LV_CPICKER_DEF_QF) >> LV_TRIGO_SHIFT); - triangle_points[2].y = y + (r * lv_trigo_sin(i + LV_CPICKER_DEF_QF + 90) >> LV_TRIGO_SHIFT); - - } - else - { - triangle_points[2].x = x + (r * lv_trigo_sin(i + LV_CPICKER_DEF_QF + TRI_OFFSET) >> LV_TRIGO_SHIFT); - triangle_points[2].y = y + (r * lv_trigo_sin(i + LV_CPICKER_DEF_QF + TRI_OFFSET + 90) >> LV_TRIGO_SHIFT); - - } - - lv_draw_triangle(triangle_points, mask, style, LV_OPA_COVER); - } - } - else if(ext->color_mode == LV_CPICKER_COLOR_MODE_SATURATION) - { - for(uint16_t i = start_angle; i <= end_angle; i += LV_CPICKER_DEF_QF) - { - style->body.main_color = angle_to_mode_color(ext, i); - style->body.grad_color = style->body.main_color; - - triangle_points[0].x = x; - triangle_points[0].y = y; - - triangle_points[1].x = x + (r * lv_trigo_sin(i) >> LV_TRIGO_SHIFT); - triangle_points[1].y = y + (r * lv_trigo_sin(i + 90) >> LV_TRIGO_SHIFT); - - if(i == end_angle || i == (360 - LV_CPICKER_DEF_QF)) - { - /*the last triangle is drawn without additional overlapping pixels*/ - triangle_points[2].x = x + (r * lv_trigo_sin(i + LV_CPICKER_DEF_QF) >> LV_TRIGO_SHIFT); - triangle_points[2].y = y + (r * lv_trigo_sin(i + LV_CPICKER_DEF_QF + 90) >> LV_TRIGO_SHIFT); - } - else - { - triangle_points[2].x = x + (r * lv_trigo_sin(i + LV_CPICKER_DEF_QF + TRI_OFFSET) >> LV_TRIGO_SHIFT); - triangle_points[2].y = y + (r * lv_trigo_sin(i + LV_CPICKER_DEF_QF + TRI_OFFSET + 90) >> LV_TRIGO_SHIFT); - } - - lv_draw_triangle(triangle_points, mask, style, LV_OPA_COVER); - } - } - else if(ext->color_mode == LV_CPICKER_COLOR_MODE_VALUE) - { - for(uint16_t i = start_angle; i <= end_angle; i += LV_CPICKER_DEF_QF) - { - style->body.main_color = angle_to_mode_color(ext, i); - style->body.grad_color = style->body.main_color; - - triangle_points[0].x = x; - triangle_points[0].y = y; - - triangle_points[1].x = x + (r * lv_trigo_sin(i) >> LV_TRIGO_SHIFT); - triangle_points[1].y = y + (r * lv_trigo_sin(i + 90) >> LV_TRIGO_SHIFT); - - if(i == end_angle || i == (360 - LV_CPICKER_DEF_QF)) - { - /*the last triangle is drawn without additional overlapping pixels*/ - triangle_points[2].x = x + (r * lv_trigo_sin(i + LV_CPICKER_DEF_QF) >> LV_TRIGO_SHIFT); - triangle_points[2].y = y + (r * lv_trigo_sin(i + LV_CPICKER_DEF_QF + 90) >> LV_TRIGO_SHIFT); - - } - else - { - triangle_points[2].x = x + (r * lv_trigo_sin(i + LV_CPICKER_DEF_QF + TRI_OFFSET) >> LV_TRIGO_SHIFT); - triangle_points[2].y = y + (r * lv_trigo_sin(i + LV_CPICKER_DEF_QF + TRI_OFFSET + 90) >> LV_TRIGO_SHIFT); - } - - lv_draw_triangle(triangle_points, mask, style, LV_OPA_COVER); - } - } - } - uint16_t angle = mode_color_to_angle(ext); /*save the angle to refresh the area later*/ ext->prev_pos = angle; - draw_disk_indicator(ext, style, mask, opa_scale, x, y, r, angle, rin, radius, center_ind_area); + /*draw the current hue indicator*/ + switch(ext->indicator.type) + { + case LV_CPICKER_INDICATOR_NONE: + /*no indicator*/ + break; + case LV_CPICKER_INDICATOR_LINE: + lv_cpicker_draw_disc_indicator_line(mask, style, opa_scale, ext, cx, cy, r, angle); + break; + case LV_CPICKER_INDICATOR_CIRCLE: + lv_cpicker_draw_disc_indicator_circle(mask, style, opa_scale, ext, cx, cy, r, angle); + break; + case LV_CPICKER_INDICATOR_IN: + lv_cpicker_draw_disc_indicator_in(mask, style, opa_scale, ext, cx, cy, (rin - radius) / 3, rin, angle); + break; + } +} + +static void lv_cpicker_draw_disc_gradient(lv_area_t * mask, lv_style_t * style, lv_opa_t opa_scale, + lv_cpicker_ext_t * ext, + lv_coord_t cx, lv_coord_t cy, uint16_t r) +{ + int16_t start_angle = 0; /*Default*/ + int16_t end_angle = 360 - LV_CPICKER_DEF_QF; /*Default*/ + + /*if the mask does not include the center of the object + * redrawing all the wheel is not necessary; + * only a given angular range + */ + lv_point_t center = {cx, cy}; + if(!lv_area_is_point_on(mask, ¢er) + /* + && (mask->x1 != cpicker->coords.x1 || mask->x2 != cpicker->coords.x2 + || mask->y1 != cpicker->coords.y1 || mask->y2 != cpicker->coords.y2) + */ + ) + { + /*get angle from center of object to each corners of the area*/ + int16_t dr, ur, ul, dl; + dr = lv_atan2(mask->x2 - cx, mask->y2 - cy); + ur = lv_atan2(mask->x2 - cx, mask->y1 - cy); + ul = lv_atan2(mask->x1 - cx, mask->y1 - cy); + dl = lv_atan2(mask->x1 - cx, mask->y2 - cy); + + /*check area position from object axis*/ + uint8_t left = (mask->x2 < cx && mask->x1 < cx); + uint8_t onYaxis = (mask->x2 > cx && mask->x1 < cx); + uint8_t right = (mask->x2 > cx && mask->x1 > cx); + uint8_t top = (mask->y2 < cy && mask->y1 < cy); + uint8_t onXaxis = (mask->y2 > cy && mask->y1 < cy); + uint8_t bottom = (mask->y2 > cy && mask->y1 > cy); + + /*store angular range*/ + if(right && bottom) + { + start_angle = dl; + end_angle = ur; + } + else if(right && onXaxis) + { + start_angle = dl; + end_angle = ul; + } + else if(right && top) + { + start_angle = dr; + end_angle = ul; + } + else if(onYaxis && top) + { + start_angle = dr; + end_angle = dl; + } + else if(left && top) + { + start_angle = ur; + end_angle = dl; + } + else if(left && onXaxis) + { + start_angle = ur; + end_angle = dr; + } + else if(left && bottom) + { + start_angle = ul; + end_angle = dr; + } + else if(onYaxis && bottom) + { + start_angle = ul; + end_angle = ur; + } + + /*rollover angle*/ + if(start_angle > end_angle) + { + end_angle += 360; + } + + /*round to QF factor*/ + start_angle = start_angle/LV_CPICKER_DEF_QF*LV_CPICKER_DEF_QF; + end_angle = end_angle/LV_CPICKER_DEF_QF*LV_CPICKER_DEF_QF;; + + /*shift angle if necessary before adding offset*/ + if((start_angle - LV_CPICKER_DEF_QF) < 0) + { + start_angle += 360; + end_angle += 360; + } + + /*ensure overlapping by adding offset*/ + start_angle -= LV_CPICKER_DEF_QF; + end_angle += LV_CPICKER_DEF_QF; + } + + lv_point_t triangle_points[3]; + + if(ext->color_mode == LV_CPICKER_COLOR_MODE_HUE) + { + for(uint16_t i = start_angle; i <= end_angle; i+= LV_CPICKER_DEF_QF) + { + style->body.main_color = angle_to_mode_color(ext, i); + style->body.grad_color = style->body.main_color; + + triangle_points[0].x = cx; + triangle_points[0].y = cy; + + triangle_points[1].x = cx + (r * lv_trigo_sin(i) >> LV_TRIGO_SHIFT); + triangle_points[1].y = cy + (r * lv_trigo_sin(i + 90) >> LV_TRIGO_SHIFT); + + if(i == end_angle || i == (360 - LV_CPICKER_DEF_QF)) + { + /*the last triangle is drawn without additional overlapping pixels*/ + triangle_points[2].x = cx + (r * lv_trigo_sin(i + LV_CPICKER_DEF_QF) >> LV_TRIGO_SHIFT); + triangle_points[2].y = cy + (r * lv_trigo_sin(i + LV_CPICKER_DEF_QF + 90) >> LV_TRIGO_SHIFT); + } + else + { + triangle_points[2].x = cx + (r * lv_trigo_sin(i + LV_CPICKER_DEF_QF + TRI_OFFSET) >> LV_TRIGO_SHIFT); + triangle_points[2].y = cy + (r * lv_trigo_sin(i + LV_CPICKER_DEF_QF + TRI_OFFSET + 90) >> LV_TRIGO_SHIFT); + } + + lv_draw_triangle(triangle_points, mask, style, LV_OPA_COVER); + } + } + else if(ext->color_mode == LV_CPICKER_COLOR_MODE_SATURATION) + { + for(uint16_t i = start_angle; i <= end_angle; i += LV_CPICKER_DEF_QF) + { + style->body.main_color = angle_to_mode_color(ext, i); + style->body.grad_color = style->body.main_color; + + triangle_points[0].x = cx; + triangle_points[0].y = cy; + + triangle_points[1].x = cx + (r * lv_trigo_sin(i) >> LV_TRIGO_SHIFT); + triangle_points[1].y = cy + (r * lv_trigo_sin(i + 90) >> LV_TRIGO_SHIFT); + + if(i == end_angle || i == (360 - LV_CPICKER_DEF_QF)) + { + /*the last triangle is drawn without additional overlapping pixels*/ + triangle_points[2].x = cx + (r * lv_trigo_sin(i + LV_CPICKER_DEF_QF) >> LV_TRIGO_SHIFT); + triangle_points[2].y = cy + (r * lv_trigo_sin(i + LV_CPICKER_DEF_QF + 90) >> LV_TRIGO_SHIFT); + } + else + { + triangle_points[2].x = cx + (r * lv_trigo_sin(i + LV_CPICKER_DEF_QF + TRI_OFFSET) >> LV_TRIGO_SHIFT); + triangle_points[2].y = cy + (r * lv_trigo_sin(i + LV_CPICKER_DEF_QF + TRI_OFFSET + 90) >> LV_TRIGO_SHIFT); + } + + lv_draw_triangle(triangle_points, mask, style, LV_OPA_COVER); + } + } + else if(ext->color_mode == LV_CPICKER_COLOR_MODE_VALUE) + { + for(uint16_t i = start_angle; i <= end_angle; i += LV_CPICKER_DEF_QF) + { + style->body.main_color = angle_to_mode_color(ext, i); + style->body.grad_color = style->body.main_color; + + triangle_points[0].x = cx; + triangle_points[0].y = cy; + + triangle_points[1].x = cx + (r * lv_trigo_sin(i) >> LV_TRIGO_SHIFT); + triangle_points[1].y = cy + (r * lv_trigo_sin(i + 90) >> LV_TRIGO_SHIFT); + + if(i == end_angle || i == (360 - LV_CPICKER_DEF_QF)) + { + /*the last triangle is drawn without additional overlapping pixels*/ + triangle_points[2].x = cx + (r * lv_trigo_sin(i + LV_CPICKER_DEF_QF) >> LV_TRIGO_SHIFT); + triangle_points[2].y = cy + (r * lv_trigo_sin(i + LV_CPICKER_DEF_QF + 90) >> LV_TRIGO_SHIFT); + } + else + { + triangle_points[2].x = cx + (r * lv_trigo_sin(i + LV_CPICKER_DEF_QF + TRI_OFFSET) >> LV_TRIGO_SHIFT); + triangle_points[2].y = cy + (r * lv_trigo_sin(i + LV_CPICKER_DEF_QF + TRI_OFFSET + 90) >> LV_TRIGO_SHIFT); + } + + lv_draw_triangle(triangle_points, mask, style, LV_OPA_COVER); + } + } +} + +/** + * Should roughly match up with `lv_cpicker_invalidate_disc` + */ +static void lv_cpicker_disc_design(lv_obj_t * cpicker, + lv_area_t * mask, lv_style_t * style, lv_opa_t opa_scale, + lv_cpicker_ext_t * ext, + lv_coord_t w, lv_coord_t h, + lv_coord_t cx, lv_coord_t cy, uint16_t r) +{ + uint16_t rin = r - style->line.width; + /* + the square area (a and b being sides) should fit into the center of diameter d + we have: + a^2+b^2<=d^2 + 2a^2 <= d^2 + a^2<=(d^2)/2 + a <= sqrt((d^2)/2) + */ + uint16_t radius = lv_sqrt((4*rin*rin)/2)/2 - style->body.padding.inner; + + lv_area_t center_ind_area; + center_ind_area.x1 = cx - radius; + center_ind_area.y1 = cy - radius; + center_ind_area.x2 = cx + radius; + center_ind_area.y2 = cy + radius; + + /*redraw the wheel only if the mask intersect with the wheel*/ + if(mask->x1 < center_ind_area.x1 || mask->x2 > center_ind_area.x2 + || mask->y1 < center_ind_area.y1 || mask->y2 > center_ind_area.y2) + { + lv_cpicker_draw_disc_gradient(mask, style, opa_scale, ext, cx, cy, r); + } + + lv_cpicker_draw_disc_indicator(mask, style, opa_scale, ext, cx, cy, r, rin, radius, center_ind_area); /* //code to color the drawn area @@ -870,11 +867,13 @@ static void lv_cpicker_disc_design(lv_obj_t * cpicker, const lv_area_t * mask, l style2.body.grad_color.full = c; c += 0x123445678; lv_draw_rect(mask, mask, &style2, opa_scale); - */ + */ } -static void lv_cpicker_rect_design(lv_obj_t * cpicker, const lv_area_t * mask, lv_style_t * style, lv_opa_t opa_scale, - lv_cpicker_ext_t * ext, lv_coord_t w, lv_coord_t h) +static uint16_t lv_cpicker_calculate_rect_preview_area(lv_obj_t * cpicker, + lv_style_t * style, + lv_cpicker_ext_t * ext, + lv_coord_t w) { lv_coord_t x1 = cpicker->coords.x1; lv_coord_t y1 = cpicker->coords.y1; @@ -954,6 +953,116 @@ static void lv_cpicker_rect_design(lv_obj_t * cpicker, const lv_area_t * mask, l } } + return style_body_padding_hor; +} + +/** + * Should roughly match up with `lv_cpicker_invalidate_rect_indicator_line` + */ +static void lv_cpicker_draw_rect_indicator_line(lv_area_t * mask, lv_opa_t opa_scale, + lv_cpicker_ext_t * ext, lv_coord_t ind_pos) +{ + lv_point_t p1, p2; + p1.x = ext->rect_gradient_area.x1 + ind_pos; + p1.y = ext->rect_gradient_area.y1; + p2.x = p1.x; + p2.y = ext->rect_gradient_area.y2; + + lv_draw_line(&p1, &p2, mask, ext->indicator.style, opa_scale); +} + +/** + * Should roughly match up with `lv_cpicker_invalidate_rect_indicator_circle` + */ +static void lv_cpicker_draw_rect_indicator_circle(lv_area_t * mask, lv_opa_t opa_scale, + lv_cpicker_ext_t * ext, lv_coord_t ind_pos) +{ + lv_area_t circle_ind_area; + circle_ind_area.x1 = ext->rect_gradient_area.x1 + ind_pos - ext->rect_gradient_h/2; + circle_ind_area.x2 = circle_ind_area.x1 + ext->rect_gradient_h; + circle_ind_area.y1 = ext->rect_gradient_area.y1; + circle_ind_area.y2 = ext->rect_gradient_area.y2; + + lv_style_t styleCopy; + lv_style_copy(&styleCopy, ext->indicator.style); + styleCopy.body.radius = LV_RADIUS_CIRCLE; + + lv_draw_rect(&circle_ind_area, mask, &styleCopy, opa_scale); +} + +/** + * Should roughly match up with `lv_cpicker_invalidate_rect_indicator_in` + */ +static void lv_cpicker_draw_rect_indicator_in(lv_area_t * mask, lv_opa_t opa_scale, + lv_cpicker_ext_t * ext, lv_coord_t ind_pos) +{ + /*draw triangle at top and bottom of gradient*/ + lv_point_t triangle_points[3]; + + triangle_points[0].x = ext->rect_gradient_area.x1 + ind_pos; + triangle_points[0].y = ext->rect_gradient_area.y1 + (ext->rect_gradient_h/3); + + triangle_points[1].x = triangle_points[0].x - ext->indicator.style->line.width * 3; + triangle_points[1].y = ext->rect_gradient_area.y1 - 1; + + triangle_points[2].x = triangle_points[0].x + ext->indicator.style->line.width * 3; + triangle_points[2].y = triangle_points[1].y; + + lv_draw_triangle(triangle_points, mask, ext->indicator.style, LV_OPA_COVER); + + triangle_points[0].y = ext->rect_gradient_area.y2 - (ext->rect_gradient_h/3); + triangle_points[1].y = ext->rect_gradient_area.y2; + triangle_points[2].y = triangle_points[1].y; + lv_draw_triangle(triangle_points, mask, ext->indicator.style, LV_OPA_COVER); +} + +static void lv_cpicker_draw_rect_indicator(lv_obj_t * cpicker, + lv_area_t * mask, lv_style_t * style, lv_opa_t opa_scale, + lv_cpicker_ext_t * ext, + uint16_t style_body_padding_hor) +{ + /*draw the color preview indicator*/ + style->body.main_color = lv_cpicker_get_color(cpicker); + style->body.grad_color = style->body.main_color; + if(style->line.rounded && style_body_padding_hor == 0) + { + style->body.radius = ext->rect_gradient_h; + } + lv_draw_rect(&(ext->rect_preview_area), mask, style, opa_scale); + + /* + styleCopy.line.width = 10; + lv_draw_arc(cpicker->coords.x1 + 3*ext->rect_gradient_h/2, cpicker->coords.y1 + ext->rect_gradient_h/2, ext->rect_gradient_h / 2 + styleCopy.line.width + 2, mask, 180, 360, &styleCopy, opa_scale); + //lv_draw_arc(cpicker->coords.x1 + ext->rect_gradient_w - ext->rect_gradient_h/2, cpicker->coords.y1 + ext->rect_gradient_h/2, ext->rect_gradient_h / 2 + styleCopy.line.width + 2, mask, 0, 180, &styleCopy, opa_scale); + */ + + /*draw the color position indicator*/ + lv_coord_t ind_pos = lv_cpicker_get_indicator_coord(style, ext); + /*save to refresh the area later*/ + ext->prev_pos = ind_pos; + + switch(ext->indicator.type) + { + case LV_CPICKER_INDICATOR_NONE: + /*no indicator*/ + break; + case LV_CPICKER_INDICATOR_LINE: + lv_cpicker_draw_rect_indicator_line(mask, opa_scale, ext, ind_pos); + break; + case LV_CPICKER_INDICATOR_CIRCLE: + lv_cpicker_draw_rect_indicator_circle(mask, opa_scale, ext, ind_pos); + break; + case LV_CPICKER_INDICATOR_IN: + lv_cpicker_draw_rect_indicator_in(mask, opa_scale, ext, ind_pos); + break; + default: + break; + } +} + +static void lv_cpicker_draw_rect_gradient(lv_area_t * mask, lv_style_t * style, lv_opa_t opa_scale, + lv_cpicker_ext_t * ext) +{ if(style->line.rounded) { /*draw rounded edges to the gradient*/ @@ -1014,101 +1123,31 @@ static void lv_cpicker_rect_design(lv_obj_t * cpicker, const lv_area_t * mask, l ext->rect_gradient_area.x2 += ext->rect_gradient_h/2; //ext->rect_gradient_w += ext->rect_gradient_h; } +} - /*draw the color preview indicator*/ - style->body.main_color = lv_cpicker_get_color(cpicker); - style->body.grad_color = style->body.main_color; - if(style->line.rounded && style_body_padding_hor == 0) - { - style->body.radius = ext->rect_gradient_h; - } - lv_draw_rect(&(ext->rect_preview_area), mask, style, opa_scale); +/** + * Should roughly match up with `lv_cpicker_invalidate_rect` + */ +static void lv_cpicker_rect_design(lv_obj_t * cpicker, + lv_area_t * mask, lv_style_t * style, lv_opa_t opa_scale, + lv_cpicker_ext_t * ext, + lv_coord_t w, lv_coord_t h) +{ + uint16_t style_body_padding_hor = lv_cpicker_calculate_rect_preview_area(cpicker, style, ext, w); - /* - styleCopy.line.width = 10; - lv_draw_arc(cpicker->coords.x1 + 3*ext->rect_gradient_h/2, cpicker->coords.y1 + ext->rect_gradient_h/2, ext->rect_gradient_h / 2 + styleCopy.line.width + 2, mask, 180, 360, &styleCopy, opa_scale); - //lv_draw_arc(cpicker->coords.x1 + ext->rect_gradient_w - ext->rect_gradient_h/2, cpicker->coords.y1 + ext->rect_gradient_h/2, ext->rect_gradient_h / 2 + styleCopy.line.width + 2, mask, 0, 180, &styleCopy, opa_scale); - */ + lv_cpicker_draw_rect_gradient(mask, style, opa_scale, ext); - /*draw the color position indicator*/ - lv_coord_t ind_pos = style->line.rounded ? ext->rect_gradient_h / 2 : 0; - switch(ext->color_mode) - { - default: - case LV_CPICKER_COLOR_MODE_HUE: - ind_pos += ext->hue * ext->rect_gradient_w / 360.0; - break; - case LV_CPICKER_COLOR_MODE_SATURATION: - ind_pos += ext->saturation * ext->rect_gradient_w / 100.0; - break; - case LV_CPICKER_COLOR_MODE_VALUE: - ind_pos += ext->value * ext->rect_gradient_w / 100.0; - break; - } - - /*save to refresh the area later*/ - ext->prev_pos = ind_pos; - - switch(ext->indicator.type) - { - case LV_CPICKER_INDICATOR_NONE: - /*no indicator*/ - break; - case LV_CPICKER_INDICATOR_LINE: - { - lv_point_t p1, p2; - p1.x = ext->rect_gradient_area.x1 + ind_pos; - p1.y = ext->rect_gradient_area.y1; - p2.x = p1.x; - p2.y = ext->rect_gradient_area.y2; - - lv_draw_line(&p1, &p2, mask, ext->indicator.style, opa_scale); - break; - } - case LV_CPICKER_INDICATOR_CIRCLE: - { - lv_area_t circle_ind_area; - circle_ind_area.x1 = ext->rect_gradient_area.x1 + ind_pos - ext->rect_gradient_h/2; - circle_ind_area.x2 = circle_ind_area.x1 + ext->rect_gradient_h; - circle_ind_area.y1 = ext->rect_gradient_area.y1; - circle_ind_area.y2 = ext->rect_gradient_area.y2; - - lv_style_copy(style, ext->indicator.style); - style->body.radius = LV_RADIUS_CIRCLE; - - lv_draw_rect(&circle_ind_area, mask, style, opa_scale); - break; - } - case LV_CPICKER_INDICATOR_IN: - { - /*draw triangle under the gradient*/ - lv_point_t triangle_points[3]; - - triangle_points[0].x = ext->rect_gradient_area.x1 + ind_pos; - triangle_points[0].y = ext->rect_gradient_area.y1 + (ext->rect_gradient_h/3); - - triangle_points[1].x = triangle_points[0].x - ext->indicator.style->line.width * 3; - triangle_points[1].y = ext->rect_gradient_area.y1 - 1; - - triangle_points[2].x = triangle_points[0].x + ext->indicator.style->line.width * 3; - triangle_points[2].y = triangle_points[1].y; - - lv_draw_triangle(triangle_points, mask, ext->indicator.style, LV_OPA_COVER); - - triangle_points[0].y = ext->rect_gradient_area.y2 - (ext->rect_gradient_h/3); - triangle_points[1].y = ext->rect_gradient_area.y2; - triangle_points[2].y = triangle_points[1].y; - lv_draw_triangle(triangle_points, mask, ext->indicator.style, LV_OPA_COVER); - break; - } - default: - break; - } + lv_cpicker_draw_rect_indicator(cpicker, mask, style, opa_scale, ext, style_body_padding_hor); } -static lv_res_t lv_cpicker_disc_signal(lv_obj_t * cpicker, lv_signal_t sign, void * param); -static lv_res_t lv_cpicker_rect_signal(lv_obj_t * cpicker, lv_signal_t sign, void * param); +static void lv_cpicker_invalidate(lv_obj_t * cpicker, bool all); + +static lv_res_t lv_cpicker_disc_signal(lv_obj_t * cpicker, lv_signal_t sign, void * param, + lv_style_t * style, lv_cpicker_ext_t * ext, + lv_coord_t r_out, lv_coord_t r_in, lv_coord_t x, lv_coord_t y); +static lv_res_t lv_cpicker_rect_signal(lv_obj_t * cpicker, lv_signal_t sign, void * param, + lv_style_t * style, lv_cpicker_ext_t * ext); /** * Signal function of the color_picker @@ -1134,173 +1173,290 @@ static lv_res_t lv_cpicker_signal(lv_obj_t * cpicker, lv_signal_t sign, void * p buf->type[i] = "lv_cpicker"; } else { lv_cpicker_ext_t * ext = lv_obj_get_ext_attr(cpicker); - lv_style_t * style = lv_cpicker_get_style(cpicker, LV_CPICKER_STYLE_MAIN); - if(ext->type == LV_CPICKER_TYPE_DISC) - { - res = lv_cpicker_disc_signal(cpicker, sign, param); - if(res != LV_RES_OK) return res; - } - else if(ext->type == LV_CPICKER_TYPE_RECT) - { - res = lv_cpicker_rect_signal(cpicker, sign, param); - if(res != LV_RES_OK) return res; + if(sign == LV_SIGNAL_CONTROL) { + uint32_t c = *((uint32_t *)param); /*uint32_t because can be UTF-8*/ + if(c == LV_KEY_RIGHT) + { + switch(ext->color_mode) + { + case LV_CPICKER_COLOR_MODE_HUE: + ext->hue = (ext->hue + 1) % 360; + break; + case LV_CPICKER_COLOR_MODE_SATURATION: + ext->saturation = (ext->saturation + 1) % 100; + break; + case LV_CPICKER_COLOR_MODE_VALUE: + ext->value = (ext->value + 1) % 100; + break; + } + + lv_cpicker_invalidate(cpicker, false); + + res = lv_event_send(cpicker, LV_EVENT_VALUE_CHANGED, NULL); + if(res != LV_RES_OK) return res; + } + else if(c == LV_KEY_LEFT) + { + switch(ext->color_mode) + { + case LV_CPICKER_COLOR_MODE_HUE: + ext->hue = ext->hue > 0?(ext->hue - 1):360; + break; + case LV_CPICKER_COLOR_MODE_SATURATION: + ext->saturation = ext->saturation > 0?(ext->saturation - 1):100; + break; + case LV_CPICKER_COLOR_MODE_VALUE: + ext->value = ext->value > 0?(ext->value - 1):100; + break; + } + + lv_cpicker_invalidate(cpicker, false); + + res = lv_event_send(cpicker, LV_EVENT_VALUE_CHANGED, NULL); + if(res != LV_RES_OK) return res; + } + else if(c == LV_KEY_UP) + { + switch(ext->color_mode) + { + case LV_CPICKER_COLOR_MODE_HUE: + ext->hue = (ext->hue + 1) % 360; + break; + case LV_CPICKER_COLOR_MODE_SATURATION: + ext->saturation = (ext->saturation + 1) % 100; + break; + case LV_CPICKER_COLOR_MODE_VALUE: + ext->value = (ext->value + 1) % 100; + break; + } + + lv_cpicker_invalidate(cpicker, false); + + res = lv_event_send(cpicker, LV_EVENT_VALUE_CHANGED, NULL); + if(res != LV_RES_OK) return res; + } + else if(c == LV_KEY_DOWN) + { + switch(ext->color_mode) + { + case LV_CPICKER_COLOR_MODE_HUE: + ext->hue = ext->hue > 0?(ext->hue - 1):360; + break; + case LV_CPICKER_COLOR_MODE_SATURATION: + ext->saturation = ext->saturation > 0?(ext->saturation - 1):100; + break; + case LV_CPICKER_COLOR_MODE_VALUE: + ext->value = ext->value > 0?(ext->value - 1):100; + break; + } + + lv_cpicker_invalidate(cpicker, false); + + res = lv_event_send(cpicker, LV_EVENT_VALUE_CHANGED, NULL); + if(res != LV_RES_OK) return res; + } + } else { + lv_style_t * style = lv_cpicker_get_style(cpicker, LV_CPICKER_STYLE_MAIN); + + if(ext->type == LV_CPICKER_TYPE_DISC) + { + lv_coord_t r_out = (LV_MATH_MIN(lv_obj_get_width(cpicker), lv_obj_get_height(cpicker))) / 2; + lv_coord_t r_in = r_out - style->line.width - style->body.padding.inner; + lv_coord_t x = cpicker->coords.x1 + lv_obj_get_width(cpicker) / 2; + lv_coord_t y = cpicker->coords.y1 + lv_obj_get_height(cpicker) / 2; + res = lv_cpicker_disc_signal(cpicker, sign, param, style, ext, r_out, r_in, x, y); + if(res != LV_RES_OK) return res; + } + else if(ext->type == LV_CPICKER_TYPE_RECT) + { + res = lv_cpicker_rect_signal(cpicker, sign, param, style, ext); + if(res != LV_RES_OK) return res; + } } } return res; } -static lv_res_t lv_cpicker_disc_signal(lv_obj_t * cpicker, lv_signal_t sign, void * param) +static void lv_cpicker_prev_hsv_save(lv_cpicker_ext_t * ext) { - lv_cpicker_ext_t * ext = lv_obj_get_ext_attr(cpicker); + switch(ext->color_mode) + { + case LV_CPICKER_COLOR_MODE_HUE: + ext->prev_hue = ext->hue; + break; + case LV_CPICKER_COLOR_MODE_SATURATION: + ext->prev_saturation = ext->saturation; + break; + case LV_CPICKER_COLOR_MODE_VALUE: + ext->prev_value = ext->value; + break; + } +} - lv_res_t res; +static void lv_cpicker_prev_hsv_restore(lv_obj_t * cpicker, + lv_cpicker_ext_t * ext) +{ + switch(ext->color_mode) + { + case LV_CPICKER_COLOR_MODE_HUE: + ext->prev_hue = ext->hue; + break; + case LV_CPICKER_COLOR_MODE_SATURATION: + ext->prev_saturation = ext->saturation; + break; + case LV_CPICKER_COLOR_MODE_VALUE: + ext->prev_value = ext->value; + break; + } + lv_cpicker_invalidate(cpicker, false); +} - lv_style_t * style = lv_cpicker_get_style(cpicker, LV_CPICKER_STYLE_MAIN); - - lv_coord_t r_out = (LV_MATH_MIN(lv_obj_get_width(cpicker), lv_obj_get_height(cpicker))) / 2; - lv_coord_t r_in = r_out - style->line.width - style->body.padding.inner; - - lv_coord_t x = cpicker->coords.x1 + lv_obj_get_width(cpicker) / 2; - lv_coord_t y = cpicker->coords.y1 + lv_obj_get_height(cpicker) / 2; - - if(sign == LV_SIGNAL_PRESSED) - { - switch(ext->color_mode) - { - case LV_CPICKER_COLOR_MODE_HUE: - ext->prev_hue = ext->hue; - break; - case LV_CPICKER_COLOR_MODE_SATURATION: - ext->prev_saturation = ext->saturation; - break; - case LV_CPICKER_COLOR_MODE_VALUE: - ext->prev_value = ext->value; - break; - } - - lv_indev_t * indev = param; - lv_coord_t xp = indev->proc.types.pointer.act_point.x - x; - lv_coord_t yp = indev->proc.types.pointer.act_point.y - y; - - if((xp*xp + yp*yp) < (r_in*r_in)) - { - if(lv_tick_elaps(ext->last_click) < 400) - { - switch(ext->color_mode) - { - case LV_CPICKER_COLOR_MODE_HUE: - ext->hue = 0; - ext->prev_hue = ext->hue; - break; - case LV_CPICKER_COLOR_MODE_SATURATION: - ext->saturation = 100; - ext->prev_saturation = ext->saturation; - break; - case LV_CPICKER_COLOR_MODE_VALUE: - ext->value = 100; - ext->prev_value = ext->value; - break; - } - //lv_cpicker_invalidate(cpicker, false); - } - ext->last_click = lv_tick_get(); - } - } - else if(sign == LV_SIGNAL_PRESSING) - { - lv_indev_t * indev = param; - lv_coord_t xp = indev->proc.types.pointer.act_point.x - x; - lv_coord_t yp = indev->proc.types.pointer.act_point.y - y; - - if((xp*xp + yp*yp) < (r_out*r_out) && (xp*xp + yp*yp) >= (r_in*r_in)) - { - bool changed = false; - uint16_t hsv; - switch(ext->color_mode) - { - case LV_CPICKER_COLOR_MODE_HUE: - hsv = lv_atan2(xp, yp); - changed = hsv != ext->hue; - if (changed) - { - ext->hue = hsv; - ext->prev_hue = ext->hue; - } - break; - case LV_CPICKER_COLOR_MODE_SATURATION: - hsv = lv_atan2(xp, yp) * 100.0 / 360.0; - changed = hsv != ext->hue; - if (changed) - { - ext->saturation = hsv; - ext->prev_saturation = ext->saturation; - } - break; - case LV_CPICKER_COLOR_MODE_VALUE: - hsv = lv_atan2(xp, yp) * 100.0 / 360.0; - changed = hsv != ext->hue; - if (changed) - { - ext->value = hsv; - ext->prev_value = ext->value; - } - break; - } - - if (changed) - { - lv_cpicker_invalidate(cpicker, false); - - res = lv_event_send(cpicker, LV_EVENT_VALUE_CHANGED, NULL); - if(res != LV_RES_OK) return res; - } - } - } - else if(sign == LV_SIGNAL_PRESS_LOST) +static void lv_cpicker_reset_hsv_if_double_clicked(lv_obj_t * cpicker, + lv_cpicker_ext_t * ext) +{ + if(lv_tick_elaps(ext->last_click) < 400) { switch(ext->color_mode) { case LV_CPICKER_COLOR_MODE_HUE: + ext->hue = 0; ext->prev_hue = ext->hue; break; case LV_CPICKER_COLOR_MODE_SATURATION: + ext->saturation = 100; ext->prev_saturation = ext->saturation; break; case LV_CPICKER_COLOR_MODE_VALUE: + ext->value = 100; ext->prev_value = ext->value; break; } lv_cpicker_invalidate(cpicker, false); } + ext->last_click = lv_tick_get(); +} + +static void lv_cpicker_set_next_color_mode(lv_obj_t * cpicker, + lv_cpicker_ext_t * ext) +{ + switch(ext->color_mode) + { + case LV_CPICKER_COLOR_MODE_HUE: + ext->prev_hue = ext->hue; + break; + case LV_CPICKER_COLOR_MODE_SATURATION: + ext->prev_saturation = ext->saturation; + break; + case LV_CPICKER_COLOR_MODE_VALUE: + ext->prev_value = ext->value; + break; + } + + ext->color_mode = (ext->color_mode + 1) % 3; + + lv_cpicker_invalidate(cpicker, true); +} + +static lv_res_t lv_cpicker_set_hsv_percent(lv_obj_t * cpicker, + lv_cpicker_ext_t * ext, + float percent) +{ + lv_res_t res; + + bool changed = false; + uint16_t hsv; + switch(ext->color_mode) + { + case LV_CPICKER_COLOR_MODE_HUE: + hsv = percent * 360.0; + changed = hsv != ext->hue; + if (changed) + { + ext->hue = hsv; + ext->prev_hue = ext->hue; + } + break; + case LV_CPICKER_COLOR_MODE_SATURATION: + hsv = percent * 100.0; + changed = hsv != ext->saturation; + if (changed) + { + ext->saturation = hsv; + ext->prev_saturation = ext->saturation; + } + break; + case LV_CPICKER_COLOR_MODE_VALUE: + hsv = percent * 100.0; + changed = hsv != ext->value; + if (changed) + { + ext->value = hsv; + ext->prev_value = ext->value; + } + break; + } + + if (changed) + { + lv_cpicker_invalidate(cpicker, false); + + res = lv_event_send(cpicker, LV_EVENT_VALUE_CHANGED, NULL); + if(res != LV_RES_OK) return res; + } + + return res; +} + +static lv_res_t lv_cpicker_disc_signal(lv_obj_t * cpicker, lv_signal_t sign, void * param, + lv_style_t * style, lv_cpicker_ext_t * ext, + lv_coord_t r_out, lv_coord_t r_in, lv_coord_t x, lv_coord_t y) +{ + lv_res_t res; + + if(sign == LV_SIGNAL_PRESSED) + { + lv_cpicker_prev_hsv_save(ext); + + lv_indev_t * indev = param; + + lv_coord_t xp = indev->proc.types.pointer.act_point.x - x; + lv_coord_t yp = indev->proc.types.pointer.act_point.y - y; + if((xp*xp + yp*yp) < (r_in*r_in)) + { + lv_cpicker_reset_hsv_if_double_clicked(cpicker, ext); + } + } + else if(sign == LV_SIGNAL_PRESSING) + { + lv_indev_t * indev = param; + + lv_coord_t xp = indev->proc.types.pointer.act_point.x - x; + lv_coord_t yp = indev->proc.types.pointer.act_point.y - y; + if((xp*xp + yp*yp) < (r_out*r_out) && (xp*xp + yp*yp) >= (r_in*r_in)) + { + float percent = lv_atan2(xp, yp) / 360.0; + + res = lv_cpicker_set_hsv_percent(cpicker, ext, percent); + if(res != LV_RES_OK) return res; + } + } + else if(sign == LV_SIGNAL_PRESS_LOST) + { + lv_cpicker_prev_hsv_restore(cpicker, ext); + } else if(sign == LV_SIGNAL_RELEASED) { lv_indev_t * indev = param; + lv_coord_t xp = indev->proc.types.pointer.act_point.x - x; lv_coord_t yp = indev->proc.types.pointer.act_point.y - y; - if((xp*xp + yp*yp) < (r_out*r_out) && (xp*xp + yp*yp) >= (r_in*r_in)) { - switch(ext->color_mode) - { - case LV_CPICKER_COLOR_MODE_HUE: - ext->hue = lv_atan2(xp, yp); - ext->prev_hue = ext->hue; - break; - case LV_CPICKER_COLOR_MODE_SATURATION: - ext->saturation = lv_atan2(xp, yp) * 100.0 / 360.0; - ext->prev_saturation = ext->saturation; - break; - case LV_CPICKER_COLOR_MODE_VALUE: - ext->value = lv_atan2(xp, yp) * 100.0 / 360.0; - ext->prev_value = ext->value; - break; - } + float percent = lv_atan2(xp, yp) / 360.0; - lv_cpicker_invalidate(cpicker, false); - - res = lv_event_send(cpicker, LV_EVENT_VALUE_CHANGED, NULL); + res = lv_cpicker_set_hsv_percent(cpicker, ext, percent); if(res != LV_RES_OK) return res; } } @@ -1309,172 +1465,33 @@ static lv_res_t lv_cpicker_disc_signal(lv_obj_t * cpicker, lv_signal_t sign, voi if(!ext->color_mode_fixed) { lv_indev_t * indev = param; + lv_coord_t xp = indev->proc.types.pointer.act_point.x - x; lv_coord_t yp = indev->proc.types.pointer.act_point.y - y; - if((xp*xp + yp*yp) < (r_in*r_in)) { - switch(ext->color_mode) - { - case LV_CPICKER_COLOR_MODE_HUE: - ext->prev_hue = ext->hue; - break; - case LV_CPICKER_COLOR_MODE_SATURATION: - ext->prev_saturation = ext->saturation; - break; - case LV_CPICKER_COLOR_MODE_VALUE: - ext->prev_value = ext->value; - break; - } - - ext->color_mode = (ext->color_mode + 1) % 3; - - lv_cpicker_invalidate(cpicker, true); + lv_cpicker_set_next_color_mode(cpicker, ext); } } } - else if(sign == LV_SIGNAL_CONTROL) - { - uint32_t c = *((uint32_t *)param); /*uint32_t because can be UTF-8*/ - if(c == LV_KEY_RIGHT) - { - switch(ext->color_mode) - { - case LV_CPICKER_COLOR_MODE_HUE: - ext->hue = (ext->hue + 1) % 360; - break; - case LV_CPICKER_COLOR_MODE_SATURATION: - ext->saturation = (ext->saturation + 1) % 100; - break; - case LV_CPICKER_COLOR_MODE_VALUE: - ext->value = (ext->value + 1) % 100; - break; - } - - lv_cpicker_invalidate(cpicker, false); - - res = lv_event_send(cpicker, LV_EVENT_VALUE_CHANGED, NULL); - if(res != LV_RES_OK) return res; - } - else if(c == LV_KEY_LEFT) - { - switch(ext->color_mode) - { - case LV_CPICKER_COLOR_MODE_HUE: - ext->hue = ext->hue > 0?(ext->hue - 1):360; - break; - case LV_CPICKER_COLOR_MODE_SATURATION: - ext->saturation = ext->saturation > 0?(ext->saturation - 1):100; - break; - case LV_CPICKER_COLOR_MODE_VALUE: - ext->value = ext->value > 0?(ext->value - 1):100; - break; - } - - lv_cpicker_invalidate(cpicker, false); - - res = lv_event_send(cpicker, LV_EVENT_VALUE_CHANGED, NULL); - if(res != LV_RES_OK) return res; - } - else if(c == LV_KEY_UP) - { - switch(ext->color_mode) - { - case LV_CPICKER_COLOR_MODE_HUE: - ext->hue = (ext->hue + 1) % 360; - break; - case LV_CPICKER_COLOR_MODE_SATURATION: - ext->saturation = (ext->saturation + 1) % 100; - break; - case LV_CPICKER_COLOR_MODE_VALUE: - ext->value = (ext->value + 1) % 100; - break; - } - - lv_cpicker_invalidate(cpicker, false); - - res = lv_event_send(cpicker, LV_EVENT_VALUE_CHANGED, NULL); - if(res != LV_RES_OK) return res; - } - else if(c == LV_KEY_DOWN) - { - switch(ext->color_mode) - { - case LV_CPICKER_COLOR_MODE_HUE: - ext->hue = ext->hue > 0?(ext->hue - 1):360; - break; - case LV_CPICKER_COLOR_MODE_SATURATION: - ext->saturation = ext->saturation > 0?(ext->saturation - 1):100; - break; - case LV_CPICKER_COLOR_MODE_VALUE: - ext->value = ext->value > 0?(ext->value - 1):100; - break; - } - - lv_cpicker_invalidate(cpicker, false); - - res = lv_event_send(cpicker, LV_EVENT_VALUE_CHANGED, NULL); - if(res != LV_RES_OK) return res; - } - } return res; } -/** - * Signal function of the color_picker of rectangle type - * @param cpicker pointer to a color_picker object - * @param sign a signal type from lv_signal_t enum - * @param param pointer to a signal specific variable - * @return LV_RES_OK: the object is not deleted in the function; LV_RES_INV: the object is deleted - */ -static lv_res_t lv_cpicker_rect_signal(lv_obj_t * cpicker, lv_signal_t sign, void * param) +static lv_res_t lv_cpicker_rect_signal(lv_obj_t * cpicker, lv_signal_t sign, void * param, + lv_style_t * style, lv_cpicker_ext_t * ext) { - lv_cpicker_ext_t * ext = lv_obj_get_ext_attr(cpicker); - lv_res_t res; - lv_style_t * style = lv_cpicker_get_style(cpicker, LV_CPICKER_STYLE_MAIN); - if(sign == LV_SIGNAL_PRESSED) { - switch(ext->color_mode) - { - case LV_CPICKER_COLOR_MODE_HUE: - ext->prev_hue = ext->hue; - break; - case LV_CPICKER_COLOR_MODE_SATURATION: - ext->prev_saturation = ext->saturation; - break; - case LV_CPICKER_COLOR_MODE_VALUE: - ext->prev_value = ext->value; - break; - } + lv_cpicker_prev_hsv_save(ext); lv_indev_t * indev = param; if(lv_area_is_point_on(&(ext->rect_preview_area), &indev->proc.types.pointer.act_point)) { - if(lv_tick_elaps(ext->last_click) < 400) - { - switch(ext->color_mode) - { - case LV_CPICKER_COLOR_MODE_HUE: - ext->hue = 0; - ext->prev_hue = ext->hue; - break; - case LV_CPICKER_COLOR_MODE_SATURATION: - ext->saturation = 100; - ext->prev_saturation = ext->saturation; - break; - case LV_CPICKER_COLOR_MODE_VALUE: - ext->value = 100; - ext->prev_value = ext->value; - break; - } - //lv_cpicker_invalidate(cpicker, false); - } - ext->last_click = lv_tick_get(); + lv_cpicker_reset_hsv_if_double_clicked(cpicker, ext); } } else if(sign == LV_SIGNAL_PRESSING) @@ -1486,43 +1503,14 @@ static lv_res_t lv_cpicker_rect_signal(lv_obj_t * cpicker, lv_signal_t sign, voi uint16_t width = ext->rect_gradient_area.x2 - ext->rect_gradient_area.x1; uint16_t distance = indev->proc.types.pointer.act_point.x - ext->rect_gradient_area.x1; float percent = distance / (float) width; - switch(ext->color_mode) - { - case LV_CPICKER_COLOR_MODE_HUE: - ext->hue = percent * 360.0; - ext->prev_hue = ext->hue; - break; - case LV_CPICKER_COLOR_MODE_SATURATION: - ext->saturation = percent * 100.0; - ext->prev_saturation = ext->saturation; - break; - case LV_CPICKER_COLOR_MODE_VALUE: - ext->value = percent * 100.0; - ext->prev_value = ext->value; - break; - } - lv_cpicker_invalidate(cpicker, false); - - res = lv_event_send(cpicker, LV_EVENT_VALUE_CHANGED, NULL); + res = lv_cpicker_set_hsv_percent(cpicker, ext, percent); if(res != LV_RES_OK) return res; } } else if(sign == LV_SIGNAL_PRESS_LOST) { - switch(ext->color_mode) - { - case LV_CPICKER_COLOR_MODE_HUE: - ext->prev_hue = ext->hue; - break; - case LV_CPICKER_COLOR_MODE_SATURATION: - ext->prev_saturation = ext->saturation; - break; - case LV_CPICKER_COLOR_MODE_VALUE: - ext->prev_value = ext->value; - break; - } - lv_cpicker_invalidate(cpicker, false); + lv_cpicker_prev_hsv_restore(cpicker, ext); } else if(sign == LV_SIGNAL_RELEASED) { @@ -1533,25 +1521,8 @@ static lv_res_t lv_cpicker_rect_signal(lv_obj_t * cpicker, lv_signal_t sign, voi uint16_t width = ext->rect_gradient_area.x2 - ext->rect_gradient_area.x1; uint16_t distance = indev->proc.types.pointer.act_point.x - ext->rect_gradient_area.x1; float percent = distance / (float) width; - switch(ext->color_mode) - { - case LV_CPICKER_COLOR_MODE_HUE: - ext->hue = percent * 360.0; - ext->prev_hue = ext->hue; - break; - case LV_CPICKER_COLOR_MODE_SATURATION: - ext->saturation = percent * 100.0; - ext->prev_saturation = ext->saturation; - break; - case LV_CPICKER_COLOR_MODE_VALUE: - ext->value = percent * 100.0; - ext->prev_value = ext->value; - break; - } - lv_cpicker_invalidate(cpicker, false); - - res = lv_event_send(cpicker, LV_EVENT_VALUE_CHANGED, NULL); + res = lv_cpicker_set_hsv_percent(cpicker, ext, percent); if(res != LV_RES_OK) return res; } } @@ -1563,113 +1534,23 @@ static lv_res_t lv_cpicker_rect_signal(lv_obj_t * cpicker, lv_signal_t sign, voi if(lv_area_is_point_on(&(ext->rect_preview_area), &indev->proc.types.pointer.act_point)) { - switch(ext->color_mode) - { - case LV_CPICKER_COLOR_MODE_HUE: - ext->prev_hue = ext->hue; - break; - case LV_CPICKER_COLOR_MODE_SATURATION: - ext->prev_saturation = ext->saturation; - break; - case LV_CPICKER_COLOR_MODE_VALUE: - ext->prev_value = ext->value; - break; - } - - ext->color_mode = (ext->color_mode + 1) % 3; - - lv_cpicker_invalidate(cpicker, true); + lv_cpicker_set_next_color_mode(cpicker, ext); } } } - else if(sign == LV_SIGNAL_CONTROL) - { - uint32_t c = *((uint32_t *)param); /*uint32_t because can be UTF-8*/ - if(c == LV_KEY_RIGHT) - { - switch(ext->color_mode) - { - case LV_CPICKER_COLOR_MODE_HUE: - ext->hue = (ext->hue + 1) % 360; - break; - case LV_CPICKER_COLOR_MODE_SATURATION: - ext->saturation = (ext->saturation + 1) % 100; - break; - case LV_CPICKER_COLOR_MODE_VALUE: - ext->value = (ext->value + 1) % 100; - break; - } - - lv_cpicker_invalidate(cpicker, false); - - res = lv_event_send(cpicker, LV_EVENT_VALUE_CHANGED, NULL); - if(res != LV_RES_OK) return res; - } - else if(c == LV_KEY_LEFT) - { - switch(ext->color_mode) - { - case LV_CPICKER_COLOR_MODE_HUE: - ext->hue = ext->hue > 0?(ext->hue - 1):360; - break; - case LV_CPICKER_COLOR_MODE_SATURATION: - ext->saturation = ext->saturation > 0?(ext->saturation - 1):100; - break; - case LV_CPICKER_COLOR_MODE_VALUE: - ext->value = ext->value > 0?(ext->value - 1):100; - break; - } - - lv_cpicker_invalidate(cpicker, false); - - res = lv_event_send(cpicker, LV_EVENT_VALUE_CHANGED, NULL); - if(res != LV_RES_OK) return res; - } - else if(c == LV_KEY_UP) - { - switch(ext->color_mode) - { - case LV_CPICKER_COLOR_MODE_HUE: - ext->hue = (ext->hue + 1) % 360; - break; - case LV_CPICKER_COLOR_MODE_SATURATION: - ext->saturation = (ext->saturation + 1) % 100; - break; - case LV_CPICKER_COLOR_MODE_VALUE: - ext->value = (ext->value + 1) % 100; - break; - } - - lv_cpicker_invalidate(cpicker, false); - - res = lv_event_send(cpicker, LV_EVENT_VALUE_CHANGED, NULL); - if(res != LV_RES_OK) return res; - } - else if(c == LV_KEY_DOWN) - { - switch(ext->color_mode) - { - case LV_CPICKER_COLOR_MODE_HUE: - ext->hue = ext->hue > 0?(ext->hue - 1):360; - break; - case LV_CPICKER_COLOR_MODE_SATURATION: - ext->saturation = ext->saturation > 0?(ext->saturation - 1):100; - break; - case LV_CPICKER_COLOR_MODE_VALUE: - ext->value = ext->value > 0?(ext->value - 1):100; - break; - } - - lv_cpicker_invalidate(cpicker, false); - - res = lv_event_send(cpicker, LV_EVENT_VALUE_CHANGED, NULL); - if(res != LV_RES_OK) return res; - } - } return res; } + +static void lv_cpicker_invalidate_disc(lv_disp_t * disp, lv_style_t * style, + lv_cpicker_ext_t * ext, + lv_coord_t w, lv_coord_t h, + lv_coord_t cx, lv_coord_t cy, uint16_t r); +static void lv_cpicker_invalidate_rect(lv_disp_t * disp, lv_style_t * style, + lv_cpicker_ext_t * ext, + lv_coord_t w, lv_coord_t h); + /** * Indicator points need to match those set in lv_cpicker_disc_design/lv_cpicker_rect_design */ @@ -1681,12 +1562,11 @@ static void lv_cpicker_invalidate(lv_obj_t * cpicker, bool all) return; } - lv_disp_t * disp = lv_disp_get_default(); - + lv_disp_t * disp = lv_obj_get_disp(cpicker); lv_cpicker_ext_t * ext = lv_obj_get_ext_attr(cpicker); lv_style_t * style = lv_cpicker_get_style(cpicker, LV_CPICKER_STYLE_MAIN); - static lv_style_t styleCopy; + lv_style_t styleCopy; lv_style_copy(&styleCopy, style); lv_coord_t w = lv_obj_get_width(cpicker); @@ -1694,284 +1574,241 @@ static void lv_cpicker_invalidate(lv_obj_t * cpicker, bool all) if(ext->type == LV_CPICKER_TYPE_DISC) { - lv_coord_t r = LV_MATH_MIN(w, h) / 2; - lv_coord_t x = cpicker->coords.x1 + w / 2; - lv_coord_t y = cpicker->coords.y1 + h / 2; - - /*invalidate center color area*/ - lv_area_t center_color_area; - - uint32_t rin = r - styleCopy.line.width; - - uint16_t radius = lv_sqrt((4*rin*rin)/2)/2 + 1 - style->body.padding.inner; - - center_color_area.x1 = x - radius; - center_color_area.y1 = y - radius; - center_color_area.x2 = x + radius; - center_color_area.y2 = y + radius; - - lv_inv_area(disp, ¢er_color_area); - - /*invalidate indicator*/ - - uint16_t angle = mode_color_to_angle(ext); - - switch(ext->indicator.type) - { - case LV_CPICKER_INDICATOR_LINE: - { - lv_area_t line_area; - lv_point_t point1, point2; - lv_coord_t x1, y1, x2, y2; - - x1 = x + ((r - style->line.width + ext->indicator.style->body.padding.inner + ext->indicator.style->line.width/2) * lv_trigo_sin(angle) >> LV_TRIGO_SHIFT); - y1 = y + ((r - style->line.width + ext->indicator.style->body.padding.inner + ext->indicator.style->line.width/2) * lv_trigo_sin(angle + 90) >> LV_TRIGO_SHIFT); - x2 = x + ((r - ext->indicator.style->body.padding.inner - ext->indicator.style->line.width/2) * lv_trigo_sin(angle) >> LV_TRIGO_SHIFT); - y2 = y + ((r - ext->indicator.style->body.padding.inner - ext->indicator.style->line.width/2) * lv_trigo_sin(angle + 90) >> LV_TRIGO_SHIFT); - - point1.x = x1; - point1.y = y1; - point2.x = x2; - point2.y = y2; - - //if(LV_MATH_ABS(point1.x - point2.x) > LV_MATH_ABS(point1.y - point2.y)) - //{ - /*Steps less in y then x -> rather horizontal*/ - if(point1.x < point2.x) { - line_area.x1 = point1.x; - //line_area.y1 = point1.y; - line_area.x2 = point2.x; - //line_area.y2 = point2.y; - } else { - line_area.x1 = point2.x; - //line_area.y1 = point2.y; - line_area.x2 = point1.x; - //line_area.y2 = point1.y; - } - //} else { - /*Steps less in x then y -> rather vertical*/ - if(point1.y < point2.y) { - //line_area.x1 = point1.x; - line_area.y1 = point1.y; - //line_area.x2 = point2.x; - line_area.y2 = point2.y; - } else { - //line_area.x1 = point2.x; - line_area.y1 = point2.y; - line_area.x2 = point1.x; - //line_area.y2 = point1.y; - } - //} - - line_area.x1 -= 2*ext->indicator.style->line.width; - line_area.y1 -= 2*ext->indicator.style->line.width; - line_area.x2 += 2*ext->indicator.style->line.width; - line_area.y2 += 2*ext->indicator.style->line.width; - - lv_inv_area(disp, &line_area); - - /* invalidate last postion */ - angle = ext->prev_pos; - - x1 = x + ((r - style->line.width + ext->indicator.style->body.padding.inner + ext->indicator.style->line.width/2) * lv_trigo_sin(angle) >> LV_TRIGO_SHIFT); - y1 = y + ((r - style->line.width + ext->indicator.style->body.padding.inner + ext->indicator.style->line.width/2) * lv_trigo_sin(angle + 90) >> LV_TRIGO_SHIFT); - - x2 = x + ((r - ext->indicator.style->body.padding.inner - ext->indicator.style->line.width/2) * lv_trigo_sin(angle) >> LV_TRIGO_SHIFT); - y2 = y + ((r - ext->indicator.style->body.padding.inner - ext->indicator.style->line.width/2) * lv_trigo_sin(angle + 90) >> LV_TRIGO_SHIFT); - - point1.x = x1; - point1.y = y1; - point2.x = x2; - point2.y = y2; - - //if(LV_MATH_ABS(point1.x - point2.x) > LV_MATH_ABS(point1.y - point2.y)) - //{ - /*rather horizontal*/ - if(point1.x < point2.x) { - line_area.x1 = point1.x; - //line_area.y1 = point1.y; - line_area.x2 = point2.x; - //line_area.y2 = point2.y; - } else { - line_area.x1 = point2.x; - //line_area.y1 = point2.y; - line_area.x2 = point1.x; - //line_area.y2 = point1.y; - } - //} else { - /*rather vertical*/ - if(point1.y < point2.y) { - //line_area.x1 = point1.x; - line_area.y1 = point1.y; - //line_area.x2 = point2.x; - line_area.y2 = point2.y; - } else { - //line_area.x1 = point2.x; - line_area.y1 = point2.y; - //line_area.x2 = point1.x; - line_area.y2 = point1.y; - } - //} - - line_area.x1 -= 2*ext->indicator.style->line.width; - line_area.y1 -= 2*ext->indicator.style->line.width; - line_area.x2 += 2*ext->indicator.style->line.width; - line_area.y2 += 2*ext->indicator.style->line.width; - - lv_inv_area(disp, &line_area); - - break; - } - case LV_CPICKER_INDICATOR_CIRCLE: - { - lv_area_t circle_ind_area; - uint32_t cx, cy; - - cx = x + ((r - style->line.width/2) * lv_trigo_sin(angle) >> LV_TRIGO_SHIFT); - cy = y + ((r - style->line.width/2) * lv_trigo_sin(angle + 90) >> LV_TRIGO_SHIFT); - - circle_ind_area.x1 = cx - style->line.width/2; - circle_ind_area.y1 = cy - style->line.width/2; - circle_ind_area.x2 = cx + style->line.width/2; - circle_ind_area.y2 = cy + style->line.width/2; - - lv_inv_area(disp, &circle_ind_area); - - /* invalidate last position*/ - angle = ext->prev_pos; - - cx = x + ((r - style->line.width/2) * lv_trigo_sin(angle) >> LV_TRIGO_SHIFT); - cy = y + ((r - style->line.width/2) * lv_trigo_sin(angle + 90) >> LV_TRIGO_SHIFT); - - circle_ind_area.x1 = cx - style->line.width/2; - circle_ind_area.y1 = cy - style->line.width/2; - circle_ind_area.x2 = cx + style->line.width/2; - circle_ind_area.y2 = cy + style->line.width/2; - - lv_inv_area(disp, &circle_ind_area); - break; - } - case LV_CPICKER_INDICATOR_IN: - { - uint16_t wradius = r - style->line.width; - - lv_area_t circle_ind_area; - uint32_t cx, cy; - - uint16_t ind_radius = lv_sqrt((4*rin*rin)/2)/2 + 1 - style->body.padding.inner; - ind_radius = (ind_radius + rin) / 2; - - cx = x + ((ind_radius) * lv_trigo_sin(angle) >> LV_TRIGO_SHIFT); - cy = y + ((ind_radius) * lv_trigo_sin(angle + 90) >> LV_TRIGO_SHIFT); - - circle_ind_area.x1 = cx - ((wradius - radius) / 3); - circle_ind_area.y1 = cy - ((wradius - radius) / 3); - circle_ind_area.x2 = cx + ((wradius - radius) / 3); - circle_ind_area.y2 = cy + ((wradius - radius) / 3); - - lv_inv_area(disp, &circle_ind_area); - - /* invalidate last position*/ - angle = ext->prev_pos; - - cx = x + ((ind_radius) * lv_trigo_sin(angle) >> LV_TRIGO_SHIFT); - cy = y + ((ind_radius) * lv_trigo_sin(angle + 90) >> LV_TRIGO_SHIFT); - - circle_ind_area.x1 = cx - ((wradius - radius) / 3); - circle_ind_area.y1 = cy - ((wradius - radius) / 3); - circle_ind_area.x2 = cx + ((wradius - radius) / 3); - circle_ind_area.y2 = cy + ((wradius - radius) / 3); - - lv_inv_area(disp, &circle_ind_area); - break; - } - } + lv_coord_t cx = cpicker->coords.x1 + w / 2; + lv_coord_t cy = cpicker->coords.y1 + h / 2; + uint16_t r = LV_MATH_MIN(w, h) / 2; + lv_cpicker_invalidate_disc(disp, &styleCopy, ext, w, h, cx, cy, r); } else if(ext->type == LV_CPICKER_TYPE_RECT) { - /*invalidate color preview area*/ - lv_inv_area(disp, &ext->rect_preview_area); - - lv_coord_t ind_pos = style->line.rounded ? ext->rect_gradient_h / 2 : 0; - switch(ext->color_mode) - { - default: - case LV_CPICKER_COLOR_MODE_HUE: - ind_pos += ext->hue / 360.0 * ext->rect_gradient_w; - break; - case LV_CPICKER_COLOR_MODE_SATURATION: - ind_pos += ext->saturation / 100.0 * ext->rect_gradient_w; - break; - case LV_CPICKER_COLOR_MODE_VALUE: - ind_pos += ext->value / 100.0 * ext->rect_gradient_w; - break; - } - lv_coord_t prev_pos = ext->prev_pos; - - switch(ext->indicator.type) - { - case LV_CPICKER_INDICATOR_LINE: - { - lv_area_t line_area; - - /*Invalidate the current position*/ - line_area.x1 = ext->rect_gradient_area.x1 + ind_pos - ext->indicator.style->line.width; - line_area.x2 = ext->rect_gradient_area.x1 + ind_pos + ext->indicator.style->line.width; - line_area.y1 = ext->rect_gradient_area.y1; - line_area.y2 = ext->rect_gradient_area.y2; - - lv_inv_area(disp, &line_area); - - /* Invalidate last position */ - line_area.x1 = ext->rect_gradient_area.x1 + prev_pos - ext->indicator.style->line.width; - line_area.x2 = ext->rect_gradient_area.x1 + prev_pos + ext->indicator.style->line.width; - - lv_inv_area(disp, &line_area); - break; - } - case LV_CPICKER_INDICATOR_CIRCLE: - { - lv_area_t circle_ind_area; - - circle_ind_area.x1 = ext->rect_gradient_area.x1 + ind_pos - ext->rect_gradient_h/2; - circle_ind_area.x2 = circle_ind_area.x1 + ext->rect_gradient_h; - circle_ind_area.y1 = ext->rect_gradient_area.y1; - circle_ind_area.y2 = ext->rect_gradient_area.y2; - - lv_inv_area(disp, &circle_ind_area); - - /* invalidate last postion */ - circle_ind_area.x1 = ext->rect_gradient_area.x1 + prev_pos - ext->rect_gradient_h/2; - circle_ind_area.x2 = circle_ind_area.x1 + ext->rect_gradient_h; - //circle_ind_area.y1 = ext->rect_gradient_area.y1; - //circle_ind_area.y2 = ext->rect_gradient_area.y2; - - lv_inv_area(disp, &circle_ind_area); - break; - } - case LV_CPICKER_INDICATOR_IN: - { - lv_coord_t center; - lv_area_t ind_area; - - center = ext->rect_gradient_area.x1 + ind_pos; - ind_area.x1 = center - ext->indicator.style->line.width * 3; - ind_area.y1 = ext->rect_gradient_area.y1 - 1; - ind_area.x2 = center + ext->indicator.style->line.width * 3; - ind_area.y2 = ext->rect_gradient_area.y2; - lv_inv_area(disp, &ind_area); - - /* invalidate last postion */ - center = ext->rect_gradient_area.x1 + prev_pos; - ind_area.x1 = center - ext->indicator.style->line.width * 3; - //ind_area.y1 = ext->rect_gradient_area.y1 - 1; - ind_area.x2 = center + ext->indicator.style->line.width * 3; - //ind_area.y2 = ext->rect_gradient_area.y2; - lv_inv_area(disp, &ind_area); - break; - } - } + lv_cpicker_invalidate_rect(disp, &styleCopy, ext, w, h); } } -#endif +/** + * Should roughly match up with `lv_cpicker_draw_disc_indicator_line` + */ +static void lv_cpicker_invalidate_disc_indicator_line(lv_disp_t * disp, lv_style_t * style, + lv_cpicker_ext_t * ext, + lv_coord_t cx, lv_coord_t cy, uint16_t r, + uint16_t angle) +{ + lv_coord_t x1 = cx + ((r - style->line.width + ext->indicator.style->body.padding.inner + ext->indicator.style->line.width/2) * lv_trigo_sin(angle) >> LV_TRIGO_SHIFT); + lv_coord_t y1 = cy + ((r - style->line.width + ext->indicator.style->body.padding.inner + ext->indicator.style->line.width/2) * lv_trigo_sin(angle + 90) >> LV_TRIGO_SHIFT); + lv_coord_t x2 = cx + ((r - ext->indicator.style->body.padding.inner - ext->indicator.style->line.width/2) * lv_trigo_sin(angle) >> LV_TRIGO_SHIFT); + lv_coord_t y2 = cy + ((r - ext->indicator.style->body.padding.inner - ext->indicator.style->line.width/2) * lv_trigo_sin(angle + 90) >> LV_TRIGO_SHIFT); + + lv_point_t point1, point2; + point1.x = x1; + point1.y = y1; + point2.x = x2; + point2.y = y2; + + lv_area_t line_area; + //if(LV_MATH_ABS(point1.x - point2.x) > LV_MATH_ABS(point1.y - point2.y)) + //{ + /*Steps less in y than x -> rather horizontal*/ + if(point1.x < point2.x) { + line_area.x1 = point1.x; + //line_area.y1 = point1.y; + line_area.x2 = point2.x; + //line_area.y2 = point2.y; + } else { + line_area.x1 = point2.x; + //line_area.y1 = point2.y; + line_area.x2 = point1.x; + //line_area.y2 = point1.y; + } + //} else { + /*Steps less in x than y -> rather vertical*/ + if(point1.y < point2.y) { + //line_area.x1 = point1.x; + line_area.y1 = point1.y; + //line_area.x2 = point2.x; + line_area.y2 = point2.y; + } else { + //line_area.x1 = point2.x; + line_area.y1 = point2.y; + //line_area.x2 = point1.x; + line_area.y2 = point1.y; + } + //} + + line_area.x1 -= 2*ext->indicator.style->line.width; + line_area.y1 -= 2*ext->indicator.style->line.width; + line_area.x2 += 2*ext->indicator.style->line.width; + line_area.y2 += 2*ext->indicator.style->line.width; + + lv_inv_area(disp, &line_area); +} + +/** + * Should roughly match up with `lv_cpicker_draw_disc_indicator_circle` + */ +static void lv_cpicker_invalidate_disc_indicator_circle(lv_disp_t * disp, lv_style_t * style, + lv_cpicker_ext_t * ext, + lv_coord_t cx, lv_coord_t cy, uint16_t r, + uint16_t angle) +{ + uint32_t ind_cx = cx + ((r - style->line.width/2) * lv_trigo_sin(angle) >> LV_TRIGO_SHIFT); + uint32_t ind_cy = cy + ((r - style->line.width/2) * lv_trigo_sin(angle + 90) >> LV_TRIGO_SHIFT); + + lv_area_t ind_area; + ind_area.x1 = ind_cx - style->line.width/2; + ind_area.y1 = ind_cy - style->line.width/2; + ind_area.x2 = ind_cx + style->line.width/2; + ind_area.y2 = ind_cy + style->line.width/2; + + lv_inv_area(disp, &ind_area); +} + +/** + * Should roughly match up with `lv_cpicker_draw_disc_indicator_in` + */ +static void lv_cpicker_invalidate_disc_indicator_in(lv_disp_t * disp, lv_style_t * style, + lv_cpicker_ext_t * ext, + lv_coord_t x, lv_coord_t y, uint16_t r, + uint16_t rin, uint16_t angle) +{ + uint16_t ind_radius = lv_sqrt((4*rin*rin)/2)/2 + 1 - style->body.padding.inner; + ind_radius = (ind_radius + rin) / 2; + + uint16_t ind_cx = x + ((ind_radius) * lv_trigo_sin(angle) >> LV_TRIGO_SHIFT); + uint16_t ind_cy = y + ((ind_radius) * lv_trigo_sin(angle + 90) >> LV_TRIGO_SHIFT); + + lv_area_t ind_area; + ind_area.x1 = ind_cx - r; + ind_area.y1 = ind_cy - r; + ind_area.x2 = ind_cx + r; + ind_area.y2 = ind_cy + r; + + lv_inv_area(disp, &ind_area); +} + +/** + * Should roughly match up with `lv_cpicker_disc_design` + */ +static void lv_cpicker_invalidate_disc(lv_disp_t * disp, lv_style_t * style, + lv_cpicker_ext_t * ext, + lv_coord_t w, lv_coord_t h, + lv_coord_t cx, lv_coord_t cy, uint16_t r) +{ + /*invalidate center color area*/ + uint16_t rin = r - style->line.width; + /* + the square area (a and b being sides) should fit into the center of diameter d + we have: + a^2+b^2<=d^2 + 2a^2 <= d^2 + a^2<=(d^2)/2 + a <= sqrt((d^2)/2) + */ + uint16_t radius = lv_sqrt((4*rin*rin)/2)/2 + 1 - style->body.padding.inner; + + lv_area_t center_color_area; + center_color_area.x1 = cx - radius; + center_color_area.y1 = cy - radius; + center_color_area.x2 = cx + radius; + center_color_area.y2 = cy + radius; + + lv_inv_area(disp, ¢er_color_area); + + /*invalidate indicator*/ + uint16_t angle = mode_color_to_angle(ext); + switch(ext->indicator.type) + { + case LV_CPICKER_INDICATOR_LINE: + lv_cpicker_invalidate_disc_indicator_line(disp, style, ext, cx, cy, r, angle); + lv_cpicker_invalidate_disc_indicator_line(disp, style, ext, cx, cy, r, ext->prev_pos); + break; + case LV_CPICKER_INDICATOR_CIRCLE: + lv_cpicker_invalidate_disc_indicator_circle(disp, style, ext, cx, cy, r, angle); + lv_cpicker_invalidate_disc_indicator_circle(disp, style, ext, cx, cy, r, ext->prev_pos); + break; + case LV_CPICKER_INDICATOR_IN: + lv_cpicker_invalidate_disc_indicator_in(disp, style, ext, cx, cy, (rin - radius) / 3, rin, angle); + lv_cpicker_invalidate_disc_indicator_in(disp, style, ext, cx, cy, (rin - radius) / 3, rin, ext->prev_pos); + break; + } +} + +/** + * Should roughly match up with `lv_cpicker_draw_rect_indicator_line` + */ +static void lv_cpicker_invalidate_rect_indicator_line(lv_disp_t * disp, + lv_cpicker_ext_t * ext, + lv_coord_t ind_pos) +{ + lv_area_t line_area; + line_area.x1 = ext->rect_gradient_area.x1 + ind_pos - ext->indicator.style->line.width; + line_area.y1 = ext->rect_gradient_area.y1; + line_area.x2 = ext->rect_gradient_area.x1 + ind_pos + ext->indicator.style->line.width; + line_area.y2 = ext->rect_gradient_area.y2; + + lv_inv_area(disp, &line_area); +} + +/** + * Should roughly match up with `lv_cpicker_draw_rect_indicator_circle` + */ +static void lv_cpicker_invalidate_rect_indicator_circle(lv_disp_t * disp, + lv_cpicker_ext_t * ext, + lv_coord_t ind_pos) +{ + lv_area_t circle_ind_area; + circle_ind_area.x1 = ext->rect_gradient_area.x1 + ind_pos - ext->rect_gradient_h/2; + circle_ind_area.x2 = circle_ind_area.x1 + ext->rect_gradient_h; + circle_ind_area.y1 = ext->rect_gradient_area.y1; + circle_ind_area.y2 = ext->rect_gradient_area.y2; + + lv_inv_area(disp, &circle_ind_area); +} + +/** + * Should roughly match up with `lv_cpicker_draw_rect_indicator_in` + */ +static void lv_cpicker_invalidate_rect_indicator_in(lv_disp_t * disp, + lv_cpicker_ext_t * ext, + lv_coord_t ind_pos) +{ + lv_coord_t center = ext->rect_gradient_area.x1 + ind_pos; + + lv_area_t ind_area; + ind_area.x1 = center - ext->indicator.style->line.width * 3; + ind_area.y1 = ext->rect_gradient_area.y1 - 1; + ind_area.x2 = center + ext->indicator.style->line.width * 3; + ind_area.y2 = ext->rect_gradient_area.y2; + + lv_inv_area(disp, &ind_area); +} + +/** + * Should roughly match up with `lv_cpicker_rect_design` + */ +static void lv_cpicker_invalidate_rect(lv_disp_t * disp, lv_style_t * style, + lv_cpicker_ext_t * ext, + lv_coord_t w, lv_coord_t h) +{ + /*invalidate color preview indicator*/ + lv_inv_area(disp, &ext->rect_preview_area); + + /*invalidate indicator*/ + lv_coord_t ind_pos = lv_cpicker_get_indicator_coord(style, ext); + switch(ext->indicator.type) + { + case LV_CPICKER_INDICATOR_LINE: + lv_cpicker_invalidate_rect_indicator_line(disp, ext, ind_pos); + lv_cpicker_invalidate_rect_indicator_line(disp, ext, ext->prev_pos); + break; + case LV_CPICKER_INDICATOR_CIRCLE: + lv_cpicker_invalidate_rect_indicator_circle(disp, ext, ind_pos); + lv_cpicker_invalidate_rect_indicator_circle(disp, ext, ext->prev_pos); + break; + case LV_CPICKER_INDICATOR_IN: + lv_cpicker_invalidate_rect_indicator_in(disp, ext, ind_pos); + lv_cpicker_invalidate_rect_indicator_in(disp, ext, ext->prev_pos); + break; + } +} + +#endif /* LV_USE_CPICKER != 0 */ From 7ac2aff9824efe2f6eda4c534fdc033302ac9395 Mon Sep 17 00:00:00 2001 From: Paul Peavyhouse Date: Thu, 26 Sep 2019 22:35:41 -0700 Subject: [PATCH 20/25] Using #define defaults instead of hard-coded numbers --- src/lv_objx/lv_cpicker.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/lv_objx/lv_cpicker.c b/src/lv_objx/lv_cpicker.c index 9889c248e..6615397c7 100644 --- a/src/lv_objx/lv_cpicker.c +++ b/src/lv_objx/lv_cpicker.c @@ -1321,15 +1321,15 @@ static void lv_cpicker_reset_hsv_if_double_clicked(lv_obj_t * cpicker, switch(ext->color_mode) { case LV_CPICKER_COLOR_MODE_HUE: - ext->hue = 0; + ext->hue = LV_CPICKER_DEF_HUE; ext->prev_hue = ext->hue; break; case LV_CPICKER_COLOR_MODE_SATURATION: - ext->saturation = 100; + ext->saturation = LV_CPICKER_DEF_SATURATION; ext->prev_saturation = ext->saturation; break; case LV_CPICKER_COLOR_MODE_VALUE: - ext->value = 100; + ext->value = LV_CPICKER_DEF_VALUE; ext->prev_value = ext->value; break; } From 333812ba7aa2d522a5c43074eb21d16308d9e8bb Mon Sep 17 00:00:00 2001 From: Paul Peavyhouse Date: Mon, 30 Sep 2019 07:00:34 -0700 Subject: [PATCH 21/25] Improvements to color picker (#1208) --- src/lv_objx/lv_cpicker.c | 290 +++++++++++++++++---------------------- src/lv_objx/lv_cpicker.h | 28 ++-- 2 files changed, 146 insertions(+), 172 deletions(-) diff --git a/src/lv_objx/lv_cpicker.c b/src/lv_objx/lv_cpicker.c index 6615397c7..ad138d126 100644 --- a/src/lv_objx/lv_cpicker.c +++ b/src/lv_objx/lv_cpicker.c @@ -9,6 +9,7 @@ #include "lv_cpicker.h" #if LV_USE_CPICKER != 0 +#include "../lv_core/lv_debug.h" #include "../lv_draw/lv_draw_arc.h" #include "../lv_themes/lv_theme.h" #include "../lv_core/lv_indev.h" @@ -34,6 +35,10 @@ #define LV_CPICKER_DEF_VALUE 100 #endif +#ifndef LV_CPICKER_DEF_HSV +#define LV_CPICKER_DEF_HSV ((lv_color_hsv_t){LV_CPICKER_DEF_HUE, LV_CPICKER_DEF_SATURATION, LV_CPICKER_DEF_VALUE}) +#endif + #ifndef LV_CPICKER_DEF_INDICATOR_TYPE #define LV_CPICKER_DEF_INDICATOR_TYPE LV_CPICKER_INDICATOR_CIRCLE #endif @@ -92,7 +97,7 @@ lv_obj_t * lv_cpicker_create(lv_obj_t * par, const lv_obj_t * copy) LV_LOG_TRACE("color_picker create started"); lv_obj_t * new_cpicker = lv_obj_create(par, copy); - lv_mem_assert(new_cpicker); + LV_ASSERT_MEM(new_cpicker); if(new_cpicker == NULL) return NULL; if(ancestor_signal == NULL) ancestor_signal = lv_obj_get_signal_cb(new_cpicker); @@ -100,14 +105,12 @@ lv_obj_t * lv_cpicker_create(lv_obj_t * par, const lv_obj_t * copy) /*Allocate the extended data*/ lv_cpicker_ext_t * ext = lv_obj_allocate_ext_attr(new_cpicker, sizeof(lv_cpicker_ext_t)); - lv_mem_assert(ext); + LV_ASSERT_MEM(ext); if(ext == NULL) return NULL; /*Initialize the allocated 'ext' */ - ext->hue = LV_CPICKER_DEF_HUE; - ext->prev_hue = ext->hue; - ext->saturation = LV_CPICKER_DEF_SATURATION; - ext->value = LV_CPICKER_DEF_VALUE; + ext->hsv = LV_CPICKER_DEF_HSV; + ext->prev_hsv = ext->hsv; ext->indicator.style = &lv_style_plain; ext->indicator.type = LV_CPICKER_DEF_INDICATOR_TYPE; ext->color_mode = LV_CPICKER_COLOR_MODE_HUE; @@ -201,7 +204,7 @@ void lv_cpicker_set_hue(lv_obj_t * cpicker, uint16_t hue) { lv_cpicker_ext_t * ext = lv_obj_get_ext_attr(cpicker); - ext->hue = hue % 360; + ext->hsv.h = hue % 360; lv_obj_invalidate(cpicker); } @@ -215,7 +218,7 @@ void lv_cpicker_set_saturation(lv_obj_t * cpicker, uint8_t saturation) { lv_cpicker_ext_t * ext = lv_obj_get_ext_attr(cpicker); - ext->saturation = saturation % 100; + ext->hsv.s = saturation % 100; lv_obj_invalidate(cpicker); } @@ -229,7 +232,21 @@ void lv_cpicker_set_value(lv_obj_t * cpicker, uint8_t val) { lv_cpicker_ext_t * ext = lv_obj_get_ext_attr(cpicker); - ext->value = val % 100; + ext->hsv.v = val % 100; + + lv_obj_invalidate(cpicker); +} + +/** + * Set the current hsv of a colorpicker. + * @param cpicker pointer to colorpicker object + * @param color current selected hsv + */ +void lv_cpicker_set_hsv(lv_obj_t * cpicker, lv_color_hsv_t hsv) +{ + lv_cpicker_ext_t * ext = lv_obj_get_ext_attr(cpicker); + + ext->hsv = hsv; lv_obj_invalidate(cpicker); } @@ -241,12 +258,7 @@ void lv_cpicker_set_value(lv_obj_t * cpicker, uint8_t val) */ void lv_cpicker_set_color(lv_obj_t * cpicker, lv_color_t color) { - lv_cpicker_ext_t * ext = lv_obj_get_ext_attr(cpicker); - - lv_color_hsv_t hsv = lv_color_rgb_to_hsv(color.ch.red, color.ch.green, color.ch.blue); - ext->hue = hsv.h; - - lv_obj_invalidate(cpicker); + lv_cpicker_set_hsv(cpicker, lv_color_rgb_to_hsv(color.ch.red, color.ch.green, color.ch.blue)); } /** @@ -325,7 +337,7 @@ lv_style_t * lv_cpicker_get_style(const lv_obj_t * cpicker, lv_cpicker_style_t t } /** - * Get the current hue of a colorpicker. + * Get the current selected hue of a colorpicker. * @param cpicker pointer to colorpicker object * @return hue current selected hue */ @@ -333,11 +345,11 @@ uint16_t lv_cpicker_get_hue(lv_obj_t * cpicker) { lv_cpicker_ext_t * ext = lv_obj_get_ext_attr(cpicker); - return ext->hue; + return ext->hsv.h; } /** - * Get the current saturation of a colorpicker. + * Get the current selected saturation of a colorpicker. * @param cpicker pointer to colorpicker object * @return current selected saturation */ @@ -345,11 +357,11 @@ uint8_t lv_cpicker_get_saturation(lv_obj_t * cpicker) { lv_cpicker_ext_t * ext = lv_obj_get_ext_attr(cpicker); - return ext->saturation; + return ext->hsv.s; } /** - * Get the current hue of a colorpicker. + * Get the current selected hue of a colorpicker. * @param cpicker pointer to colorpicker object * @return current selected value */ @@ -357,7 +369,19 @@ uint8_t lv_cpicker_get_value(lv_obj_t * cpicker) { lv_cpicker_ext_t * ext = lv_obj_get_ext_attr(cpicker); - return ext->value; + return ext->hsv.v; +} + +/** + * Get the current selected hsv of a colorpicker. + * @param cpicker pointer to colorpicker object + * @return current selected hsv + */ +lv_color_hsv_t lv_cpicker_get_hsv(lv_obj_t * cpicker) +{ + lv_cpicker_ext_t * ext = lv_obj_get_ext_attr(cpicker); + + return ext->hsv; } /** @@ -369,7 +393,7 @@ lv_color_t lv_cpicker_get_color(lv_obj_t * cpicker) { lv_cpicker_ext_t * ext = lv_obj_get_ext_attr(cpicker); - return lv_color_hsv_to_rgb(ext->hue, ext->saturation, ext->value); + return lv_color_hsv_to_rgb(ext->hsv.h, ext->hsv.s, ext->hsv.v); } /*===================== @@ -452,13 +476,13 @@ static lv_color_t angle_to_mode_color(lv_cpicker_ext_t * ext, uint16_t angle) { default: case LV_CPICKER_COLOR_MODE_HUE: - color = lv_color_hsv_to_rgb(angle % 360, ext->saturation, ext->value); + color = lv_color_hsv_to_rgb(angle % 360, ext->hsv.s, ext->hsv.v); break; case LV_CPICKER_COLOR_MODE_SATURATION: - color = lv_color_hsv_to_rgb(ext->hue, (angle % 360) / 360.0 * 100.0, ext->value); + color = lv_color_hsv_to_rgb(ext->hsv.h, (angle % 360) / 360.0 * 100.0, ext->hsv.v); break; case LV_CPICKER_COLOR_MODE_VALUE: - color = lv_color_hsv_to_rgb(ext->hue, ext->saturation, (angle % 360) / 360.0 * 100.0); + color = lv_color_hsv_to_rgb(ext->hsv.h, ext->hsv.s, (angle % 360) / 360.0 * 100.0); break; } return color; @@ -471,13 +495,13 @@ static uint16_t mode_color_to_angle(lv_cpicker_ext_t * ext) { default: case LV_CPICKER_COLOR_MODE_HUE: - angle = ext->hue; + angle = ext->hsv.h; break; case LV_CPICKER_COLOR_MODE_SATURATION: - angle = ext->saturation / 100.0 * 360.0; + angle = ext->hsv.s / 100.0 * 360.0; break; case LV_CPICKER_COLOR_MODE_VALUE: - angle = ext->value / 100.0 * 360.0; + angle = ext->hsv.v / 100.0 * 360.0; break; } return angle; @@ -490,13 +514,13 @@ static lv_coord_t lv_cpicker_get_indicator_coord(lv_style_t * style, lv_cpicker_ { default: case LV_CPICKER_COLOR_MODE_HUE: - ind_pos += ext->hue / 360.0 * ext->rect_gradient_w; + ind_pos += ext->hsv.h / 360.0 * ext->rect_gradient_w; break; case LV_CPICKER_COLOR_MODE_SATURATION: - ind_pos += ext->saturation / 100.0 * ext->rect_gradient_w; + ind_pos += ext->hsv.s / 100.0 * ext->rect_gradient_w; break; case LV_CPICKER_COLOR_MODE_VALUE: - ind_pos += ext->value / 100.0 * ext->rect_gradient_w; + ind_pos += ext->hsv.v / 100.0 * ext->rect_gradient_w; break; } return ind_pos; @@ -610,7 +634,7 @@ static void lv_cpicker_draw_disc_indicator(lv_area_t * mask, lv_style_t * style, lv_draw_rect(¢er_area, mask, &styleCenterBackground, opa_scale); /*draw the center color indicator*/ - style->body.main_color = lv_color_hsv_to_rgb(ext->hue, ext->saturation, ext->value); + style->body.main_color = lv_color_hsv_to_rgb(ext->hsv.h, ext->hsv.s, ext->hsv.v); style->body.grad_color = style->body.main_color; style->body.radius = LV_RADIUS_CIRCLE; lv_draw_rect(¢er_ind_area, mask, style, opa_scale); @@ -1162,32 +1186,39 @@ static lv_res_t lv_cpicker_signal(lv_obj_t * cpicker, lv_signal_t sign, void * p lv_res_t res = ancestor_signal(cpicker, sign, param); if(res != LV_RES_OK) return res; - if(sign == LV_SIGNAL_CLEANUP) { + if(sign == LV_SIGNAL_CLEANUP) + { /*Nothing to cleanup. (No dynamically allocated memory in 'ext')*/ - } else if(sign == LV_SIGNAL_GET_TYPE) { + } + else if(sign == LV_SIGNAL_GET_TYPE) + { lv_obj_type_t * buf = param; uint8_t i; - for(i = 0; i < LV_MAX_ANCESTOR_NUM - 1; i++) { /*Find the last set data*/ + for(i = 0; i < LV_MAX_ANCESTOR_NUM - 1; i++) /*Find the last set data*/ + { if(buf->type[i] == NULL) break; } buf->type[i] = "lv_cpicker"; - } else { + } + else + { lv_cpicker_ext_t * ext = lv_obj_get_ext_attr(cpicker); - if(sign == LV_SIGNAL_CONTROL) { + if(sign == LV_SIGNAL_CONTROL) + { uint32_t c = *((uint32_t *)param); /*uint32_t because can be UTF-8*/ - if(c == LV_KEY_RIGHT) + if(c == LV_KEY_RIGHT || c == LV_KEY_UP) { switch(ext->color_mode) { case LV_CPICKER_COLOR_MODE_HUE: - ext->hue = (ext->hue + 1) % 360; + ext->hsv.h = (ext->hsv.h + 1) % 360; break; case LV_CPICKER_COLOR_MODE_SATURATION: - ext->saturation = (ext->saturation + 1) % 100; + ext->hsv.s = (ext->hsv.s + 1) % 100; break; case LV_CPICKER_COLOR_MODE_VALUE: - ext->value = (ext->value + 1) % 100; + ext->hsv.v = (ext->hsv.v + 1) % 100; break; } @@ -1196,18 +1227,18 @@ static lv_res_t lv_cpicker_signal(lv_obj_t * cpicker, lv_signal_t sign, void * p res = lv_event_send(cpicker, LV_EVENT_VALUE_CHANGED, NULL); if(res != LV_RES_OK) return res; } - else if(c == LV_KEY_LEFT) + else if(c == LV_KEY_LEFT || c == LV_KEY_DOWN) { switch(ext->color_mode) { case LV_CPICKER_COLOR_MODE_HUE: - ext->hue = ext->hue > 0?(ext->hue - 1):360; + ext->hsv.h = ext->hsv.h > 0?(ext->hsv.h - 1):360; break; case LV_CPICKER_COLOR_MODE_SATURATION: - ext->saturation = ext->saturation > 0?(ext->saturation - 1):100; + ext->hsv.s = ext->hsv.s > 0?(ext->hsv.s - 1):100; break; case LV_CPICKER_COLOR_MODE_VALUE: - ext->value = ext->value > 0?(ext->value - 1):100; + ext->hsv.v = ext->hsv.v > 0?(ext->hsv.v - 1):100; break; } @@ -1216,47 +1247,14 @@ static lv_res_t lv_cpicker_signal(lv_obj_t * cpicker, lv_signal_t sign, void * p res = lv_event_send(cpicker, LV_EVENT_VALUE_CHANGED, NULL); if(res != LV_RES_OK) return res; } - else if(c == LV_KEY_UP) - { - switch(ext->color_mode) - { - case LV_CPICKER_COLOR_MODE_HUE: - ext->hue = (ext->hue + 1) % 360; - break; - case LV_CPICKER_COLOR_MODE_SATURATION: - ext->saturation = (ext->saturation + 1) % 100; - break; - case LV_CPICKER_COLOR_MODE_VALUE: - ext->value = (ext->value + 1) % 100; - break; - } - - lv_cpicker_invalidate(cpicker, false); - - res = lv_event_send(cpicker, LV_EVENT_VALUE_CHANGED, NULL); - if(res != LV_RES_OK) return res; - } - else if(c == LV_KEY_DOWN) - { - switch(ext->color_mode) - { - case LV_CPICKER_COLOR_MODE_HUE: - ext->hue = ext->hue > 0?(ext->hue - 1):360; - break; - case LV_CPICKER_COLOR_MODE_SATURATION: - ext->saturation = ext->saturation > 0?(ext->saturation - 1):100; - break; - case LV_CPICKER_COLOR_MODE_VALUE: - ext->value = ext->value > 0?(ext->value - 1):100; - break; - } - - lv_cpicker_invalidate(cpicker, false); - - res = lv_event_send(cpicker, LV_EVENT_VALUE_CHANGED, NULL); - if(res != LV_RES_OK) return res; - } - } else { + } + else if(sign == LV_SIGNAL_PRESS_LOST) + { + ext->prev_hsv = ext->hsv; + lv_cpicker_invalidate(cpicker, false); + } + else + { lv_style_t * style = lv_cpicker_get_style(cpicker, LV_CPICKER_STYLE_MAIN); if(ext->type == LV_CPICKER_TYPE_DISC) @@ -1279,83 +1277,57 @@ static lv_res_t lv_cpicker_signal(lv_obj_t * cpicker, lv_signal_t sign, void * p return res; } -static void lv_cpicker_prev_hsv_save(lv_cpicker_ext_t * ext) +static lv_res_t lv_cpicker_reset_hsv_if_double_clicked(lv_obj_t * cpicker, + lv_cpicker_ext_t * ext) { - switch(ext->color_mode) - { - case LV_CPICKER_COLOR_MODE_HUE: - ext->prev_hue = ext->hue; - break; - case LV_CPICKER_COLOR_MODE_SATURATION: - ext->prev_saturation = ext->saturation; - break; - case LV_CPICKER_COLOR_MODE_VALUE: - ext->prev_value = ext->value; - break; - } -} + bool changed = false; -static void lv_cpicker_prev_hsv_restore(lv_obj_t * cpicker, - lv_cpicker_ext_t * ext) -{ - switch(ext->color_mode) - { - case LV_CPICKER_COLOR_MODE_HUE: - ext->prev_hue = ext->hue; - break; - case LV_CPICKER_COLOR_MODE_SATURATION: - ext->prev_saturation = ext->saturation; - break; - case LV_CPICKER_COLOR_MODE_VALUE: - ext->prev_value = ext->value; - break; - } - lv_cpicker_invalidate(cpicker, false); -} - -static void lv_cpicker_reset_hsv_if_double_clicked(lv_obj_t * cpicker, - lv_cpicker_ext_t * ext) -{ if(lv_tick_elaps(ext->last_click) < 400) { switch(ext->color_mode) { case LV_CPICKER_COLOR_MODE_HUE: - ext->hue = LV_CPICKER_DEF_HUE; - ext->prev_hue = ext->hue; + changed = ext->hsv.h != LV_CPICKER_DEF_HSV.h; + if (changed) + { + ext->hsv.h = LV_CPICKER_DEF_HSV.h; + } break; case LV_CPICKER_COLOR_MODE_SATURATION: - ext->saturation = LV_CPICKER_DEF_SATURATION; - ext->prev_saturation = ext->saturation; + changed = ext->hsv.s != LV_CPICKER_DEF_HSV.s; + if (changed) + { + ext->hsv.s = LV_CPICKER_DEF_HSV.s; + } break; case LV_CPICKER_COLOR_MODE_VALUE: - ext->value = LV_CPICKER_DEF_VALUE; - ext->prev_value = ext->value; + changed = ext->hsv.v != LV_CPICKER_DEF_HSV.v; + if (changed) + { + ext->hsv.v = LV_CPICKER_DEF_HSV.v; + } break; } - lv_cpicker_invalidate(cpicker, false); + ext->prev_hsv = ext->hsv; } ext->last_click = lv_tick_get(); + + lv_res_t res = LV_RES_OK; + if (changed) + { + lv_cpicker_invalidate(cpicker, false); + + res = lv_event_send(cpicker, LV_EVENT_VALUE_CHANGED, NULL); + if(res != LV_RES_OK) return res; + } + return res; } static void lv_cpicker_set_next_color_mode(lv_obj_t * cpicker, lv_cpicker_ext_t * ext) { - switch(ext->color_mode) - { - case LV_CPICKER_COLOR_MODE_HUE: - ext->prev_hue = ext->hue; - break; - case LV_CPICKER_COLOR_MODE_SATURATION: - ext->prev_saturation = ext->saturation; - break; - case LV_CPICKER_COLOR_MODE_VALUE: - ext->prev_value = ext->value; - break; - } - + ext->prev_hsv = ext->hsv; ext->color_mode = (ext->color_mode + 1) % 3; - lv_cpicker_invalidate(cpicker, true); } @@ -1371,32 +1343,30 @@ static lv_res_t lv_cpicker_set_hsv_percent(lv_obj_t * cpicker, { case LV_CPICKER_COLOR_MODE_HUE: hsv = percent * 360.0; - changed = hsv != ext->hue; + changed = hsv != ext->hsv.h; if (changed) { - ext->hue = hsv; - ext->prev_hue = ext->hue; + ext->hsv.h = hsv; } break; case LV_CPICKER_COLOR_MODE_SATURATION: hsv = percent * 100.0; - changed = hsv != ext->saturation; + changed = hsv != ext->hsv.s; if (changed) { - ext->saturation = hsv; - ext->prev_saturation = ext->saturation; + ext->hsv.s = hsv; } break; case LV_CPICKER_COLOR_MODE_VALUE: hsv = percent * 100.0; - changed = hsv != ext->value; + changed = hsv != ext->hsv.v; if (changed) { - ext->value = hsv; - ext->prev_value = ext->value; + ext->hsv.v = hsv; } break; } + ext->prev_hsv = ext->hsv; if (changed) { @@ -1417,7 +1387,7 @@ static lv_res_t lv_cpicker_disc_signal(lv_obj_t * cpicker, lv_signal_t sign, voi if(sign == LV_SIGNAL_PRESSED) { - lv_cpicker_prev_hsv_save(ext); + ext->prev_hsv = ext->hsv; lv_indev_t * indev = param; @@ -1425,7 +1395,8 @@ static lv_res_t lv_cpicker_disc_signal(lv_obj_t * cpicker, lv_signal_t sign, voi lv_coord_t yp = indev->proc.types.pointer.act_point.y - y; if((xp*xp + yp*yp) < (r_in*r_in)) { - lv_cpicker_reset_hsv_if_double_clicked(cpicker, ext); + res = lv_cpicker_reset_hsv_if_double_clicked(cpicker, ext); + if(res != LV_RES_OK) return res; } } else if(sign == LV_SIGNAL_PRESSING) @@ -1442,10 +1413,6 @@ static lv_res_t lv_cpicker_disc_signal(lv_obj_t * cpicker, lv_signal_t sign, voi if(res != LV_RES_OK) return res; } } - else if(sign == LV_SIGNAL_PRESS_LOST) - { - lv_cpicker_prev_hsv_restore(cpicker, ext); - } else if(sign == LV_SIGNAL_RELEASED) { lv_indev_t * indev = param; @@ -1485,13 +1452,14 @@ static lv_res_t lv_cpicker_rect_signal(lv_obj_t * cpicker, lv_signal_t sign, voi if(sign == LV_SIGNAL_PRESSED) { - lv_cpicker_prev_hsv_save(ext); + ext->prev_hsv = ext->hsv; lv_indev_t * indev = param; if(lv_area_is_point_on(&(ext->rect_preview_area), &indev->proc.types.pointer.act_point)) { - lv_cpicker_reset_hsv_if_double_clicked(cpicker, ext); + res = lv_cpicker_reset_hsv_if_double_clicked(cpicker, ext); + if(res != LV_RES_OK) return res; } } else if(sign == LV_SIGNAL_PRESSING) @@ -1508,10 +1476,6 @@ static lv_res_t lv_cpicker_rect_signal(lv_obj_t * cpicker, lv_signal_t sign, voi if(res != LV_RES_OK) return res; } } - else if(sign == LV_SIGNAL_PRESS_LOST) - { - lv_cpicker_prev_hsv_restore(cpicker, ext); - } else if(sign == LV_SIGNAL_RELEASED) { lv_indev_t * indev = param; diff --git a/src/lv_objx/lv_cpicker.h b/src/lv_objx/lv_cpicker.h index 406322579..987800e85 100644 --- a/src/lv_objx/lv_cpicker.h +++ b/src/lv_objx/lv_cpicker.h @@ -32,17 +32,13 @@ extern "C" { **********************/ /*Data of colorpicker*/ typedef struct { - uint16_t hue; - uint8_t saturation; - uint8_t value; + lv_color_hsv_t hsv; struct { lv_style_t * style; uint8_t type; } indicator; - uint16_t prev_hue; - uint8_t prev_saturation; - uint8_t prev_value; + lv_color_hsv_t prev_hsv; uint16_t prev_pos; uint8_t color_mode:2; uint8_t color_mode_fixed:1; @@ -141,6 +137,13 @@ void lv_cpicker_set_saturation(lv_obj_t * cpicker, uint8_t saturation); */ void lv_cpicker_set_value(lv_obj_t * cpicker, uint8_t val); +/** + * Set the current hsv of a colorpicker. + * @param cpicker pointer to colorpicker object + * @param hsv current selected hsv + */ +void lv_cpicker_set_hsv(lv_obj_t * cpicker, lv_color_hsv_t hsv); + /** * Set the current color of a colorpicker. * @param cpicker pointer to colorpicker object @@ -184,14 +187,14 @@ bool lv_cpicker_get_color_mode_fixed(lv_obj_t * cpicker); * Get style of a colorpicker. * @param cpicker pointer to colorpicker object * @param type which style should be get - * @return style pointer to the style + * @return pointer to the style */ lv_style_t * lv_cpicker_get_style(const lv_obj_t * cpicker, lv_cpicker_style_t type); /** * Get the current hue of a colorpicker. * @param cpicker pointer to colorpicker object - * @return hue current selected hue + * @return current selected hue */ uint16_t lv_cpicker_get_hue(lv_obj_t * cpicker); @@ -209,10 +212,17 @@ uint8_t lv_cpicker_get_saturation(lv_obj_t * cpicker); */ uint8_t lv_cpicker_get_value(lv_obj_t * cpicker); +/** + * Get the current selected hsv of a colorpicker. + * @param cpicker pointer to colorpicker object + * @return current selected hsv + */ +lv_color_hsv_t lv_cpicker_get_hsv(lv_obj_t * cpicker); + /** * Get the current selected color of a colorpicker. * @param cpicker pointer to colorpicker object - * @return color current selected color + * @return current selected color */ lv_color_t lv_cpicker_get_color(lv_obj_t * cpicker); From 8cb508dfec1e7c2e016cadb23e33d5ea4a2ba54c Mon Sep 17 00:00:00 2001 From: Gabor Kiss-Vamosi Date: Tue, 1 Oct 2019 05:20:20 +0200 Subject: [PATCH 22/25] cpicker minor renames --- src/lv_objx/lv_cpicker.c | 97 ++++++++++++++-------------------------- src/lv_objx/lv_cpicker.h | 57 ++++++++++++----------- 2 files changed, 64 insertions(+), 90 deletions(-) diff --git a/src/lv_objx/lv_cpicker.c b/src/lv_objx/lv_cpicker.c index ad138d126..ec0c727a6 100644 --- a/src/lv_objx/lv_cpicker.c +++ b/src/lv_objx/lv_cpicker.c @@ -72,6 +72,15 @@ static bool lv_cpicker_design(lv_obj_t * cpicker, const lv_area_t * mask, lv_design_mode_t mode); static lv_res_t lv_cpicker_signal(lv_obj_t * cpicker, lv_signal_t sign, void * param); +static void lv_cpicker_disc_design(lv_obj_t * cpicker, + lv_area_t * mask, lv_style_t * style, lv_opa_t opa_scale, + lv_cpicker_ext_t * ext, + lv_coord_t w, lv_coord_t h, + lv_coord_t cx, lv_coord_t cy, uint16_t r); +static void lv_cpicker_rect_design(lv_obj_t * cpicker, + lv_area_t * mask, lv_style_t * style, lv_opa_t opa_scale, + lv_cpicker_ext_t * ext, + lv_coord_t w, lv_coord_t h); /********************** * STATIC VARIABLES **********************/ @@ -115,7 +124,7 @@ lv_obj_t * lv_cpicker_create(lv_obj_t * par, const lv_obj_t * copy) ext->indicator.type = LV_CPICKER_DEF_INDICATOR_TYPE; ext->color_mode = LV_CPICKER_COLOR_MODE_HUE; ext->color_mode_fixed = 0; - ext->last_click = 0; + ext->last_click_time = 0; /*The signal and design functions are not copied so set them here*/ lv_obj_set_signal_cb(new_cpicker, lv_cpicker_signal); @@ -408,15 +417,6 @@ lv_color_t lv_cpicker_get_color(lv_obj_t * cpicker) * STATIC FUNCTIONS **********************/ -static void lv_cpicker_disc_design(lv_obj_t * cpicker, - lv_area_t * mask, lv_style_t * style, lv_opa_t opa_scale, - lv_cpicker_ext_t * ext, - lv_coord_t w, lv_coord_t h, - lv_coord_t cx, lv_coord_t cy, uint16_t r); -static void lv_cpicker_rect_design(lv_obj_t * cpicker, - lv_area_t * mask, lv_style_t * style, lv_opa_t opa_scale, - lv_cpicker_ext_t * ext, - lv_coord_t w, lv_coord_t h); /** * Handle the drawing related tasks of the color_picker @@ -431,13 +431,11 @@ static void lv_cpicker_rect_design(lv_obj_t * cpicker, static bool lv_cpicker_design(lv_obj_t * cpicker, const lv_area_t * mask, lv_design_mode_t mode) { /*Return false if the object is not covers the mask_p area*/ - if(mode == LV_DESIGN_COVER_CHK) - { + if(mode == LV_DESIGN_COVER_CHK) { return false; } /*Draw the object*/ - else if(mode == LV_DESIGN_DRAW_MAIN) - { + else if(mode == LV_DESIGN_DRAW_MAIN) { lv_cpicker_ext_t * ext = lv_obj_get_ext_attr(cpicker); lv_style_t * style = lv_cpicker_get_style(cpicker, LV_CPICKER_STYLE_MAIN); @@ -449,21 +447,17 @@ static bool lv_cpicker_design(lv_obj_t * cpicker, const lv_area_t * mask, lv_des lv_coord_t w = lv_obj_get_width(cpicker); lv_coord_t h = lv_obj_get_height(cpicker); - if(ext->type == LV_CPICKER_TYPE_DISC) - { + if(ext->type == LV_CPICKER_TYPE_DISC) { lv_coord_t cx = cpicker->coords.x1 + (w / 2); lv_coord_t cy = cpicker->coords.y1 + (h / 2); uint16_t r = LV_MATH_MIN(w, h) / 2; lv_cpicker_disc_design(cpicker, mask, &styleCopy, opa_scale, ext, w, h, cx, cy, r); - } - else if(ext->type == LV_CPICKER_TYPE_RECT) - { + } else if(ext->type == LV_CPICKER_TYPE_RECT) { lv_cpicker_rect_design(cpicker, mask, &styleCopy, opa_scale, ext, w, h); } } /*Post draw when the children are drawn*/ - else if(mode == LV_DESIGN_DRAW_POST) - { + else if(mode == LV_DESIGN_DRAW_POST) { } return true; @@ -479,10 +473,10 @@ static lv_color_t angle_to_mode_color(lv_cpicker_ext_t * ext, uint16_t angle) color = lv_color_hsv_to_rgb(angle % 360, ext->hsv.s, ext->hsv.v); break; case LV_CPICKER_COLOR_MODE_SATURATION: - color = lv_color_hsv_to_rgb(ext->hsv.h, (angle % 360) / 360.0 * 100.0, ext->hsv.v); + color = lv_color_hsv_to_rgb(ext->hsv.h, ((angle % 360) * 100) / 360, ext->hsv.v); break; case LV_CPICKER_COLOR_MODE_VALUE: - color = lv_color_hsv_to_rgb(ext->hsv.h, ext->hsv.s, (angle % 360) / 360.0 * 100.0); + color = lv_color_hsv_to_rgb(ext->hsv.h, ext->hsv.s, ((angle % 360) * 100) / 360); break; } return color; @@ -498,10 +492,10 @@ static uint16_t mode_color_to_angle(lv_cpicker_ext_t * ext) angle = ext->hsv.h; break; case LV_CPICKER_COLOR_MODE_SATURATION: - angle = ext->hsv.s / 100.0 * 360.0; + angle = (ext->hsv.s / 100) * 360.0; break; case LV_CPICKER_COLOR_MODE_VALUE: - angle = ext->hsv.v / 100.0 * 360.0; + angle = (ext->hsv.v / 100) * 360.0; break; } return angle; @@ -514,13 +508,13 @@ static lv_coord_t lv_cpicker_get_indicator_coord(lv_style_t * style, lv_cpicker_ { default: case LV_CPICKER_COLOR_MODE_HUE: - ind_pos += ext->hsv.h / 360.0 * ext->rect_gradient_w; + ind_pos += (ext->hsv.h * ext->rect_gradient_w) / 360.0; break; case LV_CPICKER_COLOR_MODE_SATURATION: - ind_pos += ext->hsv.s / 100.0 * ext->rect_gradient_w; + ind_pos += (ext->hsv.s * ext->rect_gradient_w) / 100; break; case LV_CPICKER_COLOR_MODE_VALUE: - ind_pos += ext->hsv.v / 100.0 * ext->rect_gradient_w; + ind_pos += (ext->hsv.v * ext->rect_gradient_w) / 100; break; } return ind_pos; @@ -673,12 +667,7 @@ static void lv_cpicker_draw_disc_gradient(lv_area_t * mask, lv_style_t * style, * only a given angular range */ lv_point_t center = {cx, cy}; - if(!lv_area_is_point_on(mask, ¢er) - /* - && (mask->x1 != cpicker->coords.x1 || mask->x2 != cpicker->coords.x2 - || mask->y1 != cpicker->coords.y1 || mask->y2 != cpicker->coords.y2) - */ - ) + if(!lv_area_is_point_on(mask, ¢er)) { /*get angle from center of object to each corners of the area*/ int16_t dr, ur, ul, dl; @@ -688,12 +677,12 @@ static void lv_cpicker_draw_disc_gradient(lv_area_t * mask, lv_style_t * style, dl = lv_atan2(mask->x1 - cx, mask->y2 - cy); /*check area position from object axis*/ - uint8_t left = (mask->x2 < cx && mask->x1 < cx); - uint8_t onYaxis = (mask->x2 > cx && mask->x1 < cx); - uint8_t right = (mask->x2 > cx && mask->x1 > cx); - uint8_t top = (mask->y2 < cy && mask->y1 < cy); - uint8_t onXaxis = (mask->y2 > cy && mask->y1 < cy); - uint8_t bottom = (mask->y2 > cy && mask->y1 > cy); + bool left = (mask->x2 < cx && mask->x1 < cx) ? true : false; + bool onYaxis = (mask->x2 > cx && mask->x1 < cx) ? true : false; + bool right = (mask->x2 > cx && mask->x1 > cx) ? true : false; + bool top = (mask->y2 < cy && mask->y1 < cy) ? true : false; + bool onXaxis = (mask->y2 > cy && mask->y1 < cy) ? true : false; + bool bottom = (mask->y2 > cy && mask->y1 > cy) ? true : false; /*store angular range*/ if(right && bottom) @@ -744,8 +733,8 @@ static void lv_cpicker_draw_disc_gradient(lv_area_t * mask, lv_style_t * style, } /*round to QF factor*/ - start_angle = start_angle/LV_CPICKER_DEF_QF*LV_CPICKER_DEF_QF; - end_angle = end_angle/LV_CPICKER_DEF_QF*LV_CPICKER_DEF_QF;; + start_angle = (start_angle/LV_CPICKER_DEF_QF) * LV_CPICKER_DEF_QF; + end_angle = (end_angle / LV_CPICKER_DEF_QF) * LV_CPICKER_DEF_QF; /*shift angle if necessary before adding offset*/ if((start_angle - LV_CPICKER_DEF_QF) < 0) @@ -883,7 +872,6 @@ static void lv_cpicker_disc_design(lv_obj_t * cpicker, lv_cpicker_draw_disc_indicator(mask, style, opa_scale, ext, cx, cy, r, rin, radius, center_ind_area); /* - //code to color the drawn area static uint32_t c = 0; lv_style_t style2; lv_style_copy(&style2, &lv_style_plain); @@ -1054,12 +1042,6 @@ static void lv_cpicker_draw_rect_indicator(lv_obj_t * cpicker, } lv_draw_rect(&(ext->rect_preview_area), mask, style, opa_scale); - /* - styleCopy.line.width = 10; - lv_draw_arc(cpicker->coords.x1 + 3*ext->rect_gradient_h/2, cpicker->coords.y1 + ext->rect_gradient_h/2, ext->rect_gradient_h / 2 + styleCopy.line.width + 2, mask, 180, 360, &styleCopy, opa_scale); - //lv_draw_arc(cpicker->coords.x1 + ext->rect_gradient_w - ext->rect_gradient_h/2, cpicker->coords.y1 + ext->rect_gradient_h/2, ext->rect_gradient_h / 2 + styleCopy.line.width + 2, mask, 0, 180, &styleCopy, opa_scale); - */ - /*draw the color position indicator*/ lv_coord_t ind_pos = lv_cpicker_get_indicator_coord(style, ext); /*save to refresh the area later*/ @@ -1282,7 +1264,7 @@ static lv_res_t lv_cpicker_reset_hsv_if_double_clicked(lv_obj_t * cpicker, { bool changed = false; - if(lv_tick_elaps(ext->last_click) < 400) + if(lv_tick_elaps(ext->last_click_time) < 400) { switch(ext->color_mode) { @@ -1310,7 +1292,7 @@ static lv_res_t lv_cpicker_reset_hsv_if_double_clicked(lv_obj_t * cpicker, } ext->prev_hsv = ext->hsv; } - ext->last_click = lv_tick_get(); + ext->last_click_time = lv_tick_get(); lv_res_t res = LV_RES_OK; if (changed) @@ -1569,34 +1551,23 @@ static void lv_cpicker_invalidate_disc_indicator_line(lv_disp_t * disp, lv_style point2.y = y2; lv_area_t line_area; - //if(LV_MATH_ABS(point1.x - point2.x) > LV_MATH_ABS(point1.y - point2.y)) - //{ /*Steps less in y than x -> rather horizontal*/ if(point1.x < point2.x) { line_area.x1 = point1.x; - //line_area.y1 = point1.y; line_area.x2 = point2.x; - //line_area.y2 = point2.y; } else { line_area.x1 = point2.x; - //line_area.y1 = point2.y; line_area.x2 = point1.x; - //line_area.y2 = point1.y; } - //} else { + /*Steps less in x than y -> rather vertical*/ if(point1.y < point2.y) { - //line_area.x1 = point1.x; line_area.y1 = point1.y; - //line_area.x2 = point2.x; line_area.y2 = point2.y; } else { - //line_area.x1 = point2.x; line_area.y1 = point2.y; - //line_area.x2 = point1.x; line_area.y2 = point1.y; } - //} line_area.x1 -= 2*ext->indicator.style->line.width; line_area.y1 -= 2*ext->indicator.style->line.width; diff --git a/src/lv_objx/lv_cpicker.h b/src/lv_objx/lv_cpicker.h index 987800e85..5a542dd02 100644 --- a/src/lv_objx/lv_cpicker.h +++ b/src/lv_objx/lv_cpicker.h @@ -30,33 +30,6 @@ extern "C" { /********************** * TYPEDEFS **********************/ -/*Data of colorpicker*/ -typedef struct { - lv_color_hsv_t hsv; - struct - { - lv_style_t * style; - uint8_t type; - } indicator; - lv_color_hsv_t prev_hsv; - uint16_t prev_pos; - uint8_t color_mode:2; - uint8_t color_mode_fixed:1; - uint8_t type:1; - uint32_t last_click; - lv_area_t rect_preview_area; - lv_area_t rect_gradient_area; - lv_coord_t rect_gradient_w; - lv_coord_t rect_gradient_h; -} lv_cpicker_ext_t; - -/*Styles*/ -enum { - LV_CPICKER_STYLE_MAIN, - LV_CPICKER_STYLE_INDICATOR, -}; -typedef uint8_t lv_cpicker_style_t; - enum { LV_CPICKER_INDICATOR_NONE, LV_CPICKER_INDICATOR_LINE, @@ -78,6 +51,36 @@ enum { }; typedef uint8_t lv_cpicker_color_mode_t; + + +/*Data of colorpicker*/ +typedef struct { + lv_color_hsv_t hsv; + lv_color_hsv_t prev_hsv; + struct + { + lv_style_t * style; + lv_cpicker_indicator_type_t type; + } indicator; + uint32_t last_click_time; + lv_area_t rect_preview_area; + lv_area_t rect_gradient_area; + lv_coord_t rect_gradient_w; + lv_coord_t rect_gradient_h; + uint16_t prev_pos; + lv_cpicker_color_mode_t color_mode:2; + uint8_t color_mode_fixed:1; + lv_cpicker_type_t type:1; +} lv_cpicker_ext_t; + +/*Styles*/ +enum { + LV_CPICKER_STYLE_MAIN, + LV_CPICKER_STYLE_INDICATOR, +}; +typedef uint8_t lv_cpicker_style_t; + + /********************** * GLOBAL PROTOTYPES **********************/ From 2600c1c3d97f0d879b7440d9f1251c6724d450b0 Mon Sep 17 00:00:00 2001 From: Gabor Kiss-Vamosi Date: Tue, 1 Oct 2019 21:16:30 +0200 Subject: [PATCH 23/25] cpicker: rework --- src/lv_objx/lv_cpicker.c | 1891 ++++++++++++-------------------------- src/lv_objx/lv_cpicker.h | 52 +- 2 files changed, 601 insertions(+), 1342 deletions(-) diff --git a/src/lv_objx/lv_cpicker.c b/src/lv_objx/lv_cpicker.c index ec0c727a6..6c97f61a0 100644 --- a/src/lv_objx/lv_cpicker.c +++ b/src/lv_objx/lv_cpicker.c @@ -19,6 +19,8 @@ /********************* * DEFINES *********************/ +#define LV_OBJX_NAME "lv_cpicker" + #ifndef LV_CPICKER_DEF_TYPE #define LV_CPICKER_DEF_TYPE LV_CPICKER_TYPE_DISC #endif @@ -39,28 +41,11 @@ #define LV_CPICKER_DEF_HSV ((lv_color_hsv_t){LV_CPICKER_DEF_HUE, LV_CPICKER_DEF_SATURATION, LV_CPICKER_DEF_VALUE}) #endif -#ifndef LV_CPICKER_DEF_INDICATOR_TYPE -#define LV_CPICKER_DEF_INDICATOR_TYPE LV_CPICKER_INDICATOR_CIRCLE -#endif - #ifndef LV_CPICKER_DEF_QF /*quantization factor*/ #define LV_CPICKER_DEF_QF 3 #endif -/*for rectangular mode the QF can be down to 1*/ -/* -#define LV_CPICKER_MINIMUM_QF 4 -#if LV_CPICKER_DEF_QF < LV_CPICKER_MINIMUM_QF -#undef LV_CPICKER_DEF_QF -#define LV_CPICKER_DEF_QF LV_CPICKER_MINIMUM_QF -#endif - */ - -#ifndef LV_CPICKER_USE_TRI /*Use triangle approximation instead of arc*/ -#define LV_CPICKER_USE_TRI 1 -#endif - -#define TRI_OFFSET 4 +#define TRI_OFFSET 2 /********************** * TYPEDEFS @@ -72,15 +57,17 @@ static bool lv_cpicker_design(lv_obj_t * cpicker, const lv_area_t * mask, lv_design_mode_t mode); static lv_res_t lv_cpicker_signal(lv_obj_t * cpicker, lv_signal_t sign, void * param); -static void lv_cpicker_disc_design(lv_obj_t * cpicker, - lv_area_t * mask, lv_style_t * style, lv_opa_t opa_scale, - lv_cpicker_ext_t * ext, - lv_coord_t w, lv_coord_t h, - lv_coord_t cx, lv_coord_t cy, uint16_t r); -static void lv_cpicker_rect_design(lv_obj_t * cpicker, - lv_area_t * mask, lv_style_t * style, lv_opa_t opa_scale, - lv_cpicker_ext_t * ext, - lv_coord_t w, lv_coord_t h); +static void invalidate_indic(lv_obj_t * cpicker); +static void draw_rect_grad(lv_obj_t * cpicker, const lv_area_t * mask, lv_opa_t opa_scale); +static void draw_disc_grad(lv_obj_t * cpicker, const lv_area_t * mask, lv_opa_t opa_scale); +static void draw_indic(lv_obj_t * cpicker, const lv_area_t * mask, lv_opa_t opa_scale); + +static void next_color_mode(lv_obj_t * cpicker); +static lv_res_t double_click_reset(lv_obj_t * cpicker); +static void refr_indic_pos(lv_obj_t * cpicker); +static lv_color_t angle_to_mode_color(lv_obj_t * cpicker, uint16_t angle); +static uint16_t get_angle(lv_obj_t * cpicker); + /********************** * STATIC VARIABLES **********************/ @@ -119,9 +106,8 @@ lv_obj_t * lv_cpicker_create(lv_obj_t * par, const lv_obj_t * copy) /*Initialize the allocated 'ext' */ ext->hsv = LV_CPICKER_DEF_HSV; - ext->prev_hsv = ext->hsv; - ext->indicator.style = &lv_style_plain; - ext->indicator.type = LV_CPICKER_DEF_INDICATOR_TYPE; + ext->indic.style = &lv_style_plain; + ext->indic.colored = 1; ext->color_mode = LV_CPICKER_COLOR_MODE_HUE; ext->color_mode_fixed = 0; ext->last_click_time = 0; @@ -132,6 +118,8 @@ lv_obj_t * lv_cpicker_create(lv_obj_t * par, const lv_obj_t * copy) /*If no copy do the basic initialization*/ if(copy == NULL) { + lv_obj_set_protect(new_cpicker, LV_PROTECT_PRESS_LOST); + refr_indic_pos(new_cpicker); lv_theme_t * th = lv_theme_get_current(); if(th) { lv_cpicker_set_style(new_cpicker, LV_CPICKER_STYLE_MAIN, th->style.bg); @@ -142,10 +130,17 @@ lv_obj_t * lv_cpicker_create(lv_obj_t * par, const lv_obj_t * copy) /*Copy 'copy'*/ else { lv_cpicker_ext_t * copy_ext = lv_obj_get_ext_attr(copy); + ext->type = copy_ext->type; + ext->color_mode = copy_ext->color_mode; + ext->color_mode_fixed = copy_ext->color_mode_fixed; + ext->hsv = copy_ext->hsv; + ext->indic.colored = copy_ext->indic.colored; + ext->indic.style = copy_ext->indic.style; /*Refresh the style with new signal function*/ lv_obj_refresh_style(new_cpicker); } + refr_indic_pos(new_cpicker); LV_LOG_INFO("color_picker created"); @@ -163,10 +158,14 @@ lv_obj_t * lv_cpicker_create(lv_obj_t * par, const lv_obj_t * copy) */ void lv_cpicker_set_type(lv_obj_t * cpicker, lv_cpicker_type_t type) { + LV_ASSERT_OBJ(cpicker, LV_OBJX_NAME); + lv_cpicker_ext_t * ext = lv_obj_get_ext_attr(cpicker); if(ext->type == type) return; ext->type = type; + lv_obj_refresh_ext_draw_pad(cpicker); + refr_indic_pos(cpicker); lv_obj_invalidate(cpicker); } @@ -179,6 +178,8 @@ void lv_cpicker_set_type(lv_obj_t * cpicker, lv_cpicker_type_t type) */ void lv_cpicker_set_style(lv_obj_t * cpicker, lv_cpicker_style_t type, lv_style_t * style) { + LV_ASSERT_OBJ(cpicker, LV_OBJX_NAME); + lv_cpicker_ext_t * ext = lv_obj_get_ext_attr(cpicker); switch(type) { @@ -186,24 +187,12 @@ void lv_cpicker_set_style(lv_obj_t * cpicker, lv_cpicker_style_t type, lv_style_ lv_obj_set_style(cpicker, style); break; case LV_CPICKER_STYLE_INDICATOR: - ext->indicator.style = style; + ext->indic.style = style; lv_obj_invalidate(cpicker); break; } } -/** - * Set a type of a colorpicker indicator. - * @param cpicker pointer to colorpicker object - * @param type indicator type - */ -void lv_cpicker_set_indicator_type(lv_obj_t * cpicker, lv_cpicker_indicator_type_t type) -{ - lv_cpicker_ext_t * ext = lv_obj_get_ext_attr(cpicker); - ext->indicator.type = type; - lv_obj_invalidate(cpicker); -} - /** * Set the current hue of a colorpicker. * @param cpicker pointer to colorpicker object @@ -211,11 +200,13 @@ void lv_cpicker_set_indicator_type(lv_obj_t * cpicker, lv_cpicker_indicator_type */ void lv_cpicker_set_hue(lv_obj_t * cpicker, uint16_t hue) { + LV_ASSERT_OBJ(cpicker, LV_OBJX_NAME); + lv_cpicker_ext_t * ext = lv_obj_get_ext_attr(cpicker); ext->hsv.h = hue % 360; - lv_obj_invalidate(cpicker); + if(ext->color_mode_fixed == LV_CPICKER_COLOR_MODE_HUE) refr_indic_pos(cpicker); } /** @@ -225,11 +216,13 @@ void lv_cpicker_set_hue(lv_obj_t * cpicker, uint16_t hue) */ void lv_cpicker_set_saturation(lv_obj_t * cpicker, uint8_t saturation) { + LV_ASSERT_OBJ(cpicker, LV_OBJX_NAME); + lv_cpicker_ext_t * ext = lv_obj_get_ext_attr(cpicker); ext->hsv.s = saturation % 100; - lv_obj_invalidate(cpicker); + if(ext->color_mode_fixed == LV_CPICKER_COLOR_MODE_SATURATION) refr_indic_pos(cpicker); } /** @@ -239,11 +232,13 @@ void lv_cpicker_set_saturation(lv_obj_t * cpicker, uint8_t saturation) */ void lv_cpicker_set_value(lv_obj_t * cpicker, uint8_t val) { + LV_ASSERT_OBJ(cpicker, LV_OBJX_NAME); + lv_cpicker_ext_t * ext = lv_obj_get_ext_attr(cpicker); ext->hsv.v = val % 100; - lv_obj_invalidate(cpicker); + if(ext->color_mode_fixed == LV_CPICKER_COLOR_MODE_VALUE) refr_indic_pos(cpicker); } /** @@ -253,10 +248,13 @@ void lv_cpicker_set_value(lv_obj_t * cpicker, uint8_t val) */ void lv_cpicker_set_hsv(lv_obj_t * cpicker, lv_color_hsv_t hsv) { + LV_ASSERT_OBJ(cpicker, LV_OBJX_NAME); + lv_cpicker_ext_t * ext = lv_obj_get_ext_attr(cpicker); ext->hsv = hsv; + refr_indic_pos(cpicker); lv_obj_invalidate(cpicker); } @@ -267,6 +265,8 @@ void lv_cpicker_set_hsv(lv_obj_t * cpicker, lv_color_hsv_t hsv) */ void lv_cpicker_set_color(lv_obj_t * cpicker, lv_color_t color) { + LV_ASSERT_OBJ(cpicker, LV_OBJX_NAME); + lv_cpicker_set_hsv(cpicker, lv_color_rgb_to_hsv(color.ch.red, color.ch.green, color.ch.blue)); } @@ -277,9 +277,13 @@ void lv_cpicker_set_color(lv_obj_t * cpicker, lv_color_t color) */ void lv_cpicker_set_color_mode(lv_obj_t * cpicker, lv_cpicker_color_mode_t mode) { + LV_ASSERT_OBJ(cpicker, LV_OBJX_NAME); + lv_cpicker_ext_t * ext = lv_obj_get_ext_attr(cpicker); ext->color_mode = mode; + refr_indic_pos(cpicker); + lv_obj_invalidate(cpicker); } /** @@ -289,11 +293,27 @@ void lv_cpicker_set_color_mode(lv_obj_t * cpicker, lv_cpicker_color_mode_t mode) */ void lv_cpicker_set_color_mode_fixed(lv_obj_t * cpicker, bool fixed) { + LV_ASSERT_OBJ(cpicker, LV_OBJX_NAME); + lv_cpicker_ext_t * ext = lv_obj_get_ext_attr(cpicker); ext->color_mode_fixed = fixed; } +/** + * Make the indicator to be colored to the current color + * @param cpicker pointer to colorpicker object + * @param en true: color the indicator; false: not color the indicator + */ +void lv_cpicker_set_indic_colored(lv_obj_t * cpicker, bool en) +{ + LV_ASSERT_OBJ(cpicker, LV_OBJX_NAME); + + lv_cpicker_ext_t * ext = lv_obj_get_ext_attr(cpicker); + ext->indic.colored = en ? 1 : 0; + invalidate_indic(cpicker); +} + /*===================== * Getter functions *====================*/ @@ -305,6 +325,8 @@ void lv_cpicker_set_color_mode_fixed(lv_obj_t * cpicker, bool fixed) */ lv_cpicker_color_mode_t lv_cpicker_get_color_mode(lv_obj_t * cpicker) { + LV_ASSERT_OBJ(cpicker, LV_OBJX_NAME); + lv_cpicker_ext_t * ext = lv_obj_get_ext_attr(cpicker); return ext->color_mode; @@ -317,6 +339,8 @@ lv_cpicker_color_mode_t lv_cpicker_get_color_mode(lv_obj_t * cpicker) */ bool lv_cpicker_get_color_mode_fixed(lv_obj_t * cpicker) { + LV_ASSERT_OBJ(cpicker, LV_OBJX_NAME); + lv_cpicker_ext_t * ext = lv_obj_get_ext_attr(cpicker); return ext->color_mode_fixed; @@ -328,15 +352,17 @@ bool lv_cpicker_get_color_mode_fixed(lv_obj_t * cpicker) * @param type which style should be get * @return style pointer to the style */ -lv_style_t * lv_cpicker_get_style(const lv_obj_t * cpicker, lv_cpicker_style_t type) +const lv_style_t * lv_cpicker_get_style(const lv_obj_t * cpicker, lv_cpicker_style_t type) { + LV_ASSERT_OBJ(cpicker, LV_OBJX_NAME); + lv_cpicker_ext_t * ext = lv_obj_get_ext_attr(cpicker); switch(type) { case LV_CPICKER_STYLE_MAIN: return lv_obj_get_style(cpicker); case LV_CPICKER_STYLE_INDICATOR: - return ext->indicator.style; + return ext->indic.style; default: return NULL; } @@ -352,6 +378,8 @@ lv_style_t * lv_cpicker_get_style(const lv_obj_t * cpicker, lv_cpicker_style_t t */ uint16_t lv_cpicker_get_hue(lv_obj_t * cpicker) { + LV_ASSERT_OBJ(cpicker, LV_OBJX_NAME); + lv_cpicker_ext_t * ext = lv_obj_get_ext_attr(cpicker); return ext->hsv.h; @@ -364,6 +392,8 @@ uint16_t lv_cpicker_get_hue(lv_obj_t * cpicker) */ uint8_t lv_cpicker_get_saturation(lv_obj_t * cpicker) { + LV_ASSERT_OBJ(cpicker, LV_OBJX_NAME); + lv_cpicker_ext_t * ext = lv_obj_get_ext_attr(cpicker); return ext->hsv.s; @@ -376,6 +406,8 @@ uint8_t lv_cpicker_get_saturation(lv_obj_t * cpicker) */ uint8_t lv_cpicker_get_value(lv_obj_t * cpicker) { + LV_ASSERT_OBJ(cpicker, LV_OBJX_NAME); + lv_cpicker_ext_t * ext = lv_obj_get_ext_attr(cpicker); return ext->hsv.v; @@ -388,6 +420,8 @@ uint8_t lv_cpicker_get_value(lv_obj_t * cpicker) */ lv_color_hsv_t lv_cpicker_get_hsv(lv_obj_t * cpicker) { + LV_ASSERT_OBJ(cpicker, LV_OBJX_NAME); + lv_cpicker_ext_t * ext = lv_obj_get_ext_attr(cpicker); return ext->hsv; @@ -400,19 +434,31 @@ lv_color_hsv_t lv_cpicker_get_hsv(lv_obj_t * cpicker) */ lv_color_t lv_cpicker_get_color(lv_obj_t * cpicker) { + LV_ASSERT_OBJ(cpicker, LV_OBJX_NAME); + lv_cpicker_ext_t * ext = lv_obj_get_ext_attr(cpicker); return lv_color_hsv_to_rgb(ext->hsv.h, ext->hsv.s, ext->hsv.v); } +/** + * Whether the indicator is colored to the current color or not + * @param cpicker pointer to colorpicker object + * @return true: color the indicator; false: not color the indicator + */ +bool lv_cpicker_get_indic_colored(lv_obj_t * cpicker) +{ + LV_ASSERT_OBJ(cpicker, LV_OBJX_NAME); + + lv_cpicker_ext_t * ext = lv_obj_get_ext_attr(cpicker); + + return ext->indic.colored ? true : false; +} + /*===================== * Other functions *====================*/ -/* - * New object specific "other" functions come here - */ - /********************** * STATIC FUNCTIONS **********************/ @@ -437,24 +483,15 @@ static bool lv_cpicker_design(lv_obj_t * cpicker, const lv_area_t * mask, lv_des /*Draw the object*/ else if(mode == LV_DESIGN_DRAW_MAIN) { lv_cpicker_ext_t * ext = lv_obj_get_ext_attr(cpicker); - lv_style_t * style = lv_cpicker_get_style(cpicker, LV_CPICKER_STYLE_MAIN); - - static lv_style_t styleCopy; - lv_style_copy(&styleCopy, style); - lv_opa_t opa_scale = lv_obj_get_opa_scale(cpicker); - lv_coord_t w = lv_obj_get_width(cpicker); - lv_coord_t h = lv_obj_get_height(cpicker); - if(ext->type == LV_CPICKER_TYPE_DISC) { - lv_coord_t cx = cpicker->coords.x1 + (w / 2); - lv_coord_t cy = cpicker->coords.y1 + (h / 2); - uint16_t r = LV_MATH_MIN(w, h) / 2; - lv_cpicker_disc_design(cpicker, mask, &styleCopy, opa_scale, ext, w, h, cx, cy, r); + draw_disc_grad(cpicker, mask, opa_scale); } else if(ext->type == LV_CPICKER_TYPE_RECT) { - lv_cpicker_rect_design(cpicker, mask, &styleCopy, opa_scale, ext, w, h); + draw_rect_grad(cpicker, mask, opa_scale); } + + draw_indic(cpicker, mask, opa_scale); } /*Post draw when the children are drawn*/ else if(mode == LV_DESIGN_DRAW_POST) { @@ -463,8 +500,478 @@ static bool lv_cpicker_design(lv_obj_t * cpicker, const lv_area_t * mask, lv_des return true; } -static lv_color_t angle_to_mode_color(lv_cpicker_ext_t * ext, uint16_t angle) +static void draw_disc_grad(lv_obj_t * cpicker, const lv_area_t * mask, lv_opa_t opa_scale) { + int16_t start_angle = 0; /*Default*/ + int16_t end_angle = 360 - LV_CPICKER_DEF_QF; /*Default*/ + + lv_coord_t w = lv_obj_get_width(cpicker); + lv_coord_t h = lv_obj_get_height(cpicker); + lv_coord_t cx = cpicker->coords.x1 + w / 2; + lv_coord_t cy = cpicker->coords.y1 + h / 2; + lv_coord_t r = w / 2; + + /*if the mask does not include the center of the object + * redrawing all the wheel is not necessary; + * only a given angular range + */ + lv_point_t center = {cx, cy}; + if(!lv_area_is_point_on(mask, ¢er)) + { + /*get angle from center of object to each corners of the area*/ + int16_t dr, ur, ul, dl; + dr = lv_atan2(mask->x2 - cx, mask->y2 - cy); + ur = lv_atan2(mask->x2 - cx, mask->y1 - cy); + ul = lv_atan2(mask->x1 - cx, mask->y1 - cy); + dl = lv_atan2(mask->x1 - cx, mask->y2 - cy); + + /*check area position from object axis*/ + bool left = (mask->x2 < cx && mask->x1 < cx) ? true : false; + bool onYaxis = (mask->x2 > cx && mask->x1 < cx) ? true : false; + bool right = (mask->x2 > cx && mask->x1 > cx) ? true : false; + bool top = (mask->y2 < cy && mask->y1 < cy) ? true : false; + bool onXaxis = (mask->y2 > cy && mask->y1 < cy) ? true : false; + bool bottom = (mask->y2 > cy && mask->y1 > cy) ? true : false; + + /*store angular range*/ + if(right && bottom) { + start_angle = dl; + end_angle = ur; + } + else if(right && onXaxis) { + start_angle = dl; + end_angle = ul; + } + else if(right && top) { + start_angle = dr; + end_angle = ul; + } + else if(onYaxis && top) { + start_angle = dr; + end_angle = dl; + } + else if(left && top) { + start_angle = ur; + end_angle = dl; + } + else if(left && onXaxis) { + start_angle = ur; + end_angle = dr; + } + else if(left && bottom) { + start_angle = ul; + end_angle = dr; + } + else if(onYaxis && bottom) { + start_angle = ul; + end_angle = ur; + } + + /*rollover angle*/ + if(start_angle > end_angle) end_angle += 360; + + /*round to QF factor*/ + start_angle = (start_angle/LV_CPICKER_DEF_QF) * LV_CPICKER_DEF_QF; + end_angle = (end_angle / LV_CPICKER_DEF_QF) * LV_CPICKER_DEF_QF; + + /*shift angle if necessary before adding offset*/ + if((start_angle - LV_CPICKER_DEF_QF) < 0) + { + start_angle += 360; + end_angle += 360; + } + + /*ensure overlapping by adding offset*/ + start_angle -= LV_CPICKER_DEF_QF; + end_angle += LV_CPICKER_DEF_QF; + } + + lv_point_t triangle_points[3]; + lv_style_t style; + lv_style_copy(&style, &lv_style_plain); + for(uint16_t i = start_angle; i <= end_angle; i+= LV_CPICKER_DEF_QF) + { + style.body.main_color = angle_to_mode_color(cpicker, i); + style.body.grad_color = style.body.main_color; + + triangle_points[0].x = cx; + triangle_points[0].y = cy; + + triangle_points[1].x = cx + (r * lv_trigo_sin(i) >> LV_TRIGO_SHIFT); + triangle_points[1].y = cy + (r * lv_trigo_sin(i + 90) >> LV_TRIGO_SHIFT); + + if(i == end_angle || i == (360 - LV_CPICKER_DEF_QF)) { + /*the last triangle is drawn without additional overlapping pixels*/ + triangle_points[2].x = cx + (r * lv_trigo_sin(i + LV_CPICKER_DEF_QF) >> LV_TRIGO_SHIFT); + triangle_points[2].y = cy + (r * lv_trigo_sin(i + LV_CPICKER_DEF_QF + 90) >> LV_TRIGO_SHIFT); + } + else { + triangle_points[2].x = cx + (r * lv_trigo_sin(i + LV_CPICKER_DEF_QF + TRI_OFFSET) >> LV_TRIGO_SHIFT); + triangle_points[2].y = cy + (r * lv_trigo_sin(i + LV_CPICKER_DEF_QF + TRI_OFFSET + 90) >> LV_TRIGO_SHIFT); + } + + lv_draw_triangle(triangle_points, mask, &style, LV_OPA_COVER); + } + + /*Mask out the center area*/ + const lv_style_t * style_main = lv_cpicker_get_style(cpicker, LV_CPICKER_STYLE_MAIN); + lv_style_copy(&style, style_main); + style.body.radius = LV_RADIUS_CIRCLE; + lv_area_t area_mid; + lv_area_copy(&area_mid, &cpicker->coords); + area_mid.x1 += style_main->line.width; + area_mid.y1 += style_main->line.width; + area_mid.x2 -= style_main->line.width; + area_mid.y2 -= style_main->line.width; + + lv_draw_rect(&area_mid, mask, &style, opa_scale); +} + +static void draw_rect_grad(lv_obj_t * cpicker, const lv_area_t * mask, lv_opa_t opa_scale) +{ + lv_style_t style; + lv_style_copy(&style, lv_cpicker_get_style(cpicker, LV_CPICKER_STYLE_MAIN)); + + lv_area_t grad_area; + lv_obj_get_coords(cpicker, &grad_area); + + if(style.body.radius) { + lv_coord_t h = lv_obj_get_height(cpicker); + lv_coord_t r = style.body.radius; + if(r > h / 2) r = h / 2; + /*Make the gradient area smaller with a half circle on both ends*/ + grad_area.x1 += r; + grad_area.x2 -= r; + + /*Draw the left rounded end*/ + lv_area_t rounded_edge_area; + lv_obj_get_coords(cpicker, &rounded_edge_area); + rounded_edge_area.x2 = rounded_edge_area.x1 + 2 * r; + + style.body.main_color = angle_to_mode_color(cpicker, 0); + style.body.grad_color = style.body.main_color; + + lv_draw_rect(&rounded_edge_area, mask, &style, opa_scale); + + /*Draw the right rounded end*/ + lv_obj_get_coords(cpicker, &rounded_edge_area); + rounded_edge_area.x1 = rounded_edge_area.x2 - 2 * r; + + style.body.main_color = angle_to_mode_color(cpicker, 359); + style.body.grad_color = style.body.main_color; + + lv_draw_rect(&rounded_edge_area, mask, &style, opa_scale); + } + + lv_coord_t grad_w = lv_area_get_width(&grad_area); + uint16_t i_step = LV_MATH_MAX(LV_CPICKER_DEF_QF, 360 / grad_w); + style.body.radius = 0; + style.body.border.width = 0; + style.body.shadow.width = 0; + style.body.opa = LV_OPA_COVER; + + for(uint16_t i = 0; i < 360; i += i_step) { + style.body.main_color = angle_to_mode_color(cpicker, i); + style.body.grad_color = style.body.main_color; + + /*the following attribute might need changing between index to add border, shadow, radius etc*/ + lv_area_t rect_area; + + /*scale angle (hue/sat/val) to linear coordinate*/ + lv_coord_t xi = (i * grad_w) / 360; + + rect_area.x1 = LV_MATH_MIN(grad_area.x1 + xi, grad_area.x1 + grad_w - i_step); + rect_area.y1 = grad_area.y1; + rect_area.x2 = rect_area.x1 + i_step; + rect_area.y2 = grad_area.y2; + + lv_draw_rect(&rect_area, mask, &style, opa_scale); + } +} +/** + * Should roughly match up with `lv_cpicker_invalidate_disc_indicator_circle` + */ +static void draw_indic(lv_obj_t * cpicker, const lv_area_t * mask, lv_opa_t opa_scale) +{ + lv_cpicker_ext_t * ext = lv_obj_get_ext_attr(cpicker); + const lv_style_t * style_main = lv_cpicker_get_style(cpicker, LV_CPICKER_STYLE_MAIN); + const lv_style_t * style_indic = lv_cpicker_get_style(cpicker, LV_CPICKER_STYLE_INDICATOR); + + lv_coord_t h = lv_obj_get_height(cpicker); + uint16_t r; + if(ext->type == LV_CPICKER_TYPE_DISC) r = style_main->line.width / 2; + else if(ext->type == LV_CPICKER_TYPE_RECT) r = h / 2; + + lv_area_t ind_area; + ind_area.x1 = cpicker->coords.x1 + ext->indic.pos.x - r - style_indic->body.padding.left; + ind_area.y1 = cpicker->coords.y1 + ext->indic.pos.y - r - style_indic->body.padding.right; + ind_area.x2 = cpicker->coords.x1 + ext->indic.pos.x + r + style_indic->body.padding.top; + ind_area.y2 = cpicker->coords.y1 + ext->indic.pos.y + r + style_indic->body.padding.bottom; + + lv_style_t style_cir; + lv_style_copy(&style_cir, ext->indic.style); + style_cir.body.radius = LV_RADIUS_CIRCLE; + + if(ext->indic.colored) { + style_cir.body.main_color = lv_cpicker_get_color(cpicker); + style_cir.body.grad_color = style_cir.body.main_color; + } + + + lv_draw_rect(&ind_area, mask, &style_cir, opa_scale); +} + +/** + * Signal function of the color_picker + * @param cpicker pointer to a color_picker object + * @param sign a signal type from lv_signal_t enum + * @param param pointer to a signal specific variable + * @return LV_RES_OK: the object is not deleted in the function; LV_RES_INV: the object is deleted + */ +static lv_res_t lv_cpicker_signal(lv_obj_t * cpicker, lv_signal_t sign, void * param) +{ + /* Include the ancient signal function */ + lv_res_t res = ancestor_signal(cpicker, sign, param); + if(res != LV_RES_OK) return res; + if(sign == LV_SIGNAL_GET_TYPE) return lv_obj_handle_get_type_signal(param, LV_OBJX_NAME); + + lv_cpicker_ext_t * ext = lv_obj_get_ext_attr(cpicker); + + if(sign == LV_SIGNAL_CLEANUP) { + /*Nothing to cleanup. (No dynamically allocated memory in 'ext')*/ + } else if(sign == LV_SIGNAL_REFR_EXT_DRAW_PAD) { + const lv_style_t * style_indic = lv_cpicker_get_style(cpicker, LV_CPICKER_STYLE_INDICATOR); + lv_coord_t indic_pad = LV_MATH_MAX(style_indic->body.padding.left, style_indic->body.padding.right); + indic_pad = LV_MATH_MAX(indic_pad, style_indic->body.padding.top); + indic_pad = LV_MATH_MAX(indic_pad, style_indic->body.padding.bottom); + + if(ext->type == LV_CPICKER_TYPE_RECT) indic_pad += LV_MATH_MAX(indic_pad, lv_obj_get_height(cpicker) / 2); + + cpicker->ext_draw_pad = LV_MATH_MAX(cpicker->ext_draw_pad, indic_pad); + } else if(sign == LV_SIGNAL_CORD_CHG) { + /*Refresh extended draw area to make knob visible*/ + if(lv_obj_get_width(cpicker) != lv_area_get_width(param) || + lv_obj_get_height(cpicker) != lv_area_get_height(param)) + { + lv_obj_refresh_ext_draw_pad(cpicker); + refr_indic_pos(cpicker); + } + } else if(sign == LV_SIGNAL_STYLE_CHG) { + /*Refresh extended draw area to make knob visible*/ + lv_obj_refresh_ext_draw_pad(cpicker); + refr_indic_pos(cpicker); + } + else if(sign == LV_SIGNAL_CONTROL) { + uint32_t c = *((uint32_t *)param); /*uint32_t because can be UTF-8*/ + if(c == LV_KEY_RIGHT || c == LV_KEY_UP) { + lv_color_hsv_t hsv_cur; + hsv_cur = ext->hsv; + + switch(ext->color_mode) { + case LV_CPICKER_COLOR_MODE_HUE: + hsv_cur.h = (ext->hsv.h + 1) % 360; + break; + case LV_CPICKER_COLOR_MODE_SATURATION: + hsv_cur.s = (ext->hsv.s + 1) % 100; + break; + case LV_CPICKER_COLOR_MODE_VALUE: + hsv_cur.v = (ext->hsv.v + 1) % 100; + break; + } + + lv_cpicker_set_hsv(cpicker, hsv_cur); + + res = lv_event_send(cpicker, LV_EVENT_VALUE_CHANGED, NULL); + if(res != LV_RES_OK) return res; + } + else if(c == LV_KEY_LEFT || c == LV_KEY_DOWN) { + lv_color_hsv_t hsv_cur; + hsv_cur = ext->hsv; + + switch(ext->color_mode) { + case LV_CPICKER_COLOR_MODE_HUE: + hsv_cur.h = ext->hsv.h > 0?(ext->hsv.h - 1) : 360; + break; + case LV_CPICKER_COLOR_MODE_SATURATION: + hsv_cur.s = ext->hsv.s > 0?(ext->hsv.s - 1) : 100; + break; + case LV_CPICKER_COLOR_MODE_VALUE: + hsv_cur.v = ext->hsv.v > 0?(ext->hsv.v - 1) : 100; + break; + } + + lv_cpicker_set_hsv(cpicker, hsv_cur); + + res = lv_event_send(cpicker, LV_EVENT_VALUE_CHANGED, NULL); + if(res != LV_RES_OK) return res; + } + } + else if(sign == LV_SIGNAL_PRESSED) { + res = double_click_reset(cpicker); + ext->last_change_time = lv_tick_get(); + if(res != LV_RES_OK) return res; + } else if(sign == LV_SIGNAL_PRESSING){ + lv_indev_t * indev = lv_indev_get_act(); + lv_point_t p; + lv_indev_get_point(indev, &p); + p.x -= cpicker->coords.x1; + p.y -= cpicker->coords.y1; + + /*Ignore pressing in the inner area*/ + uint16_t w = lv_obj_get_width(cpicker); + + int16_t angle = 0; + + if(ext->type == LV_CPICKER_TYPE_RECT) { + angle = (p.x * 360) / w; + if(angle < 0) angle = 0; + if(angle >= 360) angle = 359; + + } else if(ext->type == LV_CPICKER_TYPE_DISC) { + const lv_style_t * style_main = lv_cpicker_get_style(cpicker, LV_CPICKER_STYLE_MAIN); + lv_coord_t r = w / 2; + p.x -= r; + p.y -= r; + r -= style_main->line.width; + if(p.x * p.x + p.y * p.y < r * r) return res; + + angle = lv_atan2(p.x, p.y) % 360; + } + + bool changed = false; + switch(ext->color_mode) { + case LV_CPICKER_COLOR_MODE_HUE: + if(ext->hsv.h != angle) { + lv_cpicker_set_hue(cpicker, angle); + changed = true; + } + break; + case LV_CPICKER_COLOR_MODE_SATURATION: + angle = (angle * 100) / 360; + if(ext->hsv.s != angle) { + lv_cpicker_set_saturation(cpicker, angle); + changed = true; + } + break; + case LV_CPICKER_COLOR_MODE_VALUE: + angle = (angle * 100) / 360; + if(ext->hsv.v != angle) { + lv_cpicker_set_value(cpicker, angle); + changed = true; + } + break; + } + + refr_indic_pos(cpicker); + + uint32_t diff = lv_tick_elaps(ext->last_change_time); + if(diff > indev->driver.long_press_time * 2 && !ext->color_mode_fixed) { + next_color_mode(cpicker); + lv_indev_wait_release(lv_indev_get_act()); + } + + if(changed) { + ext->last_change_time = lv_tick_get(); + } + + res = lv_event_send(cpicker, LV_EVENT_VALUE_CHANGED, NULL); + if(res != LV_RES_OK) return res; + } + + return res; +} + +static void next_color_mode(lv_obj_t * cpicker ) +{ + lv_cpicker_ext_t * ext = lv_obj_get_ext_attr(cpicker); + ext->color_mode = (ext->color_mode + 1) % 3; + refr_indic_pos(cpicker); + lv_obj_invalidate(cpicker); +} + + +/** + * Indicator points need to match those set in lv_cpicker_disc_design/lv_cpicker_rect_design + */ +static void invalidate_indic(lv_obj_t * cpicker) +{ + lv_cpicker_ext_t * ext = lv_obj_get_ext_attr(cpicker); + const lv_style_t * style_main = lv_cpicker_get_style(cpicker, LV_CPICKER_STYLE_MAIN); + const lv_style_t * style_indic = lv_cpicker_get_style(cpicker, LV_CPICKER_STYLE_INDICATOR); + + lv_coord_t h = lv_obj_get_height(cpicker); + + uint16_t r; + if(ext->type == LV_CPICKER_TYPE_DISC) r = style_main->line.width / 2; + else if(ext->type == LV_CPICKER_TYPE_RECT) r = h / 2; + + lv_area_t indic_area; + indic_area.x1 = cpicker->coords.x1 + ext->indic.pos.x - r - style_indic->body.padding.left; + indic_area.y1 = cpicker->coords.x1 + ext->indic.pos.y - r - style_indic->body.padding.top; + indic_area.x2 = cpicker->coords.x1 + ext->indic.pos.x + r + style_indic->body.padding.right; + indic_area.y2 = cpicker->coords.y1 + ext->indic.pos.y + r + style_indic->body.padding.bottom; + + lv_inv_area(lv_obj_get_disp(cpicker), &indic_area); +} + +static void refr_indic_pos(lv_obj_t * cpicker) +{ + invalidate_indic(cpicker); + + lv_cpicker_ext_t * ext = lv_obj_get_ext_attr(cpicker); + lv_coord_t w = lv_obj_get_width(cpicker); + lv_coord_t h = lv_obj_get_height(cpicker); + + if(ext->type == LV_CPICKER_TYPE_RECT) { + lv_coord_t ind_pos = 0; + switch(ext->color_mode) { + case LV_CPICKER_COLOR_MODE_HUE: + ind_pos += (ext->hsv.h * w) / 360; + break; + case LV_CPICKER_COLOR_MODE_SATURATION: + ind_pos += (ext->hsv.s * w) / 100; + break; + case LV_CPICKER_COLOR_MODE_VALUE: + ind_pos += (ext->hsv.v * w) / 100; + break; + } + + ext->indic.pos.x = ind_pos; + ext->indic.pos.y = h / 2; + } + if(ext->type == LV_CPICKER_TYPE_DISC) { + const lv_style_t * style_main = lv_cpicker_get_style(cpicker, LV_CPICKER_STYLE_MAIN); + lv_coord_t r = w / 2 - style_main->line.width / 2; + uint16_t angle = get_angle(cpicker); + ext->indic.pos.x = (((int32_t)r * lv_trigo_sin(angle)) >> LV_TRIGO_SHIFT); + ext->indic.pos.y = (((int32_t)r * lv_trigo_sin(angle + 90)) >> LV_TRIGO_SHIFT); + ext->indic.pos.x = ext->indic.pos.x + w / 2; + ext->indic.pos.y = ext->indic.pos.y + w / 2; + } + + invalidate_indic(cpicker); +} + +static lv_res_t double_click_reset(lv_obj_t * cpicker) +{ + lv_cpicker_ext_t * ext = lv_obj_get_ext_attr(cpicker); + lv_indev_t * indev = lv_indev_get_act(); + /*Double clicked? Use long press time as double click time out*/ + if(lv_tick_elaps(ext->last_click_time) < indev->driver.long_press_time) { + lv_cpicker_set_hsv(cpicker, LV_CPICKER_DEF_HSV); + + lv_res_t res; + res = lv_event_send(cpicker, LV_EVENT_VALUE_CHANGED, NULL); + if(res != LV_RES_OK) return res; + } + ext->last_click_time = lv_tick_get(); + + return LV_RES_OK; +} + +static lv_color_t angle_to_mode_color(lv_obj_t * cpicker, uint16_t angle) +{ + lv_cpicker_ext_t * ext = lv_obj_get_ext_attr(cpicker); lv_color_t color; switch(ext->color_mode) { @@ -482,8 +989,9 @@ static lv_color_t angle_to_mode_color(lv_cpicker_ext_t * ext, uint16_t angle) return color; } -static uint16_t mode_color_to_angle(lv_cpicker_ext_t * ext) +static uint16_t get_angle(lv_obj_t * cpicker) { + lv_cpicker_ext_t * ext = lv_obj_get_ext_attr(cpicker); uint16_t angle; switch(ext->color_mode) { @@ -492,1258 +1000,13 @@ static uint16_t mode_color_to_angle(lv_cpicker_ext_t * ext) angle = ext->hsv.h; break; case LV_CPICKER_COLOR_MODE_SATURATION: - angle = (ext->hsv.s / 100) * 360.0; + angle = (ext->hsv.s * 360) / 100; break; case LV_CPICKER_COLOR_MODE_VALUE: - angle = (ext->hsv.v / 100) * 360.0; + angle = (ext->hsv.v * 360) / 100 ; break; } return angle; } -static lv_coord_t lv_cpicker_get_indicator_coord(lv_style_t * style, lv_cpicker_ext_t * ext) -{ - lv_coord_t ind_pos = style->line.rounded ? ext->rect_gradient_h / 2 : 0; - switch(ext->color_mode) - { - default: - case LV_CPICKER_COLOR_MODE_HUE: - ind_pos += (ext->hsv.h * ext->rect_gradient_w) / 360.0; - break; - case LV_CPICKER_COLOR_MODE_SATURATION: - ind_pos += (ext->hsv.s * ext->rect_gradient_w) / 100; - break; - case LV_CPICKER_COLOR_MODE_VALUE: - ind_pos += (ext->hsv.v * ext->rect_gradient_w) / 100; - break; - } - return ind_pos; -} - -/** - * Should roughly match up with `lv_cpicker_invalidate_disc_indicator_line` - */ -static void lv_cpicker_draw_disc_indicator_line(lv_area_t * mask, lv_style_t * style, lv_opa_t opa_scale, - lv_cpicker_ext_t * ext, - lv_coord_t cx, lv_coord_t cy, uint16_t r, - uint16_t angle) -{ - lv_point_t start; - lv_point_t end; - start.x = cx + ((r - style->line.width + ext->indicator.style->body.padding.inner + ext->indicator.style->line.width/2) * lv_trigo_sin(angle) >> LV_TRIGO_SHIFT); - start.y = cy + ((r - style->line.width + ext->indicator.style->body.padding.inner + ext->indicator.style->line.width/2) * lv_trigo_sin(angle + 90) >> LV_TRIGO_SHIFT); - end.x = cx + ((r - ext->indicator.style->body.padding.inner - ext->indicator.style->line.width/2) * lv_trigo_sin(angle) >> LV_TRIGO_SHIFT); - end.y = cy + ((r - ext->indicator.style->body.padding.inner - ext->indicator.style->line.width/2) * lv_trigo_sin(angle + 90) >> LV_TRIGO_SHIFT); - - lv_draw_line(&start, &end, mask, ext->indicator.style, opa_scale); - - if(ext->indicator.style->line.rounded) - { - lv_area_t circle_area; - circle_area.x1 = start.x - ((ext->indicator.style->line.width - 1) >> 1) - ((ext->indicator.style->line.width - 1) & 0x1); - circle_area.y1 = start.y - ((ext->indicator.style->line.width - 1) >> 1) - ((ext->indicator.style->line.width - 1) & 0x1); - circle_area.x2 = start.x + ((ext->indicator.style->line.width - 1) >> 1); - circle_area.y2 = start.y + ((ext->indicator.style->line.width - 1) >> 1); - lv_draw_rect(&circle_area, mask, ext->indicator.style, opa_scale); - - circle_area.x1 = end.x - ((ext->indicator.style->line.width - 1) >> 1) - ((ext->indicator.style->line.width - 1) & 0x1); - circle_area.y1 = end.y - ((ext->indicator.style->line.width - 1) >> 1) - ((ext->indicator.style->line.width - 1) & 0x1); - circle_area.x2 = end.x + ((ext->indicator.style->line.width - 1) >> 1); - circle_area.y2 = end.y + ((ext->indicator.style->line.width - 1) >> 1); - lv_draw_rect(&circle_area, mask, ext->indicator.style, opa_scale); - } -} - -/** - * Should roughly match up with `lv_cpicker_invalidate_disc_indicator_circle` - */ -static void lv_cpicker_draw_disc_indicator_circle(lv_area_t * mask, lv_style_t * style, lv_opa_t opa_scale, - lv_cpicker_ext_t * ext, - lv_coord_t cx, lv_coord_t cy, uint16_t r, - uint16_t angle) -{ - uint32_t ind_cx = cx + ((r - style->line.width/2) * lv_trigo_sin(angle) >> LV_TRIGO_SHIFT); - uint32_t ind_cy = cy + ((r - style->line.width/2) * lv_trigo_sin(angle + 90) >> LV_TRIGO_SHIFT); - - lv_area_t ind_area; - ind_area.x1 = ind_cx - style->line.width/2; - ind_area.y1 = ind_cy - style->line.width/2; - ind_area.x2 = ind_cx + style->line.width/2; - ind_area.y2 = ind_cy + style->line.width/2; - - lv_style_t styleCopy; - lv_style_copy(&styleCopy, ext->indicator.style); - styleCopy.body.radius = LV_RADIUS_CIRCLE; - - lv_draw_rect(&ind_area, mask, &styleCopy, opa_scale); -} - -/** - * Should roughly match up with `lv_cpicker_invalidate_disc_indicator_in` - */ -static void lv_cpicker_draw_disc_indicator_in(lv_area_t * mask, lv_style_t * style, lv_opa_t opa_scale, - lv_cpicker_ext_t * ext, - lv_coord_t cx, lv_coord_t cy, uint16_t r, - uint16_t rin, uint16_t angle) -{ - uint16_t ind_radius = lv_sqrt((4*rin*rin)/2)/2 + 1 - style->body.padding.inner; - ind_radius = (ind_radius + rin) / 2; - - uint32_t ind_cx = cx + ((ind_radius) * lv_trigo_sin(angle) >> LV_TRIGO_SHIFT); - uint32_t ind_cy = cy + ((ind_radius) * lv_trigo_sin(angle + 90) >> LV_TRIGO_SHIFT); - - lv_area_t ind_area; - ind_area.x1 = ind_cx - r; - ind_area.y1 = ind_cy - r; - ind_area.x2 = ind_cx + r; - ind_area.y2 = ind_cy + r; - - lv_style_t styleCopy; - lv_style_copy(&styleCopy, ext->indicator.style); - styleCopy.body.radius = LV_RADIUS_CIRCLE; - - lv_draw_rect(&ind_area, mask, &styleCopy, opa_scale); -} - -static void lv_cpicker_draw_disc_indicator(lv_area_t * mask, lv_style_t * style, lv_opa_t opa_scale, - lv_cpicker_ext_t * ext, - lv_coord_t cx, lv_coord_t cy, lv_coord_t r, - uint16_t rin, uint16_t radius, lv_area_t center_ind_area) -{ - /*draw center background*/ - static lv_style_t styleCenterBackground; - lv_theme_t * th = lv_theme_get_current(); - if (th) { - lv_style_copy(&styleCenterBackground, th->style.bg); - } else { - lv_style_copy(&styleCenterBackground, &lv_style_plain); - } - - lv_area_t center_area; - center_area.x1 = cx - rin; - center_area.y1 = cy - rin; - center_area.x2 = cx + rin; - center_area.y2 = cy + rin; - styleCenterBackground.body.radius = LV_RADIUS_CIRCLE; - lv_draw_rect(¢er_area, mask, &styleCenterBackground, opa_scale); - - /*draw the center color indicator*/ - style->body.main_color = lv_color_hsv_to_rgb(ext->hsv.h, ext->hsv.s, ext->hsv.v); - style->body.grad_color = style->body.main_color; - style->body.radius = LV_RADIUS_CIRCLE; - lv_draw_rect(¢er_ind_area, mask, style, opa_scale); - - uint16_t angle = mode_color_to_angle(ext); - /*save the angle to refresh the area later*/ - ext->prev_pos = angle; - - /*draw the current hue indicator*/ - switch(ext->indicator.type) - { - case LV_CPICKER_INDICATOR_NONE: - /*no indicator*/ - break; - case LV_CPICKER_INDICATOR_LINE: - lv_cpicker_draw_disc_indicator_line(mask, style, opa_scale, ext, cx, cy, r, angle); - break; - case LV_CPICKER_INDICATOR_CIRCLE: - lv_cpicker_draw_disc_indicator_circle(mask, style, opa_scale, ext, cx, cy, r, angle); - break; - case LV_CPICKER_INDICATOR_IN: - lv_cpicker_draw_disc_indicator_in(mask, style, opa_scale, ext, cx, cy, (rin - radius) / 3, rin, angle); - break; - } -} - -static void lv_cpicker_draw_disc_gradient(lv_area_t * mask, lv_style_t * style, lv_opa_t opa_scale, - lv_cpicker_ext_t * ext, - lv_coord_t cx, lv_coord_t cy, uint16_t r) -{ - int16_t start_angle = 0; /*Default*/ - int16_t end_angle = 360 - LV_CPICKER_DEF_QF; /*Default*/ - - /*if the mask does not include the center of the object - * redrawing all the wheel is not necessary; - * only a given angular range - */ - lv_point_t center = {cx, cy}; - if(!lv_area_is_point_on(mask, ¢er)) - { - /*get angle from center of object to each corners of the area*/ - int16_t dr, ur, ul, dl; - dr = lv_atan2(mask->x2 - cx, mask->y2 - cy); - ur = lv_atan2(mask->x2 - cx, mask->y1 - cy); - ul = lv_atan2(mask->x1 - cx, mask->y1 - cy); - dl = lv_atan2(mask->x1 - cx, mask->y2 - cy); - - /*check area position from object axis*/ - bool left = (mask->x2 < cx && mask->x1 < cx) ? true : false; - bool onYaxis = (mask->x2 > cx && mask->x1 < cx) ? true : false; - bool right = (mask->x2 > cx && mask->x1 > cx) ? true : false; - bool top = (mask->y2 < cy && mask->y1 < cy) ? true : false; - bool onXaxis = (mask->y2 > cy && mask->y1 < cy) ? true : false; - bool bottom = (mask->y2 > cy && mask->y1 > cy) ? true : false; - - /*store angular range*/ - if(right && bottom) - { - start_angle = dl; - end_angle = ur; - } - else if(right && onXaxis) - { - start_angle = dl; - end_angle = ul; - } - else if(right && top) - { - start_angle = dr; - end_angle = ul; - } - else if(onYaxis && top) - { - start_angle = dr; - end_angle = dl; - } - else if(left && top) - { - start_angle = ur; - end_angle = dl; - } - else if(left && onXaxis) - { - start_angle = ur; - end_angle = dr; - } - else if(left && bottom) - { - start_angle = ul; - end_angle = dr; - } - else if(onYaxis && bottom) - { - start_angle = ul; - end_angle = ur; - } - - /*rollover angle*/ - if(start_angle > end_angle) - { - end_angle += 360; - } - - /*round to QF factor*/ - start_angle = (start_angle/LV_CPICKER_DEF_QF) * LV_CPICKER_DEF_QF; - end_angle = (end_angle / LV_CPICKER_DEF_QF) * LV_CPICKER_DEF_QF; - - /*shift angle if necessary before adding offset*/ - if((start_angle - LV_CPICKER_DEF_QF) < 0) - { - start_angle += 360; - end_angle += 360; - } - - /*ensure overlapping by adding offset*/ - start_angle -= LV_CPICKER_DEF_QF; - end_angle += LV_CPICKER_DEF_QF; - } - - lv_point_t triangle_points[3]; - - if(ext->color_mode == LV_CPICKER_COLOR_MODE_HUE) - { - for(uint16_t i = start_angle; i <= end_angle; i+= LV_CPICKER_DEF_QF) - { - style->body.main_color = angle_to_mode_color(ext, i); - style->body.grad_color = style->body.main_color; - - triangle_points[0].x = cx; - triangle_points[0].y = cy; - - triangle_points[1].x = cx + (r * lv_trigo_sin(i) >> LV_TRIGO_SHIFT); - triangle_points[1].y = cy + (r * lv_trigo_sin(i + 90) >> LV_TRIGO_SHIFT); - - if(i == end_angle || i == (360 - LV_CPICKER_DEF_QF)) - { - /*the last triangle is drawn without additional overlapping pixels*/ - triangle_points[2].x = cx + (r * lv_trigo_sin(i + LV_CPICKER_DEF_QF) >> LV_TRIGO_SHIFT); - triangle_points[2].y = cy + (r * lv_trigo_sin(i + LV_CPICKER_DEF_QF + 90) >> LV_TRIGO_SHIFT); - } - else - { - triangle_points[2].x = cx + (r * lv_trigo_sin(i + LV_CPICKER_DEF_QF + TRI_OFFSET) >> LV_TRIGO_SHIFT); - triangle_points[2].y = cy + (r * lv_trigo_sin(i + LV_CPICKER_DEF_QF + TRI_OFFSET + 90) >> LV_TRIGO_SHIFT); - } - - lv_draw_triangle(triangle_points, mask, style, LV_OPA_COVER); - } - } - else if(ext->color_mode == LV_CPICKER_COLOR_MODE_SATURATION) - { - for(uint16_t i = start_angle; i <= end_angle; i += LV_CPICKER_DEF_QF) - { - style->body.main_color = angle_to_mode_color(ext, i); - style->body.grad_color = style->body.main_color; - - triangle_points[0].x = cx; - triangle_points[0].y = cy; - - triangle_points[1].x = cx + (r * lv_trigo_sin(i) >> LV_TRIGO_SHIFT); - triangle_points[1].y = cy + (r * lv_trigo_sin(i + 90) >> LV_TRIGO_SHIFT); - - if(i == end_angle || i == (360 - LV_CPICKER_DEF_QF)) - { - /*the last triangle is drawn without additional overlapping pixels*/ - triangle_points[2].x = cx + (r * lv_trigo_sin(i + LV_CPICKER_DEF_QF) >> LV_TRIGO_SHIFT); - triangle_points[2].y = cy + (r * lv_trigo_sin(i + LV_CPICKER_DEF_QF + 90) >> LV_TRIGO_SHIFT); - } - else - { - triangle_points[2].x = cx + (r * lv_trigo_sin(i + LV_CPICKER_DEF_QF + TRI_OFFSET) >> LV_TRIGO_SHIFT); - triangle_points[2].y = cy + (r * lv_trigo_sin(i + LV_CPICKER_DEF_QF + TRI_OFFSET + 90) >> LV_TRIGO_SHIFT); - } - - lv_draw_triangle(triangle_points, mask, style, LV_OPA_COVER); - } - } - else if(ext->color_mode == LV_CPICKER_COLOR_MODE_VALUE) - { - for(uint16_t i = start_angle; i <= end_angle; i += LV_CPICKER_DEF_QF) - { - style->body.main_color = angle_to_mode_color(ext, i); - style->body.grad_color = style->body.main_color; - - triangle_points[0].x = cx; - triangle_points[0].y = cy; - - triangle_points[1].x = cx + (r * lv_trigo_sin(i) >> LV_TRIGO_SHIFT); - triangle_points[1].y = cy + (r * lv_trigo_sin(i + 90) >> LV_TRIGO_SHIFT); - - if(i == end_angle || i == (360 - LV_CPICKER_DEF_QF)) - { - /*the last triangle is drawn without additional overlapping pixels*/ - triangle_points[2].x = cx + (r * lv_trigo_sin(i + LV_CPICKER_DEF_QF) >> LV_TRIGO_SHIFT); - triangle_points[2].y = cy + (r * lv_trigo_sin(i + LV_CPICKER_DEF_QF + 90) >> LV_TRIGO_SHIFT); - } - else - { - triangle_points[2].x = cx + (r * lv_trigo_sin(i + LV_CPICKER_DEF_QF + TRI_OFFSET) >> LV_TRIGO_SHIFT); - triangle_points[2].y = cy + (r * lv_trigo_sin(i + LV_CPICKER_DEF_QF + TRI_OFFSET + 90) >> LV_TRIGO_SHIFT); - } - - lv_draw_triangle(triangle_points, mask, style, LV_OPA_COVER); - } - } -} - -/** - * Should roughly match up with `lv_cpicker_invalidate_disc` - */ -static void lv_cpicker_disc_design(lv_obj_t * cpicker, - lv_area_t * mask, lv_style_t * style, lv_opa_t opa_scale, - lv_cpicker_ext_t * ext, - lv_coord_t w, lv_coord_t h, - lv_coord_t cx, lv_coord_t cy, uint16_t r) -{ - uint16_t rin = r - style->line.width; - /* - the square area (a and b being sides) should fit into the center of diameter d - we have: - a^2+b^2<=d^2 - 2a^2 <= d^2 - a^2<=(d^2)/2 - a <= sqrt((d^2)/2) - */ - uint16_t radius = lv_sqrt((4*rin*rin)/2)/2 - style->body.padding.inner; - - lv_area_t center_ind_area; - center_ind_area.x1 = cx - radius; - center_ind_area.y1 = cy - radius; - center_ind_area.x2 = cx + radius; - center_ind_area.y2 = cy + radius; - - /*redraw the wheel only if the mask intersect with the wheel*/ - if(mask->x1 < center_ind_area.x1 || mask->x2 > center_ind_area.x2 - || mask->y1 < center_ind_area.y1 || mask->y2 > center_ind_area.y2) - { - lv_cpicker_draw_disc_gradient(mask, style, opa_scale, ext, cx, cy, r); - } - - lv_cpicker_draw_disc_indicator(mask, style, opa_scale, ext, cx, cy, r, rin, radius, center_ind_area); - - /* - static uint32_t c = 0; - lv_style_t style2; - lv_style_copy(&style2, &lv_style_plain); - style2.body.main_color.full = c; - style2.body.grad_color.full = c; - c += 0x123445678; - lv_draw_rect(mask, mask, &style2, opa_scale); - */ -} - -static uint16_t lv_cpicker_calculate_rect_preview_area(lv_obj_t * cpicker, - lv_style_t * style, - lv_cpicker_ext_t * ext, - lv_coord_t w) -{ - lv_coord_t x1 = cpicker->coords.x1; - lv_coord_t y1 = cpicker->coords.y1; - lv_coord_t x2 = cpicker->coords.x2; - lv_coord_t y2 = cpicker->coords.y2; - - /*prepare the color preview area*/ - uint16_t preview_offset = style->line.width; - uint16_t style_body_padding_ver = style->body.padding.top + style->body.padding.bottom; - uint16_t style_body_padding_hor = style->body.padding.left + style->body.padding.right; - if(style_body_padding_ver == 0) - { - /*draw the color preview rect to the side of the gradient*/ - if(style_body_padding_hor >= 0) - { - /*draw the preview to the right*/ - ext->rect_gradient_w = w - preview_offset - (LV_MATH_ABS(style_body_padding_hor) - 1); - ext->rect_gradient_h = y2 - y1; - ext->rect_gradient_area.x1 = x1; - ext->rect_gradient_area.x2 = ext->rect_gradient_area.x1 + ext->rect_gradient_w; - ext->rect_gradient_area.y1 = y1; - ext->rect_gradient_area.y2 = y2; - - ext->rect_preview_area.x1 = x2 - preview_offset; - ext->rect_preview_area.y1 = y1; - ext->rect_preview_area.x2 = x2 ; - ext->rect_preview_area.y2 = y2; - } - else - { - /*draw the preview to the left*/ - ext->rect_gradient_w = w - preview_offset - (LV_MATH_ABS(style_body_padding_hor) - 1); - ext->rect_gradient_h = y2 - y1; - ext->rect_gradient_area.x1 = x2 - ext->rect_gradient_w; - ext->rect_gradient_area.x2 = x2; - ext->rect_gradient_area.y1 = y1; - ext->rect_gradient_area.y2 = y2; - - ext->rect_preview_area.x1 = x1; - ext->rect_preview_area.y1 = y1; - ext->rect_preview_area.x2 = x1 + preview_offset; - ext->rect_preview_area.y2 = y2; - } - } - else - { - /*draw the color preview rect on top or below the gradient*/ - if(style_body_padding_ver >= 0) - { - /*draw the preview on top*/ - ext->rect_gradient_w = w; - ext->rect_gradient_h = (y2 - y1) - preview_offset - (LV_MATH_ABS(style_body_padding_ver) - 1); - ext->rect_gradient_area.x1 = x1; - ext->rect_gradient_area.x2 = x2; - ext->rect_gradient_area.y1 = y2 - ext->rect_gradient_h; - ext->rect_gradient_area.y2 = y2; - - ext->rect_preview_area.x1 = x1; - ext->rect_preview_area.y1 = y1; - ext->rect_preview_area.x2 = x2; - ext->rect_preview_area.y2 = y1 + preview_offset; - } - else - { - /*draw the preview below the gradient*/ - ext->rect_gradient_w = w; - ext->rect_gradient_h = (y2 - y1) - preview_offset - (LV_MATH_ABS(style_body_padding_ver) - 1); - ext->rect_gradient_area.x1 = x1; - ext->rect_gradient_area.x2 = x2; - ext->rect_gradient_area.y1 = y1; - ext->rect_gradient_area.y2 = y1 + ext->rect_gradient_h; - - ext->rect_preview_area.x1 = x1; - ext->rect_preview_area.y1 = y2 - preview_offset; - ext->rect_preview_area.x2 = x2; - ext->rect_preview_area.y2 = y2; - } - } - - return style_body_padding_hor; -} - -/** - * Should roughly match up with `lv_cpicker_invalidate_rect_indicator_line` - */ -static void lv_cpicker_draw_rect_indicator_line(lv_area_t * mask, lv_opa_t opa_scale, - lv_cpicker_ext_t * ext, lv_coord_t ind_pos) -{ - lv_point_t p1, p2; - p1.x = ext->rect_gradient_area.x1 + ind_pos; - p1.y = ext->rect_gradient_area.y1; - p2.x = p1.x; - p2.y = ext->rect_gradient_area.y2; - - lv_draw_line(&p1, &p2, mask, ext->indicator.style, opa_scale); -} - -/** - * Should roughly match up with `lv_cpicker_invalidate_rect_indicator_circle` - */ -static void lv_cpicker_draw_rect_indicator_circle(lv_area_t * mask, lv_opa_t opa_scale, - lv_cpicker_ext_t * ext, lv_coord_t ind_pos) -{ - lv_area_t circle_ind_area; - circle_ind_area.x1 = ext->rect_gradient_area.x1 + ind_pos - ext->rect_gradient_h/2; - circle_ind_area.x2 = circle_ind_area.x1 + ext->rect_gradient_h; - circle_ind_area.y1 = ext->rect_gradient_area.y1; - circle_ind_area.y2 = ext->rect_gradient_area.y2; - - lv_style_t styleCopy; - lv_style_copy(&styleCopy, ext->indicator.style); - styleCopy.body.radius = LV_RADIUS_CIRCLE; - - lv_draw_rect(&circle_ind_area, mask, &styleCopy, opa_scale); -} - -/** - * Should roughly match up with `lv_cpicker_invalidate_rect_indicator_in` - */ -static void lv_cpicker_draw_rect_indicator_in(lv_area_t * mask, lv_opa_t opa_scale, - lv_cpicker_ext_t * ext, lv_coord_t ind_pos) -{ - /*draw triangle at top and bottom of gradient*/ - lv_point_t triangle_points[3]; - - triangle_points[0].x = ext->rect_gradient_area.x1 + ind_pos; - triangle_points[0].y = ext->rect_gradient_area.y1 + (ext->rect_gradient_h/3); - - triangle_points[1].x = triangle_points[0].x - ext->indicator.style->line.width * 3; - triangle_points[1].y = ext->rect_gradient_area.y1 - 1; - - triangle_points[2].x = triangle_points[0].x + ext->indicator.style->line.width * 3; - triangle_points[2].y = triangle_points[1].y; - - lv_draw_triangle(triangle_points, mask, ext->indicator.style, LV_OPA_COVER); - - triangle_points[0].y = ext->rect_gradient_area.y2 - (ext->rect_gradient_h/3); - triangle_points[1].y = ext->rect_gradient_area.y2; - triangle_points[2].y = triangle_points[1].y; - lv_draw_triangle(triangle_points, mask, ext->indicator.style, LV_OPA_COVER); -} - -static void lv_cpicker_draw_rect_indicator(lv_obj_t * cpicker, - lv_area_t * mask, lv_style_t * style, lv_opa_t opa_scale, - lv_cpicker_ext_t * ext, - uint16_t style_body_padding_hor) -{ - /*draw the color preview indicator*/ - style->body.main_color = lv_cpicker_get_color(cpicker); - style->body.grad_color = style->body.main_color; - if(style->line.rounded && style_body_padding_hor == 0) - { - style->body.radius = ext->rect_gradient_h; - } - lv_draw_rect(&(ext->rect_preview_area), mask, style, opa_scale); - - /*draw the color position indicator*/ - lv_coord_t ind_pos = lv_cpicker_get_indicator_coord(style, ext); - /*save to refresh the area later*/ - ext->prev_pos = ind_pos; - - switch(ext->indicator.type) - { - case LV_CPICKER_INDICATOR_NONE: - /*no indicator*/ - break; - case LV_CPICKER_INDICATOR_LINE: - lv_cpicker_draw_rect_indicator_line(mask, opa_scale, ext, ind_pos); - break; - case LV_CPICKER_INDICATOR_CIRCLE: - lv_cpicker_draw_rect_indicator_circle(mask, opa_scale, ext, ind_pos); - break; - case LV_CPICKER_INDICATOR_IN: - lv_cpicker_draw_rect_indicator_in(mask, opa_scale, ext, ind_pos); - break; - default: - break; - } -} - -static void lv_cpicker_draw_rect_gradient(lv_area_t * mask, lv_style_t * style, lv_opa_t opa_scale, - lv_cpicker_ext_t * ext) -{ - if(style->line.rounded) - { - /*draw rounded edges to the gradient*/ - lv_area_t rounded_edge_area; - rounded_edge_area.x1 = ext->rect_gradient_area.x1; - rounded_edge_area.x2 = ext->rect_gradient_area.x1 + ext->rect_gradient_h; - rounded_edge_area.y1 = ext->rect_gradient_area.y1; - rounded_edge_area.y2 = ext->rect_gradient_area.y2; - - ext->rect_gradient_area.x1 += ext->rect_gradient_h/2; - ext->rect_gradient_area.x2 -= ext->rect_gradient_h/2; - ext->rect_gradient_w -= ext->rect_gradient_h; - - style->body.main_color = angle_to_mode_color(ext, 0); - style->body.grad_color = style->body.main_color; - - style->body.radius = LV_RADIUS_CIRCLE; - - lv_draw_rect(&rounded_edge_area, mask, style, opa_scale); - - rounded_edge_area.x1 += ext->rect_gradient_w - 1; - rounded_edge_area.x2 += ext->rect_gradient_w - 1; - - style->body.main_color = angle_to_mode_color(ext, 360); - style->body.grad_color = style->body.main_color; - - lv_draw_rect(&rounded_edge_area, mask, style, opa_scale); - } - - for(uint16_t i = 0; i < 360; i += LV_MATH_MAX(LV_CPICKER_DEF_QF, 360/ext->rect_gradient_w)) - { - style->body.main_color = angle_to_mode_color(ext, i); - style->body.grad_color = style->body.main_color; - - /*the following attribute might need changing between index to add border, shadow, radius etc*/ - style->body.radius = 0; - style->body.border.width = 0; - style->body.shadow.width = 0; - style->body.opa = LV_OPA_COVER; - - lv_area_t rect_area; - - /*scale angle (hue/sat/val) to linear coordinate*/ - lv_coord_t xi = i / 360.0 * ext->rect_gradient_w; - - rect_area.x1 = LV_MATH_MIN(ext->rect_gradient_area.x1 + xi, ext->rect_gradient_area.x1 + ext->rect_gradient_w - LV_MATH_MAX(LV_CPICKER_DEF_QF, 360/ext->rect_gradient_w)); - rect_area.y1 = ext->rect_gradient_area.y1; - rect_area.x2 = rect_area.x1 + LV_MATH_MAX(LV_CPICKER_DEF_QF, 360/ext->rect_gradient_w); - rect_area.y2 = ext->rect_gradient_area.y2; - - lv_draw_rect(&rect_area, mask, style, opa_scale); - } - - if(style->line.rounded) - { - /*Restore gradient area to take rounded end in account*/ - ext->rect_gradient_area.x1 -= ext->rect_gradient_h/2; - ext->rect_gradient_area.x2 += ext->rect_gradient_h/2; - //ext->rect_gradient_w += ext->rect_gradient_h; - } -} - -/** - * Should roughly match up with `lv_cpicker_invalidate_rect` - */ -static void lv_cpicker_rect_design(lv_obj_t * cpicker, - lv_area_t * mask, lv_style_t * style, lv_opa_t opa_scale, - lv_cpicker_ext_t * ext, - lv_coord_t w, lv_coord_t h) -{ - uint16_t style_body_padding_hor = lv_cpicker_calculate_rect_preview_area(cpicker, style, ext, w); - - lv_cpicker_draw_rect_gradient(mask, style, opa_scale, ext); - - lv_cpicker_draw_rect_indicator(cpicker, mask, style, opa_scale, ext, style_body_padding_hor); -} - - -static void lv_cpicker_invalidate(lv_obj_t * cpicker, bool all); - -static lv_res_t lv_cpicker_disc_signal(lv_obj_t * cpicker, lv_signal_t sign, void * param, - lv_style_t * style, lv_cpicker_ext_t * ext, - lv_coord_t r_out, lv_coord_t r_in, lv_coord_t x, lv_coord_t y); -static lv_res_t lv_cpicker_rect_signal(lv_obj_t * cpicker, lv_signal_t sign, void * param, - lv_style_t * style, lv_cpicker_ext_t * ext); - -/** - * Signal function of the color_picker - * @param cpicker pointer to a color_picker object - * @param sign a signal type from lv_signal_t enum - * @param param pointer to a signal specific variable - * @return LV_RES_OK: the object is not deleted in the function; LV_RES_INV: the object is deleted - */ -static lv_res_t lv_cpicker_signal(lv_obj_t * cpicker, lv_signal_t sign, void * param) -{ - /* Include the ancient signal function */ - lv_res_t res = ancestor_signal(cpicker, sign, param); - if(res != LV_RES_OK) return res; - - if(sign == LV_SIGNAL_CLEANUP) - { - /*Nothing to cleanup. (No dynamically allocated memory in 'ext')*/ - } - else if(sign == LV_SIGNAL_GET_TYPE) - { - lv_obj_type_t * buf = param; - uint8_t i; - for(i = 0; i < LV_MAX_ANCESTOR_NUM - 1; i++) /*Find the last set data*/ - { - if(buf->type[i] == NULL) break; - } - buf->type[i] = "lv_cpicker"; - } - else - { - lv_cpicker_ext_t * ext = lv_obj_get_ext_attr(cpicker); - - if(sign == LV_SIGNAL_CONTROL) - { - uint32_t c = *((uint32_t *)param); /*uint32_t because can be UTF-8*/ - if(c == LV_KEY_RIGHT || c == LV_KEY_UP) - { - switch(ext->color_mode) - { - case LV_CPICKER_COLOR_MODE_HUE: - ext->hsv.h = (ext->hsv.h + 1) % 360; - break; - case LV_CPICKER_COLOR_MODE_SATURATION: - ext->hsv.s = (ext->hsv.s + 1) % 100; - break; - case LV_CPICKER_COLOR_MODE_VALUE: - ext->hsv.v = (ext->hsv.v + 1) % 100; - break; - } - - lv_cpicker_invalidate(cpicker, false); - - res = lv_event_send(cpicker, LV_EVENT_VALUE_CHANGED, NULL); - if(res != LV_RES_OK) return res; - } - else if(c == LV_KEY_LEFT || c == LV_KEY_DOWN) - { - switch(ext->color_mode) - { - case LV_CPICKER_COLOR_MODE_HUE: - ext->hsv.h = ext->hsv.h > 0?(ext->hsv.h - 1):360; - break; - case LV_CPICKER_COLOR_MODE_SATURATION: - ext->hsv.s = ext->hsv.s > 0?(ext->hsv.s - 1):100; - break; - case LV_CPICKER_COLOR_MODE_VALUE: - ext->hsv.v = ext->hsv.v > 0?(ext->hsv.v - 1):100; - break; - } - - lv_cpicker_invalidate(cpicker, false); - - res = lv_event_send(cpicker, LV_EVENT_VALUE_CHANGED, NULL); - if(res != LV_RES_OK) return res; - } - } - else if(sign == LV_SIGNAL_PRESS_LOST) - { - ext->prev_hsv = ext->hsv; - lv_cpicker_invalidate(cpicker, false); - } - else - { - lv_style_t * style = lv_cpicker_get_style(cpicker, LV_CPICKER_STYLE_MAIN); - - if(ext->type == LV_CPICKER_TYPE_DISC) - { - lv_coord_t r_out = (LV_MATH_MIN(lv_obj_get_width(cpicker), lv_obj_get_height(cpicker))) / 2; - lv_coord_t r_in = r_out - style->line.width - style->body.padding.inner; - lv_coord_t x = cpicker->coords.x1 + lv_obj_get_width(cpicker) / 2; - lv_coord_t y = cpicker->coords.y1 + lv_obj_get_height(cpicker) / 2; - res = lv_cpicker_disc_signal(cpicker, sign, param, style, ext, r_out, r_in, x, y); - if(res != LV_RES_OK) return res; - } - else if(ext->type == LV_CPICKER_TYPE_RECT) - { - res = lv_cpicker_rect_signal(cpicker, sign, param, style, ext); - if(res != LV_RES_OK) return res; - } - } - } - - return res; -} - -static lv_res_t lv_cpicker_reset_hsv_if_double_clicked(lv_obj_t * cpicker, - lv_cpicker_ext_t * ext) -{ - bool changed = false; - - if(lv_tick_elaps(ext->last_click_time) < 400) - { - switch(ext->color_mode) - { - case LV_CPICKER_COLOR_MODE_HUE: - changed = ext->hsv.h != LV_CPICKER_DEF_HSV.h; - if (changed) - { - ext->hsv.h = LV_CPICKER_DEF_HSV.h; - } - break; - case LV_CPICKER_COLOR_MODE_SATURATION: - changed = ext->hsv.s != LV_CPICKER_DEF_HSV.s; - if (changed) - { - ext->hsv.s = LV_CPICKER_DEF_HSV.s; - } - break; - case LV_CPICKER_COLOR_MODE_VALUE: - changed = ext->hsv.v != LV_CPICKER_DEF_HSV.v; - if (changed) - { - ext->hsv.v = LV_CPICKER_DEF_HSV.v; - } - break; - } - ext->prev_hsv = ext->hsv; - } - ext->last_click_time = lv_tick_get(); - - lv_res_t res = LV_RES_OK; - if (changed) - { - lv_cpicker_invalidate(cpicker, false); - - res = lv_event_send(cpicker, LV_EVENT_VALUE_CHANGED, NULL); - if(res != LV_RES_OK) return res; - } - return res; -} - -static void lv_cpicker_set_next_color_mode(lv_obj_t * cpicker, - lv_cpicker_ext_t * ext) -{ - ext->prev_hsv = ext->hsv; - ext->color_mode = (ext->color_mode + 1) % 3; - lv_cpicker_invalidate(cpicker, true); -} - -static lv_res_t lv_cpicker_set_hsv_percent(lv_obj_t * cpicker, - lv_cpicker_ext_t * ext, - float percent) -{ - lv_res_t res; - - bool changed = false; - uint16_t hsv; - switch(ext->color_mode) - { - case LV_CPICKER_COLOR_MODE_HUE: - hsv = percent * 360.0; - changed = hsv != ext->hsv.h; - if (changed) - { - ext->hsv.h = hsv; - } - break; - case LV_CPICKER_COLOR_MODE_SATURATION: - hsv = percent * 100.0; - changed = hsv != ext->hsv.s; - if (changed) - { - ext->hsv.s = hsv; - } - break; - case LV_CPICKER_COLOR_MODE_VALUE: - hsv = percent * 100.0; - changed = hsv != ext->hsv.v; - if (changed) - { - ext->hsv.v = hsv; - } - break; - } - ext->prev_hsv = ext->hsv; - - if (changed) - { - lv_cpicker_invalidate(cpicker, false); - - res = lv_event_send(cpicker, LV_EVENT_VALUE_CHANGED, NULL); - if(res != LV_RES_OK) return res; - } - - return res; -} - -static lv_res_t lv_cpicker_disc_signal(lv_obj_t * cpicker, lv_signal_t sign, void * param, - lv_style_t * style, lv_cpicker_ext_t * ext, - lv_coord_t r_out, lv_coord_t r_in, lv_coord_t x, lv_coord_t y) -{ - lv_res_t res; - - if(sign == LV_SIGNAL_PRESSED) - { - ext->prev_hsv = ext->hsv; - - lv_indev_t * indev = param; - - lv_coord_t xp = indev->proc.types.pointer.act_point.x - x; - lv_coord_t yp = indev->proc.types.pointer.act_point.y - y; - if((xp*xp + yp*yp) < (r_in*r_in)) - { - res = lv_cpicker_reset_hsv_if_double_clicked(cpicker, ext); - if(res != LV_RES_OK) return res; - } - } - else if(sign == LV_SIGNAL_PRESSING) - { - lv_indev_t * indev = param; - - lv_coord_t xp = indev->proc.types.pointer.act_point.x - x; - lv_coord_t yp = indev->proc.types.pointer.act_point.y - y; - if((xp*xp + yp*yp) < (r_out*r_out) && (xp*xp + yp*yp) >= (r_in*r_in)) - { - float percent = lv_atan2(xp, yp) / 360.0; - - res = lv_cpicker_set_hsv_percent(cpicker, ext, percent); - if(res != LV_RES_OK) return res; - } - } - else if(sign == LV_SIGNAL_RELEASED) - { - lv_indev_t * indev = param; - - lv_coord_t xp = indev->proc.types.pointer.act_point.x - x; - lv_coord_t yp = indev->proc.types.pointer.act_point.y - y; - if((xp*xp + yp*yp) < (r_out*r_out) && (xp*xp + yp*yp) >= (r_in*r_in)) - { - float percent = lv_atan2(xp, yp) / 360.0; - - res = lv_cpicker_set_hsv_percent(cpicker, ext, percent); - if(res != LV_RES_OK) return res; - } - } - else if(sign == LV_SIGNAL_LONG_PRESS) - { - if(!ext->color_mode_fixed) - { - lv_indev_t * indev = param; - - lv_coord_t xp = indev->proc.types.pointer.act_point.x - x; - lv_coord_t yp = indev->proc.types.pointer.act_point.y - y; - if((xp*xp + yp*yp) < (r_in*r_in)) - { - lv_cpicker_set_next_color_mode(cpicker, ext); - } - } - } - - return res; -} - -static lv_res_t lv_cpicker_rect_signal(lv_obj_t * cpicker, lv_signal_t sign, void * param, - lv_style_t * style, lv_cpicker_ext_t * ext) -{ - lv_res_t res; - - if(sign == LV_SIGNAL_PRESSED) - { - ext->prev_hsv = ext->hsv; - - lv_indev_t * indev = param; - - if(lv_area_is_point_on(&(ext->rect_preview_area), &indev->proc.types.pointer.act_point)) - { - res = lv_cpicker_reset_hsv_if_double_clicked(cpicker, ext); - if(res != LV_RES_OK) return res; - } - } - else if(sign == LV_SIGNAL_PRESSING) - { - lv_indev_t * indev = param; - - if(lv_area_is_point_on(&(ext->rect_gradient_area), &indev->proc.types.pointer.act_point)) - { - uint16_t width = ext->rect_gradient_area.x2 - ext->rect_gradient_area.x1; - uint16_t distance = indev->proc.types.pointer.act_point.x - ext->rect_gradient_area.x1; - float percent = distance / (float) width; - - res = lv_cpicker_set_hsv_percent(cpicker, ext, percent); - if(res != LV_RES_OK) return res; - } - } - else if(sign == LV_SIGNAL_RELEASED) - { - lv_indev_t * indev = param; - - if(lv_area_is_point_on(&(ext->rect_gradient_area), &indev->proc.types.pointer.act_point)) - { - uint16_t width = ext->rect_gradient_area.x2 - ext->rect_gradient_area.x1; - uint16_t distance = indev->proc.types.pointer.act_point.x - ext->rect_gradient_area.x1; - float percent = distance / (float) width; - - res = lv_cpicker_set_hsv_percent(cpicker, ext, percent); - if(res != LV_RES_OK) return res; - } - } - else if(sign == LV_SIGNAL_LONG_PRESS) - { - if(!ext->color_mode_fixed) - { - lv_indev_t * indev = param; - - if(lv_area_is_point_on(&(ext->rect_preview_area), &indev->proc.types.pointer.act_point)) - { - lv_cpicker_set_next_color_mode(cpicker, ext); - } - } - } - - return res; -} - - -static void lv_cpicker_invalidate_disc(lv_disp_t * disp, lv_style_t * style, - lv_cpicker_ext_t * ext, - lv_coord_t w, lv_coord_t h, - lv_coord_t cx, lv_coord_t cy, uint16_t r); -static void lv_cpicker_invalidate_rect(lv_disp_t * disp, lv_style_t * style, - lv_cpicker_ext_t * ext, - lv_coord_t w, lv_coord_t h); - -/** - * Indicator points need to match those set in lv_cpicker_disc_design/lv_cpicker_rect_design - */ -static void lv_cpicker_invalidate(lv_obj_t * cpicker, bool all) -{ - if (all) - { - lv_obj_invalidate(cpicker); - return; - } - - lv_disp_t * disp = lv_obj_get_disp(cpicker); - lv_cpicker_ext_t * ext = lv_obj_get_ext_attr(cpicker); - lv_style_t * style = lv_cpicker_get_style(cpicker, LV_CPICKER_STYLE_MAIN); - - lv_style_t styleCopy; - lv_style_copy(&styleCopy, style); - - lv_coord_t w = lv_obj_get_width(cpicker); - lv_coord_t h = lv_obj_get_height(cpicker); - - if(ext->type == LV_CPICKER_TYPE_DISC) - { - lv_coord_t cx = cpicker->coords.x1 + w / 2; - lv_coord_t cy = cpicker->coords.y1 + h / 2; - uint16_t r = LV_MATH_MIN(w, h) / 2; - lv_cpicker_invalidate_disc(disp, &styleCopy, ext, w, h, cx, cy, r); - } - else if(ext->type == LV_CPICKER_TYPE_RECT) - { - lv_cpicker_invalidate_rect(disp, &styleCopy, ext, w, h); - } -} - -/** - * Should roughly match up with `lv_cpicker_draw_disc_indicator_line` - */ -static void lv_cpicker_invalidate_disc_indicator_line(lv_disp_t * disp, lv_style_t * style, - lv_cpicker_ext_t * ext, - lv_coord_t cx, lv_coord_t cy, uint16_t r, - uint16_t angle) -{ - lv_coord_t x1 = cx + ((r - style->line.width + ext->indicator.style->body.padding.inner + ext->indicator.style->line.width/2) * lv_trigo_sin(angle) >> LV_TRIGO_SHIFT); - lv_coord_t y1 = cy + ((r - style->line.width + ext->indicator.style->body.padding.inner + ext->indicator.style->line.width/2) * lv_trigo_sin(angle + 90) >> LV_TRIGO_SHIFT); - lv_coord_t x2 = cx + ((r - ext->indicator.style->body.padding.inner - ext->indicator.style->line.width/2) * lv_trigo_sin(angle) >> LV_TRIGO_SHIFT); - lv_coord_t y2 = cy + ((r - ext->indicator.style->body.padding.inner - ext->indicator.style->line.width/2) * lv_trigo_sin(angle + 90) >> LV_TRIGO_SHIFT); - - lv_point_t point1, point2; - point1.x = x1; - point1.y = y1; - point2.x = x2; - point2.y = y2; - - lv_area_t line_area; - /*Steps less in y than x -> rather horizontal*/ - if(point1.x < point2.x) { - line_area.x1 = point1.x; - line_area.x2 = point2.x; - } else { - line_area.x1 = point2.x; - line_area.x2 = point1.x; - } - - /*Steps less in x than y -> rather vertical*/ - if(point1.y < point2.y) { - line_area.y1 = point1.y; - line_area.y2 = point2.y; - } else { - line_area.y1 = point2.y; - line_area.y2 = point1.y; - } - - line_area.x1 -= 2*ext->indicator.style->line.width; - line_area.y1 -= 2*ext->indicator.style->line.width; - line_area.x2 += 2*ext->indicator.style->line.width; - line_area.y2 += 2*ext->indicator.style->line.width; - - lv_inv_area(disp, &line_area); -} - -/** - * Should roughly match up with `lv_cpicker_draw_disc_indicator_circle` - */ -static void lv_cpicker_invalidate_disc_indicator_circle(lv_disp_t * disp, lv_style_t * style, - lv_cpicker_ext_t * ext, - lv_coord_t cx, lv_coord_t cy, uint16_t r, - uint16_t angle) -{ - uint32_t ind_cx = cx + ((r - style->line.width/2) * lv_trigo_sin(angle) >> LV_TRIGO_SHIFT); - uint32_t ind_cy = cy + ((r - style->line.width/2) * lv_trigo_sin(angle + 90) >> LV_TRIGO_SHIFT); - - lv_area_t ind_area; - ind_area.x1 = ind_cx - style->line.width/2; - ind_area.y1 = ind_cy - style->line.width/2; - ind_area.x2 = ind_cx + style->line.width/2; - ind_area.y2 = ind_cy + style->line.width/2; - - lv_inv_area(disp, &ind_area); -} - -/** - * Should roughly match up with `lv_cpicker_draw_disc_indicator_in` - */ -static void lv_cpicker_invalidate_disc_indicator_in(lv_disp_t * disp, lv_style_t * style, - lv_cpicker_ext_t * ext, - lv_coord_t x, lv_coord_t y, uint16_t r, - uint16_t rin, uint16_t angle) -{ - uint16_t ind_radius = lv_sqrt((4*rin*rin)/2)/2 + 1 - style->body.padding.inner; - ind_radius = (ind_radius + rin) / 2; - - uint16_t ind_cx = x + ((ind_radius) * lv_trigo_sin(angle) >> LV_TRIGO_SHIFT); - uint16_t ind_cy = y + ((ind_radius) * lv_trigo_sin(angle + 90) >> LV_TRIGO_SHIFT); - - lv_area_t ind_area; - ind_area.x1 = ind_cx - r; - ind_area.y1 = ind_cy - r; - ind_area.x2 = ind_cx + r; - ind_area.y2 = ind_cy + r; - - lv_inv_area(disp, &ind_area); -} - -/** - * Should roughly match up with `lv_cpicker_disc_design` - */ -static void lv_cpicker_invalidate_disc(lv_disp_t * disp, lv_style_t * style, - lv_cpicker_ext_t * ext, - lv_coord_t w, lv_coord_t h, - lv_coord_t cx, lv_coord_t cy, uint16_t r) -{ - /*invalidate center color area*/ - uint16_t rin = r - style->line.width; - /* - the square area (a and b being sides) should fit into the center of diameter d - we have: - a^2+b^2<=d^2 - 2a^2 <= d^2 - a^2<=(d^2)/2 - a <= sqrt((d^2)/2) - */ - uint16_t radius = lv_sqrt((4*rin*rin)/2)/2 + 1 - style->body.padding.inner; - - lv_area_t center_color_area; - center_color_area.x1 = cx - radius; - center_color_area.y1 = cy - radius; - center_color_area.x2 = cx + radius; - center_color_area.y2 = cy + radius; - - lv_inv_area(disp, ¢er_color_area); - - /*invalidate indicator*/ - uint16_t angle = mode_color_to_angle(ext); - switch(ext->indicator.type) - { - case LV_CPICKER_INDICATOR_LINE: - lv_cpicker_invalidate_disc_indicator_line(disp, style, ext, cx, cy, r, angle); - lv_cpicker_invalidate_disc_indicator_line(disp, style, ext, cx, cy, r, ext->prev_pos); - break; - case LV_CPICKER_INDICATOR_CIRCLE: - lv_cpicker_invalidate_disc_indicator_circle(disp, style, ext, cx, cy, r, angle); - lv_cpicker_invalidate_disc_indicator_circle(disp, style, ext, cx, cy, r, ext->prev_pos); - break; - case LV_CPICKER_INDICATOR_IN: - lv_cpicker_invalidate_disc_indicator_in(disp, style, ext, cx, cy, (rin - radius) / 3, rin, angle); - lv_cpicker_invalidate_disc_indicator_in(disp, style, ext, cx, cy, (rin - radius) / 3, rin, ext->prev_pos); - break; - } -} - -/** - * Should roughly match up with `lv_cpicker_draw_rect_indicator_line` - */ -static void lv_cpicker_invalidate_rect_indicator_line(lv_disp_t * disp, - lv_cpicker_ext_t * ext, - lv_coord_t ind_pos) -{ - lv_area_t line_area; - line_area.x1 = ext->rect_gradient_area.x1 + ind_pos - ext->indicator.style->line.width; - line_area.y1 = ext->rect_gradient_area.y1; - line_area.x2 = ext->rect_gradient_area.x1 + ind_pos + ext->indicator.style->line.width; - line_area.y2 = ext->rect_gradient_area.y2; - - lv_inv_area(disp, &line_area); -} - -/** - * Should roughly match up with `lv_cpicker_draw_rect_indicator_circle` - */ -static void lv_cpicker_invalidate_rect_indicator_circle(lv_disp_t * disp, - lv_cpicker_ext_t * ext, - lv_coord_t ind_pos) -{ - lv_area_t circle_ind_area; - circle_ind_area.x1 = ext->rect_gradient_area.x1 + ind_pos - ext->rect_gradient_h/2; - circle_ind_area.x2 = circle_ind_area.x1 + ext->rect_gradient_h; - circle_ind_area.y1 = ext->rect_gradient_area.y1; - circle_ind_area.y2 = ext->rect_gradient_area.y2; - - lv_inv_area(disp, &circle_ind_area); -} - -/** - * Should roughly match up with `lv_cpicker_draw_rect_indicator_in` - */ -static void lv_cpicker_invalidate_rect_indicator_in(lv_disp_t * disp, - lv_cpicker_ext_t * ext, - lv_coord_t ind_pos) -{ - lv_coord_t center = ext->rect_gradient_area.x1 + ind_pos; - - lv_area_t ind_area; - ind_area.x1 = center - ext->indicator.style->line.width * 3; - ind_area.y1 = ext->rect_gradient_area.y1 - 1; - ind_area.x2 = center + ext->indicator.style->line.width * 3; - ind_area.y2 = ext->rect_gradient_area.y2; - - lv_inv_area(disp, &ind_area); -} - -/** - * Should roughly match up with `lv_cpicker_rect_design` - */ -static void lv_cpicker_invalidate_rect(lv_disp_t * disp, lv_style_t * style, - lv_cpicker_ext_t * ext, - lv_coord_t w, lv_coord_t h) -{ - /*invalidate color preview indicator*/ - lv_inv_area(disp, &ext->rect_preview_area); - - /*invalidate indicator*/ - lv_coord_t ind_pos = lv_cpicker_get_indicator_coord(style, ext); - switch(ext->indicator.type) - { - case LV_CPICKER_INDICATOR_LINE: - lv_cpicker_invalidate_rect_indicator_line(disp, ext, ind_pos); - lv_cpicker_invalidate_rect_indicator_line(disp, ext, ext->prev_pos); - break; - case LV_CPICKER_INDICATOR_CIRCLE: - lv_cpicker_invalidate_rect_indicator_circle(disp, ext, ind_pos); - lv_cpicker_invalidate_rect_indicator_circle(disp, ext, ext->prev_pos); - break; - case LV_CPICKER_INDICATOR_IN: - lv_cpicker_invalidate_rect_indicator_in(disp, ext, ind_pos); - lv_cpicker_invalidate_rect_indicator_in(disp, ext, ext->prev_pos); - break; - } -} - #endif /* LV_USE_CPICKER != 0 */ diff --git a/src/lv_objx/lv_cpicker.h b/src/lv_objx/lv_cpicker.h index 5a542dd02..a5fe5239a 100644 --- a/src/lv_objx/lv_cpicker.h +++ b/src/lv_objx/lv_cpicker.h @@ -30,13 +30,6 @@ extern "C" { /********************** * TYPEDEFS **********************/ -enum { - LV_CPICKER_INDICATOR_NONE, - LV_CPICKER_INDICATOR_LINE, - LV_CPICKER_INDICATOR_CIRCLE, - LV_CPICKER_INDICATOR_IN -}; -typedef uint8_t lv_cpicker_indicator_type_t; enum { LV_CPICKER_TYPE_RECT, @@ -56,21 +49,17 @@ typedef uint8_t lv_cpicker_color_mode_t; /*Data of colorpicker*/ typedef struct { lv_color_hsv_t hsv; - lv_color_hsv_t prev_hsv; - struct - { + struct { lv_style_t * style; - lv_cpicker_indicator_type_t type; - } indicator; + lv_point_t pos; + uint8_t colored :1; + + } indic; uint32_t last_click_time; - lv_area_t rect_preview_area; - lv_area_t rect_gradient_area; - lv_coord_t rect_gradient_w; - lv_coord_t rect_gradient_h; - uint16_t prev_pos; - lv_cpicker_color_mode_t color_mode:2; - uint8_t color_mode_fixed:1; - lv_cpicker_type_t type:1; + uint32_t last_change_time; + lv_cpicker_color_mode_t color_mode :2; + uint8_t color_mode_fixed :1; + lv_cpicker_type_t type :1; } lv_cpicker_ext_t; /*Styles*/ @@ -112,13 +101,6 @@ void lv_cpicker_set_type(lv_obj_t * chart, lv_cpicker_type_t type); */ void lv_cpicker_set_style(lv_obj_t * cpicker, lv_cpicker_style_t type, lv_style_t *style); -/** - * Set a type of a colorpicker indicator. - * @param cpicker pointer to colorpicker object - * @param type indicator type - */ -void lv_cpicker_set_indicator_type(lv_obj_t * cpicker, lv_cpicker_indicator_type_t type); - /** * Set the current hue of a colorpicker. * @param cpicker pointer to colorpicker object @@ -168,6 +150,13 @@ void lv_cpicker_set_color_mode(lv_obj_t * cpicker, lv_cpicker_color_mode_t mode) */ void lv_cpicker_set_color_mode_fixed(lv_obj_t * cpicker, bool fixed); +/** + * Make the indicator to be colored to the current color + * @param cpicker pointer to colorpicker object + * @param en true: color the indicator; false: not color the indicator + */ +void lv_cpicker_set_indic_colored(lv_obj_t * cpicker, bool en); + /*===================== * Getter functions *====================*/ @@ -192,7 +181,7 @@ bool lv_cpicker_get_color_mode_fixed(lv_obj_t * cpicker); * @param type which style should be get * @return pointer to the style */ -lv_style_t * lv_cpicker_get_style(const lv_obj_t * cpicker, lv_cpicker_style_t type); +const lv_style_t * lv_cpicker_get_style(const lv_obj_t * cpicker, lv_cpicker_style_t type); /** * Get the current hue of a colorpicker. @@ -229,6 +218,13 @@ lv_color_hsv_t lv_cpicker_get_hsv(lv_obj_t * cpicker); */ lv_color_t lv_cpicker_get_color(lv_obj_t * cpicker); +/** + * Whether the indicator is colored to the current color or not + * @param cpicker pointer to colorpicker object + * @return true: color the indicator; false: not color the indicator + */ +bool lv_cpicker_get_indic_colored(lv_obj_t * cpicker); + /*===================== * Other functions *====================*/ From eda607d82466a5f3316c0c24c6cd60525ffe58a4 Mon Sep 17 00:00:00 2001 From: Gabor Kiss-Vamosi Date: Tue, 1 Oct 2019 22:00:23 +0200 Subject: [PATCH 24/25] cpicker: minor fixes --- src/lv_objx/lv_cpicker.c | 71 ++++++++++++++++++++++------------------ src/lv_objx/lv_cpicker.h | 1 + 2 files changed, 41 insertions(+), 31 deletions(-) diff --git a/src/lv_objx/lv_cpicker.c b/src/lv_objx/lv_cpicker.c index 6c97f61a0..dae87bff8 100644 --- a/src/lv_objx/lv_cpicker.c +++ b/src/lv_objx/lv_cpicker.c @@ -107,7 +107,7 @@ lv_obj_t * lv_cpicker_create(lv_obj_t * par, const lv_obj_t * copy) /*Initialize the allocated 'ext' */ ext->hsv = LV_CPICKER_DEF_HSV; ext->indic.style = &lv_style_plain; - ext->indic.colored = 1; + ext->indic.colored = 0; ext->color_mode = LV_CPICKER_COLOR_MODE_HUE; ext->color_mode_fixed = 0; ext->last_click_time = 0; @@ -807,13 +807,24 @@ static lv_res_t lv_cpicker_signal(lv_obj_t * cpicker, lv_signal_t sign, void * p } } else if(sign == LV_SIGNAL_PRESSED) { - res = double_click_reset(cpicker); ext->last_change_time = lv_tick_get(); + lv_indev_get_point(lv_indev_get_act(), &ext->last_press_point); + res = double_click_reset(cpicker); if(res != LV_RES_OK) return res; } else if(sign == LV_SIGNAL_PRESSING){ lv_indev_t * indev = lv_indev_get_act(); + if(indev == NULL) return res; + lv_point_t p; lv_indev_get_point(indev, &p); + + if((LV_MATH_ABS(p.x - ext->last_press_point.x) > indev->driver.drag_limit / 2) || + (LV_MATH_ABS(p.y - ext->last_press_point.y) > indev->driver.drag_limit / 2)) { + ext->last_change_time = lv_tick_get(); + ext->last_press_point.x = p.x; + ext->last_press_point.y = p.y; + } + p.x -= cpicker->coords.x1; p.y -= cpicker->coords.y1; @@ -823,57 +834,54 @@ static lv_res_t lv_cpicker_signal(lv_obj_t * cpicker, lv_signal_t sign, void * p int16_t angle = 0; if(ext->type == LV_CPICKER_TYPE_RECT) { + /*If pressed long enough without change go to next color mode*/ + uint32_t diff = lv_tick_elaps(ext->last_change_time); + if(diff > indev->driver.long_press_time * 2 && !ext->color_mode_fixed) { + next_color_mode(cpicker); + lv_indev_wait_release(lv_indev_get_act()); + return res; + } + angle = (p.x * 360) / w; if(angle < 0) angle = 0; if(angle >= 360) angle = 359; } else if(ext->type == LV_CPICKER_TYPE_DISC) { const lv_style_t * style_main = lv_cpicker_get_style(cpicker, LV_CPICKER_STYLE_MAIN); - lv_coord_t r = w / 2; - p.x -= r; - p.y -= r; - r -= style_main->line.width; - if(p.x * p.x + p.y * p.y < r * r) return res; + lv_coord_t r_in = w / 2; + p.x -= r_in; + p.y -= r_in; + r_in -= style_main->line.width * 2; /* *2 to let some sensitive space inside*/ + + /*If the inner area is being pressed, go to the next color mode on long press*/ + if(p.x * p.x + p.y * p.y < r_in * r_in) { + uint32_t diff = lv_tick_elaps(ext->last_change_time); + if(diff > indev->driver.long_press_time * 2 && !ext->color_mode_fixed) { + next_color_mode(cpicker); + lv_indev_wait_release(lv_indev_get_act()); + } + return res; + } angle = lv_atan2(p.x, p.y) % 360; } - bool changed = false; switch(ext->color_mode) { case LV_CPICKER_COLOR_MODE_HUE: - if(ext->hsv.h != angle) { - lv_cpicker_set_hue(cpicker, angle); - changed = true; - } + if(ext->hsv.h != angle) lv_cpicker_set_hue(cpicker, angle); break; case LV_CPICKER_COLOR_MODE_SATURATION: angle = (angle * 100) / 360; - if(ext->hsv.s != angle) { - lv_cpicker_set_saturation(cpicker, angle); - changed = true; - } + if(ext->hsv.s != angle) lv_cpicker_set_saturation(cpicker, angle); break; case LV_CPICKER_COLOR_MODE_VALUE: angle = (angle * 100) / 360; - if(ext->hsv.v != angle) { - lv_cpicker_set_value(cpicker, angle); - changed = true; - } + if(ext->hsv.v != angle) lv_cpicker_set_value(cpicker, angle); break; } refr_indic_pos(cpicker); - uint32_t diff = lv_tick_elaps(ext->last_change_time); - if(diff > indev->driver.long_press_time * 2 && !ext->color_mode_fixed) { - next_color_mode(cpicker); - lv_indev_wait_release(lv_indev_get_act()); - } - - if(changed) { - ext->last_change_time = lv_tick_get(); - } - res = lv_event_send(cpicker, LV_EVENT_VALUE_CHANGED, NULL); if(res != LV_RES_OK) return res; } @@ -895,6 +903,7 @@ static void next_color_mode(lv_obj_t * cpicker ) */ static void invalidate_indic(lv_obj_t * cpicker) { + lv_cpicker_ext_t * ext = lv_obj_get_ext_attr(cpicker); const lv_style_t * style_main = lv_cpicker_get_style(cpicker, LV_CPICKER_STYLE_MAIN); const lv_style_t * style_indic = lv_cpicker_get_style(cpicker, LV_CPICKER_STYLE_INDICATOR); @@ -907,7 +916,7 @@ static void invalidate_indic(lv_obj_t * cpicker) lv_area_t indic_area; indic_area.x1 = cpicker->coords.x1 + ext->indic.pos.x - r - style_indic->body.padding.left; - indic_area.y1 = cpicker->coords.x1 + ext->indic.pos.y - r - style_indic->body.padding.top; + indic_area.y1 = cpicker->coords.y1 + ext->indic.pos.y - r - style_indic->body.padding.top; indic_area.x2 = cpicker->coords.x1 + ext->indic.pos.x + r + style_indic->body.padding.right; indic_area.y2 = cpicker->coords.y1 + ext->indic.pos.y + r + style_indic->body.padding.bottom; diff --git a/src/lv_objx/lv_cpicker.h b/src/lv_objx/lv_cpicker.h index a5fe5239a..0e6bea594 100644 --- a/src/lv_objx/lv_cpicker.h +++ b/src/lv_objx/lv_cpicker.h @@ -57,6 +57,7 @@ typedef struct { } indic; uint32_t last_click_time; uint32_t last_change_time; + lv_point_t last_press_point; lv_cpicker_color_mode_t color_mode :2; uint8_t color_mode_fixed :1; lv_cpicker_type_t type :1; From 10d90a8baa36f0fc2da68492b4c9c34891bdcd88 Mon Sep 17 00:00:00 2001 From: Gabor Kiss-Vamosi Date: Tue, 1 Oct 2019 22:08:14 +0200 Subject: [PATCH 25/25] cpicker: minor fixes --- src/lv_objx/lv_cpicker.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/lv_objx/lv_cpicker.c b/src/lv_objx/lv_cpicker.c index dae87bff8..23dbd6a30 100644 --- a/src/lv_objx/lv_cpicker.c +++ b/src/lv_objx/lv_cpicker.c @@ -851,12 +851,18 @@ static lv_res_t lv_cpicker_signal(lv_obj_t * cpicker, lv_signal_t sign, void * p lv_coord_t r_in = w / 2; p.x -= r_in; p.y -= r_in; - r_in -= style_main->line.width * 2; /* *2 to let some sensitive space inside*/ + r_in -= style_main->line.width; + + if(r_in > LV_DPI / 2) { + r_in -= style_main->line.width; /* to let some sensitive space inside*/ + + if(r_in < LV_DPI / 2) r_in = LV_DPI / 2; + } /*If the inner area is being pressed, go to the next color mode on long press*/ if(p.x * p.x + p.y * p.y < r_in * r_in) { uint32_t diff = lv_tick_elaps(ext->last_change_time); - if(diff > indev->driver.long_press_time * 2 && !ext->color_mode_fixed) { + if(diff > indev->driver.long_press_time && !ext->color_mode_fixed) { next_color_mode(cpicker); lv_indev_wait_release(lv_indev_get_act()); }