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