init Files
21
libraries/lvgl/docs/CHANGELOG.rst
Normal file
@@ -0,0 +1,21 @@
|
||||
.. _changelog:
|
||||
|
||||
Changelog
|
||||
=========
|
||||
|
||||
`v9.2.2 <https://github.com/kisvegabor/lvgl_upstream/compare/v9.2.2...v9.2.1>`__ 29 October 2024
|
||||
------------------------------------------------------------------------------------------------
|
||||
|
||||
This release is a hot fix to revert `932c140 <https://github.com/kisvegabor/lvgl_upstream/commit/932c14086b79aff2a27cd154441f680eb8257311>`__
|
||||
which makes Kconfig build systems fail.
|
||||
|
||||
**It's highly recommended to update v9.2.1 to v9.2.2.**
|
||||
|
||||
See the Change log of v9.2.1 `here <https://github.com/lvgl/lvgl/blob/59a6b61c9580b65089010c5273f2fcdd6c4d2aae/docs/CHANGELOG.rst>`__ .
|
||||
|
||||
|
||||
Fixes
|
||||
~~~~~
|
||||
- **Revert "fix(kconfig): add LV_ATTRIBUTE_MEM_ALIGN, LV_ATTRIBUTE_LARGE_CONST and LV_SYSMON_GET_IDLE configs (#7131)"** `932c140 <https://github.com/kisvegabor/lvgl_upstream/commit/932c14086b79aff2a27cd154441f680eb8257311>`__
|
||||
- **fix(nuttx): fix assert when release LCD draw buffer** `7159 <https://github.com/kisvegabor/lvgl_upstream/pull/7159>`__
|
||||
|
||||
83
libraries/lvgl/docs/CODE_OF_CONDUCT.rst.back
Normal file
@@ -0,0 +1,83 @@
|
||||
Contributor Covenant Code of Conduct
|
||||
====================================
|
||||
|
||||
Our Pledge
|
||||
----------
|
||||
|
||||
In the interest of fostering an open and welcoming environment, we as
|
||||
contributors and maintainers pledge to making participation in our
|
||||
project and our community a harassment-free experience for everyone,
|
||||
regardless of age, body size, disability, ethnicity, gender identity and
|
||||
expression, level of experience, nationality, personal appearance, race,
|
||||
religion, or sexual identity and orientation.
|
||||
|
||||
Our Standards
|
||||
-------------
|
||||
|
||||
Examples of behavior that contributes to creating a positive environment
|
||||
include:
|
||||
|
||||
- Using welcoming and inclusive language
|
||||
- Being respectful of differing viewpoints and experiences
|
||||
- Gracefully accepting constructive criticism
|
||||
- Focusing on what is best for the community
|
||||
- Showing empathy towards other community members
|
||||
|
||||
Examples of unacceptable behavior by participants include:
|
||||
|
||||
- The use of sexualized language or imagery and unwelcome sexual
|
||||
attention or advances
|
||||
- Trolling, insulting/derogatory comments, and personal or political
|
||||
attacks
|
||||
- Public or private harassment
|
||||
- Publishing others' private information, such as a physical or
|
||||
electronic address, without explicit permission
|
||||
- Other conduct which could reasonably be considered inappropriate in a
|
||||
professional setting
|
||||
|
||||
Our Responsibilities
|
||||
--------------------
|
||||
|
||||
Project maintainers are responsible for clarifying the standards of
|
||||
acceptable behavior and are expected to take appropriate and fair
|
||||
corrective action in response to any instances of unacceptable behavior.
|
||||
|
||||
Project maintainers have the right and responsibility to remove, edit,
|
||||
or reject comments, commits, code, wiki edits, issues, and other
|
||||
contributions that are not aligned to this Code of Conduct, or to ban
|
||||
temporarily or permanently any contributor for other behaviors that they
|
||||
deem inappropriate, threatening, offensive, or harmful.
|
||||
|
||||
Scope
|
||||
-----
|
||||
|
||||
This Code of Conduct applies both within project spaces and in public
|
||||
spaces when an individual is representing the project or its community.
|
||||
Examples of representing a project or community include using an
|
||||
official project e-mail address, posting via an official social media
|
||||
account, or acting as an appointed representative at an online or
|
||||
offline event. Representation of a project may be further defined and
|
||||
clarified by project maintainers.
|
||||
|
||||
Enforcement
|
||||
-----------
|
||||
|
||||
Instances of abusive, harassing, or otherwise unacceptable behavior may
|
||||
be reported by contacting the project team using the `contact
|
||||
form <https://lvgl.io/about>`__. All complaints will be reviewed and
|
||||
investigated and will result in a response that is deemed necessary and
|
||||
appropriate to the circumstances. The project team is obligated to
|
||||
maintain confidentiality with regard to the reporter of an incident.
|
||||
Further details of specific enforcement policies may be posted
|
||||
separately.
|
||||
|
||||
Project maintainers who do not follow or enforce the Code of Conduct in
|
||||
good faith may face temporary or permanent repercussions as determined
|
||||
by other members of the project's leadership.
|
||||
|
||||
Attribution
|
||||
-----------
|
||||
|
||||
This Code of Conduct is adapted from the `Contributor
|
||||
Covenant <http://contributor-covenant.org>`__, version 1.4, available at
|
||||
`http://contributor-covenant.org/version/1/4 <http://contributor-covenant.org/version/1/4/>`__
|
||||
211
libraries/lvgl/docs/CODING_STYLE.rst
Normal file
@@ -0,0 +1,211 @@
|
||||
.. _coding-style:
|
||||
|
||||
Coding style
|
||||
============
|
||||
|
||||
File template
|
||||
-------------
|
||||
|
||||
Use `misc/lv_templ.c <https://github.com/lvgl/lvgl/blob/master/src/misc/lv_templ.c>`__
|
||||
and `misc/lv_templ.h <https://github.com/lvgl/lvgl/blob/master/src/misc/lv_templ.h>`__
|
||||
|
||||
Naming conventions
|
||||
------------------
|
||||
|
||||
- Words are separated by '\_'
|
||||
- In variable and function names use only lower case letters
|
||||
(e.g. *height_tmp*)
|
||||
- In enums and defines use only upper case letters
|
||||
(e.g. *e.g. MAX_LINE_NUM*)
|
||||
- Global names (API):
|
||||
|
||||
- start with *lv*
|
||||
- followed by module name: *button*, *label*, *style* etc.
|
||||
- followed by the action (for functions): *set*, *get*, etc.
|
||||
- closed with the subject: *name*, *size*, *state* etc.
|
||||
|
||||
- Typedefs
|
||||
|
||||
- prefer ``typedef struct`` and ``typedef enum`` instead of
|
||||
``struct name`` and ``enum name``
|
||||
- always end ``typedef struct`` and ``typedef enum`` type names with
|
||||
``_t``
|
||||
|
||||
- Abbreviations:
|
||||
|
||||
- The following abbreviations are used and allowed:
|
||||
|
||||
- ``dsc`` descriptor
|
||||
- ``param`` parameter
|
||||
- ``indev`` input device
|
||||
- ``anim`` animation
|
||||
- ``buf`` buffer
|
||||
- ``str`` string
|
||||
- ``min/max`` minimum/maximum
|
||||
- ``alloc`` allocate
|
||||
- ``ctrl`` control
|
||||
- ``pos`` position
|
||||
- Avoid adding new abbreviations
|
||||
|
||||
Coding guide
|
||||
------------
|
||||
|
||||
- Functions:
|
||||
|
||||
- Write function with single responsibility
|
||||
- Make the functions ``static`` where possible
|
||||
|
||||
- Variables:
|
||||
|
||||
- One line, one declaration (BAD: char x, y;)
|
||||
- Use ``<stdint.h>`` (*uint8_t*, *int32_t* etc)
|
||||
- Declare variables where needed (not all at function start)
|
||||
- Use the smallest required scope
|
||||
- Variables in a file (outside functions) are always *static*
|
||||
- Do not use global variables (use functions to set/get static
|
||||
variables)
|
||||
|
||||
Comments
|
||||
--------
|
||||
|
||||
Before every function have in ``.h`` files a comment like this:
|
||||
|
||||
.. code:: c
|
||||
|
||||
/**
|
||||
* Return with the screen of an object
|
||||
* @param obj pointer to an object
|
||||
* @return pointer to a screen
|
||||
*/
|
||||
lv_obj_t * lv_obj_get_screen(lv_obj_t * obj);
|
||||
|
||||
Always use ``/*Something*/`` format and NOT ``//Something``
|
||||
|
||||
Write readable code to avoid descriptive comments like:
|
||||
``x++; /*Add 1 to x*/``. The code should show clearly what you are
|
||||
doing.
|
||||
|
||||
You should write **why** have you done this:
|
||||
``x++; /*Because of closing '\0' of the string*/``
|
||||
|
||||
Short "code summaries" of a few lines are accepted. E.g.
|
||||
``/*Calculate the new coordinates*/``
|
||||
|
||||
In comments use \` \` when referring to a variable. E.g.
|
||||
:literal:`/\*Update the value of \`x_act`*/`
|
||||
|
||||
|
||||
API Conventions
|
||||
----------------------
|
||||
|
||||
To support the auto-generation of bindings, the LVGL C API must
|
||||
follow some coding conventions:
|
||||
|
||||
- Use ``enum``\ s instead of macros. If inevitable to use ``define``\ s
|
||||
export them with :cpp:expr:`LV_EXPORT_CONST_INT(defined_value)` right after the ``define``.
|
||||
- In function arguments use ``type name[]`` declaration for array parameters instead of :cpp:expr:`type * name`
|
||||
- Use typed pointers instead of :cpp:expr:`void *` pointers
|
||||
- Widget constructor must follow the ``lv_<widget_name>_create(lv_obj_t * parent)`` pattern.
|
||||
- Widget members function must start with ``lv_<widget_name>`` and should receive :cpp:expr:`lv_obj_t *` as first
|
||||
argument which is a pointer to widget object itself.
|
||||
- ``struct`` APIs should follow the widgets' conventions. That is to receive a pointer to the ``struct`` as the
|
||||
first argument, and the prefix of the ``struct`` name should be used as the prefix of the
|
||||
function name too (e.g. :cpp:expr:`lv_display_set_default(lv_display_t * disp)`)
|
||||
- Functions and ``struct``\ s which are not part of the public API must begin with underscore in order to mark them as "private".
|
||||
- Argument must be named in H files too.
|
||||
- Do not ``malloc`` into a static or global variables. Instead declare the variable in ``lv_global_t``
|
||||
structure in ``lv_global.h`` and mark the variable with :cpp:expr:`(LV_GLOBAL_DEFAULT()->variable)` when it's used.
|
||||
- To register and use callbacks one of the following needs to be followed.
|
||||
|
||||
- Pass a pointer to a ``struct`` as the first argument of both the registration function and the callback. That
|
||||
``struct`` must contain ``void * user_data`` field.
|
||||
- The last argument of the registration function must be ``void * user_data`` and the same ``user_data``
|
||||
needs to be passed as the last argument of the callback.
|
||||
|
||||
|
||||
To learn more refer to the documentation of `MicroPython <integration/bindings/micropython>`__.
|
||||
|
||||
|
||||
Formatting
|
||||
----------
|
||||
|
||||
Here is example to show bracket placing and using of white spaces:
|
||||
|
||||
.. code:: c
|
||||
|
||||
/**
|
||||
* Set a new text for a label. Memory will be allocated to store the text by the label.
|
||||
* @param label pointer to a label object
|
||||
* @param text '\0' terminated character string. NULL to refresh with the current text.
|
||||
*/
|
||||
void lv_label_set_text(lv_obj_t * label, const char * text)
|
||||
{ /*Main brackets of functions in new line*/
|
||||
|
||||
if(label == NULL) return; /*No bracket only if the command is inline with the if statement*/
|
||||
|
||||
lv_obj_inv(label);
|
||||
|
||||
lv_label_ext_t * ext = lv_obj_get_ext(label);
|
||||
|
||||
/*Comment before a section*/
|
||||
if(text == ext->txt || text == NULL) { /*Bracket of statements start inline*/
|
||||
lv_label_refr_text(label);
|
||||
return;
|
||||
}
|
||||
|
||||
...
|
||||
}
|
||||
|
||||
Use 4 spaces indentation instead of tab.
|
||||
|
||||
You can use **astyle** to format the code. Run ``code-format.py`` from
|
||||
the ``scripts`` folder.
|
||||
|
||||
pre-commit
|
||||
----------
|
||||
|
||||
`pre-commit <https://pre-commit.com/>`__ is a multi-language package
|
||||
manager for pre-commit hooks. See the `installation
|
||||
guide <https://pre-commit.com/#installation>`__ to get pre-commit python
|
||||
package installed into your development machine.
|
||||
|
||||
Once you have ``pre-commit`` installed you will need to `set up the git
|
||||
hook scripts <https://pre-commit.com/#3-install-the-git-hook-scripts>`__
|
||||
with:
|
||||
|
||||
.. code:: console
|
||||
|
||||
pre-commit install
|
||||
|
||||
now ``pre-commit`` will run automatically on ``git commit``!
|
||||
|
||||
Hooks
|
||||
-----
|
||||
|
||||
The ``format-source`` local hook (see ``.pre-commit-config.yaml``) runs
|
||||
**astyle** on all the staged source and header files (that are not
|
||||
excluded, see ``exclude`` key of the hook configuration) before entering
|
||||
the commit message, if any file gets formatted by **astyle** you will
|
||||
need to add the change to the staging area and run ``git commit`` again.
|
||||
|
||||
The ``trailing-whitespace`` hook fixes trailing whitespaces on all of
|
||||
the files.
|
||||
|
||||
Skipping hooks
|
||||
--------------
|
||||
|
||||
If you want to skip any particular hook you can do so with:
|
||||
|
||||
.. code:: console
|
||||
|
||||
SKIP=name-of-the-hook git commit
|
||||
|
||||
Testing hooks
|
||||
-------------
|
||||
|
||||
It's no necessary to do a commit to test the hooks, you can test hooks
|
||||
by adding the files into the staging area and run:
|
||||
|
||||
.. code:: console
|
||||
|
||||
pre-commit run name-of-the-hook
|
||||
221
libraries/lvgl/docs/CONTRIBUTING.rst
Normal file
@@ -0,0 +1,221 @@
|
||||
.. _contributing:
|
||||
|
||||
Contributing
|
||||
============
|
||||
|
||||
Introduction
|
||||
------------
|
||||
|
||||
Join LVGL's community and leave your footprint in the library!
|
||||
|
||||
There are a lot of ways to contribute to LVGL even if you are new to the
|
||||
library or even new to programming.
|
||||
|
||||
It might be scary to make the first step but you have nothing to be
|
||||
afraid of. A friendly and helpful community is waiting for you. Get to
|
||||
know like-minded people and make something great together.
|
||||
|
||||
So let's find which contribution option fits you the best and help you
|
||||
join the development of LVGL!
|
||||
|
||||
Ways to contribute
|
||||
-------------------
|
||||
|
||||
- **Spread the Word**: Share your LVGL experience with friends or on social media to boost its visibility.
|
||||
- **Star LVGL** Give us a star on `GitHub <https://github.com/lvgl/lvgl>`__ ! It helps a lot to LVGL more appealing for newcomers.
|
||||
- **Report a bug**: Open a `GitHub Issue <https://github.com/lvgl/lvgl/issues>`__ if something is not working.
|
||||
- **Join our** `Forum <https://forum.lvgl.io/>`__ : Meet fellow developers and discuss questions
|
||||
- **Tell your ideas**: If you miss something from LVGL we would love to hear about it in a `GitHub Issue <https://github.com/lvgl/lvgl/issues>`__
|
||||
- **Develop features**: Help to design or develop a feature. See below.
|
||||
|
||||
|
||||
Mid and large scale issues are discussed in `Feature planning <https://github.com/lvgl/lvgl/issues/new?assignees=&labels=&projects=&template=feat-planning.yml>`__ issues.
|
||||
|
||||
An issue can be developed when all the questions in the issue template are answered and there is no objection from any core member.
|
||||
|
||||
|
||||
We are using GitHub Labels to show the state of the issue:
|
||||
|
||||
- ``planning``: Still discussing how to approach it.
|
||||
- ``outlined``: We have come to a conclusion and the feature is ready to be developed.
|
||||
- ``request-change(<user-name>)``: Each core member has a dedicated label, and when they request a change, they add their label.
|
||||
- ``under development``: It's being developed by someone (can be developed only if no change is requested by the end of the cool-down phase).
|
||||
- ``ready``: The pitch is developed and merged into master.
|
||||
- ``stale``: Inactive, can be warmed up.
|
||||
- ``rejected``: Not interested in this feature for some reason.
|
||||
|
||||
.. _contributing_pull_request:
|
||||
|
||||
Pull request
|
||||
------------
|
||||
|
||||
Merging new code into the lvgl, documentation, blog, examples, and other
|
||||
repositories happen via *Pull requests* (PR for short). A PR is a
|
||||
notification like "Hey, I made some updates to your project. Here are
|
||||
the changes, you can add them if you want." To do this you need a copy
|
||||
(called fork) of the original project under your account, make some
|
||||
changes there, and notify the original repository about your updates.
|
||||
You can see what it looks like on GitHub for LVGL here:
|
||||
https://github.com/lvgl/lvgl/pulls.
|
||||
|
||||
To add your changes you can edit files online on GitHub and send a new
|
||||
Pull request from there (recommended for small changes) or add the
|
||||
updates in your favorite editor/IDE and use git to publish the changes
|
||||
(recommended for more complex updates).
|
||||
|
||||
From GitHub
|
||||
~~~~~~~~~~~
|
||||
|
||||
1. Navigate to the file you want to edit.
|
||||
2. Click the Edit button in the top right-hand corner.
|
||||
3. Add your changes to the file.
|
||||
4. Add a commit message on the bottom of the page.
|
||||
5. Click the *Propose changes* button.
|
||||
|
||||
From command line
|
||||
~~~~~~~~~~~~~~~~~
|
||||
|
||||
The instructions describe the main ``lvgl`` repository but it works the
|
||||
same way for the other repositories.
|
||||
|
||||
1. Fork the `lvgl repository <https://github.com/lvgl/lvgl>`__. To do this click the
|
||||
"Fork" button in the top right corner. It will "copy" the ``lvgl``
|
||||
repository to your GitHub account (``https://github.com/<YOUR_NAME>?tab=repositories``)
|
||||
2. Clone your forked repository.
|
||||
3. Add your changes. You can create a *feature branch* from *master* for the updates: ``git checkout -b <the-new-feature-branch-name>``
|
||||
4. Commit and push your changes to the forked ``lvgl`` repository.
|
||||
5. Create a PR on GitHub from the page of your ``lvgl`` repository (``https://github.com/<YOUR_NAME>/lvgl``) by
|
||||
clicking the *"New pull request"* button. Don't forget to select the branch where you added your changes.
|
||||
6. Set the base branch. It means where you want to merge your update. In the ``lvgl`` repo both the fixes
|
||||
and new features go to ``master`` branch.
|
||||
7. Describe what is in the update. An example code is welcome if applicable.
|
||||
8. If you need to make more changes, just update your forked ``lvgl`` repo with new commits.
|
||||
They will automatically appear in the PR.
|
||||
|
||||
.. _contributing_commit_message_format:
|
||||
|
||||
Commit message format
|
||||
~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
The commit messages format is inspired by `Angular Commit
|
||||
Format <https://gist.github.com/brianclements/841ea7bffdb01346392c>`__.
|
||||
|
||||
The following structure should be used:
|
||||
|
||||
.. code-block::
|
||||
|
||||
<type>(<scope>): <subject>
|
||||
<BLANK LINE>
|
||||
<body>
|
||||
<BLANK LINE>
|
||||
<footer>
|
||||
|
||||
Possible ``<type>``\ s:
|
||||
|
||||
- ``fix`` bugfix in the source code.
|
||||
- ``feat`` new feature
|
||||
- ``arch`` architectural changes
|
||||
- ``perf`` changes that affect the performance
|
||||
- ``example`` anything related to examples (even fixes and new examples)
|
||||
- ``docs`` anything related to the documentation (even fixes, formatting, and new pages)
|
||||
- ``test`` anything related to tests (new and updated tests or CI actions)
|
||||
- ``chore`` any minor formatting or style changes that would make the changelog noisy
|
||||
|
||||
``<scope>`` is the module, file, or sub-system that is affected by the
|
||||
commit. It's usually one word and can be chosen freely. For example
|
||||
``img``, ``layout``, ``txt``, ``anim``. The scope can be omitted.
|
||||
|
||||
``<subject>`` contains a short description of the change:
|
||||
|
||||
- use the imperative, present tense: "change" not "changed" nor "changes"
|
||||
- don't capitalize the first letter
|
||||
- no dot (``.``) at the end
|
||||
- max 90 characters
|
||||
|
||||
``<body>`` optional and can be used to describe the details of this
|
||||
change.
|
||||
|
||||
``<footer>`` shall contain
|
||||
|
||||
- the words "BREAKING CHANGE" if the changes break the API
|
||||
- reference to the GitHub issue or Pull Request if applicable.
|
||||
|
||||
Some examples:
|
||||
|
||||
- fix(img): update size if a new source is set
|
||||
- fix(bar): fix memory leak
|
||||
The animations weren't deleted in the destructor.
|
||||
|
||||
Fixes: #1234
|
||||
- feat: add span widget
|
||||
|
||||
The span widget allows mixing different font sizes, colors and styles.
|
||||
It's similar to HTML <span>
|
||||
- docs(porting): fix typo
|
||||
|
||||
.. _contributing_dco:
|
||||
|
||||
Developer Certification of Origin (DCO)
|
||||
---------------------------------------
|
||||
|
||||
Overview
|
||||
~~~~~~~~
|
||||
|
||||
To ensure all licensing criteria are met for every repository of the
|
||||
LVGL project, we apply a process called DCO (Developer's Certificate of
|
||||
Origin).
|
||||
|
||||
The text of DCO can be read here: https://developercertificate.org/.
|
||||
|
||||
By contributing to any repositories of the LVGL project you agree that
|
||||
your contribution complies with the DCO.
|
||||
|
||||
If your contribution fulfills the requirements of the DCO no further
|
||||
action is needed. If you are unsure feel free to ask us in a comment.
|
||||
|
||||
Accepted licenses and copyright notices
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
To make the DCO easier to digest, here are some practical guides about
|
||||
specific cases:
|
||||
|
||||
Your own work
|
||||
^^^^^^^^^^^^^
|
||||
|
||||
The simplest case is when the contribution is solely your own work. In
|
||||
this case you can just send a Pull Request without worrying about any
|
||||
licensing issues.
|
||||
|
||||
Use code from online source
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
If the code you would like to add is based on an article, post or
|
||||
comment on a website (e.g. StackOverflow) the license and/or rules of
|
||||
that site should be followed.
|
||||
|
||||
For example in case of StackOverflow a notice like this can be used:
|
||||
|
||||
.. code-block::
|
||||
|
||||
/* The original version of this code-snippet was published on StackOverflow.
|
||||
* Post: http://stackoverflow.com/questions/12345
|
||||
* Author: http://stackoverflow.com/users/12345/username
|
||||
* The following parts of the snippet were changed:
|
||||
* - Check this or that
|
||||
* - Optimize performance here and there
|
||||
*/
|
||||
... code snippet here ...
|
||||
|
||||
Use MIT licensed code
|
||||
^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
As LVGL is MIT licensed, other MIT licensed code can be integrated
|
||||
without issues. The MIT license requires a copyright notice be added to
|
||||
the derived work. Any derivative work based on MIT licensed code must
|
||||
copy the original work's license file or text.
|
||||
|
||||
Use GPL licensed code
|
||||
^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
The GPL license is not compatible with the MIT license. Therefore, LVGL
|
||||
cannot accept GPL licensed code.
|
||||
2456
libraries/lvgl/docs/Doxyfile
Normal file
641
libraries/lvgl/docs/README_jp.rst
Normal file
@@ -0,0 +1,641 @@
|
||||
.. raw:: html
|
||||
|
||||
<p align="left">
|
||||
<a href="https://github.com/sponsors/lvgl" target="_blank"><img align="left" src="https://lvgl.io/github-assets//sponsor.png" height="32px"></a>
|
||||
</p>
|
||||
|
||||
<p align="right">
|
||||
<a href="../README.md">English</a>| <a href="./README_zh.rst">中文</a>| <a href="./README_pt_BR.rst">Português do Brasil</a> | <b>日本語</b>
|
||||
</p>
|
||||
|
||||
.. raw:: html
|
||||
|
||||
</p>
|
||||
|
||||
.. raw:: html
|
||||
|
||||
<p align="center">
|
||||
|
||||
.. raw:: html
|
||||
|
||||
</p>
|
||||
|
||||
.. raw:: html
|
||||
|
||||
<h1 align="center">
|
||||
|
||||
Light and Versatile Graphics Library
|
||||
|
||||
.. raw:: html
|
||||
|
||||
</h1>
|
||||
|
||||
.. raw:: html
|
||||
|
||||
<p align="center">
|
||||
|
||||
Website \| Docs \| Forum :gb: \| Demos \| Services \| SquareLine Studio
|
||||
:gb:
|
||||
|
||||
.. raw:: html
|
||||
|
||||
</p>
|
||||
|
||||
:ledger:
|
||||
Overview
|
||||
--------
|
||||
|
||||
**実績**\ LVGL
|
||||
は、フリー&オープンソースの組み込み用グラフィックスライブラリです。
|
||||
あらゆるMCU、MPU、ディスプレイタイプに対応しており、美しいUI(User
|
||||
Interface)を実現できます。 ARM, STM32, NXP, Espressif, Nuvoton, Arduino,
|
||||
RT-Thread, Zephyr, NuttX,
|
||||
Adafruitなど、業界をリードするベンダーやプロジェクトによりサポートされています。
|
||||
|
||||
**機能豊富**\
|
||||
モダンで美しいGUIを作成するための機能をすべて備えています。
|
||||
30以上の組み込みウィジェット、強力なスタイルシステム、WEB由来のレイアウトマネージャ、多くの言語をサポートする文字グラフィックシステムなどです。
|
||||
LVGL のシステム要件は、RAM 32KB、Flash
|
||||
128KB、Cコンパイラ、フレームバッファ、1/10スクリーンサイズのレンダリング用バッファです。
|
||||
|
||||
**UIエディタ**\ SquareLine Studio
|
||||
は、LVGL用のプロフェッショナル&リーズナブルなドラッグ&ドロップ型のUIエディターです。
|
||||
Windows、Linux、macOS
|
||||
で動作し、ウェブサイトへの登録なしで試すことができます。
|
||||
|
||||
**サービス**\ LVGL LLC
|
||||
では、グラフィックデザイン、UI実装、コンサルティングサービスに対する技術サポートが可能です。GUIプロジェクトの開発において何らかのサポートが必要な場合には、お気軽にお問い合わせください。
|
||||
|
||||
:rocket:
|
||||
特徴
|
||||
-------------
|
||||
|
||||
**フリー & 移植可能** - 外部依存関係がなく、完全に移植可能な
|
||||
Cライブラリ。(C++互換) -
|
||||
任意の(RT)OS、任意のMCU・MPU用にコンパイル可能。 -
|
||||
電子ペーパー、OLEDディスプレイ、TFTディスプレイ、白黒ディスプレイ、モニターに対応。
|
||||
`Porting
|
||||
Guide <https://docs-lvgl-io.translate.goog/master/porting/project.html?_x_tr_sl=en&_x_tr_tl=ja&_x_tr_hl=ja>`__
|
||||
- MITライセンスにより商用利用可能。 - システム要件:RAM 32KB、Flash
|
||||
128KB、フレームバッファ、レンダリング用に1/10以上のスクリーンサイズのバッファ。
|
||||
- OS、外部メモリ、GPUもサポート。
|
||||
|
||||
**ウィジェット、スタイル、レイアウトなど** - 30以上の組み込み
|
||||
`ウィジェット <https://docs-lvgl-io.translate.goog/master/widgets/index.html?_x_tr_sl=en&_x_tr_tl=ja&_x_tr_hl=ja>`__: ボタン、ラベル、スライダー、グラフ、キーボード、メーター、円弧、表など。
|
||||
-
|
||||
ウィジェットの任意の部分を任意の状態にカスタマイズ可能な豊富なスタイルプロパティを備えた柔軟な
|
||||
`スタイルシステム <https://docs-lvgl-io.translate.goog/master/overview/style.html?_x_tr_sl=en&_x_tr_tl=ja&_x_tr_hl=ja>`__\ 。
|
||||
-
|
||||
`Flexbox <https://docs-lvgl-io.translate.goog/master/layouts/flex.html?_x_tr_sl=en&_x_tr_tl=ja&_x_tr_hl=ja>`__
|
||||
および
|
||||
`グリッド <https://docs-lvgl-io.translate.goog/master/layouts/grid.html?_x_tr_sl=en&_x_tr_tl=ja&_x_tr_hl=ja>`__
|
||||
風のレイアウトエンジンにより、ウィジェットのサイズと位置を自動的に設定。
|
||||
-
|
||||
テキスト表示(UTF-8対応)は、中国語、日本語、韓国語、タイ語、ヒンディー語、アラビア語、ペルシア語をサポート。
|
||||
-
|
||||
ワードラッピング、カーニング、テキストスクロール、サブピクセルレンダリング、ピンイン-IME中国語入力、テキスト中の絵文字に対応。
|
||||
-
|
||||
アニメーション、アンチエイリアシング、不透明度、スムーズスクロール、シャドウ、画像変換などをサポートするレンダリングエンジン。
|
||||
-
|
||||
マウス、タッチパッド、キーパッド、キーボード、外部ボタン、エンコーダ等の
|
||||
`入力デバイス <https://docs-lvgl-io.translate.goog/master/porting/indev.html?_x_tr_sl=en&_x_tr_tl=ja&_x_tr_hl=ja>`__
|
||||
をサポート。 -
|
||||
`マルチディスプレイ <https://docs-lvgl-io.translate.goog/master/overview/display.html?_x_tr_sl=en&_x_tr_tl=ja&_x_tr_hl=ja>`__
|
||||
対応。
|
||||
|
||||
**Binding と Build をサポート** - `MicroPython
|
||||
Binding <https://blog-lvgl-io.translate.goog/2019-02-20/micropython-bindings?_x_tr_sl=en&_x_tr_tl=ja&_x_tr_hl=ja>`__
|
||||
が LVGL API を公開。 -
|
||||
カスタムビルドシステムは使用せず、プロジェクトの他のファイルをビルドするときに、LVGLをビルド可能。
|
||||
- Make と
|
||||
`CMake <https://docs-lvgl-io.translate.goog/master/get-started/platforms/cmake.html?_x_tr_sl=en&_x_tr_tl=ja&_x_tr_hl=ja>`__
|
||||
が含まれており、すぐ使えるようにサポート。 -
|
||||
`PCのシミュレータで開発したUIコード <https://docs-lvgl-io.translate.goog/master/get-started/platforms/pc-simulator.html?_x_tr_sl=en&_x_tr_tl=ja&_x_tr_hl=ja>`__
|
||||
は、そのまま組込み用ハードウェアでも使用可能。 - `Emscripten
|
||||
port <https://github.com/lvgl/lv_web_emscripten>`__ :gb:
|
||||
によりC言語のUIコードをHTMLファイルに変換。
|
||||
|
||||
**ドキュメント, ツール, 技術サービス** -
|
||||
`ドキュメント <https://docs-lvgl-io.translate.goog/master/index.html?_x_tr_sl=en&_x_tr_tl=ja&_x_tr_hl=ja>`__\ は\ `100以上の簡単なサンプルプログラム <https://github.com/lvgl/lvgl/tree/master/examples>`__
|
||||
:gb: 入り 。 - `SquareLine Studio <https://squareline.io/>`__ :gb: -
|
||||
UI開発をスピードアップおよび簡素化するためのプロフェッショナルで使いやすいUIエディターソフトウェア。
|
||||
-
|
||||
UI開発をよりシンプルかつ迅速にするための、ユーザーインターフェイスの設計、実装、コンサルティングなどの
|
||||
`技術サービス <https://lvgl-io.translate.goog/services?_x_tr_sl=en&_x_tr_tl=ja&_x_tr_hl=ja>`__\ 。
|
||||
|
||||
:package:
|
||||
パッケージ
|
||||
--------------------
|
||||
|
||||
LVGL は以下で利用可能です。 - `Arduino
|
||||
library <https://docs-lvgl-io.translate.goog/master/get-started/platforms/arduino.html?_x_tr_sl=en&_x_tr_tl=ja&_x_tr_hl=ja>`__
|
||||
- `PlatformIO
|
||||
package <https://registry.platformio.org/libraries/lvgl/lvgl>`__ :gb: -
|
||||
`Zephyr
|
||||
library <https://docs-zephyrproject-org.translate.goog/latest/index.html?_x_tr_sl=en&_x_tr_tl=ja&_x_tr_hl=ja>`__
|
||||
- `ESP32
|
||||
component <https://docs-lvgl-io.translate.goog/master/get-started/platforms/espressif.html?_x_tr_sl=en&_x_tr_tl=ja&_x_tr_hl=ja>`__
|
||||
- `NXP MCUXpresso
|
||||
component <https://www-nxp-com.translate.goog/design/software/embedded-software/lvgl-open-source-graphics-library:LITTLEVGL-OPEN-SOURCE-GRAPHICS-LIBRARY?_x_tr_sl=en&_x_tr_tl=ja&_x_tr_hl=ja>`__
|
||||
- `NuttX
|
||||
library <https://docs-lvgl-io.translate.goog/master/get-started/os/nuttx.html?_x_tr_sl=en&_x_tr_tl=ja&_x_tr_hl=ja>`__
|
||||
- `RT-Thread
|
||||
RTOS <https://docs-lvgl-io.translate.goog/master/get-started/os/rt-thread.html?_x_tr_sl=en&_x_tr_tl=ja&_x_tr_hl=ja>`__
|
||||
- NXP MCUXpresso library - CMSIS-Pack
|
||||
|
||||
:robot:
|
||||
サンプルプログラム
|
||||
--------------------------
|
||||
|
||||
ウィジェット・レイアウト・スタイルのサンプルプログラムを用意しました。 C
|
||||
と MicroPython のコードを選べます。 オンラインの MicroPythonエディタ
|
||||
へのリンクにより、サンプルプログラムの動作確認・編集もできます。
|
||||
|
||||
その他のサンプルプログラムは `Examples
|
||||
フォルダ <https://github.com/lvgl/lvgl/tree/master/examples>`__ :gb:
|
||||
を確認してください。
|
||||
|
||||
Button with Click Event
|
||||
~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
.. figure:: https://github.com/kisvegabor/test/raw/master/readme_example_1.gif
|
||||
:alt: ラベル付きボタンのLVGLサンプルプログラム
|
||||
|
||||
ラベル付きボタンのLVGLサンプルプログラム
|
||||
|
||||
.. raw:: html
|
||||
|
||||
<details>
|
||||
|
||||
.. raw:: html
|
||||
|
||||
<summary>
|
||||
|
||||
C code
|
||||
|
||||
.. raw:: html
|
||||
|
||||
</summary>
|
||||
|
||||
.. code:: c
|
||||
|
||||
lv_obj_t * btn = lv_button_create(lv_screen_active()); /*Add a button to the current screen*/
|
||||
lv_obj_center(btn); /*Set its position*/
|
||||
lv_obj_set_size(btn, 100, 50); /*Set its size*/
|
||||
lv_obj_add_event(btn, btn_event_cb, LV_EVENT_CLICKED, 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*/
|
||||
lv_obj_center(label); /*Align the label to the center*/
|
||||
...
|
||||
|
||||
void btn_event_cb(lv_event_t * e)
|
||||
{
|
||||
printf("Clicked\n");
|
||||
}
|
||||
|
||||
.. raw:: html
|
||||
|
||||
</details>
|
||||
|
||||
.. raw:: html
|
||||
|
||||
<details>
|
||||
|
||||
.. raw:: html
|
||||
|
||||
<summary>
|
||||
|
||||
MicroPython code \| Online Simulator :gb:
|
||||
|
||||
.. raw:: html
|
||||
|
||||
</summary>
|
||||
|
||||
.. code:: python
|
||||
|
||||
def btn_event_cb(e):
|
||||
print("Clicked")
|
||||
|
||||
# Create a Button and a Label
|
||||
btn = lv.btn(lv.scr_act())
|
||||
btn.center()
|
||||
btn.set_size(100, 50)
|
||||
btn.add_event(btn_event_cb, lv.EVENT.CLICKED, None)
|
||||
|
||||
label = lv.label(btn)
|
||||
label.set_text("Button")
|
||||
label.center()
|
||||
|
||||
.. raw:: html
|
||||
|
||||
</details>
|
||||
|
||||
Checkboxes with Layout
|
||||
~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
.. figure:: https://github.com/kisvegabor/test/raw/master/readme_example_2.gif
|
||||
:alt: Checkboxes with layout in LVGL
|
||||
|
||||
Checkboxes with layout in LVGL
|
||||
|
||||
.. raw:: html
|
||||
|
||||
<details>
|
||||
|
||||
.. raw:: html
|
||||
|
||||
<summary>
|
||||
|
||||
C code
|
||||
|
||||
.. raw:: html
|
||||
|
||||
</summary>
|
||||
|
||||
.. code:: c
|
||||
|
||||
|
||||
lv_obj_set_flex_flow(lv_screen_active(), LV_FLEX_FLOW_COLUMN);
|
||||
lv_obj_set_flex_align(lv_screen_active(), LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_START, LV_FLEX_ALIGN_CENTER);
|
||||
|
||||
lv_obj_t * cb;
|
||||
cb = lv_checkbox_create(lv_screen_active());
|
||||
lv_checkbox_set_text(cb, "Apple");
|
||||
lv_obj_add_event(cb, event_handler, LV_EVENT_ALL, NULL);
|
||||
|
||||
cb = lv_checkbox_create(lv_screen_active());
|
||||
lv_checkbox_set_text(cb, "Banana");
|
||||
lv_obj_add_state(cb, LV_STATE_CHECKED);
|
||||
lv_obj_add_event(cb, event_handler, LV_EVENT_ALL, NULL);
|
||||
|
||||
cb = lv_checkbox_create(lv_screen_active());
|
||||
lv_checkbox_set_text(cb, "Lemon");
|
||||
lv_obj_add_state(cb, LV_STATE_DISABLED);
|
||||
lv_obj_add_event(cb, event_handler, LV_EVENT_ALL, NULL);
|
||||
|
||||
cb = lv_checkbox_create(lv_screen_active());
|
||||
lv_obj_add_state(cb, LV_STATE_CHECKED | LV_STATE_DISABLED);
|
||||
lv_checkbox_set_text(cb, "Melon\nand a new line");
|
||||
lv_obj_add_event(cb, event_handler, LV_EVENT_ALL, NULL);
|
||||
|
||||
.. raw:: html
|
||||
|
||||
</details>
|
||||
|
||||
.. raw:: html
|
||||
|
||||
<details>
|
||||
|
||||
.. raw:: html
|
||||
|
||||
<summary>
|
||||
|
||||
MicroPython code \| Online Simulator :gb:
|
||||
|
||||
.. raw:: html
|
||||
|
||||
</summary>
|
||||
|
||||
.. code:: python
|
||||
|
||||
def event_handler(e):
|
||||
code = e.get_code()
|
||||
obj = e.get_target_obj()
|
||||
if code == lv.EVENT.VALUE_CHANGED:
|
||||
txt = obj.get_text()
|
||||
if obj.get_state() & lv.STATE.CHECKED:
|
||||
state = "Checked"
|
||||
else:
|
||||
state = "Unchecked"
|
||||
print(txt + ":" + state)
|
||||
|
||||
|
||||
lv.scr_act().set_flex_flow(lv.FLEX_FLOW.COLUMN)
|
||||
lv.scr_act().set_flex_align(lv.FLEX_ALIGN.CENTER, lv.FLEX_ALIGN.START, lv.FLEX_ALIGN.CENTER)
|
||||
|
||||
cb = lv.checkbox(lv.scr_act())
|
||||
cb.set_text("Apple")
|
||||
cb.add_event(event_handler, lv.EVENT.ALL, None)
|
||||
|
||||
cb = lv.checkbox(lv.scr_act())
|
||||
cb.set_text("Banana")
|
||||
cb.add_state(lv.STATE.CHECKED)
|
||||
cb.add_event(event_handler, lv.EVENT.ALL, None)
|
||||
|
||||
cb = lv.checkbox(lv.scr_act())
|
||||
cb.set_text("Lemon")
|
||||
cb.add_state(lv.STATE.DISABLED)
|
||||
cb.add_event(event_handler, lv.EVENT.ALL, None)
|
||||
|
||||
cb = lv.checkbox(lv.scr_act())
|
||||
cb.add_state(lv.STATE.CHECKED | lv.STATE.DISABLED)
|
||||
cb.set_text("Melon")
|
||||
cb.add_event(event_handler, lv.EVENT.ALL, None)
|
||||
|
||||
.. raw:: html
|
||||
|
||||
</details>
|
||||
|
||||
Styling a Slider
|
||||
~~~~~~~~~~~~~~~~
|
||||
|
||||
.. figure:: https://github.com/kisvegabor/test/raw/master/readme_example_3.gif
|
||||
:alt: Styling a slider with LVGL
|
||||
|
||||
Styling a slider with LVGL
|
||||
|
||||
.. raw:: html
|
||||
|
||||
<details>
|
||||
|
||||
.. raw:: html
|
||||
|
||||
<summary>
|
||||
|
||||
C code
|
||||
|
||||
.. raw:: html
|
||||
|
||||
</summary>
|
||||
|
||||
.. code:: c
|
||||
|
||||
lv_obj_t * slider = lv_slider_create(lv_screen_active());
|
||||
lv_slider_set_value(slider, 70, LV_ANIM_OFF);
|
||||
lv_obj_set_size(slider, 300, 20);
|
||||
lv_obj_center(slider);
|
||||
|
||||
/*Add local styles to MAIN part (background rectangle)*/
|
||||
lv_obj_set_style_bg_color(slider, lv_color_hex(0x0F1215), LV_PART_MAIN);
|
||||
lv_obj_set_style_bg_opa(slider, 255, LV_PART_MAIN);
|
||||
lv_obj_set_style_border_color(slider, lv_color_hex(0x333943), LV_PART_MAIN);
|
||||
lv_obj_set_style_border_width(slider, 5, LV_PART_MAIN);
|
||||
lv_obj_set_style_pad_all(slider, 5, LV_PART_MAIN);
|
||||
|
||||
/*Create a reusable style sheet for the INDICATOR part*/
|
||||
static lv_style_t style_indicator;
|
||||
lv_style_init(&style_indicator);
|
||||
lv_style_set_bg_color(&style_indicator, lv_color_hex(0x37B9F5));
|
||||
lv_style_set_bg_grad_color(&style_indicator, lv_color_hex(0x1464F0));
|
||||
lv_style_set_bg_grad_dir(&style_indicator, LV_GRAD_DIR_HOR);
|
||||
lv_style_set_shadow_color(&style_indicator, lv_color_hex(0x37B9F5));
|
||||
lv_style_set_shadow_width(&style_indicator, 15);
|
||||
lv_style_set_shadow_spread(&style_indicator, 5);
|
||||
|
||||
/*Add the style sheet to the slider's INDICATOR part*/
|
||||
lv_obj_add_style(slider, &style_indicator, LV_PART_INDICATOR);
|
||||
|
||||
/*Add the same style to the KNOB part too and locally overwrite some properties*/
|
||||
lv_obj_add_style(slider, &style_indicator, LV_PART_KNOB);
|
||||
|
||||
lv_obj_set_style_outline_color(slider, lv_color_hex(0x0096FF), LV_PART_KNOB);
|
||||
lv_obj_set_style_outline_width(slider, 3, LV_PART_KNOB);
|
||||
lv_obj_set_style_outline_pad(slider, -5, LV_PART_KNOB);
|
||||
lv_obj_set_style_shadow_spread(slider, 2, LV_PART_KNOB);
|
||||
|
||||
.. raw:: html
|
||||
|
||||
</details>
|
||||
|
||||
.. raw:: html
|
||||
|
||||
<details>
|
||||
|
||||
.. raw:: html
|
||||
|
||||
<summary>
|
||||
|
||||
MicroPython code \| Online Simulator :gb:
|
||||
|
||||
.. raw:: html
|
||||
|
||||
</summary>
|
||||
|
||||
.. code:: python
|
||||
|
||||
# Create a slider and add the style
|
||||
slider = lv.slider(lv.scr_act())
|
||||
slider.set_value(70, lv.ANIM.OFF)
|
||||
slider.set_size(300, 20)
|
||||
slider.center()
|
||||
|
||||
# Add local styles to MAIN part (background rectangle)
|
||||
slider.set_style_bg_color(lv.color_hex(0x0F1215), lv.PART.MAIN)
|
||||
slider.set_style_bg_opa(255, lv.PART.MAIN)
|
||||
slider.set_style_border_color(lv.color_hex(0x333943), lv.PART.MAIN)
|
||||
slider.set_style_border_width(5, lv.PART.MAIN)
|
||||
slider.set_style_pad_all(5, lv.PART.MAIN)
|
||||
|
||||
# Create a reusable style sheet for the INDICATOR part
|
||||
style_indicator = lv.style_t()
|
||||
style_indicator.init()
|
||||
style_indicator.set_bg_color(lv.color_hex(0x37B9F5))
|
||||
style_indicator.set_bg_grad_color(lv.color_hex(0x1464F0))
|
||||
style_indicator.set_bg_grad_dir(lv.GRAD_DIR.HOR)
|
||||
style_indicator.set_shadow_color(lv.color_hex(0x37B9F5))
|
||||
style_indicator.set_shadow_width(15)
|
||||
style_indicator.set_shadow_spread(5)
|
||||
|
||||
# Add the style sheet to the slider's INDICATOR part
|
||||
slider.add_style(style_indicator, lv.PART.INDICATOR)
|
||||
slider.add_style(style_indicator, lv.PART.KNOB)
|
||||
|
||||
# Add the same style to the KNOB part too and locally overwrite some properties
|
||||
slider.set_style_outline_color(lv.color_hex(0x0096FF), lv.PART.KNOB)
|
||||
slider.set_style_outline_width(3, lv.PART.KNOB)
|
||||
slider.set_style_outline_pad(-5, lv.PART.KNOB)
|
||||
slider.set_style_shadow_spread(2, lv.PART.KNOB)
|
||||
|
||||
.. raw:: html
|
||||
|
||||
</details>
|
||||
|
||||
English, Hebrew (mixed LRT-RTL) and Chinese texts
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
.. figure:: https://github.com/kisvegabor/test/raw/master/readme_example_4.png
|
||||
:alt: English, Hebrew and Chinese texts with LVGL
|
||||
|
||||
English, Hebrew and Chinese texts with LVGL
|
||||
|
||||
.. raw:: html
|
||||
|
||||
<details>
|
||||
|
||||
.. raw:: html
|
||||
|
||||
<summary>
|
||||
|
||||
C code
|
||||
|
||||
.. raw:: html
|
||||
|
||||
</summary>
|
||||
|
||||
.. code:: c
|
||||
|
||||
lv_obj_t * ltr_label = lv_label_create(lv_screen_active());
|
||||
lv_label_set_text(ltr_label, "In modern terminology, a microcontroller is similar to a system on a chip (SoC).");
|
||||
lv_obj_set_style_text_font(ltr_label, &lv_font_montserrat_16, 0);
|
||||
lv_obj_set_width(ltr_label, 310);
|
||||
lv_obj_align(ltr_label, LV_ALIGN_TOP_LEFT, 5, 5);
|
||||
|
||||
lv_obj_t * rtl_label = lv_label_create(lv_screen_active());
|
||||
lv_label_set_text(rtl_label,"מעבד, או בשמו המלא יחידת עיבוד מרכזית (באנגלית: CPU - Central Processing Unit).");
|
||||
lv_obj_set_style_base_dir(rtl_label, LV_BASE_DIR_RTL, 0);
|
||||
lv_obj_set_style_text_font(rtl_label, &lv_font_dejavu_16_persian_hebrew, 0);
|
||||
lv_obj_set_width(rtl_label, 310);
|
||||
lv_obj_align(rtl_label, LV_ALIGN_LEFT_MID, 5, 0);
|
||||
|
||||
lv_obj_t * cz_label = lv_label_create(lv_screen_active());
|
||||
lv_label_set_text(cz_label,
|
||||
"嵌入式系统(Embedded System),\n是一种嵌入机械或电气系统内部、具有专一功能和实时计算性能的计算机系统。");
|
||||
lv_obj_set_style_text_font(cz_label, &lv_font_simsun_16_cjk, 0);
|
||||
lv_obj_set_width(cz_label, 310);
|
||||
lv_obj_align(cz_label, LV_ALIGN_BOTTOM_LEFT, 5, -5);
|
||||
|
||||
.. raw:: html
|
||||
|
||||
</details>
|
||||
|
||||
.. raw:: html
|
||||
|
||||
<details>
|
||||
|
||||
.. raw:: html
|
||||
|
||||
<summary>
|
||||
|
||||
MicroPython code \| Online Simulator :gb:
|
||||
|
||||
.. raw:: html
|
||||
|
||||
</summary>
|
||||
|
||||
.. code:: python
|
||||
|
||||
ltr_label = lv.label(lv.scr_act())
|
||||
ltr_label.set_text("In modern terminology, a microcontroller is similar to a system on a chip (SoC).")
|
||||
ltr_label.set_style_text_font(lv.font_montserrat_16, 0);
|
||||
|
||||
ltr_label.set_width(310)
|
||||
ltr_label.align(lv.ALIGN.TOP_LEFT, 5, 5)
|
||||
|
||||
rtl_label = lv.label(lv.scr_act())
|
||||
rtl_label.set_text("מעבד, או בשמו המלא יחידת עיבוד מרכזית (באנגלית: CPU - Central Processing Unit).")
|
||||
rtl_label.set_style_base_dir(lv.BASE_DIR.RTL, 0)
|
||||
rtl_label.set_style_text_font(lv.font_dejavu_16_persian_hebrew, 0)
|
||||
rtl_label.set_width(310)
|
||||
rtl_label.align(lv.ALIGN.LEFT_MID, 5, 0)
|
||||
|
||||
font_simsun_16_cjk = lv.font_load("S:../../assets/font/lv_font_simsun_16_cjk.fnt")
|
||||
|
||||
cz_label = lv.label(lv.scr_act())
|
||||
cz_label.set_style_text_font(font_simsun_16_cjk, 0)
|
||||
cz_label.set_text("嵌入式系统(Embedded System),\n是一种嵌入机械或电气系统内部、具有专一功能和实时计算性能的计算机系统。")
|
||||
cz_label.set_width(310)
|
||||
cz_label.align(lv.ALIGN.BOTTOM_LEFT, 5, -5)
|
||||
|
||||
.. raw:: html
|
||||
|
||||
</details>
|
||||
|
||||
:arrow_forward:
|
||||
はじめに
|
||||
------------------------
|
||||
|
||||
LVGLを使い始める時は、以下の順に進める事をおすすめします。
|
||||
|
||||
**LVGLに触れてみましょう**
|
||||
|
||||
1. LVGLの動きを
|
||||
`オンラインデモ <https://lvgl-io.translate.goog/demos?_x_tr_sl=en&_x_tr_tl=ja&_x_tr_hl=ja>`__
|
||||
で確認しましょう。 (3分間)
|
||||
2. ドキュメントの
|
||||
`Introduction <https://docs-lvgl-io.translate.goog/master/intro/index.html?_x_tr_sl=en&_x_tr_tl=ja&_x_tr_hl=ja>`__
|
||||
を読みましょう。 (5分間)
|
||||
3. LVGLの基本に慣れるため `Quick
|
||||
overview <https://docs-lvgl-io.translate.goog/master/get-started/quick-overview.html?_x_tr_sl=en&_x_tr_tl=ja&_x_tr_hl=ja>`__
|
||||
を読みましょう。 (15分間)
|
||||
|
||||
**LVGLを使ってみましょう**
|
||||
|
||||
4. `シミュレータ <https://docs-lvgl-io.translate.goog/master/get-started/platforms/pc-simulator.html?_x_tr_sl=en&_x_tr_tl=ja&_x_tr_hl=ja>`__
|
||||
をセットアップしましょう。 (10 minutes)
|
||||
5. `サンプルプログラム <https://github.com/lvgl/lvgl/tree/master/examples>`__
|
||||
:gb: を動かしてみましょう。
|
||||
6. `移植ガイド <https://docs-lvgl-io.translate.goog/master/porting/index.html?_x_tr_sl=en&_x_tr_tl=ja&_x_tr_hl=ja>`__
|
||||
を参考に、LVGLを開発ボードに移植してみましょう。すぐ使える形の
|
||||
`プロジェクト <https://github.com/lvgl?q=lv_port_>`__ :gb:
|
||||
も用意してあります。
|
||||
|
||||
**より詳しく体験してみましょう**
|
||||
|
||||
7. ライブラリの理解を深めるため
|
||||
`Overview <https://docs-lvgl-io.translate.goog/master/overview/index.html?_x_tr_sl=en&_x_tr_tl=ja&_x_tr_hl=ja>`__
|
||||
を読みましょう。 (2~3時間)
|
||||
8. ウィジェットの機能や使い方の詳細は
|
||||
`Widgets <https://docs-lvgl-io.translate.goog/master/widgets/index.html?_x_tr_sl=en&_x_tr_tl=ja&_x_tr_hl=ja>`__
|
||||
でご確認ください。
|
||||
|
||||
**助け合いましょう**
|
||||
|
||||
9. 質問がある場合は `Forum <http://forum.lvgl.io/>`__ :gb:
|
||||
で質問して下さい。
|
||||
10. LVGLの改善への協力は大歓迎です。詳細は `Contributing
|
||||
guide <https://docs-lvgl-io.translate.goog/master/CONTRIBUTING.html?_x_tr_sl=en&_x_tr_tl=ja&_x_tr_hl=ja>`__
|
||||
をご覧ください。 (15分間)
|
||||
|
||||
**さらに理解を深めましょう**
|
||||
|
||||
11. `SquareLine Studio <https://squareline.io/>`__ :gb:
|
||||
をダウンロードして試用してみましょう。
|
||||
12. 技術的サポートが必要であれば、\ `技術サービス <https://lvgl.io/services>`__
|
||||
:gb: に問い合わせて下さい。
|
||||
|
||||
:handshake:
|
||||
技術サービス
|
||||
------------------------
|
||||
|
||||
`LVGL
|
||||
LLC <https://www.digikey.com/en/design-services-providers/lvgl-kft>`__
|
||||
は、LVGLライブラリの確かな背景を元に、UI開発のための様々な技術サービスを提供するために設立されました。
|
||||
UIとグラフィックス業界における15年以上の実績を活かし、UIを次のレベルに引き上げるお手伝いを致します。
|
||||
|
||||
- **グラフィックデザイン**
|
||||
当社のグラフィックデザイナーは、製品とハードウェアのリソースに合わせて美しくモダンなデザインにするエキスパートです。
|
||||
- **UI実装**
|
||||
お客様または弊社で作成したデザインを元に、UIを実装することも可能です。お客様のハードウェアとLVGLを最大限に活用することをお約束します。
|
||||
LVGLにない機能やウィジェットは、私たちが実装しますのでご安心ください。
|
||||
- **コンサルタント&技術サポート**
|
||||
UI開発において、価格と時間を要する作業でのリスクを減らすため、コンサルティングも含めてサポート致します。
|
||||
- **Board certification** development board または production ready kit
|
||||
を提供している企業に対しては、ボードがLVGLを実行できるようにするためのボード認定を行います。
|
||||
|
||||
サンプルは
|
||||
`Demos <https://lvgl-io.translate.goog/demos?_x_tr_sl=en&_x_tr_tl=ja&_x_tr_hl=ja>`__
|
||||
をご覧ください。 詳しくは `Services
|
||||
page <https://lvgl-io.translate.goog/services?_x_tr_sl=en&_x_tr_tl=ja&_x_tr_hl=ja>`__
|
||||
をご覧ください。
|
||||
|
||||
お問い合わせは `問い合わせフォーム <https://lvgl.io/#contact>`__ :gb:
|
||||
より送信して下さい。
|
||||
|
||||
:star2:
|
||||
協力
|
||||
------------
|
||||
|
||||
LVGLはオープンプロジェクトであり、協力は大歓迎です。
|
||||
色々な方法で協力できます。 協力方法の例 -
|
||||
LVGLを使用した作品やプロジェクトの公表 - サンプルプログラムの作成 -
|
||||
ドキュメントの改善 - バグの修正
|
||||
|
||||
協力方法の詳細については、ドキュメントの `Contributing
|
||||
section <https://docs-lvgl-io.translate.goog/master/CONTRIBUTING.html?_x_tr_sl=en&_x_tr_tl=ja&_x_tr_hl=ja>`__
|
||||
をご覧ください。
|
||||
|
||||
すでに 300人以上がLVGLに足跡を残しています。いっしょに活動しましょう!
|
||||
:slightly_smiling_face:
|
||||
|
||||
… and many other.
|
||||
706
libraries/lvgl/docs/README_pt_BR.rst
Normal file
@@ -0,0 +1,706 @@
|
||||
.. raw:: html
|
||||
|
||||
<p align="left">
|
||||
<a href="https://github.com/sponsors/lvgl" target="_blank"><img align="left" src="https://lvgl.io/github-assets/sponsor.png" height="32px"></a>
|
||||
</p>
|
||||
|
||||
<p align="right">
|
||||
<a href="../README.md">English</a>| <a href="./README_zh.rst">中文</a>| <b>Português do Brasil</b> | <a href="./README_jp.rst">日本語</a>
|
||||
</p>
|
||||
|
||||
.. raw:: html
|
||||
|
||||
</p>
|
||||
|
||||
.. raw:: html
|
||||
|
||||
<p align="center">
|
||||
|
||||
|
||||
|
||||
.. raw:: html
|
||||
|
||||
</p>
|
||||
|
||||
|
||||
|
||||
.. raw:: html
|
||||
|
||||
<h1 align="center">
|
||||
|
||||
LVGL - Biblioteca gráfica leve e versátil
|
||||
|
||||
.. raw:: html
|
||||
|
||||
</h1>
|
||||
|
||||
|
||||
|
||||
.. raw:: html
|
||||
|
||||
<p align="center">
|
||||
|
||||
Site \| Documentação \| Fórum \| Serviços \| Demonstrações \| Editor SquareLine Studio
|
||||
|
||||
.. raw:: html
|
||||
|
||||
</p>
|
||||
|
||||
**Visão Geral**
|
||||
---------------
|
||||
|
||||
**Maduro e popular**
|
||||
|
||||
LVGL é a biblioteca gráfica incorporada gratuita e de código aberto mais
|
||||
popular para criar belas interfaces de usuário para qualquer display do
|
||||
tipo MCU, MPU. Ela é suportada por fornecedores e projetos líderes do
|
||||
setor, como ARM, STM32, NXP, Espressif, Nuvoton, Arduino, RT-Thread,
|
||||
Zephyr, NuttX, Adafruit e muitos outros.
|
||||
|
||||
**Rico em recursos**
|
||||
|
||||
Ela tem todos os recursos para a criação de GUIs modernas e bonitas:
|
||||
mais de 30 widgets integrados, um sistema de design poderoso,
|
||||
gerenciadores de layout inspirados na web e um sistema de tipografia com
|
||||
suporte para vários idiomas. Para integrar o LVGL em sua plataforma,
|
||||
tudo que você precisa é de pelo menos 32kB de RAM e 128kB de Flash, um
|
||||
compilador C, um frame buffer e pelo menos uma tela de tamanho 1/10 para
|
||||
renderização.
|
||||
|
||||
**Editor UI profissional**
|
||||
|
||||
SquareLine Studio é um editor de interface do usuário de (arrasta e
|
||||
solta) profissional para LVGL. Ele roda em Windows, Linux e MacOS também
|
||||
e você pode experimentá-lo sem se registrar no site.
|
||||
|
||||
**Serviços**
|
||||
|
||||
Nossa equipe está pronta para ajudá-lo com design gráfico, implementação
|
||||
de UI e serviços de consultoria. Entre em contato conosco se precisar de
|
||||
algum suporte durante o desenvolvimento de seu próximo projeto de GUI.
|
||||
|
||||
**Recursos**
|
||||
------------
|
||||
|
||||
**Gratuito e portátil**
|
||||
|
||||
- Uma biblioteca C totalmente portátil (compatível com C++) sem
|
||||
dependências externas.
|
||||
- Pode ser compilado para qualquer display MCU ou MPU, e qualquer
|
||||
sistema operacional de tempo real (RT-OS).
|
||||
- Suporta monitores monocromáticos, ePaper, OLED ou TFT. `Guia de
|
||||
portabilidade <https://docs.lvgl.io/master/porting/project.html>`__
|
||||
- Distribuído sob a licença do MIT, para que você também possa usá-lo
|
||||
facilmente em projetos comerciais.
|
||||
- Precisa de apenas 32 kB de RAM e 128 kB de Flash, um frame buffer e
|
||||
pelo menos uma tela de tamanho 1/10 para renderização.
|
||||
- Sistemas operacionais, memória externa e GPU são suportados, mas não
|
||||
obrigatórios.
|
||||
|
||||
**Widgets, designs, layouts e muito mais**
|
||||
|
||||
- Mais de 30 widgets integrados: botão, etiqueta (label), controle
|
||||
deslizante (slider), gráfico (chart), teclado, medidor (meter),
|
||||
tabelas e muito mais.
|
||||
- Sistema de design flexível com pelo menos 100 propriedades de estilo
|
||||
para personalizar qualquer parte dos widgets.
|
||||
- Mecanismos de layouts Flexbox e Grid para dimensionar e posicionar
|
||||
automaticamente os widgets de maneira responsiva.
|
||||
- Os textos são renderizados com codificação UTF-8, suportando sistemas
|
||||
de escrita CJK (chinês, japonês e coreano), tailandês, hindi, árabe e
|
||||
persa.
|
||||
- Quebra de palavras (word wrapping), espaçamento entre letras
|
||||
(kerning), rolagem de texto (scrolling), renderização subpixel,
|
||||
entrada em chinês Pinyin-IME e emojis.
|
||||
- Mecanismo de renderização que suporta animações, anti-aliasing,
|
||||
opacidade, rolagem suave (smooth scroll), sombras, transformação de
|
||||
imagens, etc.
|
||||
- Suporta mouse, touchpad, teclado, botões externos, dispositivos de
|
||||
entrada codificadores (encoders).
|
||||
- Suporta vários monitores.
|
||||
|
||||
**Suporte de vinculação (binding) e compilação de arquivos**
|
||||
|
||||
- Exposição da API do LVGL com o
|
||||
`Micropython <https://blog.lvgl.io/2019-02-20/micropython-bindings>`__
|
||||
- Nenhum sistema de compilação personalizado é usado. Você pode
|
||||
construir o LVGL enquanto constrói os outros arquivos do seu projeto.
|
||||
- O suporte para Make e
|
||||
`CMake <https://docs.lvgl.io/master/get-started/platforms/cmake.html>`__
|
||||
já vem incluído.
|
||||
- `Desenvolva no
|
||||
PC <https://docs.lvgl.io/master/get-started/platforms/pc-simulator.html>`__
|
||||
e use o mesmo código de interface do usuário em hardwares
|
||||
incorporados (embedded hardware).
|
||||
- Converta o código C para um arquivo HTML com o `Emscripten
|
||||
port <https://github.com/lvgl/lv_web_emscripten>`__.
|
||||
|
||||
**Documentação, ferramentas e serviços**
|
||||
|
||||
- Documentação detalhada com `+100 exemplos
|
||||
simples <https://docs.lvgl.io/master/index.html>`__
|
||||
- `SquareLine Studio <https://squareline.io>`__ - Um software editor UI
|
||||
profissional e fácil de usar, para acelerar e simplificar o
|
||||
desenvolvimento da interface do usuário.
|
||||
- `Serviços <https://lvgl.io/services>`__ como design de UI,
|
||||
implementação e consultoria para tornar o desenvolvimento de UI mais
|
||||
simples e rápido.
|
||||
|
||||
**Patrocinador**
|
||||
----------------
|
||||
|
||||
Se o LVGL economizou muito tempo e dinheiro ou você apenas se divertiu
|
||||
ao usá-lo, considere Apoiar o desenvolvimento.
|
||||
|
||||
**Como e com o que utilizamos os recursos doados?** Nosso objetivo é
|
||||
fornecer compensação financeira para as pessoas que mais fazem pelo
|
||||
LVGL. Isso significa que não apenas os mantenedores, mas qualquer pessoa
|
||||
que implemente um ótimo recurso deve receber um pagamento com o dinheiro
|
||||
acumulado. Usamos as doações para cobrir nossos custos operacionais,
|
||||
como servidores e serviços relacionados.
|
||||
|
||||
**Como doar?** Usamos o `Open
|
||||
Collective <https://opencollective.com/lvgl>`__, onde você pode enviar
|
||||
facilmente doações únicas ou recorrentes. Você também pode ver todas as
|
||||
nossas despesas de forma transparente.
|
||||
|
||||
**Como receber o pagamento de sua contribuição?** Se alguém implementar
|
||||
ou corrigir um problema rotulado como
|
||||
`Patrocinado <https://github.com/lvgl/lvgl/labels/Sponsored>`__, essa
|
||||
pessoa receberá um pagamento por esse trabalho. Estimamos o tempo
|
||||
necessário, a complexidade e a importância da questão e definimos um
|
||||
preço de acordo. Para entrar, apenas comente sobre um problema
|
||||
patrocinado dizendo "Olá, gostaria de lidar com isso. É assim que estou
|
||||
planejando corrigi-lo/implementá-lo…". Um trabalho é considerado pronto
|
||||
quando é aprovado e mesclado por um mantenedor. Depois disso, você pode
|
||||
enviar uma "despesa" (expense) pela plataforma
|
||||
`opencollective.com <https://opencollective.com/lvgl>`__ e então
|
||||
receberá o pagamento em alguns dias.
|
||||
|
||||
**Organizações que apoiam o projeto LVGL**\ |Patrocinadores do LVGL|
|
||||
|
||||
**Pessoas que apoiam o projeto LVGL**\ |Backers of LVGL|
|
||||
|
||||
**Pacotes**
|
||||
-----------
|
||||
|
||||
LVGL está disponível para:
|
||||
|
||||
- `Arduino
|
||||
library <https://docs.lvgl.io/master/get-started/platforms/arduino.html>`__
|
||||
- `PlatformIO
|
||||
package <https://registry.platformio.org/libraries/lvgl/lvgl>`__
|
||||
- `Zephyr
|
||||
library <https://docs.zephyrproject.org/latest/kconfig.html#CONFIG_LVGL>`__
|
||||
- `ESP32
|
||||
component <https://docs.lvgl.io/master/get-started/platforms/espressif.html>`__
|
||||
- `NXP MCUXpresso
|
||||
component <https://www.nxp.com/design/software/embedded-software/lvgl-open-source-graphics-library:LITTLEVGL-OPEN-SOURCE-GRAPHICS-LIBRARY>`__
|
||||
- `NuttX
|
||||
library <https://docs.lvgl.io/master/get-started/os/nuttx.html>`__
|
||||
- `RT-Thread
|
||||
RTOS <https://docs.lvgl.io/master/get-started/os/rt-thread.html>`__
|
||||
- NXP MCUXpresso library
|
||||
- CMSIS-Pack
|
||||
|
||||
**Exemplos**
|
||||
------------
|
||||
|
||||
Veja como criar um botão com um evento de clique em C e MicroPython.
|
||||
Para mais exemplos, veja a pasta
|
||||
`examples <https://github.com/lvgl/lvgl/tree/master/examples>`__.
|
||||
|
||||
.. figure:: https://github.com/lvgl/lvgl/raw/master/docs/misc/btn_example.png
|
||||
:alt: LVGL button with label example
|
||||
|
||||
LVGL button with label example
|
||||
|
||||
Botão com evento de clique
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
.. figure:: https://github.com/kisvegabor/test/raw/master/readme_example_1.gif
|
||||
:alt: Botão LVGL com exemplo de rótulo (label)
|
||||
|
||||
Botão LVGL com exemplo de rótulo (label)
|
||||
|
||||
.. raw:: html
|
||||
|
||||
<details>
|
||||
|
||||
.. raw:: html
|
||||
|
||||
<summary>
|
||||
|
||||
Código C
|
||||
|
||||
.. raw:: html
|
||||
|
||||
</summary>
|
||||
|
||||
.. code:: c
|
||||
|
||||
lv_obj_t * btn = lv_button_create(lv_screen_active()); /* Adiciona o botão a tela atual */
|
||||
lv_obj_center(btn); /* Define a posição do botão */
|
||||
lv_obj_set_size(btn, 100, 50); /* Define o tamanho do botão */
|
||||
lv_obj_add_event(btn, btn_event_cb, LV_EVENT_CLICKED, NULL); /* Atribui um retorno de chamada (callback) ao botão */
|
||||
|
||||
lv_obj_t * label = lv_label_create(btn); /* Adiciona um rótulo (label) */
|
||||
lv_label_set_text(label, "Botão"); /* Define um texto para o rótulo (label) */
|
||||
lv_obj_center(label); /* Alinha o texto no centro do botão */
|
||||
...
|
||||
|
||||
void btn_event_cb(lv_event_t * e)
|
||||
{
|
||||
printf("Clicado\n");
|
||||
}
|
||||
|
||||
.. raw:: html
|
||||
|
||||
</details>
|
||||
|
||||
.. raw:: html
|
||||
|
||||
<details>
|
||||
|
||||
.. raw:: html
|
||||
|
||||
<summary>
|
||||
|
||||
Código MicroPython \| Simulador online
|
||||
|
||||
.. raw:: html
|
||||
|
||||
</summary>
|
||||
|
||||
.. code:: python
|
||||
|
||||
def btn_event_cb(e):
|
||||
print("Clicado")
|
||||
|
||||
# Cria um botão e um rótulo (label)
|
||||
btn = lv.btn(lv.scr_act())
|
||||
btn.center()
|
||||
btn.set_size(100, 50)
|
||||
btn.add_event(btn_event_cb, lv.EVENT.CLICKED, None)
|
||||
|
||||
label = lv.label(btn)
|
||||
label.set_text("Botão")
|
||||
label.center()
|
||||
|
||||
.. raw:: html
|
||||
|
||||
</details>
|
||||
|
||||
Caixas de seleção (chackboxes) com layout
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
.. figure:: https://github.com/kisvegabor/test/raw/master/readme_example_2.gif
|
||||
:alt: Caixas de seleção (chackboxes) com layout no LVGL
|
||||
|
||||
Caixas de seleção (chackboxes) com layout no LVGL
|
||||
|
||||
.. raw:: html
|
||||
|
||||
<details>
|
||||
|
||||
.. raw:: html
|
||||
|
||||
<summary>
|
||||
|
||||
Código em C
|
||||
|
||||
.. raw:: html
|
||||
|
||||
</summary>
|
||||
|
||||
.. code:: c
|
||||
|
||||
|
||||
lv_obj_set_flex_flow(lv_screen_active(), LV_FLEX_FLOW_COLUMN);
|
||||
lv_obj_set_flex_align(lv_screen_active(), LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_START, LV_FLEX_ALIGN_CENTER);
|
||||
|
||||
lv_obj_t * cb;
|
||||
cb = lv_checkbox_create(lv_screen_active());
|
||||
lv_checkbox_set_text(cb, "Maça");
|
||||
lv_obj_add_event(cb, event_handler, LV_EVENT_ALL, NULL);
|
||||
|
||||
cb = lv_checkbox_create(lv_screen_active());
|
||||
lv_checkbox_set_text(cb, "Banana");
|
||||
lv_obj_add_state(cb, LV_STATE_CHECKED);
|
||||
lv_obj_add_event(cb, event_handler, LV_EVENT_ALL, NULL);
|
||||
|
||||
cb = lv_checkbox_create(lv_screen_active());
|
||||
lv_checkbox_set_text(cb, "Limão");
|
||||
lv_obj_add_state(cb, LV_STATE_DISABLED);
|
||||
lv_obj_add_event(cb, event_handler, LV_EVENT_ALL, NULL);
|
||||
|
||||
cb = lv_checkbox_create(lv_screen_active());
|
||||
lv_obj_add_state(cb, LV_STATE_CHECKED | LV_STATE_DISABLED);
|
||||
lv_checkbox_set_text(cb, "Melão\ne uma nova linha");
|
||||
lv_obj_add_event(cb, event_handler, LV_EVENT_ALL, NULL);
|
||||
|
||||
.. raw:: html
|
||||
|
||||
</details>
|
||||
|
||||
.. raw:: html
|
||||
|
||||
<details>
|
||||
|
||||
.. raw:: html
|
||||
|
||||
<summary>
|
||||
|
||||
Código MicroPython \| Online Simulator
|
||||
|
||||
.. raw:: html
|
||||
|
||||
</summary>
|
||||
|
||||
.. code:: python
|
||||
|
||||
def event_handler(e):
|
||||
code = e.get_code()
|
||||
obj = e.get_target_obj()
|
||||
if code == lv.EVENT.VALUE_CHANGED:
|
||||
txt = obj.get_text()
|
||||
if obj.get_state() & lv.STATE.CHECKED:
|
||||
state = "Marcador"
|
||||
else:
|
||||
state = "Desmarcado"
|
||||
print(txt + ":" + state)
|
||||
|
||||
|
||||
lv.scr_act().set_flex_flow(lv.FLEX_FLOW.COLUMN)
|
||||
lv.scr_act().set_flex_align(lv.FLEX_ALIGN.CENTER, lv.FLEX_ALIGN.START, lv.FLEX_ALIGN.CENTER)
|
||||
|
||||
cb = lv.checkbox(lv.scr_act())
|
||||
cb.set_text("Maça")
|
||||
cb.add_event(event_handler, lv.EVENT.ALL, None)
|
||||
|
||||
cb = lv.checkbox(lv.scr_act())
|
||||
cb.set_text("Banana")
|
||||
cb.add_state(lv.STATE.CHECKED)
|
||||
cb.add_event(event_handler, lv.EVENT.ALL, None)
|
||||
|
||||
cb = lv.checkbox(lv.scr_act())
|
||||
cb.set_text("Limão")
|
||||
cb.add_state(lv.STATE.DISABLED)
|
||||
cb.add_event(event_handler, lv.EVENT.ALL, None)
|
||||
|
||||
cb = lv.checkbox(lv.scr_act())
|
||||
cb.add_state(lv.STATE.CHECKED | lv.STATE.DISABLED)
|
||||
cb.set_text("Melão")
|
||||
cb.add_event(event_handler, lv.EVENT.ALL, None)
|
||||
|
||||
.. raw:: html
|
||||
|
||||
</details>
|
||||
|
||||
Estilizando um controle deslizante (slider)
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
.. figure:: https://github.com/kisvegabor/test/raw/master/readme_example_3.gif
|
||||
:alt: Estilizando um controle deslizante (slider) com LVGL
|
||||
|
||||
Estilizando um controle deslizante (slider) com LVGL
|
||||
|
||||
.. raw:: html
|
||||
|
||||
<details>
|
||||
|
||||
.. raw:: html
|
||||
|
||||
<summary>
|
||||
|
||||
Código C
|
||||
|
||||
.. raw:: html
|
||||
|
||||
</summary>
|
||||
|
||||
.. code:: c
|
||||
|
||||
lv_obj_t * slider = lv_slider_create(lv_screen_active());
|
||||
lv_slider_set_value(slider, 70, LV_ANIM_OFF);
|
||||
lv_obj_set_size(slider, 300, 20);
|
||||
lv_obj_center(slider);
|
||||
|
||||
/* Adiciona estilos locais à parte MAIN (retângulo de fundo) */
|
||||
lv_obj_set_style_bg_color(slider, lv_color_hex(0x0F1215), LV_PART_MAIN);
|
||||
lv_obj_set_style_bg_opa(slider, 255, LV_PART_MAIN);
|
||||
lv_obj_set_style_border_color(slider, lv_color_hex(0x333943), LV_PART_MAIN);
|
||||
lv_obj_set_style_border_width(slider, 5, LV_PART_MAIN);
|
||||
lv_obj_set_style_pad_all(slider, 5, LV_PART_MAIN);
|
||||
|
||||
/* Crie uma folha de estilo reutilizável para a parte do (INDICADOR) */
|
||||
static lv_style_t style_indicator;
|
||||
lv_style_init(&style_indicator);
|
||||
lv_style_set_bg_color(&style_indicator, lv_color_hex(0x37B9F5));
|
||||
lv_style_set_bg_grad_color(&style_indicator, lv_color_hex(0x1464F0));
|
||||
lv_style_set_bg_grad_dir(&style_indicator, LV_GRAD_DIR_HOR);
|
||||
lv_style_set_shadow_color(&style_indicator, lv_color_hex(0x37B9F5));
|
||||
lv_style_set_shadow_width(&style_indicator, 15);
|
||||
lv_style_set_shadow_spread(&style_indicator, 5);
|
||||
|
||||
/* Adicione a folha de estilo à parte do INDICATOR do controle deslizante (slider) */
|
||||
lv_obj_add_style(slider, &style_indicator, LV_PART_INDICATOR);
|
||||
|
||||
/* Adicione o mesmo estilo à parte do KNOB e sobrescreva localmente algumas propriedades */
|
||||
lv_obj_add_style(slider, &style_indicator, LV_PART_KNOB);
|
||||
|
||||
lv_obj_set_style_outline_color(slider, lv_color_hex(0x0096FF), LV_PART_KNOB);
|
||||
lv_obj_set_style_outline_width(slider, 3, LV_PART_KNOB);
|
||||
lv_obj_set_style_outline_pad(slider, -5, LV_PART_KNOB);
|
||||
lv_obj_set_style_shadow_spread(slider, 2, LV_PART_KNOB);
|
||||
|
||||
.. raw:: html
|
||||
|
||||
</details>
|
||||
|
||||
.. raw:: html
|
||||
|
||||
<details>
|
||||
|
||||
.. raw:: html
|
||||
|
||||
<summary>
|
||||
|
||||
Código MicroPython \| Simulador online
|
||||
|
||||
.. raw:: html
|
||||
|
||||
</summary>
|
||||
|
||||
.. code:: python
|
||||
|
||||
# Crie um controle deslizante (slider) e adicione o estilo
|
||||
slider = lv.slider(lv.scr_act())
|
||||
slider.set_value(70, lv.ANIM.OFF)
|
||||
slider.set_size(300, 20)
|
||||
slider.center()
|
||||
|
||||
# Adicione estilos locais à parte MAIN (retângulo de fundo)
|
||||
slider.set_style_bg_color(lv.color_hex(0x0F1215), lv.PART.MAIN)
|
||||
slider.set_style_bg_opa(255, lv.PART.MAIN)
|
||||
slider.set_style_border_color(lv.color_hex(0x333943), lv.PART.MAIN)
|
||||
slider.set_style_border_width(5, lv.PART.MAIN)
|
||||
slider.set_style_pad_all(5, lv.PART.MAIN)
|
||||
|
||||
# Crie uma folha de estilo reutilizável para a parte do INDICATOR
|
||||
style_indicator = lv.style_t()
|
||||
style_indicator.init()
|
||||
style_indicator.set_bg_color(lv.color_hex(0x37B9F5))
|
||||
style_indicator.set_bg_grad_color(lv.color_hex(0x1464F0))
|
||||
style_indicator.set_bg_grad_dir(lv.GRAD_DIR.HOR)
|
||||
style_indicator.set_shadow_color(lv.color_hex(0x37B9F5))
|
||||
style_indicator.set_shadow_width(15)
|
||||
style_indicator.set_shadow_spread(5)
|
||||
|
||||
# Adicione a folha de estilo à parte do INDICATOR do controle deslizante (slider)
|
||||
slider.add_style(style_indicator, lv.PART.INDICATOR)
|
||||
slider.add_style(style_indicator, lv.PART.KNOB)
|
||||
|
||||
# Adicione o mesmo estilo à parte do KNOB e sobrescreva localmente algumas propriedades
|
||||
slider.set_style_outline_color(lv.color_hex(0x0096FF), lv.PART.KNOB)
|
||||
slider.set_style_outline_width(3, lv.PART.KNOB)
|
||||
slider.set_style_outline_pad(-5, lv.PART.KNOB)
|
||||
slider.set_style_shadow_spread(2, lv.PART.KNOB)
|
||||
|
||||
.. raw:: html
|
||||
|
||||
</details>
|
||||
|
||||
Textos em inglês, hebraico (LRT-RTL misto) e chinês
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
.. figure:: https://github.com/kisvegabor/test/raw/master/readme_example_4.png
|
||||
:alt: Textos em inglês, hebraico (LRT-RTL misto) e chinês com LVGL
|
||||
|
||||
Textos em inglês, hebraico (LRT-RTL misto) e chinês com LVGL
|
||||
|
||||
.. raw:: html
|
||||
|
||||
<details>
|
||||
|
||||
.. raw:: html
|
||||
|
||||
<summary>
|
||||
|
||||
Código C
|
||||
|
||||
.. raw:: html
|
||||
|
||||
</summary>
|
||||
|
||||
.. code:: c
|
||||
|
||||
lv_obj_t * ltr_label = lv_label_create(lv_screen_active());
|
||||
lv_label_set_text(ltr_label, "In modern terminology, a microcontroller is similar to a system on a chip (SoC).");
|
||||
lv_obj_set_style_text_font(ltr_label, &lv_font_montserrat_16, 0);
|
||||
lv_obj_set_width(ltr_label, 310);
|
||||
lv_obj_align(ltr_label, LV_ALIGN_TOP_LEFT, 5, 5);
|
||||
|
||||
lv_obj_t * rtl_label = lv_label_create(lv_screen_active());
|
||||
lv_label_set_text(rtl_label,"מעבד, או בשמו המלא יחידת עיבוד מרכזית (באנגלית: CPU - Central Processing Unit).");
|
||||
lv_obj_set_style_base_dir(rtl_label, LV_BASE_DIR_RTL, 0);
|
||||
lv_obj_set_style_text_font(rtl_label, &lv_font_dejavu_16_persian_hebrew, 0);
|
||||
lv_obj_set_width(rtl_label, 310);
|
||||
lv_obj_align(rtl_label, LV_ALIGN_LEFT_MID, 5, 0);
|
||||
|
||||
lv_obj_t * cz_label = lv_label_create(lv_screen_active());
|
||||
lv_label_set_text(cz_label,
|
||||
"嵌入式系统(Embedded System),\n是一种嵌入机械或电气系统内部、具有专一功能和实时计算性能的计算机系统。");
|
||||
lv_obj_set_style_text_font(cz_label, &lv_font_simsun_16_cjk, 0);
|
||||
lv_obj_set_width(cz_label, 310);
|
||||
lv_obj_align(cz_label, LV_ALIGN_BOTTOM_LEFT, 5, -5);
|
||||
|
||||
.. raw:: html
|
||||
|
||||
</details>
|
||||
|
||||
.. raw:: html
|
||||
|
||||
<details>
|
||||
|
||||
.. raw:: html
|
||||
|
||||
<summary>
|
||||
|
||||
Código MicroPython \| Simulador online
|
||||
|
||||
.. raw:: html
|
||||
|
||||
</summary>
|
||||
|
||||
.. code:: python
|
||||
|
||||
ltr_label = lv.label(lv.scr_act())
|
||||
ltr_label.set_text("In modern terminology, a microcontroller is similar to a system on a chip (SoC).")
|
||||
ltr_label.set_style_text_font(lv.font_montserrat_16, 0);
|
||||
|
||||
ltr_label.set_width(310)
|
||||
ltr_label.align(lv.ALIGN.TOP_LEFT, 5, 5)
|
||||
|
||||
rtl_label = lv.label(lv.scr_act())
|
||||
rtl_label.set_text("מעבד, או בשמו המלא יחידת עיבוד מרכזית (באנגלית: CPU - Central Processing Unit).")
|
||||
rtl_label.set_style_base_dir(lv.BASE_DIR.RTL, 0)
|
||||
rtl_label.set_style_text_font(lv.font_dejavu_16_persian_hebrew, 0)
|
||||
rtl_label.set_width(310)
|
||||
rtl_label.align(lv.ALIGN.LEFT_MID, 5, 0)
|
||||
|
||||
font_simsun_16_cjk = lv.font_load("S:../../assets/font/lv_font_simsun_16_cjk.fnt")
|
||||
|
||||
cz_label = lv.label(lv.scr_act())
|
||||
cz_label.set_style_text_font(font_simsun_16_cjk, 0)
|
||||
cz_label.set_text("嵌入式系统(Embedded System),\n是一种嵌入机械或电气系统内部、具有专一功能和实时计算性能的计算机系统。")
|
||||
cz_label.set_width(310)
|
||||
cz_label.align(lv.ALIGN.BOTTOM_LEFT, 5, -5)
|
||||
|
||||
.. raw:: html
|
||||
|
||||
</details>
|
||||
|
||||
**Começando**
|
||||
-------------
|
||||
|
||||
Esta lista irá guiá-lo para começar com o LVGL passo a passo.
|
||||
|
||||
**Familiarize-se com o LVGL**
|
||||
|
||||
1. Confira as `demos on-line <https://lvgl.io/demos>`__ para ver o LVGL
|
||||
em ação (~3 minutos)
|
||||
2. Leia a página de
|
||||
`introdução <https://docs.lvgl.io/master/intro/index.html>`__ da
|
||||
documentação (~5 minutos)
|
||||
3. Familiarize-se com o básico na página de `visão geral
|
||||
rápida <https://docs.lvgl.io/master/get-started/quick-overview.html>`__
|
||||
(~15 minutos)
|
||||
|
||||
**Começando a usar o LVGL**
|
||||
|
||||
4. Configure um
|
||||
`simulador <https://docs.lvgl.io/master/get-started/platforms/pc-simulator.html>`__
|
||||
(~10 minutos)
|
||||
5. Experimente alguns
|
||||
`exemplos <https://github.com/lvgl/lvgl/tree/master/examples>`__
|
||||
6. Porte o LVGL para uma placa. Veja o guia `portando o
|
||||
LVGL <https://docs.lvgl.io/master/porting/index.html>`__ ou veja um
|
||||
projeto pronto para usar em
|
||||
`projetos <https://github.com/lvgl?q=lv_port_>`__
|
||||
|
||||
**Torne-se um profissional**
|
||||
|
||||
7. Leia a página `visão
|
||||
geral <https://docs.lvgl.io/master/overview/index.html>`__ para
|
||||
entender melhor a biblioteca (~2-3 horas)
|
||||
8. Verifique a documentação dos
|
||||
`widgets <https://docs.lvgl.io/master/widgets/index.html>`__ para ver
|
||||
seus recursos e usabilidade
|
||||
|
||||
**Obtenha ajuda e ajude outras pessoas**
|
||||
|
||||
9. Se você tiver dúvidas, acesse o `Fórum <http://forum.lvgl.io>`__
|
||||
10. Leia o guia de
|
||||
`contribuição <https://docs.lvgl.io/master/CONTRIBUTING.html>`__
|
||||
para ver como você pode ajudar a melhorar o LVGL (~15 minutos)
|
||||
|
||||
**E mais**
|
||||
|
||||
11. Baixe e experimente o editor `SquareLine
|
||||
Studio <https://squareline.io>`__.
|
||||
12. Entre em contato conosco para `serviços e
|
||||
consultoria <https://lvgl.io/services>`__.
|
||||
|
||||
**Serviços**
|
||||
------------
|
||||
|
||||
A LVGL LLC foi criada para fornecer uma base sólida para a biblioteca
|
||||
LVGL e oferecer vários tipos de serviços para ajudá-lo no
|
||||
desenvolvimento da sua interface do usuário. Com mais de 15 anos de
|
||||
experiência na indústria gráfica e de interface do usuário, podemos
|
||||
ajudá-lo a levar sua interface do usuário para o próximo nível.
|
||||
|
||||
- **Design gráfico**: Nossos designers gráficos internos são
|
||||
especialistas em criar belos designs modernos que se adaptam ao seu
|
||||
produto e aos recursos do seu hardware.
|
||||
- **Implementação da interface do usuário**: Também podemos implementar
|
||||
sua interface do usuário com base no design que você ou nós criamos.
|
||||
Você pode ter certeza de que tiraremos o máximo proveito de seu
|
||||
hardware e do LVGL. Se um recurso ou widget estiver faltando no LVGL,
|
||||
não se preocupe, nós o implementaremos para você.
|
||||
- **Consultoria e Suporte**: Também podemos apoiá-lo com consultoria
|
||||
para evitar erros que podem te custar caros durante o desenvolvimento
|
||||
da sua interface do usuário.
|
||||
- **Certificação**: Para empresas que oferecem placas para
|
||||
desenvolvimento ou kits prontos para produção, fazemos certificação
|
||||
que mostram como uma placa pode executar o LVGL.
|
||||
|
||||
Confira nossas `demonstrações <https://lvgl.io/demos>`__ como
|
||||
referência. Para obter mais informações, consulte a `página de
|
||||
serviços <https://lvgl.io/services>`__.
|
||||
|
||||
`Fale conosco <https://lvgl.io/#contact>`__ e conte como podemos ajudar.
|
||||
|
||||
**Contribuindo**
|
||||
----------------
|
||||
|
||||
O LVGL é um projeto aberto e sua contribuição é muito bem-vinda. Há
|
||||
muitas maneiras de contribuir, desde simplesmente falando sobre seu
|
||||
projeto, escrevendo exemplos, melhorando a documentação, corrigindo bugs
|
||||
até hospedar seu próprio projeto sob a organização LVGL.
|
||||
|
||||
Para obter uma descrição detalhada das oportunidades de contribuição,
|
||||
visite a página de
|
||||
`contribuição <https://docs.lvgl.io/master/CONTRIBUTING.html>`__ da
|
||||
documentação.
|
||||
|
||||
Mais de 300 pessoas já deixaram sua impressão digital no LVGL. Seja um
|
||||
deles! Veja o seu aqui! :slightly_smiling_face:
|
||||
|
||||
… e muitos outros.
|
||||
|
||||
.. |Patrocinadores do LVGL| image:: https://opencollective.com/lvgl/organizations.svg?width=600
|
||||
:target: https://opencollective.com/lvgl
|
||||
.. |Backers of LVGL| image:: https://opencollective.com/lvgl/individuals.svg?width=600
|
||||
:target: https://opencollective.com/lvgl
|
||||
604
libraries/lvgl/docs/README_zh.rst
Normal file
@@ -0,0 +1,604 @@
|
||||
.. raw:: html
|
||||
|
||||
<p align="left">
|
||||
<a href="https://github.com/sponsors/lvgl" target="_blank"><img align="left" src="https://lvgl.io/github-assets/sponsor.png" height="32px"></a>
|
||||
</p>
|
||||
|
||||
<p align="right">
|
||||
<a href="../README.md">English</a>| <b>中文</b>| <a href="./README_pt_BR.rst">Português do Brasil</a> | <a href="./README_jp.rst">日本語</a>
|
||||
</p>
|
||||
|
||||
.. raw:: html
|
||||
|
||||
<br>
|
||||
|
||||
.. raw:: html
|
||||
|
||||
<p align="center">
|
||||
<img src="https://lvgl.io/github-assets/logo-colored.png" width=300px>
|
||||
</p>
|
||||
|
||||
.. raw:: html
|
||||
|
||||
<h1 align="center">
|
||||
轻量级通用型图形库
|
||||
|
||||
.. raw:: html
|
||||
|
||||
</h1>
|
||||
|
||||
.. raw:: html
|
||||
|
||||
<div align="center">
|
||||
<img src="https://lvgl.io/github-assets/smartwatch-demo.gif">
|
||||
|
||||
<img border="1px" src="https://lvgl.io/github-assets/widgets-demo.gif">
|
||||
</div>
|
||||
<br>
|
||||
<p align="center">
|
||||
<a href="https://lvgl.io" title="Homepage of LVGL">官网 </a> |
|
||||
<a href="https://docs.lvgl.io/" title="Detailed documentation with 100+ examples">文档</a> |
|
||||
<a href="https://forum.lvgl.io" title="Get help and help others">论坛</a> |
|
||||
<a href="https://lvgl.io/demos" title="Demos running in your browser">示例</a> |
|
||||
<a href="https://lvgl.io/services" title="Graphics design, UI implementation and consulting">服务</a>
|
||||
</p>
|
||||
<br>
|
||||
|
||||
.. _ledger-概况与总览:
|
||||
|
||||
📒 概况与总览
|
||||
-------------
|
||||
|
||||
**成熟且知名**\
|
||||
|
||||
LVGL 是最流行的免费开源嵌入式图形库,可以为任何 MCU、MPU 和显示类型创建漂亮的 UI。它得到了行业领先供应商和项目的支持,如 Arm、STM32、NXP、Espressif、Nuvoton、Arduino、RT-Thread、Zephyr、NuttX、Adafruit 等。
|
||||
|
||||
**功能丰富**\
|
||||
|
||||
它拥有创建现代美观 GUI 的所有功能:30 多个内置控件、强大的样式系统、Web 启发的布局管理器和支持多种语言的排版系统。要将 LVGL 集成到您的平台中,您只需要至少 32 KB
|
||||
RAM 和 128 KB Flash、C 编译器、帧缓冲区和至少 1/10 屏幕大小的渲染缓冲区。
|
||||
|
||||
**服务**\
|
||||
|
||||
我们的团队随时准备为您提供图形设计、UI 实现和咨询服务。如果您在开发下一个 GUI 项目时需要一些支持,请与我们联系。
|
||||
|
||||
.. _rocket-特性:
|
||||
|
||||
🚀 特性
|
||||
-------
|
||||
|
||||
**免费和可移植性**
|
||||
|
||||
- 一个完全可移植的 C(C++ 兼容)库,没有外部依赖关系。
|
||||
- 可以编译到任何 MCU 或 MPU,使用任何 RTOS 或者操作系统。
|
||||
- 支持单色、ePaper、OLED、TFT 显示器或者模拟器。
|
||||
`移植指南 <https://docs.lvgl.io/master/porting/project.html>`__
|
||||
- 该项目使用 MIT 许可证,因此您可以在商业项目中轻松使用它。
|
||||
- 仅需 32 KB RAM 和 128 KB Flash,一个帧缓冲区,以及至少 1/10 屏幕大小的渲染缓冲区。
|
||||
- 支持使用可选的操作系统、外部存储器和 GPU。
|
||||
|
||||
**控件、样式、布局等**
|
||||
|
||||
- 30+ 内置\ `控件 <https://docs.lvgl.io/master/widgets/index.html>`__:
|
||||
按钮、标签、滑块、图表、键盘、仪表、弧形、表格等等。
|
||||
- 灵活的\ `样式系统 <https://docs.lvgl.io/master/overview/style.html>`__
|
||||
支持约 100 个样式属性,可在任何状态下自定义控件的任何部分。
|
||||
- `Flex 布局 <https://docs.lvgl.io/master/layouts/flex.html>`__ 和
|
||||
`Grid 布局 <https://docs.lvgl.io/master/layouts/grid.html>`__
|
||||
可以响应式自动调整控件的大小和位置。
|
||||
- 文本支持 UTF-8 编码,支持 CJK、泰语、印地语、阿拉伯语和波斯语书写系统。
|
||||
- 支持自动换行、字距调整、文本滚动、亚像素渲染、拼音输入法、文本表情符号。
|
||||
- 渲染引擎支持动画、抗锯齿、不透明度、平滑滚动、阴影、图形变换等。
|
||||
- 支持鼠标、触摸板、小键盘、键盘、外部按钮、编码器\ `输入设备 <https://docs.lvgl.io/master/porting/indev.html>`__\ 。
|
||||
- 支持\ `多显示器 <https://docs.lvgl.io/master/overview/display.html#multiple-display-support>`__\ 。
|
||||
|
||||
**绑定和构建支持**
|
||||
|
||||
- `MicroPython 绑定 <https://blog.lvgl.io/2019-02-20/micropython-bindings>`__
|
||||
公开 LVGL的API
|
||||
- `PikaScript 绑定 <https://blog.lvgl.io/2022-08-24/pikascript-and-lvgl>`__
|
||||
在 MCU 上的更轻更简单的 Python 版本
|
||||
- 未使用自定义生成系统。您可以在构建项目的其他文件时构建 LVGL。
|
||||
- 支持开箱即用的 Make 和 \ `CMake <https://docs.lvgl.io/master/integration/building/cmake.html>`__\ 编译系统。
|
||||
- 支持在 \ `PC 上开发 <https://docs.lvgl.io/master/integration/ide/pc-simulator.html>`__\ ,并可以在嵌入式硬件上使用相同的 UI 代码。
|
||||
- 支持使用我们的 \ `Emscripten 移植 <https://github.com/lvgl/lv_web_emscripten>`__\ 从而将 C 写的 UI 代码转换为 HTML 文件。
|
||||
|
||||
**文档、工具和服务**
|
||||
|
||||
- 包含 \ `100 多个简单示例 <https://docs.lvgl.io/master/index.html>`__\ 的详细\ `文档 <https://docs.lvgl.io/>`__
|
||||
- `服务 <https://lvgl.io/services>`__
|
||||
如用户界面设计、实施和咨询,使 UI 开发更简单、更快。
|
||||
|
||||
.. _heart-赞助:
|
||||
|
||||
❤️ 赞助
|
||||
-------
|
||||
|
||||
如果 LVGL 为您节省了大量时间和金钱,或者您只是在使用它时玩得很开心,请考虑\ `支持它的开发 <https://github.com/sponsors/lvgl>`__\ 。
|
||||
|
||||
**我们如何使用捐赠?**\
|
||||
|
||||
我们的目标是为 LVGL 做得最多的人提供经济补偿。这意味着不仅维护人员,而且任何实现伟大功能的人都应该从累积的资金中获得报酬。我们用捐款来支付服务器和相关服务等运营成本。
|
||||
|
||||
**如何捐赠?**\
|
||||
|
||||
我们使用 \ `GitHub Sponsors <https://github.com/sponsors/lvgl>`__\ ,您可以轻松发送一次性或定期捐款。您还可以以透明的方式查看我们的所有费用。
|
||||
|
||||
**如何从您的贡献中获取报酬?**\
|
||||
|
||||
如果有人实施或修复了一个标记为\ `赞助 <https://github.com/lvgl/lvgl/labels/Sponsored>`__\ 的问题,他或她将获得该工作的报酬。我们估计问题所需的时间、复杂性和重要性,并据此设定价格。直接评论一个赞助的问题,说“嗨,我想处理它。这就是我计划修复/实施它的方式…”。当维护人员批准并合并工作时,就认为它已经准备好了。之后,您可以在 \ `opencollective.com <https://opencollective.com/lvgl>`__\ 上提交并支付费用,几天后您将收到付款。
|
||||
|
||||
**支持 LVGL 的组织**\
|
||||
|
||||
|Sponsors of LVGL|
|
||||
|
||||
**支持 LVGL 的个人**\
|
||||
|
||||
|Backers of LVGL|
|
||||
|
||||
.. _package-支持包:
|
||||
|
||||
📦 支持包
|
||||
---------
|
||||
|
||||
LVGL 可用于以下几种:
|
||||
|
||||
- `Arduino
|
||||
library <https://docs.lvgl.io/master/integration/framework/arduino.html>`__
|
||||
- `PlatformIO
|
||||
package <https://registry.platformio.org/libraries/lvgl/lvgl>`__
|
||||
- `Zephyr
|
||||
library <https://docs.lvgl.io/master/integration/os/zephyr.html>`__
|
||||
- `ESP-IDF(ESP32)
|
||||
component <https://components.espressif.com/components/lvgl/lvgl>`__
|
||||
- `NXP MCUXpresso
|
||||
component <https://www.nxp.com/design/software/embedded-software/lvgl-open-source-graphics-library:LITTLEVGL-OPEN-SOURCE-GRAPHICS-LIBRARY>`__
|
||||
- `NuttX
|
||||
library <https://docs.lvgl.io/master/integration/os/nuttx.html>`__
|
||||
- `RT-Thread
|
||||
RTOS <https://docs.lvgl.io/master/integration/os/rt-thread.html>`__
|
||||
- CMSIS-Pack
|
||||
- `RIOT OS
|
||||
package <https://doc.riot-os.org/group__pkg__lvgl.html#details>`__
|
||||
|
||||
.. _robot-示例:
|
||||
|
||||
🤖 示例
|
||||
-------
|
||||
|
||||
请参阅创建控件、使用布局和应用样式的一些示例。您将找到 C 和 MicroPython 代码,以及在在线 MicroPython 编辑器中尝试或编辑示例的链接。
|
||||
|
||||
如果要查看更多示例,可查看 \ `Examples <https://github.com/lvgl/lvgl/tree/master/examples>`__ 文件夹。
|
||||
|
||||
Hello world 标签
|
||||
~~~~~~~~~~~~~~~~
|
||||
|
||||
.. image:: https://github.com/kisvegabor/test/raw/master/readme_example_1.png
|
||||
:alt: Simple Hello world label example in LVGL
|
||||
|
||||
.. raw:: html
|
||||
|
||||
<details>
|
||||
<summary>C code</summary>
|
||||
|
||||
.. code:: c
|
||||
|
||||
/*Change the active screen's background color*/
|
||||
lv_obj_set_style_bg_color(lv_screen_active(), lv_color_hex(0x003a57), LV_PART_MAIN);
|
||||
|
||||
/*Create a white label, set its text and align it to the center*/
|
||||
lv_obj_t * label = lv_label_create(lv_screen_active());
|
||||
lv_label_set_text(label, "Hello world");
|
||||
lv_obj_set_style_text_color(lv_screen_active(), lv_color_hex(0xffffff), LV_PART_MAIN);
|
||||
lv_obj_align(label, LV_ALIGN_CENTER, 0, 0);
|
||||
|
||||
.. raw:: html
|
||||
|
||||
</details>
|
||||
|
||||
.. raw:: html
|
||||
|
||||
<details>
|
||||
<summary>MicroPython code | <a href="https://sim.lvgl.io/v8.3/micropython/ports/javascript/index.html?script_direct=4ab7c40c35b0dc349aa2f0c3b00938d7d8e8ac9f" target="_blank">在线模拟器</a></summary>
|
||||
|
||||
.. code:: python
|
||||
|
||||
# Change the active screen's background color
|
||||
scr = lv.screen_active()
|
||||
scr.set_style_bg_color(lv.color_hex(0x003a57), lv.PART.MAIN)
|
||||
|
||||
# Create a white label, set its text and align it to the center
|
||||
label = lv.label(lv.screen_active())
|
||||
label.set_text("Hello world")
|
||||
label.set_style_text_color(lv.color_hex(0xffffff), lv.PART.MAIN)
|
||||
label.align(lv.ALIGN.CENTER, 0, 0)
|
||||
|
||||
.. raw:: html
|
||||
|
||||
</details>
|
||||
<br>
|
||||
|
||||
按钮与点击事件
|
||||
~~~~~~~~~~~~~~
|
||||
|
||||
.. image:: https://github.com/kisvegabor/test/raw/master/readme_example_2.gif
|
||||
:alt: LVGL button with label example
|
||||
|
||||
.. raw:: html
|
||||
|
||||
<details>
|
||||
<summary>C code</summary>
|
||||
|
||||
.. code:: c
|
||||
|
||||
lv_obj_t * button = lv_button_create(lv_screen_active()); /*Add a button to the current screen*/
|
||||
lv_obj_center(button); /*Set its position*/
|
||||
lv_obj_set_size(button, 100, 50); /*Set its size*/
|
||||
lv_obj_add_event_cb(button, button_event_cb, LV_EVENT_CLICKED, NULL); /*Assign a callback to the button*/
|
||||
|
||||
lv_obj_t * label = lv_label_create(button); /*Add a label to the button*/
|
||||
lv_label_set_text(label, "Button"); /*Set the labels text*/
|
||||
lv_obj_center(label); /*Align the label to the center*/
|
||||
...
|
||||
|
||||
void button_event_cb(lv_event_t * e)
|
||||
{
|
||||
printf("Clicked\n");
|
||||
}
|
||||
|
||||
.. raw:: html
|
||||
|
||||
</details>
|
||||
|
||||
.. raw:: html
|
||||
|
||||
<details>
|
||||
<summary>MicroPython code | <a href="https://sim.lvgl.io/v8.3/micropython/ports/javascript/index.html?script_startup=https://raw.githubusercontent.com/lvgl/lvgl/0d9ab4ee0e591aad1970e3c9164fd7c544ecce70/examples/header.py&script=https://raw.githubusercontent.com/lvgl/lvgl/0d9ab4ee0e591aad1970e3c9164fd7c544ecce70/examples/widgets/slider/lv_example_slider_2.py&script_direct=926bde43ec7af0146c486de470c53f11f167491e" target="_blank">在线模拟器</a></summary>
|
||||
|
||||
.. code:: python
|
||||
|
||||
def button_event_cb(e):
|
||||
print("Clicked")
|
||||
|
||||
# Create a Button and a Label
|
||||
button = lv.button(lv.screen_active())
|
||||
button.center()
|
||||
button.set_size(100, 50)
|
||||
button.add_event_cb(button_event_cb, lv.EVENT.CLICKED, None)
|
||||
|
||||
label = lv.label(button)
|
||||
label.set_text("Button")
|
||||
label.center()
|
||||
|
||||
.. raw:: html
|
||||
|
||||
</details>
|
||||
<br>
|
||||
|
||||
带布局的复选框
|
||||
~~~~~~~~~~~~~~
|
||||
|
||||
.. image:: https://github.com/kisvegabor/test/raw/master/readme_example_3.gif
|
||||
:alt: Checkboxes with layout in LVGL
|
||||
|
||||
.. raw:: html
|
||||
|
||||
<details>
|
||||
<summary>C code</summary>
|
||||
|
||||
.. code:: c
|
||||
|
||||
|
||||
lv_obj_set_flex_flow(lv_screen_active(), LV_FLEX_FLOW_COLUMN);
|
||||
lv_obj_set_flex_align(lv_screen_active(), LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_START, LV_FLEX_ALIGN_CENTER);
|
||||
|
||||
lv_obj_t * cb;
|
||||
cb = lv_checkbox_create(lv_screen_active());
|
||||
lv_checkbox_set_text(cb, "Apple");
|
||||
lv_obj_add_event_cb(cb, event_handler, LV_EVENT_ALL, NULL);
|
||||
|
||||
cb = lv_checkbox_create(lv_screen_active());
|
||||
lv_checkbox_set_text(cb, "Banana");
|
||||
lv_obj_add_state(cb, LV_STATE_CHECKED);
|
||||
lv_obj_add_event_cb(cb, event_handler, LV_EVENT_ALL, NULL);
|
||||
|
||||
cb = lv_checkbox_create(lv_screen_active());
|
||||
lv_checkbox_set_text(cb, "Lemon");
|
||||
lv_obj_add_state(cb, LV_STATE_DISABLED);
|
||||
lv_obj_add_event_cb(cb, event_handler, LV_EVENT_ALL, NULL);
|
||||
|
||||
cb = lv_checkbox_create(lv_screen_active());
|
||||
lv_obj_add_state(cb, LV_STATE_CHECKED | LV_STATE_DISABLED);
|
||||
lv_checkbox_set_text(cb, "Melon\nand a new line");
|
||||
lv_obj_add_event_cb(cb, event_handler, LV_EVENT_ALL, NULL);
|
||||
|
||||
.. raw:: html
|
||||
|
||||
</details>
|
||||
|
||||
.. raw:: html
|
||||
|
||||
<details>
|
||||
<summary>MicroPython code | <a href="https://sim.lvgl.io/v8.3/micropython/ports/javascript/index.html?script_startup=https://raw.githubusercontent.com/lvgl/lvgl/0d9ab4ee0e591aad1970e3c9164fd7c544ecce70/examples/header.py&script=https://raw.githubusercontent.com/lvgl/lvgl/0d9ab4ee0e591aad1970e3c9164fd7c544ecce70/examples/widgets/slider/lv_example_slider_2.py&script_direct=311d37e5f70daf1cb0d2cad24c7f72751b5f1792" target="_blank">在线模拟器</a></summary>
|
||||
|
||||
.. code:: python
|
||||
|
||||
def event_handler(e):
|
||||
code = e.get_code()
|
||||
obj = e.get_target_obj()
|
||||
if code == lv.EVENT.VALUE_CHANGED:
|
||||
txt = obj.get_text()
|
||||
if obj.get_state() & lv.STATE.CHECKED:
|
||||
state = "Checked"
|
||||
else:
|
||||
state = "Unchecked"
|
||||
print(txt + ":" + state)
|
||||
|
||||
|
||||
lv.screen_active().set_flex_flow(lv.FLEX_FLOW.COLUMN)
|
||||
lv.screen_active().set_flex_align(lv.FLEX_ALIGN.CENTER, lv.FLEX_ALIGN.START, lv.FLEX_ALIGN.CENTER)
|
||||
|
||||
cb = lv.checkbox(lv.screen_active())
|
||||
cb.set_text("Apple")
|
||||
cb.add_event_cb(event_handler, lv.EVENT.ALL, None)
|
||||
|
||||
cb = lv.checkbox(lv.screen_active())
|
||||
cb.set_text("Banana")
|
||||
cb.add_state(lv.STATE.CHECKED)
|
||||
cb.add_event_cb(event_handler, lv.EVENT.ALL, None)
|
||||
|
||||
cb = lv.checkbox(lv.screen_active())
|
||||
cb.set_text("Lemon")
|
||||
cb.add_state(lv.STATE.DISABLED)
|
||||
cb.add_event_cb(event_handler, lv.EVENT.ALL, None)
|
||||
|
||||
cb = lv.checkbox(lv.screen_active())
|
||||
cb.add_state(lv.STATE.CHECKED | lv.STATE.DISABLED)
|
||||
cb.set_text("Melon")
|
||||
cb.add_event_cb(event_handler, lv.EVENT.ALL, None)
|
||||
|
||||
.. raw:: html
|
||||
|
||||
</details>
|
||||
<br>
|
||||
|
||||
设置滑块的样式
|
||||
~~~~~~~~~~~~~~
|
||||
|
||||
.. image:: https://github.com/kisvegabor/test/raw/master/readme_example_4.gif
|
||||
:alt: Styling a slider with LVGL
|
||||
|
||||
.. raw:: html
|
||||
|
||||
<details>
|
||||
<summary>C code</summary>
|
||||
|
||||
.. code:: c
|
||||
|
||||
lv_obj_t * slider = lv_slider_create(lv_screen_active());
|
||||
lv_slider_set_value(slider, 70, LV_ANIM_OFF);
|
||||
lv_obj_set_size(slider, 300, 20);
|
||||
lv_obj_center(slider);
|
||||
|
||||
/*Add local styles to MAIN part (background rectangle)*/
|
||||
lv_obj_set_style_bg_color(slider, lv_color_hex(0x0F1215), LV_PART_MAIN);
|
||||
lv_obj_set_style_bg_opa(slider, 255, LV_PART_MAIN);
|
||||
lv_obj_set_style_border_color(slider, lv_color_hex(0x333943), LV_PART_MAIN);
|
||||
lv_obj_set_style_border_width(slider, 5, LV_PART_MAIN);
|
||||
lv_obj_set_style_pad_all(slider, 5, LV_PART_MAIN);
|
||||
|
||||
/*Create a reusable style sheet for the INDICATOR part*/
|
||||
static lv_style_t style_indicator;
|
||||
lv_style_init(&style_indicator);
|
||||
lv_style_set_bg_color(&style_indicator, lv_color_hex(0x37B9F5));
|
||||
lv_style_set_bg_grad_color(&style_indicator, lv_color_hex(0x1464F0));
|
||||
lv_style_set_bg_grad_dir(&style_indicator, LV_GRAD_DIR_HOR);
|
||||
lv_style_set_shadow_color(&style_indicator, lv_color_hex(0x37B9F5));
|
||||
lv_style_set_shadow_width(&style_indicator, 15);
|
||||
lv_style_set_shadow_spread(&style_indicator, 5);
|
||||
4
|
||||
/*Add the style sheet to the slider's INDICATOR part*/
|
||||
lv_obj_add_style(slider, &style_indicator, LV_PART_INDICATOR);
|
||||
|
||||
/*Add the same style to the KNOB part too and locally overwrite some properties*/
|
||||
lv_obj_add_style(slider, &style_indicator, LV_PART_KNOB);
|
||||
|
||||
lv_obj_set_style_outline_color(slider, lv_color_hex(0x0096FF), LV_PART_KNOB);
|
||||
lv_obj_set_style_outline_width(slider, 3, LV_PART_KNOB);
|
||||
lv_obj_set_style_outline_pad(slider, -5, LV_PART_KNOB);
|
||||
lv_obj_set_style_shadow_spread(slider, 2, LV_PART_KNOB);
|
||||
|
||||
.. raw:: html
|
||||
|
||||
</details>
|
||||
|
||||
.. raw:: html
|
||||
|
||||
<details>
|
||||
<summary>MicroPython code |
|
||||
<a href="https://sim.lvgl.io/v8.3/micropython/ports/javascript/index.html?script_startup=https://raw.githubusercontent.com/lvgl/lvgl/0d9ab4ee0e591aad1970e3c9164fd7c544ecce70/examples/header.py&script=https://raw.githubusercontent.com/lvgl/lvgl/0d9ab4ee0e591aad1970e3c9164fd7c544ecce70/examples/widgets/slider/lv_example_slider_2.py&script_direct=c431c7b4dfd2cc0dd9c392b74365d5af6ea986f0" target="_blank">在线模拟器</a>
|
||||
</summary>
|
||||
|
||||
.. code:: python
|
||||
|
||||
# Create a slider and add the style
|
||||
slider = lv.slider(lv.screen_active())
|
||||
slider.set_value(70, lv.ANIM.OFF)
|
||||
slider.set_size(300, 20)
|
||||
slider.center()
|
||||
|
||||
# Add local styles to MAIN part (background rectangle)
|
||||
slider.set_style_bg_color(lv.color_hex(0x0F1215), lv.PART.MAIN)
|
||||
slider.set_style_bg_opa(255, lv.PART.MAIN)
|
||||
slider.set_style_border_color(lv.color_hex(0x333943), lv.PART.MAIN)
|
||||
slider.set_style_border_width(5, lv.PART.MAIN)
|
||||
slider.set_style_pad_all(5, lv.PART.MAIN)
|
||||
|
||||
# Create a reusable style sheet for the INDICATOR part
|
||||
style_indicator = lv.style_t()
|
||||
style_indicator.init()
|
||||
style_indicator.set_bg_color(lv.color_hex(0x37B9F5))
|
||||
style_indicator.set_bg_grad_color(lv.color_hex(0x1464F0))
|
||||
style_indicator.set_bg_grad_dir(lv.GRAD_DIR.HOR)
|
||||
style_indicator.set_shadow_color(lv.color_hex(0x37B9F5))
|
||||
style_indicator.set_shadow_width(15)
|
||||
style_indicator.set_shadow_spread(5)
|
||||
|
||||
# Add the style sheet to the slider's INDICATOR part
|
||||
slider.add_style(style_indicator, lv.PART.INDICATOR)
|
||||
slider.add_style(style_indicator, lv.PART.KNOB)
|
||||
|
||||
# Add the same style to the KNOB part too and locally overwrite some properties
|
||||
slider.set_style_outline_color(lv.color_hex(0x0096FF), lv.PART.KNOB)
|
||||
slider.set_style_outline_width(3, lv.PART.KNOB)
|
||||
slider.set_style_outline_pad(-5, lv.PART.KNOB)
|
||||
slider.set_style_shadow_spread(2, lv.PART.KNOB)
|
||||
|
||||
.. raw:: html
|
||||
|
||||
</details>
|
||||
<br>
|
||||
|
||||
英语、希伯来语( 双向文本排版 )和中文
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
.. image:: https://github.com/kisvegabor/test/raw/master/readme_example_5.png
|
||||
:alt: English, Hebrew and Chinese texts with LVGL
|
||||
|
||||
.. raw:: html
|
||||
|
||||
<details>
|
||||
<summary>C code</summary>
|
||||
|
||||
.. code:: c
|
||||
|
||||
lv_obj_t * ltr_label = lv_label_create(lv_screen_active());
|
||||
lv_label_set_text(ltr_label, "In modern terminology, a microcontroller is similar to a system on a chip (SoC).");
|
||||
lv_obj_set_style_text_font(ltr_label, &lv_font_montserrat_16, 0);
|
||||
lv_obj_set_width(ltr_label, 310);
|
||||
lv_obj_align(ltr_label, LV_ALIGN_TOP_LEFT, 5, 5);
|
||||
|
||||
lv_obj_t * rtl_label = lv_label_create(lv_screen_active());
|
||||
lv_label_set_text(rtl_label,"מעבד, או בשמו המלא יחידת עיבוד מרכזית (באנגלית: CPU - Central Processing Unit).");
|
||||
lv_obj_set_style_base_dir(rtl_label, LV_BASE_DIR_RTL, 0);
|
||||
lv_obj_set_style_text_font(rtl_label, &lv_font_dejavu_16_persian_hebrew, 0);
|
||||
lv_obj_set_width(rtl_label, 310);
|
||||
lv_obj_align(rtl_label, LV_ALIGN_LEFT_MID, 5, 0);
|
||||
|
||||
lv_obj_t * cz_label = lv_label_create(lv_screen_active());
|
||||
lv_label_set_text(cz_label,
|
||||
"嵌入式系统(Embedded System),\n是一种嵌入机械或电气系统内部、具有专一功能和实时计算性能的计算机系统。");
|
||||
lv_obj_set_style_text_font(cz_label, &lv_font_simsun_16_cjk, 0);
|
||||
lv_obj_set_width(cz_label, 310);
|
||||
lv_obj_align(cz_label, LV_ALIGN_BOTTOM_LEFT, 5, -5);
|
||||
|
||||
.. raw:: html
|
||||
|
||||
</details>
|
||||
|
||||
.. raw:: html
|
||||
|
||||
<details>
|
||||
<summary>MicroPython code | <a href="https://sim.lvgl.io/v8.3/micropython/ports/javascript/index.html?script_startup=https://raw.githubusercontent.com/lvgl/lvgl/0d9ab4ee0e591aad1970e3c9164fd7c544ecce70/examples/header.py&script=https://raw.githubusercontent.com/lvgl/lvgl/0d9ab4ee0e591aad1970e3c9164fd7c544ecce70/examples/widgets/slider/lv_example_slider_2.py&script_direct=18bb38200a64e10ead1aa17a65c977fc18131842" target="_blank">在线模拟器</a></summary>
|
||||
|
||||
.. code:: python
|
||||
|
||||
ltr_label = lv.label(lv.screen_active())
|
||||
ltr_label.set_text("In modern terminology, a microcontroller is similar to a system on a chip (SoC).")
|
||||
ltr_label.set_style_text_font(lv.font_montserrat_16, 0);
|
||||
|
||||
ltr_label.set_width(310)
|
||||
ltr_label.align(lv.ALIGN.TOP_LEFT, 5, 5)
|
||||
|
||||
rtl_label = lv.label(lv.screen_active())
|
||||
rtl_label.set_text("מעבד, או בשמו המלא יחידת עיבוד מרכזית (באנגלית: CPU - Central Processing Unit).")
|
||||
rtl_label.set_style_base_dir(lv.BASE_DIR.RTL, 0)
|
||||
rtl_label.set_style_text_font(lv.font_dejavu_16_persian_hebrew, 0)
|
||||
rtl_label.set_width(310)
|
||||
rtl_label.align(lv.ALIGN.LEFT_MID, 5, 0)
|
||||
|
||||
font_simsun_16_cjk = lv.font_load("S:../../assets/font/lv_font_simsun_16_cjk.fnt")
|
||||
|
||||
cz_label = lv.label(lv.screen_active())
|
||||
cz_label.set_style_text_font(font_simsun_16_cjk, 0)
|
||||
cz_label.set_text("嵌入式系统(Embedded System),\n是一种嵌入机械或电气系统内部、具有专一功能和实时计算性能的计算机系统。")
|
||||
cz_label.set_width(310)
|
||||
cz_label.align(lv.ALIGN.BOTTOM_LEFT, 5, -5)
|
||||
|
||||
.. raw:: html
|
||||
|
||||
</details>
|
||||
|
||||
.. _arrow_forward-使用 lvgl 过程:
|
||||
|
||||
▶️ 使用 LVGL 过程
|
||||
---------------
|
||||
|
||||
此列表将指导您逐步开始使用 LVGL。
|
||||
|
||||
**熟悉 LVGL**
|
||||
|
||||
1. 查看\ `在线演示 <https://lvgl.io/demos>`__\ ,了解 LVGL 的实际操作(3 分钟)
|
||||
2. 阅读\ `文档 <https://docs.lvgl.io/master/intro/index.html>`__\ 的简介页(5 分钟)
|
||||
3. 熟悉\ `快速概览 <https://docs.lvgl.io/master/get-started/quick-overview.html>`__
|
||||
页面上的基本知识(15 分钟)
|
||||
|
||||
**开始使用 LVGL**
|
||||
|
||||
4. 设置\ `模拟器 <https://docs.lvgl.io/master/integration/ide/pc-simulator.html#simulator>`__ (10 分钟)
|
||||
5. 尝试一些\ `示例 <https://github.com/lvgl/lvgl/tree/master/examples>`__
|
||||
6. 将LVGL端口连接到线路板。请参阅\ `移植 <https://docs.lvgl.io/master/porting/index.html>`__\ 指南,或查看现成的\ `项目 <https://github.com/lvgl?q=lv_port_>`__
|
||||
|
||||
**成为专业人士**
|
||||
|
||||
7. 阅读\ `概述 <https://docs.lvgl.io/master/overview/index.html>`__\ 页面以更好地了解图书馆(2-3 小时)
|
||||
8. 查看\ `控件 <https://docs.lvgl.io/master/widgets/index.html>`__\ 的文档以查看其功能和用法
|
||||
|
||||
**获得帮助并帮助他人**
|
||||
|
||||
9. 如果您有问题,请访问\ `论坛 <http://forum.lvgl.io/>`__
|
||||
10. 阅读\ `贡献 <https://docs.lvgl.io/master/CONTRIBUTING.html>`__\ 指南,了解如何帮助提高 LVGL(15 分钟)
|
||||
|
||||
.. _handshake-服务:
|
||||
|
||||
🤝 服务
|
||||
-------
|
||||
|
||||
LVGL LLC 的成立旨在为 LVGL 库提供坚实的背景,并提供多种类型的服务来帮助您进行 UI 开发。凭借在用户界面和图形行业超过15年的经验,我们可以帮助您将 UI 提升到一个新的水平。
|
||||
|
||||
- **平面设计**
|
||||
我们的内部图形设计师是创造美丽现代设计的专家,适合您的产品和硬件资源。
|
||||
- **UI 实现**
|
||||
我们还可以根据您或我们创建的设计来实现您的 UI。您可以确信,我们将充分利用您的硬件和 LVGL。如果 LVGL 中缺少某个功能或控件,请不要担心,我们会为您实现它。
|
||||
- **咨询和支持**
|
||||
我们也可以通过咨询来支持您,以避免在 UI 开发过程中出现昂贵和耗时的错误。
|
||||
- **板子认证**
|
||||
对于提供开发板或生产套件的公司,我们会进行板子认证,展示板如何运行 LVGL。
|
||||
|
||||
查看我们的 \ `Demos <https://lvgl.io/demos>`__\ 作为参考。有关更多信息,请查看\ `服务页面 <https://lvgl.io/services>`__\ 。
|
||||
|
||||
`联系我们 <https://lvgl.io/#contact>`__\ ,告诉我们如何提供帮助。
|
||||
|
||||
.. _star2-贡献:
|
||||
|
||||
🌟 贡献
|
||||
-------
|
||||
|
||||
LVGL 是一个开放的项目,我们非常欢迎您的贡献。有很多方法可以帮助您,从简单地谈论您的项目,到编写示例、改进文档、修复错误,甚至在 LVGL 组织下托管您自己的项目。
|
||||
|
||||
有关贡献的详细说明,请访问文件的\ `贡献 <https://docs.lvgl.io/master/CONTRIBUTING.html>`__\ 部分。
|
||||
|
||||
已经有 300 多人在 LVGL 留下了痕迹。期待你成为他们中的一员!并在下列贡献者中看到你! 🙂
|
||||
|
||||
.. raw:: html
|
||||
|
||||
<a href="https://github.com/lvgl/lvgl/graphs/contributors">
|
||||
<img src="https://contrib.rocks/image?repo=lvgl/lvgl&max=48" />
|
||||
</a>
|
||||
|
||||
... 等等其他人.
|
||||
|
||||
.. |Sponsors of LVGL| image:: https://opencollective.com/lvgl/organizations.svg?width=600
|
||||
:target: https://opencollective.com/lvgl
|
||||
.. |Backers of LVGL| image:: https://opencollective.com/lvgl/individuals.svg?width=600
|
||||
:target: https://opencollective.com/lvgl
|
||||
182
libraries/lvgl/docs/ROADMAP.rst
Normal file
@@ -0,0 +1,182 @@
|
||||
|
||||
.. |check| replace:: ☑️
|
||||
|
||||
.. |uncheck| replace:: 🔲
|
||||
|
||||
.. _roadmap:
|
||||
|
||||
Roadmap
|
||||
=======
|
||||
|
||||
v9
|
||||
--
|
||||
|
||||
Schedule
|
||||
~~~~~~~~
|
||||
|
||||
- December 4: Feature stop, start updating the docs and testing
|
||||
- December 18: Release candidate version and call to test
|
||||
- January 15: Release v9.0
|
||||
|
||||
Naming and API
|
||||
~~~~~~~~~~~~~~
|
||||
|
||||
- |check| `lv_style_set_size()` should have separate width and height parameters
|
||||
- |check| Reconsider image color formats.
|
||||
- |check| More consistent names:`remove/clear/delete/del`, `offset/ofs`, `add/create/register`, `id/idx/index`, `middle/mid/center`, `img/image`, `txt/text`, `opa/opacity/alpha`, `scr/screen`, `disp, display`, `finished/complete/completed/ready`, `buf/buffer`, `..._cb`, `angle/rotation`, `zoom/scale`, `has`, `is`, `enable`
|
||||
- |check| Update canvas API `LINK <https://github.com/lvgl/lvgl/issues/3393>`__
|
||||
- |check| `LV_STYLE_PROP_INHERIT` -> `LV_STYLE_PROP_FLAG_INHERITABLE`
|
||||
`LINK <https://github.com/lvgl/lvgl/pull/3390#discussion_r885915769>`__
|
||||
- |check| Replace `disp_drv->direct_mode/full_refresh` with enum.
|
||||
- |check| Consider flat directory structure. E.g. `extra/widgets` to `widgets`
|
||||
- |check| Use `uint32_t` and `int32_t` in APIs where possible. Consider hardcoding `int32_t` as `int32_t`.
|
||||
- |check| To define a new stdlib API use defines `LV_USE_CUSTOM_...` and
|
||||
let the user implement `lv_...` functions somewhere (instead of defining the name of the custom functions)
|
||||
(see `here <https://github.com/lvgl/lvgl/issues/3481#issuecomment-1206434501>`__)
|
||||
- |check| Gradient with alpha
|
||||
|
||||
Architecture
|
||||
~~~~~~~~~~~~
|
||||
|
||||
- |check| Consider merging `lv_disp_drv_t`, `lv_disp_t`, `lv_disp_draw_buf_t`, `lv_draw_ctx_t` `struct`'s from the new driver API (or only some of them)
|
||||
- |check| New driver architecture #2720
|
||||
- |check| `draw_ctx->buffer_convert`?
|
||||
(see `here <https://github.com/lvgl/lvgl/issues/3379#issuecomment-1147954592>`__)
|
||||
Also remove 16 SWAPPED color format?
|
||||
(see `here <https://github.com/lvgl/lvgl/issues/3379#issuecomment-1140886258>`__)
|
||||
- |check| Reconsider masks. There should be a generic high level mask API which is independent of the drawing engine.
|
||||
`#4059 <https://github.com/lvgl/lvgl/issues/4059>`__
|
||||
- |check| `get_glyph_bitmap` should return an a8 bitmap that can be blended immediately.
|
||||
(see `here <https://github.com/lvgl/lvgl/pull/3390#pullrequestreview-990710921>`__)
|
||||
- |check| Make LVGL render independent areas in parallel.
|
||||
`#4016 <https://github.com/lvgl/lvgl/issues/4016>`__
|
||||
- |check| Drop `lv_mem_buf_get` as tlsf should be fast enough for normal allocations too.
|
||||
Fragmentation is also lower if processes can completely clean up after themselves.
|
||||
- |check| More color formats: 24 bit, ARGB1555, ARGB4444 etc
|
||||
(see `here <https://forum.lvgl.io/t/keypad-input-device-why-lv-event-long-pressed-only-on-enter/10263>`__)
|
||||
- |check| Unified caching #3116 #3415
|
||||
- |check| Variable binding. I.e create properties which can be bound to objects and those objects are notified on value change. Maybe based on `lv_msg`?
|
||||
- |uncheck| Add GPU abstraction for display rotation
|
||||
- |check| Replace the `read_line_cb` of the image decoders with `get_area_cb`
|
||||
- |check| Limit the image caching size in bytes instead of image count
|
||||
- |check| lv_draw_buf for unified stride, buffer and cache invalidation management. `4241 <https://github.com/lvgl/lvgl/pull/4241>`__
|
||||
- |check| Add vector graphics support via ThorVG
|
||||
- |check| SVG support: integrate an SVG render library `4388 <https://github.com/lvgl/lvgl/issues/4388>`__
|
||||
- |check| Introduce optional ``float`` support. `4648 <https://github.com/lvgl/lvgl/issues/4648>`__
|
||||
- |check| Introduce support layer for 3D GPUs (OpenGL, SDL, Vulkan, etc). `4622 <https://github.com/lvgl/lvgl/issues/4622>`__
|
||||
|
||||
Styles
|
||||
~~~~~~
|
||||
|
||||
- |check| non-uniform scale of images: scale width and height differently
|
||||
- |check| Scroll anim settings should come from styles to allow customization
|
||||
|
||||
Widgets
|
||||
~~~~~~~
|
||||
|
||||
- |check| Universal scale widget/support
|
||||
- |check| `lv_img`: Reconsider image sizing models
|
||||
(when the image size is not content): center, top-left, zoom, tile, other?
|
||||
- |check| `lv_tabview` Replace button matrix with real buttons for more flexibility
|
||||
(see `here <https://forum.lvgl.io/t/linear-meter-bar-with-ticks/10986>`__ and #4043)
|
||||
- |check| Disabled widgets should absorb indev actions without sending events. `#3860 <https://github.com/lvgl/lvgl/issues/3860>`__
|
||||
|
||||
Animations
|
||||
~~~~~~~~~~
|
||||
|
||||
- |check| `lv_anim_time_to_speed` should work differently to remove
|
||||
`style_anim_speed`. E.g. on large values of anim time store the
|
||||
speed. Besides all widgets should use the `style_anim` property.
|
||||
`anim` should clamp the time if it's calculated from speed, e.g
|
||||
`lv_clamp(200, t, 2000)`. (maybe `a->min_time/max_time`).
|
||||
- |uncheck| Use dedicated `lv_anim_custom_exec_cb_t`.
|
||||
See `here <https://forum.lvgl.io/t/custom-exec-cb-prevents-lv-anim-del-obj-null/10266>`__.
|
||||
|
||||
Planned in general
|
||||
------------------
|
||||
|
||||
CI
|
||||
~~
|
||||
|
||||
- |uncheck| Platform independent benchmarking #3443
|
||||
- |uncheck| Run static analyzer
|
||||
- |uncheck| Release script
|
||||
- |uncheck| Unit test for all widgets #2337
|
||||
- |uncheck| CI test for flash/RAM usage #3127
|
||||
|
||||
|
||||
Architecture
|
||||
~~~~~~~~~~~~
|
||||
|
||||
- |uncheck| Add more feature to key presses (long press, release, etc).
|
||||
- |uncheck| `lv_image_set_src()` use “type-aware” parameter and rework image decoders.
|
||||
(see `here <https://github.com/lvgl/lvgl/tree/arch/img-decode-rework>`__)
|
||||
- |uncheck| `C++ binding <https://github.com/lvgl/lv_binding_cpp>`__
|
||||
- |uncheck| Markup language #2428
|
||||
|
||||
|
||||
Styles
|
||||
~~~~~~
|
||||
|
||||
- |uncheck| Hover
|
||||
- |uncheck| Global states in selectors. E.g. `LV_STATE_PRESSED | SMALL_SCREEN` like media quarry in CSS
|
||||
|
||||
|
||||
Drawing and rendering
|
||||
~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
- |uncheck| SW: Line drawing with image rotation
|
||||
- |uncheck| SW: Arc drawing from small squares (16x16?) to detect transparent or solid parts
|
||||
- |uncheck| SW: Rounded rectangle drawing from small squares (16x16?) to detect transparent or solid parts
|
||||
- |uncheck| Different radius on each corner #2800
|
||||
- |uncheck| Gradient to border/outline/shadow
|
||||
- |uncheck| Multiple shadow/border
|
||||
- |uncheck| Perspective
|
||||
- |uncheck| Text shadow
|
||||
- |uncheck| Inner shadow
|
||||
- |uncheck| ARGB image stroke/grow on the alpha map
|
||||
- |uncheck| Real time blur
|
||||
|
||||
|
||||
Widgets
|
||||
~~~~~~~
|
||||
|
||||
- |uncheck| `lv_bar`, `lv_arc`: handle max < min for fill direction swapping #4039
|
||||
- |uncheck| `lv_bar`, `lv_slider`, `lv_arc`: make possible to move the knob only inside the background (see `here <https://forum.lvgl.io/t/slider-knob-out-of-the-track/11956>`__)
|
||||
- |uncheck| Improve `lv_label_align_t` #1656
|
||||
- |uncheck| `lv_label` reconsider label long modes. (support min/max-width/height too) #3420
|
||||
- |uncheck| `lv_roller` make it more flexible #4009
|
||||
|
||||
Others
|
||||
~~~~~~
|
||||
- |uncheck| `em`, `ch`, `vw/vh` units
|
||||
- |uncheck| `aspect-ratio` as size
|
||||
- |uncheck| More grid features. E.g. repeat(auto-fill, minmax( px, 1fr))
|
||||
- |uncheck| Named grid cells to allow updating layouts without touching the children (like CSS `grid-template-areas`)
|
||||
- |uncheck| Scene support. See `this comment <https://github.com/lvgl/lvgl/issues/2790#issuecomment-965100911>`__
|
||||
- |uncheck| Circle layout. #2871
|
||||
- |uncheck| Consider `stagger animations <https://greensock.com/docs/v3/Staggers>`__.
|
||||
- |uncheck| Add custom indev type. See `here <https://github.com/lvgl/lvgl/issues/3298#issuecomment-1616706654>`__.
|
||||
- |uncheck| Automatically recalculate the layout if a coordinate is obtained using `lv_obj_get_width/height/x/y/etc`
|
||||
|
||||
Ideas
|
||||
-----
|
||||
- Reconsider how themes should work.
|
||||
- Better way to reset global variables in `lv_deinit()` #3385
|
||||
- `lv_array`: replace linked lists with array where possible (arrays are faster and uses less memory)
|
||||
- Reconsider how to handle UTF-8 characters (allow different encoding too) and Bidi. Maybe create an abstraction for textshaping.
|
||||
- Consider direct binary font format support
|
||||
- Improve groups. `Discussion <https://forum.lvgl.io/t/lv-group-tabindex/2927/3>`__.
|
||||
Reconsider focusing logic. Allow having no widget selected (on web it's possible). Keep editing state in `lv_obj_t`
|
||||
(see `here <https://github.com/lvgl/lvgl/issues/3646>`__). Support slider
|
||||
left knob focusing (see `here <https://github.com/lvgl/lvgl/issues/3246>`__)
|
||||
- Speed up font decompression
|
||||
- Support larger images: add support for large image #1892
|
||||
- Functional programming support, pure view?
|
||||
(see `here <https://www.freecodecamp.org/news/the-revolution-of-pure-views-aed339db7da4/>`__)
|
||||
- Style components. (see `this comment <https://github.com/lvgl/lvgl/issues/2790#issuecomment-965100911>`__
|
||||
- Support dot_begin and dot_middle long modes for labels
|
||||
- Allow matrix input for image transformation?
|
||||
- Radial/skew/conic gradient
|
||||
- Somehow let children inherit the parent's state
|
||||
- Text on path
|
||||
58
libraries/lvgl/docs/_ext/link_roles.py
Normal file
@@ -0,0 +1,58 @@
|
||||
# based on http://protips.readthedocs.io/link-roles.html
|
||||
|
||||
#from __future__ import print_function, unicode_literals
|
||||
|
||||
import os
|
||||
import re
|
||||
import subprocess
|
||||
from collections import namedtuple
|
||||
|
||||
from docutils import nodes
|
||||
from sphinx.transforms.post_transforms import SphinxPostTransform
|
||||
|
||||
URL_BASE = {
|
||||
"zh_CN": "https://lvgl.100ask.net/"
|
||||
}
|
||||
|
||||
class translation_link(nodes.Element):
|
||||
"""Node for "link_to_translation" role."""
|
||||
|
||||
|
||||
# Linking to translation is done at the "writing" stage to avoid issues with the info being cached between builders
|
||||
def link_to_translation(name, rawtext, text, lineno, inliner, options={}, content=[]):
|
||||
node = translation_link()
|
||||
node['expr'] = (rawtext, text, options)
|
||||
return [node], []
|
||||
|
||||
|
||||
class TranslationLinkNodeTransform(SphinxPostTransform):
|
||||
# Transform needs to happen early to ensure the new reference node is also transformed
|
||||
default_priority = 0
|
||||
|
||||
def run(self, **kwargs):
|
||||
# Only output relative links if building HTML
|
||||
for node in self.document.traverse(translation_link):
|
||||
if 'html' in self.app.builder.name:
|
||||
rawtext, text, options = node['expr']
|
||||
(language, link_text) = text.split(':')
|
||||
env = self.document.settings.env
|
||||
docname = env.docname
|
||||
#doc_path = env.doc2path(docname, False)
|
||||
urlpath = os.environ['LVGL_URLPATH']+'/'
|
||||
return_path = URL_BASE.get(language, "") + urlpath
|
||||
|
||||
url = '{}.html'.format(os.path.join(return_path, docname))
|
||||
|
||||
node.replace_self(nodes.reference(rawtext, link_text, refuri=url, **options))
|
||||
else:
|
||||
node.replace_self([])
|
||||
|
||||
|
||||
def setup(app):
|
||||
|
||||
# link to the current documentation file in specific language version
|
||||
app.add_role('link_to_translation', link_to_translation)
|
||||
app.add_node(translation_link)
|
||||
app.add_post_transform(TranslationLinkNodeTransform)
|
||||
|
||||
return {'parallel_read_safe': True, 'parallel_write_safe': True, 'version': '0.5'}
|
||||
115
libraries/lvgl/docs/_ext/lv_example.py
Normal file
@@ -0,0 +1,115 @@
|
||||
import os
|
||||
|
||||
from docutils import nodes
|
||||
from docutils.parsers.rst import Directive, directives
|
||||
# from docutils.parsers.rst.directives.images import Image
|
||||
# from sphinx.directives.code import LiteralInclude
|
||||
|
||||
|
||||
def excluded_list(argument):
|
||||
return argument.split(',')
|
||||
|
||||
|
||||
class LvExample(Directive):
|
||||
required_arguments = 1
|
||||
option_spec = {
|
||||
'excluded_languages': excluded_list,
|
||||
'language': directives.unchanged,
|
||||
'description': directives.unchanged
|
||||
}
|
||||
|
||||
def get_example_code_path(self, example_path, language):
|
||||
base_path = os.path.dirname(__file__)
|
||||
examples_path = os.path.abspath(os.path.join(base_path, '..', 'examples'))
|
||||
example_path = os.path.join(examples_path, example_path + '.' + language)
|
||||
return example_path
|
||||
|
||||
def human_language_name(self, language):
|
||||
if language == 'py':
|
||||
return 'MicroPython'
|
||||
elif language == 'c':
|
||||
return 'C'
|
||||
else:
|
||||
return language
|
||||
|
||||
def github_path(self, example_path, language):
|
||||
env = self.state.document.settings.env
|
||||
return f"https://github.com/lvgl/lvgl/blob/{env.config.repo_commit_hash}/examples/{example_path}.{language}"
|
||||
|
||||
def embed_code(self, example_file, example_path, language, buttons={}):
|
||||
toggle = nodes.container('', literal_block=False, classes=['toggle'])
|
||||
header = nodes.container('', literal_block=False, classes=['header'])
|
||||
toggle.append(header)
|
||||
|
||||
try:
|
||||
with open(example_file, 'rb') as f:
|
||||
contents = f.read().decode('utf-8')
|
||||
except FileNotFoundError:
|
||||
print('File Not Found', example_file)
|
||||
contents = 'Error encountered while trying to open ' + example_file
|
||||
|
||||
literal_list = nodes.literal_block(contents, contents)
|
||||
literal_list['language'] = language
|
||||
toggle.append(literal_list)
|
||||
paragraph_node = nodes.raw(text=f"<p>{self.human_language_name(language)} code </p>", format='html')
|
||||
for text, url in buttons.items():
|
||||
paragraph_node.append(nodes.raw(text=f"<a class='lv-example-link-button' onclick=\"event.stopPropagation();\" href='{url}'>{text}</a>", format='html'))
|
||||
header.append(paragraph_node)
|
||||
return toggle
|
||||
|
||||
def run(self):
|
||||
example_path = self.arguments[0]
|
||||
example_name = os.path.split(example_path)[1]
|
||||
excluded_languages = self.options.get('excluded_languages', [])
|
||||
node_list = []
|
||||
|
||||
env = self.state.document.settings.env
|
||||
|
||||
iframe_html = ""
|
||||
|
||||
c_path = self.get_example_code_path(example_path, 'c')
|
||||
py_path = self.get_example_code_path(example_path, 'py')
|
||||
|
||||
if os.path.exists(c_path):
|
||||
c_code = self.embed_code(c_path, example_path, 'c', buttons={
|
||||
'<i class="fa fa-github"></i> View on GitHub': self.github_path(example_path, 'c')
|
||||
})
|
||||
else:
|
||||
c_code = None
|
||||
|
||||
if os.path.exists(py_path):
|
||||
py_code = self.embed_code(py_path, example_path, 'py', buttons={
|
||||
'<i class="fa fa-github"></i> View on GitHub': self.github_path(example_path, 'py'),
|
||||
'<i class="fa fa-play"></i> MicroPython Simulator': f"https://sim.lvgl.io/v{env.config.version}/micropython/ports/javascript/index.html?script_startup=https://raw.githubusercontent.com/lvgl/lvgl/{env.config.repo_commit_hash}/examples/header.py&script=https://raw.githubusercontent.com/lvgl/lvgl/{env.config.repo_commit_hash}/examples/{example_path}.py"
|
||||
})
|
||||
else:
|
||||
py_code = None
|
||||
|
||||
if 'c' not in excluded_languages:
|
||||
if env.app.tags.has('html'):
|
||||
iframe_html = f"<div class='lv-example' data-real-src='/{env.config.version}/_static/built_lv_examples/index.html?example={example_name}&w=320&h=240'></div>"
|
||||
|
||||
description_html = f"<div class='lv-example-description'>{self.options.get('description', '')}</div>"
|
||||
layout_node = nodes.raw(text=f"<div class='lv-example-container'>{iframe_html}{description_html}</div>", format='html')
|
||||
|
||||
node_list.append(layout_node)
|
||||
if 'c' not in excluded_languages and c_code is not None:
|
||||
node_list.append(c_code)
|
||||
if 'py' not in excluded_languages and py_code is not None:
|
||||
node_list.append(py_code)
|
||||
|
||||
trailing_node = nodes.raw(text=f"<hr/>", format='html')
|
||||
node_list.append(trailing_node)
|
||||
|
||||
return node_list
|
||||
|
||||
|
||||
def setup(app):
|
||||
app.add_directive("lv_example", LvExample)
|
||||
app.add_config_value("repo_commit_hash", "", "env")
|
||||
|
||||
return {
|
||||
'version': '0.1',
|
||||
'parallel_read_safe': True,
|
||||
'parallel_write_safe': True,
|
||||
}
|
||||
153
libraries/lvgl/docs/_static/css/custom.css
vendored
Normal file
@@ -0,0 +1,153 @@
|
||||
table, th, td {
|
||||
border: 1px solid #bbb;
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
td {
|
||||
text-align:center;
|
||||
}
|
||||
span.pre
|
||||
{
|
||||
padding-right:8px;
|
||||
}
|
||||
|
||||
span.pre:first-child
|
||||
{
|
||||
padding-right:0px;
|
||||
}
|
||||
|
||||
|
||||
code.sig-name
|
||||
{
|
||||
/*margin-left:8px;*/
|
||||
}
|
||||
|
||||
.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;
|
||||
display: none; /*replaced by dropdown*/
|
||||
}
|
||||
|
||||
|
||||
.home-img {
|
||||
width:32%;
|
||||
transition: transform .3s ease-out;
|
||||
}
|
||||
|
||||
.home-img:hover {
|
||||
transform: translate(0, -10px);
|
||||
}
|
||||
|
||||
/*Let `code` wrap*/
|
||||
.rst-content code, .rst-content tt, code {
|
||||
white-space: normal;
|
||||
}
|
||||
|
||||
.lv-example, .lv-example > iframe {
|
||||
border: none;
|
||||
outline: none;
|
||||
padding: none;
|
||||
display: block;
|
||||
width: 320px;
|
||||
height: 240px;
|
||||
flex: none;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.lv-example > iframe {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
}
|
||||
|
||||
.lv-example-container {
|
||||
display: flex;
|
||||
padding-bottom: 16px;
|
||||
}
|
||||
.lv-example-description {
|
||||
flex: 1 1 auto;
|
||||
margin-left: 1rem;
|
||||
}
|
||||
|
||||
.lv-example-link-button {
|
||||
display: inline-block;
|
||||
padding: 4px 8px;
|
||||
border-radius: 4px;
|
||||
background-color: #2980b9;
|
||||
color: white;
|
||||
margin: 0 4px;
|
||||
}
|
||||
.lv-example-link-button:hover {
|
||||
color: white;
|
||||
filter: brightness(120%);
|
||||
}
|
||||
|
||||
.lv-example-link-button:visited {
|
||||
color: white;
|
||||
}
|
||||
|
||||
dl.cpp.unexpanded dd {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.lv-api-expansion-button {
|
||||
padding: 4px;
|
||||
}
|
||||
.lv-api-expansion-button::before {
|
||||
font-family: FontAwesome, "Lato","proxima-nova","Helvetica Neue",Arial,sans-serif;
|
||||
display: inline-block;
|
||||
font-size: 1.1em;
|
||||
cursor: pointer;
|
||||
}
|
||||
.unexpanded .lv-api-expansion-button::before {
|
||||
content: "\f0da \00a0";
|
||||
}
|
||||
.expanded .lv-api-expansion-button::before {
|
||||
content: "\f0d7 \00a0";
|
||||
}
|
||||
|
||||
.wy-nav-content{
|
||||
padding: 1.618em 3.236em;
|
||||
height: 100%;
|
||||
max-width: 1920px;
|
||||
margin: auto
|
||||
}
|
||||
|
||||
div.body {
|
||||
min-width: 360px;
|
||||
max-width: 1920px;
|
||||
}
|
||||
|
||||
.cpp-expr {
|
||||
font-family: SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;
|
||||
color: #e74c3c;
|
||||
padding: 2px 5px;
|
||||
border: 1px solid #e1e4e5;
|
||||
font-size: 75%;
|
||||
}
|
||||
5
libraries/lvgl/docs/_static/css/fontawesome.min.css
vendored
Normal file
BIN
libraries/lvgl/docs/_static/img/home_1.png
vendored
Normal file
|
After Width: | Height: | Size: 14 KiB |
BIN
libraries/lvgl/docs/_static/img/home_2.png
vendored
Normal file
|
After Width: | Height: | Size: 18 KiB |
BIN
libraries/lvgl/docs/_static/img/home_3.png
vendored
Normal file
|
After Width: | Height: | Size: 15 KiB |
BIN
libraries/lvgl/docs/_static/img/home_4.png
vendored
Normal file
|
After Width: | Height: | Size: 16 KiB |
BIN
libraries/lvgl/docs/_static/img/home_5.png
vendored
Normal file
|
After Width: | Height: | Size: 17 KiB |
BIN
libraries/lvgl/docs/_static/img/home_6.png
vendored
Normal file
|
After Width: | Height: | Size: 17 KiB |
BIN
libraries/lvgl/docs/_static/img/home_banner.jpg
vendored
Normal file
|
After Width: | Height: | Size: 186 KiB |
BIN
libraries/lvgl/docs/_static/img/js_calculator.gif
vendored
Normal file
|
After Width: | Height: | Size: 519 KiB |
BIN
libraries/lvgl/docs/_static/img/js_code.png
vendored
Normal file
|
After Width: | Height: | Size: 312 KiB |
BIN
libraries/lvgl/docs/_static/img/js_on_device.jpg
vendored
Normal file
|
After Width: | Height: | Size: 189 KiB |
BIN
libraries/lvgl/docs/_static/img/js_widgets_demo.gif
vendored
Normal file
|
After Width: | Height: | Size: 1.2 MiB |
57
libraries/lvgl/docs/_static/js/custom.js
vendored
Normal file
@@ -0,0 +1,57 @@
|
||||
/* API collapsing */
|
||||
document.addEventListener('DOMContentLoaded', (event) => {
|
||||
document.querySelectorAll("dl.cpp").forEach(cppListing => {
|
||||
const dt = cppListing.querySelector("dt");
|
||||
let shouldBeExpanded = false;
|
||||
if(dt.id == document.location.hash.substring(1))
|
||||
shouldBeExpanded = true;
|
||||
cppListing.classList.add(shouldBeExpanded ? "expanded" : "unexpanded");
|
||||
const button = document.createElement("span");
|
||||
button.classList.add("lv-api-expansion-button");
|
||||
button.addEventListener("click", () => {
|
||||
cppListing.classList.toggle("unexpanded");
|
||||
cppListing.classList.toggle("expanded");
|
||||
});
|
||||
|
||||
dt.insertBefore(button, dt.firstChild);
|
||||
});
|
||||
|
||||
fetch('https://lvgl.io/home-banner.txt') // Replace with your URL
|
||||
.then(response => {
|
||||
// Check if the request was successful
|
||||
if (!response.ok) {
|
||||
throw new Error(`HTTP error! Status: ${response.status}`);
|
||||
}
|
||||
// Read the response as text
|
||||
return response.text();
|
||||
})
|
||||
.then(data => {
|
||||
|
||||
const section = document.querySelector('.wy-nav-content-wrap');
|
||||
|
||||
//Add a div
|
||||
const newDiv = document.createElement('div');
|
||||
newDiv.style="background-image: linear-gradient(45deg, black, #5e5e5e); color: white; border-bottom: 4px solid #e10010; padding-inline:3em"
|
||||
section.insertBefore(newDiv, section.firstChild);
|
||||
|
||||
|
||||
//Add a p to the div
|
||||
const newP = document.createElement('p');
|
||||
newP.style="padding-block:12px; margin-block:0px;align-content: center;align-items: center;"
|
||||
newP.innerHTML = data
|
||||
newDiv.insertBefore(newP, newDiv.firstChild);
|
||||
|
||||
const children = newDiv.querySelectorAll('*');
|
||||
|
||||
// Iterate over each child
|
||||
children.forEach(child => {
|
||||
// Check if the child has an id
|
||||
if (child.id) {
|
||||
// Prepend 'docs-' to the id
|
||||
child.id = 'docs-' + child.id;
|
||||
}
|
||||
})
|
||||
}) .catch(error => {
|
||||
console.error('Fetch error: ' + error.message);
|
||||
});
|
||||
})
|
||||
29
libraries/lvgl/docs/_static/js/include_html.js
vendored
Normal file
@@ -0,0 +1,29 @@
|
||||
|
||||
/*https://www.w3schools.com/howto/howto_html_include.asp*/
|
||||
function includeHTML() {
|
||||
var z, i, elmnt, file, xhttp;
|
||||
/*loop through a collection of all HTML elements:*/
|
||||
z = document.getElementsByTagName("*");
|
||||
for (i = 0; i < z.length; i++) {
|
||||
elmnt = z[i];
|
||||
/*search for elements with a certain attribute:*/
|
||||
file = elmnt.getAttribute("include-html");
|
||||
if (file) {
|
||||
/*make an HTTP request using the attribute value as the file name:*/
|
||||
xhttp = new XMLHttpRequest();
|
||||
xhttp.onreadystatechange = function() {
|
||||
if (this.readyState == 4) {
|
||||
if (this.status == 200) {elmnt.innerHTML = this.responseText;}
|
||||
if (this.status == 404) {elmnt.innerHTML = "Page not found.";}
|
||||
/*remove the attribute, and call this function once more:*/
|
||||
elmnt.removeAttribute("w3-include-html");
|
||||
includeHTML();
|
||||
}
|
||||
}
|
||||
xhttp.open("GET", file, true);
|
||||
xhttp.send();
|
||||
/*exit the function:*/
|
||||
return;
|
||||
}
|
||||
}
|
||||
};
|
||||
31
libraries/lvgl/docs/_templates/layout.html
vendored
Normal file
@@ -0,0 +1,31 @@
|
||||
{% extends "!layout.html" %}
|
||||
|
||||
{%- block extrahead %}
|
||||
{{ super() }}
|
||||
<!-- Global site tag (gtag.js) - Google Analytics -->
|
||||
<script async src="https://www.googletagmanager.com/gtag/js?id=UA-78811084-3"></script>
|
||||
<script>
|
||||
window.dataLayer = window.dataLayer || [];
|
||||
function gtag(){dataLayer.push(arguments);}
|
||||
gtag('js', new Date());
|
||||
|
||||
gtag('config', 'UA-78811084-3', { 'anonymize_ip': true });
|
||||
</script>
|
||||
{% endblock %}
|
||||
|
||||
{% block footer %}
|
||||
{{ super() }}
|
||||
<div class="footer">This page uses <a href="https://analytics.google.com/">
|
||||
Google Analytics</a> to collect statistics. You can disable it by blocking
|
||||
the JavaScript coming from www.google-analytics.com.
|
||||
<script type="text/javascript">
|
||||
(function() {
|
||||
var ga = document.createElement('script');
|
||||
ga.src = ('https:' == document.location.protocol ?
|
||||
'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
|
||||
ga.setAttribute('async', 'true');
|
||||
document.documentElement.firstChild.appendChild(ga);
|
||||
})();
|
||||
</script>
|
||||
</div>
|
||||
{% endblock %}
|
||||
82
libraries/lvgl/docs/_templates/page.html
vendored
Normal file
@@ -0,0 +1,82 @@
|
||||
{% extends "!page.html" %}
|
||||
|
||||
{% block footer %}
|
||||
|
||||
<style>
|
||||
.wy-side-nav-search > div[role="search"] {
|
||||
color: black;
|
||||
}
|
||||
</style>
|
||||
<script type="text/javascript">
|
||||
$(document).ready(function() {
|
||||
$(".toggle > *").hide();
|
||||
$(".toggle .header").show();
|
||||
$(".toggle .header").click(function() {
|
||||
$(this).parent().children().not(".header").toggle(400);
|
||||
$(this).parent().children(".header").toggleClass("open");
|
||||
})
|
||||
});
|
||||
</script>
|
||||
|
||||
<script type="text/javascript">
|
||||
function add_version_selector()
|
||||
{
|
||||
return fetch("https://raw.githubusercontent.com/lvgl/docs_compiled/gh-pages/versionlist.txt")
|
||||
.then(res => res.text())
|
||||
.then(text => {
|
||||
const versions = text.split("\n").filter(version => version.trim().length > 0);
|
||||
let p = document.getElementById("rtd-search-form").parentElement;
|
||||
p.innerHTML = `
|
||||
<select name="versions" id="versions" onchange="ver_sel()" style="border-radius:5px; margin-bottom:15px">
|
||||
${versions.map(version => {
|
||||
let versionName = "";
|
||||
if(version == "master") versionName = "master (latest)";
|
||||
else versionName = "v" + ((version.indexOf(".") != -1) ? version : (version + " (latest minor)"));
|
||||
return `<option value="${version}">${versionName}</option>`;
|
||||
})}
|
||||
</select>` + p.innerHTML;
|
||||
});
|
||||
}
|
||||
|
||||
function ver_sel()
|
||||
{
|
||||
var x = document.getElementById("versions").value;
|
||||
window.location.href = window.location.protocol + "//" + window.location.host + "/" + x + "/";
|
||||
}
|
||||
|
||||
document.addEventListener('DOMContentLoaded', (event) => {
|
||||
add_version_selector().then(() => {
|
||||
var value = window.location.pathname.split('/')[1];
|
||||
document.getElementById("versions").value = value;
|
||||
});
|
||||
|
||||
})
|
||||
document.addEventListener('DOMContentLoaded', (event) => {
|
||||
function onIntersection(entries) {
|
||||
entries.forEach(entry => {
|
||||
let currentlyLoaded = entry.target.getAttribute("data-is-loaded") == "true";
|
||||
let shouldBeLoaded = entry.intersectionRatio > 0;
|
||||
if(currentlyLoaded != shouldBeLoaded) {
|
||||
entry.target.setAttribute("data-is-loaded", shouldBeLoaded);
|
||||
if(shouldBeLoaded) {
|
||||
let iframe = document.createElement("iframe");
|
||||
iframe.src = entry.target.getAttribute("data-real-src");
|
||||
entry.target.appendChild(iframe);
|
||||
} else {
|
||||
let iframe = entry.target.querySelector("iframe");
|
||||
iframe.parentNode.removeChild(iframe);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
const config = {
|
||||
rootMargin: '600px 0px',
|
||||
threshold: 0.01
|
||||
};
|
||||
let observer = new IntersectionObserver(onIntersection, config);
|
||||
document.querySelectorAll(".lv-example").forEach(iframe => {
|
||||
observer.observe(iframe);
|
||||
});
|
||||
});
|
||||
</script>
|
||||
{% endblock %}
|
||||
42
libraries/lvgl/docs/add_translation.py
Executable file
@@ -0,0 +1,42 @@
|
||||
#!/usr/bin/env python3
|
||||
import os
|
||||
|
||||
"""
|
||||
Please add the translation language you want to add here, while also modifying the variable URL_BASE in _ext/link_roles.py
|
||||
For example:
|
||||
|
||||
LANGUAGE = ':link_to_translation:`zh_CN:[中文]`\t' + \
|
||||
':link_to_translation:`en:[English]`\t' + \
|
||||
'\n\n'
|
||||
|
||||
|
||||
URL_BASE = {
|
||||
"zh_CN": "https://lvgl.100ask.net/",
|
||||
"en": "https://docs.lvgl.io/"
|
||||
}
|
||||
"""
|
||||
|
||||
LANGUAGE = ':link_to_translation:`zh_CN:[中文]`\t' + \
|
||||
'\n\n'
|
||||
|
||||
|
||||
|
||||
def find_files(dir_path, suffix):
|
||||
files = []
|
||||
|
||||
for root, _, filenames in os.walk(dir_path):
|
||||
for filename in filenames:
|
||||
if filename.endswith(suffix):
|
||||
files.append(os.path.join(root, filename))
|
||||
return files
|
||||
|
||||
|
||||
|
||||
def exec(temp_directory):
|
||||
files = find_files(temp_directory, '.rst')
|
||||
|
||||
for rst_file in files:
|
||||
with open(rst_file, 'r+', encoding='utf-8') as f:
|
||||
content = f.read()
|
||||
f.seek(0, 0)
|
||||
f.write(LANGUAGE + content)
|
||||
254
libraries/lvgl/docs/build.py
Executable file
@@ -0,0 +1,254 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
# ****************************************************************************
|
||||
# IMPORTANT: If you are getting a lexer error for an example you need to check
|
||||
# for extra lines at the end of the file. Only a single empty line
|
||||
# is allowed!!! Ask me how long it took me to figure this out
|
||||
# ****************************************************************************
|
||||
|
||||
import sys
|
||||
import os
|
||||
import subprocess
|
||||
import re
|
||||
import example_list as ex
|
||||
import doc_builder
|
||||
import shutil
|
||||
import tempfile
|
||||
import config_builder
|
||||
import add_translation
|
||||
|
||||
# due to the modifications that take place to the documentation files
|
||||
# when the documentation builds it is better to copy the source files to a
|
||||
# temporary folder and modify the copies. Not setting it up this way makes it
|
||||
# a real headache when making alterations that need to be committed as the
|
||||
# alterations trigger the files as changed.
|
||||
|
||||
# If there is debugging that needs to be done you can provide a command line
|
||||
# switch of "develop" and it will leave the temporary directory in tact and
|
||||
# that directory will be output at the end of the build.
|
||||
|
||||
# the html and PDF output locations are going to remain the same as they were.
|
||||
# it's just the source documentation files that are going to be copied.
|
||||
|
||||
temp_directory = tempfile.mkdtemp(suffix='.lvgl_docs')
|
||||
|
||||
langs = ['en']
|
||||
|
||||
# Change to script directory for consistency
|
||||
|
||||
base_path = os.path.abspath(os.path.dirname(__file__))
|
||||
project_path = os.path.abspath(os.path.join(base_path, '..'))
|
||||
examples_path = os.path.join(project_path, 'examples')
|
||||
|
||||
lvgl_src_path = os.path.join(project_path, 'src')
|
||||
latex_output_path = os.path.join(temp_directory, 'out_latex')
|
||||
|
||||
pdf_src_file = os.path.join(latex_output_path, 'LVGL.pdf')
|
||||
pdf_dst_file = os.path.join(temp_directory, 'LVGL.pdf')
|
||||
html_src_path = temp_directory
|
||||
html_dst_path = os.path.join(project_path, 'out_html')
|
||||
|
||||
os.chdir(base_path)
|
||||
|
||||
|
||||
clean = 0
|
||||
trans = 0
|
||||
skip_latex = False
|
||||
develop = False
|
||||
args = sys.argv[1:]
|
||||
|
||||
if len(args) >= 1:
|
||||
if "clean" in args:
|
||||
clean = 1
|
||||
if "skip_latex" in args:
|
||||
skip_latex = True
|
||||
if 'develop' in args:
|
||||
develop = True
|
||||
|
||||
|
||||
def cmd(s):
|
||||
print("")
|
||||
print(s)
|
||||
print("-------------------------------------")
|
||||
|
||||
result = os.system(s)
|
||||
if result != 0:
|
||||
print("Exit build due to previous error")
|
||||
sys.exit(result)
|
||||
|
||||
|
||||
# Get the current branch name
|
||||
status, br = subprocess.getstatusoutput("git branch --show-current")
|
||||
_, gitcommit = subprocess.getstatusoutput("git rev-parse HEAD")
|
||||
br = re.sub('\* ', '', br)
|
||||
|
||||
|
||||
urlpath = re.sub('release/', '', br)
|
||||
|
||||
os.environ['LVGL_URLPATH'] = urlpath
|
||||
os.environ['LVGL_GITCOMMIT'] = gitcommit
|
||||
|
||||
|
||||
lang = "en"
|
||||
print("")
|
||||
print("****************")
|
||||
print("Building")
|
||||
print("****************")
|
||||
|
||||
if clean:
|
||||
print('cleaning...')
|
||||
# api_path = os.path.join(dname, 'API')
|
||||
# xml_path = os.path.join(dname, 'xml')
|
||||
# doxy_path = os.path.join(dname, 'doxygen_html')
|
||||
|
||||
# if os.path.exists(api_path):
|
||||
# shutil.rmtree(api_path)
|
||||
|
||||
# if os.path.exists(lang):
|
||||
# shutil.rmtree(lang)
|
||||
|
||||
if os.path.exists(html_dst_path):
|
||||
shutil.rmtree(html_dst_path)
|
||||
|
||||
# if os.path.exists(xml_path):
|
||||
# shutil.rmtree(xml_path)
|
||||
#
|
||||
# if os.path.exists(doxy_path):
|
||||
# shutil.rmtree(doxy_path)
|
||||
|
||||
# os.mkdir(api_path)
|
||||
# os.mkdir(lang)
|
||||
|
||||
config_builder.run()
|
||||
|
||||
shutil.copytree('.', temp_directory, dirs_exist_ok=True)
|
||||
shutil.copytree(examples_path, os.path.join(temp_directory, 'examples'))
|
||||
|
||||
with open(os.path.join(temp_directory, 'Doxyfile'), 'rb') as f:
|
||||
data = f.read().decode('utf-8')
|
||||
|
||||
data = data.replace('#*#*LV_CONF_PATH*#*#', os.path.join(base_path, 'lv_conf.h'))
|
||||
data = data.replace('*#*#SRC#*#*', '"{0}"'.format(lvgl_src_path))
|
||||
|
||||
with open(os.path.join(temp_directory, 'Doxyfile'), 'wb') as f:
|
||||
f.write(data.encode('utf-8'))
|
||||
|
||||
|
||||
print("Generate the list of examples")
|
||||
ex.exec(temp_directory)
|
||||
|
||||
print("Add translation")
|
||||
add_translation.exec(temp_directory)
|
||||
|
||||
print("Running doxygen")
|
||||
cmd('cd "{temp_directory}" && doxygen Doxyfile'.format(temp_directory=temp_directory))
|
||||
|
||||
print('Reading Doxygen output')
|
||||
|
||||
doc_builder.run(
|
||||
project_path,
|
||||
temp_directory,
|
||||
os.path.join(temp_directory, 'layouts'),
|
||||
os.path.join(temp_directory, 'libs'),
|
||||
os.path.join(temp_directory, 'others'),
|
||||
os.path.join(temp_directory, 'overview'),
|
||||
os.path.join(temp_directory, 'overview', 'renderers'),
|
||||
os.path.join(temp_directory, 'porting'),
|
||||
os.path.join(temp_directory, 'widgets')
|
||||
)
|
||||
|
||||
# we make sure to remove the link to the PDF before the PDF get generated
|
||||
# doesn't make any sense to have a link to the PDF in the PDF. The link gets
|
||||
# added if there is a PDF build so the HTML build will have the link.
|
||||
index_path = os.path.join(temp_directory, 'index.rst')
|
||||
|
||||
with open(index_path, 'rb') as f:
|
||||
index_data = f.read().decode('utf-8')
|
||||
|
||||
if 'PDF version: :download:`LVGL.pdf <LVGL.pdf>`' in index_data:
|
||||
index_data = index_data.replace(
|
||||
'PDF version: :download:`LVGL.pdf <LVGL.pdf>`\n',
|
||||
''
|
||||
)
|
||||
with open(index_path, 'wb') as f:
|
||||
f.write(index_data.encode('utf-8'))
|
||||
|
||||
# BUILD PDF
|
||||
if skip_latex:
|
||||
print("skipping latex build as requested")
|
||||
else:
|
||||
|
||||
# Silly workaround 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 "{src}" "{dst}" -j {cpu}'.format(
|
||||
src=temp_directory,
|
||||
dst=latex_output_path,
|
||||
cpu=os.cpu_count()
|
||||
))
|
||||
|
||||
# Generate PDF
|
||||
cmd('cd "{out_latex}" && latexmk -pdf "LVGL.tex"'.format(
|
||||
out_latex=latex_output_path
|
||||
))
|
||||
|
||||
# Copy the result PDF to the main directory to make
|
||||
# it available for the HTML build
|
||||
|
||||
shutil.copyfile(pdf_src_file, pdf_dst_file)
|
||||
# cmd("cd out_latex && cp -f LVGL.pdf ../LVGL.pdf")
|
||||
|
||||
# add the PDF link so the HTML build will have it.
|
||||
index_data = 'PDF version: :download:`LVGL.pdf <LVGL.pdf>`\n' + index_data
|
||||
|
||||
with open(index_path, 'wb') as f:
|
||||
f.write(index_data.encode('utf-8'))
|
||||
|
||||
# BUILD HTML
|
||||
|
||||
|
||||
def get_version():
|
||||
_, ver = subprocess.getstatusoutput("../scripts/find_version.sh")
|
||||
return ver
|
||||
|
||||
cmd('sphinx-build -b html "{src}" "{dst}" -D version="{version}" -E -j {cpu}'.format(
|
||||
src=html_src_path,
|
||||
dst=html_dst_path,
|
||||
version=get_version(),
|
||||
cpu=os.cpu_count()
|
||||
))
|
||||
|
||||
if develop:
|
||||
print('temp directory:', temp_directory)
|
||||
else:
|
||||
def iter_temp(p):
|
||||
folders = []
|
||||
remove_folder = True
|
||||
for temp_file in os.listdir(p):
|
||||
temp_file = os.path.join(p, temp_file)
|
||||
if os.path.isdir(temp_file):
|
||||
folders.append(temp_file)
|
||||
else:
|
||||
try:
|
||||
os.remove(temp_file)
|
||||
except OSError:
|
||||
remove_folder = False
|
||||
|
||||
for folder in folders:
|
||||
if not iter_temp(folder):
|
||||
remove_folder = False
|
||||
|
||||
if remove_folder:
|
||||
try:
|
||||
os.rmdir(p)
|
||||
except OSError:
|
||||
remove_folder = False
|
||||
|
||||
return remove_folder
|
||||
|
||||
iter_temp(temp_directory)
|
||||
|
||||
config_builder.cleanup()
|
||||
|
||||
print('output path:', html_dst_path)
|
||||
print('\nFINISHED!!')
|
||||
277
libraries/lvgl/docs/conf.py
Executable file
@@ -0,0 +1,277 @@
|
||||
#!/usr/bin/env python3
|
||||
# -*- 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
|
||||
|
||||
sys.path.insert(0, os.path.abspath('./_ext'))
|
||||
|
||||
from sphinx.builders.html import StandaloneHTMLBuilder
|
||||
|
||||
# -- 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_rtd_theme',
|
||||
'sphinx.ext.autodoc',
|
||||
'sphinx.ext.intersphinx',
|
||||
'sphinx.ext.todo',
|
||||
'breathe',
|
||||
'sphinx_sitemap',
|
||||
'lv_example',
|
||||
'sphinx_design',
|
||||
'sphinx_rtd_dark_mode',
|
||||
'link_roles',
|
||||
'sphinxcontrib.mermaid'
|
||||
]
|
||||
|
||||
default_dark_mode = False
|
||||
|
||||
# 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']
|
||||
|
||||
|
||||
# The master toctree document.
|
||||
master_doc = 'index'
|
||||
|
||||
# General information about the project.
|
||||
project = 'LVGL'
|
||||
copyright = '2024, LVGL Kft'
|
||||
author = 'LVGL community'
|
||||
|
||||
|
||||
# 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 = ''
|
||||
|
||||
# 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 = 'en'
|
||||
|
||||
# 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', 'README_*', 'lv_examples', 'out_html', 'env', '_ext', 'examples']
|
||||
|
||||
# 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 = {
|
||||
'display_version': True,
|
||||
'prev_next_buttons_location': 'both',
|
||||
'style_external_links': False,
|
||||
# 'vcs_pageview_mode': '',
|
||||
# 'style_nav_header_background': 'white',
|
||||
# Toc options
|
||||
'sticky_navigation': True,
|
||||
'navigation_depth': 4,
|
||||
'includehidden': True,
|
||||
'titles_only': False,
|
||||
|
||||
'collapse_navigation': False,
|
||||
'logo_only': True,
|
||||
}
|
||||
|
||||
|
||||
# For site map generation
|
||||
html_baseurl = f"https://docs.lvgl.io/{os.environ['LVGL_URLPATH']}/"
|
||||
|
||||
sitemap_url_scheme = "{link}"
|
||||
|
||||
#lvgl_github_url = f"https://github.com/lvgl/lvgl/blob/{os.environ['LVGL_GITCOMMIT']}/docs"
|
||||
|
||||
#extlinks = {'github_link_base': (github_url + '%s', github_url)}
|
||||
|
||||
html_context = {
|
||||
'github_version': os.environ['LVGL_GITCOMMIT'],
|
||||
'github_user': 'lvgl',
|
||||
'github_repo': 'lvgl',
|
||||
'display_github': True,
|
||||
'conf_py_path': '/docs/'
|
||||
}
|
||||
|
||||
|
||||
# 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_js_files = [
|
||||
'js/custom.js',
|
||||
'js/include_html.js'
|
||||
]
|
||||
|
||||
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_engine = 'xelatex'
|
||||
latex_use_xindy = False
|
||||
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',
|
||||
'babel': '\\usepackage{babel}',
|
||||
'passoptionstopackages': r'''
|
||||
\PassOptionsToPackage{bookmarksdepth=5}{hyperref}% depth of pdf bookmarks
|
||||
''',
|
||||
'preamble': r'''
|
||||
\usepackage{fontspec}
|
||||
\setmonofont{DejaVu Sans Mono}
|
||||
\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,
|
||||
'LVGL community', '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
|
||||
|
||||
repo_commit_hash = os.environ['LVGL_GITCOMMIT']
|
||||
|
||||
|
||||
# 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_css_file('css/custom.css')
|
||||
app.add_css_file('css/fontawesome.min.css')
|
||||
49
libraries/lvgl/docs/config_builder.py
Normal file
@@ -0,0 +1,49 @@
|
||||
|
||||
import os
|
||||
|
||||
base_path = os.path.dirname(__file__)
|
||||
dst_config = os.path.join(base_path, 'lv_conf.h')
|
||||
src_config = os.path.abspath(os.path.join(
|
||||
base_path,
|
||||
'..',
|
||||
'lv_conf_template.h'
|
||||
))
|
||||
|
||||
|
||||
def run(c_path=None):
|
||||
global dst_config
|
||||
|
||||
if c_path is not None:
|
||||
dst_config = c_path
|
||||
|
||||
with open(src_config, 'r') as f:
|
||||
data = f.read()
|
||||
|
||||
data = data.split('\n')
|
||||
|
||||
for i, line in enumerate(data):
|
||||
if 'LV_USE_PROFILER' in line:
|
||||
continue
|
||||
|
||||
if 'LV_USE' in line or 'LV_FONT' in line and '#define' in line:
|
||||
line = [item for item in line.split(' ') if item]
|
||||
|
||||
for j, item in enumerate(line):
|
||||
if item == '0':
|
||||
line[j] = '1'
|
||||
|
||||
line = ' '.join(line)
|
||||
data[i] = line
|
||||
elif line.startswith('#if 0'):
|
||||
line = line.replace('#if 0', '#if 1')
|
||||
data[i] = line
|
||||
|
||||
data = '\n'.join(data)
|
||||
|
||||
with open(dst_config, 'w') as f:
|
||||
f.write(data)
|
||||
|
||||
|
||||
def cleanup():
|
||||
if os.path.exists(dst_config):
|
||||
os.remove(dst_config)
|
||||
1353
libraries/lvgl/docs/doc_builder.py
Normal file
163
libraries/lvgl/docs/example_list.py
Executable file
@@ -0,0 +1,163 @@
|
||||
#!/usr/bin/env python3
|
||||
import os
|
||||
|
||||
|
||||
def process_index_rst(path):
|
||||
# print(path)
|
||||
with open(path, 'r') as fp:
|
||||
data = fp.read()
|
||||
|
||||
data = data.split('\n')
|
||||
|
||||
last_line = ""
|
||||
title_tmp = ""
|
||||
|
||||
for line in data:
|
||||
line = line.strip()
|
||||
|
||||
if not line:
|
||||
continue
|
||||
|
||||
if line.startswith('---'):
|
||||
title_tmp = last_line.strip()
|
||||
|
||||
elif line.startswith('.. lv_example::'):
|
||||
name = line.replace('.. lv_example::', '').strip()
|
||||
yield name, title_tmp
|
||||
|
||||
last_line = line
|
||||
|
||||
|
||||
h1 = {
|
||||
"get_started": "Get started",
|
||||
"styles": "Styles",
|
||||
"anim": "Animations",
|
||||
"event": "Events",
|
||||
"layouts": "Layouts",
|
||||
"scroll": "Scrolling",
|
||||
"widgets": "Widgets"
|
||||
}
|
||||
|
||||
widgets = {
|
||||
"obj": "Base object",
|
||||
"arc": "Arc",
|
||||
"bar": "Bar",
|
||||
"btn": "Button",
|
||||
"btnmatrix": "Button matrix",
|
||||
"calendar": "Calendar",
|
||||
"canvas": "Canvas",
|
||||
"chart": "Chart",
|
||||
"checkbox": "Checkbox",
|
||||
"colorwheel": "Colorwheel",
|
||||
"dropdown": "Dropdown",
|
||||
"img": "Image",
|
||||
"imagebutton": "Image button",
|
||||
"keyboard": "Keyboard",
|
||||
"label": "Label",
|
||||
"led": "LED",
|
||||
"line": "Line",
|
||||
"list": "List",
|
||||
"menu": "Menu",
|
||||
"meter": "Meter",
|
||||
"msgbox": "Message box",
|
||||
"roller": "Roller",
|
||||
"scale":"Scale",
|
||||
"slider": "Slider",
|
||||
"span": "Span",
|
||||
"spinbox": "Spinbox",
|
||||
"spinner": "Spinner",
|
||||
"switch": "Switch",
|
||||
"table": "Table",
|
||||
"tabview": "Tabview",
|
||||
"textarea": "Textarea",
|
||||
"tileview": "Tileview",
|
||||
"win": "Window",
|
||||
}
|
||||
|
||||
HEADING = '='
|
||||
CHAPTER = '#'
|
||||
SECTION = '*'
|
||||
SUBSECTION = '='
|
||||
SUBSUBSECTION = '-'
|
||||
|
||||
|
||||
def write_header(h_num, text, f):
|
||||
text = text.strip()
|
||||
if h_num == 0:
|
||||
f.write(header_defs[h_num] * len(text))
|
||||
f.write('\n')
|
||||
|
||||
f.write(text + '\n')
|
||||
f.write(header_defs[h_num] * len(text))
|
||||
f.write('\n\n')
|
||||
|
||||
|
||||
# This is the order that Sphinx uses for the headings/titles. 0 is the
|
||||
# largest and 4 is the smallest. If this order is not kept in the reST files
|
||||
# Sphinx will complain
|
||||
header_defs = {
|
||||
0: HEADING,
|
||||
1: CHAPTER,
|
||||
2: SECTION,
|
||||
3: SUBSECTION,
|
||||
4: SUBSUBSECTION
|
||||
}
|
||||
|
||||
layouts = {
|
||||
"flex": "Flex",
|
||||
"grid": "Grid",
|
||||
}
|
||||
|
||||
|
||||
def print_item(path, lvl, d, fout):
|
||||
for k in d:
|
||||
v = d[k]
|
||||
if k.startswith(path + "/lv_example_"):
|
||||
write_header(lvl, v, fout)
|
||||
fout.write(f".. lv_example:: {k}\n")
|
||||
fout.write("\n")
|
||||
|
||||
|
||||
def exec(temp_directory):
|
||||
output_path = os.path.join(temp_directory, 'examples.rst')
|
||||
|
||||
paths = ["../examples/", "../demos/"]
|
||||
fout = open(output_path, "w")
|
||||
filelist = []
|
||||
|
||||
for path in paths:
|
||||
for root, dirs, files in os.walk(path):
|
||||
for f in files:
|
||||
# append the file name to the list
|
||||
filelist.append(os.path.join(root, f))
|
||||
|
||||
filelist = [fi for fi in filelist if fi.endswith("index.rst")]
|
||||
|
||||
d_all = {}
|
||||
# print all the file names
|
||||
for fn in filelist:
|
||||
d_all.update(dict(tuple(item for item in process_index_rst(fn))))
|
||||
|
||||
# fout.write("```eval_rst\n")
|
||||
# fout.write(":github_url: |github_link_base|/examples.md\n")
|
||||
# fout.write("```\n")
|
||||
# fout.write("\n")
|
||||
|
||||
fout.write('.. _examples:\n\n')
|
||||
write_header(0, 'Examples', fout)
|
||||
|
||||
for h in h1:
|
||||
write_header(1, h1[h], fout)
|
||||
|
||||
if h == "widgets":
|
||||
for w in widgets:
|
||||
write_header(2, widgets[w], fout)
|
||||
print_item(h + "/" + w, 3, d_all, fout)
|
||||
elif h == "layouts":
|
||||
for l in layouts:
|
||||
write_header(2, layouts[l], fout)
|
||||
print_item(h + "/" + l, 3, d_all, fout)
|
||||
else:
|
||||
print_item(h, 2, d_all, fout)
|
||||
|
||||
fout.write("")
|
||||
BIN
libraries/lvgl/docs/favicon.png
Normal file
|
After Width: | Height: | Size: 1.9 KiB |
23082
libraries/lvgl/docs/flyers/LVGL-Chinese-Flyer.pdf
Normal file
27
libraries/lvgl/docs/get-started/index.rst
Normal file
@@ -0,0 +1,27 @@
|
||||
.. _get_started:
|
||||
|
||||
===========
|
||||
Get started
|
||||
===========
|
||||
|
||||
There are several ways to get your feet wet with LVGL. Here is one
|
||||
recommended order of documents to read and things to play with when you
|
||||
are learning to use LVGL:
|
||||
|
||||
1. Check the `Online demos <https://lvgl.io/demos>`__ to see LVGL in action (3 minutes)
|
||||
2. Read the :ref:`introduction` page of the documentation (5 minutes)
|
||||
3. Read the :ref:`quick-overview` page of the documentation (15 minutes)
|
||||
4. Set up a :ref:`simulator` (10 minutes)
|
||||
5. Try out some :ref:`examples`
|
||||
6. Check out the Platform-specific tutorials. (in this section below). (10 minutes)
|
||||
7. Port LVGL to a board. See the :ref:`porting` guide or check the ready to use `Projects <https://github.com/lvgl?q=lv_port_&type=&language=>`__
|
||||
8. Read the :ref:`overview` page to get a better understanding of the library. (2-3 hours)
|
||||
9. Check the documentation of the :ref:`widgets` to see their features and usage
|
||||
10. If you have questions got to the `Forum <http://forum.lvgl.io/>`__
|
||||
11. Read the :ref:`contributing` guide to see how you can help to improve LVGL (15 minutes)
|
||||
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 2
|
||||
|
||||
quick-overview
|
||||
367
libraries/lvgl/docs/get-started/quick-overview.rst
Normal file
@@ -0,0 +1,367 @@
|
||||
.. _quick-overview:
|
||||
|
||||
==============
|
||||
Quick overview
|
||||
==============
|
||||
|
||||
Here you can learn the most important things about LVGL. You should read
|
||||
this first to get a general impression and read the detailed
|
||||
:ref:`porting` and :ref:`overview` sections
|
||||
after that.
|
||||
|
||||
Get started in a simulator
|
||||
--------------------------
|
||||
|
||||
Instead of porting LVGL to embedded hardware straight away, it's highly
|
||||
recommended to get started in a simulator first.
|
||||
|
||||
LVGL is ported to many IDEs to be sure you will find your favorite one.
|
||||
Go to the :ref:`simulator` section to get ready-to-use projects that can be run
|
||||
on your PC. This way you can save the time of porting for now and get some
|
||||
experience with LVGL immediately.
|
||||
|
||||
Add LVGL into your project
|
||||
--------------------------
|
||||
|
||||
If you would rather try LVGL on your own project follow these steps:
|
||||
|
||||
- `Download <https://github.com/lvgl/lvgl/archive/master.zip>`__ or
|
||||
clone the library from GitHub with ``git clone https://github.com/lvgl/lvgl.git``.
|
||||
- Copy the ``lvgl`` folder into your project. If you wish you can add only ``lvgl/lvgl.h``, ``lvgl/lv_version.h``, and ``lvgl/src``
|
||||
for LVGL itself, and ``lvgl/examples`` and ``lvgl/demos`` for the examples and demos respectively.
|
||||
- Copy ``lvgl/lv_conf_template.h`` as ``lv_conf.h`` next to the
|
||||
``lvgl`` folder, change the first ``#if 0`` to ``1`` to enable the
|
||||
file's content and set the :c:macro:`LV_COLOR_DEPTH` defines.
|
||||
- Include ``lvgl/lvgl.h`` in files where you need to use LVGL related functions.
|
||||
- Call :cpp:func:`lv_init`
|
||||
- Call :cpp:expr:`lv_tick_inc(x)` every ``x`` milliseconds in a Timer or Task
|
||||
(``x`` should be between 1 and 10). It is required for the internal
|
||||
timing of LVGL. Alternatively, register a ``tick_get_cb`` with
|
||||
:cpp:func:`lv_tick_set_cb` so that LVGL can retrieve the current time directly.
|
||||
- Create a display.
|
||||
|
||||
.. code:: c
|
||||
|
||||
lv_display_t *display = lv_display_create(MY_DISP_HOR_RES, MY_DISP_VER_RES);
|
||||
|
||||
- Create a draw buffer: LVGL supports multiple buffering methods. Here you
|
||||
can see how to set up partial buffering
|
||||
(that is render the screen and the changed areas in a smaller buffer).
|
||||
The buffer size can be set freely but 1/10 screen size is a good starting point.
|
||||
|
||||
.. code:: c
|
||||
|
||||
/*Declare a buffer for 1/10 screen size*/
|
||||
#define BYTE_PER_PIXEL (LV_COLOR_FORMAT_GET_SIZE(LV_COLOR_FORMAT_RGB565)) /*will be 2 for RGB565 */
|
||||
static uint8_t buf1[MY_DISP_HOR_RES * MY_DISP_VER_RES / 10 * BYTE_PER_PIXEL];
|
||||
lv_display_set_buffers(display, buf1, NULL, sizeof(buf1), LV_DISPLAY_RENDER_MODE_PARTIAL); /*Initialize the display buffer.*/
|
||||
|
||||
- Implement and register a function which can copy the rendered image
|
||||
to an area of your display:
|
||||
|
||||
.. code:: c
|
||||
|
||||
lv_display_set_flush_cb(display, my_disp_flush);
|
||||
|
||||
void my_disp_flush(lv_display_t * disp, const lv_area_t * area, lv_color_t * color_p)
|
||||
{
|
||||
int32_t x, y;
|
||||
/*It's a very slow but simple implementation.
|
||||
*`set_pixel` needs to be written by you to a set pixel on the screen*/
|
||||
for(y = area->y1; y <= area->y2; y++) {
|
||||
for(x = area->x1; x <= area->x2; x++) {
|
||||
set_pixel(x, y, *color_p);
|
||||
color_p++;
|
||||
}
|
||||
}
|
||||
|
||||
lv_display_flush_ready(disp); /* Indicate you are ready with the flushing*/
|
||||
}
|
||||
|
||||
- Implement and register a function which can read an input device.
|
||||
E.g. for a touchpad:
|
||||
|
||||
.. code:: c
|
||||
|
||||
lv_indev_t * indev = lv_indev_create(); /*Create an input device*/
|
||||
lv_indev_set_type(indev, LV_INDEV_TYPE_POINTER); /*Touch pad is a pointer-like device*/
|
||||
lv_ondev_set_read_cb(indev, my_touchpad_read); /*Set your driver function*/
|
||||
|
||||
void my_touchpad_read(lv_indev_drv_t * indev_drv, lv_indev_data_t * data)
|
||||
{
|
||||
/*`touchpad_is_pressed` and `touchpad_get_xy` needs to be implemented by you*/
|
||||
if(touchpad_is_pressed()) {
|
||||
data->state = LV_INDEV_STATE_PRESSED;
|
||||
touchpad_get_xy(&data->point.x, &data->point.y);
|
||||
} else {
|
||||
data->state = LV_INDEV_STATE_RELEASED;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
- Call :cpp:func:`lv_timer_handler` periodically every few milliseconds in
|
||||
the main ``while(1)`` loop or in an operating system task. It will
|
||||
redraw the screen if required, handle input devices, animation etc.
|
||||
|
||||
For a more detailed guide go to the :ref:`porting`
|
||||
section.
|
||||
|
||||
Learn the basics
|
||||
----------------
|
||||
|
||||
.. _quick-overview_widgets:
|
||||
|
||||
Widgets
|
||||
~~~~~~~
|
||||
|
||||
The graphical elements like Buttons, Labels, Sliders, Charts etc. are
|
||||
called objects or widgets. Go to :ref:`widgets` to see the
|
||||
full list of available widgets.
|
||||
|
||||
Every object has a parent object where it is created. For example, if a
|
||||
label is created on a button, the button is the parent of label.
|
||||
|
||||
The child object moves with the parent and if the parent is deleted the
|
||||
children will be deleted too.
|
||||
|
||||
Children can be visible only within their parent's bounding area. In
|
||||
other words, the parts of the children outside the parent are clipped.
|
||||
|
||||
A Screen is the "root" parent. You can have any number of screens.
|
||||
|
||||
To get the current screen call :cpp:func:`lv_screen_active`, and to load a screen
|
||||
use :cpp:expr:`lv_screen_load(scr1)`.
|
||||
|
||||
You can create a new object with ``lv_<type>_create(parent)``. It will
|
||||
return an :cpp:type:`lv_obj_t` ``*`` variable that can be used as a reference to the
|
||||
object to set its parameters.
|
||||
|
||||
For example:
|
||||
|
||||
.. code:: c
|
||||
|
||||
lv_obj_t * slider1 = lv_slider_create(lv_screen_active());
|
||||
|
||||
To set some basic attributes ``lv_obj_set_<parameter_name>(obj, <value>)`` functions can be used. For
|
||||
example:
|
||||
|
||||
.. code:: c
|
||||
|
||||
lv_obj_set_x(btn1, 30);
|
||||
lv_obj_set_y(btn1, 10);
|
||||
lv_obj_set_size(btn1, 200, 50);
|
||||
|
||||
Along with the basic attributes, widgets can have type specific
|
||||
parameters which are set by ``lv_<widget_type>_set_<parameter_name>(obj, <value>)`` functions. For
|
||||
example:
|
||||
|
||||
.. code:: c
|
||||
|
||||
lv_slider_set_value(slider1, 70, LV_ANIM_ON);
|
||||
|
||||
To see the full API visit the documentation of the widgets or the
|
||||
related header file
|
||||
(e.g. `lvgl/src/widgets/slider/lv_slider.h <https://github.com/lvgl/lvgl/blob/master/src/widgets/slider/lv_slider.h>`__).
|
||||
|
||||
.. _quick-overview_events:
|
||||
|
||||
Events
|
||||
~~~~~~
|
||||
|
||||
Events are used to inform the user that something has happened with an
|
||||
object. You can assign one or more callbacks to an object which will be
|
||||
called if the object is clicked, released, dragged, being deleted, etc.
|
||||
|
||||
A callback is assigned like this:
|
||||
|
||||
.. code:: c
|
||||
|
||||
lv_obj_add_event_cb(btn, btn_event_cb, LV_EVENT_CLICKED, NULL); /*Assign a callback to the button*/
|
||||
|
||||
...
|
||||
|
||||
void btn_event_cb(lv_event_t * e)
|
||||
{
|
||||
printf("Clicked\n");
|
||||
}
|
||||
|
||||
:cpp:enumerator:`LV_EVENT_ALL` can be used instead of :cpp:enumerator:`LV_EVENT_CLICKED` to invoke
|
||||
the callback for any event.
|
||||
|
||||
From :cpp:expr:`lv_event_t * e` the current event code can be retrieved with:
|
||||
|
||||
.. code:: c
|
||||
|
||||
lv_event_code_t code = lv_event_get_code(e);
|
||||
|
||||
The object that triggered the event can be retrieved with:
|
||||
|
||||
.. code:: c
|
||||
|
||||
lv_obj_t * obj = lv_event_get_target(e);
|
||||
|
||||
To learn all features of the events go to the :ref:`events` section.
|
||||
|
||||
.. _quick-overview_parts:
|
||||
|
||||
Parts
|
||||
~~~~~
|
||||
|
||||
Widgets might be built from one or more *parts*. For example, a button
|
||||
has only one part called :cpp:enumerator:`LV_PART_MAIN`. However, a
|
||||
:ref:`lv_slider` has :cpp:enumerator:`LV_PART_MAIN`, :cpp:enumerator:`LV_PART_INDICATOR`
|
||||
and :cpp:enumerator:`LV_PART_KNOB`.
|
||||
|
||||
By using parts you can apply different styles to sub-elements of a
|
||||
widget. (See below)
|
||||
|
||||
Read the widgets' documentation to learn which parts each uses.
|
||||
|
||||
.. _quick-overview_states:
|
||||
|
||||
States
|
||||
~~~~~~
|
||||
|
||||
LVGL objects can be in a combination of the following states:
|
||||
|
||||
- :cpp:enumerator:`LV_STATE_DEFAULT`: Normal, released state
|
||||
- :cpp:enumerator:`LV_STATE_CHECKED`: Toggled or checked state
|
||||
- :cpp:enumerator:`LV_STATE_FOCUSED`: Focused via keypad or encoder or clicked via touchpad/mouse
|
||||
- :cpp:enumerator:`LV_STATE_FOCUS_KEY`: Focused via keypad or encoder but not via touchpad/mouse
|
||||
- :cpp:enumerator:`LV_STATE_EDITED`: Edit by an encoder
|
||||
- :cpp:enumerator:`LV_STATE_HOVERED`: Hovered by mouse
|
||||
- :cpp:enumerator:`LV_STATE_PRESSED`: Being pressed
|
||||
- :cpp:enumerator:`LV_STATE_SCROLLED`: Being scrolled
|
||||
- :cpp:enumerator:`LV_STATE_DISABLED`: Disabled
|
||||
|
||||
For example, if you press an object it will automatically go to the
|
||||
:cpp:enumerator:`LV_STATE_FOCUSED` and :cpp:enumerator:`LV_STATE_PRESSED` states and when you
|
||||
release it the :cpp:enumerator:`LV_STATE_PRESSED` state will be removed while focus
|
||||
remains active.
|
||||
|
||||
To check if an object is in a given state use
|
||||
``lv_obj_has_state(obj, LV_STATE_...)``. It will return ``true`` if the
|
||||
object is currently in that state.
|
||||
|
||||
To manually add or remove states use:
|
||||
|
||||
.. code:: c
|
||||
|
||||
lv_obj_add_state(obj, LV_STATE_...);
|
||||
lv_obj_remove_state(obj, LV_STATE_...);
|
||||
|
||||
.. _quick-overview_styles:
|
||||
|
||||
Styles
|
||||
~~~~~~
|
||||
|
||||
A style instance contains properties such as background color, border
|
||||
width, font, etc. that describe the appearance of objects.
|
||||
|
||||
Styles are represented with :cpp:struct:`lv_style_t` variables. Only their pointer
|
||||
is saved in the objects so they need to be defined as static or global.
|
||||
Before using a style it needs to be initialized with
|
||||
:cpp:expr:`lv_style_init(&style1)`. After that, properties can be added to
|
||||
configure the style. For example:
|
||||
|
||||
.. code:: c
|
||||
|
||||
static lv_style_t style1;
|
||||
lv_style_init(&style1);
|
||||
lv_style_set_bg_color(&style1, lv_color_hex(0xa03080))
|
||||
lv_style_set_border_width(&style1, 2))
|
||||
|
||||
See the full list of properties here :ref:`styles_properties`.
|
||||
|
||||
Styles are assigned using the ORed combination of an object's part and
|
||||
state. For example to use this style on the slider's indicator when the
|
||||
slider is pressed:
|
||||
|
||||
.. code:: c
|
||||
|
||||
lv_obj_add_style(slider1, &style1, LV_PART_INDICATOR | LV_STATE_PRESSED);
|
||||
|
||||
If the *part* is :cpp:enumerator:`LV_PART_MAIN` it can be omitted:
|
||||
|
||||
.. code:: c
|
||||
|
||||
lv_obj_add_style(btn1, &style1, LV_STATE_PRESSED); /*Equal to LV_PART_MAIN | LV_STATE_PRESSED*/
|
||||
|
||||
Similarly, :cpp:enumerator:`LV_STATE_DEFAULT` can be omitted too:
|
||||
|
||||
.. code:: c
|
||||
|
||||
lv_obj_add_style(slider1, &style1, LV_PART_INDICATOR); /*Equal to LV_PART_INDICATOR | LV_STATE_DEFAULT*/
|
||||
|
||||
For :cpp:enumerator:`LV_STATE_DEFAULT` and :cpp:enumerator:`LV_PART_MAIN` simply write ``0``:
|
||||
|
||||
.. code:: c
|
||||
|
||||
lv_obj_add_style(btn1, &style1, 0); /*Equal to LV_PART_MAIN | LV_STATE_DEFAULT*/
|
||||
|
||||
Styles can be cascaded (similarly to CSS). It means you can add more
|
||||
styles to a part of an object. For example ``style_btn`` can set a
|
||||
default button appearance, and ``style_btn_red`` can overwrite the
|
||||
background color to make the button red:
|
||||
|
||||
.. code:: c
|
||||
|
||||
lv_obj_add_style(btn1, &style_btn, 0);
|
||||
lv_obj_add_style(btn1, &style1_btn_red, 0);
|
||||
|
||||
If a property is not set on for the current state, the style with
|
||||
:cpp:enumerator:`LV_STATE_DEFAULT` will be used. A default value is used if the
|
||||
property is not defined in the default state.
|
||||
|
||||
Some properties (typically the text-related ones) can be inherited. This
|
||||
means if a property is not set in an object it will be searched for in
|
||||
its parents too. For example, you can set the font once in the screen's
|
||||
style and all text on that screen will inherit it by default.
|
||||
|
||||
Local style properties also can be added to objects. This creates a
|
||||
style which resides inside the object and is used only by the object:
|
||||
|
||||
.. code:: c
|
||||
|
||||
lv_obj_set_style_bg_color(slider1, lv_color_hex(0x2080bb), LV_PART_INDICATOR | LV_STATE_PRESSED);
|
||||
|
||||
To learn all the features of styles see the :ref:`styles` section.
|
||||
|
||||
.. _quick-overview_themes:
|
||||
|
||||
Themes
|
||||
~~~~~~
|
||||
|
||||
Themes are the default styles for objects. Styles from a theme are
|
||||
applied automatically when objects are created.
|
||||
|
||||
The theme for your application is a compile time configuration set in
|
||||
``lv_conf.h``.
|
||||
|
||||
.. _quick-overview_examples:
|
||||
|
||||
Examples
|
||||
--------
|
||||
|
||||
.. include:: ../examples/get_started/index.rst
|
||||
|
||||
.. _quick-overview_micropython:
|
||||
|
||||
MicroPython
|
||||
-----------
|
||||
|
||||
Learn more about :ref:`micropython`.
|
||||
|
||||
.. code:: python
|
||||
|
||||
# Initialize
|
||||
import display_driver
|
||||
import lvgl as lv
|
||||
|
||||
# Create a button with a label
|
||||
scr = lv.obj()
|
||||
btn = lv.button(scr)
|
||||
btn.align(lv.ALIGN.CENTER, 0, 0)
|
||||
label = lv.label(btn)
|
||||
label.set_text('Hello World!')
|
||||
lv.screen_load(scr)
|
||||
33
libraries/lvgl/docs/index.rst
Normal file
@@ -0,0 +1,33 @@
|
||||
=====================================
|
||||
Welcome to the documentation of LVGL!
|
||||
=====================================
|
||||
|
||||
.. raw:: html
|
||||
|
||||
<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.html"><img class="home-img" src="_static/img/home_6.png" alt="Be part of the development of LVGL"></a>
|
||||
|
||||
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 6
|
||||
|
||||
intro/index
|
||||
examples
|
||||
get-started/index
|
||||
integration/index
|
||||
porting/index
|
||||
overview/index
|
||||
widgets/index
|
||||
layouts/index
|
||||
libs/index
|
||||
others/index
|
||||
API/index
|
||||
CONTRIBUTING
|
||||
CODING_STYLE
|
||||
CHANGELOG
|
||||
ROADMAP
|
||||
504
libraries/lvgl/docs/integration/bindings/api_json.rst
Normal file
@@ -0,0 +1,504 @@
|
||||
Output API as JSON data
|
||||
=======================
|
||||
|
||||
We have written a script that will read the header files in LVGL and outputs a
|
||||
more friendly JSON format for the API. This is done so that bindings that generate
|
||||
code automatically will have an easy way to collect the needed information without
|
||||
having to reinvent the wheel. The JSON data format has already made libraries for
|
||||
reading the format for just about every programming language out there.
|
||||
|
||||
The script in order to run does have some requirements.
|
||||
|
||||
- Python >= 3.10
|
||||
- Pycparser >= 2.21: Python Library for reading the preprocessor ouotput from the C compiler
|
||||
- PyMSVC >= 0.4.0: Python library is using MSVC Compiler
|
||||
- C compiler, gcc for Linux, clang for OSX and MSVC for Windows
|
||||
- Doxygen: used to read the docstrings from the header files.
|
||||
|
||||
There are several options when running the script. They are as follows
|
||||
|
||||
- `--output-path`: output directory for JSON file. If one is not supplied
|
||||
then it will be output stdout
|
||||
- `--lvgl-config`: path to lv_conf.h (including file name), if this is not
|
||||
set then a config file will be generated that has most common things turned on
|
||||
- `--develop`: leaves the temporary folder in place.
|
||||
|
||||
|
||||
to use the script
|
||||
|
||||
.. code:: shell
|
||||
|
||||
python /scripts/gen_json/gen_json.py --output-path=json/output/directory --lvgl-config=path/to/lv_conf.h
|
||||
|
||||
|
||||
or if you want to run a subprocess from inside of a generation script and read the output from stdout
|
||||
|
||||
.. code:: shell
|
||||
|
||||
python /scripts/gen_json/gen_json.py --lvgl-config=path/to/lv_conf.h
|
||||
|
||||
|
||||
|
||||
|
||||
The JSON data is broken apart into a couple of main categories.
|
||||
|
||||
- enums
|
||||
- functions
|
||||
- function_pointers
|
||||
- structures
|
||||
- unions
|
||||
- variables
|
||||
- typedefs
|
||||
- forward_decls
|
||||
- macros
|
||||
|
||||
Those categories are the element names undert the root of the JSON data.
|
||||
The value for each categry is an array of JSON elements. There is a bit of
|
||||
nesting with the elements in the arrays and I have created "json_types" that
|
||||
will allow you to identify exactly what you are dealing with.
|
||||
|
||||
The different "json_types" are as follows:
|
||||
|
||||
- ``"array"``: The array type is used to identify arrays.
|
||||
|
||||
Available JSON fields:
|
||||
- ``"dim"``: number of items in the array
|
||||
- ``"quals"``: array of qualifiers, IE "const"
|
||||
- ``"type"``: This may or may not be available.
|
||||
- ``"name"``: the name of the data type
|
||||
|
||||
|
||||
- ``"field"``: This type is used to describe fields in structures and unions.
|
||||
It is used in the ``"fields"`` array of the ``"struct"`` and ``"union"`` JSON types.
|
||||
|
||||
Available JSON fields:
|
||||
- ``"name"``: The name of the field.
|
||||
- ``"type"``: This contains the type information for the field. Check the
|
||||
``"json_type"`` to know what type you are dealing with.
|
||||
- ``"bitsize"``: The number of bits the field has or ``null``
|
||||
if there is no bit size defined
|
||||
- ``"docstring"``: you should know what this is.
|
||||
|
||||
|
||||
- ``"arg"``: Used to describe an argument/parameter in a function or a function pointer.
|
||||
|
||||
Available JSON fields:
|
||||
- ``"name"``: The name of the argument/parameter.
|
||||
- ``"type"``: This contains the type information for the field. Check the
|
||||
``"json_type"`` to know what type you are dealing with.
|
||||
- ``"docstring"``: you should know what this is.
|
||||
- ``"quals"``: array of qualifiers, IE "const"
|
||||
|
||||
|
||||
- ``"forward_decl"``: Describes a forward declaration.There are structures in
|
||||
LVGL that are considered to be private and that is what these desccribe.
|
||||
|
||||
Available JSON fields:
|
||||
- ``"name"``: The name of the formard declaration.
|
||||
- ``"type"``: This contains the type information for the field. Check the
|
||||
``"json_type"`` to know what type you are dealing with.
|
||||
- ``"docstring"``: you should know what this is.
|
||||
- ``"quals"``: array of qualifiers, IE "const"
|
||||
|
||||
|
||||
- ``"function_pointer"``: Describes a function pointer. These are used when
|
||||
registering callback functions in LVGL.
|
||||
|
||||
Available JSON fields:
|
||||
- ``"name"``: The name of the function pointer.
|
||||
- ``"type"``: This contains the return type information for the function pointer.
|
||||
- ``"docstring"``: you should know what this is.
|
||||
- ``"args"``: array of ``"arg"`` objects. This describes the fuction arguments/parameters.
|
||||
- ``"quals"``: array of qualifiers, IE "const"
|
||||
|
||||
|
||||
- ``"variable"``: Describes a global variable.
|
||||
|
||||
Available JSON fields:
|
||||
- ``"name"``: The name of the variable.
|
||||
- ``"type"``: This contains the type information for the field. Check the
|
||||
``"json_type"`` to know what type you are dealing with.
|
||||
- ``"docstring"``: you should know what this is.
|
||||
- ``"quals"``: array of qualifiers, IE "const"
|
||||
- ``"storage"``: array of storage classifiers, IE "extern"
|
||||
|
||||
|
||||
- ``"special_type"``: Currently only used to describe an ellipsis argument
|
||||
for a function.
|
||||
|
||||
Available JSON fields:
|
||||
- ``"name"``: will always be "ellipsis".
|
||||
|
||||
|
||||
- ``"primitive_type"``: This is a base type. There or no other types beneith this.
|
||||
This tells you that the type is a basic or primitive C type.
|
||||
IE: struct, union, int, unsigned int, etc...
|
||||
|
||||
Available JSON fields:
|
||||
- ``"name"``: The name of the primitive type.
|
||||
|
||||
|
||||
- ``"enum"``: Describes a grouping of enumeration items/members.
|
||||
|
||||
Available JSON fields:
|
||||
- ``"name"``: The name of the enumeration group/type.
|
||||
- ``"type"``: This contains the type information for the enumeration group.
|
||||
This is always going to be an "int" type. Make sure you do not use this
|
||||
type as the type for the members of this enumeration group. Check the
|
||||
enumeration members type to get the correct type.
|
||||
- ``"docstring"``: you should know what this is.
|
||||
- ``"members"``: array of ``"enum_member"`` objects
|
||||
|
||||
|
||||
- ``"enum_member"``: Describes an enumeration item/member. Only found under
|
||||
the ``"members"`` field of an ``"enum"`` JSON type
|
||||
|
||||
Available JSON fields:
|
||||
- ``"name"``: The name of the enumeration.
|
||||
- ``"type"``: This contains the type information for the enum member.
|
||||
This gets a bit tricky because the type specified in here is not always
|
||||
going to be an "int". It will usually point to an lvgl type and the type
|
||||
of the lvgl type can be found in the ``"typedefs"`` section.
|
||||
- ``"docstring"``: you should know what this is.
|
||||
- ``"value"``: the enumeration member/item's value
|
||||
|
||||
|
||||
- ``"lvgl_type"``: This is a base type. There or no other types beneith this.
|
||||
This tells you that the type is an LVGL data type.
|
||||
|
||||
Available JSON fields:
|
||||
- ``"name"``: The name of the type.
|
||||
- ``"quals"``: array of qualifiers, IE "const
|
||||
|
||||
|
||||
- ``"struct"``: Describes a structure
|
||||
|
||||
Available JSON fields:
|
||||
- ``"name"``: The name of the structure.
|
||||
- ``"type"``: This contains the primitive type information for the structure.
|
||||
- ``"docstring"``: you should know what this is.
|
||||
- ``"fields"``: array of ``"field"`` elements.
|
||||
- ``"quals"``: array of qualifiers, IE "const"
|
||||
|
||||
|
||||
- ``"union"``: Describes a union
|
||||
|
||||
Available JSON fields:
|
||||
- ``"name"``: The name of the union.
|
||||
- ``"type"``: This contains the primitive type information for the union.
|
||||
- ``"docstring"``: you should know what this is.
|
||||
- ``"fields"``: array of ``"field"`` elements.
|
||||
- ``"quals"``: array of qualifiers, IE "const"
|
||||
|
||||
|
||||
- ``"macro"``: describes a macro. There is limited information that can be
|
||||
collected about macros and in most cases a binding will need to have these
|
||||
statically added to a binding. It is more for collecting the docstrings than
|
||||
anything else.
|
||||
|
||||
Available JSON fields:
|
||||
- ``"name"``: The name of the macro.
|
||||
- ``"docstring"``: you should know what this is.
|
||||
|
||||
|
||||
- ``"ret_type"``: return type from a function. This is only going to be seen in the ``"type"``
|
||||
element of a ``"function"`` type.
|
||||
|
||||
Available JSON fields:
|
||||
- ``"type"``: This contains the type information for the field. Check the
|
||||
``"json_type"`` to know what type you are dealing with.
|
||||
- ``"docstring"``: you should know what this is.
|
||||
|
||||
|
||||
- ``"function"``: Describes a function.
|
||||
|
||||
Available JSON fields:
|
||||
- ``"name"``: The name of the function.
|
||||
- ``"type"``: This contains the type information for the return value.
|
||||
- ``"docstring"``: you should know what this is.
|
||||
- ``"args"``: array of ``"arg"`` json types. This describes the fuction arguments/parameters.
|
||||
|
||||
|
||||
- ``"stdlib_type"``: This is a base type, meaning that there are no more
|
||||
type levels beneith this. This tells us that the type is from the C stdlib.
|
||||
|
||||
Available JSON fields:
|
||||
- ``"name"``: The name of the type.
|
||||
- ``"quals"``: array of qualifiers, IE "const
|
||||
|
||||
|
||||
- ``"unknown_type"``: This should not be seen. If it is then there needs to be
|
||||
an adjustment made to the script. Please open an issue and let us know if you see this type.
|
||||
|
||||
Available JSON fields:
|
||||
- ``"name"``: The name of the type.
|
||||
- ``"quals"``: array of qualifiers, IE "const
|
||||
|
||||
|
||||
- ``"pointer"``: This is a wrapper object to let you know that the type you
|
||||
are dealing with is a pointer
|
||||
|
||||
Available JSON fields:
|
||||
- ``"type"``: This contains the type information for the pointer. Check the
|
||||
``"json_type"`` to know what type you are dealing with.
|
||||
- ``"quals"``: array of qualifiers, IE "const", may or may not be available.
|
||||
|
||||
|
||||
- ``"typedef"``: type definitions. I will explain more on this below.
|
||||
|
||||
Available JSON fields:
|
||||
- ``"name"``: The name of the typedef.
|
||||
- ``"type"``: This contains the type information for the field. Check the
|
||||
``"json_type"`` to know what type you are dealing with.
|
||||
- ``"docstring"``: you should know what this is.
|
||||
- ``"quals"``: array of qualifiers, IE "const"
|
||||
|
||||
|
||||
|
||||
Here is an example of what the output will look like.
|
||||
|
||||
.. code:: json
|
||||
|
||||
{
|
||||
"enums":[
|
||||
{
|
||||
"name":"_lv_result_t",
|
||||
"type":{
|
||||
"name":"int",
|
||||
"json_type":"primitive_type"
|
||||
},
|
||||
"json_type":"enum",
|
||||
"docstring":"LVGL error codes. ",
|
||||
"members":[
|
||||
{
|
||||
"name":"LV_RESULT_INVALID",
|
||||
"type":{
|
||||
"name":"_lv_result_t",
|
||||
"json_type":"lvgl_type"
|
||||
},
|
||||
"json_type":"enum_member",
|
||||
"docstring":"",
|
||||
"value":"0x0"
|
||||
},
|
||||
{
|
||||
"name":"LV_RESULT_OK",
|
||||
"type":{
|
||||
"name":"_lv_result_t",
|
||||
"json_type":"lvgl_type"
|
||||
},
|
||||
"json_type":"enum_member",
|
||||
"docstring":"",
|
||||
"value":"0x1"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"functions":[
|
||||
{
|
||||
"name":"lv_version_info",
|
||||
"type":{
|
||||
"type":{
|
||||
"type":{
|
||||
"name":"char",
|
||||
"json_type":"primitive_type",
|
||||
"quals":[
|
||||
"const"
|
||||
]
|
||||
},
|
||||
"json_type":"pointer",
|
||||
"quals":[]
|
||||
},
|
||||
"json_type":"ret_type",
|
||||
"docstring":""
|
||||
},
|
||||
"json_type":"function",
|
||||
"docstring":"",
|
||||
"args":[
|
||||
{
|
||||
"name":null,
|
||||
"type":{
|
||||
"name":"void",
|
||||
"json_type":"primitive_type",
|
||||
"quals":[]
|
||||
},
|
||||
"json_type":"arg",
|
||||
"docstring":"",
|
||||
"quals":[]
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"function_pointers":[
|
||||
{
|
||||
"name":"lv_tlsf_walker",
|
||||
"type":{
|
||||
"type":{
|
||||
"name":"void",
|
||||
"json_type":"primitive_type",
|
||||
"quals":[]
|
||||
},
|
||||
"json_type":"ret_type",
|
||||
"docstring":""
|
||||
},
|
||||
"json_type":"function_pointer",
|
||||
"docstring":"",
|
||||
"args":[
|
||||
{
|
||||
"name":"ptr",
|
||||
"type":{
|
||||
"type":{
|
||||
"name":"void",
|
||||
"json_type":"primitive_type",
|
||||
"quals":[]
|
||||
},
|
||||
"json_type":"pointer",
|
||||
"quals":[]
|
||||
},
|
||||
"json_type":"arg",
|
||||
"docstring":""
|
||||
},
|
||||
{
|
||||
"name":"size",
|
||||
"type":{
|
||||
"name":"size_t",
|
||||
"json_type":"stdlib_type",
|
||||
"quals":[]
|
||||
},
|
||||
"json_type":"arg",
|
||||
"docstring":""
|
||||
},
|
||||
{
|
||||
"name":"used",
|
||||
"type":{
|
||||
"name":"int",
|
||||
"json_type":"primitive_type",
|
||||
"quals":[]
|
||||
},
|
||||
"json_type":"arg",
|
||||
"docstring":""
|
||||
},
|
||||
{
|
||||
"name":"user",
|
||||
"type":{
|
||||
"type":{
|
||||
"name":"void",
|
||||
"json_type":"primitive_type",
|
||||
"quals":[]
|
||||
},
|
||||
"json_type":"pointer",
|
||||
"quals":[]
|
||||
},
|
||||
"json_type":"arg",
|
||||
"docstring":""
|
||||
}
|
||||
],
|
||||
"quals":[]
|
||||
}
|
||||
],
|
||||
"structures":[
|
||||
{
|
||||
"name":"_lv_gradient_cache_t",
|
||||
"type":{
|
||||
"name":"struct",
|
||||
"json_type":"primitive_type"
|
||||
},
|
||||
"json_type":"struct",
|
||||
"docstring":null,
|
||||
"fields":[
|
||||
{
|
||||
"name":"color_map",
|
||||
"type":{
|
||||
"type":{
|
||||
"name":"lv_color_t",
|
||||
"json_type":"lvgl_type",
|
||||
"quals":[]
|
||||
},
|
||||
"json_type":"pointer",
|
||||
"quals":[]
|
||||
},
|
||||
"json_type":"field",
|
||||
"bitsize":null,
|
||||
"docstring":""
|
||||
},
|
||||
{
|
||||
"name":"opa_map",
|
||||
"type":{
|
||||
"type":{
|
||||
"name":"lv_opa_t",
|
||||
"json_type":"lvgl_type",
|
||||
"quals":[]
|
||||
},
|
||||
"json_type":"pointer",
|
||||
"quals":[]
|
||||
},
|
||||
"json_type":"field",
|
||||
"bitsize":null,
|
||||
"docstring":""
|
||||
},
|
||||
{
|
||||
"name":"size",
|
||||
"type":{
|
||||
"name":"uint32_t",
|
||||
"json_type":"stdlib_type",
|
||||
"quals":[]
|
||||
},
|
||||
"json_type":"field",
|
||||
"bitsize":null,
|
||||
"docstring":""
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"unions":[],
|
||||
"variables":[
|
||||
{
|
||||
"name":"lv_global",
|
||||
"type":{
|
||||
"name":"lv_global_t",
|
||||
"json_type":"lvgl_type",
|
||||
"quals":[]
|
||||
},
|
||||
"json_type":"variable",
|
||||
"docstring":"",
|
||||
"quals":[],
|
||||
"storage":[
|
||||
"extern"
|
||||
]
|
||||
}
|
||||
],
|
||||
"typedefs":[
|
||||
{
|
||||
"name":"lv_pool_t",
|
||||
"type":{
|
||||
"type":{
|
||||
"name":"void",
|
||||
"json_type":"primitive_type",
|
||||
"quals":[]
|
||||
},
|
||||
"json_type":"pointer"
|
||||
},
|
||||
"json_type":"typedef",
|
||||
"docstring":"",
|
||||
"quals":[]
|
||||
}
|
||||
],
|
||||
"forward_decls":[
|
||||
{
|
||||
"name":"lv_fragment_managed_states_t",
|
||||
"type":{
|
||||
"name":"struct",
|
||||
"json_type":"primitive_type"
|
||||
},
|
||||
"json_type":"forward_decl",
|
||||
"docstring":"",
|
||||
"quals":[]
|
||||
}
|
||||
],
|
||||
"macros":[
|
||||
{
|
||||
"name":"ZERO_MEM_SENTINEL",
|
||||
"json_type":"macro",
|
||||
"docstring":""
|
||||
}
|
||||
]
|
||||
}
|
||||
5
libraries/lvgl/docs/integration/bindings/cpp.rst
Normal file
@@ -0,0 +1,5 @@
|
||||
===
|
||||
Cpp
|
||||
===
|
||||
|
||||
In progress: https://github.com/lvgl/lv_binding_cpp
|
||||
13
libraries/lvgl/docs/integration/bindings/index.rst
Normal file
@@ -0,0 +1,13 @@
|
||||
========
|
||||
Bindings
|
||||
========
|
||||
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 2
|
||||
|
||||
micropython
|
||||
cpp
|
||||
pikascript
|
||||
javascript
|
||||
api_json
|
||||
133
libraries/lvgl/docs/integration/bindings/javascript.rst
Normal file
@@ -0,0 +1,133 @@
|
||||
==========
|
||||
JavaScript
|
||||
==========
|
||||
|
||||
With `lv_binding_js <https://github.com/lvgl/lv_binding_js>`__ you can
|
||||
write lvgl with JavaScript.
|
||||
|
||||
It uses React's virtual DOM concept to manipulate lvgl UI components,
|
||||
providing a familiar React-like experience to users.
|
||||
|
||||
**Code**
|
||||
|
||||
**Code Running on Real Device**
|
||||
|
||||
Table of Contents
|
||||
-----------------
|
||||
|
||||
- `Features <#features>`__
|
||||
- `Demo <#demo>`__
|
||||
- `Building <#building>`__
|
||||
- `Components <#components>`__
|
||||
- `Font <#font>`__
|
||||
- `Animation <#animation>`__
|
||||
- `Style <#style>`__
|
||||
- `JSAPI <#jsapi>`__
|
||||
- `Thanks <#thanks>`__
|
||||
|
||||
Features
|
||||
--------
|
||||
|
||||
- Support all lvgl built-in components
|
||||
- Fully support lvgl flex and grid style
|
||||
- support most lvgl style, just write like html5 css
|
||||
- support dynamic load image
|
||||
- Fully support lvgl animation
|
||||
|
||||
Demo
|
||||
----
|
||||
|
||||
See the
|
||||
`demo <https://github.com/lvgl/lv_binding_js/tree/master/demo>`__ folder
|
||||
|
||||
Building
|
||||
--------
|
||||
|
||||
The following are developer notes on how to build lvgljs on your native
|
||||
platform. They are not complete guides, but include notes on the
|
||||
necessary libraries, compile flags, etc.
|
||||
|
||||
lvgljs
|
||||
~~~~~~
|
||||
|
||||
- `ubuntu build Notes for sdl
|
||||
simulator <https://github.com/lvgl/lv_binding_js/blob/master/doc/build/build-ubuntu-arm.md>`__
|
||||
- `macos x86 build Notes for sdl
|
||||
simulator <https://github.com/lvgl/lv_binding_js/blob/master/doc/build/build-macos-x86-simulator.md>`__
|
||||
- `ubuntu build Notes for platform
|
||||
arm <https://github.com/lvgl/lv_binding_js/blob/master/doc/build/build-ubuntu-x86-simulator.md>`__
|
||||
|
||||
JS Bundle
|
||||
~~~~~~~~~
|
||||
|
||||
- `JS Bundle build
|
||||
Notes <https://github.com/lvgl/lv_binding_js/blob/master/doc/build/js-bundle.md>`__
|
||||
|
||||
Components
|
||||
----------
|
||||
|
||||
- `View <https://github.com/lvgl/lv_binding_js/blob/master/doc/component/View.md>`__
|
||||
- `Image <https://github.com/lvgl/lv_binding_js/blob/master/doc/component/Image.md>`__
|
||||
- `Button <https://github.com/lvgl/lv_binding_js/blob/master/doc/component/Button.md>`__
|
||||
- `Text <https://github.com/lvgl/lv_binding_js/blob/master/doc/component/Text.md>`__
|
||||
- `Input <https://github.com/lvgl/lv_binding_js/blob/master/doc/component/Input.md>`__
|
||||
- `Textarea <https://github.com/lvgl/lv_binding_js/blob/master/doc/component/Textarea.md>`__
|
||||
- `Switch <https://github.com/lvgl/lv_binding_js/blob/master/doc/component/Switch.md>`__
|
||||
- `Checkbox <https://github.com/lvgl/lv_binding_js/blob/master/doc/component/Checkbox.md>`__
|
||||
- `Dropdownlist <https://github.com/lvgl/lv_binding_js/blob/master/doc/component/Dropdownlist.md>`__
|
||||
- `ProgressBar <https://github.com/lvgl/lv_binding_js/blob/master/doc/component/ProgressBar.md>`__
|
||||
- `Line <https://github.com/lvgl/lv_binding_js/blob/master/doc/component/Line.md>`__
|
||||
- `Roller <https://github.com/lvgl/lv_binding_js/blob/master/doc/component/Roller.md>`__
|
||||
- `Keyboard <https://github.com/lvgl/lv_binding_js/blob/master/doc/component/Keyboard.md>`__
|
||||
- `Calendar <https://github.com/lvgl/lv_binding_js/blob/master/doc/component/Calendar.md>`__
|
||||
- `Chart <https://github.com/lvgl/lv_binding_js/blob/master/doc/component/Chart.md>`__
|
||||
|
||||
Font
|
||||
----
|
||||
|
||||
`Builtin-Symbol <https://github.com/lvgl/lv_binding_js/blob/master/doc/Symbol/symbol.md>`__
|
||||
|
||||
Animation
|
||||
---------
|
||||
|
||||
`Animation <https://github.com/lvgl/lv_binding_js/blob/master/doc/animate/animate.md>`__
|
||||
|
||||
Style
|
||||
-----
|
||||
|
||||
.. include::https://github.com/lvgl/lv_binding_js/blob/master/doc/style/position-size-layout.md
|
||||
|
||||
- `position-size-layout <https://github.com/lvgl/lv_binding_js/blob/master/doc/style/position-size-layout.md>`__
|
||||
- `boxing-model <https://github.com/lvgl/lv_binding_js/blob/master/doc/style/boxing-model.md>`__
|
||||
- `color <https://github.com/lvgl/lv_binding_js/blob/master/doc/style/color.md>`__
|
||||
- `flex <https://github.com/lvgl/lv_binding_js/blob/master/doc/style/flex.md>`__
|
||||
- `grid <https://github.com/lvgl/lv_binding_js/blob/master/doc/style/grid.md>`__
|
||||
- `font <https://github.com/lvgl/lv_binding_js/blob/master/doc/style/font.md>`__
|
||||
- `opacity <https://github.com/lvgl/lv_binding_js/blob/master/doc/style/opacity.md>`__
|
||||
- `display <https://github.com/lvgl/lv_binding_js/blob/master/doc/style/display.md>`__
|
||||
- `background <https://github.com/lvgl/lv_binding_js/blob/master/doc/style/background.md>`__
|
||||
- `scroll <https://github.com/lvgl/lv_binding_js/blob/master/doc/style/scroll.md>`__
|
||||
- `shadow <https://github.com/lvgl/lv_binding_js/blob/master/doc/style/shadow.md>`__
|
||||
- `recolor <https://github.com/lvgl/lv_binding_js/blob/master/doc/style/recolor.md>`__
|
||||
- `line <https://github.com/lvgl/lv_binding_js/blob/master/doc/style/line.md>`__
|
||||
- `transition <https://github.com/lvgl/lv_binding_js/blob/master/doc/style/transition.md>`__
|
||||
- `transform <https://github.com/lvgl/lv_binding_js/blob/master/doc/style/transform.md>`__
|
||||
|
||||
JSAPI
|
||||
-----
|
||||
|
||||
- `network <https://github.com/lvgl/lv_binding_js/blob/master/doc/jsapi/network.md>`__
|
||||
- `filesystem <https://github.com/lvgl/lv_binding_js/blob/master/doc/jsapi/fs.md>`__
|
||||
- `dimension <https://github.com/lvgl/lv_binding_js/blob/master/doc/jsapi/dimension.md>`__
|
||||
|
||||
Thanks
|
||||
------
|
||||
|
||||
lvgljs depends on following excellent work
|
||||
|
||||
`lvgl <https://github.com/lvgl/lvgl>`__: Create beautiful UIs for any
|
||||
MCU, MPU and display type `QuickJS <https://bellard.org/quickjs/>`__:
|
||||
JavaScript engine `libuv <https://github.com/libuv/libuv>`__: platform
|
||||
abstraction layer `curl <https://github.com/curl/curl>`__: HTTP client
|
||||
`txiki.js <https://github.com/saghul/txiki.js>`__: Tiny JavaScript
|
||||
runtime
|
||||
294
libraries/lvgl/docs/integration/bindings/micropython.rst
Normal file
@@ -0,0 +1,294 @@
|
||||
.. _micropython:
|
||||
|
||||
===========
|
||||
MicroPython
|
||||
===========
|
||||
|
||||
What is MicroPython?
|
||||
--------------------
|
||||
|
||||
`MicroPython <http://micropython.org/>`__ is Python for
|
||||
microcontrollers. Using MicroPython, you can write Python3 code and run
|
||||
it even on a bare metal architecture with limited resources.
|
||||
|
||||
|
||||
Highlights of MicroPython
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
- **Compact**: Fits and runs within just 256k of code space and 16k of RAM. No OS is needed, although you
|
||||
can also run it with an OS, if you want.
|
||||
- **Compatible**: Strives to be as compatible as possible with normal Python (known as CPython).
|
||||
- **Versatile**: Supports many architectures (x86, x86-64, ARM, ARM Thumb, Xtensa).
|
||||
- **Interactive**: No need for the compile-flash-boot cycle. With the REPL (interactive prompt) you can type
|
||||
commands and execute them immediately, run scripts, etc.
|
||||
- **Popular**: Many platforms are supported. The user base is growing bigger. Notable forks:
|
||||
|
||||
- `MicroPython <https://github.com/micropython/micropython>`__
|
||||
- `CircuitPython <https://github.com/adafruit/circuitpython>`__
|
||||
- `MicroPython_ESP32_psRAM_LoBo <https://github.com/loboris/MicroPython_ESP32_psRAM_LoBo>`__
|
||||
|
||||
- **Embedded Oriented**: Comes with modules specifically for embedded systems, such as the
|
||||
`machine module <https://docs.micropython.org/en/latest/library/machine.html#classes>`__
|
||||
for accessing low-level hardware (I/O pins, ADC, UART, SPI, I2C, RTC, Timers etc.)
|
||||
|
||||
--------------
|
||||
|
||||
|
||||
Why MicroPython + LVGL?
|
||||
-----------------------
|
||||
|
||||
MicroPython `does not have a good native high-level GUI library <https://forum.micropython.org/viewtopic.php?f=18&t=5543>`__.
|
||||
LVGL is an `Object-Oriented Component Based <https://blog.lvgl.io/2018-12-13/extend-lvgl-objects>`__
|
||||
high-level GUI library, which seems to be a natural candidate to map into a higher level language, such as Python.
|
||||
LVGL is implemented in C and its APIs are in C.
|
||||
|
||||
|
||||
Here are some advantages of using LVGL in MicroPython:
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
- Develop GUI in Python, a very popular high level language. Use paradigms such as Object-Oriented Programming.
|
||||
- Usually, GUI development requires multiple iterations to get things right. With C, each iteration consists of
|
||||
**``Change code`` > ``Build`` > ``Flash`` > ``Run``**. In MicroPython it's just
|
||||
**``Change code`` > ``Run``** ! You can even run commands interactively using the
|
||||
`REPL <https://en.wikipedia.org/wiki/Read%E2%80%93eval%E2%80%93print_loop>`__ (the interactive prompt)
|
||||
|
||||
MicroPython + LVGL could be used for:
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
- Fast prototyping GUI.
|
||||
- Shortening the cycle of changing and fine-tuning the GUI.
|
||||
- Modelling the GUI in a more abstract way by defining reusable composite objects, taking advantage of Python's language features
|
||||
such as Inheritance, Closures, List Comprehension, Generators, Exception Handling, Arbitrary Precision Integers and others.
|
||||
- Make LVGL accessible to a larger audience. No need to know C to create a nice GUI on an embedded system. This goes well with
|
||||
`CircuitPython vision <https://learn.adafruit.com/welcome-to-circuitpython/what-is-circuitpython>`__.
|
||||
CircuitPython was designed with education in mind, to make it easier for new or inexperienced users to get started with
|
||||
embedded development.
|
||||
- Creating tools to work with LVGL at a higher level (e.g. drag-and-drop designer).
|
||||
|
||||
--------------
|
||||
|
||||
|
||||
So what does it look like?
|
||||
--------------------------
|
||||
|
||||
It's very much like the C API, but Object-Oriented for LVGL components.
|
||||
|
||||
Let's dive right into an example!
|
||||
|
||||
|
||||
A simple example
|
||||
~~~~~~~~~~~~~~~~
|
||||
|
||||
.. code:: python
|
||||
|
||||
# Initialize
|
||||
import display_driver
|
||||
import lvgl as lv
|
||||
|
||||
# Create a button with a label
|
||||
scr = lv.obj()
|
||||
btn = lv.button(scr)
|
||||
btn.align(lv.ALIGN.CENTER, 0, 0)
|
||||
label = lv.label(btn)
|
||||
label.set_text('Hello World!')
|
||||
lv.screen_load(scr)
|
||||
|
||||
|
||||
How can I use it?
|
||||
-----------------
|
||||
|
||||
Online Simulator
|
||||
~~~~~~~~~~~~~~~~
|
||||
|
||||
If you want to experiment with LVGL + MicroPython without downloading
|
||||
anything - you can use our online simulator! It's a fully functional
|
||||
LVGL + MicroPython that runs entirely in the browser and allows you to
|
||||
edit a python script and run it.
|
||||
|
||||
`Click here to experiment on the online simulator <https://sim.lvgl.io/>`__
|
||||
|
||||
Many `LVGL examples <https://docs.lvgl.io/master/examples.html>`__ are available also for MicroPython. Just click the link!
|
||||
|
||||
|
||||
PC Simulator
|
||||
~~~~~~~~~~~~
|
||||
|
||||
MicroPython is ported to many platforms. One notable port is "unix", which allows you to build and run MicroPython
|
||||
(+LVGL) on a Linux machine. (On a Windows machine you might need Virtual Box or WSL or MinGW or Cygwin etc.)
|
||||
|
||||
`Click here to know more information about building and running the unix port <https://github.com/lvgl/lv_micropython>`__
|
||||
|
||||
|
||||
Embedded Platforms
|
||||
~~~~~~~~~~~~~~~~~~
|
||||
|
||||
In the end, the goal is to run it all on an embedded platform. Both MicroPython and LVGL can be used on many embedded
|
||||
architectures. `lv_micropython <https://github.com/lvgl/lv_micropython>`__ is a fork of MicroPython+LVGL and currently
|
||||
supports Linux, ESP32, STM32 and RP2. It can be ported to any other platform supported by MicroPython.
|
||||
|
||||
- You would also need display and input drivers. You can either use one of the existing drivers provided with lv_micropython,
|
||||
or you can create your own input/display drivers for your specific hardware.
|
||||
- Drivers can be implemented either in C as a MicroPython module, or in pure Python!
|
||||
|
||||
lv_micropython already contains these drivers:
|
||||
|
||||
- Display drivers:
|
||||
|
||||
- SDL on Linux
|
||||
- X11 on Linux
|
||||
- ESP32 specific:
|
||||
|
||||
- ILI9341
|
||||
- ILI9488
|
||||
- GC9A01
|
||||
- ST7789
|
||||
- ST7735
|
||||
|
||||
- Generic (pure Python):
|
||||
|
||||
- ILI9341
|
||||
- ST7789
|
||||
- ST7735
|
||||
|
||||
- Input drivers:
|
||||
|
||||
- SDL
|
||||
- X11
|
||||
- XPT2046
|
||||
- FT6X36
|
||||
- ESP32 ADC with resistive touch
|
||||
|
||||
|
||||
Where can I find more information?
|
||||
----------------------------------
|
||||
|
||||
- ``lv_micropython`` `README <https://github.com/lvgl/lv_micropython>`__
|
||||
- ``lv_binding_micropython`` `README <https://github.com/lvgl/lv_binding_micropython>`__
|
||||
- The `LVGL micropython forum <https://forum.lvgl.io/c/micropython>`__ (Feel free to ask anything!)
|
||||
- At MicroPython: `docs <http://docs.micropython.org/en/latest/>`__ and `forum <https://forum.micropython.org/>`__
|
||||
- `Blog Post <https://blog.lvgl.io/2019-02-20/micropython-bindings>`__, a little outdated.
|
||||
|
||||
|
||||
The MicroPython Binding is auto generated!
|
||||
------------------------------------------
|
||||
|
||||
- LVGL is a git submodule inside `lv_micropython <https://github.com/lvgl/lv_micropython>`__
|
||||
(LVGL is a git submodule of `lv_binding_micropython <https://github.com/lvgl/lv_binding_micropython>`__
|
||||
which is itself a submodule of `lv_micropython <https://github.com/lvgl/lv_micropython>`__).
|
||||
- When building lv_micropython, the public LVGL C API is scanned and MicroPython API is auto-generated. That means that
|
||||
lv_micropython provides LVGL API for **any** LVGL version, and generally does not require code changes as LVGL evolves.
|
||||
|
||||
|
||||
LVGL C API Coding Conventions
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
For a summary of coding conventions to follow see the :ref:`coding-style`.
|
||||
|
||||
.. _memory_management:
|
||||
|
||||
Memory Management
|
||||
~~~~~~~~~~~~~~~~~
|
||||
|
||||
| When LVGL runs in MicroPython, all dynamic memory allocations (:cpp:func:`lv_malloc`) are handled by MicroPython's memory
|
||||
manager which is `garbage-collected <https://en.wikipedia.org/wiki/Garbage_collection_(computer_science)>`__ (GC).
|
||||
| To prevent GC from collecting memory prematurely, all dynamic allocated RAM must be reachable by GC.
|
||||
| GC is aware of most allocations, except from pointers on the `Data Segment <https://en.wikipedia.org/wiki/Data_segment>`__:
|
||||
|
||||
- Pointers which are global variables
|
||||
- Pointers which are static global variables
|
||||
- Pointers which are static local variables
|
||||
|
||||
Such pointers need to be defined in a special way to make them reachable by GC
|
||||
|
||||
|
||||
Identify The Problem
|
||||
^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Problem happens when an allocated memory's pointer (return value of :cpp:func:`lv_malloc`) is stored only in either **global**,
|
||||
**static global** or **static local** pointer variable and not as part of a previously allocated ``struct`` or other variable.
|
||||
|
||||
|
||||
Solve The Problem
|
||||
^^^^^^^^^^^^^^^^^
|
||||
|
||||
- Replace the global/static local var with :cpp:expr:`(LV_GLOBAL_DEFAULT()->_var)`
|
||||
- Include ``lv_global.h`` on files that use ``LV_GLOBAL_DEFAULT``
|
||||
- Add ``_var`` to ``lv_global_t`` on ``lv_global.h``
|
||||
|
||||
Example
|
||||
^^^^^^^
|
||||
|
||||
|
||||
More Information
|
||||
^^^^^^^^^^^^^^^^
|
||||
|
||||
- `In the README <https://github.com/lvgl/lv_binding_micropython#memory-management>`__
|
||||
- `In the Blog <https://blog.lvgl.io/2019-02-20/micropython-bindings#i-need-to-allocate-a-littlevgl-struct-such-as-style-color-etc-how-can-i-do-that-how-do-i-allocatedeallocate-memory-for-it>`__
|
||||
|
||||
.. _callbacks:
|
||||
|
||||
Callbacks
|
||||
~~~~~~~~~
|
||||
|
||||
In C a callback is just a function pointer. But in MicroPython we need to register a *MicroPython callable object* for each
|
||||
callback. Therefore in the MicroPython binding we need to register both a function pointer and a MicroPython object for every callback.
|
||||
|
||||
Therefore we defined a **callback convention** for the LVGL C API that expects lvgl headers to be defined in a certain
|
||||
way. Callbacks that are declared according to the convention would allow the binding to register a MicroPython object
|
||||
next to the function pointer when registering a callback, and access that object when the callback is called.
|
||||
|
||||
- The basic idea is that we have ``void * user_data`` field that is used automatically by the MicroPython Binding
|
||||
to save the *MicroPython callable object* for a callback. This field must be provided when registering the function
|
||||
pointer, and provided to the callback function itself.
|
||||
- Although called "user_data", the user is not expected to read/write that field. Instead, the MicroPython glue code uses
|
||||
``user_data`` to automatically keep track of the MicroPython callable object. The glue code updates it when the callback
|
||||
is registered, and uses it when the callback is called in order to invoke a call to the original callable object.
|
||||
|
||||
There are a few options for defining a callback in LVGL C API:
|
||||
|
||||
- Option 1: ``user_data`` in a struct
|
||||
|
||||
- There's a struct that contains a field called ``void * user_data``
|
||||
|
||||
- A pointer to that struct is provided as the **first** argument of a callback registration function
|
||||
- A pointer to that struct is provided as the **first** argument of the callback itself
|
||||
|
||||
- Option 2: ``user_data`` as a function argument
|
||||
|
||||
- A parameter called ``void * user_data`` is provided to the registration function as the **last** argument
|
||||
|
||||
- The callback itself receives ``void *`` as the **last** argument
|
||||
|
||||
- Option 3: both callback and ``user_data`` are struct fields
|
||||
|
||||
- The API exposes a struct with both function pointer member and ``user_data`` member
|
||||
|
||||
- The function pointer member receives the same struct as its **first** argument
|
||||
|
||||
In practice it's also possible to mix these options, for example provide a struct pointer when registering a callback
|
||||
(option 1) and provide ``user_data`` argument when calling the callback (options 2),
|
||||
**as long as the same ``user_data`` that was registered is passed to the callback when it's called**.
|
||||
|
||||
Examples
|
||||
^^^^^^^^
|
||||
|
||||
- :cpp:type:`lv_anim_t` contains ``user_data`` field. :cpp:func:`lv_anim_set_path_cb`
|
||||
registers `path_cb` callback. Both ``lv_anim_set_path_cb`` and :cpp:type:`lv_anim_path_cb_t`
|
||||
receive :cpp:type:`lv_anim_t` as their first argument
|
||||
- ``path_cb`` field can also be assigned directly in the Python code because it's a member
|
||||
of :cpp:type:`lv_anim_t` which contains ``user_data`` field, and :cpp:type:`lv_anim_path_cb_t`
|
||||
receive :cpp:type:`lv_anim_t` as its first argument.
|
||||
- :cpp:func:`lv_imgfont_create` registers ``path_cb`` and receives ``user_data`` as the last
|
||||
argument. The callback :cpp:type:`lv_imgfont_get_path_cb_t` also receives the ``user_data`` as the last argument.
|
||||
|
||||
.. _more-information-1:
|
||||
|
||||
More Information
|
||||
^^^^^^^^^^^^^^^^
|
||||
|
||||
- In the `Blog <https://blog.lvgl.io/2019-08-05/micropython-pure-display-driver#using-callbacks>`__
|
||||
and in the `README <https://github.com/lvgl/lv_binding_micropython#callbacks>`__
|
||||
- `[v6.0] Callback conventions #1036 <https://github.com/lvgl/lvgl/issues/1036>`__
|
||||
- Various discussions: `here <https://github.com/lvgl/lvgl/pull/3294#issuecomment-1184895335>`__
|
||||
and `here <https://github.com/lvgl/lvgl/issues/1763#issuecomment-762247629>`__
|
||||
and`here <https://github.com/lvgl/lvgl/issues/316#issuecomment-467221587>`__
|
||||
203
libraries/lvgl/docs/integration/bindings/pikascript.rst
Normal file
@@ -0,0 +1,203 @@
|
||||
PikaScript
|
||||
==========
|
||||
|
||||
What is PikaScript ?
|
||||
--------------------
|
||||
|
||||
`PikaScript <https://github.com/pikasTech/pikascript>`__ is a Python
|
||||
interpreter designed specifically for microcontrollers, and it supports
|
||||
a subset of the common Python3 syntax.
|
||||
|
||||
It's lighter, requiring only 32k of code space and 4k of RAM, which
|
||||
means it can run on stm32f103c8 (blue-pill) or even stm32g030c8, on the
|
||||
other hand, you can leave valuable space for more material or larger
|
||||
buffer areas.
|
||||
|
||||
It is simpler, out of the box, runs with no porting and configuration at
|
||||
all, does not depend on OS or file system, has good support for popular
|
||||
IDEs for Windows platforms like Keil, IAR, RT-Thread-Studio, and of
|
||||
course, supports linux-gcc development platforms.
|
||||
|
||||
It's smarter, with a unique C module mechanism that allows you to
|
||||
generate bindings automatically by simply writing the API for the C
|
||||
module in Python, and you don't need to deal with the headache of
|
||||
writing any macros or global tables manually. On the other hand, all C
|
||||
modules have sophisticated smart hints, even hinting at the types of
|
||||
your arguments .
|
||||
|
||||
--------------
|
||||
|
||||
|
||||
Why PikaScript + LVGL ?
|
||||
-----------------------
|
||||
|
||||
PikaScript now supports the main features of LVGL8, and these APIs are
|
||||
fully compatible with MicroPython!
|
||||
|
||||
This means that you can continue to use already written code from
|
||||
MicroPython, and then use less code space and RAM.
|
||||
|
||||
Enjoy detailed code hints down to the parameter type for a better
|
||||
programming experience
|
||||
|
||||
Use a more convenient IDE, such as vs-based simulation projects
|
||||
|
||||
|
||||
So how does it look like?
|
||||
-------------------------
|
||||
|
||||
Here are some examples of lvgl that PikaScript can already run, they are
|
||||
mainly from the lvgl documentation examples
|
||||
|
||||
|
||||
LV_ARC
|
||||
~~~~~~
|
||||
|
||||
.. code:: python
|
||||
|
||||
import pika_lvgl as lv
|
||||
import PikaStdLib
|
||||
mem = PikaStdLib.MemChecker()
|
||||
# Create an Arc
|
||||
arc = lv.arc(lv.screen_active())
|
||||
arc.set_end_angle(200)
|
||||
arc.set_size(150, 150)
|
||||
arc.center()
|
||||
print('mem used max: %0.2f kB' % (mem.getMax()))
|
||||
print('mem used now: %0.2f kB' % (mem.getNow()))
|
||||
|
||||
|
||||
LV_BAR
|
||||
~~~~~~
|
||||
|
||||
.. code:: python
|
||||
|
||||
import pika_lvgl as lv
|
||||
import PikaStdLib
|
||||
mem = PikaStdLib.MemChecker()
|
||||
bar1 = lv.bar(lv.screen_active())
|
||||
bar1.set_size(200, 20)
|
||||
bar1.center()
|
||||
bar1.set_value(70, lv.ANIM.OFF)
|
||||
print('mem used max: %0.2f kB' % (mem.getMax()))
|
||||
print('mem used now: %0.2f kB' % (mem.getNow()))
|
||||
|
||||
|
||||
LV_BTN
|
||||
~~~~~~
|
||||
|
||||
.. code:: python
|
||||
|
||||
import pika_lvgl as lv
|
||||
import PikaStdLib
|
||||
mem = PikaStdLib.MemChecker()
|
||||
def event_cb_1(evt):
|
||||
print('in evt1')
|
||||
print('mem used now: %0.2f kB' % (mem.getNow()))
|
||||
def event_cb_2(evt):
|
||||
print('in evt2')
|
||||
print('mem used now: %0.2f kB' % (mem.getNow()))
|
||||
btn1 = lv.btn(lv.screen_active())
|
||||
btn1.align(lv.ALIGN.TOP_MID, 0, 10)
|
||||
btn2 = lv.btn(lv.screen_active())
|
||||
btn2.align(lv.ALIGN.TOP_MID, 0, 50)
|
||||
btn1.add_event_cb(event_cb_1, lv.EVENT.CLICKED, 0)
|
||||
btn2.add_event_cb(event_cb_2, lv.EVENT.CLICKED, 0)
|
||||
print('mem used max: %0.2f kB' % (mem.getMax()))
|
||||
print('mem used now: %0.2f kB' % (mem.getNow()))
|
||||
|
||||
|
||||
LV_CHECKBOX
|
||||
~~~~~~~~~~~
|
||||
|
||||
.. code:: python
|
||||
|
||||
import pika_lvgl as lv
|
||||
import PikaStdLib
|
||||
mem = PikaStdLib.MemChecker()
|
||||
cb = lv.checkbox(lv.screen_active())
|
||||
cb.set_text("Apple")
|
||||
cb.align(lv.ALIGN.TOP_LEFT, 0 ,0)
|
||||
cb = lv.checkbox(lv.screen_active())
|
||||
cb.set_text("Banana")
|
||||
cb.add_state(lv.STATE.CHECKED)
|
||||
cb.align(lv.ALIGN.TOP_LEFT, 0 ,30)
|
||||
cb = lv.checkbox(lv.screen_active())
|
||||
cb.set_text("Lemon")
|
||||
cb.add_state(lv.STATE.DISABLED)
|
||||
cb.align(lv.ALIGN.TOP_LEFT, 0 ,60)
|
||||
cb = lv.checkbox(lv.screen_active())
|
||||
cb.add_state(lv.STATE.CHECKED | lv.STATE.DISABLED)
|
||||
cb.set_text("Melon")
|
||||
cb.align(lv.ALIGN.TOP_LEFT, 0 ,90)
|
||||
print('mem used max: %0.2f kB' % (mem.getMax()))
|
||||
print('mem used now: %0.2f kB' % (mem.getNow()))
|
||||
|
||||
--------------
|
||||
|
||||
|
||||
How does it work?
|
||||
-----------------
|
||||
|
||||
PikaScript has a unique C module smart binding tool
|
||||
|
||||
Just write the Python interface in pika_lvgl.pyi (.pyi is the python
|
||||
interface file)
|
||||
|
||||
.. code:: python
|
||||
|
||||
# pika_lvgl.pyi
|
||||
class arc(lv_obj):
|
||||
def set_end_angle(self, angle: int): ...
|
||||
def set_bg_angles(self, start: int, end: int): ...
|
||||
def set_angles(self, start: int, end: int): ...
|
||||
|
||||
Then PikaScript's pre-compiler can automatically bind the following C
|
||||
functions, simply by naming the functions in the module_class_method
|
||||
format, without any additional work, and all binding and registration is
|
||||
done automatically.
|
||||
|
||||
.. code:: c
|
||||
|
||||
/* pika_lvgl_arc.c */
|
||||
void pika_lvgl_arc_set_end_angle(PikaObj* self, int angle) {
|
||||
lv_obj_t* lv_obj = obj_getPtr(self, "lv_obj");
|
||||
lv_arc_set_end_angle(lv_obj, angle);
|
||||
}
|
||||
void pika_lvgl_arc_set_bg_angles(PikaObj *self, int start, int end){
|
||||
lv_obj_t* lv_obj = obj_getPtr(self, "lv_obj");
|
||||
lv_arc_set_bg_angles(lv_obj, start, end);
|
||||
}
|
||||
void pika_lvgl_arc_set_angles(PikaObj *self, int start, int end){
|
||||
lv_obj_t* lv_obj = obj_getPtr(self, "lv_obj");
|
||||
lv_arc_set_angles(lv_obj, start, end);
|
||||
}
|
||||
|
||||
To use the module, just ``import pika_lvgl`` and the precompiler will
|
||||
automatically scan main.py and bind the ``pika_lvgl`` module
|
||||
|
||||
::
|
||||
|
||||
$ ./rust-msc-latest-win10.exe
|
||||
(pikascript) packages installed:
|
||||
pikascript-core==v1.10.0
|
||||
PikaStdLib==v1.10.0
|
||||
PikaStdDevice==v1.10.0
|
||||
(pikascript) pika compiler:
|
||||
scanning main.py...
|
||||
binding pika_lvgl.pyi...
|
||||
|
||||
The precompiler is written in Rust, runs on windows and linux, and is
|
||||
completely open source.
|
||||
|
||||
In addition to binding C modules, the precompiler compiles Python
|
||||
scripts to bytecode in the PC, reducing the size of the script and
|
||||
increasing its speed.
|
||||
|
||||
--------------
|
||||
|
||||
How can I use it?
|
||||
-----------------
|
||||
|
||||
The simulation repo on vs is available on
|
||||
https://github.com/pikasTech/lv_pikascript
|
||||
71
libraries/lvgl/docs/integration/building/cmake.rst
Normal file
@@ -0,0 +1,71 @@
|
||||
.. _build_cmake:
|
||||
|
||||
=====
|
||||
cmake
|
||||
=====
|
||||
|
||||
Overview
|
||||
********
|
||||
This project uses CMakePresets to ensure an easy build. Find out more on Cmake Presets here:
|
||||
https://cmake.org/cmake/help/latest/manual/cmake-presets.7.html
|
||||
|
||||
Prerequisites
|
||||
-------------
|
||||
You need to install
|
||||
|
||||
- CMake
|
||||
- Ninja (for Linux builds). Be sure to Add ninja to your PATH!
|
||||
|
||||
How to build this project using cmake
|
||||
-------------------------------------
|
||||
|
||||
The recommended way to build this project is to use the provided CMakePresets.json. This file contains 2 configurations
|
||||
|
||||
- a windows (msvc) build using Visual Studio
|
||||
- a linux (gcc) build using Ninja
|
||||
|
||||
More configurations will be added once available.
|
||||
|
||||
Build with IDE
|
||||
--------------
|
||||
|
||||
The recommend way for consuming CMakePresets is a CMakePresets aware IDE such as
|
||||
|
||||
- VS 2022
|
||||
- VS Code
|
||||
- CLion
|
||||
|
||||
Simply load this project into your IDE and select your desired preset and you are good to go.
|
||||
|
||||
|
||||
Build with CMake GUI
|
||||
--------------------
|
||||
Open this project with CMake GUI and select your desired preset.
|
||||
When hitting the generate button, CMake will create solution files (for VS) or Ninja Files (for Linux Ninja Build)
|
||||
|
||||
The following targets are available.
|
||||
|
||||
- lvgl (the actual library, required)
|
||||
- lvgl_thorvg (an vector graphics extension, optional)
|
||||
- lvgl_examples (example usages, optional)
|
||||
- lvgl_demos (some demos, optional)
|
||||
|
||||
All optional targets can be disabled by setting the proper cache variables.
|
||||
If you use cmake to install lvgl 3 folders will be created.
|
||||
|
||||
- include/lvgl (contains all public headers)
|
||||
- bin (contains all binaries (\*.dll))
|
||||
- lib (contains all precompiled source files (\*.lib))
|
||||
|
||||
|
||||
Build with Command line
|
||||
-----------------------
|
||||
|
||||
You can also build your project using the command line.
|
||||
Run the following commands
|
||||
|
||||
- cmake --preset windows-base
|
||||
- cmake --build --preset windows-base_dbg
|
||||
- ctest --preset windows-base_dbg
|
||||
|
||||
|
||||
10
libraries/lvgl/docs/integration/building/index.rst
Normal file
@@ -0,0 +1,10 @@
|
||||
=============
|
||||
Build systems
|
||||
=============
|
||||
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 2
|
||||
|
||||
make
|
||||
cmake
|
||||
7
libraries/lvgl/docs/integration/building/make.rst
Normal file
@@ -0,0 +1,7 @@
|
||||
.. _build_make:
|
||||
|
||||
====
|
||||
make
|
||||
====
|
||||
|
||||
LVGL can be easily integrated into any Makefile project by adding ``include lvgl/lvgl.mk`` to the main ``Makefile``.
|
||||
57
libraries/lvgl/docs/integration/chip/arm.rst
Normal file
@@ -0,0 +1,57 @@
|
||||
.. _arm:
|
||||
|
||||
===
|
||||
Arm
|
||||
===
|
||||
|
||||
Arm is a leading semiconductor and software design company, renowned for creating the Cortex-M microcontroller (MCU) cores and Cortex-A/R (MPU) processor cores, which are integral to a wide range of devices. These cores are at the heart of many embedded systems, powering chips from industry giants such as STMicroelectronics, NXP, and Renesas. Arm's energy-efficient designs are used in billions of devices worldwide, from microcontrollers to smartphones and servers. By licensing their processor designs, Arm enables a broad ecosystem of partners to develop customized solutions optimized for performance, power, and size. Arm's architecture is highly compatible with various operating systems and software libraries, including LVGL, making it a versatile choice for developers creating efficient, high-performance graphical user interfaces.
|
||||
|
||||
Compile LVGL for Arm
|
||||
--------------------
|
||||
|
||||
No specific action is required. Any compiler that supports the target Arm architecture can be used to compile LVGL's source code, including GCC, LLVM, and AC6.
|
||||
|
||||
It is also possible to cross-compile LVGL for an MPU (instead of compiling it on the target hardware) or create a shared library. For more information, check out :ref:`build_cmake`.
|
||||
|
||||
Getting Started with AC6
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Since AC6 is a proprietary toolchain, it contains many specific optimizations, so you can expect the best performance when using it.
|
||||
|
||||
AC6 is not free, but it offers a community license that can be activated as follows:
|
||||
|
||||
1. Download and install the AC6 compiler from `Arm's website <https://developer.arm.com/Tools%20and%20Software/Arm%20Compiler%20for%20Embedded>`__.
|
||||
2. To register a community license, go to the ``bin`` folder of the compiler and, in a terminal, run ``armlm.exe activate -server https://mdk-preview.keil.arm.com -product KEMDK-COM0`` (On Linux, use ``./armlm``).
|
||||
|
||||
IDE Support
|
||||
-----------
|
||||
|
||||
There are no limitations on the supported IDEs. LVGL works in various vendors' IDEs, including Arm's Keil MDK, IAR, Renesas's e2 studio, NXP's MCUXpresso, ST's CubeIDE, as well as custom make or CMake projects.
|
||||
|
||||
Arm2D and the Helium instruction set
|
||||
------------------------------------
|
||||
|
||||
Arm Cortex-M55 and Cortex-M85 have the `SIMD Helium <https://www.arm.com/technologies/helium>`__ instruction set.
|
||||
Among many others, this can effectively speed up UI rendering. :ref:`Arm2D <arm2d>` is a library maintained by Arm that leverages the Helium instruction set.
|
||||
|
||||
Note that GCC has some known issues with Helium intrinsics. It is recommended to use AC6 or LLVM when dealing with Helium code.
|
||||
|
||||
|
||||
To add Arm2D to your project, follow these steps:
|
||||
|
||||
1. To utilize its power, ensure that ``mcpu`` is set to ``cortex-m85``, ``cortex-m55``, or ``cortex-m52`` and add the ``-fvectorize`` flag. To test without SIMD, use e.g. ``cortex-m85+nomve``.
|
||||
2. Arm2D can be downloaded from `https://github.com/ARM-software/Arm-2D <https://github.com/ARM-software/Arm-2D>`__. Consider using the ``developing`` branch, which contains the latest updates.
|
||||
3. Add ``Arm-2D/Library/Include`` to the include paths.
|
||||
4. Copy ``Arm-2D/Library/Include/template/arm_2d_cfg.h`` to any location you prefer to provide the default configuration for Arm2D. Ensure that the folder containing ``arm_2d_cfg.h`` is added to the include path.
|
||||
5. The Arm2D repository contains several examples and templates; however, ensure that only ``Arm-2D/Library/Source`` is compiled.
|
||||
6. The CMSIS DSP library also needs to be added to the project. You can use CMSIS-PACKS or add it manually.
|
||||
7. For better performance, enable ``LTO`` (Link Time Optimization) and use ``-Omax`` or ``-Ofast``.
|
||||
8. Arm2D tries to read/write multiple data with a single instruction. Therefore, it's important to use the fastest memory (e.g., ``BSS`` or ``TCM``) for LVGL's buffer to avoid memory bandwidth bottlenecks.
|
||||
9. Enable ``LV_USE_DRAW_ARM2D_SYNC 1`` in ``lv_conf.h``.
|
||||
|
||||
Neon Acceleration
|
||||
-----------------
|
||||
|
||||
Several Cortex-A microprocessors support the `Neon SIMD <https://www.arm.com/technologies/neon>`__ instruction set. LVGL has built-in support to improve the performance of software rendering by utilizing Neon instructions. To enable Neon acceleration, set ``LV_USE_DRAW_SW_ASM`` to ``LV_DRAW_SW_ASM_NEON`` in ``lv_conf.h``.
|
||||
|
||||
|
||||
197
libraries/lvgl/docs/integration/chip/espressif.rst
Normal file
@@ -0,0 +1,197 @@
|
||||
=============================
|
||||
Espressif (ESP32 Chip Series)
|
||||
=============================
|
||||
|
||||
LVGL can be used and configured as standard `ESP-IDF <https://github.com/espressif/esp-idf>`__ component.
|
||||
|
||||
If you are new to ESP-IDF, follow the instructions in the `ESP-IDF Programming guide <https://docs.espressif.com/projects/esp-idf/en/stable/esp32/get-started/index.html>`__ to install and set up ESP-IDF on your machine.
|
||||
|
||||
|
||||
LVGL Demo Projects for ESP32
|
||||
---------------------------
|
||||
|
||||
For a quick start with LVGL and ESP32, the following pre-configured demo projects are available for specific development boards:
|
||||
|
||||
- `ESP-BOX-3 <https://github.com/lvgl/lv_port_espressif_esp-box-3>`__
|
||||
- `ESP32-S3-LCD-EV-BOARD <https://github.com/lvgl/lv_port_espressif_esp32-s3-lcd-ev-board>`__
|
||||
- `M5Stack-CoreS3 <https://github.com/lvgl/lv_port_espressif_M5Stack_CoreS3>`__
|
||||
|
||||
Refer to the README.md files in these repositories for build and flash instructions.
|
||||
|
||||
These demo projects use Espressif's Board Support Packages (BSPs). Additional BSPs and examples are available in the `esp-bsp <https://github.com/espressif/esp-bsp>`__ repository.
|
||||
|
||||
|
||||
Using LVGL in Your ESP-IDF Project
|
||||
----------------------------------
|
||||
|
||||
The simplest way to integrate LVGL into your ESP-IDF project is via the `esp_lvgl_port <https://components.espressif.com/components/espressif/esp_lvgl_port>`__ component. This component, used in the demo projects mentioned above, provides helper functions for easy installation of LVGL and display drivers. Moreover, it can add support for touch, rotary encoders, button or USB HID inputs. It simplifies power savings, screen rotation and other platform specific nuances.
|
||||
|
||||
The esp_lvgl_port supports LVGL versions 8 and 9 and is compatible with ESP-IDF v4.4 and above. To add it to your project, use the following command:
|
||||
|
||||
.. code:: sh
|
||||
|
||||
idf.py add-dependency "espressif/esp_lvgl_port^2.3.0"
|
||||
|
||||
By default, esp_lvgl_port depends on the latest stable version of LVGL, so no additional steps are needed for new projects. If a specific LVGL version is required, specify this in your project to avoid automatic updates. LVGL can also be used without esp_lvgl_port, as described below.
|
||||
|
||||
Obtaining LVGL
|
||||
~~~~~~~~~~~~~~
|
||||
|
||||
LVGL is distributed through `ESP Registry <https://components.espressif.com/>`__, where all LVGL releases are uploaded.
|
||||
In case you do not want to use esp_lvgl_port, you can add `LVGL component <https://components.espressif.com/component/lvgl/lvgl>`__ into your project with following command:
|
||||
|
||||
.. code:: sh
|
||||
|
||||
idf.py add-dependency lvgl/lvgl^9.*
|
||||
|
||||
Adjust the ``^9.*`` part to match your LVGL version requirement. More information on version specifications can be found in the `IDF Component Manager documentation <https://docs.espressif.com/projects/idf-component-manager/en/latest/reference/versioning.html#range-specifications>`__. During the next build, the LVGL component will be fetched from the component registry and added to the project.
|
||||
|
||||
**Advanced usage: Use LVGL as local component**
|
||||
|
||||
For LVGL development and testing, it may be useful to use LVGL as a local component instead of from the ESP Registry, which offers only released versions and does not allow local modifications. To do this, clone LVGL to your project with the following command:
|
||||
|
||||
.. code:: sh
|
||||
|
||||
git submodule add https://github.com/lvgl/lvgl.git components/lvgl
|
||||
|
||||
.. note::
|
||||
|
||||
All components from ``${project_dir}/components`` are automatically added to build.
|
||||
|
||||
Configuration
|
||||
~~~~~~~~~~~~~
|
||||
|
||||
To configure LVGL, launch the configuration menu with ``idf.py menuconfig`` in your project root directory. Navigate to ``Component config`` and then ``LVGL configuration``.
|
||||
|
||||
|
||||
Support for Display and Touch Drivers
|
||||
-------------------------------------
|
||||
|
||||
For successful LVGL project you will need a display driver and optionally a touch driver. Espressif provides these drivers that are built on its `esp_lcd <https://docs.espressif.com/projects/esp-idf/en/stable/esp32/api-reference/peripherals/lcd/index.html>`__ component.
|
||||
|
||||
- esp_lcd natively supports for some `basic displays <https://github.com/espressif/esp-idf/tree/master/components/esp_lcd/src>`__
|
||||
- Other displays are maintained in `esp-bsp repository <https://github.com/espressif/esp-bsp/tree/master/components/lcd>`__ and are uploaded to ESP Registry
|
||||
- Touch drivers are maintained in `esp-bsp repository <https://github.com/espressif/esp-bsp/tree/master/components/lcd_touch>`__ and are uploaded to ESP Registry
|
||||
|
||||
These components share a common public API, making it easy to migrate your projects across different display and touch drivers.
|
||||
|
||||
To add a display or touch driver to your project, use a command like:
|
||||
|
||||
.. code:: sh
|
||||
idf.py add-dependency "espressif/esp_lcd_gc9a01^2.0.0"
|
||||
|
||||
Using the File System under ESP-IDF
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
ESP-IDF uses the standard C functions (``fopen``, ``fread``) in all storage related APIs.
|
||||
This allows seamless interoperability with LVGL when enabling the :c:macro:`LV_USE_FS_STDIO` configuration.
|
||||
The process is described in details below, using ``SPIFFS`` as demonstration.
|
||||
|
||||
- **Decide what storage system you want to use**
|
||||
|
||||
ESP-IDF has many, ready-to-use examples like
|
||||
`SPIFFS <https://github.com/espressif/esp-idf/tree/master/examples/storage/spiffsgen>`__
|
||||
,
|
||||
`SD Card <https://github.com/espressif/esp-idf/tree/master/examples/storage/sd_card/sdspi>`__
|
||||
and
|
||||
`LittleFS <https://github.com/espressif/esp-idf/tree/master/examples/storage/littlefs>`__
|
||||
.
|
||||
|
||||
- **Re-configure your own project**
|
||||
|
||||
The example project should be examined for details, but in general the changes involve:
|
||||
|
||||
- Enabling LVGL's STDIO file system in the configuration
|
||||
|
||||
You can use ``menuconfig``:
|
||||
|
||||
- ``Component config → LVGL configuration → 3rd Party Libraries``: enable ``File system on top of stdio API``
|
||||
- Then select ``Set an upper cased letter on which the drive will accessible`` and set it to ``65`` (ASCII **A**)
|
||||
- You can also set ``Default driver letter`` to 65 to skip the prefix in file paths.
|
||||
|
||||
- Modifying the partition table
|
||||
|
||||
The exact configuration depends on your flash size and existing partitions,
|
||||
but the new final result should look something like this:
|
||||
|
||||
.. code:: csv
|
||||
|
||||
nvs, data, nvs, 0x9000, 0x6000,
|
||||
phy_init, data, phy, 0xf000, 0x1000,
|
||||
factory, app, factory, 0x10000, 1400k,
|
||||
storage, data, spiffs, , 400k,
|
||||
|
||||
|
||||
.. note::
|
||||
|
||||
If you are not using a custom ``parition.csv`` yet, it can be added
|
||||
via ``menuconfig`` (``Partition Table → Partition Table → Custom partition table CSV``).
|
||||
|
||||
- Apply changes to the build system
|
||||
|
||||
Some ESP file systems provide automatic generation from a host folder using CMake. The proper line(s) must be copied to ``main/CMakeLists.txt``
|
||||
|
||||
.. note::
|
||||
|
||||
``LittleFS`` has extra dependencies that should be added to ``main/idf_component.yml``
|
||||
|
||||
- **Prepare the image files**
|
||||
|
||||
LVGL's ``LVGLImage.py`` Python tool can be used to convert images to binary pixel map files.
|
||||
It supports various formats and compression.
|
||||
|
||||
Meanwhile 3rd party libraries
|
||||
(like :ref:`LodePNG<lodepng>` and :ref:`Tiny JPEG<tjpgd>`)
|
||||
allow using image files without conversion.
|
||||
|
||||
After preparing the files, they should be moved to the target device:
|
||||
|
||||
- If properly activated a **SPIFFS** file system based on the ``spiffs_image`` folder should be automatically generated and later flashed to the target
|
||||
- Similar mechanism for **LittleFS** uses the ``flash_data`` folder, but it's only available for Linux hosts
|
||||
- For the **SD Card**, a traditional file browser can be used
|
||||
|
||||
- **Invoke proper API calls in the application code**
|
||||
|
||||
The core functionality requires only a few lines. The following example draws the image as well.
|
||||
|
||||
.. code:: c
|
||||
|
||||
#include "esp_spiffs.h"
|
||||
|
||||
void lv_example_image_from_esp_fs(void) {
|
||||
|
||||
esp_vfs_spiffs_conf_t conf = {
|
||||
.base_path = "/spiffs",
|
||||
.partition_label = NULL,
|
||||
.max_files = 5,
|
||||
.format_if_mount_failed = false
|
||||
};
|
||||
|
||||
esp_err_t ret = esp_vfs_spiffs_register(&conf);
|
||||
|
||||
if (ret != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Failed to register SPIFF filesystem");
|
||||
return;
|
||||
}
|
||||
|
||||
lv_obj_t * obj = lv_image_create(lv_screen_active());
|
||||
lv_image_set_src(obj, "A:/spiffs/logo.bin");
|
||||
lv_obj_center(obj);
|
||||
}
|
||||
|
||||
- **Build and flash**
|
||||
|
||||
After calling ``idf.py build flash`` the picture should be displayed on the screen.
|
||||
|
||||
|
||||
.. note::
|
||||
|
||||
Changes made by ``menuconfig`` are not being tracked in the repository if the ``sdkconfig`` file is added to ``.gitignore``, which is the default for many ESP-IDF projects.
|
||||
To make your configuration permanent, add the following lines to ``sdkconfig.defaults``:
|
||||
|
||||
.. code:: c
|
||||
|
||||
CONFIG_PARTITION_TABLE_CUSTOM=y
|
||||
CONFIG_LV_USE_FS_STDIO=y
|
||||
CONFIG_LV_FS_STDIO_LETTER=65
|
||||
CONFIG_LV_LV_FS_DEFAULT_DRIVE_LETTER=65
|
||||
11
libraries/lvgl/docs/integration/chip/index.rst
Normal file
@@ -0,0 +1,11 @@
|
||||
============
|
||||
Chip vendors
|
||||
============
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 2
|
||||
|
||||
espressif
|
||||
nxp
|
||||
renesas
|
||||
stm32
|
||||
400
libraries/lvgl/docs/integration/chip/nxp.rst
Normal file
@@ -0,0 +1,400 @@
|
||||
===
|
||||
NXP
|
||||
===
|
||||
|
||||
NXP has integrated LVGL into the MCUXpresso SDK packages for several of our
|
||||
microcontrollers as an optional software component, allowing easy evaluation and
|
||||
migration into your product design. LVGL is a free and open-source embedded
|
||||
graphic library with features that enable you need to create embedded GUIs with
|
||||
intuitive graphical elements, beautiful visual effects and a low memory
|
||||
footprint. The complete graphic framework includes a variety of widgets for you
|
||||
to use in the creation of your GUI, and supports more advanced functions such as
|
||||
animations and anti-aliasing.
|
||||
|
||||
LVGL enables graphics in our free GUI Guider UI tool. It's available for use
|
||||
with NXP’s general purpose and crossover microcontrollers, providing developers
|
||||
with a tool for creating complete, high quality GUI applications with LVGL.
|
||||
|
||||
Creating new project with LVGL
|
||||
------------------------------
|
||||
|
||||
`Download an SDK for a supported board <https://www.nxp.com/design/software/embedded-software/littlevgl-open-source-graphics-library:LITTLEVGL-OPEN-SOURCE-GRAPHICS-LIBRARY?&tid=vanLITTLEVGL-OPEN-SOURCE-GRAPHICS-LIBRARY>`__
|
||||
today and get started with your next GUI application. It comes fully configured
|
||||
with LVGL (and with PXP/VGLite support if the modules are present), no
|
||||
additional integration work is required.
|
||||
|
||||
HW acceleration for NXP iMX RT platforms
|
||||
----------------------------------------
|
||||
|
||||
Depending on the RT platform used, the acceleration can be done by NXP PXP
|
||||
(PiXel Pipeline) and/or the Verisilicon GPU through an API named VGLite. Each
|
||||
accelerator has its own context that allows them to be used individually as well
|
||||
simultaneously (in LVGL multithreading mode).
|
||||
|
||||
PXP accelerator
|
||||
~~~~~~~~~~~~~~~
|
||||
Basic configuration:
|
||||
^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
- Select NXP PXP engine in "lv_conf.h": Set :c:macro:`LV_USE_PXP` to `1`.
|
||||
- In order to use PXP as a draw unit, select in "lv_conf.h": Set :c:macro:`LV_USE_DRAW_PXP` to `1`.
|
||||
- In order to use PXP to rotate the screen, select in "lv_conf.h": Set :c:macro:`LV_USE_ROTATE_PXP` to `1`.
|
||||
- Enable PXP asserts in "lv_conf.h": Set :c:macro: `LV_USE_PXP_ASSERT` to `1`.
|
||||
There are few PXP assertions that can stop the program execution in case the
|
||||
c:macro: `LV_ASSERT_HANDLER` is set to `while(1);` (Halt by default). Else,
|
||||
there will be logged just an error message via `LV_LOG_ERROR`.
|
||||
- If :c:macro:`SDK_OS_FREE_RTOS` symbol is defined, FreeRTOS implementation
|
||||
will be used, otherwise bare metal code will be included.
|
||||
|
||||
Basic initialization:
|
||||
^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
PXP draw initialization is done automatically in :cpp:func:`lv_init()` once the
|
||||
PXP is enabled as a draw unit or to rotate the screen, no user code is required:
|
||||
|
||||
.. code:: c
|
||||
|
||||
#if LV_USE_DRAW_PXP || LV_USE_ROTATE_PXP
|
||||
lv_draw_pxp_init();
|
||||
#endif
|
||||
|
||||
During PXP initialization, a new draw unit `lv_draw_pxp_unit_t` will be created
|
||||
with the additional callbacks, if :c:macro:`LV_USE_DRAW_PXP` is set to `1`:
|
||||
|
||||
.. code:: c
|
||||
|
||||
lv_draw_pxp_unit_t * draw_pxp_unit = lv_draw_create_unit(sizeof(lv_draw_pxp_unit_t));
|
||||
draw_pxp_unit->base_unit.evaluate_cb = _pxp_evaluate;
|
||||
draw_pxp_unit->base_unit.dispatch_cb = _pxp_dispatch;
|
||||
draw_pxp_unit->base_unit.delete_cb = _pxp_delete;
|
||||
|
||||
and an addition thread `_pxp_render_thread_cb()` will be spawned in order to
|
||||
handle the supported draw tasks.
|
||||
|
||||
.. code:: c
|
||||
|
||||
#if LV_USE_PXP_DRAW_THREAD
|
||||
lv_thread_init(&draw_pxp_unit->thread, LV_THREAD_PRIO_HIGH, _pxp_render_thread_cb, 2 * 1024, draw_pxp_unit);
|
||||
#endif
|
||||
|
||||
If `LV_USE_PXP_DRAW_THREAD` is not defined, then no additional draw thread will be created
|
||||
and the PXP drawing task will get executed on the same LVGL main thread.
|
||||
|
||||
`_pxp_evaluate()` will get called after each task is being created and will
|
||||
analyze if the task is supported by PXP or not. If it is supported, then an
|
||||
preferred score and the draw unit id will be set to the task. An `score` equal
|
||||
to `100` is the default CPU score. Smaller score means that PXP is capable of
|
||||
drawing it faster.
|
||||
|
||||
`_pxp_dispatch()` is the PXP dispatcher callback, it will take a ready to draw
|
||||
task (having the `DRAW_UNIT_ID_PXP` set) and will pass the task to the PXP draw
|
||||
unit for processing.
|
||||
|
||||
`_pxp_delete()` will cleanup the PXP draw unit.
|
||||
|
||||
Features supported:
|
||||
^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Several drawing features in LVGL can be offloaded to the PXP engine. The CPU is
|
||||
available for other operations while the PXP is running. RTOS is required to
|
||||
block the LVGL drawing thread and switch to another task or suspend the CPU for
|
||||
power savings.
|
||||
|
||||
Supported draw tasks are available in "src/draw/nxp/pxp/lv_draw_pxp.c":
|
||||
|
||||
.. code:: c
|
||||
|
||||
switch(t->type) {
|
||||
case LV_DRAW_TASK_TYPE_FILL:
|
||||
lv_draw_pxp_fill(draw_unit, t->draw_dsc, &t->area);
|
||||
break;
|
||||
case LV_DRAW_TASK_TYPE_IMAGE:
|
||||
lv_draw_pxp_img(draw_unit, t->draw_dsc, &t->area);
|
||||
break;
|
||||
case LV_DRAW_TASK_TYPE_LAYER:
|
||||
lv_draw_pxp_layer(draw_unit, t->draw_dsc, &t->area);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
Additional, the screen rotation can be handled by the PXP:
|
||||
|
||||
.. code::c
|
||||
|
||||
void lv_draw_pxp_rotate(const void * src_buf, void * dest_buf, int32_t src_width, int32_t src_height,
|
||||
int32_t src_stride, int32_t dest_stride, lv_display_rotation_t rotation,
|
||||
lv_color_format_t cf);
|
||||
|
||||
- Fill area with color (w/o radius, w/o gradient) + optional opacity.
|
||||
- Blit source image RGB565/ARGB888/XRGB8888 over destination.
|
||||
RGB565/RGB888/ARGB888/XRGB8888 + optional opacity.
|
||||
- Recolor source image RGB565.
|
||||
- Scale and rotate (90, 180, 270 degree) source image RGB565.
|
||||
- Blending layers (w/ same supported formats as blitting).
|
||||
- Rotate screen (90, 180, 270 degree).
|
||||
|
||||
Known limitations:
|
||||
^^^^^^^^^^^^^^^^^^
|
||||
|
||||
- PXP can only rotate at 90x angles.
|
||||
- Rotation is not supported for images unaligned to blocks of 16x16 pixels. PXP
|
||||
is set to process 16x16 blocks to optimize the system for memory bandwidth and
|
||||
image processing time. The output engine essentially truncates any output
|
||||
pixels after the desired number of pixels has been written. When rotating a
|
||||
source image and the output is not divisible by the block size, the incorrect
|
||||
pixels could be truncated and the final output image can look shifted.
|
||||
- Recolor or transformation for images w/ opacity or alpha channel can't be
|
||||
obtained in a single PXP pipeline configuration. Two or multiple steps would
|
||||
be required.
|
||||
- Buffer address must be aligned to 64 bytes: set :c:macro:`LV_DRAW_BUF_ALIGN`
|
||||
to `64` in "lv_conf.h".
|
||||
No stride alignment is required: set :c:macro:`LV_DRAW_BUF_STRIDE_ALIGN` to
|
||||
`1` in "lv_conf.h".
|
||||
|
||||
Project setup:
|
||||
^^^^^^^^^^^^^^
|
||||
|
||||
- Add PXP related source files (and corresponding headers if available) to
|
||||
project:
|
||||
|
||||
- "src/draw/nxp/pxp/lv_draw_buf_pxp.c": draw buffer callbacks
|
||||
- "src/draw/nxp/pxp/lv_draw_pxp_fill.c": fill area
|
||||
- "src/draw/nxp/pxp/lv_draw_pxp_img.c": blit image (w/ optional recolor or
|
||||
transformation)
|
||||
- "src/draw/nxp/pxp/lv_draw_pxp_layer.c": layer blending
|
||||
- "src/draw/nxp/pxp/lv_draw_pxp.c": draw unit initialization
|
||||
- "src/draw/nxp/pxp/lv_pxp_cfg.c": init, deinit, run/wait PXP device
|
||||
- "src/draw/nxp/pxp/lv_pxp_osa.c": OS abstraction (FreeRTOS or bare metal)
|
||||
- "src/draw/nxp/pxp/lv_pxp_utils.c": function helpers
|
||||
|
||||
- PXP related code depends on two drivers provided by MCU SDK. These drivers
|
||||
need to be added to project:
|
||||
|
||||
- fsl_pxp.c: PXP driver
|
||||
- fsl_cache.c: CPU cache handling functions
|
||||
|
||||
PXP default configuration:
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
- Implementation depends on multiple OS-specific functions. The struct
|
||||
:cpp:struct:`pxp_cfg_t` with callback pointers is used as a parameter for the
|
||||
:cpp:func:`lv_pxp_init()` function. Default implementation for FreeRTOS and
|
||||
bare metal is provided in lv_pxp_osa.c.
|
||||
|
||||
- :cpp:func:`pxp_interrupt_init()`: Initialize PXP interrupt (HW setup,
|
||||
OS setup)
|
||||
- :cpp:func:`pxp_interrupt_deinit()`: Deinitialize PXP interrupt (HW setup,
|
||||
OS setup)
|
||||
- :cpp:func:`pxp_run()`: Start PXP job. Use OS-specific mechanism to block
|
||||
drawing thread.
|
||||
- :cpp:func:`pxp_wait()`: Wait for PXP completion.
|
||||
|
||||
VGLite accelerator
|
||||
~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Extra drawing features in LVGL can be handled by the VGLite engine. The
|
||||
CPU is available for other operations while the VGLite is running. An
|
||||
RTOS is required to block the LVGL drawing thread and switch to another
|
||||
task or suspend the CPU for power savings.
|
||||
|
||||
Basic configuration:
|
||||
^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
- Select NXP VGLite engine in "lv_conf.h": Set :c:macro:`LV_USE_DRAW_VGLITE` to
|
||||
`1`. :c:macro:`SDK_OS_FREE_RTOS` symbol needs to be defined so that FreeRTOS
|
||||
driver osal implementation will be enabled.
|
||||
- Enable VGLite asserts in "lv_conf.h": Set :c:macro: `LV_USE_VGLITE_ASSERT` to
|
||||
`1`.
|
||||
VGLite assertions will verify the driver API status code and in any error, it
|
||||
can stop the program execution in case the c:macro: `LV_ASSERT_HANDLER` is set
|
||||
to `while(1);` (Halt by default). Else, there will be logged just an error
|
||||
message via `LV_LOG_ERROR`.
|
||||
|
||||
Basic initialization:
|
||||
^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Initialize VGLite GPU before calling :cpp:func:`lv_init()` by specifying the
|
||||
width/height of tessellation window. The default values for tesselation width
|
||||
and height, and command buffer size are in the SDK file "vglite_support.h".
|
||||
|
||||
.. code:: c
|
||||
|
||||
#if LV_USE_DRAW_VGLITE
|
||||
#include "vg_lite.h"
|
||||
#include "vglite_support.h"
|
||||
#endif
|
||||
...
|
||||
#if LV_USE_DRAW_VGLITE
|
||||
if(vg_lite_init(DEFAULT_VG_LITE_TW_WIDTH, DEFAULT_VG_LITE_TW_HEIGHT) != VG_LITE_SUCCESS)
|
||||
{
|
||||
PRINTF("VGLite init error. STOP.");
|
||||
vg_lite_close();
|
||||
while (1)
|
||||
;
|
||||
}
|
||||
|
||||
if (vg_lite_set_command_buffer_size(VG_LITE_COMMAND_BUFFER_SIZE) != VG_LITE_SUCCESS)
|
||||
{
|
||||
PRINTF("VGLite set command buffer. STOP.");
|
||||
vg_lite_close();
|
||||
while (1)
|
||||
;
|
||||
}
|
||||
#endif
|
||||
|
||||
VGLite draw initialization is done automatically in :cpp:func:`lv_init()` once
|
||||
the VGLite is enabled, no user code is required:
|
||||
|
||||
.. code:: c
|
||||
|
||||
#if LV_USE_DRAW_VGLITE
|
||||
lv_draw_vglite_init();
|
||||
#endif
|
||||
|
||||
During VGLite initialization, a new draw unit `lv_draw_vglite_unit_t` will be
|
||||
created with the additional callbacks:
|
||||
|
||||
.. code:: c
|
||||
|
||||
lv_draw_vglite_unit_t * draw_vglite_unit = lv_draw_create_unit(sizeof(lv_draw_vglite_unit_t));
|
||||
draw_vglite_unit->base_unit.evaluate_cb = _vglite_evaluate;
|
||||
draw_vglite_unit->base_unit.dispatch_cb = _vglite_dispatch;
|
||||
draw_vglite_unit->base_unit.delete_cb = _vglite_delete;
|
||||
|
||||
and an addition thread `_vglite_render_thread_cb()` will be spawned in order to
|
||||
handle the supported draw tasks.
|
||||
|
||||
.. code:: c
|
||||
|
||||
#if LV_USE_VGLITE_DRAW_THREAD
|
||||
lv_thread_init(&draw_vglite_unit->thread, LV_THREAD_PRIO_HIGH, _vglite_render_thread_cb, 2 * 1024, draw_vglite_unit);
|
||||
#endif
|
||||
|
||||
If `LV_USE_VGLITE_DRAW_THREAD` is not defined, then no additional draw thread will be created
|
||||
and the VGLite drawing task will get executed on the same LVGL main thread.
|
||||
|
||||
`_vglite_evaluate()` will get called after each task is being created and will
|
||||
analyze if the task is supported by VGLite or not. If it is supported, then an
|
||||
preferred score and the draw unit id will be set to the task. An `score` equal
|
||||
to `100` is the default CPU score. Smaller score means that VGLite is capable of
|
||||
drawing it faster.
|
||||
|
||||
`_vglite_dispatch()` is the VGLite dispatcher callback, it will take a ready to
|
||||
draw task (having the `DRAW_UNIT_ID_VGLITE` set) and will pass the task to the
|
||||
VGLite draw unit for processing.
|
||||
|
||||
`_vglite_delete()` will cleanup the VGLite draw unit.
|
||||
|
||||
Advanced configuration:
|
||||
^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
- Enable VGLite blit split in "lv_conf.h":
|
||||
Set :c:macro: `LV_USE_VGLITE_BLIT_SPLIT` to `1`.
|
||||
Enabling the blit split workaround will mitigate any quality degradation issue
|
||||
on screen's dimension > 352 pixels.
|
||||
|
||||
.. code:: c
|
||||
|
||||
#define VGLITE_BLIT_SPLIT_THR 352
|
||||
|
||||
- By default, the blit split threshold is set to 352. Blits with width or height
|
||||
higher than this value will be done in multiple steps. Value must be multiple
|
||||
of stride alignment in px. For most color formats, the alignment is 16px
|
||||
(except the index formats). Transformation will not be supported once with
|
||||
the blit split.
|
||||
|
||||
- Enable VGLite draw task synchronously in "lv_conf.h":
|
||||
Set :c:macro: `LV_USE_VGLITE_DRAW_ASYNC` to `1`.
|
||||
Multiple draw tasks can be queued and flushed them once to the GPU based on
|
||||
the GPU idle status. If GPU is busy, the task will be queued, and the VGLite
|
||||
dispatcher will ask for a new available task. If GPU is idle, the queue with
|
||||
any pending tasks will be flushed to the GPU. The completion status of draw
|
||||
task will be sent to the main LVGL thread asynchronously.
|
||||
|
||||
Features supported:
|
||||
^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Several drawing features in LVGL can be offloaded to the VGLite engine. The CPU
|
||||
is available for other operations while the GPU is running. RTOS is required to
|
||||
block the LVGL drawing thread and switch to another task or suspend the CPU for
|
||||
power savings.
|
||||
|
||||
Supported draw tasks are available in "src/draw/nxp/pxp/lv_draw_vglite.c":
|
||||
|
||||
.. code:: c
|
||||
|
||||
switch(t->type) {
|
||||
case LV_DRAW_TASK_TYPE_LABEL:
|
||||
lv_draw_vglite_label(draw_unit, t->draw_dsc, &t->area);
|
||||
break;
|
||||
case LV_DRAW_TASK_TYPE_FILL:
|
||||
lv_draw_vglite_fill(draw_unit, t->draw_dsc, &t->area);
|
||||
break;
|
||||
case LV_DRAW_TASK_TYPE_BORDER:
|
||||
lv_draw_vglite_border(draw_unit, t->draw_dsc, &t->area);
|
||||
break;
|
||||
case LV_DRAW_TASK_TYPE_IMAGE:
|
||||
lv_draw_vglite_img(draw_unit, t->draw_dsc, &t->area);
|
||||
break;
|
||||
case LV_DRAW_TASK_TYPE_ARC:
|
||||
lv_draw_vglite_arc(draw_unit, t->draw_dsc, &t->area);
|
||||
break;
|
||||
case LV_DRAW_TASK_TYPE_LINE:
|
||||
lv_draw_vglite_line(draw_unit, t->draw_dsc);
|
||||
break;
|
||||
case LV_DRAW_TASK_TYPE_LAYER:
|
||||
lv_draw_vglite_layer(draw_unit, t->draw_dsc, &t->area);
|
||||
break;
|
||||
case LV_DRAW_TASK_TYPE_TRIANGLE:
|
||||
lv_draw_vglite_triangle(draw_unit, t->draw_dsc);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
All the below operation can be done in addition with optional opacity.
|
||||
- Fill area with color (w/ radius or gradient).
|
||||
- Blit source image (any format from `_vglite_src_cf_supported()`) over
|
||||
destination (any format from `_vglite_dest_cf_supported()`).
|
||||
- Recolor source image.
|
||||
- Scale and rotate (any decimal degree) source image.
|
||||
- Blending layers (w/ same supported formats as blitting).
|
||||
- Draw letters (blit bitmap letters - raster font).
|
||||
- Draw full borders (LV_BORDER_SIDE_FULL).
|
||||
- Draw arcs (w/ rounded edges).
|
||||
- Draw lines (w/ dash or rounded edges).
|
||||
- Draw triangles with color (w/ gradient).
|
||||
|
||||
Known limitations:
|
||||
^^^^^^^^^^^^^^^^^^
|
||||
|
||||
- Source image alignment: The byte alignment requirement for a pixel depends on
|
||||
the specific pixel format. Both buffer address and buffer stride must be
|
||||
aligned. As general rule, the alignment is set to 16 pixels. This makes the
|
||||
buffer address alignment to be 32 bytes for RGB565 and 64 bytes for ARGB8888.
|
||||
- For pixel engine (PE) destination, the alignment should be 64 bytes for all
|
||||
tiled (4x4) buffer layouts. The pixel engine has no additional alignment
|
||||
requirement for linear buffer layouts (:c:macro:`VG_LITE_LINEAR`).
|
||||
|
||||
Project setup:
|
||||
^^^^^^^^^^^^^^
|
||||
|
||||
- Add VGLite related source files (and corresponding headers if available) to
|
||||
project:
|
||||
|
||||
- "src/draw/nxp/vglite/lv_draw_buf_vglite.c": draw buffer callbacks
|
||||
- "src/draw/nxp/vglite/lv_draw_vglite_arc.c": draw arc
|
||||
- "src/draw/nxp/vglite/lv_draw_vglite_border.c": draw border
|
||||
- "src/draw/nxp/vglite/lv_draw_vglite_fill.c": fill area
|
||||
- "src/draw/nxp/vglite/lv_draw_vglite_img.c": blit image (w/ optional
|
||||
recolor or transformation)
|
||||
- "src/draw/nxp/vglite/lv_draw_vglite_label.c": draw label
|
||||
- "src/draw/nxp/vglite/lv_draw_vglite_layer.c": layer blending
|
||||
- "src/draw/nxp/vglite/lv_draw_vglite_line.c": draw line
|
||||
- "src/draw/nxp/vglite/lv_draw_vglite_triangle.c": draw triangle
|
||||
- "src/draw/nxp/vglite/lv_draw_vglite.c": draw unit initialization
|
||||
- "src/draw/nxp/vglite/lv_vglite_buf.c": init/get vglite buffer
|
||||
- "src/draw/nxp/vglite/lv_vglite_matrix.c": set vglite matrix
|
||||
- "src/draw/nxp/vglite/lv_vglite_path.c": create vglite path data
|
||||
- "src/draw/nxp/vglite/lv_vglite_utils.c": function helpers
|
||||
219
libraries/lvgl/docs/integration/chip/renesas.rst
Normal file
@@ -0,0 +1,219 @@
|
||||
.. _renesas:
|
||||
|
||||
=======
|
||||
Renesas
|
||||
=======
|
||||
|
||||
`Renesas <https://renesas.com/>`__ is an official partner of LVGL.
|
||||
Therefore, LVGL contains built-in support for `Dave2D <https://www.renesas.com/document/mas/tes-dave2d-driver-documentation>`__ (the GPU of Renesas)
|
||||
and we also maintain ready-to-use Renesas projects.
|
||||
|
||||
Dave2D
|
||||
------
|
||||
|
||||
Dave2D is capable of accelerating most of the drawing operations of LVGL:
|
||||
|
||||
- Rectangle drawing, even with gradients
|
||||
- Image drawing, scaling, and rotation
|
||||
- Letter drawing
|
||||
- Triangle drawing
|
||||
- Line drawing
|
||||
|
||||
As Dave2D works in the background, the CPU is free for other tasks. In practice, during rendering, Dave2D can reduce the CPU usage by half or to one-third, depending on the application.
|
||||
|
||||
GLCDC
|
||||
-----
|
||||
|
||||
GLCDC is a multi-stage graphics output peripheral available in several Renesas MCUs.
|
||||
It is able to drive LCD panels via a highly configurable RGB interface.
|
||||
|
||||
More info can be found at the :ref:`driver's page<renesas_glcdc>`.
|
||||
|
||||
Supported boards
|
||||
----------------
|
||||
|
||||
.. list-table::
|
||||
:widths: 10 30 30 30
|
||||
|
||||
* -
|
||||
- **EK-RA8D1**
|
||||
- **EK-RA6M3G**
|
||||
- **RX72N Envision Kit**
|
||||
* - CPU
|
||||
- 480MHz, Arm Cortex-M85 core
|
||||
- 120MHz, Arm Cortex-M4 core
|
||||
- 240MHz, Renesas RXv3 core
|
||||
* - Memory
|
||||
-
|
||||
| 1MB internal, 64MB external SDRAM
|
||||
| 2MB internal, 64MB External Octo-SPI Flash
|
||||
-
|
||||
| 640kB internal SRAM
|
||||
| 2MB internal, 32MB external QSPI Flash
|
||||
-
|
||||
| 1MB internal SRAM
|
||||
| 4MB internal, 32MB external QSPI Flash
|
||||
* - Display
|
||||
-
|
||||
| 4.5”
|
||||
| 480x854
|
||||
| 2-lane MIPI
|
||||
-
|
||||
| 4.3”
|
||||
| 480x272
|
||||
| Parallel RGB565
|
||||
-
|
||||
| 4.3”
|
||||
| 480x272
|
||||
| Parallel RGB565
|
||||
* - `Board <https://lvgl.io/boards>`__ video
|
||||
- .. raw:: html
|
||||
|
||||
<iframe width="320" height="180" src="https://www.youtube.com/embed/WkJPB8wto_U" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>
|
||||
|
||||
- .. raw:: html
|
||||
|
||||
<iframe width="320" height="180" src="https://www.youtube.com/embed/0kar4Ee3Qic" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>
|
||||
|
||||
- .. raw:: html
|
||||
|
||||
<iframe width="320" height="180" src="https://www.youtube.com/embed/__56v8DsfH0" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>
|
||||
|
||||
* - Links
|
||||
- `Demo repository for EK-RA8D1 <https://github.com/lvgl/lv_port_renesas_ek-ra8d1>`__
|
||||
- `Demo repository for EK-RA6M3G <https://github.com/lvgl/lv_port_renesas_ek-ra6m3g>`__
|
||||
- `Demo repository for RX72N Envision Kit <https://github.com/lvgl/lv_port_renesas_rx72n-envision-kit>`__
|
||||
|
||||
Get started with the Renesas ecosystem
|
||||
--------------------------------------
|
||||
|
||||
.. |img_debug_btn| image:: /misc/renesas/debug_btn.png
|
||||
:alt: Debug button
|
||||
|
||||
.. dropdown:: RA Family
|
||||
|
||||
- The official IDE of Renesas is called e² studio. As it's Eclipse-based, it runs on Windows, Linux, and Mac as well. The RA family requires the latest version with FSP 5.3. It can be downloaded `here <https://www.renesas.com/us/en/software-tool/flexible-software-package-fsp>`__.
|
||||
|
||||
- JLink is used for debugging, it can be downloaded `here <https://www.segger.com/downloads/jlink/>`__.
|
||||
|
||||
|
||||
- Clone the ready-to-use repository for your selected board:
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
git clone https://github.com/lvgl/lv_port_renesas_ek-ra8d1.git --recurse-submodules
|
||||
|
||||
Downloading the `.zip` from GitHub doesn't work as it doesn't download the submodules.
|
||||
|
||||
- Open e² studio, go to ``File`` -> ``Import project`` and select ``General`` / ``Existing projects into workspace``
|
||||
|
||||
- Browse the cloned folder and press ``Finish``.
|
||||
|
||||
- Double click on ``configuration.xml``. This will activate the `Configuration Window`.
|
||||
|
||||
Renesas' Flexible Software Package (FSP) incudes BSP and HAL layer support extended with multiple RTOS variants and other middleware stacks.
|
||||
The components will be available via code generation, including the entry point of *"main.c"*.
|
||||
|
||||
Press ``Generate Project Content`` in the top right corner.
|
||||
|
||||
.. image:: /misc/renesas/generate.png
|
||||
:alt: Code generation with FSP
|
||||
|
||||
- Build the project by pressing ``Ctrl`` + ``Alt`` + ``B``
|
||||
|
||||
- Click the Debug button (|img_debug_btn|). If prompted with `Debug Configurations`, on the `Debugger` tab select the ``J-Link ARM`` as `Debug hardware` and the proper IC as `Target Device`:
|
||||
|
||||
- ``R7FA8D1BH`` for EK-RA8D1
|
||||
|
||||
.. image:: /misc/renesas/debug_ra8.png
|
||||
:alt: Debugger parameters for RA8
|
||||
|
||||
- ``R7FA6M3AH`` for EK-RA6M3G
|
||||
|
||||
.. image:: /misc/renesas/debug_ra6.png
|
||||
:alt: Debugger parameters for RA6
|
||||
|
||||
.. note::
|
||||
On EK-RA8D1 boards, the ``SW1`` DIP switch (middle of the board) 7 should be ON, all others are OFF.
|
||||
|
||||
.. dropdown:: RX Family
|
||||
|
||||
- The official IDE of Renesas is called e² studio. As it's Eclipse-based, it runs on Windows, Linux, and Mac as well. It can be downloaded `here <https://www.renesas.com/us/en/software-tool/e-studio>`__.
|
||||
|
||||
- Download and install the required driver for the debugger
|
||||
|
||||
- for Windows: `64 bit here <https://www.renesas.com/us/en/document/uid/usb-driver-renesas-mcu-tools-v27700-64-bit-version-windows-os?r=488806>`__ and `32 bit here <https://www.renesas.com/us/en/document/uid/usb-driver-renesas-mcu-toolse2e2-liteie850ie850apg-fp5-v27700for-32-bit-version-windows-os?r=488806>`__
|
||||
- for Linux: `here <https://www.renesas.com/us/en/document/swo/e2-emulator-e2-emulator-lite-linux-driver?r=488806>`__
|
||||
|
||||
- RX72 requires an external compiler for the RXv3 core. A free and open-source version is available `here <https://llvm-gcc-renesas.com/rx-download-toolchains/>`__ after a registration.
|
||||
|
||||
The compiler must be activated in e² studio:
|
||||
|
||||
- Go to go to ``Help`` -> ``Add Renesas Toolchains``
|
||||
- Press the ``Add...`` button
|
||||
- Browse the installation folder of the toolchain
|
||||
|
||||
|
|
||||
|
||||
.. image:: /misc/renesas/toolchains.png
|
||||
:alt: Toolchains
|
||||
|
||||
- Clone the ready-to-use `lv_port_renesas_rx72n-envision-kit <https://github.com/lvgl/lv_port_renesas_rx72n-envision-kit.git>`__ repository:
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
git clone https://github.com/lvgl/lv_port_renesas_rx72n-envision-kit.git --recurse-submodules
|
||||
|
||||
Downloading the `.zip` from GitHub doesn't work as it doesn't download the submodules.
|
||||
|
||||
- Open e² studio, go to ``File`` -> ``Import project`` and select ``General`` / ``Existing projects into workspace``
|
||||
|
||||
- Select the cloned folder and press ``Finish``.
|
||||
|
||||
- Double click on ``RX72N_EnVision_LVGL.scfg``. This will activate the `Configuration Window`.
|
||||
|
||||
Renesas' Smart Configurator (SMC) incudes BSP and HAL layer support extended with multiple RTOS variants and other middleware stacks.
|
||||
The components will be available via code generation, including the entry point of the application.
|
||||
|
||||
Press ``Generate Code`` in the top right corner.
|
||||
|
||||
.. image:: /misc/renesas/generate_smc.png
|
||||
:alt: Code generation with SMC
|
||||
|
||||
- Build the project by pressing ``Ctrl`` + ``Alt`` + ``B``
|
||||
|
||||
- Click the Debug button (|img_debug_btn|). If prompted with `Debug Configurations`, on the `Debugger` tab select the ``E2 Lite`` as `Debug hardware` and ``R5F572NN`` as `Target Device`:
|
||||
|
||||
.. image:: /misc/renesas/debug_rx72.png
|
||||
:alt: Debugger parameters for RX72
|
||||
|
||||
.. note::
|
||||
Make sure that both channels of ``SW1`` DIP switch (next to ``ECN1``) are OFF.
|
||||
|
||||
Modify the project
|
||||
------------------
|
||||
|
||||
Open a demo
|
||||
~~~~~~~~~~~
|
||||
|
||||
The entry point of the main task is contained in ``src/LVGL_thread_entry.c`` in all 3 projects.
|
||||
|
||||
You can disable the LVGL demos (or just comment them out) and call some ``lv_example_...()`` functions, or add your custom code.
|
||||
|
||||
Configuration
|
||||
~~~~~~~~~~~~~
|
||||
|
||||
``src/lv_conf.h`` contains the most important settings for LVGL. Namely:
|
||||
|
||||
- ``LV_COLOR_DEPTH`` to set LVGL's default color depth
|
||||
- ``LV_MEM_SIZE to`` set the maximum RAM available for LVGL
|
||||
- ``LV_USE_DAVE2D`` to enable the GPU
|
||||
|
||||
|
||||
Hardware and software components can be modified in a visual way using the `Configuration Window`.
|
||||
|
||||
|
||||
Support
|
||||
-------
|
||||
|
||||
In case of any problems or questions open an issue in the corresponding repository.
|
||||
266
libraries/lvgl/docs/integration/chip/stm32.rst
Normal file
@@ -0,0 +1,266 @@
|
||||
=====
|
||||
STM32
|
||||
=====
|
||||
|
||||
LVGL Can be added to `STM32CubeIDE <https://www.st.com/en/development-tools/stm32cubeide.html>`__
|
||||
in a similar fashion to any other Eclipse-based IDE.
|
||||
|
||||
Including LVGL in a Project
|
||||
---------------------------
|
||||
|
||||
- Create or open a project in STM32CubeIDE.
|
||||
- Copy the entire LVGL folder to *[project_folder]/Drivers/lvgl*.
|
||||
- In the STM32CubeIDE **Project Explorer** pane: right click on the
|
||||
LVGL folder that you copied (you may need to refresh the view first
|
||||
before it will appear), and select **Add/remove include path…**. If
|
||||
this doesn't appear, or doesn't work, you can review your project
|
||||
include paths under the **Project** -> **Properties** menu, and then
|
||||
navigating to **C/C++ Build** -> **Settings** -> **Include paths**, and
|
||||
ensuring that the LVGL directory is listed.
|
||||
|
||||
Now that the source files are included in your project, follow the
|
||||
instructions for `Porting <https://docs.lvgl.io/master/porting/project.html>`__ your
|
||||
project to create the ``lv_conf.h`` file, and initialise the display.
|
||||
|
||||
Bare Metal Example
|
||||
------------------
|
||||
|
||||
A minimal example using STM32CubeIDE, and HAL. \* When setting up
|
||||
**Pinout and Configuration** using the **Device Configuration Tool**,
|
||||
select **System Core** -> **SYS** and ensure that **Timebase Source** is
|
||||
set to **SysTick**. \* Configure any other peripherals (including the
|
||||
LCD panel), and initialise them in *main.c*. \* ``#include "lvgl.h"`` in
|
||||
the *main.c* file. \* Create some frame buffer(s) as global variables:
|
||||
|
||||
.. code:: c
|
||||
|
||||
//Frame buffers
|
||||
/*Static or global buffer(s). The second buffer is optional*/
|
||||
//TODO: Adjust color format and choose buffer size. DISPLAY_WIDTH * 10 is one suggestion.
|
||||
#define BYTE_PER_PIXEL (LV_COLOR_FORMAT_GET_SIZE(LV_COLOR_FORMAT_RGB565)) /*will be 2 for RGB565 */
|
||||
#define BUFF_SIZE (DISPLAY_WIDTH * 10 * BYTE_PER_PIXEL)
|
||||
static uint8_t buf_1[BUFF_SIZE];
|
||||
static uint8_t buf_2[BUFF_SIZE];
|
||||
|
||||
- In your ``main()`` function, after initialising your CPU,
|
||||
peripherals, and LCD panel, call :cpp:func:`lv_init` to initialise LVGL.
|
||||
You can then create the display driver using
|
||||
:cpp:func:`lv_display_create`, and register the frame buffers using
|
||||
:cpp:func:`lv_display_set_buffers`.
|
||||
|
||||
.. code:: c
|
||||
|
||||
//Initialise LVGL UI library
|
||||
lv_init();
|
||||
|
||||
lv_display_t * disp = lv_display_create(WIDTH, HEIGHT); /*Basic initialization with horizontal and vertical resolution in pixels*/
|
||||
lv_display_set_flush_cb(disp, my_flush_cb); /*Set a flush callback to draw to the display*/
|
||||
lv_display_set_buffers(disp, buf_1, buf_2, sizeof(buf_1), LV_DISPLAY_RENDER_MODE_PARTIAL); /*Set an initialized buffer*/
|
||||
|
||||
- Create some dummy objects to test the output:
|
||||
|
||||
.. code:: c
|
||||
|
||||
// Change the active screen's background color
|
||||
lv_obj_set_style_bg_color(lv_screen_active(), lv_color_hex(0x003a57), LV_PART_MAIN);
|
||||
lv_obj_set_style_text_color(lv_screen_active(), lv_color_hex(0xffffff), LV_PART_MAIN);
|
||||
|
||||
/*Create a spinner*/
|
||||
lv_obj_t * spinner = lv_spinner_create(lv_screen_active(), 1000, 60);
|
||||
lv_obj_set_size(spinner, 64, 64);
|
||||
lv_obj_align(spinner, LV_ALIGN_BOTTOM_MID, 0, 0);
|
||||
|
||||
- Add a call to :cpp:func:`lv_timer_handler` inside your ``while(1)`` loop:
|
||||
|
||||
.. code:: c
|
||||
|
||||
/* Infinite loop */
|
||||
while (1)
|
||||
{
|
||||
lv_timer_handler();
|
||||
HAL_Delay(5);
|
||||
}
|
||||
|
||||
- Add a call to :cpp:func:`lv_tick_inc` inside the :cpp:func:`SysTick_Handler`
|
||||
function. Open the *stm32xxxx_it.c* file (the name will depend on
|
||||
your specific MCU), and update the :cpp:func:`SysTick_Handler` function:
|
||||
|
||||
.. code:: c
|
||||
|
||||
void SysTick_Handler(void)
|
||||
{
|
||||
/* USER CODE BEGIN SysTick_IRQn 0 */
|
||||
|
||||
HAL_SYSTICK_IRQHandler();
|
||||
lv_tick_inc(1);
|
||||
#ifdef USE_RTOS_SYSTICK
|
||||
osSystickHandler();
|
||||
#endif
|
||||
|
||||
/* USER CODE END SysTick_IRQn 0 */
|
||||
HAL_IncTick();
|
||||
/* USER CODE BEGIN SysTick_IRQn 1 */
|
||||
|
||||
/* USER CODE END SysTick_IRQn 1 */
|
||||
}
|
||||
|
||||
- Finally, write the callback function, ``my_flush_cb``, which will
|
||||
send the display buffer to your LCD panel. Below is one example, but
|
||||
it will vary depending on your setup.
|
||||
|
||||
.. code:: c
|
||||
|
||||
void my_flush_cb(lv_display_t * disp, const lv_area_t * area, lv_color_t * color_p)
|
||||
{
|
||||
//Set the drawing region
|
||||
set_draw_window(area->x1, area->y1, area->x2, area->y2);
|
||||
|
||||
int height = area->y2 - area->y1 + 1;
|
||||
int width = area->x2 - area->x1 + 1;
|
||||
|
||||
//We will do the SPI write manually here for speed
|
||||
HAL_GPIO_WritePin(DC_PORT, DC_PIN, GPIO_PIN_SET);
|
||||
//CS low to begin data
|
||||
HAL_GPIO_WritePin(CS_PORT, CS_PIN, GPIO_PIN_RESET);
|
||||
|
||||
//Write colour to each pixel
|
||||
for (int i = 0; i < width * height; i++) {
|
||||
uint16_t color_full = (color_p->red << 11) | (color_p->green << 5) | (color_p->blue);
|
||||
parallel_write(color_full);
|
||||
|
||||
color_p++;
|
||||
}
|
||||
|
||||
//Return CS to high
|
||||
HAL_GPIO_WritePin(CS_PORT, CS_PIN, GPIO_PIN_SET);
|
||||
|
||||
/* IMPORTANT!!!
|
||||
* Inform the graphics library that you are ready with the flushing*/
|
||||
lv_display_flush_ready(disp);
|
||||
}
|
||||
|
||||
FreeRTOS Example
|
||||
----------------
|
||||
|
||||
A minimal example using STM32CubeIDE, HAL, and CMSISv1 (FreeRTOS). *Note
|
||||
that we have not used Mutexes in this example, however LVGL is* **NOT**
|
||||
*thread safe and so Mutexes should be used*. See: :ref:`os_interrupt`
|
||||
\* ``#include "lvgl.h"`` \* Create your frame buffer(s) as global
|
||||
variables:
|
||||
|
||||
.. code:: c
|
||||
|
||||
//Frame buffers
|
||||
/*Static or global buffer(s). The second buffer is optional*/
|
||||
#define BYTE_PER_PIXEL (LV_COLOR_FORMAT_GET_SIZE(LV_COLOR_FORMAT_RGB565)) /*will be 2 for RGB565 */
|
||||
//TODO: Declare your own BUFF_SIZE appropriate to your system.
|
||||
#define BUFF_SIZE (DISPLAY_WIDTH * 10 * BYTE_PER_PIXEL)
|
||||
static uint8_t buf_1[BUFF_SIZE];
|
||||
static uint8_t buf_2[BUFF_SIZE];
|
||||
|
||||
- In your ``main`` function, after your peripherals (SPI, GPIOs, LCD
|
||||
etc) have been initialised, initialise LVGL using :cpp:func:`lv_init`,
|
||||
create a new display driver using :cpp:func:`lv_display_create`, and
|
||||
register the frame buffers using :cpp:func:`lv_display_set_buffers`.
|
||||
|
||||
.. code:: c
|
||||
|
||||
//Initialise LVGL UI library
|
||||
lv_init();
|
||||
lv_display_t *display = lv_display_create(WIDTH, HEIGHT); /*Create the display*/
|
||||
lv_display_set_flush_cb(display, my_flush_cb); /*Set a flush callback to draw to the display*/
|
||||
lv_display_set_buffers(disp, buf_1, buf_2, sizeof(buf_1), LV_DISPLAY_RENDER_MODE_PARTIAL); /*Set an initialized buffer*/
|
||||
|
||||
// Register the touch controller with LVGL - Not included here for brevity.
|
||||
|
||||
- Create some dummy objects to test the output:
|
||||
|
||||
.. code:: c
|
||||
|
||||
// Change the active screen's background color
|
||||
lv_obj_set_style_bg_color(lv_screen_active(), lv_color_hex(0x003a57), LV_PART_MAIN);
|
||||
lv_obj_set_style_text_color(lv_screen_active(), lv_color_hex(0xffffff), LV_PART_MAIN);
|
||||
|
||||
/*Create a spinner*/
|
||||
lv_obj_t * spinner = lv_spinner_create(lv_screen_active(), 1000, 60);
|
||||
lv_obj_set_size(spinner, 64, 64);
|
||||
lv_obj_align(spinner, LV_ALIGN_BOTTOM_MID, 0, 0);
|
||||
|
||||
- Create two threads to call :cpp:func:`lv_timer_handler`, and
|
||||
:cpp:func:`lv_tick_inc`.You will need two ``osThreadId`` handles for
|
||||
CMSISv1. These don't strictly have to be globally accessible in this
|
||||
case, however STM32Cube code generation does by default. If you are
|
||||
using CMSIS and STM32Cube code generation it should look something
|
||||
like this:
|
||||
|
||||
.. code:: c
|
||||
|
||||
//Thread Handles
|
||||
osThreadId lvgl_tickHandle;
|
||||
osThreadId lvgl_timerHandle;
|
||||
|
||||
/* definition and creation of lvgl_tick */
|
||||
osThreadDef(lvgl_tick, LVGLTick, osPriorityNormal, 0, 1024);
|
||||
lvgl_tickHandle = osThreadCreate(osThread(lvgl_tick), NULL);
|
||||
|
||||
//LVGL update timer
|
||||
osThreadDef(lvgl_timer, LVGLTimer, osPriorityNormal, 0, 1024);
|
||||
lvgl_timerHandle = osThreadCreate(osThread(lvgl_timer), NULL);
|
||||
|
||||
- And create the thread functions:
|
||||
|
||||
.. code:: c
|
||||
|
||||
/* LVGL timer for tasks. */
|
||||
void LVGLTimer(void const * argument)
|
||||
{
|
||||
for(;;)
|
||||
{
|
||||
lv_timer_handler();
|
||||
osDelay(20);
|
||||
}
|
||||
}
|
||||
/* LVGL tick source */
|
||||
void LVGLTick(void const * argument)
|
||||
{
|
||||
for(;;)
|
||||
{
|
||||
lv_tick_inc(10);
|
||||
osDelay(10);
|
||||
}
|
||||
}
|
||||
|
||||
- Finally, create the ``my_flush_cb`` function to output the frame
|
||||
buffer to your LCD. The specifics of this function will vary
|
||||
depending on which MCU features you are using. Below is an example
|
||||
for a typical MCU interface.
|
||||
|
||||
.. code:: c
|
||||
|
||||
void my_flush_cb(lv_display_t * display, const lv_area_t * area, uint8_t * px_map);
|
||||
{
|
||||
uint16_t * color_p = (uint16_t *)px_map;
|
||||
|
||||
//Set the drawing region
|
||||
set_draw_window(area->x1, area->y1, area->x2, area->y2);
|
||||
|
||||
int height = area->y2 - area->y1 + 1;
|
||||
int width = area->x2 - area->x1 + 1;
|
||||
|
||||
//Begin SPI Write for DATA
|
||||
HAL_GPIO_WritePin(DC_PORT, DC_PIN, GPIO_PIN_SET);
|
||||
HAL_GPIO_WritePin(CS_PORT, CS_PIN, GPIO_PIN_RESET);
|
||||
|
||||
//Write colour to each pixel
|
||||
for (int i = 0; i < width * height; i++) {
|
||||
parallel_write(color_p);
|
||||
color_p++;
|
||||
}
|
||||
|
||||
//Return CS to high
|
||||
HAL_GPIO_WritePin(CS_PORT, CS_PIN, GPIO_PIN_SET);
|
||||
|
||||
/* IMPORTANT!!!
|
||||
* Inform the graphics library that you are ready with the flushing*/
|
||||
lv_display_flush_ready(display);
|
||||
}
|
||||
127
libraries/lvgl/docs/integration/driver/X11.rst
Normal file
@@ -0,0 +1,127 @@
|
||||
=========================
|
||||
X11 Display/Inputs driver
|
||||
=========================
|
||||
|
||||
Overview
|
||||
--------
|
||||
|
||||
| The **X11** display/input `driver <https://github.com/lvgl/lvgl/src/drivers/x11>`__ offers support for simulating the LVGL display and keyboard/mouse inputs in an X11 desktop window.
|
||||
| It is an alternative to **Wayland**, **XCB**, **SDL** or **Qt**.
|
||||
|
||||
The main purpose for this driver is for testing/debugging the LVGL application in a **Linux** simulation window.
|
||||
|
||||
|
||||
Prerequisites
|
||||
-------------
|
||||
|
||||
The X11 driver uses XLib to access the linux window manager.
|
||||
|
||||
1. Install XLib: ``sudo apt-get install libx11-6`` (should be installed already)
|
||||
2. Install XLib development package: ``sudo apt-get install libx11-dev``
|
||||
|
||||
|
||||
Configure X11 driver
|
||||
--------------------
|
||||
|
||||
1. Enable the X11 driver support in lv_conf.h, by cmake compiler define or by KConfig
|
||||
.. code:: c
|
||||
|
||||
#define LV_USE_X11 1
|
||||
|
||||
2. Optional configuration options:
|
||||
- Direct Exit
|
||||
.. code:: c
|
||||
|
||||
#define LV_X11_DIRECT_EXIT 1 /*preferred default - ends the application automatically if last window has been closed*/
|
||||
// or
|
||||
#define LV_X11_DIRECT_EXIT 0 /*application is responsible for ending the application (e.g. by own LV_EVENT_DELETE handler*/
|
||||
|
||||
|
||||
- Double buffering
|
||||
.. code:: c
|
||||
|
||||
#define LV_X11_DOUBLE_BUFFER 1 /*preferred default*/
|
||||
// or
|
||||
#define LV_X11_DOUBLE_BUFFER 0 /*not recommended*/
|
||||
|
||||
- Render mode
|
||||
.. code:: c
|
||||
|
||||
#define LV_X11_RENDER_MODE_PARTIAL 1 /*LV_DISPLAY_RENDER_MODE_PARTIAL, preferred default*/
|
||||
// or
|
||||
#define LV_X11_RENDER_MODE_DIRECT 1 /*LV_DISPLAY_RENDER_MODE_DIRECT, not recommended for X11 driver*/
|
||||
// or
|
||||
#define LV_X11_RENDER_MODE_DULL 1 /*LV_DISPLAY_RENDER_MODE_FULL, not recommended for X11 driver*/
|
||||
|
||||
Usage
|
||||
-----
|
||||
|
||||
| The minimal initialisation opening a window and enabling keyboard/mouse support
|
||||
| (e.g. in main.c, LV_X11_DIRECT_EXIT must be 1):
|
||||
|
||||
.. code:: c
|
||||
|
||||
int main(int argc, char ** argv)
|
||||
{
|
||||
...
|
||||
|
||||
/* initialize X11 display driver */
|
||||
lv_display_t * disp = lv_x11_window_create("LVGL X11 Simulation", monitor_hor_res, monitor_ver_res);
|
||||
|
||||
/* initialize X11 input drivers (for keyboard, mouse & mousewheel) */
|
||||
lv_x11_inputs_create(disp, NULL);
|
||||
|
||||
...
|
||||
|
||||
while(true)
|
||||
{
|
||||
...
|
||||
|
||||
/* Periodically call the lv_timer handler */
|
||||
lv_timer_handler();
|
||||
}
|
||||
}
|
||||
|
||||
| Full initialisation with mouse pointer symbol and own application exit handling
|
||||
| (dependent on LV_X11_DIRECT_EXIT (can be 1 or 0))
|
||||
|
||||
.. code:: c
|
||||
|
||||
bool terminated = false;
|
||||
|
||||
#if !LV_X11_DIRECT_EXIT
|
||||
static void on_close_cb(lv_event_t * e)
|
||||
{
|
||||
...
|
||||
|
||||
terminate = true;
|
||||
}
|
||||
#endif
|
||||
|
||||
int main(int argc, char ** argv)
|
||||
{
|
||||
...
|
||||
|
||||
/* initialize X11 display driver */
|
||||
lv_display_t * disp = lv_x11_window_create("LVGL X11 Simulation", monitor_hor_res, monitor_ver_res);
|
||||
lv_display_add_event_cb(disp, on_close_cb, LV_EVENT_DELETE, disp);
|
||||
|
||||
/* initialize X11 input drivers (for keyboard, mouse & mousewheel) */
|
||||
LV_IMAGE_DECLARE(my_mouse_cursor_icon);
|
||||
lv_x11_inputs_create(disp, &my_mouse_cursor_icon);
|
||||
|
||||
#if !LV_X11_DIRECT_EXIT
|
||||
/* set optional window close callback to enable application cleanup and exit */
|
||||
lv_x11_window_set_close_cb(disp, on_close_cb, disp);
|
||||
#endif
|
||||
|
||||
...
|
||||
|
||||
while(!terminated)
|
||||
{
|
||||
...
|
||||
|
||||
/* Periodically call the lv_timer handler */
|
||||
lv_timer_handler();
|
||||
}
|
||||
}
|
||||
41
libraries/lvgl/docs/integration/driver/display/fbdev.rst
Normal file
@@ -0,0 +1,41 @@
|
||||
========================
|
||||
Linux Framebuffer Driver
|
||||
========================
|
||||
|
||||
Overview
|
||||
--------
|
||||
|
||||
The Linux framebuffer (fbdev) is a linux subsystem used to display graphics. It is a hardware-independent API that gives user space software
|
||||
access to the framebuffer (the part of a computer's video memory containing a current video frame) using only the Linux kernel's own basic
|
||||
facilities and its device file system interface, avoiding the need for libraries that implement video drivers in user space.
|
||||
|
||||
Prerequisites
|
||||
-------------
|
||||
|
||||
Your system has a framebuffer device configured (usually under ``/dev/fb0``).
|
||||
|
||||
Configuring the driver
|
||||
----------------------
|
||||
|
||||
Enable the framebuffer driver support in lv_conf.h, by cmake compiler define or by KConfig. Additionally you may configure the rendering
|
||||
mode.
|
||||
|
||||
.. code:: c
|
||||
|
||||
#define LV_USE_LINUX_FBDEV 1
|
||||
#define LV_LINUX_FBDEV_RENDER_MODE LV_DISPLAY_RENDER_MODE_PARTIAL
|
||||
|
||||
Usage
|
||||
-----
|
||||
|
||||
To set up a framebuffer-based display, first create a display with ``lv_linux_fbdev_create``. Afterwards set the framebuffer device
|
||||
node on the display (usually this is ``/dev/fb0``).
|
||||
|
||||
.. code:: c
|
||||
|
||||
lv_display_t *disp = lv_linux_fbdev_create();
|
||||
lv_linux_fbdev_set_file(disp, "/dev/fb0");
|
||||
|
||||
If your screen stays black or only draws partially, you can try enabling direct rendering via ``LV_DISPLAY_RENDER_MODE_DIRECT``. Additionally,
|
||||
you can activate a force refresh mode with ``lv_linux_fbdev_set_force_refresh(true)``. This usually has a performance impact though and shouldn't
|
||||
be enabled unless really needed.
|
||||
210
libraries/lvgl/docs/integration/driver/display/gen_mipi.rst
Normal file
@@ -0,0 +1,210 @@
|
||||
=================================================
|
||||
Generic MIPI DCS compatible LCD Controller driver
|
||||
=================================================
|
||||
|
||||
Overview
|
||||
--------
|
||||
|
||||
From the `Wikipedia <https://en.wikipedia.org/wiki/MIPI_Alliance>`__:
|
||||
|
||||
`MIPI Alliance <https://www.mipi.org/>`__ is a global business alliance that develops technical specifications
|
||||
for the mobile ecosystem, particularly smart phones but including mobile-influenced industries. MIPI was founded in 2003 by Arm, Intel, Nokia, Samsung,
|
||||
STMicroelectronics and Texas Instruments.
|
||||
|
||||
MIPI Alliance published a series of specifications related to display devices, including DBI (Display Bus Interface), DSI (Display Serial Interface) and DCS
|
||||
(Display Command Set). Usually when one talks about a MIPI-compatible display, one thinks of a device with a DSI serial interface. However, the Display Bus Interface specification
|
||||
includes a number of other, legacy interfaces, like SPI serial, or i8080-compatible parallel interface, which are often used to interface LCD displays to lower-end microcontrollers.
|
||||
Furthermore, the DCS specification contains a standard command set, which is supported by a large number of legacy TFT LCD controllers, including the popular Sitronix
|
||||
(ST7735, ST7789, ST7796) and Ilitek (ILI9341) SOCs. These commands provide a common interface to configure display orientation, color resolution, various power modes, and provide generic video memory access. On top
|
||||
of that standard command set each LCD controller chip has a number of vendor-specific commands to configure voltage generator levels, timings, or gamma curves.
|
||||
|
||||
.. note::
|
||||
|
||||
It is important to understand that this generic MIPI LCD driver is not a hardware driver for displays with the DSI ("MIPI") serial interface. Instead, it implements the MIPI DCS command set used in many LCD controllers with an SPI or i8080 bus, and provides a common framework for chip-specific display controllers.
|
||||
|
||||
.. tip::
|
||||
Although this is a generic driver, it can be used to support compatible chips which do not have a specific driver.
|
||||
|
||||
|
||||
Prerequisites
|
||||
-------------
|
||||
|
||||
There are no prerequisites.
|
||||
|
||||
Configuring the driver
|
||||
----------------------
|
||||
|
||||
Enable the generic MIPI LCD driver support in lv_conf.h, by cmake compiler define or by KConfig
|
||||
|
||||
.. code:: c
|
||||
|
||||
#define LV_USE_GENERIC_MIPI 1
|
||||
|
||||
.. note::
|
||||
``LV_USE_GENERIC_MIPI`` is automatically enabled when a compatible driver is enabled.
|
||||
|
||||
Usage
|
||||
-----
|
||||
|
||||
You need to implement two platform-dependent functions:
|
||||
|
||||
.. code:: c
|
||||
|
||||
/* Send short command to the LCD. This function shall wait until the transaction finishes. */
|
||||
int32_t my_lcd_send_cmd(lv_display_t *disp, const uint8_t *cmd, size_t cmd_size, const uint8_t *param, size_t param_size)
|
||||
{
|
||||
...
|
||||
}
|
||||
|
||||
/* Send large array of pixel data to the LCD. If necessary, this function has to do the byte-swapping. This function can do the transfer in the background. */
|
||||
int32_t my_lcd_send_color(lv_display_t *disp, const uint8_t *cmd, size_t cmd_size, uint8_t *param, size_t param_size)
|
||||
{
|
||||
...
|
||||
}
|
||||
|
||||
The only difference between the :cpp:func:`my_lcd_send_cmd()` and :cpp:func:`my_lcd_send_color()` functions is that :cpp:func:`my_lcd_send_cmd()` is used to send short commands and it is expected
|
||||
complete the transaction when it returns (in other words, it should be blocking), while :cpp:func:`my_lcd_send_color()` is only used to send pixel data, and it is recommended to use
|
||||
DMA to transmit data in the background. More sophisticated methods can be also implemented, like queuing transfers and scheduling them in the background.
|
||||
|
||||
Please note that while display flushing is handled by the driver, it is the user's responsibility to call :cpp:func:`lv_display_flush_ready()`
|
||||
when the color transfer completes. In case of a DMA transfer this is usually done in a transfer ready callback.
|
||||
|
||||
.. note::
|
||||
While it is acceptable to use a blocking implementation for the pixel transfer as well, performance will suffer.
|
||||
|
||||
.. tip::
|
||||
Care must be taken to avoid sending a command while there is an active transfer going on in the background. It is the user's responsibility to implement this either
|
||||
by polling the hardware, polling a global variable (which is reset at the end of the transfer), or by using a semaphore or other locking mechanism.
|
||||
|
||||
Please also note that the driver does not handle the draw buffer allocation, because this may be platform-dependent, too. Thus you need to allocate the buffers and assign them
|
||||
to the display object as usual by calling :cpp:func:`lv_display_set_buffers()`.
|
||||
|
||||
The driver can be used to create multiple displays. In such a configuration the callbacks must be able to distinguish between the displays. Usually one would
|
||||
implement a separate set of callbacks for each display. Also note that the user must take care of arbitrating the bus when multiple devices are connected to it.
|
||||
|
||||
Example
|
||||
-------
|
||||
|
||||
.. note::
|
||||
You can find a step-by-step guide and the actual implementation of the callbacks on an STM32F746 using STM32CubeIDE and the ST HAL libraries here: :ref:`lcd_stm32_guide`
|
||||
|
||||
|
||||
.. code:: c
|
||||
|
||||
#include "src/drivers/display/st7789/lv_st7789.h"
|
||||
|
||||
#define LCD_H_RES 240
|
||||
#define LCD_V_RES 320
|
||||
#define LCD_BUF_LINES 60
|
||||
|
||||
lv_display_t *my_disp;
|
||||
|
||||
...
|
||||
|
||||
/* Initialize LCD I/O bus, reset LCD */
|
||||
static int32_t my_lcd_io_init(void)
|
||||
{
|
||||
...
|
||||
return HAL_OK;
|
||||
}
|
||||
|
||||
/* Send command to the LCD controller */
|
||||
static void my_lcd_send_cmd(lv_display_t *disp, const uint8_t *cmd, size_t cmd_size, const uint8_t *param, size_t param_size)
|
||||
{
|
||||
...
|
||||
}
|
||||
|
||||
/* Send pixel data to the LCD controller */
|
||||
static void my_lcd_send_color(lv_display_t *disp, const uint8_t *cmd, size_t cmd_size, uint8_t *param, size_t param_size)
|
||||
{
|
||||
...
|
||||
}
|
||||
|
||||
int main(int argc, char ** argv)
|
||||
{
|
||||
...
|
||||
|
||||
/* Initialize LVGL */
|
||||
lv_init();
|
||||
|
||||
/* Initialize LCD bus I/O */
|
||||
if (my_lcd_io_init() != 0)
|
||||
return;
|
||||
|
||||
/* Create the LVGL display object and the LCD display driver */
|
||||
my_disp = lv_lcd_generic_mipi_create(LCD_H_RES, LCD_V_RES, LV_LCD_FLAG_NONE, my_lcd_send_cmd, my_lcd_send_color);
|
||||
|
||||
/* Set display orientation to landscape */
|
||||
lv_display_set_rotation(my_disp, LV_DISPLAY_ROTATION_90);
|
||||
|
||||
/* Configure draw buffers, etc. */
|
||||
uint8_t * buf1 = NULL;
|
||||
uint8_t * buf2 = NULL;
|
||||
|
||||
uint32_t buf_size = LCD_H_RES * LCD_BUF_LINES * lv_color_format_get_size(lv_display_get_color_format(my_disp));
|
||||
|
||||
buf1 = lv_malloc(buf_size);
|
||||
if(buf1 == NULL) {
|
||||
LV_LOG_ERROR("display draw buffer malloc failed");
|
||||
return;
|
||||
}
|
||||
/* Allocate secondary buffer if needed */
|
||||
...
|
||||
|
||||
lv_display_set_buffers(my_disp, buf1, buf2, buf_size, LV_DISPLAY_RENDER_MODE_PARTIAL);
|
||||
|
||||
ui_init(my_disp);
|
||||
|
||||
while(true) {
|
||||
...
|
||||
|
||||
/* Periodically call the lv_timer handler */
|
||||
lv_timer_handler();
|
||||
}
|
||||
}
|
||||
|
||||
Advanced topics
|
||||
---------------
|
||||
|
||||
Create flags
|
||||
^^^^^^^^^^^^
|
||||
|
||||
The third argument of the :cpp:func:`lv_lcd_generic_mipi_create()` function is a flag array. This can be used to configure the orientation and RGB ordering of the panel if the
|
||||
default settings do not work for you. In particular, the generic MIPI driver accepts the following flags:
|
||||
|
||||
.. code:: c
|
||||
|
||||
LV_LCD_FLAG_NONE
|
||||
LV_LCD_FLAG_MIRROR_X
|
||||
LV_LCD_FLAG_MIRROR_Y
|
||||
LV_LCD_FLAG_BGR
|
||||
|
||||
You can pass multiple flags by ORing them together, e.g., :c:macro:`LV_LCD_FLAG_MIRROR_X | LV_LCD_FLAG_BGR`.
|
||||
|
||||
Custom command lists
|
||||
^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
While the chip-specific drivers do their best to initialize the LCD controller correctly, it is possible, that different TFT panels need different configurations.
|
||||
In particular a correct gamma setup is crucial for good color reproduction. Unfortunately, finding a good set of parameters is not easy. Usually the manufacturer
|
||||
of the panel provides some example code with recommended register settings.
|
||||
|
||||
You can use the ``my_lcd_send_cmd()`` function to send an arbitrary command to the LCD controller. However, to make it easier to send a large number of parameters
|
||||
the generic MIPI driver supports sending a custom command list to the controller. The commands must be put into a 'uint8_t' array:
|
||||
|
||||
.. code:: c
|
||||
|
||||
static const uint8_t init_cmd_list[] = {
|
||||
<command 1>, <number of parameters>, <parameter 1>, ... <parameter N>,
|
||||
<command 2>, <number of parameters>, <parameter 1>, ... <parameter N>,
|
||||
...
|
||||
LV_LCD_CMD_DELAY_MS, LV_LCD_CMD_EOF /* terminate list: this is required! */
|
||||
};
|
||||
|
||||
...
|
||||
|
||||
lv_lcd_generic_mipi_send_cmd_list(my_disp, init_cmd_list);
|
||||
|
||||
You can add a delay between the commands by using the pseudo-command ``LV_LCD_CMD_DELAY_MS``, which must be followed by the delay given in 10ms units.
|
||||
To terminate the command list you must use a delay with a value of ``LV_LCD_CMD_EOF``, as shown above.
|
||||
|
||||
See an actual example of sending a command list `here <https://github.com/lvgl/lvgl/src/drivers/display/st7789/lv_st7789.c>`__.
|
||||
73
libraries/lvgl/docs/integration/driver/display/ili9341.rst
Normal file
@@ -0,0 +1,73 @@
|
||||
=============================
|
||||
ILI9341 LCD Controller driver
|
||||
=============================
|
||||
|
||||
Overview
|
||||
--------
|
||||
|
||||
The `ILI9341 <https://www.buydisplay.com/download/ic/ILI9341.pdf>`__ is a 262,144-color single-chip SOC driver for a-TFT liquid crystal display with resolution of 240RGBx320
|
||||
dots, comprising a 720-channel source driver, a 320-channel gate driver, 172,800 bytes GRAM for graphic
|
||||
display data of 240RGBx320 dots, and power supply circuit.
|
||||
ILI9341 supports parallel 8-/9-/16-/18-bit data bus MCU interface, 6-/16-/18-bit data bus RGB interface and
|
||||
3-/4-line serial peripheral interface (SPI).
|
||||
|
||||
The ILI9341 LCD controller `driver <https://github.com/lvgl/lvgl/src/drivers/display/ili9341>`__ is a platform-agnostic driver, based on the `generic MIPI driver <https://github.com/lvgl/lvgl/doc/integration/drivers/display/gen_mipi.rst>`__.
|
||||
It implements display initialization, supports display rotation and implements the display flush callback. The user needs to implement only two platform-specific functions to send
|
||||
a command or pixel data to the controller via SPI or parallel bus. Typically these are implemented by calling the appropriate SDK library functions on the given platform.
|
||||
|
||||
Prerequisites
|
||||
-------------
|
||||
|
||||
There are no prerequisites.
|
||||
|
||||
Configuring the driver
|
||||
----------------------
|
||||
|
||||
Enable the ILI9341 driver support in lv_conf.h, by cmake compiler define or by KConfig
|
||||
|
||||
.. code:: c
|
||||
|
||||
#define LV_USE_ILI9341 1
|
||||
|
||||
Usage
|
||||
-----
|
||||
|
||||
You need to implement two platform-dependent functions:
|
||||
|
||||
.. code:: c
|
||||
|
||||
/* Send short command to the LCD. This function shall wait until the transaction finishes. */
|
||||
int32_t my_lcd_send_cmd(lv_display_t *disp, const uint8_t *cmd, size_t cmd_size, const uint8_t *param, size_t param_size)
|
||||
{
|
||||
...
|
||||
}
|
||||
|
||||
/* Send large array of pixel data to the LCD. If necessary, this function has to do the byte-swapping. This function can do the transfer in the background. */
|
||||
int32_t my_lcd_send_color(lv_display_t *disp, const uint8_t *cmd, size_t cmd_size, uint8_t *param, size_t param_size)
|
||||
{
|
||||
...
|
||||
}
|
||||
|
||||
To create an ILI9341-based display use the function
|
||||
|
||||
.. code:: c
|
||||
|
||||
/**
|
||||
* Create an LCD display with ILI9341 driver
|
||||
* @param hor_res horizontal resolution
|
||||
* @param ver_res vertical resolution
|
||||
* @param flags default configuration settings (mirror, RGB ordering, etc.)
|
||||
* @param send_cmd platform-dependent function to send a command to the LCD controller (usually uses polling transfer)
|
||||
* @param send_color platform-dependent function to send pixel data to the LCD controller (usually uses DMA transfer: must implement a 'ready' callback)
|
||||
* @return pointer to the created display
|
||||
*/
|
||||
lv_display_t * lv_ili9341_create(uint32_t hor_res, uint32_t ver_res, lv_lcd_flag_t flags,
|
||||
lv_ili9341_send_cmd_cb_t send_cmd_cb, lv_ili9341_send_color_cb_t send_color_cb);
|
||||
|
||||
|
||||
For additional details and a working example see the `generic MIPI driver documentation <https://github.com/lvgl/lvgl/doc/integration/drivers/display/gen_mipi.rst>`__.
|
||||
|
||||
.. note::
|
||||
|
||||
You can find a step-by-step guide and the actual implementation of the callbacks on an STM32F746 using STM32CubeIDE and the ST HAL libraries here: :ref:`lcd_stm32_guide`
|
||||
|
||||
15
libraries/lvgl/docs/integration/driver/display/index.rst
Normal file
@@ -0,0 +1,15 @@
|
||||
=======
|
||||
Display
|
||||
=======
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 2
|
||||
|
||||
fbdev
|
||||
gen_mipi
|
||||
ili9341
|
||||
lcd_stm32_guide
|
||||
st7735
|
||||
st7789
|
||||
st7796
|
||||
renesas_glcdc
|
||||
@@ -0,0 +1,320 @@
|
||||
.. _lcd_stm32_guide:
|
||||
|
||||
=========================================================================
|
||||
Step-by-step Guide: How to use the LVGL v9 LCD drivers with STM32 devices
|
||||
=========================================================================
|
||||
|
||||
Introduction
|
||||
------------
|
||||
|
||||
This guide is intended to be a step-by-step instruction of how to configure the STM32Cube HAL with the new TFT-LCD display drivers introduced in LVGL v9.0. The example code has been tested on the STM32F746-based Nucleo-F746ZG board with an ST7789-based LCD panel connected via SPI. The application itself and the hardware configuration code were generated with the STM32CubeIDE 1.14.0 tool.
|
||||
|
||||
.. tip::
|
||||
ST Micro provide their own TFT-LCD drivers in their X-CUBE-DISPLAY Software Extension Package. While these drivers can be used with LVGL as well, the LVGL LCD drivers do not depend on this package.
|
||||
|
||||
The LVGL LCD drivers are meant as an alternative, simple to use API to implement LCD support for your LVGL-based project on any platform. Moreover, even in the initial release we support more LCD controllers than X-CUBE-DISPLAY currently provides, and we plan to add support for even more LCD controllers in the future.
|
||||
|
||||
Please note however, that – unlike X-CUBE-DISPLAY – the LVGL LCD drivers do not implement the communication part, whether SPI, parallel i8080 bus or other. It is the user's responsibility to implement – and optimize – these on their chosen platform. LVGL will only provide examples for the most popular platforms.
|
||||
|
||||
By following the steps you will have a fully functional program, which can be used as the foundation of your own LVGL-based project. If you are in a hurry and not interested in the details, you can find the final project `here <https://github.com/lvgl/lv_port_lcd_stm32>`__. You will only need to configure LVGL to use the driver corresponding to your hardware (if it is other than the ST7789), and implement the function ``ui_init()`` to create your widgets.
|
||||
|
||||
.. note::
|
||||
|
||||
This example is not meant as the best possible implementation, or the recommended solution. It relies solely on the HAL drivers provided by ST Micro, which favor portability over performance. Despite of this the performance is very good, thanks to the efficient, DMA-based implementation of the drivers.
|
||||
|
||||
.. note::
|
||||
|
||||
Although the example uses FreeRTOS, this is not a strict requirement with the LVGL LCD display drivers.
|
||||
|
||||
You can find the source code snippets of this guide in the `lv_port_lcd_stm32_template.c <https://github.com/lvgl/lvgl/examples/porting/lv_port_lcd_stm32_template.c>`__ example.
|
||||
|
||||
Hardware configuration
|
||||
----------------------
|
||||
|
||||
In this example we'll use the SPI1 peripheral to connect the microcontroller to the LCD panel. Besides the hardware-controlled SPI pins SCK and MOSI we need some additional output pins for the chip select, command/data select, and LCD reset:
|
||||
|
||||
==== ============= ======= ==========
|
||||
pin configuration LCD user label
|
||||
==== ============= ======= ==========
|
||||
PA4 GPIO_Output CS LCD_CS
|
||||
PA5 SPI1_SCK SCK --
|
||||
PA7 SPI1_MOSI SDI --
|
||||
PA15 GPIO_Output RESET LCD_RESET
|
||||
PB10 GPIO_Output DC LCD_DCX
|
||||
==== ============= ======= ==========
|
||||
|
||||
Step-by-step instructions
|
||||
-------------------------
|
||||
|
||||
#. Create new project in File/New/STM32 Project.
|
||||
#. Select target processor/board.
|
||||
#. Set project name and location.
|
||||
#. Set Targeted Project Type to STM32Cube and press Finish.
|
||||
#. Say "Yes" to Initialize peripherals with their default Mode? After the project is created, the configuration file (.ioc) is opened automatically.
|
||||
#. Switch to the Pinout & Configuration tab.
|
||||
#. In the System Core category switch to RCC.
|
||||
#. Set High Speed Clock to "BYPASS Clock Source", and Low Speed Clock to "Crystal/Ceramic Resonator".
|
||||
#. In the System Core category select SYS, and set Timebase Source to other than SysTick (in our example, TIM2).
|
||||
#. Switch to the Clock Configuration tab.
|
||||
#. Set the HCLK clock frequency to the maximum value (216 MHz for the STM32F746).
|
||||
#. Switch back to the Pinout & Configuration tab, and in the Middleware and Software Packs category select FREERTOS.
|
||||
#. Select Interface: CMSIS_V1.
|
||||
#. In the Advanced Settings tab enable USE_NEWLIB_REENTRANT. We are finished here.
|
||||
#. In the Pinout view configure PA5 as SPI1_SCK, PA7 as SPI1_MOSI (right click the pin and select the function).
|
||||
#. In the Pinout & Configuration/Connectivity category select SPI1.
|
||||
#. Set Mode to Transmit Only Master, and Hardware NSS Signal to Disable.
|
||||
#. In the Configuration subwindow switch to Parameter Settings.
|
||||
#. Set Frame Format to Motorola, Data Size to 8 Bits, First Bit to MSB First.
|
||||
#. Set the Prescaler to the maximum value according to the LCD controller’s datasheet (e.g., 15 MBits/s). Set CPOL/CPHA as required (leave as default).
|
||||
#. Set NSSP Mode to Disabled and NSS Signal Type to Software.
|
||||
#. In DMA Settings add a new Request for SPI1_TX (when using SPI1).
|
||||
#. Set Priority to Medium, Data Width to Half Word.
|
||||
#. In NVIC Settings enable SPI1 global interrupt.
|
||||
#. In GPIO Settings set SPI1_SCK to Pull-down and Very High output speed and set the User Label to ``LCD_SCK``.
|
||||
#. Set SPI1_MOSI to Pull-up and Very High, and name it ``LCD_SDI``.
|
||||
#. Select System Core/GPIO category. In the Pinout view configure additional pins for chip select, reset and command/data select. Name them ``LCD_CS``, ``LCD_RESET`` and ``LCD_DCX``, respectively. Configure them as GPIO Output. (In this example we will use PA4 for ``LCD_CS``, PA15 for ``LCD_RESET`` and PB10 for ``LCD_DCX``.)
|
||||
#. Set ``LCD_CS`` to No pull-up and no pull-down, Low level and Very High speed.
|
||||
#. Set ``LCD_RESET`` to Pull-up and High level.
|
||||
#. Set ``LCD_DCX`` to No pull-up and no pull-down, High level and Very High speed.
|
||||
#. Open the Project Manager tab, and select Advanced Settings. On the right hand side there is a Register Callback window. Select SPI and set it to ENABLE.
|
||||
#. We are ready with the hardware configuration. Save the configuration and let STM32Cube generate the source.
|
||||
#. In the project tree clone the LVGL repository into the Middlewares/Third_Party folder (this tutorial uses the release/v9.0 branch of LVGL):
|
||||
|
||||
.. code:: dosbatch
|
||||
|
||||
git clone https://github.com/lvgl/lvgl.git -b release/v9.0
|
||||
|
||||
#. Cloning should create an 'lvgl' subfolder inside the 'Third_Party' folder. From the 'lvgl' folder copy 'lv_conf_template.h' into the 'Middlewares' folder, and rename it to 'lv_conf.h'. Refresh the project tree.
|
||||
#. Open 'lv_conf.h', and in line 15 change ``#if 0`` to ``#if 1``.
|
||||
#. Search for the string ``LV_USE_ST7735``, and enable the appropriate LCD driver by setting its value to 1. This example uses the ST7789 driver:
|
||||
|
||||
.. code:: c
|
||||
|
||||
#define LV_USE_ST7789 1
|
||||
|
||||
#. Right click the folder 'Middlewares/Third_Party/lvgl/tests', select Resource Configurations/Exclude from Build..., check both Debug and Release, then press OK.
|
||||
#. Right click the project name and select "Properties". In the C/C++ Build/Settings panel select MCU GCC Compiler/Include paths. In the Configuration dropdown select [ All configurations ]. Add the following Include path:
|
||||
|
||||
.. code:: c
|
||||
|
||||
../Middlewares/Third_Party/lvgl
|
||||
|
||||
#. Open Core/Src/stm32xxx_it.c (the file name depends on the processor variation). Add 'lv_tick.h' to the Private includes section:
|
||||
|
||||
.. code:: c
|
||||
|
||||
/* Private includes ----------------------------------------------------------*/
|
||||
/* USER CODE BEGIN Includes */
|
||||
#include "./src/tick/lv_tick.h"
|
||||
/* USER CODE END Includes */
|
||||
|
||||
#. Find the function ``TIM2_IRQHandler``. Add a call to ``lv_tick_inc()``:
|
||||
|
||||
.. code:: c
|
||||
|
||||
void TIM2_IRQHandler(void)
|
||||
{
|
||||
/* USER CODE BEGIN TIM2_IRQn 0 */
|
||||
|
||||
/* USER CODE END TIM2_IRQn 0 */
|
||||
HAL_TIM_IRQHandler(&htim2);
|
||||
/* USER CODE BEGIN TIM2_IRQn 1 */
|
||||
lv_tick_inc(1);
|
||||
/* USER CODE END TIM2_IRQn 1 */
|
||||
}
|
||||
|
||||
|
||||
#. Save the file, then open Core/Src/main.c. Add the following lines to the Private includes (if your LCD uses other than the ST7789, replace the driver path and header with the appropriate one):
|
||||
|
||||
.. code:: c
|
||||
|
||||
/* Private includes ----------------------------------------------------------*/
|
||||
/* USER CODE BEGIN Includes */
|
||||
#include "lvgl.h"
|
||||
#include "./src/drivers/display/st7789/lv_st7789.h"
|
||||
/* USER CODE END Includes */
|
||||
|
||||
#. Add the following lines to Private defines (change them according to your LCD specs):
|
||||
|
||||
.. code:: c
|
||||
|
||||
#define LCD_H_RES 240
|
||||
#define LCD_V_RES 320
|
||||
#define BUS_SPI1_POLL_TIMEOUT 0x1000U
|
||||
|
||||
|
||||
#. Add the following lines to the Private variables:
|
||||
|
||||
.. code:: c
|
||||
|
||||
osThreadId LvglTaskHandle;
|
||||
lv_display_t *lcd_disp;
|
||||
volatile int lcd_bus_busy = 0;
|
||||
|
||||
#. Add the following line to the Private function prototypes:
|
||||
|
||||
.. code:: c
|
||||
|
||||
void ui_init(lv_display_t *disp);
|
||||
void LVGL_Task(void const *argument);
|
||||
|
||||
#. Add the following lines after USER CODE BEGIN RTOS_THREADS:
|
||||
|
||||
.. code:: c
|
||||
|
||||
osThreadDef(LvglTask, LVGL_Task, osPriorityIdle, 0, 1024);
|
||||
LvglTaskHandle = osThreadCreate(osThread(LvglTask), NULL);
|
||||
|
||||
#. Copy and paste the hardware initialization and the transfer callback functions from the example code after USER CODE BEGIN 4:
|
||||
|
||||
.. code:: c
|
||||
|
||||
/* USER CODE BEGIN 4 */
|
||||
|
||||
void lcd_color_transfer_ready_cb(SPI_HandleTypeDef *hspi)
|
||||
{
|
||||
/* CS high */
|
||||
HAL_GPIO_WritePin(LCD_CS_GPIO_Port, LCD_CS_Pin, GPIO_PIN_SET);
|
||||
lcd_bus_busy = 0;
|
||||
lv_display_flush_ready(lcd_disp);
|
||||
}
|
||||
|
||||
/* Initialize LCD I/O bus, reset LCD */
|
||||
static int32_t lcd_io_init(void)
|
||||
{
|
||||
/* Register SPI Tx Complete Callback */
|
||||
HAL_SPI_RegisterCallback(&hspi1, HAL_SPI_TX_COMPLETE_CB_ID, lcd_color_transfer_ready_cb);
|
||||
|
||||
/* reset LCD */
|
||||
HAL_GPIO_WritePin(LCD_RESET_GPIO_Port, LCD_RESET_Pin, GPIO_PIN_RESET);
|
||||
HAL_Delay(100);
|
||||
HAL_GPIO_WritePin(LCD_RESET_GPIO_Port, LCD_RESET_Pin, GPIO_PIN_SET);
|
||||
HAL_Delay(100);
|
||||
|
||||
HAL_GPIO_WritePin(LCD_CS_GPIO_Port, LCD_CS_Pin, GPIO_PIN_SET);
|
||||
HAL_GPIO_WritePin(LCD_DCX_GPIO_Port, LCD_DCX_Pin, GPIO_PIN_SET);
|
||||
|
||||
return HAL_OK;
|
||||
}
|
||||
|
||||
/* Platform-specific implementation of the LCD send command function. In general this should use polling transfer. */
|
||||
static void lcd_send_cmd(lv_display_t *disp, const uint8_t *cmd, size_t cmd_size, const uint8_t *param, size_t param_size)
|
||||
{
|
||||
LV_UNUSED(disp);
|
||||
while (lcd_bus_busy); /* wait until previous transfer is finished */
|
||||
/* Set the SPI in 8-bit mode */
|
||||
hspi1.Init.DataSize = SPI_DATASIZE_8BIT;
|
||||
HAL_SPI_Init(&hspi1);
|
||||
/* DCX low (command) */
|
||||
HAL_GPIO_WritePin(LCD_DCX_GPIO_Port, LCD_DCX_Pin, GPIO_PIN_RESET);
|
||||
/* CS low */
|
||||
HAL_GPIO_WritePin(LCD_CS_GPIO_Port, LCD_CS_Pin, GPIO_PIN_RESET);
|
||||
/* send command */
|
||||
if (HAL_SPI_Transmit(&hspi1, cmd, cmd_size, BUS_SPI1_POLL_TIMEOUT) == HAL_OK) {
|
||||
/* DCX high (data) */
|
||||
HAL_GPIO_WritePin(LCD_DCX_GPIO_Port, LCD_DCX_Pin, GPIO_PIN_SET);
|
||||
/* for short data blocks we use polling transfer */
|
||||
HAL_SPI_Transmit(&hspi1, (uint8_t *)param, (uint16_t)param_size, BUS_SPI1_POLL_TIMEOUT);
|
||||
/* CS high */
|
||||
HAL_GPIO_WritePin(LCD_CS_GPIO_Port, LCD_CS_Pin, GPIO_PIN_SET);
|
||||
}
|
||||
}
|
||||
|
||||
/* Platform-specific implementation of the LCD send color function. For better performance this should use DMA transfer.
|
||||
* In case of a DMA transfer a callback must be installed to notify LVGL about the end of the transfer.
|
||||
*/
|
||||
static void lcd_send_color(lv_display_t *disp, const uint8_t *cmd, size_t cmd_size, uint8_t *param, size_t param_size)
|
||||
{
|
||||
LV_UNUSED(disp);
|
||||
while (lcd_bus_busy); /* wait until previous transfer is finished */
|
||||
/* Set the SPI in 8-bit mode */
|
||||
hspi1.Init.DataSize = SPI_DATASIZE_8BIT;
|
||||
HAL_SPI_Init(&hspi1);
|
||||
/* DCX low (command) */
|
||||
HAL_GPIO_WritePin(LCD_DCX_GPIO_Port, LCD_DCX_Pin, GPIO_PIN_RESET);
|
||||
/* CS low */
|
||||
HAL_GPIO_WritePin(LCD_CS_GPIO_Port, LCD_CS_Pin, GPIO_PIN_RESET);
|
||||
/* send command */
|
||||
if (HAL_SPI_Transmit(&hspi1, cmd, cmd_size, BUS_SPI1_POLL_TIMEOUT) == HAL_OK) {
|
||||
/* DCX high (data) */
|
||||
HAL_GPIO_WritePin(LCD_DCX_GPIO_Port, LCD_DCX_Pin, GPIO_PIN_SET);
|
||||
/* for color data use DMA transfer */
|
||||
/* Set the SPI in 16-bit mode to match endianness */
|
||||
hspi1.Init.DataSize = SPI_DATASIZE_16BIT;
|
||||
HAL_SPI_Init(&hspi1);
|
||||
lcd_bus_busy = 1;
|
||||
HAL_SPI_Transmit_DMA(&hspi1, param, (uint16_t)param_size / 2);
|
||||
/* NOTE: CS will be reset in the transfer ready callback */
|
||||
}
|
||||
}
|
||||
|
||||
#. Add the LVGL_Task() function. Replace the ``lv_st7789_create()`` call with the appropriate driver. You can change the default orientation by adjusting the parameter of ``lv_display_set_rotation()``. You will also need to create the display buffers here. This example uses a double buffering scheme with 1/10th size partial buffers. In most cases this is a good compromise between the required memory size and performance, but you are free to experiment with other settings.
|
||||
|
||||
.. code:: c
|
||||
|
||||
void LVGL_Task(void const *argument)
|
||||
{
|
||||
/* Initialize LVGL */
|
||||
lv_init();
|
||||
|
||||
/* Initialize LCD I/O */
|
||||
if (lcd_io_init() != 0)
|
||||
return;
|
||||
|
||||
/* Create the LVGL display object and the LCD display driver */
|
||||
lcd_disp = lv_st7789_create(LCD_H_RES, LCD_V_RES, LV_LCD_FLAG_NONE, lcd_send_cmd, lcd_send_color);
|
||||
lv_display_set_rotation(lcd_disp, LV_DISPLAY_ROTATION_270);
|
||||
|
||||
/* Allocate draw buffers on the heap. In this example we use two partial buffers of 1/10th size of the screen */
|
||||
lv_color_t * buf1 = NULL;
|
||||
lv_color_t * buf2 = NULL;
|
||||
|
||||
uint32_t buf_size = LCD_H_RES * LCD_V_RES / 10 * lv_color_format_get_size(lv_display_get_color_format(lcd_disp));
|
||||
|
||||
buf1 = lv_malloc(buf_size);
|
||||
if(buf1 == NULL) {
|
||||
LV_LOG_ERROR("display draw buffer malloc failed");
|
||||
return;
|
||||
}
|
||||
|
||||
buf2 = lv_malloc(buf_size);
|
||||
if(buf2 == NULL) {
|
||||
LV_LOG_ERROR("display buffer malloc failed");
|
||||
lv_free(buf1);
|
||||
return;
|
||||
}
|
||||
lv_display_set_buffers(lcd_disp, buf1, buf2, buf_size, LV_DISPLAY_RENDER_MODE_PARTIAL);
|
||||
|
||||
ui_init(lcd_disp);
|
||||
|
||||
for(;;) {
|
||||
/* The task running lv_timer_handler should have lower priority than that running `lv_tick_inc` */
|
||||
lv_timer_handler();
|
||||
/* raise the task priority of LVGL and/or reduce the handler period can improve the performance */
|
||||
osDelay(10);
|
||||
}
|
||||
}
|
||||
|
||||
#. All that's left is to implement ``ui_init()`` to create the screen. Here's a simple "Hello World" example:
|
||||
|
||||
.. code:: c
|
||||
|
||||
void ui_init(lv_display_t *disp)
|
||||
{
|
||||
lv_obj_t *obj;
|
||||
|
||||
/* set screen background to white */
|
||||
lv_obj_t *scr = lv_screen_active();
|
||||
lv_obj_set_style_bg_color(scr, lv_color_white(), 0);
|
||||
lv_obj_set_style_bg_opa(scr, LV_OPA_100, 0);
|
||||
|
||||
/* create label */
|
||||
obj = lv_label_create(scr);
|
||||
lv_obj_set_align(obj, LV_ALIGN_CENTER);
|
||||
lv_obj_set_height(obj, LV_SIZE_CONTENT);
|
||||
lv_obj_set_width(obj, LV_SIZE_CONTENT);
|
||||
lv_obj_set_style_text_font(obj, &lv_font_montserrat_14, 0);
|
||||
lv_obj_set_style_text_color(obj, lv_color_black(), 0);
|
||||
lv_label_set_text(obj, "Hello World!");
|
||||
}
|
||||
|
||||
@@ -0,0 +1,82 @@
|
||||
.. _renesas_glcdc:
|
||||
|
||||
=============
|
||||
Renesas GLCDC
|
||||
=============
|
||||
|
||||
Overview
|
||||
--------
|
||||
|
||||
.. image:: /misc/renesas/glcdc.png
|
||||
:alt: Architectural overview of Renesas GLCDC
|
||||
:align: center
|
||||
|
||||
|
|
||||
|
||||
GLCDC is a multi-stage graphics output peripheral used in Renesas MCUs.
|
||||
It is designed to automatically generate timing and data signals for different LCD panels.
|
||||
|
||||
- Supports LCD panels with RGB interface (up to 24 bits) and sync signals (HSYNC, VSYNC and Data Enable optional)
|
||||
- Supports various color formats for input graphics planes (RGB888, ARGB8888, RGB565, ARGB1555, ARGB4444, CLUT8, CLUT4, CLUT1)
|
||||
- Supports the Color Look-Up Table (CLUT) usage for input graphics planes (ARGB8888) with 512 words (32 bits/word)
|
||||
- Supports various color formats for output (RGB888, RGB666, RGB565, Serial RGB888)
|
||||
- Can input two graphics planes on top of the background plane and blend them on the screen
|
||||
- Generates a dot clock to the panel. The clock source is selectable from internal or external (LCD_EXTCLK)
|
||||
- Supports brightness adjustment, contrast adjustment, and gamma correction
|
||||
- Supports GLCDC interrupts to handle frame-buffer switching or underflow detection
|
||||
|
||||
| Setting up a project and further integration with Renesas' ecosystem is described in detail on :ref:`page Renesas <renesas>`.
|
||||
| Check out the following repositories for ready-to-use examples:
|
||||
- `EK-RA8D1 <https://github.com/lvgl/lv_port_renesas_ek-ra8d1>`__
|
||||
- `EK-RA6M3G <https://github.com/lvgl/lv_port_renesas_ek-ra6m3g>`__
|
||||
- `RX72N Envision Kit <https://github.com/lvgl/lv_port_renesas_rx72n-envision-kit>`__
|
||||
|
||||
Prerequisites
|
||||
-------------
|
||||
|
||||
- This diver relies on code generated by e² studio. Missing the step while setting up the project will cause a compilation error.
|
||||
- Activate the diver by setting :c:macro:`LV_USE_RENESAS_GLCDC` to ``1`` in your *"lv_conf.h"*.
|
||||
|
||||
Usage
|
||||
-----
|
||||
|
||||
There is no need to implement any platform-specific functions.
|
||||
|
||||
The following code demonstrates using the diver in :cpp:enumerator:`LV_DISPLAY_RENDER_MODE_DIRECT` mode.
|
||||
|
||||
.. code:: c
|
||||
|
||||
lv_display_t * disp = lv_renesas_glcdc_direct_create();
|
||||
lv_display_set_default(disp);
|
||||
|
||||
To use the driver in :cpp:enumerator:`LV_DISPLAY_RENDER_MODE_PARTIAL` mode, an extra buffer must be allocated,
|
||||
preferably in the fastest available memory region.
|
||||
|
||||
Buffer swapping can be activated by passing a second buffer of same size instead of the :cpp:expr:`NULL` argument.
|
||||
|
||||
.. code:: c
|
||||
|
||||
static lv_color_t partial_draw_buf[DISPLAY_HSIZE_INPUT0 * DISPLAY_VSIZE_INPUT0 / 10] BSP_PLACE_IN_SECTION(".sdram") BSP_ALIGN_VARIABLE(1024);
|
||||
|
||||
lv_display_t * disp = lv_renesas_glcdc_partial_create(partial_draw_buf, NULL, sizeof(partial_draw_buf));
|
||||
lv_display_set_default(disp);
|
||||
|
||||
.. note::
|
||||
|
||||
Partial mode can be activated via the macro in ``src/board_init.c`` file of the demo projects.
|
||||
|
||||
|
||||
Screen rotation
|
||||
"""""""""""""""
|
||||
|
||||
Software based screen rotation is supported in partial mode. It uses the common API, no extra configuration is required:
|
||||
|
||||
.. code:: c
|
||||
|
||||
lv_display_set_rotation(lv_display_get_default(), LV_DISP_ROTATION_90);
|
||||
/* OR */
|
||||
lv_display_set_rotation(lv_display_get_default(), LV_DISP_ROTATION_180);
|
||||
/* OR */
|
||||
lv_display_set_rotation(lv_display_get_default(), LV_DISP_ROTATION_270);
|
||||
|
||||
Make sure the heap is large enough, as a buffer with the same size as the partial buffer will be allocated.
|
||||
75
libraries/lvgl/docs/integration/driver/display/st7735.rst
Normal file
@@ -0,0 +1,75 @@
|
||||
============================
|
||||
ST7735 LCD Controller driver
|
||||
============================
|
||||
|
||||
Overview
|
||||
--------
|
||||
|
||||
The `ST7735S <https://www.buydisplay.com/download/ic/ST7735S.pdf>`__ is a single-chip controller/driver for 262K-color, graphic type TFT-LCD. It consists of 396
|
||||
source line and 162 gate line driving circuits. This chip is capable of connecting directly to an external
|
||||
microprocessor, and accepts Serial Peripheral Interface (SPI), 8-bit/9-bit/16-bit/18-bit parallel interface.
|
||||
Display data can be stored in the on-chip display data RAM of 132 x 162 x 18 bits. It can perform display data
|
||||
RAM read/write operation with no external operation clock to minimize power consumption. In addition,
|
||||
because of the integrated power supply circuits necessary to drive liquid crystal, it is possible to make a
|
||||
display system with fewer components.
|
||||
|
||||
The ST7735 LCD controller `driver <https://github.com/lvgl/lvgl/src/drivers/display/st7735>`__ is a platform-agnostic driver, based on the `generic MIPI driver <https://github.com/lvgl/lvgl/doc/integration/drivers/display/gen_mipi.rst>`__.
|
||||
It implements display initialization, supports display rotation and implements the display flush callback. The user needs to implement only two platform-specific functions to send
|
||||
a command or pixel data to the controller via SPI or parallel bus. Typically these are implemented by calling the appropriate SDK library functions on the given platform.
|
||||
|
||||
Prerequisites
|
||||
-------------
|
||||
|
||||
There are no prerequisites.
|
||||
|
||||
Configuring the driver
|
||||
----------------------
|
||||
|
||||
Enable the ST7735 driver support in lv_conf.h, by cmake compiler define or by KConfig
|
||||
|
||||
.. code:: c
|
||||
|
||||
#define LV_USE_ST7735 1
|
||||
|
||||
Usage
|
||||
-----
|
||||
|
||||
You need to implement two platform-dependent functions:
|
||||
|
||||
.. code:: c
|
||||
|
||||
/* Send short command to the LCD. This function shall wait until the transaction finishes. */
|
||||
int32_t my_lcd_send_cmd(lv_display_t *disp, const uint8_t *cmd, size_t cmd_size, const uint8_t *param, size_t param_size)
|
||||
{
|
||||
...
|
||||
}
|
||||
|
||||
/* Send large array of pixel data to the LCD. If necessary, this function has to do the byte-swapping. This function can do the transfer in the background. */
|
||||
int32_t my_lcd_send_color(lv_display_t *disp, const uint8_t *cmd, size_t cmd_size, uint8_t *param, size_t param_size)
|
||||
{
|
||||
...
|
||||
}
|
||||
|
||||
To create an ST7735-based display use the function
|
||||
|
||||
.. code:: c
|
||||
|
||||
/**
|
||||
* Create an LCD display with ST7735 driver
|
||||
* @param hor_res horizontal resolution
|
||||
* @param ver_res vertical resolution
|
||||
* @param flags default configuration settings (mirror, RGB ordering, etc.)
|
||||
* @param send_cmd platform-dependent function to send a command to the LCD controller (usually uses polling transfer)
|
||||
* @param send_color platform-dependent function to send pixel data to the LCD controller (usually uses DMA transfer: must implement a 'ready' callback)
|
||||
* @return pointer to the created display
|
||||
*/
|
||||
lv_display_t * lv_st7735_create(uint32_t hor_res, uint32_t ver_res, lv_lcd_flag_t flags,
|
||||
lv_st7735_send_cmd_cb_t send_cmd_cb, lv_st7735_send_color_cb_t send_color_cb);
|
||||
|
||||
|
||||
For additional details and a working example see the `generic MIPI driver documentation <https://github.com/lvgl/lvgl/doc/integration/drivers/display/gen_mipi.rst>`__.
|
||||
|
||||
.. note::
|
||||
|
||||
You can find a step-by-step guide and the actual implementation of the callbacks on an STM32F746 using STM32CubeIDE and the ST HAL libraries here: :ref:`lcd_stm32_guide`
|
||||
|
||||
74
libraries/lvgl/docs/integration/driver/display/st7789.rst
Normal file
@@ -0,0 +1,74 @@
|
||||
============================
|
||||
ST7789 LCD Controller driver
|
||||
============================
|
||||
|
||||
Overview
|
||||
--------
|
||||
|
||||
The `ST7789 <https://www.buydisplay.com/download/ic/ST7789.pdf>`__ is a single-chip controller/driver for 262K-color, graphic type TFT-LCD. It consists of 720
|
||||
source line and 320 gate line driving circuits. This chip is capable of connecting directly to an external
|
||||
microprocessor, and accepts, 8-bits/9-bits/16-bits/18-bits parallel interface. Display data can be stored in the
|
||||
on-chip display data RAM of 240x320x18 bits. It can perform display data RAM read/write operation with no
|
||||
external operation clock to minimize power consumption. In addition, because of the integrated power supply
|
||||
circuit necessary to drive liquid crystal; it is possible to make a display system with the fewest components.
|
||||
|
||||
The ST7789 LCD controller `driver <https://github.com/lvgl/lvgl/src/drivers/display/st7789>`__ is a platform-agnostic driver, based on the `generic MIPI driver <https://github.com/lvgl/lvgl/doc/integration/drivers/display/gen_mipi.rst>`__.
|
||||
It implements display initialization, supports display rotation and implements the display flush callback. The user needs to implement only two platform-specific functions to send
|
||||
a command or pixel data to the controller via SPI or parallel bus. Typically these are implemented by calling the appropriate SDK library functions on the given platform.
|
||||
|
||||
Prerequisites
|
||||
-------------
|
||||
|
||||
There are no prerequisites.
|
||||
|
||||
Configuring the driver
|
||||
----------------------
|
||||
|
||||
Enable the ST7789 driver support in lv_conf.h, by cmake compiler define or by KConfig
|
||||
|
||||
.. code:: c
|
||||
|
||||
#define LV_USE_ST7789 1
|
||||
|
||||
Usage
|
||||
-----
|
||||
|
||||
You need to implement two platform-dependent functions:
|
||||
|
||||
.. code:: c
|
||||
|
||||
/* Send short command to the LCD. This function shall wait until the transaction finishes. */
|
||||
int32_t my_lcd_send_cmd(lv_display_t *disp, const uint8_t *cmd, size_t cmd_size, const uint8_t *param, size_t param_size)
|
||||
{
|
||||
...
|
||||
}
|
||||
|
||||
/* Send large array of pixel data to the LCD. If necessary, this function has to do the byte-swapping. This function can do the transfer in the background. */
|
||||
int32_t my_lcd_send_color(lv_display_t *disp, const uint8_t *cmd, size_t cmd_size, uint8_t *param, size_t param_size)
|
||||
{
|
||||
...
|
||||
}
|
||||
|
||||
To create an ST7789-based display use the function
|
||||
|
||||
.. code:: c
|
||||
|
||||
/**
|
||||
* Create an LCD display with ST7789 driver
|
||||
* @param hor_res horizontal resolution
|
||||
* @param ver_res vertical resolution
|
||||
* @param flags default configuration settings (mirror, RGB ordering, etc.)
|
||||
* @param send_cmd platform-dependent function to send a command to the LCD controller (usually uses polling transfer)
|
||||
* @param send_color platform-dependent function to send pixel data to the LCD controller (usually uses DMA transfer: must implement a 'ready' callback)
|
||||
* @return pointer to the created display
|
||||
*/
|
||||
lv_display_t * lv_st7789_create(uint32_t hor_res, uint32_t ver_res, lv_lcd_flag_t flags,
|
||||
lv_st7789_send_cmd_cb_t send_cmd_cb, lv_st7789_send_color_cb_t send_color_cb);
|
||||
|
||||
|
||||
For additional details and a working example see the `generic MIPI driver documentation <https://github.com/lvgl/lvgl/doc/integration/drivers/display/gen_mipi.rst>`__.
|
||||
|
||||
.. note::
|
||||
|
||||
You can find a step-by-step guide and the actual implementation of the callbacks on an STM32F746 using STM32CubeIDE and the ST HAL libraries here: :ref:`lcd_stm32_guide`
|
||||
|
||||
75
libraries/lvgl/docs/integration/driver/display/st7796.rst
Normal file
@@ -0,0 +1,75 @@
|
||||
============================
|
||||
ST7796 LCD Controller driver
|
||||
============================
|
||||
|
||||
Overview
|
||||
--------
|
||||
|
||||
The `ST7796S <https://www.buydisplay.com/download/ic/ST7796S.pdf>`__ is a single-chip controller/driver for 262K-color, graphic type TFT-LCD. It consists of 960
|
||||
source lines and 480 gate lines driving circuits. The ST7796S is capable of connecting directly to an external
|
||||
microprocessor, and accepts 8-bit/9-bit/16-bit/18-bit parallel interface, SPI, and the ST7796S also provides
|
||||
MIPI interface. Display data can be stored in the on-chip display data RAM of 320x480x18 bits. It can perform
|
||||
display data RAM read-/write-operation with no external clock to minimize power consumption. In addition,
|
||||
because of the integrated power supply circuit necessary to drive liquid crystal; it is possible to make a display
|
||||
system with fewest components.
|
||||
|
||||
The ST7796 LCD controller `driver <https://github.com/lvgl/lvgl/src/drivers/display/st7796>`__ is a platform-agnostic driver, based on the `generic MIPI driver <https://github.com/lvgl/lvgl/doc/integration/drivers/display/gen_mipi.rst>`__.
|
||||
It implements display initialization, supports display rotation and implements the display flush callback. The user needs to implement only two platform-specific functions to send
|
||||
a command or pixel data to the controller via SPI or parallel bus. Typically these are implemented by calling the appropriate SDK library functions on the given platform.
|
||||
|
||||
Prerequisites
|
||||
-------------
|
||||
|
||||
There are no prerequisites.
|
||||
|
||||
Configuring the driver
|
||||
----------------------
|
||||
|
||||
Enable the ST7796 driver support in lv_conf.h, by cmake compiler define or by KConfig
|
||||
|
||||
.. code:: c
|
||||
|
||||
#define LV_USE_ST7796 1
|
||||
|
||||
Usage
|
||||
-----
|
||||
|
||||
You need to implement two platform-dependent functions:
|
||||
|
||||
.. code:: c
|
||||
|
||||
/* Send short command to the LCD. This function shall wait until the transaction finishes. */
|
||||
int32_t my_lcd_send_cmd(lv_display_t *disp, const uint8_t *cmd, size_t cmd_size, const uint8_t *param, size_t param_size)
|
||||
{
|
||||
...
|
||||
}
|
||||
|
||||
/* Send large array of pixel data to the LCD. If necessary, this function has to do the byte-swapping. This function can do the transfer in the background. */
|
||||
int32_t my_lcd_send_color(lv_display_t *disp, const uint8_t *cmd, size_t cmd_size, uint8_t *param, size_t param_size)
|
||||
{
|
||||
...
|
||||
}
|
||||
|
||||
To create an ST7796-based display use the function
|
||||
|
||||
.. code:: c
|
||||
|
||||
/**
|
||||
* Create an LCD display with ST7796 driver
|
||||
* @param hor_res horizontal resolution
|
||||
* @param ver_res vertical resolution
|
||||
* @param flags default configuration settings (mirror, RGB ordering, etc.)
|
||||
* @param send_cmd platform-dependent function to send a command to the LCD controller (usually uses polling transfer)
|
||||
* @param send_color platform-dependent function to send pixel data to the LCD controller (usually uses DMA transfer: must implement a 'ready' callback)
|
||||
* @return pointer to the created display
|
||||
*/
|
||||
lv_display_t * lv_st7796_create(uint32_t hor_res, uint32_t ver_res, lv_lcd_flag_t flags,
|
||||
lv_st7796_send_cmd_cb_t send_cmd_cb, lv_st7796_send_color_cb_t send_color_cb);
|
||||
|
||||
|
||||
For additional details and a working example see the `generic MIPI driver documentation <https://github.com/lvgl/lvgl/doc/integration/drivers/display/gen_mipi.rst>`__.
|
||||
|
||||
.. note::
|
||||
|
||||
You can find a step-by-step guide and the actual implementation of the callbacks on an STM32F746 using STM32CubeIDE and the ST HAL libraries here: :ref:`lcd_stm32_guide`
|
||||
|
||||
14
libraries/lvgl/docs/integration/driver/index.rst
Normal file
@@ -0,0 +1,14 @@
|
||||
=======
|
||||
Drivers
|
||||
=======
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 2
|
||||
|
||||
display/index
|
||||
touchpad/index
|
||||
libinput
|
||||
X11
|
||||
windows
|
||||
opengles
|
||||
wayland
|
||||
87
libraries/lvgl/docs/integration/driver/libinput.rst
Normal file
@@ -0,0 +1,87 @@
|
||||
===============
|
||||
Libinput Driver
|
||||
===============
|
||||
|
||||
Overview
|
||||
--------
|
||||
|
||||
Libinput is an input stack for processes that need to provide events from commonly used input devices. That includes mice, keyboards, touchpads,
|
||||
touchscreens and graphics tablets. Libinput handles device-specific quirks and provides an easy-to-use API to receive events from devices.
|
||||
|
||||
Prerequisites
|
||||
-------------
|
||||
|
||||
You have the development version of libinput installed (usually ``libinput-dev``). If your input device requires quirks, make sure they are
|
||||
installed as well (usually in ``/usr/share/libinput/*.quirks``). To test if your device is set up correctly for use with libinput, you can
|
||||
run ``libinput list-devices``.
|
||||
|
||||
.. code:: console
|
||||
|
||||
$ sudo libinput list-devices
|
||||
...
|
||||
Device: ETPS/2 Elantech Touchpad
|
||||
Kernel: /dev/input/event5
|
||||
Group: 10
|
||||
Seat: seat0, default
|
||||
Size: 102x74mm
|
||||
Capabilities: pointer gesture
|
||||
Tap-to-click: disabled
|
||||
Tap-and-drag: enabled
|
||||
...
|
||||
|
||||
If your device doesn't show up, you may have to configure udev and the appropriate udev rules to connect it.
|
||||
|
||||
Additionally, if you want full keyboard support, including letters and modifiers, you'll need the development version of libxkbcommon
|
||||
installed (usually ``libxkbcommon-dev``).
|
||||
|
||||
Configuring the driver
|
||||
----------------------
|
||||
|
||||
Enable the libinput driver support in lv_conf.h, by cmake compiler define or by KConfig.
|
||||
|
||||
.. code:: c
|
||||
|
||||
#define LV_USE_LIBINPUT 1
|
||||
|
||||
Full keyboard support needs to be enabled separately.
|
||||
|
||||
.. code:: c
|
||||
|
||||
#define LV_LIBINPUT_XKB 1
|
||||
#define LV_LIBINPUT_XKB_KEY_MAP { .rules = NULL, .model = "pc101", .layout = "us", .variant = NULL, .options = NULL }
|
||||
|
||||
To find the right key map values, you may use the ``setxkbmap -query`` command.
|
||||
|
||||
Usage
|
||||
-----
|
||||
|
||||
To set up an input device via the libinput driver, all you need to do is call ``lv_libinput_create`` with the respective device type
|
||||
(``LV_INDEV_TYPE_POINTER`` or ``LV_INDEV_TYPE_KEYPAD``) and device node path (e.g. ``/dev/input/event5``).
|
||||
|
||||
.. code:: c
|
||||
|
||||
lv_indev_t *indev = lv_libinput_create(LV_INDEV_TYPE_POINTER, "/dev/input/event5");
|
||||
|
||||
Note that touchscreens are treated as (absolute) pointer devices by the libinput driver and require ``LV_INDEV_TYPE_POINTER``.
|
||||
|
||||
Depending on your system, the device node paths might not be stable across reboots. If this is the case, you can use ``lv_libinput_find_dev``
|
||||
to find the first device that has a specific capability.
|
||||
|
||||
.. code:: c
|
||||
|
||||
char *path = lv_libinput_find_dev(LV_LIBINPUT_CAPABILITY_TOUCH, true);
|
||||
|
||||
The second argument controls whether or not all devices are rescanned. If you have many devices connected this can get quite slow.
|
||||
Therefore, you should only specify ``true`` on the first call when calling this method multiple times in a row. If you want to find
|
||||
all devices that have a specific capability, use ``lv_libinput_find_devs``.
|
||||
|
||||
If you want to connect a keyboard device to a textarea, create a dedicated input group and set it on both the indev and textarea.
|
||||
|
||||
.. code:: c
|
||||
|
||||
lv_obj_t *textarea = lv_textarea_create(...);
|
||||
...
|
||||
lv_group_t *keyboard_input_group = lv_group_create();
|
||||
lv_indev_set_group(indev, keyboard_input_group);
|
||||
lv_group_add_obj(keyboard_input_group, textarea);
|
||||
|
||||
197
libraries/lvgl/docs/integration/driver/opengles.rst
Normal file
@@ -0,0 +1,197 @@
|
||||
===============================
|
||||
OpenGL ES Display/Inputs driver
|
||||
===============================
|
||||
|
||||
Overview
|
||||
--------
|
||||
|
||||
| The **OpenGL ES** display/input `driver <https://github.com/lvgl/lvgl/src/drivers/opengles>`__ offers support for simulating the LVGL display and keyboard/mouse inputs in an desktop window created via GLFW.
|
||||
| It is an alternative to **Wayland**, **XCB**, **SDL** or **Qt**.
|
||||
|
||||
The main purpose for this driver is for testing/debugging the LVGL application in an **OpenGL** simulation window.
|
||||
|
||||
Prerequisites
|
||||
-------------
|
||||
|
||||
The OpenGL driver uses GLEW GLFW to access the OpenGL window manager.
|
||||
|
||||
1. Install GLEW and GLFW: ``sudo apt-get install libglew-dev libglfw3-dev``
|
||||
|
||||
Configure OpenGL driver
|
||||
-----------------------
|
||||
|
||||
1. Required linked libraries: -lGL -lGLEW -lglfw
|
||||
2. Enable the OpenGL driver support in lv_conf.h, by cmake compiler define or by KConfig
|
||||
.. code:: c
|
||||
|
||||
#define LV_USE_OPENGLES 1
|
||||
|
||||
Basic usage
|
||||
-----------
|
||||
|
||||
.. code:: c
|
||||
|
||||
#include "lvgl/lvgl.h"
|
||||
#include "lvgl/examples/lv_examples.h"
|
||||
#include "lvgl/demos/lv_demos.h"
|
||||
|
||||
#define WIDTH 640
|
||||
#define HEIGHT 480
|
||||
|
||||
int main()
|
||||
{
|
||||
/* initialize lvgl */
|
||||
lv_init();
|
||||
|
||||
/* create a window and initialize OpenGL */
|
||||
lv_glfw_window_t * window = lv_glfw_window_create(WIDTH, HEIGHT, true);
|
||||
|
||||
/* create a display that flushes to a texture */
|
||||
lv_display_t * texture = lv_opengles_texture_create(WIDTH, HEIGHT);
|
||||
lv_display_set_default(texture);
|
||||
|
||||
/* add the texture to the window */
|
||||
unsigned int texture_id = lv_opengles_texture_get_texture_id(texture);
|
||||
lv_glfw_texture_t * window_texture = lv_glfw_window_add_texture(window, texture_id, WIDTH, HEIGHT);
|
||||
|
||||
/* get the mouse indev of the window texture */
|
||||
lv_indev_t * mouse = lv_glfw_texture_get_mouse_indev(window_texture);
|
||||
|
||||
/* add a cursor to the mouse indev */
|
||||
LV_IMAGE_DECLARE(mouse_cursor_icon);
|
||||
lv_obj_t * cursor_obj = lv_image_create(lv_screen_active());
|
||||
lv_image_set_src(cursor_obj, &mouse_cursor_icon);
|
||||
lv_indev_set_cursor(mouse, cursor_obj);
|
||||
|
||||
/* create objects on the screen */
|
||||
lv_demo_widgets();
|
||||
|
||||
while (1)
|
||||
{
|
||||
uint32_t time_until_next = lv_timer_handler();
|
||||
lv_delay_ms(time_until_next);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
Advanced usage
|
||||
--------------
|
||||
|
||||
The OpenGL driver can draw textures from the user. A third-party library could be
|
||||
used to add content to a texture and the driver will draw the texture in the window.
|
||||
|
||||
.. code:: c
|
||||
|
||||
#include "lvgl/lvgl.h"
|
||||
#include <GL/glew.h>
|
||||
#include <GLFW/glfw3.h>
|
||||
|
||||
#define WIDTH 640
|
||||
#define HEIGHT 480
|
||||
|
||||
void custom_texture_example(void)
|
||||
{
|
||||
/*****************
|
||||
* MAIN WINDOW
|
||||
*****************/
|
||||
|
||||
/* create a window and initialize OpenGL */
|
||||
/* multiple windows can be created */
|
||||
lv_glfw_window_t * window = lv_glfw_window_create(WIDTH, HEIGHT, true);
|
||||
|
||||
/****************************
|
||||
* OPTIONAL MAIN TEXTURE
|
||||
****************************/
|
||||
|
||||
/* create a main display that flushes to a texture */
|
||||
lv_display_t * main_texture = lv_opengles_texture_create(WIDTH, HEIGHT);
|
||||
lv_display_set_default(main_texture);
|
||||
|
||||
/* add the main texture to the window */
|
||||
unsigned int main_texture_id = lv_opengles_texture_get_texture_id(main_texture);
|
||||
lv_glfw_texture_t * window_main_texture = lv_glfw_window_add_texture(window, main_texture_id, WIDTH, HEIGHT);
|
||||
|
||||
/* get the mouse indev of this main texture */
|
||||
lv_indev_t * main_texture_mouse = lv_glfw_texture_get_mouse_indev(window_main_texture);
|
||||
|
||||
/* add a cursor to the mouse indev */
|
||||
LV_IMAGE_DECLARE(mouse_cursor_icon);
|
||||
lv_obj_t * cursor_obj = lv_image_create(lv_screen_active());
|
||||
lv_image_set_src(cursor_obj, &mouse_cursor_icon);
|
||||
lv_indev_set_cursor(main_texture_mouse, cursor_obj);
|
||||
|
||||
/* create objects on the screen of the main texture */
|
||||
lv_demo_widgets();
|
||||
|
||||
/**********************
|
||||
* ANOTHER TEXTURE
|
||||
**********************/
|
||||
|
||||
/* create a sub display that flushes to a texture */
|
||||
const int32_t sub_texture_w = 300;
|
||||
const int32_t sub_texture_h = 300;
|
||||
lv_display_t * sub_texture = lv_opengles_texture_create(sub_texture_w, sub_texture_h);
|
||||
|
||||
/* add the sub texture to the window */
|
||||
unsigned int sub_texture_id = lv_opengles_texture_get_texture_id(sub_texture);
|
||||
lv_glfw_texture_t * window_sub_texture = lv_glfw_window_add_texture(window, sub_texture_id, sub_texture_w, sub_texture_h);
|
||||
|
||||
/* create objects on the screen of the sub texture */
|
||||
lv_display_set_default(sub_texture);
|
||||
lv_obj_set_style_bg_color(lv_screen_active(), lv_color_black(), 0);
|
||||
lv_example_anim_2();
|
||||
lv_display_set_default(main_texture);
|
||||
|
||||
/* position the sub texture within the window */
|
||||
lv_glfw_texture_set_x(window_sub_texture, 250);
|
||||
lv_glfw_texture_set_y(window_sub_texture, 150);
|
||||
|
||||
/* optionally change the opacity of the sub texture */
|
||||
lv_glfw_texture_set_opa(window_sub_texture, LV_OPA_80);
|
||||
|
||||
/*********************************************
|
||||
* USE AN EXTERNAL OPENGL TEXTURE IN LVGL
|
||||
*********************************************/
|
||||
|
||||
unsigned int external_texture_id;
|
||||
glGenTextures(1, &external_texture_id);
|
||||
glBindTexture(GL_TEXTURE_2D, external_texture_id);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
|
||||
LV_IMAGE_DECLARE(img_cogwheel_argb);
|
||||
#if LV_COLOR_DEPTH == 8
|
||||
const int texture_format = GL_R8;
|
||||
#elif LV_COLOR_DEPTH == 16
|
||||
const int texture_format = GL_RGB565;
|
||||
#elif LV_COLOR_DEPTH == 24
|
||||
const int texture_format = GL_RGB;
|
||||
#elif LV_COLOR_DEPTH == 32
|
||||
const int texture_format = GL_RGBA;
|
||||
#else
|
||||
#error("Unsupported color format")
|
||||
#endif
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, texture_format, img_cogwheel_argb.header.w, img_cogwheel_argb.header.h, 0, GL_BGRA, GL_UNSIGNED_BYTE, img_cogwheel_argb.data);
|
||||
glGenerateMipmap(GL_TEXTURE_2D);
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
|
||||
/* add the external texture to the window */
|
||||
lv_glfw_texture_t * window_external_texture = lv_glfw_window_add_texture(window, external_texture_id, img_cogwheel_argb.header.w, img_cogwheel_argb.header.h);
|
||||
|
||||
/* set the position and opacity of the external texture within the window */
|
||||
lv_glfw_texture_set_x(window_external_texture, 20);
|
||||
lv_glfw_texture_set_y(window_external_texture, 20);
|
||||
lv_glfw_texture_set_opa(window_external_texture, LV_OPA_70);
|
||||
|
||||
/*********************************************
|
||||
* USE AN LVGL TEXTURE IN ANOTHER LIBRARY
|
||||
*********************************************/
|
||||
|
||||
lv_refr_now(sub_texture);
|
||||
|
||||
/* the texture is drawn on by LVGL and can be used by anything that uses OpenGL textures */
|
||||
third_party_lib_use_texture(sub_texture_id);
|
||||
}
|
||||
57
libraries/lvgl/docs/integration/driver/touchpad/evdev.rst
Normal file
@@ -0,0 +1,57 @@
|
||||
==================
|
||||
Linux Evdev Driver
|
||||
==================
|
||||
|
||||
Overview
|
||||
--------
|
||||
|
||||
The Linux event device (evdev) is a hardware-independent API that gives access to input events from,
|
||||
for example, a mouse or touchscreen. It is exposed via the Linux device file system interface.
|
||||
|
||||
Prerequisites
|
||||
-------------
|
||||
|
||||
Your system has an input device configured (usually under ``/dev/input/`` such as ``/dev/input/event0``).
|
||||
|
||||
Configuring the driver
|
||||
----------------------
|
||||
|
||||
Enable the Linux LVGL evdev driver support in ``lv_conf.h``.
|
||||
|
||||
.. code:: c
|
||||
|
||||
#define LV_USE_EVDEV 1
|
||||
|
||||
Usage
|
||||
-----
|
||||
|
||||
To set up an event input, first create an input device with ``lv_edev_create`` setting it to the correct Linux event device.
|
||||
Then link this to the LVGL display with ``lv_indev_set_display``.
|
||||
|
||||
.. code:: c
|
||||
|
||||
lv_indev_t *touch = lv_evdev_create(LV_INDEV_TYPE_POINTER, "/dev/input/event0");
|
||||
lv_indev_set_display(touch, disp);
|
||||
|
||||
Ensure that an ``lv_display_t`` object is already created for ``disp``. An example for this is shown below, using the Linux framebuffer driver.
|
||||
|
||||
.. code:: c
|
||||
|
||||
lv_display_t * disp = lv_linux_fbdev
|
||||
lv_linux_fbdev_set_file(disp, "/dev/fb0");_create();
|
||||
|
||||
|
||||
Locating your input device
|
||||
--------------------------
|
||||
|
||||
If you can't determine your input device, first run
|
||||
|
||||
```$cat /proc/bus/input/devices```
|
||||
|
||||
This should show input devices and there will be entries with the word ``event`` which give a clue as to the device to use eg. ``event1`` would be ``/dev/input/event1``.
|
||||
|
||||
You can use ``evtest`` to show data from that event source to see if it is actually the one you want.
|
||||
|
||||
Try:
|
||||
|
||||
``$evtest /dev/input/event1`` replacing ``eventX`` with your event device from above.
|
||||
@@ -0,0 +1,5 @@
|
||||
======
|
||||
FT6X36
|
||||
======
|
||||
|
||||
TODO
|
||||
@@ -0,0 +1,9 @@
|
||||
=======
|
||||
Touchpad
|
||||
=======
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 2
|
||||
|
||||
ft6x36
|
||||
evdev
|
||||
180
libraries/lvgl/docs/integration/driver/wayland.rst
Normal file
@@ -0,0 +1,180 @@
|
||||
=============================
|
||||
Wayland Display/Inputs driver
|
||||
=============================
|
||||
|
||||
Overview
|
||||
--------
|
||||
|
||||
| The **Wayland** `driver <https://github.com/lvgl/lvgl/tree/master/src/drivers/wayland>`__ offers support for simulating the LVGL display and keyboard/mouse inputs in a desktop window.
|
||||
| It is an alternative to **X11** or **SDL2**
|
||||
|
||||
The main purpose for this driver is for testing/debugging the LVGL application, it can also be used to run applications in 'kiosk mode'
|
||||
|
||||
Dependencies
|
||||
------------
|
||||
|
||||
The wayland driver requires some dependencies.
|
||||
|
||||
On Ubuntu
|
||||
|
||||
.. code:: bash
|
||||
|
||||
sudo apt-get install libwayland-dev libxkbcommon-dev libwayland-bin wayland-protocols
|
||||
|
||||
On Fedora
|
||||
|
||||
.. code:: bash
|
||||
|
||||
sudo dnf install wayland-devel libxkbcommon-devel wayland-utils wayland-protocols-devel
|
||||
|
||||
|
||||
Configuring the wayland driver
|
||||
------------------------------
|
||||
|
||||
1. Enable the wayland driver in ``lv_conf.h``
|
||||
|
||||
.. code:: c
|
||||
|
||||
#define LV_USE_WAYLAND 1
|
||||
|
||||
2. Optional configuration options:
|
||||
|
||||
- Enable window decorations, only required on GNOME because out of all the available wayland compositors
|
||||
**only** Mutter/GNOME enforces the use of client side decorations
|
||||
|
||||
.. code:: c
|
||||
|
||||
#define LV_WAYLAND_WINDOW_DECORATIONS 1
|
||||
|
||||
- Enable support for the deprecated 'wl_shell', Only useful when the BSP on the target has weston ``9.x``
|
||||
|
||||
.. code:: c
|
||||
|
||||
#define LV_WAYLAND_WL_SHELL 1
|
||||
|
||||
Example
|
||||
-------
|
||||
|
||||
An example simulator is available in this `repo <https://github.com/lvgl/lv_port_linux/>`__
|
||||
|
||||
Usage
|
||||
-----
|
||||
|
||||
#. In ``main.c`` ``#incude "lv_drivers/wayland/wayland.h"``
|
||||
#. Enable the Wayland driver in ``lv_conf.h`` with ``LV_USE_WAYLAND 1``
|
||||
|
||||
#. ``LV_COLOR_DEPTH`` should be set either to ``32`` or ``16`` in ``lv_conf.h``
|
||||
|
||||
#. Add a display using ``lv_wayland_window_create()``,
|
||||
possibly with a close callback to track the status of each display:
|
||||
|
||||
.. code:: c
|
||||
|
||||
#define H_RES (800)
|
||||
#define V_RES (480)
|
||||
|
||||
/* Create a display */
|
||||
lv_disp_t * disp = lv_wayland_create_window(H_RES, V_RES, "Window Title", close_cb);
|
||||
|
||||
|
||||
As part of the above call, the Wayland driver will register four input devices
|
||||
for each display:
|
||||
|
||||
* a KEYPAD connected to Wayland keyboard events
|
||||
* a POINTER connected to Wayland touch events
|
||||
* a POINTER connected to Wayland pointer events
|
||||
* an ENCODER connected to Wayland pointer axis events
|
||||
|
||||
Handles for input devices of each display can be obtained using
|
||||
``lv_wayland_get_indev_keyboard()``, ``lv_wayland_get_indev_touchscreen()``,
|
||||
``lv_wayland_get_indev_pointer()`` and ``lv_wayland_get_indev_pointeraxis()`` respectively.
|
||||
|
||||
Fullscreen mode
|
||||
^^^^^^^^^^^^^^^
|
||||
|
||||
To programmatically fullscreen the window,
|
||||
use the ``lv_wayland_window_set_fullscreen()`` function respectively with ``true``
|
||||
or ``false`` for the ``fullscreen`` argument.
|
||||
|
||||
Maximized mode
|
||||
^^^^^^^^^^^^^^
|
||||
|
||||
To programmatically maximize the window,
|
||||
use the ``lv_wayland_window_set_maximized()`` function respectively with ``true``
|
||||
or ``false`` for the ``maximized`` argument.
|
||||
|
||||
|
||||
Custom timer handler
|
||||
^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Always call ``lv_wayland_timer_handler()`` in your timer loop instead of the regular ``lv_timer_handler()``.
|
||||
|
||||
**Note:** ``lv_wayland_timer_handler()`` internally calls ``lv_timer_handler()``
|
||||
|
||||
This allows the wayland client to work on well on weston, resizing shared memory buffers during
|
||||
a commit does not work well on weston.
|
||||
|
||||
Wrapping the call to ``lv_timer_hander()`` is a necessity to have more control over
|
||||
when the LVGL flush callback is called.
|
||||
|
||||
The custom timer handler returns ``false`` if the frame from previous cycle is not rendered.
|
||||
When this happens, it usually means that the application is minimized or hidden behind another window.
|
||||
Causing the driver to wait until the arrival of any message on the wayland socket, the process is in interruptible sleep.
|
||||
|
||||
Building the wayland driver
|
||||
---------------------------
|
||||
|
||||
An example simulator is available in this `repo <https://github.com/lvgl/lv_port_linux/>`__
|
||||
|
||||
If there is a need to use driver with another build system. The source and header files for the XDG shell
|
||||
must be generated from the definitions for the XDG shell protocol.
|
||||
|
||||
In the example Cmake is used to perform the operation by invoking the ``wayland-scanner`` utility
|
||||
|
||||
To achieve this manually,
|
||||
|
||||
Make sure the dependencies listed at the start of the article are installed.
|
||||
|
||||
The wayland protocol is defined using XML files which are present in ``/usr/share/wayland-protocols``
|
||||
|
||||
To generate the required files run the following commands:
|
||||
|
||||
.. code-block:: sh
|
||||
|
||||
wayland-scanner client-header </usr/share/wayland-protocols/stable/xdg-shell/xdg-shell.xml > wayland_xdg_shell.h
|
||||
wayland-scanner private-code </usr/share/wayland-protocols/stable/xdg-shell/xdg-shell.xml > wayland_xdg_shell.c
|
||||
|
||||
The resulting files can then be integrated into the project, it's better to re-run ``wayland-scanner`` on
|
||||
each build to ensure that the correct versions are generated, they must match the version of the ``wayland-client``
|
||||
dynamically linked library installed on the system.
|
||||
|
||||
|
||||
Current state and objectives
|
||||
----------------------------
|
||||
|
||||
* Add direct rendering mode
|
||||
* Refactor the shell integrations to avoid excessive conditional compilation
|
||||
* Technically, the wayland driver allows to create multiple windows - but this feature is experimental.
|
||||
* Eventually add enhanced support for XDG shell to allow the creation of desktop apps on Unix-like platforms,
|
||||
similar to what the win32 driver does.
|
||||
* Add a support for Mesa, currently wl_shm is used and it's not the most effective technique.
|
||||
|
||||
|
||||
Bug reports
|
||||
-----------
|
||||
|
||||
The wayland driver is currently under construction, bug reports, contributions and feedback is always welcome.
|
||||
|
||||
It is however important to create detailed issues when a problem is encountered, logs and screenshots of the problem are of great help.
|
||||
|
||||
Please enable ``LV_USE_LOG`` and launch the simulator executable like so
|
||||
|
||||
.. code::
|
||||
|
||||
WAYLAND_DEBUG=1 ./path/to/simulator_executable > /tmp/debug 2>&1
|
||||
|
||||
This will create a log file called ``debug`` in the ``/tmp`` directory, copy-paste the content of the file in the github issue.
|
||||
The log file contains LVGL logs and the wayland messages.
|
||||
|
||||
Be sure to replicate the problem quickly otherwise the logs become too big
|
||||
|
||||
113
libraries/lvgl/docs/integration/driver/windows.rst
Normal file
@@ -0,0 +1,113 @@
|
||||
=============================
|
||||
Windows Display/Inputs driver
|
||||
=============================
|
||||
|
||||
Overview
|
||||
--------
|
||||
|
||||
The **Windows** display/input `driver <https://github.com/lvgl/lvgl/src/drivers/windows>`__ offers support for simulating the LVGL display and keyboard/mouse inputs in a Windows Win32 window.
|
||||
|
||||
The main purpose for this driver is for testing/debugging the LVGL application in a **Windows** simulation window via **simulator mode**, or developing a standard **Windows** desktop application with LVGL via **application mode**.
|
||||
|
||||
Here are the **similarity** for simulator mode and application mode.
|
||||
|
||||
- Support LVGL pointer, keypad and encoder devices integration.
|
||||
- Support Windows touch input.
|
||||
- Support Windows input method integration input.
|
||||
- Support Per-monitor DPI Aware (both V1 and V2).
|
||||
|
||||
Here are the **differences** for simulator mode and application mode.
|
||||
|
||||
Simulator Mode
|
||||
^^^^^^^^^^^^^^
|
||||
|
||||
- Designed for LVGL simulation scenario.
|
||||
- Keep the LVGL display resolution all time for trying best to simulate UI layout which will see in their production devices.
|
||||
- When Windows DPI scaling setting is changed, Windows backend will stretch the display content.
|
||||
|
||||
Application Mode
|
||||
^^^^^^^^^^^^^^^^
|
||||
|
||||
- Designed for Windows desktop application development scenario.
|
||||
- Have the Window resizing support and LVGL display resolution will be changed.
|
||||
- When Windows DPI scaling setting is changed, the LVGL display DPI value will also be changed.
|
||||
|
||||
Prerequisites
|
||||
-------------
|
||||
|
||||
The minimum Windows OS requirement for this driver is Windows Vista RTM.
|
||||
|
||||
If you use Windows API shim libraries like `YY-Thunks <https://github.com/Chuyu-Team/YY-Thunks>`__, the tested minimum Windows OS requirement for this driver is Windows XP RTM.
|
||||
|
||||
According to the Windows GDI API this driver used. Maybe the minimum Windows OS requirement limitation for this driver is Windows 2000 RTM.
|
||||
|
||||
Configure Windows driver
|
||||
------------------------
|
||||
|
||||
Enable the Windows driver support in lv_conf.h, by cmake compiler define or by KConfig
|
||||
|
||||
.. code:: c
|
||||
|
||||
#define LV_USE_WINDOWS 1
|
||||
|
||||
Usage
|
||||
-----
|
||||
|
||||
.. code:: c
|
||||
|
||||
#include <Windows.h>
|
||||
#include "lvgl/lvgl.h"
|
||||
#include "lvgl/examples/lv_examples.h"
|
||||
#include "lvgl/demos/lv_demos.h"
|
||||
|
||||
int main()
|
||||
{
|
||||
lv_init();
|
||||
|
||||
int32_t zoom_level = 100;
|
||||
bool allow_dpi_override = false;
|
||||
bool simulator_mode = false;
|
||||
lv_display_t* display = lv_windows_create_display(
|
||||
L"LVGL Display Window",
|
||||
800,
|
||||
480,
|
||||
zoom_level,
|
||||
allow_dpi_override,
|
||||
simulator_mode);
|
||||
if (!display)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
lv_lock();
|
||||
|
||||
lv_indev_t* pointer_device = lv_windows_acquire_pointer_indev(display);
|
||||
if (!pointer_device)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
lv_indev_t* keypad_device = lv_windows_acquire_keypad_indev(display);
|
||||
if (!keypad_device)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
lv_indev_t* encoder_device = lv_windows_acquire_encoder_indev(display);
|
||||
if (!encoder_device)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
lv_demo_widgets();
|
||||
|
||||
lv_unlock();
|
||||
|
||||
while (1)
|
||||
{
|
||||
uint32_t time_till_next = lv_timer_handler();
|
||||
lv_delay_ms(time_till_next);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
103
libraries/lvgl/docs/integration/framework/arduino.rst
Normal file
@@ -0,0 +1,103 @@
|
||||
=======
|
||||
Arduino
|
||||
=======
|
||||
|
||||
The `LVGL library <https://github.com/lvgl/lvgl>`__ is directly available as Arduino libraries.
|
||||
|
||||
Note that you need to choose a board powerful enough to run LVGL and
|
||||
your GUI. See the `requirements of LVGL <https://docs.lvgl.io/master/intro/index.html#requirements>`__.
|
||||
|
||||
For example ESP32 is a good candidate to create UI's with LVGL.
|
||||
|
||||
Get the LVGL Arduino library
|
||||
----------------------------
|
||||
|
||||
LVGL can be installed via the Arduino IDE Library Manager or as a .ZIP library.
|
||||
|
||||
You can `Download <https://github.com/lvgl/lvgl/archive/refs/heads/master.zip>`__
|
||||
the latest version of LVGL from GitHub and simply copy it to Arduino's
|
||||
library folder.
|
||||
|
||||
Set up drivers
|
||||
--------------
|
||||
|
||||
To get started it's recommended to use `TFT_eSPI <https://github.com/Bodmer/TFT_eSPI>`__ library as a TFT
|
||||
driver to simplify testing. To make it work, setup ``TFT_eSPI``
|
||||
according to your TFT display type via editing either:
|
||||
|
||||
- ``User_Setup.h``
|
||||
- or by selecting a configuration in the ``User_Setup_Select.h``
|
||||
|
||||
Both files are located in ``TFT_eSPI`` library's folder.
|
||||
|
||||
|
||||
Configure LVGL
|
||||
--------------
|
||||
|
||||
LVGL has its own configuration file called ``lv_conf.h``. When LVGL is
|
||||
installed, follow these configuration steps:
|
||||
|
||||
1. Go to the directory of the installed Arduino libraries
|
||||
2. Go to ``lvgl`` and copy ``lv_conf_template.h`` as ``lv_conf.h`` into the Arduino Libraries directory next to the ``lvgl`` library folder.
|
||||
3. Open ``lv_conf.h`` and change the first ``#if 0`` to ``#if 1`` to enable the content of the file
|
||||
4. Set the color depth of you display in :c:macro:`LV_COLOR_DEPTH`
|
||||
|
||||
Finally the layout with ``lv_conf.h`` should look like this:
|
||||
|
||||
::
|
||||
|
||||
arduino
|
||||
|-libraries
|
||||
|-lvgl
|
||||
|-other_lib_1
|
||||
|-other_lib_2
|
||||
|-lv_conf.h
|
||||
|
||||
|
||||
Initialize and run LVGL
|
||||
-----------------------
|
||||
|
||||
Take a look at `LVGL_Arduino.ino <https://github.com/lvgl/lvgl/blob/master/examples/arduino/LVGL_Arduino/LVGL_Arduino.ino>`__
|
||||
to see how to initialize LVGL. ``TFT_eSPI`` is used as the display driver.
|
||||
|
||||
In the INO file you can see how to register a display and a touchpad for
|
||||
LVGL and call an example.
|
||||
|
||||
|
||||
Use the examples and demos
|
||||
--------------------------
|
||||
|
||||
Note that, there is no dedicated INO file for every example. Instead,
|
||||
you can load an example by calling an ``lv_example_...`` function. For
|
||||
example :cpp:func:`lv_example_btn_1`.
|
||||
|
||||
:important: Due to some the limitations of Arduino's build system you
|
||||
need to copy ``lvgl/examples`` to ``lvgl/src/examples``. Similarly for
|
||||
the demos ``lvgl/demos`` to ``lvgl/src/demos``.
|
||||
|
||||
|
||||
Debugging and logging
|
||||
---------------------
|
||||
|
||||
LVGL can display debug information in case of trouble. In the
|
||||
``LVGL_Arduino.ino`` example there is a ``my_print`` method, which sends
|
||||
this debug information to the serial interface. To enable this feature
|
||||
you have to edit the ``lv_conf.h`` file and enable logging in the
|
||||
section ``log settings``:
|
||||
|
||||
.. code:: c
|
||||
|
||||
/*Log settings*/
|
||||
#define USE_LV_LOG 1 /*Enable/disable the log module*/
|
||||
#if LV_USE_LOG
|
||||
/* How important log should be added:
|
||||
* LV_LOG_LEVEL_TRACE A lot of logs to give detailed information
|
||||
* LV_LOG_LEVEL_INFO Log important events
|
||||
* LV_LOG_LEVEL_WARN Log if something unwanted happened but didn't cause a problem
|
||||
* LV_LOG_LEVEL_ERROR Only critical issue, when the system may fail
|
||||
* LV_LOG_LEVEL_NONE Do not log anything
|
||||
*/
|
||||
# define LV_LOG_LEVEL LV_LOG_LEVEL_WARN
|
||||
|
||||
After enabling the log module and setting :c:macro:`LV_LOG_LEVEL` accordingly, the
|
||||
output log is sent to the ``Serial`` port @ 115200 bps.
|
||||
11
libraries/lvgl/docs/integration/framework/index.rst
Normal file
@@ -0,0 +1,11 @@
|
||||
==========
|
||||
Frameworks
|
||||
==========
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 2
|
||||
|
||||
arduino
|
||||
platformio
|
||||
tasmota-berry
|
||||
|
||||
5
libraries/lvgl/docs/integration/framework/platformio.rst
Normal file
@@ -0,0 +1,5 @@
|
||||
==========
|
||||
Platformio
|
||||
==========
|
||||
|
||||
TODO
|
||||
105
libraries/lvgl/docs/integration/framework/tasmota-berry.rst
Normal file
@@ -0,0 +1,105 @@
|
||||
=================
|
||||
Tasmota and berry
|
||||
=================
|
||||
|
||||
What is Tasmota?
|
||||
----------------
|
||||
|
||||
`Tasmota <https://github.com/arendst/Tasmota>`__ is a widely used
|
||||
open-source firmware for ESP8266 and EPS32 based devices. It supports a
|
||||
wide variety of devices, sensors and integrations to Home Automation and
|
||||
Cloud services. Tasmota firmware is downloaded more than 200,000 times
|
||||
each month, and has an active and growing community.
|
||||
|
||||
Tasmota provides access to hundreds of supported devices, full support
|
||||
of MQTT, HTTP(S), integration with major Home Automation systems, myriad
|
||||
of sensors, IR, RF, Zigbee, Bluetooth, AWS IoT, Azure IoT, Alexa and
|
||||
many more.
|
||||
|
||||
What is Berry?
|
||||
--------------
|
||||
|
||||
`Berry <https://github.com/berry-lang/berry>`__ is a ultra-lightweight
|
||||
dynamically typed embedded scripting language. It is designed for
|
||||
lower-performance embedded devices. The interpreter of Berry include a
|
||||
one-pass compiler and register-based VM, all the code is written in ANSI
|
||||
C99. Berry offers a syntax very similar to Python, and is inspired from
|
||||
LUA VM. It is fully integrated in Tasmota
|
||||
|
||||
Highlights of Berry
|
||||
~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Berry has the following advantages:
|
||||
|
||||
- Lightweight: A well-optimized interpreter with very little resources. Ideal for use in microprocessors.
|
||||
- Fast: optimized one-pass bytecode compiler and register-based virtual machine.
|
||||
- Powerful: supports imperative programming, object-oriented programming, functional programming.
|
||||
- Flexible: Berry is a dynamic type script, and it's intended for embedding in applications.
|
||||
It can provide good dynamic scalability for the host system.
|
||||
- Simple: simple and natural syntax, support garbage collection, and easy to use FFI (foreign function interface).
|
||||
- RAM saving: With compile-time object construction, most of the constant objects are stored
|
||||
in read-only code data segments, so the RAM usage of the interpreter is very low when it starts.
|
||||
|
||||
All features are detailed in the `Berry Reference Manual <https://github.com/berry-lang/berry/wiki/Reference>`__
|
||||
|
||||
--------------
|
||||
|
||||
Why LVGL + Tasmota + Berry?
|
||||
---------------------------
|
||||
|
||||
In 2021, Tasmota added full support of LVGL for ESP32 based devices. It
|
||||
also introduced the Berry scripting language, a small-footprint language
|
||||
similar to Python and fully integrated in Tasmota.
|
||||
|
||||
A comprehensive mapping of LVGL in Berry language is now available,
|
||||
similar to the mapping of MicroPython. It allows to use +98% of all LVGL
|
||||
features. It is also possible to write custom widgets in Berry.
|
||||
|
||||
Versions supported: LVGL v8.0.2, LodePNG v20201017, Freetype 2.10.4
|
||||
|
||||
Tasmota + Berry + LVGL could be used for:
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
- Fast prototyping GUI.
|
||||
- Shortening the cycle of changing and fine-tuning the GUI.
|
||||
- Modelling the GUI in a more abstract way by defining reusable composite objects, taking
|
||||
advantage of Berry's language features such as Inheritance, Closures, Exception Handling…
|
||||
- Make LVGL accessible to a larger audience. No need to know C to create a nice GUI on an embedded system.
|
||||
|
||||
A higher level interface compatible with
|
||||
`OpenHASP <https://github.com/HASwitchPlate/openHASP>`__
|
||||
is also under development.
|
||||
|
||||
--------------
|
||||
|
||||
So what does it look like?
|
||||
--------------------------
|
||||
|
||||
TL;DR: Similar to MicroPython, it's very much like the C API, but Object-Oriented for LVGL components.
|
||||
|
||||
Let's dive right into an example!
|
||||
|
||||
A simple example
|
||||
~~~~~~~~~~~~~~~~
|
||||
|
||||
.. code:: python
|
||||
|
||||
lv.start() # start LVGL
|
||||
scr = lv.screen_active() # get default screen
|
||||
btn = lv.btn(scr) # create button
|
||||
btn.center()
|
||||
label = lv.label(btn) # create a label in the button
|
||||
label.set_text("Button") # set a label to the button
|
||||
|
||||
How can I use it?
|
||||
-----------------
|
||||
|
||||
You can start in less than 10 minutes on a M5Stack or equivalent device
|
||||
in less than 10 minutes in this `short tutorial <https://tasmota.github.io/docs/LVGL_in_10_minutes/>`__
|
||||
|
||||
Where can I find more information?
|
||||
----------------------------------
|
||||
|
||||
- `Tasmota Documentation <https://tasmota.github.io/docs/>`__
|
||||
- `Berry Documentation <https://github.com/berry-lang/berry/wiki/Reference>`__
|
||||
- `Tasmota LVGL Berry documentation <https://tasmota.github.io/docs/LVGL/>`__
|
||||
9
libraries/lvgl/docs/integration/ide/index.rst
Normal file
@@ -0,0 +1,9 @@
|
||||
====
|
||||
IDEs
|
||||
====
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 2
|
||||
|
||||
pc-simulator
|
||||
mdk
|
||||
5
libraries/lvgl/docs/integration/ide/mdk.rst
Normal file
@@ -0,0 +1,5 @@
|
||||
===
|
||||
MDK
|
||||
===
|
||||
|
||||
TODO
|
||||
54
libraries/lvgl/docs/integration/ide/pc-simulator.rst
Normal file
@@ -0,0 +1,54 @@
|
||||
.. _simulator:
|
||||
|
||||
===============
|
||||
Simulator on PC
|
||||
===============
|
||||
|
||||
You can try out LVGL **using only your PC** (i.e. without any
|
||||
development boards). LVGL will run on a simulator environment on the PC
|
||||
where anyone can write and experiment with real LVGL applications.
|
||||
|
||||
Using the simulator on a PC has the following advantages:
|
||||
|
||||
- Hardware independent: Write code, run it on the PC and see the result on a monitor.
|
||||
- Cross-platform: Any Windows, Linux or macOS system can run the PC simulator.
|
||||
- Portability: The written code is portable, which means you can simply copy it when migrating to embedded hardware.
|
||||
- Easy Validation: The simulator is also very useful to report bugs because it
|
||||
provides a common platform for every user.
|
||||
- Better developer experience: On PC Debuggers are usually faster and better, you can log to files,
|
||||
add a lot of ``printf``-s, do profiling, and so on.
|
||||
|
||||
|
||||
Select an IDE
|
||||
-------------
|
||||
|
||||
The simulator is ported to various IDEs (Integrated Development Environments).
|
||||
Choose your favorite IDE, read its README on GitHub, download the project, and load it to the IDE.
|
||||
|
||||
- `Eclipse with SDL driver <https://github.com/lvgl/lv_sim_eclipse_sdl>`__: Recommended on Linux and Mac, supports CMake too
|
||||
- `VisualStudio <https://github.com/lvgl/lv_port_pc_visual_studio>`__: Recommended on Windows
|
||||
- `VSCode with SDL driver <https://github.com/lvgl/lv_port_pc_vscode>`__: Recommended on Linux (SDL) and Mac (SDL)
|
||||
- `CodeBlocks <https://github.com/lvgl/lv_sim_codeblocks_win>`__: Recommended on Windows
|
||||
- `PlatformIO with SDL driver <https://github.com/lvgl/lv_platformio>`__: Recommended on Linux and Mac but has an STM32 environment too
|
||||
- `Generic Linux <https://github.com/lvgl/lv_port_linux>`__: CMake based project where you can easily switch between fbdev, DRM, and SDL.
|
||||
- `MDK with FastModel <https://github.com/lvgl/lv_port_an547_cm55_sim>`__: For Windows
|
||||
|
||||
External project not maintained by the LVGL organization:
|
||||
|
||||
- `QT Creator <https://github.com/Varanda-Labs/lvgl-qt-sim>`__: Cross platform
|
||||
|
||||
Built-in drivers
|
||||
----------------
|
||||
|
||||
LVGL comes with several `built-in drivers <https://docs.lvgl.io/master/integration/driver/index.html>`__.
|
||||
|
||||
Even if a simulator project comes with e.g. SDL, you can easily replace it by enabling
|
||||
another driver in ``lv_conf.h`` and calling its ``create`` function.
|
||||
|
||||
For example to use the Linux frame buffer device instead of SDL just enable ``LV_USE_LINUX_FBDEV``
|
||||
and call
|
||||
|
||||
.. code:: c
|
||||
|
||||
lv_display_t *display = lv_linux_fbdev_create();
|
||||
lv_linux_fbdev_set_file(display, "/dev/fb0")
|
||||
14
libraries/lvgl/docs/integration/index.rst
Normal file
@@ -0,0 +1,14 @@
|
||||
=======================
|
||||
Integration and Drivers
|
||||
=======================
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 2
|
||||
|
||||
building/index
|
||||
chip/index
|
||||
driver/index
|
||||
framework/index
|
||||
ide/index
|
||||
os/index
|
||||
bindings/index
|
||||
5
libraries/lvgl/docs/integration/os/freertos.rst
Normal file
@@ -0,0 +1,5 @@
|
||||
========
|
||||
FreeRTOS
|
||||
========
|
||||
|
||||
TODO
|
||||
13
libraries/lvgl/docs/integration/os/index.rst
Normal file
@@ -0,0 +1,13 @@
|
||||
======
|
||||
(RT)OS
|
||||
======
|
||||
|
||||
.. toctree:: :maxdepth: 2
|
||||
|
||||
nuttx
|
||||
rt-thread
|
||||
freertos
|
||||
zephyr
|
||||
px5
|
||||
mqx
|
||||
qnx
|
||||
8
libraries/lvgl/docs/integration/os/mqx.rst
Normal file
@@ -0,0 +1,8 @@
|
||||
========
|
||||
MQX RTOS
|
||||
========
|
||||
|
||||
See `MQX RTOS's homepage <https://www.nxp.com/design/design-center/software/embedded-software/mqx-software-solutions/mqx-real-time-operating-system-rtos:MQXRTOS>`__
|
||||
|
||||
|
||||
TODO
|
||||
146
libraries/lvgl/docs/integration/os/nuttx.rst
Normal file
@@ -0,0 +1,146 @@
|
||||
==========
|
||||
NuttX RTOS
|
||||
==========
|
||||
|
||||
What is NuttX?
|
||||
--------------
|
||||
|
||||
`NuttX <https://nuttx.apache.org/>`__ is a mature and secure real-time
|
||||
operating system (RTOS) with an emphasis on technical standards
|
||||
compliance and small size. It is scalable from 8-bit to 64-bit
|
||||
microcontrollers and microprocessors and compliant with the Portable
|
||||
Operating System Interface (POSIX) and the American National Standards
|
||||
Institute (ANSI) standards and with many Linux-like subsystems. The best
|
||||
way to think about NuttX is to think of it as a small Unix/Linux for
|
||||
microcontrollers.
|
||||
|
||||
Highlights of NuttX
|
||||
~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
- **Small** - Fits and runs in microcontrollers as small as 32 kB Flash
|
||||
and 8 kB of RAM.
|
||||
- **Compliant** - Strives to be as compatible as possible with POSIX
|
||||
and Linux.
|
||||
- **Versatile** - Supports many architectures (ARM, ARM Thumb, AVR,
|
||||
MIPS, OpenRISC, RISC-V 32-bit and 64-bit, RX65N, x86-64, Xtensa,
|
||||
Z80/Z180, etc.).
|
||||
- **Modular** - Its modular design allows developers to select only
|
||||
what really matters and use modules to include new features.
|
||||
- **Popular** - NuttX is used by many companies around the world.
|
||||
Probably you already used a product with NuttX without knowing it was
|
||||
running NuttX.
|
||||
- **Predictable** - NuttX is a preemptible Realtime kernel, so you can
|
||||
use it to create predictable applications for realtime control.
|
||||
|
||||
--------------
|
||||
|
||||
Why NuttX + LVGL?
|
||||
-----------------
|
||||
|
||||
Although NuttX has its own graphic library called
|
||||
`NX <https://cwiki.apache.org/confluence/pages/viewpage.action?pageId=139629474>`__,
|
||||
LVGL is a good alternative because users could find more eye-candy demos
|
||||
and they can reuse code from previous projects. LVGL is an
|
||||
`Object-Oriented Component
|
||||
Based <https://blog.lvgl.io/2018-12-13/extend-lvgl-objects>`__
|
||||
high-level GUI library, that could fit very well for a RTOS with
|
||||
advanced features like NuttX. LVGL is implemented in C and its APIs are
|
||||
in C.
|
||||
|
||||
Here are some advantages of using LVGL in NuttX
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
- Develop GUI in Linux first and when it is done just compile it for
|
||||
NuttX. Nothing more, no wasting of time.
|
||||
- Usually, GUI development for low level RTOS requires multiple
|
||||
iterations to get things right, where each iteration consists of
|
||||
**``Change code`` > ``Build`` > ``Flash`` > ``Run``**. Using LVGL,
|
||||
Linux and NuttX you can reduce this process and just test everything
|
||||
on your computer and when it is done, compile it on NuttX and that is
|
||||
it.
|
||||
|
||||
NuttX + LVGL could be used for
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
- GUI demos to demonstrate your board graphics capacities.
|
||||
- Fast prototyping GUI for MVP (Minimum Viable Product) presentation.
|
||||
- visualize sensor data directly and easily on the board without using
|
||||
a computer.
|
||||
- Final products with a GUI without a touchscreen (i.e. 3D Printer
|
||||
Interface using Rotary Encoder to Input data).
|
||||
- Final products with a touchscreen (and all sorts of bells and
|
||||
whistles).
|
||||
|
||||
--------------
|
||||
|
||||
How to get started with NuttX and LVGL?
|
||||
---------------------------------------
|
||||
|
||||
There are many boards in the `NuttX
|
||||
mainline <https://github.com/apache/incubator-nuttx>`__ with support for
|
||||
LVGL. Let's use the
|
||||
`STM32F429IDISCOVERY <https://www.st.com/en/evaluation-tools/32f429idiscovery.html>`__
|
||||
as an example because it is a very popular board.
|
||||
|
||||
First you need to install the pre-requisites on your system
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Let's use the `Windows Subsystem for
|
||||
Linux <https://acassis.wordpress.com/2018/01/10/how-to-build-nuttx-on-windows-10/>`__
|
||||
|
||||
.. code:: shell
|
||||
|
||||
$ sudo apt-get install automake bison build-essential flex gcc-arm-none-eabi gperf git libncurses5-dev libtool libusb-dev libusb-1.0.0-dev pkg-config kconfig-frontends openocd
|
||||
|
||||
Now let's create a workspace to save our files
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
.. code:: shell
|
||||
|
||||
$ mkdir ~/nuttxspace
|
||||
$ cd ~/nuttxspace
|
||||
|
||||
Clone the NuttX and Apps repositories:
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
.. code:: shell
|
||||
|
||||
$ git clone https://github.com/apache/incubator-nuttx nuttx
|
||||
$ git clone https://github.com/apache/incubator-nuttx-apps apps
|
||||
|
||||
Configure NuttX to use the stm32f429i-disco board and the LVGL Demo
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
.. code:: shell
|
||||
|
||||
$ ./tools/configure.sh stm32f429i-disco:lvgl
|
||||
$ make
|
||||
|
||||
If everything went fine you should have now the file ``nuttx.bin`` to
|
||||
flash on your board:
|
||||
|
||||
.. code:: shell
|
||||
|
||||
$ ls -l nuttx.bin
|
||||
-rwxrwxr-x 1 alan alan 287144 Jun 27 09:26 nuttx.bin
|
||||
|
||||
Flashing the firmware in the board using OpenOCD:
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
.. code:: shell
|
||||
|
||||
$ sudo openocd -f interface/stlink-v2.cfg -f target/stm32f4x.cfg -c init -c "reset halt" -c "flash write_image erase nuttx.bin 0x08000000"
|
||||
|
||||
Reset the board and using the 'NSH>' terminal start the LVGL demo:
|
||||
|
||||
.. code:: shell
|
||||
|
||||
nsh> lvgldemo
|
||||
|
||||
Where can I find more information?
|
||||
----------------------------------
|
||||
|
||||
- This blog post: `LVGL on
|
||||
LPCXpresso54628 <https://acassis.wordpress.com/2018/07/19/running-nuttx-on-lpcxpresso54628-om13098/>`__
|
||||
- NuttX mailing list: `Apache NuttX Mailing
|
||||
List <http://nuttx.incubator.apache.org/community/>`__
|
||||
8
libraries/lvgl/docs/integration/os/px5.rst
Normal file
@@ -0,0 +1,8 @@
|
||||
========
|
||||
PX5 RTOS
|
||||
========
|
||||
|
||||
See `PX5 RTOS's homepage <https://px5rtos.com/>`__
|
||||
|
||||
|
||||
TODO
|
||||
150
libraries/lvgl/docs/integration/os/qnx.rst
Normal file
@@ -0,0 +1,150 @@
|
||||
===
|
||||
QNX
|
||||
===
|
||||
|
||||
What is QNX?
|
||||
------------
|
||||
|
||||
QNX is a commercial operating system first released in 1980. The operating
|
||||
system is based on a micro-kernel design, with the file system(s), network
|
||||
stack, and various other drivers each running in its own process with a separate
|
||||
address space.
|
||||
|
||||
See www.qnx.com for more details.
|
||||
|
||||
Highlight of QNX
|
||||
~~~~~~~~~~~~~~~~
|
||||
|
||||
- 64-bit only, runs on x86_64 and ARMv8
|
||||
- Requires an MMU as the design mandates separation among processes
|
||||
- Support for thousands of processes and millions of threads
|
||||
- Up to 64 cores, up to 16TB of RAM
|
||||
- Virtualization support (as host and guest)
|
||||
- Full POSIX compatibility
|
||||
- Safety certification to various automotive, industrial and medical standards
|
||||
|
||||
How to run LVGL on QNX?
|
||||
-----------------------
|
||||
|
||||
There are two ways to use LVGL in your QNX project. The first is similar to how
|
||||
LVGL is used on other systems. The second is to build LVGL as either a shared or
|
||||
a static library.
|
||||
|
||||
Include LVGL in Your Project
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Follow the generic instructions for getting started with LVGL. After copying
|
||||
`lv_conf_template.h` to `lv_conf.h` make the following changes to the latter:
|
||||
|
||||
1. Enable QNX support:
|
||||
.. code::
|
||||
#define LV_USE_QNX 1
|
||||
|
||||
2. Set colour depth to 32:
|
||||
.. code::
|
||||
#define LV_COLOR_DEPTH 32
|
||||
|
||||
3. (Optional) Enable double-buffering:
|
||||
.. code::
|
||||
#define LV_QNX_BUF_COUNT 2
|
||||
|
||||
Build LVGL as a Library
|
||||
~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
**Note that this method is an alternative to including LVGL in your project. If
|
||||
you choose to build a library then you do not need to follow the instructions in
|
||||
the previous section.**
|
||||
|
||||
The top-level `qnx` directory includes a recursive make file for building LVGL,
|
||||
both as a shared library and as a static library for the supported
|
||||
architectures. To build all libraries, simply invoke `make` in this directory:
|
||||
|
||||
.. code:: shell
|
||||
|
||||
# cd $(LVGL_ROOT)/env_support/qnx
|
||||
# make
|
||||
|
||||
If you prefer to build for a specific architecture and variant, go to the
|
||||
appropriate directory and run `make` there. For example, to build a shared
|
||||
library for ARMv8:
|
||||
|
||||
.. code:: shell
|
||||
|
||||
# cd $(LVGL_ROOT)/env_support/qnx/aarch64/so.le
|
||||
# make
|
||||
|
||||
As a general rule, if you only want to have one LVGL application in your system
|
||||
then it is better to use a static library. If you have more than one, and
|
||||
especially if they run concurrently, it is better to use the shared library.
|
||||
|
||||
Before building the library, you may wish to edit
|
||||
`$(LVGL_ROOT)/env_support/qnx/lv_conf.h`, e.g. to add fonts or disable
|
||||
double-buffering.
|
||||
|
||||
Writing a LVGL Application
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
To create a LVGL application for QNX, follow these steps in your code:
|
||||
|
||||
1. Initialize the library.
|
||||
2. Create a window.
|
||||
3. Add the input devices.
|
||||
4. Create the UI.
|
||||
5. Run the event loop.
|
||||
|
||||
Steps 2, 3 and 5 use QNX-specific calls, but the rest of the code should be
|
||||
identical to that of a LVGL application written for any other platform.
|
||||
|
||||
The following code shows how to create a "Hello World" application:
|
||||
|
||||
.. code:: c
|
||||
|
||||
#include <lvgl.h>
|
||||
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
/* Initialize the library. */
|
||||
lv_init();
|
||||
|
||||
/* Create a 800x480 window. */
|
||||
lv_display_t *disp = lv_qnx_window_create(800, 480);
|
||||
lv_qnx_window_set_title(disp, "LVGL Example");
|
||||
|
||||
/* Add keyboard and mouse devices. */
|
||||
lv_qnx_add_keyboard_device(disp);
|
||||
lv_qnx_add_pointer_device(disp);
|
||||
|
||||
/* Generate the UI. */
|
||||
lv_obj_set_style_bg_color(lv_screen_active(), lv_color_hex(0x003a57), LV_PART_MAIN);
|
||||
|
||||
lv_obj_t * label = lv_label_create(lv_screen_active());
|
||||
lv_label_set_text(label, "Hello world");
|
||||
lv_obj_set_style_text_color(lv_screen_active(), lv_color_hex(0xffffff), LV_PART_MAIN);
|
||||
lv_obj_align(label, LV_ALIGN_CENTER, 0, 0);
|
||||
|
||||
/* Run the event loop until it exits. */
|
||||
return lv_qnx_event_loop(disp);
|
||||
}
|
||||
|
||||
Build the Application
|
||||
~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Building the application consists of compiling the source with the LVGL headers,
|
||||
and then linking against the library. This can be done in many ways, using
|
||||
different build systems. The following is a simple make file for the example
|
||||
above, which builds for ARMv8 with the shared library:
|
||||
|
||||
.. code:: makefile
|
||||
|
||||
CC=qcc -Vgcc_ntoaarch64le
|
||||
|
||||
LVGL_ROOT=$(HOME)/src/lvgl
|
||||
CCFLAGS=-I$(LVGL_ROOT)/env_support/qnx -I$(LVGL_ROOT)
|
||||
LDFLAGS=-lscreen -llvgl -L$(LVGL_ROOT)/env_support/qnx/aarch64/so.le
|
||||
|
||||
lvgl_example: lvgl_example.c
|
||||
$(CC) $(CCFLAGS) -Wall -o $@ $< $(LDFLAGS)
|
||||
|
||||
clean:
|
||||
rm -f *.o *~ lvgl_example
|
||||
88
libraries/lvgl/docs/integration/os/rt-thread.rst
Normal file
@@ -0,0 +1,88 @@
|
||||
==============
|
||||
RT-Thread RTOS
|
||||
==============
|
||||
|
||||
What is RT-Thread?
|
||||
------------------
|
||||
|
||||
`RT-Thread <https://www.rt-thread.io/>`__ is an `open
|
||||
source <https://github.com/RT-Thread/rt-thread>`__, neutral, and
|
||||
community-based real-time operating system (RTOS). RT-Thread has
|
||||
**Standard version** and **Nano version**. For resource-constrained
|
||||
microcontroller (MCU) systems, the Nano version that requires only 3 KB
|
||||
Flash and 1.2 KB RAM memory resources can be tailored with easy-to-use
|
||||
tools. For resource-rich IoT devices, RT-Thread can use the **online
|
||||
software package** management tool, together with system configuration
|
||||
tools, to achieve intuitive and rapid modular cutting, seamlessly import
|
||||
rich software packages; thus, achieving complex functions like Android's
|
||||
graphical interface and touch sliding effects, smart voice interaction
|
||||
effects, and so on.
|
||||
|
||||
Key features
|
||||
~~~~~~~~~~~~
|
||||
|
||||
- Designed for resource-constrained devices, the minimum kernel
|
||||
requires only 1.2KB of RAM and 3 KB of Flash.
|
||||
- A variety of standard interfaces, such as POSIX, CMSIS, C++
|
||||
application environment.
|
||||
- Has rich components and a prosperous and fast growing `package ecosystem <https://packages.rt-thread.org/en/>`__
|
||||
- Elegant code style, easy to use, read and master.
|
||||
- High Scalability. RT-Thread has high-quality scalable software
|
||||
architecture, loose coupling, modularity, is easy to tailor and
|
||||
expand.
|
||||
- Supports high-performance applications.
|
||||
- Supports all mainstream compiling tools such as GCC, Keil and IAR.
|
||||
- Supports a wide range of `architectures and chips <https://www.rt-thread.io/board.html>`__
|
||||
|
||||
How to run LVGL on RT-Thread?
|
||||
-----------------------------
|
||||
|
||||
`中文文档 <https://www.rt-thread.org/document/site/#/rt-thread-version/rt-thread-standard/packages-manual/lvgl-docs/introduction>`__
|
||||
|
||||
LVGL has registered as a
|
||||
`softwarepackage <https://packages.rt-thread.org/en/detail.html?package=LVGL>`__
|
||||
of RT-Thread. By using
|
||||
`Env tool <https://www.rt-thread.io/download.html?download=Env>`__ or
|
||||
`RT-Thread Studio IDE <https://www.rt-thread.io/download.html?download=Studio>`__,
|
||||
RT-Thread users can easily download LVGL source code and combine with
|
||||
RT-Thread project.
|
||||
|
||||
RT-Thread community has port LVGL to several BSPs:
|
||||
|
||||
+--------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------+
|
||||
| BSP | BSP |
|
||||
+======================================================================================================================================+======================================================================================================================================================+
|
||||
| `QEMU simulator <https://github.com/RT-Thread/rt-thread/tree/master/bsp/qemu-vexpress-a9/applications/lvgl>`__ | `Infineon psoc6-evaluationkit-062S2 <https://github.com/RT-Thread/rt-thread/tree/master/bsp/Infineon/psoc6-evaluationkit-062S2/applications/lvgl>`__ |
|
||||
+--------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------+
|
||||
| `Visual Studio simulator <https://github.com/RT-Thread/rt-thread/tree/master/bsp/simulator/applications/lvgl>`__ | `Renesas ra6m3-ek <https://github.com/RT-Thread/rt-thread/tree/master/bsp/renesas/ra6m3-ek/board/lvgl>`__ |
|
||||
+--------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------+
|
||||
| `Nuvoton numaker-iot-m487 <https://github.com/RT-Thread/rt-thread/tree/master/bsp/nuvoton/numaker-iot-m487/applications/lvgl>`__ | `Renesas ra6m4-cpk <https://github.com/RT-Thread/rt-thread/tree/master/bsp/renesas/ra6m4-cpk/board/lvgl>`__ |
|
||||
+--------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------+
|
||||
| `Nuvoton numaker-pfm-m487 <https://github.com/RT-Thread/rt-thread/tree/master/bsp/nuvoton/numaker-pfm-m487/applications/lvgl>`__ | `Renesas ra6m3-hmi <https://github.com/RT-Thread/rt-thread/tree/master/bsp/renesas/ra6m3-hmi-board/board/lvgl>`__ |
|
||||
+--------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------+
|
||||
| `Nuvoton nk-980iot <https://github.com/RT-Thread/rt-thread/tree/master/bsp/nuvoton/nk-980iot/applications/lvgl>`__ | `STM32H750 ART-Pi <https://github.com/RT-Thread/rt-thread/tree/master/bsp/stm32/stm32h750-artpi/applications/lvgl>`__ |
|
||||
+--------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------+
|
||||
| `Nuvoton numaker-m2354 <https://github.com/RT-Thread/rt-thread/tree/master/bsp/nuvoton/numaker-m2354/applications/lvgl>`__ | `STM32F469 Discovery <https://github.com/RT-Thread/rt-thread/tree/master/bsp/stm32/stm32f469-st-disco/applications/lvgl>`__ |
|
||||
+--------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------+
|
||||
| `Nuvoton nk-n9h30 <https://github.com/RT-Thread/rt-thread/tree/master/bsp/nuvoton/nk-n9h30/applications/lvgl>`__ | `STM32F407 explorer <https://github.com/RT-Thread/rt-thread/tree/master/bsp/stm32/stm32f407-atk-explorer/applications/lvgl>`__ |
|
||||
+--------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------+
|
||||
| `Nuvoton numaker-m032ki <https://github.com/RT-Thread/rt-thread/tree/master/bsp/nuvoton/numaker-m032ki/applications/lvgl>`__ | `STM32L475 pandora <https://github.com/RT-Thread/rt-thread/tree/master/bsp/stm32/stm32l475-atk-pandora/applications/lvgl>`__ |
|
||||
+--------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------+
|
||||
| `Nuvoton numaker-hmi-ma35d1 <https://github.com/RT-Thread/rt-thread/tree/master/bsp/nuvoton/numaker-hmi-ma35d1/applications/lvgl>`__ | `NXP imxrt1060-evk <https://github.com/RT-Thread/rt-thread/tree/master/bsp/imxrt/imxrt1060-nxp-evk/applications/lvgl>`__ |
|
||||
+--------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------+
|
||||
| `Nuvoton numaker-iot-m467 <https://github.com/RT-Thread/rt-thread/tree/master/bsp/nuvoton/numaker-iot-m467/applications/lvgl>`__ | `Raspberry PICO <https://github.com/RT-Thread/rt-thread/tree/master/bsp/raspberry-pico/applications/lvgl>`__ |
|
||||
+--------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------+
|
||||
| `Nuvoton numaker-m467hj <https://github.com/RT-Thread/rt-thread/tree/master/bsp/nuvoton/numaker-m467hj/applications/lvgl>`__ | `NXP LPC55S69 <https://github.com/RT-Thread/rt-thread/tree/master/bsp/lpc55sxx/lpc55s69_nxp_evk/applications/lvgl>`__ |
|
||||
+--------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------+
|
||||
| `synwit swm341 <https://github.com/RT-Thread/rt-thread/tree/master/bsp/synwit/swm341/applications/lvgl>`__ |
|
||||
+--------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------+
|
||||
|
||||
|
||||
Tutorials
|
||||
~~~~~~~~~
|
||||
|
||||
- `Introduce about RT-Thread and how to run LVGL on RT-Thread in simulators <https://www.youtube.com/watch?v=k7QYk6hSwnc>`__
|
||||
- `How to import a BSP project with latest code into RT-Thread Studio <https://www.youtube.com/watch?v=fREPLuh-h8k>`__
|
||||
- `How to Use LVGL with RT-Thread Studio in STM32F469 Discovery Board <https://www.youtube.com/watch?v=O_QA99BxnOE>`__
|
||||
- `RT-Thread Youtube Channel <https://www.youtube.com/channel/UCdDHtIfSYPq4002r27ffqPw>`__
|
||||
- `RT-Thread documentation center <https://www.rt-thread.io/document/site/>`__
|
||||
194
libraries/lvgl/docs/integration/os/zephyr.rst
Normal file
@@ -0,0 +1,194 @@
|
||||
======
|
||||
Zephyr
|
||||
======
|
||||
|
||||
What is Zephyr?
|
||||
---------------
|
||||
|
||||
`Zephyr <https://zephyrproject.org/>`__ is an `open
|
||||
source <https://github.com/zephyrproject-rtos/zephyr>`__ real-time operating
|
||||
system (RTOS) that is easy to deploy, secure, connect and manage.
|
||||
It has a growing set of software libraries that can be used
|
||||
across various applications and industry sectors such as
|
||||
Industrial IoT, wearables, machine learning and more.
|
||||
Zephyr is built with an emphasis on broad chipset support,
|
||||
security, dependability, longterm support releases and a
|
||||
growing open source ecosystem.
|
||||
|
||||
Highlights of Zephyr
|
||||
~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
- **Small** - Runs on microcontrollers as small as 8 kB Flash
|
||||
and 5 kB of RAM.
|
||||
- **Scalable** - Usable for complex multicore systems.
|
||||
- **Customizable** - Out-of-the-box support for 500+ boards
|
||||
and high portability.
|
||||
- **Secure** - Built with safety and security in mind,
|
||||
offers Long-term support.
|
||||
- **Ecosystem** - Zephyr not only provides the RTOS kernel but
|
||||
also developer tooling, device drivers, connectivity, logging,
|
||||
tracing, power management and much more.
|
||||
- **Decoupling** - Leverages devicetree to describe and
|
||||
configure the target system.
|
||||
- **Compliant** - Apps are runnable as native Linux applications,
|
||||
which simplifies debugging and profiling.
|
||||
|
||||
How to run LVGL on Zephyr?
|
||||
--------------------------
|
||||
|
||||
To setup your development environment refer to the
|
||||
`getting started guide <https://docs.zephyrproject.org/latest/develop/getting_started/index.html>`__.
|
||||
|
||||
After you completed the setup above you can check out all of the `provided samples <https://docs.zephyrproject.org/latest/samples/>`__ for various boards.
|
||||
You can check the list of available boards using:
|
||||
|
||||
.. code:: shell
|
||||
|
||||
$ west boards
|
||||
|
||||
After you chose a board you can build one of the LVGL demos for it. Here we are using the :code:`native_posix`
|
||||
board, which allows for running the application on your posix compliant host system:
|
||||
|
||||
.. code:: shell
|
||||
|
||||
$ west build -b native_posix samples/modules/lvgl/demos
|
||||
|
||||
To run the application on your host:
|
||||
|
||||
.. code:: shell
|
||||
|
||||
$ west build -t run
|
||||
|
||||
In case you chose any of the other supported boards you can flash to the device with:
|
||||
|
||||
.. code:: shell
|
||||
|
||||
$ west flash
|
||||
|
||||
If you want to build any of the other demo applications check out the samples
|
||||
`README <https://docs.zephyrproject.org/latest/samples/modules/lvgl/demos/README.html>`__.
|
||||
|
||||
Leveraging Zephyr Features
|
||||
--------------------------
|
||||
|
||||
Shell
|
||||
~~~~~
|
||||
|
||||
Zephyr includes a powerful shell implementation that can be enabled with the Kconfig symbols
|
||||
:code:`CONFIG_SHELL` and :code:`CONFIG_LV_Z_SHELL` (the demos from above have it enabled by default).
|
||||
|
||||
The shell offers enabling/disabling of LVGL monkeys:
|
||||
|
||||
.. code:: shell
|
||||
|
||||
# Create a new monkey with the given indev type
|
||||
uart$ lvgl monkey create [pointer|keypad|button|encoder]
|
||||
|
||||
# Enable/Disable a monkey
|
||||
uart$ lvgl monkey set <index> <inactive/active>
|
||||
|
||||
This is useful for checking your application for memory leaks and other bugs.
|
||||
Speaking of memory leaks, you can also acquire stats of the memory used by LVGL
|
||||
|
||||
.. code:: shell
|
||||
|
||||
uart$ lvgl stats memory
|
||||
|
||||
For more details refer to the `shell documentation <https://docs.zephyrproject.org/latest/services/shell/index.html>`__.
|
||||
|
||||
Devicetree
|
||||
~~~~~~~~~~
|
||||
|
||||
Zephyr uses the devicetree description language to create and manage LVGL input devices.
|
||||
|
||||
The pseudo device binding descriptions can be found at:
|
||||
|
||||
- `button input <https://docs.zephyrproject.org/latest/build/dts/api/bindings/input/zephyr,lvgl-button-input.html>`__
|
||||
- `pointer input <https://docs.zephyrproject.org/latest/build/dts/api/bindings/input/zephyr,lvgl-pointer-input.html>`__
|
||||
- `encoder input <https://docs.zephyrproject.org/latest/build/dts/api/bindings/input/zephyr,lvgl-encoder-input.html>`__
|
||||
- `keypad input <https://docs.zephyrproject.org/latest/build/dts/api/bindings/input/zephyr,lvgl-keypad-input.html>`__
|
||||
|
||||
Essentially those buffer the :code:`input_event` generated by the device pointed to by the :code:`input` phandle or if left
|
||||
empty the binding captures all events regardless of the source. You do not have to instantiate or manage the devices yourself,
|
||||
they are created at application start up before :code:`main()` is executed.
|
||||
|
||||
Most boards or shields that have a display or display connector have the pointer input device already declared:
|
||||
|
||||
.. code::
|
||||
|
||||
lvgl_pointer {
|
||||
compatible = "zephyr,lvgl-pointer-input";
|
||||
input = <&ft5336_touch>;
|
||||
};
|
||||
|
||||
You can access the underlying lvgl :code:`lv_indev_t` for configuration.
|
||||
Example with the encoder device to assign a :code:`lv_group_t`:
|
||||
|
||||
.. code:: c
|
||||
|
||||
const struct device *lvgl_encoder = DEVICE_DT_GET(DT_COMPAT_GET_ANY_STATUS_OKAY(zephyr_lvgl_encoder_input));
|
||||
|
||||
lv_obj_t *arc;
|
||||
lv_group_t *arc_group;
|
||||
|
||||
arc = lv_arc_create(lv_screen_active());
|
||||
lv_obj_align(arc, LV_ALIGN_CENTER, 0, 0);
|
||||
lv_obj_set_size(arc, 150, 150);
|
||||
|
||||
arc_group = lv_group_create();
|
||||
lv_group_add_obj(arc_group, arc);
|
||||
lv_indev_set_group(lvgl_input_get_indev(lvgl_encoder), arc_group);
|
||||
|
||||
|
||||
Kconfig
|
||||
~~~~~~~~
|
||||
|
||||
Aside from enabling the shell you can also use Kconfig to finetune
|
||||
the footprint of your application.
|
||||
|
||||
.. code::
|
||||
|
||||
# Size of the memory region from which lvgl memory is allocated
|
||||
CONFIG_LV_Z_MEM_POOL_SIZE=8192
|
||||
|
||||
# Do not include every widget/theme by default, enable them as needed.
|
||||
CONFIG_LV_CONF_MINIMAL=y
|
||||
|
||||
Overlays can be used to enable/disable features for specific boards or build
|
||||
targets. For more information refer to the
|
||||
`application development guide <https://docs.zephyrproject.org/latest/develop/application/index.html#application-configuration>`__.
|
||||
|
||||
Performance Tuning in LVGL
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
To optimize LVGL's performance, several `kconfig` options can be configured:
|
||||
|
||||
- **CONFIG_LV_Z_VDB_SIZE**: Sets the rendering buffer size as a percentage of the display area, adjustable from 1% to 100%. Larger buffers can enhance performance, especially when used with **CONFIG_LV_Z_FULL_REFRESH**.
|
||||
|
||||
- **CONFIG_LV_Z_DOUBLE_VDB**: Enables the use of two rendering buffers, allowing for parallel rendering and data flushing, thus improving responsiveness and reducing latency.
|
||||
|
||||
- **CONFIG_LV_Z_VDB_ALIGN**: Ensures that the rendering buffer is properly aligned, which is critical for efficient memory access based on the color depth.
|
||||
|
||||
- **CONFIG_LV_Z_VBD_CUSTOM_SECTION**: Allows rendering buffers to be placed in a custom memory section (e.g., `.lvgl_buf`), useful for leveraging specific memory types like tightly coupled or external memory to enhance performance.
|
||||
|
||||
Zephyr ≤ 3.7.0 Specific Options
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
For Zephyr versions 3.7.0 and below, additional options are available to manage LVGL's frame flushing:
|
||||
|
||||
- **CONFIG_LV_Z_FLUSH_THREAD**: Enables flushing LVGL frames in a separate thread, allowing the main thread to continue rendering the next frame simultaneously. This option can be disabled if the performance gain is not needed.
|
||||
|
||||
- **CONFIG_LV_Z_FLUSH_THREAD_STACK_SIZE**: Specifies the stack size for the flush thread, with a default of 1024 bytes.
|
||||
|
||||
- **CONFIG_LV_Z_FLUSH_THREAD_PRIO**: Sets the priority of the flush thread, with a default priority of 0, indicating cooperative priority.
|
||||
|
||||
For newer versions of Zephyr, the OSAL (Operating System Abstraction Layer) can be utilized, which takes care of the flushing.
|
||||
|
||||
Where can I find more information?
|
||||
----------------------------------
|
||||
|
||||
- Zephyr Documentation: `Zephyr Documentation <https://docs.zephyrproject.org/latest/index.html>`__
|
||||
- Zephyr mailing list: `Zepyhr Mailing
|
||||
List <https://lists.zephyrproject.org/g/main>`__
|
||||
- Zephyr Discord server: `Zepyhr Discord
|
||||
server <https://chat.zephyrproject.org/>`__
|
||||
290
libraries/lvgl/docs/intro/index.rst
Normal file
@@ -0,0 +1,290 @@
|
||||
.. _introduction:
|
||||
|
||||
============
|
||||
Introduction
|
||||
============
|
||||
|
||||
LVGL (Light and Versatile Graphics Library) is a free and open-source graphics library providing everything you need to create an embedded GUI with easy-to-use graphical elements, beautiful visual effects and a low memory footprint.
|
||||
|
||||
|
||||
Key features
|
||||
------------
|
||||
|
||||
- Powerful building blocks such as buttons, charts, lists, sliders, images, etc.
|
||||
- Advanced graphics with animations, anti-aliasing, opacity, smooth scrolling
|
||||
- Various input devices such as touchpad, mouse, keyboard, encoder, etc.
|
||||
- Multi-language support with UTF-8 encoding
|
||||
- Multi-display support, i.e. use multiple TFT, monochrome displays simultaneously
|
||||
- Fully customizable graphic elements with CSS-like styles
|
||||
- Hardware independent: use with any microcontroller or display
|
||||
- Scalable: able to operate with little memory (64 kB Flash, 16 kB RAM)
|
||||
- OS, external memory and GPU are supported but not required
|
||||
- Single frame buffer operation even with advanced graphic effects
|
||||
- Written in C for maximal compatibility (C++ compatible)
|
||||
- Simulator to start embedded GUI design on a PC without embedded hardware
|
||||
- Binding to MicroPython
|
||||
- Tutorials, examples, themes for rapid GUI design
|
||||
- Documentation is available online and as PDF
|
||||
- Free and open-source under MIT license
|
||||
|
||||
.. _requirements:
|
||||
|
||||
Requirements
|
||||
------------
|
||||
|
||||
Basically, every modern controller which is able to drive a display is suitable to run LVGL. The minimal requirements are:
|
||||
|
||||
* 16, 32 or 64 bit microcontroller or processor
|
||||
* > 16 MHz clock speed is recommended
|
||||
* Flash/ROM: > 64 kB for the very essential components (> 180 kB is recommended)
|
||||
* RAM:
|
||||
* Static RAM usage: ~2 kB depending on the used features and object types
|
||||
* stack: > 2kB (> 8 kB is recommended)
|
||||
* Dynamic data (heap): > 2 KB (> 48 kB is recommended if using several objects).
|
||||
Set by :c:macro:`LV_MEM_SIZE` in ``lv_conf.h``.
|
||||
* Display buffer: > *"Horizontal resolution"* pixels (> 10 *"Horizontal resolution"* is recommended)
|
||||
* One frame buffer in the MCU or in an external display controller
|
||||
* C99 or newer compiler
|
||||
* Basic C (or C++) knowledge:
|
||||
* `pointers <https://www.tutorialspoint.com/cprogramming/c_pointers.htm>`_.
|
||||
* `structs <https://www.tutorialspoint.com/cprogramming/c_structures.htm>`_.
|
||||
* `callbacks <https://www.geeksforgeeks.org/callbacks-in-c/>`_.
|
||||
|
||||
|
||||
|
||||
:Note: *memory usage may vary depending on architecture, compiler and build options.*
|
||||
|
||||
License
|
||||
-------
|
||||
|
||||
The LVGL project (including all repositories) is licensed under `MIT license <https://github.com/lvgl/lvgl/blob/master/LICENCE.txt>`_.
|
||||
This means you can use it even in commercial projects.
|
||||
|
||||
It's not mandatory, but we highly appreciate it if you write a few words about your project in the `My projects <https://forum.lvgl.io/c/my-projects/10>`_ category of the forum or a private message to `lvgl.io <https://lvgl.io/#contact>`_.
|
||||
|
||||
Although you can get LVGL for free there is a massive amount of work behind it. It's created by a group of volunteers who made it available for you in their free time.
|
||||
|
||||
To make the LVGL project sustainable, please consider :ref:`contributing` to the project.
|
||||
You can choose from many different ways of contributing See :ref:`contributing` such as simply writing a tweet about you using LVGL, fixing bugs, translating the documentation, or even becoming a maintainer.
|
||||
|
||||
Repository layout
|
||||
-----------------
|
||||
|
||||
All repositories of the LVGL project are hosted on `GitHub <https://github.com/lvgl>`_
|
||||
|
||||
You will find these repositories there:
|
||||
|
||||
* `lvgl <https://github.com/lvgl/lvgl>`_: The library itself with many `examples <https://github.com/lvgl/lvgl/blob/master/examples/>`_ and `demos <https://github.com/lvgl/lvgl/blob/master/demos/>`_.
|
||||
* `lv_drivers <https://github.com/lvgl/lv_drivers>`_: Display and input device drivers
|
||||
* `blog <https://github.com/lvgl/blog>`_: Source of the `blog's site <https://blog.lvgl.io>`_
|
||||
* `sim <https://github.com/lvgl/sim>`_: Source of the `online simulator's site <https://sim.lvgl.io>`_
|
||||
* `lv_port_* <https://github.com/lvgl?q=lv_port&type=&language=>`_: LVGL ports to development boards or environments
|
||||
* `lv_binding_* <https://github.com/lvgl?q=lv_binding&type=&language=l>`_: Bindings to other languages
|
||||
|
||||
Release policy
|
||||
--------------
|
||||
|
||||
The core repositories follow the rules of `Semantic versioning <https://semver.org/>`_:
|
||||
|
||||
* Major version: incompatible API changes. E.g. v5.0.0, v6.0.0
|
||||
* Minor version: new but backward-compatible functionalities. E.g. v6.1.0, v6.2.0
|
||||
* Patch version: backward-compatible bug fixes. E.g. v6.1.1, v6.1.2
|
||||
|
||||
Tags like `vX.Y.Z` are created for every release.
|
||||
|
||||
|
||||
Release cycle
|
||||
^^^^^^^^^^^^^
|
||||
|
||||
* Bug fixes: Released on demand even weekly
|
||||
* Minor releases: Every 3-4 months
|
||||
* Major releases: Approximately yearly
|
||||
|
||||
Branches
|
||||
^^^^^^^^
|
||||
|
||||
The core repositories have at least the following branches:
|
||||
|
||||
* `master`: latest version, patches are merged directly here.
|
||||
* `release/vX.Y`: stable versions of the minor releases
|
||||
* `fix/some-description`: temporary branches for bug fixes
|
||||
* `feat/some-description`: temporary branches for features
|
||||
|
||||
|
||||
Changelog
|
||||
^^^^^^^^^
|
||||
|
||||
The changes are recorded in :ref:`changelog`.
|
||||
|
||||
Version support
|
||||
^^^^^^^^^^^^^^^
|
||||
|
||||
Before v8 the last minor release of each major series was supported for 1 year.
|
||||
Starting from v8, every minor release is supported for 1 year.
|
||||
|
||||
|
||||
+---------+--------------+--------------+--------+
|
||||
| Version | Release date | Support end | Active |
|
||||
+=========+==============+==============+========+
|
||||
|v5.3 | 1 Feb, 2019 | 1 Feb, 2020 | No |
|
||||
+---------+--------------+--------------+--------+
|
||||
|v6.1 | 26 Nov, 2019 | 26 Nov, 2020 | No |
|
||||
+---------+--------------+--------------+--------+
|
||||
|v7.11 | 16 Mar, 2021 | 16 Mar, 2022 | No |
|
||||
+---------+--------------+--------------+--------+
|
||||
|v8.0 | 1 Jun, 2021 | 1 Jun, 2022 | No |
|
||||
+---------+--------------+--------------+--------+
|
||||
|v8.1 | 10 Nov, 2021 | 10 Nov, 2022 | No |
|
||||
+---------+--------------+--------------+--------+
|
||||
|v8.2 | 31 Jan, 2022 | 31 Jan, 2023 | No |
|
||||
+---------+--------------+--------------+--------+
|
||||
|v8.3 | 6 July, 2022 | 1 Jan, 2025 | Yes |
|
||||
+---------+--------------+--------------+--------+
|
||||
|v8.4 | Mar 19, 2024 | Mar 20, 2025 | Yes |
|
||||
+---------+--------------------------------------+
|
||||
|v9.0 | Jan 22, 2024 | Jan 22, 2025 | Yes |
|
||||
+---------+--------------------------------------+
|
||||
|v9.1 | Mar 20, 2024 | Mar 20, 2025 | Yes |
|
||||
+---------+--------------------------------------+
|
||||
|v9.2 | Aug 26, 2024 | Aug 26, 2025 | Yes |
|
||||
+---------+--------------------------------------+
|
||||
|
||||
|
||||
FAQ
|
||||
---
|
||||
|
||||
Where can I ask questions?
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
You can ask questions in the forum: `https://forum.lvgl.io/ <https://forum.lvgl.io/>`_.
|
||||
|
||||
We use `GitHub issues <https://github.com/lvgl/lvgl/issues>`_ for development related discussion.
|
||||
You should use them only if your question or issue is tightly related to the development of the library.
|
||||
|
||||
Before posting a question, please ready this FAQ section as you might find answer to your issue here too.
|
||||
|
||||
|
||||
Is my MCU/hardware supported?
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Every MCU which is capable of driving a display via parallel port, SPI, RGB interface or anything else and fulfills the :ref:`requirements` is supported by LVGL.
|
||||
|
||||
This includes:
|
||||
|
||||
* "Common" MCUs like STM32F, STM32H, NXP Kinetis, LPC, iMX, dsPIC33, PIC32, SWM341 etc.
|
||||
* Bluetooth, GSM, Wi-Fi modules like Nordic NRF, Espressif ESP32 and Raspberry Pi Pico W
|
||||
* Linux with frame buffer device such as /dev/fb0. This includes Single-board computers like the Raspberry Pi
|
||||
* Anything else with a strong enough MCU and a peripheral to drive a display
|
||||
|
||||
|
||||
Is my display supported?
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
LVGL needs just one simple driver function to copy an array of pixels into a given area of the display.
|
||||
If you can do this with your display then you can use it with LVGL.
|
||||
|
||||
Some examples of the supported display types:
|
||||
|
||||
* TFTs with 16 or 24 bit color depth
|
||||
* Monitors with an HDMI port
|
||||
* Small monochrome displays
|
||||
* Gray-scale displays
|
||||
* even LED matrices
|
||||
* or any other display where you can control the color/state of the pixels
|
||||
|
||||
See the :ref:`display_interface` section to learn more.
|
||||
|
||||
|
||||
LVGL doesn't start, randomly crashes or nothing is drawn on the display. What can be the problem?
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
* Try increasing :c:macro:`LV_MEM_SIZE`.
|
||||
* Be sure your display works without LVGL. E.g. paint it to red on start up.
|
||||
* Enable :ref:`logging`
|
||||
* Enable asserts in ``lv_conf.h`` (`LV_USE_ASSERT_...`)
|
||||
* If you use an RTOS
|
||||
* increase the stack size of the task which calls :cpp:func:`lv_timer_handler`
|
||||
* Be sure you used a mutex as described here: :ref:`os_interrupt`
|
||||
|
||||
|
||||
My display driver is not called. What have I missed?
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Be sure you are calling :cpp:expr:`lv_tick_inc(x)` in an interrupt and :cpp:func:`lv_timer_handler` in your main ``while(1)``.
|
||||
|
||||
Learn more in the :ref:`tick` and :ref:`timer` sections.
|
||||
|
||||
|
||||
Why is the display driver called only once? Only the upper part of the display is refreshed.
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Be sure you are calling :cpp:expr:`lv_display_flush_ready(drv)` at the end of your "*display flush callback*".
|
||||
|
||||
|
||||
Why do I see only garbage on the screen?
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Probably there a bug in your display driver. Try the following code without using LVGL. You should see a square with red-blue gradient.
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
#define BUF_W 20
|
||||
#define BUF_H 10
|
||||
|
||||
lv_color_t buf[BUF_W * BUF_H];
|
||||
lv_color_t * buf_p = buf;
|
||||
uint16_t x, y;
|
||||
for(y = 0; y < BUF_H; y++) {
|
||||
lv_color_t c = lv_color_mix(LV_COLOR_BLUE, LV_COLOR_RED, (y * 255) / BUF_H);
|
||||
for(x = 0; x < BUF_W; x++){
|
||||
(*buf_p) = c;
|
||||
buf_p++;
|
||||
}
|
||||
}
|
||||
|
||||
lv_area_t a;
|
||||
a.x1 = 10;
|
||||
a.y1 = 40;
|
||||
a.x2 = a.x1 + BUF_W - 1;
|
||||
a.y2 = a.y1 + BUF_H - 1;
|
||||
my_flush_cb(NULL, &a, buf);
|
||||
|
||||
|
||||
Why do I see nonsense colors on the screen?
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Probably LVGL's color format is not compatible with your display's color format. Check :c:macro:`LV_COLOR_DEPTH` in *lv_conf.h*.
|
||||
|
||||
|
||||
How to speed up my UI?
|
||||
^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
- Turn on compiler optimization and enable cache if your MCU has it
|
||||
- Increase the size of the display buffer
|
||||
- Use two display buffers and flush the buffer with DMA (or similar peripheral) in the background
|
||||
- Increase the clock speed of the SPI or parallel port if you use them to drive the display
|
||||
- If your display has an SPI port consider changing to a model with a parallel interface because it has much higher throughput
|
||||
- Keep the display buffer in internal RAM (not in external SRAM) because LVGL uses it a lot and it should have a fast access time
|
||||
|
||||
|
||||
How to reduce flash/ROM usage?
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
You can disable all the unused features (such as animations, file system, GPU etc.) and object types in *lv_conf.h*.
|
||||
|
||||
If you are using GCC/CLANG you can add `-fdata-sections -ffunction-sections` compiler flags and `--gc-sections` linker flag to remove unused functions and variables from the final binary. If possible, add the `-flto` compiler flag to enable link-time-optimisation together with `-Os` for GCC or `-Oz` for CLANG.
|
||||
|
||||
|
||||
How to reduce the RAM usage
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
* Lower the size of the *Display buffer*
|
||||
* Reduce :c:macro:`LV_MEM_SIZE` in *lv_conf.h*. This memory is used when you create objects like buttons, labels, etc.
|
||||
* To work with lower :c:macro:`LV_MEM_SIZE` you can create objects only when required and delete them when they are not needed anymore
|
||||
|
||||
|
||||
How to work with an operating system?
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
To work with an operating system where tasks can interrupt each other (preemptively) you should protect LVGL related function calls with a mutex.
|
||||
See the :ref:`os_interrupt` section to learn more.
|
||||
178
libraries/lvgl/docs/layouts/flex.rst
Normal file
@@ -0,0 +1,178 @@
|
||||
.. _flex:
|
||||
|
||||
====
|
||||
Flex
|
||||
====
|
||||
|
||||
Overview
|
||||
********
|
||||
|
||||
The Flexbox (or Flex for short) is a subset of `CSS Flexbox <https://css-tricks.com/snippets/css/a-guide-to-flexbox/>`__.
|
||||
|
||||
It can arrange items into rows or columns (tracks), handle wrapping,
|
||||
adjust the spacing between the items and tracks, handle *grow* to make
|
||||
the item(s) fill the remaining space with respect to min/max width and
|
||||
height.
|
||||
|
||||
To make an object flex container call
|
||||
:cpp:expr:`lv_obj_set_layout(obj, LV_LAYOUT_FLEX)`.
|
||||
|
||||
Note that the flex layout feature of LVGL needs to be globally enabled
|
||||
with :c:macro:`LV_USE_FLEX` in ``lv_conf.h``.
|
||||
|
||||
Terms
|
||||
*****
|
||||
|
||||
- **tracks**: the rows or columns
|
||||
- **main direction**: row or column, the direction in which the items are
|
||||
placed
|
||||
- **cross direction**: perpendicular to the main direction
|
||||
- **wrap**: if there is no more space in the track a new track is started
|
||||
- **grow**: if set on an item it will grow to fill the remaining space on
|
||||
the track. The available space will be distributed among items
|
||||
respective to their grow value (larger value means more space)
|
||||
- **gap**: the space between the rows and columns or the items on a track
|
||||
|
||||
Simple interface
|
||||
****************
|
||||
|
||||
With the following functions you can set a Flex layout on any parent.
|
||||
|
||||
.. _flex_flow:
|
||||
|
||||
Flex flow
|
||||
---------
|
||||
|
||||
:cpp:expr:`lv_obj_set_flex_flow(obj, flex_flow)`
|
||||
|
||||
The possible values for ``flex_flow`` are:
|
||||
|
||||
- :cpp:enumerator:`LV_FLEX_FLOW_ROW`: Place the children in a row without wrapping
|
||||
- :cpp:enumerator:`LV_FLEX_FLOW_COLUMN`: Place the children in a column without wrapping
|
||||
- :cpp:enumerator:`LV_FLEX_FLOW_ROW_WRAP`: Place the children in a row with wrapping
|
||||
- :cpp:enumerator:`LV_FLEX_FLOW_COLUMN_WRAP`: Place the children in a column with wrapping
|
||||
- :cpp:enumerator:`LV_FLEX_FLOW_ROW_REVERSE`: Place the children in a row without wrapping but in reversed order
|
||||
- :cpp:enumerator:`LV_FLEX_FLOW_COLUMN_REVERSE`: Place the children in a column without wrapping but in reversed order
|
||||
- :cpp:enumerator:`LV_FLEX_FLOW_ROW_WRAP_REVERSE`: Place the children in a row with wrapping but in reversed order
|
||||
- :cpp:enumerator:`LV_FLEX_FLOW_COLUMN_WRAP_REVERSE`: Place the children in a column with wrapping but in reversed order
|
||||
|
||||
.. _flex_align:
|
||||
|
||||
Flex align
|
||||
----------
|
||||
|
||||
To manage the placement of the children use
|
||||
:cpp:expr:`lv_obj_set_flex_align(obj, main_place, cross_place, track_cross_place)`
|
||||
|
||||
- ``main_place`` determines how to distribute the items in their track
|
||||
on the main axis. E.g. flush the items to the right on :cpp:enumerator:`LV_FLEX_FLOW_ROW_WRAP`. (It's called
|
||||
``justify-content`` in CSS)
|
||||
- ``cross_place`` determines how to distribute the items in their track
|
||||
on the cross axis. E.g. if the items have different height place them
|
||||
to the bottom of the track. (It's called ``align-items`` in CSS)
|
||||
- ``track_cross_place`` determines how to distribute the tracks (It's
|
||||
called ``align-content`` in CSS)
|
||||
|
||||
The possible values are:
|
||||
|
||||
- :cpp:enumerator:`LV_FLEX_ALIGN_START`: means left on a horizontally and top vertically (default)
|
||||
- :cpp:enumerator:`LV_FLEX_ALIGN_END`: means right on a horizontally and bottom vertically
|
||||
- :cpp:enumerator:`LV_FLEX_ALIGN_CENTER`: simply center
|
||||
- :cpp:enumerator:`LV_FLEX_ALIGN_SPACE_EVENLY`: items are distributed so
|
||||
that the spacing between any two items (and the space to the edges) is
|
||||
equal. Does not apply to ``track_cross_place``.
|
||||
- :cpp:enumerator:`LV_FLEX_ALIGN_SPACE_AROUND`: items are evenly
|
||||
distributed in the track with equal space around them. Note that
|
||||
visually the spaces aren't equal, since all the items have equal space
|
||||
on both sides. The first item will have one unit of space against the
|
||||
container edge, but two units of space between the next item because
|
||||
that next item has its own spacing that applies. Not applies to
|
||||
``track_cross_place``.
|
||||
- :cpp:enumerator:`LV_FLEX_ALIGN_SPACE_BETWEEN`: items are evenly distributed in
|
||||
the track: first item is on the start line, last item on the end line. Not applies to ``track_cross_place``.
|
||||
|
||||
.. _flex_grow:
|
||||
|
||||
Flex grow
|
||||
---------
|
||||
|
||||
Flex grow can be used to make one or more children fill the available
|
||||
space on the track. When more children have grow parameters, the
|
||||
available space will be distributed proportionally to the grow values.
|
||||
For example, there is 400 px remaining space and 4 objects with grow:
|
||||
|
||||
- ``A`` with grow = 1
|
||||
- ``B`` with grow = 1
|
||||
- ``C`` with grow = 2
|
||||
|
||||
``A`` and ``B`` will have 100 px size, and ``C`` will have 200 px size.
|
||||
|
||||
Flex grow can be set on a child with
|
||||
:cpp:expr:`lv_obj_set_flex_grow(child, value)`. ``value`` needs to be >
|
||||
1 or 0 to disable grow on the child.
|
||||
|
||||
.. _flex_style:
|
||||
|
||||
Style interface
|
||||
***************
|
||||
|
||||
All the Flex-related values are style properties under the hood and you
|
||||
can use them similarly to any other style property.
|
||||
|
||||
The following flex related style properties exist:
|
||||
|
||||
- :cpp:enumerator:`FLEX_FLOW`
|
||||
- :cpp:enumerator:`FLEX_MAIN_PLACE`
|
||||
- :cpp:enumerator:`FLEX_CROSS_PLACE`
|
||||
- :cpp:enumerator:`FLEX_TRACK_PLACE`
|
||||
- :cpp:enumerator:`FLEX_GROW`
|
||||
|
||||
.. _flex_padding:
|
||||
|
||||
Internal padding
|
||||
----------------
|
||||
|
||||
To modify the minimum space flexbox inserts between objects, the
|
||||
following properties can be set on the flex container style:
|
||||
|
||||
- ``pad_row`` Sets the padding between the rows.
|
||||
|
||||
- ``pad_column`` Sets the padding between the columns.
|
||||
|
||||
These can for example be used if you don't want any padding between your
|
||||
objects: :cpp:expr:`lv_style_set_pad_column(&row_container_style,0)`
|
||||
|
||||
.. _flex_other:
|
||||
|
||||
Other features
|
||||
**************
|
||||
|
||||
RTL
|
||||
---
|
||||
|
||||
If the base direction of the container is set the
|
||||
:cpp:enumerator:`LV_BASE_DIR_RTL` the meaning of
|
||||
:cpp:enumerator:`LV_FLEX_ALIGN_START` and
|
||||
:cpp:enumerator:`LV_FLEX_ALIGN_END` is swapped on ``ROW`` layouts. I.e.
|
||||
``START`` will mean right.
|
||||
|
||||
The items on ``ROW`` layouts, and tracks of ``COLUMN`` layouts will be
|
||||
placed from right to left.
|
||||
|
||||
New track
|
||||
---------
|
||||
|
||||
You can force Flex to put an item into a new line with
|
||||
:cpp:expr:`lv_obj_add_flag(child, LV_OBJ_FLAG_FLEX_IN_NEW_TRACK)`.
|
||||
|
||||
.. _flex_example:
|
||||
|
||||
Example
|
||||
*******
|
||||
|
||||
.. include:: ../examples/layouts/flex/index.rst
|
||||
|
||||
.. _flex_api:
|
||||
|
||||
API
|
||||
***
|
||||
184
libraries/lvgl/docs/layouts/grid.rst
Normal file
@@ -0,0 +1,184 @@
|
||||
.. _grid:
|
||||
|
||||
====
|
||||
Grid
|
||||
====
|
||||
|
||||
Overview
|
||||
********
|
||||
|
||||
The Grid layout is a subset of `CSS Grid <https://css-tricks.com/snippets/css/complete-guide-grid/>`__.
|
||||
|
||||
It can arrange items into a 2D "table" that has rows or columns
|
||||
(tracks). The item can span through multiple columns or rows. The
|
||||
track's size can be set in pixel, to the largest item
|
||||
(:c:macro:`LV_GRID_CONTENT`) or in "Free unit" (FR) to distribute the free
|
||||
space proportionally.
|
||||
|
||||
To make an object a grid container call :cpp:expr:`lv_obj_set_layout(obj, LV_LAYOUT_GRID)`.
|
||||
|
||||
Note that the grid layout feature of LVGL needs to be globally enabled
|
||||
with :c:macro:`LV_USE_GRID` in ``lv_conf.h``.
|
||||
|
||||
Terms
|
||||
*****
|
||||
|
||||
- **tracks**: the rows or columns
|
||||
- **free unit (FR)**: if set on track's size is set in ``FR`` it will grow
|
||||
to fill the remaining space on the parent.
|
||||
- **gap**: the space between the rows and columns or the items on a track
|
||||
|
||||
Simple interface
|
||||
****************
|
||||
|
||||
With the following functions you can easily set a Grid layout on any
|
||||
parent.
|
||||
|
||||
.. _grid_descriptors:
|
||||
|
||||
Grid descriptors
|
||||
----------------
|
||||
|
||||
First you need to describe the size of rows and columns. It can be done
|
||||
by declaring 2 arrays and the track sizes in them. The last element must
|
||||
be :c:macro:`LV_GRID_TEMPLATE_LAST`.
|
||||
|
||||
For example:
|
||||
|
||||
.. code:: c
|
||||
|
||||
static int32_t column_dsc[] = {100, 400, LV_GRID_TEMPLATE_LAST}; /*2 columns with 100 and 400 ps width*/
|
||||
static int32_t row_dsc[] = {100, 100, 100, LV_GRID_TEMPLATE_LAST}; /*3 100 px tall rows*/
|
||||
|
||||
To set the descriptors on a parent use
|
||||
:cpp:expr:`lv_obj_set_grid_dsc_array(obj, col_dsc, row_dsc)`.
|
||||
|
||||
Besides simple settings the size in pixel you can use two special
|
||||
values:
|
||||
|
||||
- :c:macro:`LV_GRID_CONTENT` set the size to fit the largest child on this track
|
||||
- :cpp:expr:`LV_GRID_FR(X)` tell what portion of the remaining space
|
||||
should be used by this track. Larger value means larger space.
|
||||
|
||||
.. _grid_items:
|
||||
|
||||
Grid items
|
||||
----------
|
||||
|
||||
By default, the children are not added to the grid. They need to be
|
||||
added manually to a cell.
|
||||
|
||||
To do this call
|
||||
:cpp:expr:`lv_obj_set_grid_cell(child, column_align, column_pos, column_span, row_align, row_pos, row_span)`.
|
||||
|
||||
``column_align`` and ``row_align`` determine how to align the children
|
||||
in its cell. The possible values are:
|
||||
|
||||
- :cpp:enumerator:`LV_GRID_ALIGN_START`: means left on a horizontally and top vertically (default)
|
||||
- :cpp:enumerator:`LV_GRID_ALIGN_END`: means right on a horizontally and bottom vertically
|
||||
- :cpp:enumerator:`LV_GRID_ALIGN_CENTER`: simply center ``column_pos`` and ``row_pos``
|
||||
means the zero based index of the cell into the item should be placed.
|
||||
|
||||
``column_span`` and ``row_span`` means how many tracks should the item
|
||||
involve from the start cell. Must be ``>= 1``.
|
||||
|
||||
.. _grid_align:
|
||||
|
||||
Grid align
|
||||
----------
|
||||
|
||||
If there are some empty space the track can be aligned several ways:
|
||||
|
||||
- :cpp:enumerator:`LV_GRID_ALIGN_START`: means left on a horizontally and top vertically. (default)
|
||||
- :cpp:enumerator:`LV_GRID_ALIGN_END`: means right on a horizontally and bottom vertically
|
||||
- :cpp:enumerator:`LV_GRID_ALIGN_CENTER`: simply center
|
||||
- :cpp:enumerator:`LV_GRID_ALIGN_SPACE_EVENLY`: items are distributed so that the spacing
|
||||
between any two items (and the space to the edges) is equal. Not applies to ``track_cross_place``.
|
||||
- :cpp:enumerator:`LV_GRID_ALIGN_SPACE_AROUND`: items are
|
||||
evenly distributed in the track with equal space around them. Note that
|
||||
visually the spaces aren't equal, since all the items have equal space
|
||||
on both sides. The first item will have one unit of space against the
|
||||
container edge, but two units of space between the next item because
|
||||
that next item has its own spacing that applies. Not applies to ``track_cross_place``.
|
||||
- :cpp:enumerator:`LV_GRID_ALIGN_SPACE_BETWEEN`: items are
|
||||
evenly distributed in the track: first item is on the start line, last
|
||||
item on the end line. Not applies to ``track_cross_place``.
|
||||
|
||||
To set the track's alignment use
|
||||
:cpp:expr:`lv_obj_set_grid_align(obj, column_align, row_align)`.
|
||||
|
||||
.. _grid_subgrid:
|
||||
|
||||
Sub grid
|
||||
--------
|
||||
|
||||
If you set the column and/or row grid descriptors of a widget to ``NULL`` it will use the grid descriptor(s) from it's parent.
|
||||
For example if you create a grid item on 2..6 columns and 1..3 rows of the parent,
|
||||
the grid item will see 5 columns and 4 rows with the corresponding track size from the parent.
|
||||
|
||||
This way even if a wrapper item is used on the grid and can be made "transparent" from the grid's point of view.
|
||||
|
||||
Limitations:
|
||||
|
||||
- The sub grid is resolved only in one level depth. That is a grid can have a sub grid children, but a sub grid can't have another sub grid.
|
||||
- ``LV_GRID_CONTENT`` tracks on the are not handled in the sub grid, only in the its own grid.
|
||||
|
||||
The sub grid feature works the same as in CSS. For further reference see `this description <https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_grid_layout/Subgrid>`__.
|
||||
|
||||
.. _grid_style:
|
||||
|
||||
Style interface
|
||||
***************
|
||||
|
||||
All the Grid related values are style properties under the hood and you
|
||||
can use them similarly to any other style properties.
|
||||
|
||||
The following Grid related style properties exist:
|
||||
|
||||
- :cpp:enumerator:`GRID_COLUMN_DSC_ARRAY`
|
||||
- :cpp:enumerator:`GRID_ROW_DSC_ARRAY`
|
||||
- :cpp:enumerator:`GRID_COLUMN_ALIGN`
|
||||
- :cpp:enumerator:`GRID_ROW_ALIGN`
|
||||
- :cpp:enumerator:`GRID_CELL_X_ALIGN`
|
||||
- :cpp:enumerator:`GRID_CELL_COLUMN_POS`
|
||||
- :cpp:enumerator:`GRID_CELL_COLUMN_SPAN`
|
||||
- :cpp:enumerator:`GRID_CELL_Y_ALIGN`
|
||||
- :cpp:enumerator:`GRID_CELL_ROW_POS`
|
||||
- :cpp:enumerator:`GRID_CELL_ROW_SPAN`
|
||||
|
||||
.. _grid_padding:
|
||||
|
||||
Internal padding
|
||||
----------------
|
||||
|
||||
To modify the minimum space Grid inserts between objects, the following
|
||||
properties can be set on the Grid container style:
|
||||
|
||||
- ``pad_row`` Sets the padding between the rows.
|
||||
- ``pad_column`` Sets the padding between the columns.
|
||||
|
||||
.. _grid_other:
|
||||
|
||||
Other features
|
||||
**************
|
||||
|
||||
RTL
|
||||
---
|
||||
|
||||
If the base direction of the container is set to :cpp:enumerator:`LV_BASE_DIR_RTL`,
|
||||
the meaning of :cpp:enumerator:`LV_GRID_ALIGN_START` and :cpp:enumerator:`LV_GRID_ALIGN_END` is
|
||||
swapped. I.e. ``START`` will mean right-most.
|
||||
|
||||
The columns will be placed from right to left.
|
||||
|
||||
.. _grid_examples:
|
||||
|
||||
Example
|
||||
*******
|
||||
|
||||
.. include:: ../examples/layouts/grid/index.rst
|
||||
|
||||
.. _grid_api:
|
||||
|
||||
API
|
||||
***
|
||||
12
libraries/lvgl/docs/layouts/index.rst
Normal file
@@ -0,0 +1,12 @@
|
||||
.. _layouts:
|
||||
|
||||
=======
|
||||
Layouts
|
||||
=======
|
||||
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 2
|
||||
|
||||
flex
|
||||
grid
|
||||
23
libraries/lvgl/docs/libs/arduino_esp_littlefs.rst
Normal file
@@ -0,0 +1,23 @@
|
||||
.. _arduino_esp_littlefs:
|
||||
|
||||
====================
|
||||
Arduino ESP littlefs
|
||||
====================
|
||||
|
||||
LittleFS is a little fail-safe filesystem designed for microcontrollers and integrated in the Arduino framework
|
||||
when used with ESP32 and ESP8266.
|
||||
|
||||
Detailed introduction:
|
||||
|
||||
- https://github.com/esp8266/Arduino
|
||||
- https://github.com/espressif/arduino-esp32
|
||||
|
||||
|
||||
Usage
|
||||
-----
|
||||
|
||||
Enable :c:macro:`LV_USE_FS_ARDUINO_ESP_LITTLEFS` and define a :c:macro:`LV_FS_ARDUINO_ESP_LITTLEFS_LETTER` in ``lv_conf.h``.
|
||||
|
||||
|
||||
API
|
||||
---
|
||||
24
libraries/lvgl/docs/libs/arduino_sd.rst
Normal file
@@ -0,0 +1,24 @@
|
||||
.. _arduino_sd:
|
||||
|
||||
==========
|
||||
Arduino SD
|
||||
==========
|
||||
|
||||
Enables reading and writing on SD cards.
|
||||
Once an SD memory card is connected to the SPI interface of the Arduino or Genuino board you can create files
|
||||
and read/write on them. You can also move through directories on the SD card..
|
||||
|
||||
Detailed introduction:
|
||||
|
||||
- https://www.arduino.cc/reference/en/libraries/sd/
|
||||
|
||||
|
||||
Usage
|
||||
-----
|
||||
|
||||
Enable :c:macro:`LV_USE_FS_ARDUINO_SD` and define a :c:macro:`LV_FS_ARDUINO_SD_LETTER` in ``lv_conf.h``.
|
||||
You will need to initialize the SD card before LVGL can use it (i.e. :cpp:expr:`SD.begin(0, SPI, 40000000)`).
|
||||
|
||||
|
||||
API
|
||||
---
|
||||
50
libraries/lvgl/docs/libs/barcode.rst
Normal file
@@ -0,0 +1,50 @@
|
||||
.. _barcode:
|
||||
|
||||
=======
|
||||
Barcode
|
||||
=======
|
||||
|
||||
Barcode generation with LVGL. Uses
|
||||
`code128 <https://github.com/fhunleth/code128>`__ by
|
||||
`fhunleth <https://github.com/fhunleth>`__.
|
||||
|
||||
.. _barcode_usage:
|
||||
|
||||
Usage
|
||||
-----
|
||||
|
||||
Enable :c:macro:`LV_USE_BARCODE` in ``lv_conf.h``.
|
||||
|
||||
Use :cpp:func:`lv_barcode_create` to create a barcode object, and use
|
||||
:cpp:func:`lv_barcode_update` to generate a barcode.
|
||||
|
||||
Call :cpp:func:`lv_barcode_set_scale` to adjust scaling,
|
||||
call :cpp:func:`lv_barcode_set_dark_color` and :cpp:func:`lv_barcode_set_light_color`
|
||||
adjust color, call :cpp:func:`lv_barcode_set_direction` will set
|
||||
direction to display, and call :cpp:func:`lv_barcode_update` again to regenerate
|
||||
the barcode.
|
||||
|
||||
Notes
|
||||
-----
|
||||
|
||||
- It is best not to manually set the width of the barcode, because when
|
||||
the width of the object is lower than the width of the barcode, the
|
||||
display will be incomplete due to truncation.
|
||||
- The scale adjustment can only be an integer multiple, for example,
|
||||
:cpp:expr:`lv_barcode_set_scale(barcode, 2)` means 2x scaling.
|
||||
- The direction adjustment can be :cpp:enumerator:`LV_DIR_HOR` or :cpp:enumerator:`LV_DIR_VER`
|
||||
|
||||
.. _barcode_example:
|
||||
|
||||
Example
|
||||
-------
|
||||
|
||||
.. include:: ../examples/libs/barcode/index.rst
|
||||
|
||||
.. _barcode_api:
|
||||
|
||||
API
|
||||
---
|
||||
|
||||
:ref:`code128`
|
||||
|
||||
54
libraries/lvgl/docs/libs/bmp.rst
Normal file
@@ -0,0 +1,54 @@
|
||||
.. _bmp:
|
||||
|
||||
===========
|
||||
BMP decoder
|
||||
===========
|
||||
|
||||
This extension allows the use of BMP images in LVGL.
|
||||
|
||||
Library source: https://github.com/caj-johnson/bmp-decoder
|
||||
|
||||
The pixels are read on demand (not the whole image is loaded)
|
||||
so using BMP images requires very little RAM.
|
||||
|
||||
If enabled in ``lv_conf.h`` by :c:macro:`LV_USE_BMP` LVGL will register a new
|
||||
image decoder automatically so BMP files can be directly used as image
|
||||
sources. For example:
|
||||
|
||||
.. code:: c
|
||||
|
||||
lv_image_set_src(my_img, "S:path/to/picture.bmp");
|
||||
|
||||
Note that, a file system driver needs to registered to open images from
|
||||
files. Read more about it :ref:`overview_file_system` or just
|
||||
enable one in ``lv_conf.h`` with ``LV_USE_FS_...``
|
||||
|
||||
.. _bmp_limitations:
|
||||
|
||||
Limitations
|
||||
-----------
|
||||
|
||||
- Only BMP files are supported and BMP images as C array
|
||||
(:c:struct:`lv_image_dsc_t`) are not. It's because there is no practical
|
||||
differences between how the BMP files and LVGL's image format stores
|
||||
the image data.
|
||||
- BMP files can be loaded only from file. If you want to store them in
|
||||
flash it's better to convert them to C array with `LVGL's image converter <https://lvgl.io/tools/imageconverter>`__.
|
||||
- The BMP files color format needs to match with :c:macro:`LV_COLOR_DEPTH`.
|
||||
Use GIMP to save the image in the required format. Both RGB888 and
|
||||
ARGB888 works with :c:macro:`LV_COLOR_DEPTH` ``32``
|
||||
- Palette is not supported.
|
||||
- Because not the whole image is read in cannot be zoomed or rotated.
|
||||
|
||||
.. _bmp_example:
|
||||
|
||||
Example
|
||||
-------
|
||||
|
||||
.. include:: ../examples/libs/bmp/index.rst
|
||||
|
||||
.. _bmp_api:
|
||||
|
||||
API
|
||||
---
|
||||
|
||||
51
libraries/lvgl/docs/libs/ffmpeg.rst
Normal file
@@ -0,0 +1,51 @@
|
||||
.. _ffmpeg:
|
||||
|
||||
==============
|
||||
FFmpeg support
|
||||
==============
|
||||
|
||||
A complete, cross-platform solution to record, convert and stream audio and video.
|
||||
|
||||
Detailed introduction: https://www.ffmpeg.org
|
||||
|
||||
Install FFmpeg
|
||||
--------------
|
||||
|
||||
Download first FFmpeg from `here <https://www.ffmpeg.org/download.html>`__, then install it:
|
||||
|
||||
.. code:: shell
|
||||
|
||||
./configure --disable-all --disable-autodetect --disable-podpages --disable-asm --enable-avcodec --enable-avformat --enable-decoders --enable-encoders --enable-demuxers --enable-parsers --enable-protocol='file' --enable-swscale --enable-zlib
|
||||
make
|
||||
sudo make install
|
||||
|
||||
Add FFmpeg to your project
|
||||
--------------------------
|
||||
|
||||
- Add library: ``FFmpeg`` (for GCC: ``-lavformat -lavcodec -lavutil -lswscale -lm -lz -lpthread``)
|
||||
|
||||
.. _ffmpeg_usage:
|
||||
|
||||
Usage
|
||||
-----
|
||||
|
||||
Enable :c:macro:`LV_USE_FFMPEG` in ``lv_conf.h``.
|
||||
|
||||
See the examples below.
|
||||
|
||||
:Note: FFmpeg extension doesn't use LVGL's file system. You can
|
||||
simply pass the path to the image or video as usual on your operating
|
||||
system or platform.
|
||||
|
||||
.. _ffmpeg_example:
|
||||
|
||||
Example
|
||||
-------
|
||||
|
||||
.. include:: ../examples/libs/ffmpeg/index.rst
|
||||
|
||||
.. _ffmpeg_api:
|
||||
|
||||
API
|
||||
---
|
||||
|
||||
117
libraries/lvgl/docs/libs/freetype.rst
Normal file
@@ -0,0 +1,117 @@
|
||||
.. _freetype:
|
||||
|
||||
================
|
||||
FreeType support
|
||||
================
|
||||
|
||||
Interface to FreeType library to generate font bitmaps run time.
|
||||
|
||||
Detailed introduction: https://www.freetype.org
|
||||
|
||||
Add FreeType to your project
|
||||
----------------------------
|
||||
|
||||
First, Download FreeType from `here <https://sourceforge.net/projects/freetype/files/>`__.
|
||||
|
||||
There are two ways to use FreeType:
|
||||
|
||||
For UNIX
|
||||
~~~~~~~~
|
||||
|
||||
For UNIX systems, it is recommended to use the way of compiling and installing libraries.
|
||||
|
||||
- Enter the FreeType source code directory
|
||||
- ``make``
|
||||
- ``sudo make install``
|
||||
- Add include path: ``/usr/include/freetype2`` (for GCC: ``-I/usr/include/freetype2 -L/usr/local/lib``)
|
||||
- Link library: ``freetype`` (for GCC: ``-L/usr/local/lib -lfreetype``)
|
||||
|
||||
For Embedded Devices
|
||||
~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
For embedded devices, it is more recommended to use the FreeType
|
||||
configuration file provided by LVGL, which only includes the most
|
||||
commonly used functions, which is very meaningful for saving limited
|
||||
FLASH space.
|
||||
|
||||
- Copy the FreeType source code to your project directory.
|
||||
- Refer to the following ``Makefile`` for configuration:
|
||||
|
||||
.. code:: make
|
||||
|
||||
# FreeType custom configuration header file
|
||||
CFLAGS += -DFT2_BUILD_LIBRARY
|
||||
CFLAGS += -DFT_CONFIG_MODULES_H=<lvgl/src/libs/freetype/ftmodule.h>
|
||||
CFLAGS += -DFT_CONFIG_OPTIONS_H=<lvgl/src/libs/freetype/ftoption.h>
|
||||
|
||||
# FreeType include path
|
||||
CFLAGS += -Ifreetype/include
|
||||
|
||||
# FreeType C source file
|
||||
FT_CSRCS += freetype/src/base/ftbase.c
|
||||
FT_CSRCS += freetype/src/base/ftbitmap.c
|
||||
FT_CSRCS += freetype/src/base/ftdebug.c
|
||||
FT_CSRCS += freetype/src/base/ftglyph.c
|
||||
FT_CSRCS += freetype/src/base/ftinit.c
|
||||
FT_CSRCS += freetype/src/cache/ftcache.c
|
||||
FT_CSRCS += freetype/src/gzip/ftgzip.c
|
||||
FT_CSRCS += freetype/src/sfnt/sfnt.c
|
||||
FT_CSRCS += freetype/src/smooth/smooth.c
|
||||
FT_CSRCS += freetype/src/truetype/truetype.c
|
||||
CSRCS += $(FT_CSRCS)
|
||||
|
||||
.. _freetype_usage:
|
||||
|
||||
Usage
|
||||
-----
|
||||
|
||||
Enable :c:macro:`LV_USE_FREETYPE` in ``lv_conf.h``.
|
||||
|
||||
Cache configuration:
|
||||
|
||||
- :c:macro:`LV_FREETYPE_CACHE_FT_GLYPH_CNT` Maximum number of cached glyphs., etc.
|
||||
|
||||
By default, the FreeType extension doesn't use LVGL's file system. You
|
||||
can simply pass the path to the font as usual on your operating system
|
||||
or platform.
|
||||
|
||||
If you want FreeType to use lvgl's memory allocation and file system
|
||||
interface, you can enable :c:macro:`LV_FREETYPE_USE_LVGL_PORT` in
|
||||
``lv_conf.h``, convenient for unified management.
|
||||
|
||||
The font style supports *Italic* and **Bold** fonts processed by
|
||||
software, and can be set with reference to the following values:
|
||||
|
||||
- :cpp:enumerator:`LV_FREETYPE_FONT_STYLE_NORMAL`: Default style.
|
||||
- :cpp:enumerator:`LV_FREETYPE_FONT_STYLE_ITALIC`: Italic style.
|
||||
- :cpp:enumerator:`LV_FREETYPE_FONT_STYLE_BOLD`: Bold style.
|
||||
|
||||
They can be combined.eg:
|
||||
:cpp:expr:`LV_FREETYPE_FONT_STYLE_BOLD | LV_FREETYPE_FONT_STYLE_ITALIC`.
|
||||
|
||||
Use the :cpp:func:`lv_freetype_font_create` function to create a font. To
|
||||
delete a font, use :cpp:func:`lv_freetype_font_delete`. For more detailed usage,
|
||||
please refer to example code.
|
||||
|
||||
.. _freetype_example:
|
||||
|
||||
Example
|
||||
-------
|
||||
|
||||
.. include:: ../examples/libs/freetype/index.rst
|
||||
|
||||
Learn more
|
||||
----------
|
||||
|
||||
- FreeType`tutorial <https://www.freetype.org/freetype2/docs/tutorial/step1.html>`__
|
||||
- LVGL's :ref:`add_font`
|
||||
|
||||
.. _freetype_api:
|
||||
|
||||
API
|
||||
---
|
||||
|
||||
:ref:`ftoption`
|
||||
|
||||
:ref:`ftmodule`
|
||||
|
||||
77
libraries/lvgl/docs/libs/fs.rst
Normal file
@@ -0,0 +1,77 @@
|
||||
.. _libs_filesystem:
|
||||
|
||||
======================
|
||||
File System Interfaces
|
||||
======================
|
||||
|
||||
LVGL has a :ref:`overview_file_system` module
|
||||
to provide an abstraction layer for various file system drivers.
|
||||
|
||||
LVG has built in support for:
|
||||
|
||||
- `FATFS <http://elm-chan.org/fsw/ff/00index_e.html>`__
|
||||
- STDIO (Linux and Windows using C standard function .e.g ``fopen``, ``fread``)
|
||||
- POSIX (Linux and Windows using POSIX function .e.g ``open``, ``read``)
|
||||
- WIN32 (Windows using Win32 API function .e.g ``CreateFileA``, ``ReadFile``)
|
||||
- MEMFS (read a file from a memory buffer)
|
||||
- LITTLEFS (a little fail-safe filesystem designed for microcontrollers)
|
||||
- Arduino ESP LITTLEFS (a little fail-safe filesystem designed for Arduino ESP)
|
||||
- Arduino SD (allows for reading from and writing to SD cards)
|
||||
|
||||
You still need to provide the drivers and libraries, this extension
|
||||
provides only the bridge between FATFS, STDIO, POSIX, WIN32 and LVGL.
|
||||
|
||||
.. _libs_filesystem_usage:
|
||||
|
||||
Usage
|
||||
*****
|
||||
|
||||
In ``lv_conf.h`` enable ``LV_USE_FS_...`` and assign an upper cased
|
||||
letter to ``LV_FS_..._LETTER`` (e.g. ``'S'``). After that you can access
|
||||
files using that driver letter. E.g. ``"S:path/to/file.txt"``.
|
||||
|
||||
Working with common prefixes
|
||||
""""""""""""""""""""""""""""
|
||||
|
||||
A **default driver letter** can be set by ``LV_FS_DEFAULT_DRIVE_LETTER``,
|
||||
which allows skipping the drive prefix in file paths.
|
||||
|
||||
For example if ``LV_FS_DEFAULT_DRIVE_LETTER`` is set the ``'S'`` *"path/to/file.txt"* will mean *"S:path/to/file.txt"*.
|
||||
|
||||
This feature is useful if you have only a single driver and don't want to bother with LVGL's driver layer in the file paths.
|
||||
It also helps to use a unified path with LVGL's file system and normal file systems.
|
||||
The original mechanism is not affected, so a path starting with drive letter will still work.
|
||||
|
||||
The **working directory** can be set with ``LV_FS_..._PATH``. E.g.
|
||||
``"/home/joe/projects/"`` The actual file/directory paths will be
|
||||
appended to it, allowing to skip the common part.
|
||||
|
||||
Caching
|
||||
"""""""
|
||||
|
||||
:ref:`Cached reading <overview_file_system_cache>` is also supported if ``LV_FS_..._CACHE_SIZE`` is set to
|
||||
not ``0`` value. :cpp:func:`lv_fs_read` caches this size of data to lower the
|
||||
number of actual reads from the storage.
|
||||
|
||||
To use the memory-mapped file emulation an ``lv_fs_path_ex_t`` object must be
|
||||
created and initialized. This object can be passed to :cpp:func:`lv_fs_open` as
|
||||
the file name:
|
||||
|
||||
.. code:: c
|
||||
|
||||
lv_fs_path_ex_t mempath;
|
||||
lv_fs_file_t file;
|
||||
uint8_t *buffer;
|
||||
uint32_t size;
|
||||
|
||||
/*Initialize buffer*/
|
||||
...
|
||||
|
||||
lv_fs_make_path_from_buffer(&mempath, LV_FS_MEMFS_LETTER, (void*)buffer, size);
|
||||
lv_fs_res_t res = lv_fs_open(&file, (const char *)&mempath, LV_FS_MODE_RD);
|
||||
|
||||
.. _libs_filesystem_api:
|
||||
|
||||
API
|
||||
***
|
||||
|
||||
61
libraries/lvgl/docs/libs/gif.rst
Normal file
@@ -0,0 +1,61 @@
|
||||
.. _gif:
|
||||
|
||||
===========
|
||||
GIF decoder
|
||||
===========
|
||||
|
||||
Allow using GIF images in LVGL.
|
||||
|
||||
Detailed introduction: https://github.com/lecram/gifdec
|
||||
|
||||
When enabled in ``lv_conf.h`` with :c:macro:`LV_USE_GIF`
|
||||
:cpp:expr:`lv_gif_create(parent)` can be used to create a gif widget.
|
||||
|
||||
:cpp:expr:`lv_gif_set_src(obj, src)` works very similarly to :cpp:func:`lv_image_set_src`.
|
||||
As source, it also accepts images as variables (:c:struct:`lv_image_dsc_t`) or
|
||||
files.
|
||||
|
||||
Convert GIF files to C array
|
||||
----------------------------
|
||||
|
||||
To convert a GIF file to byte values array use `LVGL's online
|
||||
converter <https://lvgl.io/tools/imageconverter>`__. Select "Raw" color
|
||||
format and "C array" Output format.
|
||||
|
||||
Use GIF images from file
|
||||
------------------------
|
||||
|
||||
For example:
|
||||
|
||||
.. code:: c
|
||||
|
||||
lv_gif_set_src(obj, "S:path/to/example.gif");
|
||||
|
||||
Note that, a file system driver needs to be registered to open images
|
||||
from files. Read more about it :ref:`overview_file_system` or just
|
||||
enable one in ``lv_conf.h`` with ``LV_USE_FS_...``
|
||||
|
||||
Memory requirements
|
||||
-------------------
|
||||
|
||||
To decode and display a GIF animation the following amount of RAM is
|
||||
required:
|
||||
|
||||
- :c:macro:`LV_COLOR_DEPTH` ``8``: 3 x image width x image height
|
||||
- :c:macro:`LV_COLOR_DEPTH` ``16``: 4 x image width x image height
|
||||
- :c:macro:`LV_COLOR_DEPTH` ``32``: 5 x image width x image height
|
||||
|
||||
.. _gif_example:
|
||||
|
||||
Example
|
||||
-------
|
||||
|
||||
.. include:: ../examples/libs/gif/index.rst
|
||||
|
||||
.. _gif_api:
|
||||
|
||||
API
|
||||
---
|
||||
|
||||
:ref:`gifdec`
|
||||
|
||||