feat(docs): batch 6 of proofread/edited docs (#7277)

This commit is contained in:
Victor Wheeler
2024-11-25 08:20:26 -07:00
committed by GitHub
parent 804aaede39
commit 8c2289f87f
6 changed files with 389 additions and 196 deletions

View File

@@ -4,39 +4,42 @@
Menu (lv_menu)
==============
Overview
********
The menu widget can be used to easily create multi-level menus. It
handles the traversal between pages automatically.
The Menu Widget can be used to easily create multi-level menus. It
handles the traversal between Pages automatically.
.. _lv_menu_parts_and_styles:
Parts and Styles
****************
The menu widget is built from the following Widgets:
The Menu Widget is built from the following Widgets:
- Main container: :cpp:type:`lv_menu_main_cont`
- Main header: :cpp:type:`lv_menu_main_header_cont`
- Back button: :ref:`lv_button`
- Back button icon: :ref:`lv_image`
- Main page: :cpp:type:`lv_menu_page`
- Main Page: :cpp:type:`lv_menu_page`
- Sidebar container: :cpp:type:`lv_menu_sidebar_cont`
- Sidebar header: :cpp:type:`lv_menu_sidebar_header_cont`
- Back button: :ref:`lv_button`
- Back button icon: :ref:`lv_image`
- Sidebar page: :cpp:type:`lv_menu_page`
- Sidebar Page: :cpp:type:`lv_menu_page`
.. _lv_menu_usage:
Usage
*****
Create a menu
Create a Menu
-------------
:cpp:expr:`lv_menu_create(parent)` creates a new empty menu.
:cpp:expr:`lv_menu_create(parent)` creates a new empty Menu.
Header mode
-----------
@@ -60,41 +63,41 @@ The following root back button modes exist:
You can set root back button modes with
:cpp:expr:`lv_menu_set_mode_root_back_button(menu, LV_MENU_ROOT_BACK_BTN...)`.
Create a menu page
Create a Menu Page
------------------
:cpp:expr:`lv_menu_page_create(menu, title)` creates a new empty menu page. You
can add any widgets to the page.
:cpp:expr:`lv_menu_page_create(menu, title)` creates a new empty Menu Page. You
can add any Widgets to the Page.
Set a menu page in the main area
Set a Menu Page in the main area
--------------------------------
Once a menu page has been created, you can set it to the main area with
:cpp:expr:`lv_menu_set_page(menu, page)`. ``NULL`` to clear main and clear menu
Once a Menu Page has been created, you can set it to the main area with
:cpp:expr:`lv_menu_set_page(menu, page)`. ``NULL`` to clear main and clear Menu
history.
Set a menu page in the sidebar
Set a Menu Page in the sidebar
------------------------------
Once a menu page has been created, you can set it to the sidebar with
Once a Menu Page has been created, you can set it to the sidebar with
:cpp:expr:`lv_menu_set_sidebar_page(menu, page)`. ``NULL`` to clear sidebar.
Linking between menu pages
Linking between Menu Pages
--------------------------
For instance, you have created a button obj in the main page. When you
click the button Widget, you want it to open up a new page, use
If you have, for instance, created a button obj in the main Page. When you
click the button Widget, you want it to open up a new Page, use
:cpp:expr:`lv_menu_set_load_page_event(menu, btn, new page)`.
Create a menu container, section, separator
Create a Menu container, section, separator
-------------------------------------------
The following objects can be created so that it is easier to style the
menu:
Menu:
- :cpp:expr:`lv_menu_cont_create(parent page)` creates a new empty container.
- :cpp:expr:`lv_menu_section_create(parent page)` creates a new empty section.
- :cpp:expr:`lv_menu_separator_create(parent page)` creates a separator.
- :cpp:expr:`lv_menu_cont_create(parent_page)` creates a new empty container.
- :cpp:expr:`lv_menu_section_create(parent_page)` creates a new empty section.
- :cpp:expr:`lv_menu_separator_create(parent_page)` creates a separator.
@@ -103,19 +106,19 @@ menu:
Events
******
- :cpp:enumerator:`LV_EVENT_VALUE_CHANGED` Sent when a page is shown.
- :cpp:enumerator:`LV_EVENT_VALUE_CHANGED` Sent when a Page is shown.
- :cpp:expr:`lv_menu_get_cur_main_page(menu)` returns a pointer to menu page
that is currently displayed in main.
- :cpp:expr:`lv_menu_get_cur_sidebar_page(menu)` returns a pointer to menu
page that is currently displayed in sidebar.
- :cpp:expr:`lv_menu_get_cur_main_page(menu)` returns a pointer to Menu Page
that is currently displayed in the main container.
- :cpp:expr:`lv_menu_get_cur_sidebar_page(menu)` returns a pointer to Menu
Page that is currently displayed in the sidebar container.
- :cpp:enumerator:`LV_EVENT_CLICKED` Sent when a back button in a header from either
main or sidebar is clicked. :cpp:enumerator:`LV_OBJ_FLAG_EVENT_BUBBLE` is enabled
on the buttons so you can add events to the menu itself.
on the buttons so you can add events to the Menu itself.
- :cpp:expr:`lv_menu_back_button_is_root(menu, button)` to check if button is root
back button
back button.
.. admonition:: Further Reading

View File

@@ -4,6 +4,8 @@
Message Box (lv_msgbox)
=======================
Overview
********
@@ -14,59 +16,79 @@ with buttons.
The text will be broken into multiple lines and the height
will be set automatically. If the height
is set manually, the content will become scrollable.
is set programmatically, the content will become scrollable.
The message box can be modal (blocking clicks on the rest of the screen)
or not modal.
.. _lv_msgbox_parts_and_styles:
Parts and Styles
****************
The message box is built from other widgets, so you can check these
widgets' documentation for details.
The message box is built from other Widgets, so you can check these
Widgets' documentation for details.
- Content, header, and footer: :ref:`base_widget`
- Buttons: :ref:`lv_button`
- Title and content text: :ref:`lv_label`
.. _lv_msgbox_usage:
Usage
*****
Create a message box
--------------------
:cpp:expr:`lv_msgbox_create(parent)` creates a message box.
If ``parent`` is ``NULL`` the message box will be modal.
E.g. ``const char * btn_txts[] = {"Ok", "Cancel", NULL}``.
If ``parent`` is ``NULL`` the message box will be modal, and will use the
:ref:`default_display`'s Top :ref:`Layer <screen_layers>` as a parent.
Get the parts
-------------
Adding buttons
--------------
If you want to add an [OK] or [Cancel] or other buttons for the
user to have a choice of responses, add each button using the
:cpp:expr:`lv_msgbox_add_footer_button(msgbox, btn_text)` function. Calling this
function adds a footer (container) if one was not already present, and it returns a
pointer to the button created, which can be used to add ``LV_EVENT_CLICKED`` (or
other) events to detect and act on the user's response.
Footer buttons so added are evenly spaced and centered.
Buttons can also be added to the header if desired with
:cpp:expr:`lv_msgbox_add_header_button(msgbox, symbol)`.
Buttons so added are added to the right end of the header.
Getting the parts
-----------------
The building blocks of the message box can be obtained using the
following functions:
.. code-block:: c
lv_obj_t * lv_msgbox_get_content(lv_obj_t * widget);
lv_obj_t * lv_msgbox_get_title(lv_obj_t * widget);
lv_obj_t * lv_msgbox_get_header(lv_obj_t * widget);
lv_obj_t * lv_msgbox_get_footer(lv_obj_t * widget);
lv_obj_t * lv_msgbox_get_content(lv_obj_t * msgbox);
lv_obj_t * lv_msgbox_get_title(lv_obj_t * msgbox);
lv_obj_t * lv_msgbox_get_header(lv_obj_t * msgbox);
lv_obj_t * lv_msgbox_get_footer(lv_obj_t * msgbox);
Functions that add something to the message box return the newly added Widget:
Functions that add something to the message box return a pointer to the newly added Widget:
.. code:: c
lv_obj_t * lv_msgbox_add_text(lv_obj_t * widget, const char * text);
lv_obj_t * lv_msgbox_add_title(lv_obj_t * widget, const char * title);
lv_obj_t * lv_msgbox_add_close_button(lv_obj_t * widget);
lv_obj_t * lv_msgbox_add_header_button(lv_obj_t * widget, const void * icon);
lv_obj_t * lv_msgbox_add_footer_button(lv_obj_t * widget, const char * text);
lv_obj_t * lv_msgbox_add_text(lv_obj_t * msgbox, const char * text);
lv_obj_t * lv_msgbox_add_title(lv_obj_t * msgbox, const char * title);
lv_obj_t * lv_msgbox_add_close_button(lv_obj_t * msgbox);
lv_obj_t * lv_msgbox_add_header_button(lv_obj_t * msgbox, const void * symbol);
lv_obj_t * lv_msgbox_add_footer_button(lv_obj_t * msgbox, const char * text);
Close the message box
@@ -85,7 +107,8 @@ the next call to ``lv_timer_handler`` instead of immediately.
Events
******
No special events are sent by this widget.
No special events are sent by this Widget, though its parts can send events.
See their documentation for details: :ref:`lv_button` and :ref:`lv_label`.
.. admonition:: Further Reading

View File

@@ -4,55 +4,63 @@
Roller (lv_roller)
==================
Overview
********
Roller allows you to simply select one option from a list by scrolling.
Roller allows the end user to select an item from a list by scrolling it.
.. _lv_roller_parts_and_styles:
Parts and Styles
****************
- :cpp:enumerator:`LV_PART_MAIN` The background of the roller uses all the typical
background properties and text style properties.
``style_text_line_space`` adjusts the space between the options. When
the Roller is scrolled and doesn't stop exactly on an option it will
scroll to the nearest valid option automatically in ``anim_time``
milliseconds as specified in the style.
- :cpp:enumerator:`LV_PART_SELECTED` The selected option in the middle. Besides the
typical background properties it uses the text style properties to
change the appearance of the text in the selected area.
- :cpp:enumerator:`LV_PART_MAIN` The background of the Roller uses the
background- and text-style properties.
- Style ``text_line_space`` adjusts the space between list items.
Use :cpp:func:`lv_obj_set_style_text_line_space` to set this value.
- When the Roller is scrolled and doesn't stop exactly on an item, it will
automatically scroll to the nearest valid item in ``anim_time``
milliseconds as specified in the ``anim_duration`` style. Use
:cpp:func:`lv_obj_set_style_anim_duration` to set this value.
- :cpp:enumerator:`LV_PART_SELECTED` The selected item (displayed in the middle of
the Roller). Besides the typical background properties, it uses text style
properties to change the appearance of the text of the selected item.
.. _lv_roller_usage:
Usage
*****
Set options
-----------
Setting the list items
----------------------
Options are passed to the Roller as a string with
:cpp:expr:`lv_roller_set_options(roller, options, LV_ROLLER_MODE_NORMAL)`.
The options should be separated by ``\n``. For example:
List items are passed to the Roller as a string with
:cpp:expr:`lv_roller_set_options(roller, string_list, LV_ROLLER_MODE_NORMAL)`.
The items should be separated by ``\n``. For example:
``"First\nSecond\nThird"``.
:cpp:enumerator:`LV_ROLLER_MODE_INFINITE` makes the roller circular.
:cpp:enumerator:`LV_ROLLER_MODE_INFINITE` makes the Roller circular.
You can select an option manually with
You can select an option programmatically with
:cpp:expr:`lv_roller_set_selected(roller, id, LV_ANIM_ON)`,
where *id* is the index of an option.
where *id* is the zero-based index of the list item to be selected.
If you don't know the index of an option can also select an option with
If you don't know the index of an option can also select an item with
:cpp:expr:`lv_roller_set_selected_str(roller, str, LV_ANIM_ON)`,
where *str* is the string equal to one of the options.
where *str* is the string equal to one of the list items.
Get selected option
-------------------
To get the *index* of the currently selected option use :cpp:expr:`lv_roller_get_selected(roller)`.
To get the *index* of the currently selected item use :cpp:expr:`lv_roller_get_selected(roller)`.
:cpp:expr:`lv_roller_get_selected_str(roller, buf, buf_size)` will copy the name of the selected option to ``buf``.
:cpp:expr:`lv_roller_get_selected_str(roller, buf, buf_size)` will copy the name of the selected item to ``buf``.
Visible rows
------------
@@ -60,7 +68,7 @@ Visible rows
The number of visible rows can be adjusted with :cpp:expr:`lv_roller_set_visible_row_count(roller, num)`.
This function calculates the height with the current style. If the font,
line space, border width, etc. of the roller changes this function needs
line space, border width, etc. of the Roller changes, this function needs
to be called again.
@@ -70,7 +78,7 @@ to be called again.
Events
******
- :cpp:enumerator:`LV_EVENT_VALUE_CHANGED` Sent when a new option is selected.
- :cpp:enumerator:`LV_EVENT_VALUE_CHANGED` Sent when a new list item is selected.
.. admonition:: Further Reading
@@ -85,9 +93,9 @@ Events
Keys
****
- ``LV_KEY_RIGHT/DOWN`` Select the next option
- ``LV_KEY_LEFT/UP`` Select the previous option
- :cpp:enumerator:`LY_KEY_ENTER` Apply the selected option (Send :cpp:enumerator:`LV_EVENT_VALUE_CHANGED` event)
- ``LV_KEY_RIGHT/DOWN`` Select next option
- ``LV_KEY_LEFT/UP`` Select previous option
- :cpp:enumerator:`LY_KEY_ENTER` Accept the selected option (sends :cpp:enumerator:`LV_EVENT_VALUE_CHANGED` event)
.. admonition:: Further Reading

View File

@@ -4,110 +4,259 @@
Scale (lv_scale)
================
Overview
********
Scale allows you to have a linear scale with ranges and sections with custom styling.
Scale Widgets show linear or circular scales with configurable ranges, tick counts,
placement, labeling, and sub-sections (:ref:`scale_sections`) with custom styling.
.. _lv_scale_parts_and_styles:
Parts and Styles
****************
The scale widget is divided in the following three parts:
The Scale Widget has the following three parts:
- :cpp:enumerator:`LV_PART_MAIN` Main line. See blue line in the example image.
- :cpp:enumerator:`LV_PART_ITEMS` Minor ticks. See red minor ticks in the example image.
- :cpp:enumerator:`LV_PART_INDICATOR` Major ticks and its labels (if enabled).
See pink labels and green major ticks in the example image.
- :cpp:enumerator:`LV_PART_MAIN` Main line --- the blue line in example image.
- :cpp:enumerator:`LV_PART_ITEMS` Minor ticks --- the red minor ticks in example image.
- :cpp:enumerator:`LV_PART_INDICATOR` Major ticks and their labels (if enabled) ---
the green major ticks and pink labels in example image.
.. image:: /misc/scale.png
.. _lv_scale_usage:
Usage
*****
Set ranges
----------
Mode
----
When a Scale Widget is created, it starts out in MODE
:cpp:enumerator:`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 :cpp:expr:`lv_scale_set_mode(scale, mode)`, where ``mode`` can
be any of these values:
- :cpp:enumerator:`LV_SCALE_MODE_HORIZONTAL_TOP`
- :cpp:enumerator:`LV_SCALE_MODE_HORIZONTAL_BOTTOM`
- :cpp:enumerator:`LV_SCALE_MODE_VERTICAL_LEFT`
- :cpp:enumerator:`LV_SCALE_MODE_VERTICAL_RIGHT`
- :cpp:enumerator:`LV_SCALE_MODE_ROUND_INNER`
- :cpp:enumerator:`LV_SCALE_MODE_ROUND_OUTER`
Setting range
-------------
A Scale starts its life with a default range of [0..100]. You can change this
range with :cpp:expr:`lv_scale_set_range(scale, min, max)`.
The minor and major range (values of each tick) are configured with :cpp:expr:`lv_scale_set_range(scale, minor_range, major_range)`.
Tick drawing order
------------------
You can set the drawing of the ticks on top of the main line with :cpp:expr:`lv_scale_set_draw_ticks_on_top(scale, true)`. The default
drawing order is below the main line.
This is a scale with the ticks being drawn below of the main line (default):
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
:cpp:expr:`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):
.. image:: /misc/scale_ticks_below.png
This is an scale with the ticks being drawn at the top of the main line:
Example with ticks and labels drawn *on top of* the main line:
.. image:: /misc/scale_ticks_on_top.png
Configure ticks
---------------
Set the number of total ticks with :cpp:expr:`lv_scale_set_total_tick_count(scale, total_tick_count)`
and then configure the major tick being every Nth ticks with :cpp:expr:`lv_scale_set_major_tick_every(scale, nth_tick)`.
Configuring ticks
-----------------
Labels on major ticks can be configured with :cpp:expr:`lv_scale_set_label_show(scale, show_label)`,
set `show_label` to true if labels should be drawn, :cpp:expr:`false` to hide them.
If instead of a numerical value in the major ticks a text is required they can be set
with :cpp:expr:`lv_scale_set_text_src(scale, custom_labels)` using ``NULL`` as the last element,
i.e. ``static char * custom_labels[3] = {"One", "Two", NULL}``.
You configure the major and minor ticks of a Scale by calling 2 functions:
It's possible to have the labels automatically rotated to match the ticks (only for RADIAL scales) using
:cpp:expr:`lv_obj_set_style_transform_rotation(scale, LV_SCALE_LABEL_ROTATE_MATCH_TICKS, LV_PART_INDICATOR);`
Or rotated a fixed amount (on any scale type) - here for 20 degrees:
:cpp:expr:`lv_obj_set_style_transform_rotation(scale, 20, LV_PART_INDICATOR);`
Or both at the same time
:cpp:expr:`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.
- :cpp:expr:`lv_scale_set_total_tick_count(scale, total_tick_count)`, and
- :cpp:expr:`lv_scale_set_major_tick_every(scale, nth_tick)`.
If you want labels to be drawn with the major ticks, call
:cpp:expr:`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
:cpp:expr:`lv_scale_set_text_src(scale, custom_labels)` where ``custom_labels`` is an
array of string pointers. Example:
.. code-block:: c
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
:cpp:expr:`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:
:cpp:expr:`lv_obj_set_style_transform_rotation(scale, 200, LV_PART_INDICATOR)`.
Or both of the above can be done at the same time:
:cpp:expr:`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
:cpp:expr:`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 using e.g.
:cpp:expr:`lv_obj_set_style_translate_x(scale, 10, LV_PART_INDICATOR);`
:cpp:expr:`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
:cpp:expr:`lv_obj_set_style_translate_x(scale, 10, LV_PART_INDICATOR)`.
.. note::
The major tick value is calculated with the :cpp:expr:`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 float number.
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 :cpp:enumerator:`LV_PART_INDICATOR`
for major ticks and :cpp:enumerator:`LV_PART_ITEMS` for minor ticks, for example with local style:
:cpp:expr:`lv_obj_set_style_length(scale, 5, LV_PART_INDICATOR);` for major ticks
and :cpp:expr:`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 RADIAL scales only with:
:cpp:expr:`lv_obj_set_style_radial_offset(scale, 5, LV_PART_INDICATOR);` for major ticks and
:cpp:expr:`lv_obj_set_style_radial_offset(scale, 5, LV_PART_ITEMS);` for minor .
The length of the ticks can be configured with the length Style property on the
:cpp:enumerator:`LV_PART_INDICATOR` for major ticks and :cpp:enumerator:`LV_PART_ITEMS`
for minor ticks. Example with local Style:
:cpp:expr:`lv_obj_set_style_length(scale, 5, LV_PART_INDICATOR)` for major ticks
and :cpp:expr:`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:
:cpp:expr:`lv_obj_set_style_radial_offset(scale, 5, LV_PART_INDICATOR)` for major ticks and
:cpp:expr:`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.
i.e. :cpp:expr:`static char * custom_labels[3] = {"One", "Two", NULL}`.
It is also possible to offset the labels from the major ticks (either positive or negative) using
:cpp:expr:`lv_obj_set_style_pad_radial(scale, 5, LV_PART_INDICATOR);`
It is also possible to offset the labels from the major ticks (either positive or negative) using
:cpp:expr:`lv_obj_set_style_pad_radial(scale, 5, LV_PART_INDICATOR)`
.. _scale_sections:
Sections
--------
A section is the space between a minor and a major range. They can be created with :cpp:expr:`lv_scale_add_section(scale)`
and it handles back an :cpp:type:`lv_scale_section_t` pointer.
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.).
The range of the section is configured with :cpp:expr:`lv_scale_section_set_range(section, minor_range, major_range)`.
The style of each of the three parts of the scale section can be set with
:cpp:expr:`lv_scale_section_set_style(section, PART, style_pointer)`, where `PART` can be
:cpp:enumerator:`LV_PART_MAIN`, :cpp:enumerator:`LV_PART_ITEMS` or :cpp:enumerator:`LV_PART_INDICATOR`,
:cpp:expr:`style_pointer` should point to a global or static :cpp:type:`lv_style_t` variable.
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.
For labels the following properties can be configured:
:cpp:func:`lv_style_set_text_font`, :cpp:func:`lv_style_set_text_color`,
:cpp:func:`lv_style_set_text_letter_space`, :cpp:func:`lv_style_set_text_opa`.
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.
For lines (main line, major and minor ticks) the following properties can be configured:
:cpp:func:`lv_style_set_line_color`, :cpp:func:`lv_style_set_line_width`.
.. _scale_creating_sections:
Creating Sections
~~~~~~~~~~~~~~~~~
A Section is created using :cpp:expr:`lv_scale_add_section(scale)`, which returns a
pointer to a :cpp:type:`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 :ref:`Style
<styles>` added to it before it will be used in drawing the Scale.
Next, set the range using :cpp:expr:`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.
:cpp:expr:`lv_scale_section_set_range(section, 0, -1)`.)
.. _scale_styling_sections:
Styling Sections
~~~~~~~~~~~~~~~~
You set a Section's Style properties by creating a :cpp:type:`lv_style_t` object
for each "section" you want to appear different than the parent Scale. Add style
properties as is documented in :ref:`style_initialize`.
You attach each :cpp:type:`lv_style_t` object to each Section it will apply to using
:cpp:expr:`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 :ref:`PART <lv_scale_parts_and_styles>` of the
parent Scale it will apply to, namely :cpp:enumerator:`LV_PART_MAIN`,
:cpp:enumerator:`LV_PART_ITEMS` or :cpp:enumerator:`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:
.. code-block:: c
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.
:cpp:type:`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:
.. code-block:: c
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
:cpp:enumerator:`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:
- For main line *when it is a straight line* (:cpp:enumerator:`LV_PART_MAIN`):
:LV_STYLE_LINE_WIDTH: :cpp:func:`lv_style_set_line_width`
:LV_STYLE_LINE_COLOR: :cpp:func:`lv_style_set_line_color`
:LV_STYLE_LINE_OPA: :cpp:func:`lv_style_set_line_opa`
- For main line *when it is an arc* (:cpp:enumerator:`LV_PART_MAIN`):
:LV_STYLE_ARC_WIDTH: :cpp:func:`lv_style_set_arc_width`
:LV_STYLE_ARC_COLOR: :cpp:func:`lv_style_set_arc_color`
:LV_STYLE_ARC_OPA: :cpp:func:`lv_style_set_arc_opa`
:LV_STYLE_ARC_ROUNDED: :cpp:func:`lv_style_set_arc_rounded`
:LV_STYLE_ARC_IMAGE_SRC: :cpp:func:`lv_style_set_arc_image_src`
- For tick lines (:cpp:enumerator:`LV_PART_ITEMS` and :cpp:enumerator:`LV_PART_INDICATOR`):
:LV_STYLE_LINE_WIDTH: :cpp:func:`lv_style_set_line_width`
:LV_STYLE_LINE_COLOR: :cpp:func:`lv_style_set_line_color`
:LV_STYLE_LINE_OPA: :cpp:func:`lv_style_set_line_opa`
- For labels on major ticks (:cpp:enumerator:`LV_PART_INDICATOR`)
:LV_STYLE_TEXT_COLOR: :cpp:func:`lv_style_set_text_color`
:LV_STYLE_TEXT_OPA: :cpp:func:`lv_style_set_text_opa`
:LV_STYLE_TEXT_LETTER_SPACE: :cpp:func:`lv_style_set_text_letter_space`
:LV_STYLE_TEXT_FONT: :cpp:func:`lv_style_set_text_font`
@@ -116,7 +265,7 @@ For lines (main line, major and minor ticks) the following properties can be con
Events
******
No events supported by this widget.
No special events are sent by Scale Widgets.
.. admonition:: Further Reading

View File

@@ -332,17 +332,9 @@ lv_scale_section_t * lv_scale_add_section(lv_obj_t * obj)
if(section == NULL) return NULL;
/* Section default values */
section->main_style = NULL;
section->indicator_style = NULL;
section->items_style = NULL;
section->minor_range = 0U;
section->major_range = 0U;
lv_memzero(section, sizeof(lv_scale_section_t));
section->first_tick_idx_in_section = LV_SCALE_TICK_IDX_DEFAULT_ID;
section->last_tick_idx_in_section = LV_SCALE_TICK_IDX_DEFAULT_ID;
section->first_tick_idx_is_major = 0U;
section->last_tick_idx_is_major = 0U;
section->first_tick_in_section_width = 0U;
section->last_tick_in_section_width = 0U;
return section;
}
@@ -444,13 +436,13 @@ static void lv_scale_constructor(const lv_obj_class_t * class_p, lv_obj_t * obj)
scale->label_enabled = LV_SCALE_LABEL_ENABLED_DEFAULT;
scale->angle_range = LV_SCALE_DEFAULT_ANGLE_RANGE;
scale->rotation = LV_SCALE_DEFAULT_ROTATION;
scale->range_min = 0U;
scale->range_max = 100U;
scale->last_tick_width = 0U;
scale->first_tick_width = 0U;
scale->range_min = 0;
scale->range_max = 100;
scale->last_tick_width = 0;
scale->first_tick_width = 0;
scale->post_draw = false;
scale->draw_ticks_on_top = false;
scale->custom_label_cnt = 0U;
scale->custom_label_cnt = 0;
scale->txt_src = NULL;
lv_obj_remove_flag(obj, LV_OBJ_FLAG_SCROLLABLE);
@@ -557,16 +549,18 @@ static void scale_draw_indicator(lv_obj_t * obj, lv_event_t * event)
lv_draw_line_dsc_init(&main_line_dsc);
lv_obj_init_draw_line_dsc(obj, LV_PART_MAIN, &main_line_dsc);
const uint32_t total_tick_count = scale->total_tick_count;
uint32_t tick_idx = 0;
uint32_t major_tick_idx = 0;
/* These 2 values need to be signed since they are being passed
* to `lv_map()` which expects signed integers. */
const int32_t total_tick_count = scale->total_tick_count;
int32_t tick_idx = 0;
uint32_t major_tick_idx = 0U;
for(tick_idx = 0; tick_idx < total_tick_count; tick_idx++) {
/* A major tick is the one which has a label in it */
bool is_major_tick = false;
if(tick_idx % scale->major_tick_every == 0) is_major_tick = true;
if(is_major_tick) major_tick_idx++;
const int32_t tick_value = lv_map(tick_idx, 0U, total_tick_count - 1, scale->range_min, scale->range_max);
const int32_t tick_value = lv_map(tick_idx, 0, total_tick_count - 1, scale->range_min, scale->range_max);
label_dsc.base.id1 = tick_idx;
label_dsc.base.id2 = tick_value;
@@ -658,16 +652,16 @@ static void scale_draw_label(lv_obj_t * obj, lv_event_t * event, lv_draw_label_d
/* Find the center of the scale */
lv_point_t center_point;
int32_t radius_edge = LV_MIN(lv_area_get_width(&scale_area) / 2U, lv_area_get_height(&scale_area) / 2U);
int32_t radius_edge = LV_MIN(lv_area_get_width(&scale_area) / 2, lv_area_get_height(&scale_area) / 2);
center_point.x = scale_area.x1 + radius_edge;
center_point.y = scale_area.y1 + radius_edge;
const int32_t major_len = lv_obj_get_style_length(obj, LV_PART_INDICATOR);
/* Also take into consideration the letter space of the style */
int32_t angle_upscale = ((tick_idx * scale->angle_range) * 10U) / (scale->total_tick_count - 1) +
(translate_rotation * 10U);
angle_upscale += scale->rotation * 10U;
int32_t angle_upscale = ((tick_idx * scale->angle_range) * 10U) / (scale->total_tick_count - 1U) +
(translate_rotation * 10);
angle_upscale += scale->rotation * 10;
uint32_t radius_text = 0;
if(LV_SCALE_MODE_ROUND_INNER == scale->mode) {
@@ -756,7 +750,7 @@ static void scale_calculate_main_compensation(lv_obj_t * obj)
const bool is_major_tick = tick_idx % scale->major_tick_every == 0;
const int32_t tick_value = lv_map(tick_idx, 0U, total_tick_count - 1, scale->range_min, scale->range_max);
const int32_t tick_value = lv_map(tick_idx, 0, total_tick_count - 1, scale->range_min, scale->range_max);
/* Overwrite label and tick properties if tick value is within section range */
lv_scale_section_t * section;
@@ -812,24 +806,24 @@ static void scale_draw_main(lv_obj_t * obj, lv_event_t * event)
const int32_t pad_left = lv_obj_get_style_pad_left(obj, LV_PART_MAIN) + border_width;
const int32_t pad_right = lv_obj_get_style_pad_right(obj, LV_PART_MAIN) + border_width;
int32_t x_ofs = 0U;
int32_t y_ofs = 0U;
int32_t x_ofs = 0;
int32_t y_ofs = 0;
if(LV_SCALE_MODE_VERTICAL_LEFT == scale->mode) {
x_ofs = obj->coords.x2 + (line_dsc.width / 2U) - pad_right;
x_ofs = obj->coords.x2 + (line_dsc.width / 2) - pad_right;
y_ofs = obj->coords.y1 + pad_top;
}
else if(LV_SCALE_MODE_VERTICAL_RIGHT == scale->mode) {
x_ofs = obj->coords.x1 + (line_dsc.width / 2U) + pad_left;
x_ofs = obj->coords.x1 + (line_dsc.width / 2) + pad_left;
y_ofs = obj->coords.y1 + pad_top;
}
if(LV_SCALE_MODE_HORIZONTAL_BOTTOM == scale->mode) {
x_ofs = obj->coords.x1 + pad_right;
y_ofs = obj->coords.y1 + (line_dsc.width / 2U) + pad_top;
y_ofs = obj->coords.y1 + (line_dsc.width / 2) + pad_top;
}
else if(LV_SCALE_MODE_HORIZONTAL_TOP == scale->mode) {
x_ofs = obj->coords.x1 + pad_left;
y_ofs = obj->coords.y2 + (line_dsc.width / 2U) - pad_bottom;
y_ofs = obj->coords.y2 + (line_dsc.width / 2) - pad_bottom;
}
else { /* Nothing to do */ }
@@ -838,14 +832,14 @@ static void scale_draw_main(lv_obj_t * obj, lv_event_t * event)
/* Setup the tick points */
if(LV_SCALE_MODE_VERTICAL_LEFT == scale->mode || LV_SCALE_MODE_VERTICAL_RIGHT == scale->mode) {
main_line_point_a.x = x_ofs - 1U;
main_line_point_a.x = x_ofs - 1;
main_line_point_a.y = y_ofs;
main_line_point_b.x = x_ofs - 1U;
main_line_point_b.x = x_ofs - 1;
main_line_point_b.y = obj->coords.y2 - pad_bottom;
/* Adjust main line with initial and last tick width */
main_line_point_a.y -= scale->last_tick_width / 2U;
main_line_point_b.y += scale->first_tick_width / 2U;
main_line_point_a.y -= scale->last_tick_width / 2;
main_line_point_b.y += scale->first_tick_width / 2;
}
else {
main_line_point_a.x = x_ofs;
@@ -855,8 +849,8 @@ static void scale_draw_main(lv_obj_t * obj, lv_event_t * event)
main_line_point_b.y = y_ofs;
/* Adjust main line with initial and last tick width */
main_line_point_a.x -= scale->last_tick_width / 2U;
main_line_point_b.x += scale->first_tick_width / 2U;
main_line_point_a.x -= scale->last_tick_width / 2;
main_line_point_b.x += scale->first_tick_width / 2;
}
line_dsc.p1 = lv_point_to_precise(&main_line_point_a);
@@ -873,8 +867,8 @@ static void scale_draw_main(lv_obj_t * obj, lv_event_t * event)
lv_point_t section_point_a;
lv_point_t section_point_b;
const int32_t first_tick_width_halved = (int32_t)(section->first_tick_in_section_width / 2U);
const int32_t last_tick_width_halved = (int32_t)(section->last_tick_in_section_width / 2U);
const int32_t first_tick_width_halved = (int32_t)(section->first_tick_in_section_width / 2);
const int32_t last_tick_width_halved = (int32_t)(section->last_tick_in_section_width / 2);
/* Calculate the position of the section based on the ticks (first and last) index */
if(LV_SCALE_MODE_VERTICAL_LEFT == scale->mode || LV_SCALE_MODE_VERTICAL_RIGHT == scale->mode) {
@@ -970,7 +964,7 @@ static void scale_get_center(const lv_obj_t * obj, lv_point_t * center, int32_t
int32_t top_bg = lv_obj_get_style_pad_top(obj, LV_PART_MAIN);
int32_t bottom_bg = lv_obj_get_style_pad_bottom(obj, LV_PART_MAIN);
int32_t r = (LV_MIN(lv_obj_get_width(obj) - left_bg - right_bg, lv_obj_get_height(obj) - top_bg - bottom_bg)) / 2U;
int32_t r = (LV_MIN(lv_obj_get_width(obj) - left_bg - right_bg, lv_obj_get_height(obj) - top_bg - bottom_bg)) / 2;
center->x = obj->coords.x1 + r + left_bg;
center->y = obj->coords.y1 + r + top_bg;
@@ -1026,25 +1020,25 @@ static void scale_get_tick_points(lv_obj_t * obj, const uint32_t tick_idx, bool
const int32_t tick_pad_top = lv_obj_get_style_pad_top(obj, LV_PART_ITEMS);
const int32_t tick_pad_bottom = lv_obj_get_style_pad_bottom(obj, LV_PART_ITEMS);
int32_t x_ofs = 0U;
int32_t y_ofs = 0U;
int32_t x_ofs = 0;
int32_t y_ofs = 0;
if(LV_SCALE_MODE_VERTICAL_LEFT == scale->mode) {
x_ofs = obj->coords.x2 + (main_line_dsc.width / 2U) - pad_right;
x_ofs = obj->coords.x2 + (main_line_dsc.width / 2) - pad_right;
y_ofs = obj->coords.y1 + (pad_top + tick_pad_top);
}
else if(LV_SCALE_MODE_VERTICAL_RIGHT == scale->mode) {
x_ofs = obj->coords.x1 + (main_line_dsc.width / 2U) + pad_left;
x_ofs = obj->coords.x1 + (main_line_dsc.width / 2) + pad_left;
y_ofs = obj->coords.y1 + (pad_top + tick_pad_top);
}
else if(LV_SCALE_MODE_HORIZONTAL_BOTTOM == scale->mode) {
x_ofs = obj->coords.x1 + (pad_right + tick_pad_right);
y_ofs = obj->coords.y1 + (main_line_dsc.width / 2U) + pad_top;
y_ofs = obj->coords.y1 + (main_line_dsc.width / 2) + pad_top;
}
/* LV_SCALE_MODE_HORIZONTAL_TOP == scale->mode */
else {
x_ofs = obj->coords.x1 + (pad_left + tick_pad_left);
y_ofs = obj->coords.y2 + (main_line_dsc.width / 2U) - pad_bottom;
y_ofs = obj->coords.y2 + (main_line_dsc.width / 2) - pad_bottom;
}
/* Adjust length when tick will be drawn on horizontal top or vertical right scales */
@@ -1082,7 +1076,7 @@ static void scale_get_tick_points(lv_obj_t * obj, const uint32_t tick_idx, bool
}
else { /* Nothing to do */ }
tick_point_a->x = x_ofs - 1U; /* Move extra pixel out of scale boundary */
tick_point_a->x = x_ofs - 1; /* Move extra pixel out of scale boundary */
tick_point_a->y = vertical_position;
tick_point_b->x = tick_point_a->x - tick_length;
tick_point_b->y = vertical_position;
@@ -1115,12 +1109,12 @@ static void scale_get_tick_points(lv_obj_t * obj, const uint32_t tick_idx, bool
/* Find the center of the scale */
lv_point_t center_point;
const int32_t radius_edge = LV_MIN(lv_area_get_width(&scale_area) / 2U, lv_area_get_height(&scale_area) / 2U);
const int32_t radius_edge = LV_MIN(lv_area_get_width(&scale_area) / 2, lv_area_get_height(&scale_area) / 2);
center_point.x = scale_area.x1 + radius_edge;
center_point.y = scale_area.y1 + radius_edge;
int32_t angle_upscale = ((tick_idx * scale->angle_range) * 10U) / (scale->total_tick_count - 1);
angle_upscale += scale->rotation * 10U;
int32_t angle_upscale = (int32_t)((tick_idx * scale->angle_range) * 10U) / (scale->total_tick_count - 1U);
angle_upscale += scale->rotation * 10;
/* Draw a little bit longer lines to be sure the mask will clip them correctly
* and to get a better precision. Adding the main line width to the calculation so we don't have gaps
@@ -1168,8 +1162,8 @@ static void scale_get_label_coords(lv_obj_t * obj, lv_draw_label_dsc_t * label_d
/* Set the label draw area at some distance of the major tick */
if((LV_SCALE_MODE_HORIZONTAL_BOTTOM == scale->mode) || (LV_SCALE_MODE_HORIZONTAL_TOP == scale->mode)) {
label_coords->x1 = tick_point->x - (label_size.x / 2U);
label_coords->x2 = tick_point->x + (label_size.x / 2U);
label_coords->x1 = tick_point->x - (label_size.x / 2);
label_coords->x2 = tick_point->x + (label_size.x / 2);
if(LV_SCALE_MODE_HORIZONTAL_BOTTOM == scale->mode) {
label_coords->y1 = tick_point->y + lv_obj_get_style_pad_bottom(obj, LV_PART_INDICATOR);
@@ -1181,8 +1175,8 @@ static void scale_get_label_coords(lv_obj_t * obj, lv_draw_label_dsc_t * label_d
}
}
else if((LV_SCALE_MODE_VERTICAL_LEFT == scale->mode) || (LV_SCALE_MODE_VERTICAL_RIGHT == scale->mode)) {
label_coords->y1 = tick_point->y - (label_size.y / 2U);
label_coords->y2 = tick_point->y + (label_size.y / 2U);
label_coords->y1 = tick_point->y - (label_size.y / 2);
label_coords->y2 = tick_point->y + (label_size.y / 2);
if(LV_SCALE_MODE_VERTICAL_LEFT == scale->mode) {
label_coords->x1 = tick_point->x - label_size.x - lv_obj_get_style_pad_left(obj, LV_PART_INDICATOR);
@@ -1194,8 +1188,8 @@ static void scale_get_label_coords(lv_obj_t * obj, lv_draw_label_dsc_t * label_d
}
}
else if(LV_SCALE_MODE_ROUND_OUTER == scale->mode || LV_SCALE_MODE_ROUND_INNER == scale->mode) {
label_coords->x1 = tick_point->x - (label_size.x / 2U);
label_coords->y1 = tick_point->y - (label_size.y / 2U);
label_coords->x1 = tick_point->x - (label_size.x / 2);
label_coords->y1 = tick_point->y - (label_size.y / 2);
label_coords->x2 = label_coords->x1 + label_size.x;
label_coords->y2 = label_coords->y1 + label_size.y;
}
@@ -1397,7 +1391,7 @@ static void scale_find_section_tick_idx(lv_obj_t * obj)
bool is_major_tick = false;
if(tick_idx % scale->major_tick_every == 0) is_major_tick = true;
const int32_t tick_value = lv_map(tick_idx, 0U, total_tick_count - 1, min_out, max_out);
const int32_t tick_value = lv_map(tick_idx, 0, total_tick_count - 1, min_out, max_out);
lv_scale_section_t * section;
LV_LL_READ_BACK(&scale->section_ll, section) {
@@ -1406,12 +1400,23 @@ static void scale_find_section_tick_idx(lv_obj_t * obj)
section->first_tick_idx_in_section = tick_idx;
section->first_tick_idx_is_major = is_major_tick;
}
if(section->first_tick_idx_in_section != tick_idx) {
if(LV_SCALE_TICK_IDX_DEFAULT_ID == section->last_tick_idx_in_section) {
/* This gets it initialized when the beginning and ending range values are the same. */
section->last_tick_idx_in_section = tick_idx;
section->last_tick_idx_is_major = is_major_tick;
}
/* Now keep setting the `last_tick_idx_...` values as we
* proceed through the `for` loop so it is left with the
* actual last-tick value that is within the Scale's range. */
else if(section->first_tick_idx_in_section != tick_idx) {
section->last_tick_idx_in_section = tick_idx;
section->last_tick_idx_is_major = is_major_tick;
}
}
else { /* Nothing to do */ }
else {
/* `tick_value` is outside Section's range.
* Nothing to do. */
}
}
}
}
@@ -1537,15 +1542,19 @@ static void scale_store_section_line_tick_width_compensation(lv_obj_t * obj, con
/* Add 1px as adjustment if tmp_width is odd */
if(tmp_width & 0x01U) {
if(LV_SCALE_MODE_VERTICAL_LEFT == scale->mode || LV_SCALE_MODE_VERTICAL_RIGHT == scale->mode) {
tmp_width += 1U;
tmp_width += 1;
}
else {
tmp_width -= 1U;
tmp_width -= 1;
}
}
section->first_tick_in_section_width = tmp_width;
}
else if(tick_idx == section->last_tick_idx_in_section) {
/* This can also apply when
* (tick_idx == section->first_tick_idx_in_section) when the
* beginning and ending vlues of the range are the same. */
if(tick_idx == section->last_tick_idx_in_section) {
if(section->last_tick_idx_is_major) {
tmp_width = major_tick_dsc->width;
}
@@ -1557,10 +1566,10 @@ static void scale_store_section_line_tick_width_compensation(lv_obj_t * obj, con
/* Add 1px as adjustment if tmp_width is odd */
if(tmp_width & 0x01U) {
if(LV_SCALE_MODE_VERTICAL_LEFT == scale->mode || LV_SCALE_MODE_VERTICAL_RIGHT == scale->mode) {
tmp_width -= 1U;
tmp_width -= 1;
}
else {
tmp_width += 1U;
tmp_width += 1;
}
}
section->last_tick_in_section_width = tmp_width;

View File

@@ -160,7 +160,8 @@ void lv_scale_set_image_needle_value(lv_obj_t * obj, lv_obj_t * needle_img, int3
/**
* Set custom text source for major ticks labels
* @param obj pointer to a scale object
* @param txt_src pointer to an array of strings which will be display at major ticks
* @param txt_src pointer to an array of strings which will be display at major ticks;
* last element must be a NULL pointer.
*/
void lv_scale_set_text_src(lv_obj_t * obj, const char * txt_src[]);