跳到主要内容位置

UI系统

1.数据结构抽象#

抽象一个按钮数据结构,包括名称、区域、绘制函数、按压处理函数。

typedef struct Button
{
char *name;
Region tRegion;
int (*OnDraw)(struct Button *PButton, PDispBuff ptDispBuff); //绘制button
int (*OnPressed)(struct Button *PButton, PDispBuff ptDispBuff, PInputEvent ptInputEvent); //按压输入
} Button, *PButton;

定义函数指针后:

#define BUTTON_DEFAULT_COLOR 0xff0000
#define BUTTON_PRESSED_COLOR 0x00ff00
#define BUTTON_TEXT_COLOR 0x000000
/* 定义函数指针 */
typedef int (*ONDRAW_FUNC)(struct Button *PButton, PDispBuff ptDispBuff);
typedef int (*ONPRESSED_FUNC)(struct Button *PButton, PDispBuff ptDispBuff, PInputEvent ptInputEvent);
typedef struct Button
{
char *name;
Region tRegion;
ONDRAW_FUNC OnDraw; //绘制button
ONPRESSED_FUNC OnPressed; //按压输入
} Button, *PButton;

2.按键#

创建ui\button.c:编写上面三个函数

  • 初始化函数InitButton:初始化按键结构体

    void InitButton(char *name, PButton ptButton, PRegion ptRegion, ONDRAW_FUNC OnDraw,
    ONPRESSED_FUNC OnPressed)
    {
    ptButton->name = name;
    ptButton->status = 0;
    ptButton->tRegion = *ptRegion;
    ptButton->OnDraw = OnDraw ? OnDraw : DefaultOnDraw;
    ptButton->OnPressed = OnPressed ? OnPressed : DefaultOnPressed;
    }

    然后在没有提供绘制和按下处理函数的情况下,我们需要有默认的函数,DefaultOnDraw、 DefaultOnPressed

  • 绘制默认状态函数DefaultOnDraw

    static int DefaultOnDraw(struct Button *ptButton, PDispBuff ptDispBuff)
    {
    // 绘制底色
    DrawRegion(&ptButton->tRegion, BUTTON_DEFAULT_COLOR);
    // 居中文字
    DrawTextInRegionCentrl(ptButton->name, &ptButton->tRegion, BUTTON_TEXT_COLOR);
    // flush to lcd or web
    FlushDispalyRegion(&ptButton->tRegion, ptDispBuff);
    }

    相关函数在display/disp_manager.c中实现:

    • DrawRegion:绘制一个区域ptRegion成一种颜色dwColor

      void DrawRegion(PRegion ptRegion, unsigned int dwColor)
      {
      int x, y, width, heigh;
      int i, j;
      x = ptRegion->iLeftUpX;
      y = ptRegion->iLeftUpy;
      width = ptRegion->iWidth;
      heigh = ptRegion->iHight;
      for (j = y; j < y + heigh; j++)
      {
      for (i = x; i < x + width; i++)
      {
      PutPixel(i, j, dwColor);
      }
      }
      }
    • DrawTextInRegionCentrl :绘制居中文字

      计算文字原点(起笔点)、大小,设置大小,循环获取文字位图,绘制所有文字

      void DrawTextInRegionCentrl(char *name, PRegion ptRegion, unsigned int dwColor)
      {
      int n = strlen(name);
      int iFontSize = ptRegion->iWidth / n / 2;
      int iOriginX, iOriginY;
      int i = 0;
      FontBitMap tFontBitMap;
      if (iFontSize > ptRegion->iHight)
      {
      iFontSize = ptRegion->iHight
      }
      SetFontSize(iFontSize);
      iOriginX = (ptRegion->iWidth - n * iFontSize) / 2 + ptRegion->iLeftUpX;
      iOriginY = (ptRegion->iHight - iFontSize) / 2 + iFontSize + ptRegion->iLeftUpX;
      while (name[i])
      {
      tFontBitMap.iCurOriginX = iOriginX;
      tFontBitMap.iCurOriginY = iOriginY;
      err = GetFontBitMap(name[i], &tFontBitMap);
      if (err)
      {
      printf("%c GetFontBitMap err\n", str[i]);
      return -1;
      }
      /* 绘制位图 */
      DrawFontBitMap(&tFontBitMap, dwColor);
      /* 更新 */
      iOriginX = tFontBitMap.iNextOriginX;
      iOriginY = tFontBitMap.iNextOriginY;
      i++;
      }
      }
    • FlushDispalyRegion:刷新区域到lcd或web,之前已经实现

  • DefaultOnPressed:设置按键的状态翻转,修改底色

    static int DefaultOnPressed(struct Button *ptButton, PDispBuff ptDispBuff, PInputEvent ptInputEvent)
    {
    unsigned int dwColor = BUTTON_DEFAULT_COLOR;
    ptButton->status = !ptButton->status;
    if (1 == ptButton->status)
    {
    dwColor = BUTTON_PRESSED_COLOR;
    }
    //绘制底色
    DrawRegion(&ptButton->tRegion, dwColor);
    //居中写文字
    DrawTextInRegionCentrl(ptButton->name, &ptButton->tRegion, BUTTON_TEXT_COLOR);
    // flush to lcd or web
    FlushDispalyRegion(&ptButton->tRegion, ptDispBuff);
    }

3.测试#

(1)编译#

ui.hstruct Button需要先声明一下:

struct Button;
/* 定义函数指针 */
typedef int (*ONDRAW_FUNC)(struct Button *PButton, PDispBuff ptDispBuff);
typedef int (*ONPRESSED_FUNC)(struct Button *PButton, PDispBuff ptDispBuff, PInputEvent ptInputEvent);
typedef struct Button
{
char *name;
int status;
Region tRegion;
ONDRAW_FUNC OnDraw; //绘制button
ONPRESSED_FUNC OnPressed; //按压输入
} Button, *PButton;

请点击左侧菜单(移动端为右下角)选择要查看的所有笔记吧。