1
0
mirror of https://github.com/lvgl/lvgl.git synced 2025-01-21 06:53:01 +08:00

experiemt with simplified classes

This commit is contained in:
Gabor Kiss-Vamosi 2021-01-01 13:57:59 +01:00
parent 1d2d73438d
commit 98c2cdde3a
12 changed files with 458 additions and 579 deletions

View File

@ -55,7 +55,6 @@ extern "C" {
/* Can't include lv_obj.h because it includes this header file */ /* Can't include lv_obj.h because it includes this header file */
struct _lv_obj_t; struct _lv_obj_t;
typedef struct _lv_obj_t lv_obj_t;
typedef struct { typedef struct {
const lv_coord_t * col_dsc; const lv_coord_t * col_dsc;
@ -96,16 +95,16 @@ void lv_grid_set_gap(lv_grid_t * grid, lv_coord_t col_gap, uint8_t row_gap);
* @param obj pointer to an object * @param obj pointer to an object
* @param grid the grid to set * @param grid the grid to set
*/ */
void lv_obj_set_grid(lv_obj_t * obj, const lv_grid_t * grid); void lv_obj_set_grid(struct _lv_obj_t * obj, const lv_grid_t * grid);
/** /**
* Get the grid of an object * Get the grid of an object
* @param obj pointer to an object * @param obj pointer to an object
* @return the grid, NULL if no grid * @return the grid, NULL if no grid
*/ */
const lv_grid_t * lv_obj_get_grid(lv_obj_t * obj); const lv_grid_t * lv_obj_get_grid(struct _lv_obj_t * obj);
void lv_obj_set_grid_cell(lv_obj_t * obj, lv_coord_t col_pos, lv_coord_t row_pos); void lv_obj_set_grid_cell(struct _lv_obj_t * obj, lv_coord_t col_pos, lv_coord_t row_pos);
/** /**
* Notify all object if a style is modified * Notify all object if a style is modified
@ -123,9 +122,9 @@ bool _lv_grid_has_fr_col(struct _lv_obj_t * obj);
bool _lv_grid_has_fr_row(struct _lv_obj_t * obj); bool _lv_grid_has_fr_row(struct _lv_obj_t * obj);
void _lv_grid_full_refresh(lv_obj_t * cont); void _lv_grid_full_refresh(struct _lv_obj_t * cont);
void lv_grid_item_refr_pos(lv_obj_t * item); void lv_grid_item_refr_pos(struct _lv_obj_t * item);
/********************** /**********************

View File

@ -86,7 +86,13 @@ static void lv_obj_destructor(void * obj);
static bool lv_initialized = false; static bool lv_initialized = false;
static lv_event_temp_data_t * event_temp_data_head; static lv_event_temp_data_t * event_temp_data_head;
static const void * event_act_data; static const void * event_act_data;
lv_obj_class_t lv_obj; const lv_obj_class_t lv_obj = {
.constructor = lv_obj_constructor,
.destructor = lv_obj_destructor,
.signal_cb = lv_obj_signal,
.design_cb = lv_obj_design,
.ext_size = 0,
};
/********************** /**********************
* MACROS * MACROS
@ -111,6 +117,7 @@ void lv_init(void)
/*Initialize the lv_misc modules*/ /*Initialize the lv_misc modules*/
_lv_mem_init(); _lv_mem_init();
_lv_timer_core_init(); _lv_timer_core_init();
#if LV_USE_FILESYSTEM #if LV_USE_FILESYSTEM
@ -132,12 +139,6 @@ void lv_init(void)
_lv_style_system_init(); _lv_style_system_init();
LV_CLASS_INIT(lv_obj, lv_base);
lv_obj.constructor = lv_obj_constructor;
lv_obj.destructor = lv_obj_destructor;
lv_obj.signal_cb = lv_obj_signal;
lv_obj.design_cb = lv_obj_design;
_lv_obj_style_init(); _lv_obj_style_init();
_lv_ll_init(&LV_GC_ROOT(_lv_disp_ll), sizeof(lv_disp_t)); _lv_ll_init(&LV_GC_ROOT(_lv_disp_ll), sizeof(lv_disp_t));
@ -217,7 +218,10 @@ void lv_deinit(void)
*/ */
lv_obj_t * lv_obj_create(lv_obj_t * parent, const lv_obj_t * copy) lv_obj_t * lv_obj_create(lv_obj_t * parent, const lv_obj_t * copy)
{ {
lv_obj_t * obj = lv_class_new(&lv_obj); lv_obj_t * obj = lv_mem_alloc(sizeof(lv_obj_t));
_lv_memset_00(obj, sizeof(lv_obj_t));
obj->class_p = &lv_obj;
lv_obj.constructor(obj, parent, copy); lv_obj.constructor(obj, parent, copy);
lv_obj_create_finish(obj, parent, copy); lv_obj_create_finish(obj, parent, copy);
@ -1401,7 +1405,6 @@ static void obj_del_core(lv_obj_t * obj)
static void lv_obj_constructor(lv_obj_t * obj, lv_obj_t * parent, const lv_obj_t * copy) static void lv_obj_constructor(lv_obj_t * obj, lv_obj_t * parent, const lv_obj_t * copy)
{ {
LV_CLASS_CONSTRUCTOR_BEGIN(obj, lv_obj) LV_CLASS_CONSTRUCTOR_BEGIN(obj, lv_obj)
lv_obj.base_p->constructor(obj);
/*Create a screen*/ /*Create a screen*/
if(parent == NULL) { if(parent == NULL) {
@ -1522,7 +1525,6 @@ static void lv_obj_destructor(void * p)
lv_obj_remove_all_styles(obj); lv_obj_remove_all_styles(obj);
if(obj->spec_attr) lv_mem_free(obj->spec_attr); if(obj->spec_attr) lv_mem_free(obj->spec_attr);
lv_class_destroy(obj);
} }
/** /**

View File

@ -194,7 +194,7 @@ typedef uint16_t lv_obj_flag_t;
typedef struct { typedef struct {
lv_obj_t ** children; /**< Store the pointer of the children.*/ struct _lv_obj_t ** children; /**< Store the pointer of the children.*/
uint32_t child_cnt; uint32_t child_cnt;
#if LV_USE_GROUP != 0 #if LV_USE_GROUP != 0
void * group_p; void * group_p;
@ -222,30 +222,32 @@ typedef struct {
}lv_obj_spec_attr_t; }lv_obj_spec_attr_t;
LV_CLASS_DECLARE_START(lv_obj, lv_base) #define _lv_obj_constructor
#define _lv_obj_constructor void (*constructor)(struct _lv_obj_t * obj, struct _lv_obj_t * parent, const struct _lv_obj_t * copy) typedef struct {
void (*constructor)(struct _lv_obj_t * obj, struct _lv_obj_t * parent, const struct _lv_obj_t * copy);
void (*destructor)(struct _lv_obj_t * obj);
lv_signal_cb_t signal_cb; /**< Object type specific signal function*/
lv_design_cb_t design_cb; /**< Object type specific design function*/
uint32_t ext_size;
}lv_obj_class_t;
#define _lv_obj_data \ typedef struct _lv_obj_t{
_lv_base_data \ const lv_obj_class_t * class_p;
struct _lv_obj_t * parent; \ void * ext_attr;
lv_obj_spec_attr_t * spec_attr; \ struct _lv_obj_t * parent;
lv_obj_style_list_t style_list; \ lv_obj_spec_attr_t * spec_attr;
lv_area_t coords; \ lv_obj_style_list_t style_list;
lv_coord_t x_set; \ lv_area_t coords;
lv_coord_t y_set; \ lv_coord_t x_set;
lv_coord_t w_set; \ lv_coord_t y_set;
lv_coord_t h_set; \ lv_coord_t w_set;
lv_obj_flag_t flags; \ lv_coord_t h_set;
lv_state_t state; lv_obj_flag_t flags;
lv_state_t state;
}lv_obj_t;
#define _lv_obj_class_dsc \ extern const lv_obj_class_t lv_obj;
_lv_base_class_dsc \
lv_signal_cb_t signal_cb; /**< Object type specific signal function*/ \
lv_design_cb_t design_cb; /**< Object type specific design function*/
LV_CLASS_DECLARE_END(lv_obj, lv_base)
extern lv_obj_class_t lv_obj;
enum { enum {
LV_PART_MAIN, LV_PART_MAIN,

View File

@ -163,13 +163,13 @@ lv_style_value_t lv_obj_get_style_prop(const struct _lv_obj_t * obj, uint8_t par
*/ */
void _lv_obj_refresh_style(struct _lv_obj_t * obj, lv_style_prop_t prop); void _lv_obj_refresh_style(struct _lv_obj_t * obj, lv_style_prop_t prop);
lv_style_t * lv_obj_get_local_style(lv_obj_t * obj, uint32_t part, uint32_t state); lv_style_t * lv_obj_get_local_style(struct _lv_obj_t * obj, uint32_t part, uint32_t state);
/** /**
* Remove all transitions from an object * Remove all transitions from an object
* @param obj pointer to an object * @param obj pointer to an object
*/ */
void _lv_obj_remove_style_trans(struct _lv_obj_t * obj); void _lv_obj_remove_style_trans(struct _lv_obj_t * obj);
void lv_obj_set_style_prop(lv_obj_t * obj, uint32_t part, uint32_t state, lv_style_prop_t prop, lv_style_value_t value); void lv_obj_set_style_prop(struct _lv_obj_t * obj, uint32_t part, uint32_t state, lv_style_prop_t prop, lv_style_value_t value);
#if LV_USE_ANIMATION #if LV_USE_ANIMATION

View File

@ -50,8 +50,6 @@ static uint32_t buf_ptr_p = 1;
void _lv_style_system_init(void) void _lv_style_system_init(void)
{ {
LV_CLASS_INIT(lv_style, lv_base);
lv_style.constructor = NULL;
lv_style.remove_prop = remove_prop; lv_style.remove_prop = remove_prop;
lv_style.set_prop = set_prop; lv_style.set_prop = set_prop;
lv_style.get_prop = get_prop; lv_style.get_prop = get_prop;

View File

@ -316,81 +316,78 @@ typedef struct _lv_style_transiton_t{
uint32_t delay; uint32_t delay;
}lv_style_transiton_t; }lv_style_transiton_t;
LV_CLASS_DECLARE_START(lv_style, lv_base);
#define _lv_style_constructor void (*constructor)(struct _lv_style_t * style)
#if LV_USE_ASSERT_STYLE #if LV_USE_ASSERT_STYLE
# define _LV_STYLE_SENTINEL uint32_t sentinel; # define _LV_STYLE_SENTINEL uint32_t sentinel;
#else #else
# define _LV_STYLE_SENTINEL # define _LV_STYLE_SENTINEL
#endif #endif
#define _lv_style_data \ struct _lv_style_t;
_lv_base_data \
lv_style_ext_t * ext; \
_LV_STYLE_SENTINEL \
/*32*/ \
uint32_t radius :5; \
uint32_t transform_width :5; \
uint32_t transform_height :5; \
uint32_t opa :5; \
uint32_t color_filter_cb :4; \
uint32_t transition :4; \
uint32_t bg_color :4; \
\
uint32_t color_filter_opa :5; \
uint32_t bg_opa :5; \
uint32_t border_opa:5; \
uint32_t img_opa:5; \
uint32_t bg_grad_color :4; \
uint32_t border_color:4; \
uint32_t border_width:4; \
\
uint32_t pad_top:5; \
uint32_t pad_bottom:5; \
uint32_t pad_left:5; \
uint32_t pad_right:5; \
uint32_t text_color:4; \
uint32_t text_font :4; \
uint32_t line_color :4; \
\
uint32_t margin_top:5; \
uint32_t margin_bottom:5; \
uint32_t margin_left:5; \
uint32_t margin_right:5; \
uint32_t outline_color:4; \
uint32_t shadow_color:4; \
uint32_t line_rounded:1; \
uint32_t border_post:1; \
uint32_t clip_corner:1; \
uint32_t has_line_rounded:1; \
uint32_t has_clip_corner:1; \
\
uint32_t text_opa:5; \
uint32_t line_width :5; \
uint32_t line_opa :5; \
uint32_t outline_width:5; \
uint32_t outline_pad:5; \
uint32_t outline_opa:5; \
uint32_t bg_grad_dir:2; \
\
uint32_t shadow_width:5; \
uint32_t shadow_ofs_y:5; \
uint32_t shadow_ofs_x:5; \
uint32_t shadow_spread:5; \
uint32_t shadow_opa:4; \
uint32_t has_bg_grad_dir:1; \
uint32_t has_border_post:1; \
uint32_t dont_index:1; \
#define _lv_style_class_dsc \ typedef struct {
_lv_base_class_dsc \ bool (*remove_prop)(struct _lv_style_t * style, lv_style_prop_t prop);
bool (*remove_prop)(struct _lv_style_t * style, lv_style_prop_t prop); \ void (*set_prop)(struct _lv_style_t * style, lv_style_prop_t prop, lv_style_value_t value);
void (*set_prop)(struct _lv_style_t * style, lv_style_prop_t prop, lv_style_value_t value); \ bool (*get_prop)(const struct _lv_style_t * style, lv_style_prop_t prop, lv_style_value_t * value);
bool (*get_prop)(const struct _lv_style_t * style, lv_style_prop_t prop, lv_style_value_t * value); \ }lv_style_class_t;
LV_CLASS_DECLARE_END(lv_style, lv_base); typedef struct _lv_style_t{
lv_style_class_t * class_p;
lv_style_ext_t * ext;
_LV_STYLE_SENTINEL
/*32*/
uint32_t radius :5;
uint32_t transform_width :5;
uint32_t transform_height :5;
uint32_t opa :5;
uint32_t color_filter_cb :4;
uint32_t transition :4;
uint32_t bg_color :4;
uint32_t color_filter_opa :5;
uint32_t bg_opa :5;
uint32_t border_opa:5;
uint32_t img_opa:5;
uint32_t bg_grad_color :4;
uint32_t border_color:4;
uint32_t border_width:4;
uint32_t pad_top:5;
uint32_t pad_bottom:5;
uint32_t pad_left:5;
uint32_t pad_right:5;
uint32_t text_color:4;
uint32_t text_font :4;
uint32_t line_color :4;
uint32_t margin_top:5;
uint32_t margin_bottom:5;
uint32_t margin_left:5;
uint32_t margin_right:5;
uint32_t outline_color:4;
uint32_t shadow_color:4;
uint32_t line_rounded:1;
uint32_t border_post:1;
uint32_t clip_corner:1;
uint32_t has_line_rounded:1;
uint32_t has_clip_corner:1;
uint32_t text_opa:5;
uint32_t line_width :5;
uint32_t line_opa :5;
uint32_t outline_width:5;
uint32_t outline_pad:5;
uint32_t outline_opa:5;
uint32_t bg_grad_dir:2;
uint32_t shadow_width:5;
uint32_t shadow_ofs_y:5;
uint32_t shadow_ofs_x:5;
uint32_t shadow_spread:5;
uint32_t shadow_opa:4;
uint32_t has_bg_grad_dir:1;
uint32_t has_border_post:1;
uint32_t dont_index:1;
} lv_style_t;
extern lv_style_class_t lv_style; extern lv_style_class_t lv_style;

View File

@ -1,88 +1,89 @@
/** ///**
* @file lv_class.c // * @file lv_class.c
* // *
*/ // */
//
/********************* ///*********************
* INCLUDES // * INCLUDES
*********************/ // *********************/
#include "lv_class.h" //#include "lv_class.h"
#include "lv_mem.h" //#include "lv_mem.h"
//
/********************* ///*********************
* DEFINES // * DEFINES
*********************/ // *********************/
//
/********************** ///**********************
* TYPEDEFS // * TYPEDEFS
**********************/ // **********************/
//
/********************** ///**********************
* STATIC PROTOTYPES // * STATIC PROTOTYPES
**********************/ // **********************/
//
/********************** ///**********************
* STATIC VARIABLES // * STATIC VARIABLES
**********************/ // **********************/
lv_base_class_t lv_base; //lv_base_class_t lv_base;
//
/********************** ///**********************
* MACROS // * MACROS
**********************/ // **********************/
//
/********************** ///**********************
* GLOBAL FUNCTIONS // * GLOBAL FUNCTIONS
**********************/ // **********************/
//
void _lv_class_init(void * class_p, uint32_t class_size, uint32_t instance_size, void * base_p) //void _lv_class_init(void * class_p, uint32_t class_size, uint32_t instance_size, void * base_p)
{ //{
lv_base_class_t * c = class_p; // lv_base_class_t * c = class_p;
const lv_base_class_t * bc = base_p; // const lv_base_class_t * bc = base_p;
_lv_memset_00(c, class_size); // _lv_memset_00(c, class_size);
//
/*By default use the same methods as the base*/ // /*By default use the same methods as the base*/
if(bc) _lv_memcpy(c, base_p, bc->_class_size); // if(bc) _lv_memcpy(c, base_p, bc->_class_size);
//
c->base_p = base_p; /*Save the base to allow accessing its methods later*/ // c->base_p = base_p; /*Save the base to allow accessing its methods later*/
c->constructor = NULL; // c->init = NULL;
c->_instance_size = instance_size; // c->constructor = NULL;
c->_class_size = class_size; // c->_instance_size = instance_size;
c->_inited = 1; // c->_class_size = class_size;
} // c->_inited = 1;
//}
void * lv_class_new(void * class_p) //
{ //void * lv_class_new(void * class_p)
lv_base_class_t * base_class_p = class_p; //{
lv_base_t * instance = lv_mem_alloc(base_class_p->_instance_size); // lv_base_class_t * base_class_p = class_p;
_lv_memset_00(instance, base_class_p->_instance_size); // lv_base_t * instance = lv_mem_alloc(base_class_p->_instance_size);
instance->class_p = class_p; // _lv_memset_00(instance, base_class_p->_instance_size);
return instance; // instance->class_p = class_p;
} // return instance;
//}
//
void lv_class_destroy(void * instance) //
{ //void lv_class_destroy(void * instance)
lv_mem_free(instance); //{
} // lv_mem_free(instance);
//}
/********************** //
* STATIC FUNCTIONS ///**********************
**********************/ // * STATIC FUNCTIONS
// **********************/
//static void desctructor_chain(void * inst) //
////static void desctructor_chain(void * inst)
////{
//// lv_base_t * base_inst = inst;
//// if(base->)
////}
//
///**
// * Constructor of the base class. Just zero out the instance
// * @param inst pointer to an instance
// */
//void lv_class_base_construct(void * inst)
//{ //{
// lv_base_t * base_inst = inst; // lv_base_t * base_inst = inst;
// if(base->) // void * class_p = base_inst->class_p;
// _lv_memset_00(inst, base_inst->class_p->_instance_size);
// base_inst->class_p = class_p; /*Restore class dsc pointer*/
//} //}
/**
* Constructor of the base class. Just zero out the instance
* @param inst pointer to an instance
*/
void lv_class_base_construct(void * inst)
{
lv_base_t * base_inst = inst;
void * class_p = base_inst->class_p;
_lv_memset_00(inst, base_inst->class_p->_instance_size);
base_inst->class_p = class_p; /*Restore class dsc pointer*/
}

View File

@ -1,99 +1,3 @@
/**
* @file lv_class.h
*
*/
#ifndef LV_CLASS_H
#define LV_CLASS_H
#ifdef __cplusplus
extern "C" {
#endif
/*********************
* INCLUDES
*********************/
#include <stdint.h>
/*********************
* DEFINES
*********************/
#define _lv_base_class_dsc \
void(*destructor)(void * inst); \
uint32_t _instance_size; \
uint32_t _class_size; \
uint32_t _inited :1;
#define _lv_base_data
/**********************
* TYPEDEFS
**********************/
typedef struct _lv_base_class_t
{
struct _lv_base_class_t * base_p;
void (*constructor)(void *);
_lv_base_class_dsc
}lv_base_class_t;
typedef struct {
lv_base_class_t * class_p;
_lv_base_data
} lv_base_t;
/**********************
* GLOBAL PROTOTYPES
**********************/
/**
* Initialize a class.
* @param class_p pointer to to class
* @param class_size size of the class in bytes (`sizeof(class_type`))
* @param instance_size size of the instance in bytes (`sizeof(instance_type`)
* @param base_p pointer to the base class.
*/
void _lv_class_init(void * class_p, uint32_t class_size, uint32_t instance_size, void * base_p);
/**
* Dynamically create a new instance of a class
* @param class pointer to a class to create
* @return the created instance
*/
void * lv_class_new(void * class_p);
void lv_class_base_construct(void * inst);
void lv_class_destroy(void * instance);
void lv_class_construct(void * inst, lv_base_class_t * dsc);
extern lv_base_class_t lv_base;
/**********************
* MACROS
**********************/
/**
* Start class declaration
*/
#define LV_CLASS_DECLARE_START(classname, basename) \
struct _##classname##_t; \
struct _##classname##_class_t; \
/**
* End class declaration
*/
#define LV_CLASS_DECLARE_END(classname, basename) \
typedef struct _##classname##_class_t { \
basename##_class_t * base_p; \
_##classname##_constructor; \
_##classname##_class_dsc \
}classname##_class_t; \
\
typedef struct _##classname##_t { \
classname##_class_t * class_p; \
_##classname##_data \
} classname##_t;
/** /**
* Start the constructor * Start the constructor
@ -101,7 +5,7 @@ typedef struct _##classname##_t { \
* It's important because the virtual functions should be called from the level of the constructor. * It's important because the virtual functions should be called from the level of the constructor.
*/ */
#define LV_CLASS_CONSTRUCTOR_BEGIN(inst, classname) \ #define LV_CLASS_CONSTRUCTOR_BEGIN(inst, classname) \
void * _original_class_p = ((lv_base_t*)inst)->class_p; \ void * _original_class_p = inst->class_p; \
obj->class_p = (void*)&classname; obj->class_p = (void*)&classname;
/** /**
@ -109,16 +13,5 @@ typedef struct _##classname##_t { \
* It reverts the original base class (changed by LV_CLASS_CONSTRUCTOR_BEGIN). * It reverts the original base class (changed by LV_CLASS_CONSTRUCTOR_BEGIN).
*/ */
#define LV_CLASS_CONSTRUCTOR_END(inst, classname) \ #define LV_CLASS_CONSTRUCTOR_END(inst, classname) \
((lv_base_t*)inst)->class_p = _original_class_p; inst->class_p = _original_class_p;
/**
* Initialize a class. Need to be called only once per class
*/
#define LV_CLASS_INIT(classname, basename) _lv_class_init(&(classname), sizeof(classname##_class_t), sizeof(classname##_t), &(basename));
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /*LV_CLASS_H*/

View File

@ -37,15 +37,15 @@
* STATIC PROTOTYPES * STATIC PROTOTYPES
**********************/ **********************/
static void lv_bar_constructor(lv_obj_t * obj, lv_obj_t * parent, const lv_obj_t * copy); static void lv_bar_constructor(lv_obj_t * obj, lv_obj_t * parent, const lv_obj_t * copy);
static void lv_bar_destructor(void * obj); static void lv_bar_destructor(lv_obj_t * obj);
static lv_design_res_t lv_bar_design(lv_obj_t * bar, const lv_area_t * clip_area, lv_design_mode_t mode); static lv_design_res_t lv_bar_design(lv_obj_t * bar, const lv_area_t * clip_area, lv_design_mode_t mode);
static lv_res_t lv_bar_signal(lv_obj_t * bar, lv_signal_t sign, void * param); static lv_res_t lv_bar_signal(lv_obj_t * bar, lv_signal_t sign, void * param);
static void draw_indic(lv_obj_t * bar, const lv_area_t * clip_area); static void draw_indic(lv_obj_t * bar, const lv_area_t * clip_area);
#if LV_USE_ANIMATION #if LV_USE_ANIMATION
static void lv_bar_set_value_with_anim(lv_bar_t * bar, int16_t new_value, int16_t * value_ptr, static void lv_bar_set_value_with_anim(lv_obj_t * obj, int16_t new_value, int16_t * value_ptr,
lv_bar_anim_t * anim_info, lv_anim_enable_t en); lv_bar_anim_t * anim_info, lv_anim_enable_t en);
static void lv_bar_init_anim(lv_bar_t * bar, lv_bar_anim_t * bar_anim); static void lv_bar_init_anim(lv_obj_t * bar, lv_bar_anim_t * bar_anim);
static void lv_bar_anim(lv_bar_anim_t * bar, lv_anim_value_t value); static void lv_bar_anim(lv_bar_anim_t * bar, lv_anim_value_t value);
static void lv_bar_anim_ready(lv_anim_t * a); static void lv_bar_anim_ready(lv_anim_t * a);
#endif #endif
@ -53,7 +53,13 @@ static void lv_bar_anim_ready(lv_anim_t * a);
/********************** /**********************
* STATIC VARIABLES * STATIC VARIABLES
**********************/ **********************/
lv_bar_class_t lv_bar; const lv_obj_class_t lv_bar = {
.constructor = lv_bar_constructor,
.destructor = lv_bar_destructor,
.signal_cb = lv_bar_signal,
.design_cb = lv_bar_design,
.ext_size = sizeof(lv_bar_ext_t),
};
/********************** /**********************
* MACROS * MACROS
@ -62,7 +68,6 @@ lv_bar_class_t lv_bar;
/********************** /**********************
* GLOBAL FUNCTIONS * GLOBAL FUNCTIONS
**********************/ **********************/
/** /**
* Create a bar objects * Create a bar objects
* @param par pointer to an object, it will be the parent of the new bar * @param par pointer to an object, it will be the parent of the new bar
@ -72,15 +77,15 @@ lv_bar_class_t lv_bar;
*/ */
lv_obj_t * lv_bar_create(lv_obj_t * parent, const lv_obj_t * copy) lv_obj_t * lv_bar_create(lv_obj_t * parent, const lv_obj_t * copy)
{ {
if(!lv_bar._inited) { lv_obj_t * obj = lv_mem_alloc(sizeof(lv_obj_t));
LV_CLASS_INIT(lv_bar, lv_obj); _lv_memset_00(obj, sizeof(lv_obj_t));
lv_bar.constructor = lv_bar_constructor; obj->class_p = &lv_bar;
lv_bar.destructor = lv_bar_destructor;
lv_bar.design_cb = lv_bar_design; if(obj->class_p->ext_size) {
lv_bar.signal_cb = lv_bar_signal; obj->ext_attr = lv_mem_alloc(sizeof(lv_bar_ext_t));
_lv_memset_00(obj->ext_attr, sizeof(lv_bar_ext_t));
} }
lv_obj_t * obj = lv_class_new(&lv_bar);
lv_bar.constructor(obj, parent, copy); lv_bar.constructor(obj, parent, copy);
lv_obj_create_finish(obj, parent, copy); lv_obj_create_finish(obj, parent, copy);
@ -101,23 +106,23 @@ lv_obj_t * lv_bar_create(lv_obj_t * parent, const lv_obj_t * copy)
void lv_bar_set_value(lv_obj_t * obj, int16_t value, lv_anim_enable_t anim) void lv_bar_set_value(lv_obj_t * obj, int16_t value, lv_anim_enable_t anim)
{ {
LV_ASSERT_OBJ(obj, LV_OBJX_NAME); LV_ASSERT_OBJ(obj, LV_OBJX_NAME);
lv_bar_t * bar = (lv_bar_t *)obj; lv_bar_ext_t * ext = obj->ext_attr;
if(bar->cur_value == value) return; if(ext->cur_value == value) return;
int16_t new_value = value; int16_t new_value = value;
new_value = value > bar->max_value ? bar->max_value : new_value; new_value = value > ext->max_value ? ext->max_value : new_value;
new_value = new_value < bar->min_value ? bar->min_value : new_value; new_value = new_value < ext->min_value ? ext->min_value : new_value;
new_value = new_value < bar->start_value ? bar->start_value : new_value; new_value = new_value < ext->start_value ? ext->start_value : new_value;
if(bar->cur_value == new_value) return; if(ext->cur_value == new_value) return;
#if LV_USE_ANIMATION == 0 #if LV_USE_ANIMATION == 0
LV_UNUSED(anim); LV_UNUSED(anim);
bar->cur_value = new_value; ext->cur_value = new_value;
lv_obj_invalidate(bar); lv_obj_invalidate(bar);
#else #else
lv_bar_set_value_with_anim(bar, new_value, &bar->cur_value, &bar->cur_value_anim, anim); lv_bar_set_value_with_anim(obj, new_value, &ext->cur_value, &ext->cur_value_anim, anim);
#endif #endif
} }
@ -131,19 +136,19 @@ void lv_bar_set_start_value(lv_obj_t * obj, int16_t start_value, lv_anim_enable_
{ {
LV_ASSERT_OBJ(obj, LV_OBJX_NAME); LV_ASSERT_OBJ(obj, LV_OBJX_NAME);
lv_bar_t * bar = (lv_bar_t *)obj; lv_bar_ext_t * ext = obj->ext_attr;
int16_t new_value = start_value; int16_t new_value = start_value;
new_value = new_value > bar->max_value ? bar->max_value : new_value; new_value = new_value > ext->max_value ? ext->max_value : new_value;
new_value = new_value < bar->min_value ? bar->min_value : new_value; new_value = new_value < ext->min_value ? ext->min_value : new_value;
new_value = new_value > bar->cur_value ? bar->cur_value : new_value; new_value = new_value > ext->cur_value ? ext->cur_value : new_value;
if(bar->start_value == new_value) return; if(ext->start_value == new_value) return;
#if LV_USE_ANIMATION == 0 #if LV_USE_ANIMATION == 0
LV_UNUSED(anim); LV_UNUSED(anim);
bar->start_value = new_value; ext->start_value = new_value;
#else #else
lv_bar_set_value_with_anim(bar, new_value, &bar->start_value, &bar->start_value_anim, anim); lv_bar_set_value_with_anim(obj, new_value, &ext->start_value, &ext->start_value_anim, anim);
#endif #endif
} }
@ -156,23 +161,24 @@ void lv_bar_set_start_value(lv_obj_t * obj, int16_t start_value, lv_anim_enable_
void lv_bar_set_range(lv_obj_t * obj, int16_t min, int16_t max) void lv_bar_set_range(lv_obj_t * obj, int16_t min, int16_t max)
{ {
LV_ASSERT_OBJ(obj, LV_OBJX_NAME); LV_ASSERT_OBJ(obj, LV_OBJX_NAME);
lv_bar_t * bar = (lv_bar_t *)obj;
if(bar->min_value == min && bar->max_value == max) return; lv_bar_ext_t * ext = obj->ext_attr;
bar->max_value = max; if(ext->min_value == min && ext->max_value == max) return;
bar->min_value = min;
ext->max_value = max;
ext->min_value = min;
if(lv_bar_get_type(obj) != LV_BAR_TYPE_CUSTOM) if(lv_bar_get_type(obj) != LV_BAR_TYPE_CUSTOM)
bar->start_value = min; ext->start_value = min;
if(bar->cur_value > max) { if(ext->cur_value > max) {
bar->cur_value = max; ext->cur_value = max;
lv_bar_set_value(obj, bar->cur_value, false); lv_bar_set_value(obj, ext->cur_value, false);
} }
if(bar->cur_value < min) { if(ext->cur_value < min) {
bar->cur_value = min; ext->cur_value = min;
lv_bar_set_value(obj, bar->cur_value, false); lv_bar_set_value(obj, ext->cur_value, false);
} }
lv_obj_invalidate(obj); lv_obj_invalidate(obj);
} }
@ -185,11 +191,11 @@ void lv_bar_set_range(lv_obj_t * obj, int16_t min, int16_t max)
void lv_bar_set_type(lv_obj_t * obj, lv_bar_type_t type) void lv_bar_set_type(lv_obj_t * obj, lv_bar_type_t type)
{ {
LV_ASSERT_OBJ(obj, LV_OBJX_NAME); LV_ASSERT_OBJ(obj, LV_OBJX_NAME);
lv_bar_t * bar = (lv_bar_t *)obj; lv_bar_ext_t * ext = obj->ext_attr;
bar->type = type; ext->type = type;
if(bar->type != LV_BAR_TYPE_CUSTOM) if(ext->type != LV_BAR_TYPE_CUSTOM)
bar->start_value = bar->min_value; ext->start_value = ext->min_value;
lv_obj_invalidate(obj); lv_obj_invalidate(obj);
} }
@ -204,8 +210,8 @@ void lv_bar_set_anim_time(lv_obj_t * obj, uint16_t anim_time)
LV_ASSERT_OBJ(obj, LV_OBJX_NAME); LV_ASSERT_OBJ(obj, LV_OBJX_NAME);
#if LV_USE_ANIMATION #if LV_USE_ANIMATION
lv_bar_t * bar = (lv_bar_t *)obj; lv_bar_ext_t * ext = obj->ext_attr;
bar->anim_time = anim_time; ext->anim_time = anim_time;
#else #else
(void)bar; /*Unused*/ (void)bar; /*Unused*/
(void)anim_time; /*Unused*/ (void)anim_time; /*Unused*/
@ -224,9 +230,9 @@ void lv_bar_set_anim_time(lv_obj_t * obj, uint16_t anim_time)
int16_t lv_bar_get_value(const lv_obj_t * obj) int16_t lv_bar_get_value(const lv_obj_t * obj)
{ {
LV_ASSERT_OBJ(obj, LV_OBJX_NAME); LV_ASSERT_OBJ(obj, LV_OBJX_NAME);
lv_bar_t * bar = (lv_bar_t *)obj; lv_bar_ext_t * ext = obj->ext_attr;
return LV_BAR_GET_ANIM_VALUE(bar->cur_value, bar->cur_value_anim); return LV_BAR_GET_ANIM_VALUE(ext->cur_value, ext->cur_value_anim);
} }
/** /**
@ -237,11 +243,11 @@ int16_t lv_bar_get_value(const lv_obj_t * obj)
int16_t lv_bar_get_start_value(const lv_obj_t * obj) int16_t lv_bar_get_start_value(const lv_obj_t * obj)
{ {
LV_ASSERT_OBJ(obj, LV_OBJX_NAME); LV_ASSERT_OBJ(obj, LV_OBJX_NAME);
lv_bar_t * bar = (lv_bar_t *)obj; lv_bar_ext_t * ext = obj->ext_attr;
if(bar->type != LV_BAR_TYPE_CUSTOM) return bar->min_value; if(ext->type != LV_BAR_TYPE_CUSTOM) return ext->min_value;
return LV_BAR_GET_ANIM_VALUE(bar->start_value, bar->start_value_anim); return LV_BAR_GET_ANIM_VALUE(ext->start_value, ext->start_value_anim);
} }
/** /**
@ -252,8 +258,8 @@ int16_t lv_bar_get_start_value(const lv_obj_t * obj)
int16_t lv_bar_get_min_value(const lv_obj_t * obj) int16_t lv_bar_get_min_value(const lv_obj_t * obj)
{ {
LV_ASSERT_OBJ(obj, LV_OBJX_NAME); LV_ASSERT_OBJ(obj, LV_OBJX_NAME);
lv_bar_t * bar = (lv_bar_t *)obj; lv_bar_ext_t * ext = obj->ext_attr;
return bar->min_value; return ext->min_value;
} }
/** /**
@ -264,9 +270,9 @@ int16_t lv_bar_get_min_value(const lv_obj_t * obj)
int16_t lv_bar_get_max_value(const lv_obj_t * obj) int16_t lv_bar_get_max_value(const lv_obj_t * obj)
{ {
LV_ASSERT_OBJ(obj, LV_OBJX_NAME); LV_ASSERT_OBJ(obj, LV_OBJX_NAME);
lv_bar_t * bar = (lv_bar_t *)obj; lv_bar_ext_t * ext = obj->ext_attr;
return bar->max_value; return ext->max_value;
} }
/** /**
@ -277,9 +283,9 @@ int16_t lv_bar_get_max_value(const lv_obj_t * obj)
lv_bar_type_t lv_bar_get_type(lv_obj_t * obj) lv_bar_type_t lv_bar_get_type(lv_obj_t * obj)
{ {
LV_ASSERT_OBJ(obj, LV_OBJX_NAME); LV_ASSERT_OBJ(obj, LV_OBJX_NAME);
lv_bar_t * bar = (lv_bar_t *)obj; lv_bar_ext_t * ext = obj->ext_attr;
return bar->type; return ext->type;
} }
/** /**
@ -293,8 +299,8 @@ uint16_t lv_bar_get_anim_time(const lv_obj_t * obj)
#if LV_USE_ANIMATION #if LV_USE_ANIMATION
LV_ASSERT_OBJ(obj, LV_OBJX_NAME); LV_ASSERT_OBJ(obj, LV_OBJX_NAME);
lv_bar_t * bar = (lv_bar_t *)obj; lv_bar_ext_t * ext = obj->ext_attr;
return bar->anim_time; return ext->anim_time;
#else #else
(void)bar; /*Unused*/ (void)bar; /*Unused*/
return 0; return 0;
@ -311,19 +317,19 @@ static void lv_bar_constructor(lv_obj_t * obj, lv_obj_t * parent, const lv_obj_t
LV_LOG_TRACE("lv_bar create started"); LV_LOG_TRACE("lv_bar create started");
LV_CLASS_CONSTRUCTOR_BEGIN(obj, lv_bar) LV_CLASS_CONSTRUCTOR_BEGIN(obj, lv_bar)
lv_bar.base_p->constructor(obj, parent, copy); lv_obj.constructor(obj, parent, copy);
lv_bar_t * bar = (lv_bar_t *) obj; lv_bar_ext_t * ext = obj->ext_attr;
bar->min_value = 0; ext->min_value = 0;
bar->max_value = 100; ext->max_value = 100;
bar->start_value = 0; ext->start_value = 0;
bar->cur_value = 0; ext->cur_value = 0;
bar->type = LV_BAR_TYPE_NORMAL; ext->type = LV_BAR_TYPE_NORMAL;
#if LV_USE_ANIMATION #if LV_USE_ANIMATION
bar->anim_time = 200; ext->anim_time = 200;
lv_bar_init_anim(bar, &bar->cur_value_anim); lv_bar_init_anim(obj, &ext->cur_value_anim);
lv_bar_init_anim(bar, &bar->start_value_anim); lv_bar_init_anim(obj, &ext->start_value_anim);
#endif #endif
if(copy == NULL) { if(copy == NULL) {
@ -332,30 +338,30 @@ static void lv_bar_constructor(lv_obj_t * obj, lv_obj_t * parent, const lv_obj_t
lv_obj_set_size(obj, LV_DPI * 2, LV_DPI / 10); lv_obj_set_size(obj, LV_DPI * 2, LV_DPI / 10);
lv_bar_set_value(obj, 0, LV_ANIM_OFF); lv_bar_set_value(obj, 0, LV_ANIM_OFF);
} else { } else {
lv_bar_t * bar_copy = (lv_bar_t *)copy; lv_bar_ext_t * copy_ext = copy->ext_attr;
bar->min_value = bar_copy->min_value; ext->min_value = copy_ext->min_value;
bar->start_value = bar_copy->start_value; ext->start_value = copy_ext->start_value;
bar->max_value = bar_copy->max_value; ext->max_value = copy_ext->max_value;
bar->cur_value = bar_copy->cur_value; ext->cur_value = copy_ext->cur_value;
bar->type = bar_copy->type; ext->type = copy_ext->type;
lv_bar_set_value(obj, bar->cur_value, LV_ANIM_OFF); lv_bar_set_value(obj, ext->cur_value, LV_ANIM_OFF);
} }
LV_CLASS_CONSTRUCTOR_END(obj, lv_bar) LV_CLASS_CONSTRUCTOR_END(obj, lv_bar)
LV_LOG_INFO("bar created"); LV_LOG_INFO("bar created");
} }
static void lv_bar_destructor(void * obj) static void lv_bar_destructor(lv_obj_t * obj)
{ {
// lv_bar_t * bar = obj; // lv_bar_t * bar = obj;
// //
// _lv_obj_reset_style_list_no_refr(obj, LV_PART_INDICATOR); // _lv_obj_reset_style_list_no_refr(obj, LV_PART_INDICATOR);
//#if LV_USE_ANIMATION //#if LV_USE_ANIMATION
// lv_anim_del(&bar->cur_value_anim, NULL); // lv_anim_del(&ext->cur_value_anim, NULL);
// lv_anim_del(&bar->start_value_anim, NULL); // lv_anim_del(&ext->start_value_anim, NULL);
//#endif //#endif
// bar->class_p->base_p->destructor(obj); // ext->class_p->base_p->destructor(obj);
} }
/** /**
@ -370,15 +376,13 @@ static void lv_bar_destructor(void * obj)
*/ */
static lv_design_res_t lv_bar_design(lv_obj_t * obj, const lv_area_t * clip_area, lv_design_mode_t mode) static lv_design_res_t lv_bar_design(lv_obj_t * obj, const lv_area_t * clip_area, lv_design_mode_t mode)
{ {
lv_bar_t * bar = (lv_bar_t *)obj;
if(mode == LV_DESIGN_COVER_CHK) { if(mode == LV_DESIGN_COVER_CHK) {
/*Return false if the object is not covers the mask area*/ /*Return false if the object is not covers the mask area*/
return lv_bar.base_p->design_cb(obj, clip_area, mode); return lv_obj.design_cb(obj, clip_area, mode);
} }
else if(mode == LV_DESIGN_DRAW_MAIN) { else if(mode == LV_DESIGN_DRAW_MAIN) {
//Draw the background //Draw the background
lv_bar.base_p->design_cb(obj, clip_area, mode); lv_obj.design_cb(obj, clip_area, mode);
draw_indic(obj, clip_area); draw_indic(obj, clip_area);
/*Get the value and draw it after the indicator*/ /*Get the value and draw it after the indicator*/
@ -390,17 +394,17 @@ static lv_design_res_t lv_bar_design(lv_obj_t * obj, const lv_area_t * clip_area
draw_dsc.content_opa = LV_OPA_TRANSP; draw_dsc.content_opa = LV_OPA_TRANSP;
draw_dsc.outline_opa = LV_OPA_TRANSP; draw_dsc.outline_opa = LV_OPA_TRANSP;
lv_obj_init_draw_rect_dsc(obj, LV_PART_MAIN, &draw_dsc); lv_obj_init_draw_rect_dsc(obj, LV_PART_MAIN, &draw_dsc);
lv_draw_rect(&bar->coords, clip_area, &draw_dsc); lv_draw_rect(&obj->coords, clip_area, &draw_dsc);
} }
else if(mode == LV_DESIGN_DRAW_POST) { else if(mode == LV_DESIGN_DRAW_POST) {
lv_bar.base_p->design_cb(obj, clip_area, mode); lv_obj.design_cb(obj, clip_area, mode);
} }
return LV_DESIGN_RES_OK; return LV_DESIGN_RES_OK;
} }
static void draw_indic(lv_obj_t * obj, const lv_area_t * clip_area) static void draw_indic(lv_obj_t * obj, const lv_area_t * clip_area)
{ {
lv_bar_t * bar = (lv_bar_t *)obj; lv_bar_ext_t * ext = obj->ext_attr;
lv_bidi_dir_t base_dir = lv_obj_get_base_dir(obj); lv_bidi_dir_t base_dir = lv_obj_get_base_dir(obj);
@ -415,11 +419,11 @@ static void draw_indic(lv_obj_t * obj, const lv_area_t * clip_area)
bar_coords.y2 += transf_h; bar_coords.y2 += transf_h;
lv_coord_t barw = lv_area_get_width(&bar_coords); lv_coord_t barw = lv_area_get_width(&bar_coords);
lv_coord_t barh = lv_area_get_height(&bar_coords); lv_coord_t barh = lv_area_get_height(&bar_coords);
int32_t range = bar->max_value - bar->min_value; int32_t range = ext->max_value - ext->min_value;
bool hor = barw >= barh ? true : false; bool hor = barw >= barh ? true : false;
bool sym = false; bool sym = false;
if(bar->type == LV_BAR_TYPE_SYMMETRICAL && bar->min_value < 0 && bar->max_value > 0 && if(ext->type == LV_BAR_TYPE_SYMMETRICAL && ext->min_value < 0 && ext->max_value > 0 &&
bar->start_value == bar->min_value) sym = true; ext->start_value == ext->min_value) sym = true;
/*Calculate the indicator area*/ /*Calculate the indicator area*/
lv_coord_t bg_left = lv_obj_get_style_pad_left(obj, LV_PART_MAIN); lv_coord_t bg_left = lv_obj_get_style_pad_left(obj, LV_PART_MAIN);
@ -427,23 +431,23 @@ static void draw_indic(lv_obj_t * obj, const lv_area_t * clip_area)
lv_coord_t bg_top = lv_obj_get_style_pad_top(obj, LV_PART_MAIN); lv_coord_t bg_top = lv_obj_get_style_pad_top(obj, LV_PART_MAIN);
lv_coord_t bg_bottom = lv_obj_get_style_pad_bottom(obj, LV_PART_MAIN); lv_coord_t bg_bottom = lv_obj_get_style_pad_bottom(obj, LV_PART_MAIN);
/*Respect padding and minimum width/height too*/ /*Respect padding and minimum width/height too*/
lv_area_copy(&bar->indic_area, &bar_coords); lv_area_copy(&ext->indic_area, &bar_coords);
bar->indic_area.x1 += bg_left; ext->indic_area.x1 += bg_left;
bar->indic_area.x2 -= bg_right; ext->indic_area.x2 -= bg_right;
bar->indic_area.y1 += bg_top; ext->indic_area.y1 += bg_top;
bar->indic_area.y2 -= bg_bottom; ext->indic_area.y2 -= bg_bottom;
if(hor && lv_area_get_height(&bar->indic_area) < LV_BAR_SIZE_MIN) { if(hor && lv_area_get_height(&ext->indic_area) < LV_BAR_SIZE_MIN) {
bar->indic_area.y1 = bar->coords.y1 + (barh / 2) - (LV_BAR_SIZE_MIN / 2); ext->indic_area.y1 = obj->coords.y1 + (barh / 2) - (LV_BAR_SIZE_MIN / 2);
bar->indic_area.y2 = bar->indic_area.y1 + LV_BAR_SIZE_MIN; ext->indic_area.y2 = ext->indic_area.y1 + LV_BAR_SIZE_MIN;
} }
else if(!hor && lv_area_get_width(&bar->indic_area) < LV_BAR_SIZE_MIN) { else if(!hor && lv_area_get_width(&ext->indic_area) < LV_BAR_SIZE_MIN) {
bar->indic_area.x1 = bar->coords.x1 + (barw / 2) - (LV_BAR_SIZE_MIN / 2); ext->indic_area.x1 = obj->coords.x1 + (barw / 2) - (LV_BAR_SIZE_MIN / 2);
bar->indic_area.x2 = bar->indic_area.x1 + LV_BAR_SIZE_MIN; ext->indic_area.x2 = ext->indic_area.x1 + LV_BAR_SIZE_MIN;
} }
lv_coord_t indicw = lv_area_get_width(&bar->indic_area); lv_coord_t indicw = lv_area_get_width(&ext->indic_area);
lv_coord_t indich = lv_area_get_height(&bar->indic_area); lv_coord_t indich = lv_area_get_height(&ext->indic_area);
/*Calculate the indicator length*/ /*Calculate the indicator length*/
lv_coord_t anim_length = hor ? indicw : indich; lv_coord_t anim_length = hor ? indicw : indich;
@ -454,24 +458,24 @@ static void draw_indic(lv_obj_t * obj, const lv_area_t * clip_area)
lv_coord_t (*indic_length_calc)(const lv_area_t * area); lv_coord_t (*indic_length_calc)(const lv_area_t * area);
if(hor) { if(hor) {
axis1 = &bar->indic_area.x1; axis1 = &ext->indic_area.x1;
axis2 = &bar->indic_area.x2; axis2 = &ext->indic_area.x2;
indic_length_calc = lv_area_get_width; indic_length_calc = lv_area_get_width;
} }
else { else {
axis1 = &bar->indic_area.y1; axis1 = &ext->indic_area.y1;
axis2 = &bar->indic_area.y2; axis2 = &ext->indic_area.y2;
indic_length_calc = lv_area_get_height; indic_length_calc = lv_area_get_height;
} }
#if LV_USE_ANIMATION #if LV_USE_ANIMATION
if(LV_BAR_IS_ANIMATING(bar->start_value_anim)) { if(LV_BAR_IS_ANIMATING(ext->start_value_anim)) {
lv_coord_t anim_start_value_start_x = lv_coord_t anim_start_value_start_x =
(int32_t)((int32_t)anim_length * (bar->start_value_anim.anim_start - bar->min_value)) / range; (int32_t)((int32_t)anim_length * (ext->start_value_anim.anim_start - ext->min_value)) / range;
lv_coord_t anim_start_value_end_x = lv_coord_t anim_start_value_end_x =
(int32_t)((int32_t)anim_length * (bar->start_value_anim.anim_end - bar->min_value)) / range; (int32_t)((int32_t)anim_length * (ext->start_value_anim.anim_end - ext->min_value)) / range;
anim_start_value_x = (((anim_start_value_end_x - anim_start_value_start_x) * bar->start_value_anim.anim_state) / anim_start_value_x = (((anim_start_value_end_x - anim_start_value_start_x) * ext->start_value_anim.anim_state) /
LV_BAR_ANIM_STATE_END); LV_BAR_ANIM_STATE_END);
anim_start_value_x += anim_start_value_start_x; anim_start_value_x += anim_start_value_start_x;
@ -479,24 +483,24 @@ static void draw_indic(lv_obj_t * obj, const lv_area_t * clip_area)
else else
#endif #endif
{ {
anim_start_value_x = (int32_t)((int32_t)anim_length * (bar->start_value - bar->min_value)) / range; anim_start_value_x = (int32_t)((int32_t)anim_length * (ext->start_value - ext->min_value)) / range;
} }
#if LV_USE_ANIMATION #if LV_USE_ANIMATION
if(LV_BAR_IS_ANIMATING(bar->cur_value_anim)) { if(LV_BAR_IS_ANIMATING(ext->cur_value_anim)) {
lv_coord_t anim_cur_value_start_x = lv_coord_t anim_cur_value_start_x =
(int32_t)((int32_t)anim_length * (bar->cur_value_anim.anim_start - bar->min_value)) / range; (int32_t)((int32_t)anim_length * (ext->cur_value_anim.anim_start - ext->min_value)) / range;
lv_coord_t anim_cur_value_end_x = lv_coord_t anim_cur_value_end_x =
(int32_t)((int32_t)anim_length * (bar->cur_value_anim.anim_end - bar->min_value)) / range; (int32_t)((int32_t)anim_length * (ext->cur_value_anim.anim_end - ext->min_value)) / range;
anim_cur_value_x = anim_cur_value_start_x + (((anim_cur_value_end_x - anim_cur_value_start_x) * anim_cur_value_x = anim_cur_value_start_x + (((anim_cur_value_end_x - anim_cur_value_start_x) *
bar->cur_value_anim.anim_state) / ext->cur_value_anim.anim_state) /
LV_BAR_ANIM_STATE_END); LV_BAR_ANIM_STATE_END);
} }
else else
#endif #endif
{ {
anim_cur_value_x = (int32_t)((int32_t)anim_length * (bar->cur_value - bar->min_value)) / range; anim_cur_value_x = (int32_t)((int32_t)anim_length * (ext->cur_value - ext->min_value)) / range;
} }
if(hor && base_dir == LV_BIDI_DIR_RTL) { if(hor && base_dir == LV_BIDI_DIR_RTL) {
@ -520,7 +524,7 @@ static void draw_indic(lv_obj_t * obj, const lv_area_t * clip_area)
} }
if(sym) { if(sym) {
lv_coord_t zero; lv_coord_t zero;
zero = *axis1 + (-bar->min_value * anim_length) / range; zero = *axis1 + (-ext->min_value * anim_length) / range;
if(*axis2 > zero) if(*axis2 > zero)
*axis1 = zero; *axis1 = zero;
else { else {
@ -532,7 +536,7 @@ static void draw_indic(lv_obj_t * obj, const lv_area_t * clip_area)
/*Draw the indicator*/ /*Draw the indicator*/
/*Do not draw a zero length indicator*/ /*Do not draw a zero length indicator*/
if(!sym && indic_length_calc(&bar->indic_area) <= 1) return; if(!sym && indic_length_calc(&ext->indic_area) <= 1) return;
uint16_t bg_radius = lv_obj_get_style_radius(obj, LV_PART_MAIN); uint16_t bg_radius = lv_obj_get_style_radius(obj, LV_PART_MAIN);
lv_coord_t short_side = LV_MATH_MIN(barw, barh); lv_coord_t short_side = LV_MATH_MIN(barw, barh);
@ -545,15 +549,15 @@ static void draw_indic(lv_obj_t * obj, const lv_area_t * clip_area)
/* Draw only the shadow if the indicator is long enough. /* Draw only the shadow if the indicator is long enough.
* The radius of the bg and the indicator can make a strange shape where * The radius of the bg and the indicator can make a strange shape where
* it'd be very difficult to draw shadow. */ * it'd be very difficult to draw shadow. */
if((hor && lv_area_get_width(&bar->indic_area) > bg_radius * 2) || if((hor && lv_area_get_width(&ext->indic_area) > bg_radius * 2) ||
(!hor && lv_area_get_height(&bar->indic_area) > bg_radius * 2)) { (!hor && lv_area_get_height(&ext->indic_area) > bg_radius * 2)) {
lv_opa_t bg_opa = draw_indic_dsc.bg_opa; lv_opa_t bg_opa = draw_indic_dsc.bg_opa;
lv_opa_t border_opa = draw_indic_dsc.border_opa; lv_opa_t border_opa = draw_indic_dsc.border_opa;
lv_opa_t content_opa = draw_indic_dsc.content_opa; lv_opa_t content_opa = draw_indic_dsc.content_opa;
draw_indic_dsc.bg_opa = LV_OPA_TRANSP; draw_indic_dsc.bg_opa = LV_OPA_TRANSP;
draw_indic_dsc.border_opa = LV_OPA_TRANSP; draw_indic_dsc.border_opa = LV_OPA_TRANSP;
draw_indic_dsc.content_opa = LV_OPA_TRANSP; draw_indic_dsc.content_opa = LV_OPA_TRANSP;
lv_draw_rect(&bar->indic_area, clip_area, &draw_indic_dsc); lv_draw_rect(&ext->indic_area, clip_area, &draw_indic_dsc);
draw_indic_dsc.bg_opa = bg_opa; draw_indic_dsc.bg_opa = bg_opa;
draw_indic_dsc.border_opa = border_opa; draw_indic_dsc.border_opa = border_opa;
draw_indic_dsc.content_opa = content_opa; draw_indic_dsc.content_opa = content_opa;
@ -579,17 +583,17 @@ static void draw_indic(lv_obj_t * obj, const lv_area_t * clip_area)
mask_indic_max_area.x2 -= bg_right; mask_indic_max_area.x2 -= bg_right;
mask_indic_max_area.y2 -= bg_bottom; mask_indic_max_area.y2 -= bg_bottom;
if(hor && lv_area_get_height(&mask_indic_max_area) < LV_BAR_SIZE_MIN) { if(hor && lv_area_get_height(&mask_indic_max_area) < LV_BAR_SIZE_MIN) {
mask_indic_max_area.y1 = bar->coords.y1 + (barh / 2) - (LV_BAR_SIZE_MIN / 2); mask_indic_max_area.y1 = obj->coords.y1 + (barh / 2) - (LV_BAR_SIZE_MIN / 2);
mask_indic_max_area.y2 = mask_indic_max_area.y1 + LV_BAR_SIZE_MIN; mask_indic_max_area.y2 = mask_indic_max_area.y1 + LV_BAR_SIZE_MIN;
} }
else if(!hor && lv_area_get_width(&mask_indic_max_area) < LV_BAR_SIZE_MIN) { else if(!hor && lv_area_get_width(&mask_indic_max_area) < LV_BAR_SIZE_MIN) {
mask_indic_max_area.x1 = bar->coords.x1 + (barw / 2) - (LV_BAR_SIZE_MIN / 2); mask_indic_max_area.x1 = obj->coords.x1 + (barw / 2) - (LV_BAR_SIZE_MIN / 2);
mask_indic_max_area.x2 = mask_indic_max_area.x1 + LV_BAR_SIZE_MIN; mask_indic_max_area.x2 = mask_indic_max_area.x1 + LV_BAR_SIZE_MIN;
} }
/*Create a mask to the current indicator area to see only this part from the whole gradient.*/ /*Create a mask to the current indicator area to see only this part from the whole gradient.*/
lv_draw_mask_radius_param_t mask_indic_param; lv_draw_mask_radius_param_t mask_indic_param;
lv_draw_mask_radius_init(&mask_indic_param, &bar->indic_area, draw_indic_dsc.radius, false); lv_draw_mask_radius_init(&mask_indic_param, &ext->indic_area, draw_indic_dsc.radius, false);
int16_t mask_indic_id = lv_draw_mask_add(&mask_indic_param, NULL); int16_t mask_indic_id = lv_draw_mask_add(&mask_indic_param, NULL);
lv_draw_rect(&mask_indic_max_area, clip_area, &draw_indic_dsc); lv_draw_rect(&mask_indic_max_area, clip_area, &draw_indic_dsc);
@ -601,7 +605,7 @@ static void draw_indic(lv_obj_t * obj, const lv_area_t * clip_area)
draw_indic_dsc.bg_opa = LV_OPA_TRANSP; draw_indic_dsc.bg_opa = LV_OPA_TRANSP;
draw_indic_dsc.shadow_opa = LV_OPA_TRANSP; draw_indic_dsc.shadow_opa = LV_OPA_TRANSP;
draw_indic_dsc.content_opa = LV_OPA_TRANSP; draw_indic_dsc.content_opa = LV_OPA_TRANSP;
lv_draw_rect(&bar->indic_area, clip_area, &draw_indic_dsc); lv_draw_rect(&ext->indic_area, clip_area, &draw_indic_dsc);
lv_draw_mask_remove_id(mask_indic_id); lv_draw_mask_remove_id(mask_indic_id);
lv_draw_mask_remove_id(mask_bg_id); lv_draw_mask_remove_id(mask_bg_id);
@ -609,7 +613,7 @@ static void draw_indic(lv_obj_t * obj, const lv_area_t * clip_area)
/*When not masks draw the value*/ /*When not masks draw the value*/
draw_indic_dsc.content_opa = content_opa; draw_indic_dsc.content_opa = content_opa;
draw_indic_dsc.border_opa = LV_OPA_TRANSP; draw_indic_dsc.border_opa = LV_OPA_TRANSP;
lv_draw_rect(&bar->indic_area, clip_area, &draw_indic_dsc); lv_draw_rect(&ext->indic_area, clip_area, &draw_indic_dsc);
} }
@ -623,12 +627,10 @@ static void draw_indic(lv_obj_t * obj, const lv_area_t * clip_area)
static lv_res_t lv_bar_signal(lv_obj_t * obj, lv_signal_t sign, void * param) static lv_res_t lv_bar_signal(lv_obj_t * obj, lv_signal_t sign, void * param)
{ {
LV_ASSERT_OBJ(obj, LV_OBJX_NAME); LV_ASSERT_OBJ(obj, LV_OBJX_NAME);
lv_bar_t * bar = (lv_bar_t *)obj;
lv_res_t res; lv_res_t res;
/* Include the ancient signal function */ /* Include the ancient signal function */
res = lv_bar.base_p->signal_cb(obj, sign, param); res = lv_obj.signal_cb(obj, sign, param);
if(res != LV_RES_OK) return res; if(res != LV_RES_OK) return res;
if(sign == LV_SIGNAL_REFR_EXT_DRAW_PAD) { if(sign == LV_SIGNAL_REFR_EXT_DRAW_PAD) {
@ -653,24 +655,26 @@ static void lv_bar_anim(lv_bar_anim_t * var, lv_anim_value_t value)
static void lv_bar_anim_ready(lv_anim_t * a) static void lv_bar_anim_ready(lv_anim_t * a)
{ {
lv_bar_anim_t * var = a->var; lv_bar_anim_t * var = a->var;
lv_bar_t * bar = (lv_bar_t *)var->bar; lv_obj_t * obj = (lv_obj_t *)var->bar;
lv_bar_ext_t * ext = obj->ext_attr;
var->anim_state = LV_BAR_ANIM_STATE_INV; var->anim_state = LV_BAR_ANIM_STATE_INV;
if(var == &bar->cur_value_anim) if(var == &ext->cur_value_anim)
bar->cur_value = var->anim_end; ext->cur_value = var->anim_end;
else if(var == &bar->start_value_anim) else if(var == &ext->start_value_anim)
bar->start_value = var->anim_end; ext->start_value = var->anim_end;
lv_obj_invalidate(var->bar); lv_obj_invalidate(var->bar);
} }
static void lv_bar_set_value_with_anim(lv_bar_t * bar, int16_t new_value, int16_t * value_ptr, static void lv_bar_set_value_with_anim(lv_obj_t * obj, int16_t new_value, int16_t * value_ptr,
lv_bar_anim_t * anim_info, lv_anim_enable_t en) lv_bar_anim_t * anim_info, lv_anim_enable_t en)
{ {
if(en == LV_ANIM_OFF) { if(en == LV_ANIM_OFF) {
*value_ptr = new_value; *value_ptr = new_value;
lv_obj_invalidate((lv_obj_t*)bar); lv_obj_invalidate((lv_obj_t*)obj);
} }
else { else {
lv_bar_ext_t * ext = obj->ext_attr;
/*No animation in progress -> simply set the values*/ /*No animation in progress -> simply set the values*/
if(anim_info->anim_state == LV_BAR_ANIM_STATE_INV) { if(anim_info->anim_state == LV_BAR_ANIM_STATE_INV) {
@ -692,14 +696,14 @@ static void lv_bar_set_value_with_anim(lv_bar_t * bar, int16_t new_value, int16_
lv_anim_set_exec_cb(&a, (lv_anim_exec_xcb_t)lv_bar_anim); lv_anim_set_exec_cb(&a, (lv_anim_exec_xcb_t)lv_bar_anim);
lv_anim_set_values(&a, LV_BAR_ANIM_STATE_START, LV_BAR_ANIM_STATE_END); lv_anim_set_values(&a, LV_BAR_ANIM_STATE_START, LV_BAR_ANIM_STATE_END);
lv_anim_set_ready_cb(&a, lv_bar_anim_ready); lv_anim_set_ready_cb(&a, lv_bar_anim_ready);
lv_anim_set_time(&a, bar->anim_time); lv_anim_set_time(&a, ext->anim_time);
lv_anim_start(&a); lv_anim_start(&a);
} }
} }
static void lv_bar_init_anim(lv_bar_t * bar, lv_bar_anim_t * bar_anim) static void lv_bar_init_anim(lv_obj_t * obj, lv_bar_anim_t * bar_anim)
{ {
bar_anim->bar = (lv_obj_t *)bar; bar_anim->bar = obj;
bar_anim->anim_start = 0; bar_anim->anim_start = 0;
bar_anim->anim_end = 0; bar_anim->anim_end = 0;
bar_anim->anim_state = LV_BAR_ANIM_STATE_INV; bar_anim->anim_state = LV_BAR_ANIM_STATE_INV;

View File

@ -58,36 +58,21 @@ typedef struct {
} lv_bar_anim_t; } lv_bar_anim_t;
#endif #endif
typedef struct {
LV_CLASS_DECLARE_START(lv_bar, lv_obj); int16_t cur_value; /*Current value of the bar*/
int16_t min_value; /*Minimum value of the bar*/
#define _lv_bar_constructor void (*constructor)(struct _lv_obj_t * obj, struct _lv_obj_t * parent, const struct _lv_obj_t * copy) int16_t max_value; /*Maximum value of the bar*/
int16_t start_value; /*Start value of the bar*/
lv_area_t indic_area; /*Save the indicator area. Might be used by derived types*/
#if LV_USE_ANIMATION #if LV_USE_ANIMATION
#define _lv_bar_anim_data \ lv_anim_value_t anim_time;
lv_anim_value_t anim_time; \ lv_bar_anim_t cur_value_anim;
lv_bar_anim_t cur_value_anim; \
lv_bar_anim_t start_value_anim; lv_bar_anim_t start_value_anim;
#else
#define _lv_bar_anim_data
#endif #endif
uint8_t type : 2; /*Type of bar*/
}lv_bar_ext_t;
#define _lv_bar_data \ extern const lv_obj_class_t lv_bar;
_lv_obj_data \
int16_t cur_value; /*Current value of the bar*/ \
int16_t min_value; /*Minimum value of the bar*/ \
int16_t max_value; /*Maximum value of the bar*/ \
int16_t start_value; /*Start value of the bar*/ \
lv_area_t indic_area; /*Save the indicator area. Might be used by derived types*/ \
_lv_bar_anim_data \
uint8_t type : 2; /*Type of bar*/ \
#define _lv_bar_class_dsc \
_lv_obj_class_dsc \
LV_CLASS_DECLARE_END(lv_bar, lv_obj);
extern lv_bar_class_t lv_bar;
/********************** /**********************
* GLOBAL PROTOTYPES * GLOBAL PROTOTYPES

View File

@ -33,8 +33,8 @@
/********************** /**********************
* STATIC PROTOTYPES * STATIC PROTOTYPES
**********************/ **********************/
static void lv_slider_desctructor(void * obj);
static void lv_slider_constructor(lv_obj_t * obj, lv_obj_t * parent, const lv_obj_t * copy); static void lv_slider_constructor(lv_obj_t * obj, lv_obj_t * parent, const lv_obj_t * copy);
static void lv_slider_destructor(lv_obj_t * obj);
static lv_design_res_t lv_slider_design(lv_obj_t * slider, const lv_area_t * clip_area, lv_design_mode_t mode); static lv_design_res_t lv_slider_design(lv_obj_t * slider, const lv_area_t * clip_area, lv_design_mode_t mode);
static lv_res_t lv_slider_signal(lv_obj_t * slider, lv_signal_t sign, void * param); static lv_res_t lv_slider_signal(lv_obj_t * slider, lv_signal_t sign, void * param);
static void lv_slider_position_knob(lv_obj_t * slider, lv_area_t * knob_area, lv_coord_t knob_size, bool hor); static void lv_slider_position_knob(lv_obj_t * slider, lv_area_t * knob_area, lv_coord_t knob_size, bool hor);
@ -43,7 +43,13 @@ static void lv_slider_draw_knob(lv_obj_t * slider, const lv_area_t * knob_area,
/********************** /**********************
* STATIC VARIABLES * STATIC VARIABLES
**********************/ **********************/
lv_slider_class_t lv_slider; const lv_obj_class_t lv_slider = {
.constructor = lv_slider_constructor,
.destructor = lv_slider_destructor,
.signal_cb = lv_slider_signal,
.design_cb = lv_slider_design,
.ext_size = sizeof(lv_slider_ext_t),
};
/********************** /**********************
* MACROS * MACROS
@ -64,15 +70,15 @@ lv_obj_t * lv_slider_create(lv_obj_t * parent, const lv_obj_t * copy)
{ {
LV_LOG_TRACE("slider create started"); LV_LOG_TRACE("slider create started");
if(!lv_slider._inited) { lv_obj_t * obj = lv_mem_alloc(sizeof(lv_obj_t));
LV_CLASS_INIT(lv_slider, lv_bar); _lv_memset_00(obj, sizeof(lv_obj_t));
lv_slider.constructor = lv_slider_constructor; obj->class_p = &lv_slider;
lv_slider.destructor = lv_slider_desctructor;
lv_slider.signal_cb = lv_slider_signal; if(obj->class_p->ext_size) {
lv_slider.design_cb = lv_slider_design; obj->ext_attr = lv_mem_alloc(sizeof(lv_slider_ext_t));
_lv_memset_00(obj->ext_attr, sizeof(lv_slider_ext_t));
} }
lv_obj_t * obj = lv_class_new(&lv_slider);
lv_slider.constructor(obj, parent, copy); lv_slider.constructor(obj, parent, copy);
lv_obj_create_finish(obj, parent, copy); lv_obj_create_finish(obj, parent, copy);
@ -98,9 +104,9 @@ lv_obj_t * lv_slider_create(lv_obj_t * parent, const lv_obj_t * copy)
bool lv_slider_is_dragged(const lv_obj_t * obj) bool lv_slider_is_dragged(const lv_obj_t * obj)
{ {
LV_ASSERT_OBJ(obj, LV_OBJX_NAME); LV_ASSERT_OBJ(obj, LV_OBJX_NAME);
lv_slider_t * slider = (lv_slider_t *) obj; lv_slider_ext_t * ext = obj->ext_attr;
return slider->dragging ? true : false; return ext->dragging ? true : false;
} }
/********************** /**********************
@ -110,14 +116,15 @@ bool lv_slider_is_dragged(const lv_obj_t * obj)
static void lv_slider_constructor(lv_obj_t * obj, lv_obj_t * parent, const lv_obj_t * copy) static void lv_slider_constructor(lv_obj_t * obj, lv_obj_t * parent, const lv_obj_t * copy)
{ {
LV_CLASS_CONSTRUCTOR_BEGIN(obj, lv_slider) LV_CLASS_CONSTRUCTOR_BEGIN(obj, lv_slider)
lv_slider.base_p->constructor(obj, parent, copy);
lv_slider_t * slider = (lv_slider_t*) obj; lv_bar.constructor(obj, parent, copy);
lv_slider_ext_t * ext = obj->ext_attr;
/*Initialize the allocated 'slider' */ /*Initialize the allocated 'slider' */
slider->value_to_set = NULL; ext->value_to_set = NULL;
slider->dragging = 0; ext->dragging = 0;
slider->left_knob_focus = 0; ext->left_knob_focus = 0;
/*Init the new slider slider*/ /*Init the new slider slider*/
if(copy == NULL) { if(copy == NULL) {
@ -126,21 +133,21 @@ static void lv_slider_constructor(lv_obj_t * obj, lv_obj_t * parent, const lv_ob
lv_obj_set_ext_click_area(obj, lv_dpx(5), lv_dpx(5), lv_dpx(5), lv_dpx(5)); lv_obj_set_ext_click_area(obj, lv_dpx(5), lv_dpx(5), lv_dpx(5), lv_dpx(5));
lv_obj_set_height(obj, LV_DPI / 15); lv_obj_set_height(obj, LV_DPI / 15);
} else { } else {
lv_slider_t * copy_slider = (lv_slider_t *) copy; lv_slider_ext_t * copy_ext = copy->ext_attr;
lv_area_copy(&slider->left_knob_area, &copy_slider->left_knob_area); lv_area_copy(&ext->left_knob_area, &copy_ext->left_knob_area);
lv_area_copy(&slider->right_knob_area, &copy_slider->right_knob_area); lv_area_copy(&ext->right_knob_area, &copy_ext->right_knob_area);
} }
LV_CLASS_CONSTRUCTOR_END(obj, lv_slider) LV_CLASS_CONSTRUCTOR_END(obj, lv_slider)
} }
static void lv_slider_desctructor(void * obj) static void lv_slider_destructor(lv_obj_t * obj)
{ {
// lv_slider_t * slider = obj; // lv_slider_t * slider = obj;
// //
// _lv_obj_reset_style_list_no_refr(obj, LV_PART_KNOB); // _lv_obj_reset_style_list_no_refr(obj, LV_PART_KNOB);
// //
// slider->class_p->base_p->destructor(obj); // ext->class_p->base_p->destructor(obj);
} }
/** /**
@ -162,10 +169,10 @@ static lv_design_res_t lv_slider_design(lv_obj_t * obj, const lv_area_t * clip_a
/*Draw the object*/ /*Draw the object*/
else if(mode == LV_DESIGN_DRAW_MAIN) { else if(mode == LV_DESIGN_DRAW_MAIN) {
/* The ancestor design function will draw the background and the indicator. /* The ancestor design function will draw the background and the indicator.
* It also sets slider->indic_area*/ * It also sets ext->bar.indic_area*/
lv_slider.base_p->design_cb(obj, clip_area, mode); lv_bar.design_cb(obj, clip_area, mode);
lv_slider_t * slider = (lv_slider_t *)obj; lv_slider_ext_t * ext = obj->ext_attr;
lv_bidi_dir_t base_dir = lv_obj_get_base_dir(obj); lv_bidi_dir_t base_dir = lv_obj_get_base_dir(obj);
lv_coord_t objw = lv_obj_get_width(obj); lv_coord_t objw = lv_obj_get_width(obj);
@ -173,60 +180,60 @@ static lv_design_res_t lv_slider_design(lv_obj_t * obj, const lv_area_t * clip_a
bool hor = objw >= objh ? true : false; bool hor = objw >= objh ? true : false;
lv_coord_t knob_size = hor ? objh : objw; lv_coord_t knob_size = hor ? objh : objw;
bool sym = false; bool sym = false;
if(slider->type == LV_BAR_TYPE_SYMMETRICAL && slider->min_value < 0 && slider->max_value > 0) sym = true; if(ext->bar.type == LV_BAR_TYPE_SYMMETRICAL && ext->bar.min_value < 0 && ext->bar.max_value > 0) sym = true;
lv_area_t knob_area; lv_area_t knob_area;
/*Horizontal*/ /*Horizontal*/
if(hor) { if(hor) {
if(!sym) { if(!sym) {
knob_area.x1 = LV_SLIDER_KNOB_COORD(hor, base_dir == LV_BIDI_DIR_RTL, slider->indic_area); knob_area.x1 = LV_SLIDER_KNOB_COORD(hor, base_dir == LV_BIDI_DIR_RTL, ext->bar.indic_area);
} }
else { else {
if(slider->cur_value >= 0) { if(ext->bar.cur_value >= 0) {
knob_area.x1 = LV_SLIDER_KNOB_COORD(hor, base_dir == LV_BIDI_DIR_RTL, slider->indic_area); knob_area.x1 = LV_SLIDER_KNOB_COORD(hor, base_dir == LV_BIDI_DIR_RTL, ext->bar.indic_area);
} }
else { else {
knob_area.x1 = LV_SLIDER_KNOB_COORD(hor, base_dir != LV_BIDI_DIR_RTL, slider->indic_area); knob_area.x1 = LV_SLIDER_KNOB_COORD(hor, base_dir != LV_BIDI_DIR_RTL, ext->bar.indic_area);
} }
} }
} }
/*Vertical*/ /*Vertical*/
else { else {
if(!sym) { if(!sym) {
knob_area.y1 = slider->indic_area.y1; knob_area.y1 = ext->bar.indic_area.y1;
} }
else { else {
if(slider->cur_value >= 0) { if(ext->bar.cur_value >= 0) {
knob_area.y1 = slider->indic_area.y1; knob_area.y1 = ext->bar.indic_area.y1;
} }
else { else {
knob_area.y1 = slider->indic_area.y2; knob_area.y1 = ext->bar.indic_area.y2;
} }
} }
} }
lv_slider_position_knob(obj, &knob_area, knob_size, hor); lv_slider_position_knob(obj, &knob_area, knob_size, hor);
lv_area_copy(&slider->right_knob_area, &knob_area); lv_area_copy(&ext->right_knob_area, &knob_area);
lv_slider_draw_knob(obj, &knob_area, clip_area); lv_slider_draw_knob(obj, &knob_area, clip_area);
if(lv_slider_get_type(obj) == LV_SLIDER_TYPE_RANGE) { if(lv_slider_get_type(obj) == LV_SLIDER_TYPE_RANGE) {
/* Draw a second knob for the start_value side */ /* Draw a second knob for the start_value side */
if(hor) { if(hor) {
knob_area.x1 = LV_SLIDER_KNOB_COORD(hor, base_dir != LV_BIDI_DIR_RTL, slider->indic_area); knob_area.x1 = LV_SLIDER_KNOB_COORD(hor, base_dir != LV_BIDI_DIR_RTL, ext->bar.indic_area);
} }
else { else {
knob_area.y1 = slider->indic_area.y2; knob_area.y1 = ext->bar.indic_area.y2;
} }
lv_slider_position_knob(obj, &knob_area, knob_size, hor); lv_slider_position_knob(obj, &knob_area, knob_size, hor);
lv_area_copy(&slider->left_knob_area, &knob_area); lv_area_copy(&ext->left_knob_area, &knob_area);
lv_slider_draw_knob(obj, &knob_area, clip_area); lv_slider_draw_knob(obj, &knob_area, clip_area);
} }
} }
/*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 lv_slider.base_p->design_cb(obj, clip_area, mode); return lv_bar.design_cb(obj, clip_area, mode);
} }
return LV_DESIGN_RES_OK; return LV_DESIGN_RES_OK;
@ -243,12 +250,11 @@ static lv_res_t lv_slider_signal(lv_obj_t * obj, lv_signal_t sign, void * param)
{ {
lv_res_t res; lv_res_t res;
lv_slider_t * slider = (lv_slider_t *)obj;
/* Include the ancient signal function */ /* Include the ancient signal function */
res = lv_slider.base_p->signal_cb(obj, sign, param); res = lv_bar.signal_cb(obj, sign, param);
if(res != LV_RES_OK) return res; if(res != LV_RES_OK) return res;
lv_slider_ext_t * ext = obj->ext_attr;
lv_slider_type_t type = lv_slider_get_type(obj); lv_slider_type_t type = lv_slider_get_type(obj);
/* Advanced hit testing: react only on dragging the knob(s) */ /* Advanced hit testing: react only on dragging the knob(s) */
@ -256,20 +262,20 @@ static lv_res_t lv_slider_signal(lv_obj_t * obj, lv_signal_t sign, void * param)
lv_hit_test_info_t * info = param; lv_hit_test_info_t * info = param;
/* Ordinary slider: was the knob area hit? */ /* Ordinary slider: was the knob area hit? */
info->result = _lv_area_is_point_on(&slider->right_knob_area, info->point, 0); info->result = _lv_area_is_point_on(&ext->right_knob_area, info->point, 0);
/* There's still a change we have a hit, if we have another knob */ /* There's still a change we have a hit, if we have another knob */
if((info->result == false) && (type == LV_SLIDER_TYPE_RANGE)) { if((info->result == false) && (type == LV_SLIDER_TYPE_RANGE)) {
info->result = _lv_area_is_point_on(&slider->left_knob_area, info->point, 0); info->result = _lv_area_is_point_on(&ext->left_knob_area, info->point, 0);
} }
} }
lv_point_t p; lv_point_t p;
if(sign == LV_SIGNAL_PRESSED) { if(sign == LV_SIGNAL_PRESSED) {
slider->dragging = true; ext->dragging = true;
if(type == LV_SLIDER_TYPE_NORMAL || type == LV_SLIDER_TYPE_SYMMETRICAL) { if(type == LV_SLIDER_TYPE_NORMAL || type == LV_SLIDER_TYPE_SYMMETRICAL) {
slider->value_to_set = &slider->cur_value; ext->value_to_set = &ext->bar.cur_value;
} }
else if(type == LV_SLIDER_TYPE_RANGE) { else if(type == LV_SLIDER_TYPE_RANGE) {
lv_indev_get_point(param, &p); lv_indev_get_point(param, &p);
@ -278,44 +284,44 @@ static lv_res_t lv_slider_signal(lv_obj_t * obj, lv_signal_t sign, void * param)
lv_coord_t dist_left, dist_right; lv_coord_t dist_left, dist_right;
if(hor) { if(hor) {
if((base_dir != LV_BIDI_DIR_RTL && p.x > slider->right_knob_area.x2) || (base_dir == LV_BIDI_DIR_RTL && if((base_dir != LV_BIDI_DIR_RTL && p.x > ext->right_knob_area.x2) || (base_dir == LV_BIDI_DIR_RTL &&
p.x < slider->right_knob_area.x1)) { p.x < ext->right_knob_area.x1)) {
slider->value_to_set = &slider->cur_value; ext->value_to_set = &ext->bar.cur_value;
} }
else if((base_dir != LV_BIDI_DIR_RTL && p.x < slider->left_knob_area.x1) || (base_dir == LV_BIDI_DIR_RTL && else if((base_dir != LV_BIDI_DIR_RTL && p.x < ext->left_knob_area.x1) || (base_dir == LV_BIDI_DIR_RTL &&
p.x > slider->left_knob_area.x2)) { p.x > ext->left_knob_area.x2)) {
slider->value_to_set = &slider->start_value; ext->value_to_set = &ext->bar.start_value;
} }
else { else {
/* Calculate the distance from each knob */ /* Calculate the distance from each knob */
dist_left = LV_MATH_ABS((slider->left_knob_area.x1 + (slider->left_knob_area.x2 - slider->left_knob_area.x1) / 2) - p.x); dist_left = LV_MATH_ABS((ext->left_knob_area.x1 + (ext->left_knob_area.x2 - ext->left_knob_area.x1) / 2) - p.x);
dist_right = LV_MATH_ABS((slider->right_knob_area.x1 + (slider->right_knob_area.x2 - slider->right_knob_area.x1) / 2) - p.x); dist_right = LV_MATH_ABS((ext->right_knob_area.x1 + (ext->right_knob_area.x2 - ext->right_knob_area.x1) / 2) - p.x);
/* Use whichever one is closer */ /* Use whichever one is closer */
if(dist_right < dist_left)slider->value_to_set = &slider->cur_value; if(dist_right < dist_left)ext->value_to_set = &ext->bar.cur_value;
else slider->value_to_set = &slider->start_value; else ext->value_to_set = &ext->bar.start_value;
} }
} }
else { else {
if(p.y < slider->right_knob_area.y1) { if(p.y < ext->right_knob_area.y1) {
slider->value_to_set = &slider->cur_value; ext->value_to_set = &ext->bar.cur_value;
} }
else if(p.y > slider->left_knob_area.y2) { else if(p.y > ext->left_knob_area.y2) {
slider->value_to_set = &slider->start_value; ext->value_to_set = &ext->bar.start_value;
} }
else { else {
/* Calculate the distance from each knob */ /* Calculate the distance from each knob */
dist_left = LV_MATH_ABS((slider->left_knob_area.y1 + (slider->left_knob_area.y2 - slider->left_knob_area.y1) / 2) - p.y); dist_left = LV_MATH_ABS((ext->left_knob_area.y1 + (ext->left_knob_area.y2 - ext->left_knob_area.y1) / 2) - p.y);
dist_right = LV_MATH_ABS((slider->right_knob_area.y1 + (slider->right_knob_area.y2 - slider->right_knob_area.y1) / 2) - p.y); dist_right = LV_MATH_ABS((ext->right_knob_area.y1 + (ext->right_knob_area.y2 - ext->right_knob_area.y1) / 2) - p.y);
/* Use whichever one is closer */ /* Use whichever one is closer */
if(dist_right < dist_left)slider->value_to_set = &slider->cur_value; if(dist_right < dist_left)ext->value_to_set = &ext->bar.cur_value;
else slider->value_to_set = &slider->start_value; else ext->value_to_set = &ext->bar.start_value;
} }
} }
} }
} }
else if(sign == LV_SIGNAL_PRESSING && slider->value_to_set != NULL) { else if(sign == LV_SIGNAL_PRESSING && ext->value_to_set != NULL) {
if(lv_indev_get_type(param) != LV_INDEV_TYPE_POINTER) return res; if(lv_indev_get_type(param) != LV_INDEV_TYPE_POINTER) return res;
lv_indev_get_point(param, &p); lv_indev_get_point(param, &p);
@ -329,42 +335,42 @@ static lv_res_t lv_slider_signal(lv_obj_t * obj, lv_signal_t sign, void * param)
lv_coord_t bg_top = lv_obj_get_style_pad_top(obj, LV_PART_MAIN); lv_coord_t bg_top = lv_obj_get_style_pad_top(obj, LV_PART_MAIN);
lv_coord_t bg_bottom = lv_obj_get_style_pad_bottom(obj, LV_PART_MAIN); lv_coord_t bg_bottom = lv_obj_get_style_pad_bottom(obj, LV_PART_MAIN);
int32_t range = slider->max_value - slider->min_value; int32_t range = ext->bar.max_value - ext->bar.min_value;
int16_t new_value = 0; int16_t new_value = 0;
int16_t real_max_value = slider->max_value; int16_t real_max_value = ext->bar.max_value;
int16_t real_min_value = slider->min_value; int16_t real_min_value = ext->bar.min_value;
if(w >= h) { if(w >= h) {
lv_coord_t indic_w = w - bg_left - bg_right; lv_coord_t indic_w = w - bg_left - bg_right;
if(base_dir == LV_BIDI_DIR_RTL) { if(base_dir == LV_BIDI_DIR_RTL) {
new_value = (slider->coords.x2 - bg_right) - p.x; /*Make the point relative to the indicator*/ new_value = (obj->coords.x2 - bg_right) - p.x; /*Make the point relative to the indicator*/
} }
else { else {
new_value = p.x - (slider->coords.x1 + bg_left); /*Make the point relative to the indicator*/ new_value = p.x - (obj->coords.x1 + bg_left); /*Make the point relative to the indicator*/
} }
new_value = (new_value * range) / indic_w; new_value = (new_value * range) / indic_w;
new_value += slider->min_value; new_value += ext->bar.min_value;
} }
else { else {
lv_coord_t indic_h = h - bg_bottom - bg_top; lv_coord_t indic_h = h - bg_bottom - bg_top;
new_value = p.y - (slider->coords.y2 + bg_bottom); /*Make the point relative to the indicator*/ new_value = p.y - (obj->coords.y2 + bg_bottom); /*Make the point relative to the indicator*/
new_value = (-new_value * range) / indic_h; new_value = (-new_value * range) / indic_h;
new_value += slider->min_value; new_value += ext->bar.min_value;
} }
/* Figure out the min. and max. for this mode */ /* Figure out the min. and max. for this mode */
if(slider->value_to_set == &slider->start_value) { if(ext->value_to_set == &ext->bar.start_value) {
real_max_value = slider->cur_value; real_max_value = ext->bar.cur_value;
} }
else { else {
real_min_value = slider->start_value; real_min_value = ext->bar.start_value;
} }
if(new_value < real_min_value) new_value = real_min_value; if(new_value < real_min_value) new_value = real_min_value;
else if(new_value > real_max_value) new_value = real_max_value; else if(new_value > real_max_value) new_value = real_max_value;
if(*slider->value_to_set != new_value) { if(*ext->value_to_set != new_value) {
*slider->value_to_set = new_value; *ext->value_to_set = new_value;
lv_obj_invalidate(obj); lv_obj_invalidate(obj);
res = lv_event_send(obj, LV_EVENT_VALUE_CHANGED, NULL); res = lv_event_send(obj, LV_EVENT_VALUE_CHANGED, NULL);
if(res != LV_RES_OK) return res; if(res != LV_RES_OK) return res;
@ -372,8 +378,8 @@ static lv_res_t lv_slider_signal(lv_obj_t * obj, lv_signal_t sign, void * param)
} }
else if(sign == LV_SIGNAL_RELEASED || sign == LV_SIGNAL_PRESS_LOST) { else if(sign == LV_SIGNAL_RELEASED || sign == LV_SIGNAL_PRESS_LOST) {
slider->dragging = false; ext->dragging = false;
slider->value_to_set = NULL; ext->value_to_set = NULL;
#if LV_USE_GROUP #if LV_USE_GROUP
/*Leave edit mode if released. (No need to wait for LONG_PRESS) */ /*Leave edit mode if released. (No need to wait for LONG_PRESS) */
@ -383,9 +389,9 @@ static lv_res_t lv_slider_signal(lv_obj_t * obj, lv_signal_t sign, void * param)
if(indev_type == LV_INDEV_TYPE_ENCODER) { if(indev_type == LV_INDEV_TYPE_ENCODER) {
if(editing) { if(editing) {
if(lv_slider_get_type(slider) == LV_SLIDER_TYPE_RANGE) { if(lv_slider_get_type(slider) == LV_SLIDER_TYPE_RANGE) {
if(slider->left_knob_focus == 0) slider->left_knob_focus = 1; if(ext->left_knob_focus == 0) ext->left_knob_focus = 1;
else { else {
slider->left_knob_focus = 0; ext->left_knob_focus = 0;
lv_group_set_editing(g, false); lv_group_set_editing(g, false);
} }
} }
@ -398,7 +404,7 @@ static lv_res_t lv_slider_signal(lv_obj_t * obj, lv_signal_t sign, void * param)
} }
else if(sign == LV_SIGNAL_FOCUS) { else if(sign == LV_SIGNAL_FOCUS) {
slider->left_knob_focus = 0; ext->left_knob_focus = 0;
} }
else if(sign == LV_SIGNAL_COORD_CHG) { else if(sign == LV_SIGNAL_COORD_CHG) {
/* The knob size depends on slider size. /* The knob size depends on slider size.
@ -433,14 +439,14 @@ static lv_res_t lv_slider_signal(lv_obj_t * obj, lv_signal_t sign, void * param)
char c = *((char *)param); char c = *((char *)param);
if(c == LV_KEY_RIGHT || c == LV_KEY_UP) { if(c == LV_KEY_RIGHT || c == LV_KEY_UP) {
if(!slider->left_knob_focus) lv_slider_set_value(slider, lv_slider_get_value(slider) + 1, LV_ANIM_ON); if(!ext->left_knob_focus) lv_slider_set_value(slider, lv_slider_get_value(slider) + 1, LV_ANIM_ON);
else lv_slider_set_left_value(slider, lv_slider_get_left_value(slider) + 1, LV_ANIM_ON); else lv_slider_set_left_value(slider, lv_slider_get_left_value(slider) + 1, LV_ANIM_ON);
res = lv_event_send(slider, LV_EVENT_VALUE_CHANGED, NULL); res = lv_event_send(slider, LV_EVENT_VALUE_CHANGED, NULL);
if(res != LV_RES_OK) return res; if(res != LV_RES_OK) return res;
} }
else if(c == LV_KEY_LEFT || c == LV_KEY_DOWN) { else if(c == LV_KEY_LEFT || c == LV_KEY_DOWN) {
if(!slider->left_knob_focus) lv_slider_set_value(slider, lv_slider_get_value(slider) - 1, LV_ANIM_ON); if(!ext->left_knob_focus) lv_slider_set_value(slider, lv_slider_get_value(slider) - 1, LV_ANIM_ON);
else lv_slider_set_left_value(slider, lv_slider_get_left_value(slider) - 1, LV_ANIM_ON); else lv_slider_set_left_value(slider, lv_slider_get_left_value(slider) - 1, LV_ANIM_ON);
res = lv_event_send(slider, LV_EVENT_VALUE_CHANGED, NULL); res = lv_event_send(slider, LV_EVENT_VALUE_CHANGED, NULL);
@ -458,29 +464,29 @@ static lv_res_t lv_slider_signal(lv_obj_t * obj, lv_signal_t sign, void * param)
return res; return res;
} }
static void lv_slider_position_knob(lv_obj_t * slider, lv_area_t * knob_area, lv_coord_t knob_size, bool hor) static void lv_slider_position_knob(lv_obj_t * obj, lv_area_t * knob_area, lv_coord_t knob_size, bool hor)
{ {
if(hor) { if(hor) {
knob_area->x1 -= (knob_size >> 1); knob_area->x1 -= (knob_size >> 1);
knob_area->x2 = knob_area->x1 + knob_size - 1; knob_area->x2 = knob_area->x1 + knob_size - 1;
knob_area->y1 = slider->coords.y1; knob_area->y1 = obj->coords.y1;
knob_area->y2 = slider->coords.y2; knob_area->y2 = obj->coords.y2;
} }
else { else {
knob_area->y1 -= (knob_size >> 1); knob_area->y1 -= (knob_size >> 1);
knob_area->y2 = knob_area->y1 + knob_size - 1; knob_area->y2 = knob_area->y1 + knob_size - 1;
knob_area->x1 = slider->coords.x1; knob_area->x1 = obj->coords.x1;
knob_area->x2 = slider->coords.x2; knob_area->x2 = obj->coords.x2;
} }
lv_coord_t knob_left = lv_obj_get_style_pad_left(slider, LV_PART_KNOB); lv_coord_t knob_left = lv_obj_get_style_pad_left(obj, LV_PART_KNOB);
lv_coord_t knob_right = lv_obj_get_style_pad_right(slider, LV_PART_KNOB); lv_coord_t knob_right = lv_obj_get_style_pad_right(obj, LV_PART_KNOB);
lv_coord_t knob_top = lv_obj_get_style_pad_top(slider, LV_PART_KNOB); lv_coord_t knob_top = lv_obj_get_style_pad_top(obj, LV_PART_KNOB);
lv_coord_t knob_bottom = lv_obj_get_style_pad_bottom(slider, LV_PART_KNOB); lv_coord_t knob_bottom = lv_obj_get_style_pad_bottom(obj, LV_PART_KNOB);
lv_coord_t transf_w = lv_obj_get_style_transform_width(slider, LV_PART_KNOB); lv_coord_t transf_w = lv_obj_get_style_transform_width(obj, LV_PART_KNOB);
lv_coord_t transf_h = lv_obj_get_style_transform_height(slider, LV_PART_KNOB); lv_coord_t transf_h = lv_obj_get_style_transform_height(obj, LV_PART_KNOB);
/*Apply the paddings on the knob area*/ /*Apply the paddings on the knob area*/
knob_area->x1 -= knob_left + transf_w; knob_area->x1 -= knob_left + transf_w;

View File

@ -40,24 +40,16 @@ enum {
}; };
typedef uint8_t lv_slider_type_t; typedef uint8_t lv_slider_type_t;
LV_CLASS_DECLARE_START(lv_slider, lv_bar) typedef struct {
lv_bar_ext_t bar; /*Add the ancestor's type first*/
lv_area_t left_knob_area; \
lv_area_t right_knob_area; \
int16_t * value_to_set; /* Which bar value to set */ \
uint8_t dragging : 1; /*1: the slider is being dragged*/ \
uint8_t left_knob_focus : 1; /*1: with encoder now the right knob can be adjusted*/
}lv_slider_ext_t;
#define _lv_slider_constructor void (*constructor)(struct _lv_obj_t * obj, struct _lv_obj_t * parent, const struct _lv_obj_t * copy) extern const lv_obj_class_t lv_slider;
#define _lv_slider_data \
_lv_bar_data \
lv_area_t left_knob_area; \
lv_area_t right_knob_area; \
int16_t * value_to_set; /* Which bar value to set */ \
uint8_t dragging : 1; /*1: the slider is being dragged*/ \
uint8_t left_knob_focus : 1; /*1: with encoder now the right knob can be adjusted*/
#define _lv_slider_class_dsc \
_lv_bar_class_dsc \
LV_CLASS_DECLARE_END(lv_slider, lv_bar)
extern lv_slider_class_t lv_slider;
/********************** /**********************
* GLOBAL PROTOTYPES * GLOBAL PROTOTYPES