From 43a231cf5a748e5ff9d3e5f6dadedc946849747a Mon Sep 17 00:00:00 2001 From: Gabor Kiss-Vamosi Date: Wed, 15 Nov 2023 22:25:39 +0100 Subject: [PATCH] refactor(tabview): make it use with buttons instead of button matrix --- demos/stress/lv_demo_stress.c | 3 +- demos/widgets/lv_demo_widgets.c | 23 +- docs/ROADMAP.rst | 8 +- examples/widgets/slider/lv_example_slider_1.c | 1 + .../widgets/tabview/lv_example_tabview_1.c | 2 +- .../widgets/tabview/lv_example_tabview_2.c | 7 +- src/themes/default/lv_theme_default.c | 40 +-- src/widgets/tabview/lv_tabview.c | 270 ++++++++---------- src/widgets/tabview/lv_tabview.h | 21 +- tests/ref_imgs/widgets/tabview_05.png | Bin 4250 -> 4249 bytes tests/ref_imgs/widgets/tabview_06.png | Bin 12073 -> 12073 bytes tests/ref_imgs/widgets/tabview_07.png | Bin 5040 -> 5041 bytes tests/ref_imgs/widgets/tabview_08.png | Bin 3798 -> 3797 bytes tests/ref_imgs/widgets/tabview_09.png | Bin 5476 -> 5041 bytes tests/ref_imgs/widgets/tabview_10.png | Bin 2255 -> 2255 bytes tests/src/test_cases/widgets/test_tabview.c | 67 +++-- 16 files changed, 238 insertions(+), 204 deletions(-) diff --git a/demos/stress/lv_demo_stress.c b/demos/stress/lv_demo_stress.c index 470370035..cf699a36c 100644 --- a/demos/stress/lv_demo_stress.c +++ b/demos/stress/lv_demo_stress.c @@ -95,7 +95,8 @@ static void obj_test_task_cb(lv_timer_t * tmr) break; case 1: { - obj = lv_tabview_create(lv_screen_active(), LV_DIR_TOP, 50); + obj = lv_tabview_create(lv_screen_active()); + lv_tabview_set_tab_bar_size(obj, 50); lv_obj_set_size(obj, LV_HOR_RES / 2, LV_VER_RES / 2); lv_obj_align(obj, LV_ALIGN_BOTTOM_RIGHT, 0, 0); lv_obj_t * t = lv_tabview_add_tab(obj, "First"); diff --git a/demos/widgets/lv_demo_widgets.c b/demos/widgets/lv_demo_widgets.c index b2a9cdac0..808d34e27 100644 --- a/demos/widgets/lv_demo_widgets.c +++ b/demos/widgets/lv_demo_widgets.c @@ -177,33 +177,38 @@ void lv_demo_widgets(void) lv_style_set_border_width(&style_bullet, 0); lv_style_set_radius(&style_bullet, LV_RADIUS_CIRCLE); - tv = lv_tabview_create(lv_screen_active(), LV_DIR_TOP, tab_h); + tv = lv_tabview_create(lv_screen_active()); + lv_tabview_set_tab_bar_size(tv, tab_h); lv_obj_add_event(tv, tabview_delete_event_cb, LV_EVENT_DELETE, NULL); lv_obj_set_style_text_font(lv_screen_active(), font_normal, 0); + lv_obj_t * t1 = lv_tabview_add_tab(tv, "Profile"); + lv_obj_t * t2 = lv_tabview_add_tab(tv, "Analytics"); + lv_obj_t * t3 = lv_tabview_add_tab(tv, "Shop"); + if(disp_size == DISP_LARGE) { - lv_obj_t * tab_buttons = lv_tabview_get_tab_buttons(tv); - lv_obj_set_style_pad_left(tab_buttons, LV_HOR_RES / 2, 0); - lv_obj_t * logo = lv_image_create(tab_buttons); + lv_obj_t * tab_bar = lv_tabview_get_tab_bar(tv); + lv_obj_set_style_pad_left(tab_bar, LV_HOR_RES / 2, 0); + lv_obj_t * logo = lv_image_create(tab_bar); + lv_obj_add_flag(logo, LV_OBJ_FLAG_IGNORE_LAYOUT); LV_IMAGE_DECLARE(img_lvgl_logo); lv_image_set_src(logo, &img_lvgl_logo); lv_obj_align(logo, LV_ALIGN_LEFT_MID, -LV_HOR_RES / 2 + 25, 0); - lv_obj_t * label = lv_label_create(tab_buttons); + lv_obj_t * label = lv_label_create(tab_bar); lv_obj_add_style(label, &style_title, 0); + lv_obj_add_flag(label, LV_OBJ_FLAG_IGNORE_LAYOUT); lv_label_set_text_fmt(label, "LVGL v%d.%d.%d", lv_version_major(), lv_version_minor(), lv_version_patch()); lv_obj_align_to(label, logo, LV_ALIGN_OUT_RIGHT_TOP, 10, 0); - label = lv_label_create(tab_buttons); + label = lv_label_create(tab_bar); lv_label_set_text(label, "Widgets demo"); + lv_obj_add_flag(label, LV_OBJ_FLAG_IGNORE_LAYOUT); lv_obj_add_style(label, &style_text_muted, 0); lv_obj_align_to(label, logo, LV_ALIGN_OUT_RIGHT_BOTTOM, 10, 0); } - lv_obj_t * t1 = lv_tabview_add_tab(tv, "Profile"); - lv_obj_t * t2 = lv_tabview_add_tab(tv, "Analytics"); - lv_obj_t * t3 = lv_tabview_add_tab(tv, "Shop"); profile_create(t1); analytics_create(t2); shop_create(t3); diff --git a/docs/ROADMAP.rst b/docs/ROADMAP.rst index 7c1d50103..c92ba147d 100644 --- a/docs/ROADMAP.rst +++ b/docs/ROADMAP.rst @@ -52,12 +52,14 @@ Architecture - |check| Replace the `read_line_cb` of the image decoders with `get_area_cb` - |check| Limit the image caching size in bytes instead of image count - |check| lv_draw_buf for unified stride, buffer and cache invalidation management. `4241 `__ +- |check| Add vector graphics support via ThorVG - |uncheck| SVG support: integrate an SVG render library `4388 `__ - |check| Introduce optional ``float`` support. `4648 `__ - |uncheck| Introduce support layer for 3D GPUs (OpenGL, SDL, Vulkan, etc). `4622 `__ Styles ~~~~~~ + - |check| non-uniform scale of images: scale width and height differently - |uncheck| Scroll anim settings should come from styles to allow customization @@ -67,9 +69,7 @@ Widgets - |check| Universal scale widget/support - |check| `lv_img`: Reconsider image sizing models (when the image size is not content): center, top-left, zoom, tile, other? -- |uncheck| `lv_tabview` Replace button matrix with real buttons for more flexibility -- |uncheck| `lv_label` reconsider label long modes. (support min/max-width/height too) #3420 -- |uncheck| `lv_roller` make it more flexible #4009 +- |check| `lv_tabview` Replace button matrix with real buttons for more flexibility (see `here `__ and #4043) - |check| Disabled widgets should absorb indev actions without sending events. `#3860 `__ @@ -141,6 +141,8 @@ Widgets - |uncheck| `lv_bar`, `lv_arc`: handle max < min for fill direction swapping #4039 - |uncheck| `lv_bar`, `lv_slider`, `lv_arc`: make possible to move the knob only inside the background (see `here `__) - |uncheck| Improve `lv_label_align_t` #1656 +- |uncheck| `lv_label` reconsider label long modes. (support min/max-width/height too) #3420 +- |uncheck| `lv_roller` make it more flexible #4009 Others ~~~~~~ diff --git a/examples/widgets/slider/lv_example_slider_1.c b/examples/widgets/slider/lv_example_slider_1.c index 0c8acf6ec..bad320f0b 100644 --- a/examples/widgets/slider/lv_example_slider_1.c +++ b/examples/widgets/slider/lv_example_slider_1.c @@ -14,6 +14,7 @@ void lv_example_slider_1(void) lv_obj_center(slider); lv_obj_add_event(slider, slider_event_cb, LV_EVENT_VALUE_CHANGED, NULL); + lv_obj_set_style_anim_time(slider, 2000, 0); /*Create a label below the slider*/ slider_label = lv_label_create(lv_screen_active()); lv_label_set_text(slider_label, "0%"); diff --git a/examples/widgets/tabview/lv_example_tabview_1.c b/examples/widgets/tabview/lv_example_tabview_1.c index c37cb520a..fe84d71ea 100644 --- a/examples/widgets/tabview/lv_example_tabview_1.c +++ b/examples/widgets/tabview/lv_example_tabview_1.c @@ -5,7 +5,7 @@ void lv_example_tabview_1(void) { /*Create a Tab view object*/ lv_obj_t * tabview; - tabview = lv_tabview_create(lv_screen_active(), LV_DIR_TOP, 50); + tabview = lv_tabview_create(lv_screen_active()); /*Add 3 tabs (the tabs are page (lv_page) and can be scrolled*/ lv_obj_t * tab1 = lv_tabview_add_tab(tabview, "Tab 1"); diff --git a/examples/widgets/tabview/lv_example_tabview_2.c b/examples/widgets/tabview/lv_example_tabview_2.c index 346fc13a6..7585b3f31 100644 --- a/examples/widgets/tabview/lv_example_tabview_2.c +++ b/examples/widgets/tabview/lv_example_tabview_2.c @@ -1,15 +1,18 @@ #include "../../lv_examples.h" #if LV_USE_TABVIEW && LV_BUILD_EXAMPLES +/*A vertical tab view with disabled scrolling and some styling*/ void lv_example_tabview_2(void) { /*Create a Tab view object*/ lv_obj_t * tabview; - tabview = lv_tabview_create(lv_screen_active(), LV_DIR_LEFT, 80); + tabview = lv_tabview_create(lv_screen_active()); + lv_tabview_set_tab_position(tabview, LV_DIR_LEFT); + lv_tabview_set_tab_bar_size(tabview, 80); lv_obj_set_style_bg_color(tabview, lv_palette_lighten(LV_PALETTE_RED, 2), 0); - lv_obj_t * tab_buttons = lv_tabview_get_tab_buttons(tabview); + lv_obj_t * tab_buttons = lv_tabview_get_tab_bar(tabview); lv_obj_set_style_bg_color(tab_buttons, lv_palette_darken(LV_PALETTE_GREY, 3), 0); lv_obj_set_style_text_color(tab_buttons, lv_palette_lighten(LV_PALETTE_GREY, 5), 0); lv_obj_set_style_border_side(tab_buttons, LV_BORDER_SIDE_RIGHT, LV_PART_ITEMS | LV_STATE_CHECKED); diff --git a/src/themes/default/lv_theme_default.c b/src/themes/default/lv_theme_default.c index 51f44aaa0..ef496cde7 100644 --- a/src/themes/default/lv_theme_default.c +++ b/src/themes/default/lv_theme_default.c @@ -608,6 +608,7 @@ static void style_init(struct _my_theme_t * theme) lv_style_set_border_color(&theme->styles.tab_btn, theme->base.color_primary); lv_style_set_border_width(&theme->styles.tab_btn, BORDER_WIDTH * 2); lv_style_set_border_side(&theme->styles.tab_btn, LV_BORDER_SIDE_BOTTOM); + lv_style_set_pad_top(&theme->styles.tab_btn, BORDER_WIDTH * 2); style_init_reset(&theme->styles.tab_bg_focus); lv_style_set_outline_pad(&theme->styles.tab_bg_focus, -BORDER_WIDTH); @@ -758,11 +759,18 @@ static void theme_apply(lv_theme_t * th, lv_obj_t * obj) #if LV_USE_TABVIEW lv_obj_t * parent = lv_obj_get_parent(obj); /*Tabview content area*/ - if(lv_obj_check_type(parent, &lv_tabview_class)) { + if(parent && lv_obj_check_type(parent, &lv_tabview_class) && lv_obj_get_index(obj) == 1) { + return; + } + /*Tabview button container*/ + else if(lv_obj_check_type(parent, &lv_tabview_class) && lv_obj_get_index(obj) == 0) { + lv_obj_add_style(obj, &theme->styles.bg_color_white, 0); + lv_obj_add_style(obj, &theme->styles.outline_primary, LV_STATE_FOCUS_KEY); + lv_obj_add_style(obj, &theme->styles.tab_bg_focus, LV_STATE_FOCUS_KEY); return; } /*Tabview pages*/ - else if(lv_obj_check_type(lv_obj_get_parent(parent), &lv_tabview_class)) { + else if(parent && lv_obj_check_type(lv_obj_get_parent(parent), &lv_tabview_class)) { lv_obj_add_style(obj, &theme->styles.pad_normal, 0); lv_obj_add_style(obj, &theme->styles.scrollbar, LV_PART_SCROLLBAR); lv_obj_add_style(obj, &theme->styles.scrollbar_scrolled, LV_PART_SCROLLBAR | LV_STATE_SCROLLED); @@ -800,6 +808,20 @@ static void theme_apply(lv_theme_t * th, lv_obj_t * obj) } #if LV_USE_BTN else if(lv_obj_check_type(obj, &lv_button_class)) { + +#if LV_USE_TABVIEW + lv_obj_t * parent = lv_obj_get_parent(obj); + if(parent && lv_obj_check_type(lv_obj_get_parent(parent), &lv_tabview_class)) { + lv_obj_add_style(obj, &theme->styles.pressed, LV_STATE_PRESSED); + lv_obj_add_style(obj, &theme->styles.bg_color_primary_muted, LV_STATE_CHECKED); + lv_obj_add_style(obj, &theme->styles.tab_btn, LV_STATE_CHECKED); + lv_obj_add_style(obj, &theme->styles.outline_primary, LV_STATE_FOCUS_KEY); + lv_obj_add_style(obj, &theme->styles.outline_secondary, LV_STATE_EDITED); + lv_obj_add_style(obj, &theme->styles.tab_bg_focus, LV_STATE_FOCUS_KEY); + return; + } + +#endif lv_obj_add_style(obj, &theme->styles.btn, 0); lv_obj_add_style(obj, &theme->styles.bg_color_primary, 0); lv_obj_add_style(obj, &theme->styles.transition_delayed, 0); @@ -843,20 +865,6 @@ static void theme_apply(lv_theme_t * th, lv_obj_t * obj) return; } #endif -#if LV_USE_TABVIEW - if(lv_obj_check_type(lv_obj_get_parent(obj), &lv_tabview_class)) { - lv_obj_add_style(obj, &theme->styles.bg_color_white, 0); - lv_obj_add_style(obj, &theme->styles.outline_primary, LV_STATE_FOCUS_KEY); - lv_obj_add_style(obj, &theme->styles.tab_bg_focus, LV_STATE_FOCUS_KEY); - lv_obj_add_style(obj, &theme->styles.pressed, LV_PART_ITEMS | LV_STATE_PRESSED); - lv_obj_add_style(obj, &theme->styles.bg_color_primary_muted, LV_PART_ITEMS | LV_STATE_CHECKED); - lv_obj_add_style(obj, &theme->styles.tab_btn, LV_PART_ITEMS | LV_STATE_CHECKED); - lv_obj_add_style(obj, &theme->styles.outline_primary, LV_PART_ITEMS | LV_STATE_FOCUS_KEY); - lv_obj_add_style(obj, &theme->styles.outline_secondary, LV_PART_ITEMS | LV_STATE_EDITED); - lv_obj_add_style(obj, &theme->styles.tab_bg_focus, LV_PART_ITEMS | LV_STATE_FOCUS_KEY); - return; - } -#endif #if LV_USE_CALENDAR if(lv_obj_check_type(lv_obj_get_parent(obj), &lv_calendar_class)) { diff --git a/src/widgets/tabview/lv_tabview.c b/src/widgets/tabview/lv_tabview.c index 829fde18e..b9d850147 100644 --- a/src/widgets/tabview/lv_tabview.c +++ b/src/widgets/tabview/lv_tabview.c @@ -25,9 +25,8 @@ * STATIC PROTOTYPES **********************/ static void lv_tabview_constructor(const lv_obj_class_t * class_p, lv_obj_t * obj); -static void lv_tabview_destructor(const lv_obj_class_t * class_p, lv_obj_t * obj); static void lv_tabview_event(const lv_obj_class_t * class_p, lv_event_t * e); -static void buttons_value_changed_event_cb(lv_event_t * e); +static void button_clicked_event_cb(lv_event_t * e); static void cont_scroll_end_event_cb(lv_event_t * e); /********************** @@ -35,7 +34,6 @@ static void cont_scroll_end_event_cb(lv_event_t * e); **********************/ const lv_obj_class_t lv_tabview_class = { .constructor_cb = lv_tabview_constructor, - .destructor_cb = lv_tabview_destructor, .event_cb = lv_tabview_event, .width_def = LV_PCT(100), .height_def = LV_PCT(100), @@ -49,9 +47,6 @@ typedef struct { int32_t tab_size; } lv_tabview_create_info_t; -// only used in lv_obj_class_create_obj, no affect multiple instances -static lv_tabview_create_info_t create_info; - /********************** * MACROS **********************/ @@ -60,11 +55,9 @@ static lv_tabview_create_info_t create_info; * GLOBAL FUNCTIONS **********************/ -lv_obj_t * lv_tabview_create(lv_obj_t * parent, lv_dir_t tab_pos, int32_t tab_size) +lv_obj_t * lv_tabview_create(lv_obj_t * parent) { LV_LOG_INFO("begin"); - create_info.tab_pos = tab_pos; - create_info.tab_size = tab_size; lv_obj_t * obj = lv_obj_class_create_obj(&lv_tabview_class, parent); lv_obj_class_init_obj(obj); @@ -74,138 +67,94 @@ lv_obj_t * lv_tabview_create(lv_obj_t * parent, lv_dir_t tab_pos, int32_t tab_si lv_obj_t * lv_tabview_add_tab(lv_obj_t * obj, const char * name) { LV_ASSERT_OBJ(obj, MY_CLASS); - lv_tabview_t * tabview = (lv_tabview_t *)obj; lv_obj_t * cont = lv_tabview_get_content(obj); lv_obj_t * page = lv_obj_create(cont); - lv_obj_set_size(page, LV_PCT(100), LV_PCT(100)); - uint32_t tab_id = lv_obj_get_child_cnt(cont); + lv_obj_set_size(page, lv_pct(100), lv_pct(100)); + uint32_t tab_idx = lv_obj_get_child_cnt(cont); - lv_obj_t * buttons = lv_tabview_get_tab_buttons(obj); + lv_obj_t * tab_bar = lv_tabview_get_tab_bar(obj); - char ** old_map = tabview->map; - char ** new_map; + lv_obj_t * button = lv_button_create(tab_bar); + lv_obj_set_flex_grow(button, 1); + lv_obj_set_size(button, lv_pct(100), lv_pct(100)); + lv_obj_add_event(button, button_clicked_event_cb, LV_EVENT_CLICKED, NULL); + lv_group_t * g = lv_group_get_default(); + if(g) lv_group_add_obj(g, button); - /*top or bottom dir*/ - if(tabview->tab_pos & LV_DIR_VER) { - new_map = lv_malloc((tab_id + 1) * sizeof(const char *)); - lv_memcpy(new_map, old_map, sizeof(const char *) * (tab_id - 1)); - new_map[tab_id - 1] = lv_strdup(name); - LV_ASSERT_MALLOC(new_map[tab_id - 1]); - new_map[tab_id] = (char *)""; - } - /*left or right dir*/ - else { - new_map = lv_malloc((tab_id * 2) * sizeof(const char *)); - lv_memcpy(new_map, old_map, sizeof(const char *) * (tab_id - 1) * 2); - if(tabview->tab_cnt == 0) { - new_map[0] = lv_strdup(name); - LV_ASSERT_MALLOC(new_map[0]); - new_map[1] = (char *)""; - } - else { - new_map[tab_id * 2 - 3] = (char *)"\n"; - new_map[tab_id * 2 - 2] = lv_strdup(name); - new_map[tab_id * 2 - 1] = (char *)""; - } - } - tabview->map = new_map; - lv_buttonmatrix_set_map(buttons, (const char **)new_map); - lv_free(old_map); + lv_obj_t * label = lv_label_create(button); + lv_label_set_text(label, name); + lv_obj_center(label); - lv_buttonmatrix_set_button_ctrl_all(buttons, LV_BUTTONMATRIX_CTRL_CHECKABLE | LV_BUTTONMATRIX_CTRL_CLICK_TRIG | - LV_BUTTONMATRIX_CTRL_NO_REPEAT); - - tabview->tab_cnt++; - if(tabview->tab_cnt == 1) { + if(tab_idx == 1) { lv_tabview_set_active(obj, 0, LV_ANIM_OFF); } - lv_buttonmatrix_set_button_ctrl(buttons, tabview->tab_cur, LV_BUTTONMATRIX_CTRL_CHECKED); - return page; } -void lv_tabview_rename_tab(lv_obj_t * obj, uint32_t id, const char * new_name) +void lv_tabview_rename_tab(lv_obj_t * obj, uint32_t idx, const char * new_name) { LV_ASSERT_OBJ(obj, MY_CLASS); - lv_tabview_t * tabview = (lv_tabview_t *)obj; - if(id >= tabview->tab_cnt) return; - if(tabview->tab_pos & LV_DIR_HOR) id *= 2; - - lv_free(tabview->map[id]); - tabview->map[id] = lv_strdup(new_name); - LV_ASSERT_MALLOC(tabview->map[id]); - lv_obj_invalidate(obj); + lv_obj_t * tab_bar = lv_tabview_get_tab_bar(obj); + lv_obj_t * button = lv_obj_get_child_by_type(tab_bar, idx, &lv_button_class); + lv_obj_t * label = lv_obj_get_child_by_type(button, 0, &lv_label_class); + lv_label_set_text(label, new_name); } -void lv_tabview_set_active(lv_obj_t * obj, uint32_t id, lv_anim_enable_t anim_en) +void lv_tabview_set_active(lv_obj_t * obj, uint32_t idx, lv_anim_enable_t anim_en) { LV_ASSERT_OBJ(obj, MY_CLASS); lv_tabview_t * tabview = (lv_tabview_t *)obj; - if(id >= tabview->tab_cnt) { - id = tabview->tab_cnt - 1; + lv_obj_t * cont = lv_tabview_get_content(obj); + lv_obj_t * tab_bar = lv_tabview_get_tab_bar(obj); + + uint32_t tab_cnt = lv_tabview_get_tab_count(obj); + if(idx >= tab_cnt) { + idx = tab_cnt - 1; } /*To be sure lv_obj_get_content_width will return valid value*/ lv_obj_update_layout(obj); - lv_obj_t * cont = lv_tabview_get_content(obj); if(cont == NULL) return; if((tabview->tab_pos & LV_DIR_VER) != 0) { int32_t gap = lv_obj_get_style_pad_column(cont, LV_PART_MAIN); int32_t w = lv_obj_get_content_width(cont); if(lv_obj_get_style_base_dir(obj, LV_PART_MAIN) != LV_BASE_DIR_RTL) { - lv_obj_scroll_to_x(cont, id * (gap + w), anim_en); + lv_obj_scroll_to_x(cont, idx * (gap + w), anim_en); } else { - int32_t id_rtl = -(int32_t)id; + int32_t id_rtl = -(int32_t)idx; lv_obj_scroll_to_x(cont, (gap + w) * id_rtl, anim_en); } } else { int32_t gap = lv_obj_get_style_pad_row(cont, LV_PART_MAIN); int32_t h = lv_obj_get_content_height(cont); - lv_obj_scroll_to_y(cont, id * (gap + h), anim_en); + lv_obj_scroll_to_y(cont, idx * (gap + h), anim_en); } - lv_obj_t * buttons = lv_tabview_get_tab_buttons(obj); - lv_buttonmatrix_set_button_ctrl(buttons, id, LV_BUTTONMATRIX_CTRL_CHECKED); - tabview->tab_cur = id; + uint32_t i = 0; + lv_obj_t * button = lv_obj_get_child_by_type(tab_bar, i, &lv_button_class); + while(button) { + lv_obj_set_state(button, LV_STATE_CHECKED, i == idx); + i++; + button = lv_obj_get_child_by_type(tab_bar, (int32_t)i, &lv_button_class); + } + + tabview->tab_cur = idx; } -uint32_t lv_tabview_get_tab_active(lv_obj_t * obj) +void lv_tabview_set_tab_position(lv_obj_t * obj, lv_dir_t dir) { LV_ASSERT_OBJ(obj, MY_CLASS); lv_tabview_t * tabview = (lv_tabview_t *)obj; - return tabview->tab_cur; -} -lv_obj_t * lv_tabview_get_content(lv_obj_t * tv) -{ - return lv_obj_get_child(tv, 1); -} - -lv_obj_t * lv_tabview_get_tab_buttons(lv_obj_t * tv) -{ - return lv_obj_get_child(tv, 0); -} - -/********************** - * STATIC FUNCTIONS - **********************/ - -static void lv_tabview_constructor(const lv_obj_class_t * class_p, lv_obj_t * obj) -{ - LV_UNUSED(class_p); - lv_tabview_t * tabview = (lv_tabview_t *)obj; - - tabview->tab_pos = create_info.tab_pos; - - switch(tabview->tab_pos) { + switch(dir) { case LV_DIR_TOP: lv_obj_set_flex_flow(obj, LV_FLEX_FLOW_COLUMN); break; @@ -220,75 +169,108 @@ static void lv_tabview_constructor(const lv_obj_class_t * class_p, lv_obj_t * ob break; } - lv_obj_set_size(obj, LV_PCT(100), LV_PCT(100)); + lv_obj_t * tab_bar = lv_tabview_get_tab_bar(obj); + lv_obj_t * cont = lv_tabview_get_content(obj); - lv_obj_t * btnm; - lv_obj_t * cont; - - btnm = lv_buttonmatrix_create(obj); - cont = lv_obj_create(obj); - - lv_buttonmatrix_set_one_checked(btnm, true); - tabview->map = lv_malloc(sizeof(const char *)); - tabview->map[0] = (char *)""; - lv_buttonmatrix_set_map(btnm, (const char **)tabview->map); - lv_obj_add_event(btnm, buttons_value_changed_event_cb, LV_EVENT_VALUE_CHANGED, NULL); - lv_obj_add_flag(btnm, LV_OBJ_FLAG_EVENT_BUBBLE); - - lv_obj_add_event(cont, cont_scroll_end_event_cb, LV_EVENT_ALL, NULL); - lv_obj_set_scrollbar_mode(cont, LV_SCROLLBAR_MODE_OFF); - - switch(tabview->tab_pos) { + switch(dir) { case LV_DIR_TOP: case LV_DIR_BOTTOM: - lv_obj_set_size(btnm, LV_PCT(100), create_info.tab_size); lv_obj_set_width(cont, LV_PCT(100)); lv_obj_set_flex_grow(cont, 1); + lv_obj_set_flex_flow(tab_bar, LV_FLEX_FLOW_ROW); + lv_obj_set_flex_flow(cont, LV_FLEX_FLOW_ROW); + lv_obj_set_scroll_snap_x(cont, LV_SCROLL_SNAP_CENTER); + lv_obj_set_scroll_snap_y(cont, LV_SCROLL_SNAP_NONE); break; case LV_DIR_LEFT: case LV_DIR_RIGHT: - lv_obj_set_size(btnm, create_info.tab_size, LV_PCT(100)); lv_obj_set_height(cont, LV_PCT(100)); lv_obj_set_flex_grow(cont, 1); + lv_obj_set_flex_flow(tab_bar, LV_FLEX_FLOW_COLUMN); + lv_obj_set_flex_flow(cont, LV_FLEX_FLOW_COLUMN); + lv_obj_set_scroll_snap_x(cont, LV_SCROLL_SNAP_NONE); + lv_obj_set_scroll_snap_y(cont, LV_SCROLL_SNAP_CENTER); break; } - lv_group_t * g = lv_group_get_default(); - if(g) lv_group_add_obj(g, btnm); + bool was_ver = tabview->tab_pos & LV_DIR_VER; + bool now_ver = dir & LV_DIR_VER; - if((tabview->tab_pos & LV_DIR_VER) != 0) { - lv_obj_set_flex_flow(cont, LV_FLEX_FLOW_ROW); - lv_obj_set_scroll_snap_x(cont, LV_SCROLL_SNAP_CENTER); + if(was_ver != now_ver) { + int32_t dpi = lv_display_get_dpi(lv_obj_get_disp(obj)); + if(now_ver) { + lv_obj_set_size(tab_bar, lv_pct(100), dpi / 2); + } + else { + lv_obj_set_size(tab_bar, dpi, lv_pct(100)); + } } - else { - lv_obj_set_flex_flow(cont, LV_FLEX_FLOW_COLUMN); - lv_obj_set_scroll_snap_y(cont, LV_SCROLL_SNAP_CENTER); - } - lv_obj_add_flag(cont, LV_OBJ_FLAG_SCROLL_ONE); - lv_obj_remove_flag(cont, LV_OBJ_FLAG_SCROLL_ON_FOCUS); + tabview->tab_pos = dir; } -static void lv_tabview_destructor(const lv_obj_class_t * class_p, lv_obj_t * obj) +void lv_tabview_set_tab_bar_size(lv_obj_t * obj, int32_t size) +{ + LV_ASSERT_OBJ(obj, MY_CLASS); + lv_tabview_t * tabview = (lv_tabview_t *)obj; + + lv_obj_t * tab_bar = lv_tabview_get_tab_bar(obj); + if(tabview->tab_pos & LV_DIR_VER) { + lv_obj_set_height(tab_bar, size); + } + else { + lv_obj_set_width(tab_bar, size); + } + +} + +uint32_t lv_tabview_get_tab_active(lv_obj_t * obj) +{ + LV_ASSERT_OBJ(obj, MY_CLASS); + lv_tabview_t * tabview = (lv_tabview_t *)obj; + return tabview->tab_cur; +} + +uint32_t lv_tabview_get_tab_count(lv_obj_t * obj) +{ + LV_ASSERT_OBJ(obj, MY_CLASS); + lv_obj_t * tab_bar = lv_tabview_get_tab_bar(obj); + return lv_obj_get_child_count_by_type(tab_bar, &lv_button_class); +} + +lv_obj_t * lv_tabview_get_content(lv_obj_t * tv) +{ + return lv_obj_get_child(tv, 1); +} + +lv_obj_t * lv_tabview_get_tab_bar(lv_obj_t * tv) +{ + return lv_obj_get_child(tv, 0); +} + +/********************** + * STATIC FUNCTIONS + **********************/ + +static void lv_tabview_constructor(const lv_obj_class_t * class_p, lv_obj_t * obj) { LV_UNUSED(class_p); lv_tabview_t * tabview = (lv_tabview_t *)obj; + tabview->tab_pos = LV_DIR_NONE; /*Invalid value to apply the default TOP direction correctly*/ - uint32_t i; - if(tabview->tab_pos & LV_DIR_VER) { - for(i = 0; i < tabview->tab_cnt; i++) { - lv_free(tabview->map[i]); - tabview->map[i] = NULL; - } - } - if(tabview->tab_pos & LV_DIR_HOR) { - for(i = 0; i < tabview->tab_cnt; i++) { - lv_free(tabview->map[i * 2]); - tabview->map[i * 2] = NULL; - } - } + lv_obj_set_size(obj, LV_PCT(100), LV_PCT(100)); - lv_free(tabview->map); - tabview->map = NULL; + lv_obj_t * cont; + + lv_obj_create(obj); + cont = lv_obj_create(obj); + lv_obj_set_flex_flow(cont, LV_FLEX_FLOW_ROW); + + lv_obj_add_event(cont, cont_scroll_end_event_cb, LV_EVENT_ALL, NULL); + lv_obj_set_scrollbar_mode(cont, LV_SCROLLBAR_MODE_OFF); + lv_tabview_set_tab_position(obj, LV_DIR_TOP); + + lv_obj_add_flag(cont, LV_OBJ_FLAG_SCROLL_ONE); + lv_obj_remove_flag(cont, LV_OBJ_FLAG_SCROLL_ON_FOCUS); } static void lv_tabview_event(const lv_obj_class_t * class_p, lv_event_t * e) @@ -305,13 +287,13 @@ static void lv_tabview_event(const lv_obj_class_t * class_p, lv_event_t * e) } } -static void buttons_value_changed_event_cb(lv_event_t * e) +static void button_clicked_event_cb(lv_event_t * e) { - lv_obj_t * buttons = lv_event_get_target(e); + lv_obj_t * button = lv_event_get_target(e); - lv_obj_t * tv = lv_obj_get_parent(buttons); - uint32_t id = lv_buttonmatrix_get_selected_button(buttons); - lv_tabview_set_active(tv, id, LV_ANIM_OFF); + lv_obj_t * tv = lv_obj_get_parent(lv_obj_get_parent(button)); + int32_t idx = lv_obj_get_index_by_type(button, &lv_button_class); + lv_tabview_set_active(tv, idx, LV_ANIM_OFF); } static void cont_scroll_end_event_cb(lv_event_t * e) diff --git a/src/widgets/tabview/lv_tabview.h b/src/widgets/tabview/lv_tabview.h index 3bfe738be..b04d441a2 100644 --- a/src/widgets/tabview/lv_tabview.h +++ b/src/widgets/tabview/lv_tabview.h @@ -27,8 +27,6 @@ extern "C" { typedef struct { lv_obj_t obj; - char ** map; - uint32_t tab_cnt; uint32_t tab_cur; lv_dir_t tab_pos; } lv_tabview_t; @@ -38,20 +36,29 @@ LV_ATTRIBUTE_EXTERN_DATA extern const lv_obj_class_t lv_tabview_class; /********************** * GLOBAL PROTOTYPES **********************/ -lv_obj_t * lv_tabview_create(lv_obj_t * parent, lv_dir_t tab_pos, int32_t tab_size); + +lv_obj_t * lv_tabview_create(lv_obj_t * parent); lv_obj_t * lv_tabview_add_tab(lv_obj_t * tv, const char * name); void lv_tabview_rename_tab(lv_obj_t * obj, uint32_t tab_id, const char * new_name); -lv_obj_t * lv_tabview_get_content(lv_obj_t * tv); - -lv_obj_t * lv_tabview_get_tab_buttons(lv_obj_t * tv); - void lv_tabview_set_active(lv_obj_t * obj, uint32_t id, lv_anim_enable_t anim_en); +void lv_tabview_set_tab_position(lv_obj_t * obj, lv_dir_t dir); + +void lv_tabview_set_tab_bar_size(lv_obj_t * obj, int32_t size); + +uint32_t lv_tabview_get_tab_count(lv_obj_t * tv); + uint32_t lv_tabview_get_tab_active(lv_obj_t * tv); +uint32_t lv_tabview_get_tab_count(lv_obj_t * tv); + +lv_obj_t * lv_tabview_get_content(lv_obj_t * tv); + +lv_obj_t * lv_tabview_get_tab_bar(lv_obj_t * tv); + /********************** * MACROS **********************/ diff --git a/tests/ref_imgs/widgets/tabview_05.png b/tests/ref_imgs/widgets/tabview_05.png index c04457a33a5aa2ef1be3423c65ccee0bf20343cd..81b1194cc19421f11a04ca886dd2a8a504020dde 100644 GIT binary patch delta 2189 zcmV;82y*wDA(Q4ICfAOz`^V%#Dy2w9h{Ezea0jw9&qjX%^tZAhGP=|6UO^zv zf}-7$8Wyb;(N*G)UYum2Iri+}pLfXy-f^k+YRUVrb#M@zR}+V$C&8?39MDE_8*dr=fW z`q}jjjsvi60t?t2Pd@tD&!3;p-~9NKTkS84qWF)Gu7CgNXV*XYP4S&=x1QL!<)vNQ zJ9m6>Kf^!%=O?XS+*rEa@x4cizuvX|kAC;|AS;JzeQ@LBPrv%p09cKCuz&~7>+jw8 zL3Qi+)7xI!wf)M%t-t^GFGA_!uWnuZ<;|CNZ6AMn+rtla9Q?OW-~aWEO`Iygs;poE z51f@ZPJcc8P%-}Y7Z>}!v+dTAKig3*Xg&Gpwgdn2+t=T_{mWoUU}#LEMF~M?>P9cpS=Cy^|wE~KK7I44}Mep@caIu z2t087U;-X2ojbOSKfUdhcdq~V=Qkexonqj-TYvoXFMdz(&;MY{!`q8j-ubkAOv8~s zT@mFm4FH?2#&K327s@- zOkkZjabj?Au&1Y|r>AFVXz1d_iyItpa&mI--o25zt$V2R=g&`1Pai#c^ytx})oS%C zn%>$+tW+wu9r~`;p4(S6a{yqaZ5tnAaBy&TcD7!x*X#A7C}w7VW`>7{j~qGjb^nWe zc6PQ_tM&KyZ{iUrCnx{kjt&5%bSy0`ZRGO@4jj02>C&lFr@Fhl+Z!)mzTDH(Q@%cN z;>7gy^!)sMwOVa78iRv_<@TYWp>l2Jt+(D+2gE8yg-TUgLaMJ;cR}7n{xI?CflNkgl$-FP~AZRvQ}| zYyYtV0BhKK=+L2ce|TYG;n1N&qobp@<-*RLJIfd2?aAMD*d04|?Af!YeVSLVUfsWc|L)zp-+%x8;o;#%qcJivvTN6_ zD_5>O|NQf7pYN)B43ya zb+uaEw{PFv++25ecXxMprBW%1qP<=+H#gU6wcdE+jdD$>+}><9+hKR_L*3&H*ZAO_ zc6D}ko<4oLd|j*6+H<(;ctmdY;RdyTwM8vdmrk)W_VxjG>5xR{@y+Q_~T{n6h$#GFmUYHvA({(J$v@l zYPErZf%dNZQeGnb@WT(=TgomhilVQtZ{?VO0|NuEz4qGrW)1+~DjN!{TCG+T#mvmi zT~nrX?b@}Cyy4WTQ{@6oH8g_TwQB48r|L9 zU!KyXOP3ZF7TRC7TCJ6PI`T6-; ztu`|=Gc`3eGBR>6!`5oGsi~WKX&X``I~h2JJiaI zD2H9g4A&U*%QiCkHJm9vT|DeEIUk#Kg)s zFD@?b+qbX$hD=XS&(6+{jg4(&&H(T&vC+Wl>gqau`gHlEgK`C>x3~BB@#AHGJ&cc! zmn$pfLlDNs#@df*SliycduL{54jw$%+1dH(tFLx-b+w0@nwskD?0n&c7w$1ozC6^* zz3ZFd+GBp%x+lMe-rnBw;^5-qVzpWw85t>OzV_U1+uPIAbNu-6iHV73vstZH%Mfh8 zxn8eVDwV^B50{T=SjQzu0Qhzb+URqz006j+|BDc_p$p>#vrr2{0v7ha<+CZ9I<#GX P00000NkvXXu0mjfxkS8@ delta 2188 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 WztAkx!4K*Zfl}8!SFC0g@_zu^z@|O` literal 12073 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 E0Vx5z*Z=?k diff --git a/tests/ref_imgs/widgets/tabview_07.png b/tests/ref_imgs/widgets/tabview_07.png index a3b4fa6ff09f5dd7d2e3a01c3140f8c29d922b9f..d5ba732971d6f4b594d205868f85a078469b4ef0 100644 GIT binary patch delta 2690 zcmW+&dsve99>=+IJ4@|0J!)k;&oNq-Zkd8N+{u|WXLd17@luviTH*}>QQsL$pEPkj zl+0{Uwlp+h=7ozF)NG|-<^@ba5U-_9#2X+8=eK?SSiLXB*V7rBdk(a$nun^N4rZ4C83Ars1|GXG5x~#ut`ri#e`a4D%gmOkv2O zOq1N{3j~{6cSUUh2^&o5(;R;Rm$1-rlax@%W^tE8OpE<{o%8K8=f>HJ7PYH+c^Eq; zT8_+I`7k&bx|(!)Cp?6nwf?a(@YpdH!N{DiWHOl*6&02A%mm%i6zz_o2%9z07wA}n zdfM2yhE}XgCMSQVp3k}|<09U?h!)x4R zt|QIkZxL_>G_COa?CDw4s*!2R!Y&thlfqp2de$asOtz*dHu~XfW=HU{EUnjf<(0XfTxzEQGRP{t13s+RCh-*G=$moGy24&W$Lu3 z)IZSDyd{+K?*A^|8*uu0Ov}1+tggGQtxc=dc2VJE>g9d8?$+{$S?v7< z0$p7IgQusI!mEGq+hAxadIjMv`jO68B%0PeWzNCQ?(2eaV20?%>%&t*8+Oau$mHbZ z)rHziufuAfNStmjm}72;%?>>r4-`rc@b29=9v)#a zx80Y|7F^Z|eXSF0T<0TNt|~%Y3}Z94ej66AMtbFHG6P!lY!?_OZs8RX^ZKr)si7nD z>xIr)!RE5e+1c66n>X|Md^&Nu^l1>Sk;CaVoatO!TN@b}0rM@LJ^I15WuP$#qMcPlrOpb@bS8*0Lwxi4LAnd1aayP-Y?)w7<>#%v~jZbQwfx(i4 zQZ`e!Szd%B*E2ISBmcp%W5=#Qmobi=Xe6W6+L`jV+8e;Z^eJ*jR{MfzWSrzTfSX-&!?1lR>^> z1rya@UGN9T6j3OR|G*~TTgbvkZm%@dWkY%3}&9UL4u(DmUnmUrj=olxQYHn{{I zlM;@>V2F*(hf0yB2&GH3YZN_SiVr(*-!_JDQL`}W9M1B|F%Ym=RcGh-!NI{nK|y%D zrXslP3b7^Jr;~ZMGLu9K3=FI$4~oUn#sYf>ho+{cYC#z6f(Jl+Z2UY_ZNHs)fnNlB=b@$Yd~bs@&8mo72Q+FXl0&ss%z zIT7CY0XhHcix~m<~(B9rFbLA@W z5=-61^H-RYCIZ^h9JSYAQ-o*&HcP%g@|1m9@hY_ zv$eG_+pXxx$f~C9LpyftaHEM`>}G>v*U#XDD=RA^izxjm$7^|xUHLuADykrZp_k2c z%f2p%`)j0uq*=Ie?HX|`*8+HB2x3K}M_2FO3;KCtVnTc<-qt3dufP9rny4XhD95B% z2wF?c+it|4%oV?Xe}3ny#l^*QXDg0?9MUX&OorvD&wqVWd$X5c(ueAw^b?7;fwlp+ zp2v|RM?kPZ6u}L+%PalElME&3Ti#o4;t=bHr-!|~yq34vz>>44p%r&a91b@{yjNRW zTPhV+R|*Xv%LE*WSB2XR&+mSmmzOu2!}eK^+Q;}!d9HXnBg^wR8ZD*!l1?&EKo&nF zQhPdZe=iHj3tk(AdOA=U5_0lnn99o1vd1UL0+#hF&t+Q)BZ{O|<^x8n;q~Cm?k~zB z(P$2IL+bJEw|(#5BYk{i3WWeT3uF$=A`l3EWK2&_gGW=0zHnSy^r z&7N{|E8n%|bpl~yL4#H45!mF?~A5{U$CNw;s`UUG`UCDG;&F%Bb~zUNV^s%3>569Zf5BgUR+y+n)zKh*|#bz>fQO-^b~0Ee zo}M8tb-{(~Yg~%caTwRPXO#rHoBOk=aBE$zrQPPbKdiQx*{nh18QsF2pYn2H04D-Y Le$P63;pYDVihjpb delta 2688 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 diff --git a/tests/ref_imgs/widgets/tabview_09.png b/tests/ref_imgs/widgets/tabview_09.png index 754f6303c403a1b190aac76671baee25cf77606b..d5ba732971d6f4b594d205868f85a078469b4ef0 100644 GIT binary patch literal 5041 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 R{1peB^EiK+_QmCI{tf?k;#L3v literal 5476 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 F1OTi55AFZ} delta 47 zcmX>vcwTUWIwR+{v}a$~7#dbrY;I(