Scale (lv_scale)

Overview

Scale Widgets show linear or circular scales with configurable ranges, tick counts, placement, labeling, and sub-sections (Sections) with custom styling.

Parts and Styles

The Scale Widget has the following three parts:

  • LV_PART_MAIN Main line — the blue line in example image.

  • LV_PART_ITEMS Minor ticks — the red minor ticks in example image.

  • LV_PART_INDICATOR Major ticks and their labels (if enabled) — the green major ticks and pink labels in example image.

../../_images/scale.png

Usage

Mode

When a Scale Widget is created, it starts out in MODE LV_SCALE_MODE_HORIZONTAL_BOTTOM. This makes the scale horizontal with tick marks below the line. If you need it to have a different shape, orientation or tick position, use lv_scale_set_mode(scale, mode), where mode can be any of these values:

Setting range

A Scale starts its life with a default numeric range of [0..100] and a default angular range of 270. You can change these ranges with:

where min and max will become the numeric low and high values for the Scale, and angle_range is the angle between the low and high ends of the Scale.

Tick drawing order

Normally ticks and their labels are drawn first and the main line is drawn next, giving the ticks and their labels the appearance of being underneath the main line when there is overlap. You can reverse this sequence if you wish, making the ticks and labels appear on top the main line, using lv_scale_set_draw_ticks_on_top(scale, true). (This effect can be reversed by passing false instead.)

Example with with ticks and labels drawn under the main line (default):

../../_images/scale_ticks_below.png

Example with ticks and labels drawn on top of the main line:

../../_images/scale_ticks_on_top.png

Configuring ticks

You configure the major and minor ticks of a Scale by calling 2 functions:

If you want labels to be drawn with the major ticks, call lv_scale_set_label_show(scale, true). (Pass false to hide them again.)

By default, the labels shown are the numeric values of the scale at the major tick points. Can you specify different label content by calling lv_scale_set_text_src(scale, custom_labels) where custom_labels is an array of string pointers. Example:

static char * custom_labels[3] = {"One", "Two", NULL};

Note that a NULL pointer is used to terminate the list.

The content of the buffers pointed to need to remain valid for the life of the Scale.

For a Scale in one of the ..._ROUND_... modes, you can optionally get it to rotate the major-tick labels to match the rotation of the major ticks using lv_obj_set_style_transform_rotation(scale, LV_SCALE_LABEL_ROTATE_MATCH_TICKS, LV_PART_INDICATOR).

Alternately, labels can be rotated by a fixed amount (for any Scale mode). This example rotates labels by 20 degrees: lv_obj_set_style_transform_rotation(scale, 200, LV_PART_INDICATOR).

Or both of the above can be done at the same time: lv_obj_set_style_transform_rotation(scale, LV_SCALE_LABEL_ROTATE_MATCH_TICKS + 200, LV_PART_INDICATOR).

Some labels of the Scale might be drawn upside down (to match the tick) if the Scale includes a certain angle range. If you don't want this, to automatically rotate the labels to keep them upright, an additional flag can be used. Labels that would be upside down are then rotated 180 lv_obj_set_style_transform_rotation(scale, LV_SCALE_LABEL_ROTATE_MATCH_TICKS | LV_SCALE_LABEL_ROTATE_KEEP_UPRIGHT, LV_PART_INDICATOR). Labels can also be moved a fixed distance in X and Y pixels using lv_obj_set_style_translate_x(scale, 10, LV_PART_INDICATOR).

Note

The major tick value is calculated with the lv_map API (when not setting custom labels), this calculation takes into consideration the total number of ticks and the Scale range, so the label drawn can present rounding errors when the calculated value is a floating-point value.

The length of the ticks can be configured with the length Style property on the LV_PART_INDICATOR for major ticks and LV_PART_ITEMS for minor ticks. Example with local Style: lv_obj_set_style_length(scale, 5, LV_PART_INDICATOR) for major ticks and lv_obj_set_style_length(scale, 5, LV_PART_ITEMS) for minor ticks. The ticks can be padded in either direction (outwards or inwards) for ..._ROUND_... Scales only with: lv_obj_set_style_radial_offset(scale, 5, LV_PART_INDICATOR) for major ticks and lv_obj_set_style_radial_offset(scale, 5, LV_PART_ITEMS) for minor. Using length and radial offset together allows total control of the tick position.

It is also possible to offset the labels from the major ticks (either positive or negative) using lv_obj_set_style_pad_radial(scale, 5, LV_PART_INDICATOR)

Sections

Sections make it possible for portions of a Scale to convey meaning by using different Style properties to draw them (colors, line thicknesses, font, etc.).

A Section represents a sub-range of the Scale, whose Styles (like Cascading Style Sheets) take precedence while drawing the PARTS (lines, arcs, ticks and labels) of the Scale that are within the range of that Section.

If a PART of a Scale is within the range of 2 or more Sections (i.e. those Sections overlap), the Style's properties belonging to the most recently added Section takes precedence over the same style properties of other Section(s) that "involve" that PART.

Creating Sections

A Section is created using lv_scale_add_section(scale), which returns a pointer to a lv_scale_section_t object. This creates a Section with range [0..0] and no Styles added to it, which ensures that Section will not be drawn yet: it needs both a range inside the Scale's range and at least one Style added to it before it will be used in drawing the Scale.

Next, set the range using lv_scale_section_set_range(section, min, max) where min and max are the Section's boundary values that should normally be within the Scale's value range. (If they are only partially within the Scale's range, the Scale will only use that portion of the Section that overlaps the Scale's range. If a Section's range is not within the Scale's range at all, it will not be used in drawing. That can be useful to temporarily "disable" a Section, e.g. lv_scale_section_set_range(section, 0, -1).)

Styling Sections

You set a Section's Style properties by creating a lv_style_t object for each "section" you want to appear different than the parent Scale. Add style properties as is documented in Initialize Styles and Set/Get Properties.

You attach each lv_style_t object to each Section it will apply to using lv_scale_section_set_style(section, PART, style_pointer), where:

  • style_pointer should point to the contents of a global or static variable (can be dynamically-allocated), since it needs to remain valid through the life of the Scale; and

  • PART indicates which single PART of the parent Scale it will apply to, namely LV_PART_MAIN, LV_PART_ITEMS or LV_PART_INDICATOR.

Unlike adding normal styles to Widgets, you cannot combine PARTs by bit-wise OR-ing the PART values together to get the style to apply to more than one part. However, you can do something like this to accomplish the same thing:

static lv_style_t  tick_style;
lv_style_init(&tick_style);
lv_style_set_line_color(&tick_style, lv_palette_darken(LV_PALETTE_RED, 3));
lv_scale_section_set_style(section, LV_PART_ITEMS, &tick_style);
lv_scale_section_set_style(section, LV_PART_INDICATOR, &tick_style);

to get that one Style object to apply to both major and minor ticks.

lv_style_t objects can be shared among Sections and among PARTs, but unlike normal Styles added to a Widget, a Section can only have 1 style per PART. Thus, doing this:

lv_scale_section_set_style(section, LV_PART_INDICATOR, &tick_style_1);
lv_scale_section_set_style(section, LV_PART_INDICATOR, &tick_style_2);

replaces tick_style_1 with tick_style_2 for part LV_PART_INDICATOR rather than adding to it.

Useful Style Properties for Sections

The Style properties that are used during Scale drawing (and are thus useful) are:

Events

No special events are sent by Scale Widgets.

In LV_EVENT_DRAW_TASK_ADDED events, a major or minor line draw descriptor's members id1 and id2 will be the tick index and tick value, respectively. If the part is LV_PART_INDICATOR, it is a major tick. If the part is LV_PART_ITEMS it is a minor tick.

Further Reading

Learn more about Base-Widget Events emitted by all Widgets.

Learn more about Events.

Keys

No Keys are processed by Scale Widgets.

Further Reading

Learn more about Keys.

Example

A simple horizontal scale


An vertical scale with section and custom styling


A simple round scale


A round scale with section and custom styling


A scale with section and custom styling


A round scale with multiple needles, resembling a clock


Customizing scale major tick label color with LV_EVENT_DRAW_TASK_ADDED event


A round scale with labels rotated and translated


A horizontal scale with labels rotated and translated


API

Scale (lv_scale) .. Autogenerated

lv_scale.h

lv_scale_private.h