diff --git a/.github/workflows/ccpp.yml b/.github/workflows/ccpp.yml index eb40232e2..46a81c62c 100644 --- a/.github/workflows/ccpp.yml +++ b/.github/workflows/ccpp.yml @@ -14,4 +14,4 @@ jobs: steps: - uses: actions/checkout@v2 - name: Run tests - run: cd tests; python ./build.py + run: sudo apt-get install libpng-dev; cd tests; python ./build.py diff --git a/CHANGELOG.md b/CHANGELOG.md index 66f4c4760..adb860656 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,21 +1,34 @@ # Changelog -## v7.4.0 (planned on 01.09.2020) +## v7.5.0 (planned at 15.09.2020) + +### New features +- Add `clean_dcache_cb` and `lv_disp_clean_dcache` to enable users to use their own cache management function +- Add `gpu_wait_cb` to wait until the GPU is working. It allows to run CPU a wait only when the rendered data is needed. + +### Bugfixes + + +## v7.4.0 (01.09.2020) + +The main new features of v7.4 are run-time font loading, style caching and arc knob with value setting by click. ### New features -- arc: add set value by click feature -- arc: add `LV_ARC_PART_KNOB` similarly to slider -- send gestures even is the the obejct was dragged. User can check dragging with `lv_indev_is_dragging(lv_indev_act())` in the event function. - Add `lv_font_load()` function - Loads a `lv_font_t` object from a binary font file - Add `lv_font_free()` function - Frees the memory allocated by the `lv_font_load()` function - Add style caching to reduce acces time of properties with default value +- arc: add set value by click feature +- arc: add `LV_ARC_PART_KNOB` similarly to slider +- send gestures even is the the obejct was dragged. User can check dragging with `lv_indev_is_dragging(lv_indev_act())` in the event function. ### Bugfixes - Fix color bleeding on border drawing - Fix using 'LV_SCROLLBAR_UNHIDE' after 'LV_SCROLLBAR_ON' - Fix croping of last column/row if an image is zoomed -- Fix zooming and rotateing mosaic images7 +- Fix zooming and rotateing mosaic images - Fix deleting tabview with LEFT/RIGHT tab position +- Fix btnmatrix to not send event when CLICK_TRIG = true and the cursor slid from a pressed button +- Fix roller width if selected text is larger than the normal ## v7.3.1 (18.08.2020) diff --git a/docs/ROADMAP.md b/docs/ROADMAP.md index 9b5914e58..889b19fa6 100644 --- a/docs/ROADMAP.md +++ b/docs/ROADMAP.md @@ -21,8 +21,6 @@ Planned to September/October 2020 - Work in progress - Simplified File system interface ([feat/new_fs_api](https://github.com/lvgl/lvgl/tree/feat/new-fs-api) branch) to make porting easier - Work in progress -- Add new label alignment modes - - See [#1656](https://github.com/lvgl/lvgl/issues/1656) - Remove the align parameter from `lv_canvas_draw_text` ## v9 @@ -37,3 +35,4 @@ Planned to September/October 2020 - Need coverage report for tests - Need static analize (via coverity.io or somehing else) - Support dot_begin and dot_middle long modes for labels +- Add new label alignment modes. [#1656](https://github.com/lvgl/lvgl/issues/1656) diff --git a/library.json b/library.json index a6eb48edf..5f6adb3ed 100644 --- a/library.json +++ b/library.json @@ -1,6 +1,6 @@ { "name": "lvgl", - "version": "7.3.1", + "version": "7.4.0", "keywords": "graphics, gui, embedded, tft, lvgl", "description": "Graphics library to create embedded GUI with easy-to-use graphical elements, beautiful visual effects and low memory footprint. It offers anti-aliasing, opacity, and animations using only one frame buffer.", "repository": { diff --git a/library.properties b/library.properties index 44897bb54..4a160a47f 100644 --- a/library.properties +++ b/library.properties @@ -1,5 +1,5 @@ name=lvgl -version=7.3.1 +version=7.4.0 author=kisvegabor maintainer=kisvegabor,embeddedt,pete-pjb sentence=Full-featured Graphics Library for Embedded Systems diff --git a/lv_conf_template.h b/lv_conf_template.h index 6faeafad3..7f009b082 100644 --- a/lv_conf_template.h +++ b/lv_conf_template.h @@ -1,6 +1,6 @@ /** * @file lv_conf.h - * Configuration file for v7.6.0-dev-dev + * Configuration file for v7.5.0-dev */ /* @@ -687,9 +687,6 @@ typedef void * lv_obj_user_data_t; # define LV_ROLLER_INF_PAGES 7 #endif -/*Rotary (dependencies: lv_arc, lv_btn)*/ -#define LV_USE_ROTARY 1 - /*Slider (dependencies: lv_bar)*/ #define LV_USE_SLIDER 1 diff --git a/lvgl.h b/lvgl.h index 0cc2f8fae..288d48184 100644 --- a/lvgl.h +++ b/lvgl.h @@ -15,7 +15,7 @@ extern "C" { * CURRENT VERSION OF LVGL ***************************/ #define LVGL_VERSION_MAJOR 7 -#define LVGL_VERSION_MINOR 4 +#define LVGL_VERSION_MINOR 5 #define LVGL_VERSION_PATCH 0 #define LVGL_VERSION_INFO "dev" @@ -82,6 +82,8 @@ extern "C" { #include "src/lv_api_map.h" +//#define LV_BUILD_TEST 1 + /********************* * DEFINES *********************/ diff --git a/scripts/release.py b/scripts/release.py index feaa3707b..c06bf5292 100755 --- a/scripts/release.py +++ b/scripts/release.py @@ -54,6 +54,7 @@ import sys upstream_org_url = "https://github.com/lvgl/" workdir = "./release_tmp" +proj_list = [ "lv_sim_eclipse_sdl"] ver_major = -1 ver_minor = -1 @@ -81,11 +82,12 @@ def cmd(c, exit_on_err = True): def define_set(fn, name, value): print("In " + fn + " set " + name + " to " + value) - new_content = "" + new_content = "" + s = r'^ *# *define +' + str(name).rstrip() + f = open(fn, "r") - for i in f.read().splitlines(): - r = re.search(r'^ *# *define +' + name, i) + r = re.search(s, i) if r: d = i.split("define") i = d[0] + "define " + name + " " + value @@ -106,12 +108,16 @@ def clone_repos(): #cmd("cp -a ../repos/. .") #return - cmd("git clone " + upstream("lvgl") + " lvgl; cd lvgl; git checkout master") + cmd("git clone " + upstream("lvgl") + "; cd lvgl; git checkout master") cmd("git clone " + upstream("lv_examples") + "; cd lv_examples; git checkout master") cmd("git clone " + upstream("lv_drivers") + "; cd lv_drivers; git checkout master") cmd("git clone --recurse-submodules " + upstream("docs") + "; cd docs; git checkout master") cmd("git clone " + upstream("blog") + "; cd blog; git checkout master") + for p in proj_list: + cmd("git clone " + upstream(p) + " --recurse-submodules ; cd " + p + "; git checkout master") + + def get_lvgl_version(br): print("Get LVGL's version") @@ -299,14 +305,25 @@ def update_release_branches(): cmd("cd docs; " + merge_cmd) def publish_master(): + + #Merge LVGL master to dev first to avoid "merge-to-dev.yml" running asynchronous + os.chdir("./lvgl") + cmd("git checkout dev") + cmd("git merge master -X theirs") + cmd("git add .") + cmd("git commit -am 'Merge master'", False) + cmd("git push origin dev") + cmd("git checkout master") + os.chdir("../") + pub_cmd = "git push origin master; git push origin " + ver_str cmd("cd lvgl; " + pub_cmd) cmd("cd lv_examples; " + pub_cmd) cmd("cd lv_drivers; " + pub_cmd) pub_cmd = "git push origin latest; git push origin " + ver_str - cmd("cd docs; " + pub_cmd) - cmd("cd docs; git checkout master; ./update.py " + release_br) + cmd("cd docs; " + pub_cmd) + cmd("cd docs; git checkout master; python 2.7 ./update.py " + release_br) pub_cmd = "git push origin master" cmd("cd blog; " + pub_cmd) @@ -342,7 +359,7 @@ def lvgl_update_master_version(): templ = fnmatch.filter(os.listdir('.'), '*templ*') if templ[0]: print("Updating version in " + templ[0]) - cmd("sed -i -r 's/v[0-9]+\.[0-9]+\.[0-9]+/"+ ver_str +"/' " + templ[0]) + cmd("sed -i -r 's/v[0-9]+\.[0-9]+\.[0-9]+.*/"+ ver_str +"/' " + templ[0]) cmd("git commit -am 'Update version'") @@ -367,15 +384,15 @@ def lvgl_update_dev_version(): os.chdir("./lvgl") cmd("git checkout dev") - define_set("./lvgl.h", "LVGL_VERSION_MAJOR", ver_major) - define_set("./lvgl.h", "LVGL_VERSION_MINOR", ver_minor) - define_set("./lvgl.h", "LVGL_VERSION_PATCH", ver_patch) + define_set("./lvgl.h", "LVGL_VERSION_MAJOR", str(ver_major)) + define_set("./lvgl.h", "LVGL_VERSION_MINOR", str(ver_minor)) + define_set("./lvgl.h", "LVGL_VERSION_PATCH", str(ver_patch)) define_set("./lvgl.h", "LVGL_VERSION_INFO", "\"dev\"") templ = fnmatch.filter(os.listdir('.'), '*templ*') if templ[0]: print("Updating version in " + templ[0]) - cmd("sed -i -r 's/v[0-9]+\.[0-9]+\.[0-9]+/"+ dev_ver_str +"/' " + templ[0]) + cmd("sed -i -r 's/v[0-9]+\.[0-9]+\.[0-9]+.*/"+ dev_ver_str +"/' " + templ[0]) cmd("git commit -am 'Update dev version'") @@ -401,22 +418,60 @@ def publish_dev_and_master(): pub_cmd = "git checkout master; git push origin master" cmd("cd lvgl; " + pub_cmd) - cmd("cd docs; git checkout master; ./update.py latest dev") + cmd("cd docs; git checkout master; python 2.7 ./update.py latest dev") + +def projs_update(): + global proj_list, release_br, ver_str + for p in proj_list: + os.chdir("./" + p) + cmd('git checkout master') + print(p + ": upadte lvgl"); + cmd("cd lvgl; git co " + release_br + "; git pull origin " + release_br) + cmd("cp -f lvgl/lv_conf_template.h lv_conf.h") + cmd("sed -i -r 's/#if 0/#if 1/' lv_conf.h") # Enable lv_conf.h + d = {} + with open("confdef.txt") as f: + for line in f: + (key, val) = line.rstrip().split('\t') + d[key] = val + + for k,v in d.items(): + define_set("lv_conf.h", str(k), str(v)) + + if os.path.exists("lv_examples"): + print(p + ": upadte lv_examples"); + cmd("cd lv_examples; git co " + release_br + "; git pull origin " + release_br) + + if os.path.exists("lv_drivers"): + print(p + ": upadte lv_drivers"); + cmd("cd lv_drivers " + release_br + "; git pull origin " + release_br) + + msg = 'Update to ' + ver_str + cmd("git add .") + cmd('git commit -am "' + msg + '"') + cmd('git push origin master') + cmd("git tag -a " + ver_str + " -m '" + msg + "' " ) + cmd('git push origin ' + ver_str) + + os.chdir("../") + def cleanup(): os.chdir("../") cmd("rm -fr " + workdir) if __name__ == '__main__': + dev_prepare = 'minor' if(len(sys.argv) != 2): - print("Argument error. Usage ./release.py bugfix | minor | major") - exit(1) - - dev_prepare = sys.argv[1] + print("Missing argument. Usage ./release.py bugfix | minor | major") + print("Use minor by deafult") + else: + dev_prepare = sys.argv[1] + if not (dev_prepare in prepare_type): print("Invalid argument. Usage ./release.py bugfix | minor | major") exit(1) - + clone_repos() get_lvgl_version("master") lvgl_prepare() @@ -454,9 +509,9 @@ if __name__ == '__main__': ver_minor = "0" ver_patch = "0" - dev_ver_str = "v" + ver_major + "." + ver_minor + "." + ver_patch + "-dev" + dev_ver_str = "v" + str(ver_major) + "." + str(ver_minor) + "." + str(ver_patch) + "-dev" - print("Prepare minor version " + ver_str) + print("Prepare minor version " + dev_ver_str) merge_to_dev() merge_from_dev() @@ -465,5 +520,6 @@ if __name__ == '__main__': docs_update_dev_version() publish_dev_and_master() + projs_update() cleanup() diff --git a/src/lv_conf_internal.h b/src/lv_conf_internal.h index 8a031535f..0f5f28ac0 100644 --- a/src/lv_conf_internal.h +++ b/src/lv_conf_internal.h @@ -1049,8 +1049,9 @@ e.g. "stm32f769xx.h" or "stm32f429xx.h" */ /*Rotary (dependencies: lv_arc, lv_btn)*/ #ifndef LV_USE_ROTARY -#define LV_USE_ROTARY 1 +#define LV_USE_ROTARY 1 #endif + /*Slider (dependencies: lv_bar)*/ #ifndef LV_USE_SLIDER #define LV_USE_SLIDER 1 diff --git a/src/lv_core/lv_disp.c b/src/lv_core/lv_disp.c index 6cf6283ef..2b24c1d0b 100644 --- a/src/lv_core/lv_disp.c +++ b/src/lv_core/lv_disp.c @@ -352,6 +352,21 @@ void lv_disp_trig_activity(lv_disp_t * disp) disp->last_activity_time = lv_tick_get(); } +/** + * Clean any CPU cache that is related to the display. + * @param disp pointer to an display (NULL to use the default display) + */ +void lv_disp_clean_dcache(lv_disp_t * disp) +{ + if(!disp) disp = lv_disp_get_default(); + if(!disp) { + LV_LOG_WARN("lv_disp_clean_dcache: no display registered"); + return; + } + + if(disp->driver.clean_dcache_cb) + disp->driver.clean_dcache_cb(&disp->driver); +} /** * Get a pointer to the screen refresher task to diff --git a/src/lv_core/lv_disp.h b/src/lv_core/lv_disp.h index 888a0c093..3083c46d2 100644 --- a/src/lv_core/lv_disp.h +++ b/src/lv_core/lv_disp.h @@ -133,6 +133,12 @@ uint32_t lv_disp_get_inactive_time(const lv_disp_t * disp); */ void lv_disp_trig_activity(lv_disp_t * disp); +/** + * Clean any CPU cache that is related to the display. + * @param disp pointer to an display (NULL to use the default display) + */ +void lv_disp_clean_dcache(lv_disp_t * disp); + /** * Get a pointer to the screen refresher task to * modify its parameters with `lv_task_...` functions. diff --git a/src/lv_core/lv_obj.c b/src/lv_core/lv_obj.c index 04a0bc1a2..30c5f6c6c 100644 --- a/src/lv_core/lv_obj.c +++ b/src/lv_core/lv_obj.c @@ -1442,10 +1442,10 @@ void _lv_obj_disable_style_caching(lv_obj_t * obj, bool dis) list->ignore_cache = dis; } for(part = _LV_OBJ_PART_REAL_FIRST; part < 0xFF; part++) { - lv_style_list_t * list = lv_obj_get_style_list(obj, part); - if(list == NULL) break; - list->ignore_cache = dis; - } + lv_style_list_t * list = lv_obj_get_style_list(obj, part); + if(list == NULL) break; + list->ignore_cache = dis; + } } /*----------------- @@ -2512,61 +2512,61 @@ lv_style_int_t _lv_obj_get_style_int(const lv_obj_t * obj, uint8_t part, lv_styl while(parent) { lv_style_list_t * list = lv_obj_get_style_list(parent, part); if(!list->ignore_cache && list->style_cnt > 0) { - if(!list->valid_cache) update_style_cache((lv_obj_t*)parent, part, prop & (~LV_STYLE_STATE_MASK)); + if(!list->valid_cache) update_style_cache((lv_obj_t *)parent, part, prop & (~LV_STYLE_STATE_MASK)); bool def = false; switch(prop & (~LV_STYLE_STATE_MASK)) { - case LV_STYLE_BG_GRAD_DIR: - if(list->bg_grad_dir_none) def = true; - break; - case LV_STYLE_CLIP_CORNER: - if(list->clip_corner_off) def = true; - break; - case LV_STYLE_TEXT_LETTER_SPACE: - case LV_STYLE_TEXT_LINE_SPACE: - if(list->text_space_zero) def = true; - break; - case LV_STYLE_TRANSFORM_ANGLE: - case LV_STYLE_TRANSFORM_WIDTH: - case LV_STYLE_TRANSFORM_HEIGHT: - case LV_STYLE_TRANSFORM_ZOOM: - if(list->transform_all_zero) def = true; - break; - case LV_STYLE_BORDER_WIDTH: - if(list->border_width_zero) def = true; - break; - case LV_STYLE_BORDER_SIDE: - if(list->border_side_full) def = true; - break; - case LV_STYLE_BORDER_POST: - if(list->border_post_off) def = true; - break; - case LV_STYLE_OUTLINE_WIDTH: - if(list->outline_width_zero) def = true; - break; - case LV_STYLE_RADIUS: - if(list->radius_zero) def = true; - break; - case LV_STYLE_SHADOW_WIDTH: - if(list->shadow_width_zero) def = true; - break; - case LV_STYLE_PAD_TOP: - case LV_STYLE_PAD_BOTTOM: - case LV_STYLE_PAD_LEFT: - case LV_STYLE_PAD_RIGHT: - if(list->pad_all_zero) def = true; - break; - case LV_STYLE_BG_BLEND_MODE: - case LV_STYLE_BORDER_BLEND_MODE: - case LV_STYLE_IMAGE_BLEND_MODE: - case LV_STYLE_LINE_BLEND_MODE: - case LV_STYLE_OUTLINE_BLEND_MODE: - case LV_STYLE_PATTERN_BLEND_MODE: - case LV_STYLE_SHADOW_BLEND_MODE: - case LV_STYLE_TEXT_BLEND_MODE: - case LV_STYLE_VALUE_BLEND_MODE: - if(list->blend_mode_all_normal) def = true; - break; + case LV_STYLE_BG_GRAD_DIR: + if(list->bg_grad_dir_none) def = true; + break; + case LV_STYLE_CLIP_CORNER: + if(list->clip_corner_off) def = true; + break; + case LV_STYLE_TEXT_LETTER_SPACE: + case LV_STYLE_TEXT_LINE_SPACE: + if(list->text_space_zero) def = true; + break; + case LV_STYLE_TRANSFORM_ANGLE: + case LV_STYLE_TRANSFORM_WIDTH: + case LV_STYLE_TRANSFORM_HEIGHT: + case LV_STYLE_TRANSFORM_ZOOM: + if(list->transform_all_zero) def = true; + break; + case LV_STYLE_BORDER_WIDTH: + if(list->border_width_zero) def = true; + break; + case LV_STYLE_BORDER_SIDE: + if(list->border_side_full) def = true; + break; + case LV_STYLE_BORDER_POST: + if(list->border_post_off) def = true; + break; + case LV_STYLE_OUTLINE_WIDTH: + if(list->outline_width_zero) def = true; + break; + case LV_STYLE_RADIUS: + if(list->radius_zero) def = true; + break; + case LV_STYLE_SHADOW_WIDTH: + if(list->shadow_width_zero) def = true; + break; + case LV_STYLE_PAD_TOP: + case LV_STYLE_PAD_BOTTOM: + case LV_STYLE_PAD_LEFT: + case LV_STYLE_PAD_RIGHT: + if(list->pad_all_zero) def = true; + break; + case LV_STYLE_BG_BLEND_MODE: + case LV_STYLE_BORDER_BLEND_MODE: + case LV_STYLE_IMAGE_BLEND_MODE: + case LV_STYLE_LINE_BLEND_MODE: + case LV_STYLE_OUTLINE_BLEND_MODE: + case LV_STYLE_PATTERN_BLEND_MODE: + case LV_STYLE_SHADOW_BLEND_MODE: + case LV_STYLE_TEXT_BLEND_MODE: + case LV_STYLE_VALUE_BLEND_MODE: + if(list->blend_mode_all_normal) def = true; + break; } if(def) { @@ -2694,19 +2694,19 @@ lv_opa_t _lv_obj_get_style_opa(const lv_obj_t * obj, uint8_t part, lv_style_prop lv_style_list_t * list = lv_obj_get_style_list(parent, part); if(!list->ignore_cache && list->style_cnt > 0) { - if(!list->valid_cache) update_style_cache((lv_obj_t*)parent, part, prop & (~LV_STYLE_STATE_MASK)); + if(!list->valid_cache) update_style_cache((lv_obj_t *)parent, part, prop & (~LV_STYLE_STATE_MASK)); bool def = false; switch(prop & (~LV_STYLE_STATE_MASK)) { - case LV_STYLE_OPA_SCALE: - if(list->opa_scale_cover) def = true; - break; - case LV_STYLE_BG_OPA: - if(list->bg_opa_cover) return LV_OPA_COVER; /*Special case, not the default value is used*/ - if(list->bg_opa_transp) def = true; - break; - case LV_STYLE_IMAGE_RECOLOR_OPA: - if(list->img_recolor_opa_transp) def = true; - break; + case LV_STYLE_OPA_SCALE: + if(list->opa_scale_cover) def = true; + break; + case LV_STYLE_BG_OPA: + if(list->bg_opa_cover) return LV_OPA_COVER; /*Special case, not the default value is used*/ + if(list->bg_opa_transp) def = true; + break; + case LV_STYLE_IMAGE_RECOLOR_OPA: + if(list->img_recolor_opa_transp) def = true; + break; } if(def) { @@ -2773,18 +2773,18 @@ const void * _lv_obj_get_style_ptr(const lv_obj_t * obj, uint8_t part, lv_style_ lv_style_list_t * list = lv_obj_get_style_list(parent, part); if(!list->ignore_cache && list->style_cnt > 0) { - if(!list->valid_cache) update_style_cache((lv_obj_t*)parent, part, prop & (~LV_STYLE_STATE_MASK)); + if(!list->valid_cache) update_style_cache((lv_obj_t *)parent, part, prop & (~LV_STYLE_STATE_MASK)); bool def = false; switch(prop & (~LV_STYLE_STATE_MASK)) { - case LV_STYLE_VALUE_STR: - if(list->value_txt_str) def = true; - break; - case LV_STYLE_PATTERN_IMAGE: - if(list->pattern_img_null) def = true; - break; - case LV_STYLE_TEXT_FONT: - if(list->text_font_normal) def = true; - break; + case LV_STYLE_VALUE_STR: + if(list->value_txt_str) def = true; + break; + case LV_STYLE_PATTERN_IMAGE: + if(list->pattern_img_null) def = true; + break; + case LV_STYLE_TEXT_FONT: + if(list->text_font_normal) def = true; + break; } if(def) { @@ -4472,44 +4472,44 @@ static bool style_prop_is_cacheble(lv_style_property_t prop) { switch(prop) { - case LV_STYLE_PROP_ALL: - case LV_STYLE_BG_GRAD_DIR: - case LV_STYLE_CLIP_CORNER: - case LV_STYLE_TEXT_LETTER_SPACE: - case LV_STYLE_TEXT_LINE_SPACE: - case LV_STYLE_TEXT_FONT: - case LV_STYLE_TRANSFORM_ANGLE: - case LV_STYLE_TRANSFORM_WIDTH: - case LV_STYLE_TRANSFORM_HEIGHT: - case LV_STYLE_TRANSFORM_ZOOM: - case LV_STYLE_BORDER_WIDTH: - case LV_STYLE_OUTLINE_WIDTH: - case LV_STYLE_RADIUS: - case LV_STYLE_SHADOW_WIDTH: - case LV_STYLE_OPA_SCALE: - case LV_STYLE_BG_OPA: - case LV_STYLE_BORDER_SIDE: - case LV_STYLE_BORDER_POST: - case LV_STYLE_IMAGE_RECOLOR_OPA: - case LV_STYLE_VALUE_STR: - case LV_STYLE_PATTERN_IMAGE: - case LV_STYLE_PAD_TOP: - case LV_STYLE_PAD_BOTTOM: - case LV_STYLE_PAD_LEFT: - case LV_STYLE_PAD_RIGHT: - case LV_STYLE_BG_BLEND_MODE: - case LV_STYLE_BORDER_BLEND_MODE: - case LV_STYLE_IMAGE_BLEND_MODE: - case LV_STYLE_LINE_BLEND_MODE: - case LV_STYLE_OUTLINE_BLEND_MODE: - case LV_STYLE_PATTERN_BLEND_MODE: - case LV_STYLE_SHADOW_BLEND_MODE: - case LV_STYLE_TEXT_BLEND_MODE: - case LV_STYLE_VALUE_BLEND_MODE: - return true; - break; - default: - return false; + case LV_STYLE_PROP_ALL: + case LV_STYLE_BG_GRAD_DIR: + case LV_STYLE_CLIP_CORNER: + case LV_STYLE_TEXT_LETTER_SPACE: + case LV_STYLE_TEXT_LINE_SPACE: + case LV_STYLE_TEXT_FONT: + case LV_STYLE_TRANSFORM_ANGLE: + case LV_STYLE_TRANSFORM_WIDTH: + case LV_STYLE_TRANSFORM_HEIGHT: + case LV_STYLE_TRANSFORM_ZOOM: + case LV_STYLE_BORDER_WIDTH: + case LV_STYLE_OUTLINE_WIDTH: + case LV_STYLE_RADIUS: + case LV_STYLE_SHADOW_WIDTH: + case LV_STYLE_OPA_SCALE: + case LV_STYLE_BG_OPA: + case LV_STYLE_BORDER_SIDE: + case LV_STYLE_BORDER_POST: + case LV_STYLE_IMAGE_RECOLOR_OPA: + case LV_STYLE_VALUE_STR: + case LV_STYLE_PATTERN_IMAGE: + case LV_STYLE_PAD_TOP: + case LV_STYLE_PAD_BOTTOM: + case LV_STYLE_PAD_LEFT: + case LV_STYLE_PAD_RIGHT: + case LV_STYLE_BG_BLEND_MODE: + case LV_STYLE_BORDER_BLEND_MODE: + case LV_STYLE_IMAGE_BLEND_MODE: + case LV_STYLE_LINE_BLEND_MODE: + case LV_STYLE_OUTLINE_BLEND_MODE: + case LV_STYLE_PATTERN_BLEND_MODE: + case LV_STYLE_SHADOW_BLEND_MODE: + case LV_STYLE_TEXT_BLEND_MODE: + case LV_STYLE_VALUE_BLEND_MODE: + return true; + break; + default: + return false; } } @@ -4564,32 +4564,29 @@ static void update_style_cache(lv_obj_t * obj, uint8_t part, uint16_t prop) if(lv_obj_get_style_transform_angle(obj, part) != 0 || lv_obj_get_style_transform_width(obj, part) != 0 || lv_obj_get_style_transform_height(obj, part) != 0 || - lv_obj_get_style_transform_zoom(obj, part) != LV_IMG_ZOOM_NONE) - { + lv_obj_get_style_transform_zoom(obj, part) != LV_IMG_ZOOM_NONE) { list->transform_all_zero = 0; } list->pad_all_zero = 1; if(lv_obj_get_style_pad_top(obj, part) != 0 || - lv_obj_get_style_pad_bottom(obj, part) != 0 || - lv_obj_get_style_pad_left(obj, part) != 0 || - lv_obj_get_style_pad_right(obj, part) != 0) - { + lv_obj_get_style_pad_bottom(obj, part) != 0 || + lv_obj_get_style_pad_left(obj, part) != 0 || + lv_obj_get_style_pad_right(obj, part) != 0) { list->pad_all_zero = 0; } list->blend_mode_all_normal = 1; #if LV_USE_BLEND_MODES if(lv_obj_get_style_bg_blend_mode(obj, part) != LV_BLEND_MODE_NORMAL || - lv_obj_get_style_border_blend_mode(obj, part) != LV_BLEND_MODE_NORMAL || - lv_obj_get_style_pattern_blend_mode(obj, part) != LV_BLEND_MODE_NORMAL || - lv_obj_get_style_outline_blend_mode(obj, part) != LV_BLEND_MODE_NORMAL || - lv_obj_get_style_value_blend_mode(obj, part) != LV_BLEND_MODE_NORMAL || - lv_obj_get_style_text_blend_mode(obj, part) != LV_BLEND_MODE_NORMAL || - lv_obj_get_style_line_blend_mode(obj, part) != LV_BLEND_MODE_NORMAL || - lv_obj_get_style_image_blend_mode(obj, part) != LV_BLEND_MODE_NORMAL || - lv_obj_get_style_shadow_blend_mode(obj, part) != LV_BLEND_MODE_NORMAL) - { + lv_obj_get_style_border_blend_mode(obj, part) != LV_BLEND_MODE_NORMAL || + lv_obj_get_style_pattern_blend_mode(obj, part) != LV_BLEND_MODE_NORMAL || + lv_obj_get_style_outline_blend_mode(obj, part) != LV_BLEND_MODE_NORMAL || + lv_obj_get_style_value_blend_mode(obj, part) != LV_BLEND_MODE_NORMAL || + lv_obj_get_style_text_blend_mode(obj, part) != LV_BLEND_MODE_NORMAL || + lv_obj_get_style_line_blend_mode(obj, part) != LV_BLEND_MODE_NORMAL || + lv_obj_get_style_image_blend_mode(obj, part) != LV_BLEND_MODE_NORMAL || + lv_obj_get_style_shadow_blend_mode(obj, part) != LV_BLEND_MODE_NORMAL) { list->blend_mode_all_normal = 0; } #endif @@ -4619,7 +4616,7 @@ static void update_style_cache_children(lv_obj_t * obj) list->text_space_zero = 1; if(lv_obj_get_style_text_letter_space(obj, part) != 0 || - lv_obj_get_style_text_line_space(obj, part) != 0) { + lv_obj_get_style_text_line_space(obj, part) != 0) { list->text_space_zero = 0; } @@ -4647,7 +4644,8 @@ static void invalidate_style_cache(lv_obj_t * obj, uint8_t part, lv_style_proper lv_style_list_t * list = lv_obj_get_style_list(obj, part); if(list == NULL) return; list->valid_cache = 0; - } else { + } + else { for(part = 0; part < _LV_OBJ_PART_REAL_FIRST; part++) { lv_style_list_t * list = lv_obj_get_style_list(obj, part); @@ -4655,10 +4653,10 @@ static void invalidate_style_cache(lv_obj_t * obj, uint8_t part, lv_style_proper list->valid_cache = 0; } for(part = _LV_OBJ_PART_REAL_FIRST; part < 0xFF; part++) { - lv_style_list_t * list = lv_obj_get_style_list(obj, part); - if(list == NULL) break; - list->valid_cache = 0; - } + lv_style_list_t * list = lv_obj_get_style_list(obj, part); + if(list == NULL) break; + list->valid_cache = 0; + } } lv_obj_t * child = lv_obj_get_child(obj, NULL); diff --git a/src/lv_core/lv_refr.c b/src/lv_core/lv_refr.c index 0765fba27..17ba015d6 100644 --- a/src/lv_core/lv_refr.c +++ b/src/lv_core/lv_refr.c @@ -572,10 +572,15 @@ static lv_obj_t * lv_refr_get_top_obj(const lv_area_t * area_p, lv_obj_t * obj) /*If this object is fully cover the draw area check the children too */ if(_lv_area_is_in(area_p, &obj->coords, 0) && obj->hidden == 0) { - lv_design_res_t design_res = obj->design_cb ? obj->design_cb(obj, area_p, - LV_DESIGN_COVER_CHK) : LV_DESIGN_RES_NOT_COVER; + lv_design_res_t design_res = obj->design_cb(obj, area_p, LV_DESIGN_COVER_CHK); if(design_res == LV_DESIGN_RES_MASKED) return NULL; +#if LV_USE_OPA_SCALE + if(design_res == LV_DESIGN_RES_COVER && lv_obj_get_style_opa_scale(obj, LV_OBJ_PART_MAIN) != LV_OPA_COVER) { + design_res = LV_DESIGN_RES_NOT_COVER; + } +#endif + lv_obj_t * i; _LV_LL_READ(obj->child_ll, i) { found_p = lv_refr_get_top_obj(area_p, i); @@ -741,6 +746,8 @@ static void lv_refr_vdb_flush(void) /*Flush the rendered content to the display*/ lv_disp_t * disp = _lv_refr_get_disp_refreshing(); + if (disp->driver.gpu_wait_cb) disp->driver.gpu_wait_cb(&disp->driver); + if(disp->driver.flush_cb) disp->driver.flush_cb(&disp->driver, &vdb->area, vdb->buf_act); if(vdb->buf1 && vdb->buf2) { diff --git a/src/lv_core/lv_style.h b/src/lv_core/lv_style.h index 7ed69dbc5..8d9d15d8e 100644 --- a/src/lv_core/lv_style.h +++ b/src/lv_core/lv_style.h @@ -221,37 +221,37 @@ typedef struct { #if LV_USE_ASSERT_STYLE uint32_t sentinel; #endif - uint32_t style_cnt :6; - uint32_t has_local :1; - uint32_t has_trans :1; - uint32_t skip_trans :1; /*1: Temporally skip the transition style if any*/ - uint32_t ignore_trans :1; /*1: Mark that this style list shouldn't receive transitions at all*/ - uint32_t valid_cache :1; /*1: The cache is valid and can be used*/ - uint32_t ignore_cache :1; /*1: Ignore cache while getting value of properties*/ + uint32_t style_cnt : 6; + uint32_t has_local : 1; + uint32_t has_trans : 1; + uint32_t skip_trans : 1; /*1: Temporally skip the transition style if any*/ + uint32_t ignore_trans : 1; /*1: Mark that this style list shouldn't receive transitions at all*/ + uint32_t valid_cache : 1; /*1: The cache is valid and can be used*/ + uint32_t ignore_cache : 1; /*1: Ignore cache while getting value of properties*/ - uint32_t radius_zero :1; - uint32_t opa_scale_cover :1; - uint32_t clip_corner_off :1; - uint32_t transform_all_zero :1; - uint32_t pad_all_zero :1; - uint32_t blend_mode_all_normal :1; - uint32_t bg_opa_transp :1; - uint32_t bg_opa_cover :1; - uint32_t bg_grad_dir_none :1; + uint32_t radius_zero : 1; + uint32_t opa_scale_cover : 1; + uint32_t clip_corner_off : 1; + uint32_t transform_all_zero : 1; + uint32_t pad_all_zero : 1; + uint32_t blend_mode_all_normal : 1; + uint32_t bg_opa_transp : 1; + uint32_t bg_opa_cover : 1; + uint32_t bg_grad_dir_none : 1; - uint32_t border_width_zero :1; - uint32_t border_side_full :1; - uint32_t border_post_off :1; + uint32_t border_width_zero : 1; + uint32_t border_side_full : 1; + uint32_t border_post_off : 1; - uint32_t outline_width_zero :1; - uint32_t pattern_img_null :1; - uint32_t shadow_width_zero :1; - uint32_t value_txt_str :1; - uint32_t img_recolor_opa_transp :1; + uint32_t outline_width_zero : 1; + uint32_t pattern_img_null : 1; + uint32_t shadow_width_zero : 1; + uint32_t value_txt_str : 1; + uint32_t img_recolor_opa_transp : 1; - uint32_t text_space_zero :1; - uint32_t text_decor_none :1; - uint32_t text_font_normal :1; + uint32_t text_space_zero : 1; + uint32_t text_decor_none : 1; + uint32_t text_font_normal : 1; } lv_style_list_t; /********************** diff --git a/src/lv_draw/lv_draw_blend.c b/src/lv_draw/lv_draw_blend.c index a7d9e0d1d..f4de48e7e 100644 --- a/src/lv_draw/lv_draw_blend.c +++ b/src/lv_draw/lv_draw_blend.c @@ -138,7 +138,8 @@ LV_ATTRIBUTE_FAST_MEM void _lv_blend_fill(const lv_area_t * clip_area, const lv_ const lv_area_t * disp_area = &vdb->area; lv_color_t * disp_buf = vdb->buf_act; - + if (disp->driver.gpu_wait_cb) disp->driver.gpu_wait_cb(&disp->driver); + /* Get clipped fill area which is the real draw area. * It is always the same or inside `fill_area` */ lv_area_t draw_area; @@ -212,6 +213,8 @@ LV_ATTRIBUTE_FAST_MEM void _lv_blend_map(const lv_area_t * clip_area, const lv_a const lv_area_t * disp_area = &vdb->area; lv_color_t * disp_buf = vdb->buf_act; + if (disp->driver.gpu_wait_cb) disp->driver.gpu_wait_cb(&disp->driver); + /* Now `draw_area` has absolute coordinates. * Make it relative to `disp_area` to simplify draw to `disp_buf`*/ draw_area.x1 -= disp_area->x1; diff --git a/src/lv_draw/lv_draw_rect.h b/src/lv_draw/lv_draw_rect.h index 1d3c4c4f7..0bf884832 100644 --- a/src/lv_draw/lv_draw_rect.h +++ b/src/lv_draw/lv_draw_rect.h @@ -41,7 +41,7 @@ typedef struct { lv_style_int_t border_side; lv_opa_t border_opa; lv_blend_mode_t border_blend_mode; - uint8_t border_post :1; /*There is a border it will be drawn later. */ + uint8_t border_post : 1; /*There is a border it will be drawn later. */ /*Outline*/ lv_color_t outline_color; diff --git a/src/lv_draw/lv_img_buf.h b/src/lv_draw/lv_img_buf.h index d549c8109..5b43456ac 100644 --- a/src/lv_draw/lv_img_buf.h +++ b/src/lv_draw/lv_img_buf.h @@ -308,14 +308,14 @@ static inline bool _lv_img_buf_transform(lv_img_transform_dsc_t * dsc, lv_coord_ ys = ((dsc->tmp.sinma * xt + dsc->tmp.cosma * yt) >> (_LV_TRANSFORM_TRIGO_SHIFT - 8)) + dsc->tmp.pivot_y_256; } else if(dsc->cfg.angle == 0) { - xt = (xt * dsc->tmp.zoom_inv) >> _LV_ZOOM_INV_UPSCALE; - yt = (yt * dsc->tmp.zoom_inv) >> _LV_ZOOM_INV_UPSCALE; + xt = (int32_t)((int32_t)xt * dsc->tmp.zoom_inv) >> _LV_ZOOM_INV_UPSCALE; + yt = (int32_t)((int32_t)yt * dsc->tmp.zoom_inv) >> _LV_ZOOM_INV_UPSCALE; xs = xt + dsc->tmp.pivot_x_256; ys = yt + dsc->tmp.pivot_y_256; } else { - xt = (xt * dsc->tmp.zoom_inv) >> _LV_ZOOM_INV_UPSCALE; - yt = (yt * dsc->tmp.zoom_inv) >> _LV_ZOOM_INV_UPSCALE; + xt = (int32_t)((int32_t)xt * dsc->tmp.zoom_inv) >> _LV_ZOOM_INV_UPSCALE; + yt = (int32_t)((int32_t)yt * dsc->tmp.zoom_inv) >> _LV_ZOOM_INV_UPSCALE; xs = ((dsc->tmp.cosma * xt - dsc->tmp.sinma * yt) >> (_LV_TRANSFORM_TRIGO_SHIFT)) + dsc->tmp.pivot_x_256; ys = ((dsc->tmp.sinma * xt + dsc->tmp.cosma * yt) >> (_LV_TRANSFORM_TRIGO_SHIFT)) + dsc->tmp.pivot_y_256; } diff --git a/src/lv_font/lv_font_loader.c b/src/lv_font/lv_font_loader.c index 53e7f77f4..cb9e78a21 100644 --- a/src/lv_font/lv_font_loader.c +++ b/src/lv_font/lv_font_loader.c @@ -102,7 +102,7 @@ lv_font_t * lv_font_load(const char * font_name) if(!success) { LV_LOG_WARN("Error loading font file: %s\n", font_name); - /* + /* * When `lvgl_load_font` fails it can leak some pointers. * All non-null pointers can be assumed as allocated and * `lv_font_free` should free them correctly. diff --git a/src/lv_gpu/lv_gpu_stm32_dma2d.c b/src/lv_gpu/lv_gpu_stm32_dma2d.c index d5c8e40dc..f11c4c6a4 100644 --- a/src/lv_gpu/lv_gpu_stm32_dma2d.c +++ b/src/lv_gpu/lv_gpu_stm32_dma2d.c @@ -7,6 +7,7 @@ * INCLUDES *********************/ #include "lv_gpu_stm32_dma2d.h" +#include "../lv_core/lv_disp.h" #include "../lv_core/lv_refr.h" #if LV_USE_GPU_STM32_DMA2D @@ -216,11 +217,10 @@ void lv_gpu_stm32_dma2d_blend(lv_color_t * buf, lv_coord_t buf_w, const lv_color static void invalidate_cache(void) { -#if __DCACHE_PRESENT - if(SCB->CCR & (uint32_t)SCB_CCR_DC_Msk) { + lv_disp_t * disp = _lv_refr_get_disp_refreshing(); + if(disp->driver.clean_dcache_cb) disp->driver.clean_dcache_cb(&disp->driver); + else SCB_CleanInvalidateDCache(); - } -#endif } static void dma2d_wait(void) diff --git a/src/lv_hal/lv_hal_disp.h b/src/lv_hal/lv_hal_disp.h index e99830b19..7a1eef6b0 100644 --- a/src/lv_hal/lv_hal_disp.h +++ b/src/lv_hal/lv_hal_disp.h @@ -111,7 +111,14 @@ typedef struct _disp_drv_t { * User can execute very simple tasks here or yield the task */ void (*wait_cb)(struct _disp_drv_t * disp_drv); + /** OPTIONAL: Called when lvgl needs any CPU cache that affects rendering to be cleaned */ + void (*clean_dcache_cb)(struct _disp_drv_t * disp_drv); + + /** OPTIONAL: called to wait while the gpu is working */ + void (*gpu_wait_cb)(struct _disp_drv_t * disp_drv); + #if LV_USE_GPU + /** OPTIONAL: Blend two memories using opacity (GPU only)*/ void (*gpu_blend_cb)(struct _disp_drv_t * disp_drv, lv_color_t * dest, const lv_color_t * src, uint32_t length, lv_opa_t opa); diff --git a/src/lv_misc/lv_txt.c b/src/lv_misc/lv_txt.c index a29a3c158..20c8326bb 100644 --- a/src/lv_misc/lv_txt.c +++ b/src/lv_misc/lv_txt.c @@ -436,6 +436,8 @@ void _lv_txt_ins(char * txt_buf, uint32_t pos, const char * ins_txt) { size_t old_len = strlen(txt_buf); size_t ins_len = strlen(ins_txt); + if(ins_len == 0) return; + size_t new_len = ins_len + old_len; pos = _lv_txt_encoded_get_byte_id(txt_buf, pos); /*Convert to byte index instead of letter index*/ diff --git a/src/lv_themes/lv_theme.h b/src/lv_themes/lv_theme.h index 3647f48f0..8297b0b53 100644 --- a/src/lv_themes/lv_theme.h +++ b/src/lv_themes/lv_theme.h @@ -109,9 +109,6 @@ typedef enum { #if LV_USE_ROLLER LV_THEME_ROLLER, #endif -#if LV_USE_ROTARY - LV_THEME_ROTARY, -#endif #if LV_USE_SLIDER LV_THEME_SLIDER, #endif diff --git a/src/lv_widgets/lv_arc.c b/src/lv_widgets/lv_arc.c index 98ad5339e..655a12802 100644 --- a/src/lv_widgets/lv_arc.c +++ b/src/lv_widgets/lv_arc.c @@ -34,6 +34,7 @@ static lv_style_list_t * lv_arc_get_style(lv_obj_t * arc, uint8_t part); static void inv_arc_area(lv_obj_t * arc, uint16_t start_angle, uint16_t end_angle, lv_arc_part_t part); static void get_center(lv_obj_t * arc, lv_point_t * center, lv_coord_t * arc_r); static void get_knob_area(lv_obj_t * arc, const lv_point_t * center, lv_coord_t r, lv_area_t * knob_area); +static void value_update(lv_obj_t * arc); /********************** * STATIC VARIABLES @@ -87,6 +88,7 @@ lv_obj_t * lv_arc_create(lv_obj_t * par, const lv_obj_t * copy) ext->min_value = 0; ext->max_value = 100; ext->dragging = false; + ext->adjustable = false; ext->chg_rate = 540; ext->last_tick = lv_tick_get(); ext->last_angle = ext->arc_angle_end; @@ -119,6 +121,7 @@ lv_obj_t * lv_arc_create(lv_obj_t * par, const lv_obj_t * copy) ext->min_value = copy_ext->min_value; ext->max_value = copy_ext->max_value; ext->dragging = copy_ext->dragging; + ext->adjustable = copy_ext->adjustable; ext->chg_rate = copy_ext->chg_rate; ext->last_tick = copy_ext->last_tick; ext->last_angle = copy_ext->last_angle; @@ -165,11 +168,13 @@ void lv_arc_set_start_angle(lv_obj_t * arc, uint16_t start) } /*Only a smaller incremental move*/ else if(ext->arc_angle_start > ext->arc_angle_end && start > ext->arc_angle_end) { - inv_arc_area(arc, LV_MATH_MIN(ext->arc_angle_start, start), LV_MATH_MAX(ext->arc_angle_start, start), LV_ARC_PART_INDIC); + inv_arc_area(arc, LV_MATH_MIN(ext->arc_angle_start, start), LV_MATH_MAX(ext->arc_angle_start, start), + LV_ARC_PART_INDIC); } /*Only a smaller incremental move*/ else if(ext->arc_angle_start < ext->arc_angle_end && start < ext->arc_angle_end) { - inv_arc_area(arc, LV_MATH_MIN(ext->arc_angle_start, start), LV_MATH_MAX(ext->arc_angle_start, start), LV_ARC_PART_INDIC); + inv_arc_area(arc, LV_MATH_MIN(ext->arc_angle_start, start), LV_MATH_MAX(ext->arc_angle_start, start), + LV_ARC_PART_INDIC); } /*Crossing the start angle makes the whole arc change*/ else { @@ -351,14 +356,14 @@ void lv_arc_set_type(lv_obj_t * arc, lv_arc_type_t type) { LV_ASSERT_OBJ(arc, LV_OBJX_NAME); - lv_arc_ext_t *ext = (lv_arc_ext_t *)lv_obj_get_ext_attr(arc); + lv_arc_ext_t * ext = (lv_arc_ext_t *)lv_obj_get_ext_attr(arc); int16_t val = ext->cur_value; ext->type = type; ext->cur_value = -1; /** Force set_value handling*/ int16_t bg_midpoint, bg_end = ext->bg_angle_end; - if (ext->bg_angle_end < ext->bg_angle_start) bg_end = ext->bg_angle_end + 360; + if(ext->bg_angle_end < ext->bg_angle_start) bg_end = ext->bg_angle_end + 360; switch(ext->type) { case LV_ARC_TYPE_SYMMETRIC: @@ -396,7 +401,7 @@ void lv_arc_set_value(lv_obj_t * arc, int16_t value) ext->cur_value = new_value; int16_t bg_midpoint, range_midpoint, bg_end = ext->bg_angle_end; - if (ext->bg_angle_end < ext->bg_angle_start) bg_end = ext->bg_angle_end + 360; + if(ext->bg_angle_end < ext->bg_angle_start) bg_end = ext->bg_angle_end + 360; int16_t angle; switch(ext->type) { @@ -404,11 +409,12 @@ void lv_arc_set_value(lv_obj_t * arc, int16_t value) bg_midpoint = (ext->bg_angle_start + bg_end) / 2; range_midpoint = (int32_t)(ext->min_value + ext->max_value) / 2; - if (ext->cur_value < range_midpoint) { + if(ext->cur_value < range_midpoint) { angle = _lv_map(ext->cur_value, ext->min_value, range_midpoint, ext->bg_angle_start, bg_midpoint); lv_arc_set_start_angle(arc, angle); lv_arc_set_end_angle(arc, bg_midpoint); - } else { + } + else { angle = _lv_map(ext->cur_value, range_midpoint, ext->max_value, bg_midpoint, bg_end); lv_arc_set_start_angle(arc, bg_midpoint); lv_arc_set_end_angle(arc, angle); @@ -420,6 +426,7 @@ void lv_arc_set_value(lv_obj_t * arc, int16_t value) break; default: /** LV_ARC_TYPE_NORMAL*/ angle = _lv_map(ext->cur_value, ext->min_value, ext->max_value, ext->bg_angle_start, bg_end); + lv_arc_set_start_angle(arc, ext->bg_angle_start); lv_arc_set_end_angle(arc, angle); } ext->last_angle = angle; /*Cache angle for slew rate limiting*/ @@ -433,7 +440,7 @@ void lv_arc_set_value(lv_obj_t * arc, int16_t value) */ void lv_arc_set_range(lv_obj_t * arc, int16_t min, int16_t max) { - LV_ASSERT_OBJ(arc, LV_OBJX_NAME); + LV_ASSERT_OBJ(arc, LV_OBJX_NAME); lv_arc_ext_t * ext = (lv_arc_ext_t *)lv_obj_get_ext_attr(arc); if(ext->min_value == min && ext->max_value == max) return; @@ -448,7 +455,7 @@ void lv_arc_set_range(lv_obj_t * arc, int16_t min, int16_t max) ext->cur_value = max; } - lv_arc_set_value(arc, ext->cur_value); + value_update(arc); /* value has changed relative to the new range */ } /** @@ -461,10 +468,28 @@ void lv_arc_set_chg_rate(lv_obj_t * arc, uint16_t rate) { LV_ASSERT_OBJ(arc, LV_OBJX_NAME); - lv_arc_ext_t *ext = (lv_arc_ext_t *)lv_obj_get_ext_attr(arc); + lv_arc_ext_t * ext = (lv_arc_ext_t *)lv_obj_get_ext_attr(arc); ext->chg_rate = rate; } +/** + * Set whether the arc is adjustable. + * @param arc pointer to a arc object + * @param adjustable whether the arc has a knob that can be dragged + */ +void lv_arc_set_adjustable(lv_obj_t * arc, bool adjustable) +{ + LV_ASSERT_OBJ(arc, LV_OBJX_NAME); + + lv_arc_ext_t *ext = (lv_arc_ext_t *)lv_obj_get_ext_attr(arc); + if(ext->adjustable == adjustable) + return; + + ext->adjustable = adjustable; + if(!adjustable) + ext->dragging = false; + lv_obj_invalidate(arc); +} /*===================== * Getter functions @@ -549,7 +574,7 @@ int16_t lv_arc_get_min_value(const lv_obj_t * arc) { LV_ASSERT_OBJ(arc, LV_OBJX_NAME); - lv_arc_ext_t *ext = (lv_arc_ext_t *)lv_obj_get_ext_attr(arc); + lv_arc_ext_t * ext = (lv_arc_ext_t *)lv_obj_get_ext_attr(arc); return ext->min_value; } @@ -562,7 +587,7 @@ int16_t lv_arc_get_max_value(const lv_obj_t * arc) { LV_ASSERT_OBJ(arc, LV_OBJX_NAME); - lv_arc_ext_t *ext = (lv_arc_ext_t *)lv_obj_get_ext_attr(arc); + lv_arc_ext_t * ext = (lv_arc_ext_t *)lv_obj_get_ext_attr(arc); return ext->max_value; } @@ -592,6 +617,19 @@ lv_arc_type_t lv_arc_get_type(const lv_obj_t * arc) return ext->type; } +/** + * Get whether the arc is adjustable. + * @param arc pointer to a arc object + * @return whether the arc has a knob that can be dragged + */ +bool lv_arc_get_adjustable(lv_obj_t * arc) +{ + LV_ASSERT_OBJ(arc, LV_OBJX_NAME); + + lv_arc_ext_t *ext = (lv_arc_ext_t *)lv_obj_get_ext_attr(arc); + return ext->adjustable; +} + /*===================== * Other functions *====================*/ @@ -640,7 +678,8 @@ static lv_design_res_t lv_arc_design(lv_obj_t * arc, const lv_area_t * clip_area lv_draw_line_dsc_init(&arc_dsc); lv_obj_init_draw_line_dsc(arc, LV_ARC_PART_BG, &arc_dsc); - lv_draw_arc(center.x, center.y, arc_r, ext->bg_angle_start + ext->rotation_angle, ext->bg_angle_end + ext->rotation_angle, clip_area, + lv_draw_arc(center.x, center.y, arc_r, ext->bg_angle_start + ext->rotation_angle, + ext->bg_angle_end + ext->rotation_angle, clip_area, &arc_dsc); } @@ -656,18 +695,21 @@ static lv_design_res_t lv_arc_design(lv_obj_t * arc, const lv_area_t * clip_area lv_draw_line_dsc_init(&arc_dsc); lv_obj_init_draw_line_dsc(arc, LV_ARC_PART_INDIC, &arc_dsc); - lv_draw_arc(center.x, center.y, indic_r, ext->arc_angle_start + ext->rotation_angle, ext->arc_angle_end + ext->rotation_angle, clip_area, + lv_draw_arc(center.x, center.y, indic_r, ext->arc_angle_start + ext->rotation_angle, + ext->arc_angle_end + ext->rotation_angle, clip_area, &arc_dsc); } - lv_area_t knob_area; - get_knob_area(arc, ¢er, arc_r, &knob_area); + if(ext->adjustable) { + lv_area_t knob_area; + get_knob_area(arc, ¢er, arc_r, &knob_area); - lv_draw_rect_dsc_t knob_rect_dsc; - lv_draw_rect_dsc_init(&knob_rect_dsc); - lv_obj_init_draw_rect_dsc(arc, LV_ARC_PART_KNOB, &knob_rect_dsc); + lv_draw_rect_dsc_t knob_rect_dsc; + lv_draw_rect_dsc_init(&knob_rect_dsc); + lv_obj_init_draw_rect_dsc(arc, LV_ARC_PART_KNOB, &knob_rect_dsc); - lv_draw_rect(&knob_area, clip_area, &knob_rect_dsc); + lv_draw_rect(&knob_area, clip_area, &knob_rect_dsc); + } } /*Post draw when the children are drawn*/ @@ -703,6 +745,9 @@ static lv_res_t lv_arc_signal(lv_obj_t * arc, lv_signal_t sign, void * param) lv_arc_ext_t * ext = lv_obj_get_ext_attr(arc); if(sign == LV_SIGNAL_PRESSING) { + /* Only adjustable arcs can be dragged */ + if(!ext->adjustable) return res; + lv_indev_t * indev = lv_indev_get_act(); if(indev == NULL) return res; @@ -738,7 +783,7 @@ static lv_res_t lv_arc_signal(lv_obj_t * arc, lv_signal_t sign, void * param) /*Calculate the angle of the pressed point*/ int16_t angle; int16_t bg_end = ext->bg_angle_end; - if (ext->bg_angle_end < ext->bg_angle_start) { + if(ext->bg_angle_end < ext->bg_angle_start) { bg_end = ext->bg_angle_end + 360; } @@ -752,9 +797,10 @@ static lv_res_t lv_arc_signal(lv_obj_t * arc, lv_signal_t sign, void * param) uint32_t delta_tick = lv_tick_elaps(ext->last_tick); int16_t delta_angle_max = (ext->chg_rate * delta_tick) / 1000; - if (delta_angle > delta_angle_max) { + if(delta_angle > delta_angle_max) { delta_angle = delta_angle_max; - } else if (delta_angle < -delta_angle_max) { + } + else if(delta_angle < -delta_angle_max) { delta_angle = -delta_angle_max; } @@ -797,6 +843,8 @@ static lv_res_t lv_arc_signal(lv_obj_t * arc, lv_signal_t sign, void * param) } else if(sign == LV_SIGNAL_CONTROL) { + if(!ext->adjustable) return res; + char c = *((char *)param); int16_t old_value = ext->cur_value; @@ -807,7 +855,7 @@ static lv_res_t lv_arc_signal(lv_obj_t * arc, lv_signal_t sign, void * param) lv_arc_set_value(arc, lv_arc_get_value(arc) - 1); } - if (old_value != ext->cur_value) { + if(old_value != ext->cur_value) { res = lv_event_send(arc, LV_EVENT_VALUE_CHANGED, NULL); if(res != LV_RES_OK) return res; } @@ -1005,9 +1053,11 @@ static void get_knob_area(lv_obj_t * arc, const lv_point_t * center, lv_coord_t uint16_t angle = ext->rotation_angle; if(ext->type == LV_ARC_TYPE_NORMAL) { angle += ext->arc_angle_end; - } else if(ext->type == LV_ARC_TYPE_REVERSE) { + } + else if(ext->type == LV_ARC_TYPE_REVERSE) { angle += ext->arc_angle_start; - } else if(ext->type == LV_ARC_TYPE_SYMMETRIC) { + } + else if(ext->type == LV_ARC_TYPE_SYMMETRIC) { int32_t range_midpoint = (int32_t)(ext->min_value + ext->max_value) / 2; if(ext->cur_value < range_midpoint) angle += ext->arc_angle_start; else angle += ext->arc_angle_end; @@ -1026,4 +1076,42 @@ static void get_knob_area(lv_obj_t * arc, const lv_point_t * center, lv_coord_t knob_area->y2 = center->y + knob_y + bottom_knob + indic_width_half; } +/** + * Used internally to update arc angles after a value change + * @param arc pointer to a arc object + */ +static void value_update(lv_obj_t * arc) +{ + lv_arc_ext_t *ext = (lv_arc_ext_t *)lv_obj_get_ext_attr(arc); + + int16_t bg_midpoint, range_midpoint, bg_end = ext->bg_angle_end; + if (ext->bg_angle_end < ext->bg_angle_start) bg_end = ext->bg_angle_end + 360; + + int16_t angle; + switch(ext->type) { + case LV_ARC_TYPE_SYMMETRIC: + bg_midpoint = (ext->bg_angle_start + bg_end) / 2; + range_midpoint = (int32_t)(ext->min_value + ext->max_value) / 2; + + if (ext->cur_value < range_midpoint) { + angle = _lv_map(ext->cur_value, ext->min_value, range_midpoint, ext->bg_angle_start, bg_midpoint); + lv_arc_set_start_angle(arc, angle); + lv_arc_set_end_angle(arc, bg_midpoint); + } else { + angle = _lv_map(ext->cur_value, range_midpoint, ext->max_value, bg_midpoint, bg_end); + lv_arc_set_start_angle(arc, bg_midpoint); + lv_arc_set_end_angle(arc, angle); + } + break; + case LV_ARC_TYPE_REVERSE: + angle = _lv_map(ext->cur_value, ext->min_value, ext->max_value, ext->bg_angle_start, bg_end); + lv_arc_set_start_angle(arc, angle); + break; + default: /** LV_ARC_TYPE_NORMAL*/ + angle = _lv_map(ext->cur_value, ext->min_value, ext->max_value, ext->bg_angle_start, bg_end); + lv_arc_set_end_angle(arc, angle); + } + ext->last_angle = angle; /*Cache angle for slew rate limiting*/ +} + #endif diff --git a/src/lv_widgets/lv_arc.h b/src/lv_widgets/lv_arc.h index 602527b2c..53c145c05 100644 --- a/src/lv_widgets/lv_arc.h +++ b/src/lv_widgets/lv_arc.h @@ -50,6 +50,7 @@ typedef struct { int16_t max_value; /*Maximum value of the arc*/ uint16_t dragging :1; uint16_t type :2; + uint16_t adjustable :1; uint16_t chg_rate; /*Drag angle rate of change of the arc (degrees/sec)*/ uint32_t last_tick; /*Last dragging event timestamp of the arc*/ int16_t last_angle; /*Last dragging angle of the arc*/ @@ -167,6 +168,13 @@ void lv_arc_set_range(lv_obj_t * arc, int16_t min, int16_t max); */ void lv_arc_set_chg_rate(lv_obj_t * arc, uint16_t threshold); +/** + * Set whether the arc is adjustable. + * @param arc pointer to a arc object + * @param adjustable whether the arc has a knob that can be dragged + */ +void lv_arc_set_adjustable(lv_obj_t * arc, bool adjustable); + /*===================== * Getter functions *====================*/ @@ -234,6 +242,13 @@ int16_t lv_arc_get_max_value(const lv_obj_t * arc); */ bool lv_arc_is_dragged(const lv_obj_t * arc); +/** + * Get whether the arc is adjustable. + * @param arc pointer to a arc object + * @return whether the arc has a knob that can be dragged + */ +bool lv_arc_get_adjustable(lv_obj_t * arc); + /*===================== * Other functions *====================*/ diff --git a/src/lv_widgets/lv_btnmatrix.c b/src/lv_widgets/lv_btnmatrix.c index 4acb82643..9f39dd638 100644 --- a/src/lv_widgets/lv_btnmatrix.c +++ b/src/lv_widgets/lv_btnmatrix.c @@ -905,11 +905,11 @@ static lv_res_t lv_btnmatrix_signal(lv_obj_t * btnm, lv_signal_t sign, void * pa if(btn_pr != LV_BTNMATRIX_BTN_NONE && button_is_inactive(ext->ctrl_bits[btn_pr]) == false && button_is_hidden(ext->ctrl_bits[btn_pr]) == false) { + invalidate_button_area(btnm, btn_pr); /* Send VALUE_CHANGED for the newly pressed button */ - uint32_t b = btn_pr; - res = lv_event_send(btnm, LV_EVENT_VALUE_CHANGED, &b); - if(res == LV_RES_OK) { - invalidate_button_area(btnm, btn_pr); + if(button_is_click_trig(ext->ctrl_bits[btn_pr]) == false) { + uint32_t b = btn_pr; + lv_event_send(btnm, LV_EVENT_VALUE_CHANGED, &b); } } } diff --git a/src/lv_widgets/lv_gauge.c b/src/lv_widgets/lv_gauge.c index f7f47dc40..97ccd54f3 100644 --- a/src/lv_widgets/lv_gauge.c +++ b/src/lv_widgets/lv_gauge.c @@ -619,7 +619,6 @@ static void lv_gauge_draw_needle(lv_obj_t * gauge, const lv_area_t * clip_area) lv_draw_img_dsc_t img_dsc; lv_draw_img_dsc_init(&img_dsc); lv_obj_init_draw_img_dsc(gauge, LV_GAUGE_PART_MAIN, &img_dsc); - img_dsc.recolor_opa = LV_OPA_COVER; img_dsc.pivot.x = ext->needle_img_pivot.x; img_dsc.pivot.y = ext->needle_img_pivot.y; diff --git a/src/lv_widgets/lv_img.c b/src/lv_widgets/lv_img.c index 19223bb56..d7fb1a85d 100644 --- a/src/lv_widgets/lv_img.c +++ b/src/lv_widgets/lv_img.c @@ -580,6 +580,9 @@ static lv_design_res_t lv_img_design(lv_obj_t * img, const lv_area_t * clip_area /*Non true color format might have "holes"*/ if(ext->cf != LV_IMG_CF_TRUE_COLOR && ext->cf != LV_IMG_CF_RAW) return LV_DESIGN_RES_NOT_COVER; + /*With not LV_OPA_COVER images acn't cover an area */ + if(lv_obj_get_style_image_opa(img, LV_IMG_PART_MAIN) != LV_OPA_COVER) return LV_DESIGN_RES_NOT_COVER; + int32_t angle_final = lv_obj_get_style_transform_angle(img, LV_IMG_PART_MAIN); angle_final += ext->angle; @@ -602,7 +605,10 @@ static lv_design_res_t lv_img_design(lv_obj_t * img, const lv_area_t * clip_area if(_lv_area_is_in(clip_area, &a, 0) == false) return LV_DESIGN_RES_NOT_COVER; } - if(lv_obj_get_style_image_opa(img, LV_IMG_PART_MAIN) != LV_OPA_COVER) return LV_DESIGN_RES_NOT_COVER; +#if LV_USE_BLEND_MODES + if(lv_obj_get_style_bg_blend_mode(img, LV_IMG_PART_MAIN) != LV_BLEND_MODE_NORMAL) return LV_DESIGN_RES_NOT_COVER; + if(lv_obj_get_style_image_blend_mode(img, LV_IMG_PART_MAIN) != LV_BLEND_MODE_NORMAL) return LV_DESIGN_RES_NOT_COVER; +#endif return LV_DESIGN_RES_COVER; } @@ -672,7 +678,9 @@ static lv_design_res_t lv_img_design(lv_obj_t * img, const lv_area_t * clip_area img_dsc.antialias = ext->antialias; lv_coord_t zoomed_src_w = (int32_t)((int32_t)ext->w * zoom_final) >> 8; + if(zoomed_src_w <= 0) return LV_DESIGN_RES_OK; lv_coord_t zoomed_src_h = (int32_t)((int32_t)ext->h * zoom_final) >> 8; + if(zoomed_src_h <= 0) return LV_DESIGN_RES_OK; lv_area_t zommed_coords; lv_obj_get_coords(img, &zommed_coords); @@ -685,7 +693,8 @@ static lv_design_res_t lv_img_design(lv_obj_t * img, const lv_area_t * clip_area if(zommed_coords.y1 > img->coords.y1) zommed_coords.y1 -= ext->h; lv_area_t clip_real; - _lv_img_buf_get_transformed_area(&clip_real, lv_obj_get_width(img), lv_obj_get_height(img), angle_final, zoom_final, &ext->pivot); + _lv_img_buf_get_transformed_area(&clip_real, lv_obj_get_width(img), lv_obj_get_height(img), angle_final, zoom_final, + &ext->pivot); clip_real.x1 += img->coords.x1; clip_real.x2 += img->coords.x1; clip_real.y1 += img->coords.y1; @@ -697,10 +706,10 @@ static lv_design_res_t lv_img_design(lv_obj_t * img, const lv_area_t * clip_area coords_tmp.y1 = zommed_coords.y1; coords_tmp.y2 = zommed_coords.y1 + ext->h - 1; - for(; coords_tmp.y1 <= zommed_coords.y2; coords_tmp.y1 += zoomed_src_h, coords_tmp.y2 += zoomed_src_h) { + for(; coords_tmp.y1 < zommed_coords.y2; coords_tmp.y1 += zoomed_src_h, coords_tmp.y2 += zoomed_src_h) { coords_tmp.x1 = zommed_coords.x1; coords_tmp.x2 = zommed_coords.x1 + ext->w - 1; - for(; coords_tmp.x1 <= zommed_coords.x2; coords_tmp.x1 += zoomed_src_w, coords_tmp.x2 += zoomed_src_w) { + for(; coords_tmp.x1 < zommed_coords.x2; coords_tmp.x1 += zoomed_src_w, coords_tmp.x2 += zoomed_src_w) { lv_draw_img(&coords_tmp, &clip_real, ext->src, &img_dsc); } } diff --git a/src/lv_widgets/lv_keyboard.c b/src/lv_widgets/lv_keyboard.c index fc41ee1ba..9138b171e 100644 --- a/src/lv_widgets/lv_keyboard.c +++ b/src/lv_widgets/lv_keyboard.c @@ -60,7 +60,7 @@ static const lv_btnmatrix_ctrl_t default_kb_ctrl_uc_map[] = { LV_KEYBOARD_CTRL_BTN_FLAGS | 2, 2, 6, 2, LV_KEYBOARD_CTRL_BTN_FLAGS | 2 }; -static const char * const default_kb_map_spec[] = {"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", LV_SYMBOL_BACKSPACE, "\n", +static const char * const default_kb_map_spec[] = {"1", "2", "3", "4", "5", "6", "7", "8", "9", "0", LV_SYMBOL_BACKSPACE, "\n", "abc", "+", "-", "/", "*", "=", "%", "!", "?", "#", "<", ">", "\n", "\\", "@", "$", "(", ")", "{", "}", "[", "]", ";", "\"", "'", "\n", LV_SYMBOL_CLOSE, LV_SYMBOL_LEFT, " ", LV_SYMBOL_RIGHT, LV_SYMBOL_OK, "" diff --git a/src/lv_widgets/lv_roller.c b/src/lv_widgets/lv_roller.c index 8b6818edc..b412470b4 100644 --- a/src/lv_widgets/lv_roller.c +++ b/src/lv_widgets/lv_roller.c @@ -585,10 +585,8 @@ static lv_res_t lv_roller_signal(lv_obj_t * roller, lv_signal_t sign, void * par /* Include the ancient signal function */ if(sign != LV_SIGNAL_CONTROL) { /*Don't let the page to scroll on keys*/ -#if LV_USE_GROUP res = ancestor_signal(roller, sign, param); if(res != LV_RES_OK) return res; -#endif } if(sign == LV_SIGNAL_GET_TYPE) return lv_obj_handle_get_type_signal(param, LV_OBJX_NAME); @@ -966,6 +964,18 @@ static void refr_width(lv_obj_t * roller) lv_style_int_t left = lv_obj_get_style_pad_left(roller, LV_ROLLER_PART_BG); lv_style_int_t right = lv_obj_get_style_pad_right(roller, LV_ROLLER_PART_BG); + const lv_font_t * base_font = lv_obj_get_style_text_font(roller, LV_ROLLER_PART_BG); + const lv_font_t * sel_font = lv_obj_get_style_text_font(roller, LV_ROLLER_PART_SELECTED); + + /*The selected text might be larger to get its size*/ + if(base_font != sel_font) { + lv_coord_t letter_sp = lv_obj_get_style_text_letter_space(roller, LV_ROLLER_PART_SELECTED); + lv_coord_t line_sp = lv_obj_get_style_text_line_space(roller, LV_ROLLER_PART_SELECTED); + lv_point_t p; + _lv_txt_get_size(&p, lv_label_get_text(label), sel_font, letter_sp, line_sp, LV_COORD_MAX, LV_TXT_FLAG_NONE); + if(label_w < p.x)label_w = p.x; + } + lv_obj_set_width(roller, label_w + left + right); } diff --git a/src/lv_widgets/lv_spinbox.c b/src/lv_widgets/lv_spinbox.c index 1fac9de80..28f2de153 100644 --- a/src/lv_widgets/lv_spinbox.c +++ b/src/lv_widgets/lv_spinbox.c @@ -390,10 +390,8 @@ static lv_res_t lv_spinbox_signal(lv_obj_t * spinbox, lv_signal_t sign, void * p /* Include the ancient signal function */ if(sign != LV_SIGNAL_CONTROL) { -#if LV_USE_GROUP res = ancestor_signal(spinbox, sign, param); if(res != LV_RES_OK) return res; -#endif } if(sign == LV_SIGNAL_GET_TYPE) return lv_obj_handle_get_type_signal(param, LV_OBJX_NAME); diff --git a/tests/Makefile b/tests/Makefile index 429862de6..70a44c1a6 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -31,6 +31,7 @@ CSRCS += lv_test_core/lv_test_core.c CSRCS += lv_test_core/lv_test_obj.c CSRCS += lv_test_core/lv_test_style.c CSRCS += lv_test_core/lv_test_font_loader.c +CSRCS += lv_test_widgets/lv_test_label.c CSRCS += lv_test_fonts/font_1.c CSRCS += lv_test_fonts/font_2.c CSRCS += lv_test_fonts/font_3.c diff --git a/tests/build.py b/tests/build.py index f014027c7..96e5bb2b8 100755 --- a/tests/build.py +++ b/tests/build.py @@ -120,7 +120,6 @@ minimal_monochrome = { "LV_USE_PAGE":0, "LV_USE_SPINNER":0, "LV_USE_ROLLER":0, - "LV_USE_ROTARY":0, "LV_USE_SLIDER":0, "LV_USE_SPINBOX":0, "LV_USE_SWITCH":0, @@ -197,7 +196,6 @@ all_obj_minimal_features = { "LV_USE_PAGE":1, "LV_USE_SPINNER":0, #Disabled beacsue needs anim "LV_USE_ROLLER":1, - "LV_USE_ROTARY":1, "LV_USE_SLIDER":1, "LV_USE_SPINBOX":1, "LV_USE_SWITCH":1, @@ -276,7 +274,6 @@ all_obj_all_features = { "LV_USE_PAGE":1, "LV_USE_SPINNER":1, "LV_USE_ROLLER":1, - "LV_USE_ROTARY":1, "LV_USE_SLIDER":1, "LV_USE_SPINBOX":1, "LV_USE_SWITCH":1, @@ -294,8 +291,8 @@ advanced_features = { "LV_MEM_CUSTOM":1, "LV_HOR_RES_MAX":800, "LV_VER_RES_MAX":480, - "LV_COLOR_DEPTH":16, - "LV_COLOR_16_SWAP":1, + "LV_COLOR_DEPTH":32, + "LV_COLOR_16_SWAP":0, "LV_COLOR_SCREEN_TRANSP":1, "LV_USE_GROUP":1, "LV_USE_ANIMATION":1, @@ -305,9 +302,6 @@ advanced_features = { "LV_USE_IMG_TRANSFORM":1, "LV_USE_API_EXTENSION_V6":1, "LV_USE_USER_DATA":1, - "LV_USE_USER_DATA_FREE":1, - "LV_USER_DATA_FREE_INCLUDE":"\\\"\\\"", - "LV_USER_DATA_FREE": "\\\"free\\\"", "LV_IMG_CACHE_DEF_SIZE":32, "LV_USE_LOG":1, "LV_USE_THEME_MATERIAL":1, @@ -368,7 +362,6 @@ advanced_features = { "LV_USE_PAGE":1, "LV_USE_SPINNER":1, "LV_USE_ROLLER":1, - "LV_USE_ROTARY":1, "LV_USE_SLIDER":1, "LV_USE_SPINBOX":1, "LV_USE_SWITCH":1, @@ -382,7 +375,8 @@ advanced_features = { build("Minimal monochrome", minimal_monochrome) build("All objects, minimal features", all_obj_minimal_features) -build("All objects, all features", all_obj_all_features) +build("All objects, all common features", all_obj_all_features) +build("All objects, with advanced features", advanced_features) diff --git a/tests/lv_test_assert.c b/tests/lv_test_assert.c index c4edc0d37..ce0d7a5ff 100644 --- a/tests/lv_test_assert.c +++ b/tests/lv_test_assert.c @@ -28,7 +28,8 @@ /********************* * DEFINES *********************/ -#define REF_IMGS_PATH "lvgl/tests/lv_test_ref_imgs/" +//#define REF_IMGS_PATH "lvgl/tests/lv_test_ref_imgs/" +#define REF_IMGS_PATH "lv_test_ref_imgs/" /********************** * TYPEDEFS @@ -177,6 +178,16 @@ void lv_test_assert_color_eq(lv_color_t c_ref, lv_color_t c_act, const char * s) void lv_test_assert_img_eq(const char * fn_ref, const char * s) { +#if LV_COLOR_DEPTH != 32 + lv_test_print(" SKIP: Can't compare '%s' because LV_COLOR_DEPTH != 32", fn_ref); + return; +#endif + +#if LV_HOR_RES_MAX != 800 || LV_VER_RES_MAX != 480 + lv_test_print(" SKIP: Can't compare '%s' because the resolution needs to be 800x480 (LV_HOR_RES_MAX, LV_VER_RES_MAX)", fn_ref); + return; +#endif + char fn_ref_full[512]; sprintf(fn_ref_full, "%s%s", REF_IMGS_PATH, fn_ref); @@ -185,16 +196,23 @@ void lv_test_assert_img_eq(const char * fn_ref, const char * s) uint8_t * screen_buf; lv_disp_t * disp = lv_disp_get_default(); + lv_obj_invalidate(lv_disp_get_scr_act(disp)); lv_refr_now(disp); - screen_buf = disp->driver.buffer->buf1; + + extern lv_color_t test_fb[]; + + screen_buf = (uint8_t *)test_fb; + + uint8_t * ptr_act = NULL; + const png_byte* ptr_ref = NULL; bool err = false; int x, y, i_buf = 0; for (y=0; yrow_pointers[y]); free(p->row_pointers); } -// + //static void process_file(png_img_t * p) //{ // if (png_get_color_type(p->png_ptr, p->info_ptr) == PNG_COLOR_TYPE_RGB) diff --git a/tests/lv_test_core/lv_test_font_loader.c b/tests/lv_test_core/lv_test_font_loader.c index ea0fc2753..3b3f6321a 100644 --- a/tests/lv_test_core/lv_test_font_loader.c +++ b/tests/lv_test_core/lv_test_font_loader.c @@ -7,12 +7,12 @@ * INCLUDES *********************/ -#include "../lv_test_assert.h" +#include "lvgl/lvgl.h" #if LV_BUILD_TEST -#include "../lvgl.h" -#include "../src/lv_font/lv_font_fmt_txt.h" -#include "../src/lv_font/lv_font.h" -#include "../src/lv_font/lv_font_loader.h" +#include "../lv_test_assert.h" +#include "lvgl/src/lv_font/lv_font_fmt_txt.h" +#include "lvgl/src/lv_font/lv_font.h" +#include "lvgl/src/lv_font/lv_font_loader.h" #include "lv_test_font_loader.h" @@ -28,7 +28,7 @@ * STATIC PROTOTYPES **********************/ -#if LV_USE_FILESYSTEM +#if LV_USE_FILESYSTEM && LV_FONT_FMT_TXT_LARGE == 0 static int compare_fonts(lv_font_t * f1, lv_font_t * f2); #endif @@ -50,7 +50,7 @@ extern lv_font_t font_3; void lv_test_font_loader(void) { -#if LV_USE_FILESYSTEM +#if LV_USE_FILESYSTEM && LV_FONT_FMT_TXT_LARGE == 0 lv_font_t * font_1_bin = lv_font_load("f:font_1.fnt"); lv_font_t * font_2_bin = lv_font_load("f:font_2.fnt"); lv_font_t * font_3_bin = lv_font_load("f:font_3.fnt"); @@ -62,10 +62,12 @@ void lv_test_font_loader(void) lv_font_free(font_1_bin); lv_font_free(font_2_bin); lv_font_free(font_3_bin); +#else + lv_test_print("SKIP: font load test because it requires LV_USE_FILESYSTEM 1 and LV_FONT_FMT_TXT_LARGE 0"); #endif } -#if LV_USE_FILESYSTEM +#if LV_USE_FILESYSTEM && LV_FONT_FMT_TXT_LARGE == 0 static int compare_fonts(lv_font_t * f1, lv_font_t * f2) { lv_test_assert_true(f1 != NULL && f2 != NULL, "font not null"); diff --git a/tests/lv_test_main.c b/tests/lv_test_main.c index 13d8f14eb..f1fd224cc 100644 --- a/tests/lv_test_main.c +++ b/tests/lv_test_main.c @@ -3,12 +3,15 @@ #include #include #include "lv_test_core/lv_test_core.h" +#include "lv_test_widgets/lv_test_label.h" #if LV_BUILD_TEST static void hal_init(void); static void dummy_flush_cb(lv_disp_drv_t * disp_drv, const lv_area_t * area, lv_color_t * color_p); +lv_color_t test_fb[LV_HOR_RES_MAX * LV_VER_RES_MAX]; + int main(void) { printf("Call lv_init...\n"); @@ -17,6 +20,7 @@ int main(void) hal_init(); lv_test_core(); + lv_test_label(); printf("Exit with success!\n"); return 0; @@ -85,7 +89,7 @@ static void hal_init(void) static lv_disp_buf_t disp_buf; lv_color_t * disp_buf1 = (lv_color_t *)malloc(LV_HOR_RES * LV_VER_RES * sizeof(lv_color_t)); - lv_disp_buf_init(&disp_buf, disp_buf1, NULL, LV_HOR_RES* LV_VER_RES); + lv_disp_buf_init(&disp_buf, disp_buf1, NULL, LV_HOR_RES * LV_VER_RES); lv_disp_drv_t disp_drv; lv_disp_drv_init(&disp_drv); @@ -109,11 +113,15 @@ static void hal_init(void) lv_fs_drv_register(&drv); /*Finally register the drive*/ #endif } +#include static void dummy_flush_cb(lv_disp_drv_t * disp_drv, const lv_area_t * area, lv_color_t * color_p) { LV_UNUSED(area); LV_UNUSED(color_p); + + memcpy(test_fb, color_p, lv_area_get_size(area) * sizeof(lv_color_t)); + lv_disp_flush_ready(disp_drv); } diff --git a/tests/lv_test_objx/lv_test_cont.c b/tests/lv_test_objx/lv_test_cont.c deleted file mode 100644 index 5afc75a67..000000000 --- a/tests/lv_test_objx/lv_test_cont.c +++ /dev/null @@ -1,80 +0,0 @@ -/** - * @file lv_test_cont.c - * - */ - -/********************* - * INCLUDES - *********************/ -#include "../../lvgl.h" -#include "../lv_test_assert.h" - -#if LV_BUILD_TEST - - -/********************* - * DEFINES - *********************/ - -/********************** - * TYPEDEFS - **********************/ - -/********************** - * STATIC PROTOTYPES - **********************/ -static void create_copy(void); - -/********************** - * STATIC VARIABLES - **********************/ - -/********************** - * MACROS - **********************/ - -/********************** - * GLOBAL FUNCTIONS - **********************/ - -void lv_test_cont(void) -{ - lv_test_print(""); - lv_test_print("==================="); - lv_test_print("Start lv_cont tests"); - lv_test_print("==================="); - - create_copy(); -} - - -/********************** - * STATIC FUNCTIONS - **********************/ - -static void create_copy(void) -{ - lv_test_print(""); - lv_test_print("Create and copy a container"); - lv_test_print("---------------------------"); - - lv_test_print("Create a container"); - lv_test_assert_int_eq(0, lv_obj_count_children(lv_scr_act()), "Screen's children count before creation"); - - lv_obj_t * obj = lv_cont_create(lv_scr_act(), NULL); - lv_test_assert_int_eq(1, lv_obj_count_children(lv_scr_act()), "Screen's children count after creation"); - - lv_test_print("Test the default values"); - lv_test_assert_int_eq(LV_FIT_NONE, lv_cont_get_fit_left(obj), "Default left fit"); - lv_test_assert_int_eq(LV_FIT_NONE, lv_cont_get_fit_right(obj), "Default right fit"); - lv_test_assert_int_eq(LV_FIT_NONE, lv_cont_get_fit_top(obj), "Default top fit"); - lv_test_assert_int_eq(LV_FIT_NONE, lv_cont_get_fit_bottom(obj), "Default bottom fit"); - lv_test_assert_int_eq(LV_LAYOUT_OFF, lv_cont_get_layout(obj), "Default layout"); - - lv_test_print("Delete the container"); - lv_obj_del(obj); - obj = NULL; - lv_test_assert_int_eq(0, lv_obj_count_children(lv_scr_act()), "Screen's children count after delete"); - -} -#endif diff --git a/tests/lv_test_ref_imgs/lv_test_img32_label_1.png b/tests/lv_test_ref_imgs/lv_test_img32_label_1.png new file mode 100644 index 000000000..29c84d082 Binary files /dev/null and b/tests/lv_test_ref_imgs/lv_test_img32_label_1.png differ diff --git a/tests/lv_test_ref_imgs/lv_test_obj_1_1.png b/tests/lv_test_ref_imgs/lv_test_obj_1_1.png deleted file mode 100644 index 40f187369..000000000 Binary files a/tests/lv_test_ref_imgs/lv_test_obj_1_1.png and /dev/null differ diff --git a/tests/lv_test_widgets/lv_test_label.c b/tests/lv_test_widgets/lv_test_label.c new file mode 100644 index 000000000..3d0435a2e --- /dev/null +++ b/tests/lv_test_widgets/lv_test_label.c @@ -0,0 +1,70 @@ +/** + * @file lv_test_label.c + * + */ + +/********************* + * INCLUDES + *********************/ +#include "../../lvgl.h" +#include "../lv_test_assert.h" +#include "lv_test_label.h" + +#if LV_BUILD_TEST + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * STATIC PROTOTYPES + **********************/ +static void create_copy(void); + +/********************** + * STATIC VARIABLES + **********************/ + +/********************** + * MACROS + **********************/ + +/********************** + * GLOBAL FUNCTIONS + **********************/ + +void lv_test_label(void) +{ + lv_test_print(""); + lv_test_print("==================="); + lv_test_print("Start lv_label tests"); + lv_test_print("==================="); + +#if LV_USE_LABEL + create_copy(); +#else + lv_test_print("Skip label test: LV_USE_LABEL == 0"); +#endif +} + + +/********************** + * STATIC FUNCTIONS + **********************/ + +static void create_copy(void) +{ + lv_test_print(""); + lv_test_print("Create a label"); + lv_test_print("---------------------------"); + + lv_label_create(lv_scr_act(), NULL); +#if LV_COLOR_DEPTH == 32 + lv_test_assert_img_eq("lv_test_img32_label_1.png", "Create a label and leave the default settings"); +#endif +} +#endif diff --git a/tests/lv_test_objx/lv_test_cont.h b/tests/lv_test_widgets/lv_test_label.h similarity index 82% rename from tests/lv_test_objx/lv_test_cont.h rename to tests/lv_test_widgets/lv_test_label.h index 08bbd8b59..36aac4e5e 100644 --- a/tests/lv_test_objx/lv_test_cont.h +++ b/tests/lv_test_widgets/lv_test_label.h @@ -1,10 +1,10 @@ /** - * @file lv_test_obj.h + * @file lv_test_label.h * */ -#ifndef LV_TEST_CONT_H -#define LV_TEST_CONT_H +#ifndef LV_TEST_LABEL_H +#define LV_TEST_LABEL_H #ifdef __cplusplus extern "C" { @@ -25,7 +25,7 @@ extern "C" { /********************** * GLOBAL PROTOTYPES **********************/ -void lv_test_cont(void); +void lv_test_label(void); /********************** * MACROS