Compare commits

...

89 Commits

Author SHA1 Message Date
Gabor Kiss-Vamosi
bca13143b9 chore: kick CI to rebuild the docs 2024-04-23 15:58:34 +02:00
Gabor Kiss-Vamosi
5d0ba633a5 chore(docs): fix lv_list_add_text 2022-01-10 12:12:09 +01:00
Philippe Coval
b9eaaffe92 build add install rule to CMakeList.txt (#2621) (#2687)
* build add install rule to CMakeList.txt (#2621)

* build: Add install rule

This can help to install lvgl on systems,
for clients applications.

It's made for unix (Linux OE/Yocto actually)
if needed it can be enabled for other platforms too.

Relate-to: https://github.com/lvgl/lvgl/issues/2534
Forwarded: https://github.com/lvgl/lvgl/pull/2621
Signed-off-by: Philippe Coval <philippe.coval@astrolabe.coop>

* build: Make install rules optionnal

This change may be reverted, once verified it's harmless

It was tested using:

    cmake -Dinstall=ON . && make install DESTDIR=/tmp/

Forwarded: https://github.com/lvgl/lvgl/pull/2621
Signed-off-by: Philippe Coval <philippe.coval@huawei.com>

* build: remove use of 'project' keyword in CMakeLists (#2640)

It looks like it's not supported on ESP32: "project command is not scriptable"

Signed-off-by: Philippe Coval <philippe.coval@huawei.com>

* build: fix lib name in CMakeLists (#2641)

Fixup for #2640
2021-10-28 20:35:09 +02:00
Miguel Magno
14825e03fa docs fix typos (#2472) 2021-08-21 08:58:05 -04:00
tfx2001
b20412ca6b docs(overview) fix typo (#2465) 2021-08-21 08:57:11 -04:00
embeddedt
fe4f9d7349 fix(docs) commit to meta repo as lvgl-bot instead of actual commit author 2021-08-13 13:20:50 -04:00
fvanroie
6ee2c0593b fix(docs) add static keyword to driver declaration (#2452)
Add missing static keyword to disp_drv and indev_drv declarations in the examples
2021-08-13 13:00:42 -04:00
Gabor Kiss-Vamosi
c2c24a7bc7 perf(refresh) optimize where to wait for lv_disp_flush_ready with 2 buffers 2021-07-20 11:14:15 +02:00
Gabor Kiss-Vamosi
ae058a3d8f Update CHANGELOG.md 2021-07-16 18:00:05 +02:00
Gabor Kiss-Vamosi
2e942060f0 Update versions to v8.0.2 2021-07-16 17:40:51 +02:00
Gabor Kiss-Vamosi
346b9979dc fix(theme) improve button focus of keyboard
fixes https://github.com/lvgl/lvgl/issues/2359#issuecomment-880704341
2021-07-16 17:40:51 +02:00
Gabor Kiss-Vamosi
e742455be2 fix(tabview) send LV_EVENT_VALUE_CHANGED only once
Fixes #2377
2021-07-16 17:40:51 +02:00
Gabor Kiss-Vamosi
de8b0ad834 fix(imgbtn) use the correct src in LV_EVENT_GET_SELF_SIZE 2021-07-16 17:40:51 +02:00
Themba Dube
04bae5f006 fix(color) remove extraneous cast for 8-bit color
This brings it in line with the corresponding macros for other BPP values.

This issue was found via CI added in the following commit.
2021-07-16 17:40:51 +02:00
Gabor Kiss-Vamosi
7bd924bd4d fix(obj style) fix children reposition if the parent's padding changes.
fixes #2368
2021-07-16 17:40:51 +02:00
embeddedt
7f7b9670d9 fix(color) remove extraneous _LV_COLOR_MAKE_TYPE_HELPER (#2372)
This updates it to match the other `LV_COLOR_MAKEXX` (where XX is the color depth) lines.
2021-07-16 17:40:51 +02:00
HX2003
31d49d1527 fix(spinner) should not be clickable (#2373) 2021-07-16 17:40:51 +02:00
Gabor Kiss-Vamosi
64728e7d0a fix(obj) improve how the focusing indev is determined 2021-07-16 17:40:51 +02:00
embeddedt
2c1d9e868d fix(template) update indev template for v8
A few APIs were missed in the last attempt.

Fixes #2363
2021-07-16 17:40:51 +02:00
Themba Dube
be67fa1cec fix(printf) skip defining attribute if pycparser is used 2021-07-16 17:40:51 +02:00
Avamander
e62d43c83a refactor(printf) add printf-like function attribute to _lv_txt_set_text_vfmt and lv_label_set_text_fmt (#2332)
This improves static analysis and compiler warnings of incorrect format usage.
2021-07-16 17:40:51 +02:00
Gabor Kiss-Vamosi
3e11cf38a9 fix(template) include lvgl.h in lv_port_*_template.c files
fixes: #2361
2021-07-16 17:40:51 +02:00
Gabor Kiss-Vamosi
5b4c61a871 fix(obj) detecting which indev sent LV_EVENT_FOCUS
fixes #2359
2021-07-16 17:40:51 +02:00
guoweilkd
b415e2d122 fix (span) fill LV_EVENT_GET_SELF_SIZE (#2360)
Co-authored-by: guowei15 <guowei15@xiaomi.com>
2021-07-16 17:40:51 +02:00
Gabor Kiss-Vamosi
05ca75e8ea fix(arc) disable LV_OBJ_FLAG_SCROLL_CHAIN by default 2021-07-16 17:40:51 +02:00
Gabor Kiss-Vamosi
752ac98d96 fix (draw) fix arc bg image drawing with full arcs 2021-07-16 17:40:51 +02:00
xaowang96
c4ff3ccc14 fix(disp) fix memory leak in lv_disp_remove (#2355)
Co-authored-by: wangxuedong <wangxuedong@xiaomi.com>
2021-07-16 17:40:50 +02:00
Gabor Kiss-Vamosi
a4915d3a34 fix warnigs introduced by 3fb8baf5 2021-07-16 17:40:50 +02:00
Gabor Kiss-Vamosi
43638ceb4b fix(widgets) use lv_obj_class for all the widgets
Related to #2346
2021-07-16 17:40:50 +02:00
Gabor Kiss-Vamosi
dfef40dbe6 fix(obj) move clean ups from lv_obj_del to lv_obj_destructor 2021-07-16 17:40:50 +02:00
Gabor Kiss-Vamosi
e0cc92ddec fix(roller) fix partial redraw of the selected area 2021-07-16 17:40:50 +02:00
Gabor Kiss-Vamosi
c774c26ac1 fix(roller) adjust the size of the selected area correctly
fixes #2340
2021-07-16 17:40:50 +02:00
guoweilkd
8eb99b0e4e fix(obj) delete useless type conversion (#2343)
Co-authored-by: guowei15 <guowei15@xiaomi.com>
2021-07-16 17:40:50 +02:00
guoweilkd
4fa45941fc fix(lv_obj_scroll.h) typos (#2345)
Co-authored-by: guowei15 <guowei15@xiaomi.com>
2021-07-16 17:40:50 +02:00
embeddedt
0d09025e70 fix(scroll) fire LV_EVENT_SCROLL_BEGIN in the same spot for both axes 2021-07-16 17:40:50 +02:00
Gabor Kiss-Vamosi
335b55e932 fix(btnmatrix) fix button invalidation on focus change 2021-07-16 17:40:50 +02:00
Gabor Kiss-Vamosi
01ca590c6d fix(textarea) style update in oneline mode + improve sroll to cursor
fixes: #2335
2021-07-16 17:40:50 +02:00
Gabor Kiss-Vamosi
4ac4d87fff fix(tlsf) do not use <assert.h>
fixes: #2341
2021-07-16 17:40:50 +02:00
Gabor Kiss-Vamosi
8080b5f718 fix(imgbtn) consider width==LV_SIZE_CONTENT if only mid. img is set
fixes #2305
2021-07-16 17:40:50 +02:00
Gabor Kiss-Vamosi
4faede19e9 fix(refr) reduce the nesting level in lv_refr_area 2021-07-16 17:40:50 +02:00
guoweilkd
0de30d7f56 fix(txt) enhance the function of break_chars (#2327)
Co-authored-by: guowei15 <guowei15@xiaomi.com>
2021-07-16 17:40:50 +02:00
Seb Fagard
bff9546c26 fix(pxp): update RTOS macro for SDK 2.10
replace FSL_RTOS_FREE_RTOS by SDK_OS_FREE_RTOS in order to be aligned
with MCU SDK 2.10.
See MCUX-41577.

Signed-off-by: Seb Fagard <sebastien.fagard@nxp.com>
2021-07-16 17:40:50 +02:00
Jozef Bastek
e74e6c27af fix(vglite): update for v8
includes updates coming from NXP MCU SDK 2.10 with adaptation for lvgl v8:

Fixed BLIT offset computation

Previous implementation didn't take into account a possibility of
non-zero offset in source image, so output was wrong if offset was used.
With this fix, CPU and VG-Lite output is the same even with offsets.

Signed-off-by: Jozef Bastek <jozef.bastek@nxp.com>

gpu: vglite: Buffer sync with BLITs

Added buffer synchronisation with BLITs instead of memcpy for VG-Lite.
In LVGL v8, buffer synchronisation acceleration is moved to littlevgl_support.c.

Signed-off-by: Jozef Bastek <jozef.bastek@nxp.com>

gpu: vglite: Fixed BLIT boundary

Fixed artifact issue revealed by buffer sync with BLIT feature. Caused
by wrong BLIT boundary.

Signed-off-by: Jozef Bastek <jozef.bastek@nxp.com>

gpu: vglite: BLIT quality degradation workaround for RT595

Limitation in RT595 causes BLIT image quality degradation when
coordinates are above 368 px. This patch implements workaround that will
break the BLIT into multiple smaller BLITs, so the quality is not
affected for higher resolutions.

Signed-off-by: Jozef Bastek <jozef.bastek@nxp.com>

gpu: vglite: Fix address alignment and stride requirements

Fixed multiple issues:
- The VGLite alignment requirement checks for the pixel destination
buffer are not applicable in our case of Linear (non-tiled) format.
- Some VGLite stride requirement requirement should be expressed in bytes,
not in pixels.
- Fix the Y alignment function to ensure that line starts at an address
that the respects the alignment requirement of VG-Lite.

Such mistakes do not break application,
but cause a fallback to non-accelerated Blit by CPU.
See MGG-741.

Signed-off-by: Seb Fagard <sebastien.fagard@nxp.com>

gpu: vglite: fix some MISRA C 2012 violations

fixed 56 violations: mainly implicit format casts
and unchecked returned values.

see JIRA MCUX-43327

Signed-off-by: Seb Fagard <sebastien.fagard@nxp.com>

gpu: vglite: fix stride requirement in _init_vg_buf()

fix unit: need to convert the alignment requirement into bytes when checking
stride parameter.
fix condition: stride requirement applies only on source buffers.

Signed-off-by: Seb Fagard <sebastien.fagard@nxp.com>

gpu: vglite: updates for v8

cache callback type changed in display driver struct

Signed-off-by: Seb Fagard <sebastien.fagard@nxp.com>

gpu: vglite: update parameter type for v8

display driver is now a pointer in structure.

Signed-off-by: Seb Fagard <sebastien.fagard@nxp.com>
2021-07-16 17:40:50 +02:00
Jozef Bastek
4766e97bc5 fix(pxp): update for v8
includes updates from NXP MCU SDK 2.10 with adaptation for lvgl v8:

Updated cache handling

- range limited cache flushing changed to complete cache flush, which is
faster and shold be safe
- flushing done via callback system, so OS specific code is removed
from LVGL

Signed-off-by: Jozef Bastek <jozef.bastek@nxp.com>

gpu: pxp: Buffer sync with BLITs

Added buffer synchronisation with BLITs instead of memcpy for PXP.
In LVGL v8, buffer synchronisation acceleration is moved to littlevgl_support.c.

Signed-off-by: Jozef Bastek <jozef.bastek@nxp.com>

gpu: pxp: updates for v8

cache callback type changed in display driver struct
chroma key name changed

Signed-off-by: Seb Fagard <sebastien.fagard@nxp.com>

gpu: pxp: new log header file for v8

Signed-off-by: Seb Fagard <sebastien.fagard@nxp.com>

core: init PXP accelerator

Signed-off-by: Seb Fagard <sebastien.fagard@nxp.com>
2021-07-16 17:40:50 +02:00
Gabor Kiss-Vamosi
ebcb6c0224 fix(flex) fix layout update and invalidation issues 2021-07-16 17:40:50 +02:00
Gabor Kiss-Vamosi
fbd88fe434 fix(flex) fix NULL pointer dereference
fixes #2331
2021-07-16 17:40:50 +02:00
Gabor Kiss-Vamosi
de1f6e978e fix(obj, switch) do not send LV_EVENT_VALUE_CHANGED twice
fixes #2330
2021-07-16 17:40:50 +02:00
Gabor Kiss-Vamosi
edb23d2640 fix(color) overflow with 16 bit color depth 2021-07-16 17:40:50 +02:00
Gabor Kiss-Vamosi
dee6530b0b fix(coords) fix using large coordinates
Fixes #2323
2021-07-16 17:40:50 +02:00
Gabor Kiss-Vamosi
68651c718a fix(chart) fix crash if no series are added
fixes #2322
2021-07-16 17:40:50 +02:00
Gabor Kiss-Vamosi
90c878ee92 fix(chart) invalidation with LV_CHART_UPDATE_MODE_SHIFT 2021-07-16 17:40:50 +02:00
Gabor Kiss-Vamosi
9acd70d9ec fix(align) fix lv_obj_align_to 2021-07-16 17:40:50 +02:00
Gabor Kiss-Vamosi
d7e5b2983e fix(table) invalidate the table on cell value change 2021-07-16 17:40:50 +02:00
Gabor Kiss-Vamosi
6d73386245 fix(label) remove dupliacted lv_obj_refresh_self_size 2021-07-16 17:40:49 +02:00
Gabor Kiss-Vamosi
502ca5b809 fix(draw) underflow in subpixel font drawing
Fixes: #2273
2021-07-16 17:40:49 +02:00
Gabor Kiss-Vamosi
62255ad153 fix (scroll) do not send unnecessary scroll end events 2021-07-16 17:40:49 +02:00
Gabor Kiss-Vamosi
16f576319c docs update CHANGELOG for v8.0.1 2021-06-14 13:45:19 +02:00
Gabor Kiss-Vamosi
f2c6f5dc9c update verson numbers to v8.0.1 2021-06-14 13:41:36 +02:00
Gabor Kiss-Vamosi
f18e1eb967 docs(filesystem) update to v8 2021-06-14 13:29:23 +02:00
Gabor Kiss-Vamosi
4d334f5c72 fix(msgbox) create modals on top layer instead of act screen
To cover widgets on the top layer too
2021-06-14 13:29:07 +02:00
Gabor Kiss-Vamosi
7001f851da fix(colowheel) disable LV_OBJ_FLAG_SCROLL_CHAIN by default 2021-06-14 13:28:53 +02:00
Ali Rostami
b7e6230a89 docs(grid) typo fix (#2310) 2021-06-14 13:28:45 +02:00
dronecz
0c1105951d fix(arduino) fix the prototype of my_touchpad_read in the LVGL_Arduino.ino 2021-06-14 13:28:30 +02:00
Gabor Kiss-Vamosi
58a169d757 fix(meter) fix needle image invalidation
Fixes #2300
2021-06-14 13:28:22 +02:00
Gabor Kiss-Vamosi
3847fd5b46 fix(mem) add lv_ prefix to tlsf functions and types
It avoids collision if tlsf is used by other libs in the project too
Fixes https://github.com/lvgl/lvgl/issues/2116#issuecomment-857765919
2021-06-14 13:28:13 +02:00
Gabor Kiss-Vamosi
7793e8b730 fix(calendar) fix the position calculation today
Fixes https://forum.lvgl.io/t/calendar-widget-bug-in-v8-0/5763
2021-06-14 13:27:55 +02:00
Rop Gonggrijp
e0cd31fe95 docs(color) language fixes (#2302) 2021-06-14 13:26:11 +02:00
Gabor Kiss-Vamosi
26c7f48756 fix conflict 2021-06-14 13:25:58 +02:00
Rop Gonggrijp
1deff8ed03 Spelling and other language fixes to documentation (#2293) 2021-06-14 13:24:32 +02:00
Gabor Kiss-Vamosi
ad9de31a05 fix(theme) show disabled state on buttons of btnmatrix, msgbox and kayboard 2021-06-14 13:24:22 +02:00
Gabor Kiss-Vamosi
d4d88ac642 fix(scroll) keep the scroll position on object deleted 2021-06-14 13:24:13 +02:00
Gabor Kiss-Vamosi
0cd5a15969 fix(msgbox) handle NULL btn map paramter 2021-06-14 13:24:04 +02:00
Gabor Kiss-Vamosi
19a6cff016 fix(group) allow refocusing obejcts
But do not send defocus event if the same obejct is refocused
2021-06-14 13:23:55 +02:00
embeddedt
790e1078d5 docs(overview) spelling fixes 2021-06-14 13:23:47 +02:00
Gabor Kiss-Vamosi
db1e56a90e chore(docs) minor formatting on example's GitHub link 2021-06-14 13:23:16 +02:00
Themba Dube
f76c01b4ca feat(docs) add view on GitHub link 2021-06-14 13:23:03 +02:00
Themba Dube
42d191c679 chore(lv_conf_template) fix spelling mistake
Also forces the docs to rebuild.
2021-06-14 13:22:37 +02:00
Gabor Kiss-Vamosi
054d933742 fix(theme) fix the switch style in the default theme
LVGL didn't see that the styles were changed in checked state therefore the switch wasn't invalidated.
2021-06-14 13:22:21 +02:00
Gabor Kiss-Vamosi
57839d8e7d docs fix typo 2021-06-14 13:22:12 +02:00
Gabor Kiss-Vamosi
5ca2528bff feat(event) pass the scroll aniamtion to LV_EVENT_SCROLL_BEGIN
Also add lv_example_tabview_2 for demonstration
2021-06-14 13:21:27 +02:00
Gabor Kiss-Vamosi
1afcd1691f fix(tabview) fix with left and right tabs 2021-06-14 13:21:18 +02:00
Gabor Kiss-Vamosi
8e60f28432 fix(template) udpate lv_objx_template to v8 2021-06-14 13:21:00 +02:00
Ali Rostami
a4b7ef4f50 Update quick-overview.md (#2295)
* Update quick-overview.md

* Update quick-overview.md

* Update lv_example_get_started_3.c

* Update coords.md
2021-06-14 13:20:43 +02:00
Gabor Kiss-Vamosi
70911accf5 fix(pxp) change LV_COLOR_TRANSP to LV_COLOR_CHROMA_KEY to v8 compatibility
Fixes #2289
2021-06-14 13:20:36 +02:00
Gabor Kiss-Vamosi
a4d854291a docs(color) minor fix 2021-06-14 13:20:24 +02:00
Gabor Kiss-Vamosi
9446a9aecb fix(example) revert test code 2021-06-14 13:20:17 +02:00
Gabor Kiss-Vamosi
bb6b8037cd fix(draw) with additive blending with 32 bit color depth 2021-06-14 13:20:04 +02:00
Gabor Kiss-Vamosi
bd5c8c0e12 docs(color) update colors' docs 2021-06-14 13:19:54 +02:00
KSam
d83258ab4a docs(lv_obj_style) update add_style and remove_style function headers (#2287) 2021-06-14 13:19:38 +02:00
149 changed files with 2559 additions and 1796 deletions

View File

@@ -71,5 +71,21 @@ jobs:
BRANCH: gh-pages # The branch the action should deploy to.
FOLDER: out_html # The folder the action should deploy.
TARGET_FOLDER: ${{ steps.version.outputs.VERSION_NAME }}
GIT_CONFIG_NAME: lvgl-bot
GIT_CONFIG_EMAIL: lvgl-bot@users.noreply.github.com
PRESERVE: true
SINGLE_COMMIT: true
- name: Deploy to master
if: github.ref == 'refs/heads/master'
uses: JamesIves/github-pages-deploy-action@3.7.1
with:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
ACCESS_TOKEN: ${{ secrets.LVGL_BOT_TOKEN }}
REPOSITORY_NAME: lvgl/docs
BRANCH: gh-pages # The branch the action should deploy to.
FOLDER: out_html # The folder the action should deploy.
TARGET_FOLDER: master
GIT_CONFIG_NAME: lvgl-bot
GIT_CONFIG_EMAIL: lvgl-bot@users.noreply.github.com
PRESERVE: true
SINGLE_COMMIT: true

View File

@@ -65,3 +65,35 @@ file(GLOB_RECURSE SOURCES src/*.c)
add_library(lvgl STATIC ${SOURCES})
endif()
option(install "Enable install to system" OFF)
if(install)
include_directories(${CMAKE_SOURCE_DIR})
file(GLOB LVGL_PUBLIC_HEADERS
"${CMAKE_SOURCE_DIR}/lv_conf.h"
"${CMAKE_SOURCE_DIR}/lvgl.h")
if("${LIB_INSTALL_DIR}" STREQUAL "")
set(LIB_INSTALL_DIR "lib")
endif()
if("${INC_INSTALL_DIR}" STREQUAL "")
set(INC_INSTALL_DIR "include/lvgl")
endif()
install(DIRECTORY "${CMAKE_SOURCE_DIR}/src"
DESTINATION "${CMAKE_INSTALL_PREFIX}/${INC_INSTALL_DIR}/"
FILES_MATCHING
PATTERN "*.h")
set_target_properties(lvgl PROPERTIES
OUTPUT_NAME lvgl
ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lib"
PUBLIC_HEADER "${LVGL_PUBLIC_HEADERS}")
install(TARGETS lvgl
ARCHIVE DESTINATION "${LIB_INSTALL_DIR}"
PUBLIC_HEADER DESTINATION "${INC_INSTALL_DIR}")
endif(install)

View File

@@ -166,7 +166,7 @@ menu "LVGL configuration"
1: Add default bare metal and FreeRTOS interrupt handling
routines for PXP (lv_gpu_nxp_pxp_osa.c) and call
lv_gpu_nxp_pxp_init() automatically during lv_init().
Note that symbol FSL_RTOS_FREE_RTOS has to be defined in order
Note that symbol SDK_OS_FREE_RTOS has to be defined in order
to use FreeRTOS OSA, otherwise bare-metal implementation is
selected.
0: lv_gpu_nxp_pxp_init() has to be called manually before

View File

@@ -162,4 +162,3 @@ lv.scr_load(scr)
LVGL is an open project and contribution is very welcome. There are many ways to contribute from simply speaking about your project, through writing examples, improving the documentation, fixing bugs to hosing your own project under in LVGL.
For a detailed description of contribution opportunities visit the [Contributing](https://docs.lvgl.io/latest/en/html/contributing/index.html) section of the documentation.

View File

@@ -1,5 +1,103 @@
# Changelog
## v8.0.2 (16.07.2021)
- fix(theme) improve button focus of keyboard
- fix(tabview) send LV_EVENT_VALUE_CHANGED only once
- fix(imgbtn) use the correct src in LV_EVENT_GET_SELF_SIZE
- fix(color) remove extraneous cast for 8-bit color
- fix(obj style) fix children reposition if the parent's padding changes.
- fix(color) remove extraneous _LV_COLOR_MAKE_TYPE_HELPER (#2372)
- fix(spinner) should not be clickable (#2373)
- fix(obj) improve how the focusing indev is determined
- fix(template) update indev template for v8
- fix(printf) skip defining attribute if pycparser is used
- refactor(printf) add printf-like function attribute to _lv_txt_set_text_vfmt and lv_label_set_text_fmt (#2332)
- fix(template) include lvgl.h in lv_port_*_template.c files
- fix(obj) detecting which indev sent LV_EVENT_FOCUS
- fix (span) fill LV_EVENT_GET_SELF_SIZE (#2360)
- fix(arc) disable LV_OBJ_FLAG_SCROLL_CHAIN by default
- fix (draw) fix arc bg image drawing with full arcs
- fix(disp) fix memory leak in lv_disp_remove (#2355)
- fix warnigs introduced by 3fb8baf5
- fix(widgets) use lv_obj_class for all the widgets
- fix(obj) move clean ups from lv_obj_del to lv_obj_destructor
- fix(roller) fix partial redraw of the selected area
- fix(roller) adjust the size of the selected area correctly
- fix(obj) delete useless type conversion (#2343)
- fix(lv_obj_scroll.h) typos (#2345)
- fix(scroll) fire LV_EVENT_SCROLL_BEGIN in the same spot for both axes
- fix(btnmatrix) fix button invalidation on focus change
- fix(textarea) style update in oneline mode + improve sroll to cursor
- fix(tlsf) do not use <assert.h>
- fix(imgbtn) consider width==LV_SIZE_CONTENT if only mid. img is set
- fix(refr) reduce the nesting level in lv_refr_area
- fix(txt) enhance the function of break_chars (#2327)
- fix(pxp): update RTOS macro for SDK 2.10
- fix(vglite): update for v8
- fix(pxp): update for v8
- fix(flex) fix layout update and invalidation issues
- fix(flex) fix NULL pointer dereference
- fix(obj, switch) do not send LV_EVENT_VALUE_CHANGED twice
- fix(color) overflow with 16 bit color depth
- fix(coords) fix using large coordinates
- fix(chart) fix crash if no series are added
- fix(chart) invalidation with LV_CHART_UPDATE_MODE_SHIFT
- fix(align) fix lv_obj_align_to G
- fix(table) invalidate the table on cell value change
- fix(label) remove dupliacted lv_obj_refresh_self_size
- fix(draw) underflow in subpixel font drawing
- fix (scroll) do not send unnecessary scroll end events
## v8.0.1 (14.06.2021)
- docs(filesystem) update to v8 <a href="https://github.com/lvgl/lvgl/commit/7971ade4">7971ade4</a>
- fix(msgbox) create modals on top layer instead of act screen <a href="https://github.com/lvgl/lvgl/commit/5cf6303e">5cf6303e</a>
- fix(colowheel) disable LV_OBJ_FLAG_SCROLL_CHAIN by default <a href="https://github.com/lvgl/lvgl/commit/48d1c292">48d1c292</a>
- docs(grid) typo fix (#2310) <a href="https://github.com/lvgl/lvgl/commit/69d109d2">69d109d2</a>
- fix(arduino) fix the prototype of my_touchpad_read in the LVGL_Arduino.ino <a href="https://github.com/lvgl/lvgl/commit/1a62f7a6">1a62f7a6</a>
- fix(meter) fix needle image invalidation <a href="https://github.com/lvgl/lvgl/commit/54d8e817">54d8e817</a>
- fix(mem) add lv_ prefix to tlsf functions and types <a href="https://github.com/lvgl/lvgl/commit/0d52b59c">0d52b59c</a>
- fix(calendar) fix the position calculation today <a href="https://github.com/lvgl/lvgl/commit/ad05e196">ad05e196</a>
- fix(typo) rename LV_OBJ_FLAG_SNAPABLE to LV_OBJ_FLAG_SNAPPABLE <a href="https://github.com/lvgl/lvgl/commit/e697807c">e697807c</a>
- docs(color) language fixes (#2302) <a href="https://github.com/lvgl/lvgl/commit/07ecc9f1">07ecc9f1</a>
- fix(tick) minor optmization on lv_tick_inc call test <a href="https://github.com/lvgl/lvgl/commit/b4305df5">b4305df5</a>
- Spelling and other language fixes to documentation (#2293) <a href="https://github.com/lvgl/lvgl/commit/d0aaacaf">d0aaacaf</a>
- fix(theme) show disabled state on buttons of btnmatrix, msgbox and kayboard <a href="https://github.com/lvgl/lvgl/commit/0be582b3">0be582b3</a>
- fix(scroll) keep the scroll position on object deleted <a href="https://github.com/lvgl/lvgl/commit/52edbb46">52edbb46</a>
- fix(msgbox) handle NULL btn map paramter <a href="https://github.com/lvgl/lvgl/commit/769c4a30">769c4a30</a>
- fix(group) allow refocusing obejcts <a href="https://github.com/lvgl/lvgl/commit/1520208b">1520208b</a>
- docs(overview) spelling fixes <a href="https://github.com/lvgl/lvgl/commit/d2efb8c6">d2efb8c6</a>
- Merge branch 'master' of https://github.com/lvgl/lvgl <a href="https://github.com/lvgl/lvgl/commit/45960838">45960838</a>
- feat(timer) check if lv_tick_inc is called <a href="https://github.com/lvgl/lvgl/commit/aa6641a6">aa6641a6</a>
- feat(docs) add view on GitHub link <a href="https://github.com/lvgl/lvgl/commit/a716ac6e">a716ac6e</a>
- fix(theme) fix the switch style in the default theme <a href="https://github.com/lvgl/lvgl/commit/0c0dc8ea">0c0dc8ea</a>
- docs fix typo <a href="https://github.com/lvgl/lvgl/commit/8ab80645">8ab80645</a>
- Merge branch 'master' of https://github.com/lvgl/lvgl <a href="https://github.com/lvgl/lvgl/commit/e796448f">e796448f</a>
- feat(event) pass the scroll aniamtion to LV_EVENT_SCROLL_BEGIN <a href="https://github.com/lvgl/lvgl/commit/ca54ecfe">ca54ecfe</a>
- fix(tabview) fix with left and right tabs <a href="https://github.com/lvgl/lvgl/commit/17c57449">17c57449</a>
- chore(docs) force docs rebuild <a href="https://github.com/lvgl/lvgl/commit/4a0f4139">4a0f4139</a>
- chore(docs) always deploy master to docs/master as well <a href="https://github.com/lvgl/lvgl/commit/6d05692d">6d05692d</a>
- fix(template) udpate lv_objx_template to v8 <a href="https://github.com/lvgl/lvgl/commit/38bb8afc">38bb8afc</a>
- docs(extra) add extra/README.md <a href="https://github.com/lvgl/lvgl/commit/8cd504d5">8cd504d5</a>
- Update CHANGELOG.md <a href="https://github.com/lvgl/lvgl/commit/48fd73d2">48fd73d2</a>
- Update quick-overview.md (#2295) <a href="https://github.com/lvgl/lvgl/commit/5616471c">5616471c</a>
- fix(pxp) change LV_COLOR_TRANSP to LV_COLOR_CHROMA_KEY to v8 compatibility <a href="https://github.com/lvgl/lvgl/commit/81f3068d">81f3068d</a>
- adding micropython examples (#2286) <a href="https://github.com/lvgl/lvgl/commit/c60ed68e">c60ed68e</a>
- docs(color) minor fix <a href="https://github.com/lvgl/lvgl/commit/ac8f4534">ac8f4534</a>
- fix(example) revert test code <a href="https://github.com/lvgl/lvgl/commit/77e2c1ff">77e2c1ff</a>
- fix(draw) with additive blending with 32 bit color depth <a href="https://github.com/lvgl/lvgl/commit/786db2af">786db2af</a>
- docs(color) update colors' docs <a href="https://github.com/lvgl/lvgl/commit/9056b5ee">9056b5ee</a>
- Merge branch 'master' of https://github.com/lvgl/lvgl <a href="https://github.com/lvgl/lvgl/commit/a711a1dd">a711a1dd</a>
- perf(refresh) optimize where to wait for lv_disp_flush_ready with 2 buffers <a href="https://github.com/lvgl/lvgl/commit/d0172f14">d0172f14</a>
- docs(lv_obj_style) update add_style and remove_style function headers (#2287) <a href="https://github.com/lvgl/lvgl/commit/60f7bcbf">60f7bcbf</a>
- fix memory leak of spangroup (#2285) <a href="https://github.com/lvgl/lvgl/commit/33e0926a">33e0926a</a>
- fix make lv_img_cache.h public becasue cache invalidation is public <a href="https://github.com/lvgl/lvgl/commit/38ebcd81">38ebcd81</a>
- Merge branch 'master' of https://github.com/lvgl/lvgl <a href="https://github.com/lvgl/lvgl/commit/2b292495">2b292495</a>
- fix(btnmamatrix) fix focus event handling <a href="https://github.com/lvgl/lvgl/commit/3b58ef14">3b58ef14</a>
- Merge pull request #2280 from lvgl/dependabot/pip/docs/urllib3-1.26.5 <a href="https://github.com/lvgl/lvgl/commit/a2f45b26">a2f45b26</a>
- fix(label) calculating the clip area <a href="https://github.com/lvgl/lvgl/commit/57e211cc">57e211cc</a>
- chore(deps): bump urllib3 from 1.26.4 to 1.26.5 in /docs <a href="https://github.com/lvgl/lvgl/commit/b2f77dfc">b2f77dfc</a>
- fix(docs) add docs about the default group <a href="https://github.com/lvgl/lvgl/commit/29bfe604">29bfe604</a>
## v8.0.0 (01.06.2021)
v8.0 brings many new features like simplified and more powerful scrolling, new layouts inspired by CSS Flexbox and Grid, simplified and improved widgets, more powerful events, hookable drawing, and more.

View File

@@ -34,7 +34,7 @@ This Code of Conduct applies both within project spaces and in public spaces whe
## 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.
Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team using the [contact form](https://lvgl.io/about). All complaints will be reviewed and investigated and will result in a response that is deemed necessary and appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately.
Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership.

View File

@@ -1,14 +1,17 @@
from docutils.parsers.rst import Directive
import os
from docutils import nodes
from docutils.parsers.rst import Directive
from docutils.parsers.rst.directives.images import Image
from sphinx.directives.code import LiteralInclude
import os
class LvExample(Directive):
required_arguments = 3
def run(self):
example_path = self.arguments[0]
example_name = os.path.split(example_path)[1]
language = self.arguments[2]
node_list = []
env = self.state.document.settings.env
@@ -28,9 +31,9 @@ class LvExample(Directive):
except FileNotFoundError:
contents = 'Error encountered while trying to open ' + example_file
literal_list = nodes.literal_block(contents, contents)
literal_list['language'] = self.arguments[2]
literal_list['language'] = language
toggle.append(literal_list)
header.append(nodes.paragraph(text="code"))
header.append(nodes.raw(text=f"<p>code &nbsp; <a class='fa fa-github' href='https://github.com/lvgl/lvgl/blob/{env.config.repo_commit_hash}/examples/{example_path}.{language}'>&nbsp; view on GitHub</a></p>", format='html'))
if env.app.tags.has('html'):
node_list.append(paragraph_node)
node_list.append(toggle)
@@ -38,8 +41,7 @@ class LvExample(Directive):
def setup(app):
app.add_directive("lv_example", LvExample)
app.add_config_value("example_commit_hash", "", "env")
app.add_config_value("built_example_commit_hash", "", "env")
app.add_config_value("repo_commit_hash", "", "env")
return {
'version': '0.1',

View File

@@ -224,6 +224,9 @@ StandaloneHTMLBuilder.supported_image_types = [
smartquotes = False
_, repo_commit_hash = subprocess.getstatusoutput("git rev-parse HEAD")
# Example configuration for intersphinx: refer to the Python standard library.
def setup(app):

View File

@@ -14,7 +14,7 @@ For example ESP32 is a good candidate to create your UI with LVGL.
## Get the LVGL Ardunio library
LVGL can be installed via Arduino IDE Library Manager or as an .ZIP library.
LVGL can be installed via the Arduino IDE Library Manager or as a .ZIP library.
It will also install [lv_exmaples](https://github.com/lvgl/lv_examples) which contains a lot of examples and demos to try LVGL.
## Set up drivers
@@ -46,7 +46,7 @@ LVGL has its own configuration file called `lv_conf.h`. When LVGL is installed t
## Initialize LVGL and run an example
Take a look at [LVGL_Arduino.ino](https://github.com/lvgl/lvgl/blob/master/examples/LVGL_Arduino.ino) to see how to initialize LVGL.
It also uses TFT_eSPI as driver.
TFT_eSPI is used as the display driver.
In the INO file you can see how to register a display and a touch pad for LVGL and call an example.
@@ -55,9 +55,9 @@ For the full list of examples see the [README of lv_examples](https://github.com
## Debugging and logging
In case of trouble there are debug information inside LVGL.
In case of trouble LVGL can display debug information.
In the `LVGL_Arduino.ino` example there is `my_print` method, which allow to send this debug information to the serial interface.
To enable this feature you have to edit `lv_conf.h` file and enable logging in section `log settings`:
To enable this feature you have to edit `lv_conf.h` file and enable logging in the section `log settings`:
```c
/*Log settings*/
@@ -73,5 +73,5 @@ To enable this feature you have to edit `lv_conf.h` file and enable logging in s
# define LV_LOG_LEVEL LV_LOG_LEVEL_WARN
```
After enabling log module and setting LV_LOG_LEVEL accordingly the output log is sent to the `Serial` port @ 115200 Baud rate.
After enabling the log module and setting LV_LOG_LEVEL accordingly the output log is sent to the `Serial` port @ 115200 bps.

View File

@@ -4,7 +4,7 @@
```
# Get started
There are several ways to get your feet wet with LVGL. This list shows the recommended way of learning the library:
There are several ways to get your feet wet with LVGL. Here is one recommended order of documents to read and things to play with when you are learning to use LVGL:
1. Check the [Online demos](https://lvgl.io/demos) to see LVGL in action (3 minutes)
2. Read the [Introduction](https://docs.lvgl.io/latest/en/html/intro/index.html) page of the documentation (5 minutes)
3. Read the [Quick overview](https://docs.lvgl.io/latest/en/html/get-started/quick-overview.html) page of the documentation (15 minutes)

View File

@@ -33,8 +33,8 @@ In Micropython it's just **`Change code` > `Run`** ! You can even run commands i
### Micropython + LVGL could be used for:
- Fast prototyping GUI.
- Shorten the cycle of changing and fine-tuning the GUI.
- Model the GUI in a more abstract way by defining reusable composite objects, taking advantage of Python's language features such as Inheritance, Closures, List Comprehension, Generators, Exception Handling, Arbitrary Precision Integers and others.
- Shortening the cycle of changing and fine-tuning the GUI.
- Modelling the GUI in a more abstract way by defining reusable composite objects, taking advantage of Python's language features such as Inheritance, Closures, List Comprehension, Generators, Exception Handling, Arbitrary Precision Integers and others.
- Make LVGL accessible to a larger audience. No need to know C in order to create a nice GUI on an embedded system.
This goes well with [CircuitPython vision](https://learn.adafruit.com/welcome-to-circuitpython/what-is-circuitpython). CircuitPython was designed with education in mind, to make it easier for new or unexperienced users to get started with embedded development.
- Creating tools to work with LVGL at a higher level (e.g. drag-and-drop designer).
@@ -82,15 +82,15 @@ Micropython is ported to many platforms. One notable port is "unix", which allow
### Embedded platform
At the end, the goal is to run it all on an embedded platform.
In the end, the goal is to run it all on an embedded platform.
Both Micropython and LVGL can be used on many embedded architectures, such as stm32, ESP32 etc.
You would also need display and input drivers. We have some sample drivers (ESP32+ILI9341, as well as some other examples), but most chances are you would want to create your own input/display drivers for your specific purposes.
Drivers can be implemented either in C as Micropython module, or in pure Micropython!
You would also need display and input drivers. We have some sample drivers (ESP32+ILI9341, as well as some other examples), but chances are you would want to create your own input/display drivers for your specific hardware.
Drivers can be implemented either in C as a Micropython module, or in pure Micropython!
## Where can I find more information?
- On the [Blog Post](https://blog.lvgl.io/2019-02-20/micropython-bindings)
- On `lv_micropython` [README](https://github.com/lvgl/lv_micropython)
- On `lv_binding_micropython` [README](https://github.com/lvgl/lv_binding_micropython)
- On LVGL forum (Feel free to ask anything!)
- On Micropython [docs](http://docs.micropython.org/en/latest/) and [forum](https://forum.micropython.org/)
- In this [Blog Post](https://blog.lvgl.io/2019-02-20/micropython-bindings)
- `lv_micropython` [README](https://github.com/lvgl/lv_micropython)
- `lv_binding_micropython` [README](https://github.com/lvgl/lv_binding_micropython)
- The [LVGL micropython forum](https://forum.lvgl.io/c/micropython) (Feel free to ask anything!)
- At Micropython: [docs](http://docs.micropython.org/en/latest/) and [forum](https://forum.micropython.org/)

View File

@@ -7,50 +7,50 @@
## What is NuttX?
[NuttX](https://nuttx.apache.org/) is a mature and secure real-time operating system (RTOS) with an emphasis on technical standards compliance and small size.
It is scalable from 8-bit to 64-bit microcontroller and microprocessors. Complaint with the Portable Operating System Interface (POSIX) and the American National Standards Institute (ANSI) standards and with many Linux-like subsystems.
The best way to think about NuttX is thinking about a small Unix/Linux for microcontrollers.
It is scalable from 8-bit to 64-bit microcontrollers and microprocessors and compliant with the Portable Operating System Interface (POSIX) and the American National Standards Institute (ANSI) standards and with many Linux-like subsystems.
The best way to think about NuttX is to think of it as a small Unix/Linux for microcontrollers.
### Highlights of NuttX
- **Small** - Fits and runs within small microcontroller as small was 32KB Flash and 8KB of RAM.
- **Small** - Fits and runs in microcontrollers as small as 32KB Flash and 8KB of RAM.
- **Compliant** - Strives to be as compatible as possible with POSIX and Linux.
- **Versatile** - Supports many architectures (ARM, ARM Thumb, AVR, MIPS, OpenRISC, RISC-V 32-bit and 64-bit, RX65N, x86-64, Xtensa, Z80/Z180, etc).
- **Modular** - Its modular design allow developers to select only what really matters and use modules to include new features.
- **Modular** - Its modular design allows developers to select only what really matters and use modules to include new features.
- **Popular** - NuttX is used by many companies around the world. Probably you already used a product with NuttX without knowing it was running NuttX.
- **Predictable** - NuttX is a preemptible Realtime kernel, then you can use it to create predictable applications for realtime control.
- **Predictable** - NuttX is a preemptible Realtime kernel, so you can use it to create predictable applications for realtime control.
---
## Why NuttX + LVGL?
Although NuttX has its own graphic library called [NX](https://cwiki.apache.org/confluence/pages/viewpage.action?pageId=139629474), LVGL is a good alternative because users could find more eyes-candy demos and reuse it from previous projects.
Although NuttX has its own graphic library called [NX](https://cwiki.apache.org/confluence/pages/viewpage.action?pageId=139629474), LVGL is a good alternative because users could find more eye-candy demos and they can reuse code from previous projects.
LVGL is an [Object Oriented Component Based](https://blog.lvgl.io/2018-12-13/extend-lvgl-objects) high-level GUI library, that could fit very well for a RTOS with advanced features like NuttX.
LVGL is implemented in C and its APIs are in C.
### Here are some advantages of using LVGL in NuttX
- Develop GUI in Linux first and when it is done just compile it for NuttX, nothing more, no wasting of time.
- Usually, GUI development for low level RTOS requires multiple iterations to get things right. Where each iteration consists of **`Change code` > `Build` > `Flash` > `Run`**.
- Develop GUI in Linux first and when it is done just compile it for NuttX. Nothing more, no wasting of time.
- Usually, GUI development for low level RTOS requires multiple iterations to get things right, where each iteration consists of **`Change code` > `Build` > `Flash` > `Run`**.
Using LVGL, Linux and NuttX you can reduce this process and just test everything on your computer and when it is done, compile it on NuttX and that is it.
### NuttX + LVGL could be used for
- GUI demos to demonstrate your board graphics capacities.
- Fast prototyping GUI for MVP (Minimum Viable Product) presentation.
- Easy way to visualize sensors data directly on the board without using a computer.
- Final products GUI without touchscreen (i.e. 3D Printer Interface using Rotary Encoder to Input data).
- Final products interface with touchscren (and bells and whistles).
- visualize sensor data directly and easily on the board without using a computer.
- Final products with a GUI without a touchscreen (i.e. 3D Printer Interface using Rotary Encoder to Input data).
- Final products with a touchscreen (and all sorts of bells and whistles).
---
## How to get started with NuttX and LVGL?
There are many boards in the NuttX mainline (https://github.com/apache/incubator-nuttx) with support for LVGL.
Let's to use the [STM32F429IDISCOVERY](https://www.st.com/en/evaluation-tools/32f429idiscovery.html) as example because it is a very popular board.
Let's use the [STM32F429IDISCOVERY](https://www.st.com/en/evaluation-tools/32f429idiscovery.html) as example because it is a very popular board.
### First you need to install the pre-requisite on your system
Let's to use Linux and example, for [Windows](https://acassis.wordpress.com/2018/01/10/how-to-build-nuttx-on-windows-10/)
Let's use the [Windows Subsystem for Linux](https://acassis.wordpress.com/2018/01/10/how-to-build-nuttx-on-windows-10/)
```shell
$ sudo apt-get install automake bison build-essential flex gcc-arm-none-eabi gperf git libncurses5-dev libtool libusb-dev libusb-1.0.0-dev pkg-config kconfig-frontends openocd
@@ -96,6 +96,6 @@ nsh> lvgldemo
## Where can I find more information?
- On the [LVGL on LPCXpresso54628](https://acassis.wordpress.com/2018/07/19/running-nuttx-on-lpcxpresso54628-om13098/)
- NuttX mailing list [Apache NuttX Mailing List](http://nuttx.incubator.apache.org/community/)
- This blog post: [LVGL on LPCXpresso54628](https://acassis.wordpress.com/2018/07/19/running-nuttx-on-lpcxpresso54628-om13098/)
- NuttX mailing list: [Apache NuttX Mailing List](http://nuttx.incubator.apache.org/community/)

View File

@@ -5,13 +5,13 @@
# Simulator on PC
You can try out the LVGL **using only your PC** (i.e. without any development boards). The LVGL will run on a simulator environment on the PC where anyone can write and experiment the real LVGL applications.
You can try out LVGL **using only your PC** (i.e. without any development boards). LVGL will run on a simulator environment on the PC where anyone can write and experiment the real LVGL applications.
Simulator on the PC have the following advantages:
- Hardware independent - Write a code, run it on the PC and see the result on the PC monitor.
- Cross-platform - Any Windows, Linux or OSX PC can run the PC simulator.
Using the simulator on the PC has the following advantages:
- Hardware independent - Write code, run it on the PC and see the result on the PC monitor.
- Cross-platform - Any Windows, Linux or MacOS system can run the PC simulator.
- Portability - the written code is portable, which means you can simply copy it when using an embedded hardware.
- Easy Validation - The simulator is also very useful to report bugs because it means common platform for every user. So it's a good idea to reproduce a bug in simulator and use the code snippet in the [Forum](https://forum.lvgl.io).
- Easy Validation - The simulator is also very useful to report bugs because it means common platform for every user. So it's a good idea to reproduce a bug in the simulator and use the code snippet in the [Forum](https://forum.lvgl.io).
## Select an IDE
@@ -23,7 +23,7 @@ The simulator is ported to various IDEs (Integrated Development Environments). C
- [VSCode with SDL driver](https://github.com/lvgl/lv_sim_vscode_sdl): Recommended on Linux and Mac
- [PlatformIO with SDL driver](https://github.com/lvgl/lv_platformio): Recommended on Linux and Mac
You can use any IDEs for the development but, for simplicity, the configuration for Eclipse CDT is focused in this tutorial.
You can use any IDE for the development but, for simplicity, the configuration for Eclipse CDT is what we'll focus on in this tutorial.
The following section describes the set-up guide of Eclipse CDT in more details.
**Note: If you are on Windows, it's usually better to use the Visual Studio or CodeBlocks projects instead. They work out of the box without requiring extra steps.**
@@ -91,8 +91,8 @@ On **Windows** you have to do two additional things:
### Compile and Run
Now you are ready to run the LVGL Graphics Library on your PC. Click on the Hammer Icon on the top menu bar to Build the project. If you have done everything right, then you will not get any errors. Note that on some systems additional steps might be required to "see" SDL 2 from Eclipse but, in most of cases the configurations in the downloaded project is enough.
Now you are ready to run LVGL on your PC. Click on the Hammer Icon on the top menu bar to Build the project. If you have done everything right, then you will not get any errors. Note that on some systems additional steps might be required to "see" SDL 2 from Eclipse but, in most of cases the configurations in the downloaded project is enough.
After a success build, click on the Play button on the top menu bar to run the project. Now a window should appear in the middle of your screen.
Now everything is ready to use the LVGL in the practice or begin the development on your PC.
Now you are ready to use LVGL and begin development on your PC.

View File

@@ -6,41 +6,41 @@
# Quick overview
Here you can learn the most important things about LVGL.
You should read it first to get a general impression and read the detailed [Porting](/porting/index) and [Overview](/overview/index) sections after that.
You should read this first to get a general impression and read the detailed [Porting](/porting/index) and [Overview](/overview/index) sections after that.
## Get started in a simulator
Instead of porting LVGL to an embedded hardware, it's highly recommended to get started in a simulator first.
Instead of porting LVGL to embedded hardware straight away, it's highly recommended to get started in a simulator first.
LVGL is ported to many IDEs to be sure you will find your favorite one.
Go to the [Simulators](/get-started/pc-simulator) section to get ready-to-use projects that can be run on your PC.
This way you can save the time of porting for now and make some experience with LVGL immediately.
This way you can save the time of porting for now and get some experience with LVGL immediately.
## Add LVGL into your project
If you rather want to try LVGL on your own project follow these steps:
If you would rather try LVGL on your own project follow these steps:
- [Download](https://github.com/lvgl/lvgl/archive/master.zip) or Clone the library from GitHub with `git clone https://github.com/lvgl/lvgl.git`.
- [Download](https://github.com/lvgl/lvgl/archive/master.zip) or clone the library from GitHub with `git clone https://github.com/lvgl/lvgl.git`.
- Copy the `lvgl` folder into your project.
- Copy `lvgl/lv_conf_template.h` as `lv_conf.h` next to the `lvgl` folder, change the first `#if 0` to `1` to enable the file's content and set the `LV_COLOR_DEPTH` defines.
- Include `lvgl/lvgl.h` in files where you need to use LVGL related functions.
- Call `lv_tick_inc(x)` every `x` milliseconds in a Timer or Task (`x` should be between 1 and 10). It is required for the internal timing of LVGL.
Alternatively, configure `LV_TICK_CUSTOM` (see `lv_conf.h`) so that LVGL can retrieve the current time directly.
- Call `lv_init()`
- Create a draw buffer: LVGL will render the graphics here first, and seed the rendered image to the display.
- Create a draw buffer: LVGL will render the graphics here first, and send the rendered image to the display.
The buffer size can be set freely but 1/10 screen size is a good starting point.
```c
static lv_disp_darw_buf_t draw_buf;
static lv_disp_draw_buf_t draw_buf;
static lv_color_t buf1[DISP_HOR_RES * DISP_VER_RES / 10]; /*Declare a buffer for 1/10 screen size*/
lv_disp_draw_buf_init(&draw_buf, buf1, NULL, MY_DISP_HOR_RES * MY_DISP_VER_SER / 10); /*Initialize the display buffer.*/
```
- Implement and register a function which can copy the rendered image to an area of your display:
```c
lv_disp_drv_t disp_drv; /*Descriptor of a display driver*/
static lv_disp_drv_t disp_drv; /*Descriptor of a display driver*/
lv_disp_drv_init(&disp_drv); /*Basic initialization*/
disp_drv.flush_cb = my_disp_flush; /*Set your driver function*/
disp_drv.buffer = &draw_buf; /*Assign the buffer to the display*/
disp_drv.hor_res = MY_DISP_HOR_RES; /*Set the horizontal resolution of the display*/
disp_drv.hor_res = MY_DISP_VER_RES; /*Set the verizontal resolution of the display*/
disp_drv.ver_res = MY_DISP_VER_RES; /*Set the vertical resolution of the display*/
lv_disp_drv_register(&disp_drv); /*Finally register the driver*/
void my_disp_flush(lv_disp_drv_t * disp, const lv_area_t * area, lv_color_t * color_p)
@@ -61,13 +61,13 @@ void my_disp_flush(lv_disp_drv_t * disp, const lv_area_t * area, lv_color_t * co
```
- Implement and register a function which can read an input device. E.g. for a touch pad:
```c
lv_indev_drv_t indev_drv; /*Descriptor of a input device driver*/
static lv_indev_drv_t indev_drv; /*Descriptor of a input device driver*/
lv_indev_drv_init(&indev_drv); /*Basic initialization*/
indev_drv.type = LV_INDEV_TYPE_POINTER; /*Touch pad is a pointer-like device*/
indev_drv.read_cb = my_touchpad_read; /*Set your driver function*/
lv_indev_drv_register(&indev_drv); /*Finally register the driver*/
bool my_touchpad_read(lv_indev_t * indev, lv_indev_data_t * data)
void my_touchpad_read(lv_indev_t * indev, lv_indev_data_t * data)
{
/*`touchpad_is_pressed` and `touchpad_get_xy` needs to be implemented by you*/
if(touchpad_is_pressed()) {
@@ -79,7 +79,7 @@ bool my_touchpad_read(lv_indev_t * indev, lv_indev_data_t * data)
}
```
- Call `lv_timer_handler()` periodically every few milliseconds in the main `while(1)` loop or in an Operation system task.
- Call `lv_timer_handler()` periodically every few milliseconds in the main `while(1)` loop or in an operating system task.
It will redraw the screen if required, handle input devices, animation etc.
For a more detailed guide go to the [Porting](/porting/index) section.
@@ -90,11 +90,11 @@ For a more detailed guide go to the [Porting](/porting/index) section.
The graphical elements like Buttons, Labels, Sliders, Charts etc. are called objects or widgets. Go to [Widgets](/widgets/index) to see the full list of available widgets.
Every object has a parent object where it is create. For example if a label is created on a button, the button is the parent of label.
Every object has a parent object where it is created. For example if a label is created on a button, the button is the parent of label.
The child object moves with the parent and if the parent is deleted the children will be deleted too.
Children can be visible only on their parent. It other words, the parts of the children out of the parent are clipped.
Children can be visible only on their parent. It other words, the parts of the children outside of the parent are clipped.
A Screen is the "root" parent. You can have any number of screens.
@@ -107,14 +107,14 @@ For example:
lv_obj_t * slider1 = lv_slider_create(lv_scr_act());
```
To set some basic attribute `lv_obj_set_<paramters_name>(obj, <value>)` function can be used. For example:
To set some basic attributes `lv_obj_set_<parameter_name>(obj, <value>)` functions can be used. For example:
```c
lv_obj_set_x(btn1, 30);
lv_obj_set_y(btn1, 10);
lv_obj_set_size(btn1, 200, 50);
```
The widgets have type specific parameters too which can be set by `lv_<widget_type>_set_<paramters_name>(obj, <value>)` functions. For example:
The widgets have type specific parameters too which can be set by `lv_<widget_type>_set_<parameter_name>(obj, <value>)` functions. For example:
```c
lv_slider_set_value(slider1, 70, LV_ANIM_ON);
```
@@ -124,10 +124,10 @@ To see the full API visit the documentation of the widgets or the related header
### Events
Events are used to inform the user if something has happened with an object.
Events are used to inform the user that something has happened with an object.
You can assign one or more callbacks to an object which will be called if the object is clicked, released, dragged, being deleted etc.
It should look like this:
A callback is assigned like this:
```c
lv_obj_add_event_cb(btn, btn_event_cb, LV_EVENT_CLICKED, NULL); /*Assign a callback to the button*/
@@ -170,15 +170,15 @@ The objects can be in a combination of the following states:
- `LV_STATE_FOCUS_KEY` Focused via keypad or encoder but not via touchpad/mouse
- `LV_STATE_EDITED` Edit by an encoder
- `LV_STATE_HOVERED` Hovered by mouse (not supported now)
- `LV_STATE_PRESSED` eing pressed
- `LV_STATE_PRESSED` Being pressed
- `LV_STATE_SCROLLED` Being scrolled
- `LV_STATE_DISABLED` Disabled
For example, if you press an object it will automatically goes to `LV_STATE_FOCUSED` and `LV_STATE_PRESSED` state and when you release it, the `LV_STATE_PRESSED` state will be removed.
For example, if you press an object it will automatically go to `LV_STATE_FOCUSED` and `LV_STATE_PRESSED` state and when you release it, the `LV_STATE_PRESSED` state will be removed.
To check if an object is in a geven state use `lv_obj_has_state(obj, LV_STATE_...)`. It will return `true` if the object "has" the given state at that moment.
To check if an object is in a given state use `lv_obj_has_state(obj, LV_STATE_...)`. It will return `true` if the object is in that state at that time.
To manually add remove the states use
To manually add or remove states use
```c
lv_obj_add_state(obj, LV_STATE_...);
lv_obj_clear_state(obj, LV_STATE_...);
@@ -195,7 +195,7 @@ lv_style_init(&style1);
lv_style_set_bg_color(&style1, lv_color_hex(0xa03080))
lv_style_set_border_width(&style1, 2))
```
See the full list of properties go [here](/overview/style.html#properties).
See the full list of properties [here](/overview/style.html#properties).
The styles are assigned to an object's part and state. For example to *"Use this style on the slider's indicator when the slider is pressed"*:
@@ -230,15 +230,15 @@ lv_obj_add_style(btn1, &style1_btn_red, 0);
If a property is not set on for the current state the style with `LV_STATE_DEFAULT` will be used. If the property is not defined even in the default state a default value is used.
Some properties (typically the text-related ones) can be inherited. It means if a property is not set in an object it will be searched in its parents too.
For example, you can set the font once in the screen's style and every text will inherit it by default.
For example, you can set the font once in the screen's style and all text on that screen will inherit it by default.
Local style properties also can be added to the objects. It creates a style is inside the object that is used only by the object:
Local style properties also can be added to the objects. It creates a style which resides inside the object and which is used only by the object:
```c
lv_obj_set_style_bg_color(slider1, lv_color_hex(0x2080bb), LV_PART_INDICATOR | LV_STATE_PRESSED);
```
To learn all the features of styles see the [Style overview](/overview/style) section
To learn all the features of styles see the [Style overview](/overview/style) section.
### Themes

View File

@@ -5,20 +5,20 @@
# Introduction
LVGL (Light and Versatile Graphics Library) is a free and open-source graphics library providing everything you need to create embedded GUI with easy-to-use graphical elements, beautiful visual effects and low memory footprint.
LVGL (Light and Versatile Graphics Library) is a free and open-source graphics library providing everything you need to create embedded GUI with easy-to-use graphical elements, beautiful visual effects and a low memory footprint.
## Key features
- Powerful building blocks such as buttons, charts, lists, sliders, images etc.
- Powerful building blocks such as buttons, charts, lists, sliders, images, etc.
- Advanced graphics with animations, anti-aliasing, opacity, smooth scrolling
- Various input devices such as touchpad, mouse, keyboard, encoder etc.
- Various input devices such as touchpad, mouse, keyboard, encoder, etc.
- Multi-language support with UTF-8 encoding
- Multi-display support, i.e. use more TFT, monochrome displays simultaneously
- Fully customizable graphic elements withh CSS-like styles
- Hardware independent to use with any microcontroller or display
- Scalable to operate with little memory (64 kB Flash, 16 kB RAM)
- OS, External memory and GPU supported but not required
- Single frame buffer operation even with advanced graphical effects
- Multi-display support, i.e. use multiple TFT, monochrome displays simultaneously
- Fully customizable graphic elements with CSS-like styles
- Hardware independent: use with any microcontroller or display
- Scalable: able to operate with little memory (64 kB Flash, 16 kB RAM)
- OS, external memory and GPU supported but not required
- Single frame buffer operation even with advanced graphic effects
- Written in C for maximal compatibility (C++ compatible)
- Simulator to start embedded GUI design on a PC without embedded hardware
- Binding to MicroPython
@@ -48,23 +48,23 @@ Basically, every modern controller  (which is able to drive a display) is suita
<a href="https://www.tutorialspoint.com/cprogramming/c_structures.htm">structs</a>,
<a href="https://www.geeksforgeeks.org/callbacks-in-c/">callbacks</a>.</li>
</ul>
<em>Note that the memory usage might vary depending on the architecture, compiler and build options.</em>
<em>Note that memory usage may vary depending on architecture, compiler and build options.</em>
## License
The LVGL project (including all repositories) is licensed under [MIT license](https://github.com/lvgl/lvgl/blob/master/LICENCE.txt).
It means you can use it even in commercial projects.
It's not mandatory but we highly appreciate it if you write a few words about your project in the [My projects](https://forum.lvgl.io/c/my-projects/10) category of the Forum or a private message from [lvgl.io](https://lvgl.io/#contact).
It's not mandatory but we highly appreciate it if you write a few words about your project in the [My projects](https://forum.lvgl.io/c/my-projects/10) category of the forum or a private message to [lvgl.io](https://lvgl.io/#contact).
Although you can get LVGL for free there is a huge work behind it. It's created by a group of volunteers who made it available for you in their free time.
Although you can get LVGL for free there is a massive amount of work behind it. It's created by a group of volunteers who made it available for you in their free time.
To make the LVGL project sustainable, please consider [Contributing](/CONTRIBUTING) to the project.
You can choose from [many ways of contributions](/CONTRIBUTING) such as simply writing a tweet about you are using LVGL, fixing bugs, translating the documentation, or even becoming a maintainer.
To make the LVGL project sustainable, please consider [contributing](/CONTRIBUTING) to the project.
You can choose from [many different ways of contributing](/CONTRIBUTING) such as simply writing a tweet about you are using LVGL, fixing bugs, translating the documentation, or even becoming a maintainer.
## Repository layout
All repositories of the LVGL project are hosted n GitHub: https://github.com/lvgl
All repositories of the LVGL project are hosted on GitHub: https://github.com/lvgl
You find these repositories there:
You will find these repositories there:
- [lvgl](https://github.com/lvgl/lvgl) The library itself with many [examples](https://github.com/lvgl/lvgl/blob/master/examples/).
- [lv_demos](https://github.com/lvgl/lv_demos) Demos created with LVGL.
- [lv_drivers](https://github.com/lvgl/lv_drivers) Display and input device drivers
@@ -86,7 +86,7 @@ Tags like `vX.Y.Z` are created for every release.
### Release cycle
- Bugfixes: Released on demand even weekly
- Minor releases: In every 3-4 month
- Minor releases: Every 3-4 months
- Major releases: Approximatelly yearly
### Branches
@@ -102,7 +102,7 @@ The core repositories have at least the following branches:
The changes are recorded in [CHANGELOG.md](/CHANGELOG).
### Version support
Before v8 every minor release of major releases are supproted for 1 year.
Before v8 every minor release of major releases is supported for 1 year.
From v8 every minor release is supported for 1 year.
| Version | Release date | Support end | Active |
@@ -116,7 +116,7 @@ From v8 every minor release is supported for 1 year.
## FAQ
### Where can I ask questions?
You can ask questions in the Forum: [https://forum.lvgl.io/](https://forum.lvgl.io/).
You can ask questions in the forum: [https://forum.lvgl.io/](https://forum.lvgl.io/).
We use [GitHub issues](https://github.com/lvgl/lvgl/issues) for development related discussion.
So you should use them only if your question or issue is tightly related to the development of the library.
@@ -124,10 +124,10 @@ So you should use them only if your question or issue is tightly related to the
### Is my MCU/hardware supported?
Every MCU which is capable of driving a display via Parallel port, SPI, RGB interface or anything else and fulfills the [Requirements](#requirements) is supported by LLVGL.
It includes:
This includes:
- "Common" MCUs like STM32F, STM32H, NXP Kinetis, LPC, iMX, dsPIC33, PIC32 etc.
- Bluetooth, GSM, WiFi modules like Nordic NRF and Espressif ESP32
- Linux frame buffer like /dev/fb0 which includes Single-board computers too like Raspberry Pi
- Linux with frame buffer device such as /dev/fb0. This includes Single-board computers like the Raspberry Pi
- And anything else with a strong enough MCU and a periphery to drive a display
### Is my display supported?
@@ -149,11 +149,11 @@ Be sure you are calling `lv_tick_inc(x)` in an interrupt and `lv_timer_handler()
Learn more in the [Tick](/porting/tick) and [Task handler](/porting/task-handler) section.
### Why the display driver is called only once? Only the upper part of the display is refreshed.
### Why is the display driver called only once? Only the upper part of the display is refreshed.
Be sure you are calling `lv_disp_flush_ready(drv)` at the end of your "*display flush callback*".
### Why I see only garbage on the screen?
Probably there a bug in your display driver. Try the following code without using LVGL. You should see a square with red-blue gradient
### Why do I see only garbage on the screen?
Probably there a bug in your display driver. Try the following code without using LVGL. You should see a square with red-blue gradient.
```c
#define BUF_W 20
@@ -178,7 +178,7 @@ a.y2 = a.y1 + BUF_H - 1;
my_flush_cb(NULL, &a, buf);
```
### Why I see non-sense colors on the screen?
### Why I see nonsense colors on the screen?
Probably LVGL's color format is not compatible with your displays color format. Check `LV_COLOR_DEPTH` in *lv_conf.h*.
If you are using 16 bit colors with SPI (or other byte-oriented interface) probably you need to set `LV_COLOR_16_SWAP  1` in *lv_conf.h*.

View File

@@ -9,11 +9,11 @@
The Flexbox (or Flex for short) is a subset of [CSS Flexbox](https://css-tricks.com/snippets/css/a-guide-to-flexbox/).
It can arrange items into rows or columns (tracks), handle wrapping, adjust the spacing between the items and tracks, handle *grow* to make the item(s) will the remaining space with respect to min/max width and height.
It can arrange items into rows or columns (tracks), handle wrapping, adjust the spacing between the items and tracks, handle *grow* to make the item(s) fill the remaining space with respect to min/max width and height.
To make an object flex container call `lv_obj_set_layout(obj, LV_LAYOUT_FLEX)`.
Note that, the flex layout needs to enabled with `LV_USE_FLEX` in `lv_conf.h`.
Note that the flex layout feature of LVGL needs to be globally enabled with `LV_USE_FLEX` in `lv_conf.h`.
## Terms
- tracks: the rows or columns
@@ -26,13 +26,13 @@ The available space will be distributed among items respective to the their grow
## Simple interface
With follwoing functions you can simple set a Flex layout on any parent.
With the following functions you can set a Flex layout on any parent.
### Flex flow
`lv_obj_set_flex_flow(obj, felx_flow)`
`lv_obj_set_flex_flow(obj, flex_flow)`
The possible values for `felx_flow` are:
The possible values for `flex_flow` are:
- `LV_FLEX_FLOW_ROW` Place the children in a row without wrapping
- `LV_FLEX_FLOW_COLUMN` Place the children in a column without wrapping
- `LV_FLEX_FLOW_ROW_WRAP` Place the children in a row with wrapping
@@ -45,15 +45,15 @@ The possible values for `felx_flow` are:
### Flex align
To manage the placement of the children use `lv_obj_set_flex_align(obj, main_place, cross_place, track_cross_place)`
- `main_place` tells how to distribute the items in their track on the main axis. E.g. flush the items to the right on `LV_FLEX_FLOW_ROW_WRAP`. (It's called `justify-content` in CSS)
- `cross_place` tells how to distribute the items in their track on the cross axis. E.g. if the items have differetn height place them to the bottom of the track. (It's called `align-items` in CSS)
- `track_cross_place` tells how to distribute the tracks (It's called `align-content` in CSS)
- `main_place` determines how to distribute the items in their track on the main axis. E.g. flush the items to the right on `LV_FLEX_FLOW_ROW_WRAP`. (It's called `justify-content` in CSS)
- `cross_place` determines how to distribute the items in their track on the cross axis. E.g. if the items have different height place them to the bottom of the track. (It's called `align-items` in CSS)
- `track_cross_place` determines how to distribute the tracks (It's called `align-content` in CSS)
The possible values are:
- `LV_FLEX_ALIGN_START` means left on a horizontally and top vertically. (default)
- `LV_FLEX_ALIGN_END` means right on a horizontally and bottom vertically
- `LV_FLEX_ALIGN_CENTER` simply center
- `LV_FLEX_ALIGN_SPACE_EVENLY` items are distributed so that the spacing between any two items (and the space to the edges) is equal. Not applies to `track_cross_place`.
- `LV_FLEX_ALIGN_SPACE_EVENLY` items are distributed so that the spacing between any two items (and the space to the edges) is equal. Does not apply to `track_cross_place`.
- `LV_FLEX_ALIGN_SPACE_AROUND` items are evenly distributed in the track with equal space around them.
Note that visually the spaces arent equal, since all the items have equal space on both sides.
The first item will have one unit of space against the container edge, but two units of space between the next item because that next item has its own spacing that applies. Not applies to `track_cross_place`.
@@ -66,7 +66,7 @@ Flex grow can be used to make one or more children fill the available space on t
For example let's there is 400 px remaining space and 4 object with grow:
- `A` with grow = 1
- `B` with grow = 1
- `c` with grow = 2
- `C` with grow = 2
`A` and `B` will have 100 px size, and `C` will have 200 px size.
@@ -75,7 +75,7 @@ Flex grow can be set on a child with `lv_obj_set_flex_flow(child, value)`. `valu
## Style interface
All the Flex related values are style properties under the hood and you can use them similarly to any other style property. The following flex related style properties exist:
All the Flex-related values are style properties under the hood and you can use them similarly to any other style property. The following flex related style properties exist:
- `FLEX_FLOW`
- `FLEX_MAIN_PLACE`

View File

@@ -12,9 +12,9 @@ The Grid layout is a subset of [CSS Flexbox](https://css-tricks.com/snippets/css
It can arrange items into 2D "table" that has rows or columns (tracks). The item can span through multiple columns or rows.
The track's size can be set in pixel, to the largest item (`LV_GRID_CONTENT`) or in "Free unit" (FR) to distribute the free space proportionally.
To make an object grid container call `lv_obj_set_layout(obj, LV_LAYOUT_GRID)`.
To make an object a grid container call `lv_obj_set_layout(obj, LV_LAYOUT_GRID)`.
Note that, the grid layout needs to enabled with `LV_USE_GRID` in `lv_conf.h`.
Note that the grid layout feature of LVGL needs to be globally enabled with `LV_USE_GRID` in `lv_conf.h`.
## Terms
- tracks: the rows or columns
@@ -23,11 +23,11 @@ Note that, the grid layout needs to enabled with `LV_USE_GRID` in `lv_conf.h`.
## Simple interface
With the following functions you can simple set a Grid layout on any parent.
With the following functions you can easily set a Grid layout on any parent.
### Grid descriptors
First you need to describe the size of rows and columns. It can be done by declaring 2 arrays and the the track sizes in them. The last element must be `LV_GRID_TEMPLATE_LAST`.
First you need to describe the size of rows and columns. It can be done by declaring 2 arrays and the track sizes in them. The last element must be `LV_GRID_TEMPLATE_LAST`.
For example:
```
@@ -42,11 +42,11 @@ Besides simple settings the size in pixel you can use two special values:
- `LV_GRID_FR(X)` tell what portion of the remaining space should be used by this track. Larger value means larger space.
### Grid items
By default the children are not added to the grid but they needs to be added manually to a cell.
By default the children are not added to the grid. They need to be added manually to a cell.
To to this call `lv_obj_set_grid_cell(child, column_align, column_pos, column_span, row_align, row_pos, row_span)`.
To do this call `lv_obj_set_grid_cell(child, column_align, column_pos, column_span, row_align, row_pos, row_span)`.
`column_align` and `row_align` tells how to align the children in its cell. The possible values are:
`column_align` and `row_align` determine how to align the children in its cell. The possible values are:
- `LV_GRID_ALIGN_START` means left on a horizontally and top vertically. (default)
- `LV_GRID_ALIGN_END` means right on a horizontally and bottom vertically
- `LV_GRID_ALIGN_CENTER` simply center
@@ -87,7 +87,7 @@ All the Grid related values are style properties under the hood and you can use
## Other features
### RTL
If the base direction of the container is set the `LV_BASE_DIR_RTL` the meaning of `LV_GRID_ALIGN_START` and `LV_GRID_ALIGN_END` is swapped. I.e. `START` will mean right.
If the base direction of the container is set to `LV_BASE_DIR_RTL`, the meaning of `LV_GRID_ALIGN_START` and `LV_GRID_ALIGN_END` is swapped. I.e. `START` will mean right-most.
The columns will be placed from right to left.

View File

@@ -5,13 +5,13 @@
# Animations
You can automatically change the value of a variable between a start and an end value using animations.
The animation will happen by the periodical call of an "animator" function with the corresponding value parameter.
The animation will happen by periodically calling an "animator" function with the corresponding value parameter.
The *animator* functions has the following prototype:
The *animator* functions have the following prototype:
```c
void func(void * var, lv_anim_var_t value);
```
This prototype is compatible with the majority of the *set* function of LVGL. For example `lv_obj_set_x(obj, value)` or `lv_obj_set_width(obj, value)`
This prototype is compatible with the majority of the *set* functions of LVGL. For example `lv_obj_set_x(obj, value)` or `lv_obj_set_width(obj, value)`
## Create an animation
@@ -82,27 +82,27 @@ Therefore `lv_anim_start()` will delete the already existing variable-function a
## Animation path
You can determinate the path of animation. In the most simple case, it is linear, which means the current value between *start* and *end* is changed linearly.
You can determinate the path of animation. The most simple case is linear, meaning the current value between *start* and *end* is changed with fixed steps.
A *path* is a function which calculates the next value to set based on the current state of the animation. Currently, there are the following built-in paths functions:
- `lv_anim_path_linear` linear animation
- `lv_anim_path_step` change in one step at the end
- `lv_anim_path_ease_in` slow at the beginning
- `lv_anim_path_ease_out` slow at the end
- `lv_anim_path_ease_in_out` slow at the beginning and end too
- `lv_anim_path_ease_in_out` slow at the beginning and at the end
- `lv_anim_path_overshoot` overshoot the end value
- `lv_anim_path_bounce` bounce back a little from the end value (like hitting a wall)
## Speed vs time
By default, you can set the animation time. But, in some cases, the animation speed is more practical.
By default, you set the animation time. But in some cases, setting the animation speed is more practical.
The `lv_anim_speed_to_time(speed, start, end)` function calculates the required time in milliseconds to reach the end value from a start value with the given speed.
The speed is interpreted in _unit/sec_ dimension. For example, `lv_anim_speed_to_time(20,0,100)` will give 5000 milliseconds. For example, in case of `lv_obj_set_x` *unit* is pixels so *20* means *20 px/sec* speed.
The speed is interpreted in _unit/sec_ dimension. For example, `lv_anim_speed_to_time(20,0,100)` will yield 5000 milliseconds. For example, in case of `lv_obj_set_x` *unit* is pixels so *20* means *20 px/sec* speed.
## Delete animations
You can delete an animation by `lv_anim_del(var, func)` by providing the animated variable and its animator function.
You can delete an animation with `lv_anim_del(var, func)` if you provide the animated variable and its animator function.
## Examples

157
docs/overview/color.md Normal file
View File

@@ -0,0 +1,157 @@
```eval_rst
.. include:: /header.rst
:github_url: |github_link_base|/overview/color.md
```
# Colors
The color module handles all color-related functions like changing color depth, creating colors from hex code, converting between color depths, mixing colors, etc.
`lv_color_t` is used to store a color, its fileds are set according to `LV_COLOR_DEPTH` in `lv_conf.h`. (See below)
You may set `LV_COLOR_16_SWAP` in `lv_conf.h` to swap the bytes of *RGB565* colors. You may need this to send the 16-bit colors via a byte-oriented interface like SPI. As 16-bit numbers are stored in Little Endian format (lower byte on the lower address), the interface will send the lower byte first. However, displays usually need the higher byte first. A mismatch in the byte order will result in highly distorted colors.
## Creating colors
### RGB
Create colors from Red, Green and Blue channel values
```c
//All channels are 0-255
lv_color_t c = lv_color_make(red, green, blue);
//From hex code 0x000000..0xFFFFFF interpreted as RED + GREEN + BLUE
lv_color_t c = lv_color_hex(0x123456);
//From 3 digits. Same as lv_color_hex(0x112233)
lv_color_t c = lv_color_hex3(0x123);
```
### HSV
Create colors from Hue, Saturation and Value values
```c
//h = 0..359, s = 0..100, v = 0..100
lv_color_t c = lv_color_hsv_to_rgb(h, s, v);
//All channels are 0-255
lv_color_hsv_t c_hsv = lv_color_rgb_to_hsv(r, g, b);
//From lv_color_t variable
lv_color_hsv_t c_hsv = lv_color_to_hsv(color);
```
### Palette
LVGL includes [material design's palette](https://vuetifyjs.com/en/styles/colors/#material-colors). In this all color have a main as well as four darker and five lighter variants.
The names of the colors are as follows:
- `LV_PALETTE_RED`
- `LV_PALETTE_PINK`
- `LV_PALETTE_PURPLE`
- `LV_PALETTE_DEEP_PURPLE`
- `LV_PALETTE_INDIGO`
- `LV_PALETTE_BLUE`
- `LV_PALETTE_LIGHT_BLUE`
- `LV_PALETTE_CYAN`
- `LV_PALETTE_TEAL`
- `LV_PALETTE_GREEN`
- `LV_PALETTE_LIGHT_GREEN`
- `LV_PALETTE_LIME`
- `LV_PALETTE_YELLOW`
- `LV_PALETTE_AMBER`
- `LV_PALETTE_ORANGE`
- `LV_PALETTE_DEEP_ORANGE`
- `LV_PALETTE_BROWN`
- `LV_PALETTE_BLUE_GREY`
- `LV_PALETTE_GREY`
To get the main color use `lv_color_t c = lv_palette_main(LV_PALETTE_...)`.
For the lighter variants of a palette color use `lv_color_t c = lv_palette_lighten(LV_PALETTE_..., v)`. `v` can be 1..5.
For the darker variants of a palette color use `lv_color_t c = lv_palette_darken(LV_PALETTE_..., v)`. `v` can be 1..4.
### Modify and mix colors
The following functions can modify a color:
```c
// Lighten a color. 0: no change, 255: white
lv_color_t c = lv_color_lighten(c, lvl);
// Darken a color. 0: no change, 255: black
lv_color_t c = lv_color_darken(lv_color_t c, lv_opa_t lvl);
// Lighten or darken a color. 0: black, 128: no change 255: black
lv_color_t c = lv_color_change_lightness(lv_color_t c, lv_opa_t lvl);
// Mix 2 colors with a given ratio 0: full c2, 255: full c1, 128: half c1 and half c2
lv_color_t c = lv_color_mix(c1, c2, ratio);
```
### Built-in colors
`lv_color_white()` and `lv_color_black()` return `0xFFFFFF` and `0x000000` respectively.
## Opacity
To describe opacity the `lv_opa_t` type is created as a wrapper to `uint8_t`. Some defines are also introduced:
- `LV_OPA_TRANSP` Value: 0, means the opacity makes the color completely transparent
- `LV_OPA_10` Value: 25, means the color covers only a little
- `LV_OPA_20 ... OPA_80` come logically
- `LV_OPA_90` Value: 229, means the color near completely covers
- `LV_OPA_COVER` Value: 255, means the color completely covers
You can also use the `LV_OPA_*` defines in `lv_color_mix()` as a *ratio*.
## Color types
The following variable types are defined by the color module:
- `lv_color1_t` Monochrome color. Also has R, G, B fields for compatibility but they are always the same value (1 byte)
- `lv_color8_t` A structure to store R (3 bit),G (3 bit),B (2 bit) components for 8-bit colors (1 byte)
- `lv_color16_t` A structure to store R (5 bit),G (6 bit),B (5 bit) components for 16-bit colors (2 byte)
- `lv_color32_t` A structure to store R (8 bit),G (8 bit), B (8 bit) components for 24-bit colors (4 byte)
- `lv_color_t` Equal to `lv_color1/8/16/24_t` depending on current color depth setting
- `lv_color_int_t` `uint8_t`, `uint16_t` or `uint32_t` depending on color depth setting. Used to build color arrays from plain numbers.
- `lv_opa_t` A simple `uint8_t` type to describe opacity.
The `lv_color_t`, `lv_color1_t`, `lv_color8_t`, `lv_color16_t` and `lv_color32_t` types have four fields:
- `ch.red` red channel
- `ch.green` green channel
- `ch.blue` blue channel
- `full*` red + green + blue as one number
You can set the current color depth in *lv_conf.h*, by setting the `LV_COLOR_DEPTH` define to 1 (monochrome), 8, 16 or 32.
### Convert color
You can convert a color from the current color depth to another. The converter functions return with a number, so you have to use the `full` field:
```c
lv_color_t c;
c.red = 0x38;
c.green = 0x70;
c.blue = 0xCC;
lv_color1_t c1;
c1.full = lv_color_to1(c); /*Return 1 for light colors, 0 for dark colors*/
lv_color8_t c8;
c8.full = lv_color_to8(c); /*Give a 8 bit number with the converted color*/
lv_color16_t c16;
c16.full = lv_color_to16(c); /*Give a 16 bit number with the converted color*/
lv_color32_t c24;
c32.full = lv_color_to32(c); /*Give a 32 bit number with the converted color*/
```
## API
```eval_rst
.. doxygenfile:: lv_color.h
:project: lvgl
```

View File

@@ -5,8 +5,8 @@
# Positions, sizes, and layouts
## Overview
Similarly to many other parts of LVGL, the concept of setting the coordinates were inspired by CSS. It doesn't mean a perfect copy of the standard but subsets of CSS were implemented (sometimes with minor adjustments).
It shorts it means:
Similarly to many other parts of LVGL, the concept of setting the coordinates was inspired by CSS. By no means a complete implementation of the standard but subsets of CSS were implemented (sometimes with minor adjustments).
In shorts this means:
- the set coordinates (size, position, layouts, etc) are stored in styles
- support min-width, max-width, min-height, max-height
- have pixel, percentage, and "content" units
@@ -15,7 +15,7 @@ It shorts it means:
- a subset of flexbox and grid layouts are supported
### Units
- pixel: Simply a position in pixels. A simple integer always mean pixel. E.g. `lv_obj_set_x(btn, 10)`
- pixel: Simply a position in pixels. A simple integer always means pixel. E.g. `lv_obj_set_x(btn, 10)`
- percentage: The percentage of the size of the object or its parent (depending on the property). The `lv_pct(value)` converts a value to percentage. E.g. `lv_obj_set_width(btn, lv_pct(50))`
- `LV_SIZE_CONTENT`: Special value to set the width/height of an object to involve all the children. Its similar to `auto` in CSS. E.g. `lv_obj_set_width(btn, LV_SIZE_CONTENT)`.
@@ -34,16 +34,16 @@ The border is drawn inside the bounding box. Inside the border LVGL keeps "paddi
The outline is drawn outside of the bounding box.
### Important notes
This section describes special cases in which LVGL's behavior might look unexpected.
This section describes special cases in which LVGL's behavior might be unexpected.
#### Postponed coordinate calculation
LVGL doesn't recalculate all the coordinate changes immediately to improve performance.
LVGL doesn't recalculate all the coordinate changes immediately. This is done to improve performance.
Instead, the objects are marked as "dirty" and before redrawing the screen LVGL checks if there are any "dirty" objects. If so it refreshes their position, size and layout.
In other words, if you need to get the any coordinate of an object and it the coordinates were just changed LVGL's needs to be forced to recalculate to coordinates.
In other words, if you need to get the any coordinate of an object and it the coordinates were just changed LVGL's needs to be forced to recalculate the coordinates.
To do this call `lv_obj_update_layout(obj)`.
The size and position might depends on the parent or layout therefor `lv_obj_update_layout` recalculates the coordinates of all objects on the screen of `obj`.
The size and position might depend on the parent or layout. Therefore `lv_obj_update_layout` recalculates the coordinates of all objects on the screen of `obj`.
#### Removing styles
As it's described in the [Using styles](#using-styles) section the coordinates can be set via style properties too.
@@ -83,7 +83,7 @@ lv_obj_set_pos(obj, 10, 20); //Or in one function
```
By default the the x and y coordinates are measured from the top left corner of the parent's content area.
For example if the parent has 5 pixel padding on every side, the above code will place `obj` to (15, 25) because the content area starts after the padding.
For example if the parent has 5 pixels padding on every side, the above code will place `obj` at (15, 25) because the content area starts after the padding.
If percentage values are calculated from the parents content area size.
```c
@@ -143,12 +143,12 @@ Besides the alignments options above the following can be used to align the obje
- `LV_ALIGN_OUT_RIGHT_MID`
- `LV_ALIGN_OUT_RIGHT_BOTTOM`
For example to align a label above a button and center the label is horizontally:
For example to align a label above a button and center the label horizontally:
```c
lv_obj_align_to(label, btn, LV_ALIGN_OUT_TOP_MID, 0, -10);
```
Not that - unlike with `lv_obj_align()` - `lv_obj_align_to()` can not realign the object if its coordinates or the reference object's coordinates changes.
Note that - unlike with `lv_obj_align()` - `lv_obj_align_to()` can not realign the object if its coordinates or the reference object's coordinates changes.
## Size
@@ -165,10 +165,10 @@ Percentage values are calculated based on the parent's content area size. For ex
lv_obj_set_height(obj, lv_pct(100));
```
Size setting supports a value: `LV_SIZE_CONTENT`. It means the object's size in the respective direction will be set to involve its the children.
Note that only children on the right and bottom will be considered and children on the top and left remains cropped. This limitation makes the behavior more predictable.
Size setting supports a value: `LV_SIZE_CONTENT`. It means the object's size in the respective direction will be set to the size of its children.
Note that only children on the right and bottom will be considered and children on the top and left remain cropped. This limitation makes the behavior more predictable.
Object with `LV_OBJ_FLAG_HIDDEN` or `LV_OBJ_FLAG_FLOATING` will be ignored by `LV_SIZE_CONTENT` calculation.
Objects with `LV_OBJ_FLAG_HIDDEN` or `LV_OBJ_FLAG_FLOATING` will be ignored by the `LV_SIZE_CONTENT` calculation.
The above functions set the size of the bounding box of the object but the size of the content area can be set as well. It means the object's bounding box will be larger with the paddings than the set size.
```c
@@ -189,7 +189,7 @@ Under the hood the position, size and alignment properties are style properties.
The above described "simple functions" hide the style related code for the sake of simplicity and set the position, size, and alignment properties in the local styles of the obejct.
However, using styles as to set the coordinates has some great advantages:
- It makes easy to set the width/height/etc for several object together with ease. E.g. all make all the sliders 100x10 pixels sized.
- It makes it easy to set the width/height/etc for several objects together. E.g. make all the sliders 100x10 pixels sized.
- It also makes possible to modify the values in one place.
- The values can be overwritten by other styles. For example `style_btn` makes the object `100x50` by default but adding `style_full_width` overwrites only the width of the object.
- The object can have different position or size in different state. E.g. 100 px wide in `LV_STATE_DEFAULT` but 120 px in `LV_STATE_PRESSED`.
@@ -258,14 +258,14 @@ Translation is applied from the current position of the object.
Percentage values can be used in translations as well. The percentage is relative to the size of the object (and not to the size of the parent). For example `lv_pct(50)` will move the object with half of its width/height.
The translations is applied after the layouts are calculated. Therefore, even the layouted objects' position can be translated.
The translation is applied after the layouts are calculated. Therefore, even the layouted objects' position can be translated.
The translation actually moves the object. It means it makes the scrollbars and `LV_SIZE_CONTENT` sized objects react on the position change.
The translation actually moves the object. It means it makes the scrollbars and `LV_SIZE_CONTENT` sized objects react to the position change.
## Transformation
Similarly to the position the size can be changed relative to the current size as well.
The transformed width and height is added on both sides of the object. That is 10 px transformed width makes the object 2x10 pixel wider.
The transformed width and height are added on both sides of the object. This means 10 px transformed width makes the object 2x10 pixel wider.
Unlike position translation, the size transformation doesn't make the object "really" larger. In other words scrollbars, layouts, `LV_SIZE_CONTENT` will not consider the transformed size.
Hence size transformation if "only" a visual effect.

View File

@@ -22,16 +22,16 @@ Why would you want multi-display support? Here are some examples:
- Have two large TFT displays: one for a customer and one for the shop assistant.
### Using only one display
Using more displays can be useful, but in most cases, it's not required. Therefore, the whole concept of multi-display is completely hidden if you register only one display.
By default, the lastly created (the only one) display is used as default.
Using more displays can be useful but in most cases it's not required. Therefore, the whole concept of multi-display is completely hidden if you register only one display.
By default, the lastly created (and only) display is used.
`lv_scr_act()`, `lv_scr_load(scr)`, `lv_layer_top()`, `lv_layer_sys()`, `LV_HOR_RES` and `LV_VER_RES` are always applied on the lastly created (default) screen.
`lv_scr_act()`, `lv_scr_load(scr)`, `lv_layer_top()`, `lv_layer_sys()`, `LV_HOR_RES` and `LV_VER_RES` are always applied on the most recently created (default) screen.
If you pass `NULL` as `disp` parameter to display related function, usually the default display will be used.
E.g. `lv_disp_trig_activity(NULL)` will trigger a user activity on the default screen. (See below in [Inactivity](#Inactivity)).
### Mirror display
To mirror the image of the display to another display, you don't need to use the multi-display support. Just transfer the buffer received in `drv.flush_cb` to another display too.
To mirror the image of the display to another display, you don't need to use the multi-display support. Just transfer the buffer received in `drv.flush_cb` to the other display too.
### Split image
You can create a larger display from smaller ones. You can create it as below:
@@ -51,7 +51,7 @@ Be sure not to confuse displays and screens:
Screens can be considered the highest level containers which have no parent.
The screen's size is always equal to its display and size their position is (0;0). Therefore, the screens coordinates can't be changed, i.e. `lv_obj_set_pos()`, `lv_obj_set_size()` or similar functions can't be used on screens.
A screen can be created from any object type but, the two most typical types are the [Base object](/widgets/obj) and the [Image](/widgets/core/img) (to create a wallpaper).
A screen can be created from any object type but the two most typical types are the [Base object](/widgets/obj) and the [Image](/widgets/core/img) (to create a wallpaper).
To create a screen, use `lv_obj_t * scr = lv_<type>_create(NULL, copy)`. `copy` can be an other screen to copy it.
@@ -64,10 +64,10 @@ Screens can be deleted with `lv_obj_del(scr)`, but ensure that you do not delete
Usually, the opacity of the screen is `LV_OPA_COVER` to provide a solid background for its children. If it's not the case (opacity &lt; 100%) the display's background color or image will be visible.
See the [Display background](#display-background) section for more details. If the display's background opacity is also not `LV_OPA_COVER` LVGL has no solid background to draw.
This configuration (transparent screen ans display) could be used to create for example OSD menus where a video is played to lower layer, and menu is created on an upper layer.
This configuration (transparent screen and display) could be used to create for example OSD menus where a video is played on a lower layer, and a menu is overlayed on an upper layer.
To handle transparent displays special (slower) color mixing algorithms needs to be used by LVGL so this feature needs to enabled with `LV_COLOR_SCREEN_TRANSP` n `lv_conf.h`.
As this mode operates on the Alpha channel of the pixels `LV_COLOR_DEPTH = 32` is also required. The Alpha channel of 32-bit colors will be 0 where there are no objects and will be 255 where there are solid objects.
To handle transparent displays special (slower) color mixing algorithms need to be used by LVGL so this feature needs to enabled with `LV_COLOR_SCREEN_TRANSP` in `lv_conf.h`.
As this mode operates on the Alpha channel of the pixels `LV_COLOR_DEPTH = 32` is also required. The Alpha channel of 32-bit colors will be 0 where there are no objects and 255 where there are solid objects.
In summary, to enable transparent screen and displays to create OSD menu-like UIs:
- Enable `LV_COLOR_SCREEN_TRANSP` in `lv_conf.h`
@@ -89,102 +89,20 @@ Every display has background color, a background image and background opacity pr
Background color is a simple color to fill the display. It can be adjusted with `lv_disp_set_bg_color(disp, color)`;
Background image is path to file or pointer to an `lv_img_dsc_t` variable (converted image) to be used as wallpaper. It can be set with `lv_disp_set_bg_color(disp, &my_img)`;
If the background image is set (not `NULL`) the background won't filled with `bg_color`.
Background image is a path to a file or a pointer to an `lv_img_dsc_t` variable (converted image) to be used as wallpaper. It can be set with `lv_disp_set_bg_color(disp, &my_img)`;
If the background image is set (not `NULL`) the background won't be filled with `bg_color`.
The opacity of the background color or image can be adjusted with `lv_disp_set_bg_opa(disp, opa)`.
The `disp` parameter of these functions can be `NULL` to refer it to the default display.
## Colors
The color module handles all color-related functions like changing color depth, creating colors from hex code, converting between color depths, mixing colors, etc.
The following variable types are defined by the color module:
- **lv_color1_t** Store monochrome color. For compatibility, it also has R, G, B fields but they are always the same value (1 byte)
- **lv_color8_t** A structure to store R (3 bit),G (3 bit),B (2 bit) components for 8-bit colors (1 byte)
- **lv_color16_t** A structure to store R (5 bit),G (6 bit),B (5 bit) components for 16-bit colors (2 byte)
- **lv_color32_t** A structure to store R (8 bit),G (8 bit), B (8 bit) components for 24-bit colors (4 byte)
- **lv_color_t** Equal to `lv_color1/8/16/24_t` according to color depth settings
- **lv_color_int_t** `uint8_t`, `uint16_t` or `uint32_t` according to color depth setting. Used to build color arrays from plain numbers.
- **lv_opa_t** A simple `uint8_`t type to describe opacity.
The `lv_color_t`, `lv_color1_t`, `lv_color8_t`, `lv_color16_t` and `lv_color32_t` types have got four fields:
- **ch.red** red channel
- **ch.green** green channel
- **ch.blue** blue channel
- **full** red + green + blue as one number
You can set the current color depth in *lv_conf.h*, by setting the `LV_COLOR_DEPTH` define to 1 (monochrome), 8, 16 or 32.
### Convert color
You can convert a color from the current color depth to another. The converter functions return with a number, so you have to use the `full` field:
```c
lv_color_t c;
c.red = 0x38;
c.green = 0x70;
c.blue = 0xCC;
lv_color1_t c1;
c1.full = lv_color_to1(c); /*Return 1 for light colors, 0 for dark colors*/
lv_color8_t c8;
c8.full = lv_color_to8(c); /*Give a 8 bit number with the converted color*/
lv_color16_t c16;
c16.full = lv_color_to16(c); /*Give a 16 bit number with the converted color*/
lv_color32_t c24;
c32.full = lv_color_to32(c); /*Give a 32 bit number with the converted color*/
```
### Swap 16 colors
You may set `LV_COLOR_16_SWAP` in *lv_conf.h* to swap the bytes of *RGB565* colors. It's useful if you send the 16-bit colors via a byte-oriented interface like SPI.
As 16-bit numbers are stored in Little Endian format (lower byte on the lower address), the interface will send the lower byte first. However, displays usually need the higher byte first. A mismatch in the byte order will result in highly distorted colors.
### Create and mix colors
You can create colors with the current color depth using the LV_COLOR_MAKE macro. It takes 3 arguments (red, green, blue) as 8-bit numbers.
For example to create light red color: `my_color = COLOR_MAKE(0xFF,0x80,0x80)`.
Colors can be created from HEX codes too: `my_color = lv_color_hex(0x288ACF)` or `my_color = lv_folro_hex3(0x28C)`.
Mixing two colors is possible with `mixed_color = lv_color_mix(color1, color2, ratio)`. Ration can be 0..255. 0 results fully color2, 255 result fully color1.
Colors can be created with from HSV space too using `lv_color_hsv_to_rgb(hue, saturation, value)` . `hue` should be in 0..360 range, `saturation` and `value` in 0..100 range.
### Opacity
To describe opacity the `lv_opa_t` type is created as a wrapper to `uint8_t`. Some defines are also introduced:
- **LV_OPA_TRANSP** Value: 0, means the opacity makes the color completely transparent
- **LV_OPA_10** Value: 25, means the color covers only a little
- **LV_OPA_20 ... OPA_80** come logically
- **LV_OPA_90** Value: 229, means the color near completely covers
- **LV_OPA_COVER** Value: 255, means the color completely covers
You can also use the `LV_OPA_*` defines in `lv_color_mix()` as a *ratio*.
## API
### Display
```eval_rst
.. doxygenfile:: lv_disp.h
:project: lvgl
```
### Colors
```eval_rst
.. doxygenfile:: lv_color.h
:project: lvgl
```

View File

@@ -8,7 +8,7 @@ With LVGL, you don't need to draw anything manually. Just create objects (like b
However, it might be useful to have a basic understanding of how drawing happens in LVGL to add customization, make it easier to find bugs or just out of curiosity.
The basic concept is to not draw directly to the screen, but draw to an internal draw buffer first. When drawing (rendering) is ready copy that buffer to the screen.
The basic concept is to not draw directly to the screen, but draw to an internal draw buffer first. When drawing (rendering) is ready, that buffer is copied to the screen.
The draw buffer can be smaller than the screen's size. LVGL will simply render in "tiles" that fit into the given draw buffer.
@@ -17,7 +17,7 @@ This approach has two main advantages compared to directly drawing to the screen
2. It's faster to modify a buffer in internal RAM and finally write one pixel only once than reading/writing the display directly on each pixel access.
(e.g. via a display controller with SPI interface).
Note that, this concept is different from "traditional" double buffering where there are 2 screen sized frame buffers:
Note that this concept is different from "traditional" double buffering where there are 2 screen sized frame buffers:
one holds the current image to show on the display, and rendering happens to the other (inactive) frame buffer, and they are swapped when the rendering is finished.
The main difference is that with LVGL you don't have to store 2 frame buffers (which usually requires external RAM) but only smaller draw buffer(s) that can easily fit into the internal RAM too.
@@ -27,7 +27,7 @@ The main difference is that with LVGL you don't have to store 2 frame buffers (w
Be sure to get familiar with the [Buffering modes of LVGL](/porting/display) first.
LVGL refreshes the screen in the following steps:
1. Something happens on the UI which requires redrawing. For example, a button is pressed, a chart is changed or an animation happened, etc.
1. Something happens on the UI which requires redrawing. For example, a button is pressed, a chart is changed, an animation happened, etc.
2. LVGL saves the changed object's old and new area into a buffer, called an *Invalid area buffer*. For optimization, in some cases, objects are not added to the buffer:
- Hidden objects are not added.
- Objects completely out of their parent are not added.
@@ -42,7 +42,7 @@ LVGL refreshes the screen in the following steps:
- Do the same with all the joined areas.
When an area is redrawn, the library searches the top most object which covers that area, and starts drawing from that object.
For example, if a button's label has changed, the library will see that it's enough to draw the button under the text, and it's not required to draw the screen under the button too.
For example, if a button's label has changed, the library will see that it's enough to draw the button under the text, and that it's not required to draw the screen under the button too.
The difference between buffering modes regarding the drawing mechanism is the following:
1. **One buffer** - LVGL needs to wait for `lv_disp_flush_ready()` (called from `flush_cb`) before starting to redraw the next part.
@@ -51,18 +51,18 @@ The difference between buffering modes regarding the drawing mechanism is the fo
## Masking
*Masking* is the basic concept of LVGL's draw engine.
To use LVGL it's not required to know about the mechanisms described here, you might find interesting to know how drawing works under hood.
Knowing about mask comes in handy if you want to customize drawing.
To use LVGL it's not required to know about the mechanisms described here, but you might find interesting to know how drawing works under hood.
Knowing about masking comes in handy if you want to customize drawing.
To learn masking let's learn the steps of drawing first.
LVGL performs the following steps to render any shape, image or text. It can be considered as a drawing pipeline.
1. **Prepare the draw descriptors** Create a draw descriptor from an object's styles (e.g. `lv_draw_rect_dsc_t`). It tells the parameters of drawing, for example the colors, widths, opacity, fonts, radius, etc.
1. **Prepare the draw descriptors** Create a draw descriptor from an object's styles (e.g. `lv_draw_rect_dsc_t`). This gives us the parameters for drawing, for example the colors, widths, opacity, fonts, radius, etc.
2. **Call the draw function** Call the draw function with the draw descriptor and some other parameters (e.g. `lv_draw_rect()`). It renders the primitive shape to the current draw buffer.
3. **Create masks** If the shape is very simple and doesn't require masks go to #5. Else create the required masks (e.g. a rounded rectangle mask)
4. **Calculate all the added mask**. It creates 0..255 values into a *mask buffer* with the "shape" of the created masks.
E.g. in case of a "line mask" according to the parameters of the mask, keep one side of the buffer as it is (255 by default) and set the rest to 0 to indicate that this side should be removed.
5. **Blend a color or image** During blending masks (make some pixels transparent or opaque), blending modes (additive, subtractive, etc), opacity are handled.
5. **Blend a color or image** During blending masks (make some pixels transparent or opaque), blending modes (additive, subtractive, etc) and opacity are handled.
LVGL has the following built-in mask types which can be calculated and applied real-time:
- `LV_DRAW_MASK_TYPE_LINE` Removes a side from a line (top, bottom, left or right). `lv_draw_line` uses 4 of it.
@@ -83,23 +83,23 @@ Masks are used the create almost every basic primitives:
## Hook drawing
Although widgets can be very well customized by styles there might be cases when something really custom is required.
To ensure a great level of flexibility LVGL sends a lot events during drawing with parameters that tells what LVGL is about to draw.
To ensure a great level of flexibility LVGL sends a lot events during drawing with parameters that tell what LVGL is about to draw.
Some fields of these parameters can be modified to draw something else or any custom drawing can be added manually.
A good use case for it is the [Button matrix](/widgets/core/btnmatrix) widget. By default its buttons can be styled in different states but you can't style the buttons one by one.
However, an event is sent for ever button and you can tell LVGL for example to use different colors on a specific buttons or manually draw an image on an some buttons.
However, an event is sent for every button and you can for example tell LVGL to use different colors on a specific button or to manually draw an image on some buttons.
Below each related events are described in detail.
Below each of these events are described in detail.
### Main drawing
These events are related to the actual drawing of the object. E.g. drawing of buttons, texts, etc happens here.
`lv_event_get_clip_area(event)` can be used to get the current clip area. The clip area is required in draw functions to make them draw only on limited area.
`lv_event_get_clip_area(event)` can be used to get the current clip area. The clip area is required in draw functions to make them draw only on a limited area.
#### LV_EVENT_DRAW_MAIN_BEGIN
Sent before starting to draw an object. It's a good place to add masks manually. E.g. add a line mask that "removes" the right side of an object.
Sent before starting to draw an object. This is a good place to add masks manually. E.g. add a line mask that "removes" the right side of an object.
#### LV_EVENT_DRAW_MAIN
@@ -122,7 +122,7 @@ Sent before starting the post draw phase. Masks can be added here too to mask ou
#### LV_EVENT_DRAW_POST
The actual drawing should happens here.
The actual drawing should happen here.
#### LV_EVENT_DRAW_POST_END
@@ -131,7 +131,7 @@ Called when post drawing has finished. If the masks were not removed in `LV_EVEN
### Part drawing
When LVGL draws a part of an object (e.g. a slider's indicator, a table's cell or a button matrix's button) it sends events before and after drawing that part with some context of the drawing.
It allows changing the parts on a very low level with masks, extra drawing, or changing the parameters the LVGL is planning to use for drawing.
It allows changing the parts on a very low level with masks, extra drawing, or changing the parameters that LVGL is planning to use for drawing.
In these events an `lv_obj_draw_part_t` structure is used to describe the context of the drawing. Not all fields are set for every part and widget.
To see which fields are set for a widget see the widget's documentation.
@@ -165,11 +165,11 @@ const void * sub_part_ptr; // A pointer the identifies something in the
#### LV_EVENT_DRAW_PART_BEGIN
Start the drawing of a part. It's good place to modify the draw descriptors (e.g. `rect_dsc`), or add masks.
Start the drawing of a part. This is a good place to modify the draw descriptors (e.g. `rect_dsc`), or add masks.
#### LV_EVENT_DRAW_PART_END
Finish the drawing of a part. It's a good place to draw extra content on the part, or remove the masks added in `LV_EVENT_DRAW_PART_BEGIN`.
Finish the drawing of a part. This is a good place to draw extra content on the part, or remove the masks added in `LV_EVENT_DRAW_PART_BEGIN`.
### Others
@@ -180,22 +180,22 @@ This event is used to check whether an object fully covers an area or not.
`lv_event_get_cover_area(event)` returns an pointer to an area to check and `lv_event_set_cover_res(event, res)` can be used to set one of these results:
- `LV_COVER_RES_COVER` the areas is fully covered by the object
- `LV_COVER_RES_NOT_COVER` the areas is not covered by the object
- `LV_COVER_RES_MASKED` there is a mask on the object so it can not covert the area
- `LV_COVER_RES_MASKED` there is a mask on the object so it can not cover the area
Here are some cases why can't an object fully cover an area:
- It's simply not fully on the that area
- It has radius
Here are some reasons why an object would be unable to fully cover an area:
- It's simply not fully in area
- It has a radius
- It has not 100% background opacity
- It's an ARGB or chroma keyed image
- It has not normal blending mode. In this case LVGL needs to know the colors under the object to make the blending properly
- It does not have normal blending mode. In this case LVGL needs to know the colors under the object to do the blending properly
- It's a text, etc
In short if for any reason the the area below the object is visible than it doesn't cover that area.
In short if for any reason the area below the object is visible than it doesn't cover that area.
Before sending this event LVGL checks if at least the widget's coordinates fully cover the area or not. If not the event is not called.
You need to check only the drawing you have added. The existing properties known by widget are handled in the widget's internal events.
E.g. if a widget has &gt; 0 radius it might not cover an area but you need to handle `radius` only if you will modify it and widget can't know about it.
E.g. if a widget has &gt; 0 radius it might not cover an area but you need to handle `radius` only if you will modify it and the widget can't know about it.
#### LV_EVENT_REFR_EXT_DRAW_SIZE

View File

@@ -4,11 +4,11 @@
```
# Events
Events are triggered in LVGL when something happens which might be interesting to the user, e.g. if an object:
Events are triggered in LVGL when something happens which might be interesting to the user, e.g. when an object
- is clicked
- is scrolled
- its value has changed
- redrawn, etc.
- has its value changed
- is redrawn, etc.
## Add events to the object
@@ -76,10 +76,10 @@ The following event codes exist:
- `LV_EVENT_SHORT_CLICKED` The object was pressed for a short period of time, then released it. Not called if scrolled.
- `LV_EVENT_LONG_PRESSED` Object has been pressed for at least the `long_press_time` specified in the input device driver. Not called if scrolled.
- `LV_EVENT_LONG_PRESSED_REPEAT` Called after `long_press_time` in every `long_press_repeat_time` ms. Not called if scrolled.
- `LV_EVENT_CLICKED` Called on release if the object not scrolled (regardless to long press)
- `LV_EVENT_RELEASED` Called in every cases when the object has been released
- `LV_EVENT_SCROLL_BEGIN` Scrolling begins
- `LV_EVENT_SCROLL_END` Scrolling ends
- `LV_EVENT_CLICKED` Called on release if the object did not scroll (regardless of long press)
- `LV_EVENT_RELEASED` Called in every case when the object has been released
- `LV_EVENT_SCROLL_BEGIN` Scrolling begins. The event paramter is `NULL` or an `lv_anim_t *` with the scroll animation descriptor to modify if required.
- `LV_EVENT_SCROLL_END` Scrolling ends.
- `LV_EVENT_SCROLL` The object was scrolled
- `LV_EVENT_GESTURE` A gesture is detected. Get the gesture with `lv_indev_get_gesture_dir(lv_indev_get_act());`
- `LV_EVENT_KEY` A key is sent to the object. Get the key with `lv_indev_get_key(lv_indev_get_act());`
@@ -126,7 +126,7 @@ And can be sent to any object with `lv_event_send(obj, MY_EVENT_1, &some_data)`
To manually send events to an object, use `lv_event_send(obj, <EVENT_CODE> &some_data)`.
For example, it can be used to manually close a message box by simulating a button press (although there are simpler ways of doing this):
For example, this can be used to manually close a message box by simulating a button press (although there are simpler ways to do this):
```c
/*Simulate the press of the first button (indexes start from zero)*/
uint32_t btn_id = 0;
@@ -143,7 +143,7 @@ lv_event_send(mbox, LV_EVENT_VALUE_CHANGED, &btn_id);
## Fields of lv_event_t
`lv_event_t` is the only parameter passed to event callback and it contains all the data about the event. The following values can be get from it:
`lv_event_t` is the only parameter passed to event callback and it contains all the data about the event. The following values can be gotten from it:
- `lv_event_get_code(e)` get the event code
- `lv_event_get_target(e)` get the object to which the event is sent
- `lv_event_get_original_target(e)` get the object to which the event is sent originally sent (different from `lv_event_get_target` if [event bubbling](#event-bubbling) is enabled)

View File

@@ -4,20 +4,23 @@
```
# File system
LVGL has a 'File system' abstraction module that enables you to attach any type of file systems.
LVGL has a 'File system' abstraction module that enables you to attach any type of file system.
The file system is identified by a drive letter.
For example, if the SD card is associated with the letter `'S'`, a file can be reached like `"S:path/to/file.txt"`.
## Ready to use drivers
The [lv_fs_if](https://github.com/lvgl/lv_fs_if) repository contains ready to use drivers using POSIX, standard C and [FATFS](http://elm-chan.org/fsw/ff/00index_e.html) API.
See it's [README](https://github.com/lvgl/lv_fs_if#readme) for the details.
## Add a driver
To add a driver, `lv_fs_drv_t` needs to be initialized like this:
### Registering a driver
To add a driver, `lv_fs_drv_t` needs to be initialized like below. `lv_fs_drv_t` needs to be static, global or dynamically allocated and not a local varaible.
```c
lv_fs_drv_t drv;
static lv_fs_drv_t drv; /*Needs to be static or global*/
lv_fs_drv_init(&drv); /*Basic initialization*/
drv.letter = 'S'; /*An uppercase letter to identify the drive */
drv.file_size = sizeof(my_file_object); /*Size required to store a file object*/
drv.rddir_size = sizeof(my_dir_object); /*Size required to store a directory object (used by dir_open/close/read)*/
drv.ready_cb = my_ready_cb; /*Callback to tell if the drive is ready to use */
drv.open_cb = my_open_cb; /*Callback to open a file */
drv.close_cb = my_close_cb; /*Callback to close a file */
@@ -25,17 +28,11 @@ drv.read_cb = my_read_cb; /*Callback to read a file */
drv.write_cb = my_write_cb; /*Callback to write a file */
drv.seek_cb = my_seek_cb; /*Callback to seek in a file (Move cursor) */
drv.tell_cb = my_tell_cb; /*Callback to tell the cursor position */
drv.trunc_cb = my_trunc_cb; /*Callback to delete a file */
drv.size_cb = my_size_cb; /*Callback to tell a file's size */
drv.rename_cb = my_rename_cb; /*Callback to rename a file */
drv.dir_open_cb = my_dir_open_cb; /*Callback to open directory to read its content */
drv.dir_read_cb = my_dir_read_cb; /*Callback to read a directory's content */
drv.dir_close_cb = my_dir_close_cb; /*Callback to close a directory */
drv.free_space_cb = my_free_space_cb; /*Callback to tell free space on the drive */
drv.user_data = my_user_data; /*Any custom data if required*/
lv_fs_drv_register(&drv); /*Finally register the drive*/
@@ -44,11 +41,30 @@ lv_fs_drv_register(&drv); /*Finally register the drive*/
Any of the callbacks can be `NULL` to indicate that operation is not supported.
As an example of how the callbacks are used, if you use `lv_fs_open(&file, "S:/folder/file.txt", LV_FS_MODE_WR)`, LVGL:
1. Verifies that a registered drive exists with the letter `'S'`.
2. Checks if it's `open_cb` is implemented (not `NULL`).
3. Calls the set `open_cb` with `"folder/file.txt"` path.
### Implementing the callbacks
#### Open callback
The prototype of `open_cb` looks like this:
```c
void * (*open_cb)(lv_fs_drv_t * drv, const char * path, lv_fs_mode_t mode);
```
`path` is path after the driver letter (e.g. "S:path/to/file.txt" -> "path/to/file.txt"). `mode` can be `LV_FS_MODE_WR` or `LV_FS_MODE_RD` to open for write or read.
The return value is a pointer the *file object* the describes the opened file or `NULL` if there were any issues (e.g. the file wasn't found).
The returned file object will be passed to to other file system related callbacks. (see below)
### Other callbacks
The other callbacks are quite similar. For example `write_cb` looks like this:
```c
lv_fs_res_t (*write_cb)(lv_fs_drv_t * drv, void * file_p, const void * buf, uint32_t btw, uint32_t * bw);
```
As `file_p` LVGL passes the return value of `open_cb`, `buf` is the data to write, `btw` is the Bytes To Write, `bw` is the actually written bytes.
For a template to the callbacks see [lv_fs_template.c](https://github.com/lvgl/lvgl/blob/master/examples/porting/lv_port_fs_template.c).
## Usage example
@@ -98,7 +114,7 @@ lv_fs_dir_close(&dir);
[Image](/widgets/core/img) objects can be opened from files too (besides variables stored in the flash).
To initialize the image, the following callbacks are required:
To use files in image widgets the following callbacks are required:
- open
- close
- read
@@ -106,6 +122,7 @@ To initialize the image, the following callbacks are required:
- tell
## API
```eval_rst

View File

@@ -5,7 +5,7 @@
# Fonts
In LVGL fonts are collections of bitmaps and other information required to render the images of the letters (glyph).
A font is stored in a `lv_font_t` variable and can be set in style's *text_font* field. For example:
A font is stored in a `lv_font_t` variable and can be set in a style's *text_font* field. For example:
```c
lv_style_set_text_font(&my_style, LV_STATE_DEFAULT, &lv_font_montserrat_28); /*Set a larger font*/
```
@@ -13,7 +13,7 @@ lv_style_set_text_font(&my_style, LV_STATE_DEFAULT, &lv_font_montserrat_28); /*
The fonts have a **bpp (bits per pixel)** property. It shows how many bits are used to describe a pixel in the font. The value stored for a pixel determines the pixel's opacity.
This way, with higher *bpp*, the edges of the letter can be smoother. The possible *bpp* values are 1, 2, 4 and 8 (higher value means better quality).
The *bpp* also affects the required memory size to store the font. For example, *bpp = 4* makes the font nearly 4 times greater compared to *bpp = 1*.
The *bpp* also affects the required memory size to store the font. For example, *bpp = 4* makes the font nearly 4 times larger compared to *bpp = 1*.
## Unicode support
@@ -32,7 +32,7 @@ If all works well, a ✓ character should be displayed.
There are several built-in fonts in different sizes, which can be enabled in `lv_conf.h` by *LV_FONT_...* defines.
### Normal fonts
Containing all the ASCII characters, the degree symbol (U+00B0), the bullet symbol (U+2022) and the build in symbols (see below).
Containing all the ASCII characters, the degree symbol (U+00B0), the bullet symbol (U+2022) and the built-in symbols (see below).
- `LV_FONT_MONTSERRAT_12` 12 px font
- `LV_FONT_MONTSERRAT_14` 14 px font
- `LV_FONT_MONTSERRAT_16` 16 px font
@@ -56,15 +56,15 @@ Containing all the ASCII characters, the degree symbol (U+00B0), the bullet symb
### Special fonts
- `LV_FONT_MONTSERRAT_12_SUBPX` Same as normal 12 px font but with [subpixel rendering](#subpixel-rendering)
- `LV_FONT_MONTSERRAT_28_COMPRESSED` Same as normal 28 px font but [compressed font](#compress-fonts) with 3 bpp
- `LV_FONT_DEJAVU_16_PERSIAN_HEBREW` 16 px font with normal range + Hebrew, Arabic, Perisan letters and all their forms
- `LV_FONT_DEJAVU_16_PERSIAN_HEBREW` 16 px font with normal range + Hebrew, Arabic, Persian letters and all their forms
- `LV_FONT_SIMSUN_16_CJK`16 px font with normal range + 1000 most common CJK radicals
- `LV_FONT_UNSCII_8` 8 px pixel perfect font with only ASCII characters
- `LV_FONT_UNSCII_16` 16 px pixel perfect font with only ASCII characters
The built-in fonts are **global variables** with names like `lv_font_montserrat_16` for 16 px hight font. To use them in a style, just add a pointer to a font variable like shown above.
The built-in fonts are **global variables** with names like `lv_font_montserrat_16` for a 16 px hight font. To use them in a style, just add a pointer to a font variable like shown above.
The built-in fonts have *bpp = 4*, contains the ASCII characters and uses the [Montserrat](https://fonts.google.com/specimen/Montserrat) font.
The built-in fonts with *bpp = 4* contain the ASCII characters and use the [Montserrat](https://fonts.google.com/specimen/Montserrat) font.
In addition to the ASCII range, the following symbols are also added to the built-in fonts from the [FontAwesome](https://fontawesome.com/) font.
@@ -94,7 +94,7 @@ LVGL not only supports RTL texts but supports mixed (a.k.a. bidirectional, BiDi)
![](/misc/bidi.png "Bidirectional text examples")
The BiDi support can be enabled by `LV_USE_BIDI` in *lv_conf.h*
BiDi support is enabled by `LV_USE_BIDI` in *lv_conf.h*
All texts have a base direction (LTR or RTL) which determines some rendering rules and the default alignment of the text (Left or Right).
However, in LVGL, base direction is applied not only for labels. It's a general property which can be set for every object.
@@ -125,32 +125,31 @@ A different form of the same letter needs to be used if it isolated, start, midd
LVGL supports to apply these rules if `LV_USE_ARABIC_PERSIAN_CHARS` is enabled.
However, there some limitations:
- Only displaying texts is supported (e.g. on labels), text inputs (e.g. text area) doesn't support this feature
- Static text (i.e. const) are not processed. E.g. texts set by `lv_label_set_text()` will "Arabic processed" but `lv_lable_set_text_static()` won't.
- Only displaying texts is supported (e.g. on labels), text inputs (e.g. text area) don't support this feature.
- Static text (i.e. const) is not processed. E.g. texts set by `lv_label_set_text()` will be "Arabic processed" but `lv_lable_set_text_static()` won't.
- Text get functions (e.g. `lv_label_get_text()`) will return the processed text.
### Subpixel rendering
Subpixel rendering means to triple the horizontal resolution by rendering on Red, Green and Blue channel instead of pixel level. It takes advantage of the position of physical color channels of each pixel.
It results in higher quality letter anti-aliasing. Lear more [here](https://en.wikipedia.org/wiki/Subpixel_rendering).
Subpixel rendering allows for tripling the horizontal resolution by rendering on Red, Green and Blue channel instead of pixel level. This takes advantage of the position of physical color channels of each pixel, resulting in higher quality letter anti-aliasing. Learn more [here](https://en.wikipedia.org/wiki/Subpixel_rendering).
Subpixel rendering requires to generate the fonts with special settings:
For subpixel rendering the fonts need to be generated with special settings:
- In the online converter tick the `Subpixel` box
- In the command line tool use `--lcd` flag. Note that the generated font needs about 3 times more memory.
Subpixel rendering works only if the color channels of the pixels have a horizontal layout. That is the R, G, B channels are next each other and not above each other.
The order of color channels also needs to match with the library settings. By default the LVGL assumes `RGB` order, however it can be swapped by setting `LV_SUBPX_BGR 1` in *lv_conf.h*.
The order of color channels also needs to match with the library settings. By default LVGL assumes `RGB` order, however this can be swapped by setting `LV_SUBPX_BGR 1` in *lv_conf.h*.
### Compress fonts
The bitmaps of the fonts can be compressed by
- ticking the `Compressed` check box in the online converter
- not passing `--no-compress` flag to the offline converter (applies compression by default)
- not passing `--no-compress` flag to the offline converter (compression is applied by default)
The compression is more effective with larger fonts and higher bpp. However, it's about 30% slower to render the compressed fonts.
Therefore it's recommended to compress only the largest fonts of user interface, because
- they need the most memory
- they can be compressed better
- and probably they are used less frequently then the medium sized fonts. (so performance cost is smaller)
- and probably they are used less frequently then the medium sized fonts, so the performance cost is smaller.
## Add new font
@@ -158,14 +157,14 @@ There are several ways to add a new font to your project:
1. The simplest method is to use the [Online font converter](https://lvgl.io/tools/fontconverter). Just set the parameters, click the *Convert* button, copy the font to your project and use it. **Be sure to carefully read the steps provided on that site or you will get an error while converting.**
2. Use the [Offline font converter](https://github.com/lvgl/lv_font_conv). (Requires Node.js to be installed)
3. If you want to create something like the built-in fonts (Roboto font and symbols) but in different size and/or ranges, you can use the `built_in_font_gen.py` script in `lvgl/scripts/built_in_font` folder.
(It requires Python and `lv_font_conv` to be installed)
(This requires Python and `lv_font_conv` to be installed)
To declare the font in a file, use `LV_FONT_DECLARE(my_font_name)`.
To make the fonts globally available (like the builtin fonts), add them to `LV_FONT_CUSTOM_DECLARE` in *lv_conf.h*.
## Add new symbols
The built-in symbols are created from [FontAwesome](https://fontawesome.com/) font.
The built-in symbols are created from the [FontAwesome](https://fontawesome.com/) font.
1. Search symbol on [https://fontawesome.com](https://fontawesome.com). For example the [USB symbol](https://fontawesome.com/icons/usb?style=brands). Copy it's Unicode ID which is `0xf287` in this case.
2. Open the [Online font converter](https://lvgl.io/tools/fontconverter). Add Add [FontAwesome.woff](https://lvgl.io/assets/others/FontAwesome5-Solid+Brands+Regular.woff). .
@@ -175,13 +174,13 @@ The built-in symbols are created from [FontAwesome](https://fontawesome.com/) fo
6. Declare the font using `extern lv_font_t my_font_name;` or simply `LV_FONT_DECLARE(my_font_name);`.
**Using the symbol**
1. Convert the Unicode value to UTF8. You can do it e.g on [this site](http://www.ltg.ed.ac.uk/~richard/utf-8.cgi?input=f287&mode=hex). For `0xf287` the *Hex UTF-8 bytes* are `EF 8A 87`.
1. Convert the Unicode value to UTF8, for example on [this site](http://www.ltg.ed.ac.uk/~richard/utf-8.cgi?input=f287&mode=hex). For `0xf287` the *Hex UTF-8 bytes* are `EF 8A 87`.
2. Create a `define` from the UTF8 values: `#define MY_USB_SYMBOL "\xEF\x8A\x87"`
3. Create a label and set the text. Eg. `lv_label_set_text(label, MY_USB_SYMBOL)`
Note - `lv_label_set_text(label, MY_USB_SYMBOL)` searches for this symbol in the font defined in `style.text.font` properties. To use the symbol you may need to change it. Eg ` style.text.font = my_font_name`
## Load font in run-time
## Load font at run-time
`lv_font_load` can be used to load a font from a file. The font to load needs to have a special binary format. (Not TTF or WOFF).
Use [lv_font_conv](https://github.com/lvgl/lv_font_conv/) with `--format bin` option to generate an LVGL compatible font file.
@@ -202,7 +201,7 @@ lv_font_free(my_font);
## Add a new font engine
LVGL's font interface is designed to be very flexible.
You don't need to use LVGL's internal font engine but, you can add your own.
But even so you don't need to use LVGL's internal font engine: you can add your own.
For example, use [FreeType](https://www.freetype.org/) to real-time render glyphs from TTF fonts or use an external flash to store the font's bitmap and read them when the library needs them.
A ready to use FreeType can be found in [lv_freetype](https://github.com/lvgl/lv_lib_freetype) repository.

View File

@@ -12,7 +12,7 @@ You can store images in two places
- as a file
### Variables
The images stored internally in a variable is composed mainly of an `lv_img_dsc_t` structure with the following fields:
The images stored internally in a variable are composed mainly of an `lv_img_dsc_t` structure with the following fields:
- **header**
- *cf* Color format. See [below](#color-format)
- *w* width in pixels (<= 2048)
@@ -27,7 +27,7 @@ These are usually stored within a project as C files. They are linked into the r
### Files
To deal with files you need to add a *Drive* to LVGL. In short, a *Drive* is a collection of functions (*open*, *read*, *close*, etc.) registered in LVGL to make file operations.
You can add an interface to a standard file system (FAT32 on SD card) or you create your simple file system to read data from an SPI Flash memory.
In every case, a *Drive* is just an abstraction to read and/or write data to a memory.
In every case, a *Drive* is just an abstraction to read and/or write data to memory.
See the [File system](/overview/file-system) section to learn more.
Images stored as files are not linked into the resulting executable, and must be read to RAM before being drawn. As a result, they are not as resource-friendly as variable images. However, they are easier to replace without needing to recompile the main program.
@@ -58,10 +58,10 @@ For 8-bit color depth:
- Byte 2: Alpha byte (only with LV_IMG_CF_TRUE_COLOR_ALPHA)
You can store images in a *Raw* format to indicate that, it's not a built-in color format and an external [Image decoder](#image-decoder) needs to be used to decode the image.
You can store images in a *Raw* format to indicate that it's not encoded with one of the built-in color formats and an external [Image decoder](#image-decoder) needs to be used to decode the image.
- **LV_IMG_CF_RAW** Indicates a basic raw image (e.g. a PNG or JPG image).
- **LV_IMG_CF_RAW_ALPHA** Indicates that the image has alpha and an alpha byte is added for every pixel.
- **LV_IMG_CF_RAW_CHROME_KEYED** Indicates that the image is chrome keyed as described in `LV_IMG_CF_TRUE_COLOR_CHROMA_KEYED` above.
- **LV_IMG_CF_RAW_CHROME_KEYED** Indicates that the image is chroma-keyed as described in `LV_IMG_CF_TRUE_COLOR_CHROMA_KEYED` above.
## Add and use images
@@ -138,21 +138,21 @@ The image decoder consists of 4 callbacks:
- **read** if *open* didn't fully open the image this function should give some decoded data (max 1 line) from a given position.
- **close** close the opened image, free the allocated resources.
You can add any number of image decoders. When an image needs to be drawn, the library will try all the registered image decoder until finding one which can open the image, i.e. knowing that format.
You can add any number of image decoders. When an image needs to be drawn, the library will try all the registered image decoders until it finds one which can open the image, i.e. one which knows that format.
The `LV_IMG_CF_TRUE_COLOR_...`, `LV_IMG_INDEXED_...` and `LV_IMG_ALPHA_...` formats (essentially, all non-`RAW` formats) are understood by the built-in decoder.
### Custom image formats
The easiest way to create a custom image is to use the online image converter and set `Raw`, `Raw with alpha` or `Raw with chrome keyed` format. It will just take every byte of the binary file you uploaded and write it as the image "bitmap". You then need to attach an image decoder that will parse that bitmap and generate the real, renderable bitmap.
The easiest way to create a custom image is to use the online image converter and set `Raw`, `Raw with alpha` or `Raw with chroma-keyed` format. It will just take every byte of the binary file you uploaded and write it as the image "bitmap". You then need to attach an image decoder that will parse that bitmap and generate the real, renderable bitmap.
`header.cf` will be `LV_IMG_CF_RAW`, `LV_IMG_CF_RAW_ALPHA` or `LV_IMG_CF_RAW_CHROME_KEYED` accordingly. You should choose the correct format according to your needs: fully opaque image, use alpha channel or use chroma keying.
After decoding, the *raw* formats are considered *True color* by the library. In other words, the image decoder must decode the *Raw* images to *True color* according to the format described in [#color-formats](Color formats) section.
If you want to create a custom image, you should use `LV_IMG_CF_USER_ENCODED_0..7` color formats. However, the library can draw the images only in *True color* format (or *Raw* but finally it's supposed to be in *True color* format).
So the `LV_IMG_CF_USER_ENCODED_...` formats are not known by the library, therefore, they should be decoded to one of the known formats from [#color-formats](Color formats) section.
It's possible to decode the image to a non-true color format first, for example, `LV_IMG_INDEXED_4BITS`, and then call the built-in decoder functions to convert it to *True color*.
The `LV_IMG_CF_USER_ENCODED_...` formats are not known by the library and therefore they should be decoded to one of the known formats from [#color-formats](Color formats) section.
It's possible to decode the image to a non-true color format first (for example: `LV_IMG_INDEXED_4BITS`) and then call the built-in decoder functions to convert it to *True color*.
With *User encoded* formats, the color format in the open function (`dsc->header.cf`) should be changed according to the new format.
@@ -256,11 +256,11 @@ So in summary:
- In `decoder_open`, you should try to open the image source pointed by `dsc->src`. Its type is already in `dsc->src_type == LV_IMG_SRC_FILE/VARIABLE`.
If this format/type is not supported by the decoder, return `LV_RES_INV`.
However, if you can open the image, a pointer to the decoded *True color* image should be set in `dsc->img_data`.
If the format is known but, you don't want to decode while image (e.g. no memory for it) set `dsc->img_data = NULL` to call `read_line` to get the pixels.
If the format is known but you don't want to decode the entire image (e.g. no memory for it) set `dsc->img_data = NULL` to call `read_line` to get the pixels.
- In `decoder_close` you should free all the allocated resources.
- `decoder_read` is optional. Decoding the whole image requires extra memory and some computational overhead.
However, if can decode one line of the image without decoding the whole image, you can save memory and time.
To indicate that, the *line read* function should be used, set `dsc->img_data = NULL` in the open function.
To indicate that the *line read* function should be used, set `dsc->img_data = NULL` in the open function.
### Manually use an image decoder
@@ -301,15 +301,15 @@ To decide which image to close, LVGL uses a measurement it previously made of ho
If you want or need to override LVGL's measurement, you can manually set the *time to open* value in the decoder open function in `dsc->time_to_open = time_ms` to give a higher or lower value. (Leave it unchanged to let LVGL set it.)
Every cache entry has a *"life"* value. Every time an image opening happens through the cache, the *life* of all entries are decreased to make them older.
When a cached image is used, its *life* is increased by the *time to open* value to make it more alive.
Every cache entry has a *"life"* value. Every time an image opening happens through the cache, the *life* value of all entries is decreased to make them older.
When a cached image is used, its *life* value is increased by the *time to open* value to make it more alive.
If there is no more space in the cache, always the entry with the smallest life will be closed.
If there is no more space in the cache, the entry with the smallest life value will be closed.
### Memory usage
Note that, the cached image might continuously consume memory. For example, if 3 PNG images are cached, they will consume memory while they are opened.
Note that the cached image might continuously consume memory. For example, if 3 PNG images are cached, they will consume memory while they are open.
Therefore, it's the user's responsibility to be sure there is enough RAM to cache, even the largest images at the same time.
Therefore, it's the user's responsibility to be sure there is enough RAM to cache even the largest images at the same time.
### Clean the cache
Let's say you have loaded a PNG image into a `lv_img_dsc_t my_png` variable and use it in an `lv_img` object. If the image is already cached and you then change the underlying PNG file, you need to notify LVGL to cache the image again. Otherwise, there is no easy way of detecting that the underlying file changed and LVGL will still draw the old image.

View File

@@ -16,7 +16,7 @@ An input device usually means:
## Pointers
Pointer input devices can have a cursor. (typically for mouses)
Pointer input devices (like a mouse) can have a cursor.
```c
...
@@ -73,7 +73,7 @@ With an encoder, you should use only `LV_KEY_LEFT`, `LV_KEY_RIGHT`, and `LV_KEY_
#### Edit and navigate mode
Since a keypad has plenty of keys, it's easy to navigate between the objects and edit them using the keypad. But, the encoders have a limited number of "keys" hence, it is difficult to navigate using the default options. *Navigate* and *Edit* are created to avoid this problem with the encoders.
Since a keypad has plenty of keys, it's easy to navigate between the objects and edit them using the keypad. But the encoders have a limited number of "keys" and hence it is difficult to navigate using the default options. *Navigate* and *Edit* are created to avoid this problem with the encoders.
In *Navigate* mode, the encoders `LV_KEY_LEFT/RIGHT` is translated to `LV_KEY_NEXT/PREV`. Therefore the next or previous object will be selected by turning the encoder.
Pressing `LV_KEY_ENTER` will change to *Edit* mode.

View File

@@ -20,6 +20,7 @@
event
indev
display
color
font
image
file-system

View File

@@ -7,7 +7,7 @@
## Order of creation
By default, LVGL draws old objects on the background and new objects on the foreground.
By default, LVGL draws new objects on top of old objects.
For example, assume we added a button to a parent object named button1 and then another button named button2. Then button1 (with its child object(s)) will be in the background and can be covered by button2 and its children.
@@ -57,4 +57,4 @@ The `layer_top` can be used by the user to create some content visible everywher
lv_obj_set_click(lv_layer_top(), true);
```
The `layer_sys` is also used for a similar purpose on LVGL. For example, it places the mouse cursor above all layers to be sure it's always visible.
The `layer_sys` is also used for similar purposes on LVGL. For example, it places the mouse cursor above all layers to be sure it's always visible.

View File

@@ -4,10 +4,10 @@
```
# Objects
In the LVGL the **basic building blocks** of a user interface are the objects, also called *Widgets*.
In LVGL the **basic building blocks** of a user interface are the objects, also called *Widgets*.
For example a [Button](/widgets/core/btn), [Label](/widgets/core/label), [Image](/widgets/core/img), [List](/widgets/extra/list), [Chart](/widgets/extra/chart) or [Text area](/widgets/core/textarea).
Check all the [Object types](/widgets/index) here.
You can see all the [Object types](/widgets/index) here.
All objects are referenced using an `lv_obj_t` pointer as a handle. This pointer can later be used to set or get the attributes of the object.
@@ -39,7 +39,7 @@ The object types have special attributes too. For example, a slider has
- Minimum and maximum values
- Current value
For these attributes, every object type have unique API functions. For example for a slider:
For these special attributes, every object type may have unique API functions. For example for a slider:
```c
/*Set slider specific attributes*/
@@ -95,9 +95,9 @@ lv_obj_set_x(obj1, -30); /*Move the child a little bit off the parent*/
In LVGL objects can be created and deleted dynamically in run time. It means only the currently created (existing) objects consume RAM.
It allows to create a screen just when a button is clicked to open it. A delete the screen when a new screen is loaded.
This allows for the creation of a screen just when a button is clicked to open it, and for deletion of screens when a new screen is loaded.
Or the UI can be created based on the current environment of the device. For example create meter, charts, bars, slider etc according to the currently attached sensors.
UIs can be created based on the current environment of the device. For example one can create meters, charts, bars and sliders based on the currently attached sensors.
Every widget has its own **create** function with a prototype like this:
```c
@@ -116,8 +116,8 @@ void lv_obj_del(lv_obj_t * obj);
```
`lv_obj_del` will delete the object immediately.
If for any reason you can't delete the object immediately you can use `lv_obj_del_async(obj)` that will perefome the deletion on hte next call of `lv_timer_handler()`.
It is useful e.g. if you want to delete the parent of an object in the child's `LV_EVENT_DELETE` signal.
If for any reason you can't delete the object immediately you can use `lv_obj_del_async(obj)` that will perform the deletion on the next call of `lv_timer_handler()`.
This is useful e.g. if you want to delete the parent of an object in the child's `LV_EVENT_DELETE` handler.
You can remove all the children of an object (but not the object itself) using `lv_obj_clean(obj)`.
@@ -149,7 +149,7 @@ There are two automatically generated layers:
They are independent of the screens and they will be shown on every screen. The *top layer* is above every object on the screen and the *system layer* is above the *top layer* too.
You can add any pop-up windows to the *top layer* freely. But, the *system layer* is restricted to system-level things (e.g. mouse cursor will be placed here in `lv_indev_set_cursor()`).
The `lv_layer_top()` and `lv_layer_sys()` functions gives a pointer to the top or system layer.
The `lv_layer_top()` and `lv_layer_sys()` functions return pointers to the top and system layers respectively.
Read the [Layer overview](/overview/layer) section to learn more about layers.
@@ -176,11 +176,11 @@ Visit [Multi-display support](/overview/display) to learn more.
## Parts
The widgets are built from multiple parts. For example a [Base object](/widgets/obj) uses the main and scroll bar parts but a [Slider](/widgets/core/slider) uses the main, the indicator and the knob parts.
The widgets are built from multiple parts. For example a [Base object](/widgets/obj) uses the main and scrollbar parts but a [Slider](/widgets/core/slider) uses the main, the indicator and the knob parts.
Parts are similar to *pseudo elements* in CSS.
The following predefined parts exist in LVGL:
- `LV_PART_MAIN` A background like rectangle*/
- `LV_PART_MAIN` A background like rectangle*/``
- `LV_PART_SCROLLBAR` The scrollbar(s)
- `LV_PART_INDICATOR` Indicator, e.g. for slider, bar, switch, or the tick box of the checkbox
- `LV_PART_KNOB` Like a handle to grab to adjust the value*/
@@ -194,7 +194,7 @@ The main purpose of parts to allow styling the "components" of the widgets.
Therefore the parts are described in more detail in the [Style overview](/overview/style) section.
## States
The object can be in a combinations of the following states:
The object can be in a combination of the following states:
- `LV_STATE_DEFAULT` Normal, released state
- `LV_STATE_CHECKED` Toggled or checked state
- `LV_STATE_FOCUSED` Focused via keypad or encoder or clicked via touchpad/mouse

View File

@@ -9,7 +9,7 @@ In LVGL scrolling works very intuitively: if an object is out of its parent cont
Any object can be scrollable including `lv_obj_t`, `lv_img`, `lv_btn`, `lv_meter`, etc
The obejct can be scrolled either horizontally or vertically at a time, that is diagonal scrolling is not possible.
The object can either be scrolled either horizontally or vertically in one stroke; diagonal scrolling is not possible.
### Scrollbar
@@ -24,7 +24,7 @@ The scrollbars are displayed according to the set `mode`. The following `mode`s
#### Styling
The scrollbars have its own dedicated part, called `LV_PART_SCROLLBAR`. For example a scrollbar can turned to red like this:
The scrollbars have their own dedicated part, called `LV_PART_SCROLLBAR`. For example a scrollbar can turned to red like this:
```c
static lv_style_t style_red;
lv_style_init(&style_red);
@@ -83,13 +83,13 @@ OR-ed values are also possible. E.g. `LV_DIR_TOP | LV_DIR_LEFT`.
### Scroll chain
If an object can't be scrolled further (e.g. it's content has reached the bottom most position) the scrolling is propagated to it's parent. If the parent an be scrolled in that direction than it will be scrolled instead.
It goes to the grad parent and grand grandparents too.
It propagets to the grandparent and grand-grandparents too.
The propagation on scrolling in called "scroll chaining" and it can be enabled/disabled with the `LV_OBJ_FLAG_SCROLL_CHAIN` flag.
The propagation on scrolling is called "scroll chaining" and it can be enabled/disabled with the `LV_OBJ_FLAG_SCROLL_CHAIN` flag.
If chaining is disabled the propagation stops on the object and the parent(s) won't be scrolled.
### Scroll momentum
When the user scrolls an object and releases it LVGL can emulate a momentum for the scrolling. It's like to object were thrown and the scrolling slows down smoothly.
When the user scrolls an object and releases it, LVGL can emulate a momentum for the scrolling. It's like the object was thrown and scrolling slows down smoothly.
The scroll momentum can be enabled/disabled with the `LV_OBJ_FLAG_SCROLL_MOMENTUM` flag.
@@ -97,10 +97,10 @@ The scroll momentum can be enabled/disabled with the `LV_OBJ_FLAG_SCROLL_MOMENTU
Normally the content can't be scrolled inside the object. That is the top side of the content can't be below the top side of the object.
However, with `LV_OBJ_FLAG_SCROLL_ELASTIC` a fancy effect can be added when the user "over-scrolls" the content. The scrolling slows down, and the content can be scrolled inside the object.
When the object is releases the content is scrolled in it will be animated back to the valid position.
When the object is released the content scrolled in it will be animated back to the valid position.
### Snaping
The children of an object can be snapped according to specific rules when scrolling ends. Children can be made snapable individually with the `LV_OBJ_FLAG_SNAPABLE` flag.
### Snapping
The children of an object can be snapped according to specific rules when scrolling ends. Children can be made snappable individually with the `LV_OBJ_FLAG_SNAPABLE` flag. (Note misspelling of the flag name: your code needs to spell it with one P.)
The object can align the snapped children in 4 ways:
- `LV_SCROLL_SNAP_NONE` Snapping is disabled. (default)
- `LV_SCROLL_SNAP_START` Align the children to the left/top side of the scrolled object
@@ -109,15 +109,15 @@ The object can align the snapped children in 4 ways:
The alignment can be set with `lv_obj_set_scroll_snap_x/y(obj, LV_SCROLL_SNAP_...)`:
Under the hood the followings happen
Under the hood the following happens:
1. User scrolls an object and releases the screen
2. LVGL calculates where would the scroll end considering scroll momentum
2. LVGL calculates where the scroll would end considering scroll momentum
3. LVGL finds the nearest scroll point
4. LVGL scrolls the snap point with an animation
4. LVGL scrolls to the snap point with an animation
### Scroll one
The "scroll one" feature tells LVGL to allow scrolling only one snapable children at a time.
So it requires to make the children snapable and and set a scroll snap alignment different from `LV_SCROLL_SNAP_NONE`.
The "scroll one" feature tells LVGL to allow scrolling only one snappable child at a time.
So this requires to make the children snappable (LV_OBJ_FLAG_SNAPABLE spelled with one P in code) and and set a scroll snap alignment different from `LV_SCROLL_SNAP_NONE`.
This feature can be enabled by the `LV_OBJ_FLAG_SCROLL_ONE` flag.

View File

@@ -93,7 +93,7 @@ Set the Y coordinate of the object considering the set `align`. Pixel and percen
### align
Set the alignment which tells from which point of the parent the X and Y coordinates should be interpreted. The possible values are: `LV_ALIGN_TOP_LEFT/MID/RIGHT`, `LV_ALIGN_BOTTOM_LEFT/MID/RIGHT`, `LV_ALIGN_LEFT/RIGHT_MID`, `LV_ALIGN_CENTER`
Set the alignment which determines from which point of the parent the X and Y coordinates should be interpreted. The possible values are: `LV_ALIGN_TOP_LEFT/MID/RIGHT`, `LV_ALIGN_BOTTOM_LEFT/MID/RIGHT`, `LV_ALIGN_LEFT/RIGHT_MID`, `LV_ALIGN_CENTER`
<ul>
<li style='display:inline; margin-right: 20px; margin-left: 0px'><strong>Default</strong> 0</li>
<li style='display:inline; margin-right: 20px; margin-left: 0px'><strong>Inherited</strong> No</li>
@@ -264,7 +264,7 @@ Enable to clip the overflowed content on the rounded corner. Can be `true` or `f
### opa
Scale down all opacity values of the object by this factor. Value 0, `LV_OPA_0` or `LV_OPA_TRANSP` means fully transparent, 256, `LV_OPA_100` or `LV_OPA_COVER` means fully covering, other values or LV_OPA_10, LV_OPA_20, etc means semi transparency.
Scale down all opacity values of the object by this factor. Value 0, `LV_OPA_0` or `LV_OPA_TRANSP` means fully transparent, 256, `LV_OPA_100` or `LV_OPA_COVER` means fully covering, other values or LV_OPA_10, LV_OPA_20, etc indicate semi-transparency.
<ul>
<li style='display:inline; margin-right: 20px; margin-left: 0px'><strong>Default</strong> 0</li>
<li style='display:inline; margin-right: 20px; margin-left: 0px'><strong>Inherited</strong> No</li>
@@ -297,7 +297,7 @@ The intensity of mixing of color filter.
### anim_time
The animation time in milliseconds. It's meaning is widget specific. E.g. blink time of the cursor on the text area or scroll time of a roller. See the widgets' documentation to learn more.
The animation time in milliseconds. Its meaning is widget specific. E.g. blink time of the cursor on the text area or scroll time of a roller. See the widgets' documentation to learn more.
<ul>
<li style='display:inline; margin-right: 20px; margin-left: 0px'><strong>Default</strong> 0</li>
<li style='display:inline; margin-right: 20px; margin-left: 0px'><strong>Inherited</strong> No</li>
@@ -308,7 +308,7 @@ The animation time in milliseconds. It's meaning is widget specific. E.g. blink
### anim_speed
The animation speed in pixel/sec. It's meaning is widget specific. E.g. scroll speed of label. See the widgets' documentation to learn more.
The animation speed in pixel/sec. Its meaning is widget specific. E.g. scroll speed of label. See the widgets' documentation to learn more.
<ul>
<li style='display:inline; margin-right: 20px; margin-left: 0px'><strong>Default</strong> 0</li>
<li style='display:inline; margin-right: 20px; margin-left: 0px'><strong>Inherited</strong> No</li>
@@ -330,7 +330,7 @@ An initialized `lv_style_transition_dsc_t` to describe a transition.
### blend_mode
Describes how to blend the colors to the background. The possibel values are `LV_BLEND_MODE_NORMAL/ADDITIVE/SUBTRACTIVE`
Describes how to blend the colors to the background. The possible values are `LV_BLEND_MODE_NORMAL/ADDITIVE/SUBTRACTIVE`
<ul>
<li style='display:inline; margin-right: 20px; margin-left: 0px'><strong>Default</strong> 0</li>
<li style='display:inline; margin-right: 20px; margin-left: 0px'><strong>Inherited</strong> No</li>
@@ -352,7 +352,7 @@ Set the layout if the object. The children will be repositioned and resized acco
### base_dir
Set the base direction of the obejct. The possible values are `LV_BIDI_DIR_LTR/RTL/AUTO`.
Set the base direction of the object. The possible values are `LV_BIDI_DIR_LTR/RTL/AUTO`.
<ul>
<li style='display:inline; margin-right: 20px; margin-left: 0px'><strong>Default</strong> 0</li>
<li style='display:inline; margin-right: 20px; margin-left: 0px'><strong>Inherited</strong> No</li>
@@ -377,7 +377,7 @@ Set the background color of the object.
### bg_opa
Set the opacity of the background. Value 0, `LV_OPA_0` or `LV_OPA_TRANSP` means fully transparent, 256, `LV_OPA_100` or `LV_OPA_COVER` means fully covering, other values or LV_OPA_10, LV_OPA_20, etc means semi transparency.
Set the opacity of the background. Value 0, `LV_OPA_0` or `LV_OPA_TRANSP` means fully transparent, 256, `LV_OPA_100` or `LV_OPA_COVER` means fully covering, other values or LV_OPA_10, LV_OPA_20, etc indicate semi-transparency.
<ul>
<li style='display:inline; margin-right: 20px; margin-left: 0px'><strong>Default</strong> 0</li>
<li style='display:inline; margin-right: 20px; margin-left: 0px'><strong>Inherited</strong> No</li>
@@ -443,7 +443,7 @@ Set a background image. Can be a pointer to `lv_img_dsc_t`, a path to a file or
### bg_img_opa
Set the opacity of the background image. Value 0, `LV_OPA_0` or `LV_OPA_TRANSP` means fully transparent, 256, `LV_OPA_100` or `LV_OPA_COVER` means fully covering, other values or LV_OPA_10, LV_OPA_20, etc means semi transparency.
Set the opacity of the background image. Value 0, `LV_OPA_0` or `LV_OPA_TRANSP` means fully transparent, 256, `LV_OPA_100` or `LV_OPA_COVER` means fully covering, other values or LV_OPA_10, LV_OPA_20, etc indicate semi-transparency.
<ul>
<li style='display:inline; margin-right: 20px; margin-left: 0px'><strong>Default</strong> 0</li>
<li style='display:inline; margin-right: 20px; margin-left: 0px'><strong>Inherited</strong> No</li>
@@ -476,7 +476,7 @@ Set the intensity of background image recoloring. Value 0, `LV_OPA_0` or `LV_OPA
### bg_img_tiled
If enbaled the background image will be tiled. The possible values are `true` or `false`.
If enabled the background image will be tiled. The possible values are `true` or `false`.
<ul>
<li style='display:inline; margin-right: 20px; margin-left: 0px'><strong>Default</strong> 0</li>
<li style='display:inline; margin-right: 20px; margin-left: 0px'><strong>Inherited</strong> No</li>
@@ -501,7 +501,7 @@ Set the color of the border
### border_opa
Set the opcitiy of the border. Value 0, `LV_OPA_0` or `LV_OPA_TRANSP` means fully transparent, 256, `LV_OPA_100` or `LV_OPA_COVER` means fully covering, other values or LV_OPA_10, LV_OPA_20, etc means semi transparency.
Set the opcitiy of the border. Value 0, `LV_OPA_0` or `LV_OPA_TRANSP` means fully transparent, 256, `LV_OPA_100` or `LV_OPA_COVER` means fully covering, other values or LV_OPA_10, LV_OPA_20, etc indicate semi-transparency.
<ul>
<li style='display:inline; margin-right: 20px; margin-left: 0px'><strong>Default</strong> 0</li>
<li style='display:inline; margin-right: 20px; margin-left: 0px'><strong>Inherited</strong> No</li>
@@ -512,7 +512,7 @@ Set the opcitiy of the border. Value 0, `LV_OPA_0` or `LV_OPA_TRANSP` means full
### border_width
Set hte width of the border. Only pixel values can be used.
Set the width of the border. Only pixel values can be used.
<ul>
<li style='display:inline; margin-right: 20px; margin-left: 0px'><strong>Default</strong> 0</li>
<li style='display:inline; margin-right: 20px; margin-left: 0px'><strong>Inherited</strong> No</li>
@@ -523,7 +523,7 @@ Set hte width of the border. Only pixel values can be used.
### border_side
Set ony which side(s) the border should be drawn. The possible values are `LV_BORDER_SIDE_NONE/TOP/BOTTOM/LEFT/RIGHT/INTERNAL`. OR-ed calues an be used as well, e.g. `LV_BORDER_SIDE_TOP | LV_BORDER_SIDE_LEFT`.
Set which side(s) the border should be drawn. The possible values are `LV_BORDER_SIDE_NONE/TOP/BOTTOM/LEFT/RIGHT/INTERNAL`. OR-ed calues an be used as well, e.g. `LV_BORDER_SIDE_TOP | LV_BORDER_SIDE_LEFT`.
<ul>
<li style='display:inline; margin-right: 20px; margin-left: 0px'><strong>Default</strong> 0</li>
<li style='display:inline; margin-right: 20px; margin-left: 0px'><strong>Inherited</strong> No</li>
@@ -534,7 +534,7 @@ Set ony which side(s) the border should be drawn. The possible values are `LV_BO
### border_post
Sets wheter the the border should be drawn before or after the children ar drawn. `true`: after children, `false`: before children
Sets wheter the border should be drawn before or after the children ar drawn. `true`: after children, `false`: before children
<ul>
<li style='display:inline; margin-right: 20px; margin-left: 0px'><strong>Default</strong> 0</li>
<li style='display:inline; margin-right: 20px; margin-left: 0px'><strong>Inherited</strong> No</li>
@@ -559,7 +559,7 @@ Sets the color of the text.
### text_opa
Set the opacity of the text. Value 0, `LV_OPA_0` or `LV_OPA_TRANSP` means fully transparent, 256, `LV_OPA_100` or `LV_OPA_COVER` means fully covering, other values or LV_OPA_10, LV_OPA_20, etc means semi transparency.
Set the opacity of the text. Value 0, `LV_OPA_0` or `LV_OPA_TRANSP` means fully transparent, 256, `LV_OPA_100` or `LV_OPA_COVER` means fully covering, other values or LV_OPA_10, LV_OPA_20, etc indicate semi-transparency.
<ul>
<li style='display:inline; margin-right: 20px; margin-left: 0px'><strong>Default</strong> 0</li>
<li style='display:inline; margin-right: 20px; margin-left: 0px'><strong>Inherited</strong> No</li>
@@ -628,7 +628,7 @@ TODO
### img_opa
Set the opacity of an image. Value 0, `LV_OPA_0` or `LV_OPA_TRANSP` means fully transparent, 256, `LV_OPA_100` or `LV_OPA_COVER` means fully covering, other values or LV_OPA_10, LV_OPA_20, etc means semi transparency.
Set the opacity of an image. Value 0, `LV_OPA_0` or `LV_OPA_TRANSP` means fully transparent, 256, `LV_OPA_100` or `LV_OPA_COVER` means fully covering, other values or LV_OPA_10, LV_OPA_20, etc indicate semi-transparency.
<ul>
<li style='display:inline; margin-right: 20px; margin-left: 0px'><strong>Default</strong> 0</li>
<li style='display:inline; margin-right: 20px; margin-left: 0px'><strong>Inherited</strong> No</li>
@@ -639,7 +639,7 @@ Set the opacity of an image. Value 0, `LV_OPA_0` or `LV_OPA_TRANSP` means fully
### img_recolor
Set color to mixt to the image.
Set color to mix to the image.
<ul>
<li style='display:inline; margin-right: 20px; margin-left: 0px'><strong>Default</strong> 0</li>
<li style='display:inline; margin-right: 20px; margin-left: 0px'><strong>Inherited</strong> No</li>
@@ -650,7 +650,7 @@ Set color to mixt to the image.
### img_recolor_opa
Set the intensity of the color mixing. Value 0, `LV_OPA_0` or `LV_OPA_TRANSP` means fully transparent, 256, `LV_OPA_100` or `LV_OPA_COVER` means fully covering, other values or LV_OPA_10, LV_OPA_20, etc means semi transparency.
Set the intensity of the color mixing. Value 0, `LV_OPA_0` or `LV_OPA_TRANSP` means fully transparent, 256, `LV_OPA_100` or `LV_OPA_COVER` means fully covering, other values or LV_OPA_10, LV_OPA_20, etc indicate semi-transparency.
<ul>
<li style='display:inline; margin-right: 20px; margin-left: 0px'><strong>Default</strong> 0</li>
<li style='display:inline; margin-right: 20px; margin-left: 0px'><strong>Inherited</strong> No</li>
@@ -686,7 +686,7 @@ Set the color of the outline.
### outline_opa
Set the opacity of the outline. Value 0, `LV_OPA_0` or `LV_OPA_TRANSP` means fully transparent, 256, `LV_OPA_100` or `LV_OPA_COVER` means fully covering, other values or LV_OPA_10, LV_OPA_20, etc means semi transparency.
Set the opacity of the outline. Value 0, `LV_OPA_0` or `LV_OPA_TRANSP` means fully transparent, 256, `LV_OPA_100` or `LV_OPA_COVER` means fully covering, other values or LV_OPA_10, LV_OPA_20, etc indicate semi-transparency.
<ul>
<li style='display:inline; margin-right: 20px; margin-left: 0px'><strong>Default</strong> 0</li>
<li style='display:inline; margin-right: 20px; margin-left: 0px'><strong>Inherited</strong> No</li>
@@ -744,7 +744,7 @@ Set an offset on the shadow in pixels in Y direction.
### shadow_spread
Make the shadow calcuation to use a larger or smaller rectangle as base. The value can be in pixel t make the area larger/smaller
Make the shadow calculation to use a larger or smaller rectangle as base. The value can be in pixel to make the area larger/smaller
<ul>
<li style='display:inline; margin-right: 20px; margin-left: 0px'><strong>Default</strong> 0</li>
<li style='display:inline; margin-right: 20px; margin-left: 0px'><strong>Inherited</strong> No</li>
@@ -766,7 +766,7 @@ Set the color of the shadow
### shadow_opa
Set the opacity of the shadow. Value 0, `LV_OPA_0` or `LV_OPA_TRANSP` means fully transparent, 256, `LV_OPA_100` or `LV_OPA_COVER` means fully covering, other values or LV_OPA_10, LV_OPA_20, etc means semi transparency.
Set the opacity of the shadow. Value 0, `LV_OPA_0` or `LV_OPA_TRANSP` means fully transparent, 256, `LV_OPA_100` or `LV_OPA_COVER` means fully covering, other values or LV_OPA_10, LV_OPA_20, etc indicate semi-transparency.
<ul>
<li style='display:inline; margin-right: 20px; margin-left: 0px'><strong>Default</strong> 0</li>
<li style='display:inline; margin-right: 20px; margin-left: 0px'><strong>Inherited</strong> No</li>
@@ -813,7 +813,7 @@ Set the gap between dashes in pixel. Note that dash works only on horizontal and
### line_rounded
Make the end points of the lines rounded. `true`: rounded, `false`: perpandicular line ending
Make the end points of the lines rounded. `true`: rounded, `false`: perpendicular line ending
<ul>
<li style='display:inline; margin-right: 20px; margin-left: 0px'><strong>Default</strong> 0</li>
<li style='display:inline; margin-right: 20px; margin-left: 0px'><strong>Inherited</strong> No</li>
@@ -849,7 +849,7 @@ TODO
### arc_width
Set the width (ticjkness) of the arcs in pixel.
Set the width (thickness) of the arcs in pixel.
<ul>
<li style='display:inline; margin-right: 20px; margin-left: 0px'><strong>Default</strong> 0</li>
<li style='display:inline; margin-right: 20px; margin-left: 0px'><strong>Inherited</strong> No</li>
@@ -860,7 +860,7 @@ Set the width (ticjkness) of the arcs in pixel.
### arc_rounded
Make the end points of the arcs rounded. `true`: rounded, `false`: perpandicular line ending
Make the end points of the arcs rounded. `true`: rounded, `false`: perpendicular line ending
<ul>
<li style='display:inline; margin-right: 20px; margin-left: 0px'><strong>Default</strong> 0</li>
<li style='display:inline; margin-right: 20px; margin-left: 0px'><strong>Inherited</strong> No</li>

View File

@@ -4,10 +4,10 @@
```
# Styles
*Styles* are used to set the appearance of the objects. Styles in lvgl are heavily inspired by CSS. The concept in nutshell is the following:
- A style is an `lv_style_t` variable which can hold properties, for example border width, text color and so on. It's similar to a `class` in CSS.
*Styles* are used to set the appearance of the objects. Styles in lvgl are heavily inspired by CSS. The concept in nutshell is as follows:
- A style is an `lv_style_t` variable which can hold properties like border width, text color and so on. It's similar to a `class` in CSS.
- Styles can be assigned to objects to change their appearance. During the assignment the target part (*pseudo element* in CSS) and target state (*pseudo class*) can be specified.
For example add `style_blue` to the knob of a slider when it's in pressed state.
For example one can add `style_blue` to the knob of a slider when it's in pressed state.
- The same style can be used by any number of objects.
- Styles can be cascaded which means multiple styles can be assigned to an object and each style can have different properties.
Therefore not all properties have to be specified in style. LVLG will look for a property until a style defines it or use a default if it's not spefied by any of the styles.
@@ -35,16 +35,16 @@ The objects can be in the combination of the following states:
- `LV_STATE_USER_3` (0x4000) Custom state
- `LV_STATE_USER_4` (0x8000) Custom state
The combination states the object can be focused and pressed at the same time. It represented as `LV_STATE_FOCUSED | LV_STATE_PRESSED`.
The combination states the object can be focused and pressed at the same time. This is represented as `LV_STATE_FOCUSED | LV_STATE_PRESSED`.
The style can be added to any state and state combination.
For example, setting a different background color for default and pressed state.
If a property is not defined in a state the best matching state's property will be used. Typically it means the property with `LV_STATE_DEFAULT` state.˛
If a property is not defined in a state the best matching state's property will be used. Typically this means the property with `LV_STATE_DEFAULT` is used.˛
If the property is not set even for the default state the default value will be used. (See later)
But what does the "best matching state's property" really means?
But what does the "best matching state's property" really mean?
States have a precedence which is shown by their value (see in the above list). A higher value means higher precedence.
To determine which state's property to use let's use an example. Let's see the background color is defined like this:
To determine which state's property to use let's take an example. Imagine the background color is defined like this:
- `LV_STATE_DEFAULT`: white
- `LV_STATE_PRESSED`: gray
- `LV_STATE_FOCUSED`: red
@@ -55,13 +55,13 @@ The pressed state has 0x0020 precedence which is higher than the default state's
3. When the object is focused the same thing happens as in pressed state and red color will be used. (Focused state has higher precedence than default state).
4. When the object is focused and pressed both gray and red would work, but the pressed state has higher precedence than focused so gray color will be used.
5. It's possible to set e.g rose color for `LV_STATE_PRESSED | LV_STATE_FOCUSED`.
In this case, this combined state has 0x0020 + 0x0002 = 0x0022 precedence, which higher than the pressed states precedence so rose color would be used.
6. When the object is in checked state there is no property to set the background color for this state. So in lack of a better option, the object remains white from the default state's property.
In this case, this combined state has 0x0020 + 0x0002 = 0x0022 precedence, which is higher than the pressed state's precedence so rose color would be used.
6. When the object is in checked state there is no property to set the background color for this state. So for lack of a better option, the object remains white from the default state's property.
Some practical notes:
- The precedence (value) of states is quite intuitive and it's something the user would expect naturally. E.g. if an object is focused, the user still want to see if it's pressed, therefore pressed state has a higher precedence.
If the focused state had higher precedence it would overwrite the pressed color.
- If you want to set a property for all state (e.g. red background color) just set it for the default state. If the object can't find a property for its current state it will fall back to the default state's property.
- The precedence (value) of states is quite intuitive and it's something the user would expect naturally. E.g. if an object is focused the user will still want to see if it's pressed, therefore pressed state has a higher precedence.
If the focused state had a higher precedence it would overwrite the pressed color.
- If you want to set a property for all states (e.g. red background color) just set it for the default state. If the object can't find a property for its current state it will fall back to the default state's property.
- Use ORed states to describe the properties for complex cases. (E.g. pressed + checked + focused)
- It might be a good idea to use different style elements for different states.
For example, finding background colors for released, pressed, checked + pressed, focused, focused + pressed, focused + pressed + checked, etc states is quite difficult.
@@ -71,21 +71,21 @@ Instead, for example, use the background color for pressed and checked states an
It's not required to set all the properties in one style. It's possible to add more styles to an object and let the later added style to modify or extend appearance.
For example, create a general gray button style and create a new for red buttons where only the new background color is set.
It's the same concept when in CSS all the used classes are listed like `<div class=".btn .btn-red">`.
This is much like in CSS when used classes are listed like `<div class=".btn .btn-red">`.
The later added styles have higher precedence over the earlier ones. So in the gray/red button example above, the normal button style should be added first and the red style second.
Styles added later have precedence over ones set earlier. So in the gray/red button example above, the normal button style should be added first and the red style second.
However, the precedence coming from states are still taken into account.
So let's examine the following case:
- the basic button style defines dark-gray color for default state and light-gray color pressed state
- the red button style defines the background color as red only in the default state
In this case, when the button is released (it's in default state) it will be red because a perfect match is found in the lastly added style (red style).
In this case, when the button is released (it's in default state) it will be red because a perfect match is found in the most recently added style (red).
When the button is pressed the light-gray color is a better match because it describes the current state perfectly, so the button will be light-gray.
## Inheritance
Some properties (typically that are related to texts) can be inherited from the parent object's styles.
Inheritance is applied only if the given property is not set in the object's styles (even in default state).
In this case, if the property is inheritable, the property's value will be searched in the parents too until an object can tell a value for the property. The parents will use their own state to tell the value.
In this case, if the property is inheritable, the property's value will be searched in the parents too until an object specifies a value for the property. The parents will use their own state to detemine the value.
So if a button is pressed, and the text color comes from here, the pressed text color will be used.
@@ -98,7 +98,7 @@ The following predefined parts exist in LVGL:
- `LV_PART_INDICATOR` Indicator, e.g. for slider, bar, switch, or the tick box of the checkbox
- `LV_PART_KNOB` Like a handle to grab to adjust the value*/
- `LV_PART_SELECTED` Indicate the currently selected option or section
- `LV_PART_ITEMS` Used if the widget has multiple similar elements (e.g. tabel cells)*/
- `LV_PART_ITEMS` Used if the widget has multiple similar elements (e.g. table cells)*/
- `LV_PART_TICKS` Ticks on scales e.g. for a chart or meter
- `LV_PART_CURSOR` Mark a specific place e.g. text area's or chart's cursor
- `LV_PART_CUSTOM_FIRST` Custom parts can be added from here.
@@ -139,7 +139,7 @@ To remove a property use:
lv_style_remove_prop(&style, LV_STYLE_BG_COLOR);
```
To get a properties value from style:
To get a property's value from a style:
```c
lv_style_value_t v;
lv_res_t res = lv_style_rget_prop(&style, LV_STYLE_BG_COLOR, &v);
@@ -159,7 +159,7 @@ lv_style_reset(&style);
```
## Add and remove styles to a widget
A style on its own not that useful. It should be assigned to an object to take its effect.
A style on its own is not that useful, it needs to be assigned to an object to take effect.
### Add styles
To add a style to an object use `lv_obj_add_style(obj, &style, <selector>)`. `<selector>` is an OR-ed value of parts and state to which the style should be added. Some examples:
@@ -188,7 +188,7 @@ If a style which is already assigned to object changes (i.e. a property is added
1. If you know that the changed properties can be applied by a simple redraw (e.g. color or opacity changes) just call `lv_obj_invalidate(obj)` or `lv_obj_invalideate(lv_scr_act())`.
2. If more complex style properties were changed or added, and you know which object(s) are affected by that style call `lv_obj_refresh_style(obj, part, property)`.
To refresh all parts and properties use `lv_obj_refresh_style(obj, LV_PART_ANY, LV_STYLE_PROP_ANY)`.
3. No make LVGL check all object whether they use the style and refresh them call `lv_obj_report_style_change(&style)`. If `style` is `NULL` all object's will be notified about the style change.
3. To make LVGL check all objects to see whether they use the style and refresh them when needed call `lv_obj_report_style_change(&style)`. If `style` is `NULL` all objects will be notified about the style change.
### Get a property's value on an object
To get a final value of property - considering cascading, inheritance, local styles and transitions (see below) - get functions like this can be used:
@@ -205,7 +205,7 @@ Besides "normal" styles, the objects can store local styles too. This concept is
So local styles are like normal styles but they can't be shared among other objects. If used, local styles are allocated automatically, and freed when the object is deleted.
They are useful to add local customization to the object.
Unlike in CSS, in LVGL local styles can be assigned to states (*pseudo-classes*) and parts (pseudo-elements).
Unlike in CSS, in LVGL local styles can be assigned to states (*pseudo-classes*) and parts (*pseudo-elements*).
To set a local property use functions like `lv_obj_set_style_local_<property_name>(obj, <value>, <selector>);`  
For example:
@@ -236,9 +236,9 @@ The parameters of the transitions are stored in the styles. It's possible to set
- the animation path (also known as timing or easing function)
- the properties to animate
The transition properties can be defined for each state. For example, setting 500 ms transition time in default state will mean that when the object goes to default state 500 ms transition time will be applied.
Setting 100 ms transition time in the pressed state will mean a 100 ms transition time when going to presses state.
So this example configuration will result in fast going to presses state and slow going back to default.
The transition properties can be defined for each state. For example, setting 500 ms transition time in default state will mean that when the object goes to the default state a 500 ms transition time will be applied.
Setting 100 ms transition time in the pressed state will mean a 100 ms transition time when going to pressed state.
So this example configuration will result in going to pressed state quickly and then going back to default slowly.
To describe a transition an `lv_transition_dsc_t` variable needs to initialized and added to a style:
```c
@@ -259,12 +259,12 @@ TODO
## Themes
Themes are a collection of styles. If there is an active theme LVGL applies it on the every created widget.
It gives a default appearance to UI which can be modified by adding further styles.
Themes are a collection of styles. If there is an active theme LVGL applies it on every created widget.
This will give a default appearance to the UI which can then be modified by adding further styles.
Every display can have a different theme. For example a colorful theme on a TFT and monochrome theme on a secondary monochrome display.
Every display can have a different theme. For example you could have a colorful theme on a TFT and monochrome theme on a secondary monochrome display.
To set a theme for a display 2 steps are required:
To set a theme for a display, 2 steps are required:
1. Initialize a theme
2. Assign the initialized theme to a display.

View File

@@ -4,7 +4,7 @@
```
# Timers
LVGL has a built-in timer system. You can register a function to have it be called periodically. The timers are handled and called in `lv_timer_handler()`, which needs to be called periodically every few milliseconds.
LVGL has a built-in timer system. You can register a function to have it be called periodically. The timers are handled and called in `lv_timer_handler()`, which needs to be called every few milliseconds.
See [Porting](/porting/task-handler) for more information.
The timers are non-preemptive, which means a timer cannot interrupt another timer. Therefore, you can call any LVGL related function in a timer.
@@ -12,7 +12,7 @@ The timers are non-preemptive, which means a timer cannot interrupt another time
## Create a timer
To create a new timer, use `lv_timer_create(timer_cb, period_ms, user_data)`. It will create an `lv_timer_t *` variable, which can be used later to modify the parameters of the timer.
`lv_timer_create_basic()` can also be used. It allows you to create a new timer without specifying any parameters.
`lv_timer_create_basic()` can also be used. This allows you to create a new timer without specifying any parameters.
A timer callback should have `void (*lv_timer_cb_t)(lv_timer_t *);` prototype.
@@ -52,13 +52,13 @@ You can modify some parameters of the timers later:
## Repeat count
You can make a timer repat only a given times with `lv_timer_set_repeat_count(timer, count)`. The timer will automatically be deleted after being called the defined times. Set the count to `-1` to repeat infinitly.
You can make a timer repeat only a given number of times with `lv_timer_set_repeat_count(timer, count)`. The timer will automatically be deleted after being called the defined number of times. Set the count to `-1` to repeat indefinitely.
## Measure idle time
You can get the idle percentage time of `lv_timer_handler` with `lv_timer_get_idle()`. Note that, it doesn't measure the idle time of the overall system, only `lv_timer_handler`.
It can be misleading if you use an operating system and call `lv_timer_handler` in an timer, as it won't actually measure the time the OS spends in an idle thread.
It can be misleading if you use an operating system and call `lv_timer_handler` in a timer, as it won't actually measure the time the OS spends in an idle thread.
## Asynchronous calls

View File

@@ -4,14 +4,14 @@
```
# Display interface
To register a display for LVGL an `lv_disp_draw_buf_t` and an `lv_disp_drv_t` variables have to be initialized.
- `lv_disp_draw_buf_t` contains internal graphic buffer(s), called draw buffer(s).
To register a display for LVGL a `lv_disp_draw_buf_t` and a `lv_disp_drv_t` variable have to be initialized.
- `lv_disp_draw_buf_t` contains internal graphic buffer(s) called draw buffer(s).
- `lv_disp_drv_t` contains callback functions to interact with the display and manipulate drawing related things.
## Draw buffer
Draw buffer(s) are simple array(s) that LVGL uses to render the content of the screen.
Once rendering is ready the content of the draw buffer is send to display using the `flush_cb` set in the display driver (see below).
Once rendering is ready the content of the draw buffer is sent to the display using the `flush_cb` function set in the display driver (see below).
A draw draw buffer can be initialized via a `lv_disp_draw_buf_t` variable like this:
```c
@@ -28,8 +28,8 @@ lv_disp_draw_buf_init(&disp_buf, buf_1, buf_2, MY_DISP_HOR_RES*10);
Note that `lv_disp_draw_buf_t` needs to be static, global or dynamically allocated and not a local variable destroyed if goes out of the scope.
As you can see the draw buffer can be smaller than the screen. In this case, the larger areas will be redrawn in smaller parts that fit into the draw buffer(s).
If only a small area changes (e.g. a button is pressed) then only that area will be refreshed.
As you can see the draw buffer can be smaller than the screen. In this case, the larger areas will be redrawn in smaller parts that fit into the draw buffer(s).
If only a small area changes (e.g. a button is pressed) then only that area will be refreshed.
A larger buffer results in better performance but above 1/10 screen sized buffer(s) there is no significant performance improvement.
Therefore it's recommended to choose the size of the draw buffer(s) to at least 1/10 screen sized.
@@ -41,31 +41,31 @@ If **two buffers** are used LVGL can draw into one buffer while the content of
DMA or other hardware should be used to transfer the data to the display to let the MCU draw meanwhile.
This way, the rendering and refreshing of the display become parallel.
In the display driver (`lv_disp_drv_t`) the `full_refresh` bit can be enabled to force LVGL always redraw the whole screen. It works in both *one buffer* and *two buffers* modes.
In the display driver (`lv_disp_drv_t`) the `full_refresh` bit can be enabled to force LVGL to always redraw the whole screen. This works in both *one buffer* and *two buffers* modes.
If `full_refresh` is enabled and 2 screen sized draw buffers are provided, LVGL work as "traditional" double buffering.
It means in `flush_cb` only the address of the frame buffer needs to be changed to provided pointer (`color_p` parameter).
If `full_refresh` is enabled and 2 screen sized draw buffers are provided, LVGL's display handling works like "traditional" double buffering.
This means in `flush_cb` only the address of the frame buffer needs to be changed to the provided pointer (`color_p` parameter).
This configuration should be used if the MCU has LCD controller periphery and not with an external display controller (e.g. ILI9341 or SSD1963).
You can measure the performance of different draw buffer configurations using the [benchmark example](https://github.com/lvgl/lv_demos/tree/master/src/lv_demo_benchmark).
## Display driver
Once the buffer initialization is ready a `lv_disp_drv_t` display drivers need to be
Once the buffer initialization is ready a `lv_disp_drv_t` display driver needs to be
1. initialized with `lv_disp_drv_init(&disp_drv)`
2. its fields needs to be set
3. registered in LVGL with `lv_disp_drv_register(&disp_drv)`
2. its fields need to be set
3. it needs to be registered in LVGL with `lv_disp_drv_register(&disp_drv)`
Note that `lv_disp_drv_t` also needs to be static, global or dynamically allocated and not a local variable destroyed if goes out of the scope.
### Mandatory fields
In the most simple case only the following fields of `lv_disp_drv_t` needs to be set:
In the most simple case only the following fields of `lv_disp_drv_t` need to be set:
- `draw_buf` pointer to an initialized `lv_disp_draw_buf_t` variable.
- `hor_res` horizontal resolution of the display in pixels.
- `ver_res` vertical resolution of the display in pixels.
- `flush_cb` a callback function to copy a buffer's content to a specific area of the display.
`lv_disp_flush_ready(&disp_drv)` needs to be called when flushing is ready.
LVGL might render the screen in multiple chunks and therefore call `flush_cb` multiple times. To see which is the last chunk of rendering use `lv_disp_flush_is_last(&disp_drv)`.
LVGL might render the screen in multiple chunks and therefore call `flush_cb` multiple times. To see if the current one is the last chunk of rendering use `lv_disp_flush_is_last(&disp_drv)`.
### Optional fields
There are some optional data fields:
@@ -85,7 +85,7 @@ This way the buffers used in `lv_disp_draw_buf_t` can be smaller to hold only th
LVGL has built-in support to several GPUs (see `lv_conf.h`) but if something else is required these functions can be used to make LVGL use a GPU:
- `gpu_fill_cb` fill an area in the memory with a color.
- `gpu_wait_cb` if any GPU function return, while the GPU is still working, LVGL will use this function when required the be sure GPU rendering is ready.
- `gpu_wait_cb` if any GPU function returns while the GPU is still working, LVGL will use this function when required to make sure GPU rendering is ready.
### Examples
All together it looks like this:

View File

@@ -28,7 +28,7 @@ lv_indev_t * my_indev = lv_indev_drv_register(&indev_drv);
Visit [Input devices](/overview/indev) to learn more about input devices in general.
### Touchpad, mouse or any pointer
Input devices that can click points of the screen belong to this category.
Input devices that can click points on the screen belong to this category.
```c
indev_drv.type = LV_INDEV_TYPE_POINTER;
@@ -56,7 +56,7 @@ Full keyboards with all the letters or simple keypads with a few navigation butt
To use a keyboard/keypad:
- Register a `read_cb` function with `LV_INDEV_TYPE_KEYPAD` type.
- An object group has to be created: `lv_group_t * g = lv_group_create()` and objects have to be added to it with `lv_group_add_obj(g, obj)`
- An object group has to be created: `lv_group_t * g = lv_group_create()` and objects have to be added to it with `lv_group_add_obj(g, obj)`
- The created group has to be assigned to an input device: `lv_indev_set_group(my_indev, g)` (`my_indev` is the return value of `lv_indev_drv_register`)
- Use `LV_KEY_...` to navigate among the objects in the group. See `lv_core/lv_group.h` for the available keys.
@@ -176,23 +176,23 @@ The default value of the following parameters can changed in `lv_indev_drv_t`:
- `scroll_throw` Scroll throw (momentum) slow-down in [%]. Greater value means faster slow-down.
- `long_press_time` Press time to send `LV_EVENT_LONG_PRESSED` (in milliseconds)
- `long_press_rep_time` Interval of sending `LV_EVENT_LONG_PRESSED_REPEAT` (in milliseconds)
- `read_timer` pointer to the `lv_rimer` which reads the input device. Its parameters can be changed by `lv_timer_...()` functions. `LV_INDEV_DEF_READ_PERIOD` in `lv_conf.h` sets the default read period.
- `read_timer` pointer to the `lv_timer` which reads the input device. Its parameters can be changed by `lv_timer_...()` functions. `LV_INDEV_DEF_READ_PERIOD` in `lv_conf.h` sets the default read period.
### Feedback
Besides `read_cb` a `feedback_cb` callback can be also specified in `lv_indev_drv_t`.
`feedback_cb` is called when any type of event is sent by the input devices. (independently from its type). It allows making feedback for the user e.g. to play a sound on `LV_EVENT_CLICKED`.
`feedback_cb` is called when any type of event is sent by the input devices (independently from its type). This allows generating feedback for the user, e.g. to play a sound on `LV_EVENT_CLICKED`.
### Associating with a display
Every Input device is associated with a display. By default, a new input device is added to the lastly created or the explicitly selected (using `lv_disp_set_default()`) display.
Every input device is associated with a display. By default, a new input device is added to the lastly created or the explicitly selected (using `lv_disp_set_default()`) display.
The associated display is stored and can be changed in `disp` field of the driver.
### Buffered reading
By default LVGL calls `read_cb` periodically. This way there is a chance that some user gestures are missed.
To solve this you can write an event driven driver for your input device that buffers measured data. In `read_cb` you can set the buffered data instead of reading the input device.
You can set the `data->continue_reding` flag to tell that LVGL there is more data to read and it should call the `read_cb` again.
You can set the `data->continue_reading` flag to tell that LVGL there is more data to read and it should call the `read_cb` again.
## Further reading

View File

@@ -11,7 +11,7 @@ To enable logging, set `LV_USE_LOG 1` in `lv_conf.h` and set `LV_LOG_LEVEL` to
- `LV_LOG_LEVEL_TRACE` A lot of logs to give detailed information
- `LV_LOG_LEVEL_INFO` Log important events
- `LV_LOG_LEVEL_WARN` Log if something unwanted happened but didn't cause a problem
- `LV_LOG_LEVEL_ERROR` Only critical issue, when the system may fail
- `LV_LOG_LEVEL_ERROR` Only critical issues, where the system may fail
- `LV_LOG_LEVEL_USER` Only user messages
- `LV_LOG_LEVEL_NONE` Do not log anything

View File

@@ -13,9 +13,9 @@ However, in the following conditions it's valid to call LVGL related functions:
## Tasks and threads
If you need to use real tasks or threads, you need a mutex which should be invoked before the call of `lv_timer_handler` and released after it.
Also, you have to use the same mutex in other tasks and threads around every LVGL (`lv_...`) related function calls and codes.
Also, you have to use the same mutex in other tasks and threads around every LVGL (`lv_...`) related function call and code.
This way you can use LVGL in a real multitasking environment. Just make use of a mutex to avoid the concurrent calling of LVGL functions.
## Interrupts
Try to avoid calling LVGL functions from the interrupts (except `lv_tick_inc()` and `lv_disp_flush_ready()`). But, if you need to do this you have to disable the interrupt which uses LVGL functions while `lv_timer_handler` is running.
Try to avoid calling LVGL functions from interrupt handlers (except `lv_tick_inc()` and `lv_disp_flush_ready()`). But if you need to do this you have to disable the interrupt which uses LVGL functions while `lv_timer_handler` is running.
It's a better approach to set a flag or some value and periodically check it in an `lv_timer`.

View File

@@ -7,22 +7,22 @@
## Get the library
LVGL Graphics Library is available on GitHub: [https://github.com/lvgl/lvgl](https://github.com/lvgl/lvgl).
LVGL is available on GitHub: [https://github.com/lvgl/lvgl](https://github.com/lvgl/lvgl).
You can clone it or download the latest version of the library from GitHub.
The graphics library is the **lvgl** directory which should be copied into your project.
The graphics library itself is the **lvgl** directory which should be copied into your project.
## Configuration file
There is a configuration header file for LVGL called **lv_conf.h**. In this you can set the library's basic behaviour, disable unused modules and features, adjusts the size of memory buffers in compile-time, etc.
There is a configuration header file for LVGL called **lv_conf.h**. In this you can set the library's basic behavior, disable unused modules and features, adjust the size of memory buffers in compile-time, etc.
Copy **lvgl/lv_conf_template.h** next to the *lvgl* directory and rename it to *lv_conf.h*. Open the file and change the `#if 0` at the beginning to `#if 1` to enable its content.
*lv_conf.h* can be copied other places as well but then you should add `LV_CONF_INCLUDE_SIMPLE` define to your compiler options (e.g. `-DLV_CONF_INCLUDE_SIMPLE` for gcc compiler) and set the include path manually.
*lv_conf.h* can be copied to another place as well but then you should add `LV_CONF_INCLUDE_SIMPLE` define to your compiler options (e.g. `-DLV_CONF_INCLUDE_SIMPLE` for gcc compiler) and set the include path manually.
In this case LVGL will attempt to include `lv_conf.h` simply with `#include "lv_conf.h"`.
In the config file comments explain the meaning of the options. Be sure to set at least `LV_COLOR_DEPTH` according to your display's colro depth.
In the config file comments explain the meaning of the options. Be sure to set at least `LV_COLOR_DEPTH` according to your display's color depth.
## Initialization
@@ -31,5 +31,5 @@ To use the graphics library you have to initialize it and the other components t
1. Call `lv_init()`.
2. Initialize your drivers.
3. Register the display and input devices drivers in LVGL. Lear more about [Display](/porting/display) and [Input device](/porting/indev) registration.
4. Call `lv_tick_inc(x)` in every `x` milliseconds in an interrupt to tell the elapsed time. [Learn more](/porting/tick).
5. Call `lv_timer_handler()` periodically in every few milliseconds to handle LVGL related tasks. [Learn more](/porting/task-handler).
4. Call `lv_tick_inc(x)` every `x` milliseconds in an interrupt to tell the elapsed time. [Learn more](/porting/tick).
5. Call `lv_timer_handler()` every few milliseconds to handle LVGL related tasks. [Learn more](/porting/task-handler).

View File

@@ -21,11 +21,11 @@ while(1) {
}
```
You should also add below lines to your input device read function if a wake-up (press, touch or click etc.) happens:
You should also add the below lines to your input device read function to signal a wake-up (press, touch or click etc.) happened:
```c
lv_tick_inc(LV_DISP_DEF_REFR_PERIOD); /*Force task execution on wake-up*/
timer_start(); /*Restart the timer where lv_tick_inc() is called*/
lv_task_handler(); /*Call `lv_task_handler()` manually to process the wake-up event*/
```
In addition to `lv_disp_get_inactive_time()` you can check `lv_anim_count_running()` to see if every animations are finished.
In addition to `lv_disp_get_inactive_time()` you can check `lv_anim_count_running()` to see if all animations have finished.

View File

@@ -4,9 +4,9 @@
```
# Task Handler
To handle the tasks of LVGL you need to call `lv_timer_handler()` periodically in one of the followings:
To handle the tasks of LVGL you need to call `lv_timer_handler()` periodically in one of the following:
- *while(1)* of *main()* function
- timer interrupt periodically (low priority then `lv_tick_inc()`)
- timer interrupt periodically (lower priority than `lv_tick_inc()`)
- an OS task periodically
The timing is not critical but it should be about 5 milliseconds to keep the system responsive.

View File

@@ -4,15 +4,15 @@
```
# Tick interface
The LVGL needs a system tick to know the elapsed time for animation and other tasks.
LVGL needs a system tick to know elapsed time for animations and other tasks.
You need to call the `lv_tick_inc(tick_period)` function periodically and tell the call period in milliseconds. For example, `lv_tick_inc(1)` for calling in every millisecond.
You need to call the `lv_tick_inc(tick_period)` function periodically and provide the call period in milliseconds. For example, `lv_tick_inc(1)` when calling every millisecond.
`lv_tick_inc` should be called in a higher priority routine than `lv_task_handler()` (e.g. in an interrupt) to precisely know the elapsed milliseconds even if the execution of `lv_task_handler` takes longer time.
`lv_tick_inc` should be called in a higher priority routine than `lv_task_handler()` (e.g. in an interrupt) to precisely know the elapsed milliseconds even if the execution of `lv_task_handler` takes more time.
With FreeRTOS `lv_tick_inc` can be called in `vApplicationTickHook`.
On Linux based operating system (e.g. on Raspberry Pi) `lv_tick_inc` can be called in a thread as below:
On Linux based operating system (e.g. on Raspberry Pi) `lv_tick_inc` can be called in a thread like below:
```c
void * tick_thread (void *args)
{

View File

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

View File

@@ -10,12 +10,12 @@ The bar object has a background and an indicator on it. The width of the indicat
Vertical bars can be created if the width of the object is smaller than its height.
Not only the end, but the start value of the bar can be set which changes the start position of the indicator.
Not only the end, but also the start value of the bar can be set, which changes the start position of the indicator.
## Parts and Styles
- `LV_PART_MAIN` The background of the bar and it uses the typical background style properties. Adding padding makes the indicator smaller or larger. The `anim_time` style property sets the animation time if the values set with `LV_ANIM_ON`.
- `LV_PART_INDICATOR` The indicator and it also also uses all the typical background properties.
- `LV_PART_INDICATOR` The indicator itself; also also uses all the typical background properties.
## Usage
@@ -29,12 +29,11 @@ The new value in `lv_bar_set_value` can be set with or without an animation depe
### Modes
The bar can be one the following modes:
- `LV_BAR_MODE_NORMAL` A normal bar as described above
- `LV_BAR_SYMMETRICAL` Draw the indicator form the zero value to current value. Requires negaitve minimum range and positive maximum range.
- `LV_BAR_RANGE` Allows setting the start value too by `lv_bar_set_start_value(bar, new_value, LV_ANIM_ON/OFF)`. The start value has to be always smaller than the end value.
- `LV_BAR_SYMMETRICAL` Draw the indicator from the zero value to current value. Requires a negative minimum range and positive maximum range.
- `LV_BAR_RANGE` Allows setting the start value too by `lv_bar_set_start_value(bar, new_value, LV_ANIM_ON/OFF)`. The start value always has to be smaller than the end value.
## Events
- `LV_EVENT_DRAW_PART_BEGIN` and `LV_EVENT_DRAW_PART_END` are sent for both main and indicator parts to allow hooking the drawing.
The for more detail on the main part see the [Base object](/widgets/obj#events)'s documentation.
- `LV_EVENT_DRAW_PART_BEGIN` and `LV_EVENT_DRAW_PART_END` are sent for both main and indicator parts to allow hooking the drawing. For more detail on the main part see the [Base object](/widgets/obj#events)'s documentation.
For the indicator the following fields are used: `clip_area`, `draw_area`, `rect_dsc`, `part`.
Learn more about [Events](/overview/event).

View File

@@ -6,30 +6,30 @@
## Overview
Buttons has no new features compared to the [Base object](/widgets/obj). It usufule for semantic purposes and has slightly different default settings.
Buttons have no new features compared to the [Base object](/widgets/obj). They are usuful for semantic purposes and have slightly different default settings.
Buttons differ from Base object in the following points by default:
Buttons, by default, differ from Base object in the following ways:
- Not scrollable
- Added to the default group
- Its default height and width is `LV_SIZE_CONTENT`
- Default height and width set to `LV_SIZE_CONTENT`
## Parts and Styles
- `LV_PART_MAIN` The background of the button. It uses the typical background style properties.
- `LV_PART_MAIN` The background of the button. Uses the typical background style properties.
## Usage
There are no new features compared to [Base object](/widgets/obj).
## Events
- `LV_EVENT_VALUE_CHANGED` when the `LV_OBJ_FLAG_CHECKABLE` flag is enabled and the obejct clicked (on transition to/from the checked state)
- `LV_EVENT_VALUE_CHANGED` when the `LV_OBJ_FLAG_CHECKABLE` flag is enabled and the object is clicked. The event happens on transition to/from the checked state.
Learn more about [Events](/overview/event).
## Keys
If `LV_OBJ_FLAG_CHECKABLE` is enabled `LV_KEY_RIGHT` and `LV_KEY_UP` makes the object checked, and `LV_KEY_LEFT` and `LV_KEY_DOWN` makes it unchecked.
If `LV_OBJ_FLAG_CHECKABLE` is enabled `LV_KEY_RIGHT` and `LV_KEY_UP` make the object checked, and `LV_KEY_LEFT` and `LV_KEY_DOWN` make it unchecked.
Note that, the state of `LV_KEY_ENTER` is translated to `LV_EVENT_PRESSED/PRESSING/RELEASED` etc.
Note that the state of `LV_KEY_ENTER` is translated to `LV_EVENT_PRESSED/PRESSING/RELEASED` etc.
Learn more about [Keys](/overview/indev).

View File

@@ -6,16 +6,13 @@
## Overview
The Button Matrix objects can display multiple buttons in rows and columns.
The Button Matrix object is a lightweight way to display multiple buttons in rows and columns. Lightweight because the buttons are not actually created but just virtually drawn on the fly. This way, one button use only eight extra bytes of memory instead of the ~100-150 bytes a normal [Button](/widgets/core/btn) object plus the 100 or so bytes for the the [Label](/widgets/core/label) object.
The Button matrix object is very light weighted because the buttons are not created just virtually drawn on the fly.
This way, 1 button use only 8 extra bytes instead of the ~100-150 byte size of a normal [Button](/widgets/core/btn) object and other ~100 byte for the size of the [Label](/widgets/core/label) object.
The Button matrix is added to the deafult group (if it is set). Besides the Button matrix is an editable object to allow selecting and clicing the buttons with encoder navigation too.
The Button matrix is added to the default group (if one is set). Besides the Button matrix is an editable object to allow selecting and clicking the buttons with encoder navigation too.
## Parts and Styles
- `LV_PART_MAIN` The bacground of the button matrix. It uses the typical background style properties. `pad_row` and `pad_column` sets the space between the buttons.
- `LV_PART_ITEMS` The buttons and they all use the text and typical background style properties expect translations and transformations.
- `LV_PART_MAIN` The background of the button matrix, uses the typical background style properties. `pad_row` and `pad_column` sets the space between the buttons.
- `LV_PART_ITEMS` The buttons all use the text and typical background style properties except translations and transformations.
## Usage
@@ -23,16 +20,16 @@ The Button matrix is added to the deafult group (if it is set). Besides the Butt
There is a text on each button. To specify them a descriptor string array, called *map*, needs to be used.
The map can be set with `lv_btnmatrix_set_map(btnm, my_map)`.
The declaration of a map should look like `const char * map[] = {"btn1", "btn2", "btn3", NULL}`.
Note that, the last element has to be `NULL` or an empty string (`""`)!
Note that the last element has to be either `NULL` or an empty string (`""`)!
Use `"\n"` in the map to make **line break**. E.g. `{"btn1", "btn2", "\n", "btn3", ""}`. Each line's buttons have their width calculated automatically.
Use `"\n"` in the map to insert a **line break**. E.g. `{"btn1", "btn2", "\n", "btn3", ""}`. Each line's buttons have their width calculated automatically.
So in the example the first row will have 2 buttons each with 50% width and a second row with 1 button having 100% width.
### Control buttons
The buttons' width can be set relative to the other button in the same row with `lv_btnmatrix_set_btn_width(btnm, btn_id, width)`
E.g. in a line with two buttons: *btnA, width = 1* and *btnB, width = 2*, *btnA* will have 33 % width and *btnB* will have 66 % width.
It's similar to how the [`flex-grow`](https://developer.mozilla.org/en-US/docs/Web/CSS/flex-grow) property works in CSS.
The width's value mus be in the \[1..7\] range and the deafult width is 1.
The width must be in the \[1..7\] range and the default width is 1.
In addition to the width, each button can be customized with the following parameters:
- `LV_BTNMATRIX_CTRL_HIDDEN` Makes a button hidden (hidden buttons still take up space in the layout, they are just not visible or clickable)
@@ -45,7 +42,7 @@ In addition to the width, each button can be customized with the following param
- `LV_BTNMATRIX_CTRL_CUSTOM_1` Custom free to use flag
- `LV_BTNMATRIX_CTRL_CUSTOM_2` Custom free to use flag
By deafult all flags are disabled.
By default all flags are disabled.
To set or clear a button's control attribute, use `lv_btnmatrix_set_btn_ctrl(btnm, btn_id, LV_BTNM_CTRL_...)` and
`lv_btnmatrix_clear_btn_ctrl(btnm, btn_id, LV_BTNMATRIX_CTRL_...)` respectively. More `LV_BTNM_CTRL_...` values can be OR-ed
@@ -58,15 +55,15 @@ An element of `ctrl_map` should look like `ctrl_map[0] = width | LV_BTNM_CTRL_NO
The number of elements should be equal to the number of buttons (excluding newlines characters).
### One check
The "One check" feature can be enabled with `lv_btnmatrix_set_one_check(btnm, true)` to allow only one button to be checked at once.
The "One check" feature can be enabled with `lv_btnmatrix_set_one_check(btnm, true)` to allow only one button to be checked at a time.
## Events
- `LV_EVENT_VALUE_CHANGED` Sent when a button is pressed/released or repeated after long press. The event paramter is set to the ID of the pressed/released button.
- `LV_EVENT_VALUE_CHANGED` Sent when a button is pressed/released or repeated after long press. The event parameter is set to the ID of the pressed/released button.
- `LV_EVENT_DRAW_PART_BEGIN` and `LV_EVENT_DRAW_PART_END` are sent for both the main and the items (buttons) parts to allow hooking the drawing.
The for more detail on the main part see the [Base object](/widgets/obj#events)'s documentation.
For more detail on the main part see the [Base object](/widgets/obj#events)'s documentation.
For the buttons the following fields are used: `clip_area`, `draw_area`, `rect_dsc`, `rect_dsc`, `part`, `id` (index of the button being drawn).
`lv_btnmatrix_get_selected_btn(btnm)` returns the index of the lastly pressed, released or focused button or `LV_BTNMATRIX_BTN_NONE` if no such button.
`lv_btnmatrix_get_selected_btn(btnm)` returns the index of the most recently released or focused button or `LV_BTNMATRIX_BTN_NONE` if no such button.
`lv_btnmatrix_get_btn_text(btnm, btn_id)` returns a pointer to the text of `btn_id`th button.

View File

@@ -7,9 +7,9 @@
## Overview
A Canvas inherites from [Image](/widgets/core/img) where the user can draw anything.
A Canvas inherits from [Image](/widgets/core/img) where the user can draw anything.
Rectangles, texts, images, lines, arcs can be drawn here using lvgl's drawing engine.
Besides some "effects" can be applied as well like rotation, zoom and blur.
Additionally "effects" can be applied, such as rotation, zoom and blur.
## Parts and Styles
@@ -18,7 +18,7 @@ Besides some "effects" can be applied as well like rotation, zoom and blur.
## Usage
### Buffer
The Canvas needs a buffer which stores the drawn image.
The Canvas needs a buffer in which stores the drawn image.
To assign a buffer to a Canvas, use `lv_canvas_set_buffer(canvas, buffer, width, height, LV_IMG_CF_...)`.
Where `buffer` is a static buffer (not just a local variable) to hold the image of the canvas.
For example,
@@ -37,7 +37,7 @@ To set a pixel on the canvas, use `lv_canvas_set_px(canvas, x, y, LV_COLOR_RED)`
With `LV_IMG_CF_INDEXED_...` or `LV_IMG_CF_ALPHA_...`, the index of the color or the alpha value needs to be passed as color.
E.g. `lv_color_t c; c.full = 3;`
`lv_canvas_fill_bg(canvas, LV_COLOR_BLUE, LV_OPA_50)` fills the whole canvas to blue with 50% opacity. Note that, if the current color format doesn't support colors (e.g. `LV_IMG_CF_ALPHA_2BIT`) the color will be ignored.
`lv_canvas_fill_bg(canvas, LV_COLOR_BLUE, LV_OPA_50)` fills the whole canvas to blue with 50% opacity. Note that if the current color format doesn't support colors (e.g. `LV_IMG_CF_ALPHA_2BIT`) the color will be ignored.
Similarly, if opacity is not supported (e.g. `LV_IMG_CF_TRUE_COLOR`) it will be ignored.
An array of pixels can be copied to the canvas with `lv_canvas_copy_buf(canvas, buffer_to_copy, x, y, width, height)`.
@@ -51,7 +51,7 @@ To draw something to the canvas use
- `lv_canvas_draw_polygon(canvas, points_array, point_cnt, &draw_dsc)`
- `lv_canvas_draw_arc(canvas, x, y, radius, start_angle, end_angle, &draw_dsc)`
`draw_dsc` is a `lv_draw_rect/label/img/line/arc_dsc_t` variable which should be first initialized with `lv_draw_rect/label/img/line/arc_dsc_init()` function and then it's filed should be modified with the desired colors and other values.
`draw_dsc` is a `lv_draw_rect/label/img/line/arc_dsc_t` variable which should be first initialized with one of `lv_draw_rect/label/img/line/arc_dsc_init()` and then modified with the desired colors and other values.
The draw function can draw to any color format. For example, it's possible to draw a text to an `LV_IMG_VF_ALPHA_8BIT` canvas and use the result image as a [draw mask](/overview/drawing) later.
@@ -61,7 +61,7 @@ The function needs the following parameters:
- `canvas` pointer to a canvas object to store the result of the transformation.
- `img pointer` to an image descriptor to transform. Can be the image descriptor of an other canvas too (`lv_canvas_get_img()`).
- `angle` the angle of rotation (0..3600), 0.1 deg resolution
- `zoom` zoom factor (256 no zoom, 512 double size, 128 half size);
- `zoom` zoom factor (256: no zoom, 512: double size, 128: half size);
- `offset_x` offset X to tell where to put the result data on destination canvas
- `offset_y` offset X to tell where to put the result data on destination canvas
- `pivot_x` pivot X of rotation. Relative to the source canvas. Set to `source width / 2` to rotate around the center
@@ -72,10 +72,10 @@ Note that a canvas can't be rotated on itself. You need a source and destinatio
### Blur
A given area of the canvas can be blurred horizontally with `lv_canvas_blur_hor(canvas, &area, r)` or vertically with `lv_canvas_blur_ver(canvas, &area, r)`.
`r` is the radius of the blur (greater value means more intensive burring). `area` is the area where the blur should be applied (interpreted relative to the canvas)
`r` is the radius of the blur (greater value means more intensive burring). `area` is the area where the blur should be applied (interpreted relative to the canvas).
## Events
The same events are sent than for the [Images](/widgets/core/img).
The same events are sent as for the [Images](/widgets/core/img).
Learn more about [Events](/overview/event).

View File

@@ -7,29 +7,27 @@
## Overview
The Checkbox object is created from a "tick box" and a label.
When the Chackbox is clicked the tick box is toggled.
The Checkbox object is created from a "tick box" and a label. When the Chackbox is clicked the tick box is toggled.
## Parts and Styles
- `LV_PART_MAIN` The is the background of the Checkbox and it uses the text and all the typical backround style properties.
`pad_column` adjusts the spacing between the tickbox and the label
- `LV_PART_INDICATOR` The "tick box" is a square the uses all the typical backround style properties.
By deafult its size is equal to the height of the main part's font. Padding properties makes the tick boy larger in the respectiev directions.
- `LV_PART_INDICATOR` The "tick box" is a square that uses all the typical backround style properties.
By default its size is equal to the height of the main part's font. Padding properties make the tick box larger in the respective directions.
The Checkbox is added to the deafult group (if it is set).
The Checkbox is added to the default group (if it is set).
## Usage
### Text
The text can be modified by the `lv_checkbox_set_text(cb, "New text")` function.
It will dynamically allocate the text.
The text can be modified with the `lv_checkbox_set_text(cb, "New text")` function and will be dynamically allocated.
To set a static text,
use `lv_checkbox_set_static_text(cb, txt)`. This way, only a pointer of `txt` will be stored and it shouldn't be deallocated while the checkbox exists.
use `lv_checkbox_set_static_text(cb, txt)`. This way, only a pointer to `txt` will be stored. The text then shouldn't be deallocated while the checkbox exists.
### Check, uncheck, disable
You can manually check, un-check, and disable the Checkbox by using the common state state add/clear function:
You can manually check, un-check, and disable the Checkbox by using the common state add/clear function:
```c
lv_obj_add_state(cb, LV_STATE_CHECKED); /*Make the chekbox checked*/
lv_obj_clear_state(cb, LV_STATE_CHECKED); /*MAke the checkbox unchecked*/
@@ -39,7 +37,7 @@ lv_obj_add_state(cb, LV_STATE_CHECKED | LV_STATE_DISABLED); /*Make the checkbox
## Events
- `LV_EVENT_VALUE_CHANGED` Sent when the checkbox is toggled.
- `LV_EVENT_DRAW_PART_BEGIN` and `LV_EVENT_DRAW_PART_END` are sent for both main and indicator parts to allow hooking the drawing.
The for more detail on the main part see the [Base object](/widgets/obj#events)'s documentation.
For more detail on the main part see the [Base object](/widgets/obj#events)'s documentation.
For the indicator the following fields are used: `clip_area`, `draw_area`, `rect_dsc`, `part`.
Learn more about [Events](/overview/event).

View File

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

View File

@@ -7,20 +7,20 @@
## Overview
Images are the basic object to display images from the flash (as arrays) or externally as files. Images can display symbols (`LV_SYMBOL_...`) too.
Images are the basic object to display images from flash (as arrays) or from files. Images can display symbols (`LV_SYMBOL_...`) too.
Using the [Image decoder interface](/overview/image.html#image-decoder) custom image formats can be supported as well.
## Parts and Styles
- `LV_PART_MAIN` A background rectangle that uses the typical background style proeprties and the image itself using teh image style proeprties.
- `LV_PART_MAIN` A background rectangle that uses the typical background style properties and the image itself using the image style properties.
## Usage
### Image source
To provide maximum flexibility, the source of the image can be:
- a variable in the code (a C array with the pixels).
- a file stored externally (like on an SD card).
- a variable in code (a C array with the pixels).
- a file stored externally (e.g. on an SD card).
- a text with [Symbols](/overview/font).
To set the source of an image, use `lv_img_set_src(img, src)`.
@@ -32,8 +32,7 @@ To use external files, you also need to convert the image files using the online
You also need to use LVGL's file system module and register a driver with some functions for the basic file operation. Go to the [File system](/overview/file-system) to learn more.
To set an image sourced from a file, use `lv_img_set_src(img, "S:folder1/my_img.bin")`.
You can set a symbol similarly to [Labels](/widgets/core/label). In this case, the image will be rendered as text according to the *font* specified in the style. It enables to use of light-weighted mono-color
"letters" instead of real images. You can set symbol like `lv_img_set_src(img1, LV_SYMBOL_OK)`.
You can also set a symbol similarly to [Labels](/widgets/core/label). In this case, the image will be rendered as text according to the *font* specified in the style. It enables to use of light-weight monochrome "letters" instead of real images. You can set symbol like `lv_img_set_src(img1, LV_SYMBOL_OK)`.
### Label as an image
Images and labels are sometimes used to convey the same thing. For example, to describe what a button does.
@@ -43,35 +42,35 @@ Therefore, images and labels are somewhat interchangeable, that is the images ca
### Transparency
The internal (variable) and external images support 2 transparency handling methods:
- **Chrome keying** - Pixels with `LV_COLOR_CHROMA_KEY` (*lv_conf.h*) color will be transparent.
- **Chroma-keying** - Pixels with `LV_COLOR_CHROMA_KEY` (*lv_conf.h*) color will be transparent.
- **Alpha byte** - An alpha byte is added to every pixel that contains the pixel's opacity
### Palette and Alpha index
Besides *True color* (RGB) color format, the following formats are also supported:
Besides the *True color* (RGB) color format, the following formats are supported:
- **Indexed** - Image has a palette.
- **Alpha indexed** - Only alpha values are stored.
These options can be selected in the image converter. To learn more about the color formats, read the [Images](/overview/image) section.
### Recolor
A color can be mixed to every pixel of an image with a given intensity.
It is very useful to show different states (checked, inactive, pressed, etc.) of an image without storing more versions of the same image.
A color can be mixed with every pixel of an image with a given intensity.
This can be useful to show different states (checked, inactive, pressed, etc.) of an image without storing more versions of the same image.
This feature can be enabled in the style by setting `img_recolor_opa` between `LV_OPA_TRANSP` (no recolor, value: 0) and `LV_OPA_COVER` (full recolor, value: 255).
The default value is `LV_OPA_TRANSP` so this feature is disabled.
The color to mix is set by `img_recolor`.
### Auto-size
Is the width or height of the image object is set to `LV_SIZE_CONTENT` the obejct's size will be set according to the size of image source in the respective direction.
If the width or height of the image object is set to `LV_SIZE_CONTENT` the object's size will be set according to the size of the image source in the respective direction.
### Mosaic
If the object's size is greater than the image size in any directions, then the image will be repeated like a mosaic.
It's a very useful feature to create a large image from only a very narrow source.
This allows creation a large image from only a very narrow source.
For example, you can have a *300 x 5* image with a special gradient and set it as a wallpaper using the mosaic feature.
### Offset
With `lv_img_set_offset_x(img, x_ofs)` and `lv_img_set_offset_y(img, y_ofs)`, you can add some offset to the displayed image.
It is useful if the object size is smaller than the image source size.
Useful if the object size is smaller than the image source size.
Using the offset parameter a [Texture atlas](https://en.wikipedia.org/wiki/Texture_atlas) or a "running image" effect can be created by [Animating](/overview/animation) the x or y offset.
## Transformations
@@ -82,19 +81,19 @@ Fractional scale works as well. E.g. `281` for 10% enlargement.
To rotate the image use `lv_img_set_angle(img, angle)`. Angle has 0.1 degree precision, so for 45.8° set 458.
The `transform_zoom` and `transform_angle` style proeprties are also used to determin the final zoom and angle.
The `transform_zoom` and `transform_angle` style properties are also used to determine the final zoom and angle.
By default, the pivot point of the rotation is the center of the image. It can be changed with `lv_img_set_pivot(img, pivot_x, pivot_y)`. `0;0` is the top left corner.
The quality of the transformation can be adjusted with `lv_img_set_antialias(img, true/false)`. With enabled anti-aliasing the transformations has a higher quality but they are slower.
The quality of the transformation can be adjusted with `lv_img_set_antialias(img, true/false)`. With enabled anti-aliasing the transformations are higher quality but slower.
The transformations require the whole image to be available. Therefore indexed images (`LV_IMG_CF_INDEXED_...`), alpha only images (`LV_IMG_CF_ALPHA_...`) or images from files can not be transformed.
In other words transformations work only on true color images stored as C array, or if a custom [Image decoder](/overview/images#image-edecoder) returns the whole image.
Note that, the real coordinates of image object won't change during transformation. That is `lv_obj_get_width/height/x/y()` will returned the original, non-zoomed coordinates.
Note that the real coordinates of image objects won't change during transformation. That is `lv_obj_get_width/height/x/y()` will return the original, non-zoomed coordinates.
## Events
No special events are sendt by the imge objects.
No special events are sent by image objects.
Learn more about [Events](/overview/event).

View File

@@ -16,7 +16,7 @@ A label is the basic object type that is used to display text.
### Set text
You can set the text on a label at runtime with `lv_label_set_text(label, "New text")`.
It will allocate a buffer dynamically, and the provided string will be copied into that buffer.
This will allocate a buffer dynamically, and the provided string will be copied into that buffer.
Therefore, you don't need to keep the text you pass to `lv_label_set_text` in scope after that function returns.
With `lv_label_set_text_fmt(label, "Value: %d", 15)` printf formatting can be used to set the text.
@@ -26,15 +26,15 @@ In this case, the text is not stored in the dynamic memory and the given buffer
This means that the array can't be a local variable which goes out of scope when the function exits.
Constant strings are safe to use with `lv_label_set_text_static` (except when used with `LV_LABEL_LONG_DOT`, as it modifies the buffer in-place), as they are stored in ROM memory, which is always accessible.
### New line
### Newline
New line characters are handled automatically by the label object. You can use `\n` to make a line break. For example: `"line1\nline2\n\nline4"`
Newline characters are handled automatically by the label object. You can use `\n` to make a line break. For example: `"line1\nline2\n\nline4"`
### Long modes
By default, the width and height of the label is set to `LV_SIZE_CONTENT`therefore the size of the label is automatically expands to the text size.
Otherwise, if the width or height is explicitly set (useing e.g.`lv_obj_set_width` or a layout), the lines wider than the label's width can be manipulated according to several long mode policies.
By default, the width and height of the label is set to `LV_SIZE_CONTENT`. Therefore the size of the label is automatically expanded to the text size.
Otherwise, if the width or height are explicitly set (useing e.g.`lv_obj_set_width` or a layout), the lines wider than the label's width can be manipulated according to several long mode policies.
Similary, the policies can be applied if the height of the text is greater than the height of the label.
- `LV_LABEL_LONG_WRAP` Wrap too long lines. If the height is `LV_SIZE_CONTENT` the label's height will be expanded, elst the text will be clipped. (Default)
- `LV_LABEL_LONG_WRAP` Wrap too long lines. If the height is `LV_SIZE_CONTENT` the label's height will be expanded, otherwise the text will be clipped. (Default)
- `LV_LABEL_LONG_DOT` Replaces the last 3 characters from bottom right corner of the label with dots (`.`)
- `LV_LABEL_LONG_SCROLL` If the text is wider than the label scroll it horizontally back and forth. If it's higher, scroll vertically. Only one direction is scrolled and horizontal scrolling has higher precedence.
- `LV_LABEL_LONG_SCROLL_CIRCULAR` If the text is wider than the label scroll it horizontally continously. If it's higher, scroll vertically. Only one direction is scrolled and horizontal scrolling has higher precedence.
@@ -52,17 +52,17 @@ This feature can be enabled individually for each label by `lv_label_set_recolor
### Text selection
If enabled by `LV_LABEL_TEXT_SELECTION` part of the text can be selected. It's similar when on PC a you use your mouse to select a text.
The whole mechanzim (click and select the text as you drag your finger/mouse) is implemeted in [Text area](/widgets/core/textarea) and the Label widget allows only to manually make parts of the text selected with
The whole mechanism (click and select the text as you drag your finger/mouse) is implemented in [Text area](/widgets/core/textarea) and the Label widget only allows manual text selection with
`lv_label_get_text_selection_start(label, start_char_index)` and `lv_label_get_text_selection_start(label, end_char_index)`.
### Very long texts
LVGL can efficiently handle very long (e.g. > 40k characters) by saving some extra data (~12 bytes) to speed up drawing. To enable this feature, set `LV_LABEL_LONG_TXT_HINT 1` in `lv_conf.h`.
LVGL can efficiently handle very long (e.g. > 40k characters) labels by saving some extra data (~12 bytes) to speed up drawing. To enable this feature, set `LV_LABEL_LONG_TXT_HINT 1` in `lv_conf.h`.
### Symbols
The labels can display symbols alongside letters (or on their own). Read the [Font](/overview/font) section to learn more about the symbols.
## Events
No special event's are send by the Label.
No special events are sent by the Label.
Learn more about [Events](/overview/event).

View File

@@ -8,22 +8,19 @@
The Line object is capable of drawing straight lines between a set of points.
## Parts and Styles
- `LV_PART_MAIN` It uses all the typical backgrund properties and the line style properties.
- `LV_PART_MAIN` uses all the typical background properties and line style properties.
## Usage
### Set points
The points has to be stored in an `lv_point_t` array and passed to the object by the `lv_line_set_points(lines, point_array, point_cnt)` function.
The points have to be stored in an `lv_point_t` array and passed to the object by the `lv_line_set_points(lines, point_array, point_cnt)` function.
### Auto-size
By default the Line's width and height is set to `LV_SIZE_CONTENT` to automatically set its size to involve all the points.
If the size if set explicitly the point out of the object
It can be enable with the `lv_line_set_auto_size(line, true)` function.
If enabled then when the points are set the object's width and height will be changed according to the maximal x and y coordinates among the points. The *auto size* is enabled by default.
By default the Line's width and height are set to `LV_SIZE_CONTENT`. This means it will automatically set its size to fit all the points. If the size is set explicitly, parts on the line may not be visible.
### Invert y
By deafult, the *y == 0* point is in the top of the object. It might be conter-intuitive in some cases so the y coordinates can be inverted with `lv_line_set_y_invert(line, true)`. In this case, *y == 0* will be the bottom of teh obejct.
The *y invert* is disabled by default.
By default, the *y == 0* point is in the top of the object. It might be conter-intuitive in some cases so the y coordinates can be inverted with `lv_line_set_y_invert(line, true)`. In this case, *y == 0* will be the bottom of the object.
*y invert* is disabled by default.
## Events
Only the [Generic events](../overview/event.html#generic-events) are sent by the object type.

View File

@@ -6,26 +6,26 @@
## Overview
Roller allows you to simply select one option from more with scrolling.
Roller allows you to simply select one option from a list by scrolling.
## Parts and Styles
- `LV_PART_MAIN` The background of the roller that uses all the typical background properties and the text style properties. `style_text_line_space` adjusts the space between the options.
When the Roller is scrolled and doesn't stop exactly on an option it will scroll to the nearest valid option automatically in `anim_time` milliseconds as it's specified in the style.
- `LV_PART_MAIN` The background of the roller uses all the typical background properties and text style properties. `style_text_line_space` adjusts the space between the options.
When the Roller is scrolled and doesn't stop exactly on an option it will scroll to the nearest valid option automatically in `anim_time` milliseconds as specified in the style.
- `LV_PART_SELECTED` The selected option in the middle. Besides the typical background properties it uses the text style properties to change the appearance of the text in the selected area.
## Usage
### Set options
The options are passed to the Roller as a string with `lv_roller_set_options(roller, options, LV_ROLLER_MODE_NORMAL/INFINITE)`. The options should be separated by `\n`. For example: `"First\nSecond\nThird"`.
Options are passed to the Roller as a string with `lv_roller_set_options(roller, options, LV_ROLLER_MODE_NORMAL/INFINITE)`. The options should be separated by `\n`. For example: `"First\nSecond\nThird"`.
`LV_ROLLER_MODE_INFINITE` make the roller circular.
`LV_ROLLER_MODE_INFINITE` makes the roller circular.
You can select an option manually with `lv_roller_set_selected(roller, id, LV_ANIM_ON/OFF)`, where *id* is the index of an option.
### Get selected option
The get the currently selected option use `lv_roller_get_selected(roller)` it will return the *index* of the selected option.
The get the *index* of the currently selected option use `lv_roller_get_selected(roller)`.
`lv_roller_get_selected_str(roller, buf, buf_size)` copy the name of the selected option to `buf`.
`lv_roller_get_selected_str(roller, buf, buf_size)` will copy the name of the selected option to `buf`.
### Visible rows
The number of visible rows can be adjusted with `lv_roller_set_visible_row_count(roller, num)`.

View File

@@ -6,20 +6,20 @@
## Overview
The Slider object looks like a [Bar](/widgets/core/bar) supplemented with a knob. The knob can be dragged to set a value. The Slider also can be vertical or horizontal.
The Slider object looks like a [Bar](/widgets/core/bar) supplemented with a knob. The knob can be dragged to set a value. Just like Bar, Slider can be vertical or horizontal.
## Parts and Styles
- `LV_PART_MAIN` The background of the slider and it uses all the typical background style properties. `padding` makes the indicator smaller in the respective direction.
- `LV_PART_INDICATOR` The indicator the show the current state of the slider. Also uses all the typical background style properties.
- `LV_PART_KNOB` A rectangle (or circle) drawn at the current value. It also uses all the typical background properties to describe the knob(s). By default the knob is square (with a optional radius) with side length equal to the smaller side of the slider. The knob can be made larger with the `padding` values. Padding values can be asymmetric too.
- `LV_PART_MAIN` The background of the slider. Uses all the typical background style properties. `padding` makes the indicator smaller in the respective direction.
- `LV_PART_INDICATOR` The indicator that shows the current state of the slider. Also uses all the typical background style properties.
- `LV_PART_KNOB` A rectangle (or circle) drawn at the current value. Also uses all the typical background properties to describe the knob(s). By default the knob is square (with a optional corner radius) with side length equal to the smaller side of the slider. The knob can be made larger with the `padding` values. Padding values can be asymmetric too.
## Usage
### Value and range
To set an initial value use `lv_slider_set_value(slider, new_value, LV_ANIM_ON/OFF)`. The animation time is set by the styles' `anim_time` property.
To specify the range (min, max values) the `lv_slider_set_range(slider, min , max)` can be used.
To specify the range (min, max values), `lv_slider_set_range(slider, min , max)` can be used.
### Modes
The slider can be one the following modes:
@@ -30,14 +30,12 @@ The slider can be one the following modes:
The mode can be changed with `lv_slider_set_mode(slider, LV_SLIDER_MODE_...)`
### Knob-only mode
Normally, the slider can be adjusted either by dragging the knob, or clicking on the slider bar.
In the latter case the knob moves to the point clicked and slider value changes accordingly. In some cases it is desirable to set the slider to react on dragging the knob only.
This feature is enabled by adding the `LV_OBJ_FLAG_ADV_HITTEST`: `lv_obj_add_flag(slider, LV_OBJ_FLAG_ADV_HITTEST)`.
Normally, the slider can be adjusted either by dragging the knob, or by clicking on the slider bar.
In the latter case the knob moves to the point clicked and slider value changes accordingly. In some cases it is desirable to set the slider to react on dragging the knob only. This feature is enabled by adding the `LV_OBJ_FLAG_ADV_HITTEST`: `lv_obj_add_flag(slider, LV_OBJ_FLAG_ADV_HITTEST)`.
## Events
- `LV_EVENT_VALUE_CHANGED` Sent while the slider is being dragged or changed with keys.
The event is sent continuously while the slider is dragged and only when it is released. Use `lv_slider_is_dragged` to decide whether is slider is being dragged or just released.
The event is sent continuously while the slider is dragged and once when released. Use `lv_slider_is_dragged` to detemine whether the Slider is still being dragged or has just been released.
Learn more about [Events](/overview/event).
## Keys

View File

@@ -7,18 +7,18 @@
## Overview
The Switch can be used to turn on/off something. It looks like a little slider.
The Switch looks like a little slider and can be used to turn something on and off.
## Parts and Styles
- `LV_PART_MAIN` The background of the switch and it uses all the typical background style properties. `padding` makes the indicator smaller in the respective direction.
- `LV_PART_INDICATOR` The indicator the show the current state of the switch. Also uses all the typical background style properties.
- `LV_PART_KNOB` A rectangle (or circle) drawn at left or right side of teh indicator. It also uses all the typical background properties to describe the knob(s). By default the knob is square (with a optional radius) with side length equal to the smaller side of the slider. The knob can be made larger with the `padding` values. Padding values can be asymmetric too.
- `LV_PART_MAIN` The background of the switch uses all the typical background style properties. `padding` makes the indicator smaller in the respective direction.
- `LV_PART_INDICATOR` The indicator that shows the current state of the switch. Also uses all the typical background style properties.
- `LV_PART_KNOB` A rectangle (or circle) drawn at left or right side of the indicator. Also uses all the typical background properties to describe the knob(s). By default the knob is square (with a optional corner radius) with side length equal to the smaller side of the slider. The knob can be made larger with the `padding` values. Padding values can be asymmetric too.
## Usage
### Change state
When the switch is turned on it goes to `LV_STATE_CHACKED`. To get the current satte of the switch use `lv_obj_has_state(switch, LV_STATE_CHECHKED)`.
When the switch is turned on it goes to `LV_STATE_CHECKED`. To get the current satte of the switch use `lv_obj_has_state(switch, LV_STATE_CHECKED)`.
To manually turn the switch on/off call `lvobj_add/clear_state(switch, LV_STATE_CHECKED)`.

View File

@@ -8,25 +8,25 @@
Tables, as usual, are built from rows, columns, and cells containing texts.
The Table object is very light weighted because only the texts are stored. No real objects are created for cells but they are just drawn on the fly.
The Table object is very lightweight because only the texts are stored. No real objects are created for cells but they are just drawn on the fly.
## Parts and Styles
- `LV_PART_MAIN` The background of the table and uses all the typical background style properties.
- `LV_PART_ITEMS` The cells of the table and they also use all the typical background style properties and the text properties.
- `LV_PART_MAIN` The background of the table uses all the typical background style properties.
- `LV_PART_ITEMS` The cells of the table also use all the typical background style properties and the text properties.
## Usage
### Set cell value
The cells can store only texts so numbers needs to be converted to text before displaying them in a table.
The cells can store only text so numbers need to be converted to text before displaying them in a table.
`lv_table_set_cell_value(table, row, col, "Content")`. The text is saved by the table so it can be even a local variable.
Line break can be used in the text like `"Value\n60.3"`.
Line breaks can be used in the text like `"Value\n60.3"`.
The new rows and column are automatically added is required
New rows and columns are automatically added is required
### Rows and Columns
@@ -40,18 +40,18 @@ The height is calculated automatically from the cell styles (font, padding etc)
### Merge cells
Cells can be merged horizontally with `lv_table_set_cell_merge_right(table, col, row, true)`. To merge more adjacent cells apply this function for each cell.
Cells can be merged horizontally with `lv_table_set_cell_merge_right(table, col, row, true)`. To merge more adjacent cells call this function for each cell.
### Scroll
If the label's width or height is set to `LV_SIZE_CONTENT` that size will be se to show the whole table in the respective direction.
If the label's width or height is set to `LV_SIZE_CONTENT` that size will be used to show the whole table in the respective direction.
E.g. `lv_obj_set_size(table, LV_SIZE_CONTENT, LV_SIZE_CONTENT)` automatically sets the table size to show all the columns and rows.
If the width or height is set to smaller number than the "intrinsic" size then the table becomes scrollable.
If the width or height is set to a smaller number than the "intrinsic" size then the table becomes scrollable.
## Events
- `LV_EVENT_DRAW_PART_BEGIN` and `LV_EVENT_DRAW_PART_END` are sent for both main and items parts to allow hooking the drawing.
The for more detail on the main part see the [Base object](/widgets/obj#events)'s documentation.
For the items (sells) the following fields are used: `clip_area`, `draw_area`, `part`, `rect_dsc`, `label_dsc` `id` (current row &times; col count + current column).
For more detail on the main part see the [Base object](/widgets/obj#events)'s documentation.
For the items (cells) the following fields are used: `clip_area`, `draw_area`, `part`, `rect_dsc`, `label_dsc` `id` (current row &times; col count + current column).
Learn more about [Events](/overview/event).

View File

@@ -13,13 +13,13 @@ Long lines are wrapped and when the text becomes long enough the Text area can b
One line mode and password modes are supported.
## Parts and Styles
- `LV_PART_MAIN` The background of the text area and it uses all the typical backgrond style properties and the text related style properties including `text_align` to align the text to the left, right or center.
- `LV_PART_MAIN` The background of the text area. Uses all the typical backgrond style properties and the text related style properties including `text_align` to align the text to the left, right or center.
- `LV_PART_SCROLLBAR` The scrollbar that is shown when the text is too long.
- `LV_PART_SELECTED` Tells the style of the [selected text](#text-selection). Only `text_color` and `bg_color` style properties can be used.
- `LV_PART_SELECTED` Detemines the style of the [selected text](#text-selection). Only `text_color` and `bg_color` style properties can be used.
- `LV_PART_CURSOR` Marks the position where the characters are inserted. The cursor's area is always the bounding box of the current character.
A block cursor can be created by adding a background color and background opacity to `LV_PART_CURSOR`'s style. The create line cursor let the cursor transparent and set a left border.
The `anim_time` style property sets the cursors blink time.
- `LV_PART_TEXTAREA_PLACEHOLDER` It's a part related only to the text area and allows styling the placeholder text.
A block cursor can be created by adding a background color and background opacity to `LV_PART_CURSOR`'s style. The create line cursor leave the cursor transparent and set a left border.
The `anim_time` style property sets the cursor's blink time.
- `LV_PART_TEXTAREA_PLACEHOLDER` Unique to Text Area, allows styling the placeholder text.
## Usage
@@ -58,11 +58,11 @@ You can step the cursor with
If `lv_textarea_set_cursor_click_pos(textarea, true)` is applied the cursor will jump to the position where the Text area was clicked.
### Hide the cursor
The cursor is always visible, hiwever it can be good idea to style to be visible only in `LV_STATE_FOCUSED` state.
The cursor is always visible, however it can be a good idea to style it to be visible only in `LV_STATE_FOCUSED` state.
### One line mode
The Text area can be configures to be one lined with `lv_textarea_set_one_line(textarea, true)`.
In this mode the height is set automatically to show only one line, line break character are ignored, and word wrap is disabled.
The Text area can be configured to be on a single line with `lv_textarea_set_one_line(textarea, true)`.
In this mode the height is set automatically to show only one line, line break characters are ignored, and word wrap is disabled.
### Password mode
The text area supports password mode which can be enabled with `lv_textarea_set_password_mode(textarea, true)`.
@@ -70,7 +70,7 @@ The text area supports password mode which can be enabled with `lv_textarea_set_
If the `•` ([Bullet, U+2022](http://www.fileformat.info/info/unicode/char/2022/index.htm)) character exists in the font, the entered characters are converted to it after some time or when a new character is entered.
If `•` not exists, `*` will be used.
In password mode `lv_textarea_get_text(textarea)` gives the real text, not the bullet characters.
In password mode `lv_textarea_get_text(textarea)` returns the actual text entered, not the bullet characters.
The visibility time can be adjusted with `LV_TEXTAREA_DEF_PWD_SHOW_TIME)` in `lv_conf.h`.
@@ -82,19 +82,19 @@ Other characters will be ignored.
The maximum number of characters can be limited with `lv_textarea_set_max_length(textarea, max_char_num)`
### Very long texts
If there is a very long text in the Text area (e. g. > 20k characters) its scrolling and drawing might be slow.
If there is a very long text in the Text area (e. g. > 20k characters), scrolling and drawing might be slow.
However, by enabling `LV_LABEL_LONG_TXT_HINT 1` in `lv_conf.h` the performance can be hugely improved.
It will save some information about the label to speed up its drawing.
This will save some additional information about the label to speed up its drawing.
Using `LV_LABEL_LONG_TXT_HINT` the scrolling and drawing will as fast as with "normal" short texts.
### Select text
A part of text can be selected if enabled with `lv_textarea_set_text_selection(textarea, true)`.
It works like when you select a text on your PC with your mouse.
Any part of the text can be selected if enabled with `lv_textarea_set_text_selection(textarea, true)`.
This works much like when you select text on your PC with your mouse.
## Events
- `LV_EVENT_INSERT` Sent when before a character or text is inserted.
The event paramter is the text planned to be inserted. `lv_textarea_set_insert_replace(textarea, "New text")` replaces the text to insert.
The new text can not be in a local variable which is destroyed when the event callback exists. `""` means do not insert anything.
- `LV_EVENT_INSERT` Sent right before a character or text is inserted.
The event paramter is the text about to be inserted. `lv_textarea_set_insert_replace(textarea, "New text")` replaces the text to insert.
The new text cannot be in a local variable which is destroyed when the event callback exists. `""` means do not insert anything.
- `LV_EVENT_VALUE_CHANGED` Sent when the content of the text area has been changed.
- `LV_EVENT_APPLY` Sent when `LV_KEY_ENTER` is pressed (or(sent) to a one line text area.

View File

@@ -7,27 +7,27 @@
## Overview
The Calendar object is a classic calendar which can:
- can show the days of any month in a 7x7 matrix
- show the days of any month in a 7x7 matrix
- Show the name of the days
- highlight the current day (today)
- highlight any user-defined dates
The Calendar is added to the default group (if it is set). Besides the Calendar is an editable object to allow selecting and clicking the dates with encoder navigation too.
The Calendar is added to the default group (if it is set). Calendar is an editable object which allow selecting and clicking the dates with encoder navigation too.
To make the Calendar flexible, by default it doesn't show the current year or month. Instead, there area external "headers" that can be attached to the calendar.
To make the Calendar flexible, by default it doesn't show the current year or month. Instead, there are external "headers" that can be attached to the calendar.
## Parts and Styles
The calendar object uses the [Button matrix](/widgets/core/btnmatrix) object under the hood to arrange the days into a matrix.
- `LV_PART_MAIN` The background of the calendar. It uses all the background related style properties.
- `LV_PART_ITEMS` Refers to the dates and day names. Button matrix control flags are set the to differentiate the buttons and a custom drawer event is added modify the properties of the buttons
- `LV_PART_MAIN` The background of the calendar. Uses all the background related style properties.
- `LV_PART_ITEMS` Refers to the dates and day names. Button matrix control flags are set to differentiate the buttons and a custom drawer event is added modify the properties of the buttons as follows:
- day names have no border, no background and drawn with a gray color
- days of the previous and next month have `LV_BTNMATRIX_CTRL_DISABLED` flag
- today has a ticker border with the themes primary color
- highlighted day have some opacity with the themes primary color.
- today has a thicker border with the theme's primary color
- highlighted days have some opacity with the theme's primary color.
## Usage
Some functions uses the `lv_calendar_date_t` type which is a structure with `year`, `month` and `day` fields.
Some functions use the `lv_calendar_date_t` type which is a structure with `year`, `month` and `day` fields.
### Current date
To set the current date (today), use the `lv_calendar_set_today_date(calendar, year, month, day)` function. `month` needs to be in 1..12 range and `day` in 1..31 range.
@@ -37,17 +37,17 @@ To set the shown date, use `lv_calendar_set_shown_date(calendar, year, month)`;
### Highlighted days
The list of highlighted dates should be stored in a `lv_calendar_date_t` array loaded by `lv_calendar_set_highlighted_dates(calendar, highlighted_dates, date_num)`.
Only the arrays pointer will be saved so the array should be a static or global variable.
The list of highlighted dates should be stored in a `lv_calendar_date_t` array loaded by `lv_calendar_set_highlighted_dates(calendar, highlighted_dates, date_num)`.
Only the array's pointer will be saved so the array should be a static or global variable.
### Name of the days
The name of the days can be adjusted with `lv_calendar_set_day_names(calendar, day_names)` where `day_names` looks like `const char * day_names[7] = {"Su", "Mo", ...};`
Only the pointer of the day names is saved so the elements should be static, global or constant variables.
Only the pointer of the day names is saved so the elements should be static, global or constant variables.
## Events
- `LV_EVENT_VALUE_CHANGED` Sent is a data is clicked. `lv_calendar_get_pressed_date(calendar, &date)` tells which day is currently being pressed. Returns `LV_RES_OK` if theres is valid pressed data, else `LV_RES_INV`.
- `LV_EVENT_VALUE_CHANGED` Sent if a date is clicked. `lv_calendar_get_pressed_date(calendar, &date)` set `date` to the date currently being pressed. Returns `LV_RES_OK` if there is a valid pressed date, else `LV_RES_INV`.
Learn more about [vent](/overview/event).
Learn more about [Events](/overview/event).
## Keys
- `LV_KEY_RIGHT/UP/LEFT/RIGHT` To navigate among the buttons to dates
@@ -63,7 +63,7 @@ Learn more about [Keys](/overview/indev).
### Drop-down
`lv_calendar_header_dropdown_create(parent, calendar)` creates a header that contains 2 drop-drown lists: one for the year and an other for the month.
`lv_calendar_header_dropdown_create(parent, calendar)` creates a header that contains 2 drop-drown lists: one for the year and another for the month.

View File

@@ -6,10 +6,9 @@
## Overview
Charts are a basic object to visualize data points.
They support *Line* charts (connect points with lines and/or draw points on them) and *Bar* charts.
Charts are a basic object to visualize data points. Currently *Line* charts (connect points with lines and/or draw points on them) and *Bar* charts are supported.
Charts also support:
Charts can have:
- division lines
- 2 y axis
- axis ticks and texts on ticks
@@ -17,13 +16,13 @@ Charts also support:
- scrolling and zooming
## Parts and Styles
- `LV_PART_MAIN` The background of the chart. It uses all the typical background related style properties and *line* properties for the division lines. *Padding* makes the series area smaller.
- `LV_PART_MAIN` The background of the chart. Uses all the typical background and *line* (for the division lines) related style properties. *Padding* makes the series area smaller.
- `LV_PART_SCROLLBAR` The scrollbar used if the chart is zoomed. See the [Base object](/widgets/obj)'s documentation for details.
- `LV_PART_ITEMS` Refers to the line or bar series.
- Line chart: The *line* properties are used by the lines. `width`, `height`, `bg_color` and `radius` is used to set the appearance of points.
- Bar chart: The typical background properties are used to style the bars.
- `LV_PART_INDICATOR` Refers to the points on line and scatter chart (small circles or squares).
- `LV_PART_CURSOR` *Line* properties are used to style the cursors. `width`, `height`, `bg_color` and `radius` is used to set the appearance of points.
- `LV_PART_CURSOR` *Line* properties are used to style the cursors. `width`, `height`, `bg_color` and `radius` are used to set the appearance of points.
- `LV_PART_TICKS` *Line* and *Text* style properties are used to style the ticks
## Usage
@@ -31,7 +30,7 @@ Charts also support:
### Chart type
The following data display types exist:
- `LV_CHART_TYPE_NONE` Do not display any data. It can be used to hide the series.
- `LV_CHART_TYPE_NONE` Do not display any data. Can be used to hide the series.
- `LV_CHART_TYPE_LINE` Draw lines between the data points and/or points (rectangles or circles) on the data points.
- `LV_CHART_TYPE_BAR` - Draw bars.
- `LV_CHART_TYPE_SCATTER` - X/Y chart drawing point's and lines between the points. .
@@ -40,9 +39,8 @@ You can specify the display type with `lv_chart_set_type(chart, LV_CHART_TYPE_..
### Data series
You can add any number of series to the charts by `lv_chart_add_series(chart, color, axis)`.
It allocates data for a `lv_chart_series_t` structure which contains the chosen `color` and an array for the data points.
`axis` can ha the following values:
You can add any number of series to the charts by `lv_chart_add_series(chart, color, axis)`. This will allocates a `lv_chart_series_t` structure which contains the chosen `color` and an array for the data points.
`axis` can have the following values:
- `LV_CHART_AXIS_PRIMARY_Y` Left axis
- `LV_CHART_AXIS_SECONDARY_Y` Right axis
- `LV_CHART_AXIS_PRIMARY_X` Bottom axis
@@ -51,12 +49,12 @@ It allocates data for a `lv_chart_series_t` structure which contains the chosen
`axis` tells which axis's range should be used te scale the values.
With `lv_chart_set_ext_y_array(chart, ser, value_array)` makes the chart use an external array for the given series.
`lv_chart_set_ext_y_array(chart, ser, value_array)` makes the chart use an external array for the given series.
`value_array` should look like this: `lv_coord_t * value_array[num_points]`. The array size needs to be large enough to hold all the points of that series.
The array's pointer will be saved in the chart so it needs to be global, static or dynamically allocated.
Note: you should call `lv_chart_refresh(chart)` after the external data source has been updated, to update the chart.
Note: you should call `lv_chart_refresh(chart)` after the external data source has been updated to update the chart.
The value array of a series can be get by `lv_chart_get_y_array(chart, ser)`. It can be use with `ext_array` or *normal array*s.
The value array of a series can be obtained with `lv_chart_get_y_array(chart, ser)`, which can be used with `ext_array` or *normal array*s.
For `LV_CHART_TYPE_SCATTER` type `lv_chart_set_ext_x_array(chart, ser, value_array)` and `lv_chart_get_x_array(chart, ser)` can be used as well.
@@ -75,17 +73,17 @@ For `LV_CHART_TYPE_SCATTER` type `lv_chart_set_value_by_id2(chart, ser, id, val
### Update modes
`lv_chart_set_next_value` can behave in two ways depending on *update mode*:
- `LV_CHART_UPDATE_MODE_SHIFT` Shift old data to the left and add the new one to the right.
- `LV_CHART_UPDATE_MODE_CIRCULAR` - Circularly add the new data (Like an ECG diagram).
- `LV_CHART_UPDATE_MODE_CIRCULAR` - Add the new data in circular fashion, like an ECG diagram).
The update mode can be changed with `lv_chart_set_update_mode(chart, LV_CHART_UPDATE_MODE_...)`.
### Number of points
The number of points in the series can be modified by `lv_chart_set_point_count(chart, point_num)`. The default value is 10.
Note: this also affects the number of points processed when an external buffer is assigned to a series. So you need to be sure the external array is large enough.
Note: this also affects the number of points processed when an external buffer is assigned to a series, so you need to be sure the external array is large enough.
#### Handling large number of points
On line charts if the number of points is greater than the pixels horizontally, the Chart will draw only vertical lines to make the drawing of large amount of data effective.
If there are let's say 10 point a pixel, LVGL searches the smallest and the greatest value and draws a vertical lines between them. It ensures to not miss any peaks.
If there are, let's say, 10 points to a pixel, LVGL searches the smallest and the largest value and draws a vertical lines between them to ensure no peaks are missed.
### Vertical range
You can specify the minimum and maximum values in y-direction with `lv_chart_set_range(chart, axis, min, max)`.
@@ -96,10 +94,10 @@ The value of the points will be scaled proportionally. The default range is: 0..
### Division lines
The number of horizontal and vertical division lines can be modified by `lv_chart_set_div_line_count(chart, hdiv_num, vdiv_num)`.
The default settings are 3 horizontal and 5 vertical division lines.
If the there is visible border on a side and there is not padding on that side the division line would be drawn on top the border, therefore on it won't be drawn.
If there is a visible border on a side and no padding on that side, the division line would be drawn on top of the border and therefore it won't be drawn.
### Override default start point for series
If you wish a plot to start from a point other than the default which is `point[0]` of the series, you can set an alternative
If you want a plot to start from a point other than the default which is `point[0]` of the series, you can set an alternative
index with the function `lv_chart_set_x_start_point(chart, ser, id)` where `id` is the new index position to start plotting from.
Note that `LV_CHART_UPDATE_MODE_SHIFT` also changes the `start_point`.
@@ -115,7 +113,7 @@ Ticks and labels can be added to the axis with `lv_chart_set_axis_tick(chart, ax
- `draw_size` extra size required to draw the tick and labels (start with 20 px and increase if the ticks/labels are clipped)
### Zoom
The chart can be zoom independently in x and y directions with `lv_chart_set_zoom_x(chart, factor)` and `lv_chart_set_zoom_y(chart, factor)`.
The chart can be zoomed independently in x and y directions with `lv_chart_set_zoom_x(chart, factor)` and `lv_chart_set_zoom_y(chart, factor)`.
If `factor` is 256 there is no zoom. 512 means double zoom, etc. Fractional values are also possible but &lt; 256 value is not allowed.
@@ -125,20 +123,20 @@ A cursor can be added with `lv_chart_cursor_t * c1 = lv_chart_add_cursor(chart,
The possible values of `dir` `LV_DIR_NONE/RIGHT/UP/LEFT/DOWN/HOR/VER/ALL` or their OR-ed values to tell in which direction(s) should the cursor be drawn.
`lv_chart_set_cursor_pos(chart, cursor, &point)` sets the position of the cursor.
`pos` is a pointer to an `lv_point_t` variable. E.g. `lv_point_t point = {10, 20};`. If the chart is scrolled the cursor will remain on the same place.
`pos` is a pointer to an `lv_point_t` variable. E.g. `lv_point_t point = {10, 20};`. If the chart is scrolled the cursor will remain in the same place.
`lv_chart_get_point_pos_by_id(chart, series, id, &point_out)` tells the coordinate of a given point. It's useful to place the cursor to given point.
`lv_chart_get_point_pos_by_id(chart, series, id, &point_out)` gets the coordinate of a given point. It's useful to place the cursor at a given point.
`lv_chart_set_cursor_point(chart, cursor, series, point_id)` sticks the cursor the point. If the point's position changes (new value or scrolling) the cursor will move with the point.
`lv_chart_set_cursor_point(chart, cursor, series, point_id)` sticks the cursor at a point. If the point's position changes (new value or scrolling) the cursor will move with the point.
## Events
- `LV_EVENT_VALUE_CHANGED` Sent when a new point is clicked perssed. `lv_chart_get_pressed_point(chart)` returns the zero based index of the pressed point.
- `LV_EVENT_DRAW_PART_BEGIN` and `LV_EVENT_DRAW_PART_END` are sent for multiple parts. The fields of `lv_obj_draw_part_dsc_t` is set as the followings:
- `LV_EVENT_VALUE_CHANGED` Sent when a new point is clicked pressed. `lv_chart_get_pressed_point(chart)` returns the zero-based index of the pressed point.
- `LV_EVENT_DRAW_PART_BEGIN` and `LV_EVENT_DRAW_PART_END` are sent for multiple parts. The fields of `lv_obj_draw_part_dsc_t` are set as follows:
- `LV_PART_ITEMS` (the series)
- *Line chart* `clip_area`, `id` (index of the point), `value` (value of `id`th point), `p1`, `p2` (points of the line), `draw_area` (area of the point), `line_dsc`, `rect_dsc`, `sub_part_ptr` (pointer to the series), `part`
- *Bar chart* `clip_area`, `id` (index of the point), `value` (value of `id`th point), `draw_area` (area of the point), `rect_dsc`, `sub_part_ptr` (pointer to the series), `part`
- `LV_PART_TICKS` (major tick lines and label) `clip_area`, `id` (axis), `value` (scaled value of the tick), `text` (`value` converted to decimal), `line_dsc`, `label_dsc`, `part`
- `LV_PART_CURSOR` Te events are send for 3 times:
- `LV_PART_CURSOR` These events are sent at three times:
- vertical line `clip_area`, `p1`, `p2` (points of the line), `line_dsc`, `part`
- horizontal line `clip_area`, `p1`, `p2` (points of the line), `line_dsc`, `part`
- point `clip_area`, `draw_area` (points of the line), `rect_dsc`, `part`

View File

@@ -5,10 +5,9 @@
# Color wheel (lv_colorwheel)
## Overview
As its name implies *Color wheel* allows to select color. The Hue, Saturation and Value of the color can be selected after each other.
As its name implies *Color wheel* allows the user to select a color. The Hue, Saturation and Value of the color can be selected separately.
Long pressing the object, the color wheel will change to the next parameter of the color (hue, saturation or value).
Besides, double click will reset the current parameter.
Long pressing the object, the color wheel will change to the next parameter of the color (hue, saturation or value). A double click will reset the current parameter.
## Parts and Styles
- `LV_PART_MAIN` Only `arc_width` is used to set the width of the color wheel
@@ -28,7 +27,7 @@ The color can be set manually with `lv_colorwheel_set_hue/saturation/value(color
The current color mode can be manually selected with `lv_colorwheel_set_color_mode(colorwheel, LV_COLORWHEEL_MODE_HUE/SATURATION/VALUE)`.
The color mode be fixed (do not change with long press) using `lv_colorwheel_set_color_mode_fixed(colorwheel, true)`
The color mode can be fixed (so as to not change with long press) using `lv_colorwheel_set_color_mode_fixed(colorwheel, true)`
## Events
- `LV_EVENT_VALUE_CHANGED` Sent if a new color is selected.
@@ -38,7 +37,7 @@ Learn more about [Events](/overview/event).
## Keys
- `LV_KEY_UP`, `LV_KEY_RIGHT` Increment the current parameter's value by 1
- `LV_KEY_DOWN`, `LV_KEY_LEFT` Decrement the current parameter's by 1
- `LV_KEY_ENTER` By long press the next mode will be shown. By double click the current parameter will be reset.
- `LV_KEY_ENTER` A long press will show the next mode. Double click to reset the current parameter.
Learn more about [Keys](/overview/indev).

View File

@@ -20,7 +20,7 @@ You can set a left, right and center image, and the center image will be repeate
### Image sources
To set the image in a state, use the `lv_imgbtn_set_src(imgbtn, LV_IMGBTN_STATE_..., src_left, src_center, src_right)`.
The image sources works the same as described in the [Image object](/widgets/core/img) except that, "Symbols" are not supported by the Image button.
The image sources work the same as described in the [Image object](/widgets/core/img) except that "Symbols" are not supported by the Image button.
Any of the sources can `NULL`.
The possible states are:
@@ -31,7 +31,7 @@ The possible states are:
- `LV_IMGBTN_STATE_CHECKED_PRESSED`
- `LV_IMGBTN_STATE_CHECKED_DISABLED`
If you set the sources only in `LV_IMGBTN_STATE_RELEASED`, the sources will be used in other states too.
If you set sources only in `LV_IMGBTN_STATE_RELEASED`, these sources will be used in other states too.
If you set e.g. `LV_IMGBTN_STATE_PRESSED` they will be used in pressed state instead of the released images.
## Events

View File

@@ -12,8 +12,8 @@ The Keyboard object is a special [Button matrix](/widgets/core/btnmatrix) with p
## Parts and Styles
Similarly to Button matrices Keyboards consist of 2 part:
- `LV_PART_MAIN` The main part and uses all the typical background properties
- `LV_PART_ITEMS` The buttons and it also uses all typical background properties and the *text* properties.
- `LV_PART_MAIN` The main part. Uses all the typical background properties
- `LV_PART_ITEMS` The buttons. Also uses all typical background properties as well as the *text* properties.
## Usage
@@ -36,7 +36,7 @@ To assign the text area, use `lv_keyboard_set_textarea(kb, ta)`.
### New Keymap
You can specify a new map (layout) for the keyboard with `lv_keyboard_set_map(kb, map)` and `lv_keyboard_set_ctrl_map(kb, ctrl_map)`.
Learn more about the [Button matrix](/widgets/core/btnmatrix) object.
Keep in mind that, using following keywords will have the same effect as with the original map:
Keep in mind that using following keywords will have the same effect as with the original map:
- `LV_SYMBOL_OK` Apply.
- `LV_SYMBOL_CLOSE` or `LV_SYMBOL_KEYBOARD` Close.
- `LV_SYMBOL_BACKSPACE` Delete on the left.
@@ -52,9 +52,7 @@ Keep in mind that, using following keywords will have the same effect as with th
- `LV_EVENT_READY` - The *Ok* button is clicked.
- `LV_EVENT_CANCEL` - The *Close* button is clicked.
The keyboard has a **default event handler** callback called `lv_keyboard_def_event_cb`.
It handles the button pressing, map changing, the assigned text area, etc.
You can remove it and replace it with a custom event handler if you wish.
The keyboard has a **default event handler** callback called `lv_keyboard_def_event_cb`, which handles the button pressing, map changing, the assigned text area, etc. You can remove it and replace it with a custom event handler if you wish.
Learn more about [Events](/overview/event).

View File

@@ -6,7 +6,7 @@
## Overview
The LEDs are rectangle-like (or circle) object. It's brightness can be adjusted. With lower brightness the the colors of the LED become darker.
The LEDs are rectangle-like (or circle) object whose brightness can be adjusted. With lower brightness the colors of the LED become darker.
## Parts and Styles
The LEDs have only one main part, called `LV_LED_PART_MAIN` and it uses all the typical background style properties.

View File

@@ -24,7 +24,7 @@ See the [Button](/widgets/core/btn)'s and [Label](/widgets/core/label)'s documen
The text starts to scroll horizontally if its too long.
### Texts
`lv_list_add_text(list, icon, text)` adds a text.
`lv_list_add_text(list, text)` adds a text.
## Events

View File

@@ -8,23 +8,23 @@
The Meter widget can visualize data in very flexible ways. In can show arcs, needles, ticks lines and labels.
## Parts and Styles
- `LV_PART_MAIN` The background of the Meter and it uses the typical background properties.
- `LV_PART_MAIN` The background of the Meter. Uses the typical background properties.
- `LV_PART_TICK` The tick lines a labels using the *line* and *text* style properties.
- `LV_PART_INDICATOR` The needle line or image using the *line* and *img* style properties, plus the background properties to draw a square (or circle) on the pivot of the needles. Padding makes the square larger.
- `LV_PART_INDICATOR` The needle line or image using the *line* and *img* style properties, as well as the background properties to draw a square (or circle) on the pivot of the needles. Padding makes the square larger.
- `LV_PART_ITEMS` The arcs using the *arc* properties.
## Usage
### Add a scale
For first a *Scale* needs to be added to the Meter with `lv_meter_scale_t * scale = lv_meter_add_scale(meter)`.
The Scale has minor and major ticks and labels on the major tick. Later indicators (needles, arcs, tick modifiers) can be added to the meter
First a *Scale* needs to be added to the Meter with `lv_meter_scale_t * scale = lv_meter_add_scale(meter)`.
The Scale has minor and major ticks and labels on the major ticks. Later indicators (needles, arcs, tick modifiers) can be added to the meter
Any number of scaled can be added to Meter.
Any number of scales can be added to Meter.
The minor tick lines can be configured with: `lv_meter_set_scale_ticks(meter, scale, tick_count, line_width, tick_length, ctick_olor)`.
To add major tick lines use `lv_meter_set_scale_major_ticks(meter, scale, nth_major, tick_width, tick_length, tick_color, label_gap)`. `nth_major` tells how many minor ticks to skip to draw a major tick.
To add major tick lines use `lv_meter_set_scale_major_ticks(meter, scale, nth_major, tick_width, tick_length, tick_color, label_gap)`. `nth_major` to specify how many minor ticks to skip to draw a major tick.
Labels are added automatically on major ticks with `label_gap` distance from the ticks with text proportionally to the values of the tick line.
@@ -34,7 +34,7 @@ Labels are added automatically on major ticks with `label_gap` distance from the
Indicators needs to be added to a Scale and their value is interpreted in the range of the Scale.
All the indicator add functions returns `lv_meter_indicator_t *`.
All the indicator add functions return `lv_meter_indicator_t *`.
#### Needle line
@@ -57,7 +57,7 @@ All the indicator add functions returns `lv_meter_indicator_t *`.
#### Scale lines (ticks)
`indic = lv_meter_add_scale_lines(meter, scale, color_start, color_end, local, width_mod)` adds an indicator that modifies the ticks lines.
If `local` is `true` the ticks' color will be faded from `color_start` to `color_end` in the indicator's start and end value range.
If `local` is `false` `color_start` and `color_end` is mapped to the start and end value of the scale and only a "slice" of that color gradient will be visible in the indicator's start and end value range.
If `local` is `false` `color_start` and `color_end` will be mapped to the start and end value of the scale and only a "slice" of that color gradient will be visible in the indicator's start and end value range.
`width_mod` modifies the width of the tick lines.
`lv_meter_set_indicator_start_value(meter, inidicator, value)` and `lv_meter_set_indicator_end_value(meter, inidicator, value)` sets the value of the indicator.

View File

@@ -8,9 +8,9 @@
The Message boxes act as pop-ups.
They are built from a background container, a title, an optional close button, a text and optional buttons.
The text will be broken into multiple lines automatically and the height will be set automatically to involve the text and the buttons.
The text will be broken into multiple lines automatically and the height will be set automatically to include the text and the buttons.
The message box can be a modal (block clicks on the rest of the screen) or not modal.
The message box can be modal (blocking clicks on the rest of the screen) or not modal.
## Parts and Styles
The mesasge box is built from other widgets so you can check these widget's documentation for details.
@@ -21,16 +21,16 @@ The mesasge box is built from other widgets so you can check these widget's docu
## Usage
### Create a messaeg box
### Create a message box
`lv_msgbox_create(parent, title, txt, btn_txts[], add_close_btn)` creates a message box.
If `parent` is `NULL` the message box will be a modal. `title` and `txt` are strings for the title and the text.
If `parent` is `NULL` the message box will be modal. `title` and `txt` are strings for the title and the text.
`btn_txts[]` is an array with the buttons' text. E.g. `const char * btn_txts[] = {"Ok", "Cancel", NULL}`.
`add_colse_btn` can be `true` or `false` to add/don't add a close button.
### Get the parts
The building block of the message box can be get with the following functions:
The building blocks of the message box can be obtained using the following functions:
```c
lv_obj_t * lv_msgbox_get_title(lv_obj_t * mbox);
lv_obj_t * lv_msgbox_get_close_btn(lv_obj_t * mbox);
@@ -43,7 +43,7 @@ lv_obj_t * lv_msgbox_get_btns(lv_obj_t * mbox);
## Events
- `LV_EVENT_VALUE_CHANGED` is sent by the buttons if one of them is clicked. `LV_OBJ_FLAG_EVENT_BUBBLE` is enabled on the buttons so you can add events to the message box itself.
In the event `lv_event_get_target(e)` will give the button matrix, `lv_event_get_current_target(e)` will give the message box. `lv_msgbox_get_active_btn_text(msgbox)` can be used to get the text of the clicked button.
In the event handler, `lv_event_get_target(e)` will return the button matrix and `lv_event_get_current_target(e)` will givreturn the message box. `lv_msgbox_get_active_btn_text(msgbox)` can be used to get the text of the clicked button.
Learn more about [Events](/overview/event).

View File

@@ -6,21 +6,21 @@
## Overview
A spangroup is the object that is used to display rich text. different from the label object, `spangroup` can automatically organize text of different fonts, colors, and sizes into the spangroup obj.
A spangroup is the object that is used to display rich text. Different from the label object, `spangroup` can automatically organize text of different fonts, colors, and sizes into the spangroup obj.
## Parts and Styles
- `LV_PART_MAIN` The spangroup has only the part.
- `LV_PART_MAIN` The spangroup has only one part.
## Usage
### Set text and style
spangroup object uses span to describe text and text style. so, first we need to create `span` descriptor use function `lv_span_t * span = lv_spangroup_new_span(spangroup)`.then use `lv_span_set_text(span, "text")` to set text.The style of the modified text is the same as the normal style used,eg:`lv_style_set_text_color(&span->style, lv_palette_main(LV_PALETTE_RED))`.
The spangroup object uses span to describe text and text style. so, first we need to create `span` descriptor using `lv_span_t * span = lv_spangroup_new_span(spangroup)`. Then use `lv_span_set_text(span, "text")` to set text.The style of the modified text is the same as the normal style used, eg:`lv_style_set_text_color(&span->style, lv_palette_main(LV_PALETTE_RED))`.
If spangroup object `mode != LV_SPAN_MODE_FIXED`.You must call `lv_spangroup_refr_mode()` after you have modified `span` style(eg:set text, changed the font size, del span).
If spangroup object `mode != LV_SPAN_MODE_FIXED` you must call `lv_spangroup_refr_mode()` after you have modified `span` style(eg:set text, changed the font size, del span).
### Text align
like label object, The spangroup can be one the following modes:
like label object, the spangroup can be set to one the following modes:
- `LV_TEXT_ALIGN_LEFT` Align text to left.
- `LV_TEXT_ALIGN_CENTER` Align text to center.
- `LV_TEXT_ALIGN_RIGHT` Align text to right.
@@ -29,22 +29,22 @@ like label object, The spangroup can be one the following modes:
use function `lv_spangroup_set_align(spangroup, LV_TEXT_ALIGN_CENTER)` to set text align.
### Modes
The spangroup can be one the following modes:
- `LV_SPAN_MODE_FIXED` fixed the obj size.
- `LV_SPAN_MODE_EXPAND` Expand the object size to the text size. only one line.
The spangroup can be set to one the following modes:
- `LV_SPAN_MODE_FIXED` fixes the object size.
- `LV_SPAN_MODE_EXPAND` Expand the object size to the text size but stay on a single line.
- `LV_SPAN_MODE_BREAK` Keep width, break the too long lines and auto expand height.
use function `lv_spangroup_set_mode(spangroup, LV_SPAN_MODE_BREAK)` to set obj mode.
Use `lv_spangroup_set_mode(spangroup, LV_SPAN_MODE_BREAK)` to set object mode.
### Overflow
The spangroup can be one the following modes:
- `LV_SPAN_OVERFLOW_CLIP` truncate the text at the limit of the area.
- `LV_SPAN_OVERFLOW_ELLIPSIS` This mode value will display an ellipsis(`...`) when text overflow the area.
The spangroup can be set to one the following modes:
- `LV_SPAN_OVERFLOW_CLIP` truncates the text at the limit of the area.
- `LV_SPAN_OVERFLOW_ELLIPSIS` will display an ellipsis(`...`) when text overflows the area.
use function `lv_spangroup_set_overflow(spangroup, LV_SPAN_OVERFLOW_CLIP)` to set obj Overflow.
Use `lv_spangroup_set_overflow(spangroup, LV_SPAN_OVERFLOW_CLIP)` to set object overflow mode.
### first line indent
use function `lv_spangroup_set_indent(spangroup, 20)` to set text indent of first line.
Use `lv_spangroup_set_indent(spangroup, 20)` to set the indent of the first line, in pixels.
## Events
No special events are sent by this widget.

View File

@@ -9,7 +9,7 @@ The Spinbox contains a number as text which can be increased or decreased by *Ke
Under the hood the Spinbox is a modified [Text area](/widgets/core/textarea).
## Parts and Styles
The parts of the Spinbox are identiacl to the [Text area](/widgets/core/textarea).
The parts of the Spinbox are identical to the [Text area](/widgets/core/textarea).
### Value, range and step
`lv_spinbox_set_value(spinbox, 1234)` sets a new value on the Spinbox.
@@ -18,16 +18,15 @@ The parts of the Spinbox are identiacl to the [Text area](/widgets/core/textarea
`lv_spinbox_set_range(spinbox, -1000, 2500)` sets a range. If the value is changed by `lv_spinbox_set_value`, by *Keys*,`lv_spinbox_increment/decrement` this range will be respected.
`lv_spinbox_set_step(spinbox, 100)` sets which digits to change on increment/decrement. Only 10^n values values can be set, and not for example 3.
`lv_spinbox_set_step(spinbox, 100)` sets which digits to change on increment/decrement. Only multiples of ten can be set, and not for example 3.
### Format
`lv_spinbox_set_digit_format(spinbox, digit_count, separator_position)` sets the number format. `digit_count` is the number of digit excluding the decimal separator and the sign.
`separator_position` is the number of digit before the decimal point. If 0, decimal point is not
`lv_spinbox_set_digit_format(spinbox, digit_count, separator_position)` sets the number format. `digit_count` is the number of digits excluding the decimal separator and the sign.
`separator_position` is the number of digits before the decimal point. If 0, no decimal point is displayed.
### Rollover
`lv_spinbox_set_rollover(spinbox, true/false)` enables/disabled rolloiver mode. If the minimum or maximum values is reached with rollover the value will change to the other limit.
If not enabled the value will be reamain at the minimum or maximum value.
`lv_spinbox_set_rollover(spinbox, true/false)` enables/disabled rollover mode. If either the minimum or maximum value is reached with rollover enabled, the value will change to the other limit. If rollover is disabled the value will be remain at the minimum or maximum value.
## Events
- `LV_EVENT_VALUE_CHANGED` Sent when the value has changed.

View File

@@ -14,7 +14,7 @@ The parts are identical to the parts of [lv_arc](/widgets/core/arc).
### Create a spinner
To create spinner use `lv_spinner_create(parent, spin_time, arc_length)`. `spin time` set the spin time in milliseconds, `arc_length` sets the length of the spinning arc in degrees.
To create a spinner use `lv_spinner_create(parent, spin_time, arc_length)`. `spin time` sets the spin time in milliseconds, `arc_length` sets the length of the spinning arc in degrees.
## Events
No special events are sent the the Spinner.

View File

@@ -8,18 +8,18 @@
## Overview
The Tab view object can be used to organize content in tabs.
The Tab view is built from other widgets like this:
The Tab view is built from other widgets:
- Main container: [lv_obj](/widgets/obj))
- Tab buttons: [lv_btnmatrix](/widgets/core/btnmatrix)
- Container for the tabs: [lv_obj](/widgets/obj)
- Content of the tabs: [lv_obj](/widgets/obj)
The tab buttons can be positioned on the topn, bottom, left and right side of teh Tab view.
The tab buttons can be positioned on the top, bottom, left and right side of the Tab view.
A new tab can be selected either clicking on a tab button or sliding horizontally on the content.
A new tab can be selected either by clicking on a tab button or by sliding horizontally on the content.
## Parts and Styles
There are no special parts on the Tab view but the `lv_obj` and `lv_btnnmatrix` widgets are used to build up the Tab view.
There are no special parts on the Tab view but the `lv_obj` and `lv_btnnmatrix` widgets are used to create the Tab view.
## Usage
@@ -30,7 +30,7 @@ There are no special parts on the Tab view but the `lv_obj` and `lv_btnnmatrix`
### Add tabs
New tabs can be added with `lv_tabview_add_tab(tabview, "Tab name")`. It will return with a pointer to an [lv_obj](/widgets/obj) object where the tab's content can be created.
New tabs can be added with `lv_tabview_add_tab(tabview, "Tab name")`. This will return a pointer to an [lv_obj](/widgets/obj) object where the tab's content can be created.
### Change tab
@@ -41,7 +41,7 @@ To select a new tab you can:
### Get the parts
`lv_tabview_get_content(tabview)` return the container for the tabs, `lv_tabview_get_tab_btns(tabview)` returns the Tab buttons which is a [Button matrix](/widgets/core/btnmatrix).
`lv_tabview_get_content(tabview)` returns the container for the tabs, `lv_tabview_get_tab_btns(tabview)` returns the Tab buttons object which is a [Button matrix](/widgets/core/btnmatrix).
## Events
- `LV_EVENT_VALUE_CHANGED` Sent when a new tab is selected by sliding or clicking the tab button. `lv_tabview_get_tab_act(tabview)` returns the zero based index of the current tab.
@@ -50,7 +50,7 @@ Learn more about [Events](/overview/event).
## Keys
Keys have effect only on the tab buttons (Button matrix). You can add it manually to a group if required.
Keys have effect only on the tab buttons (Button matrix). Add manually to a group if required.
Learn more about [Keys](/overview/indev).

View File

@@ -6,14 +6,14 @@
## Overview
The Tile view is a container object where its elements (called *tiles*) can be arranged in a grid form.
The Tile view is a container object whose elements (called *tiles*) can be arranged in grid form.
By swiping the user can navigate between the tiles.
Any direction of swiping can be disabled on the tiles individually to not allow moving from tile to an other.
Any direction of swiping can be disabled on the tiles individually to not allow moving from one tile to another.
If the Tile view is screen sized it gives a user interface you might have seen on the smartwatches.
If the Tile view is screen sized, the user interface resembles what you may have seen on smartwatches.
## Parts and Styles
The Tile view is build from an [lv_obj](/widgets/obj) container and also [lv_obj](/widgets/obj) tiles.
The Tile view is built from an [lv_obj](/widgets/obj) container and [lv_obj](/widgets/obj) tiles.
The parts and styles work the same as for [lv_obj](/widgets/obj).
@@ -22,7 +22,7 @@ The parts and styles work the same as for [lv_obj](/widgets/obj).
### Add a tile
`lv_tileview_add_tile(tileview, row_id, col_id, dir)` creates a new tile on the `row_id`th row and `col_id`th column.
`dir` can be `LV_DIR_LEFT/RIGHT/TOP/BOTTOM/HOR/VER/ALL` or OR-ed values to enable moving to the adjacent tiles into the given direction with swiping.
`dir` can be `LV_DIR_LEFT/RIGHT/TOP/BOTTOM/HOR/VER/ALL` or OR-ed values to enable moving to the adjacent tiles into the given direction by swiping.
The returned value is an `lv_obj_t *` on which the content of the tab can be created.
@@ -31,7 +31,7 @@ The Tile view can scroll to a tile with `lv_obj_set_tile(tileview, tile_obj, LV_
## Events
- `LV_EVENT_VALUE_CHANGED` Sent when a new tile loaded either with scrolling. `lv_tileview_get_tile_act(tabview)` can be used to get current tile.
- `LV_EVENT_VALUE_CHANGED` Sent when a new tile loaded by scrolling. `lv_tileview_get_tile_act(tabview)` can be used to get current tile.
## Keys
*Keys* are not handled by the Tile view.

View File

@@ -6,10 +6,10 @@
## Overview
The Window is container-like objects built from a header with title and button and a content area.
The Window is container-like object built from a header with title and buttons and a content area.
## Parts and Styles
The Window is built from other widgets so you can check these widget's documentation for details:
The Window is built from other widgets so you can check their documentation for details:
- Background: [lv_obj](/widgets/obj)
- Header on the background: [lv_obj](/widgets/obj)
- Title on the header: [lv_label](/widgets/core/label)
@@ -21,19 +21,19 @@ The Window is built from other widgets so you can check these widget's document
### Create a Window
`lv_win_create(parent, header_height)` creates a Window with am empty header.
`lv_win_create(parent, header_height)` creates a Window with an empty header.
### Title and buttons
Any number of text's (but typically only one) can be added to the header with `lv_win_add_title(win, "The title")`.
Any number of texts (but typically only one) can be added to the header with `lv_win_add_title(win, "The title")`.
Control buttons can be added to the window's header with `lv_win_add_btn_right(win, icon, btn_width)`. `icon` can be any image source, and `btn_width` is the width of the button.
The title and the buttons will be added in the order of the functions are called. So adding a button, a text and two other buttons will result in a button on the left, a title, ant 2 buttons on the right.
The width of the title is set to take all the remaining space on the header. In other words it pushes the buttons to the right added after the title.
The title and the buttons will be added in the order the functions are called. So adding a button, a text and two other buttons will result in a button on the left, a title, and 2 buttons on the right.
The width of the title is set to take all the remaining space on the header. In other words: it pushes to the right all the buttons that are added after the title.
## Get the parts
`lv_win_get_header(win)` return a pointer to the header, `lv_win_get_content(win)` returns a pointer to the content container to which the content of the window can be added.
`lv_win_get_header(win)` returns a pointer to the header, `lv_win_get_content(win)` returns a pointer to the content container to which the content of the window can be added.
## Events
No special events are sent by the windows, however events can be added manually to the return value of `lv_win_add_btn_right`.

View File

@@ -15,23 +15,23 @@ The 'Base Object' implements the basic properties of widgets on a screen, such a
In object-oriented thinking, it is the base class from which all other objects in LVGL are inherited.
The functions and functionalities of Base object can be used with other widgets too. For example `lv_obj_set_width(slider, 100)`
The functions and functionalities of the Base object can be used with other widgets too. For example `lv_obj_set_width(slider, 100)`
The Base object can be directly used as a simple widgets. It nothing else than a rectangle. Or from the the HTML world it's like a `<div>`.
The Base object can be directly used as a simple widget: it nothing else than a rectangle. In HTML terms, think of it as a `<div>`.
### Coordinates
Here only a small subset of cooridnate settings is described. To see all the features of LVGL (padding, cooridnates in styles, layouts, etc) visit the [Coordinates](/overview/coords) page.
Only a small subset of coordinate settings is described here. To see all the features of LVGL (padding, coordinates in styles, layouts, etc) visit the [Coordinates](/overview/coords) page.
#### Size
The object size can be modified on individual axes with `lv_obj_set_width(obj, new_width)` and `lv_obj_set_height(obj, new_height)`, or both axes can be modified at the same time with `lv_obj_set_size(obj, new_width, new_height)`.
#### Position
You can set the x and y coordinates relative to the parent with `lv_obj_set_x(obj, new_x)` and `lv_obj_set_y(obj, new_y)`, or both at the same time with `lv_obj_set_pos(obj, new_x, new_y)`.
You can set the position relative to the parent with `lv_obj_set_x(obj, new_x)` and `lv_obj_set_y(obj, new_y)`, or both axes at the same time with `lv_obj_set_pos(obj, new_x, new_y)`.
#### Alignment
You can align the object on it's parent with `lv_obj_set_align(obj, LV_ALIGN_...)`. After this every x and y settings will be ralitiev to the set alignment mode.
For example a this will shift the object by 10;20 px fro mthe center of its parent.
You can align the object on its parent with `lv_obj_set_align(obj, LV_ALIGN_...)`. After this every x and y setting will be ralitive to the set alignment mode.
For example a this will shift the object by 10;20 px from the center of its parent.
```c
lv_obj_set_align(obj, LV_ALIGN_CENTER);
lv_obj_set_pos(obj, 10, 20);
@@ -40,11 +40,11 @@ lv_obj_set_pos(obj, 10, 20);
lv_obj_align(obj, LV_ALIGN_CENTER, 10, 20);
```
To align an object to an other use `lv_obj_align_to(obj_to_align, obj_referece, LV_ALIGN_..., x, y)`
To align one object to another use `lv_obj_align_to(obj_to_align, obj_referece, LV_ALIGN_..., x, y)`
For example, to align a text below an image: `lv_obj_align(text, image, LV_ALIGN_OUT_BOTTOM_MID, 0, 10)`.
The following align types exists:
The following align types exist:
![](/misc/align.png "Alignment types in LVGL")
@@ -52,9 +52,9 @@ The following align types exists:
You can set a new parent for an object with `lv_obj_set_parent(obj, new_parent)`. To get the current parent, use `lv_obj_get_parent(obj)`.
To get a specific children of a parent use `lv_obj_get_child(parent, idx)`. Some examples for `idx`:
- `0` get the firstly (youngest) created child
- `1` get the secondly created child
- `-1` get the lastly (youngest) craeted child
- `0` get the child created first child
- `1` get the child created second
- `-1` get the child created last
The children can be iterated lke this
```c
@@ -65,14 +65,14 @@ for(i = 0; i < lv_obj_get_child_cnt(parent); i++) {
}
```
`lv_obj_get_child_id(obj)` tells the index of the object. That is how many younger children its parent has.
`lv_obj_get_child_id(obj)` returns the index of the object. That is how many younger children its parent has.
You can bring an object to the foreground or send it to the background with `lv_obj_move_foreground(obj)` and `lv_obj_move_background(obj)`.
### Screens
When you have created a screen like `lv_obj_t * screen = lv_obj_create(NULL)`, you can load it with `lv_scr_load(screen)`. The `lv_scr_act()` function gives you a pointer to the current screen.
If you have more display then it's important to know that these functions operate on the lastly created or the explicitly selected (with `lv_disp_set_default`) display.
If you have multiple displays then it's important to know that these functions operate on the most-recently created or on the explicitly selected (with `lv_disp_set_default`) display.
To get an object's screen use the `lv_obj_get_screen(obj)` function.
@@ -86,12 +86,12 @@ Read the [Event overview](/overview/event) to learn more about the events.
### Styles
Be sure to read the [Style overview](/overview/style). Here or only the most essential functions are described.
Be sure to read the [Style overview](/overview/style). Here only the most essential functions are described.
A new style can be added to an object with `lv_obj_add_style(obj, &new_style, selector)` function.
`selector` is a combination of part and state(s). E.g. `LV_PART_SCROLLBAR | LV_STATE_PRESSED`.
The Base object use `LV_PART_MAIN` style properties and `LV_PART_SCROLLBAR` with the typical backgroud style proeprties.
The base objects use `LV_PART_MAIN` style properties and `LV_PART_SCROLLBAR` with the typical backgroud style properties.
### Flags
@@ -104,7 +104,7 @@ There are some attributes which can be enabled/disabled by `lv_obj_add/clear_fla
- `LV_OBJ_FLAG_SCROLLABLE` Make the object scrollable
- `LV_OBJ_FLAG_SCROLL_ELASTIC` Allow scrolling inside but with slower speed
- `LV_OBJ_FLAG_SCROLL_MOMENTUM` Make the object scroll further when "thrown"
- `LV_OBJ_FLAG_SCROLL_ONE`Allow scrolling only one snapable children
- `LV_OBJ_FLAG_SCROLL_ONE` Allow scrolling only one snapable children
- `LV_OBJ_FLAG_SCROLL_CHAIN` Allow propagating the scroll to a parent
- `LV_OBJ_FLAG_SCROLL_ON_FOCUS` Automatically scroll object to make it visible when focused
- `LV_OBJ_FLAG_SNAPABLE` If scroll snap is enabled on the parent it can snap to this object
@@ -139,21 +139,21 @@ lv_obj_clear_flag(obj, LV_OBJ_FLAG_CLICKABLE);
Read the [Input devices overview](/overview/indev) to learn more about the *Groups*.
Once, an object is added to *group* with `lv_group_add_obj(group, obj)` the object's current group can be get with `lv_obj_get_group(obj)`.
Objects are added to a *group* with `lv_group_add_obj(group, obj)`, and you can use `lv_obj_get_group(obj)` to see which group an object belongs to.
`lv_obj_is_focused(obj)` tells if the object is currently focused on its group or not. If the object is not added to a group, `false` will be returned.
`lv_obj_is_focused(obj)` returns if the object is currently focused on its group or not. If the object is not added to a group, `false` will be returned.
### Extended click area
By default, the objects can be clicked only on their coordinates, however, this area can be extended with `lv_obj_set_ext_click_area(obj, size)`.
## Events
- `LV_EVENT_VALUE_CHANGED` when the `LV_OBJ_FLAG_CHECKABLE` flag is enabled and the obejct clicked (on transition to/from the checked state)
- `LV_EVENT_VALUE_CHANGED` when the `LV_OBJ_FLAG_CHECKABLE` flag is enabled and the object clicked (on transition to/from the checked state)
Learn more about [Events](/overview/event).
## Keys
If `LV_OBJ_FLAG_CHECKABLE` is enabled `LV_KEY_RIGHT` and `LV_KEY_UP` makes the object checked, and `LV_KEY_LEFT` and `LV_KEY_DOWN` makes it unchecked.
If `LV_OBJ_FLAG_CHECKABLE` is enabled `LV_KEY_RIGHT` and `LV_KEY_UP` make the object checked, and `LV_KEY_LEFT` and `LV_KEY_DOWN` make it unchecked.
Learn more about [Keys](/overview/indev).

View File

@@ -41,7 +41,7 @@ void my_disp_flush( lv_disp_drv_t *disp, const lv_area_t *area, lv_color_t *colo
}
/*Read the touchpad*/
bool my_touchpad_read( lv_indev_drv_t * indev_driver, lv_indev_data_t * data )
void my_touchpad_read( lv_indev_drv_t * indev_driver, lv_indev_data_t * data )
{
uint16_t touchX, touchY;
@@ -65,8 +65,6 @@ bool my_touchpad_read( lv_indev_drv_t * indev_driver, lv_indev_data_t * data )
Serial.print( "Data y " );
Serial.println( touchY );
}
return false; /*Return `false` because we are not buffering and no more data to read*/
}
void setup()
@@ -135,4 +133,4 @@ void loop()
{
lv_timer_handler(); /* let the GUI do its work */
delay( 5 );
}
}

View File

@@ -9,7 +9,7 @@ static void slider_event_cb(lv_event_t * e)
/*Refresh the text*/
lv_label_set_text_fmt(label, "%d", lv_slider_get_value(slider));
lv_obj_align_to(label, slider, LV_ALIGN_OUT_TOP_MID, 0, -15); /*Align below the slider*/
lv_obj_align_to(label, slider, LV_ALIGN_OUT_TOP_MID, 0, -15); /*Align top of the slider*/
}
/**
@@ -26,7 +26,7 @@ void lv_example_get_started_3(void)
/*Create a label below the slider*/
label = lv_label_create(lv_scr_act());
lv_label_set_text(label, "0");
lv_obj_align_to(label, slider, LV_ALIGN_OUT_TOP_MID, 0, -15); /*Align below the slider*/
lv_obj_align_to(label, slider, LV_ALIGN_OUT_TOP_MID, 0, -15); /*Align top of the slider*/
}
#endif

View File

@@ -10,6 +10,7 @@
* INCLUDES
*********************/
#include "lv_port_disp_template.h"
#include "../../lvgl.h"
/*********************
* DEFINES

View File

@@ -10,6 +10,7 @@
* INCLUDES
*********************/
#include "lv_port_fs_template.h"
#include "../../lvgl.h"
/*********************
* DEFINES
@@ -19,23 +20,6 @@
* TYPEDEFS
**********************/
/*Create a type to store the required data about your file.
*If you are using a File System library
*it already should have a File type.
*For example FatFS has `FIL`. In this case use `typedef FIL file_t`*/
typedef struct {
/*Add the data you need to store about a file*/
uint32_t dummy1;
uint32_t dummy2;
}file_t;
/*Similarly to `file_t` create a type for directory reading too*/
typedef struct {
/*Add the data you need to store about directory reading*/
uint32_t dummy1;
uint32_t dummy2;
}dir_t;
/**********************
* STATIC PROTOTYPES
**********************/
@@ -45,13 +29,10 @@ static lv_fs_res_t fs_open (lv_fs_drv_t * drv, void * file_p, const char * path,
static lv_fs_res_t fs_close (lv_fs_drv_t * drv, void * file_p);
static lv_fs_res_t fs_read (lv_fs_drv_t * drv, void * file_p, void * buf, uint32_t btr, uint32_t * br);
static lv_fs_res_t fs_write(lv_fs_drv_t * drv, void * file_p, const void * buf, uint32_t btw, uint32_t * bw);
static lv_fs_res_t fs_seek (lv_fs_drv_t * drv, void * file_p, uint32_t pos);
static lv_fs_res_t fs_seek (lv_fs_drv_t * drv, void * file_p, uint32_t pos, lv_fs_whence_t whence););
static lv_fs_res_t fs_size (lv_fs_drv_t * drv, void * file_p, uint32_t * size_p);
static lv_fs_res_t fs_tell (lv_fs_drv_t * drv, void * file_p, uint32_t * pos_p);
static lv_fs_res_t fs_remove (lv_fs_drv_t * drv, const char *path);
static lv_fs_res_t fs_trunc (lv_fs_drv_t * drv, void * file_p);
static lv_fs_res_t fs_rename (lv_fs_drv_t * drv, const char * oldname, const char * newname);
static lv_fs_res_t fs_free (lv_fs_drv_t * drv, uint32_t * total_p, uint32_t * free_p);
static lv_fs_res_t fs_dir_open (lv_fs_drv_t * drv, void * rddir_p, const char *path);
static lv_fs_res_t fs_dir_read (lv_fs_drv_t * drv, void * rddir_p, char *fn);
static lv_fs_res_t fs_dir_close (lv_fs_drv_t * drv, void * rddir_p);
@@ -88,7 +69,6 @@ void lv_port_fs_init(void)
lv_fs_drv_init(&fs_drv);
/*Set up fields...*/
fs_drv.file_size = sizeof(file_t);
fs_drv.letter = 'P';
fs_drv.open_cb = fs_open;
fs_drv.close_cb = fs_close;
@@ -96,13 +76,7 @@ void lv_port_fs_init(void)
fs_drv.write_cb = fs_write;
fs_drv.seek_cb = fs_seek;
fs_drv.tell_cb = fs_tell;
fs_drv.free_space_cb = fs_free;
fs_drv.size_cb = fs_size;
fs_drv.remove_cb = fs_remove;
fs_drv.rename_cb = fs_rename;
fs_drv.trunc_cb = fs_trunc;
fs_drv.rddir_size = sizeof(dir_t);
fs_drv.dir_close_cb = fs_dir_close;
fs_drv.dir_open_cb = fs_dir_open;
fs_drv.dir_read_cb = fs_dir_read;
@@ -124,44 +98,41 @@ static void fs_init(void)
/**
* Open a file
* @param drv pointer to a driver where this function belongs
* @param file_p pointer to a file_t variable
* @param path path to the file beginning with the driver letter (e.g. S:/folder/file.txt)
* @param mode read: FS_MODE_RD, write: FS_MODE_WR, both: FS_MODE_RD | FS_MODE_WR
* @return LV_FS_RES_OK or any error from lv_fs_res_t enum
* @param drv pointer to a driver where this function belongs
* @param path path to the file beginning with the driver letter (e.g. S:/folder/file.txt)
* @param mode read: FS_MODE_RD, write: FS_MODE_WR, both: FS_MODE_RD | FS_MODE_WR
* @return a file descriptor or NULL on error
*/
static lv_fs_res_t fs_open (lv_fs_drv_t * drv, void * file_p, const char * path, lv_fs_mode_t mode)
static void * fs_open (lv_fs_drv_t * drv, const char * path, lv_fs_mode_t mode)
{
lv_fs_res_t res = LV_FS_RES_NOT_IMP;
void * f = NULL;
if(mode == LV_FS_MODE_WR)
{
/*Open a file for write*/
/*Add your code here*/
f = ... /*Add your code here*/
}
else if(mode == LV_FS_MODE_RD)
{
/*Open a file for read*/
/*Add your code here*/
f = ... /*Add your code here*/
}
else if(mode == (LV_FS_MODE_WR | LV_FS_MODE_RD))
{
/*Open a file for read and write*/
/*Add your code here*/
f = ... /*Add your code here*/
}
return res;
return file;
}
/**
* Close an opened file
* @param drv pointer to a driver where this function belongs
* @param file_p pointer to a file_t variable. (opened with lv_ufs_open)
* @return LV_FS_RES_OK: no error, the file is read
* any error from lv_fs_res_t enum
* @param drv pointer to a driver where this function belongs
* @param file_p pointer to a file_t variable. (opened with lv_ufs_open)
* @return LV_FS_RES_OK: no error or any error from @lv_fs_res_t enum
*/
static lv_fs_res_t fs_close (lv_fs_drv_t * drv, void * file_p)
{
@@ -174,13 +145,12 @@ static lv_fs_res_t fs_close (lv_fs_drv_t * drv, void * file_p)
/**
* Read data from an opened file
* @param drv pointer to a driver where this function belongs
* @param file_p pointer to a file_t variable.
* @param buf pointer to a memory block where to store the read data
* @param btr number of Bytes To Read
* @param br the real number of read bytes (Byte Read)
* @return LV_FS_RES_OK: no error, the file is read
* any error from lv_fs_res_t enum
* @param drv pointer to a driver where this function belongs
* @param file_p pointer to a file_t variable.
* @param buf pointer to a memory block where to store the read data
* @param btr number of Bytes To Read
* @param br the real number of read bytes (Byte Read)
* @return LV_FS_RES_OK: no error or any error from @lv_fs_res_t enum
*/
static lv_fs_res_t fs_read (lv_fs_drv_t * drv, void * file_p, void * buf, uint32_t btr, uint32_t * br)
{
@@ -193,12 +163,12 @@ static lv_fs_res_t fs_read (lv_fs_drv_t * drv, void * file_p, void * buf, uint32
/**
* Write into a file
* @param drv pointer to a driver where this function belongs
* @param file_p pointer to a file_t variable
* @param buf pointer to a buffer with the bytes to write
* @param btr Bytes To Write
* @param br the number of real written bytes (Bytes Written). NULL if unused.
* @return LV_FS_RES_OK or any error from lv_fs_res_t enum
* @param drv pointer to a driver where this function belongs
* @param file_p pointer to a file_t variable
* @param buf pointer to a buffer with the bytes to write
* @param btr Bytes To Write
* @param br the number of real written bytes (Bytes Written). NULL if unused.
* @return LV_FS_RES_OK: no error or any error from @lv_fs_res_t enum
*/
static lv_fs_res_t fs_write(lv_fs_drv_t * drv, void * file_p, const void * buf, uint32_t btw, uint32_t * bw)
{
@@ -211,29 +181,13 @@ static lv_fs_res_t fs_write(lv_fs_drv_t * drv, void * file_p, const void * buf,
/**
* Set the read write pointer. Also expand the file size if necessary.
* @param drv pointer to a driver where this function belongs
* @param file_p pointer to a file_t variable. (opened with lv_ufs_open )
* @param pos the new position of read write pointer
* @return LV_FS_RES_OK: no error, the file is read
* any error from lv_fs_res_t enum
* @param drv pointer to a driver where this function belongs
* @param file_p pointer to a file_t variable. (opened with lv_ufs_open )
* @param pos the new position of read write pointer
* @param whence tells from where to interpret the `pos`. See @lv_fs_whence_t
* @return LV_FS_RES_OK: no error or any error from @lv_fs_res_t enum
*/
static lv_fs_res_t fs_seek (lv_fs_drv_t * drv, void * file_p, uint32_t pos)
{
lv_fs_res_t res = LV_FS_RES_NOT_IMP;
/*Add your code here*/
return res;
}
/**
* Give the size of a file bytes
* @param drv pointer to a driver where this function belongs
* @param file_p pointer to a file_t variable
* @param size pointer to a variable to store the size
* @return LV_FS_RES_OK or any error from lv_fs_res_t enum
*/
static lv_fs_res_t fs_size (lv_fs_drv_t * drv, void * file_p, uint32_t * size_p)
static lv_fs_res_t fs_seek (lv_fs_drv_t * drv, void * file_p, uint32_t pos, lv_fs_whence_t whence)
{
lv_fs_res_t res = LV_FS_RES_NOT_IMP;
@@ -243,11 +197,10 @@ static lv_fs_res_t fs_size (lv_fs_drv_t * drv, void * file_p, uint32_t * size_p)
}
/**
* Give the position of the read write pointer
* @param drv pointer to a driver where this function belongs
* @param file_p pointer to a file_t variable.
* @param pos_p pointer to to store the result
* @return LV_FS_RES_OK: no error, the file is read
* any error from lv_fs_res_t enum
* @param drv pointer to a driver where this function belongs
* @param file_p pointer to a file_t variable.
* @param pos_p pointer to to store the result
* @return LV_FS_RES_OK: no error or any error from @lv_fs_res_t enum
*/
static lv_fs_res_t fs_tell (lv_fs_drv_t * drv, void * file_p, uint32_t * pos_p)
{
@@ -258,93 +211,27 @@ static lv_fs_res_t fs_tell (lv_fs_drv_t * drv, void * file_p, uint32_t * pos_p)
return res;
}
/**
* Delete a file
* @param drv pointer to a driver where this function belongs
* @param path path of the file to delete
* @return LV_FS_RES_OK or any error from lv_fs_res_t enum
*/
static lv_fs_res_t fs_remove (lv_fs_drv_t * drv, const char *path)
{
lv_fs_res_t res = LV_FS_RES_NOT_IMP;
/*Add your code here*/
return res;
}
/**
* Truncate the file size to the current position of the read write pointer
* @param drv pointer to a driver where this function belongs
* @param file_p pointer to an 'ufs_file_t' variable. (opened with lv_fs_open )
* @return LV_FS_RES_OK: no error, the file is read
* any error from lv_fs_res_t enum
*/
static lv_fs_res_t fs_trunc (lv_fs_drv_t * drv, void * file_p)
{
lv_fs_res_t res = LV_FS_RES_NOT_IMP;
/*Add your code here*/
return res;
}
/**
* Rename a file
* @param drv pointer to a driver where this function belongs
* @param oldname path to the file
* @param newname path with the new name
* @return LV_FS_RES_OK or any error from 'fs_res_t'
*/
static lv_fs_res_t fs_rename (lv_fs_drv_t * drv, const char * oldname, const char * newname)
{
lv_fs_res_t res = LV_FS_RES_NOT_IMP;
/*Add your code here*/
return res;
}
/**
* Get the free and total size of a driver in kB
* @param drv pointer to a driver where this function belongs
* @param letter the driver letter
* @param total_p pointer to store the total size [kB]
* @param free_p pointer to store the free size [kB]
* @return LV_FS_RES_OK or any error from lv_fs_res_t enum
*/
static lv_fs_res_t fs_free (lv_fs_drv_t * drv, uint32_t * total_p, uint32_t * free_p)
{
lv_fs_res_t res = LV_FS_RES_NOT_IMP;
/*Add your code here*/
return res;
}
/**
* Initialize a 'lv_fs_dir_t' variable for directory reading
* @param drv pointer to a driver where this function belongs
* @param rddir_p pointer to a 'lv_fs_dir_t' variable
* @param path path to a directory
* @return LV_FS_RES_OK or any error from lv_fs_res_t enum
* @param drv pointer to a driver where this function belongs
* @param path path to a directory
* @return pointer to the directory read descriptor or NULL on error
*/
static lv_fs_res_t fs_dir_open (lv_fs_drv_t * drv, void * rddir_p, const char *path)
static void * fs_dir_open (lv_fs_drv_t * drv, void * rddir_p, const char *path)
{
lv_fs_res_t res = LV_FS_RES_NOT_IMP;
void * dir = NULL;
/*Add your code here*/
return res;
dir = ... /*Add your code here*/
return dir;
}
/**
* Read the next filename form a directory.
* The name of the directories will begin with '/'
* @param drv pointer to a driver where this function belongs
* @param rddir_p pointer to an initialized 'lv_fs_dir_t' variable
* @param fn pointer to a buffer to store the filename
* @return LV_FS_RES_OK or any error from lv_fs_res_t enum
* @param drv pointer to a driver where this function belongs
* @param rddir_p pointer to an initialized 'lv_fs_dir_t' variable
* @param fn pointer to a buffer to store the filename
* @return LV_FS_RES_OK: no error or any error from @lv_fs_res_t enum
*/
static lv_fs_res_t fs_dir_read (lv_fs_drv_t * drv, void * rddir_p, char *fn)
{
@@ -357,9 +244,9 @@ static lv_fs_res_t fs_dir_read (lv_fs_drv_t * drv, void * rddir_p, char *fn)
/**
* Close the directory reading
* @param drv pointer to a driver where this function belongs
* @param rddir_p pointer to an initialized 'lv_fs_dir_t' variable
* @return LV_FS_RES_OK or any error from lv_fs_res_t enum
* @param drv pointer to a driver where this function belongs
* @param rddir_p pointer to an initialized 'lv_fs_dir_t' variable
* @return LV_FS_RES_OK: no error or any error from @lv_fs_res_t enum
*/
static lv_fs_res_t fs_dir_close (lv_fs_drv_t * drv, void * rddir_p)
{

View File

@@ -10,6 +10,7 @@
* INCLUDES
*********************/
#include "lv_port_indev_template.h"
#include "../../lvgl.h"
/*********************
* DEFINES
@@ -38,7 +39,7 @@ static void keypad_read(lv_indev_drv_t * indev_drv, lv_indev_data_t * data);
static uint32_t keypad_get_key(void);
static void encoder_init(void);
static bool encoder_read(lv_indev_drv_t * indev_drv, lv_indev_data_t * data);
static void encoder_read(lv_indev_drv_t * indev_drv, lv_indev_data_t * data);
static void encoder_handler(void);
static void button_init(void);
@@ -109,7 +110,7 @@ void lv_port_indev_init(void)
indev_mouse = lv_indev_drv_register(&indev_drv);
/*Set cursor. For simplicity set a HOME symbol now.*/
lv_obj_t * mouse_cursor = lv_img_create(lv_disp_get_scr_act(NULL), NULL);
lv_obj_t * mouse_cursor = lv_img_create(lv_scr_act());
lv_img_set_src(mouse_cursor, LV_SYMBOL_HOME);
lv_indev_set_cursor(indev_mouse, mouse_cursor);

View File

@@ -113,6 +113,7 @@ void lv_example_table_1(void);
void lv_example_table_2(void);
void lv_example_tabview_1(void);
void lv_example_tabview_2(void);
void lv_example_textarea_1(void);
void lv_example_textarea_2(void);

View File

@@ -7,6 +7,12 @@ Simple Tabview
.. lv_example:: widgets/tabview/lv_example_tabview_1
:language: c
Tabs on the left, styling and no scrolling
"""""""""""""""""""""""""""""""""""""""""""""
.. lv_example:: widgets/tabview/lv_example_tabview_2
:language: c
MicroPython
^^^^^^^^^^^

View File

@@ -0,0 +1,56 @@
#include "../../lv_examples.h"
#if LV_USE_TABVIEW && LV_BUILD_EXAMPLES
static void scroll_begin_event(lv_event_t * e)
{
/*Disable the scroll animations. Triggered when a tab button is clicked */
if(lv_event_get_code(e) == LV_EVENT_SCROLL_BEGIN) {
lv_anim_t * a = lv_event_get_param(e);
if(a) a->time = 0;
}
}
void lv_example_tabview_2(void)
{
/*Create a Tab view object*/
lv_obj_t *tabview;
tabview = lv_tabview_create(lv_scr_act(), LV_DIR_LEFT, 80);
lv_obj_add_event_cb(lv_tabview_get_content(tabview), scroll_begin_event, LV_EVENT_SCROLL_BEGIN, NULL);
lv_obj_set_style_bg_color(tabview, lv_palette_lighten(LV_PALETTE_RED, 2), 0);
lv_obj_t * tab_btns = lv_tabview_get_tab_btns(tabview);
lv_obj_set_style_bg_color(tab_btns, lv_palette_darken(LV_PALETTE_GREY, 3), 0);
lv_obj_set_style_text_color(tab_btns, lv_palette_lighten(LV_PALETTE_GREY, 5), 0);
lv_obj_set_style_border_side(tab_btns, LV_BORDER_SIDE_RIGHT, LV_PART_ITEMS | LV_STATE_CHECKED);
/*Add 3 tabs (the tabs are page (lv_page) and can be scrolled*/
lv_obj_t *tab1 = lv_tabview_add_tab(tabview, "Tab 1");
lv_obj_t *tab2 = lv_tabview_add_tab(tabview, "Tab 2");
lv_obj_t *tab3 = lv_tabview_add_tab(tabview, "Tab 3");
lv_obj_t *tab4 = lv_tabview_add_tab(tabview, "Tab 4");
lv_obj_t *tab5 = lv_tabview_add_tab(tabview, "Tab 5");
lv_obj_set_style_bg_color(tab2, lv_palette_lighten(LV_PALETTE_AMBER, 3), 0);
lv_obj_set_style_bg_opa(tab2, LV_OPA_COVER, 0);
/*Add content to the tabs*/
lv_obj_t * label = lv_label_create(tab1);
lv_label_set_text(label, "First tab");
label = lv_label_create(tab2);
lv_label_set_text(label, "Second tab");
label = lv_label_create(tab3);
lv_label_set_text(label, "Third tab");
label = lv_label_create(tab4);
lv_label_set_text(label, "Forth tab");
label = lv_label_create(tab5);
lv_label_set_text(label, "Fifth tab");
lv_obj_clear_flag(lv_tabview_get_content(tabview), LV_OBJ_FLAG_SCROLLABLE);
}
#endif

View File

@@ -1,6 +1,6 @@
{
"name": "lvgl",
"version": "8.0.0",
"version": "8.0.2",
"keywords": "graphics, gui, embedded, tft, lvgl",
"description": "Graphics library to create embedded GUI with easy-to-use graphical elements, beautiful visual effects and low memory footprint. It offers anti-aliasing, opacity, and animations using only one frame buffer.",
"repository": {

View File

@@ -1,5 +1,5 @@
name=lvgl
version=8.0.0
version=8.0.2
author=kisvegabor
maintainer=kisvegabor,embeddedt,pete-pjb
sentence=Full-featured Graphics Library for Embedded Systems

View File

@@ -1,6 +1,6 @@
/**
* @file lv_conf.h
* Configuration file for v8.0.0
* Configuration file for v8.0.2
*/
/*
@@ -27,7 +27,7 @@
#define LV_COLOR_16_SWAP 0
/*Enable more complex drawing routines to manage screens transparency.
*Can be used if the UI is above an other layer, e.g. an OSD menu or video player.
*Can be used if the UI is above another layer, e.g. an OSD menu or video player.
*Requires `LV_COLOR_DEPTH = 32` colors and the screen's `bg_opa` should be set to non LV_OPA_COVER value*/
#define LV_COLOR_SCREEN_TRANSP 0
@@ -122,7 +122,7 @@ e.g. "stm32f769xx.h" or "stm32f429xx.h"*/
#define LV_USE_GPU_NXP_PXP 0
#if LV_USE_GPU_NXP_PXP
/*1: Add default bare metal and FreeRTOS interrupt handling routines for PXP (lv_gpu_nxp_pxp_osa.c)
* and call lv_gpu_nxp_pxp_init() automatically during lv_init(). Note that symbol FSL_RTOS_FREE_RTOS
* and call lv_gpu_nxp_pxp_init() automatically during lv_init(). Note that symbol SDK_OS_FREE_RTOS
* has to be defined in order to use FreeRTOS OSA, otherwise bare-metal implementation is selected.
*0: lv_gpu_nxp_pxp_init() has to be called manually before lv_init()
*/

2
lvgl.h
View File

@@ -15,7 +15,7 @@ extern "C" {
***************************/
#define LVGL_VERSION_MAJOR 8
#define LVGL_VERSION_MINOR 0
#define LVGL_VERSION_PATCH 0
#define LVGL_VERSION_PATCH 2
#define LVGL_VERSION_INFO ""
/*********************

View File

@@ -288,6 +288,16 @@ uint32_t lv_event_get_key(lv_event_t * e)
}
}
lv_anim_t * lv_event_get_scroll_anim(lv_event_t * e)
{
if(e->code == LV_EVENT_SCROLL_BEGIN) {
return lv_event_get_param(e);
} else {
LV_LOG_WARN("Not interpreted with this event code");
return 0;
}
}
void lv_event_set_ext_draw_size(lv_event_t * e, lv_coord_t size)
{
if(e->code == LV_EVENT_REFR_EXT_DRAW_SIZE) {

View File

@@ -263,6 +263,13 @@ const lv_area_t * lv_event_get_old_size(lv_event_t * e);
*/
uint32_t lv_event_get_key(lv_event_t * e);
/**
* Get the animation descriptor of a scrolling. Can be used in `LV_EVENT_SCROLL_BEGIN`
* @param e pointer to an event
* @return the animation that will scroll the object. (can be modified as required)
*/
lv_anim_t * lv_event_get_scroll_anim(lv_event_t * e);
/**
* Set the new extra draw size. Can be used in `LV_EVENT_REFR_EXT_DRAW_SIZE`
* @param e pointer to an event

View File

@@ -206,15 +206,13 @@ void lv_group_focus_obj(lv_obj_t * obj)
if(g->frozen != 0) return;
if(g->obj_focus != NULL && obj == *g->obj_focus) return;
/*On defocus edit mode must be leaved*/
lv_group_set_editing(g, false);
lv_obj_t ** i;
_LV_LL_READ(&g->obj_ll, i) {
if(*i == obj) {
if(g->obj_focus != NULL) {
if(g->obj_focus != NULL && obj != *g->obj_focus) { /*Do not defocus if the same object needs to be focused again*/
lv_res_t res = lv_event_send(*g->obj_focus, LV_EVENT_DEFOCUSED, get_indev(g));
if(res != LV_RES_OK) return;
lv_obj_invalidate(*g->obj_focus);

View File

@@ -55,8 +55,7 @@ void _lv_indev_scroll_handler(_lv_indev_proc_t * proc)
init_scroll_limits(proc);
lv_indev_t * indev_act = lv_indev_get_act();
lv_event_send(scroll_obj, LV_EVENT_SCROLL_BEGIN, indev_act);
lv_event_send(scroll_obj, LV_EVENT_SCROLL_BEGIN, NULL);
if(proc->reset_query) return;
}

View File

@@ -30,6 +30,11 @@
#include "../gpu/lv_gpu_stm32_dma2d.h"
#endif
#if LV_USE_GPU_NXP_PXP && LV_USE_GPU_NXP_PXP_AUTO_INIT
#include "../gpu/lv_gpu_nxp_pxp.h"
#include "../gpu/lv_gpu_nxp_pxp_osa.h"
#endif
/*********************
* DEFINES
*********************/
@@ -105,6 +110,13 @@ void lv_init(void)
lv_gpu_stm32_dma2d_init();
#endif
#if LV_USE_GPU_NXP_PXP && LV_USE_GPU_NXP_PXP_AUTO_INIT
if(lv_gpu_nxp_pxp_init(&pxp_default_cfg) != LV_RES_OK) {
LV_LOG_ERROR("PXP init error. STOP.\n");
for(; ;) ;
}
#endif
_lv_obj_style_init();
_lv_ll_init(&LV_GC_ROOT(_lv_disp_ll), sizeof(lv_disp_t));
_lv_ll_init(&LV_GC_ROOT(_lv_indev_ll), sizeof(lv_indev_t));
@@ -385,6 +397,20 @@ static void lv_obj_destructor(const lv_obj_class_t * class_p, lv_obj_t * obj)
{
LV_UNUSED(class_p);
_lv_event_mark_deleted(obj);
/*Remove all style*/
lv_obj_enable_style_refresh(false); /*No need to refresh the style because the object will be deleted*/
lv_obj_remove_style_all(obj);
lv_obj_enable_style_refresh(true);
/*Remove the animations from this object*/
lv_anim_del(obj, NULL);
/*Delete from the group*/
lv_group_t * group = lv_obj_get_group(obj);
if(group) lv_group_remove_obj(obj);
if(obj->spec_attr) {
if(obj->spec_attr->children) {
lv_mem_free(obj->spec_attr->children);
@@ -398,7 +424,6 @@ static void lv_obj_destructor(const lv_obj_class_t * class_p, lv_obj_t * obj)
lv_mem_free(obj->spec_attr);
obj->spec_attr = NULL;
}
}
static void lv_obj_draw(lv_event_t * e)
@@ -609,6 +634,13 @@ static void lv_obj_event(const lv_obj_class_t * class_p, lv_event_t * e)
else if(code == LV_EVENT_PRESS_LOST) {
lv_obj_clear_state(obj, LV_STATE_PRESSED);
}
else if(code == LV_EVENT_STYLE_CHANGED) {
uint32_t child_cnt = lv_obj_get_child_cnt(obj);
for(uint32_t i = 0; i < child_cnt; i++) {
lv_obj_t * child = obj->spec_attr->children[i];
lv_obj_mark_layout_as_dirty(child);
}
}
else if(code == LV_EVENT_KEY) {
if(lv_obj_has_flag(obj, LV_OBJ_FLAG_CHECKABLE)) {
char c = *((char *)lv_event_get_param(e));
@@ -618,8 +650,12 @@ static void lv_obj_event(const lv_obj_class_t * class_p, lv_event_t * e)
else if(c == LV_KEY_LEFT || c == LV_KEY_DOWN) {
lv_obj_clear_state(obj, LV_STATE_CHECKED);
}
lv_res_t res = lv_event_send(obj, LV_EVENT_VALUE_CHANGED, NULL);
if(res != LV_RES_OK) return;
/*With Enter LV_EVENT_RELEASED will send VALUE_CHANGE event*/
if(c != LV_KEY_ENTER) {
lv_res_t res = lv_event_send(obj, LV_EVENT_VALUE_CHANGED, NULL);
if(res != LV_RES_OK) return;
}
}
}
else if(code == LV_EVENT_FOCUSED) {
@@ -631,7 +667,12 @@ static void lv_obj_event(const lv_obj_class_t * class_p, lv_event_t * e)
editing = lv_group_get_editing(lv_obj_get_group(obj));
lv_state_t state = LV_STATE_FOCUSED;
/* Use the indev for then indev handler.
* But if the obj was focused manually it returns NULL so try to
* use the indev from the event*/
lv_indev_t * indev = lv_indev_get_act();
if(indev == NULL) indev = lv_event_get_indev(e);
lv_indev_type_t indev_type = lv_indev_get_type(indev);
if(indev_type == LV_INDEV_TYPE_KEYPAD || indev_type == LV_INDEV_TYPE_ENCODER) state |= LV_STATE_FOCUS_KEY;
if(editing) {
@@ -770,7 +811,6 @@ static void lv_obj_set_state(lv_obj_t * obj, lv_state_t new_state)
static bool obj_valid_child(const lv_obj_t * parent, const lv_obj_t * obj_to_find)
{
/*Check all children of `parent`*/
uint32_t child_cnt = 0;
if(parent->spec_attr) child_cnt = parent->spec_attr->child_cnt;

View File

@@ -71,7 +71,7 @@ enum {
LV_PART_INDICATOR = 0x020000, /**< Indicator, e.g. for slider, bar, switch, or the tick box of the checkbox*/
LV_PART_KNOB = 0x030000, /**< Like handle to grab to adjust the value*/
LV_PART_SELECTED = 0x040000, /**< Indicate the currently selected option or section*/
LV_PART_ITEMS = 0x050000, /**< Used if the widget has multiple similar elements (e.g. tabel cells)*/
LV_PART_ITEMS = 0x050000, /**< Used if the widget has multiple similar elements (e.g. table cells)*/
LV_PART_TICKS = 0x060000, /**< Ticks on scale e.g. for a chart or meter*/
LV_PART_CURSOR = 0x070000, /**< Mark a specific place e.g. for text area's cursor or on a chart*/

View File

@@ -112,7 +112,6 @@ void lv_obj_class_init_obj(lv_obj_t * obj)
lv_group_t * def_group = lv_group_get_default();
if(def_group && lv_obj_is_group_def(obj)) {
lv_group_add_obj(def_group, obj);
}
@@ -127,7 +126,7 @@ void lv_obj_class_init_obj(lv_obj_t * obj)
}
}
void _lv_obj_destructor(lv_obj_t * obj)
void _lv_obj_destruct(lv_obj_t * obj)
{
if(obj->class_p->destructor_cb) obj->class_p->destructor_cb(obj->class_p, obj);
@@ -136,7 +135,7 @@ void _lv_obj_destructor(lv_obj_t * obj)
obj->class_p = obj->class_p->base_class;
/*Call the base class's destructor too*/
_lv_obj_destructor(obj);
_lv_obj_destruct(obj);
}
}
@@ -163,6 +162,7 @@ bool lv_obj_is_group_def(lv_obj_t * obj)
return class_p->group_def == LV_OBJ_CLASS_GROUP_DEF_TRUE ? true : false;
}
/**********************
* STATIC FUNCTIONS
**********************/

View File

@@ -75,7 +75,7 @@ struct _lv_obj_t * lv_obj_class_create_obj(const struct _lv_obj_class_t * class_
void lv_obj_class_init_obj(struct _lv_obj_t * obj);
void _lv_obj_destructor(struct _lv_obj_t * obj);
void _lv_obj_destruct(struct _lv_obj_t * obj);
bool lv_obj_is_editable(struct _lv_obj_t * obj);

View File

@@ -83,7 +83,6 @@ void lv_obj_set_y(lv_obj_t * obj, lv_coord_t y)
bool lv_obj_refr_size(lv_obj_t * obj)
{
LV_ASSERT_OBJ(obj, MY_CLASS);
/*If the width or height is set by a layout do not modify them*/
@@ -187,34 +186,7 @@ bool lv_obj_refr_size(lv_obj_t * obj)
/*Invalidate the new area*/
lv_obj_invalidate(obj);
/*Be sure the bottom side is not remains scrolled in*/
/*With snapping the content can't be scrolled in*/
if(lv_obj_get_scroll_snap_y(obj) == LV_SCROLL_SNAP_NONE) {
lv_coord_t st = lv_obj_get_scroll_top(obj);
lv_coord_t sb = lv_obj_get_scroll_bottom(obj);
if(sb < 0 && st > 0) {
sb = LV_MIN(st, -sb);
lv_obj_scroll_by(obj, 0, sb, LV_ANIM_OFF);
}
}
if(lv_obj_get_scroll_snap_x(obj) == LV_SCROLL_SNAP_NONE) {
lv_coord_t sl = lv_obj_get_scroll_left(obj);
lv_coord_t sr = lv_obj_get_scroll_right(obj);
if(lv_obj_get_style_base_dir(obj, LV_PART_MAIN) != LV_BASE_DIR_RTL) {
/*Be sure the left side is not remains scrolled in*/
if(sr < 0 && sl > 0) {
sr = LV_MIN(sl, -sr);
lv_obj_scroll_by(obj, sr, 0, LV_ANIM_OFF);
}
} else {
/*Be sure the right side is not remains scrolled in*/
if(sl < 0 && sr > 0) {
sr = LV_MIN(sr, -sl);
lv_obj_scroll_by(obj, sl, 0, LV_ANIM_OFF);
}
}
}
lv_obj_readjust_scroll(obj, LV_ANIM_OFF);
/*If the object was out of the parent invalidate the new scrollbar area too.
*If it wasn't out of the parent but out now, also invalidate the srollbars*/
@@ -369,123 +341,127 @@ void lv_obj_align_to(lv_obj_t * obj, const lv_obj_t * base, lv_align_t align, lv
lv_coord_t x = 0;
lv_coord_t y = 0;
lv_obj_t * parent = lv_obj_get_parent(obj);
lv_coord_t border_width = lv_obj_get_style_border_width(parent, LV_PART_MAIN);
lv_coord_t pleft = lv_obj_get_style_pad_left(parent, LV_PART_MAIN) + border_width;
lv_coord_t ptop = lv_obj_get_style_pad_top(parent, LV_PART_MAIN) + border_width;
lv_obj_t * parent = lv_obj_get_parent(obj);
lv_coord_t pborder = lv_obj_get_style_border_width(parent, LV_PART_MAIN);
lv_coord_t pleft = lv_obj_get_style_pad_left(parent, LV_PART_MAIN) + pborder;
lv_coord_t ptop = lv_obj_get_style_pad_top(parent, LV_PART_MAIN) + pborder;
lv_coord_t bborder = lv_obj_get_style_border_width(base, LV_PART_MAIN);
lv_coord_t bleft = lv_obj_get_style_pad_left(base, LV_PART_MAIN) + bborder;
lv_coord_t btop = lv_obj_get_style_pad_top(base, LV_PART_MAIN) + bborder;
if(align == LV_ALIGN_DEFAULT) {
if(lv_obj_get_style_base_dir(parent, LV_PART_MAIN) == LV_BASE_DIR_RTL) align = LV_ALIGN_TOP_RIGHT;
if(lv_obj_get_style_base_dir(base, LV_PART_MAIN) == LV_BASE_DIR_RTL) align = LV_ALIGN_TOP_RIGHT;
else align = LV_ALIGN_TOP_LEFT;
}
switch(align) {
case LV_ALIGN_CENTER:
x = lv_obj_get_content_width(base) / 2 - lv_obj_get_width(obj) / 2;
y = lv_obj_get_content_height(base) / 2 - lv_obj_get_height(obj) / 2;
x = lv_obj_get_content_width(base) / 2 - lv_obj_get_width(obj) / 2 + bleft;
y = lv_obj_get_content_height(base) / 2 - lv_obj_get_height(obj) / 2 + btop;
break;
case LV_ALIGN_TOP_LEFT:
x = 0;
y = 0;
x = bleft;
y = btop;
break;
case LV_ALIGN_TOP_MID:
x = lv_obj_get_content_width(base) / 2 - lv_obj_get_width(obj) / 2;
y = 0;
x = lv_obj_get_content_width(base) / 2 - lv_obj_get_width(obj) / 2 + bleft;
y = btop;
break;
case LV_ALIGN_TOP_RIGHT:
x = lv_obj_get_content_width(base) - lv_obj_get_width(obj);
y = 0;
x = lv_obj_get_content_width(base) - lv_obj_get_width(obj) + bleft;
y = btop;
break;
case LV_ALIGN_BOTTOM_LEFT:
x = 0;
y = lv_obj_get_content_height(base) - lv_obj_get_height(obj);
x = bleft;
y = lv_obj_get_content_height(base) - lv_obj_get_height(obj) + btop;
break;
case LV_ALIGN_BOTTOM_MID:
x = lv_obj_get_content_width(base) / 2 - lv_obj_get_width(obj) / 2;
y = lv_obj_get_content_height(base) - lv_obj_get_height(obj);
x = lv_obj_get_content_width(base) / 2 - lv_obj_get_width(obj) / 2 + bleft;
y = lv_obj_get_content_height(base) - lv_obj_get_height(obj) + btop;
break;
case LV_ALIGN_BOTTOM_RIGHT:
x = lv_obj_get_content_width(base) - lv_obj_get_width(obj);
y = lv_obj_get_content_height(base) - lv_obj_get_height(obj);
x = lv_obj_get_content_width(base) - lv_obj_get_width(obj) + bleft;
y = lv_obj_get_content_height(base) - lv_obj_get_height(obj) + btop;
break;
case LV_ALIGN_LEFT_MID:
x = 0;
y = lv_obj_get_content_height(base) / 2 - lv_obj_get_height(obj) / 2;
x = bleft;
y = lv_obj_get_content_height(base) / 2 - lv_obj_get_height(obj) / 2 + btop;
break;
case LV_ALIGN_RIGHT_MID:
x = lv_obj_get_content_width(base) - lv_obj_get_width(obj);
y = lv_obj_get_content_height(base) / 2 - lv_obj_get_height(obj) / 2;
x = lv_obj_get_content_width(base) - lv_obj_get_width(obj) + bleft;
y = lv_obj_get_content_height(base) / 2 - lv_obj_get_height(obj) / 2 + btop;
break;
case LV_ALIGN_OUT_TOP_LEFT:
x = -pleft;
y = -lv_obj_get_height(obj) - ptop;
x = 0;
y = -lv_obj_get_height(obj);
break;
case LV_ALIGN_OUT_TOP_MID:
x = lv_obj_get_width(base) / 2 - lv_obj_get_width(obj) / 2 - pleft;
y = -lv_obj_get_height(obj) - ptop;
x = lv_obj_get_width(base) / 2 - lv_obj_get_width(obj) / 2;
y = -lv_obj_get_height(obj);
break;
case LV_ALIGN_OUT_TOP_RIGHT:
x = lv_obj_get_width(base) - lv_obj_get_width(obj) - pleft;
y = -lv_obj_get_height(obj) - ptop;
x = lv_obj_get_width(base) - lv_obj_get_width(obj);
y = -lv_obj_get_height(obj);
break;
case LV_ALIGN_OUT_BOTTOM_LEFT:
x = - pleft;
y = lv_obj_get_height(base) - ptop;
x = 0;
y = lv_obj_get_height(base);
break;
case LV_ALIGN_OUT_BOTTOM_MID:
x = lv_obj_get_width(base) / 2 - lv_obj_get_width(obj) / 2 - pleft;
y = lv_obj_get_height(base) - ptop;
x = lv_obj_get_width(base) / 2 - lv_obj_get_width(obj) / 2;
y = lv_obj_get_height(base);
break;
case LV_ALIGN_OUT_BOTTOM_RIGHT:
x = lv_obj_get_width(base) - lv_obj_get_width(obj) - pleft;
y = lv_obj_get_height(base) - ptop;
x = lv_obj_get_width(base) - lv_obj_get_width(obj);
y = lv_obj_get_height(base);
break;
case LV_ALIGN_OUT_LEFT_TOP:
x = -lv_obj_get_width(obj) - pleft;
y = - ptop;
x = -lv_obj_get_width(obj);
y = 0;
break;
case LV_ALIGN_OUT_LEFT_MID:
x = -lv_obj_get_width(obj) - pleft;
y = lv_obj_get_height(base) / 2 - lv_obj_get_height(obj) / 2 - ptop;
x = -lv_obj_get_width(obj);
y = lv_obj_get_height(base) / 2 - lv_obj_get_height(obj) / 2;
break;
case LV_ALIGN_OUT_LEFT_BOTTOM:
x = -lv_obj_get_width(obj) - pleft;
y = lv_obj_get_height(base) - lv_obj_get_height(obj) - ptop;
x = -lv_obj_get_width(obj);
y = lv_obj_get_height(base) - lv_obj_get_height(obj);
break;
case LV_ALIGN_OUT_RIGHT_TOP:
x = lv_obj_get_width(base) - pleft;
y = - ptop;
x = lv_obj_get_width(base);
y = 0;
break;
case LV_ALIGN_OUT_RIGHT_MID:
x = lv_obj_get_width(base) - pleft;
y = lv_obj_get_height(base) / 2 - lv_obj_get_height(obj) / 2 - ptop;
x = lv_obj_get_width(base);
y = lv_obj_get_height(base) / 2 - lv_obj_get_height(obj) / 2;
break;
case LV_ALIGN_OUT_RIGHT_BOTTOM:
x = lv_obj_get_width(base) - pleft;
y = lv_obj_get_height(base) - lv_obj_get_height(obj) - ptop;
x = lv_obj_get_width(base);
y = lv_obj_get_height(base) - lv_obj_get_height(obj);
break;
}
x += x_ofs + base->coords.x1 - parent->coords.x1 + lv_obj_get_scroll_left(parent);
y += y_ofs + base->coords.y1 - parent->coords.y1 + lv_obj_get_scroll_top(parent);
x += x_ofs + base->coords.x1 - parent->coords.x1 + lv_obj_get_scroll_left(parent) - pleft;
y += y_ofs + base->coords.y1 - parent->coords.y1 + lv_obj_get_scroll_top(parent) - ptop;
lv_obj_set_style_align(obj, LV_ALIGN_TOP_LEFT, 0);
lv_obj_set_pos(obj, x, y);
@@ -577,8 +553,8 @@ lv_coord_t lv_obj_get_content_height(const lv_obj_t * obj)
{
LV_ASSERT_OBJ(obj, MY_CLASS);
lv_coord_t top = lv_obj_get_style_pad_top((lv_obj_t *)obj, LV_PART_MAIN);
lv_coord_t bottom = lv_obj_get_style_pad_bottom((lv_obj_t *)obj, LV_PART_MAIN);
lv_coord_t top = lv_obj_get_style_pad_top(obj, LV_PART_MAIN);
lv_coord_t bottom = lv_obj_get_style_pad_bottom(obj, LV_PART_MAIN);
lv_coord_t border_width = lv_obj_get_style_border_width(obj, LV_PART_MAIN);
return lv_obj_get_height(obj) - top - bottom - 2 * border_width;

View File

@@ -222,7 +222,9 @@ lv_coord_t lv_obj_get_scroll_right(lv_obj_t * obj)
lv_coord_t pad_left = lv_obj_get_style_pad_left(obj, LV_PART_MAIN);
lv_coord_t border_width = lv_obj_get_style_border_width(obj, LV_PART_MAIN);
child_res -= (obj->coords.x2 - pad_right - border_width);
if(child_res != LV_COORD_MIN) {
child_res -= (obj->coords.x2 - pad_right - border_width);
}
lv_coord_t self_w;
self_w = lv_obj_get_self_width(obj);
@@ -256,10 +258,6 @@ void lv_obj_scroll_by(lv_obj_t * obj, lv_coord_t x, lv_coord_t y, lv_anim_enable
lv_anim_set_ready_cb(&a, scroll_anim_ready_cb);
if(x) {
lv_res_t res;
res = lv_event_send(obj, LV_EVENT_SCROLL_BEGIN, NULL);
if(res != LV_RES_OK) return;
uint32_t t = lv_anim_speed_to_time((lv_disp_get_hor_res(d) * 2) >> 2, 0, x);
if(t < SCROLL_ANIM_TIME_MIN) t = SCROLL_ANIM_TIME_MIN;
if(t > SCROLL_ANIM_TIME_MAX) t = SCROLL_ANIM_TIME_MAX;
@@ -268,14 +266,14 @@ void lv_obj_scroll_by(lv_obj_t * obj, lv_coord_t x, lv_coord_t y, lv_anim_enable
lv_anim_set_values(&a, -sx, -sx + x);
lv_anim_set_exec_cb(&a, scroll_x_anim);
lv_anim_set_path_cb(&a, lv_anim_path_ease_out);
lv_res_t res;
res = lv_event_send(obj, LV_EVENT_SCROLL_BEGIN, &a);
if(res != LV_RES_OK) return;
lv_anim_start(&a);
}
if(y) {
lv_res_t res;
res = lv_event_send(obj, LV_EVENT_SCROLL_BEGIN, NULL);
if(res != LV_RES_OK) return;
uint32_t t = lv_anim_speed_to_time((lv_disp_get_ver_res(d) * 2) >> 2, 0, y);
if(t < SCROLL_ANIM_TIME_MIN) t = SCROLL_ANIM_TIME_MIN;
if(t > SCROLL_ANIM_TIME_MAX) t = SCROLL_ANIM_TIME_MAX;
@@ -284,13 +282,22 @@ void lv_obj_scroll_by(lv_obj_t * obj, lv_coord_t x, lv_coord_t y, lv_anim_enable
lv_anim_set_values(&a, -sy, -sy + y);
lv_anim_set_exec_cb(&a, scroll_y_anim);
lv_anim_set_path_cb(&a, lv_anim_path_ease_out);
lv_res_t res;
res = lv_event_send(obj, LV_EVENT_SCROLL_BEGIN, &a);
if(res != LV_RES_OK) return;
lv_anim_start(&a);
}
} else {
/*Remove pending animations*/
lv_anim_del(obj, scroll_y_anim);
lv_anim_del(obj, scroll_x_anim);
bool y_del = lv_anim_del(obj, scroll_y_anim);
bool x_del = lv_anim_del(obj, scroll_x_anim);
scroll_by_raw(obj, x, y);
if(y_del || x_del) {
lv_res_t res;
res = lv_event_send(obj, LV_EVENT_SCROLL_END, NULL);
if(res != LV_RES_OK) return;
}
}
}
@@ -537,6 +544,38 @@ void lv_obj_scrollbar_invalidate(lv_obj_t * obj)
if(lv_area_get_size(&ver_area) > 0) lv_obj_invalidate_area(obj, &ver_area);
}
void lv_obj_readjust_scroll(lv_obj_t * obj, lv_anim_enable_t anim_en)
{
/*Be sure the bottom side is not remains scrolled in*/
/*With snapping the content can't be scrolled in*/
if(lv_obj_get_scroll_snap_y(obj) == LV_SCROLL_SNAP_NONE) {
lv_coord_t st = lv_obj_get_scroll_top(obj);
lv_coord_t sb = lv_obj_get_scroll_bottom(obj);
if(sb < 0 && st > 0) {
sb = LV_MIN(st, -sb);
lv_obj_scroll_by(obj, 0, sb, anim_en);
}
}
if(lv_obj_get_scroll_snap_x(obj) == LV_SCROLL_SNAP_NONE) {
lv_coord_t sl = lv_obj_get_scroll_left(obj);
lv_coord_t sr = lv_obj_get_scroll_right(obj);
if(lv_obj_get_style_base_dir(obj, LV_PART_MAIN) != LV_BASE_DIR_RTL) {
/*Be sure the left side is not remains scrolled in*/
if(sr < 0 && sl > 0) {
sr = LV_MIN(sl, -sr);
lv_obj_scroll_by(obj, sr, 0, anim_en);
}
} else {
/*Be sure the right side is not remains scrolled in*/
if(sl < 0 && sr > 0) {
sr = LV_MIN(sr, -sl);
lv_obj_scroll_by(obj, sl, 0, anim_en);
}
}
}
}
/**********************
* STATIC FUNCTIONS
**********************/
@@ -664,8 +703,13 @@ static void scroll_area_into_view(const lv_area_t * area, lv_obj_t * child, lv_p
}
/*Remove any pending scroll animations.*/
lv_anim_del(parent, scroll_x_anim);
lv_anim_del(parent, scroll_y_anim);
bool y_del = lv_anim_del(parent, scroll_y_anim);
bool x_del = lv_anim_del(parent, scroll_x_anim);
if(y_del || x_del) {
lv_res_t res;
res = lv_event_send(parent, LV_EVENT_SCROLL_END, NULL);
if(res != LV_RES_OK) return;
}
if((scroll_dir & LV_DIR_LEFT) == 0 && x_scroll < 0) x_scroll = 0;
if((scroll_dir & LV_DIR_RIGHT) == 0 && x_scroll > 0) x_scroll = 0;

View File

@@ -40,9 +40,9 @@ typedef uint8_t lv_scrollbar_mode_t;
/** Scroll span align options. Tells where to align the snapable children when scroll stops.*/
enum {
LV_SCROLL_SNAP_NONE, /**< Do not align, leave where it is*/
LV_SCROLL_SNAP_START, /**< Align to to the left/top*/
LV_SCROLL_SNAP_END, /**< Align to to the right/bottom*/
LV_SCROLL_SNAP_CENTER /**< Align to to the center*/
LV_SCROLL_SNAP_START, /**< Align to the left/top*/
LV_SCROLL_SNAP_END, /**< Align to the right/bottom*/
LV_SCROLL_SNAP_CENTER /**< Align to the center*/
};
typedef uint8_t lv_scroll_snap_t;
@@ -71,14 +71,14 @@ void lv_obj_set_scroll_dir(struct _lv_obj_t * obj, lv_dir_t dir);
/**
* Set where to snap the children when scrolling ends horizontally
* @param obj pointer to an object
* @param align the snap align to set from `lv_snap_align_t`
* @param align the snap align to set from `lv_scroll_snap_t`
*/
void lv_obj_set_scroll_snap_x(struct _lv_obj_t * obj, lv_scroll_snap_t align);
/**
* Set where to snap the children when scrolling ends vertically
* @param obj pointer to an object
* @param align the snap align to set from `lv_snap_align_t`
* @param align the snap align to set from `lv_scroll_snap_t`
*/
void lv_obj_set_scroll_snap_y(struct _lv_obj_t * obj, lv_scroll_snap_t align);
@@ -89,7 +89,7 @@ void lv_obj_set_scroll_snap_y(struct _lv_obj_t * obj, lv_scroll_snap_t align);
/**
* Get the current scroll mode (when to hide the scrollbars)
* @param obj pointer to an object
* @return the current scroll mode from `lv_scroll_mode_t`
* @return the current scroll mode from `lv_scrollbar_mode_t`
*/
lv_scrollbar_mode_t lv_obj_get_scrollbar_mode(const struct _lv_obj_t * obj);
@@ -103,14 +103,14 @@ lv_dir_t lv_obj_get_scroll_dir(const struct _lv_obj_t * obj);
/**
* Get where to snap the children when scrolling ends horizontally
* @param obj pointer to an object
* @return the current snap align from `lv_snap_align_t`
* @return the current snap align from `lv_scroll_snap_t`
*/
lv_scroll_snap_t lv_obj_get_scroll_snap_x(const struct _lv_obj_t * obj);
/**
* Get where to snap the children when scrolling ends vertically
* @param obj pointer to an object
* @return the current snap align from `lv_snap_align_t`
* @return the current snap align from `lv_scroll_snap_t`
*/
lv_scroll_snap_t lv_obj_get_scroll_snap_y(const struct _lv_obj_t * obj);
@@ -254,9 +254,9 @@ void lv_obj_update_snap(struct _lv_obj_t * obj, lv_anim_enable_t anim_en);
/**
* Get the area of the scrollbars
* @param obj pointer to an object
* @param hor_area pointer to store the area of the horizontal scrollbar
* @param ver_area pointer to store the area of the vertical scrollbar
* @param obj pointer to an object
* @param hor pointer to store the area of the horizontal scrollbar
* @param ver pointer to store the area of the vertical scrollbar
*/
void lv_obj_get_scrollbar_area(struct _lv_obj_t * obj, lv_area_t * hor, lv_area_t * ver);
@@ -266,6 +266,13 @@ void lv_obj_get_scrollbar_area(struct _lv_obj_t * obj, lv_area_t * hor, lv_area_
*/
void lv_obj_scrollbar_invalidate(struct _lv_obj_t * obj);
/**
* Checked if the content is scrolled "in" and adjusts it to a normal position.
* @param obj pointer to an object
* @param anim_en LV_ANIM_ON/OFF
*/
void lv_obj_readjust_scroll(struct _lv_obj_t * obj, lv_anim_enable_t anim_en);
/**********************
* MACROS
**********************/

View File

@@ -67,10 +67,10 @@ void _lv_obj_style_init(void);
/**
* Add a style to an object.
* @param obj pointer to an object
* @param part a part of the object to which the style should be added E.g. `LV_PART_MAIN` or `LV_PART_KNOB`
* @param state a state or combination of states to which the style should be assigned
* @param style pointer to a style to add
* @example lv_obj_add_style_no_refresh(slider, LV_PART_KNOB, LV_STATE_PRESSED, &style1);
* @param selector OR-ed value of parts and state to which the style should be added
* @example lv_obj_add_style(btn, &style_btn, 0); //Default button style
* @example lv_obj_add_style(btn, &btn_red, LV_STATE_PRESSED); //Overwrite only some colors to red when pressed
*/
void lv_obj_add_style(struct _lv_obj_t * obj, lv_style_t * style, lv_style_selector_t selector);
@@ -79,9 +79,9 @@ void lv_obj_add_style(struct _lv_obj_t * obj, lv_style_t * style, lv_style_selec
* @param obj pointer to an object
* @param style pointer to a style to remove. Can be NULL to check only the selector
* @param selector OR-ed values of states and a part to remove only styles with matching selectors. LV_STATE_ANY and LV_PART_ANY can be used
* @example lv_obj_remove_style(obj, LV_PART_ANY, LV_STATE_ANY, &style); //Remove a specific style
* @example lv_obj_remove_style(obj, LV_PART_MAIN, LV_STATE_ANY, &style); //Remove all styles from the main part
* @example lv_obj_remove_style(obj, LV_PART_ANY, LV_STATE_ANY, NULL); //Remove all styles
* @example lv_obj_remove_style(obj, &style, LV_PART_ANY | LV_STATE_ANY); //Remove a specific style
* @example lv_obj_remove_style(obj, NULL, LV_PART_MAIN | LV_STATE_ANY); //Remove all styles from the main part
* @example lv_obj_remove_style(obj, NULL, LV_PART_ANY | LV_STATE_ANY); //Remove all styles
*/
void lv_obj_remove_style(struct _lv_obj_t * obj, lv_style_t * style, lv_style_selector_t selector);

View File

@@ -67,12 +67,8 @@ void lv_obj_del(lv_obj_t * obj)
/*Call the ancestor's event handler to the parent to notify it about the child delete*/
if(par) {
/*Just to remove scroll animations if any*/
lv_obj_scroll_to(par, 0, 0, LV_ANIM_OFF);
if(par->spec_attr) {
par->spec_attr->scroll.x = 0;
par->spec_attr->scroll.y = 0;
}
lv_obj_readjust_scroll(par, LV_ANIM_OFF);
lv_obj_scrollbar_invalidate(par);
lv_event_send(par, LV_EVENT_CHILD_CHANGED, NULL);
}
@@ -335,13 +331,6 @@ static void obj_del_core(lv_obj_t * obj)
lv_res_t res = lv_event_send(obj, LV_EVENT_DELETE, NULL);
if(res == LV_RES_INV) return;
/*Delete from the group*/
lv_group_t * group = lv_obj_get_group(obj);
if(group) lv_group_remove_obj(obj);
/*Remove the animations from this object*/
lv_anim_del(obj, NULL);
/*Recursively delete the children*/
lv_obj_t * child = lv_obj_get_child(obj, 0);
while(child) {
@@ -349,12 +338,7 @@ static void obj_del_core(lv_obj_t * obj)
child = lv_obj_get_child(obj, 0);
}
_lv_event_mark_deleted(obj);
/*Remove all style*/
lv_obj_enable_style_refresh(false); /*No need to refresh the style because the object will be deleted*/
lv_obj_remove_style_all(obj);
lv_obj_enable_style_refresh(true);
lv_group_t * group = lv_obj_get_group(obj);
/*Reset all input devices if the object to delete is used*/
lv_indev_t * indev = lv_indev_get_next(NULL);
@@ -373,7 +357,7 @@ static void obj_del_core(lv_obj_t * obj)
}
/*All children deleted. Now clean up the object specific data*/
_lv_obj_destructor(obj);
_lv_obj_destruct(obj);
/*Remove the screen for the screen list*/
if(obj->parent == NULL) {

View File

@@ -408,75 +408,75 @@ static void lv_refr_area(const lv_area_t * area_p)
draw_buf->area.y2 = lv_disp_get_ver_res(disp_refr) - 1;
disp_refr->driver->draw_buf->last_part = 1;
lv_refr_area_part(area_p);
return;
}
/*Normal refresh: draw the area in parts*/
else {
lv_disp_draw_buf_t * draw_buf = lv_disp_get_draw_buf(disp_refr);
/*Calculate the max row num*/
lv_coord_t w = lv_area_get_width(area_p);
lv_coord_t h = lv_area_get_height(area_p);
lv_coord_t y2 =
area_p->y2 >= lv_disp_get_ver_res(disp_refr) ? lv_disp_get_ver_res(disp_refr) - 1 : area_p->y2;
lv_disp_draw_buf_t * draw_buf = lv_disp_get_draw_buf(disp_refr);
/*Calculate the max row num*/
lv_coord_t w = lv_area_get_width(area_p);
lv_coord_t h = lv_area_get_height(area_p);
lv_coord_t y2 = area_p->y2 >= lv_disp_get_ver_res(disp_refr) ?
lv_disp_get_ver_res(disp_refr) - 1 : area_p->y2;
int32_t max_row = (uint32_t)draw_buf->size / w;
int32_t max_row = (uint32_t)draw_buf->size / w;
if(max_row > h) max_row = h;
if(max_row > h) max_row = h;
/*Round down the lines of draw_buf if rounding is added*/
if(disp_refr->driver->rounder_cb) {
lv_area_t tmp;
tmp.x1 = 0;
tmp.x2 = 0;
tmp.y1 = 0;
/*Round down the lines of draw_buf if rounding is added*/
if(disp_refr->driver->rounder_cb) {
lv_area_t tmp;
tmp.x1 = 0;
tmp.x2 = 0;
tmp.y1 = 0;
lv_coord_t h_tmp = max_row;
do {
tmp.y2 = h_tmp - 1;
disp_refr->driver->rounder_cb(disp_refr->driver, &tmp);
lv_coord_t h_tmp = max_row;
do {
tmp.y2 = h_tmp - 1;
disp_refr->driver->rounder_cb(disp_refr->driver, &tmp);
/*If this height fits into `max_row` then fine*/
if(lv_area_get_height(&tmp) <= max_row) break;
/*If this height fits into `max_row` then fine*/
if(lv_area_get_height(&tmp) <= max_row) break;
/*Decrement the height of the area until it fits into `max_row` after rounding*/
h_tmp--;
} while(h_tmp > 0);
/*Decrement the height of the area until it fits into `max_row` after rounding*/
h_tmp--;
} while(h_tmp > 0);
if(h_tmp <= 0) {
LV_LOG_WARN("Can't set draw_buf height using the round function. (Wrong round_cb or to "
"small draw_buf)");
return;
}
else {
max_row = tmp.y2 + 1;
}
if(h_tmp <= 0) {
LV_LOG_WARN("Can't set draw_buf height using the round function. (Wrong round_cb or to "
"small draw_buf)");
return;
}
/*Always use the full row*/
lv_coord_t row;
lv_coord_t row_last = 0;
for(row = area_p->y1; row + max_row - 1 <= y2; row += max_row) {
/*Calc. the next y coordinates of draw_buf*/
draw_buf->area.x1 = area_p->x1;
draw_buf->area.x2 = area_p->x2;
draw_buf->area.y1 = row;
draw_buf->area.y2 = row + max_row - 1;
if(draw_buf->area.y2 > y2) draw_buf->area.y2 = y2;
row_last = draw_buf->area.y2;
if(y2 == row_last) disp_refr->driver->draw_buf->last_part = 1;
lv_refr_area_part(area_p);
else {
max_row = tmp.y2 + 1;
}
}
/*If the last y coordinates are not handled yet ...*/
if(y2 != row_last) {
/*Calc. the next y coordinates of draw_buf*/
draw_buf->area.x1 = area_p->x1;
draw_buf->area.x2 = area_p->x2;
draw_buf->area.y1 = row;
draw_buf->area.y2 = y2;
/*Always use the full row*/
lv_coord_t row;
lv_coord_t row_last = 0;
for(row = area_p->y1; row + max_row - 1 <= y2; row += max_row) {
/*Calc. the next y coordinates of draw_buf*/
draw_buf->area.x1 = area_p->x1;
draw_buf->area.x2 = area_p->x2;
draw_buf->area.y1 = row;
draw_buf->area.y2 = row + max_row - 1;
if(draw_buf->area.y2 > y2) draw_buf->area.y2 = y2;
row_last = draw_buf->area.y2;
if(y2 == row_last) disp_refr->driver->draw_buf->last_part = 1;
lv_refr_area_part(area_p);
}
disp_refr->driver->draw_buf->last_part = 1;
lv_refr_area_part(area_p);
}
/*If the last y coordinates are not handled yet ...*/
if(y2 != row_last) {
/*Calc. the next y coordinates of draw_buf*/
draw_buf->area.x1 = area_p->x1;
draw_buf->area.x2 = area_p->x2;
draw_buf->area.y1 = row;
draw_buf->area.y2 = y2;
disp_refr->driver->draw_buf->last_part = 1;
lv_refr_area_part(area_p);
}
}
@@ -488,8 +488,12 @@ static void lv_refr_area_part(const lv_area_t * area_p)
{
lv_disp_draw_buf_t * draw_buf = lv_disp_get_draw_buf(disp_refr);
while(draw_buf->flushing) {
if(disp_refr->driver->wait_cb) disp_refr->driver->wait_cb(disp_refr->driver);
/* Below the `area_p` area will be redrawn into the draw buffer.
* In single buffered mode wait here until the buffer is freed.*/
if(draw_buf->buf1 && !draw_buf->buf2) {
while(draw_buf->flushing) {
if(disp_refr->driver->wait_cb) disp_refr->driver->wait_cb(disp_refr->driver);
}
}
lv_obj_t * top_act_scr = NULL;
@@ -893,15 +897,23 @@ static void draw_buf_flush(void)
lv_disp_draw_buf_t * draw_buf = lv_disp_get_draw_buf(disp_refr);
lv_color_t * color_p = draw_buf->buf_act;
draw_buf->flushing = 1;
if(disp_refr->driver->draw_buf->last_area && disp_refr->driver->draw_buf->last_part) draw_buf->flushing_last = 1;
else draw_buf->flushing_last = 0;
/*Flush the rendered content to the display*/
lv_disp_t * disp = _lv_refr_get_disp_refreshing();
if(disp->driver->gpu_wait_cb) disp->driver->gpu_wait_cb(disp->driver);
/* In double buffered mode wait until the other buffer is freed
* and driver is ready to receive the new buffer */
if(draw_buf->buf1 && draw_buf->buf2) {
while(draw_buf->flushing) {
if(disp_refr->driver->wait_cb) disp_refr->driver->wait_cb(disp_refr->driver);
}
}
draw_buf->flushing = 1;
if(disp_refr->driver->draw_buf->last_area && disp_refr->driver->draw_buf->last_part) draw_buf->flushing_last = 1;
else draw_buf->flushing_last = 0;
if(disp->driver->flush_cb) {
/*Rotate the buffer to the display's native orientation if necessary*/
if(disp->driver->rotated != LV_DISP_ROT_NONE && disp->driver->sw_rotate) {

View File

@@ -103,14 +103,22 @@ void lv_draw_arc(lv_coord_t center_x, lv_coord_t center_y, uint16_t radius, uin
area_in.x2 -= dsc->width;
area_in.y2 -= dsc->width;
/*Create inner the mask*/
lv_draw_mask_radius_param_t mask_in_param;
lv_draw_mask_radius_init(&mask_in_param, &area_in, LV_RADIUS_CIRCLE, true);
int16_t mask_in_id = lv_draw_mask_add(&mask_in_param, NULL);
lv_draw_mask_radius_param_t mask_out_param;
lv_draw_mask_radius_init(&mask_out_param, &area_out, LV_RADIUS_CIRCLE, false);
int16_t mask_out_id = lv_draw_mask_add(&mask_out_param, NULL);
/*Draw a full ring*/
if(start_angle + 360 == end_angle || start_angle == end_angle + 360) {
cir_dsc.border_width = dsc->width;
cir_dsc.border_color = dsc->color;
cir_dsc.border_opa = dsc->opa;
cir_dsc.bg_opa = LV_OPA_TRANSP;
cir_dsc.radius = LV_RADIUS_CIRCLE;
lv_draw_rect(&area_out, clip_area, &cir_dsc);
lv_draw_mask_remove_id(mask_out_id);
lv_draw_mask_remove_id(mask_in_id);
return;
}
@@ -121,15 +129,6 @@ void lv_draw_arc(lv_coord_t center_x, lv_coord_t center_y, uint16_t radius, uin
lv_draw_mask_angle_init(&mask_angle_param, center_x, center_y, start_angle, end_angle);
int16_t mask_angle_id = lv_draw_mask_add(&mask_angle_param, NULL);
/*Create inner the mask*/
lv_draw_mask_radius_param_t mask_in_param;
lv_draw_mask_radius_init(&mask_in_param, &area_in, LV_RADIUS_CIRCLE, true);
int16_t mask_in_id = lv_draw_mask_add(&mask_in_param, NULL);
lv_draw_mask_radius_param_t mask_out_param;
lv_draw_mask_radius_init(&mask_out_param, &area_out, LV_RADIUS_CIRCLE, false);
int16_t mask_out_id = lv_draw_mask_add(&mask_out_param, NULL);
int32_t angle_gap;
if(end_angle > start_angle) {
angle_gap = 360 - (end_angle - start_angle);

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