多分辨率 LCD 的 GUI 架构设计与实现
1.1多分辨率显示系统的挑战与解决方案
1.1.1 分辨率适配的核心问题
在嵌入式系统中,同时支持不同分辨率的 LCD(如 240×160、320×480 等)面临以下挑战:
布局适配:同一界面元素在不同分辨率下需要调整大小和位置
字体显示:小分辨率屏幕需要更小的字体,而大分辨率需要更清晰的字体
内存占用:高分辨率屏幕需要更多显存,而低分辨率需要优化内存使用
渲染性能:高分辨率屏幕渲染压力更大,需要优化渲染算法
针对这些问题, 采用以下解决方案:
抽象显示接口:定义统一的显示操作接口,屏蔽底层硬件差异
相对布局系统:使用百分比或相对单位定义界面元素位置和大小
字体动态缩放:根据屏幕分辨率动态调整字体大小
资源按需加载:根据当前屏幕分辨率选择合适的图片和字体资源
1.1.2 单色屏与彩屏的兼容性设计
同时支持单色屏和彩屏时,需要解决以下问题:
颜色表示:单色屏只有黑白两色,而彩屏支持多种颜色
图形渲染:彩屏支持渐变、阴影等复杂效果,单色屏需要简化
交互反馈:彩屏可通过颜色变化提供反馈,单色屏需依赖对比度或闪烁
解决方案包括:
颜色抽象层:定义颜色映射表,将 RGB 颜色映射到单色屏的黑白值
渲染策略分离:为单色屏和彩屏分别实现不同的渲染算法
交互反馈统一:使用统一的交互反馈接口,底层根据屏幕类型实现
1.2 统一显示抽象层设计
1.2.1 显示接口定义
我们首先定义一个抽象的显示接口,屏蔽不同分辨率和类型的 LCD 差异:
c
/**
* 显示抽象层接口定义
* 支持不同分辨率和类型的LCD
*/
#ifndef DISPLAY_ABSTRACTION_H
#define DISPLAY_ABSTRACTION_H
#include <stdint.h>
#include <stdbool.h>
/* 颜色定义 - 采用RGB565格式 */
typedef uint16_t color_t;
/* 标准颜色常量 */
#define COLOR_BLACK 0x0000
#define COLOR_WHITE 0xFFFF
#define COLOR_RED 0xF800
#define COLOR_GREEN 0x07E0
#define COLOR_BLUE 0x001F
#define COLOR_YELLOW 0xFFE0
#define COLOR_CYAN 0x07FF
#define COLOR_MAGENTA 0xF81F
/* 显示区域结构体 */
typedef struct
{
uint16_t x;
uint16_t y;
uint16_t width;
uint16_t height;
} rect_t;
/* 显示设备能力结构体 */
typedef struct
{
uint16_t width; /* 屏幕宽度 */
uint16_t height; /* 屏幕高度 */
uint8_t bits_per_pixel; /* 每像素位数 */
bool color_support; /* 是否支持彩色 */
uint16_t max_font_size; /* 最大支持字体大小 */
uint16_t min_font_size; /* 最小支持字体大小 */
} display_capabilities_t;
/* 显示接口函数指针结构体 */
typedef struct
{
/* 基本操作 */
void (*init)(void);
void (*clear)(color_t color);
void (*refresh)(void);
/* 绘制基本图形 */
void (*draw_pixel)(uint16_t x, uint16_t y, color_t color);
void (*draw_line)(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, color_t color);
void (*draw_rect)(uint16_t x, uint16_t y, uint16_t width, uint16_t height, color_t color);
void (*fill_rect)(uint16_t x, uint16_t y, uint16_t width, uint16_t height, color_t color);
void (*draw_circle)(uint16_t x, uint16_t y, uint16_t radius, color_t color);
void (*fill_circle)(uint16_t x, uint16_t y, uint16_t radius, color_t color);
/* 文本绘制 */
void (*set_font_size)(uint8_t size);
void (*set_text_color)(color_t color, color_t background);
void (*draw_char)(uint16_t x, uint16_t y, char c);
void (*draw_string)(uint16_t x, uint16_t y, const char* str);
/* 图像绘制 */
void (*draw_image)(uint16_t x, uint16_t y, uint16_t width, uint16_t height, const uint16_t* data);
/* 获取显示能力 */
void (*get_capabilities)(display_capabilities_t* caps);
} display_interface_t;
/* 获取当前显示接口实例 */
display_interface_t* get_display_interface(void);
/* 设置当前显示接口实例 */
void set_display_interface(display_interface_t* display);
#endif /* DISPLAY_ABSTRACTION_H */
1.2.2 显示接口实现
下面是显示接口的基础实现,提供了统一的操作入口:
/**
* 显示抽象层实现
*/
#include "display_abstraction.h"
/* 当前显示接口实例 */
static display_interface_t* current_display = NULL;
/* 获取当前显示接口实例 */
display_interface_t* get_display_interface(void)
{
return current_display;
}
/* 设置当前显示接口实例 */
void set_display_interface(display_interface_t* display)
{
current_display = display;
}
/* 通用绘制函数 - 使用当前显示接口 */
void display_clear(color_t color)
{
if (current_display && current_display->clear)
{
current_display->clear(color);
}
}
void display_refresh(void)
{
if (current_display && current_display->refresh)
{
current_display->refresh();
}
}
void display_draw_pixel(uint16_t x, uint16_t y, color_t color)
{
if (current_display && current_display->draw_pixel)
{
current_display->draw_pixel(x, y, color);
}
}
// 其他通用绘制函数实现...
1.3 相对布局系统设计
1.3.1 布局管理器设计
为了实现跨分辨率的 GUI 适配,我们设计一个相对布局管理器:
/**
* 相对布局管理器
* 支持基于百分比的界面元素布局
*/
#ifndef LAYOUT_MANAGER_H
#define LAYOUT_MANAGER_H
#include "display_abstraction.h"
/* 对齐方式枚举 */
typedef enum
{
ALIGN_LEFT,
ALIGN_CENTER,
ALIGN_RIGHT,
ALIGN_TOP,
ALIGN_MIDDLE,
ALIGN_BOTTOM
} alignment_t;
/* 相对位置结构体 */
typedef struct
{
float x_percent; /* X坐标百分比 (0.0-1.0) */
float y_percent; /* Y坐标百分比 (0.0-1.0) */
float width_percent; /* 宽度百分比 (0.0-1.0) */
float height_percent; /* 高度百分比 (0.0-1.0) */
alignment_t h_align; /* 水平对齐方式 */
alignment_t v_align; /* 垂直对齐方式 */
} relative_position_t;
/* GUI元素基类 */
typedef struct gui_element
{
char* id; /* 元素ID */
relative_position_t position; /* 相对位置 */
bool visible; /* 是否可见 */
/* 绘制函数 */
void (*draw)(struct gui_element* element);
/* 事件处理函数 */
bool (*handle_event)(struct gui_element* element, void* event);
/* 布局计算函数 */
void (*calculate_layout)(struct gui_element* element, rect_t* parent_rect);
/* 实际屏幕位置 */
rect_t screen_rect;
/* 指向下一个元素的指针 */
struct gui_element* next;
} gui_element_t;
/* 布局管理器 */
typedef struct
{
gui_element_t* elements; /* 元素链表 */
display_interface_t* display; /* 显示接口 */
rect_t root_rect; /* 根区域 */
} layout_manager_t;
/* 初始化布局管理器 */
void layout_manager_init(layout_manager_t* manager, display_interface_t* display);
/* 添加GUI元素 */
void layout_manager_add_element(layout_manager_t* manager, gui_element_t* element);
/* 移除GUI元素 */
void layout_manager_remove_element(layout_manager_t* manager, gui_element_t*