Compare commits
106 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7dfb4eb374 | ||
|
|
b424927b80 | ||
|
|
42f040f885 | ||
|
|
f776a8f1cf | ||
|
|
9fddc294ab | ||
|
|
7fdd633561 | ||
|
|
b8080ef1db | ||
|
|
e044e02541 | ||
|
|
22dabf9c2a | ||
|
|
96a43ba3c5 | ||
|
|
a8721ff3c3 | ||
|
|
d15980cdd3 | ||
|
|
2e60555506 | ||
|
|
692a4b33c8 | ||
|
|
da0a235a33 | ||
|
|
77e1dc21bb | ||
|
|
94b6be4c3d | ||
|
|
1ff5f1f91d | ||
|
|
3e053db00b | ||
|
|
317c8f40da | ||
|
|
267d0d96af | ||
|
|
660a986e04 | ||
|
|
b83023703b | ||
|
|
740eaa56b7 | ||
|
|
5b06a41ebc | ||
|
|
894d5f5861 | ||
|
|
969640717f | ||
|
|
d69c18dba4 | ||
|
|
125b199f85 | ||
|
|
4924e871b2 | ||
|
|
4ab5d9459e | ||
|
|
ff3f2ed80c | ||
|
|
dee00b08cc | ||
|
|
3052681761 | ||
|
|
a90aa4211b | ||
|
|
09f8e25fdd | ||
|
|
702ba26dd8 | ||
|
|
7284aa0d05 | ||
|
|
fb5cee3b56 | ||
|
|
d9147ae21b | ||
|
|
1749a0e7e1 | ||
|
|
3a7d160bfa | ||
|
|
958ad5f999 | ||
|
|
178f42b89a | ||
|
|
cd15f653f6 | ||
|
|
6e1a32e891 | ||
|
|
0c1e3239b7 | ||
|
|
e6b6c3a19c | ||
|
|
f547a7dbc2 | ||
|
|
fa8846a2ce | ||
|
|
e4cf96cb81 | ||
|
|
9b51181575 | ||
|
|
22d79cd585 | ||
|
|
25651261c2 | ||
|
|
687dea0543 | ||
|
|
55b7a9f513 | ||
|
|
61881ca7cd | ||
|
|
2ab2a5a973 | ||
|
|
d3a07c866f | ||
|
|
7c3263bc7b | ||
|
|
053e70342c | ||
|
|
46f51b1d67 | ||
|
|
81e84ed829 | ||
|
|
04197a83d0 | ||
|
|
931e74e2a6 | ||
|
|
7b26cdc75e | ||
|
|
c72c8c62de | ||
|
|
e65f781bbd | ||
|
|
2846cff2d3 | ||
|
|
31fcc7d395 | ||
|
|
ec776b48d5 | ||
|
|
b8226ace04 | ||
|
|
3bf1dde5b2 | ||
|
|
3b3ba1b5df | ||
|
|
d1837d2684 | ||
|
|
fbe39b7357 | ||
|
|
f4b9b2a477 | ||
|
|
af47b4bd40 | ||
|
|
e78c3d132c | ||
|
|
2dbda3d004 | ||
|
|
6d4791c6e9 | ||
|
|
3c2c4c5f86 | ||
|
|
358f7cf00b | ||
|
|
7248eef1f0 | ||
|
|
422481533e | ||
|
|
6cd9fda009 | ||
|
|
c46e31c536 | ||
|
|
a7a24bcf84 | ||
|
|
73d4fd00bd | ||
|
|
e52a2fb87c | ||
|
|
2bdfdc0ed2 | ||
|
|
6b3444271c | ||
|
|
78c5ad0cdb | ||
|
|
df00db0dc2 | ||
|
|
89731ae74a | ||
|
|
592a54f8ee | ||
|
|
9fcb264e05 | ||
|
|
1456853135 | ||
|
|
92ebe1f940 | ||
|
|
cd83e6febc | ||
|
|
9fcb8e0d1b | ||
|
|
adbd978155 | ||
|
|
455676e982 | ||
|
|
faf33212e7 | ||
|
|
8dba219f42 | ||
|
|
ab21e705d5 |
46
docs/CODE_OF_CONDUCT.md
Normal file
46
docs/CODE_OF_CONDUCT.md
Normal file
@@ -0,0 +1,46 @@
|
||||
# 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 at [atom@github.com](mailto:atom@github.com). 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/
|
||||
180
docs/CONTRIBUTING.md
Normal file
180
docs/CONTRIBUTING.md
Normal file
@@ -0,0 +1,180 @@
|
||||
# Contributing to Littlev Graphics Library
|
||||
First of all thank you for reading these guide before contributing!
|
||||
|
||||
In this guide you can read how can you help in developing the Littlev Graphic Library. These are not strict rules rather just suggestions. If you have a constructive idea just create pull request on this document!
|
||||
|
||||
### Table Of Content
|
||||
* [Who can contribute?](#who-can-contribute)
|
||||
* [How to report an issue?](#how-to-report-an-issue)
|
||||
* [Simple issue](#simple-issue)
|
||||
* [Complex issue](#complex-issue)
|
||||
* [How to suggest a feature?](#how-to-suggest-a-feature)
|
||||
* [How to implement a feature?](#how-to-implement-a-feature)
|
||||
* [Styling guide](#styling-guide)
|
||||
* [Git Commit Messages](#Git-commit-messages)
|
||||
* [File format](#file-format)
|
||||
* [Functions](#functions)
|
||||
* [Variables](#variables)
|
||||
* [Defines](#defines)
|
||||
* [Comments](#comments)
|
||||
* [Formatting](#formatting)
|
||||
|
||||
|
||||
## Who can contribute?
|
||||
Everybody is welcome in contributing independently from skills, programming level or any personal attribute.
|
||||
|
||||
There are several ways to contribute in the graphics library like:
|
||||
* Report an issue
|
||||
* Suggest feature
|
||||
* Fix an issue
|
||||
* Implement a feature
|
||||
|
||||
Please, take a look at [CODE_OF_CONDUCT](https://github.com/littlevgl/lvgl/blob/master/docs/CODE_OF_CONDUCT.md)
|
||||
|
||||
## How to report an issue?
|
||||
There are 3 permanent branches:
|
||||
* `master` for stable, released versions
|
||||
* `beta` for developers, all feature branches merged here first
|
||||
* `bugfix` for hotfixes, not new features
|
||||
|
||||
### Simple issue
|
||||
If you find an issue which is very simple to fix, and you fixed it, please send a pull request against `beta` branch.
|
||||
A simple issue could be:
|
||||
* Misspelled names
|
||||
* Comment: misspelling or grammatical error in comments
|
||||
* Variable: misspelled variable name (e.g. ***ojb**_next* instead of ***obj**_next*)
|
||||
* Define: only local defines in files because global defines affect API
|
||||
* Function: only static function name because global functions affect API
|
||||
* Not handled error case:
|
||||
* A parameter can be NULL (during normal usage)
|
||||
* Negative index in array or over indexing
|
||||
* Overflow in variable
|
||||
* Anything which is local an can be fixed with a few lines of code
|
||||
|
||||
### Complex issue
|
||||
If you find a complex issue which:
|
||||
* might be simple but you don't know its origin
|
||||
* affects a whole file, module or even the architecture
|
||||
* needs deeper discussion
|
||||
|
||||
please create a **new issue** and describe
|
||||
* what you experience
|
||||
* how to reproduce the issue (maybe with example code)
|
||||
* version you are using (lvgl.h)
|
||||
* misc library version (misc.h)
|
||||
|
||||
## How to suggest a feature?
|
||||
If you have a good and useful idea you can use GitHub issues to suggest a new feature. Please note the followings on feature requests:
|
||||
* What the new feature is about?
|
||||
* Why/Where/In which case is it useful/helpful/relevant?
|
||||
* Can you help in implementing it?
|
||||
|
||||
After a discussion we figure out the specification of the new feature and the technical details/implementation possibilities.
|
||||
With the knowledge of how to do it somebody can implement the new feature.
|
||||
|
||||
The new feature should be in a new branch.
|
||||
|
||||
Keep in mind if you wouldn't like to do the implementation there is no guarantee that it will be ready in the new future.
|
||||
However if you would like to force it, take a look at this page: [Feature request service](http://www.gl.littlev.hu/services#feature)
|
||||
|
||||
## How to implement a feature?
|
||||
In [docs/TODO_MINOR.md](https://github.com/littlevgl/lvgl/blob/master/docs/TODO_MINOR.md) and [docs/TODO_PATCH.md](https://github.com/littlevgl/lvgl/blob/master/docs/TODO_PATCH.md) you can see some ideas which are waiting for somebody to realize them! If want to deal with a feature from this files, please start an issue and discusse the details.
|
||||
|
||||
## Styling guide
|
||||
|
||||
### Git Commit Messages
|
||||
* Use the present tense ("Add feature" not "Added feature")
|
||||
* Use the imperative mood ("Move cursor to..." not "Moves cursor to...")
|
||||
* Limit the first line to 72 characters or less
|
||||
* Reference issues and pull requests liberally after the first line
|
||||
|
||||
### File format
|
||||
Use [misc/templ/templ.c](https://github.com/littlevgl/misc/blob/master/templ/templ.c) and [misc/templ/templ.h](https://github.com/littlevgl/misc/blob/master/templ/templ.h)
|
||||
|
||||
### Functions
|
||||
* try to write function shorter then is 40 lines
|
||||
* always shorter then 100 lines (except very straightforwards)
|
||||
* in function names:
|
||||
* words sparated by '_'
|
||||
* only lower case letters
|
||||
* only clear abbreviation (OK: *lv_xy_get_title_txt*, BAD: *lv_xy_get_ttxt*)
|
||||
|
||||
#### Global functions names (API)
|
||||
An example: *lv_btn_set_state()*
|
||||
* starts with *lv*
|
||||
* followed by module name: *btn*, *label*, *style* etc.
|
||||
* followed by the action: *set*, *get*, *refr* etc.
|
||||
* closed with subject: *name*, *size*, *state* etc.
|
||||
* optional like in *lv_obj_del()* it is missing
|
||||
* could contain more words: *long_mode*, *point_all*
|
||||
|
||||
#### Static functions names
|
||||
Names can be used freely.
|
||||
|
||||
### Variables
|
||||
* words sparated by '_'
|
||||
* always lower case
|
||||
* one line one declaration (BAD: char x, y;)
|
||||
* use `<stdint.h>` (*uint8_t*, *int32_t* etc)
|
||||
* declare variables when 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)
|
||||
|
||||
### Defines
|
||||
* always upper case
|
||||
* starts with *LV_*
|
||||
* followed by the modul: *OBJ*, *BTN* etc.
|
||||
* closed by the subject: *ANIM_TIME*, *VALUE_MIN*, *WIDTH_DEF*
|
||||
|
||||
### Comments
|
||||
Before every function have a comment like this:
|
||||
|
||||
```
|
||||
/**
|
||||
* 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 */`
|
||||
|
||||
### Formatting
|
||||
Here is example to show bracket placing and using of white spaces:
|
||||
```
|
||||
/**
|
||||
* 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 bracket 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 start inline*/
|
||||
lv_label_refr_text(label);
|
||||
return;
|
||||
}
|
||||
|
||||
.
|
||||
.
|
||||
.
|
||||
}
|
||||
```
|
||||
|
||||
Use 4 spaces indentation instead of tab.
|
||||
@@ -1,40 +1,40 @@
|
||||
# LittleV Graphics Libraray
|
||||
|
||||

|
||||

|
||||
|
||||
The LittlevGL is a graphics library which allows you to create graphical user interfaces (GUI) from the most simple monochrome designs to amazing GUIs for high resolution TFTs. No double buffering is required to use transparency and smooth animations.
|
||||
LittlevGL is a graphics library to create Graphical User Interfaces (GUI) on TFT, LCD or monochrome displays using microcontroller based embedded systems.
|
||||
|
||||
Transparency, anti-aliassing and smooth animations can be used with no double buffering so typically no external memories are required.
|
||||
|
||||
The graphics library is written in C and it is completely hardware independent. You can even run it in a PC simulator without any embedded hardware.
|
||||
|
||||
Visit the http://gl.littlev.hu
|
||||
Homepage: http://gl.littlev.hu
|
||||
|
||||
## Key features
|
||||
* Hardware independent
|
||||
* Support any modern microcontroller
|
||||
* No external RAM, FPU or GPU required
|
||||
* High resolution TFTs and monochrome displays are also supported
|
||||
* Scalable and modular
|
||||
* Clear and well-structured source code
|
||||
* Color depth options: 24 bit, 16 bit, 8 bot or 1 bit
|
||||
* Hardware independent, support any modern microcontroller
|
||||
* High resolution TFTs, monochrome or any type of display supported (24/16/8/1 bit color depth)
|
||||
* External RAM, FPU or GPU not required just optional
|
||||
* Build GUI from simple graphical objects
|
||||
* Buttons, Labels, Images
|
||||
* Charts, Lists, Bars, Sliders, Text areas etc.
|
||||
* High level graphical features:
|
||||
* High level graphical features without double buffering
|
||||
* Antialiassing (font or full screen)
|
||||
* Animations
|
||||
* Transparency
|
||||
* Gradient colors
|
||||
* Smooth dragging and scrolling
|
||||
* Layers
|
||||
* Layers
|
||||
* Customizable appearance with styles
|
||||
* Applications for complex tasks
|
||||
* Can run in a PC simulator
|
||||
* Modular and well-structured source code
|
||||
* Actively developed
|
||||
|
||||
## Porting
|
||||
The following functions has to be provided
|
||||
* hal/disp `disp_fill(x1, y1, x2, y2, color)` to fill area with a color
|
||||
* hal/disp `disp_map(x1, y1, x2, y2, &color_array)` copy a color map to an area
|
||||
* hal/disp `disp_color_cpy(dest, src, length, opa)` copy pixel, optional for GPU
|
||||
* hal/indev `indev_get(id, &x, &y)` get the *x* and *y* coordinates from an input device (e.g. touch pad)
|
||||
* hal/systick `systick_get()` get a system tick with 1 ms resolution
|
||||
* hal/systick `systick_elapse(prev_time)` get the elapsed milliseconds sience *prev_time*
|
||||
@@ -63,7 +63,7 @@ See the [example HAL](https://github.com/littlevgl/hal) repository!
|
||||
* your_systick_init();
|
||||
* your_disp_init();
|
||||
* your_indev_init();
|
||||
* **lvgl_init()**;
|
||||
* **lv_init()**;
|
||||
10. To **test** create a label: `lv_obj_t * label = lv_label_create(lv_scr_act(), NULL);`
|
||||
11. In the main *while(1)* call `ptask_handler();` and make a few milliseconds delay (e.g. `your_delay_ms(5);`)
|
||||
12. Compile the code and load it to your embedded hardware
|
||||
@@ -74,16 +74,10 @@ If you don't have got an embedded hardware you can test the graphics library in
|
||||
There is a pre-configured PC project for **Eclipse CDT** in this repository: https://github.com/littlevgl/proj_pc
|
||||
|
||||
## Contributing
|
||||
1. Fork it!
|
||||
2. Create your feature branch: `git checkout -b my-new-feature`
|
||||
3. Commit your changes: `git commit -am 'Add some feature'`
|
||||
4. Push to the branch: `git push origin my-new-feature`
|
||||
5. Submit a pull request!
|
||||
|
||||
If you find an issue, please report it via GitHub!
|
||||
See [CONTRIBUTING.md](https://github.com/littlevgl/lvgl/blob/master/docs/CONTRIBUTING.md)
|
||||
|
||||
## Donate
|
||||
If you are pleased with the graphics library and found it useful pleas support its further development:
|
||||
If you are pleased with the graphics library and found it useful please support its further development:
|
||||
|
||||
[](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=GJV3SC5EHDANS)
|
||||
|
||||
12
docs/TODO_MAJOR.md
Normal file
12
docs/TODO_MAJOR.md
Normal file
@@ -0,0 +1,12 @@
|
||||
# TODOs for major versions
|
||||
Major versions released typically when API changes are required
|
||||
|
||||
## Contributing
|
||||
Please create an issue to suggest a new feature instead of adding pull request to this file.
|
||||
|
||||
## v5
|
||||
- [ ] rename repository from *lvgl* to *littlevgl*
|
||||
- [ ] define renames: e.g. *USE_LV_BTN* to *LV_BTN_USE*
|
||||
- [ ] Remove LV_DOWNSCALE (LV_ANTIALIAS will be used instead)
|
||||
- [ ] *lv_ta_get_txt* rename to *lv_ta_get_text*
|
||||
- [ ] btnm_action pass text instead of text_id
|
||||
30
docs/TODO_MINOR.md
Normal file
30
docs/TODO_MINOR.md
Normal file
@@ -0,0 +1,30 @@
|
||||
# TODOs for minor versions
|
||||
Minor versions (x.1.0, x.2.0 ...) released when one or more new feature is addded without changing the API. New features can be added with major versions (1.0.0, 2.0.0 ...) too.
|
||||
|
||||
## Contributing
|
||||
Please create an issue to suggest a new feature instead of adding pull request to this file.
|
||||
|
||||
## Ideas
|
||||
Here are ideas which are not assigned to a minor version yet:
|
||||
- label: add a horzintal line (e.g. underline or line through).
|
||||
- label long mode: dot begin
|
||||
- music player app
|
||||
- files app update: show content as text
|
||||
- GUI remote control
|
||||
- automatically build GUI from file (e.g. XML, JSON or HTML)
|
||||
- lv_split: new object type, a hor. or ver. line for decoration purpose
|
||||
- lv_valset: new object type, a label with "+" and "-" buttons
|
||||
- lv_tabview: new object type to organise content with tabs
|
||||
- lv_btngrp: new object type to display more buttons to choose an option from them
|
||||
- lv_switch: new object type, turn on/off by tap (a little slider)
|
||||
- lv_roller: new object type, a roller to select a value (like on smartphones)
|
||||
|
||||
## v4.2
|
||||
- [x] Double VDB support: one for rendering, another to transfer former rendered image to frame buffer in the background (e.g. with DMA) [#15](https://github.com/littlevgl/lvgl/issues/15)
|
||||
- [x] lv_group: to control without touch pad. Issue [#14](https://github.com/littlevgl/lvgl/issues/14)
|
||||
- [x] lv_page: scrl def fit modification: hor:false, ver:true, and always set width to parent width
|
||||
- [x] lv_btn: add lv_btn_get_..._action
|
||||
- [x] lv_list: add lv_list_get_element_label/img
|
||||
- [x] lv_ta: lv_ta_set_one_line to configure the Text area to one lined input field
|
||||
- [x] style animations add
|
||||
- [x] lv_btnm: besides 0. byte (width dsc) 1. byte: hidden (\177, 0x7F, delete)
|
||||
13
docs/TODO_PATCH.md
Normal file
13
docs/TODO_PATCH.md
Normal file
@@ -0,0 +1,13 @@
|
||||
# TODOs for patch versions
|
||||
Patch versions (x.y.1, x.y.2) contain bugfixes without changing the API but they can apppear in minor (x.1.0, x.2.0) or major (1.0.0, 2.0.0) versions too.
|
||||
|
||||
Bugfixes are done in `bugfix` branche.
|
||||
|
||||
The bugfixes of the still not released version are in `beta` branche.
|
||||
|
||||
## Contributing
|
||||
Please create an issue to introduce a bug instead of adding pull request to this file.
|
||||
|
||||
## Next release
|
||||
- [x] lv_slider: don't let indicator or bar to disappear because of hpad/vpad
|
||||
- [x] lv_ta: memory leak if deleted in password mode
|
||||
@@ -146,6 +146,14 @@ const lv_app_dsc_t * lv_app_benchmark_init(void)
|
||||
static void my_app_run(lv_app_inst_t * app, void * conf)
|
||||
{
|
||||
/*Initialize the application*/
|
||||
my_app_data_t * ad = app->app_data;
|
||||
ad->opa = 0;
|
||||
ad->recolor = 0;
|
||||
ad->shdw = 0;
|
||||
ad->upscalse = 0;
|
||||
ad->wp = 0;
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -17,18 +17,19 @@
|
||||
#define LV_HOR_RES (320 * LV_DOWNSCALE)
|
||||
#define LV_VER_RES (240 * LV_DOWNSCALE)
|
||||
#define LV_DPI (80 * LV_DOWNSCALE)
|
||||
/* Enable anti-aliasing
|
||||
* If enabled everything will half-sized
|
||||
* Use LV_DOWNSCALE to compensate he down scaling effect of anti-aliasing*/
|
||||
#define LV_ANTIALIAS 1
|
||||
#define LV_DOWNSCALE (1 << LV_ANTIALIAS) /*Set the downscaling value*/
|
||||
|
||||
/* Buffered rendering: >= LV_DOWNSCALE * LV_HOR_RES or 0 to disable buffering*/
|
||||
#define LV_VDB_SIZE (LV_HOR_RES * 30)
|
||||
|
||||
/* Enable antialaiassing
|
||||
* If enabled everything will half-sized
|
||||
* Use LV_DOWNSCALE to compensate
|
||||
* the down scaling effect of antialiassing*/
|
||||
#define LV_ANTIALIAS 1
|
||||
|
||||
/*Set the downscaling value*/
|
||||
#define LV_DOWNSCALE (1 << LV_ANTIALIAS)
|
||||
#define LV_VDB_SIZE (LV_HOR_RES * LV_VER_RES / 20)
|
||||
#if LV_VDB_SIZE
|
||||
/* Double virtual buffering
|
||||
* One for rendering another to transfer former rendered image to frame buffer in the background*/
|
||||
#define LV_VDB_DOUBLE 0
|
||||
#endif
|
||||
|
||||
#define LV_REFR_PERIOD 40 /*Screen refresh period in milliseconds*/
|
||||
#define LV_INV_FIFO_SIZE 32 /*The average number of objects on a screen */
|
||||
@@ -47,9 +48,11 @@
|
||||
/*lv_obj (base object) settings*/
|
||||
#define LV_OBJ_FREE_NUM 1 /*Enable the free number attribute*/
|
||||
#define LV_OBJ_FREE_P 1 /*Enable the free pointer attribute*/
|
||||
#define LV_OBJ_GROUP 1 /*Enable object groups*/
|
||||
|
||||
/*Others*/
|
||||
#define LV_COLOR_TRANSP COLOR_LIME
|
||||
#define LV_COLOR_TRANSP COLOR_LIME /*This could mean transparent pixel*/
|
||||
#define USE_LV_EXAMPLE 1 /*Enable examples (lvgl/lv_examples/). Disable to save memory*/
|
||||
|
||||
/*==================
|
||||
* LV OBJ X USAGE
|
||||
@@ -145,6 +148,9 @@
|
||||
|
||||
/*List (dependencies: lv_page, lv_btn, lv_label, lv_img)*/
|
||||
#define USE_LV_LIST 1
|
||||
#if USE_LV_LIST != 0
|
||||
#define LV_LIST_FOCUS_TIME 100 /*Animation time of focusing to the a list element [ms] (0: no animation) */
|
||||
#endif
|
||||
|
||||
/*Drop down list (dependencies: lv_page, lv_label)*/
|
||||
#define USE_LV_DDLIST 1
|
||||
|
||||
@@ -123,8 +123,7 @@ void lv_vfill(const area_t * cords_p, const area_t * mask_p,
|
||||
cord_t map_width = area_get_width(&vdb_rel_a);
|
||||
if(color_map[0].full != color.full || last_width != map_width) {
|
||||
uint16_t i;
|
||||
|
||||
for(i =0; i < map_width; i++) {
|
||||
for(i = 0; i < map_width; i++) {
|
||||
color_map[i].full = color.full;
|
||||
}
|
||||
|
||||
@@ -133,7 +132,6 @@ void lv_vfill(const area_t * cords_p, const area_t * mask_p,
|
||||
cord_t row;
|
||||
for(row = vdb_rel_a.y1;row <= vdb_rel_a.y2; row++) {
|
||||
disp_color_cpy(&vdb_buf_tmp[vdb_rel_a.x1], color_map, map_width, opa);
|
||||
|
||||
vdb_buf_tmp += vdb_width;
|
||||
}
|
||||
#endif
|
||||
|
||||
67
lv_examples/1_1_hello_world/lv_ex_hello_world.c
Normal file
67
lv_examples/1_1_hello_world/lv_ex_hello_world.c
Normal file
@@ -0,0 +1,67 @@
|
||||
/**
|
||||
* @file lv_ex_hello_world.c
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Greetings,
|
||||
* this is the first example in the tutorial hence this is the most simple one.
|
||||
* It only creates a Label, set its text, and align to the middle.
|
||||
*
|
||||
* Be sure in lv_conf.h LV_APP_ENEBLE is 0 (just for simplicity)
|
||||
*/
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "lv_ex_hello_world.h"
|
||||
#if USE_LV_EXAMPLE != 0
|
||||
|
||||
#include "lvgl/lvgl.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL FUNCTIONS
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Create a simple 'Hello world!' label
|
||||
*/
|
||||
void lv_ex_hello_world(void)
|
||||
{
|
||||
/*Create a Label on the current screen*/
|
||||
lv_obj_t * label1 = lv_label_create(lv_scr_act(), NULL);
|
||||
|
||||
/*Modify the Label's text*/
|
||||
lv_label_set_text(label1, "Hello world!");
|
||||
|
||||
/* Align the Label to the center
|
||||
* NULL means align on parent (which is the screen now)
|
||||
* 0, 0 at the and means an x, y offset after alignment*/
|
||||
lv_obj_align_us(label1, NULL, LV_ALIGN_CENTER, 0, 0);
|
||||
}
|
||||
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
|
||||
#endif /*USE_LV_EXAMPLE != 0*/
|
||||
42
lv_examples/1_1_hello_world/lv_ex_hello_world.h
Normal file
42
lv_examples/1_1_hello_world/lv_ex_hello_world.h
Normal file
@@ -0,0 +1,42 @@
|
||||
/**
|
||||
* @file lv_ex_hello_world.h
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LV_EX_HELLO_WORLD_H
|
||||
#define LV_EX_HELLO_WORLD_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "lv_conf.h"
|
||||
#if USE_LV_EXAMPLE != 0
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
void lv_ex_hello_world(void);
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
#endif /*USE_LV_EXAMPLE != 0*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif /*LV_HELLO_WORLD_H*/
|
||||
BIN
lv_examples/1_1_hello_world/lv_ex_hello_world.png
Normal file
BIN
lv_examples/1_1_hello_world/lv_ex_hello_world.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.8 KiB |
218
lv_examples/1_2_objects/lv_ex_objects.c
Normal file
218
lv_examples/1_2_objects/lv_ex_objects.c
Normal file
@@ -0,0 +1,218 @@
|
||||
/**
|
||||
* @file lv_hello_world.c
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* The basic building blocks (components or widgets) in LittlevGL are the graphical objects.
|
||||
* For example:
|
||||
* - Buttons
|
||||
* - Labels
|
||||
* - Charts
|
||||
* - Sliders etc
|
||||
*
|
||||
* In this part you can learn the basics of the objects like creating, positioning, sizing etc.
|
||||
* You will also meet some different object types and their attributes.
|
||||
*
|
||||
* Regardless to the object type the 'lv_obj_t' variable type is used stores the objects
|
||||
* and you can refer to an object with an lv_obj_t pointer (lv_obj_t *)
|
||||
*
|
||||
* INHERITANCE
|
||||
* -------------
|
||||
* Similarly to object oriented languages some kind of inheritance is used
|
||||
* among the object types.
|
||||
*
|
||||
* Every object is derived from the 'Basic object'. (lv_obj)
|
||||
*
|
||||
* The types are backward compatible which means a type can use all the ancestor
|
||||
* attributes/functions too.
|
||||
*
|
||||
* For example a 'Button' is derived from 'Container' which is derived from 'Basic objects'.
|
||||
* Therefore a button can use container attributes like automatically fit size to the content.
|
||||
*
|
||||
* PARENT-CHILD
|
||||
* -------------
|
||||
* A parent can be considered as the container of its children.
|
||||
* Every object has exactly one parent object (except screens).
|
||||
* A parent can have unlimited number of children.
|
||||
* There is no limitation for the type of the parent.
|
||||
*
|
||||
* The children are visible only on their parent. The parts outside will be cropped (not displayed)
|
||||
*
|
||||
* If the parent is moved the children will be moved with it.
|
||||
*
|
||||
* The earlier created object (and its children) will drawn earlier.
|
||||
* Using this layers can be built.
|
||||
*
|
||||
* LEARN MORE
|
||||
* -------------
|
||||
* - General overview: http://www.gl.littlev.hu/objects
|
||||
* - Detailed description of types: http://www.gl.littlev.hu/object-types
|
||||
*
|
||||
* NOTES
|
||||
* -------------
|
||||
* - Be sure 'LV_OBJ_FREE_P' is enabled in 'lv_conf.h'
|
||||
*/
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "lv_ex_objects.h"
|
||||
#if USE_LV_EXAMPLE != 0
|
||||
|
||||
#include "lvgl/lvgl.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
static lv_action_res_t btn_rel_action(lv_obj_t * btn, lv_dispi_t * dispi);
|
||||
static lv_action_res_t ddlist_action(lv_obj_t * ddlist, lv_dispi_t * dispi);
|
||||
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL FUNCTIONS
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Initialize the Object usage example
|
||||
*/
|
||||
void lv_ex_objects(void)
|
||||
{
|
||||
|
||||
/********************
|
||||
* CREATE A SCREEN
|
||||
*******************/
|
||||
|
||||
/* Create a new screen and load it
|
||||
* Screen can be created from any type object
|
||||
* Now a Page is used which is an objects with scrollable content*/
|
||||
lv_obj_t * scr = lv_page_create(NULL, NULL);
|
||||
lv_scr_load(scr);
|
||||
|
||||
|
||||
/****************
|
||||
* ADD A TITLE
|
||||
****************/
|
||||
lv_obj_t * label = lv_label_create(scr, NULL); /*First parameters (scr) is the parent*/
|
||||
lv_label_set_text(label, "Object usage demo"); /*Set the text*/
|
||||
lv_obj_set_x(label, 50); /*Labels are inherited from Basic object so 'lv_obj_...' functions can be used*/
|
||||
|
||||
|
||||
/********************
|
||||
* CREATE TWO BUTTONS
|
||||
********************/
|
||||
|
||||
/*Create a button*/
|
||||
lv_obj_t * btn1 = lv_btn_create(lv_scr_act(), NULL); /*Create a button on the currently loaded screen*/
|
||||
lv_btn_set_rel_action(btn1, btn_rel_action); /*Set function to call when the button is released*/
|
||||
lv_obj_align(btn1, label, LV_ALIGN_OUT_BOTTOM_LEFT, 0, 20); /*Align below the label*/
|
||||
label = lv_label_create(btn1, NULL); /*Create a label on the button (the 'label' variable can be reused)*/
|
||||
lv_label_set_text(label, "Button 1");
|
||||
|
||||
/*Copy the previous button*/
|
||||
lv_obj_t * btn2 = lv_btn_create(lv_scr_act(), btn1); /*Second parameter is an object to copy*/
|
||||
lv_obj_align(btn2, btn1, LV_ALIGN_OUT_RIGHT_MID, 50, 0);/*Align next to the prev. button.*/
|
||||
label = lv_label_create(btn2, NULL); /*Create a label on the button*/
|
||||
lv_label_set_text(label, "Button 2");
|
||||
|
||||
|
||||
/****************
|
||||
* ADD A SLIDER
|
||||
****************/
|
||||
|
||||
/*Add a slider (inheritance: lv_obj -> lv_bar -> lv_slider)*/
|
||||
lv_obj_t * slider = lv_slider_create(scr, NULL); /*Create a slider*/
|
||||
lv_obj_set_size(slider, lv_obj_get_width(lv_scr_act()) / 3, LV_DPI / 3); /*Set the size*/
|
||||
lv_obj_align(slider, btn1, LV_ALIGN_OUT_BOTTOM_LEFT, 0, 20); /*Align below the first button*/
|
||||
lv_bar_set_value(slider, 30); /*Slider is a 'bar' so set its value like a 'bar'*/
|
||||
|
||||
|
||||
/***********************
|
||||
* ADD A DROP DOWN LIST
|
||||
************************/
|
||||
|
||||
lv_obj_t * ddlist = lv_ddlist_create(lv_scr_act(), NULL);
|
||||
lv_obj_align(ddlist, slider, LV_ALIGN_OUT_RIGHT_TOP, 20, 0); /*Align next to the slider*/
|
||||
lv_obj_set_free_p(ddlist, slider); /*Save the pointer of the slider in the ddlist (used in 'ddlist_action()')*/
|
||||
lv_ddlist_set_options_str(ddlist, "None\nLittle\nHalf\nA lot\nAll"); /*Set the options*/
|
||||
lv_ddlist_set_action(ddlist, ddlist_action); /*Set function to call on new option choose*/
|
||||
lv_obj_set_top(ddlist, true); /*Enable the drop down list always be on the top*/
|
||||
|
||||
|
||||
/****************
|
||||
* CREATE A CHART
|
||||
****************/
|
||||
lv_obj_t * chart = lv_chart_create(lv_scr_act(), NULL); /*Craete the chart*/
|
||||
lv_obj_set_size(chart, lv_obj_get_width(scr) / 2, lv_obj_get_width(scr) / 4); /*Set the size*/
|
||||
lv_obj_align(chart, slider, LV_ALIGN_OUT_BOTTOM_LEFT, 0, 20); /*Align below the slider*/
|
||||
lv_chart_set_dl_width(chart, 3 * LV_DOWNSCALE); /*Set the line width (LV_DOWNSCALE compensates anti-aliasing if enabled)*/
|
||||
|
||||
/*Add a RED data line and set some points*/
|
||||
lv_chart_dl_t * dl1 = lv_chart_add_data_line(chart, COLOR_RED);
|
||||
lv_chart_set_next(chart, dl1, 10);
|
||||
lv_chart_set_next(chart, dl1, 25);
|
||||
lv_chart_set_next(chart, dl1, 45);
|
||||
lv_chart_set_next(chart, dl1, 80);
|
||||
|
||||
/*Add a BLUE data line and set some points*/
|
||||
lv_chart_dl_t * dl2 = lv_chart_add_data_line(chart, COLOR_MAKE(0x40, 0x70, 0xC0));
|
||||
lv_chart_set_next(chart, dl2, 10);
|
||||
lv_chart_set_next(chart, dl2, 25);
|
||||
lv_chart_set_next(chart, dl2, 45);
|
||||
lv_chart_set_next(chart, dl2, 80);
|
||||
lv_chart_set_next(chart, dl2, 75);
|
||||
lv_chart_set_next(chart, dl2, 505);
|
||||
|
||||
}
|
||||
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Called when a button is released
|
||||
* @param btn pointer to the released button
|
||||
* @param dispi pointer to caller display input (e.g. touchpad)
|
||||
* @return LV_ACTION_RES_OK because the object is not deleted in this function
|
||||
*/
|
||||
static lv_action_res_t btn_rel_action(lv_obj_t * btn, lv_dispi_t * dispi)
|
||||
{
|
||||
/*Increase the button width*/
|
||||
cord_t width = lv_obj_get_width(btn);
|
||||
lv_obj_set_width(btn, width + 20);
|
||||
|
||||
return LV_ACTION_RES_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when a new option is chosen in the drop down list
|
||||
* @param ddlist pointer to the drop down list
|
||||
* @param dispi pointer to caller display input (e.g. touchpad)
|
||||
* @return LV_ACTION_RES_OK because the object is not deleted in this function
|
||||
*/
|
||||
static lv_action_res_t ddlist_action(lv_obj_t * ddlist, lv_dispi_t * dispi)
|
||||
{
|
||||
uint16_t opt = lv_ddlist_get_selected(ddlist); /*Get the id of selected option*/
|
||||
|
||||
lv_obj_t * slider = lv_obj_get_free_p(ddlist); /*Get the saved slider*/
|
||||
lv_bar_set_value(slider, (opt * 100) / 4); /*Modify the slider value according to the selection*/
|
||||
|
||||
return LV_ACTION_RES_OK;
|
||||
}
|
||||
|
||||
#endif /*USE_LV_EXAMPLE != 0*/
|
||||
42
lv_examples/1_2_objects/lv_ex_objects.h
Normal file
42
lv_examples/1_2_objects/lv_ex_objects.h
Normal file
@@ -0,0 +1,42 @@
|
||||
/**
|
||||
* @file lv_ex_objects.h
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LV_EX_OBJECTS_H
|
||||
#define LV_EX_OBJECTS_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "lv_conf.h"
|
||||
#if USE_LV_EXAMPLE != 0
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
void lv_ex_objects(void);
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
#endif /*USE_LV_EXAMPLE != 0*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif /*LV_OBJ_USAGE_H*/
|
||||
BIN
lv_examples/1_2_objects/lv_ex_objects.png
Normal file
BIN
lv_examples/1_2_objects/lv_ex_objects.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 11 KiB |
161
lv_examples/1_3_styles/lv_ex_styles.c
Normal file
161
lv_examples/1_3_styles/lv_ex_styles.c
Normal file
@@ -0,0 +1,161 @@
|
||||
/**
|
||||
* @file lv_ex_styles.h
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* You can modify the appearance of the graphical objects with styles.
|
||||
* A style is simple 'lv_style_t' variable.
|
||||
* Objects save the address of this variable so it has to be 'static or 'global'.
|
||||
*
|
||||
* A style contains various attributes to describe rectangle, image or text like
|
||||
* objects at same time. To know which attribute is used by an object see:
|
||||
* http://www.gl.littlev.hu/object-types
|
||||
*
|
||||
* To set a new style for an object use: 'lv_obj_set_style(obj, &style);
|
||||
* If NULL is set as style then the object will inherit the parents style.
|
||||
* For example is you create a style for button the label appearance can be defined there as well.
|
||||
*
|
||||
* You can use built-in styles. 'lv_style_get(LV_STYLE_... , ©)' will give you a pointer to built in style
|
||||
* and copy it to variable (second parameter) if it is not NULL.
|
||||
* By default the objects use the built-in styles.
|
||||
* The built-in styles can be modified in run time to give a new default skin to your GUI.
|
||||
*
|
||||
* Learn more here: http://www.gl.littlev.hu/objects#style
|
||||
* */
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "lv_ex_styles.h"
|
||||
|
||||
#if USE_LV_EXAMPLE != 0
|
||||
|
||||
#include "lvgl/lvgl.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL FUNCTIONS
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Create a simple 'Hello world!' label
|
||||
*/
|
||||
void lv_ex_styles(void)
|
||||
{
|
||||
|
||||
/****************************************
|
||||
* BASE OBJECT + LABEL WITH DEFAULT STYLE
|
||||
****************************************/
|
||||
|
||||
lv_obj_t * obj1;
|
||||
obj1 = lv_obj_create(lv_scr_act(), NULL); /*Create a simple objects*/
|
||||
lv_obj_set_pos(obj1, 10, 10);
|
||||
lv_obj_t * label = lv_label_create(obj1, NULL);
|
||||
|
||||
/*Add a label to the object*/
|
||||
lv_label_set_text(label, "Default");
|
||||
lv_obj_align(label, NULL, LV_ALIGN_CENTER, 0, 0);
|
||||
|
||||
/****************************************
|
||||
* BASE OBJECT WITH PRETTY COLOR STYLE
|
||||
****************************************/
|
||||
|
||||
lv_obj_t * obj2;
|
||||
obj2 = lv_obj_create(lv_scr_act(), NULL);
|
||||
lv_obj_align(obj2, obj1, LV_ALIGN_OUT_RIGHT_MID, 20, 0); /*Align next to the previous object*/
|
||||
lv_obj_set_style(obj2, lv_style_get(LV_STYLE_PRETTY_COLOR, NULL)); /*Set built in style*/
|
||||
label = lv_label_create(obj2, NULL);
|
||||
|
||||
/* Add a label to the object.
|
||||
* Labels by default inherit the parent's style */
|
||||
lv_label_set_text(label, "Pretty\ncolor");
|
||||
lv_obj_align(label, NULL, LV_ALIGN_CENTER, 0, 0);
|
||||
|
||||
/*****************************
|
||||
* BASE OBJECT WITH NEW STYLE
|
||||
*****************************/
|
||||
|
||||
/* Create a new style */
|
||||
static lv_style_t style_new; /*Styles can't be local variables*/
|
||||
lv_style_get(LV_STYLE_PRETTY_COLOR, &style_new); /*Copy a built-in style as a starting point*/
|
||||
style_new.radius = LV_RADIUS_CIRCLE; /*Fully round corners*/
|
||||
style_new.swidth = 8; /*8 px shadow*/
|
||||
style_new.bwidth = 2; /*2 px border width*/
|
||||
style_new.mcolor = COLOR_WHITE; /*White main color*/
|
||||
style_new.gcolor = color_mix(COLOR_BLUE, COLOR_WHITE, OPA_40); /*light blue gradient color*/
|
||||
style_new.scolor = COLOR_MAKE(0xa0, 0xa0, 0xa0); /*Light gray shadow color*/
|
||||
style_new.ccolor = color_mix(COLOR_BLUE, COLOR_WHITE, OPA_90); /*Blue content color (text color)*/
|
||||
style_new.letter_space = 10; /*10 px letter space*/
|
||||
style_new.txt_align = LV_TXT_ALIGN_MID; /*Middel text align*/
|
||||
|
||||
/*Create a base object and apply the new style*/
|
||||
lv_obj_t * obj3;
|
||||
obj3 = lv_obj_create(lv_scr_act(), NULL);
|
||||
lv_obj_align(obj3, obj2, LV_ALIGN_OUT_RIGHT_MID, 20, 0);
|
||||
lv_obj_set_style(obj3, &style_new);
|
||||
|
||||
/* Add a label to the object.
|
||||
* Labels by default inherit the parent's style */
|
||||
label = lv_label_create(obj3, NULL);
|
||||
lv_label_set_text(label, "New\nstyle");
|
||||
lv_obj_align(label, NULL, LV_ALIGN_CENTER, 0, 0);
|
||||
|
||||
|
||||
/************************
|
||||
* CREATE A STYLED LED
|
||||
***********************/
|
||||
|
||||
/*Create a style for the LED*/
|
||||
static lv_style_t style_led;
|
||||
lv_style_get(LV_STYLE_PRETTY_COLOR, &style_led);
|
||||
style_led.swidth = 15;
|
||||
style_led.radius = LV_RADIUS_CIRCLE;
|
||||
style_led.bwidth = 3;
|
||||
style_led.bopa = OPA_30;
|
||||
style_led.mcolor = COLOR_MAKE(0xb5, 0x0f, 0x04);
|
||||
style_led.gcolor = COLOR_MAKE(0x50, 0x07, 0x02);
|
||||
style_led.bcolor = COLOR_MAKE(0xfa, 0x0f, 0x00);
|
||||
style_led.scolor = COLOR_MAKE(0xb5, 0x0f, 0x04);
|
||||
|
||||
/*Create a LED and switch it ON*/
|
||||
lv_obj_t * led1 = lv_led_create(lv_scr_act(), NULL);
|
||||
lv_obj_set_style(led1, &style_led);
|
||||
lv_obj_align_us(led1, obj1, LV_ALIGN_OUT_BOTTOM_MID, 0, 40);
|
||||
lv_led_on(led1);
|
||||
|
||||
/*Copy the previous LED and set a brightness*/
|
||||
lv_obj_t * led2 = lv_led_create(lv_scr_act(), led1);
|
||||
lv_obj_align_us(led2, obj2, LV_ALIGN_OUT_BOTTOM_MID, 0, 40);
|
||||
lv_led_set_bright(led2, 190);
|
||||
|
||||
/*Copy the previous LED and switch it OFF*/
|
||||
lv_obj_t * led3 = lv_led_create(lv_scr_act(), led1);
|
||||
lv_obj_align_us(led3, obj3, LV_ALIGN_OUT_BOTTOM_MID, 0, 40);
|
||||
lv_led_off(led3);
|
||||
}
|
||||
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
|
||||
#endif /*USE_LV_EXAMPLE != 0*/
|
||||
42
lv_examples/1_3_styles/lv_ex_styles.h
Normal file
42
lv_examples/1_3_styles/lv_ex_styles.h
Normal file
@@ -0,0 +1,42 @@
|
||||
/**
|
||||
* @file style_usage.h
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef STYLE_USAGE_H
|
||||
#define STYLE_USAGE_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "lv_conf.h"
|
||||
#if USE_LV_EXAMPLE != 0
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
void lv_ex_styles(void);
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
#endif /*USE_LV_EXAMPLE != 0*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif /*LV_HELLO_WORLD_H*/
|
||||
BIN
lv_examples/1_3_styles/lv_ex_styles.png
Normal file
BIN
lv_examples/1_3_styles/lv_ex_styles.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 11 KiB |
0
lv_examples/1_4_responsive/lv_ex_responsive.c
Normal file
0
lv_examples/1_4_responsive/lv_ex_responsive.c
Normal file
0
lv_examples/1_4_responsive/lv_ex_responsive.h
Normal file
0
lv_examples/1_4_responsive/lv_ex_responsive.h
Normal file
1
lv_examples/1_5_animations/lv_ex_animations.c
Normal file
1
lv_examples/1_5_animations/lv_ex_animations.c
Normal file
@@ -0,0 +1 @@
|
||||
|
||||
0
lv_examples/1_5_animations/lv_ex_animations.h
Normal file
0
lv_examples/1_5_animations/lv_ex_animations.h
Normal file
0
lv_examples/1_6_anti_aliasing/lv_ex_anti_aliasing.c
Normal file
0
lv_examples/1_6_anti_aliasing/lv_ex_anti_aliasing.c
Normal file
0
lv_examples/1_6_anti_aliasing/lv_ex_anti_aliasing.h
Normal file
0
lv_examples/1_6_anti_aliasing/lv_ex_anti_aliasing.h
Normal file
0
lv_examples/1_7_gui/lv_ex_gui.c
Normal file
0
lv_examples/1_7_gui/lv_ex_gui.c
Normal file
0
lv_examples/1_7_gui/lv_ex_gui.h
Normal file
0
lv_examples/1_7_gui/lv_ex_gui.h
Normal file
0
lv_examples/1_8_new_obj_type/lv_ex_new_obj_type.c
Normal file
0
lv_examples/1_8_new_obj_type/lv_ex_new_obj_type.c
Normal file
0
lv_examples/1_8_new_obj_type/lv_ex_new_obj_type.h
Normal file
0
lv_examples/1_8_new_obj_type/lv_ex_new_obj_type.h
Normal file
0
lv_examples/2_1_button_ctrl/lv_ex_button_ctrl.c
Normal file
0
lv_examples/2_1_button_ctrl/lv_ex_button_ctrl.c
Normal file
0
lv_examples/2_1_button_ctrl/lv_ex_button_ctrl.h
Normal file
0
lv_examples/2_1_button_ctrl/lv_ex_button_ctrl.h
Normal file
328
lv_examples/2_2_encoder_ctrl/lv_ex_encoder_ctrl.c
Normal file
328
lv_examples/2_2_encoder_ctrl/lv_ex_encoder_ctrl.c
Normal file
@@ -0,0 +1,328 @@
|
||||
/**
|
||||
* @file lv_ex_encoder_ctrl.c
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Create a simple GUI to demonstrate how to control it with an encoder
|
||||
* using 'lv_group'.
|
||||
*
|
||||
* Be sure in lv_conf.h:
|
||||
* - LV_OBJ_GROUP 1 to enable groups
|
||||
* - LV_APP_ENABLE 0 to disable applications because they might bother now
|
||||
*
|
||||
* lv_group:
|
||||
* - you can create groups and add object to them
|
||||
* - it can be a focused object within a group
|
||||
* - the style of the focused object will be automatically modified
|
||||
* - different style modifier functions can be applied in each groups
|
||||
* - you can focus on the next or previous object (lv_group_focus_next/prev)
|
||||
* - letters can be sent to the focused object to do something (lv_group_send):
|
||||
* - LV_GROUP_KEY_RIGHT/UP: increment action in the object
|
||||
* - LV_GROUP_KEY_LEFT/DOWN: decrement action in the object
|
||||
* - LV_GROUP_KEY_ENTER: ok or select action in the object
|
||||
* - LV_GROUP_KEY_ESC: close or back action action in the object
|
||||
* - or any character for example to a text area
|
||||
*
|
||||
* The encoder is replaced by 4 button on the screen:
|
||||
* - [>] Next (lv_group_focus_next): focus on the next object in the group (simulates encoder press)
|
||||
* - [+] IncrementNext (LV_GROUP_KEY_RIGHT): increment signal to the object (simulates rotate right)
|
||||
* - [-] DecrementNext (LV_GROUP_KEY_LEFT): increment signal to the object (simulates rotate left)
|
||||
* - [!] SelectNext (LV_GROUP_KEY_ENTER): Select something (simulates encoder long press or an 'Select' button)
|
||||
*/
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "lv_ex_encoder_ctrl.h"
|
||||
#if USE_LV_EXAMPLE != 0
|
||||
|
||||
#include "lvgl/lvgl.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
static void gui_create(void);
|
||||
static void enc_create(void);
|
||||
static lv_action_res_t mbox_yes_action(lv_obj_t * btn, lv_dispi_t * dispi);
|
||||
static lv_action_res_t mbox_no_action(lv_obj_t * btn, lv_dispi_t * dispi);
|
||||
static lv_action_res_t enable_action(lv_obj_t * btn, lv_dispi_t * dispi);
|
||||
static lv_action_res_t enc_next(lv_obj_t * btn, lv_dispi_t * dispi);
|
||||
static lv_action_res_t enc_inc(lv_obj_t * btn, lv_dispi_t * dispi);
|
||||
static lv_action_res_t enc_dec(lv_obj_t * btn, lv_dispi_t * dispi);
|
||||
static lv_action_res_t enc_sel(lv_obj_t * btn, lv_dispi_t * dispi);
|
||||
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
**********************/
|
||||
static lv_obj_t * scr; /*The screen for the demo*/
|
||||
static lv_obj_t * btn_enable; /*An enable button*/
|
||||
static lv_style_t style_mbox_bg; /*Black bg. style with opacity*/
|
||||
static lv_group_t * g; /*An Object Group*/
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL FUNCTIONS
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Create a simple GUI to demonstrate encoder control capability
|
||||
*/
|
||||
void lv_ex_encoder_ctrl(void)
|
||||
{
|
||||
/* Create a Page screen (to make it scrollable)
|
||||
* and use Pretty layout to make the content responsive.
|
||||
* See the 'responsive' example for more information */
|
||||
scr = lv_page_create(NULL, NULL);
|
||||
lv_cont_set_layout(lv_page_get_scrl(scr), LV_CONT_LAYOUT_PRETTY);
|
||||
lv_page_set_sb_mode(scr, LV_PAGE_SB_MODE_AUTO);
|
||||
lv_scr_load(scr);
|
||||
|
||||
/*Create an object group for objects to focus*/
|
||||
g = lv_group_create();
|
||||
|
||||
/* Create a dark plain style for a message box's background*/
|
||||
lv_style_get(LV_STYLE_PLAIN, &style_mbox_bg);
|
||||
style_mbox_bg.mcolor = COLOR_BLACK;
|
||||
style_mbox_bg.gcolor = COLOR_BLACK;
|
||||
style_mbox_bg.opa = OPA_50;
|
||||
|
||||
/*Create a demo GUI*/
|
||||
gui_create();
|
||||
|
||||
/*Create virtual encoder*/
|
||||
enc_create();
|
||||
}
|
||||
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Create a demo GUI
|
||||
*/
|
||||
static void gui_create(void)
|
||||
{
|
||||
/*Create a title*/
|
||||
lv_obj_t * title = lv_label_create(scr, NULL);
|
||||
lv_label_set_text(title, "Encoder control");
|
||||
lv_obj_set_protect(title, LV_PROTECT_FOLLOW); /*Make a line break in the layout*/
|
||||
|
||||
/*Create a drop down list*/
|
||||
lv_obj_t * ddlist = lv_ddlist_create(scr, NULL);
|
||||
lv_ddlist_set_options_str(ddlist, "Low\nMedium\nHigh");
|
||||
lv_group_add_obj(g, ddlist); /*Add the object to the group*/
|
||||
|
||||
/*Create a holder an check boxes on it*/
|
||||
lv_obj_t * holder = lv_cont_create(scr, NULL); /*Create a transparent holder*/
|
||||
lv_cont_set_fit(holder, true, true);
|
||||
lv_cont_set_layout(holder, LV_CONT_LAYOUT_COL_L);
|
||||
lv_obj_set_style(holder, lv_style_get(LV_STYLE_TRANSP, NULL));
|
||||
|
||||
lv_obj_t * cb = lv_cb_create(holder, NULL); /*First check box*/
|
||||
lv_cb_set_text(cb, "Red");
|
||||
lv_group_add_obj(g, cb); /*Add to the group*/
|
||||
|
||||
cb = lv_cb_create(holder, cb); /*Copy the first check box. Automatically added to the same group*/
|
||||
lv_cb_set_text(cb, "Green");
|
||||
|
||||
cb = lv_cb_create(holder, cb); /*Copy the second check box. Automatically added to the same group*/
|
||||
lv_cb_set_text(cb, "Blue");
|
||||
|
||||
/*Create a sliders*/
|
||||
lv_obj_t * slider = lv_slider_create(scr, NULL);
|
||||
lv_obj_set_size_us(slider, 180, 30);
|
||||
lv_bar_set_range(slider, 0, 20);
|
||||
lv_group_add_obj(g, slider); /*Add to the group*/
|
||||
|
||||
/*Create a button*/
|
||||
btn_enable = lv_btn_create(scr, NULL);
|
||||
lv_btn_set_rel_action(btn_enable, enable_action);
|
||||
lv_cont_set_fit(btn_enable, true, true);
|
||||
lv_group_add_obj(g, btn_enable); /*Add to the group*/
|
||||
lv_obj_t * l = lv_label_create(btn_enable, NULL);
|
||||
lv_label_set_text(l, "Enable");
|
||||
lv_obj_set_protect(btn_enable, LV_PROTECT_FOLLOW); /*Make a line break in the layout*/
|
||||
}
|
||||
|
||||
/**
|
||||
* Create virtual encoder using 4 buttons:
|
||||
* - [>] Next: focus on the next object in the group (simulates encoder press)
|
||||
* - [+] Increment: increment signal to the object (simulates rotate right)
|
||||
* - [-] Decrement: increment signal to the object (simulates rotate left)
|
||||
* - [!] Select: Select something (simulates encoder long press or an 'Select' button)
|
||||
*/
|
||||
static void enc_create(void)
|
||||
{
|
||||
/*Next button*/
|
||||
lv_obj_t * btn = lv_btn_create(lv_scr_act(), NULL);
|
||||
lv_btn_set_rel_action(btn, enc_next);
|
||||
lv_cont_set_fit(btn, true, true);
|
||||
lv_obj_t * l = lv_label_create(btn, NULL);
|
||||
lv_label_set_text(l, ">");
|
||||
|
||||
/*Increment button*/
|
||||
btn = lv_btn_create(lv_scr_act(), btn);
|
||||
lv_btn_set_rel_action(btn, enc_dec);
|
||||
l = lv_label_create(btn, NULL);
|
||||
lv_label_set_text(l, "-");
|
||||
|
||||
/*Decrement button*/
|
||||
btn = lv_btn_create(lv_scr_act(), btn);
|
||||
lv_btn_set_rel_action(btn, enc_inc);
|
||||
l = lv_label_create(btn, NULL);
|
||||
lv_label_set_text(l, "+");
|
||||
|
||||
/*Select button*/
|
||||
btn = lv_btn_create(lv_scr_act(), btn);
|
||||
lv_btn_set_rel_action(btn, enc_sel);
|
||||
l = lv_label_create(btn, NULL);
|
||||
lv_label_set_text(l, "!");
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when the Enable button is released. Show a message box to really enable or not?
|
||||
* @param btn pointer to the Enable button
|
||||
* @param dispi pointer to the caller display input or NULL if the encoder used
|
||||
* @return LV_ACTION_RES_OK: because the button is not deleted
|
||||
*/
|
||||
static lv_action_res_t enable_action(lv_obj_t * btn, lv_dispi_t * dispi)
|
||||
{
|
||||
/*If the butto nsi released the show message box to be sure about the Enable*/
|
||||
if(lv_btn_get_state(btn) == LV_BTN_STATE_REL) {
|
||||
/* Create a dark screen sized bg. with opacity to show
|
||||
* the other objects are not available now*/
|
||||
lv_obj_t * bg = lv_obj_create(scr, NULL);
|
||||
lv_obj_set_protect(bg, LV_PROTECT_PARENT); /*The page screen move it to scrollable area*/
|
||||
lv_obj_set_parent(bg, scr); /*So movi it back ater protected*/
|
||||
lv_obj_set_style(bg, &style_mbox_bg);
|
||||
lv_obj_set_size(bg, LV_HOR_RES, LV_VER_RES);
|
||||
lv_obj_set_pos(bg, 0, 0);
|
||||
lv_obj_set_click(bg, false); /*For test disable click there fore buttons under it remain clickable*/
|
||||
|
||||
/*Create a message box*/
|
||||
lv_obj_t * mbox = lv_mbox_create(bg, NULL);
|
||||
lv_mbox_set_text(mbox, "Really Enable the outputs?");
|
||||
lv_group_add_obj(g, mbox); /*Add to he group*/
|
||||
|
||||
/*Add two buttons*/
|
||||
lv_mbox_add_btn(mbox, "Yes", mbox_yes_action);
|
||||
lv_mbox_add_btn(mbox, "No", mbox_no_action);
|
||||
|
||||
lv_obj_align(mbox, NULL, LV_ALIGN_CENTER, 0, - LV_DPI / 2);
|
||||
|
||||
/*Focus on the new message box, can freeze focus on it*/
|
||||
lv_group_focus_obj(mbox);
|
||||
lv_group_focus_freeze(g, true);
|
||||
}
|
||||
/*Disable is not dangerous so just change the button state*/
|
||||
else {
|
||||
lv_btn_set_state(btn_enable, LV_BTN_STATE_REL);
|
||||
}
|
||||
return LV_ACTION_RES_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when the message box's 'Yes' button is released
|
||||
* @param btn pointer to the 'Yes' button
|
||||
* @param dispi pointer to the caller display input or NULL if the encoder used
|
||||
* @return LV_ACTION_RES_INV: because the button along with the message box will be deleted
|
||||
*/
|
||||
static lv_action_res_t mbox_yes_action(lv_obj_t * btn, lv_dispi_t * dispi)
|
||||
{
|
||||
lv_group_focus_freeze(g, false); /*Release the freeze*/
|
||||
lv_obj_t * mbox = lv_mbox_get_from_btn(btn);
|
||||
lv_obj_del(lv_obj_get_parent(mbox)); /*Delete the black background. (it will delete the mbox too)*/
|
||||
|
||||
/*Mark the enabled state by toggling the button*/
|
||||
lv_btn_set_state(btn_enable, LV_BTN_STATE_TREL);
|
||||
|
||||
/* In a real case you can add some specific actions here
|
||||
* to really enable something */
|
||||
|
||||
return LV_ACTION_RES_INV;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when the message box's 'No' button is released
|
||||
* @param btn pointer to the 'No' button
|
||||
* @param dispi pointer to the caller display input or NULL if the encoder used
|
||||
* @return LV_ACTION_RES_INV: because the button along with the message box will be deleted
|
||||
*/
|
||||
static lv_action_res_t mbox_no_action(lv_obj_t * btn, lv_dispi_t * dispi)
|
||||
{
|
||||
lv_group_focus_freeze(g, false); /*Release the freeze*/
|
||||
lv_obj_t * mbox = lv_mbox_get_from_btn(btn);
|
||||
lv_obj_del(lv_obj_get_parent(mbox)); /*Delete the black background. (it will delete the mbox too)*/
|
||||
|
||||
return LV_ACTION_RES_INV;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when the Encoder emulator's Next button is released
|
||||
* @param btn pointer to the button
|
||||
* @param dispi pointer to the caller display input
|
||||
* @return LV_ACTION_RES_OK: because the button is not deleted
|
||||
*/
|
||||
static lv_action_res_t enc_next(lv_obj_t * btn, lv_dispi_t * dispi)
|
||||
{
|
||||
/*Focus on the next object in the group*/
|
||||
lv_group_focus_next(g);
|
||||
|
||||
return LV_ACTION_RES_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when the Encoder emulator's Increment button is released
|
||||
* @param btn pointer to the button
|
||||
* @param dispi pointer to the caller display input
|
||||
* @return LV_ACTION_RES_OK: because the button is not deleted
|
||||
*/
|
||||
static lv_action_res_t enc_inc(lv_obj_t * btn, lv_dispi_t * dispi)
|
||||
{
|
||||
/* Send RIGHT key when rotate to right.
|
||||
* It will trigger an increment like action in the object */
|
||||
lv_group_send(g, LV_GROUP_KEY_RIGHT);
|
||||
return LV_ACTION_RES_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when the Encoder emulator's Increment button is released
|
||||
* @param btn pointer to the button
|
||||
* @param dispi pointer to the caller display input
|
||||
* @return LV_ACTION_RES_OK: because the button is not deleted
|
||||
*/
|
||||
static lv_action_res_t enc_dec(lv_obj_t * btn, lv_dispi_t * dispi)
|
||||
{
|
||||
/* Send LEFT key when rotate to left.
|
||||
* It will trigger a decrement like action in the object */
|
||||
lv_group_send(g, LV_GROUP_KEY_LEFT);
|
||||
|
||||
return LV_ACTION_RES_OK;
|
||||
}
|
||||
/**
|
||||
* Called when the Encoder emulator's Send button is released
|
||||
* @param btn pointer to the button
|
||||
* @param dispi pointer to the caller display input
|
||||
* @return LV_ACTION_RES_OK: because the button is not deleted
|
||||
*/
|
||||
static lv_action_res_t enc_sel(lv_obj_t * btn, lv_dispi_t * dispi)
|
||||
{
|
||||
/* Send ENTER key.
|
||||
* It will trigger an 'OK' or 'Select' action in the object */
|
||||
lv_group_send(g, LV_GROUP_KEY_ENTER);
|
||||
|
||||
return LV_ACTION_RES_OK;
|
||||
}
|
||||
|
||||
#endif /*USE_LV_EXAMPLE != 0*/
|
||||
42
lv_examples/2_2_encoder_ctrl/lv_ex_encoder_ctrl.h
Normal file
42
lv_examples/2_2_encoder_ctrl/lv_ex_encoder_ctrl.h
Normal file
@@ -0,0 +1,42 @@
|
||||
/**
|
||||
* @file lv_ex_encoder_ctrl.h
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LV_EX_ENCODER_CTRL_H
|
||||
#define LV_EX_ENCODER_CTRL_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "lv_conf.h"
|
||||
#if USE_LV_EXAMPLE != 0
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
void lv_ex_encoder_ctrl(void);
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
#endif /*USE_LV_EXAMPLE != 0*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif /*ENCODER_CTRL_H*/
|
||||
BIN
lv_examples/2_2_encoder_ctrl/lv_ex_encoder_ctrl.png
Normal file
BIN
lv_examples/2_2_encoder_ctrl/lv_ex_encoder_ctrl.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 8.8 KiB |
0
lv_examples/2_3_keyboard_ctrl/lv_ex_keyboard_ctrl.c
Normal file
0
lv_examples/2_3_keyboard_ctrl/lv_ex_keyboard_ctrl.c
Normal file
0
lv_examples/2_3_keyboard_ctrl/lv_ex_keyboard_ctrl.h
Normal file
0
lv_examples/2_3_keyboard_ctrl/lv_ex_keyboard_ctrl.h
Normal file
0
lv_examples/2_4_mouse_ctrl/lv_ex_mouse_ctrl.c
Normal file
0
lv_examples/2_4_mouse_ctrl/lv_ex_mouse_ctrl.c
Normal file
0
lv_examples/2_4_mouse_ctrl/lv_ex_mouse_ctrl.h
Normal file
0
lv_examples/2_4_mouse_ctrl/lv_ex_mouse_ctrl.h
Normal file
0
lv_examples/3_1_app_desktop/lv_ex_app_desktop.c
Normal file
0
lv_examples/3_1_app_desktop/lv_ex_app_desktop.c
Normal file
0
lv_examples/3_1_app_desktop/lv_ex_app_desktop.h
Normal file
0
lv_examples/3_1_app_desktop/lv_ex_app_desktop.h
Normal file
0
lv_examples/3_2_app_run/lv_ex_app_run.c
Normal file
0
lv_examples/3_2_app_run/lv_ex_app_run.c
Normal file
0
lv_examples/3_2_app_run/lv_ex_app_run.h
Normal file
0
lv_examples/3_2_app_run/lv_ex_app_run.h
Normal file
0
lv_examples/3_3_app_com/lv_ex_app_com.c
Normal file
0
lv_examples/3_3_app_com/lv_ex_app_com.c
Normal file
0
lv_examples/3_3_app_com/lv_ex_app_com.h
Normal file
0
lv_examples/3_3_app_com/lv_ex_app_com.h
Normal file
41
lv_examples/README.md
Normal file
41
lv_examples/README.md
Normal file
@@ -0,0 +1,41 @@
|
||||
# EXAMPLES FOR LITTLEV GRAPHICS LIBRARY
|
||||
|
||||
## Introduction
|
||||
In the folders you will find simple hardware independent examples to know the key features of Littlev Graphics Library.
|
||||
The examples are organized in consistent way and can be used as a **Tutorial**.
|
||||
|
||||
Every example consist of least an *example_name.c* and *example_name.h* files. You can load an example in your *main* function with **example_name_init()**. The header file has to be included too.
|
||||
|
||||
You will find **detailed explanation** in the *c* and *h* files.
|
||||
|
||||
The examples can be enabled/disabled in *lv_conf.h* with **USE_LV_EXAMPLES**.
|
||||
|
||||
## 1_x Getting started
|
||||
With examples in this section you can learn the basics from a simple *Hello world* label to a complex full featured GUI with animations and other effects. You will learn about
|
||||
- creating, deleting graphical objects
|
||||
- modify their attributes
|
||||
- change their style
|
||||
- and even creating a new object type
|
||||
|
||||
## 2_x GUI control without Touchpad
|
||||
You can control your GUI not only with Touchpad. The most simple way to put real buttons next to the graphical ones and simulate *touch pad-like press* on the display. An other way is to organize the objects in groups and *focus* on one of objects. Then you can control the object-in-focus with simple character instructions. Or using a cursor and mouse is also possible. So an external control device can be
|
||||
- push buttons
|
||||
- encoders
|
||||
- keyboard
|
||||
- or a mouse
|
||||
|
||||
In this section you will find examples for them!
|
||||
|
||||
## 3_x Applications
|
||||
The applications are high level components to do complex thing with a nice user interface. An application can be for example
|
||||
- WiFi network manager
|
||||
- File system browser
|
||||
- System monitor
|
||||
- Terminal etc.
|
||||
|
||||
Here you will find examples how to run application, and communicate with them.
|
||||
|
||||
## Final words
|
||||
If you also have codes which could be useful for others, please share it via *Pull requests* on *GitHub*!
|
||||
Thank you in advance!
|
||||
|
||||
264
lv_obj/lv_group.c
Normal file
264
lv_obj/lv_group.c
Normal file
@@ -0,0 +1,264 @@
|
||||
/**
|
||||
* @file lv_group.c
|
||||
*
|
||||
*/
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "lv_group.h"
|
||||
#if LV_OBJ_GROUP != 0
|
||||
#include <stddef.h>
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
static void style_mod_def(lv_style_t * style);
|
||||
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL FUNCTIONS
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Create a new object group
|
||||
* @return pointer to the new object group
|
||||
*/
|
||||
lv_group_t * lv_group_create(void)
|
||||
{
|
||||
lv_group_t * group = dm_alloc(sizeof(lv_group_t));
|
||||
ll_init(&group->obj_ll, sizeof(lv_obj_t *));
|
||||
|
||||
group->style_mod = style_mod_def;
|
||||
group->obj_focus = NULL;
|
||||
group->frozen = 0;
|
||||
|
||||
return group;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add an object to a group
|
||||
* @param group pointer to a group
|
||||
* @param obj pointer to an object to add
|
||||
*/
|
||||
void lv_group_add_obj(lv_group_t * group, lv_obj_t * obj)
|
||||
{
|
||||
obj->group_p = group;
|
||||
lv_obj_t ** next = ll_ins_tail(&group->obj_ll);
|
||||
*next = obj;
|
||||
|
||||
/* If the head and the tail is equal then there is only one object in the linked list.
|
||||
* In this case automatically activate it*/
|
||||
if(ll_get_head(&group->obj_ll) == next) {
|
||||
lv_group_focus_next(group);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove an object from its group
|
||||
* @param obj pointer to an objectto remove
|
||||
*/
|
||||
void lv_group_rem_obj(lv_obj_t * obj)
|
||||
{
|
||||
lv_group_t * g = obj->group_p;
|
||||
if(g == NULL) return;
|
||||
lv_obj_t ** i;
|
||||
|
||||
LL_READ(g->obj_ll, i) {
|
||||
if(*i == obj) {
|
||||
ll_rem(&g->obj_ll, i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(*g->obj_focus == obj) {
|
||||
g->obj_focus = NULL;
|
||||
lv_group_focus_next(g);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Focus on an object (defocus the current)
|
||||
* @param obj pointer to an object to focus on
|
||||
*/
|
||||
void lv_group_focus_obj(lv_obj_t * obj)
|
||||
{
|
||||
lv_group_t * g = obj->group_p;
|
||||
if(g == NULL) return;
|
||||
|
||||
if(g->frozen != 0) return;
|
||||
|
||||
lv_obj_t ** i;
|
||||
|
||||
LL_READ(g->obj_ll, i) {
|
||||
if(*i == obj) {
|
||||
if(g->obj_focus != NULL) {
|
||||
(*g->obj_focus)->signal_f(*g->obj_focus, LV_SIGNAL_DEFOCUS, NULL);
|
||||
lv_obj_inv(*g->obj_focus);
|
||||
}
|
||||
|
||||
g->obj_focus = i;
|
||||
|
||||
if(g->obj_focus != NULL){
|
||||
(*g->obj_focus)->signal_f(*g->obj_focus, LV_SIGNAL_FOCUS, NULL);
|
||||
lv_obj_inv(*g->obj_focus);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Focus the next object in a group (defocus the current)
|
||||
* @param group pointer to a group
|
||||
*/
|
||||
void lv_group_focus_next(lv_group_t * group)
|
||||
{
|
||||
if(group->frozen != 0) return;
|
||||
|
||||
if(group->obj_focus != NULL) {
|
||||
(*group->obj_focus)->signal_f(*group->obj_focus, LV_SIGNAL_DEFOCUS, NULL);
|
||||
lv_obj_inv(*group->obj_focus);
|
||||
}
|
||||
|
||||
lv_obj_t ** obj_next;
|
||||
if(group->obj_focus == NULL) obj_next = ll_get_head(&group->obj_ll);
|
||||
else obj_next = ll_get_next(&group->obj_ll, group->obj_focus);
|
||||
|
||||
if(obj_next == NULL) obj_next = ll_get_head(&group->obj_ll);
|
||||
group->obj_focus = obj_next;
|
||||
|
||||
if(group->obj_focus != NULL){
|
||||
(*group->obj_focus)->signal_f(*group->obj_focus, LV_SIGNAL_FOCUS, NULL);
|
||||
lv_obj_inv(*group->obj_focus);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Focus the previous object in a group (defocus the current)
|
||||
* @param group pointer to a group
|
||||
*/
|
||||
void lv_group_focus_prev(lv_group_t * group)
|
||||
{
|
||||
if(group->frozen != 0) return;
|
||||
|
||||
if(group->obj_focus != NULL) {
|
||||
(*group->obj_focus)->signal_f(*group->obj_focus, LV_SIGNAL_DEFOCUS, NULL);
|
||||
lv_obj_inv(*group->obj_focus);
|
||||
}
|
||||
|
||||
lv_obj_t ** obj_next;
|
||||
if(group->obj_focus == NULL) obj_next = ll_get_tail(&group->obj_ll);
|
||||
else obj_next = ll_get_prev(&group->obj_ll, group->obj_focus);
|
||||
|
||||
if(obj_next == NULL) obj_next = ll_get_tail(&group->obj_ll);
|
||||
group->obj_focus = obj_next;
|
||||
|
||||
if(group->obj_focus != NULL){
|
||||
(*group->obj_focus)->signal_f(*group->obj_focus, LV_SIGNAL_FOCUS, NULL);
|
||||
lv_obj_inv(*group->obj_focus);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Do not let to change the focus from the current object
|
||||
* @param group pointer to a group
|
||||
* @param en true: freeze, false: release freezing (normal mode)
|
||||
*/
|
||||
void lv_group_focus_freeze(lv_group_t * group, bool en)
|
||||
{
|
||||
if(en == false) group->frozen = 0;
|
||||
else group->frozen = 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Send a control character to the focuses object of a group
|
||||
* @param group pointer to a group
|
||||
* @param c a control character (use LV_GROUP_KEY_.. to navigate)
|
||||
*/
|
||||
void lv_group_send(lv_group_t * group, char c)
|
||||
{
|
||||
lv_obj_t * act = lv_group_get_focused(group);
|
||||
if(act == NULL) return;
|
||||
|
||||
act->signal_f(act, LV_SIGNAL_CONTROLL, &c);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set a function for a group which will modify the object's style if it is in focus
|
||||
* @param group pointer to a group
|
||||
* @param style_cb the style modifier function pointer
|
||||
*/
|
||||
void lv_group_set_style_mod_cb(lv_group_t * group, void (*style_cb)(lv_style_t * style))
|
||||
{
|
||||
group->style_mod = style_cb;
|
||||
if(group->obj_focus != NULL) lv_obj_inv(*group->obj_focus);
|
||||
}
|
||||
|
||||
/**
|
||||
* Modify a style with the set 'style_mod' function. The input style remains unchanged.
|
||||
* @param group pointer to group
|
||||
* @param style pointer to a style to modify
|
||||
* @return a copy of the input style but modified with the 'style_mod' function
|
||||
*/
|
||||
lv_style_t * lv_group_mod_style(lv_group_t * group, const lv_style_t * style)
|
||||
{
|
||||
lv_style_cpy(&group->style_tmp, style);
|
||||
|
||||
if(group->style_mod != NULL) group->style_mod(&group->style_tmp);
|
||||
else style_mod_def(&group->style_tmp);
|
||||
|
||||
return &group->style_tmp;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the focused object or NULL if there isn't one
|
||||
* @param group pointer to a group
|
||||
* @return pointer to the focused object
|
||||
*/
|
||||
lv_obj_t * lv_group_get_focused(lv_group_t * group)
|
||||
{
|
||||
if(group == NULL) return NULL;
|
||||
if(group->obj_focus == NULL) return NULL;
|
||||
|
||||
return *group->obj_focus;
|
||||
}
|
||||
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Default style modifier function
|
||||
* @param style pointer to a style to modify. (Typically &group->style_tmp) It will be OVERWRITTEN.
|
||||
*/
|
||||
static void style_mod_def(lv_style_t * style)
|
||||
{
|
||||
/*Make the style a little bit orange*/
|
||||
style->bcolor = COLOR_ORANGE;
|
||||
style->bopa = OPA_COVER;
|
||||
if(style->bwidth == 0 && style->empty == 0) style->bwidth = 2 * LV_DOWNSCALE; /*Add border to not transparent styles*/
|
||||
else style->bwidth = style->bwidth * 2; /*Make the border thicker*/
|
||||
style->mcolor = color_mix(style->mcolor, COLOR_ORANGE, OPA_80);
|
||||
style->gcolor = color_mix(style->gcolor, COLOR_ORANGE, OPA_80);
|
||||
}
|
||||
|
||||
#endif /*LV_OBJ_GROUP != 0*/
|
||||
68
lv_obj/lv_group.h
Normal file
68
lv_obj/lv_group.h
Normal file
@@ -0,0 +1,68 @@
|
||||
/**
|
||||
* @file lv_group.h
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LV_GROUP_H
|
||||
#define LV_GROUP_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "lv_conf.h"
|
||||
#include "lv_obj.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
/*Predefined keys to control the focused object via lv_group_send(group, c)*/
|
||||
/*For compatibility in signal function define the keys regardless to LV_OBJ_GROUP*/
|
||||
#define LV_GROUP_KEY_UP 17 /*0x11*/
|
||||
#define LV_GROUP_KEY_DOWN 18 /*0x12*/
|
||||
#define LV_GROUP_KEY_RIGHT 19 /*0x13*/
|
||||
#define LV_GROUP_KEY_LEFT 20 /*0x14*/
|
||||
#define LV_GROUP_KEY_ESC 33 /*0x1B*/
|
||||
#define LV_GROUP_KEY_ENTER 10 /*0x0A, '\n'*/
|
||||
|
||||
#if LV_OBJ_GROUP != 0
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
typedef struct
|
||||
{
|
||||
ll_dsc_t obj_ll;
|
||||
lv_obj_t ** obj_focus;
|
||||
void (*style_mod)(lv_style_t * style);
|
||||
lv_style_t style_tmp;
|
||||
uint8_t frozen:1;
|
||||
}lv_group_t;
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
lv_group_t * lv_group_create(void);
|
||||
void lv_group_add_obj(lv_group_t * group, lv_obj_t * obj);
|
||||
void lv_group_rem_obj(lv_obj_t * obj);
|
||||
void lv_group_focus_obj(lv_obj_t * obj);
|
||||
void lv_group_focus_next(lv_group_t * group);
|
||||
void lv_group_focus_prev(lv_group_t * group);
|
||||
void lv_group_focus_freeze(lv_group_t * group, bool en);
|
||||
void lv_group_send(lv_group_t * group, char c);
|
||||
lv_style_t * lv_group_mod_style(lv_group_t * group, const lv_style_t * style);
|
||||
lv_obj_t * lv_group_get_focused(lv_group_t * group);
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
#endif /*LV_OBJ_GROUP != 0*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif /*LV_GROUP_H*/
|
||||
@@ -12,8 +12,10 @@
|
||||
#include "lvgl/lv_obj/lv_dispi.h"
|
||||
#include "lvgl/lv_obj/lv_obj.h"
|
||||
#include "lvgl/lv_obj/lv_refr.h"
|
||||
#include "lvgl/lv_obj/lv_group.h"
|
||||
#include "lvgl/lv_app/lv_app.h"
|
||||
#include "lvgl/lv_draw/lv_draw_rbasic.h"
|
||||
#include "lv_group.h"
|
||||
#include "misc/gfx/anim.h"
|
||||
#include "hal/indev/indev.h"
|
||||
#include <stdint.h>
|
||||
@@ -141,10 +143,14 @@ lv_obj_t * lv_obj_create(lv_obj_t * parent, lv_obj_t * copy)
|
||||
#if LV_OBJ_FREE_NUM != 0
|
||||
new_obj->free_num = 0;
|
||||
#endif
|
||||
|
||||
#if LV_OBJ_FREE_P != 0
|
||||
new_obj->free_p = NULL;
|
||||
#endif
|
||||
|
||||
#if LV_OBJ_GROUP != 0
|
||||
new_obj->group_p = NULL;
|
||||
#endif
|
||||
/*Set attributes*/
|
||||
new_obj->click_en = 0;
|
||||
new_obj->drag_en = 0;
|
||||
@@ -187,6 +193,9 @@ lv_obj_t * lv_obj_create(lv_obj_t * parent, lv_obj_t * copy)
|
||||
#if LV_OBJ_FREE_P != 0
|
||||
new_obj->free_p = NULL;
|
||||
#endif
|
||||
#if LV_OBJ_GROUP != 0
|
||||
new_obj->group_p = NULL;
|
||||
#endif
|
||||
|
||||
/*Set attributes*/
|
||||
new_obj->click_en = 1;
|
||||
@@ -198,7 +207,6 @@ lv_obj_t * lv_obj_create(lv_obj_t * parent, lv_obj_t * copy)
|
||||
new_obj->protect = LV_PROTECT_NONE;
|
||||
|
||||
new_obj->ext = NULL;
|
||||
|
||||
}
|
||||
|
||||
if(copy != NULL) {
|
||||
@@ -223,6 +231,13 @@ lv_obj_t * lv_obj_create(lv_obj_t * parent, lv_obj_t * copy)
|
||||
|
||||
new_obj->style_p = copy->style_p;
|
||||
|
||||
#if LV_OBJ_GROUP != 0
|
||||
/*Add to the same group*/
|
||||
if(copy->group_p != NULL) {
|
||||
lv_group_add_obj(copy->group_p, new_obj);
|
||||
}
|
||||
#endif
|
||||
|
||||
lv_obj_set_pos(new_obj, lv_obj_get_x(copy), lv_obj_get_y(copy));
|
||||
}
|
||||
|
||||
@@ -405,12 +420,14 @@ void lv_obj_set_parent(lv_obj_t * obj, lv_obj_t * parent)
|
||||
old_pos.x = lv_obj_get_x(obj);
|
||||
old_pos.y = lv_obj_get_y(obj);
|
||||
|
||||
lv_obj_t * old_par = obj->par;
|
||||
|
||||
ll_chg_list(&obj->par->child_ll, &parent->child_ll, obj);
|
||||
obj->par = parent;
|
||||
lv_obj_set_pos(obj, old_pos.x, old_pos.y);
|
||||
|
||||
/*Notify the original parent because one of its children is lost*/
|
||||
obj->par->signal_f(obj->par, LV_SIGNAL_CHILD_CHG, NULL);
|
||||
old_par->signal_f(old_par, LV_SIGNAL_CHILD_CHG, NULL);
|
||||
|
||||
/*Notify the new parent about the child*/
|
||||
parent->signal_f(parent, LV_SIGNAL_CHILD_CHG, obj);
|
||||
@@ -1234,20 +1251,28 @@ cord_t lv_obj_get_ext_size(lv_obj_t * obj)
|
||||
*/
|
||||
lv_style_t * lv_obj_get_style(lv_obj_t * obj)
|
||||
{
|
||||
if(obj->style_p != NULL) return obj->style_p;
|
||||
else {
|
||||
lv_style_t * style_act = obj->style_p;
|
||||
if(style_act == NULL) {
|
||||
lv_obj_t * par = obj->par;
|
||||
|
||||
while(par != NULL) {
|
||||
if(par->style_p != NULL) {
|
||||
if(par->style_p->glass == 0) return par->style_p;
|
||||
if(par->style_p->glass == 0) {
|
||||
style_act = par->style_p;
|
||||
break;
|
||||
}
|
||||
}
|
||||
par = par->par;
|
||||
}
|
||||
}
|
||||
|
||||
/*Never reach this, at least the screen has to be a style*/
|
||||
return NULL;
|
||||
#if LV_OBJ_GROUP != 0
|
||||
if(obj->group_p != NULL) {
|
||||
if(lv_group_get_focused(obj->group_p) == obj) {
|
||||
style_act = lv_group_mod_style(obj->group_p, style_act);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return style_act;
|
||||
}
|
||||
|
||||
/*-----------------
|
||||
@@ -1395,6 +1420,18 @@ void * lv_obj_get_free_p(lv_obj_t * obj)
|
||||
}
|
||||
#endif
|
||||
|
||||
#if LV_OBJ_GROUP != 0
|
||||
/**
|
||||
* Get the group of the object
|
||||
* @param obj pointer to an object
|
||||
* @return the pointer to group of the object
|
||||
*/
|
||||
void * lv_obj_get_group(lv_obj_t * obj)
|
||||
{
|
||||
return obj->group_p;
|
||||
}
|
||||
#endif
|
||||
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
@@ -1471,9 +1508,7 @@ static void lv_style_refr_core(void * style_p, lv_obj_t * obj)
|
||||
lv_obj_t * i;
|
||||
LL_READ(obj->child_ll, i) {
|
||||
if(i->style_p == style_p || style_p == NULL) {
|
||||
lv_obj_inv(i);
|
||||
i->signal_f(i, LV_SIGNAL_STYLE_CHG, NULL);
|
||||
lv_obj_inv(i);
|
||||
lv_child_refr_style(i);
|
||||
}
|
||||
|
||||
lv_style_refr_core(style_p, i);
|
||||
@@ -1523,13 +1558,16 @@ static void lv_obj_del_child(lv_obj_t * obj)
|
||||
/*Remove the animations from this object*/
|
||||
anim_del(obj, NULL);
|
||||
|
||||
/*Delete from the group*/
|
||||
#if LV_OBJ_GROUP != 0
|
||||
if(obj->group_p != NULL) lv_group_rem_obj(obj);
|
||||
#endif
|
||||
|
||||
/*Remove the object from parent's children list*/
|
||||
lv_obj_t * par = lv_obj_get_parent(obj);
|
||||
|
||||
ll_rem(&(par->child_ll), obj);
|
||||
|
||||
/* All children deleted.
|
||||
* Now clean up the object specific data*/
|
||||
/* Clean up the object specific data*/
|
||||
obj->signal_f(obj, LV_SIGNAL_CLEANUP, NULL);
|
||||
|
||||
/*Delete the base objects*/
|
||||
|
||||
@@ -72,19 +72,27 @@ typedef bool (* lv_design_f_t) (struct __LV_OBJ_T * obj, const area_t * mask_p,
|
||||
|
||||
typedef enum
|
||||
{
|
||||
/*General signals*/
|
||||
LV_SIGNAL_CLEANUP,
|
||||
LV_SIGNAL_CHILD_CHG,
|
||||
LV_SIGNAL_CORD_CHG,
|
||||
LV_SIGNAL_STYLE_CHG,
|
||||
LV_SIGNAL_REFR_EXT_SIZE,
|
||||
|
||||
/*Display input related*/
|
||||
LV_SIGNAL_PRESSED,
|
||||
LV_SIGNAL_PRESSING,
|
||||
LV_SIGNAL_PRESSING,
|
||||
LV_SIGNAL_PRESS_LOST,
|
||||
LV_SIGNAL_RELEASED,
|
||||
LV_SIGNAL_LONG_PRESS,
|
||||
LV_SIGNAL_LONG_PRESS_REP,
|
||||
LV_SIGNAL_DRAG_BEGIN,
|
||||
LV_SIGNAL_DRAG_END,
|
||||
LV_SIGNAL_CHILD_CHG,
|
||||
LV_SIGNAL_CORD_CHG,
|
||||
LV_SIGNAL_STYLE_CHG,
|
||||
LV_SIGNAL_REFR_EXT_SIZE,
|
||||
LV_SIGNAL_DRAG_END,
|
||||
|
||||
/*Group related*/
|
||||
LV_SIGNAL_FOCUS,
|
||||
LV_SIGNAL_DEFOCUS,
|
||||
LV_SIGNAL_CONTROLL,
|
||||
}lv_signal_t;
|
||||
|
||||
typedef bool (* lv_signal_f_t) (struct __LV_OBJ_T * obj, lv_signal_t sign, void * param);
|
||||
@@ -106,6 +114,8 @@ typedef struct __LV_OBJ_T
|
||||
void * free_p; /*Application specific pointer (set it freely)*/
|
||||
#endif
|
||||
|
||||
void * group_p; /*Pointer to the group of the object*/
|
||||
|
||||
/*Attributes and states*/
|
||||
uint8_t click_en :1; /*1: Can be pressed by a display input device*/
|
||||
uint8_t drag_en :1; /*1: Enable the dragging*/
|
||||
@@ -159,13 +169,6 @@ typedef enum
|
||||
LV_ALIGN_OUT_RIGHT_BOTTOM,
|
||||
}lv_align_t;
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
color_t color;
|
||||
opa_t opa;
|
||||
}lv_objs_t;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
LV_ANIM_NONE = 0,
|
||||
@@ -473,6 +476,7 @@ void lv_obj_set_free_num(lv_obj_t * obj, uint8_t free_num);
|
||||
*/
|
||||
void lv_obj_set_free_p(lv_obj_t * obj, void * free_p);
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Animate an object
|
||||
* @param obj pointer to an object to animate
|
||||
@@ -665,6 +669,14 @@ uint8_t lv_obj_get_free_num(lv_obj_t * obj);
|
||||
void * lv_obj_get_free_p(lv_obj_t * obj);
|
||||
#endif
|
||||
|
||||
#if LV_OBJ_GROUP != 0
|
||||
/**
|
||||
* Get the group of the object
|
||||
* @param obj pointer to an object
|
||||
* @return the pointer to group of the object
|
||||
*/
|
||||
void * lv_obj_get_group(lv_obj_t * obj);
|
||||
#endif
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
@@ -70,7 +70,6 @@ void lv_refr_init(void)
|
||||
ptask_t* task;
|
||||
task = ptask_create(lv_refr_task, LV_REFR_PERIOD, PTASK_PRIO_MID, NULL);
|
||||
dm_assert(task);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -130,7 +129,7 @@ void lv_inv_area(const area_t * area_p)
|
||||
* @param cb pointer to a callback function (void my_refr_cb(uint32_t time_ms, uint32_t px_num))
|
||||
* time_ms: refresh time in [ms]
|
||||
* px_num: not the drawn pixels but the number of affected pixels of the screen
|
||||
* (more pixels are drawn with opacity areas)
|
||||
* (more pixels are drawn because of overlapping objects)
|
||||
*/
|
||||
void lv_refr_set_monitor_cb(void (*cb)(uint32_t, uint32_t))
|
||||
{
|
||||
@@ -257,15 +256,8 @@ static void lv_refr_area_no_vdb(const area_t * area_p)
|
||||
*/
|
||||
static void lv_refr_area_with_vdb(const area_t * area_p)
|
||||
{
|
||||
lv_vdb_t * vdb_p = lv_vdb_get();
|
||||
|
||||
/*Always use the full row*/
|
||||
vdb_p->area.x1 = area_p->x1;
|
||||
vdb_p->area.y1 = area_p->y1;
|
||||
vdb_p->area.x2 = area_p->x2;
|
||||
|
||||
/*Calculate the max row num*/
|
||||
uint32_t max_row = (uint32_t) LV_VDB_SIZE / (vdb_p->area.x2 - vdb_p->area.x1 + 1);
|
||||
uint32_t max_row = (uint32_t) LV_VDB_SIZE / (area_get_width(area_p));
|
||||
if(max_row > area_get_height(area_p)) max_row = area_get_height(area_p);
|
||||
|
||||
/*Round the row number with downscale*/
|
||||
@@ -273,20 +265,28 @@ static void lv_refr_area_with_vdb(const area_t * area_p)
|
||||
max_row &= (~0x1);
|
||||
#endif
|
||||
|
||||
/*Refresh all rows*/
|
||||
cord_t row = area_p->y1;
|
||||
|
||||
/*Always use the full row*/
|
||||
cord_t row;
|
||||
cord_t row_last = 0;
|
||||
for(row = area_p->y1; row + max_row - 1 <= area_p->y2; row += max_row) {
|
||||
lv_vdb_t * vdb_p = lv_vdb_get();
|
||||
|
||||
/*Calc. the next y coordinates of VDB*/
|
||||
vdb_p->area.x1 = area_p->x1;
|
||||
vdb_p->area.x2 = area_p->x2;
|
||||
vdb_p->area.y1 = row;
|
||||
vdb_p->area.y2 = row + max_row - 1;
|
||||
|
||||
row_last = row + max_row - 1;
|
||||
lv_refr_area_part_vdb(area_p);
|
||||
}
|
||||
|
||||
/*If the last y coordinates are not handled yet ...*/
|
||||
if(area_p->y2 != vdb_p->area.y2) {
|
||||
if(area_p->y2 != row_last) {
|
||||
lv_vdb_t * vdb_p = lv_vdb_get();
|
||||
|
||||
/*Calc. the next y coordinates of VDB*/
|
||||
vdb_p->area.x1 = area_p->x1;
|
||||
vdb_p->area.x2 = area_p->x2;
|
||||
vdb_p->area.y1 = row;
|
||||
vdb_p->area.y2 = area_p->y2;
|
||||
|
||||
|
||||
@@ -8,18 +8,31 @@
|
||||
*********************/
|
||||
#include "lv_conf.h"
|
||||
#include "lv_style.h"
|
||||
#include "lv_obj.h"
|
||||
#include "misc/mem/dyn_mem.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
#define LV_STYLE_ANIM_RES 255 /*Animation max in 1024 steps*/
|
||||
#define LV_STYLE_ANIM_SHIFT 8 /*log2(LV_STYLE_ANIM_RES)*/
|
||||
|
||||
#define VAL_PROP(v1, v2, r) v1 + (((v2-v1) * r) >> LV_STYLE_ANIM_SHIFT)
|
||||
#define STYLE_ATTR_ANIM(attr, r) if(start->attr != end->attr) act->attr = VAL_PROP(start->attr, end->attr, r)
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
typedef struct {
|
||||
const lv_style_t * style_start;
|
||||
const lv_style_t * style_end;
|
||||
lv_style_t * style_anim;
|
||||
}lv_style_anim_dsc_t;
|
||||
|
||||
/**********************
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
static void lv_style_aimator(lv_style_anim_dsc_t * dsc, int32_t val);
|
||||
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
@@ -229,6 +242,84 @@ void lv_style_cpy(lv_style_t * dest, const lv_style_t * src)
|
||||
memcpy(dest, src, sizeof(lv_style_t));
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an animation from a pre-configured 'lv_style_anim_t' variable
|
||||
* @param anim pointer to a pre-configured 'lv_style_anim_t' variable (will be copied)
|
||||
*/
|
||||
void lv_style_anim_create(lv_style_anim_t * anim)
|
||||
{
|
||||
lv_style_anim_dsc_t * dsc;
|
||||
dsc = dm_alloc(sizeof(lv_style_anim_dsc_t));
|
||||
dsc->style_anim = anim->style_anim;
|
||||
dsc->style_start = anim->style_start;
|
||||
dsc->style_end = anim->style_end;
|
||||
|
||||
anim_t a;
|
||||
a.var = (void*)dsc;
|
||||
a.start = 0;
|
||||
a.end = LV_STYLE_ANIM_RES;
|
||||
a.fp = (anim_fp_t)lv_style_aimator;
|
||||
a.path = anim_get_path(ANIM_PATH_LIN);
|
||||
a.end_cb = anim->end_cb;
|
||||
a.act_time = anim->act_time;
|
||||
a.time = anim->time;
|
||||
a.playback = anim->playback;
|
||||
a.playback_pause = anim->playback_pause;
|
||||
a.repeat = anim->repeat;
|
||||
a.repeat_pause = anim->repeat_pause;
|
||||
|
||||
anim_create(&a);
|
||||
}
|
||||
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Used by the style animations to set the values of a style according to start and end style.
|
||||
* @param dsc the 'animated variable' set by lv_style_anim_create()
|
||||
* @param val the current state of the animation between 0 and LV_STYLE_ANIM_RES
|
||||
*/
|
||||
static void lv_style_aimator(lv_style_anim_dsc_t * dsc, int32_t val)
|
||||
{
|
||||
const lv_style_t * start = dsc->style_start;
|
||||
const lv_style_t * end = dsc->style_end;
|
||||
lv_style_t * act = dsc->style_anim;
|
||||
|
||||
STYLE_ATTR_ANIM(opa, val);
|
||||
STYLE_ATTR_ANIM(radius, val);
|
||||
STYLE_ATTR_ANIM(bwidth, val);
|
||||
STYLE_ATTR_ANIM(swidth, val);
|
||||
STYLE_ATTR_ANIM(hpad, val);
|
||||
STYLE_ATTR_ANIM(vpad, val);
|
||||
STYLE_ATTR_ANIM(opad, val);
|
||||
STYLE_ATTR_ANIM(line_space, val);
|
||||
STYLE_ATTR_ANIM(letter_space, val);
|
||||
STYLE_ATTR_ANIM(line_width, val);
|
||||
STYLE_ATTR_ANIM(img_recolor, val);
|
||||
|
||||
act->mcolor = color_mix(end->mcolor, start->mcolor, val);
|
||||
act->gcolor = color_mix(end->gcolor, start->gcolor, val);
|
||||
act->bcolor = color_mix(end->bcolor, start->bcolor, val);
|
||||
act->scolor = color_mix(end->scolor, start->scolor, val);
|
||||
act->ccolor = color_mix(end->ccolor, start->ccolor, val);
|
||||
|
||||
|
||||
if(val == 0) {
|
||||
act->empty = start->empty;
|
||||
act->glass = start->glass;
|
||||
act->font = start->font;
|
||||
act->stype = start->stype;
|
||||
act->txt_align = start->txt_align;
|
||||
}
|
||||
|
||||
if(val == LV_STYLE_ANIM_RES) {
|
||||
act->empty = end->empty;
|
||||
act->glass = end->glass;
|
||||
act->font = end->font;
|
||||
act->stype = end->stype;
|
||||
act->txt_align = end->txt_align;
|
||||
}
|
||||
|
||||
lv_style_refr_objs(dsc->style_anim);
|
||||
}
|
||||
|
||||
@@ -17,6 +17,7 @@ extern "C" {
|
||||
#include "misc/gfx/color.h"
|
||||
#include "misc/gfx/area.h"
|
||||
#include "misc/gfx/font.h"
|
||||
#include "misc/gfx/anim.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
@@ -83,6 +84,34 @@ typedef enum {
|
||||
}lv_style_name_t;
|
||||
|
||||
|
||||
typedef struct {
|
||||
const lv_style_t * style_start; /*Pointer to the starting style*/
|
||||
const lv_style_t * style_end; /*Pointer to the destination style*/
|
||||
lv_style_t * style_anim; /*Pointer to a style to animate*/
|
||||
anim_cb_t end_cb; /*Call it when the animation is ready*/
|
||||
int16_t time; /*Animation time in ms*/
|
||||
int16_t act_time; /*Current time in animation. Set to negative to make delay.*/
|
||||
uint16_t playback_pause; /*Wait before play back*/
|
||||
uint16_t repeat_pause; /*Wait before repeat*/
|
||||
uint8_t playback :1; /*When the animation is ready play it back*/
|
||||
uint8_t repeat :1; /*Repeat the animation infinitely*/
|
||||
}lv_style_anim_t;
|
||||
|
||||
/* Example initialization
|
||||
lv_style_anim_t a;
|
||||
a.style_anim = &style_to_anim;
|
||||
a.style_start = &style_1;
|
||||
a.style_end = &style_2;
|
||||
a.act_time = 0;
|
||||
a.time = 1000;
|
||||
a.playback = 0;
|
||||
a.playback_pause = 0;
|
||||
a.repeat = 0;
|
||||
a.repeat_pause = 0;
|
||||
a.end_cb = NULL;
|
||||
lv_style_anim_create(&a);
|
||||
*/
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
@@ -99,8 +128,20 @@ void lv_style_init (void);
|
||||
*/
|
||||
lv_style_t * lv_style_get(lv_style_name_t style_name, lv_style_t * copy);
|
||||
|
||||
|
||||
/**
|
||||
* Copy a style to an other
|
||||
* @param dest pointer to the destination style
|
||||
* @param src pointer to the source style
|
||||
*/
|
||||
void lv_style_cpy(lv_style_t * dest, const lv_style_t * src);
|
||||
|
||||
/**
|
||||
* Create an animation from a pre-configured 'lv_style_anim_t' variable
|
||||
* @param anim pointer to a pre-configured 'lv_style_anim_t' variable (will be copied)
|
||||
*/
|
||||
void lv_style_anim_create(lv_style_anim_t * anim);
|
||||
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
|
||||
@@ -20,7 +20,13 @@
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
#if LV_VDB_DOUBLE != 0
|
||||
typedef enum {
|
||||
LV_VDB_STATE_FREE = 0,
|
||||
LV_VDB_STATE_ACTIVE,
|
||||
LV_VDB_STATE_FLUSH,
|
||||
} lv_vdb_state_t;
|
||||
#endif
|
||||
/**********************
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
@@ -28,7 +34,12 @@
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
**********************/
|
||||
#if LV_VDB_DOUBLE == 0
|
||||
static lv_vdb_t vdb;
|
||||
#else
|
||||
static lv_vdb_t vdb[2];
|
||||
static volatile lv_vdb_state_t vdb_state[2] = {LV_VDB_STATE_FREE, LV_VDB_STATE_FREE};
|
||||
#endif
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
@@ -39,21 +50,53 @@ static lv_vdb_t vdb;
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Get the vdb variable
|
||||
* @return pointer to the vdb variable
|
||||
* Get the 'vdb' variable or allocate one in LV_VDB_DOUBLE mode
|
||||
* @return pointer to the 'vdb' variable
|
||||
*/
|
||||
lv_vdb_t * lv_vdb_get(void)
|
||||
{
|
||||
#if LV_VDB_DOUBLE == 0
|
||||
return &vdb;
|
||||
#else
|
||||
/*If already there is an active do nothing*/
|
||||
if(vdb_state[0] == LV_VDB_STATE_ACTIVE) return &vdb[0];
|
||||
if(vdb_state[1] == LV_VDB_STATE_ACTIVE) return &vdb[1];
|
||||
|
||||
/*Try to allocate a free VDB*/
|
||||
if(vdb_state[0] == LV_VDB_STATE_FREE) {
|
||||
vdb_state[0] = LV_VDB_STATE_ACTIVE;
|
||||
return &vdb[0];
|
||||
}
|
||||
|
||||
if(vdb_state[1] == LV_VDB_STATE_FREE) {
|
||||
vdb_state[1] = LV_VDB_STATE_ACTIVE;
|
||||
return &vdb[1];
|
||||
}
|
||||
|
||||
return NULL; /*There wasn't free VDB (never happen)*/
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* Flush the content of the vdb
|
||||
* Flush the content of the VDB
|
||||
*/
|
||||
void lv_vdb_flush(void)
|
||||
{
|
||||
lv_vdb_t * vdb_act = lv_vdb_get();
|
||||
if(vdb_act == NULL) return;
|
||||
|
||||
#if LV_VDB_DOUBLE != 0
|
||||
/* Wait the pending flush before starting this one
|
||||
* (Don't forget: 'lv_vdb_flush_ready' has to be called when flushing is ready)*/
|
||||
while(vdb_state[0] == LV_VDB_STATE_FLUSH || vdb_state[1] == LV_VDB_STATE_FLUSH);
|
||||
|
||||
/*Turn the active VDB to flushing*/
|
||||
if(vdb_state[0] == LV_VDB_STATE_ACTIVE) vdb_state[0] = LV_VDB_STATE_FLUSH;
|
||||
if(vdb_state[1] == LV_VDB_STATE_ACTIVE) vdb_state[1] = LV_VDB_STATE_FLUSH;
|
||||
#endif
|
||||
|
||||
#if LV_ANTIALIAS == 0
|
||||
disp_map(vdb.area.x1, vdb.area.y1, vdb.area.x2, vdb.area.y2, vdb.buf);
|
||||
disp_map(vdb_act->area.x1, vdb_act->area.y1, vdb_act->area.x2, vdb_act->area.y2, vdb_act->buf);
|
||||
#else
|
||||
/* Get the average of 2x2 pixels and put the result back to the VDB
|
||||
* The reading goes much faster then the write back
|
||||
@@ -68,12 +111,12 @@ void lv_vdb_flush(void)
|
||||
* */
|
||||
cord_t x;
|
||||
cord_t y;
|
||||
cord_t w = area_get_width(&vdb.area);
|
||||
color_t * in1_buf = vdb.buf; /*Pointer to the first row*/
|
||||
color_t * in2_buf = vdb.buf + w; /*Pointer to the second row*/
|
||||
color_t * out_buf = vdb.buf; /*Store the result here*/
|
||||
for(y = vdb.area.y1; y < vdb.area.y2; y += 2) {
|
||||
for(x = vdb.area.x1; x < vdb.area.x2; x += 2) {
|
||||
cord_t w = area_get_width(&vdb_act->area);
|
||||
color_t * in1_buf = vdb_act->buf; /*Pointer to the first row*/
|
||||
color_t * in2_buf = vdb_act->buf + w; /*Pointer to the second row*/
|
||||
color_t * out_buf = vdb_act->buf; /*Store the result here*/
|
||||
for(y = vdb_act->area.y1; y < vdb_act->area.y2; y += 2) {
|
||||
for(x = vdb_act->area.x1; x < vdb_act->area.x2; x += 2) {
|
||||
|
||||
/*If the pixels are the same do not calculate the average */
|
||||
if(in1_buf->full == (in1_buf + 1)->full &&
|
||||
@@ -103,7 +146,19 @@ void lv_vdb_flush(void)
|
||||
|
||||
/* Now the full the VDB is filtered and the result is stored in the first quarter of it
|
||||
* Write out the filtered map to the display*/
|
||||
disp_map(vdb.area.x1 >> 1, vdb.area.y1 >> 1, vdb.area.x2 >> 1, vdb.area.y2 >> 1, vdb.buf);
|
||||
disp_map(vdb_act->area.x1 >> 1, vdb_act->area.y1 >> 1, vdb_act->area.x2 >> 1, vdb_act->area.y2 >> 1, vdb_act->buf);
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* In 'LV_VDB_DOUBLE' mode has to be called when the 'disp_map'
|
||||
* is ready with copying the map to a frame buffer.
|
||||
*/
|
||||
void lv_vdb_flush_ready(void)
|
||||
{
|
||||
#if LV_VDB_DOUBLE != 0
|
||||
if(vdb_state[0] == LV_VDB_STATE_FLUSH) vdb_state[0] = LV_VDB_STATE_FREE;
|
||||
if(vdb_state[1] == LV_VDB_STATE_FLUSH) vdb_state[1] = LV_VDB_STATE_FREE;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -34,15 +34,13 @@ typedef struct
|
||||
color_t buf[LV_VDB_SIZE];
|
||||
}lv_vdb_t;
|
||||
|
||||
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Get the vdb variable
|
||||
* @return pointer to the vdb variable
|
||||
* Get the 'vdb' variable or allocate one in LV_VDB_DOUBLE mode
|
||||
* @return pointer to the 'vdb' variable
|
||||
*/
|
||||
lv_vdb_t * lv_vdb_get(void);
|
||||
|
||||
@@ -51,6 +49,13 @@ lv_vdb_t * lv_vdb_get(void);
|
||||
*/
|
||||
void lv_vdb_flush(void);
|
||||
|
||||
|
||||
/**
|
||||
* In 'LV_VDB_DOUBLE' mode has to be called when 'disp_map()'
|
||||
* is ready with copying the map to a frame buffer.
|
||||
*/
|
||||
void lv_vdb_flush_ready(void);
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
@@ -10,11 +10,11 @@
|
||||
#include "lv_conf.h"
|
||||
#if USE_LV_BTN != 0
|
||||
|
||||
#include "lvgl/lv_obj/lv_obj.h"
|
||||
#include "lv_btn.h"
|
||||
#include "../lv_obj/lv_group.h"
|
||||
#include "../lv_draw/lv_draw.h"
|
||||
#include "misc/gfx/area.h"
|
||||
#include "misc/gfx/color.h"
|
||||
#include "../lv_draw/lv_draw.h"
|
||||
#include "lv_btn.h"
|
||||
#include <stdbool.h>
|
||||
#include <string.h>
|
||||
|
||||
@@ -185,6 +185,31 @@ bool lv_btn_signal(lv_obj_t * btn, lv_signal_t sign, void * param)
|
||||
if(ext->lpr_rep_action != NULL && state != LV_BTN_STATE_INA) {
|
||||
valid = ext->lpr_rep_action(btn, param);
|
||||
}
|
||||
} else if(sign == LV_SIGNAL_CONTROLL) {
|
||||
lv_btn_ext_t * ext = lv_obj_get_ext(btn);
|
||||
char c = *((char*)param);
|
||||
if(c == LV_GROUP_KEY_RIGHT || c == LV_GROUP_KEY_UP) {
|
||||
if(lv_btn_get_tgl(btn) != false) lv_btn_set_state(btn, LV_BTN_STATE_TREL);
|
||||
if(ext->rel_action != NULL && lv_btn_get_state(btn) != LV_BTN_STATE_INA) {
|
||||
valid = ext->rel_action(btn, param);
|
||||
}
|
||||
} else if(c == LV_GROUP_KEY_LEFT || c == LV_GROUP_KEY_DOWN) {
|
||||
if(lv_btn_get_tgl(btn) != false) lv_btn_set_state(btn, LV_BTN_STATE_REL);
|
||||
if(ext->rel_action != NULL && lv_btn_get_state(btn) != LV_BTN_STATE_INA) {
|
||||
valid = ext->rel_action(btn, param);
|
||||
}
|
||||
} else if(c == LV_GROUP_KEY_ENTER) {
|
||||
if(lv_btn_get_tgl(btn) != false) {
|
||||
lv_btn_state_t state = lv_btn_get_state(btn);
|
||||
if(state == LV_BTN_STATE_REL) lv_btn_set_state(btn, LV_BTN_STATE_TREL);
|
||||
else if(state == LV_BTN_STATE_PR) lv_btn_set_state(btn, LV_BTN_STATE_TPR);
|
||||
else if(state == LV_BTN_STATE_TREL) lv_btn_set_state(btn, LV_BTN_STATE_REL);
|
||||
else if(state == LV_BTN_STATE_TPR) lv_btn_set_state(btn, LV_BTN_STATE_PR);
|
||||
}
|
||||
if(ext->rel_action != NULL && lv_btn_get_state(btn) != LV_BTN_STATE_INA) {
|
||||
valid = ext->rel_action(btn, param);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -321,6 +346,50 @@ bool lv_btn_get_tgl(lv_obj_t * btn)
|
||||
return ext->tgl != 0 ? true : false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the release action of a button
|
||||
* @param btn pointer to a button object
|
||||
* @return pointer to the release action function
|
||||
*/
|
||||
lv_action_t lv_btn_get_rel_action(lv_obj_t * btn)
|
||||
{
|
||||
lv_btn_ext_t * ext = lv_obj_get_ext(btn);
|
||||
return ext->rel_action;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the press action of a button
|
||||
* @param btn pointer to a button object
|
||||
* @return pointer to the press action function
|
||||
*/
|
||||
lv_action_t lv_btn_get_pr_action(lv_obj_t * btn)
|
||||
{
|
||||
lv_btn_ext_t * ext = lv_obj_get_ext(btn);
|
||||
return ext->pr_action;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the long press action of a button
|
||||
* @param btn pointer to a button object
|
||||
* @return pointer to the release action function
|
||||
*/
|
||||
lv_action_t lv_btn_get_lpr_action(lv_obj_t * btn)
|
||||
{
|
||||
lv_btn_ext_t * ext = lv_obj_get_ext(btn);
|
||||
return ext->lpr_action;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the long press repeat action of a button
|
||||
* @param btn pointer to a button object
|
||||
* @return pointer to the long press repeat action function
|
||||
*/
|
||||
lv_action_t lv_btn_get_lpr_rep_action(lv_obj_t * btn)
|
||||
{
|
||||
lv_btn_ext_t * ext = lv_obj_get_ext(btn);
|
||||
return ext->lpr_rep_action;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the style of a button in a given state
|
||||
* @param btn pointer to a button object
|
||||
|
||||
@@ -148,6 +148,32 @@ lv_btn_state_t lv_btn_get_state(lv_obj_t * btn);
|
||||
*/
|
||||
bool lv_btn_get_tgl(lv_obj_t * btn);
|
||||
|
||||
/**
|
||||
* Get the release action of a button
|
||||
* @param btn pointer to a button object
|
||||
* @return pointer to the release action function
|
||||
*/
|
||||
lv_action_t lv_btn_get_rel_action(lv_obj_t * btn);
|
||||
|
||||
/**
|
||||
* Get the press action of a button
|
||||
* @param btn pointer to a button object
|
||||
* @return pointer to the press action function
|
||||
*/
|
||||
lv_action_t lv_btn_get_pr_action(lv_obj_t * btn);
|
||||
|
||||
/**
|
||||
* Get the long press action of a button
|
||||
* @param btn pointer to a button object
|
||||
* @return pointer to the release action function
|
||||
*/
|
||||
lv_action_t lv_btn_get_lpr_action(lv_obj_t * btn);
|
||||
/**
|
||||
* Get the long press repeat action of a button
|
||||
* @param btn pointer to a button object
|
||||
* @return pointer to the long press repeat action function
|
||||
*/
|
||||
lv_action_t lv_btn_get_lpr_rep_action(lv_obj_t * btn);
|
||||
/**
|
||||
* Get the style of a button in a given state
|
||||
* @param btn pointer to a button object
|
||||
|
||||
@@ -10,9 +10,10 @@
|
||||
#if USE_LV_BTNM != 0
|
||||
|
||||
#include "lv_btnm.h"
|
||||
#include "misc/gfx/text.h"
|
||||
#include "../lv_obj/lv_group.h"
|
||||
#include "../lv_draw/lv_draw.h"
|
||||
#include "../lv_obj/lv_refr.h"
|
||||
#include "misc/gfx/text.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
@@ -29,6 +30,7 @@
|
||||
static bool lv_btnm_design(lv_obj_t * btnm, const area_t * mask, lv_design_mode_t mode);
|
||||
static uint8_t lv_btnm_get_width_unit(const char * btn_str);
|
||||
static uint16_t lv_btnm_get_btn_from_point(lv_obj_t * btnm, point_t * p);
|
||||
static uint16_t lv_btnm_get_btn_txt(lv_obj_t * btnm, uint16_t btn_id);
|
||||
static void lv_btnm_create_btns(lv_obj_t * btnm, const char ** map);
|
||||
|
||||
/**********************
|
||||
@@ -155,18 +157,8 @@ bool lv_btnm_signal(lv_obj_t * btnm, lv_signal_t sign, void * param)
|
||||
}
|
||||
else if(sign == LV_SIGNAL_RELEASED || sign == LV_SIGNAL_LONG_PRESS_REP) {
|
||||
if(ext->cb != NULL && ext->btn_pr != LV_BTNM_PR_NONE) {
|
||||
uint16_t txt_i = 0;
|
||||
uint16_t btn_i = 0;
|
||||
|
||||
/* Search the text of ext->btn_pr the buttons text in the map
|
||||
* Skip "\n"-s*/
|
||||
while(btn_i != ext->btn_pr) {
|
||||
btn_i ++;
|
||||
txt_i ++;
|
||||
if(strcmp(ext->map_p[txt_i], "\n") == 0) txt_i ++;
|
||||
}
|
||||
|
||||
ext->cb(btnm, txt_i);
|
||||
uint16_t txt_i = lv_btnm_get_btn_txt(btnm, ext->btn_pr);
|
||||
if(txt_i != LV_BTNM_PR_NONE) ext->cb(btnm, txt_i);
|
||||
}
|
||||
|
||||
if(sign == LV_SIGNAL_RELEASED && ext->btn_pr != LV_BTNM_PR_NONE) {
|
||||
@@ -181,11 +173,30 @@ bool lv_btnm_signal(lv_obj_t * btnm, lv_signal_t sign, void * param)
|
||||
|
||||
ext->btn_pr = LV_BTNM_PR_NONE;
|
||||
}
|
||||
}
|
||||
else if(sign == LV_SIGNAL_PRESS_LOST) {
|
||||
} else if(sign == LV_SIGNAL_PRESS_LOST || sign == LV_SIGNAL_DEFOCUS) {
|
||||
ext->btn_pr = LV_BTNM_PR_NONE;
|
||||
lv_obj_inv(btnm);
|
||||
|
||||
} else if(sign == LV_SIGNAL_FOCUS) {
|
||||
ext->btn_pr = 0;
|
||||
lv_obj_inv(btnm);
|
||||
} else if(sign == LV_SIGNAL_CONTROLL) {
|
||||
lv_btnm_ext_t * ext = lv_obj_get_ext(btnm);
|
||||
char c = *((char*)param);
|
||||
if(c == LV_GROUP_KEY_RIGHT || c == LV_GROUP_KEY_UP) {
|
||||
if(ext->btn_pr == LV_BTNM_PR_NONE) ext->btn_pr = 0;
|
||||
else ext->btn_pr++;
|
||||
if(ext->btn_pr >= ext->btn_cnt - 1) ext->btn_pr = ext->btn_cnt - 1;
|
||||
lv_obj_inv(btnm);
|
||||
} else if(c == LV_GROUP_KEY_LEFT || c == LV_GROUP_KEY_DOWN) {
|
||||
if(ext->btn_pr == LV_BTNM_PR_NONE) ext->btn_pr = 0;
|
||||
if(ext->btn_pr > 0) ext->btn_pr--;
|
||||
lv_obj_inv(btnm);
|
||||
} else if(c == LV_GROUP_KEY_ENTER) {
|
||||
if(ext->cb != NULL) {
|
||||
uint16_t txt_i = lv_btnm_get_btn_txt(btnm, ext->btn_pr);
|
||||
if(txt_i != LV_BTNM_PR_NONE) ext->cb(btnm, txt_i);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -405,7 +416,12 @@ static bool lv_btnm_design(lv_obj_t * btnm, const area_t * mask, lv_design_mode_
|
||||
|
||||
uint16_t btn_i = 0;
|
||||
uint16_t txt_i = 0;
|
||||
for(btn_i = 0; btn_i < ext->btn_cnt; btn_i ++) {
|
||||
for(btn_i = 0; btn_i < ext->btn_cnt; btn_i ++, txt_i ++) {
|
||||
/*Search the next valid text in the map*/
|
||||
while(strcmp(ext->map_p[txt_i], "\n") == 0) txt_i ++;
|
||||
|
||||
if(ext->map_p[txt_i][1] == '\177') continue;
|
||||
|
||||
lv_obj_get_cords(btnm, &area_btnm);
|
||||
|
||||
area_cpy(&area_tmp, &ext->btn_areas[btn_i]);
|
||||
@@ -422,9 +438,6 @@ static bool lv_btnm_design(lv_obj_t * btnm, const area_t * mask, lv_design_mode_
|
||||
|
||||
lv_draw_rect(&area_tmp, mask, btn_style);
|
||||
|
||||
/*Search the next valid text in the map*/
|
||||
while(strcmp(ext->map_p[txt_i], "\n") == 0) txt_i ++;
|
||||
|
||||
/*Calculate the size of the text*/
|
||||
const font_t * font = btn_style->font;
|
||||
point_t txt_size;
|
||||
@@ -438,11 +451,8 @@ static bool lv_btnm_design(lv_obj_t * btnm, const area_t * mask, lv_design_mode_
|
||||
area_tmp.y2 = area_tmp.y1 + txt_size.y;
|
||||
|
||||
lv_draw_label(&area_tmp, mask, btn_style, ext->map_p[txt_i], TXT_FLAG_NONE, NULL);
|
||||
txt_i ++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -486,6 +496,12 @@ static uint8_t lv_btnm_get_width_unit(const char * btn_str)
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gives the button id of a button under a given point
|
||||
* @param btnm pointer to a button matrix object
|
||||
* @param p a point with absolute coordinates
|
||||
* @return the id of the button or LV_BTNM_PR_NONE.
|
||||
*/
|
||||
static uint16_t lv_btnm_get_btn_from_point(lv_obj_t * btnm, point_t * p)
|
||||
{
|
||||
area_t btnm_cords;
|
||||
@@ -510,5 +526,33 @@ static uint16_t lv_btnm_get_btn_from_point(lv_obj_t * btnm, point_t * p)
|
||||
return i;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the text of a button
|
||||
* @param btnm pointer to a button matrix object
|
||||
* @param btn_id button id
|
||||
* @return text id in ext->map_p or LV_BTNM_PR_NONE if 'btn_id' was invalid
|
||||
*/
|
||||
static uint16_t lv_btnm_get_btn_txt(lv_obj_t * btnm, uint16_t btn_id)
|
||||
{
|
||||
lv_btnm_ext_t * ext = lv_obj_get_ext(btnm);
|
||||
if(btn_id > ext->btn_cnt) return LV_BTNM_PR_NONE;
|
||||
|
||||
uint16_t txt_i = 0;
|
||||
uint16_t btn_i = 0;
|
||||
|
||||
/* Search the text of ext->btn_pr the buttons text in the map
|
||||
* Skip "\n"-s*/
|
||||
while(btn_i != btn_id) {
|
||||
btn_i ++;
|
||||
txt_i ++;
|
||||
if(strcmp(ext->map_p[txt_i], "\n") == 0) txt_i ++;
|
||||
}
|
||||
|
||||
if(btn_i == ext->btn_cnt) return LV_BTNM_PR_NONE;
|
||||
|
||||
return txt_i;
|
||||
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
#if USE_LV_CB != 0
|
||||
|
||||
#include "lv_cb.h"
|
||||
#include "../lv_obj/lv_group.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
@@ -23,11 +24,14 @@
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
static bool lv_cb_design(lv_obj_t * cb, const area_t * mask, lv_design_mode_t mode);
|
||||
static bool lv_bullet_design(lv_obj_t * bullet, const area_t * mask, lv_design_mode_t mode);
|
||||
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
**********************/
|
||||
static lv_design_f_t ancestor_design_f;
|
||||
static lv_design_f_t ancestor_bg_design_f;
|
||||
static lv_design_f_t ancestor_bullet_design_f;
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
@@ -57,7 +61,7 @@ lv_obj_t * lv_cb_create(lv_obj_t * par, lv_obj_t * copy)
|
||||
ext->bullet = NULL;
|
||||
ext->label = NULL;
|
||||
|
||||
if(ancestor_design_f == NULL) ancestor_design_f = lv_obj_get_design_f(new_cb);
|
||||
if(ancestor_bg_design_f == NULL) ancestor_bg_design_f = lv_obj_get_design_f(new_cb);
|
||||
|
||||
lv_obj_set_signal_f(new_cb, lv_cb_signal);
|
||||
lv_obj_set_design_f(new_cb, lv_cb_design);
|
||||
@@ -65,6 +69,7 @@ lv_obj_t * lv_cb_create(lv_obj_t * par, lv_obj_t * copy)
|
||||
/*Init the new checkbox object*/
|
||||
if(copy == NULL) {
|
||||
ext->bullet = lv_btn_create(new_cb, NULL);
|
||||
if(ancestor_bullet_design_f == NULL) ancestor_bullet_design_f = lv_obj_get_design_f(ext->bullet);
|
||||
lv_btn_set_styles(new_cb, lv_style_get(LV_STYLE_TRANSP, NULL), lv_style_get(LV_STYLE_TRANSP, NULL),
|
||||
lv_style_get(LV_STYLE_TRANSP, NULL), lv_style_get(LV_STYLE_TRANSP, NULL),
|
||||
lv_style_get(LV_STYLE_TRANSP, NULL));
|
||||
@@ -88,6 +93,8 @@ lv_obj_t * lv_cb_create(lv_obj_t * par, lv_obj_t * copy)
|
||||
/*Refresh the style with new signal function*/
|
||||
lv_obj_refr_style(new_cb);
|
||||
}
|
||||
|
||||
lv_obj_set_design_f(ext->bullet, lv_bullet_design);
|
||||
|
||||
return new_cb;
|
||||
}
|
||||
@@ -114,11 +121,17 @@ bool lv_cb_signal(lv_obj_t * cb, lv_signal_t sign, void * param)
|
||||
if(valid != false) {
|
||||
if(sign == LV_SIGNAL_STYLE_CHG) {
|
||||
lv_obj_set_size(ext->bullet, font_get_height(style->font), font_get_height(style->font));
|
||||
}
|
||||
if(sign == LV_SIGNAL_PRESSED ||
|
||||
} else if(sign == LV_SIGNAL_PRESSED ||
|
||||
sign == LV_SIGNAL_RELEASED ||
|
||||
sign == LV_SIGNAL_PRESS_LOST) {
|
||||
lv_btn_set_state(lv_cb_get_bullet(cb), lv_btn_get_state(cb));
|
||||
} else if(sign == LV_SIGNAL_CONTROLL) {
|
||||
char c = *((char*)param);
|
||||
if(c == LV_GROUP_KEY_RIGHT || c == LV_GROUP_KEY_DOWN ||
|
||||
c == LV_GROUP_KEY_LEFT || c == LV_GROUP_KEY_UP ||
|
||||
c == LV_GROUP_KEY_ENTER) {
|
||||
lv_btn_set_state(lv_cb_get_bullet(cb), lv_btn_get_state(cb));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -186,19 +199,62 @@ static bool lv_cb_design(lv_obj_t * cb, const area_t * mask, lv_design_mode_t mo
|
||||
{
|
||||
if(mode == LV_DESIGN_COVER_CHK) {
|
||||
/*Return false if the object is not covers the mask_p area*/
|
||||
return ancestor_design_f(cb, mask, mode);
|
||||
return ancestor_bg_design_f(cb, mask, mode);
|
||||
} else if(mode == LV_DESIGN_DRAW_MAIN || mode == LV_DESIGN_DRAW_POST) {
|
||||
lv_cb_ext_t * cb_ext = lv_obj_get_ext(cb);
|
||||
lv_btn_ext_t * bullet_ext = lv_obj_get_ext(cb_ext->bullet);
|
||||
|
||||
/*Be sure he state of the bullet is the same as the parent button*/
|
||||
/*Be sure the state of the bullet is the same as the parent button*/
|
||||
bullet_ext->state = cb_ext->bg_btn.state;
|
||||
|
||||
return ancestor_design_f(cb, mask, mode);
|
||||
return ancestor_bg_design_f(cb, mask, mode);
|
||||
|
||||
} else {
|
||||
return ancestor_bg_design_f(cb, mask, mode);
|
||||
}
|
||||
|
||||
/*Draw the object*/
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle the drawing related tasks of the check boxes
|
||||
* @param bullet pointer to an object
|
||||
* @param mask the object will be drawn only in this area
|
||||
* @param mode LV_DESIGN_COVER_CHK: only check if the object fully covers the 'mask_p' area
|
||||
* (return 'true' if yes)
|
||||
* LV_DESIGN_DRAW: draw the object (always return 'true')
|
||||
* LV_DESIGN_DRAW_POST: drawing after every children are drawn
|
||||
* @param return true/false, depends on 'mode'
|
||||
*/
|
||||
static bool lv_bullet_design(lv_obj_t * bullet, const area_t * mask, lv_design_mode_t mode)
|
||||
{
|
||||
if(mode == LV_DESIGN_COVER_CHK) {
|
||||
return ancestor_bullet_design_f(bullet, mask, mode);
|
||||
} else if(mode == LV_DESIGN_DRAW_MAIN) {
|
||||
#if LV_OBJ_GROUP != 0
|
||||
/* If the check box is the active in a group and
|
||||
* the background is not visible (transparent or empty)
|
||||
* then activate the style of the bullet*/
|
||||
lv_style_t * style_ori = lv_obj_get_style(bullet);
|
||||
lv_obj_t * bg = lv_obj_get_parent(bullet);
|
||||
lv_style_t * style_page = lv_obj_get_style(bg);
|
||||
lv_group_t * g = lv_obj_get_group(bg);
|
||||
if(style_page->empty != 0 || style_page->opa == OPA_TRANSP) { /*Background is visible?*/
|
||||
if(lv_group_get_focused(g) == bg) {
|
||||
lv_style_t * style_mod;
|
||||
style_mod = lv_group_mod_style(g, style_ori);
|
||||
bullet->style_p = style_mod; /*Temporally change the style to the activated */
|
||||
}
|
||||
}
|
||||
#endif
|
||||
ancestor_bullet_design_f(bullet, mask, mode);
|
||||
|
||||
#if LV_OBJ_GROUP != 0
|
||||
bullet->style_p = style_ori; /*Revert the style*/
|
||||
#endif
|
||||
} else if(mode == LV_DESIGN_DRAW_POST) {
|
||||
ancestor_bullet_design_f(bullet, mask, mode);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* @file lv_rect.c
|
||||
* @file lv_cont.c
|
||||
*
|
||||
*/
|
||||
|
||||
@@ -465,10 +465,19 @@ static void lv_cont_layout_pretty(lv_obj_t * cont)
|
||||
h_row = lv_obj_get_height(child_rc); /*Not set previously because of the early break*/
|
||||
}
|
||||
}
|
||||
/*If here is only one object in the row then align it to the middle*/
|
||||
/*If there is only one object in the row then align it to the middle*/
|
||||
else if (obj_num == 1) {
|
||||
lv_obj_align(child_rs, cont, LV_ALIGN_IN_TOP_MID, 0, act_y);
|
||||
}
|
||||
/*If are two object in the row then align them proportionally*/
|
||||
else if (obj_num == 2) {
|
||||
lv_obj_t * obj1 = child_rs;
|
||||
lv_obj_t * obj2 = ll_get_prev(&cont->child_ll, child_rs);
|
||||
w_row = lv_obj_get_width(obj1) + lv_obj_get_width(obj2);
|
||||
cord_t pad = (w_obj - w_row) / 3;
|
||||
lv_obj_align(obj1, cont, LV_ALIGN_IN_TOP_LEFT, pad, act_y);
|
||||
lv_obj_align(obj2, cont, LV_ALIGN_IN_TOP_RIGHT, -pad, act_y);
|
||||
}
|
||||
/* Align the children (from child_rs to child_rc)*/
|
||||
else {
|
||||
w_row -= style->opad * obj_num;
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
#include "lv_ddlist.h"
|
||||
#include "../lv_draw/lv_draw.h"
|
||||
#include "misc/gfx/anim.h"
|
||||
#include "../lv_obj/lv_group.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
@@ -70,6 +71,7 @@ lv_obj_t * lv_ddlist_create(lv_obj_t * par, lv_obj_t * copy)
|
||||
ext->opened = 0;
|
||||
ext->auto_size = 0;
|
||||
ext->sel_opt = 0;
|
||||
ext->num_opt = 0;
|
||||
ext->anim_time = LV_DDLIST_DEF_ANIM_TIME;
|
||||
ext->style_sel = lv_style_get(LV_STYLE_PLAIN_COLOR, NULL);
|
||||
|
||||
@@ -83,7 +85,8 @@ lv_obj_t * lv_ddlist_create(lv_obj_t * par, lv_obj_t * copy)
|
||||
if(copy == NULL) {
|
||||
lv_obj_t * scrl = lv_page_get_scrl(new_ddlist);
|
||||
lv_obj_set_drag(scrl, false);
|
||||
lv_obj_set_style(scrl, lv_style_get(LV_STYLE_TRANSP, NULL));
|
||||
lv_obj_set_style(scrl, lv_style_get(LV_STYLE_TRANSP, NULL));;
|
||||
lv_cont_set_fit(scrl, true, true);
|
||||
|
||||
ext->opt_label = lv_label_create(new_ddlist, NULL);
|
||||
lv_cont_set_fit(new_ddlist, true, false);
|
||||
@@ -100,6 +103,7 @@ lv_obj_t * lv_ddlist_create(lv_obj_t * par, lv_obj_t * copy)
|
||||
ext->sel_opt = copy_ext->sel_opt;
|
||||
ext->auto_size = copy_ext->auto_size;
|
||||
ext->cb = copy_ext->cb;
|
||||
ext->num_opt = copy_ext->num_opt;
|
||||
|
||||
/*Refresh the style with new signal function*/
|
||||
lv_obj_refr_style(new_ddlist);
|
||||
@@ -129,7 +133,44 @@ bool lv_ddlist_signal(lv_obj_t * ddlist, lv_signal_t sign, void * param)
|
||||
lv_ddlist_ext_t * ext = lv_obj_get_ext(ddlist);
|
||||
lv_obj_set_style(ext->opt_label, lv_obj_get_style(ddlist));
|
||||
lv_ddlist_refr_size(ddlist, 0);
|
||||
}
|
||||
} else if(sign == LV_SIGNAL_FOCUS) {
|
||||
lv_ddlist_ext_t * ext = lv_obj_get_ext(ddlist);
|
||||
if(ext->opened == false) {
|
||||
ext->opened = true;
|
||||
lv_ddlist_refr_size(ddlist, true);
|
||||
}
|
||||
} else if(sign == LV_SIGNAL_DEFOCUS) {
|
||||
lv_ddlist_ext_t * ext = lv_obj_get_ext(ddlist);
|
||||
if(ext->opened != false) {
|
||||
ext->opened = false;
|
||||
lv_ddlist_refr_size(ddlist, true);
|
||||
}
|
||||
} else if(sign == LV_SIGNAL_CONTROLL) {
|
||||
lv_ddlist_ext_t * ext = lv_obj_get_ext(ddlist);
|
||||
char c = *((char*)param);
|
||||
if(c == LV_GROUP_KEY_RIGHT || c == LV_GROUP_KEY_DOWN) {
|
||||
if(ext->sel_opt +1 < ext->num_opt) {
|
||||
ext->sel_opt ++;
|
||||
lv_obj_inv(ddlist);
|
||||
if(ext->cb != NULL) {
|
||||
ext->cb(ddlist, NULL);
|
||||
}
|
||||
}
|
||||
} else if(c == LV_GROUP_KEY_LEFT || c == LV_GROUP_KEY_UP) {
|
||||
if(ext->sel_opt > 0) {
|
||||
ext->sel_opt --;
|
||||
lv_obj_inv(ddlist);
|
||||
if(ext->cb != NULL) {
|
||||
ext->cb(ddlist, NULL);
|
||||
}
|
||||
}
|
||||
} else if(c == LV_GROUP_KEY_ENTER || c == LV_GROUP_KEY_ESC) {
|
||||
if(ext->opened != false) ext->opened = false;
|
||||
if(ext->opened == false) ext->opened = true;
|
||||
|
||||
lv_ddlist_refr_size(ddlist, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return valid;
|
||||
@@ -158,6 +199,8 @@ void lv_ddlist_set_options(lv_obj_t * ddlist, const char ** options)
|
||||
i++;
|
||||
}
|
||||
|
||||
ext->num_opt = i;
|
||||
|
||||
lv_ddlist_refr_size(ddlist, 0);
|
||||
}
|
||||
|
||||
@@ -169,6 +212,15 @@ void lv_ddlist_set_options(lv_obj_t * ddlist, const char ** options)
|
||||
void lv_ddlist_set_options_str(lv_obj_t * ddlist, const char * options)
|
||||
{
|
||||
lv_ddlist_ext_t * ext = lv_obj_get_ext(ddlist);
|
||||
|
||||
/*Count the '\n'-s to determine the number of options*/
|
||||
ext->num_opt = 0;
|
||||
uint16_t i;
|
||||
for(i = 0; options[i] != '\0'; i++) {
|
||||
if(options[i] == '\n') ext->num_opt++;
|
||||
}
|
||||
ext->num_opt++; /*Last option in the at row*/
|
||||
|
||||
lv_label_set_text(ext->opt_label, options);
|
||||
lv_ddlist_refr_size(ddlist, 0);
|
||||
}
|
||||
@@ -352,13 +404,12 @@ static bool lv_ddlist_design(lv_obj_t * ddlist, const area_t * mask, lv_design_m
|
||||
const font_t * font = style->font;
|
||||
cord_t font_h = font_get_height(font) >> FONT_ANTIALIAS;
|
||||
area_t rect_area;
|
||||
lv_style_t * style_page_scrl = lv_obj_get_style(lv_page_get_scrl(ddlist));
|
||||
rect_area.y1 = ext->opt_label->cords.y1;
|
||||
rect_area.y1 += ext->sel_opt * (font_h + style->line_space);
|
||||
rect_area.y1 -= style->line_space / 2;
|
||||
|
||||
rect_area.y2 = rect_area.y1 + font_h + style->line_space;
|
||||
rect_area.x1 = ext->opt_label->cords.x1 - style_page_scrl->hpad;
|
||||
rect_area.x1 = ext->opt_label->cords.x1 - style->hpad;
|
||||
rect_area.x2 = rect_area.x1 + lv_obj_get_width(lv_page_get_scrl(ddlist));
|
||||
|
||||
lv_draw_rect(&rect_area, mask, ext->style_sel);
|
||||
@@ -417,7 +468,7 @@ static lv_action_res_t lv_ddlist_rel_action(lv_obj_t * ddlist, lv_dispi_t * disp
|
||||
}
|
||||
|
||||
/**
|
||||
* Refresh the size of drop down list according its start (open or closed)
|
||||
* Refresh the size of drop down list according its status (open or closed)
|
||||
* @param ddlist pointer to a drop down list object
|
||||
* @param anim_time animations time for open/close [ms]
|
||||
*/
|
||||
|
||||
@@ -43,7 +43,8 @@ typedef struct
|
||||
/*New data for this type */
|
||||
lv_obj_t * opt_label; /*Label for the options*/
|
||||
lv_style_t * style_sel; /*Style of the selected option*/
|
||||
lv_action_t cb; /*Pointer to function to call when an option is slected*/
|
||||
lv_action_t cb; /*Pointer to function to call when an option is selected*/
|
||||
uint16_t num_opt; /*Number of options*/
|
||||
uint16_t sel_opt; /*Index of the current option*/
|
||||
uint16_t anim_time; /*Open/Close animation time [ms]*/
|
||||
uint8_t opened :1; /*1: The list is opened*/
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
#include "misc/math/math_base.h"
|
||||
#include "lv_label.h"
|
||||
#include "../lv_obj/lv_obj.h"
|
||||
#include "../lv_obj/lv_group.h"
|
||||
#include "misc/gfx/text.h"
|
||||
#include "misc/gfx/anim.h"
|
||||
#include "../lv_draw/lv_draw.h"
|
||||
@@ -83,6 +84,7 @@ lv_obj_t * lv_label_create(lv_obj_t * par, lv_obj_t * copy)
|
||||
ext->txt = NULL;
|
||||
ext->static_txt = 0;
|
||||
ext->recolor = 0;
|
||||
ext->no_break = 0;
|
||||
ext->dot_end = LV_LABEL_DOT_END_INV;
|
||||
ext->long_mode = LV_LABEL_LONG_EXPAND;
|
||||
ext->offset.x = 0;
|
||||
@@ -307,6 +309,19 @@ void lv_label_set_recolor(lv_obj_t * label, bool recolor)
|
||||
lv_label_refr_text(label);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the label the ignore (or accept) line breaks on '\n'
|
||||
* @param label pointer to a label object
|
||||
* @param en true: ignore line breaks, false: make line breaks on '\n'
|
||||
*/
|
||||
void lv_label_set_no_break(lv_obj_t * label, bool en)
|
||||
{
|
||||
lv_label_ext_t * ext = lv_obj_get_ext(label);
|
||||
ext->no_break = en == false ? 0 : 1;
|
||||
|
||||
lv_label_refr_text(label);
|
||||
|
||||
}
|
||||
/*=====================
|
||||
* Getter functions
|
||||
*====================*/
|
||||
@@ -366,6 +381,7 @@ void lv_label_get_letter_pos(lv_obj_t * label, uint16_t index, point_t * pos)
|
||||
|
||||
if(ext->recolor != 0) flag |= TXT_FLAG_RECOLOR;
|
||||
if(ext->expand != 0) flag |= TXT_FLAG_EXPAND;
|
||||
if(ext->no_break != 0) flag |= TXT_FLAG_NO_BREAK;
|
||||
|
||||
/*If the width will be expanded the set the max length to very big */
|
||||
if(ext->long_mode == LV_LABEL_LONG_EXPAND || ext->long_mode == LV_LABEL_LONG_SCROLL) {
|
||||
@@ -401,6 +417,8 @@ void lv_label_get_letter_pos(lv_obj_t * label, uint16_t index, point_t * pos)
|
||||
|
||||
}
|
||||
|
||||
if(x > style->letter_space) x-= style->letter_space;
|
||||
|
||||
if(style->txt_align == LV_TXT_ALIGN_MID) {
|
||||
cord_t line_w;
|
||||
line_w = txt_get_width(&txt[line_start], new_line_start - line_start,
|
||||
@@ -434,6 +452,7 @@ uint16_t lv_label_get_letter_on(lv_obj_t * label, point_t * pos)
|
||||
|
||||
if(ext->recolor != 0) flag |= TXT_FLAG_RECOLOR;
|
||||
if(ext->expand != 0) flag |= TXT_FLAG_EXPAND;
|
||||
if(ext->no_break != 0) flag |= TXT_FLAG_NO_BREAK;
|
||||
|
||||
/*If the width will be expanded set the max length to very big */
|
||||
if(ext->long_mode == LV_LABEL_LONG_EXPAND || ext->long_mode == LV_LABEL_LONG_SCROLL) {
|
||||
@@ -468,11 +487,9 @@ uint16_t lv_label_get_letter_on(lv_obj_t * label, point_t * pos)
|
||||
}
|
||||
|
||||
x += (font_get_width(font, txt[i]) >> FONT_ANTIALIAS) + style->letter_space;
|
||||
|
||||
if(pos->x < x) break;
|
||||
}
|
||||
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
@@ -496,25 +513,27 @@ static bool lv_label_design(lv_obj_t * label, const area_t * mask, lv_design_mod
|
||||
/* A label never covers an area */
|
||||
if(mode == LV_DESIGN_COVER_CHK) return false;
|
||||
else if(mode == LV_DESIGN_DRAW_MAIN) {
|
||||
/*TEST: draw a background for the label*/
|
||||
area_t cords;
|
||||
lv_style_t * style = lv_obj_get_style(label);
|
||||
lv_obj_get_cords(label, &cords);
|
||||
|
||||
#if LV_OBJ_GROUP != 0
|
||||
lv_group_t * g = lv_obj_get_group(label);
|
||||
if(lv_group_get_focused(g) == label) {
|
||||
lv_draw_rect(&cords, mask, style);
|
||||
}
|
||||
#endif
|
||||
|
||||
/*TEST: draw a background for the label*/
|
||||
//lv_vfill(&label->cords, mask, COLOR_LIME, OPA_COVER);
|
||||
|
||||
area_t cords;
|
||||
lv_obj_get_cords(label, &cords);
|
||||
lv_label_ext_t * ext = lv_obj_get_ext(label);
|
||||
txt_flag_t flag = TXT_FLAG_NONE;
|
||||
if(ext->recolor != 0) flag |= TXT_FLAG_RECOLOR;
|
||||
if(ext->expand != 0) flag |= TXT_FLAG_EXPAND;
|
||||
if(ext->no_break != 0) flag |= TXT_FLAG_NO_BREAK;
|
||||
|
||||
if(strcmp("Folder1", ext->txt) == 0) {
|
||||
uint8_t i;
|
||||
i = 0;
|
||||
i++;
|
||||
}
|
||||
|
||||
lv_draw_label(&cords, mask, lv_obj_get_style(label), ext->txt, flag, &ext->offset);
|
||||
|
||||
|
||||
lv_draw_label(&cords, mask, style, ext->txt, flag, &ext->offset);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@@ -546,6 +565,7 @@ static void lv_label_refr_text(lv_obj_t * label)
|
||||
txt_flag_t flag = TXT_FLAG_NONE;
|
||||
if(ext->recolor != 0) flag |= TXT_FLAG_RECOLOR;
|
||||
if(ext->expand != 0) flag |= TXT_FLAG_EXPAND;
|
||||
if(ext->no_break != 0) flag |= TXT_FLAG_NO_BREAK;
|
||||
txt_get_size(&size, ext->txt, font, style->letter_space, style->line_space, max_w, flag);
|
||||
|
||||
/*Refresh the full size in expand mode*/
|
||||
|
||||
@@ -48,10 +48,11 @@ typedef struct
|
||||
lv_label_long_mode_t long_mode; /*Determinate what to do with the long texts*/
|
||||
char dot_tmp[LV_LABEL_DOT_NUM + 1]; /*Store the character which are replaced by dots (Handled by the library)*/
|
||||
uint16_t dot_end; /*The text end position in dot mode (Handled by the library)*/
|
||||
point_t offset;
|
||||
point_t offset; /*Text draw position offset*/
|
||||
uint8_t static_txt :1; /*Flag to indicate the text is static*/
|
||||
uint8_t recolor :1; /*Enable in-line letter re-coloring*/
|
||||
uint8_t expand :1; /*Force expand size when solving line length (used by the library with LV_LABEL_LONG_ROLL)*/
|
||||
uint8_t expand :1; /*Ignore real width (used by the library with LV_LABEL_LONG_ROLL)*/
|
||||
uint8_t no_break :1; /*Ignore new line characters*/
|
||||
}lv_label_ext_t;
|
||||
|
||||
/**********************
|
||||
@@ -119,12 +120,13 @@ void lv_label_set_long_mode(lv_obj_t * label, lv_label_long_mode_t long_mode);
|
||||
*/
|
||||
void lv_label_set_recolor(lv_obj_t * label, bool recolor);
|
||||
|
||||
|
||||
/**
|
||||
* Enable the password mode
|
||||
* Set the label the ignore (or accept) line breaks on '\n'
|
||||
* @param label pointer to a label object
|
||||
* @param pwd true: enable password mode, false: disable
|
||||
* @param en true: ignore line breaks, false: make line breaks on '\n'
|
||||
*/
|
||||
void lv_label_set_pwd_mode(lv_obj_t * label, bool pwd);
|
||||
void lv_label_set_no_break(lv_obj_t * label, bool en);
|
||||
|
||||
/**
|
||||
* Get the text of a label
|
||||
|
||||
@@ -10,13 +10,18 @@
|
||||
#if USE_LV_LIST != 0
|
||||
|
||||
#include "lv_list.h"
|
||||
#include <lvgl/lv_objx/lv_cont.h>
|
||||
#include "lvgl/lv_obj/lv_group.h"
|
||||
#include "lvgl/lv_objx/lv_cont.h"
|
||||
#include "misc/gfx/anim.h"
|
||||
#include "misc/math/math_base.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
#define LV_LIST_LAYOUT_DEF LV_CONT_LAYOUT_COL_M
|
||||
#ifndef LV_LIST_FOCUS_TIME
|
||||
#define LV_LIST_FOCUS_TIME 100 /*Animation time of focusing to the a list element [ms] (0: no animation) */
|
||||
#endif
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
@@ -29,6 +34,8 @@
|
||||
static bool lv_list_design(lv_obj_t * list, const area_t * mask, lv_design_mode_t mode);
|
||||
#endif
|
||||
|
||||
static lv_obj_t * lv_list_get_next_btn(lv_obj_t * list, lv_obj_t * prev_btn);
|
||||
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
**********************/
|
||||
@@ -108,6 +115,85 @@ bool lv_list_signal(lv_obj_t * list, lv_signal_t sign, void * param)
|
||||
/* Include the ancient signal function */
|
||||
valid = lv_page_signal(list, sign, param);
|
||||
|
||||
/* The object can be deleted so check its validity and then
|
||||
* make the object specific signal handling */
|
||||
if(valid != false) {
|
||||
if(sign == LV_SIGNAL_FOCUS) {
|
||||
/*Get the first button*/
|
||||
lv_obj_t * btn = NULL;
|
||||
lv_obj_t * btn_prev = NULL;
|
||||
btn = lv_list_get_next_btn(list, btn);
|
||||
while(btn != NULL) {
|
||||
btn_prev = btn;
|
||||
btn = lv_list_get_next_btn(list, btn);
|
||||
}
|
||||
if(btn_prev != NULL) {
|
||||
lv_btn_set_state(btn_prev, LV_BTN_STATE_PR);
|
||||
}
|
||||
} else if(sign == LV_SIGNAL_DEFOCUS) {
|
||||
/*Get the 'pressed' button*/
|
||||
lv_obj_t * btn = NULL;
|
||||
btn = lv_list_get_next_btn(list, btn);
|
||||
while(btn != NULL) {
|
||||
if(lv_btn_get_state(btn) == LV_BTN_STATE_PR) break;
|
||||
btn = lv_list_get_next_btn(list, btn);
|
||||
}
|
||||
|
||||
if(btn != NULL) {
|
||||
lv_btn_set_state(btn, LV_BTN_STATE_REL);
|
||||
}
|
||||
} else if(sign == LV_SIGNAL_CONTROLL) {
|
||||
char c = *((char*)param);
|
||||
if(c == LV_GROUP_KEY_RIGHT || c == LV_GROUP_KEY_DOWN) {
|
||||
/*Get the last pressed button*/
|
||||
lv_obj_t * btn = NULL;
|
||||
lv_obj_t * btn_prev = NULL;
|
||||
btn = lv_list_get_next_btn(list, btn);
|
||||
while(btn != NULL) {
|
||||
if(lv_btn_get_state(btn) == LV_BTN_STATE_PR) break;
|
||||
btn_prev = btn;
|
||||
btn = lv_list_get_next_btn(list, btn);
|
||||
}
|
||||
|
||||
if(btn_prev != NULL && btn != NULL) {
|
||||
lv_btn_set_state(btn, LV_BTN_STATE_REL);
|
||||
lv_btn_set_state(btn_prev, LV_BTN_STATE_PR);
|
||||
lv_page_focus(list, btn_prev, LV_LIST_FOCUS_TIME);
|
||||
}
|
||||
} else if(c == LV_GROUP_KEY_LEFT || c == LV_GROUP_KEY_UP) {
|
||||
/*Get the last pressed button*/
|
||||
lv_obj_t * btn = NULL;
|
||||
btn = lv_list_get_next_btn(list, btn);
|
||||
while(btn != NULL) {
|
||||
if(lv_btn_get_state(btn) == LV_BTN_STATE_PR) break;
|
||||
btn = lv_list_get_next_btn(list, btn);
|
||||
}
|
||||
|
||||
if(btn != NULL) {
|
||||
lv_obj_t * btn_prev = lv_list_get_next_btn(list, btn);
|
||||
if(btn_prev != NULL) {
|
||||
lv_btn_set_state(btn, LV_BTN_STATE_REL);
|
||||
lv_btn_set_state(btn_prev, LV_BTN_STATE_PR);
|
||||
lv_page_focus(list, btn_prev, LV_LIST_FOCUS_TIME);
|
||||
}
|
||||
}
|
||||
} else if(c == LV_GROUP_KEY_ENTER) {
|
||||
/*Get the 'pressed' button*/
|
||||
lv_obj_t * btn = NULL;
|
||||
btn = lv_list_get_next_btn(list, btn);
|
||||
while(btn != NULL) {
|
||||
if(lv_btn_get_state(btn) == LV_BTN_STATE_PR) break;
|
||||
btn = lv_list_get_next_btn(list, btn);
|
||||
}
|
||||
|
||||
if(btn != NULL) {
|
||||
lv_action_t rel_action;
|
||||
rel_action = lv_btn_get_rel_action(btn);
|
||||
if(rel_action != NULL) rel_action(btn, NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return valid;
|
||||
}
|
||||
|
||||
@@ -175,19 +261,37 @@ void lv_list_up(lv_obj_t * list)
|
||||
{
|
||||
/*Search the first list element which 'y' coordinate is below the parent
|
||||
* and position the list to show this element on the bottom*/
|
||||
lv_obj_t * h = lv_obj_get_parent(list);
|
||||
lv_obj_t * scrl = lv_page_get_scrl(list);
|
||||
lv_obj_t * e;
|
||||
lv_obj_t * e_prev = NULL;
|
||||
e = lv_obj_get_child(list, NULL);
|
||||
e = lv_list_get_next_btn(list, NULL);
|
||||
while(e != NULL) {
|
||||
if(e->cords.y2 <= h->cords.y2) {
|
||||
if(e_prev != NULL)
|
||||
lv_obj_set_y(list, lv_obj_get_height(h) -
|
||||
(lv_obj_get_y(e_prev) + lv_obj_get_height(e_prev)));
|
||||
if(e->cords.y2 <= list->cords.y2) {
|
||||
if(e_prev != NULL) {
|
||||
cord_t new_y = lv_obj_get_height(list) - (lv_obj_get_y(e_prev) + lv_obj_get_height(e_prev));
|
||||
#if LV_LIST_FOCUS_TIME == 0
|
||||
lv_obj_set_y(scrl, new_y);
|
||||
#else
|
||||
anim_t a;
|
||||
a.var = scrl;
|
||||
a.start = lv_obj_get_y(scrl);
|
||||
a.end = new_y;
|
||||
a.fp = (anim_fp_t)lv_obj_set_y;
|
||||
a.path = anim_get_path(ANIM_PATH_LIN);
|
||||
a.end_cb = NULL;
|
||||
a.act_time = 0;
|
||||
a.time = LV_LIST_FOCUS_TIME;
|
||||
a.playback = 0;
|
||||
a.playback_pause = 0;
|
||||
a.repeat = 0;
|
||||
a.repeat_pause = 0;
|
||||
anim_create(&a);
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
}
|
||||
e_prev = e;
|
||||
e = lv_obj_get_child(list, e);
|
||||
e = lv_list_get_next_btn(list, e);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -199,19 +303,36 @@ void lv_list_down(lv_obj_t * list)
|
||||
{
|
||||
/*Search the first list element which 'y' coordinate is above the parent
|
||||
* and position the list to show this element on the top*/
|
||||
lv_obj_t * h = lv_obj_get_parent(list);
|
||||
lv_obj_t * scrl = lv_page_get_scrl(list);
|
||||
lv_obj_t * e;
|
||||
e = lv_obj_get_child(list, NULL);
|
||||
e = lv_list_get_next_btn(list, NULL);
|
||||
while(e != NULL) {
|
||||
if(e->cords.y1 < h->cords.y1) {
|
||||
lv_obj_set_y(list, -lv_obj_get_y(e));
|
||||
if(e->cords.y1 < list->cords.y1) {
|
||||
cord_t new_y = -lv_obj_get_y(e);
|
||||
#if LV_LIST_FOCUS_TIME == 0
|
||||
lv_obj_set_y(scrl, new_y);
|
||||
#else
|
||||
anim_t a;
|
||||
a.var = scrl;
|
||||
a.start = lv_obj_get_y(scrl);
|
||||
a.end = new_y;
|
||||
a.fp = (anim_fp_t)lv_obj_set_y;
|
||||
a.path = anim_get_path(ANIM_PATH_LIN);
|
||||
a.end_cb = NULL;
|
||||
a.act_time = 0;
|
||||
a.time = LV_LIST_FOCUS_TIME;
|
||||
a.playback = 0;
|
||||
a.playback_pause = 0;
|
||||
a.repeat = 0;
|
||||
a.repeat_pause = 0;
|
||||
anim_create(&a);
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
e = lv_obj_get_child(list, e);
|
||||
e = lv_list_get_next_btn(list, e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*=====================
|
||||
* Setter functions
|
||||
*====================*/
|
||||
@@ -236,8 +357,9 @@ void lv_list_set_sb_out(lv_obj_t * list, bool out)
|
||||
*/
|
||||
void lv_list_set_element_text_roll(lv_obj_t * liste, bool en)
|
||||
{
|
||||
/*The last child is the label*/
|
||||
lv_obj_t * label = lv_obj_get_child(liste, NULL);
|
||||
lv_obj_t * label = lv_list_get_element_label(liste);
|
||||
if(label == NULL) return;
|
||||
|
||||
if(en == false) {
|
||||
lv_label_set_long_mode(label, LV_LABEL_LONG_DOTS);
|
||||
} else {
|
||||
@@ -269,12 +391,11 @@ void lv_list_set_styles_btn(lv_obj_t * list, lv_style_t * rel, lv_style_t * pr,
|
||||
ext->styles_btn[LV_BTN_STATE_TPR] = tpr;
|
||||
ext->styles_btn[LV_BTN_STATE_INA] = ina;
|
||||
|
||||
lv_obj_t * scrl = lv_page_get_scrl(list);
|
||||
lv_obj_t * liste = lv_obj_get_child(scrl, NULL);
|
||||
lv_obj_t * liste = lv_list_get_next_btn(list, NULL);
|
||||
while(liste != NULL)
|
||||
{
|
||||
lv_btn_set_styles(liste, rel, pr, trel, tpr, ina);
|
||||
liste = lv_obj_get_child(scrl, liste);
|
||||
liste = lv_list_get_next_btn(list, liste);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -290,16 +411,14 @@ void lv_list_set_style_img(lv_obj_t * list, lv_style_t * style)
|
||||
|
||||
ext->style_img = style;
|
||||
|
||||
lv_obj_t * scrl = lv_page_get_scrl(list);
|
||||
lv_obj_t * liste = lv_obj_get_child(scrl, NULL);
|
||||
lv_obj_t * liste = lv_list_get_next_btn(list, NULL);
|
||||
lv_obj_t * img;
|
||||
while(liste != NULL)
|
||||
{
|
||||
img = lv_obj_get_child(liste, NULL); /*Now img = the label*/
|
||||
img = lv_obj_get_child(liste, img); /*Now img = the image (if ULL then no image) */
|
||||
img = lv_list_get_element_img(liste);
|
||||
if(img != NULL) lv_obj_set_style(img, style);
|
||||
|
||||
liste = lv_obj_get_child(scrl, liste);
|
||||
liste = lv_list_get_next_btn(list, liste);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -314,11 +433,47 @@ void lv_list_set_style_img(lv_obj_t * list, lv_style_t * style)
|
||||
*/
|
||||
const char * lv_list_get_element_text(lv_obj_t * liste)
|
||||
{
|
||||
/*The last child is the label*/
|
||||
lv_obj_t * label = lv_obj_get_child(liste, NULL);
|
||||
lv_obj_t * label = lv_list_get_element_label(liste);
|
||||
if(label == NULL) return "";
|
||||
return lv_label_get_text(label);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the label object from a list element
|
||||
* @param liste pointer to a list element (button)
|
||||
* @return pointer to the label from the list element or NULL if not found
|
||||
*/
|
||||
lv_obj_t * lv_list_get_element_label(lv_obj_t * liste)
|
||||
{
|
||||
lv_obj_t * label = lv_obj_get_child(liste, NULL);
|
||||
if(label == NULL) return NULL;
|
||||
|
||||
while(label->signal_f != lv_label_signal) {
|
||||
label = lv_obj_get_child(liste, NULL);
|
||||
if(label == NULL) break;
|
||||
}
|
||||
|
||||
return label;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the image object from a list element
|
||||
* @param liste pointer to a list element (button)
|
||||
* @return pointer to the image from the list element or NULL if not found
|
||||
*/
|
||||
lv_obj_t * lv_list_get_element_img(lv_obj_t * liste)
|
||||
{
|
||||
lv_obj_t * img = lv_obj_get_child(liste, NULL);
|
||||
if(img == NULL) return NULL;
|
||||
|
||||
while(img->signal_f != lv_img_signal) {
|
||||
img = lv_obj_get_child(liste, NULL);
|
||||
if(img == NULL) break;
|
||||
}
|
||||
|
||||
return img;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the scroll bar outside attribute
|
||||
* @param list pointer to list object
|
||||
@@ -388,4 +543,29 @@ static bool lv_list_design(lv_obj_t * list, const area_t * mask, lv_design_mode_
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Get the next button from list
|
||||
* @param list pointer to a list object
|
||||
* @param prev_btn pointer to button. Search the next after it.
|
||||
* @return pointer to the next button or NULL
|
||||
*/
|
||||
static lv_obj_t * lv_list_get_next_btn(lv_obj_t * list, lv_obj_t * prev_btn)
|
||||
{
|
||||
/* Not a good practice but user can add/create objects to the lists manually.
|
||||
* When getting the next button try to be sure that it is at least a button */
|
||||
|
||||
lv_obj_t * btn ;
|
||||
lv_obj_t * scrl = lv_page_get_scrl(list);
|
||||
|
||||
btn = lv_obj_get_child(scrl, prev_btn);
|
||||
if(btn == NULL) return NULL;
|
||||
|
||||
while(btn->signal_f != lv_btn_signal) {
|
||||
btn = lv_obj_get_child(scrl, prev_btn);
|
||||
if(btn == NULL) break;
|
||||
}
|
||||
|
||||
return btn;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -141,6 +141,20 @@ void lv_list_set_style_img(lv_obj_t * list, lv_style_t * style);
|
||||
*/
|
||||
const char * lv_list_get_element_text(lv_obj_t * liste);
|
||||
|
||||
/**
|
||||
* Get the label object from a list element
|
||||
* @param liste pointer to a list element (button)
|
||||
* @return pointer to the label from the list element or NULL if not found
|
||||
*/
|
||||
lv_obj_t * lv_list_get_element_label(lv_obj_t * liste);
|
||||
|
||||
/**
|
||||
* Get the image object from a list element
|
||||
* @param liste pointer to a list element (button)
|
||||
* @return pointer to the image from the list element or NULL if not found
|
||||
*/
|
||||
lv_obj_t * lv_list_get_element_img(lv_obj_t * liste);
|
||||
|
||||
/**
|
||||
* Get the scroll bar outside attribute
|
||||
* @param list pointer to list object
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
#if USE_LV_MBOX != 0
|
||||
|
||||
#include "lv_mbox.h"
|
||||
#include "lvgl/lv_obj/lv_group.h"
|
||||
#include "misc/gfx/anim.h"
|
||||
#include "misc/math/math_base.h"
|
||||
|
||||
@@ -132,13 +133,11 @@ bool lv_mbox_signal(lv_obj_t * mbox, lv_signal_t sign, void * param)
|
||||
area_get_height(param) != lv_obj_get_height(mbox)) {
|
||||
lv_mbox_realign(mbox);
|
||||
}
|
||||
}
|
||||
else if(sign == LV_SIGNAL_LONG_PRESS) {
|
||||
} else if(sign == LV_SIGNAL_LONG_PRESS) {
|
||||
lv_mbox_start_auto_close(mbox, 0);
|
||||
lv_dispi_wait_release(param);
|
||||
valid = false;
|
||||
}
|
||||
else if(sign == LV_SIGNAL_STYLE_CHG) {
|
||||
} else if(sign == LV_SIGNAL_STYLE_CHG) {
|
||||
/*Refresh all the buttons*/
|
||||
if(ext->btnh != NULL) {
|
||||
lv_obj_t * btn;
|
||||
@@ -150,6 +149,90 @@ bool lv_mbox_signal(lv_obj_t * mbox, lv_signal_t sign, void * param)
|
||||
btn = lv_obj_get_child(ext->btnh, btn);
|
||||
}
|
||||
}
|
||||
} else if(sign == LV_SIGNAL_FOCUS) {
|
||||
/*Get the first button*/
|
||||
if(ext->btnh != NULL) {
|
||||
lv_obj_t * btn = NULL;
|
||||
lv_obj_t * btn_prev = NULL;
|
||||
btn = lv_obj_get_child(ext->btnh, btn);
|
||||
while(btn != NULL) {
|
||||
btn_prev = btn;
|
||||
btn = lv_obj_get_child(ext->btnh, btn);
|
||||
}
|
||||
if(btn_prev != NULL) {
|
||||
lv_btn_set_state(btn_prev, LV_BTN_STATE_PR);
|
||||
}
|
||||
}
|
||||
} else if(sign == LV_SIGNAL_DEFOCUS) {
|
||||
/*Get the 'pressed' button*/
|
||||
if(ext->btnh != NULL) {
|
||||
lv_obj_t * btn = NULL;
|
||||
btn = lv_obj_get_child(ext->btnh, btn);
|
||||
while(btn != NULL) {
|
||||
if(lv_btn_get_state(btn) == LV_BTN_STATE_PR) break;
|
||||
btn = lv_obj_get_child(ext->btnh, btn);
|
||||
}
|
||||
|
||||
if(btn != NULL) {
|
||||
lv_btn_set_state(btn, LV_BTN_STATE_REL);
|
||||
}
|
||||
}
|
||||
} else if(sign == LV_SIGNAL_CONTROLL) {
|
||||
lv_mbox_ext_t * ext = lv_obj_get_ext(mbox);
|
||||
char c = *((char*)param);
|
||||
if(c == LV_GROUP_KEY_RIGHT || c == LV_GROUP_KEY_UP) {
|
||||
/*Get the last pressed button*/
|
||||
if(ext->btnh != NULL) {
|
||||
lv_obj_t * btn = NULL;
|
||||
lv_obj_t * btn_prev = NULL;
|
||||
btn = lv_obj_get_child(ext->btnh, btn);
|
||||
while(btn != NULL) {
|
||||
if(lv_btn_get_state(btn) == LV_BTN_STATE_PR) break;
|
||||
btn_prev = btn;
|
||||
btn = lv_obj_get_child(ext->btnh, btn);
|
||||
}
|
||||
|
||||
if(btn_prev != NULL && btn != NULL) {
|
||||
lv_btn_set_state(btn, LV_BTN_STATE_REL);
|
||||
lv_btn_set_state(btn_prev, LV_BTN_STATE_PR);
|
||||
}
|
||||
}
|
||||
} else if(c == LV_GROUP_KEY_LEFT || c == LV_GROUP_KEY_DOWN) {
|
||||
/*Get the last pressed button*/
|
||||
if(ext->btnh != NULL) {
|
||||
lv_obj_t * btn = NULL;
|
||||
btn = lv_obj_get_child(ext->btnh, btn);
|
||||
while(btn != NULL) {
|
||||
if(lv_btn_get_state(btn) == LV_BTN_STATE_PR) break;
|
||||
btn = lv_obj_get_child(ext->btnh, btn);
|
||||
}
|
||||
|
||||
if(btn != NULL) {
|
||||
lv_obj_t * btn_prev = lv_obj_get_child(ext->btnh, btn);
|
||||
if(btn_prev != NULL) {
|
||||
lv_btn_set_state(btn, LV_BTN_STATE_REL);
|
||||
lv_btn_set_state(btn_prev, LV_BTN_STATE_PR);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
} else if(c == LV_GROUP_KEY_ENTER) {
|
||||
/*Get the 'pressed' button*/
|
||||
if(ext->btnh != NULL) {
|
||||
lv_obj_t * btn = NULL;
|
||||
btn = lv_obj_get_child(ext->btnh, btn);
|
||||
while(btn != NULL) {
|
||||
if(lv_btn_get_state(btn) == LV_BTN_STATE_PR) break;
|
||||
btn = lv_obj_get_child(ext->btnh, btn);
|
||||
}
|
||||
|
||||
if(btn != NULL) {
|
||||
lv_action_t rel_action;
|
||||
rel_action = lv_btn_get_rel_action(btn);
|
||||
if(rel_action != NULL) rel_action(btn, NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
#if USE_LV_PAGE != 0
|
||||
|
||||
#include "misc/math/math_base.h"
|
||||
#include "../lv_obj/lv_group.h"
|
||||
#include "../lv_objx/lv_page.h"
|
||||
#include "../lv_objx/lv_cont.h"
|
||||
#include "../lv_draw/lv_draw.h"
|
||||
@@ -28,13 +29,15 @@
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
static void lv_page_sb_refresh(lv_obj_t * main);
|
||||
static bool lv_page_design(lv_obj_t * page, const area_t * mask, lv_design_mode_t mode);
|
||||
static bool lv_page_design(lv_obj_t * scrl, const area_t * mask, lv_design_mode_t mode);
|
||||
static bool lv_scrl_design(lv_obj_t * scrl, const area_t * mask, lv_design_mode_t mode);
|
||||
static bool lv_scrl_signal(lv_obj_t * scrl, lv_signal_t sign, void* param);
|
||||
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
**********************/
|
||||
static lv_design_f_t ancestor_design_f;
|
||||
static lv_design_f_t ancestor_page_design_f;
|
||||
static lv_design_f_t ancestor_scrl_design_f;
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
@@ -72,18 +75,20 @@ lv_obj_t * lv_page_create(lv_obj_t * par, lv_obj_t * copy)
|
||||
ext->sb_width = LV_DPI / 8; /*Will be modified later*/
|
||||
ext->sb_mode = LV_PAGE_SB_MODE_ON;
|
||||
|
||||
if(ancestor_design_f == NULL) ancestor_design_f = lv_obj_get_design_f(new_page);
|
||||
if(ancestor_page_design_f == NULL) ancestor_page_design_f = lv_obj_get_design_f(new_page);
|
||||
|
||||
/*Init the new page object*/
|
||||
if(copy == NULL) {
|
||||
lv_style_t * style = lv_style_get(LV_STYLE_PRETTY_COLOR, NULL);
|
||||
ext->scrl = lv_cont_create(new_page, NULL);
|
||||
if(ancestor_scrl_design_f == NULL) ancestor_scrl_design_f = lv_obj_get_design_f(ext->scrl);
|
||||
lv_obj_set_signal_f(ext->scrl, lv_scrl_signal);
|
||||
lv_obj_set_drag(ext->scrl, true);
|
||||
lv_obj_set_drag_throw(ext->scrl, true);
|
||||
lv_obj_set_protect(ext->scrl, LV_PROTECT_PARENT);
|
||||
lv_cont_set_fit(ext->scrl, true, true);
|
||||
lv_cont_set_fit(ext->scrl, false, true);
|
||||
lv_obj_set_style(ext->scrl, lv_style_get(LV_STYLE_PRETTY, NULL));
|
||||
lv_obj_set_design_f(ext->scrl, lv_scrl_design);
|
||||
|
||||
lv_page_set_sb_width(new_page, style->hpad);
|
||||
lv_page_set_sb_mode(new_page, ext->sb_mode);
|
||||
@@ -138,60 +143,60 @@ bool lv_page_signal(lv_obj_t * page, lv_signal_t sign, void * param)
|
||||
if(obj_valid != false) {
|
||||
lv_page_ext_t * ext = lv_obj_get_ext(page);
|
||||
lv_obj_t * child;
|
||||
switch(sign) {
|
||||
case LV_SIGNAL_CHILD_CHG: /*Move children to the scrollable object*/
|
||||
child = lv_obj_get_child(page, NULL);
|
||||
while(child != NULL) {
|
||||
if(lv_obj_is_protected(child, LV_PROTECT_PARENT) == false) {
|
||||
lv_obj_t * tmp = child;
|
||||
child = lv_obj_get_child(page, child); /*Get the next child before move this*/
|
||||
lv_obj_set_parent(tmp, ext->scrl);
|
||||
} else {
|
||||
child = lv_obj_get_child(page, child);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case LV_SIGNAL_STYLE_CHG:
|
||||
if(ext->sb_mode == LV_PAGE_SB_MODE_ON) {
|
||||
ext->sbh_draw = 1;
|
||||
ext->sbv_draw = 1;
|
||||
} else {
|
||||
ext->sbh_draw = 0;
|
||||
ext->sbv_draw = 0;
|
||||
}
|
||||
|
||||
lv_page_sb_refresh(page);
|
||||
break;
|
||||
|
||||
case LV_SIGNAL_CORD_CHG:
|
||||
/*Refresh the scrollbar and notify the scrl if the size is changed*/
|
||||
if(ext->scrl != NULL &&
|
||||
(lv_obj_get_width(page) != area_get_width(param) ||
|
||||
lv_obj_get_height(page) != area_get_height(param))) {
|
||||
ext->scrl->signal_f(ext->scrl, LV_SIGNAL_CORD_CHG, &ext->scrl->cords);
|
||||
|
||||
/*The scrolbars are important olny if they are visible now*/
|
||||
if(ext->sbh_draw != 0 || ext->sbv_draw != 0)
|
||||
lv_page_sb_refresh(page);
|
||||
|
||||
}
|
||||
break;
|
||||
case LV_SIGNAL_PRESSED:
|
||||
if(ext->pr_action != NULL) {
|
||||
ext->pr_action(page, param);
|
||||
if(sign == LV_SIGNAL_CHILD_CHG) { /*Move children to the scrollable object*/
|
||||
child = lv_obj_get_child(page, NULL);
|
||||
while(child != NULL) {
|
||||
if(lv_obj_is_protected(child, LV_PROTECT_PARENT) == false) {
|
||||
lv_obj_t * tmp = child;
|
||||
child = lv_obj_get_child(page, child); /*Get the next child before move this*/
|
||||
lv_obj_set_parent(tmp, ext->scrl);
|
||||
} else {
|
||||
child = lv_obj_get_child(page, child);
|
||||
}
|
||||
break;
|
||||
case LV_SIGNAL_RELEASED:
|
||||
if(lv_dispi_is_dragging(param) == false) {
|
||||
if(ext->rel_action != NULL) {
|
||||
ext->rel_action(page, param);
|
||||
}
|
||||
}
|
||||
} else if(sign == LV_SIGNAL_STYLE_CHG) {
|
||||
lv_style_t * style = lv_obj_get_style(page);
|
||||
if(lv_cont_get_hfit(ext->scrl) == false) {
|
||||
lv_obj_set_width(ext->scrl, lv_obj_get_width(page) - 2 * style->hpad);
|
||||
}
|
||||
|
||||
if(ext->sb_mode == LV_PAGE_SB_MODE_ON) {
|
||||
ext->sbh_draw = 1;
|
||||
ext->sbv_draw = 1;
|
||||
} else {
|
||||
ext->sbh_draw = 0;
|
||||
ext->sbv_draw = 0;
|
||||
}
|
||||
|
||||
lv_page_sb_refresh(page);
|
||||
} else if(sign == LV_SIGNAL_CORD_CHG) {
|
||||
lv_style_t * style = lv_obj_get_style(page);
|
||||
/*Refresh the scrollbar and notify the scrl if the size is changed*/
|
||||
if(ext->scrl != NULL &&
|
||||
(lv_obj_get_width(page) != area_get_width(param) ||
|
||||
lv_obj_get_height(page) != area_get_height(param))) {
|
||||
|
||||
if(lv_cont_get_hfit(ext->scrl) == false) {
|
||||
lv_obj_set_width(ext->scrl, lv_obj_get_width(page) - 2 * style->hpad);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
||||
|
||||
ext->scrl->signal_f(ext->scrl, LV_SIGNAL_CORD_CHG, &ext->scrl->cords);
|
||||
|
||||
/*The scrollbars are important olny if they are visible now*/
|
||||
if(ext->sbh_draw != 0 || ext->sbv_draw != 0)
|
||||
lv_page_sb_refresh(page);
|
||||
|
||||
}
|
||||
} else if(sign == LV_SIGNAL_PRESSED) {
|
||||
if(ext->pr_action != NULL) {
|
||||
ext->pr_action(page, param);
|
||||
}
|
||||
} else if(sign == LV_SIGNAL_RELEASED) {
|
||||
if(lv_dispi_is_dragging(param) == false) {
|
||||
if(ext->rel_action != NULL) {
|
||||
ext->rel_action(page, param);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -215,118 +220,112 @@ static bool lv_scrl_signal(lv_obj_t * scrl, lv_signal_t sign, void* param)
|
||||
* make the object specific signal handling */
|
||||
if(obj_valid != false) {
|
||||
|
||||
cord_t new_x;
|
||||
cord_t new_y;
|
||||
bool refr_x = false;
|
||||
bool refr_y = false;
|
||||
area_t page_cords;
|
||||
area_t obj_cords;
|
||||
lv_obj_t * page = lv_obj_get_parent(scrl);
|
||||
lv_style_t * page_style = lv_obj_get_style(page);
|
||||
lv_page_ext_t * page_ext = lv_obj_get_ext(page);
|
||||
cord_t hpad = page_style->hpad;
|
||||
cord_t vpad = page_style->vpad;
|
||||
|
||||
switch(sign) {
|
||||
case LV_SIGNAL_CORD_CHG:
|
||||
new_x = lv_obj_get_x(scrl);
|
||||
new_y = lv_obj_get_y(scrl);
|
||||
lv_obj_get_cords(scrl, &obj_cords);
|
||||
lv_obj_get_cords(page, &page_cords);
|
||||
if(sign == LV_SIGNAL_CORD_CHG) {
|
||||
cord_t new_x;
|
||||
cord_t new_y;
|
||||
bool refr_x = false;
|
||||
bool refr_y = false;
|
||||
area_t page_cords;
|
||||
area_t scrl_cords;
|
||||
cord_t hpad = page_style->hpad;
|
||||
cord_t vpad = page_style->vpad;
|
||||
|
||||
/*scrollable width smaller then page width? -> align to left*/
|
||||
if(area_get_width(&obj_cords) + 2 * hpad < area_get_width(&page_cords)) {
|
||||
if(obj_cords.x1 != page_cords.x1 + hpad) {
|
||||
new_x = hpad;
|
||||
refr_x = true;
|
||||
}
|
||||
} else {
|
||||
/*The edges of the scrollable can not be in the page (minus hpad) */
|
||||
if(obj_cords.x2 < page_cords.x2 - hpad) {
|
||||
new_x = area_get_width(&page_cords) - area_get_width(&obj_cords) - hpad; /* Right align */
|
||||
refr_x = true;
|
||||
}
|
||||
if (obj_cords.x1 > page_cords.x1 + hpad) {
|
||||
new_x = hpad; /*Left align*/
|
||||
refr_x = true;
|
||||
}
|
||||
new_x = lv_obj_get_x(scrl);
|
||||
new_y = lv_obj_get_y(scrl);
|
||||
lv_obj_get_cords(scrl, &scrl_cords);
|
||||
lv_obj_get_cords(page, &page_cords);
|
||||
|
||||
/*scrollable width smaller then page width? -> align to left*/
|
||||
if(area_get_width(&scrl_cords) + 2 * hpad < area_get_width(&page_cords)) {
|
||||
if(scrl_cords.x1 != page_cords.x1 + hpad) {
|
||||
new_x = hpad;
|
||||
refr_x = true;
|
||||
}
|
||||
|
||||
/*scrollable height smaller then page height? -> align to left*/
|
||||
if(area_get_height(&obj_cords) + 2 * vpad < area_get_height(&page_cords)) {
|
||||
if(obj_cords.y1 != page_cords.y1 + vpad) {
|
||||
new_y = vpad;
|
||||
refr_y = true;
|
||||
}
|
||||
} else {
|
||||
/*The edges of the scrollable can not be in the page (minus vpad) */
|
||||
if(obj_cords.y2 < page_cords.y2 - vpad) {
|
||||
new_y = area_get_height(&page_cords) - area_get_height(&obj_cords) - vpad; /* Bottom align */
|
||||
refr_y = true;
|
||||
}
|
||||
if (obj_cords.y1 > page_cords.y1 + vpad) {
|
||||
new_y = vpad; /*Top align*/
|
||||
refr_y = true;
|
||||
}
|
||||
} else {
|
||||
/*The edges of the scrollable can not be in the page (minus hpad) */
|
||||
if(scrl_cords.x2 < page_cords.x2 - hpad) {
|
||||
new_x = area_get_width(&page_cords) - area_get_width(&scrl_cords) - hpad; /* Right align */
|
||||
refr_x = true;
|
||||
}
|
||||
if(refr_x != false || refr_y != false) {
|
||||
lv_obj_set_pos(scrl, new_x, new_y);
|
||||
if (scrl_cords.x1 > page_cords.x1 + hpad) {
|
||||
new_x = hpad; /*Left align*/
|
||||
refr_x = true;
|
||||
}
|
||||
}
|
||||
|
||||
lv_page_sb_refresh(page);
|
||||
break;
|
||||
|
||||
case LV_SIGNAL_DRAG_BEGIN:
|
||||
if(page_ext->sb_mode == LV_PAGE_SB_MODE_DRAG ) {
|
||||
cord_t sbh_pad = MATH_MAX(page_ext->sb_width, page_style->hpad);
|
||||
cord_t sbv_pad = MATH_MAX(page_ext->sb_width, page_style->vpad);
|
||||
if(area_get_height(&page_ext->sbv) < lv_obj_get_height(scrl) - 2 * sbv_pad) {
|
||||
page_ext->sbv_draw = 1;
|
||||
}
|
||||
if(area_get_width(&page_ext->sbh) < lv_obj_get_width(scrl) - 2 * sbh_pad) {
|
||||
page_ext->sbh_draw = 1;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case LV_SIGNAL_DRAG_END:
|
||||
if(page_ext->sb_mode == LV_PAGE_SB_MODE_DRAG) {
|
||||
area_t sb_area_tmp;
|
||||
if(page_ext->sbh_draw != 0) {
|
||||
area_cpy(&sb_area_tmp, &page_ext->sbh);
|
||||
sb_area_tmp.x1 += page->cords.x1;
|
||||
sb_area_tmp.y1 += page->cords.y1;
|
||||
sb_area_tmp.x2 += page->cords.x2;
|
||||
sb_area_tmp.y2 += page->cords.y2;
|
||||
lv_inv_area(&sb_area_tmp);
|
||||
page_ext->sbh_draw = 0;
|
||||
}
|
||||
if(page_ext->sbv_draw != 0) {
|
||||
area_cpy(&sb_area_tmp, &page_ext->sbv);
|
||||
sb_area_tmp.x1 += page->cords.x1;
|
||||
sb_area_tmp.y1 += page->cords.y1;
|
||||
sb_area_tmp.x2 += page->cords.x2;
|
||||
sb_area_tmp.y2 += page->cords.y2;
|
||||
lv_inv_area(&sb_area_tmp);
|
||||
page_ext->sbv_draw = 0;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case LV_SIGNAL_PRESSED:
|
||||
if(page_ext->pr_action != NULL) {
|
||||
page_ext->pr_action(page, param);
|
||||
/*scrollable height smaller then page height? -> align to left*/
|
||||
if(area_get_height(&scrl_cords) + 2 * vpad < area_get_height(&page_cords)) {
|
||||
if(scrl_cords.y1 != page_cords.y1 + vpad) {
|
||||
new_y = vpad;
|
||||
refr_y = true;
|
||||
}
|
||||
break;
|
||||
case LV_SIGNAL_RELEASED:
|
||||
if(lv_dispi_is_dragging(param) == false) {
|
||||
if(page_ext->rel_action != NULL) {
|
||||
page_ext->rel_action(page, param);
|
||||
}
|
||||
} else {
|
||||
/*The edges of the scrollable can not be in the page (minus vpad) */
|
||||
if(scrl_cords.y2 < page_cords.y2 - vpad) {
|
||||
new_y = area_get_height(&page_cords) - area_get_height(&scrl_cords) - vpad; /* Bottom align */
|
||||
refr_y = true;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
if (scrl_cords.y1 > page_cords.y1 + vpad) {
|
||||
new_y = vpad; /*Top align*/
|
||||
refr_y = true;
|
||||
}
|
||||
}
|
||||
if(refr_x != false || refr_y != false) {
|
||||
lv_obj_set_pos(scrl, new_x, new_y);
|
||||
}
|
||||
|
||||
lv_page_sb_refresh(page);
|
||||
} else if(sign == LV_SIGNAL_CORD_CHG) {
|
||||
if(lv_cont_get_hfit(scrl) == false) {
|
||||
lv_obj_set_width(scrl, lv_obj_get_width(page) - 2 * page_style->hpad);
|
||||
}
|
||||
} else if(sign == LV_SIGNAL_DRAG_BEGIN) {
|
||||
if(page_ext->sb_mode == LV_PAGE_SB_MODE_DRAG ) {
|
||||
cord_t sbh_pad = MATH_MAX(page_ext->sb_width, page_style->hpad);
|
||||
cord_t sbv_pad = MATH_MAX(page_ext->sb_width, page_style->vpad);
|
||||
if(area_get_height(&page_ext->sbv) < lv_obj_get_height(scrl) - 2 * sbv_pad) {
|
||||
page_ext->sbv_draw = 1;
|
||||
}
|
||||
if(area_get_width(&page_ext->sbh) < lv_obj_get_width(scrl) - 2 * sbh_pad) {
|
||||
page_ext->sbh_draw = 1;
|
||||
}
|
||||
}
|
||||
} else if(sign == LV_SIGNAL_DRAG_END) {
|
||||
if(page_ext->sb_mode == LV_PAGE_SB_MODE_DRAG) {
|
||||
area_t sb_area_tmp;
|
||||
if(page_ext->sbh_draw != 0) {
|
||||
area_cpy(&sb_area_tmp, &page_ext->sbh);
|
||||
sb_area_tmp.x1 += page->cords.x1;
|
||||
sb_area_tmp.y1 += page->cords.y1;
|
||||
sb_area_tmp.x2 += page->cords.x2;
|
||||
sb_area_tmp.y2 += page->cords.y2;
|
||||
lv_inv_area(&sb_area_tmp);
|
||||
page_ext->sbh_draw = 0;
|
||||
}
|
||||
if(page_ext->sbv_draw != 0) {
|
||||
area_cpy(&sb_area_tmp, &page_ext->sbv);
|
||||
sb_area_tmp.x1 += page->cords.x1;
|
||||
sb_area_tmp.y1 += page->cords.y1;
|
||||
sb_area_tmp.x2 += page->cords.x2;
|
||||
sb_area_tmp.y2 += page->cords.y2;
|
||||
lv_inv_area(&sb_area_tmp);
|
||||
page_ext->sbv_draw = 0;
|
||||
}
|
||||
}
|
||||
}else if(sign == LV_SIGNAL_PRESSED) {
|
||||
if(page_ext->pr_action != NULL) {
|
||||
page_ext->pr_action(page, param);
|
||||
}
|
||||
} else if(sign == LV_SIGNAL_RELEASED) {
|
||||
if(lv_dispi_is_dragging(param) == false) {
|
||||
if(page_ext->rel_action != NULL) {
|
||||
page_ext->rel_action(page, param);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -534,41 +533,85 @@ lv_style_t * lv_page_get_style_sb(lv_obj_t * page)
|
||||
* LV_DESIGN_DRAW_POST: drawing after every children are drawn
|
||||
* @param return true/false, depends on 'mode'
|
||||
*/
|
||||
static bool lv_page_design(lv_obj_t * page, const area_t * mask, lv_design_mode_t mode)
|
||||
static bool lv_page_design(lv_obj_t * scrl, const area_t * mask, lv_design_mode_t mode)
|
||||
{
|
||||
if(mode == LV_DESIGN_COVER_CHK) {
|
||||
return ancestor_design_f(page, mask, mode);
|
||||
return ancestor_page_design_f(scrl, mask, mode);
|
||||
} else if(mode == LV_DESIGN_DRAW_MAIN) {
|
||||
ancestor_design_f(page, mask, mode);
|
||||
ancestor_page_design_f(scrl, mask, mode);
|
||||
} else if(mode == LV_DESIGN_DRAW_POST) { /*Draw the scroll bars finally*/
|
||||
ancestor_design_f(page, mask, mode);
|
||||
lv_page_ext_t * ext = lv_obj_get_ext(page);
|
||||
ancestor_page_design_f(scrl, mask, mode);
|
||||
lv_page_ext_t * ext = lv_obj_get_ext(scrl);
|
||||
|
||||
/*Draw the scrollbars*/
|
||||
area_t sb_area;
|
||||
if(ext->sbh_draw != 0) {
|
||||
/*Convert the relative coordinates to absolute*/
|
||||
area_cpy(&sb_area, &ext->sbh);
|
||||
sb_area.x1 += page->cords.x1;
|
||||
sb_area.y1 += page->cords.y1;
|
||||
sb_area.x2 += page->cords.x1;
|
||||
sb_area.y2 += page->cords.y1;
|
||||
sb_area.x1 += scrl->cords.x1;
|
||||
sb_area.y1 += scrl->cords.y1;
|
||||
sb_area.x2 += scrl->cords.x1;
|
||||
sb_area.y2 += scrl->cords.y1;
|
||||
lv_draw_rect(&sb_area, mask, ext->style_sb);
|
||||
}
|
||||
|
||||
if(ext->sbv_draw != 0) {
|
||||
/*Convert the relative coordinates to absolute*/
|
||||
area_cpy(&sb_area, &ext->sbv);
|
||||
sb_area.x1 += page->cords.x1;
|
||||
sb_area.y1 += page->cords.y1;
|
||||
sb_area.x2 += page->cords.x1;
|
||||
sb_area.y2 += page->cords.y1;
|
||||
sb_area.x1 += scrl->cords.x1;
|
||||
sb_area.y1 += scrl->cords.y1;
|
||||
sb_area.x2 += scrl->cords.x1;
|
||||
sb_area.y2 += scrl->cords.y1;
|
||||
lv_draw_rect(&sb_area, mask, ext->style_sb);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
/**
|
||||
* Handle the drawing related tasks of the scrollable object
|
||||
* @param scrl pointer to an object
|
||||
* @param mask the object will be drawn only in this area
|
||||
* @param mode LV_DESIGN_COVER_CHK: only check if the object fully covers the 'mask_p' area
|
||||
* (return 'true' if yes)
|
||||
* LV_DESIGN_DRAW: draw the object (always return 'true')
|
||||
* LV_DESIGN_DRAW_POST: drawing after every children are drawn
|
||||
* @param return true/false, depends on 'mode'
|
||||
*/
|
||||
static bool lv_scrl_design(lv_obj_t * scrl, const area_t * mask, lv_design_mode_t mode)
|
||||
{
|
||||
if(mode == LV_DESIGN_COVER_CHK) {
|
||||
return ancestor_page_design_f(scrl, mask, mode);
|
||||
} else if(mode == LV_DESIGN_DRAW_MAIN) {
|
||||
#if LV_OBJ_GROUP != 0
|
||||
/* If the page is the active in a group and
|
||||
* the background (page) is not visible (transparent or empty)
|
||||
* then activate the style of the scrollable*/
|
||||
lv_style_t * style_ori = lv_obj_get_style(scrl);
|
||||
lv_obj_t * page = lv_obj_get_parent(scrl);
|
||||
lv_style_t * style_page = lv_obj_get_style(page);
|
||||
lv_group_t * g = lv_obj_get_group(page);
|
||||
if(style_page->empty != 0 || style_page->opa == OPA_TRANSP) { /*Background is visible?*/
|
||||
if(lv_group_get_focused(g) == page) {
|
||||
lv_style_t * style_mod;
|
||||
style_mod = lv_group_mod_style(g, style_ori);
|
||||
scrl->style_p = style_mod; /*Temporally change the style to the activated */
|
||||
}
|
||||
}
|
||||
#endif
|
||||
ancestor_page_design_f(scrl, mask, mode);
|
||||
|
||||
#if LV_OBJ_GROUP != 0
|
||||
scrl->style_p = style_ori; /*Revert the style*/
|
||||
#endif
|
||||
} else if(mode == LV_DESIGN_DRAW_POST) {
|
||||
ancestor_page_design_f(scrl, mask, mode);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Refresh the position and size of the scroll bars.
|
||||
|
||||
@@ -10,12 +10,14 @@
|
||||
#if USE_LV_SLIDER != 0
|
||||
|
||||
#include "lv_slider.h"
|
||||
#include "lvgl/lv_obj/lv_group.h"
|
||||
#include "misc/math/math_base.h"
|
||||
#include "../lv_draw/lv_draw.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
#define LV_SLIDER_SIZE_MIN (2 * LV_DOWNSCALE) /*hpad and vpad cannot make the bar or indicator smaller then this [px]*/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
@@ -52,7 +54,6 @@ static lv_design_f_t ancestor_design_f;
|
||||
lv_obj_t * lv_slider_create(lv_obj_t * par, lv_obj_t * copy)
|
||||
{
|
||||
/*Create the ancestor slider*/
|
||||
/*TODO modify it to the ancestor create function */
|
||||
lv_obj_t * new_slider = lv_bar_create(par, copy);
|
||||
dm_assert(new_slider);
|
||||
|
||||
@@ -102,7 +103,6 @@ bool lv_slider_signal(lv_obj_t * slider, lv_signal_t sign, void * param)
|
||||
bool valid;
|
||||
|
||||
/* Include the ancient signal function */
|
||||
/* TODO update it to the ancestor's signal function*/
|
||||
valid = lv_bar_signal(slider, sign, param);
|
||||
|
||||
/* The object can be deleted so check its validity and then
|
||||
@@ -145,10 +145,19 @@ bool lv_slider_signal(lv_obj_t * slider, lv_signal_t sign, void * param)
|
||||
lv_obj_get_height(slider) != area_get_height(param)) {
|
||||
slider->signal_f(slider, LV_SIGNAL_REFR_EXT_SIZE, NULL);
|
||||
}
|
||||
}
|
||||
else if(sign == LV_SIGNAL_REFR_EXT_SIZE) {
|
||||
} else if(sign == LV_SIGNAL_REFR_EXT_SIZE) {
|
||||
cord_t x = MATH_MIN(w, h);
|
||||
if(slider->ext_size < x) slider->ext_size = x;
|
||||
} else if(sign == LV_SIGNAL_CONTROLL) {
|
||||
lv_slider_ext_t * ext = lv_obj_get_ext(slider);
|
||||
char c = *((char*)param);
|
||||
if(c == LV_GROUP_KEY_RIGHT || c == LV_GROUP_KEY_UP) {
|
||||
lv_bar_set_value(slider, lv_bar_get_value(slider) + 1);
|
||||
if(ext->cb != NULL) ext->cb(slider, NULL);
|
||||
} else if(c == LV_GROUP_KEY_LEFT || c == LV_GROUP_KEY_DOWN) {
|
||||
lv_bar_set_value(slider, lv_bar_get_value(slider) - 1);
|
||||
if(ext->cb != NULL) ext->cb(slider, NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -238,24 +247,47 @@ static bool lv_slider_design(lv_obj_t * slider, const area_t * mask, lv_design_m
|
||||
lv_style_t * style_knob = lv_slider_get_style_knob(slider);
|
||||
lv_style_t * style_indic = lv_bar_get_style_indic(slider);
|
||||
|
||||
/*Draw the bar*/
|
||||
area_t area_bar;
|
||||
|
||||
area_cpy(&area_bar, &slider->cords);
|
||||
area_bar.x1 += style_knob->hpad;
|
||||
area_bar.x2 -= style_knob->hpad;
|
||||
area_bar.y1 += style_knob->vpad;
|
||||
area_bar.y2 -= style_knob->vpad;
|
||||
/*Be sure at least vpad/hpad width bar will remain*/
|
||||
cord_t vpad_bar = style_indic->vpad;
|
||||
cord_t hpad_bar = style_indic->hpad;
|
||||
if(vpad_bar * 2 + LV_SLIDER_SIZE_MIN > area_get_height(&area_bar)) {
|
||||
vpad_bar = (area_get_height(&area_bar) - LV_SLIDER_SIZE_MIN) >> 1;
|
||||
}
|
||||
if(hpad_bar * 2 + LV_SLIDER_SIZE_MIN > area_get_width(&area_bar)) {
|
||||
hpad_bar = (area_get_width(&area_bar) - LV_SLIDER_SIZE_MIN) >> 1;
|
||||
}
|
||||
|
||||
area_bar.x1 += hpad_bar;
|
||||
area_bar.x2 -= hpad_bar;
|
||||
area_bar.y1 += vpad_bar;
|
||||
area_bar.y2 -= vpad_bar;
|
||||
lv_draw_rect(&area_bar, mask, style_slider);
|
||||
|
||||
/*Draw the indicator*/
|
||||
area_t area_indic;
|
||||
area_cpy(&area_indic, &area_bar);
|
||||
area_indic.x1 += style_indic->hpad;
|
||||
area_indic.x2 -= style_indic->hpad;
|
||||
area_indic.y1 += style_indic->vpad;
|
||||
area_indic.y2 -= style_indic->vpad;
|
||||
|
||||
/*Be sure at least vpad/hpad width indicator will remain*/
|
||||
cord_t vpad_indic = style_indic->vpad;
|
||||
cord_t hpad_indic = style_indic->hpad;
|
||||
if(vpad_indic * 2 + LV_SLIDER_SIZE_MIN > area_get_height(&area_bar)) {
|
||||
vpad_indic = (area_get_height(&area_bar) - LV_SLIDER_SIZE_MIN) >> 1;
|
||||
}
|
||||
if(hpad_indic * 2 + LV_SLIDER_SIZE_MIN > area_get_width(&area_bar)) {
|
||||
hpad_indic = (area_get_width(&area_bar) - LV_SLIDER_SIZE_MIN) >> 1;
|
||||
}
|
||||
|
||||
area_indic.x1 += hpad_indic;
|
||||
area_indic.x2 -= hpad_indic;
|
||||
area_indic.y1 += vpad_indic;
|
||||
area_indic.y2 -= vpad_indic;
|
||||
|
||||
cord_t slider_w = area_get_width(&slider->cords);
|
||||
cord_t slider_h = area_get_height(&slider->cords);
|
||||
|
||||
cord_t act_value = lv_bar_get_value(slider);
|
||||
cord_t min_value = lv_bar_get_min_value(slider);
|
||||
cord_t max_value = lv_bar_get_max_value(slider);
|
||||
|
||||
110
lv_objx/lv_ta.c
110
lv_objx/lv_ta.c
@@ -11,6 +11,7 @@
|
||||
#if USE_LV_TA != 0
|
||||
|
||||
#include "lv_ta.h"
|
||||
#include "lvgl/lv_obj/lv_group.h"
|
||||
#include "misc/gfx/anim.h"
|
||||
#include "../lv_draw/lv_draw.h"
|
||||
|
||||
@@ -114,6 +115,7 @@ lv_obj_t * lv_ta_create(lv_obj_t * par, lv_obj_t * copy)
|
||||
lv_ta_ext_t * copy_ext = lv_obj_get_ext(copy);
|
||||
ext->label = lv_label_create(new_ta, copy_ext->label);
|
||||
ext->cursor_show = copy_ext->cursor_show;
|
||||
ext->pwd_mode = copy_ext->pwd_mode;
|
||||
lv_page_glue_obj(ext->label, true);
|
||||
|
||||
/*Refresh the style with new signal function*/
|
||||
@@ -158,32 +160,39 @@ bool lv_ta_signal(lv_obj_t * ta, lv_signal_t sign, void * param)
|
||||
if(valid != false) {
|
||||
lv_ta_ext_t * ext = lv_obj_get_ext(ta);
|
||||
lv_style_t * style = lv_obj_get_style(ta);
|
||||
switch(sign) {
|
||||
case LV_SIGNAL_CLEANUP:
|
||||
/* Nothing to clean up.
|
||||
* (The created label will be deleted automatically) */
|
||||
break;
|
||||
case LV_SIGNAL_STYLE_CHG:
|
||||
if(ext->label) {
|
||||
lv_obj_set_style(ext->label, lv_obj_get_style(ext->page.scrl));
|
||||
lv_obj_set_width(ext->label, lv_obj_get_width(ta) - 2 *
|
||||
(style->hpad + style->hpad));
|
||||
lv_label_set_text(ext->label, NULL);
|
||||
}
|
||||
break;
|
||||
if(sign == LV_SIGNAL_CLEANUP) {
|
||||
if(ext->pwd_tmp != NULL) dm_free(ext->pwd_tmp);
|
||||
|
||||
/* (The created label will be deleted automatically) */
|
||||
} else if(sign == LV_SIGNAL_STYLE_CHG) {
|
||||
if(ext->label) {
|
||||
lv_obj_set_style(ext->label, lv_obj_get_style(ext->page.scrl));
|
||||
lv_obj_set_width(ext->label, lv_obj_get_width(ta) - 2 *
|
||||
(style->hpad + style->hpad));
|
||||
lv_label_set_text(ext->label, NULL);
|
||||
}
|
||||
} else if(sign == LV_SIGNAL_CORD_CHG) {
|
||||
/*Set the label width according to the text area width*/
|
||||
case LV_SIGNAL_CORD_CHG:
|
||||
if(ext->label != NULL) {
|
||||
lv_obj_set_width(ext->label, lv_obj_get_width(ta) - 2 *
|
||||
(style->hpad + style->hpad));
|
||||
if(ext->label != NULL) {
|
||||
if(lv_obj_get_width(ta) != area_get_width(param) ||
|
||||
lv_obj_get_height(ta) != area_get_height(param)) {
|
||||
lv_obj_set_width(ext->label, lv_obj_get_width(ta) - 2 * style->hpad);
|
||||
lv_label_set_text(ext->label, NULL);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (sign == LV_SIGNAL_CONTROLL) {
|
||||
char c = *((char*)param);
|
||||
if(c == LV_GROUP_KEY_RIGHT) {
|
||||
lv_ta_cursor_right(ta);
|
||||
} else if(c == LV_GROUP_KEY_LEFT) {
|
||||
lv_ta_cursor_left(ta);
|
||||
} else if(c == LV_GROUP_KEY_UP) {
|
||||
lv_ta_cursor_up(ta);
|
||||
} else if(c == LV_GROUP_KEY_DOWN) {
|
||||
lv_ta_cursor_down(ta);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return valid;
|
||||
}
|
||||
|
||||
@@ -305,6 +314,12 @@ void lv_ta_set_text(lv_obj_t * ta, const char * txt)
|
||||
lv_label_set_text(ext->label, txt);
|
||||
lv_ta_set_cursor_pos(ta, LV_TA_CUR_LAST);
|
||||
|
||||
/*Don't let 'width == 0' because cursor will not be visible*/
|
||||
if(lv_obj_get_width(ext->label) == 0) {
|
||||
lv_style_t * style = lv_obj_get_style(ext->label);
|
||||
lv_obj_set_width(ext->label, style->line_width);
|
||||
}
|
||||
|
||||
/*It is a valid x step so save it*/
|
||||
lv_ta_save_valid_cursor_x(ta);
|
||||
|
||||
@@ -346,6 +361,11 @@ void lv_ta_del(lv_obj_t * ta)
|
||||
|
||||
/*Refresh the label*/
|
||||
lv_label_set_text(ext->label, buf);
|
||||
/*Don't let 'width == 0' because cursor will not be visible*/
|
||||
if(lv_obj_get_width(ext->label) == 0) {
|
||||
lv_style_t * style = lv_obj_get_style(ext->label);
|
||||
lv_obj_set_width(ext->label, style->line_width);
|
||||
}
|
||||
|
||||
/*Move the cursor to the place of the deleted character*/
|
||||
lv_ta_set_cursor_pos(ta, lv_ta_get_cursor_pos(ta) - 1);
|
||||
@@ -397,6 +417,16 @@ void lv_ta_set_cursor_pos(lv_obj_t * ta, int16_t pos)
|
||||
lv_obj_set_y(label_par, -(cur_pos.y - lv_obj_get_height(ta) +
|
||||
font_h + 2 * style_scrl->vpad));
|
||||
}
|
||||
/*Check the left (use the font_h as general unit)*/
|
||||
if(lv_obj_get_x(label_par) + cur_pos.x < font_h) {
|
||||
lv_obj_set_x(label_par, - cur_pos.x + font_h);
|
||||
}
|
||||
|
||||
/*Check the right (use the font_h as general unit)*/
|
||||
if(label_cords.x1 + cur_pos.x + font_h + style_scrl->hpad > ta_cords.x2) {
|
||||
lv_obj_set_x(label_par, -(cur_pos.x - lv_obj_get_width(ta) +
|
||||
font_h + 2 * style_scrl->hpad));
|
||||
}
|
||||
|
||||
lv_obj_inv(ta);
|
||||
}
|
||||
@@ -526,6 +556,36 @@ void lv_ta_set_pwd_mode(lv_obj_t * ta, bool en)
|
||||
|
||||
ext->pwd_mode = en == false ? 0 : 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Configure the text area to one line or back to normal
|
||||
* @param ta pointer to a Text area object
|
||||
* @param en true: one line, false: normal
|
||||
*/
|
||||
void lv_ta_set_one_line(lv_obj_t * ta, bool en)
|
||||
{
|
||||
if(en != false) {
|
||||
lv_ta_ext_t * ext = lv_obj_get_ext(ta);
|
||||
lv_style_t * style_ta = lv_obj_get_style(ta);
|
||||
lv_style_t * style_label = lv_obj_get_style(ext->label);
|
||||
|
||||
lv_cont_set_fit(lv_page_get_scrl(ta), true, true);
|
||||
lv_obj_set_height(ta, font_get_height(style_label->font) + style_ta->vpad * 2);
|
||||
lv_label_set_long_mode(ext->label, LV_LABEL_LONG_EXPAND);
|
||||
lv_label_set_no_break(ext->label, true);
|
||||
lv_obj_set_pos(lv_page_get_scrl(ta), style_ta->hpad, style_ta->vpad);
|
||||
} else {
|
||||
lv_ta_ext_t * ext = lv_obj_get_ext(ta);
|
||||
lv_style_t * style_ta = lv_obj_get_style(ta);
|
||||
|
||||
lv_cont_set_fit(lv_page_get_scrl(ta), false, true);
|
||||
lv_label_set_long_mode(ext->label, LV_LABEL_LONG_BREAK);
|
||||
lv_label_set_no_break(ext->label, false);
|
||||
lv_obj_set_height(ta, LV_TA_DEF_HEIGHT);
|
||||
lv_obj_set_pos(lv_page_get_scrl(ta), style_ta->hpad, style_ta->vpad);
|
||||
}
|
||||
}
|
||||
|
||||
/*=====================
|
||||
* Getter functions
|
||||
*====================*/
|
||||
@@ -657,9 +717,9 @@ static bool lv_ta_scrling_design(lv_obj_t * scrling, const area_t * mask, lv_des
|
||||
|
||||
area_t cur_area;
|
||||
lv_style_t * labels_p = lv_obj_get_style(ta_ext->label);
|
||||
cur_area.x1 = letter_pos.x + ta_ext->label->cords.x1;
|
||||
cur_area.x1 = letter_pos.x + ta_ext->label->cords.x1 - scrl_style->line_width / 2 ;
|
||||
cur_area.y1 = letter_pos.y + ta_ext->label->cords.y1;
|
||||
cur_area.x2 = letter_pos.x + ta_ext->label->cords.x1 + scrl_style->line_width ;
|
||||
cur_area.x2 = letter_pos.x + ta_ext->label->cords.x1 + scrl_style->line_width / 2 + (scrl_style->line_width & 0x1);
|
||||
cur_area.y2 = letter_pos.y + ta_ext->label->cords.y1 + (font_get_height(labels_p->font) >> FONT_ANTIALIAS);
|
||||
|
||||
lv_style_t cur_rects;
|
||||
|
||||
@@ -147,6 +147,13 @@ void lv_ta_set_cursor_show(lv_obj_t * ta, bool show);
|
||||
*/
|
||||
void lv_ta_set_pwd_mode(lv_obj_t * ta, bool en);
|
||||
|
||||
/**
|
||||
* Configure the Text area to one line or back to normal
|
||||
* @param ta pointer to a text area object
|
||||
* @param en true: one line, false: normal
|
||||
*/
|
||||
void lv_ta_set_one_line(lv_obj_t * ta, bool en);
|
||||
|
||||
/**
|
||||
* Get the text of the i the text area
|
||||
* @param ta obj pointer to a text area object
|
||||
|
||||
7
lvgl.h
7
lvgl.h
@@ -17,6 +17,7 @@ extern "C" {
|
||||
/*Test misc. module version*/
|
||||
#include "misc/misc.h"
|
||||
#include "lv_obj/lv_obj.h"
|
||||
#include "lv_obj/lv_group.h"
|
||||
#include "lv_objx/lv_btn.h"
|
||||
#include "lv_objx/lv_img.h"
|
||||
#include "lv_objx/lv_label.h"
|
||||
@@ -44,12 +45,12 @@ extern "C" {
|
||||
*********************/
|
||||
/*Current version of LittlevGL*/
|
||||
#define LVGL_VERSION_MAJOR 4
|
||||
#define LVGL_VERSION_MINOR 1
|
||||
#define LVGL_VERSION_PATH 1
|
||||
#define LVGL_VERSION_MINOR 2
|
||||
#define LVGL_VERSION_PATH 0
|
||||
|
||||
/*Required misc. library version*/
|
||||
#define LV_MISC_REQ_MAJOR 4
|
||||
#define LV_MISC_REQ_MINOR 1
|
||||
#define LV_MISC_REQ_MINOR 2
|
||||
#define LV_MISC_REQ_PATCH 0
|
||||
|
||||
#if MISC_VERSION_MAJOR != LV_MISC_REQ_MAJOR /*The version major has to match*/
|
||||
|
||||
Reference in New Issue
Block a user