1
0
mirror of https://github.com/lvgl/lvgl.git synced 2025-01-28 07:03:00 +08:00

Merge branch 'dev-5.3' of https://github.com/littlevgl/lvgl into dev-5.3

This commit is contained in:
Gabor Kiss-Vamosi 2018-12-19 16:35:58 +01:00
commit 47f507ff62
36 changed files with 1402 additions and 299 deletions

View File

@ -1,181 +1,93 @@
# Contributing to Littlev Graphics Library
It's glad to see that you are interested in Contributing to LittlevGL!
In this guide you can learn how can you help to develop LittlevGL.
### Table Of Content
* [Who can contribute?](#who-can-contribute)
* [How to report an issue?](#how-to-report-a-bug)
* [How to suggest a feature?](#how-to-suggest-a-feature)
* [How to implement a feature?](#how-to-implement-a-feature)
* [Styling guide](#styling-guide)
## Who can contribute?
As graphical interfaces for embedded systems has an increasing relevance today you also might find important to work with a good graphics library. Now - independently from skills, programming level or any personal attributes - you can influence and help the development of Littlev Graphics Library with:
* Report an issue
* Suggest feature
* Fix an issue
* Implement a feature
* Help with testing bugfixes and new features
Please, take a look at [CODE_OF_CONDUCT](https://github.com/littlevgl/lvgl/blob/master/docs/CODE_OF_CONDUCT.md)
There are few **general rules**
* We use [GitHub's issue tracker](https://github.com/littlevgl/lvgl/issues)
* Be kind and respectful. Starting with "Hi" is always a good idea :)
* If somebody helped you give a feedback.
* One issue should be about one topic. If you have other questions please open a new issue.
* Always create an issue before creating a [Pull request](https://help.github.com/articles/about-pull-requests/) to discuss the idea first
* Create small, "digestible" Pull requests.
* Tell your remarks in a structured way. Use paragraphs and the [Markdown](https://guides.github.com/features/mastering-markdown/) support of GitHub.
* Be sure you are using the latest version (from `master` branch)
* Keep in mind LittlevGL should be and should remain:
- usable on small MCUs as well (think about memory footprint)
- compilable with "non-standard" tools like Arduino (no gcc specific options)
- C compatible (no C++ specific code and features)
- all configuration should be in `lv_conf.h`. (Instead of modifying the library)
- the API clean and easiy to understand
## How to report a bug?
If you found a **simple and straightforward bug** like:
* misspelling (in comments function/variable names or grammatical issues in comments)
* not handled error cases (negative array index, overflow etc)
* anything else which can be fixed locally with a few lines of code
* or defective documentation
then tell:
* where you found the bug (which file/function/variable)
* how can it cause problem
* what is your suggested solution if you have
If you faced with **something more complex** like:
* might be simple but you don't know its origin
* affects a whole file, module or even the architecture
* needs deeper discussion
then please
* tell what do you experience
* tell what do you expect to happen
* tell how to reproduce the issue
* provide a simplified code example (better if can be tested with copy-paste)
* attache your lv_conf.h (if you feel it's important)
* logs and long codes should be attached in a file (instead of copying into a comment)
## How to suggest a feature?
If you have a good and useful idea open issue to tell it! Please note the followings on suggesting new features:
* What the new feature is about?
* Why/Where/In which case is it useful/helpful/relevant?
* Can you mention real life usecases/examples for the use this feature?
* Can you help in implementing it?
Your suggestion can have 4 possible outcomes:
1. This feature is already exists. In this case you will learn how to achieve your goal.
2. You can simply realize it with the current functionality.
3. Although it's a new feature but it would break LittlevGL's platform independent and/or resource minimalist nature.
4. It's really a new feature which would be good to be in LittlevGL. Hurray! In a discussion we figure out the technical details and implementation options. With the knowledge of how to do it somebody can implement the new feature.
Keep in mind if you wouldn't like to do the implementation there is no guarantee that it will be ready in the near 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 these files, please start an issue and discuss the details.
The new feature should be in a new branch.
## Styling guide
### File format
Use [lv_misc/lv_templ.c](https://github.com/littlevgl/lvgl/blob/master/lv_misc/lv_templ.c) and [lv_misc/lv_templ.h](https://github.com/littlevgl/lvgl/blob/master/lv_misc/lv_templ.h)
### Naming conventions
* Words are separated by '_'
* In variable and function names use only lower case letters (e.g. *height_tmp*)
* In enums and defines use only upper case letters (e.g. *e.g. MAX_LINE_NUM*)
* Global names (API):
* starts with *lv*
* followed by module name: *btn*, *label*, *style* etc.
* followed by the action (for functions): *set*, *get*, *refr* etc.
* closed with the subject: *name*, *size*, *state* etc.
* Typedefs
* prefer `typedef struct` and `typedef enum` instead of `struct name` and `enum name`
* always add a closing *..._t*
* Abbreviations:
* Use abbreviations on public names only if they become longer than 32 characters
* Use only very straightforward (e.g. pos: position) or well-established (e.g. pr: press) abbreviations
### Coding guide
* Functions:
* Try to write function shorter than is 50 lines
* Always shorter than 100 lines (except very straightforwards)
* Variables:
* 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)
### Comments
Before every function have a comment like this:
```c
/**
* Return with the screen of an object
* @param obj pointer to an object
* @return pointer to a screen
*/
lv_obj_t * lv_obj_get_scr(lv_obj_t * obj);
```
Always use `/* Something */` format and NOT `//Something`
Write readable code to avoid descriptive comments like:
`x++; /* Add 1 to x */`.
The code should show clearly what you are doing.
You should write **why** have you done this:
`x++; /*Because of closing '\0' of the string */`
Short "code summaries" of a few lines are accepted. E.g. `/*Calculate the new coordinates*/`
In comments use \` \` when referring to a variable. E.g. ``/*Update the value of `x_act`*/``
### Formatting
Here is example to show bracket placing and using of white spaces:
```c
/**
* Set a new text for a label. Memory will be allocated to store the text by the label.
* @param label pointer to a label object
* @param text '\0' terminated character string. NULL to refresh with the current text.
*/
void lv_label_set_text(lv_obj_t * label, const char * text)
{ /* Main brackets of functions in new line*/
if(label == NULL) return; /*No bracket only if the command is inline with the if statement*/
lv_obj_inv(label);
lv_label_ext_t * ext = lv_obj_get_ext(label);
/*Comment before a section */
if(text == ext->txt || text == NULL) { /*Bracket of statements start inline*/
lv_label_refr_text(label);
return;
}
...
}
```
Use 4 spaces indentation instead of tab.
You can use **astyle** to format the code. The required config flies are: `docs/astyle_c` and `docs/astyle_h`.
To format the source files:
`$ find . -type f -name "*.c" | xargs astyle --options=docs/astyle_c`
To format the header files:
`$ find . -type f -name "*.h" | xargs astyle --options=docs/astyle_h`
Append `-n` to the end to skip creation of backup file OR use `$ find . -type f -name "*.bak" -delete` (for source file's backups) and `find . -type f -name "*.orig" -delete` (for header file's backups)
**Welcome! It's glad to see that you are interested in contributing to LittlevGL! There are several types of task where you can help to build a better library! Let's see how to get started!**
There are many different possibilities to join the community. If you have some time to work with us I'm sure you will find something that fits you! You can:
- answer other's questions
- report and/or fix bugs
- suggest and/or implement new features
- improve and/or translate the documentation
- write a blog post about your experiences
But first, start with the most Frequently Asked Questions.
## FAQ about contributing
### Where can I write my question and remarks?
We use [GitHub's issue tracker](https://github.com/littlevgl/lvgl/issues) to ask questions., report bugs and suggest features. But there are some simple rules:
- Be kind and friendly.
- Speak about one thing in one issue.
- Give feedback and close the issue if your question is answered.
- Tell what you experience or expect. _"The button is not working"_ is not enough info to get help.
- If possible send an absolute minimal code example in order to reproduce the issue
- Use [Markdown](https://github.com/adam-p/markdown-here/wiki/Markdown-Cheatsheet) to format your post.
- If you don't get any answer in a week write a comment like "Can somebody help?". Maybe your issue wasn't noticed.
### How can I send fixes and improvements?
Merging new code happens via Pull Requests. If you are still not familiar with the Pull Requests (PR for short) here is a quick guide about them:
1. **Fork** the [lvgl repository](https://github.com/littlevgl/lvgl). To do this click the "Fork" button in the top right corner. It will "copy" the `lvgl` repository to your GitHub account (`https://github.com/your_name?tab=repositories`)
2. **Clone** the forked repository and add your updates
3. **Create a PR** on the GitHub on the page of you `lvgl` repository(`https://github.com/your_name/lvgl`) by hitting the "New pull request" button
4. **Set the base branch**. It means where you want to merge your update. Fixes go to `master`, new features to the actual `dev-x.y` branch.
5. **Describe** what is in the update. An example code is welcome if applicable.
Some advice:
- If you are not sure about your fix or feature it's better to open an issue first, and discuss the details there.
- Maybe your fix or update won't be perfect at first. Don't be afraid, just improve it and push the new commits. The PR will be updated accordingly.
- If your update needs some extra work it's okay to say: _"I'm busy now and I will improve it soon"_ or _"Sorry, I don't have time to improve it, I hope it helps in this form too"_. So it's better to say don't have time to continue then saying nothing.
- Please read and follow this [guide about the coding style](https://doc.littlevgl.com/#Coding-Style-Guide)
### Where is the documentation?
You can read the documentation here: https://doc.littlevgl.com/
You can edit the documentation here: https://github.com/littlevgl/doc
### Where is the blog?
You can read the blog here: https://blog.littlevgl.com/
You can edit the blog here: https://github.com/littlevgl/blog
## So how and where can I contribute?
### Answering other's questions
It's a great way to contribute to the library if you already use it. Just go the [issue tracker](https://github.com/littlevgl/lvgl/issues), read the titles and if you are already familiar with a topic, don't be shy, and write your suggestion.
### Reporting and/or fixing bugs
For simple bugfixes (typos, missing error handling, fixing a warning) is fine to send a Pull request directly. However, for more complex bugs it's better to open an issue first. In the issue, you should describe how to reproduce the bug and even add the minimal code snippet.
### Suggesting and/or implementing new features
If you have a good idea don't hesitate to share with us. It's even better if you have time to deal with its implementation. Don't be afraid if you still don't know LittlevGL well enough. We will help you to get started.
During the implementation don't forget the [Code style guide](https://doc.littlevgl.com/#Coding-Style-Guide).
### Improving and/or translating the documentation
The documentation of LittlevGL is written in Markdown and available [here](https://github.com/littlevgl/doc) for editing. If you find some parts of the documentation obscure or insufficient just search the related `.md` file, hit the edit icon and add your updates. This way a new Pull request will be generated automatically.
If you can devote more time to improve the documentation you can translate it!
1. Just copy the English `.md` files from the root folder to `locale/LANGUAGE_CODE` (language code is e.g. DE, FR, ES etc)
2. Append the language code the end of files (e.g. Welcome_fr.md)
3. Update the filenames in `_Sidebar.md`
4. Translate the page(s) you want
5. Create a Pull request
### Writing a blog post about your experiences
Have ported LittlevGL to a new platform? Have you created a fancy GUI? Do you know a great trick?
You can share your knowledge on LittelvGL's blog! It's super easy to add your own post:
- Fork and clone the [blog repository](https://github.com/littlevgl/blog)
- Add your post in Markdown to the `_posts` folder.
- Store the images and other resources in a dedicated folder in `assets`
- Create a Pull Request
The blog uses [Jekyll](https://jekyllrb.com/) to convert the `.md` files to a webpage. You can easily [run Jekyll offline](https://jekyllrb.com/docs/) to check your post before creating the Pull request
## Summary
I hope you have taken a liking to contribute to LittelvGL. A helpful and friendly community is waiting for you! :)

View File

@ -247,6 +247,12 @@
/*Chart (dependencies: -)*/
#define USE_LV_CHART 1
/*Table (dependencies: lv_label)*/
#define USE_LV_TABLE 1
#if USE_LV_TABLE
#define LV_TABLE_COL_MAX 12
#endif
/*LED (dependencies: -)*/
#define USE_LV_LED 1

View File

@ -204,7 +204,10 @@ void lv_group_focus_next(lv_group_t * group)
if(group->obj_focus == NULL) obj_next = lv_ll_get_head(&group->obj_ll);
else obj_next = lv_ll_get_next(&group->obj_ll, group->obj_focus);
if(obj_next == NULL) obj_next = lv_ll_get_head(&group->obj_ll);
if(obj_next == NULL) {
if(group->wrap) obj_next = lv_ll_get_head(&group->obj_ll);
else obj_next = lv_ll_get_tail(&group->obj_ll);
}
group->obj_focus = obj_next;
if(group->obj_focus) {
@ -232,7 +235,10 @@ void lv_group_focus_prev(lv_group_t * group)
if(group->obj_focus == NULL) obj_next = lv_ll_get_tail(&group->obj_ll);
else obj_next = lv_ll_get_prev(&group->obj_ll, group->obj_focus);
if(obj_next == NULL) obj_next = lv_ll_get_tail(&group->obj_ll);
if(obj_next == NULL) {
if(group->wrap) obj_next = lv_ll_get_tail(&group->obj_ll);
else obj_next = lv_ll_get_head(&group->obj_ll);
}
group->obj_focus = obj_next;
if(group->obj_focus != NULL) {
@ -334,10 +340,26 @@ void lv_group_set_refocus_policy(lv_group_t * group, lv_group_refocus_policy_t p
}
static void lv_group_refocus(lv_group_t *g) {
if(g->refocus_policy == LV_GROUP_REFOCUS_POLICY_NEXT)
lv_group_focus_next(g);
else if(g->refocus_policy == LV_GROUP_REFOCUS_POLICY_PREV)
lv_group_focus_prev(g);
/*Refocus must temporarily allow wrapping to work correctly*/
uint8_t temp_wrap = g->wrap;
g->wrap = 1;
if(g->refocus_policy == LV_GROUP_REFOCUS_POLICY_NEXT)
lv_group_focus_next(g);
else if(g->refocus_policy == LV_GROUP_REFOCUS_POLICY_PREV)
lv_group_focus_prev(g);
/*Restore wrap property*/
g->wrap = temp_wrap;
}
/**
* Set whether focus next/prev will allow wrapping from first->last or last->first.
* @param group pointer to group
* @param en: true: enable `click_focus`
*/
void lv_group_set_wrap(lv_group_t * group, bool en)
{
group->wrap = en ? 1 : 0;
}
/**
@ -428,6 +450,17 @@ bool lv_group_get_click_focus(const lv_group_t * group)
return group->click_focus ? true : false;
}
/**
* Get whether focus next/prev will allow wrapping from first->last or last->first object.
* @param group pointer to group
* @param en: true: wrapping enabled; false: wrapping disabled
*/
bool lv_group_get_wrap(lv_group_t * group)
{
if(!group) return false;
return group->wrap ? true : false;
}
/**********************
* STATIC FUNCTIONS
**********************/

View File

@ -58,6 +58,7 @@ typedef struct _lv_group_t
uint8_t editing :1; /*1: Edit mode, 0: Navigate mode*/
uint8_t click_focus :1; /*1: If an object in a group is clicked by an indev then it will be focused */
uint8_t refocus_policy :1; /*1: Focus prev if focused on deletion. 0: Focus prev if focused on deletion.*/
uint8_t wrap :1; /*1: Focus next/prev can wrap at end of list. 0: Focus next/prev stops at end of list.*/
} lv_group_t;
typedef enum _lv_group_refocus_policy_t {
@ -168,6 +169,13 @@ void lv_group_set_editing(lv_group_t * group, bool edit);
*/
void lv_group_set_click_focus(lv_group_t * group, bool en);
/**
* Set whether focus next/prev will allow wrapping from first->last or last->first object.
* @param group pointer to group
* @param en: true: wrapping enabled; false: wrapping disabled
*/
void lv_group_set_wrap(lv_group_t * group, bool en);
/**
* Modify a style with the set 'style_mod' function. The input style remains unchanged.
* @param group pointer to group
@ -218,6 +226,12 @@ bool lv_group_get_editing(const lv_group_t * group);
*/
bool lv_group_get_click_focus(const lv_group_t * group);
/**
* Get whether focus next/prev will allow wrapping from first->last or last->first object.
* @param group pointer to group
* @param en: true: wrapping enabled; false: wrapping disabled
*/
bool lv_group_get_wrap(lv_group_t * group);
/**********************
* MACROS

View File

@ -136,7 +136,7 @@ void lv_indev_enable(lv_hal_indev_type_t type, bool enable)
*/
void lv_indev_set_cursor(lv_indev_t * indev, lv_obj_t * cur_obj)
{
if(indev->driver.type != LV_INDEV_TYPE_POINTER && indev->driver.type != LV_INDEV_TYPE_BUTTON) return;
if(indev->driver.type != LV_INDEV_TYPE_POINTER) return;
indev->cursor = cur_obj;
lv_obj_set_parent(indev->cursor, lv_layer_sys());
@ -368,6 +368,10 @@ static void indev_keypad_proc(lv_indev_t * i, lv_indev_data_t * data)
if(data->state == LV_INDEV_STATE_PR &&
i->proc.last_state == LV_INDEV_STATE_REL) {
i->proc.pr_timestamp = lv_tick_get();
lv_obj_t * focused = lv_group_get_focused(i->group);
if(focused && data->key == LV_GROUP_KEY_ENTER) {
focused->signal_func(focused, LV_SIGNAL_PRESSED, indev_act);
}
}
/*Pressing*/
else if(data->state == LV_INDEV_STATE_PR && i->proc.last_state == LV_INDEV_STATE_PR) {

View File

@ -514,7 +514,6 @@ static void lv_refr_obj(lv_obj_t * obj, const lv_area_t * mask_ori_p)
if(union_ok != false) {
/* Redraw the object */
lv_style_t * style = lv_obj_get_style(obj);
obj->design_func(obj, &obj_ext_mask, LV_DESIGN_DRAW_MAIN);
//tick_wait_ms(100); /*DEBUG: Wait after every object draw to see the order of drawing*/

View File

@ -115,6 +115,8 @@ void lv_draw_label(const lv_area_t * coords, const lv_area_t * mask, const lv_st
lv_rletter_set_background(style->body.main_color);
#endif
lv_coord_t line_height = lv_font_get_height(font) + style->text.line_space;
/*Write out all lines*/
while(txt[line_start] != '\0') {
if(offset != NULL) {
@ -126,6 +128,9 @@ void lv_draw_label(const lv_area_t * coords, const lv_area_t * mask, const lv_st
uint32_t letter;
while(i < line_end) {
letter = lv_txt_encoded_next(txt, &i);
if(pos.y + line_height < mask->y1) continue;
/*Handle the re-color command*/
if((flag & LV_TXT_FLAG_RECOLOR) != 0) {
if(letter == (uint32_t)LV_TXT_COLOR_CMD[0]) {
@ -193,8 +198,9 @@ void lv_draw_label(const lv_area_t * coords, const lv_area_t * mask, const lv_st
}
/*Go the next line position*/
pos.y += lv_font_get_height(font);
pos.y += style->text.line_space;
pos.y += line_height;
if(pos.y > mask->y2) return;
}
}

View File

@ -73,7 +73,7 @@ static bool line_next_x(line_draw_t * line);
* @param opa_scale scale down all opacities by the factor
*/
void lv_draw_line(const lv_point_t * point1, const lv_point_t * point2, const lv_area_t * mask,
const lv_style_t * style, lv_opa_t opa_scale)
const lv_style_t * style, lv_opa_t opa_scale)
{
if(style->line.width == 0) return;
@ -279,16 +279,12 @@ static void line_draw_skew(line_draw_t * main_line, bool dir_ori, const lv_area_
width = i;
#if LV_ANTIALIAS
width--;
#endif
break;
}
line_next(&pattern_line);
}
} else {
pattern[0].x = 0;
pattern[0].y = 0;
}
#if LV_ANTIALIAS
@ -299,12 +295,22 @@ static void line_draw_skew(line_draw_t * main_line, bool dir_ori, const lv_area_
aa_last_corner = 0;
#endif
lv_coord_t x_center_ofs = 0;
lv_coord_t y_center_ofs = 0;
if(width != 0) {
x_center_ofs = pattern[width - 1].x / 2;
y_center_ofs = pattern[width - 1].y / 2;
}
else {
if(main_line->hor && main_line->p1.y >= main_line->p2.y + dir_ori) pattern[0].y --;
if(!main_line->hor && main_line->p1.x >= main_line->p2.x + dir_ori) pattern[0].x --;
}
/* Make the coordinates relative to the center */
for(i = 0; i < width; i++) {
pattern[i].x -= pattern[width - 1].x / 2;
pattern[i].y -= pattern[width - 1].y / 2;
pattern[i].x -= x_center_ofs;
pattern[i].y -= y_center_ofs;
#if LV_ANTIALIAS
if(i != 0) {
if(main_line->hor) {
@ -312,16 +318,16 @@ static void line_draw_skew(line_draw_t * main_line, bool dir_ori, const lv_area_
lv_coord_t seg_w = pattern[i].y - pattern[aa_last_corner].y;
if(main_line->sy < 0) {
lv_draw_aa_ver_seg(main_line->p1.x + pattern[aa_last_corner].x - 1, main_line->p1.y + pattern[aa_last_corner].y + seg_w + 1,
seg_w, mask, style->line.color, opa);
seg_w, mask, style->line.color, opa);
lv_draw_aa_ver_seg(main_line->p2.x + pattern[aa_last_corner].x + 1, main_line->p2.y + pattern[aa_last_corner].y + seg_w + 1,
-seg_w, mask, style->line.color, opa);
-seg_w, mask, style->line.color, opa);
} else {
lv_draw_aa_ver_seg(main_line->p1.x + pattern[aa_last_corner].x - 1, main_line->p1.y + pattern[aa_last_corner].y,
seg_w, mask, style->line.color, opa);
seg_w, mask, style->line.color, opa);
lv_draw_aa_ver_seg(main_line->p2.x + pattern[aa_last_corner].x + 1, main_line->p2.y + pattern[aa_last_corner].y,
-seg_w, mask, style->line.color, opa);
-seg_w, mask, style->line.color, opa);
}
aa_last_corner = i;
}
@ -330,16 +336,16 @@ static void line_draw_skew(line_draw_t * main_line, bool dir_ori, const lv_area_
lv_coord_t seg_w = pattern[i].x - pattern[aa_last_corner].x;
if(main_line->sx < 0) {
lv_draw_aa_hor_seg(main_line->p1.x + pattern[aa_last_corner].x + seg_w + 1, main_line->p1.y + pattern[aa_last_corner].y - 1,
seg_w, mask, style->line.color, opa);
seg_w, mask, style->line.color, opa);
lv_draw_aa_hor_seg(main_line->p2.x + pattern[aa_last_corner].x + seg_w + 1, main_line->p2.y + pattern[aa_last_corner].y + 1,
-seg_w, mask, style->line.color, opa);
-seg_w, mask, style->line.color, opa);
} else {
lv_draw_aa_hor_seg(main_line->p1.x + pattern[aa_last_corner].x, main_line->p1.y + pattern[aa_last_corner].y - 1,
seg_w, mask, style->line.color, opa);
seg_w, mask, style->line.color, opa);
lv_draw_aa_hor_seg(main_line->p2.x + pattern[aa_last_corner].x, main_line->p2.y + pattern[aa_last_corner].y + 1,
-seg_w, mask, style->line.color, opa);
-seg_w, mask, style->line.color, opa);
}
aa_last_corner = i;
}
@ -358,33 +364,33 @@ static void line_draw_skew(line_draw_t * main_line, bool dir_ori, const lv_area_
lv_coord_t seg_w = pattern[width_safe - 1].y - pattern[aa_last_corner].y;
if(main_line->sy < 0) {
lv_draw_aa_ver_seg(main_line->p1.x + pattern[aa_last_corner].x - 1, main_line->p1.y + pattern[aa_last_corner].y + seg_w,
seg_w + main_line->sy, mask, style->line.color, opa);
seg_w + main_line->sy, mask, style->line.color, opa);
lv_draw_aa_ver_seg(main_line->p2.x + pattern[aa_last_corner].x + 1, main_line->p2.y + pattern[aa_last_corner].y + seg_w,
-(seg_w + main_line->sy), mask, style->line.color, opa);
-(seg_w + main_line->sy), mask, style->line.color, opa);
} else {
lv_draw_aa_ver_seg(main_line->p1.x + pattern[aa_last_corner].x - 1, main_line->p1.y + pattern[aa_last_corner].y,
seg_w + main_line->sy, mask, style->line.color, opa);
seg_w + main_line->sy, mask, style->line.color, opa);
lv_draw_aa_ver_seg(main_line->p2.x + pattern[aa_last_corner].x + 1, main_line->p2.y + pattern[aa_last_corner].y,
-(seg_w + main_line->sy), mask, style->line.color, opa);
-(seg_w + main_line->sy), mask, style->line.color, opa);
}
} else {
lv_coord_t seg_w = pattern[width_safe - 1].x - pattern[aa_last_corner].x;
if(main_line->sx < 0) {
lv_draw_aa_hor_seg(main_line->p1.x + pattern[aa_last_corner].x + seg_w, main_line->p1.y + pattern[aa_last_corner].y - 1,
seg_w + main_line->sx, mask, style->line.color, opa);
seg_w + main_line->sx, mask, style->line.color, opa);
lv_draw_aa_hor_seg(main_line->p2.x + pattern[aa_last_corner].x + seg_w, main_line->p2.y + pattern[aa_last_corner].y + 1,
-(seg_w + main_line->sx), mask, style->line.color, opa);
-(seg_w + main_line->sx), mask, style->line.color, opa);
} else {
lv_draw_aa_hor_seg(main_line->p1.x + pattern[aa_last_corner].x, main_line->p1.y + pattern[aa_last_corner].y - 1,
seg_w + main_line->sx, mask, style->line.color, opa);
seg_w + main_line->sx, mask, style->line.color, opa);
lv_draw_aa_hor_seg(main_line->p2.x + pattern[aa_last_corner].x, main_line->p2.y + pattern[aa_last_corner].y + 1,
-(seg_w + main_line->sx), mask, style->line.color, opa);
-(seg_w + main_line->sx), mask, style->line.color, opa);
}
}
@ -441,9 +447,9 @@ static void line_draw_skew(line_draw_t * main_line, bool dir_ori, const lv_area_
#if LV_ANTIALIAS
lv_draw_aa_hor_seg(prev_p.x + pattern[0].x, prev_p.y + pattern[0].y - aa_shift1,
-(main_line->p_act.x - prev_p.x), mask, style->line.color, opa);
-(main_line->p_act.x - prev_p.x), mask, style->line.color, opa);
lv_draw_aa_hor_seg(prev_p.x + pattern[width_safe - 1].x, prev_p.y + pattern[width_safe - 1].y + aa_shift2,
main_line->p_act.x - prev_p.x, mask, style->line.color, opa);
main_line->p_act.x - prev_p.x, mask, style->line.color, opa);
#endif
first_run = false;
@ -468,9 +474,9 @@ static void line_draw_skew(line_draw_t * main_line, bool dir_ori, const lv_area_
#if LV_ANTIALIAS
lv_draw_aa_hor_seg(prev_p.x + pattern[0].x, prev_p.y + pattern[0].y - aa_shift1,
-(main_line->p_act.x - prev_p.x + 1), mask, style->line.color, opa);
-(main_line->p_act.x - prev_p.x + 1), mask, style->line.color, opa);
lv_draw_aa_hor_seg(prev_p.x + pattern[width_safe - 1].x, prev_p.y + pattern[width_safe - 1].y + aa_shift2,
main_line->p_act.x - prev_p.x + 1, mask, style->line.color, opa);
main_line->p_act.x - prev_p.x + 1, mask, style->line.color, opa);
#endif
}
/*Rather a vertical line*/
@ -495,9 +501,9 @@ static void line_draw_skew(line_draw_t * main_line, bool dir_ori, const lv_area_
#if LV_ANTIALIAS
lv_draw_aa_ver_seg(prev_p.x + pattern[0].x - aa_shift1, prev_p.y + pattern[0].y,
-(main_line->p_act.y - prev_p.y), mask, style->line.color, opa);
-(main_line->p_act.y - prev_p.y), mask, style->line.color, opa);
lv_draw_aa_ver_seg(prev_p.x + pattern[width_safe - 1].x + aa_shift2, prev_p.y + pattern[width_safe - 1].y,
main_line->p_act.y - prev_p.y, mask, style->line.color, opa);
main_line->p_act.y - prev_p.y, mask, style->line.color, opa);
#endif
first_run = false;
@ -524,9 +530,9 @@ static void line_draw_skew(line_draw_t * main_line, bool dir_ori, const lv_area_
#if LV_ANTIALIAS
lv_draw_aa_ver_seg(prev_p.x + pattern[0].x - aa_shift1, prev_p.y + pattern[0].y,
-(main_line->p_act.y - prev_p.y + 1), mask, style->line.color, opa);
-(main_line->p_act.y - prev_p.y + 1), mask, style->line.color, opa);
lv_draw_aa_ver_seg(prev_p.x + pattern[width_safe - 1].x + aa_shift2, prev_p.y + pattern[width_safe - 1].y,
main_line->p_act.y - prev_p.y + 1, mask, style->line.color, opa);
main_line->p_act.y - prev_p.y + 1, mask, style->line.color, opa);
#endif
}
}

View File

@ -47,10 +47,9 @@ void lv_font_init(void)
}
/**
* Create a pair from font name and font dsc. get function. After it 'font_get' can be used for this font
* @param name name of the font
* @param dsc_get_fp the font descriptor get function
* @param parent add this font as charter set extension of 'parent'
* Add a font to an other to extend the character set.
* @param child the font to add
* @param parent this font will be extended. Using it later will contain the characters from `child`
*/
void lv_font_add(lv_font_t * child, lv_font_t * parent)
{
@ -64,6 +63,24 @@ void lv_font_add(lv_font_t * child, lv_font_t * parent)
}
/**
* Remove a font from a character set.
* @param child the font to remove
* @param parent remove `child` from here
*/
void lv_font_remove(lv_font_t * child, lv_font_t * parent)
{
if(parent == NULL) return;
if(child == NULL) return;
while(parent->next_page != child) {
parent = parent->next_page; /*Got to the last page and add the new font there*/
}
parent->next_page = child->next_page;
}
/**
* Tells if font which contains `letter` is monospace or not
* @param font_p point to font

View File

@ -72,12 +72,19 @@ typedef struct _lv_font_struct
void lv_font_init(void);
/**
* Create a pair from font name and font dsc. get function. After it 'font_get' can be used for this font
* @param child pointer to a font to join to the 'parent'
* @param parent pointer to a font. 'child' will be joined here
* Add a font to an other to extend the character set.
* @param child the font to add
* @param parent this font will be extended. Using it later will contain the characters from `child`
*/
void lv_font_add(lv_font_t *child, lv_font_t *parent);
/**
* Remove a font from a character set.
* @param child the font to remove
* @param parent remove `child` from here
*/
void lv_font_remove(lv_font_t * child, lv_font_t * parent);
/**
* Tells if font which contains `letter` is monospace or not
* @param font_p point to font

View File

@ -674,10 +674,11 @@ static lv_res_t lv_btn_signal(lv_obj_t * btn, lv_signal_t sign, void * param)
} else if(c == LV_GROUP_KEY_ENTER) {
if(!ext->long_pr_action_executed) {
if(lv_btn_get_toggle(btn)) {
if(state == LV_BTN_STATE_REL) lv_btn_set_state(btn, LV_BTN_STATE_TGL_REL);
else if(state == LV_BTN_STATE_PR) lv_btn_set_state(btn, LV_BTN_STATE_TGL_PR);
else if(state == LV_BTN_STATE_TGL_REL) lv_btn_set_state(btn, LV_BTN_STATE_REL);
else if(state == LV_BTN_STATE_TGL_PR) lv_btn_set_state(btn, LV_BTN_STATE_PR);
if(state == LV_BTN_STATE_REL || state == LV_BTN_STATE_PR) lv_btn_set_state(btn, LV_BTN_STATE_TGL_REL);
else if(state == LV_BTN_STATE_TGL_REL || state == LV_BTN_STATE_TGL_PR) lv_btn_set_state(btn, LV_BTN_STATE_REL);
} else {
if(state == LV_BTN_STATE_REL || state == LV_BTN_STATE_PR) lv_btn_set_state(btn, LV_BTN_STATE_REL);
else if(state == LV_BTN_STATE_TGL_REL || state == LV_BTN_STATE_TGL_PR) lv_btn_set_state(btn, LV_BTN_STATE_TGL_REL);
}
if(ext->actions[LV_BTN_ACTION_CLICK] && state != LV_BTN_STATE_INA) {
res = ext->actions[LV_BTN_ACTION_CLICK](btn);

View File

@ -314,6 +314,14 @@ void lv_btnm_set_style(lv_obj_t * btnm, lv_btnm_style_t type, lv_style_t * style
}
}
void lv_btnm_set_recolor(const lv_obj_t * btnm, bool en)
{
lv_btnm_ext_t * ext = lv_obj_get_ext_attr(btnm);
ext->recolor = en;
lv_obj_invalidate(btnm);
}
/*=====================
* Getter functions
*====================*/
@ -402,6 +410,13 @@ lv_style_t * lv_btnm_get_style(const lv_obj_t * btnm, lv_btnm_style_t type)
return style;
}
bool lv_btnm_get_recolor(const lv_obj_t * btnm)
{
lv_btnm_ext_t * ext = lv_obj_get_ext_attr(btnm);
return ext->recolor;
}
/**********************
* STATIC FUNCTIONS
**********************/
@ -424,6 +439,7 @@ static bool lv_btnm_design(lv_obj_t * btnm, const lv_area_t * mask, lv_design_mo
}
/*Draw the object*/
else if(mode == LV_DESIGN_DRAW_MAIN) {
ancestor_design_f(btnm, mask, mode);
lv_btnm_ext_t * ext = lv_obj_get_ext_attr(btnm);
@ -437,10 +453,15 @@ static bool lv_btnm_design(lv_obj_t * btnm, const lv_area_t * mask, lv_design_mo
lv_area_t area_tmp;
lv_coord_t btn_w;
lv_coord_t btn_h;
bool border_mod = false;
uint16_t btn_i = 0;
uint16_t txt_i = 0;
lv_txt_flag_t txt_flag = LV_TXT_FLAG_NONE;
if(ext->recolor)
txt_flag = LV_TXT_FLAG_RECOLOR;
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 ++;
@ -465,36 +486,22 @@ static bool lv_btnm_design(lv_obj_t * btnm, const lv_area_t * mask, lv_design_mo
else if(btn_i == ext->btn_id_pr && btn_i == ext->btn_id_tgl) btn_style = lv_btnm_get_style(btnm, LV_BTNM_STYLE_BTN_TGL_PR);
else btn_style = lv_btnm_get_style(btnm, LV_BTNM_STYLE_BTN_REL); /*Not possible option, just to be sure*/
/*On the right buttons clear the border if only right borders are drawn*/
if(ext->map_p[txt_i + 1][0] == '\0' || ext->map_p[txt_i + 1][0] == '\n') {
if(btn_style->body.border.part == LV_BORDER_RIGHT) {
btn_style->body.border.part = LV_BORDER_NONE;
border_mod = true;
}
}
lv_draw_rect(&area_tmp, mask, btn_style, opa_scale);
if(border_mod) {
border_mod = false;
btn_style->body.border.part = LV_BORDER_RIGHT;
}
/*Calculate the size of the text*/
if(btn_style->glass) btn_style = bg_style;
const lv_font_t * font = btn_style->text.font;
lv_point_t txt_size;
lv_txt_get_size(&txt_size, ext->map_p[txt_i], font,
btn_style->text.letter_space, btn_style->text.line_space,
lv_area_get_width(&area_btnm), LV_TXT_FLAG_NONE);
lv_area_get_width(&area_btnm), txt_flag);
area_tmp.x1 += (btn_w - txt_size.x) / 2;
area_tmp.y1 += (btn_h - txt_size.y) / 2;
area_tmp.x2 = area_tmp.x1 + txt_size.x;
area_tmp.y2 = area_tmp.y1 + txt_size.y;
lv_draw_label(&area_tmp, mask, btn_style, opa_scale, ext->map_p[txt_i], LV_TXT_FLAG_NONE, NULL);
lv_draw_label(&area_tmp, mask, btn_style, opa_scale, ext->map_p[txt_i], txt_flag, NULL);
}
}
return true;

View File

@ -62,6 +62,7 @@ typedef struct
uint16_t btn_id_pr; /*Index of the currently pressed button (in `button_areas`) or LV_BTNM_PR_NONE*/
uint16_t btn_id_tgl; /*Index of the currently toggled button (in `button_areas`) or LV_BTNM_PR_NONE */
uint8_t toggle :1; /*Enable toggling*/
uint8_t recolor :1; /*Enable button recoloring*/
} lv_btnm_ext_t;
enum {
@ -129,6 +130,13 @@ void lv_btnm_set_toggle(lv_obj_t * btnm, bool en, uint16_t id);
*/
void lv_btnm_set_style(lv_obj_t *btnm, lv_btnm_style_t type, lv_style_t *style);
/**
* Set whether recoloring is enabled
* @param btnm pointer to button matrix object
* @param en whether recoloring is enabled
*/
void lv_btnm_set_recolor(const lv_obj_t * btnm, bool en);
/*=====================
* Getter functions
*====================*/
@ -169,6 +177,13 @@ uint16_t lv_btnm_get_toggled(const lv_obj_t * btnm);
*/
lv_style_t * lv_btnm_get_style(const lv_obj_t *btnm, lv_btnm_style_t type);
/**
* Find whether recoloring is enabled
* @param btnm pointer to button matrix object
* @return whether recoloring is enabled
*/
bool lv_btnm_get_recolor(const lv_obj_t * btnm);
/**********************
* MACROS
**********************/

View File

@ -731,7 +731,6 @@ static void lv_chart_draw_cols(lv_obj_t * chart, const lv_area_t * mask)
col_a.y2 = chart->coords.y2;
lv_coord_t x_act;
printf("\n", y_tmp);
/*Go through all points*/
for(i = 0; i < ext->point_cnt; i ++) {
@ -749,7 +748,6 @@ static void lv_chart_draw_cols(lv_obj_t * chart, const lv_area_t * mask)
lv_coord_t p_act = (ser->start_point + i) % ext->point_cnt;
y_tmp = (int32_t)((int32_t) ser->points[p_act] - ext->ymin) * h;
y_tmp = y_tmp / (ext->ymax - ext->ymin);
printf("ytmp:%d\n", y_tmp);
col_a.y1 = h - y_tmp + chart->coords.y1;
mask_ret = lv_area_intersect(&col_mask, mask, &col_a);

View File

@ -287,6 +287,12 @@ void lv_ddlist_set_style(lv_obj_t * ddlist, lv_ddlist_style_t type, lv_style_t *
}
}
void lv_ddlist_set_align(lv_obj_t *ddlist, lv_label_align_t align)
{
lv_ddlist_ext_t * ext = lv_obj_get_ext_attr(ddlist);
lv_label_set_align(ext->label, align);
}
/*=====================
* Getter functions
*====================*/
@ -407,6 +413,14 @@ lv_style_t * lv_ddlist_get_style(const lv_obj_t * ddlist, lv_ddlist_style_t type
/*To avoid warning*/
return NULL;
}
lv_label_align_t lv_ddlist_get_align(const lv_obj_t *ddlist)
{
lv_ddlist_ext_t * ext = lv_obj_get_ext_attr(ddlist);
return lv_label_get_align(ext->label);
}
/*=====================
* Other functions
*====================*/
@ -447,6 +461,32 @@ void lv_ddlist_close(lv_obj_t * ddlist, bool anim_en)
* STATIC FUNCTIONS
**********************/
/**
* Get the text alignment flag for a drop down list.
* @param ddlist drop down list
* @return text alignment flag
*/
static lv_txt_flag_t lv_ddlist_get_txt_flag(const lv_obj_t *ddlist)
{
lv_ddlist_ext_t * ext = lv_obj_get_ext_attr(ddlist);
/*The label might be already deleted so just return with some value*/
if(!ext->label) return LV_TXT_FLAG_CENTER;
lv_label_align_t align = lv_label_get_align(ext->label);
switch(align)
{
default:
case LV_LABEL_ALIGN_LEFT:
return LV_TXT_FLAG_NONE;
case LV_LABEL_ALIGN_CENTER:
return LV_TXT_FLAG_CENTER;
case LV_LABEL_ALIGN_RIGHT:
return LV_TXT_FLAG_RIGHT;
}
}
/**
* Handle the drawing related tasks of the drop down lists
* @param ddlist pointer to an object
@ -517,8 +557,9 @@ static bool lv_ddlist_design(lv_obj_t * ddlist, const lv_area_t * mask, lv_desig
lv_style_copy(&new_style, style);
new_style.text.color = sel_style->text.color;
new_style.text.opa = sel_style->text.opa;
lv_txt_flag_t flag = lv_ddlist_get_txt_flag(ddlist);
lv_draw_label(&ext->label->coords, &mask_sel, &new_style, opa_scale,
lv_label_get_text(ext->label), LV_TXT_FLAG_NONE, NULL);
lv_label_get_text(ext->label), flag, NULL);
}
}

View File

@ -150,6 +150,13 @@ void lv_ddlist_set_anim_time(lv_obj_t * ddlist, uint16_t anim_time);
* */
void lv_ddlist_set_style(lv_obj_t *ddlist, lv_ddlist_style_t type, lv_style_t *style);
/**
* Set the alignment of the labels in a drop down list
* @param ddlist pointer to a drop down list object
* @param align alignment of labels
*/
void lv_ddlist_set_align(lv_obj_t *ddlist, lv_label_align_t align);
/*=====================
* Getter functions
*====================*/
@ -220,6 +227,13 @@ uint16_t lv_ddlist_get_anim_time(const lv_obj_t * ddlist);
*/
lv_style_t * lv_ddlist_get_style(const lv_obj_t *ddlist, lv_ddlist_style_t type);
/**
* Get the alignment of the labels in a drop down list
* @param ddlist pointer to a drop down list object
* @return alignment of labels
*/
lv_label_align_t lv_ddlist_get_align(const lv_obj_t *ddlist);
/*=====================
* Other functions
*====================*/

View File

@ -81,10 +81,11 @@ lv_obj_t * lv_imgbtn_create(lv_obj_t * par, const lv_obj_t * copy)
}
/*Copy an existing image button*/
else {
lv_imgbtn_ext_t * copy_ext = lv_obj_get_ext_attr(copy);
#if LV_IMGBTN_TILED == 0
memset(ext->img_src, 0, sizeof(ext->img_src));
#else
lv_imgbtn_ext_t * copy_ext = lv_obj_get_ext_attr(copy);
memcpy(ext->img_src_left, copy_ext->img_src_left, sizeof(ext->img_src_left));
memcpy(ext->img_src_mid, copy_ext->img_src_mid, sizeof(ext->img_src_mid));
memcpy(ext->img_src_right, copy_ext->img_src_right, sizeof(ext->img_src_right));
@ -163,7 +164,7 @@ void lv_imgbtn_set_style(lv_obj_t * imgbtn, lv_imgbtn_style_t type, lv_style_t *
*/
const void * lv_imgbtn_get_src(lv_obj_t * imgbtn, lv_btn_state_t state)
{
lv_imgbtn_ext_t * ext = lv_obj_get_ext_attr(imgbtn);
// lv_imgbtn_ext_t * ext = lv_obj_get_ext_attr(imgbtn);
return NULL;//ext->img_src[state];
}

View File

@ -419,13 +419,14 @@ static lv_res_t lv_kb_def_action(lv_obj_t * kb, const char * txt)
lv_kb_set_ta(kb, NULL); /*De-assign the text area to hide it cursor if needed*/
lv_obj_del(kb);
}
return LV_RES_INV;
return res;
} else if(strcmp(txt, SYMBOL_OK) == 0) {
if(ext->ok_action) res = ext->ok_action(kb);
else {
lv_kb_set_ta(kb, NULL); /*De-assign the text area to hide it cursor if needed*/
res = lv_obj_del(kb);
}
return res;
}
if(res != LV_RES_OK) return res; /*The keyboard might be deleted in the actions*/

View File

@ -787,7 +787,7 @@ static void lv_label_refr_text(lv_obj_t * label)
anim.var = label;
anim.repeat = 1;
anim.playback = 1;
anim.start = lv_font_get_width(font, ' ');
anim.start = 0;
anim.act_time = 0;
anim.end_cb = NULL;
anim.path = lv_anim_path_linear;
@ -797,7 +797,7 @@ static void lv_label_refr_text(lv_obj_t * label)
anim.repeat_pause = anim.playback_pause;
if(lv_obj_get_width(label) > lv_obj_get_width(parent)) {
anim.end = lv_obj_get_width(parent) - lv_obj_get_width(label) - lv_font_get_width(font, ' ');
anim.end = lv_obj_get_width(parent) - lv_obj_get_width(label);
anim.fp = (lv_anim_fp_t) lv_obj_set_x;
anim.time = lv_anim_speed_to_time(ext->anim_speed, anim.start, anim.end);
lv_anim_create(&anim);
@ -817,7 +817,7 @@ static void lv_label_refr_text(lv_obj_t * label)
anim.var = label;
anim.repeat = 1;
anim.playback = 1;
anim.start = lv_font_get_width(font, ' ');
anim.start = 0;
anim.act_time = 0;
anim.end_cb = NULL;
anim.path = lv_anim_path_linear;
@ -826,7 +826,7 @@ static void lv_label_refr_text(lv_obj_t * label)
bool hor_anim = false;
if(size.x > lv_obj_get_width(label)) {
anim.end = lv_obj_get_width(label) - size.x - lv_font_get_width(font, ' ');
anim.end = lv_obj_get_width(label) - size.x;
anim.fp = (lv_anim_fp_t) lv_label_set_offset_x;
anim.time = lv_anim_speed_to_time(ext->anim_speed, anim.start, anim.end);
lv_anim_create(&anim);

View File

@ -38,6 +38,7 @@
static lv_res_t lv_list_signal(lv_obj_t * list, lv_signal_t sign, void * param);
static lv_res_t lv_list_btn_signal(lv_obj_t * btn, lv_signal_t sign, void * param);
static void refr_btn_width(lv_obj_t * list);
static void lv_list_btn_single_selected(lv_obj_t *btn);
/**********************
* STATIC VARIABLES
@ -89,6 +90,8 @@ lv_obj_t * lv_list_create(lv_obj_t * par, const lv_obj_t * copy)
ext->styles_btn[LV_BTN_STATE_TGL_PR] = &lv_style_btn_tgl_pr;
ext->styles_btn[LV_BTN_STATE_INA] = &lv_style_btn_ina;
ext->anim_time = LV_LIST_FOCUS_TIME;
ext->single_mode = false;
#if USE_LV_GROUP
ext->last_sel = NULL;
ext->selected_btn = NULL;
@ -216,11 +219,12 @@ lv_obj_t * lv_list_add(lv_obj_t * list, const void * img_src, const char * txt,
}
#endif
if(txt != NULL) {
lv_coord_t btn_hor_pad = ext->styles_btn[LV_BTN_STYLE_REL]->body.padding.hor;
lv_obj_t * label = lv_label_create(liste, NULL);
lv_label_set_text(label, txt);
lv_obj_set_click(label, false);
lv_label_set_long_mode(label, LV_LABEL_LONG_ROLL);
lv_obj_set_width(label, liste->coords.x2 - label->coords.x1);
lv_obj_set_width(label, liste->coords.x2 - label->coords.x1 - btn_hor_pad);
if(label_signal == NULL) label_signal = lv_obj_get_signal_func(label);
}
@ -255,6 +259,18 @@ bool lv_list_remove(const lv_obj_t * list, uint32_t index)
* Setter functions
*====================*/
/**
* Set single button selected mode, only one button will be selected if enabled.
* @param list pointer to the currently pressed list object
* @param mode, enable(true)/disable(false) single selected mode.
*/
void lv_list_set_single_mode(lv_obj_t *list, bool mode)
{
lv_list_ext_t * ext = lv_obj_get_ext_attr(list);
ext->single_mode = mode;
}
#if USE_LV_GROUP
/**
@ -367,6 +383,17 @@ void lv_list_set_style(lv_obj_t * list, lv_list_style_t type, lv_style_t * style
* Getter functions
*====================*/
/**
* Get single button selected mode.
* @param list pointer to the currently pressed list object.
*/
bool lv_list_get_single_mode(lv_obj_t *list)
{
lv_list_ext_t * ext = lv_obj_get_ext_attr(list);
return (ext->single_mode);
}
/**
* Get the text of a list element
* @param btn pointer to list element
@ -420,10 +447,10 @@ lv_obj_t * lv_list_get_btn_img(const lv_obj_t * btn)
}
/**
* Get the next button from list. (Starts from the bottom button)
* Get the previous button from list. (Starts from the top button)
* @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 when no more buttons
* @param prev_btn pointer to button. Search the previous before it.
* @return pointer to the previous button or NULL when no more buttons
*/
lv_obj_t * lv_list_get_prev_btn(const lv_obj_t * list, lv_obj_t * prev_btn)
{
@ -445,11 +472,12 @@ lv_obj_t * lv_list_get_prev_btn(const lv_obj_t * list, lv_obj_t * prev_btn)
}
/**
* Get the previous button from list. (Starts from the top button)
/**
* Get the next button from list. (Starts from the bottom button)
* @param list pointer to a list object
* @param prev_btn pointer to button. Search the previous before it.
* @return pointer to the previous button or NULL when no more buttons
* @param prev_btn pointer to button. Search the next after it.
* @return pointer to the next button or NULL when no more buttons
*/
lv_obj_t * lv_list_get_next_btn(const lv_obj_t * list, lv_obj_t * prev_btn)
{
@ -858,7 +886,10 @@ static lv_res_t lv_list_btn_signal(lv_obj_t * btn, lv_signal_t sign, void * para
* to mark it as selected (pressed state)*/
last_clicked_btn = btn;
#endif
if(lv_indev_is_dragging(lv_indev_get_act()) == false && ext->single_mode)
{
lv_list_btn_single_selected(btn);
}
}
else if(sign == LV_SIGNAL_PRESS_LOST) {
lv_obj_t * list = lv_obj_get_parent(lv_obj_get_parent(btn));
@ -899,5 +930,27 @@ static void refr_btn_width(lv_obj_t * list)
}
}
/**
* Make a single button selected in the list, deselect others, should be called in list btns call back.
* @param btn pointer to the currently pressed list btn object
*/
static void lv_list_btn_single_selected(lv_obj_t *btn)
{
lv_obj_t *list = lv_obj_get_parent(lv_obj_get_parent(btn));
lv_obj_t * e = lv_list_get_next_btn(list, NULL);
do
{
if(e == btn)
{
lv_btn_set_state(e, LV_BTN_STATE_TGL_REL);
}
else
{
lv_btn_set_state(e, LV_BTN_STATE_REL);
}
e = lv_list_get_next_btn(list, e);
} while (e != NULL);
}
#endif

View File

@ -57,6 +57,7 @@ typedef struct
lv_style_t *styles_btn[LV_BTN_STATE_NUM]; /*Styles of the list element buttons*/
lv_style_t *style_img; /*Style of the list element images on buttons*/
uint32_t size; /*the number of items(buttons) in the list*/
bool single_mode; /* whether single selected mode is enabled */
#if USE_LV_GROUP
lv_obj_t * last_sel; /* Last btn selected */
lv_obj_t * selected_btn;
@ -120,6 +121,14 @@ bool lv_list_remove(const lv_obj_t * list, uint32_t index);
/*=====================
* Setter functions
*====================*/
/**
* Set single button selected mode, only one button will be selected if enabled.
* @param list pointer to the currently pressed list object
* @param mode, enable(true)/disable(false) single selected mode.
*/
void lv_list_set_single_mode(lv_obj_t *list, bool mode);
#if USE_LV_GROUP
/**
@ -179,6 +188,12 @@ void lv_list_set_style(lv_obj_t *list, lv_list_style_t type, lv_style_t *style);
* Getter functions
*====================*/
/**
* Get single button selected mode.
* @param list pointer to the currently pressed list object.
*/
bool lv_list_get_single_mode(lv_obj_t *list);
/**
* Get the text of a list element
* @param btn pointer to list element

View File

@ -280,6 +280,18 @@ void lv_mbox_set_style(lv_obj_t * mbox, lv_mbox_style_t type, lv_style_t * style
}
/**
* Set whether recoloring is enabled
* @param btnm pointer to button matrix object
* @param en whether recoloring is enabled
*/
void lv_mbox_set_recolor(lv_obj_t * mbox, bool en)
{
lv_mbox_ext_t * ext = lv_obj_get_ext_attr(mbox);
if(ext->btnm)
lv_btnm_set_recolor(ext->btnm, en);
}
/*=====================
* Getter functions
@ -362,6 +374,21 @@ lv_style_t * lv_mbox_get_style(const lv_obj_t * mbox, lv_mbox_style_t type)
return style;
}
/**
* Get whether recoloring is enabled
* @param btnm pointer to button matrix object
* @return whether recoloring is enabled
*/
bool lv_mbox_get_recolor(const lv_obj_t * mbox)
{
lv_mbox_ext_t * ext = lv_obj_get_ext_attr(mbox);
if(!ext->btnm)
return false;
return lv_btnm_get_recolor(ext->btnm);
}
/**********************
* STATIC FUNCTIONS

View File

@ -140,6 +140,13 @@ void lv_mbox_stop_auto_close(lv_obj_t * mbox);
*/
void lv_mbox_set_style(lv_obj_t *mbox, lv_mbox_style_t type, lv_style_t *style);
/**
* Set whether recoloring is enabled. Must be called after `lv_mbox_add_btns`.
* @param btnm pointer to button matrix object
* @param en whether recoloring is enabled
*/
void lv_mbox_set_recolor(lv_obj_t * mbox, bool en);
/*=====================
* Getter functions
*====================*/
@ -175,6 +182,13 @@ uint16_t lv_mbox_get_anim_time(const lv_obj_t * mbox);
*/
lv_style_t * lv_mbox_get_style(const lv_obj_t *mbox, lv_mbox_style_t type);
/**
* Get whether recoloring is enabled
* @param btnm pointer to button matrix object
* @return whether recoloring is enabled
*/
bool lv_mbox_get_recolor(const lv_obj_t * mbox);
/**********************
* MACROS
**********************/

View File

@ -144,18 +144,18 @@ void lv_templ_set_style(lv_obj_t * templ, lv_templ_style_t type, lv_style_t * st
lv_style_t * lv_templ_get_style(const lv_obj_t * templ, lv_templ_style_t type)
{
lv_templ_ext_t * ext = lv_obj_get_ext_attr(templ);
lv_style_t * style = NULL;
switch(type) {
case LV_TEMPL_STYLE_X:
return NULL;
style = NULL; /*Replace NULL with a pointer to the style*/
case LV_TEMPL_STYLE_Y:
return NULL;
style = NULL; /*Replace NULL with a pointer to the style*/
default:
return NULL;
style = NULL;
}
/*To avoid warning*/
return NULL;
return style;
}
/*=====================

View File

@ -571,7 +571,6 @@ void lv_page_scroll_ver(lv_obj_t * page, lv_coord_t dist)
#endif
}
/**
* Not intended to use directly by the user but by other object types internally.
* Start an edge flash animation. Exactly one `ext->edge_flash.xxx_ip` should be set
@ -579,6 +578,7 @@ void lv_page_scroll_ver(lv_obj_t * page, lv_coord_t dist)
*/
void lv_page_start_edge_flash(lv_obj_t * page)
{
#if USE_LV_ANIMATION
lv_page_ext_t * ext = lv_obj_get_ext_attr(page);
if(ext->edge_flash.enabled) {
lv_anim_t a;
@ -596,6 +596,7 @@ void lv_page_start_edge_flash(lv_obj_t * page)
a.repeat_pause = 0;
lv_anim_create(&a);
}
#endif
}

View File

@ -22,7 +22,7 @@
# endif
#else
# undef LV_ROLLER_ANIM_TIME
# define LV_ROLLER_ANIM_TIME 0 /*No animation*/
# define LV_ROLLER_ANIM_TIME 0 /*No animation*/
#endif
/**********************
@ -75,7 +75,7 @@ lv_obj_t * lv_roller_create(lv_obj_t * par, const lv_obj_t * copy)
lv_mem_assert(ext);
if(ext == NULL) return NULL;
ext->ddlist.draw_arrow = 0; /*Do not draw arrow by default*/
/*The signal and design functions are not copied so set them here*/
lv_obj_set_signal_func(new_roller, lv_roller_signal);
lv_obj_set_design_func(new_roller, lv_roller_design);
@ -123,6 +123,19 @@ lv_obj_t * lv_roller_create(lv_obj_t * par, const lv_obj_t * copy)
* Setter functions
*====================*/
/**
* Set the align of the roller's options (left or center)
* @param roller - pointer to a roller object
* @param align - one of lv_label_align_t values (left, right, center)
*/
void lv_roller_set_align(lv_obj_t * roller, lv_label_align_t align)
{
lv_roller_ext_t * ext = lv_obj_get_ext_attr(roller);
lv_mem_assert(ext);
if(ext->ddlist.label == NULL) return; /*Probably the roller is being deleted if the label is NULL.*/
lv_label_set_align(ext->ddlist.label, align);
}
/**
* Set the selected option
* @param roller pointer to a roller object
@ -151,8 +164,8 @@ void lv_roller_set_visible_row_count(lv_obj_t * roller, uint8_t row_cnt)
lv_roller_ext_t * ext = lv_obj_get_ext_attr(roller);
lv_style_t * style_label = lv_obj_get_style(ext->ddlist.label);
lv_ddlist_set_fix_height(roller, lv_font_get_height(style_label->text.font) * row_cnt + style_label->text.line_space * (row_cnt));
}
/**
* Set a style of a roller
* @param roller pointer to a roller object
@ -175,6 +188,19 @@ void lv_roller_set_style(lv_obj_t * roller, lv_roller_style_t type, lv_style_t *
* Getter functions
*====================*/
/**
* Get the align attribute. Default alignment after _create is LV_LABEL_ALIGN_CENTER
* @param roller pointer to a roller object
* @return LV_LABEL_ALIGN_LEFT, LV_LABEL_ALIGN_RIGHT or LV_LABEL_ALIGN_CENTER
*/
lv_label_align_t lv_roller_get_align(const lv_obj_t * roller)
{
lv_roller_ext_t * ext = lv_obj_get_ext_attr(roller);
lv_mem_assert(ext);
lv_mem_assert(ext->ddlist.label);
return lv_label_get_align(ext->ddlist.label);
}
/**
* Get the auto width set attribute
* @param roller pointer to a roller object
@ -210,7 +236,6 @@ lv_style_t * lv_roller_get_style(const lv_obj_t * roller, lv_roller_style_t type
* STATIC FUNCTIONS
**********************/
/**
* Handle the drawing related tasks of the rollers
* @param roller pointer to an object
@ -266,11 +291,23 @@ static bool lv_roller_design(lv_obj_t * roller, const lv_area_t * mask, lv_desig
if(area_ok) {
lv_style_t * sel_style = lv_roller_get_style(roller, LV_ROLLER_STYLE_SEL);
lv_style_t new_style;
lv_txt_flag_t txt_align = LV_TXT_FLAG_NONE;
{
lv_label_align_t label_align = lv_label_get_align(ext->ddlist.label);
if(LV_LABEL_ALIGN_CENTER == label_align) {
txt_align |= LV_TXT_FLAG_CENTER;
} else if(LV_LABEL_ALIGN_RIGHT == label_align) {
txt_align |= LV_TXT_FLAG_RIGHT;
}
}
lv_style_copy(&new_style, style);
new_style.text.color = sel_style->text.color;
new_style.text.opa = sel_style->text.opa;
lv_draw_label(&ext->ddlist.label->coords, &mask_sel, &new_style, opa_scale,
lv_label_get_text(ext->ddlist.label), LV_TXT_FLAG_CENTER, NULL);
lv_label_get_text(ext->ddlist.label), txt_align, NULL);
}
}
@ -296,10 +333,17 @@ static lv_res_t lv_roller_signal(lv_obj_t * roller, lv_signal_t sign, void * par
}
lv_roller_ext_t * ext = lv_obj_get_ext_attr(roller);
lv_align_t obj_align = LV_ALIGN_IN_LEFT_MID;
if(ext->ddlist.label) {
lv_label_align_t label_align = lv_label_get_align(ext->ddlist.label);
if(LV_LABEL_ALIGN_CENTER == label_align) obj_align = LV_ALIGN_CENTER;
else if(LV_LABEL_ALIGN_RIGHT == label_align) obj_align = LV_ALIGN_IN_RIGHT_MID;
}
if(sign == LV_SIGNAL_STYLE_CHG) {
lv_obj_set_height(lv_page_get_scrl(roller),
lv_obj_get_height(ext->ddlist.label) + lv_obj_get_height(roller));
lv_obj_align(ext->ddlist.label, NULL, LV_ALIGN_CENTER, 0, 0);
lv_obj_align(ext->ddlist.label, NULL, obj_align, 0, 0);
lv_ddlist_set_selected(roller, ext->ddlist.sel_opt_id);
refr_position(roller, false);
} else if(sign == LV_SIGNAL_CORD_CHG) {
@ -311,7 +355,7 @@ static lv_res_t lv_roller_signal(lv_obj_t * roller, lv_signal_t sign, void * par
lv_obj_set_height(lv_page_get_scrl(roller),
lv_obj_get_height(ext->ddlist.label) + lv_obj_get_height(roller));
lv_obj_align(ext->ddlist.label, NULL, LV_ALIGN_CENTER, 0, 0);
lv_obj_align(ext->ddlist.label, NULL, obj_align, 0, 0);
lv_ddlist_set_selected(roller, ext->ddlist.sel_opt_id);
refr_position(roller, false);
}
@ -337,14 +381,12 @@ static lv_res_t lv_roller_signal(lv_obj_t * roller, lv_signal_t sign, void * par
ext->ddlist.sel_opt_id_ori = ext->ddlist.sel_opt_id; /*Save the current value. Used to revert this state if ENER wont't be pressed*/
}
} else if(sign == LV_SIGNAL_DEFOCUS) {
/*Revert the original state*/
if(ext->ddlist.sel_opt_id != ext->ddlist.sel_opt_id_ori) {
ext->ddlist.sel_opt_id = ext->ddlist.sel_opt_id_ori;
refr_position(roller, true);
}
} else if(sign == LV_SIGNAL_CONTROLL) {
char c = *((char *)param);
if(c == LV_GROUP_KEY_RIGHT || c == LV_GROUP_KEY_DOWN) {
@ -486,7 +528,6 @@ static void draw_bg(lv_obj_t * roller, const lv_area_t * mask)
style->body.main_color = main_tmp;
style->body.grad_color = grad_tmp;
}
}
/**

View File

@ -28,6 +28,7 @@ extern "C" {
#include "../lv_core/lv_obj.h"
#include "lv_ddlist.h"
#include "lv_label.h"
/*********************
* DEFINES
@ -64,6 +65,13 @@ lv_obj_t * lv_roller_create(lv_obj_t * par, const lv_obj_t * copy);
* Setter functions
*====================*/
/**
* Set the align of the roller's options (left, right or center[default])
* @param roller - pointer to a roller object
* @param align - one of lv_label_align_t values (left, right, center)
*/
void lv_roller_set_align(lv_obj_t * roller, lv_label_align_t align);
/**
* Set the options on a roller
* @param roller pointer to roller object
@ -82,7 +90,6 @@ static inline void lv_roller_set_options(lv_obj_t * roller, const char * options
*/
void lv_roller_set_selected(lv_obj_t *roller, uint16_t sel_opt, bool anim_en);
/**
* Set a function to call when a new option is chosen
* @param roller pointer to a roller
@ -120,7 +127,6 @@ static inline void lv_roller_set_anim_time(lv_obj_t *roller, uint16_t anim_time)
lv_ddlist_set_anim_time(roller, anim_time);
}
/**
* Set a style of a roller
* @param roller pointer to a roller object
@ -133,6 +139,13 @@ void lv_roller_set_style(lv_obj_t *roller, lv_roller_style_t type, lv_style_t *s
* Getter functions
*====================*/
/**
* Get the align attribute. Default alignment after _create is LV_LABEL_ALIGN_CENTER
* @param roller pointer to a roller object
* @return LV_LABEL_ALIGN_LEFT, LV_LABEL_ALIGN_RIGHT or LV_LABEL_ALIGN_CENTER
*/
lv_label_align_t lv_roller_get_align(const lv_obj_t * roller);
/**
* Get the options of a roller
* @param roller pointer to roller object

View File

@ -490,11 +490,13 @@ static lv_res_t lv_slider_signal(lv_obj_t * slider, lv_signal_t sign, void * par
}
} else if(sign == LV_SIGNAL_CONTROLL) {
char c = *((char *)param);
ext->drag_value = LV_SLIDER_NOT_PRESSED;
#if USE_LV_GROUP
lv_group_t * g = lv_obj_get_group(slider);
bool editing = lv_group_get_editing(g);
lv_hal_indev_type_t indev_type = lv_indev_get_type(lv_indev_get_act());
/*Encoders need special handling*/
if(indev_type == LV_INDEV_TYPE_ENCODER && c == LV_GROUP_KEY_ENTER) {
if(editing) lv_group_set_editing(g, false);

View File

@ -69,7 +69,9 @@ lv_obj_t * lv_sw_create(lv_obj_t * par, const lv_obj_t * copy)
/*Initialize the allocated 'ext' */
ext->changed = 0;
#if USE_LV_ANIMATION
ext->anim_time = 0;
#endif
ext->style_knob_off = ext->slider.style_knob;
ext->style_knob_on = ext->slider.style_knob;
@ -100,7 +102,9 @@ lv_obj_t * lv_sw_create(lv_obj_t * par, const lv_obj_t * copy)
lv_sw_ext_t * copy_ext = lv_obj_get_ext_attr(copy);
ext->style_knob_off = copy_ext->style_knob_off;
ext->style_knob_on = copy_ext->style_knob_on;
#if USE_LV_ANIMATION
ext->anim_time = copy_ext->anim_time;
#endif
if(lv_sw_get_state(new_sw)) lv_slider_set_style(new_sw, LV_SLIDER_STYLE_KNOB, ext->style_knob_on);
else lv_slider_set_style(new_sw, LV_SLIDER_STYLE_KNOB, ext->style_knob_off);
@ -150,8 +154,7 @@ void lv_sw_off(lv_obj_t * sw)
void lv_sw_on_anim(lv_obj_t * sw)
{
lv_sw_ext_t * ext = lv_obj_get_ext_attr(sw);
if(lv_sw_get_anim_time(sw) > 0) lv_sw_anim_to_value(sw, LV_SWITCH_SLIDER_ANIM_MAX);
if(lv_sw_get_anim_time(sw) > 0)lv_sw_anim_to_value(sw, LV_SWITCH_SLIDER_ANIM_MAX);
else lv_slider_set_value(sw, LV_SWITCH_SLIDER_ANIM_MAX);
lv_slider_set_style(sw, LV_SLIDER_STYLE_KNOB, ext->style_knob_on);
@ -200,13 +203,13 @@ void lv_sw_set_style(lv_obj_t * sw, lv_sw_style_t type, lv_style_t * style)
void lv_sw_set_anim_time(lv_obj_t *sw, uint16_t anim_time)
{
#if USE_LV_ANIMATION == 0
anim_time = 0;
#endif
lv_sw_ext_t * ext = lv_obj_get_ext_attr(sw);
#if USE_LV_ANIMATION
lv_sw_ext_t * ext = lv_obj_get_ext_attr(sw);
ext->anim_time = anim_time;
#endif
}
/*=====================
* Getter functions
*====================*/
@ -325,11 +328,15 @@ static lv_res_t lv_sw_signal(lv_obj_t * sw, lv_signal_t sign, void * param)
else if(sign == LV_SIGNAL_PRESS_LOST) {
if(lv_sw_get_state(sw)) {
lv_slider_set_style(sw, LV_SLIDER_STYLE_KNOB, ext->style_knob_on);
#if USE_LV_ANIMATION
lv_sw_anim_to_value(sw, LV_SWITCH_SLIDER_ANIM_MAX);
#endif
}
else {
lv_slider_set_style(sw, LV_SLIDER_STYLE_KNOB, ext->style_knob_off);
#if USE_LV_ANIMATION
lv_sw_anim_to_value(sw, 0);
#endif
}
}
else if(sign == LV_SIGNAL_RELEASED) {
@ -380,9 +387,9 @@ static lv_res_t lv_sw_signal(lv_obj_t * sw, lv_signal_t sign, void * param)
return res;
}
static void lv_sw_anim_to_value(lv_obj_t * sw, int16_t value)
{
#if USE_LV_ANIMATION
lv_anim_t a;
lv_sw_ext_t * ext = lv_obj_get_ext_attr(sw);
a.var = sw;
@ -398,6 +405,7 @@ static void lv_sw_anim_to_value(lv_obj_t * sw, int16_t value)
a.repeat = 0;
a.repeat_pause = 0;
lv_anim_create(&a);
#endif
}
#endif

View File

@ -160,14 +160,12 @@ static inline lv_action_t lv_sw_get_action(const lv_obj_t * slider)
*/
lv_style_t * lv_sw_get_style(const lv_obj_t *sw, lv_sw_style_t type);
#if USE_LV_ANIMATION
/**
* Get the animation time of the switch
* @param sw pointer to a switch object
* @return style pointer to a style
*/
uint16_t lv_sw_get_anim_time(const lv_obj_t *sw);
#endif
/**********************
* MACROS

View File

@ -966,11 +966,12 @@ static bool lv_ta_scrollable_design(lv_obj_t * scrl, const lv_area_t * mask, lv_
uint32_t byte_pos;
#if LV_TXT_UTF8 != 0
byte_pos = lv_txt_encoded_get_byte_id(txt, cur_pos);
uint32_t letter = lv_txt_encoded_next(&txt[byte_pos], NULL);
#else
byte_pos = cur_pos;
uint32_t letter = txt[byte_pos];
#endif
uint32_t letter = lv_txt_encoded_next(&txt[byte_pos], NULL);
lv_coord_t letter_h = lv_font_get_height(label_style->text.font);
/*Set letter_w (set not 0 on non printable but valid chars)*/
lv_coord_t letter_w;
@ -1003,6 +1004,7 @@ static bool lv_ta_scrollable_design(lv_obj_t * scrl, const lv_area_t * mask, lv_
}
}
/*Draw he cursor according to the type*/
lv_area_t cur_area;
if(ext->cursor.type == LV_CURSOR_LINE) {

633
lv_objx/lv_table.c Normal file
View File

@ -0,0 +1,633 @@
/**
* @file lv_table.c
*
*/
/*********************
* INCLUDES
*********************/
#include "lv_table.h"
#if USE_LV_TABLE != 0
#include "../lv_misc/lv_txt.h"
#include "../lv_misc/lv_math.h"
#include "../lv_draw/lv_draw_label.h"
/*********************
* DEFINES
*********************/
/**********************
* TYPEDEFS
**********************/
/**********************
* STATIC PROTOTYPES
**********************/
static bool lv_table_design(lv_obj_t * table, const lv_area_t * mask, lv_design_mode_t mode);
static lv_res_t lv_table_signal(lv_obj_t * table, lv_signal_t sign, void * param);
static lv_coord_t get_row_height(lv_obj_t * table, uint16_t row_id);
static void refr_size(lv_obj_t * table);
/**********************
* STATIC VARIABLES
**********************/
static lv_signal_func_t ancestor_signal;
static lv_design_func_t ancestor_scrl_design;
/**********************
* MACROS
**********************/
/**********************
* GLOBAL FUNCTIONS
**********************/
/**
* Create a table object
* @param par pointer to an object, it will be the parent of the new table
* @param copy pointer to a table object, if not NULL then the new object will be copied from it
* @return pointer to the created table
*/
lv_obj_t * lv_table_create(lv_obj_t * par, const lv_obj_t * copy)
{
LV_LOG_TRACE("table create started");
/*Create the ancestor of table*/
lv_obj_t * new_table = lv_obj_create(par, copy);
lv_mem_assert(new_table);
if(new_table == NULL) return NULL;
/*Allocate the table type specific extended data*/
lv_table_ext_t * ext = lv_obj_allocate_ext_attr(new_table, sizeof(lv_table_ext_t));
lv_mem_assert(ext);
if(ext == NULL) return NULL;
if(ancestor_signal == NULL) ancestor_signal = lv_obj_get_signal_func(new_table);
if(ancestor_scrl_design == NULL) ancestor_scrl_design = lv_obj_get_design_func(new_table);
/*Initialize the allocated 'ext' */
ext->cell_data = NULL;
ext->cell_style = &lv_style_plain;
ext->col_cnt = 0;
ext->row_cnt = 0;
uint16_t i;
for(i = 0; i < LV_TABLE_COL_MAX; i++) {
ext->col_w[i] = LV_DPI;
}
/*The signal and design functions are not copied so set them here*/
lv_obj_set_signal_func(new_table, lv_table_signal);
lv_obj_set_design_func(new_table, lv_table_design);
/*Init the new table table*/
if(copy == NULL) {
lv_table_set_style(new_table, LV_TABLE_STYLE_BG, &lv_style_plain_color);
}
/*Copy an existing table*/
else {
lv_table_ext_t * copy_ext = lv_obj_get_ext_attr(copy);
ext->cell_style = copy_ext->cell_style;
ext->col_cnt = copy_ext->col_cnt;
ext->row_cnt = copy_ext->row_cnt;
/*Refresh the style with new signal function*/
lv_obj_refresh_style(new_table);
}
LV_LOG_INFO("table created");
return new_table;
}
/*=====================
* Setter functions
*====================*/
/**
* Set the value of a cell.
* @param table pointer to a Table object
* @param row id of the row [0 .. row_cnt -1]
* @param col id of the column [0 .. col_cnt -1]
* @param txt text to display in the cell. It will be copied and saved so this variable is not required after this function call.
*/
void lv_table_set_cell_value(lv_obj_t * table, uint16_t row, uint16_t col, const char * txt)
{
lv_table_ext_t * ext = lv_obj_get_ext_attr(table);
if(row >= ext->row_cnt || col >= ext->col_cnt) {
LV_LOG_WARN("lv_table_set_cell_value: invalid row or column");
return;
}
uint32_t cell = row * ext->col_cnt + col;
lv_table_cell_format_t format;
/*Save the format byte*/
if(ext->cell_data[cell]) {
format.format_byte = ext->cell_data[cell][0];
}
/*Initialize the format byte*/
else {
format.align = LV_LABEL_ALIGN_LEFT;
format.right_merge = 0;
}
ext->cell_data[cell] = lv_mem_realloc(ext->cell_data[cell], strlen(txt) + 2); /*+1: trailing '\0; +1: format byte*/
strcpy(ext->cell_data[cell] + 1, txt); /*Leave the format byte*/
ext->cell_data[cell][0] = format.format_byte;
refr_size(table);
}
/**
* Set the number of rows
* @param table table pointer to a Table object
* @param row_cnt number of rows
*/
void lv_table_set_row_cnt(lv_obj_t * table, uint16_t row_cnt)
{
lv_table_ext_t * ext = lv_obj_get_ext_attr(table);
ext->row_cnt = row_cnt;
if(ext->row_cnt > 0 && ext->col_cnt > 0) {
ext->cell_data = lv_mem_realloc(ext->cell_data, ext->row_cnt * ext->col_cnt * sizeof(char*));
}
else {
lv_mem_free(ext->cell_data);
ext->cell_data = NULL;
}
refr_size(table);
}
/**
* Set the number of columns
* @param table table pointer to a Table object
* @param col_cnt number of columns. Must be < LV_TABLE_COL_MAX
*/
void lv_table_set_col_cnt(lv_obj_t * table, uint16_t col_cnt)
{
if(col_cnt >= LV_TABLE_COL_MAX) {
LV_LOG_WARN("lv_table_set_col_cnt: too many columns. Must be < LV_TABLE_COL_MAX.");
return;
}
lv_table_ext_t * ext = lv_obj_get_ext_attr(table);
ext->col_cnt = col_cnt;
if(ext->row_cnt > 0 && ext->col_cnt > 0) {
ext->cell_data = lv_mem_realloc(ext->cell_data, ext->row_cnt * ext->col_cnt * sizeof(char*));
}
else {
lv_mem_free(ext->cell_data);
ext->cell_data = NULL;
}
refr_size(table);
}
/**
* Set the width of a column
* @param table table pointer to a Table object
* @param col_id id of the column [0 .. LV_TABLE_COL_MAX -1]
* @param w width of the column
*/
void lv_table_set_col_width(lv_obj_t * table, uint16_t col_id, lv_coord_t w)
{
if(col_id >= LV_TABLE_COL_MAX) {
LV_LOG_WARN("lv_table_set_col_width: too big 'col_id'. Must be < LV_TABLE_COL_MAX.");
return;
}
lv_table_ext_t * ext = lv_obj_get_ext_attr(table);
ext->col_w[col_id] = w;
refr_size(table);
}
/**
* Set the text align in a cell
* @param table pointer to a Table object
* @param row id of the row [0 .. row_cnt -1]
* @param col id of the column [0 .. col_cnt -1]
* @param align LV_LABEL_ALIGN_LEFT or LV_LABEL_ALIGN_CENTER or LV_LABEL_ALIGN_RIGHT
*/
void lv_table_set_cell_align(lv_obj_t * table, uint16_t row, uint16_t col, lv_label_align_t align)
{
lv_table_ext_t * ext = lv_obj_get_ext_attr(table);
if(row >= ext->row_cnt || col >= ext->col_cnt) {
LV_LOG_WARN("lv_table_set_cell_align: invalid row or column");
return;
}
uint32_t cell = row * ext->col_cnt + col;
if(ext->cell_data[cell] == NULL) {
ext->cell_data[cell] = lv_mem_alloc(2); /*+1: trailing '\0; +1: format byte*/
ext->cell_data[cell][1] = '\0';
}
lv_table_cell_format_t format;
format.format_byte = ext->cell_data[cell][0];
format.align = align;
ext->cell_data[cell][0] = format.format_byte;
}
/**
* Merge a cell with the right neighbor. The value of the cell to the right won't be displayed.
* @param table table pointer to a Table object
* @param row id of the row [0 .. row_cnt -1]
* @param col id of the column [0 .. col_cnt -1]
* @param en true: merge right; false: don't merge right
*/
void lv_table_set_cell_merge_right(lv_obj_t * table, uint16_t row, uint16_t col, bool en)
{
lv_table_ext_t * ext = lv_obj_get_ext_attr(table);
if(row >= ext->row_cnt || col >= ext->col_cnt) {
LV_LOG_WARN("lv_table_set_cell_merge_right: invalid row or column");
return;
}
uint32_t cell = row * ext->col_cnt + col;
if(ext->cell_data[cell] == NULL) {
ext->cell_data[cell] = lv_mem_alloc(2); /*+1: trailing '\0; +1: format byte*/
ext->cell_data[cell][1] = '\0';
}
lv_table_cell_format_t format;
format.format_byte = ext->cell_data[cell][0];
format.right_merge = en ? 1 : 0;
ext->cell_data[cell][0] = format.format_byte;
refr_size(table);
}
/**
* Set a style of a table.
* @param table pointer to table object
* @param type which style should be set
* @param style pointer to a style
*/
void lv_table_set_style(lv_obj_t * table, lv_table_style_t type, lv_style_t * style)
{
lv_table_ext_t * ext = lv_obj_get_ext_attr(table);
switch(type) {
case LV_TABLE_STYLE_BG:
lv_obj_set_style(table, style);
refr_size(table);
break;
case LV_TABLE_STYLE_CELL:
ext->cell_style = style;
lv_obj_invalidate(table);
break;
}
}
/*=====================
* Getter functions
*====================*/
/**
* Get the value of a cell.
* @param table pointer to a Table object
* @param row id of the row [0 .. row_cnt -1]
* @param col id of the column [0 .. col_cnt -1]
* @return text in the cell
*/
const char * lv_table_get_cell_value(lv_obj_t * table, uint16_t row, uint16_t col)
{
lv_table_ext_t * ext = lv_obj_get_ext_attr(table);
if(row >= ext->row_cnt || col >= ext->col_cnt) {
LV_LOG_WARN("lv_table_set_cell_value: invalid row or column");
return "";
}
uint32_t cell = row * ext->col_cnt + col;
if(ext->cell_data[cell] == NULL) return "";
return &ext->cell_data[cell][1]; /*Skip the format byte*/
}
/**
* Get the number of rows.
* @param table table pointer to a Table object
* @return number of rows.
*/
uint16_t lv_table_get_row_cnt(lv_obj_t * table)
{
lv_table_ext_t * ext = lv_obj_get_ext_attr(table);
return ext->row_cnt;
}
/**
* Get the number of columns.
* @param table table pointer to a Table object
* @return number of columns.
*/
uint16_t lv_table_get_col_cnt(lv_obj_t * table)
{
lv_table_ext_t * ext = lv_obj_get_ext_attr(table);
return ext->col_cnt;
}
/**
* Get the width of a column
* @param table table pointer to a Table object
* @param col_id id of the column [0 .. LV_TABLE_COL_MAX -1]
* @return width of the column
*/
lv_coord_t lv_table_get_col_width(lv_obj_t * table, uint16_t col_id)
{
if(col_id >= LV_TABLE_COL_MAX) {
LV_LOG_WARN("lv_table_set_col_width: too big 'col_id'. Must be < LV_TABLE_COL_MAX.");
return 0;
}
lv_table_ext_t * ext = lv_obj_get_ext_attr(table);
return ext->col_w[col_id];
}
/**
* Get the text align of a cell
* @param table pointer to a Table object
* @param row id of the row [0 .. row_cnt -1]
* @param col id of the column [0 .. col_cnt -1]
* @return LV_LABEL_ALIGN_LEFT (default in case of error) or LV_LABEL_ALIGN_CENTER or LV_LABEL_ALIGN_RIGHT
*/
lv_label_align_t lv_table_get_cell_align(lv_obj_t * table, uint16_t row, uint16_t col)
{
lv_table_ext_t * ext = lv_obj_get_ext_attr(table);
if(row >= ext->row_cnt || col >= ext->col_cnt) {
LV_LOG_WARN("lv_table_set_cell_align: invalid row or column");
return LV_LABEL_ALIGN_LEFT; /*Just return with something*/
}
uint32_t cell = row * ext->col_cnt + col;
if(ext->cell_data[cell] == NULL) return LV_LABEL_ALIGN_LEFT; /*Just return with something*/
else {
lv_table_cell_format_t format;
format.format_byte = ext->cell_data[cell][0];
return format.align;
}
}
/**
* Get the cell merge attribute.
* @param table table pointer to a Table object
* @param row id of the row [0 .. row_cnt -1]
* @param col id of the column [0 .. col_cnt -1]
* @return true: merge right; false: don't merge right
*/
bool lv_table_get_cell_merge_right(lv_obj_t * table, uint16_t row, uint16_t col)
{
lv_table_ext_t * ext = lv_obj_get_ext_attr(table);
if(row >= ext->row_cnt || col >= ext->col_cnt) {
LV_LOG_WARN("lv_table_get_cell_merge_right: invalid row or column");
return false;
}
uint32_t cell = row * ext->col_cnt + col;
if(ext->cell_data[cell] == NULL) return false;
else {
lv_table_cell_format_t format;
format.format_byte = ext->cell_data[cell][0];
return format.right_merge ? true : false;
}
}
/**
* Get style of a table.
* @param table pointer to table object
* @param type which style should be get
* @return style pointer to the style
*/
lv_style_t * lv_table_get_style(const lv_obj_t * table, lv_table_style_t type)
{
lv_table_ext_t * ext = lv_obj_get_ext_attr(table);
lv_style_t * style = NULL;
switch(type) {
case LV_TABLE_STYLE_BG:
style = lv_obj_get_style(table);
break;
case LV_TABLE_STYLE_CELL:
style = ext->cell_style;
break;
default:
return NULL;
}
return style;
}
/**********************
* STATIC FUNCTIONS
**********************/
/**
* Handle the drawing related tasks of the tables
* @param table 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_table_design(lv_obj_t * table, const lv_area_t * mask, lv_design_mode_t mode)
{
/*Return false if the object is not covers the mask_p area*/
if(mode == LV_DESIGN_COVER_CHK) {
return false;
}
/*Draw the object*/
else if(mode == LV_DESIGN_DRAW_MAIN) {
ancestor_scrl_design(table, mask, mode);
lv_table_ext_t * ext = lv_obj_get_ext_attr(table);
lv_style_t * bg_style = lv_obj_get_style(table);
lv_coord_t h_row;
lv_point_t txt_size;
lv_area_t cell_area;
lv_area_t txt_area;
lv_txt_flag_t txt_flags;
uint16_t col;
uint16_t row;
uint16_t cell = 0;
cell_area.y2 = table->coords.y1 + bg_style->body.padding.ver;
for(row = 0; row < ext->row_cnt; row++) {
h_row = get_row_height(table, row);
cell_area.y1 = cell_area.y2;
cell_area.y2 = cell_area.y1 + h_row;
cell_area.x2 = table->coords.x1 + bg_style->body.padding.hor;
for(col = 0; col < ext->col_cnt; col++) {
cell_area.x1 = cell_area.x2;
cell_area.x2 = cell_area.x1 + ext->col_w[col];
uint16_t col_merge = 0;
for(col_merge = 0; col_merge + col < ext->col_cnt - 1; col_merge ++) {
if(ext->cell_data[cell + col_merge] != NULL) {
lv_table_cell_format_t format;
format.format_byte = ext->cell_data[cell + col_merge][0];
if(format.right_merge) cell_area.x2 += ext->col_w[col + col_merge + 1];
else break;
} else {
break;
}
}
lv_draw_rect(&cell_area, mask, ext->cell_style, LV_OPA_COVER);
if(ext->cell_data[cell]) {
txt_area.x1 = cell_area.x1 + ext->cell_style->body.padding.hor;
txt_area.x2 = cell_area.x2 - ext->cell_style->body.padding.hor;
txt_area.y1 = cell_area.y1 + ext->cell_style->body.padding.ver;
txt_area.y2 = cell_area.y2 - ext->cell_style->body.padding.ver;
lv_table_cell_format_t format;
format.format_byte = ext->cell_data[cell][0];
switch(format.align) {
default:
case LV_LABEL_ALIGN_LEFT:
txt_flags = LV_TXT_FLAG_NONE;
break;
case LV_LABEL_ALIGN_RIGHT:
txt_flags = LV_TXT_FLAG_RIGHT;
break;
case LV_LABEL_ALIGN_CENTER:
txt_flags = LV_TXT_FLAG_CENTER;
break;
}
lv_txt_get_size(&txt_size, ext->cell_data[cell] + 1, ext->cell_style->text.font,
ext->cell_style->text.letter_space, ext->cell_style->text.line_space, lv_area_get_width(&txt_area), txt_flags);
lv_draw_label(&txt_area, mask, ext->cell_style, LV_OPA_COVER, ext->cell_data[cell] + 1, txt_flags, NULL);
}
cell += col_merge + 1;
col += col_merge;
}
}
}
/*Post draw when the children are drawn*/
else if(mode == LV_DESIGN_DRAW_POST) {
}
return true;
}
/**
* Signal function of the table
* @param table pointer to a table object
* @param sign a signal type from lv_signal_t enum
* @param param pointer to a signal specific variable
* @return LV_RES_OK: the object is not deleted in the function; LV_RES_INV: the object is deleted
*/
static lv_res_t lv_table_signal(lv_obj_t * table, lv_signal_t sign, void * param)
{
lv_res_t res;
/* Include the ancient signal function */
res = ancestor_signal(table, sign, param);
if(res != LV_RES_OK) return res;
if(sign == LV_SIGNAL_CLEANUP) {
/*Free the cell texts*/
lv_table_ext_t * ext = lv_obj_get_ext_attr(table);
uint16_t cell;
for(cell = 0; cell < ext->col_cnt * ext->row_cnt; cell++) {
if(ext->cell_data[cell]) {
lv_mem_free(ext->cell_data[cell]);
ext->cell_data[cell] = NULL;
}
}
} else if(sign == LV_SIGNAL_GET_TYPE) {
lv_obj_type_t * buf = param;
uint8_t i;
for(i = 0; i < LV_MAX_ANCESTOR_NUM - 1; i++) { /*Find the last set data*/
if(buf->type[i] == NULL) break;
}
buf->type[i] = "lv_table";
}
return res;
}
static void refr_size(lv_obj_t * table)
{
lv_coord_t h = 0;
lv_coord_t w = 0;
lv_table_ext_t * ext = lv_obj_get_ext_attr(table);
uint16_t i;
for(i= 0; i < ext->col_cnt; i++) {
w += ext->col_w[i];
}
for(i= 0; i < ext->row_cnt; i++) {
h += get_row_height(table, i);
}
lv_style_t * bg_style = lv_obj_get_style(table);
w += bg_style->body.padding.hor * 2;
h += bg_style->body.padding.ver * 2;
lv_obj_set_size(table, w, h);
lv_obj_invalidate(table);
}
static lv_coord_t get_row_height(lv_obj_t * table, uint16_t row_id)
{
lv_table_ext_t * ext = lv_obj_get_ext_attr(table);
lv_point_t txt_size;
lv_coord_t txt_w;
uint16_t row_start = row_id * ext->col_cnt;
uint16_t cell;
uint16_t col;
lv_coord_t h_max = lv_font_get_height(ext->cell_style->text.font);
for(cell = row_start, col = 0; cell < row_start + ext->col_cnt; cell++, col ++) {
if(ext->cell_data[cell] != NULL) {
txt_w = ext->col_w[col];
uint16_t col_merge = 0;
for(col_merge = 0; col_merge + col < ext->col_cnt - 1; col_merge ++) {
if(ext->cell_data[cell + col_merge] != NULL) {
lv_table_cell_format_t format;
format.format_byte = ext->cell_data[cell + col_merge][0];
if(format.right_merge) txt_w += ext->col_w[col + col_merge + 1];
else break;
} else {
break;
}
}
txt_w -= 2 * ext->cell_style->body.padding.hor;
lv_txt_get_size(&txt_size, ext->cell_data[cell] + 1, ext->cell_style->text.font,
ext->cell_style->text.letter_space, ext->cell_style->text.line_space, txt_w, LV_TXT_FLAG_NONE);
h_max = LV_MATH_MAX(txt_size.y, h_max);
cell += col_merge;
col += col_merge;
}
}
return h_max + 2 * ext->cell_style->body.padding.ver;
}
#endif

217
lv_objx/lv_table.h Normal file
View File

@ -0,0 +1,217 @@
/**
* @file lv_table.h
*
*/
#ifndef LV_TABLE_H
#define LV_TABLE_H
#ifdef __cplusplus
extern "C" {
#endif
/*********************
* INCLUDES
*********************/
#ifdef LV_CONF_INCLUDE_SIMPLE
#include "lv_conf.h"
#else
#include "../../lv_conf.h"
#endif
#if USE_LV_TABLE != 0
/*Testing of dependencies*/
#if USE_LV_LABEL == 0
#error "lv_table: lv_label is required. Enable it in lv_conf.h (USE_LV_LABEL 1) "
#endif
#include "../lv_core/lv_obj.h"
#include "lv_label.h"
/*********************
* DEFINES
*********************/
#ifndef LV_TABLE_COL_MAX
#define LV_TABLE_COL_MAX 12
#endif
/**********************
* TYPEDEFS
**********************/
typedef union {
struct {
uint8_t align:3;
uint8_t right_merge:1;
};
uint8_t format_byte;
}lv_table_cell_format_t;
/*Data of table*/
typedef struct {
/*New data for this type */
uint16_t col_cnt;
uint16_t row_cnt;
char ** cell_data;
lv_style_t * cell_style;
lv_coord_t col_w[LV_TABLE_COL_MAX];
} lv_table_ext_t;
/*Styles*/
enum {
LV_TABLE_STYLE_BG,
LV_TABLE_STYLE_CELL,
};
typedef uint8_t lv_table_style_t;
/**********************
* GLOBAL PROTOTYPES
**********************/
/**
* Create a table object
* @param par pointer to an object, it will be the parent of the new table
* @param copy pointer to a table object, if not NULL then the new object will be copied from it
* @return pointer to the created table
*/
lv_obj_t * lv_table_create(lv_obj_t * par, const lv_obj_t * copy);
/*=====================
* Setter functions
*====================*/
/**
* Set the value of a cell.
* @param table pointer to a Table object
* @param row id of the row [0 .. row_cnt -1]
* @param col id of the column [0 .. col_cnt -1]
* @param txt text to display in the cell. It will be copied and saved so this variable is not required after this function call.
*/
void lv_table_set_cell_value(lv_obj_t * table, uint16_t row, uint16_t col, const char * txt);
/**
* Set the number of rows
* @param table table pointer to a Table object
* @param row_cnt number of rows
*/
void lv_table_set_row_cnt(lv_obj_t * table, uint16_t row_cnt);
/**
* Set the number of columns
* @param table table pointer to a Table object
* @param col_cnt number of columns. Must be < LV_TABLE_COL_MAX
*/
void lv_table_set_col_cnt(lv_obj_t * table, uint16_t col_cnt);
/**
* Set the width of a column
* @param table table pointer to a Table object
* @param col_id id of the column [0 .. LV_TABLE_COL_MAX -1]
* @param w width of the column
*/
void lv_table_set_col_width(lv_obj_t * table, uint16_t col_id, lv_coord_t w);
/**
* Set the text align in a cell
* @param table pointer to a Table object
* @param row id of the row [0 .. row_cnt -1]
* @param col id of the column [0 .. col_cnt -1]
* @param align LV_LABEL_ALIGN_LEFT or LV_LABEL_ALIGN_CENTER or LV_LABEL_ALIGN_RIGHT
*/
void lv_table_set_cell_align(lv_obj_t * table, uint16_t row, uint16_t col, lv_label_align_t align);
/**
* Merge a cell with the right neighbor. The value of the cell to the right won't be displayed.
* @param table table pointer to a Table object
* @param row id of the row [0 .. row_cnt -1]
* @param col id of the column [0 .. col_cnt -1]
* @param en true: merge right; false: don't merge right
*/
void lv_table_set_cell_merge_right(lv_obj_t * table, uint16_t row, uint16_t col, bool en);
/**
* Set a style of a table.
* @param table pointer to table object
* @param type which style should be set
* @param style pointer to a style
*/
void lv_table_set_style(lv_obj_t * table, lv_table_style_t type, lv_style_t * style);
/*=====================
* Getter functions
*====================*/
/**
* Get the value of a cell.
* @param table pointer to a Table object
* @param row id of the row [0 .. row_cnt -1]
* @param col id of the column [0 .. col_cnt -1]
* @return text in the cell
*/
const char * lv_table_get_cell_value(lv_obj_t * table, uint16_t row, uint16_t col);
/**
* Get the number of rows.
* @param table table pointer to a Table object
* @return number of rows.
*/
uint16_t lv_table_get_row_cnt(lv_obj_t * table);
/**
* Get the number of columns.
* @param table table pointer to a Table object
* @return number of columns.
*/
uint16_t lv_table_get_col_cnt(lv_obj_t * table);
/**
* Get the width of a column
* @param table table pointer to a Table object
* @param col_id id of the column [0 .. LV_TABLE_COL_MAX -1]
* @return width of the column
*/
lv_coord_t lv_table_get_col_width(lv_obj_t * table, uint16_t col_id);
/**
* Get the text align of a cell
* @param table pointer to a Table object
* @param row id of the row [0 .. row_cnt -1]
* @param col id of the column [0 .. col_cnt -1]
* @return LV_LABEL_ALIGN_LEFT (default in case of error) or LV_LABEL_ALIGN_CENTER or LV_LABEL_ALIGN_RIGHT
*/
lv_label_align_t lv_table_get_cell_align(lv_obj_t * table, uint16_t row, uint16_t col);
/**
* Get the cell merge attribute.
* @param table table pointer to a Table object
* @param row id of the row [0 .. row_cnt -1]
* @param col id of the column [0 .. col_cnt -1]
* @return true: merge right; false: don't merge right
*/
bool lv_table_get_cell_merge_right(lv_obj_t * table, uint16_t row, uint16_t col);
/**
* Get style of a table.
* @param table pointer to table object
* @param type which style should be get
* @return style pointer to the style
*/
lv_style_t * lv_table_get_style(const lv_obj_t * table, lv_table_style_t type);
/*=====================
* Other functions
*====================*/
/**********************
* MACROS
**********************/
#endif /*USE_LV_TABLE*/
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /*LV_TABLE_H*/

View File

@ -28,8 +28,6 @@
static uint16_t _hue;
static lv_font_t * _font;
static lv_font_t * _font;
static lv_font_t * _font;
static lv_theme_t theme;
static lv_style_t def;

View File

@ -36,7 +36,6 @@ static lv_style_t light_frame;
static lv_style_t dark_frame;
/*Saved input parameters*/
static uint16_t _hue;
static lv_font_t * _font;
@ -421,7 +420,7 @@ static void win_init(void)
/**
* Initialize the mono theme
* @param hue [0..360] hue value from HSV color space to define the theme's base color
* @param hue [0..360] hue value from HSV color space to define the theme's base color; is not used in lv_theme_mono
* @param font pointer to a font (NULL to use the default)
* @return pointer to the initialized theme
*/
@ -429,7 +428,6 @@ lv_theme_t * lv_theme_mono_init(uint16_t hue, lv_font_t * font)
{
if(font == NULL) font = LV_FONT_DEFAULT;
_hue = hue;
_font = font;
/*For backward compatibility initialize all theme elements with a default style */

1
lvgl.h
View File

@ -36,6 +36,7 @@ extern "C" {
#include "lv_objx/lv_cont.h"
#include "lv_objx/lv_list.h"
#include "lv_objx/lv_chart.h"
#include "lv_objx/lv_table.h"
#include "lv_objx/lv_cb.h"
#include "lv_objx/lv_bar.h"
#include "lv_objx/lv_slider.h"