mirror of
https://github.com/lvgl/lvgl.git
synced 2026-05-10 04:37:55 +08:00
feat(label): implement api to bind a translation tag to a label (#8948)
Co-authored-by: Liam Howatt <30486941+liamHowatt@users.noreply.github.com>
This commit is contained in:
@@ -76,6 +76,8 @@ These return a translated string which can be used with widgets:
|
||||
lv_dropdown_set_options(dd, lv_tr("color_list"));
|
||||
|
||||
|
||||
.. _translation_fallbacks:
|
||||
|
||||
Fallbacks
|
||||
---------
|
||||
|
||||
@@ -89,6 +91,8 @@ Dynamically Updating UI Text
|
||||
|
||||
When :cpp:expr:`lv_translation_set_language("language")` is called, LVGL sends ``LV_EVENT_TRANSLATION_LANGUAGE_CHANGED`` to every widget, allowing you to update text automatically.
|
||||
|
||||
The new language can be retrieved by either calling :cpp:expr:`lv_translation_get_language()` or by getting the event parameter in the event callback with :cpp:expr:`lv_event_get_param(e)`
|
||||
|
||||
Basic Example
|
||||
-------------
|
||||
|
||||
@@ -99,6 +103,11 @@ Basic Example
|
||||
lv_obj_t * label = lv_event_get_target_obj(e);
|
||||
const char * tag = (const char *) lv_event_get_user_data(e);
|
||||
lv_label_set_text(label, lv_tr(tag));
|
||||
|
||||
/* You can get the new language with `lv_event_get_param`*/
|
||||
/* const char * language = (const char *) lv_event_get_param(e); */
|
||||
/* or with `lv_translation_get_language` */
|
||||
/* const char * language = lv_translation_get_language(); */
|
||||
}
|
||||
|
||||
lv_obj_t * label = lv_label_create(lv_screen_active());
|
||||
|
||||
@@ -76,6 +76,13 @@ they are stored in ROM memory, which is always accessible.
|
||||
realloc() will be forced every time the length of the string changes. That
|
||||
MCU overhead can be avoided by doing the above.
|
||||
|
||||
Set translation tag
|
||||
-------------------
|
||||
|
||||
When using LVGL's translation module, you can bind a translation tag to a label directly with :cpp:expr:`lv_label_set_translation_tag(label, tag)`.
|
||||
After this function is called, future changes to the language will automatically update the label's text to display the corresponding translation
|
||||
for that tag in the new language.
|
||||
|
||||
.. _lv_label_newline:
|
||||
|
||||
Newline
|
||||
|
||||
@@ -34,9 +34,7 @@ e.g., ``languages="en de hu"``. Language codes are free-form, but ISO-style code
|
||||
|
||||
Each ``<translation>`` defines a ``tag``, which acts as the lookup key, and attributes for each language.
|
||||
|
||||
Translations may be omitted --- fallbacks will be applied when needed.
|
||||
|
||||
TODO: link to more information about translation fallbacks: xml_translations_fallbacks
|
||||
Translations may be omitted --- fallbacks will be applied when needed. See :ref:`translation_fallbacks` for more details.
|
||||
|
||||
To register XML translations:
|
||||
|
||||
@@ -44,17 +42,3 @@ To register XML translations:
|
||||
- :cpp:expr:`lv_xml_translation_register_from_data(xml_string)`
|
||||
|
||||
Multiple XML sources can be registered; they will be merged and searched collectively.
|
||||
|
||||
|
||||
|
||||
Usage in XML
|
||||
************
|
||||
|
||||
Some widget properties support a ``*-translated`` suffix to refer to translation tags. For example:
|
||||
|
||||
.. code-block:: xml
|
||||
|
||||
<lv_label text-translated="dog"/>
|
||||
|
||||
This sets the label's text to the translated string for ``"dog"``.
|
||||
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
</styles>
|
||||
|
||||
<view extends="lv_obj" style_radius="3" width="#size" height="content" styles="gray" style_bg_color="$bg_color" >
|
||||
<lv_label text-translated="$title" align="left_mid"/>
|
||||
<lv_label translation_tag="$title" align="left_mid"/>
|
||||
<my_button btn_text="$action" align="right_mid">
|
||||
<style name="$btn_rel_style"/>
|
||||
<style name="$btn_pr_style" selector="pressed"/>
|
||||
|
||||
@@ -34,3 +34,10 @@ Monospace font
|
||||
|
||||
.. lv_example:: widgets/label/lv_example_label_6
|
||||
:language: c
|
||||
|
||||
Assign a translation tag to a label
|
||||
-----------------------------------
|
||||
|
||||
.. lv_example:: widgets/label/lv_example_label_7
|
||||
:language: c
|
||||
|
||||
|
||||
@@ -0,0 +1,59 @@
|
||||
#include "../../lv_examples.h"
|
||||
|
||||
#if LV_USE_TRANSLATION && LV_USE_DROPDOWN && LV_USE_LABEL && LV_BUILD_EXAMPLES
|
||||
|
||||
static const char * tags[] = {"tiger", "lion", "rabbit", "elephant", NULL};
|
||||
static const char * languages[] = {"English", "Deutsch", "Español", NULL};
|
||||
|
||||
static void add_static_translations(void)
|
||||
{
|
||||
static const char * translations[] = {
|
||||
"The Tiger", "Der Tiger", "El Tigre",
|
||||
"The Lion", "Der Löwe", "El León",
|
||||
"The Rabbit", "Das Kaninchen", "El Conejo",
|
||||
"The Elephant", "Der Elefant", "El Elefante",
|
||||
};
|
||||
|
||||
lv_translation_add_static(languages, tags, translations);
|
||||
}
|
||||
|
||||
static void language_change_cb(lv_event_t * e)
|
||||
{
|
||||
static char selected_lang[20];
|
||||
|
||||
lv_obj_t * dropdown = lv_event_get_target_obj(e);
|
||||
lv_dropdown_get_selected_str(dropdown, selected_lang, sizeof(selected_lang));
|
||||
lv_translation_set_language(selected_lang);
|
||||
}
|
||||
|
||||
/**
|
||||
* Use a translation tag in labels
|
||||
*/
|
||||
void lv_example_label_7(void)
|
||||
{
|
||||
lv_obj_set_flex_flow(lv_screen_active(), LV_FLEX_FLOW_COLUMN);
|
||||
lv_obj_set_flex_align(lv_screen_active(), LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER);
|
||||
|
||||
add_static_translations();
|
||||
const size_t tag_count = sizeof(tags) / sizeof(tags[0]) - 1;
|
||||
const size_t lang_count = sizeof(languages) / sizeof(languages[0]) - 1;
|
||||
|
||||
/* Create a dropdown to be able to select the language */
|
||||
lv_obj_t * language_dropdown = lv_dropdown_create(lv_screen_active());
|
||||
lv_dropdown_clear_options(language_dropdown);
|
||||
|
||||
for(size_t i = 0; i < lang_count; ++i) {
|
||||
lv_dropdown_add_option(language_dropdown, languages[i], i);
|
||||
}
|
||||
|
||||
lv_obj_add_event_cb(language_dropdown, language_change_cb, LV_EVENT_VALUE_CHANGED, NULL);
|
||||
lv_translation_set_language("English");
|
||||
|
||||
/* Create a label for each tag */
|
||||
for(size_t i = 0; i < tag_count; ++i) {
|
||||
lv_obj_t * label = lv_label_create(lv_screen_active());
|
||||
lv_label_set_translation_tag(label, tags[i]);
|
||||
}
|
||||
}
|
||||
|
||||
#endif /*LV_USE_TRANSLATION && LV_USE_DROPDOWN && LV_USE_LABEL && LV_BUILD_EXAMPLES*/
|
||||
@@ -98,6 +98,7 @@ void lv_example_label_3(void);
|
||||
void lv_example_label_4(void);
|
||||
void lv_example_label_5(void);
|
||||
void lv_example_label_6(void);
|
||||
void lv_example_label_7(void);
|
||||
|
||||
void lv_example_led_1(void);
|
||||
|
||||
|
||||
@@ -58,9 +58,8 @@ void lv_xml_label_apply(lv_xml_parser_state_t * state, const char ** attrs)
|
||||
if(lv_streq("text", name)) lv_label_set_text(item, value);
|
||||
else if(lv_streq("long_mode", name)) lv_label_set_long_mode(item, long_mode_text_to_enum_value(value));
|
||||
#if LV_USE_TRANSLATION
|
||||
if(lv_streq("text-translated", name)) lv_label_set_text(item, lv_tr(value));
|
||||
else if(lv_streq("translation_tag", name)) lv_label_set_translation_tag(item, value);
|
||||
#endif
|
||||
if(lv_streq("long_mode", name)) lv_label_set_long_mode(item, long_mode_text_to_enum_value(value));
|
||||
else if(lv_streq("bind_text", name)) {
|
||||
lv_subject_t * subject = lv_xml_get_subject(&state->scope, value);
|
||||
if(subject == NULL) {
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
#include "../../stdlib/lv_sprintf.h"
|
||||
#include "../../stdlib/lv_string.h"
|
||||
#include "../../others/observer/lv_observer_private.h"
|
||||
#include "../../others/translation/lv_translation.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
@@ -48,6 +49,8 @@ static void lv_label_destructor(const lv_obj_class_t * class_p, lv_obj_t * obj);
|
||||
static void lv_label_event(const lv_obj_class_t * class_p, lv_event_t * e);
|
||||
static void draw_main(lv_event_t * e);
|
||||
|
||||
static void set_text_internal(lv_obj_t * obj, const char * text);
|
||||
static void remove_translation_tag(lv_obj_t * obj);
|
||||
static void lv_label_refr_text(lv_obj_t * obj);
|
||||
static void lv_label_revert_dots(lv_obj_t * label);
|
||||
static void lv_label_set_dots(lv_obj_t * label, uint32_t dot_begin);
|
||||
@@ -138,43 +141,8 @@ lv_obj_t * lv_label_create(lv_obj_t * parent)
|
||||
void lv_label_set_text(lv_obj_t * obj, const char * text)
|
||||
{
|
||||
LV_ASSERT_OBJ(obj, MY_CLASS);
|
||||
lv_label_t * label = (lv_label_t *)obj;
|
||||
|
||||
/*If text is NULL then just refresh with the current text*/
|
||||
if(text == NULL) text = label->text;
|
||||
|
||||
lv_label_revert_dots(obj); /*In case text == label->text*/
|
||||
const size_t text_len = get_text_length(text);
|
||||
|
||||
/*If set its own text then reallocate it (maybe its size changed)*/
|
||||
if(label->text == text && label->static_txt == 0) {
|
||||
label->text = lv_realloc(label->text, text_len);
|
||||
LV_ASSERT_MALLOC(label->text);
|
||||
if(label->text == NULL) return;
|
||||
|
||||
#if LV_USE_ARABIC_PERSIAN_CHARS
|
||||
lv_text_ap_proc(label->text, label->text);
|
||||
#endif
|
||||
|
||||
}
|
||||
else {
|
||||
/*Free the old text*/
|
||||
if(label->text != NULL && label->static_txt == 0) {
|
||||
lv_free(label->text);
|
||||
label->text = NULL;
|
||||
}
|
||||
|
||||
label->text = lv_malloc(text_len);
|
||||
LV_ASSERT_MALLOC(label->text);
|
||||
if(label->text == NULL) return;
|
||||
|
||||
copy_text_to_label(label, text);
|
||||
|
||||
/*Now the text is dynamically allocated*/
|
||||
label->static_txt = 0;
|
||||
}
|
||||
|
||||
lv_label_refr_text(obj);
|
||||
remove_translation_tag(obj);
|
||||
set_text_internal(obj, text);
|
||||
}
|
||||
|
||||
void lv_label_set_text_fmt(lv_obj_t * obj, const char * fmt, ...)
|
||||
@@ -190,6 +158,7 @@ void lv_label_set_text_vfmt(lv_obj_t * obj, const char * fmt, va_list args)
|
||||
LV_ASSERT_OBJ(obj, MY_CLASS);
|
||||
LV_ASSERT_NULL(fmt);
|
||||
|
||||
remove_translation_tag(obj);
|
||||
lv_obj_invalidate(obj);
|
||||
lv_label_t * label = (lv_label_t *)obj;
|
||||
|
||||
@@ -217,6 +186,7 @@ void lv_label_set_text_static(lv_obj_t * obj, const char * text)
|
||||
LV_ASSERT_OBJ(obj, MY_CLASS);
|
||||
lv_label_t * label = (lv_label_t *)obj;
|
||||
|
||||
remove_translation_tag(obj);
|
||||
if(label->static_txt == 0 && label->text != NULL) {
|
||||
lv_free(label->text);
|
||||
label->text = NULL;
|
||||
@@ -230,6 +200,28 @@ void lv_label_set_text_static(lv_obj_t * obj, const char * text)
|
||||
lv_label_refr_text(obj);
|
||||
}
|
||||
|
||||
#if LV_USE_TRANSLATION
|
||||
void lv_label_set_translation_tag(lv_obj_t * obj, const char * tag)
|
||||
{
|
||||
LV_ASSERT_OBJ(obj, MY_CLASS);
|
||||
lv_label_t * label = (lv_label_t *)obj;
|
||||
if(!tag) {
|
||||
return;
|
||||
}
|
||||
char * new_tag = lv_strdup(tag);
|
||||
LV_ASSERT_MALLOC(new_tag);
|
||||
if(!new_tag) {
|
||||
LV_LOG_WARN("Failed to allocate memory for new tag");
|
||||
return;
|
||||
}
|
||||
if(label->translation_tag) {
|
||||
lv_free(label->translation_tag);
|
||||
}
|
||||
label->translation_tag = new_tag;
|
||||
set_text_internal(obj, lv_tr(tag));
|
||||
}
|
||||
#endif /*LV_USE_TRANSLATION*/
|
||||
|
||||
void lv_label_set_long_mode(lv_obj_t * obj, lv_label_long_mode_t long_mode)
|
||||
{
|
||||
LV_ASSERT_OBJ(obj, MY_CLASS);
|
||||
@@ -796,6 +788,10 @@ static void lv_label_destructor(const lv_obj_class_t * class_p, lv_obj_t * obj)
|
||||
|
||||
if(!label->static_txt) lv_free(label->text);
|
||||
label->text = NULL;
|
||||
#if LV_USE_TRANSLATION
|
||||
if(label->translation_tag) lv_free(label->translation_tag);
|
||||
label->translation_tag = NULL;
|
||||
#endif /*LV_USE_TRANSLATION*/
|
||||
}
|
||||
|
||||
static void lv_label_event(const lv_obj_class_t * class_p, lv_event_t * e)
|
||||
@@ -861,7 +857,17 @@ static void lv_label_event(const lv_obj_class_t * class_p, lv_event_t * e)
|
||||
}
|
||||
else if(code == LV_EVENT_DRAW_MAIN) {
|
||||
draw_main(e);
|
||||
|
||||
}
|
||||
#if LV_USE_TRANSLATION
|
||||
else if(code == LV_EVENT_TRANSLATION_LANGUAGE_CHANGED) {
|
||||
lv_label_t * label = (lv_label_t *)obj;
|
||||
if(label->translation_tag) {
|
||||
const char * new_text = lv_tr(label->translation_tag);
|
||||
set_text_internal(obj, new_text);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
static void draw_main(lv_event_t * e)
|
||||
@@ -978,6 +984,59 @@ static void draw_main(lv_event_t * e)
|
||||
layer->_clip_area = clip_area_ori;
|
||||
}
|
||||
|
||||
static void set_text_internal(lv_obj_t * obj, const char * text)
|
||||
{
|
||||
lv_label_t * label = (lv_label_t *)obj;
|
||||
|
||||
/*If text is NULL then just refresh with the current text*/
|
||||
if(text == NULL) text = label->text;
|
||||
|
||||
lv_label_revert_dots(obj); /*In case text == label->text*/
|
||||
const size_t text_len = get_text_length(text);
|
||||
|
||||
/*If set its own text then reallocate it (maybe its size changed)*/
|
||||
if(label->text == text && label->static_txt == 0) {
|
||||
label->text = lv_realloc(label->text, text_len);
|
||||
LV_ASSERT_MALLOC(label->text);
|
||||
if(label->text == NULL) return;
|
||||
|
||||
#if LV_USE_ARABIC_PERSIAN_CHARS
|
||||
lv_text_ap_proc(label->text, label->text);
|
||||
#endif
|
||||
|
||||
}
|
||||
else {
|
||||
/*Free the old text*/
|
||||
if(label->text != NULL && label->static_txt == 0) {
|
||||
lv_free(label->text);
|
||||
label->text = NULL;
|
||||
}
|
||||
|
||||
label->text = lv_malloc(text_len);
|
||||
LV_ASSERT_MALLOC(label->text);
|
||||
if(label->text == NULL) return;
|
||||
|
||||
copy_text_to_label(label, text);
|
||||
|
||||
/*Now the text is dynamically allocated*/
|
||||
label->static_txt = 0;
|
||||
}
|
||||
|
||||
lv_label_refr_text(obj);
|
||||
}
|
||||
|
||||
static void remove_translation_tag(lv_obj_t * obj)
|
||||
{
|
||||
LV_UNUSED(obj);
|
||||
#if LV_USE_TRANSLATION
|
||||
lv_label_t * label = (lv_label_t *)obj;
|
||||
/* Remove translation tag so we don't update the text automatically if the language changes*/
|
||||
if(label->translation_tag) {
|
||||
lv_free(label->translation_tag);
|
||||
label->translation_tag = NULL;
|
||||
}
|
||||
#endif /*LV_USE_TRANSLATION*/
|
||||
}
|
||||
static void overwrite_anim_property(lv_anim_t * dest, const lv_anim_t * src, lv_label_long_mode_t mode)
|
||||
{
|
||||
switch(mode) {
|
||||
@@ -1409,7 +1468,5 @@ static void label_text_observer_cb(lv_observer_t * observer, lv_subject_t * subj
|
||||
}
|
||||
}
|
||||
|
||||
#endif /*LV_USE_LABEL*/
|
||||
|
||||
|
||||
#endif
|
||||
#endif /*LV_USE_LABEL*/
|
||||
|
||||
@@ -158,6 +158,19 @@ void lv_label_set_text_selection_end(lv_obj_t * obj, uint32_t index);
|
||||
*/
|
||||
void lv_label_set_recolor(lv_obj_t * obj, bool en);
|
||||
|
||||
#if LV_USE_TRANSLATION
|
||||
|
||||
/**
|
||||
* Assign a translation tag for this label. Memory will be allocated to store the tag by the label.
|
||||
* The label text will automatically update when the language is changed via `lv_translation_set_language`.
|
||||
* @param obj pointer to a label object
|
||||
* @param tag '\0' terminated character string.
|
||||
*/
|
||||
void lv_label_set_translation_tag(lv_obj_t * obj, const char * tag);
|
||||
|
||||
#endif /*LV_USE_TRANSLATION*/
|
||||
|
||||
|
||||
/*=====================
|
||||
* Getter functions
|
||||
*====================*/
|
||||
|
||||
@@ -31,6 +31,9 @@ extern "C" {
|
||||
struct _lv_label_t {
|
||||
lv_obj_t obj;
|
||||
char * text;
|
||||
#if LV_USE_TRANSLATION
|
||||
char * translation_tag;
|
||||
#endif /*LV_USE_TRANSLATION*/
|
||||
char dot[LV_LABEL_DOT_NUM + 1]; /**< Bytes that have been replaced with dots */
|
||||
uint32_t dot_begin; /**< Offset where bytes have been replaced with dots */
|
||||
|
||||
|
||||
@@ -789,5 +789,65 @@ void test_label_wrap_mode_clip(void)
|
||||
lv_snprintf(buf, sizeof(buf), "widgets/label_wrap_clip.png");
|
||||
TEST_ASSERT_EQUAL_SCREENSHOT(buf);
|
||||
}
|
||||
void test_label_translation_tag(void)
|
||||
{
|
||||
static const char * tags[] = {"tiger", NULL};
|
||||
static const char * languages[] = {"en", "de", "es", NULL};
|
||||
static const char * translations[] = { "The Tiger", "Der Tiger", "El Tigre" };
|
||||
lv_translation_add_static(languages, tags, translations);
|
||||
label = lv_label_create(NULL);
|
||||
lv_label_set_translation_tag(label, "tiger");
|
||||
|
||||
lv_translation_set_language("en");
|
||||
TEST_ASSERT_EQUAL_STRING(lv_label_get_text(label), "The Tiger");
|
||||
|
||||
lv_translation_set_language("de");
|
||||
TEST_ASSERT_EQUAL_STRING(lv_label_get_text(label), "Der Tiger");
|
||||
|
||||
lv_translation_set_language("es");
|
||||
TEST_ASSERT_EQUAL_STRING(lv_label_get_text(label), "El Tigre");
|
||||
|
||||
/* Unknown language translates to the tag */
|
||||
lv_translation_set_language("fr");
|
||||
TEST_ASSERT_EQUAL_STRING(lv_label_get_text(label), "tiger");
|
||||
}
|
||||
|
||||
void test_label_setting_text_disables_translation(void)
|
||||
{
|
||||
static const char * tags[] = {"tiger", NULL};
|
||||
static const char * languages[] = {"en", "de", "es", NULL};
|
||||
static const char * translations[] = { "The Tiger", "Der Tiger", "El Tigre" };
|
||||
lv_translation_add_static(languages, tags, translations);
|
||||
label = lv_label_create(NULL);
|
||||
lv_label_set_translation_tag(label, "tiger");
|
||||
|
||||
lv_translation_set_language("en");
|
||||
TEST_ASSERT_EQUAL_STRING(lv_label_get_text(label), "The Tiger");
|
||||
|
||||
lv_translation_set_language("de");
|
||||
TEST_ASSERT_EQUAL_STRING(lv_label_get_text(label), "Der Tiger");
|
||||
|
||||
/* Using set text should unbind the translation tag*/
|
||||
lv_label_set_text(label, "Hello world");
|
||||
lv_translation_set_language("de");
|
||||
TEST_ASSERT_EQUAL_STRING(lv_label_get_text(label), "Hello world");
|
||||
|
||||
lv_label_set_translation_tag(label, "tiger");
|
||||
TEST_ASSERT_EQUAL_STRING(lv_label_get_text(label), "Der Tiger");
|
||||
|
||||
/* Using set text static should unbind the translation tag*/
|
||||
lv_label_set_text_static(label, "Hello world");
|
||||
lv_translation_set_language("en");
|
||||
TEST_ASSERT_EQUAL_STRING(lv_label_get_text(label), "Hello world");
|
||||
lv_label_set_translation_tag(label, "tiger");
|
||||
TEST_ASSERT_EQUAL_STRING(lv_label_get_text(label), "The Tiger");
|
||||
|
||||
/* Using set text fmt should unbind the translation tag*/
|
||||
lv_label_set_text_fmt(label, "Hello world %d", 1);
|
||||
lv_translation_set_language("de");
|
||||
TEST_ASSERT_EQUAL_STRING(lv_label_get_text(label), "Hello world 1");
|
||||
lv_label_set_translation_tag(label, "tiger");
|
||||
TEST_ASSERT_EQUAL_STRING(lv_label_get_text(label), "Der Tiger");
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -62,5 +62,21 @@ void test_xml_label_with_attrs(void)
|
||||
|
||||
TEST_ASSERT_EQUAL_SCREENSHOT("xml/lv_label.png");
|
||||
}
|
||||
void test_xml_label_translation_tag(void)
|
||||
{
|
||||
static const char * tags[] = {"tiger", NULL};
|
||||
static const char * languages[] = {"en", "de", "es", NULL};
|
||||
static const char * translations[] = { "The Tiger", "Der Tiger", "El Tigre" };
|
||||
lv_translation_add_static(languages, tags, translations);
|
||||
|
||||
lv_obj_t * scr = lv_screen_active();
|
||||
const char * label1_attrs[] = {
|
||||
"translation_tag", "tiger",
|
||||
NULL, NULL,
|
||||
};
|
||||
lv_obj_t * label = lv_xml_create(scr, "lv_label", label1_attrs);
|
||||
lv_translation_set_language("de");
|
||||
TEST_ASSERT_EQUAL_STRING(lv_label_get_text(label), "Der Tiger");
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
+1
-1
@@ -14,7 +14,7 @@ Example
|
||||
</enumdef>
|
||||
|
||||
<prop name="text" type="string" />
|
||||
<prop name="text-translated" type="string" />
|
||||
<prop name="translation_tag" type="string" />
|
||||
<prop name="long_mode" type="enum:lv_label_long_mode" />
|
||||
<prop name="bind_text">
|
||||
<param name="bind_text" type="subject" />
|
||||
|
||||
Reference in New Issue
Block a user