199 lines
5.8 KiB
C
Raw Normal View History

2025-04-10 17:31:33 +08:00
/**
* @file desktop.c
*
*/
/*********************
* INCLUDES
*********************/
#include "lvgl.h"
#include "../ui_conf.h"
#include "page.h"
#include "desktop.h"
/*********************
* DEFINES
*********************/
/**********************
* TYPEDEFS
**********************/
typedef enum {
DISP_SMALL,
DISP_LARGE,
} disp_size_t;
/**********************
* STATIC PROTOTYPES
**********************/
static lv_obj_t* indicator_create(lv_obj_t* parent, uint32_t count, uint32_t home_index);
static void tab_changed_cb(lv_event_t* e);
/**********************
* STATIC VARIABLES
**********************/
/**********************
* MACROS
**********************/
/**********************
* GLOBAL FUNCTIONS
**********************/
lv_obj_t* ui_desktop_create(uint32_t frame_count, uint32_t home_index)
{
lv_obj_t* desktop;
lv_obj_t* tv;
lv_obj_t* indicator;
if (frame_count == 0) {
frame_count = 1;
}
if (frame_count > UI_DESKTOP_FRAME_COUNT_MAX) {
frame_count = UI_DESKTOP_FRAME_COUNT_MAX;
}
if (home_index >= frame_count) {
home_index = frame_count;
}
// desktop是一个page, 以page的content为parent创建一个tabview(tab按钮不显示), 以便使用tabview的左右滑动效果
// 再以tabview为parent创建一个indicator(页面指示器, 底部的几个小圆点)
desktop = ui_page_create(NULL, UI_PAGE_RETURN_DISABLE, UI_PAGE_CLOSE_DISABLE);
uint8_t i;
// tv必须为ui_page_content的第一个child
tv = lv_tabview_create(ui_page_get_content(desktop), LV_DIR_TOP, 0);
for (i = 0; i < frame_count; i++) {
char buf[10];
lv_snprintf(buf, 10, "tab%d", i);
lv_obj_t* t = lv_tabview_add_tab(tv, buf);
lv_obj_set_style_bg_opa(t, LV_OPA_100, 0);
}
lv_obj_set_user_data(desktop, (void*)home_index);
lv_tabview_set_act(tv, home_index, LV_ANIM_OFF);
// indicator必须为tv的最后一个child
indicator = indicator_create(tv, frame_count, home_index);
lv_obj_add_event_cb(tv, tab_changed_cb, LV_EVENT_VALUE_CHANGED, indicator);
return desktop;
}
// frame_custom_height: frame的用户可用高度. 由于frame底部有页面指示器, 因此可用高度需要减掉指示器高度
uint32_t ui_desktop_get_frame_custom_height(lv_obj_t* obj)
{
lv_obj_t* page_content = ui_page_get_content(obj);
lv_tabview_t* tv = (lv_tabview_t*)lv_obj_get_child(page_content, 0);
lv_obj_t* indicator = lv_obj_get_child(tv, -1);
return lv_obj_get_y(indicator);
}
lv_obj_t* ui_desktop_get_frame(lv_obj_t* obj, uint32_t frame_index)
{
lv_obj_t* page_content = ui_page_get_content(obj);
lv_tabview_t* tv = (lv_tabview_t*)lv_obj_get_child(page_content, 0);
lv_obj_t* content = lv_tabview_get_content(tv);
uint32_t count = lv_obj_get_child_cnt(content);
if (frame_index >= count) {
frame_index = count - 1;
}
return lv_obj_get_child(content, frame_index);
}
uint32_t ui_desktop_get_frame_count(lv_obj_t* obj)
{
lv_obj_t* page_content = ui_page_get_content(obj);
lv_tabview_t* tv = (lv_tabview_t*)lv_obj_get_child(page_content, 0);
lv_obj_t* content = lv_tabview_get_content(tv);
uint32_t count = lv_obj_get_child_cnt(content);
return count;
}
uint32_t ui_desktop_get_home_index(lv_obj_t* obj)
{
return lv_obj_get_user_data(obj);
}
/**********************
* STATIC FUNCTIONS
**********************/
static lv_obj_t* indicator_create(lv_obj_t* parent, uint32_t count, uint32_t home_index)
{
lv_obj_t* indicator = lv_obj_create(parent);
const lv_coord_t circle_d = 8; // 小圆点直径
const lv_coord_t circle_pad = 15; // 小圆点之间的间隔
const lv_coord_t h_pad = 4; // 上下间隔
lv_coord_t indicator_w;
lv_coord_t indicator_h;
lv_coord_t max_w = lv_obj_get_width(lv_obj_get_parent(indicator));
indicator_h = circle_d + h_pad * 2;
indicator_w = (count + 1) * circle_pad + count * circle_d; // count + 1: 圆点之间间隔+左右间隔
indicator_w = LV_MIN(indicator_w, max_w);
lv_obj_remove_style_all(indicator);
lv_obj_set_flex_flow(indicator, LV_FLEX_FLOW_ROW);
lv_obj_set_flex_align(indicator, LV_FLEX_ALIGN_SPACE_EVENLY, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER);
lv_obj_add_flag(indicator, LV_OBJ_FLAG_FLOATING);
lv_obj_set_style_bg_color(indicator, lv_color_white(), 0);
lv_obj_set_style_pad_right(indicator, 0, 0);
//lv_obj_set_style_bg_opa(indicator, LV_OPA_40, 0);
lv_obj_set_style_bg_opa(indicator, LV_OPA_0, 0);
lv_obj_set_style_radius(indicator, LV_RADIUS_CIRCLE, 0);
lv_obj_set_size(indicator, LV_DPX(indicator_w), LV_DPX(indicator_h));
lv_obj_align(indicator, LV_ALIGN_BOTTOM_MID, -LV_DPX(0), -LV_DPX(10));
uint8_t i;
for (i = 0; i < count; i++) {
lv_obj_t* c = lv_btn_create(indicator);
lv_obj_set_style_bg_color(c, lv_color_white(), 0);
lv_obj_set_style_radius(c, LV_RADIUS_CIRCLE, 0);
if (i == home_index) {
lv_obj_set_style_opa(c, LV_OPA_COVER, 0);
}
else {
lv_obj_set_style_opa(c, LV_OPA_60, 0);
}
lv_obj_set_size(c, LV_DPX(circle_d), LV_DPX(circle_d));
lv_obj_clear_flag(c, LV_OBJ_FLAG_SCROLL_ON_FOCUS);
}
return indicator;
}
static void tab_changed_cb(lv_event_t* e)
{
lv_obj_t* indicator = lv_event_get_user_data(e);
lv_obj_t* tv = lv_event_get_target(e);
uint32_t count = lv_obj_get_child_cnt(indicator);
uint32_t index = lv_tabview_get_tab_act(tv);
uint8_t i;
for (i = 0; i < count; i++) {
lv_obj_t* c = lv_obj_get_child(indicator, i);
if (i == index) {
lv_obj_set_style_opa(c, LV_OPA_COVER, 0);
}
else {
lv_obj_set_style_opa(c, LV_OPA_50, 0);
}
}
}