refactor(tabview): make it use with buttons instead of button matrix

This commit is contained in:
Gabor Kiss-Vamosi
2023-11-15 22:25:39 +01:00
parent d90363a8e9
commit 43a231cf5a
16 changed files with 238 additions and 204 deletions

View File

@@ -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");

View File

@@ -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);

View File

@@ -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 <https://github.com/lvgl/lvgl/pull/4241>`__
- |check| Add vector graphics support via ThorVG
- |uncheck| SVG support: integrate an SVG render library `4388 <https://github.com/lvgl/lvgl/issues/4388>`__
- |check| Introduce optional ``float`` support. `4648 <https://github.com/lvgl/lvgl/issues/4648>`__
- |uncheck| Introduce support layer for 3D GPUs (OpenGL, SDL, Vulkan, etc). `4622 <https://github.com/lvgl/lvgl/issues/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 <https://forum.lvgl.io/t/linear-meter-bar-with-ticks/10986>`__ and #4043)
- |check| Disabled widgets should absorb indev actions without sending events. `#3860 <https://github.com/lvgl/lvgl/issues/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 <https://forum.lvgl.io/t/slider-knob-out-of-the-track/11956>`__)
- |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
~~~~~~

View File

@@ -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%");

View File

@@ -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");

View File

@@ -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);

View File

@@ -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)) {

View File

@@ -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);
}
uint32_t lv_tabview_get_tab_active(lv_obj_t * obj)
tabview->tab_cur = idx;
}
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_flex_flow(cont, LV_FLEX_FLOW_COLUMN);
lv_obj_set_scroll_snap_y(cont, LV_SCROLL_SNAP_CENTER);
lv_obj_set_size(tab_bar, dpi, lv_pct(100));
}
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)

View File

@@ -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
**********************/

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.2 KiB

After

Width:  |  Height:  |  Size: 4.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.9 KiB

After

Width:  |  Height:  |  Size: 4.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.7 KiB

After

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.3 KiB

After

Width:  |  Height:  |  Size: 4.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.2 KiB

After

Width:  |  Height:  |  Size: 2.2 KiB

View File

@@ -1,4 +1,4 @@
#if LV_BUILD_TEST
#if LV_BUILD_TEST || 1
#include "../lvgl.h"
#include "unity/unity.h"
@@ -18,7 +18,7 @@ void test_tabview_add_several_tabs_no_scroll(void);
void test_tabview_rename_tab(void);
void test_tabview_add_several_tabs_hor(void);
void test_tabview_get_content(void);
void test_tabview_get_tab_buttons(void);
void test_tabview_get_tab_bar(void);
void test_tabview_set_act_non_existent(void);
void test_tabview_tab2_selected_event(void);
void test_tabview_update_on_external_scroll(void);
@@ -38,7 +38,8 @@ void tearDown(void)
void test_tabview_create_successful_dir_top(void)
{
tabview = lv_tabview_create(active_screen, LV_DIR_TOP, 50);
tabview = lv_tabview_create(active_screen);
lv_tabview_set_tab_bar_size(tabview, 50);
TEST_ASSERT_NOT_NULL(tabview);
@@ -47,7 +48,9 @@ void test_tabview_create_successful_dir_top(void)
void test_tabview_create_successful_dir_bottom(void)
{
tabview = lv_tabview_create(active_screen, LV_DIR_BOTTOM, 50);
tabview = lv_tabview_create(active_screen);
lv_tabview_set_tab_position(tabview, LV_DIR_BOTTOM);
lv_tabview_set_tab_bar_size(tabview, 50);
TEST_ASSERT_NOT_NULL(tabview);
@@ -56,7 +59,9 @@ void test_tabview_create_successful_dir_bottom(void)
void test_tabview_create_successful_dir_left(void)
{
tabview = lv_tabview_create(active_screen, LV_DIR_LEFT, 50);
tabview = lv_tabview_create(active_screen);
lv_tabview_set_tab_position(tabview, LV_DIR_LEFT);
lv_tabview_set_tab_bar_size(tabview, 50);
TEST_ASSERT_NOT_NULL(tabview);
@@ -65,7 +70,9 @@ void test_tabview_create_successful_dir_left(void)
void test_tabview_create_successful_dir_right(void)
{
tabview = lv_tabview_create(active_screen, LV_DIR_RIGHT, 50);
tabview = lv_tabview_create(active_screen);
lv_tabview_set_tab_position(tabview, LV_DIR_RIGHT);
lv_tabview_set_tab_bar_size(tabview, 50);
TEST_ASSERT_NOT_NULL(tabview);
@@ -74,7 +81,9 @@ void test_tabview_create_successful_dir_right(void)
void test_tabview_add_one_tab_empty(void)
{
tabview = lv_tabview_create(active_screen, LV_DIR_TOP, 50);
tabview = lv_tabview_create(active_screen);
lv_tabview_set_tab_position(tabview, LV_DIR_TOP);
lv_tabview_set_tab_bar_size(tabview, 50);
lv_obj_t * tab1 = lv_tabview_add_tab(tabview, "Tab 1");
@@ -83,7 +92,9 @@ void test_tabview_add_one_tab_empty(void)
void test_tabview_add_one_tab_empty_hor(void)
{
tabview = lv_tabview_create(active_screen, LV_DIR_LEFT, 50);
tabview = lv_tabview_create(active_screen);
lv_tabview_set_tab_position(tabview, LV_DIR_LEFT);
lv_tabview_set_tab_bar_size(tabview, 50);
lv_obj_t * tab1 = lv_tabview_add_tab(tabview, "Tab 1");
@@ -92,7 +103,9 @@ void test_tabview_add_one_tab_empty_hor(void)
void test_tabview_add_one_tab_no_scroll(void)
{
tabview = lv_tabview_create(active_screen, LV_DIR_TOP, 50);
tabview = lv_tabview_create(active_screen);
lv_tabview_set_tab_position(tabview, LV_DIR_TOP);
lv_tabview_set_tab_bar_size(tabview, 50);
lv_obj_t * tab1 = lv_tabview_add_tab(tabview, "Tab 1");
@@ -105,7 +118,9 @@ void test_tabview_add_one_tab_no_scroll(void)
void test_tabview_add_one_tab_with_scroll(void)
{
tabview = lv_tabview_create(active_screen, LV_DIR_TOP, 50);
tabview = lv_tabview_create(active_screen);
lv_tabview_set_tab_position(tabview, LV_DIR_TOP);
lv_tabview_set_tab_bar_size(tabview, 50);
lv_obj_t * tab1 = lv_tabview_add_tab(tabview, "Tab 1");
@@ -131,7 +146,9 @@ void test_tabview_add_one_tab_with_scroll(void)
void test_tabview_add_several_tabs_no_scroll(void)
{
tabview = lv_tabview_create(active_screen, LV_DIR_TOP, 50);
tabview = lv_tabview_create(active_screen);
lv_tabview_set_tab_position(tabview, LV_DIR_TOP);
lv_tabview_set_tab_bar_size(tabview, 50);
lv_obj_t * tab1 = lv_tabview_add_tab(tabview, "Tab 1");
lv_obj_t * tab2 = lv_tabview_add_tab(tabview, "Tab 2");
@@ -149,7 +166,9 @@ void test_tabview_add_several_tabs_no_scroll(void)
void test_tabview_rename_tab(void)
{
tabview = lv_tabview_create(active_screen, LV_DIR_TOP, 50);
tabview = lv_tabview_create(active_screen);
lv_tabview_set_tab_position(tabview, LV_DIR_TOP);
lv_tabview_set_tab_bar_size(tabview, 50);
lv_obj_t * tab1 = lv_tabview_add_tab(tabview, "Tab 1");
lv_obj_t * tab2 = lv_tabview_add_tab(tabview, "Tab 2");
@@ -168,7 +187,9 @@ void test_tabview_rename_tab(void)
void test_tabview_add_several_tabs_hor(void)
{
tabview = lv_tabview_create(active_screen, LV_DIR_LEFT, 50);
tabview = lv_tabview_create(active_screen);
lv_tabview_set_tab_position(tabview, LV_DIR_TOP);
lv_tabview_set_tab_bar_size(tabview, 50);
lv_obj_t * tab1 = lv_tabview_add_tab(tabview, "Tab 1");
lv_obj_t * tab2 = lv_tabview_add_tab(tabview, "Tab 2");
@@ -186,25 +207,25 @@ void test_tabview_add_several_tabs_hor(void)
void test_tabview_get_content(void)
{
tabview = lv_tabview_create(active_screen, LV_DIR_TOP, 50);
tabview = lv_tabview_create(active_screen);
lv_obj_t * content = lv_tabview_get_content(tabview);
TEST_ASSERT_NOT_NULL(content);
}
void test_tabview_get_tab_buttons(void)
void test_tabview_get_tab_bar(void)
{
tabview = lv_tabview_create(active_screen, LV_DIR_TOP, 50);
tabview = lv_tabview_create(active_screen);
lv_obj_t * buttons = lv_tabview_get_tab_buttons(tabview);
lv_obj_t * tab_bar = lv_tabview_get_tab_bar(tabview);
TEST_ASSERT_NOT_NULL(buttons);
TEST_ASSERT_NOT_NULL(tab_bar);
}
void test_tabview_set_act_non_existent(void)
{
tabview = lv_tabview_create(active_screen, LV_DIR_TOP, 50);
tabview = lv_tabview_create(active_screen);
lv_tabview_set_active(tabview, 1, LV_ANIM_ON);
@@ -213,7 +234,9 @@ void test_tabview_set_act_non_existent(void)
void test_tabview_tab2_selected_event(void)
{
tabview = lv_tabview_create(active_screen, LV_DIR_TOP, 50);
tabview = lv_tabview_create(active_screen);
lv_tabview_set_tab_position(tabview, LV_DIR_TOP);
lv_tabview_set_tab_bar_size(tabview, 50);
lv_obj_t * tab1 = lv_tabview_add_tab(tabview, "Tab 1");
lv_obj_t * tab2 = lv_tabview_add_tab(tabview, "Tab 2");
@@ -229,7 +252,9 @@ void test_tabview_tab2_selected_event(void)
void test_tabview_update_on_external_scroll(void)
{
tabview = lv_tabview_create(active_screen, LV_DIR_TOP, 50);
tabview = lv_tabview_create(active_screen);
lv_tabview_set_tab_position(tabview, LV_DIR_TOP);
lv_tabview_set_tab_bar_size(tabview, 50);
lv_obj_t * tab1 = lv_tabview_add_tab(tabview, "Tab 1");
lv_obj_t * tab2 = lv_tabview_add_tab(tabview, "Tab 2");