diff --git a/lv_objx/lv_slider.c b/lv_objx/lv_slider.c index 814f2867fd..11a108fd32 100644 --- a/lv_objx/lv_slider.c +++ b/lv_objx/lv_slider.c @@ -256,13 +256,17 @@ static bool lv_slider_design(lv_obj_t * slider, const area_t * mask, lv_design_m /*If dragged draw to the drag position*/ if(ext->drag_value != LV_SLIDER_NOT_PRESSED) cur_value = ext->drag_value; + else { + char x = 'a'; + x++; + } if(slider_w >= slider_h) { - area_indic.x2 = (int32_t) ((int32_t)area_get_width(&area_indic) * cur_value) / (max_value - min_value); + area_indic.x2 = (int32_t) ((int32_t)area_get_width(&area_indic) * (cur_value - min_value)) / (max_value - min_value); area_indic.x2 += area_indic.x1; } else { - area_indic.y1 = (int32_t) ((int32_t)area_get_height(&area_indic) * cur_value) / (max_value - min_value); + area_indic.y1 = (int32_t) ((int32_t)area_get_height(&area_indic) * (cur_value - min_value)) / (max_value - min_value); area_indic.y1 = area_indic.y2 - area_indic.y1; } @@ -338,6 +342,7 @@ static lv_res_t lv_slider_signal(lv_obj_t * slider, lv_signal_t sign, void * par cord_t knob_w = h; p.x -= slider->coords.x1 + h / 2; /*Modify the point to shift with half knob (important on the start and end)*/ ext->drag_value = (int32_t) ((int32_t) p.x * (ext->bar.max_value - ext->bar.min_value + 1)) / (w - knob_w); + ext->drag_value += ext->bar.min_value; } else { cord_t knob_h = w; p.y -= slider->coords.y1 + w / 2; /*Modify the point to shift with half knob (important on the start and end)*/ @@ -347,11 +352,11 @@ static lv_res_t lv_slider_signal(lv_obj_t * slider, lv_signal_t sign, void * par if(ext->drag_value < ext->bar.min_value) ext->drag_value = ext->bar.min_value; else if(ext->drag_value > ext->bar.max_value) ext->drag_value = ext->bar.max_value; - lv_obj_invalidate(slider); } else if (sign == LV_SIGNAL_PRESS_LOST) { ext->drag_value = LV_SLIDER_NOT_PRESSED; + lv_obj_invalidate(slider); } else if (sign == LV_SIGNAL_RELEASED) { @@ -368,7 +373,7 @@ static lv_res_t lv_slider_signal(lv_obj_t * slider, lv_signal_t sign, void * par } } else if(sign == LV_SIGNAL_REFR_EXT_SIZE) { if(ext->knob_in == 0) { - cord_t x = MATH_MIN(w, h); /*The smaller size is the knob diameter*/ + cord_t x = MATH_MIN(w / 2, h / 2); /*The smaller size is the knob diameter*/ if(slider->ext_size < x) slider->ext_size = x; } else { lv_style_t * style = lv_obj_get_style(slider); diff --git a/lv_objx/lv_sw.c b/lv_objx/lv_sw.c index c5eaff9761..890ef1287d 100644 --- a/lv_objx/lv_sw.c +++ b/lv_objx/lv_sw.c @@ -22,13 +22,12 @@ /********************** * STATIC PROTOTYPES **********************/ -#if 0 /*Slider design is used*/ -static bool lv_sw_design(lv_obj_t * sw, const area_t * mask, lv_design_mode_t mode); -#endif -static lv_signal_func_t ancestor_signal; +static lv_res_t lv_sw_signal(lv_obj_t * sw, lv_signal_t sign, void * param); + /********************** * STATIC VARIABLES **********************/ +static lv_signal_func_t ancestor_signal; /********************** * MACROS @@ -74,8 +73,12 @@ lv_obj_t * lv_sw_create(lv_obj_t * par, lv_obj_t * copy) } /*Copy an existing switch*/ else { - /*Nothing to copy*/ + lv_sw_ext_t *copy_ext = lv_obj_get_ext_attr(copy); + ext->knob_off_style = copy_ext->knob_off_style; + ext->knob_on_style = copy_ext->knob_on_style; + if(lv_sw_get_state(new_sw)) lv_slider_set_style(new_sw, NULL, NULL, ext->knob_on_style); + else lv_slider_set_style(new_sw, NULL, NULL, ext->knob_off_style); /*Refresh the style with new signal function*/ lv_obj_refresh_style(new_sw); } @@ -83,107 +86,138 @@ lv_obj_t * lv_sw_create(lv_obj_t * par, lv_obj_t * copy) return new_sw; } -/** - * Signal function of the switch - * @param sw pointer to a switch object - * @param sign a signal type from lv_signal_t enum - * @param param pointer to a signal specific variable - * @return true: the object is still valid (not deleted), false: the object become invalid - */ -bool lv_sw_signal(lv_obj_t * sw, lv_signal_t sign, void * param) -{ - bool valid; - - lv_sw_ext_t * ext = lv_obj_get_ext_attr(sw); - int16_t old_val = lv_slider_get_value(sw); - - lv_action_t slider_cb = ext->slider.action; - ext->slider.action = NULL; /*Do not let the slider to call the callback. The Switch will do it*/ - - /* Include the ancient signal function */ - valid = ancestor_signal(sw, sign, param); - - /* The object can be deleted so check its validity and then - * make the object specific signal handling */ - if(valid != false) { - if(sign == LV_SIGNAL_CLEANUP) { - /*Nothing to cleanup. (No dynamically allocated memory in 'ext')*/ - } - else if(sign == LV_SIGNAL_PRESSING) { - int16_t act_val = lv_slider_get_value(sw); - if(act_val != old_val) ext->changed = 1; - } - else if(sign == LV_SIGNAL_PRESS_LOST) { - ext->changed = 0; - } - else if(sign == LV_SIGNAL_RELEASED) { - if(ext->changed == 0) { - int16_t v = lv_slider_get_value(sw); - if(v == 0) lv_slider_set_value(sw, 1); - else lv_slider_set_value(sw, 0); - } - if(slider_cb != NULL) slider_cb(sw); - - ext->changed = 0; - } - } - - /*Restore the callback*/ - ext->slider.action = slider_cb; - - return valid; -} - /*===================== * Setter functions *====================*/ -/* - * New object specific "set" function comes here +/** + * Turn ON the switch + * @param sw pointer to a switch object */ +void lv_sw_set_on(lv_obj_t *sw) +{ + lv_sw_ext_t *ext = lv_obj_get_ext_attr(sw); + lv_slider_set_value(sw, 1); + lv_slider_set_style(sw, NULL, NULL,ext->knob_on_style); +} +/** + * Turn OFF the switch + * @param sw pointer to a switch object + */ +void lv_sw_set_off(lv_obj_t *sw) +{ + lv_sw_ext_t *ext = lv_obj_get_ext_attr(sw); + lv_slider_set_value(sw, 0); + lv_slider_set_style(sw, NULL, NULL,ext->knob_off_style); +} + +/** + * Set the styles of a switch + * @param sw pointer to a switch object + * @param bg pointer to the background's style + * @param indic pointer to the indicator's style + * @param knob_off pointer to the knob's style when the switch is OFF + * @param knob_on pointer to the knob's style when the switch is ON + */ +void lv_sw_set_style(lv_obj_t * sw, lv_style_t *bg, lv_style_t *indic, lv_style_t *knob_off, lv_style_t *knob_on) +{ + lv_sw_ext_t *ext = lv_obj_get_ext_attr(sw); + + ext->knob_on_style = knob_on; + ext->knob_off_style = knob_off; + + if(lv_sw_get_state(sw)) lv_slider_set_style(sw, bg, indic, knob_on); + else lv_slider_set_style(sw, bg, indic, knob_off); +} /*===================== * Getter functions *====================*/ -/* - * New object specific "get" function comes here +/** + * Get the style of the switch's knob when the switch is OFF + * @param sw pointer to a switch object + * @return pointer to the switch's knob OFF style */ +lv_style_t * lv_sw_get_style_knob_off(lv_obj_t *sw) +{ + lv_sw_ext_t *ext = lv_obj_get_ext_attr(sw); + return ext->knob_off_style; +} +/** + * Get the style of the switch's knob when the switch is ON + * @param sw pointer to a switch object + * @return pointer to the switch's knob ON style + */ +lv_style_t * lv_sw_get_style_knob_on(lv_obj_t *sw) +{ + lv_sw_ext_t *ext = lv_obj_get_ext_attr(sw); + return ext->knob_on_style; +} + /********************** * STATIC FUNCTIONS **********************/ -#if 0 /*Slider design is used*/ /** - * Handle the drawing related tasks of the switchs - * @param sw 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' + * Signal function of the switch + * @param sw pointer to a switch 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 bool lv_sw_design(lv_obj_t * sw, const area_t * mask, lv_design_mode_t mode) +static lv_res_t lv_sw_signal(lv_obj_t * sw, lv_signal_t sign, void * param) { - /*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_sw_ext_t * ext = lv_obj_get_ext_attr(sw); - } - /*Post draw when the children are drawn*/ - else if(mode == LV_DESIGN_DRAW_POST) { + /*Save the current (old) value before slider signal modifies it*/ + int16_t old_val; + if(sign == LV_SIGNAL_PRESSING) old_val = ext->slider.drag_value; + else old_val = lv_slider_get_value(sw); + /*Do not let the slider to call the callback. The Switch will do it if required*/ + lv_action_t slider_cb = ext->slider.action; + ext->slider.action = NULL; + + lv_res_t res; + /* Include the ancient signal function */ + res = ancestor_signal(sw, 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_PRESSING) { + int16_t act_val = ext->slider.drag_value; + if(act_val != old_val) ext->changed = 1; + } + else if(sign == LV_SIGNAL_PRESS_LOST) { + ext->changed = 0; + if(lv_sw_get_state(sw)) lv_slider_set_style(sw, NULL, NULL, ext->knob_on_style); + else lv_slider_set_style(sw, NULL, NULL, ext->knob_off_style); + } + else if(sign == LV_SIGNAL_RELEASED) { + if(ext->changed == 0) { + int16_t v = lv_slider_get_value(sw); + if(v == 0) lv_slider_set_value(sw, 1); + else lv_slider_set_value(sw, 0); + } + + if(lv_sw_get_state(sw)) lv_slider_set_style(sw, NULL, NULL, ext->knob_on_style); + else lv_slider_set_style(sw, NULL, NULL, ext->knob_off_style); + + if(slider_cb != NULL) slider_cb(sw); + + ext->changed = 0; } - return true; + /*Restore the callback*/ + ext->slider.action = slider_cb; + + return res; } -#endif #endif diff --git a/lv_objx/lv_sw.h b/lv_objx/lv_sw.h index 98f4091e15..0a86d70e53 100644 --- a/lv_objx/lv_sw.h +++ b/lv_objx/lv_sw.h @@ -34,9 +34,11 @@ extern "C" { /*Data of switch*/ typedef struct { - lv_slider_ext_t slider; /*Ext. of ancestor*/ + lv_slider_ext_t slider; /*Ext. of ancestor*/ /*New data for this type */ - uint8_t changed :1; /*Indicates the switch explicitly changed by drag*/ + lv_style_t *knob_off_style; /*Style of the knob when the switch is OFF*/ + lv_style_t *knob_on_style; /*Style of the knob when the switch is ON (NULL to use the same as OFF)*/ + uint8_t changed :1; /*Indicates the switch explicitly changed by drag*/ }lv_sw_ext_t; /********************** @@ -51,48 +53,44 @@ typedef struct */ lv_obj_t * lv_sw_create(lv_obj_t * par, lv_obj_t * copy); -/** - * Signal function of the switch - * @param sw pointer to a switch object - * @param sign a signal type from lv_signal_t enum - * @param param pointer to a signal specific variable - * @return true: the object is still valid (not deleted), false: the object become invalid - */ -bool lv_sw_signal(lv_obj_t * sw, lv_signal_t sign, void * param); - -/****************************** - * TRANSPARENT API FUNCTIONS - ******************************/ - -/** - * Set the styles of a switch - * @param sw pointer to a switch object - * @param bg pointer to the background's style - * @param indic pointer to the indicator's style - * @param knob pointer to the knob's style - */ -static inline void lv_sw_set_style(lv_obj_t * sw, lv_style_t *bg, lv_style_t *indic, lv_style_t *knob) -{ - lv_slider_set_style(sw, bg, indic, knob); -} - /** * Turn ON the switch * @param sw pointer to a switch object */ -static inline void lv_sw_set_on(lv_obj_t *sw) -{ - lv_bar_set_value(sw, 1); -} +void lv_sw_set_on(lv_obj_t *sw); /** * Turn OFF the switch * @param sw pointer to a switch object */ -static inline void lv_sw_set_off(lv_obj_t *sw) -{ - lv_bar_set_value(sw, 0); -} +void lv_sw_set_off(lv_obj_t *sw); +/** + * Set the styles of a switch + * @param sw pointer to a switch object + * @param bg pointer to the background's style + * @param indic pointer to the indicator's style + * @param knob_off pointer to the knob's style when the switch is OFF + * @param knob_on pointer to the knob's style when the switch is ON + */ +void lv_sw_set_style(lv_obj_t * sw, lv_style_t *bg, lv_style_t *indic, lv_style_t *knob_off, lv_style_t *knob_on); + +/** + * Get the style of the switch's knob when the switch is OFF + * @param sw pointer to a switch object + * @return pointer to the switch's knob OFF style + */ +lv_style_t * lv_sw_get_style_knob_off(lv_obj_t *sw); + +/** + * Get the style of the switch's knob when the switch is ON + * @param sw pointer to a switch object + * @return pointer to the switch's knob ON style + */ +lv_style_t * lv_sw_get_style_knob_on(lv_obj_t *sw); + +/****************************** + * TRANSPARENT API FUNCTIONS + ******************************/ /** * Set a function which will be called when the switch is toggled by the user @@ -129,7 +127,7 @@ static inline lv_action_t lv_sw_get_action(lv_obj_t * slider) * @param sw pointer to a switch object * @return pointer to the switch's background style */ -static inline bool lv_sw_get_style_bg(lv_obj_t *sw) +static inline lv_style_t * lv_sw_get_style_bg(lv_obj_t *sw) { return lv_slider_get_style_bg(sw); } @@ -139,21 +137,11 @@ static inline bool lv_sw_get_style_bg(lv_obj_t *sw) * @param sw pointer to a switch object * @return pointer to the switch's indicator style */ -static inline bool lv_sw_get_style_indicator(lv_obj_t *sw) +static inline lv_style_t * lv_sw_get_style_indicator(lv_obj_t *sw) { return lv_slider_get_style_indicator(sw); } -/** - * Get the style of the switch's knob - * @param sw pointer to a switch object - * @return pointer to the switch's knob style - */ -static inline bool lv_sw_get_style_knob(lv_obj_t *sw) -{ - return lv_slider_get_style_knob(sw); -} - /********************** * MACROS **********************/