Styles — LVGL documentation (2024)

Styles are used to set the appearance of objects. Styles in lvgl areheavily inspired by CSS. The concept in a nutshell is as follows: - Astyle is an lv_style_t variable which can hold properties likeborder width, text color and so on. It's similar to a class in CSS.

  • Styles can be assigned to objects to change their appearance. Uponassignment, the target part (pseudo-element in CSS) and target state(pseudo class) can be specified. For example one can addstyle_blue to the knob of a slider when it's in pressed state.

  • The same style can be used by any number of objects.

  • Styles can be cascaded which means multiple styles may be assigned to an object andeach style can have different properties. Therefore, not all propertieshave to be specified in a style. LVGL will search for a property until astyle defines it or use a default if it's not specified by any of thestyles. For example style_btn can result in a default gray buttonand style_btn_red can add only a background-color=red tooverwrite the background color.

  • The most recently added style has higher precedence. This means if a propertyis specified in two styles the newest style in the object will be used.

  • Some properties (e.g. text color) can be inherited from a parent(s) if it's not specified in an object.

  • Objects can also have local styles with higher precedence than "normal" styles.

  • Unlike CSS (where pseudo-classes describe different states, e.g. :focus),in LVGL a property is assigned to a given state.

  • Transitions can be applied when the object changes state.

States

The objects can be in the combination of the following states:

  • LV_STATE_DEFAULT: (0x0000) Normal, released state

  • LV_STATE_CHECKED: (0x0001) Toggled or checked state

  • LV_STATE_FOCUSED: (0x0002) Focused via keypad or encoder or clicked via touchpad/mouse

  • LV_STATE_FOCUS_KEY: (0x0004) Focused via keypad or encoder but not via touchpad/mouse

  • LV_STATE_EDITED: (0x0008) Edit by an encoder

  • LV_STATE_HOVERED: (0x0010) Hovered by mouse (not supported now)

  • LV_STATE_PRESSED: (0x0020) Being pressed

  • LV_STATE_SCROLLED: (0x0040) Being scrolled

  • LV_STATE_DISABLED: (0x0080) Disabled state

  • LV_STATE_USER_1: (0x1000) Custom state

  • LV_STATE_USER_2: (0x2000) Custom state

  • LV_STATE_USER_3: (0x4000) Custom state

  • LV_STATE_USER_4: (0x8000) Custom state

An object can be in a combination of states such as being focused andpressed at the same time. This is represented as LV_STATE_FOCUSED | LV_STATE_PRESSED.

A style can be added to any state or state combination. For example,setting a different background color for the default and pressed states.If a property is not defined in a state the best matching state'sproperty will be used. Typically this means the property withLV_STATE_DEFAULT is used.˛ If the property is not set even for thedefault state the default value will be used. (See later)

But what does the "best matching state's property" really mean? Stateshave a precedence which is shown by their value (see in the above list).A higher value means higher precedence. To determine which state'sproperty to use let's take an example. Imagine the background color isdefined like this:

  • LV_STATE_DEFAULT: white

  • LV_STATE_PRESSED: gray

  • LV_STATE_FOCUSED: red

  1. Initially the object is in the default state, so it's a simple case:the property is perfectly defined in the object's current state aswhite.

  2. When the object is pressed there are 2 related properties: defaultwith white (default is related to every state) and pressed with gray.The pressed state has 0x0020 precedence which is higher than thedefault state's 0x0000 precedence, so gray color will be used.

  3. When the object is focused the same thing happens as in pressed stateand red color will be used. (Focused state has higher precedence thandefault state).

  4. When the object is focused and pressed both gray and red would work,but the pressed state has higher precedence than focused so graycolor will be used.

  5. It's possible to set e.g. rose color for LV_STATE_PRESSED | LV_STATE_FOCUSED.In this case, this combined state has 0x0020 + 0x0002 = 0x0022 precedence, which is higher thanthe pressed state's precedence so rose color would be used.

  6. When the object is in the checked state there is no property to setthe background color for this state. So for lack of a better option,the object remains white from the default state's property.

Some practical notes:

  • The precedence (value) of states is quite intuitive, and it's something theuser would expect naturally. E.g. if an object is focused the user will stillwant to see if it's pressed, therefore the pressed state has a higherprecedence. If the focused state had a higher precedence it would overwritethe pressed color.

  • If you want to set a property for all states (e.g. red background color)just set it for the default state. If the object can't find a propertyfor its current state it will fall back to the default state's property.

  • Use ORed states to describe the properties for complex cases. (E.g.pressed + checked + focused)

  • It might be a good idea to use differentstyle elements for different states. For example, finding backgroundcolors for released, pressed, checked + pressed, focused, focused +pressed, focused + pressed + checked, etc. states is quite difficult.Instead, for example, use the background color for pressed and checkedstates and indicate the focused state with a different border color.

Cascading styles

It's not required to set all the properties in one style. It's possibleto add more styles to an object and have the latter added style modifyor extend appearance. For example, create a general gray button styleand create a new one for red buttons where only the new background coloris set.

This is much like in CSS when used classes are listed like<div class=".btn .btn-red">.

Styles added later have precedence over ones set earlier. So in thegray/red button example above, the normal button style should be addedfirst and the red style second. However, the precedence of the statesare still taken into account. So let's examine the following case:

  • the basic button style defines dark-gray color for the default state andlight-gray color for the pressed state

  • the red button style defines the background color as red only in the default state

In this case, when the button is released (it's in default state) itwill be red because a perfect match is found in the most recently addedstyle (red). When the button is pressed the light-gray color is a bettermatch because it describes the current state perfectly, so the buttonwill be light-gray.

Inheritance

Some properties (typically those related to text) can be inherited fromthe parent object's styles. Inheritance is applied only if the givenproperty is not set in the object's styles (even in default state). Inthis case, if the property is inheritable, the property's value will besearched in the parents until an object specifies a value for theproperty. The parents will use their own state to determine the value.So if a button is pressed, and the text color comes from here, thepressed text color will be used.

Parts

Objects can be composed of parts which may each have their own styles.

The following predefined parts exist in LVGL:

  • LV_PART_MAIN: A background like rectangle

  • LV_PART_SCROLLBAR: The scrollbar(s)

  • LV_PART_INDICATOR: Indicator, e.g. for slider, bar, switch, or the tick box of the checkbox

  • LV_PART_KNOB: Like a handle to grab to adjust a value

  • LV_PART_SELECTED: Indicate the currently selected option or section

  • LV_PART_ITEMS: Used if the widget has multiple similar elements (e.g. table cells)

  • LV_PART_CURSOR: Mark a specific place e.g. text area's or chart's cursor

  • LV_PART_CUSTOM_FIRST: Custom part identifiers can be added starting from here.

For example a Slider has three parts:

  • Background

  • Indicator

  • Knob

This means all three parts of the slider can have their own styles. Seelater how to add styles to objects and parts.

Initialize styles and set/get properties

Styles are stored in lv_style_t variables. Style variables should bestatic, global or dynamically allocated. In other words they cannotbe local variables in functions which are destroyed when the functionexits. Before using a style it should be initialized withlv_style_init(&my_style). After initializing a style, properties canbe added or changed.

Property set functions looks like this:lv_style_set_<property_name>(&style, <value>); For example:

static lv_style_t style_btn;lv_style_init(&style_btn);lv_style_set_bg_color(&style_btn, lv_color_hex(0x115588));lv_style_set_bg_opa(&style_btn, LV_OPA_50);lv_style_set_border_width(&style_btn, 2);lv_style_set_border_color(&style_btn, lv_color_black());static lv_style_t style_btn_red;lv_style_init(&style_btn_red);lv_style_set_bg_color(&style_btn_red, lv_plaette_main(LV_PALETTE_RED));lv_style_set_bg_opa(&style_btn_red, LV_OPA_COVER);

To remove a property use:

lv_style_remove_prop(&style, LV_STYLE_BG_COLOR);

To get a property's value from a style:

lv_style_value_t v;lv_result_t res = lv_style_get_prop(&style, LV_STYLE_BG_COLOR, &v);if(res == LV_RESULT_OK) { /*Found*/ do_something(v.color);}

lv_style_value_t has 3 fields:

  • num: for integer, boolean and opacity properties

  • color: for color properties

  • ptr: for pointer properties

To reset a style (free all its data) use:

lv_style_reset(&style);

Styles can be built as const too to save RAM:

const lv_style_const_prop_t style1_props[] = { LV_STYLE_CONST_WIDTH(50), LV_STYLE_CONST_HEIGHT(50), LV_STYLE_CONST_PROPS_END};LV_STYLE_CONST_INIT(style1, style1_props);

Later const style can be used like any other style but (obviously)new properties can not be added.

Add and remove styles to a widget

A style on its own is not that useful. It must be assigned to an objectto take effect.

Add styles

To add a style to an object uselv_obj_add_style(obj, &style, <selector>). <selector> is anOR-ed value of parts and state to which the style should be added. Someexamples:

  • LV_PART_MAIN | LV_STATE_DEFAULT

  • LV_STATE_PRESSED: The main part in pressed state. LV_PART_MAIN can be omitted

  • LV_PART_SCROLLBAR: The scrollbar part in the default state. LV_STATE_DEFAULT can be omitted.

  • LV_PART_SCROLLBAR | LV_STATE_SCROLLED: The scrollbar part when the object is being scrolled

  • LV_PART_INDICATOR | LV_STATE_PRESSED | LV_STATE_CHECKED The indicator part when the object is pressed and checked at the same time.

Using lv_obj_add_style():

lv_obj_add_style(btn, &style_btn, 0); /*Default button style*/lv_obj_add_style(btn, &btn_red, LV_STATE_PRESSED); /*Overwrite only some colors to red when pressed*/

Replace styles

To replace a specific style of an object uselv_obj_replace_style(obj, old_style, new_style, selector). Thisfunction will only replace old_style with new_style if theselector matches the selector used in lv_obj_add_style. Bothstyles, i.e. old_style and new_style, must not be NULL (foradding and removing separate functions exist). If the combination ofold_style and selector exists multiple times in obj'sstyles, all occurrences will be replaced. The return value of thefunction indicates whether at least one successful replacement tookplace.

Using lv_obj_replace_style():

lv_obj_add_style(btn, &style_btn, 0); /*Add a button style*/lv_obj_replace_style(btn, &style_btn, &new_style_btn, 0); /*Replace the button style with a different one*/

Remove styles

To remove all styles from an object use lv_obj_remove_style_all(obj).

To remove specific styles uselv_obj_remove_style(obj, style, selector). This function will removestyle only if the selector matches with the selector used inlv_obj_add_style(). style can be NULL to check only theselector and remove all matching styles. The selector can usethe LV_STATE_ANY and LV_PART_ANY values to remove the style fromany state or part.

Report style changes

If a style which is already assigned to an object changes (i.e. aproperty is added or changed), the objects using that style should benotified. There are 3 options to do this:

  1. If you know that the changed properties can be applied by a simple redraw(e.g. color or opacity changes) just call lv_obj_invalidate(obj)or lv_obj_invalidate(lv_screen_active()).

  2. If more complex style properties were changed or added, and you know whichobject(s) are affected by that style call lv_obj_refresh_style(obj, part, property).To refresh all parts and properties use lv_obj_refresh_style(obj, LV_PART_ANY, LV_STYLE_PROP_ANY).

  3. To make LVGL check all objects to see if they use a style and refresh themwhen needed, call lv_obj_report_style_change(&style). If styleis NULL all objects will be notified about a style change.

Get a property's value on an object

To get a final value of property

  • considering cascading, inheritance, local styles and transitions (see below)

  • property get functions like this can be used: lv_obj_get_style_<property_name>(obj, <part>).These functions use the object's current state and if no better candidate exists they return a default value.For example:

lv_color_t color = lv_obj_get_style_bg_color(btn, LV_PART_MAIN);

Local styles

In addition to "normal" styles, objects can also store local styles.This concept is similar to inline styles in CSS(e.g. <div style="color:red">) with some modification.

Local styles are like normal styles, but they can't be shared amongother objects. If used, local styles are allocated automatically, andfreed when the object is deleted. They are useful to add localcustomization to an object.

Unlike in CSS, LVGL local styles can be assigned to states(pseudo-classes) and parts (pseudo-elements).

To set a local property use functions likelv_obj_set_style_<property_name>(obj, <value>, <selector>); For example:

lv_obj_set_style_bg_color(slider, lv_color_red(), LV_PART_INDICATOR | LV_STATE_FOCUSED);

Properties

For the full list of style properties clickhere.

Typical background properties

In the documentation of the widgets you will see sentences like "Thewidget uses the typical background properties". These "typicalbackground properties" are the ones related to:

  • Background

  • Border

  • Outline

  • Shadow

  • Padding

  • Width and height transformation

  • X and Y translation

Transitions

By default, when an object changes state (e.g. it's pressed) the newproperties from the new state are set immediately. However, withtransitions it's possible to play an animation on state change. Forexample, on pressing a button its background color can be animated tothe pressed color over 300 ms.

The parameters of the transitions are stored in the styles. It'spossible to set

  • the time of the transition

  • the delay before starting the transition

  • the animation path (also known as the timing or easing function)

  • the properties to animate

The transition properties can be defined for each state. For example,setting a 500 ms transition time in the default state means that whenthe object goes to the default state a 500 ms transition time isapplied. Setting a 100 ms transition time in the pressed state causes a100 ms transition when going to the pressed state. This exampleconfiguration results in going to the pressed state quickly and thengoing back to default slowly.

To describe a transition an lv_transition_dsc_t variable needs to beinitialized and added to a style:

/*Only its pointer is saved so must static, global or dynamically allocated */static const lv_style_prop_t trans_props[] = { LV_STYLE_BG_OPA, LV_STYLE_BG_COLOR, 0, /*End marker*/};static lv_style_transition_dsc_t trans1;lv_style_transition_dsc_init(&trans1, trans_props, lv_anim_path_ease_out, duration_ms, delay_ms);lv_style_set_transition(&style1, &trans1);

Opacity, Blend modes and Transformations

If the opa, blend_mode, transform_angle, ortransform_zoom properties are set to their non-default value LVGLcreates a snapshot about the widget and all its children in order toblend the whole widget with the set opacity, blend mode andtransformation properties.

These properties have this effect only on the MAIN part of thewidget.

The created snapshot is called "intermediate layer" or simply "layer".If only opa and/or blend_mode is set to a non-default value LVGLcan build the layer from smaller chunks. The size of these chunks can beconfigured by the following properties in lv_conf.h:

  • LV_LAYER_SIMPLE_BUF_SIZE: [bytes] the optimal target buffer size. LVGL will try to allocate this size of memory.

  • LV_LAYER_SIMPLE_FALLBACK_BUF_SIZE: [bytes] used if LV_LAYER_SIMPLE_BUF_SIZE couldn't be allocated.

If transformation properties were also used the layer can not berendered in chunks, but one larger memory needs to be allocated. Therequired memory depends on the angle, zoom and pivot parameters, and thesize of the area to redraw, but it's never larger than the size of thewidget (including the extra draw size used for shadow, outline, etc).

If the widget can fully cover the area to redraw, LVGL creates an RGBlayer (which is faster to render and uses less memory). If the oppositecase ARGB rendering needs to be used. A widget might not cover its areaif it has radius, bg_opa != 255, has shadow, outline, etc.

The click area of the widget is also transformed accordingly.

Color filter

TODO

Themes

Themes are a collection of styles. If there is an active theme LVGLapplies it on every created widget. This will give a default appearanceto the UI which can then be modified by adding further styles.

Every display can have a different theme. For example, you could have acolorful theme on a TFT and monochrome theme on a secondary monochromedisplay.

To set a theme for a display, two steps are required:

  1. Initialize a theme

  2. Assign the initialized theme to a display.

Theme initialization functions can have different prototypes. Thisexample shows how to set the "default" theme:

lv_theme_t * th = lv_theme_default_init(display, /*Use the DPI, size, etc from this display*/ LV_COLOR_PALETTE_BLUE, LV_COLOR_PALETTE_CYAN, /*Primary and secondary palette*/ false, /*Light or dark mode*/ &lv_font_montserrat_10, &lv_font_montserrat_14, &lv_font_montserrat_18); /*Small, normal, large fonts*/lv_display_set_theme(display, th); /*Assign the theme to the display*/

The included themes are enabled in lv_conf.h. If the default themeis enabled by LV_USE_THEME_DEFAULT LVGL automatically initializesand sets it when a display is created.

Extending themes

Built-in themes can be extended. If a custom theme is created, a parenttheme can be selected. The parent theme's styles will be added beforethe custom theme's styles. Any number of themes can be chained this way.E.g. default theme -> custom theme -> dark theme.

lv_theme_set_parent(new_theme, base_theme) extends thebase_theme with the new_theme.

There is an example for it below.

Examples

[中文]

Size styles

#include "../lv_examples.h"#if LV_BUILD_EXAMPLES && LV_USE_IMAGE/** * Using the Size, Position and Padding style properties */void lv_example_style_1(void){ static lv_style_t style; lv_style_init(&style); lv_style_set_radius(&style, 5); /*Make a gradient*/ lv_style_set_width(&style, 150); lv_style_set_height(&style, LV_SIZE_CONTENT); lv_style_set_pad_ver(&style, 20); lv_style_set_pad_left(&style, 5); lv_style_set_x(&style, lv_pct(50)); lv_style_set_y(&style, 80); /*Create an object with the new style*/ lv_obj_t * obj = lv_obj_create(lv_screen_active()); lv_obj_add_style(obj, &style, 0); lv_obj_t * label = lv_label_create(obj); lv_label_set_text(label, "Hello");}#endif

Background styles

#include "../lv_examples.h"#if LV_BUILD_EXAMPLES/** * Using the background style properties */void lv_example_style_2(void){ static lv_style_t style; lv_style_init(&style); lv_style_set_radius(&style, 5); /*Make a gradient*/ lv_style_set_bg_opa(&style, LV_OPA_COVER); static lv_grad_dsc_t grad; grad.dir = LV_GRAD_DIR_VER; grad.stops_count = 2; grad.stops[0].color = lv_palette_lighten(LV_PALETTE_GREY, 1); grad.stops[0].opa = LV_OPA_COVER; grad.stops[1].color = lv_palette_main(LV_PALETTE_BLUE); grad.stops[1].opa = LV_OPA_COVER; /*Shift the gradient to the bottom*/ grad.stops[0].frac = 128; grad.stops[1].frac = 192; lv_style_set_bg_grad(&style, &grad); /*Create an object with the new style*/ lv_obj_t * obj = lv_obj_create(lv_screen_active()); lv_obj_add_style(obj, &style, 0); lv_obj_center(obj);}#endif

Border styles

#include "../lv_examples.h"#if LV_BUILD_EXAMPLES/** * Using the border style properties */void lv_example_style_3(void){ static lv_style_t style; lv_style_init(&style); /*Set a background color and a radius*/ lv_style_set_radius(&style, 10); lv_style_set_bg_opa(&style, LV_OPA_COVER); lv_style_set_bg_color(&style, lv_palette_lighten(LV_PALETTE_GREY, 1)); /*Add border to the bottom+right*/ lv_style_set_border_color(&style, lv_palette_main(LV_PALETTE_BLUE)); lv_style_set_border_width(&style, 5); lv_style_set_border_opa(&style, LV_OPA_50); lv_style_set_border_side(&style, LV_BORDER_SIDE_BOTTOM | LV_BORDER_SIDE_RIGHT); /*Create an object with the new style*/ lv_obj_t * obj = lv_obj_create(lv_screen_active()); lv_obj_add_style(obj, &style, 0); lv_obj_center(obj);}#endif

Outline styles

#include "../lv_examples.h"#if LV_BUILD_EXAMPLES/** * Using the outline style properties */void lv_example_style_4(void){ static lv_style_t style; lv_style_init(&style); /*Set a background color and a radius*/ lv_style_set_radius(&style, 5); lv_style_set_bg_opa(&style, LV_OPA_COVER); lv_style_set_bg_color(&style, lv_palette_lighten(LV_PALETTE_GREY, 1)); /*Add outline*/ lv_style_set_outline_width(&style, 2); lv_style_set_outline_color(&style, lv_palette_main(LV_PALETTE_BLUE)); lv_style_set_outline_pad(&style, 8); /*Create an object with the new style*/ lv_obj_t * obj = lv_obj_create(lv_screen_active()); lv_obj_add_style(obj, &style, 0); lv_obj_center(obj);}#endif

Shadow styles

#include "../lv_examples.h"#if LV_BUILD_EXAMPLES/** * Using the Shadow style properties */void lv_example_style_5(void){ static lv_style_t style; lv_style_init(&style); /*Set a background color and a radius*/ lv_style_set_radius(&style, 5); lv_style_set_bg_opa(&style, LV_OPA_COVER); lv_style_set_bg_color(&style, lv_palette_lighten(LV_PALETTE_GREY, 1)); /*Add a shadow*/ lv_style_set_shadow_width(&style, 55); lv_style_set_shadow_color(&style, lv_palette_main(LV_PALETTE_BLUE)); /*Create an object with the new style*/ lv_obj_t * obj = lv_obj_create(lv_screen_active()); lv_obj_add_style(obj, &style, 0); lv_obj_center(obj);}#endif

Image styles

#include "../lv_examples.h"#if LV_BUILD_EXAMPLES && LV_USE_IMAGE/** * Using the Image style properties */void lv_example_style_6(void){ static lv_style_t style; lv_style_init(&style); /*Set a background color and a radius*/ lv_style_set_radius(&style, 5); lv_style_set_bg_opa(&style, LV_OPA_COVER); lv_style_set_bg_color(&style, lv_palette_lighten(LV_PALETTE_GREY, 3)); lv_style_set_border_width(&style, 2); lv_style_set_border_color(&style, lv_palette_main(LV_PALETTE_BLUE)); lv_style_set_image_recolor(&style, lv_palette_main(LV_PALETTE_BLUE)); lv_style_set_image_recolor_opa(&style, LV_OPA_50); lv_style_set_transform_rotation(&style, 300); /*Create an object with the new style*/ lv_obj_t * obj = lv_image_create(lv_screen_active()); lv_obj_add_style(obj, &style, 0); LV_IMAGE_DECLARE(img_cogwheel_argb); lv_image_set_src(obj, &img_cogwheel_argb); lv_obj_center(obj);}#endif

Arc styles

#include "../lv_examples.h"#if LV_BUILD_EXAMPLES && LV_USE_ARC/** * Using the Arc style properties */void lv_example_style_7(void){ static lv_style_t style; lv_style_init(&style); lv_style_set_arc_color(&style, lv_palette_main(LV_PALETTE_RED)); lv_style_set_arc_width(&style, 4); /*Create an object with the new style*/ lv_obj_t * obj = lv_arc_create(lv_screen_active()); lv_obj_add_style(obj, &style, 0); lv_obj_center(obj);}#endif

Text styles

#include "../lv_examples.h"#if LV_BUILD_EXAMPLES && LV_USE_LABEL/** * Using the text style properties */void lv_example_style_8(void){ static lv_style_t style; lv_style_init(&style); lv_style_set_radius(&style, 5); lv_style_set_bg_opa(&style, LV_OPA_COVER); lv_style_set_bg_color(&style, lv_palette_lighten(LV_PALETTE_GREY, 2)); lv_style_set_border_width(&style, 2); lv_style_set_border_color(&style, lv_palette_main(LV_PALETTE_BLUE)); lv_style_set_pad_all(&style, 10); lv_style_set_text_color(&style, lv_palette_main(LV_PALETTE_BLUE)); lv_style_set_text_letter_space(&style, 5); lv_style_set_text_line_space(&style, 20); lv_style_set_text_decor(&style, LV_TEXT_DECOR_UNDERLINE); /*Create an object with the new style*/ lv_obj_t * obj = lv_label_create(lv_screen_active()); lv_obj_add_style(obj, &style, 0); lv_label_set_text(obj, "Text of\n" "a label"); lv_obj_center(obj);}#endif

Line styles

#include "../lv_examples.h"#if LV_BUILD_EXAMPLES && LV_USE_LINE/** * Using the line style properties */void lv_example_style_9(void){ static lv_style_t style; lv_style_init(&style); lv_style_set_line_color(&style, lv_palette_main(LV_PALETTE_GREY)); lv_style_set_line_width(&style, 6); lv_style_set_line_rounded(&style, true); /*Create an object with the new style*/ lv_obj_t * obj = lv_line_create(lv_screen_active()); lv_obj_add_style(obj, &style, 0); static lv_point_precise_t p[] = {{10, 30}, {30, 50}, {100, 0}}; lv_line_set_points(obj, p, 3); lv_obj_center(obj);}#endif

Transition

#include "../lv_examples.h"#if LV_BUILD_EXAMPLES && LV_USE_IMAGE/** * Creating a transition */void lv_example_style_10(void){ static const lv_style_prop_t props[] = {LV_STYLE_BG_COLOR, LV_STYLE_BORDER_COLOR, LV_STYLE_BORDER_WIDTH, 0}; /* A default transition * Make it fast (100ms) and start with some delay (200 ms)*/ static lv_style_transition_dsc_t trans_def; lv_style_transition_dsc_init(&trans_def, props, lv_anim_path_linear, 100, 200, NULL); /* A special transition when going to pressed state * Make it slow (500 ms) but start without delay*/ static lv_style_transition_dsc_t trans_pr; lv_style_transition_dsc_init(&trans_pr, props, lv_anim_path_linear, 500, 0, NULL); static lv_style_t style_def; lv_style_init(&style_def); lv_style_set_transition(&style_def, &trans_def); static lv_style_t style_pr; lv_style_init(&style_pr); lv_style_set_bg_color(&style_pr, lv_palette_main(LV_PALETTE_RED)); lv_style_set_border_width(&style_pr, 6); lv_style_set_border_color(&style_pr, lv_palette_darken(LV_PALETTE_RED, 3)); lv_style_set_transition(&style_pr, &trans_pr); /*Create an object with the new style_pr*/ lv_obj_t * obj = lv_obj_create(lv_screen_active()); lv_obj_add_style(obj, &style_def, 0); lv_obj_add_style(obj, &style_pr, LV_STATE_PRESSED); lv_obj_center(obj);}#endif

Using multiple styles

#include "../lv_examples.h"#if LV_BUILD_EXAMPLES && LV_USE_IMAGE/** * Using multiple styles */void lv_example_style_11(void){ /*A base style*/ static lv_style_t style_base; lv_style_init(&style_base); lv_style_set_bg_color(&style_base, lv_palette_main(LV_PALETTE_LIGHT_BLUE)); lv_style_set_border_color(&style_base, lv_palette_darken(LV_PALETTE_LIGHT_BLUE, 3)); lv_style_set_border_width(&style_base, 2); lv_style_set_radius(&style_base, 10); lv_style_set_shadow_width(&style_base, 10); lv_style_set_shadow_offset_y(&style_base, 5); lv_style_set_shadow_opa(&style_base, LV_OPA_50); lv_style_set_text_color(&style_base, lv_color_white()); lv_style_set_width(&style_base, 100); lv_style_set_height(&style_base, LV_SIZE_CONTENT); /*Set only the properties that should be different*/ static lv_style_t style_warning; lv_style_init(&style_warning); lv_style_set_bg_color(&style_warning, lv_palette_main(LV_PALETTE_YELLOW)); lv_style_set_border_color(&style_warning, lv_palette_darken(LV_PALETTE_YELLOW, 3)); lv_style_set_text_color(&style_warning, lv_palette_darken(LV_PALETTE_YELLOW, 4)); /*Create an object with the base style only*/ lv_obj_t * obj_base = lv_obj_create(lv_screen_active()); lv_obj_add_style(obj_base, &style_base, 0); lv_obj_align(obj_base, LV_ALIGN_LEFT_MID, 20, 0); lv_obj_t * label = lv_label_create(obj_base); lv_label_set_text(label, "Base"); lv_obj_center(label); /*Create another object with the base style and earnings style too*/ lv_obj_t * obj_warning = lv_obj_create(lv_screen_active()); lv_obj_add_style(obj_warning, &style_base, 0); lv_obj_add_style(obj_warning, &style_warning, 0); lv_obj_align(obj_warning, LV_ALIGN_RIGHT_MID, -20, 0); label = lv_label_create(obj_warning); lv_label_set_text(label, "Warning"); lv_obj_center(label);}#endif

Local styles

#include "../lv_examples.h"#if LV_BUILD_EXAMPLES && LV_USE_IMAGE/** * Local styles */void lv_example_style_12(void){ static lv_style_t style; lv_style_init(&style); lv_style_set_bg_color(&style, lv_palette_main(LV_PALETTE_GREEN)); lv_style_set_border_color(&style, lv_palette_lighten(LV_PALETTE_GREEN, 3)); lv_style_set_border_width(&style, 3); lv_obj_t * obj = lv_obj_create(lv_screen_active()); lv_obj_add_style(obj, &style, 0); /*Overwrite the background color locally*/ lv_obj_set_style_bg_color(obj, lv_palette_main(LV_PALETTE_ORANGE), LV_PART_MAIN); lv_obj_center(obj);}#endif

Add styles to parts and states

#include "../lv_examples.h"#if LV_BUILD_EXAMPLES && LV_USE_IMAGE/** * Add styles to parts and states */void lv_example_style_13(void){ static lv_style_t style_indic; lv_style_init(&style_indic); lv_style_set_bg_color(&style_indic, lv_palette_lighten(LV_PALETTE_RED, 3)); lv_style_set_bg_grad_color(&style_indic, lv_palette_main(LV_PALETTE_RED)); lv_style_set_bg_grad_dir(&style_indic, LV_GRAD_DIR_HOR); static lv_style_t style_indic_pr; lv_style_init(&style_indic_pr); lv_style_set_shadow_color(&style_indic_pr, lv_palette_main(LV_PALETTE_RED)); lv_style_set_shadow_width(&style_indic_pr, 10); lv_style_set_shadow_spread(&style_indic_pr, 3); /*Create an object with the new style_pr*/ lv_obj_t * obj = lv_slider_create(lv_screen_active()); lv_obj_add_style(obj, &style_indic, LV_PART_INDICATOR); lv_obj_add_style(obj, &style_indic_pr, LV_PART_INDICATOR | LV_STATE_PRESSED); lv_slider_set_value(obj, 70, LV_ANIM_OFF); lv_obj_center(obj);}#endif

Extending the current theme

#include "../lv_examples.h"#if LV_BUILD_EXAMPLES && LV_USE_IMAGEstatic lv_style_t style_btn;/*Will be called when the styles of the base theme are already added to add new styles*/static void new_theme_apply_cb(lv_theme_t * th, lv_obj_t * obj){ LV_UNUSED(th); if(lv_obj_check_type(obj, &lv_button_class)) { lv_obj_add_style(obj, &style_btn, 0); }}static void new_theme_init_and_set(void){ /*Initialize the styles*/ lv_style_init(&style_btn); lv_style_set_bg_color(&style_btn, lv_palette_main(LV_PALETTE_GREEN)); lv_style_set_border_color(&style_btn, lv_palette_darken(LV_PALETTE_GREEN, 3)); lv_style_set_border_width(&style_btn, 3); /*Initialize the new theme from the current theme*/ lv_theme_t * th_act = lv_display_get_theme(NULL); static lv_theme_t th_new; th_new = *th_act; /*Set the parent theme and the style apply callback for the new theme*/ lv_theme_set_parent(&th_new, th_act); lv_theme_set_apply_cb(&th_new, new_theme_apply_cb); /*Assign the new theme to the current display*/ lv_display_set_theme(NULL, &th_new);}/** * Extending the current theme */void lv_example_style_14(void){ lv_obj_t * btn; lv_obj_t * label; btn = lv_button_create(lv_screen_active()); lv_obj_align(btn, LV_ALIGN_TOP_MID, 0, 20); label = lv_label_create(btn); lv_label_set_text(label, "Original theme"); new_theme_init_and_set(); btn = lv_button_create(lv_screen_active()); lv_obj_align(btn, LV_ALIGN_BOTTOM_MID, 0, -20); label = lv_label_create(btn); lv_label_set_text(label, "New theme");}#endif

Opacity and Transformations

#include "../lv_examples.h"#if LV_BUILD_EXAMPLES && LV_USE_BUTTON && LV_USE_LABEL/** * Opacity and Transformations */void lv_example_style_15(void){ lv_obj_t * btn; lv_obj_t * label; /*Normal button*/ btn = lv_button_create(lv_screen_active()); lv_obj_set_size(btn, 100, 40); lv_obj_align(btn, LV_ALIGN_CENTER, 0, -70); label = lv_label_create(btn); lv_label_set_text(label, "Normal"); lv_obj_center(label); /*Set opacity *The button and the label is rendered to a layer first and that layer is blended*/ btn = lv_button_create(lv_screen_active()); lv_obj_set_size(btn, 100, 40); lv_obj_set_style_opa(btn, LV_OPA_50, 0); lv_obj_align(btn, LV_ALIGN_CENTER, 0, 0); label = lv_label_create(btn); lv_label_set_text(label, "Opa:50%"); lv_obj_center(label); /*Set transformations *The button and the label is rendered to a layer first and that layer is transformed*/ btn = lv_button_create(lv_screen_active()); lv_obj_set_size(btn, 100, 40); lv_obj_set_style_transform_rotation(btn, 150, 0); /*15 deg*/ lv_obj_set_style_transform_scale(btn, 256 + 64, 0); /*1.25x*/ lv_obj_set_style_transform_pivot_x(btn, 50, 0); lv_obj_set_style_transform_pivot_y(btn, 20, 0); lv_obj_set_style_opa(btn, LV_OPA_50, 0); lv_obj_align(btn, LV_ALIGN_CENTER, 0, 70); label = lv_label_create(btn); lv_label_set_text(label, "Transf."); lv_obj_center(label);}#endif

API

lv_api_map_v8.h

lv_style.h

lv_style_gen.h

lv_obj_style.h

Styles — LVGL  documentation (2024)
Top Articles
Latest Posts
Article information

Author: Gov. Deandrea McKenzie

Last Updated:

Views: 6337

Rating: 4.6 / 5 (66 voted)

Reviews: 89% of readers found this page helpful

Author information

Name: Gov. Deandrea McKenzie

Birthday: 2001-01-17

Address: Suite 769 2454 Marsha Coves, Debbieton, MS 95002

Phone: +813077629322

Job: Real-Estate Executive

Hobby: Archery, Metal detecting, Kitesurfing, Genealogy, Kitesurfing, Calligraphy, Roller skating

Introduction: My name is Gov. Deandrea McKenzie, I am a spotless, clean, glamorous, sparkling, adventurous, nice, brainy person who loves writing and wants to share my knowledge and understanding with you.