feat(docs): migrate from .md to .rst (#4129)
This commit is contained in:
1925
docs/CHANGELOG.md
1925
docs/CHANGELOG.md
File diff suppressed because it is too large
Load Diff
4111
docs/CHANGELOG.rst
Normal file
4111
docs/CHANGELOG.rst
Normal file
File diff suppressed because it is too large
Load Diff
@@ -1,46 +0,0 @@
|
||||
# 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][homepage], version 1.4, available at [http://contributor-covenant.org/version/1/4][version]
|
||||
|
||||
[homepage]: http://contributor-covenant.org
|
||||
[version]: http://contributor-covenant.org/version/1/4/
|
||||
83
docs/CODE_OF_CONDUCT.rst.back
Normal file
83
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/>`__
|
||||
@@ -1,124 +0,0 @@
|
||||
# Coding style
|
||||
|
||||
## File format
|
||||
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: *btn*, *label*, *style* etc.
|
||||
* followed by the action (for functions): *set*, *get*, *refr* 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:
|
||||
* Only words longer or equal than 6 characters can be abbreviated.
|
||||
* Abbreviate only if it makes the word at least half as long
|
||||
* Use only very straightforward and well-known abbreviations (e.g. pos: position, def: default, btn: button)
|
||||
|
||||
## Coding guide
|
||||
* Functions:
|
||||
* Try to write function shorter than is 50 lines
|
||||
* Always shorter than 200 lines (except very straightforwards)
|
||||
* 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 a comment like this:
|
||||
|
||||
```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_scr(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. ``/*Update the value of `x_act`*/``
|
||||
|
||||
### Formatting
|
||||
Here is example to show bracket placing and using of white spaces:
|
||||
```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 [instalation 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:
|
||||
```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:
|
||||
```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:
|
||||
```console
|
||||
pre-commit run name-of-the-hook
|
||||
```
|
||||
168
docs/CODING_STYLE.rst
Normal file
168
docs/CODING_STYLE.rst
Normal file
@@ -0,0 +1,168 @@
|
||||
Coding style
|
||||
============
|
||||
|
||||
File format
|
||||
-----------
|
||||
|
||||
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: *btn*, *label*, *style* etc.
|
||||
- followed by the action (for functions): *set*, *get*, *refr* 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:
|
||||
|
||||
- Only words longer or equal than 6 characters can be abbreviated.
|
||||
- Abbreviate only if it makes the word at least half as long
|
||||
- Use only very straightforward and well-known abbreviations
|
||||
(e.g. pos: position, def: default, btn: button)
|
||||
|
||||
Coding guide
|
||||
------------
|
||||
|
||||
- Functions:
|
||||
|
||||
- Try to write function shorter than is 50 lines
|
||||
- Always shorter than 200 lines (except very straightforwards)
|
||||
|
||||
- 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 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_scr(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`*/`
|
||||
|
||||
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 `instalation
|
||||
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
|
||||
@@ -1,296 +0,0 @@
|
||||
|
||||
# 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!
|
||||
|
||||
Before getting started here are some guidelines to make contribution smoother:
|
||||
- Be kind and friendly.
|
||||
- Be sure to read the relevant part of the documentation before posting a question.
|
||||
- Ask questions in the [Forum](https://forum.lvgl.io/) and use [GitHub](https://github.com/lvgl/) for development-related discussions.
|
||||
- Always fill out the post or issue templates in the Forum or GitHub (or at least provide equivalent information). It makes understanding your contribution or issue easier and you will get a useful response faster.
|
||||
- If possible send an absolute minimal but buildable code example in order to reproduce the issue. Be sure it contains all the required variable declarations, constants, and assets (images, fonts).
|
||||
- Use [Markdown](https://github.com/adam-p/markdown-here/wiki/Markdown-Cheatsheet) to format your posts. You can learn it in 10 minutes.
|
||||
- Speak about one thing in one issue or topic. It makes your post easier to find later for someone with the same question.
|
||||
- Give feedback and close the issue or mark the topic as solved if your question is answered.
|
||||
- For non-trivial fixes and features, it's better to open an issue first to discuss the details instead of sending a pull request directly.
|
||||
- Please read and follow the <a href="https://github.com/lvgl/lvgl/blob/master/docs/CODING_STYLE.md">Coding style</a> guide.
|
||||
|
||||
## 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](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`
|
||||
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.
|
||||
7. 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.
|
||||
8. Describe what is in the update. An example code is welcome if applicable.
|
||||
9. If you need to make more changes, just update your forked `lvgl` repo with new commits. They will automatically appear in the PR.
|
||||
|
||||
### 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:
|
||||
```
|
||||
<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
|
||||
```
|
||||
|
||||
## 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/](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:
|
||||
```
|
||||
/* 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 can not accept GPL licensed code.
|
||||
|
||||
## Ways to contribute
|
||||
|
||||
Even if you're just getting started with LVGL there are plenty of ways to get your feet wet.
|
||||
Most of these options don't even require knowing a single line of LVGL code.
|
||||
|
||||
Below we have collected some opportunities about the ways you can contribute to LVGL.
|
||||
|
||||
### Give LVGL a Star
|
||||
|
||||
Show that you like LVGL by giving it star on GitHub!
|
||||
<!-- Place this tag in your head or just before your close body tag. -->
|
||||
<script async defer src="https://buttons.github.io/buttons.js"></script>
|
||||
<!-- Place this tag where you want the button to render. -->
|
||||
<a class="github-button" href="https://github.com/lvgl/lvgl" data-icon="octicon-star" data-size="large" data-show-count="true" aria-label="Star lvgl/lvgl on GitHub">Star</a>
|
||||
|
||||
This simple click makes LVGL more visible on GitHub and makes it more attractive to other people.
|
||||
So with this, you already helped a lot!
|
||||
|
||||
### Tell what you have achieved
|
||||
|
||||
Have you already started using LVGL in a [Simulator](/get-started/platforms/pc-simulator), a development board, or on your custom hardware?
|
||||
Was it easy or were there some obstacles? Are you happy with the result?
|
||||
Showing your project to others is a win-win situation because it increases your and LVGL's reputation at the same time.
|
||||
|
||||
You can post about your project on Twitter, Facebook, LinkedIn, create a YouTube video, and so on.
|
||||
Only one thing: On social media don't forget to add a link to `https://lvgl.io` or `https://github.com/lvgl` and use the hashtag `#lvgl`. Thank you! :)
|
||||
|
||||
You can also open a new topic in the [My projects](https://forum.lvgl.io/c/my-projects/10) category of the Forum.
|
||||
|
||||
The [LVGL Blog](https://blog.lvgl.io) welcomes posts from anyone.
|
||||
It's a good place to talk about a project you created with LVGL, write a tutorial, or share some nice tricks.
|
||||
The latest blog posts are shown on the [homepage of LVGL](https://lvgl.io) to make your work more visible.
|
||||
|
||||
The blog is hosted on GitHub. If you add a post GitHub automatically turns it into a website.
|
||||
See the [README](https://github.com/lvgl/blog) of the blog repo to see how to add your post.
|
||||
|
||||
Any of these help to spread the word and familiarize new developers with LVGL.
|
||||
|
||||
If you don't want to speak about your project publicly, feel free to use [Contact form](https://lvgl.io/#contact) on lvgl.io to private message to us.
|
||||
|
||||
### Write examples
|
||||
As you learn LVGL you will probably play with the features of widgets. Why not publish your experiments?
|
||||
|
||||
Each widgets' documentation contains examples. For instance, here are the examples of the [Drop-down list](/widgets/dropdown#examples) widget.
|
||||
The examples are directly loaded from the [lvgl/examples](https://github.com/lvgl/lvgl/tree/master/examples) folder.
|
||||
|
||||
So all you need to do is send a [Pull request](#pull-request) to the [lvgl](https://github.com/lvgl/lvgl) repository and follow some conventions:
|
||||
- Name the examples like `lv_example_<widget_name>_<index>`.
|
||||
- Make the example as short and simple as possible.
|
||||
- Add comments to explain what the example does.
|
||||
- Use 320x240 resolution.
|
||||
- Update `index.rst` in the example's folder with your new example. To see how other examples are added, look in the [lvgl/examples/widgets](https://github.com/lvgl/lvgl/tree/master/examples/widgets) folder.
|
||||
|
||||
### Improve the docs
|
||||
|
||||
As you read the documentation you might see some typos or unclear sentences. All the documentation is located in the [lvgl/docs](https://github.com/lvgl/lvgl/tree/master/docs) folder.
|
||||
For typos and straightforward fixes, you can simply edit the file on GitHub.
|
||||
|
||||
Note that the documentation is also formatted in [Markdown](https://github.com/adam-p/markdown-here/wiki/Markdown-Cheatsheet).
|
||||
|
||||
### Report bugs
|
||||
As you use LVGL you might find bugs. Before reporting them be sure to check the relevant parts of the documentation.
|
||||
|
||||
If it really seems like a bug feel free to open an [issue on GitHub](https://github.com/lvgl/lvgl/issues).
|
||||
|
||||
When filing the issue be sure to fill out the template. It helps find the root of the problem while avoiding extensive questions and exchanges with other developers.
|
||||
|
||||
### Send fixes
|
||||
The beauty of open-source software is you can easily dig in to it to understand how it works. You can also fix or adjust it as you wish.
|
||||
|
||||
If you found and fixed a bug don't hesitate to send a [Pull request](#pull-request) with the fix.
|
||||
|
||||
In your Pull request please also add a line to [`CHANGELOG.md`](https://github.com/lvgl/lvgl/blob/master/CHANGELOG.md).
|
||||
|
||||
### Join the conversations in the Forum
|
||||
It feels great to know you are not alone if something is not working. It's even better to help others when they struggle with something.
|
||||
|
||||
While you were learning LVGL you might have had questions and used the Forum to get answers. As a result, you probably have more knowledge about how LVGL works.
|
||||
|
||||
One of the best ways to give back is to use the Forum and answer the questions of newcomers - like you were once.
|
||||
|
||||
Just read the titles and if you are familiar with the topic don't hesitate to share your thoughts and suggestions.
|
||||
|
||||
Participating in the discussions is one of the best ways to become part of the project and get to know like-minded people!
|
||||
|
||||
### Add features
|
||||
If you have created a cool widget, or added useful feature to LVGL feel free to open a new PR for it.
|
||||
We collect the optional features (a.k.a. plugins) in [lvgl/src/extra](https://github.com/lvgl/lvgl/tree/master/src/extra) folder so if you are interested in adding a new features please use this folder.
|
||||
The [README](https://github.com/lvgl/lvgl/blob/master/src/extra/README.md) file describes the basics rules of contribution and also lists some ideas.
|
||||
|
||||
For further ideas take a look at the [Roadmap](/ROADMAP) page. If you are interested in any of them feel free to share your opinion and/or participate in the implementation.
|
||||
|
||||
Other features which are (still) not on the road map are listed in the [Feature request](https://forum.lvgl.io/c/feature-request/9) category of the Forum.
|
||||
|
||||
When adding a new features the followings also needs to be updated:
|
||||
- Update [lv_conf_template.h](https://github.com/lvgl/lvgl/blob/master/lv_conf_template.h)
|
||||
- Add description in the [docs](https://github.com/lvgl/lvgl/tree/master/docs)
|
||||
- Add [examples](https://github.com/lvgl/lvgl/tree/master/examples)
|
||||
- Update the [changelog](https://github.com/lvgl/lvgl/tree/master/docs/CHANGELOG.md)
|
||||
|
||||
### Become a maintainer
|
||||
|
||||
If you want to become part of the core development team, you can become a maintainer of a repository.
|
||||
|
||||
By becoming a maintainer:
|
||||
- You get write access to that repo:
|
||||
- Add code directly without sending a pull request
|
||||
- Accept pull requests
|
||||
- Close/reopen/edit issues
|
||||
- Your input has higher impact when we are making decisions
|
||||
|
||||
You can become a maintainer by invitation, however the following conditions need to met
|
||||
1. Have > 50 replies in the Forum. You can look at your stats [here](https://forum.lvgl.io/u?period=all)
|
||||
2. Send > 5 non-trivial pull requests to the repo where you would like to be a maintainer
|
||||
|
||||
|
||||
If you are interested, just send a message (e.g. from the Forum) to the current maintainers of the repository. They will check if the prerequisites are met.
|
||||
Note that meeting the prerequisites is not a guarantee of acceptance, i.e. if the conditions are met you won't automatically become a maintainer.
|
||||
It's up to the current maintainers to make the decision.
|
||||
|
||||
### Move your project repository under LVGL organization
|
||||
Besides the core `lvgl` repository there are other repos for ports to development boards, IDEs or other environment.
|
||||
If you ported LVGL to a new platform we can host it under the LVGL organization among the other repos.
|
||||
|
||||
This way your project will become part of the whole LVGL project and can get more visibility.
|
||||
If you are interested in this opportunity just open an [issue in lvgl repo](https://github.com/lvgl/lvgl/issues) and tell what you have!
|
||||
|
||||
If we agree that your port fit well into the LVGL organization, we will open a repository for your project where you will have admin rights.
|
||||
|
||||
To make this concept sustainable there a few rules to follow:
|
||||
- You need to add a README to your repo.
|
||||
- We expect to maintain the repo to some extent:
|
||||
- Follow at least the major versions of LVGL
|
||||
- Respond to the issues (in a reasonable time)
|
||||
- If there is no activity in a repo for 1 year it will be archived
|
||||
431
docs/CONTRIBUTING.rst
Normal file
431
docs/CONTRIBUTING.rst
Normal file
@@ -0,0 +1,431 @@
|
||||
.. _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!
|
||||
|
||||
Before getting started here are some guidelines to make contribution smoother:
|
||||
|
||||
- Be kind and friendly.
|
||||
- Be sure to read the relevant part of the documentation before posting a question.
|
||||
- Ask questions in the `Forum <https://forum.lvgl.io/>`__ and use
|
||||
`GitHub <https://github.com/lvgl/>`__ for development-related discussions.
|
||||
- Always fill out the post or issue templates in the Forum or GitHub (or at least provide equivalent information). It makes
|
||||
understanding your contribution or issue easier and you will get a useful response faster.
|
||||
- If possible send an absolute minimal but buildable code example in order to reproduce the issue. Be sure it
|
||||
contains all the required variable declarations, constants, and assets (images, fonts).
|
||||
- Use `Markdown <https://github.com/adam-p/markdown-here/wiki/Markdown-Cheatsheet>`__
|
||||
to format your posts. You can learn it in 10 minutes.
|
||||
- Speak about one thing in one issue or topic. It makes your post easier to find later for
|
||||
someone with the same question.
|
||||
- Give feedback and close the issue or mark the topic as solved if your question is answered.
|
||||
- For non-trivial fixes and features, it’s better to open an issue first to discuss the
|
||||
details instead of sending a pull request directly.
|
||||
- Please read and follow the Coding style guide.
|
||||
|
||||
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``
|
||||
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.
|
||||
|
||||
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
|
||||
|
||||
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
|
||||
can not accept GPL licensed code.
|
||||
|
||||
Ways to contribute
|
||||
------------------
|
||||
|
||||
Even if you’re just getting started with LVGL there are plenty of ways
|
||||
to get your feet wet. Most of these options don’t even require knowing a
|
||||
single line of LVGL code.
|
||||
|
||||
Below we have collected some opportunities about the ways you can
|
||||
contribute to LVGL.
|
||||
|
||||
Give LVGL a Star
|
||||
~~~~~~~~~~~~~~~~
|
||||
|
||||
Show that you like LVGL by giving it star on GitHub!
|
||||
|
||||
.. raw:: html
|
||||
|
||||
<script async defer src="https://buttons.github.io/buttons.js"></script>
|
||||
|
||||
.. raw:: html
|
||||
|
||||
<!-- Place this tag where you want the button to render. -->
|
||||
|
||||
Star
|
||||
|
||||
This simple click makes LVGL more visible on GitHub and makes it more
|
||||
attractive to other people. So with this, you already helped a lot!
|
||||
|
||||
Tell what you have achieved
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Have you already started using LVGL in a
|
||||
`Simulator </get-started/platforms/pc-simulator>`__, a development
|
||||
board, or on your custom hardware? Was it easy or were there some
|
||||
obstacles? Are you happy with the result? Showing your project to others
|
||||
is a win-win situation because it increases your and LVGL’s reputation
|
||||
at the same time.
|
||||
|
||||
You can post about your project on Twitter, Facebook, LinkedIn, create a
|
||||
YouTube video, and so on. Only one thing: On social media don’t forget
|
||||
to add a link to ``https://lvgl.io`` or ``https://github.com/lvgl`` and
|
||||
use the hashtag ``#lvgl``. Thank you! :)
|
||||
|
||||
You can also open a new topic in the `My
|
||||
projects <https://forum.lvgl.io/c/my-projects/10>`__ category of the
|
||||
Forum.
|
||||
|
||||
The `LVGL Blog <https://blog.lvgl.io>`__ welcomes posts from anyone.
|
||||
It’s a good place to talk about a project you created with LVGL, write a
|
||||
tutorial, or share some nice tricks. The latest blog posts are shown on
|
||||
the `homepage of LVGL <https://lvgl.io>`__ to make your work more
|
||||
visible.
|
||||
|
||||
The blog is hosted on GitHub. If you add a post GitHub automatically
|
||||
turns it into a website. See the
|
||||
`README <https://github.com/lvgl/blog>`__ of the blog repo to see how to
|
||||
add your post.
|
||||
|
||||
Any of these help to spread the word and familiarize new developers with
|
||||
LVGL.
|
||||
|
||||
If you don’t want to speak about your project publicly, feel free to use
|
||||
`Contact form <https://lvgl.io/#contact>`__ on lvgl.io to private
|
||||
message to us.
|
||||
|
||||
Write examples
|
||||
~~~~~~~~~~~~~~
|
||||
|
||||
As you learn LVGL you will probably play with the features of widgets.
|
||||
Why not publish your experiments?
|
||||
|
||||
Each widgets’ documentation contains examples. For instance, here are
|
||||
the examples of the `Drop-down list </widgets/dropdown#examples>`__
|
||||
widget. The examples are directly loaded from the
|
||||
`lvgl/examples <https://github.com/lvgl/lvgl/tree/master/examples>`__
|
||||
folder.
|
||||
|
||||
So all you need to do is send a `Pull request <#pull-request>`__ to the
|
||||
`lvgl <https://github.com/lvgl/lvgl>`__ repository and follow some
|
||||
conventions:
|
||||
|
||||
- Name the examples like ``lv_example_<widget_name>_<index>``.
|
||||
- Make the example as short and simple as possible.
|
||||
- Add comments to explain what the example does.
|
||||
- Use 320x240 resolution.
|
||||
- Update ``index.rst`` in the example’s folder with your new example. To see how other examples are added, look in the
|
||||
`lvgl/examples/widgets <https://github.com/lvgl/lvgl/tree/master/examples/widgets>`__
|
||||
folder.
|
||||
|
||||
Improve the docs
|
||||
~~~~~~~~~~~~~~~~
|
||||
|
||||
As you read the documentation you might see some typos or unclear
|
||||
sentences. All the documentation is located in the
|
||||
`lvgl/docs <https://github.com/lvgl/lvgl/tree/master/docs>`__ folder.
|
||||
For typos and straightforward fixes, you can simply edit the file on
|
||||
GitHub.
|
||||
|
||||
Note that the documentation is also formatted in
|
||||
`Markdown <https://github.com/adam-p/markdown-here/wiki/Markdown-Cheatsheet>`__.
|
||||
|
||||
Report bugs
|
||||
~~~~~~~~~~~
|
||||
|
||||
As you use LVGL you might find bugs. Before reporting them be sure to
|
||||
check the relevant parts of the documentation.
|
||||
|
||||
If it really seems like a bug feel free to open an `issue on
|
||||
GitHub <https://github.com/lvgl/lvgl/issues>`__.
|
||||
|
||||
When filing the issue be sure to fill out the template. It helps find
|
||||
the root of the problem while avoiding extensive questions and exchanges
|
||||
with other developers.
|
||||
|
||||
Send fixes
|
||||
~~~~~~~~~~
|
||||
|
||||
The beauty of open-source software is you can easily dig in to it to
|
||||
understand how it works. You can also fix or adjust it as you wish.
|
||||
|
||||
If you found and fixed a bug don’t hesitate to send a `Pull
|
||||
request <#pull-request>`__ with the fix.
|
||||
|
||||
In your Pull request please also add a line to
|
||||
```CHANGELOG.md`` <https://github.com/lvgl/lvgl/blob/master/CHANGELOG.md>`__.
|
||||
|
||||
Join the conversations in the Forum
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
It feels great to know you are not alone if something is not working.
|
||||
It’s even better to help others when they struggle with something.
|
||||
|
||||
While you were learning LVGL you might have had questions and used the
|
||||
Forum to get answers. As a result, you probably have more knowledge
|
||||
about how LVGL works.
|
||||
|
||||
One of the best ways to give back is to use the Forum and answer the
|
||||
questions of newcomers - like you were once.
|
||||
|
||||
Just read the titles and if you are familiar with the topic don’t
|
||||
hesitate to share your thoughts and suggestions.
|
||||
|
||||
Participating in the discussions is one of the best ways to become part
|
||||
of the project and get to know like-minded people!
|
||||
|
||||
Add features
|
||||
~~~~~~~~~~~~
|
||||
|
||||
If you have created a cool widget, or added useful feature to LVGL feel
|
||||
free to open a new PR for it. We collect the optional features (a.k.a.
|
||||
plugins) in
|
||||
`lvgl/src/extra <https://github.com/lvgl/lvgl/tree/master/src/extra>`__
|
||||
folder so if you are interested in adding a new features please use this
|
||||
folder. The
|
||||
`README <https://github.com/lvgl/lvgl/blob/master/src/extra/README.md>`__
|
||||
file describes the basics rules of contribution and also lists some
|
||||
ideas.
|
||||
|
||||
For further ideas take a look at the `Roadmap </ROADMAP>`__ page. If you
|
||||
are interested in any of them feel free to share your opinion and/or
|
||||
participate in the implementation.
|
||||
|
||||
Other features which are (still) not on the road map are listed in the
|
||||
`Feature request <https://forum.lvgl.io/c/feature-request/9>`__ category
|
||||
of the Forum.
|
||||
|
||||
When adding a new features the followings also needs to be updated:
|
||||
|
||||
- Update `lv_conf_template.h <https://github.com/lvgl/lvgl/blob/master/lv_conf_template.h>`__
|
||||
- Add description in the `docs <https://github.com/lvgl/lvgl/tree/master/docs>`__
|
||||
- Add `examples <https://github.com/lvgl/lvgl/tree/master/examples>`__
|
||||
- Update the `changelog <https://github.com/lvgl/lvgl/tree/master/docs/CHANGELOG.md>`__
|
||||
|
||||
Become a maintainer
|
||||
~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
If you want to become part of the core development team, you can become
|
||||
a maintainer of a repository.
|
||||
|
||||
By becoming a maintainer:
|
||||
|
||||
- You get write access to that repo:
|
||||
|
||||
- Add code directly without sending a pull request
|
||||
- Accept pull requests - Close/reopen/edit issues - Your input has higher impact when we are making decisions
|
||||
|
||||
You can become a maintainer by invitation, however the following
|
||||
conditions need to met 1. Have > 50 replies in the Forum. You can look
|
||||
at your stats `here <https://forum.lvgl.io/u?period=all>`__ 2. Send > 5
|
||||
non-trivial pull requests to the repo where you would like to be a
|
||||
maintainer
|
||||
|
||||
If you are interested, just send a message (e.g. from the Forum) to the
|
||||
current maintainers of the repository. They will check if the
|
||||
prerequisites are met. Note that meeting the prerequisites is not a
|
||||
guarantee of acceptance, i.e. if the conditions are met you won’t
|
||||
automatically become a maintainer. It’s up to the current maintainers to
|
||||
make the decision.
|
||||
|
||||
Move your project repository under LVGL organization
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Besides the core ``lvgl`` repository there are other repos for ports to
|
||||
development boards, IDEs or other environment. If you ported LVGL to a
|
||||
new platform we can host it under the LVGL organization among the other
|
||||
repos.
|
||||
|
||||
This way your project will become part of the whole LVGL project and can
|
||||
get more visibility. If you are interested in this opportunity just open
|
||||
an `issue in lvgl repo <https://github.com/lvgl/lvgl/issues>`__ and tell
|
||||
what you have!
|
||||
|
||||
If we agree that your port fit well into the LVGL organization, we will
|
||||
open a repository for your project where you will have admin rights.
|
||||
|
||||
To make this concept sustainable there a few rules to follow:
|
||||
|
||||
- You need to add a README to your repo.
|
||||
- We expect to maintain the repo to some extent
|
||||
- Follow at least the major versions of LVGL
|
||||
- Respond to the issues (in a reasonable time)
|
||||
- If there is no activity in a repo for 1 year it will be archived
|
||||
2455
docs/Doxyfile
Normal file
2455
docs/Doxyfile
Normal file
File diff suppressed because it is too large
Load Diff
@@ -1,430 +0,0 @@
|
||||
<p align="right"><a href="../README.md">English</a> | <a href="./README_zh.md">中文</a> | <a href="./README_pt_BR.md">Português do Brasil</a> | <b>日本語</b></p>
|
||||
|
||||
<br>
|
||||
<p align="center">
|
||||
<img src="https://lvgl.io/assets/images/logo_lvgl.png">
|
||||
</p>
|
||||
|
||||
<h1 align="center">Light and Versatile Graphics Library</h1>
|
||||
<br>
|
||||
<div align="center">
|
||||
<img src="https://github.com/kisvegabor/test/raw/master/smartwatch_demo.gif">
|
||||
|
||||
<img border="1px" src="https://lvgl.io/assets/images/lvgl_widgets_demo.gif">
|
||||
</div>
|
||||
<br>
|
||||
<p align="center">
|
||||
<a href="https://lvgl-io.translate.goog/?_x_tr_sl=en&_x_tr_tl=ja&_x_tr_hl=ja" title="Homepage of LVGL">Website </a></a> |
|
||||
<a href="https://docs-lvgl-io.translate.goog/master/index.html?_x_tr_sl=en&_x_tr_tl=ja&_x_tr_hl=ja" title="Detailed documentation with 100+ examples">Docs</a> |
|
||||
<a href="https://forum.lvgl.io" title="Get help and help others">Forum</a> :gb: |
|
||||
<a href="https://lvgl-io.translate.goog/demos?_x_tr_sl=en&_x_tr_tl=ja&_x_tr_hl=ja" title="Demos running in your browser">Demos</a> |
|
||||
<a href="https://lvgl-io.translate.goog/services?_x_tr_sl=en&_x_tr_tl=ja&_x_tr_hl=ja" title="Graphics design, UI implementation and consulting">Services</a> |
|
||||
<a href="https://squareline.io/" title="UI Editor for LVGL">SquareLine Studio</a> :gb:
|
||||
</p>
|
||||
<br>
|
||||
|
||||
## :ledger: Overview
|
||||
|
||||
**実績**<br>
|
||||
LVGL は、フリー&オープンソースの組み込み用グラフィックスライブラリです。
|
||||
あらゆるMCU、MPU、ディスプレイタイプに対応しており、美しいUI(User Interface)を実現できます。
|
||||
ARM, STM32, NXP, Espressif, Nuvoton, Arduino, RT-Thread, Zephyr, NuttX, Adafruitなど、業界をリードするベンダーやプロジェクトによりサポートされています。
|
||||
|
||||
**機能豊富**<br>
|
||||
モダンで美しいGUIを作成するための機能をすべて備えています。
|
||||
30以上の組み込みウィジェット、強力なスタイルシステム、WEB由来のレイアウトマネージャ、多くの言語をサポートする文字グラフィックシステムなどです。
|
||||
LVGL のシステム要件は、RAM 32KB、Flash 128KB、Cコンパイラ、フレームバッファ、1/10スクリーンサイズのレンダリング用バッファです。
|
||||
|
||||
**UIエディタ**<br>
|
||||
SquareLine Studio は、LVGL用のプロフェッショナル&リーズナブルなドラッグ&ドロップ型のUIエディターです。
|
||||
Windows、Linux、MacOS で動作し、ウェブサイトへの登録なしで試すことができます。
|
||||
|
||||
**サービス**<br>
|
||||
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
|
||||
|
||||

|
||||
|
||||
<details>
|
||||
<summary>C code</summary>
|
||||
|
||||
```c
|
||||
lv_obj_t * btn = lv_btn_create(lv_scr_act()); /*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");
|
||||
}
|
||||
```
|
||||
</details>
|
||||
|
||||
<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">Online Simulator</a> :gb:</summary>
|
||||
|
||||
```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()
|
||||
```
|
||||
</details>
|
||||
<br>
|
||||
|
||||
### Checkboxes with Layout
|
||||

|
||||
|
||||
<details>
|
||||
<summary>C code</summary>
|
||||
|
||||
```c
|
||||
|
||||
lv_obj_set_flex_flow(lv_scr_act(), LV_FLEX_FLOW_COLUMN);
|
||||
lv_obj_set_flex_align(lv_scr_act(), LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_START, LV_FLEX_ALIGN_CENTER);
|
||||
|
||||
lv_obj_t * cb;
|
||||
cb = lv_checkbox_create(lv_scr_act());
|
||||
lv_checkbox_set_text(cb, "Apple");
|
||||
lv_obj_add_event(cb, event_handler, LV_EVENT_ALL, NULL);
|
||||
|
||||
cb = lv_checkbox_create(lv_scr_act());
|
||||
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_scr_act());
|
||||
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_scr_act());
|
||||
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);
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
<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">Online Simulator</a> :gb:</summary>
|
||||
|
||||
```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)
|
||||
```
|
||||
|
||||
</details>
|
||||
<br>
|
||||
|
||||
### Styling a Slider
|
||||

|
||||
|
||||
|
||||
<details>
|
||||
<summary>C code</summary>
|
||||
|
||||
```c
|
||||
lv_obj_t * slider = lv_slider_create(lv_scr_act());
|
||||
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);
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
<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">Online Simulator</a> :gb:
|
||||
</summary>
|
||||
|
||||
|
||||
```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)
|
||||
```
|
||||
</details>
|
||||
<br>
|
||||
|
||||
### English, Hebrew (mixed LRT-RTL) and Chinese texts
|
||||
|
||||

|
||||
|
||||
<details>
|
||||
<summary>C code</summary>
|
||||
|
||||
```c
|
||||
lv_obj_t * ltr_label = lv_label_create(lv_scr_act());
|
||||
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_scr_act());
|
||||
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_scr_act());
|
||||
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);
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
<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">Online Simulator</a> :gb:</summary>
|
||||
|
||||
```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)
|
||||
|
||||
```
|
||||
</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:
|
||||
|
||||
<a href="https://github.com/lvgl/lvgl/graphs/contributors">
|
||||
<img src="https://contrib.rocks/image?repo=lvgl/lvgl&max=48" />
|
||||
</a>
|
||||
|
||||
... and many other.
|
||||
648
docs/README_jp.rst.back
Normal file
648
docs/README_jp.rst.back
Normal file
@@ -0,0 +1,648 @@
|
||||
.. raw:: html
|
||||
|
||||
<p align="right">
|
||||
|
||||
English \| 中文 \| Português do Brasil \| 日本語
|
||||
|
||||
.. 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_btn_create(lv_scr_act()); /*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_scr_act(), LV_FLEX_FLOW_COLUMN);
|
||||
lv_obj_set_flex_align(lv_scr_act(), LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_START, LV_FLEX_ALIGN_CENTER);
|
||||
|
||||
lv_obj_t * cb;
|
||||
cb = lv_checkbox_create(lv_scr_act());
|
||||
lv_checkbox_set_text(cb, "Apple");
|
||||
lv_obj_add_event(cb, event_handler, LV_EVENT_ALL, NULL);
|
||||
|
||||
cb = lv_checkbox_create(lv_scr_act());
|
||||
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_scr_act());
|
||||
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_scr_act());
|
||||
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_scr_act());
|
||||
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_scr_act());
|
||||
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_scr_act());
|
||||
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_scr_act());
|
||||
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.
|
||||
@@ -1,451 +0,0 @@
|
||||
**NOTA IMPORTANTE** A próxima versão principal (v9.0.0) está sendo desenvolvida na branch master.
|
||||
A última versão estável está disponível na branch [release/v8.3](https://github.com/lvgl/lvgl/tree/release/v8.3).
|
||||
|
||||
---
|
||||
|
||||
<a href="https://opencollective.com/lvgl" target="_blank"><img align="left" src="https://lvgl.io/assets/images/sponsor.png" height="32px"></a>
|
||||
|
||||
<p align="right">
|
||||
<a href="../README.md">English</a> |
|
||||
<a href="./README_zh.md">中文</a> |
|
||||
<b>Português do Brasil</b> |
|
||||
<a href="./README_jp.md">日本語</a>
|
||||
</p>
|
||||
|
||||
<p align="center">
|
||||
<img src="https://lvgl.io/assets/images/logo_lvgl.png">
|
||||
</p>
|
||||
|
||||
<h1 align="center">LVGL - Biblioteca gráfica leve e versátil</h1>
|
||||
<br>
|
||||
<div align="center">
|
||||
<img src="https://github.com/kisvegabor/test/raw/master/smartwatch_demo.gif">
|
||||
|
||||
<img border="1px" src="https://lvgl.io/assets/images/lvgl_widgets_demo.gif">
|
||||
</div>
|
||||
<br>
|
||||
<p align="center">
|
||||
<a href="https://lvgl.io" title="Página inicial do LVGL">Site</a> |
|
||||
<a href="https://docs.lvgl.io/" title="Documentação detalhada com +100 exemplos">Documentação</a> |
|
||||
<a href="https://forum.lvgl.io" title="Obtenha ajuda e ajude outras pessoas">Fórum</a> |
|
||||
<a href="https://lvgl.io/services" title="Design gráfico, implementações e consultoria de serviços">Serviços</a> |
|
||||
<a href="https://lvgl.io/demos" title="Execute demonstrações no seu navegador">Demonstrações</a> |
|
||||
<a href="https://squareline.io/" title="Editor web para LVGL">Editor SquareLine Studio</a>
|
||||
</p>
|
||||
<br>
|
||||
|
||||
## :monocle_face: 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.
|
||||
|
||||
## :rocket: 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.
|
||||
|
||||
## :heart: 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**<br>
|
||||
[](https://opencollective.com/lvgl)
|
||||
|
||||
**Pessoas que apoiam o projeto LVGL**<br>
|
||||
[](https://opencollective.com/lvgl)
|
||||
|
||||
## :package: 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
|
||||
|
||||
## :man_technologist: 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).
|
||||
|
||||

|
||||
|
||||
### Botão com evento de clique
|
||||
|
||||

|
||||
|
||||
<details>
|
||||
<summary>Código C</summary>
|
||||
|
||||
```c
|
||||
lv_obj_t * btn = lv_btn_create(lv_scr_act()); /* 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");
|
||||
}
|
||||
```
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary>Código MicroPython | <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">Simulador online</a></summary>
|
||||
|
||||
```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()
|
||||
```
|
||||
</details>
|
||||
<br>
|
||||
|
||||
### Caixas de seleção (chackboxes) com layout
|
||||

|
||||
|
||||
<details>
|
||||
<summary>Código em C</summary>
|
||||
|
||||
```c
|
||||
|
||||
lv_obj_set_flex_flow(lv_scr_act(), LV_FLEX_FLOW_COLUMN);
|
||||
lv_obj_set_flex_align(lv_scr_act(), LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_START, LV_FLEX_ALIGN_CENTER);
|
||||
|
||||
lv_obj_t * cb;
|
||||
cb = lv_checkbox_create(lv_scr_act());
|
||||
lv_checkbox_set_text(cb, "Maça");
|
||||
lv_obj_add_event(cb, event_handler, LV_EVENT_ALL, NULL);
|
||||
|
||||
cb = lv_checkbox_create(lv_scr_act());
|
||||
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_scr_act());
|
||||
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_scr_act());
|
||||
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);
|
||||
```
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary>Código MicroPython | <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">Online Simulator</a></summary>
|
||||
|
||||
```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)
|
||||
```
|
||||
|
||||
</details>
|
||||
<br>
|
||||
|
||||
### Estilizando um controle deslizante (slider)
|
||||

|
||||
|
||||
|
||||
<details>
|
||||
<summary>Código C</summary>
|
||||
|
||||
```c
|
||||
lv_obj_t * slider = lv_slider_create(lv_scr_act());
|
||||
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);
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary>Código MicroPython |
|
||||
<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">Simulador online</a>
|
||||
</summary>
|
||||
|
||||
|
||||
```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)
|
||||
```
|
||||
|
||||
</details>
|
||||
<br>
|
||||
|
||||
### Textos em inglês, hebraico (LRT-RTL misto) e chinês
|
||||
|
||||

|
||||
|
||||
<details>
|
||||
<summary>Código C</summary>
|
||||
|
||||
```c
|
||||
lv_obj_t * ltr_label = lv_label_create(lv_scr_act());
|
||||
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_scr_act());
|
||||
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_scr_act());
|
||||
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);
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary>Código MicroPython | <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">Simulador online</a></summary>
|
||||
|
||||
```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)
|
||||
|
||||
```
|
||||
</details>
|
||||
|
||||
## :arrow_forward: 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).
|
||||
|
||||
## :handshake: 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.
|
||||
|
||||
## :star2: 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:
|
||||
|
||||
<a href="https://github.com/lvgl/lvgl/graphs/contributors">
|
||||
<img src="https://contrib.rocks/image?repo=lvgl/lvgl&max=48" />
|
||||
</a>
|
||||
|
||||
... e muitos outros.
|
||||
708
docs/README_pt_BR.rst.back
Normal file
708
docs/README_pt_BR.rst.back
Normal file
@@ -0,0 +1,708 @@
|
||||
:note: **NOTA IMPORTANTE** A próxima versão principal (v9.0.0) está sendo
|
||||
desenvolvida na branch master. A última versão estável está disponível
|
||||
na branch `release/v8.3 <https://github.com/lvgl/lvgl/tree/release/v8.3>`__.
|
||||
|
||||
--------------
|
||||
|
||||
.. raw:: html
|
||||
|
||||
<p align="right">
|
||||
|
||||
English \| 中文 \| Português do Brasil \| 日本語
|
||||
|
||||
.. 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_btn_create(lv_scr_act()); /* 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_scr_act(), LV_FLEX_FLOW_COLUMN);
|
||||
lv_obj_set_flex_align(lv_scr_act(), LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_START, LV_FLEX_ALIGN_CENTER);
|
||||
|
||||
lv_obj_t * cb;
|
||||
cb = lv_checkbox_create(lv_scr_act());
|
||||
lv_checkbox_set_text(cb, "Maça");
|
||||
lv_obj_add_event(cb, event_handler, LV_EVENT_ALL, NULL);
|
||||
|
||||
cb = lv_checkbox_create(lv_scr_act());
|
||||
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_scr_act());
|
||||
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_scr_act());
|
||||
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_scr_act());
|
||||
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_scr_act());
|
||||
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_scr_act());
|
||||
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_scr_act());
|
||||
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
|
||||
@@ -1,204 +0,0 @@
|
||||
<a href="https://opencollective.com/lvgl" target="_blank"><img align="left" src="https://lvgl.io/assets/images/sponsor.png" height="32px"></a>
|
||||
|
||||
<p align="right">
|
||||
<a href="../README.md">English</a> | <b>中文</b> | <a href="./README_pt_BR.md">Português do Brasil</a> | <a href="./README_jp.md">日本語</a>
|
||||
</p>
|
||||
|
||||
<br>
|
||||
|
||||
<p align="center">
|
||||
<img src="https://lvgl.io/assets/images/logo_lvgl.png">
|
||||
</p>
|
||||
|
||||
<h1 align="center">Light and Versatile Graphics Library</h1>
|
||||
<h1 align="center">轻量级通用型图形库</h1>
|
||||
<br>
|
||||
<div align="center">
|
||||
<img src="https://github.com/kisvegabor/test/raw/master/smartwatch_demo.gif">
|
||||
|
||||
<img border="1px" src="https://lvgl.io/assets/images/lvgl_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> |
|
||||
<a href="https://squareline.io/" title="UI Editor for LVGL">SquareLine Studio</a>
|
||||
</p>
|
||||
<br>
|
||||
|
||||
[中文宣传单](./flyers/LVGL-Chinese-Flyer.pdf)
|
||||
|
||||
#### 目录
|
||||
- [概况与总览](#概况与总览)
|
||||
- [特性](#特性)
|
||||
- [硬件要求](#硬件要求)
|
||||
- [已经支持的平台](#已经支持的平台)
|
||||
- [如何入门](#如何入门)
|
||||
- [例程](#例程)
|
||||
- [C](#c)
|
||||
- [Micropython](#micropython)
|
||||
- [服务](#服务)
|
||||
- [如何向社区贡献](#如何向社区贡献)
|
||||
|
||||
## 概况与总览
|
||||
### 特性
|
||||
* 丰富且强大的模块化[图形组件](https://docs.lvgl.io/master/widgets/index.html):按钮 (buttons)、图表 (charts)、列表 (lists)、滑动条 (sliders)、图片 (images) 等
|
||||
* 高级的图形引擎:动画、抗锯齿、透明度、平滑滚动、图层混合等效果
|
||||
* 支持多种[输入设备](https://docs.lvgl.io/master/overview/indev.html):触摸屏、 键盘、编码器、按键等
|
||||
* 支持[多显示设备](https://docs.lvgl.io/master/overview/display.html)
|
||||
* 不依赖特定的硬件平台,可以在任何显示屏上运行
|
||||
* 配置可裁剪(最低资源占用:64 kB Flash,16 kB RAM)
|
||||
* 基于UTF-8的多语种支持,例如中文、日文、韩文、阿拉伯文等
|
||||
* 可以通过[类CSS](https://docs.lvgl.io/master/overview/style.html)的方式来设计、布局图形界面(例如:[Flexbox](https://docs.lvgl.io/master/layouts/flex.html)、[Grid](https://docs.lvgl.io/master/layouts/grid.html))
|
||||
* 支持操作系统、外置内存、以及硬件加速(LVGL已内建支持STM32 DMA2D、SWM341 DMA2D、NXP PXP和VGLite)
|
||||
* 即便仅有[单缓冲区(frame buffer)](https://docs.lvgl.io/master/porting/display.html)的情况下,也可保证渲染如丝般顺滑
|
||||
* 全部由C编写完成,并支持C++调用
|
||||
* 支持Micropython编程,参见:[LVGL API in Micropython](https://blog.lvgl.io/2019-02-20/micropython-bindings)
|
||||
* 支持[模拟器](https://docs.lvgl.io/master/get-started/platforms/pc-simulator.html)仿真,可以无硬件依托进行开发
|
||||
* 丰富详实的[例程](https://github.com/lvgl/lvgl/tree/master/examples)
|
||||
* 详尽的[文档](http://docs.lvgl.io/)以及API参考手册,可线上查阅或可下载为PDF格式
|
||||
|
||||
### 硬件要求
|
||||
|
||||
<table>
|
||||
<tr>
|
||||
<td> <strong>要求</strong> </td>
|
||||
<td><strong>最低要求</strong></td>
|
||||
<td><strong>建议要求</strong></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><strong>架构</strong></td>
|
||||
<td colspan="2">16、32、64位微控制器或微处理器</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td> <strong>时钟</strong></td>
|
||||
<td> > 16 MHz</td>
|
||||
<td> > 48 MHz</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td> <strong>Flash/ROM</strong></td>
|
||||
<td> > 64 kB </td>
|
||||
<td> > 180 kB</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td> <strong>Static RAM</strong></td>
|
||||
<td> > 16 kB </td>
|
||||
<td> > 48 kB</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td> <strong>Draw buffer</strong></td>
|
||||
<td> > 1 × <em>hor. res.</em> pixels </td>
|
||||
<td> > 1/10屏幕大小 </td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td> <strong>编译器</strong></td>
|
||||
<td colspan="2"> C99或更新 </td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
*注意:资源占用情况与具体硬件平台、编译器等因素有关,上表中仅给出参考值*
|
||||
|
||||
### 已经支持的平台
|
||||
LVGL本身并不依赖特定的硬件平台,任何满足LVGL硬件配置要求的微控制器均可运行LVGL。
|
||||
如下仅列举其中一部分:
|
||||
|
||||
- NXP: Kinetis, LPC, iMX, iMX RT
|
||||
- STM32F1, STM32F3, STM32F4, STM32F7, STM32L4, STM32L5, STM32H7
|
||||
- Microchip dsPIC33, PIC24, PIC32MX, PIC32MZ
|
||||
- [Linux frame buffer](https://blog.lvgl.io/2018-01-03/linux_fb) (/dev/fb)
|
||||
- [Raspberry Pi](http://www.vk3erw.com/index.php/16-software/63-raspberry-pi-official-7-touchscreen-and-littlevgl)
|
||||
- [Espressif ESP32](https://github.com/lvgl/lv_port_esp32)
|
||||
- [Infineon Aurix](https://github.com/lvgl/lv_port_aurix)
|
||||
- Nordic NRF52 Bluetooth modules
|
||||
- Quectel modems
|
||||
- [SYNWIT SWM341](https://www.synwit.cn/)
|
||||
|
||||
LVGL也支持:
|
||||
- [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://www.rt-thread.org/document/site/#/rt-thread-version/rt-thread-standard/packages-manual/lvgl-docs/introduction)
|
||||
|
||||
|
||||
## 如何入门
|
||||
请按照如下顺序来学习LVGL:
|
||||
1. 使用[网页在线例程](https://lvgl.io/demos)来体验LVGL(3分钟)
|
||||
2. 阅读文档[简介](https://docs.lvgl.io/master/intro/index.html)章节来初步了解LVGL(5分钟)
|
||||
3. 再来阅读一下文档快速[快速概览](https://docs.lvgl.io/master/get-started/quick-overview.html)章节来了解LVGL的基本知识(15分钟)
|
||||
4. 学习如何使用[模拟器](https://docs.lvgl.io/master/get-started/platforms/pc-simulator.html)来在电脑上仿真LVGL(10分钟)
|
||||
5. 试着动手实践一些[例程](https://github.com/lvgl/lvgl/tree/master/examples)
|
||||
6. 参考[移植指南](https://docs.lvgl.io/master/porting/index.html)尝试将LVGL移植到一块开发板上,LVGL也已经提供了一些移植好的[工程](https://github.com/lvgl?q=lv_port_)
|
||||
7. 仔细阅读文档[总览](https://docs.lvgl.io/master/overview/index.html)章节来更加深入的了解和熟悉LVGL(2-3小时)
|
||||
8. 浏览文档[组件(Widgets)](https://docs.lvgl.io/master/widgets/index.html)章节来了解如何使用它们
|
||||
9. 如果你有问题可以到LVGL[论坛](http://forum.lvgl.io/)提问
|
||||
10. 阅读文档[如何向社区贡献](https://docs.lvgl.io/master/CONTRIBUTING.html)章节来看看你能帮LVGL社区做些什么,以促进LVGL软件质量的不断提高(15分钟)
|
||||
|
||||
## 例程
|
||||
|
||||
更多例程请参见 [examples](https://github.com/lvgl/lvgl/tree/master/examples) 文件夹。
|
||||
|
||||

|
||||
|
||||
### C
|
||||
```c
|
||||
lv_obj_t * btn = lv_btn_create(lv_scr_act()); /*Add a button to the current screen*/
|
||||
lv_obj_set_pos(btn, 10, 10); /*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");
|
||||
}
|
||||
```
|
||||
### Micropython
|
||||
更多信息请到 [Micropython官网](https://docs.lvgl.io/master/get-started/bindings/micropython.html) 查询.
|
||||
```python
|
||||
def btn_event_cb(e):
|
||||
print("Clicked")
|
||||
|
||||
# Create a Button and a Label
|
||||
btn = lv.btn(lv.scr_act())
|
||||
btn.set_pos(10, 10)
|
||||
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()
|
||||
```
|
||||
|
||||
## 服务
|
||||
LVGL 责任有限公司成立的目的是为了给用户使用LVGL图形库提供额外的技术支持,我们致力于提供以下服务:
|
||||
|
||||
- 图形设计
|
||||
- UI设计
|
||||
- 技术咨询以及技术支持
|
||||
|
||||
更多信息请参见 https://lvgl.io/services ,如果有任何问题请随时联系我们。
|
||||
|
||||
|
||||
## 如何向社区贡献
|
||||
LVGL是一个开源项目,非常欢迎您参与到社区贡献当中。您有很多种方式来为提高LVGL贡献您的一份力量,包括但不限于:
|
||||
|
||||
- 介绍你基于LVGL设计的作品或项目
|
||||
- 写一些例程
|
||||
- 修改以及完善文档
|
||||
- 修复bug
|
||||
|
||||
请参见文档[如何向社区贡献](https://docs.lvgl.io/master/CONTRIBUTING.html)章节来获取更多信息。
|
||||
493
docs/README_zh.rst.back
Normal file
493
docs/README_zh.rst.back
Normal file
@@ -0,0 +1,493 @@
|
||||
.. raw:: html
|
||||
|
||||
<p align="right">
|
||||
|
||||
English \| 中文 \| Português do Brasil \| 日本語
|
||||
|
||||
.. 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
|
||||
|
||||
<h1 align="center">
|
||||
|
||||
轻量级通用型图形库
|
||||
|
||||
.. raw:: html
|
||||
|
||||
</h1>
|
||||
|
||||
|
||||
|
||||
.. raw:: html
|
||||
|
||||
<p align="center">
|
||||
|
||||
官网 \| 文档 \| 论坛 \| 示例 \| 服务 \| SquareLine Studio
|
||||
|
||||
.. raw:: html
|
||||
|
||||
</p>
|
||||
|
||||
`中文宣传单 <./flyers/LVGL-Chinese-Flyer.pdf>`__
|
||||
|
||||
目录
|
||||
^^^^
|
||||
|
||||
- `概况与总览 <#概况与总览>`__
|
||||
|
||||
- `特性 <#特性>`__
|
||||
- `硬件要求 <#硬件要求>`__
|
||||
- `已经支持的平台 <#已经支持的平台>`__
|
||||
|
||||
- `如何入门 <#如何入门>`__
|
||||
- `例程 <#例程>`__
|
||||
|
||||
- `C <#c>`__
|
||||
- `Micropython <#micropython>`__
|
||||
|
||||
- `服务 <#服务>`__
|
||||
- `如何向社区贡献 <#如何向社区贡献>`__
|
||||
|
||||
概况与总览
|
||||
----------
|
||||
|
||||
特性
|
||||
~~~~
|
||||
|
||||
- 丰富且强大的模块化\ `图形组件 <https://docs.lvgl.io/master/widgets/index.html>`__\ :按钮
|
||||
(buttons)、图表 (charts)、列表 (lists)、滑动条 (sliders)、图片
|
||||
(images) 等
|
||||
- 高级的图形引擎:动画、抗锯齿、透明度、平滑滚动、图层混合等效果
|
||||
- 支持多种\ `输入设备 <https://docs.lvgl.io/master/overview/indev.html>`__\ :触摸屏、
|
||||
键盘、编码器、按键等
|
||||
- 支持\ `多显示设备 <https://docs.lvgl.io/master/overview/display.html>`__
|
||||
- 不依赖特定的硬件平台,可以在任何显示屏上运行
|
||||
- 配置可裁剪(最低资源占用:64 kB Flash,16 kB RAM)
|
||||
- 基于UTF-8的多语种支持,例如中文、日文、韩文、阿拉伯文等
|
||||
- 可以通过\ `类CSS <https://docs.lvgl.io/master/overview/style.html>`__\ 的方式来设计、布局图形界面(例如:\ `Flexbox <https://docs.lvgl.io/master/layouts/flex.html>`__\ 、\ `Grid <https://docs.lvgl.io/master/layouts/grid.html>`__\ )
|
||||
- 支持操作系统、外置内存、以及硬件加速(LVGL已内建支持STM32
|
||||
DMA2D、SWM341 DMA2D、NXP PXP和VGLite)
|
||||
- 即便仅有\ `单缓冲区(frame
|
||||
buffer) <https://docs.lvgl.io/master/porting/display.html>`__\ 的情况下,也可保证渲染如丝般顺滑
|
||||
- 全部由C编写完成,并支持C++调用
|
||||
- 支持Micropython编程,参见:\ `LVGL API in
|
||||
Micropython <https://blog.lvgl.io/2019-02-20/micropython-bindings>`__
|
||||
- 支持\ `模拟器 <https://docs.lvgl.io/master/get-started/platforms/pc-simulator.html>`__\ 仿真,可以无硬件依托进行开发
|
||||
- 丰富详实的\ `例程 <https://github.com/lvgl/lvgl/tree/master/examples>`__
|
||||
- 详尽的\ `文档 <http://docs.lvgl.io/>`__\ 以及API参考手册,可线上查阅或可下载为PDF格式
|
||||
|
||||
硬件要求
|
||||
~~~~~~~~
|
||||
|
||||
.. raw:: html
|
||||
|
||||
<table>
|
||||
|
||||
.. raw:: html
|
||||
|
||||
<tr>
|
||||
|
||||
.. raw:: html
|
||||
|
||||
<td>
|
||||
|
||||
要求
|
||||
|
||||
.. raw:: html
|
||||
|
||||
</td>
|
||||
|
||||
.. raw:: html
|
||||
|
||||
<td>
|
||||
|
||||
最低要求
|
||||
|
||||
.. raw:: html
|
||||
|
||||
</td>
|
||||
|
||||
.. raw:: html
|
||||
|
||||
<td>
|
||||
|
||||
建议要求
|
||||
|
||||
.. raw:: html
|
||||
|
||||
</td>
|
||||
|
||||
.. raw:: html
|
||||
|
||||
</tr>
|
||||
|
||||
.. raw:: html
|
||||
|
||||
<tr>
|
||||
|
||||
.. raw:: html
|
||||
|
||||
<td>
|
||||
|
||||
架构
|
||||
|
||||
.. raw:: html
|
||||
|
||||
</td>
|
||||
|
||||
.. raw:: html
|
||||
|
||||
<td colspan="2">
|
||||
|
||||
16、32、64位微控制器或微处理器
|
||||
|
||||
.. raw:: html
|
||||
|
||||
</td>
|
||||
|
||||
.. raw:: html
|
||||
|
||||
</tr>
|
||||
|
||||
.. raw:: html
|
||||
|
||||
<tr>
|
||||
|
||||
.. raw:: html
|
||||
|
||||
<td>
|
||||
|
||||
时钟
|
||||
|
||||
.. raw:: html
|
||||
|
||||
</td>
|
||||
|
||||
.. raw:: html
|
||||
|
||||
<td>
|
||||
|
||||
> 16 MHz
|
||||
|
||||
.. raw:: html
|
||||
|
||||
</td>
|
||||
|
||||
.. raw:: html
|
||||
|
||||
<td>
|
||||
|
||||
> 48 MHz
|
||||
|
||||
.. raw:: html
|
||||
|
||||
</td>
|
||||
|
||||
.. raw:: html
|
||||
|
||||
</tr>
|
||||
|
||||
.. raw:: html
|
||||
|
||||
<tr>
|
||||
|
||||
.. raw:: html
|
||||
|
||||
<td>
|
||||
|
||||
Flash/ROM
|
||||
|
||||
.. raw:: html
|
||||
|
||||
</td>
|
||||
|
||||
.. raw:: html
|
||||
|
||||
<td>
|
||||
|
||||
> 64 kB
|
||||
|
||||
.. raw:: html
|
||||
|
||||
</td>
|
||||
|
||||
.. raw:: html
|
||||
|
||||
<td>
|
||||
|
||||
> 180 kB
|
||||
|
||||
.. raw:: html
|
||||
|
||||
</td>
|
||||
|
||||
.. raw:: html
|
||||
|
||||
</tr>
|
||||
|
||||
.. raw:: html
|
||||
|
||||
<tr>
|
||||
|
||||
.. raw:: html
|
||||
|
||||
<td>
|
||||
|
||||
Static RAM
|
||||
|
||||
.. raw:: html
|
||||
|
||||
</td>
|
||||
|
||||
.. raw:: html
|
||||
|
||||
<td>
|
||||
|
||||
> 16 kB
|
||||
|
||||
.. raw:: html
|
||||
|
||||
</td>
|
||||
|
||||
.. raw:: html
|
||||
|
||||
<td>
|
||||
|
||||
> 48 kB
|
||||
|
||||
.. raw:: html
|
||||
|
||||
</td>
|
||||
|
||||
.. raw:: html
|
||||
|
||||
</tr>
|
||||
|
||||
.. raw:: html
|
||||
|
||||
<tr>
|
||||
|
||||
.. raw:: html
|
||||
|
||||
<td>
|
||||
|
||||
Draw buffer
|
||||
|
||||
.. raw:: html
|
||||
|
||||
</td>
|
||||
|
||||
.. raw:: html
|
||||
|
||||
<td>
|
||||
|
||||
> 1 × hor. res. pixels
|
||||
|
||||
.. raw:: html
|
||||
|
||||
</td>
|
||||
|
||||
.. raw:: html
|
||||
|
||||
<td>
|
||||
|
||||
> 1/10屏幕大小
|
||||
|
||||
.. raw:: html
|
||||
|
||||
</td>
|
||||
|
||||
.. raw:: html
|
||||
|
||||
</tr>
|
||||
|
||||
.. raw:: html
|
||||
|
||||
<tr>
|
||||
|
||||
.. raw:: html
|
||||
|
||||
<td>
|
||||
|
||||
编译器
|
||||
|
||||
.. raw:: html
|
||||
|
||||
</td>
|
||||
|
||||
.. raw:: html
|
||||
|
||||
<td colspan="2">
|
||||
|
||||
C99或更新
|
||||
|
||||
.. raw:: html
|
||||
|
||||
</td>
|
||||
|
||||
.. raw:: html
|
||||
|
||||
</tr>
|
||||
|
||||
.. raw:: html
|
||||
|
||||
</table>
|
||||
|
||||
*注意:资源占用情况与具体硬件平台、编译器等因素有关,上表中仅给出参考值*
|
||||
|
||||
已经支持的平台
|
||||
~~~~~~~~~~~~~~
|
||||
|
||||
LVGL本身并不依赖特定的硬件平台,任何满足LVGL硬件配置要求的微控制器均可运行LVGL。
|
||||
如下仅列举其中一部分:
|
||||
|
||||
- NXP: Kinetis, LPC, iMX, iMX RT
|
||||
- STM32F1, STM32F3, STM32F4, STM32F7, STM32L4, STM32L5, STM32H7
|
||||
- Microchip dsPIC33, PIC24, PIC32MX, PIC32MZ
|
||||
- `Linux frame buffer <https://blog.lvgl.io/2018-01-03/linux_fb>`__
|
||||
(/dev/fb)
|
||||
- `Raspberry
|
||||
Pi <http://www.vk3erw.com/index.php/16-software/63-raspberry-pi-official-7-touchscreen-and-littlevgl>`__
|
||||
- `Espressif ESP32 <https://github.com/lvgl/lv_port_esp32>`__
|
||||
- `Infineon Aurix <https://github.com/lvgl/lv_port_aurix>`__
|
||||
- Nordic NRF52 Bluetooth modules
|
||||
- Quectel modems
|
||||
- `SYNWIT SWM341 <https://www.synwit.cn/>`__
|
||||
|
||||
LVGL也支持: - `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://www.rt-thread.org/document/site/#/rt-thread-version/rt-thread-standard/packages-manual/lvgl-docs/introduction>`__
|
||||
|
||||
如何入门
|
||||
--------
|
||||
|
||||
请按照如下顺序来学习LVGL: 1.
|
||||
使用\ `网页在线例程 <https://lvgl.io/demos>`__\ 来体验LVGL(3分钟) 2.
|
||||
阅读文档\ `简介 <https://docs.lvgl.io/master/intro/index.html>`__\ 章节来初步了解LVGL(5分钟)
|
||||
3.
|
||||
再来阅读一下文档快速\ `快速概览 <https://docs.lvgl.io/master/get-started/quick-overview.html>`__\ 章节来了解LVGL的基本知识(15分钟)
|
||||
4.
|
||||
学习如何使用\ `模拟器 <https://docs.lvgl.io/master/get-started/platforms/pc-simulator.html>`__\ 来在电脑上仿真LVGL(10分钟)
|
||||
5.
|
||||
试着动手实践一些\ `例程 <https://github.com/lvgl/lvgl/tree/master/examples>`__
|
||||
6.
|
||||
参考\ `移植指南 <https://docs.lvgl.io/master/porting/index.html>`__\ 尝试将LVGL移植到一块开发板上,LVGL也已经提供了一些移植好的\ `工程 <https://github.com/lvgl?q=lv_port_>`__
|
||||
7.
|
||||
仔细阅读文档\ `总览 <https://docs.lvgl.io/master/overview/index.html>`__\ 章节来更加深入的了解和熟悉LVGL(2-3小时)
|
||||
8.
|
||||
浏览文档\ `组件(Widgets) <https://docs.lvgl.io/master/widgets/index.html>`__\ 章节来了解如何使用它们
|
||||
9. 如果你有问题可以到LVGL\ `论坛 <http://forum.lvgl.io/>`__\ 提问 10.
|
||||
阅读文档\ `如何向社区贡献 <https://docs.lvgl.io/master/CONTRIBUTING.html>`__\ 章节来看看你能帮LVGL社区做些什么,以促进LVGL软件质量的不断提高(15分钟)
|
||||
|
||||
例程
|
||||
----
|
||||
|
||||
更多例程请参见
|
||||
`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
|
||||
|
||||
C
|
||||
~
|
||||
|
||||
.. code:: c
|
||||
|
||||
lv_obj_t * btn = lv_btn_create(lv_scr_act()); /*Add a button to the current screen*/
|
||||
lv_obj_set_pos(btn, 10, 10); /*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");
|
||||
}
|
||||
|
||||
Micropython
|
||||
~~~~~~~~~~~
|
||||
|
||||
更多信息请到
|
||||
`Micropython官网 <https://docs.lvgl.io/master/get-started/bindings/micropython.html>`__
|
||||
查询.
|
||||
|
||||
.. code:: python
|
||||
|
||||
def btn_event_cb(e):
|
||||
print("Clicked")
|
||||
|
||||
# Create a Button and a Label
|
||||
btn = lv.btn(lv.scr_act())
|
||||
btn.set_pos(10, 10)
|
||||
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()
|
||||
|
||||
服务
|
||||
----
|
||||
|
||||
LVGL
|
||||
责任有限公司成立的目的是为了给用户使用LVGL图形库提供额外的技术支持,我们致力于提供以下服务:
|
||||
|
||||
- 图形设计
|
||||
- UI设计
|
||||
- 技术咨询以及技术支持
|
||||
|
||||
更多信息请参见 https://lvgl.io/services ,如果有任何问题请随时联系我们。
|
||||
|
||||
如何向社区贡献
|
||||
--------------
|
||||
|
||||
LVGL是一个开源项目,非常欢迎您参与到社区贡献当中。您有很多种方式来为提高LVGL贡献您的一份力量,包括但不限于:
|
||||
|
||||
- 介绍你基于LVGL设计的作品或项目
|
||||
- 写一些例程
|
||||
- 修改以及完善文档
|
||||
- 修复bug
|
||||
|
||||
请参见文档\ `如何向社区贡献 <https://docs.lvgl.io/master/CONTRIBUTING.html>`__\ 章节来获取更多信息。
|
||||
@@ -2,16 +2,14 @@ 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
|
||||
# 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 = {
|
||||
@@ -19,8 +17,13 @@ class LvExample(Directive):
|
||||
'language': directives.unchanged,
|
||||
'description': directives.unchanged
|
||||
}
|
||||
|
||||
def get_example_code_path(self, example_path, language):
|
||||
return os.path.abspath("../examples/" + 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'
|
||||
@@ -28,18 +31,23 @@ class LvExample(Directive):
|
||||
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) as f:
|
||||
contents = f.read()
|
||||
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)
|
||||
@@ -48,6 +56,7 @@ class LvExample(Directive):
|
||||
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]
|
||||
@@ -61,15 +70,22 @@ class LvExample(Directive):
|
||||
c_path = self.get_example_code_path(example_path, 'c')
|
||||
py_path = self.get_example_code_path(example_path, 'py')
|
||||
|
||||
c_code = self.embed_code(c_path, example_path, 'c', buttons={
|
||||
'<i class="fa fa-github"></i> GitHub': self.github_path(example_path, 'c')
|
||||
})
|
||||
py_code = self.embed_code(py_path, example_path, 'py', buttons={
|
||||
'<i class="fa fa-github"></i> GitHub': self.github_path(example_path, 'py'),
|
||||
'<i class="fa fa-play"></i> 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"
|
||||
})
|
||||
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 not 'c' in excluded_languages:
|
||||
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>"
|
||||
|
||||
@@ -77,9 +93,9 @@ class LvExample(Directive):
|
||||
layout_node = nodes.raw(text=f"<div class='lv-example-container'>{iframe_html}{description_html}</div>", format='html')
|
||||
|
||||
node_list.append(layout_node)
|
||||
if not 'c' in excluded_languages:
|
||||
if 'c' not in excluded_languages and c_code is not None:
|
||||
node_list.append(c_code)
|
||||
if not 'py' in excluded_languages:
|
||||
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')
|
||||
@@ -87,6 +103,7 @@ class LvExample(Directive):
|
||||
|
||||
return node_list
|
||||
|
||||
|
||||
def setup(app):
|
||||
app.add_directive("lv_example", LvExample)
|
||||
app.add_config_value("repo_commit_hash", "", "env")
|
||||
|
||||
12
docs/_static/css/custom.css
vendored
12
docs/_static/css/custom.css
vendored
@@ -130,4 +130,16 @@ dl.cpp.unexpanded dd {
|
||||
}
|
||||
.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;
|
||||
}
|
||||
2
docs/_static/js/custom.js
vendored
2
docs/_static/js/custom.js
vendored
@@ -15,4 +15,4 @@ document.addEventListener('DOMContentLoaded', (event) => {
|
||||
|
||||
dt.insertBefore(button, dt.firstChild);
|
||||
});
|
||||
})
|
||||
})
|
||||
|
||||
29
docs/_static/js/include_html.js
vendored
Normal file
29
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;
|
||||
}
|
||||
}
|
||||
};
|
||||
259
docs/build.py
259
docs/build.py
@@ -1,74 +1,261 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
# ****************************************************************************
|
||||
# IMPOTRANT: If you are getting a lexer error for an example you need to check
|
||||
# for extra lines at the edn 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
|
||||
|
||||
# due to the modifications that take place to the documentation files
|
||||
# when the documentaation 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 comitted 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
|
||||
abspath = os.path.abspath(__file__)
|
||||
dname = os.path.dirname(abspath)
|
||||
os.chdir(dname)
|
||||
|
||||
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("-------------------------------------")
|
||||
r = os.system(s)
|
||||
if r != 0:
|
||||
print("Exit build due to previous error")
|
||||
exit(-1)
|
||||
print("")
|
||||
print(s)
|
||||
print("-------------------------------------")
|
||||
r = os.system(s)
|
||||
if r != 0:
|
||||
print("Exit build due to previous error")
|
||||
exit(-1)
|
||||
|
||||
|
||||
# Get the current branch name
|
||||
status, br = subprocess.getstatusoutput("git branch | grep '*'")
|
||||
status, br = subprocess.getstatusoutput("git branch")
|
||||
_, gitcommit = subprocess.getstatusoutput("git rev-parse HEAD")
|
||||
br = re.sub('\* ', '', br)
|
||||
|
||||
# Generate the list of examples
|
||||
ex.exec()
|
||||
|
||||
urlpath = re.sub('release/', '', br)
|
||||
|
||||
os.environ['LVGL_URLPATH'] = urlpath
|
||||
os.environ['LVGL_GITCOMMIT'] = gitcommit
|
||||
|
||||
clean = 0
|
||||
trans = 0
|
||||
skip_latex = False
|
||||
args = sys.argv[1:]
|
||||
if len(args) >= 1:
|
||||
if "clean" in args: clean = 1
|
||||
if "skip_latex" in args: skip_latex = True
|
||||
|
||||
lang = "en"
|
||||
print("")
|
||||
print("****************")
|
||||
print("Building")
|
||||
print("****************")
|
||||
if clean:
|
||||
cmd("rm -rf " + lang)
|
||||
cmd("mkdir " + lang)
|
||||
|
||||
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)
|
||||
|
||||
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('*#*#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("Running doxygen")
|
||||
cmd("cd ../scripts && doxygen Doxyfile")
|
||||
cmd('cd "{0}" && doxygen Doxyfile'.format(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 not skip_latex:
|
||||
# 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 . out_latex")
|
||||
|
||||
# Generate PDF
|
||||
cmd("cd out_latex && latexmk -pdf 'LVGL.tex'")
|
||||
# Copy the result PDF to the main directory to make it available for the HTML build
|
||||
cmd("cd out_latex && cp -f LVGL.pdf ../LVGL.pdf")
|
||||
if skip_latex:
|
||||
print("skipping latex build as requested")
|
||||
else:
|
||||
print("skipping latex build as requested")
|
||||
|
||||
# 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
|
||||
cmd("sphinx-build -b html . ../out_html")
|
||||
|
||||
|
||||
def get_version():
|
||||
path = os.path.join(project_path, 'lvgl.h')
|
||||
with open(path, 'rb') as f:
|
||||
d = f.read().decode('utf-8')
|
||||
|
||||
d = d.split('#define LVGL_VERSION_MAJOR', 1)[-1]
|
||||
major, d = d.split('\n', 1)
|
||||
d = d.split('#define LVGL_VERSION_MINOR', 1)[-1]
|
||||
minor, d = d.split('\n', 1)
|
||||
d = d.split('#define LVGL_VERSION_PATCH', 1)[-1]
|
||||
patch, d = d.split('\n', 1)
|
||||
|
||||
ver = '{0}.{1}.{2}'.format(major.strip(), minor.strip(), patch.strip())
|
||||
|
||||
if '#define LVGL_VERSION_INFO' in d:
|
||||
d = d.split('#define LVGL_VERSION_INFO', 1)[-1]
|
||||
info, d = d.split('\n', 1)
|
||||
info = info.strip().replace('"', '')
|
||||
ver += '-' + info
|
||||
|
||||
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)
|
||||
|
||||
print('output path:', html_dst_path)
|
||||
print('\nFINISHED!!')
|
||||
|
||||
50
docs/conf.py
50
docs/conf.py
@@ -23,9 +23,9 @@ import sys
|
||||
|
||||
sys.path.insert(0, os.path.abspath('./_ext'))
|
||||
|
||||
from subprocess import PIPE, Popen
|
||||
# from subprocess import PIPE, Popen
|
||||
|
||||
import recommonmark
|
||||
# import recommonmark
|
||||
from recommonmark.transform import AutoStructify
|
||||
from sphinx.builders.html import StandaloneHTMLBuilder
|
||||
|
||||
@@ -38,15 +38,20 @@ from sphinx.builders.html import StandaloneHTMLBuilder
|
||||
# Add any Sphinx extension module names here, as strings. They can be
|
||||
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
|
||||
# ones.
|
||||
extensions = ['sphinx.ext.autodoc',
|
||||
extensions = [
|
||||
'sphinx_rtd_theme',
|
||||
'sphinx.ext.autodoc',
|
||||
'sphinx.ext.intersphinx',
|
||||
'sphinx.ext.todo',
|
||||
'recommonmark',
|
||||
'sphinx_markdown_tables',
|
||||
# 'recommonmark',
|
||||
# 'sphinx_markdown_tables',
|
||||
'breathe',
|
||||
'sphinx_sitemap',
|
||||
'lv_example'
|
||||
]
|
||||
'lv_example',
|
||||
'sphinx_rtd_dark_mode'
|
||||
]
|
||||
|
||||
default_dark_mode = False
|
||||
|
||||
# Add any paths that contain templates here, relative to this directory.
|
||||
templates_path = ['_templates']
|
||||
@@ -60,7 +65,7 @@ highlight_language = 'c'
|
||||
# The suffix(es) of source filenames.
|
||||
# You can specify multiple suffix as a list of string:
|
||||
#
|
||||
source_suffix = ['.rst', '.md']
|
||||
source_suffix = ['.rst']# , '.md']
|
||||
|
||||
|
||||
# The master toctree document.
|
||||
@@ -68,9 +73,10 @@ master_doc = 'index'
|
||||
|
||||
# General information about the project.
|
||||
project = 'LVGL'
|
||||
copyright = '2021, LVGL Kft'
|
||||
copyright = '2023, 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.
|
||||
@@ -78,20 +84,20 @@ author = 'LVGL community'
|
||||
# The short X.Y version.
|
||||
# embeddedt: extract using scripts/find_version.sh
|
||||
|
||||
version = subprocess.run(["../scripts/find_version.sh"], capture_output=True).stdout.decode("utf-8").strip()
|
||||
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 = None
|
||||
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', 'lv_examples', 'out_html', 'env' ]
|
||||
'README.md', 'lv_examples', 'out_html', 'env', '_ext', 'examples']
|
||||
|
||||
# The name of the Pygments (syntax highlighting) style to use.
|
||||
pygments_style = 'sphinx'
|
||||
@@ -111,10 +117,25 @@ html_theme = 'sphinx_rtd_theme'
|
||||
# further. For a list of options available for each theme, see the
|
||||
# documentation.
|
||||
#
|
||||
|
||||
|
||||
html_theme_options = {
|
||||
'collapse_navigation' : False,
|
||||
'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']}/en/html/"
|
||||
|
||||
@@ -151,7 +172,8 @@ html_sidebars = {
|
||||
}
|
||||
|
||||
html_js_files = [
|
||||
'js/custom.js'
|
||||
'js/custom.js',
|
||||
'js/include_html.js'
|
||||
]
|
||||
|
||||
html_favicon = 'favicon.png'
|
||||
|
||||
713
docs/doc_builder.py
Normal file
713
docs/doc_builder.py
Normal file
@@ -0,0 +1,713 @@
|
||||
import os
|
||||
from xml.etree import ElementTree as ET
|
||||
|
||||
base_path = ''
|
||||
xml_path = ''
|
||||
|
||||
|
||||
def load_xml(fle):
|
||||
fle = os.path.join(xml_path, fle + '.xml')
|
||||
|
||||
with open(fle, 'rb') as f:
|
||||
d = f.read().decode('utf-8')
|
||||
|
||||
# This code is to correct a bug in Doxygen. That bug incorrectly parses
|
||||
# a typedef and it causes an error to occur building the docs. The Error
|
||||
# doesn't stop the documentation from being generated, I just don't want
|
||||
# to see the ugly red output.
|
||||
#
|
||||
# if 'typedef void() lv_lru_free_t(void *v)' in d:
|
||||
# d = d.replace(
|
||||
# '<type>void()</type>\n '
|
||||
# '<definition>typedef void() lv_lru_free_t(void *v)</definition>',
|
||||
# '<type>void</type>\n '
|
||||
# '<definition>typedef void(lv_lru_free_t)(void *v)</definition>'
|
||||
# )
|
||||
# with open(fle, 'wb') as f:
|
||||
# f.write(d.encode('utf-8'))
|
||||
|
||||
return ET.fromstring(d)
|
||||
|
||||
|
||||
structures = {}
|
||||
functions = {}
|
||||
enums = {}
|
||||
typedefs = {}
|
||||
variables = {}
|
||||
unions = {}
|
||||
namespaces = {}
|
||||
files = {}
|
||||
|
||||
|
||||
class STRUCT(object):
|
||||
template = '''\
|
||||
.. doxygenstruct:: {name}
|
||||
:project: lvgl
|
||||
:members:
|
||||
:protected-members:
|
||||
:private-members:
|
||||
:undoc-members:
|
||||
'''
|
||||
|
||||
def __init__(self, parent, refid, name, **_):
|
||||
if name in structures:
|
||||
self.__dict__.update(structures[name].__dict__)
|
||||
return
|
||||
|
||||
structures[name] = self
|
||||
self.parent = parent
|
||||
self.refid = refid
|
||||
self.name = name
|
||||
self.types = set()
|
||||
self._deps = None
|
||||
self.header_file = ''
|
||||
|
||||
root = load_xml(refid)
|
||||
|
||||
for compounddef in root:
|
||||
if compounddef.attrib['id'] != self.refid:
|
||||
continue
|
||||
|
||||
for child in compounddef:
|
||||
if child.tag == 'includes':
|
||||
self.header_file = os.path.splitext(child.text)[0]
|
||||
|
||||
if child.tag != 'sectiondef':
|
||||
continue
|
||||
|
||||
for memberdef in child:
|
||||
t = get_type(memberdef)
|
||||
|
||||
if t is None:
|
||||
continue
|
||||
|
||||
self.types.add(t)
|
||||
|
||||
@property
|
||||
def deps(self):
|
||||
if self._deps is None:
|
||||
self._deps = dict(
|
||||
typedefs=set(),
|
||||
functions=set(),
|
||||
enums=set(),
|
||||
structures=set(),
|
||||
unions=set(),
|
||||
namespaces=set(),
|
||||
variables=set(),
|
||||
)
|
||||
for type_ in self.types:
|
||||
if type_ in typedefs:
|
||||
self._deps['typedefs'].add(typedefs[type_])
|
||||
elif type_ in structures:
|
||||
self._deps['structures'].add(structures[type_])
|
||||
elif type_ in unions:
|
||||
self._deps['unions'].add(unions[type_])
|
||||
elif type_ in enums:
|
||||
self._deps['enums'].add(enums[type_])
|
||||
elif type_ in functions:
|
||||
self._deps['functions'].add(functions[type_])
|
||||
elif type_ in variables:
|
||||
self._deps['variables'].add(variables[type_])
|
||||
elif type_ in namespaces:
|
||||
self._deps['namespaces'].add(namespaces[type_])
|
||||
return self._deps
|
||||
|
||||
def __str__(self):
|
||||
return self.template.format(name=self.name)
|
||||
|
||||
|
||||
class UNION(STRUCT):
|
||||
template = '''\
|
||||
.. doxygenunion:: {name}
|
||||
:project: lvgl
|
||||
'''
|
||||
|
||||
|
||||
def get_type(node):
|
||||
def gt(n):
|
||||
for c in n:
|
||||
if c.tag == 'ref':
|
||||
t = c.text.strip()
|
||||
break
|
||||
else:
|
||||
t = node.text.strip()
|
||||
|
||||
return t.replace('*', '').replace('(', '').replace(')', '').strip()
|
||||
|
||||
for child in node:
|
||||
if child.tag == 'type':
|
||||
return gt(child)
|
||||
|
||||
|
||||
class VARIABLE(object):
|
||||
template = '''\
|
||||
.. doxygenvariable:: {name}
|
||||
:project: lvgl
|
||||
'''
|
||||
|
||||
def __init__(self, parent, refid, name, **_):
|
||||
if name in variables:
|
||||
self.__dict__.update(variables[name].__dict__)
|
||||
return
|
||||
|
||||
variables[name] = self
|
||||
self.parent = parent
|
||||
self.refid = refid
|
||||
self.name = name
|
||||
|
||||
def __str__(self):
|
||||
return self.template.format(name=self.name)
|
||||
|
||||
|
||||
class NAMESPACE(object):
|
||||
template = '''\
|
||||
.. doxygennamespace:: {name}
|
||||
:project: lvgl
|
||||
:members:
|
||||
:protected-members:
|
||||
:private-members:
|
||||
:undoc-members:
|
||||
'''
|
||||
|
||||
def __init__(self, parent, refid, name, **_):
|
||||
if name in namespaces:
|
||||
self.__dict__.update(namespaces[name].__dict__)
|
||||
return
|
||||
|
||||
namespaces[name] = self
|
||||
self.parent = parent
|
||||
self.refid = refid
|
||||
self.name = name
|
||||
|
||||
def __str__(self):
|
||||
return self.template.format(name=self.name)
|
||||
|
||||
|
||||
class FUNCTION(object):
|
||||
template = '''\
|
||||
.. doxygenfunction:: {name}
|
||||
:project: lvgl
|
||||
'''
|
||||
|
||||
def __init__(self, parent, refid, name, **_):
|
||||
if name in functions:
|
||||
self.__dict__.update(functions[name].__dict__)
|
||||
return
|
||||
|
||||
functions[name] = self
|
||||
self.parent = parent
|
||||
self.refid = refid
|
||||
self.name = name
|
||||
self.types = set()
|
||||
self.restype = None
|
||||
self._deps = None
|
||||
|
||||
if parent is not None:
|
||||
root = load_xml(parent.refid)
|
||||
|
||||
for compounddef in root:
|
||||
if compounddef.attrib['id'] != parent.refid:
|
||||
continue
|
||||
|
||||
for child in compounddef:
|
||||
if child.tag != 'sectiondef':
|
||||
continue
|
||||
if child.attrib['kind'] != 'func':
|
||||
continue
|
||||
|
||||
for memberdef in child:
|
||||
if memberdef.attrib['id'] == refid:
|
||||
break
|
||||
else:
|
||||
continue
|
||||
|
||||
break
|
||||
else:
|
||||
continue
|
||||
|
||||
break
|
||||
else:
|
||||
return
|
||||
|
||||
self.restype = get_type(memberdef)
|
||||
|
||||
for child in memberdef:
|
||||
if child.tag == 'param':
|
||||
t = get_type(child)
|
||||
if t is not None:
|
||||
self.types.add(t)
|
||||
|
||||
if self.restype in self.types:
|
||||
self.restype = None
|
||||
|
||||
@property
|
||||
def deps(self):
|
||||
if self._deps is None:
|
||||
self._deps = dict(
|
||||
typedefs=set(),
|
||||
functions=set(),
|
||||
enums=set(),
|
||||
structures=set(),
|
||||
unions=set(),
|
||||
namespaces=set(),
|
||||
variables=set(),
|
||||
)
|
||||
if self.restype is not None:
|
||||
self.types.add(self.restype)
|
||||
|
||||
for type_ in self.types:
|
||||
if type_ in typedefs:
|
||||
self._deps['typedefs'].add(typedefs[type_])
|
||||
elif type_ in structures:
|
||||
self._deps['structures'].add(structures[type_])
|
||||
elif type_ in unions:
|
||||
self._deps['unions'].add(unions[type_])
|
||||
elif type_ in enums:
|
||||
self._deps['enums'].add(enums[type_])
|
||||
elif type_ in functions:
|
||||
self._deps['functions'].add(functions[type_])
|
||||
elif type_ in variables:
|
||||
self._deps['variables'].add(variables[type_])
|
||||
elif type_ in namespaces:
|
||||
self._deps['namespaces'].add(namespaces[type_])
|
||||
return self._deps
|
||||
|
||||
def __str__(self):
|
||||
return self.template.format(name=self.name)
|
||||
|
||||
|
||||
class FILE(object):
|
||||
def __init__(self, _, refid, name, node, **__):
|
||||
if name in files:
|
||||
self.__dict__.update(files[name].__dict__)
|
||||
return
|
||||
|
||||
files[name] = self
|
||||
|
||||
self.refid = refid
|
||||
self.name = name
|
||||
self.header_file = os.path.splitext(name)[0]
|
||||
|
||||
enums_ = []
|
||||
|
||||
for member in node:
|
||||
if member.tag != 'member':
|
||||
continue
|
||||
|
||||
cls = globals()[member.attrib['kind'].upper()]
|
||||
if cls == ENUM:
|
||||
member.attrib['name'] = member[0].text.strip()
|
||||
enums_.append(cls(self, **member.attrib))
|
||||
elif cls == ENUMVALUE:
|
||||
if enums_[-1].is_member(member):
|
||||
enums_[-1].add_member(member)
|
||||
|
||||
else:
|
||||
member.attrib['name'] = member[0].text.strip()
|
||||
cls(self, **member.attrib)
|
||||
|
||||
|
||||
class ENUM(object):
|
||||
template = '''\
|
||||
.. doxygenenum:: {name}
|
||||
:project: lvgl
|
||||
'''
|
||||
|
||||
def __init__(self, parent, refid, name, **_):
|
||||
if name in enums:
|
||||
self.__dict__.update(enums[name].__dict__)
|
||||
return
|
||||
|
||||
enums[name] = self
|
||||
|
||||
self.parent = parent
|
||||
self.refid = refid
|
||||
self.name = name
|
||||
self.members = []
|
||||
|
||||
def is_member(self, member):
|
||||
return (
|
||||
member.attrib['kind'] == 'enumvalue' and
|
||||
member.attrib['refid'].startswith(self.refid)
|
||||
)
|
||||
|
||||
def add_member(self, member):
|
||||
self.members.append(
|
||||
ENUMVALUE(
|
||||
self,
|
||||
member.attrib['refid'],
|
||||
member[0].text.strip()
|
||||
)
|
||||
)
|
||||
|
||||
def __str__(self):
|
||||
template = [self.template.format(name=self.name)]
|
||||
template.extend(list(str(member) for member in self.members))
|
||||
|
||||
return '\n'.join(template)
|
||||
|
||||
|
||||
defines = {}
|
||||
|
||||
|
||||
class DEFINE(object):
|
||||
template = '''\
|
||||
.. doxygendefine:: {name}
|
||||
:project: lvgl
|
||||
'''
|
||||
|
||||
def __init__(self, parent, refid, name, **_):
|
||||
if name in defines:
|
||||
self.__dict__.update(defines[name].__dict__)
|
||||
return
|
||||
|
||||
defines[name] = self
|
||||
|
||||
self.parent = parent
|
||||
self.refid = refid
|
||||
self.name = name
|
||||
|
||||
def __str__(self):
|
||||
return self.template.format(name=self.name)
|
||||
|
||||
|
||||
class ENUMVALUE(object):
|
||||
template = '''\
|
||||
.. doxygenenumvalue:: {name}
|
||||
:project: lvgl
|
||||
'''
|
||||
|
||||
def __init__(self, parent, refid, name, **_):
|
||||
self.parent = parent
|
||||
self.refid = refid
|
||||
self.name = name
|
||||
|
||||
def __str__(self):
|
||||
return self.template.format(name=self.name)
|
||||
|
||||
|
||||
class TYPEDEF(object):
|
||||
template = '''\
|
||||
.. doxygentypedef:: {name}
|
||||
:project: lvgl
|
||||
'''
|
||||
|
||||
def __init__(self, parent, refid, name, **_):
|
||||
if name in typedefs:
|
||||
self.__dict__.update(typedefs[name].__dict__)
|
||||
return
|
||||
|
||||
typedefs[name] = self
|
||||
|
||||
self.parent = parent
|
||||
self.refid = refid
|
||||
self.name = name
|
||||
self.type = None
|
||||
self._deps = None
|
||||
|
||||
if parent is not None:
|
||||
root = load_xml(parent.refid)
|
||||
|
||||
for compounddef in root:
|
||||
if compounddef.attrib['id'] != parent.refid:
|
||||
continue
|
||||
|
||||
for child in compounddef:
|
||||
if child.tag != 'sectiondef':
|
||||
continue
|
||||
if child.attrib['kind'] != 'typedef':
|
||||
continue
|
||||
|
||||
for memberdef in child:
|
||||
if memberdef.attrib['id'] == refid:
|
||||
break
|
||||
else:
|
||||
continue
|
||||
|
||||
break
|
||||
else:
|
||||
continue
|
||||
|
||||
break
|
||||
else:
|
||||
return
|
||||
|
||||
self.type = get_type(memberdef)
|
||||
|
||||
@property
|
||||
def deps(self):
|
||||
if self._deps is None:
|
||||
self._deps = dict(
|
||||
typedefs=set(),
|
||||
functions=set(),
|
||||
enums=set(),
|
||||
structures=set(),
|
||||
unions=set(),
|
||||
namespaces=set(),
|
||||
variables=set(),
|
||||
)
|
||||
if self.type is not None:
|
||||
type_ = self.type
|
||||
|
||||
if type_ in typedefs:
|
||||
self._deps['typedefs'].add(typedefs[type_])
|
||||
elif type_ in structures:
|
||||
self._deps['structures'].add(structures[type_])
|
||||
elif type_ in unions:
|
||||
self._deps['unions'].add(unions[type_])
|
||||
elif type_ in enums:
|
||||
self._deps['enums'].add(enums[type_])
|
||||
elif type_ in functions:
|
||||
self._deps['functions'].add(functions[type_])
|
||||
elif type_ in variables:
|
||||
self._deps['variables'].add(variables[type_])
|
||||
elif type_ in namespaces:
|
||||
self._deps['namespaces'].add(namespaces[type_])
|
||||
|
||||
return self._deps
|
||||
|
||||
def __str__(self):
|
||||
return self.template.format(name=self.name)
|
||||
|
||||
|
||||
classes = {}
|
||||
|
||||
|
||||
class CLASS(object):
|
||||
|
||||
def __init__(self, _, refid, name, node, **__):
|
||||
if name in classes:
|
||||
self.__dict__.update(classes[name].__dict__)
|
||||
return
|
||||
|
||||
classes[name] = self
|
||||
|
||||
self.refid = refid
|
||||
self.name = name
|
||||
|
||||
enums_ = []
|
||||
|
||||
for member in node:
|
||||
if member.tag != 'member':
|
||||
continue
|
||||
|
||||
cls = globals()[member.attrib['kind'].upper()]
|
||||
if cls == ENUM:
|
||||
member.attrib['name'] = member[0].text.strip()
|
||||
enums_.append(cls(self, **member.attrib))
|
||||
elif cls == ENUMVALUE:
|
||||
if enums_[-1].is_member(member):
|
||||
enums_[-1].add_member(member)
|
||||
|
||||
else:
|
||||
member.attrib['name'] = member[0].text.strip()
|
||||
cls(self, **member.attrib)
|
||||
|
||||
|
||||
lvgl_src_path = ''
|
||||
api_path = ''
|
||||
html_files = {}
|
||||
|
||||
|
||||
def iter_src(n, p):
|
||||
if p:
|
||||
out_path = os.path.join(api_path, p)
|
||||
else:
|
||||
out_path = api_path
|
||||
|
||||
index_file = None
|
||||
|
||||
if p:
|
||||
src_path = os.path.join(lvgl_src_path, p)
|
||||
else:
|
||||
src_path = lvgl_src_path
|
||||
|
||||
folders = []
|
||||
|
||||
for file in os.listdir(src_path):
|
||||
if 'private' in file:
|
||||
continue
|
||||
|
||||
if os.path.isdir(os.path.join(src_path, file)):
|
||||
folders.append((file, os.path.join(p, file)))
|
||||
continue
|
||||
|
||||
if not file.endswith('.h'):
|
||||
continue
|
||||
|
||||
if not os.path.exists(out_path):
|
||||
os.makedirs(out_path)
|
||||
|
||||
if index_file is None:
|
||||
index_file = open(os.path.join(out_path, 'index.rst'), 'w')
|
||||
if n:
|
||||
index_file.write('=' * len(n))
|
||||
index_file.write('\n' + n + '\n')
|
||||
index_file.write('=' * len(n))
|
||||
index_file.write('\n\n\n')
|
||||
|
||||
index_file.write('.. toctree::\n :maxdepth: 2\n\n')
|
||||
|
||||
name = os.path.splitext(file)[0]
|
||||
index_file.write(' ' + name + '\n')
|
||||
|
||||
rst_file = os.path.join(out_path, name + '.rst')
|
||||
html_file = os.path.join(p, name + '.html')
|
||||
html_files[name] = html_file
|
||||
|
||||
with open(rst_file, 'w') as f:
|
||||
f.write('.. _{0}:'.format(name))
|
||||
f.write('\n\n')
|
||||
f.write('=' * len(file))
|
||||
f.write('\n')
|
||||
f.write(file)
|
||||
f.write('\n')
|
||||
f.write('=' * len(file))
|
||||
f.write('\n\n\n')
|
||||
|
||||
f.write('.. doxygenfile:: ' + file)
|
||||
f.write('\n')
|
||||
f.write(' :project: lvgl')
|
||||
f.write('\n\n')
|
||||
|
||||
for name, folder in folders:
|
||||
if iter_src(name, folder):
|
||||
if index_file is None:
|
||||
index_file = open(os.path.join(out_path, 'index.rst'), 'w')
|
||||
|
||||
if n:
|
||||
index_file.write('=' * len(n))
|
||||
index_file.write('\n' + n + '\n')
|
||||
index_file.write('=' * len(n))
|
||||
index_file.write('\n\n\n')
|
||||
|
||||
index_file.write('.. toctree::\n :maxdepth: 2\n\n')
|
||||
|
||||
index_file.write(' ' + os.path.split(folder)[-1] + '/index\n')
|
||||
|
||||
if index_file is not None:
|
||||
index_file.write('\n')
|
||||
index_file.close()
|
||||
return True
|
||||
|
||||
return False
|
||||
|
||||
|
||||
def clean_name(nme):
|
||||
if nme.startswith('_lv_'):
|
||||
nme = nme[4:]
|
||||
elif nme.startswith('lv_'):
|
||||
nme = nme[3:]
|
||||
|
||||
if nme.endswith('_t'):
|
||||
nme = nme[:-2]
|
||||
|
||||
return nme
|
||||
|
||||
|
||||
def is_name_match(item_name, obj_name):
|
||||
u_num = item_name.count('_') + 1
|
||||
|
||||
obj_name = obj_name.split('_')
|
||||
if len(obj_name) < u_num:
|
||||
return False
|
||||
obj_name = '_'.join(obj_name[:u_num])
|
||||
|
||||
return item_name == obj_name
|
||||
|
||||
|
||||
def get_includes(name1, name2, obj, includes):
|
||||
name2 = clean_name(name2)
|
||||
|
||||
if not is_name_match(name1, name2):
|
||||
return
|
||||
|
||||
if obj.parent is not None:
|
||||
header_file = obj.parent.header_file
|
||||
elif hasattr(obj, 'header_file'):
|
||||
header_file = obj.header_file
|
||||
else:
|
||||
return
|
||||
|
||||
if not header_file:
|
||||
return
|
||||
|
||||
if header_file not in html_files:
|
||||
return
|
||||
|
||||
includes.add((header_file, html_files[header_file]))
|
||||
|
||||
|
||||
def run(project_path, temp_directory, *doc_paths):
|
||||
global base_path
|
||||
global xml_path
|
||||
global lvgl_src_path
|
||||
global api_path
|
||||
|
||||
base_path = temp_directory
|
||||
xml_path = os.path.join(base_path, 'xml')
|
||||
api_path = os.path.join(base_path, 'API')
|
||||
lvgl_src_path = os.path.join(project_path, 'src')
|
||||
|
||||
if not os.path.exists(api_path):
|
||||
os.makedirs(api_path)
|
||||
|
||||
iter_src('API', '')
|
||||
index = load_xml('index')
|
||||
|
||||
for compound in index:
|
||||
compound.attrib['name'] = compound[0].text.strip()
|
||||
if compound.attrib['kind'] in ('example', 'page', 'dir'):
|
||||
continue
|
||||
|
||||
globals()[compound.attrib['kind'].upper()](
|
||||
None,
|
||||
node=compound,
|
||||
**compound.attrib
|
||||
)
|
||||
|
||||
for folder in doc_paths:
|
||||
items = list(
|
||||
(os.path.splitext(item)[0], os.path.join(folder, item))
|
||||
for item in os.listdir(folder)
|
||||
if item.endswith('rst') and 'index' not in item
|
||||
)
|
||||
|
||||
for name, path in items:
|
||||
html_includes = set()
|
||||
|
||||
for container in (
|
||||
defines,
|
||||
enums,
|
||||
variables,
|
||||
namespaces,
|
||||
structures,
|
||||
unions,
|
||||
typedefs,
|
||||
functions
|
||||
):
|
||||
for n, o in container.items():
|
||||
get_includes(name, n, o, html_includes)
|
||||
|
||||
if html_includes:
|
||||
html_includes = list(
|
||||
':ref:`{0}`\n'.format(inc)
|
||||
for inc, _ in html_includes
|
||||
)
|
||||
|
||||
output = ('\n'.join(html_includes)) + '\n'
|
||||
|
||||
with open(path, 'rb') as f:
|
||||
try:
|
||||
data = f.read().decode('utf-8')
|
||||
except UnicodeDecodeError:
|
||||
print(path)
|
||||
raise
|
||||
|
||||
data = data.split('.. Autogenerated', 1)[0]
|
||||
|
||||
data += '.. Autogenerated\n\n'
|
||||
data += output
|
||||
|
||||
with open(path, 'wb') as f:
|
||||
f.write(data.encode('utf-8'))
|
||||
@@ -3,123 +3,160 @@ import os
|
||||
|
||||
|
||||
def process_index_rst(path):
|
||||
# print(path)
|
||||
with open(path) as fp:
|
||||
last_line=""
|
||||
line=""
|
||||
title_tmp=""
|
||||
line = fp.readline()
|
||||
d = {}
|
||||
while line:
|
||||
if line[0:3] == '"""':
|
||||
title_tmp = last_line
|
||||
elif line[0:15] ==".. lv_example::":
|
||||
name = line[16:].strip()
|
||||
title_tmp = title_tmp.strip()
|
||||
d[name] = title_tmp
|
||||
last_line = line
|
||||
line = fp.readline()
|
||||
# print(path)
|
||||
with open(path, 'r') as fp:
|
||||
data = fp.read()
|
||||
|
||||
return(d)
|
||||
data = data.split('\n')
|
||||
|
||||
h1= {
|
||||
"get_started":"Get started",
|
||||
"styles":"Styles",
|
||||
"anim":"Animations",
|
||||
"event":"Events",
|
||||
"layouts":"Layouts",
|
||||
"scroll":"Scrolling",
|
||||
"widgets":"Widgets"
|
||||
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",
|
||||
"imgbtn":"Image button",
|
||||
"keyboard":"Keyboard",
|
||||
"label":"Label",
|
||||
"led":"LED",
|
||||
"line":"Line",
|
||||
"list":"List",
|
||||
"menu":"Menu",
|
||||
"meter":"Meter",
|
||||
"msgbox":"Message box",
|
||||
"roller":"Roller",
|
||||
"slider":"Slider",
|
||||
"span":"Span",
|
||||
"spinbox":"Spinbox",
|
||||
"spinner":"Spinner",
|
||||
"switch":"Switch",
|
||||
"table":"Table",
|
||||
"tabview":"Tabview",
|
||||
"textarea":"Textarea",
|
||||
"tileview":"Tabview",
|
||||
"win":"Window",
|
||||
"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",
|
||||
"imgbtn": "Image button",
|
||||
"keyboard": "Keyboard",
|
||||
"label": "Label",
|
||||
"led": "LED",
|
||||
"line": "Line",
|
||||
"list": "List",
|
||||
"menu": "Menu",
|
||||
"meter": "Meter",
|
||||
"msgbox": "Message box",
|
||||
"roller": "Roller",
|
||||
"slider": "Slider",
|
||||
"span": "Span",
|
||||
"spinbox": "Spinbox",
|
||||
"spinner": "Spinner",
|
||||
"switch": "Switch",
|
||||
"table": "Table",
|
||||
"tabview": "Tabview",
|
||||
"textarea": "Textarea",
|
||||
"tileview": "Tabview",
|
||||
"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",
|
||||
"flex": "Flex",
|
||||
"grid": "Grid",
|
||||
}
|
||||
|
||||
|
||||
def print_item(path, lvl, d, fout):
|
||||
for k in d:
|
||||
v = d[k]
|
||||
if k.startswith(path + "/lv_example_"):
|
||||
fout.write("#"*lvl + " " + v + "\n")
|
||||
fout.write('```eval_rst\n')
|
||||
fout.write(f".. lv_example:: {k}\n")
|
||||
fout.write('```\n')
|
||||
fout.write("\n")
|
||||
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():
|
||||
paths = [ "../examples/", "../demos/"]
|
||||
fout = open("examples.md", "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))
|
||||
def exec(temp_directory):
|
||||
output_path = os.path.join(temp_directory, 'examples.rst')
|
||||
|
||||
filelist = [ fi for fi in filelist if fi.endswith("index.rst") ]
|
||||
paths = ["../examples/", "../demos/"]
|
||||
fout = open(output_path, "w")
|
||||
filelist = []
|
||||
|
||||
d_all = {}
|
||||
#print all the file names
|
||||
for fn in filelist:
|
||||
d_act = process_index_rst(fn)
|
||||
d_all.update(d_act)
|
||||
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))
|
||||
|
||||
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")
|
||||
filelist = [fi for fi in filelist if fi.endswith("index.rst")]
|
||||
|
||||
for h in h1:
|
||||
fout.write("## " + h1[h] + "\n")
|
||||
d_all = {}
|
||||
# print all the file names
|
||||
for fn in filelist:
|
||||
d_all.update(dict(tuple(item for item in process_index_rst(fn))))
|
||||
|
||||
if h == "widgets":
|
||||
for w in widgets:
|
||||
fout.write("### " + widgets[w] + "\n")
|
||||
print_item(h + "/" + w, 4, d_all, fout)
|
||||
elif h == "layouts":
|
||||
for l in layouts:
|
||||
fout.write("### " + layouts[l] + "\n")
|
||||
print_item(h + "/" + l, 4, d_all, fout)
|
||||
else:
|
||||
print_item(h, 3, d_all, fout)
|
||||
# fout.write("```eval_rst\n")
|
||||
# fout.write(":github_url: |github_link_base|/examples.md\n")
|
||||
# fout.write("```\n")
|
||||
# fout.write("\n")
|
||||
|
||||
fout.write("")
|
||||
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("")
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
# Cpp
|
||||
===
|
||||
Cpp
|
||||
===
|
||||
|
||||
In progress: https://github.com/lvgl/lv_binding_cpp
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
# Bindings
|
||||
========
|
||||
Bindings
|
||||
========
|
||||
|
||||
|
||||
```eval_rst
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 2
|
||||
|
||||
@@ -10,5 +10,3 @@
|
||||
cpp
|
||||
pikascript
|
||||
javascript
|
||||
```
|
||||
|
||||
@@ -1,113 +0,0 @@
|
||||
# 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**
|
||||
|
||||
<img src="../../_static/img/js_code.png">
|
||||
|
||||
|
||||
**Code Runing on Real Device**
|
||||
|
||||
<img src="../../_static/img/js_on_device.jpg" style="transform: rotate(270deg); max-width: 400px; padding-left: 100px;">
|
||||
|
||||
## 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 suport 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-simualtor.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
|
||||
|
||||
[Buitin-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
|
||||
|
||||
- [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
|
||||
133
docs/get-started/bindings/javascript.rst
Normal file
133
docs/get-started/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 Runing 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 suport 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-simualtor.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
|
||||
----
|
||||
|
||||
`Buitin-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
|
||||
@@ -1,193 +0,0 @@
|
||||
# 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?
|
||||
|
||||
**TL;DR:** It's very much like the C API, but Object-Oriented for LVGL components.
|
||||
|
||||
Let's dive right into an example!
|
||||
|
||||
### A simple example
|
||||
|
||||
```python
|
||||
import lvgl as lv
|
||||
lv.init()
|
||||
scr = lv.obj()
|
||||
btn = lv.btn(scr)
|
||||
btn.align(lv.ALIGN.CENTER, 0, 0)
|
||||
label = lv.label(btn)
|
||||
label.set_text('Hello World!')
|
||||
lv.scr_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
|
||||
<img src="https://user-images.githubusercontent.com/11742638/198729010-35a12e49-4945-414a-8c3e-d32bc95da940.png" align=middle /> 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
|
||||
- ESP32 specific: ILI9341, ILI9488, GC9A01, ST7789, ST7735
|
||||
- Generic (pure Python): ILI9341, ST7789, ST7735
|
||||
- Input drivers:
|
||||
- SDL, 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
|
||||
|
||||
To support the auto-generation of the Python API, the LVGL C API must follow some coding conventions:
|
||||
|
||||
- Use `enum`s instead of macros. If inevitable to use `define`s export them with `LV_EXPORT_CONST_INT(defined_value)` right after the `define`.
|
||||
- In function arguments use `type name[]` declaration for array parameters instead of `type * name`
|
||||
- Use typed pointers instead of `void *` pointers
|
||||
- Widget constructor must follow the `lv_<widget_name>_create(lv_obj_t * parent)` pattern.
|
||||
- Widget members function must start with `lv_<modul_name>` and should receive `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. `lv_disp_set_default(lv_disp_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_ITERATE_ROOTS` list in `lv_gc.h` and mark the variable with `GC_ROOT(variable)` when it's used.
|
||||
**See [Memory Management](#memory-management)**
|
||||
- To register and use callbacks one of the followings needs to be followed. **See [Callbacks](#callbacks)**
|
||||
- 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.
|
||||
|
||||
Most of these rules are simple and straightforward but there are two related concepts that worth a deeper look: **Memory Management** and **Callbacks**.
|
||||
|
||||
### Memory Management
|
||||
|
||||
When LVGL runs in Micropython, all dynamic memory allocations (`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 `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 `LV_GC_ROOT(_var)`
|
||||
- Include `lv_gc.h` on files that use `LV_GC_ROOT`
|
||||
- Add `_var` to `LV_ITERATE_ROOTS` on `lv_gc.h`
|
||||
|
||||
#### Example
|
||||
|
||||
https://github.com/lvgl/lvgl/commit/adced46eccfa0437f84aa51aedca4895cc3c679c
|
||||
|
||||
#### 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
|
||||
|
||||
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 expectd 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 recieves `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
|
||||
|
||||
- [lv_anim_t](https://github.com/lvgl/lvgl/blob/5d50fbc066938d1a4eb43a8366cf83fbd4ce29f2/src/misc/lv_anim.h#L73-L100) contains `user_data` field.
|
||||
[lv_anim_set_path_cb](https://github.com/lvgl/lvgl/blob/5d50fbc066938d1a4eb43a8366cf83fbd4ce29f2/src/misc/lv_anim.h#L197) registers `path_cb` callback. Both `lv_anim_set_path_cb` and [`lv_anim_path_cb_t`](https://github.com/lvgl/lvgl/blob/5d50fbc066938d1a4eb43a8366cf83fbd4ce29f2/src/misc/lv_anim.h#L46) recieve `lv_anim_t` as their first argument
|
||||
- [`path_cb` field](https://github.com/lvgl/lvgl/blob/5d50fbc066938d1a4eb43a8366cf83fbd4ce29f2/src/misc/lv_anim.h#L83) can also be assigned directly in the Python code because it's a member of `lv_anim_t` which contains `user_data` field, and [`lv_anim_path_cb_t`](https://github.com/lvgl/lvgl/blob/5d50fbc066938d1a4eb43a8366cf83fbd4ce29f2/src/misc/lv_anim.h#L46) recieve `lv_anim_t` as its first argument.
|
||||
- [`lv_imgfont_create`](https://github.com/lvgl/lvgl/blob/5d50fbc066938d1a4eb43a8366cf83fbd4ce29f2/src/others/imgfont/lv_imgfont.h#L43) registers `path_cb` and recieves `user_data` as the last argument. The callback [`lv_imgfont_get_path_cb_t`](https://github.com/lvgl/lvgl/blob/5d50fbc066938d1a4eb43a8366cf83fbd4ce29f2/src/others/imgfont/lv_imgfont.h#L29-L31) also receieves the `user_data` as the last argument.
|
||||
|
||||
#### 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)
|
||||
316
docs/get-started/bindings/micropython.rst
Normal file
316
docs/get-started/bindings/micropython.rst
Normal file
@@ -0,0 +1,316 @@
|
||||
.. _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
|
||||
|
||||
import lvgl as lv
|
||||
lv.init()
|
||||
scr = lv.obj()
|
||||
btn = lv.btn(scr)
|
||||
btn.align(lv.ALIGN.CENTER, 0, 0)
|
||||
label = lv.label(btn)
|
||||
label.set_text('Hello World!')
|
||||
lv.scr_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
|
||||
- ESP32 specific:
|
||||
|
||||
- ILI9341
|
||||
- ILI9488
|
||||
- GC9A01
|
||||
- ST7789
|
||||
- ST7735
|
||||
|
||||
- Generic (pure Python):
|
||||
|
||||
- ILI9341
|
||||
- ST7789
|
||||
- ST7735
|
||||
|
||||
- Input drivers:
|
||||
|
||||
- SDL
|
||||
- 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
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
To support the auto-generation of the Python API, 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_<modul_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_disp_set_default(lv_disp_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 :c:macro:`LV_ITERATE_ROOTS`
|
||||
list in ``lv_gc.h`` and mark the variable with :cpp:expr:`GC_ROOT(variable)` when it's used. **See** :ref:`memory_management`
|
||||
- To register and use callbacks one of the followings needs to be followed. **See** :ref:`callbacks`
|
||||
|
||||
- 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.
|
||||
|
||||
Most of these rules are simple and straightforward but there are two related concepts that worth a deeper look:
|
||||
:ref:`memory_management` and :ref:`callbacks`.
|
||||
|
||||
.. _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_GC_ROOT(_var)`
|
||||
- Include ``lv_gc.h`` on files that use :c:macro:`LV_GC_ROOT`
|
||||
- Add ``_var`` to :c:macro:`LV_ITERATE_ROOTS` on ``lv_gc.h``
|
||||
|
||||
Example
|
||||
^^^^^^^
|
||||
|
||||
https://github.com/lvgl/lvgl/commit/adced46eccfa0437f84aa51aedca4895cc3c679c
|
||||
|
||||
|
||||
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 expectd 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 recieves ``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`
|
||||
recieve :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`
|
||||
recieve :cpp:type:`lv_anim_t` as its first argument.
|
||||
- :cpp:func:`lv_imgfont_create` registers ``path_cb`` and recieves ``user_data`` as the last
|
||||
argument. The callback :cpp:func:`lv_imgfont_get_path_cb_t` also receieves 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>`__
|
||||
@@ -1,162 +0,0 @@
|
||||
# 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
|
||||
|
||||
```python
|
||||
import pika_lvgl as lv
|
||||
import PikaStdLib
|
||||
mem = PikaStdLib.MemChecker()
|
||||
# Create an Arc
|
||||
arc = lv.arc(lv.scr_act())
|
||||
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
|
||||
|
||||
``` python
|
||||
import pika_lvgl as lv
|
||||
import PikaStdLib
|
||||
mem = PikaStdLib.MemChecker()
|
||||
bar1 = lv.bar(lv.scr_act())
|
||||
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
|
||||
|
||||
``` 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.scr_act())
|
||||
btn1.align(lv.ALIGN.TOP_MID, 0, 10)
|
||||
btn2 = lv.btn(lv.scr_act())
|
||||
btn2.align(lv.ALIGN.TOP_MID, 0, 50)
|
||||
btn1.add_event(event_cb_1, lv.EVENT.CLICKED, 0)
|
||||
btn2.add_event(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
|
||||
|
||||
``` python
|
||||
import pika_lvgl as lv
|
||||
import PikaStdLib
|
||||
mem = PikaStdLib.MemChecker()
|
||||
cb = lv.checkbox(lv.scr_act())
|
||||
cb.set_text("Apple")
|
||||
cb.align(lv.ALIGN.TOP_LEFT, 0 ,0)
|
||||
cb = lv.checkbox(lv.scr_act())
|
||||
cb.set_text("Banana")
|
||||
cb.add_state(lv.STATE.CHECKED)
|
||||
cb.align(lv.ALIGN.TOP_LEFT, 0 ,30)
|
||||
cb = lv.checkbox(lv.scr_act())
|
||||
cb.set_text("Lemon")
|
||||
cb.add_state(lv.STATE.DISABLED)
|
||||
cb.align(lv.ALIGN.TOP_LEFT, 0 ,60)
|
||||
cb = lv.checkbox(lv.scr_act())
|
||||
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)
|
||||
|
||||
``` 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.
|
||||
|
||||
``` 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:
|
||||
scaning 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
|
||||
|
||||
---
|
||||
203
docs/get-started/bindings/pikascript.rst
Normal file
203
docs/get-started/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.scr_act())
|
||||
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.scr_act())
|
||||
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.scr_act())
|
||||
btn1.align(lv.ALIGN.TOP_MID, 0, 10)
|
||||
btn2 = lv.btn(lv.scr_act())
|
||||
btn2.align(lv.ALIGN.TOP_MID, 0, 50)
|
||||
btn1.add_event(event_cb_1, lv.EVENT.CLICKED, 0)
|
||||
btn2.add_event(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.scr_act())
|
||||
cb.set_text("Apple")
|
||||
cb.align(lv.ALIGN.TOP_LEFT, 0 ,0)
|
||||
cb = lv.checkbox(lv.scr_act())
|
||||
cb.set_text("Banana")
|
||||
cb.add_state(lv.STATE.CHECKED)
|
||||
cb.align(lv.ALIGN.TOP_LEFT, 0 ,30)
|
||||
cb = lv.checkbox(lv.scr_act())
|
||||
cb.set_text("Lemon")
|
||||
cb.add_state(lv.STATE.DISABLED)
|
||||
cb.align(lv.ALIGN.TOP_LEFT, 0 ,60)
|
||||
cb = lv.checkbox(lv.scr_act())
|
||||
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:
|
||||
scaning 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
|
||||
@@ -1,27 +0,0 @@
|
||||
# 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 [Introduction](https://docs.lvgl.io/master/intro/index.html) page of the documentation (5 minutes)
|
||||
3. Read the [Quick overview](https://docs.lvgl.io/master/get-started/quick-overview.html) page of the documentation (15 minutes)
|
||||
4. Set up a [Simulator](https://docs.lvgl.io/master/get-started/platforms/pc-simulator.html) (10 minutes)
|
||||
5. Try out some [Examples](https://docs.lvgl.io/master/examples.html)
|
||||
6. Check out the Platform-specific tutorials. (in this section below). (10 minutes)
|
||||
7. Port LVGL to a board. See the [Porting](https://docs.lvgl.io/master/porting/index.html) guide or check the ready to use [Projects](https://github.com/lvgl?q=lv_port_&type=&language=)
|
||||
8. Read the [Overview](https://docs.lvgl.io/master/overview/index.html) page to get a better understanding of the library. (2-3 hours)
|
||||
9. Check the documentation of the [Widgets](https://docs.lvgl.io/master/widgets/index.html) to see their features and usage
|
||||
10. If you have questions got to the [Forum](http://forum.lvgl.io/)
|
||||
11. Read the [Contributing](https://docs.lvgl.io/master/CONTRIBUTING.html) guide to see how you can help to improve LVGL (15 minutes)
|
||||
|
||||
|
||||
```eval_rst
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 2
|
||||
|
||||
quick-overview
|
||||
platforms/index
|
||||
os/index
|
||||
bindings/index
|
||||
```
|
||||
|
||||
28
docs/get-started/index.rst
Normal file
28
docs/get-started/index.rst
Normal file
@@ -0,0 +1,28 @@
|
||||
===========
|
||||
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
|
||||
platforms/index
|
||||
os/index
|
||||
bindings/index
|
||||
@@ -1,3 +0,0 @@
|
||||
# FreeRTOS
|
||||
|
||||
TODO
|
||||
5
docs/get-started/os/freertos.rst
Normal file
5
docs/get-started/os/freertos.rst
Normal file
@@ -0,0 +1,5 @@
|
||||
========
|
||||
FreeRTOS
|
||||
========
|
||||
|
||||
TODO
|
||||
@@ -1,13 +0,0 @@
|
||||
# (RT)OS
|
||||
|
||||
```eval_rst
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 2
|
||||
|
||||
nuttx
|
||||
rt-thread
|
||||
freertos
|
||||
zephyr
|
||||
```
|
||||
|
||||
10
docs/get-started/os/index.rst
Normal file
10
docs/get-started/os/index.rst
Normal file
@@ -0,0 +1,10 @@
|
||||
======
|
||||
(RT)OS
|
||||
======
|
||||
|
||||
.. toctree:: :maxdepth: 2
|
||||
|
||||
nuttx
|
||||
rt-thread
|
||||
freertos
|
||||
zephyr
|
||||
@@ -1,97 +0,0 @@
|
||||
# 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/)
|
||||
|
||||
```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
|
||||
|
||||
```shell
|
||||
$ mkdir ~/nuttxspace
|
||||
$ cd ~/nuttxspace
|
||||
```
|
||||
|
||||
### Clone the NuttX and Apps repositories:
|
||||
|
||||
```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
|
||||
|
||||
```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:
|
||||
|
||||
```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:
|
||||
```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:
|
||||
```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/)
|
||||
|
||||
146
docs/get-started/os/nuttx.rst
Normal file
146
docs/get-started/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/>`__
|
||||
@@ -1,46 +0,0 @@
|
||||
# RT-Thread RTOS
|
||||
|
||||
<img src="https://raw.githubusercontent.com/RT-Thread/rt-thread/master/documentation/figures/logo.png" width=40% style="float: center;" >
|
||||
|
||||
## 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 <a href="https://packages.rt-thread.org/en/">package ecosystem</a>
|
||||
- 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 <a href="https://www.rt-thread.io/board.html">architectures and chips</a>.
|
||||
|
||||
## 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 [software package](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 | Note |
|
||||
| --------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| [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) | [synwit swm341](https://github.com/RT-Thread/rt-thread/tree/master/bsp/synwit/swm341/applications/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) | |
|
||||
|
||||
### 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/)
|
||||
|
||||
86
docs/get-started/os/rt-thread.rst
Normal file
86
docs/get-started/os/rt-thread.rst
Normal file
@@ -0,0 +1,86 @@
|
||||
==============
|
||||
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 | Note |
|
||||
+======================================================================================================================================+======================================================================================================================================================+
|
||||
| `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>`__ | `synwit swm341 <https://github.com/RT-Thread/rt-thread/tree/master/bsp/synwit/swm341/applications/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>`__ |
|
||||
+--------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------+
|
||||
|
||||
|
||||
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/>`__
|
||||
@@ -1,3 +0,0 @@
|
||||
# Zephyr
|
||||
|
||||
TODO
|
||||
5
docs/get-started/os/zephyr.rst
Normal file
5
docs/get-started/os/zephyr.rst
Normal file
@@ -0,0 +1,5 @@
|
||||
======
|
||||
Zephyr
|
||||
======
|
||||
|
||||
TODO
|
||||
104
docs/get-started/platforms/arduino.rst
Normal file
104
docs/get-started/platforms/arduino.rst
Normal file
@@ -0,0 +1,104 @@
|
||||
=======
|
||||
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`
|
||||
5. Set :c:macro:`LV_TICK_CUSTOM`
|
||||
|
||||
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.
|
||||
@@ -1,92 +0,0 @@
|
||||
|
||||
# CMake
|
||||
LVGL supports integrating with [CMake](https://cmake.org/). It comes with preconfigured targets for:
|
||||
- [Espressif (ESP32)](https://docs.espressif.com/projects/esp-idf/en/v3.3/get-started-cmake/index.html)
|
||||
- [MicroPython](https://docs.micropython.org/en/v1.15/develop/cmodules.html)
|
||||
- [Zephyr](https://docs.zephyrproject.org/latest/guides/zephyr_cmake_package.html)
|
||||
|
||||
On top of the preconfigured targets you can also use "plain" CMake to integrate LVGL into any custom C/C++ project.
|
||||
|
||||
## Prerequisites
|
||||
- CMake ( >= 3.12.4 )
|
||||
- Compatible build tool e.g.
|
||||
- [Make](https://www.gnu.org/software/make/)
|
||||
- [Ninja](https://ninja-build.org/)
|
||||
|
||||
## Building LVGL with CMake
|
||||
There are many ways to include external CMake projects into your own. A modern one also used in this example is the CMake [FetchContent](https://cmake.org/cmake/help/latest/module/FetchContent.html) module. This module conveniently allows us to download dependencies directly at configure time from e.g. [GitHub](https://github.com/). Here is an example how we might include LVGL into our own project.
|
||||
|
||||
```cmake
|
||||
cmake_minimum_required(VERSION 3.14)
|
||||
include(FetchContent)
|
||||
|
||||
project(MyProject LANGUAGES C CXX)
|
||||
|
||||
# Build an executable called "MyFirmware"
|
||||
add_executable(MyFirmware src/main.c)
|
||||
|
||||
# Specify path to own LVGL config header
|
||||
set(LV_CONF_PATH
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/lv_conf.h
|
||||
CACHE STRING "" FORCE)
|
||||
|
||||
# Fetch LVGL from GitHub
|
||||
FetchContent_Declare(lvgl GIT_REPOSITORY https://github.com/lvgl/lvgl.git)
|
||||
FetchContent_MakeAvailable(lvgl)
|
||||
|
||||
# The target "MyFirmware" depends on LVGL
|
||||
target_link_libraries(MyFirmware PRIVATE lvgl::lvgl)
|
||||
```
|
||||
|
||||
This configuration declares a dependency between the two targets **MyFirmware** and **lvgl**. Upon building the target **MyFirmware** this dependency will be resolved and **lvgl** will be built and linked with it. Since LVGL requires a config header called [lv_conf.h](https://github.com/lvgl/lvgl/blob/master/lv_conf_template.h) to be includable by its sources we also set the option `LV_CONF_PATH` to point to our own copy of it.
|
||||
|
||||
### Additional CMake options
|
||||
Besides `LV_CONF_PATH` there are few additional CMake options available.
|
||||
|
||||
#### Include paths options
|
||||
|
||||
- `LV_LVGL_H_INCLUDE_SIMPLE`: which specifies whether to `#include "lvgl.h"` absolut or relative
|
||||
|
||||
| ON (default) | OFF |
|
||||
|--------------|----------------|
|
||||
| "lvgl.h" | "../../lvgl.h" |
|
||||
|
||||
- `LV_CONF_INCLUDE_SIMPLE`: which specifies whether to `#include "lv_conf.h"` and `"lv_drv_conf.h"` absolut or relative
|
||||
|
||||
| ON (default) | OFF |
|
||||
|-----------------|-----------------------|
|
||||
| "lv_conf.h" | "../../lv_conf.h" |
|
||||
| "lv_drv_conf.h" | "../../lv_drv_conf.h" |
|
||||
|
||||
> We do not recommend disabling those options unless your folder layout makes it absolutely necessary.
|
||||
|
||||
#### Examples/demos options
|
||||
|
||||
LVGL [examples](https://docs.lvgl.io/master/examples.html) and [demos](https://github.com/lvgl/lvgl/demos) are built by default in the main CMake file.
|
||||
To disable their built, use:
|
||||
|
||||
- `LV_CONF_BUILD_DISABLE_EXAMPLES`: Set to `1` to disable _examples_ build
|
||||
- `LV_CONF_BUILD_DISABLE_DEMOS`: Set to `1` to disable _demos_ build
|
||||
|
||||
## Building LVGL drivers
|
||||
|
||||
To build [LVGL drivers](https://github.com/lvgl/lv_drivers), you can use:
|
||||
|
||||
```cmake
|
||||
FetchContent_Declare(lv_drivers
|
||||
GIT_REPOSITORY https://github.com/lvgl/lv_drivers)
|
||||
FetchContent_MakeAvailable(lv_drivers)
|
||||
|
||||
# The target "MyFirmware" depends on LVGL and drivers
|
||||
target_link_libraries(MyFirmware PRIVATE lvgl::lvgl lvgl::drivers)
|
||||
```
|
||||
|
||||
# Build shared libraries with CMake
|
||||
By default, LVGL will be built as a static library (archive). CMake can instead be instructed to build LVGL as shared library (.so/.dll/etc.):
|
||||
```cmake
|
||||
set(BUILD_SHARED_LIBS ON)
|
||||
```
|
||||
OR
|
||||
```
|
||||
$ cmake "-DBUILD_SHARED_LIBS=ON" .
|
||||
```
|
||||
137
docs/get-started/platforms/cmake.rst
Normal file
137
docs/get-started/platforms/cmake.rst
Normal file
@@ -0,0 +1,137 @@
|
||||
=====
|
||||
CMake
|
||||
=====
|
||||
|
||||
LVGL supports integrating with `CMake <https://cmake.org/>`__. It comes
|
||||
with preconfigured targets for:
|
||||
|
||||
- `Espressif (ESP32) <https://docs.espressif.com/projects/esp-idf/en/v3.3/get-started-cmake/index.html>`__
|
||||
- `MicroPython <https://docs.micropython.org/en/v1.15/develop/cmodules.html>`__
|
||||
- `Zephyr <https://docs.zephyrproject.org/latest/guides/zephyr_cmake_package.html>`__
|
||||
|
||||
On top of the preconfigured targets you can also use “plain” CMake to
|
||||
integrate LVGL into any custom C/C++ project.
|
||||
|
||||
|
||||
Prerequisites
|
||||
*************
|
||||
|
||||
* CMake ( >= 3.12.4 )
|
||||
* Compatible build tool e.g.
|
||||
* `Make <https://www.gnu.org/software/make/>`__
|
||||
* `Ninja <https://ninja-build.org/>`__
|
||||
|
||||
|
||||
Building LVGL with CMake
|
||||
************************
|
||||
|
||||
There are many ways to include external CMake projects into your own. A
|
||||
modern one also used in this example is the CMake `FetchContent <https://cmake.org/cmake/help/latest/module/FetchContent.html>`__
|
||||
module. This module conveniently allows us to download dependencies
|
||||
directly at configure time from e.g. `GitHub <https://github.com/>`__.
|
||||
Here is an example how we might include LVGL into our own project.
|
||||
|
||||
.. code:: cmake
|
||||
|
||||
cmake_minimum_required(VERSION 3.14)
|
||||
include(FetchContent)
|
||||
|
||||
project(MyProject LANGUAGES C CXX)
|
||||
|
||||
# Build an executable called "MyFirmware"
|
||||
add_executable(MyFirmware src/main.c)
|
||||
|
||||
# Specify path to own LVGL config header
|
||||
set(LV_CONF_PATH
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/lv_conf.h
|
||||
CACHE STRING "" FORCE)
|
||||
|
||||
# Fetch LVGL from GitHub
|
||||
FetchContent_Declare(lvgl GIT_REPOSITORY https://github.com/lvgl/lvgl.git)
|
||||
FetchContent_MakeAvailable(lvgl)
|
||||
|
||||
# The target "MyFirmware" depends on LVGL
|
||||
target_link_libraries(MyFirmware PRIVATE lvgl::lvgl)
|
||||
|
||||
This configuration declares a dependency between the two targets
|
||||
**MyFirmware** and **lvgl**. Upon building the target **MyFirmware**
|
||||
this dependency will be resolved and **lvgl** will be built and linked
|
||||
with it. Since LVGL requires a config header called `lv_conf.h <https://github.com/lvgl/lvgl/blob/master/lv_conf_template.h>`__
|
||||
to be includable by its sources we also set the option :c:macro:`LV_CONF_PATH`
|
||||
to point to our own copy of it.
|
||||
|
||||
|
||||
Additional CMake options
|
||||
========================
|
||||
|
||||
Besides :c:macro:`LV_CONF_PATH` there are few additional CMake options available.
|
||||
|
||||
|
||||
Include paths options
|
||||
---------------------
|
||||
|
||||
- :c:macro:`LV_LVGL_H_INCLUDE_SIMPLE`: which specifies whether to ``#include "lvgl.h"`` absolut or relative
|
||||
|
||||
============ ==============
|
||||
ON (default) OFF
|
||||
============ ==============
|
||||
“lvgl.h” “../../lvgl.h”
|
||||
============ ==============
|
||||
|
||||
- :c:macro:`LV_CONF_INCLUDE_SIMPLE`: which specifies whether to ``#include "lv_conf.h"`` and ``"lv_drv_conf.h"`` absolut or relative
|
||||
|
||||
=============== =====================
|
||||
ON (default) OFF
|
||||
=============== =====================
|
||||
“lv_conf.h” “../../lv_conf.h”
|
||||
“lv_drv_conf.h” “../../lv_drv_conf.h”
|
||||
=============== =====================
|
||||
|
||||
..
|
||||
|
||||
We do not recommend disabling those options unless your folder layout
|
||||
makes it absolutely necessary.
|
||||
|
||||
|
||||
Examples/demos options
|
||||
----------------------
|
||||
|
||||
| LVGL `examples <https://docs.lvgl.io/master/examples.html>`__ and
|
||||
`demos <https://github.com/lvgl/lvgl/demos>`__ are built by default in
|
||||
the main CMake file.
|
||||
| To disable their built, use:
|
||||
|
||||
- :c:macro:`LV_CONF_BUILD_DISABLE_EXAMPLES`: Set to ``1`` to disable *examples* build
|
||||
- :c:macro:`LV_CONF_BUILD_DISABLE_DEMOS`: Set to ``1`` to disable *demos* build
|
||||
|
||||
|
||||
Building LVGL drivers
|
||||
*********************
|
||||
|
||||
To build `LVGL drivers <https://github.com/lvgl/lv_drivers>`__, you can use:
|
||||
|
||||
.. code:: cmake
|
||||
|
||||
FetchContent_Declare(lv_drivers
|
||||
GIT_REPOSITORY https://github.com/lvgl/lv_drivers)
|
||||
FetchContent_MakeAvailable(lv_drivers)
|
||||
|
||||
# The target "MyFirmware" depends on LVGL and drivers
|
||||
target_link_libraries(MyFirmware PRIVATE lvgl::lvgl lvgl::drivers)
|
||||
|
||||
|
||||
Build shared libraries with CMake
|
||||
*********************************
|
||||
|
||||
By default, LVGL will be built as a static library (archive). CMake can
|
||||
instead be instructed to build LVGL as shared library (.so/.dll/etc.):
|
||||
|
||||
.. code:: cmake
|
||||
|
||||
set(BUILD_SHARED_LIBS ON)
|
||||
|
||||
OR
|
||||
|
||||
.. code:: console
|
||||
|
||||
$ cmake "-DBUILD_SHARED_LIBS=ON" .
|
||||
@@ -1,58 +0,0 @@
|
||||
|
||||
# Espressif (ESP32 chip series)
|
||||
LVGL can be used and configured as a standard [ESP-IDF](https://github.com/espressif/esp-idf) component.
|
||||
|
||||
More information about ESP-IDF build system can be found [here](https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-guides/build-system.html).
|
||||
|
||||
## LVGL demo project for ESP32
|
||||
|
||||
We've created [lv_port_esp32](https://github.com/lvgl/lv_port_esp32), a project using ESP-IDF and LVGL to show one of the demos from [demos](https://github.com/lvgl/lvgl/demos).
|
||||
You can configure the project to use one of the many supported display controllers and targets (chips).
|
||||
|
||||
See [lvgl_esp32_drivers](https://github.com/lvgl/lvgl_esp32_drivers) repository for a complete list
|
||||
of supported display and indev (touch) controllers and targets.
|
||||
|
||||
## Using LVGL in your ESP-IDF project
|
||||
|
||||
### Prerequisites
|
||||
|
||||
* ESP-IDF v4.1 and above
|
||||
* ESP evaluation board with a display
|
||||
|
||||
### Obtaining LVGL
|
||||
|
||||
__Option 1:__ git submodule
|
||||
|
||||
Simply clone LVGL into your `project_root/components` directory and it will be automatically integrated into the project.
|
||||
If the project is a git repository you can include LVGL as a git submodule:
|
||||
|
||||
```sh
|
||||
git submodule add https://github.com/lvgl/lvgl.git components/lvgl
|
||||
```
|
||||
|
||||
The above command will clone LVGL's main repository into the `components/lvgl` directory. LVGL includes a `CMakeLists.txt` file that sets some configuration options so you can use LVGL right away.
|
||||
|
||||
__Option 2:__ IDF Component Manager
|
||||
|
||||
LVGL is also distributed through [IDF Component Manager](https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-guides/tools/idf-component-manager.html).
|
||||
It allows users to seamlessly integrate [LVGL component](https://components.espressif.com/component/lvgl/lvgl) into their project with following command:
|
||||
|
||||
```sh
|
||||
idf.py add-dependency lvgl/lvgl>=8.*
|
||||
```
|
||||
|
||||
During next project build, LVGL component will be fetched from the component registry and added to project build.
|
||||
|
||||
### Configuration
|
||||
|
||||
When you are ready to configure LVGL, launch the configuration menu with `idf.py menuconfig` in your project root directory, go to `Component config` and then `LVGL configuration`.
|
||||
|
||||
## Using lvgl_esp32_drivers in ESP-IDF project
|
||||
|
||||
You can also add `lvgl_esp32_drivers` as a "component". This component should be located inside a directory named "components" in your project root directory.
|
||||
|
||||
When your project is a git repository you can include `lvgl_esp32_drivers` as a git submodule:
|
||||
|
||||
```sh
|
||||
git submodule add https://github.com/lvgl/lvgl_esp32_drivers.git components/lvgl_esp32_drivers
|
||||
```
|
||||
85
docs/get-started/platforms/espressif.rst
Normal file
85
docs/get-started/platforms/espressif.rst
Normal file
@@ -0,0 +1,85 @@
|
||||
=============================
|
||||
Espressif (ESP32 chip series)
|
||||
=============================
|
||||
|
||||
LVGL can be used and configured as a standard `ESP-IDF <https://github.com/espressif/esp-idf>`__ component.
|
||||
|
||||
More information about ESP-IDF build system can be found `here <https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-guides/build-system.html>`__.
|
||||
|
||||
|
||||
LVGL demo project for ESP32
|
||||
---------------------------
|
||||
|
||||
We’ve created `lv_port_esp32 <https://github.com/lvgl/lv_port_esp32>`__,
|
||||
a project using ESP-IDF and LVGL to show one of the demos from
|
||||
`demos <https://github.com/lvgl/lvgl/demos>`__. You can configure the
|
||||
project to use one of the many supported display controllers and targets
|
||||
(chips).
|
||||
|
||||
See `lvgl_esp32_drivers <https://github.com/lvgl/lvgl_esp32_drivers>`__
|
||||
repository for a complete list of supported display and indev (touch)
|
||||
controllers and targets.
|
||||
|
||||
|
||||
Using LVGL in your ESP-IDF project
|
||||
----------------------------------
|
||||
|
||||
Prerequisites
|
||||
~~~~~~~~~~~~~
|
||||
|
||||
- ESP-IDF v4.1 and above
|
||||
- ESP evaluation board with a display
|
||||
|
||||
|
||||
Obtaining LVGL
|
||||
~~~~~~~~~~~~~~
|
||||
|
||||
**Option 1:** git submodule
|
||||
|
||||
Simply clone LVGL into your ``project_root/components`` directory and it
|
||||
will be automatically integrated into the project. If the project is a
|
||||
git repository you can include LVGL as a git submodule:
|
||||
|
||||
.. code:: sh
|
||||
|
||||
git submodule add https://github.com/lvgl/lvgl.git components/lvgl
|
||||
|
||||
The above command will clone LVGL’s main repository into the
|
||||
``components/lvgl`` directory. LVGL includes a ``CMakeLists.txt`` file
|
||||
that sets some configuration options so you can use LVGL right away.
|
||||
|
||||
**Option 2:** IDF Component Manager
|
||||
|
||||
LVGL is also distributed through `IDF Component Manager <https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-guides/tools/idf-component-manager.html>`__.
|
||||
It allows users to seamlessly integrate `LVGL component <https://components.espressif.com/component/lvgl/lvgl>`__ into
|
||||
their project with following command:
|
||||
|
||||
.. code:: sh
|
||||
|
||||
idf.py add-dependency lvgl/lvgl>=8.*
|
||||
|
||||
During next project build, LVGL component will be fetched from the
|
||||
component registry and added to project build.
|
||||
|
||||
|
||||
Configuration
|
||||
~~~~~~~~~~~~~
|
||||
|
||||
When you are ready to configure LVGL, launch the configuration menu with
|
||||
``idf.py menuconfig`` in your project root directory, go to
|
||||
``Component config`` and then ``LVGL configuration``.
|
||||
|
||||
|
||||
Using lvgl_esp32_drivers in ESP-IDF project
|
||||
-------------------------------------------
|
||||
|
||||
You can also add ``lvgl_esp32_drivers`` as a “component”. This component
|
||||
should be located inside a directory named “components” in your project
|
||||
root directory.
|
||||
|
||||
When your project is a git repository you can include
|
||||
``lvgl_esp32_drivers`` as a git submodule:
|
||||
|
||||
.. code:: sh
|
||||
|
||||
git submodule add https://github.com/lvgl/lvgl_esp32_drivers.git components/lvgl_esp32_drivers
|
||||
@@ -1,17 +0,0 @@
|
||||
# Platforms
|
||||
|
||||
```eval_rst
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 2
|
||||
|
||||
pc-simulator
|
||||
nxp
|
||||
stm32
|
||||
espressif
|
||||
arduino
|
||||
tasmota-berry
|
||||
cmake
|
||||
mdk
|
||||
```
|
||||
|
||||
15
docs/get-started/platforms/index.rst
Normal file
15
docs/get-started/platforms/index.rst
Normal file
@@ -0,0 +1,15 @@
|
||||
=========
|
||||
Platforms
|
||||
=========
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 2
|
||||
|
||||
pc-simulator
|
||||
nxp
|
||||
stm32
|
||||
espressif
|
||||
arduino
|
||||
tasmota-berry
|
||||
cmake
|
||||
mdk
|
||||
@@ -1,4 +0,0 @@
|
||||
|
||||
# MDK
|
||||
|
||||
TODO
|
||||
5
docs/get-started/platforms/mdk.rst
Normal file
5
docs/get-started/platforms/mdk.rst
Normal file
@@ -0,0 +1,5 @@
|
||||
===
|
||||
MDK
|
||||
===
|
||||
|
||||
TODO
|
||||
@@ -1,178 +0,0 @@
|
||||
# NXP
|
||||
NXP has integrated LVGL into the MCUXpresso SDK packages for general purpose and crossover microcontrollers, allowing
|
||||
easy evaluation and migration into your product design.
|
||||
[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.
|
||||
|
||||
## Creating new project with LVGL
|
||||
Downloading the MCU SDK example project is recommended as a starting point. 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
|
||||
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 callbacks are available in "src/draw/nxp/pxp/lv_draw_pxp.c":
|
||||
```c
|
||||
pxp_draw_ctx->base_draw.draw_img_decoded = lv_draw_pxp_img_decoded;
|
||||
pxp_draw_ctx->blend = lv_draw_pxp_blend;
|
||||
pxp_draw_ctx->base_draw.wait_for_finish = lv_draw_pxp_wait_for_finish;
|
||||
```
|
||||
|
||||
#### Features supported:
|
||||
All operations can be used in conjunction with optional transparency.
|
||||
|
||||
- RGB565 and ARGB8888 color formats
|
||||
- Area fill with color
|
||||
- BLIT (BLock Image Transfer)
|
||||
- Screen Rotation (90, 180, 270 degree)
|
||||
- Color keying
|
||||
- Recoloring (color tint)
|
||||
- Image Rotation (90, 180, 270 degree)
|
||||
- RTOS integration layer
|
||||
- Default FreeRTOS and bare metal code provided
|
||||
|
||||
- Combination of recolor and/or rotation + color key/alpha blend/transparency is supported.
|
||||
That is achieved by PXP in two steps:
|
||||
- First step is to recolor/rotate the image to a temporary buffer (statically allocated)
|
||||
- Second step is required to handle color keying, alpha channel or to apply transparency
|
||||
|
||||
#### Known limitations:
|
||||
- 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.
|
||||
|
||||
#### Basic configuration:
|
||||
- Select NXP PXP engine in lv_conf.h: Set `LV_USE_GPU_NXP_PXP` to 1
|
||||
- Enable default implementation for interrupt handling, PXP start function and automatic initialization:
|
||||
Set `LV_USE_GPU_NXP_PXP_AUTO_INIT` to 1
|
||||
- If `SDK_OS_FREE_RTOS` symbol is defined, FreeRTOS implementation will be used, otherwise bare metal code will be
|
||||
included
|
||||
|
||||
#### Basic initialization:
|
||||
- If `LV_USE_GPU_NXP_PXP_AUTO_INIT` is enabled, no user code is required; PXP is initialized automatically in
|
||||
`lv_init()`
|
||||
- For manual PXP initialization, default configuration structure for callbacks can be used. Initialize PXP before
|
||||
calling `lv_init()`
|
||||
```c
|
||||
#if LV_USE_GPU_NXP_PXP
|
||||
#include "src/draw/nxp/pxp/lv_gpu_nxp_pxp.h"
|
||||
#endif
|
||||
. . .
|
||||
#if LV_USE_GPU_NXP_PXP
|
||||
PXP_COND_STOP(!lv_gpu_nxp_pxp_init(), "PXP init failed.");
|
||||
#endif
|
||||
```
|
||||
|
||||
#### Project setup:
|
||||
- Add PXP related files to project:
|
||||
- src/draw/nxp/pxp/lv_draw_pxp.c[.h]: draw context callbacks
|
||||
- src/draw/nxp/pxp/lv_draw_pxp_blend.c[.h]: fill and blit (with optional transformation)
|
||||
- src/draw/nxp/pxp/lv_gpu_nxp_pxp.c[.h]: init, uninit, run/wait PXP device
|
||||
- src/draw/nxp/pxp/lv_gpu_nxp_pxp_osa.c[.h]: OS abstraction (FreeRTOS or bare metal)
|
||||
- optional, required only if `LV_USE_GPU_NXP_PXP_AUTO_INIT` is set to 1
|
||||
- PXP related code depends on two drivers provided by MCU SDK. These drivers need to be added to project:
|
||||
- fsl_pxp.c[.h]: PXP driver
|
||||
- fsl_cache.c[.h]: CPU cache handling functions
|
||||
|
||||
#### Logging:
|
||||
- By default, `LV_GPU_NXP_PXP_LOG_ERRORS` is enabled so that any PXP error will be seen on SDK debug console
|
||||
- By default, `LV_GPU_NXP_PXP_LOG_TRACES` is disabled. Enable it for tracing logs (like PXP limitations)
|
||||
|
||||
#### Advanced configuration:
|
||||
- Implementation depends on multiple OS-specific functions. The struct `lv_nxp_pxp_cfg_t` with callback pointers is
|
||||
used as a parameter for the `lv_gpu_nxp_pxp_init()` function. Default implementation for FreeRTOS and bare metal is
|
||||
provided in lv_gpu_nxp_pxp_osa.c
|
||||
- `pxp_interrupt_init()`: Initialize PXP interrupt (HW setup, OS setup)
|
||||
- `pxp_interrupt_deinit()`: Deinitialize PXP interrupt (HW setup, OS setup)
|
||||
- `pxp_run()`: Start PXP job. Use OS-specific mechanism to block drawing thread. PXP must finish drawing before
|
||||
leaving this function.
|
||||
- Area threshold (size limit) is configurable and used to decide whether the area will be processed by PXP or not.
|
||||
Areas smaller than the defined value will be processed by CPU and those bigger than the threshold will be processed by
|
||||
PXP. The threshold is defined as a macro in lv_draw_pxp.c
|
||||
- `LV_GPU_NXP_PXP_SIZE_LIMIT`: size threshold for fill/blit (with optional transformation)
|
||||
|
||||
### 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.
|
||||
|
||||
Supported draw callbacks are available in "src/draw/nxp/vglite/lv_draw_vglite.c":
|
||||
```c
|
||||
vglite_draw_ctx->base_draw.init_buf = lv_draw_vglite_init_buf;
|
||||
vglite_draw_ctx->base_draw.draw_line = lv_draw_vglite_line;
|
||||
vglite_draw_ctx->base_draw.draw_arc = lv_draw_vglite_arc;
|
||||
vglite_draw_ctx->base_draw.draw_rect = lv_draw_vglite_rect;
|
||||
vglite_draw_ctx->base_draw.draw_img_decoded = lv_draw_vglite_img_decoded;
|
||||
vglite_draw_ctx->blend = lv_draw_vglite_blend;
|
||||
vglite_draw_ctx->base_draw.wait_for_finish = lv_draw_vglite_wait_for_finish;
|
||||
```
|
||||
|
||||
#### Features supported:
|
||||
All operations can be used in conjunction with optional transparency.
|
||||
|
||||
- RGB565 and ARGB8888 color formats
|
||||
- Area fill with color
|
||||
- BLIT (BLock Image Transfer)
|
||||
- Image Rotation (any degree with decimal)
|
||||
- Image Scale
|
||||
- Draw rectangle background with optional radius or gradient
|
||||
- Blit rectangle background image
|
||||
- Draw rectangle border/outline with optional rounded corners
|
||||
- Draw arc with optional rounded ending
|
||||
- Draw line or dashed line with optional rounded ending
|
||||
|
||||
#### 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 (`VG_LITE_LINEAR`).
|
||||
|
||||
#### Basic configuration:
|
||||
- Select NXP VGLite engine in lv_conf.h: Set `LV_USE_GPU_NXP_VG_LITE` to 1
|
||||
- `SDK_OS_FREE_RTOS` symbol needs to be defined so that the FreeRTOS implementation will be used
|
||||
|
||||
#### Basic initialization:
|
||||
- Initialize VGLite before calling `lv_init()` by specifying the width/height of tessellation window. Value should be
|
||||
a multiple of 16; minimum value is 16 pixels, maximum cannot be greater than the frame width. If less than or equal
|
||||
to 0, then no tessellation buffer is created, in which case VGLite is initialized only for blitting.
|
||||
```c
|
||||
#if LV_USE_GPU_NXP_VG_LITE
|
||||
#include "vg_lite.h"
|
||||
#endif
|
||||
. . .
|
||||
#if LV_USE_GPU_NXP_VG_LITE
|
||||
VG_LITE_COND_STOP(vg_lite_init(64, 64) != VG_LITE_SUCCESS, "VGLite init failed.");
|
||||
#endif
|
||||
```
|
||||
|
||||
#### Project setup:
|
||||
- Add VGLite related files to project:
|
||||
- src/draw/nxp/vglite/lv_draw_vglite.c[.h]: draw context callbacks
|
||||
- src/draw/nxp/vglite/lv_draw_vglite_blend.c[.h]: fill and blit (with optional transformation)
|
||||
- src/draw/nxp/vglite/lv_draw_vglite_rect.c[.h]: draw rectangle
|
||||
- src/draw/nxp/vglite/lv_draw_vglite_arc.c[.h]: draw arc
|
||||
- src/draw/nxp/vglite/lv_draw_vglite_line.c[.h]: draw line
|
||||
- src/draw/nxp/vglite/lv_vglite_buf.c[.h]: init/get vglite buffer
|
||||
- src/draw/nxp/vglite/lv_vglite_utils.c[.h]: function helpers
|
||||
|
||||
#### Logging:
|
||||
- By default, `LV_GPU_NXP_VG_LITE_LOG_ERRORS` is enabled so that any VGLite error will be seen on SDK debug console
|
||||
- By default, `LV_GPU_NXP_VG_LITE_LOG_TRACES` is disabled. Enable it for tracing logs (like blit split workaround or
|
||||
VGLite fallback to CPU due to any error on the driver)
|
||||
|
||||
#### Advanced configuration:
|
||||
- Area threshold (size limit) is configurable and used to decide whether the area will be processed by VGLite or not.
|
||||
Areas smaller than the defined value will be processed by CPU and those bigger than the threshold will be processed by
|
||||
VGLite. The threshold is defined as a macro in lv_draw_vglite.c
|
||||
- `LV_GPU_NXP_VG_LITE_SIZE_LIMIT`: size threshold for fill/blit (with optional transformation)
|
||||
278
docs/get-started/platforms/nxp.rst
Normal file
278
docs/get-started/platforms/nxp.rst
Normal file
@@ -0,0 +1,278 @@
|
||||
===
|
||||
NXP
|
||||
===
|
||||
|
||||
NXP has integrated LVGL into the MCUXpresso SDK packages for general
|
||||
purpose and crossover microcontrollers, allowing easy evaluation and
|
||||
migration into your product design.
|
||||
`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.
|
||||
|
||||
|
||||
Creating new project with LVGL
|
||||
------------------------------
|
||||
|
||||
Downloading the MCU SDK example project is recommended as a starting
|
||||
point. 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
|
||||
~~~~~~~~~~~~~~~
|
||||
|
||||
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 callbacks are available in "src/draw/nxp/pxp/lv_draw_pxp.c":
|
||||
|
||||
.. code:: c
|
||||
|
||||
pxp_draw_ctx->base_draw.draw_img_decoded = lv_draw_pxp_img_decoded;
|
||||
pxp_draw_ctx->blend = lv_draw_pxp_blend;
|
||||
pxp_draw_ctx->base_draw.wait_for_finish = lv_draw_pxp_wait_for_finish;
|
||||
|
||||
|
||||
Features supported:
|
||||
^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
All operations can be used in conjunction with optional transparency.
|
||||
|
||||
- RGB565 and ARGB8888 color formats
|
||||
- Area fill with color
|
||||
- BLIT (BLock Image Transfer)
|
||||
- Screen Rotation (90, 180, 270 degree)
|
||||
- Color keying
|
||||
- Recoloring (color tint)
|
||||
- Image Rotation (90, 180, 270 degree)
|
||||
- RTOS integration layer
|
||||
- Default FreeRTOS and bare metal code provided
|
||||
- Combination of recolor and/or rotation + color key/alpha
|
||||
blend/transparency is supported. That is achieved by PXP in two
|
||||
steps:
|
||||
|
||||
- First step is to recolor/rotate the image to a temporary buffer (statically allocated)
|
||||
- Second step is required to handle color keying, alpha channel or to apply transparency
|
||||
|
||||
|
||||
Known limitations:
|
||||
^^^^^^^^^^^^^^^^^^
|
||||
|
||||
- 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.
|
||||
|
||||
|
||||
Basic configuration:
|
||||
^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
- Select NXP PXP engine in lv_conf.h: Set :c:macro:`LV_USE_GPU_NXP_PXP` to ``1``
|
||||
- Enable default implementation for interrupt handling, PXP start
|
||||
function and automatic initialization: Set
|
||||
:c:macro:`LV_USE_GPU_NXP_PXP_AUTO_INIT` to ``1``
|
||||
- If :c:macro:`SDK_OS_FREE_RTOS` symbol is defined, FreeRTOS implementation
|
||||
will be used, otherwise bare metal code will be included
|
||||
|
||||
|
||||
Basic initialization:
|
||||
^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
- If :c:macro:`LV_USE_GPU_NXP_PXP_AUTO_INIT` is enabled, no user code is
|
||||
required; PXP is initialized automatically in :cpp:func:`lv_init`
|
||||
- For manual PXP initialization, default configuration structure for
|
||||
callbacks can be used. Initialize PXP before calling :cpp:func:`lv_init`
|
||||
|
||||
.. code:: c
|
||||
|
||||
#if LV_USE_GPU_NXP_PXP
|
||||
#include "src/draw/nxp/pxp/lv_gpu_nxp_pxp.h"
|
||||
#endif
|
||||
...
|
||||
#if LV_USE_GPU_NXP_PXP
|
||||
PXP_COND_STOP(!lv_gpu_nxp_pxp_init(), "PXP init failed.");
|
||||
#endif
|
||||
|
||||
|
||||
Project setup:
|
||||
^^^^^^^^^^^^^^
|
||||
|
||||
- Add PXP related files to project:
|
||||
|
||||
- src/draw/nxp/pxp/lv_draw_pxp.c[.h]: draw context callbacks
|
||||
- src/draw/nxp/pxp/lv_draw_pxp_blend.c[.h]: fill and blit (with optional transformation)
|
||||
- src/draw/nxp/pxp/lv_gpu_nxp_pxp.c[.h]: init, uninit, run/wait PXP device
|
||||
- src/draw/nxp/pxp/lv_gpu_nxp_pxp_osa.c[.h]: OS abstraction (FreeRTOS or bare metal)
|
||||
|
||||
- optional, required only if :c:macro:`LV_USE_GPU_NXP_PXP_AUTO_INIT` is set to ``1``
|
||||
|
||||
- PXP related code depends on two drivers provided by MCU SDK. These
|
||||
drivers need to be added to project:
|
||||
|
||||
- fsl_pxp.c[.h]: PXP driver
|
||||
- fsl_cache.c[.h]: CPU cache handling functions
|
||||
|
||||
|
||||
Logging:
|
||||
^^^^^^^^
|
||||
|
||||
- By default, :c:macro:`LV_GPU_NXP_PXP_LOG_ERRORS` is enabled so that any PXP error will be seen on SDK debug console
|
||||
- By default, :c:macro:`LV_GPU_NXP_PXP_LOG_TRACES` is disabled. Enable it for tracing logs (like PXP limitations)
|
||||
|
||||
|
||||
Advanced configuration:
|
||||
^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
- Implementation depends on multiple OS-specific functions. The struct
|
||||
:cpp:struct:`lv_nxp_pxp_cfg_t` with callback pointers is used as a parameter
|
||||
for the :cpp:func:`lv_gpu_nxp_pxp_init` function. Default implementation
|
||||
for FreeRTOS and bare metal is provided in lv_gpu_nxp_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.
|
||||
PXP must finish drawing before leaving this function.
|
||||
|
||||
- Area threshold (size limit) is configurable and used to decide
|
||||
whether the area will be processed by PXP or not. Areas smaller than
|
||||
the defined value will be processed by CPU and those bigger than the
|
||||
threshold will be processed by PXP. The threshold is defined as a
|
||||
macro in lv_draw_pxp.c
|
||||
|
||||
- :c:macro:`LV_GPU_NXP_PXP_SIZE_LIMIT`: size threshold for fill/blit (with optional transformation)
|
||||
|
||||
|
||||
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.
|
||||
|
||||
Supported draw callbacks are available in "src/draw/nxp/vglite/lv_draw_vglite.c":
|
||||
|
||||
.. code:: c
|
||||
|
||||
vglite_draw_ctx->base_draw.init_buf = lv_draw_vglite_init_buf;
|
||||
vglite_draw_ctx->base_draw.draw_line = lv_draw_vglite_line;
|
||||
vglite_draw_ctx->base_draw.draw_arc = lv_draw_vglite_arc;
|
||||
vglite_draw_ctx->base_draw.draw_rect = lv_draw_vglite_rect;
|
||||
vglite_draw_ctx->base_draw.draw_img_decoded = lv_draw_vglite_img_decoded;
|
||||
vglite_draw_ctx->blend = lv_draw_vglite_blend;
|
||||
vglite_draw_ctx->base_draw.wait_for_finish = lv_draw_vglite_wait_for_finish;
|
||||
|
||||
.. _features-supported-1:
|
||||
|
||||
|
||||
Features supported:
|
||||
^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
All operations can be used in conjunction with optional transparency.
|
||||
|
||||
- RGB565 and ARGB8888 color formats
|
||||
- Area fill with color
|
||||
- BLIT (BLock Image Transfer)
|
||||
- Image Rotation (any degree with decimal)
|
||||
- Image Scale
|
||||
- Draw rectangle background with optional radius or gradient
|
||||
- Blit rectangle background image
|
||||
- Draw rectangle border/outline with optional rounded corners
|
||||
- Draw arc with optional rounded ending
|
||||
- Draw line or dashed line with optional rounded ending
|
||||
|
||||
.. _known-limitations-1:
|
||||
|
||||
|
||||
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`).
|
||||
|
||||
.. _basic-configuration-1:
|
||||
|
||||
|
||||
Basic configuration:
|
||||
^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
- Select NXP VGLite engine in lv_conf.h: Set :c:macro:`LV_USE_GPU_NXP_VG_LITE` to 1
|
||||
- :c:macro:`SDK_OS_FREE_RTOS` symbol needs to be defined so that the FreeRTOS implementation will be used
|
||||
|
||||
.. _basic-initialization-1:
|
||||
|
||||
Basic initialization:
|
||||
^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
- Initialize VGLite before calling :cpp:func:`lv_init` by specifying the
|
||||
width/height of tessellation window. Value should be a multiple of
|
||||
16; minimum value is 16 pixels, maximum cannot be greater than the
|
||||
frame width. If less than or equal to 0, then no tessellation buffer
|
||||
is created, in which case VGLite is initialized only for blitting.
|
||||
|
||||
.. code:: c
|
||||
|
||||
#if LV_USE_GPU_NXP_VG_LITE
|
||||
#include "vg_lite.h"
|
||||
#endif
|
||||
...
|
||||
#if LV_USE_GPU_NXP_VG_LITE
|
||||
VG_LITE_COND_STOP(vg_lite_init(64, 64) != VG_LITE_SUCCESS, "VGLite init failed.");
|
||||
#endif
|
||||
|
||||
.. _project-setup-1:
|
||||
|
||||
Project setup:
|
||||
^^^^^^^^^^^^^^
|
||||
|
||||
- Add VGLite related files to project:
|
||||
|
||||
- src/draw/nxp/vglite/lv_draw_vglite.c[.h]: draw context callbacks
|
||||
- src/draw/nxp/vglite/lv_draw_vglite_blend.c[.h]: fill and blit (with optional transformation)
|
||||
- src/draw/nxp/vglite/lv_draw_vglite_rect.c[.h]: draw rectangle
|
||||
- src/draw/nxp/vglite/lv_draw_vglite_arc.c[.h]: draw arc
|
||||
- src/draw/nxp/vglite/lv_draw_vglite_line.c[.h]: draw line
|
||||
- src/draw/nxp/vglite/lv_vglite_buf.c[.h]: init/get vglite buffer
|
||||
- src/draw/nxp/vglite/lv_vglite_utils.c[.h]: function helpers
|
||||
|
||||
.. _logging-1:
|
||||
|
||||
Logging:
|
||||
^^^^^^^^
|
||||
|
||||
- By default, :c:macro:`LV_GPU_NXP_VG_LITE_LOG_ERRORS` is enabled so that any VGLite error will be seen on SDK debug console
|
||||
- By default, :c:macro:`LV_GPU_NXP_VG_LITE_LOG_TRACES` is disabled. Enable it
|
||||
for tracing logs (like blit split workaround or VGLite fallback to CPU due to any error on the driver)
|
||||
|
||||
.. _advanced-configuration-1:
|
||||
|
||||
Advanced configuration:
|
||||
^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
- Area threshold (size limit) is configurable and used to decide
|
||||
whether the area will be processed by VGLite or not. Areas smaller
|
||||
than the defined value will be processed by CPU and those bigger than
|
||||
the threshold will be processed by VGLite. The threshold is defined
|
||||
as a macro in lv_draw_vglite.c
|
||||
|
||||
- :c:macro:`LV_GPU_NXP_VG_LITE_SIZE_LIMIT`: size threshold for fill/blit (with optional transformation)
|
||||
@@ -1,100 +0,0 @@
|
||||
# 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. So it's a good idea to reproduce a bug in the simulator and use that code snippet in the [Forum](https://forum.lvgl.io).
|
||||
|
||||
## 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
|
||||
- [CodeBlocks](https://github.com/lvgl/lv_sim_codeblocks_win): Recommended on Windows
|
||||
- [VisualStudio with SDL driver](https://github.com/lvgl/lv_sim_visual_studio_sdl): For Windows
|
||||
- [VSCode with SDL driver](https://github.com/lvgl/lv_sim_vscode_sdl): Recommended on Linux and Mac
|
||||
- [PlatformIO with SDL driver](https://github.com/lvgl/lv_platformio): Recommended on Linux and Mac
|
||||
- [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
|
||||
|
||||
You can use any IDE for development but, for simplicity, the configuration for Eclipse CDT is what we'll focus on in this tutorial.
|
||||
The following section describes the set-up guide of Eclipse CDT in more detail.
|
||||
|
||||
|
||||
|
||||
**Note: If you are on Windows, it's usually better to use the Visual Studio or CodeBlocks projects instead. They work out of the box without requiring extra steps.**
|
||||
|
||||
## Set-up Eclipse CDT
|
||||
|
||||
### Install Eclipse CDT
|
||||
|
||||
[Eclipse CDT](https://eclipse.org/cdt/) is a C/C++ IDE.
|
||||
|
||||
Eclipse is a Java-based tool so be sure **Java Runtime Environment** is installed on your system.
|
||||
|
||||
On Debian-based distros (e.g. Ubuntu): `sudo apt-get install default-jre`
|
||||
|
||||
Note: If you are using other distros, then please install a 'Java Runtime Environment' suitable to your distro.
|
||||
Note: If you are using macOS and get a "Failed to create the Java Virtual Machine" error, uninstall any other Java JDK installs and install Java JDK 8u. This should fix the problem.
|
||||
|
||||
You can download Eclipse's CDT from: [https://www.eclipse.org/cdt/downloads.php](https://www.eclipse.org/cdt/downloads.php). Start the installer and choose *Eclipse CDT* from the list.
|
||||
|
||||
### Install SDL 2
|
||||
|
||||
The PC simulator uses the [SDL 2](https://www.libsdl.org/download-2.0.php) cross-platform library to simulate a TFT display and a touchpad.
|
||||
|
||||
#### Linux
|
||||
On **Linux** you can easily install SDL2 using a terminal:
|
||||
|
||||
1. Find the current version of SDL2: `apt-cache search libsdl2 (e.g. libsdl2-2.0-0)`
|
||||
2. Install SDL2: `sudo apt-get install libsdl2-2.0-0` (replace with the found version)
|
||||
3. Install SDL2 development package: `sudo apt-get install libsdl2-dev`
|
||||
4. If build essentials are not installed yet: `sudo apt-get install build-essential`
|
||||
|
||||
#### Windows
|
||||
If you are using **Windows** firstly you need to install MinGW ([64 bit version](https://www.mingw-w64.org/downloads/#msys2)). After installing MinGW, do the following steps to add SDL2:
|
||||
|
||||
1. Download the development libraries of SDL.
|
||||
Go to [https://www.libsdl.org/download-2.0.php](https://www.libsdl.org/download-2.0.php) and download _Development Libraries: SDL2-devel-2.0.5-mingw.tar.gz_
|
||||
2. Decompress the file and go to _x86_64-w64-mingw32_ directory (for 64 bit MinGW) or to _i686-w64-mingw32_ (for 32 bit MinGW)
|
||||
3. Copy _..._mingw32/include/SDL2_ folder to _C:/MinGW/.../x86_64-w64-mingw32/include_
|
||||
4. Copy _..._mingw32/lib/_ content to _C:/MinGW/.../x86_64-w64-mingw32/lib_
|
||||
5. Copy _..._mingw32/bin/SDL2.dll_ to _{eclipse_workspace}/pc_simulator/Debug/_. Do it later when Eclipse is installed.
|
||||
|
||||
Note: If you are using **Microsoft Visual Studio** instead of Eclipse then you don't have to install MinGW.
|
||||
|
||||
#### OSX
|
||||
On **OSX** you can easily install SDL2 with brew: `brew install sdl2`
|
||||
|
||||
If something is not working, then please refer [this tutorial](http://lazyfoo.net/tutorials/SDL/01_hello_SDL/index.php) to get started with SDL.
|
||||
|
||||
### Pre-configured project
|
||||
|
||||
A pre-configured graphics library project (based on the latest release) is always available to get started easily.
|
||||
You can find the latest one on [GitHub](https://github.com/lvgl/lv_sim_eclipse_sdl).
|
||||
(Please note that, the project is configured for Eclipse CDT).
|
||||
|
||||
### Add the pre-configured project to Eclipse CDT
|
||||
|
||||
Run Eclipse CDT. It will show a dialogue about the **workspace path**. Before accepting the path, check that path and copy (and unzip) the downloaded pre-configured project there. After that, you can accept the workspace path. Of course you can modify this path but in that case copy the project to the corresponding location.
|
||||
|
||||
Close the start-up window and go to **File->Import** and choose **General->Existing project into Workspace**. **Browse the root directory** of the project and click **Finish**
|
||||
|
||||
On **Windows** you have to do two additional things:
|
||||
|
||||
- Copy the **SDL2.dll** into the project's Debug folder
|
||||
- Right-click on the project -> Project properties -> C/C++ Build -> Settings -> Libraries -> Add ... and add _mingw32_ above SDLmain and SDL. (The order is important: mingw32, SDLmain, SDL)
|
||||
|
||||
### Compile and Run
|
||||
|
||||
Now you are ready to run LVGL on your PC. Click on the Hammer Icon on the top menu bar to Build the project. If you have done everything right, then you will not get any errors. Note that on some systems additional steps might be required to "see" SDL 2 from Eclipse but in most cases the configuration in the downloaded project is enough.
|
||||
|
||||
After a successful build, click on the Play button on the top menu bar to run the project. Now a window should appear in the middle of your screen.
|
||||
|
||||
Now you are ready to use LVGL and begin development on your PC.
|
||||
152
docs/get-started/platforms/pc-simulator.rst
Normal file
152
docs/get-started/platforms/pc-simulator.rst
Normal file
@@ -0,0 +1,152 @@
|
||||
.. _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. So it's a good idea to
|
||||
reproduce a bug in the simulator and use that code snippet in the
|
||||
`Forum <https://forum.lvgl.io>`__.
|
||||
|
||||
|
||||
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 SDLdriver <https://github.com/lvgl/lv_sim_eclipse_sdl>`__: Recommended on Linux and Mac
|
||||
- `CodeBlocks <https://github.com/lvgl/lv_sim_codeblocks_win>`__: Recommended on Windows
|
||||
- `VisualStudio with SDL driver <https://github.com/lvgl/lv_sim_visual_studio_sdl>`__: For Windows
|
||||
- `VSCode with SDL driver <https://github.com/lvgl/lv_sim_vscode_sdl>`__: Recommended on Linux and Mac
|
||||
- `PlatformIO with SDL driver <https://github.com/lvgl/lv_platformio>`__: Recommended on Linux and Mac
|
||||
- `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
|
||||
|
||||
You can use any IDE for development but, for simplicity, the
|
||||
configuration for Eclipse CDT is what we'll focus on in this tutorial.
|
||||
The following section describes the set-up guide of Eclipse CDT in more
|
||||
detail.
|
||||
|
||||
:Note: If you are on Windows, it's usually better to use the Visual
|
||||
Studio or CodeBlocks projects instead. They work out of the box without
|
||||
requiring extra steps.**
|
||||
|
||||
Set-up Eclipse CDT
|
||||
------------------
|
||||
|
||||
Install Eclipse CDT
|
||||
~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
`Eclipse CDT <https://eclipse.org/cdt/>`__ is a C/C++ IDE.
|
||||
|
||||
Eclipse is a Java-based tool so be sure **Java Runtime Environment** is installed on your system.
|
||||
|
||||
On Debian-based distros (e.g. Ubuntu): ``sudo apt-get install default-jre``
|
||||
|
||||
:note: If you are using other distros, then please install a ‘Java
|
||||
Runtime Environment' suitable to your distro. Note: If you are using
|
||||
macOS and get a “Failed to create the Java Virtual Machine” error,
|
||||
uninstall any other Java JDK installs and install Java JDK 8u. This
|
||||
should fix the problem.
|
||||
|
||||
You can download Eclipse's CDT from:
|
||||
https://www.eclipse.org/cdt/downloads.php. Start the installer and
|
||||
choose *Eclipse CDT* from the list.
|
||||
|
||||
Install SDL 2
|
||||
~~~~~~~~~~~~~
|
||||
|
||||
The PC simulator uses the `SDL2 <https://www.libsdl.org/download-2.0.php>`__ cross-platform library to
|
||||
simulate a TFT display and a touchpad.
|
||||
|
||||
Linux
|
||||
^^^^^
|
||||
|
||||
On **Linux** you can easily install SDL2 using a terminal:
|
||||
|
||||
1. Find the current version of SDL2: ``apt-cache search libsdl2 (e.g. libsdl2-2.0-0)``
|
||||
2. Install SDL2: ``sudo apt-get install libsdl2-2.0-0`` (replace with the found version)
|
||||
3. Install SDL2 development package: ``sudo apt-get install libsdl2-dev``
|
||||
4. If build essentials are not installed yet: ``sudo apt-get install build-essential``
|
||||
|
||||
Windows
|
||||
^^^^^^^
|
||||
|
||||
If you are using **Windows** firstly you need to install
|
||||
MinGW (`64 bit version <https://www.mingw-w64.org/downloads/#msys2>`__). After
|
||||
installing MinGW, do the following steps to add SDL2:
|
||||
|
||||
1. Download the development libraries of SDL. Go to
|
||||
https://www.libsdl.org/download-2.0.php and download *Development Libraries: SDL2-devel-2.0.5-mingw.tar.gz*
|
||||
2. Decompress the file and go to *x86_64-w64-mingw32* directory (for 64 bit MinGW) or to *i686-w64-mingw32* (for 32 bit MinGW)
|
||||
3. Copy *mingw32/include/SDL2* folder to *C:/MinGW/…/x86_64-w64-mingw32/include*
|
||||
4. Copy *mingw32/lib/* content to *C:/MinGW/…/x86_64-w64-mingw32/lib*
|
||||
5. Copy *mingw32/bin/SDL2.dll* to *{eclipse_workspace}/pc_simulator/Debug/\_*. Do it later when Eclipse is installed.
|
||||
|
||||
:Note: If you are using **Microsoft Visual Studio** instead of Eclipse
|
||||
then you don't have to install MinGW.
|
||||
|
||||
OSX
|
||||
^^^
|
||||
|
||||
On **OSX** you can easily install SDL2 with brew: ``brew install sdl2``
|
||||
|
||||
If something is not working, then please refer `this tutorial <http://lazyfoo.net/tutorials/SDL/01_hello_SDL/index.php>`__ to
|
||||
get started with SDL.
|
||||
|
||||
Pre-configured project
|
||||
~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
A pre-configured graphics library project (based on the latest release)
|
||||
is always available to get started easily. You can find the latest one
|
||||
on `GitHub <https://github.com/lvgl/lv_sim_eclipse_sdl>`__.
|
||||
(Please note that, the project is configured for Eclipse CDT).
|
||||
|
||||
Add the pre-configured project to Eclipse CDT
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Run Eclipse CDT. It will show a dialogue about the **workspace path**.
|
||||
Before accepting the path, check that path and copy (and unzip) the
|
||||
downloaded pre-configured project there. After that, you can accept the
|
||||
workspace path. Of course you can modify this path but in that case copy
|
||||
the project to the corresponding location.
|
||||
|
||||
Close the start-up window and go to **File->Import** and choose
|
||||
**General->Existing project into Workspace**. **Browse the root
|
||||
directory** of the project and click **Finish**
|
||||
|
||||
On **Windows** you have to do two additional things:
|
||||
|
||||
- Copy the **SDL2.dll** into the project's Debug folder
|
||||
- Right-click on the project -> Project properties -> C/C++ Build ->
|
||||
Settings -> Libraries -> Add … and add *mingw32* above SDLmain and
|
||||
SDL. (The order is important: mingw32, SDLmain, SDL)
|
||||
|
||||
Compile and Run
|
||||
~~~~~~~~~~~~~~~
|
||||
|
||||
Now you are ready to run LVGL on your PC. Click on the Hammer Icon on
|
||||
the top menu bar to Build the project. If you have done everything
|
||||
right, then you will not get any errors. Note that on some systems
|
||||
additional steps might be required to “see” SDL 2 from Eclipse but in
|
||||
most cases the configuration in the downloaded project is enough.
|
||||
|
||||
After a successful build, click on the Play button on the top menu bar
|
||||
to run the project. Now a window should appear in the middle of your
|
||||
screen.
|
||||
|
||||
Now you are ready to use LVGL and begin development on your PC.
|
||||
@@ -1,219 +0,0 @@
|
||||
|
||||
# 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:
|
||||
```
|
||||
//Frame buffers
|
||||
/*A static or global variable to store the buffers*/
|
||||
static lv_disp_draw_buf_t disp_buf;
|
||||
|
||||
/*Static or global buffer(s). The second buffer is optional*/
|
||||
static lv_color_t buf_1[BUFF_SIZE]; //TODO: Chose a buffer size. DISPLAY_WIDTH * 10 is one suggestion.
|
||||
static lv_color_t buf_2[BUFF_SIZE];
|
||||
```
|
||||
* In your ```main()``` function, after initialising your CPU, peripherals, and LCD panel, call ```lv_init();``` to initialise LVGL. You can then register the frame buffers using ```lv_disp_draw_buf_init()```, and create the display driver using ```lv_disp_drv_init()```.
|
||||
```
|
||||
//Initialise LVGL UI library
|
||||
lv_init();
|
||||
lv_disp_draw_buf_init(&disp_buf, buf_1, NULL, BUFF_SIZE);
|
||||
|
||||
static lv_disp_drv_t disp_drv; /*A variable to hold the drivers. Must be static or global.*/
|
||||
lv_disp_drv_init(&disp_drv); /*Basic initialization*/
|
||||
disp_drv.draw_buf = &disp_buf; /*Set an initialized buffer*/
|
||||
disp_drv.flush_cb = my_flush_cb; /*Set a flush callback to draw to the display*/
|
||||
disp_drv.hor_res = WIDTH; /*Set the horizontal resolution in pixels*/
|
||||
disp_drv.ver_res = HEIGHT; /*Set the vertical resolution in pixels*/
|
||||
|
||||
lv_disp_t * disp;
|
||||
disp = lv_disp_drv_register(&disp_drv); /*Register the driver and save the created display objects*/
|
||||
```
|
||||
* Create some dummy objects to test the output:
|
||||
```
|
||||
// Change the active screen's background color
|
||||
lv_obj_set_style_bg_color(lv_scr_act(), lv_color_hex(0x003a57), LV_PART_MAIN);
|
||||
lv_obj_set_style_text_color(lv_scr_act(), lv_color_hex(0xffffff), LV_PART_MAIN);
|
||||
|
||||
/*Create a spinner*/
|
||||
lv_obj_t * spinner = lv_spinner_create(lv_scr_act(), 1000, 60);
|
||||
lv_obj_set_size(spinner, 64, 64);
|
||||
lv_obj_align(spinner, LV_ALIGN_BOTTOM_MID, 0, 0);
|
||||
```
|
||||
* Add a call to ```lv_timer_handler()``` inside your ```while(1)``` loop:
|
||||
```
|
||||
/* Infinite loop */
|
||||
while (1)
|
||||
{
|
||||
lv_timer_handler();
|
||||
HAL_Delay(5);
|
||||
}
|
||||
```
|
||||
* Add a call to ```lv_tick_inc()``` inside the ```SysTick_Handler()``` function. Open the *stm32xxxx_it.c* file (the name will depend on your specific MCU), and update the ```SysTick_Handler()``` function:
|
||||
```
|
||||
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.
|
||||
```
|
||||
void my_flush_cb(lv_disp_drv_t * disp_drv, 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++) {
|
||||
parallel_write(color_p->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_disp_flush_ready(disp_drv);
|
||||
}
|
||||
```
|
||||
|
||||
## FreeRTOS Example
|
||||
A minimal example using STM32CubeIDE, HAL, and CMSISv1 (FreeRTOS). <br />
|
||||
*Note that we have not used Mutexes in this example, however LVGL is **NOT** thread safe and so Mutexes should be used. See: [Operating system and interrupts](https://docs.lvgl.io/master/porting/os.html)*
|
||||
* ```#include "lvgl.h"```
|
||||
* Create your frame buffer(s) as global variables:
|
||||
```
|
||||
//Frame buffers
|
||||
/*A static or global variable to store the buffers*/
|
||||
static lv_disp_draw_buf_t disp_buf;
|
||||
|
||||
/*Static or global buffer(s). The second buffer is optional*/
|
||||
static lv_color_t buf_1[BUFF_SIZE]; //TODO: Declare your own BUFF_SIZE appropriate to your system.
|
||||
static lv_color_t buf_2[BUFF_SIZE];
|
||||
```
|
||||
* In your ```main()``` function, after your peripherals (SPI, GPIOs, LCD etc) have been initialised, initialise LVGL using ```lv_init();```, register the frame buffers using ```lv_disp_draw_buf_init()```, and create a new display driver using ```lv_disp_drv_init()```.
|
||||
```
|
||||
//Initialise LVGL UI library
|
||||
lv_init();
|
||||
lv_disp_draw_buf_init(&disp_buf, buf_1, buf_2, BUFF_SIZE);
|
||||
|
||||
static lv_disp_drv_t disp_drv; /*A variable to hold the drivers. Must be static or global.*/
|
||||
lv_disp_drv_init(&disp_drv); /*Basic initialization*/
|
||||
disp_drv.draw_buf = &disp_buf; /*Set an initialized buffer*/
|
||||
disp_drv.flush_cb = my_flush_cb; /*Set a flush callback to draw to the display*/
|
||||
disp_drv.hor_res = WIDTH; /*Set the horizontal resolution in pixels*/
|
||||
disp_drv.ver_res = HEIGHT; /*Set the vertical resolution in pixels*/
|
||||
|
||||
lv_disp_t * disp;
|
||||
disp = lv_disp_drv_register(&disp_drv); /*Register the driver and save the created display objects*/
|
||||
|
||||
// Register the touch controller with LVGL - Not included here for brevity.
|
||||
```
|
||||
* Create some dummy objects to test the output:
|
||||
```
|
||||
// Change the active screen's background color
|
||||
lv_obj_set_style_bg_color(lv_scr_act(), lv_color_hex(0x003a57), LV_PART_MAIN);
|
||||
lv_obj_set_style_text_color(lv_scr_act(), lv_color_hex(0xffffff), LV_PART_MAIN);
|
||||
|
||||
/*Create a spinner*/
|
||||
lv_obj_t * spinner = lv_spinner_create(lv_scr_act(), 1000, 60);
|
||||
lv_obj_set_size(spinner, 64, 64);
|
||||
lv_obj_align(spinner, LV_ALIGN_BOTTOM_MID, 0, 0);
|
||||
```
|
||||
* Create two threads to call ```lv_timer_handler()```, and ```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:
|
||||
```
|
||||
//Thread Handles
|
||||
osThreadId lvgl_tickHandle;
|
||||
osThreadId lvgl_timerHandle;
|
||||
```
|
||||
```
|
||||
/* definition and creation of lvgl_tick */
|
||||
osThreadDef(lvgl_tick, LGVLTick, 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:
|
||||
```
|
||||
/* LVGL timer for tasks. */
|
||||
void LVGLTimer(void const * argument)
|
||||
{
|
||||
for(;;)
|
||||
{
|
||||
lv_timer_handler();
|
||||
osDelay(20);
|
||||
}
|
||||
}
|
||||
/* LVGL tick source */
|
||||
void LGVLTick(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.
|
||||
```
|
||||
void my_flush_cb(lv_disp_drv_t * disp_drv, 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;
|
||||
|
||||
//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->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_disp_flush_ready(disp_drv);
|
||||
}
|
||||
```
|
||||
277
docs/get-started/platforms/stm32.rst
Normal file
277
docs/get-started/platforms/stm32.rst
Normal file
@@ -0,0 +1,277 @@
|
||||
=====
|
||||
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
|
||||
/*A static or global variable to store the buffers*/
|
||||
static lv_disp_draw_buf_t disp_buf;
|
||||
|
||||
/*Static or global buffer(s). The second buffer is optional*/
|
||||
static lv_color_t buf_1[BUFF_SIZE]; //TODO: Chose a buffer size. DISPLAY_WIDTH * 10 is one suggestion.
|
||||
static lv_color_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 register the frame buffers using
|
||||
:cpp:func:`lv_disp_draw_buf_init`, and create the display driver using
|
||||
:cpp:func:`lv_disp_drv_init`.
|
||||
|
||||
.. code:: c
|
||||
|
||||
//Initialise LVGL UI library
|
||||
lv_init();
|
||||
lv_disp_draw_buf_init(&disp_buf, buf_1, NULL, BUFF_SIZE);
|
||||
|
||||
static lv_disp_drv_t disp_drv; /*A variable to hold the drivers. Must be static or global.*/
|
||||
lv_disp_drv_init(&disp_drv); /*Basic initialization*/
|
||||
disp_drv.draw_buf = &disp_buf; /*Set an initialized buffer*/
|
||||
disp_drv.flush_cb = my_flush_cb; /*Set a flush callback to draw to the display*/
|
||||
disp_drv.hor_res = WIDTH; /*Set the horizontal resolution in pixels*/
|
||||
disp_drv.ver_res = HEIGHT; /*Set the vertical resolution in pixels*/
|
||||
|
||||
lv_disp_t * disp;
|
||||
disp = lv_disp_drv_register(&disp_drv); /*Register the driver and save the created display objects*/
|
||||
|
||||
- Create some dummy objects to test the output:
|
||||
|
||||
.. code:: c
|
||||
|
||||
// Change the active screen's background color
|
||||
lv_obj_set_style_bg_color(lv_scr_act(), lv_color_hex(0x003a57), LV_PART_MAIN);
|
||||
lv_obj_set_style_text_color(lv_scr_act(), lv_color_hex(0xffffff), LV_PART_MAIN);
|
||||
|
||||
/*Create a spinner*/
|
||||
lv_obj_t * spinner = lv_spinner_create(lv_scr_act(), 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_disp_drv_t * disp_drv, 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++) {
|
||||
parallel_write(color_p->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_disp_flush_ready(disp_drv);
|
||||
}
|
||||
|
||||
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
|
||||
/*A static or global variable to store the buffers*/
|
||||
static lv_disp_draw_buf_t disp_buf;
|
||||
|
||||
/*Static or global buffer(s). The second buffer is optional*/
|
||||
static lv_color_t buf_1[BUFF_SIZE]; //TODO: Declare your own BUFF_SIZE appropriate to your system.
|
||||
static lv_color_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`,
|
||||
register the frame buffers using :cpp:func:`lv_disp_draw_buf_init`, and
|
||||
create a new display driver using :cpp:func:`lv_disp_drv_init`.
|
||||
|
||||
.. code:: c
|
||||
|
||||
//Initialise LVGL UI library
|
||||
lv_init();
|
||||
lv_disp_draw_buf_init(&disp_buf, buf_1, buf_2, BUFF_SIZE);
|
||||
|
||||
static lv_disp_drv_t disp_drv; /*A variable to hold the drivers. Must be static or global.*/
|
||||
lv_disp_drv_init(&disp_drv); /*Basic initialization*/
|
||||
disp_drv.draw_buf = &disp_buf; /*Set an initialized buffer*/
|
||||
disp_drv.flush_cb = my_flush_cb; /*Set a flush callback to draw to the display*/
|
||||
disp_drv.hor_res = WIDTH; /*Set the horizontal resolution in pixels*/
|
||||
disp_drv.ver_res = HEIGHT; /*Set the vertical resolution in pixels*/
|
||||
|
||||
lv_disp_t * disp;
|
||||
disp = lv_disp_drv_register(&disp_drv); /*Register the driver and save the created display objects*/
|
||||
|
||||
// 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_scr_act(), lv_color_hex(0x003a57), LV_PART_MAIN);
|
||||
lv_obj_set_style_text_color(lv_scr_act(), lv_color_hex(0xffffff), LV_PART_MAIN);
|
||||
|
||||
/*Create a spinner*/
|
||||
lv_obj_t * spinner = lv_spinner_create(lv_scr_act(), 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, LGVLTick, 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 LGVLTick(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_disp_drv_t * disp_drv, 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;
|
||||
|
||||
//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->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_disp_flush_ready(disp_drv);
|
||||
}
|
||||
@@ -1,73 +0,0 @@
|
||||
# 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
|
||||
|
||||
```python
|
||||
lv.start() # start LVGL
|
||||
scr = lv.scr_act() # 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/)
|
||||
105
docs/get-started/platforms/tasmota-berry.rst
Normal file
105
docs/get-started/platforms/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.scr_act() # 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/>`__
|
||||
@@ -1,266 +0,0 @@
|
||||
|
||||
# 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 [Porting](/porting/index) and [Overview](/overview/index) 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 [Simulators](/get-started/platforms/pc-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.
|
||||
- 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 `LV_COLOR_DEPTH` defines.
|
||||
- Include `lvgl/lvgl.h` in files where you need to use LVGL related functions.
|
||||
- Call `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, configure `LV_TICK_CUSTOM` (see `lv_conf.h`) so that LVGL can retrieve the current time directly.
|
||||
- Call `lv_init()`
|
||||
- Create a draw buffer: LVGL will render the graphics here first, and send the rendered image to the display.
|
||||
The buffer size can be set freely but 1/10 screen size is a good starting point.
|
||||
```c
|
||||
static lv_disp_draw_buf_t draw_buf;
|
||||
static lv_color_t buf1[MY_DISP_HOR_RES * MY_DISP_VER_RES / 10]; /*Declare a buffer for 1/10 screen size*/
|
||||
lv_disp_draw_buf_init(&draw_buf, buf1, NULL, MY_DISP_HOR_RES * MY_DISP_VER_RES / 10); /*Initialize the display buffer.*/
|
||||
```
|
||||
- Implement and register a function which can copy the rendered image to an area of your display:
|
||||
```c
|
||||
static lv_disp_t disp_drv; /*Descriptor of a display driver*/
|
||||
lv_disp_drv_init(&disp_drv); /*Basic initialization*/
|
||||
disp_drv.flush_cb = my_disp_flush; /*Set your driver function*/
|
||||
disp_drv.draw_buf = &draw_buf; /*Assign the buffer to the display*/
|
||||
disp_drv.hor_res = MY_DISP_HOR_RES; /*Set the horizontal resolution of the display*/
|
||||
disp_drv.ver_res = MY_DISP_VER_RES; /*Set the vertical resolution of the display*/
|
||||
lv_disp_drv_register(&disp_drv); /*Finally register the driver*/
|
||||
|
||||
void my_disp_flush(lv_disp_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_disp_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:
|
||||
```c
|
||||
static lv_indev_t indev_drv; /*Descriptor of a input device driver*/
|
||||
lv_indev_drv_init(&indev_drv); /*Basic initialization*/
|
||||
indev_drv.type = LV_INDEV_TYPE_POINTER; /*Touch pad is a pointer-like device*/
|
||||
indev_drv.read_cb = my_touchpad_read; /*Set your driver function*/
|
||||
lv_indev_drv_register(&indev_drv); /*Finally register the driver*/
|
||||
|
||||
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 `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 [Porting](/porting/index) section.
|
||||
|
||||
## Learn the basics
|
||||
|
||||
### Widgets
|
||||
|
||||
The graphical elements like Buttons, Labels, Sliders, Charts etc. are called objects or widgets. Go to [Widgets](/widgets/index) 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 `lv_scr_act()`, and to load a screen use `lv_scr_load(scr1)`.
|
||||
|
||||
You can create a new object with `lv_<type>_create(parent)`. It will return an `lv_obj_t *` variable that can be used as a reference to the object to set its parameters.
|
||||
|
||||
For example:
|
||||
```c
|
||||
lv_obj_t * slider1 = lv_slider_create(lv_scr_act());
|
||||
```
|
||||
|
||||
To set some basic attributes `lv_obj_set_<parameter_name>(obj, <value>)` functions can be used. For example:
|
||||
```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:
|
||||
```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)).
|
||||
|
||||
|
||||
|
||||
### 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:
|
||||
|
||||
```c
|
||||
lv_obj_add_event(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");
|
||||
}
|
||||
```
|
||||
|
||||
`LV_EVENT_ALL` can be used instead of `LV_EVENT_CLICKED` to invoke the callback for any event.
|
||||
|
||||
From `lv_event_t * e` the current event code can be retrieved with:
|
||||
```c
|
||||
lv_event_code_t code = lv_event_get_code(e);
|
||||
```
|
||||
|
||||
The object that triggered the event can be retrieved with:
|
||||
```c
|
||||
lv_obj_t * obj = lv_event_get_target(e);
|
||||
```
|
||||
|
||||
To learn all features of the events go to the [Event overview](/overview/event) section.
|
||||
|
||||
### Parts
|
||||
Widgets might be built from one or more *parts*. For example, a button has only one part called `LV_PART_MAIN`.
|
||||
However, a [Slider](/widgets/slider) has `LV_PART_MAIN`, `LV_PART_INDICATOR` and `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.
|
||||
|
||||
### States
|
||||
LVGL objects can be in a combination of the following states:
|
||||
- `LV_STATE_DEFAULT` Normal, released state
|
||||
- `LV_STATE_CHECKED` Toggled or checked state
|
||||
- `LV_STATE_FOCUSED` Focused via keypad or encoder or clicked via touchpad/mouse
|
||||
- `LV_STATE_FOCUS_KEY` Focused via keypad or encoder but not via touchpad/mouse
|
||||
- `LV_STATE_EDITED` Edit by an encoder
|
||||
- `LV_STATE_HOVERED` Hovered by mouse (not supported now)
|
||||
- `LV_STATE_PRESSED` Being pressed
|
||||
- `LV_STATE_SCROLLED` Being scrolled
|
||||
- `LV_STATE_DISABLED` Disabled
|
||||
|
||||
For example, if you press an object it will automatically go to the `LV_STATE_FOCUSED` and `LV_STATE_PRESSED` states and when you release it the `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:
|
||||
```c
|
||||
lv_obj_add_state(obj, LV_STATE_...);
|
||||
lv_obj_clear_state(obj, LV_STATE_...);
|
||||
```
|
||||
|
||||
### Styles
|
||||
A style instance contains properties such as background color, border width, font, etc. that describe the appearance of objects.
|
||||
|
||||
Styles are represented with `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 `lv_style_init(&style1)`. After that, properties can be added to configure the style. For example:
|
||||
```
|
||||
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](/overview/style.html#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:
|
||||
```c
|
||||
lv_obj_add_style(slider1, &style1, LV_PART_INDICATOR | LV_STATE_PRESSED);
|
||||
```
|
||||
|
||||
If the *part* is `LV_PART_MAIN` it can be omitted:
|
||||
```c
|
||||
lv_obj_add_style(btn1, &style1, LV_STATE_PRESSED); /*Equal to LV_PART_MAIN | LV_STATE_PRESSED*/
|
||||
```
|
||||
|
||||
Similarly, `LV_STATE_DEFAULT` can be omitted too:
|
||||
```c
|
||||
lv_obj_add_style(slider1, &style1, LV_PART_INDICATOR); /*Equal to LV_PART_INDICATOR | LV_STATE_DEFAULT*/
|
||||
```
|
||||
|
||||
For `LV_STATE_DEFAULT` and `LV_PART_MAIN` simply write `0`:
|
||||
```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:
|
||||
```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 `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:
|
||||
```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 [Style overview](/overview/style) section.
|
||||
|
||||
|
||||
### 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`.
|
||||
|
||||
## Examples
|
||||
|
||||
```eval_rst
|
||||
|
||||
.. include:: ../../examples/get_started/index.rst
|
||||
```
|
||||
|
||||
## Micropython
|
||||
Learn more about [Micropython](/get-started/bindings/micropython).
|
||||
```python
|
||||
# Create a Button and a Label
|
||||
scr = lv.obj()
|
||||
btn = lv.btn(scr)
|
||||
btn.align(lv.scr_act(), lv.ALIGN.CENTER, 0, 0)
|
||||
label = lv.label(btn)
|
||||
label.set_text("Button")
|
||||
|
||||
# Load the screen
|
||||
lv.scr_load(scr)
|
||||
```
|
||||
|
||||
350
docs/get-started/quick-overview.rst
Normal file
350
docs/get-started/quick-overview.rst
Normal file
@@ -0,0 +1,350 @@
|
||||
.. _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.
|
||||
- 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: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, configure :c:macro:`LV_TICK_CUSTOM` (see
|
||||
``lv_conf.h``) so that LVGL can retrieve the current time directly.
|
||||
- Call :cpp:func:`lv_init`
|
||||
- Create a draw buffer: LVGL will render the graphics here first, and
|
||||
send the rendered image to the display. The buffer size can be set
|
||||
freely but 1/10 screen size is a good starting point.
|
||||
|
||||
.. code:: c
|
||||
|
||||
static lv_disp_draw_buf_t draw_buf;
|
||||
static lv_color_t buf1[MY_DISP_HOR_RES * MY_DISP_VER_RES / 10]; /*Declare a buffer for 1/10 screen size*/
|
||||
lv_disp_draw_buf_init(&draw_buf, buf1, NULL, MY_DISP_HOR_RES * MY_DISP_VER_RES / 10); /*Initialize the display buffer.*/
|
||||
|
||||
- Implement and register a function which can copy the rendered image
|
||||
to an area of your display:
|
||||
|
||||
.. code:: c
|
||||
|
||||
static lv_disp_t disp_drv; /*Descriptor of a display driver*/
|
||||
lv_disp_drv_init(&disp_drv); /*Basic initialization*/
|
||||
disp_drv.flush_cb = my_disp_flush; /*Set your driver function*/
|
||||
disp_drv.draw_buf = &draw_buf; /*Assign the buffer to the display*/
|
||||
disp_drv.hor_res = MY_DISP_HOR_RES; /*Set the horizontal resolution of the display*/
|
||||
disp_drv.ver_res = MY_DISP_VER_RES; /*Set the vertical resolution of the display*/
|
||||
lv_disp_drv_register(&disp_drv); /*Finally register the driver*/
|
||||
|
||||
void my_disp_flush(lv_disp_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_disp_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
|
||||
|
||||
static lv_indev_t indev_drv; /*Descriptor of a input device driver*/
|
||||
lv_indev_drv_init(&indev_drv); /*Basic initialization*/
|
||||
indev_drv.type = LV_INDEV_TYPE_POINTER; /*Touch pad is a pointer-like device*/
|
||||
indev_drv.read_cb = my_touchpad_read; /*Set your driver function*/
|
||||
lv_indev_drv_register(&indev_drv); /*Finally register the driver*/
|
||||
|
||||
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
|
||||
----------------
|
||||
|
||||
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_scr_act`, and to load a screen
|
||||
use :cpp:expr:`lv_scr_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_scr_act());
|
||||
|
||||
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>`__).
|
||||
|
||||
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(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.
|
||||
|
||||
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:`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.
|
||||
|
||||
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 (not supported now)
|
||||
- :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_clear_state(obj, LV_STATE_...);
|
||||
|
||||
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:`style_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.
|
||||
|
||||
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``.
|
||||
|
||||
Examples
|
||||
--------
|
||||
|
||||
.. include:: ../examples/get_started/index.rst
|
||||
|
||||
Micropython
|
||||
-----------
|
||||
|
||||
Learn more about :ref:`micropython`.
|
||||
|
||||
.. code:: python
|
||||
|
||||
import lvgl as lv
|
||||
|
||||
# Create a Button and a Label
|
||||
scr = lv.obj()
|
||||
btn = lv.btn(scr)
|
||||
btn.align(lv.scr_act(), lv.ALIGN.CENTER, 0, 0)
|
||||
label = lv.label(btn)
|
||||
label.set_text("Button")
|
||||
|
||||
# Load the screen
|
||||
lv.scr_load(scr)
|
||||
@@ -1,38 +1,32 @@
|
||||
=====================================
|
||||
Welcome to the documentation of LVGL!
|
||||
=====================================
|
||||
|
||||
```eval_rst
|
||||
.. raw:: html
|
||||
|
||||
PDF version: :download:`LVGL.pdf <LVGL.pdf>`
|
||||
```
|
||||
|
||||
# Welcome to the documentation of LVGL!
|
||||
|
||||
<img src="_static/img/home_banner.jpg" style="width:100%">
|
||||
|
||||
|
||||
<div style="margin-bottom:48px">
|
||||
<a href="intro/index.html"><img class="home-img" src="_static/img/home_1.png" alt="Get familiar with the LVGL project"></a>
|
||||
<a href="get-started/index.html"><img class="home-img" src="_static/img/home_2.png" alt="Learn the basic of LVGL and its usage on various platforms"></a>
|
||||
<a href="porting/index.html"><img class="home-img" src="_static/img/home_3.png" alt="See how to port LVGL to any platform"></a>
|
||||
<a href="overview/index.html"><img class="home-img" src="_static/img/home_4.png" alt="Learn the how LVGL works in more detail"></a>
|
||||
<a href="widgets/index.html"><img class="home-img" src="_static/img/home_5.png" alt="Take a look at the description of the available widgets"></a>
|
||||
<a href="CONTRIBUTING.html"><img class="home-img" src="_static/img/home_6.png" alt="Be part of the development of LVGL"></a>
|
||||
</div>
|
||||
|
||||
|
||||
```eval_rst
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 2
|
||||
:maxdepth: 6
|
||||
|
||||
intro/index
|
||||
examples
|
||||
get-started/index
|
||||
porting/index
|
||||
overview/index
|
||||
widgets/index
|
||||
layouts/index
|
||||
libs/index
|
||||
others/index
|
||||
CONTRIBUTING
|
||||
CHANGELOG
|
||||
ROADMAP
|
||||
```
|
||||
intro/index
|
||||
examples
|
||||
get-started/index
|
||||
porting/index
|
||||
overview/index
|
||||
widgets/index
|
||||
layouts/index
|
||||
libs/index
|
||||
others/index
|
||||
API/index
|
||||
CONTRIBUTING
|
||||
CODING_STYLE
|
||||
CHANGELOG
|
||||
ROADMAP
|
||||
@@ -1,213 +0,0 @@
|
||||
|
||||
# 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
|
||||
Basically, every modern controller which is able to drive a display is suitable to run LVGL. The minimal requirements are:
|
||||
<ul>
|
||||
<li> 16, 32 or 64 bit microcontroller or processor</li>
|
||||
<li>> 16 MHz clock speed is recommended</li>
|
||||
<li> Flash/ROM: > 64 kB for the very essential components (> 180 kB is recommended)</li>
|
||||
<li> RAM:
|
||||
<ul>
|
||||
<li> Static RAM usage: ~2 kB depending on the used features and object types</li>
|
||||
<li> Stack: > 2kB (> 8 kB is recommended)</li>
|
||||
<li> Dynamic data (heap): > 4 KB (> 48 kB is recommended if using several objects).
|
||||
Set by <em>LV_MEM_SIZE</em> in <em>lv_conf.h</em>. </li>
|
||||
<li> Display buffer: > <em>"Horizontal resolution"</em> pixels (> 10 × <em>"Horizontal resolution"</em> is recommended) </li>
|
||||
<li> One frame buffer in the MCU or in an external display controller</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li> C99 or newer compiler</li>
|
||||
<li> Basic C (or C++) knowledge:
|
||||
<a href="https://www.tutorialspoint.com/cprogramming/c_pointers.htm">pointers</a>,
|
||||
<a href="https://www.tutorialspoint.com/cprogramming/c_structures.htm">structs</a>,
|
||||
<a href="https://www.geeksforgeeks.org/callbacks-in-c/">callbacks</a>.</li>
|
||||
</ul>
|
||||
<em>Note that memory usage may vary depending on architecture, compiler and build options.</em>
|
||||
|
||||
## 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 [contributing](/CONTRIBUTING) to the project.
|
||||
You can choose from [many different ways of contributing](/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 versions for incompatible API changes. E.g. v5.0.0, v6.0.0
|
||||
- Minor version for new but backward-compatible functionalities. E.g. v6.1.0, v6.2.0
|
||||
- Patch version for 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 [CHANGELOG.md](/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 | Feb 1, 2019 | Feb 1, 2020 | No |
|
||||
| v6.1 | Nov 26, 2019 | Nov 26, 2020 | No |
|
||||
| v7.11 | Mar 16, 2021 | Mar 16, 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 | Yes |
|
||||
| v8.3 | 6 July, 2022 | 6 July, 2023 | Yes |
|
||||
| v9.0 | In progress | | |
|
||||
|
||||
## 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 [Requirements](#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 [Porting](/porting/display) section to learn more.
|
||||
|
||||
### LVGL doesn't start, randomly crashes or nothing is drawn on the display. What can be the problem?
|
||||
- Try increasing `LV_MEM_SIZE`.
|
||||
- Be sure `lv_disp_t`, `lv_indev_t` and `lv_fs_drv_t` are global or `static`.
|
||||
- Be sure your display works without LVGL. E.g. paint it to red on start up.
|
||||
- Enable [Logging](porting/log)
|
||||
- Enable asserts in `lv_conf.h` (`LV_USE_ASSERT_...`)
|
||||
- If you use an RTOS
|
||||
- increase the stack size of the task which calls `lv_timer_handler()`
|
||||
- Be sure you used a mutex as [described here](/porting/os)
|
||||
|
||||
### My display driver is not called. What have I missed?
|
||||
Be sure you are calling `lv_tick_inc(x)` in an interrupt and `lv_timer_handler()` in your main `while(1)`.
|
||||
|
||||
Learn more in the [Tick](/porting/tick) and [Timer handler](/porting/timer-handler) sections.
|
||||
|
||||
### Why is the display driver called only once? Only the upper part of the display is refreshed.
|
||||
Be sure you are calling `lv_disp_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.
|
||||
|
||||
```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 `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 `LV_MEM_SIZE` in *lv_conf.h*. This memory is used when you create objects like buttons, labels, etc.
|
||||
- To work with lower `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 [Operating system and interrupts](/porting/os) section to learn more.
|
||||
285
docs/intro/index.rst
Normal file
285
docs/intro/index.rst
Normal file
@@ -0,0 +1,285 @@
|
||||
.. _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 | Yes |
|
||||
+---------+--------------+--------------+--------+
|
||||
|v8.3 | 6 July, 2022 | 6 July, 2023 | Yes |
|
||||
+---------+--------------+--------------+--------+
|
||||
|v9.0 |In progress |
|
||||
+---------+--------------------------------------+
|
||||
|
||||
|
||||
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 :cpp:type:`lv_disp_t`, :cpp:type:`lv_indev_t` and :cpp:type:`lv_fs_drv_t` are global or `static`.
|
||||
* 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_disp_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.
|
||||
@@ -1,119 +0,0 @@
|
||||
|
||||
# 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 `lv_obj_set_layout(obj, LV_LAYOUT_FLEX)`.
|
||||
|
||||
Note that the flex layout feature of LVGL needs to be globally enabled with `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
|
||||
|
||||
`lv_obj_set_flex_flow(obj, flex_flow)`
|
||||
|
||||
The possible values for `flex_flow` are:
|
||||
- `LV_FLEX_FLOW_ROW` Place the children in a row without wrapping
|
||||
- `LV_FLEX_FLOW_COLUMN` Place the children in a column without wrapping
|
||||
- `LV_FLEX_FLOW_ROW_WRAP` Place the children in a row with wrapping
|
||||
- `LV_FLEX_FLOW_COLUMN_WRAP` Place the children in a column with wrapping
|
||||
- `LV_FLEX_FLOW_ROW_REVERSE` Place the children in a row without wrapping but in reversed order
|
||||
- `LV_FLEX_FLOW_COLUMN_REVERSE` Place the children in a column without wrapping but in reversed order
|
||||
- `LV_FLEX_FLOW_ROW_WRAP_REVERSE` Place the children in a row with wrapping but in reversed order
|
||||
- `LV_FLEX_FLOW_COLUMN_WRAP_REVERSE` Place the children in a column with wrapping but in reversed order
|
||||
|
||||
### Flex align
|
||||
To manage the placement of the children use `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 `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:
|
||||
- `LV_FLEX_ALIGN_START` means left on a horizontally and top vertically. (default)
|
||||
- `LV_FLEX_ALIGN_END` means right on a horizontally and bottom vertically
|
||||
- `LV_FLEX_ALIGN_CENTER` simply center
|
||||
- `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`.
|
||||
- `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`.
|
||||
- `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 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 `lv_obj_set_flex_grow(child, value)`. `value` needs to be > 1 or 0 to disable grow on the child.
|
||||
|
||||
|
||||
## 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:
|
||||
|
||||
- `FLEX_FLOW`
|
||||
- `FLEX_MAIN_PLACE`
|
||||
- `FLEX_CROSS_PLACE`
|
||||
- `FLEX_TRACK_PLACE`
|
||||
- `FLEX_GROW`
|
||||
|
||||
### 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: `lv_style_set_pad_column(&row_container_style,0)`
|
||||
|
||||
## Other features
|
||||
|
||||
### RTL
|
||||
If the base direction of the container is set the `LV_BASE_DIR_RTL` the meaning of `LV_FLEX_ALIGN_START` and `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 `lv_obj_add_flag(child, LV_OBJ_FLAG_FLEX_IN_NEW_TRACK)`.
|
||||
|
||||
|
||||
## Example
|
||||
|
||||
```eval_rst
|
||||
|
||||
.. include:: ../../examples/layouts/flex/index.rst
|
||||
|
||||
```
|
||||
|
||||
## API
|
||||
|
||||
```eval_rst
|
||||
|
||||
.. doxygenfile:: lv_flex.h
|
||||
:project: lvgl
|
||||
|
||||
```
|
||||
156
docs/layouts/flex.rst
Normal file
156
docs/layouts/flex.rst
Normal file
@@ -0,0 +1,156 @@
|
||||
====
|
||||
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
|
||||
:c: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
|
||||
---------
|
||||
|
||||
:c:expr:`lv_obj_set_flex_flow(obj, flex_flow)`
|
||||
|
||||
The possible values for ``flex_flow`` are:
|
||||
|
||||
- :c:enumerator:`LV_FLEX_FLOW_ROW`: Place the children in a row without wrapping
|
||||
- :c:enumerator:`LV_FLEX_FLOW_COLUMN`: Place the children in a column without wrapping
|
||||
- :c:enumerator:`LV_FLEX_FLOW_ROW_WRAP`: Place the children in a row with wrapping
|
||||
- :c:enumerator:`LV_FLEX_FLOW_COLUMN_WRAP`: Place the children in a column with wrapping
|
||||
- :c:enumerator:`LV_FLEX_FLOW_ROW_REVERSE`: Place the children in a row without wrapping but in reversed order
|
||||
- :c:enumerator:`LV_FLEX_FLOW_COLUMN_REVERSE`: Place the children in a column without wrapping but in reversed order
|
||||
- :c:enumerator:`LV_FLEX_FLOW_ROW_WRAP_REVERSE`: Place the children in a row with wrapping but in reversed order
|
||||
- :c:enumerator:`LV_FLEX_FLOW_COLUMN_WRAP_REVERSE`: Place the children in a column with wrapping but in reversed order
|
||||
|
||||
Flex align
|
||||
----------
|
||||
|
||||
To manage the placement of the children use
|
||||
:c: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 :c: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:
|
||||
|
||||
- :c:enumerator:`LV_FLEX_ALIGN_START`: means left on a horizontally and top vertically. (default)
|
||||
- :c:enumerator:`LV_FLEX_ALIGN_END`: means right on a horizontally and bottom vertically
|
||||
- :c:enumerator:`LV_FLEX_ALIGN_CENTER`: simply center
|
||||
- :c: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``.
|
||||
- :c: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``.
|
||||
- :c: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 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
|
||||
:c:expr:`lv_obj_set_flex_grow(child, value)`. ``value`` needs to be >
|
||||
1 or 0 to disable grow on the child.
|
||||
|
||||
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:
|
||||
|
||||
- :c:enumerator:`FLEX_FLOW`
|
||||
- :c:enumerator:`FLEX_MAIN_PLACE`
|
||||
- :c:enumerator:`FLEX_CROSS_PLACE`
|
||||
- :c:enumerator:`FLEX_TRACK_PLACE`
|
||||
- :c:enumerator:`FLEX_GROW`
|
||||
|
||||
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: :c:expr:`lv_style_set_pad_column(&row_container_style,0)`
|
||||
|
||||
Other features
|
||||
**************
|
||||
|
||||
RTL
|
||||
---
|
||||
|
||||
If the base direction of the container is set the
|
||||
:c:enumerator:`LV_BASE_DIR_RTL` the meaning of
|
||||
:c:enumerator:`LV_FLEX_ALIGN_START` and
|
||||
:c: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
|
||||
:c:expr:`lv_obj_add_flag(child, LV_OBJ_FLAG_FLEX_IN_NEW_TRACK)`.
|
||||
|
||||
Example
|
||||
*******
|
||||
|
||||
.. include:: ../examples/layouts/flex/index.rst
|
||||
|
||||
API
|
||||
***
|
||||
@@ -1,113 +0,0 @@
|
||||
|
||||
# Grid
|
||||
|
||||
## Overview
|
||||
|
||||
The Grid layout is a subset of [CSS Flexbox](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 (`LV_GRID_CONTENT`) or in "Free unit" (FR) to distribute the free space proportionally.
|
||||
|
||||
To make an object a grid container call `lv_obj_set_layout(obj, LV_LAYOUT_GRID)`.
|
||||
|
||||
Note that the grid layout feature of LVGL needs to be globally enabled with `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
|
||||
|
||||
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 `LV_GRID_TEMPLATE_LAST`.
|
||||
|
||||
For example:
|
||||
```
|
||||
static lv_coord_t column_dsc[] = {100, 400, LV_GRID_TEMPLATE_LAST}; /*2 columns with 100 and 400 ps width*/
|
||||
static lv_coord_t row_dsc[] = {100, 100, 100, LV_GRID_TEMPLATE_LAST}; /*3 100 px tall rows*/
|
||||
```
|
||||
|
||||
To set the descriptors on a parent use `lv_obj_set_grid_dsc_array(obj, col_dsc, row_dsc)`.
|
||||
|
||||
Besides simple settings the size in pixel you can use two special values:
|
||||
- `LV_GRID_CONTENT` set the width to the largest children on this track
|
||||
- `LV_GRID_FR(X)` tell what portion of the remaining space should be used by this track. Larger value means larger space.
|
||||
|
||||
### 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 `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:
|
||||
- `LV_GRID_ALIGN_START` means left on a horizontally and top vertically. (default)
|
||||
- `LV_GRID_ALIGN_END` means right on a horizontally and bottom vertically
|
||||
- `LV_GRID_ALIGN_CENTER` simply center
|
||||
|
||||
`colum_pos` and `row_pos` means the zero based index of the cell into the item should be placed.
|
||||
|
||||
`colum_span` and `row_span` means how many tracks should the item involve from the start cell. Must be > 1.
|
||||
|
||||
### Grid align
|
||||
|
||||
If there are some empty space the track can be aligned several ways:
|
||||
- `LV_GRID_ALIGN_START` means left on a horizontally and top vertically. (default)
|
||||
- `LV_GRID_ALIGN_END` means right on a horizontally and bottom vertically
|
||||
- `LV_GRID_ALIGN_CENTER` simply center
|
||||
- `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`.
|
||||
- `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`.
|
||||
- `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 `lv_obj_set_grid_align(obj, column_align, row_align)`.
|
||||
|
||||
## 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:
|
||||
|
||||
- `GRID_COLUMN_DSC_ARRAY`
|
||||
- `GRID_ROW_DSC_ARRAY`
|
||||
- `GRID_COLUMN_ALIGN`
|
||||
- `GRID_ROW_ALIGN`
|
||||
- `GRID_CELL_X_ALIGN`
|
||||
- `GRID_CELL_COLUMN_POS`
|
||||
- `GRID_CELL_COLUMN_SPAN`
|
||||
- `GRID_CELL_Y_ALIGN`
|
||||
- `GRID_CELL_ROW_POS`
|
||||
- `GRID_CELL_ROW_SPAN`
|
||||
|
||||
### 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.
|
||||
|
||||
## Other features
|
||||
|
||||
### RTL
|
||||
If the base direction of the container is set to `LV_BASE_DIR_RTL`, the meaning of `LV_GRID_ALIGN_START` and `LV_GRID_ALIGN_END` is swapped. I.e. `START` will mean right-most.
|
||||
|
||||
The columns will be placed from right to left.
|
||||
|
||||
|
||||
## Example
|
||||
|
||||
```eval_rst
|
||||
|
||||
.. include:: ../../examples/layouts/grid/index.rst
|
||||
|
||||
```
|
||||
|
||||
## API
|
||||
|
||||
```eval_rst
|
||||
|
||||
.. doxygenfile:: lv_grid.h
|
||||
:project: lvgl
|
||||
|
||||
```
|
||||
147
docs/layouts/grid.rst
Normal file
147
docs/layouts/grid.rst
Normal file
@@ -0,0 +1,147 @@
|
||||
====
|
||||
Grid
|
||||
====
|
||||
|
||||
Overview
|
||||
********
|
||||
|
||||
The Grid layout is a subset of `CSS Flexbox <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 :c: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
|
||||
----------------
|
||||
|
||||
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 lv_coord_t column_dsc[] = {100, 400, LV_GRID_TEMPLATE_LAST}; /*2 columns with 100 and 400 ps width*/
|
||||
static lv_coord_t row_dsc[] = {100, 100, 100, LV_GRID_TEMPLATE_LAST}; /*3 100 px tall rows*/
|
||||
|
||||
To set the descriptors on a parent use
|
||||
:c: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 width to the largest children on this track
|
||||
- :c: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
|
||||
----------
|
||||
|
||||
By default, the children are not added to the grid. They need to be
|
||||
added manually to a cell.
|
||||
|
||||
To do this call
|
||||
:c: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:
|
||||
|
||||
- :c:enumerator:`LV_GRID_ALIGN_START`: means left on a horizontally and top vertically. (default)
|
||||
- :c:enumerator:`LV_GRID_ALIGN_END`: means right on a horizontally and bottom vertically
|
||||
- :c:enumerator:`LV_GRID_ALIGN_CENTER`: simply center ``colum_pos`` and ``row_pos``
|
||||
means the zero based index of the cell into the item should be placed.
|
||||
|
||||
``colum_span`` and ``row_span`` means how many tracks should the item
|
||||
involve from the start cell. Must be > 1.
|
||||
|
||||
Grid align
|
||||
----------
|
||||
|
||||
If there are some empty space the track can be aligned several ways:
|
||||
|
||||
- :c:enumerator:`LV_GRID_ALIGN_START`: means left on a horizontally and top vertically. (default)
|
||||
- :c:enumerator:`LV_GRID_ALIGN_END`: means right on a horizontally and bottom vertically
|
||||
- :c:enumerator:`LV_GRID_ALIGN_CENTER`: simply center
|
||||
- :c: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``.
|
||||
- :c: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``.
|
||||
- :c: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
|
||||
:c:expr:`lv_obj_set_grid_align(obj, column_align, row_align)`.
|
||||
|
||||
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:
|
||||
|
||||
- :c:enumerator:`GRID_COLUMN_DSC_ARRAY`
|
||||
- :c:enumerator:`GRID_ROW_DSC_ARRAY`
|
||||
- :c:enumerator:`GRID_COLUMN_ALIGN`
|
||||
- :c:enumerator:`GRID_ROW_ALIGN`
|
||||
- :c:enumerator:`GRID_CELL_X_ALIGN`
|
||||
- :c:enumerator:`GRID_CELL_COLUMN_POS`
|
||||
- :c:enumerator:`GRID_CELL_COLUMN_SPAN`
|
||||
- :c:enumerator:`GRID_CELL_Y_ALIGN`
|
||||
- :c:enumerator:`GRID_CELL_ROW_POS`
|
||||
- :c:enumerator:`GRID_CELL_ROW_SPAN`
|
||||
|
||||
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.
|
||||
|
||||
Other features
|
||||
**************
|
||||
|
||||
RTL
|
||||
---
|
||||
|
||||
If the base direction of the container is set to :c:enumerator:`LV_BASE_DIR_RTL`,
|
||||
the meaning of :c:enumerator:`LV_GRID_ALIGN_START` and :c:enumerator:`LV_GRID_ALIGN_END` is
|
||||
swapped. I.e. ``START`` will mean right-most.
|
||||
|
||||
The columns will be placed from right to left.
|
||||
|
||||
Example
|
||||
*******
|
||||
|
||||
.. include:: ../examples/layouts/grid/index.rst
|
||||
|
||||
API
|
||||
***
|
||||
@@ -1,11 +0,0 @@
|
||||
|
||||
# Layouts
|
||||
|
||||
|
||||
```eval_rst
|
||||
.. toctree::
|
||||
:maxdepth: 2
|
||||
|
||||
flex
|
||||
grid
|
||||
```
|
||||
10
docs/layouts/index.rst
Normal file
10
docs/layouts/index.rst
Normal file
@@ -0,0 +1,10 @@
|
||||
=======
|
||||
Layouts
|
||||
=======
|
||||
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 2
|
||||
|
||||
flex
|
||||
grid
|
||||
@@ -1,30 +0,0 @@
|
||||
|
||||
# Barcode
|
||||
|
||||
Barcode generation with LVGL. Uses [code128](https://github.com/fhunleth/code128) by [fhunleth](https://github.com/fhunleth).
|
||||
|
||||
## Usage
|
||||
|
||||
Enable `LV_USE_BARCODE` in `lv_conf.h`.
|
||||
|
||||
Use `lv_barcode_create()` to create a barcode object, and use `lv_barcode_update()` to generate a barcode.
|
||||
|
||||
Call `lv_barcode_set_scale()` or `lv_barcode_set_dark/light_color()` to adjust scaling and color, and call `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, `lv_barcode_set_scale(barcode, 2)` means 2x scaling.
|
||||
|
||||
## Example
|
||||
```eval_rst
|
||||
|
||||
.. include:: ../../examples/libs/barcode/index.rst
|
||||
|
||||
```
|
||||
|
||||
## API
|
||||
|
||||
```eval_rst
|
||||
|
||||
.. doxygenfile:: lv_barcode.h
|
||||
:project: lvgl
|
||||
40
docs/libs/barcode.rst
Normal file
40
docs/libs/barcode.rst
Normal file
@@ -0,0 +1,40 @@
|
||||
=======
|
||||
Barcode
|
||||
=======
|
||||
|
||||
Barcode generation with LVGL. Uses
|
||||
`code128 <https://github.com/fhunleth/code128>`__ by
|
||||
`fhunleth <https://github.com/fhunleth>`__.
|
||||
|
||||
Usage
|
||||
-----
|
||||
|
||||
Enable :c:macro:`LV_USE_BARCODE` in ``lv_conf.h``.
|
||||
|
||||
Use :c:expr:`lv_barcode_create()` to create a barcode object, and use
|
||||
:c:expr:`lv_barcode_update()` to generate a barcode.
|
||||
|
||||
Call :c:expr:`lv_barcode_set_scale()` or :c:expr:`lv_barcode_set_dark/light_color()`
|
||||
to adjust scaling and color, and call :c:expr:`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,
|
||||
:c:expr:`lv_barcode_set_scale(barcode, 2)` means 2x scaling.
|
||||
|
||||
Example
|
||||
-------
|
||||
|
||||
.. include:: ../examples/libs/barcode/index.rst
|
||||
|
||||
API
|
||||
---
|
||||
|
||||
:ref:`lv_barcode`
|
||||
|
||||
:ref:`code128`
|
||||
@@ -1,38 +0,0 @@
|
||||
|
||||
# BMP decoder
|
||||
|
||||
This extension allows the use of BMP images in LVGL.
|
||||
This implementation uses [bmp-decoder](https://github.com/caj-johnson/bmp-decoder) library.
|
||||
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 `LV_USE_BMP` LVGL will register a new image decoder automatically so BMP files can be directly used as image sources. For example:
|
||||
```
|
||||
lv_img_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 [here](https://docs.lvgl.io/master/overview/file-system.html) or just enable one in `lv_conf.h` with `LV_USE_FS_...`
|
||||
|
||||
## Limitations
|
||||
- Only BMP files are supported and BMP images as C array (`lv_img_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 `LV_COLOR_DEPTH`. Use GIMP to save the image in the required format.
|
||||
Both RGB888 and ARGB888 works with `LV_COLOR_DEPTH 32`
|
||||
- Palette is not supported.
|
||||
- Because not the whole image is read in can not be zoomed or rotated.
|
||||
|
||||
|
||||
## Example
|
||||
```eval_rst
|
||||
|
||||
.. include:: ../../examples/libs/bmp/index.rst
|
||||
|
||||
```
|
||||
|
||||
## API
|
||||
|
||||
```eval_rst
|
||||
|
||||
.. doxygenfile:: lv_bmp.h
|
||||
:project: lvgl
|
||||
|
||||
```
|
||||
45
docs/libs/bmp.rst
Normal file
45
docs/libs/bmp.rst
Normal file
@@ -0,0 +1,45 @@
|
||||
===========
|
||||
BMP decoder
|
||||
===========
|
||||
|
||||
This extension allows the use of BMP images in LVGL. This implementation
|
||||
uses `bmp-decoder <https://github.com/caj-johnson/bmp-decoder>`__
|
||||
library. 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_img_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:`file-system` or just
|
||||
enable one in ``lv_conf.h`` with ``LV_USE_FS_...``
|
||||
|
||||
Limitations
|
||||
-----------
|
||||
|
||||
- Only BMP files are supported and BMP images as C array
|
||||
(:c:struct:`lv_img_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 can not be zoomed or rotated.
|
||||
|
||||
Example
|
||||
-------
|
||||
|
||||
.. include:: ../examples/libs/bmp/index.rst
|
||||
|
||||
API
|
||||
---
|
||||
|
||||
:ref:`lv_bmp`
|
||||
@@ -1,37 +0,0 @@
|
||||
|
||||
# FFmpeg support
|
||||
[FFmpeg](https://www.ffmpeg.org/) A complete, cross-platform solution to record, convert and stream audio and video.
|
||||
|
||||
## Install FFmpeg
|
||||
- Download FFmpeg from [here](https://www.ffmpeg.org/download.html)
|
||||
- `./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`)
|
||||
|
||||
## Usage
|
||||
|
||||
Enable `LV_USE_FFMPEG` in `lv_conf.h`.
|
||||
|
||||
See the examples below.
|
||||
|
||||
Note that, the 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.
|
||||
|
||||
## Example
|
||||
```eval_rst
|
||||
|
||||
.. include:: ../../examples/libs/ffmpeg/index.rst
|
||||
|
||||
```
|
||||
|
||||
## API
|
||||
|
||||
```eval_rst
|
||||
|
||||
.. doxygenfile:: lv_ffmpeg.h
|
||||
:project: lvgl
|
||||
|
||||
```
|
||||
40
docs/libs/ffmpeg.rst
Normal file
40
docs/libs/ffmpeg.rst
Normal file
@@ -0,0 +1,40 @@
|
||||
==============
|
||||
FFmpeg support
|
||||
==============
|
||||
|
||||
`FFmpeg <https://www.ffmpeg.org/>`__ A complete, cross-platform solution
|
||||
to record, convert and stream audio and video.
|
||||
|
||||
Install FFmpeg
|
||||
--------------
|
||||
|
||||
- Download FFmpeg from `here <https://www.ffmpeg.org/download.html>`__
|
||||
- ``./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``)
|
||||
|
||||
Usage
|
||||
-----
|
||||
|
||||
Enable :c:macro:`LV_USE_FFMPEG` in ``lv_conf.h``.
|
||||
|
||||
See the examples below.
|
||||
|
||||
Note that, the 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.
|
||||
|
||||
Example
|
||||
-------
|
||||
|
||||
.. include:: ../examples/libs/ffmpeg/index.rst
|
||||
|
||||
API
|
||||
---
|
||||
|
||||
:ref:`lv_ffmpeg`
|
||||
@@ -1,86 +0,0 @@
|
||||
|
||||
# FreeType support
|
||||
Interface to [FreeType](https://www.freetype.org/) to generate font bitmaps run time.
|
||||
|
||||
## 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:
|
||||
|
||||
```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)
|
||||
```
|
||||
|
||||
## Usage
|
||||
Enable `LV_USE_FREETYPE` in `lv_conf.h`.
|
||||
|
||||
Cache configuration:
|
||||
- `LV_FREETYPE_CACHE_SIZE` - Maximum memory(Bytes) used to cache font bitmap, outline, character maps, etc. **Note:** This value does not include the memory used by 'FT_Face' and 'FT_Size' objects
|
||||
- `LV_FREETYPE_CACHE_FT_FACES` - Maximum open number of `FT_Face` objects.
|
||||
- `LV_FREETYPE_CACHE_FT_SIZES` - Maximum open number of `FT_Size` objects.
|
||||
|
||||
When you are sure that all the used font sizes will not be greater than 256, you can enable `LV_FREETYPE_SBIT_CACHE`, which is much more memory efficient for small bitmaps.
|
||||
|
||||
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 `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:
|
||||
- `LV_FREETYPE_FONT_STYLE_NORMAL` - Default style.
|
||||
- `LV_FREETYPE_FONT_STYLE_ITALIC` - Italic style.
|
||||
- `LV_FREETYPE_FONT_STYLE_BOLD` - Bold style.
|
||||
|
||||
They can be combined.eg: `LV_FREETYPE_FONT_STYLE_BOLD | LV_FREETYPE_FONT_STYLE_ITALIC`.
|
||||
|
||||
Use the `lv_freetype_font_create()` function to create a font. To delete a font, use `lv_freetype_font_del()`. For more detailed usage, please refer to example code.
|
||||
|
||||
## Example
|
||||
```eval_rst
|
||||
.. include:: ../../examples/libs/freetype/index.rst
|
||||
```
|
||||
|
||||
|
||||
## Learn more
|
||||
- FreeType [tutorial](https://www.freetype.org/freetype2/docs/tutorial/step1.html)
|
||||
- LVGL's [font interface](https://docs.lvgl.io/master/overview/font.html#add-a-new-font-engine)
|
||||
|
||||
|
||||
## API
|
||||
```eval_rst
|
||||
.. doxygenfile:: lv_freetype.h
|
||||
:project: lvgl
|
||||
```
|
||||
112
docs/libs/freetype.rst
Normal file
112
docs/libs/freetype.rst
Normal file
@@ -0,0 +1,112 @@
|
||||
================
|
||||
FreeType support
|
||||
================
|
||||
|
||||
Interface to `FreeType <https://www.freetype.org/>`__ to generate font
|
||||
bitmaps run time.
|
||||
|
||||
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)
|
||||
|
||||
Usage
|
||||
-----
|
||||
|
||||
Enable :c:macro:`LV_USE_FREETYPE` in ``lv_conf.h``.
|
||||
|
||||
Cache configuration:
|
||||
|
||||
- :c:macro:`LV_FREETYPE_CACHE_SIZE` Maximum memory(Bytes) used to cache font bitmap, outline, character maps, etc.
|
||||
:Note: This value does not include the memory used by ``FT_Face`` and ``FT_Size`` objects
|
||||
- :c:macro:`LV_FREETYPE_CACHE_FT_FACES`: Maximum open number of ``FT_Face`` objects.
|
||||
- :c:macro:`LV_FREETYPE_CACHE_FT_SIZES`: Maximum open number of ``FT_Size`` objects.
|
||||
|
||||
When you are sure that all the used font sizes will not be greater than
|
||||
256, you can enable :c:macro:`LV_FREETYPE_SBIT_CACHE`, which is much more
|
||||
memory efficient for small bitmaps.
|
||||
|
||||
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:
|
||||
|
||||
- :c:enumerator:`LV_FREETYPE_FONT_STYLE_NORMAL`: Default style.
|
||||
- :c:enumerator:`LV_FREETYPE_FONT_STYLE_ITALIC`: Italic style.
|
||||
- :c:enumerator:`LV_FREETYPE_FONT_STYLE_BOLD`: Bold style.
|
||||
|
||||
They can be combined.eg:
|
||||
:c:expr:`LV_FREETYPE_FONT_STYLE_BOLD | LV_FREETYPE_FONT_STYLE_ITALIC`.
|
||||
|
||||
Use the :c:expr:`lv_freetype_font_create()` function to create a font. To
|
||||
delete a font, use :c:expr:`lv_freetype_font_del()`. For more detailed usage,
|
||||
please refer to example code.
|
||||
|
||||
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`
|
||||
|
||||
API
|
||||
---
|
||||
|
||||
:ref:`lv_freetype`
|
||||
|
||||
:ref:`ftoption`
|
||||
|
||||
:ref:`ftmodule`
|
||||
35
docs/libs/fs.rst
Normal file
35
docs/libs/fs.rst
Normal file
@@ -0,0 +1,35 @@
|
||||
======================
|
||||
File System Interfaces
|
||||
======================
|
||||
|
||||
LVGL has a :ref:`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)
|
||||
|
||||
You still need to provide the drivers and libraries, this extension
|
||||
provides only the bridge between FATFS, STDIO, POSIX, WIN32 and LVGL.
|
||||
|
||||
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"``.
|
||||
|
||||
The work directory can be set with ``LV_FS_..._PATH``. E.g.
|
||||
``"/home/joe/projects/"`` The actual file/directory paths will be
|
||||
appended to it.
|
||||
|
||||
Cached reading is also supported if ``LV_FS_..._CACHE_SIZE`` is set to
|
||||
not ``0`` value. :c:func:`lv_fs_read` caches this size of data to lower the
|
||||
number of actual reads from the storage.
|
||||
|
||||
API
|
||||
***
|
||||
|
||||
:ref:`lv_fsdrv`
|
||||
@@ -1,21 +0,0 @@
|
||||
|
||||
# File System Interfaces
|
||||
|
||||
LVGL has a [File system](https://docs.lvgl.io/master/overview/file-system.html) 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)
|
||||
|
||||
You still need to provide the drivers and libraries, this extension provides only the bridge between FATFS, STDIO, POSIX, WIN32 and LVGL.
|
||||
|
||||
## 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"`.
|
||||
|
||||
The work directory can be set with `LV_FS_..._PATH`. E.g. `"/home/joe/projects/"` The actual file/directory paths will be appended to it.
|
||||
|
||||
Cached reading is also supported if `LV_FS_..._CACHE_SIZE` is set to not `0` value. `lv_fs_read` caches this size of data to lower the number of actual reads from the storage.
|
||||
@@ -1,39 +0,0 @@
|
||||
|
||||
# GIF decoder
|
||||
Allow using GIF images in LVGL. Based on https://github.com/lecram/gifdec
|
||||
|
||||
When enabled in `lv_conf.h` with `LV_USE_GIF` `lv_gif_create(parent)` can be used to create a gif widget.
|
||||
|
||||
`lv_gif_set_src(obj, src)` works very similarly to `lv_img_set_src`. As source, it also accepts images as variables (`lv_img_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:
|
||||
```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 [here](https://docs.lvgl.io/master/overview/file-system.html) 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:
|
||||
- `LV_COLOR_DEPTH 8`: 3 x image width x image height
|
||||
- `LV_COLOR_DEPTH 16`: 4 x image width x image height
|
||||
- `LV_COLOR_DEPTH 32`: 5 x image width x image height
|
||||
|
||||
## Example
|
||||
```eval_rst
|
||||
.. include:: ../../examples/libs/gif/index.rst
|
||||
```
|
||||
|
||||
## API
|
||||
|
||||
```eval_rst
|
||||
.. doxygenfile:: lv_gif.h
|
||||
:project: lvgl
|
||||
```
|
||||
55
docs/libs/gif.rst
Normal file
55
docs/libs/gif.rst
Normal file
@@ -0,0 +1,55 @@
|
||||
===========
|
||||
GIF decoder
|
||||
===========
|
||||
|
||||
Allow using GIF images in LVGL. Based on
|
||||
https://github.com/lecram/gifdec
|
||||
|
||||
When enabled in ``lv_conf.h`` with :c:macro:`LV_USE_GIF`
|
||||
:c:expr:`lv_gif_create(parent)` can be used to create a gif widget.
|
||||
|
||||
:c:expr:`lv_gif_set_src(obj, src)` works very similarly to :c:func:`lv_img_set_src`.
|
||||
As source, it also accepts images as variables (:c:struct:`lv_img_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:`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
|
||||
|
||||
Example
|
||||
-------
|
||||
|
||||
.. include:: ../examples/libs/gif/index.rst
|
||||
|
||||
API
|
||||
---
|
||||
|
||||
:ref:`lv_gif`
|
||||
|
||||
:ref:`gifdec`
|
||||
@@ -1,21 +0,0 @@
|
||||
# 3rd party libraries
|
||||
|
||||
|
||||
```eval_rst
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 1
|
||||
|
||||
fsdrv
|
||||
bmp
|
||||
sjpg
|
||||
png
|
||||
gif
|
||||
freetype
|
||||
tiny_ttf
|
||||
qrcode
|
||||
barcode
|
||||
rlottie
|
||||
ffmpeg
|
||||
```
|
||||
|
||||
19
docs/libs/index.rst
Normal file
19
docs/libs/index.rst
Normal file
@@ -0,0 +1,19 @@
|
||||
===================
|
||||
3rd party libraries
|
||||
===================
|
||||
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 1
|
||||
|
||||
fs
|
||||
bmp
|
||||
sjpg
|
||||
png
|
||||
gif
|
||||
freetype
|
||||
tiny_ttf
|
||||
qrcode
|
||||
barcode
|
||||
rlottie
|
||||
ffmpeg
|
||||
@@ -1,27 +0,0 @@
|
||||
|
||||
# PNG decoder
|
||||
|
||||
Allow the use of PNG images in LVGL. This implementation uses [lodepng](https://github.com/lvandeve/lodepng) library.
|
||||
|
||||
If enabled in `lv_conf.h` by `LV_USE_PNG` LVGL will register a new image decoder automatically so PNG files can be directly used as any other image sources.
|
||||
|
||||
Note that, a file system driver needs to registered to open images from files. Read more about it [here](https://docs.lvgl.io/master/overview/file-system.html) or just enable one in `lv_conf.h` with `LV_USE_FS_...`
|
||||
|
||||
The whole PNG image is decoded so during decoding RAM equals to `image width x image height x 4` bytes are required.
|
||||
|
||||
As it might take significant time to decode PNG images LVGL's [images caching](https://docs.lvgl.io/master/overview/image.html#image-caching) feature can be useful.
|
||||
|
||||
## Example
|
||||
```eval_rst
|
||||
|
||||
.. include:: ../../examples/libs/png/index.rst
|
||||
|
||||
```
|
||||
|
||||
## API
|
||||
|
||||
```eval_rst
|
||||
|
||||
.. doxygenfile:: lv_png.h
|
||||
:project: lvgl
|
||||
|
||||
31
docs/libs/png.rst
Normal file
31
docs/libs/png.rst
Normal file
@@ -0,0 +1,31 @@
|
||||
===========
|
||||
PNG decoder
|
||||
===========
|
||||
|
||||
Allow the use of PNG images in LVGL. This implementation uses
|
||||
`lodepng <https://github.com/lvandeve/lodepng>`__ library.
|
||||
|
||||
If enabled in ``lv_conf.h`` by :c:macro:`LV_USE_PNG` LVGL will register a new
|
||||
image decoder automatically so PNG files can be directly used as any
|
||||
other image sources.
|
||||
|
||||
Note that, a file system driver needs to registered to open images from
|
||||
files. Read more about it :ref:`file-system` or just
|
||||
enable one in ``lv_conf.h`` with ``LV_USE_FS_...``
|
||||
|
||||
The whole PNG image is decoded so during decoding RAM equals to
|
||||
``image width x image height x 4`` bytes are required.
|
||||
|
||||
As it might take significant time to decode PNG images LVGL’s :ref:`image-caching` feature can be useful.
|
||||
|
||||
Example
|
||||
-------
|
||||
|
||||
.. include:: ../examples/libs/png/index.rst
|
||||
|
||||
API
|
||||
---
|
||||
|
||||
:ref:`lv_png`
|
||||
|
||||
:ref:`lodepng`
|
||||
@@ -1,30 +0,0 @@
|
||||
|
||||
# QR code
|
||||
|
||||
QR code generation with LVGL. Uses [QR-Code-generator](https://github.com/nayuki/QR-Code-generator) by [nayuki](https://github.com/nayuki).
|
||||
|
||||
## Usage
|
||||
|
||||
Enable `LV_USE_QRCODE` in `lv_conf.h`.
|
||||
|
||||
Use `lv_qrcode_create()` to create a qrcode object, and use `lv_qrcode_update()` to generate a QR code.
|
||||
|
||||
If you need to re-modify the size and color, use `lv_qrcode_set_size()` and `lv_qrcode_set_dark/light_color()`, and call `lv_qrcode_update()` again to regenerate the QR code.
|
||||
|
||||
## Notes
|
||||
- QR codes with less data are smaller, but they scaled by an integer number to best fit to the given size.
|
||||
|
||||
|
||||
## Example
|
||||
```eval_rst
|
||||
|
||||
.. include:: ../../examples/libs/qrcode/index.rst
|
||||
|
||||
```
|
||||
|
||||
## API
|
||||
|
||||
```eval_rst
|
||||
|
||||
.. doxygenfile:: lv_qrcode.h
|
||||
:project: lvgl
|
||||
37
docs/libs/qrcode.rst
Normal file
37
docs/libs/qrcode.rst
Normal file
@@ -0,0 +1,37 @@
|
||||
=======
|
||||
QR code
|
||||
=======
|
||||
|
||||
QR code generation with LVGL. Uses
|
||||
`QR-Code-generator <https://github.com/nayuki/QR-Code-generator>`__ by
|
||||
`nayuki <https://github.com/nayuki>`__.
|
||||
|
||||
Usage
|
||||
-----
|
||||
|
||||
Enable :c:macro:`LV_USE_QRCODE` in ``lv_conf.h``.
|
||||
|
||||
Use :c:expr:`lv_qrcode_create()` to create a qrcode object, and use
|
||||
:c:expr:`lv_qrcode_update()` to generate a QR code.
|
||||
|
||||
If you need to re-modify the size and color, use
|
||||
:c:expr:`lv_qrcode_set_size()` and :c:expr:`lv_qrcode_set_dark/light_color()`, and
|
||||
call :c:expr:`lv_qrcode_update()` again to regenerate the QR code.
|
||||
|
||||
Notes
|
||||
-----
|
||||
|
||||
- QR codes with less data are smaller, but they scaled by an integer
|
||||
number to best fit to the given size.
|
||||
|
||||
Example
|
||||
-------
|
||||
|
||||
.. include:: ../examples/libs/qrcode/index.rst
|
||||
|
||||
API
|
||||
---
|
||||
|
||||
:ref:`lv_qrcode`
|
||||
|
||||
:ref:`qrcodegen`
|
||||
@@ -1,194 +0,0 @@
|
||||
|
||||
|
||||
# Lottie player
|
||||
Allows to use Lottie animations in LVGL. Taken from this [base repository](https://github.com/ValentiWorkLearning/lv_rlottie)
|
||||
|
||||
LVGL provides the interface to [Samsung/rlottie](https://github.com/Samsung/rlottie) library's C API. That is the actual Lottie player is not part of LVGL, it needs to be built separately.
|
||||
|
||||
## Build Rlottie
|
||||
To build Samsung's Rlottie C++14-compatible compiler and optionally CMake 3.14 or higher is required.
|
||||
|
||||
To build on desktop you can follow the instructions from Rlottie's [README](https://github.com/Samsung/rlottie/blob/master/README.md). In the most basic case it looks like this:
|
||||
```
|
||||
mkdir rlottie_workdir
|
||||
cd rlottie_workdir
|
||||
git clone https://github.com/Samsung/rlottie.git
|
||||
mkdir build
|
||||
cd build
|
||||
cmake ../rlottie
|
||||
make -j
|
||||
sudo make install
|
||||
```
|
||||
|
||||
And finally add the `-lrlottie` flag to your linker.
|
||||
|
||||
On embedded systems you need to take care of integrating Rlottie to the given build system.
|
||||
|
||||
### ESP-IDF example at bottom
|
||||
|
||||
## Usage
|
||||
|
||||
You can use animation from files or raw data (text). In either case first you need to enable `LV_USE_RLOTTIE` in `lv_conf.h`.
|
||||
|
||||
|
||||
The `width` and `height` of the object be set in the *create* function and the animation will be scaled accordingly.
|
||||
|
||||
### Use Rlottie from file
|
||||
|
||||
To create a Lottie animation from file use:
|
||||
```c
|
||||
lv_obj_t * lottie = lv_rlottie_create_from_file(parent, width, height, "path/to/lottie.json");
|
||||
```
|
||||
|
||||
Note that, Rlottie uses the standard STDIO C file API, so you can use the path "normally" and no LVGL specific driver letter is required.
|
||||
|
||||
|
||||
### Use Rlottie from raw string data
|
||||
|
||||
`lv_example_rlottie_approve.c` contains an example animation in raw format. Instead storing the JSON string a hex array is stored for the following reasons:
|
||||
- avoid escaping `"` in the JSON file
|
||||
- some compilers don't support very long strings
|
||||
|
||||
`lvgl/scripts/filetohex.py` can be used to convert a Lottie file a hex array. E.g.:
|
||||
```
|
||||
./filetohex.py path/to/lottie.json > out.txt
|
||||
```
|
||||
|
||||
To create an animation from raw data:
|
||||
|
||||
```c
|
||||
extern const uint8_t lottie_data[];
|
||||
lv_obj_t* lottie = lv_rlottie_create_from_raw(parent, width, height, (const char *)lottie_data);
|
||||
```
|
||||
|
||||
## Getting animations
|
||||
|
||||
Lottie is standard and popular format so you can find many animation files on the web.
|
||||
For example: https://lottiefiles.com/
|
||||
|
||||
You can also create your own animations with Adobe After Effects or similar software.
|
||||
|
||||
## Controlling animations
|
||||
|
||||
LVGL provides two functions to control the animation mode: `lv_rlottie_set_play_mode` and `lv_rlottie_set_current_frame`.
|
||||
You'll combine your intentions when calling the first method, like in these examples:
|
||||
```c
|
||||
lv_obj_t * lottie = lv_rlottie_create_from_file(scr, 128, 128, "test.json");
|
||||
lv_obj_center(lottie);
|
||||
// Pause to a specific frame
|
||||
lv_rlottie_set_current_frame(lottie, 50);
|
||||
lv_rlottie_set_play_mode(lottie, LV_RLOTTIE_CTRL_PAUSE); // The specified frame will be displayed and then the animation will pause
|
||||
|
||||
// Play backward and loop
|
||||
lv_rlottie_set_play_mode(lottie, LV_RLOTTIE_CTRL_PLAY | LV_RLOTTIE_CTRL_BACKWARD | LV_RLOTTIE_CTRL_LOOP);
|
||||
|
||||
// Play forward once (no looping)
|
||||
lv_rlottie_set_play_mode(lottie, LV_RLOTTIE_CTRL_PLAY | LV_RLOTTIE_CTRL_FORWARD);
|
||||
```
|
||||
|
||||
The default animation mode is **play forward with loop**.
|
||||
|
||||
If you don't enable looping, a `LV_EVENT_READY` is sent when the animation can not make more progress without looping.
|
||||
|
||||
To get the number of frames in an animation or the current frame index, you can cast the `lv_obj_t` instance to a `lv_rlottie_t` instance and inspect the `current_frame` and `total_frames` members.
|
||||
|
||||
|
||||
## ESP-IDF Example
|
||||
### Background
|
||||
Rlottie can be expensive to render on embedded hardware. Lottie animations tend to use a large amount of CPU time and can use large portions of RAM. This will vary from lottie to lottie but in general for best performance:
|
||||
* Limit total # of frames in the animation
|
||||
* Where possible, try to avoid bezier type animations
|
||||
* Limit animation render size
|
||||
|
||||
If your ESP32 chip does not have SPIRAM you will face severe limitations in render size.
|
||||
|
||||
To give a better idea on this, lets assume you want to render a 240x320 lottie animation.
|
||||
|
||||
In order to pass initialization of the lv_rlottie_t object, you need 240x320x32/8 (307k) available memory. The latest ESP32-S3 has 256kb RAM available for this (before freeRtos and any other initialization starts taking chunks out). So while you can probably start to render a 50x50 animation without SPIRAM, PSRAM is highly recommended.
|
||||
|
||||
Additionally, while you might be able to pass initialization of the lv_rlottie_t object, as rlottie renders frame to frame, this consumes additional memory. A 30 frame animation that plays over 1 second probably has minimal issues, but a 300 frame animation playing over 10 seconds could very easily crash due to lack of memory as rlottie renders, depending on the complexity of the animation.
|
||||
|
||||
Rlottie will not compile for the IDF using the -02 compiler option at this time.
|
||||
|
||||
For stability in lottie animations, I found that they run best in the IDF when enabling LV_MEM_CUSTOM (using stdlib.h)
|
||||
|
||||
For all its faults, when running right-sized animations, they provide a wonderful utility to LVGL on embedded LCDs and can look really good when done properly.
|
||||
|
||||
When picking/designing a lottie animation consider the following limitations:
|
||||
- Build the lottie animation to be sized for the intended size - it can scale/resize, but performance will be best when the base lottie size is as intended
|
||||
- Limit total number of frames, the longer the lottie animation is, the more memory it will consume for rendering (rlottie consumes IRAM for rendering)
|
||||
- Build the lottie animation for the intended frame rate - default lottie is 60fps, embedded LCDs likely wont go above 30fps
|
||||
|
||||
### IDF Setup
|
||||
Where the LVGL simulator uses the installed rlottie lib, the IDF works best when using rlottie as a submodule under the components directory.
|
||||
|
||||
```
|
||||
cd 'your/project/directory'
|
||||
git add submodule
|
||||
git add submodule https://github.com/Samsung/rlottie.git ./components/rlottie/rlottie
|
||||
git submodule update --init --recursive
|
||||
```
|
||||
|
||||
Now, Rlottie is available as a component in the IDF, but it requires some additional changes and a CMakeLists file to tell the IDF how to compile.
|
||||
|
||||
|
||||
### Rlottie patch file
|
||||
Rlottie relies on a dynamic linking for an image loader lib. This needs to be disabled as the IDF doesn't play nice with dynamic linking.
|
||||
|
||||
A patch file is available in lvgl uner: /env_support/esp/rlottie/0001-changes-to-compile-with-esp-idf.patch
|
||||
|
||||
Apply the patch file to your rlottie submodule.
|
||||
|
||||
### CMakeLists for IDF
|
||||
An example CMakeLists file has been provided at /env_support/esp/rlottie/CMakeLists.txt
|
||||
|
||||
Copy this CMakeLists file to 'your-project-directory'/components/rlottie/
|
||||
|
||||
In addition to the component CMakeLists file, you'll also need to tell your project level CMakeLists in your IDF project to require rlottie:
|
||||
|
||||
```
|
||||
REQUIRES "lvgl" "rlottie"
|
||||
```
|
||||
|
||||
From here, you should be able to use lv_rlottie objects in your ESP-IDF project as any other widget in LVGL ESP examples. Please remember that these animations can be highly resource constrained and this does not guarantee that every animation will work.
|
||||
|
||||
### Additional Rlottie considerations in ESP-IDF
|
||||
While unecessary, removing the rlottie/rlottie/example folder can remove many un-needed files for this embedded LVGL application
|
||||
|
||||
From here, you can use the relevant LVGL lv_rlottie functions to create lottie animations in LVGL on embedded hardware!
|
||||
|
||||
Please note, that while lottie animations are capable of running on many ESP chips, below is recommended for best performance.
|
||||
|
||||
* ESP32-S3-WROOM-1-N16R8
|
||||
* 16mb quad spi flash
|
||||
* 8mb octal spi PSRAM
|
||||
* IDF4.4 or higher
|
||||
|
||||
The Esp-box devkit meets this spec and https://github.com/espressif/esp-box is a great starting point to adding lottie animations.
|
||||
|
||||
you'll need to enable LV_USE_RLOTTIE through idf.py menuconfig under LVGL component settings.
|
||||
|
||||
### Additional changes to make use of SPIRAM
|
||||
|
||||
lv_alloc/realloc do not make use of SPIRAM. Given the high memory usage of lottie animations, it is recommended to shift as much out of internal DRAM into SPIRAM as possible. In order to do so, SPIRAM will need to be enabled in the menuconfig options for your given espressif chip.
|
||||
|
||||
There may be a better solution for this, but for the moment the recommendation is to make local modifications to the lvgl component in your espressif project. This is as simple as swapping lv_alloc/lv_realloc calls in lv_rlottie.c with heap_caps_malloc (for IDF) with the appropriate MALLOC_CAP call - for SPIRAM usage this is MALLOC_CAP_SPIRAM.
|
||||
|
||||
```c
|
||||
rlottie->allocated_buf = heap_caps_malloc(allocaled_buf_size+1, MALLOC_CAP_SPIRAM);
|
||||
```
|
||||
|
||||
|
||||
## Example
|
||||
```eval_rst
|
||||
|
||||
.. include:: ../../examples/libs/rlottie/index.rst
|
||||
|
||||
```
|
||||
|
||||
## API
|
||||
|
||||
```eval_rst
|
||||
|
||||
.. doxygenfile:: lv_rlottie.h
|
||||
:project: lvgl
|
||||
277
docs/libs/rlottie.rst
Normal file
277
docs/libs/rlottie.rst
Normal file
@@ -0,0 +1,277 @@
|
||||
=============
|
||||
Lottie player
|
||||
=============
|
||||
|
||||
Allows to use Lottie animations in LVGL. Taken from this `base repository <https://github.com/ValentiWorkLearning/lv_rlottie>`__
|
||||
|
||||
LVGL provides the interface to `Samsung/rlottie <https://github.com/Samsung/rlottie>`__ library's C
|
||||
API. That is the actual Lottie player is not part of LVGL, it needs to
|
||||
be built separately.
|
||||
|
||||
Build Rlottie
|
||||
-------------
|
||||
|
||||
To build Samsung's Rlottie C++14-compatible compiler and optionally
|
||||
CMake 3.14 or higher is required.
|
||||
|
||||
To build on desktop you can follow the instructions from Rlottie's
|
||||
`README <https://github.com/Samsung/rlottie/blob/master/README.md>`__.
|
||||
In the most basic case it looks like this:
|
||||
|
||||
.. code:: shell
|
||||
|
||||
mkdir rlottie_workdir
|
||||
cd rlottie_workdir
|
||||
git clone https://github.com/Samsung/rlottie.git
|
||||
mkdir build
|
||||
cd build
|
||||
cmake ../rlottie
|
||||
make -j
|
||||
sudo make install
|
||||
|
||||
And finally add the ``-lrlottie`` flag to your linker.
|
||||
|
||||
On embedded systems you need to take care of integrating Rlottie to the
|
||||
given build system.
|
||||
|
||||
ESP-IDF example at bottom
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Usage
|
||||
-----
|
||||
|
||||
You can use animation from files or raw data (text). In either case
|
||||
first you need to enable :c:macro:`LV_USE_RLOTTIE` in ``lv_conf.h``.
|
||||
|
||||
The ``width`` and ``height`` of the object be set in the *create*
|
||||
function and the animation will be scaled accordingly.
|
||||
|
||||
Use Rlottie from file
|
||||
~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
To create a Lottie animation from file use:
|
||||
|
||||
.. code:: c
|
||||
|
||||
lv_obj_t * lottie = lv_rlottie_create_from_file(parent, width, height, "path/to/lottie.json");
|
||||
|
||||
Note that, Rlottie uses the standard STDIO C file API, so you can use
|
||||
the path “normally” and no LVGL specific driver letter is required.
|
||||
|
||||
Use Rlottie from raw string data
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
``lv_example_rlottie_approve.c`` contains an example animation in raw
|
||||
format. Instead storing the JSON string a hex array is stored for the
|
||||
following reasons: - avoid escaping ``"`` in the JSON file - some
|
||||
compilers don't support very long strings
|
||||
|
||||
``lvgl/scripts/filetohex.py`` can be used to convert a Lottie file a hex
|
||||
array. E.g.:
|
||||
|
||||
.. code:: shell
|
||||
|
||||
./filetohex.py path/to/lottie.json > out.txt
|
||||
|
||||
To create an animation from raw data:
|
||||
|
||||
.. code:: c
|
||||
|
||||
extern const uint8_t lottie_data[];
|
||||
lv_obj_t* lottie = lv_rlottie_create_from_raw(parent, width, height, (const char *)lottie_data);
|
||||
|
||||
Getting animations
|
||||
------------------
|
||||
|
||||
Lottie is standard and popular format so you can find many animation
|
||||
files on the web. For example: https://lottiefiles.com/
|
||||
|
||||
You can also create your own animations with Adobe After Effects or
|
||||
similar software.
|
||||
|
||||
Controlling animations
|
||||
----------------------
|
||||
|
||||
LVGL provides two functions to control the animation mode:
|
||||
:c:func:`lv_rlottie_set_play_mode` and :c:func:`lv_rlottie_set_current_frame`.
|
||||
You'll combine your intentions when calling the first method, like in
|
||||
these examples:
|
||||
|
||||
.. code:: c
|
||||
|
||||
lv_obj_t * lottie = lv_rlottie_create_from_file(scr, 128, 128, "test.json");
|
||||
lv_obj_center(lottie);
|
||||
// Pause to a specific frame
|
||||
lv_rlottie_set_current_frame(lottie, 50);
|
||||
lv_rlottie_set_play_mode(lottie, LV_RLOTTIE_CTRL_PAUSE); // The specified frame will be displayed and then the animation will pause
|
||||
|
||||
// Play backward and loop
|
||||
lv_rlottie_set_play_mode(lottie, LV_RLOTTIE_CTRL_PLAY | LV_RLOTTIE_CTRL_BACKWARD | LV_RLOTTIE_CTRL_LOOP);
|
||||
|
||||
// Play forward once (no looping)
|
||||
lv_rlottie_set_play_mode(lottie, LV_RLOTTIE_CTRL_PLAY | LV_RLOTTIE_CTRL_FORWARD);
|
||||
|
||||
The default animation mode is **play forward with loop**.
|
||||
|
||||
If you don't enable looping, a :c:enumerator:`LV_EVENT_READY` is sent when the
|
||||
animation can not make more progress without looping.
|
||||
|
||||
To get the number of frames in an animation or the current frame index,
|
||||
you can cast the :c:struct:`lv_obj_t` instance to a :c:struct:`lv_rlottie_t` instance
|
||||
and inspect the ``current_frame`` and ``total_frames`` members.
|
||||
|
||||
ESP-IDF Example
|
||||
---------------
|
||||
|
||||
Background
|
||||
~~~~~~~~~~
|
||||
|
||||
Rlottie can be expensive to render on embedded hardware. Lottie
|
||||
animations tend to use a large amount of CPU time and can use large
|
||||
portions of RAM. This will vary from lottie to lottie but in general for
|
||||
best performance: \* Limit total # of frames in the animation \* Where
|
||||
possible, try to avoid bezier type animations \* Limit animation render
|
||||
size
|
||||
|
||||
If your ESP32 chip does not have SPIRAM you will face severe limitations
|
||||
in render size.
|
||||
|
||||
To give a better idea on this, lets assume you want to render a 240x320
|
||||
lottie animation.
|
||||
|
||||
In order to pass initialization of the lv_rlottie_t object, you need
|
||||
240x320x32/8 (307k) available memory. The latest ESP32-S3 has 256kb RAM
|
||||
available for this (before freeRtos and any other initialization starts
|
||||
taking chunks out). So while you can probably start to render a 50x50
|
||||
animation without SPIRAM, PSRAM is highly recommended.
|
||||
|
||||
Additionally, while you might be able to pass initialization of the
|
||||
lv_rlottie_t object, as rlottie renders frame to frame, this consumes
|
||||
additional memory. A 30 frame animation that plays over 1 second
|
||||
probably has minimal issues, but a 300 frame animation playing over 10
|
||||
seconds could very easily crash due to lack of memory as rlottie
|
||||
renders, depending on the complexity of the animation.
|
||||
|
||||
Rlottie will not compile for the IDF using the -02 compiler option at
|
||||
this time.
|
||||
|
||||
For stability in lottie animations, I found that they run best in the
|
||||
IDF when enabling :c:macro:`LV_MEM_CUSTOM` (using stdlib.h)
|
||||
|
||||
For all its faults, when running right-sized animations, they provide a
|
||||
wonderful utility to LVGL on embedded LCDs and can look really good when
|
||||
done properly.
|
||||
|
||||
When picking/designing a lottie animation consider the following
|
||||
limitations: - Build the lottie animation to be sized for the intended
|
||||
size - it can scale/resize, but performance will be best when the base
|
||||
lottie size is as intended - Limit total number of frames, the longer
|
||||
the lottie animation is, the more memory it will consume for rendering
|
||||
(rlottie consumes IRAM for rendering) - Build the lottie animation for
|
||||
the intended frame rate - default lottie is 60fps, embedded LCDs likely
|
||||
wont go above 30fps
|
||||
|
||||
IDF Setup
|
||||
~~~~~~~~~
|
||||
|
||||
Where the LVGL simulator uses the installed rlottie lib, the IDF works
|
||||
best when using rlottie as a submodule under the components directory.
|
||||
|
||||
.. code:: shell
|
||||
|
||||
cd 'your/project/directory'
|
||||
git add submodule
|
||||
git add submodule https://github.com/Samsung/rlottie.git ./components/rlottie/rlottie
|
||||
git submodule update --init --recursive
|
||||
|
||||
Now, Rlottie is available as a component in the IDF, but it requires
|
||||
some additional changes and a CMakeLists file to tell the IDF how to
|
||||
compile.
|
||||
|
||||
Rlottie patch file
|
||||
~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Rlottie relies on a dynamic linking for an image loader lib. This needs
|
||||
to be disabled as the IDF doesn't play nice with dynamic linking.
|
||||
|
||||
A patch file is available in lvgl uner:
|
||||
``/env_support/esp/rlottie/0001-changes-to-compile-with-esp-idf.patch``
|
||||
|
||||
Apply the patch file to your rlottie submodule.
|
||||
|
||||
CMakeLists for IDF
|
||||
~~~~~~~~~~~~~~~~~~
|
||||
|
||||
An example CMakeLists file has been provided at
|
||||
``/env_support/esp/rlottie/CMakeLists.txt``
|
||||
|
||||
Copy this CMakeLists file to
|
||||
``‘your-project-directory'/components/rlottie/``
|
||||
|
||||
In addition to the component CMakeLists file, you'll also need to tell
|
||||
your project level CMakeLists in your IDF project to require rlottie:
|
||||
|
||||
.. code:: console
|
||||
|
||||
REQUIRES "lvgl" "rlottie"
|
||||
|
||||
From here, you should be able to use lv_rlottie objects in your ESP-IDF
|
||||
project as any other widget in LVGL ESP examples. Please remember that
|
||||
these animations can be highly resource constrained and this does not
|
||||
guarantee that every animation will work.
|
||||
|
||||
Additional Rlottie considerations in ESP-IDF
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
While unecessary, removing the ``rlottie/rlottie/example`` folder can remove
|
||||
many un-needed files for this embedded LVGL application
|
||||
|
||||
From here, you can use the relevant LVGL lv_rlottie functions to create
|
||||
lottie animations in LVGL on embedded hardware!
|
||||
|
||||
Please note, that while lottie animations are capable of running on many
|
||||
ESP chips, below is recommended for best performance.
|
||||
|
||||
- ESP32-S3-WROOM-1-N16R8
|
||||
|
||||
- 16mb quad spi flash
|
||||
- 8mb octal spi PSRAM
|
||||
|
||||
- IDF4.4 or higher
|
||||
|
||||
The Esp-box devkit meets this spec and
|
||||
https://github.com/espressif/esp-box is a great starting point to adding
|
||||
lottie animations.
|
||||
|
||||
you'll need to enable:c:macro:`LV_USE_RLOTTIE` through idf.py menuconfig under
|
||||
LVGL component settings.
|
||||
|
||||
Additional changes to make use of SPIRAM
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
lv_alloc/realloc do not make use of SPIRAM. Given the high memory usage
|
||||
of lottie animations, it is recommended to shift as much out of internal
|
||||
DRAM into SPIRAM as possible. In order to do so, SPIRAM will need to be
|
||||
enabled in the menuconfig options for your given espressif chip.
|
||||
|
||||
There may be a better solution for this, but for the moment the
|
||||
recommendation is to make local modifications to the lvgl component in
|
||||
your espressif project. This is as simple as swapping
|
||||
lv_alloc/lv_realloc calls in lv_rlottie.c with heap_caps_malloc (for
|
||||
IDF) with the appropriate :c:expr:`MALLOC_CAP` call - for SPIRAM usage this is
|
||||
:c:expr:`MALLOC_CAP_SPIRAM`.
|
||||
|
||||
.. code:: c
|
||||
|
||||
rlottie->allocated_buf = heap_caps_malloc(allocaled_buf_size+1, MALLOC_CAP_SPIRAM);
|
||||
|
||||
Example
|
||||
-------
|
||||
|
||||
.. include:: ../examples/libs/rlottie/index.rst
|
||||
|
||||
|
||||
API
|
||||
---
|
||||
|
||||
:ref:`lv_rlottie`
|
||||
@@ -1,73 +0,0 @@
|
||||
|
||||
# JPG decoder
|
||||
|
||||
Allow the use of JPG images in LVGL. Besides that it also allows the use of a custom format, called Split JPG (SJPG), which can be decoded in more optimal way on embedded systems.
|
||||
|
||||
## Overview
|
||||
- Supports both normal JPG and the custom SJPG formats.
|
||||
- Decoding normal JPG consumes RAM with the size fo the whole uncompressed image (recommended only for devices with more RAM)
|
||||
- SJPG is a custom format based on "normal" JPG and specially made for LVGL.
|
||||
- SJPG is 'split-jpeg' which is a bundle of small jpeg fragments with an sjpg header.
|
||||
- SJPG size will be almost comparable to the jpg file or might be a slightly larger.
|
||||
- File read from file and c-array are implemented.
|
||||
- SJPEG frame fragment cache enables fast fetching of lines if available in cache.
|
||||
- By default the sjpg image cache will be image width * 2 * 16 bytes (can be modified)
|
||||
- Currently only 16 bit image format is supported (TODO)
|
||||
- Only the required partion of the JPG and SJPG images are decoded, therefore they can't be zoomed or rotated.
|
||||
|
||||
## Usage
|
||||
|
||||
If enabled in `lv_conf.h` by `LV_USE_SJPG` LVGL will register a new image decoder automatically so JPG and SJPG files can be directly used as image sources. For example:
|
||||
```
|
||||
lv_img_set_src(my_img, "S:path/to/picture.jpg");
|
||||
```
|
||||
|
||||
Note that, a file system driver needs to registered to open images from files. Read more about it [here](https://docs.lvgl.io/master/overview/file-system.html) or just enable one in `lv_conf.h` with `LV_USE_FS_...`
|
||||
|
||||
|
||||
|
||||
## Converter
|
||||
|
||||
### Converting JPG to C array
|
||||
- Use lvgl online tool https://lvgl.io/tools/imageconverter
|
||||
- Color format = RAW, output format = C Array
|
||||
|
||||
### Converting JPG to SJPG
|
||||
python3 and the PIL library required. (PIL can be installed with `pip3 install pillow`)
|
||||
|
||||
To create SJPG from JPG:
|
||||
- Copy the image to convert into `lvgl/scripts`
|
||||
- `cd lvgl/scripts`
|
||||
- `python3 jpg_to_sjpg.py image_to_convert.jpg`. It creates both a C files and an SJPG image.
|
||||
|
||||
The expected result is:
|
||||
```sh
|
||||
Conversion started...
|
||||
|
||||
Input:
|
||||
image_to_convert.jpg
|
||||
RES = 640 x 480
|
||||
|
||||
Output:
|
||||
Time taken = 1.66 sec
|
||||
bin size = 77.1 KB
|
||||
walpaper.sjpg (bin file)
|
||||
walpaper.c (c array)
|
||||
|
||||
All good!
|
||||
```
|
||||
|
||||
|
||||
## Example
|
||||
```eval_rst
|
||||
|
||||
.. include:: ../../examples/libs/sjpg/index.rst
|
||||
|
||||
```
|
||||
|
||||
## API
|
||||
|
||||
```eval_rst
|
||||
|
||||
.. doxygenfile:: lv_sjpg.h
|
||||
:project: lvgl
|
||||
96
docs/libs/sjpg.rst
Normal file
96
docs/libs/sjpg.rst
Normal file
@@ -0,0 +1,96 @@
|
||||
===========
|
||||
JPG decoder
|
||||
===========
|
||||
|
||||
Allow the use of JPG images in LVGL. Besides that it also allows the use
|
||||
of a custom format, called Split JPG (SJPG), which can be decoded in
|
||||
more optimal way on embedded systems.
|
||||
|
||||
Overview
|
||||
--------
|
||||
|
||||
- Supports both normal JPG and the custom SJPG formats.
|
||||
- Decoding normal JPG consumes RAM with the size fo the whole
|
||||
uncompressed image (recommended only for devices with more RAM)
|
||||
- SJPG is a custom format based on “normal” JPG and specially made for
|
||||
LVGL.
|
||||
- SJPG is ‘split-jpeg’ which is a bundle of small jpeg fragments with
|
||||
an sjpg header.
|
||||
- SJPG size will be almost comparable to the jpg file or might be a
|
||||
slightly larger.
|
||||
- File read from file and c-array are implemented.
|
||||
- SJPEG frame fragment cache enables fast fetching of lines if
|
||||
available in cache.
|
||||
- By default the sjpg image cache will be image width \* 2 \* 16 bytes
|
||||
(can be modified)
|
||||
- Currently only 16 bit image format is supported (TODO)
|
||||
- Only the required partion of the JPG and SJPG images are decoded,
|
||||
therefore they can’t be zoomed or rotated.
|
||||
|
||||
Usage
|
||||
-----
|
||||
|
||||
If enabled in ``lv_conf.h`` by :c:macro:`LV_USE_SJPG` LVGL will register a new
|
||||
image decoder automatically so JPG and SJPG files can be directly used
|
||||
as image sources. For example:
|
||||
|
||||
.. code:: c
|
||||
|
||||
lv_img_set_src(my_img, "S:path/to/picture.jpg");
|
||||
|
||||
Note that, a file system driver needs to registered to open images from
|
||||
files. Read more about it :ref:`file-system` or just
|
||||
enable one in ``lv_conf.h`` with ``LV_USE_FS_...``
|
||||
|
||||
Converter
|
||||
---------
|
||||
|
||||
Converting JPG to C array
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
- Use lvgl online tool https://lvgl.io/tools/imageconverter
|
||||
- Color format = RAW, output format = C Array
|
||||
|
||||
Converting JPG to SJPG
|
||||
~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
python3 and the PIL library required. (PIL can be installed with ``pip3 install pillow``)
|
||||
|
||||
To create SJPG from JPG: - Copy the image to convert into
|
||||
``lvgl/scripts`` - ``cd lvgl/scripts`` -
|
||||
``python3 jpg_to_sjpg.py image_to_convert.jpg``. It creates both a C
|
||||
files and an SJPG image.
|
||||
|
||||
The expected result is:
|
||||
|
||||
.. code:: sh
|
||||
|
||||
Conversion started...
|
||||
|
||||
Input:
|
||||
image_to_convert.jpg
|
||||
RES = 640 x 480
|
||||
|
||||
Output:
|
||||
Time taken = 1.66 sec
|
||||
bin size = 77.1 KB
|
||||
walpaper.sjpg (bin file)
|
||||
walpaper.c (c array)
|
||||
|
||||
All good!
|
||||
|
||||
|
||||
Example
|
||||
-------
|
||||
|
||||
.. include:: ../examples/libs/sjpg/index.rst
|
||||
|
||||
|
||||
API
|
||||
---
|
||||
|
||||
:ref:`lv_sjpg`
|
||||
|
||||
:ref:`tjpgd`
|
||||
|
||||
:ref:`tjpgdcnf`
|
||||
@@ -1,29 +0,0 @@
|
||||
# Tiny TTF font engine
|
||||
|
||||
## Usage
|
||||
|
||||
Allow using TrueType fonts LVGL. Based on https://github.com/nothings/stb
|
||||
|
||||
When enabled in `lv_conf.h` with `LV_USE_TINY_TTF` `lv_tiny_ttf_create_data(data, data_size, line_height)` can be used to create a TTF font instance at the specified line height. You can then use that font anywhere `lv_font_t` is accepted.
|
||||
|
||||
By default, the TTF or OTF file must be embedded as an array, either in a header, or loaded into RAM in order to function.
|
||||
|
||||
However, if `LV_TINY_TTF_FILE_SUPPORT` is enabled, `lv_tiny_ttf_create_file(path, line_height)` will also be available, allowing tiny_ttf to stream from a file. The file must remain open the entire time the font is being used.
|
||||
|
||||
After a font is created, you can change the size by using `lv_tiny_ttf_set_size(font, line_height)`.
|
||||
|
||||
By default, a font will use up to 4KB of cache to speed up rendering glyphs. This maximum can be changed by using `lv_tiny_ttf_create_data_ex(data, data_size, line_height, cache_size)` or `lv_tiny_ttf_create_file_ex(path, line_height, cache_size)` (when available). The cache size is indicated in bytes.
|
||||
|
||||
## Example
|
||||
```eval_rst
|
||||
|
||||
.. include:: ../../examples/libs/tiny_ttf/index.rst
|
||||
|
||||
```
|
||||
|
||||
## API
|
||||
|
||||
```eval_rst
|
||||
|
||||
.. doxygenfile:: lv_tiny_ttf.h
|
||||
:project: lvgl
|
||||
46
docs/libs/tiny_ttf.rst
Normal file
46
docs/libs/tiny_ttf.rst
Normal file
@@ -0,0 +1,46 @@
|
||||
====================
|
||||
Tiny TTF font engine
|
||||
====================
|
||||
|
||||
Usage
|
||||
-----
|
||||
|
||||
Allow using TrueType fonts LVGL. Based on
|
||||
https://github.com/nothings/stb
|
||||
|
||||
When enabled in ``lv_conf.h`` with :c:macro:`LV_USE_TINY_TTF`
|
||||
:c:expr:`lv_tiny_ttf_create_data(data, data_size, line_height)` can be used to
|
||||
create a TTF font instance at the specified line height. You can then
|
||||
use that font anywhere :c:struct:`lv_font_t` is accepted.
|
||||
|
||||
By default, the TTF or OTF file must be embedded as an array, either in
|
||||
a header, or loaded into RAM in order to function.
|
||||
|
||||
However, if :c:macro:`LV_TINY_TTF_FILE_SUPPORT` is enabled,
|
||||
:c:expr:`lv_tiny_ttf_create_file(path, line_height)` will also be available,
|
||||
allowing tiny_ttf to stream from a file. The file must remain open the
|
||||
entire time the font is being used.
|
||||
|
||||
After a font is created, you can change the size by using
|
||||
:c:expr:`lv_tiny_ttf_set_size(font, line_height)`.
|
||||
|
||||
By default, a font will use up to 4KB of cache to speed up rendering
|
||||
glyphs. This maximum can be changed by using
|
||||
:c:expr:`lv_tiny_ttf_create_data_ex(data, data_size, line_height, cache_size)`
|
||||
or :c:expr:`lv_tiny_ttf_create_file_ex(path, line_height, cache_size)` (when
|
||||
available). The cache size is indicated in bytes.
|
||||
|
||||
Example
|
||||
-------
|
||||
|
||||
.. include:: ../examples/libs/tiny_ttf/index.rst
|
||||
|
||||
|
||||
API
|
||||
---
|
||||
|
||||
:ref:`lv_tiny_ttf`
|
||||
|
||||
:ref:`stb_rect_pack`
|
||||
|
||||
:ref:`stb_truetype_htcw`
|
||||
@@ -1,161 +0,0 @@
|
||||
# File Explorer
|
||||
|
||||
`lv_file_explorer` provides an API to browse the contents of the file system. `lv_file_explorer` only provides the file browsing function, but does not provide the actual file operation function. In other words, you can't click a picture file to open and view the picture like a PC. `lv_file_explorer` will tell you the full path and name of the currently clicked file. The file operation function needs to be implemented by the user.
|
||||
|
||||
|
||||
The file list in `lv_file_explorer` is based on [lv_table](/widgets/table), and the quick access bar is based on [lv_list](/widgets/list). Therefore, care should be taken to ensure that [lv_table](/widgets/table) and [lv_list](/widgets/list) are enabled.
|
||||
|
||||
<details>
|
||||
<summary>中文</summary>
|
||||
<p>
|
||||
|
||||
`lv_file_explorer` 提供API让我们可以浏览文件系统中的内容。`lv_file_explorer` 只提供了文件浏览功能,并不提供实际的文件操作功能,也就是说,不能像PC那样点击一个图片文件就可以打开查看该图片。`lv_file_explorer` 会告诉您当前点击的文件的完整路径和名称,文件操作功能需要用户自己实现。
|
||||
|
||||
`lv_file_explorer` 中的文件列表基于 [lv_table](/widgets/table) 实现,快速访问栏基于 [lv_list](/widgets/list) 实现。因此,要注意确保使能了 `lv_table` 和 `lv_list`。
|
||||
|
||||
|
||||
</p>
|
||||
</details>
|
||||
|
||||
## Usage
|
||||
|
||||
Enable `LV_USE_FILE_EXPLORER` in `lv_conf.h`.
|
||||
|
||||
First use `lv_file_explorer_create(lv_scr_act())` to create a file explorer, The default size is the screen size. After that, you can customize the style like widget.
|
||||
|
||||
<details>
|
||||
<summary>中文</summary>
|
||||
<p>
|
||||
|
||||
在 `lv_conf.h` 中打开 `LV_USE_FILE_EXPLORER`。
|
||||
|
||||
首先,使用 `lv_file_explorer_create(lv_scr_act())` 函数创建一个文件浏览器,默认大小为屏幕大小,之后可以像组件那样自定义样式。
|
||||
|
||||
</p>
|
||||
</details>
|
||||
|
||||
|
||||
### Quick access
|
||||
|
||||
The quick access bar is optional. You can turn off `LV_FILE_EXPLORER_QUICK_ACCESS` in `lv_conf.h` so that the quick access bar will not be created. This can save some memory, but not much. After the quick access bar is created, it can be hidden by clicking the button at the top left corner of the browsing area, which is very useful for small screen devices.
|
||||
|
||||
You can use `lv_file_explorer_set_quick_access_path(file_explorer, LV_FILE_EXPLORER_QA_XX, "path")` to set the path of the quick access bar. The items of the quick access bar are fixed. Currently, there are the following items:
|
||||
|
||||
- `LV_FILE_EXPLORER_QA_HOME`
|
||||
- `LV_FILE_EXPLORER_QA_MUSIC`
|
||||
- `LV_FILE_EXPLORER_QA_PICTURES`
|
||||
- `LV_FILE_EXPLORER_QA_VIDEO`
|
||||
- `LV_FILE_EXPLORER_QA_DOCS`
|
||||
- `LV_FILE_EXPLORER_QA_MNT`
|
||||
- `LV_FILE_EXPLORER_QA_FS`
|
||||
|
||||
<details>
|
||||
<summary>中文</summary>
|
||||
<p>
|
||||
|
||||
快速访问栏是可选的,您可以在 `lv_conf.h` 中关闭 `LV_FILE_EXPLORER_QUICK_ACCESS`,这样快速访问栏就不会被创建出来,这能节省一些内存,但并不是很多。快速访问栏被创建出来之后,可以通过点击浏览区域顶部左上角的按钮隐藏起来,这对于小屏幕设备非常有用。
|
||||
|
||||
可以通过 `lv_file_explorer_set_quick_access_path(file_explorer, LV_FILE_EXPLORER_QA_XX, "path")` 设置快速访问栏的路径,快速访问栏的项目是固定的,目前有以下项目:
|
||||
|
||||
- `LV_FILE_EXPLORER_QA_HOME`
|
||||
- `LV_FILE_EXPLORER_QA_MUSIC`
|
||||
- `LV_FILE_EXPLORER_QA_PICTURES`
|
||||
- `LV_FILE_EXPLORER_QA_VIDEO`
|
||||
- `LV_FILE_EXPLORER_QA_DOCS`
|
||||
- `LV_FILE_EXPLORER_QA_MNT`
|
||||
- `LV_FILE_EXPLORER_QA_FS`
|
||||
|
||||
</p>
|
||||
</details>
|
||||
|
||||
### Sort
|
||||
|
||||
You can use `lv_file_explorer_set_sort(file_explorer, LV_EXPLORER_SORT_XX)` to set sorting method. There are the following sorting methods:
|
||||
|
||||
- `LV_EXPLORER_SORT_NONE`
|
||||
- `LV_EXPLORER_SORT_KIND`
|
||||
|
||||
You can customize the sorting. Before custom sort, please set the default sorting to `LV_EXPLORER_SORT_NONE`. The default is `LV_EXPLORER_SORT_NONE`.
|
||||
|
||||
<details>
|
||||
<summary>中文</summary>
|
||||
<p>
|
||||
|
||||
可以通过 `lv_file_explorer_set_sort(file_explorer, LV_EXPLORER_SORT_XX)` 设置排序方式,有以下排序方式:
|
||||
|
||||
- `LV_EXPLORER_SORT_NONE`
|
||||
- `LV_EXPLORER_SORT_KIND`
|
||||
|
||||
您可以自定义排序规则,在这之前请先将排序规则设置为 `LV_EXPLORER_SORT_NONE` 然后在 `LV_EVENT_READY` 事件中处理。默认的排序规则是 `LV_EXPLORER_SORT_NONE`
|
||||
|
||||
</p>
|
||||
</details>
|
||||
|
||||
## Event
|
||||
|
||||
- `LV_EVENT_READY` sent shen a directory is opened. You can customize the sort.
|
||||
|
||||
- `LV_EVENT_VALUE_CHANGED` sent when an item(file) in the file list is clicked.
|
||||
|
||||
You can use `lv_file_explorer_get_cur_path` to get the current path and `lv_file_explorer_get_sel_fn` to get the name of the currently selected file in the event processing function. For example:
|
||||
|
||||
```c
|
||||
static void file_explorer_event_handler(lv_event_t * e)
|
||||
{
|
||||
lv_event_code_t code = lv_event_get_code(e);
|
||||
lv_obj_t * obj = lv_event_get_target(e);
|
||||
|
||||
if(code == LV_EVENT_VALUE_CHANGED) {
|
||||
char * cur_path = lv_file_explorer_get_cur_path(obj);
|
||||
char * sel_fn = lv_file_explorer_get_sel_fn(obj);
|
||||
LV_LOG_USER("%s%s", cur_path, sel_fn);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
You can also save the obtained **path** and **file** name into an array through functions such as *strcpy* and *strcat* for later use.
|
||||
|
||||
<details>
|
||||
<summary>中文</summary>
|
||||
<p>
|
||||
|
||||
- 当打开一个目录后会发送 `LV_EVENT_READY` 事件。您可以在这里自定义排序规则。
|
||||
- 当文件列表中的项目(文件)被点击时会发送 `LV_EVENT_VALUE_CHANGED` 事件。
|
||||
|
||||
可以在事件处理函数中通过 `lv_file_explorer_get_cur_path` 获取当前所在的路径,通过 `lv_file_explorer_get_sel_fn` 获取当前选中的文件的名称。比如:
|
||||
|
||||
```c
|
||||
static void file_explorer_event_handler(lv_event_t * e)
|
||||
{
|
||||
lv_event_code_t code = lv_event_get_code(e);
|
||||
lv_obj_t * obj = lv_event_get_target(e);
|
||||
|
||||
if(code == LV_EVENT_VALUE_CHANGED) {
|
||||
char * cur_path = lv_file_explorer_get_cur_path(obj);
|
||||
char * sel_fn = lv_file_explorer_get_sel_fn(obj);
|
||||
LV_LOG_USER("%s%s", cur_path, sel_fn);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
您还可以将获取到的 **路径** 和 **文件名称** 通过例如 strcpy 和 strcat 函数保存到一个数组中,方便后续使用。
|
||||
|
||||
</p>
|
||||
</details>
|
||||
|
||||
## Example
|
||||
|
||||
```eval_rst
|
||||
|
||||
.. include:: ../../examples/others/file_explorer/index.rst
|
||||
|
||||
```
|
||||
|
||||
## API
|
||||
|
||||
```eval_rst
|
||||
|
||||
.. doxygenfile:: lv_file_explorer.h
|
||||
:project: lvgl
|
||||
|
||||
```
|
||||
299
docs/others/file_explorer.rst
Normal file
299
docs/others/file_explorer.rst
Normal file
@@ -0,0 +1,299 @@
|
||||
=============
|
||||
File Explorer
|
||||
=============
|
||||
|
||||
``lv_file_explorer`` provides an API to browse the contents of the file
|
||||
system. ``lv_file_explorer`` only provides the file browsing function,
|
||||
but does not provide the actual file operation function. In other words,
|
||||
you can’t click a picture file to open and view the picture like a PC.
|
||||
``lv_file_explorer`` will tell you the full path and name of the
|
||||
currently clicked file. The file operation function needs to be
|
||||
implemented by the user.
|
||||
|
||||
The file list in ``lv_file_explorer`` is based on
|
||||
`lv_table </widgets/table>`__, and the quick access bar is based on
|
||||
`lv_list </widgets/list>`__. Therefore, care should be taken to ensure
|
||||
that `lv_table </widgets/table>`__ and `lv_list </widgets/list>`__ are
|
||||
enabled.
|
||||
|
||||
.. raw:: html
|
||||
|
||||
<details>
|
||||
|
||||
.. raw:: html
|
||||
|
||||
<summary>
|
||||
|
||||
中文
|
||||
|
||||
.. raw:: html
|
||||
|
||||
</summary>
|
||||
|
||||
.. raw:: html
|
||||
|
||||
<p>
|
||||
|
||||
``lv_file_explorer``
|
||||
提供API让我们可以浏览文件系统中的内容。\ ``lv_file_explorer``
|
||||
只提供了文件浏览功能,并不提供实际的文件操作功能,也就是说,不能像PC那样点击一个图片文件就可以打开查看该图片。\ ``lv_file_explorer``
|
||||
会告诉您当前点击的文件的完整路径和名称,文件操作功能需要用户自己实现。
|
||||
|
||||
``lv_file_explorer`` 中的文件列表基于 `lv_table </widgets/table>`__
|
||||
实现,快速访问栏基于 `lv_list </widgets/list>`__
|
||||
实现。因此,要注意确保使能了 ``lv_table`` 和 ``lv_list``\ 。
|
||||
|
||||
.. raw:: html
|
||||
|
||||
</p>
|
||||
|
||||
.. raw:: html
|
||||
|
||||
</details>
|
||||
|
||||
Usage
|
||||
-----
|
||||
|
||||
Enable :c:macro:`LV_USE_FILE_EXPLORER` in ``lv_conf.h``.
|
||||
|
||||
First use :c:expr:`lv_file_explorer_create(lv_scr_act())` to create a file
|
||||
explorer, The default size is the screen size. After that, you can
|
||||
customize the style like widget.
|
||||
|
||||
.. raw:: html
|
||||
|
||||
<details>
|
||||
|
||||
.. raw:: html
|
||||
|
||||
<summary>
|
||||
|
||||
中文
|
||||
|
||||
.. raw:: html
|
||||
|
||||
</summary>
|
||||
|
||||
.. raw:: html
|
||||
|
||||
<p>
|
||||
|
||||
在 ``lv_conf.h`` 中打开 :c:macro:`LV_USE_FILE_EXPLORER`\ 。
|
||||
|
||||
首先,使用 :c:expr:`lv_file_explorer_create(lv_scr_act())`
|
||||
函数创建一个文件浏览器,默认大小为屏幕大小,之后可以像组件那样自定义样式。
|
||||
|
||||
.. raw:: html
|
||||
|
||||
</p>
|
||||
|
||||
.. raw:: html
|
||||
|
||||
</details>
|
||||
|
||||
Quick access
|
||||
~~~~~~~~~~~~
|
||||
|
||||
The quick access bar is optional. You can turn off
|
||||
:c:macro:`LV_FILE_EXPLORER_QUICK_ACCESS` in ``lv_conf.h`` so that the quick
|
||||
access bar will not be created. This can save some memory, but not much.
|
||||
After the quick access bar is created, it can be hidden by clicking the
|
||||
button at the top left corner of the browsing area, which is very useful
|
||||
for small screen devices.
|
||||
|
||||
You can use
|
||||
:c:expr:`lv_file_explorer_set_quick_access_path(file_explorer, LV_FILE_EXPLORER_QA_XX, "path")`
|
||||
to set the path of the quick access bar. The items of the quick access
|
||||
bar are fixed. Currently, there are the following items:
|
||||
|
||||
- :c:enumerator:`LV_FILE_EXPLORER_QA_HOME`
|
||||
- :c:enumerator:`LV_FILE_EXPLORER_QA_MUSIC`
|
||||
- :c:enumerator:`LV_FILE_EXPLORER_QA_PICTURES`
|
||||
- :c:enumerator:`LV_FILE_EXPLORER_QA_VIDEO`
|
||||
- :c:enumerator:`LV_FILE_EXPLORER_QA_DOCS`
|
||||
- :c:enumerator:`LV_FILE_EXPLORER_QA_MNT`
|
||||
- :c:enumerator:`LV_FILE_EXPLORER_QA_FS`
|
||||
|
||||
.. raw:: html
|
||||
|
||||
<details>
|
||||
|
||||
.. raw:: html
|
||||
|
||||
<summary>
|
||||
|
||||
中文
|
||||
|
||||
.. raw:: html
|
||||
|
||||
</summary>
|
||||
|
||||
.. raw:: html
|
||||
|
||||
<p>
|
||||
|
||||
快速访问栏是可选的,您可以在 ``lv_conf.h`` 中关闭
|
||||
:c:macro:`LV_FILE_EXPLORER_QUICK_ACCESS`\ ,这样快速访问栏就不会被创建出来,这能节省一些内存,但并不是很多。快速访问栏被创建出来之后,可以通过点击浏览区域顶部左上角的按钮隐藏起来,这对于小屏幕设备非常有用。
|
||||
|
||||
可以通过
|
||||
:c:expr:`lv_file_explorer_set_quick_access_path(file_explorer, LV_FILE_EXPLORER_QA_XX, "path")`
|
||||
设置快速访问栏的路径,快速访问栏的项目是固定的,目前有以下项目:
|
||||
|
||||
- :c:enumerator:`LV_FILE_EXPLORER_QA_HOME`
|
||||
- :c:enumerator:`LV_FILE_EXPLORER_QA_MUSIC`
|
||||
- :c:enumerator:`LV_FILE_EXPLORER_QA_PICTURES`
|
||||
- :c:enumerator:`LV_FILE_EXPLORER_QA_VIDEO`
|
||||
- :c:enumerator:`LV_FILE_EXPLORER_QA_DOCS`
|
||||
- :c:enumerator:`LV_FILE_EXPLORER_QA_MNT`
|
||||
- :c:enumerator:`LV_FILE_EXPLORER_QA_FS`
|
||||
|
||||
.. raw:: html
|
||||
|
||||
</p>
|
||||
|
||||
.. raw:: html
|
||||
|
||||
</details>
|
||||
|
||||
Sort
|
||||
~~~~
|
||||
|
||||
You can use
|
||||
:c:expr:`lv_file_explorer_set_sort(file_explorer, LV_EXPLORER_SORT_XX)` to set
|
||||
sorting method. There are the following sorting methods:
|
||||
|
||||
- :c:enumerator:`LV_EXPLORER_SORT_NONE`
|
||||
- :c:enumerator:`LV_EXPLORER_SORT_KIND`
|
||||
|
||||
You can customize the sorting. Before custom sort, please set the
|
||||
default sorting to :c:enumerator:`LV_EXPLORER_SORT_NONE`. The default is
|
||||
:c:enumerator:`LV_EXPLORER_SORT_NONE`.
|
||||
|
||||
.. raw:: html
|
||||
|
||||
<details>
|
||||
|
||||
.. raw:: html
|
||||
|
||||
<summary>
|
||||
|
||||
中文
|
||||
|
||||
.. raw:: html
|
||||
|
||||
</summary>
|
||||
|
||||
.. raw:: html
|
||||
|
||||
<p>
|
||||
|
||||
可以通过
|
||||
:c:expr:`lv_file_explorer_set_sort(file_explorer, LV_EXPLORER_SORT_XX)`
|
||||
设置排序方式,有以下排序方式:
|
||||
|
||||
- :c:enumerator:`LV_EXPLORER_SORT_NONE`
|
||||
- :c:enumerator:`LV_EXPLORER_SORT_KIND`
|
||||
|
||||
您可以自定义排序规则,在这之前请先将排序规则设置为
|
||||
:c:enumerator:`LV_EXPLORER_SORT_NONE` 然后在 :c:enumerator:`LV_EVENT_READY`
|
||||
事件中处理。默认的排序规则是 :c:enumerator:`LV_EXPLORER_SORT_NONE`
|
||||
|
||||
.. raw:: html
|
||||
|
||||
</p>
|
||||
|
||||
.. raw:: html
|
||||
|
||||
</details>
|
||||
|
||||
Event
|
||||
-----
|
||||
|
||||
- :c:enumerator:`LV_EVENT_READY` sent shen a directory is opened. You can customize
|
||||
the sort.
|
||||
|
||||
- :c:enumerator:`LV_EVENT_VALUE_CHANGED` sent when an item(file) in the file list
|
||||
is clicked.
|
||||
|
||||
You can use :c:func:`lv_file_explorer_get_cur_path` to get the current path
|
||||
and :c:func:`lv_file_explorer_get_sel_fn` to get the name of the currently
|
||||
selected file in the event processing function. For example:
|
||||
|
||||
.. code:: c
|
||||
|
||||
static void file_explorer_event_handler(lv_event_t * e)
|
||||
{
|
||||
lv_event_code_t code = lv_event_get_code(e);
|
||||
lv_obj_t * obj = lv_event_get_target(e);
|
||||
|
||||
if(code == LV_EVENT_VALUE_CHANGED) {
|
||||
char * cur_path = lv_file_explorer_get_cur_path(obj);
|
||||
char * sel_fn = lv_file_explorer_get_sel_fn(obj);
|
||||
LV_LOG_USER("%s%s", cur_path, sel_fn);
|
||||
}
|
||||
}
|
||||
|
||||
You can also save the obtained **path** and **file** name into an array
|
||||
through functions such as *strcpy* and *strcat* for later use.
|
||||
|
||||
.. raw:: html
|
||||
|
||||
<details>
|
||||
|
||||
.. raw:: html
|
||||
|
||||
<summary>
|
||||
|
||||
中文
|
||||
|
||||
.. raw:: html
|
||||
|
||||
</summary>
|
||||
|
||||
.. raw:: html
|
||||
|
||||
<p>
|
||||
|
||||
- 当打开一个目录后会发送 :c:enumerator:`LV_EVENT_READY`
|
||||
事件。您可以在这里自定义排序规则。
|
||||
- 当文件列表中的项目(文件)被点击时会发送 :c:enumerator:`LV_EVENT_VALUE_CHANGED`
|
||||
事件。
|
||||
|
||||
可以在事件处理函数中通过 :c:func:`lv_file_explorer_get_cur_path`
|
||||
获取当前所在的路径,通过 :c:func:`lv_file_explorer_get_sel_fn`
|
||||
获取当前选中的文件的名称。比如:
|
||||
|
||||
.. code:: c
|
||||
|
||||
static void file_explorer_event_handler(lv_event_t * e)
|
||||
{
|
||||
lv_event_code_t code = lv_event_get_code(e);
|
||||
lv_obj_t * obj = lv_event_get_target(e);
|
||||
|
||||
if(code == LV_EVENT_VALUE_CHANGED) {
|
||||
char * cur_path = lv_file_explorer_get_cur_path(obj);
|
||||
char * sel_fn = lv_file_explorer_get_sel_fn(obj);
|
||||
LV_LOG_USER("%s%s", cur_path, sel_fn);
|
||||
}
|
||||
}
|
||||
|
||||
您还可以将获取到的 **路径** 和 **文件名称** 通过例如 strcpy 和 strcat
|
||||
函数保存到一个数组中,方便后续使用。
|
||||
|
||||
.. raw:: html
|
||||
|
||||
</p>
|
||||
|
||||
.. raw:: html
|
||||
|
||||
</details>
|
||||
|
||||
Example
|
||||
-------
|
||||
|
||||
.. include:: ../examples/others/file_explorer/index.rst
|
||||
|
||||
API
|
||||
---
|
||||
|
||||
:ref:`lv_file_explorer`
|
||||
@@ -1,77 +0,0 @@
|
||||
|
||||
# Fragment
|
||||
|
||||
Fragment is a concept copied from [Android](https://developer.android.com/guide/fragments).
|
||||
|
||||
It represents a reusable portion of your app's UI. A fragment defines and manages its own layout, has its own lifecycle,
|
||||
and can handle its own events. Like Android's Fragment that must be hosted by an activity or another fragment, Fragment
|
||||
in LVGL needs to be hosted by an object, or another fragment. The fragment’s view hierarchy becomes part of, or attaches
|
||||
to, the host’s view hierarchy.
|
||||
|
||||
Such concept also has some similarities
|
||||
to [UiViewController on iOS](https://developer.apple.com/documentation/uikit/uiviewcontroller).
|
||||
|
||||
Fragment Manager is a manager holding references to fragments attached to it, and has an internal stack to achieve
|
||||
navigation. You can use fragment manager to build navigation stack, or multi pane application easily.
|
||||
|
||||
## Usage
|
||||
|
||||
Enable `LV_USE_FRAGMENT` in `lv_conf.h`.
|
||||
|
||||
### Create Fragment Class
|
||||
|
||||
```c
|
||||
struct sample_fragment_t {
|
||||
/* IMPORTANT: don't miss this part */
|
||||
lv_fragment_t base;
|
||||
/* States, object references and data fields for this fragment */
|
||||
const char *title;
|
||||
};
|
||||
|
||||
const lv_fragment_class_t sample_cls = {
|
||||
/* Initialize something needed */
|
||||
.constructor_cb = sample_fragment_ctor,
|
||||
/* Create view objects */
|
||||
.create_obj_cb = sample_fragment_create_obj,
|
||||
/* IMPORTANT: size of your fragment struct */
|
||||
.instance_size = sizeof(struct sample_fragment_t)
|
||||
};
|
||||
```
|
||||
|
||||
### Use `lv_fragment_manager`
|
||||
|
||||
```c
|
||||
/* Create fragment instance, and objects will be added to container */
|
||||
lv_fragment_manager_t *manager = lv_fragment_manager_create(container, NULL);
|
||||
/* Replace current fragment with instance of sample_cls, and init_argument is user defined pointer */
|
||||
lv_fragment_manager_replace(manager, &sample_cls, init_argument);
|
||||
```
|
||||
|
||||
### Fragment Based Navigation
|
||||
|
||||
```c
|
||||
/* Add one instance into manager stack. View object of current fragment will be destroyed,
|
||||
* but instances created in class constructor will be kept.
|
||||
*/
|
||||
lv_fragment_manager_push(manager, &sample_cls, NULL);
|
||||
|
||||
/* Remove the top most fragment from the stack, and bring back previous one. */
|
||||
lv_fragment_manager_pop(manager);
|
||||
```
|
||||
|
||||
## Example
|
||||
|
||||
```eval_rst
|
||||
|
||||
.. include:: ../../examples/others/fragment/index.rst
|
||||
|
||||
```
|
||||
|
||||
## API
|
||||
|
||||
```eval_rst
|
||||
|
||||
.. doxygenfile:: lv_fragment.h
|
||||
:project: lvgl
|
||||
|
||||
```
|
||||
80
docs/others/fragment.rst
Normal file
80
docs/others/fragment.rst
Normal file
@@ -0,0 +1,80 @@
|
||||
========
|
||||
Fragment
|
||||
========
|
||||
|
||||
Fragment is a concept copied from
|
||||
`Android <https://developer.android.com/guide/fragments>`__.
|
||||
|
||||
It represents a reusable portion of your app’s UI. A fragment defines
|
||||
and manages its own layout, has its own lifecycle, and can handle its
|
||||
own events. Like Android’s Fragment that must be hosted by an activity
|
||||
or another fragment, Fragment in LVGL needs to be hosted by an object,
|
||||
or another fragment. The fragment’s view hierarchy becomes part of, or
|
||||
attaches to, the host’s view hierarchy.
|
||||
|
||||
Such concept also has some similarities to `UiViewController on
|
||||
iOS <https://developer.apple.com/documentation/uikit/uiviewcontroller>`__.
|
||||
|
||||
Fragment Manager is a manager holding references to fragments attached
|
||||
to it, and has an internal stack to achieve navigation. You can use
|
||||
fragment manager to build navigation stack, or multi pane application
|
||||
easily.
|
||||
|
||||
Usage
|
||||
-----
|
||||
|
||||
Enable :c:macro:`LV_USE_FRAGMENT` in ``lv_conf.h``.
|
||||
|
||||
Create Fragment Class
|
||||
~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
.. code:: c
|
||||
|
||||
struct sample_fragment_t {
|
||||
/* IMPORTANT: don't miss this part */
|
||||
lv_fragment_t base;
|
||||
/* States, object references and data fields for this fragment */
|
||||
const char *title;
|
||||
};
|
||||
|
||||
const lv_fragment_class_t sample_cls = {
|
||||
/* Initialize something needed */
|
||||
.constructor_cb = sample_fragment_ctor,
|
||||
/* Create view objects */
|
||||
.create_obj_cb = sample_fragment_create_obj,
|
||||
/* IMPORTANT: size of your fragment struct */
|
||||
.instance_size = sizeof(struct sample_fragment_t)
|
||||
};
|
||||
|
||||
Use ``lv_fragment_manager``
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
.. code:: c
|
||||
|
||||
/* Create fragment instance, and objects will be added to container */
|
||||
lv_fragment_manager_t *manager = lv_fragment_manager_create(container, NULL);
|
||||
/* Replace current fragment with instance of sample_cls, and init_argument is user defined pointer */
|
||||
lv_fragment_manager_replace(manager, &sample_cls, init_argument);
|
||||
|
||||
Fragment Based Navigation
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
.. code:: c
|
||||
|
||||
/* Add one instance into manager stack. View object of current fragment will be destroyed,
|
||||
* but instances created in class constructor will be kept.
|
||||
*/
|
||||
lv_fragment_manager_push(manager, &sample_cls, NULL);
|
||||
|
||||
/* Remove the top most fragment from the stack, and bring back previous one. */
|
||||
lv_fragment_manager_pop(manager);
|
||||
|
||||
Example
|
||||
-------
|
||||
|
||||
.. include:: ../examples/others/fragment/index.rst
|
||||
|
||||
API
|
||||
---
|
||||
|
||||
:ref:`lv_fragment`
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user