feat(xml): add float support to subject change events (#8535)

Co-authored-by: André Costa <andre_miguel_costa@hotmail.com>
This commit is contained in:
Gabor Kiss-Vamosi
2025-07-04 14:40:01 +02:00
committed by GitHub
parent b68caaf7f9
commit 2da5aeddda
6 changed files with 107 additions and 26 deletions
+12 -7
View File
@@ -120,9 +120,10 @@ It's possible to set a :ref:`Subject <observer_subject>` value on user interacti
<view>
<lv_button width="200" height="100">
<subject_set_int trigger="clicked" subject="subject1" value="10"/>
<subject_set_string trigger="clicked" subject="subject2" value="Hello"/>
<lv_label text="Set to 10"/>
<subject_set_int_event trigger="clicked" subject="subject_int" value="10"/>
<subject_set_float_event trigger="clicked" subject="subject_float" value="12.34"/>
<subject_set_string_event trigger="clicked" subject="subject_string" value="Hello"/>
<lv_label text="Set the values"/>
</lv_button>
</view>
@@ -137,14 +138,18 @@ Incrementing or decrementing a :ref:`Subject <observer_subject>` value can be de
<view>
<lv_button width="200" height="100">
<subject_increment trigger="clicked" subject="subject1" step="10"/>
<subject_increment trigger="clicked" subject="subject2" step="-10" min="0" max="50"/>
<subject_increment_event trigger="clicked" subject="subject_int1" step="10"/>
<subject_increment_event trigger="clicked" subject="subject_int2" step="-10" min="0" max="50"/>
<subject_increment_event trigger="clicked" subject="subject_float1" step="2"/>
</lv_button>
</view>
The ``<subject_increment>`` element defines a ``step`` to be added to the subject's current value when the ``trigger`` occurs.
Optionally, ``min`` and/or ``max`` can be set to limit the subject's value.
The ``<subject_increment_event>`` element defines a ``step`` to be added to the subject's current value
when the ``trigger`` occurs. Optionally, ``min`` and/or ``max`` can be set to limit the subject's value.
``subject`` must be an ``int`` or ``float`` subject.
If ``step`` is **negative**, the subject's value will be decremented.
Only integer ``step`` values are supported now.
**Note:** Only integer subjects are supported by ``<subject_increment>``.
+50 -4
View File
@@ -45,6 +45,11 @@ typedef struct {
int32_t value;
} subject_set_int_user_data_t;
typedef struct {
lv_subject_t * subject;
float value;
} subject_set_float_user_data_t;
typedef struct {
lv_subject_t * subject;
const char * value;
@@ -63,6 +68,11 @@ typedef struct {
**********************/
static void subject_set_int_cb(lv_event_t * e);
#if LV_USE_FLOAT
static void subject_set_float_cb(lv_event_t * e);
#endif
static void subject_set_string_cb(lv_event_t * e);
static void subject_increment_cb(lv_event_t * e);
@@ -574,6 +584,24 @@ void lv_obj_add_subject_set_int_event(lv_obj_t * obj, lv_subject_t * subject, lv
lv_obj_add_event_cb(obj, free_user_data_event_cb, LV_EVENT_DELETE, user_data);
}
#if LV_USE_FLOAT
void lv_obj_add_subject_set_float_event(lv_obj_t * obj, lv_subject_t * subject, lv_event_code_t trigger, float value)
{
subject_set_float_user_data_t * user_data = lv_malloc(sizeof(subject_set_float_user_data_t));
if(user_data == NULL) {
LV_ASSERT_MALLOC(user_data);
LV_LOG_WARN("Couldn't allocate user_data");
return;
}
user_data->subject = subject;
user_data->value = value;
lv_obj_add_event_cb(obj, subject_set_float_cb, trigger, user_data);
lv_obj_add_event_cb(obj, free_user_data_event_cb, LV_EVENT_DELETE, user_data);
}
#endif /*LV_USE_FLOAT*/
void lv_obj_add_subject_set_string_event(lv_obj_t * obj, lv_subject_t * subject, lv_event_code_t trigger,
const char * value)
{
@@ -846,6 +874,14 @@ static void subject_set_int_cb(lv_event_t * e)
lv_subject_set_int(user_data->subject, user_data->value);
}
#if LV_USE_FLOAT
static void subject_set_float_cb(lv_event_t * e)
{
subject_set_float_user_data_t * user_data = lv_event_get_user_data(e);
lv_subject_set_float(user_data->subject, user_data->value);
}
#endif
static void subject_set_string_cb(lv_event_t * e)
{
subject_set_string_user_data_t * user_data = lv_event_get_user_data(e);
@@ -855,12 +891,22 @@ static void subject_set_string_cb(lv_event_t * e)
static void subject_increment_cb(lv_event_t * e)
{
subject_increment_user_data_t * user_data = lv_event_get_user_data(e);
int32_t value = lv_subject_get_int(user_data->subject);
value += user_data->step;
value = LV_CLAMP(user_data->min, value, user_data->max);
lv_subject_set_int(user_data->subject, value);
if(user_data->subject->type == LV_SUBJECT_TYPE_INT) {
int32_t value = lv_subject_get_int(user_data->subject);
value += user_data->step;
value = LV_CLAMP(user_data->min, value, user_data->max);
lv_subject_set_int(user_data->subject, value);
}
#if LV_USE_FLOAT
else if(user_data->subject->type == LV_SUBJECT_TYPE_FLOAT) {
float value = lv_subject_get_float(user_data->subject);
value += (float)user_data->step;
value = LV_CLAMP(user_data->min, value, user_data->max);
lv_subject_set_float(user_data->subject, (float)value);
}
#endif
}
+12
View File
@@ -363,6 +363,18 @@ void lv_obj_add_subject_increment_event(lv_obj_t * obj, lv_subject_t * subject,
*/
void lv_obj_add_subject_set_int_event(lv_obj_t * obj, lv_subject_t * subject, lv_event_code_t trigger, int32_t value);
#if LV_USE_FLOAT
/**
* Set the value of a float subject.
* @param obj pointer to a widget
* @param subject pointer to a subject to change
* @param trigger the trigger on which the subject should be changed
* @param value the value to set
*/
void lv_obj_add_subject_set_float_event(lv_obj_t * obj, lv_subject_t * subject, lv_event_code_t trigger, float value);
#endif
/**
* Set the value of a string subject.
* @param obj pointer to a widget
+1
View File
@@ -117,6 +117,7 @@ void lv_xml_init(void)
lv_xml_widget_register("lv_obj-event_cb", lv_obj_xml_event_cb_create, lv_obj_xml_event_cb_apply);
lv_xml_widget_register("lv_obj-subject_set_int_event", lv_obj_xml_subject_set_create, lv_obj_xml_subject_set_apply);
lv_xml_widget_register("lv_obj-subject_set_float_event", lv_obj_xml_subject_set_create, lv_obj_xml_subject_set_apply);
lv_xml_widget_register("lv_obj-subject_set_string_event", lv_obj_xml_subject_set_create, lv_obj_xml_subject_set_apply);
lv_xml_widget_register("lv_obj-subject_increment_event", lv_obj_xml_subject_increment_create,
lv_obj_xml_subject_increment_apply);
+32 -13
View File
@@ -279,8 +279,25 @@ void lv_obj_xml_subject_set_apply(lv_xml_parser_state_t * state, const char ** a
{
/*If the tag_name is */
bool int_subject = lv_streq(state->tag_name, "lv_obj-subject_set_int") ||
lv_streq(state->tag_name, "subject_set_int");
lv_subject_type_t subject_type = LV_SUBJECT_TYPE_NONE;
if(lv_streq(state->tag_name, "lv_obj-subject_set_int_event") ||
lv_streq(state->tag_name, "subject_set_int_event")) {
subject_type = LV_SUBJECT_TYPE_INT;
}
#if LV_USE_FLOAT
else if(lv_streq(state->tag_name, "lv_obj-subject_set_float_event") ||
lv_streq(state->tag_name, "subject_set_float_event")) {
subject_type = LV_SUBJECT_TYPE_FLOAT;
}
#endif
else if(lv_streq(state->tag_name, "lv_obj-subject_set_string_event") ||
lv_streq(state->tag_name, "subject_set_string_event")) {
subject_type = LV_SUBJECT_TYPE_STRING;
}
else {
LV_LOG_WARN("`%s` is not supported in <lv_obj-subject_set_event>", state->tag_name);
return;
}
const char * subject_str = lv_xml_get_value_of(attrs, "subject");
const char * trigger_str = lv_xml_get_value_of(attrs, "trigger");
@@ -309,18 +326,23 @@ void lv_obj_xml_subject_set_apply(lv_xml_parser_state_t * state, const char ** a
return;
}
bool type_ok = (subject->type == LV_SUBJECT_TYPE_INT && int_subject) ||
(subject->type == LV_SUBJECT_TYPE_STRING && !int_subject);
if(!type_ok) {
if(subject->type != subject_type) {
LV_LOG_WARN("`%s` subject has incorrect type in <lv_obj-subject_set>", subject_str);
return;
}
void * item = lv_xml_state_get_item(state);
if(int_subject) {
if(subject_type == LV_SUBJECT_TYPE_INT) {
lv_obj_add_subject_set_int_event(item, subject, trigger, lv_xml_atoi(value_str));
}
else {
else if(subject_type == LV_SUBJECT_TYPE_FLOAT) {
#if LV_USE_FLOAT
lv_obj_add_subject_set_float_event(item, subject, trigger, lv_xml_atof(value_str));
#else
LV_LOG_ERROR("Tried to add a subject of type float but LV_USE_FLOAT is not enabled");
#endif
}
else if(subject_type == LV_SUBJECT_TYPE_STRING) {
lv_obj_add_subject_set_string_event(item, subject, trigger, value_str);
}
}
@@ -345,10 +367,7 @@ void lv_obj_xml_subject_increment_apply(lv_xml_parser_state_t * state, const cha
return;
}
if(step_str == NULL) {
LV_LOG_WARN("`value` is missing in <lv_obj-subject_increment>");
return;
}
if(step_str == NULL) step_str = "1";
lv_event_code_t trigger = LV_EVENT_CLICKED;
if(trigger_str) trigger = lv_xml_trigger_text_to_enum_value(trigger_str);
@@ -363,14 +382,14 @@ void lv_obj_xml_subject_increment_apply(lv_xml_parser_state_t * state, const cha
return;
}
if(subject->type != LV_SUBJECT_TYPE_INT) {
if(subject->type != LV_SUBJECT_TYPE_INT && subject->type != LV_SUBJECT_TYPE_FLOAT) {
LV_LOG_WARN("`%s` subject should have integer type in <lv_obj-subject_increment>", subject_str);
return;
}
void * item = lv_xml_state_get_item(state);
int32_t step = step_str ? lv_xml_atoi(step_str) : 1;
int32_t step = lv_xml_atoi(step_str);
int32_t min_v = min_str ? lv_xml_atoi(min_str) : INT32_MIN;
int32_t max_v = max_str ? lv_xml_atoi(max_str) : INT32_MAX;
lv_obj_add_subject_increment_event(item, subject, trigger, step, min_v, max_v);
-2
View File
@@ -81,14 +81,12 @@ Example
</element>
<element name="subject_set_int_event" access="add">
<arg name="name" type="string"/>
<arg name="trigger" type="lv_event" default="clicked"/>
<arg name="subject" type="subject"/>
<arg name="value" type="int"/>
</element>
<element name="subject_set_string_event" access="add">
<arg name="name" type="string"/>
<arg name="trigger" type="lv_event" default="clicked"/>
<arg name="subject" type="subject"/>
<arg name="value" type="int"/>