1
0
mirror of https://github.com/lvgl/lvgl.git synced 2025-01-28 07:03:00 +08:00

add btn and arc to classes

This commit is contained in:
Gabor Kiss-Vamosi 2020-12-14 10:56:59 +01:00
parent ec124559f6
commit 6d964609e5
9 changed files with 643 additions and 802 deletions

View File

@ -1704,7 +1704,7 @@ static lv_res_t lv_obj_signal(lv_obj_t * obj, lv_signal_t sign, void * param)
lv_obj_t * parent = lv_obj_get_parent(obj); lv_obj_t * parent = lv_obj_get_parent(obj);
lv_obj_t * child = obj; lv_obj_t * child = obj;
while(parent && lv_obj_has_flag(child, LV_OBJ_FLAG_FOCUS_SCROLL)) { while(parent && lv_obj_has_flag(child, LV_OBJ_FLAG_FOCUS_SCROLL)) {
lv_obj_scroll_to_child(parent, child, LV_ANIM_ON); lv_obj_scroll_to_view(child, LV_ANIM_ON);
child = parent; child = parent;
parent = lv_obj_get_parent(parent); parent = lv_obj_get_parent(parent);
} }

View File

@ -320,29 +320,33 @@ void lv_obj_scroll_to_y(lv_obj_t * obj, lv_coord_t y, lv_anim_enable_t anim_en)
lv_obj_scroll_by(obj, 0, -y + lv_obj_get_scroll_y(obj), anim_en); lv_obj_scroll_by(obj, 0, -y + lv_obj_get_scroll_y(obj), anim_en);
} }
void lv_obj_scroll_to_child(lv_obj_t * obj, lv_obj_t * child, lv_anim_enable_t anim_en) void lv_obj_scroll_to_view(lv_obj_t * obj, lv_anim_enable_t anim_en)
{ {
lv_coord_t pleft = lv_obj_get_style_pad_left(obj, LV_OBJ_PART_MAIN); lv_obj_t * parent = lv_obj_get_parent(obj);
lv_coord_t pright = lv_obj_get_style_pad_right(obj, LV_OBJ_PART_MAIN);
lv_coord_t ptop = lv_obj_get_style_pad_top(obj, LV_OBJ_PART_MAIN);
lv_coord_t pbottom = lv_obj_get_style_pad_bottom(obj, LV_OBJ_PART_MAIN);
lv_coord_t left_diff = obj->coords.x1 + pleft - child->coords.x1; lv_coord_t pleft = lv_obj_get_style_pad_left(parent, LV_OBJ_PART_MAIN);
lv_coord_t right_diff = -(obj->coords.x2 - pright - child->coords.x2); lv_coord_t pright = lv_obj_get_style_pad_right(parent, LV_OBJ_PART_MAIN);
lv_coord_t top_diff = obj->coords.y1 + ptop - child->coords.y1; lv_coord_t ptop = lv_obj_get_style_pad_top(parent, LV_OBJ_PART_MAIN);
lv_coord_t bottom_diff = -(obj->coords.y2 - pbottom - child->coords.y2); lv_coord_t pbottom = lv_obj_get_style_pad_bottom(parent, LV_OBJ_PART_MAIN);
lv_coord_t left_diff = parent->coords.x1 + pleft - obj->coords.x1;
lv_coord_t right_diff = -(parent->coords.x2 - pright - obj->coords.x2);
lv_coord_t top_diff = parent->coords.y1 + ptop - obj->coords.y1;
lv_coord_t bottom_diff = -(parent->coords.y2 - pbottom - obj->coords.y2);
lv_coord_t y_scroll = 0; lv_coord_t y_scroll = 0;
if(top_diff > 0 && bottom_diff > 0) y_scroll = 0; if((top_diff > 0 || bottom_diff > 0)) {
if(top_diff > 0) y_scroll = top_diff; if(LV_MATH_ABS(top_diff) < LV_MATH_ABS(bottom_diff)) y_scroll = top_diff;
else if(bottom_diff > 0) y_scroll = -bottom_diff; else y_scroll = -bottom_diff;
}
lv_coord_t x_scroll = 0; lv_coord_t x_scroll = 0;
if(left_diff > 0 && right_diff > 0) x_scroll = 0; if((left_diff > 0 || right_diff > 0)) {
if(left_diff > 0) y_scroll = left_diff; if(LV_MATH_ABS(left_diff) < LV_MATH_ABS(right_diff)) x_scroll = left_diff;
else if(right_diff > 0) x_scroll = -right_diff; else x_scroll = -right_diff;
}
lv_obj_scroll_by(obj, x_scroll, y_scroll, anim_en); lv_obj_scroll_by(parent, x_scroll, y_scroll, anim_en);
} }

View File

@ -228,11 +228,10 @@ void lv_obj_scroll_to_y(struct _lv_obj_t * obj, lv_coord_t y, lv_anim_enable_t a
/** /**
* Scroll to an object * Scroll to an object
* @param obj pointer to a parent whose children should be scrolled * @param obj pointer to an object to scroll into view
* @param child pointer to an object to which scrolling should happen
* @param anim_en LV_ANIM_ON: scroll with animation; LV_ANIM_OFF: scroll immediately * @param anim_en LV_ANIM_ON: scroll with animation; LV_ANIM_OFF: scroll immediately
*/ */
void lv_obj_scroll_to_child(struct _lv_obj_t * obj, struct _lv_obj_t * child, lv_anim_enable_t anim_en); void lv_obj_scroll_to_view(struct _lv_obj_t * obj, lv_anim_enable_t anim_en);
/********************** /**********************
* MACROS * MACROS

File diff suppressed because it is too large Load Diff

View File

@ -34,28 +34,40 @@ enum {
}; };
typedef uint8_t lv_arc_type_t; typedef uint8_t lv_arc_type_t;
/*Data of arc*/
typedef struct {
/*New data for this type */
uint16_t rotation_angle;
uint16_t arc_angle_start;
uint16_t arc_angle_end;
uint16_t bg_angle_start;
uint16_t bg_angle_end;
lv_style_list_t style_arc;
lv_style_list_t style_knob; /* Style of the knob */
int16_t cur_value; /*Current value of the arc*/
int16_t min_value; /*Minimum value of the arc*/ LV_CLASS_DECLARE_START(lv_arc, lv_obj);
int16_t max_value; /*Maximum value of the arc*/
uint16_t dragging : 1; #define _lv_arc_constructor void (*constructor)(struct _lv_obj_t * obj, struct _lv_obj_t * parent, const struct _lv_obj_t * copy)
uint16_t type : 2;
uint16_t adjustable : 1; #define _lv_arc_data \
uint16_t min_close : 1; /*1: the last pressed angle was closer to minimum end*/ _lv_obj_data \
uint16_t chg_rate; /*Drag angle rate of change of the arc (degrees/sec)*/ uint16_t angle_ofs; \
uint32_t last_tick; /*Last dragging event timestamp of the arc*/ uint16_t indic_angle_start; \
uint16_t indic_angle_end; \
uint16_t bg_angle_start; \
uint16_t bg_angle_end; \
lv_style_list_t style_arc; \
lv_style_list_t style_knob; /* Style of the knob */ \
int16_t value; /*Current value of the arc*/ \
int16_t min_value; /*Minimum value of the arc*/ \
int16_t max_value; /*Maximum value of the arc*/ \
uint16_t dragging : 1; \
uint16_t type : 2; \
uint16_t adjustable : 1; \
uint16_t min_close : 1; /*1: the last pressed angle was closer to minimum end*/ \
uint16_t chg_rate; /*Drag angle rate of change of the arc (degrees/sec)*/ \
uint32_t last_tick; /*Last dragging event timestamp of the arc*/ \
int16_t last_angle; /*Last dragging angle of the arc*/ int16_t last_angle; /*Last dragging angle of the arc*/
} lv_arc_ext_t;
#define _lv_arc_class_dsc \
_lv_obj_class_dsc \
LV_CLASS_DECLARE_END(lv_arc, lv_obj);
extern lv_arc_class_t lv_arc;
/*Parts of the arc*/ /*Parts of the arc*/
enum { enum {
@ -135,7 +147,7 @@ void lv_arc_set_bg_angles(lv_obj_t * arc, uint16_t start, uint16_t end);
* @param arc pointer to an arc object * @param arc pointer to an arc object
* @param rotation_angle rotation angle * @param rotation_angle rotation angle
*/ */
void lv_arc_set_rotation(lv_obj_t * arc, uint16_t rotation_angle); void lv_arc_set_angle_ofs(lv_obj_t * arc, uint16_t rotation_angle);
/** /**
@ -184,70 +196,100 @@ void lv_arc_set_adjustable(lv_obj_t * arc, bool adjustable);
* @param arc pointer to an arc object * @param arc pointer to an arc object
* @return the start angle [0..360] * @return the start angle [0..360]
*/ */
uint16_t lv_arc_get_angle_start(lv_obj_t * arc); static inline uint16_t lv_arc_get_angle_start(lv_obj_t * obj)
{
LV_ASSERT_OBJ(obj, LV_OBJX_NAME);
return ((lv_arc_t*) obj)->indic_angle_start;
}
/** /**
* Get the end angle of an arc. * Get the end angle of an arc.
* @param arc pointer to an arc object * @param arc pointer to an arc object
* @return the end angle [0..360] * @return the end angle [0..360]
*/ */
uint16_t lv_arc_get_angle_end(lv_obj_t * arc); static inline uint16_t lv_arc_get_angle_end(lv_obj_t * obj)
{
LV_ASSERT_OBJ(obj, LV_OBJX_NAME);
return ((lv_arc_t*) obj)->indic_angle_end;
}
/** /**
* Get the start angle of an arc background. * Get the start angle of an arc background.
* @param arc pointer to an arc object * @param arc pointer to an arc object
* @return the start angle [0..360] * @return the start angle [0..360]
*/ */
uint16_t lv_arc_get_bg_angle_start(lv_obj_t * arc); static inline uint16_t lv_arc_get_bg_angle_start(lv_obj_t * obj)
{
LV_ASSERT_OBJ(obj, LV_OBJX_NAME);
return ((lv_arc_t*) obj)->bg_angle_start;
}
/** /**
* Get the end angle of an arc background. * Get the end angle of an arc background.
* @param arc pointer to an arc object * @param arc pointer to an arc object
* @return the end angle [0..360] * @return the end angle [0..360]
*/ */
uint16_t lv_arc_get_bg_angle_end(lv_obj_t * arc); static inline uint16_t lv_arc_get_bg_angle_end(lv_obj_t * obj)
{
LV_ASSERT_OBJ(obj, LV_OBJX_NAME);
return ((lv_arc_t*) obj)->bg_angle_end;
}
/** /**
* Get whether the arc is type or not. * Get the value of a arc
* @param arc pointer to a arc object * @param arc pointer to a arc object
* @return arc type * @return the value of the arc
*/ */
lv_arc_type_t lv_arc_get_type(const lv_obj_t * arc); static inline int16_t lv_arc_get_value(const lv_obj_t * obj)
{
/** LV_ASSERT_OBJ(obj, LV_OBJX_NAME);
* Get the value of the of a arc return ((lv_arc_t*) obj)->value;
* @param arc pointer to a arc object }
* @return the value of the of the arc
*/
int16_t lv_arc_get_value(const lv_obj_t * arc);
/** /**
* Get the minimum value of a arc * Get the minimum value of a arc
* @param arc pointer to a arc object * @param arc pointer to a arc object
* @return the minimum value of the arc * @return the minimum value of the arc
*/ */
int16_t lv_arc_get_min_value(const lv_obj_t * arc); static inline int16_t lv_arc_get_min_value(const lv_obj_t * obj)
{
LV_ASSERT_OBJ(obj, LV_OBJX_NAME);
return ((lv_arc_t*) obj)->min_value;
}
/** /**
* Get the maximum value of a arc * Get the maximum value of a arc
* @param arc pointer to a arc object * @param arc pointer to a arc object
* @return the maximum value of the arc * @return the maximum value of the arc
*/ */
int16_t lv_arc_get_max_value(const lv_obj_t * arc); static inline int16_t lv_arc_get_max_value(const lv_obj_t * obj)
{
LV_ASSERT_OBJ(obj, LV_OBJX_NAME);
return ((lv_arc_t*) obj)->max_value;
}
/** /**
* Give the arc is being dragged or not * Get whether the arc is type or not.
* @param arc pointer to a arc object * @param arc pointer to a arc object
* @return true: drag in progress false: not dragged * @return arc type
*/ */
bool lv_arc_is_dragged(const lv_obj_t * arc); static inline lv_arc_type_t lv_arc_get_type(const lv_obj_t * obj)
{
LV_ASSERT_OBJ(obj, LV_OBJX_NAME);
return ((lv_arc_t*) obj)->type;
}
/** /**
* Get whether the arc is adjustable. * Get whether the arc is adjustable.
* @param arc pointer to a arc object * @param arc pointer to a arc object
* @return whether the arc has a knob that can be dragged * @return whether the arc has a knob that can be dragged
*/ */
bool lv_arc_get_adjustable(lv_obj_t * arc); static inline bool lv_arc_get_adjustable(lv_obj_t * obj)
{
LV_ASSERT_OBJ(obj, LV_OBJX_NAME);
return ((lv_arc_t*) obj)->adjustable;
}
/*===================== /*=====================
* Other functions * Other functions

View File

@ -31,12 +31,14 @@
/********************** /**********************
* STATIC PROTOTYPES * STATIC PROTOTYPES
**********************/ **********************/
static lv_res_t lv_btn_signal(lv_obj_t * btn, lv_signal_t sign, void * param); static void lv_btn_constructor(lv_obj_t * obj, lv_obj_t * parent, const lv_obj_t * copy);
static void lv_btn_destructor(void * obj);
/********************** /**********************
* STATIC VARIABLES * STATIC VARIABLES
**********************/ **********************/
static lv_signal_cb_t ancestor_signal; lv_btn_class_t lv_btn;
/********************** /**********************
* MACROS * MACROS
@ -55,31 +57,21 @@ static lv_signal_cb_t ancestor_signal;
*/ */
lv_obj_t * lv_btn_create(lv_obj_t * parent, const lv_obj_t * copy) lv_obj_t * lv_btn_create(lv_obj_t * parent, const lv_obj_t * copy)
{ {
LV_LOG_TRACE("button create started");
lv_obj_t * btn;
btn = lv_obj_create(parent, copy); if(!lv_btn._inited) {
LV_ASSERT_MEM(btn); LV_CLASS_INIT(lv_btn, lv_obj);
if(btn == NULL) return NULL; lv_btn.constructor = lv_btn_constructor;
lv_btn.destructor = lv_btn_destructor;
}
if(ancestor_signal == NULL) ancestor_signal = lv_obj_get_signal_cb(btn); lv_obj_t * obj = lv_class_new(&lv_btn);
lv_btn.constructor(obj, parent, copy);
lv_obj_set_signal_cb(btn, lv_btn_signal); if(!copy) lv_theme_apply(obj, LV_THEME_BTN);
if(copy == NULL) { LV_LOG_TRACE("button create started");
/*Set layout if the button is not a screen*/ return obj;
if(parent) {
lv_obj_set_size(btn, LV_DPI, LV_DPI / 3);
lv_obj_clear_flag(btn, LV_OBJ_FLAG_SCROLLABLE);
}
lv_theme_apply(btn, LV_THEME_BTN);
}
LV_LOG_INFO("button created");
return btn;
} }
/*===================== /*=====================
@ -94,26 +86,32 @@ lv_obj_t * lv_btn_create(lv_obj_t * parent, const lv_obj_t * copy)
* STATIC FUNCTIONS * STATIC FUNCTIONS
**********************/ **********************/
/** static void lv_btn_constructor(lv_obj_t * obj, lv_obj_t * parent, const lv_obj_t * copy)
* Signal function of the button
* @param btn pointer to a button 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_btn_signal(lv_obj_t * btn, lv_signal_t sign, void * param)
{ {
lv_res_t res; LV_LOG_TRACE("lv_btn create started");
/* Include the ancient signal function */ LV_CLASS_CONSTRUCTOR_BEGIN(obj, lv_btn)
res = ancestor_signal(btn, sign, param); lv_btn.base_p->constructor(obj, parent, copy);
if(res != LV_RES_OK) return res;
if(sign == LV_SIGNAL_GET_TYPE) { lv_obj_set_size(obj, LV_DPI, LV_DPI / 3);
return _lv_obj_handle_get_type_signal(param, LV_OBJX_NAME); lv_obj_clear_flag(obj, LV_OBJ_FLAG_SCROLLABLE);
}
return res;
LV_CLASS_CONSTRUCTOR_END(obj, lv_btn)
LV_LOG_INFO("btn created");
}
static void lv_btn_destructor(void * obj)
{
// lv_bar_t * bar = obj;
//
// _lv_obj_reset_style_list_no_refr(obj, LV_BAR_PART_INDIC);
//#if LV_USE_ANIMATION
// lv_anim_del(&bar->cur_value_anim, NULL);
// lv_anim_del(&bar->start_value_anim, NULL);
//#endif
lv_btn.base_p->destructor(obj);
} }
#endif #endif

View File

@ -33,6 +33,23 @@ enum {
}; };
typedef uint8_t lv_btn_part_t; typedef uint8_t lv_btn_part_t;
LV_CLASS_DECLARE_START(lv_btn, lv_obj);
#define _lv_btn_constructor void (*constructor)(struct _lv_obj_t * obj, struct _lv_obj_t * parent, const struct _lv_obj_t * copy)
#define _lv_btn_data \
_lv_obj_data \
#define _lv_btn_class_dsc \
_lv_obj_class_dsc \
LV_CLASS_DECLARE_END(lv_btn, lv_obj);
extern lv_btn_class_t lv_btn;
/********************** /**********************
* GLOBAL PROTOTYPES * GLOBAL PROTOTYPES
**********************/ **********************/

View File

@ -34,15 +34,16 @@
/********************** /**********************
* STATIC PROTOTYPES * STATIC PROTOTYPES
**********************/ **********************/
static lv_res_t lv_switch_signal(lv_obj_t * sw, lv_signal_t sign, void * param); static void lv_switch_constructor(lv_obj_t * obj, lv_obj_t * parent, const lv_obj_t * copy);
static void lv_switch_destructor(void * obj);
static lv_res_t lv_switch_signal(lv_obj_t * obj, lv_signal_t sign, void * param);
static lv_design_res_t lv_switch_design(lv_obj_t * sw, const lv_area_t * clip_area, lv_design_mode_t mode); static lv_design_res_t lv_switch_design(lv_obj_t * sw, const lv_area_t * clip_area, lv_design_mode_t mode);
static lv_style_list_t * lv_switch_get_style(lv_obj_t * sw, uint8_t part); static lv_style_list_t * lv_switch_get_style(lv_obj_t * sw, uint8_t part);
/********************** /**********************
* STATIC VARIABLES * STATIC VARIABLES
**********************/ **********************/
static lv_signal_cb_t ancestor_signal; lv_switch_class_t lv_switch;
static lv_design_cb_t ancestor_design;
/********************** /**********************
* MACROS * MACROS
@ -61,122 +62,66 @@ static lv_design_cb_t ancestor_design;
*/ */
lv_obj_t * lv_switch_create(lv_obj_t * parent, const lv_obj_t * copy) lv_obj_t * lv_switch_create(lv_obj_t * parent, const lv_obj_t * copy)
{ {
LV_LOG_TRACE("switch create started"); if(!lv_switch._inited) {
LV_CLASS_INIT(lv_switch, lv_obj);
/*Create the ancestor of switch*/ lv_switch.constructor = lv_switch_constructor;
lv_obj_t * sw = lv_bar_create(parent, copy); lv_switch.destructor = lv_switch_destructor;
LV_ASSERT_MEM(sw); lv_switch.design_cb = lv_switch_design;
lv_switch.signal_cb = lv_switch_signal;
if(sw == NULL) return NULL;
if(ancestor_signal == NULL) ancestor_signal = lv_obj_get_signal_cb(sw);
if(ancestor_design == NULL) ancestor_design = lv_obj_get_design_cb(sw);
/*Allocate the switch type specific extended data*/
lv_switch_ext_t * ext = lv_obj_allocate_ext_attr(sw, sizeof(lv_switch_ext_t));
LV_ASSERT_MEM(ext);
if(ext == NULL) {
lv_obj_del(sw);
return NULL;
} }
lv_style_list_init(&ext->style_knob); lv_obj_t * obj = lv_class_new(&lv_switch);
lv_switch.constructor(obj, parent, copy);
/*The signal and design functions are not copied so set them here*/ lv_switch_t * sw = (lv_switch_t *) obj;
lv_obj_set_signal_cb(sw, lv_switch_signal); const lv_switch_t * sw_copy = (const lv_switch_t *) copy;
lv_obj_set_design_cb(sw, lv_switch_design); if(!copy) lv_theme_apply(obj, LV_THEME_SWITCH);
else {
/*Init the new switch switch*/ lv_style_list_copy(&sw->style_indic, &sw_copy->style_indic);
if(copy == NULL) { lv_style_list_copy(&sw->style_knob, &sw_copy->style_knob);
lv_obj_add_flag(sw, LV_OBJ_FLAG_CLICKABLE); _lv_obj_refresh_style(obj, LV_OBJ_PART_ALL, LV_STYLE_PROP_ALL);
lv_obj_set_size(sw, LV_DPX(60), LV_DPX(35));
lv_bar_set_range(sw, 0, 1);
lv_theme_apply(sw, LV_THEME_SWITCH);
} else {
lv_switch_ext_t * copy_ext = lv_obj_get_ext_attr(copy);
lv_style_list_copy(&ext->style_knob, &copy_ext->style_knob);
_lv_obj_refresh_style(sw, LV_OBJ_PART_ALL, LV_STYLE_PROP_ALL);
} }
/*Refresh the style with new signal function*/
LV_LOG_INFO("switch created"); return obj;
return sw;
} }
/*=====================
* Setter functions
*====================*/
/**
* Turn ON the switch
* @param sw pointer to a switch object
* @param anim LV_ANIM_ON: set the value with an animation; LV_ANIM_OFF: change the value immediately
*/
void lv_switch_on(lv_obj_t * sw, lv_anim_enable_t anim)
{
LV_ASSERT_OBJ(sw, LV_OBJX_NAME);
#if LV_USE_ANIMATION == 0
anim = LV_ANIM_OFF;
#endif
if(lv_bar_get_value(sw) == 1)
return;
lv_bar_set_value(sw, 1, anim);
lv_obj_add_state(sw, LV_STATE_CHECKED);
}
/**
* Turn OFF the switch
* @param sw pointer to a switch object
* @param anim LV_ANIM_ON: set the value with an animation; LV_ANIM_OFF: change the value immediately
*/
void lv_switch_off(lv_obj_t * sw, lv_anim_enable_t anim)
{
LV_ASSERT_OBJ(sw, LV_OBJX_NAME);
#if LV_USE_ANIMATION == 0
anim = LV_ANIM_OFF;
#endif
if(lv_bar_get_value(sw) == 0)
return;
lv_bar_set_value(sw, 0, anim);
lv_obj_clear_state(sw, LV_STATE_CHECKED);
}
/**
* Toggle the position of the switch
* @param sw pointer to a switch object
* @param anim LV_ANIM_ON: set the value with an animation; LV_ANIM_OFF: change the value immediately
* @return resulting state of the switch.
*/
bool lv_switch_toggle(lv_obj_t * sw, lv_anim_enable_t anim)
{
LV_ASSERT_OBJ(sw, LV_OBJX_NAME);
#if LV_USE_ANIMATION == 0
anim = LV_ANIM_OFF;
#endif
bool state = lv_switch_get_state(sw);
if(state)
lv_switch_off(sw, anim);
else
lv_switch_on(sw, anim);
return !state;
}
/*=====================
* Getter functions
*====================*/
/********************** /**********************
* STATIC FUNCTIONS * STATIC FUNCTIONS
**********************/ **********************/
static void lv_switch_constructor(lv_obj_t * obj, lv_obj_t * parent, const lv_obj_t * copy)
{
LV_LOG_TRACE("switch create started");
LV_CLASS_CONSTRUCTOR_BEGIN(obj, lv_switch)
lv_switch.base_p->constructor(obj, parent, copy);
lv_switch_t * sw = (lv_switch_t *) obj;
lv_style_list_init(&sw->style_indic);
lv_style_list_init(&sw->style_knob);
if(copy == NULL) {
lv_obj_clear_flag(obj, LV_OBJ_FLAG_SCROLLABLE);
lv_obj_add_flag(obj, LV_OBJ_FLAG_CHECKABLE);
lv_obj_set_size(obj, LV_DPX(60), LV_DPX(35));
}
LV_CLASS_CONSTRUCTOR_END(obj, lv_switch)
LV_LOG_INFO("switch created");
}
static void lv_switch_destructor(void * obj)
{
// lv_bar_t * bar = obj;
//
// _lv_obj_reset_style_list_no_refr(obj, LV_BAR_PART_INDIC);
// _lv_obj_reset_style_list_no_refr(sw, LV_SWITCH_PART_KNOB);
//
// bar->class_p->base_p->destructor(obj);
}
/** /**
* Handle the drawing related tasks of the sliders * Handle the drawing related tasks of the sliders
* @param slider pointer to an object * @param slider pointer to an object
@ -187,7 +132,7 @@ bool lv_switch_toggle(lv_obj_t * sw, lv_anim_enable_t anim)
* LV_DESIGN_DRAW_POST: drawing after every children are drawn * LV_DESIGN_DRAW_POST: drawing after every children are drawn
* @param return an element of `lv_design_res_t` * @param return an element of `lv_design_res_t`
*/ */
static lv_design_res_t lv_switch_design(lv_obj_t * sw, const lv_area_t * clip_area, lv_design_mode_t mode) static lv_design_res_t lv_switch_design(lv_obj_t * obj, const lv_area_t * clip_area, lv_design_mode_t mode)
{ {
/*Return false if the object is not covers the mask_p area*/ /*Return false if the object is not covers the mask_p area*/
if(mode == LV_DESIGN_COVER_CHK) { if(mode == LV_DESIGN_COVER_CHK) {
@ -195,40 +140,59 @@ static lv_design_res_t lv_switch_design(lv_obj_t * sw, const lv_area_t * clip_ar
} }
/*Draw the object*/ /*Draw the object*/
else if(mode == LV_DESIGN_DRAW_MAIN) { else if(mode == LV_DESIGN_DRAW_MAIN) {
lv_bidi_dir_t base_dir = lv_obj_get_base_dir(sw);
/*The ancestor design function will draw the background and the indicator. /*The ancestor design function will draw the background.*/
* It also sets ext->bar.indic_area*/ lv_switch.base_p->design_cb(obj, clip_area, mode);
ancestor_design(sw, clip_area, mode);
lv_switch_ext_t * ext = lv_obj_get_ext_attr(sw); lv_bidi_dir_t base_dir = lv_obj_get_base_dir(obj);
lv_coord_t objw = lv_obj_get_width(sw); lv_switch_t * sw = (lv_switch_t *)obj;
lv_coord_t objh = lv_obj_get_height(sw);
/*Calculate the indicator area*/
lv_style_int_t bg_left = lv_obj_get_style_pad_left(obj, LV_SWITCH_PART_MAIN);
lv_style_int_t bg_right = lv_obj_get_style_pad_right(obj, LV_SWITCH_PART_MAIN);
lv_style_int_t bg_top = lv_obj_get_style_pad_top(obj, LV_SWITCH_PART_MAIN);
lv_style_int_t bg_bottom = lv_obj_get_style_pad_bottom(obj, LV_SWITCH_PART_MAIN);
bool chk = lv_obj_get_state(obj) & LV_STATE_CHECKED;
/*Draw the indicator in checked state*/
if(chk) {
/*Respect the background's padding*/
lv_area_t indic_area;
lv_area_copy(&indic_area, &sw->coords);
indic_area.x1 += bg_left;
indic_area.x2 -= bg_right;
indic_area.y1 += bg_top;
indic_area.y2 -= bg_bottom;
lv_draw_rect_dsc_t draw_indic_dsc;
lv_draw_rect_dsc_init(&draw_indic_dsc);
lv_obj_init_draw_rect_dsc(obj, LV_SWITCH_PART_INDIC, &draw_indic_dsc);
lv_draw_rect(&indic_area, clip_area, &draw_indic_dsc);
}
/*Draw the knob*/
lv_coord_t objh = lv_obj_get_height(obj);
lv_coord_t knob_size = objh; lv_coord_t knob_size = objh;
lv_area_t knob_area; lv_area_t knob_area;
lv_style_int_t bg_left = lv_obj_get_style_pad_left(sw, LV_SWITCH_PART_MAIN); /*Left*/
lv_style_int_t bg_right = lv_obj_get_style_pad_right(sw, LV_SWITCH_PART_MAIN); if((base_dir != LV_BIDI_DIR_RTL && !chk) || (base_dir == LV_BIDI_DIR_RTL && chk)) {
knob_area.x1 = sw->coords.x1 + bg_left;
lv_coord_t max_indic_w = objw - bg_left - bg_right;
lv_coord_t act_indic_w = lv_area_get_width(&ext->bar.indic_area);
if(base_dir != LV_BIDI_DIR_RTL) {
knob_area.x1 = ext->bar.indic_area.x2 - ((act_indic_w * knob_size) / max_indic_w);
knob_area.x2 = knob_area.x1 + knob_size; knob_area.x2 = knob_area.x1 + knob_size;
} }
else { else {
knob_area.x2 = ext->bar.indic_area.x1 + ((act_indic_w * knob_size) / max_indic_w); knob_area.x2 = sw->coords.x2 - bg_right;
knob_area.x1 = knob_area.x2 - knob_size; knob_area.x1 = knob_area.x2 - knob_size;
} }
knob_area.y1 = sw->coords.y1; knob_area.y1 = sw->coords.y1 + bg_top;
knob_area.y2 = sw->coords.y2; knob_area.y2 = sw->coords.y2 - bg_bottom;
lv_style_int_t knob_left = lv_obj_get_style_pad_left(sw, LV_SWITCH_PART_KNOB); lv_style_int_t knob_left = lv_obj_get_style_pad_left(obj, LV_SWITCH_PART_KNOB);
lv_style_int_t knob_right = lv_obj_get_style_pad_right(sw, LV_SWITCH_PART_KNOB); lv_style_int_t knob_right = lv_obj_get_style_pad_right(obj, LV_SWITCH_PART_KNOB);
lv_style_int_t knob_top = lv_obj_get_style_pad_top(sw, LV_SWITCH_PART_KNOB); lv_style_int_t knob_top = lv_obj_get_style_pad_top(obj, LV_SWITCH_PART_KNOB);
lv_style_int_t knob_bottom = lv_obj_get_style_pad_bottom(sw, LV_SWITCH_PART_KNOB); lv_style_int_t knob_bottom = lv_obj_get_style_pad_bottom(obj, LV_SWITCH_PART_KNOB);
/*Apply the paddings on the knob area*/ /*Apply the paddings on the knob area*/
knob_area.x1 -= knob_left; knob_area.x1 -= knob_left;
@ -238,14 +202,14 @@ static lv_design_res_t lv_switch_design(lv_obj_t * sw, const lv_area_t * clip_ar
lv_draw_rect_dsc_t knob_rect_dsc; lv_draw_rect_dsc_t knob_rect_dsc;
lv_draw_rect_dsc_init(&knob_rect_dsc); lv_draw_rect_dsc_init(&knob_rect_dsc);
lv_obj_init_draw_rect_dsc(sw, LV_SWITCH_PART_KNOB, &knob_rect_dsc); lv_obj_init_draw_rect_dsc(obj, LV_SWITCH_PART_KNOB, &knob_rect_dsc);
lv_draw_rect(&knob_area, clip_area, &knob_rect_dsc); lv_draw_rect(&knob_area, clip_area, &knob_rect_dsc);
} }
/*Post draw when the children are drawn*/ /*Post draw when the children are drawn*/
else if(mode == LV_DESIGN_DRAW_POST) { else if(mode == LV_DESIGN_DRAW_POST) {
return ancestor_design(sw, clip_area, mode); return lv_switch.base_p->design_cb(obj, clip_area, mode);
} }
return LV_DESIGN_RES_OK; return LV_DESIGN_RES_OK;
@ -259,62 +223,39 @@ static lv_design_res_t lv_switch_design(lv_obj_t * sw, const lv_area_t * clip_ar
* @param param pointer to a signal specific variable * @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 * @return LV_RES_OK: the object is not deleted in the function; LV_RES_INV: the object is deleted
*/ */
static lv_res_t lv_switch_signal(lv_obj_t * sw, lv_signal_t sign, void * param) static lv_res_t lv_switch_signal(lv_obj_t * obj, lv_signal_t sign, void * param)
{ {
lv_res_t res; lv_res_t res;
/* Include the ancient signal function */ /* Include the ancient signal function */
res = ancestor_signal(sw, sign, param); res = lv_switch.base_p->signal_cb(obj, sign, param);
if(res != LV_RES_OK) return res; if(res != LV_RES_OK) return res;
if(sign == LV_SIGNAL_GET_STYLE) { if(sign == LV_SIGNAL_GET_STYLE) {
lv_get_style_info_t * info = param; lv_get_style_info_t * info = param;
info->result = lv_switch_get_style(sw, info->part); info->result = lv_switch_get_style(obj, info->part);
if(info->result != NULL) return LV_RES_OK; if(info->result != NULL) return LV_RES_OK;
else return ancestor_signal(sw, sign, param); else return lv_switch.base_p->signal_cb(obj, sign, param);
}
else if(sign == LV_SIGNAL_GET_TYPE) {
res = ancestor_signal(sw, sign, param);
if(res != LV_RES_OK) return res;
return _lv_obj_handle_get_type_signal(param, LV_OBJX_NAME);
}
else if(sign == LV_SIGNAL_CLEANUP) {
_lv_obj_reset_style_list_no_refr(sw, LV_SWITCH_PART_KNOB);
}
else if(sign == LV_SIGNAL_RELEASED) {
if(lv_switch_get_state(sw)) lv_switch_off(sw, LV_ANIM_ON);
else lv_switch_on(sw, LV_ANIM_ON);
res = lv_event_send(sw, LV_EVENT_VALUE_CHANGED, NULL);
if(res != LV_RES_OK) return res;
}
else if(sign == LV_SIGNAL_CONTROL) {
#if LV_USE_GROUP
char c = *((char *)param);
if(c == LV_KEY_RIGHT || c == LV_KEY_UP) lv_switch_on(sw, LV_ANIM_ON);
else if(c == LV_KEY_LEFT || c == LV_KEY_DOWN) lv_switch_off(sw, LV_ANIM_ON);
res = lv_event_send(sw, LV_EVENT_VALUE_CHANGED, NULL);
if(res != LV_RES_OK) return res;
#endif
} }
else if(sign == LV_SIGNAL_REFR_EXT_DRAW_PAD) { else if(sign == LV_SIGNAL_REFR_EXT_DRAW_PAD) {
lv_style_int_t knob_left = lv_obj_get_style_pad_left(sw, LV_SWITCH_PART_KNOB); lv_style_int_t knob_left = lv_obj_get_style_pad_left(obj, LV_SWITCH_PART_KNOB);
lv_style_int_t knob_right = lv_obj_get_style_pad_right(sw, LV_SWITCH_PART_KNOB); lv_style_int_t knob_right = lv_obj_get_style_pad_right(obj, LV_SWITCH_PART_KNOB);
lv_style_int_t knob_top = lv_obj_get_style_pad_top(sw, LV_SWITCH_PART_KNOB); lv_style_int_t knob_top = lv_obj_get_style_pad_top(obj, LV_SWITCH_PART_KNOB);
lv_style_int_t knob_bottom = lv_obj_get_style_pad_bottom(sw, LV_SWITCH_PART_KNOB); lv_style_int_t knob_bottom = lv_obj_get_style_pad_bottom(obj, LV_SWITCH_PART_KNOB);
/* The smaller size is the knob diameter*/ /* The smaller size is the knob diameter*/
lv_coord_t knob_size = LV_MATH_MIN(lv_obj_get_width(sw), lv_obj_get_height(sw)) >> 1; lv_coord_t knob_size = LV_MATH_MIN(lv_obj_get_width(obj), lv_obj_get_height(obj)) >> 1;
knob_size += LV_MATH_MAX(LV_MATH_MAX(knob_left, knob_right), LV_MATH_MAX(knob_bottom, knob_top)); knob_size += LV_MATH_MAX(LV_MATH_MAX(knob_left, knob_right), LV_MATH_MAX(knob_bottom, knob_top));
knob_size += 2; /*For rounding error*/ knob_size += 2; /*For rounding error*/
knob_size += _lv_obj_get_draw_rect_ext_pad_size(sw, LV_SWITCH_PART_KNOB); knob_size += _lv_obj_get_draw_rect_ext_pad_size(obj, LV_SWITCH_PART_KNOB);
/*Indic. size is handled by bar*/
lv_coord_t * s = param; lv_coord_t * s = param;
*s = LV_MATH_MAX(*s, knob_size); *s = LV_MATH_MAX(*s, knob_size);
*s = LV_MATH_MAX(*s, _lv_obj_get_draw_rect_ext_pad_size(obj, LV_SWITCH_PART_INDIC));
}
else if(sign == LV_SIGNAL_RELEASED) {
lv_obj_invalidate(obj);
} }
else if(sign == LV_SIGNAL_GET_EDITABLE) { else if(sign == LV_SIGNAL_GET_EDITABLE) {
#if LV_USE_GROUP #if LV_USE_GROUP
@ -326,11 +267,11 @@ static lv_res_t lv_switch_signal(lv_obj_t * sw, lv_signal_t sign, void * param)
return res; return res;
} }
static lv_style_list_t * lv_switch_get_style(lv_obj_t * sw, uint8_t part) static lv_style_list_t * lv_switch_get_style(lv_obj_t * obj, uint8_t part)
{ {
LV_ASSERT_OBJ(sw, LV_OBJX_NAME); LV_ASSERT_OBJ(obj, LV_OBJX_NAME);
lv_switch_ext_t * ext = lv_obj_get_ext_attr(sw); lv_switch_t * sw = (lv_switch_t *) obj;
lv_style_list_t * style_dsc_p; lv_style_list_t * style_dsc_p;
switch(part) { switch(part) {
@ -338,10 +279,10 @@ static lv_style_list_t * lv_switch_get_style(lv_obj_t * sw, uint8_t part)
style_dsc_p = &sw->style_list; style_dsc_p = &sw->style_list;
break; break;
case LV_SWITCH_PART_INDIC: case LV_SWITCH_PART_INDIC:
style_dsc_p = &ext->bar.style_indic; style_dsc_p = &sw->style_indic;
break; break;
case LV_SWITCH_PART_KNOB: case LV_SWITCH_PART_KNOB:
style_dsc_p = &ext->style_knob; style_dsc_p = &sw->style_knob;
break; break;
default: default:
style_dsc_p = NULL; style_dsc_p = NULL;

View File

@ -22,7 +22,7 @@ extern "C" {
#error "lv_switch: lv_slider is required. Enable it in lv_conf.h (LV_USE_SLIDER 1)" #error "lv_switch: lv_slider is required. Enable it in lv_conf.h (LV_USE_SLIDER 1)"
#endif #endif
#include "lv_bar.h" #include "../lv_core/lv_obj.h"
/********************* /*********************
* DEFINES * DEFINES
@ -31,20 +31,31 @@ extern "C" {
/********************** /**********************
* TYPEDEFS * TYPEDEFS
**********************/ **********************/
/*Data of switch*/
typedef struct {
lv_bar_ext_t bar; /*Ext. of ancestor*/ LV_CLASS_DECLARE_START(lv_switch, lv_obj);
/*New data for this type */
lv_style_list_t style_knob; /*Style of the knob*/ #define _lv_switch_constructor void (*constructor)(struct _lv_obj_t * obj, struct _lv_obj_t * parent, const struct _lv_obj_t * copy)
} lv_switch_ext_t;
#define _lv_switch_data \
_lv_obj_data \
lv_style_list_t style_indic; \
lv_style_list_t style_knob;
#define _lv_switch_class_dsc \
_lv_obj_class_dsc \
LV_CLASS_DECLARE_END(lv_switch, lv_obj);
extern lv_switch_class_t lv_switch;
/** /**
* Switch parts. * Switch parts.
*/ */
enum { enum {
LV_SWITCH_PART_MAIN = LV_BAR_PART_MAIN, /**< Switch background. */ LV_SWITCH_PART_MAIN = LV_OBJ_PART_MAIN, /**< Switch background. */
LV_SWITCH_PART_INDIC = LV_BAR_PART_INDIC, /**< Switch fill area. */ LV_SWITCH_PART_INDIC, /**< Switch fill area. */
LV_SWITCH_PART_KNOB = _LV_BAR_PART_VIRTUAL_LAST, /**< Switch knob. */ LV_SWITCH_PART_KNOB, /**< Switch knob. */
_LV_SWITCH_PART_VIRTUAL_LAST _LV_SWITCH_PART_VIRTUAL_LAST
}; };
@ -63,67 +74,6 @@ typedef uint8_t lv_switch_part_t;
*/ */
lv_obj_t * lv_switch_create(lv_obj_t * parent, const lv_obj_t * copy); lv_obj_t * lv_switch_create(lv_obj_t * parent, const lv_obj_t * copy);
/*=====================
* Setter functions
*====================*/
/**
* Turn ON the switch
* @param sw pointer to a switch object
* @param anim LV_ANIM_ON: set the value with an animation; LV_ANIM_OFF: change the value immediately
*/
void lv_switch_on(lv_obj_t * sw, lv_anim_enable_t anim);
/**
* Turn OFF the switch
* @param sw pointer to a switch object
* @param anim LV_ANIM_ON: set the value with an animation; LV_ANIM_OFF: change the value immediately
*/
void lv_switch_off(lv_obj_t * sw, lv_anim_enable_t anim);
/**
* Toggle the position of the switch
* @param sw pointer to a switch object
* @param anim LV_ANIM_ON: set the value with an animation; LV_ANIM_OFF: change the value immediately
* @return resulting state of the switch.
*/
bool lv_switch_toggle(lv_obj_t * sw, lv_anim_enable_t anim);
/**
* Set the animation time of the switch
* @param sw pointer to a switch object
* @param anim_time animation time
* @return style pointer to a style
*/
static inline void lv_switch_set_anim_time(lv_obj_t * sw, uint16_t anim_time)
{
lv_bar_set_anim_time(sw, anim_time);
}
/*=====================
* Getter functions
*====================*/
/**
* Get the state of a switch
* @param sw pointer to a switch object
* @return false: OFF; true: ON
*/
static inline bool lv_switch_get_state(const lv_obj_t * sw)
{
return lv_bar_get_value(sw) == 1 ? true : false;
}
/**
* Get the animation time of the switch
* @param sw pointer to a switch object
* @return style pointer to a style
*/
static inline uint16_t lv_switch_get_anim_time(const lv_obj_t * sw)
{
return lv_bar_get_anim_time(sw);
}
/********************** /**********************
* MACROS * MACROS
**********************/ **********************/