1
0
mirror of https://github.com/lvgl/lvgl.git synced 2025-01-14 06:42:58 +08:00

Merge branch 'master' into feat/img-frame-id

This commit is contained in:
Gabor Kiss-Vamosi 2021-05-03 17:43:05 +02:00
commit 418830e831
294 changed files with 9569 additions and 6339 deletions

View File

@ -18,7 +18,9 @@ jobs:
sudo apt-get update -y -qq
sudo apt-get install libsdl2-dev
- name: Clone lv_micropython
run: git clone https://github.com/lvgl/lv_micropython.git .
run: |
git clone https://github.com/lvgl/lv_micropython.git .
git checkout dev-8.0
- name: Update submodules
run: git submodule update --init --recursive
- name: Checkout LVGL submodule

43
.github/workflows/compile_docs.yml vendored Normal file
View File

@ -0,0 +1,43 @@
name: Build docs
on:
push:
branches:
- master
jobs:
build-and-deploy:
if: github.repository == 'lvgl/lvgl'
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v2
with:
persist-credentials: false
fetch-depth: 0
- name: Setup Python
uses: actions/setup-python@v1
with:
python-version: 3.7
- name: Install Doxygen
run: sudo apt-get install doxygen
- name: Install requirements
run: |
pip install --upgrade --upgrade-strategy eager sphinx recommonmark commonmark breathe sphinx-rtd-theme sphinx-markdown-tables sphinx-sitemap
- name: Build docs
run: docs/build.py
- name: Remove .doctrees
run: rm -rf out_html/.doctrees
- name: Retrieve version
run: |
echo "::set-output name=VERSION_NAME::$(scripts/find_version.sh)"
id: version
- name: Deploy
uses: JamesIves/github-pages-deploy-action@3.7.1
with:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
ACCESS_TOKEN: ${{ secrets.LVGL_BOT_TOKEN }}
REPOSITORY_NAME: lvgl/docs_compiled
BRANCH: gh-pages # The branch the action should deploy to.
FOLDER: out_html # The folder the action should deploy.
TARGET_FOLDER: ${{ steps.version.outputs.VERSION_NAME }}
PRESERVE: true
SINGLE_COMMIT: true

5
.gitignore vendored
View File

@ -1,4 +1,3 @@
scripts/release/__pycache__
**/*.o
**/*bin
**/*.swp
@ -7,3 +6,7 @@ tags
docs/api_doc
scripts/cppcheck_res.txt
scripts/built_in_font/lv_font_*
docs/doxygen_html
docs/xml
out_html
__pycache__

View File

@ -1,6 +1,6 @@
# Changelog
## v7.11.0 (Planned for 19.02.2021)
## v7.11.0
### New features
- Add better screen orientation management with software rotation support

View File

@ -5,10 +5,10 @@ This is a summary for thenew fatures of the major releases and a collection of i
This list indicates only the current intention and can be changed.
## v8
Planned to November/December 2020
- Create an `lv_components` repository for compley widgets
Planned to May 2021
- Create an `extra` folder for complex widgets
- It makes the core LVGL leaner
- In `lv_components` we can have a lot and specific widgets
- In `extra` we can have a lot and specific widgets
- Good place for contribution
- New scrolling:
- See [feat/new-scroll](https://github.com/lvgl/lvgl/tree/feat/new-scroll) branch and [#1614](https://github.com/lvgl/lvgl/issues/1614)) issue.
@ -27,7 +27,7 @@ Planned to November/December 2020
- Simplified File system interface ([feat/new_fs_api](https://github.com/lvgl/lvgl/tree/feat/new-fs-api) branch) to make porting easier
- Work in progress
- Remove the align parameter from `lv_canvas_draw_text`
- Make the copy parameter obsolate in create functions
- Remove the copy parameter from create functions
- Optimize and simplifie styles [#1832](https://github.com/lvgl/lvgl/issues/1832)
- Use a more generic inheritenace [#1919](https://github.com/lvgl/lvgl/issues/1919)
@ -37,17 +37,21 @@ Planned to November/December 2020
- Benchmarking (gem5?). See [#1660](https://github.com/lvgl/lvgl/issues/1660)
- chart: pre-delete `X` pint after the lastly set
- chart: autoscroll to the right
- `lv_snapshot`: buffer a widget and all of its children into an image. he source widget can be on a different screen too. The result image can be transformed.
- 9-patch support for `lv_imgbtn`.
- Handle stride. See [#1858](https://github.com/lvgl/lvgl/issues/1858)
- Rework animation to something like [GSAP](https://greensock.com/gsap/)
- Add scroll trigger inspired by [GSAP scrolltrigger](https://greensock.com/scrolltrigger/)
- Add FLIP inspired by [GSAP FLIP](https://greensock.com/docs/v3/Plugins/Flip/)
## v9
- Simplify `group`s. Discussion is [here](https://forum.lvgl.io/t/lv-group-tabindex/2927/3).
- Consider direct binary font format support
- Optimize line and circle drawing and masking
- Reconsider color format management for run time color format setting, and custom color format usage. (Also [RGB888](https://github.com/lvgl/lvgl/issues/1722))
- 9-patch support for `lv_imgbtn`.
- Handle stride. See [#1858](https://github.com/lvgl/lvgl/issues/1858)
- Switch to RGBA colors in styles
- Make gradients more versatile
- Make image transformations more versatile
- Allow snapshoting object to tranfrom them to images
## Ideas
- Use [generate-changelog](https://github.com/lob/generate-changelog) to automatically generate changelog
@ -55,7 +59,6 @@ Planned to November/December 2020
- Text node. See [#1701](https://github.com/lvgl/lvgl/issues/1701#issuecomment-699479408)
- CPP binding. See [Forum](https://forum.lvgl.io/t/is-it-possible-to-officially-support-optional-cpp-api/2736)
- Optimize font decompression
- Switch to RGBA colors in styles
- Need coverage report for tests
- Need static analyze (via coverity.io or somehing else)
- Support dot_begin and dot_middle long modes for labels

45
docs/_ext/lv_example.py Normal file
View File

@ -0,0 +1,45 @@
from docutils.parsers.rst import Directive
from docutils import nodes
from docutils.parsers.rst.directives.images import Image
from sphinx.directives.code import LiteralInclude
import os
class LvExample(Directive):
required_arguments = 3
def run(self):
example_path = self.arguments[0]
example_name = os.path.split(example_path)[1]
node_list = []
env = self.state.document.settings.env
if self.arguments[2] == 'py':
paragraph_node = nodes.raw(text=f"Click to try in the simulator!<br/><a target='_blank' href='https://sim.lvgl.io/v7/micropython/ports/javascript/bundle_out/index.html?script_startup=https://raw.githubusercontent.com/lvgl/lv_examples/{env.config.example_commit_hash}/src/header.py&script=https://raw.githubusercontent.com/lvgl/lv_examples/{env.config.built_example_commit_hash}/{example_name}/{example_name}.py'><img alt='{example_name}' src='https://raw.githubusercontent.com/lvgl/lv_examples/{env.config.built_example_commit_hash}/{example_name}/{example_name}.png'/></a>", format='html')
else:
paragraph_node = nodes.raw(text=f"<iframe class='lv-example' src='../_static/built_lv_examples/{example_name}/?w=320&h=240'></iframe>", format='html')
toggle = nodes.container('', literal_block=False, classes=['toggle'])
header = nodes.container('', literal_block=False, classes=['header'])
toggle.append(header)
example_file = os.path.abspath("lv_examples/src/" + example_path + "." + self.arguments[2])
with open(example_file) as f:
contents = f.read()
literal_list = nodes.literal_block(contents, contents)
literal_list['language'] = self.arguments[2]
toggle.append(literal_list)
header.append(nodes.paragraph(text="code"))
if env.app.tags.has('html'):
node_list.append(paragraph_node)
node_list.append(toggle)
return node_list
def setup(app):
app.add_directive("lv_example", LvExample)
app.add_config_value("example_commit_hash", "", "env")
app.add_config_value("built_example_commit_hash", "", "env")
return {
'version': '0.1',
'parallel_read_safe': True,
'parallel_write_safe': True,
}

58
docs/_static/css/custom.css vendored Normal file
View File

@ -0,0 +1,58 @@
table, th, td {
border: 1px solid #bbb;
padding: 10px;
}
td {
text-align:center;
}
.toggle .header {
display: block;
clear: both;
cursor: pointer;
font-weight: bold;
}
.toggle .header:before {
font-family: FontAwesome, "Lato","proxima-nova","Helvetica Neue",Arial,sans-serif;
content: "\f0da \00a0 Show ";
display: inline-block;
font-size: 1.1em;
}
.toggle .header.open:before {
content: "\f0d7 \00a0 Hide ";
}
.header p {
display: inline-block;
font-size: 1.1em;
margin-bottom: 8px;
}
.wy-side-nav-search {
background-color: #f5f5f5;
}
.wy-side-nav-search>div.version {
color: #333;
}
.home-img {
width:32%;
transition: transform .3s ease-out;
}
.home-img:hover {
transform: translate(0, -10px);
}
.lv-example {
border: none;
outline: none;
padding: none;
display: block;
width: 320px;
height: 240px;
}

5
docs/_static/css/fontawesome.min.css vendored Normal file

File diff suppressed because one or more lines are too long

BIN
docs/_static/img/home_1.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

BIN
docs/_static/img/home_2.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

BIN
docs/_static/img/home_3.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

BIN
docs/_static/img/home_4.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

BIN
docs/_static/img/home_5.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

BIN
docs/_static/img/home_6.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

BIN
docs/_static/img/home_banner.jpg vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 186 KiB

69
docs/build.py Executable file
View File

@ -0,0 +1,69 @@
#!/usr/bin/env python3
import sys
import os
import subprocess
import re
langs = ['en']
# Change to script directory for consistency
abspath = os.path.abspath(__file__)
dname = os.path.dirname(abspath)
os.chdir(dname)
def cmd(s):
print("")
print(s)
print("-------------------------------------")
r = os.system(s)
if r != 0:
print("Exit build due to previous error")
exit(-1)
# Get the current branch name
status, br = subprocess.getstatusoutput("git branch | grep '*'")
br = re.sub('\* ', '', br)
urlpath = re.sub('release/', '', br)
# Be sure the github links point to the right branch
f = open("header.rst", "w")
f.write(".. |github_link_base| replace:: https://github.com/lvgl/docs/blob/" + br)
f.close()
base_html = "html_baseurl = 'https://docs.lvgl.io/" + urlpath + "/en/html/'"
os.system("sed -i \"s|html_baseurl = .*|" + base_html +"|\" conf.py")
clean = 0
trans = 0
args = sys.argv[1:]
if len(args) >= 1:
if "clean" in args: clean = 1
lang = "en"
print("")
print("****************")
print("Building")
print("****************")
if clean:
cmd("rm -rf " + lang)
cmd("mkdir " + lang)
print("Running doxygen")
cmd("cd ../scripts && doxygen Doxyfile")
# BUILD PDF
# Silly workarond to include the more or less correct PDF download link in the PDF
#cmd("cp -f " + lang +"/latex/LVGL.pdf LVGL.pdf | true")
#cmd("sphinx-build -b latex . en/latex")
# Generat PDF
#cmd("cd " + lang + "/latex && xelatex -interaction=batchmode *.tex")
# Copy the result PDF to the main diractory to make it avaiable for the HTML build
#cmd("cd " + lang + "/latex && cp -f LVGL.pdf ../../LVGL.pdf")
# BULD HTML
cmd("sphinx-build -b html . ../out_html")

257
docs/conf.py Normal file
View File

@ -0,0 +1,257 @@
#!/usr/bin/env python3.7
# -*- coding: utf-8 -*-
#
# LVGL documentation build configuration file, created by
# sphinx-quickstart on Wed Jun 12 16:38:40 2019.
#
# This file is execfile()d with the current directory set to its
# containing dir.
#
# Note that not all possible configuration values are present in this
# autogenerated file.
#
# All configuration values have a default; values that are commented out
# serve to show the default.
# If extensions (or modules to document with autodoc) are in another directory,
# add these directories to sys.path here. If the directory is relative to the
# documentation root, use os.path.abspath to make it absolute, like shown here.
#
import os
import sys
import subprocess
sys.path.insert(0, os.path.abspath('./_ext'))
import recommonmark
from recommonmark.transform import AutoStructify
from sphinx.builders.html import StandaloneHTMLBuilder
from subprocess import Popen, PIPE
# -- General configuration ------------------------------------------------
# If your documentation needs a minimal Sphinx version, state it here.
#
# needs_sphinx = '1.0'
# Add any Sphinx extension module names here, as strings. They can be
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
# ones.
extensions = ['sphinx.ext.autodoc',
'sphinx.ext.intersphinx',
'sphinx.ext.todo',
'recommonmark',
'sphinx_markdown_tables',
'breathe',
'sphinx_sitemap',
#'lv_example'
]
# Add any paths that contain templates here, relative to this directory.
templates_path = ['_templates']
# The default language to highlight source code in. The default is 'python'.
# The value should be a valid Pygments lexer name, see Showing code examples for more details.
highlight_language = 'c'
# The suffix(es) of source filenames.
# You can specify multiple suffix as a list of string:
#
source_suffix = ['.rst', '.md']
# The master toctree document.
master_doc = 'index'
# General information about the project.
project = 'LVGL'
copyright = '2020, LVGL LLC'
author = 'The community of LVGL'
# The version info for the project you're documenting, acts as replacement for
# |version| and |release|, also used in various other places throughout the
# built documents.
#
# The short X.Y version.
# embeddedt: extract using scripts/find_version.sh
version = subprocess.run(["../scripts/find_version.sh"], capture_output=True).stdout.decode("utf-8").strip()
# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.
#
# This is also used if you do content translation via gettext catalogs.
# Usually you set "language" from the command line for these cases.
language = None
# List of patterns, relative to source directory, that match files and
# directories to ignore when looking for source files.
# This patterns also effect to html_static_path and html_extra_path
exclude_patterns = ['_build', 'doxygen_html', 'Thumbs.db', '.DS_Store',
'README.md', 'lv_examples', 'out_html' ]
# The name of the Pygments (syntax highlighting) style to use.
pygments_style = 'sphinx'
# If true, `todo` and `todoList` produce output, else they produce nothing.
todo_include_todos = True
# -- Options for HTML output ----------------------------------------------
# The theme to use for HTML and HTML Help pages. See the documentation for
# a list of builtin themes.
#
html_theme = 'sphinx_rtd_theme'
# Theme options are theme-specific and customize the look and feel of a theme
# further. For a list of options available for each theme, see the
# documentation.
#
html_theme_options = {
'collapse_navigation' : False,
'logo_only': True,
}
# For site map generation
html_baseurl = 'https://docs.lvgl.io/master/en/html/'
sitemap_url_scheme = "{link}"
# Add any paths that contain custom static files (such as style sheets) here,
# relative to this directory. They are copied after the builtin static files,
# so a file named "default.css" will overwrite the builtin "default.css".
html_static_path = ['_static']
# Custom sidebar templates, must be a dictionary that maps document names
# to template names.
#
# This is required for the alabaster theme
# refs: http://alabaster.readthedocs.io/en/latest/installation.html#sidebars
html_sidebars = {
'**': [
'relations.html', # needs 'show_related': True theme option to display
'searchbox.html',
]
}
html_favicon = 'favicon.png'
html_logo = 'logo_lvgl.png'
# -- Options for HTMLHelp output ------------------------------------------
# Output file base name for HTML help builder.
htmlhelp_basename = 'LVGLdoc'
html_last_updated_fmt = ''
# -- Options for LaTeX output ---------------------------------------------
latex_elements = {
# The paper size ('letterpaper' or 'a4paper').
#
# 'papersize': 'letterpaper',
# The font size ('10pt', '11pt' or '12pt').
#
# 'pointsize': '10pt',
# Additional stuff for the LaTeX preamble.
#
# 'preamble': '',
# Latex figure (float) alignment
#
# 'figure_align': 'htbp',
'inputenc': '',
'utf8extra': '',
'classoptions': ',openany,oneside',
'preamble': r'''
\usepackage{fontspec}
\setmonofont{DejaVu Sans Mono}
\usepackage{xeCJK}
\setCJKmainfont{SimSun}
\usepackage{silence}
\WarningsOff*
''',
}
# Grouping the document tree into LaTeX files. List of tuples
# (source start file, target name, title,
# author, documentclass [howto, manual, or own class]).
latex_documents = [
(master_doc, 'LVGL.tex', 'LVGL Documentation ' + version,
'Contributors of LVGL', 'manual'),
]
# -- Options for manual page output ---------------------------------------
# One entry per manual page. List of tuples
# (source start file, name, description, authors, manual section).
man_pages = [
(master_doc, 'lvgl', 'LVGL Documentation ' + version,
[author], 1)
]
# -- Options for Texinfo output -------------------------------------------
# Grouping the document tree into Texinfo files. List of tuples
# (source start file, target name, title, author,
# dir menu entry, description, category)
texinfo_documents = [
(master_doc, 'LVGL', 'LVGL Documentation ' + version,
author, 'Contributors of LVGL', 'One line description of project.',
'Miscellaneous'),
]
breathe_projects = {
"lvgl":"xml/",
}
StandaloneHTMLBuilder.supported_image_types = [
'image/svg+xml',
'image/gif', #prefer gif over png
'image/png',
'image/jpeg'
]
smartquotes = False
# Example configuration for intersphinx: refer to the Python standard library.
def setup(app):
app.add_config_value('recommonmark_config', {
'enable_eval_rst': True,
'enable_auto_toc_tree': 'True',
}, True)
app.add_transform(AutoStructify)
app.add_stylesheet('css/custom.css')
app.add_stylesheet('css/fontawesome.min.css')
# Attempt to checkout _static/built_lv_examples
"""
if not os.path.exists('_static/built_lv_examples'):
os.system('git clone https://github.com/lvgl/lv_examples.git _static/built_lv_examples')
os.system('git -C _static/built_lv_examples fetch origin')
out = subprocess.Popen(["git", "-C", "lv_examples", "rev-parse", "HEAD"],
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT)
stdout,stderr = out.communicate()
example_commit_hash = stdout.decode("utf-8").strip()
search_command = ["git", "-C", "_static/built_lv_examples", "--no-pager", "log", "--pretty=format:'%H'", "--all", "-n", "1", f"--grep='Deploying to gh-pages from @ {example_commit_hash}'"]
log_output = subprocess.check_output(' '.join(search_command), shell=True).strip().decode("utf-8")
if len(log_output) == 0:
raise ValueError('lv_examples: cannot find corresponding deployed commit: ' + example_commit_hash)
built_example_commit_hash = log_output
os.system('git -C _static/built_lv_examples reset --hard')
os.system('git -C _static/built_lv_examples checkout ' + log_output)
"""

BIN
docs/favicon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 533 B

View File

@ -117,7 +117,7 @@ lv_obj_set_event_cb(btn, btn_event_cb); /*Assign a callback to t
void btn_event_cb(lv_obj_t * btn, lv_event_t event)
{
if(event == LV_EVENT_CLICKED) {
if(code == LV_EVENT_CLICKED) {
printf("Clicked\n");
}
}
@ -172,36 +172,9 @@ You can select the theme to use in `lv_conf.h`.
## Examples
### Button with label
```eval_rst
.. image:: /lv_examples/src/lv_ex_get_started/lv_ex_get_started_1.*
:alt: Simple button with label with LVGL
.. literalinclude:: /lv_examples/src/lv_ex_get_started/lv_ex_get_started_1.c
:language: c
```
### Styling buttons
```eval_rst
.. image:: /lv_examples/src/lv_ex_get_started/lv_ex_get_started_2.*
:alt: Styling buttons with LVGL
.. literalinclude:: /lv_examples/src/lv_ex_get_started/lv_ex_get_started_2.c
:language: c
```
### Slider and alignment
```eval_rst
.. image:: /lv_examples/src/lv_ex_get_started/lv_ex_get_started_3.*
:alt: Create a slider with LVGL
.. literalinclude:: /lv_examples/src/lv_ex_get_started/lv_ex_get_started_3.c
:language: c
.. include:: ../../examples/get_started/index.rst
```
## Micropython

1
docs/header.rst Normal file
View File

@ -0,0 +1 @@
.. |github_link_base| replace:: https://github.com/lvgl/docs/blob/master

33
docs/index.md Normal file
View File

@ -0,0 +1,33 @@
```eval_rst
.. include:: /header.rst
:github_url: |github_link_base|/index.md
```
# Welcome to the documentation of LVGL!
<img src="_static/img/home_banner.jpg" style="width:100%">
<div style="margin-bottom:48px">
<a href="intro/index.html"><img class="home-img" src="_static/img/home_1.png" alt="Get familiar with the LVGL project"></a>
<a href="get-started/index.html"><img class="home-img" src="_static/img/home_2.png" alt="Learn the basic of LVGL and its usage on various platforms"></a>
<a href="porting/index.html"><img class="home-img" src="_static/img/home_3.png" alt="See how to port LVGL to any platform"></a>
<a href="overview/index.html"><img class="home-img" src="_static/img/home_4.png" alt="Learn the how LVGL works in more detail"></a>
<a href="widgets/index.html"><img class="home-img" src="_static/img/home_5.png" alt="Take a look at the description of the available widgets"></a>
<a href="contributing/index.html"><img class="home-img" src="_static/img/home_6.png" alt="Be part of the development of LVGL"></a>
</div>
```eval_rst
.. toctree::
:maxdepth: 2
intro/index
get-started/index
porting/index
overview/index
widgets/index
layouts/index
contributing/index
```

6
docs/layouts/flex.md Normal file
View File

@ -0,0 +1,6 @@
```eval_rst
.. include:: /header.rst
:github_url: |github_link_base|/layouts/flex.md
```
# Flex

6
docs/layouts/grid.md Normal file
View File

@ -0,0 +1,6 @@
```eval_rst
.. include:: /header.rst
:github_url: |github_link_base|/layouts/grid.md
```
# Grid

15
docs/layouts/index.md Normal file
View File

@ -0,0 +1,15 @@
```eval_rst
.. include:: /header.rst
:github_url: |github_link_base|/layouts/index.md
```
# Layouts
```eval_rst
.. toctree::
:maxdepth: 2
flex
grid
```

BIN
docs/logo_lvgl.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.6 KiB

BIN
docs/misc/boxmodel.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 105 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 86 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 58 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.3 KiB

379
docs/overview/coords.md Normal file
View File

@ -0,0 +1,379 @@
```eval_rst
.. include:: /header.rst
:github_url: |github_link_base|/overview/coords.md
```
# Positions, sizes, and layouts
## Overview
Similarly to many other parts of LVGL, the concept of setting the coordinates were inspired by CSS. It doesn't mean a perfect copy of the standard but parts that are reasonable were adopted in LVGL.
It shorts it means:
- the set coordinates (size, position, layouts, etc) are stored in styles
- support min-width, max-width, min-height, max-height
- have pixel, percentage, and "content" units
- a subset of flexbox and grid layouts are supported by default
### Units
- pixel: Simply a position in pixels. A simple integer always mean pixel. E.g. `lv_obj_set_x(btn, 10)`
- percentage: The percentage of the size of the object or its parent (depending on the property). The `lv_pct(value)` converts a value to percentage. E.g. `lv_obj_set_width(btn, lv_pct(50))`
- `LV_SIZE_CONTENT`: Special value to set the width/height of an object to involve all the children. Its similar to `auto` in CSS. E.g. `lv_obj_set_width(btn, LV_SIZE_CONTENT)`.
### Boxing model
An object's "box" is built from the following parts:
- bounding box: the width/height of the elements.
- padding: space between the sides of the object and its children.
- content: the content area which size if the bounding box reduced by the size of the paddings.
![The box models of LVGL: The content area is smaller then the bounding box with the padding](/misc/boxmodel.png)
The border is drawn inside the bounding box and doesn't take an extra space. (It's different from CSS in which increasing the border width makes the object larger.)
The outline is drawn outside of the bounding box.
### Important notes
This section describes special cases in which LVGL's behavior might look unexpected.
#### Postponed coordinate calculation
LVGL doesn't recalculate all the coordinate changes immediately to improve performance.
Instead, the object's are marked as "dirty" and before redrawing the screen LVGL checks if there are any "dirty" objects. If so it refreshes their position, size and layout.
The following functions set size/position immediately:
- `lv_obj_set_pos/x/y`
- `lv_obj_set_size/width/height`
- `lv_obj_set_content_width/height`
- `lv_obj_align`
- `lv_obj_set_align`
- `lv_obj_align_to`
So if you don't use any complex feature (e.g. layouts) you don't have to worry about postponed layout recalculation.
However, if the coordinates are set by a style or layout the recalculation will be delayed.
In some special cases even if the coordinates are set the by the above listed functions they can be incorrect.
For example if the width of an object is set in the percentage of parent width (e.g. `lv_pct(80)`) and the parent's size is set by a layout the child size might use non-updated size from the parent.
It will be recalculated automatically before the next screen redraw but if you need the final coordinates immediately after changing the coordinates and see incorrect values you need to use
```c
lv_obj_unpdate_layout(obj);
```
As the it can be seen form the above example the sizes and positions might depends on each other, therefore `lv_obj_unpdate_layout(obj)` recalculates the coordinates of all objects on the screen of `obj`.
#### Removing styles
As it's described in the [Using styles](#using-styles) section the coordinates can be set via style properties too.
To be more precise under the hood every style coordinate related property is stored as style a property. If you use `lv_obj_set_x(obj, 20)` LVGL saves `x=20` in the local style of the object.
It's an internal mechanism and doesn't matter much as you use LVGL. However, there is one case in which you need to aware of that. If the style(s) of an object are removed by
```c
lv_obj_remove_style_all(obj)
˙``
or
```c
lv_obj_remove_style(obj, NULL, LV_PART_MAIN);
```
The earlier set coordinates will be removed as well.
For example:
```c
/*The size of obj1 will be set back to the default in the end*/
lv_obj_set_size(obj1, 200, 100); /*Now obj1 has 200;100 size*/
lv_obj_remove_style_all(obj1); /*It removes the set sizes*/
/*obj2 will have 200;100 size in the end */
lv_obj_remove_style_all(obj2);
lv_obj_set_size(obj2, 200, 100);
```
## Position
### Simple way
To simple set the x and y coordinates of an object use
```c
lv_obj_set_x(obj, 10);
lv_obj_set_y(obj, 20);
lv_obj_set_pos(obj, 10, 20); //Or in one function
```
By default the the x and y coordinates are measured from the top left corner of the parent's content area.
For example if the parent has 5 pixel padding on every side, the above code will place `obj` to (15, 25) because the content area starts after the padding.
If percentage values are calculated from the parents content area size.
```c
lv_obj_set_x(btn, lv_pct(10)); //x = 10 % of parant content area width
```
### Align
In some cases it's convenient to change the origin of the positioning from the the default top left. If the the orogin is changed e.g. to bottom-right, the (0,0) position means: align to the bottom-right corner.
To change the origin use:
```c
lv_obj_set_align(obj, align);
```
To change the alignment and set new coordinates:
```c
lv_obj_align(obj, align, x, y);
```
The following alignment options can be used:
- `LV_ALIGN_TOP_LEFT`
- `LV_ALIGN_TOP_MID`
- `LV_ALIGN_TOP_RIGHT`
- `LV_ALIGN_BOTTOM_LEFT`
- `LV_ALIGN_BOTTOM_MID`
- `LV_ALIGN_BOTTOM_RIGHT`
- `LV_ALIGN_LEFT_MID`
- `LV_ALIGN_RIGHT_MID`
- `LV_ALIGN_CENTER`
It quite common to align a children to the center of its parent, there fore is a dedicated function for it:
```c
lv_obj_center(obj);
//Has the same effect
lv_obj_align(obj, LV_ALIGN_CENTER, 0, 0);
```
If the parent's size changes the set alignment and position of the children is applied again automatically.
The functions introduced above aligns the object to its parent. However it's also possible to align an object to an arbitrary object.
```c
lv_obj_align_to(obj_to_align, reference_obj, align, x, y);
```
Besides the alignments options above the following can be used to align the object outside of the reference object:
- `LV_ALIGN_OUT_TOP_LEFT`
- `LV_ALIGN_OUT_TOP_MID`
- `LV_ALIGN_OUT_TOP_RIGHT`
- `LV_ALIGN_OUT_BOTTOM_LEFT`
- `LV_ALIGN_OUT_BOTTOM_MID`
- `LV_ALIGN_OUT_BOTTOM_RIGHT`
- `LV_ALIGN_OUT_LEFT_TOP`
- `LV_ALIGN_OUT_LEFT_MID`
- `LV_ALIGN_OUT_LEFT_BOTTOM`
- `LV_ALIGN_OUT_RIGHT_TOP`
- `LV_ALIGN_OUT_RIGHT_MID`
- `LV_ALIGN_OUT_RIGHT_BOTTOM`
For example to align a label above a button and center the label is horizontally:
```c
lv_obj_align_to(label, btn, LV_ALIGN_OUT_TOP_MID, 0, -10);
```
Not that - unlike with `lv_obj_align()` - `lv_obj_align_to()` can not realign the object if its coordinates or the reference object's coordinates changes.
## Size
### Simple way
The width and the height of an object can be set easily as well:
```c
lv_obj_set_width(obj, 200);
lv_obj_set_height(obj, 100);
lv_obj_set_size(obj, 200, 100); //Or in one function
```
Percentage values aer calculated based on the parent's content area size. For example to set the object's height to the screen height:
```c
lv_obj_set_height(obj, lv_pct(100));
```
Size setting supports a value: `LV_SIZE_CONTENT`. It means the object's size in the respective direction will be set to involve its the children.
Note that only children on the right and bottom will be considered and children o nthe top and left remains cropped. This limitation makes the behavior more predictable.
Object with `LV_OBJ_FLAG_HIDDEN` or `LV_OBJ_FLAG_FLOATING` will be ignored by `LV_SIZE_CONTENT` calculation.
The above functions set the size of the bounding box of the object but the size of the content area can be set as well. It means the object's bounding box will be larger with the paddings than the set size.
```c
lv_obj_set_content_width(obj, 50); //The actual width: padding left + 50 + padding right
lv_obj_set_content_height(obj, 30); //The actual width: padding top + 30 + padding bottom
```
The size of the bounding box and the content area can be get with the following functions:
```c
lv_coord_t w = lv_obj_get_width(obj);
lv_coord_t h = lv_obj_get_height(obj);
lv_coord_t content_w = lv_obj_get_content_width(obj);
lv_coord_t content_h = lv_obj_get_content_height(obj);
```
## Using styles
Under the hood the position, size and alignment properties are style properties.
The above described "simple functions" hide the style related code for the sake of simplicity and set the position, size, and alignment properties in the local styles of the obejct.
However, using styles as to set the coordinates has some great advantages:
- It makes easy to set the width/height/etc for several object together with ease. E.g. all make all the sliders 100x10 pixels sized.
- It also makes possible to modify the values in one place.
- The values can be overwritten by other styles. For example `style_btn` makes the object `100x50` by default but adding `style_full_width` overwrites only the width of the object.
- The object can have different position or size in different state. E.g. 100 px wide in `LV_STATE_DEFAULT` but 120 px in `LV_STATE_PRESSED`.
- Style transitions can be used to make the coordinate changes smooth.
Here are some examples to set an object's size using a style:
```c
static lv_style_t style;
lv_style_init(&style);
lv_style_set_width(&style, 100);
lv_obj_t * btn = lv_btn_create(lv_scr_act());
lv_obj_add_style(btn, &style, LV_PART_MAIN);
```
As you will see below there are some other great features of size and position setting.
However, to keep the LVGL's API lean only the most common coordinate setting features have a "simple" version and the more complex features can be used via styles.
## Translation
Let's say the there are 3 buttons next to each other. Their position is set as described above.
Now you want to move a buttons up a little when it's pressed.
One way to achieve this is setting a new Y coordinate for pressed state:
```c
static lv_style_t style_normal;
lv_style_init(&style_normal);
lv_style_set_y(&style_normal, 100);
static lv_style_t style_pressed;
lv_style_init(&style_pressed);
lv_style_set_y(&style_pressed, 80);
lv_obj_add_style(btn1, &style_normal, LV_STATE_DEFAULT);
lv_obj_add_style(btn1, &style_pressed, LV_STATE_PRESSED);
lv_obj_add_style(btn2, &style_normal, LV_STATE_DEFAULT);
lv_obj_add_style(btn2, &style_pressed, LV_STATE_PRESSED);
lv_obj_add_style(btn3, &style_normal, LV_STATE_DEFAULT);
lv_obj_add_style(btn3, &style_pressed, LV_STATE_PRESSED);
```
It works but it's not really flexible because the pressed coordinate is hard-coded. If the buttons are not at y=100 `style_pressed` won't work as expected. To solve this translations can be used:
```c
static lv_style_t style_normal;
lv_style_init(&style_normal);
lv_style_set_y(&style_normal, 100);
static lv_style_t style_pressed;
lv_style_init(&style_pressed);
lv_style_set_translate_y(&style_pressed, -20);
lv_obj_add_style(btn1, &style_normal, LV_STATE_DEFAULT);
lv_obj_add_style(btn1, &style_pressed, LV_STATE_PRESSED);
lv_obj_add_style(btn2, &style_normal, LV_STATE_DEFAULT);
lv_obj_add_style(btn2, &style_pressed, LV_STATE_PRESSED);
lv_obj_add_style(btn3, &style_normal, LV_STATE_DEFAULT);
lv_obj_add_style(btn3, &style_pressed, LV_STATE_PRESSED);
```
Translation is applied from the current position of the object.
Percentage values can be used in translations as well. The percentage is relative to the size of the object (and not to the size of the parent). For example `lv_pct(50)` will move the object with half of its width/height.
The translations is applied after the layouts are calculated. Therefore, even the layouted objects' position can be translated.
The translation actually moves the object. It means it makes the scrollbars and `LV_SIZE_CONTENT` sized objects react on the position change.
## Transformation
Similarly to the position the size can be changed relative to the current size as well.
The transformed width and height is added on both sides of the object. That is 10 px transformed width makes the object 2x10 pixel wider.
Unlike position translation, the size transformation doesn't make the object "really" larger. In other words scrollbars, layouts, `LV_SIZE_CONTENT` will not consider the transformed size.
Hence size transformation if "only" a visual effect.
This code makes the a button larger when it's pressed:
```c
static lv_style_t style_pressed;
lv_style_init(&style_pressed);
lv_style_set_transform_width(&style_pressed, 10);
lv_style_set_transform_height(&style_pressed, 10);
lv_obj_add_style(btn, &style_pressed, LV_STATE_PRESSED);
```
### Min and Max size
Similarly to CSS, LVGL also support `min-width`, `max-width`, `min-height` and `max-height`. These are limits preventing an object's size to be smaller/larger then these values.
They are especially useful if the size is set by percentage or `LV_SIZE_CONTENT`.
```c
static lv_style_t style_max_height;
lv_style_init(&style_max_height);
lv_style_set_y(&style_max_height, 200);
lv_obj_set_height(obj, lv_pct(100));
lv_obj_add_style(obj, &style_max_height, LV_STATE_DEFAULT); //Limit the height to 200 px
```
Percentage values can be used as well which are relative to the size of the parent's content area size.
```c
static lv_style_t style_max_height;
lv_style_init(&style_max_height);
lv_style_set_y(&style_max_height, lv_pct(50));
lv_obj_set_height(obj, lv_pct(100));
lv_obj_add_style(obj, &style_max_height, LV_STATE_DEFAULT); //Limit the height to half parent height
```
## Layout
### Overview
Layouts can update the position and size of an object's children. They can be used to automatically arrange the children into a line or column, or in much more complicated forms.
The position and size set by the layout overwrites the "normal" x, y, width, and height settings.
There is only one function that is the same for every layout: `lv_obj_set_layout(obj, <LAYOUT_NAME>)` sets the layout on an object.
For the further settings of the parent and children see the documentations of the given layout.
### Built-in layout
LVGL comes with two very powerful layouts:
- Flexbox
- Grid
Both are heavily inspired by the CSS layouts with the same name.
### Flags
There are some flags that can be used on object to affect how they behave with layouts:
- `LV_OBJ_FLAG_HIDDEN` Hidden object are ignored from layout calculations.
- `LV_OBJ_FLAG_IGNORE_LAYOUT` The object is simply ignored by the layouts. Its coordinates can be set as usual.
- `LV_OBJ_FLAG_FLOATING` Same as `LV_OBJ_FLAG_IGNORE_LAYOUT` but the object with `LV_OBJ_FLAG_FLOATING` will be ignored from `LV_SIZE_CONTENT` calculations.
These flags can be added/removed with `lv_obj_add/clear_flag(obj, FLAG);`
### Adding new layouts
LVGL can be freely extended by a custom layouts like this:
```c
uint32_t MY_LAYOUT;
...
MY_LAYOUT = lv_layout_register(my_layout_update, &user_data);
...
void my_layout_update(lv_obj_t * obj, void * user_data)
{
/*Will be called automatically if required to reposition/resize the children of "obj" */
}
```
Custom style properties can be added too that can be get and used in the update callback. For example:
```c
uint32_t MY_PROP;
...
LV_STYLE_MY_PROP = lv_style_register_prop();
...
static inline void lv_style_set_my_prop(lv_style_t * style, uint32_t value)
{
lv_style_value_t v = {
.num = (int32_t)value
};
lv_style_set_prop(style, LV_STYLE_MY_PROP, v);
}
```
## Examples

View File

@ -12,58 +12,34 @@ Events are triggered in LVGL when something happens which might be interesting t
## Add events to the object
The user can assign callback functions to an object to see these events. In practice, it looks like this:
The user can assign callback functions to an object to see its events. In practice, it looks like this:
```c
lv_obj_t * btn = lv_btn_create(lv_scr_act());
lv_obj_add_event_cb(btn, my_event_cb, NULL); /*Assign an event callback*/
lv_obj_add_event_cb(btn, my_event_cb, LV_EVENT_CLICKED, NULL); /*Assign an event callback*/
...
static void my_event_cb(lv_obj_t * obj, lv_event_t event)
static void my_event_cb(lv_event_t * event)
{
switch(event) {
case LV_EVENT_PRESSED:
printf("Pressed\n");
break;
case LV_EVENT_SHORT_CLICKED:
printf("Short clicked\n");
break;
case LV_EVENT_CLICKED:
printf("Clicked\n");
break;
case LV_EVENT_LONG_PRESSED:
printf("Long press\n");
break;
case LV_EVENT_LONG_PRESSED_REPEAT:
printf("Long press repeat\n");
break;
case LV_EVENT_RELEASED:
printf("Released\n");
break;
}
/*Etc.*/
printf("Clicked\n");
}
```
In the example `LV_EVENT_CLICKED` means that only the click event will call `my_event_cb`. See the [list of event codes](#event-codes) for all the options.
`LV_EVENT_ALL` can be used to receive all the events.
The last parameter of `lv_obj_add_event_cb` is a pointer to any custom data that will be available in the event. It will be described later in more detail.
More events can be added to an object, like this:
```c
lv_obj_add_event_cb(obj, my_event_cb_1, NULL);
lv_obj_add_event_cb(obj, my_event_cb_2, NULL);
lv_obj_add_event_cb(obj, my_event_cb_3, NULL);
lv_obj_add_event_cb(obj, my_event_cb_1, LV_EVENT_CLICKED, NULL);
lv_obj_add_event_cb(obj, my_event_cb_2, LV_EVENT_PRESSED, NULL);
lv_obj_add_event_cb(obj, my_event_cb_3, LV_EVENT_ALL, NULL); /*No filtering, receive all events*/
```
Even the same event callback can be used on an object with different `user_data`. For example:
```c
lv_obj_add_event_cb(obj, increment_on_click, &num1);
lv_obj_add_event_cb(obj, increment_on_click, &num2);
lv_obj_add_event_cb(obj, increment_on_click, LV_EVENT_CLICKED, &num1);
lv_obj_add_event_cb(obj, increment_on_click, LV_EVENT_CLICKED, &num2);
```
The events will be called in the order as they were added.
@ -74,7 +50,7 @@ More objects can use the same *event callback*.
## Remove event(s) from an object
Events can be removed fro man object with the `lv_obj_remove_event_cb(obj, event_cb, user_data)` function. If `user_data = NULL` the first matching `event_cb` will be removed regardless its `user_data`.
Events can be removed from an object with the `lv_obj_remove_event_cb(obj, event_cb)` function or `lv_obj_remove_event_dsc(obj, event_dsc)`. `event_dsc` is a pointer returned by `lv_obj_add_event_cb`.
## Event codes
@ -87,11 +63,11 @@ The event codes can be grouped into these categories:
All objects (such as Buttons/Labels/Sliders etc.) regardless their type receive the *Input device*, *Drawing* and *Other* events.
However the *Special events* are specific to a particular object type. See the [widgets' documentation](/widgets/index) to learn when they are sent,
However the *Special events* are specific to a particular widget type. See the [widgets' documentation](/widgets/index) to learn when they are sent,
*Custom events* are added by the user and therefore these are never sent by LVGL
*Custom events* are added by the user and therefore these are never sent by LVGL.
The following event types exist:
The following event codes exist:
### Input device events
- `LV_EVENT_PRESSED` The object has been pressed
@ -122,8 +98,8 @@ The following event types exist:
- `LV_EVENT_DRAW_POST_BEGIN` Starting the post draw phase (when all children are drawn)
- `LV_EVENT_DRAW_POST` Perform the post draw phase (when all children are drawn)
- `LV_EVENT_DRAW_POST_END` Finishing the post draw phase (when all children are drawn)
- `LV_EVENT_DRAW_PART_BEGIN` Starting to draw a part. The event parameter is `lv_obj_draw_dsc_t *`.
- `LV_EVENT_DRAW_PART_END` Finishing to draw a part. The event parameter is `lv_obj_draw_dsc_t *`.
- `LV_EVENT_DRAW_PART_BEGIN` Starting to draw a part. The event parameter is `lv_obj_draw_dsc_t *`. Learn more [here](/overview/drawing).
- `LV_EVENT_DRAW_PART_END` Finishing to draw a part. The event parameter is `lv_obj_draw_dsc_t *`. Learn more [here](/overview/drawing).
### Other events
- `LV_EVENT_DELETE` Object is being deleted
@ -142,18 +118,13 @@ The following event types exist:
### Custom events
Any custom event can be added from `_LV_EVENT_LAST`. For example:
```c
#define MY_EVENT_1 (_LV_EVENT_LAST + 0)
#define MY_EVENT_2 (_LV_EVENT_LAST + 1)
#define MY_EVENT_3 (_LV_EVENT_LAST + 2)
```
Any custom event codes can be registered by `uint32_t MY_EVENT_1 = lv_event_register_id();`
And can be sent to any object with `lv_event_send(obj, MY_EVENT_1, &some_data)`
## Sending events
To manually send events to an object, use `lv_event_send(obj, LV_EVENT_..., &some_data)`.
To manually send events to an object, use `lv_event_send(obj, <EVENT_CODE> &some_data)`.
For example, it can be used to manually close a message box by simulating a button press (although there are simpler ways of doing this):
```c
@ -170,19 +141,19 @@ lv_event_send(mbox, LV_EVENT_VALUE_CHANGED, &btn_id);
- enable a button if some conditions are met (e.g. the correct PIN is entered)
- add/remove styles to/from an object if a limit is exceeded, etc
## Fields of lv_event_t
## User data and event parameter
There are 2 custom pointer that are available in the events:
- `user_data`: set when the event is registered.
- `event_param`: set when the event is sent in `lv_event_send`
In any event callback these pointer can be get with `lv_event_get_user_data()` and `lv_event_get_param()`.
`lv_event_t` is the only parameter passed to event callback and it contains all the data about the event. The following values can be get from it:
- `lv_event_get_code(e)` get the event code
- `lv_event_get_target(e)` get the object to which the event is sent
- `lv_event_get_original_target(e)` get the object to which the event is sent originally sent (different from `lv_event_get_target` if [event bubbling](event-bubbling) is enabled)
- `lv_event_get_user_data(e)` get the pointer passed as the last parameter of `lv_obj_add_event_cb`.
- `lv_event_get_param(e)` get the parameter passed as the last parameter of `lv_event_send`
## Event bubbling
If `lv_obj_add_flag(obj, LV_OBJ_FLAG_EVENT_BUBBLE)` is enabled all events will be sent to the object's parent too. If the parent also has `LV_OBJ_FLAG_EVENT_BUBBLE` enabled the event will be sent to its parent too, and so on.
The `lv_obj_t * obj` argument of the event handler is always the current target object, not the original object. To get the original target call `lv_event_get_original_target()` in the event handler.
The *target* parameter of the event is always the current target object, not the original object. To get the original target call `lv_event_get_original_target(e)` in the event handler.

View File

@ -319,24 +319,6 @@ To do this, use `lv_img_cache_invalidate_src(&my_png)`. If `NULL` is passed as a
## API
### Image decoder
```eval_rst
.. doxygenfile:: lv_img_decoder.h
:project: lvgl
```
### Image cache
```eval_rst
.. doxygenfile:: lv_img_cache.h
:project: lvgl
```
### Image buffer
@ -346,12 +328,3 @@ To do this, use `lv_img_cache_invalidate_src(&my_png)`. If `NULL` is passed as a
:project: lvgl
```
### Image draw
```eval_rst
.. doxygenfile:: lv_draw_img.h
:project: lvgl
```

View File

@ -40,8 +40,8 @@ You can fully control the user interface without touchpad or mouse using a keypa
The objects, you want to control with keypad or encoder, needs to be added to a *Group*.
In every group, there is exactly one focused object which receives the pressed keys or the encoder actions.
For example, if a [Text area](/widgets/textarea) is focused and you press some letter on a keyboard, the keys will be sent and inserted into the text area.
Similarly, if a [Slider](/widgets/slider) is focused and you press the left or right arrows, the slider's value will be changed.
For example, if a [Text area](/widgets/core/textarea) is focused and you press some letter on a keyboard, the keys will be sent and inserted into the text area.
Similarly, if a [Slider](/widgets/core/slider) is focused and you press the left or right arrows, the slider's value will be changed.
You need to associate an input device with a group. An input device can send the keys to only one group but, a group can receive data from more than one input device too.
@ -58,11 +58,11 @@ There are some predefined keys which have special meaning:
- **LV_KEY_DOWN** Decrease value or move downwards
- **LV_KEY_RIGHT** Increase value or move the the right
- **LV_KEY_LEFT** Decrease value or move the the left
- **LV_KEY_ESC** Close or exit (E.g. close a [Drop down list](/widgets/dropdown))
- **LV_KEY_DEL** Delete (E.g. a character on the right in a [Text area](/widgets/textarea))
- **LV_KEY_BACKSPACE** Delete a character on the left (E.g. in a [Text area](/widgets/textarea))
- **LV_KEY_HOME** Go to the beginning/top (E.g. in a [Text area](/widgets/textarea))
- **LV_KEY_END** Go to the end (E.g. in a [Text area](/widgets/textarea)))
- **LV_KEY_ESC** Close or exit (E.g. close a [Drop down list](/widgets/core/dropdown))
- **LV_KEY_DEL** Delete (E.g. a character on the right in a [Text area](/widgets/core/textarea))
- **LV_KEY_BACKSPACE** Delete a character on the left (E.g. in a [Text area](/widgets/core/textarea))
- **LV_KEY_HOME** Go to the beginning/top (E.g. in a [Text area](/widgets/core/textarea))
- **LV_KEY_END** Go to the end (E.g. in a [Text area](/widgets/core/textarea)))
The most important special keys are `LV_KEY_NEXT/PREV`, `LV_KEY_ENTER` and `LV_KEY_UP/DOWN/LEFT/RIGHT`.
In your `read_cb` function, you should translate some of your keys to these special keys to navigate in the group and interact with the selected object.
@ -80,7 +80,7 @@ Pressing `LV_KEY_ENTER` will change to *Edit* mode.
In *Edit* mode, `LV_KEY_NEXT/PREV` is usually used to edit the object.
Depending on the object's type, a short or long press of `LV_KEY_ENTER` changes back to *Navigate* mode.
Usually, an object which can not be pressed (like a [Slider](/widgets/slider)) leaves *Edit* mode on short click. But with objects where short click has meaning (e.g. [Button](/widgets/btn)), a long press is required.
Usually, an object which can not be pressed (like a [Slider](/widgets/core/slider)) leaves *Edit* mode on short click. But with objects where short click has meaning (e.g. [Button](/widgets/core/btn)), a long press is required.
### Styling

View File

@ -12,16 +12,19 @@
:maxdepth: 2
object
coords
style
scroll
layer
event
style
indev
display
font
image
file-system
animation
task
timer
drawing
new_widget
```

View File

@ -0,0 +1,7 @@
```eval_rst
.. include:: /header.rst
:github_url: |github_link_base|/overview/new_widget.md
```
# New widget

View File

@ -5,10 +5,12 @@
# Objects
In the LVGL the **basic building blocks** of a user interface are the objects, also called *Widgets*.
For example a [Button](/widgets/btn), [Label](/widgets/label), [Image](/widgets/img), [List](/widgets/list), [Chart](/widgets/chart) or [Text area](/widgets/textarea).
For example a [Button](/widgets/core/btn), [Label](/widgets/core/label), [Image](/widgets/core/img), [List](/widgets/core/list), [Chart](/widgets/extra/chart) or [Text area](/widgets/core/textarea).
Check all the [Object types](/widgets/index) here.
All objects are referenced using an `lv_obj_t` pointer as a handle. This pointer can later be used to set or get the attributes of the object.
## Attributes
### Basic attributes
@ -17,59 +19,56 @@ All object types share some basic attributes:
- Position
- Size
- Parent
- Drag enable
- Click enable etc.
- Styles
- Event handlers
- Etc
You can set/get these attributes with `lv_obj_set_...` and `lv_obj_get_...` functions. For example:
```c
/*Set basic object attributes*/
lv_obj_set_size(btn1, 100, 50); /*Button size*/
lv_obj_set_pos(btn1, 20,30); /*Button position*/
lv_obj_set_size(btn1, 100, 50); /*Set a button's size*/
lv_obj_set_pos(btn1, 20,30); /*Set a button's position*/
```
To see all the available functions visit the Base object's [documentation](/widgets/obj).
To see all the available functions visit the [Base object's documentation](/widgets/obj).
### Specific attributes
The object types have special attributes too. For example, a slider has
- Min. max. values
- Minimum and maximum values
- Current value
- Custom styles
For these attributes, every object type have unique API functions. For example for a slider:
```c
/*Set slider specific attributes*/
lv_slider_set_range(slider1, 0, 100); /*Set min. and max. values*/
lv_slider_set_value(slider1, 40, LV_ANIM_ON); /*Set the current value (position)*/
lv_slider_set_action(slider1, my_action); /*Set a callback function*/
lv_slider_set_range(slider1, 0, 100); /*Set the min. and max. values*/
lv_slider_set_value(slider1, 40, LV_ANIM_ON); /*Set the current value (position)*/
```
The API of the object types are described in their [Documentation](/widgets/index) but you can also check the respective header files (e.g. *lv_objx/lv_slider.h*)
The API of the widgets is described in their [Documentation](/widgets/index) but you can also check the respective header files (e.g. *widgets/lv_slider.h*)
## Working mechanisms
### Parent-child structure
A parent object can be considered as the container of its children. Every object has exactly one parent object (except screens), but a parent can have an unlimited number of children.
A parent object can be considered as the container of its children. Every object has exactly one parent object (except screens), but a parent can have any number of children.
There is no limitation for the type of the parent but, there are typical parent (e.g. button) and typical child (e.g. label) objects.
### Moving together
If the position of the parent is changed the children will move with the parent.
If the position of the parent changes the children will move with the parent.
Therefore all positions are relative to the parent.
The (0;0) coordinates mean the objects will remain in the top left-hand corner of the parent independently from the position of the parent.
![](/misc/par_child1.png "Objects are moving together 1")
```c
lv_obj_t * par = lv_obj_create(lv_scr_act(), NULL); /*Create a parent object on the current screen*/
lv_obj_set_size(par, 100, 80); /*Set the size of the parent*/
lv_obj_t * parent = lv_obj_create(lv_scr_act()); /*Create a parent object on the current screen*/
lv_obj_set_size(parent, 100, 80); /*Set the size of the parent*/
lv_obj_t * obj1 = lv_obj_create(par, NULL); /*Create an object on the previously created parent object*/
lv_obj_set_pos(obj1, 10, 10); /*Set the position of the new object*/
lv_obj_t * obj1 = lv_obj_create(parent); /*Create an object on the previously created parent object*/
lv_obj_set_pos(obj1, 10, 10); /*Set the position of the new object*/
```
Modify the position of the parent:
@ -77,7 +76,7 @@ Modify the position of the parent:
![](/misc/par_child2.png "Graphical objects are moving together 2")
```c
lv_obj_set_pos(par, 50, 50); /*Move the parent. The child will move with it.*/
lv_obj_set_pos(parent, 50, 50); /*Move the parent. The child will move with it.*/
```
(For simplicity the adjusting of colors of the objects is not shown in the example.)
@ -89,28 +88,27 @@ If a child is partially or fully out of its parent then the parts outside will n
![](/misc/par_child3.png "A graphical object is visible on its parent")
```c
lv_obj_set_x(obj1, -30); /*Move the child a little bit of the parent*/
lv_obj_set_x(obj1, -30); /*Move the child a little bit off the parent*/
```
### Create - delete objects
### Create and delete objects
In LVGL objects can be created and deleted dynamically in run-time.
It means only the currently created objects consume RAM.
For example, if you need a chart, you can create it when required and delete it when it is not visible or necessary.
In LVGL objects can be created and deleted dynamically in run time. It means only the currently created (existing) objects consume RAM.
Every object type has its own **create** function with a unified prototype.
It needs two parameters:
- A pointer to the *parent* object. To create a screen give *NULL* as parent.
- Optionally, a pointer to *copy* object with the same type to copy it. This *copy* object can be *NULL* to avoid the copy operation.
All objects are referenced in C code using an `lv_obj_t` pointer as a handle. This pointer can later be used to set or get the attributes of the object.
The create functions look like this:
It allows to create a screen just when a button is clicked to open it. A delete the screen when a new screen is loaded.
Or the UI can be created based on the current environment of the device. For example create meter, charts, bars, slider etc according to the currently attached sensors.
Every widget has its own **create** function with a prototype like this:
```c
lv_obj_t * lv_ <type>_create(lv_obj_t * parent, lv_obj_t * copy);
lv_obj_t * lv_<widget>_create(lv_obj_t * parent, <other paramaters if any>);
```
In most of the cases the create functions have only a *parent* parameter that tells on which object create the new widget.
The return value is a pointer to the created object with `lv_obj_t *` type.
There is a common **delete** function for all object types. It deletes the object and all of its children.
```c
@ -118,27 +116,24 @@ void lv_obj_del(lv_obj_t * obj);
```
`lv_obj_del` will delete the object immediately.
If for any reason you can't delete the object immediately you can use `lv_obj_del_async(obj)`.
If for any reason you can't delete the object immediately you can use `lv_obj_del_async(obj)` that will perefome the deletion on hte next call of `lv_timer_handler()`.
It is useful e.g. if you want to delete the parent of an object in the child's `LV_EVENT_DELETE` signal.
You can remove all the children of an object (but not the object itself) using `lv_obj_clean`:
You can remove all the children of an object (but not the object itself) using `lv_obj_clean(obj)`.
```c
void lv_obj_clean(lv_obj_t * obj);
```
## Screens
### Create screens
The screens are special objects which have no parent object. So they can be created like:
```c
lv_obj_t * scr1 = lv_obj_create(NULL, NULL);
lv_obj_t * scr1 = lv_obj_create(NULL);
```
Screens can be created with any object type. For example, a [Base object](/widgets/obj) or an image to make a wallpaper.
### Get the active screen
There is always an active screen on each display. By default, the library creates and loads a "Base object" as a screen for each display.
There is always an active screen on each display. By default, the library creates and loads a "Base object" as a screen for each display.
To get the currently active screen use the `lv_scr_act()` function.
@ -146,12 +141,25 @@ To get the currently active screen use the `lv_scr_act()` function.
To load a new screen, use `lv_scr_load(scr1)`.
### Layers
There are two automatically generated layers:
- top layer
- system layer
They are independent of the screens and they will be shown on every screen. The *top layer* is above every object on the screen and the *system layer* is above the *top layer* too.
You can add any pop-up windows to the *top layer* freely. But, the *system layer* is restricted to system-level things (e.g. mouse cursor will be placed here in `lv_indev_set_cursor()`).
The `lv_layer_top()` and `lv_layer_sys()` functions gives a pointer to the top or system layer.
Read the [Layer overview](/overview/layer) section to learn more about layers.
#### Load screen with animation
A new screen can be loaded with animation too using `lv_scr_load_anim(scr, transition_type, time, delay, auto_del)`. The following transition types exist:
- `LV_SCR_LOAD_ANIM_NONE`: switch immediately after `delay` ms
- `LV_SCR_LOAD_ANIM_OVER_LEFT/RIGHT/TOP/BOTTOM` move the new screen over the other towards the given direction
- `LV_SCR_LOAD_ANIM_MOVE_LEFT/RIGHT/TOP/BOTTOM` move both the old and new screens towards the given direction
- `LV_SCR_LOAD_ANIM_NONE`: switch immediately after `delay` milliseconds
- `LV_SCR_LOAD_ANIM_OVER_LEFT/RIGHT/TOP/BOTTOM` move the new screen over the current towards the given direction
- `LV_SCR_LOAD_ANIM_MOVE_LEFT/RIGHT/TOP/BOTTOM` move both the current and new screens towards the given direction
- `LV_SCR_LOAD_ANIM_FADE_ON` fade the new screen over the old screen
Setting `auto_del` to `true` will automatically delete the old screen when the animation is finished.
@ -168,28 +176,43 @@ Visit [Multi-display support](/overview/display) to learn more.
## Parts
The widgets can have multiple parts. For example a [Button](/widgets/btn) has only a main part but a [Slider](/widgets/slider) is built from a background, an indicator and a knob.
The widgets are built from multiple parts. For example a [Base object](/widgets/obj) uses the main and scroll bar parts but a [Slider](/widgets/core/slider) uses the main, the indicator and the knob parts.
Parts are similar to *pseudo elements* in CSS.
The name of the parts is constructed like `LV_ + <TYPE> _PART_ <NAME>`. For example `LV_BTN_PART_MAIN` or `LV_SLIDER_PART_KNOB`. The parts are usually used when styles are add to the objects.
Using parts different styles can be assigned to the different parts of the objects.
To learn more about the parts read the related section of the [Style overview](/overview/style#parts).
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 the value*/
- `LV_PART_SELECTED` Indicate the currently selected option or section
- `LV_PART_ITEMS` Used if the widget has multiple similar elements (e.g. tabel cells)*/
- `LV_PART_TICKS` Ticks on scales e.g. for a chart or meter
- `LV_PART_CURSOR` Mark a specific place e.g. text area's or chart's cursor
- `LV_PART_CUSTOM_FIRST` Custom parts can be added from here.
The main purpose of parts to allow styling the "components" of the widgets.
Therefore the parts are described in more detail in the [Style overview](/overview/style) section.
## States
The object can be in a combinations of the following states:
- **LV_STATE_DEFAULT** Normal, released
- **LV_STATE_CHECKED** Toggled or checked
- **LV_STATE_FOCUSED** Focused via keypad or encoder or clicked via touchpad/mouse
- **LV_STATE_EDITED**  Edit by an encoder
- **LV_STATE_HOVERED** Hovered by mouse (not supported now)
- **LV_STATE_PRESSED** Pressed
- **LV_STATE_DISABLED** Disabled or inactive
- `LV_STATE_DEFAULT` Normal, released state
- `LV_STATE_CHECKED` Toggled or checked state
- `LV_STATE_FOCUSED` Focused via keypad or encoder or clicked via touchpad/mouse
- `LV_STATE_FOCUS_KEY` Focused via keypad or encoder but not via touchpad/mouse
- `LV_STATE_EDITED` Edit by an encoder
- `LV_STATE_HOVERED` Hovered by mouse (not supported now)
- `LV_STATE_PRESSED` Being pressed
- `LV_STATE_SCROLLED` Being scrolled
- `LV_STATE_DISABLED` Disabled state
- `LV_STATE_USER_1` Custom state
- `LV_STATE_USER_2` Custom state
- `LV_STATE_USER_3` Custom state
- `LV_STATE_USER_4` Custom state
The states are usually automatically changed by the library as the user presses, releases, focuses etc an object.
However, the states can be changed manually too. To completely overwrite the current state use `lv_obj_set_state(obj, part, LV_STATE...)`.
To set or clear given state (but leave to other states untouched) use `lv_obj_add/clear_state(obj, part, LV_STATE_...)`
In both cases ORed state values can be used as well. E.g. `lv_obj_set_state(obj, part, LV_STATE_PRESSED | LV_PRESSED_CHECKED)`.
However, the states can be changed manually too.
To set or clear given state (but leave the other states untouched) use `lv_obj_add/clear_state(obj, LV_STATE_...)`
In both cases ORed state values can be used as well. E.g. `lv_obj_add_state(obj, part, LV_STATE_PRESSED | LV_PRESSED_CHECKED)`.
To learn more about the states read the related section of the [Style overview](/overview/style#states).
To learn more about the states read the related section of the [Style overview](/overview/style).

163
docs/overview/scroll.md Normal file
View File

@ -0,0 +1,163 @@
```eval_rst
.. include:: /header.rst
:github_url: |github_link_base|/overview/scroll.md
```
# Scroll
## Overview
In LVGL scrolling works very intuitively: if an object is out of its parent content area (the size without paddings), the parent becomes scrollable and scrollbar(s) will appear. That's it.
Any object can be scrollable including `lv_obj_t`, `lv_img`, `lv_btn`, `lv_meter`, etc
The obejct can be scrolled either horizontally or vertically at a time, that is diagonal scrolling is not possible.
### Scrollbar
#### Mode
The scrollbars are displayed according to the set `mode`. The following `mode`s exist:
- `LV_SCROLLBAR_MODE_OFF` Never show the scrollbars
- `LV_SCROLLBAR_MODE_ON` Always show the scrollbars
- `LV_SCROLLBAR_MODE_ACTIVE` Show scroll bars while object is being scrolled
- `LV_SCROLLBAR_MODE_AUTO` Show scroll bars when the content is large enough to be scrolled
`lv_obj_set_scrollbar_mode(obj, LV_SCROLLBAR_MODE_...)` set the scrollbar mode on an object.
#### Styling
The scrollbars have its own dedicated part, called `LV_PART_SCROLLBAR`. For example a scrollbar can turned to red like this:
```c
static lv_style_t style_red;
lv_style_init(&style_red);
lv_style_set_bg_color(&style_red, lv_color_red());
...
lv_obj_add_style(obj, &style_red, LV_PART_SCROLLBAR);
```
The object goes to `LV_STATE_SCROLLED` state while it's being scrolled. It allows adding different style to the scrollbar or the object itself when scrolled.
This code makes the scrollbar blue when the object is scrolled:
```c
static lv_style_t style_blue;
lv_style_init(&style_blue);
lv_style_set_bg_color(&style_red, lv_color_blue());
...
lv_obj_add_style(obj, &style_blue, LV_STATE_SCROLLED | LV_PART_SCROLLBAR);
```
### Events
The following events are related to scrolling:
- `LV_EVENT_SCROLL_BEGIN` Scrolling begins
- `LV_EVENT_SCROLL_END` Scrolling ends
- `LV_EVENT_SCROLL` Scroll happened. Triggered on every position change.
Scroll events
## Basic example
TODO
## Features of scrolling
Besides managing "normal" scrolling there are many interesting and useful additional features too.
### Scrollable
It's possible to make an object non-scrollable with `lv_obj_add_flag(obj, LV_OBJ_FLAG_SCROLLABLE)`.
Non-scrollable object can still propagate the scrolling (chain) to the parents.
The direction in which scrolling can happen can be controlled by `lv_obj_set_scroll_dir(obj, LV_DIR_...)`.
The following values are possible for the direction:
- `LV_DIR_TOP` only scroll up
- `LV_DIR_LEFT` only scroll left
- `LV_DIR_BOTTOM` only scroll down
- `LV_DIR_RIGHT` only scroll right
- `LV_DIR_HOR` only scroll horizontally
- `LV_DIR_TOP` only scroll vertically
- `LV_DIR_ALL` scroll any directions
OR-ed values are also possible. E.g. `LV_DIR_TOP | LV_DIR_LEFT`.
### Scroll chain
If an object can't be scrolled further (e.g. it's content has reached the bottom most position) the scrolling is propagated to it's parent. If the parent an be scrolled in that direction than it will be scrolled instead.
It goes to the grad parent and grand grandparents too.
The propagation on scrolling in called "scroll chaining" and it can be enabled/disabled with the `LV_OBJ_FLAG_SCROLL_CHAIN` flag.
If chaining is disabled the propagation stops on the object and the parent(s) won't be scrolled.
### Scroll momentum
When the user scrolls an object and releases it LVGL can emulate a momentum for the scrolling. It's like to object were thrown and the scrolling slows down smoothly.
The scroll momentum can be enabled/disabled with the `LV_OBJ_FLAG_SCROLL_MOMENTUM` flag.
### Elastic scroll
Normally the content can't be scrolled inside the object. That is the top side of the content can't be below the top side of the object.
However, with `LV_OBJ_FLAG_SCROLL_ELASTIC` a fancy effect can be added when the user "over-scrolls" the content. The scrolling slows down, and the content can be scrolled inside the object.
When the object is releases the content is scrolled in it will be animated back to the valid position.
### Snaping
The children of an object can be snapped according to specific rules when scrolling ends. Children can be made snapable individually with the `LV_OBJ_FLAG_SNAPABLE` flag.
The object can align the snapped children in 4 ways:
- `LV_SCROLL_SNAP_NONE` Snapping is disabled. (default)
- `LV_SCROLL_SNAP_START` Align the children to the left/top side of the scrolled object
- `LV_SCROLL_SNAP_END` Align the children to the right/bottom side of the scrolled object
- `LV_SCROLL_SNAP_CENTER` Align the children to the center of the scrolled object
The alignment can be set with `lv_obj_set_scroll_snap_x/y(obj, LV_SCROLL_SNAP_...)`:
Under the hood the followings happen
1. User scrolls an object and releases the screen
2. LVGL calculates where would the scroll end considering scroll momentum
3. LVGL finds the nearest scroll point
4. LVGL scrolls the snap point with an animation
### Scroll one
The "scroll one" feature tells LVGL to allow scrolling only one snapable children at a time.
So it requires to make the children snapable and and set a scroll snap alignment different from `LV_SCROLL_SNAP_NONE`.
This feature can be enabled by the `LV_OBJ_FLAG_SCROLL_ONE` flag.
### Scroll on focus
Imagine that there a lot of objects in a group that are on scrollable object. Pressing the "Tab" button focuses the next object but it might be out of the visible area of the scrollable object.
If the "scroll on focus" features is enabled LVGL will automatically scroll to the objects to bring the children into the view.
The scrolling happens recursively therefore even nested scrollable object are handled properly.
The object will be scrolled to the view even if it's on a different page of a tabview.
## Scroll manually
The following API functions allow to manually scroll objects:
- `lv_obj_scroll_by(obj, x, y, LV_ANIM_ON/OFF)` scroll by `x` and `y` values
- `lv_obj_scroll_to(obj, x, y, LV_ANIM_ON/OFF)` scroll to bring the given coordinate to the top left corner
- `lv_obj_scroll_to_x(obj, x, LV_ANIM_ON/OFF)` scroll to bring the given coordinate to the left side
- `lv_obj_scroll_to_y(obj, y, LV_ANIM_ON/OFF)` scroll to bring the given coordinate to the left side
## Self size
Self size is a property of an object. Normally, the user shouldn't use this parameter but if a custom widget is created it might be useful.
In short, self size tell the size of the content. To understand it better take the example of a table.
Let's say it has 10 rows each with 50 px height. So the total height of the content is 500 px. In other words the "self height" is 500 px.
If the user sets only 200 px height for the table LVGL will see that the self size is larger and make the table scrollable.
It means not only the children can make an object scrollable but a larger self size too.
LVGL uses the `LV_EVENT_GET_SELF_SIZE` event to get the self size of an object. Here is an example to see how to handle the event
```c
if(event_code == LV_EVENT_GET_SELF_SIZE) {
lv_point_t * p = lv_event_get_param(e);
//If x or y < 0 then it doesn't neesd to be calculated now
if(p->x >= 0) {
p->x = 200; //Set or calculate the self width
}
if(p->x >= 0) {
p->y = 50; //Set or calculate the self height
}
}
```
## Examples

View File

@ -4,34 +4,41 @@
```
# Styles
*Styles* are used to set the appearance of the objects. Styles in lvgl are heavily inspired by CSS. The concept in nutshell is the following:
- A style is an `lv_style_t` variable which can hold properties, for example border width, text color and so on. It's similar to `class` in CSS.
- Not all properties have to be specified. Unspecified properties will use a default value.
- Styles can be assigned to objects to change their appearance.
- A style can be used by any number of objects.
- Styles can be cascaded which means multiple styles can be assigned to an object and each style can have different properties.  
- A style is an `lv_style_t` variable which can hold properties, for example border width, text color and so on. It's similar to a `class` in CSS.
- Styles can be assigned to objects to change their appearance. During the assignment the target part (*pseudo element* in CSS) and target state (*pseudo class*) can be specified.
For example add `style_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 can be assigned to an object and each style can have different properties.
Therefore not all properties have to be specified in style. LVLG will look for a property until a style defines it or use a default if it's not spefied by any of the styles.
For example `style_btn` can result in a default gray button and `style_btn_red` can add only a `background-color=red` to overwrite the background color.
- Later added styles have higher precedence. It means if a property is specified in two styles the later added will be used.
- Some properties (e.g. text color) can be inherited from the parent(s) if it's not specified in the object.
- Objects can have local styles that have higher precedence than "normal" styles.
- Unlike CSS (where pseudo-classes describes different states, e.g. `:hover`), in lvgl a property is assigned to a given state. (I.e. not the "class" is related to state but every single property has a state)
- 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 following states:
- **LV_STATE_DEFAULT** (0x00): Normal, released
- **LV_STATE_CHECKED** (0x01): Toggled or checked
- **LV_STATE_FOCUSED** (0x02): Focused via keypad or encoder or clicked via touchpad/mouse
- **LV_STATE_EDITED**  (0x04): Edit by an encoder
- **LV_STATE_HOVERED** (0x08): Hovered by mouse (not supported now)
- **LV_STATE_PRESSED** (0x10): Pressed
- **LV_STATE_DISABLED** (0x20): Disabled or inactive
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
Combination of states is also possible, for example `LV_STATE_FOCUSED | LV_STATE_PRESSED`.
The combination states the object can be focused and pressed at the same time. It represented as `LV_STATE_FOCUSED | LV_STATE_PRESSED`.
The style properties can be defined in every state and state combination. For example, setting a different background color for default and pressed state.
The style can be added to any state and state combination.
For example, setting a different background color for default and pressed state.
If a property is not defined in a state the best matching state's property will be used. Typically it means the property with `LV_STATE_DEFAULT` state.˛
If the property is not set even for the default state the default value will be used. (See later)
@ -42,16 +49,18 @@ To determine which state's property to use let's use an example. Let's see the b
- `LV_STATE_PRESSED`: gray
- `LV_STATE_FOCUSED`: red
1. By the default the object is in default state, so it's a simple case: the property is perfectly defined in the object's current state as white
1. By the default the object is in default state, so it's a simple case: the property is perfectly defined in the object's current state as white.
2. When the object is pressed there are 2 related properties: default with white (default is related to every state) and pressed with gray.
The pressed state has 0x10 precedence which is higher than the default state's 0x00 precedence, so gray color will be used.
The pressed state has 0x0020 precedence which is higher than the default state's 0x0000 precedence, so gray color will be used.
3. When the object is focused the same thing happens as in pressed state and red color will be used. (Focused state has higher precedence than default 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 gray color 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 0x02 + 0x10 = 0x12 precedence, which higher than the pressed states precedence so rose color would be used.
6. When the object is checked there is no property to set the background color for this state. So in lack of a better option, the object remains white from the default state's property.
In this case, this combined state has 0x0020 + 0x0002 = 0x0022 precedence, which higher than the pressed states precedence so rose color would be used.
6. When the object is in checked state there is no property to set the background color for this state. So in 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 the user would expect naturally. E.g. if an object is focused, the user still want to see if it's pressed, therefore pressed state has a higher precedence.
If the focused state had higher precedence it would overwrite the pressed color.
- If you want to set a property for all state (e.g. red background color) just set it for the default state. If the object can't find a property for 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 different style elements for different states.
@ -59,7 +68,7 @@ For example, finding background colors for released, pressed, checked + pressed,
Instead, for example, use the background color for pressed and checked states 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 possible to add more styles to an object and let the later added style to modify or extend the properties in the other styles.
It's not required to set all the properties in one style. It's possible to add more styles to an object and let the later added style to modify or extend appearance.
For example, create a general gray button style and create a new for red buttons where only the new background color is set.
It's the same concept when in CSS all the used classes are listed like `<div class=".btn .btn-red">`.
@ -74,107 +83,153 @@ In this case, when the button is released (it's in default state) it will be red
When the button is pressed the light-gray color is a better match because it describes the current state perfectly, so the button will be light-gray.
## Inheritance
Some properties (typically that are related to texts) can be inherited from the parent object's styles. Inheritance is applied only if the given property is not set in the object's styles (even in default state).
In this case, if the property is inheritable, the property's value will be searched in the parent too until a part can tell a value for the property. The parents will use their own state to tell the value.
So is button is pressed, and text color comes from here, the pressed text color will be used.
Some properties (typically that are related to texts) can be inherited from the parent object's styles.
Inheritance is applied only if the given property is not set in the object's styles (even in default state).
In this case, if the property is inheritable, the property's value will be searched in the parents too until an object can tell a value for the property. The parents will use their own state to tell the value.
So if a button is pressed, and the text color comes from here, the pressed text color will be used.
## Parts
Objects can have *parts* which can have their own style. For example a [page](/widgets/page) has four parts:
Objects can have *parts* which can 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 the value*/
- `LV_PART_SELECTED` Indicate the currently selected option or section
- `LV_PART_ITEMS` Used if the widget has multiple similar elements (e.g. tabel cells)*/
- `LV_PART_TICKS` Ticks on scales e.g. for a chart or meter
- `LV_PART_CURSOR` Mark a specific place e.g. text area's or chart's cursor
- `LV_PART_CUSTOM_FIRST` Custom parts can be added from here.
For example a [Slider](/widgets/slider) has three parts:
- Background
- Scrollable
- Scrollbar
- Edge flash
- Indiactor
- Knob
There is three types of object parts **main**, **virtual** and **real**.
The main part is usually the background and largest part of the object. Some object has only a main part. For example, a button has only a background.
The virtual parts are additional parts just drawn on the fly to the main part. There is no "real" object behind them.
For example, the page's scrollbar is not a real object, it's just drawn when the page's background is drawn.
The virtual parts always have the same state as the main part.
If the property can be inherited, the main part will be also considered before going to the parent.
The real parts are real objects created and managed by the main object. For example, the page's scrollable part is real object.
Real parts can be in different state than the main part.
To see which parts an object has visit their documentation page.
It means the all three parts of teh slider can have their own styles. See later how to add style styles to objects and parts.
## Initialize styles and set/get properties
Styles are stored in `lv_style_t` variables. Style variables should be `static`, global or dynamically allocated. In other words they can not be local variables in functions which are destroyed when the function exists.
Styles are stored in `lv_style_t` variables. Style variables should be `static`, global or dynamically allocated.
In other words they can not be local variables in functions which are destroyed when the function exists.
Before using a style it should be initialized with `lv_style_init(&my_style)`.
After initializing the style properties can be set or added to it.
Property set functions looks like this: `lv_style_set_<property_name>(&style, <state>, <value>);`
For example the [above mentioned](#states) example looks like this:
```c
static lv_style_t style1;
lv_style_set_bg_color(&style1, LV_STATE_DEFAULT, LV_COLOR_WHITE);
lv_style_set_bg_color(&style1, LV_STATE_PRESSED, LV_COLOR_GRAY);
lv_style_set_bg_color(&style1, LV_STATE_FOCUSED, LV_COLOR_RED);
lv_style_set_bg_color(&style1, LV_STATE_FOCUSED | LV_STATE_PRESSED, lv_color_hex(0xf88));
```
It's possible to copy a style with `lv_style_copy(&style_destination, &style_source)`. After copy properties still can be added freely.
Property set functions looks like this: `lv_style_set_<property_name>(&style, <value>);` For example:
```c
static lv_style_t style_btn;
lv_style_init(&style_btn);
lv_style_set_bg_color(&style_btn, lv_color_grey());
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_color_red());
lv_style_set_bg_opa(&style_btn_red, LV_OPA_COVER);
```
To remove a property use:
```c
lv_style_remove_prop(&style, LV_STYLE_BG_COLOR | (LV_STATE_PRESSED << LV_STYLE_STATE_POS));
lv_style_remove_prop(&style, LV_STYLE_BG_COLOR);
```
To get the value from style in a given state functions with the following prototype are available: `_lv_style_get_color/int/opa/ptr(&style, <prop>, <result buf>);`.
The best matching property will be selected and it's precedence will be returned. `-1` will be returned if the property is not found.
The form of the function (`...color/int/opa/ptr`) should be used according to the type of `<prop>`.
For example:
To get a properties value from style:
```c
lv_color_t color;
int16_t res;
res = _lv_style_get_color(&style1, LV_STYLE_BG_COLOR | (LV_STATE_PRESSED << LV_STYLE_STATE_POS), &color);
if(res >= 0) {
//the bg_color is loaded into `color`
lv_style_value_t v;
lv_res_t res = lv_style_rget_prop(&style, LV_STYLE_BG_COLOR, &v);
if(res == LV_RES_OK) { /*Found*/
do_something(v.color);
}
```
To reset a style (free all it's data) use
`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
```c
lv_style_reset(&style);
```
## Managing style list
## Add and remove styles to a widget
A style on its own not that useful. It should be assigned to an object to take its effect.
Every part of the objects stores a *style list* which is the list of assigned styles.
To add a style to an object use `lv_obj_add_style(obj, <part>, &style)`
For example:
### Add styles
To add a style to an object use `lv_obj_add_style(obj, &style, <selector>)`. `<selector>` is an OR-ed value of parts and state to which the style should be added. Some examples:
- `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
- `0` Same as `LV_PART_MAIN | LV_STATE_DEFAULT`.
- `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`:
```c
lv_obj_add_style(btn, LV_BTN_PART_MAIN, &btn); /*Default button style*/
lv_obj_add_style(btn, LV_BTN_PART_MAIN, &btn_red);  /*Overwrite only a some colors to red*/
lv_obj_add_style(btn, &style_btn, 0); /*Default button style*/
lv_obj_add_style(btn, &btn_red, LV_STATE_PRESSED);  /*Overwrite only a some colors to red when pressed*/
```
An objects style list can be reset with `lv_obj_reset_style_list(obj, <part>)`
### Remove styles
To remove all styles from an object use `lv_obj_reove_style_all(obj)`.
If a style which is already assigned to an object changes (i.e. one of it's property is set to a new value) the objects using that style should be notified with `lv_obj_refresh_style(obj, part, property)`. To refresh all parts and proeprties use `lv_obj_refresh_style(obj, LV_OBJ_PART_ALL, LV_STYLE_PROP_ALL)`.
To remove specific styles use `lv_obj_remoev_style(obj, style, selector)`. This function will remove `style` only if the `selector` matches with the `selector` used in `lv_obj_add_style`.
`style` can be `NULL` to check only the `selector` and remove all matching styles. The `selector` can use the `LV_STATE_ANY` and `LV_PART_ANY` values to remove the style with any state or part.
To get a final value of property, including cascading, inheritance, local styles and transitions (see below), get functions like this can be used: `lv_obj_get_style_<property_name>(obj, <part>)`.
### Report style changes
If a style - which is already assigned to object - changes (i.e. one of it's property is set to a new value) the objects using that style should be notified. There are 3 options to do this:
1. If you know that the changed properties can be applied by a simple (e.g. color or opacity changes) redraw just call `lv_obj_invalidate(obj)`, `lv_obj_invalideate(lv_scr_act())`.
2. If something more complex change happened on a style and you know which object(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. No make LVGL check all object whether thy use the style and refresh them use `lv_obj_report_style_change(&style)`. If `style` is `NULL` all object's will be notified.
### Get a property's value on an object
To get a final value of property - considering cascading, inheritance, local styles and transitions (see below) - get functions like this can be used:
`lv_obj_get_style_<property_name>(obj, <part>)`.
These functions uses the object's current state and if no better candidate returns a default value.  
For example:
```c
lv_color_t color = lv_obj_get_style_bg_color(btn, LV_BTN_PART_MAIN);
lv_color_t color = lv_obj_get_style_bg_color(btn, LV_PART_MAIN);
```
## Local styles
In the object's style lists, so-called local properties can be stored as well. It's the same concept than CSS's `<div style="color:red">`.
The local style is the same as a normal style, but it belongs only to a given object and can not be shared with other objects.
To set a local property use functions like `lv_obj_set_style_local_<property_name>(obj, <part>, <state>, <value>);`  
Besides "normal" styles, the objects can store local styles too. This concept is similar to inline styles in CSS (e.g. `<div style="color:red">`) with some modification.
So local styles are like normal styles but they can't be shared among other objects. If used, local styles are allocated automatically, and freed when the object is deleted.
They are usuful to add local customization to the object.
Unlike in CSS, in LVGL local styles can be assigned to states (*pseudo-classes*) and parts (pseudo-elements).
To set a local property use functions like `lv_obj_set_style_local_<property_name>(obj, <value>, <selector>);`  
For example:
```c
lv_obj_set_style_local_bg_color(btn, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_RED);
lv_obj_set_style_local_bg_color(slider, lv_color_red(), LV_PART_INDICATOR | LV_STATE_FOCUSED);
```
## Properties
TODO include properties generated by style_api_gen.py
### Typical background properties
In the documentation of the widgets you will see sentences like "The widget use the typical background properties". The "typical background 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 new properties from the new state are set immediately. However, with transitions it's possible to play an animation on state change.
For example, on pressing a button its background color can be animated to the pressed color over 300 ms.
@ -182,328 +237,111 @@ For example, on pressing a button its background color can be animated to the pr
The parameters of the transitions are stored in the styles. It's possible to set
- the time of the transition
- the delay before starting the transition
- the animation path (also known as timing function)
- the animation path (also known as timing or easing function)
- the properties to animate
The transition properties can be defined for each state.
For example, setting 500 ms transition time in default state will mean that when the object goes to default state 500 ms transition time will be applied.
The transition properties can be defined for each state. For example, setting 500 ms transition time in default state will mean that when the object goes to default state 500 ms transition time will be applied.
Setting 100 ms transition time in the pressed state will mean a 100 ms transition time when going to presses state.
So this example configuration will result in fast going to presses state and slow going back to default.
## Properties
To describe a transition an `lv_transition_dsc_t` variable needs to initialized and added to a style:
```c
/*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*/
};
The following properties can be used in the styles.
static lv_style_transition_dsc_t trans1;
lv_style_transition_dsc_init(&trans1, trans_props, lv_anim_path_ease_out, duration_ms, delay_ms);
### Mixed properties
- **radius** (`lv_style_int_t`): Set the radius of the background. 0: no radius, `LV_RADIUS_CIRCLE`: maximal radius. Default value: 0.
- **clip_corner** (`bool`): `true`: enable to clip the overflowed content on the rounded (radius > 0) corners. Default value: `false`.
- **size** (`lv_style_int_t`): Size of internal elements of the widgets. See the documentation of the widgets if this property is used or not. Default value: `LV_DPI / 20`.
- **transform_width**  (`lv_style_int_t`): Make the object wider on both sides with this value. Default value: 0.
- **transform_height**  (`lv_style_int_t`) Make the object higher on both sides with this value. Default value: 0.
- **transform_angle**  (`lv_style_int_t`): Rotate the image-like objects. It's uinit is 0.1 deg, for 45 deg use 450. Default value: 0.
- **transform_zoom**  (`lv_style_int_t`) Zoom image-like objects. 256 (or `LV_IMG_ZOOM_NONE`) for normal size, 128 half size, 512 double size, ans so on. Default value: `LV_IMG_ZOOM_NONE`.
- **opa_scale** (`lv_style_int_t`): Inherited. Scale down all opacity values of the object by this factor. As it's inherited the children objects will be affected too. Default value: `LV_OPA_COVER`.
### Padding and margin properties
*Padding* sets the space on the inner sides of the edges. It means "I don't want my children too close to my sides, so keep this space".
*Padding inner* set the "gap" between the children.
*Margin* sets the space on the outer side of the edges. It means "I want this space around me".
These properties are typically used by [Container](/widgets/cont) object if [layout](/widgets/cont#layout) or
[auto fit](/widgets/cont#auto-fit) is enabled.
However other widgets also use them to set spacing. See the documentation of the widgets for the details.
- **pad_top** (`lv_style_int_t`): Set the padding on the top. Default value: 0.
- **pad_bottom** (`lv_style_int_t`): Set the padding on the bottom. Default value: 0.
- **pad_left** (`lv_style_int_t`): Set the padding on the left. Default value: 0.
- **pad_right** (`lv_style_int_t`): Set the padding on the right. Default value: 0.
- **pad_inner** (`lv_style_int_t`): Set the padding inside the object between children. Default value: 0.
- **margin_top** (`lv_style_int_t`): Set the margin on the top. Default value: 0.
- **margin_bottom** (`lv_style_int_t`): Set the margin on the bottom. Default value: 0.
- **margin_left** (`lv_style_int_t`): Set the margin on the left. Default value: 0.
- **margin_right** (`lv_style_int_t`): Set the margin on the right. Default value: 0.
### Background properties
The background is a simple rectangle which can have gradient and `radius` rounding.
- **bg_color** (`lv_color_t`) Specifies the color of the background. Default value: `LV_COLOR_WHITE`.
- **bg_opa** (`lv_opa_t`) Specifies opacity of the background. Default value: `LV_OPA_TRANSP`.
- **bg_grad_color** (`lv_color_t`) Specifies the color of the background's gradient. The color on the right or bottom is `bg_grad_dir != LV_GRAD_DIR_NONE`. Default value: `LV_COLOR_WHITE`.
- **bg_main_stop** (`uint8_t`): Specifies where should the gradient start. 0: at left/top most position, 255: at right/bottom most position. Default value: 0.
- **bg_grad_stop** (`uint8_t`): Specifies where should the gradient stop. 0: at left/top most position, 255: at right/bottom most position. Default value: 255.
- **bg_grad_dir** (`lv_grad_dir_t`) Specifies the direction of the gradient. Can be `LV_GRAD_DIR_NONE/HOR/VER`. Default value: `LV_GRAD_DIR_NONE`.
- **bg_blend_mode** (`lv_blend_mode_t`): Set the blend mode the background. Can be `LV_BLEND_MODE_NORMAL/ADDITIVE/SUBTRACTIVE`). Default value: `LV_BLEND_MODE_NORMAL`.
```eval_rst
.. image:: /lv_examples/src/lv_ex_style/lv_ex_style_1.*
:alt: Styling the background in lvgl
.. literalinclude:: /lv_examples/src/lv_ex_style/lv_ex_style_1.c
:language: c
lv_style_set_transition(&style1, &trans1);
```
### Border properties
The border is drawn on top of the *background*. It has `radius` rounding.
- **border_color** (`lv_color_t`) Specifies the color of the border. Default value: `LV_COLOR_BLACK`.
- **border_opa** (`lv_opa_t`) Specifies opacity of the border. Default value: `LV_OPA_COVER`.
- **border_width** (`lv_style_int_t`): Set the width of the border. Default value: 0.
- **border_side** (`lv_border_side_t`) Specifies which sides of the border to draw. Can be `LV_BORDER_SIDE_NONE/LEFT/RIGHT/TOP/BOTTOM/FULL`. ORed values are also possible. Default value: `LV_BORDER_SIDE_FULL`.
- **border_post** (`bool`): If `true` the border will be drawn after all children have been drawn. Default value: `false`.
- **border_blend_mode** (`lv_blend_mode_t`): Set the blend mode of the border. Can be `LV_BLEND_MODE_NORMAL/ADDITIVE/SUBTRACTIVE`). Default value: `LV_BLEND_MODE_NORMAL`.
## Color filter
TODO
```eval_rst
.. image:: /lv_examples/src/lv_ex_style/lv_ex_style_2.*
:alt: Styling the border in lvgl
.. literalinclude:: /lv_examples/src/lv_ex_style/lv_ex_style_2.c
:language: c
```
### Outline properties
The outline is similar to *border* but is drawn outside of the object.
- **outline_color** (`lv_color_t`) Specifies the color of the outline. Default value: `LV_COLOR_BLACK`.
- **outline_opa** (`lv_opa_t`) Specifies opacity of the outline. Default value: `LV_OPA_COVER`.
- **outline_width** (`lv_style_int_t`): Set the width of the outline. Default value: 0.
- **outline_pad** (`lv_style_int_t`) Set the space between the object and the outline. Default value: 0.
- **outline_blend_mode** (`lv_blend_mode_t`): Set the blend mode of the outline. Can be `LV_BLEND_MODE_NORMAL/ADDITIVE/SUBTRACTIVE`). Default value: `LV_BLEND_MODE_NORMAL`.
```eval_rst
.. image:: /lv_examples/src/lv_ex_style/lv_ex_style_3.*
:alt: Styling the outline in lvgl
.. literalinclude:: /lv_examples/src/lv_ex_style/lv_ex_style_3.c
:language: c
```
### Shadow properties
The shadow is a blurred area under the object.
- **shadow_color** (`lv_color_t`) Specifies the color of the shadow. Default value: `LV_COLOR_BLACK`.
- **shadow_opa** (`lv_opa_t`) Specifies opacity of the shadow. Default value: `LV_OPA_TRANSP`.
- **shadow_width** (`lv_style_int_t`): Set the width (blur size) of the outline. Default value: 0.
- **shadow_ofs_x** (`lv_style_int_t`): Set the an X offset for the shadow. Default value: 0.
- **shadow_ofs_y** (`lv_style_int_t`): Set the an Y offset for the shadow. Default value: 0.
- **shadow_spread** (`lv_style_int_t`): make the shadow larger than the background in every direction by this value. Default value: 0.
- **shadow_blend_mode** (`lv_blend_mode_t`): Set the blend mode of the shadow. Can be `LV_BLEND_MODE_NORMAL/ADDITIVE/SUBTRACTIVE`). Default value: `LV_BLEND_MODE_NORMAL`.
```eval_rst
.. image:: /lv_examples/src/lv_ex_style/lv_ex_style_4.*
:alt: Styling the shadow in lvgl
.. literalinclude:: /lv_examples/src/lv_ex_style/lv_ex_style_4.c
:language: c
```
### Pattern properties
The pattern is an image (or symbol) drawn in the middle of the background or repeated to fill the whole background.
- **pattern_image** (`const void *`): Pointer to an `lv_img_dsc_t` variable, a path to an image file or a symbol. Default value: `NULL`.
- **pattern_opa** (`lv_opa_t`): Specifies opacity of the pattern. Default value: `LV_OPA_COVER`.
- **pattern_recolor** (`lv_color_t`): Mix this color to the pattern image. In case of symbols (texts) it will be the text color. Default value: `LV_COLOR_BLACK`.
- **pattern_recolor_opa** (`lv_opa_t`): Intensity of recoloring. Default value: `LV_OPA_TRANSP` (no recoloring).
- **pattern_repeat** (`bool`): `true`: the pattern will be repeated as a mosaic. `false`: place the pattern in the middle of the background. Default value: `false`.
- **pattern_blend_mode** (`lv_blend_mode_t`): Set the blend mode of the pattern. Can be `LV_BLEND_MODE_NORMAL/ADDITIVE/SUBTRACTIVE`). Default value: `LV_BLEND_MODE_NORMAL`.
```eval_rst
.. image:: /lv_examples/src/lv_ex_style/lv_ex_style_5.*
:alt: Styling the shadow in lvgl
.. literalinclude:: /lv_examples/src/lv_ex_style/lv_ex_style_5.c
:language: c
```
### Value properties
Value is an arbitrary text drawn to the background. It can be a lightweighted replacement of creating label objects.
- **value_str** (`const char *`): Pointer to text to display. Only the pointer is saved! (Don't use local variable with lv_style_set_value_str, instead use static, global or dynamically allocated data). Default value: `NULL`.
- **value_color** (`lv_color_t`): Color of the text. Default value: `LV_COLOR_BLACK`.
- **value_opa** (`lv_opa_t`): Opacity of the text. Default value: `LV_OPA_COVER`.
- **value_font** (`const lv_font_t *`): Pointer to font of the text. Default value: `NULL`.
- **value_letter_space** (`lv_style_int_t`): Letter space of the text. Default value: 0.
- **value_line_space** (`lv_style_int_t`): Line space of the text. Default value: 0.
- **value_align** (`lv_align_t`): Alignment of the text. Can be `LV_ALIGN_...`. Default value: `LV_ALIGN_CENTER`.
- **value_ofs_x** (`lv_style_int_t`): X offset from the original position of the alignment. Default value: 0.
- **value_ofs_y** (`lv_style_int_t`): Y offset from the original position of the alignment. Default value: 0.
- **value_blend_mode** (`lv_blend_mode_t`): Set the blend mode of the text. Can be `LV_BLEND_MODE_NORMAL/ADDITIVE/SUBTRACTIVE`). Default value: `LV_BLEND_MODE_NORMAL`.
```eval_rst
.. image:: /lv_examples/src/lv_ex_style/lv_ex_style_6.*
:alt: Styling the value text in lvgl
.. literalinclude:: /lv_examples/src/lv_ex_style/lv_ex_style_6.c
:language: c
```
### Text properties
Properties for textual object.
- **text_color** (`lv_color_t`): Color of the text. Default value: `LV_COLOR_BLACK`.
- **text_opa** (`lv_opa_t`): Opacity of the text. Default value: `LV_OPA_COVER`.
- **text_font** (`const lv_font_t *`): Pointer to font of the text. Default value: `NULL`.
- **text_letter_space** (`lv_style_int_t`): Letter space of the text. Default value: 0.
- **text_line_space** (`lv_style_int_t`): Line space of the text. Default value: 0.
- **text_decor** (`lv_text_decor_t`): Add text decoration. Can be `LV_TEXT_DECOR_NONE/UNDERLINE/STRIKETHROUGH`. Default value: `LV_TEXT_DECOR_NONE`.
- **text_sel_color** (`lv_color_t`): Set color of the text selection. Default value: `LV_COLOR_BLACK`
- **text_sel_bg_color** (`lv_color_t`): Set background color of text selection. Default value: `LV_COLOR_BLUE`
- **text_blend_mode** (`lv_blend_mode_t`): Set the blend mode of the text. Can be `LV_BLEND_MODE_NORMAL/ADDITIVE/SUBTRACTIVE`). Default value: `LV_BLEND_MODE_NORMAL`.
```eval_rst
.. image:: /lv_examples/src/lv_ex_style/lv_ex_style_7.*
:alt: Styling a text in lvgl
.. literalinclude:: /lv_examples/src/lv_ex_style/lv_ex_style_7.c
:language: c
```
### Line properties
Properties of lines.
- **line_color** (`lv_color_t`): Color of the line. Default value: `LV_COLOR_BLACK`
- **line_opa** (`lv_opa_t`): Opacity of the line. Default value: `LV_OPA_COVER`
- **line_width** (`lv_style_int_t`): Width of the line. Default value: 0.
- **line_dash_width** (`lv_style_int_t`): Width of dash. Dashing is drawn only for horizontal or vertical lines. 0: disable dash. Default value: 0.
- **line_dash_gap** (`lv_style_int_t`): Gap between two dash line. Dashing is drawn only for horizontal or vertical lines. 0: disable dash. Default value: 0.
- **line_rounded** (`bool`): `true`: draw rounded line endings. Default value: `false`.
- **line_blend_mode** (`lv_blend_mode_t`): Set the blend mode of the line. Can be `LV_BLEND_MODE_NORMAL/ADDITIVE/SUBTRACTIVE`). Default value: `LV_BLEND_MODE_NORMAL`.
```eval_rst
.. image:: /lv_examples/src/lv_ex_style/lv_ex_style_8.*
:alt: Styling a line in lvgl
.. literalinclude:: /lv_examples/src/lv_ex_style/lv_ex_style_8.c
:language: c
```
### Image properties
Properties of image.
- **image_recolor** (`lv_color_t`):  Mix this color to the pattern image. In case of symbols (texts) it will be the text color. Default value: `LV_COLOR_BLACK`
- **image_recolor_opa** (`lv_opa_t`): Intensity of recoloring. Default value: `LV_OPA_TRANSP` (no recoloring). Default value: `LV_OPA_TRANSP`
- **image_opa** (`lv_opa_t`): Opacity of the image. Default value: `LV_OPA_COVER`
- **image_blend_mode** (`lv_blend_mode_t`): Set the blend mode of the image. Can be `LV_BLEND_MODE_NORMAL/ADDITIVE/SUBTRACTIVE`). Default value: `LV_BLEND_MODE_NORMAL`.
```eval_rst
.. image:: /lv_examples/src/lv_ex_style/lv_ex_style_9.*
:alt: Styling an image in lvgl
.. literalinclude:: /lv_examples/src/lv_ex_style/lv_ex_style_9.c
:language: c
```
### Transition properties
Properties to describe state change animations.
- **transition_time** (`lv_style_int_t`): Time of the transition. Default value: 0.
- **transition_delay** (`lv_style_int_t`): Delay before the transition. Default value: 0.
- **transition_prop_1** (`property name`): A property on which transition should be applied. Use the property name with upper case with `LV_STYLE_` prefix, e.g. `LV_STYLE_BG_COLOR`. Default value: 0 (none).
- **transition_prop_2** (`property name`): Same as *transition_1* just for another property. Default value: 0 (none).
- **transition_prop_3** (`property name`): Same as *transition_1* just for another property. Default value: 0 (none).
- **transition_prop_4** (`property name`): Same as *transition_1* just for another property. Default value: 0 (none).
- **transition_prop_5** (`property name`): Same as *transition_1* just for another property. Default value: 0 (none).
- **transition_prop_6** (`property name`): Same as *transition_1* just for another property. Default value: 0 (none).
- **transition_path** (`lv_anim_path_t`): An animation path for the transition. (Needs to be static or global variable because only its pointer is saved).
Default value: `lv_anim_path_def` (linear path).
```eval_rst
.. image:: /lv_examples/src/lv_ex_style/lv_ex_style_10.*
:alt: Styling an transitions in lvgl
.. literalinclude:: /lv_examples/src/lv_ex_style/lv_ex_style_10.c
:language: c
```
### Scale properties
Auxiliary properties for scale-like elements. Scales have a normal and end region.
As the name implies the end region is the end of the scale where can be critical values or inactive values. The normal region is before the end region.
Both regions could have different properties.
- **scale_grad_color** (`lv_color_t`):  In normal region make gradient to this color on the scale lines. Default value: `LV_COLOR_BLACK`.
- **scale_end_color** (`lv_color_t`):  Color of the scale lines in the end region. Default value: `LV_COLOR_BLACK`.
- **scale_width** (`lv_style_int_t`): Width of the scale. Default value: `LV_DPI / 8`. Default value: `LV_DPI / 8`.
- **scale_border_width** (`lv_style_int_t`): Width of a border drawn on the outer side of the scale in the normal region. Default value: 0.
- **scale_end_border_width** (`lv_style_int_t`): Width of a border drawn on the outer side of the scale in the end region. Default value: 0.
- **scale_end_line_width** (`lv_style_int_t`): Width of a scale lines in the end region. Default value: 0.
```eval_rst
.. image:: /lv_examples/src/lv_ex_style/lv_ex_style_11.*
:alt: Styling a scale in lvgl
.. literalinclude:: /lv_examples/src/lv_ex_style/lv_ex_style_11.c
:language: c
```
In the documentation of the widgets you will see sentences like "The widget use the typical background properties". The "typical background" properties are:
- Background
- Border
- Outline
- Shadow
- Pattern
- Value
## Themes
Themes are a collection of styles. There is always an active theme whose styles are automatically applied when an object is created.
Themes are a collection of styles. If there is an active theme LVGL applies it on the every created widget.
It gives a default appearance to UI which can be modified by adding further styles.
The default theme is set in `lv_conf.h` with `LV_THEME_...` defines. Every theme has the following properties
- primary color
- secondary color
- small font
- normal font
- subtitle font
- title font
- flags (specific to the given theme)
Every display can have a different theme. For example a colorful theme on a TFT and monochrome theme on a secondary monochrome display.
It up to the theme how to use these properties.
To set a theme for a display 2 steps are required:
1. Initialize a theme
2. Assign the initialized theme to a display.
There are 3 built-in themes:
- empty: no default styles are added
- material: an impressive, modern theme - mono: simple black and white theme for monochrome displays
- template: a very simple theme which can be copied to create a custom theme 
Theme initialization functions can have different prototype. This example shows how to set the "default" theme:
```c
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_disp_set_theme(display, th); /*Assign the theme to the display*/
```
The themes can be enabled in `lv_conf.h`. If the default theme is enabled by `LV_USE_THEME_DEFAULT 1` LVGL automatically initializes and sets it when a display is created.
### Extending themes
Built-in themes can be extended by custom theme. If a custom theme is created a "base theme" can be selected. The base theme's styles will be added before the custom theme. Any number of themes can be chained this was. E.g. material theme -> custom theme -> dark theme.
Built-in themes can be extended.
If a custom theme is created a parent theme can be selected. The parent theme's styles will be added before the custom theme's styles.
Any number of themes can be chained this way. E.g. default theme -> custom theme -> dark theme.
Here is an example about how to create a custom theme based on the currently active built-in theme.
Here is an example about creating a custom theme based on the currently active theme.
```c
/*Get the current theme (e.g. material). It will be the base of the custom theme.*/
lv_theme_t * base_theme = lv_theme_get_act();
/*Declare the style used in the theme*/
static lv_style_t style_btn;
...
/*Initialize a custom theme*/
static lv_theme_t custom_theme; /*Declare a theme*/
lv_theme_copy(&custom_theme, base_theme); /*Initialize the custom theme from the base theme*/
lv_theme_set_apply_cb(&custom_theme, custom_apply_cb); /*Set a custom theme apply callback*/
lv_theme_set_base(custom_theme, base_theme); /*Set the base theme of the csutom theme*/
/*Initialize the styles*/
lv_style_init(&style_btn);
lv_style_set_bg_color(&style_btn, lv_color_green());
/*Initialize styles for the new theme*/
static lv_style_t style1;
lv_style_init(&style1);
lv_style_set_bg_color(&style1, LV_STATE_DEFAULT, custom_theme.color_primary);
/*Initialize the new theme from the current theme*/
lv_theme_t * th_act = lv_disp_get_theme(NULL);
static lv_theme_t th_new;
th_new = *th_act;
/*Set the parent theme ans the style applay 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 the the current display*/
lv_disp_set_theme(NULL, &th_new);
...
/*Add a custom apply callback*/
static void custom_apply_cb(lv_theme_t * th, lv_obj_t * obj, lv_theme_style_t name)
/*Will be called when the styles of the base theme are already added
to add new styles*/
void new_theme_apply_cb(lv_theme_t * th, lv_obj_t * obj)
{
lv_style_list_t * list;
switch(name) {
case LV_THEME_BTN:
list = lv_obj_get_style_list(obj, LV_BTN_PART_MAIN);
_lv_style_list_add_style(list, &my_style);
break;
if(lv_obj_check_type(obj, &lv_btn_class)) {
lv_obj_add_style(obj, &style_btn, 0);
}
}
```
## Examples
## Example
### Styling a button
```eval_rst
.. image:: /lv_examples/src/lv_ex_get_started/lv_ex_get_started_2.*
:alt: Styling a button in LVGL
.. literalinclude:: /lv_examples/src/lv_ex_get_started/lv_ex_get_started_2.c
:language: c
```
## API
```eval_rst
.. doxygenfile:: lv_obj_style.h
:project: lvgl
.. doxygenfile:: lv_obj_style_dec.h
:project: lvgl
.. doxygenfile:: lv_style.h
:project: lvgl
.. doxygenfile:: lv_style_dec.h
:project: lvgl
.. doxygenfile:: lv_theme.h
:project: lvgl

View File

@ -1,79 +0,0 @@
```eval_rst
.. include:: /header.rst
:github_url: |github_link_base|/widgets/arc.md
```
# Arc (lv_arc)
## Overview
The Arc are consists of a background and a foreground arc. Both can have start and end angles and thickness.
## Parts and Styles
The Arc's main part is called `LV_ARC_PART_MAIN`. It draws a background using the typical background style properties and an arc using the *line* style properties.
The arc's size and position will respect the *padding* style properties.
`LV_ARC_PART_INDIC` is virtual part and it draws an other arc using the *line* style properties. It's padding values are interpreted relative to the background arc.
The radius of the indicator arc will be modified according to the greatest padding value.
`LV_ARC_PART_KNOB` is virtual part and it draws on the end of the arc indicator. It uses all background properties and padding values. With zero padding the knob size is the same as the indicator's width.
Larger padding makes it larger, smaller padding makes it smaller.
## Usage
### Angles
To set the angles of the background, use the `lv_arc_set_bg_angles(arc, start_angle, end_angle)` function or `lv_arc_set_bg_start/end_angle(arc, start_angle)`.
Zero degree is at the middle right (3 o'clock) of the object and the degrees are increasing in a clockwise direction.
The angles should be in [0;360] range.
Similarly, `lv_arc_set_angles(arc, start_angle, end_angle)` function or `lv_arc_set_start/end_angle(arc, start_angle)` sets the angles of the indicator arc.
### Rotation
An offset to the 0 degree position can added with `lv_arc_set_rotation(arc, deg)`.
### Range and values
Besides setting angles manually the arc can have a range and a value. To set the range use `lv_arc_set_range(arc, min, max)` and to set a value use `lv_arc_set_value(arc, value)`.
Using range and value the angle of the indicator will be mapped between background angles.
Note that, settings angles and values are independent. You should use either value and angle settings. Mixing the two might result unintended behavior.
### Type
The arc can have the different "types". They are set with `lv_arc_set_type`.
The following types exist:
- `LV_ARC_TYPE_NORMAL` indicator arc drawn clockwise (min to current)
- `LV_ARC_TYPE_REVERSE` indicator arc drawn counter clockwise (max to current)
- `LV_ARC_TYPE_SYMMETRIC` indicator arc drawn from the middle point to the current value.
## Events
Besides the [Generic events](../overview/event.html#generic-events) the following [Special events](../overview/event.html#special-events) are sent by the arcs:
- **LV_EVENT_VALUE_CHANGED** sent when the arc is pressed/dragged to set a new value.
Learn more about [Events](/overview/event).
## Keys
No *Keys* are processed by the object type.
Learn more about [Keys](/overview/indev).
## Example
```eval_rst
.. include:: /lv_examples/src/lv_ex_widgets/lv_ex_arc/index.rst
```
## API
```eval_rst
.. doxygenfile:: lv_arc.h
:project: lvgl
```

View File

@ -1,64 +0,0 @@
```eval_rst
.. include:: /header.rst
:github_url: |github_link_base|/widgets/bar.md
```
# Bar (lv_bar)
## Overview
The bar object has a background and an indicator on it. The width of the indicator is set according to the current value of the bar.
Vertical bars can be created if the width of the object is smaller than its height.
Not only end, but the start value of the bar can be set which changes the start position of the indicator.
## Parts and Styles
The Bar's main part is called `LV_BAR_PART_BG` and it uses the typical background style properties.
`LV_BAR_PART_INDIC` is a virtual part which also uses all the typical background properties.
By default the indicator maximal size is the same as the background's size but setting positive padding values in `LV_BAR_PART_BG` will make the indicator smaller. (negative values will make it larger)
If the *value* style property is used on the indicator the alignment will be calculated based on the current size of the indicator.
For example a center aligned value is always shown in the middle of the indicator regardless it's current size.
## Usage
### Value and range
A new value can be set by `lv_bar_set_value(bar, new_value, LV_ANIM_ON/OFF)`.
The value is interpreted in a range (minimum and maximum values) which can be modified with `lv_bar_set_range(bar, min, max)`.
The default range is 1..100.
The new value in `lv_bar_set_value` can be set with or without an animation depending on the last parameter (`LV_ANIM_ON/OFF`).
The time of the animation can be adjusted by `lv_bar_set_anim_time(bar, 100)`. The time is in milliseconds unit.
It's also possible to set the start value of the bar using `lv_bar_set_start_value(bar, new_value, LV_ANIM_ON/OFF)`
### Modes
The bar can be drawn symmetrical to zero (drawn from zero, left to right), if it's enabled with `lv_bar_set_type(bar, LV_BAR_TYPE_SYMMETRICAL)`.
## Events
Only the [Generic events](../overview/event.html#generic-events) are sent by the object type.
Learn more about [Events](/overview/event).
## Keys
No *Keys* are processed by the object type.
Learn more about [Keys](/overview/indev).
## Example
```eval_rst
.. include:: /lv_examples/src/lv_ex_widgets/lv_ex_bar/index.rst
```
## API
```eval_rst
.. doxygenfile:: lv_bar.h
:project: lvgl
```

View File

@ -1,82 +0,0 @@
```eval_rst
.. include:: /header.rst
:github_url: |github_link_base|/widgets/btn.md
```
# Button (lv_btn)
## Overview
Buttons are simple rectangle-like objects. They are derived from [Containers](/widgets/cont) so [layout](/widgets/cont#layout) and [fit](/widgets/cont#fit) are also available.
Besides, it can be enabled to automatically go to checked state on click.
## Parts and Styles
The buttons has only a main style called `LV_BTN_PART_MAIN` and it can use all the properties from the following groups:
- background
- border
- outline
- shadow
- value
- pattern
- transitions
It also uses the *padding* properties when *layout* or *fit* is enabled.
## Usage
### States
To make buttons usage simpler the button's state can be get with `lv_btn_get_state(btn)`. It returns one of the following values:
- **LV_BTN_STATE_RELEASED**
- **LV_BTN_STATE_PRESSED**
- **LV_BTN_STATE_CHECKED_RELEASED**
- **LV_BTN_STATE_CHECKED_PRESSED**
- **LV_BTN_STATE_DISABLED**
- **LV_BTN_STATE_CHECKED_DISABLED**
With `lv_btn_set_state(btn, LV_BTN_STATE_...)` the buttons state can be changed manually.
If a more precise description of the state is required (e.g. focused) the general `lv_obj_get_state(btn)` can be used.
### Checkable
You can configure the buttons as *toggle button* with `lv_btn_set_checkable(btn, true)`. In this case, on click, the button goes to `LV_STATE_CHECKED` state automatically, or back when clicked again.
### Layout and Fit
Similarly to [Containers](/widgets/cont), buttons also have layout and fit attributes.
- `lv_btn_set_layout(btn, LV_LAYOUT_...) `set a layout. The default is `LV_LAYOUT_CENTER`.
So, if you add a label, then it will be automatically aligned to the middle and can't be moved with `lv_obj_set_pos()`.
You can disable the layout with `lv_btn_set_layout(btn, LV_LAYOUT_OFF)`.
- `lv_btn_set_fit/fit2/fit4(btn, LV_FIT_..)` enables to set the button width and/or height automatically according to the children, parent, and fit type.
## Events
Besides the [Generic events](../overview/event.html#generic-events) the following [Special events](../overview/event.html#special-events) are sent by the buttons:
- **LV_EVENT_VALUE_CHANGED** - sent when the button is toggled.
Learn more about [Events](/overview/event).
## Keys
The following *Keys* are processed by the Buttons:
- **LV_KEY_RIGHT/UP** - Go to toggled state if toggling is enabled.
- **LV_KEY_LEFT/DOWN** - Go to non-toggled state if toggling is enabled.
Note that, the state of `LV_KEY_ENTER` is translated to `LV_EVENT_PRESSED/PRESSING/RELEASED` etc.
Learn more about [Keys](/overview/indev).
## Example
```eval_rst
.. include:: /lv_examples/src/lv_ex_widgets/lv_ex_btn/index.rst
```
## API
```eval_rst
.. doxygenfile:: lv_btn.h
:project: lvgl
```

View File

@ -1,103 +0,0 @@
```eval_rst
.. include:: /header.rst
:github_url: |github_link_base|/widgets/btnmatrix.md
```
# Button matrix (lv_btnmatrix)
## Overview
The Button Matrix objects can display **multiple buttons** in rows and columns.
The main reasons for wanting to use a button matrix instead of a container and individual button objects are:
- The button matrix is simpler to use for grid-based button layouts.
- The button matrix consumes a lot less memory per button.
## Parts and Styles
The Button matrix's main part is called `LV_BTNMATRIX_PART_BG`. It draws a background using the typical background style properties.
`LV_BTNMATRIX_PART_BTN` is virtual part and it refers to the buttons on the button matrix. It also uses all the typical background properties.
The top/bottom/left/right padding values from the background are used to keep some space on the sides. Inner padding is applied between the buttons.
## Usage
### Button's text
There is a text on each button. To specify them a descriptor string array, called *map*, needs to be used.
The map can be set with `lv_btnmatrix_set_map(btnm, my_map)`.
The declaration of a map should look like `const char * map[] = {"btn1", "btn2", "btn3", ""}`.
Note that **the last element has to be an empty string**!
Use `"\n"` in the map to make **line break**. E.g. `{"btn1", "btn2", "\n", "btn3", ""}`. Each line's buttons have their width calculated automatically.
### Control buttons
The **buttons width** can be set relative to the other button in the same line with `lv_btnmatrix_set_btn_width(btnm, btn_id, width)`
E.g. in a line with two buttons: *btnA, width = 1* and *btnB, width = 2*, *btnA* will have 33 % width and *btnB* will have 66 % width.
It's similar to how the [`flex-grow`](https://developer.mozilla.org/en-US/docs/Web/CSS/flex-grow) property works in CSS.
In addition to width, each button can be customized with the following parameters:
- **LV_BTNMATRIX_CTRL_HIDDEN** - make a button hidden (hidden buttons still take up space in the layout, they are just not visible or clickable)
- **LV_BTNMATRIX_CTRL_NO_REPEAT** - disable repeating when the button is long pressed
- **LV_BTNMATRIX_CTRL_DISABLED** - make a button disabled
- **LV_BTNMATRIX_CTRL_CHECKABLE** - enable toggling of a button
- **LV_BTNMATRIX_CTRL_CHECK_STATE** - set the toggle state
- **LV_BTNMATRIX_CTRL_CLICK_TRIG** - if 0, the button will react on press, if 1, will react on release
The set or clear a button's control attribute, use `lv_btnmatrix_set_btn_ctrl(btnm, btn_id, LV_BTNM_CTRL_...)` and
`lv_btnmatrix_clear_btn_ctrl(btnm, btn_id, LV_BTNM_CTRL_...)` respectively. More `LV_BTNM_CTRL_...` values can be *Or*ed
The set/clear the same control attribute for all buttons of a button matrix, use `lv_btnmatrix_set_btn_ctrl_all(btnm, btn_id, LV_BTNM_CTRL_...)` and
`lv_btnmatrix_clear_btn_ctrl_all(btnm, btn_id, LV_BTNM_CTRL_...)`.
The set a control map for a button matrix (similarly to the map for the text), use `lv_btnmatrix_set_ctrl_map(btnm, ctrl_map)`.
An element of `ctrl_map` should look like `ctrl_map[0] = width | LV_BTNM_CTRL_NO_REPEAT | LV_BTNM_CTRL_TGL_ENABLE`.
The number of elements should be equal to the number of buttons (excluding newlines characters).
### One check
The "One check" feature can be enabled with `lv_btnmatrix_set_one_check(btnm, true)` to allow only one button to be checked (toggled) at once.
### Recolor
The **texts** on the button can be **recolored** similarly to the recolor feature for [Label](/widgets/label) object. To enable it, use `lv_btnmatrix_set_recolor(btnm, true)`.
After that a button with `#FF0000 Red#` text will be red.
### Aligning the button's text
To align the text on the buttons, use `lv_btnmatrix_set_align(roller, LV_LABEL_ALIGN_LEFT/CENTER/RIGHT)`.
All text items in the button matrix will conform to the alignment proprty as it is set.
### Notes
The Button matrix object is very light weighted because the buttons are not created just virtually drawn on the fly.
This way, 1 button use only 8 extra bytes instead of the ~100-150 byte size of a normal [Button](/widgets/btn) object (plus the size of its container and a label for each button).
The disadvantage of this setup is that the ability to style individual buttons to be different from others is limited (aside from the toggling feature).
If you require that ability, using individual buttons is very likely to be a better approach.
## Events
Besides the [Generic events](../overview/event.html#generic-events), the following [Special events](../overview/event.html#special-events) are sent by the button matrices:
- **LV_EVENT_VALUE_CHANGED** - sent when the button is pressed/released or repeated after long press. The event data is set to the ID of the pressed/released button.
Learn more about [Events](/overview/event).
## Keys
The following *Keys* are processed by the Buttons:
- **LV_KEY_RIGHT/UP/LEFT/RIGHT** - To navigate among the buttons to select one
- **LV_KEY_ENTER** - To press/release the selected button
Learn more about [Keys](/overview/indev).
## Example
```eval_rst
.. include:: /lv_examples/src/lv_ex_widgets/lv_ex_btnmatrix/index.rst
```
## API
```eval_rst
.. doxygenfile:: lv_btnmatrix.h
:project: lvgl
```

View File

@ -1,82 +0,0 @@
```eval_rst
.. include:: /header.rst
:github_url: |github_link_base|/widgets/calendar.md
```
# Calendar (lv_calendar)
## Overview
The Calendar object is a classic calendar which can:
- highlight the current day
- highlight any user-defined dates
- display the name of the days
- go the next/previous month by button click
- highlight the clicked day
## Parts and Styles
The calendar's main part is called `LV_CALENDAR_PART_BG`. It draws a background using the typical background style properties.
Besides the following virtual parts exist:
- `LV_CALENDAR_PART_HEADER` The upper area where the current year and month's name is shown. It also has buttons to move the next/previous month.
It uses typical background properties plus padding to adjust its size and margin to set the distance from the top of the calendar and the day names below it.
- `LV_CALENDAR_PART_DAY_NAMES` Shows the name of the days below the header. It uses the *text* style properties padding to keep some distance from the background (left, right), header (top) and dates (bottom).
- `LV_CALENDAR_PART_DATES` Show the date numbers from 1..28/29/30/31 (depending on current month). Different "state" of the states are drawn according to the states defined in this part:
- normal dates: drawn with `LV_STATE_DEFAULT` style
- pressed date: drawn with `LV_STATE_PRESSED` style
- today: drawn with `LV_STATE_FOCUSED` style
- highlighted dates: drawn with `LV_STATE_CHECKED` style
## Usage
## Overview
To set and get dates in the calendar, the `lv_calendar_date_t` type is used which is a structure with `year`, `month` and `day` fields.
### Current date
To set the current date (today), use the `lv_calendar_set_today_date(calendar, &today_date)` function.
### Shown date
To set the shown date, use `lv_calendar_set_shown_date(calendar, &shown_date)`;
### Highlighted days
The list of highlighted dates should be stored in a `lv_calendar_date_t` array loaded by `lv_calendar_set_highlighted_dates(calendar, &highlighted_dates)`.
Only the arrays pointer will be saved so the array should be a static or global variable.
### Name of the days
The name of the days can be adjusted with `lv_calendar_set_day_names(calendar, day_names)` where `day_names` looks like `const char * day_names[7] = {"Su", "Mo", ...};`
### Name of the months
Similarly to `day_names`, the name of the month can be set with `lv_calendar_set_month_names(calendar, month_names_array)`.
## Events
Besides the [Generic events](../overview/event.html#generic-events), the following [Special events](../overview/event.html#special-events) are sent by the calendars:
**LV_EVENT_VALUE_CHANGED** is sent when the current month has changed.
In *Input device related* events, `lv_calendar_get_pressed_date(calendar)` tells which day is currently being pressed or return `NULL` if no date is pressed.
## Keys
No *Keys* are processed by the object type.
Learn more about [Keys](/overview/indev).
## Example
```eval_rst
.. include:: /lv_examples/src/lv_ex_widgets/lv_ex_calendar/index.rst
```
## API
```eval_rst
.. doxygenfile:: lv_calendar.h
:project: lvgl
```

View File

@ -1,81 +0,0 @@
```eval_rst
.. include:: /header.rst
:github_url: |github_link_base|/widgets/checkbox.md
```
# Checkbox (lv_cb)
## Overview
The Checkbox objects are built from a [Button](/widgets/btn) background which contains an also Button *bullet* and a [Label](/widgets/label) to realize a classical checkbox.
## Parts and Styles
The Check box's main part is called `LV_CHECKBOX_PART_BG`. It's a container for a "bullet" and a text next to it. The background uses all the typical background style properties.
The bullet is real [lv_obj](/widgets/obj) object and can be referred with `LV_CHECKBOX_PART_BULLET`.
The bullet automatically inherits the state of the background. So the background is pressed the bullet goes to pressed state as well.
The bullet also uses all the typical background style properties.
There is not dedicated part for the label. Its styles can be set in the background's styles because the *text* styles properties are always inherited.
## Usage
### Text
The text can be modified by the `lv_checkbox_set_text(cb, "New text")` function. It will dynamically allocate the text.
To set a static text, use `lv_checkbox_set_static_text(cb, txt)`. This way, only a pointer of `txt` will be stored and it shouldn't be deallocated while the checkbox exists.
### Check/Uncheck
You can manually check / un-check the Checkbox via `lv_checkbox_set_checked(cb, true/false)`. Setting `true` will check the checkbox and `false` will un-check the checkbox.
### Disabled
To make the Checkbox disabled, use `lv_checkbox_set_disabled(cb, true)`.
### Get/Set Checkbox State
You can get the current state of the Checkbox with the `lv_checkbox_get_state(cb)` function which returns the current state.
You can set the current state of the Checkbox with the `lv_checkbox_set_state(cb, state)`.
The available states as defined by the enum `lv_btn_state_t` are:
- **LV_BTN_STATE_RELEASED**
- **LV_BTN_STATE_PRESSED**
- **LV_BTN_STATE_DISABLED**
- **LV_BTN_STATE_CHECKED_RELEASED**
- **LV_BTN_STATE_CHECKED_PRESSED**
- **LV_BTN_STATE_CHECKED_DISABLED**
## Events
Besides the [Generic events](../overview/event.html#generic-events) the following [Special events](../overview/event.html#special-events) are sent by the Checkboxes:
- **LV_EVENT_VALUE_CHANGED** - sent when the checkbox is toggled.
Note that, the generic input device-related events (like `LV_EVENT_PRESSED`) are sent in the inactive state too. You need to check the state with `lv_cb_is_inactive(cb)` to ignore the events from inactive Checkboxes.
Learn more about [Events](/overview/event).
## Keys
The following *Keys* are processed by the 'Buttons':
- **LV_KEY_RIGHT/UP** - Go to toggled state if toggling is enabled
- **LV_KEY_LEFT/DOWN** - Go to non-toggled state if toggling is enabled
Note that, as usual, the state of `LV_KEY_ENTER` is translated to `LV_EVENT_PRESSED/PRESSING/RELEASED` etc.
Learn more about [Keys](/overview/indev).
## Example
```eval_rst
.. include:: /lv_examples/src/lv_ex_widgets/lv_ex_checkbox/index.rst
```
## API
```eval_rst
.. doxygenfile:: lv_checkbox.h
:project: lvgl
```

View File

@ -1,72 +0,0 @@
```eval_rst
.. include:: /header.rst
:github_url: |github_link_base|/widgets/cont.md
```
# Container (lv_cont)
## Overview
The containers are essentially a **basic object** with layout and automatic sizing features features.
## Parts and Styles
The containers has only a main style called `LV_CONT_PART_MAIN` and it can use all the typicaly bacground properties properties and padding for layout auto sizing.
## Usage
### Layout
You can apply a layout on the containers to automatically order their children. The layout spacing comes from the style's `pad` properties. The possible layout options:
- **LV_LAYOUT_OFF** - Do not align the children.
- **LV_LAYOUT_CENTER** - Align children to the center in column and keep `pad_inner` space between them.
- **LV_LAYOUT_COLUMN_LEFT** - Align children in a left-justified column. Keep `pad_left` space on the left, `pad_top` space on the top and `pad_inner` space between the children.
- **LV_LAYOUT_COLUMN_MID** - Align children in centered column. Keep `pad_top` space on the top and `pad_inner` space between the children.
- **LV_LAYOUT_COLUMN_RIGHT** - Align children in a right-justified column. Keep `pad_right` space on the right, `pad_top` space on the top and `pad_inner` space between the children.
- **LV_LAYOUT_ROW_TOP** - Align children in a top justified row. Keep `pad_left` space on the left, `pad_top` space on the top and `pad_inner` space between the children.
- **LV_LAYOUT_ROW_MID** - Align children in centered row. Keep `pad_left` space on the left and `pad_inner` space between the children.
- **LV_LAYOUT_ROW_BOTTOM** - Align children in a bottom justified row. Keep `pad_left` space on the left, `pad_bottom` space on the bottom and `pad_inner` space between the children.
- **LV_LAYOUT_PRETTY_TOP** - Put as many objects as possible in a row (with at least `pad_inner` space and `pad_left/right` space on the sides). Divide the space in each line equally between the children.
If here are children with different height in a row align their top edge.
- **LV_LAYOUT_PRETTY_MID** - Same as `LV_LAYOUT_PRETTY_TOP` but if here are children with different height in a row align their middle line.
- **LV_LAYOUT_PRETTY_BOTTOM** - Same as `LV_LAYOUT_PRETTY_TOP` but if here are children with different height in a row align their bottom line.
- **LV_LAYOUT_GRID** - Similar to `LV_LAYOUT_PRETTY` but not divide horizontal space equally just let `pad_left/right` on the edges and `pad_inner` space between the elements.
### Autofit
Container have an autofit feature which can automatically change the size of the container according to its children and/or its parent. The following options exist:
- **LV_FIT_NONE** - Do not change the size automatically.
- **LV_FIT_TIGHT** - Shrink-wrap the container around all of its children, while keeping `pad_top/bottom/left/right` space on the edges.
- **LV_FIT_PARENT** - Set the size to the parent's size minus `pad_top/bottom/left/right` (from the parent's style) space.
- **LV_FIT_MAX** - Use `LV_FIT_PARENT` while smaller than the parent and `LV_FIT_TIGHT` when larger. It will ensure that the container is, at minimum, the size of its parent.
To set the auto fit mode for all directions, use `lv_cont_set_fit(cont, LV_FIT_...)`.
To use different auto fit horizontally and vertically, use `lv_cont_set_fit2(cont, hor_fit_type, ver_fit_type)`.
To use different auto fit in all 4 directions, use `lv_cont_set_fit4(cont, left_fit_type, right_fit_type, top_fit_type, bottom_fit_type)`.
## Events
Only the [Generic events](../overview/event.html#generic-events) are sent by the object type.
Learn more about [Events](/overview/event).
## Keys
No *Keys* are processed by the object type.
Learn more about [Keys](/overview/indev).
## Example
```eval_rst
.. include:: /lv_examples/src/lv_ex_widgets/lv_ex_cont/index.rst
```
## API
```eval_rst
.. doxygenfile:: lv_cont.h
:project: lvgl
```

94
docs/widgets/core/arc.md Normal file
View File

@ -0,0 +1,94 @@
```eval_rst
.. include:: /header.rst
:github_url: |github_link_base|/widgets/arc.md
```
# Arc (lv_arc)
## Overview
The Arc are consists of a background and a foreground arc. The foregrond (indicator) arc can be adjusted by finger.
## Parts and Styles
- `LV_PART_MAIN` It draws a background using the typical background style properties and an arc using the arc style properties. The arc's size and position will respect the *padding* style properties.
- `LV_PART_INDICATOR` It draws an other arc using the *arc* style properties. It's padding values are interpreted relative to the background arc.
- `LV_PART_KNOB`It draws a handle on the end of the indicator. It uses all background properties and padding values. With zero padding the knob size is the same as the indicator's width.
Larger padding makes it larger, smaller padding makes it smaller.
## Usage
### Value and range
A new value can be set by `lv_arc_set_value(arc, new_value)`.
The value is interpreted in a range (minimum and maximum values) which can be modified with `lv_arc_set_range(arc, min, max)`.
The default range is 1..100.
The indicator arc is drawn on the main part's arc. That is if the vale is set to maximum the indicator arc will cover the entire "background" arc.
To set the start and end angl of the background arc use the `lv_arc_set_bg_angles(arc, start_angle, end_angle)` function or `lv_arc_set_bg_start/end_angle(arc, start_angle)`.
Zero degree is at the middle right (3 o'clock) of the object and the degrees are increasing in clockwise direction.
The angles should be in [0;360] range.
### Rotation
An offset to the 0 degree position can added with `lv_arc_set_rotation(arc, deg)`.
### Mode
The arc can be one of the following modes:
- `LV_ARC_MODE_NORMAL` The indicator arc is drawn from the minimimum value to the current.
- `LV_ARC_MODE_REVERSE` The indicator arc is drawn counter clockwise from the maximum value to the current.
- `LV_ARC_MODE_SYMMETRICAL` The indicator arc is drawn from the middle point to the current value.
The mode can be set by `lv_arc_set_mode(arc, LV_ARC_MODE_...)` and used only if the the angle is set by `lv_arc_set_value()` or the arc is adjusted by finger.
### Change rate
If the the arc is pressed the current value will set with a limited speed according to the set *change rate*.
The change rate is defined in degree/second unit and can be set with `lv_arc_set_change_rage(arc, rate)`
### Setting the indicator manually
It also possible to set the angles o the indicator arc directly with `lv_arc_set_angles(arc, start_angle, end_angle)` function or `lv_arc_set_start/end_angle(arc, start_angle)` sets the angles of the indicator arc.
In this case the set "value" and "mode" is ignored.
In other words, settings angles and values are independent. You should use either value and angle settings. Mixing the two might result unintended behavior.
To make the arc non-adjutabe remove the style of the knob and make the object non-clickable:
```c
lv_obj_remove_style(arc, NULL, LV_PART_KNOB);
lv_obj_clear_flag(arc, LV_OBJ_FLAG_CLICKABLE);
```
## Events
- `LV_EVENT_VALUE_CHANGED` sent when the arc is pressed/dragged to set a new value.
- `LV_EVENT_DRAW_PART_BEGIN` and `LV_EVENT_DRAW_PART_END` are sent for the background rectangle, the background arc, the foreground arc and the knob to allow hooking the drawing.
For more detail on the backround rectangle part see the [Base object](/widgets/obj#events)'s documentation. The fields of `lv_obj_draw_dsc_t` is set like the followings:
- For both arcs: `clip_area`, `p1` (center of the arc), `radius`, `arc_dsc`, `part`.
- For the knob: `clip_area`, `draw_area`, `rect_dsc`, `part`.
Learn more about [Events](/overview/event).
## Keys
- `LV_KEY_RIGHT/UP` Increases the value by one.
- `LV_KEY_LEFT/DOWN` Decreases the value by one.
Learn more about [Keys](/overview/indev).
## Example
```eval_rst
.. include:: ../../../examples/widgets/arc/index.rst
```
## API
```eval_rst
.. doxygenfile:: lv_arc.h
:project: lvgl
```

62
docs/widgets/core/bar.md Normal file
View File

@ -0,0 +1,62 @@
```eval_rst
.. include:: /header.rst
:github_url: |github_link_base|/widgets/bar.md
```
# Bar (lv_bar)
## Overview
The bar object has a background and an indicator on it. The width of the indicator is set according to the current value of the bar.
Vertical bars can be created if the width of the object is smaller than its height.
Not only the end, but the start value of the bar can be set which changes the start position of the indicator.
## Parts and Styles
- `LV_PART_MAIN` The background of the bar and it uses the typical background style properties. Adding padding makes the indicator smaller or larger. The `anim_time` style property sets the animation time if the values set with `LV_ANIM_ON`.
- `LV_PART_INDICATOR` The indicator and it also also uses all the typical background properties.
## Usage
### Value and range
A new value can be set by `lv_bar_set_value(bar, new_value, LV_ANIM_ON/OFF)`.
The value is interpreted in a range (minimum and maximum values) which can be modified with `lv_bar_set_range(bar, min, max)`.
The default range is 1..100.
The new value in `lv_bar_set_value` can be set with or without an animation depending on the last parameter (`LV_ANIM_ON/OFF`).
### Modes
The bar can be one the following modes:
- `LV_BAR_MODE_NORMAL` A normal bar as described above
- `LV_BAR_SYMMETRICAL` Draw the indicator form the zero value to current value. Requires negaitve minimum range and positive maximum range.
- `LV_BAR_RANGE` Allows setting the setar value too by `lv_bar_set_start_value(bar, new_value, LV_ANIM_ON/OFF)`. The start value has to be always smaller than the end value.
## Events
- `LV_EVENT_DRAW_PART_BEGIN` and `LV_EVENT_DRAW_PART_END` are sent for both main and indicator parts to allow hooking the drawing.
The for more detail on the main part see the [Base object](/widgets/obj#events)'s documentation.
For the indicator the following fields are used: `clip_area`, `draw_area`, `rect_dsc`, `part`.
Learn more about [Events](/overview/event).
## Keys
No *Keys* are processed by the object type.
Learn more about [Keys](/overview/indev).
## Example
```eval_rst
.. include:: ../../../examples/widgets/bar/index.rst
```
## API
```eval_rst
.. doxygenfile:: lv_bar.h
:project: lvgl
```

50
docs/widgets/core/btn.md Normal file
View File

@ -0,0 +1,50 @@
```eval_rst
.. include:: /header.rst
:github_url: |github_link_base|/widgets/btn.md
```
# Button (lv_btn)
## Overview
Buttons has no new features compared to the [Base object](/widgets/obj). It usufule for semantic purposes and has slightly different default settings.
Buttons differ from Base object in the following points by default:
- Not scrollable
- Added to the default group
- Its default height and width is `LV_SIZE_CONTENT`
## Parts and Styles
- `LV_PART_MAIN` The background of the button. It uses the typical background style properties.
## Usage
There are no new features compared to [Base object](/widgets/obj).
## Events
- `LV_EVENT_VALUE_CHANGED` when the `LV_OBJ_FLAG_CHECKABLE` flag is enabled and the obejct clicked (on transition to/from the checked state)
Learn more about [Events](/overview/event).
## Keys
If `LV_OBJ_FLAG_CHECKABLE` is enabled `LV_KEY_RIGHT` and `LV_KEY_UP` makes the object checked, and `LV_KEY_LEFT` and `LV_KEY_DOWN` makes it unchecked.
Note that, the state of `LV_KEY_ENTER` is translated to `LV_EVENT_PRESSED/PRESSING/RELEASED` etc.
Learn more about [Keys](/overview/indev).
## Example
```eval_rst
.. include:: ../../../examples/widgets/btn/index.rst
```
## API
```eval_rst
.. doxygenfile:: lv_btn.h
:project: lvgl
```

View File

@ -0,0 +1,96 @@
```eval_rst
.. include:: /header.rst
:github_url: |github_link_base|/widgets/btnmatrix.md
```
# Button matrix (lv_btnmatrix)
## Overview
The Button Matrix objects can display multiple buttons in rows and columns.
The Button matrix object is very light weighted because the buttons are not created just virtually drawn on the fly.
This way, 1 button use only 8 extra bytes instead of the ~100-150 byte size of a normal [Button](/widgets/core/btn) object and other ~100 byte for the size of the [Label](/widgets/core/label) object.
The Button matrix is added to the deafult group (if it is set). Besides the Button matrix is an editable object to allow selecting and clicing the buttons with encoder navigation too.
## Parts and Styles
- `LV_PART_MAIN` The bacground of the button matrix. It uses the typical background style properties. `pad_row` and `pad_column` sets the space between the buttons.
- `LV_PART_ITEMS` The buttons and they all use the text and typical background style properties expect translations and transformations.
## Usage
### Button's text
There is a text on each button. To specify them a descriptor string array, called *map*, needs to be used.
The map can be set with `lv_btnmatrix_set_map(btnm, my_map)`.
The declaration of a map should look like `const char * map[] = {"btn1", "btn2", "btn3", NULL}`.
Note that, the last element has to be `NULL` or an empty string (`""`)!
Use `"\n"` in the map to make **line break**. E.g. `{"btn1", "btn2", "\n", "btn3", ""}`. Each line's buttons have their width calculated automatically.
So in the example the first row will have 2 buttons each with 50% width and a second row with 1 button having 100% width.
### Control buttons
The buttons' width can be set relative to the other button in the same row with `lv_btnmatrix_set_btn_width(btnm, btn_id, width)`
E.g. in a line with two buttons: *btnA, width = 1* and *btnB, width = 2*, *btnA* will have 33 % width and *btnB* will have 66 % width.
It's similar to how the [`flex-grow`](https://developer.mozilla.org/en-US/docs/Web/CSS/flex-grow) property works in CSS.
The width's value mus be in the \[1..7\] range and the deafult width is 1.
In addition to the width, each button can be customized with the following parameters:
- `LV_BTNMATRIX_CTRL_HIDDEN` Makes a button hidden (hidden buttons still take up space in the layout, they are just not visible or clickable)
- `LV_BTNMATRIX_CTRL_NO_REPEAT` Disable repeating when the button is long pressed
- `LV_BTNMATRIX_CTRL_DISABLED` Makes a button disabled Like `LV_STATE_DISABLED` on normal objects
- `LV_BTNMATRIX_CTRL_CHECKABLE` Enable toggling of a button. I.e. `LV_STATE_CHECHED` will be added/removed as the button is clicked
- `LV_BTNMATRIX_CTRL_CHECKED` MAke the button checked. It will use the `LV_STATE_CHECHKED` styles.
- `LV_BTNMATRIX_CTRL_CLICK_TRIG` Enabled: send LV_EVENT_VALUE_CHANGE on CLICK, Disabled: send LV_EVENT_VALUE_CHANGE on PRESS*/
- `LV_BTNMATRIX_CTRL_RECOLOR` Enable recoloring of button texts with `#`. E.g. `"It's #ff0000 red#"`
- `LV_BTNMATRIX_CTRL_CUSTOM_1` Custom free to use flag
- `LV_BTNMATRIX_CTRL_CUSTOM_2` Custom free to use flag
By deafult all flags are disabled.
To set or clear a button's control attribute, use `lv_btnmatrix_set_btn_ctrl(btnm, btn_id, LV_BTNM_CTRL_...)` and
`lv_btnmatrix_clear_btn_ctrl(btnm, btn_id, LV_BTNMATRIX_CTRL_...)` respectively. More `LV_BTNM_CTRL_...` values can be OR-ed
To set/clear the same control attribute for all buttons of a button matrix, use `lv_btnmatrix_set_btn_ctrl_all(btnm, btn_id, LV_BTNM_CTRL_...)` and
`lv_btnmatrix_clear_btn_ctrl_all(btnm, btn_id, LV_BTNMATRIX_CTRL_...)`.
The set a control map for a button matrix (similarly to the map for the text), use `lv_btnmatrix_set_ctrl_map(btnm, ctrl_map)`.
An element of `ctrl_map` should look like `ctrl_map[0] = width | LV_BTNM_CTRL_NO_REPEAT | LV_BTNM_CTRL_CHECHKABLE`.
The number of elements should be equal to the number of buttons (excluding newlines characters).
### One check
The "One check" feature can be enabled with `lv_btnmatrix_set_one_check(btnm, true)` to allow only one button to be checked at once.
## Events
- `LV_EVENT_VALUE_CHANGED` Sent when a button is pressed/released or repeated after long press. The event paramter is set to the ID of the pressed/released button.
- `LV_EVENT_DRAW_PART_BEGIN` and `LV_EVENT_DRAW_PART_END` are sent for both the main and the items (buttons) parts to allow hooking the drawing.
The for more detail on the main part see the [Base object](/widgets/obj#events)'s documentation.
For the buttons the following fields are used: `clip_area`, `draw_area`, `rect_dsc`, `rect_dsc`, `part`, `id` (index of the button being drawn).
`lv_btnmatrix_get_selected_btn(btnm)` returns the index of the lastly pressed, released or focused button or `LV_BTNMATRIX_BTN_NONE` if no such button.
`lv_btnmatrix_get_btn_text(btnm, btn_id)` returns a pointer to the text of `btn_id`th button.
Learn more about [Events](/overview/event).
## Keys
- `LV_KEY_RIGHT/UP/LEFT/RIGHT` To navigate among the buttons to select one
- `LV_KEY_ENTER` To press/release the selected button
Learn more about [Keys](/overview/indev).
## Example
```eval_rst
.. include:: ../../../examples/widgets/btnmatrix/index.rst
```
## API
```eval_rst
.. doxygenfile:: lv_btnmatrix.h
:project: lvgl
```

View File

@ -7,12 +7,13 @@
## Overview
A Canvas inherites from [Image](/widgets/img) where the user can draw anything. Rectangles, texts, images, lines arcs can be drawn here using lvgl's drawing engine.
A Canvas inherites from [Image](/widgets/core/img) where the user can draw anything.
Rectangles, texts, images, lines, arcs can be drawn here using lvgl's drawing engine.
Besides some "effects" can be applied as well like rotation, zoom and blur.
## Parts and Styles
The Canvas has on one main part called `LV_CANVAS_PART_MAIN` and only the *image_recolor* property is used to give a color to `LV_IMG_CF_ALPHA_1/2/4/8BIT` images.
`LV_PART_MAIN` Uses the typical rectangle style properties and image style properties.
## Usage
@ -21,38 +22,42 @@ The Canvas needs a buffer which stores the drawn image.
To assign a buffer to a Canvas, use `lv_canvas_set_buffer(canvas, buffer, width, height, LV_IMG_CF_...)`.
Where `buffer` is a static buffer (not just a local variable) to hold the image of the canvas.
For example,
`static lv_color_t buffer[LV_CANVAS_BUF_SIZE_TRUE_COLOR(width, height)]`. `LV_CANVAS_BUF_SIZE_...` macros help to determine the size of the buffer with different color formats.
`static lv_color_t buffer[LV_CANVAS_BUF_SIZE_TRUE_COLOR(width, height)]`.
`LV_CANVAS_BUF_SIZE_...` macros help to determine the size of the buffer with different color formats.
The canvas supports all the built-in color formats like `LV_IMG_CF_TRUE_COLOR` or `LV_IMG_CF_INDEXED_2BIT`.
See the full list in the [Color formats](/overview/image.html#color-formats) section.
### Palette
For `LV_IMG_CF_INDEXED_...` color formats, a palette needs to be initialized with `lv_canvas_set_palette(canvas, 3, LV_COLOR_RED)`. It sets pixels with *index=3* to red.
### Indexed colors
For `LV_IMG_CF_INDEXED_1/2/4/8` color formats a palette needs to be
initialized with `lv_canvas_set_palette(canvas, 3, LV_COLOR_RED)`. It sets pixels with *index=3* to red.
### Drawing
To set a pixel on the canvas, use `lv_canvas_set_px(canvas, x, y, LV_COLOR_RED)`.
With `LV_IMG_CF_INDEXED_...` or `LV_IMG_CF_ALPHA_...`, the index of the color or the alpha value needs to be passed as color. E.g. `lv_color_t c; c.full = 3;`
With `LV_IMG_CF_INDEXED_...` or `LV_IMG_CF_ALPHA_...`, the index of the color or the alpha value needs to be passed as color.
E.g. `lv_color_t c; c.full = 3;`
`lv_canvas_fill_bg(canvas, LV_COLOR_BLUE, LV_OPA_50)` fills the whole canvas to blue with 50% opacity. Note that, if the current color format doesn't support colors (e.g. `LV_IMG_CF_ALPHA_2BIT`) teh color will be ignored.
`lv_canvas_fill_bg(canvas, LV_COLOR_BLUE, LV_OPA_50)` fills the whole canvas to blue with 50% opacity. Note that, if the current color format doesn't support colors (e.g. `LV_IMG_CF_ALPHA_2BIT`) the color will be ignored.
Similarly, if opacity is not supported (e.g. `LV_IMG_CF_TRUE_COLOR`) it will be ignored.
An array of pixels can be copied to the canvas with `lv_canvas_copy_buf(canvas, buffer_to_copy, x, y, width, height)`. The color format of the buffer and the canvas need to match.
An array of pixels can be copied to the canvas with `lv_canvas_copy_buf(canvas, buffer_to_copy, x, y, width, height)`.
The color format of the buffer and the canvas need to match.
To draw something to the canvas use
- `lv_canvas_draw_rect(canvas, x, y, width, heigth, &draw_dsc)`
- `lv_canvas_draw_text(canvas, x, y, max_width, &draw_dsc, txt, LV_LABEL_ALIGN_LEFT/CENTER/RIGHT)`
- `lv_canvas_draw_text(canvas, x, y, max_width, &draw_dsc, txt)`
- `lv_canvas_draw_img(canvas, x, y, &img_src, &draw_dsc)`
- `lv_canvas_draw_line(canvas, point_array, point_cnt, &draw_dsc)`
- `lv_canvas_draw_polygon(canvas, points_array, point_cnt, &draw_dsc)`
- `lv_canvas_draw_arc(canvas, x, y, radius, start_angle, end_angle, &draw_dsc)`
`draw_dsc` is a `lv_draw_rect/label/img/line_dsc_t` variable which should be first initialized with `lv_draw_rect/label/img/line_dsc_init()` function and then it's filed should be modified with the desired colors and other values.
`draw_dsc` is a `lv_draw_rect/label/img/line/arc_dsc_t` variable which should be first initialized with `lv_draw_rect/label/img/line/arc_dsc_init()` function and then it's filed should be modified with the desired colors and other values.
The draw function can draw to any color format. For example, it's possible to draw a text to an `LV_IMG_VF_ALPHA_8BIT` canvas and use the result image as a mask in [lv_objmask](/widgets/objmask) later.
The draw function can draw to any color format. For example, it's possible to draw a text to an `LV_IMG_VF_ALPHA_8BIT` canvas and use the result image as a [draw mask](/overview/drawing) later.
### Transformations
`lv_canvas_transform()` can be used to rotate and/or scale the image of an image and store the result on the canvas. The function needs the following parameters:
`lv_canvas_transform()` can be used to rotate and/or scale the image of an image and store the result on the canvas.
The function needs the following parameters:
- `canvas` pointer to a canvas object to store the result of the transformation.
- `img pointer` to an image descriptor to transform. Can be the image descriptor of an other canvas too (`lv_canvas_get_img()`).
- `angle` the angle of rotation (0..3600), 0.1 deg resolution
@ -65,14 +70,12 @@ The draw function can draw to any color format. For example, it's possible to dr
Note that a canvas can't be rotated on itself. You need a source and destination canvas or image.
## Blur
A given area of the canvas can be blurred horizontally with `lv_canvas_blur_hor(canvas, &area, r)` to vertically with `lv_canvas_blur_ver(canvas, &area, r)`.
### Blur
A given area of the canvas can be blurred horizontally with `lv_canvas_blur_hor(canvas, &area, r)` or vertically with `lv_canvas_blur_ver(canvas, &area, r)`.
`r` is the radius of the blur (greater value means more intensive burring). `area` is the area where the blur should be applied (interpreted relative to the canvas)
## Events
As default the clicking of a canvas is disabled (inherited by [Image](/widgets/img)) and therefore no events are generated.
If clicking is enabled (`lv_obj_set_click(canvas, true)`) only the [Generic events](../overview/event.html#generic-events) are sent by the object type.
The same events are sent than for the [Images](/widgets/core/img).
Learn more about [Events](/overview/event).
@ -84,7 +87,7 @@ Learn more about [Keys](/overview/indev).
## Example
```eval_rst
.. include:: /lv_examples/src/lv_ex_widgets/lv_ex_canvas/index.rst
.. include:: ../../../examples/widgets/canvas/index.rst
```

View File

@ -0,0 +1,74 @@
```eval_rst
.. include:: /header.rst
:github_url: |github_link_base|/widgets/checkbox.md
```
# Checkbox (lv_checkbox)
## Overview
The Checkbox object is created from a "tick box" and a label.
When the Chackbox is clicked the tick box is toggled.
## Parts and Styles
- `LV_PART_MAIN` The is the background of the Checkbox and it uses the text and all the typical backround style properties.
`pad_column` adjusts the spacing between the tickbox and the label
- `LV_PART_INDICATOR` The "tick box" is a square the uses all the typical backround style properties.
By deafult its size is equal to the height of the main part's font. Padding properties makes the tick boy larger in the respectiev directions.
The Checkbox is added to the deafult group (if it is set).
## Usage
### Text
The text can be modified by the `lv_checkbox_set_text(cb, "New text")` function.
It will dynamically allocate the text.
To set a static text,
use `lv_checkbox_set_static_text(cb, txt)`. This way, only a pointer of `txt` will be stored and it shouldn't be deallocated while the checkbox exists.
### Check, uncheck, disable
You can manually check, un-check, and disable the Checkbox by using the common state state add/clear function:
```c
lv_obj_add_state(cb, LV_STATE_CHECKED); /*Make the chekbox checked*/
lv_obj_clear_state(cb, LV_STATE_CHECKED); /*MAke the checkbox unchecked*/
lv_obj_add_state(cb, LV_STATE_CHECKED | LV_STATE_DISABLED); /*Make the checkbox checked and disabled*/
```
## Events
- `LV_EVENT_VALUE_CHANGED` Sent when the checkbox is toggled.
- `LV_EVENT_DRAW_PART_BEGIN` and `LV_EVENT_DRAW_PART_END` are sent for both main and indicator parts to allow hooking the drawing.
The for more detail on the main part see the [Base object](/widgets/obj#events)'s documentation.
For the indicator the following fields are used: `clip_area`, `draw_area`, `rect_dsc`, `part`.
Learn more about [Events](/overview/event).
## Keys
The following *Keys* are processed by the 'Buttons':
- `LV_KEY_RIGHT/UP` Go to toggled state if toggling is enabled
- `LV_KEY_LEFT/DOWN` Go to non-toggled state if toggling is enabled
- `LV_KEY_ENTER` Clicks the checkbox and toggles it
Note that, as usual, the state of `LV_KEY_ENTER` is translated to `LV_EVENT_PRESSED/PRESSING/RELEASED` etc.
Learn more about [Keys](/overview/indev).
## Example
```eval_rst
.. include:: ../../../examples/widgets/checkbox/index.rst
```
## API
```eval_rst
.. doxygenfile:: lv_checkbox.h
:project: lvgl
```

View File

@ -0,0 +1,106 @@
```eval_rst
.. include:: /header.rst
:github_url: |github_link_base|/widgets/dropdown.md
```
# Drop-down list (lv_dropdown)
## Overview
The drop-down list allows the user to select one value from a list.
The drop-down list is closed by default and displays a single value or a predefined text.
When activated (by click on the drop-down list), a list is created from which the user may select one option.
When the user selects a new value, the list is deleted.
The Drop-down list is added to the deafult group (if it is set). Besides the Drop-down list is an editable object to allow selecting an option with encoder navigation too.
## Parts and Styles
The Dropdown widgets is built from the elements: a "button" and a "list" (they are not realted to the butto and list widgets)
### Button
- `LV_PART_MAIN` The background of the button. It uses the typicaly background proeprties and text proeprties for the text on it.
- `LV_PART_INDICATOR` Typically an arrow symbol that can be an image or a text (`LV_SYMBOL`).
The button goes to `LV_STATE_CHECKED` when its opened.
### List
- `LV_PART_MAIN` The list itself and it uses the typical background proeprties. `max_height` can be used to limit the height of the list.
- `LV_PART_SCROLLBAR` The scrollbar the background, border, shadow properties and width (for its width) and right padding for the spacing on the right.
- `LV_PART_SELECTED` Refers to the currently pressed, checked or prssed+checked option.
It also uses the typical background properties.
As the list not exists when the drop-down list is closed it's not possible to simply add styles to it.
Instead the following should be done:
1. Ad an event handler to the button for `LV_EVENT_VALUE_CHANGED` (triggered when the list is opened/closed)
2. Use `lv_obj_t * list = lv_dropdown_get_list(dropdown)`
3. `if(list != NULL) {/*Add the styles to the list*/}`
Alternatively the the theme can be extended with the new styles.
## Usage
## Overview
### Set options
The options are passed to the drop-down list as a string with `lv_dropdown_set_options(dropdown, options)`. The options should be separated by `\n`. For example: `"First\nSecond\nThird"`.
The string will be saved in the drop-down list, so it can in local variable too.
The `lv_dropdown_add_option(dropdown, "New option", pos)` function inserts a new option to `pos` index.
To save memory the options can set from a static(constant) string too with `lv_dropdown_set_static_options(dropdown, options)`.
In this case the options string should be alive while the drop-down list exists and `lv_dropdown_add_option` can't be used
You can select an option manually with `lv_dropdown_set_selected(dropdown, id)`, where `id` is the index of an option.
### Get selected option
The get the currently selected option, use `lv_dropdown_get_selected(dropdown)`. It will return the *index* of the selected option.
`lv_dropdown_get_selected_str(dropdown, buf, buf_size)` copies the name of the selected option to a `buf`.
### Direction
The list can be created on any side. The default `LV_DIR_BOTTOM` can be modified by `lv_dropdown_set_dir(dropdown, LV_DIR_LEFT/RIGHT/UP/BOTTOM)` function.
If the list would be vertically out of the screen, it will aligned to the edge.
### Symbol
A symbol (typically an arrow) can be added to the drop down list with `lv_dropdown_set_symbol(dropdown, LV_SYMBOL_...)`
If the direction of the drop-down list is `LV_DIR_LEFT` the symbol will be shown on the left, else on the right.
### Show selected
The main part can either show the selected option or a static text. If a static is set with `lv_dropdown_set_text(dropdown, "Some text")` it will be shown regardless to th selected option.
Id the text text is `NULL` the selected option is displayed on the button.
### Manually open/close
To manually open or close the drop-down list the `lv_dropdown_open/close(dropdown)` function can be used.
## Events
Besides the [Generic events](../overview/event.html#generic-events), the following [Special events](../overview/event.html#special-events) are sent by the drop-down list:
- `LV_EVENT_VALUE_CHANGED` Sent when the new option is selected or the list is opened/closed.
Learn more about [Events](/overview/event).
## Keys
- `LV_KEY_RIGHT/DOWN` Select the next option.
- `LV_KEY_LEFT/UP` Select the previous option.
- `LY_KEY_ENTER` Apply the selected option (Send `LV_EVENT_VALUE_CHANGED` event and close the drop-down list).
Learn more about [Keys](/overview/indev).
## Example
```eval_rst
.. include:: ../../../examples/widgets/dropdown/index.rst
```
## API
```eval_rst
.. doxygenfile:: lv_dropdown.h
:project: lvgl
```

View File

@ -7,13 +7,12 @@
## Overview
*Images* are the basic object to display from the flash (as arrays) or externally as files. Images can display symbols (`LV_SYMBOL_...`) too.
Images are the basic object to display images from the flash (as arrays) or externally as files. Images can display symbols (`LV_SYMBOL_...`) too.
Using the [Image decoder interface](/overview/image.html#image-decoder) custom image formats can be supported as well.
## Parts and Styles
The images has only a main part called `LV_IMG_PART_MAIN` which uses the typical background style propeties to draw a background rectangle and the *image* properties.
The padding values are used to make the background virtually larger. (It won't change the image's real size but the size modification is applied only during drawing)
- `LV_PART_MAIN` A background rectangle that uses the typical background style proeprties and the image itself using teh image style proeprties.
## Usage
@ -26,49 +25,49 @@ To provide maximum flexibility, the source of the image can be:
To set the source of an image, use `lv_img_set_src(img, src)`.
To generate a **pixel array** from a PNG, JPG or BMP image, use the [Online image converter tool](https://lvgl.io/tools/imageconverter) and set the converted image with its pointer: `lv_img_set_src(img1, &converted_img_var);`
To generate a pixel array from a PNG, JPG or BMP image, use the [Online image converter tool](https://lvgl.io/tools/imageconverter) and set the converted image with its pointer: `lv_img_set_src(img1, &converted_img_var);`
To make the variable visible in the C file, you need to declare it with `LV_IMG_DECLARE(converted_img_var)`.
To use **external files**, you also need to convert the image files using the online converter tool but now you should select the binary Output format.
You also need to use LVGL's file system module and register a driver with some functions for the basic file operation. Got to the [File system](/overview/file-system) to learn more.
To use external files, you also need to convert the image files using the online converter tool but now you should select the binary output format.
You also need to use LVGL's file system module and register a driver with some functions for the basic file operation. Go to the [File system](/overview/file-system) to learn more.
To set an image sourced from a file, use `lv_img_set_src(img, "S:folder1/my_img.bin")`.
You can set a **symbol** similarly to [Labels](/widgets/label). In this case, the image will be rendered as text according to the *font* specified in the style. It enables to use of light-weighted mono-color
You can set a symbol similarly to [Labels](/widgets/core/label). In this case, the image will be rendered as text according to the *font* specified in the style. It enables to use of light-weighted mono-color
"letters" instead of real images. You can set symbol like `lv_img_set_src(img1, LV_SYMBOL_OK)`.
### Label as an image
Images and labels are sometimes used to convey the same thing. For example, to describe what a button does. Therefore, images and labels are somewhat interchangeable.
To handle these images can even display texts by using `LV_SYMBOL_DUMMY` as the prefix of the text. For example, `lv_img_set_src(img, LV_SYMBOL_DUMMY "Some text")`.
Images and labels are sometimes used to convey the same thing. For example, to describe what a button does.
Therefore, images and labels are somewhat interchangeable, that is the images can display texts by using `LV_SYMBOL_DUMMY` as the prefix of the text. For example, `lv_img_set_src(img, LV_SYMBOL_DUMMY "Some text")`.
### Transparency
The internal (variable) and external images support 2 transparency handling methods:
- **Chrome keying** - Pixels with `LV_COLOR_TRANSP` (*lv_conf.h*) color will be transparent.
- **Alpha byte** - An alpha byte is added to every pixel.
- **Chrome keying** - Pixels with `LV_COLOR_CHROMA_KEY` (*lv_conf.h*) color will be transparent.
- **Alpha byte** - An alpha byte is added to every pixel that contains the pixel's opacity
### Palette and Alpha index
Besides *True color* (RGB) color format, the following formats are also supported:
- **Indexed** - Image has a palette.
- **Alpha indexed** - Only alpha values are stored.
These options can be selected in the font converter. To learn more about the color formats, read the [Images](/overview/image) section.
These options can be selected in the image converter. To learn more about the color formats, read the [Images](/overview/image) section.
### Recolor
The images can be re-colored in run-time to any color according to the brightness of the pixels.
It is very useful to show different states (selected, inactive, pressed, etc.) of an image without storing more versions of the same image.
This feature can be enabled in the style by setting `img.intense` between `LV_OPA_TRANSP` (no recolor, value: 0) and `LV_OPA_COVER` (full recolor, value: 255).
A color can be mixed to every pixel of an image with a given intensity.
It is very useful to show different states (checked, inactive, pressed, etc.) of an image without storing more versions of the same image.
This feature can be enabled in the style by setting `img_recolor_opa` between `LV_OPA_TRANSP` (no recolor, value: 0) and `LV_OPA_COVER` (full recolor, value: 255).
The default value is `LV_OPA_TRANSP` so this feature is disabled.
The color to mix is set by `img_recolor`.
### Auto-size
It is possible to automatically set the size of the image object to the image source's width and height if enabled by the `lv_img_set_auto_size(image, true)` function.
If *auto-size* is enabled, then when a new file is set, the object size is automatically changed. Later, you can modify the size manually. The *auto-size* is enabled by default if the image is not a screen.
Is the width or height of the image object is set to `LV_SIZE_CONTENT` the obejct's size will be set according to the size of image source in the respective direction.
### Mosaic
If the object size is greater than the image size in any directions, then the image will be repeated like a mosaic.
If the object's size is greater than the image size in any directions, then the image will be repeated like a mosaic.
It's a very useful feature to create a large image from only a very narrow source.
For example, you can have a *300 x 1* image with a special gradient and set it as a wallpaper using the mosaic feature.
For example, you can have a *300 x 5* image with a special gradient and set it as a wallpaper using the mosaic feature.
### Offset
With `lv_img_set_offset_x(img, x_ofs)` and `lv_img_set_offset_y(img, y_ofs)`, you can add some offset to the displayed image.
@ -83,6 +82,8 @@ Fractional scale works as well. E.g. `281` for 10% enlargement.
To rotate the image use `lv_img_set_angle(img, angle)`. Angle has 0.1 degree precision, so for 45.8° set 458.
The `transform_zoom` and `transform_angle` style proeprties are also used to determin the final zoom and angle.
By default, the pivot point of the rotation is the center of the image. It can be changed with `lv_img_set_pivot(img, pivot_x, pivot_y)`. `0;0` is the top left corner.
The quality of the transformation can be adjusted with `lv_img_set_antialias(img, true/false)`. With enabled anti-aliasing the transformations has a higher quality but they are slower.
@ -92,12 +93,8 @@ In other words transformations work only on true color images stored as C array,
Note that, the real coordinates of image object won't change during transformation. That is `lv_obj_get_width/height/x/y()` will returned the original, non-zoomed coordinates.
## Rotate
The images can be rotated with
## Events
As by default, clicking of the image objects is disabled, only [generic](../overview/event.html#generic-events) non-input device-related events are sent.
If you want to catch all of the generic events of an image object, you should enable its clicking by using this: `lv_obj_set_click(img, true)`
No special events are sendt by the imge objects.
Learn more about [Events](/overview/event).
@ -110,7 +107,7 @@ Learn more about [Keys](/overview/indev).
```eval_rst
.. include:: /lv_examples/src/lv_ex_widgets/lv_ex_img/index.rst
.. include:: ../../../examples/widgets/img/index.rst
```

View File

@ -0,0 +1,30 @@
```eval_rst
.. include:: /header.rst
:github_url: |github_link_base|/object-types/index.md
```
# Core widgets
```eval_rst
.. toctree::
:maxdepth: 1
arc
bar
btn
btnmatrix
canvas
checkbox
dropdown
img
label
line
roller
slider
switch
table
textarea
```

View File

@ -6,13 +6,13 @@
## Overview
The Text Area is a [Page](/widgets/page) with a [Label](/widgets/label) and a cursor on it.
The Text Area is a Page with a [Label](/widgets/core/label) and a cursor on it.
Texts or characters can be added to it.
Long lines are wrapped and when the text becomes long enough the Text area can be scrolled.
## Parts and Styles
The Text area has the same parts as [Page](/widgets/page).
The Text area has the same parts as Page.
Expect `LV_PAGE_PART_SCRL` because it can't be referenced and it's always transparent.
Refer the Page's documentation of details.
@ -100,17 +100,12 @@ Using `LV_LABEL_LONG_TXT_HINT` the scrolling and drawing will as fast as with "n
A part of text can be selected if enabled with `lv_textarea_set_text_sel(textarea, true)`.
It works like when you select a text on your PC with your mouse.
### Scrollbars
The scrollbars can shown according to different policies set by `lv_textarea_set_scrollbar_mode(textarea, LV_SCRLBAR_MODE_...)`.
Learn more at the [Page](/widgets/page) object.
### Scroll propagation
When the Text area is scrolled on an other scrollable object (like a Page) and the scrolling has reached the edge of the Text area, the scrolling can be propagated to the parent.
In other words, when the Text area can be scrolled further, the parent will be scrolled instead.
It can be enabled with `lv_ta_set_scroll_propagation(ta, true)`.
Learn more at the [Page](/widgets/page) object.
### Edge flash
When the Text area is scrolled to edge a circle like flash animation can be shown if it is enabled with `lv_ta_set_edge_flash(ta, true)`
@ -133,7 +128,7 @@ Learn more about [Keys](/overview/indev).
```eval_rst
.. include:: /lv_examples/src/lv_ex_widgets/lv_ex_textarea/index.rst
.. include:: ../../../examples/widgets/textarea/index.rst
```

View File

@ -1,106 +0,0 @@
```eval_rst
.. include:: /header.rst
:github_url: |github_link_base|/widgets/dropdown.md
```
# Drop-down list (lv_dropdown)
## Overview
The drop-down list allows the user to select one value from a list.
The drop-down list is closed by default and displays a single value or a predefined text.
When activated (by click on the drop-down list), a list is created from which the user may select one option.
When the user selects a new value, the list is deleted.
## Parts and Styles
The drop-down list's main part is called `LV_DROPDOWN_PART_MAIN` which is a simple [lv_obj](/widgets/obj) object.
It uses all the typical background properties. *Pressed*, *Focused*, *Edited* etc. stiles are also applied as usual.
The list, which is created when the main object is clicked, is an [Page](/widgets/page).
Its background part can be referenced with `LV_DROPDOWN_PART_LIST` and uses all the typical background properties for the rectangle itself and text properties for the options.
To adjust the space between the options use the *text_line_space* style property.
Padding values can be used to make some space on the edges.
The scrollable part of the page is hidden and its styles are always empty (so transparent with no padding).
The scrollbar can be referenced with `LV_DROPDOWN_PART_SCRLBAR` and uses all the typical background properties.
The selected option can be referenced with `LV_DROPDOWN_PART_SELECTED` and uses all the typical background properties.
It will used in its default state to draw a rectangle on the selected option, and in pressed state to draw a rectangle on the being pressed option.
## Usage
## Overview
### Set options
The options are passed to the drop-down list as a string with `lv_dropdown_set_options(dropdown, options)`. The options should be separated by `\n`. For example: `"First\nSecond\nThird"`.
The string will be saved in the drop-down list, so it can in local variable too.
The `lv_dropdown_add_option(dropdown, "New option", pos)` function inserts a new option to `pos` index.
To save memory the options can set from a static(constant) string too with `lv_dropdown_set_static_options(dropdown, options)`.
In this case the options string should be alive while the drop-down list exists and `lv_dropdown_add_option` can't be used
You can select an option manually with `lv_dropdown_set_selected(dropdown, id)`, where _id_ is the index of an option.
### Get selected option
The get the currently selected option, use `lv_dropdown_get_selected(dropdown)`. It will return the *index* of the selected option.
`lv_dropdown_get_selected_str(dropdown, buf, buf_size)` copies the name of the selected option to a `buf`.
### Direction
The list can be created on any side. The default `LV_DROPDOWN_DOWN` can be modified by `lv_dropdown_set_dir(dropdown, LV_DROPDOWN_DIR_LEFT/RIGHT/UP/DOWN)` function.
If the list would be vertically out of the screen, it will aligned to the edge.
### Symbol
A symbol (typically an arrow) can be added to the drop down list with `lv_dropdown_set_symbol(dropdown, LV_SYMBOL_...)`
If the direction of the drop-down list is `LV_DROPDOWN_DIR_LEFT` the symbol will be shown on the left, else on the right.
### Maximum height
The maximum height of drop-down list can be set via `lv_dropdown_set_max_height(dropdown, height)`. By default it's set to 3/4 vertical resolution.
### Show selected
The main part can either show the selected option or a static text. It can controlled with `lv_dropdown_set_show_selected(sropdown, true/false)`.
The static text can be set with `lv_dropdown_set_text(dropdown, "Text")`. Only the pointer of the text is saved.
If you also don't want the selected option to be highlighted, a custom transparent style can be used for `LV_DROPDOWN_PART_SELECTED`.
### Animation time
The drop-down list's open/close animation time is adjusted by `lv_dropdown_set_anim_time(ddlist, anim_time)`. Zero animation time means no animation.
### Manually open/close
To manually open or close the drop-down list the `lv_dropdown_open/close(dropdown, LV_ANIM_ON/OFF)` function can be used.
## Events
Besides the [Generic events](../overview/event.html#generic-events), the following [Special events](../overview/event.html#special-events) are sent by the drop-down list:
- **LV_EVENT_VALUE_CHANGED** - Sent when the new option is selected.
Learn more about [Events](/overview/event).
## Keys
The following *Keys* are processed by the Buttons:
- **LV_KEY_RIGHT/DOWN** - Select the next option.
- **LV_KEY_LEFT/UP** - Select the previous option.
- **LY_KEY_ENTER** - Apply the selected option (Send `LV_EVENT_VALUE_CHANGED` event and close the drop-down list).
## Example
```eval_rst
.. include:: /lv_examples/src/lv_ex_widgets/lv_ex_dropdown/index.rst
```
## API
```eval_rst
.. doxygenfile:: lv_dropdown.h
:project: lvgl
```

View File

@ -0,0 +1,80 @@
```eval_rst
.. include:: /header.rst
:github_url: |github_link_base|/widgets/calendar.md
```
# Calendar (lv_calendar)
## Overview
The Calendar object is a classic calendar which can:
- can show the days of any month in a 7x7 matrix
- Show the name of the days
- highlight the current day
- highlight any user-defined dates
The Calendar is added to the deafult group (if it is set). Besides the Calendar is an editable object to allow selecting and clicing the dates with encoder navigation too.
To make the Calendar flexible, by default it doesn't show the curent year or month. Instead, there external "headers" that can be attached to the calendar.
## Parts and Styles
The calendar object uses the [Button matrix](/widgets/btnmatrix) object under the hood to arrange the days into a matrix.
- `LV_PART_MAIN`
- `LV_PART_ITEMS` Refers to the dates and day names. Button matrix control flags are set the to differentiate the buttons and a custom drawer event modifies the properties of the buttons
- day names haev no border, no background, drawn with a grey color
- days of the previous and next month have `LV_BTNMATRIX_CTRL_DISABLED` flag
- today has a ticker border with the themes primary color
- highlighted day have 40% opacity with the themes primary color.
## Usage
Some funnctions uses the `lv_calendar_date_t` type is used which is a structure with `year`, `month` and `day` fields.
### Current date
To set the current date (today), use the `lv_calendar_set_today_date(calendar, year, month, day)` function. `month` needs to be in 1..12 range and `day` in 1..31 range
### Shown date
To set the shown date, use `lv_calendar_set_shown_date(calendar, year, month)`;
### Highlighted days
The list of highlighted dates should be stored in a `lv_calendar_date_t` array loaded by `lv_calendar_set_highlighted_dates(calendar, highlighted_dates, date_num)`.
Only the arrays pointer will be saved so the array should be a static or global variable.
### Name of the days
The name of the days can be adjusted with `lv_calendar_set_day_names(calendar, day_names)` where `day_names` looks like `const char * day_names[7] = {"Su", "Mo", ...};`
Only the pointer of the day names is saved so the array should be a static, global or constant variables.
## Headers
### Arrow buttons
`lv_calendar_header_arrow_create(parent, calendar, button_size)` creates a header that contains a left and right arrow on the sides and atext with the current year and month between them.
### Dropdown
`lv_calendar_header_dropdown_create(parent, calendar)` creates a header that contains 2 drop-drown lists: one for the year and an other for the month.
## Events
- `LV_EVENT_VALUE_CHANGED` Sent is a data is clicked. `lv_calendar_get_pressed_date(calendar, &date)` tells which day is currently being pressed. Returns `LV_RES_OK` if theres is valid pressed data, else `LV_RES_INV`.
## Keys
- `LV_KEY_RIGHT/UP/LEFT/RIGHT` To navigate among the buttons to dates
- `LV_KEY_ENTER` To press/release the selected date
Learn more about [Keys](/overview/indev).
## Example
```eval_rst
.. include:: /lv_examples/src/lv_ex_widgets/lv_ex_calendar/index.rst
```
## API
```eval_rst
.. doxygenfile:: lv_calendar.h
:project: lvgl
```

View File

@ -0,0 +1,28 @@
```eval_rst
.. include:: /header.rst
:github_url: |github_link_base|/object-types/index.md
```
# Extra widgets
```eval_rst
.. toctree::
:maxdepth: 1
calendar
chart
colorwheel
imgbtn
keyboard
led
list
meter
msgbox
spinbox
spinner
tabview
tileview
win
```

View File

@ -1,70 +0,0 @@
```eval_rst
.. include:: /header.rst
:github_url: |github_link_base|/widgets/gauge.md
```
# Gauge (lv_gauge)
## Overview
The gauge is a meter with scale labels and one or more needles.
## Parts and Styles
The Gauge's main part is called `LV_GAUGE_PART_MAIN`. It draws a background using the typical background style properties and "minor" scale lines using the *line* and *scale* style properties.
It also uses the *text* properties to set the style of the scale labels. *pad_inner* is used to set space between the scale lines and the scale labels.
`LV_GAUGE_PART_MAJOR` is a virtual part which describes the major scale lines (where labels are added) using the *line* and *scale* style properties.
`LV_GAUGE_PART_NEEDLE` is also virtual part and it describes the needle(s) via the *line* style properties.
The *size* and the typical background properties are used to describe a rectangle (or circle) in the pivot point of the needle(s).
*pad_inner* is used to to make the needle(s) smaller than the outer radius of the scale lines.
## Usage
### Set value and needles
The gauge can show more than one needle.
Use the `lv_gauge_set_needle_count(gauge, needle_num, color_array)` function to set the number of needles and an array with colors for each needle.
The array must be static or global variable because only its pointer is stored.
You can use `lv_gauge_set_value(gauge, needle_id, value)` to set the value of a needle.
### Scale
You can use the `lv_gauge_set_scale(gauge, angle, line_num, label_cnt)` function to adjust the scale angle and the number of the scale lines and labels.
The default settings are 220 degrees, 6 scale labels, and 21 lines.
The scale of the Gauge can have offset. It can be adjusted with `lv_gauge_set_angle_offset(gauge, angle)`.
### Range
The range of the gauge can be specified by `lv_gauge_set_range(gauge, min, max)`. The default range is 0..100.
### Needle image
An images also can be used as needles. The image should point to the right (like `==>`). To set an image use `lv_gauge_set_needle_img(gauge1, &img, pivot_x, pivot_y)`. `pivot_x` and `pivot_y` are offset of the rotation center from the top left corner. Images will be recolored to the needle's color with `image_recolor_opa` intensity coming from the styles in `LV_GAUGE_PART_NEEDLE`.
### Critical value
To set a critical value, use `lv_gauge_set_critical_value(gauge, value)`. The scale color will be changed to *scale_end_color* after this value. The default critical value is 80.
## Events
Only the [Generic events](../overview/event.html#generic-events) are sent by the object type.
Learn more about [Events](/overview/event).
## Keys
No *Keys* are processed by the object type.
Learn more about [Keys](/overview/indev).
## Example
```eval_rst
.. include:: /lv_examples/src/lv_ex_widgets/lv_ex_gauge/index.rst
```
## API
```eval_rst
.. doxygenfile:: lv_gauge.h
:project: lvgl
```

View File

@ -10,39 +10,8 @@
:maxdepth: 1
obj
arc
bar
btn
btnmatrix
calendar
canvas
checkbox
chart
cont
cpicker
dropdown
gauge
img
imgbtn
keyboard
label
led
line
list
linemeter
msgbox
objmask
page
roller
slider
spinbox
spinner
switch
table
tabview
textarea
tileview
win
core/index
extra/index
```

View File

@ -1,61 +0,0 @@
```eval_rst
.. include:: /header.rst
:github_url: |github_link_base|/widgets/linemeter.md
```
# Line meter (lv_lmeter)
## Overview
The Line meter object consists of some radial lines which draw a scale. Setting a value for the Line meter will change the color of the scale lines proportionally.
## Parts and Styles
The Line meter has only a main part, called `LV_LINEMETER_PART_MAIN`. It uses all the typical background properties the draw a rectangle-like or circle background and the *line* and *scale* properties to draw the scale lines.
The active lines (which are related to smaller values the the current value) are colored from *line_color* to *scale_grad_color*. The lines in the end (after the current value) are set to *scale_end_color* color.
## Usage
### Set value
When setting a new value with `lv_linemeter_set_value(linemeter, new_value)` the proportional part of the scale will be recolored.
### Range and Angles
The `lv_linemeter_set_range(linemeter, min, max)` function sets the range of the line meter.
You can set the angle of the scale and the number of the lines by: `lv_linemeter_set_scale(linemeter, angle, line_num)`.
The default angle is 240 and the default line number is 31.
### Angle offset
By default the scale angle is interpreted symmetrically to the y axis. It results in "standing" line meter. With `lv_linemeter_set_angle_offset` an offset can be added the scale angle.
It can used e.g to put a quarter line meter into a corner or a half line meter to the right or left side.
### Mirror
By default the Line meter's lines are activated clock-wise. It can be changed using `lv_linemeter_set_mirror(linemeter, true/false)`.
## Events
Only the [Generic events](../overview/event.html#generic-events) are sent by the object type.
Learn more about [Events](/overview/event).
## Keys
No *Keys* are processed by the object type.
Learn more about [Keys](/overview/indev).
## Example
```eval_rst
.. include:: /lv_examples/src/lv_ex_widgets/lv_ex_linemeter/index.rst
```
## API
```eval_rst
.. doxygenfile:: lv_linemeter.h
:project: lvgl
```

View File

@ -10,205 +10,153 @@ The 'Base Object' implements the basic properties of widgets on a screen, such a
- coordinates
- parent object
- children
- main style
- attributes like *Click enable*, *Drag enable*, etc.
- contains the styles
- attributes like *Clickable*, *Scrollable*, etc.
In object-oriented thinking, it is the base class from which all other objects in LVGL are inherited. This, among another things, helps reduce code duplication.
In object-oriented thinking, it is the base class from which all other objects in LVGL are inherited.
The functions and functionalities of Base object can be used with other widgets too. For example `lv_obj_set_width(slider, 100)`
The Base object can be directly used as a simple widgets. It nothing else then a rectangle.
The Base object can be directly used as a simple widgets. It nothing else than a rectangle. Or from the the HTML world it's like a `<div>`.
### Coordinates
Here only a small subset of cooridnate settings is described. To see all the features of LVGL (padding, cooridnates in styles, layouts, etc) visit the [Coordinates](overview/coord) page.
#### Size
The object size can be modified on individual axes with `lv_obj_set_width(obj, new_width)` and `lv_obj_set_height(obj, new_height)`, or both axes can be modified at the same time with `lv_obj_set_size(obj, new_width, new_height)`.
Styles can add [Margin](/overview/style/#properties) to the objects. Margin tells that "I want this space around me".
To set width or height reduced by the margin `lv_obj_set_width_margin(obj, new_width)` or `lv_obj_set_height_margin(obj, new_height)`.
In more exact way: `new_width = left_margin + object_width + right_margin`.
To get the width or height which includes the margins use `lv_obj_get_width/height_margin(obj)`.
Styles can add [Padding](/overview/style/#properties) to the object as well. Padding means "I don't want my children too close to my sides, so keep this space".
To set width or height reduced by the padding `lv_obj_set_width_fit(obj, new_width)` or `lv_obj_set_height_fit(obj, new_height)`.
In a more exact way: `new_width = left_pad + object_width + right_pad`
To get the width or height which is REDUCED by padding use `lv_obj_get_width/height_fit(obj)`. It can be considered the "useful size of the object".
Margin and padding gets important when [Layout](/widget/cont#layout) or [Auto-fit](/wisgets/cont#fit) is used by other widgets.
#### Position
You can set the x and y coordinates relative to the parent with `lv_obj_set_x(obj, new_x)` and `lv_obj_set_y(obj, new_y)`, or both at the same time with `lv_obj_set_pos(obj, new_x, new_y)`.
#### Alignment
You can align the object to another with `lv_obj_align(obj, obj_ref, LV_ALIGN_..., x_ofs, y_ofs)`.
- `obj` is the object to align.
- `obj_ref` is a reference object. `obj` will be aligned to it. If `obj_ref = NULL`, then the parent of `obj` will be used.
- The third argument is the *type* of alignment. These are the possible options:
![](/misc/align.png "Alignment types in LVGL")
You can align the object on it's parent with `lv_obj_set_align(obj, LV_ALIGN_...)`. After this every x and y settings will be ralitiev to the set alignment mode.
For example a this will shift the object by 10;20 px fro mthe center of its parent.
```c
lv_obj_set_align(obj, LV_ALIGN_CENTER);
lv_obj_set_pos(obj, 10, 20);
The alignment types build like `LV_ALIGN_OUT_TOP_MID`.
- The last two arguments allow you to shift the object by a specified number of pixels after aligning it.
//Or in one function
lv_obj_align(obj, LV_ALIGN_CENTER, 10, 20);
```
To align an object to an other use `lv_obj_align_to(obj_to_align, obj_referece, LV_ALIGN_..., x, y)`
For example, to align a text below an image: `lv_obj_align(text, image, LV_ALIGN_OUT_BOTTOM_MID, 0, 10)`.
Or to align a text in the middle of its parent: `lv_obj_align(text, NULL, LV_ALIGN_CENTER, 0, 0)`.
The following align types exists:
![](/misc/align.png "Alignment types in LVGL")
`lv_obj_align_origo` works similarly to `lv_obj_align` but it aligns the center of the object.
For example, `lv_obj_align_origo(btn, image, LV_ALIGN_OUT_BOTTOM_MID, 0, 0)` will align the center of the button the bottom of the image.
The parameters of the alignment will be saved in the object if `LV_USE_OBJ_REALIGN` is enabled in *lv_conf.h*. You can then realign the objects simply by calling `lv_obj_realign(obj)`.
It's equivalent to calling `lv_obj_align` again with the same parameters.
If the alignment happened with `lv_obj_align_origo`, then it will be used when the object is realigned.
The `lv_obj_align_x/y` and `lv_obj_align_origo_x/y` function can be used t align only on one axis.
If `lv_obj_set_auto_realign(obj, true)` is used the object will be realigned automatically, if its size changes in `lv_obj_set_width/height/size()` functions.
It's very useful when size animations are applied to the object and the original position needs to be kept.
**Note that the coordinates of screens can't be changed. Attempting to use these functions on screens will result in undefined behavior.**
### Parents and children
You can set a new parent for an object with `lv_obj_set_parent(obj, new_parent)`. To get the current parent, use `lv_obj_get_parent(obj)`.
To get the children of an object, use `lv_obj_get_child(obj, child_prev)` (from last to first) or `lv_obj_get_child_back(obj, child_prev)` (from first to last).
To get the first child, pass `NULL` as the second parameter and use the return value to iterate through the children. The function will return `NULL` if there are no more children. For example:
To get a specific children of a parent use `lv_obj_get_child(parent, idx)`. Some examples for `idx`:
- `0` get the firstly (youngest) created child
- `1` get the secondly created child
- `-1` get the lastly (youngest) craeted child
The children can be iterated lke this
```c
lv_obj_t * child = lv_obj_get_child(parent, NULL);
while(child) {
/*Do something with "child" */
child = lv_obj_get_child(parent, child);
uint32_t i;
for(i = 0; i < lv_obj_get_child_cnt(parent); i++) {
lv_obj_t * child = lv_obj_get_child(paernt, i);
/*Do something with child*/
}
```
`lv_obj_count_children(obj)` tells the number of children on an object. `lv_obj_count_children_recursive(obj)` also tells the number of children but counts children of children recursively.
`lv_obj_get_child_id(obj)` tells the index of the object. That is how many younger children its parent has.
You can bring an object to the foreground or send it to the background with `lv_obj_move_foreground(obj)` and `lv_obj_move_background(obj)`.
### Screens
When you have created a screen like `lv_obj_t * screen = lv_obj_create(NULL, NULL)`, you can load it with `lv_scr_load(screen)`. The `lv_scr_act()` function gives you a pointer to the current screen.
When you have created a screen like `lv_obj_t * screen = lv_obj_create(NULL)`, you can load it with `lv_scr_load(screen)`. The `lv_scr_act()` function gives you a pointer to the current screen.
If you have more display then it's important to know that these functions operate on the lastly created or the explicitly selected (with `lv_disp_set_default`) display.
To get an object's screen use the `lv_obj_get_screen(obj)` function.
### Layers
There are two automatically generated layers:
- top layer
- system layer
They are independent of the screens and they will be shown on every screen. The *top layer* is above every object on the screen and the *system layer* is above the *top layer* too.
You can add any pop-up windows to the *top layer* freely. But, the *system layer* is restricted to system-level things (e.g. mouse cursor will be placed here in `lv_indev_set_cursor()`).
The `lv_layer_top()` and `lv_layer_sys()` functions gives a pointer to the top or system layer.
You can bring an object to the foreground or send it to the background with `lv_obj_move_foreground(obj)` and `lv_obj_move_background(obj)`.
Read the [Layer overview](/overview/layer) section to learn more about layers.
### Events
To set an event callback for an object, use `lv_obj_set_event_cb(obj, event_cb)`,
To set an event callback for an object, use `lv_obj_add_event_cb(obj, event_cb, LV_EVENT_..., user_data)`,
To manually send an event to an object, use `lv_event_send(obj, LV_EVENT_..., data)`
To manually send an event to an object, use `lv_event_send(obj, LV_EVENT_..., param)`
Read the [Event overview](/overview/event) to learn more about the events.
## Parts
The widgets can have multiple parts. For example a [Button](/widgets/btn) has only a main part but a [Slider](/widgets/slider) is built from a background, an indicator and a knob.
The name of the parts is constructed like `LV_ + <TYPE> _PART_ <NAME>`. For example `LV_BTN_PART_MAIN` or `LV_SLIDER_PART_KNOB`. The parts are usually used when styles are add to the objects.
Using parts different styles can be assigned to the different parts of the objects.
To learn more about the parts read the related section of the [Style overview](/overview/style#parts).
### States
The object can be in a combinations of the following states:
- **LV_STATE_DEFAULT** Normal, released
- **LV_STATE_CHECKED** Toggled or checked
- **LV_STATE_FOCUSED** Focused via keypad or encoder or clicked via touchpad/mouse
- **LV_STATE_EDITED**  Edit by an encoder
- **LV_STATE_HOVERED** Hovered by mouse (not supported now)
- **LV_STATE_PRESSED** Pressed
- **LV_STATE_DISABLED** Disabled or inactive
The states are usually automatically changed by the library as the user presses, releases, focuses etc an object.
However, the states can be changed manually too. To completely overwrite the current state use `lv_obj_set_state(obj, part, LV_STATE...)`.
To set or clear given state (but leave to other states untouched) use `lv_obj_add/clear_state(obj, part, LV_STATE_...)`
In both cases ORed state values can be used as well. E.g. `lv_obj_set_state(obj, part, LV_STATE_PRESSED | LV_PRESSED_CHECKED)`.
To learn more about the states read the related section of the [Style overview](/overview/style#states).
### Style
Be sure to read the [Style overview](/overview/style) first.
Be sure to read the [Style overview](/overview/style). Here or only the most essential functions are described.
To add a style to an object use `lv_obj_add_style(obj, part, &new_style)` function. The Base object use all the rectangle-like style properties.
To remove all styles from an object use `lv_obj_reset_style_list(obj, part)`
A new style can be added to an object with `lv_obj_add_style(obj, part, &new_style)` function. The Base object use all the rectangle-like style properties.
If you modify a style, which is already used by objects, in order to refresh the affected objects you can use either `lv_obj_refresh_style(obj)` on each object using it or
to notify all objects with a given style use `lv_obj_report_style_mod(&style)`. If the parameter of `lv_obj_report_style_mod` is `NULL`, all objects will be notified.
notify all objects with a given style use `lv_obj_report_style_change(&style)`. If the parameter of `lv_obj_report_style_change` is `NULL`, all objects will be notified.
### Attributes
There are some attributes which can be enabled/disabled by `lv_obj_set_...(obj, true/false)`:
### Flags
There are some attributes which can be enabled/disabled by `lv_obj_add/clear_flag(obj, LV_OBJ_FLAG_...)`:
- **hidden** - Hide the object. It will not be drawn and will be considered by input devices as if it doesn't exist., Its children will be hidden too.
- **click** - Allows you to click the object via input devices. If disabled, then click events are passed to the object behind this one. (E.g. [Labels](/widgets/label) are not clickable by default)
- **top** - If enabled then when this object or any of its children is clicked then this object comes to the foreground.
- **drag** - Enable dragging (moving by an input device)
- **drag_dir** - Enable dragging only in specific directions. Can be `LV_DRAG_DIR_HOR/VER/ALL`.
- **drag_throw** - Enable "throwing" with dragging as if the object would have momentum
- **drag_parent** - If enabled then the object's parent will be moved during dragging. It will look like as if the parent is dragged. Checked recursively, so can propagate to grandparents too.
- **parent_event** - Propagate the events to the parents too. Checked recursively, so can propagate to grandparents too.
- **opa_scale_enable** - Enable opacity scaling. See the [#opa-scale](Opa scale) section.
-`LV_OBJ_FLAG_HIDDEN` Make the object hidden. (Like it wasn't there at all)
-`LV_OBJ_FLAG_CLICKABLE` Make the object clickable by the input devices
-`LV_OBJ_FLAG_CLICK_FOCUSABLE` Add focused state to the object when clicked
-`LV_OBJ_FLAG_CHECKABLE` Toggle checked state when the object is clicked
-`LV_OBJ_FLAG_SCROLLABLE` Make the object scrollable
-`LV_OBJ_FLAG_SCROLL_ELASTIC` Allow scrolling inside but with slower speed
-`LV_OBJ_FLAG_SCROLL_MOMENTUM` Make the object scroll further when "thrown"
-`LV_OBJ_FLAG_SCROLL_ONE`Allow scrolling only one snapable children
-`LV_OBJ_FLAG_SCROLL_CHAIN` Allow propagating the scroll to a parent
-`LV_OBJ_FLAG_SCROLL_ON_FOCUS` Automatically scroll object to make it visible when focused
-`LV_OBJ_FLAG_SNAPABLE` If scroll snap is enabled on the parent it can snap to this object
-`LV_OBJ_FLAG_PRESS_LOCK` Keep the object pressed even if the press slid from the object
-`LV_OBJ_FLAG_EVENT_BUBBLE` Propagate the events to the parent too
-`LV_OBJ_FLAG_GESTURE_BUBBLE` Propagate the gestures to the parent
-`LV_OBJ_FLAG_ADV_HITTEST` Allow performing more accurate hit (click) test. E.g. consider rounded corners.
-`LV_OBJ_FLAG_IGNORE_LAYOUT` Make the object position-able by the layouts
-`LV_OBJ_FLAG_FLOATING` Do not scroll the object when the parent scrolls and ignore layout
### Protect
There are some specific actions which happen automatically in the library.
To prevent one or more that kind of actions, you can protect the object against them. The following protections exists:
- **LV_PROTECT_NONE** No protection
- **LV_PROTECT_POS** Prevent automatic positioning (e.g. Layout in [Containers](/widgets/cont))
- **LV_PROTECT_FOLLOW** Prevent the object be followed (make a "line break") in automatic ordering (e.g. Layout in [Containers](/widgets/cont))
- **LV_PROTECT_PARENT** Prevent automatic parent change. (e.g. [Page](/widgets/page) moves the children created on the background to the scrollable)
- **LV_PROTECT_PRESS_LOST** Prevent losing press when the press is slid out of the objects. (E.g. a [Button](/widgets/btn) can be released out of it if it was being pressed)
- **LV_PROTECT_CLICK_FOCUS** Prevent automatically focusing the object if it's in a *Group* and click focus is enabled.
- **LV_PROTECT_CHILD_CHG** Disable the child change signal. Used internally by the library
-`LV_OBJ_FLAG_LAYOUT_1` Custom flag, free to use by layouts
-`LV_OBJ_FLAG_LAYOUT_2` Custom flag, free to use by layouts
The `lv_obj_add/clear_protect(obj, LV_PROTECT_...)` sets/clears the protection. You can use *'OR'ed* values of protection types too.
-`LV_OBJ_FLAG_WIDGET_1` Custom flag, free to use by widget
-`LV_OBJ_FLAG_WIDGET_2` Custom flag, free to use by widget
-`LV_OBJ_FLAG_USER_1` Custom flag, free to use by user
-`LV_OBJ_FLAG_USER_2` Custom flag, free to use by user
-`LV_OBJ_FLAG_USER_3` Custom flag, free to use by user
-`LV_OBJ_FLAG_USER_4` Custom flag, free to use by usersection.
Some examples:
```c
/*Hide on object*/
lv_obj_add_flag(obj, LV_OBJ_FLAG_HIDDEN);
/*Make an obejct non-clickable*/
lv_obj_clear_flag(obj, LV_OBJ_FLAG_CLICKABLE);
```
### Groups
Read the [Input devices overview](/overview/indev) to learn more about the *Groups*.
Once, an object is added to *group* with `lv_group_add_obj(group, obj)` the object's current group can be get with `lv_obj_get_group(obj)`.
`lv_obj_is_focused(obj)` tells if the object is currently focused on its group or not. If the object is not added to a group, `false` will be returned.
Read the [Input devices overview](/overview/indev) to learn more about the *Groups*.
### Extended click area
By default, the objects can be clicked only on their coordinates, however, this area can be extended with `lv_obj_set_ext_click_area(obj, left, right, top, bottom)`.
`left/right/top/bottom` describes how far the clickable area should extend past the default in each direction.
This feature needs to enabled in *lv_conf.h* with `LV_USE_EXT_CLICK_AREA`. The possible values are:
- **LV_EXT_CLICK_AREA_FULL** store all 4 coordinates as `lv_coord_t`
- **LV_EXT_CLICK_AREA_TINY** store only horizontal and vertical coordinates (use the greater value of left/right and top/bottom) as `uint8_t`
- **LV_EXT_CLICK_AREA_OFF** Disable this feature
By default, the objects can be clicked only on their coordinates, however, this area can be extended with `lv_obj_set_ext_click_area(obj, size)`.
## Events
Only the [Generic events](../overview/event.html#generic-events) are sent by the object type.
- `LV_EVENT_VALUE_CHANGED` when the `LV_OBJ_FLAG_CHECKABLE` flag is enabled and the obejct clicked (on transition to/from the checked state)
Learn more about [Events](/overview/event).
## Keys
No *Keys* are processed by the object type.
If `LV_OBJ_FLAG_CHECKABLE` is enabled `LV_KEY_RIGHT` and `LV_KEY_UP` makes the object checked, and `LV_KEY_LEFT` and `LV_KEY_DOWN` makes it unchecked.
Learn more about [Keys](/overview/indev).
## Example
```eval_rst

View File

@ -1,70 +0,0 @@
```eval_rst
.. include:: /header.rst
:github_url: |github_link_base|/widgets/objmask.md
```
# Object mask (lv_objmask)
## Overview
The *Object mask* is capable of add some mask to drawings when its children is drawn.
## Parts and Styles
The Object mask has only a main part called `LV_OBJMASK_PART_BG` and it uses the typical background style properties.
## Usage
### Adding mask
Before adding a mask to the *Object mask* the mask should be initialized:
```c
lv_draw_mask_<type>_param_t mask_param;
lv_draw_mask_<type>_init(&mask_param, ...);
lv_objmask_mask_t * mask_p = lv_objmask_add_mask(objmask, &mask_param);
```
Lvgl supports the following mask types:
- **line** clip the pixels on the top/bottom left/right of a line. Can be initialized from two points or a point and an angle:
- **angle** keep the pixels only between a given start and end angle
- **radius** keep the pixel only inside a rectangle which can have radius (can for a circle too). Can be inverted to keep the pixel outside of the rectangle.
- **fade** fade vertically (change the pixels opacity according to their y position)
- **map** use an alpha mask (a byte array) to describe the pixels opacity.
The coordinates in the mask are relative to the Object. That is if the object moves the masks move with it.
For the details of the mask *init* function see the [API](#api) documentation below.
### Update mask
AN existing mask can be updated with `lv_objmask_update_mask(objmask, mask_p, new_param)`, where `mask_p` is return value of `lv_objmask_add_mask`.
### Remove mask
A mask can be removed with `lv_objmask_remove_mask(objmask, mask_p)`
## Events
Only the [Generic events](../overview/event.html#generic-events) are sent by the object type.
Learn more about [Events](/overview/event).
## Keys
No *Keys* are processed by the object type.
Learn more about [Keys](/overview/indev).
## Example
```eval_rst
.. include:: /lv_examples/src/lv_ex_widgets/lv_ex_objmask/index.rst
```
## API
```eval_rst
.. doxygenfile:: lv_objmask.h
:project: lvgl
.. doxygenfile:: lv_draw_mask.h
:project: lvgl
```

View File

@ -1,111 +0,0 @@
```eval_rst
.. include:: /header.rst
:github_url: |github_link_base|/widgets/page.md
```
# Page (lv_page)
## Overview
The Page consist of two [Containers](/widgets/cont) on each other:
- a **background**
- a top which is **scrollable**.
## Parts and Styles
The Page's main part is called `LV_PAGE_PART_BG` which is the background of the Page. It uses all the typical background style properties. Using padding will add space on the sides.
The scrollable object can be referenced via the `LV_PAGE_PART_SCRL` part. It also uses all the typical background style properties and padding to add space on the sides.
`LV_LIST_PART_SCROLLBAR` is a virtual part of the background to draw the scroll bars. Uses all the typical background style properties, *size* to set the width of the scroll bars, and *pad_right* and *pad_bottom* to set the spacing.
`LV_LIST_PART_EDGE_FLASH`is also a virtual part of the background to draw a semicircle on the sides when the list can not be scrolled in that direction further. Uses all the typical background properties.
## Usage
The background object can be referenced as the page itself like. E.g. to set the page's width: `lv_obj_set_width(page, 100)`.
If a child is created on the page it will be automatically moved to the scrollable container.
If the scrollable container becomes larger then the background it can be scrolled by dragging (like the lists on smartphones).
By default, the scrollable's has `LV_FIT_MAX` fit in all directions.
It means the scrollable size will be the same as the background's size (minus the padding) while the children are in the background.
But when an object is positioned out of the background the scrollable size will be increased to involve it.
### Scrollbars
Scrollbars can be shown according to four policies:
- `LV_SCRLBAR_MODE_OFF` Never show scroll bars
- `LV_SCRLBAR_MODE_ON` Always show scroll bars
- `LV_SCRLBAR_MODE_DRAG` Show scroll bars when the page is being dragged
- `LV_SCRLBAR_MODE_AUTO` Show scroll bars when the scrollable container is large enough to be scrolled
- `LV_SCRLBAR_MODE_HIDE` Hide the scroll bar temporally
- `LV_SCRLBAR_MODE_UNHIDE` Unhide the previously hidden scrollbar. Recover the original mode too
The scroll bar show policy can be changed by: `lv_page_set_scrlbar_mode(page, SB_MODE)`. The default value is `LV_SCRLBAR_MODE_AUTO`.
### Glue object
A children can be "glued" to the page. In this case, if the page can be scrolled by dragging that object.
It can be enabled by the `lv_page_glue_obj(child, true)`.
### Focus object
An object on a page can be focused with `lv_page_focus(page, child, LV_ANIM_ONO/FF)`.
It will move the scrollable container to show a child. The time of the animation can be set by `lv_page_set_anim_time(page, anim_time)` in milliseconds.
`child` doesn't have to be a direct child of the page. This is it works if the scrollable object is the grandparent of the object too.
### Manual navigation
You can move the scrollable object manually using `lv_page_scroll_hor(page, dist)` and `lv_page_scroll_ver(page, dist)`
### Edge flash
A circle-like effect can be shown if the list reached the most top/bottom/left/right position. `lv_page_set_edge_flash(list, en)` enables this feature.
### Scroll propagation
If the list is created on an other scrollable element (like an other page) and the Page can't be scrolled further the scrolling can be propagated to the parent to continue the scrolling on the parent.
It can be enabled with `lv_page_set_scroll_propagation(list, true)`
## Clean the page
All the object created on the page can be clean with `lv_page_clean(page)`. Note that `lv_obj_clean(page)` doesn't work here because it would delete the scrollable object too.
### Scrollable API
There are functions to directly set/get the scrollable's attributes:
- `lv_page_get_scrl()`
- `lv_page_set_scrl_fit/fint2/fit4()`
- `lv_page_set_scrl_width()`
- `lv_page_set_scrl_height()`
- `lv_page_set_scrl_fit_width()`
- `lv_page_set_scrl_fit_height()`
- `lv_page_set_scrl_layout()`
## Events
Only the [Generic events](../overview/event.html#generic-events) are sent by the object type.
The scrollable object has a default event callback which propagates the following events to the background object:
`LV_EVENT_PRESSED`, `LV_EVENT_PRESSING`, `LV_EVENT_PRESS_LOST`,`LV_EVENT_RELEASED`, `LV_EVENT_SHORT_CLICKED`, `LV_EVENT_CLICKED`, `LV_EVENT_LONG_PRESSED`, `LV_EVENT_LONG_PRESSED_REPEAT`
Learn more about [Events](/overview/event).
##Keys
The following *Keys* are processed by the Page:
- **LV_KEY_RIGHT/LEFT/UP/DOWN** Scroll the page
Learn more about [Keys](/overview/indev).
## Example
```eval_rst
.. include:: /lv_examples/src/lv_ex_widgets/lv_ex_page/index.rst
```
## API
```eval_rst
.. doxygenfile:: lv_page.h
:project: lvgl
```

View File

@ -1,9 +1,11 @@
#include "../lv_examples.h"
#if LV_BUILD_EXAMPLES && LV_USE_BTN
static void btn_event_cb(lv_obj_t * btn, lv_event_t event)
static void btn_event_cb(lv_event_t * e)
{
if(event == LV_EVENT_CLICKED) {
lv_event_code_t code = lv_event_get_code(e);
lv_obj_t * btn = lv_event_get_target(e);
if(code == LV_EVENT_CLICKED) {
static uint8_t cnt = 0;
cnt++;
@ -21,7 +23,7 @@ void lv_example_get_started_1(void)
lv_obj_t * btn = lv_btn_create(lv_scr_act()); /*Add a button the current screen*/
lv_obj_set_pos(btn, 10, 10); /*Set its position*/
lv_obj_set_size(btn, 120, 50); /*Set its size*/
lv_obj_add_event_cb(btn, btn_event_cb, NULL); /*Assign a callback to the button*/
lv_obj_add_event_cb(btn, btn_event_cb, LV_EVENT_ALL, NULL); /*Assign a callback to the button*/
lv_obj_t * label = lv_label_create(btn); /*Add a label to the button*/
lv_label_set_text(label, "Button"); /*Set the labels text*/

View File

@ -14,8 +14,8 @@ void lv_example_get_started_2(void)
lv_style_init(&style_btn);
lv_style_set_radius(&style_btn, 10);
lv_style_set_bg_opa(&style_btn, LV_OPA_COVER);
lv_style_set_bg_color(&style_btn, lv_color_grey_lighten_3());
lv_style_set_bg_grad_color(&style_btn, lv_color_grey());
lv_style_set_bg_color(&style_btn, lv_palette_lighten(LV_PALETTE_GREY, 3));
lv_style_set_bg_grad_color(&style_btn, lv_palette_main(LV_PALETTE_GREY));
lv_style_set_bg_grad_dir(&style_btn, LV_GRAD_DIR_VER);
/*Add a border*/
@ -28,19 +28,22 @@ void lv_example_get_started_2(void)
/*Create a red style. Change only some colors.*/
lv_style_init(&style_btn_red);
lv_style_set_bg_color(&style_btn_red, lv_color_light_blue());
lv_style_set_bg_grad_color(&style_btn_red, lv_color_light_blue_darken_3());
lv_style_set_bg_color(&style_btn_red, lv_palette_main(LV_PALETTE_RED));
lv_style_set_bg_grad_color(&style_btn_red, lv_palette_lighten(LV_PALETTE_RED, 2));
/*Create a style for the pressed state. Add color filter to make every color darker*/
/*Create a style for the pressed state.*/
lv_style_init(&style_btn_pressed);
lv_style_set_bg_color(&style_btn_red, lv_color_blue());
lv_style_set_bg_grad_color(&style_btn_red, lv_color_blue_darken_3());
lv_style_set_bg_color(&style_btn_pressed, lv_palette_main(LV_PALETTE_BLUE));
lv_style_set_bg_grad_color(&style_btn_pressed, lv_palette_darken(LV_PALETTE_RED, 3));
/*Create a button and use the new styles*/
lv_obj_t * btn = lv_btn_create(lv_scr_act()); /*Add a button the current screen*/
lv_obj_t * btn = lv_btn_create(lv_scr_act()); /*Add a button the current screen*/
/* Remove the styles coming from the theme
* Note that size and position are also stored as style properties
* so lv_obj_remove_style_all will remove the set size and position too */
lv_obj_remove_style_all(btn);
lv_obj_set_pos(btn, 10, 10); /*Set its position*/
lv_obj_set_size(btn, 120, 50); /*Set its size*/
lv_obj_remove_style_all(btn); /*Remove the styles coming from the theme*/
lv_obj_add_style(btn, &style_btn, 0);
lv_obj_add_style(btn, &style_btn_pressed, LV_STATE_PRESSED);
@ -50,9 +53,9 @@ void lv_example_get_started_2(void)
/*Create an other button and use the red style too*/
lv_obj_t * btn2 = lv_btn_create(lv_scr_act());
lv_obj_remove_style_all(btn2); /*Remove the styles coming from the theme*/
lv_obj_set_pos(btn2, 10, 80);
lv_obj_set_size(btn2, 120, 50); /*Set its size*/
lv_obj_remove_style_all(btn2); /*Remove the styles coming from the theme*/
lv_obj_add_style(btn2, &style_btn, 0);
lv_obj_add_style(btn2, &style_btn_red, 0);
lv_obj_add_style(btn2, &style_btn_pressed, LV_STATE_PRESSED);

View File

@ -3,13 +3,13 @@
static lv_obj_t * label;
static void slider_event_cb(lv_obj_t * slider, lv_event_t event)
static void slider_event_cb(lv_event_t * e)
{
if(event == LV_EVENT_VALUE_CHANGED) {
/*Refresh the text*/
lv_label_set_text_fmt(label, "%d", lv_slider_get_value(slider));
lv_obj_align_to(label, slider, LV_ALIGN_OUT_TOP_MID, 0, -15); /*Align below the slider*/
}
lv_obj_t * slider = lv_event_get_target(e);
/*Refresh the text*/
lv_label_set_text_fmt(label, "%d", lv_slider_get_value(slider));
lv_obj_align_to(label, slider, LV_ALIGN_OUT_TOP_MID, 0, -15); /*Align below the slider*/
}
/**
@ -21,7 +21,7 @@ void lv_example_get_started_3(void)
lv_obj_t * slider = lv_slider_create(lv_scr_act());
lv_obj_set_width(slider, 200); /*Set the width*/
lv_obj_center(slider); /*Align to the center of the parent (screen)*/
lv_obj_add_event_cb(slider, slider_event_cb, NULL); /*Assign an event function*/
lv_obj_add_event_cb(slider, slider_event_cb, LV_EVENT_VALUE_CHANGED, NULL); /*Assign an event function*/
/*Create a label below the slider*/
label = lv_label_create(lv_scr_act());

View File

@ -24,16 +24,16 @@ void lv_example_flex_1(void)
lv_obj_t * label;
/*Add items to the row*/
obj= lv_obj_create(cont_row);
lv_obj_set_size(obj, 100, LV_SIZE_PCT(100));
obj= lv_btn_create(cont_row);
lv_obj_set_size(obj, 100, LV_PCT(100));
label = lv_label_create(obj);
lv_label_set_text_fmt(label, "Item: %d", i);
lv_obj_center(label);
/*Add items to the column*/
obj = lv_obj_create(cont_col);
lv_obj_set_size(obj, LV_SIZE_PCT(100), LV_SIZE_CONTENT);
obj = lv_btn_create(cont_col);
lv_obj_set_size(obj, LV_PCT(100), LV_SIZE_CONTENT);
label = lv_label_create(obj);
lv_label_set_text_fmt(label, "Item: %d", i);

View File

@ -9,7 +9,7 @@ void lv_example_flex_2(void)
static lv_style_t style;
lv_style_init(&style);
lv_style_set_flex_flow(&style, LV_FLEX_FLOW_ROW_WRAP);
lv_style_set_flex_main_place(&style, LV_FLEX_PLACE_SPACE_EVENLY);
lv_style_set_flex_main_place(&style, LV_FLEX_ALIGN_SPACE_EVENLY);
lv_style_set_layout(&style, LV_LAYOUT_FLEX);
lv_obj_t * cont = lv_obj_create(lv_scr_act());

View File

@ -25,11 +25,11 @@ void lv_example_grid_1(void)
uint8_t col = i % 3;
uint8_t row = i / 3;
obj = lv_obj_create(cont);
obj = lv_btn_create(cont);
/*Stretch the cell horizontally and vertically too
*Set span to 1 to make the cell 1 column/row sized*/
lv_obj_set_grid_cell(obj, LV_GRID_STRETCH, col, 1,
LV_GRID_STRETCH, row, 1);
lv_obj_set_grid_cell(obj, LV_GRID_ALIGN_STRETCH, col, 1,
LV_GRID_ALIGN_STRETCH, row, 1);
label = lv_label_create(obj);
lv_label_set_text_fmt(label, "c%d, r%d", col, row);

View File

@ -22,40 +22,40 @@ void lv_example_grid_2(void)
/*Cell to 0;0 and align to to the start (left/top) horizontally and vertically too*/
obj = lv_obj_create(cont);
lv_obj_set_size(obj, LV_SIZE_CONTENT, LV_SIZE_CONTENT);
lv_obj_set_grid_cell(obj, LV_GRID_START, 0, 1,
LV_GRID_START, 0, 1);
lv_obj_set_grid_cell(obj, LV_GRID_ALIGN_START, 0, 1,
LV_GRID_ALIGN_START, 0, 1);
label = lv_label_create(obj);
lv_label_set_text(label, "c0, r0");
/*Cell to 1;0 and align to to the start (left) horizontally and center vertically too*/
obj = lv_obj_create(cont);
lv_obj_set_size(obj, LV_SIZE_CONTENT, LV_SIZE_CONTENT);
lv_obj_set_grid_cell(obj, LV_GRID_START, 1, 1,
LV_GRID_CENTER, 0, 1);
lv_obj_set_grid_cell(obj, LV_GRID_ALIGN_START, 1, 1,
LV_GRID_ALIGN_CENTER, 0, 1);
label = lv_label_create(obj);
lv_label_set_text(label, "c1, r0");
/*Cell to 2;0 and align to to the start (left) horizontally and end (bottom) vertically too*/
obj = lv_obj_create(cont);
lv_obj_set_size(obj, LV_SIZE_CONTENT, LV_SIZE_CONTENT);
lv_obj_set_grid_cell(obj, LV_GRID_START, 2, 1,
LV_GRID_END, 0, 1);
lv_obj_set_grid_cell(obj, LV_GRID_ALIGN_START, 2, 1,
LV_GRID_ALIGN_END, 0, 1);
label = lv_label_create(obj);
lv_label_set_text(label, "c2, r0");
/*Cell to 1;1 but 2 column wide (span = 2).Set width and height to stretched.*/
obj = lv_obj_create(cont);
lv_obj_set_size(obj, LV_SIZE_CONTENT, LV_SIZE_CONTENT);
lv_obj_set_grid_cell(obj, LV_GRID_STRETCH, 1, 2,
LV_GRID_STRETCH, 1, 1);
lv_obj_set_grid_cell(obj, LV_GRID_ALIGN_STRETCH, 1, 2,
LV_GRID_ALIGN_STRETCH, 1, 1);
label = lv_label_create(obj);
lv_label_set_text(label, "c1-2, r1");
/*Cell to 0;1 but 2 rows tall (span = 2).Set width and height to stretched.*/
obj = lv_obj_create(cont);
lv_obj_set_size(obj, LV_SIZE_CONTENT, LV_SIZE_CONTENT);
lv_obj_set_grid_cell(obj, LV_GRID_STRETCH, 0, 1,
LV_GRID_STRETCH, 1, 2);
lv_obj_set_grid_cell(obj, LV_GRID_ALIGN_STRETCH, 0, 1,
LV_GRID_ALIGN_STRETCH, 1, 2);
label = lv_label_create(obj);
lv_label_set_text(label, "c0\nr1-2");
}

View File

@ -32,8 +32,8 @@ void lv_example_grid_3(void)
obj = lv_obj_create(cont);
/*Stretch the cell horizontally and vertically too
*Set span to 1 to make the cell 1 column/row sized*/
lv_obj_set_grid_cell(obj, LV_GRID_STRETCH, col, 1,
LV_GRID_STRETCH, row, 1);
lv_obj_set_grid_cell(obj, LV_GRID_ALIGN_STRETCH, col, 1,
LV_GRID_ALIGN_STRETCH, row, 1);
label = lv_label_create(obj);
lv_label_set_text_fmt(label, "%d,%d", col, row);

View File

@ -14,7 +14,7 @@ void lv_example_grid_4(void)
/*Create a container with grid*/
lv_obj_t * cont = lv_obj_create(lv_scr_act());
lv_obj_set_grid_place(cont, LV_GRID_SPACE_BETWEEN, LV_GRID_END);
lv_obj_set_grid_align(cont, LV_GRID_ALIGN_SPACE_BETWEEN, LV_GRID_ALIGN_END);
lv_obj_set_grid_dsc_array(cont, col_dsc, row_dsc);
lv_obj_set_size(cont, 300, 220);
lv_obj_center(cont);
@ -29,8 +29,8 @@ void lv_example_grid_4(void)
obj = lv_obj_create(cont);
/*Stretch the cell horizontally and vertically too
*Set span to 1 to make the cell 1 column/row sized*/
lv_obj_set_grid_cell(obj, LV_GRID_STRETCH, col, 1,
LV_GRID_STRETCH, row, 1);
lv_obj_set_grid_cell(obj, LV_GRID_ALIGN_STRETCH, col, 1,
LV_GRID_ALIGN_STRETCH, row, 1);
label = lv_label_create(obj);
lv_label_set_text_fmt(label, "%d,%d", col, row);

View File

@ -35,8 +35,8 @@ void lv_example_grid_5(void)
uint8_t row = i / 3;
obj = lv_obj_create(cont);
lv_obj_set_grid_cell(obj, LV_GRID_STRETCH, col, 1,
LV_GRID_STRETCH, row, 1);
lv_obj_set_grid_cell(obj, LV_GRID_ALIGN_STRETCH, col, 1,
LV_GRID_ALIGN_STRETCH, row, 1);
label = lv_label_create(obj);
lv_label_set_text_fmt(label, "%d,%d", col, row);
lv_obj_center(label);

View File

@ -27,8 +27,8 @@ void lv_example_grid_6(void)
obj = lv_obj_create(cont);
/*Stretch the cell horizontally and vertically too
*Set span to 1 to make the cell 1 column/row sized*/
lv_obj_set_grid_cell(obj, LV_GRID_STRETCH, col, 1,
LV_GRID_STRETCH, row, 1);
lv_obj_set_grid_cell(obj, LV_GRID_ALIGN_STRETCH, col, 1,
LV_GRID_ALIGN_STRETCH, row, 1);
label = lv_label_create(obj);
lv_label_set_text_fmt(label, "%d,%d", col, row);

View File

@ -1,10 +1,13 @@
#include "../lv_examples.h"
#if LV_BUILD_EXAMPLES && LV_USE_FLEX
static void sw_event_cb(lv_obj_t * sw, lv_event_t e)
static void sw_event_cb(lv_event_t * e)
{
if(e == LV_EVENT_VALUE_CHANGED) {
lv_obj_t * list = lv_event_get_user_data();
lv_event_code_t code = lv_event_get_code(e);
lv_obj_t * sw = lv_event_get_target(e);
if(code == LV_EVENT_VALUE_CHANGED) {
lv_obj_t * list = lv_event_get_user_data(e);
if(lv_obj_has_state(sw, LV_STATE_CHECKED)) lv_obj_add_flag(list, LV_OBJ_FLAG_SCROLL_ONE);
else lv_obj_clear_flag(list, LV_OBJ_FLAG_SCROLL_ONE);
@ -43,7 +46,7 @@ void lv_example_scroll_2(void)
/*Switch between "One scroll" and "Normal scroll" mode*/
lv_obj_t * sw = lv_switch_create(lv_scr_act());
lv_obj_align(sw, LV_ALIGN_TOP_RIGHT, -20, 10);
lv_obj_add_event_cb(sw, sw_event_cb, panel);
lv_obj_add_event_cb(sw, sw_event_cb, LV_EVENT_ALL, panel);
lv_obj_t * label = lv_label_create(lv_scr_act());
lv_label_set_text(label, "One scroll");
lv_obj_align_to(label, sw, LV_ALIGN_OUT_BOTTOM_MID, 0, 5);

View File

@ -3,10 +3,13 @@
static uint32_t btn_cnt = 1;
static void float_btn_event_cb(lv_obj_t * float_btn, lv_event_t e)
static void float_btn_event_cb(lv_event_t * e)
{
if(e == LV_EVENT_CLICKED) {
lv_obj_t * list = lv_event_get_user_data();
lv_event_code_t code = lv_event_get_code(e);
lv_obj_t * float_btn = lv_event_get_target(e);
if(code == LV_EVENT_CLICKED) {
lv_obj_t * list = lv_event_get_user_data(e);
char buf[32];
lv_snprintf(buf, sizeof(buf), "Track %d", btn_cnt);
lv_obj_t * list_btn = lv_list_add_btn(list, LV_SYMBOL_AUDIO, buf, NULL);
@ -37,7 +40,7 @@ void lv_example_scroll_3(void)
lv_obj_set_size(float_btn, 50, 50);
lv_obj_add_flag(float_btn, LV_OBJ_FLAG_FLOATING);
lv_obj_align(float_btn, LV_ALIGN_BOTTOM_RIGHT, 0, -lv_obj_get_style_pad_right(list, LV_PART_MAIN));
lv_obj_add_event_cb(float_btn, float_btn_event_cb, list);
lv_obj_add_event_cb(float_btn, float_btn_event_cb, LV_EVENT_ALL, list);
lv_obj_set_style_radius(float_btn, LV_RADIUS_CIRCLE, 0);
lv_obj_set_style_bg_img_src(float_btn, LV_SYMBOL_PLUS, 0);
lv_obj_set_style_text_font(float_btn, lv_theme_get_font_large(float_btn), 0);

Some files were not shown because too many files have changed in this diff Show More