Description
What do you want to achieve?
making template composed of two or more component. so it is like a new component that has some features like positon
in my case I have a name label , a slider and another label to show slider value in a row
making template composed of two or more component. so it is like a new component that has some features like positon
in my case I have a name label , a slider and another label to show slider value in a row
You need to fill out the whole template. You can’t just erase part of it.
hardware is not part of my question,it is a general question and those other parts are irrelevant , but if you have a point I will
It’s fine this time, but for the future, we want to make it a rule that you have to fill out the template. We get lots of requests where little to no useful information is provided at the start.
I suggest you make a function that creates the objects on a given container and sets their positions and then reuse that function throughout your code.
I always read all part of template and if there is a relevant part I fill that part
I will make a try your idea but the hardest part I think is event call back part of slider
My approach usually is to create a gui folder where lvgl is a submodule inside it and create files like gui_slider.c with functions:
gui_slider_t * gui_slider_create(lv_obj_t * parent, gui_slider_type_t type, void (*cb) (gui_slider_t *, int32_t))
{
/*Alloacte `gui_slider_t`*/
/*Create a slider and save it in `gui_slider_t`*/
/*Set a generic callback which will call `cb` on value change*/
/*Set size, ranges and styles according to type*/
/*Create additoinal objects (like labels) and save them in `gui_slider_t`*/
/*Other settings an adjustments*/
/*Return `gui_slider_t *` */
}
void gui_slider_set_title(gui_slider_t * slider, const char * title)
{
/*Set the text of a label stored in `gui_slider_t`*/
}
You can do anything you want it’s just what worked well in my projects and aligns to my coding style and taste.
Thank you for suggestion but there are some issues that I did not understand ,
one of labels inside my template is sync with slider that shows value of slider . so It’s handler must be called inside slider callback. with this structure how is it possible to do this? keep this in mind that I don’t want to declare this label globally because I want to use it in a for-loop.
You can use the lv_obj_set_user_data(slider, custom_slider_dsc) the user data type can be set in lv_conf.h as lv_obj_user_data_t (the default void* could work for you)
Or a more professional way it to add custom data to the slider’s extended data. See this post.
I studied your article, that was so advanced for me(took me 8 hours that can write something) but gave me a lot of insight though I am not finished with that. I end up with something like this.
typedef struct
{
lv_obj_t *slider; /*Include the ancestors extend data first*/
lv_obj_t *value_label;
lv_obj_t *name_label;
/*Add new data*/
} gui_slider_t;
void slider_event_handler(lv_obj_t *obj, lv_event_t event)
{
gui_slider_t *ext = lv_obj_get_ext_attr(obj);
if (event == LV_EVENT_VALUE_CHANGED)
{
char val[5];
sprintf(val, "%d", lv_slider_get_value(obj) );
lv_label_set_text(ext->value_label, val);
//printf("Value: %d\n", );
}
}
gui_slider_t *gui_slider_create(lv_obj_t *parent, lv_event_cb_t cb)
{
//slider part
static lv_style_t style_bg;
static lv_style_t style_indic;
static lv_style_t style_knob;
lv_style_copy(&style_bg, &lv_style_pretty);
style_bg.body.main_color = LV_COLOR_BLACK;
style_bg.body.grad_color = LV_COLOR_GRAY;
style_bg.body.radius = LV_RADIUS_CIRCLE;
style_bg.body.border.color = LV_COLOR_WHITE;
lv_style_copy(&style_indic, &lv_style_pretty_color);
style_indic.body.radius = LV_RADIUS_CIRCLE;
style_indic.body.shadow.width = 8;
style_indic.body.shadow.color = style_indic.body.main_color;
style_indic.body.padding.left = 3;
style_indic.body.padding.right = 3;
style_indic.body.padding.top = 3;
style_indic.body.padding.bottom = 3;
lv_style_copy(&style_knob, &lv_style_pretty);
style_knob.body.radius = LV_RADIUS_CIRCLE;
style_knob.body.opa = LV_OPA_70;
style_knob.body.padding.top = 10 ;
style_knob.body.padding.bottom = 10 ;
/*Create a slider*/
lv_obj_t* slider = lv_slider_create(parent, NULL);
lv_slider_set_range(slider, 0, 6);
lv_obj_set_pos(slider, 50, 0);
lv_slider_set_style(slider, LV_SLIDER_STYLE_BG, &style_bg);
lv_slider_set_style(slider, LV_SLIDER_STYLE_INDIC, &style_indic);
lv_slider_set_style(slider, LV_SLIDER_STYLE_KNOB, &style_knob);
lv_obj_set_event_cb(slider, cb);
lv_obj_set_width(slider, 90);
lv_obj_allocate_ext_attr(slider, sizeof(gui_slider_t));
/*Create additoinal objects (like labels) and save them in `gui_slider_t`*/
lv_obj_t *value_label = lv_label_create(parent, NULL);
lv_obj_t* name_label = lv_label_create(parent, NULL);
gui_slider_t *ext = lv_obj_get_ext_attr(slider);
// ext->slider=slider;
ext->value_label=value_label;
ext->name_label=name_label;
//label name part
lv_label_set_long_mode(name_label, LV_LABEL_LONG_BREAK); /*Break the long lines*/
lv_label_set_recolor(name_label, true); /*Enable re-coloring by commands in the text*/
lv_obj_set_pos(name_label, 10, 0);
lv_obj_set_width(name_label, 120);
// value label
lv_label_set_long_mode(value_label, LV_LABEL_LONG_BREAK); /*Break the long lines*/
lv_label_set_recolor(value_label, true); /*Enable re-coloring by commands in the text*/
lv_obj_set_pos(value_label, 160, 5); /*Center aligned lines*/
lv_label_set_text(value_label, "0");
lv_obj_set_width(value_label, 60);
/*Other settings an adjustments*/
return ext;
/*Return `gui_slider_t *` */
}
in main i will call
gui_slider_t *x1= gui_slider_create(page, slider_event_handler);
when I changed slider value it changed from 0 to 7480 while I set it from 0 to 6
what is my mistake?
problem is
lv_obj_allocate_ext_attr(slider, sizeof(gui_slider_t));
in gui_slider_create function I tested this in simulator and adding this line prevent tft from start
It took me a lot of time without any success so I abandon this subject and declare everything globally until a solution provided
The ancestor data needs to be of type lv_slider_ext_t not lv_obj_t *
I wanted it to be simple and easy to digest. I’ll improve it.