Merge branch 'develop' of JF/PineTime into master
This commit is contained in:
commit
b89c92b71d
3
.gitmodules
vendored
Normal file
3
.gitmodules
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
[submodule "src/libs/lvgl"]
|
||||
path = src/libs/lvgl
|
||||
url = https://github.com/joaquimorg/lvgl.git
|
@ -1,5 +1,5 @@
|
||||
cmake_minimum_required(VERSION 3.10)
|
||||
project(pinetime VERSION 0.13.0 LANGUAGES C CXX ASM)
|
||||
project(pinetime VERSION 0.14.0 LANGUAGES C CXX ASM)
|
||||
|
||||
set(NRF_TARGET "nrf52")
|
||||
|
||||
|
@ -19,7 +19,7 @@ The goal of this project is to design an open-source firmware for the Pinetime s
|
||||
- Code written in **modern C++**;
|
||||
- Build system based on **CMake**;
|
||||
- Based on **[FreeRTOS 10.0.0](https://freertos.org)** real-time OS.
|
||||
- Using **[LittleVGL/LVGL 6.1.2](https://lvgl.io/)** as UI library...
|
||||
- Using **[LittleVGL/LVGL 7](https://lvgl.io/)** as UI library...
|
||||
- ... and **[NimBLE 1.3.0](https://github.com/apache/mynewt-nimble)** as BLE stack.
|
||||
|
||||
## Overview
|
||||
|
@ -10,6 +10,7 @@ To build this project, you'll need:
|
||||
```
|
||||
git clone https://github.com/JF002/Pinetime.git
|
||||
cd Pinetime
|
||||
git submodule update --init
|
||||
mkdir build
|
||||
cd build
|
||||
```
|
||||
|
@ -168,132 +168,180 @@ set(NIMBLE_SRC
|
||||
set(LVGL_SRC
|
||||
libs/lv_conf.h
|
||||
libs/lvgl/lvgl.h
|
||||
libs/lvgl/src/lv_core/lv_obj.c
|
||||
libs/lvgl/src/lv_core/lv_obj.h
|
||||
libs/lvgl/src/lv_core/lv_group.c
|
||||
libs/lvgl/src/lv_core/lv_group.h
|
||||
libs/lvgl/src/lv_core/lv_disp.c
|
||||
|
||||
libs/lvgl/src/lvgl.h
|
||||
libs/lvgl/src/lv_api_map.h
|
||||
libs/lvgl/src/lv_conf_internal.h
|
||||
libs/lvgl/src/lv_core/lv_disp.h
|
||||
libs/lvgl/src/lv_core/lv_debug.h
|
||||
libs/lvgl/src/lv_core/lv_debug.c
|
||||
libs/lvgl/src/lv_core/lv_indev.c
|
||||
libs/lvgl/src/lv_core/lv_group.h
|
||||
libs/lvgl/src/lv_core/lv_indev.h
|
||||
libs/lvgl/src/lv_core/lv_refr.c
|
||||
libs/lvgl/src/lv_core/lv_obj.h
|
||||
libs/lvgl/src/lv_core/lv_obj_style_dec.h
|
||||
libs/lvgl/src/lv_core/lv_refr.h
|
||||
libs/lvgl/src/lv_core/lv_style.c
|
||||
libs/lvgl/src/lv_core/lv_style.h
|
||||
libs/lvgl/src/lv_misc/lv_anim.c
|
||||
libs/lvgl/src/lv_misc/lv_anim.h
|
||||
libs/lvgl/src/lv_misc/lv_async.h
|
||||
libs/lvgl/src/lv_misc/lv_async.c
|
||||
libs/lvgl/src/lv_misc/lv_fs.c
|
||||
libs/lvgl/src/lv_misc/lv_fs.h
|
||||
libs/lvgl/src/lv_misc/lv_task.c
|
||||
libs/lvgl/src/lv_misc/lv_task.h
|
||||
libs/lvgl/src/lv_misc/lv_area.c
|
||||
libs/lvgl/src/lv_misc/lv_area.h
|
||||
libs/lvgl/src/lv_misc/lv_bidi.c
|
||||
libs/lvgl/src/lv_misc/lv_bidi.h
|
||||
libs/lvgl/src/lv_misc/lv_circ.c
|
||||
libs/lvgl/src/lv_misc/lv_circ.h
|
||||
libs/lvgl/src/lv_misc/lv_color.c
|
||||
libs/lvgl/src/lv_misc/lv_color.h
|
||||
libs/lvgl/src/lv_misc/lv_fs.c
|
||||
libs/lvgl/src/lv_misc/lv_fs.h
|
||||
libs/lvgl/src/lv_misc/lv_gc.c
|
||||
libs/lvgl/src/lv_misc/lv_gc.h
|
||||
libs/lvgl/src/lv_misc/lv_ll.c
|
||||
libs/lvgl/src/lv_misc/lv_ll.h
|
||||
libs/lvgl/src/lv_misc/lv_log.c
|
||||
libs/lvgl/src/lv_misc/lv_log.h
|
||||
libs/lvgl/src/lv_misc/lv_math.c
|
||||
libs/lvgl/src/lv_misc/lv_math.h
|
||||
libs/lvgl/src/lv_misc/lv_mem.c
|
||||
libs/lvgl/src/lv_misc/lv_mem.h
|
||||
libs/lvgl/src/lv_misc/lv_printf.c
|
||||
libs/lvgl/src/lv_misc/lv_printf.h
|
||||
libs/lvgl/src/lv_misc/lv_task.c
|
||||
libs/lvgl/src/lv_misc/lv_task.h
|
||||
libs/lvgl/src/lv_misc/lv_templ.c
|
||||
libs/lvgl/src/lv_misc/lv_templ.h
|
||||
libs/lvgl/src/lv_misc/lv_txt.c
|
||||
libs/lvgl/src/lv_misc/lv_txt.h
|
||||
libs/lvgl/src/lv_misc/lv_types.h
|
||||
libs/lvgl/src/lv_misc/lv_utils.c
|
||||
libs/lvgl/src/lv_misc/lv_utils.h
|
||||
libs/lvgl/src/lv_draw/lv_draw.c
|
||||
libs/lvgl/src/lv_draw/lv_draw.h
|
||||
libs/lvgl/src/lv_draw/lv_draw_arc.c
|
||||
libs/lvgl/src/lv_draw/lv_draw_arc.h
|
||||
libs/lvgl/src/lv_draw/lv_draw_basic.c
|
||||
libs/lvgl/src/lv_draw/lv_draw_basic.h
|
||||
libs/lvgl/src/lv_draw/lv_draw_img.c
|
||||
libs/lvgl/src/lv_draw/lv_draw_blend.h
|
||||
libs/lvgl/src/lv_draw/lv_draw_img.h
|
||||
libs/lvgl/src/lv_draw/lv_draw_label.c
|
||||
libs/lvgl/src/lv_draw/lv_draw_label.h
|
||||
libs/lvgl/src/lv_draw/lv_draw_line.c
|
||||
libs/lvgl/src/lv_draw/lv_draw_line.h
|
||||
libs/lvgl/src/lv_draw/lv_draw_rect.c
|
||||
libs/lvgl/src/lv_draw/lv_draw_mask.h
|
||||
libs/lvgl/src/lv_draw/lv_draw_rect.h
|
||||
libs/lvgl/src/lv_draw/lv_draw_triangle.c
|
||||
libs/lvgl/src/lv_draw/lv_draw_triangle.h
|
||||
libs/lvgl/src/lv_draw/lv_img_cache.c
|
||||
libs/lvgl/src/lv_draw/lv_img_buf.h
|
||||
libs/lvgl/src/lv_draw/lv_img_cache.h
|
||||
libs/lvgl/src/lv_draw/lv_img_decoder.c
|
||||
libs/lvgl/src/lv_draw/lv_img_decoder.h
|
||||
libs/lvgl/src/lv_hal/lv_hal.h
|
||||
libs/lvgl/src/lv_hal/lv_hal_disp.c
|
||||
libs/lvgl/src/lv_hal/lv_hal_disp.h
|
||||
libs/lvgl/src/lv_hal/lv_hal_indev.c
|
||||
libs/lvgl/src/lv_hal/lv_hal_indev.h
|
||||
libs/lvgl/src/lv_hal/lv_hal_tick.c
|
||||
libs/lvgl/src/lv_hal/lv_hal_tick.h
|
||||
libs/lvgl/src/lv_font/lv_font.c
|
||||
libs/lvgl/src/lv_font/lv_font.h
|
||||
libs/lvgl/src/lv_font/lv_font_fmt_txt.c
|
||||
libs/lvgl/src/lv_font/lv_font_fmt_txt.h
|
||||
libs/lvgl/src/lv_font/lv_font_loader.h
|
||||
libs/lvgl/src/lv_font/lv_symbol_def.h
|
||||
libs/lvgl/src/lv_themes/lv_theme.c
|
||||
libs/lvgl/src/lv_hal/lv_hal.h
|
||||
libs/lvgl/src/lv_hal/lv_hal_disp.h
|
||||
libs/lvgl/src/lv_hal/lv_hal_indev.h
|
||||
libs/lvgl/src/lv_hal/lv_hal_tick.h
|
||||
libs/lvgl/src/lv_misc/lv_anim.h
|
||||
libs/lvgl/src/lv_misc/lv_area.h
|
||||
libs/lvgl/src/lv_misc/lv_async.h
|
||||
libs/lvgl/src/lv_misc/lv_bidi.h
|
||||
libs/lvgl/src/lv_misc/lv_color.h
|
||||
libs/lvgl/src/lv_misc/lv_debug.h
|
||||
libs/lvgl/src/lv_misc/lv_fs.h
|
||||
libs/lvgl/src/lv_misc/lv_gc.h
|
||||
libs/lvgl/src/lv_misc/lv_ll.h
|
||||
libs/lvgl/src/lv_misc/lv_log.h
|
||||
libs/lvgl/src/lv_misc/lv_math.h
|
||||
libs/lvgl/src/lv_misc/lv_mem.h
|
||||
libs/lvgl/src/lv_misc/lv_printf.h
|
||||
libs/lvgl/src/lv_misc/lv_task.h
|
||||
libs/lvgl/src/lv_misc/lv_templ.h
|
||||
libs/lvgl/src/lv_misc/lv_txt.h
|
||||
libs/lvgl/src/lv_misc/lv_txt_ap.h
|
||||
libs/lvgl/src/lv_misc/lv_types.h
|
||||
libs/lvgl/src/lv_misc/lv_utils.h
|
||||
libs/lvgl/src/lv_themes/lv_theme.h
|
||||
libs/lvgl/src/lv_objx/lv_btn.h
|
||||
libs/lvgl/src/lv_objx/lv_btn.c
|
||||
libs/lvgl/src/lv_objx/lv_cont.h
|
||||
libs/lvgl/src/lv_objx/lv_cont.c
|
||||
libs/lvgl/src/lv_objx/lv_label.h
|
||||
libs/lvgl/src/lv_objx/lv_label.c
|
||||
libs/lvgl/src/lv_objx/lv_table.c
|
||||
libs/lvgl/src/lv_themes/lv_theme_empty.h
|
||||
libs/lvgl/src/lv_themes/lv_theme_material.h
|
||||
#libs/lvgl/src/lv_themes/lv_theme_mono.h
|
||||
#libs/lvgl/src/lv_themes/lv_theme_template.h
|
||||
libs/lvgl/src/lv_widgets/lv_arc.h
|
||||
libs/lvgl/src/lv_widgets/lv_bar.h
|
||||
libs/lvgl/src/lv_widgets/lv_btn.h
|
||||
libs/lvgl/src/lv_widgets/lv_btnmatrix.h
|
||||
libs/lvgl/src/lv_widgets/lv_calendar.h
|
||||
libs/lvgl/src/lv_widgets/lv_canvas.h
|
||||
libs/lvgl/src/lv_widgets/lv_chart.h
|
||||
libs/lvgl/src/lv_widgets/lv_checkbox.h
|
||||
libs/lvgl/src/lv_widgets/lv_cont.h
|
||||
libs/lvgl/src/lv_widgets/lv_cpicker.h
|
||||
libs/lvgl/src/lv_widgets/lv_dropdown.h
|
||||
libs/lvgl/src/lv_widgets/lv_img.h
|
||||
libs/lvgl/src/lv_widgets/lv_imgbtn.h
|
||||
libs/lvgl/src/lv_widgets/lv_keyboard.h
|
||||
libs/lvgl/src/lv_widgets/lv_label.h
|
||||
libs/lvgl/src/lv_widgets/lv_led.h
|
||||
libs/lvgl/src/lv_widgets/lv_line.h
|
||||
libs/lvgl/src/lv_widgets/lv_linemeter.h
|
||||
libs/lvgl/src/lv_widgets/lv_list.h
|
||||
libs/lvgl/src/lv_widgets/lv_msgbox.h
|
||||
libs/lvgl/src/lv_widgets/lv_objmask.h
|
||||
libs/lvgl/src/lv_widgets/lv_objx_templ.h
|
||||
libs/lvgl/src/lv_widgets/lv_page.h
|
||||
libs/lvgl/src/lv_widgets/lv_roller.h
|
||||
libs/lvgl/src/lv_widgets/lv_slider.h
|
||||
libs/lvgl/src/lv_widgets/lv_spinbox.h
|
||||
libs/lvgl/src/lv_widgets/lv_spinner.h
|
||||
libs/lvgl/src/lv_widgets/lv_switch.h
|
||||
libs/lvgl/src/lv_widgets/lv_table.h
|
||||
libs/lvgl/src/lv_widgets/lv_tabview.h
|
||||
libs/lvgl/src/lv_widgets/lv_textarea.h
|
||||
libs/lvgl/src/lv_widgets/lv_tileview.h
|
||||
libs/lvgl/src/lv_widgets/lv_win.h
|
||||
libs/lvgl/src/lv_core/lv_disp.c
|
||||
libs/lvgl/src/lv_core/lv_group.c
|
||||
libs/lvgl/src/lv_core/lv_indev.c
|
||||
libs/lvgl/src/lv_core/lv_obj.c
|
||||
libs/lvgl/src/lv_core/lv_refr.c
|
||||
libs/lvgl/src/lv_core/lv_style.c
|
||||
libs/lvgl/src/lv_draw/lv_draw_arc.c
|
||||
libs/lvgl/src/lv_draw/lv_draw_blend.c
|
||||
libs/lvgl/src/lv_draw/lv_draw_img.c
|
||||
libs/lvgl/src/lv_draw/lv_draw_label.c
|
||||
libs/lvgl/src/lv_draw/lv_draw_line.c
|
||||
libs/lvgl/src/lv_draw/lv_draw_mask.c
|
||||
libs/lvgl/src/lv_draw/lv_draw_rect.c
|
||||
libs/lvgl/src/lv_draw/lv_draw_triangle.c
|
||||
libs/lvgl/src/lv_draw/lv_img_buf.c
|
||||
libs/lvgl/src/lv_draw/lv_img_cache.c
|
||||
libs/lvgl/src/lv_draw/lv_img_decoder.c
|
||||
libs/lvgl/src/lv_font/lv_font.c
|
||||
#libs/lvgl/src/lv_font/lv_font_dejavu_16_persian_hebrew.c
|
||||
libs/lvgl/src/lv_font/lv_font_fmt_txt.c
|
||||
libs/lvgl/src/lv_font/lv_font_loader.c
|
||||
# LVGL Fonts
|
||||
libs/lvgl/src/lv_font/lv_font_montserrat_14.c
|
||||
libs/lvgl/src/lv_font/lv_font_montserrat_18.c
|
||||
libs/lvgl/src/lv_font/lv_font_montserrat_22.c
|
||||
libs/lvgl/src/lv_font/lv_font_montserrat_28.c
|
||||
#
|
||||
libs/lvgl/src/lv_hal/lv_hal_disp.c
|
||||
libs/lvgl/src/lv_hal/lv_hal_indev.c
|
||||
libs/lvgl/src/lv_hal/lv_hal_tick.c
|
||||
libs/lvgl/src/lv_misc/lv_anim.c
|
||||
libs/lvgl/src/lv_misc/lv_area.c
|
||||
libs/lvgl/src/lv_misc/lv_async.c
|
||||
libs/lvgl/src/lv_misc/lv_bidi.c
|
||||
libs/lvgl/src/lv_misc/lv_color.c
|
||||
libs/lvgl/src/lv_misc/lv_debug.c
|
||||
libs/lvgl/src/lv_misc/lv_fs.c
|
||||
libs/lvgl/src/lv_misc/lv_gc.c
|
||||
libs/lvgl/src/lv_misc/lv_ll.c
|
||||
libs/lvgl/src/lv_misc/lv_log.c
|
||||
libs/lvgl/src/lv_misc/lv_math.c
|
||||
libs/lvgl/src/lv_misc/lv_mem.c
|
||||
libs/lvgl/src/lv_misc/lv_printf.c
|
||||
libs/lvgl/src/lv_misc/lv_task.c
|
||||
libs/lvgl/src/lv_misc/lv_templ.c
|
||||
libs/lvgl/src/lv_misc/lv_txt.c
|
||||
libs/lvgl/src/lv_misc/lv_txt_ap.c
|
||||
libs/lvgl/src/lv_misc/lv_utils.c
|
||||
libs/lvgl/src/lv_themes/lv_theme.c
|
||||
libs/lvgl/src/lv_themes/lv_theme.h
|
||||
libs/lvgl/src/lv_themes/lv_theme_night.h
|
||||
libs/lvgl/src/lv_themes/lv_theme_night.c
|
||||
libs/lvgl/src/lv_objx/lv_list.c
|
||||
libs/lvgl/src/lv_objx/lv_list.h
|
||||
libs/lvgl/src/lv_objx/lv_tileview.c
|
||||
libs/lvgl/src/lv_objx/lv_tileview.h
|
||||
libs/lvgl/src/lv_objx/lv_tabview.c
|
||||
libs/lvgl/src/lv_objx/lv_tabview.h
|
||||
libs/lvgl/src/lv_objx/lv_btnm.c
|
||||
libs/lvgl/src/lv_objx/lv_btnm.h
|
||||
libs/lvgl/src/lv_objx/lv_page.c
|
||||
libs/lvgl/src/lv_objx/lv_page.h
|
||||
libs/lvgl/src/lv_objx/lv_img.c
|
||||
libs/lvgl/src/lv_objx/lv_img.h
|
||||
libs/lvgl/src/lv_objx/lv_lmeter.c
|
||||
libs/lvgl/src/lv_objx/lv_lmeter.h
|
||||
libs/lvgl/src/lv_objx/lv_arc.c
|
||||
libs/lvgl/src/lv_objx/lv_arc.h
|
||||
libs/lvgl/src/lv_objx/lv_gauge.c
|
||||
libs/lvgl/src/lv_objx/lv_gauge.h
|
||||
libs/lvgl/src/lv_objx/lv_mbox.c
|
||||
libs/lvgl/src/lv_objx/lv_mbox.h
|
||||
libs/lvgl/src/lv_objx/lv_bar.c
|
||||
libs/lvgl/src/lv_objx/lv_bar.h
|
||||
libs/lvgl/src/lv_objx/lv_slider.h
|
||||
libs/lvgl/src/lv_objx/lv_slider.c
|
||||
libs/lvgl/src/lv_objx/lv_ddlist.c
|
||||
libs/lvgl/src/lv_objx/lv_ddlist.h
|
||||
libs/lvgl/src/lv_objx/lv_line.c
|
||||
libs/lvgl/src/lv_objx/lv_line.h
|
||||
libs/lvgl/src/lv_themes/lv_theme_empty.c
|
||||
libs/lvgl/src/lv_themes/lv_theme_material.c
|
||||
#libs/lvgl/src/lv_themes/lv_theme_mono.c
|
||||
#libs/lvgl/src/lv_themes/lv_theme_template.c
|
||||
libs/lvgl/src/lv_widgets/lv_arc.c
|
||||
libs/lvgl/src/lv_widgets/lv_bar.c
|
||||
libs/lvgl/src/lv_widgets/lv_btn.c
|
||||
libs/lvgl/src/lv_widgets/lv_btnmatrix.c
|
||||
libs/lvgl/src/lv_widgets/lv_calendar.c
|
||||
libs/lvgl/src/lv_widgets/lv_canvas.c
|
||||
libs/lvgl/src/lv_widgets/lv_chart.c
|
||||
libs/lvgl/src/lv_widgets/lv_checkbox.c
|
||||
libs/lvgl/src/lv_widgets/lv_cont.c
|
||||
libs/lvgl/src/lv_widgets/lv_cpicker.c
|
||||
libs/lvgl/src/lv_widgets/lv_dropdown.c
|
||||
libs/lvgl/src/lv_widgets/lv_img.c
|
||||
libs/lvgl/src/lv_widgets/lv_imgbtn.c
|
||||
libs/lvgl/src/lv_widgets/lv_keyboard.c
|
||||
libs/lvgl/src/lv_widgets/lv_label.c
|
||||
libs/lvgl/src/lv_widgets/lv_led.c
|
||||
libs/lvgl/src/lv_widgets/lv_line.c
|
||||
libs/lvgl/src/lv_widgets/lv_linemeter.c
|
||||
libs/lvgl/src/lv_widgets/lv_list.c
|
||||
libs/lvgl/src/lv_widgets/lv_msgbox.c
|
||||
libs/lvgl/src/lv_widgets/lv_objmask.c
|
||||
libs/lvgl/src/lv_widgets/lv_objx_templ.c
|
||||
libs/lvgl/src/lv_widgets/lv_page.c
|
||||
libs/lvgl/src/lv_widgets/lv_roller.c
|
||||
libs/lvgl/src/lv_widgets/lv_slider.c
|
||||
libs/lvgl/src/lv_widgets/lv_spinbox.c
|
||||
libs/lvgl/src/lv_widgets/lv_spinner.c
|
||||
libs/lvgl/src/lv_widgets/lv_switch.c
|
||||
libs/lvgl/src/lv_widgets/lv_table.c
|
||||
libs/lvgl/src/lv_widgets/lv_tabview.c
|
||||
libs/lvgl/src/lv_widgets/lv_textarea.c
|
||||
libs/lvgl/src/lv_widgets/lv_tileview.c
|
||||
libs/lvgl/src/lv_widgets/lv_win.c
|
||||
)
|
||||
|
||||
list(APPEND IMAGE_FILES
|
||||
@ -424,10 +472,8 @@ list(APPEND SOURCE_FILES
|
||||
displayapp/screens/Clock.cpp
|
||||
displayapp/screens/Tile.cpp
|
||||
displayapp/screens/Meter.cpp
|
||||
displayapp/screens/Gauge.cpp
|
||||
displayapp/screens/InfiniPaint.cpp
|
||||
displayapp/screens/Paddle.cpp
|
||||
displayapp/screens/DropDownDemo.cpp
|
||||
displayapp/screens/BatteryIcon.cpp
|
||||
displayapp/screens/BleIcon.cpp
|
||||
displayapp/screens/NotificationIcon.cpp
|
||||
@ -479,6 +525,7 @@ list(APPEND SOURCE_FILES
|
||||
displayapp/LittleVgl.cpp
|
||||
displayapp/fonts/jetbrains_mono_extrabold_compressed.c
|
||||
displayapp/fonts/jetbrains_mono_bold_20.c
|
||||
displayapp/lv_pinetime_theme.c
|
||||
|
||||
systemtask/SystemTask.cpp
|
||||
drivers/TwiMaster.cpp
|
||||
@ -518,7 +565,6 @@ set(INCLUDE_FILES
|
||||
displayapp/screens/Clock.h
|
||||
displayapp/screens/Tile.h
|
||||
displayapp/screens/Meter.h
|
||||
displayapp/screens/Gauge.h
|
||||
displayapp/screens/InfiniPaint.h
|
||||
displayapp/screens/Paddle.h
|
||||
displayapp/screens/DropDownDemo.h
|
||||
@ -571,6 +617,7 @@ set(INCLUDE_FILES
|
||||
libs/date/includes/date/ptz.h
|
||||
libs/date/includes/date/tz_private.h
|
||||
displayapp/LittleVgl.h
|
||||
displayapp/lv_pinetime_theme.h
|
||||
systemtask/SystemTask.h
|
||||
systemtask/SystemMonitor.h
|
||||
displayapp/screens/Symbols.h
|
||||
@ -831,7 +878,7 @@ if (USE_JLINK)
|
||||
COMMAND ${NRFJPROG} --program ${EXECUTABLE_FILE_NAME}.hex -f ${NRF_TARGET} --sectorerase
|
||||
COMMAND sleep 0.5s
|
||||
COMMAND ${NRFJPROG} --reset -f ${NRF_TARGET}
|
||||
COMMENT "flashing ${EXECUTABLE_NAME}.hex"
|
||||
COMMENT "flashing ${EXECUTABLE_FILE_NAME}.hex"
|
||||
)
|
||||
|
||||
elseif (USE_GDB_CLIENT)
|
||||
@ -841,8 +888,8 @@ elseif (USE_GDB_CLIENT)
|
||||
)
|
||||
add_custom_target("FLASH_${EXECUTABLE_NAME}"
|
||||
DEPENDS ${EXECUTABLE_NAME}
|
||||
COMMAND ${GDB_CLIENT_BIN_PATH} -nx --batch -ex 'target extended-remote ${GDB_CLIENT_TARGET_REMOTE}' -ex 'monitor swdp_scan' -ex 'attach 1' -ex 'load' -ex 'kill' ${EXECUTABLE_NAME}.hex
|
||||
COMMENT "flashing ${EXECUTABLE_NAME}.hex"
|
||||
COMMAND ${GDB_CLIENT_BIN_PATH} -nx --batch -ex 'target extended-remote ${GDB_CLIENT_TARGET_REMOTE}' -ex 'monitor swdp_scan' -ex 'attach 1' -ex 'load' -ex 'kill' ${EXECUTABLE_FILE_NAME}.hex
|
||||
COMMENT "flashing ${EXECUTABLE_FILE_NAME}.hex"
|
||||
)
|
||||
elseif (USE_OPENOCD)
|
||||
if (USE_CMSIS_DAP)
|
||||
@ -867,10 +914,10 @@ elseif (USE_OPENOCD)
|
||||
-c 'transport select swd'
|
||||
-c 'source [find target/nrf52.cfg]'
|
||||
-c 'halt'
|
||||
-c "program \"${EXECUTABLE_NAME}.hex\""
|
||||
-c "program \"${EXECUTABLE_FILE_NAME}.hex\""
|
||||
-c 'reset'
|
||||
-c 'shutdown'
|
||||
COMMENT "flashing ${EXECUTABLE_NAME}.hex"
|
||||
COMMENT "flashing ${EXECUTABLE_BIN_NAME}.hex"
|
||||
)
|
||||
else ()
|
||||
add_custom_target(FLASH_ERASE
|
||||
@ -879,8 +926,8 @@ elseif (USE_OPENOCD)
|
||||
)
|
||||
add_custom_target("FLASH_${EXECUTABLE_NAME}"
|
||||
DEPENDS ${EXECUTABLE_NAME}
|
||||
COMMAND ${OPENOCD_BIN_PATH} -c "tcl_port disabled" -c "gdb_port 3333" -c "telnet_port 4444" -f interface/stlink.cfg -c 'transport select hla_swd' -f target/nrf52.cfg -c "program \"${EXECUTABLE_NAME}.hex\"" -c reset -c shutdown
|
||||
COMMENT "flashing ${EXECUTABLE_NAME}.hex"
|
||||
COMMAND ${OPENOCD_BIN_PATH} -c "tcl_port disabled" -c "gdb_port 3333" -c "telnet_port 4444" -f interface/stlink.cfg -c 'transport select hla_swd' -f target/nrf52.cfg -c "program \"${EXECUTABLE_FILE_NAME}.hex\"" -c reset -c shutdown
|
||||
COMMENT "flashing ${EXECUTABLE_FILE_NAME}.hex"
|
||||
)
|
||||
endif ()
|
||||
endif ()
|
||||
|
@ -2,6 +2,6 @@
|
||||
|
||||
namespace Pinetime {
|
||||
namespace Applications {
|
||||
enum class Apps {None, Launcher, Clock, SysInfo, Meter, Gauge, Brightness, Music, FirmwareValidation, Paint, Paddle, Notifications, Twos, HeartRate, Navigation};
|
||||
enum class Apps {None, Launcher, Clock, SysInfo, Meter, Brightness, Music, FirmwareValidation, Paint, Paddle, Notifications, Twos, HeartRate, Navigation};
|
||||
}
|
||||
}
|
||||
|
@ -10,7 +10,6 @@
|
||||
#include "displayapp/screens/Clock.h"
|
||||
#include "displayapp/screens/FirmwareUpdate.h"
|
||||
#include "displayapp/screens/FirmwareValidation.h"
|
||||
#include "displayapp/screens/Gauge.h"
|
||||
#include "displayapp/screens/InfiniPaint.h"
|
||||
#include "displayapp/screens/Paddle.h"
|
||||
#include "displayapp/screens/Meter.h"
|
||||
@ -200,11 +199,9 @@ void DisplayApp::RunningState() {
|
||||
currentScreen.reset(new Screens::Clock(this, dateTimeController, batteryController, bleController, notificationManager, heartRateController));
|
||||
onClockApp = true;
|
||||
break;
|
||||
// case Apps::Test: currentScreen.reset(new Screens::Message(this)); break;
|
||||
case Apps::SysInfo: currentScreen.reset(new Screens::SystemInfo(this, dateTimeController, batteryController, brightnessController, bleController, watchdog)); break;
|
||||
case Apps::Meter: currentScreen.reset(new Screens::Meter(this)); break;
|
||||
case Apps::Twos: currentScreen.reset(new Screens::Twos(this)); break;
|
||||
case Apps::Gauge: currentScreen.reset(new Screens::Gauge(this)); break;
|
||||
case Apps::Paint: currentScreen.reset(new Screens::InfiniPaint(this, lvgl)); break;
|
||||
case Apps::Paddle: currentScreen.reset(new Screens::Paddle(this, lvgl)); break;
|
||||
case Apps::Brightness : currentScreen.reset(new Screens::Brightness(this, brightnessController)); break;
|
||||
|
@ -9,7 +9,7 @@
|
||||
#include "TouchEvents.h"
|
||||
#include "components/brightness/BrightnessController.h"
|
||||
#include "components/firmwarevalidator/FirmwareValidator.h"
|
||||
#include "displayapp/screens/Modal.h"
|
||||
#include "displayapp/screens/Screen.h"
|
||||
|
||||
namespace Pinetime {
|
||||
|
||||
|
@ -1,4 +1,5 @@
|
||||
#include "LittleVgl.h"
|
||||
#include "lv_pinetime_theme.h"
|
||||
|
||||
#include <FreeRTOS.h>
|
||||
#include <task.h>
|
||||
@ -8,11 +9,6 @@
|
||||
|
||||
using namespace Pinetime::Components;
|
||||
|
||||
extern "C" {
|
||||
LV_FONT_DECLARE(jetbrains_mono_extrabold_compressed)
|
||||
LV_FONT_DECLARE(jetbrains_mono_bold_20)
|
||||
}
|
||||
|
||||
lv_style_t* LabelBigStyle = nullptr;
|
||||
|
||||
static void disp_flush(lv_disp_drv_t * disp_drv, const lv_area_t * area, lv_color_t * color_p) {
|
||||
@ -210,620 +206,15 @@ bool LittleVgl::GetTouchPadInfo(lv_indev_data_t *ptr) {
|
||||
}
|
||||
|
||||
void LittleVgl::InitTheme() {
|
||||
uint16_t i;
|
||||
lv_style_t ** style_p = (lv_style_t **)&theme.style;
|
||||
for(i = 0; i < LV_THEME_STYLE_COUNT; i++) {
|
||||
*style_p = &def;
|
||||
style_p++;
|
||||
}
|
||||
|
||||
InitBaseTheme();
|
||||
InitThemeContainer();
|
||||
InitThemeButton();
|
||||
InitThemeLabel();
|
||||
InitThemeLine();
|
||||
InitThemeLed();
|
||||
InitThemeImage();
|
||||
InitThemeBar();
|
||||
InitThemeSlider();
|
||||
InitThemeSwitch();
|
||||
InitThemeMeter();
|
||||
InitThemeGauge();
|
||||
InitThemeArc();
|
||||
InitThemePreload();
|
||||
InitThemeChart();
|
||||
InitThemeCalendar();
|
||||
InitThemeCheckBox();
|
||||
InitThemeButtonMatrix();
|
||||
InitThemeKnob();
|
||||
InitThemeMessageBox();
|
||||
InitThemePage();
|
||||
InitThemeTextArea();
|
||||
InitThemeSpinBox();
|
||||
InitThemeList();
|
||||
InitThemeDropDownList();
|
||||
InitThemeRoller();
|
||||
InitThemeTabView();
|
||||
InitThemeTileView();
|
||||
InitThemeTable();
|
||||
InitThemeWindow();
|
||||
lv_theme_t * th = lv_pinetime_theme_init(
|
||||
LV_COLOR_WHITE, LV_COLOR_SILVER,
|
||||
0,
|
||||
&jetbrains_mono_bold_20,
|
||||
&jetbrains_mono_bold_20,
|
||||
&jetbrains_mono_bold_20,
|
||||
&jetbrains_mono_bold_20);
|
||||
|
||||
lv_theme_set_act(th);
|
||||
|
||||
lv_theme_set_current(&theme);
|
||||
}
|
||||
|
||||
void LittleVgl::InitBaseTheme() {
|
||||
if(font == nullptr) font = &jetbrains_mono_bold_20;
|
||||
lv_style_copy(&def, &lv_style_plain); /*Initialize the default style*/
|
||||
def.text.font = font;
|
||||
|
||||
lv_style_copy(&bg, &lv_style_plain);
|
||||
bg.body.main_color = LV_COLOR_BLACK;
|
||||
bg.body.grad_color = LV_COLOR_BLACK;
|
||||
bg.text.color = LV_COLOR_WHITE;
|
||||
bg.text.font = font;
|
||||
bg.image.color = LV_COLOR_WHITE;
|
||||
|
||||
lv_style_copy(&scr, &bg);
|
||||
scr.body.padding.bottom = 0;
|
||||
scr.body.padding.top = 0;
|
||||
scr.body.padding.left = 0;
|
||||
scr.body.padding.right = 0;
|
||||
|
||||
lv_style_copy(&sb, &def);
|
||||
sb.body.main_color = lv_color_hsv_to_rgb(hue, 30, 60);
|
||||
sb.body.grad_color = lv_color_hsv_to_rgb(hue, 30, 60);
|
||||
sb.body.border.width = 0;
|
||||
sb.body.padding.inner = LV_DPI / 20;
|
||||
sb.body.padding.left = 0;
|
||||
sb.body.padding.right = 0;
|
||||
sb.body.padding.top = 0;
|
||||
sb.body.padding.bottom = 0;
|
||||
sb.body.radius = LV_DPI / 30;
|
||||
sb.body.opa = LV_OPA_COVER;
|
||||
|
||||
lv_style_copy(&panel, &bg);
|
||||
panel.body.main_color = lv_color_hsv_to_rgb(hue, 11, 18);
|
||||
panel.body.grad_color = lv_color_hsv_to_rgb(hue, 11, 18);
|
||||
panel.body.radius = LV_DPI / 20;
|
||||
panel.body.border.color = lv_color_hsv_to_rgb(hue, 10, 25);
|
||||
panel.body.border.width = 1;
|
||||
panel.body.border.opa = LV_OPA_COVER;
|
||||
panel.body.padding.left = LV_DPI / 10;
|
||||
panel.body.padding.right = LV_DPI / 10;
|
||||
panel.body.padding.top = LV_DPI / 10;
|
||||
panel.body.padding.bottom = LV_DPI / 10;
|
||||
panel.line.color = lv_color_hsv_to_rgb(hue, 20, 40);
|
||||
panel.line.width = 1;
|
||||
|
||||
theme.style.scr = &scr;
|
||||
theme.style.bg = &bg;
|
||||
theme.style.panel = &def;
|
||||
}
|
||||
|
||||
void LittleVgl::InitThemeContainer() {
|
||||
theme.style.cont = &panel;
|
||||
}
|
||||
|
||||
void LittleVgl::InitThemeButton() {
|
||||
|
||||
|
||||
lv_style_copy(&btn_rel, &def);
|
||||
btn_rel.body.main_color = lv_color_hsv_to_rgb(hue, 10, 40);
|
||||
btn_rel.body.grad_color = lv_color_hsv_to_rgb(hue, 10, 20);
|
||||
btn_rel.body.border.color = lv_color_hex3(0x111);
|
||||
btn_rel.body.border.width = 1;
|
||||
btn_rel.body.border.opa = LV_OPA_70;
|
||||
btn_rel.body.padding.left = LV_DPI / 4;
|
||||
btn_rel.body.padding.right = LV_DPI / 4;
|
||||
btn_rel.body.padding.top = LV_DPI / 8;
|
||||
btn_rel.body.padding.bottom = LV_DPI / 8;
|
||||
btn_rel.body.shadow.type = LV_SHADOW_BOTTOM;
|
||||
btn_rel.body.shadow.color = lv_color_hex3(0x111);
|
||||
btn_rel.body.shadow.width = LV_DPI / 30;
|
||||
btn_rel.text.color = lv_color_hex3(0xeee);
|
||||
btn_rel.image.color = lv_color_hex3(0xeee);
|
||||
|
||||
lv_style_copy(&btn_pr, &btn_rel);
|
||||
btn_pr.body.main_color = lv_color_hsv_to_rgb(hue, 10, 30);
|
||||
btn_pr.body.grad_color = lv_color_hsv_to_rgb(hue, 10, 10);
|
||||
|
||||
lv_style_copy(&btn_tgl_rel, &btn_rel);
|
||||
btn_tgl_rel.body.main_color = lv_color_hsv_to_rgb(hue, 10, 20);
|
||||
btn_tgl_rel.body.grad_color = lv_color_hsv_to_rgb(hue, 10, 40);
|
||||
btn_tgl_rel.body.shadow.width = LV_DPI / 40;
|
||||
btn_tgl_rel.text.color = lv_color_hex3(0xddd);
|
||||
btn_tgl_rel.image.color = lv_color_hex3(0xddd);
|
||||
|
||||
lv_style_copy(&btn_tgl_pr, &btn_rel);
|
||||
btn_tgl_pr.body.main_color = lv_color_hsv_to_rgb(hue, 10, 10);
|
||||
btn_tgl_pr.body.grad_color = lv_color_hsv_to_rgb(hue, 10, 30);
|
||||
btn_tgl_pr.body.shadow.width = LV_DPI / 30;
|
||||
btn_tgl_pr.text.color = lv_color_hex3(0xddd);
|
||||
btn_tgl_pr.image.color = lv_color_hex3(0xddd);
|
||||
|
||||
lv_style_copy(&btn_ina, &btn_rel);
|
||||
btn_ina.body.main_color = lv_color_hsv_to_rgb(hue, 10, 20);
|
||||
btn_ina.body.grad_color = lv_color_hsv_to_rgb(hue, 10, 20);
|
||||
btn_ina.body.shadow.width = 0;
|
||||
btn_ina.text.color = lv_color_hex3(0xaaa);
|
||||
btn_ina.image.color = lv_color_hex3(0xaaa);
|
||||
|
||||
theme.style.btn.rel = &btn_rel;
|
||||
theme.style.btn.pr = &btn_pr;
|
||||
theme.style.btn.tgl_rel = &btn_tgl_rel;
|
||||
theme.style.btn.tgl_pr = &btn_tgl_pr;
|
||||
theme.style.btn.ina = &btn_ina;
|
||||
}
|
||||
|
||||
void LittleVgl::InitThemeLabel() {
|
||||
lv_style_copy(&prim, &bg);
|
||||
prim.text.color = lv_color_hsv_to_rgb(hue, 5, 95);
|
||||
|
||||
lv_style_copy(&labelBigStyle, &prim);
|
||||
labelBigStyle.text.font = &jetbrains_mono_extrabold_compressed;
|
||||
LabelBigStyle = &(this->labelBigStyle);
|
||||
|
||||
lv_style_copy(&sec, &bg);
|
||||
sec.text.color = lv_color_hsv_to_rgb(hue, 15, 65);
|
||||
|
||||
lv_style_copy(&hint, &bg);
|
||||
hint.text.color = lv_color_hsv_to_rgb(hue, 20, 55);
|
||||
|
||||
theme.style.label.prim = &prim;
|
||||
theme.style.label.sec = &sec;
|
||||
theme.style.label.hint = &hint;
|
||||
}
|
||||
|
||||
void LittleVgl::InitThemeLine() {
|
||||
theme.style.line.decor = &def;
|
||||
}
|
||||
|
||||
void LittleVgl::InitThemeLed() {
|
||||
lv_style_copy(&led, &def);
|
||||
led.body.shadow.width = LV_DPI / 10;
|
||||
led.body.radius = LV_RADIUS_CIRCLE;
|
||||
led.body.border.width = LV_DPI / 30;
|
||||
led.body.border.opa = LV_OPA_30;
|
||||
led.body.main_color = lv_color_hsv_to_rgb(hue, 100, 100);
|
||||
led.body.grad_color = lv_color_hsv_to_rgb(hue, 100, 40);
|
||||
led.body.border.color = lv_color_hsv_to_rgb(hue, 60, 60);
|
||||
led.body.shadow.color = lv_color_hsv_to_rgb(hue, 100, 100);
|
||||
|
||||
theme.style.led = &led;
|
||||
}
|
||||
|
||||
void LittleVgl::InitThemeImage() {
|
||||
theme.style.img.light = &def;
|
||||
theme.style.img.dark = &def;
|
||||
}
|
||||
|
||||
void LittleVgl::InitThemeBar() {
|
||||
lv_style_copy(&bar_bg, &panel);
|
||||
bar_bg.body.padding.left = LV_DPI / 16;
|
||||
bar_bg.body.padding.right = LV_DPI / 16;
|
||||
bar_bg.body.padding.top = LV_DPI / 16;
|
||||
bar_bg.body.padding.bottom = LV_DPI / 16;
|
||||
bar_bg.body.radius = LV_RADIUS_CIRCLE;
|
||||
|
||||
lv_style_copy(&bar_indic, &def);
|
||||
bar_indic.body.main_color = lv_color_hsv_to_rgb(hue, 80, 70);
|
||||
bar_indic.body.grad_color = lv_color_hsv_to_rgb(hue, 80, 70);
|
||||
bar_indic.body.border.color = lv_color_hsv_to_rgb(hue, 20, 15);
|
||||
bar_indic.body.border.width = 1;
|
||||
bar_indic.body.border.opa = LV_OPA_COVER;
|
||||
bar_indic.body.radius = LV_RADIUS_CIRCLE;
|
||||
bar_indic.body.padding.left = 0;
|
||||
bar_indic.body.padding.right = 0;
|
||||
bar_indic.body.padding.top = 0;
|
||||
bar_indic.body.padding.bottom = 0;
|
||||
|
||||
theme.style.bar.bg = &bar_bg;
|
||||
theme.style.bar.indic = &bar_indic;
|
||||
}
|
||||
|
||||
void LittleVgl::InitThemeSlider() {
|
||||
lv_style_copy(&slider_knob, theme.style.btn.rel);
|
||||
slider_knob.body.radius = LV_RADIUS_CIRCLE;
|
||||
|
||||
theme.style.slider.bg = theme.style.bar.bg;
|
||||
theme.style.slider.indic = theme.style.bar.indic;
|
||||
theme.style.slider.knob = &slider_knob;
|
||||
}
|
||||
|
||||
void LittleVgl::InitThemeSwitch() {
|
||||
theme.style.sw.bg = theme.style.bar.bg;
|
||||
theme.style.sw.indic = theme.style.bar.indic;
|
||||
theme.style.sw.knob_off = theme.style.slider.knob;
|
||||
theme.style.sw.knob_on = theme.style.slider.knob;
|
||||
}
|
||||
|
||||
void LittleVgl::InitThemeMeter() {
|
||||
static lv_style_t lmeter_bg;
|
||||
lv_style_copy(&lmeter_bg, &def);
|
||||
lmeter_bg.body.main_color = lv_color_hsv_to_rgb(hue, 10, 70);
|
||||
lmeter_bg.body.grad_color = lv_color_hsv_to_rgb(hue, 95, 90);
|
||||
lmeter_bg.body.padding.left = LV_DPI / 10; /*Scale line length*/
|
||||
lmeter_bg.body.padding.inner = LV_DPI / 10; /*Text padding*/
|
||||
lmeter_bg.body.border.color = lv_color_hex3(0x333);
|
||||
lmeter_bg.line.color = lv_color_hex3(0x555);
|
||||
lmeter_bg.line.width = 1;
|
||||
lmeter_bg.text.color = lv_color_hex3(0xddd);
|
||||
|
||||
theme.style.lmeter = &lmeter_bg;
|
||||
}
|
||||
|
||||
void LittleVgl::InitThemeGauge() {
|
||||
static lv_style_t gauge_bg;
|
||||
lv_style_copy(&gauge_bg, &def);
|
||||
gauge_bg.body.main_color = lv_color_hsv_to_rgb(hue, 10, 70);
|
||||
gauge_bg.body.grad_color = gauge_bg.body.main_color;
|
||||
gauge_bg.line.color = lv_color_hsv_to_rgb(hue, 80, 75);
|
||||
gauge_bg.line.width = 1;
|
||||
gauge_bg.text.color = lv_color_hex3(0xddd);
|
||||
|
||||
theme.style.gauge = &gauge_bg;
|
||||
}
|
||||
|
||||
void LittleVgl::InitThemeArc() {
|
||||
lv_style_copy(&arc, &def);
|
||||
arc.line.width = 8;
|
||||
arc.line.color = lv_color_hsv_to_rgb(hue, 80, 70);
|
||||
arc.line.rounded = 1;
|
||||
|
||||
/*For preloader*/
|
||||
arc.body.border.width = 7;
|
||||
arc.body.border.color = lv_color_hsv_to_rgb(hue, 11, 48);
|
||||
arc.body.padding.left = 1;
|
||||
arc.body.padding.right = 1;
|
||||
arc.body.padding.top = 1;
|
||||
arc.body.padding.bottom = 1;
|
||||
|
||||
theme.style.arc = &arc;
|
||||
}
|
||||
|
||||
void LittleVgl::InitThemePreload() {
|
||||
// theme.style.preload = theme.style.arc;
|
||||
}
|
||||
|
||||
void LittleVgl::InitThemeChart() {
|
||||
theme.style.chart = &panel;
|
||||
}
|
||||
|
||||
void LittleVgl::InitThemeCalendar() {
|
||||
|
||||
lv_style_copy(&cal_bg, &bg);
|
||||
cal_bg.body.main_color = lv_color_hsv_to_rgb(hue, 10, 40);
|
||||
cal_bg.body.grad_color = lv_color_hsv_to_rgb(hue, 10, 40);
|
||||
cal_bg.body.border.color = lv_color_hex3(0x333);
|
||||
cal_bg.body.border.width = 1;
|
||||
cal_bg.body.radius = LV_DPI / 20;
|
||||
cal_bg.body.padding.left = LV_DPI / 10;
|
||||
cal_bg.body.padding.right = LV_DPI / 10;
|
||||
cal_bg.body.padding.top = LV_DPI / 10;
|
||||
cal_bg.body.padding.bottom = LV_DPI / 10;
|
||||
|
||||
|
||||
lv_style_copy(&cal_header, &bg);
|
||||
cal_header.body.main_color = lv_color_hsv_to_rgb(hue, 10, 20);
|
||||
cal_header.body.grad_color = lv_color_hsv_to_rgb(hue, 10, 20);
|
||||
cal_header.body.radius = 0;
|
||||
cal_header.body.border.width = 1;
|
||||
cal_header.body.border.color = lv_color_hex3(0x333);
|
||||
cal_header.body.padding.left = LV_DPI / 10;
|
||||
cal_header.body.padding.right = LV_DPI / 10;
|
||||
cal_header.body.padding.top = LV_DPI / 10;
|
||||
cal_header.body.padding.bottom = LV_DPI / 10;
|
||||
|
||||
|
||||
lv_style_copy(&week_box, &panel);
|
||||
week_box.body.main_color = lv_color_hsv_to_rgb(hue, 30, 45);
|
||||
week_box.body.grad_color = lv_color_hsv_to_rgb(hue, 30, 45);
|
||||
week_box.body.radius = LV_DPI / 20;
|
||||
week_box.body.border.width = 1;
|
||||
week_box.body.padding.left = LV_DPI / 20;
|
||||
week_box.body.padding.right = LV_DPI / 20;
|
||||
week_box.body.padding.top = LV_DPI / 25;
|
||||
week_box.body.padding.bottom = LV_DPI / 25;
|
||||
|
||||
lv_style_copy(&today_box, &week_box);
|
||||
today_box.body.main_color = lv_color_hsv_to_rgb(hue, 80, 70);
|
||||
today_box.body.grad_color = lv_color_hsv_to_rgb(hue, 80, 70);
|
||||
today_box.body.radius = LV_DPI / 20;
|
||||
today_box.body.padding.left = LV_DPI / 14;
|
||||
today_box.body.padding.right = LV_DPI / 14;
|
||||
today_box.body.padding.top = LV_DPI / 14;
|
||||
today_box.body.padding.bottom = LV_DPI / 14;
|
||||
|
||||
lv_style_copy(&highlighted_days, &bg);
|
||||
highlighted_days.text.color = lv_color_hsv_to_rgb(hue, 40, 80);
|
||||
|
||||
lv_style_copy(&ina_days, &bg);
|
||||
ina_days.text.color = lv_color_hsv_to_rgb(hue, 0, 60);
|
||||
|
||||
theme.style.calendar.bg = &cal_bg;
|
||||
theme.style.calendar.header = &cal_header;
|
||||
theme.style.calendar.week_box = &week_box;
|
||||
theme.style.calendar.today_box = &today_box;
|
||||
theme.style.calendar.highlighted_days = &highlighted_days;
|
||||
theme.style.calendar.day_names = &cal_bg;
|
||||
theme.style.calendar.inactive_days = &ina_days;
|
||||
}
|
||||
|
||||
void LittleVgl::InitThemeCheckBox() {
|
||||
|
||||
lv_style_copy(&rel, &def);
|
||||
rel.body.radius = LV_DPI / 20;
|
||||
rel.body.main_color = lv_color_hsv_to_rgb(hue, 10, 95);
|
||||
rel.body.grad_color = lv_color_hsv_to_rgb(hue, 10, 95);
|
||||
rel.body.border.color = lv_color_hsv_to_rgb(hue, 10, 50);
|
||||
rel.body.border.width = 2;
|
||||
;
|
||||
|
||||
lv_style_copy(&pr, &rel);
|
||||
pr.body.main_color = lv_color_hsv_to_rgb(hue, 10, 80);
|
||||
pr.body.grad_color = lv_color_hsv_to_rgb(hue, 10, 80);
|
||||
pr.body.border.color = lv_color_hsv_to_rgb(hue, 10, 20);
|
||||
pr.body.border.width = 1;
|
||||
;
|
||||
|
||||
lv_style_copy(&tgl_rel, &rel);
|
||||
tgl_rel.body.main_color = lv_color_hsv_to_rgb(hue, 80, 90);
|
||||
tgl_rel.body.grad_color = lv_color_hsv_to_rgb(hue, 80, 90);
|
||||
tgl_rel.body.border.color = lv_color_hsv_to_rgb(hue, 80, 50);
|
||||
|
||||
lv_style_copy(&tgl_pr, &tgl_rel);
|
||||
tgl_pr.body.main_color = lv_color_hsv_to_rgb(hue, 80, 70);
|
||||
tgl_pr.body.grad_color = lv_color_hsv_to_rgb(hue, 80, 70);
|
||||
tgl_pr.body.border.color = lv_color_hsv_to_rgb(hue, 80, 30);
|
||||
tgl_pr.body.border.width = 1;
|
||||
;
|
||||
|
||||
lv_style_copy(&ina, &rel);
|
||||
ina.body.main_color = lv_color_hex3(0x777);
|
||||
ina.body.grad_color = lv_color_hex3(0x777);
|
||||
ina.body.border.width = 0;
|
||||
|
||||
theme.style.cb.bg = &lv_style_transp;
|
||||
theme.style.cb.box.rel = &rel;
|
||||
theme.style.cb.box.pr = ≺
|
||||
theme.style.cb.box.tgl_rel = &tgl_rel;
|
||||
theme.style.cb.box.tgl_pr = &tgl_pr;
|
||||
theme.style.cb.box.ina = &def;
|
||||
}
|
||||
|
||||
void LittleVgl::InitThemeButtonMatrix() {
|
||||
|
||||
lv_style_copy(&btnm_bg, theme.style.btn.rel);
|
||||
btnm_bg.body.padding.left = 2;
|
||||
btnm_bg.body.padding.right = 2;
|
||||
btnm_bg.body.padding.top = 2;
|
||||
btnm_bg.body.padding.bottom = 2;
|
||||
btnm_bg.body.padding.inner = 0;
|
||||
btnm_bg.body.border.width = 1;
|
||||
|
||||
lv_style_copy(&btnm_rel, theme.style.btn.rel);
|
||||
btnm_rel.body.border.part = LV_BORDER_FULL | LV_BORDER_INTERNAL;
|
||||
btnm_rel.body.border.width = 1;
|
||||
btnm_rel.body.radius = 2;
|
||||
|
||||
lv_style_copy(&btnm_pr, theme.style.btn.pr);
|
||||
btnm_pr.body.border.part = btnm_rel.body.border.part;
|
||||
btnm_pr.body.border.width = btnm_rel.body.border.width;
|
||||
btnm_pr.body.radius = btnm_rel.body.radius;
|
||||
|
||||
lv_style_copy(&btnm_tgl_rel, theme.style.btn.tgl_rel);
|
||||
btnm_tgl_rel.body.border.part = btnm_rel.body.border.part;
|
||||
btnm_tgl_rel.body.border.width = btnm_rel.body.border.width;
|
||||
btnm_tgl_rel.body.radius = btnm_rel.body.radius;
|
||||
|
||||
lv_style_copy(&btnm_tgl_pr, theme.style.btn.pr);
|
||||
btnm_tgl_pr.body.border.part = btnm_rel.body.border.part;
|
||||
btnm_tgl_pr.body.border.width = btnm_rel.body.border.width;
|
||||
btnm_tgl_pr.body.radius = btnm_rel.body.radius;
|
||||
|
||||
lv_style_copy(&btnm_ina, theme.style.btn.ina);
|
||||
btnm_ina.body.border.part = btnm_rel.body.border.part;
|
||||
btnm_ina.body.border.width = btnm_rel.body.border.width;
|
||||
btnm_ina.body.radius = btnm_rel.body.radius;
|
||||
|
||||
theme.style.btnm.bg = &btnm_bg;
|
||||
theme.style.btnm.btn.rel = &btnm_rel;
|
||||
theme.style.btnm.btn.pr = &btnm_pr;
|
||||
theme.style.btnm.btn.tgl_rel = &btnm_tgl_rel;
|
||||
theme.style.btnm.btn.tgl_pr = &btnm_tgl_pr;
|
||||
theme.style.btnm.btn.ina = &btnm_ina;
|
||||
}
|
||||
|
||||
void LittleVgl::InitThemeKnob() {
|
||||
theme.style.kb.bg = &bg;
|
||||
theme.style.kb.btn.rel = theme.style.btn.rel;
|
||||
theme.style.kb.btn.pr = theme.style.btn.pr;
|
||||
theme.style.kb.btn.tgl_rel = theme.style.btn.tgl_rel;
|
||||
theme.style.kb.btn.tgl_pr = theme.style.btn.tgl_pr;
|
||||
theme.style.kb.btn.ina = theme.style.btn.ina;
|
||||
}
|
||||
|
||||
void LittleVgl::InitThemeMessageBox() {
|
||||
lv_style_copy(&mbox_bg, &bg);
|
||||
mbox_bg.body.main_color = lv_color_hsv_to_rgb(hue, 30, 30);
|
||||
mbox_bg.body.grad_color = lv_color_hsv_to_rgb(hue, 30, 30);
|
||||
mbox_bg.body.border.color = lv_color_hsv_to_rgb(hue, 11, 20);
|
||||
mbox_bg.body.border.width = 1;
|
||||
mbox_bg.body.shadow.width = LV_DPI / 10;
|
||||
mbox_bg.body.shadow.color = lv_color_hex3(0x222);
|
||||
mbox_bg.body.radius = LV_DPI / 20;
|
||||
theme.style.mbox.bg = &mbox_bg;
|
||||
theme.style.mbox.btn.bg = &lv_style_transp;
|
||||
theme.style.mbox.btn.rel = theme.style.btn.rel;
|
||||
theme.style.mbox.btn.pr = theme.style.btn.pr;
|
||||
}
|
||||
|
||||
void LittleVgl::InitThemePage() {
|
||||
lv_style_copy(&page_scrl, &bg);
|
||||
page_scrl.body.main_color = lv_color_hsv_to_rgb(hue, 10, 40);
|
||||
page_scrl.body.grad_color = lv_color_hsv_to_rgb(hue, 10, 40);
|
||||
page_scrl.body.border.color = lv_color_hex3(0x333);
|
||||
page_scrl.body.border.width = 1;
|
||||
page_scrl.body.radius = LV_DPI / 20;
|
||||
|
||||
theme.style.page.bg = &panel;
|
||||
theme.style.page.scrl = &page_scrl;
|
||||
theme.style.page.sb = &sb;
|
||||
}
|
||||
|
||||
void LittleVgl::InitThemeTextArea() {
|
||||
theme.style.ta.area = &panel;
|
||||
theme.style.ta.oneline = &panel;
|
||||
theme.style.ta.cursor = NULL;
|
||||
theme.style.ta.sb = &def;
|
||||
}
|
||||
|
||||
void LittleVgl::InitThemeSpinBox() {
|
||||
theme.style.spinbox.bg = &panel;
|
||||
theme.style.spinbox.cursor = theme.style.ta.cursor;
|
||||
theme.style.spinbox.sb = theme.style.ta.sb;
|
||||
}
|
||||
|
||||
void LittleVgl::InitThemeList() {
|
||||
|
||||
lv_style_copy(&list_bg, &panel);
|
||||
list_bg.body.padding.top = 0;
|
||||
list_bg.body.padding.bottom = 0;
|
||||
list_bg.body.padding.left = 0;
|
||||
list_bg.body.padding.right = 0;
|
||||
list_bg.body.padding.inner = 0;
|
||||
|
||||
lv_style_copy(&list_btn_rel, &bg);
|
||||
list_btn_rel.body.opa = LV_OPA_TRANSP;
|
||||
list_btn_rel.body.border.part = LV_BORDER_BOTTOM;
|
||||
list_btn_rel.body.border.color = lv_color_hsv_to_rgb(hue, 10, 5);
|
||||
list_btn_rel.body.border.width = 1;
|
||||
list_btn_rel.body.radius = LV_DPI / 10;
|
||||
list_btn_rel.text.color = lv_color_hsv_to_rgb(hue, 5, 80);
|
||||
list_btn_rel.image.color = lv_color_hsv_to_rgb(hue, 5, 80);
|
||||
list_btn_rel.body.padding.top = LV_DPI / 6;
|
||||
list_btn_rel.body.padding.bottom = LV_DPI / 6;
|
||||
list_btn_rel.body.padding.left = LV_DPI / 8;
|
||||
list_btn_rel.body.padding.right = LV_DPI / 8;
|
||||
|
||||
lv_style_copy(&list_btn_pr, theme.style.btn.pr);
|
||||
list_btn_pr.body.main_color = lv_color_hsv_to_rgb(hue, 10, 5);
|
||||
list_btn_pr.body.grad_color = lv_color_hsv_to_rgb(hue, 10, 5);
|
||||
list_btn_pr.body.border.color = lv_color_hsv_to_rgb(hue, 10, 5);
|
||||
list_btn_pr.body.border.width = 0;
|
||||
list_btn_pr.body.padding.top = LV_DPI / 6;
|
||||
list_btn_pr.body.padding.bottom = LV_DPI / 6;
|
||||
list_btn_pr.body.padding.left = LV_DPI / 8;
|
||||
list_btn_pr.body.padding.right = LV_DPI / 8;
|
||||
list_btn_pr.text.color = lv_color_hsv_to_rgb(hue, 5, 80);
|
||||
list_btn_pr.image.color = lv_color_hsv_to_rgb(hue, 5, 80);
|
||||
|
||||
lv_style_copy(&list_btn_tgl_rel, &list_btn_rel);
|
||||
list_btn_tgl_rel.body.opa = LV_OPA_COVER;
|
||||
list_btn_tgl_rel.body.main_color = lv_color_hsv_to_rgb(hue, 80, 70);
|
||||
list_btn_tgl_rel.body.grad_color = lv_color_hsv_to_rgb(hue, 80, 70);
|
||||
list_btn_tgl_rel.body.border.color = lv_color_hsv_to_rgb(hue, 60, 40);
|
||||
list_btn_tgl_rel.body.radius = list_bg.body.radius;
|
||||
|
||||
lv_style_copy(&list_btn_tgl_pr, &list_btn_tgl_rel);
|
||||
list_btn_tgl_pr.body.main_color = lv_color_hsv_to_rgb(hue, 80, 60);
|
||||
list_btn_tgl_pr.body.grad_color = lv_color_hsv_to_rgb(hue, 80, 60);
|
||||
|
||||
theme.style.list.sb = &sb;
|
||||
theme.style.list.bg = &list_bg;
|
||||
theme.style.list.scrl = &lv_style_transp_tight;
|
||||
theme.style.list.btn.rel = &list_btn_rel;
|
||||
theme.style.list.btn.pr = &list_btn_pr;
|
||||
theme.style.list.btn.tgl_rel = &list_btn_tgl_rel;
|
||||
theme.style.list.btn.tgl_pr = &list_btn_tgl_pr;
|
||||
theme.style.list.btn.ina = &def;
|
||||
}
|
||||
|
||||
void LittleVgl::InitThemeDropDownList() {
|
||||
lv_style_copy(&ddlist_bg, theme.style.btn.rel);
|
||||
ddlist_bg.text.line_space = LV_DPI / 8;
|
||||
ddlist_bg.body.padding.top = LV_DPI / 8;
|
||||
ddlist_bg.body.padding.bottom = LV_DPI / 8;
|
||||
ddlist_bg.body.padding.left = LV_DPI / 8;
|
||||
ddlist_bg.body.padding.right = LV_DPI / 8;
|
||||
ddlist_bg.body.radius = LV_DPI / 30;
|
||||
|
||||
lv_style_copy(&ddlist_sel, theme.style.btn.rel);
|
||||
ddlist_sel.body.main_color = lv_color_hsv_to_rgb(hue, 20, 50);
|
||||
ddlist_sel.body.grad_color = lv_color_hsv_to_rgb(hue, 20, 50);
|
||||
ddlist_sel.body.radius = 0;
|
||||
|
||||
theme.style.ddlist.bg = &ddlist_bg;
|
||||
theme.style.ddlist.sel = &ddlist_sel;
|
||||
theme.style.ddlist.sb = &def;
|
||||
}
|
||||
|
||||
void LittleVgl::InitThemeRoller() {
|
||||
lv_style_t roller_bg;
|
||||
|
||||
lv_style_copy(&roller_bg, theme.style.ddlist.bg);
|
||||
roller_bg.body.main_color = lv_color_hsv_to_rgb(hue, 10, 20);
|
||||
roller_bg.body.grad_color = lv_color_hsv_to_rgb(hue, 10, 40);
|
||||
roller_bg.text.color = lv_color_hsv_to_rgb(hue, 5, 70);
|
||||
roller_bg.text.opa = LV_OPA_60;
|
||||
|
||||
theme.style.roller.bg = &roller_bg;
|
||||
theme.style.roller.sel = theme.style.ddlist.sel;
|
||||
}
|
||||
|
||||
void LittleVgl::InitThemeTabView() {
|
||||
theme.style.tabview.bg = &bg;
|
||||
theme.style.tabview.indic = &lv_style_transp;
|
||||
theme.style.tabview.btn.bg = &lv_style_transp;
|
||||
theme.style.tabview.btn.rel = theme.style.btn.rel;
|
||||
theme.style.tabview.btn.pr = theme.style.btn.pr;
|
||||
theme.style.tabview.btn.tgl_rel = theme.style.btn.tgl_rel;
|
||||
theme.style.tabview.btn.tgl_pr = theme.style.btn.tgl_pr;
|
||||
}
|
||||
|
||||
void LittleVgl::InitThemeTileView() {
|
||||
theme.style.tileview.bg = &lv_style_transp_tight;
|
||||
theme.style.tileview.scrl = &lv_style_transp_tight;
|
||||
theme.style.tileview.sb = theme.style.page.sb;
|
||||
}
|
||||
|
||||
void LittleVgl::InitThemeTable() {
|
||||
lv_style_copy(&cell, &panel);
|
||||
cell.body.radius = 0;
|
||||
cell.body.border.width = 1;
|
||||
cell.body.padding.left = LV_DPI / 12;
|
||||
cell.body.padding.right = LV_DPI / 12;
|
||||
cell.body.padding.top = LV_DPI / 12;
|
||||
cell.body.padding.bottom = LV_DPI / 12;
|
||||
|
||||
theme.style.table.bg = &lv_style_transp_tight;
|
||||
theme.style.table.cell = &cell;
|
||||
}
|
||||
|
||||
void LittleVgl::InitThemeWindow() {
|
||||
// lv_style_copy(&win_bg, &bg);
|
||||
// win_bg.body.border.color = lv_color_hex3(0x333);
|
||||
// win_bg.body.border.width = 1;
|
||||
//
|
||||
// lv_style_copy(&win_header, &win_bg);
|
||||
// win_header.body.main_color = lv_color_hsv_to_rgb(hue, 10, 20);
|
||||
// win_header.body.grad_color = lv_color_hsv_to_rgb(hue, 10, 20);
|
||||
// win_header.body.radius = 0;
|
||||
// win_header.body.padding.left = 0;
|
||||
// win_header.body.padding.right = 0;
|
||||
// win_header.body.padding.top = 0;
|
||||
// win_header.body.padding.bottom = 0;
|
||||
//
|
||||
// lv_style_copy(&win_btn_pr, &def);
|
||||
// win_btn_pr.body.main_color = lv_color_hsv_to_rgb(hue, 10, 10);
|
||||
// win_btn_pr.body.grad_color = lv_color_hsv_to_rgb(hue, 10, 10);
|
||||
// win_btn_pr.text.color = lv_color_hex3(0xaaa);
|
||||
// win_btn_pr.image.color = lv_color_hex3(0xaaa);
|
||||
//
|
||||
// theme.style.win.bg = &win_bg;
|
||||
// theme.style.win.sb = &sb;
|
||||
// theme.style.win.header = &win_header;
|
||||
// theme.style.win.content = &lv_style_transp;
|
||||
// theme.style.win.btn.rel = &lv_style_transp;
|
||||
// theme.style.win.btn.pr = &win_btn_pr;
|
||||
}
|
||||
|
@ -28,36 +28,7 @@ namespace Pinetime {
|
||||
void InitDisplay();
|
||||
void InitTouchpad();
|
||||
void InitTheme();
|
||||
void InitBaseTheme();
|
||||
void InitThemeContainer();
|
||||
void InitThemeButton();
|
||||
void InitThemeLabel();
|
||||
void InitThemeLine();
|
||||
void InitThemeLed();
|
||||
void InitThemeImage();
|
||||
void InitThemeBar();
|
||||
void InitThemeSlider();
|
||||
void InitThemeSwitch();
|
||||
void InitThemeMeter();
|
||||
void InitThemeGauge();
|
||||
void InitThemeArc();
|
||||
void InitThemePreload();
|
||||
void InitThemeChart();
|
||||
void InitThemeCalendar();
|
||||
void InitThemeCheckBox();
|
||||
void InitThemeButtonMatrix();
|
||||
void InitThemeKnob();
|
||||
void InitThemeMessageBox();
|
||||
void InitThemePage();
|
||||
void InitThemeTextArea();
|
||||
void InitThemeSpinBox();
|
||||
void InitThemeList();
|
||||
void InitThemeDropDownList();
|
||||
void InitThemeRoller();
|
||||
void InitThemeTabView();
|
||||
void InitThemeTileView();
|
||||
void InitThemeTable();
|
||||
void InitThemeWindow();
|
||||
|
||||
|
||||
Pinetime::Drivers::St7789& lcd;
|
||||
Pinetime::Drivers::Cst816S& touchPanel;
|
||||
@ -70,35 +41,6 @@ namespace Pinetime {
|
||||
lv_disp_drv_t disp_drv;
|
||||
lv_point_t previousClick;
|
||||
|
||||
lv_style_t def;
|
||||
lv_style_t scr, bg, sb, panel;
|
||||
lv_font_t * font = nullptr;
|
||||
uint16_t hue = 10;
|
||||
lv_theme_t theme;
|
||||
lv_style_t btn_rel, btn_pr, btn_tgl_rel, btn_tgl_pr, btn_ina;
|
||||
lv_style_t labelBigStyle;
|
||||
lv_style_t prim, sec, hint;
|
||||
lv_style_t led;
|
||||
lv_style_t bar_bg, bar_indic;
|
||||
lv_style_t slider_knob;
|
||||
lv_style_t arc;
|
||||
lv_style_t cal_bg;
|
||||
lv_style_t cal_header;
|
||||
lv_style_t week_box;
|
||||
lv_style_t today_box;
|
||||
lv_style_t highlighted_days;
|
||||
lv_style_t ina_days;
|
||||
lv_style_t rel, pr, tgl_rel, tgl_pr, ina;
|
||||
lv_style_t btnm_bg, btnm_rel, btnm_pr, btnm_tgl_rel, btnm_tgl_pr, btnm_ina;
|
||||
lv_style_t mbox_bg;
|
||||
lv_style_t page_scrl;
|
||||
lv_style_t list_bg, list_btn_rel, list_btn_pr, list_btn_tgl_rel, list_btn_tgl_pr;
|
||||
lv_style_t ddlist_bg, ddlist_sel;
|
||||
lv_style_t cell;
|
||||
lv_style_t win_bg;
|
||||
lv_style_t win_header;
|
||||
lv_style_t win_btn_pr;
|
||||
|
||||
bool firstTouch = true;
|
||||
static constexpr uint8_t nbWriteLines = 4;
|
||||
static constexpr uint16_t totalNbLines = 320;
|
||||
|
482
src/displayapp/lv_pinetime_theme.c
Normal file
482
src/displayapp/lv_pinetime_theme.c
Normal file
@ -0,0 +1,482 @@
|
||||
/**
|
||||
* @file lv_pinetime_theme.c
|
||||
*
|
||||
*/
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "lv_pinetime_theme.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
static void theme_apply(lv_obj_t * obj, lv_theme_style_t name);
|
||||
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
**********************/
|
||||
static lv_theme_t theme;
|
||||
|
||||
static lv_style_t style_pad;
|
||||
static lv_style_t style_circle;
|
||||
|
||||
static lv_style_t style_bg;
|
||||
static lv_style_t style_box;
|
||||
static lv_style_t style_box_border;
|
||||
static lv_style_t style_btn;
|
||||
static lv_style_t style_btn_border;
|
||||
static lv_style_t style_title;
|
||||
static lv_style_t style_label_white;
|
||||
static lv_style_t style_back;
|
||||
static lv_style_t style_icon;
|
||||
static lv_style_t style_bar_indic;
|
||||
static lv_style_t style_slider_knob;
|
||||
static lv_style_t style_scrollbar;
|
||||
static lv_style_t style_list_btn;
|
||||
static lv_style_t style_ddlist_list;
|
||||
static lv_style_t style_ddlist_selected;
|
||||
static lv_style_t style_sw_bg;
|
||||
static lv_style_t style_sw_indic;
|
||||
static lv_style_t style_sw_knob;
|
||||
static lv_style_t style_arc_bg;
|
||||
static lv_style_t style_arc_indic;
|
||||
static lv_style_t style_table_cell;
|
||||
static lv_style_t style_pad_small;
|
||||
static lv_style_t style_bg_grad;
|
||||
static lv_style_t style_lmeter;
|
||||
|
||||
static bool inited;
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
|
||||
static void style_init_reset(lv_style_t * style)
|
||||
{
|
||||
if(inited) lv_style_reset(style);
|
||||
else lv_style_init(style);
|
||||
}
|
||||
|
||||
|
||||
static void basic_init(void)
|
||||
{
|
||||
|
||||
style_init_reset(&style_pad);
|
||||
lv_style_set_pad_top(&style_pad, LV_STATE_DEFAULT, LV_VER_RES / 30);
|
||||
lv_style_set_pad_bottom(&style_pad, LV_STATE_DEFAULT, LV_VER_RES / 30);
|
||||
lv_style_set_pad_left(&style_pad, LV_STATE_DEFAULT, LV_VER_RES / 40);
|
||||
lv_style_set_pad_right(&style_pad, LV_STATE_DEFAULT, LV_VER_RES / 40);
|
||||
|
||||
style_init_reset(&style_circle);
|
||||
lv_style_set_radius(&style_circle, LV_STATE_DEFAULT, LV_RADIUS_CIRCLE);
|
||||
|
||||
style_init_reset(&style_bg);
|
||||
lv_style_set_bg_opa(&style_bg, LV_STATE_DEFAULT, LV_OPA_COVER);
|
||||
lv_style_set_bg_color(&style_bg, LV_STATE_DEFAULT, LV_COLOR_BLACK);
|
||||
lv_style_set_text_font(&style_bg, LV_STATE_DEFAULT, theme.font_normal);
|
||||
|
||||
style_init_reset(&style_box);
|
||||
lv_style_set_bg_opa(&style_box, LV_STATE_DEFAULT, LV_OPA_COVER);
|
||||
lv_style_set_radius(&style_box, LV_STATE_DEFAULT, 10);
|
||||
lv_style_set_value_color(&style_box, LV_STATE_DEFAULT, LV_PINETIME_BLUE);
|
||||
lv_style_set_value_font(&style_box, LV_STATE_DEFAULT, theme.font_normal);
|
||||
|
||||
style_init_reset(&style_box_border);
|
||||
lv_style_set_bg_opa(&style_box_border, LV_STATE_DEFAULT, LV_OPA_TRANSP);
|
||||
lv_style_set_border_width(&style_box_border, LV_STATE_DEFAULT, 2);
|
||||
lv_style_set_border_color(&style_box_border, LV_STATE_DEFAULT, LV_PINETIME_GRAY);
|
||||
lv_style_set_text_color(&style_box, LV_STATE_DEFAULT, LV_PINETIME_BLUE);
|
||||
|
||||
|
||||
style_init_reset(&style_title);
|
||||
lv_style_set_text_color(&style_title, LV_STATE_DEFAULT, LV_PINETIME_WHITE);
|
||||
lv_style_set_text_font(&style_title, LV_STATE_DEFAULT, theme.font_subtitle);
|
||||
|
||||
style_init_reset(&style_label_white);
|
||||
lv_style_set_text_color(&style_label_white, LV_STATE_DEFAULT, LV_PINETIME_WHITE);
|
||||
|
||||
style_init_reset(&style_btn);
|
||||
lv_style_set_radius(&style_btn, LV_STATE_DEFAULT, 10);
|
||||
lv_style_set_bg_opa(&style_btn, LV_STATE_DEFAULT, LV_OPA_COVER);
|
||||
lv_style_set_bg_color(&style_btn, LV_STATE_DEFAULT, LV_PINETIME_GRAY);
|
||||
lv_style_set_text_color(&style_btn, LV_STATE_DEFAULT, LV_PINETIME_WHITE);
|
||||
lv_style_set_value_color(&style_btn, LV_STATE_DEFAULT, LV_PINETIME_WHITE);
|
||||
lv_style_set_pad_top(&style_btn, LV_STATE_DEFAULT, LV_VER_RES / 40);
|
||||
lv_style_set_pad_bottom(&style_btn, LV_STATE_DEFAULT, LV_VER_RES / 40);
|
||||
|
||||
lv_style_set_pad_left(&style_btn, LV_STATE_DEFAULT, LV_DPX(15));
|
||||
lv_style_set_pad_right(&style_btn, LV_STATE_DEFAULT, LV_DPX(15));
|
||||
lv_style_set_pad_top(&style_btn, LV_STATE_DEFAULT, LV_DPX(10));
|
||||
lv_style_set_pad_bottom(&style_btn, LV_STATE_DEFAULT, LV_DPX(10));
|
||||
lv_style_set_pad_inner(&style_btn, LV_STATE_DEFAULT, LV_DPX(5));
|
||||
lv_style_set_outline_width(&style_btn, LV_STATE_DEFAULT, LV_DPX(2));
|
||||
|
||||
|
||||
style_init_reset(&style_btn_border);
|
||||
lv_style_set_radius(&style_btn_border, LV_STATE_DEFAULT, LV_RADIUS_CIRCLE);
|
||||
lv_style_set_border_color(&style_btn_border, LV_STATE_DEFAULT, LV_PINETIME_WHITE);
|
||||
lv_style_set_border_width(&style_btn_border, LV_STATE_DEFAULT, 2);
|
||||
lv_style_set_bg_opa(&style_btn_border, LV_STATE_DEFAULT, LV_OPA_TRANSP);
|
||||
lv_style_set_bg_color(&style_btn_border, LV_STATE_DEFAULT, LV_PINETIME_WHITE);
|
||||
lv_style_set_text_color(&style_btn_border, LV_STATE_DEFAULT, LV_PINETIME_WHITE);
|
||||
lv_style_set_value_color(&style_btn_border, LV_STATE_DEFAULT, LV_PINETIME_WHITE);
|
||||
lv_style_set_transition_prop_3(&style_btn_border, LV_STATE_DEFAULT, LV_STYLE_BG_OPA);
|
||||
|
||||
style_init_reset(&style_icon);
|
||||
lv_style_set_text_color(&style_icon, LV_STATE_DEFAULT, LV_PINETIME_WHITE);
|
||||
|
||||
style_init_reset(&style_back);
|
||||
lv_style_set_value_color(&style_back, LV_STATE_DEFAULT, LV_PINETIME_GRAY);
|
||||
lv_style_set_value_str(&style_back, LV_STATE_DEFAULT, LV_SYMBOL_LEFT);
|
||||
lv_style_set_value_font(&style_back, LV_STATE_DEFAULT, theme.font_subtitle);
|
||||
|
||||
style_init_reset(&style_bar_indic);
|
||||
lv_style_set_bg_opa(&style_bar_indic, LV_STATE_DEFAULT, LV_OPA_COVER);
|
||||
lv_style_set_radius(&style_bar_indic, LV_STATE_DEFAULT, 10);
|
||||
|
||||
style_init_reset(&style_scrollbar);
|
||||
lv_style_set_bg_opa(&style_scrollbar, LV_STATE_DEFAULT, LV_OPA_COVER);
|
||||
lv_style_set_radius(&style_scrollbar, LV_STATE_DEFAULT, LV_RADIUS_CIRCLE);
|
||||
lv_style_set_bg_color(&style_scrollbar, LV_STATE_DEFAULT, LV_PINETIME_LIGHT_GRAY);
|
||||
lv_style_set_size(&style_scrollbar, LV_STATE_DEFAULT, LV_HOR_RES / 80);
|
||||
lv_style_set_pad_right(&style_scrollbar, LV_STATE_DEFAULT, LV_HOR_RES / 60);
|
||||
|
||||
style_init_reset(&style_list_btn);
|
||||
lv_style_set_bg_opa(&style_list_btn, LV_STATE_DEFAULT, LV_OPA_COVER);
|
||||
lv_style_set_bg_color(&style_list_btn, LV_STATE_DEFAULT, LV_PINETIME_WHITE);
|
||||
lv_style_set_bg_color(&style_list_btn, LV_STATE_CHECKED, LV_PINETIME_GRAY);
|
||||
lv_style_set_bg_color(&style_list_btn, LV_STATE_CHECKED | LV_STATE_PRESSED, lv_color_darken(LV_PINETIME_GRAY, LV_OPA_20));
|
||||
lv_style_set_text_color(&style_list_btn, LV_STATE_DEFAULT, LV_PINETIME_BLUE);
|
||||
lv_style_set_text_color(&style_list_btn, LV_STATE_CHECKED, LV_PINETIME_WHITE);
|
||||
lv_style_set_text_color(&style_list_btn, LV_STATE_CHECKED | LV_STATE_PRESSED, LV_PINETIME_WHITE);
|
||||
lv_style_set_image_recolor(&style_list_btn, LV_STATE_DEFAULT, LV_PINETIME_BLUE);
|
||||
lv_style_set_image_recolor(&style_list_btn, LV_STATE_CHECKED, LV_PINETIME_WHITE);
|
||||
lv_style_set_image_recolor(&style_list_btn, LV_STATE_CHECKED | LV_STATE_PRESSED, LV_PINETIME_WHITE);
|
||||
lv_style_set_pad_left(&style_list_btn, LV_STATE_DEFAULT, LV_HOR_RES / 25);
|
||||
lv_style_set_pad_right(&style_list_btn, LV_STATE_DEFAULT, LV_HOR_RES / 25);
|
||||
lv_style_set_pad_top(&style_list_btn, LV_STATE_DEFAULT, LV_HOR_RES / 100);
|
||||
lv_style_set_pad_bottom(&style_list_btn, LV_STATE_DEFAULT, LV_HOR_RES / 100);
|
||||
lv_style_set_pad_inner(&style_list_btn, LV_STATE_DEFAULT, LV_HOR_RES / 50);
|
||||
|
||||
style_init_reset(&style_ddlist_list);
|
||||
lv_style_set_text_line_space(&style_ddlist_list, LV_STATE_DEFAULT, LV_VER_RES / 25);
|
||||
lv_style_set_shadow_width(&style_ddlist_list, LV_STATE_DEFAULT, LV_VER_RES / 20);
|
||||
lv_style_set_shadow_color(&style_ddlist_list, LV_STATE_DEFAULT, LV_PINETIME_GRAY);
|
||||
|
||||
style_init_reset(&style_ddlist_selected);
|
||||
lv_style_set_bg_opa(&style_ddlist_selected, LV_STATE_DEFAULT, LV_OPA_COVER);
|
||||
lv_style_set_bg_color(&style_ddlist_selected, LV_STATE_DEFAULT, LV_PINETIME_BLUE);
|
||||
|
||||
style_init_reset(&style_sw_bg);
|
||||
lv_style_set_bg_opa(&style_sw_bg, LV_STATE_DEFAULT, LV_OPA_COVER);
|
||||
lv_style_set_bg_color(&style_sw_bg, LV_STATE_DEFAULT, LV_PINETIME_LIGHT_GRAY);
|
||||
lv_style_set_radius(&style_sw_bg, LV_STATE_DEFAULT, LV_RADIUS_CIRCLE);
|
||||
lv_style_set_value_color(&style_sw_bg, LV_STATE_DEFAULT, LV_PINETIME_BLUE);
|
||||
|
||||
style_init_reset(&style_sw_indic);
|
||||
lv_style_set_bg_opa(&style_sw_indic, LV_STATE_DEFAULT, LV_OPA_COVER);
|
||||
lv_style_set_bg_color(&style_sw_indic, LV_STATE_DEFAULT, LV_PINETIME_GREEN);
|
||||
|
||||
style_init_reset(&style_sw_knob);
|
||||
lv_style_set_bg_opa(&style_sw_knob, LV_STATE_DEFAULT, LV_OPA_COVER);
|
||||
lv_style_set_bg_color(&style_sw_knob, LV_STATE_DEFAULT, LV_PINETIME_WHITE);
|
||||
lv_style_set_radius(&style_sw_knob, LV_STATE_DEFAULT, LV_RADIUS_CIRCLE);
|
||||
lv_style_set_pad_top(&style_sw_knob, LV_STATE_DEFAULT, - 4);
|
||||
lv_style_set_pad_bottom(&style_sw_knob, LV_STATE_DEFAULT, - 4);
|
||||
lv_style_set_pad_left(&style_sw_knob, LV_STATE_DEFAULT, - 4);
|
||||
lv_style_set_pad_right(&style_sw_knob, LV_STATE_DEFAULT, - 4);
|
||||
|
||||
style_init_reset(&style_slider_knob);
|
||||
lv_style_set_bg_opa(&style_slider_knob, LV_STATE_DEFAULT, LV_OPA_COVER);
|
||||
lv_style_set_bg_color(&style_slider_knob, LV_STATE_DEFAULT, LV_COLOR_RED);
|
||||
lv_style_set_border_color(&style_slider_knob, LV_STATE_DEFAULT, LV_COLOR_WHITE);
|
||||
lv_style_set_border_width(&style_slider_knob, LV_STATE_DEFAULT, 6);
|
||||
lv_style_set_radius(&style_slider_knob, LV_STATE_DEFAULT, LV_RADIUS_CIRCLE);
|
||||
lv_style_set_pad_top(&style_slider_knob, LV_STATE_DEFAULT, 10);
|
||||
lv_style_set_pad_bottom(&style_slider_knob, LV_STATE_DEFAULT, 10);
|
||||
lv_style_set_pad_left(&style_slider_knob, LV_STATE_DEFAULT, 10);
|
||||
lv_style_set_pad_right(&style_slider_knob, LV_STATE_DEFAULT, 10);
|
||||
lv_style_set_pad_top(&style_slider_knob, LV_STATE_PRESSED, 14);
|
||||
lv_style_set_pad_bottom(&style_slider_knob, LV_STATE_PRESSED, 14);
|
||||
lv_style_set_pad_left(&style_slider_knob, LV_STATE_PRESSED, 14);
|
||||
lv_style_set_pad_right(&style_slider_knob, LV_STATE_PRESSED, 14);
|
||||
|
||||
style_init_reset(&style_arc_indic);
|
||||
lv_style_set_line_color(&style_arc_indic, LV_STATE_DEFAULT, LV_PINETIME_BLUE);
|
||||
lv_style_set_line_width(&style_arc_indic, LV_STATE_DEFAULT, LV_DPX(25));
|
||||
lv_style_set_line_rounded(&style_arc_indic, LV_STATE_DEFAULT, true);
|
||||
|
||||
style_init_reset(&style_arc_bg);
|
||||
lv_style_set_line_color(&style_arc_bg, LV_STATE_DEFAULT, LV_PINETIME_GRAY);
|
||||
lv_style_set_line_width(&style_arc_bg, LV_STATE_DEFAULT, LV_DPX(25));
|
||||
lv_style_set_line_rounded(&style_arc_bg, LV_STATE_DEFAULT, true);
|
||||
|
||||
style_init_reset(&style_table_cell);
|
||||
lv_style_set_border_color(&style_table_cell, LV_STATE_DEFAULT, LV_PINETIME_GRAY);
|
||||
lv_style_set_border_width(&style_table_cell, LV_STATE_DEFAULT, 1);
|
||||
lv_style_set_border_side(&style_table_cell, LV_STATE_DEFAULT, LV_BORDER_SIDE_FULL);
|
||||
lv_style_set_pad_left(&style_table_cell, LV_STATE_DEFAULT, 12);
|
||||
lv_style_set_pad_right(&style_table_cell, LV_STATE_DEFAULT, 12);
|
||||
lv_style_set_pad_top(&style_table_cell, LV_STATE_DEFAULT, 12);
|
||||
lv_style_set_pad_bottom(&style_table_cell, LV_STATE_DEFAULT, 12);
|
||||
|
||||
style_init_reset(&style_pad_small);
|
||||
lv_style_int_t pad_small_value = 10;
|
||||
lv_style_set_pad_left(&style_pad_small, LV_STATE_DEFAULT, pad_small_value);
|
||||
lv_style_set_pad_right(&style_pad_small, LV_STATE_DEFAULT, pad_small_value);
|
||||
lv_style_set_pad_top(&style_pad_small, LV_STATE_DEFAULT, pad_small_value);
|
||||
lv_style_set_pad_bottom(&style_pad_small, LV_STATE_DEFAULT, pad_small_value);
|
||||
lv_style_set_pad_inner(&style_pad_small, LV_STATE_DEFAULT, pad_small_value);
|
||||
|
||||
style_init_reset(&style_bg_grad);
|
||||
lv_style_set_bg_color(&style_bg_grad, LV_STATE_DEFAULT, lv_color_hsv_to_rgb(10, 10, 40));
|
||||
lv_style_set_bg_grad_color(&style_bg_grad, LV_STATE_DEFAULT, lv_color_hsv_to_rgb(10, 10, 20));
|
||||
lv_style_set_bg_grad_dir(&style_bg_grad, LV_STATE_DEFAULT, LV_GRAD_DIR_VER);
|
||||
|
||||
style_init_reset(&style_lmeter);
|
||||
lv_style_set_radius(&style_lmeter, LV_STATE_DEFAULT, LV_RADIUS_CIRCLE);
|
||||
lv_style_set_pad_left(&style_lmeter, LV_STATE_DEFAULT, LV_DPX(20));
|
||||
lv_style_set_pad_right(&style_lmeter, LV_STATE_DEFAULT, LV_DPX(20));
|
||||
lv_style_set_pad_top(&style_lmeter, LV_STATE_DEFAULT, LV_DPX(20));
|
||||
lv_style_set_pad_inner(&style_lmeter, LV_STATE_DEFAULT, LV_DPX(30));
|
||||
lv_style_set_scale_width(&style_lmeter, LV_STATE_DEFAULT, LV_DPX(25));
|
||||
|
||||
lv_style_set_line_color(&style_lmeter, LV_STATE_DEFAULT, theme.color_primary);
|
||||
lv_style_set_scale_grad_color(&style_lmeter, LV_STATE_DEFAULT, theme.color_primary);
|
||||
lv_style_set_scale_end_color(&style_lmeter, LV_STATE_DEFAULT, lv_color_hex3(0x888));
|
||||
lv_style_set_line_width(&style_lmeter, LV_STATE_DEFAULT, LV_DPX(10));
|
||||
lv_style_set_scale_end_line_width(&style_lmeter, LV_STATE_DEFAULT, LV_DPX(7));
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**********************
|
||||
* GLOBAL FUNCTIONS
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Initialize the default
|
||||
* @param color_primary the primary color of the theme
|
||||
* @param color_secondary the secondary color for the theme
|
||||
* @param flags ORed flags starting with `LV_THEME_DEF_FLAG_...`
|
||||
* @param font_small pointer to a small font
|
||||
* @param font_normal pointer to a normal font
|
||||
* @param font_subtitle pointer to a large font
|
||||
* @param font_title pointer to a extra large font
|
||||
* @return a pointer to reference this theme later
|
||||
*/
|
||||
lv_theme_t * lv_pinetime_theme_init(lv_color_t color_primary, lv_color_t color_secondary, uint32_t flags,
|
||||
const lv_font_t * font_small, const lv_font_t * font_normal, const lv_font_t * font_subtitle,
|
||||
const lv_font_t * font_title)
|
||||
{
|
||||
theme.color_primary = color_primary;
|
||||
theme.color_secondary = color_secondary;
|
||||
theme.font_small = font_small;
|
||||
theme.font_normal = font_normal;
|
||||
theme.font_subtitle = font_subtitle;
|
||||
theme.font_title = font_title;
|
||||
theme.flags = flags;
|
||||
|
||||
basic_init();
|
||||
|
||||
theme.apply_xcb = theme_apply;
|
||||
|
||||
inited = true;
|
||||
|
||||
return &theme;
|
||||
}
|
||||
|
||||
|
||||
static void theme_apply(lv_obj_t * obj, lv_theme_style_t name)
|
||||
{
|
||||
lv_style_list_t * list;
|
||||
|
||||
/*To avoid warnings*/
|
||||
uint32_t name_int = (uint32_t) name;
|
||||
switch(name_int) {
|
||||
case LV_THEME_NONE:
|
||||
break;
|
||||
|
||||
case LV_THEME_SCR:
|
||||
lv_obj_clean_style_list(obj, LV_OBJ_PART_MAIN);
|
||||
list = lv_obj_get_style_list(obj, LV_OBJ_PART_MAIN);
|
||||
_lv_style_list_add_style(list, &style_bg);
|
||||
break;
|
||||
|
||||
case LV_THEME_OBJ:
|
||||
lv_obj_clean_style_list(obj, LV_OBJ_PART_MAIN);
|
||||
list = lv_obj_get_style_list(obj, LV_OBJ_PART_MAIN);
|
||||
_lv_style_list_add_style(list, &style_box);
|
||||
break;
|
||||
|
||||
case LV_THEME_CONT:
|
||||
lv_obj_clean_style_list(obj, LV_OBJ_PART_MAIN);
|
||||
list = lv_obj_get_style_list(obj, LV_CONT_PART_MAIN);
|
||||
_lv_style_list_add_style(list, &style_box);
|
||||
break;
|
||||
|
||||
case LV_THEME_BTN:
|
||||
lv_obj_clean_style_list(obj, LV_BTN_PART_MAIN);
|
||||
list = lv_obj_get_style_list(obj, LV_BTN_PART_MAIN);
|
||||
_lv_style_list_add_style(list, &style_btn);
|
||||
_lv_style_list_add_style(list, &style_bg_grad);
|
||||
break;
|
||||
|
||||
case LV_THEME_BTNMATRIX:
|
||||
list = lv_obj_get_style_list(obj, LV_BTNMATRIX_PART_BG);
|
||||
_lv_style_list_add_style(list, &style_bg);
|
||||
_lv_style_list_add_style(list, &style_pad_small);
|
||||
|
||||
list = lv_obj_get_style_list(obj, LV_BTNMATRIX_PART_BTN);
|
||||
_lv_style_list_add_style(list, &style_btn);
|
||||
_lv_style_list_add_style(list, &style_bg_grad);
|
||||
//_lv_style_list_add_style(list, &styles->bg_click);
|
||||
break;
|
||||
|
||||
case LV_THEME_BAR:
|
||||
lv_obj_clean_style_list(obj, LV_BAR_PART_BG);
|
||||
list = lv_obj_get_style_list(obj, LV_BAR_PART_BG);
|
||||
|
||||
lv_obj_clean_style_list(obj, LV_BAR_PART_INDIC);
|
||||
list = lv_obj_get_style_list(obj, LV_BAR_PART_INDIC);
|
||||
_lv_style_list_add_style(list, &style_bar_indic);
|
||||
break;
|
||||
|
||||
case LV_THEME_IMAGE:
|
||||
lv_obj_clean_style_list(obj, LV_IMG_PART_MAIN);
|
||||
list = lv_obj_get_style_list(obj, LV_IMG_PART_MAIN);
|
||||
_lv_style_list_add_style(list, &style_icon);
|
||||
break;
|
||||
|
||||
case LV_THEME_LABEL:
|
||||
lv_obj_clean_style_list(obj, LV_LABEL_PART_MAIN);
|
||||
list = lv_obj_get_style_list(obj, LV_LABEL_PART_MAIN);
|
||||
_lv_style_list_add_style(list, &style_label_white);
|
||||
break;
|
||||
|
||||
case LV_THEME_SLIDER:
|
||||
lv_obj_clean_style_list(obj, LV_SLIDER_PART_BG);
|
||||
list = lv_obj_get_style_list(obj, LV_SLIDER_PART_BG);
|
||||
_lv_style_list_add_style(list, &style_sw_bg);
|
||||
|
||||
lv_obj_clean_style_list(obj, LV_SLIDER_PART_INDIC);
|
||||
list = lv_obj_get_style_list(obj, LV_SLIDER_PART_INDIC);
|
||||
|
||||
lv_obj_clean_style_list(obj, LV_SLIDER_PART_KNOB);
|
||||
list = lv_obj_get_style_list(obj, LV_SLIDER_PART_KNOB);
|
||||
_lv_style_list_add_style(list, &style_slider_knob);
|
||||
break;
|
||||
|
||||
case LV_THEME_LIST:
|
||||
lv_obj_clean_style_list(obj, LV_LIST_PART_BG);
|
||||
list = lv_obj_get_style_list(obj, LV_LIST_PART_BG);
|
||||
_lv_style_list_add_style(list, &style_box);
|
||||
|
||||
lv_obj_clean_style_list(obj, LV_LIST_PART_SCROLLABLE);
|
||||
list = lv_obj_get_style_list(obj, LV_LIST_PART_SCROLLABLE);
|
||||
|
||||
lv_obj_clean_style_list(obj, LV_LIST_PART_SCROLLBAR);
|
||||
list = lv_obj_get_style_list(obj, LV_LIST_PART_SCROLLBAR);
|
||||
_lv_style_list_add_style(list, &style_scrollbar);
|
||||
break;
|
||||
|
||||
case LV_THEME_LIST_BTN:
|
||||
lv_obj_clean_style_list(obj, LV_BTN_PART_MAIN);
|
||||
list = lv_obj_get_style_list(obj, LV_BTN_PART_MAIN);
|
||||
_lv_style_list_add_style(list, &style_list_btn);
|
||||
break;
|
||||
|
||||
|
||||
case LV_THEME_ARC:
|
||||
lv_obj_clean_style_list(obj, LV_ARC_PART_BG);
|
||||
list = lv_obj_get_style_list(obj, LV_ARC_PART_BG);
|
||||
_lv_style_list_add_style(list, &style_arc_bg);
|
||||
|
||||
lv_obj_clean_style_list(obj, LV_ARC_PART_INDIC);
|
||||
list = lv_obj_get_style_list(obj, LV_ARC_PART_INDIC);
|
||||
_lv_style_list_add_style(list, &style_arc_indic);
|
||||
break;
|
||||
|
||||
|
||||
case LV_THEME_SWITCH:
|
||||
lv_obj_clean_style_list(obj, LV_SWITCH_PART_BG);
|
||||
list = lv_obj_get_style_list(obj, LV_SWITCH_PART_BG);
|
||||
_lv_style_list_add_style(list, &style_sw_bg);
|
||||
|
||||
lv_obj_clean_style_list(obj, LV_SWITCH_PART_INDIC);
|
||||
list = lv_obj_get_style_list(obj, LV_SWITCH_PART_INDIC);
|
||||
_lv_style_list_add_style(list, &style_sw_indic);
|
||||
|
||||
lv_obj_clean_style_list(obj, LV_SWITCH_PART_KNOB);
|
||||
list = lv_obj_get_style_list(obj, LV_SWITCH_PART_KNOB);
|
||||
_lv_style_list_add_style(list, &style_sw_knob);
|
||||
break;
|
||||
|
||||
case LV_THEME_DROPDOWN:
|
||||
lv_obj_clean_style_list(obj, LV_DROPDOWN_PART_MAIN);
|
||||
list = lv_obj_get_style_list(obj, LV_DROPDOWN_PART_MAIN);
|
||||
_lv_style_list_add_style(list, &style_btn);
|
||||
_lv_style_list_add_style(list, &style_pad);
|
||||
|
||||
lv_obj_clean_style_list(obj, LV_DROPDOWN_PART_LIST);
|
||||
list = lv_obj_get_style_list(obj, LV_DROPDOWN_PART_LIST);
|
||||
_lv_style_list_add_style(list, &style_box);
|
||||
_lv_style_list_add_style(list, &style_ddlist_list);
|
||||
_lv_style_list_add_style(list, &style_pad);
|
||||
|
||||
lv_obj_clean_style_list(obj, LV_DROPDOWN_PART_SELECTED);
|
||||
list = lv_obj_get_style_list(obj, LV_DROPDOWN_PART_SELECTED);
|
||||
_lv_style_list_add_style(list, &style_ddlist_selected);
|
||||
|
||||
lv_obj_clean_style_list(obj, LV_DROPDOWN_PART_SCROLLBAR);
|
||||
list = lv_obj_get_style_list(obj, LV_DROPDOWN_PART_SCROLLBAR);
|
||||
_lv_style_list_add_style(list, &style_scrollbar);
|
||||
break;
|
||||
|
||||
case LV_THEME_TABLE:
|
||||
list = lv_obj_get_style_list(obj, LV_TABLE_PART_BG);
|
||||
_lv_style_list_add_style(list, &style_bg);
|
||||
|
||||
int idx = 1; /* start value should be 1, not zero, since cell styles
|
||||
start at 1 due to presence of LV_TABLE_PART_BG=0
|
||||
in the enum (lv_table.h) */
|
||||
/* declaring idx outside loop to work with older compilers */
|
||||
for(; idx <= LV_TABLE_CELL_STYLE_CNT; idx ++) {
|
||||
list = lv_obj_get_style_list(obj, idx);
|
||||
_lv_style_list_add_style(list, &style_table_cell);
|
||||
}
|
||||
break;
|
||||
|
||||
case LV_THEME_LINEMETER:
|
||||
list = lv_obj_get_style_list(obj, LV_LINEMETER_PART_MAIN);
|
||||
_lv_style_list_add_style(list, &style_bg);
|
||||
_lv_style_list_add_style(list, &style_lmeter);
|
||||
break;
|
||||
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
lv_obj_refresh_style(obj, LV_OBJ_PART_ALL, LV_STYLE_PROP_ALL);
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
62
src/displayapp/lv_pinetime_theme.h
Normal file
62
src/displayapp/lv_pinetime_theme.h
Normal file
@ -0,0 +1,62 @@
|
||||
/**
|
||||
* @file lv_pinetime_theme.h
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LV_PINETIME_THEME_H
|
||||
#define LV_PINETIME_THEME_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include <lvgl/lvgl.h>
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
/*Colors*/
|
||||
#define LV_PINETIME_WHITE lv_color_hex(0xffffff)
|
||||
#define LV_PINETIME_LIGHT lv_color_hex(0xf3f8fe)
|
||||
#define LV_PINETIME_GRAY lv_color_hex(0x8a8a8a)
|
||||
#define LV_PINETIME_LIGHT_GRAY lv_color_hex(0xc4c4c4)
|
||||
#define LV_PINETIME_BLUE lv_color_hex(0x2f3243) //006fb6
|
||||
#define LV_PINETIME_GREEN lv_color_hex(0x4cb242)
|
||||
#define LV_PINETIME_RED lv_color_hex(0xd51732)
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
|
||||
|
||||
/**
|
||||
* Initialize the default
|
||||
* @param color_primary the primary color of the theme
|
||||
* @param color_secondary the secondary color for the theme
|
||||
* @param flags ORed flags starting with `LV_THEME_DEF_FLAG_...`
|
||||
* @param font_small pointer to a small font
|
||||
* @param font_normal pointer to a normal font
|
||||
* @param font_subtitle pointer to a large font
|
||||
* @param font_title pointer to a extra large font
|
||||
* @return a pointer to reference this theme later
|
||||
*/
|
||||
lv_theme_t * lv_pinetime_theme_init(lv_color_t color_primary, lv_color_t color_secondary, uint32_t flags,
|
||||
const lv_font_t * font_small, const lv_font_t * font_normal, const lv_font_t * font_subtitle,
|
||||
const lv_font_t * font_title);
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
@ -71,7 +71,7 @@ std::unique_ptr<Screen> ApplicationList::CreateScreen2() {
|
||||
std::unique_ptr<Screen> ApplicationList::CreateScreen3() {
|
||||
std::array<Screens::Tile::Applications, 6> applications {
|
||||
{{"A", Apps::Meter},
|
||||
{"B", Apps::Gauge},
|
||||
{"B", Apps::Navigation},
|
||||
{"C", Apps::Clock},
|
||||
{"D", Apps::Music},
|
||||
{"E", Apps::SysInfo},
|
||||
|
@ -22,7 +22,7 @@ Brightness::Brightness(Pinetime::Applications::DisplayApp *app, Controllers::Bri
|
||||
slider_label = lv_label_create(lv_scr_act(), nullptr);
|
||||
lv_label_set_text(slider_label, LevelToString(brightness.Level()));
|
||||
lv_obj_set_auto_realign(slider_label, true);
|
||||
lv_obj_align(slider_label, slider, LV_ALIGN_OUT_BOTTOM_MID, 0, 10);
|
||||
lv_obj_align(slider_label, slider, LV_ALIGN_OUT_BOTTOM_MID, 0, 30);
|
||||
}
|
||||
|
||||
Brightness::~Brightness() {
|
||||
@ -75,6 +75,9 @@ bool Brightness::OnTouchEvent(Pinetime::Applications::TouchEvents event) {
|
||||
switch(event) {
|
||||
case TouchEvents::SwipeLeft:
|
||||
brightness.Lower();
|
||||
if ( brightness.Level() == Pinetime::Controllers::BrightnessController::Levels::Off) {
|
||||
brightness.Set(Controllers::BrightnessController::Levels::Low);
|
||||
}
|
||||
SetValue();
|
||||
return true;
|
||||
case TouchEvents::SwipeRight:
|
||||
|
@ -14,9 +14,6 @@
|
||||
#include "../DisplayApp.h"
|
||||
|
||||
using namespace Pinetime::Applications::Screens;
|
||||
extern lv_font_t jetbrains_mono_extrabold_compressed;
|
||||
extern lv_font_t jetbrains_mono_bold_20;
|
||||
extern lv_style_t* LabelBigStyle;
|
||||
|
||||
static void event_handler(lv_obj_t * obj, lv_event_t event) {
|
||||
Clock* screen = static_cast<Clock *>(obj->user_data);
|
||||
@ -59,7 +56,9 @@ Clock::Clock(DisplayApp* app,
|
||||
lv_obj_align(label_date, lv_scr_act(), LV_ALIGN_IN_LEFT_MID, 0, 60);
|
||||
|
||||
label_time = lv_label_create(lv_scr_act(), nullptr);
|
||||
lv_label_set_style(label_time, LV_LABEL_STYLE_MAIN, LabelBigStyle);
|
||||
|
||||
lv_obj_set_style_local_text_font(label_time, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, &jetbrains_mono_extrabold_compressed);
|
||||
|
||||
lv_obj_align(label_time, lv_scr_act(), LV_ALIGN_IN_LEFT_MID, 0, 0);
|
||||
|
||||
backgroundLabel = lv_label_create(lv_scr_act(), nullptr);
|
||||
|
@ -4,8 +4,6 @@
|
||||
#include "../DisplayApp.h"
|
||||
|
||||
using namespace Pinetime::Applications::Screens;
|
||||
extern lv_font_t jetbrains_mono_extrabold_compressed;
|
||||
extern lv_font_t jetbrains_mono_bold_20;
|
||||
|
||||
DropDownDemo::DropDownDemo(Pinetime::Applications::DisplayApp *app) : Screen(app) {
|
||||
// Create the dropdown object, with many item, and fix its height
|
||||
|
@ -4,8 +4,6 @@
|
||||
#include "../DisplayApp.h"
|
||||
|
||||
using namespace Pinetime::Applications::Screens;
|
||||
extern lv_font_t jetbrains_mono_extrabold_compressed;
|
||||
extern lv_font_t jetbrains_mono_bold_20;
|
||||
|
||||
|
||||
FirmwareUpdate::FirmwareUpdate(Pinetime::Applications::DisplayApp *app, Pinetime::Controllers::Ble& bleController) :
|
||||
|
@ -5,8 +5,6 @@
|
||||
#include "../DisplayApp.h"
|
||||
|
||||
using namespace Pinetime::Applications::Screens;
|
||||
extern lv_font_t jetbrains_mono_extrabold_compressed;
|
||||
extern lv_font_t jetbrains_mono_bold_20;
|
||||
|
||||
namespace {
|
||||
static void ButtonEventHandler(lv_obj_t * obj, lv_event_t event)
|
||||
|
@ -1,57 +0,0 @@
|
||||
#include "Gauge.h"
|
||||
#include "../DisplayApp.h"
|
||||
|
||||
using namespace Pinetime::Applications::Screens;
|
||||
extern lv_font_t jetbrains_mono_extrabold_compressed;
|
||||
extern lv_font_t jetbrains_mono_bold_20;
|
||||
|
||||
|
||||
Gauge::Gauge(Pinetime::Applications::DisplayApp *app) : Screen(app) {
|
||||
/*Create a style*/
|
||||
lv_style_copy(&style, &lv_style_pretty_color);
|
||||
style.body.main_color = LV_COLOR_CYAN; /*Line color at the beginning*/
|
||||
style.body.grad_color = LV_COLOR_RED; /*Line color at the end*/
|
||||
style.body.padding.left = 10; /*Scale line length*/
|
||||
style.body.padding.inner = 8 ; /*Scale label padding*/
|
||||
style.body.border.color = lv_color_hex3(0x333); /*Needle middle circle color*/
|
||||
style.line.width = 3;
|
||||
style.text.color = LV_COLOR_WHITE;
|
||||
style.line.color = LV_COLOR_RED; /*Line color after the critical value*/
|
||||
|
||||
|
||||
/*Describe the color for the needles*/
|
||||
|
||||
needle_colors[0] = LV_COLOR_ORANGE;
|
||||
|
||||
/*Create a gauge*/
|
||||
gauge1 = lv_gauge_create(lv_scr_act(), nullptr);
|
||||
lv_gauge_set_style(gauge1, LV_GAUGE_STYLE_MAIN, &style);
|
||||
lv_gauge_set_needle_count(gauge1, 1, needle_colors);
|
||||
lv_obj_set_size(gauge1, 180, 180);
|
||||
lv_obj_align(gauge1, nullptr, LV_ALIGN_CENTER, 0, 0);
|
||||
lv_gauge_set_scale(gauge1, 360, 60, 0);
|
||||
lv_gauge_set_range(gauge1, 0, 59);
|
||||
|
||||
/*Set the values*/
|
||||
lv_gauge_set_value(gauge1, 0, value);
|
||||
}
|
||||
|
||||
Gauge::~Gauge() {
|
||||
|
||||
|
||||
lv_obj_clean(lv_scr_act());
|
||||
}
|
||||
|
||||
bool Gauge::Refresh() {
|
||||
// lv_lmeter_set_value(lmeter, value++); /*Set the current value*/
|
||||
// if(value>=60) value = 0;
|
||||
|
||||
lv_gauge_set_value(gauge1, 0, value++);
|
||||
if(value == 59) value = 0;
|
||||
return running;
|
||||
}
|
||||
|
||||
bool Gauge::OnButtonPushed() {
|
||||
running = false;
|
||||
return true;
|
||||
}
|
@ -1,30 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
#include "Screen.h"
|
||||
#include <lvgl/lvgl.h>
|
||||
|
||||
namespace Pinetime {
|
||||
namespace Applications {
|
||||
namespace Screens {
|
||||
|
||||
class Gauge : public Screen{
|
||||
public:
|
||||
Gauge(DisplayApp* app);
|
||||
~Gauge() override;
|
||||
|
||||
bool Refresh() override;
|
||||
bool OnButtonPushed() override;
|
||||
|
||||
private:
|
||||
lv_style_t style;
|
||||
lv_color_t needle_colors[3];
|
||||
lv_obj_t * gauge1;
|
||||
|
||||
uint32_t value=30;
|
||||
bool running = true;
|
||||
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
@ -5,8 +5,6 @@
|
||||
#include "../DisplayApp.h"
|
||||
|
||||
using namespace Pinetime::Applications::Screens;
|
||||
extern lv_font_t jetbrains_mono_extrabold_compressed;
|
||||
extern lv_font_t jetbrains_mono_bold_20;
|
||||
|
||||
namespace {
|
||||
const char *ToString(Pinetime::Controllers::HeartRateController::States s) {
|
||||
@ -30,28 +28,22 @@ namespace {
|
||||
}
|
||||
|
||||
HeartRate::HeartRate(Pinetime::Applications::DisplayApp *app, Controllers::HeartRateController& heartRateController) : Screen(app), heartRateController{heartRateController} {
|
||||
label_bpm = lv_label_create(lv_scr_act(), NULL);
|
||||
|
||||
labelStyle = const_cast<lv_style_t *>(lv_label_get_style(label_bpm, LV_LABEL_STYLE_MAIN));
|
||||
labelStyle->text.font = &jetbrains_mono_bold_20;
|
||||
|
||||
lv_style_copy(&labelBigStyle, labelStyle);
|
||||
labelBigStyle.text.font = &jetbrains_mono_extrabold_compressed;
|
||||
|
||||
lv_label_set_style(label_bpm, LV_LABEL_STYLE_MAIN, labelStyle);
|
||||
|
||||
|
||||
label_hr = lv_label_create(lv_scr_act(), NULL);
|
||||
lv_label_set_style(label_hr, LV_LABEL_STYLE_MAIN, &labelBigStyle);
|
||||
|
||||
lv_obj_set_style_local_text_font(label_hr, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, &jetbrains_mono_extrabold_compressed);
|
||||
|
||||
lv_obj_align(label_hr, lv_scr_act(), LV_ALIGN_CENTER, -70, -40);
|
||||
lv_label_set_text(label_hr, "000");
|
||||
|
||||
label_bpm = lv_label_create(lv_scr_act(), NULL);
|
||||
lv_label_set_text(label_bpm, "Heart rate BPM");
|
||||
lv_obj_align(label_bpm, label_hr, LV_ALIGN_OUT_TOP_MID, 0, -20);
|
||||
|
||||
|
||||
label_status = lv_label_create(lv_scr_act(), NULL);
|
||||
lv_label_set_text(label_status, ToString(Pinetime::Controllers::HeartRateController::States::NotEnoughData));
|
||||
lv_label_set_style(label_status, LV_LABEL_STYLE_MAIN, labelStyle);
|
||||
|
||||
lv_obj_align(label_status, label_hr, LV_ALIGN_OUT_BOTTOM_MID, 0, 10);
|
||||
|
||||
btn_startStop = lv_btn_create(lv_scr_act(), NULL);
|
||||
|
@ -3,8 +3,6 @@
|
||||
#include "../LittleVgl.h"
|
||||
|
||||
using namespace Pinetime::Applications::Screens;
|
||||
extern lv_font_t jetbrains_mono_extrabold_compressed;
|
||||
extern lv_font_t jetbrains_mono_bold_20;
|
||||
|
||||
InfiniPaint::InfiniPaint(Pinetime::Applications::DisplayApp* app, Pinetime::Components::LittleVgl& lvgl) : Screen(app), lvgl{lvgl} {
|
||||
app->SetTouchMode(DisplayApp::TouchModes::Polling);
|
||||
|
@ -3,27 +3,23 @@
|
||||
#include "../DisplayApp.h"
|
||||
|
||||
using namespace Pinetime::Applications::Screens;
|
||||
extern lv_font_t jetbrains_mono_extrabold_compressed;
|
||||
extern lv_font_t jetbrains_mono_bold_20;
|
||||
|
||||
|
||||
Meter::Meter(Pinetime::Applications::DisplayApp *app) : Screen(app) {
|
||||
|
||||
lv_style_copy(&style_lmeter, &lv_style_pretty_color);
|
||||
style_lmeter.line.width = 2;
|
||||
style_lmeter.line.color = LV_COLOR_SILVER;
|
||||
style_lmeter.body.main_color = lv_color_make(255,0,0);
|
||||
style_lmeter.body.grad_color = lv_color_make(160,0,0);
|
||||
style_lmeter.body.padding.left = 16; /*Line length*/
|
||||
|
||||
/*Create a line meter */
|
||||
lmeter = lv_lmeter_create(lv_scr_act(), nullptr);
|
||||
lv_lmeter_set_range(lmeter, 0, 60); /*Set the range*/
|
||||
lv_lmeter_set_value(lmeter, value); /*Set the current value*/
|
||||
lv_lmeter_set_angle_offset(lmeter, 180);
|
||||
lv_lmeter_set_scale(lmeter, 360, 60); /*Set the angle and number of lines*/
|
||||
lv_lmeter_set_style(lmeter, LV_LMETER_STYLE_MAIN, &style_lmeter); /*Apply the new style*/
|
||||
lv_obj_set_size(lmeter, 150, 150);
|
||||
lmeter = lv_linemeter_create(lv_scr_act(), nullptr);
|
||||
lv_linemeter_set_range(lmeter, 0, 60); /*Set the range*/
|
||||
lv_linemeter_set_value(lmeter, value); /*Set the current value*/
|
||||
lv_linemeter_set_angle_offset(lmeter, 180);
|
||||
lv_linemeter_set_scale(lmeter, 360, 60); /*Set the angle and number of lines*/
|
||||
|
||||
lv_obj_set_style_local_scale_end_color(lmeter, LV_LINEMETER_PART_MAIN, LV_STATE_DEFAULT, lv_color_make(255,0,0));
|
||||
lv_obj_set_style_local_scale_grad_color(lmeter, LV_LINEMETER_PART_MAIN, LV_STATE_DEFAULT, lv_color_make(160,0,0));
|
||||
lv_obj_set_style_local_line_width(lmeter, LV_LINEMETER_PART_MAIN, LV_STATE_DEFAULT, 2);
|
||||
lv_obj_set_style_local_line_color(lmeter, LV_LINEMETER_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_SILVER);
|
||||
|
||||
lv_obj_set_size(lmeter, 200, 200);
|
||||
lv_obj_align(lmeter, nullptr, LV_ALIGN_CENTER, 0, 0);
|
||||
|
||||
}
|
||||
@ -35,7 +31,7 @@ Meter::~Meter() {
|
||||
}
|
||||
|
||||
bool Meter::Refresh() {
|
||||
lv_lmeter_set_value(lmeter, value++); /*Set the current value*/
|
||||
lv_linemeter_set_value(lmeter, value++); /*Set the current value*/
|
||||
if(value>=60) value = 0;
|
||||
|
||||
return running;
|
||||
|
@ -1,109 +0,0 @@
|
||||
#include "Modal.h"
|
||||
#include <lvgl/lvgl.h>
|
||||
#include "../DisplayApp.h"
|
||||
|
||||
using namespace Pinetime::Applications::Screens;
|
||||
extern lv_font_t jetbrains_mono_extrabold_compressed;
|
||||
extern lv_font_t jetbrains_mono_bold_20;
|
||||
|
||||
Modal::Modal(Pinetime::Applications::DisplayApp *app) : Screen(app), alertNotificationService(nullptr) {}
|
||||
|
||||
Modal::~Modal() {
|
||||
lv_obj_clean(lv_scr_act());
|
||||
}
|
||||
|
||||
bool Modal::Refresh() {
|
||||
|
||||
return running;
|
||||
}
|
||||
|
||||
bool Modal::OnButtonPushed() {
|
||||
running = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
void Modal::Hide() {
|
||||
/* Delete the parent modal background */
|
||||
lv_obj_del_async(lv_obj_get_parent(mbox));
|
||||
mbox = NULL; /* happens before object is actually deleted! */
|
||||
isVisible = false;
|
||||
}
|
||||
|
||||
void Modal::mbox_event_cb(lv_obj_t *obj, lv_event_t evt) {
|
||||
auto* m = static_cast<Modal *>(obj->user_data);
|
||||
m->OnEvent(obj, evt);
|
||||
}
|
||||
|
||||
void Modal::OnEvent(lv_obj_t *event_obj, lv_event_t evt) {
|
||||
if(evt == LV_EVENT_DELETE && event_obj == mbox) {
|
||||
Hide();
|
||||
} else if(evt == LV_EVENT_VALUE_CHANGED) {
|
||||
if(event_obj == mbox) {
|
||||
if(strcmp(lv_mbox_get_active_btn_text(event_obj), this->positiveButton.c_str()) == 0) {
|
||||
if(alertNotificationService != nullptr) {
|
||||
alertNotificationService->event(Pinetime::Controllers::AlertNotificationService::EVENT_ANSWER_CALL);
|
||||
}
|
||||
} else {
|
||||
if(alertNotificationService != nullptr) {
|
||||
alertNotificationService->event(Pinetime::Controllers::AlertNotificationService::EVENT_HANG_UP_CALL);
|
||||
}
|
||||
}
|
||||
lv_mbox_start_auto_close(mbox, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Modal::NewNotification(Pinetime::Controllers::NotificationManager ¬ificationManager, Pinetime::Controllers::AlertNotificationService* alertService) {
|
||||
alertNotificationService = alertService;
|
||||
auto notification = notificationManager.GetLastNotification();
|
||||
std::string msg;
|
||||
if(notification.valid) {
|
||||
switch(notification.category) {
|
||||
case Pinetime::Controllers::NotificationManager::Categories::IncomingCall:
|
||||
this->positiveButton = "Answer";
|
||||
this->negativeButton = "Hang up";
|
||||
msg += "Incoming call from:\n";
|
||||
msg += notification.message.data();
|
||||
break;
|
||||
default:
|
||||
this->positiveButton = "Ok";
|
||||
this->negativeButton = "Cancel";
|
||||
msg = notification.message.data();
|
||||
break;
|
||||
}
|
||||
|
||||
static const char *btns[] = {this->positiveButton.c_str(), this->negativeButton.c_str(), ""};
|
||||
this->Show(msg.c_str(), btns);
|
||||
}
|
||||
}
|
||||
|
||||
void Modal::Show(const char* msg, const char *btns[]) {
|
||||
if(isVisible) return;
|
||||
isVisible = true;
|
||||
lv_style_copy(&modal_style, &lv_style_plain_color);
|
||||
modal_style.body.main_color = modal_style.body.grad_color = LV_COLOR_BLACK;
|
||||
modal_style.body.opa = LV_OPA_50;
|
||||
|
||||
obj = lv_obj_create(lv_scr_act(), nullptr);
|
||||
lv_obj_set_style(obj, &modal_style);
|
||||
lv_obj_set_pos(obj, 0, 0);
|
||||
lv_obj_set_size(obj, LV_HOR_RES, LV_VER_RES);
|
||||
lv_obj_set_opa_scale_enable(obj, true); /* Enable opacity scaling for the animation */
|
||||
|
||||
/* Create the message box as a child of the modal background */
|
||||
mbox = lv_mbox_create(obj, nullptr);
|
||||
lv_mbox_add_btns(mbox, btns);
|
||||
lv_mbox_set_text(mbox, msg);
|
||||
lv_obj_align(mbox, nullptr, LV_ALIGN_CENTER, 0, 0);
|
||||
lv_obj_set_event_cb(mbox, Modal::mbox_event_cb);
|
||||
|
||||
mbox->user_data = this;
|
||||
|
||||
/* Fade the message box in with an animation */
|
||||
lv_anim_t a;
|
||||
lv_anim_init(&a);
|
||||
lv_anim_set_time(&a, 500, 0);
|
||||
lv_anim_set_values(&a, LV_OPA_TRANSP, LV_OPA_COVER);
|
||||
lv_anim_set_exec_cb(&a, obj, (lv_anim_exec_xcb_t)lv_obj_set_opa_scale);
|
||||
lv_anim_create(&a);
|
||||
}
|
@ -1,45 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "Screen.h"
|
||||
#include <lvgl/src/lv_core/lv_style.h>
|
||||
#include <lvgl/src/lv_core/lv_obj.h>
|
||||
#include <components/ble/NotificationManager.h>
|
||||
#include <components/ble/AlertNotificationService.h>
|
||||
|
||||
namespace Pinetime {
|
||||
namespace Applications {
|
||||
namespace Screens {
|
||||
|
||||
class Modal : public Screen{
|
||||
public:
|
||||
Modal(DisplayApp* app);
|
||||
~Modal() override;
|
||||
|
||||
|
||||
void NewNotification(Pinetime::Controllers::NotificationManager ¬ificationManager, Pinetime::Controllers::AlertNotificationService* alertService);
|
||||
void Show(const char* msg, const char *btns[]);
|
||||
void Hide();
|
||||
|
||||
bool Refresh() override;
|
||||
bool OnButtonPushed() override;
|
||||
|
||||
static void mbox_event_cb(lv_obj_t *obj, lv_event_t evt);
|
||||
private:
|
||||
void OnEvent(lv_obj_t *event_obj, lv_event_t evt);
|
||||
|
||||
Pinetime::Controllers::AlertNotificationService* alertNotificationService = nullptr;
|
||||
|
||||
std::string positiveButton;
|
||||
std::string negativeButton;
|
||||
|
||||
lv_style_t modal_style;
|
||||
lv_obj_t *obj;
|
||||
lv_obj_t *mbox;
|
||||
lv_obj_t *info;
|
||||
bool running = true;
|
||||
bool isVisible = false;
|
||||
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
@ -26,9 +26,6 @@
|
||||
|
||||
using namespace Pinetime::Applications::Screens;
|
||||
|
||||
extern lv_font_t jetbrains_mono_extrabold_compressed;
|
||||
extern lv_font_t jetbrains_mono_bold_20;
|
||||
|
||||
static void event_handler(lv_obj_t *obj, lv_event_t event) {
|
||||
Music *screen = static_cast<Music *>(obj->user_data);
|
||||
screen->OnObjectEvent(obj, event);
|
||||
|
@ -22,9 +22,6 @@
|
||||
|
||||
using namespace Pinetime::Applications::Screens;
|
||||
|
||||
extern lv_font_t jetbrains_mono_extrabold_compressed;
|
||||
extern lv_font_t jetbrains_mono_bold_20;
|
||||
|
||||
/**
|
||||
* Set the pixel array to display by the image
|
||||
* This just calls lv_img_set_src but adds type safety
|
||||
|
@ -1,6 +1,7 @@
|
||||
#include "Notifications.h"
|
||||
#include <displayapp/DisplayApp.h>
|
||||
#include "components/ble/MusicService.h"
|
||||
#include "components/ble/AlertNotificationService.h"
|
||||
#include "Symbols.h"
|
||||
|
||||
using namespace Pinetime::Applications::Screens;
|
||||
@ -35,14 +36,13 @@ Notifications::Notifications(DisplayApp *app,
|
||||
}
|
||||
|
||||
if(mode == Modes::Preview) {
|
||||
static lv_style_t style_line;
|
||||
lv_style_copy(&style_line, &lv_style_plain);
|
||||
style_line.line.color = LV_COLOR_WHITE;
|
||||
style_line.line.width = 3;
|
||||
style_line.line.rounded = 0;
|
||||
|
||||
timeoutLine = lv_line_create(lv_scr_act(), nullptr);
|
||||
lv_line_set_style(timeoutLine, LV_LINE_STYLE_MAIN, &style_line);
|
||||
|
||||
lv_obj_set_style_local_line_width(timeoutLine, LV_LINE_PART_MAIN, LV_STATE_DEFAULT, 3);
|
||||
lv_obj_set_style_local_line_color(timeoutLine, LV_LINE_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_WHITE);
|
||||
lv_obj_set_style_local_line_rounded(timeoutLine, LV_LINE_PART_MAIN, LV_STATE_DEFAULT, true);
|
||||
|
||||
lv_line_set_points(timeoutLine, timeoutLinePoints, 2);
|
||||
timeoutTickCountStart = xTaskGetTickCount();
|
||||
timeoutTickCountEnd = timeoutTickCountStart + (5*1024);
|
||||
@ -134,13 +134,13 @@ bool Notifications::OnButtonPushed() {
|
||||
}
|
||||
|
||||
namespace {
|
||||
static void AcceptIncomingCallEventHandler(lv_obj_t *obj, lv_event_t event) {
|
||||
auto* item = static_cast<Notifications::NotificationItem *>(obj->user_data);
|
||||
static void AcceptIncomingCallEventHandler(lv_obj_t* obj, lv_event_t event) {
|
||||
auto* item = static_cast<Notifications::NotificationItem*>(obj->user_data);
|
||||
item->OnAcceptIncomingCall(event);
|
||||
}
|
||||
|
||||
static void MuteIncomingCallEventHandler(lv_obj_t *obj, lv_event_t event) {
|
||||
auto* item = static_cast<Notifications::NotificationItem *>(obj->user_data);
|
||||
static void MuteIncomingCallEventHandler(lv_obj_t* obj, lv_event_t event) {
|
||||
auto* item = static_cast<Notifications::NotificationItem*>(obj->user_data);
|
||||
item->OnMuteIncomingCall(event);
|
||||
}
|
||||
|
||||
@ -150,128 +150,101 @@ namespace {
|
||||
}
|
||||
}
|
||||
|
||||
Notifications::NotificationItem::NotificationItem(const char *title,
|
||||
const char *msg,
|
||||
uint8_t notifNr,
|
||||
Controllers::NotificationManager::Categories category,
|
||||
uint8_t notifNb,
|
||||
Modes mode,
|
||||
Pinetime::Controllers::AlertNotificationService& alertNotificationService)
|
||||
: notifNr{notifNr}, notifNb{notifNb}, mode{mode}, alertNotificationService{alertNotificationService} {
|
||||
container1 = lv_cont_create(lv_scr_act(), nullptr);
|
||||
static lv_style_t contStyle;
|
||||
lv_style_copy(&contStyle, lv_cont_get_style(container1, LV_CONT_STYLE_MAIN));
|
||||
contStyle.body.padding.inner = 20;
|
||||
lv_cont_set_style(container1, LV_CONT_STYLE_MAIN, &contStyle);
|
||||
lv_obj_set_width(container1, LV_HOR_RES);
|
||||
lv_obj_set_height(container1, LV_VER_RES);
|
||||
lv_obj_set_pos(container1, 0, 0);
|
||||
lv_cont_set_layout(container1, LV_LAYOUT_OFF);
|
||||
lv_cont_set_fit2(container1, LV_FIT_FLOOD, LV_FIT_FLOOD);
|
||||
Notifications::NotificationItem::NotificationItem(const char *title,
|
||||
const char *msg,
|
||||
uint8_t notifNr,
|
||||
Controllers::NotificationManager::Categories category,
|
||||
uint8_t notifNb,
|
||||
Modes mode,
|
||||
Pinetime::Controllers::AlertNotificationService& alertNotificationService)
|
||||
: notifNr{notifNr}, notifNb{notifNb}, mode{mode}, alertNotificationService{alertNotificationService} {
|
||||
|
||||
t1 = lv_label_create(container1, nullptr);
|
||||
static lv_style_t titleStyle;
|
||||
static lv_style_t textStyle;
|
||||
static lv_style_t bottomStyle;
|
||||
lv_style_copy(&titleStyle, lv_label_get_style(t1, LV_LABEL_STYLE_MAIN));
|
||||
lv_style_copy(&textStyle, lv_label_get_style(t1, LV_LABEL_STYLE_MAIN));
|
||||
lv_style_copy(&bottomStyle, lv_label_get_style(t1, LV_LABEL_STYLE_MAIN));
|
||||
titleStyle.body.padding.inner = 5;
|
||||
titleStyle.body.grad_color = LV_COLOR_GRAY;
|
||||
titleStyle.body.main_color = LV_COLOR_GRAY;
|
||||
titleStyle.body.radius = 20;
|
||||
textStyle.body.border.part = LV_BORDER_NONE;
|
||||
textStyle.body.padding.inner = 5;
|
||||
lv_obj_t* container1 = lv_cont_create(lv_scr_act(), NULL);
|
||||
|
||||
bottomStyle.body.main_color = LV_COLOR_GREEN;
|
||||
bottomStyle.body.grad_color = LV_COLOR_GREEN;
|
||||
bottomStyle.body.border.part = LV_BORDER_TOP;
|
||||
bottomStyle.body.border.color = LV_COLOR_RED;
|
||||
lv_obj_set_style_local_bg_color(container1, LV_CONT_PART_MAIN, LV_STATE_DEFAULT, lv_color_hex(0x222222));
|
||||
lv_obj_set_style_local_pad_all(container1, LV_CONT_PART_MAIN, LV_STATE_DEFAULT, 10);
|
||||
lv_obj_set_style_local_pad_inner(container1, LV_CONT_PART_MAIN, LV_STATE_DEFAULT, 5);
|
||||
lv_obj_set_style_local_border_width(container1, LV_CONT_PART_MAIN, LV_STATE_DEFAULT, 0);
|
||||
|
||||
lv_label_set_style(t1, LV_LABEL_STYLE_MAIN, &titleStyle);
|
||||
lv_label_set_long_mode(t1, LV_LABEL_LONG_BREAK);
|
||||
lv_label_set_body_draw(t1, true);
|
||||
lv_obj_set_width(t1, LV_HOR_RES - (titleStyle.body.padding.left + titleStyle.body.padding.right));
|
||||
lv_label_set_text(t1, title);
|
||||
static constexpr int16_t offscreenOffset = -20 ;
|
||||
lv_obj_set_pos(t1, titleStyle.body.padding.left, offscreenOffset);
|
||||
lv_obj_set_pos(container1, 0, 50);
|
||||
lv_obj_set_width(container1, 240);
|
||||
lv_obj_set_height(container1, 190);
|
||||
|
||||
auto titleHeight = lv_obj_get_height(t1);
|
||||
lv_cont_set_layout(container1, LV_LAYOUT_COLUMN_LEFT);
|
||||
|
||||
lv_obj_t* alert_count = lv_label_create(lv_scr_act(), nullptr);
|
||||
lv_label_set_text_fmt(alert_count, "%i/%i", notifNr, notifNb);
|
||||
lv_obj_align(alert_count, NULL, LV_ALIGN_IN_TOP_RIGHT, 0, 16);
|
||||
|
||||
lv_obj_t* alert_type = lv_label_create(lv_scr_act(), nullptr);
|
||||
lv_obj_set_style_local_text_color(alert_type, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, lv_color_hex(0x888888));
|
||||
lv_label_set_text(alert_type, title);
|
||||
lv_obj_align(alert_type, NULL, LV_ALIGN_IN_TOP_LEFT, 0, -4);
|
||||
|
||||
/////////
|
||||
switch(category) {
|
||||
default: {
|
||||
l1 = lv_label_create(container1, nullptr);
|
||||
lv_label_set_style(l1, LV_LABEL_STYLE_MAIN, &textStyle);
|
||||
lv_obj_set_pos(l1, textStyle.body.padding.left,
|
||||
titleHeight + offscreenOffset + textStyle.body.padding.bottom +
|
||||
textStyle.body.padding.top);
|
||||
|
||||
lv_label_set_long_mode(l1, LV_LABEL_LONG_BREAK);
|
||||
lv_label_set_body_draw(l1, true);
|
||||
lv_obj_set_width(l1, LV_HOR_RES - (textStyle.body.padding.left + textStyle.body.padding.right));
|
||||
lv_label_set_text(l1, msg);
|
||||
lv_obj_t* alert_subject = lv_label_create(container1, nullptr);
|
||||
lv_obj_set_style_local_text_color(alert_subject, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_ORANGE);
|
||||
lv_label_set_long_mode(alert_subject, LV_LABEL_LONG_BREAK);
|
||||
lv_obj_set_width(alert_subject, LV_HOR_RES - 20);
|
||||
lv_label_set_text(alert_subject, msg);
|
||||
}
|
||||
break;
|
||||
case Controllers::NotificationManager::Categories::IncomingCall: {
|
||||
l1 = lv_label_create(container1, nullptr);
|
||||
lv_label_set_style(l1, LV_LABEL_STYLE_MAIN, &textStyle);
|
||||
lv_obj_set_pos(l1, textStyle.body.padding.left,
|
||||
titleHeight + offscreenOffset + textStyle.body.padding.bottom +
|
||||
textStyle.body.padding.top);
|
||||
lv_obj_t* alert_subject = lv_label_create(container1, nullptr);
|
||||
lv_obj_set_style_local_text_color(alert_subject, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_ORANGE);
|
||||
lv_label_set_long_mode(alert_subject, LV_LABEL_LONG_BREAK);
|
||||
lv_obj_set_width(alert_subject, LV_HOR_RES - 20);
|
||||
lv_label_set_text(alert_subject, "Incoming call from");
|
||||
|
||||
lv_label_set_long_mode(l1, LV_LABEL_LONG_BREAK);
|
||||
lv_label_set_body_draw(l1, true);
|
||||
lv_obj_set_width(l1, LV_HOR_RES - (textStyle.body.padding.left + textStyle.body.padding.right));
|
||||
lv_label_set_text(l1, "Incoming call from ");
|
||||
auto l1Height = lv_obj_get_height(l1);
|
||||
lv_obj_t* alert_caller = lv_label_create(container1, nullptr);
|
||||
lv_obj_align(alert_caller, alert_subject, LV_ALIGN_OUT_BOTTOM_LEFT, 0, 0);
|
||||
lv_label_set_long_mode(alert_caller, LV_LABEL_LONG_BREAK);
|
||||
lv_obj_set_width(alert_caller, LV_HOR_RES - 20);
|
||||
lv_label_set_text(alert_caller, msg);
|
||||
|
||||
l2 = lv_label_create(container1, nullptr);
|
||||
lv_label_set_style(l2, LV_LABEL_STYLE_MAIN, &textStyle);
|
||||
lv_obj_set_pos(l2, textStyle.body.padding.left,
|
||||
titleHeight + l1Height + offscreenOffset + (textStyle.body.padding.bottom*2) +
|
||||
(textStyle.body.padding.top*2));
|
||||
lv_label_set_long_mode(l2, LV_LABEL_LONG_BREAK);
|
||||
lv_label_set_body_draw(l2, true);
|
||||
lv_obj_set_width(l2, LV_HOR_RES - (textStyle.body.padding.left + textStyle.body.padding.right));
|
||||
lv_label_set_text(l2, msg);
|
||||
lv_obj_t* callBtnContainer = lv_cont_create(container1, NULL);
|
||||
lv_obj_set_width(callBtnContainer, 240);
|
||||
lv_obj_set_height(callBtnContainer, 90);
|
||||
lv_cont_set_layout(callBtnContainer, LV_LAYOUT_ROW_MID);
|
||||
|
||||
bt_accept = lv_btn_create(container1, nullptr);
|
||||
lv_obj_set_style_local_bg_color(callBtnContainer, LV_CONT_PART_MAIN, LV_STATE_DEFAULT, lv_color_hex(0x222222));
|
||||
lv_obj_set_style_local_pad_all(callBtnContainer, LV_CONT_PART_MAIN, LV_STATE_DEFAULT, 0);
|
||||
lv_obj_set_style_local_margin_top(callBtnContainer, LV_CONT_PART_MAIN, LV_STATE_DEFAULT, 40);
|
||||
lv_obj_set_style_local_margin_left(callBtnContainer, LV_CONT_PART_MAIN, LV_STATE_DEFAULT, -8);
|
||||
lv_obj_set_style_local_pad_inner(callBtnContainer, LV_CONT_PART_MAIN, LV_STATE_DEFAULT, 5);
|
||||
lv_obj_set_style_local_border_width(callBtnContainer, LV_CONT_PART_MAIN, LV_STATE_DEFAULT, 0);
|
||||
|
||||
bt_accept = lv_btn_create(callBtnContainer, nullptr);
|
||||
bt_accept->user_data = this;
|
||||
lv_obj_set_event_cb(bt_accept, AcceptIncomingCallEventHandler);
|
||||
lv_obj_set_size(bt_accept, LV_HOR_RES / 3, 80);
|
||||
lv_obj_align(bt_accept, lv_scr_act(), LV_ALIGN_IN_BOTTOM_LEFT, 0, -20);
|
||||
lv_obj_set_size(bt_accept, (LV_HOR_RES / 3) - 5, 80);
|
||||
label_accept = lv_label_create(bt_accept, nullptr);
|
||||
lv_label_set_text(label_accept, Symbols::phone);
|
||||
|
||||
bt_reject = lv_btn_create(container1, nullptr);
|
||||
bt_reject = lv_btn_create(callBtnContainer, nullptr);
|
||||
bt_reject->user_data = this;
|
||||
lv_obj_set_event_cb(bt_reject, RejectIncomingCallEventHandler);
|
||||
lv_obj_set_size(bt_reject, LV_HOR_RES / 3, 80);
|
||||
lv_obj_align(bt_reject, lv_scr_act(), LV_ALIGN_IN_BOTTOM_RIGHT, 0, -20);
|
||||
lv_obj_set_size(bt_reject, (LV_HOR_RES / 3) - 5, 80);
|
||||
label_reject = lv_label_create(bt_reject, nullptr);
|
||||
lv_label_set_text(label_reject, Symbols::phoneSlash);
|
||||
|
||||
bt_mute = lv_btn_create(container1, nullptr);
|
||||
bt_mute = lv_btn_create(callBtnContainer, nullptr);
|
||||
bt_mute->user_data = this;
|
||||
lv_obj_set_event_cb(bt_mute, MuteIncomingCallEventHandler);
|
||||
lv_obj_set_size(bt_mute, LV_HOR_RES / 3, 80);
|
||||
lv_obj_align(bt_mute, lv_scr_act(), LV_ALIGN_IN_BOTTOM_MID, 0, -20);
|
||||
lv_obj_set_size(bt_mute, (LV_HOR_RES / 3) - 5, 80);
|
||||
label_mute = lv_label_create(bt_mute, nullptr);
|
||||
lv_label_set_text(label_mute, Symbols::volumMute);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if(mode == Modes::Normal) {
|
||||
if(notifNr < notifNb) {
|
||||
bottomPlaceholder = lv_label_create(container1, nullptr);
|
||||
lv_label_set_style(bottomPlaceholder, LV_LABEL_STYLE_MAIN, &titleStyle);
|
||||
lv_label_set_long_mode(bottomPlaceholder, LV_LABEL_LONG_BREAK);
|
||||
lv_label_set_body_draw(bottomPlaceholder, true);
|
||||
lv_obj_set_width(bottomPlaceholder, LV_HOR_RES - (titleStyle.body.padding.left + titleStyle.body.padding.right));
|
||||
lv_label_set_text(bottomPlaceholder, " ");
|
||||
lv_obj_set_pos(bottomPlaceholder, titleStyle.body.padding.left, LV_VER_RES - 5);
|
||||
}
|
||||
}
|
||||
lv_obj_t* backgroundLabel = lv_label_create(lv_scr_act(), nullptr);
|
||||
lv_label_set_long_mode(backgroundLabel, LV_LABEL_LONG_CROP);
|
||||
lv_obj_set_size(backgroundLabel, 240, 240);
|
||||
lv_obj_set_pos(backgroundLabel, 0, 0);
|
||||
lv_label_set_text(backgroundLabel, "");
|
||||
}
|
||||
|
||||
void Notifications::NotificationItem::OnAcceptIncomingCall(lv_event_t event) {
|
||||
|
@ -68,7 +68,7 @@ namespace Pinetime {
|
||||
Controllers::NotificationManager::Notification::Id currentId;
|
||||
bool validDisplay = false;
|
||||
|
||||
lv_point_t timeoutLinePoints[2] { {0, 237}, {239, 237} };
|
||||
lv_point_t timeoutLinePoints[2] { {0, 1}, {239, 1} };
|
||||
lv_obj_t* timeoutLine;
|
||||
uint32_t timeoutTickCountStart;
|
||||
uint32_t timeoutTickCountEnd;
|
||||
|
@ -3,8 +3,6 @@
|
||||
#include "../LittleVgl.h"
|
||||
|
||||
using namespace Pinetime::Applications::Screens;
|
||||
extern lv_font_t jetbrains_mono_extrabold_compressed;
|
||||
extern lv_font_t jetbrains_mono_bold_20;
|
||||
|
||||
namespace{
|
||||
const uint8_t paddle_map[] = {
|
||||
|
@ -3,8 +3,6 @@
|
||||
|
||||
using namespace Pinetime::Applications::Screens;
|
||||
|
||||
extern lv_font_t jetbrains_mono_bold_20;
|
||||
|
||||
static void event_handler(lv_obj_t * obj, lv_event_t event) {
|
||||
Tile* screen = static_cast<Tile *>(obj->user_data);
|
||||
uint32_t* eventDataPtr = (uint32_t*) lv_event_get_data();
|
||||
@ -23,8 +21,8 @@ Tile::Tile(DisplayApp* app, std::array<Applications, 6>& applications) : Screen(
|
||||
}
|
||||
}
|
||||
|
||||
btnm1 = lv_btnm_create(lv_scr_act(), nullptr);
|
||||
lv_btnm_set_map(btnm1, btnm_map1);
|
||||
btnm1 = lv_btnmatrix_create(lv_scr_act(), nullptr);
|
||||
lv_btnmatrix_set_map(btnm1, btnm_map1);
|
||||
lv_obj_set_size(btnm1, LV_HOR_RES, LV_VER_RES);
|
||||
|
||||
btnm1->user_data = this;
|
||||
|
@ -3,7 +3,6 @@
|
||||
#include <lvgl/lvgl.h>
|
||||
#include <cstdint>
|
||||
#include <memory>
|
||||
#include "Modal.h"
|
||||
#include "Screen.h"
|
||||
#include "../Apps.h"
|
||||
|
||||
|
@ -8,43 +8,50 @@
|
||||
|
||||
using namespace Pinetime::Applications::Screens;
|
||||
|
||||
extern lv_font_t jetbrains_mono_bold_20;
|
||||
|
||||
Twos::Twos(Pinetime::Applications::DisplayApp *app) : Screen(app) {
|
||||
|
||||
// create styles to apply to different valued tiles
|
||||
static lv_style_t style_cell1;
|
||||
lv_style_copy(&style_cell1, &lv_style_plain);
|
||||
style_cell1.body.border.width = 1;
|
||||
style_cell1.text.font = &jetbrains_mono_bold_20;
|
||||
style_cell1.body.padding.top = 16;
|
||||
style_cell1.body.padding.bottom = 16;
|
||||
style_cell1.body.main_color = LV_COLOR_MAKE(214, 197, 165);
|
||||
style_cell1.body.grad_color = LV_COLOR_MAKE(214, 197, 165);
|
||||
style_cell1.text.color = LV_COLOR_BLACK;
|
||||
lv_style_init(&style_cell1);
|
||||
lv_style_init(&style_cell2);
|
||||
lv_style_init(&style_cell3);
|
||||
lv_style_init(&style_cell4);
|
||||
lv_style_init(&style_cell5);
|
||||
|
||||
static lv_style_t style_cell2;
|
||||
lv_style_copy(&style_cell2, &style_cell1);
|
||||
style_cell2.body.main_color = LV_COLOR_MAKE(209, 146, 92);
|
||||
style_cell2.body.grad_color = LV_COLOR_MAKE(209, 146, 92);
|
||||
style_cell2.text.color = LV_COLOR_WHITE;
|
||||
lv_style_set_border_color(&style_cell1, LV_STATE_DEFAULT, lv_color_hex(0xbbada0));
|
||||
lv_style_set_border_width(&style_cell1, LV_STATE_DEFAULT, 3);
|
||||
lv_style_set_bg_opa(&style_cell1, LV_STATE_DEFAULT, LV_OPA_COVER);
|
||||
lv_style_set_bg_color(&style_cell1, LV_STATE_DEFAULT, lv_color_hex(0xcdc0b4));
|
||||
|
||||
static lv_style_t style_cell3;
|
||||
lv_style_copy(&style_cell3, &style_cell2);
|
||||
style_cell3.body.main_color = LV_COLOR_MAKE(246, 94, 59);
|
||||
style_cell3.body.grad_color = LV_COLOR_MAKE(246, 94, 59);
|
||||
lv_style_set_border_color(&style_cell2, LV_STATE_DEFAULT, lv_color_hex(0xbbada0));
|
||||
lv_style_set_border_width(&style_cell2, LV_STATE_DEFAULT, 3);
|
||||
lv_style_set_bg_opa(&style_cell2, LV_STATE_DEFAULT, LV_OPA_COVER);
|
||||
lv_style_set_bg_color(&style_cell2, LV_STATE_DEFAULT, lv_color_hex(0xefdfc6));
|
||||
|
||||
static lv_style_t style_cell4;
|
||||
lv_style_copy(&style_cell4, &style_cell3);
|
||||
style_cell4.body.main_color = LV_COLOR_MAKE(212, 170, 28);
|
||||
style_cell4.body.grad_color = LV_COLOR_MAKE(212, 170, 28);
|
||||
lv_style_set_border_color(&style_cell3, LV_STATE_DEFAULT, lv_color_hex(0xbbada0));
|
||||
lv_style_set_border_width(&style_cell3, LV_STATE_DEFAULT, 3);
|
||||
lv_style_set_bg_opa(&style_cell3, LV_STATE_DEFAULT, LV_OPA_COVER);
|
||||
lv_style_set_bg_color(&style_cell3, LV_STATE_DEFAULT, lv_color_hex(0xef9263));
|
||||
|
||||
lv_style_set_border_color(&style_cell4, LV_STATE_DEFAULT, lv_color_hex(0xbbada0));
|
||||
lv_style_set_border_width(&style_cell4, LV_STATE_DEFAULT, 3);
|
||||
lv_style_set_bg_opa(&style_cell4, LV_STATE_DEFAULT, LV_OPA_COVER);
|
||||
lv_style_set_bg_color(&style_cell4, LV_STATE_DEFAULT, lv_color_hex(0xf76142));
|
||||
//lv_style_set_text_color(&style_cell4, LV_STATE_DEFAULT, LV_COLOR_WHITE);
|
||||
|
||||
lv_style_set_border_color(&style_cell5, LV_STATE_DEFAULT, lv_color_hex(0xbbada0));
|
||||
lv_style_set_border_width(&style_cell5, LV_STATE_DEFAULT, 3);
|
||||
lv_style_set_bg_opa(&style_cell5, LV_STATE_DEFAULT, LV_OPA_COVER);
|
||||
lv_style_set_bg_color(&style_cell5, LV_STATE_DEFAULT, lv_color_hex(0x007dc5));
|
||||
//lv_style_set_text_color(&style_cell5, LV_STATE_DEFAULT, LV_COLOR_WHITE);
|
||||
|
||||
// format grid display
|
||||
gridDisplay = lv_table_create(lv_scr_act(), nullptr);
|
||||
lv_table_set_style(gridDisplay, LV_TABLE_STYLE_CELL1, &style_cell1);
|
||||
lv_table_set_style(gridDisplay, LV_TABLE_STYLE_CELL2, &style_cell2);
|
||||
lv_table_set_style(gridDisplay, LV_TABLE_STYLE_CELL3, &style_cell3);
|
||||
lv_table_set_style(gridDisplay, LV_TABLE_STYLE_CELL4, &style_cell4);
|
||||
|
||||
gridDisplay = lv_table_create(lv_scr_act(), nullptr);
|
||||
lv_obj_add_style(gridDisplay, LV_TABLE_PART_CELL1, &style_cell1);
|
||||
lv_obj_add_style(gridDisplay, LV_TABLE_PART_CELL2, &style_cell2);
|
||||
lv_obj_add_style(gridDisplay, LV_TABLE_PART_CELL3, &style_cell3);
|
||||
lv_obj_add_style(gridDisplay, LV_TABLE_PART_CELL4, &style_cell4);
|
||||
lv_obj_add_style(gridDisplay, LV_TABLE_PART_CELL4 + 1, &style_cell5);
|
||||
lv_table_set_col_cnt(gridDisplay, 4);
|
||||
lv_table_set_row_cnt(gridDisplay, 4);
|
||||
lv_table_set_col_width(gridDisplay, 0, LV_HOR_RES/4);
|
||||
@ -53,11 +60,13 @@ Twos::Twos(Pinetime::Applications::DisplayApp *app) : Screen(app) {
|
||||
lv_table_set_col_width(gridDisplay, 3, LV_HOR_RES/4);
|
||||
lv_obj_align(gridDisplay, NULL, LV_ALIGN_IN_BOTTOM_MID, 0, 0);
|
||||
|
||||
lv_obj_clean_style_list(gridDisplay, LV_TABLE_PART_BG);
|
||||
|
||||
// initialize grid
|
||||
for(int row = 0; row < 4; row++) {
|
||||
for(int col = 0; col < 4; col++) {
|
||||
grid[row][col].value = 0;
|
||||
lv_table_set_cell_type(gridDisplay, row, col, 2);
|
||||
lv_table_set_cell_type(gridDisplay, row, col, 1);
|
||||
lv_table_set_cell_align(gridDisplay, row, col, LV_LABEL_ALIGN_CENTER);
|
||||
}
|
||||
}
|
||||
@ -68,11 +77,23 @@ Twos::Twos(Pinetime::Applications::DisplayApp *app) : Screen(app) {
|
||||
scoreText = lv_label_create(lv_scr_act(), nullptr);
|
||||
lv_obj_set_width(scoreText, LV_HOR_RES);
|
||||
lv_label_set_align(scoreText, LV_ALIGN_IN_LEFT_MID);
|
||||
lv_obj_align(scoreText, nullptr, LV_ALIGN_IN_TOP_LEFT, 0, 0);
|
||||
lv_label_set_text(scoreText, ("Score: " + std::to_string(score)).c_str());
|
||||
lv_obj_align(scoreText, nullptr, LV_ALIGN_IN_TOP_LEFT, 0, 10);
|
||||
lv_label_set_recolor(scoreText, true);
|
||||
lv_label_set_text_fmt(scoreText, "Score #FFFF00 %i#", score);
|
||||
|
||||
lv_obj_t * backgroundLabel = lv_label_create(lv_scr_act(), nullptr);
|
||||
lv_label_set_long_mode(backgroundLabel, LV_LABEL_LONG_CROP);
|
||||
lv_obj_set_size(backgroundLabel, 240, 240);
|
||||
lv_obj_set_pos(backgroundLabel, 0, 0);
|
||||
lv_label_set_text(backgroundLabel, "");
|
||||
}
|
||||
|
||||
Twos::~Twos() {
|
||||
lv_style_reset(&style_cell1);
|
||||
lv_style_reset(&style_cell2);
|
||||
lv_style_reset(&style_cell3);
|
||||
lv_style_reset(&style_cell4);
|
||||
lv_style_reset(&style_cell5);
|
||||
lv_obj_clean(lv_scr_act());
|
||||
}
|
||||
|
||||
@ -117,7 +138,7 @@ bool Twos::tryMerge(Tile grid[][4], int &newRow, int &newCol, int oldRow, int ol
|
||||
unsigned int newVal = grid[oldRow][oldCol].value *= 2;
|
||||
grid[newRow][newCol].value = newVal;
|
||||
score += newVal;
|
||||
lv_label_set_text(scoreText, ("Score: " + std::to_string(score)).c_str());
|
||||
lv_label_set_text_fmt(scoreText, "Score #FFFF00 %i#", score);
|
||||
grid[oldRow][oldCol].value = 0;
|
||||
grid[newRow][newCol].merged = true;
|
||||
return true;
|
||||
@ -250,20 +271,22 @@ void Twos::updateGridDisplay(Tile grid[][4]) {
|
||||
}
|
||||
switch (grid[row][col].value) {
|
||||
case 0:
|
||||
lv_table_set_cell_type(gridDisplay, row, col, 1);
|
||||
break;
|
||||
case 2:
|
||||
case 4:
|
||||
lv_table_set_cell_type(gridDisplay, row, col, 1);
|
||||
lv_table_set_cell_type(gridDisplay, row, col, 2);
|
||||
break;
|
||||
case 8:
|
||||
case 16:
|
||||
lv_table_set_cell_type(gridDisplay, row, col, 2);
|
||||
lv_table_set_cell_type(gridDisplay, row, col, 3);
|
||||
break;
|
||||
case 32:
|
||||
case 64:
|
||||
lv_table_set_cell_type(gridDisplay, row, col, 3);
|
||||
lv_table_set_cell_type(gridDisplay, row, col, 4);
|
||||
break;
|
||||
default:
|
||||
lv_table_set_cell_type(gridDisplay, row, col, 4);
|
||||
lv_table_set_cell_type(gridDisplay, row, col, 5);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -19,6 +19,13 @@ namespace Pinetime {
|
||||
bool OnTouchEvent(TouchEvents event) override;
|
||||
|
||||
private:
|
||||
|
||||
lv_style_t style_cell1;
|
||||
lv_style_t style_cell2;
|
||||
lv_style_t style_cell3;
|
||||
lv_style_t style_cell4;
|
||||
lv_style_t style_cell5;
|
||||
|
||||
bool running = true;
|
||||
lv_obj_t *scoreText;
|
||||
lv_obj_t *gridDisplay;
|
||||
|
@ -1,10 +1,8 @@
|
||||
/**
|
||||
* @file lv_conf.h
|
||||
*
|
||||
* Configuration file for v7.7.0-dev
|
||||
*/
|
||||
|
||||
#if 1 /*Set it to "1" to enable content*/
|
||||
|
||||
#ifndef LV_CONF_H
|
||||
#define LV_CONF_H
|
||||
/* clang-format off */
|
||||
@ -21,7 +19,7 @@
|
||||
|
||||
/* Color depth:
|
||||
* - 1: 1 byte per pixel
|
||||
* - 8: RGB233
|
||||
* - 8: RGB332
|
||||
* - 16: RGB565
|
||||
* - 32: ARGB8888
|
||||
*/
|
||||
@ -37,10 +35,7 @@
|
||||
#define LV_COLOR_SCREEN_TRANSP 0
|
||||
|
||||
/*Images pixels with this color will not be drawn (with chroma keying)*/
|
||||
#define LV_COLOR_TRANSP LV_COLOR_MAKE(0x6c, 0xFc, 0x6a)/*LV_COLOR_LIME*/ /*LV_COLOR_LIME: pure green*/
|
||||
|
||||
/* Enable chroma keying for indexed images. */
|
||||
#define LV_INDEXED_CHROMA 1
|
||||
#define LV_COLOR_TRANSP LV_COLOR_MAKE(0x6c, 0xFc, 0x6a) /*LV_COLOR_LIME: pure green*/
|
||||
|
||||
/* Enable anti-aliasing (lines, and radiuses will be smoothed) */
|
||||
#define LV_ANTIALIAS 1
|
||||
@ -54,6 +49,17 @@
|
||||
* (Not so important, you can adjust it to modify default sizes and spaces)*/
|
||||
#define LV_DPI 100 /*[px]*/
|
||||
|
||||
/* The the real width of the display changes some default values:
|
||||
* default object sizes, layout of examples, etc.
|
||||
* According to the width of the display (hor. res. / dpi)
|
||||
* the displays fall in 4 categories.
|
||||
* The 4th is extra large which has no upper limit so not listed here
|
||||
* The upper limit of the categories are set below in 0.1 inch unit.
|
||||
*/
|
||||
#define LV_DISP_SMALL_LIMIT 30
|
||||
#define LV_DISP_MEDIUM_LIMIT 50
|
||||
#define LV_DISP_LARGE_LIMIT 70
|
||||
|
||||
/* Type of coordinates. Should be `int16_t` (or `int32_t` for extreme cases) */
|
||||
typedef int16_t lv_coord_t;
|
||||
|
||||
@ -68,30 +74,34 @@ typedef int16_t lv_coord_t;
|
||||
#define LV_MEM_CUSTOM 0
|
||||
#if LV_MEM_CUSTOM == 0
|
||||
/* Size of the memory used by `lv_mem_alloc` in bytes (>= 2kB)*/
|
||||
# define LV_MEM_SIZE (4U * 1024U)
|
||||
#define LV_MEM_SIZE (12U * 1024U)
|
||||
|
||||
/* Complier prefix for a big array declaration */
|
||||
# define LV_MEM_ATTR
|
||||
#define LV_MEM_ATTR
|
||||
|
||||
/* Set an address for the memory pool instead of allocating it as an array.
|
||||
* Can be in external SRAM too. */
|
||||
# define LV_MEM_ADR 0
|
||||
#define LV_MEM_ADR 0
|
||||
|
||||
/* Automatically defrag. on free. Defrag. means joining the adjacent free cells. */
|
||||
# define LV_MEM_AUTO_DEFRAG 1
|
||||
#define LV_MEM_AUTO_DEFRAG 1
|
||||
#else /*LV_MEM_CUSTOM*/
|
||||
# define LV_MEM_CUSTOM_INCLUDE <stdlib.h> /*Header for the dynamic memory function*/
|
||||
# define LV_MEM_CUSTOM_ALLOC malloc /*Wrapper to malloc*/
|
||||
# define LV_MEM_CUSTOM_FREE free /*Wrapper to free*/
|
||||
#define LV_MEM_CUSTOM_INCLUDE <stdlib.h> /*Header for the dynamic memory function*/
|
||||
#define LV_MEM_CUSTOM_ALLOC malloc /*Wrapper to malloc*/
|
||||
#define LV_MEM_CUSTOM_FREE free /*Wrapper to free*/
|
||||
#endif /*LV_MEM_CUSTOM*/
|
||||
|
||||
/* Use the standard memcpy and memset instead of LVGL's own functions.
|
||||
* The standard functions might or might not be faster depending on their implementation. */
|
||||
#define LV_MEMCPY_MEMSET_STD 1
|
||||
|
||||
/* Garbage Collector settings
|
||||
* Used if lvgl is binded to higher level language and the memory is managed by that language */
|
||||
#define LV_ENABLE_GC 0
|
||||
#if LV_ENABLE_GC != 0
|
||||
# define LV_GC_INCLUDE "gc.h" /*Include Garbage Collector related things*/
|
||||
# define LV_MEM_CUSTOM_REALLOC your_realloc /*Wrapper to realloc*/
|
||||
# define LV_MEM_CUSTOM_GET_SIZE your_mem_get_size /*Wrapper to lv_mem_get_size*/
|
||||
#define LV_GC_INCLUDE "gc.h" /*Include Garbage Collector related things*/
|
||||
#define LV_MEM_CUSTOM_REALLOC your_realloc /*Wrapper to realloc*/
|
||||
#define LV_MEM_CUSTOM_GET_SIZE your_mem_get_size /*Wrapper to lv_mem_get_size*/
|
||||
#endif /* LV_ENABLE_GC */
|
||||
|
||||
/*=======================
|
||||
@ -118,32 +128,82 @@ typedef int16_t lv_coord_t;
|
||||
* Time between `LV_EVENT_LONG_PRESSED_REPEAT */
|
||||
#define LV_INDEV_DEF_LONG_PRESS_REP_TIME 100
|
||||
|
||||
|
||||
/* Gesture threshold in pixels */
|
||||
#define LV_INDEV_DEF_GESTURE_LIMIT 50
|
||||
|
||||
/* Gesture min velocity at release before swipe (pixels)*/
|
||||
#define LV_INDEV_DEF_GESTURE_MIN_VELOCITY 3
|
||||
|
||||
/*==================
|
||||
* Feature usage
|
||||
*==================*/
|
||||
|
||||
/*1: Enable the Animations */
|
||||
#define LV_USE_ANIMATION 1
|
||||
#define LV_USE_ANIMATION 0
|
||||
#if LV_USE_ANIMATION
|
||||
|
||||
/*Declare the type of the user data of animations (can be e.g. `void *`, `int`, `struct`)*/
|
||||
typedef void * lv_anim_user_data_t;
|
||||
typedef void* lv_anim_user_data_t;
|
||||
|
||||
#endif
|
||||
|
||||
/* 1: Enable shadow drawing*/
|
||||
/* 1: Enable shadow drawing on rectangles*/
|
||||
#define LV_USE_SHADOW 0
|
||||
#if LV_USE_SHADOW
|
||||
/* Allow buffering some shadow calculation
|
||||
* LV_SHADOW_CACHE_SIZE is the max. shadow size to buffer,
|
||||
* where shadow size is `shadow_width + radius`
|
||||
* Caching has LV_SHADOW_CACHE_SIZE^2 RAM cost*/
|
||||
#define LV_SHADOW_CACHE_SIZE 0
|
||||
#endif
|
||||
|
||||
/*1: enable outline drawing on rectangles*/
|
||||
#define LV_USE_OUTLINE 0
|
||||
|
||||
/*1: enable pattern drawing on rectangles*/
|
||||
#define LV_USE_PATTERN 0
|
||||
|
||||
/*1: enable value string drawing on rectangles*/
|
||||
#define LV_USE_VALUE_STR 1
|
||||
|
||||
/* 1: Use other blend modes than normal (`LV_BLEND_MODE_...`)*/
|
||||
#define LV_USE_BLEND_MODES 0
|
||||
|
||||
/* 1: Use the `opa_scale` style property to set the opacity of an object and its children at once*/
|
||||
#define LV_USE_OPA_SCALE 0
|
||||
|
||||
/* 1: Use image zoom and rotation*/
|
||||
#define LV_USE_IMG_TRANSFORM 0
|
||||
|
||||
/* 1: Enable object groups (for keyboard/encoder navigation) */
|
||||
#define LV_USE_GROUP 0
|
||||
#define LV_USE_GROUP 1
|
||||
#if LV_USE_GROUP
|
||||
typedef void * lv_group_user_data_t;
|
||||
typedef void* lv_group_user_data_t;
|
||||
#endif /*LV_USE_GROUP*/
|
||||
|
||||
/* 1: Enable GPU interface*/
|
||||
#define LV_USE_GPU 0
|
||||
#define LV_USE_GPU 0 /*Only enables `gpu_fill_cb` and `gpu_blend_cb` in the disp. drv- */
|
||||
#define LV_USE_GPU_STM32_DMA2D 0
|
||||
/*If enabling LV_USE_GPU_STM32_DMA2D, LV_GPU_DMA2D_CMSIS_INCLUDE must be defined to include path of CMSIS header of target processor
|
||||
e.g. "stm32f769xx.h" or "stm32f429xx.h" */
|
||||
#define LV_GPU_DMA2D_CMSIS_INCLUDE
|
||||
|
||||
/*1: Use PXP for CPU off-load on NXP RTxxx platforms */
|
||||
#define LV_USE_GPU_NXP_PXP 0
|
||||
|
||||
/*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 to use FreeRTOS OSA, otherwise bare-metal implementation is selected.
|
||||
*0: lv_gpu_nxp_pxp_init() has to be called manually before lv_init()
|
||||
* */
|
||||
#define LV_USE_GPU_NXP_PXP_AUTO_INIT 0
|
||||
|
||||
/*1: Use VG-Lite for CPU offload on NXP RTxxx platforms */
|
||||
#define LV_USE_GPU_NXP_VG_LITE 0
|
||||
|
||||
/* 1: Enable file system (might be required for images */
|
||||
// TODO: Enable FS
|
||||
#define LV_USE_FILESYSTEM 0
|
||||
#if LV_USE_FILESYSTEM
|
||||
/*Declare the type of the user data of file system drivers (can be e.g. `void *`, `int`, `struct`)*/
|
||||
@ -153,6 +213,13 @@ typedef void * lv_fs_drv_user_data_t;
|
||||
/*1: Add a `user_data` to drivers and objects*/
|
||||
#define LV_USE_USER_DATA 1
|
||||
|
||||
/*1: Show CPU usage and FPS count in the right bottom corner*/
|
||||
#define LV_USE_PERF_MONITOR 0
|
||||
|
||||
/*1: Use the functions and types from the older API if possible */
|
||||
#define LV_USE_API_EXTENSION_V6 0
|
||||
#define LV_USE_API_EXTENSION_V7 1
|
||||
|
||||
/*========================
|
||||
* Image decoder and cache
|
||||
*========================*/
|
||||
@ -161,7 +228,7 @@ typedef void * lv_fs_drv_user_data_t;
|
||||
#define LV_IMG_CF_INDEXED 1
|
||||
|
||||
/* 1: Enable alpha indexed images */
|
||||
#define LV_IMG_CF_ALPHA 1
|
||||
#define LV_IMG_CF_ALPHA 0
|
||||
|
||||
/* Default image cache size. Image caching keeps the images opened.
|
||||
* If only the built-in image formats are used there is no real advantage of caching.
|
||||
@ -172,26 +239,42 @@ typedef void * lv_fs_drv_user_data_t;
|
||||
#define LV_IMG_CACHE_DEF_SIZE 1
|
||||
|
||||
/*Declare the type of the user data of image decoder (can be e.g. `void *`, `int`, `struct`)*/
|
||||
typedef void * lv_img_decoder_user_data_t;
|
||||
typedef void* lv_img_decoder_user_data_t;
|
||||
|
||||
/*=====================
|
||||
* Compiler settings
|
||||
*====================*/
|
||||
|
||||
/* For big endian systems set to 1 */
|
||||
#define LV_BIG_ENDIAN_SYSTEM 0
|
||||
|
||||
/* Define a custom attribute to `lv_tick_inc` function */
|
||||
#define LV_ATTRIBUTE_TICK_INC
|
||||
|
||||
/* Define a custom attribute to `lv_task_handler` function */
|
||||
#define LV_ATTRIBUTE_TASK_HANDLER
|
||||
|
||||
/* Define a custom attribute to `lv_disp_flush_ready` function */
|
||||
#define LV_ATTRIBUTE_FLUSH_READY
|
||||
|
||||
/* Required alignment size for buffers */
|
||||
#define LV_ATTRIBUTE_MEM_ALIGN_SIZE
|
||||
|
||||
/* With size optimization (-Os) the compiler might not align data to
|
||||
* 4 or 8 byte boundary. This alignment will be explicitly applied where needed.
|
||||
* E.g. __attribute__((aligned(4))) */
|
||||
* 4 or 8 byte boundary. Some HW may need even 32 or 64 bytes.
|
||||
* This alignment will be explicitly applied where needed.
|
||||
* LV_ATTRIBUTE_MEM_ALIGN_SIZE should be used to specify required align size.
|
||||
* E.g. __attribute__((aligned(LV_ATTRIBUTE_MEM_ALIGN_SIZE))) */
|
||||
#define LV_ATTRIBUTE_MEM_ALIGN
|
||||
|
||||
/* Attribute to mark large constant arrays for example
|
||||
* font's bitmaps */
|
||||
#define LV_ATTRIBUTE_LARGE_CONST
|
||||
|
||||
/* Prefix performance critical functions to place them into a faster memory (e.g RAM)
|
||||
* Uses 15-20 kB extra memory */
|
||||
//#define LV_ATTRIBUTE_FAST_MEM
|
||||
|
||||
/* Export integer constant to binding.
|
||||
* This macro is used with constants in the form of LV_<CONST> that
|
||||
* should also appear on lvgl binding API such as Micropython
|
||||
@ -200,6 +283,10 @@ typedef void * lv_img_decoder_user_data_t;
|
||||
*/
|
||||
#define LV_EXPORT_CONST_INT(int_value) struct _silence_gcc_warning
|
||||
|
||||
/* Prefix variables that are used in GPU accelerated operations, often these need to be
|
||||
* placed in RAM sections that are DMA accessible */
|
||||
// #define LV_ATTRIBUTE_DMA
|
||||
|
||||
/*===================
|
||||
* HAL settings
|
||||
*==================*/
|
||||
@ -208,12 +295,12 @@ typedef void * lv_img_decoder_user_data_t;
|
||||
* It removes the need to manually update the tick with `lv_tick_inc`) */
|
||||
#define LV_TICK_CUSTOM 0
|
||||
#if LV_TICK_CUSTOM == 1
|
||||
#define LV_TICK_CUSTOM_INCLUDE "something.h" /*Header for the sys time function*/
|
||||
#define LV_TICK_CUSTOM_SYS_TIME_EXPR (millis()) /*Expression evaluating to current systime in ms*/
|
||||
#define LV_TICK_CUSTOM_INCLUDE "Arduino.h" /*Header for the system time function*/
|
||||
#define LV_TICK_CUSTOM_SYS_TIME_EXPR (millis()) /*Expression evaluating to current system time in ms*/
|
||||
#endif /*LV_TICK_CUSTOM*/
|
||||
|
||||
typedef void * lv_disp_drv_user_data_t; /*Type of user data in the display driver*/
|
||||
typedef void * lv_indev_drv_user_data_t; /*Type of user data in the input device driver*/
|
||||
typedef void* lv_disp_drv_user_data_t; /*Type of user data in the display driver*/
|
||||
typedef void* lv_indev_drv_user_data_t; /*Type of user data in the input device driver*/
|
||||
|
||||
/*================
|
||||
* Log settings
|
||||
@ -229,11 +316,11 @@ typedef void * lv_indev_drv_user_data_t; /*Type of user data in the i
|
||||
* LV_LOG_LEVEL_ERROR Only critical issue, when the system may fail
|
||||
* LV_LOG_LEVEL_NONE Do not log anything
|
||||
*/
|
||||
# define LV_LOG_LEVEL LV_LOG_LEVEL_WARN
|
||||
#define LV_LOG_LEVEL LV_LOG_LEVEL_WARN
|
||||
|
||||
/* 1: Print the log with 'printf';
|
||||
* 0: user need to register a callback with `lv_log_register_print_cb`*/
|
||||
# define LV_LOG_PRINTF 0
|
||||
#define LV_LOG_PRINTF 0
|
||||
#endif /*LV_USE_LOG*/
|
||||
|
||||
/*=================
|
||||
@ -258,6 +345,9 @@ typedef void * lv_indev_drv_user_data_t; /*Type of user data in the i
|
||||
/*Checks is the memory is successfully allocated or no. (Quite fast)*/
|
||||
#define LV_USE_ASSERT_MEM 1
|
||||
|
||||
/*Check the integrity of `lv_mem` after critical operations. (Slow)*/
|
||||
#define LV_USE_ASSERT_MEM_INTEGRITY 0
|
||||
|
||||
/* Check the strings.
|
||||
* Search for NULL, very long strings, invalid characters, and unnatural repetitions. (Slow)
|
||||
* If disabled `LV_USE_ASSERT_NULL` will be performed instead (if it's enabled) */
|
||||
@ -268,44 +358,49 @@ typedef void * lv_indev_drv_user_data_t; /*Type of user data in the i
|
||||
#define LV_USE_ASSERT_OBJ 0
|
||||
|
||||
/*Check if the styles are properly initialized. (Fast)*/
|
||||
#define LV_USE_ASSERT_STYLE 1
|
||||
#define LV_USE_ASSERT_STYLE 0
|
||||
|
||||
#endif /*LV_USE_DEBUG*/
|
||||
|
||||
/*================
|
||||
* THEME USAGE
|
||||
*================*/
|
||||
#define LV_THEME_LIVE_UPDATE 0 /*1: Allow theme switching at run time. Uses 8..10 kB of RAM*/
|
||||
|
||||
#define LV_USE_THEME_TEMPL 0 /*Just for test*/
|
||||
#define LV_USE_THEME_DEFAULT 1 /*Built mainly from the built-in styles. Consumes very few RAM*/
|
||||
#define LV_USE_THEME_ALIEN 0 /*Dark futuristic theme*/
|
||||
#define LV_USE_THEME_NIGHT 1 /*Dark elegant theme*/
|
||||
#define LV_USE_THEME_MONO 0 /*Mono color theme for monochrome displays*/
|
||||
#define LV_USE_THEME_MATERIAL 0 /*Flat theme with bold colors and light shadows*/
|
||||
#define LV_USE_THEME_ZEN 0 /*Peaceful, mainly light theme */
|
||||
#define LV_USE_THEME_NEMO 0 /*Water-like theme based on the movie "Finding Nemo"*/
|
||||
|
||||
/*==================
|
||||
* FONT USAGE
|
||||
*===================*/
|
||||
|
||||
/* The built-in fonts contains the ASCII range and some Symbols with 4 bit-per-pixel.
|
||||
* The symbols are available via `LV_SYMBOL_...` defines
|
||||
* More info about fonts: https://docs.littlevgl.com/#Fonts
|
||||
* To create a new font go to: https://littlevgl.com/ttf-font-to-c-array
|
||||
* More info about fonts: https://docs.lvgl.io/v7/en/html/overview/font.html
|
||||
* To create a new font go to: https://lvgl.com/ttf-font-to-c-array
|
||||
*/
|
||||
|
||||
/* Robot fonts with bpp = 4
|
||||
* https://fonts.google.com/specimen/Roboto */
|
||||
#define LV_FONT_ROBOTO_12 0
|
||||
#define LV_FONT_ROBOTO_16 0
|
||||
#define LV_FONT_ROBOTO_22 0
|
||||
#define LV_FONT_ROBOTO_28 0
|
||||
/* Montserrat fonts with bpp = 4
|
||||
* https://fonts.google.com/specimen/Montserrat */
|
||||
#define LV_FONT_MONTSERRAT_8 0
|
||||
#define LV_FONT_MONTSERRAT_10 0
|
||||
#define LV_FONT_MONTSERRAT_12 0
|
||||
#define LV_FONT_MONTSERRAT_14 0
|
||||
#define LV_FONT_MONTSERRAT_16 0
|
||||
#define LV_FONT_MONTSERRAT_18 0
|
||||
#define LV_FONT_MONTSERRAT_20 0
|
||||
#define LV_FONT_MONTSERRAT_22 0
|
||||
#define LV_FONT_MONTSERRAT_24 0
|
||||
#define LV_FONT_MONTSERRAT_26 0
|
||||
#define LV_FONT_MONTSERRAT_28 0
|
||||
#define LV_FONT_MONTSERRAT_30 0
|
||||
#define LV_FONT_MONTSERRAT_32 0
|
||||
#define LV_FONT_MONTSERRAT_34 0
|
||||
#define LV_FONT_MONTSERRAT_36 0
|
||||
#define LV_FONT_MONTSERRAT_38 0
|
||||
#define LV_FONT_MONTSERRAT_40 0
|
||||
#define LV_FONT_MONTSERRAT_42 0
|
||||
#define LV_FONT_MONTSERRAT_44 0
|
||||
#define LV_FONT_MONTSERRAT_46 0
|
||||
#define LV_FONT_MONTSERRAT_48 0
|
||||
|
||||
/* Demonstrate special features */
|
||||
#define LV_FONT_ROBOTO_12_SUBPX 1
|
||||
#define LV_FONT_ROBOTO_28_COMPRESSED 1 /*bpp = 3*/
|
||||
#define LV_FONT_MONTSERRAT_12_SUBPX 0
|
||||
#define LV_FONT_MONTSERRAT_28_COMPRESSED 0 /*bpp = 3*/
|
||||
#define LV_FONT_DEJAVU_16_PERSIAN_HEBREW 0 /*Hebrew, Arabic, PErisan letters and all their forms*/
|
||||
#define LV_FONT_SIMSUN_16_CJK 0 /*1000 most common CJK radicals*/
|
||||
|
||||
/*Pixel perfect monospace font
|
||||
* http://pelulamu.net/unscii/ */
|
||||
@ -314,27 +409,75 @@ typedef void * lv_indev_drv_user_data_t; /*Type of user data in the i
|
||||
/* Optionally declare your custom fonts here.
|
||||
* You can use these fonts as default font too
|
||||
* and they will be available globally. E.g.
|
||||
* #define LV_FONT_CUSTOM_DECLARE LV_FONT_DECLARE(my_font_1) \LV_SUBPX_BGR
|
||||
* #define LV_FONT_CUSTOM_DECLARE LV_FONT_DECLARE(my_font_1) \
|
||||
* LV_FONT_DECLARE(my_font_2)
|
||||
*/
|
||||
#define LV_FONT_CUSTOM_DECLARE
|
||||
|
||||
/*Always set a default font from the built-in fonts*/
|
||||
#define LV_FONT_DEFAULT NULL; // The default font is specified in the custom theme.
|
||||
#define LV_FONT_CUSTOM_DECLARE LV_FONT_DECLARE(jetbrains_mono_bold_20) \
|
||||
LV_FONT_DECLARE(jetbrains_mono_extrabold_compressed)
|
||||
|
||||
/* Enable it if you have fonts with a lot of characters.
|
||||
* The limit depends on the font size, font face and bpp
|
||||
* but with > 10,000 characters if you see issues probably you need to enable it.*/
|
||||
#define LV_FONT_FMT_TXT_LARGE 0
|
||||
|
||||
/* Enables/disables support for compressed fonts. If it's disabled, compressed
|
||||
* glyphs cannot be processed by the library and won't be rendered.
|
||||
*/
|
||||
#define LV_USE_FONT_COMPRESSED 0
|
||||
|
||||
/* Enable subpixel rendering */
|
||||
#define LV_USE_FONT_SUBPX 0
|
||||
#if LV_USE_FONT_SUBPX
|
||||
/* Set the pixel order of the display.
|
||||
* Important only if "subpx fonts" are used.
|
||||
* With "normal" font it doesn't matter.
|
||||
*/
|
||||
#define LV_FONT_SUBPX_BGR 0
|
||||
#endif
|
||||
|
||||
/*Declare the type of the user data of fonts (can be e.g. `void *`, `int`, `struct`)*/
|
||||
typedef void * lv_font_user_data_t;
|
||||
typedef void* lv_font_user_data_t;
|
||||
|
||||
/*================
|
||||
* THEME USAGE
|
||||
*================*/
|
||||
|
||||
/*Always enable at least on theme*/
|
||||
|
||||
/* No theme, you can apply your styles as you need
|
||||
* No flags. Set LV_THEME_DEFAULT_FLAG 0 */
|
||||
#define LV_USE_THEME_EMPTY 1
|
||||
|
||||
/*Simple to the create your theme based on it
|
||||
* No flags. Set LV_THEME_DEFAULT_FLAG 0 */
|
||||
#define LV_USE_THEME_TEMPLATE 0
|
||||
|
||||
/* A fast and impressive theme.
|
||||
* Flags:
|
||||
* LV_THEME_MATERIAL_FLAG_LIGHT: light theme
|
||||
* LV_THEME_MATERIAL_FLAG_DARK: dark theme
|
||||
* LV_THEME_MATERIAL_FLAG_NO_TRANSITION: disable transitions (state change animations)
|
||||
* LV_THEME_MATERIAL_FLAG_NO_FOCUS: disable indication of focused state)
|
||||
* */
|
||||
#define LV_USE_THEME_MATERIAL 0
|
||||
|
||||
/* Mono-color theme for monochrome displays.
|
||||
* If LV_THEME_DEFAULT_COLOR_PRIMARY is LV_COLOR_BLACK the
|
||||
* texts and borders will be black and the background will be
|
||||
* white. Else the colors are inverted.
|
||||
* No flags. Set LV_THEME_DEFAULT_FLAG 0 */
|
||||
#define LV_USE_THEME_MONO 0
|
||||
|
||||
#define LV_THEME_DEFAULT_INCLUDE <stdint.h> /*Include a header for the init. function*/
|
||||
#define LV_THEME_DEFAULT_INIT lv_theme_empty_init//lv_theme_material_init
|
||||
#define LV_THEME_DEFAULT_COLOR_PRIMARY lv_color_hex(0xffffff)
|
||||
#define LV_THEME_DEFAULT_COLOR_SECONDARY lv_color_hex(0xaaaaaa)
|
||||
#define LV_THEME_DEFAULT_FLAG 0//LV_THEME_MATERIAL_FLAG_DARK
|
||||
#define LV_THEME_DEFAULT_FONT_SMALL &jetbrains_mono_bold_20
|
||||
#define LV_THEME_DEFAULT_FONT_NORMAL &jetbrains_mono_bold_20
|
||||
#define LV_THEME_DEFAULT_FONT_SUBTITLE &jetbrains_mono_bold_20
|
||||
#define LV_THEME_DEFAULT_FONT_TITLE &jetbrains_mono_bold_20
|
||||
|
||||
/*=================
|
||||
* Text settings
|
||||
@ -347,7 +490,7 @@ typedef void * lv_font_user_data_t;
|
||||
* */
|
||||
#define LV_TXT_ENC LV_TXT_ENC_UTF8
|
||||
|
||||
/*Can break (wrap) texts on these chars*/
|
||||
/*Can break (wrap) texts on these chars*/
|
||||
#define LV_TXT_BREAK_CHARS " ,.;:-_"
|
||||
|
||||
/* If a word is at least this long, will break wherever "prettiest"
|
||||
@ -378,22 +521,38 @@ typedef void * lv_font_user_data_t;
|
||||
#define LV_BIDI_BASE_DIR_DEF LV_BIDI_DIR_AUTO
|
||||
#endif
|
||||
|
||||
/* Enable Arabic/Persian processing
|
||||
* In these languages characters should be replaced with
|
||||
* an other form based on their position in the text */
|
||||
#define LV_USE_ARABIC_PERSIAN_CHARS 0
|
||||
|
||||
/*Change the built in (v)snprintf functions*/
|
||||
#define LV_SPRINTF_CUSTOM 0
|
||||
#if LV_SPRINTF_CUSTOM
|
||||
# define LV_SPRINTF_INCLUDE <stdio.h>
|
||||
# define lv_snprintf snprintf
|
||||
# define lv_vsnprintf vsnprintf
|
||||
#define LV_SPRINTF_INCLUDE <stdio.h>
|
||||
#define lv_snprintf snprintf
|
||||
#define lv_vsnprintf vsnprintf
|
||||
#else /*!LV_SPRINTF_CUSTOM*/
|
||||
#define LV_SPRINTF_DISABLE_FLOAT 1
|
||||
#endif /*LV_SPRINTF_CUSTOM*/
|
||||
|
||||
/*===================
|
||||
* LV_OBJ SETTINGS
|
||||
*==================*/
|
||||
|
||||
#if LV_USE_USER_DATA
|
||||
/*Declare the type of the user data of object (can be e.g. `void *`, `int`, `struct`)*/
|
||||
typedef void * lv_obj_user_data_t;
|
||||
typedef void* lv_obj_user_data_t;
|
||||
/*Provide a function to free user data*/
|
||||
#define LV_USE_USER_DATA_FREE 0
|
||||
#if LV_USE_USER_DATA_FREE
|
||||
#define LV_USER_DATA_FREE_INCLUDE "something.h" /*Header for user data free function*/
|
||||
/* Function prototype : void user_data_free(lv_obj_t * obj); */
|
||||
#define LV_USER_DATA_FREE (user_data_free) /*Invoking for user data free function*/
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/*1: enable `lv_obj_realaign()` based on `lv_obj_align()` parameters*/
|
||||
/*1: enable `lv_obj_realign()` based on `lv_obj_align()` parameters*/
|
||||
#define LV_USE_OBJ_REALIGN 1
|
||||
|
||||
/* Enable to make the object clickable on a larger area.
|
||||
@ -401,13 +560,13 @@ typedef void * lv_obj_user_data_t;
|
||||
* LV_EXT_CLICK_AREA_TINY: The extra area can be adjusted horizontally and vertically (0..255 px)
|
||||
* LV_EXT_CLICK_AREA_FULL: The extra area can be adjusted in all 4 directions (-32k..+32k px)
|
||||
*/
|
||||
#define LV_USE_EXT_CLICK_AREA LV_EXT_CLICK_AREA_OFF
|
||||
#define LV_USE_EXT_CLICK_AREA LV_EXT_CLICK_AREA_TINY
|
||||
|
||||
/*==================
|
||||
* LV OBJ X USAGE
|
||||
*================*/
|
||||
/*
|
||||
* Documentation of the object types: https://docs.littlevgl.com/#Object-types
|
||||
* Documentation of the object types: https://docs.lvgl.com/#Object-types
|
||||
*/
|
||||
|
||||
/*Arc (dependencies: -)*/
|
||||
@ -418,43 +577,42 @@ typedef void * lv_obj_user_data_t;
|
||||
|
||||
/*Button (dependencies: lv_cont*/
|
||||
#define LV_USE_BTN 1
|
||||
#if LV_USE_BTN != 0
|
||||
/*Enable button-state animations - draw a circle on click (dependencies: LV_USE_ANIMATION)*/
|
||||
# define LV_BTN_INK_EFFECT 0
|
||||
#endif
|
||||
|
||||
/*Button matrix (dependencies: -)*/
|
||||
#define LV_USE_BTNM 1
|
||||
#define LV_USE_BTNMATRIX 1
|
||||
|
||||
/*Calendar (dependencies: -)*/
|
||||
#define LV_USE_CALENDAR 1
|
||||
#if LV_USE_CALENDAR
|
||||
#define LV_CALENDAR_WEEK_STARTS_MONDAY 0
|
||||
#endif
|
||||
|
||||
/*Canvas (dependencies: lv_img)*/
|
||||
#define LV_USE_CANVAS 1
|
||||
|
||||
/*Check box (dependencies: lv_btn, lv_label)*/
|
||||
#define LV_USE_CB 1
|
||||
#define LV_USE_CHECKBOX 1
|
||||
|
||||
/*Chart (dependencies: -)*/
|
||||
#define LV_USE_CHART 1
|
||||
#if LV_USE_CHART
|
||||
# define LV_CHART_AXIS_TICK_LABEL_MAX_LEN 20
|
||||
#define LV_CHART_AXIS_TICK_LABEL_MAX_LEN 256
|
||||
#endif
|
||||
|
||||
/*Container (dependencies: -*/
|
||||
#define LV_USE_CONT 1
|
||||
|
||||
/*Color picker (dependencies: -*/
|
||||
#define LV_USE_CPICKER 1
|
||||
#define LV_USE_CPICKER 0
|
||||
|
||||
/*Drop down list (dependencies: lv_page, lv_label, lv_symbol_def.h)*/
|
||||
#define LV_USE_DDLIST 1
|
||||
#if LV_USE_DDLIST != 0
|
||||
#define LV_USE_DROPDOWN 1
|
||||
#if LV_USE_DROPDOWN != 0
|
||||
/*Open and close default animation time [ms] (0: no animation)*/
|
||||
# define LV_DDLIST_DEF_ANIM_TIME 200
|
||||
#define LV_DROPDOWN_DEF_ANIM_TIME 200
|
||||
#endif
|
||||
|
||||
/*Gauge (dependencies:lv_bar, lv_lmeter)*/
|
||||
/*Gauge (dependencies:lv_bar, lv_linemeter)*/
|
||||
#define LV_USE_GAUGE 1
|
||||
|
||||
/*Image (dependencies: lv_label*/
|
||||
@ -464,30 +622,34 @@ typedef void * lv_obj_user_data_t;
|
||||
#define LV_USE_IMGBTN 1
|
||||
#if LV_USE_IMGBTN
|
||||
/*1: The imgbtn requires left, mid and right parts and the width can be set freely*/
|
||||
# define LV_IMGBTN_TILED 0
|
||||
#define LV_IMGBTN_TILED 0
|
||||
#endif
|
||||
|
||||
/*Keyboard (dependencies: lv_btnm)*/
|
||||
#define LV_USE_KB 1
|
||||
#define LV_USE_KEYBOARD 0
|
||||
|
||||
/*Label (dependencies: -*/
|
||||
#define LV_USE_LABEL 1
|
||||
#if LV_USE_LABEL != 0
|
||||
/*Hor, or ver. scroll speed [px/sec] in 'LV_LABEL_LONG_ROLL/ROLL_CIRC' mode*/
|
||||
# define LV_LABEL_DEF_SCROLL_SPEED 25
|
||||
#define LV_LABEL_DEF_SCROLL_SPEED 25
|
||||
|
||||
/* Waiting period at beginning/end of animation cycle */
|
||||
# define LV_LABEL_WAIT_CHAR_COUNT 3
|
||||
#define LV_LABEL_WAIT_CHAR_COUNT 3
|
||||
|
||||
/*Enable selecting text of the label */
|
||||
# define LV_LABEL_TEXT_SEL 0
|
||||
#define LV_LABEL_TEXT_SEL 0
|
||||
|
||||
/*Store extra some info in labels (12 bytes) to speed up drawing of very long texts*/
|
||||
# define LV_LABEL_LONG_TXT_HINT 0
|
||||
#define LV_LABEL_LONG_TXT_HINT 0
|
||||
#endif
|
||||
|
||||
/*LED (dependencies: -)*/
|
||||
#define LV_USE_LED 1
|
||||
#define LV_USE_LED 0
|
||||
#if LV_USE_LED
|
||||
#define LV_LED_BRIGHT_MIN 120 /*Minimal brightness*/
|
||||
#define LV_LED_BRIGHT_MAX 255 /*Maximal brightness*/
|
||||
#endif
|
||||
|
||||
/*Line (dependencies: -*/
|
||||
#define LV_USE_LINE 1
|
||||
@ -496,38 +658,50 @@ typedef void * lv_obj_user_data_t;
|
||||
#define LV_USE_LIST 1
|
||||
#if LV_USE_LIST != 0
|
||||
/*Default animation time of focusing to a list element [ms] (0: no animation) */
|
||||
# define LV_LIST_DEF_ANIM_TIME 100
|
||||
#define LV_LIST_DEF_ANIM_TIME 100
|
||||
#endif
|
||||
|
||||
/*Line meter (dependencies: *;)*/
|
||||
#define LV_USE_LMETER 1
|
||||
#define LV_USE_LINEMETER 1
|
||||
#if LV_USE_LINEMETER
|
||||
/* Draw line more precisely at cost of performance.
|
||||
* Useful if there are lot of lines any minor are visible
|
||||
* 0: No extra precision
|
||||
* 1: Some extra precision
|
||||
* 2: Best precision
|
||||
*/
|
||||
#define LV_LINEMETER_PRECISE 0
|
||||
#endif
|
||||
|
||||
/*Mask (dependencies: -)*/
|
||||
#define LV_USE_OBJMASK 1
|
||||
|
||||
/*Message box (dependencies: lv_rect, lv_btnm, lv_label)*/
|
||||
#define LV_USE_MBOX 1
|
||||
#define LV_USE_MSGBOX 1
|
||||
|
||||
/*Page (dependencies: lv_cont)*/
|
||||
#define LV_USE_PAGE 1
|
||||
#if LV_USE_PAGE != 0
|
||||
/*Focus default animation time [ms] (0: no animation)*/
|
||||
# define LV_PAGE_DEF_ANIM_TIME 400
|
||||
#define LV_PAGE_DEF_ANIM_TIME 400
|
||||
#endif
|
||||
|
||||
/*Preload (dependencies: lv_arc, lv_anim)*/
|
||||
#define LV_USE_PRELOAD 0
|
||||
#if LV_USE_PRELOAD != 0
|
||||
# define LV_PRELOAD_DEF_ARC_LENGTH 60 /*[deg]*/
|
||||
# define LV_PRELOAD_DEF_SPIN_TIME 1000 /*[ms]*/
|
||||
# define LV_PRELOAD_DEF_ANIM LV_PRELOAD_TYPE_SPINNING_ARC
|
||||
#define LV_USE_SPINNER 0
|
||||
#if LV_USE_SPINNER != 0
|
||||
#define LV_SPINNER_DEF_ARC_LENGTH 60 /*[deg]*/
|
||||
#define LV_SPINNER_DEF_SPIN_TIME 1000 /*[ms]*/
|
||||
#define LV_SPINNER_DEF_ANIM LV_SPINNER_TYPE_SPINNING_ARC
|
||||
#endif
|
||||
|
||||
/*Roller (dependencies: lv_ddlist)*/
|
||||
#define LV_USE_ROLLER 1
|
||||
#if LV_USE_ROLLER != 0
|
||||
/*Focus animation time [ms] (0: no animation)*/
|
||||
# define LV_ROLLER_DEF_ANIM_TIME 200
|
||||
#define LV_ROLLER_DEF_ANIM_TIME 200
|
||||
|
||||
/*Number of extra "pages" when the roller is infinite*/
|
||||
# define LV_ROLLER_INF_PAGES 7
|
||||
#define LV_ROLLER_INF_PAGES 7
|
||||
#endif
|
||||
|
||||
/*Slider (dependencies: lv_bar)*/
|
||||
@ -537,33 +711,35 @@ typedef void * lv_obj_user_data_t;
|
||||
#define LV_USE_SPINBOX 1
|
||||
|
||||
/*Switch (dependencies: lv_slider)*/
|
||||
#define LV_USE_SW 1
|
||||
#define LV_USE_SWITCH 1
|
||||
|
||||
/*Text area (dependencies: lv_label, lv_page)*/
|
||||
#define LV_USE_TA 1
|
||||
#if LV_USE_TA != 0
|
||||
# define LV_TA_DEF_CURSOR_BLINK_TIME 400 /*ms*/
|
||||
# define LV_TA_DEF_PWD_SHOW_TIME 1500 /*ms*/
|
||||
#define LV_USE_TEXTAREA 1
|
||||
#if LV_USE_TEXTAREA != 0
|
||||
#define LV_TEXTAREA_DEF_CURSOR_BLINK_TIME 400 /*ms*/
|
||||
#define LV_TEXTAREA_DEF_PWD_SHOW_TIME 1500 /*ms*/
|
||||
#endif
|
||||
|
||||
/*Table (dependencies: lv_label)*/
|
||||
#define LV_USE_TABLE 1
|
||||
#if LV_USE_TABLE
|
||||
# define LV_TABLE_COL_MAX 12
|
||||
#define LV_TABLE_COL_MAX 12
|
||||
#define LV_TABLE_CELL_STYLE_CNT 5
|
||||
#endif
|
||||
|
||||
|
||||
/*Tab (dependencies: lv_page, lv_btnm)*/
|
||||
#define LV_USE_TABVIEW 1
|
||||
# if LV_USE_TABVIEW != 0
|
||||
/*Time of slide animation [ms] (0: no animation)*/
|
||||
# define LV_TABVIEW_DEF_ANIM_TIME 300
|
||||
#define LV_TABVIEW_DEF_ANIM_TIME 300
|
||||
#endif
|
||||
|
||||
/*Tileview (dependencies: lv_page) */
|
||||
#define LV_USE_TILEVIEW 1
|
||||
#if LV_USE_TILEVIEW
|
||||
/*Time of slide animation [ms] (0: no animation)*/
|
||||
# define LV_TILEVIEW_DEF_ANIM_TIME 300
|
||||
#define LV_TILEVIEW_DEF_ANIM_TIME 300
|
||||
#endif
|
||||
|
||||
/*Window (dependencies: lv_cont, lv_btn, lv_label, lv_img, lv_page)*/
|
||||
@ -574,14 +750,9 @@ typedef void * lv_obj_user_data_t;
|
||||
*==================*/
|
||||
|
||||
#if defined(_MSC_VER) && !defined(_CRT_SECURE_NO_WARNINGS) /* Disable warnings for Visual Studio*/
|
||||
# define _CRT_SECURE_NO_WARNINGS
|
||||
#define _CRT_SECURE_NO_WARNINGS
|
||||
#endif
|
||||
|
||||
/*--END OF LV_CONF_H--*/
|
||||
|
||||
/*Be sure every define has a default value*/
|
||||
#include "lvgl/src/lv_conf_checker.h"
|
||||
|
||||
#endif /*LV_CONF_H*/
|
||||
|
||||
#endif /*End of "Content enable"*/
|
||||
#endif /*LV_CONF_H*/
|
1
src/libs/lvgl
Submodule
1
src/libs/lvgl
Submodule
@ -0,0 +1 @@
|
||||
Subproject commit b89c30eafe1397a778ae5d65f108a0ef820de124
|
@ -1,8 +0,0 @@
|
||||
MIT licence
|
||||
Copyright (c) 2016 Gábor Kiss-Vámosi
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
@ -1,398 +0,0 @@
|
||||
<h1 align="center"> LittlevGL - Open-source Embedded GUI Library</h1>
|
||||
<p align="center">
|
||||
<a href="https://github.com/littlevgl/lvgl/blob/master/LICENCE.txt"><img src="https://img.shields.io/badge/licence-MIT-blue.svg"></a>
|
||||
<a href="https://github.com/littlevgl/lvgl/releases/tag/v6.0"><img src="https://img.shields.io/badge/version-6.0-blue.svg"></a>
|
||||
</p>
|
||||
|
||||
<p align="center">
|
||||
<img src="https://littlevgl.com/github/cover_ori_reduced_2.gif">
|
||||
</p>
|
||||
|
||||
<p align="center">
|
||||
LittlevGL provides everything you need to create a Graphical User Interface (GUI) on embedded systems with easy-to-use graphical elements, beautiful visual effects and low memory footprint.
|
||||
</p>
|
||||
|
||||
<h4 align="center">
|
||||
<a href="https://littlevgl.com">Website </a> ·
|
||||
<a href="https://littlevgl.com/live-demo">Live demo</a> ·
|
||||
<a href="https://docs.littlevgl.com/en/html/get-started/pc-simulator.html">Simulator</a> ·
|
||||
<a href="https://forum.littlevgl.com">Forum</a> ·
|
||||
<a href="https://docs.littlevgl.com/">Docs</a> ·
|
||||
<a href="https://blog.littlevgl.com/">Blog</a>
|
||||
</h4>
|
||||
|
||||
---
|
||||
|
||||
- [Features](#features)
|
||||
- [Supported devices](#supported-devices)
|
||||
- [Quick start in a simulator](#quick-start-in-a-simulator)
|
||||
- [Add LittlevGL to your project](#add-littlevgl-to-your-project)
|
||||
- [Learn the basics](#learn-the-basics)
|
||||
- [Examples](#examples)
|
||||
- [Contributing](#contributing)
|
||||
- [Donate](#donate)
|
||||
|
||||
|
||||
## Features
|
||||
* **Powerful building blocks** buttons, charts, lists, sliders, images, etc.
|
||||
* **Advanced graphics** with animations, anti-aliasing, opacity, smooth scrolling
|
||||
* **Simultaneously use various input devices** touchscreen, mouse, keyboard, encoder, buttons, etc.
|
||||
* **Simultaneously use multiple displays** i.e. monochrome and color display
|
||||
* **Multi-language support** with UTF-8 encoding
|
||||
* **Fully customizable** graphical elements
|
||||
* **Hardware independent** to use with any microcontroller or display
|
||||
* **Scalable** to operate with little memory (64 kB Flash, 10 kB RAM)
|
||||
* **OS, External memory and GPU** supported but not required
|
||||
* **Single frame buffer** operation even with advances graphical effects
|
||||
* **Written in C** for maximal compatibility
|
||||
* **Micropython Binding** exposes [LittlevGL API in Micropython](https://blog.littlevgl.com/2019-02-20/micropython-bindings)
|
||||
* **Simulator** to develop on PC without embedded hardware
|
||||
* **Tutorials, examples, themes** for rapid development
|
||||
* **Documentation** and API references
|
||||
|
||||
## Supported devices
|
||||
Basically, every modern controller - which is able to drive a display - is suitable to run LittlevGL. The minimal requirements:
|
||||
- 16, 32 or 64 bit microcontroller or processor
|
||||
- > 16 MHz clock speed is recommended
|
||||
- Flash/ROM: > 64 kB for the very essential components (> 180 kB is recommended)
|
||||
- RAM:
|
||||
- Static RAM usage: ~8..16 kB depending on the used features and objects types
|
||||
- Stack: > 2kB (> 4 kB is recommended)
|
||||
- Dynamic data (heap): > 4 KB (> 16 kB is recommended if using several objects).
|
||||
Set by `LV_MEM_SIZE` in *lv_conf.h*.
|
||||
- Display buffer: > *"Horizontal resolution"* pixels (> 10 × *"Horizontal resolution"* is recommended)
|
||||
- C99 or newer compiler
|
||||
|
||||
*Note that the memory usage might vary depending on the architecture, compiler and build options.*
|
||||
|
||||
Just to mention some **platforms**:
|
||||
- STM32F1, STM32F3, [STM32F4](https://blog.littlevgl.com/2017-07-15/stm32f429_disco_port), [STM32F7](https://github.com/littlevgl/stm32f746_disco_no_os_sw4stm32)
|
||||
- Microchip dsPIC33, PIC24, PIC32MX, PIC32MZ
|
||||
- NXP Kinetis, LPC, iMX
|
||||
- [Linux frame buffer](https://blog.littlevgl.com/2018-01-03/linux_fb) (/dev/fb)
|
||||
- [Raspberry PI](http://www.vk3erw.com/index.php/16-software/63-raspberry-pi-official-7-touchscreen-and-littlevgl)
|
||||
- [Espressif ESP32](https://github.com/littlevgl/esp32_ili9431)
|
||||
- Nordic nrf52
|
||||
- Quectell M66
|
||||
|
||||
## Quick start in a simulator
|
||||
The easiest way to get started with LittlevGL is to run it in a simulator on your PC without any embedded hardware.
|
||||
|
||||
Choose a project with your favourite IDE:
|
||||
|
||||
| Eclipse | CodeBlocks | Visual Studio | PlatformIO | Qt Creator |
|
||||
|-------------|-------------|---------------|-----------|------------|
|
||||
| [![Eclipse](https://littlevgl.com/logo/ide/eclipse.jpg)](https://github.com/littlevgl/pc_simulator_sdl_eclipse) | [![CodeBlocks](https://littlevgl.com/logo/ide/codeblocks.jpg)](https://github.com/littlevgl/pc_simulator_win_codeblocks) | [![VisualStudio](https://littlevgl.com/logo/ide/visualstudio.jpg)](https://github.com/littlevgl/visual_studio_2017_sdl_x64) | [![PlatformIO](https://littlevgl.com/logo/ide/platformio.jpg)](https://github.com/littlevgl/pc_simulator_sdl_platformio) | [![QtCreator](https://littlevgl.com/logo/ide/qtcreator.jpg)](https://blog.littlevgl.com/2019-01-03/qt-creator) |
|
||||
| Cross-platform<br>with SDL<br>(Recommended on<br>Linux and Mac) | Native Windows | Windows<br>with SDL | Cross-platform<br>with SDL | Cross-platform<br>with SDL |
|
||||
|
||||
|
||||
## Add LittlevGL to your project
|
||||
|
||||
The steps below show how to setup LittlevGL on an embedded system with a display and a touchpad.
|
||||
You can use the [Simulators](https://docs.littlevgl.com/en/html/get-started/pc-simulator) to get ready to use projects which can be run on your PC.
|
||||
|
||||
1. [Download](https://littlevgl.com/download) or [Clone](https://github.com/littlevgl/lvgl) the library
|
||||
2. Copy the `lvgl` folder into your project
|
||||
3. Copy `lvgl/lv_conf_template.h` as `lv_conf.h` next to the `lvgl` folder and set at least `LV_HOR_RES_MAX`, `LV_VER_RES_MAX` and `LV_COLOR_DEPTH`.
|
||||
4. Include `lvgl/lvgl.h` where you need to use LittlevGL related functions.
|
||||
5. 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 LittlevGL.
|
||||
6. Call `lv_init()`
|
||||
7. Create a display buffer for LittlevGL
|
||||
```c
|
||||
static lv_disp_buf_t disp_buf;
|
||||
static lv_color_t buf[LV_HOR_RES_MAX * 10]; /*Declare a buffer for 10 lines*/
|
||||
lv_disp_buf_init(&disp_buf, buf, NULL, LV_HOR_RES_MAX * 10); /*Initialize the display buffer*/
|
||||
```
|
||||
8. Implement and register a function which can **copy a pixel array** to an area of your display:
|
||||
```c
|
||||
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 = &disp_buf; /*Assign the buffer to the display*/
|
||||
lv_disp_drv_register(&disp_drv); /*Finally register the driver*/
|
||||
|
||||
void my_disp_flush(lv_disp_t * disp, const lv_area_t * area, lv_color_t * color_p)
|
||||
{
|
||||
int32_t x, y;
|
||||
for(y = area->y1; y <= area->y2; y++) {
|
||||
for(x = area->x1; x <= area->x2; x++) {
|
||||
set_pixel(x, y, *color_p); /* Put a pixel to the display.*/
|
||||
color_p++;
|
||||
}
|
||||
}
|
||||
|
||||
lv_disp_flush_ready(disp); /* Indicate you are ready with the flushing*/
|
||||
}
|
||||
|
||||
```
|
||||
9. Implement and register a function which can **read an input device**. E.g. for a touch pad:
|
||||
```c
|
||||
lv_indev_drv_init(&indev_drv); /*Descriptor of a input device driver*/
|
||||
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_drv_t * indev_driver, lv_indev_data_t * data)
|
||||
{
|
||||
static lv_coord_t last_x = 0;
|
||||
static lv_coord_t last_y = 0;
|
||||
|
||||
/*Save the state and save the pressed coordinate*/
|
||||
data->state = touchpad_is_pressed() ? LV_INDEV_STATE_PR : LV_INDEV_STATE_REL;
|
||||
if(data->state == LV_INDEV_STATE_PR) touchpad_get_xy(&last_x, &last_y);
|
||||
|
||||
/*Set the coordinates (if released use the last pressed coordinates)*/
|
||||
data->point.x = last_x;
|
||||
data->point.y = last_y;
|
||||
|
||||
return false; /*Return `false` because we are not buffering and no more data to read*/
|
||||
}
|
||||
```
|
||||
10. Call `lv_task_handler()` periodically every few milliseconds in the main `while(1)` loop, in Timer interrupt or in an Operation system task.
|
||||
It will redraw the screen if required, handle input devices etc.
|
||||
|
||||
|
||||
## Learn the basics
|
||||
|
||||
### Objects (Widgets)
|
||||
|
||||
The graphical elements like Buttons, Labels, Sliders, Charts etc are called objects in LittelvGL. Go to [Object types](https://docs.littlevgl.com/en/html/object-types/index) to see the full list of available types.
|
||||
|
||||
Every object has a parent object. The child object moves with the parent and if you delete the parent the children will be deleted too. Children can be visible only on their parent.
|
||||
|
||||
The *screen* are the "root" parents. To get the current screen call `lv_scr_act()`.
|
||||
|
||||
You can create a new object with `lv_<type>_create(parent, obj_to_copy)`. It will return an `lv_obj_t *` variable which should be used as a reference to the object to set its parameters.
|
||||
The first parameter is the desired *parent*, te second parameters can be an object to copy (`NULL` is unused).
|
||||
For example:
|
||||
```c
|
||||
lv_obj_t * slider1 = lv_slider_create(lv_scr_act(), NULL);
|
||||
```
|
||||
|
||||
To set some basic attribute `lv_obj_set_<paramters_name>(obj, <value>)` function 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 objects has type specific parameters too which can be set by `lv_<type>_set_<paramters_name>(obj, <value>)` functions. For example:
|
||||
```c
|
||||
lv_slider_set_value(slider1, 70, LV_ANIM_ON);
|
||||
```
|
||||
|
||||
To see the full API visit the documentation of the object types or the related header file (e.g. `lvgl/src/lv_objx/lv_slider.h`).
|
||||
|
||||
### Styles
|
||||
Styles can be assigned to the objects to changed their appearance. A style describes the appearance of rectangle-like objects (like a button or slider), texts, images and lines at once.
|
||||
|
||||
You can create a new style like this:
|
||||
```c
|
||||
static lv_style_t style1; /*Declare a new style. Should be `static`*/
|
||||
lv_style_copy(&style1, &lv_style_plain); /*Copy a built-in style*/
|
||||
style1.body.main_color = LV_COLOR_RED; /*Main color*/
|
||||
style1.body.grad_color = lv_color_hex(0xffd83c) /*Gradient color (orange)*/
|
||||
style1.body.radius = 3;
|
||||
style1.text.color = lv_color_hex3(0x0F0) /*Label color (green)*/
|
||||
style1.text.font = &lv_font_dejavu_22; /*Change font*/
|
||||
...
|
||||
```
|
||||
|
||||
To set a new style for an object use the `lv_<type>set_style(obj, LV_<TYPE>_STYLE_<NAME>, &my_style)` functions. For example:
|
||||
```c
|
||||
lv_slider_set_style(slider1, LV_SLIDER_STYLE_BG, &slider_bg_style);
|
||||
lv_slider_set_style(slider1, LV_SLIDER_STYLE_INDIC, &slider_indic_style);
|
||||
lv_slider_set_style(slider1, LV_SLIDER_STYLE_KNOB, &slider_knob_style);
|
||||
```
|
||||
|
||||
If an object's style is `NULL` then it will inherit its parent's style. For example, the labels' style are `NULL` by default. If you place them on a button then they will use the `style.text` properties from the button's style.
|
||||
|
||||
Learn more in [Style overview](https://docs.littlevgl.com/en/html/overview/style) section.
|
||||
|
||||
### Events
|
||||
Events are used to inform the user if something has happened with an object. You can assign a callback to an object which will be called if the object is clicked, released, dragged, being deleted etc. It should look like this:
|
||||
|
||||
```c
|
||||
lv_obj_set_event_cb(btn, btn_event_cb); /*Assign a callback to the button*/
|
||||
|
||||
...
|
||||
|
||||
void btn_event_cb(lv_obj_t * btn, lv_event_t event)
|
||||
{
|
||||
if(event == LV_EVENT_CLICKED) {
|
||||
printf("Clicked\n");
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Learn more about the events in the [Event overview](https://docs.littlevgl.com/en/html/overview/event) section.
|
||||
|
||||
|
||||
## Examples
|
||||
|
||||
### Button with label
|
||||
```c
|
||||
lv_obj_t * btn = lv_btn_create(lv_scr_act(), NULL); /*Add a button the current screen*/
|
||||
lv_obj_set_pos(btn, 10, 10); /*Set its position*/
|
||||
lv_obj_set_size(btn, 100, 50); /*Set its size*/
|
||||
lv_obj_set_event_cb(btn, btn_event_cb); /*Assign a callback to the button*/
|
||||
|
||||
lv_obj_t * label = lv_label_create(btn, NULL); /*Add a label to the button*/
|
||||
lv_label_set_text(label, "Button"); /*Set the labels text*/
|
||||
|
||||
...
|
||||
|
||||
void btn_event_cb(lv_obj_t * btn, lv_event_t event)
|
||||
{
|
||||
if(event == LV_EVENT_CLICKED) {
|
||||
printf("Clicked\n");
|
||||
}
|
||||
}
|
||||
```
|
||||
![LittlevGL button with label example](https://docs.littlevgl.com/en/misc/simple_button_example.gif)
|
||||
|
||||
### Button with styles
|
||||
Add styles to the previously button from the previous example
|
||||
```c
|
||||
static lv_style_t style_btn_rel; /*A variable to store the released style*/
|
||||
lv_style_copy(&style_btn_rel, &lv_style_plain); /*Initialize from a built-in style*/
|
||||
style_btn_rel.body.border.color = lv_color_hex3(0x269);
|
||||
style_btn_rel.body.border.width = 1;
|
||||
style_btn_rel.body.main_color = lv_color_hex3(0xADF);
|
||||
style_btn_rel.body.grad_color = lv_color_hex3(0x46B);
|
||||
style_btn_rel.body.shadow.width = 4;
|
||||
style_btn_rel.body.shadow.type = LV_SHADOW_BOTTOM;
|
||||
style_btn_rel.body.radius = LV_RADIUS_CIRCLE;
|
||||
style_btn_rel.text.color = lv_color_hex3(0xDEF);
|
||||
|
||||
static lv_style_t style_btn_pr; /*A variable to store the pressed style*/
|
||||
lv_style_copy(&style_btn_pr, &style_btn_rel); /*Initialize from the released style*/
|
||||
style_btn_pr.body.border.color = lv_color_hex3(0x46B);
|
||||
style_btn_pr.body.main_color = lv_color_hex3(0x8BD);
|
||||
style_btn_pr.body.grad_color = lv_color_hex3(0x24A);
|
||||
style_btn_pr.body.shadow.width = 2;
|
||||
style_btn_pr.text.color = lv_color_hex3(0xBCD);
|
||||
|
||||
lv_btn_set_style(btn, LV_BTN_STYLE_REL, &style_btn_rel); /*Set the button's released style*/
|
||||
lv_btn_set_style(btn, LV_BTN_STYLE_PR, &style_btn_pr); /*Set the button's pressed style*/
|
||||
```
|
||||
|
||||
![Stylsd button is LittelvGL](https://docs.littlevgl.com/en/misc/button_style_example.gif)
|
||||
|
||||
### Slider and object alignment
|
||||
```c
|
||||
lv_obj_t * label;
|
||||
|
||||
...
|
||||
|
||||
/* Create a slider in the center of the display */
|
||||
lv_obj_t * slider = lv_slider_create(lv_scr_act(), NULL);
|
||||
lv_obj_set_width(slider, 200); /*Set the width*/
|
||||
lv_obj_align(slider, NULL, LV_ALIGN_CENTER, 0, 0); /*Align to the center of the parent (screen)*/
|
||||
lv_obj_set_event_cb(slider, slider_event_cb); /*Assign an event function*/
|
||||
|
||||
/* Create a label below the slider */
|
||||
label = lv_label_create(lv_scr_act(), NULL);
|
||||
lv_label_set_text(label, "0");
|
||||
lv_obj_set_auto_realign(slider, true);
|
||||
lv_obj_align(label, slider, LV_ALIGN_OUT_BOTTOM_MID, 0, 10);
|
||||
|
||||
...
|
||||
|
||||
void slider_event_cb(lv_obj_t * slider, lv_event_t event)
|
||||
{
|
||||
if(event == LV_EVENT_VALUE_CHANGED) {
|
||||
static char buf[4]; /* max 3 bytes for number plus 1 null terminating byte */
|
||||
snprintf(buf, 4, "%u", lv_slider_get_value(slider));
|
||||
lv_label_set_text(slider_label, buf); /*Refresh the text*/
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
![Slider example with LittlevGL](https://docs.littlevgl.com/en/misc/slider_example.gif)
|
||||
|
||||
### List and themes
|
||||
```c
|
||||
/*Texts of the list elements*/
|
||||
const char * txts[] = {"First", "Second", "Third", "Forth", "Fifth", "Sixth", NULL};
|
||||
|
||||
/* Initialize and set a theme. `LV_THEME_NIGHT` needs to enabled in lv_conf.h. */
|
||||
lv_theme_t * th = lv_theme_night_init(20, NULL);
|
||||
lv_theme_set_current(th);
|
||||
|
||||
/*Create a list*/
|
||||
lv_obj_t* list = lv_list_create(lv_scr_act(), NULL);
|
||||
lv_obj_set_size(list, 120, 180);
|
||||
lv_obj_set_pos(list, 10, 10);
|
||||
|
||||
/*Add buttons*/
|
||||
uint8_t i;
|
||||
for(i = 0; txts[i]; i++) {
|
||||
lv_obj_t * btn = lv_list_add_btn(list, LV_SYMBOL_FILE, txts[i]);
|
||||
lv_obj_set_event_cb(btn, list_event); /*Assign event function*/
|
||||
lv_btn_set_toggle(btn, true); /*Enable on/off states*/
|
||||
}
|
||||
|
||||
/* Initialize and set an other theme. `LV_THEME_MATERIAL` needs to enabled in lv_conf.h.
|
||||
* If `LV_TEHE_LIVE_UPDATE 1` then the previous list's style will be updated too.*/
|
||||
th = lv_theme_material_init(210, NULL);
|
||||
lv_theme_set_current(th);
|
||||
|
||||
/*Create an other list*/
|
||||
list = lv_list_create(lv_scr_act(), NULL);
|
||||
lv_obj_set_size(list, 120, 180);
|
||||
lv_obj_set_pos(list, 150, 10);
|
||||
|
||||
/*Add buttons with the same texts*/
|
||||
for(i = 0; txts[i]; i++) {
|
||||
lv_obj_t * btn = lv_list_add_btn(list, LV_SYMBOL_FILE, txts[i]);
|
||||
lv_obj_set_event_cb(btn, list_event);
|
||||
lv_btn_set_toggle(btn, true);
|
||||
}
|
||||
|
||||
...
|
||||
|
||||
static void list_event(lv_obj_t * btn, lv_event_t e)
|
||||
{
|
||||
if(e == LV_EVENT_CLICKED) {
|
||||
printf("%s\n", lv_list_get_btn_text(btn));
|
||||
}
|
||||
|
||||
}
|
||||
```
|
||||
![List and theme example with LittlevGL](https://docs.littlevgl.com/en/misc/list_theme_example.gif)
|
||||
|
||||
### Use LittlevGL from Micropython
|
||||
Learn more about [Micropython](https://docs.littlevgl.com/en/html/get-started/micropython).
|
||||
```python
|
||||
# Create a Button and a Label
|
||||
scr = lv.obj()
|
||||
btn = lv.btn(scr)
|
||||
btn.align(lv.scr_act(), lv.ALIGN.CENTER, 0, 0)
|
||||
label = lv.label(btn)
|
||||
label.set_text("Button")
|
||||
|
||||
# Load the screen
|
||||
lv.scr_load(scr)
|
||||
```
|
||||
|
||||
## Contributing
|
||||
To ask questions please use the [Forum](https://forum.littlevgl.com).
|
||||
For development-related things (bug reports, feature suggestions) use [GitHub's Issue tracker](https://github.com/littlevgl/lvgl/issues).
|
||||
|
||||
If you are interested in contributing to LittlevGL you can
|
||||
- **Help others** in the [Forum](https://forum.littlevgl.com).
|
||||
- **Inspire people** by speaking about your project in [My project](https://forum.littlevgl.com/c/my-projects) category in the Forum or add it to the [References](https://blog.littlevgl.com/2018-12-26/references) post
|
||||
- **Improve and/or translate the documentation.** Go to the [Documentation](https://github.com/littlevgl/docs) repository to learn more
|
||||
- **Write a blog post** about your experiences. See how to do it in the [Blog](https://github.com/littlevgl/blog) repository
|
||||
- **Report and/or fix bugs** in [GitHub's issue tracker](https://github.com/littlevgl/lvgl/issues)
|
||||
- **Help in the developement**. Check the [Open issues](https://github.com/littlevgl/lvgl/issues) especially the ones with [Help wanted](https://github.com/littlevgl/lvgl/issues?q=is%3Aissue+is%3Aopen+label%3A%22help+wanted%22) label and tell your ideas about a topic or implement a feature.
|
||||
|
||||
It should be useful to read the
|
||||
- [Contributing guide](https://blog.littlevgl.com/2018-12-06/contributing)
|
||||
- [Coding style guide](https://github.com/littlevgl/lvgl/blob/master/docs/CODING_STYLE.md)
|
||||
|
||||
## Donate
|
||||
If you are pleased with the library, found it useful, or you are happy with the support you got, please help its further development:
|
||||
|
||||
[![Donate](https://littlevgl.com/donate_dir/donate_btn.png)](https://littlevgl.com/donate)
|
@ -1,46 +0,0 @@
|
||||
# Contributor Covenant Code of Conduct
|
||||
|
||||
## Our Pledge
|
||||
|
||||
In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation.
|
||||
|
||||
## Our Standards
|
||||
|
||||
Examples of behavior that contributes to creating a positive environment include:
|
||||
|
||||
* Using welcoming and inclusive language
|
||||
* Being respectful of differing viewpoints and experiences
|
||||
* Gracefully accepting constructive criticism
|
||||
* Focusing on what is best for the community
|
||||
* Showing empathy towards other community members
|
||||
|
||||
Examples of unacceptable behavior by participants include:
|
||||
|
||||
* The use of sexualized language or imagery and unwelcome sexual attention or advances
|
||||
* Trolling, insulting/derogatory comments, and personal or political attacks
|
||||
* Public or private harassment
|
||||
* Publishing others' private information, such as a physical or electronic address, without explicit permission
|
||||
* Other conduct which could reasonably be considered inappropriate in a professional setting
|
||||
|
||||
## Our Responsibilities
|
||||
|
||||
Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior.
|
||||
|
||||
Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful.
|
||||
|
||||
## Scope
|
||||
|
||||
This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers.
|
||||
|
||||
## Enforcement
|
||||
|
||||
Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at [atom@github.com](mailto:atom@github.com). All complaints will be reviewed and investigated and will result in a response that is deemed necessary and appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately.
|
||||
|
||||
Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership.
|
||||
|
||||
## Attribution
|
||||
|
||||
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [http://contributor-covenant.org/version/1/4][version]
|
||||
|
||||
[homepage]: http://contributor-covenant.org
|
||||
[version]: http://contributor-covenant.org/version/1/4/
|
@ -1,94 +0,0 @@
|
||||
|
||||
## File format
|
||||
Use [lv_misc/lv_templ.c](https://github.com/littlevgl/lvgl/blob/master/src/lv_misc/lv_templ.c) and [lv_misc/lv_templ.h](https://github.com/littlevgl/lvgl/blob/master/src/lv_misc/lv_templ.h)
|
||||
|
||||
## Naming conventions
|
||||
* Words are separated by '_'
|
||||
* In variable and function names use only lower case letters (e.g. *height_tmp*)
|
||||
* In enums and defines use only upper case letters (e.g. *e.g. MAX_LINE_NUM*)
|
||||
* Global names (API):
|
||||
* starts with *lv*
|
||||
* followed by module name: *btn*, *label*, *style* etc.
|
||||
* followed by the action (for functions): *set*, *get*, *refr* etc.
|
||||
* closed with the subject: *name*, *size*, *state* etc.
|
||||
* Typedefs
|
||||
* prefer `typedef struct` and `typedef enum` instead of `struct name` and `enum name`
|
||||
* always end `typedef struct` and `typedef enum` type names with `_t`
|
||||
* Abbreviations:
|
||||
* Use abbreviations on public names only if they become longer than 32 characters
|
||||
* Use only very straightforward (e.g. pos: position) or well-established (e.g. pr: press) abbreviations
|
||||
|
||||
## Coding guide
|
||||
* Functions:
|
||||
* Try to write function shorter than is 50 lines
|
||||
* Always shorter than 100 lines (except very straightforwards)
|
||||
* Variables:
|
||||
* One line, one declaration (BAD: char x, y;)
|
||||
* Use `<stdint.h>` (*uint8_t*, *int32_t* etc)
|
||||
* Declare variables when needed (not all at function start)
|
||||
* Use the smallest required scope
|
||||
* Variables in a file (outside functions) are always *static*
|
||||
* Do not use global variables (use functions to set/get static variables)
|
||||
|
||||
## Comments
|
||||
Before every function have a comment like this:
|
||||
|
||||
```c
|
||||
/**
|
||||
* Return with the screen of an object
|
||||
* @param obj pointer to an object
|
||||
* @return pointer to a screen
|
||||
*/
|
||||
lv_obj_t * lv_obj_get_scr(lv_obj_t * obj);
|
||||
```
|
||||
|
||||
Always use `/* Something */` format and NOT `//Something`
|
||||
|
||||
Write readable code to avoid descriptive comments like:
|
||||
`x++; /* Add 1 to x */`.
|
||||
The code should show clearly what you are doing.
|
||||
|
||||
You should write **why** have you done this:
|
||||
`x++; /*Because of closing '\0' of the string */`
|
||||
|
||||
Short "code summaries" of a few lines are accepted. E.g. `/*Calculate the new coordinates*/`
|
||||
|
||||
In comments use \` \` when referring to a variable. E.g. ``/*Update the value of `x_act`*/``
|
||||
|
||||
### Formatting
|
||||
Here is example to show bracket placing and using of white spaces:
|
||||
```c
|
||||
/**
|
||||
* Set a new text for a label. Memory will be allocated to store the text by the label.
|
||||
* @param label pointer to a label object
|
||||
* @param text '\0' terminated character string. NULL to refresh with the current text.
|
||||
*/
|
||||
void lv_label_set_text(lv_obj_t * label, const char * text)
|
||||
{ /* Main brackets of functions in new line*/
|
||||
|
||||
if(label == NULL) return; /*No bracket only if the command is inline with the if statement*/
|
||||
|
||||
lv_obj_inv(label);
|
||||
|
||||
lv_label_ext_t * ext = lv_obj_get_ext(label);
|
||||
|
||||
/*Comment before a section */
|
||||
if(text == ext->txt || text == NULL) { /*Bracket of statements start inline*/
|
||||
lv_label_refr_text(label);
|
||||
return;
|
||||
}
|
||||
|
||||
...
|
||||
}
|
||||
```
|
||||
|
||||
Use 4 spaces indentation instead of tab.
|
||||
|
||||
You can use **astyle** to format the code. The required config flies are: `docs/astyle_c` and `docs/astyle_h`.
|
||||
To format the source files:
|
||||
`$ find . -type f -name "*.c" | xargs astyle --options=docs/astyle_c`
|
||||
|
||||
To format the header files:
|
||||
`$ find . -type f -name "*.h" | xargs astyle --options=docs/astyle_h`
|
||||
|
||||
Append `-n` to the end to skip creation of backup file OR use `$ find . -type f -name "*.bak" -delete` (for source file's backups) and `find . -type f -name "*.orig" -delete` (for header file's backups)
|
@ -1,111 +0,0 @@
|
||||
# Contributing to Littlev Graphics Library
|
||||
|
||||
**Do you have some free time to spend with programming?
|
||||
Are you working on an Embedded GUI project with LittlevGL?
|
||||
See how can you help to improve the graphics library!**
|
||||
|
||||
There are many ways to join the community. If you have some time to work with us I'm sure you will find something that fits you! You can:
|
||||
- help others in the [Forum](https://forum.littlevgl.com/)
|
||||
- improve and/or translate the documentation
|
||||
- write a blog post about your experiences
|
||||
- report and/or fix bugs
|
||||
- suggest and/or implement new features
|
||||
|
||||
But first, start with the most Frequently Asked Questions.
|
||||
|
||||
# FAQ about contributing
|
||||
|
||||
## Where can I write my question and remarks?
|
||||
|
||||
We use the [Forum](https://forum.littlevgl.com/) to ask and answer questions and [GitHub's issue tracker](https://github.com/littlevgl/lvgl/issues) for development-related discussion.
|
||||
|
||||
But there are some simple rules:
|
||||
- Be kind and friendly.
|
||||
- Speak about one thing in one issue/topic.
|
||||
- Give feedback and close the issue or mark the topic as solved if your question is answered.
|
||||
- Tell what you experience or expect. _"The button is not working"_ is not enough info to get help.
|
||||
- If possible send an absolute minimal code example in order to reproduce the issue
|
||||
- Use [Markdown](https://github.com/adam-p/markdown-here/wiki/Markdown-Cheatsheet) to format your post.
|
||||
|
||||
## How can I send fixes and improvements?
|
||||
|
||||
Merging new code happens via Pull Requests. If you are still not familiar with the Pull Requests (PR for short) here is a quick guide:
|
||||
1. **Fork** the [lvgl repository](https://github.com/littlevgl/lvgl). To do this click the "Fork" button in the top right corner. It will "copy" the `lvgl` repository to your GitHub account (`https://github.com/your_name?tab=repositories`)
|
||||
2. **Clone** the forked repository and add your changes
|
||||
3. **Create a PR** on GitHub from the page of your `lvgl` repository (`https://github.com/your_name/lvgl`) by hitting the "New pull request" button
|
||||
4. **Set the base branch**. It means where you want to merge your update. Fixes go to `master`, new features to the actual `dev-x.y` branch.
|
||||
5. **Describe** what is in the update. An example code is welcome if applicable.
|
||||
|
||||
Some advice:
|
||||
- If you are not sure about your fix or feature it's better to open an issue first and discuss the details there.
|
||||
- Maybe your fix or update won't be perfect at first. Don't be afraid, just improve it and push the new commits. The PR will be updated accordingly.
|
||||
- If your update needs some extra work it's okay to say: _"I'm busy now and I will improve it soon"_ or _"Sorry, I don't have time to improve it, I hope it helps in this form too"_.
|
||||
So it's better to say don't have time to continue than saying nothing.
|
||||
- Please read and follow this [guide about the coding style](https://github.com/littlevgl/lvgl/blob/master/docs/CODING_STYLE.md)
|
||||
|
||||
|
||||
## Where is the documentation?
|
||||
|
||||
You can read the documentation here: <https://docs.littlevgl.com/>
|
||||
You can edit the documentation here: <https://github.com/littlevgl/doc>
|
||||
|
||||
## Where is the blog?
|
||||
|
||||
You can read the blog here: <https://blog.littlevgl.com/>
|
||||
You can edit the blog here: <https://github.com/littlevgl/blog>
|
||||
|
||||
# So how and where can you contribute?
|
||||
|
||||
## Help others in the Forum
|
||||
|
||||
It's a great way to contribute to the library if you already use it.
|
||||
Just go to [https://forum.littlevgl.com/](https://forum.littlevgl.com/) a register (Google and GitHub login also works).
|
||||
Log in, read the titles and if you are already familiar with a topic, don't be shy, and write your suggestion.
|
||||
|
||||
## Improving and/or translating the documentation
|
||||
|
||||
If you would like to contribute to LittlevGL the documentation is the best place to start.
|
||||
|
||||
### Fix typos, add missing parts
|
||||
|
||||
If you find a typo, an obscure sentence or something which is not explained well enough in the [English documentation](https://docs.littlevgl.com/en/html/index.html)
|
||||
click the *"Edit on GitHub"* button in the top right corner and fix the issue by sending a Pull Request.
|
||||
|
||||
### Translate the documentation
|
||||
|
||||
If you have time and interest you can translate the documentation to your native language or any language you speak.
|
||||
You can join others to work on an already existing language or you can start a new one.
|
||||
|
||||
To translate the documentation we use [Zanata](https://zanata.org) which is an online translation platform.
|
||||
You will find the LittlevGL project here: [LittlevGL on Zanata](https://translate.zanata.org/iteration/view/littlevgl-docs/v6.0-doc1?dswid=3430)
|
||||
|
||||
To get started you need to:
|
||||
- register at [Zanata](https://zanata.org) which is an online translation platform.
|
||||
- comment to [this post](https://forum.littlevgl.com/t/translate-the-documentation/238?u=kisvegabor)
|
||||
- tell your username at *Zanata* and your selected language(s) to get permission the edit the translations
|
||||
|
||||
Note that a translation will be added to the documentation only if at least the [Porting section](https://docs.littlevgl.com/en/html/porting/index.html) is translated.
|
||||
|
||||
|
||||
## Writing a blog post about your experiences
|
||||
|
||||
Have you ported LittlevGL to a new platform? Have you created a fancy GUI? Do you know a great trick?
|
||||
You can share your knowledge on LittlevGL's blog! It's super easy to add your own post:
|
||||
- Fork and clone the [blog repository](https://github.com/littlevgl/blog)
|
||||
- Add your post in Markdown to the `_posts` folder.
|
||||
- Store the images and other resources in a dedicated folder in `assets`
|
||||
- Create a Pull Request
|
||||
|
||||
The blog uses [Jekyll](https://jekyllrb.com/) to convert the `.md` files to a webpage. You can easily [run Jekyll offline](https://jekyllrb.com/docs/) to check your post before creating the Pull request
|
||||
|
||||
## Reporting and/or fixing bugs
|
||||
For simple bugfixes (typos, missing error handling, fixing a warning) is fine to send a Pull request directly. However, for more complex bugs it's better to open an issue first. In the issue, you should describe how to reproduce the bug and even add the minimal code snippet.
|
||||
|
||||
## Suggesting and/or implementing new features
|
||||
If you have a good idea don't hesitate to share with us. It's even better if you have time to deal with its implementation. Don't be afraid if you still don't know LittlevGL well enough. We will help you to get started.
|
||||
|
||||
During the implementation don't forget the [Code style guide](https://github.com/littlevgl/lvgl/blob/master/docs/CODING_STYLE.md).
|
||||
|
||||
# Summary
|
||||
|
||||
I hope you have taken a liking to contribute to LittlevGL. A helpful and friendly community is waiting for you! :)
|
@ -1,14 +0,0 @@
|
||||
{
|
||||
"name": "lvgl",
|
||||
"version": "v6.1.2",
|
||||
"keywords": "graphics, gui, embedded, littlevgl",
|
||||
"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":
|
||||
{
|
||||
"type": "git",
|
||||
"url": "https://github.com/littlevgl/lvgl.git"
|
||||
},
|
||||
"build": {
|
||||
"includeDir": "."
|
||||
}
|
||||
}
|
@ -1,591 +0,0 @@
|
||||
/**
|
||||
* @file lv_conf.h
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* COPY THIS FILE AS `lv_conf.h` NEXT TO the `lvgl` FOLDER
|
||||
*/
|
||||
|
||||
#if 0 /*Set it to "1" to enable content*/
|
||||
|
||||
#ifndef LV_CONF_H
|
||||
#define LV_CONF_H
|
||||
/* clang-format off */
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
/*====================
|
||||
Graphical settings
|
||||
*====================*/
|
||||
|
||||
/* Maximal horizontal and vertical resolution to support by the library.*/
|
||||
#define LV_HOR_RES_MAX (480)
|
||||
#define LV_VER_RES_MAX (320)
|
||||
|
||||
/* Color depth:
|
||||
* - 1: 1 byte per pixel
|
||||
* - 8: RGB233
|
||||
* - 16: RGB565
|
||||
* - 32: ARGB8888
|
||||
*/
|
||||
#define LV_COLOR_DEPTH 16
|
||||
|
||||
/* Swap the 2 bytes of RGB565 color.
|
||||
* Useful if the display has a 8 bit interface (e.g. SPI)*/
|
||||
#define LV_COLOR_16_SWAP 0
|
||||
|
||||
/* 1: Enable screen transparency.
|
||||
* Useful for OSD or other overlapping GUIs.
|
||||
* Requires `LV_COLOR_DEPTH = 32` colors and the screen's style should be modified: `style.body.opa = ...`*/
|
||||
#define LV_COLOR_SCREEN_TRANSP 0
|
||||
|
||||
/*Images pixels with this color will not be drawn (with chroma keying)*/
|
||||
#define LV_COLOR_TRANSP LV_COLOR_LIME /*LV_COLOR_LIME: pure green*/
|
||||
|
||||
/* Enable chroma keying for indexed images. */
|
||||
#define LV_INDEXED_CHROMA 1
|
||||
|
||||
/* Enable anti-aliasing (lines, and radiuses will be smoothed) */
|
||||
#define LV_ANTIALIAS 1
|
||||
|
||||
/* Default display refresh period.
|
||||
* Can be changed in the display driver (`lv_disp_drv_t`).*/
|
||||
#define LV_DISP_DEF_REFR_PERIOD 30 /*[ms]*/
|
||||
|
||||
/* Dot Per Inch: used to initialize default sizes.
|
||||
* E.g. a button with width = LV_DPI / 2 -> half inch wide
|
||||
* (Not so important, you can adjust it to modify default sizes and spaces)*/
|
||||
#define LV_DPI 100 /*[px]*/
|
||||
|
||||
/* Type of coordinates. Should be `int16_t` (or `int32_t` for extreme cases) */
|
||||
typedef int16_t lv_coord_t;
|
||||
|
||||
/*=========================
|
||||
Memory manager settings
|
||||
*=========================*/
|
||||
|
||||
/* LittelvGL's internal memory manager's settings.
|
||||
* The graphical objects and other related data are stored here. */
|
||||
|
||||
/* 1: use custom malloc/free, 0: use the built-in `lv_mem_alloc` and `lv_mem_free` */
|
||||
#define LV_MEM_CUSTOM 0
|
||||
#if LV_MEM_CUSTOM == 0
|
||||
/* Size of the memory used by `lv_mem_alloc` in bytes (>= 2kB)*/
|
||||
# define LV_MEM_SIZE (32U * 1024U)
|
||||
|
||||
/* Complier prefix for a big array declaration */
|
||||
# define LV_MEM_ATTR
|
||||
|
||||
/* Set an address for the memory pool instead of allocating it as an array.
|
||||
* Can be in external SRAM too. */
|
||||
# define LV_MEM_ADR 0
|
||||
|
||||
/* Automatically defrag. on free. Defrag. means joining the adjacent free cells. */
|
||||
# define LV_MEM_AUTO_DEFRAG 1
|
||||
#else /*LV_MEM_CUSTOM*/
|
||||
# define LV_MEM_CUSTOM_INCLUDE <stdlib.h> /*Header for the dynamic memory function*/
|
||||
# define LV_MEM_CUSTOM_ALLOC malloc /*Wrapper to malloc*/
|
||||
# define LV_MEM_CUSTOM_FREE free /*Wrapper to free*/
|
||||
#endif /*LV_MEM_CUSTOM*/
|
||||
|
||||
/* Garbage Collector settings
|
||||
* Used if lvgl is binded to higher level language and the memory is managed by that language */
|
||||
#define LV_ENABLE_GC 0
|
||||
#if LV_ENABLE_GC != 0
|
||||
# define LV_GC_INCLUDE "gc.h" /*Include Garbage Collector related things*/
|
||||
# define LV_MEM_CUSTOM_REALLOC your_realloc /*Wrapper to realloc*/
|
||||
# define LV_MEM_CUSTOM_GET_SIZE your_mem_get_size /*Wrapper to lv_mem_get_size*/
|
||||
#endif /* LV_ENABLE_GC */
|
||||
|
||||
/*=======================
|
||||
Input device settings
|
||||
*=======================*/
|
||||
|
||||
/* Input device default settings.
|
||||
* Can be changed in the Input device driver (`lv_indev_drv_t`)*/
|
||||
|
||||
/* Input device read period in milliseconds */
|
||||
#define LV_INDEV_DEF_READ_PERIOD 30
|
||||
|
||||
/* Drag threshold in pixels */
|
||||
#define LV_INDEV_DEF_DRAG_LIMIT 10
|
||||
|
||||
/* Drag throw slow-down in [%]. Greater value -> faster slow-down */
|
||||
#define LV_INDEV_DEF_DRAG_THROW 20
|
||||
|
||||
/* Long press time in milliseconds.
|
||||
* Time to send `LV_EVENT_LONG_PRESSSED`) */
|
||||
#define LV_INDEV_DEF_LONG_PRESS_TIME 400
|
||||
|
||||
/* Repeated trigger period in long press [ms]
|
||||
* Time between `LV_EVENT_LONG_PRESSED_REPEAT */
|
||||
#define LV_INDEV_DEF_LONG_PRESS_REP_TIME 100
|
||||
|
||||
/*==================
|
||||
* Feature usage
|
||||
*==================*/
|
||||
|
||||
/*1: Enable the Animations */
|
||||
#define LV_USE_ANIMATION 1
|
||||
#if LV_USE_ANIMATION
|
||||
|
||||
/*Declare the type of the user data of animations (can be e.g. `void *`, `int`, `struct`)*/
|
||||
typedef void * lv_anim_user_data_t;
|
||||
|
||||
#endif
|
||||
|
||||
/* 1: Enable shadow drawing*/
|
||||
#define LV_USE_SHADOW 1
|
||||
|
||||
/* 1: Enable object groups (for keyboard/encoder navigation) */
|
||||
#define LV_USE_GROUP 1
|
||||
#if LV_USE_GROUP
|
||||
typedef void * lv_group_user_data_t;
|
||||
#endif /*LV_USE_GROUP*/
|
||||
|
||||
/* 1: Enable GPU interface*/
|
||||
#define LV_USE_GPU 1
|
||||
|
||||
/* 1: Enable file system (might be required for images */
|
||||
#define LV_USE_FILESYSTEM 1
|
||||
#if LV_USE_FILESYSTEM
|
||||
/*Declare the type of the user data of file system drivers (can be e.g. `void *`, `int`, `struct`)*/
|
||||
typedef void * lv_fs_drv_user_data_t;
|
||||
#endif
|
||||
|
||||
/*1: Add a `user_data` to drivers and objects*/
|
||||
#define LV_USE_USER_DATA 0
|
||||
|
||||
/*========================
|
||||
* Image decoder and cache
|
||||
*========================*/
|
||||
|
||||
/* 1: Enable indexed (palette) images */
|
||||
#define LV_IMG_CF_INDEXED 1
|
||||
|
||||
/* 1: Enable alpha indexed images */
|
||||
#define LV_IMG_CF_ALPHA 1
|
||||
|
||||
/* Default image cache size. Image caching keeps the images opened.
|
||||
* If only the built-in image formats are used there is no real advantage of caching.
|
||||
* (I.e. no new image decoder is added)
|
||||
* With complex image decoders (e.g. PNG or JPG) caching can save the continuous open/decode of images.
|
||||
* However the opened images might consume additional RAM.
|
||||
* LV_IMG_CACHE_DEF_SIZE must be >= 1 */
|
||||
#define LV_IMG_CACHE_DEF_SIZE 1
|
||||
|
||||
/*Declare the type of the user data of image decoder (can be e.g. `void *`, `int`, `struct`)*/
|
||||
typedef void * lv_img_decoder_user_data_t;
|
||||
|
||||
/*=====================
|
||||
* Compiler settings
|
||||
*====================*/
|
||||
/* Define a custom attribute to `lv_tick_inc` function */
|
||||
#define LV_ATTRIBUTE_TICK_INC
|
||||
|
||||
/* Define a custom attribute to `lv_task_handler` function */
|
||||
#define LV_ATTRIBUTE_TASK_HANDLER
|
||||
|
||||
/* With size optimization (-Os) the compiler might not align data to
|
||||
* 4 or 8 byte boundary. This alignment will be explicitly applied where needed.
|
||||
* E.g. __attribute__((aligned(4))) */
|
||||
#define LV_ATTRIBUTE_MEM_ALIGN
|
||||
|
||||
/* Attribute to mark large constant arrays for example
|
||||
* font's bitmaps */
|
||||
#define LV_ATTRIBUTE_LARGE_CONST
|
||||
|
||||
/* Export integer constant to binding.
|
||||
* This macro is used with constants in the form of LV_<CONST> that
|
||||
* should also appear on lvgl binding API such as Micropython
|
||||
*
|
||||
* The default value just prevents a GCC warning.
|
||||
*/
|
||||
#define LV_EXPORT_CONST_INT(int_value) struct _silence_gcc_warning
|
||||
|
||||
/*===================
|
||||
* HAL settings
|
||||
*==================*/
|
||||
|
||||
/* 1: use a custom tick source.
|
||||
* It removes the need to manually update the tick with `lv_tick_inc`) */
|
||||
#define LV_TICK_CUSTOM 0
|
||||
#if LV_TICK_CUSTOM == 1
|
||||
#define LV_TICK_CUSTOM_INCLUDE "something.h" /*Header for the sys time function*/
|
||||
#define LV_TICK_CUSTOM_SYS_TIME_EXPR (millis()) /*Expression evaluating to current systime in ms*/
|
||||
#endif /*LV_TICK_CUSTOM*/
|
||||
|
||||
typedef void * lv_disp_drv_user_data_t; /*Type of user data in the display driver*/
|
||||
typedef void * lv_indev_drv_user_data_t; /*Type of user data in the input device driver*/
|
||||
|
||||
/*================
|
||||
* Log settings
|
||||
*===============*/
|
||||
|
||||
/*1: Enable the log module*/
|
||||
#define LV_USE_LOG 0
|
||||
#if LV_USE_LOG
|
||||
/* How important log should be added:
|
||||
* LV_LOG_LEVEL_TRACE A lot of logs to give detailed information
|
||||
* LV_LOG_LEVEL_INFO Log important events
|
||||
* LV_LOG_LEVEL_WARN Log if something unwanted happened but didn't cause a problem
|
||||
* LV_LOG_LEVEL_ERROR Only critical issue, when the system may fail
|
||||
* LV_LOG_LEVEL_NONE Do not log anything
|
||||
*/
|
||||
# define LV_LOG_LEVEL LV_LOG_LEVEL_WARN
|
||||
|
||||
/* 1: Print the log with 'printf';
|
||||
* 0: user need to register a callback with `lv_log_register_print_cb`*/
|
||||
# define LV_LOG_PRINTF 0
|
||||
#endif /*LV_USE_LOG*/
|
||||
|
||||
/*=================
|
||||
* Debug settings
|
||||
*================*/
|
||||
|
||||
/* If Debug is enabled LittelvGL validates the parameters of the functions.
|
||||
* If an invalid parameter is found an error log message is printed and
|
||||
* the MCU halts at the error. (`LV_USE_LOG` should be enabled)
|
||||
* If you are debugging the MCU you can pause
|
||||
* the debugger to see exactly where the issue is.
|
||||
*
|
||||
* The behavior of asserts can be overwritten by redefining them here.
|
||||
* E.g. #define LV_ASSERT_MEM(p) <my_assert_code>
|
||||
*/
|
||||
#define LV_USE_DEBUG 1
|
||||
#if LV_USE_DEBUG
|
||||
|
||||
/*Check if the parameter is NULL. (Quite fast) */
|
||||
#define LV_USE_ASSERT_NULL 1
|
||||
|
||||
/*Checks is the memory is successfully allocated or no. (Quite fast)*/
|
||||
#define LV_USE_ASSERT_MEM 1
|
||||
|
||||
/* Check the strings.
|
||||
* Search for NULL, very long strings, invalid characters, and unnatural repetitions. (Slow)
|
||||
* If disabled `LV_USE_ASSERT_NULL` will be performed instead (if it's enabled) */
|
||||
#define LV_USE_ASSERT_STR 0
|
||||
|
||||
/* Check NULL, the object's type and existence (e.g. not deleted). (Quite slow)
|
||||
* If disabled `LV_USE_ASSERT_NULL` will be performed instead (if it's enabled) */
|
||||
#define LV_USE_ASSERT_OBJ 0
|
||||
|
||||
/*Check if the styles are properly initialized. (Fast)*/
|
||||
#define LV_USE_ASSERT_STYLE 1
|
||||
|
||||
#endif /*LV_USE_DEBUG*/
|
||||
|
||||
/*================
|
||||
* THEME USAGE
|
||||
*================*/
|
||||
#define LV_THEME_LIVE_UPDATE 0 /*1: Allow theme switching at run time. Uses 8..10 kB of RAM*/
|
||||
|
||||
#define LV_USE_THEME_TEMPL 0 /*Just for test*/
|
||||
#define LV_USE_THEME_DEFAULT 0 /*Built mainly from the built-in styles. Consumes very few RAM*/
|
||||
#define LV_USE_THEME_ALIEN 0 /*Dark futuristic theme*/
|
||||
#define LV_USE_THEME_NIGHT 0 /*Dark elegant theme*/
|
||||
#define LV_USE_THEME_MONO 0 /*Mono color theme for monochrome displays*/
|
||||
#define LV_USE_THEME_MATERIAL 0 /*Flat theme with bold colors and light shadows*/
|
||||
#define LV_USE_THEME_ZEN 0 /*Peaceful, mainly light theme */
|
||||
#define LV_USE_THEME_NEMO 0 /*Water-like theme based on the movie "Finding Nemo"*/
|
||||
|
||||
/*==================
|
||||
* FONT USAGE
|
||||
*===================*/
|
||||
|
||||
/* The built-in fonts contains the ASCII range and some Symbols with 4 bit-per-pixel.
|
||||
* The symbols are available via `LV_SYMBOL_...` defines
|
||||
* More info about fonts: https://docs.littlevgl.com/#Fonts
|
||||
* To create a new font go to: https://littlevgl.com/ttf-font-to-c-array
|
||||
*/
|
||||
|
||||
/* Robot fonts with bpp = 4
|
||||
* https://fonts.google.com/specimen/Roboto */
|
||||
#define LV_FONT_ROBOTO_12 0
|
||||
#define LV_FONT_ROBOTO_16 1
|
||||
#define LV_FONT_ROBOTO_22 0
|
||||
#define LV_FONT_ROBOTO_28 0
|
||||
|
||||
/* Demonstrate special features */
|
||||
#define LV_FONT_ROBOTO_12_SUBPX 1
|
||||
#define LV_FONT_ROBOTO_28_COMPRESSED 1 /*bpp = 3*/
|
||||
|
||||
/*Pixel perfect monospace font
|
||||
* http://pelulamu.net/unscii/ */
|
||||
#define LV_FONT_UNSCII_8 0
|
||||
|
||||
/* Optionally declare your custom fonts here.
|
||||
* You can use these fonts as default font too
|
||||
* and they will be available globally. E.g.
|
||||
* #define LV_FONT_CUSTOM_DECLARE LV_FONT_DECLARE(my_font_1) \
|
||||
* LV_FONT_DECLARE(my_font_2)
|
||||
*/
|
||||
#define LV_FONT_CUSTOM_DECLARE
|
||||
|
||||
/*Always set a default font from the built-in fonts*/
|
||||
#define LV_FONT_DEFAULT &lv_font_roboto_16
|
||||
|
||||
/* Enable it if you have fonts with a lot of characters.
|
||||
* The limit depends on the font size, font face and bpp
|
||||
* but with > 10,000 characters if you see issues probably you need to enable it.*/
|
||||
#define LV_FONT_FMT_TXT_LARGE 0
|
||||
|
||||
/* Set the pixel order of the display.
|
||||
* Important only if "subpx fonts" are used.
|
||||
* With "normal" font it doesn't matter.
|
||||
*/
|
||||
#define LV_FONT_SUBPX_BGR 0
|
||||
|
||||
/*Declare the type of the user data of fonts (can be e.g. `void *`, `int`, `struct`)*/
|
||||
typedef void * lv_font_user_data_t;
|
||||
|
||||
/*=================
|
||||
* Text settings
|
||||
*=================*/
|
||||
|
||||
/* Select a character encoding for strings.
|
||||
* Your IDE or editor should have the same character encoding
|
||||
* - LV_TXT_ENC_UTF8
|
||||
* - LV_TXT_ENC_ASCII
|
||||
* */
|
||||
#define LV_TXT_ENC LV_TXT_ENC_UTF8
|
||||
|
||||
/*Can break (wrap) texts on these chars*/
|
||||
#define LV_TXT_BREAK_CHARS " ,.;:-_"
|
||||
|
||||
/* If a word is at least this long, will break wherever "prettiest"
|
||||
* To disable, set to a value <= 0 */
|
||||
#define LV_TXT_LINE_BREAK_LONG_LEN 12
|
||||
|
||||
/* Minimum number of characters in a long word to put on a line before a break.
|
||||
* Depends on LV_TXT_LINE_BREAK_LONG_LEN. */
|
||||
#define LV_TXT_LINE_BREAK_LONG_PRE_MIN_LEN 3
|
||||
|
||||
/* Minimum number of characters in a long word to put on a line after a break.
|
||||
* Depends on LV_TXT_LINE_BREAK_LONG_LEN. */
|
||||
#define LV_TXT_LINE_BREAK_LONG_POST_MIN_LEN 3
|
||||
|
||||
/* The control character to use for signalling text recoloring. */
|
||||
#define LV_TXT_COLOR_CMD "#"
|
||||
|
||||
/* Support bidirectional texts.
|
||||
* Allows mixing Left-to-Right and Right-to-Left texts.
|
||||
* The direction will be processed according to the Unicode Bidirectioanl Algorithm:
|
||||
* https://www.w3.org/International/articles/inline-bidi-markup/uba-basics*/
|
||||
#define LV_USE_BIDI 0
|
||||
#if LV_USE_BIDI
|
||||
/* Set the default direction. Supported values:
|
||||
* `LV_BIDI_DIR_LTR` Left-to-Right
|
||||
* `LV_BIDI_DIR_RTL` Right-to-Left
|
||||
* `LV_BIDI_DIR_AUTO` detect texts base direction */
|
||||
#define LV_BIDI_BASE_DIR_DEF LV_BIDI_DIR_AUTO
|
||||
#endif
|
||||
|
||||
/*Change the built in (v)snprintf functions*/
|
||||
#define LV_SPRINTF_CUSTOM 0
|
||||
#if LV_SPRINTF_CUSTOM
|
||||
# define LV_SPRINTF_INCLUDE <stdio.h>
|
||||
# define lv_snprintf snprintf
|
||||
# define lv_vsnprintf vsnprintf
|
||||
#endif /*LV_SPRINTF_CUSTOM*/
|
||||
|
||||
/*===================
|
||||
* LV_OBJ SETTINGS
|
||||
*==================*/
|
||||
|
||||
/*Declare the type of the user data of object (can be e.g. `void *`, `int`, `struct`)*/
|
||||
typedef void * lv_obj_user_data_t;
|
||||
|
||||
/*1: enable `lv_obj_realaign()` based on `lv_obj_align()` parameters*/
|
||||
#define LV_USE_OBJ_REALIGN 1
|
||||
|
||||
/* Enable to make the object clickable on a larger area.
|
||||
* LV_EXT_CLICK_AREA_OFF or 0: Disable this feature
|
||||
* LV_EXT_CLICK_AREA_TINY: The extra area can be adjusted horizontally and vertically (0..255 px)
|
||||
* LV_EXT_CLICK_AREA_FULL: The extra area can be adjusted in all 4 directions (-32k..+32k px)
|
||||
*/
|
||||
#define LV_USE_EXT_CLICK_AREA LV_EXT_CLICK_AREA_OFF
|
||||
|
||||
/*==================
|
||||
* LV OBJ X USAGE
|
||||
*================*/
|
||||
/*
|
||||
* Documentation of the object types: https://docs.littlevgl.com/#Object-types
|
||||
*/
|
||||
|
||||
/*Arc (dependencies: -)*/
|
||||
#define LV_USE_ARC 1
|
||||
|
||||
/*Bar (dependencies: -)*/
|
||||
#define LV_USE_BAR 1
|
||||
|
||||
/*Button (dependencies: lv_cont*/
|
||||
#define LV_USE_BTN 1
|
||||
#if LV_USE_BTN != 0
|
||||
/*Enable button-state animations - draw a circle on click (dependencies: LV_USE_ANIMATION)*/
|
||||
# define LV_BTN_INK_EFFECT 0
|
||||
#endif
|
||||
|
||||
/*Button matrix (dependencies: -)*/
|
||||
#define LV_USE_BTNM 1
|
||||
|
||||
/*Calendar (dependencies: -)*/
|
||||
#define LV_USE_CALENDAR 1
|
||||
|
||||
/*Canvas (dependencies: lv_img)*/
|
||||
#define LV_USE_CANVAS 1
|
||||
|
||||
/*Check box (dependencies: lv_btn, lv_label)*/
|
||||
#define LV_USE_CB 1
|
||||
|
||||
/*Chart (dependencies: -)*/
|
||||
#define LV_USE_CHART 1
|
||||
#if LV_USE_CHART
|
||||
# define LV_CHART_AXIS_TICK_LABEL_MAX_LEN 20
|
||||
#endif
|
||||
|
||||
/*Container (dependencies: -*/
|
||||
#define LV_USE_CONT 1
|
||||
|
||||
/*Color picker (dependencies: -*/
|
||||
#define LV_USE_CPICKER 1
|
||||
|
||||
/*Drop down list (dependencies: lv_page, lv_label, lv_symbol_def.h)*/
|
||||
#define LV_USE_DDLIST 1
|
||||
#if LV_USE_DDLIST != 0
|
||||
/*Open and close default animation time [ms] (0: no animation)*/
|
||||
# define LV_DDLIST_DEF_ANIM_TIME 200
|
||||
#endif
|
||||
|
||||
/*Gauge (dependencies:lv_bar, lv_lmeter)*/
|
||||
#define LV_USE_GAUGE 1
|
||||
|
||||
/*Image (dependencies: lv_label*/
|
||||
#define LV_USE_IMG 1
|
||||
|
||||
/*Image Button (dependencies: lv_btn*/
|
||||
#define LV_USE_IMGBTN 1
|
||||
#if LV_USE_IMGBTN
|
||||
/*1: The imgbtn requires left, mid and right parts and the width can be set freely*/
|
||||
# define LV_IMGBTN_TILED 0
|
||||
#endif
|
||||
|
||||
/*Keyboard (dependencies: lv_btnm)*/
|
||||
#define LV_USE_KB 1
|
||||
|
||||
/*Label (dependencies: -*/
|
||||
#define LV_USE_LABEL 1
|
||||
#if LV_USE_LABEL != 0
|
||||
/*Hor, or ver. scroll speed [px/sec] in 'LV_LABEL_LONG_ROLL/ROLL_CIRC' mode*/
|
||||
# define LV_LABEL_DEF_SCROLL_SPEED 25
|
||||
|
||||
/* Waiting period at beginning/end of animation cycle */
|
||||
# define LV_LABEL_WAIT_CHAR_COUNT 3
|
||||
|
||||
/*Enable selecting text of the label */
|
||||
# define LV_LABEL_TEXT_SEL 0
|
||||
|
||||
/*Store extra some info in labels (12 bytes) to speed up drawing of very long texts*/
|
||||
# define LV_LABEL_LONG_TXT_HINT 0
|
||||
#endif
|
||||
|
||||
/*LED (dependencies: -)*/
|
||||
#define LV_USE_LED 1
|
||||
|
||||
/*Line (dependencies: -*/
|
||||
#define LV_USE_LINE 1
|
||||
|
||||
/*List (dependencies: lv_page, lv_btn, lv_label, (lv_img optionally for icons ))*/
|
||||
#define LV_USE_LIST 1
|
||||
#if LV_USE_LIST != 0
|
||||
/*Default animation time of focusing to a list element [ms] (0: no animation) */
|
||||
# define LV_LIST_DEF_ANIM_TIME 100
|
||||
#endif
|
||||
|
||||
/*Line meter (dependencies: *;)*/
|
||||
#define LV_USE_LMETER 1
|
||||
|
||||
/*Message box (dependencies: lv_rect, lv_btnm, lv_label)*/
|
||||
#define LV_USE_MBOX 1
|
||||
|
||||
/*Page (dependencies: lv_cont)*/
|
||||
#define LV_USE_PAGE 1
|
||||
#if LV_USE_PAGE != 0
|
||||
/*Focus default animation time [ms] (0: no animation)*/
|
||||
# define LV_PAGE_DEF_ANIM_TIME 400
|
||||
#endif
|
||||
|
||||
/*Preload (dependencies: lv_arc, lv_anim)*/
|
||||
#define LV_USE_PRELOAD 1
|
||||
#if LV_USE_PRELOAD != 0
|
||||
# define LV_PRELOAD_DEF_ARC_LENGTH 60 /*[deg]*/
|
||||
# define LV_PRELOAD_DEF_SPIN_TIME 1000 /*[ms]*/
|
||||
# define LV_PRELOAD_DEF_ANIM LV_PRELOAD_TYPE_SPINNING_ARC
|
||||
#endif
|
||||
|
||||
/*Roller (dependencies: lv_ddlist)*/
|
||||
#define LV_USE_ROLLER 1
|
||||
#if LV_USE_ROLLER != 0
|
||||
/*Focus animation time [ms] (0: no animation)*/
|
||||
# define LV_ROLLER_DEF_ANIM_TIME 200
|
||||
|
||||
/*Number of extra "pages" when the roller is infinite*/
|
||||
# define LV_ROLLER_INF_PAGES 7
|
||||
#endif
|
||||
|
||||
/*Slider (dependencies: lv_bar)*/
|
||||
#define LV_USE_SLIDER 1
|
||||
|
||||
/*Spinbox (dependencies: lv_ta)*/
|
||||
#define LV_USE_SPINBOX 1
|
||||
|
||||
/*Switch (dependencies: lv_slider)*/
|
||||
#define LV_USE_SW 1
|
||||
|
||||
/*Text area (dependencies: lv_label, lv_page)*/
|
||||
#define LV_USE_TA 1
|
||||
#if LV_USE_TA != 0
|
||||
# define LV_TA_DEF_CURSOR_BLINK_TIME 400 /*ms*/
|
||||
# define LV_TA_DEF_PWD_SHOW_TIME 1500 /*ms*/
|
||||
#endif
|
||||
|
||||
/*Table (dependencies: lv_label)*/
|
||||
#define LV_USE_TABLE 1
|
||||
#if LV_USE_TABLE
|
||||
# define LV_TABLE_COL_MAX 12
|
||||
#endif
|
||||
|
||||
/*Tab (dependencies: lv_page, lv_btnm)*/
|
||||
#define LV_USE_TABVIEW 1
|
||||
# if LV_USE_TABVIEW != 0
|
||||
/*Time of slide animation [ms] (0: no animation)*/
|
||||
# define LV_TABVIEW_DEF_ANIM_TIME 300
|
||||
#endif
|
||||
|
||||
/*Tileview (dependencies: lv_page) */
|
||||
#define LV_USE_TILEVIEW 1
|
||||
#if LV_USE_TILEVIEW
|
||||
/*Time of slide animation [ms] (0: no animation)*/
|
||||
# define LV_TILEVIEW_DEF_ANIM_TIME 300
|
||||
#endif
|
||||
|
||||
/*Window (dependencies: lv_cont, lv_btn, lv_label, lv_img, lv_page)*/
|
||||
#define LV_USE_WIN 1
|
||||
|
||||
/*==================
|
||||
* Non-user section
|
||||
*==================*/
|
||||
|
||||
#if defined(_MSC_VER) && !defined(_CRT_SECURE_NO_WARNINGS) /* Disable warnings for Visual Studio*/
|
||||
# define _CRT_SECURE_NO_WARNINGS
|
||||
#endif
|
||||
|
||||
/*--END OF LV_CONF_H--*/
|
||||
|
||||
/*Be sure every define has a default value*/
|
||||
#include "lvgl/src/lv_conf_checker.h"
|
||||
|
||||
#endif /*LV_CONF_H*/
|
||||
|
||||
#endif /*End of "Content enable"*/
|
@ -1,97 +0,0 @@
|
||||
/**
|
||||
* @file lvgl.h
|
||||
* Include all LittleV GL related headers
|
||||
*/
|
||||
|
||||
#ifndef LVGL_H
|
||||
#define LVGL_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
|
||||
#include "src/lv_version.h"
|
||||
|
||||
#include "src/lv_misc/lv_log.h"
|
||||
#include "src/lv_misc/lv_task.h"
|
||||
#include "src/lv_misc/lv_math.h"
|
||||
#include "src/lv_misc/lv_async.h"
|
||||
|
||||
#include "src/lv_hal/lv_hal.h"
|
||||
|
||||
#include "src/lv_core/lv_obj.h"
|
||||
#include "src/lv_core/lv_group.h"
|
||||
#include "src/lv_core/lv_indev.h"
|
||||
|
||||
#include "src/lv_core/lv_refr.h"
|
||||
#include "src/lv_core/lv_disp.h"
|
||||
#include "src/lv_core/lv_debug.h"
|
||||
|
||||
#include "src/lv_themes/lv_theme.h"
|
||||
|
||||
#include "src/lv_font/lv_font.h"
|
||||
#include "src/lv_font/lv_font_fmt_txt.h"
|
||||
#include "src/lv_misc/lv_bidi.h"
|
||||
#include "src/lv_misc/lv_printf.h"
|
||||
|
||||
#include "src/lv_objx/lv_btn.h"
|
||||
#include "src/lv_objx/lv_imgbtn.h"
|
||||
#include "src/lv_objx/lv_img.h"
|
||||
#include "src/lv_objx/lv_label.h"
|
||||
#include "src/lv_objx/lv_line.h"
|
||||
#include "src/lv_objx/lv_page.h"
|
||||
#include "src/lv_objx/lv_cont.h"
|
||||
#include "src/lv_objx/lv_list.h"
|
||||
#include "src/lv_objx/lv_chart.h"
|
||||
#include "src/lv_objx/lv_table.h"
|
||||
#include "src/lv_objx/lv_cb.h"
|
||||
#include "src/lv_objx/lv_cpicker.h"
|
||||
#include "src/lv_objx/lv_bar.h"
|
||||
#include "src/lv_objx/lv_slider.h"
|
||||
#include "src/lv_objx/lv_led.h"
|
||||
#include "src/lv_objx/lv_btnm.h"
|
||||
#include "src/lv_objx/lv_kb.h"
|
||||
#include "src/lv_objx/lv_ddlist.h"
|
||||
#include "src/lv_objx/lv_roller.h"
|
||||
#include "src/lv_objx/lv_ta.h"
|
||||
#include "src/lv_objx/lv_canvas.h"
|
||||
#include "src/lv_objx/lv_win.h"
|
||||
#include "src/lv_objx/lv_tabview.h"
|
||||
#include "src/lv_objx/lv_tileview.h"
|
||||
#include "src/lv_objx/lv_mbox.h"
|
||||
#include "src/lv_objx/lv_gauge.h"
|
||||
#include "src/lv_objx/lv_lmeter.h"
|
||||
#include "src/lv_objx/lv_sw.h"
|
||||
#include "src/lv_objx/lv_kb.h"
|
||||
#include "src/lv_objx/lv_arc.h"
|
||||
#include "src/lv_objx/lv_preload.h"
|
||||
#include "src/lv_objx/lv_calendar.h"
|
||||
#include "src/lv_objx/lv_spinbox.h"
|
||||
|
||||
#include "src/lv_draw/lv_img_cache.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /*LVGL_H*/
|
@ -1,8 +0,0 @@
|
||||
include $(LVGL_DIR)/lvgl/src/lv_core/lv_core.mk
|
||||
include $(LVGL_DIR)/lvgl/src/lv_hal/lv_hal.mk
|
||||
include $(LVGL_DIR)/lvgl/src/lv_objx/lv_objx.mk
|
||||
include $(LVGL_DIR)/lvgl/src/lv_font/lv_font.mk
|
||||
include $(LVGL_DIR)/lvgl/src/lv_misc/lv_misc.mk
|
||||
include $(LVGL_DIR)/lvgl/src/lv_themes/lv_themes.mk
|
||||
include $(LVGL_DIR)/lvgl/src/lv_draw/lv_draw.mk
|
||||
|
@ -1,122 +0,0 @@
|
||||
From 1f57703589c6d202d9f6259f1d0fefe7bfd39061 Mon Sep 17 00:00:00 2001
|
||||
From: Koen Zandberg <koen@bergzand.net>
|
||||
Date: Thu, 27 Feb 2020 16:33:06 +0100
|
||||
Subject: [PATCH] lv_refr: add support for selecting render direction
|
||||
|
||||
---
|
||||
src/lv_core/lv_refr.c | 71 ++++++++++++++++++++++++++++------------
|
||||
src/lv_hal/lv_hal_disp.h | 6 ++++
|
||||
2 files changed, 56 insertions(+), 21 deletions(-)
|
||||
|
||||
diff --git a/src/lv_core/lv_refr.c b/src/lv_core/lv_refr.c
|
||||
index 5ee3fbb2..e71e1629 100644
|
||||
--- a/src/lv_core/lv_refr.c
|
||||
+++ b/src/lv_core/lv_refr.c
|
||||
@@ -339,30 +339,59 @@ static void lv_refr_area(const lv_area_t * area_p)
|
||||
}
|
||||
}
|
||||
|
||||
- /*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 VDB*/
|
||||
- vdb->area.x1 = area_p->x1;
|
||||
- vdb->area.x2 = area_p->x2;
|
||||
- vdb->area.y1 = row;
|
||||
- vdb->area.y2 = row + max_row - 1;
|
||||
- if(vdb->area.y2 > y2) vdb->area.y2 = y2;
|
||||
- row_last = vdb->area.y2;
|
||||
- lv_refr_area_part(area_p);
|
||||
+ if (disp_refr->render_direction) {
|
||||
+ /*Always use the full row*/
|
||||
+ lv_coord_t row;
|
||||
+ lv_coord_t row_last = y2;
|
||||
+ for(row = area_p->y2; row > max_row - 1 + area_p->y1; row -= max_row) {
|
||||
+ /*Calc. the next y coordinates of VDB*/
|
||||
+ vdb->area.x1 = area_p->x1;
|
||||
+ vdb->area.x2 = area_p->x2;
|
||||
+ vdb->area.y1 = row - max_row + 1;
|
||||
+ vdb->area.y2 = row;
|
||||
+ if(vdb->area.y2 > y2) vdb->area.y2 = y2;
|
||||
+ row_last = vdb->area.y1;
|
||||
+ lv_refr_area_part(area_p);
|
||||
+ }
|
||||
+
|
||||
+ /*If the last (first) y coordinates are not handled yet ...*/
|
||||
+ if(area_p->y1 != row_last) {
|
||||
+ /*Calc. the next y coordinates of VDB*/
|
||||
+ vdb->area.x1 = area_p->x1;
|
||||
+ vdb->area.x2 = area_p->x2;
|
||||
+ vdb->area.y1 = area_p->y1;
|
||||
+ vdb->area.y2 = row;
|
||||
+
|
||||
+ /*Refresh this part too*/
|
||||
+ lv_refr_area_part(area_p);
|
||||
+ }
|
||||
}
|
||||
+ else {
|
||||
+ /*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 VDB*/
|
||||
+ vdb->area.x1 = area_p->x1;
|
||||
+ vdb->area.x2 = area_p->x2;
|
||||
+ vdb->area.y1 = row;
|
||||
+ vdb->area.y2 = row + max_row - 1;
|
||||
+ if(vdb->area.y2 > y2) vdb->area.y2 = y2;
|
||||
+ row_last = vdb->area.y2;
|
||||
+ 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 VDB*/
|
||||
- vdb->area.x1 = area_p->x1;
|
||||
- vdb->area.x2 = area_p->x2;
|
||||
- vdb->area.y1 = row;
|
||||
- vdb->area.y2 = y2;
|
||||
+ /*If the last y coordinates are not handled yet ...*/
|
||||
+ if(y2 != row_last) {
|
||||
+ /*Calc. the next y coordinates of VDB*/
|
||||
+ vdb->area.x1 = area_p->x1;
|
||||
+ vdb->area.x2 = area_p->x2;
|
||||
+ vdb->area.y1 = row;
|
||||
+ vdb->area.y2 = y2;
|
||||
|
||||
- /*Refresh this part too*/
|
||||
- lv_refr_area_part(area_p);
|
||||
+ /*Refresh this part too*/
|
||||
+ lv_refr_area_part(area_p);
|
||||
+ }
|
||||
}
|
||||
}
|
||||
}
|
||||
diff --git a/src/lv_hal/lv_hal_disp.h b/src/lv_hal/lv_hal_disp.h
|
||||
index 8db692a0..eef22d98 100644
|
||||
--- a/src/lv_hal/lv_hal_disp.h
|
||||
+++ b/src/lv_hal/lv_hal_disp.h
|
||||
@@ -143,6 +143,7 @@ typedef struct _disp_t
|
||||
uint8_t inv_area_joined[LV_INV_BUF_SIZE];
|
||||
uint32_t inv_p : 10;
|
||||
|
||||
+ int render_direction; /**< 0 when rendering down, 1 when rendering up */
|
||||
/*Miscellaneous data*/
|
||||
uint32_t last_activity_time; /**< Last time there was activity on this display */
|
||||
} lv_disp_t;
|
||||
@@ -230,6 +231,11 @@ lv_coord_t lv_disp_get_ver_res(lv_disp_t * disp);
|
||||
*/
|
||||
bool lv_disp_get_antialiasing(lv_disp_t * disp);
|
||||
|
||||
+static inline void lv_disp_set_direction(lv_disp_t * disp, int direction)
|
||||
+{
|
||||
+ disp->render_direction = direction;
|
||||
+}
|
||||
+
|
||||
//! @cond Doxygen_Suppress
|
||||
|
||||
/**
|
||||
--
|
||||
2.24.1
|
||||
|
@ -1,51 +0,0 @@
|
||||
Index: src/libs/lvgl/src/lv_misc/lv_anim.c
|
||||
IDEA additional info:
|
||||
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
|
||||
<+>UTF-8
|
||||
===================================================================
|
||||
diff --git a/src/libs/lvgl/src/lv_misc/lv_anim.c b/src/libs/lvgl/src/lv_misc/lv_anim.c
|
||||
--- a/src/libs/lvgl/src/lv_misc/lv_anim.c (revision 12a3b6cc8ec1fd6b951c353ab3a5fbbb9934fdd4)
|
||||
+++ b/src/libs/lvgl/src/lv_misc/lv_anim.c (date 1610901672072)
|
||||
@@ -158,12 +158,12 @@
|
||||
* @param end end value of the animation
|
||||
* @return the required time [ms] for the animation with the given parameters
|
||||
*/
|
||||
-uint16_t lv_anim_speed_to_time(uint16_t speed, lv_anim_value_t start, lv_anim_value_t end)
|
||||
+uint32_t lv_anim_speed_to_time(uint16_t speed, lv_anim_value_t start, lv_anim_value_t end)
|
||||
{
|
||||
int32_t d = LV_MATH_ABS((int32_t)start - end);
|
||||
uint32_t time = (int32_t)((int32_t)(d * 1000) / speed);
|
||||
|
||||
- if(time > UINT16_MAX) time = UINT16_MAX;
|
||||
+ if(time > UINT32_MAX) time = UINT32_MAX;
|
||||
|
||||
if(time == 0) {
|
||||
time++;
|
||||
Index: src/libs/lvgl/src/lv_misc/lv_anim.h
|
||||
IDEA additional info:
|
||||
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
|
||||
<+>UTF-8
|
||||
===================================================================
|
||||
diff --git a/src/libs/lvgl/src/lv_misc/lv_anim.h b/src/libs/lvgl/src/lv_misc/lv_anim.h
|
||||
--- a/src/libs/lvgl/src/lv_misc/lv_anim.h (revision 12a3b6cc8ec1fd6b951c353ab3a5fbbb9934fdd4)
|
||||
+++ b/src/libs/lvgl/src/lv_misc/lv_anim.h (date 1610901672076)
|
||||
@@ -73,8 +73,8 @@
|
||||
lv_anim_ready_cb_t ready_cb; /**< Call it when the animation is ready*/
|
||||
int32_t start; /**< Start value*/
|
||||
int32_t end; /**< End value*/
|
||||
- uint16_t time; /**< Animation time in ms*/
|
||||
- int16_t act_time; /**< Current time in animation. Set to negative to make delay.*/
|
||||
+ uint32_t time; /**< Animation time in ms*/
|
||||
+ int32_t act_time; /**< Current time in animation. Set to negative to make delay.*/
|
||||
uint16_t playback_pause; /**< Wait before play back*/
|
||||
uint16_t repeat_pause; /**< Wait before repeat*/
|
||||
#if LV_USE_USER_DATA
|
||||
@@ -266,7 +266,7 @@
|
||||
* @param end end value of the animation
|
||||
* @return the required time [ms] for the animation with the given parameters
|
||||
*/
|
||||
-uint16_t lv_anim_speed_to_time(uint16_t speed, lv_anim_value_t start, lv_anim_value_t end);
|
||||
+uint32_t lv_anim_speed_to_time(uint16_t speed, lv_anim_value_t start, lv_anim_value_t end);
|
||||
|
||||
/**
|
||||
* Calculate the current value of an animation applying linear characteristic
|
@ -1,196 +0,0 @@
|
||||
/**
|
||||
* @file lv_port_disp_templ.c
|
||||
*
|
||||
*/
|
||||
|
||||
/*Copy this file as "lv_port_disp.c" and set this value to "1" to enable content*/
|
||||
#if 0
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "lv_port_disp_template.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
static void disp_init(void);
|
||||
|
||||
static void disp_flush(lv_disp_drv_t * disp_drv, const lv_area_t * area, lv_color_t * color_p);
|
||||
#if LV_USE_GPU
|
||||
static void gpu_blend(lv_disp_drv_t * disp_drv, lv_color_t * dest, const lv_color_t * src, uint32_t length, lv_opa_t opa);
|
||||
static void gpu_fill(lv_disp_drv_t * disp_drv, lv_color_t * dest_buf, lv_coord_t dest_width,
|
||||
const lv_area_t * fill_area, lv_color_t color);
|
||||
#endif
|
||||
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL FUNCTIONS
|
||||
**********************/
|
||||
|
||||
void lv_port_disp_init(void)
|
||||
{
|
||||
/*-------------------------
|
||||
* Initialize your display
|
||||
* -----------------------*/
|
||||
disp_init();
|
||||
|
||||
/*-----------------------------
|
||||
* Create a buffer for drawing
|
||||
*----------------------------*/
|
||||
|
||||
/* LittlevGL requires a buffer where it draws the objects. The buffer's has to be greater than 1 display row
|
||||
*
|
||||
* There are three buffering configurations:
|
||||
* 1. Create ONE buffer with some rows:
|
||||
* LittlevGL will draw the display's content here and writes it to your display
|
||||
*
|
||||
* 2. Create TWO buffer with some rows:
|
||||
* LittlevGL will draw the display's content to a buffer and writes it your display.
|
||||
* You should use DMA to write the buffer's content to the display.
|
||||
* It will enable LittlevGL to draw the next part of the screen to the other buffer while
|
||||
* the data is being sent form the first buffer. It makes rendering and flushing parallel.
|
||||
*
|
||||
* 3. Create TWO screen-sized buffer:
|
||||
* Similar to 2) but the buffer have to be screen sized. When LittlevGL is ready it will give the
|
||||
* whole frame to display. This way you only need to change the frame buffer's address instead of
|
||||
* copying the pixels.
|
||||
* */
|
||||
|
||||
/* Example for 1) */
|
||||
static lv_disp_buf_t disp_buf_1;
|
||||
static lv_color_t buf1_1[LV_HOR_RES_MAX * 10]; /*A buffer for 10 rows*/
|
||||
lv_disp_buf_init(&disp_buf_1, buf1_1, NULL, LV_HOR_RES_MAX * 10); /*Initialize the display buffer*/
|
||||
|
||||
/* Example for 2) */
|
||||
static lv_disp_buf_t disp_buf_2;
|
||||
static lv_color_t buf2_1[LV_HOR_RES_MAX * 10]; /*A buffer for 10 rows*/
|
||||
static lv_color_t buf2_2[LV_HOR_RES_MAX * 10]; /*An other buffer for 10 rows*/
|
||||
lv_disp_buf_init(&disp_buf_2, buf2_1, buf2_2, LV_HOR_RES_MAX * 10); /*Initialize the display buffer*/
|
||||
|
||||
/* Example for 3) */
|
||||
static lv_disp_buf_t disp_buf_3;
|
||||
static lv_color_t buf3_1[LV_HOR_RES_MAX * LV_VER_RES_MAX]; /*A screen sized buffer*/
|
||||
static lv_color_t buf3_2[LV_HOR_RES_MAX * LV_VER_RES_MAX]; /*An other screen sized buffer*/
|
||||
lv_disp_buf_init(&disp_buf_3, buf3_1, buf3_2, LV_HOR_RES_MAX * LV_VER_RES_MAX); /*Initialize the display buffer*/
|
||||
|
||||
|
||||
/*-----------------------------------
|
||||
* Register the display in LittlevGL
|
||||
*----------------------------------*/
|
||||
|
||||
lv_disp_drv_t disp_drv; /*Descriptor of a display driver*/
|
||||
lv_disp_drv_init(&disp_drv); /*Basic initialization*/
|
||||
|
||||
/*Set up the functions to access to your display*/
|
||||
|
||||
/*Set the resolution of the display*/
|
||||
disp_drv.hor_res = 480;
|
||||
disp_drv.ver_res = 320;
|
||||
|
||||
/*Used to copy the buffer's content to the display*/
|
||||
disp_drv.flush_cb = disp_flush;
|
||||
|
||||
/*Set a display buffer*/
|
||||
disp_drv.buffer = &disp_buf_2;
|
||||
|
||||
#if LV_USE_GPU
|
||||
/*Optionally add functions to access the GPU. (Only in buffered mode, LV_VDB_SIZE != 0)*/
|
||||
|
||||
/*Blend two color array using opacity*/
|
||||
disp_drv.gpu_blend_cb = gpu_blend;
|
||||
|
||||
/*Fill a memory array with a color*/
|
||||
disp_drv.gpu_fill_cb = gpu_fill;
|
||||
#endif
|
||||
|
||||
/*Finally register the driver*/
|
||||
lv_disp_drv_register(&disp_drv);
|
||||
}
|
||||
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
|
||||
/* Initialize your display and the required peripherals. */
|
||||
static void disp_init(void)
|
||||
{
|
||||
/*You code here*/
|
||||
}
|
||||
|
||||
/* Flush the content of the internal buffer the specific area on the display
|
||||
* You can use DMA or any hardware acceleration to do this operation in the background but
|
||||
* 'lv_disp_flush_ready()' has to be called when finished. */
|
||||
static void disp_flush(lv_disp_drv_t * disp_drv, const lv_area_t * area, lv_color_t * color_p)
|
||||
{
|
||||
/*The most simple case (but also the slowest) to put all pixels to the screen one-by-one*/
|
||||
|
||||
int32_t x;
|
||||
int32_t y;
|
||||
for(y = area->y1; y <= area->y2; y++) {
|
||||
for(x = area->x1; x <= area->x2; x++) {
|
||||
/* Put a pixel to the display. For example: */
|
||||
/* put_px(x, y, *color_p)*/
|
||||
color_p++;
|
||||
}
|
||||
}
|
||||
|
||||
/* IMPORTANT!!!
|
||||
* Inform the graphics library that you are ready with the flushing*/
|
||||
lv_disp_flush_ready(disp_drv);
|
||||
}
|
||||
|
||||
|
||||
/*OPTIONAL: GPU INTERFACE*/
|
||||
#if LV_USE_GPU
|
||||
|
||||
/* If your MCU has hardware accelerator (GPU) then you can use it to blend to memories using opacity
|
||||
* It can be used only in buffered mode (LV_VDB_SIZE != 0 in lv_conf.h)*/
|
||||
static void gpu_blend(lv_disp_drv_t * disp_drv, lv_color_t * dest, const lv_color_t * src, uint32_t length, lv_opa_t opa)
|
||||
{
|
||||
/*It's an example code which should be done by your GPU*/
|
||||
uint32_t i;
|
||||
for(i = 0; i < length; i++) {
|
||||
dest[i] = lv_color_mix(dest[i], src[i], opa);
|
||||
}
|
||||
}
|
||||
|
||||
/* If your MCU has hardware accelerator (GPU) then you can use it to fill a memory with a color
|
||||
* It can be used only in buffered mode (LV_VDB_SIZE != 0 in lv_conf.h)*/
|
||||
static void gpu_fill(lv_disp_drv_t * disp_drv, lv_color_t * dest_buf, lv_coord_t dest_width,
|
||||
const lv_area_t * fill_area, lv_color_t color)
|
||||
{
|
||||
/*It's an example code which should be done by your GPU*/
|
||||
int32_t x, y;
|
||||
dest_buf += dest_width * fill_area->y1; /*Go to the first line*/
|
||||
|
||||
for(y = fill_area->y1; y < fill_area->y2; y++) {
|
||||
for(x = fill_area->x1; x < fill_area->x2; x++) {
|
||||
dest_buf[x] = color;
|
||||
}
|
||||
dest_buf+=dest_width; /*Go to the next line*/
|
||||
}
|
||||
}
|
||||
|
||||
#endif /*LV_USE_GPU*/
|
||||
|
||||
#else /* Enable this file at the top */
|
||||
|
||||
/* This dummy typedef exists purely to silence -Wpedantic. */
|
||||
typedef int keep_pedantic_happy;
|
||||
#endif
|
@ -1,44 +0,0 @@
|
||||
/**
|
||||
* @file lv_port_disp_templ.h
|
||||
*
|
||||
*/
|
||||
|
||||
/*Copy this file as "lv_port_disp.h" and set this value to "1" to enable content*/
|
||||
#if 0
|
||||
|
||||
#ifndef LV_PORT_DISP_TEMPL_H
|
||||
#define LV_PORT_DISP_TEMPL_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "lvgl/lvgl.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif /*LV_PORT_DISP_TEMPL_H*/
|
||||
|
||||
#endif /*Disable/Enable content*/
|
@ -1,379 +0,0 @@
|
||||
/**
|
||||
* @file lv_port_fs_templ.c
|
||||
*
|
||||
*/
|
||||
|
||||
/*Copy this file as "lv_port_fs.c" and set this value to "1" to enable content*/
|
||||
#if 0
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "lv_port_fs_template.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* 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
|
||||
**********************/
|
||||
static void fs_init(void);
|
||||
|
||||
static lv_fs_res_t fs_open (lv_fs_drv_t * drv, void * file_p, const char * path, lv_fs_mode_t mode);
|
||||
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_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);
|
||||
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL FUNCTIONS
|
||||
**********************/
|
||||
|
||||
void lv_port_fs_init(void)
|
||||
{
|
||||
/*----------------------------------------------------
|
||||
* Initialize your storage device and File System
|
||||
* -------------------------------------------------*/
|
||||
fs_init();
|
||||
|
||||
/*---------------------------------------------------
|
||||
* Register the file system interface in LittlevGL
|
||||
*--------------------------------------------------*/
|
||||
|
||||
/* Add a simple drive to open images */
|
||||
lv_fs_drv_t fs_drv;
|
||||
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;
|
||||
fs_drv.read_cb = fs_read;
|
||||
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;
|
||||
|
||||
lv_fs_drv_register(&fs_drv);
|
||||
}
|
||||
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
|
||||
/* Initialize your Storage device and File system. */
|
||||
static void fs_init(void)
|
||||
{
|
||||
/*E.g. for FatFS initalize the SD card and FatFS itself*/
|
||||
|
||||
/*You code here*/
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
static lv_fs_res_t fs_open (lv_fs_drv_t * drv, void * file_p, const char * path, lv_fs_mode_t mode)
|
||||
{
|
||||
lv_fs_res_t res = LV_FS_RES_NOT_IMP;
|
||||
|
||||
if(mode == LV_FS_MODE_WR)
|
||||
{
|
||||
/*Open a file for write*/
|
||||
|
||||
/* Add your code here*/
|
||||
}
|
||||
else if(mode == LV_FS_MODE_RD)
|
||||
{
|
||||
/*Open a file for read*/
|
||||
|
||||
/* 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*/
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
static lv_fs_res_t fs_close (lv_fs_drv_t * drv, void * file_p)
|
||||
{
|
||||
lv_fs_res_t res = LV_FS_RES_NOT_IMP;
|
||||
|
||||
/* Add your code here*/
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
static lv_fs_res_t fs_read (lv_fs_drv_t * drv, void * file_p, void * buf, uint32_t btr, uint32_t * br)
|
||||
{
|
||||
lv_fs_res_t res = LV_FS_RES_NOT_IMP;
|
||||
|
||||
/* Add your code here*/
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
static lv_fs_res_t fs_write(lv_fs_drv_t * drv, void * file_p, const void * buf, uint32_t btw, uint32_t * bw)
|
||||
{
|
||||
lv_fs_res_t res = LV_FS_RES_NOT_IMP;
|
||||
|
||||
/* Add your code here*/
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
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)
|
||||
{
|
||||
lv_fs_res_t res = LV_FS_RES_NOT_IMP;
|
||||
|
||||
/* Add your code here*/
|
||||
|
||||
return res;
|
||||
}
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
static lv_fs_res_t fs_tell (lv_fs_drv_t * drv, void * file_p, uint32_t * pos_p)
|
||||
{
|
||||
lv_fs_res_t res = LV_FS_RES_NOT_IMP;
|
||||
|
||||
/* Add your code here*/
|
||||
|
||||
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 'fs_read_dir_t' variable for directory reading
|
||||
* @param drv pointer to a driver where this function belongs
|
||||
* @param rddir_p pointer to a 'fs_read_dir_t' variable
|
||||
* @param path path to a directory
|
||||
* @return LV_FS_RES_OK or any error from lv_fs_res_t enum
|
||||
*/
|
||||
static lv_fs_res_t fs_dir_open (lv_fs_drv_t * drv, void * rddir_p, const char *path)
|
||||
{
|
||||
lv_fs_res_t res = LV_FS_RES_NOT_IMP;
|
||||
|
||||
/* Add your code here*/
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 'fs_read_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
|
||||
*/
|
||||
static lv_fs_res_t fs_dir_read (lv_fs_drv_t * drv, void * rddir_p, char *fn)
|
||||
{
|
||||
lv_fs_res_t res = LV_FS_RES_NOT_IMP;
|
||||
|
||||
/* Add your code here*/
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
/**
|
||||
* Close the directory reading
|
||||
* @param drv pointer to a driver where this function belongs
|
||||
* @param rddir_p pointer to an initialized 'fs_read_dir_t' variable
|
||||
* @return LV_FS_RES_OK 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)
|
||||
{
|
||||
lv_fs_res_t res = LV_FS_RES_NOT_IMP;
|
||||
|
||||
/* Add your code here*/
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
#else /* Enable this file at the top */
|
||||
|
||||
/* This dummy typedef exists purely to silence -Wpedantic. */
|
||||
typedef int keep_pedantic_happy;
|
||||
#endif
|
@ -1,44 +0,0 @@
|
||||
/**
|
||||
* @file lv_port_fs_templ.h
|
||||
*
|
||||
*/
|
||||
|
||||
/*Copy this file as "lv_port_fs.h" and set this value to "1" to enable content*/
|
||||
#if 0
|
||||
|
||||
#ifndef LV_PORT_FS_TEMPL_H
|
||||
#define LV_PORT_FS_TEMPL_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "lvgl/lvgl.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif /*LV_PORT_FS_TEMPL_H*/
|
||||
|
||||
#endif /*Disable/Enable content*/
|
@ -1,428 +0,0 @@
|
||||
/**
|
||||
* @file lv_port_indev_templ.c
|
||||
*
|
||||
*/
|
||||
|
||||
/*Copy this file as "lv_port_indev.c" and set this value to "1" to enable content*/
|
||||
#if 0
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "lv_port_indev_template.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
|
||||
static void touchpad_init(void);
|
||||
static bool touchpad_read(lv_indev_drv_t * indev_drv, lv_indev_data_t * data);
|
||||
static bool touchpad_is_pressed(void);
|
||||
static void touchpad_get_xy(lv_coord_t * x, lv_coord_t * y);
|
||||
|
||||
static void mouse_init(void);
|
||||
static bool mouse_read(lv_indev_drv_t * indev_drv, lv_indev_data_t * data);
|
||||
static bool mouse_is_pressed(void);
|
||||
static void mouse_get_xy(lv_coord_t * x, lv_coord_t * y);
|
||||
|
||||
static void keypad_init(void);
|
||||
static bool 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_handler(void);
|
||||
|
||||
static void button_init(void);
|
||||
static bool button_read(lv_indev_drv_t * indev_drv, lv_indev_data_t * data);
|
||||
static int8_t button_get_pressed_id(void);
|
||||
static bool button_is_pressed(uint8_t id);
|
||||
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
**********************/
|
||||
lv_indev_t * indev_touchpad;
|
||||
lv_indev_t * indev_mouse;
|
||||
lv_indev_t * indev_keypad;
|
||||
lv_indev_t * indev_encoder;
|
||||
lv_indev_t * indev_button;
|
||||
|
||||
static int32_t encoder_diff;
|
||||
static lv_indev_state_t encoder_state;
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL FUNCTIONS
|
||||
**********************/
|
||||
|
||||
void lv_port_indev_init(void)
|
||||
{
|
||||
/* Here you will find example implementation of input devices supported by LittelvGL:
|
||||
* - Touchpad
|
||||
* - Mouse (with cursor support)
|
||||
* - Keypad (supports GUI usage only with key)
|
||||
* - Encoder (supports GUI usage only with: left, right, push)
|
||||
* - Button (external buttons to press points on the screen)
|
||||
*
|
||||
* The `..._read()` function are only examples.
|
||||
* You should shape them according to your hardware
|
||||
*/
|
||||
|
||||
|
||||
lv_indev_drv_t indev_drv;
|
||||
|
||||
/*------------------
|
||||
* Touchpad
|
||||
* -----------------*/
|
||||
|
||||
/*Initialize your touchpad if you have*/
|
||||
touchpad_init();
|
||||
|
||||
/*Register a touchpad input device*/
|
||||
lv_indev_drv_init(&indev_drv);
|
||||
indev_drv.type = LV_INDEV_TYPE_POINTER;
|
||||
indev_drv.read_cb = touchpad_read;
|
||||
indev_touchpad = lv_indev_drv_register(&indev_drv);
|
||||
|
||||
/*------------------
|
||||
* Mouse
|
||||
* -----------------*/
|
||||
|
||||
/*Initialize your touchpad if you have*/
|
||||
mouse_init();
|
||||
|
||||
/*Register a mouse input device*/
|
||||
lv_indev_drv_init(&indev_drv);
|
||||
indev_drv.type = LV_INDEV_TYPE_POINTER;
|
||||
indev_drv.read_cb = mouse_read;
|
||||
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_img_set_src(mouse_cursor, LV_SYMBOL_HOME);
|
||||
lv_indev_set_cursor(indev_mouse, mouse_cursor);
|
||||
|
||||
/*------------------
|
||||
* Keypad
|
||||
* -----------------*/
|
||||
|
||||
/*Initialize your keypad or keyboard if you have*/
|
||||
keypad_init();
|
||||
|
||||
/*Register a keypad input device*/
|
||||
lv_indev_drv_init(&indev_drv);
|
||||
indev_drv.type = LV_INDEV_TYPE_KEYPAD;
|
||||
indev_drv.read_cb = keypad_read;
|
||||
indev_keypad = lv_indev_drv_register(&indev_drv);
|
||||
|
||||
/* Later you should create group(s) with `lv_group_t * group = lv_group_create()`,
|
||||
* add objects to the group with `lv_group_add_obj(group, obj)`
|
||||
* and assign this input device to group to navigate in it:
|
||||
* `lv_indev_set_group(indev_keypad, group);` */
|
||||
|
||||
/*------------------
|
||||
* Encoder
|
||||
* -----------------*/
|
||||
|
||||
/*Initialize your encoder if you have*/
|
||||
encoder_init();
|
||||
|
||||
/*Register a encoder input device*/
|
||||
lv_indev_drv_init(&indev_drv);
|
||||
indev_drv.type = LV_INDEV_TYPE_KEYPAD;
|
||||
indev_drv.read_cb = encoder_read;
|
||||
indev_encoder = lv_indev_drv_register(&indev_drv);
|
||||
|
||||
/* Later you should create group(s) with `lv_group_t * group = lv_group_create()`,
|
||||
* add objects to the group with `lv_group_add_obj(group, obj)`
|
||||
* and assign this input device to group to navigate in it:
|
||||
* `lv_indev_set_group(indev_keypad, group);` */
|
||||
|
||||
/*------------------
|
||||
* Button
|
||||
* -----------------*/
|
||||
|
||||
/*Initialize your button if you have*/
|
||||
button_init();
|
||||
|
||||
/*Register a button input device*/
|
||||
lv_indev_drv_init(&indev_drv);
|
||||
indev_drv.type = LV_INDEV_TYPE_BUTTON;
|
||||
indev_drv.read_cb = button_read;
|
||||
indev_button = lv_indev_drv_register(&indev_drv);
|
||||
|
||||
/*Assign buttons to points on the screen*/
|
||||
static const lv_point_t btn_points[2] = {
|
||||
{10, 10}, /*Button 0 -> x:10; y:10*/
|
||||
{40, 100}, /*Button 1 -> x:40; y:100*/
|
||||
};
|
||||
lv_indev_set_button_points(indev_button, btn_points);
|
||||
}
|
||||
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
|
||||
|
||||
|
||||
/*------------------
|
||||
* Touchpad
|
||||
* -----------------*/
|
||||
|
||||
/*Initialize your touchpad*/
|
||||
static void touchpad_init(void)
|
||||
{
|
||||
/*Your code comes here*/
|
||||
}
|
||||
|
||||
/* Will be called by the library to read the touchpad */
|
||||
static bool touchpad_read(lv_indev_drv_t * indev_drv, lv_indev_data_t * data)
|
||||
{
|
||||
static lv_coord_t last_x = 0;
|
||||
static lv_coord_t last_y = 0;
|
||||
|
||||
/*Save the pressed coordinates and the state*/
|
||||
if(touchpad_is_pressed()) {
|
||||
touchpad_get_xy(&last_x, &last_y);
|
||||
data->state = LV_INDEV_STATE_PR;
|
||||
} else {
|
||||
data->state = LV_INDEV_STATE_REL;
|
||||
}
|
||||
|
||||
/*Set the last pressed coordinates*/
|
||||
data->point.x = last_x;
|
||||
data->point.y = last_y;
|
||||
|
||||
/*Return `false` because we are not buffering and no more data to read*/
|
||||
return false;
|
||||
}
|
||||
|
||||
/*Return true is the touchpad is pressed*/
|
||||
static bool touchpad_is_pressed(void)
|
||||
{
|
||||
/*Your code comes here*/
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/*Get the x and y coordinates if the touchpad is pressed*/
|
||||
static void touchpad_get_xy(lv_coord_t * x, lv_coord_t * y)
|
||||
{
|
||||
/*Your code comes here*/
|
||||
|
||||
(*x) = 0;
|
||||
(*y) = 0;
|
||||
}
|
||||
|
||||
|
||||
/*------------------
|
||||
* Mouse
|
||||
* -----------------*/
|
||||
|
||||
/* Initialize your mouse */
|
||||
static void mouse_init(void)
|
||||
{
|
||||
/*Your code comes here*/
|
||||
}
|
||||
|
||||
/* Will be called by the library to read the mouse */
|
||||
static bool mouse_read(lv_indev_drv_t * indev_drv, lv_indev_data_t * data)
|
||||
{
|
||||
/*Get the current x and y coordinates*/
|
||||
mouse_get_xy(&data->point.x, &data->point.y);
|
||||
|
||||
/*Get whether the mouse button is pressed or released*/
|
||||
if(mouse_is_pressed()) {
|
||||
data->state = LV_INDEV_STATE_PR;
|
||||
} else {
|
||||
data->state = LV_INDEV_STATE_REL;
|
||||
}
|
||||
|
||||
/*Return `false` because we are not buffering and no more data to read*/
|
||||
return false;
|
||||
}
|
||||
|
||||
/*Return true is the mouse button is pressed*/
|
||||
static bool mouse_is_pressed(void)
|
||||
{
|
||||
/*Your code comes here*/
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/*Get the x and y coordinates if the mouse is pressed*/
|
||||
static void mouse_get_xy(lv_coord_t * x, lv_coord_t * y)
|
||||
{
|
||||
/*Your code comes here*/
|
||||
|
||||
(*x) = 0;
|
||||
(*y) = 0;
|
||||
}
|
||||
|
||||
/*------------------
|
||||
* Keypad
|
||||
* -----------------*/
|
||||
|
||||
/* Initialize your keypad */
|
||||
static void keypad_init(void)
|
||||
{
|
||||
/*Your code comes here*/
|
||||
}
|
||||
|
||||
/* Will be called by the library to read the mouse */
|
||||
static bool keypad_read(lv_indev_drv_t * indev_drv, lv_indev_data_t * data)
|
||||
{
|
||||
static uint32_t last_key = 0;
|
||||
|
||||
/*Get the current x and y coordinates*/
|
||||
mouse_get_xy(&data->point.x, &data->point.y);
|
||||
|
||||
/*Get whether the a key is pressed and save the pressed key*/
|
||||
uint32_t act_key = keypad_get_key();
|
||||
if(act_key != 0) {
|
||||
data->state = LV_INDEV_STATE_PR;
|
||||
|
||||
/*Translate the keys to LittlevGL control characters according to your key definitions*/
|
||||
switch(act_key) {
|
||||
case 1:
|
||||
act_key = LV_KEY_NEXT;
|
||||
break;
|
||||
case 2:
|
||||
act_key = LV_KEY_PREV;
|
||||
break;
|
||||
case 3:
|
||||
act_key = LV_KEY_LEFT;
|
||||
break;
|
||||
case 4:
|
||||
act_key = LV_KEY_RIGHT;
|
||||
break;
|
||||
case 5:
|
||||
act_key = LV_KEY_ENTER;
|
||||
break;
|
||||
}
|
||||
|
||||
last_key = act_key;
|
||||
} else {
|
||||
data->state = LV_INDEV_STATE_REL;
|
||||
}
|
||||
|
||||
data->key = last_key;
|
||||
|
||||
/*Return `false` because we are not buffering and no more data to read*/
|
||||
return false;
|
||||
}
|
||||
|
||||
/*Get the currently being pressed key. 0 if no key is pressed*/
|
||||
static uint32_t keypad_get_key(void)
|
||||
{
|
||||
/*Your code comes here*/
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*------------------
|
||||
* Encoder
|
||||
* -----------------*/
|
||||
|
||||
/* Initialize your keypad */
|
||||
static void encoder_init(void)
|
||||
{
|
||||
/*Your code comes here*/
|
||||
}
|
||||
|
||||
/* Will be called by the library to read the encoder */
|
||||
static bool encoder_read(lv_indev_drv_t * indev_drv, lv_indev_data_t * data)
|
||||
{
|
||||
|
||||
data->enc_diff = encoder_diff;
|
||||
data->state = encoder_state;
|
||||
|
||||
/*Return `false` because we are not buffering and no more data to read*/
|
||||
return false;
|
||||
}
|
||||
|
||||
/*Call this function in an interrupt to process encoder events (turn, press)*/
|
||||
static void encoder_handler(void)
|
||||
{
|
||||
/*Your code comes here*/
|
||||
|
||||
encoder_diff += 0;
|
||||
encoder_state = LV_INDEV_STATE_REL;
|
||||
}
|
||||
|
||||
|
||||
/*------------------
|
||||
* Button
|
||||
* -----------------*/
|
||||
|
||||
/* Initialize your buttons */
|
||||
static void button_init(void)
|
||||
{
|
||||
/*Your code comes here*/
|
||||
}
|
||||
|
||||
/* Will be called by the library to read the button */
|
||||
static bool button_read(lv_indev_drv_t * indev_drv, lv_indev_data_t * data)
|
||||
{
|
||||
|
||||
static uint8_t last_btn = 0;
|
||||
|
||||
/*Get the pressed button's ID*/
|
||||
int8_t btn_act = button_get_pressed_id();
|
||||
|
||||
if(btn_act >= 0) {
|
||||
data->state = LV_INDEV_STATE_PR;
|
||||
last_btn = btn_act;
|
||||
} else {
|
||||
data->state = LV_INDEV_STATE_REL;
|
||||
}
|
||||
|
||||
/*Save the last pressed button's ID*/
|
||||
data->btn_id = last_btn;
|
||||
|
||||
/*Return `false` because we are not buffering and no more data to read*/
|
||||
return false;
|
||||
}
|
||||
|
||||
/*Get ID (0, 1, 2 ..) of the pressed button*/
|
||||
static int8_t button_get_pressed_id(void)
|
||||
{
|
||||
uint8_t i;
|
||||
|
||||
/*Check to buttons see which is being pressed (assume there are 2 buttons)*/
|
||||
for(i = 0; i < 2; i++) {
|
||||
/*Return the pressed button's ID*/
|
||||
if(button_is_pressed(i)) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
/*No button pressed*/
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*Test if `id` button is pressed or not*/
|
||||
static bool button_is_pressed(uint8_t id)
|
||||
{
|
||||
|
||||
/*Your code comes here*/
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
#else /* Enable this file at the top */
|
||||
|
||||
/* This dummy typedef exists purely to silence -Wpedantic. */
|
||||
typedef int keep_pedantic_happy;
|
||||
#endif
|
@ -1,45 +0,0 @@
|
||||
|
||||
/**
|
||||
* @file lv_port_indev_templ.h
|
||||
*
|
||||
*/
|
||||
|
||||
/*Copy this file as "lv_port_indev.h" and set this value to "1" to enable content*/
|
||||
#if 0
|
||||
|
||||
#ifndef LV_PORT_INDEV_TEMPL_H
|
||||
#define LV_PORT_INDEV_TEMPL_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "lvgl/lvgl.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif /*LV_PORT_INDEV_TEMPL_H*/
|
||||
|
||||
#endif /*Disable/Enable content*/
|
File diff suppressed because it is too large
Load Diff
Binary file not shown.
Binary file not shown.
@ -1,47 +0,0 @@
|
||||
import argparse
|
||||
from argparse import RawTextHelpFormatter
|
||||
import os
|
||||
import sys
|
||||
|
||||
parser = argparse.ArgumentParser(description="""Create fonts for LittelvGL including the built-in symbols. lv_font_conv needs to be installed. See https://github.com/littlevgl/lv_font_conv
|
||||
Example: python built_in_font_gen.py --size 16 -o lv_font_roboto_16.c --bpp 4 -r 0x20-0x7F""", formatter_class=RawTextHelpFormatter)
|
||||
parser.add_argument('-s', '--size',
|
||||
type=int,
|
||||
metavar = 'px',
|
||||
nargs='?',
|
||||
help='Size of the font in px')
|
||||
parser.add_argument('--bpp',
|
||||
type=int,
|
||||
metavar = '1,2,4',
|
||||
nargs='?',
|
||||
help='Bit per pixel')
|
||||
parser.add_argument('-r', '--range',
|
||||
nargs='+',
|
||||
metavar = 'start-end',
|
||||
default='0x20-0x7F',
|
||||
help='Ranges and/or characters to include. Default is 0x20-7F (ASCII). E.g. -r 0x20-0x7F, 0x200, 324')
|
||||
parser.add_argument('--font',
|
||||
metavar = 'file',
|
||||
nargs='?',
|
||||
default='Roboto-Regular.woff',
|
||||
help='A TTF or WOFF file')
|
||||
parser.add_argument('-o', '--output',
|
||||
nargs='?',
|
||||
metavar='file',
|
||||
help='Output file name. E.g. my_font_20.c')
|
||||
parser.add_argument('--compressed', action='store_true',
|
||||
help='Compress the bitmaps')
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
if args.compressed == False:
|
||||
compr = "--no-compress --no-prefilter"
|
||||
else:
|
||||
compr = ""
|
||||
|
||||
#Built in symbols
|
||||
syms = "61441,61448,61451,61452,61452,61453,61457,61459,61461,61465,61468,61473,61478,61479,61480,61502,61512,61515,61516,61517,61521,61522,61523,61524,61543,61544,61550,61552,61553,61556,61559,61560,61561,61563,61587,61589,61636,61637,61639,61671,61674,61683,61724,61732,61787,61931,62016,62017,62018,62019,62020,62087,62099,62212,62189,62810,63426,63650"
|
||||
|
||||
#Run the command
|
||||
cmd = "lv_font_conv {} --bpp {} --size {} --font Roboto-Regular.woff -r {} --font FontAwesome5-Solid+Brands+Regular.woff -r {} --format lvgl -o {} --force-fast-kern-format".format(compr, args.bpp, args.size, args.range[0], syms, args.output)
|
||||
os.system(cmd)
|
@ -1,13 +0,0 @@
|
||||
clang-format-7 -style=file ../src/lv_core/*.c -i
|
||||
clang-format-7 -style=file ../src/lv_draw/*.c -i
|
||||
clang-format-7 -style=file ../src/lv_hal/*.c -i
|
||||
clang-format-7 -style=file ../src/lv_misc/*.c -i
|
||||
clang-format-7 -style=file ../src/lv_objx/*.c -i
|
||||
clang-format-7 -style=file ../src/lv_themes/*.c -i
|
||||
|
||||
clang-format-7 -style=file ../src/lv_core/*.h -i
|
||||
clang-format-7 -style=file ../src/lv_draw/*.h -i
|
||||
clang-format-7 -style=file ../src/lv_hal/*.h -i
|
||||
clang-format-7 -style=file ../src/lv_misc/*.h -i
|
||||
clang-format-7 -style=file ../src/lv_objx/*.h -i
|
||||
clang-format-7 -style=file ../src/lv_themes/*.h -i
|
@ -1,2 +0,0 @@
|
||||
cppcheck --template="{severity}\t{file}:{line}\t{id}: {message}" --enable=all ../src/ --output-file=cppcheck_res.txt --suppress=unusedFunction --suppress=preprocessorErrorDirective --force
|
||||
|
@ -1,60 +0,0 @@
|
||||
#!/usr/bin/env python3.6
|
||||
|
||||
'''
|
||||
Generates a checker file for lv_conf.h from lv_conf_templ.h define all the not defined values
|
||||
'''
|
||||
|
||||
|
||||
import re
|
||||
|
||||
fin = open("../lv_conf_template.h", "r")
|
||||
fout = open("../src/lv_conf_checker.h", "w")
|
||||
|
||||
|
||||
fout.write(
|
||||
'''/**
|
||||
* GENERATED FILE, DO NOT EDIT IT!
|
||||
* @file lv_conf_checker.h
|
||||
* Make sure all the defines of lv_conf.h have a default value
|
||||
**/
|
||||
|
||||
#ifndef LV_CONF_CHECKER_H
|
||||
#define LV_CONF_CHECKER_H
|
||||
'''
|
||||
)
|
||||
|
||||
started = 0
|
||||
|
||||
for i in fin.read().splitlines():
|
||||
if not started:
|
||||
if '#define LV_CONF_H' in i:
|
||||
started = 1
|
||||
continue
|
||||
else:
|
||||
continue
|
||||
|
||||
if '/*--END OF LV_CONF_H--*/' in i: break
|
||||
|
||||
r = re.search(r'^ *# *define ([^\s]+).*$', i)
|
||||
|
||||
if r:
|
||||
line = re.sub('\(.*?\)', '', r[1], 1) #remove parentheses from macros
|
||||
fout.write(
|
||||
f'#ifndef {line}\n'
|
||||
f'{i}\n'
|
||||
'#endif\n'
|
||||
)
|
||||
elif re.search('^ *typedef .*;.*$', i):
|
||||
continue #ignore typedefs to avoide redeclaration
|
||||
else:
|
||||
fout.write(f'{i}\n')
|
||||
|
||||
|
||||
fout.write(
|
||||
'''
|
||||
#endif /*LV_CONF_CHECKER_H*/
|
||||
'''
|
||||
)
|
||||
|
||||
fin.close()
|
||||
fout.close()
|
@ -1,851 +0,0 @@
|
||||
/**
|
||||
* GENERATED FILE, DO NOT EDIT IT!
|
||||
* @file lv_conf_checker.h
|
||||
* Make sure all the defines of lv_conf.h have a default value
|
||||
**/
|
||||
|
||||
#ifndef LV_CONF_CHECKER_H
|
||||
#define LV_CONF_CHECKER_H
|
||||
/* clang-format off */
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
/*====================
|
||||
Graphical settings
|
||||
*====================*/
|
||||
|
||||
/* Maximal horizontal and vertical resolution to support by the library.*/
|
||||
#ifndef LV_HOR_RES_MAX
|
||||
#define LV_HOR_RES_MAX (480)
|
||||
#endif
|
||||
#ifndef LV_VER_RES_MAX
|
||||
#define LV_VER_RES_MAX (320)
|
||||
#endif
|
||||
|
||||
/* Color depth:
|
||||
* - 1: 1 byte per pixel
|
||||
* - 8: RGB233
|
||||
* - 16: RGB565
|
||||
* - 32: ARGB8888
|
||||
*/
|
||||
#ifndef LV_COLOR_DEPTH
|
||||
#define LV_COLOR_DEPTH 16
|
||||
#endif
|
||||
|
||||
/* Swap the 2 bytes of RGB565 color.
|
||||
* Useful if the display has a 8 bit interface (e.g. SPI)*/
|
||||
#ifndef LV_COLOR_16_SWAP
|
||||
#define LV_COLOR_16_SWAP 0
|
||||
#endif
|
||||
|
||||
/* 1: Enable screen transparency.
|
||||
* Useful for OSD or other overlapping GUIs.
|
||||
* Requires `LV_COLOR_DEPTH = 32` colors and the screen's style should be modified: `style.body.opa = ...`*/
|
||||
#ifndef LV_COLOR_SCREEN_TRANSP
|
||||
#define LV_COLOR_SCREEN_TRANSP 0
|
||||
#endif
|
||||
|
||||
/*Images pixels with this color will not be drawn (with chroma keying)*/
|
||||
#ifndef LV_COLOR_TRANSP
|
||||
#define LV_COLOR_TRANSP LV_COLOR_LIME /*LV_COLOR_LIME: pure green*/
|
||||
#endif
|
||||
|
||||
/* Enable chroma keying for indexed images. */
|
||||
#ifndef LV_INDEXED_CHROMA
|
||||
#define LV_INDEXED_CHROMA 1
|
||||
#endif
|
||||
|
||||
/* Enable anti-aliasing (lines, and radiuses will be smoothed) */
|
||||
#ifndef LV_ANTIALIAS
|
||||
#define LV_ANTIALIAS 1
|
||||
#endif
|
||||
|
||||
/* Default display refresh period.
|
||||
* Can be changed in the display driver (`lv_disp_drv_t`).*/
|
||||
#ifndef LV_DISP_DEF_REFR_PERIOD
|
||||
#define LV_DISP_DEF_REFR_PERIOD 30 /*[ms]*/
|
||||
#endif
|
||||
|
||||
/* Dot Per Inch: used to initialize default sizes.
|
||||
* E.g. a button with width = LV_DPI / 2 -> half inch wide
|
||||
* (Not so important, you can adjust it to modify default sizes and spaces)*/
|
||||
#ifndef LV_DPI
|
||||
#define LV_DPI 100 /*[px]*/
|
||||
#endif
|
||||
|
||||
/* Type of coordinates. Should be `int16_t` (or `int32_t` for extreme cases) */
|
||||
|
||||
/*=========================
|
||||
Memory manager settings
|
||||
*=========================*/
|
||||
|
||||
/* LittelvGL's internal memory manager's settings.
|
||||
* The graphical objects and other related data are stored here. */
|
||||
|
||||
/* 1: use custom malloc/free, 0: use the built-in `lv_mem_alloc` and `lv_mem_free` */
|
||||
#ifndef LV_MEM_CUSTOM
|
||||
#define LV_MEM_CUSTOM 0
|
||||
#endif
|
||||
#if LV_MEM_CUSTOM == 0
|
||||
/* Size of the memory used by `lv_mem_alloc` in bytes (>= 2kB)*/
|
||||
#ifndef LV_MEM_SIZE
|
||||
# define LV_MEM_SIZE (32U * 1024U)
|
||||
#endif
|
||||
|
||||
/* Complier prefix for a big array declaration */
|
||||
#ifndef LV_MEM_ATTR
|
||||
# define LV_MEM_ATTR
|
||||
#endif
|
||||
|
||||
/* Set an address for the memory pool instead of allocating it as an array.
|
||||
* Can be in external SRAM too. */
|
||||
#ifndef LV_MEM_ADR
|
||||
# define LV_MEM_ADR 0
|
||||
#endif
|
||||
|
||||
/* Automatically defrag. on free. Defrag. means joining the adjacent free cells. */
|
||||
#ifndef LV_MEM_AUTO_DEFRAG
|
||||
# define LV_MEM_AUTO_DEFRAG 1
|
||||
#endif
|
||||
#else /*LV_MEM_CUSTOM*/
|
||||
#ifndef LV_MEM_CUSTOM_INCLUDE
|
||||
# define LV_MEM_CUSTOM_INCLUDE <stdlib.h> /*Header for the dynamic memory function*/
|
||||
#endif
|
||||
#ifndef LV_MEM_CUSTOM_ALLOC
|
||||
# define LV_MEM_CUSTOM_ALLOC malloc /*Wrapper to malloc*/
|
||||
#endif
|
||||
#ifndef LV_MEM_CUSTOM_FREE
|
||||
# define LV_MEM_CUSTOM_FREE free /*Wrapper to free*/
|
||||
#endif
|
||||
#endif /*LV_MEM_CUSTOM*/
|
||||
|
||||
/* Garbage Collector settings
|
||||
* Used if lvgl is binded to higher level language and the memory is managed by that language */
|
||||
#ifndef LV_ENABLE_GC
|
||||
#define LV_ENABLE_GC 0
|
||||
#endif
|
||||
#if LV_ENABLE_GC != 0
|
||||
#ifndef LV_GC_INCLUDE
|
||||
# define LV_GC_INCLUDE "gc.h" /*Include Garbage Collector related things*/
|
||||
#endif
|
||||
#ifndef LV_MEM_CUSTOM_REALLOC
|
||||
# define LV_MEM_CUSTOM_REALLOC your_realloc /*Wrapper to realloc*/
|
||||
#endif
|
||||
#ifndef LV_MEM_CUSTOM_GET_SIZE
|
||||
# define LV_MEM_CUSTOM_GET_SIZE your_mem_get_size /*Wrapper to lv_mem_get_size*/
|
||||
#endif
|
||||
#endif /* LV_ENABLE_GC */
|
||||
|
||||
/*=======================
|
||||
Input device settings
|
||||
*=======================*/
|
||||
|
||||
/* Input device default settings.
|
||||
* Can be changed in the Input device driver (`lv_indev_drv_t`)*/
|
||||
|
||||
/* Input device read period in milliseconds */
|
||||
#ifndef LV_INDEV_DEF_READ_PERIOD
|
||||
#define LV_INDEV_DEF_READ_PERIOD 30
|
||||
#endif
|
||||
|
||||
/* Drag threshold in pixels */
|
||||
#ifndef LV_INDEV_DEF_DRAG_LIMIT
|
||||
#define LV_INDEV_DEF_DRAG_LIMIT 10
|
||||
#endif
|
||||
|
||||
/* Drag throw slow-down in [%]. Greater value -> faster slow-down */
|
||||
#ifndef LV_INDEV_DEF_DRAG_THROW
|
||||
#define LV_INDEV_DEF_DRAG_THROW 20
|
||||
#endif
|
||||
|
||||
/* Long press time in milliseconds.
|
||||
* Time to send `LV_EVENT_LONG_PRESSSED`) */
|
||||
#ifndef LV_INDEV_DEF_LONG_PRESS_TIME
|
||||
#define LV_INDEV_DEF_LONG_PRESS_TIME 400
|
||||
#endif
|
||||
|
||||
/* Repeated trigger period in long press [ms]
|
||||
* Time between `LV_EVENT_LONG_PRESSED_REPEAT */
|
||||
#ifndef LV_INDEV_DEF_LONG_PRESS_REP_TIME
|
||||
#define LV_INDEV_DEF_LONG_PRESS_REP_TIME 100
|
||||
#endif
|
||||
|
||||
/*==================
|
||||
* Feature usage
|
||||
*==================*/
|
||||
|
||||
/*1: Enable the Animations */
|
||||
#ifndef LV_USE_ANIMATION
|
||||
#define LV_USE_ANIMATION 1
|
||||
#endif
|
||||
#if LV_USE_ANIMATION
|
||||
|
||||
/*Declare the type of the user data of animations (can be e.g. `void *`, `int`, `struct`)*/
|
||||
|
||||
#endif
|
||||
|
||||
/* 1: Enable shadow drawing*/
|
||||
#ifndef LV_USE_SHADOW
|
||||
#define LV_USE_SHADOW 1
|
||||
#endif
|
||||
|
||||
/* 1: Enable object groups (for keyboard/encoder navigation) */
|
||||
#ifndef LV_USE_GROUP
|
||||
#define LV_USE_GROUP 1
|
||||
#endif
|
||||
#if LV_USE_GROUP
|
||||
#endif /*LV_USE_GROUP*/
|
||||
|
||||
/* 1: Enable GPU interface*/
|
||||
#ifndef LV_USE_GPU
|
||||
#define LV_USE_GPU 1
|
||||
#endif
|
||||
|
||||
/* 1: Enable file system (might be required for images */
|
||||
#ifndef LV_USE_FILESYSTEM
|
||||
#define LV_USE_FILESYSTEM 1
|
||||
#endif
|
||||
#if LV_USE_FILESYSTEM
|
||||
/*Declare the type of the user data of file system drivers (can be e.g. `void *`, `int`, `struct`)*/
|
||||
#endif
|
||||
|
||||
/*1: Add a `user_data` to drivers and objects*/
|
||||
#ifndef LV_USE_USER_DATA
|
||||
#define LV_USE_USER_DATA 0
|
||||
#endif
|
||||
|
||||
/*========================
|
||||
* Image decoder and cache
|
||||
*========================*/
|
||||
|
||||
/* 1: Enable indexed (palette) images */
|
||||
#ifndef LV_IMG_CF_INDEXED
|
||||
#define LV_IMG_CF_INDEXED 1
|
||||
#endif
|
||||
|
||||
/* 1: Enable alpha indexed images */
|
||||
#ifndef LV_IMG_CF_ALPHA
|
||||
#define LV_IMG_CF_ALPHA 1
|
||||
#endif
|
||||
|
||||
/* Default image cache size. Image caching keeps the images opened.
|
||||
* If only the built-in image formats are used there is no real advantage of caching.
|
||||
* (I.e. no new image decoder is added)
|
||||
* With complex image decoders (e.g. PNG or JPG) caching can save the continuous open/decode of images.
|
||||
* However the opened images might consume additional RAM.
|
||||
* LV_IMG_CACHE_DEF_SIZE must be >= 1 */
|
||||
#ifndef LV_IMG_CACHE_DEF_SIZE
|
||||
#define LV_IMG_CACHE_DEF_SIZE 1
|
||||
#endif
|
||||
|
||||
/*Declare the type of the user data of image decoder (can be e.g. `void *`, `int`, `struct`)*/
|
||||
|
||||
/*=====================
|
||||
* Compiler settings
|
||||
*====================*/
|
||||
/* Define a custom attribute to `lv_tick_inc` function */
|
||||
#ifndef LV_ATTRIBUTE_TICK_INC
|
||||
#define LV_ATTRIBUTE_TICK_INC
|
||||
#endif
|
||||
|
||||
/* Define a custom attribute to `lv_task_handler` function */
|
||||
#ifndef LV_ATTRIBUTE_TASK_HANDLER
|
||||
#define LV_ATTRIBUTE_TASK_HANDLER
|
||||
#endif
|
||||
|
||||
/* With size optimization (-Os) the compiler might not align data to
|
||||
* 4 or 8 byte boundary. This alignment will be explicitly applied where needed.
|
||||
* E.g. __attribute__((aligned(4))) */
|
||||
#ifndef LV_ATTRIBUTE_MEM_ALIGN
|
||||
#define LV_ATTRIBUTE_MEM_ALIGN
|
||||
#endif
|
||||
|
||||
/* Attribute to mark large constant arrays for example
|
||||
* font's bitmaps */
|
||||
#ifndef LV_ATTRIBUTE_LARGE_CONST
|
||||
#define LV_ATTRIBUTE_LARGE_CONST
|
||||
#endif
|
||||
|
||||
/* Export integer constant to binding.
|
||||
* This macro is used with constants in the form of LV_<CONST> that
|
||||
* should also appear on lvgl binding API such as Micropython
|
||||
*
|
||||
* The default value just prevents a GCC warning.
|
||||
*/
|
||||
#ifndef LV_EXPORT_CONST_INT
|
||||
#define LV_EXPORT_CONST_INT(int_value) struct _silence_gcc_warning
|
||||
#endif
|
||||
|
||||
/*===================
|
||||
* HAL settings
|
||||
*==================*/
|
||||
|
||||
/* 1: use a custom tick source.
|
||||
* It removes the need to manually update the tick with `lv_tick_inc`) */
|
||||
#ifndef LV_TICK_CUSTOM
|
||||
#define LV_TICK_CUSTOM 0
|
||||
#endif
|
||||
#if LV_TICK_CUSTOM == 1
|
||||
#ifndef LV_TICK_CUSTOM_INCLUDE
|
||||
#define LV_TICK_CUSTOM_INCLUDE "something.h" /*Header for the sys time function*/
|
||||
#endif
|
||||
#ifndef LV_TICK_CUSTOM_SYS_TIME_EXPR
|
||||
#define LV_TICK_CUSTOM_SYS_TIME_EXPR (millis()) /*Expression evaluating to current systime in ms*/
|
||||
#endif
|
||||
#endif /*LV_TICK_CUSTOM*/
|
||||
|
||||
|
||||
/*================
|
||||
* Log settings
|
||||
*===============*/
|
||||
|
||||
/*1: Enable the log module*/
|
||||
#ifndef LV_USE_LOG
|
||||
#define LV_USE_LOG 0
|
||||
#endif
|
||||
#if LV_USE_LOG
|
||||
/* How important log should be added:
|
||||
* LV_LOG_LEVEL_TRACE A lot of logs to give detailed information
|
||||
* LV_LOG_LEVEL_INFO Log important events
|
||||
* LV_LOG_LEVEL_WARN Log if something unwanted happened but didn't cause a problem
|
||||
* LV_LOG_LEVEL_ERROR Only critical issue, when the system may fail
|
||||
* LV_LOG_LEVEL_NONE Do not log anything
|
||||
*/
|
||||
#ifndef LV_LOG_LEVEL
|
||||
# define LV_LOG_LEVEL LV_LOG_LEVEL_WARN
|
||||
#endif
|
||||
|
||||
/* 1: Print the log with 'printf';
|
||||
* 0: user need to register a callback with `lv_log_register_print_cb`*/
|
||||
#ifndef LV_LOG_PRINTF
|
||||
# define LV_LOG_PRINTF 0
|
||||
#endif
|
||||
#endif /*LV_USE_LOG*/
|
||||
|
||||
/*=================
|
||||
* Debug settings
|
||||
*================*/
|
||||
|
||||
/* If Debug is enabled LittelvGL validates the parameters of the functions.
|
||||
* If an invalid parameter is found an error log message is printed and
|
||||
* the MCU halts at the error. (`LV_USE_LOG` should be enabled)
|
||||
* If you are debugging the MCU you can pause
|
||||
* the debugger to see exactly where the issue is.
|
||||
*
|
||||
* The behavior of asserts can be overwritten by redefining them here.
|
||||
* E.g. #define LV_ASSERT_MEM(p) <my_assert_code>
|
||||
*/
|
||||
#ifndef LV_USE_DEBUG
|
||||
#define LV_USE_DEBUG 1
|
||||
#endif
|
||||
#if LV_USE_DEBUG
|
||||
|
||||
/*Check if the parameter is NULL. (Quite fast) */
|
||||
#ifndef LV_USE_ASSERT_NULL
|
||||
#define LV_USE_ASSERT_NULL 1
|
||||
#endif
|
||||
|
||||
/*Checks is the memory is successfully allocated or no. (Quite fast)*/
|
||||
#ifndef LV_USE_ASSERT_MEM
|
||||
#define LV_USE_ASSERT_MEM 1
|
||||
#endif
|
||||
|
||||
/* Check the strings.
|
||||
* Search for NULL, very long strings, invalid characters, and unnatural repetitions. (Slow)
|
||||
* If disabled `LV_USE_ASSERT_NULL` will be performed instead (if it's enabled) */
|
||||
#ifndef LV_USE_ASSERT_STR
|
||||
#define LV_USE_ASSERT_STR 0
|
||||
#endif
|
||||
|
||||
/* Check NULL, the object's type and existence (e.g. not deleted). (Quite slow)
|
||||
* If disabled `LV_USE_ASSERT_NULL` will be performed instead (if it's enabled) */
|
||||
#ifndef LV_USE_ASSERT_OBJ
|
||||
#define LV_USE_ASSERT_OBJ 0
|
||||
#endif
|
||||
|
||||
/*Check if the styles are properly initialized. (Fast)*/
|
||||
#ifndef LV_USE_ASSERT_STYLE
|
||||
#define LV_USE_ASSERT_STYLE 1
|
||||
#endif
|
||||
|
||||
#endif /*LV_USE_DEBUG*/
|
||||
|
||||
/*================
|
||||
* THEME USAGE
|
||||
*================*/
|
||||
#ifndef LV_THEME_LIVE_UPDATE
|
||||
#define LV_THEME_LIVE_UPDATE 0 /*1: Allow theme switching at run time. Uses 8..10 kB of RAM*/
|
||||
#endif
|
||||
|
||||
#ifndef LV_USE_THEME_TEMPL
|
||||
#define LV_USE_THEME_TEMPL 0 /*Just for test*/
|
||||
#endif
|
||||
#ifndef LV_USE_THEME_DEFAULT
|
||||
#define LV_USE_THEME_DEFAULT 0 /*Built mainly from the built-in styles. Consumes very few RAM*/
|
||||
#endif
|
||||
#ifndef LV_USE_THEME_ALIEN
|
||||
#define LV_USE_THEME_ALIEN 0 /*Dark futuristic theme*/
|
||||
#endif
|
||||
#ifndef LV_USE_THEME_NIGHT
|
||||
#define LV_USE_THEME_NIGHT 0 /*Dark elegant theme*/
|
||||
#endif
|
||||
#ifndef LV_USE_THEME_MONO
|
||||
#define LV_USE_THEME_MONO 0 /*Mono color theme for monochrome displays*/
|
||||
#endif
|
||||
#ifndef LV_USE_THEME_MATERIAL
|
||||
#define LV_USE_THEME_MATERIAL 0 /*Flat theme with bold colors and light shadows*/
|
||||
#endif
|
||||
#ifndef LV_USE_THEME_ZEN
|
||||
#define LV_USE_THEME_ZEN 0 /*Peaceful, mainly light theme */
|
||||
#endif
|
||||
#ifndef LV_USE_THEME_NEMO
|
||||
#define LV_USE_THEME_NEMO 0 /*Water-like theme based on the movie "Finding Nemo"*/
|
||||
#endif
|
||||
|
||||
/*==================
|
||||
* FONT USAGE
|
||||
*===================*/
|
||||
|
||||
/* The built-in fonts contains the ASCII range and some Symbols with 4 bit-per-pixel.
|
||||
* The symbols are available via `LV_SYMBOL_...` defines
|
||||
* More info about fonts: https://docs.littlevgl.com/#Fonts
|
||||
* To create a new font go to: https://littlevgl.com/ttf-font-to-c-array
|
||||
*/
|
||||
|
||||
/* Robot fonts with bpp = 4
|
||||
* https://fonts.google.com/specimen/Roboto */
|
||||
#ifndef LV_FONT_ROBOTO_12
|
||||
#define LV_FONT_ROBOTO_12 0
|
||||
#endif
|
||||
#ifndef LV_FONT_ROBOTO_16
|
||||
#define LV_FONT_ROBOTO_16 1
|
||||
#endif
|
||||
#ifndef LV_FONT_ROBOTO_22
|
||||
#define LV_FONT_ROBOTO_22 0
|
||||
#endif
|
||||
#ifndef LV_FONT_ROBOTO_28
|
||||
#define LV_FONT_ROBOTO_28 0
|
||||
#endif
|
||||
|
||||
/* Demonstrate special features */
|
||||
#ifndef LV_FONT_ROBOTO_12_SUBPX
|
||||
#define LV_FONT_ROBOTO_12_SUBPX 1
|
||||
#endif
|
||||
#ifndef LV_FONT_ROBOTO_28_COMPRESSED
|
||||
#define LV_FONT_ROBOTO_28_COMPRESSED 1 /*bpp = 3*/
|
||||
#endif
|
||||
|
||||
/*Pixel perfect monospace font
|
||||
* http://pelulamu.net/unscii/ */
|
||||
#ifndef LV_FONT_UNSCII_8
|
||||
#define LV_FONT_UNSCII_8 0
|
||||
#endif
|
||||
|
||||
/* Optionally declare your custom fonts here.
|
||||
* You can use these fonts as default font too
|
||||
* and they will be available globally. E.g.
|
||||
* #define LV_FONT_CUSTOM_DECLARE LV_FONT_DECLARE(my_font_1) \
|
||||
* LV_FONT_DECLARE(my_font_2)
|
||||
*/
|
||||
#ifndef LV_FONT_CUSTOM_DECLARE
|
||||
#define LV_FONT_CUSTOM_DECLARE
|
||||
#endif
|
||||
|
||||
/*Always set a default font from the built-in fonts*/
|
||||
#ifndef LV_FONT_DEFAULT
|
||||
#define LV_FONT_DEFAULT &lv_font_roboto_16
|
||||
#endif
|
||||
|
||||
/* Enable it if you have fonts with a lot of characters.
|
||||
* The limit depends on the font size, font face and bpp
|
||||
* but with > 10,000 characters if you see issues probably you need to enable it.*/
|
||||
#ifndef LV_FONT_FMT_TXT_LARGE
|
||||
#define LV_FONT_FMT_TXT_LARGE 0
|
||||
#endif
|
||||
|
||||
/* Set the pixel order of the display.
|
||||
* Important only if "subpx fonts" are used.
|
||||
* With "normal" font it doesn't matter.
|
||||
*/
|
||||
#ifndef LV_FONT_SUBPX_BGR
|
||||
#define LV_FONT_SUBPX_BGR 0
|
||||
#endif
|
||||
|
||||
/*Declare the type of the user data of fonts (can be e.g. `void *`, `int`, `struct`)*/
|
||||
|
||||
/*=================
|
||||
* Text settings
|
||||
*=================*/
|
||||
|
||||
/* Select a character encoding for strings.
|
||||
* Your IDE or editor should have the same character encoding
|
||||
* - LV_TXT_ENC_UTF8
|
||||
* - LV_TXT_ENC_ASCII
|
||||
* */
|
||||
#ifndef LV_TXT_ENC
|
||||
#define LV_TXT_ENC LV_TXT_ENC_UTF8
|
||||
#endif
|
||||
|
||||
/*Can break (wrap) texts on these chars*/
|
||||
#ifndef LV_TXT_BREAK_CHARS
|
||||
#define LV_TXT_BREAK_CHARS " ,.;:-_"
|
||||
#endif
|
||||
|
||||
/* If a word is at least this long, will break wherever "prettiest"
|
||||
* To disable, set to a value <= 0 */
|
||||
#ifndef LV_TXT_LINE_BREAK_LONG_LEN
|
||||
#define LV_TXT_LINE_BREAK_LONG_LEN 12
|
||||
#endif
|
||||
|
||||
/* Minimum number of characters in a long word to put on a line before a break.
|
||||
* Depends on LV_TXT_LINE_BREAK_LONG_LEN. */
|
||||
#ifndef LV_TXT_LINE_BREAK_LONG_PRE_MIN_LEN
|
||||
#define LV_TXT_LINE_BREAK_LONG_PRE_MIN_LEN 3
|
||||
#endif
|
||||
|
||||
/* Minimum number of characters in a long word to put on a line after a break.
|
||||
* Depends on LV_TXT_LINE_BREAK_LONG_LEN. */
|
||||
#ifndef LV_TXT_LINE_BREAK_LONG_POST_MIN_LEN
|
||||
#define LV_TXT_LINE_BREAK_LONG_POST_MIN_LEN 3
|
||||
#endif
|
||||
|
||||
/* The control character to use for signalling text recoloring. */
|
||||
#ifndef LV_TXT_COLOR_CMD
|
||||
#define LV_TXT_COLOR_CMD "#"
|
||||
#endif
|
||||
|
||||
/* Support bidirectional texts.
|
||||
* Allows mixing Left-to-Right and Right-to-Left texts.
|
||||
* The direction will be processed according to the Unicode Bidirectioanl Algorithm:
|
||||
* https://www.w3.org/International/articles/inline-bidi-markup/uba-basics*/
|
||||
#ifndef LV_USE_BIDI
|
||||
#define LV_USE_BIDI 0
|
||||
#endif
|
||||
#if LV_USE_BIDI
|
||||
/* Set the default direction. Supported values:
|
||||
* `LV_BIDI_DIR_LTR` Left-to-Right
|
||||
* `LV_BIDI_DIR_RTL` Right-to-Left
|
||||
* `LV_BIDI_DIR_AUTO` detect texts base direction */
|
||||
#ifndef LV_BIDI_BASE_DIR_DEF
|
||||
#define LV_BIDI_BASE_DIR_DEF LV_BIDI_DIR_AUTO
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/*Change the built in (v)snprintf functions*/
|
||||
#ifndef LV_SPRINTF_CUSTOM
|
||||
#define LV_SPRINTF_CUSTOM 0
|
||||
#endif
|
||||
#if LV_SPRINTF_CUSTOM
|
||||
#ifndef LV_SPRINTF_INCLUDE
|
||||
# define LV_SPRINTF_INCLUDE <stdio.h>
|
||||
#endif
|
||||
#ifndef lv_snprintf
|
||||
# define lv_snprintf snprintf
|
||||
#endif
|
||||
#ifndef lv_vsnprintf
|
||||
# define lv_vsnprintf vsnprintf
|
||||
#endif
|
||||
#endif /*LV_SPRINTF_CUSTOM*/
|
||||
|
||||
/*===================
|
||||
* LV_OBJ SETTINGS
|
||||
*==================*/
|
||||
|
||||
/*Declare the type of the user data of object (can be e.g. `void *`, `int`, `struct`)*/
|
||||
|
||||
/*1: enable `lv_obj_realaign()` based on `lv_obj_align()` parameters*/
|
||||
#ifndef LV_USE_OBJ_REALIGN
|
||||
#define LV_USE_OBJ_REALIGN 1
|
||||
#endif
|
||||
|
||||
/* Enable to make the object clickable on a larger area.
|
||||
* LV_EXT_CLICK_AREA_OFF or 0: Disable this feature
|
||||
* LV_EXT_CLICK_AREA_TINY: The extra area can be adjusted horizontally and vertically (0..255 px)
|
||||
* LV_EXT_CLICK_AREA_FULL: The extra area can be adjusted in all 4 directions (-32k..+32k px)
|
||||
*/
|
||||
#ifndef LV_USE_EXT_CLICK_AREA
|
||||
#define LV_USE_EXT_CLICK_AREA LV_EXT_CLICK_AREA_OFF
|
||||
#endif
|
||||
|
||||
/*==================
|
||||
* LV OBJ X USAGE
|
||||
*================*/
|
||||
/*
|
||||
* Documentation of the object types: https://docs.littlevgl.com/#Object-types
|
||||
*/
|
||||
|
||||
/*Arc (dependencies: -)*/
|
||||
#ifndef LV_USE_ARC
|
||||
#define LV_USE_ARC 1
|
||||
#endif
|
||||
|
||||
/*Bar (dependencies: -)*/
|
||||
#ifndef LV_USE_BAR
|
||||
#define LV_USE_BAR 1
|
||||
#endif
|
||||
|
||||
/*Button (dependencies: lv_cont*/
|
||||
#ifndef LV_USE_BTN
|
||||
#define LV_USE_BTN 1
|
||||
#endif
|
||||
#if LV_USE_BTN != 0
|
||||
/*Enable button-state animations - draw a circle on click (dependencies: LV_USE_ANIMATION)*/
|
||||
#ifndef LV_BTN_INK_EFFECT
|
||||
# define LV_BTN_INK_EFFECT 0
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/*Button matrix (dependencies: -)*/
|
||||
#ifndef LV_USE_BTNM
|
||||
#define LV_USE_BTNM 1
|
||||
#endif
|
||||
|
||||
/*Calendar (dependencies: -)*/
|
||||
#ifndef LV_USE_CALENDAR
|
||||
#define LV_USE_CALENDAR 1
|
||||
#endif
|
||||
|
||||
/*Canvas (dependencies: lv_img)*/
|
||||
#ifndef LV_USE_CANVAS
|
||||
#define LV_USE_CANVAS 1
|
||||
#endif
|
||||
|
||||
/*Check box (dependencies: lv_btn, lv_label)*/
|
||||
#ifndef LV_USE_CB
|
||||
#define LV_USE_CB 1
|
||||
#endif
|
||||
|
||||
/*Chart (dependencies: -)*/
|
||||
#ifndef LV_USE_CHART
|
||||
#define LV_USE_CHART 1
|
||||
#endif
|
||||
#if LV_USE_CHART
|
||||
#ifndef LV_CHART_AXIS_TICK_LABEL_MAX_LEN
|
||||
# define LV_CHART_AXIS_TICK_LABEL_MAX_LEN 20
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/*Container (dependencies: -*/
|
||||
#ifndef LV_USE_CONT
|
||||
#define LV_USE_CONT 1
|
||||
#endif
|
||||
|
||||
/*Color picker (dependencies: -*/
|
||||
#ifndef LV_USE_CPICKER
|
||||
#define LV_USE_CPICKER 1
|
||||
#endif
|
||||
|
||||
/*Drop down list (dependencies: lv_page, lv_label, lv_symbol_def.h)*/
|
||||
#ifndef LV_USE_DDLIST
|
||||
#define LV_USE_DDLIST 1
|
||||
#endif
|
||||
#if LV_USE_DDLIST != 0
|
||||
/*Open and close default animation time [ms] (0: no animation)*/
|
||||
#ifndef LV_DDLIST_DEF_ANIM_TIME
|
||||
# define LV_DDLIST_DEF_ANIM_TIME 200
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/*Gauge (dependencies:lv_bar, lv_lmeter)*/
|
||||
#ifndef LV_USE_GAUGE
|
||||
#define LV_USE_GAUGE 1
|
||||
#endif
|
||||
|
||||
/*Image (dependencies: lv_label*/
|
||||
#ifndef LV_USE_IMG
|
||||
#define LV_USE_IMG 1
|
||||
#endif
|
||||
|
||||
/*Image Button (dependencies: lv_btn*/
|
||||
#ifndef LV_USE_IMGBTN
|
||||
#define LV_USE_IMGBTN 1
|
||||
#endif
|
||||
#if LV_USE_IMGBTN
|
||||
/*1: The imgbtn requires left, mid and right parts and the width can be set freely*/
|
||||
#ifndef LV_IMGBTN_TILED
|
||||
# define LV_IMGBTN_TILED 0
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/*Keyboard (dependencies: lv_btnm)*/
|
||||
#ifndef LV_USE_KB
|
||||
#define LV_USE_KB 1
|
||||
#endif
|
||||
|
||||
/*Label (dependencies: -*/
|
||||
#ifndef LV_USE_LABEL
|
||||
#define LV_USE_LABEL 1
|
||||
#endif
|
||||
#if LV_USE_LABEL != 0
|
||||
/*Hor, or ver. scroll speed [px/sec] in 'LV_LABEL_LONG_ROLL/ROLL_CIRC' mode*/
|
||||
#ifndef LV_LABEL_DEF_SCROLL_SPEED
|
||||
# define LV_LABEL_DEF_SCROLL_SPEED 25
|
||||
#endif
|
||||
|
||||
/* Waiting period at beginning/end of animation cycle */
|
||||
#ifndef LV_LABEL_WAIT_CHAR_COUNT
|
||||
# define LV_LABEL_WAIT_CHAR_COUNT 3
|
||||
#endif
|
||||
|
||||
/*Enable selecting text of the label */
|
||||
#ifndef LV_LABEL_TEXT_SEL
|
||||
# define LV_LABEL_TEXT_SEL 0
|
||||
#endif
|
||||
|
||||
/*Store extra some info in labels (12 bytes) to speed up drawing of very long texts*/
|
||||
#ifndef LV_LABEL_LONG_TXT_HINT
|
||||
# define LV_LABEL_LONG_TXT_HINT 0
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/*LED (dependencies: -)*/
|
||||
#ifndef LV_USE_LED
|
||||
#define LV_USE_LED 1
|
||||
#endif
|
||||
|
||||
/*Line (dependencies: -*/
|
||||
#ifndef LV_USE_LINE
|
||||
#define LV_USE_LINE 1
|
||||
#endif
|
||||
|
||||
/*List (dependencies: lv_page, lv_btn, lv_label, (lv_img optionally for icons ))*/
|
||||
#ifndef LV_USE_LIST
|
||||
#define LV_USE_LIST 1
|
||||
#endif
|
||||
#if LV_USE_LIST != 0
|
||||
/*Default animation time of focusing to a list element [ms] (0: no animation) */
|
||||
#ifndef LV_LIST_DEF_ANIM_TIME
|
||||
# define LV_LIST_DEF_ANIM_TIME 100
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/*Line meter (dependencies: *;)*/
|
||||
#ifndef LV_USE_LMETER
|
||||
#define LV_USE_LMETER 1
|
||||
#endif
|
||||
|
||||
/*Message box (dependencies: lv_rect, lv_btnm, lv_label)*/
|
||||
#ifndef LV_USE_MBOX
|
||||
#define LV_USE_MBOX 1
|
||||
#endif
|
||||
|
||||
/*Page (dependencies: lv_cont)*/
|
||||
#ifndef LV_USE_PAGE
|
||||
#define LV_USE_PAGE 1
|
||||
#endif
|
||||
#if LV_USE_PAGE != 0
|
||||
/*Focus default animation time [ms] (0: no animation)*/
|
||||
#ifndef LV_PAGE_DEF_ANIM_TIME
|
||||
# define LV_PAGE_DEF_ANIM_TIME 400
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/*Preload (dependencies: lv_arc, lv_anim)*/
|
||||
#ifndef LV_USE_PRELOAD
|
||||
#define LV_USE_PRELOAD 1
|
||||
#endif
|
||||
#if LV_USE_PRELOAD != 0
|
||||
#ifndef LV_PRELOAD_DEF_ARC_LENGTH
|
||||
# define LV_PRELOAD_DEF_ARC_LENGTH 60 /*[deg]*/
|
||||
#endif
|
||||
#ifndef LV_PRELOAD_DEF_SPIN_TIME
|
||||
# define LV_PRELOAD_DEF_SPIN_TIME 1000 /*[ms]*/
|
||||
#endif
|
||||
#ifndef LV_PRELOAD_DEF_ANIM
|
||||
# define LV_PRELOAD_DEF_ANIM LV_PRELOAD_TYPE_SPINNING_ARC
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/*Roller (dependencies: lv_ddlist)*/
|
||||
#ifndef LV_USE_ROLLER
|
||||
#define LV_USE_ROLLER 1
|
||||
#endif
|
||||
#if LV_USE_ROLLER != 0
|
||||
/*Focus animation time [ms] (0: no animation)*/
|
||||
#ifndef LV_ROLLER_DEF_ANIM_TIME
|
||||
# define LV_ROLLER_DEF_ANIM_TIME 200
|
||||
#endif
|
||||
|
||||
/*Number of extra "pages" when the roller is infinite*/
|
||||
#ifndef LV_ROLLER_INF_PAGES
|
||||
# define LV_ROLLER_INF_PAGES 7
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/*Slider (dependencies: lv_bar)*/
|
||||
#ifndef LV_USE_SLIDER
|
||||
#define LV_USE_SLIDER 1
|
||||
#endif
|
||||
|
||||
/*Spinbox (dependencies: lv_ta)*/
|
||||
#ifndef LV_USE_SPINBOX
|
||||
#define LV_USE_SPINBOX 1
|
||||
#endif
|
||||
|
||||
/*Switch (dependencies: lv_slider)*/
|
||||
#ifndef LV_USE_SW
|
||||
#define LV_USE_SW 1
|
||||
#endif
|
||||
|
||||
/*Text area (dependencies: lv_label, lv_page)*/
|
||||
#ifndef LV_USE_TA
|
||||
#define LV_USE_TA 1
|
||||
#endif
|
||||
#if LV_USE_TA != 0
|
||||
#ifndef LV_TA_DEF_CURSOR_BLINK_TIME
|
||||
# define LV_TA_DEF_CURSOR_BLINK_TIME 400 /*ms*/
|
||||
#endif
|
||||
#ifndef LV_TA_DEF_PWD_SHOW_TIME
|
||||
# define LV_TA_DEF_PWD_SHOW_TIME 1500 /*ms*/
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/*Table (dependencies: lv_label)*/
|
||||
#ifndef LV_USE_TABLE
|
||||
#define LV_USE_TABLE 1
|
||||
#endif
|
||||
#if LV_USE_TABLE
|
||||
#ifndef LV_TABLE_COL_MAX
|
||||
# define LV_TABLE_COL_MAX 12
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/*Tab (dependencies: lv_page, lv_btnm)*/
|
||||
#ifndef LV_USE_TABVIEW
|
||||
#define LV_USE_TABVIEW 1
|
||||
#endif
|
||||
# if LV_USE_TABVIEW != 0
|
||||
/*Time of slide animation [ms] (0: no animation)*/
|
||||
#ifndef LV_TABVIEW_DEF_ANIM_TIME
|
||||
# define LV_TABVIEW_DEF_ANIM_TIME 300
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/*Tileview (dependencies: lv_page) */
|
||||
#ifndef LV_USE_TILEVIEW
|
||||
#define LV_USE_TILEVIEW 1
|
||||
#endif
|
||||
#if LV_USE_TILEVIEW
|
||||
/*Time of slide animation [ms] (0: no animation)*/
|
||||
#ifndef LV_TILEVIEW_DEF_ANIM_TIME
|
||||
# define LV_TILEVIEW_DEF_ANIM_TIME 300
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/*Window (dependencies: lv_cont, lv_btn, lv_label, lv_img, lv_page)*/
|
||||
#ifndef LV_USE_WIN
|
||||
#define LV_USE_WIN 1
|
||||
#endif
|
||||
|
||||
/*==================
|
||||
* Non-user section
|
||||
*==================*/
|
||||
|
||||
#if defined(_MSC_VER) && !defined(_CRT_SECURE_NO_WARNINGS) /* Disable warnings for Visual Studio*/
|
||||
#ifndef _CRT_SECURE_NO_WARNINGS
|
||||
# define _CRT_SECURE_NO_WARNINGS
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
#endif /*LV_CONF_CHECKER_H*/
|
@ -1,12 +0,0 @@
|
||||
CSRCS += lv_group.c
|
||||
CSRCS += lv_indev.c
|
||||
CSRCS += lv_disp.c
|
||||
CSRCS += lv_obj.c
|
||||
CSRCS += lv_refr.c
|
||||
CSRCS += lv_style.c
|
||||
CSRCS += lv_debug.c
|
||||
|
||||
DEPPATH += --dep-path $(LVGL_DIR)/lvgl/src/lv_core
|
||||
VPATH += :$(LVGL_DIR)/lvgl/src/lv_core
|
||||
|
||||
CFLAGS += "-I$(LVGL_DIR)/lvgl/src/lv_core"
|
@ -1,193 +0,0 @@
|
||||
/**
|
||||
* @file lv_debug.c
|
||||
*
|
||||
*/
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "lv_obj.h"
|
||||
#include "lv_debug.h"
|
||||
|
||||
#if LV_USE_DEBUG
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
#ifndef LV_DEBUG_STR_MAX_LENGTH
|
||||
#define LV_DEBUG_STR_MAX_LENGTH (1024 * 8)
|
||||
#endif
|
||||
|
||||
#ifndef LV_DEBUG_STR_MAX_REPEAT
|
||||
#define LV_DEBUG_STR_MAX_REPEAT 8
|
||||
#endif
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
static bool obj_valid_child(const lv_obj_t * parent, const lv_obj_t * obj_to_find);
|
||||
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL FUNCTIONS
|
||||
**********************/
|
||||
|
||||
bool lv_debug_check_null(const void * p)
|
||||
{
|
||||
if(p) return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool lv_debug_check_obj_type(const lv_obj_t * obj, const char * obj_type)
|
||||
{
|
||||
if(obj_type[0] == '\0') return true;
|
||||
|
||||
lv_obj_type_t types;
|
||||
lv_obj_get_type((lv_obj_t *)obj, &types);
|
||||
|
||||
uint8_t i;
|
||||
for(i = 0; i < LV_MAX_ANCESTOR_NUM; i++) {
|
||||
if(strcmp(types.type[i], obj_type) == 0) return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool lv_debug_check_obj_valid(const lv_obj_t * obj)
|
||||
{
|
||||
lv_disp_t * disp = lv_disp_get_next(NULL);
|
||||
while(disp) {
|
||||
lv_obj_t * scr;
|
||||
LV_LL_READ(disp->scr_ll, scr) {
|
||||
|
||||
if(scr == obj) return true;
|
||||
bool found = obj_valid_child(scr, obj);
|
||||
if(found) return true;
|
||||
}
|
||||
|
||||
disp = lv_disp_get_next(disp);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool lv_debug_check_style(const lv_style_t * style)
|
||||
{
|
||||
if(style == NULL) return true; /*NULL style is still valid*/
|
||||
|
||||
#if LV_USE_ASSERT_STYLE
|
||||
if(style->debug_sentinel != LV_STYLE_DEGUG_SENTINEL_VALUE) {
|
||||
LV_LOG_WARN("Invalid style (local variable or not initialized?)");
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool lv_debug_check_str(const void * str)
|
||||
{
|
||||
const uint8_t * s = (const uint8_t *)str;
|
||||
uint8_t last_byte = 0;
|
||||
uint32_t rep = 0;
|
||||
uint32_t i;
|
||||
|
||||
for(i = 0; s[i] != '\0' && i < LV_DEBUG_STR_MAX_LENGTH; i++) {
|
||||
if(s[i] != last_byte) {
|
||||
last_byte = s[i];
|
||||
rep = 1;
|
||||
} else if(s[i] > 0x7F){
|
||||
rep++;
|
||||
if(rep > LV_DEBUG_STR_MAX_REPEAT) {
|
||||
LV_LOG_WARN("lv_debug_check_str: a non-ASCII char has repeated more than LV_DEBUG_STR_MAX_REPEAT times)");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if(s[i] < 10) {
|
||||
LV_LOG_WARN("lv_debug_check_str: invalid char in the string (< 10 value)");
|
||||
return false; /*Shouldn't occur in strings*/
|
||||
}
|
||||
}
|
||||
|
||||
if(s[i] == '\0') return true;
|
||||
|
||||
LV_LOG_WARN("lv_debug_check_str: string is longer than LV_DEBUG_STR_MAX_LENGTH");
|
||||
return false;
|
||||
}
|
||||
|
||||
void lv_debug_log_error(const char * msg, uint64_t value)
|
||||
{
|
||||
static const char hex[] = "0123456789ABCDEF";
|
||||
|
||||
size_t msg_len = strlen(msg);
|
||||
uint32_t value_len = sizeof(unsigned long int);
|
||||
|
||||
if(msg_len < 230) {
|
||||
char buf[255];
|
||||
char * bufp = buf;
|
||||
|
||||
/*Add the function name*/
|
||||
memcpy(bufp, msg, msg_len);
|
||||
bufp += msg_len;
|
||||
|
||||
/*Add value in hey*/
|
||||
*bufp = ' ';
|
||||
bufp ++;
|
||||
*bufp = '(';
|
||||
bufp ++;
|
||||
*bufp = '0';
|
||||
bufp ++;
|
||||
*bufp = 'x';
|
||||
bufp ++;
|
||||
|
||||
int8_t i;
|
||||
for(i = value_len * 2 - 1; i >= 0; i--) {
|
||||
uint8_t x = (unsigned long int)((unsigned long int)value >> (i * 4)) & 0xF;
|
||||
|
||||
*bufp = hex[x];
|
||||
bufp++;
|
||||
}
|
||||
|
||||
*bufp = ')';
|
||||
bufp ++;
|
||||
|
||||
*bufp = '\0';
|
||||
LV_LOG_ERROR(buf);
|
||||
} else {
|
||||
LV_LOG_ERROR(msg);
|
||||
}
|
||||
}
|
||||
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
|
||||
static bool obj_valid_child(const lv_obj_t * parent, const lv_obj_t * obj_to_find)
|
||||
{
|
||||
/*Check all children of `parent`*/
|
||||
lv_obj_t * child;
|
||||
LV_LL_READ(parent->child_ll, child) {
|
||||
if(child == obj_to_find) return true;
|
||||
|
||||
/*Check the children*/
|
||||
bool found = obj_valid_child(child, obj_to_find);
|
||||
if(found) return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
#endif /*LV_USE_DEBUG*/
|
||||
|
@ -1,154 +0,0 @@
|
||||
/**
|
||||
* @file lv_debug.h
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LV_DEBUG_H
|
||||
#define LV_DEBUG_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "lv_obj.h"
|
||||
|
||||
#if LV_USE_DEBUG
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
bool lv_debug_check_null(const void * p);
|
||||
|
||||
bool lv_debug_check_obj_type(const lv_obj_t * obj, const char * obj_type);
|
||||
|
||||
bool lv_debug_check_obj_valid(const lv_obj_t * obj);
|
||||
|
||||
bool lv_debug_check_style(const lv_style_t * style);
|
||||
|
||||
bool lv_debug_check_str(const void * str);
|
||||
|
||||
void lv_debug_log_error(const char * msg, uint64_t value);
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
#ifndef LV_DEBUG_ASSERT
|
||||
#define LV_DEBUG_ASSERT(expr, msg, value) \
|
||||
{ \
|
||||
if(!(expr)) { \
|
||||
LV_LOG_ERROR(__func__); \
|
||||
lv_debug_log_error(msg, (uint64_t)((uintptr_t)value)); \
|
||||
while(1); \
|
||||
} \
|
||||
}
|
||||
#endif
|
||||
|
||||
/*----------------
|
||||
* CHECKS
|
||||
*----------------*/
|
||||
|
||||
#ifndef LV_DEBUG_IS_NULL
|
||||
#define LV_DEBUG_IS_NULL(p) (lv_debug_check_null(p))
|
||||
#endif
|
||||
|
||||
#ifndef LV_DEBUG_IS_STR
|
||||
#define LV_DEBUG_IS_STR(str) (lv_debug_check_null(str) && \
|
||||
lv_debug_check_str(str))
|
||||
#endif
|
||||
|
||||
#ifndef LV_DEBUG_IS_OBJ
|
||||
#define LV_DEBUG_IS_OBJ(obj_p, obj_type) (lv_debug_check_null(obj_p) && \
|
||||
lv_debug_check_obj_valid(obj_p) && \
|
||||
lv_debug_check_obj_type(obj_p, obj_type))
|
||||
#endif
|
||||
|
||||
#ifndef LV_DEBUG_IS_STYLE
|
||||
#define LV_DEBUG_IS_STYLE(style_p) (lv_debug_check_style(style_p))
|
||||
#endif
|
||||
|
||||
/*-----------------
|
||||
* ASSERTS
|
||||
*-----------------*/
|
||||
|
||||
/*clang-format off*/
|
||||
|
||||
#if LV_USE_ASSERT_NULL
|
||||
# ifndef LV_ASSERT_NULL
|
||||
# define LV_ASSERT_NULL(p) LV_DEBUG_ASSERT(LV_DEBUG_IS_NULL(p), "NULL pointer", p);
|
||||
# endif
|
||||
#else
|
||||
# define LV_ASSERT_NULL(p) true
|
||||
#endif
|
||||
|
||||
#if LV_USE_ASSERT_MEM
|
||||
# ifndef LV_ASSERT_MEM
|
||||
# define LV_ASSERT_MEM(p) LV_DEBUG_ASSERT(LV_DEBUG_IS_NULL(p), "Out of memory", p);
|
||||
# endif
|
||||
#else
|
||||
# define LV_ASSERT_MEM(p) true
|
||||
#endif
|
||||
|
||||
#if LV_USE_ASSERT_STR
|
||||
# ifndef LV_ASSERT_STR
|
||||
# define LV_ASSERT_STR(str) LV_DEBUG_ASSERT(LV_DEBUG_IS_STR(str), "Strange or invalid string", str);
|
||||
# endif
|
||||
#else /* LV_USE_ASSERT_OBJ == 0 */
|
||||
# if LV_USE_ASSERT_NULL /*Use at least LV_ASSERT_NULL if enabled*/
|
||||
# define LV_ASSERT_STR(str) LV_ASSERT_NULL(str)
|
||||
# else
|
||||
# define LV_ASSERT_STR(str) true
|
||||
# endif
|
||||
#endif
|
||||
|
||||
|
||||
#if LV_USE_ASSERT_OBJ
|
||||
# ifndef LV_ASSERT_OBJ
|
||||
# define LV_ASSERT_OBJ(obj_p, obj_type) LV_DEBUG_ASSERT(LV_DEBUG_IS_OBJ(obj_p, obj_type), "Invalid object", obj_p);
|
||||
# endif
|
||||
#else /* LV_USE_ASSERT_OBJ == 0 */
|
||||
# if LV_USE_ASSERT_NULL /*Use at least LV_ASSERT_NULL if enabled*/
|
||||
# define LV_ASSERT_OBJ(obj_p, obj_type) LV_ASSERT_NULL(obj_p)
|
||||
# else
|
||||
# define LV_ASSERT_OBJ(obj_p, obj_type) true
|
||||
# endif
|
||||
#endif
|
||||
|
||||
|
||||
#if LV_USE_ASSERT_STYLE
|
||||
# ifndef LV_ASSERT_STYLE
|
||||
# define LV_ASSERT_STYLE(style_p) LV_DEBUG_ASSERT(LV_DEBUG_IS_STYLE(style_p), "Invalid style", style_p);
|
||||
# endif
|
||||
#else
|
||||
# define LV_ASSERT_STYLE(style) true
|
||||
#endif
|
||||
|
||||
#else /* LV_USE_DEBUG == 0 */
|
||||
|
||||
#define LV_DEBUG_ASSERT(expr, msg, value) do{}while(0)
|
||||
|
||||
#define LV_ASSERT_NULL(p) true
|
||||
#define LV_ASSERT_MEM(p) true
|
||||
#define LV_ASSERT_STR(p) true
|
||||
#define LV_ASSERT_OBJ(obj, obj_type) true
|
||||
#define LV_ASSERT_STYLE(p) true
|
||||
|
||||
#endif /* LV_USE_DEBUG */
|
||||
/*clang-format on*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif /*LV_DEBUG_H*/
|
@ -1,178 +0,0 @@
|
||||
/**
|
||||
* @file lv_disp.c
|
||||
*
|
||||
*/
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "lv_disp.h"
|
||||
#include "../lv_misc/lv_math.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL FUNCTIONS
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Return with a pointer to the active screen
|
||||
* @param disp pointer to display which active screen should be get. (NULL to use the default
|
||||
* screen)
|
||||
* @return pointer to the active screen object (loaded by 'lv_scr_load()')
|
||||
*/
|
||||
lv_obj_t * lv_disp_get_scr_act(lv_disp_t * disp)
|
||||
{
|
||||
if(!disp) disp = lv_disp_get_default();
|
||||
if(!disp) {
|
||||
LV_LOG_WARN("lv_scr_act: no display registered to get its top layer");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return disp->act_scr;
|
||||
}
|
||||
|
||||
/**
|
||||
* Make a screen active
|
||||
* @param scr pointer to a screen
|
||||
*/
|
||||
void lv_disp_load_scr(lv_obj_t * scr)
|
||||
{
|
||||
lv_disp_t * d = lv_obj_get_disp(scr);
|
||||
|
||||
d->act_scr = scr;
|
||||
|
||||
lv_obj_invalidate(scr);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return with the top layer. (Same on every screen and it is above the normal screen layer)
|
||||
* @param disp pointer to display which top layer should be get. (NULL to use the default screen)
|
||||
* @return pointer to the top layer object (transparent screen sized lv_obj)
|
||||
*/
|
||||
lv_obj_t * lv_disp_get_layer_top(lv_disp_t * disp)
|
||||
{
|
||||
if(!disp) disp = lv_disp_get_default();
|
||||
if(!disp) {
|
||||
LV_LOG_WARN("lv_layer_top: no display registered to get its top layer");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return disp->top_layer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return with the sys. layer. (Same on every screen and it is above the normal screen and the top
|
||||
* layer)
|
||||
* @param disp pointer to display which sys. layer should be get. (NULL to use the default screen)
|
||||
* @return pointer to the sys layer object (transparent screen sized lv_obj)
|
||||
*/
|
||||
lv_obj_t * lv_disp_get_layer_sys(lv_disp_t * disp)
|
||||
{
|
||||
if(!disp) disp = lv_disp_get_default();
|
||||
if(!disp) {
|
||||
LV_LOG_WARN("lv_layer_sys: no display registered to get its top layer");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return disp->sys_layer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Assign a screen to a display.
|
||||
* @param disp pointer to a display where to assign the screen
|
||||
* @param scr pointer to a screen object to assign
|
||||
*/
|
||||
void lv_disp_assign_screen(lv_disp_t * disp, lv_obj_t * scr)
|
||||
{
|
||||
if(lv_obj_get_parent(scr) != NULL) {
|
||||
LV_LOG_WARN("lv_disp_assign_screen: try to assign a non-screen object");
|
||||
return;
|
||||
}
|
||||
|
||||
lv_disp_t * old_disp = lv_obj_get_disp(scr);
|
||||
|
||||
if(old_disp == disp) return;
|
||||
|
||||
lv_ll_chg_list(&old_disp->scr_ll, &disp->scr_ll, scr, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a pointer to the screen refresher task to
|
||||
* modify its parameters with `lv_task_...` functions.
|
||||
* @param disp pointer to a display
|
||||
* @return pointer to the display refresher task. (NULL on error)
|
||||
*/
|
||||
lv_task_t * lv_disp_get_refr_task(lv_disp_t * disp)
|
||||
{
|
||||
if(!disp) disp = lv_disp_get_default();
|
||||
if(!disp) {
|
||||
LV_LOG_WARN("lv_disp_get_refr_task: no display registered");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return disp->refr_task;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get elapsed time since last user activity on a display (e.g. click)
|
||||
* @param disp pointer to an display (NULL to get the overall smallest inactivity)
|
||||
* @return elapsed ticks (milliseconds) since the last activity
|
||||
*/
|
||||
uint32_t lv_disp_get_inactive_time(const lv_disp_t * disp)
|
||||
{
|
||||
if(!disp) disp = lv_disp_get_default();
|
||||
if(!disp) {
|
||||
LV_LOG_WARN("lv_disp_get_inactive_time: no display registered");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if(disp) return lv_tick_elaps(disp->last_activity_time);
|
||||
|
||||
lv_disp_t * d;
|
||||
uint32_t t = UINT32_MAX;
|
||||
d = lv_disp_get_next(NULL);
|
||||
while(d) {
|
||||
t = LV_MATH_MIN(t, lv_tick_elaps(d->last_activity_time));
|
||||
d = lv_disp_get_next(d);
|
||||
}
|
||||
|
||||
return t;
|
||||
}
|
||||
|
||||
/**
|
||||
* Manually trigger an activity on a display
|
||||
* @param disp pointer to an display (NULL to use the default display)
|
||||
*/
|
||||
void lv_disp_trig_activity(lv_disp_t * disp)
|
||||
{
|
||||
if(!disp) disp = lv_disp_get_default();
|
||||
if(!disp) {
|
||||
LV_LOG_WARN("lv_disp_trig_activity: no display registered");
|
||||
return;
|
||||
}
|
||||
|
||||
disp->last_activity_time = lv_tick_get();
|
||||
}
|
||||
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
@ -1,152 +0,0 @@
|
||||
/**
|
||||
* @file lv_disp.h
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LV_DISP_H
|
||||
#define LV_DISP_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "../lv_hal/lv_hal.h"
|
||||
#include "lv_obj.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Return with a pointer to the active screen
|
||||
* @param disp pointer to display which active screen should be get. (NULL to use the default
|
||||
* screen)
|
||||
* @return pointer to the active screen object (loaded by 'lv_scr_load()')
|
||||
*/
|
||||
lv_obj_t * lv_disp_get_scr_act(lv_disp_t * disp);
|
||||
|
||||
/**
|
||||
* Make a screen active
|
||||
* @param scr pointer to a screen
|
||||
*/
|
||||
void lv_disp_load_scr(lv_obj_t * scr);
|
||||
|
||||
/**
|
||||
* Return with the top layer. (Same on every screen and it is above the normal screen layer)
|
||||
* @param disp pointer to display which top layer should be get. (NULL to use the default screen)
|
||||
* @return pointer to the top layer object (transparent screen sized lv_obj)
|
||||
*/
|
||||
lv_obj_t * lv_disp_get_layer_top(lv_disp_t * disp);
|
||||
|
||||
/**
|
||||
* Return with the sys. layer. (Same on every screen and it is above the normal screen and the top
|
||||
* layer)
|
||||
* @param disp pointer to display which sys. layer should be get. (NULL to use the default screen)
|
||||
* @return pointer to the sys layer object (transparent screen sized lv_obj)
|
||||
*/
|
||||
lv_obj_t * lv_disp_get_layer_sys(lv_disp_t * disp);
|
||||
|
||||
/**
|
||||
* Assign a screen to a display.
|
||||
* @param disp pointer to a display where to assign the screen
|
||||
* @param scr pointer to a screen object to assign
|
||||
*/
|
||||
void lv_disp_assign_screen(lv_disp_t * disp, lv_obj_t * scr);
|
||||
|
||||
/**
|
||||
* Get a pointer to the screen refresher task to
|
||||
* modify its parameters with `lv_task_...` functions.
|
||||
* @param disp pointer to a display
|
||||
* @return pointer to the display refresher task. (NULL on error)
|
||||
*/
|
||||
lv_task_t * lv_disp_get_refr_task(lv_disp_t * disp);
|
||||
|
||||
/**
|
||||
* Get elapsed time since last user activity on a display (e.g. click)
|
||||
* @param disp pointer to an display (NULL to get the overall smallest inactivity)
|
||||
* @return elapsed ticks (milliseconds) since the last activity
|
||||
*/
|
||||
uint32_t lv_disp_get_inactive_time(const lv_disp_t * disp);
|
||||
|
||||
/**
|
||||
* Manually trigger an activity on a display
|
||||
* @param disp pointer to an display (NULL to use the default display)
|
||||
*/
|
||||
void lv_disp_trig_activity(lv_disp_t * disp);
|
||||
|
||||
/*------------------------------------------------
|
||||
* To improve backward compatibility
|
||||
* Recommended only if you have one display
|
||||
*------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* Get the active screen of the default display
|
||||
* @return pointer to the active screen
|
||||
*/
|
||||
static inline lv_obj_t * lv_scr_act(void)
|
||||
{
|
||||
return lv_disp_get_scr_act(lv_disp_get_default());
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the top layer of the default display
|
||||
* @return pointer to the top layer
|
||||
*/
|
||||
static inline lv_obj_t * lv_layer_top(void)
|
||||
{
|
||||
return lv_disp_get_layer_top(lv_disp_get_default());
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the active screen of the default display
|
||||
* @return pointer to the sys layer
|
||||
*/
|
||||
static inline lv_obj_t * lv_layer_sys(void)
|
||||
{
|
||||
return lv_disp_get_layer_sys(lv_disp_get_default());
|
||||
}
|
||||
|
||||
static inline void lv_scr_load(lv_obj_t * scr)
|
||||
{
|
||||
lv_disp_load_scr(scr);
|
||||
}
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
/*------------------------------------------------
|
||||
* To improve backward compatibility
|
||||
* Recommended only if you have one display
|
||||
*------------------------------------------------*/
|
||||
|
||||
#ifndef LV_HOR_RES
|
||||
/**
|
||||
* The horizontal resolution of the currently active display.
|
||||
*/
|
||||
#define LV_HOR_RES lv_disp_get_hor_res(lv_disp_get_default())
|
||||
#endif
|
||||
|
||||
#ifndef LV_VER_RES
|
||||
/**
|
||||
* The vertical resolution of the currently active display.
|
||||
*/
|
||||
#define LV_VER_RES lv_disp_get_ver_res(lv_disp_get_default())
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif /*LV_TEMPL_H*/
|
@ -1,708 +0,0 @@
|
||||
/**
|
||||
* @file lv_group.c
|
||||
*
|
||||
*/
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "lv_group.h"
|
||||
#if LV_USE_GROUP != 0
|
||||
#include <stddef.h>
|
||||
#include "../lv_core/lv_debug.h"
|
||||
#include "../lv_themes/lv_theme.h"
|
||||
#include "../lv_misc/lv_gc.h"
|
||||
|
||||
#if defined(LV_GC_INCLUDE)
|
||||
#include LV_GC_INCLUDE
|
||||
#endif /* LV_ENABLE_GC */
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
static void style_mod_def(lv_group_t * group, lv_style_t * style);
|
||||
static void style_mod_edit_def(lv_group_t * group, lv_style_t * style);
|
||||
static void refresh_theme(lv_group_t * g, lv_theme_t * th);
|
||||
static void focus_next_core(lv_group_t * group, void * (*begin)(const lv_ll_t *),
|
||||
void * (*move)(const lv_ll_t *, const void *));
|
||||
static void lv_group_refocus(lv_group_t * g);
|
||||
static void obj_to_foreground(lv_obj_t * obj);
|
||||
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL FUNCTIONS
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Init. the group module
|
||||
*/
|
||||
void lv_group_init(void)
|
||||
{
|
||||
lv_ll_init(&LV_GC_ROOT(_lv_group_ll), sizeof(lv_group_t));
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new object group
|
||||
* @return pointer to the new object group
|
||||
*/
|
||||
lv_group_t * lv_group_create(void)
|
||||
{
|
||||
lv_group_t * group = lv_ll_ins_head(&LV_GC_ROOT(_lv_group_ll));
|
||||
LV_ASSERT_MEM(group);
|
||||
if(group == NULL) return NULL;
|
||||
lv_ll_init(&group->obj_ll, sizeof(lv_obj_t *));
|
||||
|
||||
group->obj_focus = NULL;
|
||||
group->frozen = 0;
|
||||
group->focus_cb = NULL;
|
||||
group->click_focus = 1;
|
||||
group->editing = 0;
|
||||
group->refocus_policy = LV_GROUP_REFOCUS_POLICY_PREV;
|
||||
group->wrap = 1;
|
||||
|
||||
#if LV_USE_USER_DATA
|
||||
memset(&group->user_data, 0, sizeof(lv_group_user_data_t));
|
||||
#endif
|
||||
|
||||
/*Initialize style modification callbacks from current theme*/
|
||||
refresh_theme(group, lv_theme_get_current());
|
||||
|
||||
return group;
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete a group object
|
||||
* @param group pointer to a group
|
||||
*/
|
||||
void lv_group_del(lv_group_t * group)
|
||||
{
|
||||
/*Defocus the the currently focused object*/
|
||||
if(group->obj_focus != NULL) {
|
||||
(*group->obj_focus)->signal_cb(*group->obj_focus, LV_SIGNAL_DEFOCUS, NULL);
|
||||
lv_obj_invalidate(*group->obj_focus);
|
||||
}
|
||||
|
||||
/*Remove the objects from the group*/
|
||||
lv_obj_t ** obj;
|
||||
LV_LL_READ(group->obj_ll, obj)
|
||||
{
|
||||
(*obj)->group_p = NULL;
|
||||
}
|
||||
|
||||
lv_ll_clear(&(group->obj_ll));
|
||||
lv_ll_rem(&LV_GC_ROOT(_lv_group_ll), group);
|
||||
lv_mem_free(group);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add an object to a group
|
||||
* @param group pointer to a group
|
||||
* @param obj pointer to an object to add
|
||||
*/
|
||||
void lv_group_add_obj(lv_group_t * group, lv_obj_t * obj)
|
||||
{
|
||||
if(group == NULL) return;
|
||||
|
||||
/*Do not add the object twice*/
|
||||
lv_obj_t ** obj_i;
|
||||
LV_LL_READ(group->obj_ll, obj_i)
|
||||
{
|
||||
if((*obj_i) == obj) {
|
||||
LV_LOG_INFO("lv_group_add_obj: the object is already added to this group");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/*If the object is already in a group and focused then defocus it*/
|
||||
if(obj->group_p) {
|
||||
if(lv_obj_is_focused(obj)) {
|
||||
lv_group_refocus(obj->group_p);
|
||||
|
||||
LV_LOG_INFO("lv_group_add_obj: assign object to an other group");
|
||||
}
|
||||
}
|
||||
|
||||
obj->group_p = group;
|
||||
lv_obj_t ** next = lv_ll_ins_tail(&group->obj_ll);
|
||||
LV_ASSERT_MEM(next);
|
||||
if(next == NULL) return;
|
||||
*next = obj;
|
||||
|
||||
/* If the head and the tail is equal then there is only one object in the linked list.
|
||||
* In this case automatically activate it*/
|
||||
if(lv_ll_get_head(&group->obj_ll) == next) {
|
||||
lv_group_refocus(group);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove an object from its group
|
||||
* @param obj pointer to an object to remove
|
||||
*/
|
||||
void lv_group_remove_obj(lv_obj_t * obj)
|
||||
{
|
||||
lv_group_t * g = obj->group_p;
|
||||
if(g == NULL) return;
|
||||
if(g->obj_focus == NULL) return; /*Just to be sure (Not possible if there is at least one object in the group)*/
|
||||
|
||||
/*Focus on the next object*/
|
||||
if(*g->obj_focus == obj) {
|
||||
/*If this is the only object in the group then focus to nothing.*/
|
||||
if(lv_ll_get_head(&g->obj_ll) == g->obj_focus && lv_ll_get_tail(&g->obj_ll) == g->obj_focus) {
|
||||
(*g->obj_focus)->signal_cb(*g->obj_focus, LV_SIGNAL_DEFOCUS, NULL);
|
||||
}
|
||||
/*If there more objects in the group then focus to the next/prev object*/
|
||||
else {
|
||||
lv_group_refocus(g);
|
||||
}
|
||||
}
|
||||
|
||||
/* If the focuses object is still the same then it was the only object in the group but it will
|
||||
* be deleted. Set the `obj_focus` to NULL to get back to the initial state of the group with
|
||||
* zero objects*/
|
||||
if(*g->obj_focus == obj) {
|
||||
g->obj_focus = NULL;
|
||||
}
|
||||
|
||||
/*Search the object and remove it from its group */
|
||||
lv_obj_t ** i;
|
||||
LV_LL_READ(g->obj_ll, i)
|
||||
{
|
||||
if(*i == obj) {
|
||||
lv_ll_rem(&g->obj_ll, i);
|
||||
lv_mem_free(i);
|
||||
obj->group_p = NULL;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove all objects from a group
|
||||
* @param group pointer to a group
|
||||
*/
|
||||
void lv_group_remove_all_objs(lv_group_t * group)
|
||||
{
|
||||
/*Defocus the the currently focused object*/
|
||||
if(group->obj_focus != NULL) {
|
||||
(*group->obj_focus)->signal_cb(*group->obj_focus, LV_SIGNAL_DEFOCUS, NULL);
|
||||
lv_obj_invalidate(*group->obj_focus);
|
||||
group->obj_focus = NULL;
|
||||
}
|
||||
|
||||
/*Remove the objects from the group*/
|
||||
lv_obj_t ** obj;
|
||||
LV_LL_READ(group->obj_ll, obj)
|
||||
{
|
||||
(*obj)->group_p = NULL;
|
||||
}
|
||||
|
||||
lv_ll_clear(&(group->obj_ll));
|
||||
}
|
||||
|
||||
/**
|
||||
* Focus on an object (defocus the current)
|
||||
* @param obj pointer to an object to focus on
|
||||
*/
|
||||
void lv_group_focus_obj(lv_obj_t * obj)
|
||||
{
|
||||
if(obj == NULL) return;
|
||||
lv_group_t * g = obj->group_p;
|
||||
if(g == NULL) return;
|
||||
|
||||
if(g->frozen != 0) 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) {
|
||||
(*g->obj_focus)->signal_cb(*g->obj_focus, LV_SIGNAL_DEFOCUS, NULL);
|
||||
lv_res_t res = lv_event_send(*g->obj_focus, LV_EVENT_DEFOCUSED, NULL);
|
||||
if(res != LV_RES_OK) return;
|
||||
lv_obj_invalidate(*g->obj_focus);
|
||||
}
|
||||
|
||||
g->obj_focus = i;
|
||||
|
||||
if(g->obj_focus != NULL) {
|
||||
(*g->obj_focus)->signal_cb(*g->obj_focus, LV_SIGNAL_FOCUS, NULL);
|
||||
if(g->focus_cb) g->focus_cb(g);
|
||||
lv_res_t res = lv_event_send(*g->obj_focus, LV_EVENT_FOCUSED, NULL);
|
||||
if(res != LV_RES_OK) return;
|
||||
lv_obj_invalidate(*g->obj_focus);
|
||||
|
||||
/*If the object or its parent has `top == true` bring it to the foregorund*/
|
||||
obj_to_foreground(*g->obj_focus);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Focus the next object in a group (defocus the current)
|
||||
* @param group pointer to a group
|
||||
*/
|
||||
void lv_group_focus_next(lv_group_t * group)
|
||||
{
|
||||
focus_next_core(group, lv_ll_get_head, lv_ll_get_next);
|
||||
}
|
||||
|
||||
/**
|
||||
* Focus the previous object in a group (defocus the current)
|
||||
* @param group pointer to a group
|
||||
*/
|
||||
void lv_group_focus_prev(lv_group_t * group)
|
||||
{
|
||||
focus_next_core(group, lv_ll_get_tail, lv_ll_get_prev);
|
||||
}
|
||||
|
||||
/**
|
||||
* Do not let to change the focus from the current object
|
||||
* @param group pointer to a group
|
||||
* @param en true: freeze, false: release freezing (normal mode)
|
||||
*/
|
||||
void lv_group_focus_freeze(lv_group_t * group, bool en)
|
||||
{
|
||||
if(en == false)
|
||||
group->frozen = 0;
|
||||
else
|
||||
group->frozen = 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Send a control character to the focuses object of a group
|
||||
* @param group pointer to a group
|
||||
* @param c a character (use LV_KEY_.. to navigate)
|
||||
* @return result of focused object in group.
|
||||
*/
|
||||
lv_res_t lv_group_send_data(lv_group_t * group, uint32_t c)
|
||||
{
|
||||
lv_obj_t * act = lv_group_get_focused(group);
|
||||
if(act == NULL) return LV_RES_OK;
|
||||
|
||||
lv_res_t res;
|
||||
|
||||
res = act->signal_cb(act, LV_SIGNAL_CONTROL, &c);
|
||||
if(res != LV_RES_OK) return res;
|
||||
|
||||
res = lv_event_send(act, LV_EVENT_KEY, &c);
|
||||
if(res != LV_RES_OK) return res;
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a function for a group which will modify the object's style if it is in focus
|
||||
* @param group pointer to a group
|
||||
* @param style_mod_cb the style modifier function pointer
|
||||
*/
|
||||
void lv_group_set_style_mod_cb(lv_group_t * group, lv_group_style_mod_cb_t style_mod_cb)
|
||||
{
|
||||
group->style_mod_cb = style_mod_cb;
|
||||
if(group->obj_focus != NULL) lv_obj_invalidate(*group->obj_focus);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a function for a group which will modify the object's style if it is in focus in edit mode
|
||||
* @param group pointer to a group
|
||||
* @param style_mod_func the style modifier function pointer
|
||||
*/
|
||||
void lv_group_set_style_mod_edit_cb(lv_group_t * group, lv_group_style_mod_cb_t style_mod_edit_cb)
|
||||
{
|
||||
group->style_mod_edit_cb = style_mod_edit_cb;
|
||||
if(group->obj_focus != NULL) lv_obj_invalidate(*group->obj_focus);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a function for a group which will be called when a new object is focused
|
||||
* @param group pointer to a group
|
||||
* @param focus_cb the call back function or NULL if unused
|
||||
*/
|
||||
void lv_group_set_focus_cb(lv_group_t * group, lv_group_focus_cb_t focus_cb)
|
||||
{
|
||||
group->focus_cb = focus_cb;
|
||||
}
|
||||
|
||||
/**
|
||||
* Manually set the current mode (edit or navigate).
|
||||
* @param group pointer to group
|
||||
* @param edit: true: edit mode; false: navigate mode
|
||||
*/
|
||||
void lv_group_set_editing(lv_group_t * group, bool edit)
|
||||
{
|
||||
uint8_t en_val = edit ? 1 : 0;
|
||||
|
||||
if(en_val == group->editing) return; /*Do not set the same mode again*/
|
||||
|
||||
group->editing = en_val;
|
||||
lv_obj_t * focused = lv_group_get_focused(group);
|
||||
|
||||
if(focused) {
|
||||
focused->signal_cb(focused, LV_SIGNAL_FOCUS, NULL); /*Focus again to properly leave/open edit/navigate mode*/
|
||||
lv_res_t res = lv_event_send(*group->obj_focus, LV_EVENT_FOCUSED, NULL);
|
||||
if(res != LV_RES_OK) return;
|
||||
}
|
||||
|
||||
lv_obj_invalidate(focused);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the `click_focus` attribute. If enabled then the object will be focused then it is clicked.
|
||||
* @param group pointer to group
|
||||
* @param en: true: enable `click_focus`
|
||||
*/
|
||||
void lv_group_set_click_focus(lv_group_t * group, bool en)
|
||||
{
|
||||
group->click_focus = en ? 1 : 0;
|
||||
}
|
||||
|
||||
void lv_group_set_refocus_policy(lv_group_t * group, lv_group_refocus_policy_t policy)
|
||||
{
|
||||
group->refocus_policy = policy & 0x01;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set whether focus next/prev will allow wrapping from first->last or last->first.
|
||||
* @param group pointer to group
|
||||
* @param en: true: enable `wrap`
|
||||
*/
|
||||
void lv_group_set_wrap(lv_group_t * group, bool en)
|
||||
{
|
||||
group->wrap = en ? 1 : 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Modify a style with the set 'style_mod' function. The input style remains unchanged.
|
||||
* @param group pointer to group
|
||||
* @param style pointer to a style to modify
|
||||
* @return a copy of the input style but modified with the 'style_mod' function
|
||||
*/
|
||||
lv_style_t * lv_group_mod_style(lv_group_t * group, const lv_style_t * style)
|
||||
{
|
||||
/*Load the current style. It will be modified by the callback*/
|
||||
lv_style_copy(&group->style_tmp, style);
|
||||
|
||||
if(group->editing) {
|
||||
if(group->style_mod_edit_cb) group->style_mod_edit_cb(group, &group->style_tmp);
|
||||
} else {
|
||||
if(group->style_mod_cb) group->style_mod_cb(group, &group->style_tmp);
|
||||
}
|
||||
return &group->style_tmp;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the focused object or NULL if there isn't one
|
||||
* @param group pointer to a group
|
||||
* @return pointer to the focused object
|
||||
*/
|
||||
lv_obj_t * lv_group_get_focused(const lv_group_t * group)
|
||||
{
|
||||
if(!group) return NULL;
|
||||
if(group->obj_focus == NULL) return NULL;
|
||||
|
||||
return *group->obj_focus;
|
||||
}
|
||||
|
||||
#if LV_USE_USER_DATA
|
||||
/**
|
||||
* Get a pointer to the group's user data
|
||||
* @param group pointer to an group
|
||||
* @return pointer to the user data
|
||||
*/
|
||||
lv_group_user_data_t * lv_group_get_user_data(lv_group_t * group)
|
||||
{
|
||||
return &group->user_data;
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Get a the style modifier function of a group
|
||||
* @param group pointer to a group
|
||||
* @return pointer to the style modifier function
|
||||
*/
|
||||
lv_group_style_mod_cb_t lv_group_get_style_mod_cb(const lv_group_t * group)
|
||||
{
|
||||
if(!group) return false;
|
||||
return group->style_mod_cb;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a the style modifier function of a group in edit mode
|
||||
* @param group pointer to a group
|
||||
* @return pointer to the style modifier function
|
||||
*/
|
||||
lv_group_style_mod_cb_t lv_group_get_style_mod_edit_cb(const lv_group_t * group)
|
||||
{
|
||||
if(!group) return false;
|
||||
return group->style_mod_edit_cb;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the focus callback function of a group
|
||||
* @param group pointer to a group
|
||||
* @return the call back function or NULL if not set
|
||||
*/
|
||||
lv_group_focus_cb_t lv_group_get_focus_cb(const lv_group_t * group)
|
||||
{
|
||||
if(!group) return false;
|
||||
return group->focus_cb;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the current mode (edit or navigate).
|
||||
* @param group pointer to group
|
||||
* @return true: edit mode; false: navigate mode
|
||||
*/
|
||||
bool lv_group_get_editing(const lv_group_t * group)
|
||||
{
|
||||
if(!group) return false;
|
||||
return group->editing ? true : false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the `click_focus` attribute.
|
||||
* @param group pointer to group
|
||||
* @return true: `click_focus` is enabled; false: disabled
|
||||
*/
|
||||
bool lv_group_get_click_focus(const lv_group_t * group)
|
||||
{
|
||||
if(!group) return false;
|
||||
return group->click_focus ? true : false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get whether focus next/prev will allow wrapping from first->last or last->first object.
|
||||
* @param group pointer to group
|
||||
* @param en: true: wrapping enabled; false: wrapping disabled
|
||||
*/
|
||||
bool lv_group_get_wrap(lv_group_t * group)
|
||||
{
|
||||
if(!group) return false;
|
||||
return group->wrap ? true : false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Notify the group that current theme changed and style modification callbacks need to be
|
||||
* refreshed.
|
||||
* @param group pointer to group. If NULL then all groups are notified.
|
||||
*/
|
||||
void lv_group_report_style_mod(lv_group_t * group)
|
||||
{
|
||||
lv_theme_t * th = lv_theme_get_current();
|
||||
|
||||
if(group != NULL) {
|
||||
refresh_theme(group, th);
|
||||
return;
|
||||
}
|
||||
|
||||
lv_group_t * i;
|
||||
LV_LL_READ(LV_GC_ROOT(_lv_group_ll), i)
|
||||
{
|
||||
refresh_theme(i, th);
|
||||
}
|
||||
}
|
||||
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
|
||||
static void lv_group_refocus(lv_group_t * g)
|
||||
{
|
||||
/*Refocus must temporarily allow wrapping to work correctly*/
|
||||
uint8_t temp_wrap = g->wrap;
|
||||
g->wrap = 1;
|
||||
|
||||
if(g->refocus_policy == LV_GROUP_REFOCUS_POLICY_NEXT)
|
||||
lv_group_focus_next(g);
|
||||
else if(g->refocus_policy == LV_GROUP_REFOCUS_POLICY_PREV)
|
||||
lv_group_focus_prev(g);
|
||||
/*Restore wrap property*/
|
||||
g->wrap = temp_wrap;
|
||||
}
|
||||
|
||||
/**
|
||||
* Default style modifier function
|
||||
* @param group pointer to the caller group
|
||||
* @param style pointer to a style to modify. (Typically group.style_tmp) It will be OVERWRITTEN.
|
||||
*/
|
||||
static void style_mod_def(lv_group_t * group, lv_style_t * style)
|
||||
{
|
||||
(void)group; /*Unused*/
|
||||
#if LV_COLOR_DEPTH != 1
|
||||
|
||||
/*Make the style to be a little bit orange*/
|
||||
style->body.border.opa = LV_OPA_COVER;
|
||||
style->body.border.color = LV_COLOR_ORANGE;
|
||||
|
||||
/*If not transparent or has border then emphasis the border*/
|
||||
if(style->body.opa != LV_OPA_TRANSP || style->body.border.width != 0) style->body.border.width = LV_DPI / 20;
|
||||
|
||||
style->body.main_color = lv_color_mix(style->body.main_color, LV_COLOR_ORANGE, LV_OPA_70);
|
||||
style->body.grad_color = lv_color_mix(style->body.grad_color, LV_COLOR_ORANGE, LV_OPA_70);
|
||||
style->body.shadow.color = lv_color_mix(style->body.shadow.color, LV_COLOR_ORANGE, LV_OPA_60);
|
||||
|
||||
style->text.color = lv_color_mix(style->text.color, LV_COLOR_ORANGE, LV_OPA_70);
|
||||
|
||||
/*Add some recolor to the images*/
|
||||
if(style->image.intense < LV_OPA_MIN) {
|
||||
style->image.color = LV_COLOR_ORANGE;
|
||||
style->image.intense = LV_OPA_40;
|
||||
}
|
||||
#else
|
||||
style->body.border.opa = LV_OPA_COVER;
|
||||
style->body.border.color = LV_COLOR_BLACK;
|
||||
style->body.border.width = 2;
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* Default style modifier function
|
||||
* @param group pointer to the caller group
|
||||
* @param style pointer to a style to modify. (Typically group.style_tmp) It will be OVERWRITTEN.
|
||||
*/
|
||||
static void style_mod_edit_def(lv_group_t * group, lv_style_t * style)
|
||||
{
|
||||
(void)group; /*Unused*/
|
||||
#if LV_COLOR_DEPTH != 1
|
||||
|
||||
/*Make the style to be a little bit orange*/
|
||||
style->body.border.opa = LV_OPA_COVER;
|
||||
style->body.border.color = LV_COLOR_GREEN;
|
||||
|
||||
/*If not empty or has border then emphasis the border*/
|
||||
if(style->body.opa != LV_OPA_TRANSP || style->body.border.width != 0) style->body.border.width = LV_DPI / 20;
|
||||
|
||||
style->body.main_color = lv_color_mix(style->body.main_color, LV_COLOR_GREEN, LV_OPA_70);
|
||||
style->body.grad_color = lv_color_mix(style->body.grad_color, LV_COLOR_GREEN, LV_OPA_70);
|
||||
style->body.shadow.color = lv_color_mix(style->body.shadow.color, LV_COLOR_GREEN, LV_OPA_60);
|
||||
|
||||
style->text.color = lv_color_mix(style->text.color, LV_COLOR_GREEN, LV_OPA_70);
|
||||
|
||||
/*Add some recolor to the images*/
|
||||
if(style->image.intense < LV_OPA_MIN) {
|
||||
style->image.color = LV_COLOR_GREEN;
|
||||
style->image.intense = LV_OPA_40;
|
||||
}
|
||||
|
||||
#else
|
||||
style->body.border.opa = LV_OPA_COVER;
|
||||
style->body.border.color = LV_COLOR_BLACK;
|
||||
style->body.border.width = 3;
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
static void refresh_theme(lv_group_t * g, lv_theme_t * th)
|
||||
{
|
||||
g->style_mod_cb = style_mod_def;
|
||||
g->style_mod_edit_cb = style_mod_edit_def;
|
||||
if(th) {
|
||||
if(th->group.style_mod_xcb) g->style_mod_cb = th->group.style_mod_xcb;
|
||||
if(th->group.style_mod_edit_xcb) g->style_mod_edit_cb = th->group.style_mod_edit_xcb;
|
||||
}
|
||||
}
|
||||
|
||||
static void focus_next_core(lv_group_t * group, void * (*begin)(const lv_ll_t *),
|
||||
void * (*move)(const lv_ll_t *, const void *))
|
||||
{
|
||||
if(group->frozen) return;
|
||||
|
||||
lv_obj_t ** obj_next = group->obj_focus;
|
||||
lv_obj_t ** obj_sentinel = NULL;
|
||||
bool can_move = true;
|
||||
bool can_begin = true;
|
||||
|
||||
for(;;) {
|
||||
if(obj_next == NULL) {
|
||||
if(group->wrap || obj_sentinel == NULL) {
|
||||
if(!can_begin) return;
|
||||
obj_next = begin(&group->obj_ll);
|
||||
can_move = false;
|
||||
can_begin = false;
|
||||
} else {
|
||||
/*Currently focused object is the last/first in the group, keep it that way*/
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if(obj_sentinel == NULL) {
|
||||
obj_sentinel = obj_next;
|
||||
if(obj_sentinel == NULL) return; /*Group is empty*/
|
||||
}
|
||||
|
||||
if(can_move) {
|
||||
obj_next = move(&group->obj_ll, obj_next);
|
||||
|
||||
/*Give up if we walked the entire list and haven't found another visible object*/
|
||||
if(obj_next == obj_sentinel) return;
|
||||
}
|
||||
|
||||
can_move = true;
|
||||
|
||||
if(obj_next == NULL) continue;
|
||||
|
||||
/*Hidden objects don't receive focus*/
|
||||
if(!lv_obj_get_hidden(*obj_next)) break;
|
||||
}
|
||||
|
||||
if(obj_next == group->obj_focus) return; /*There's only one visible object and it's already focused*/
|
||||
|
||||
if(group->obj_focus) {
|
||||
(*group->obj_focus)->signal_cb(*group->obj_focus, LV_SIGNAL_DEFOCUS, NULL);
|
||||
lv_res_t res = lv_event_send(*group->obj_focus, LV_EVENT_DEFOCUSED, NULL);
|
||||
if(res != LV_RES_OK) return;
|
||||
lv_obj_invalidate(*group->obj_focus);
|
||||
}
|
||||
|
||||
group->obj_focus = obj_next;
|
||||
|
||||
(*group->obj_focus)->signal_cb(*group->obj_focus, LV_SIGNAL_FOCUS, NULL);
|
||||
lv_res_t res = lv_event_send(*group->obj_focus, LV_EVENT_FOCUSED, NULL);
|
||||
if(res != LV_RES_OK) return;
|
||||
|
||||
/*If the object or its parent has `top == true` bring it to the foregorund*/
|
||||
obj_to_foreground(*group->obj_focus);
|
||||
|
||||
lv_obj_invalidate(*group->obj_focus);
|
||||
|
||||
if(group->focus_cb) group->focus_cb(group);
|
||||
}
|
||||
|
||||
static void obj_to_foreground(lv_obj_t * obj)
|
||||
{
|
||||
/*Search for 'top' attribute*/
|
||||
lv_obj_t * i = obj;
|
||||
lv_obj_t * last_top = NULL;
|
||||
while(i != NULL) {
|
||||
if(i->top != 0) last_top = i;
|
||||
i = lv_obj_get_parent(i);
|
||||
}
|
||||
|
||||
if(last_top != NULL) {
|
||||
/*Move the last_top object to the foreground*/
|
||||
lv_obj_move_foreground(last_top);
|
||||
}
|
||||
}
|
||||
|
||||
#endif /*LV_USE_GROUP != 0*/
|
@ -1,293 +0,0 @@
|
||||
/**
|
||||
* @file lv_group.h
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LV_GROUP_H
|
||||
#define LV_GROUP_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#ifdef LV_CONF_INCLUDE_SIMPLE
|
||||
#include "lv_conf.h"
|
||||
#else
|
||||
#include "../../../lv_conf.h"
|
||||
#endif
|
||||
|
||||
#include "lv_obj.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
/*Predefined keys to control the focused object via lv_group_send(group, c)*/
|
||||
/*For compatibility in signal function define the keys regardless to `LV_USE_GROUP`*/
|
||||
|
||||
enum {
|
||||
LV_KEY_UP = 17, /*0x11*/
|
||||
LV_KEY_DOWN = 18, /*0x12*/
|
||||
LV_KEY_RIGHT = 19, /*0x13*/
|
||||
LV_KEY_LEFT = 20, /*0x14*/
|
||||
LV_KEY_ESC = 27, /*0x1B*/
|
||||
LV_KEY_DEL = 127, /*0x7F*/
|
||||
LV_KEY_BACKSPACE = 8, /*0x08*/
|
||||
LV_KEY_ENTER = 10, /*0x0A, '\n'*/
|
||||
LV_KEY_NEXT = 9, /*0x09, '\t'*/
|
||||
LV_KEY_PREV = 11, /*0x0B, '*/
|
||||
LV_KEY_HOME = 2, /*0x02, STX*/
|
||||
LV_KEY_END = 3, /*0x03, ETX*/
|
||||
};
|
||||
typedef uint8_t lv_key_t;
|
||||
|
||||
#if LV_USE_GROUP != 0
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
struct _lv_group_t;
|
||||
|
||||
typedef void (*lv_group_style_mod_cb_t)(struct _lv_group_t *, lv_style_t *);
|
||||
typedef void (*lv_group_focus_cb_t)(struct _lv_group_t *);
|
||||
|
||||
/**
|
||||
* Groups can be used to logically hold objects so that they can be individually focused.
|
||||
* They are NOT for laying out objects on a screen (try `lv_cont` for that).
|
||||
*/
|
||||
typedef struct _lv_group_t
|
||||
{
|
||||
lv_ll_t obj_ll; /**< Linked list to store the objects in the group */
|
||||
lv_obj_t ** obj_focus; /**< The object in focus*/
|
||||
|
||||
lv_group_style_mod_cb_t style_mod_cb; /**< A function to modifies the style of the focused object*/
|
||||
lv_group_style_mod_cb_t style_mod_edit_cb; /**< A function which modifies the style of the edited object*/
|
||||
lv_group_focus_cb_t focus_cb; /**< A function to call when a new object is focused (optional)*/
|
||||
lv_style_t style_tmp; /**< Stores the modified style of the focused object */
|
||||
#if LV_USE_USER_DATA
|
||||
lv_group_user_data_t user_data;
|
||||
#endif
|
||||
|
||||
uint8_t frozen : 1; /**< 1: can't focus to new object*/
|
||||
uint8_t editing : 1; /**< 1: Edit mode, 0: Navigate mode*/
|
||||
uint8_t click_focus : 1; /**< 1: If an object in a group is clicked by an indev then it will be
|
||||
focused */
|
||||
uint8_t refocus_policy : 1; /**< 1: Focus prev if focused on deletion. 0: Focus next if focused on
|
||||
deletion.*/
|
||||
uint8_t wrap : 1; /**< 1: Focus next/prev can wrap at end of list. 0: Focus next/prev stops at end
|
||||
of list.*/
|
||||
} lv_group_t;
|
||||
|
||||
enum { LV_GROUP_REFOCUS_POLICY_NEXT = 0, LV_GROUP_REFOCUS_POLICY_PREV = 1 };
|
||||
typedef uint8_t lv_group_refocus_policy_t;
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Init. the group module
|
||||
* @remarks Internal function, do not call directly.
|
||||
*/
|
||||
void lv_group_init(void);
|
||||
|
||||
/**
|
||||
* Create a new object group
|
||||
* @return pointer to the new object group
|
||||
*/
|
||||
lv_group_t * lv_group_create(void);
|
||||
|
||||
/**
|
||||
* Delete a group object
|
||||
* @param group pointer to a group
|
||||
*/
|
||||
void lv_group_del(lv_group_t * group);
|
||||
|
||||
/**
|
||||
* Add an object to a group
|
||||
* @param group pointer to a group
|
||||
* @param obj pointer to an object to add
|
||||
*/
|
||||
void lv_group_add_obj(lv_group_t * group, lv_obj_t * obj);
|
||||
|
||||
/**
|
||||
* Remove an object from its group
|
||||
* @param obj pointer to an object to remove
|
||||
*/
|
||||
void lv_group_remove_obj(lv_obj_t * obj);
|
||||
|
||||
/**
|
||||
* Remove all objects from a group
|
||||
* @param group pointer to a group
|
||||
*/
|
||||
void lv_group_remove_all_objs(lv_group_t * group);
|
||||
|
||||
/**
|
||||
* Focus on an object (defocus the current)
|
||||
* @param obj pointer to an object to focus on
|
||||
*/
|
||||
void lv_group_focus_obj(lv_obj_t * obj);
|
||||
|
||||
/**
|
||||
* Focus the next object in a group (defocus the current)
|
||||
* @param group pointer to a group
|
||||
*/
|
||||
void lv_group_focus_next(lv_group_t * group);
|
||||
|
||||
/**
|
||||
* Focus the previous object in a group (defocus the current)
|
||||
* @param group pointer to a group
|
||||
*/
|
||||
void lv_group_focus_prev(lv_group_t * group);
|
||||
|
||||
/**
|
||||
* Do not let to change the focus from the current object
|
||||
* @param group pointer to a group
|
||||
* @param en true: freeze, false: release freezing (normal mode)
|
||||
*/
|
||||
void lv_group_focus_freeze(lv_group_t * group, bool en);
|
||||
|
||||
/**
|
||||
* Send a control character to the focuses object of a group
|
||||
* @param group pointer to a group
|
||||
* @param c a character (use LV_KEY_.. to navigate)
|
||||
* @return result of focused object in group.
|
||||
*/
|
||||
lv_res_t lv_group_send_data(lv_group_t * group, uint32_t c);
|
||||
|
||||
/**
|
||||
* Set a function for a group which will modify the object's style if it is in focus
|
||||
* @param group pointer to a group
|
||||
* @param style_mod_cb the style modifier function pointer
|
||||
*/
|
||||
void lv_group_set_style_mod_cb(lv_group_t * group, lv_group_style_mod_cb_t style_mod_cb);
|
||||
|
||||
/**
|
||||
* Set a function for a group which will modify the object's style if it is in focus in edit mode
|
||||
* @param group pointer to a group
|
||||
* @param style_mod_edit_cb the style modifier function pointer
|
||||
*/
|
||||
void lv_group_set_style_mod_edit_cb(lv_group_t * group, lv_group_style_mod_cb_t style_mod_edit_cb);
|
||||
|
||||
/**
|
||||
* Set a function for a group which will be called when a new object is focused
|
||||
* @param group pointer to a group
|
||||
* @param focus_cb the call back function or NULL if unused
|
||||
*/
|
||||
void lv_group_set_focus_cb(lv_group_t * group, lv_group_focus_cb_t focus_cb);
|
||||
|
||||
/**
|
||||
* Set whether the next or previous item in a group is focused if the currently focussed obj is
|
||||
* deleted.
|
||||
* @param group pointer to a group
|
||||
* @param new refocus policy enum
|
||||
*/
|
||||
void lv_group_set_refocus_policy(lv_group_t * group, lv_group_refocus_policy_t policy);
|
||||
|
||||
/**
|
||||
* Manually set the current mode (edit or navigate).
|
||||
* @param group pointer to group
|
||||
* @param edit: true: edit mode; false: navigate mode
|
||||
*/
|
||||
void lv_group_set_editing(lv_group_t * group, bool edit);
|
||||
|
||||
/**
|
||||
* Set the `click_focus` attribute. If enabled then the object will be focused then it is clicked.
|
||||
* @param group pointer to group
|
||||
* @param en: true: enable `click_focus`
|
||||
*/
|
||||
void lv_group_set_click_focus(lv_group_t * group, bool en);
|
||||
|
||||
/**
|
||||
* Set whether focus next/prev will allow wrapping from first->last or last->first object.
|
||||
* @param group pointer to group
|
||||
* @param en: true: wrapping enabled; false: wrapping disabled
|
||||
*/
|
||||
void lv_group_set_wrap(lv_group_t * group, bool en);
|
||||
|
||||
/**
|
||||
* Modify a style with the set 'style_mod' function. The input style remains unchanged.
|
||||
* @param group pointer to group
|
||||
* @param style pointer to a style to modify
|
||||
* @return a copy of the input style but modified with the 'style_mod' function
|
||||
*/
|
||||
lv_style_t * lv_group_mod_style(lv_group_t * group, const lv_style_t * style);
|
||||
|
||||
/**
|
||||
* Get the focused object or NULL if there isn't one
|
||||
* @param group pointer to a group
|
||||
* @return pointer to the focused object
|
||||
*/
|
||||
lv_obj_t * lv_group_get_focused(const lv_group_t * group);
|
||||
|
||||
#if LV_USE_USER_DATA
|
||||
/**
|
||||
* Get a pointer to the group's user data
|
||||
* @param group pointer to an group
|
||||
* @return pointer to the user data
|
||||
*/
|
||||
lv_group_user_data_t * lv_group_get_user_data(lv_group_t * group);
|
||||
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Get a the style modifier function of a group
|
||||
* @param group pointer to a group
|
||||
* @return pointer to the style modifier function
|
||||
*/
|
||||
lv_group_style_mod_cb_t lv_group_get_style_mod_cb(const lv_group_t * group);
|
||||
|
||||
/**
|
||||
* Get a the style modifier function of a group in edit mode
|
||||
* @param group pointer to a group
|
||||
* @return pointer to the style modifier function
|
||||
*/
|
||||
lv_group_style_mod_cb_t lv_group_get_style_mod_edit_cb(const lv_group_t * group);
|
||||
|
||||
/**
|
||||
* Get the focus callback function of a group
|
||||
* @param group pointer to a group
|
||||
* @return the call back function or NULL if not set
|
||||
*/
|
||||
lv_group_focus_cb_t lv_group_get_focus_cb(const lv_group_t * group);
|
||||
|
||||
/**
|
||||
* Get the current mode (edit or navigate).
|
||||
* @param group pointer to group
|
||||
* @return true: edit mode; false: navigate mode
|
||||
*/
|
||||
bool lv_group_get_editing(const lv_group_t * group);
|
||||
|
||||
/**
|
||||
* Get the `click_focus` attribute.
|
||||
* @param group pointer to group
|
||||
* @return true: `click_focus` is enabled; false: disabled
|
||||
*/
|
||||
bool lv_group_get_click_focus(const lv_group_t * group);
|
||||
|
||||
/**
|
||||
* Get whether focus next/prev will allow wrapping from first->last or last->first object.
|
||||
* @param group pointer to group
|
||||
* @param en: true: wrapping enabled; false: wrapping disabled
|
||||
*/
|
||||
bool lv_group_get_wrap(lv_group_t * group);
|
||||
|
||||
/**
|
||||
* Notify the group that current theme changed and style modification callbacks need to be
|
||||
* refreshed.
|
||||
* @param group pointer to group. If NULL then all groups are notified.
|
||||
*/
|
||||
void lv_group_report_style_mod(lv_group_t * group);
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
#endif /*LV_USE_GROUP != 0*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif /*LV_GROUP_H*/
|
File diff suppressed because it is too large
Load Diff
@ -1,159 +0,0 @@
|
||||
/**
|
||||
* @file lv_indev.h
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LV_INDEV_H
|
||||
#define LV_INDEV_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "lv_obj.h"
|
||||
#include "../lv_hal/lv_hal_indev.h"
|
||||
#include "../lv_core/lv_group.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Initialize the display input device subsystem
|
||||
*/
|
||||
void lv_indev_init(void);
|
||||
|
||||
/**
|
||||
* Called periodically to read the input devices
|
||||
* @param task pointer to the task itself
|
||||
*/
|
||||
void lv_indev_read_task(lv_task_t * task);
|
||||
|
||||
/**
|
||||
* Get the currently processed input device. Can be used in action functions too.
|
||||
* @return pointer to the currently processed input device or NULL if no input device processing
|
||||
* right now
|
||||
*/
|
||||
lv_indev_t * lv_indev_get_act(void);
|
||||
|
||||
/**
|
||||
* Get the type of an input device
|
||||
* @param indev pointer to an input device
|
||||
* @return the type of the input device from `lv_hal_indev_type_t` (`LV_INDEV_TYPE_...`)
|
||||
*/
|
||||
lv_indev_type_t lv_indev_get_type(const lv_indev_t * indev);
|
||||
|
||||
/**
|
||||
* Reset one or all input devices
|
||||
* @param indev pointer to an input device to reset or NULL to reset all of them
|
||||
*/
|
||||
void lv_indev_reset(lv_indev_t * indev);
|
||||
|
||||
/**
|
||||
* Reset the long press state of an input device
|
||||
* @param indev_proc pointer to an input device
|
||||
*/
|
||||
void lv_indev_reset_long_press(lv_indev_t * indev);
|
||||
|
||||
/**
|
||||
* Enable or disable an input devices
|
||||
* @param indev pointer to an input device
|
||||
* @param en true: enable; false: disable
|
||||
*/
|
||||
void lv_indev_enable(lv_indev_t * indev, bool en);
|
||||
|
||||
/**
|
||||
* Set a cursor for a pointer input device (for LV_INPUT_TYPE_POINTER and LV_INPUT_TYPE_BUTTON)
|
||||
* @param indev pointer to an input device
|
||||
* @param cur_obj pointer to an object to be used as cursor
|
||||
*/
|
||||
void lv_indev_set_cursor(lv_indev_t * indev, lv_obj_t * cur_obj);
|
||||
|
||||
#if LV_USE_GROUP
|
||||
/**
|
||||
* Set a destination group for a keypad input device (for LV_INDEV_TYPE_KEYPAD)
|
||||
* @param indev pointer to an input device
|
||||
* @param group point to a group
|
||||
*/
|
||||
void lv_indev_set_group(lv_indev_t * indev, lv_group_t * group);
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Set the an array of points for LV_INDEV_TYPE_BUTTON.
|
||||
* These points will be assigned to the buttons to press a specific point on the screen
|
||||
* @param indev pointer to an input device
|
||||
* @param group point to a group
|
||||
*/
|
||||
void lv_indev_set_button_points(lv_indev_t * indev, const lv_point_t * points);
|
||||
|
||||
/**
|
||||
* Get the last point of an input device (for LV_INDEV_TYPE_POINTER and LV_INDEV_TYPE_BUTTON)
|
||||
* @param indev pointer to an input device
|
||||
* @param point pointer to a point to store the result
|
||||
*/
|
||||
void lv_indev_get_point(const lv_indev_t * indev, lv_point_t * point);
|
||||
|
||||
/**
|
||||
* Get the last pressed key of an input device (for LV_INDEV_TYPE_KEYPAD)
|
||||
* @param indev pointer to an input device
|
||||
* @return the last pressed key (0 on error)
|
||||
*/
|
||||
uint32_t lv_indev_get_key(const lv_indev_t * indev);
|
||||
|
||||
/**
|
||||
* Check if there is dragging with an input device or not (for LV_INDEV_TYPE_POINTER and
|
||||
* LV_INDEV_TYPE_BUTTON)
|
||||
* @param indev pointer to an input device
|
||||
* @return true: drag is in progress
|
||||
*/
|
||||
bool lv_indev_is_dragging(const lv_indev_t * indev);
|
||||
|
||||
/**
|
||||
* Get the vector of dragging of an input device (for LV_INDEV_TYPE_POINTER and
|
||||
* LV_INDEV_TYPE_BUTTON)
|
||||
* @param indev pointer to an input device
|
||||
* @param point pointer to a point to store the vector
|
||||
*/
|
||||
void lv_indev_get_vect(const lv_indev_t * indev, lv_point_t * point);
|
||||
|
||||
/**
|
||||
* Do nothing until the next release
|
||||
* @param indev pointer to an input device
|
||||
*/
|
||||
void lv_indev_wait_release(lv_indev_t * indev);
|
||||
|
||||
/**
|
||||
* Get a pointer to the indev read task to
|
||||
* modify its parameters with `lv_task_...` functions.
|
||||
* @param indev pointer to an inout device
|
||||
* @return pointer to the indev read refresher task. (NULL on error)
|
||||
*/
|
||||
lv_task_t * lv_indev_get_read_task(lv_disp_t * indev);
|
||||
|
||||
/**
|
||||
* Gets a pointer to the currently active object in indev proc functions.
|
||||
* NULL if no object is currently being handled or if groups aren't used.
|
||||
* @return pointer to currently active object
|
||||
*/
|
||||
lv_obj_t * lv_indev_get_obj_act(void);
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif /*LV_INDEV_H*/
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -1,612 +0,0 @@
|
||||
/**
|
||||
* @file lv_refr.c
|
||||
*
|
||||
*/
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include <stddef.h>
|
||||
#include "lv_refr.h"
|
||||
#include "lv_disp.h"
|
||||
#include "../lv_hal/lv_hal_tick.h"
|
||||
#include "../lv_hal/lv_hal_disp.h"
|
||||
#include "../lv_misc/lv_task.h"
|
||||
#include "../lv_misc/lv_mem.h"
|
||||
#include "../lv_misc/lv_gc.h"
|
||||
#include "../lv_draw/lv_draw.h"
|
||||
|
||||
#if defined(LV_GC_INCLUDE)
|
||||
#include LV_GC_INCLUDE
|
||||
#endif /* LV_ENABLE_GC */
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
/* Draw translucent random colored areas on the invalidated (redrawn) areas*/
|
||||
#define MASK_AREA_DEBUG 0
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
static void lv_refr_join_area(void);
|
||||
static void lv_refr_areas(void);
|
||||
static void lv_refr_area(const lv_area_t * area_p);
|
||||
static void lv_refr_area_part(const lv_area_t * area_p);
|
||||
static lv_obj_t * lv_refr_get_top_obj(const lv_area_t * area_p, lv_obj_t * obj);
|
||||
static void lv_refr_obj_and_children(lv_obj_t * top_p, const lv_area_t * mask_p);
|
||||
static void lv_refr_obj(lv_obj_t * obj, const lv_area_t * mask_ori_p);
|
||||
static void lv_refr_vdb_flush(void);
|
||||
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
**********************/
|
||||
static uint32_t px_num;
|
||||
static lv_disp_t * disp_refr; /*Display being refreshed*/
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL FUNCTIONS
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Initialize the screen refresh subsystem
|
||||
*/
|
||||
void lv_refr_init(void)
|
||||
{
|
||||
/*Nothing to do*/
|
||||
}
|
||||
|
||||
/**
|
||||
* Redraw the invalidated areas now.
|
||||
* Normally the redrawing is periodically executed in `lv_task_handler` but a long blocking process
|
||||
* can prevent the call of `lv_task_handler`. In this case if the the GUI is updated in the process
|
||||
* (e.g. progress bar) this function can be called when the screen should be updated.
|
||||
* @param disp pointer to display to refresh. NULL to refresh all displays.
|
||||
*/
|
||||
void lv_refr_now(lv_disp_t * disp)
|
||||
{
|
||||
if(disp) {
|
||||
lv_disp_refr_task(disp->refr_task);
|
||||
} else {
|
||||
lv_disp_t * d;
|
||||
d = lv_disp_get_next(NULL);
|
||||
while(d) {
|
||||
lv_disp_refr_task(d->refr_task);
|
||||
d = lv_disp_get_next(d);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Invalidate an area on display to redraw it
|
||||
* @param area_p pointer to area which should be invalidated (NULL: delete the invalidated areas)
|
||||
* @param disp pointer to display where the area should be invalidated (NULL can be used if there is
|
||||
* only one display)
|
||||
*/
|
||||
void lv_inv_area(lv_disp_t * disp, const lv_area_t * area_p)
|
||||
{
|
||||
if(!disp) disp = lv_disp_get_default();
|
||||
if(!disp) return;
|
||||
|
||||
/*Clear the invalidate buffer if the parameter is NULL*/
|
||||
if(area_p == NULL) {
|
||||
disp->inv_p = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
lv_area_t scr_area;
|
||||
scr_area.x1 = 0;
|
||||
scr_area.y1 = 0;
|
||||
scr_area.x2 = lv_disp_get_hor_res(disp) - 1;
|
||||
scr_area.y2 = lv_disp_get_ver_res(disp) - 1;
|
||||
|
||||
lv_area_t com_area;
|
||||
bool suc;
|
||||
|
||||
suc = lv_area_intersect(&com_area, area_p, &scr_area);
|
||||
|
||||
/*The area is truncated to the screen*/
|
||||
if(suc != false) {
|
||||
if(disp->driver.rounder_cb) disp->driver.rounder_cb(&disp->driver, &com_area);
|
||||
|
||||
/*Save only if this area is not in one of the saved areas*/
|
||||
uint16_t i;
|
||||
for(i = 0; i < disp->inv_p; i++) {
|
||||
if(lv_area_is_in(&com_area, &disp->inv_areas[i]) != false) return;
|
||||
}
|
||||
|
||||
/*Save the area*/
|
||||
if(disp->inv_p < LV_INV_BUF_SIZE) {
|
||||
lv_area_copy(&disp->inv_areas[disp->inv_p], &com_area);
|
||||
} else { /*If no place for the area add the screen*/
|
||||
disp->inv_p = 0;
|
||||
lv_area_copy(&disp->inv_areas[disp->inv_p], &scr_area);
|
||||
}
|
||||
disp->inv_p++;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the display which is being refreshed
|
||||
* @return the display being refreshed
|
||||
*/
|
||||
lv_disp_t * lv_refr_get_disp_refreshing(void)
|
||||
{
|
||||
return disp_refr;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the display which is being refreshed.
|
||||
* It shouldn1t be used directly by the user.
|
||||
* It can be used to trick the drawing functions about there is an active display.
|
||||
* @param the display being refreshed
|
||||
*/
|
||||
void lv_refr_set_disp_refreshing(lv_disp_t * disp)
|
||||
{
|
||||
disp_refr = disp;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called periodically to handle the refreshing
|
||||
* @param task pointer to the task itself
|
||||
*/
|
||||
void lv_disp_refr_task(lv_task_t * task)
|
||||
{
|
||||
LV_LOG_TRACE("lv_refr_task: started");
|
||||
|
||||
uint32_t start = lv_tick_get();
|
||||
|
||||
disp_refr = task->user_data;
|
||||
|
||||
lv_refr_join_area();
|
||||
|
||||
lv_refr_areas();
|
||||
|
||||
/*If refresh happened ...*/
|
||||
if(disp_refr->inv_p != 0) {
|
||||
/*In true double buffered mode copy the refreshed areas to the new VDB to keep it up to
|
||||
* date*/
|
||||
if(lv_disp_is_true_double_buf(disp_refr)) {
|
||||
lv_disp_buf_t * vdb = lv_disp_get_buf(disp_refr);
|
||||
|
||||
/*Flush the content of the VDB*/
|
||||
lv_refr_vdb_flush();
|
||||
|
||||
/* With true double buffering the flushing should be only the address change of the
|
||||
* current frame buffer. Wait until the address change is ready and copy the changed
|
||||
* content to the other frame buffer (new active VDB) to keep the buffers synchronized*/
|
||||
while(vdb->flushing)
|
||||
;
|
||||
|
||||
uint8_t * buf_act = (uint8_t *)vdb->buf_act;
|
||||
uint8_t * buf_ina = (uint8_t *)vdb->buf_act == vdb->buf1 ? vdb->buf2 : vdb->buf1;
|
||||
|
||||
lv_coord_t hres = lv_disp_get_hor_res(disp_refr);
|
||||
uint16_t a;
|
||||
for(a = 0; a < disp_refr->inv_p; a++) {
|
||||
if(disp_refr->inv_area_joined[a] == 0) {
|
||||
lv_coord_t y;
|
||||
uint32_t start_offs =
|
||||
(hres * disp_refr->inv_areas[a].y1 + disp_refr->inv_areas[a].x1) * sizeof(lv_color_t);
|
||||
uint32_t line_length = lv_area_get_width(&disp_refr->inv_areas[a]) * sizeof(lv_color_t);
|
||||
|
||||
for(y = disp_refr->inv_areas[a].y1; y <= disp_refr->inv_areas[a].y2; y++) {
|
||||
memcpy(buf_act + start_offs, buf_ina + start_offs, line_length);
|
||||
start_offs += hres * sizeof(lv_color_t);
|
||||
}
|
||||
}
|
||||
}
|
||||
} /*End of true double buffer handling*/
|
||||
|
||||
/*Clean up*/
|
||||
memset(disp_refr->inv_areas, 0, sizeof(disp_refr->inv_areas));
|
||||
memset(disp_refr->inv_area_joined, 0, sizeof(disp_refr->inv_area_joined));
|
||||
disp_refr->inv_p = 0;
|
||||
|
||||
/*Call monitor cb if present*/
|
||||
if(disp_refr->driver.monitor_cb) {
|
||||
disp_refr->driver.monitor_cb(&disp_refr->driver, lv_tick_elaps(start), px_num);
|
||||
}
|
||||
}
|
||||
|
||||
lv_draw_free_buf();
|
||||
|
||||
LV_LOG_TRACE("lv_refr_task: ready");
|
||||
}
|
||||
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Join the areas which has got common parts
|
||||
*/
|
||||
static void lv_refr_join_area(void)
|
||||
{
|
||||
uint32_t join_from;
|
||||
uint32_t join_in;
|
||||
lv_area_t joined_area;
|
||||
for(join_in = 0; join_in < disp_refr->inv_p; join_in++) {
|
||||
if(disp_refr->inv_area_joined[join_in] != 0) continue;
|
||||
|
||||
/*Check all areas to join them in 'join_in'*/
|
||||
for(join_from = 0; join_from < disp_refr->inv_p; join_from++) {
|
||||
/*Handle only unjoined areas and ignore itself*/
|
||||
if(disp_refr->inv_area_joined[join_from] != 0 || join_in == join_from) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/*Check if the areas are on each other*/
|
||||
if(lv_area_is_on(&disp_refr->inv_areas[join_in], &disp_refr->inv_areas[join_from]) == false) {
|
||||
continue;
|
||||
}
|
||||
|
||||
lv_area_join(&joined_area, &disp_refr->inv_areas[join_in], &disp_refr->inv_areas[join_from]);
|
||||
|
||||
/*Join two area only if the joined area size is smaller*/
|
||||
if(lv_area_get_size(&joined_area) < (lv_area_get_size(&disp_refr->inv_areas[join_in]) +
|
||||
lv_area_get_size(&disp_refr->inv_areas[join_from]))) {
|
||||
lv_area_copy(&disp_refr->inv_areas[join_in], &joined_area);
|
||||
|
||||
/*Mark 'join_form' is joined into 'join_in'*/
|
||||
disp_refr->inv_area_joined[join_from] = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Refresh the joined areas
|
||||
*/
|
||||
static void lv_refr_areas(void)
|
||||
{
|
||||
px_num = 0;
|
||||
uint32_t i;
|
||||
|
||||
for(i = 0; i < disp_refr->inv_p; i++) {
|
||||
/*Refresh the unjoined areas*/
|
||||
if(disp_refr->inv_area_joined[i] == 0) {
|
||||
|
||||
lv_refr_area(&disp_refr->inv_areas[i]);
|
||||
|
||||
if(disp_refr->driver.monitor_cb) px_num += lv_area_get_size(&disp_refr->inv_areas[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Refresh an area if there is Virtual Display Buffer
|
||||
* @param area_p pointer to an area to refresh
|
||||
*/
|
||||
static void lv_refr_area(const lv_area_t * area_p)
|
||||
{
|
||||
/*True double buffering: there are two screen sized buffers. Just redraw directly into a
|
||||
* buffer*/
|
||||
if(lv_disp_is_true_double_buf(disp_refr)) {
|
||||
lv_disp_buf_t * vdb = lv_disp_get_buf(disp_refr);
|
||||
vdb->area.x1 = 0;
|
||||
vdb->area.x2 = lv_disp_get_hor_res(disp_refr) - 1;
|
||||
vdb->area.y1 = 0;
|
||||
vdb->area.y2 = lv_disp_get_ver_res(disp_refr) - 1;
|
||||
lv_refr_area_part(area_p);
|
||||
}
|
||||
/*The buffer is smaller: refresh the area in parts*/
|
||||
else {
|
||||
lv_disp_buf_t * vdb = lv_disp_get_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) ? y2 = lv_disp_get_ver_res(disp_refr) - 1 : area_p->y2;
|
||||
|
||||
int32_t max_row = (uint32_t)vdb->size / w;
|
||||
|
||||
if(max_row > h) max_row = h;
|
||||
|
||||
/*Round down the lines of VDB 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);
|
||||
|
||||
/*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);
|
||||
|
||||
if(h_tmp <= 0) {
|
||||
LV_LOG_WARN("Can't set VDB height using the round function. (Wrong round_cb or to "
|
||||
"small VDB)");
|
||||
return;
|
||||
} else {
|
||||
max_row = tmp.y2 + 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (disp_refr->render_direction) {
|
||||
/*Always use the full row*/
|
||||
lv_coord_t row;
|
||||
lv_coord_t row_last = y2;
|
||||
for(row = area_p->y2; row > max_row - 1 + area_p->y1; row -= max_row) {
|
||||
/*Calc. the next y coordinates of VDB*/
|
||||
vdb->area.x1 = area_p->x1;
|
||||
vdb->area.x2 = area_p->x2;
|
||||
vdb->area.y1 = row - max_row + 1;
|
||||
vdb->area.y2 = row;
|
||||
if(vdb->area.y2 > y2) vdb->area.y2 = y2;
|
||||
row_last = vdb->area.y1;
|
||||
lv_refr_area_part(area_p);
|
||||
}
|
||||
|
||||
/*If the last (first) y coordinates are not handled yet ...*/
|
||||
if(area_p->y1 != row_last) {
|
||||
/*Calc. the next y coordinates of VDB*/
|
||||
vdb->area.x1 = area_p->x1;
|
||||
vdb->area.x2 = area_p->x2;
|
||||
vdb->area.y1 = area_p->y1;
|
||||
vdb->area.y2 = row;
|
||||
|
||||
/*Refresh this part too*/
|
||||
lv_refr_area_part(area_p);
|
||||
}
|
||||
}
|
||||
else {
|
||||
/*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 VDB*/
|
||||
vdb->area.x1 = area_p->x1;
|
||||
vdb->area.x2 = area_p->x2;
|
||||
vdb->area.y1 = row;
|
||||
vdb->area.y2 = row + max_row - 1;
|
||||
if(vdb->area.y2 > y2) vdb->area.y2 = y2;
|
||||
row_last = vdb->area.y2;
|
||||
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 VDB*/
|
||||
vdb->area.x1 = area_p->x1;
|
||||
vdb->area.x2 = area_p->x2;
|
||||
vdb->area.y1 = row;
|
||||
vdb->area.y2 = y2;
|
||||
|
||||
/*Refresh this part too*/
|
||||
lv_refr_area_part(area_p);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Refresh a part of an area which is on the actual Virtual Display Buffer
|
||||
* @param area_p pointer to an area to refresh
|
||||
*/
|
||||
static void lv_refr_area_part(const lv_area_t * area_p)
|
||||
{
|
||||
|
||||
lv_disp_buf_t * vdb = lv_disp_get_buf(disp_refr);
|
||||
|
||||
/*In non double buffered mode, before rendering the next part wait until the previous image is
|
||||
* flushed*/
|
||||
if(lv_disp_is_double_buf(disp_refr) == false) {
|
||||
while(vdb->flushing)
|
||||
;
|
||||
}
|
||||
|
||||
lv_obj_t * top_p;
|
||||
|
||||
/*Get the new mask from the original area and the act. VDB
|
||||
It will be a part of 'area_p'*/
|
||||
lv_area_t start_mask;
|
||||
lv_area_intersect(&start_mask, area_p, &vdb->area);
|
||||
|
||||
/*Get the most top object which is not covered by others*/
|
||||
top_p = lv_refr_get_top_obj(&start_mask, lv_disp_get_scr_act(disp_refr));
|
||||
|
||||
/*Do the refreshing from the top object*/
|
||||
lv_refr_obj_and_children(top_p, &start_mask);
|
||||
|
||||
/*Also refresh top and sys layer unconditionally*/
|
||||
lv_refr_obj_and_children(lv_disp_get_layer_top(disp_refr), &start_mask);
|
||||
lv_refr_obj_and_children(lv_disp_get_layer_sys(disp_refr), &start_mask);
|
||||
|
||||
/* In true double buffered mode flush only once when all areas were rendered.
|
||||
* In normal mode flush after every area */
|
||||
if(lv_disp_is_true_double_buf(disp_refr) == false) {
|
||||
lv_refr_vdb_flush();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Search the most top object which fully covers an area
|
||||
* @param area_p pointer to an area
|
||||
* @param obj the first object to start the searching (typically a screen)
|
||||
* @return
|
||||
*/
|
||||
static lv_obj_t * lv_refr_get_top_obj(const lv_area_t * area_p, lv_obj_t * obj)
|
||||
{
|
||||
lv_obj_t * found_p = NULL;
|
||||
|
||||
/*If this object is fully cover the draw area check the children too */
|
||||
if(lv_area_is_in(area_p, &obj->coords) && obj->hidden == 0) {
|
||||
lv_obj_t * i;
|
||||
LV_LL_READ(obj->child_ll, i)
|
||||
{
|
||||
found_p = lv_refr_get_top_obj(area_p, i);
|
||||
|
||||
/*If a children is ok then break*/
|
||||
if(found_p != NULL) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*If no better children check this object*/
|
||||
if(found_p == NULL) {
|
||||
const lv_style_t * style = lv_obj_get_style(obj);
|
||||
if(style->body.opa == LV_OPA_COVER && obj->design_cb(obj, area_p, LV_DESIGN_COVER_CHK) != false &&
|
||||
lv_obj_get_opa_scale(obj) == LV_OPA_COVER) {
|
||||
found_p = obj;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return found_p;
|
||||
}
|
||||
|
||||
/**
|
||||
* Make the refreshing from an object. Draw all its children and the youngers too.
|
||||
* @param top_p pointer to an objects. Start the drawing from it.
|
||||
* @param mask_p pointer to an area, the objects will be drawn only here
|
||||
*/
|
||||
static void lv_refr_obj_and_children(lv_obj_t * top_p, const lv_area_t * mask_p)
|
||||
{
|
||||
/* Normally always will be a top_obj (at least the screen)
|
||||
* but in special cases (e.g. if the screen has alpha) it won't.
|
||||
* In this case use the screen directly */
|
||||
if(top_p == NULL) top_p = lv_disp_get_scr_act(disp_refr);
|
||||
|
||||
/*Refresh the top object and its children*/
|
||||
lv_refr_obj(top_p, mask_p);
|
||||
|
||||
/*Draw the 'younger' sibling objects because they can be on top_obj */
|
||||
lv_obj_t * par;
|
||||
lv_obj_t * border_p = top_p;
|
||||
|
||||
par = lv_obj_get_parent(top_p);
|
||||
|
||||
/*Do until not reach the screen*/
|
||||
while(par != NULL) {
|
||||
/*object before border_p has to be redrawn*/
|
||||
lv_obj_t * i = lv_ll_get_prev(&(par->child_ll), border_p);
|
||||
|
||||
while(i != NULL) {
|
||||
/*Refresh the objects*/
|
||||
lv_refr_obj(i, mask_p);
|
||||
i = lv_ll_get_prev(&(par->child_ll), i);
|
||||
}
|
||||
|
||||
/*Call the post draw design function of the parents of the to object*/
|
||||
par->design_cb(par, mask_p, LV_DESIGN_DRAW_POST);
|
||||
|
||||
/*The new border will be there last parents,
|
||||
*so the 'younger' brothers of parent will be refreshed*/
|
||||
border_p = par;
|
||||
/*Go a level deeper*/
|
||||
par = lv_obj_get_parent(par);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Refresh an object an all of its children. (Called recursively)
|
||||
* @param obj pointer to an object to refresh
|
||||
* @param mask_ori_p pointer to an area, the objects will be drawn only here
|
||||
*/
|
||||
static void lv_refr_obj(lv_obj_t * obj, const lv_area_t * mask_ori_p)
|
||||
{
|
||||
/*Do not refresh hidden objects*/
|
||||
if(obj->hidden != 0) return;
|
||||
|
||||
bool union_ok; /* Store the return value of area_union */
|
||||
/* Truncate the original mask to the coordinates of the parent
|
||||
* because the parent and its children are visible only here */
|
||||
lv_area_t obj_mask;
|
||||
lv_area_t obj_ext_mask;
|
||||
lv_area_t obj_area;
|
||||
lv_coord_t ext_size = obj->ext_draw_pad;
|
||||
lv_obj_get_coords(obj, &obj_area);
|
||||
obj_area.x1 -= ext_size;
|
||||
obj_area.y1 -= ext_size;
|
||||
obj_area.x2 += ext_size;
|
||||
obj_area.y2 += ext_size;
|
||||
union_ok = lv_area_intersect(&obj_ext_mask, mask_ori_p, &obj_area);
|
||||
|
||||
/*Draw the parent and its children only if they ore on 'mask_parent'*/
|
||||
if(union_ok != false) {
|
||||
|
||||
/* Redraw the object */
|
||||
obj->design_cb(obj, &obj_ext_mask, LV_DESIGN_DRAW_MAIN);
|
||||
|
||||
#if MASK_AREA_DEBUG
|
||||
static lv_color_t debug_color = LV_COLOR_RED;
|
||||
lv_draw_fill(&obj_ext_mask, &obj_ext_mask, debug_color, LV_OPA_50);
|
||||
debug_color.full *= 17;
|
||||
debug_color.full += 0xA1;
|
||||
#endif
|
||||
/*Create a new 'obj_mask' without 'ext_size' because the children can't be visible there*/
|
||||
lv_obj_get_coords(obj, &obj_area);
|
||||
union_ok = lv_area_intersect(&obj_mask, mask_ori_p, &obj_area);
|
||||
if(union_ok != false) {
|
||||
lv_area_t mask_child; /*Mask from obj and its child*/
|
||||
lv_obj_t * child_p;
|
||||
lv_area_t child_area;
|
||||
LV_LL_READ_BACK(obj->child_ll, child_p)
|
||||
{
|
||||
lv_obj_get_coords(child_p, &child_area);
|
||||
ext_size = child_p->ext_draw_pad;
|
||||
child_area.x1 -= ext_size;
|
||||
child_area.y1 -= ext_size;
|
||||
child_area.x2 += ext_size;
|
||||
child_area.y2 += ext_size;
|
||||
/* Get the union (common parts) of original mask (from obj)
|
||||
* and its child */
|
||||
union_ok = lv_area_intersect(&mask_child, &obj_mask, &child_area);
|
||||
|
||||
/*If the parent and the child has common area then refresh the child */
|
||||
if(union_ok) {
|
||||
/*Refresh the next children*/
|
||||
lv_refr_obj(child_p, &mask_child);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* If all the children are redrawn make 'post draw' design */
|
||||
obj->design_cb(obj, &obj_ext_mask, LV_DESIGN_DRAW_POST);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Flush the content of the VDB
|
||||
*/
|
||||
static void lv_refr_vdb_flush(void)
|
||||
{
|
||||
lv_disp_buf_t * vdb = lv_disp_get_buf(disp_refr);
|
||||
|
||||
/*In double buffered mode wait until the other buffer is flushed before flushing the current
|
||||
* one*/
|
||||
if(lv_disp_is_double_buf(disp_refr)) {
|
||||
while(vdb->flushing)
|
||||
;
|
||||
}
|
||||
|
||||
vdb->flushing = 1;
|
||||
|
||||
/*Flush the rendered content to the display*/
|
||||
lv_disp_t * disp = lv_refr_get_disp_refreshing();
|
||||
if(disp->driver.flush_cb) disp->driver.flush_cb(&disp->driver, &vdb->area, vdb->buf_act);
|
||||
|
||||
if(vdb->buf1 && vdb->buf2) {
|
||||
if(vdb->buf_act == vdb->buf1)
|
||||
vdb->buf_act = vdb->buf2;
|
||||
else
|
||||
vdb->buf_act = vdb->buf1;
|
||||
}
|
||||
}
|
@ -1,93 +0,0 @@
|
||||
/**
|
||||
* @file lv_refr.h
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LV_REFR_H
|
||||
#define LV_REFR_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "lv_obj.h"
|
||||
#include <stdbool.h>
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL FUNCTIONS
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Initialize the screen refresh subsystem
|
||||
*/
|
||||
void lv_refr_init(void);
|
||||
|
||||
/**
|
||||
* Redraw the invalidated areas now.
|
||||
* Normally the redrawing is periodically executed in `lv_task_handler` but a long blocking process
|
||||
* can prevent the call of `lv_task_handler`. In this case if the the GUI is updated in the process
|
||||
* (e.g. progress bar) this function can be called when the screen should be updated.
|
||||
* @param disp pointer to display to refresh. NULL to refresh all displays.
|
||||
*/
|
||||
void lv_refr_now(lv_disp_t * disp);
|
||||
|
||||
/**
|
||||
* Invalidate an area on display to redraw it
|
||||
* @param area_p pointer to area which should be invalidated (NULL: delete the invalidated areas)
|
||||
* @param disp pointer to display where the area should be invalidated (NULL can be used if there is
|
||||
* only one display)
|
||||
*/
|
||||
void lv_inv_area(lv_disp_t * disp, const lv_area_t * area_p);
|
||||
|
||||
/**
|
||||
* Get the display which is being refreshed
|
||||
* @return the display being refreshed
|
||||
*/
|
||||
lv_disp_t * lv_refr_get_disp_refreshing(void);
|
||||
|
||||
/**
|
||||
* Set the display which is being refreshed.
|
||||
* It shouldn1t be used directly by the user.
|
||||
* It can be used to trick the drawing functions about there is an active display.
|
||||
* @param the display being refreshed
|
||||
*/
|
||||
void lv_refr_set_disp_refreshing(lv_disp_t * disp);
|
||||
|
||||
/**
|
||||
* Called periodically to handle the refreshing
|
||||
* @param task pointer to the task itself
|
||||
*/
|
||||
void lv_disp_refr_task(lv_task_t * task);
|
||||
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif /*LV_REFR_H*/
|
@ -1,353 +0,0 @@
|
||||
/**
|
||||
* @file lv_style.c
|
||||
*
|
||||
*/
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "lv_obj.h"
|
||||
#include "../lv_core/lv_debug.h"
|
||||
#include "../lv_misc/lv_mem.h"
|
||||
#include "../lv_misc/lv_anim.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
#define STYLE_MIX_MAX 256
|
||||
#define STYLE_MIX_SHIFT 8 /*log2(STYLE_MIX_MAX)*/
|
||||
|
||||
#define VAL_PROP(v1, v2, r) v1 + (((v2 - v1) * r) >> STYLE_MIX_SHIFT)
|
||||
#define STYLE_ATTR_MIX(attr, r) \
|
||||
if(start->attr != end->attr) { \
|
||||
res->attr = VAL_PROP(start->attr, end->attr, r); \
|
||||
} else { \
|
||||
res->attr = start->attr; \
|
||||
}
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
#if LV_USE_ANIMATION
|
||||
static void style_animator(lv_style_anim_dsc_t * dsc, lv_anim_value_t val);
|
||||
static void style_animation_common_end_cb(lv_anim_t * a);
|
||||
#endif
|
||||
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
**********************/
|
||||
lv_style_t lv_style_scr;
|
||||
lv_style_t lv_style_transp;
|
||||
lv_style_t lv_style_transp_fit;
|
||||
lv_style_t lv_style_transp_tight;
|
||||
lv_style_t lv_style_plain;
|
||||
lv_style_t lv_style_plain_color;
|
||||
lv_style_t lv_style_pretty;
|
||||
lv_style_t lv_style_pretty_color;
|
||||
lv_style_t lv_style_btn_rel;
|
||||
lv_style_t lv_style_btn_pr;
|
||||
lv_style_t lv_style_btn_tgl_rel;
|
||||
lv_style_t lv_style_btn_tgl_pr;
|
||||
lv_style_t lv_style_btn_ina;
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL FUNCTIONS
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Init the basic styles
|
||||
*/
|
||||
void lv_style_init(void)
|
||||
{
|
||||
/* Not White/Black/Gray colors are created by HSV model with
|
||||
* HUE = 210*/
|
||||
|
||||
/*Screen style*/
|
||||
lv_style_scr.glass = 0;
|
||||
lv_style_scr.body.opa = LV_OPA_COVER;
|
||||
lv_style_scr.body.main_color = LV_COLOR_WHITE;
|
||||
lv_style_scr.body.grad_color = LV_COLOR_WHITE;
|
||||
lv_style_scr.body.radius = 0;
|
||||
lv_style_scr.body.padding.left = 0;
|
||||
lv_style_scr.body.padding.right = 0;
|
||||
lv_style_scr.body.padding.top = 0;
|
||||
lv_style_scr.body.padding.bottom = 0;
|
||||
lv_style_scr.body.padding.inner = LV_DPI / 20;
|
||||
|
||||
lv_style_scr.body.border.color = LV_COLOR_BLACK;
|
||||
lv_style_scr.body.border.opa = LV_OPA_COVER;
|
||||
lv_style_scr.body.border.width = 0;
|
||||
lv_style_scr.body.border.part = LV_BORDER_FULL;
|
||||
|
||||
lv_style_scr.body.shadow.color = LV_COLOR_GRAY;
|
||||
lv_style_scr.body.shadow.type = LV_SHADOW_FULL;
|
||||
lv_style_scr.body.shadow.width = 0;
|
||||
|
||||
lv_style_scr.text.opa = LV_OPA_COVER;
|
||||
lv_style_scr.text.color = lv_color_make(0x30, 0x30, 0x30);
|
||||
lv_style_scr.text.sel_color = lv_color_make(0x55, 0x96, 0xd8);
|
||||
lv_style_scr.text.font = LV_FONT_DEFAULT;
|
||||
lv_style_scr.text.letter_space = 0;
|
||||
lv_style_scr.text.line_space = 2;
|
||||
|
||||
lv_style_scr.image.opa = LV_OPA_COVER;
|
||||
lv_style_scr.image.color = lv_color_make(0x20, 0x20, 0x20);
|
||||
lv_style_scr.image.intense = LV_OPA_TRANSP;
|
||||
|
||||
lv_style_scr.line.opa = LV_OPA_COVER;
|
||||
lv_style_scr.line.color = lv_color_make(0x20, 0x20, 0x20);
|
||||
lv_style_scr.line.width = 2;
|
||||
lv_style_scr.line.rounded = 0;
|
||||
|
||||
#if LV_USE_DEBUG
|
||||
#if LV_USE_ASSERT_STYLE
|
||||
lv_style_scr.debug_sentinel = LV_STYLE_DEGUG_SENTINEL_VALUE;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/*Plain style (by default near the same as the screen style)*/
|
||||
lv_style_copy(&lv_style_plain, &lv_style_scr);
|
||||
lv_style_plain.body.padding.left = LV_DPI / 20;
|
||||
lv_style_plain.body.padding.right = LV_DPI / 20;
|
||||
lv_style_plain.body.padding.top = LV_DPI / 20;
|
||||
lv_style_plain.body.padding.bottom = LV_DPI / 20;
|
||||
|
||||
/*Plain color style*/
|
||||
lv_style_copy(&lv_style_plain_color, &lv_style_plain);
|
||||
lv_style_plain_color.text.color = lv_color_make(0xf0, 0xf0, 0xf0);
|
||||
lv_style_plain_color.image.color = lv_color_make(0xf0, 0xf0, 0xf0);
|
||||
lv_style_plain_color.line.color = lv_color_make(0xf0, 0xf0, 0xf0);
|
||||
lv_style_plain_color.body.main_color = lv_color_make(0x55, 0x96, 0xd8);
|
||||
lv_style_plain_color.body.grad_color = lv_style_plain_color.body.main_color;
|
||||
|
||||
/*Pretty style */
|
||||
lv_style_copy(&lv_style_pretty, &lv_style_plain);
|
||||
lv_style_pretty.text.color = lv_color_make(0x20, 0x20, 0x20);
|
||||
lv_style_pretty.image.color = lv_color_make(0x20, 0x20, 0x20);
|
||||
lv_style_pretty.line.color = lv_color_make(0x20, 0x20, 0x20);
|
||||
lv_style_pretty.body.main_color = LV_COLOR_WHITE;
|
||||
lv_style_pretty.body.grad_color = LV_COLOR_SILVER;
|
||||
lv_style_pretty.body.radius = LV_DPI / 15;
|
||||
lv_style_pretty.body.border.color = lv_color_make(0x40, 0x40, 0x40);
|
||||
lv_style_pretty.body.border.width = LV_DPI / 50 >= 1 ? LV_DPI / 50 : 1;
|
||||
lv_style_pretty.body.border.opa = LV_OPA_30;
|
||||
|
||||
/*Pretty color style*/
|
||||
lv_style_copy(&lv_style_pretty_color, &lv_style_pretty);
|
||||
lv_style_pretty_color.text.color = lv_color_make(0xe0, 0xe0, 0xe0);
|
||||
lv_style_pretty_color.image.color = lv_color_make(0xe0, 0xe0, 0xe0);
|
||||
lv_style_pretty_color.line.color = lv_color_make(0xc0, 0xc0, 0xc0);
|
||||
lv_style_pretty_color.body.main_color = lv_color_make(0x6b, 0x9a, 0xc7);
|
||||
lv_style_pretty_color.body.grad_color = lv_color_make(0x2b, 0x59, 0x8b);
|
||||
lv_style_pretty_color.body.border.color = lv_color_make(0x15, 0x2c, 0x42);
|
||||
|
||||
/*Transparent style*/
|
||||
lv_style_copy(&lv_style_transp, &lv_style_plain);
|
||||
lv_style_transp.glass = 1;
|
||||
lv_style_transp.body.border.width = 0;
|
||||
lv_style_transp.body.opa = LV_OPA_TRANSP;
|
||||
|
||||
/*Transparent fitting size*/
|
||||
lv_style_copy(&lv_style_transp_fit, &lv_style_transp);
|
||||
lv_style_transp_fit.body.padding.left = 0;
|
||||
lv_style_transp_fit.body.padding.right = 0;
|
||||
lv_style_transp_fit.body.padding.top = 0;
|
||||
lv_style_transp_fit.body.padding.bottom = 0;
|
||||
|
||||
/*Transparent tight style*/
|
||||
lv_style_copy(&lv_style_transp_tight, &lv_style_transp_fit);
|
||||
lv_style_transp_tight.body.padding.inner = 0;
|
||||
|
||||
/*Button released style*/
|
||||
lv_style_copy(&lv_style_btn_rel, &lv_style_plain);
|
||||
lv_style_btn_rel.body.main_color = lv_color_make(0x76, 0xa2, 0xd0);
|
||||
lv_style_btn_rel.body.grad_color = lv_color_make(0x19, 0x3a, 0x5d);
|
||||
lv_style_btn_rel.body.radius = LV_DPI / 15;
|
||||
lv_style_btn_rel.body.padding.left = LV_DPI / 4;
|
||||
lv_style_btn_rel.body.padding.right = LV_DPI / 4;
|
||||
lv_style_btn_rel.body.padding.top = LV_DPI / 6;
|
||||
lv_style_btn_rel.body.padding.bottom = LV_DPI / 6;
|
||||
lv_style_btn_rel.body.padding.inner = LV_DPI / 10;
|
||||
lv_style_btn_rel.body.border.color = lv_color_make(0x0b, 0x19, 0x28);
|
||||
lv_style_btn_rel.body.border.width = LV_DPI / 50 >= 1 ? LV_DPI / 50 : 1;
|
||||
lv_style_btn_rel.body.border.opa = LV_OPA_70;
|
||||
lv_style_btn_rel.body.shadow.color = LV_COLOR_GRAY;
|
||||
lv_style_btn_rel.body.shadow.width = 0;
|
||||
lv_style_btn_rel.text.color = lv_color_make(0xff, 0xff, 0xff);
|
||||
lv_style_btn_rel.image.color = lv_color_make(0xff, 0xff, 0xff);
|
||||
|
||||
/*Button pressed style*/
|
||||
lv_style_copy(&lv_style_btn_pr, &lv_style_btn_rel);
|
||||
lv_style_btn_pr.body.main_color = lv_color_make(0x33, 0x62, 0x94);
|
||||
lv_style_btn_pr.body.grad_color = lv_color_make(0x10, 0x26, 0x3c);
|
||||
lv_style_btn_pr.text.color = lv_color_make(0xa4, 0xb5, 0xc6);
|
||||
lv_style_btn_pr.image.color = lv_color_make(0xa4, 0xb5, 0xc6);
|
||||
lv_style_btn_pr.line.color = lv_color_make(0xa4, 0xb5, 0xc6);
|
||||
|
||||
/*Button toggle released style*/
|
||||
lv_style_copy(&lv_style_btn_tgl_rel, &lv_style_btn_rel);
|
||||
lv_style_btn_tgl_rel.body.main_color = lv_color_make(0x0a, 0x11, 0x22);
|
||||
lv_style_btn_tgl_rel.body.grad_color = lv_color_make(0x37, 0x62, 0x90);
|
||||
lv_style_btn_tgl_rel.body.border.color = lv_color_make(0x01, 0x07, 0x0d);
|
||||
lv_style_btn_tgl_rel.text.color = lv_color_make(0xc8, 0xdd, 0xf4);
|
||||
lv_style_btn_tgl_rel.image.color = lv_color_make(0xc8, 0xdd, 0xf4);
|
||||
lv_style_btn_tgl_rel.line.color = lv_color_make(0xc8, 0xdd, 0xf4);
|
||||
|
||||
/*Button toggle pressed style*/
|
||||
lv_style_copy(&lv_style_btn_tgl_pr, &lv_style_btn_tgl_rel);
|
||||
lv_style_btn_tgl_pr.body.main_color = lv_color_make(0x02, 0x14, 0x27);
|
||||
lv_style_btn_tgl_pr.body.grad_color = lv_color_make(0x2b, 0x4c, 0x70);
|
||||
lv_style_btn_tgl_pr.text.color = lv_color_make(0xa4, 0xb5, 0xc6);
|
||||
lv_style_btn_tgl_pr.image.color = lv_color_make(0xa4, 0xb5, 0xc6);
|
||||
lv_style_btn_tgl_pr.line.color = lv_color_make(0xa4, 0xb5, 0xc6);
|
||||
|
||||
/*Button inactive style*/
|
||||
lv_style_copy(&lv_style_btn_ina, &lv_style_btn_rel);
|
||||
lv_style_btn_ina.body.main_color = lv_color_make(0xd8, 0xd8, 0xd8);
|
||||
lv_style_btn_ina.body.grad_color = lv_color_make(0xd8, 0xd8, 0xd8);
|
||||
lv_style_btn_ina.body.border.color = lv_color_make(0x90, 0x90, 0x90);
|
||||
lv_style_btn_ina.text.color = lv_color_make(0x70, 0x70, 0x70);
|
||||
lv_style_btn_ina.image.color = lv_color_make(0x70, 0x70, 0x70);
|
||||
lv_style_btn_ina.line.color = lv_color_make(0x70, 0x70, 0x70);
|
||||
}
|
||||
|
||||
/**
|
||||
* Copy a style to an other
|
||||
* @param dest pointer to the destination style
|
||||
* @param src pointer to the source style
|
||||
*/
|
||||
void lv_style_copy(lv_style_t * dest, const lv_style_t * src)
|
||||
{
|
||||
memcpy(dest, src, sizeof(lv_style_t));
|
||||
}
|
||||
|
||||
/**
|
||||
* Mix two styles according to a given ratio
|
||||
* @param start start style
|
||||
* @param end end style
|
||||
* @param res store the result style here
|
||||
* @param ratio the ratio of mix [0..256]; 0: `start` style; 256: `end` style
|
||||
*/
|
||||
void lv_style_mix(const lv_style_t * start, const lv_style_t * end, lv_style_t * res, uint16_t ratio)
|
||||
{
|
||||
STYLE_ATTR_MIX(body.opa, ratio);
|
||||
STYLE_ATTR_MIX(body.radius, ratio);
|
||||
STYLE_ATTR_MIX(body.border.width, ratio);
|
||||
STYLE_ATTR_MIX(body.border.opa, ratio);
|
||||
STYLE_ATTR_MIX(body.shadow.width, ratio);
|
||||
STYLE_ATTR_MIX(body.padding.left, ratio);
|
||||
STYLE_ATTR_MIX(body.padding.right, ratio);
|
||||
STYLE_ATTR_MIX(body.padding.top, ratio);
|
||||
STYLE_ATTR_MIX(body.padding.bottom, ratio);
|
||||
STYLE_ATTR_MIX(body.padding.inner, ratio);
|
||||
STYLE_ATTR_MIX(text.line_space, ratio);
|
||||
STYLE_ATTR_MIX(text.letter_space, ratio);
|
||||
STYLE_ATTR_MIX(text.opa, ratio);
|
||||
STYLE_ATTR_MIX(line.width, ratio);
|
||||
STYLE_ATTR_MIX(line.opa, ratio);
|
||||
STYLE_ATTR_MIX(image.intense, ratio);
|
||||
STYLE_ATTR_MIX(image.opa, ratio);
|
||||
|
||||
lv_opa_t opa = ratio == STYLE_MIX_MAX ? LV_OPA_COVER : ratio;
|
||||
|
||||
res->body.main_color = lv_color_mix(end->body.main_color, start->body.main_color, opa);
|
||||
res->body.grad_color = lv_color_mix(end->body.grad_color, start->body.grad_color, opa);
|
||||
res->body.border.color = lv_color_mix(end->body.border.color, start->body.border.color, opa);
|
||||
res->body.shadow.color = lv_color_mix(end->body.shadow.color, start->body.shadow.color, opa);
|
||||
res->text.color = lv_color_mix(end->text.color, start->text.color, opa);
|
||||
res->image.color = lv_color_mix(end->image.color, start->image.color, opa);
|
||||
res->line.color = lv_color_mix(end->line.color, start->line.color, opa);
|
||||
|
||||
if(ratio < (STYLE_MIX_MAX >> 1)) {
|
||||
res->body.border.part = start->body.border.part;
|
||||
res->glass = start->glass;
|
||||
res->text.font = start->text.font;
|
||||
res->body.shadow.type = start->body.shadow.type;
|
||||
res->line.rounded = start->line.rounded;
|
||||
} else {
|
||||
res->body.border.part = end->body.border.part;
|
||||
res->glass = end->glass;
|
||||
res->text.font = end->text.font;
|
||||
res->body.shadow.type = end->body.shadow.type;
|
||||
res->line.rounded = end->line.rounded;
|
||||
}
|
||||
}
|
||||
|
||||
#if LV_USE_ANIMATION
|
||||
|
||||
void lv_style_anim_init(lv_anim_t * a)
|
||||
{
|
||||
lv_anim_init(a);
|
||||
a->start = 0;
|
||||
a->end = STYLE_MIX_MAX;
|
||||
a->exec_cb = (lv_anim_exec_xcb_t)style_animator;
|
||||
a->path_cb = lv_anim_path_linear;
|
||||
a->ready_cb = style_animation_common_end_cb;
|
||||
|
||||
lv_style_anim_dsc_t * dsc;
|
||||
dsc = lv_mem_alloc(sizeof(lv_style_anim_dsc_t));
|
||||
LV_ASSERT_MEM(dsc);
|
||||
if(dsc == NULL) return;
|
||||
dsc->ready_cb = NULL;
|
||||
dsc->style_anim = NULL;
|
||||
lv_style_copy(&dsc->style_start, &lv_style_plain);
|
||||
lv_style_copy(&dsc->style_end, &lv_style_plain);
|
||||
|
||||
a->var = (void *)dsc;
|
||||
}
|
||||
|
||||
void lv_style_anim_set_styles(lv_anim_t * a, lv_style_t * to_anim, const lv_style_t * start, const lv_style_t * end)
|
||||
{
|
||||
|
||||
lv_style_anim_dsc_t * dsc = a->var;
|
||||
dsc->style_anim = to_anim;
|
||||
memcpy(&dsc->style_start, start, sizeof(lv_style_t));
|
||||
memcpy(&dsc->style_end, end, sizeof(lv_style_t));
|
||||
memcpy(dsc->style_anim, start, sizeof(lv_style_t));
|
||||
}
|
||||
#endif
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
#if LV_USE_ANIMATION
|
||||
/**
|
||||
* Used by the style animations to set the values of a style according to start and end style.
|
||||
* @param dsc the 'animated variable' set by lv_style_anim_create()
|
||||
* @param val the current state of the animation between 0 and LV_ANIM_RESOLUTION
|
||||
*/
|
||||
static void style_animator(lv_style_anim_dsc_t * dsc, lv_anim_value_t val)
|
||||
{
|
||||
const lv_style_t * start = &dsc->style_start;
|
||||
const lv_style_t * end = &dsc->style_end;
|
||||
lv_style_t * act = dsc->style_anim;
|
||||
|
||||
lv_style_mix(start, end, act, val);
|
||||
|
||||
lv_obj_report_style_mod(dsc->style_anim);
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when a style animation is ready
|
||||
* It called the user defined call back and free the allocated memories
|
||||
* @param a pointer to the animation
|
||||
*/
|
||||
static void style_animation_common_end_cb(lv_anim_t * a)
|
||||
{
|
||||
|
||||
(void)a; /*Unused*/
|
||||
lv_style_anim_dsc_t * dsc = a->var; /*To avoid casting*/
|
||||
|
||||
if(dsc->ready_cb) dsc->ready_cb(a);
|
||||
|
||||
lv_mem_free(dsc);
|
||||
}
|
||||
|
||||
#endif
|
@ -1,301 +0,0 @@
|
||||
/**
|
||||
* @file lv_style.h
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LV_STYLE_H
|
||||
#define LV_STYLE_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include <stdbool.h>
|
||||
#include "../lv_font/lv_font.h"
|
||||
#include "../lv_misc/lv_color.h"
|
||||
#include "../lv_misc/lv_area.h"
|
||||
#include "../lv_misc/lv_anim.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
#define LV_RADIUS_CIRCLE (LV_COORD_MAX) /**< A very big radius to always draw as circle*/
|
||||
#define LV_STYLE_DEGUG_SENTINEL_VALUE 0x12345678
|
||||
|
||||
LV_EXPORT_CONST_INT(LV_RADIUS_CIRCLE);
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/*Border types (Use 'OR'ed values)*/
|
||||
enum {
|
||||
LV_BORDER_NONE = 0x00,
|
||||
LV_BORDER_BOTTOM = 0x01,
|
||||
LV_BORDER_TOP = 0x02,
|
||||
LV_BORDER_LEFT = 0x04,
|
||||
LV_BORDER_RIGHT = 0x08,
|
||||
LV_BORDER_FULL = 0x0F,
|
||||
LV_BORDER_INTERNAL = 0x10, /**< FOR matrix-like objects (e.g. Button matrix)*/
|
||||
};
|
||||
typedef uint8_t lv_border_part_t;
|
||||
|
||||
/*Shadow types*/
|
||||
enum {
|
||||
LV_SHADOW_BOTTOM = 0, /**< Only draw bottom shadow */
|
||||
LV_SHADOW_FULL, /**< Draw shadow on all sides */
|
||||
};
|
||||
typedef uint8_t lv_shadow_type_t;
|
||||
|
||||
/**
|
||||
* Objects in LittlevGL can be assigned a style - which holds information about
|
||||
* how the object should be drawn.
|
||||
*
|
||||
* This allows for easy customization without having to modify the object's design
|
||||
* function.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint8_t glass : 1; /**< 1: Do not inherit this style*/
|
||||
|
||||
/** Object background. */
|
||||
struct
|
||||
{
|
||||
lv_color_t main_color; /**< Object's main background color. */
|
||||
lv_color_t grad_color; /**< Second color. If not equal to `main_color` a gradient will be drawn for the background. */
|
||||
lv_coord_t radius; /**< Object's corner radius. You can use #LV_RADIUS_CIRCLE if you want to draw a circle. */
|
||||
lv_opa_t opa; /**< Object's opacity (0-255). */
|
||||
|
||||
struct
|
||||
{
|
||||
lv_color_t color; /**< Border color */
|
||||
lv_coord_t width; /**< Border width */
|
||||
lv_border_part_t part; /**< Which borders to draw */
|
||||
lv_opa_t opa; /**< Border opacity. */
|
||||
} border;
|
||||
|
||||
|
||||
struct
|
||||
{
|
||||
lv_color_t color;
|
||||
lv_coord_t width;
|
||||
lv_shadow_type_t type; /**< Which parts of the shadow to draw */
|
||||
} shadow;
|
||||
|
||||
struct
|
||||
{
|
||||
lv_coord_t top;
|
||||
lv_coord_t bottom;
|
||||
lv_coord_t left;
|
||||
lv_coord_t right;
|
||||
lv_coord_t inner;
|
||||
} padding;
|
||||
} body;
|
||||
|
||||
/** Style for text drawn by this object. */
|
||||
struct
|
||||
{
|
||||
lv_color_t color; /**< Text color */
|
||||
lv_color_t sel_color; /**< Text selection background color. */
|
||||
const lv_font_t * font;
|
||||
lv_coord_t letter_space; /**< Space between letters */
|
||||
lv_coord_t line_space; /**< Space between lines (vertical) */
|
||||
lv_opa_t opa; /**< Text opacity */
|
||||
} text;
|
||||
|
||||
/**< Style of images. */
|
||||
struct
|
||||
{
|
||||
lv_color_t color; /**< Color to recolor the image with */
|
||||
lv_opa_t intense; /**< Opacity of recoloring (0 means no recoloring) */
|
||||
lv_opa_t opa; /**< Opacity of whole image */
|
||||
} image;
|
||||
|
||||
/**< Style of lines (not borders). */
|
||||
struct
|
||||
{
|
||||
lv_color_t color;
|
||||
lv_coord_t width;
|
||||
lv_opa_t opa;
|
||||
uint8_t rounded : 1; /**< 1: rounded line endings*/
|
||||
} line;
|
||||
|
||||
#if LV_USE_DEBUG
|
||||
#if LV_USE_ASSERT_STYLE
|
||||
uint32_t debug_sentinel; /**<Should `LV_STYLE_DEGUG_SENTINEL_VALUE` to indicate that the style is valid*/
|
||||
#endif
|
||||
#endif
|
||||
|
||||
} lv_style_t;
|
||||
|
||||
#if LV_USE_ANIMATION
|
||||
/** Data structure for style animations. */
|
||||
typedef struct
|
||||
{
|
||||
lv_style_t style_start; /*Save not only pointers because can be same as 'style_anim' then it
|
||||
will be modified too*/
|
||||
lv_style_t style_end;
|
||||
lv_style_t * style_anim;
|
||||
lv_anim_ready_cb_t ready_cb;
|
||||
} lv_style_anim_dsc_t;
|
||||
#endif
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Init the basic styles
|
||||
*/
|
||||
void lv_style_init(void);
|
||||
|
||||
/**
|
||||
* Copy a style to an other
|
||||
* @param dest pointer to the destination style
|
||||
* @param src pointer to the source style
|
||||
*/
|
||||
void lv_style_copy(lv_style_t * dest, const lv_style_t * src);
|
||||
|
||||
/**
|
||||
* Mix two styles according to a given ratio
|
||||
* @param start start style
|
||||
* @param end end style
|
||||
* @param res store the result style here
|
||||
* @param ratio the ratio of mix [0..256]; 0: `start` style; 256: `end` style
|
||||
*/
|
||||
void lv_style_mix(const lv_style_t * start, const lv_style_t * end, lv_style_t * res, uint16_t ratio);
|
||||
|
||||
#if LV_USE_ANIMATION
|
||||
|
||||
/**
|
||||
* Initialize an animation variable.
|
||||
* E.g.:
|
||||
* lv_anim_t a;
|
||||
* lv_style_anim__init(&a);
|
||||
* lv_style_anim_set_...(&a);
|
||||
* lv_style_anim_create(&a);
|
||||
* @param a pointer to an `lv_anim_t` variable to initialize
|
||||
*/
|
||||
void lv_style_anim_init(lv_anim_t * a);
|
||||
|
||||
/**
|
||||
*
|
||||
* @param a pointer to an initialized `lv_anim_t` variable
|
||||
* @param to_anim pointer to the style to animate
|
||||
* @param start pointer to a style to animate from (start value)
|
||||
* @param end pointer to a style to animate to (end value)
|
||||
*/
|
||||
void lv_style_anim_set_styles(lv_anim_t * a, lv_style_t * to_anim, const lv_style_t * start, const lv_style_t * end);
|
||||
|
||||
/**
|
||||
* Set the duration and delay of an animation
|
||||
* @param a pointer to an initialized `lv_anim_t` variable
|
||||
* @param duration duration of the animation in milliseconds
|
||||
* @param delay delay before the animation in milliseconds
|
||||
*/
|
||||
static inline void lv_style_anim_set_time(lv_anim_t * a, uint16_t duration, int16_t delay)
|
||||
{
|
||||
lv_anim_set_time(a, duration, delay);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a function call when the animation is ready
|
||||
* @param a pointer to an initialized `lv_anim_t` variable
|
||||
* @param ready_cb a function call when the animation is ready
|
||||
*/
|
||||
static inline void lv_style_anim_set_ready_cb(lv_anim_t * a, lv_anim_ready_cb_t ready_cb)
|
||||
{
|
||||
lv_style_anim_dsc_t * dsc = (lv_style_anim_dsc_t *)a->var;
|
||||
dsc->ready_cb = ready_cb;
|
||||
}
|
||||
|
||||
/**
|
||||
* Make the animation to play back to when the forward direction is ready
|
||||
* @param a pointer to an initialized `lv_anim_t` variable
|
||||
* @param wait_time time in milliseconds to wait before starting the back direction
|
||||
*/
|
||||
static inline void lv_style_anim_set_playback(lv_anim_t * a, uint16_t wait_time)
|
||||
{
|
||||
lv_anim_set_playback(a, wait_time);
|
||||
}
|
||||
|
||||
/**
|
||||
* Disable playback. (Disabled after `lv_anim_init()`)
|
||||
* @param a pointer to an initialized `lv_anim_t` variable
|
||||
*/
|
||||
static inline void lv_style_anim_clear_playback(lv_anim_t * a)
|
||||
{
|
||||
lv_anim_clear_playback(a);
|
||||
}
|
||||
|
||||
/**
|
||||
* Make the animation to start again when ready.
|
||||
* @param a pointer to an initialized `lv_anim_t` variable
|
||||
* @param wait_time time in milliseconds to wait before starting the animation again
|
||||
*/
|
||||
static inline void lv_style_anim_set_repeat(lv_anim_t * a, uint16_t wait_time)
|
||||
{
|
||||
lv_anim_set_repeat(a, wait_time);
|
||||
}
|
||||
|
||||
/**
|
||||
* Disable repeat. (Disabled after `lv_anim_init()`)
|
||||
* @param a pointer to an initialized `lv_anim_t` variable
|
||||
*/
|
||||
static inline void lv_style_anim_clear_repeat(lv_anim_t * a)
|
||||
{
|
||||
lv_anim_clear_repeat(a);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an animation
|
||||
* @param a an initialized 'anim_t' variable. Not required after call.
|
||||
*/
|
||||
static inline void lv_style_anim_create(lv_anim_t * a)
|
||||
{
|
||||
lv_anim_create(a);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/*************************
|
||||
* GLOBAL VARIABLES
|
||||
*************************/
|
||||
extern lv_style_t lv_style_scr;
|
||||
extern lv_style_t lv_style_transp;
|
||||
extern lv_style_t lv_style_transp_fit;
|
||||
extern lv_style_t lv_style_transp_tight;
|
||||
extern lv_style_t lv_style_plain;
|
||||
extern lv_style_t lv_style_plain_color;
|
||||
extern lv_style_t lv_style_pretty;
|
||||
extern lv_style_t lv_style_pretty_color;
|
||||
extern lv_style_t lv_style_btn_rel;
|
||||
extern lv_style_t lv_style_btn_pr;
|
||||
extern lv_style_t lv_style_btn_tgl_rel;
|
||||
extern lv_style_t lv_style_btn_tgl_pr;
|
||||
extern lv_style_t lv_style_btn_ina;
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Create and initialize a `static` style
|
||||
* Example:
|
||||
* LV_STYLE_CREATE(my_style, &lv_style_plain);
|
||||
* is equivalent to
|
||||
* static lv_style_t my_style;
|
||||
* lv_style_copy(my_style, &lv_style_plain);
|
||||
*
|
||||
* If the style to copy is `NULL` `lv_style_plain` will be used.
|
||||
*/
|
||||
#define LV_STYLE_CREATE(name, copy_p) static lv_style_t name; lv_style_copy(&name, copy_p == NULL ? &lv_style_plain : copy_p);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif /*LV_STYLE_H*/
|
@ -1,191 +0,0 @@
|
||||
/**
|
||||
* @file lv_draw.c
|
||||
*
|
||||
*/
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdbool.h>
|
||||
#include "lv_draw.h"
|
||||
#include "../lv_core/lv_debug.h"
|
||||
#include "../lv_misc/lv_math.h"
|
||||
#include "../lv_misc/lv_log.h"
|
||||
#include "../lv_misc/lv_math.h"
|
||||
#include "../lv_misc/lv_mem.h"
|
||||
#include "../lv_misc/lv_gc.h"
|
||||
|
||||
#if defined(LV_GC_INCLUDE)
|
||||
#include LV_GC_INCLUDE
|
||||
#endif /* LV_ENABLE_GC */
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
**********************/
|
||||
static uint32_t draw_buf_size = 0;
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL FUNCTIONS
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Give a buffer with the given to use during drawing.
|
||||
* Be careful to not use the buffer while other processes are using it.
|
||||
* @param size the required size
|
||||
*/
|
||||
void * lv_draw_get_buf(uint32_t size)
|
||||
{
|
||||
if(size <= draw_buf_size) return LV_GC_ROOT(_lv_draw_buf);
|
||||
|
||||
LV_LOG_TRACE("lv_draw_get_buf: allocate");
|
||||
|
||||
draw_buf_size = size;
|
||||
|
||||
if(LV_GC_ROOT(_lv_draw_buf) == NULL) {
|
||||
LV_GC_ROOT(_lv_draw_buf) = lv_mem_alloc(size);
|
||||
LV_ASSERT_MEM(LV_GC_ROOT(_lv_draw_buf));
|
||||
return LV_GC_ROOT(_lv_draw_buf);
|
||||
}
|
||||
|
||||
LV_GC_ROOT(_lv_draw_buf) = lv_mem_realloc(LV_GC_ROOT(_lv_draw_buf), size);
|
||||
LV_ASSERT_MEM(LV_GC_ROOT(_lv_draw_buf));
|
||||
return LV_GC_ROOT(_lv_draw_buf);
|
||||
}
|
||||
|
||||
/**
|
||||
* Free the draw buffer
|
||||
*/
|
||||
void lv_draw_free_buf(void)
|
||||
{
|
||||
if(LV_GC_ROOT(_lv_draw_buf)) {
|
||||
lv_mem_free(LV_GC_ROOT(_lv_draw_buf));
|
||||
LV_GC_ROOT(_lv_draw_buf) = NULL;
|
||||
draw_buf_size = 0;
|
||||
}
|
||||
}
|
||||
|
||||
#if LV_ANTIALIAS
|
||||
|
||||
/**
|
||||
* Get the opacity of a pixel based it's position in a line segment
|
||||
* @param seg segment length
|
||||
* @param px_id position of of a pixel which opacity should be get [0..seg-1]
|
||||
* @param base_opa the base opacity
|
||||
* @return the opacity of the given pixel
|
||||
*/
|
||||
lv_opa_t lv_draw_aa_get_opa(lv_coord_t seg, lv_coord_t px_id, lv_opa_t base_opa)
|
||||
{
|
||||
/* How to calculate the opacity of pixels on the edges which makes the anti-aliasing?
|
||||
* For example we have a line like this (y = -0.5 * x):
|
||||
*
|
||||
* | _ _
|
||||
* * * |
|
||||
*
|
||||
* Anti-aliased pixels come to the '*' characters
|
||||
* Calculate what percentage of the pixels should be covered if real line (not rasterized) would
|
||||
* be drawn:
|
||||
* 1. A real line should start on (0;0) and end on (2;1)
|
||||
* 2. So the line intersection coordinates on the first pixel: (0;0) (1;0.5) -> 25% covered
|
||||
* pixel in average
|
||||
* 3. For the second pixel: (1;0.5) (2;1) -> 75% covered pixel in average
|
||||
* 4. The equation: (px_id * 2 + 1) / (segment_width * 2)
|
||||
* segment_width: the line segment which is being anti-aliased (was 2 in the
|
||||
* example) px_id: pixel ID from 0 to (segment_width - 1) result: [0..1] coverage of the pixel
|
||||
*/
|
||||
|
||||
/*Accelerate the common segment sizes to avoid division*/
|
||||
static const lv_opa_t seg1[1] = {128};
|
||||
static const lv_opa_t seg2[2] = {64, 192};
|
||||
static const lv_opa_t seg3[3] = {42, 128, 212};
|
||||
static const lv_opa_t seg4[4] = {32, 96, 159, 223};
|
||||
static const lv_opa_t seg5[5] = {26, 76, 128, 178, 230};
|
||||
static const lv_opa_t seg6[6] = {21, 64, 106, 148, 191, 234};
|
||||
static const lv_opa_t seg7[7] = {18, 55, 91, 128, 164, 200, 237};
|
||||
static const lv_opa_t seg8[8] = {16, 48, 80, 112, 143, 175, 207, 239};
|
||||
|
||||
static const lv_opa_t * seg_map[] = {seg1, seg2, seg3, seg4, seg5, seg6, seg7, seg8};
|
||||
|
||||
if(seg == 0)
|
||||
return LV_OPA_TRANSP;
|
||||
else if(seg < 8)
|
||||
return (uint32_t)((uint32_t)seg_map[seg - 1][px_id] * base_opa) >> 8;
|
||||
else {
|
||||
return ((px_id * 2 + 1) * base_opa) / (2 * seg);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a vertical anti-aliasing segment (pixels with decreasing opacity)
|
||||
* @param x start point x coordinate
|
||||
* @param y start point y coordinate
|
||||
* @param length length of segment (negative value to start from 0 opacity)
|
||||
* @param mask draw only in this area
|
||||
* @param color color of pixels
|
||||
* @param opa maximum opacity
|
||||
*/
|
||||
void lv_draw_aa_ver_seg(lv_coord_t x, lv_coord_t y, lv_coord_t length, const lv_area_t * mask, lv_color_t color,
|
||||
lv_opa_t opa)
|
||||
{
|
||||
bool aa_inv = false;
|
||||
if(length < 0) {
|
||||
aa_inv = true;
|
||||
length = -length;
|
||||
}
|
||||
|
||||
lv_coord_t i;
|
||||
for(i = 0; i < length; i++) {
|
||||
lv_opa_t px_opa = lv_draw_aa_get_opa(length, i, opa);
|
||||
if(aa_inv) px_opa = opa - px_opa;
|
||||
lv_draw_px(x, y + i, mask, color, px_opa);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a horizontal anti-aliasing segment (pixels with decreasing opacity)
|
||||
* @param x start point x coordinate
|
||||
* @param y start point y coordinate
|
||||
* @param length length of segment (negative value to start from 0 opacity)
|
||||
* @param mask draw only in this area
|
||||
* @param color color of pixels
|
||||
* @param opa maximum opacity
|
||||
*/
|
||||
void lv_draw_aa_hor_seg(lv_coord_t x, lv_coord_t y, lv_coord_t length, const lv_area_t * mask, lv_color_t color,
|
||||
lv_opa_t opa)
|
||||
{
|
||||
bool aa_inv = false;
|
||||
if(length < 0) {
|
||||
aa_inv = true;
|
||||
length = -length;
|
||||
}
|
||||
|
||||
lv_coord_t i;
|
||||
for(i = 0; i < length; i++) {
|
||||
lv_opa_t px_opa = lv_draw_aa_get_opa(length, i, opa);
|
||||
if(aa_inv) px_opa = opa - px_opa;
|
||||
lv_draw_px(x + i, y, mask, color, px_opa);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
@ -1,109 +0,0 @@
|
||||
/**
|
||||
* @file lv_draw.h
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LV_DRAW_H
|
||||
#define LV_DRAW_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#ifdef LV_CONF_INCLUDE_SIMPLE
|
||||
#include "lv_conf.h"
|
||||
#else
|
||||
#include "../../../lv_conf.h"
|
||||
#endif
|
||||
|
||||
#include "../lv_core/lv_style.h"
|
||||
#include "../lv_misc/lv_txt.h"
|
||||
#include "lv_img_decoder.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Give a buffer with the given to use during drawing.
|
||||
* Be careful to not use the buffer while other processes are using it.
|
||||
* @param size the required size
|
||||
*/
|
||||
void * lv_draw_get_buf(uint32_t size);
|
||||
|
||||
/**
|
||||
* Free the draw buffer
|
||||
*/
|
||||
void lv_draw_free_buf(void);
|
||||
|
||||
#if LV_ANTIALIAS
|
||||
|
||||
/**
|
||||
* Get the opacity of a pixel based it's position in a line segment
|
||||
* @param seg segment length
|
||||
* @param px_id position of of a pixel which opacity should be get [0..seg-1]
|
||||
* @param base_opa the base opacity
|
||||
* @return the opacity of the given pixel
|
||||
*/
|
||||
lv_opa_t lv_draw_aa_get_opa(lv_coord_t seg, lv_coord_t px_id, lv_opa_t base_opa);
|
||||
|
||||
/**
|
||||
* Add a vertical anti-aliasing segment (pixels with decreasing opacity)
|
||||
* @param x start point x coordinate
|
||||
* @param y start point y coordinate
|
||||
* @param length length of segment (negative value to start from 0 opacity)
|
||||
* @param mask draw only in this area
|
||||
* @param color color of pixels
|
||||
* @param opa maximum opacity
|
||||
*/
|
||||
void lv_draw_aa_ver_seg(lv_coord_t x, lv_coord_t y, lv_coord_t length, const lv_area_t * mask, lv_color_t color,
|
||||
lv_opa_t opa);
|
||||
|
||||
/**
|
||||
* Add a horizontal anti-aliasing segment (pixels with decreasing opacity)
|
||||
* @param x start point x coordinate
|
||||
* @param y start point y coordinate
|
||||
* @param length length of segment (negative value to start from 0 opacity)
|
||||
* @param mask draw only in this area
|
||||
* @param color color of pixels
|
||||
* @param opa maximum opacity
|
||||
*/
|
||||
void lv_draw_aa_hor_seg(lv_coord_t x, lv_coord_t y, lv_coord_t length, const lv_area_t * mask, lv_color_t color,
|
||||
lv_opa_t opa);
|
||||
#endif
|
||||
|
||||
/**********************
|
||||
* GLOBAL VARIABLES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* POST INCLUDES
|
||||
*********************/
|
||||
#include "lv_draw_basic.h"
|
||||
#include "lv_draw_rect.h"
|
||||
#include "lv_draw_label.h"
|
||||
#include "lv_draw_img.h"
|
||||
#include "lv_draw_line.h"
|
||||
#include "lv_draw_triangle.h"
|
||||
#include "lv_draw_arc.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif /*LV_DRAW_H*/
|
@ -1,15 +0,0 @@
|
||||
CSRCS += lv_draw_basic.c
|
||||
CSRCS += lv_draw.c
|
||||
CSRCS += lv_draw_rect.c
|
||||
CSRCS += lv_draw_label.c
|
||||
CSRCS += lv_draw_line.c
|
||||
CSRCS += lv_draw_img.c
|
||||
CSRCS += lv_draw_arc.c
|
||||
CSRCS += lv_draw_triangle.c
|
||||
CSRCS += lv_img_decoder.c
|
||||
CSRCS += lv_img_cache.c
|
||||
|
||||
DEPPATH += --dep-path $(LVGL_DIR)/lvgl/src/lv_draw
|
||||
VPATH += :$(LVGL_DIR)/lvgl/src/lv_draw
|
||||
|
||||
CFLAGS += "-I$(LVGL_DIR)lvgl/src/lv_draw"
|
@ -1,251 +0,0 @@
|
||||
/**
|
||||
* @file lv_draw_arc.c
|
||||
*
|
||||
*/
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "lv_draw_arc.h"
|
||||
#include "../lv_misc/lv_math.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
static void ver_line(lv_coord_t x, lv_coord_t y, const lv_area_t * mask, lv_coord_t len, lv_color_t color,
|
||||
lv_opa_t opa);
|
||||
static void hor_line(lv_coord_t x, lv_coord_t y, const lv_area_t * mask, lv_coord_t len, lv_color_t color,
|
||||
lv_opa_t opa);
|
||||
static bool deg_test_norm(uint16_t deg, uint16_t start, uint16_t end);
|
||||
static bool deg_test_inv(uint16_t deg, uint16_t start, uint16_t end);
|
||||
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL FUNCTIONS
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Draw an arc. (Can draw pie too with great thickness.)
|
||||
* @param center_x the x coordinate of the center of the arc
|
||||
* @param center_y the y coordinate of the center of the arc
|
||||
* @param radius the radius of the arc
|
||||
* @param mask the arc will be drawn only in this mask
|
||||
* @param start_angle the start angle of the arc (0 deg on the bottom, 90 deg on the right)
|
||||
* @param end_angle the end angle of the arc
|
||||
* @param style style of the arc (`body.thickness`, `body.main_color`, `body.opa` is used)
|
||||
* @param opa_scale scale down all opacities by the factor
|
||||
*/
|
||||
void lv_draw_arc(lv_coord_t center_x, lv_coord_t center_y, uint16_t radius, const lv_area_t * mask,
|
||||
uint16_t start_angle, uint16_t end_angle, const lv_style_t * style, lv_opa_t opa_scale)
|
||||
{
|
||||
lv_coord_t thickness = style->line.width;
|
||||
if(thickness > radius) thickness = radius;
|
||||
|
||||
#if LV_ANTIALIAS
|
||||
thickness--;
|
||||
radius--;
|
||||
#endif
|
||||
|
||||
lv_coord_t r_out = radius;
|
||||
lv_coord_t r_in = r_out - thickness;
|
||||
int16_t deg_base;
|
||||
int16_t deg;
|
||||
lv_coord_t x_start[4];
|
||||
lv_coord_t x_end[4];
|
||||
|
||||
lv_color_t color = style->line.color;
|
||||
lv_opa_t opa = opa_scale == LV_OPA_COVER ? style->body.opa : (uint16_t)((uint16_t)style->body.opa * opa_scale) >> 8;
|
||||
|
||||
bool (*deg_test)(uint16_t, uint16_t, uint16_t);
|
||||
if(start_angle <= end_angle)
|
||||
deg_test = deg_test_norm;
|
||||
else
|
||||
deg_test = deg_test_inv;
|
||||
|
||||
int middle_r_out = r_out;
|
||||
#if !LV_ANTIALIAS
|
||||
thickness--;
|
||||
middle_r_out = r_out - 1;
|
||||
#endif
|
||||
if(deg_test(270, start_angle, end_angle))
|
||||
hor_line(center_x - middle_r_out, center_y, mask, thickness, color, opa); /*Left Middle*/
|
||||
if(deg_test(90, start_angle, end_angle))
|
||||
hor_line(center_x + r_in, center_y, mask, thickness, color, opa); /*Right Middle*/
|
||||
if(deg_test(180, start_angle, end_angle))
|
||||
ver_line(center_x, center_y - middle_r_out, mask, thickness, color, opa); /*Top Middle*/
|
||||
if(deg_test(0, start_angle, end_angle))
|
||||
ver_line(center_x, center_y + r_in, mask, thickness, color, opa); /*Bottom middle*/
|
||||
|
||||
uint32_t r_out_sqr = r_out * r_out;
|
||||
uint32_t r_in_sqr = r_in * r_in;
|
||||
#if LV_ANTIALIAS
|
||||
uint32_t r_out_aa_sqr = (r_out + 1) * (r_out + 1);
|
||||
uint32_t r_in_aa_sqr = (r_in - 1) * (r_in - 1);
|
||||
#endif
|
||||
int16_t xi;
|
||||
int16_t yi;
|
||||
for(yi = -r_out; yi < 0; yi++) {
|
||||
x_start[0] = LV_COORD_MIN;
|
||||
x_start[1] = LV_COORD_MIN;
|
||||
x_start[2] = LV_COORD_MIN;
|
||||
x_start[3] = LV_COORD_MIN;
|
||||
x_end[0] = LV_COORD_MIN;
|
||||
x_end[1] = LV_COORD_MIN;
|
||||
x_end[2] = LV_COORD_MIN;
|
||||
x_end[3] = LV_COORD_MIN;
|
||||
int xe = 0;
|
||||
for(xi = -r_out; xi < 0; xi++) {
|
||||
|
||||
uint32_t r_act_sqr = xi * xi + yi * yi;
|
||||
#if LV_ANTIALIAS
|
||||
if(r_act_sqr > r_out_aa_sqr) {
|
||||
continue;
|
||||
}
|
||||
#else
|
||||
if(r_act_sqr > r_out_sqr) continue;
|
||||
#endif
|
||||
|
||||
deg_base = lv_atan2(xi, yi) - 180;
|
||||
|
||||
#if LV_ANTIALIAS
|
||||
int opa2 = -1;
|
||||
if(r_act_sqr > r_out_sqr) {
|
||||
opa2 = LV_OPA_100 * (r_out + 1) - lv_sqrt(LV_OPA_100 * LV_OPA_100 * r_act_sqr);
|
||||
if(opa2 < LV_OPA_0)
|
||||
opa2 = LV_OPA_0;
|
||||
else if(opa2 > LV_OPA_100)
|
||||
opa2 = LV_OPA_100;
|
||||
} else if(r_act_sqr < r_in_sqr) {
|
||||
if(xe == 0) xe = xi;
|
||||
opa2 = lv_sqrt(LV_OPA_100 * LV_OPA_100 * r_act_sqr) - LV_OPA_100 * (r_in - 1);
|
||||
if(opa2 < LV_OPA_0)
|
||||
opa2 = LV_OPA_0;
|
||||
else if(opa2 > LV_OPA_100)
|
||||
opa2 = LV_OPA_100;
|
||||
if(r_act_sqr < r_in_aa_sqr)
|
||||
break; /*No need to continue the iteration in x once we found the inner edge of the
|
||||
arc*/
|
||||
}
|
||||
if(opa2 != -1) {
|
||||
if(deg_test(180 + deg_base, start_angle, end_angle)) {
|
||||
lv_draw_px(center_x + xi, center_y + yi, mask, color, opa2);
|
||||
}
|
||||
if(deg_test(360 - deg_base, start_angle, end_angle)) {
|
||||
lv_draw_px(center_x + xi, center_y - yi, mask, color, opa2);
|
||||
}
|
||||
if(deg_test(180 - deg_base, start_angle, end_angle)) {
|
||||
lv_draw_px(center_x - xi, center_y + yi, mask, color, opa2);
|
||||
}
|
||||
if(deg_test(deg_base, start_angle, end_angle)) {
|
||||
lv_draw_px(center_x - xi, center_y - yi, mask, color, opa2);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
|
||||
deg = 180 + deg_base;
|
||||
if(deg_test(deg, start_angle, end_angle)) {
|
||||
if(x_start[0] == LV_COORD_MIN) x_start[0] = xi;
|
||||
} else if(x_start[0] != LV_COORD_MIN && x_end[0] == LV_COORD_MIN) {
|
||||
x_end[0] = xi - 1;
|
||||
}
|
||||
|
||||
deg = 360 - deg_base;
|
||||
if(deg_test(deg, start_angle, end_angle)) {
|
||||
if(x_start[1] == LV_COORD_MIN) x_start[1] = xi;
|
||||
} else if(x_start[1] != LV_COORD_MIN && x_end[1] == LV_COORD_MIN) {
|
||||
x_end[1] = xi - 1;
|
||||
}
|
||||
|
||||
deg = 180 - deg_base;
|
||||
if(deg_test(deg, start_angle, end_angle)) {
|
||||
if(x_start[2] == LV_COORD_MIN) x_start[2] = xi;
|
||||
} else if(x_start[2] != LV_COORD_MIN && x_end[2] == LV_COORD_MIN) {
|
||||
x_end[2] = xi - 1;
|
||||
}
|
||||
|
||||
deg = deg_base;
|
||||
if(deg_test(deg, start_angle, end_angle)) {
|
||||
if(x_start[3] == LV_COORD_MIN) x_start[3] = xi;
|
||||
} else if(x_start[3] != LV_COORD_MIN && x_end[3] == LV_COORD_MIN) {
|
||||
x_end[3] = xi - 1;
|
||||
}
|
||||
|
||||
if(r_act_sqr < r_in_sqr) {
|
||||
xe = xi;
|
||||
break; /*No need to continue the iteration in x once we found the inner edge of the
|
||||
arc*/
|
||||
}
|
||||
}
|
||||
|
||||
if(x_start[0] != LV_COORD_MIN) {
|
||||
if(x_end[0] == LV_COORD_MIN) x_end[0] = xe - 1;
|
||||
hor_line(center_x + x_start[0], center_y + yi, mask, x_end[0] - x_start[0], color, opa);
|
||||
}
|
||||
|
||||
if(x_start[1] != LV_COORD_MIN) {
|
||||
if(x_end[1] == LV_COORD_MIN) x_end[1] = xe - 1;
|
||||
hor_line(center_x + x_start[1], center_y - yi, mask, x_end[1] - x_start[1], color, opa);
|
||||
}
|
||||
|
||||
if(x_start[2] != LV_COORD_MIN) {
|
||||
if(x_end[2] == LV_COORD_MIN) x_end[2] = xe - 1;
|
||||
hor_line(center_x - x_end[2], center_y + yi, mask, LV_MATH_ABS(x_end[2] - x_start[2]), color, opa);
|
||||
}
|
||||
|
||||
if(x_start[3] != LV_COORD_MIN) {
|
||||
if(x_end[3] == LV_COORD_MIN) x_end[3] = xe - 1;
|
||||
hor_line(center_x - x_end[3], center_y - yi, mask, LV_MATH_ABS(x_end[3] - x_start[3]), color, opa);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
static void ver_line(lv_coord_t x, lv_coord_t y, const lv_area_t * mask, lv_coord_t len, lv_color_t color, lv_opa_t opa)
|
||||
{
|
||||
lv_area_t area;
|
||||
lv_area_set(&area, x, y, x, y + len);
|
||||
|
||||
lv_draw_fill(&area, mask, color, opa);
|
||||
}
|
||||
|
||||
static void hor_line(lv_coord_t x, lv_coord_t y, const lv_area_t * mask, lv_coord_t len, lv_color_t color, lv_opa_t opa)
|
||||
{
|
||||
lv_area_t area;
|
||||
lv_area_set(&area, x, y, x + len, y);
|
||||
|
||||
lv_draw_fill(&area, mask, color, opa);
|
||||
}
|
||||
|
||||
static bool deg_test_norm(uint16_t deg, uint16_t start, uint16_t end)
|
||||
{
|
||||
if(deg >= start && deg <= end)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool deg_test_inv(uint16_t deg, uint16_t start, uint16_t end)
|
||||
{
|
||||
if(deg >= start || deg <= end) {
|
||||
return true;
|
||||
} else
|
||||
return false;
|
||||
}
|
@ -1,52 +0,0 @@
|
||||
/**
|
||||
* @file lv_draw_arc.h
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LV_DRAW_ARC_H
|
||||
#define LV_DRAW_ARC_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "lv_draw.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Draw an arc. (Can draw pie too with great thickness.)
|
||||
* @param center_x the x coordinate of the center of the arc
|
||||
* @param center_y the y coordinate of the center of the arc
|
||||
* @param radius the radius of the arc
|
||||
* @param mask the arc will be drawn only in this mask
|
||||
* @param start_angle the start angle of the arc (0 deg on the bottom, 90 deg on the right)
|
||||
* @param end_angle the end angle of the arc
|
||||
* @param style style of the arc (`body.thickness`, `body.main_color`, `body.opa` is used)
|
||||
* @param opa_scale scale down all opacities by the factor
|
||||
*/
|
||||
void lv_draw_arc(lv_coord_t center_x, lv_coord_t center_y, uint16_t radius, const lv_area_t * mask,
|
||||
uint16_t start_angle, uint16_t end_angle, const lv_style_t * style, lv_opa_t opa_scale);
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif /*LV_DRAW_ARC*/
|
@ -1,783 +0,0 @@
|
||||
/**
|
||||
* @file lv_draw_basic.c
|
||||
*
|
||||
*/
|
||||
|
||||
#include "lv_draw_basic.h"
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "../lv_core/lv_refr.h"
|
||||
#include "../lv_hal/lv_hal.h"
|
||||
#include "../lv_font/lv_font.h"
|
||||
#include "../lv_misc/lv_area.h"
|
||||
#include "../lv_misc/lv_color.h"
|
||||
#include "../lv_misc/lv_log.h"
|
||||
|
||||
#include <stddef.h>
|
||||
#include "lv_draw.h"
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/*Always fill < 50 px with 'sw_color_fill' because of the hw. init overhead*/
|
||||
#define VFILL_HW_ACC_SIZE_LIMIT 50
|
||||
|
||||
#ifndef LV_ATTRIBUTE_MEM_ALIGN
|
||||
#define LV_ATTRIBUTE_MEM_ALIGN
|
||||
#endif
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
static void sw_mem_blend(lv_color_t * dest, const lv_color_t * src, uint32_t length, lv_opa_t opa);
|
||||
static void sw_color_fill(lv_color_t * mem, lv_coord_t mem_width, const lv_area_t * fill_area, lv_color_t color,
|
||||
lv_opa_t opa);
|
||||
|
||||
#if LV_COLOR_DEPTH == 32 && LV_COLOR_SCREEN_TRANSP
|
||||
static inline lv_color_t color_mix_2_alpha(lv_color_t bg_color, lv_opa_t bg_opa, lv_color_t fg_color, lv_opa_t fg_opa);
|
||||
#endif
|
||||
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL FUNCTIONS
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Put a pixel in the Virtual Display Buffer
|
||||
* @param x pixel x coordinate
|
||||
* @param y pixel y coordinate
|
||||
* @param mask_p fill only on this mask (truncated to VDB area)
|
||||
* @param color pixel color
|
||||
* @param opa opacity of the area (0..255)
|
||||
*/
|
||||
void lv_draw_px(lv_coord_t x, lv_coord_t y, const lv_area_t * mask_p, lv_color_t color, lv_opa_t opa)
|
||||
{
|
||||
|
||||
if(opa < LV_OPA_MIN) return;
|
||||
if(opa > LV_OPA_MAX) opa = LV_OPA_COVER;
|
||||
|
||||
/*Pixel out of the mask*/
|
||||
if(x < mask_p->x1 || x > mask_p->x2 || y < mask_p->y1 || y > mask_p->y2) {
|
||||
return;
|
||||
}
|
||||
|
||||
lv_disp_t * disp = lv_refr_get_disp_refreshing();
|
||||
lv_disp_buf_t * vdb = lv_disp_get_buf(disp);
|
||||
uint32_t vdb_width = lv_area_get_width(&vdb->area);
|
||||
|
||||
/*Make the coordinates relative to VDB*/
|
||||
x -= vdb->area.x1;
|
||||
y -= vdb->area.y1;
|
||||
|
||||
if(disp->driver.set_px_cb) {
|
||||
disp->driver.set_px_cb(&disp->driver, (uint8_t *)vdb->buf_act, vdb_width, x, y, color, opa);
|
||||
} else {
|
||||
bool scr_transp = false;
|
||||
#if LV_COLOR_DEPTH == 32 && LV_COLOR_SCREEN_TRANSP
|
||||
scr_transp = disp->driver.screen_transp;
|
||||
#endif
|
||||
|
||||
lv_color_t * vdb_px_p = vdb->buf_act;
|
||||
vdb_px_p += y * vdb_width + x;
|
||||
|
||||
if(scr_transp == false) {
|
||||
if(opa == LV_OPA_COVER) {
|
||||
*vdb_px_p = color;
|
||||
} else {
|
||||
*vdb_px_p = lv_color_mix(color, *vdb_px_p, opa);
|
||||
}
|
||||
} else {
|
||||
#if LV_COLOR_DEPTH == 32 && LV_COLOR_SCREEN_TRANSP
|
||||
*vdb_px_p = color_mix_2_alpha(*vdb_px_p, (*vdb_px_p).ch.alpha, color, opa);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Fill an area in the Virtual Display Buffer
|
||||
* @param cords_p coordinates of the area to fill
|
||||
* @param mask_p fill only o this mask (truncated to VDB area)
|
||||
* @param color fill color
|
||||
* @param opa opacity of the area (0..255)
|
||||
*/
|
||||
void lv_draw_fill(const lv_area_t * cords_p, const lv_area_t * mask_p, lv_color_t color, lv_opa_t opa)
|
||||
{
|
||||
if(opa < LV_OPA_MIN) return;
|
||||
if(opa > LV_OPA_MAX) opa = LV_OPA_COVER;
|
||||
|
||||
lv_area_t res_a;
|
||||
bool union_ok;
|
||||
|
||||
/*Get the union of cord and mask*/
|
||||
/* The mask is already truncated to the vdb size
|
||||
* in 'lv_refr_area_with_vdb' function */
|
||||
union_ok = lv_area_intersect(&res_a, cords_p, mask_p);
|
||||
|
||||
/*If there are common part of the three area then draw to the vdb*/
|
||||
if(union_ok == false) {
|
||||
return;
|
||||
}
|
||||
|
||||
lv_disp_t * disp = lv_refr_get_disp_refreshing();
|
||||
lv_disp_buf_t * vdb = lv_disp_get_buf(disp);
|
||||
|
||||
lv_area_t vdb_rel_a; /*Stores relative coordinates on vdb*/
|
||||
vdb_rel_a.x1 = res_a.x1 - vdb->area.x1;
|
||||
vdb_rel_a.y1 = res_a.y1 - vdb->area.y1;
|
||||
vdb_rel_a.x2 = res_a.x2 - vdb->area.x1;
|
||||
vdb_rel_a.y2 = res_a.y2 - vdb->area.y1;
|
||||
|
||||
lv_color_t * vdb_buf_tmp = vdb->buf_act;
|
||||
uint32_t vdb_width = lv_area_get_width(&vdb->area);
|
||||
/*Move the vdb_tmp to the first row*/
|
||||
vdb_buf_tmp += vdb_width * vdb_rel_a.y1;
|
||||
|
||||
#if LV_USE_GPU
|
||||
static LV_ATTRIBUTE_MEM_ALIGN lv_color_t color_array_tmp[LV_HOR_RES_MAX]; /*Used by 'lv_disp_mem_blend'*/
|
||||
static lv_coord_t last_width = -1;
|
||||
|
||||
lv_coord_t w = lv_area_get_width(&vdb_rel_a);
|
||||
/*Don't use hw. acc. for every small fill (because of the init overhead)*/
|
||||
if(w < VFILL_HW_ACC_SIZE_LIMIT) {
|
||||
sw_color_fill(vdb->buf_act, vdb_width, &vdb_rel_a, color, opa);
|
||||
}
|
||||
/*Not opaque fill*/
|
||||
else if(opa == LV_OPA_COVER) {
|
||||
/*Use hw fill if present*/
|
||||
if(disp->driver.gpu_fill_cb) {
|
||||
disp->driver.gpu_fill_cb(&disp->driver, vdb->buf_act, vdb_width, &vdb_rel_a, color);
|
||||
}
|
||||
/*Use hw blend if present and the area is not too small*/
|
||||
else if(lv_area_get_height(&vdb_rel_a) > VFILL_HW_ACC_SIZE_LIMIT && disp->driver.gpu_blend_cb) {
|
||||
/*Fill a one line sized buffer with a color and blend this later*/
|
||||
if(color_array_tmp[0].full != color.full || last_width != w) {
|
||||
uint16_t i;
|
||||
for(i = 0; i < w; i++) {
|
||||
color_array_tmp[i].full = color.full;
|
||||
}
|
||||
last_width = w;
|
||||
}
|
||||
|
||||
/*Blend the filled line to every line VDB line-by-line*/
|
||||
lv_coord_t row;
|
||||
for(row = vdb_rel_a.y1; row <= vdb_rel_a.y2; row++) {
|
||||
disp->driver.gpu_blend_cb(&disp->driver, &vdb_buf_tmp[vdb_rel_a.x1], color_array_tmp, w, opa);
|
||||
vdb_buf_tmp += vdb_width;
|
||||
}
|
||||
|
||||
}
|
||||
/*Else use sw fill if no better option*/
|
||||
else {
|
||||
sw_color_fill(vdb->buf_act, vdb_width, &vdb_rel_a, color, opa);
|
||||
}
|
||||
|
||||
}
|
||||
/*Fill with opacity*/
|
||||
else {
|
||||
/*Use hw blend if present*/
|
||||
if(disp->driver.gpu_blend_cb) {
|
||||
if(color_array_tmp[0].full != color.full || last_width != w) {
|
||||
uint16_t i;
|
||||
for(i = 0; i < w; i++) {
|
||||
color_array_tmp[i].full = color.full;
|
||||
}
|
||||
|
||||
last_width = w;
|
||||
}
|
||||
lv_coord_t row;
|
||||
for(row = vdb_rel_a.y1; row <= vdb_rel_a.y2; row++) {
|
||||
disp->driver.gpu_blend_cb(&disp->driver, &vdb_buf_tmp[vdb_rel_a.x1], color_array_tmp, w, opa);
|
||||
vdb_buf_tmp += vdb_width;
|
||||
}
|
||||
|
||||
}
|
||||
/*Use sw fill with opa if no better option*/
|
||||
else {
|
||||
sw_color_fill(vdb->buf_act, vdb_width, &vdb_rel_a, color, opa);
|
||||
}
|
||||
}
|
||||
#else
|
||||
sw_color_fill(vdb->buf_act, vdb_width, &vdb_rel_a, color, opa);
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* Draw a letter in the Virtual Display Buffer
|
||||
* @param pos_p left-top coordinate of the latter
|
||||
* @param mask_p the letter will be drawn only on this area (truncated to VDB area)
|
||||
* @param font_p pointer to font
|
||||
* @param letter a letter to draw
|
||||
* @param color color of letter
|
||||
* @param opa opacity of letter (0..255)
|
||||
*/
|
||||
void lv_draw_letter(const lv_point_t * pos_p, const lv_area_t * mask_p, const lv_font_t * font_p, uint32_t letter,
|
||||
lv_color_t color, lv_opa_t opa)
|
||||
{
|
||||
/*clang-format off*/
|
||||
const uint8_t bpp1_opa_table[2] = {0, 255}; /*Opacity mapping with bpp = 1 (Just for compatibility)*/
|
||||
const uint8_t bpp2_opa_table[4] = {0, 85, 170, 255}; /*Opacity mapping with bpp = 2*/
|
||||
const uint8_t bpp4_opa_table[16] = {0, 17, 34, 51, /*Opacity mapping with bpp = 4*/
|
||||
68, 85, 102, 119, 136, 153, 170, 187, 204, 221, 238, 255};
|
||||
/*clang-format on*/
|
||||
|
||||
if(opa < LV_OPA_MIN) return;
|
||||
if(opa > LV_OPA_MAX) opa = LV_OPA_COVER;
|
||||
|
||||
if(font_p == NULL) {
|
||||
LV_LOG_WARN("Font: character's bitmap not found");
|
||||
return;
|
||||
}
|
||||
|
||||
lv_font_glyph_dsc_t g;
|
||||
bool g_ret = lv_font_get_glyph_dsc(font_p, &g, letter, '\0');
|
||||
if(g_ret == false) return;
|
||||
|
||||
|
||||
lv_coord_t pos_x = pos_p->x + g.ofs_x;
|
||||
lv_coord_t pos_y = pos_p->y + (font_p->line_height - font_p->base_line) - g.box_h - g.ofs_y;
|
||||
|
||||
const uint8_t * bpp_opa_table;
|
||||
uint8_t bitmask_init;
|
||||
uint8_t bitmask;
|
||||
|
||||
/*bpp = 3 should be converted to bpp = 4 in lv_font_get_glyph_bitmap */
|
||||
if(g.bpp == 3) g.bpp = 4;
|
||||
|
||||
switch(g.bpp) {
|
||||
case 1:
|
||||
bpp_opa_table = bpp1_opa_table;
|
||||
bitmask_init = 0x80;
|
||||
break;
|
||||
case 2:
|
||||
bpp_opa_table = bpp2_opa_table;
|
||||
bitmask_init = 0xC0;
|
||||
break;
|
||||
case 4:
|
||||
bpp_opa_table = bpp4_opa_table;
|
||||
bitmask_init = 0xF0;
|
||||
break;
|
||||
case 8:
|
||||
bpp_opa_table = NULL;
|
||||
bitmask_init = 0xFF;
|
||||
break; /*No opa table, pixel value will be used directly*/
|
||||
default: return; /*Invalid bpp. Can't render the letter*/
|
||||
}
|
||||
|
||||
const uint8_t * map_p = lv_font_get_glyph_bitmap(font_p, letter);
|
||||
|
||||
if(map_p == NULL) return;
|
||||
|
||||
/*If the letter is completely out of mask don't draw it */
|
||||
if(pos_x + g.box_w < mask_p->x1 || pos_x > mask_p->x2 || pos_y + g.box_h < mask_p->y1 || pos_y > mask_p->y2) return;
|
||||
|
||||
lv_disp_t * disp = lv_refr_get_disp_refreshing();
|
||||
lv_disp_buf_t * vdb = lv_disp_get_buf(disp);
|
||||
|
||||
lv_coord_t vdb_width = lv_area_get_width(&vdb->area);
|
||||
lv_color_t * vdb_buf_tmp = vdb->buf_act;
|
||||
lv_coord_t col, row;
|
||||
|
||||
uint8_t width_byte_scr = g.box_w >> 3; /*Width in bytes (on the screen finally) (e.g. w = 11 -> 2 bytes wide)*/
|
||||
if(g.box_w & 0x7) width_byte_scr++;
|
||||
uint16_t width_bit = g.box_w * g.bpp; /*Letter width in bits*/
|
||||
|
||||
bool subpx = font_p->subpx == LV_FONT_SUBPX_NONE ? false : true;
|
||||
|
||||
/* Calculate the col/row start/end on the map*/
|
||||
lv_coord_t col_start;
|
||||
lv_coord_t col_end;
|
||||
lv_coord_t row_start;
|
||||
lv_coord_t row_end;
|
||||
|
||||
if(subpx == false) {
|
||||
col_start = pos_x >= mask_p->x1 ? 0 : mask_p->x1 - pos_x;
|
||||
col_end = pos_x + g.box_w <= mask_p->x2 ? g.box_w : mask_p->x2 - pos_x + 1;
|
||||
row_start = pos_y >= mask_p->y1 ? 0 : mask_p->y1 - pos_y;
|
||||
row_end = pos_y + g.box_h <= mask_p->y2 ? g.box_h : mask_p->y2 - pos_y + 1;
|
||||
} else {
|
||||
col_start = pos_x >= mask_p->x1 ? 0 : (mask_p->x1 - pos_x) * 3;
|
||||
col_end = pos_x + g.box_w / 3 <= mask_p->x2 ? g.box_w : (mask_p->x2 - pos_x + 1) * 3;
|
||||
row_start = pos_y >= mask_p->y1 ? 0 : mask_p->y1 - pos_y;
|
||||
row_end = pos_y + g.box_h <= mask_p->y2 ? g.box_h : mask_p->y2 - pos_y + 1;
|
||||
}
|
||||
|
||||
/*Set a pointer on VDB to the first pixel of the letter*/
|
||||
vdb_buf_tmp += ((pos_y - vdb->area.y1) * vdb_width) + pos_x - vdb->area.x1;
|
||||
|
||||
/*If the letter is partially out of mask the move there on VDB*/
|
||||
if(subpx) vdb_buf_tmp += (row_start * vdb_width) + col_start / 3;
|
||||
else vdb_buf_tmp += (row_start * vdb_width) + col_start;
|
||||
|
||||
/*Move on the map too*/
|
||||
uint32_t bit_ofs = (row_start * width_bit) + (col_start * g.bpp);
|
||||
map_p += bit_ofs >> 3;
|
||||
|
||||
uint8_t letter_px;
|
||||
lv_opa_t px_opa = 0;
|
||||
uint16_t col_bit;
|
||||
col_bit = bit_ofs & 0x7; /* "& 0x7" equals to "% 8" just faster */
|
||||
|
||||
bool scr_transp = false;
|
||||
#if LV_COLOR_DEPTH == 32 && LV_COLOR_SCREEN_TRANSP
|
||||
scr_transp = disp->driver.screen_transp;
|
||||
#endif
|
||||
|
||||
uint8_t font_rgb[3];
|
||||
uint8_t txt_rgb[3] = {LV_COLOR_GET_R(color), LV_COLOR_GET_G(color), LV_COLOR_GET_B(color)};
|
||||
|
||||
for(row = row_start; row < row_end; row++) {
|
||||
bitmask = bitmask_init >> col_bit;
|
||||
uint8_t sub_px_cnt = 0;
|
||||
for(col = col_start; col < col_end; col++) {
|
||||
letter_px = (*map_p & bitmask) >> (8 - col_bit - g.bpp);
|
||||
|
||||
/*subpx == 0*/
|
||||
if(subpx == false) {
|
||||
if(letter_px != 0) {
|
||||
if(opa == LV_OPA_COVER) {
|
||||
px_opa = g.bpp == 8 ? letter_px : bpp_opa_table[letter_px];
|
||||
} else {
|
||||
px_opa = g.bpp == 8 ? (uint16_t)((uint16_t)letter_px * opa) >> 8
|
||||
: (uint16_t)((uint16_t)bpp_opa_table[letter_px] * opa) >> 8;
|
||||
}
|
||||
|
||||
if(disp->driver.set_px_cb) {
|
||||
disp->driver.set_px_cb(&disp->driver, (uint8_t *)vdb->buf_act, vdb_width,
|
||||
(col + pos_x) - vdb->area.x1, (row + pos_y) - vdb->area.y1, color, px_opa);
|
||||
} else if(vdb_buf_tmp->full != color.full) {
|
||||
if(px_opa > LV_OPA_MAX) {
|
||||
*vdb_buf_tmp = color;
|
||||
} else if(px_opa > LV_OPA_MIN) {
|
||||
if(scr_transp == false) {
|
||||
*vdb_buf_tmp = lv_color_mix(color, *vdb_buf_tmp, px_opa);
|
||||
} else {
|
||||
#if LV_COLOR_DEPTH == 32 && LV_COLOR_SCREEN_TRANSP
|
||||
*vdb_buf_tmp = color_mix_2_alpha(*vdb_buf_tmp, (*vdb_buf_tmp).ch.alpha, color, px_opa);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
vdb_buf_tmp++;
|
||||
}
|
||||
/*Handle subpx drawing*/
|
||||
else {
|
||||
if(letter_px != 0) {
|
||||
if(opa == LV_OPA_COVER) {
|
||||
px_opa = g.bpp == 8 ? letter_px : bpp_opa_table[letter_px];
|
||||
} else {
|
||||
px_opa = g.bpp == 8 ? (uint16_t)((uint16_t)letter_px * opa) >> 8
|
||||
: (uint16_t)((uint16_t)bpp_opa_table[letter_px] * opa) >> 8;
|
||||
}
|
||||
|
||||
font_rgb[sub_px_cnt] = px_opa;
|
||||
} else {
|
||||
font_rgb[sub_px_cnt] = 0;
|
||||
}
|
||||
sub_px_cnt ++;
|
||||
|
||||
if(sub_px_cnt == 3) {
|
||||
lv_color_t res_color;
|
||||
|
||||
if(font_rgb[0] == 0 && font_rgb[1] == 0 && font_rgb[2] == 0) {
|
||||
res_color = *vdb_buf_tmp;
|
||||
} else {
|
||||
|
||||
uint8_t bg_rgb[3] = {LV_COLOR_GET_R(*vdb_buf_tmp), LV_COLOR_GET_G(*vdb_buf_tmp), LV_COLOR_GET_B(*vdb_buf_tmp)};
|
||||
|
||||
#if LV_FONT_SUBPX_BGR
|
||||
LV_COLOR_SET_B(res_color, (uint16_t)((uint16_t)txt_rgb[0] * font_rgb[0] + (bg_rgb[2] * (255 - font_rgb[0]))) >> 8);
|
||||
LV_COLOR_SET_R(res_color, (uint16_t)((uint16_t)txt_rgb[2] * font_rgb[2] + (bg_rgb[0] * (255 - font_rgb[2]))) >> 8);
|
||||
#else
|
||||
LV_COLOR_SET_R(res_color, (uint16_t)((uint16_t)txt_rgb[0] * font_rgb[0] + (bg_rgb[0] * (255 - font_rgb[0]))) >> 8);
|
||||
LV_COLOR_SET_B(res_color, (uint16_t)((uint16_t)txt_rgb[2] * font_rgb[2] + (bg_rgb[2] * (255 - font_rgb[2]))) >> 8);
|
||||
#endif
|
||||
LV_COLOR_SET_G(res_color, (uint16_t)((uint16_t)txt_rgb[1] * font_rgb[1] + (bg_rgb[1] * (255 - font_rgb[1]))) >> 8);
|
||||
}
|
||||
if(scr_transp == false) {
|
||||
vdb_buf_tmp->full = res_color.full;
|
||||
#if LV_COLOR_DEPTH == 32 && LV_COLOR_SCREEN_TRANSP
|
||||
} else {
|
||||
*vdb_buf_tmp = color_mix_2_alpha(*vdb_buf_tmp, (*vdb_buf_tmp).ch.alpha, color, px_opa);
|
||||
#endif
|
||||
}
|
||||
sub_px_cnt = 0;
|
||||
vdb_buf_tmp++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if(col_bit < 8 - g.bpp) {
|
||||
col_bit += g.bpp;
|
||||
bitmask = bitmask >> g.bpp;
|
||||
} else {
|
||||
col_bit = 0;
|
||||
bitmask = bitmask_init;
|
||||
map_p++;
|
||||
}
|
||||
}
|
||||
|
||||
col_bit += ((g.box_w - col_end) + col_start) * g.bpp;
|
||||
|
||||
map_p += (col_bit >> 3);
|
||||
col_bit = col_bit & 0x7;
|
||||
|
||||
/*Next row in VDB*/
|
||||
if(subpx) vdb_buf_tmp += vdb_width - (col_end - col_start) / 3;
|
||||
else vdb_buf_tmp += vdb_width - (col_end - col_start);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Draw a color map to the display (image)
|
||||
* @param cords_p coordinates the color map
|
||||
* @param mask_p the map will drawn only on this area (truncated to VDB area)
|
||||
* @param map_p pointer to a lv_color_t array
|
||||
* @param opa opacity of the map
|
||||
* @param chroma_keyed true: enable transparency of LV_IMG_LV_COLOR_TRANSP color pixels
|
||||
* @param alpha_byte true: extra alpha byte is inserted for every pixel
|
||||
* @param recolor mix the pixels with this color
|
||||
* @param recolor_opa the intense of recoloring
|
||||
*/
|
||||
void lv_draw_map(const lv_area_t * cords_p, const lv_area_t * mask_p, const uint8_t * map_p, lv_opa_t opa,
|
||||
bool chroma_key, bool alpha_byte, lv_color_t recolor, lv_opa_t recolor_opa)
|
||||
{
|
||||
|
||||
if(opa < LV_OPA_MIN) return;
|
||||
if(opa > LV_OPA_MAX) opa = LV_OPA_COVER;
|
||||
|
||||
lv_area_t masked_a;
|
||||
bool union_ok;
|
||||
|
||||
/*Get the union of map size and mask*/
|
||||
/* The mask is already truncated to the vdb size
|
||||
* in 'lv_refr_area_with_vdb' function */
|
||||
union_ok = lv_area_intersect(&masked_a, cords_p, mask_p);
|
||||
|
||||
/*If there are common part of the three area then draw to the vdb*/
|
||||
if(union_ok == false) return;
|
||||
|
||||
/*The pixel size in byte is different if an alpha byte is added too*/
|
||||
uint8_t px_size_byte = alpha_byte ? LV_IMG_PX_SIZE_ALPHA_BYTE : sizeof(lv_color_t);
|
||||
|
||||
/*If the map starts OUT of the masked area then calc. the first pixel*/
|
||||
lv_coord_t map_width = lv_area_get_width(cords_p);
|
||||
if(cords_p->y1 < masked_a.y1) {
|
||||
map_p += (uint32_t)map_width * ((masked_a.y1 - cords_p->y1)) * px_size_byte;
|
||||
}
|
||||
if(cords_p->x1 < masked_a.x1) {
|
||||
map_p += (masked_a.x1 - cords_p->x1) * px_size_byte;
|
||||
}
|
||||
|
||||
lv_disp_t * disp = lv_refr_get_disp_refreshing();
|
||||
lv_disp_buf_t * vdb = lv_disp_get_buf(disp);
|
||||
|
||||
/*Stores coordinates relative to the current VDB*/
|
||||
masked_a.x1 = masked_a.x1 - vdb->area.x1;
|
||||
masked_a.y1 = masked_a.y1 - vdb->area.y1;
|
||||
masked_a.x2 = masked_a.x2 - vdb->area.x1;
|
||||
masked_a.y2 = masked_a.y2 - vdb->area.y1;
|
||||
|
||||
lv_coord_t vdb_width = lv_area_get_width(&vdb->area);
|
||||
lv_color_t * vdb_buf_tmp = vdb->buf_act;
|
||||
vdb_buf_tmp += (uint32_t)vdb_width * masked_a.y1; /*Move to the first row*/
|
||||
vdb_buf_tmp += (uint32_t)masked_a.x1; /*Move to the first col*/
|
||||
|
||||
lv_coord_t row;
|
||||
lv_coord_t map_useful_w = lv_area_get_width(&masked_a);
|
||||
|
||||
bool scr_transp = false;
|
||||
#if LV_COLOR_DEPTH == 32 && LV_COLOR_SCREEN_TRANSP
|
||||
scr_transp = disp->driver.screen_transp;
|
||||
#endif
|
||||
|
||||
/*The simplest case just copy the pixels into the VDB*/
|
||||
if(chroma_key == false && alpha_byte == false && opa == LV_OPA_COVER && recolor_opa == LV_OPA_TRANSP) {
|
||||
|
||||
/*Use the custom VDB write function is exists*/
|
||||
if(disp->driver.set_px_cb) {
|
||||
lv_coord_t col;
|
||||
for(row = masked_a.y1; row <= masked_a.y2; row++) {
|
||||
for(col = 0; col < map_useful_w; col++) {
|
||||
lv_color_t px_color = *((lv_color_t *)&map_p[(uint32_t)col * px_size_byte]);
|
||||
disp->driver.set_px_cb(&disp->driver, (uint8_t *)vdb->buf_act, vdb_width, col + masked_a.x1, row,
|
||||
px_color, opa);
|
||||
}
|
||||
map_p += map_width * px_size_byte; /*Next row on the map*/
|
||||
}
|
||||
}
|
||||
/*Normal native VDB*/
|
||||
else {
|
||||
for(row = masked_a.y1; row <= masked_a.y2; row++) {
|
||||
#if LV_USE_GPU
|
||||
if(disp->driver.gpu_blend_cb == false) {
|
||||
sw_mem_blend(vdb_buf_tmp, (lv_color_t *)map_p, map_useful_w, opa);
|
||||
} else {
|
||||
disp->driver.gpu_blend_cb(&disp->driver, vdb_buf_tmp, (lv_color_t *)map_p, map_useful_w, opa);
|
||||
}
|
||||
#else
|
||||
sw_mem_blend(vdb_buf_tmp, (lv_color_t *)map_p, map_useful_w, opa);
|
||||
#endif
|
||||
map_p += map_width * px_size_byte; /*Next row on the map*/
|
||||
vdb_buf_tmp += vdb_width; /*Next row on the VDB*/
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*In the other cases every pixel need to be checked one-by-one*/
|
||||
else {
|
||||
|
||||
lv_coord_t col;
|
||||
lv_color_t last_img_px = LV_COLOR_BLACK;
|
||||
lv_color_t recolored_px = lv_color_mix(recolor, last_img_px, recolor_opa);
|
||||
for(row = masked_a.y1; row <= masked_a.y2; row++) {
|
||||
for(col = 0; col < map_useful_w; col++) {
|
||||
lv_opa_t opa_result = opa;
|
||||
uint8_t * px_color_p = (uint8_t *)&map_p[(uint32_t)col * px_size_byte];
|
||||
lv_color_t px_color;
|
||||
|
||||
/*Calculate with the pixel level alpha*/
|
||||
if(alpha_byte) {
|
||||
#if LV_COLOR_DEPTH == 8 || LV_COLOR_DEPTH == 1
|
||||
px_color.full = px_color_p[0];
|
||||
#elif LV_COLOR_DEPTH == 16
|
||||
/*Because of Alpha byte 16 bit color can start on odd address which can cause
|
||||
* crash*/
|
||||
px_color.full = px_color_p[0] + (px_color_p[1] << 8);
|
||||
#elif LV_COLOR_DEPTH == 32
|
||||
px_color = *((lv_color_t *)px_color_p);
|
||||
#endif
|
||||
lv_opa_t px_opa = *(px_color_p + LV_IMG_PX_SIZE_ALPHA_BYTE - 1);
|
||||
if(px_opa == LV_OPA_TRANSP)
|
||||
continue;
|
||||
else if(px_opa != LV_OPA_COVER)
|
||||
opa_result = (uint32_t)((uint32_t)px_opa * opa_result) >> 8;
|
||||
} else {
|
||||
px_color = *((lv_color_t *)px_color_p);
|
||||
}
|
||||
|
||||
/*Handle chroma key*/
|
||||
if(chroma_key && px_color.full == disp->driver.color_chroma_key.full) continue;
|
||||
|
||||
/*Re-color the pixel if required*/
|
||||
if(recolor_opa != LV_OPA_TRANSP) {
|
||||
if(last_img_px.full != px_color.full) { /*Minor acceleration: calculate only for
|
||||
new colors (save the last)*/
|
||||
last_img_px = px_color;
|
||||
recolored_px = lv_color_mix(recolor, last_img_px, recolor_opa);
|
||||
}
|
||||
/*Handle custom VDB write is present*/
|
||||
if(disp->driver.set_px_cb) {
|
||||
disp->driver.set_px_cb(&disp->driver, (uint8_t *)vdb->buf_act, vdb_width, col + masked_a.x1,
|
||||
row, recolored_px, opa_result);
|
||||
}
|
||||
/*Normal native VDB write*/
|
||||
else {
|
||||
if(opa_result == LV_OPA_COVER)
|
||||
vdb_buf_tmp[col].full = recolored_px.full;
|
||||
else
|
||||
vdb_buf_tmp[col] = lv_color_mix(recolored_px, vdb_buf_tmp[col], opa_result);
|
||||
}
|
||||
} else {
|
||||
/*Handle custom VDB write is present*/
|
||||
if(disp->driver.set_px_cb) {
|
||||
disp->driver.set_px_cb(&disp->driver, (uint8_t *)vdb->buf_act, vdb_width, col + masked_a.x1,
|
||||
row, px_color, opa_result);
|
||||
}
|
||||
/*Normal native VDB write*/
|
||||
else {
|
||||
|
||||
if(opa_result == LV_OPA_COVER)
|
||||
vdb_buf_tmp[col] = px_color;
|
||||
else {
|
||||
if(scr_transp == false) {
|
||||
vdb_buf_tmp[col] = lv_color_mix(px_color, vdb_buf_tmp[col], opa_result);
|
||||
} else {
|
||||
#if LV_COLOR_DEPTH == 32 && LV_COLOR_SCREEN_TRANSP
|
||||
vdb_buf_tmp[col] = color_mix_2_alpha(vdb_buf_tmp[col], vdb_buf_tmp[col].ch.alpha,
|
||||
px_color, opa_result);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
map_p += map_width * px_size_byte; /*Next row on the map*/
|
||||
vdb_buf_tmp += vdb_width; /*Next row on the VDB*/
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Blend pixels to destination memory using opacity
|
||||
* @param dest a memory address. Copy 'src' here.
|
||||
* @param src pointer to pixel map. Copy it to 'dest'.
|
||||
* @param length number of pixels in 'src'
|
||||
* @param opa opacity (0, LV_OPA_TRANSP: transparent ... 255, LV_OPA_COVER, fully cover)
|
||||
*/
|
||||
static void sw_mem_blend(lv_color_t * dest, const lv_color_t * src, uint32_t length, lv_opa_t opa)
|
||||
{
|
||||
if(opa == LV_OPA_COVER) {
|
||||
memcpy(dest, src, length * sizeof(lv_color_t));
|
||||
} else {
|
||||
uint32_t col;
|
||||
for(col = 0; col < length; col++) {
|
||||
dest[col] = lv_color_mix(src[col], dest[col], opa);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Fill an area with a color
|
||||
* @param mem a memory address. Considered to a rectangular window according to 'mem_area'
|
||||
* @param mem_width width of the 'mem' buffer
|
||||
* @param fill_area coordinates of an area to fill. Relative to 'mem_area'.
|
||||
* @param color fill color
|
||||
* @param opa opacity (0, LV_OPA_TRANSP: transparent ... 255, LV_OPA_COVER, fully cover)
|
||||
*/
|
||||
static void sw_color_fill(lv_color_t * mem, lv_coord_t mem_width, const lv_area_t * fill_area, lv_color_t color,
|
||||
lv_opa_t opa)
|
||||
{
|
||||
/*Set all row in vdb to the given color*/
|
||||
lv_coord_t row;
|
||||
lv_coord_t col;
|
||||
|
||||
lv_disp_t * disp = lv_refr_get_disp_refreshing();
|
||||
if(disp->driver.set_px_cb) {
|
||||
for(col = fill_area->x1; col <= fill_area->x2; col++) {
|
||||
for(row = fill_area->y1; row <= fill_area->y2; row++) {
|
||||
disp->driver.set_px_cb(&disp->driver, (uint8_t *)mem, mem_width, col, row, color, opa);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
mem += fill_area->y1 * mem_width; /*Go to the first row*/
|
||||
|
||||
/*Run simpler function without opacity*/
|
||||
if(opa == LV_OPA_COVER) {
|
||||
|
||||
/*Fill the first row with 'color'*/
|
||||
for(col = fill_area->x1; col <= fill_area->x2; col++) {
|
||||
mem[col] = color;
|
||||
}
|
||||
|
||||
/*Copy the first row to all other rows*/
|
||||
lv_color_t * mem_first = &mem[fill_area->x1];
|
||||
lv_coord_t copy_size = (fill_area->x2 - fill_area->x1 + 1) * sizeof(lv_color_t);
|
||||
mem += mem_width;
|
||||
|
||||
for(row = fill_area->y1 + 1; row <= fill_area->y2; row++) {
|
||||
memcpy(&mem[fill_area->x1], mem_first, copy_size);
|
||||
mem += mem_width;
|
||||
}
|
||||
}
|
||||
/*Calculate with alpha too*/
|
||||
else {
|
||||
bool scr_transp = false;
|
||||
#if LV_COLOR_DEPTH == 32 && LV_COLOR_SCREEN_TRANSP
|
||||
scr_transp = disp->driver.screen_transp;
|
||||
#endif
|
||||
|
||||
lv_color_t bg_tmp = LV_COLOR_BLACK;
|
||||
lv_color_t opa_tmp = lv_color_mix(color, bg_tmp, opa);
|
||||
for(row = fill_area->y1; row <= fill_area->y2; row++) {
|
||||
for(col = fill_area->x1; col <= fill_area->x2; col++) {
|
||||
if(scr_transp == false) {
|
||||
/*If the bg color changed recalculate the result color*/
|
||||
if(mem[col].full != bg_tmp.full) {
|
||||
bg_tmp = mem[col];
|
||||
opa_tmp = lv_color_mix(color, bg_tmp, opa);
|
||||
}
|
||||
|
||||
mem[col] = opa_tmp;
|
||||
|
||||
} else {
|
||||
#if LV_COLOR_DEPTH == 32 && LV_COLOR_SCREEN_TRANSP
|
||||
mem[col] = color_mix_2_alpha(mem[col], mem[col].ch.alpha, color, opa);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
mem += mem_width;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#if LV_COLOR_DEPTH == 32 && LV_COLOR_SCREEN_TRANSP
|
||||
/**
|
||||
* Mix two colors. Both color can have alpha value. It requires ARGB888 colors.
|
||||
* @param bg_color background color
|
||||
* @param bg_opa alpha of the background color
|
||||
* @param fg_color foreground color
|
||||
* @param fg_opa alpha of the foreground color
|
||||
* @return the mixed color. the alpha channel (color.alpha) contains the result alpha
|
||||
*/
|
||||
static inline lv_color_t color_mix_2_alpha(lv_color_t bg_color, lv_opa_t bg_opa, lv_color_t fg_color, lv_opa_t fg_opa)
|
||||
{
|
||||
/* Pick the foreground if it's fully opaque or the Background is fully transparent*/
|
||||
if(fg_opa > LV_OPA_MAX || bg_opa <= LV_OPA_MIN) {
|
||||
fg_color.ch.alpha = fg_opa;
|
||||
return fg_color;
|
||||
}
|
||||
/*Transparent foreground: use the Background*/
|
||||
else if(fg_opa <= LV_OPA_MIN) {
|
||||
return bg_color;
|
||||
}
|
||||
/*Opaque background: use simple mix*/
|
||||
else if(bg_opa >= LV_OPA_MAX) {
|
||||
return lv_color_mix(fg_color, bg_color, fg_opa);
|
||||
}
|
||||
/*Both colors have alpha. Expensive calculation need to be applied*/
|
||||
else {
|
||||
/*Save the parameters and the result. If they will be asked again don't compute again*/
|
||||
static lv_opa_t fg_opa_save = 0;
|
||||
static lv_opa_t bg_opa_save = 0;
|
||||
static lv_color_t fg_color_save = {{0}};
|
||||
static lv_color_t bg_color_save = {{0}};
|
||||
static lv_color_t c = {{0}};
|
||||
|
||||
if(fg_opa != fg_opa_save || bg_opa != bg_opa_save || fg_color.full != fg_color_save.full ||
|
||||
bg_color.full != bg_color_save.full) {
|
||||
fg_opa_save = fg_opa;
|
||||
bg_opa_save = bg_opa;
|
||||
fg_color_save.full = fg_color.full;
|
||||
bg_color_save.full = bg_color.full;
|
||||
/*Info:
|
||||
* https://en.wikipedia.org/wiki/Alpha_compositing#Analytical_derivation_of_the_over_operator*/
|
||||
lv_opa_t alpha_res = 255 - ((uint16_t)((uint16_t)(255 - fg_opa) * (255 - bg_opa)) >> 8);
|
||||
if(alpha_res == 0) {
|
||||
while(1)
|
||||
;
|
||||
}
|
||||
lv_opa_t ratio = (uint16_t)((uint16_t)fg_opa * 255) / alpha_res;
|
||||
c = lv_color_mix(fg_color, bg_color, ratio);
|
||||
c.ch.alpha = alpha_res;
|
||||
}
|
||||
return c;
|
||||
}
|
||||
}
|
||||
#endif
|
@ -1,82 +0,0 @@
|
||||
/**
|
||||
* @file lv_draw_basic.h
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LV_DRAW_BASIC_H
|
||||
#define LV_DRAW_BASIC_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#ifdef LV_CONF_INCLUDE_SIMPLE
|
||||
#include "lv_conf.h"
|
||||
#else
|
||||
#include "../../../lv_conf.h"
|
||||
#endif
|
||||
|
||||
#include "../lv_font/lv_font.h"
|
||||
#include "../lv_misc/lv_color.h"
|
||||
#include "../lv_misc/lv_area.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
|
||||
void lv_draw_px(lv_coord_t x, lv_coord_t y, const lv_area_t * mask_p, lv_color_t color, lv_opa_t opa);
|
||||
/**
|
||||
* Fill an area in the Virtual Display Buffer
|
||||
* @param cords_p coordinates of the area to fill
|
||||
* @param mask_p fill only o this mask
|
||||
* @param color fill color
|
||||
* @param opa opacity of the area (0..255)
|
||||
*/
|
||||
void lv_draw_fill(const lv_area_t * cords_p, const lv_area_t * mask_p, lv_color_t color, lv_opa_t opa);
|
||||
|
||||
/**
|
||||
* Draw a letter in the Virtual Display Buffer
|
||||
* @param pos_p left-top coordinate of the latter
|
||||
* @param mask_p the letter will be drawn only on this area
|
||||
* @param font_p pointer to font
|
||||
* @param letter a letter to draw
|
||||
* @param color color of letter
|
||||
* @param opa opacity of letter (0..255)
|
||||
*/
|
||||
void lv_draw_letter(const lv_point_t * pos_p, const lv_area_t * mask_p, const lv_font_t * font_p, uint32_t letter,
|
||||
lv_color_t color, lv_opa_t opa);
|
||||
|
||||
/**
|
||||
* Draw a color map to the display (image)
|
||||
* @param cords_p coordinates the color map
|
||||
* @param mask_p the map will drawn only on this area (truncated to VDB area)
|
||||
* @param map_p pointer to a lv_color_t array
|
||||
* @param opa opacity of the map
|
||||
* @param chroma_keyed true: enable transparency of LV_IMG_LV_COLOR_TRANSP color pixels
|
||||
* @param alpha_byte true: extra alpha byte is inserted for every pixel
|
||||
* @param recolor mix the pixels with this color
|
||||
* @param recolor_opa the intense of recoloring
|
||||
*/
|
||||
void lv_draw_map(const lv_area_t * cords_p, const lv_area_t * mask_p, const uint8_t * map_p, lv_opa_t opa,
|
||||
bool chroma_key, bool alpha_byte, lv_color_t recolor, lv_opa_t recolor_opa);
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif /*LV_DRAW_BASIC_H*/
|
@ -1,601 +0,0 @@
|
||||
/**
|
||||
* @file lv_draw_img.c
|
||||
*
|
||||
*/
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "lv_draw_img.h"
|
||||
#include "lv_img_cache.h"
|
||||
#include "../lv_misc/lv_log.h"
|
||||
#include "../lv_misc/lv_mem.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
static lv_res_t lv_img_draw_core(const lv_area_t * coords, const lv_area_t * mask, const void * src,
|
||||
const lv_style_t * style, lv_opa_t opa_scale);
|
||||
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL FUNCTIONS
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Draw an image
|
||||
* @param coords the coordinates of the image
|
||||
* @param mask the image will be drawn only in this area
|
||||
* @param src pointer to a lv_color_t array which contains the pixels of the image
|
||||
* @param style style of the image
|
||||
* @param opa_scale scale down all opacities by the factor
|
||||
*/
|
||||
void lv_draw_img(const lv_area_t * coords, const lv_area_t * mask, const void * src, const lv_style_t * style,
|
||||
lv_opa_t opa_scale)
|
||||
{
|
||||
if(src == NULL) {
|
||||
LV_LOG_WARN("Image draw: src is NULL");
|
||||
lv_draw_rect(coords, mask, &lv_style_plain, LV_OPA_COVER);
|
||||
lv_draw_label(coords, mask, &lv_style_plain, LV_OPA_COVER, "No\ndata", LV_TXT_FLAG_NONE, NULL, NULL, NULL, LV_BIDI_DIR_LTR);
|
||||
return;
|
||||
}
|
||||
|
||||
lv_res_t res;
|
||||
res = lv_img_draw_core(coords, mask, src, style, opa_scale);
|
||||
|
||||
if(res == LV_RES_INV) {
|
||||
LV_LOG_WARN("Image draw error");
|
||||
lv_draw_rect(coords, mask, &lv_style_plain, LV_OPA_COVER);
|
||||
lv_draw_label(coords, mask, &lv_style_plain, LV_OPA_COVER, "No\ndata", LV_TXT_FLAG_NONE, NULL, NULL, NULL, LV_BIDI_DIR_LTR);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the color of an image's pixel
|
||||
* @param dsc an image descriptor
|
||||
* @param x x coordinate of the point to get
|
||||
* @param y x coordinate of the point to get
|
||||
* @param style style of the image. In case of `LV_IMG_CF_ALPHA_1/2/4/8` `style->image.color` shows
|
||||
* the color. Can be `NULL` but for `ALPHA` images black will be returned. In other cases it is not
|
||||
* used.
|
||||
* @return color of the point
|
||||
*/
|
||||
lv_color_t lv_img_buf_get_px_color(lv_img_dsc_t * dsc, lv_coord_t x, lv_coord_t y, const lv_style_t * style)
|
||||
{
|
||||
lv_color_t p_color = LV_COLOR_BLACK;
|
||||
if(x >= (lv_coord_t)dsc->header.w) {
|
||||
x = dsc->header.w - 1;
|
||||
LV_LOG_WARN("lv_canvas_get_px: x is too large (out of canvas)");
|
||||
} else if(x < 0) {
|
||||
x = 0;
|
||||
LV_LOG_WARN("lv_canvas_get_px: x is < 0 (out of canvas)");
|
||||
}
|
||||
|
||||
if(y >= (lv_coord_t)dsc->header.h) {
|
||||
y = dsc->header.h - 1;
|
||||
LV_LOG_WARN("lv_canvas_get_px: y is too large (out of canvas)");
|
||||
} else if(y < 0) {
|
||||
y = 0;
|
||||
LV_LOG_WARN("lv_canvas_get_px: y is < 0 (out of canvas)");
|
||||
}
|
||||
|
||||
uint8_t * buf_u8 = (uint8_t *)dsc->data;
|
||||
|
||||
if(dsc->header.cf == LV_IMG_CF_TRUE_COLOR || dsc->header.cf == LV_IMG_CF_TRUE_COLOR_CHROMA_KEYED ||
|
||||
dsc->header.cf == LV_IMG_CF_TRUE_COLOR_ALPHA) {
|
||||
uint8_t px_size = lv_img_color_format_get_px_size(dsc->header.cf) >> 3;
|
||||
uint32_t px = dsc->header.w * y * px_size + x * px_size;
|
||||
memcpy(&p_color, &buf_u8[px], sizeof(lv_color_t));
|
||||
#if LV_COLOR_SIZE == 32
|
||||
p_color.ch.alpha = 0xFF; /*Only the color should be get so use a deafult alpha value*/
|
||||
#endif
|
||||
} else if(dsc->header.cf == LV_IMG_CF_INDEXED_1BIT) {
|
||||
buf_u8 += 4 * 2;
|
||||
uint8_t bit = x & 0x7;
|
||||
x = x >> 3;
|
||||
|
||||
/* Get the current pixel.
|
||||
* dsc->header.w + 7 means rounding up to 8 because the lines are byte aligned
|
||||
* so the possible real width are 8, 16, 24 ...*/
|
||||
uint32_t px = ((dsc->header.w + 7) >> 3) * y + x;
|
||||
p_color.full = (buf_u8[px] & (1 << (7 - bit))) >> (7 - bit);
|
||||
} else if(dsc->header.cf == LV_IMG_CF_INDEXED_2BIT) {
|
||||
buf_u8 += 4 * 4;
|
||||
uint8_t bit = (x & 0x3) * 2;
|
||||
x = x >> 2;
|
||||
|
||||
/* Get the current pixel.
|
||||
* dsc->header.w + 3 means rounding up to 4 because the lines are byte aligned
|
||||
* so the possible real width are 4, 8, 12 ...*/
|
||||
uint32_t px = ((dsc->header.w + 3) >> 2) * y + x;
|
||||
p_color.full = (buf_u8[px] & (3 << (6 - bit))) >> (6 - bit);
|
||||
} else if(dsc->header.cf == LV_IMG_CF_INDEXED_4BIT) {
|
||||
buf_u8 += 4 * 16;
|
||||
uint8_t bit = (x & 0x1) * 4;
|
||||
x = x >> 1;
|
||||
|
||||
/* Get the current pixel.
|
||||
* dsc->header.w + 1 means rounding up to 2 because the lines are byte aligned
|
||||
* so the possible real width are 2, 4, 6 ...*/
|
||||
uint32_t px = ((dsc->header.w + 1) >> 1) * y + x;
|
||||
p_color.full = (buf_u8[px] & (0xF << (4 - bit))) >> (4 - bit);
|
||||
} else if(dsc->header.cf == LV_IMG_CF_INDEXED_8BIT) {
|
||||
buf_u8 += 4 * 256;
|
||||
uint32_t px = dsc->header.w * y + x;
|
||||
p_color.full = buf_u8[px];
|
||||
} else if(dsc->header.cf == LV_IMG_CF_ALPHA_1BIT || dsc->header.cf == LV_IMG_CF_ALPHA_2BIT ||
|
||||
dsc->header.cf == LV_IMG_CF_ALPHA_4BIT || dsc->header.cf == LV_IMG_CF_ALPHA_8BIT) {
|
||||
if(style)
|
||||
p_color = style->image.color;
|
||||
else
|
||||
p_color = LV_COLOR_BLACK;
|
||||
}
|
||||
return p_color;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the alpha value of an image's pixel
|
||||
* @param dsc pointer to an image descriptor
|
||||
* @param x x coordinate of the point to set
|
||||
* @param y x coordinate of the point to set
|
||||
* @return alpha value of the point
|
||||
*/
|
||||
lv_opa_t lv_img_buf_get_px_alpha(lv_img_dsc_t * dsc, lv_coord_t x, lv_coord_t y)
|
||||
{
|
||||
if(x >= (lv_coord_t)dsc->header.w) {
|
||||
x = dsc->header.w - 1;
|
||||
LV_LOG_WARN("lv_canvas_get_px: x is too large (out of canvas)");
|
||||
} else if(x < 0) {
|
||||
x = 0;
|
||||
LV_LOG_WARN("lv_canvas_get_px: x is < 0 (out of canvas)");
|
||||
}
|
||||
|
||||
if(y >= (lv_coord_t)dsc->header.h) {
|
||||
y = dsc->header.h - 1;
|
||||
LV_LOG_WARN("lv_canvas_get_px: y is too large (out of canvas)");
|
||||
} else if(y < 0) {
|
||||
y = 0;
|
||||
LV_LOG_WARN("lv_canvas_get_px: y is < 0 (out of canvas)");
|
||||
}
|
||||
|
||||
uint8_t * buf_u8 = (uint8_t *)dsc->data;
|
||||
|
||||
if(dsc->header.cf == LV_IMG_CF_TRUE_COLOR_ALPHA) {
|
||||
uint32_t px = dsc->header.w * y * LV_IMG_PX_SIZE_ALPHA_BYTE + x * LV_IMG_PX_SIZE_ALPHA_BYTE;
|
||||
return buf_u8[px + LV_IMG_PX_SIZE_ALPHA_BYTE - 1];
|
||||
} else if(dsc->header.cf == LV_IMG_CF_ALPHA_1BIT) {
|
||||
uint8_t bit = x & 0x7;
|
||||
x = x >> 3;
|
||||
|
||||
/* Get the current pixel.
|
||||
* dsc->header.w + 7 means rounding up to 8 because the lines are byte aligned
|
||||
* so the possible real width are 8 ,16, 24 ...*/
|
||||
uint32_t px = ((dsc->header.w + 7) >> 3) * y + x;
|
||||
uint8_t px_opa = (buf_u8[px] & (1 << (7 - bit))) >> (7 - bit);
|
||||
return px_opa ? LV_OPA_TRANSP : LV_OPA_COVER;
|
||||
} else if(dsc->header.cf == LV_IMG_CF_ALPHA_2BIT) {
|
||||
const uint8_t opa_table[4] = {0, 85, 170, 255}; /*Opacity mapping with bpp = 2*/
|
||||
|
||||
uint8_t bit = (x & 0x3) * 2;
|
||||
x = x >> 2;
|
||||
|
||||
/* Get the current pixel.
|
||||
* dsc->header.w + 4 means rounding up to 8 because the lines are byte aligned
|
||||
* so the possible real width are 4 ,8, 12 ...*/
|
||||
uint32_t px = ((dsc->header.w + 3) >> 2) * y + x;
|
||||
uint8_t px_opa = (buf_u8[px] & (3 << (6 - bit))) >> (6 - bit);
|
||||
return opa_table[px_opa];
|
||||
} else if(dsc->header.cf == LV_IMG_CF_ALPHA_4BIT) {
|
||||
const uint8_t opa_table[16] = {0, 17, 34, 51, /*Opacity mapping with bpp = 4*/
|
||||
68, 85, 102, 119, 136, 153, 170, 187, 204, 221, 238, 255};
|
||||
|
||||
uint8_t bit = (x & 0x1) * 4;
|
||||
x = x >> 1;
|
||||
|
||||
/* Get the current pixel.
|
||||
* dsc->header.w + 1 means rounding up to 8 because the lines are byte aligned
|
||||
* so the possible real width are 2 ,4, 6 ...*/
|
||||
uint32_t px = ((dsc->header.w + 1) >> 1) * y + x;
|
||||
uint8_t px_opa = (buf_u8[px] & (0xF << (4 - bit))) >> (4 - bit);
|
||||
return opa_table[px_opa];
|
||||
} else if(dsc->header.cf == LV_IMG_CF_ALPHA_8BIT) {
|
||||
uint32_t px = dsc->header.w * y + x;
|
||||
return buf_u8[px];
|
||||
}
|
||||
|
||||
return LV_OPA_COVER;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the color of a pixel of an image. The alpha channel won't be affected.
|
||||
* @param dsc pointer to an image descriptor
|
||||
* @param x x coordinate of the point to set
|
||||
* @param y x coordinate of the point to set
|
||||
* @param c color of the point
|
||||
*/
|
||||
void lv_img_buf_set_px_color(lv_img_dsc_t * dsc, lv_coord_t x, lv_coord_t y, lv_color_t c)
|
||||
{
|
||||
uint8_t * buf_u8 = (uint8_t *)dsc->data;
|
||||
|
||||
if(dsc->header.cf == LV_IMG_CF_TRUE_COLOR || dsc->header.cf == LV_IMG_CF_TRUE_COLOR_CHROMA_KEYED) {
|
||||
uint8_t px_size = lv_img_color_format_get_px_size(dsc->header.cf) >> 3;
|
||||
uint32_t px = dsc->header.w * y * px_size + x * px_size;
|
||||
memcpy(&buf_u8[px], &c, px_size);
|
||||
} else if(dsc->header.cf == LV_IMG_CF_TRUE_COLOR_ALPHA) {
|
||||
uint8_t px_size = lv_img_color_format_get_px_size(dsc->header.cf) >> 3;
|
||||
uint32_t px = dsc->header.w * y * px_size + x * px_size;
|
||||
memcpy(&buf_u8[px], &c, px_size - 1); /*-1 to not overwrite the alpha value*/
|
||||
} else if(dsc->header.cf == LV_IMG_CF_INDEXED_1BIT) {
|
||||
buf_u8 += sizeof(lv_color32_t) * 2; /*Skip the palette*/
|
||||
|
||||
uint8_t bit = x & 0x7;
|
||||
x = x >> 3;
|
||||
|
||||
/* Get the current pixel.
|
||||
* dsc->header.w + 7 means rounding up to 8 because the lines are byte aligned
|
||||
* so the possible real width are 8 ,16, 24 ...*/
|
||||
uint32_t px = ((dsc->header.w + 7) >> 3) * y + x;
|
||||
buf_u8[px] = buf_u8[px] & ~(1 << (7 - bit));
|
||||
buf_u8[px] = buf_u8[px] | ((c.full & 0x1) << (7 - bit));
|
||||
} else if(dsc->header.cf == LV_IMG_CF_INDEXED_2BIT) {
|
||||
buf_u8 += sizeof(lv_color32_t) * 4; /*Skip the palette*/
|
||||
uint8_t bit = (x & 0x3) * 2;
|
||||
x = x >> 2;
|
||||
|
||||
/* Get the current pixel.
|
||||
* dsc->header.w + 3 means rounding up to 4 because the lines are byte aligned
|
||||
* so the possible real width are 4, 8 ,12 ...*/
|
||||
uint32_t px = ((dsc->header.w + 3) >> 2) * y + x;
|
||||
|
||||
buf_u8[px] = buf_u8[px] & ~(3 << (6 - bit));
|
||||
buf_u8[px] = buf_u8[px] | ((c.full & 0x3) << (6 - bit));
|
||||
} else if(dsc->header.cf == LV_IMG_CF_INDEXED_4BIT) {
|
||||
buf_u8 += sizeof(lv_color32_t) * 16; /*Skip the palette*/
|
||||
uint8_t bit = (x & 0x1) * 4;
|
||||
x = x >> 1;
|
||||
|
||||
/* Get the current pixel.
|
||||
* dsc->header.w + 1 means rounding up to 2 because the lines are byte aligned
|
||||
* so the possible real width are 2 ,4, 6 ...*/
|
||||
uint32_t px = ((dsc->header.w + 1) >> 1) * y + x;
|
||||
buf_u8[px] = buf_u8[px] & ~(0xF << (4 - bit));
|
||||
buf_u8[px] = buf_u8[px] | ((c.full & 0xF) << (4 - bit));
|
||||
} else if(dsc->header.cf == LV_IMG_CF_INDEXED_8BIT) {
|
||||
buf_u8 += sizeof(lv_color32_t) * 256; /*Skip the palette*/
|
||||
uint32_t px = dsc->header.w * y + x;
|
||||
buf_u8[px] = c.full;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the alpha value of a pixel of an image. The color won't be affected
|
||||
* @param dsc pointer to an image descriptor
|
||||
* @param x x coordinate of the point to set
|
||||
* @param y x coordinate of the point to set
|
||||
* @param opa the desired opacity
|
||||
*/
|
||||
void lv_img_buf_set_px_alpha(lv_img_dsc_t * dsc, lv_coord_t x, lv_coord_t y, lv_opa_t opa)
|
||||
{
|
||||
uint8_t * buf_u8 = (uint8_t *)dsc->data;
|
||||
|
||||
if(dsc->header.cf == LV_IMG_CF_TRUE_COLOR_ALPHA) {
|
||||
uint8_t px_size = lv_img_color_format_get_px_size(dsc->header.cf) >> 3;
|
||||
uint32_t px = dsc->header.w * y * px_size + x * px_size;
|
||||
buf_u8[px + px_size - 1] = opa;
|
||||
} else if(dsc->header.cf == LV_IMG_CF_ALPHA_1BIT) {
|
||||
opa = opa >> 7; /*opa -> [0,1]*/
|
||||
uint8_t bit = x & 0x7;
|
||||
x = x >> 3;
|
||||
|
||||
/* Get the current pixel.
|
||||
* dsc->header.w + 7 means rounding up to 8 because the lines are byte aligned
|
||||
* so the possible real width are 8 ,16, 24 ...*/
|
||||
uint32_t px = ((dsc->header.w + 7) >> 3) * y + x;
|
||||
buf_u8[px] = buf_u8[px] & ~(1 << (7 - bit));
|
||||
buf_u8[px] = buf_u8[px] | ((opa & 0x1) << (7 - bit));
|
||||
} else if(dsc->header.cf == LV_IMG_CF_ALPHA_2BIT) {
|
||||
opa = opa >> 6; /*opa -> [0,3]*/
|
||||
uint8_t bit = (x & 0x3) * 2;
|
||||
x = x >> 2;
|
||||
|
||||
/* Get the current pixel.
|
||||
* dsc->header.w + 4 means rounding up to 8 because the lines are byte aligned
|
||||
* so the possible real width are 4 ,8, 12 ...*/
|
||||
uint32_t px = ((dsc->header.w + 3) >> 2) * y + x;
|
||||
buf_u8[px] = buf_u8[px] & ~(3 << (6 - bit));
|
||||
buf_u8[px] = buf_u8[px] | ((opa & 0x3) << (6 - bit));
|
||||
} else if(dsc->header.cf == LV_IMG_CF_ALPHA_4BIT) {
|
||||
opa = opa >> 4; /*opa -> [0,15]*/
|
||||
uint8_t bit = (x & 0x1) * 4;
|
||||
x = x >> 1;
|
||||
|
||||
/* Get the current pixel.
|
||||
* dsc->header.w + 1 means rounding up to 8 because the lines are byte aligned
|
||||
* so the possible real width are 2 ,4, 6 ...*/
|
||||
uint32_t px = ((dsc->header.w + 1) >> 1) * y + x;
|
||||
buf_u8[px] = buf_u8[px] & ~(0xF << (4 - bit));
|
||||
buf_u8[px] = buf_u8[px] | ((opa & 0xF) << (4 - bit));
|
||||
} else if(dsc->header.cf == LV_IMG_CF_ALPHA_8BIT) {
|
||||
uint32_t px = dsc->header.w * y + x;
|
||||
buf_u8[px] = opa;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the palette color of an indexed image. Valid only for `LV_IMG_CF_INDEXED1/2/4/8`
|
||||
* @param dsc pointer to an image descriptor
|
||||
* @param id the palette color to set:
|
||||
* - for `LV_IMG_CF_INDEXED1`: 0..1
|
||||
* - for `LV_IMG_CF_INDEXED2`: 0..3
|
||||
* - for `LV_IMG_CF_INDEXED4`: 0..15
|
||||
* - for `LV_IMG_CF_INDEXED8`: 0..255
|
||||
* @param c the color to set
|
||||
*/
|
||||
void lv_img_buf_set_palette(lv_img_dsc_t * dsc, uint8_t id, lv_color_t c)
|
||||
{
|
||||
if((dsc->header.cf == LV_IMG_CF_ALPHA_1BIT && id > 1) || (dsc->header.cf == LV_IMG_CF_ALPHA_2BIT && id > 3) ||
|
||||
(dsc->header.cf == LV_IMG_CF_ALPHA_4BIT && id > 15) || (dsc->header.cf == LV_IMG_CF_ALPHA_8BIT)) {
|
||||
LV_LOG_WARN("lv_img_buf_set_px_alpha: invalid 'id'");
|
||||
return;
|
||||
}
|
||||
|
||||
lv_color32_t c32;
|
||||
c32.full = lv_color_to32(c);
|
||||
uint8_t * buf = (uint8_t *)dsc->data;
|
||||
memcpy(&buf[id * sizeof(c32)], &c32, sizeof(c32));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the pixel size of a color format in bits
|
||||
* @param cf a color format (`LV_IMG_CF_...`)
|
||||
* @return the pixel size in bits
|
||||
*/
|
||||
uint8_t lv_img_color_format_get_px_size(lv_img_cf_t cf)
|
||||
{
|
||||
uint8_t px_size = 0;
|
||||
|
||||
switch(cf) {
|
||||
case LV_IMG_CF_UNKNOWN:
|
||||
case LV_IMG_CF_RAW: px_size = 0; break;
|
||||
case LV_IMG_CF_TRUE_COLOR:
|
||||
case LV_IMG_CF_TRUE_COLOR_CHROMA_KEYED: px_size = LV_COLOR_SIZE; break;
|
||||
case LV_IMG_CF_TRUE_COLOR_ALPHA: px_size = LV_IMG_PX_SIZE_ALPHA_BYTE << 3; break;
|
||||
case LV_IMG_CF_INDEXED_1BIT:
|
||||
case LV_IMG_CF_ALPHA_1BIT: px_size = 1; break;
|
||||
case LV_IMG_CF_INDEXED_2BIT:
|
||||
case LV_IMG_CF_ALPHA_2BIT: px_size = 2; break;
|
||||
case LV_IMG_CF_INDEXED_4BIT:
|
||||
case LV_IMG_CF_ALPHA_4BIT: px_size = 4; break;
|
||||
case LV_IMG_CF_INDEXED_8BIT:
|
||||
case LV_IMG_CF_ALPHA_8BIT: px_size = 8; break;
|
||||
default: px_size = 0; break;
|
||||
}
|
||||
|
||||
return px_size;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a color format is chroma keyed or not
|
||||
* @param cf a color format (`LV_IMG_CF_...`)
|
||||
* @return true: chroma keyed; false: not chroma keyed
|
||||
*/
|
||||
bool lv_img_color_format_is_chroma_keyed(lv_img_cf_t cf)
|
||||
{
|
||||
bool is_chroma_keyed = false;
|
||||
|
||||
switch(cf) {
|
||||
case LV_IMG_CF_TRUE_COLOR_CHROMA_KEYED:
|
||||
case LV_IMG_CF_RAW_CHROMA_KEYED:
|
||||
#if LV_INDEXED_CHROMA
|
||||
case LV_IMG_CF_INDEXED_1BIT:
|
||||
case LV_IMG_CF_INDEXED_2BIT:
|
||||
case LV_IMG_CF_INDEXED_4BIT:
|
||||
case LV_IMG_CF_INDEXED_8BIT:
|
||||
#endif
|
||||
is_chroma_keyed = true; break;
|
||||
|
||||
default: is_chroma_keyed = false; break;
|
||||
}
|
||||
|
||||
return is_chroma_keyed;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a color format has alpha channel or not
|
||||
* @param cf a color format (`LV_IMG_CF_...`)
|
||||
* @return true: has alpha channel; false: doesn't have alpha channel
|
||||
*/
|
||||
bool lv_img_color_format_has_alpha(lv_img_cf_t cf)
|
||||
{
|
||||
bool has_alpha = false;
|
||||
|
||||
switch(cf) {
|
||||
case LV_IMG_CF_TRUE_COLOR_ALPHA:
|
||||
case LV_IMG_CF_RAW_ALPHA:
|
||||
case LV_IMG_CF_INDEXED_1BIT:
|
||||
case LV_IMG_CF_INDEXED_2BIT:
|
||||
case LV_IMG_CF_INDEXED_4BIT:
|
||||
case LV_IMG_CF_INDEXED_8BIT:
|
||||
case LV_IMG_CF_ALPHA_1BIT:
|
||||
case LV_IMG_CF_ALPHA_2BIT:
|
||||
case LV_IMG_CF_ALPHA_4BIT:
|
||||
case LV_IMG_CF_ALPHA_8BIT: has_alpha = true; break;
|
||||
default: has_alpha = false; break;
|
||||
}
|
||||
|
||||
return has_alpha;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the type of an image source
|
||||
* @param src pointer to an image source:
|
||||
* - pointer to an 'lv_img_t' variable (image stored internally and compiled into the code)
|
||||
* - a path to a file (e.g. "S:/folder/image.bin")
|
||||
* - or a symbol (e.g. LV_SYMBOL_CLOSE)
|
||||
* @return type of the image source LV_IMG_SRC_VARIABLE/FILE/SYMBOL/UNKNOWN
|
||||
*/
|
||||
lv_img_src_t lv_img_src_get_type(const void * src)
|
||||
{
|
||||
lv_img_src_t img_src_type = LV_IMG_SRC_UNKNOWN;
|
||||
|
||||
if(src == NULL) return img_src_type;
|
||||
const uint8_t * u8_p = src;
|
||||
|
||||
/*The first byte shows the type of the image source*/
|
||||
if(u8_p[0] >= 0x20 && u8_p[0] <= 0x7F) {
|
||||
img_src_type = LV_IMG_SRC_FILE; /*If it's an ASCII character then it's file name*/
|
||||
} else if(u8_p[0] >= 0x80) {
|
||||
img_src_type = LV_IMG_SRC_SYMBOL; /*Symbols begins after 0x7F*/
|
||||
} else {
|
||||
img_src_type = LV_IMG_SRC_VARIABLE; /*`lv_img_dsc_t` is design to the first byte < 0x20*/
|
||||
}
|
||||
|
||||
if(LV_IMG_SRC_UNKNOWN == img_src_type) {
|
||||
LV_LOG_WARN("lv_img_src_get_type: unknown image type");
|
||||
}
|
||||
|
||||
return img_src_type;
|
||||
}
|
||||
|
||||
lv_img_dsc_t *lv_img_buf_alloc(lv_coord_t w, lv_coord_t h, lv_img_cf_t cf)
|
||||
{
|
||||
/* Allocate image descriptor */
|
||||
lv_img_dsc_t *dsc = lv_mem_alloc(sizeof(lv_img_dsc_t));
|
||||
if(dsc == NULL)
|
||||
return NULL;
|
||||
|
||||
memset(dsc, 0, sizeof(lv_img_dsc_t));
|
||||
|
||||
/* Get image data size */
|
||||
dsc->data_size = lv_img_buf_get_img_size(w, h, cf);
|
||||
if(dsc->data_size == 0) {
|
||||
lv_mem_free(dsc);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Allocate raw buffer */
|
||||
dsc->data = lv_mem_alloc(dsc->data_size);
|
||||
if(dsc->data == NULL) {
|
||||
lv_mem_free(dsc);
|
||||
return NULL;
|
||||
}
|
||||
memset((uint8_t *)dsc->data, 0, dsc->data_size);
|
||||
|
||||
/* Fill in header */
|
||||
dsc->header.always_zero = 0;
|
||||
dsc->header.w = w;
|
||||
dsc->header.h = h;
|
||||
dsc->header.cf = cf;
|
||||
return dsc;
|
||||
}
|
||||
|
||||
void lv_img_buf_free(lv_img_dsc_t *dsc)
|
||||
{
|
||||
if(dsc != NULL) {
|
||||
if(dsc->data != NULL)
|
||||
lv_mem_free(dsc->data);
|
||||
|
||||
lv_mem_free(dsc);
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t lv_img_buf_get_img_size(lv_coord_t w, lv_coord_t h, lv_img_cf_t cf)
|
||||
{
|
||||
switch(cf) {
|
||||
case LV_IMG_CF_TRUE_COLOR: return LV_IMG_BUF_SIZE_TRUE_COLOR(w, h);
|
||||
case LV_IMG_CF_TRUE_COLOR_ALPHA: return LV_IMG_BUF_SIZE_TRUE_COLOR_ALPHA(w, h);
|
||||
case LV_IMG_CF_TRUE_COLOR_CHROMA_KEYED: return LV_IMG_BUF_SIZE_TRUE_COLOR_CHROMA_KEYED(w, h);
|
||||
case LV_IMG_CF_ALPHA_1BIT: return LV_IMG_BUF_SIZE_ALPHA_1BIT(w, h);
|
||||
case LV_IMG_CF_ALPHA_2BIT: return LV_IMG_BUF_SIZE_ALPHA_2BIT(w, h);
|
||||
case LV_IMG_CF_ALPHA_4BIT: return LV_IMG_BUF_SIZE_ALPHA_4BIT(w, h);
|
||||
case LV_IMG_CF_ALPHA_8BIT: return LV_IMG_BUF_SIZE_ALPHA_8BIT(w, h);
|
||||
case LV_IMG_CF_INDEXED_1BIT: return LV_IMG_BUF_SIZE_INDEXED_1BIT(w, h);
|
||||
case LV_IMG_CF_INDEXED_2BIT: return LV_IMG_BUF_SIZE_INDEXED_2BIT(w, h);
|
||||
case LV_IMG_CF_INDEXED_4BIT: return LV_IMG_BUF_SIZE_INDEXED_4BIT(w, h);
|
||||
case LV_IMG_CF_INDEXED_8BIT: return LV_IMG_BUF_SIZE_INDEXED_8BIT(w, h);
|
||||
default: return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
|
||||
static lv_res_t lv_img_draw_core(const lv_area_t * coords, const lv_area_t * mask, const void * src,
|
||||
const lv_style_t * style, lv_opa_t opa_scale)
|
||||
{
|
||||
|
||||
lv_area_t mask_com; /*Common area of mask and coords*/
|
||||
bool union_ok;
|
||||
union_ok = lv_area_intersect(&mask_com, mask, coords);
|
||||
if(union_ok == false) {
|
||||
return LV_RES_OK; /*Out of mask. There is nothing to draw so the image is drawn
|
||||
successfully.*/
|
||||
}
|
||||
|
||||
lv_opa_t opa =
|
||||
opa_scale == LV_OPA_COVER ? style->image.opa : (uint16_t)((uint16_t)style->image.opa * opa_scale) >> 8;
|
||||
|
||||
lv_img_cache_entry_t * cdsc = lv_img_cache_open(src, style);
|
||||
|
||||
if(cdsc == NULL) return LV_RES_INV;
|
||||
|
||||
bool chroma_keyed = lv_img_color_format_is_chroma_keyed(cdsc->dec_dsc.header.cf);
|
||||
bool alpha_byte = lv_img_color_format_has_alpha(cdsc->dec_dsc.header.cf);
|
||||
|
||||
if(cdsc->dec_dsc.error_msg != NULL) {
|
||||
LV_LOG_WARN("Image draw error");
|
||||
lv_draw_rect(coords, mask, &lv_style_plain, LV_OPA_COVER);
|
||||
lv_draw_label(coords, mask, &lv_style_plain, LV_OPA_COVER, cdsc->dec_dsc.error_msg, LV_TXT_FLAG_NONE, NULL, NULL, NULL, LV_BIDI_DIR_LTR);
|
||||
}
|
||||
/* The decoder open could open the image and gave the entire uncompressed image.
|
||||
* Just draw it!*/
|
||||
else if(cdsc->dec_dsc.img_data) {
|
||||
lv_draw_map(coords, mask, cdsc->dec_dsc.img_data, opa, chroma_keyed, alpha_byte, style->image.color,
|
||||
style->image.intense);
|
||||
}
|
||||
/* The whole uncompressed image is not available. Try to read it line-by-line*/
|
||||
else {
|
||||
lv_coord_t width = lv_area_get_width(&mask_com);
|
||||
|
||||
uint8_t * buf = lv_draw_get_buf(lv_area_get_width(&mask_com) * LV_IMG_PX_SIZE_ALPHA_BYTE); /*space for the possible alpha byte*/
|
||||
|
||||
lv_area_t line;
|
||||
lv_area_copy(&line, &mask_com);
|
||||
lv_area_set_height(&line, 1);
|
||||
lv_coord_t x = mask_com.x1 - coords->x1;
|
||||
lv_coord_t y = mask_com.y1 - coords->y1;
|
||||
lv_coord_t row;
|
||||
lv_res_t read_res;
|
||||
for(row = mask_com.y1; row <= mask_com.y2; row++) {
|
||||
read_res = lv_img_decoder_read_line(&cdsc->dec_dsc, x, y, width, buf);
|
||||
if(read_res != LV_RES_OK) {
|
||||
lv_img_decoder_close(&cdsc->dec_dsc);
|
||||
LV_LOG_WARN("Image draw can't read the line");
|
||||
return LV_RES_INV;
|
||||
}
|
||||
lv_draw_map(&line, mask, buf, opa, chroma_keyed, alpha_byte, style->image.color, style->image.intense);
|
||||
line.y1++;
|
||||
line.y2++;
|
||||
y++;
|
||||
}
|
||||
}
|
||||
|
||||
return LV_RES_OK;
|
||||
}
|
@ -1,172 +0,0 @@
|
||||
/**
|
||||
* @file lv_draw_img.h
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LV_DRAW_IMG_H
|
||||
#define LV_DRAW_IMG_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "lv_draw.h"
|
||||
#include "lv_img_decoder.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
#define LV_IMG_BUF_SIZE_TRUE_COLOR(w, h) ((LV_COLOR_SIZE / 8) * w * h)
|
||||
#define LV_IMG_BUF_SIZE_TRUE_COLOR_CHROMA_KEYED(w, h) ((LV_COLOR_SIZE / 8) * w * h)
|
||||
#define LV_IMG_BUF_SIZE_TRUE_COLOR_ALPHA(w, h) (LV_IMG_PX_SIZE_ALPHA_BYTE * w * h)
|
||||
|
||||
/*+ 1: to be sure no fractional row*/
|
||||
#define LV_IMG_BUF_SIZE_ALPHA_1BIT(w, h) ((((w / 8) + 1) * h))
|
||||
#define LV_IMG_BUF_SIZE_ALPHA_2BIT(w, h) ((((w / 4) + 1) * h))
|
||||
#define LV_IMG_BUF_SIZE_ALPHA_4BIT(w, h) ((((w / 2) + 1) * h))
|
||||
#define LV_IMG_BUF_SIZE_ALPHA_8BIT(w, h) ((w * h))
|
||||
|
||||
/*4 * X: for palette*/
|
||||
#define LV_IMG_BUF_SIZE_INDEXED_1BIT(w, h) (LV_IMG_BUF_SIZE_ALPHA_1BIT(w, h) + 4 * 2)
|
||||
#define LV_IMG_BUF_SIZE_INDEXED_2BIT(w, h) (LV_IMG_BUF_SIZE_ALPHA_2BIT(w, h) + 4 * 4)
|
||||
#define LV_IMG_BUF_SIZE_INDEXED_4BIT(w, h) (LV_IMG_BUF_SIZE_ALPHA_4BIT(w, h) + 4 * 16)
|
||||
#define LV_IMG_BUF_SIZE_INDEXED_8BIT(w, h) (LV_IMG_BUF_SIZE_ALPHA_8BIT(w, h) + 4 * 256)
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Draw an image
|
||||
* @param coords the coordinates of the image
|
||||
* @param mask the image will be drawn only in this area
|
||||
* @param src pointer to a lv_color_t array which contains the pixels of the image
|
||||
* @param style style of the image
|
||||
* @param opa_scale scale down all opacities by the factor
|
||||
*/
|
||||
void lv_draw_img(const lv_area_t * coords, const lv_area_t * mask, const void * src, const lv_style_t * style,
|
||||
lv_opa_t opa_scale);
|
||||
|
||||
/**
|
||||
* Get the type of an image source
|
||||
* @param src pointer to an image source:
|
||||
* - pointer to an 'lv_img_t' variable (image stored internally and compiled into the code)
|
||||
* - a path to a file (e.g. "S:/folder/image.bin")
|
||||
* - or a symbol (e.g. LV_SYMBOL_CLOSE)
|
||||
* @return type of the image source LV_IMG_SRC_VARIABLE/FILE/SYMBOL/UNKNOWN
|
||||
*/
|
||||
lv_img_src_t lv_img_src_get_type(const void * src);
|
||||
|
||||
/**
|
||||
* Get the color of an image's pixel
|
||||
* @param dsc an image descriptor
|
||||
* @param x x coordinate of the point to get
|
||||
* @param y x coordinate of the point to get
|
||||
* @param style style of the image. In case of `LV_IMG_CF_ALPHA_1/2/4/8` `style->image.color` shows
|
||||
* the color. Can be `NULL` but for `ALPHA` images black will be returned. In other cases it is not
|
||||
* used.
|
||||
* @return color of the point
|
||||
*/
|
||||
lv_color_t lv_img_buf_get_px_color(lv_img_dsc_t * dsc, lv_coord_t x, lv_coord_t y, const lv_style_t * style);
|
||||
/**
|
||||
* Get the alpha value of an image's pixel
|
||||
* @param dsc pointer to an image descriptor
|
||||
* @param x x coordinate of the point to set
|
||||
* @param y x coordinate of the point to set
|
||||
* @return alpha value of the point
|
||||
*/
|
||||
lv_opa_t lv_img_buf_get_px_alpha(lv_img_dsc_t * dsc, lv_coord_t x, lv_coord_t y);
|
||||
|
||||
/**
|
||||
* Set the color of a pixel of an image. The alpha channel won't be affected.
|
||||
* @param dsc pointer to an image descriptor
|
||||
* @param x x coordinate of the point to set
|
||||
* @param y x coordinate of the point to set
|
||||
* @param c color of the point
|
||||
*/
|
||||
void lv_img_buf_set_px_color(lv_img_dsc_t * dsc, lv_coord_t x, lv_coord_t y, lv_color_t c);
|
||||
|
||||
/**
|
||||
* Set the alpha value of a pixel of an image. The color won't be affected
|
||||
* @param dsc pointer to an image descriptor
|
||||
* @param x x coordinate of the point to set
|
||||
* @param y x coordinate of the point to set
|
||||
* @param opa the desired opacity
|
||||
*/
|
||||
void lv_img_buf_set_px_alpha(lv_img_dsc_t * dsc, lv_coord_t x, lv_coord_t y, lv_opa_t opa);
|
||||
|
||||
/**
|
||||
* Set the palette color of an indexed image. Valid only for `LV_IMG_CF_INDEXED1/2/4/8`
|
||||
* @param dsc pointer to an image descriptor
|
||||
* @param id the palette color to set:
|
||||
* - for `LV_IMG_CF_INDEXED1`: 0..1
|
||||
* - for `LV_IMG_CF_INDEXED2`: 0..3
|
||||
* - for `LV_IMG_CF_INDEXED4`: 0..15
|
||||
* - for `LV_IMG_CF_INDEXED8`: 0..255
|
||||
* @param c the color to set
|
||||
*/
|
||||
void lv_img_buf_set_palette(lv_img_dsc_t * dsc, uint8_t id, lv_color_t c);
|
||||
|
||||
/**
|
||||
* Get the pixel size of a color format in bits
|
||||
* @param cf a color format (`LV_IMG_CF_...`)
|
||||
* @return the pixel size in bits
|
||||
*/
|
||||
uint8_t lv_img_color_format_get_px_size(lv_img_cf_t cf);
|
||||
|
||||
/**
|
||||
* Check if a color format is chroma keyed or not
|
||||
* @param cf a color format (`LV_IMG_CF_...`)
|
||||
* @return true: chroma keyed; false: not chroma keyed
|
||||
*/
|
||||
bool lv_img_color_format_is_chroma_keyed(lv_img_cf_t cf);
|
||||
|
||||
/**
|
||||
* Check if a color format has alpha channel or not
|
||||
* @param cf a color format (`LV_IMG_CF_...`)
|
||||
* @return true: has alpha channel; false: doesn't have alpha channel
|
||||
*/
|
||||
bool lv_img_color_format_has_alpha(lv_img_cf_t cf);
|
||||
|
||||
/**
|
||||
* Allocate an image buffer in RAM
|
||||
* @param w width of image
|
||||
* @param h height of image
|
||||
* @param cf a color format (`LV_IMG_CF_...`)
|
||||
* @return an allocated image, or NULL on failure
|
||||
*/
|
||||
lv_img_dsc_t *lv_img_buf_alloc(lv_coord_t w, lv_coord_t h, lv_img_cf_t cf);
|
||||
|
||||
/**
|
||||
* Free an allocated image buffer
|
||||
* @param dsc image buffer to free
|
||||
*/
|
||||
void lv_img_buf_free(lv_img_dsc_t *dsc);
|
||||
|
||||
/**
|
||||
* Get the memory consumption of a raw bitmap, given color format and dimensions.
|
||||
* @param w width
|
||||
* @param h height
|
||||
* @param cf color format
|
||||
* @return size in bytes
|
||||
*/
|
||||
uint32_t lv_img_buf_get_img_size(lv_coord_t w, lv_coord_t h, lv_img_cf_t cf);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif /*LV_TEMPL_H*/
|
@ -1,319 +0,0 @@
|
||||
/**
|
||||
* @file lv_draw_label.c
|
||||
*
|
||||
*/
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "lv_draw_label.h"
|
||||
#include "../lv_misc/lv_math.h"
|
||||
#include "../lv_misc/lv_bidi.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
#define LABEL_RECOLOR_PAR_LENGTH 6
|
||||
#define LV_LABEL_HINT_UPDATE_TH 1024 /*Update the "hint" if the label's y coordinates have changed more then this*/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
enum {
|
||||
CMD_STATE_WAIT,
|
||||
CMD_STATE_PAR,
|
||||
CMD_STATE_IN,
|
||||
};
|
||||
typedef uint8_t cmd_state_t;
|
||||
|
||||
/**********************
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
static uint8_t hex_char_to_num(char hex);
|
||||
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL FUNCTIONS
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Write a text
|
||||
* @param coords coordinates of the label
|
||||
* @param mask the label will be drawn only in this area
|
||||
* @param style pointer to a style
|
||||
* @param opa_scale scale down all opacities by the factor
|
||||
* @param txt 0 terminated text to write
|
||||
* @param flag settings for the text from 'txt_flag_t' enum
|
||||
* @param offset text offset in x and y direction (NULL if unused)
|
||||
* @param sel make the text selected in the range by drawing a background there
|
||||
*/
|
||||
void lv_draw_label(const lv_area_t * coords, const lv_area_t * mask, const lv_style_t * style, lv_opa_t opa_scale,
|
||||
const char * txt, lv_txt_flag_t flag, lv_point_t * offset, lv_draw_label_txt_sel_t * sel,
|
||||
lv_draw_label_hint_t * hint, lv_bidi_dir_t bidi_dir)
|
||||
{
|
||||
const lv_font_t * font = style->text.font;
|
||||
lv_coord_t w;
|
||||
|
||||
/*No need to waste processor time if string is empty*/
|
||||
if (txt[0] == '\0') return;
|
||||
|
||||
if((flag & LV_TXT_FLAG_EXPAND) == 0) {
|
||||
/*Normally use the label's width as width*/
|
||||
w = lv_area_get_width(coords);
|
||||
} else {
|
||||
/*If EXAPND is enabled then not limit the text's width to the object's width*/
|
||||
lv_point_t p;
|
||||
lv_txt_get_size(&p, txt, style->text.font, style->text.letter_space, style->text.line_space, LV_COORD_MAX,
|
||||
flag);
|
||||
w = p.x;
|
||||
}
|
||||
|
||||
lv_coord_t line_height = lv_font_get_line_height(font) + style->text.line_space;
|
||||
|
||||
/*Init variables for the first line*/
|
||||
lv_coord_t line_width = 0;
|
||||
lv_point_t pos;
|
||||
pos.x = coords->x1;
|
||||
pos.y = coords->y1;
|
||||
|
||||
lv_coord_t x_ofs = 0;
|
||||
lv_coord_t y_ofs = 0;
|
||||
if(offset != NULL) {
|
||||
x_ofs = offset->x;
|
||||
y_ofs = offset->y;
|
||||
pos.y += y_ofs;
|
||||
}
|
||||
|
||||
uint32_t line_start = 0;
|
||||
int32_t last_line_start = -1;
|
||||
|
||||
/*Check the hint to use the cached info*/
|
||||
if(hint && y_ofs == 0 && coords->y1 < 0) {
|
||||
/*If the label changed too much recalculate the hint.*/
|
||||
if(LV_MATH_ABS(hint->coord_y - coords->y1) > LV_LABEL_HINT_UPDATE_TH - 2 * line_height) {
|
||||
hint->line_start = -1;
|
||||
}
|
||||
last_line_start = hint->line_start;
|
||||
}
|
||||
|
||||
/*Use the hint if it's valid*/
|
||||
if(hint && last_line_start >= 0) {
|
||||
line_start = last_line_start;
|
||||
pos.y += hint->y;
|
||||
}
|
||||
|
||||
|
||||
uint32_t line_end = line_start + lv_txt_get_next_line(&txt[line_start], font, style->text.letter_space, w, flag);
|
||||
|
||||
/*Go the first visible line*/
|
||||
while(pos.y + line_height < mask->y1) {
|
||||
/*Go to next line*/
|
||||
line_start = line_end;
|
||||
line_end += lv_txt_get_next_line(&txt[line_start], font, style->text.letter_space, w, flag);
|
||||
pos.y += line_height;
|
||||
|
||||
/*Save at the threshold coordinate*/
|
||||
if(hint && pos.y >= -LV_LABEL_HINT_UPDATE_TH && hint->line_start < 0) {
|
||||
hint->line_start = line_start;
|
||||
hint->y = pos.y - coords->y1;
|
||||
hint->coord_y = coords->y1;
|
||||
}
|
||||
|
||||
if(txt[line_start] == '\0') return;
|
||||
}
|
||||
|
||||
/*Align to middle*/
|
||||
if(flag & LV_TXT_FLAG_CENTER) {
|
||||
line_width = lv_txt_get_width(&txt[line_start], line_end - line_start, font, style->text.letter_space, flag);
|
||||
|
||||
pos.x += (lv_area_get_width(coords) - line_width) / 2;
|
||||
|
||||
}
|
||||
/*Align to the right*/
|
||||
else if(flag & LV_TXT_FLAG_RIGHT) {
|
||||
line_width = lv_txt_get_width(&txt[line_start], line_end - line_start, font, style->text.letter_space, flag);
|
||||
pos.x += lv_area_get_width(coords) - line_width;
|
||||
}
|
||||
|
||||
lv_opa_t opa = opa_scale == LV_OPA_COVER ? style->text.opa : (uint16_t)((uint16_t)style->text.opa * opa_scale) >> 8;
|
||||
|
||||
uint16_t sel_start = 0xFFFF;
|
||||
uint16_t sel_end = 0xFFFF;
|
||||
if(sel) {
|
||||
sel_start = sel->start;
|
||||
sel_end = sel->end;
|
||||
if(sel_start > sel_end) {
|
||||
uint16_t tmp = sel_start;
|
||||
sel_start = sel_end;
|
||||
sel_end = tmp;
|
||||
}
|
||||
}
|
||||
|
||||
cmd_state_t cmd_state = CMD_STATE_WAIT;
|
||||
uint32_t i;
|
||||
uint16_t par_start = 0;
|
||||
lv_color_t recolor;
|
||||
lv_coord_t letter_w;
|
||||
lv_style_t sel_style;
|
||||
lv_style_copy(&sel_style, &lv_style_plain_color);
|
||||
sel_style.body.main_color = sel_style.body.grad_color = style->text.sel_color;
|
||||
|
||||
/*Write out all lines*/
|
||||
while(txt[line_start] != '\0') {
|
||||
if(offset != NULL) {
|
||||
pos.x += x_ofs;
|
||||
}
|
||||
/*Write all letter of a line*/
|
||||
cmd_state = CMD_STATE_WAIT;
|
||||
i = 0;
|
||||
uint32_t letter;
|
||||
uint32_t letter_next;
|
||||
#if LV_USE_BIDI
|
||||
char *bidi_txt = lv_draw_get_buf(line_end - line_start + 1);
|
||||
lv_bidi_process_paragraph(txt + line_start, bidi_txt, line_end - line_start, bidi_dir, NULL, 0);
|
||||
#else
|
||||
(void)bidi_dir;
|
||||
const char *bidi_txt = txt + line_start;
|
||||
#endif
|
||||
|
||||
while(i < line_end - line_start) {
|
||||
uint16_t logical_char_pos = 0;
|
||||
if(sel_start != 0xFFFF && sel_end != 0xFFFF) {
|
||||
#if LV_USE_BIDI
|
||||
logical_char_pos = lv_txt_encoded_get_char_id(txt, line_start);
|
||||
uint16_t t = lv_txt_encoded_get_char_id(bidi_txt, i);
|
||||
logical_char_pos += lv_bidi_get_logical_pos(bidi_txt, NULL, line_end - line_start, bidi_dir, t, NULL);
|
||||
#else
|
||||
logical_char_pos = lv_txt_encoded_get_char_id(txt, line_start + i);
|
||||
#endif
|
||||
}
|
||||
|
||||
letter = lv_txt_encoded_next(bidi_txt, &i);
|
||||
letter_next = lv_txt_encoded_next(&bidi_txt[i], NULL);
|
||||
|
||||
|
||||
/*Handle the re-color command*/
|
||||
if((flag & LV_TXT_FLAG_RECOLOR) != 0) {
|
||||
if(letter == (uint32_t)LV_TXT_COLOR_CMD[0]) {
|
||||
if(cmd_state == CMD_STATE_WAIT) { /*Start char*/
|
||||
par_start = i;
|
||||
cmd_state = CMD_STATE_PAR;
|
||||
continue;
|
||||
} else if(cmd_state == CMD_STATE_PAR) { /*Other start char in parameter escaped cmd. char */
|
||||
cmd_state = CMD_STATE_WAIT;
|
||||
} else if(cmd_state == CMD_STATE_IN) { /*Command end */
|
||||
cmd_state = CMD_STATE_WAIT;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
/*Skip the color parameter and wait the space after it*/
|
||||
if(cmd_state == CMD_STATE_PAR) {
|
||||
if(letter == ' ') {
|
||||
/*Get the parameter*/
|
||||
if(i - par_start == LABEL_RECOLOR_PAR_LENGTH + 1) {
|
||||
char buf[LABEL_RECOLOR_PAR_LENGTH + 1];
|
||||
memcpy(buf, &bidi_txt[par_start], LABEL_RECOLOR_PAR_LENGTH);
|
||||
buf[LABEL_RECOLOR_PAR_LENGTH] = '\0';
|
||||
int r, g, b;
|
||||
r = (hex_char_to_num(buf[0]) << 4) + hex_char_to_num(buf[1]);
|
||||
g = (hex_char_to_num(buf[2]) << 4) + hex_char_to_num(buf[3]);
|
||||
b = (hex_char_to_num(buf[4]) << 4) + hex_char_to_num(buf[5]);
|
||||
recolor = lv_color_make(r, g, b);
|
||||
} else {
|
||||
recolor.full = style->text.color.full;
|
||||
}
|
||||
cmd_state = CMD_STATE_IN; /*After the parameter the text is in the command*/
|
||||
}
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
lv_color_t color = style->text.color;
|
||||
|
||||
if(cmd_state == CMD_STATE_IN) color = recolor;
|
||||
|
||||
letter_w = lv_font_get_glyph_width(font, letter, letter_next);
|
||||
|
||||
if(sel_start != 0xFFFF && sel_end != 0xFFFF) {
|
||||
if(logical_char_pos >= sel_start && logical_char_pos < sel_end) {
|
||||
lv_area_t sel_coords;
|
||||
sel_coords.x1 = pos.x;
|
||||
sel_coords.y1 = pos.y;
|
||||
sel_coords.x2 = pos.x + letter_w + style->text.letter_space - 1;
|
||||
sel_coords.y2 = pos.y + line_height - 1;
|
||||
lv_draw_rect(&sel_coords, mask, &sel_style, opa);
|
||||
}
|
||||
}
|
||||
|
||||
lv_draw_letter(&pos, mask, font, letter, color, opa);
|
||||
|
||||
if(letter_w > 0) {
|
||||
pos.x += letter_w + style->text.letter_space;
|
||||
}
|
||||
}
|
||||
/*Go to next line*/
|
||||
line_start = line_end;
|
||||
line_end += lv_txt_get_next_line(&txt[line_start], font, style->text.letter_space, w, flag);
|
||||
|
||||
pos.x = coords->x1;
|
||||
/*Align to middle*/
|
||||
if(flag & LV_TXT_FLAG_CENTER) {
|
||||
line_width =
|
||||
lv_txt_get_width(&txt[line_start], line_end - line_start, font, style->text.letter_space, flag);
|
||||
|
||||
pos.x += (lv_area_get_width(coords) - line_width) / 2;
|
||||
|
||||
}
|
||||
/*Align to the right*/
|
||||
else if(flag & LV_TXT_FLAG_RIGHT) {
|
||||
line_width =
|
||||
lv_txt_get_width(&txt[line_start], line_end - line_start, font, style->text.letter_space, flag);
|
||||
pos.x += lv_area_get_width(coords) - line_width;
|
||||
}
|
||||
|
||||
/*Go the next line position*/
|
||||
pos.y += line_height;
|
||||
|
||||
if(pos.y > mask->y2) return;
|
||||
}
|
||||
}
|
||||
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Convert a hexadecimal characters to a number (0..15)
|
||||
* @param hex Pointer to a hexadecimal character (0..9, A..F)
|
||||
* @return the numerical value of `hex` or 0 on error
|
||||
*/
|
||||
static uint8_t hex_char_to_num(char hex)
|
||||
{
|
||||
uint8_t result = 0;
|
||||
|
||||
if(hex >= '0' && hex <= '9') {
|
||||
result = hex - '0';
|
||||
} else {
|
||||
if(hex >= 'a') hex -= 'a' - 'A'; /*Convert to upper case*/
|
||||
|
||||
switch(hex) {
|
||||
case 'A': result = 10; break;
|
||||
case 'B': result = 11; break;
|
||||
case 'C': result = 12; break;
|
||||
case 'D': result = 13; break;
|
||||
case 'E': result = 14; break;
|
||||
case 'F': result = 15; break;
|
||||
default: result = 0; break;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
@ -1,80 +0,0 @@
|
||||
/**
|
||||
* @file lv_draw_label.h
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LV_DRAW_LABEL_H
|
||||
#define LV_DRAW_LABEL_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "lv_draw.h"
|
||||
#include "../lv_misc/lv_bidi.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
#define LV_DRAW_LABEL_NO_TXT_SEL (0xFFFF)
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint16_t start;
|
||||
uint16_t end;
|
||||
}lv_draw_label_txt_sel_t;
|
||||
|
||||
|
||||
/** Store some info to speed up drawing of very large texts
|
||||
* It takes a lot of time to get the first visible character because
|
||||
* all the previous characters needs to be checked to calculate the positions.
|
||||
* This structure stores an earlier (e.g. at -1000 px) coordinate and the index of that line.
|
||||
* Therefore the calculations can start from here.*/
|
||||
typedef struct {
|
||||
/** Index of the line at `y` coordinate*/
|
||||
int32_t line_start;
|
||||
|
||||
/** Give the `y` coordinate of the first letter at `line start` index. Relative to the label's coordinates*/
|
||||
int32_t y;
|
||||
|
||||
/** The 'y1' coordinate of the label when the hint was saved.
|
||||
* Used to invalidate the hint if the label has moved too much. */
|
||||
int32_t coord_y;
|
||||
}lv_draw_label_hint_t;
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Write a text
|
||||
* @param coords coordinates of the label
|
||||
* @param mask the label will be drawn only in this area
|
||||
* @param style pointer to a style
|
||||
* @param opa_scale scale down all opacities by the factor
|
||||
* @param txt 0 terminated text to write
|
||||
* @param flag settings for the text from 'txt_flag_t' enum
|
||||
* @param offset text offset in x and y direction (NULL if unused)
|
||||
* @param sel_start start index of selected area (`LV_LABEL_TXT_SEL_OFF` if none)
|
||||
* @param bidi_dir base direction of the text
|
||||
*/
|
||||
void lv_draw_label(const lv_area_t * coords, const lv_area_t * mask, const lv_style_t * style, lv_opa_t opa_scale,
|
||||
const char * txt, lv_txt_flag_t flag, lv_point_t * offset, lv_draw_label_txt_sel_t * sel,
|
||||
lv_draw_label_hint_t * hint, lv_bidi_dir_t bidi_dir);
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif /*LV_DRAW_LABEL_H*/
|
@ -1,637 +0,0 @@
|
||||
/**
|
||||
* @file lv_draw_line.c
|
||||
*
|
||||
*/
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include <stdio.h>
|
||||
#include <stdbool.h>
|
||||
#include "lv_draw.h"
|
||||
#include "../lv_core/lv_refr.h"
|
||||
#include "../lv_misc/lv_math.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
typedef struct
|
||||
{
|
||||
lv_point_t p1;
|
||||
lv_point_t p2;
|
||||
lv_point_t p_act;
|
||||
lv_coord_t dx;
|
||||
lv_coord_t sx; /*-1: x1 < x2; 1: x2 >= x1*/
|
||||
lv_coord_t dy;
|
||||
lv_coord_t sy; /*-1: y1 < y2; 1: y2 >= y1*/
|
||||
lv_coord_t err;
|
||||
lv_coord_t e2;
|
||||
bool hor; /*Rather horizontal or vertical*/
|
||||
} line_draw_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
lv_coord_t width;
|
||||
lv_coord_t width_1;
|
||||
lv_coord_t width_half;
|
||||
} line_width_t;
|
||||
|
||||
/**********************
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
static void line_draw_hor(line_draw_t * main_line, const lv_area_t * mask, const lv_style_t * style,
|
||||
lv_opa_t opa_scale);
|
||||
static void line_draw_ver(line_draw_t * main_line, const lv_area_t * mask, const lv_style_t * style,
|
||||
lv_opa_t opa_scale);
|
||||
static void line_draw_skew(line_draw_t * main_line, bool dir_ori, const lv_area_t * mask, const lv_style_t * style,
|
||||
lv_opa_t opa_scale);
|
||||
static void line_init(line_draw_t * line, const lv_point_t * p1, const lv_point_t * p2);
|
||||
static bool line_next(line_draw_t * line);
|
||||
static bool line_next_y(line_draw_t * line);
|
||||
static bool line_next_x(line_draw_t * line);
|
||||
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL FUNCTIONS
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Draw a line
|
||||
* @param point1 first point of the line
|
||||
* @param point2 second point of the line
|
||||
* @param mask the line will be drawn only on this area
|
||||
* @param style pointer to a line's style
|
||||
* @param opa_scale scale down all opacities by the factor
|
||||
*/
|
||||
void lv_draw_line(const lv_point_t * point1, const lv_point_t * point2, const lv_area_t * mask,
|
||||
const lv_style_t * style, lv_opa_t opa_scale)
|
||||
{
|
||||
|
||||
if(style->line.width == 0) return;
|
||||
if(point1->x == point2->x && point1->y == point2->y) return;
|
||||
|
||||
/*Return if the points are out of the mask*/
|
||||
if(point1->x < mask->x1 - style->line.width && point2->x < mask->x1 - style->line.width) return;
|
||||
if(point1->x > mask->x2 + style->line.width && point2->x > mask->x2 + style->line.width) return;
|
||||
if(point1->y < mask->y1 - style->line.width && point2->y < mask->y1 - style->line.width) return;
|
||||
if(point1->y > mask->y2 + style->line.width && point2->y > mask->y2 + style->line.width) return;
|
||||
|
||||
line_draw_t main_line;
|
||||
lv_point_t p1;
|
||||
lv_point_t p2;
|
||||
|
||||
/*If the line if rather vertical then be sure y1 < y2 else x1 < x2*/
|
||||
|
||||
if(LV_MATH_ABS(point1->x - point2->x) > LV_MATH_ABS(point1->y - point2->y)) {
|
||||
|
||||
/*Steps less in y then x -> rather horizontal*/
|
||||
if(point1->x < point2->x) {
|
||||
p1.x = point1->x;
|
||||
p1.y = point1->y;
|
||||
p2.x = point2->x;
|
||||
p2.y = point2->y;
|
||||
} else {
|
||||
p1.x = point2->x;
|
||||
p1.y = point2->y;
|
||||
p2.x = point1->x;
|
||||
p2.y = point1->y;
|
||||
}
|
||||
} else {
|
||||
/*Steps less in x then y -> rather vertical*/
|
||||
if(point1->y < point2->y) {
|
||||
p1.x = point1->x;
|
||||
p1.y = point1->y;
|
||||
p2.x = point2->x;
|
||||
p2.y = point2->y;
|
||||
} else {
|
||||
p1.x = point2->x;
|
||||
p1.y = point2->y;
|
||||
p2.x = point1->x;
|
||||
p2.y = point1->y;
|
||||
}
|
||||
}
|
||||
|
||||
line_init(&main_line, &p1, &p2);
|
||||
|
||||
/*Special case draw a horizontal line*/
|
||||
if(main_line.p1.y == main_line.p2.y) {
|
||||
line_draw_hor(&main_line, mask, style, opa_scale);
|
||||
}
|
||||
/*Special case draw a vertical line*/
|
||||
else if(main_line.p1.x == main_line.p2.x) {
|
||||
line_draw_ver(&main_line, mask, style, opa_scale);
|
||||
}
|
||||
/*Arbitrary skew line*/
|
||||
else {
|
||||
bool dir_ori = false;
|
||||
#if LV_ANTIALIAS
|
||||
bool aa = lv_disp_get_antialiasing(lv_refr_get_disp_refreshing());
|
||||
if(aa) {
|
||||
lv_point_t p_tmp;
|
||||
|
||||
if(main_line.hor) {
|
||||
if(main_line.p1.y < main_line.p2.y) {
|
||||
dir_ori = true;
|
||||
p_tmp.x = main_line.p2.x;
|
||||
p_tmp.y = main_line.p2.y - 1;
|
||||
line_init(&main_line, &p1, &p_tmp);
|
||||
main_line.sy = LV_MATH_ABS(main_line.sy); /*The sign can change if the line becomes horizontal*/
|
||||
} else if(main_line.p1.y > main_line.p2.y) {
|
||||
dir_ori = false;
|
||||
p_tmp.x = main_line.p2.x;
|
||||
p_tmp.y = main_line.p2.y + 1;
|
||||
line_init(&main_line, &p1, &p_tmp);
|
||||
main_line.sy = -LV_MATH_ABS(main_line.sy); /*The sign can change if the line becomes horizontal*/
|
||||
}
|
||||
} else {
|
||||
if(main_line.p1.x < main_line.p2.x) {
|
||||
dir_ori = true;
|
||||
p_tmp.x = main_line.p2.x - 1;
|
||||
p_tmp.y = main_line.p2.y;
|
||||
line_init(&main_line, &p1, &p_tmp);
|
||||
main_line.sx = LV_MATH_ABS(main_line.sx); /*The sign can change if the line becomes vertical*/
|
||||
} else if(main_line.p1.x > main_line.p2.x) {
|
||||
dir_ori = false;
|
||||
p_tmp.x = main_line.p2.x + 1;
|
||||
p_tmp.y = main_line.p2.y;
|
||||
line_init(&main_line, &p1, &p_tmp);
|
||||
main_line.sx = -LV_MATH_ABS(main_line.sx); /*The sign can change if the line becomes vertical*/
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
line_draw_skew(&main_line, dir_ori, mask, style, opa_scale);
|
||||
}
|
||||
}
|
||||
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
|
||||
static void line_draw_hor(line_draw_t * main_line, const lv_area_t * mask, const lv_style_t * style, lv_opa_t opa_scale)
|
||||
{
|
||||
lv_coord_t width = style->line.width - 1;
|
||||
lv_coord_t width_half = width >> 1;
|
||||
lv_coord_t width_1 = width & 0x1;
|
||||
lv_opa_t opa = opa_scale == LV_OPA_COVER ? style->line.opa : (uint16_t)((uint16_t)style->line.opa * opa_scale) >> 8;
|
||||
|
||||
lv_area_t act_area;
|
||||
act_area.x1 = main_line->p1.x;
|
||||
act_area.x2 = main_line->p2.x;
|
||||
act_area.y1 = main_line->p1.y - width_half - width_1;
|
||||
act_area.y2 = main_line->p2.y + width_half;
|
||||
|
||||
lv_area_t draw_area;
|
||||
draw_area.x1 = LV_MATH_MIN(act_area.x1, act_area.x2);
|
||||
draw_area.x2 = LV_MATH_MAX(act_area.x1, act_area.x2);
|
||||
draw_area.y1 = LV_MATH_MIN(act_area.y1, act_area.y2);
|
||||
draw_area.y2 = LV_MATH_MAX(act_area.y1, act_area.y2);
|
||||
lv_draw_fill(&draw_area, mask, style->line.color, opa);
|
||||
}
|
||||
|
||||
static void line_draw_ver(line_draw_t * main_line, const lv_area_t * mask, const lv_style_t * style, lv_opa_t opa_scale)
|
||||
{
|
||||
lv_coord_t width = style->line.width - 1;
|
||||
lv_coord_t width_half = width >> 1;
|
||||
lv_coord_t width_1 = width & 0x1;
|
||||
lv_opa_t opa = opa_scale == LV_OPA_COVER ? style->line.opa : (uint16_t)((uint16_t)style->line.opa * opa_scale) >> 8;
|
||||
|
||||
lv_area_t act_area;
|
||||
act_area.x1 = main_line->p1.x - width_half;
|
||||
act_area.x2 = main_line->p2.x + width_half + width_1;
|
||||
act_area.y1 = main_line->p1.y;
|
||||
act_area.y2 = main_line->p2.y;
|
||||
|
||||
lv_area_t draw_area;
|
||||
draw_area.x1 = LV_MATH_MIN(act_area.x1, act_area.x2);
|
||||
draw_area.x2 = LV_MATH_MAX(act_area.x1, act_area.x2);
|
||||
draw_area.y1 = LV_MATH_MIN(act_area.y1, act_area.y2);
|
||||
draw_area.y2 = LV_MATH_MAX(act_area.y1, act_area.y2);
|
||||
lv_draw_fill(&draw_area, mask, style->line.color, opa);
|
||||
}
|
||||
|
||||
static void line_draw_skew(line_draw_t * main_line, bool dir_ori, const lv_area_t * mask, const lv_style_t * style,
|
||||
lv_opa_t opa_scale)
|
||||
{
|
||||
|
||||
lv_opa_t opa = opa_scale == LV_OPA_COVER ? style->line.opa : (uint16_t)((uint16_t)style->line.opa * opa_scale) >> 8;
|
||||
#if LV_ANTIALIAS
|
||||
bool aa = lv_disp_get_antialiasing(lv_refr_get_disp_refreshing());
|
||||
#endif
|
||||
lv_point_t vect_main, vect_norm;
|
||||
vect_main.x = main_line->p2.x - main_line->p1.x;
|
||||
vect_main.y = main_line->p2.y - main_line->p1.y;
|
||||
|
||||
if(main_line->hor) {
|
||||
if(main_line->p1.y < main_line->p2.y + dir_ori) {
|
||||
vect_norm.x = -vect_main.y;
|
||||
vect_norm.y = vect_main.x;
|
||||
} else {
|
||||
vect_norm.x = vect_main.y;
|
||||
vect_norm.y = -vect_main.x;
|
||||
}
|
||||
} else {
|
||||
if(main_line->p1.x < main_line->p2.x + dir_ori) {
|
||||
vect_norm.x = vect_main.y;
|
||||
vect_norm.y = -vect_main.x;
|
||||
} else {
|
||||
vect_norm.x = -vect_main.y;
|
||||
vect_norm.y = vect_main.x;
|
||||
}
|
||||
}
|
||||
|
||||
/* In case of a short but tick line the perpendicular ending is longer then the real line.
|
||||
* it would break the calculations so make the normal vector larger*/
|
||||
vect_norm.x = vect_norm.x << 4;
|
||||
vect_norm.y = vect_norm.y << 4;
|
||||
|
||||
lv_coord_t width;
|
||||
width = style->line.width;
|
||||
|
||||
/* The pattern stores the points of the line ending. It has the good direction and length.
|
||||
* The worth case is the 45° line where pattern can have 1.41 x `width` points*/
|
||||
|
||||
lv_coord_t pattern_size = width * 2;
|
||||
lv_point_t * pattern = lv_draw_get_buf(pattern_size * sizeof(lv_point_t));
|
||||
lv_coord_t i = 0;
|
||||
|
||||
/*Create a perpendicular pattern (a small line)*/
|
||||
if(width != 0) {
|
||||
line_draw_t pattern_line;
|
||||
lv_point_t p0 = {0, 0};
|
||||
line_init(&pattern_line, &p0, &vect_norm);
|
||||
|
||||
uint32_t width_sqr = width * width;
|
||||
/* Run for a lot of times. Meanwhile the real width will be determined as well */
|
||||
for(i = 0; i < (lv_coord_t)pattern_size - 1; i++) {
|
||||
pattern[i].x = pattern_line.p_act.x;
|
||||
pattern[i].y = pattern_line.p_act.y;
|
||||
|
||||
/*Finish the pattern line if it's length equal to the desired width (Use Pythagoras
|
||||
* theorem)*/
|
||||
uint32_t sqr = pattern_line.p_act.x * pattern_line.p_act.x + pattern_line.p_act.y * pattern_line.p_act.y;
|
||||
if(sqr >= width_sqr) {
|
||||
width = i;
|
||||
#if LV_ANTIALIAS
|
||||
if(aa) width--;
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
|
||||
line_next(&pattern_line);
|
||||
}
|
||||
}
|
||||
|
||||
#if LV_ANTIALIAS
|
||||
lv_coord_t aa_last_corner;
|
||||
lv_coord_t width_safe = width;
|
||||
if(aa) {
|
||||
if(width == 0) width_safe = 1;
|
||||
|
||||
aa_last_corner = 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
lv_coord_t x_center_ofs = 0;
|
||||
lv_coord_t y_center_ofs = 0;
|
||||
|
||||
if(width != 0) {
|
||||
x_center_ofs = pattern[width - 1].x / 2;
|
||||
y_center_ofs = pattern[width - 1].y / 2;
|
||||
} else {
|
||||
if(main_line->hor && main_line->p1.y >= main_line->p2.y + dir_ori) pattern[0].y--;
|
||||
if(!main_line->hor && main_line->p1.x >= main_line->p2.x + dir_ori) pattern[0].x--;
|
||||
}
|
||||
|
||||
/* Make the coordinates relative to the center */
|
||||
for(i = 0; i < width; i++) {
|
||||
pattern[i].x -= x_center_ofs;
|
||||
pattern[i].y -= y_center_ofs;
|
||||
#if LV_ANTIALIAS
|
||||
if(aa) {
|
||||
if(i != 0) {
|
||||
if(main_line->hor) {
|
||||
if(pattern[i - 1].x != pattern[i].x) {
|
||||
lv_coord_t seg_w = pattern[i].y - pattern[aa_last_corner].y;
|
||||
if(main_line->sy < 0) {
|
||||
lv_draw_aa_ver_seg(main_line->p1.x + pattern[aa_last_corner].x - 1,
|
||||
main_line->p1.y + pattern[aa_last_corner].y + seg_w + 1, seg_w, mask,
|
||||
style->line.color, opa);
|
||||
|
||||
lv_draw_aa_ver_seg(main_line->p2.x + pattern[aa_last_corner].x + 1,
|
||||
main_line->p2.y + pattern[aa_last_corner].y + seg_w + 1, -seg_w, mask,
|
||||
style->line.color, opa);
|
||||
} else {
|
||||
lv_draw_aa_ver_seg(main_line->p1.x + pattern[aa_last_corner].x - 1,
|
||||
main_line->p1.y + pattern[aa_last_corner].y, seg_w, mask,
|
||||
style->line.color, opa);
|
||||
|
||||
lv_draw_aa_ver_seg(main_line->p2.x + pattern[aa_last_corner].x + 1,
|
||||
main_line->p2.y + pattern[aa_last_corner].y, -seg_w, mask,
|
||||
style->line.color, opa);
|
||||
}
|
||||
aa_last_corner = i;
|
||||
}
|
||||
} else {
|
||||
if(pattern[i - 1].y != pattern[i].y) {
|
||||
lv_coord_t seg_w = pattern[i].x - pattern[aa_last_corner].x;
|
||||
if(main_line->sx < 0) {
|
||||
lv_draw_aa_hor_seg(main_line->p1.x + pattern[aa_last_corner].x + seg_w + 1,
|
||||
main_line->p1.y + pattern[aa_last_corner].y - 1, seg_w, mask,
|
||||
style->line.color, opa);
|
||||
|
||||
lv_draw_aa_hor_seg(main_line->p2.x + pattern[aa_last_corner].x + seg_w + 1,
|
||||
main_line->p2.y + pattern[aa_last_corner].y + 1, -seg_w, mask,
|
||||
style->line.color, opa);
|
||||
} else {
|
||||
lv_draw_aa_hor_seg(main_line->p1.x + pattern[aa_last_corner].x,
|
||||
main_line->p1.y + pattern[aa_last_corner].y - 1, seg_w, mask,
|
||||
style->line.color, opa);
|
||||
|
||||
lv_draw_aa_hor_seg(main_line->p2.x + pattern[aa_last_corner].x,
|
||||
main_line->p2.y + pattern[aa_last_corner].y + 1, -seg_w, mask,
|
||||
style->line.color, opa);
|
||||
}
|
||||
aa_last_corner = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#if LV_ANTIALIAS
|
||||
/*Add the last part of anti-aliasing for the perpendicular ending*/
|
||||
if(width != 0 && aa) { /*Due to rounding error with very thin lines it looks ugly*/
|
||||
if(main_line->hor) {
|
||||
lv_coord_t seg_w = pattern[width_safe - 1].y - pattern[aa_last_corner].y;
|
||||
if(main_line->sy < 0) {
|
||||
lv_draw_aa_ver_seg(main_line->p1.x + pattern[aa_last_corner].x - 1,
|
||||
main_line->p1.y + pattern[aa_last_corner].y + seg_w, seg_w + main_line->sy, mask,
|
||||
style->line.color, opa);
|
||||
|
||||
lv_draw_aa_ver_seg(main_line->p2.x + pattern[aa_last_corner].x + 1,
|
||||
main_line->p2.y + pattern[aa_last_corner].y + seg_w, -(seg_w + main_line->sy), mask,
|
||||
style->line.color, opa);
|
||||
|
||||
} else {
|
||||
lv_draw_aa_ver_seg(main_line->p1.x + pattern[aa_last_corner].x - 1,
|
||||
main_line->p1.y + pattern[aa_last_corner].y, seg_w + main_line->sy, mask,
|
||||
style->line.color, opa);
|
||||
|
||||
lv_draw_aa_ver_seg(main_line->p2.x + pattern[aa_last_corner].x + 1,
|
||||
main_line->p2.y + pattern[aa_last_corner].y, -(seg_w + main_line->sy), mask,
|
||||
style->line.color, opa);
|
||||
}
|
||||
} else {
|
||||
lv_coord_t seg_w = pattern[width_safe - 1].x - pattern[aa_last_corner].x;
|
||||
if(main_line->sx < 0) {
|
||||
lv_draw_aa_hor_seg(main_line->p1.x + pattern[aa_last_corner].x + seg_w,
|
||||
main_line->p1.y + pattern[aa_last_corner].y - 1, seg_w + main_line->sx, mask,
|
||||
style->line.color, opa);
|
||||
|
||||
lv_draw_aa_hor_seg(main_line->p2.x + pattern[aa_last_corner].x + seg_w,
|
||||
main_line->p2.y + pattern[aa_last_corner].y + 1, -(seg_w + main_line->sx), mask,
|
||||
style->line.color, opa);
|
||||
|
||||
} else {
|
||||
lv_draw_aa_hor_seg(main_line->p1.x + pattern[aa_last_corner].x,
|
||||
main_line->p1.y + pattern[aa_last_corner].y - 1, seg_w + main_line->sx, mask,
|
||||
style->line.color, opa);
|
||||
|
||||
lv_draw_aa_hor_seg(main_line->p2.x + pattern[aa_last_corner].x,
|
||||
main_line->p2.y + pattern[aa_last_corner].y + 1, -(seg_w + main_line->sx), mask,
|
||||
style->line.color, opa);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#if LV_ANTIALIAS
|
||||
|
||||
/*Shift the anti aliasing on the edges (-1, 1 or 0 (zero only in case width == 0))*/
|
||||
lv_coord_t aa_shift1 = 0;
|
||||
lv_coord_t aa_shift2 = 0;
|
||||
if(aa) {
|
||||
if(main_line->hor == false) {
|
||||
if(main_line->sx < 0) {
|
||||
aa_shift1 = -1;
|
||||
aa_shift2 = width == 0 ? 0 : aa_shift1;
|
||||
} else {
|
||||
aa_shift2 = 1;
|
||||
aa_shift1 = width == 0 ? 0 : aa_shift2;
|
||||
}
|
||||
} else {
|
||||
if(main_line->sy < 0) {
|
||||
aa_shift1 = -1;
|
||||
aa_shift2 = width == 0 ? 0 : aa_shift1;
|
||||
} else {
|
||||
aa_shift2 = 1;
|
||||
aa_shift1 = width == 0 ? 0 : aa_shift2;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
volatile lv_point_t prev_p;
|
||||
prev_p.x = main_line->p1.x;
|
||||
prev_p.y = main_line->p1.y;
|
||||
lv_area_t draw_area;
|
||||
bool first_run = true;
|
||||
|
||||
if(main_line->hor) {
|
||||
while(line_next_y(main_line)) {
|
||||
for(i = 0; i < width; i++) {
|
||||
draw_area.x1 = prev_p.x + pattern[i].x;
|
||||
draw_area.y1 = prev_p.y + pattern[i].y;
|
||||
draw_area.x2 = draw_area.x1 + main_line->p_act.x - prev_p.x - 1;
|
||||
draw_area.y2 = draw_area.y1;
|
||||
lv_draw_fill(&draw_area, mask, style->line.color, opa);
|
||||
|
||||
/* Fill the gaps
|
||||
* When stepping in y one pixel remains empty on every corner (don't do this on the
|
||||
* first segment ) */
|
||||
if(i != 0 && pattern[i].x != pattern[i - 1].x && !first_run) {
|
||||
lv_draw_px(draw_area.x1, draw_area.y1 - main_line->sy, mask, style->line.color, opa);
|
||||
}
|
||||
}
|
||||
|
||||
#if LV_ANTIALIAS
|
||||
if(aa) {
|
||||
lv_draw_aa_hor_seg(prev_p.x + pattern[0].x, prev_p.y + pattern[0].y - aa_shift1,
|
||||
-(main_line->p_act.x - prev_p.x), mask, style->line.color, opa);
|
||||
lv_draw_aa_hor_seg(prev_p.x + pattern[width_safe - 1].x,
|
||||
prev_p.y + pattern[width_safe - 1].y + aa_shift2, main_line->p_act.x - prev_p.x,
|
||||
mask, style->line.color, opa);
|
||||
}
|
||||
#endif
|
||||
|
||||
first_run = false;
|
||||
|
||||
prev_p.x = main_line->p_act.x;
|
||||
prev_p.y = main_line->p_act.y;
|
||||
}
|
||||
|
||||
for(i = 0; i < width; i++) {
|
||||
draw_area.x1 = prev_p.x + pattern[i].x;
|
||||
draw_area.y1 = prev_p.y + pattern[i].y;
|
||||
draw_area.x2 = draw_area.x1 + main_line->p_act.x - prev_p.x;
|
||||
draw_area.y2 = draw_area.y1;
|
||||
lv_draw_fill(&draw_area, mask, style->line.color, opa);
|
||||
|
||||
/* Fill the gaps
|
||||
* When stepping in y one pixel remains empty on every corner */
|
||||
if(i != 0 && pattern[i].x != pattern[i - 1].x && !first_run) {
|
||||
lv_draw_px(draw_area.x1, draw_area.y1 - main_line->sy, mask, style->line.color, opa);
|
||||
}
|
||||
}
|
||||
|
||||
#if LV_ANTIALIAS
|
||||
if(aa) {
|
||||
lv_draw_aa_hor_seg(prev_p.x + pattern[0].x, prev_p.y + pattern[0].y - aa_shift1,
|
||||
-(main_line->p_act.x - prev_p.x + 1), mask, style->line.color, opa);
|
||||
lv_draw_aa_hor_seg(prev_p.x + pattern[width_safe - 1].x, prev_p.y + pattern[width_safe - 1].y + aa_shift2,
|
||||
main_line->p_act.x - prev_p.x + 1, mask, style->line.color, opa);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
/*Rather a vertical line*/
|
||||
else {
|
||||
|
||||
while(line_next_x(main_line)) {
|
||||
for(i = 0; i < width; i++) {
|
||||
draw_area.x1 = prev_p.x + pattern[i].x;
|
||||
draw_area.y1 = prev_p.y + pattern[i].y;
|
||||
draw_area.x2 = draw_area.x1;
|
||||
draw_area.y2 = draw_area.y1 + main_line->p_act.y - prev_p.y - 1;
|
||||
|
||||
lv_draw_fill(&draw_area, mask, style->line.color, opa);
|
||||
|
||||
/* Fill the gaps
|
||||
* When stepping in x one pixel remains empty on every corner (don't do this on the
|
||||
* first segment ) */
|
||||
if(i != 0 && pattern[i].y != pattern[i - 1].y && !first_run) {
|
||||
lv_draw_px(draw_area.x1 - main_line->sx, draw_area.y1, mask, style->line.color, opa);
|
||||
}
|
||||
}
|
||||
|
||||
#if LV_ANTIALIAS
|
||||
if(aa) {
|
||||
lv_draw_aa_ver_seg(prev_p.x + pattern[0].x - aa_shift1, prev_p.y + pattern[0].y,
|
||||
-(main_line->p_act.y - prev_p.y), mask, style->line.color, opa);
|
||||
lv_draw_aa_ver_seg(prev_p.x + pattern[width_safe - 1].x + aa_shift2,
|
||||
prev_p.y + pattern[width_safe - 1].y, main_line->p_act.y - prev_p.y, mask,
|
||||
style->line.color, opa);
|
||||
}
|
||||
#endif
|
||||
|
||||
first_run = false;
|
||||
|
||||
prev_p.x = main_line->p_act.x;
|
||||
prev_p.y = main_line->p_act.y;
|
||||
}
|
||||
|
||||
/*Draw the last part*/
|
||||
for(i = 0; i < width; i++) {
|
||||
draw_area.x1 = prev_p.x + pattern[i].x;
|
||||
draw_area.y1 = prev_p.y + pattern[i].y;
|
||||
draw_area.x2 = draw_area.x1;
|
||||
draw_area.y2 = draw_area.y1 + main_line->p_act.y - prev_p.y;
|
||||
|
||||
lv_draw_fill(&draw_area, mask, style->line.color, opa);
|
||||
|
||||
/* Fill the gaps
|
||||
* When stepping in x one pixel remains empty on every corner */
|
||||
if(i != 0 && pattern[i].y != pattern[i - 1].y && !first_run) {
|
||||
lv_draw_px(draw_area.x1 - main_line->sx, draw_area.y1, mask, style->line.color, opa);
|
||||
}
|
||||
}
|
||||
|
||||
#if LV_ANTIALIAS
|
||||
if(aa) {
|
||||
lv_draw_aa_ver_seg(prev_p.x + pattern[0].x - aa_shift1, prev_p.y + pattern[0].y,
|
||||
-(main_line->p_act.y - prev_p.y + 1), mask, style->line.color, opa);
|
||||
lv_draw_aa_ver_seg(prev_p.x + pattern[width_safe - 1].x + aa_shift2, prev_p.y + pattern[width_safe - 1].y,
|
||||
main_line->p_act.y - prev_p.y + 1, mask, style->line.color, opa);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
static void line_init(line_draw_t * line, const lv_point_t * p1, const lv_point_t * p2)
|
||||
{
|
||||
line->p1.x = p1->x;
|
||||
line->p1.y = p1->y;
|
||||
line->p2.x = p2->x;
|
||||
line->p2.y = p2->y;
|
||||
|
||||
line->dx = LV_MATH_ABS(line->p2.x - line->p1.x);
|
||||
line->sx = line->p1.x < line->p2.x ? 1 : -1;
|
||||
line->dy = LV_MATH_ABS(line->p2.y - line->p1.y);
|
||||
line->sy = line->p1.y < line->p2.y ? 1 : -1;
|
||||
line->err = (line->dx > line->dy ? line->dx : -line->dy) / 2;
|
||||
line->e2 = 0;
|
||||
line->hor = line->dx > line->dy ? true : false; /*Rather horizontal or vertical*/
|
||||
|
||||
line->p_act.x = line->p1.x;
|
||||
line->p_act.y = line->p1.y;
|
||||
}
|
||||
|
||||
static bool line_next(line_draw_t * line)
|
||||
{
|
||||
if(line->p_act.x == line->p2.x && line->p_act.y == line->p2.y) return false;
|
||||
line->e2 = line->err;
|
||||
if(line->e2 > -line->dx) {
|
||||
line->err -= line->dy;
|
||||
line->p_act.x += line->sx;
|
||||
}
|
||||
if(line->e2 < line->dy) {
|
||||
line->err += line->dx;
|
||||
line->p_act.y += line->sy;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Iterate until step one in y direction.
|
||||
* @param line
|
||||
* @return
|
||||
*/
|
||||
static bool line_next_y(line_draw_t * line)
|
||||
{
|
||||
lv_coord_t last_y = line->p_act.y;
|
||||
|
||||
do {
|
||||
if(!line_next(line)) return false;
|
||||
} while(last_y == line->p_act.y);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Iterate until step one in x direction.
|
||||
* @param line
|
||||
* @return
|
||||
*/
|
||||
static bool line_next_x(line_draw_t * line)
|
||||
{
|
||||
lv_coord_t last_x = line->p_act.x;
|
||||
|
||||
do {
|
||||
if(!line_next(line)) return false;
|
||||
} while(last_x == line->p_act.x);
|
||||
|
||||
return true;
|
||||
}
|
@ -1,48 +0,0 @@
|
||||
/**
|
||||
* @file lv_draw_line.h
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LV_DRAW_LINE_H
|
||||
#define LV_DRAW_LINE_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Draw a line
|
||||
* @param point1 first point of the line
|
||||
* @param point2 second point of the line
|
||||
* @param mask the line will be drawn only on this area
|
||||
* @param style pointer to a line's style
|
||||
* @param opa_scale scale down all opacities by the factor
|
||||
*/
|
||||
void lv_draw_line(const lv_point_t * point1, const lv_point_t * point2, const lv_area_t * mask,
|
||||
const lv_style_t * style, lv_opa_t opa_scale);
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif /*LV_DRAW_LINE_H*/
|
File diff suppressed because it is too large
Load Diff
@ -1,47 +0,0 @@
|
||||
/**
|
||||
* @file lv_draw_rect.h
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LV_DRAW_RECT_H
|
||||
#define LV_DRAW_RECT_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "lv_draw.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Draw a rectangle
|
||||
* @param coords the coordinates of the rectangle
|
||||
* @param mask the rectangle will be drawn only in this mask
|
||||
* @param style pointer to a style
|
||||
* @param opa_scale scale down all opacities by the factor
|
||||
*/
|
||||
void lv_draw_rect(const lv_area_t * coords, const lv_area_t * mask, const lv_style_t * style, lv_opa_t opa_scale);
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif /*LV_DRAW_RECT_H*/
|
@ -1,343 +0,0 @@
|
||||
/**
|
||||
* @file lv_draw_triangle.c
|
||||
*
|
||||
*/
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "lv_draw_triangle.h"
|
||||
#include "../lv_misc/lv_math.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
void tri_draw_flat(const lv_point_t * points, const lv_area_t * mask, const lv_style_t * style, lv_opa_t opa);
|
||||
void tri_draw_tall(const lv_point_t * points, const lv_area_t * mask, const lv_style_t * style, lv_opa_t opa);
|
||||
static void point_swap(lv_point_t * p1, lv_point_t * p2);
|
||||
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL FUNCTIONS
|
||||
**********************/
|
||||
|
||||
/**
|
||||
*
|
||||
* @param points pointer to an array with 3 points
|
||||
* @param mask the triangle will be drawn only in this mask
|
||||
* @param style style for of the triangle
|
||||
* @param opa_scale scale down all opacities by the factor (0..255)
|
||||
*/
|
||||
void lv_draw_triangle(const lv_point_t * points, const lv_area_t * mask, const lv_style_t * style, lv_opa_t opa_scale)
|
||||
{
|
||||
/*Return if the triangle is degenerated*/
|
||||
if(points[0].x == points[1].x && points[0].y == points[1].y) return;
|
||||
if(points[1].x == points[2].x && points[1].y == points[2].y) return;
|
||||
if(points[0].x == points[2].x && points[0].y == points[2].y) return;
|
||||
|
||||
if(points[0].x == points[1].x && points[1].x == points[2].x) return;
|
||||
if(points[0].y == points[1].y && points[1].y == points[2].y) return;
|
||||
|
||||
lv_opa_t opa = opa_scale == LV_OPA_COVER ? style->body.opa : (uint16_t)((uint16_t)style->body.opa * opa_scale) >> 8;
|
||||
|
||||
/*Is the triangle flat or tall?*/
|
||||
lv_coord_t x_min = LV_MATH_MIN(LV_MATH_MIN(points[0].x, points[1].x), points[2].x);
|
||||
lv_coord_t x_max = LV_MATH_MAX(LV_MATH_MAX(points[0].x, points[1].x), points[2].x);
|
||||
lv_coord_t y_min = LV_MATH_MIN(LV_MATH_MIN(points[0].y, points[1].y), points[2].y);
|
||||
lv_coord_t y_max = LV_MATH_MAX(LV_MATH_MAX(points[0].y, points[1].y), points[2].y);
|
||||
|
||||
/* Draw the tall rectangles from vertical lines
|
||||
* and from the flat triangles from horizontal lines
|
||||
* to minimize the number of lines.
|
||||
* Some pixels are overdrawn on the common edges of the triangles
|
||||
* so use it only if the triangle has no opacity*/
|
||||
|
||||
/* Draw from horizontal lines*/
|
||||
if(x_max - x_min < y_max - y_min) {
|
||||
tri_draw_tall(points, mask, style, opa);
|
||||
}
|
||||
/*Else flat so draw from vertical lines*/
|
||||
else {
|
||||
tri_draw_flat(points, mask, style, opa);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Draw a polygon from triangles. Only convex polygons are supported
|
||||
* @param points an array of points
|
||||
* @param point_cnt number of points
|
||||
* @param mask polygon will be drawn only in this mask
|
||||
* @param style style of the polygon
|
||||
* @param opa_scale scale down all opacities by the factor (0..255)
|
||||
*/
|
||||
void lv_draw_polygon(const lv_point_t * points, uint32_t point_cnt, const lv_area_t * mask, const lv_style_t * style,
|
||||
lv_opa_t opa_scale)
|
||||
{
|
||||
if(point_cnt < 3) return;
|
||||
if(points == NULL) return;
|
||||
|
||||
uint32_t i;
|
||||
lv_point_t tri[3];
|
||||
tri[0].x = points[0].x;
|
||||
tri[0].y = points[0].y;
|
||||
for(i = 0; i < point_cnt - 1; i++) {
|
||||
tri[1].x = points[i].x;
|
||||
tri[1].y = points[i].y;
|
||||
tri[2].x = points[i + 1].x;
|
||||
tri[2].y = points[i + 1].y;
|
||||
lv_draw_triangle(tri, mask, style, opa_scale);
|
||||
}
|
||||
}
|
||||
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
|
||||
void tri_draw_flat(const lv_point_t * points, const lv_area_t * mask, const lv_style_t * style, lv_opa_t opa)
|
||||
{
|
||||
/*Return if the points are out of the mask*/
|
||||
if(points[0].x < mask->x1 && points[1].x < mask->x1 && points[2].x < mask->x1) {
|
||||
return;
|
||||
}
|
||||
|
||||
if(points[0].x > mask->x2 && points[1].x > mask->x2 && points[2].x > mask->x2) {
|
||||
return;
|
||||
}
|
||||
|
||||
if(points[0].y < mask->y1 && points[1].y < mask->y1 && points[2].y < mask->y1) {
|
||||
return;
|
||||
}
|
||||
|
||||
if(points[0].y > mask->y2 && points[1].y > mask->y2 && points[2].y > mask->y2) {
|
||||
return;
|
||||
}
|
||||
|
||||
lv_point_t tri[3];
|
||||
|
||||
memcpy(tri, points, sizeof(tri));
|
||||
|
||||
/*Sort the vertices according to their y coordinate (0: y max, 1: y mid, 2:y min)*/
|
||||
if(tri[1].y < tri[0].y) point_swap(&tri[1], &tri[0]);
|
||||
if(tri[2].y < tri[1].y) point_swap(&tri[2], &tri[1]);
|
||||
if(tri[1].y < tri[0].y) point_swap(&tri[1], &tri[0]);
|
||||
|
||||
/*Draw the triangle*/
|
||||
lv_point_t edge1;
|
||||
lv_coord_t dx1 = LV_MATH_ABS(tri[0].x - tri[1].x);
|
||||
lv_coord_t sx1 = tri[0].x < tri[1].x ? 1 : -1;
|
||||
lv_coord_t dy1 = LV_MATH_ABS(tri[0].y - tri[1].y);
|
||||
lv_coord_t sy1 = tri[0].y < tri[1].y ? 1 : -1;
|
||||
lv_coord_t err1 = (dx1 > dy1 ? dx1 : -dy1) / 2;
|
||||
lv_coord_t err_tmp1;
|
||||
|
||||
lv_point_t edge2;
|
||||
lv_coord_t dx2 = LV_MATH_ABS(tri[0].x - tri[2].x);
|
||||
lv_coord_t sx2 = tri[0].x < tri[2].x ? 1 : -1;
|
||||
lv_coord_t dy2 = LV_MATH_ABS(tri[0].y - tri[2].y);
|
||||
lv_coord_t sy2 = tri[0].y < tri[2].y ? 1 : -1;
|
||||
lv_coord_t err2 = (dx1 > dy2 ? dx2 : -dy2) / 2;
|
||||
lv_coord_t err_tmp2;
|
||||
|
||||
lv_coord_t y1_tmp;
|
||||
lv_coord_t y2_tmp;
|
||||
|
||||
edge1.x = tri[0].x;
|
||||
edge1.y = tri[0].y;
|
||||
edge2.x = tri[0].x;
|
||||
edge2.y = tri[0].y;
|
||||
lv_area_t act_area;
|
||||
lv_area_t draw_area;
|
||||
|
||||
while(1) {
|
||||
act_area.x1 = edge1.x;
|
||||
act_area.x2 = edge2.x;
|
||||
act_area.y1 = edge1.y;
|
||||
act_area.y2 = edge2.y;
|
||||
|
||||
/* Get the area of a line.
|
||||
* Adjust it a little bit to perfectly match (no redrawn pixels) with the adjacent triangles*/
|
||||
draw_area.x1 = LV_MATH_MIN(act_area.x1, act_area.x2) + 1;
|
||||
draw_area.x2 = LV_MATH_MAX(act_area.x1, act_area.x2);
|
||||
draw_area.y1 = LV_MATH_MIN(act_area.y1, act_area.y2) - 1;
|
||||
draw_area.y2 = LV_MATH_MAX(act_area.y1, act_area.y2) - 1;
|
||||
|
||||
lv_draw_fill(&draw_area, mask, style->body.main_color, opa);
|
||||
|
||||
/*Calc. the next point of edge1*/
|
||||
y1_tmp = edge1.y;
|
||||
do {
|
||||
if(edge1.x == tri[1].x && edge1.y == tri[1].y) {
|
||||
|
||||
dx1 = LV_MATH_ABS(tri[1].x - tri[2].x);
|
||||
sx1 = tri[1].x < tri[2].x ? 1 : -1;
|
||||
dy1 = LV_MATH_ABS(tri[1].y - tri[2].y);
|
||||
sy1 = tri[1].y < tri[2].y ? 1 : -1;
|
||||
err1 = (dx1 > dy1 ? dx1 : -dy1) / 2;
|
||||
} else if(edge1.x == tri[2].x && edge1.y == tri[2].y) {
|
||||
return;
|
||||
}
|
||||
err_tmp1 = err1;
|
||||
if(err_tmp1 > -dx1) {
|
||||
err1 -= dy1;
|
||||
edge1.x += sx1;
|
||||
}
|
||||
if(err_tmp1 < dy1) {
|
||||
err1 += dx1;
|
||||
edge1.y += sy1;
|
||||
}
|
||||
} while(edge1.y == y1_tmp);
|
||||
|
||||
/*Calc. the next point of edge2*/
|
||||
y2_tmp = edge2.y;
|
||||
do {
|
||||
if(edge2.x == tri[2].x && edge2.y == tri[2].y) return;
|
||||
err_tmp2 = err2;
|
||||
if(err_tmp2 > -dx2) {
|
||||
err2 -= dy2;
|
||||
edge2.x += sx2;
|
||||
}
|
||||
if(err_tmp2 < dy2) {
|
||||
err2 += dx2;
|
||||
edge2.y += sy2;
|
||||
}
|
||||
} while(edge2.y == y2_tmp);
|
||||
}
|
||||
}
|
||||
|
||||
void tri_draw_tall(const lv_point_t * points, const lv_area_t * mask, const lv_style_t * style, lv_opa_t opa)
|
||||
{
|
||||
/*
|
||||
* Better to draw from vertical lines
|
||||
* |\
|
||||
* | |
|
||||
* | |
|
||||
* | \
|
||||
* | |
|
||||
* |___|
|
||||
*/
|
||||
|
||||
lv_point_t tri[3];
|
||||
|
||||
memcpy(tri, points, sizeof(tri));
|
||||
|
||||
/*Sort the vertices according to their x coordinate (0: x max, 1: x mid, 2:x min)*/
|
||||
if(tri[1].x < tri[0].x) point_swap(&tri[1], &tri[0]);
|
||||
if(tri[2].x < tri[1].x) point_swap(&tri[2], &tri[1]);
|
||||
if(tri[1].x < tri[0].x) point_swap(&tri[1], &tri[0]);
|
||||
|
||||
/*Draw the triangle*/
|
||||
lv_point_t edge1;
|
||||
lv_coord_t dx1 = LV_MATH_ABS(tri[0].x - tri[1].x);
|
||||
lv_coord_t sx1 = tri[0].x < tri[1].x ? 1 : -1;
|
||||
lv_coord_t dy1 = LV_MATH_ABS(tri[0].y - tri[1].y);
|
||||
lv_coord_t sy1 = tri[0].y < tri[1].y ? 1 : -1;
|
||||
lv_coord_t err1 = (dx1 > dy1 ? dx1 : -dy1) / 2;
|
||||
lv_coord_t err_tmp1;
|
||||
|
||||
lv_point_t edge2;
|
||||
lv_coord_t dx2 = LV_MATH_ABS(tri[0].x - tri[2].x);
|
||||
lv_coord_t sx2 = tri[0].x < tri[2].x ? 1 : -1;
|
||||
lv_coord_t dy2 = LV_MATH_ABS(tri[0].y - tri[2].y);
|
||||
lv_coord_t sy2 = tri[0].y < tri[2].y ? 1 : -1;
|
||||
lv_coord_t err2 = (dx1 > dy2 ? dx2 : -dy2) / 2;
|
||||
lv_coord_t err_tmp2;
|
||||
|
||||
lv_coord_t x1_tmp;
|
||||
lv_coord_t x2_tmp;
|
||||
|
||||
edge1.x = tri[0].x;
|
||||
edge1.y = tri[0].y;
|
||||
edge2.x = tri[0].x;
|
||||
edge2.y = tri[0].y;
|
||||
lv_area_t act_area;
|
||||
lv_area_t draw_area;
|
||||
|
||||
while(1) {
|
||||
act_area.x1 = edge1.x;
|
||||
act_area.x2 = edge2.x;
|
||||
act_area.y1 = edge1.y;
|
||||
act_area.y2 = edge2.y;
|
||||
|
||||
draw_area.x1 = LV_MATH_MIN(act_area.x1, act_area.x2);
|
||||
draw_area.x2 = LV_MATH_MAX(act_area.x1, act_area.x2);
|
||||
draw_area.y1 = LV_MATH_MIN(act_area.y1, act_area.y2);
|
||||
draw_area.y2 = LV_MATH_MAX(act_area.y1, act_area.y2) - 1;
|
||||
|
||||
lv_draw_fill(&draw_area, mask, style->body.main_color, opa);
|
||||
|
||||
/*Calc. the next point of edge1*/
|
||||
x1_tmp = edge1.x;
|
||||
do {
|
||||
if(edge1.y == tri[1].y && edge1.x == tri[1].x) {
|
||||
|
||||
dx1 = LV_MATH_ABS(tri[1].x - tri[2].x);
|
||||
sx1 = tri[1].x < tri[2].x ? 1 : -1;
|
||||
dy1 = LV_MATH_ABS(tri[1].y - tri[2].y);
|
||||
sy1 = tri[1].y < tri[2].y ? 1 : -1;
|
||||
err1 = (dx1 > dy1 ? dx1 : -dy1) / 2;
|
||||
} else if(edge1.y == tri[2].y && edge1.x == tri[2].x) {
|
||||
return;
|
||||
}
|
||||
err_tmp1 = err1;
|
||||
if(err_tmp1 > -dx1) {
|
||||
err1 -= dy1;
|
||||
edge1.x += sx1;
|
||||
}
|
||||
if(err_tmp1 < dy1) {
|
||||
err1 += dx1;
|
||||
edge1.y += sy1;
|
||||
}
|
||||
} while(edge1.x == x1_tmp);
|
||||
|
||||
/*Calc. the next point of edge2*/
|
||||
x2_tmp = edge2.x;
|
||||
do {
|
||||
if(edge2.y == tri[2].y && edge2.x == tri[2].x) {
|
||||
return;
|
||||
}
|
||||
|
||||
err_tmp2 = err2;
|
||||
if(err_tmp2 > -dx2) {
|
||||
err2 -= dy2;
|
||||
edge2.x += sx2;
|
||||
}
|
||||
if(err_tmp2 < dy2) {
|
||||
err2 += dx2;
|
||||
edge2.y += sy2;
|
||||
}
|
||||
} while(edge2.x == x2_tmp);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Swap two points
|
||||
* p1 pointer to the first point
|
||||
* p2 pointer to the second point
|
||||
*/
|
||||
static void point_swap(lv_point_t * p1, lv_point_t * p2)
|
||||
{
|
||||
lv_point_t tmp;
|
||||
tmp.x = p1->x;
|
||||
tmp.y = p1->y;
|
||||
|
||||
p1->x = p2->x;
|
||||
p1->y = p2->y;
|
||||
|
||||
p2->x = tmp.x;
|
||||
p2->y = tmp.y;
|
||||
}
|
@ -1,58 +0,0 @@
|
||||
/**
|
||||
* @file lv_draw_triangle.h
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LV_DRAW_TRIANGLE_H
|
||||
#define LV_DRAW_TRIANGLE_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "lv_draw.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/**
|
||||
*
|
||||
* @param points pointer to an array with 3 points
|
||||
* @param mask the triangle will be drawn only in this mask
|
||||
* @param style style for of the triangle
|
||||
* @param opa_scale scale down all opacities by the factor (0..255)
|
||||
*/
|
||||
void lv_draw_triangle(const lv_point_t * points, const lv_area_t * mask, const lv_style_t * style, lv_opa_t opa_scale);
|
||||
|
||||
/**
|
||||
* Draw a polygon from triangles. Only convex polygons are supported
|
||||
* @param points an array of points
|
||||
* @param point_cnt number of points
|
||||
* @param mask polygon will be drawn only in this mask
|
||||
* @param style style of the polygon
|
||||
* @param opa_scale scale down all opacities by the factor (0..255)
|
||||
*/
|
||||
void lv_draw_polygon(const lv_point_t * points, uint32_t point_cnt, const lv_area_t * mask, const lv_style_t * style,
|
||||
lv_opa_t opa_scale);
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif /*LV_DRAW_TRIANGLE_H*/
|
@ -1,206 +0,0 @@
|
||||
/**
|
||||
* @file lv_img_cache.c
|
||||
*
|
||||
*/
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "../lv_core/lv_debug.h"
|
||||
#include "lv_img_cache.h"
|
||||
#include "lv_img_decoder.h"
|
||||
#include "lv_draw_img.h"
|
||||
#include "../lv_hal/lv_hal_tick.h"
|
||||
#include "../lv_misc/lv_gc.h"
|
||||
|
||||
#if defined(LV_GC_INCLUDE)
|
||||
#include LV_GC_INCLUDE
|
||||
#endif /* LV_ENABLE_GC */
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
/*Decrement life with this value in every open*/
|
||||
#define LV_IMG_CACHE_AGING 1
|
||||
|
||||
/*Boost life by this factor (multiply time_to_open with this value)*/
|
||||
#define LV_IMG_CACHE_LIFE_GAIN 1
|
||||
|
||||
/*Don't let life to be greater than this limit because it would require a lot of time to
|
||||
* "die" from very high values */
|
||||
#define LV_IMG_CACHE_LIFE_LIMIT 1000
|
||||
|
||||
#if LV_IMG_CACHE_DEF_SIZE < 1
|
||||
#error "LV_IMG_CACHE_DEF_SIZE must be >= 1. See lv_conf.h"
|
||||
#endif
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
**********************/
|
||||
static uint16_t entry_cnt;
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL FUNCTIONS
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Open an image using the image decoder interface and cache it.
|
||||
* The image will be left open meaning if the image decoder open callback allocated memory then it will remain.
|
||||
* The image is closed if a new image is opened and the new image takes its place in the cache.
|
||||
* @param src source of the image. Path to file or pointer to an `lv_img_dsc_t` variable
|
||||
* @param style style of the image
|
||||
* @return pointer to the cache entry or NULL if can open the image
|
||||
*/
|
||||
lv_img_cache_entry_t * lv_img_cache_open(const void * src, const lv_style_t * style)
|
||||
{
|
||||
if(entry_cnt == 0) {
|
||||
LV_LOG_WARN("lv_img_cache_open: the cache size is 0");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
lv_img_cache_entry_t * cache = LV_GC_ROOT(_lv_img_cache_array);
|
||||
|
||||
/*Decrement all lifes. Make the entries older*/
|
||||
uint16_t i;
|
||||
for(i = 0; i < entry_cnt; i++) {
|
||||
if(cache[i].life > INT32_MIN + LV_IMG_CACHE_AGING) {
|
||||
cache[i].life -= LV_IMG_CACHE_AGING;
|
||||
}
|
||||
}
|
||||
|
||||
/*Is the image cached?*/
|
||||
lv_img_cache_entry_t * cached_src = NULL;
|
||||
for(i = 0; i < entry_cnt; i++) {
|
||||
bool match = false;
|
||||
lv_img_src_t src_type = lv_img_src_get_type(cache[i].dec_dsc.src);
|
||||
if(src_type == LV_IMG_SRC_VARIABLE) {
|
||||
if(cache[i].dec_dsc.src == src && cache[i].dec_dsc.style == style) match = true;
|
||||
} else if(src_type == LV_IMG_SRC_FILE) {
|
||||
if(strcmp(cache[i].dec_dsc.src, src) == 0) match = true;
|
||||
}
|
||||
|
||||
if(match) {
|
||||
/* If opened increment its life.
|
||||
* Image difficult to open should live longer to keep avoid frequent their recaching.
|
||||
* Therefore increase `life` with `time_to_open`*/
|
||||
cached_src = &cache[i];
|
||||
cached_src->life += cached_src->dec_dsc.time_to_open * LV_IMG_CACHE_LIFE_GAIN;
|
||||
if(cached_src->life > LV_IMG_CACHE_LIFE_LIMIT) cached_src->life = LV_IMG_CACHE_LIFE_LIMIT;
|
||||
LV_LOG_TRACE("image draw: image found in the cache");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*The image is not cached then cache it now*/
|
||||
if(cached_src == NULL) {
|
||||
/*Find an entry to reuse. Select the entry with the least life*/
|
||||
cached_src = &cache[0];
|
||||
for(i = 1; i < entry_cnt; i++) {
|
||||
if(cache[i].life < cached_src->life) {
|
||||
cached_src = &cache[i];
|
||||
}
|
||||
}
|
||||
|
||||
/*Close the decoder to reuse if it was opened (has a valid source)*/
|
||||
if(cached_src->dec_dsc.src) {
|
||||
lv_img_decoder_close(&cached_src->dec_dsc);
|
||||
LV_LOG_INFO("image draw: cache miss, close and reuse an entry");
|
||||
} else {
|
||||
LV_LOG_INFO("image draw: cache miss, cached to an empty entry");
|
||||
}
|
||||
|
||||
/*Open the image and measure the time to open*/
|
||||
uint32_t t_start;
|
||||
t_start = lv_tick_get();
|
||||
cached_src->dec_dsc.time_to_open = 0;
|
||||
lv_res_t open_res = lv_img_decoder_open(&cached_src->dec_dsc, src, style);
|
||||
if(open_res == LV_RES_INV) {
|
||||
LV_LOG_WARN("Image draw cannot open the image resource");
|
||||
lv_img_decoder_close(&cached_src->dec_dsc);
|
||||
memset(&cached_src->dec_dsc, 0, sizeof(lv_img_decoder_dsc_t));
|
||||
memset(cached_src, 0, sizeof(lv_img_cache_entry_t));
|
||||
cached_src->life = INT32_MIN; /*Make the empty entry very "weak" to force its use */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
cached_src->life = 0;
|
||||
|
||||
/*If `time_to_open` was not set in the open function set it here*/
|
||||
if(cached_src->dec_dsc.time_to_open == 0) {
|
||||
cached_src->dec_dsc.time_to_open = lv_tick_elaps(t_start);
|
||||
}
|
||||
|
||||
if(cached_src->dec_dsc.time_to_open == 0) cached_src->dec_dsc.time_to_open = 1;
|
||||
}
|
||||
|
||||
return cached_src;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the number of images to be cached.
|
||||
* More cached images mean more opened image at same time which might mean more memory usage.
|
||||
* E.g. if 20 PNG or JPG images are open in the RAM they consume memory while opened in the cache.
|
||||
* @param new_entry_cnt number of image to cache
|
||||
*/
|
||||
void lv_img_cache_set_size(uint16_t new_entry_cnt)
|
||||
{
|
||||
if(LV_GC_ROOT(_lv_img_cache_array) != NULL) {
|
||||
/*Clean the cache before free it*/
|
||||
lv_img_cache_invalidate_src(NULL);
|
||||
lv_mem_free(LV_GC_ROOT(_lv_img_cache_array));
|
||||
}
|
||||
|
||||
/*Reallocate the cache*/
|
||||
LV_GC_ROOT(_lv_img_cache_array) = lv_mem_alloc(sizeof(lv_img_cache_entry_t) * new_entry_cnt);
|
||||
LV_ASSERT_MEM(LV_GC_ROOT(_lv_img_cache_array));
|
||||
if(LV_GC_ROOT(_lv_img_cache_array) == NULL) {
|
||||
entry_cnt = 0;
|
||||
return;
|
||||
}
|
||||
entry_cnt = new_entry_cnt;
|
||||
|
||||
/*Clean the cache*/
|
||||
uint16_t i;
|
||||
for(i = 0; i < entry_cnt; i++) {
|
||||
memset(&LV_GC_ROOT(_lv_img_cache_array)[i].dec_dsc, 0, sizeof(lv_img_decoder_dsc_t));
|
||||
memset(&LV_GC_ROOT(_lv_img_cache_array)[i], 0, sizeof(lv_img_cache_entry_t));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Invalidate an image source in the cache.
|
||||
* Useful if the image source is updated therefore it needs to be cached again.
|
||||
* @param src an image source path to a file or pointer to an `lv_img_dsc_t` variable.
|
||||
*/
|
||||
void lv_img_cache_invalidate_src(const void * src)
|
||||
{
|
||||
|
||||
lv_img_cache_entry_t * cache = LV_GC_ROOT(_lv_img_cache_array);
|
||||
|
||||
uint16_t i;
|
||||
for(i = 0; i < entry_cnt; i++) {
|
||||
if(cache[i].dec_dsc.src == src || src == NULL) {
|
||||
if(cache[i].dec_dsc.src != NULL) {
|
||||
lv_img_decoder_close(&cache[i].dec_dsc);
|
||||
}
|
||||
|
||||
memset(&cache[i].dec_dsc, 0, sizeof(lv_img_decoder_dsc_t));
|
||||
memset(&cache[i], 0, sizeof(lv_img_cache_entry_t));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
@ -1,78 +0,0 @@
|
||||
/**
|
||||
* @file lv_img_cache.h
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LV_IMG_CACHE_H
|
||||
#define LV_IMG_CACHE_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "lv_img_decoder.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* When loading images from the network it can take a long time to download and decode the image.
|
||||
*
|
||||
* To avoid repeating this heavy load images can be cached.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
lv_img_decoder_dsc_t dec_dsc; /**< Image information */
|
||||
|
||||
/** Count the cache entries's life. Add `time_tio_open` to `life` when the entry is used.
|
||||
* Decrement all lifes by one every in every ::lv_img_cache_open.
|
||||
* If life == 0 the entry can be reused */
|
||||
int32_t life;
|
||||
} lv_img_cache_entry_t;
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Open an image using the image decoder interface and cache it.
|
||||
* The image will be left open meaning if the image decoder open callback allocated memory then it will remain.
|
||||
* The image is closed if a new image is opened and the new image takes its place in the cache.
|
||||
* @param src source of the image. Path to file or pointer to an `lv_img_dsc_t` variable
|
||||
* @param style style of the image
|
||||
* @return pointer to the cache entry or NULL if can open the image
|
||||
*/
|
||||
lv_img_cache_entry_t * lv_img_cache_open(const void * src, const lv_style_t * style);
|
||||
|
||||
/**
|
||||
* Set the number of images to be cached.
|
||||
* More cached images mean more opened image at same time which might mean more memory usage.
|
||||
* E.g. if 20 PNG or JPG images are open in the RAM they consume memory while opened in the cache.
|
||||
* @param new_entry_cnt number of image to cache
|
||||
*/
|
||||
void lv_img_cache_set_size(uint16_t new_slot_num);
|
||||
|
||||
/**
|
||||
* Invalidate an image source in the cache.
|
||||
* Useful if the image source is updated therefore it needs to be cached again.
|
||||
* @param src an image source path to a file or pointer to an `lv_img_dsc_t` variable.
|
||||
*/
|
||||
void lv_img_cache_invalidate_src(const void * src);
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif /*LV_IMG_CACHE_H*/
|
@ -1,756 +0,0 @@
|
||||
/**
|
||||
* @file lv_img_decoder.c
|
||||
*
|
||||
*/
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "lv_img_decoder.h"
|
||||
#include "../lv_core/lv_debug.h"
|
||||
#include "../lv_draw/lv_draw_img.h"
|
||||
#include "../lv_misc/lv_ll.h"
|
||||
#include "../lv_misc/lv_color.h"
|
||||
#include "../lv_misc/lv_gc.h"
|
||||
|
||||
#if defined(LV_GC_INCLUDE)
|
||||
#include LV_GC_INCLUDE
|
||||
#endif /* LV_ENABLE_GC */
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
#define CF_BUILT_IN_FIRST LV_IMG_CF_TRUE_COLOR
|
||||
#define CF_BUILT_IN_LAST LV_IMG_CF_ALPHA_8BIT
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
typedef struct
|
||||
{
|
||||
#if LV_USE_FILESYSTEM
|
||||
lv_fs_file_t * f;
|
||||
#endif
|
||||
lv_color_t * palette;
|
||||
lv_opa_t * opa;
|
||||
} lv_img_decoder_built_in_data_t;
|
||||
|
||||
/**********************
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
static lv_res_t lv_img_decoder_built_in_line_true_color(lv_img_decoder_dsc_t * dsc, lv_coord_t x, lv_coord_t y,
|
||||
lv_coord_t len, uint8_t * buf);
|
||||
static lv_res_t lv_img_decoder_built_in_line_alpha(lv_img_decoder_dsc_t * dsc, lv_coord_t x, lv_coord_t y,
|
||||
lv_coord_t len, uint8_t * buf);
|
||||
static lv_res_t lv_img_decoder_built_in_line_indexed(lv_img_decoder_dsc_t * dsc, lv_coord_t x, lv_coord_t y,
|
||||
lv_coord_t len, uint8_t * buf);
|
||||
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL FUNCTIONS
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Initialize the image decoder module
|
||||
* */
|
||||
void lv_img_decoder_init(void)
|
||||
{
|
||||
lv_ll_init(&LV_GC_ROOT(_lv_img_defoder_ll), sizeof(lv_img_decoder_t));
|
||||
|
||||
lv_img_decoder_t * decoder;
|
||||
|
||||
/*Create a decoder for the built in color format*/
|
||||
decoder = lv_img_decoder_create();
|
||||
if(decoder == NULL) {
|
||||
LV_LOG_WARN("lv_img_decoder_init: out of memory");
|
||||
LV_ASSERT_MEM(decoder);
|
||||
return;
|
||||
}
|
||||
|
||||
lv_img_decoder_set_info_cb(decoder, lv_img_decoder_built_in_info);
|
||||
lv_img_decoder_set_open_cb(decoder, lv_img_decoder_built_in_open);
|
||||
lv_img_decoder_set_read_line_cb(decoder, lv_img_decoder_built_in_read_line);
|
||||
lv_img_decoder_set_close_cb(decoder, lv_img_decoder_built_in_close);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get information about an image.
|
||||
* Try the created image decoder one by one. Once one is able to get info that info will be used.
|
||||
* @param src the image source. E.g. file name or variable.
|
||||
* @param header the image info will be stored here
|
||||
* @return LV_RES_OK: success; LV_RES_INV: wasn't able to get info about the image
|
||||
*/
|
||||
lv_res_t lv_img_decoder_get_info(const char * src, lv_img_header_t * header)
|
||||
{
|
||||
header->always_zero = 0;
|
||||
|
||||
lv_res_t res = LV_RES_INV;
|
||||
lv_img_decoder_t * d;
|
||||
LV_LL_READ(LV_GC_ROOT(_lv_img_defoder_ll), d)
|
||||
{
|
||||
res = LV_RES_INV;
|
||||
if(d->info_cb) {
|
||||
res = d->info_cb(d, src, header);
|
||||
if(res == LV_RES_OK) break;
|
||||
}
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
/**
|
||||
* Open an image.
|
||||
* Try the created image decoder one by one. Once one is able to open the image that decoder is save in `dsc`
|
||||
* @param dsc describe a decoding session. Simply a pointer to an `lv_img_decoder_dsc_t` variable.
|
||||
* @param src the image source. Can be
|
||||
* 1) File name: E.g. "S:folder/img1.png" (The drivers needs to registered via `lv_fs_add_drv()`)
|
||||
* 2) Variable: Pointer to an `lv_img_dsc_t` variable
|
||||
* 3) Symbol: E.g. `LV_SYMBOL_OK`
|
||||
* @param style the style of the image
|
||||
* @return LV_RES_OK: opened the image. `dsc->img_data` and `dsc->header` are set.
|
||||
* LV_RES_INV: none of the registered image decoders were able to open the image.
|
||||
*/
|
||||
lv_res_t lv_img_decoder_open(lv_img_decoder_dsc_t * dsc, const void * src, const lv_style_t * style)
|
||||
{
|
||||
dsc->style = style;
|
||||
dsc->src_type = lv_img_src_get_type(src);
|
||||
dsc->user_data = NULL;
|
||||
|
||||
if(dsc->src_type == LV_IMG_SRC_FILE) {
|
||||
size_t fnlen = strlen(src);
|
||||
dsc->src = lv_mem_alloc(fnlen + 1);
|
||||
strcpy((char *)dsc->src, src);
|
||||
} else {
|
||||
dsc->src = src;
|
||||
}
|
||||
|
||||
lv_res_t res = LV_RES_INV;
|
||||
|
||||
lv_img_decoder_t * d;
|
||||
LV_LL_READ(LV_GC_ROOT(_lv_img_defoder_ll), d)
|
||||
{
|
||||
/*Info an Open callbacks are required*/
|
||||
if(d->info_cb == NULL || d->open_cb == NULL) continue;
|
||||
|
||||
res = d->info_cb(d, src, &dsc->header);
|
||||
if(res != LV_RES_OK) continue;
|
||||
|
||||
dsc->error_msg = NULL;
|
||||
dsc->img_data = NULL;
|
||||
dsc->decoder = d;
|
||||
|
||||
res = d->open_cb(d, dsc);
|
||||
|
||||
/*Opened successfully. It is a good decoder to for this image source*/
|
||||
if(res == LV_RES_OK) break;
|
||||
}
|
||||
|
||||
if(res == LV_RES_INV) {
|
||||
memset(dsc, 0, sizeof(lv_img_decoder_dsc_t));
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
/**
|
||||
* Read a line from an opened image
|
||||
* @param dsc pointer to `lv_img_decoder_dsc_t` used in `lv_img_decoder_open`
|
||||
* @param x start X coordinate (from left)
|
||||
* @param y start Y coordinate (from top)
|
||||
* @param len number of pixels to read
|
||||
* @param buf store the data here
|
||||
* @return LV_RES_OK: success; LV_RES_INV: an error occurred
|
||||
*/
|
||||
lv_res_t lv_img_decoder_read_line(lv_img_decoder_dsc_t * dsc, lv_coord_t x, lv_coord_t y, lv_coord_t len, uint8_t * buf)
|
||||
{
|
||||
lv_res_t res = LV_RES_INV;
|
||||
if(dsc->decoder->read_line_cb) res = dsc->decoder->read_line_cb(dsc->decoder, dsc, x, y, len, buf);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
/**
|
||||
* Close a decoding session
|
||||
* @param dsc pointer to `lv_img_decoder_dsc_t` used in `lv_img_decoder_open`
|
||||
*/
|
||||
void lv_img_decoder_close(lv_img_decoder_dsc_t * dsc)
|
||||
{
|
||||
if(dsc->decoder) {
|
||||
if(dsc->decoder->close_cb) dsc->decoder->close_cb(dsc->decoder, dsc);
|
||||
|
||||
if(dsc->src_type == LV_IMG_SRC_FILE) {
|
||||
lv_mem_free(dsc->src);
|
||||
dsc->src = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new image decoder
|
||||
* @return pointer to the new image decoder
|
||||
*/
|
||||
lv_img_decoder_t * lv_img_decoder_create(void)
|
||||
{
|
||||
lv_img_decoder_t * decoder;
|
||||
decoder = lv_ll_ins_head(&LV_GC_ROOT(_lv_img_defoder_ll));
|
||||
LV_ASSERT_MEM(decoder);
|
||||
if(decoder == NULL) return NULL;
|
||||
|
||||
memset(decoder, 0, sizeof(lv_img_decoder_t));
|
||||
|
||||
return decoder;
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete an image decoder
|
||||
* @param decoder pointer to an image decoder
|
||||
*/
|
||||
void lv_img_decoder_delete(lv_img_decoder_t * decoder)
|
||||
{
|
||||
lv_ll_rem(&LV_GC_ROOT(_lv_img_defoder_ll), decoder);
|
||||
lv_mem_free(decoder);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a callback to get information about the image
|
||||
* @param decoder pointer to an image decoder
|
||||
* @param info_cb a function to collect info about an image (fill an `lv_img_header_t` struct)
|
||||
*/
|
||||
void lv_img_decoder_set_info_cb(lv_img_decoder_t * decoder, lv_img_decoder_info_f_t info_cb)
|
||||
{
|
||||
decoder->info_cb = info_cb;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a callback to open an image
|
||||
* @param decoder pointer to an image decoder
|
||||
* @param open_cb a function to open an image
|
||||
*/
|
||||
void lv_img_decoder_set_open_cb(lv_img_decoder_t * decoder, lv_img_decoder_open_f_t open_cb)
|
||||
{
|
||||
decoder->open_cb = open_cb;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a callback to a decoded line of an image
|
||||
* @param decoder pointer to an image decoder
|
||||
* @param read_line_cb a function to read a line of an image
|
||||
*/
|
||||
void lv_img_decoder_set_read_line_cb(lv_img_decoder_t * decoder, lv_img_decoder_read_line_f_t read_line_cb)
|
||||
{
|
||||
decoder->read_line_cb = read_line_cb;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a callback to close a decoding session. E.g. close files and free other resources.
|
||||
* @param decoder pointer to an image decoder
|
||||
* @param close_cb a function to close a decoding session
|
||||
*/
|
||||
void lv_img_decoder_set_close_cb(lv_img_decoder_t * decoder, lv_img_decoder_close_f_t close_cb)
|
||||
{
|
||||
decoder->close_cb = close_cb;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get info about a built-in image
|
||||
* @param decoder the decoder where this function belongs
|
||||
* @param src the image source: pointer to an `lv_img_dsc_t` variable, a file path or a symbol
|
||||
* @param header store the image data here
|
||||
* @return LV_RES_OK: the info is successfully stored in `header`; LV_RES_INV: unknown format or other error.
|
||||
*/
|
||||
lv_res_t lv_img_decoder_built_in_info(lv_img_decoder_t * decoder, const void * src, lv_img_header_t * header)
|
||||
{
|
||||
(void)decoder; /*Unused*/
|
||||
|
||||
lv_img_src_t src_type = lv_img_src_get_type(src);
|
||||
if(src_type == LV_IMG_SRC_VARIABLE) {
|
||||
lv_img_cf_t cf = ((lv_img_dsc_t *)src)->header.cf;
|
||||
if(cf < CF_BUILT_IN_FIRST || cf > CF_BUILT_IN_LAST) return LV_RES_INV;
|
||||
|
||||
header->w = ((lv_img_dsc_t *)src)->header.w;
|
||||
header->h = ((lv_img_dsc_t *)src)->header.h;
|
||||
header->cf = ((lv_img_dsc_t *)src)->header.cf;
|
||||
}
|
||||
#if LV_USE_FILESYSTEM
|
||||
else if(src_type == LV_IMG_SRC_FILE) {
|
||||
lv_fs_file_t file;
|
||||
lv_fs_res_t res;
|
||||
uint32_t rn;
|
||||
res = lv_fs_open(&file, src, LV_FS_MODE_RD);
|
||||
if(res == LV_FS_RES_OK) {
|
||||
res = lv_fs_read(&file, header, sizeof(lv_img_header_t), &rn);
|
||||
lv_fs_close(&file);
|
||||
}
|
||||
|
||||
if(header->cf < CF_BUILT_IN_FIRST || header->cf > CF_BUILT_IN_LAST) return LV_RES_INV;
|
||||
|
||||
}
|
||||
#endif
|
||||
else if(src_type == LV_IMG_SRC_SYMBOL) {
|
||||
/*The size depend on the font but it is unknown here. It should be handled outside of the
|
||||
* function*/
|
||||
header->w = 1;
|
||||
header->h = 1;
|
||||
/* Symbols always have transparent parts. Important because of cover check in the design
|
||||
* function. The actual value doesn't matter because lv_draw_label will draw it*/
|
||||
header->cf = LV_IMG_CF_ALPHA_1BIT;
|
||||
} else {
|
||||
LV_LOG_WARN("Image get info found unknown src type");
|
||||
return LV_RES_INV;
|
||||
}
|
||||
return LV_RES_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* Open a built in image
|
||||
* @param decoder the decoder where this function belongs
|
||||
* @param dsc pointer to decoder descriptor. `src`, `style` are already initialized in it.
|
||||
* @return LV_RES_OK: the info is successfully stored in `header`; LV_RES_INV: unknown format or other error.
|
||||
*/
|
||||
lv_res_t lv_img_decoder_built_in_open(lv_img_decoder_t * decoder, lv_img_decoder_dsc_t * dsc)
|
||||
{
|
||||
/*Open the file if it's a file*/
|
||||
if(dsc->src_type == LV_IMG_SRC_FILE) {
|
||||
#if LV_USE_FILESYSTEM
|
||||
|
||||
/*Support only "*.bin" files*/
|
||||
if(strcmp(lv_fs_get_ext(dsc->src), "bin")) return LV_RES_INV;
|
||||
|
||||
lv_fs_file_t f;
|
||||
lv_fs_res_t res = lv_fs_open(&f, dsc->src, LV_FS_MODE_RD);
|
||||
if(res != LV_FS_RES_OK) {
|
||||
LV_LOG_WARN("Built-in image decoder can't open the file");
|
||||
return LV_RES_INV;
|
||||
}
|
||||
|
||||
/*If the file was open successfully save the file descriptor*/
|
||||
if(dsc->user_data == NULL) {
|
||||
dsc->user_data = lv_mem_alloc(sizeof(lv_img_decoder_built_in_data_t));
|
||||
if(dsc->user_data == NULL) {
|
||||
LV_LOG_ERROR("img_decoder_built_in_open: out of memory");
|
||||
LV_ASSERT_MEM(dsc->user_data);
|
||||
}
|
||||
memset(dsc->user_data, 0, sizeof(lv_img_decoder_built_in_data_t));
|
||||
}
|
||||
|
||||
lv_img_decoder_built_in_data_t * user_data = dsc->user_data;
|
||||
user_data->f = lv_mem_alloc(sizeof(f));
|
||||
if(user_data->f == NULL) {
|
||||
LV_LOG_ERROR("img_decoder_built_in_open: out of memory");
|
||||
LV_ASSERT_MEM(user_data->f);
|
||||
}
|
||||
|
||||
memcpy(user_data->f, &f, sizeof(f));
|
||||
|
||||
#else
|
||||
LV_LOG_WARN("Image built-in decoder cannot read file because LV_USE_FILESYSTEM = 0");
|
||||
return LV_RES_INV;
|
||||
#endif
|
||||
}
|
||||
|
||||
lv_img_cf_t cf = dsc->header.cf;
|
||||
/*Process true color formats*/
|
||||
if(cf == LV_IMG_CF_TRUE_COLOR || cf == LV_IMG_CF_TRUE_COLOR_ALPHA || cf == LV_IMG_CF_TRUE_COLOR_CHROMA_KEYED) {
|
||||
if(dsc->src_type == LV_IMG_SRC_VARIABLE) {
|
||||
/* In case of uncompressed formats the image stored in the ROM/RAM.
|
||||
* So simply give its pointer*/
|
||||
dsc->img_data = ((lv_img_dsc_t *)dsc->src)->data;
|
||||
return LV_RES_OK;
|
||||
} else {
|
||||
/*If it's a file it need to be read line by line later*/
|
||||
dsc->img_data = NULL;
|
||||
return LV_RES_OK;
|
||||
}
|
||||
}
|
||||
/*Process indexed images. Build a palette*/
|
||||
else if(cf == LV_IMG_CF_INDEXED_1BIT || cf == LV_IMG_CF_INDEXED_2BIT || cf == LV_IMG_CF_INDEXED_4BIT ||
|
||||
cf == LV_IMG_CF_INDEXED_8BIT) {
|
||||
|
||||
#if LV_IMG_CF_INDEXED
|
||||
uint8_t px_size = lv_img_color_format_get_px_size(cf);
|
||||
uint32_t palette_size = 1 << px_size;
|
||||
|
||||
/*Allocate the palette*/
|
||||
if(dsc->user_data == NULL) {
|
||||
dsc->user_data = lv_mem_alloc(sizeof(lv_img_decoder_built_in_data_t));
|
||||
if(dsc->user_data == NULL) {
|
||||
LV_LOG_ERROR("img_decoder_built_in_open: out of memory");
|
||||
LV_ASSERT_MEM(dsc->user_data);
|
||||
}
|
||||
memset(dsc->user_data, 0, sizeof(lv_img_decoder_built_in_data_t));
|
||||
}
|
||||
|
||||
lv_img_decoder_built_in_data_t * user_data = dsc->user_data;
|
||||
user_data->palette = lv_mem_alloc(palette_size * sizeof(lv_color_t));
|
||||
user_data->opa = lv_mem_alloc(palette_size * sizeof(lv_opa_t));
|
||||
if(user_data->palette == NULL || user_data->opa == NULL) {
|
||||
LV_LOG_ERROR("img_decoder_built_in_open: out of memory");
|
||||
#if LV_USE_FILESYSTEM
|
||||
LV_ASSERT_MEM(user_data->f);
|
||||
#endif
|
||||
}
|
||||
|
||||
if(dsc->src_type == LV_IMG_SRC_FILE) {
|
||||
/*Read the palette from file*/
|
||||
#if LV_USE_FILESYSTEM
|
||||
lv_fs_seek(user_data->f, 4); /*Skip the header*/
|
||||
lv_color32_t cur_color;
|
||||
uint32_t i;
|
||||
for(i = 0; i < palette_size; i++) {
|
||||
lv_fs_read(user_data->f, &cur_color, sizeof(lv_color32_t), NULL);
|
||||
user_data->palette[i] = lv_color_make(cur_color.ch.red, cur_color.ch.green, cur_color.ch.blue);
|
||||
user_data->opa[i] = cur_color.ch.alpha;
|
||||
}
|
||||
#else
|
||||
LV_LOG_WARN("Image built-in decoder can read the palette because LV_USE_FILESYSTEM = 0");
|
||||
return LV_RES_INV;
|
||||
#endif
|
||||
} else {
|
||||
/*The palette begins in the beginning of the image data. Just point to it.*/
|
||||
lv_color32_t * palette_p = (lv_color32_t *)((lv_img_dsc_t *)dsc->src)->data;
|
||||
|
||||
uint32_t i;
|
||||
for(i = 0; i < palette_size; i++) {
|
||||
user_data->palette[i] = lv_color_make(palette_p[i].ch.red, palette_p[i].ch.green, palette_p[i].ch.blue);
|
||||
user_data->opa[i] = palette_p[i].ch.alpha;
|
||||
}
|
||||
}
|
||||
|
||||
dsc->img_data = NULL;
|
||||
return LV_RES_OK;
|
||||
#else
|
||||
LV_LOG_WARN("Indexed (palette) images are not enabled in lv_conf.h. See LV_IMG_CF_INDEXED");
|
||||
return LV_RES_INV;
|
||||
#endif
|
||||
}
|
||||
/*Alpha indexed images. */
|
||||
else if(cf == LV_IMG_CF_ALPHA_1BIT || cf == LV_IMG_CF_ALPHA_2BIT || cf == LV_IMG_CF_ALPHA_4BIT ||
|
||||
cf == LV_IMG_CF_ALPHA_8BIT) {
|
||||
#if LV_IMG_CF_ALPHA
|
||||
dsc->img_data = NULL;
|
||||
return LV_RES_OK; /*Nothing to process*/
|
||||
#else
|
||||
LV_LOG_WARN("Alpha indexed images are not enabled in lv_conf.h. See LV_IMG_CF_ALPHA");
|
||||
return LV_RES_INV;
|
||||
#endif
|
||||
}
|
||||
/*Unknown format. Can't decode it.*/
|
||||
else {
|
||||
/*Free the potentially allocated memories*/
|
||||
lv_img_decoder_built_in_close(decoder, dsc);
|
||||
|
||||
LV_LOG_WARN("Image decoder open: unknown color format")
|
||||
return LV_RES_INV;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Decode `len` pixels starting from the given `x`, `y` coordinates and store them in `buf`.
|
||||
* Required only if the "open" function can't return with the whole decoded pixel array.
|
||||
* @param decoder pointer to the decoder the function associated with
|
||||
* @param dsc pointer to decoder descriptor
|
||||
* @param x start x coordinate
|
||||
* @param y start y coordinate
|
||||
* @param len number of pixels to decode
|
||||
* @param buf a buffer to store the decoded pixels
|
||||
* @return LV_RES_OK: ok; LV_RES_INV: failed
|
||||
*/
|
||||
lv_res_t lv_img_decoder_built_in_read_line(lv_img_decoder_t * decoder, lv_img_decoder_dsc_t * dsc, lv_coord_t x,
|
||||
lv_coord_t y, lv_coord_t len, uint8_t * buf)
|
||||
{
|
||||
(void)decoder; /*Unused*/
|
||||
|
||||
lv_res_t res = LV_RES_INV;
|
||||
|
||||
if(dsc->header.cf == LV_IMG_CF_TRUE_COLOR || dsc->header.cf == LV_IMG_CF_TRUE_COLOR_ALPHA ||
|
||||
dsc->header.cf == LV_IMG_CF_TRUE_COLOR_CHROMA_KEYED) {
|
||||
/* For TRUE_COLOR images read line required only for files.
|
||||
* For variables the image data was returned in `open`*/
|
||||
if(dsc->src_type == LV_IMG_SRC_FILE) {
|
||||
res = lv_img_decoder_built_in_line_true_color(dsc, x, y, len, buf);
|
||||
}
|
||||
} else if(dsc->header.cf == LV_IMG_CF_ALPHA_1BIT || dsc->header.cf == LV_IMG_CF_ALPHA_2BIT ||
|
||||
dsc->header.cf == LV_IMG_CF_ALPHA_4BIT || dsc->header.cf == LV_IMG_CF_ALPHA_8BIT) {
|
||||
|
||||
res = lv_img_decoder_built_in_line_alpha(dsc, x, y, len, buf);
|
||||
} else if(dsc->header.cf == LV_IMG_CF_INDEXED_1BIT || dsc->header.cf == LV_IMG_CF_INDEXED_2BIT ||
|
||||
dsc->header.cf == LV_IMG_CF_INDEXED_4BIT || dsc->header.cf == LV_IMG_CF_INDEXED_8BIT) {
|
||||
res = lv_img_decoder_built_in_line_indexed(dsc, x, y, len, buf);
|
||||
} else {
|
||||
LV_LOG_WARN("Built-in image decoder read not supports the color format");
|
||||
return LV_RES_INV;
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
/**
|
||||
* Close the pending decoding. Free resources etc.
|
||||
* @param decoder pointer to the decoder the function associated with
|
||||
* @param dsc pointer to decoder descriptor
|
||||
*/
|
||||
void lv_img_decoder_built_in_close(lv_img_decoder_t * decoder, lv_img_decoder_dsc_t * dsc)
|
||||
{
|
||||
(void)decoder; /*Unused*/
|
||||
|
||||
lv_img_decoder_built_in_data_t * user_data = dsc->user_data;
|
||||
if(user_data) {
|
||||
#if LV_USE_FILESYSTEM
|
||||
if(user_data->f) {
|
||||
lv_fs_close(user_data->f);
|
||||
lv_mem_free(user_data->f);
|
||||
}
|
||||
#endif
|
||||
if(user_data->palette) lv_mem_free(user_data->palette);
|
||||
if(user_data->opa) lv_mem_free(user_data->opa);
|
||||
|
||||
lv_mem_free(user_data);
|
||||
|
||||
dsc->user_data = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
|
||||
static lv_res_t lv_img_decoder_built_in_line_true_color(lv_img_decoder_dsc_t * dsc, lv_coord_t x, lv_coord_t y,
|
||||
lv_coord_t len, uint8_t * buf)
|
||||
{
|
||||
#if LV_USE_FILESYSTEM
|
||||
lv_img_decoder_built_in_data_t * user_data = dsc->user_data;
|
||||
lv_fs_res_t res;
|
||||
uint8_t px_size = lv_img_color_format_get_px_size(dsc->header.cf);
|
||||
|
||||
uint32_t pos = ((y * dsc->header.w + x) * px_size) >> 3;
|
||||
pos += 4; /*Skip the header*/
|
||||
res = lv_fs_seek(user_data->f, pos);
|
||||
if(res != LV_FS_RES_OK) {
|
||||
LV_LOG_WARN("Built-in image decoder seek failed");
|
||||
return LV_RES_INV;
|
||||
}
|
||||
uint32_t btr = len * (px_size >> 3);
|
||||
uint32_t br = 0;
|
||||
lv_fs_read(user_data->f, buf, btr, &br);
|
||||
if(res != LV_FS_RES_OK || btr != br) {
|
||||
LV_LOG_WARN("Built-in image decoder read failed");
|
||||
return LV_RES_INV;
|
||||
}
|
||||
|
||||
return LV_RES_OK;
|
||||
#else
|
||||
LV_LOG_WARN("Image built-in decoder cannot read file because LV_USE_FILESYSTEM = 0");
|
||||
return LV_RES_INV;
|
||||
#endif
|
||||
}
|
||||
|
||||
static lv_res_t lv_img_decoder_built_in_line_alpha(lv_img_decoder_dsc_t * dsc, lv_coord_t x, lv_coord_t y,
|
||||
lv_coord_t len, uint8_t * buf)
|
||||
{
|
||||
|
||||
#if LV_IMG_CF_ALPHA
|
||||
const lv_opa_t alpha1_opa_table[2] = {0, 255}; /*Opacity mapping with bpp = 1 (Just for compatibility)*/
|
||||
const lv_opa_t alpha2_opa_table[4] = {0, 85, 170, 255}; /*Opacity mapping with bpp = 2*/
|
||||
const lv_opa_t alpha4_opa_table[16] = {0, 17, 34, 51, /*Opacity mapping with bpp = 4*/
|
||||
68, 85, 102, 119, 136, 153, 170, 187, 204, 221, 238, 255};
|
||||
|
||||
/*Simply fill the buffer with the color. Later only the alpha value will be modified.*/
|
||||
lv_color_t bg_color = dsc->style->image.color;
|
||||
lv_coord_t i;
|
||||
for(i = 0; i < len; i++) {
|
||||
#if LV_COLOR_DEPTH == 8 || LV_COLOR_DEPTH == 1
|
||||
buf[i * LV_IMG_PX_SIZE_ALPHA_BYTE] = bg_color.full;
|
||||
#elif LV_COLOR_DEPTH == 16
|
||||
/*Because of Alpha byte 16 bit color can start on odd address which can cause crash*/
|
||||
buf[i * LV_IMG_PX_SIZE_ALPHA_BYTE] = bg_color.full & 0xFF;
|
||||
buf[i * LV_IMG_PX_SIZE_ALPHA_BYTE + 1] = (bg_color.full >> 8) & 0xFF;
|
||||
#elif LV_COLOR_DEPTH == 32
|
||||
*((uint32_t *)&buf[i * LV_IMG_PX_SIZE_ALPHA_BYTE]) = bg_color.full;
|
||||
#else
|
||||
#error "Invalid LV_COLOR_DEPTH. Check it in lv_conf.h"
|
||||
#endif
|
||||
}
|
||||
|
||||
const lv_opa_t * opa_table = NULL;
|
||||
uint8_t px_size = lv_img_color_format_get_px_size(dsc->header.cf);
|
||||
uint16_t mask = (1 << px_size) - 1; /*E.g. px_size = 2; mask = 0x03*/
|
||||
|
||||
lv_coord_t w = 0;
|
||||
uint32_t ofs = 0;
|
||||
int8_t pos = 0;
|
||||
switch(dsc->header.cf) {
|
||||
case LV_IMG_CF_ALPHA_1BIT:
|
||||
w = (dsc->header.w >> 3); /*E.g. w = 20 -> w = 2 + 1*/
|
||||
if(dsc->header.w & 0x7) w++;
|
||||
ofs += w * y + (x >> 3); /*First pixel*/
|
||||
pos = 7 - (x & 0x7);
|
||||
opa_table = alpha1_opa_table;
|
||||
break;
|
||||
case LV_IMG_CF_ALPHA_2BIT:
|
||||
w = (dsc->header.w >> 2); /*E.g. w = 13 -> w = 3 + 1 (bytes)*/
|
||||
if(dsc->header.w & 0x3) w++;
|
||||
ofs += w * y + (x >> 2); /*First pixel*/
|
||||
pos = 6 - ((x & 0x3) * 2);
|
||||
opa_table = alpha2_opa_table;
|
||||
break;
|
||||
case LV_IMG_CF_ALPHA_4BIT:
|
||||
w = (dsc->header.w >> 1); /*E.g. w = 13 -> w = 6 + 1 (bytes)*/
|
||||
if(dsc->header.w & 0x1) w++;
|
||||
ofs += w * y + (x >> 1); /*First pixel*/
|
||||
pos = 4 - ((x & 0x1) * 4);
|
||||
opa_table = alpha4_opa_table;
|
||||
break;
|
||||
case LV_IMG_CF_ALPHA_8BIT:
|
||||
w = dsc->header.w; /*E.g. x = 7 -> w = 7 (bytes)*/
|
||||
ofs += w * y + x; /*First pixel*/
|
||||
pos = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
#if LV_USE_FILESYSTEM
|
||||
lv_img_decoder_built_in_data_t * user_data = dsc->user_data;
|
||||
uint8_t fs_buf[LV_HOR_RES_MAX];
|
||||
#endif
|
||||
|
||||
const uint8_t * data_tmp = NULL;
|
||||
if(dsc->src_type == LV_IMG_SRC_VARIABLE) {
|
||||
const lv_img_dsc_t * img_dsc = dsc->src;
|
||||
|
||||
data_tmp = img_dsc->data + ofs;
|
||||
} else {
|
||||
#if LV_USE_FILESYSTEM
|
||||
lv_fs_seek(user_data->f, ofs + 4); /*+4 to skip the header*/
|
||||
lv_fs_read(user_data->f, fs_buf, w, NULL);
|
||||
data_tmp = fs_buf;
|
||||
#else
|
||||
LV_LOG_WARN("Image built-in alpha line reader can't read file because LV_USE_FILESYSTEM = 0");
|
||||
data_tmp = NULL; /*To avoid warnings*/
|
||||
return LV_RES_INV;
|
||||
#endif
|
||||
}
|
||||
|
||||
uint8_t byte_act = 0;
|
||||
uint8_t val_act;
|
||||
for(i = 0; i < len; i++) {
|
||||
val_act = (data_tmp[byte_act] & (mask << pos)) >> pos;
|
||||
|
||||
buf[i * LV_IMG_PX_SIZE_ALPHA_BYTE + LV_IMG_PX_SIZE_ALPHA_BYTE - 1] =
|
||||
dsc->header.cf == LV_IMG_CF_ALPHA_8BIT ? val_act : opa_table[val_act];
|
||||
|
||||
pos -= px_size;
|
||||
if(pos < 0) {
|
||||
pos = 8 - px_size;
|
||||
data_tmp++;
|
||||
}
|
||||
}
|
||||
|
||||
return LV_RES_OK;
|
||||
|
||||
#else
|
||||
LV_LOG_WARN("Image built-in alpha line reader failed because LV_IMG_CF_ALPHA is 0 in lv_conf.h");
|
||||
return LV_RES_INV;
|
||||
#endif
|
||||
}
|
||||
|
||||
static lv_res_t lv_img_decoder_built_in_line_indexed(lv_img_decoder_dsc_t * dsc, lv_coord_t x, lv_coord_t y,
|
||||
lv_coord_t len, uint8_t * buf)
|
||||
{
|
||||
|
||||
#if LV_IMG_CF_INDEXED
|
||||
uint8_t px_size = lv_img_color_format_get_px_size(dsc->header.cf);
|
||||
uint16_t mask = (1 << px_size) - 1; /*E.g. px_size = 2; mask = 0x03*/
|
||||
|
||||
lv_coord_t w = 0;
|
||||
int8_t pos = 0;
|
||||
uint32_t ofs = 0;
|
||||
switch(dsc->header.cf) {
|
||||
case LV_IMG_CF_INDEXED_1BIT:
|
||||
w = (dsc->header.w >> 3); /*E.g. w = 20 -> w = 2 + 1*/
|
||||
if(dsc->header.w & 0x7) w++;
|
||||
ofs += w * y + (x >> 3); /*First pixel*/
|
||||
ofs += 8; /*Skip the palette*/
|
||||
pos = 7 - (x & 0x7);
|
||||
break;
|
||||
case LV_IMG_CF_INDEXED_2BIT:
|
||||
w = (dsc->header.w >> 2); /*E.g. w = 13 -> w = 3 + 1 (bytes)*/
|
||||
if(dsc->header.w & 0x3) w++;
|
||||
ofs += w * y + (x >> 2); /*First pixel*/
|
||||
ofs += 16; /*Skip the palette*/
|
||||
pos = 6 - ((x & 0x3) * 2);
|
||||
break;
|
||||
case LV_IMG_CF_INDEXED_4BIT:
|
||||
w = (dsc->header.w >> 1); /*E.g. w = 13 -> w = 6 + 1 (bytes)*/
|
||||
if(dsc->header.w & 0x1) w++;
|
||||
ofs += w * y + (x >> 1); /*First pixel*/
|
||||
ofs += 64; /*Skip the palette*/
|
||||
pos = 4 - ((x & 0x1) * 4);
|
||||
break;
|
||||
case LV_IMG_CF_INDEXED_8BIT:
|
||||
w = dsc->header.w; /*E.g. x = 7 -> w = 7 (bytes)*/
|
||||
ofs += w * y + x; /*First pixel*/
|
||||
ofs += 1024; /*Skip the palette*/
|
||||
pos = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
lv_img_decoder_built_in_data_t * user_data = dsc->user_data;
|
||||
|
||||
#if LV_USE_FILESYSTEM
|
||||
uint8_t fs_buf[LV_HOR_RES_MAX];
|
||||
#endif
|
||||
const uint8_t * data_tmp = NULL;
|
||||
if(dsc->src_type == LV_IMG_SRC_VARIABLE) {
|
||||
const lv_img_dsc_t * img_dsc = dsc->src;
|
||||
data_tmp = img_dsc->data + ofs;
|
||||
} else {
|
||||
#if LV_USE_FILESYSTEM
|
||||
lv_fs_seek(user_data->f, ofs + 4); /*+4 to skip the header*/
|
||||
lv_fs_read(user_data->f, fs_buf, w, NULL);
|
||||
data_tmp = fs_buf;
|
||||
#else
|
||||
LV_LOG_WARN("Image built-in indexed line reader can't read file because LV_USE_FILESYSTEM = 0");
|
||||
data_tmp = NULL; /*To avoid warnings*/
|
||||
return LV_RES_INV;
|
||||
#endif
|
||||
}
|
||||
|
||||
uint8_t val_act;
|
||||
lv_coord_t i;
|
||||
for(i = 0; i < len; i++) {
|
||||
val_act = (*data_tmp & (mask << pos)) >> pos;
|
||||
|
||||
lv_color_t color = user_data->palette[val_act];
|
||||
#if LV_COLOR_DEPTH == 8 || LV_COLOR_DEPTH == 1
|
||||
buf[i * LV_IMG_PX_SIZE_ALPHA_BYTE] = color.full;
|
||||
#elif LV_COLOR_DEPTH == 16
|
||||
/*Because of Alpha byte 16 bit color can start on odd address which can cause crash*/
|
||||
buf[i * LV_IMG_PX_SIZE_ALPHA_BYTE] = color.full & 0xFF;
|
||||
buf[i * LV_IMG_PX_SIZE_ALPHA_BYTE + 1] = (color.full >> 8) & 0xFF;
|
||||
#elif LV_COLOR_DEPTH == 32
|
||||
*((uint32_t *)&buf[i * LV_IMG_PX_SIZE_ALPHA_BYTE]) = color.full;
|
||||
#else
|
||||
#error "Invalid LV_COLOR_DEPTH. Check it in lv_conf.h"
|
||||
#endif
|
||||
buf[i * LV_IMG_PX_SIZE_ALPHA_BYTE + LV_IMG_PX_SIZE_ALPHA_BYTE - 1] = user_data->opa[val_act];
|
||||
|
||||
pos -= px_size;
|
||||
if(pos < 0) {
|
||||
pos = 8 - px_size;
|
||||
data_tmp++;
|
||||
}
|
||||
}
|
||||
|
||||
return LV_RES_OK;
|
||||
#else
|
||||
LV_LOG_WARN("Image built-in indexed line reader failed because LV_IMG_CF_INDEXED is 0 in lv_conf.h");
|
||||
return LV_RES_INV;
|
||||
#endif
|
||||
}
|
@ -1,357 +0,0 @@
|
||||
/**
|
||||
* @file lv_img_decoder.h
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LV_IMG_DEOCER_H
|
||||
#define LV_IMG_DEOCER_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#ifdef LV_CONF_INCLUDE_SIMPLE
|
||||
#include "lv_conf.h"
|
||||
#else
|
||||
#include "../../../lv_conf.h"
|
||||
#endif
|
||||
|
||||
#include <stdint.h>
|
||||
#include "../lv_misc/lv_fs.h"
|
||||
#include "../lv_misc/lv_types.h"
|
||||
#include "../lv_misc/lv_area.h"
|
||||
#include "../lv_core/lv_style.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
/*If image pixels contains alpha we need to know how much byte is a pixel*/
|
||||
#if LV_COLOR_DEPTH == 1 || LV_COLOR_DEPTH == 8
|
||||
#define LV_IMG_PX_SIZE_ALPHA_BYTE 2
|
||||
#elif LV_COLOR_DEPTH == 16
|
||||
#define LV_IMG_PX_SIZE_ALPHA_BYTE 3
|
||||
#elif LV_COLOR_DEPTH == 32
|
||||
#define LV_IMG_PX_SIZE_ALPHA_BYTE 4
|
||||
#endif
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Source of image. */
|
||||
enum {
|
||||
LV_IMG_SRC_VARIABLE, /** Binary/C variable */
|
||||
LV_IMG_SRC_FILE, /** File in filesystem */
|
||||
LV_IMG_SRC_SYMBOL, /** Symbol (@ref lv_symbol_def.h) */
|
||||
LV_IMG_SRC_UNKNOWN, /** Unknown source */
|
||||
};
|
||||
|
||||
typedef uint8_t lv_img_src_t;
|
||||
/**
|
||||
* LittlevGL image header
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
|
||||
/* The first 8 bit is very important to distinguish the different source types.
|
||||
* For more info see `lv_img_get_src_type()` in lv_img.c */
|
||||
uint32_t cf : 5; /* Color format: See `lv_img_color_format_t`*/
|
||||
uint32_t always_zero : 3; /*It the upper bits of the first byte. Always zero to look like a
|
||||
non-printable character*/
|
||||
|
||||
uint32_t reserved : 2; /*Reserved to be used later*/
|
||||
|
||||
uint32_t w : 11; /*Width of the image map*/
|
||||
uint32_t h : 11; /*Height of the image map*/
|
||||
} lv_img_header_t;
|
||||
|
||||
/*Image color format*/
|
||||
enum {
|
||||
LV_IMG_CF_UNKNOWN = 0,
|
||||
|
||||
LV_IMG_CF_RAW, /**< Contains the file as it is. Needs custom decoder function*/
|
||||
LV_IMG_CF_RAW_ALPHA, /**< Contains the file as it is. The image has alpha. Needs custom decoder
|
||||
function*/
|
||||
LV_IMG_CF_RAW_CHROMA_KEYED, /**< Contains the file as it is. The image is chroma keyed. Needs
|
||||
custom decoder function*/
|
||||
|
||||
LV_IMG_CF_TRUE_COLOR, /**< Color format and depth should match with LV_COLOR settings*/
|
||||
LV_IMG_CF_TRUE_COLOR_ALPHA, /**< Same as `LV_IMG_CF_TRUE_COLOR` but every pixel has an alpha byte*/
|
||||
LV_IMG_CF_TRUE_COLOR_CHROMA_KEYED, /**< Same as `LV_IMG_CF_TRUE_COLOR` but LV_COLOR_TRANSP pixels
|
||||
will be transparent*/
|
||||
|
||||
LV_IMG_CF_INDEXED_1BIT, /**< Can have 2 different colors in a palette (always chroma keyed)*/
|
||||
LV_IMG_CF_INDEXED_2BIT, /**< Can have 4 different colors in a palette (always chroma keyed)*/
|
||||
LV_IMG_CF_INDEXED_4BIT, /**< Can have 16 different colors in a palette (always chroma keyed)*/
|
||||
LV_IMG_CF_INDEXED_8BIT, /**< Can have 256 different colors in a palette (always chroma keyed)*/
|
||||
|
||||
LV_IMG_CF_ALPHA_1BIT, /**< Can have one color and it can be drawn or not*/
|
||||
LV_IMG_CF_ALPHA_2BIT, /**< Can have one color but 4 different alpha value*/
|
||||
LV_IMG_CF_ALPHA_4BIT, /**< Can have one color but 16 different alpha value*/
|
||||
LV_IMG_CF_ALPHA_8BIT, /**< Can have one color but 256 different alpha value*/
|
||||
|
||||
LV_IMG_CF_RESERVED_15, /**< Reserved for further use. */
|
||||
LV_IMG_CF_RESERVED_16, /**< Reserved for further use. */
|
||||
LV_IMG_CF_RESERVED_17, /**< Reserved for further use. */
|
||||
LV_IMG_CF_RESERVED_18, /**< Reserved for further use. */
|
||||
LV_IMG_CF_RESERVED_19, /**< Reserved for further use. */
|
||||
LV_IMG_CF_RESERVED_20, /**< Reserved for further use. */
|
||||
LV_IMG_CF_RESERVED_21, /**< Reserved for further use. */
|
||||
LV_IMG_CF_RESERVED_22, /**< Reserved for further use. */
|
||||
LV_IMG_CF_RESERVED_23, /**< Reserved for further use. */
|
||||
|
||||
LV_IMG_CF_USER_ENCODED_0, /**< User holder encoding format. */
|
||||
LV_IMG_CF_USER_ENCODED_1, /**< User holder encoding format. */
|
||||
LV_IMG_CF_USER_ENCODED_2, /**< User holder encoding format. */
|
||||
LV_IMG_CF_USER_ENCODED_3, /**< User holder encoding format. */
|
||||
LV_IMG_CF_USER_ENCODED_4, /**< User holder encoding format. */
|
||||
LV_IMG_CF_USER_ENCODED_5, /**< User holder encoding format. */
|
||||
LV_IMG_CF_USER_ENCODED_6, /**< User holder encoding format. */
|
||||
LV_IMG_CF_USER_ENCODED_7, /**< User holder encoding format. */
|
||||
};
|
||||
typedef uint8_t lv_img_cf_t;
|
||||
|
||||
/** Image header it is compatible with
|
||||
* the result from image converter utility*/
|
||||
typedef struct
|
||||
{
|
||||
lv_img_header_t header;
|
||||
uint32_t data_size;
|
||||
const uint8_t * data;
|
||||
} lv_img_dsc_t;
|
||||
|
||||
/* Decoder function definitions */
|
||||
|
||||
struct _lv_img_decoder;
|
||||
struct _lv_img_decoder_dsc;
|
||||
|
||||
/**
|
||||
* Get info from an image and store in the `header`
|
||||
* @param src the image source. Can be a pointer to a C array or a file name (Use
|
||||
* `lv_img_src_get_type` to determine the type)
|
||||
* @param header store the info here
|
||||
* @return LV_RES_OK: info written correctly; LV_RES_INV: failed
|
||||
*/
|
||||
typedef lv_res_t (*lv_img_decoder_info_f_t)(struct _lv_img_decoder * decoder, const void * src,
|
||||
lv_img_header_t * header);
|
||||
|
||||
/**
|
||||
* Open an image for decoding. Prepare it as it is required to read it later
|
||||
* @param decoder pointer to the decoder the function associated with
|
||||
* @param dsc pointer to decoder descriptor. `src`, `style` are already initialized in it.
|
||||
*/
|
||||
typedef lv_res_t (*lv_img_decoder_open_f_t)(struct _lv_img_decoder * decoder, struct _lv_img_decoder_dsc * dsc);
|
||||
|
||||
/**
|
||||
* Decode `len` pixels starting from the given `x`, `y` coordinates and store them in `buf`.
|
||||
* Required only if the "open" function can't return with the whole decoded pixel array.
|
||||
* @param decoder pointer to the decoder the function associated with
|
||||
* @param dsc pointer to decoder descriptor
|
||||
* @param x start x coordinate
|
||||
* @param y start y coordinate
|
||||
* @param len number of pixels to decode
|
||||
* @param buf a buffer to store the decoded pixels
|
||||
* @return LV_RES_OK: ok; LV_RES_INV: failed
|
||||
*/
|
||||
typedef lv_res_t (*lv_img_decoder_read_line_f_t)(struct _lv_img_decoder * decoder, struct _lv_img_decoder_dsc * dsc,
|
||||
lv_coord_t x, lv_coord_t y, lv_coord_t len, uint8_t * buf);
|
||||
|
||||
/**
|
||||
* Close the pending decoding. Free resources etc.
|
||||
* @param decoder pointer to the decoder the function associated with
|
||||
* @param dsc pointer to decoder descriptor
|
||||
*/
|
||||
typedef void (*lv_img_decoder_close_f_t)(struct _lv_img_decoder * decoder, struct _lv_img_decoder_dsc * dsc);
|
||||
|
||||
typedef struct _lv_img_decoder
|
||||
{
|
||||
lv_img_decoder_info_f_t info_cb;
|
||||
lv_img_decoder_open_f_t open_cb;
|
||||
lv_img_decoder_read_line_f_t read_line_cb;
|
||||
lv_img_decoder_close_f_t close_cb;
|
||||
|
||||
#if LV_USE_USER_DATA
|
||||
lv_img_decoder_user_data_t user_data;
|
||||
#endif
|
||||
} lv_img_decoder_t;
|
||||
|
||||
/**Describe an image decoding session. Stores data about the decoding*/
|
||||
typedef struct _lv_img_decoder_dsc
|
||||
{
|
||||
/**The decoder which was able to open the image source*/
|
||||
lv_img_decoder_t * decoder;
|
||||
|
||||
/**The image source. A file path like "S:my_img.png" or pointer to an `lv_img_dsc_t` variable*/
|
||||
const void * src;
|
||||
|
||||
/**Style to draw the image.*/
|
||||
const lv_style_t * style;
|
||||
|
||||
/**Type of the source: file or variable. Can be set in `open` function if required*/
|
||||
lv_img_src_t src_type;
|
||||
|
||||
/**Info about the opened image: color format, size, etc. MUST be set in `open` function*/
|
||||
lv_img_header_t header;
|
||||
|
||||
/** Pointer to a buffer where the image's data (pixels) are stored in a decoded, plain format.
|
||||
* MUST be set in `open` function*/
|
||||
const uint8_t * img_data;
|
||||
|
||||
/** How much time did it take to open the image. [ms]
|
||||
* If not set `lv_img_cache` will measure and set the time to open*/
|
||||
uint32_t time_to_open;
|
||||
|
||||
/**A text to display instead of the image when the image can't be opened.
|
||||
* Can be set in `open` function or set NULL. */
|
||||
const char * error_msg;
|
||||
|
||||
/**Store any custom data here is required*/
|
||||
void * user_data;
|
||||
} lv_img_decoder_dsc_t;
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Initialize the image decoder module
|
||||
*/
|
||||
void lv_img_decoder_init(void);
|
||||
|
||||
/**
|
||||
* Get information about an image.
|
||||
* Try the created image decoder one by one. Once one is able to get info that info will be used.
|
||||
* @param src the image source. Can be
|
||||
* 1) File name: E.g. "S:folder/img1.png" (The drivers needs to registered via `lv_fs_add_drv()`)
|
||||
* 2) Variable: Pointer to an `lv_img_dsc_t` variable
|
||||
* 3) Symbol: E.g. `LV_SYMBOL_OK`
|
||||
* @param header the image info will be stored here
|
||||
* @return LV_RES_OK: success; LV_RES_INV: wasn't able to get info about the image
|
||||
*/
|
||||
lv_res_t lv_img_decoder_get_info(const char * src, lv_img_header_t * header);
|
||||
|
||||
/**
|
||||
* Open an image.
|
||||
* Try the created image decoder one by one. Once one is able to open the image that decoder is save in `dsc`
|
||||
* @param dsc describe a decoding session. Simply a pointer to an `lv_img_decoder_dsc_t` variable.
|
||||
* @param src the image source. Can be
|
||||
* 1) File name: E.g. "S:folder/img1.png" (The drivers needs to registered via `lv_fs_add_drv()`)
|
||||
* 2) Variable: Pointer to an `lv_img_dsc_t` variable
|
||||
* 3) Symbol: E.g. `LV_SYMBOL_OK`
|
||||
* @param style the style of the image
|
||||
* @return LV_RES_OK: opened the image. `dsc->img_data` and `dsc->header` are set.
|
||||
* LV_RES_INV: none of the registered image decoders were able to open the image.
|
||||
*/
|
||||
lv_res_t lv_img_decoder_open(lv_img_decoder_dsc_t * dsc, const void * src, const lv_style_t * style);
|
||||
|
||||
/**
|
||||
* Read a line from an opened image
|
||||
* @param dsc pointer to `lv_img_decoder_dsc_t` used in `lv_img_decoder_open`
|
||||
* @param x start X coordinate (from left)
|
||||
* @param y start Y coordinate (from top)
|
||||
* @param len number of pixels to read
|
||||
* @param buf store the data here
|
||||
* @return LV_RES_OK: success; LV_RES_INV: an error occurred
|
||||
*/
|
||||
lv_res_t lv_img_decoder_read_line(lv_img_decoder_dsc_t * dsc, lv_coord_t x, lv_coord_t y, lv_coord_t len,
|
||||
uint8_t * buf);
|
||||
|
||||
/**
|
||||
* Close a decoding session
|
||||
* @param dsc pointer to `lv_img_decoder_dsc_t` used in `lv_img_decoder_open`
|
||||
*/
|
||||
void lv_img_decoder_close(lv_img_decoder_dsc_t * dsc);
|
||||
|
||||
/**
|
||||
* Create a new image decoder
|
||||
* @return pointer to the new image decoder
|
||||
*/
|
||||
lv_img_decoder_t * lv_img_decoder_create(void);
|
||||
|
||||
/**
|
||||
* Delete an image decoder
|
||||
* @param decoder pointer to an image decoder
|
||||
*/
|
||||
void lv_img_decoder_delete(lv_img_decoder_t * decoder);
|
||||
|
||||
/**
|
||||
* Set a callback to get information about the image
|
||||
* @param decoder pointer to an image decoder
|
||||
* @param info_cb a function to collect info about an image (fill an `lv_img_header_t` struct)
|
||||
*/
|
||||
void lv_img_decoder_set_info_cb(lv_img_decoder_t * decoder, lv_img_decoder_info_f_t info_cb);
|
||||
|
||||
/**
|
||||
* Set a callback to open an image
|
||||
* @param decoder pointer to an image decoder
|
||||
* @param open_cb a function to open an image
|
||||
*/
|
||||
void lv_img_decoder_set_open_cb(lv_img_decoder_t * decoder, lv_img_decoder_open_f_t open_cb);
|
||||
|
||||
/**
|
||||
* Set a callback to a decoded line of an image
|
||||
* @param decoder pointer to an image decoder
|
||||
* @param read_line_cb a function to read a line of an image
|
||||
*/
|
||||
void lv_img_decoder_set_read_line_cb(lv_img_decoder_t * decoder, lv_img_decoder_read_line_f_t read_line_cb);
|
||||
|
||||
/**
|
||||
* Set a callback to close a decoding session. E.g. close files and free other resources.
|
||||
* @param decoder pointer to an image decoder
|
||||
* @param close_cb a function to close a decoding session
|
||||
*/
|
||||
void lv_img_decoder_set_close_cb(lv_img_decoder_t * decoder, lv_img_decoder_close_f_t close_cb);
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Get info about a built-in image
|
||||
* @param decoder the decoder where this function belongs
|
||||
* @param src the image source: pointer to an `lv_img_dsc_t` variable, a file path or a symbol
|
||||
* @param header store the image data here
|
||||
* @return LV_RES_OK: the info is successfully stored in `header`; LV_RES_INV: unknown format or other error.
|
||||
*/
|
||||
lv_res_t lv_img_decoder_built_in_info(lv_img_decoder_t * decoder, const void * src, lv_img_header_t * header);
|
||||
|
||||
/**
|
||||
* Open a built in image
|
||||
* @param decoder the decoder where this function belongs
|
||||
* @param dsc pointer to decoder descriptor. `src`, `style` are already initialized in it.
|
||||
* @return LV_RES_OK: the info is successfully stored in `header`; LV_RES_INV: unknown format or other error.
|
||||
*/
|
||||
lv_res_t lv_img_decoder_built_in_open(lv_img_decoder_t * decoder, lv_img_decoder_dsc_t * dsc);
|
||||
|
||||
/**
|
||||
* Decode `len` pixels starting from the given `x`, `y` coordinates and store them in `buf`.
|
||||
* Required only if the "open" function can't return with the whole decoded pixel array.
|
||||
* @param decoder pointer to the decoder the function associated with
|
||||
* @param dsc pointer to decoder descriptor
|
||||
* @param x start x coordinate
|
||||
* @param y start y coordinate
|
||||
* @param len number of pixels to decode
|
||||
* @param buf a buffer to store the decoded pixels
|
||||
* @return LV_RES_OK: ok; LV_RES_INV: failed
|
||||
*/
|
||||
lv_res_t lv_img_decoder_built_in_read_line(lv_img_decoder_t * decoder, lv_img_decoder_dsc_t * dsc, lv_coord_t x,
|
||||
lv_coord_t y, lv_coord_t len, uint8_t * buf);
|
||||
|
||||
/**
|
||||
* Close the pending decoding. Free resources etc.
|
||||
* @param decoder pointer to the decoder the function associated with
|
||||
* @param dsc pointer to decoder descriptor
|
||||
*/
|
||||
void lv_img_decoder_built_in_close(lv_img_decoder_t * decoder, lv_img_decoder_dsc_t * dsc);
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif /*LV_TEMPL_H*/
|
@ -1,84 +0,0 @@
|
||||
/**
|
||||
* @file lv_font.c
|
||||
*
|
||||
*/
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
|
||||
#include "lv_font.h"
|
||||
#include "../lv_misc/lv_utils.h"
|
||||
#include "../lv_misc/lv_log.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL FUNCTIONS
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Return with the bitmap of a font.
|
||||
* @param font_p pointer to a font
|
||||
* @param letter an UNICODE character code
|
||||
* @return pointer to the bitmap of the letter
|
||||
*/
|
||||
const uint8_t * lv_font_get_glyph_bitmap(const lv_font_t * font_p, uint32_t letter)
|
||||
{
|
||||
return font_p->get_glyph_bitmap(font_p, letter);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the descriptor of a glyph
|
||||
* @param font_p pointer to font
|
||||
* @param dsc_out store the result descriptor here
|
||||
* @param letter an UNICODE letter code
|
||||
* @return true: descriptor is successfully loaded into `dsc_out`.
|
||||
* false: the letter was not found, no data is loaded to `dsc_out`
|
||||
*/
|
||||
bool lv_font_get_glyph_dsc(const lv_font_t * font_p, lv_font_glyph_dsc_t * dsc_out, uint32_t letter, uint32_t letter_next)
|
||||
{
|
||||
return font_p->get_glyph_dsc(font_p, dsc_out, letter, letter_next);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the width of a glyph with kerning
|
||||
* @param font pointer to a font
|
||||
* @param letter an UNICODE letter
|
||||
* @param letter_next the next letter after `letter`. Used for kerning
|
||||
* @return the width of the glyph
|
||||
*/
|
||||
uint16_t lv_font_get_glyph_width(const lv_font_t * font, uint32_t letter, uint32_t letter_next)
|
||||
{
|
||||
lv_font_glyph_dsc_t g;
|
||||
bool ret;
|
||||
ret = lv_font_get_glyph_dsc(font, &g, letter, letter_next);
|
||||
if(ret) return g.adv_w;
|
||||
else return 0;
|
||||
}
|
||||
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
@ -1,164 +0,0 @@
|
||||
/**
|
||||
* @file lv_font.h
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LV_FONT_H
|
||||
#define LV_FONT_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#ifdef LV_CONF_INCLUDE_SIMPLE
|
||||
#include "lv_conf.h"
|
||||
#else
|
||||
#include "../../../lv_conf.h"
|
||||
#endif
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#include "lv_symbol_def.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
/*Number of fractional digits in the advanced width (`adv_w`) field of `lv_font_glyph_dsc_t`*/
|
||||
#define LV_FONT_WIDTH_FRACT_DIGIT 4
|
||||
|
||||
#define LV_FONT_KERN_POSITIVE 0
|
||||
#define LV_FONT_KERN_NEGATIVE 1
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/*------------------
|
||||
* General types
|
||||
*-----------------*/
|
||||
|
||||
/** Describes the properties of a glyph. */
|
||||
typedef struct
|
||||
{
|
||||
uint16_t adv_w; /**< The glyph needs this space. Draw the next glyph after this width. 8 bit integer, 4 bit fractional */
|
||||
uint8_t box_w; /**< Width of the glyph's bounding box*/
|
||||
uint8_t box_h; /**< Height of the glyph's bounding box*/
|
||||
int8_t ofs_x; /**< x offset of the bounding box*/
|
||||
int8_t ofs_y; /**< y offset of the bounding box*/
|
||||
uint8_t bpp; /**< Bit-per-pixel: 1, 2, 4, 8*/
|
||||
}lv_font_glyph_dsc_t;
|
||||
|
||||
|
||||
/** The bitmaps might be upscaled by 3 to achieve subpixel rendering. */
|
||||
enum {
|
||||
LV_FONT_SUBPX_NONE,
|
||||
LV_FONT_SUBPX_HOR,
|
||||
LV_FONT_SUBPX_VER,
|
||||
LV_FONT_SUBPX_BOTH,
|
||||
};
|
||||
|
||||
typedef uint8_t lv_font_subpx_t;
|
||||
|
||||
/** Describe the properties of a font*/
|
||||
typedef struct _lv_font_struct
|
||||
{
|
||||
/** Get a glyph's descriptor from a font*/
|
||||
bool (*get_glyph_dsc)(const struct _lv_font_struct *, lv_font_glyph_dsc_t *, uint32_t letter, uint32_t letter_next);
|
||||
|
||||
/** Get a glyph's bitmap from a font*/
|
||||
const uint8_t * (*get_glyph_bitmap)(const struct _lv_font_struct *, uint32_t);
|
||||
|
||||
/*Pointer to the font in a font pack (must have the same line height)*/
|
||||
uint8_t line_height; /**< The real line height where any text fits*/
|
||||
int8_t base_line; /**< Base line measured from the top of the line_height*/
|
||||
uint8_t subpx :2; /**< An element of `lv_font_subpx_t`*/
|
||||
void * dsc; /**< Store implementation specific or run_time data or caching here*/
|
||||
#if LV_USE_USER_DATA
|
||||
lv_font_user_data_t user_data; /**< Custom user data for font. */
|
||||
#endif
|
||||
|
||||
|
||||
} lv_font_t;
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Return with the bitmap of a font.
|
||||
* @param font_p pointer to a font
|
||||
* @param letter an UNICODE character code
|
||||
* @return pointer to the bitmap of the letter
|
||||
*/
|
||||
const uint8_t * lv_font_get_glyph_bitmap(const lv_font_t * font_p, uint32_t letter);
|
||||
|
||||
/**
|
||||
* Get the descriptor of a glyph
|
||||
* @param font_p pointer to font
|
||||
* @param dsc_out store the result descriptor here
|
||||
* @param letter an UNICODE letter code
|
||||
* @return true: descriptor is successfully loaded into `dsc_out`.
|
||||
* false: the letter was not found, no data is loaded to `dsc_out`
|
||||
*/
|
||||
bool lv_font_get_glyph_dsc(const lv_font_t * font_p, lv_font_glyph_dsc_t * dsc_out, uint32_t letter, uint32_t letter_next);
|
||||
|
||||
/**
|
||||
* Get the width of a glyph with kerning
|
||||
* @param font pointer to a font
|
||||
* @param letter an UNICODE letter
|
||||
* @param letter_next the next letter after `letter`. Used for kerning
|
||||
* @return the width of the glyph
|
||||
*/
|
||||
uint16_t lv_font_get_glyph_width(const lv_font_t * font, uint32_t letter, uint32_t letter_next);
|
||||
|
||||
/**
|
||||
* Get the line height of a font. All characters fit into this height
|
||||
* @param font_p pointer to a font
|
||||
* @return the height of a font
|
||||
*/
|
||||
static inline uint8_t lv_font_get_line_height(const lv_font_t * font_p)
|
||||
{
|
||||
return font_p->line_height;
|
||||
}
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
#define LV_FONT_DECLARE(font_name) extern lv_font_t font_name;
|
||||
|
||||
#if LV_FONT_ROBOTO_12
|
||||
LV_FONT_DECLARE(lv_font_roboto_12)
|
||||
#endif
|
||||
|
||||
#if LV_FONT_ROBOTO_16
|
||||
LV_FONT_DECLARE(lv_font_roboto_16)
|
||||
#endif
|
||||
|
||||
#if LV_FONT_ROBOTO_22
|
||||
LV_FONT_DECLARE(lv_font_roboto_22)
|
||||
#endif
|
||||
|
||||
#if LV_FONT_ROBOTO_28
|
||||
LV_FONT_DECLARE(lv_font_roboto_28)
|
||||
#endif
|
||||
|
||||
#if LV_FONT_UNSCII_8
|
||||
LV_FONT_DECLARE(lv_font_unscii_8)
|
||||
#endif
|
||||
|
||||
/*Declare the custom (user defined) fonts*/
|
||||
#ifdef LV_FONT_CUSTOM_DECLARE
|
||||
LV_FONT_CUSTOM_DECLARE
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif /*USE_FONT*/
|
@ -1,12 +0,0 @@
|
||||
CSRCS += lv_font.c
|
||||
CSRCS += lv_font_fmt_txt.c
|
||||
CSRCS += lv_font_roboto_12.c
|
||||
CSRCS += lv_font_roboto_16.c
|
||||
CSRCS += lv_font_roboto_22.c
|
||||
CSRCS += lv_font_roboto_28.c
|
||||
CSRCS += lv_font_unscii_8.c
|
||||
|
||||
DEPPATH += --dep-path $(LVGL_DIR)/lvgl/src/lv_font
|
||||
VPATH += :$(LVGL_DIR)/lvgl/src/lv_font
|
||||
|
||||
CFLAGS += "-I$(LVGL_DIR)/lvgl/src/lv_font"
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user