1.. _lv_scale: 2 3================ 4Scale (lv_scale) 5================ 6 7 8Overview 9******** 10 11Scale Widgets show linear or circular scales with configurable ranges, tick counts, 12placement, labeling, and sub-sections (:ref:`scale_sections`) with custom styling. 13 14 15 16.. _lv_scale_parts_and_styles: 17 18Parts and Styles 19**************** 20 21The Scale Widget has the following three parts: 22 23- :cpp:enumerator:`LV_PART_MAIN` Main line --- the blue line in example image. 24- :cpp:enumerator:`LV_PART_ITEMS` Minor ticks --- the red minor ticks in example image. 25- :cpp:enumerator:`LV_PART_INDICATOR` Major ticks and their labels (if enabled) --- 26 the green major ticks and pink labels in example image. 27 28.. image:: /misc/scale.png 29 30.. _lv_scale_usage: 31 32 33 34Usage 35***** 36 37Mode 38---- 39 40When a Scale Widget is created, it starts out in MODE 41:cpp:enumerator:`LV_SCALE_MODE_HORIZONTAL_BOTTOM`. This makes the scale horizontal 42with tick marks below the line. If you need it to have a different shape, orientation 43or tick position, use :cpp:expr:`lv_scale_set_mode(scale, mode)`, where ``mode`` can 44be any of these values: 45 46- :cpp:enumerator:`LV_SCALE_MODE_HORIZONTAL_TOP` 47- :cpp:enumerator:`LV_SCALE_MODE_HORIZONTAL_BOTTOM` 48- :cpp:enumerator:`LV_SCALE_MODE_VERTICAL_LEFT` 49- :cpp:enumerator:`LV_SCALE_MODE_VERTICAL_RIGHT` 50- :cpp:enumerator:`LV_SCALE_MODE_ROUND_INNER` 51- :cpp:enumerator:`LV_SCALE_MODE_ROUND_OUTER` 52 53 54Setting range 55------------- 56 57A Scale starts its life with a default numeric range of [0..100] and a default 58angular range of 270. You can change these ranges with: 59 60- :cpp:expr:`lv_scale_set_range(scale, min, max)`, and 61- :cpp:expr:`lv_scale_set_angle_range(scale, angle_range)` 62 63where ``min`` and ``max`` will become the numeric low and high values for the Scale, 64and ``angle_range`` is the angle between the low and high ends of the Scale. 65 66 67Tick drawing order 68------------------ 69 70Normally ticks and their labels are drawn first and the main line is drawn next, 71giving the ticks and their labels the appearance of being underneath the main line 72when there is overlap. You can reverse this sequence if you wish, making the ticks 73and labels appear on top the main line, using 74:cpp:expr:`lv_scale_set_draw_ticks_on_top(scale, true)`. (This effect can be 75reversed by passing ``false`` instead.) 76 77Example with with ticks and labels drawn *under* the main line (default): 78 79.. image:: /misc/scale_ticks_below.png 80 81Example with ticks and labels drawn *on top of* the main line: 82 83.. image:: /misc/scale_ticks_on_top.png 84 85 86Configuring ticks 87----------------- 88 89You configure the major and minor ticks of a Scale by calling 2 functions: 90 91- :cpp:expr:`lv_scale_set_total_tick_count(scale, total_tick_count)`, and 92- :cpp:expr:`lv_scale_set_major_tick_every(scale, nth_tick)`. 93 94If you want labels to be drawn with the major ticks, call 95:cpp:expr:`lv_scale_set_label_show(scale, true)`. (Pass ``false`` to hide them again.) 96 97By default, the labels shown are the numeric values of the scale at the major tick 98points. Can you specify different label content by calling 99:cpp:expr:`lv_scale_set_text_src(scale, custom_labels)` where ``custom_labels`` is an 100array of string pointers. Example: 101 102.. code-block:: c 103 104 static char * custom_labels[3] = {"One", "Two", NULL}; 105 106Note that a ``NULL`` pointer is used to terminate the list. 107 108The content of the buffers pointed to need to remain valid for the life of the Scale. 109 110For a Scale in one of the ``..._ROUND_...`` modes, you can optionally get it to 111rotate the major-tick labels to match the rotation of the major ticks using 112:cpp:expr:`lv_obj_set_style_transform_rotation(scale, LV_SCALE_LABEL_ROTATE_MATCH_TICKS, LV_PART_INDICATOR)`. 113 114Alternately, labels can be rotated by a fixed amount (for any Scale mode). This 115example rotates labels by 20 degrees: 116:cpp:expr:`lv_obj_set_style_transform_rotation(scale, 200, LV_PART_INDICATOR)`. 117 118Or both of the above can be done at the same time: 119:cpp:expr:`lv_obj_set_style_transform_rotation(scale, LV_SCALE_LABEL_ROTATE_MATCH_TICKS + 200, LV_PART_INDICATOR)`. 120 121Some labels of the Scale might be drawn upside down (to match the tick) if the Scale includes a certain angle range. 122If you don't want this, to automatically rotate the labels to keep them upright, an additional flag can be used. 123Labels that would be upside down are then rotated 180 124:cpp:expr:`lv_obj_set_style_transform_rotation(scale, LV_SCALE_LABEL_ROTATE_MATCH_TICKS | LV_SCALE_LABEL_ROTATE_KEEP_UPRIGHT, LV_PART_INDICATOR)`. 125Labels can also be moved a fixed distance in X and Y pixels using 126:cpp:expr:`lv_obj_set_style_translate_x(scale, 10, LV_PART_INDICATOR)`. 127 128.. note:: 129 130 The major tick value is calculated with the :cpp:expr:`lv_map` API (when not 131 setting custom labels), this calculation takes into consideration the total 132 number of ticks and the Scale range, so the label drawn can present rounding 133 errors when the calculated value is a floating-point value. 134 135The length of the ticks can be configured with the length Style property on the 136:cpp:enumerator:`LV_PART_INDICATOR` for major ticks and :cpp:enumerator:`LV_PART_ITEMS` 137for minor ticks. Example with local Style: 138:cpp:expr:`lv_obj_set_style_length(scale, 5, LV_PART_INDICATOR)` for major ticks 139and :cpp:expr:`lv_obj_set_style_length(scale, 5, LV_PART_ITEMS)` for minor ticks. The ticks can be 140padded in either direction (outwards or inwards) for ``..._ROUND_...`` Scales only with: 141:cpp:expr:`lv_obj_set_style_radial_offset(scale, 5, LV_PART_INDICATOR)` for major ticks and 142:cpp:expr:`lv_obj_set_style_radial_offset(scale, 5, LV_PART_ITEMS)` for minor. 143Using length and radial offset together allows total control of the tick position. 144 145It is also possible to offset the labels from the major ticks (either positive or negative) using 146:cpp:expr:`lv_obj_set_style_pad_radial(scale, 5, LV_PART_INDICATOR)` 147 148 149.. _scale_sections: 150 151Sections 152-------- 153 154Sections make it possible for portions of a Scale to *convey meaning* by using 155different Style properties to draw them (colors, line thicknesses, font, etc.). 156 157A Section represents a sub-range of the Scale, whose Styles (like Cascading Style 158Sheets) take precedence while drawing the PARTS (lines, arcs, ticks and labels) of 159the Scale that are within the range of that Section. 160 161If a PART of a Scale is within the range of 2 or more Sections (i.e. those Sections 162overlap), the Style's properties belonging to the most recently added Section takes 163precedence over the same style properties of other Section(s) that "involve" that 164PART. 165 166 167.. _scale_creating_sections: 168 169Creating Sections 170~~~~~~~~~~~~~~~~~ 171 172A Section is created using :cpp:expr:`lv_scale_add_section(scale)`, which returns a 173pointer to a :cpp:type:`lv_scale_section_t` object. This creates a Section with 174range [0..0] and no Styles added to it, which ensures that Section will not be drawn 175yet: it needs both a range inside the Scale's range and at least one :ref:`Style 176<styles>` added to it before it will be used in drawing the Scale. 177 178Next, set the range using :cpp:expr:`lv_scale_section_set_range(section, min, max)` 179where ``min`` and ``max`` are the Section's boundary values that should normally be 180within the Scale's value range. (If they are only partially within the Scale's 181range, the Scale will only use that portion of the Section that overlaps the Scale's 182range. If a Section's range is not within the Scale's range at all, it will not be 183used in drawing. That can be useful to temporarily "disable" a Section, e.g. 184:cpp:expr:`lv_scale_section_set_range(section, 0, -1)`.) 185 186 187.. _scale_styling_sections: 188 189Styling Sections 190~~~~~~~~~~~~~~~~ 191 192You set a Section's Style properties by creating a :cpp:type:`lv_style_t` object 193for each "section" you want to appear different than the parent Scale. Add style 194properties as is documented in :ref:`style_initialize`. 195 196You attach each :cpp:type:`lv_style_t` object to each Section it will apply to using 197:cpp:expr:`lv_scale_section_set_style(section, PART, style_pointer)`, where: 198 199- ``style_pointer`` should point to the contents of a global or static variable (can 200 be dynamically-allocated), since it needs to remain valid through the life of the 201 Scale; and 202 203- ``PART`` indicates which single :ref:`PART <lv_scale_parts_and_styles>` of the 204 parent Scale it will apply to, namely :cpp:enumerator:`LV_PART_MAIN`, 205 :cpp:enumerator:`LV_PART_ITEMS` or :cpp:enumerator:`LV_PART_INDICATOR`. 206 207Unlike adding normal styles to Widgets, you cannot combine PARTs by bit-wise OR-ing 208the PART values together to get the style to apply to more than one part. However, 209you can do something like this to accomplish the same thing: 210 211.. code-block:: c 212 213 static lv_style_t tick_style; 214 lv_style_init(&tick_style); 215 lv_style_set_line_color(&tick_style, lv_palette_darken(LV_PALETTE_RED, 3)); 216 lv_scale_section_set_style(section, LV_PART_ITEMS, &tick_style); 217 lv_scale_section_set_style(section, LV_PART_INDICATOR, &tick_style); 218 219to get that one Style object to apply to both major and minor ticks. 220 221:cpp:type:`lv_style_t` objects can be shared among Sections and among PARTs, but 222unlike normal Styles added to a Widget, a Section can only have 1 style per PART. 223Thus, doing this: 224 225.. code-block:: c 226 227 lv_scale_section_set_style(section, LV_PART_INDICATOR, &tick_style_1); 228 lv_scale_section_set_style(section, LV_PART_INDICATOR, &tick_style_2); 229 230replaces ``tick_style_1`` with ``tick_style_2`` for part 231:cpp:enumerator:`LV_PART_INDICATOR` rather than adding to it. 232 233 234Useful Style Properties for Sections 235~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 236 237The Style properties that are used during Scale drawing (and are thus useful) are: 238 239- For main line *when it is a straight line* (:cpp:enumerator:`LV_PART_MAIN`): 240 241 :LV_STYLE_LINE_WIDTH: :cpp:func:`lv_style_set_line_width` 242 :LV_STYLE_LINE_COLOR: :cpp:func:`lv_style_set_line_color` 243 :LV_STYLE_LINE_OPA: :cpp:func:`lv_style_set_line_opa` 244 245- For main line *when it is an arc* (:cpp:enumerator:`LV_PART_MAIN`): 246 247 :LV_STYLE_ARC_WIDTH: :cpp:func:`lv_style_set_arc_width` 248 :LV_STYLE_ARC_COLOR: :cpp:func:`lv_style_set_arc_color` 249 :LV_STYLE_ARC_OPA: :cpp:func:`lv_style_set_arc_opa` 250 :LV_STYLE_ARC_ROUNDED: :cpp:func:`lv_style_set_arc_rounded` 251 :LV_STYLE_ARC_IMAGE_SRC: :cpp:func:`lv_style_set_arc_image_src` 252 253- For tick lines (:cpp:enumerator:`LV_PART_ITEMS` and :cpp:enumerator:`LV_PART_INDICATOR`): 254 255 :LV_STYLE_LINE_WIDTH: :cpp:func:`lv_style_set_line_width` 256 :LV_STYLE_LINE_COLOR: :cpp:func:`lv_style_set_line_color` 257 :LV_STYLE_LINE_OPA: :cpp:func:`lv_style_set_line_opa` 258 259- For labels on major ticks (:cpp:enumerator:`LV_PART_INDICATOR`) 260 261 :LV_STYLE_TEXT_COLOR: :cpp:func:`lv_style_set_text_color` 262 :LV_STYLE_TEXT_OPA: :cpp:func:`lv_style_set_text_opa` 263 :LV_STYLE_TEXT_LETTER_SPACE: :cpp:func:`lv_style_set_text_letter_space` 264 :LV_STYLE_TEXT_FONT: :cpp:func:`lv_style_set_text_font` 265 266 267 268.. _lv_scale_events: 269 270Events 271****** 272 273No special events are sent by Scale Widgets. 274 275.. admonition:: Further Reading 276 277 Learn more about :ref:`lv_obj_events` emitted by all Widgets. 278 279 Learn more about :ref:`events`. 280 281 282 283.. _lv_scale_keys: 284 285Keys 286**** 287 288No *Keys* are processed by Scale Widgets. 289 290.. admonition:: Further Reading 291 292 Learn more about :ref:`indev_keys`. 293 294 295 296.. _lv_scale_example: 297 298Example 299******* 300 301.. include:: ../../examples/widgets/scale/index.rst 302 303 304 305.. _lv_scale_api: 306 307API 308*** 309 310:ref:`lv_scale` 311