回复:【ST学习小组】STM32自编GUI探讨小组
对这个有兴趣,但是手上的板子没有触屏回复:【ST学习小组】STM32自编GUI探讨小组
为了响应阿呆版主的号召,更新下进程哈,上次上传了内存管理的文件,今天我们就来具体的创建按钮,先发一个创建按钮的函数,这个函数是我自己写的哈,欢迎大家拍砖完善://按钮结构体
typedef struct BOTTON //
{
uint16_t x; //按钮左上X
uint16_t y; //按钮左上Y
uint8_t xsize; //按钮宽
uint8_t ysize; //按钮高
uint16_t TextColor; //按钮文字颜色
uint16_t TextBKColor; //按钮文字背景颜色
uint16_t PenColor; //按钮画笔色
uint16_t BrushColor; //按钮画刷色
uint16_t* BKBmp; //按钮位图背景
uint8_t TextAlign; //文本对齐方式
uint8_t* id; //按钮ID id作标识用,不显示 这个兼作Text用
// uint8_t* Text; //按钮文字 Text用于在按钮上显示文本(支持中英文混显) 这个暂时没启用
} Button;
//创建按钮
Button* BUTTON_Create(uint16_t x,uint16_t y,uint8_t xsize,uint8_t ysize,uint8_t * id/*,uint8_t * text*/)//创建按钮,参数:左上点X,左上点Y,宽,高,按钮ID
{
Button* btt;//按钮对象指针
uint16_t n=1;//id的字节数
uint8_t* ID;//ID指针
// uint8_t* TEXT;//Text指针
uint8_t* str;
//开辟内存
btt=(Button*)mem_malloc(sizeof(Button)); //动态申请内存 会初始化为0 返回值就是申请成功的内存首地址 注意free(btt);
//为各元素赋值
(btt->x)=x;
(btt->y)=y;
(btt->xsize)=xsize;
(btt->ysize)=ysize;
(btt->TextColor)=Black;
(btt->TextBKColor)=Grey;
(btt->PenColor)=Grey;
(btt->BrushColor)=Grey;
(btt->BKBmp)=NULL;
(btt->TextAlign)=Align_XCenter | Align_YCenter;
//=====================================================
//循环求出ID的字节数,以确定为id开辟多少字节内存
str=id;
do
{
n++;//ID的字节数加1
str++;//ID的地址加1
}
while(*str!=0);
//为id另外开辟内存 期内存起始地址为ID
ID=(uint8_t*)mem_malloc(sizeof(uint8_t)*n); //动态申请内存 会初始化为0 注意将id free(id) 释放
if(ID==NULL)
{
GUI_Text(0,100,"calloc err!",Red,Black);
return NULL;
}
else
{
str=ID;
do
{
*str=*id;
str++;
id++;
}
while(*id!=0);
str++;
*str=0;
//将新开辟的内存首地址保存到Button->id中
(btt->id)=ID;
}
/*
//================================================================
//循环求出TEXT的字节数,以确定为Text开辟多少字节内存 TEXT
n=1;
str=text;
do
{
n++;//ID的字节数加1
str++;//ID的地址加1
}
while(*str!=0);
//为id另外开辟内存 期内存起始地址为ID
TEXT=(uint8_t*)calloc(n,sizeof(uint8_t)); //动态申请内存 会初始化为0 注意将Text free(Text) 释放
if(TEXT==NULL)
{
GUI_Text(0,0,"calloc err!",Red,Black);
return NULL;
}
else
{
str=TEXT;
do
{
*str=*text;
str++;
text++;
}
while(*text!=0);
str++;
*str=0;
//将新开辟的内存首地址保存到Button->Text中
(btt->Text)=TEXT;
}
*/
return btt;//返回创建的按钮指针
}
这个函数的参数含义上面都列出来了,注意,按钮ID其实就是显示在按钮上面的文字!
回复:【ST学习小组】STM32自编GUI探讨小组
创建了按钮当然还要显示出来,怎么办呢,调用下面这个函数,按钮就能在指定的位置显示出来://显示按钮
void BUTTON_Show(Button* bt)//显示按钮
{
if(bt->BKBmp)
LCD_DrawBMP(bt->x, bt->y,bt->xsize,bt->ysize,bt->BKBmp);
else
LCD_FillRect(bt->x, bt->y, bt->xsize, bt->ysize,bt->PenColor,bt->BrushColor);//画填充矩形,参数:左上点X坐标,左上点Y坐标,宽,高,画笔色,画刷色
DispStringInRect(bt->x, bt->y, bt->xsize, bt->ysize,(bt->id),bt->TextColor,bt->TextBKColor,bt->TextAlign); //在矩形中显示字符串 (不显示矩形) 参数:左上X,左上Y,宽,高,字符串,前景色,背景色,对齐方式(可或运算)
}
回复:【ST学习小组】STM32自编GUI探讨小组
按钮是用来触控的,光创建、显示出来有什么用,当然关键得知道点中的是哪个按钮,这就得判断点中的点是在按钮内,你调用如下这个函数就OK了:////点在按钮内
uint8_t TP_PointInButton(Button* btt,uint16_t x,uint16_t y)//点在按钮内 参数:按钮指针,点X坐标,点Y坐标 返回值为1:点在按钮内; 0:点不在按钮内
{
if((x>=(btt->x)) && xx)+(btt->xsize)) && (y>=btt->y) && (yy)+(btt->ysize))))
{
return 1;
}
else
return 0;
}
注意哈,这个函数返回1,表示点中了此按钮,返回0表示没有点中此按钮,循环查询创建的所有按钮就知道点中了哪个按钮了不。
回复:【ST学习小组】STM32自编GUI探讨小组
最后总结陈词,学到这里,一个简单但功能完备的GUI其实就已经完成了,由于相机坏了,我暂时就没拍图了,如有需要,等相机修好后补个图。其实大家仔细看看就会发现,这个GUI是支持图片按钮的,也就是说像智能机上那种漂亮的图片按钮,你用这个GUI也能做出来,而且效果超好。由于创建按钮使用了动态内存管理,因此你可以创建无数版面的N多个按钮,只要一页显示的按钮数不要太多,总数随便多少都没有关系,不会消耗完你的系统资源的。
当然,你有可能想动态的改变某个按钮的文字或图片,这一切也能轻松做的,有基础的人应该一看就知道如何实现。
再次说明下,这个GUI是很简单的,但功能是完备的,效果是值得肯定的,性能是可靠的。祝大家学习愉快!有问题继续讨论!
RE:【ST学习小组】STM32自编GUI探讨小组
啊,这个找了好久,楼上的资料丰富、详实,申请加入,共同学习!:lolRE:【ST学习小组】STM32自编GUI探讨小组
欢迎5186加入学习哈,来的正是时候啊;PRE:【ST学习小组】STM32自编GUI探讨小组
说明一下,本GUI是本人原创的,记得刚学GUI的时候,看了下其它的商业GUI,发现像天书一样的,不是入门者一下子能看懂的。于是想干脆自己写个得了,估计看懂别人的和自己搞个的时间、精力也差不多,于是乎就搞了这个。我发布这个学习计划的目的也是希望大家能多动动脑筋,多些原创的东西,毕竟自己的才是最好的,以后系统维护起来也方便些。
如果大家有更好的思路,恳请承上来,大家分享。
RE:【ST学习小组】STM32自编GUI探讨小组
请问如下这个函数具体是如何实现的DispStringInRect(bt->x, bt->y, bt->xsize, bt->ysize,(bt->id),bt->TextColor,bt->TextBKColor,bt->TextAlign); //在矩形中显示字符串 (不显示矩形) 参数:左上X,左上Y,宽,高,字符串,前景色,背景色,对齐方式(可或运算)
RE:【ST学习小组】STM32自编GUI探讨小组
回答楼上的提问,这个函数的实现有点长,我把代码贴出来参考//在矩形中显示字字符串
//void DispStringInRect(uint8_t *str, struct Rect* pRect, uint8_t TextAlign,uint16_t Color, uint16_t bkColor)//在矩形中显示字符 参数:混合字符串,矩形,对齐方式(可以或运算)
void DispStringInRect(uint16_t x, uint16_t y, uint16_t xsize, uint16_t ysize,uint8_t *str,uint16_t Color,uint16_t bkColor, uint8_t TextAlign)//在矩形中显示字符串 参数:左上X,左上Y,宽,高,字符串,前景色,背景色,对齐方式(可或运算)
{
uint8_t*OldStr; //字符串起始地址
uint16_t ZF_Num; //字符串字节数
uint16_t ZF_Num_Rem;//剩余字节数
uint16_t OneLine_ZJ_Num;//每行能显示的字节数
uint16_t FirstLine_ZJ_Num;//第一行能显示的字节数
uint16_t ZF_Line_Num; //字符行数
uint16_t Rect_X_Left; //矩形左
uint16_t Rect_X_Right;//矩形右
uint16_t Rect_Y_Top;//矩形上
// uint16_t Rect_Y_Bottom;//矩形下
uint16_t Xpos;//字符显示X位置
uint16_t Ypos;//字符显示Y位置
OldStr=str; //将起始址保存
ZF_Num=0;//字节数初始化为0
ZF_Line_Num=1;//字符行数初始为1
FirstLine_ZJ_Num=0;//第一行能显示的字节数初始化0
OneLine_ZJ_Num=xsize/8;
Rect_X_Left=x; //矩形左
Rect_X_Right=x+xsize; //矩形右
Rect_Y_Top=y; //矩形上
// Rect_Y_Bottom=y+ysize); //矩形下
Xpos=Rect_X_Left;
Ypos=Rect_Y_Top;
//第一步:模拟显示一次统计字符总字节数及总行数 ++++++++++++++++++++++++++++++++++++
do //模拟显示一次统计字符总字节数及总行数 FirstLine_ZJ_Num
{
if(((signed char)(*str))>=0) //如果是英文字符
{
ZF_Num++;//字节数加1
str++;
if (Xpos