绘制电池图标
绘制电池图标

绘制电池图标

使用填充函数,在 LCD 上绘制电池图标。

首先先放一张效果图。

这个驱动可以绘制四种不同方向的电池图标,颜色、线宽可以自由配置,电量显示范围 0%~100%。

实现代码如下。

/*********************************************************************************************************
* 函数名称: GUIDrawBatIcon
* 函数功能: 绘制电池图标
* 输入参数: x,y     :整型变量。原点坐标。
*            width    :整型变量。宽度。
*            height   :整型变量。高度。
*            lineSize :整型变量。线条宽度。线条宽度为偶数的时候显示会异常???
*            edgeColor:整型变量。边沿线条颜色。
*            batColor :整型变量。剩余电量颜色。
*            direction:整型变量。电池方向。0-朝左,1-朝右,2-朝上,3-朝下。
*            remain   :整型变量。剩余电量,取值 0-100,表示 0-100% 电量
* 输出参数: void
* 返 回 值: void
* 创建日期: 2023年10月18日
* 注    意: 
*********************************************************************************************************/
void GUIDrawBatIcon(const unsigned int x, const unsigned int y, const unsigned int width, const unsigned int height,
  unsigned int lineSize, unsigned int edgeColor, unsigned int batColor, unsigned int direction, unsigned int remain)
{
  typedef struct
  {
    unsigned int x;
    unsigned int y;
  }StructBatCoord;
  StructBatCoord coord[8];
  unsigned int x0, y0, x1, y1, space, tWidth, tHeight, tx, ty;

  //参数校验
  if((0 == width) || (0 == height) || (0 == lineSize) || (direction > 3)) { return; }

  //电量超过 100,强制定义为 100
  if (remain > 100)
  {
    remain = 100;
  }

  /*
   *      1____________________2
   *   7__|                    |
   *   |  0                    |
   *   |__5                    |
   *   6  |____________________|
   *      4                    3
   *
   * 电池正极突起高度固定为整体高度的 10%
   * 电池正极直径为整个电池直径的 50%
   */
  if (0 == direction)
  {
    //求各个点之间的坐标
    space = width / 10;
    coord[0].x = x + space - 1;
    coord[0].y = y + (height / 4) - 1;
    coord[1].x = coord[0].x;
    coord[1].y = y;
    coord[2].x = x + width - 1;
    coord[2].y = y;
    coord[3].x = coord[2].x;
    coord[3].y = y + height - 1;
    coord[4].x = coord[0].x;
    coord[4].y = coord[3].y;
    coord[5].x = coord[0].x;
    coord[5].y = coord[4].y - (height / 4) + 1;
    coord[6].x = x;
    coord[6].y = coord[5].y;
    coord[7].x = x;
    coord[7].y = coord[0].y;

    //绘制缺口
    x0 = coord[1].x; y0 = coord[1].y; x1 = coord[2].x; y1 = coord[2].y + lineSize - 1; GUIFillColor(x0, y0, x1, y1, edgeColor);
    x0 = coord[2].x - lineSize + 1; y0 = coord[2].y; x1 = coord[3].x; y1 = coord[3].y; GUIFillColor(x0, y0, x1, y1, edgeColor);
    x0 = coord[4].x; y0 = coord[4].y - lineSize + 1; x1 = coord[3].x; y1 = coord[3].y; GUIFillColor(x0, y0, x1, y1, edgeColor);

    //画正极竖线
    x0 = coord[1].x; y0 = coord[1].y; x1 = coord[0].x + lineSize - 1; y1 = coord[0].y; GUIFillColor(x0, y0, x1, y1, edgeColor);
    x0 = coord[5].x; y0 = coord[5].y; x1 = coord[4].x + lineSize - 1; y1 = coord[4].y; GUIFillColor(x0, y0, x1, y1, edgeColor);
    x0 = coord[7].x; y0 = coord[7].y; x1 = coord[6].x + lineSize - 1; y1 = coord[6].y; GUIFillColor(x0, y0, x1, y1, edgeColor);

    //画正极横线
    x0 = coord[7].x; y0 = coord[7].y; x1 = coord[0].x + lineSize - 1; y1 = coord[0].y + lineSize - 1; GUIFillColor(x0, y0, x1, y1, edgeColor);
    x0 = coord[6].x; y0 = coord[6].y - lineSize + 1; x1 = coord[5].x + lineSize - 1; y1 = coord[5].y; GUIFillColor(x0, y0, x1, y1, edgeColor);

    //电量为零,直接返回
    if (0 == remain) { return; }

    //确定电池主体部分内部区域坐标
    x0 = coord[1].x + lineSize;
    x1 = coord[2].x - lineSize;
    y0 = coord[1].y + lineSize;
    y1 = coord[4].y - lineSize;
    tWidth = x1 - x0 + 1;
    tHeight = y1 - y0 + 1;

    //填充小于等于 90 的部分
    tx = x1 - remain * tWidth / 90;
    if (tx > x0) { x0 = tx; }
    GUIFillColor(x0, y0, x1, y1, batColor);

    //确定正极部分内部区域坐标
    x0 = coord[7].x + lineSize;
    x1 = coord[1].x + lineSize - 1;
    y0 = coord[7].y + lineSize;
    y1 = coord[6].y - lineSize;
    tWidth = x1 - x0 + 1;
    tHeight = y1 - y0 + 1;

    //填充正极部分部分
    if (remain > 90)
    {
      remain = remain - 90;
      tx = x1 - remain * tWidth / 10;
      if (tx > x0) { x0 = tx; }
      GUIFillColor(x0, y0, x1, y1, batColor);
    }
  }

  /*
   *      0____________________1
   *      |                    |__3
   *      |                    2  |
   *      |                    5__|
   *      |____________________|  4
   *      7                    6
   *
   * 电池正极突起高度固定为整体高度的 10%
   * 电池正极直径为整个电池直径的 50%
   */
  else if (1 == direction)
  {
    //求各个点之间的坐标
    space = width / 10;
    coord[0].x = x;
    coord[0].y = y;
    coord[1].x = (x + width - 1) - space + 1;
    coord[1].y = y;
    coord[2].x = coord[1].x;
    coord[2].y = y + (height / 4) - 1;
    coord[3].x = x + width - 1;
    coord[3].y = coord[2].y;
    coord[4].x = coord[3].x;
    coord[4].y = (y + height - 1) - (height / 4) + 1;
    coord[5].x = coord[1].x;
    coord[5].y = coord[4].y;
    coord[6].x = coord[1].x;
    coord[6].y = y + height - 1;
    coord[7].x = x;
    coord[7].y = coord[6].y;

    //绘制缺口
    x0 = coord[0].x; y0 = coord[0].y; x1 = coord[1].x; y1 = coord[1].y + lineSize - 1; GUIFillColor(x0, y0, x1, y1, edgeColor);
    x0 = coord[7].x; y0 = coord[7].y - lineSize + 1; x1 = coord[6].x; y1 = coord[6].y; GUIFillColor(x0, y0, x1, y1, edgeColor);
    x0 = coord[0].x; y0 = coord[0].y; x1 = coord[7].x + lineSize - 1; y1 = coord[7].y; GUIFillColor(x0, y0, x1, y1, edgeColor);

    //画正极竖线
    x0 = coord[1].x - lineSize + 1; y0 = coord[1].y; x1 = coord[2].x; y1 = coord[2].y; GUIFillColor(x0, y0, x1, y1, edgeColor);
    x0 = coord[5].x - lineSize + 1; y0 = coord[5].y; x1 = coord[6].x; y1 = coord[6].y; GUIFillColor(x0, y0, x1, y1, edgeColor);
    x0 = coord[3].x - lineSize + 1; y0 = coord[3].y; x1 = coord[4].x; y1 = coord[4].y; GUIFillColor(x0, y0, x1, y1, edgeColor);

    //画正极横线
    x0 = coord[2].x - lineSize + 1; y0 = coord[2].y; x1 = coord[3].x; y1 = coord[3].y + lineSize - 1; GUIFillColor(x0, y0, x1, y1, edgeColor);
    x0 = coord[5].x - lineSize + 1; y0 = coord[5].y - lineSize + 1; x1 = coord[4].x; y1 = coord[4].y; GUIFillColor(x0, y0, x1, y1, edgeColor);

    //电量为零,直接返回
    if (0 == remain)
    {
      return;
    }

    //确定电池主体部分内部区域坐标
    x0 = coord[0].x + lineSize;
    x1 = coord[1].x - lineSize;
    y0 = coord[0].y + lineSize;
    y1 = coord[7].y - lineSize;
    tWidth = x1 - x0 + 1;
    tHeight = y1 - y0 + 1;

    //填充小于等于 90 的部分
    tx = x0 + remain * tWidth / 90;
    if (tx < x1) { x1 = tx; }
    GUIFillColor(x0, y0, x1, y1, batColor);

    //确定正极部分内部区域坐标
    x0 = coord[2].x - lineSize + 1;
    x1 = coord[3].x - lineSize;
    y0 = coord[2].y + lineSize;
    y1 = coord[5].y - lineSize;
    tWidth = x1 - x0 + 1;
    tHeight = y1 - y0 + 1;

    //填充正极部分部分
    if (remain > 90)
    {
      remain = remain - 90;
      tx = x0 + remain * tWidth / 10;
      if (tx < x1) { x1 = tx; }
      GUIFillColor(x0, y0, x1, y1, batColor);
    }
  }

  /*
   *          0____1
   *      6___|    |___3
   *      |   7    2   |
   *      |            |
   *      |            |
   *      |            |
   *      |            |
   *      |            |
   *      |____________|
   *      5            4
   *
   * 电池正极突起高度固定为整体高度的 10%
   * 电池正极直径为整个电池直径的 50%
   */
  else if (2 == direction)
  {
    //求各个点之间的坐标
    space = height / 10;
    coord[0].x = x + (width / 4) - 1;
    coord[0].y = y;
    coord[1].x = (x + width - 1) - (width / 4) + 1;
    coord[1].y = y;
    coord[2].x = coord[1].x;
    coord[2].y = y + space - 1;
    coord[3].x = x + width - 1;
    coord[3].y = coord[2].y;
    coord[4].x = coord[3].x;
    coord[4].y = y + height - 1;
    coord[5].x = x;
    coord[5].y = coord[4].y;
    coord[6].x = x;
    coord[6].y = coord[2].y;
    coord[7].x = coord[0].x;
    coord[7].y = coord[6].y;

    //绘制缺口
    x0 = coord[6].x; y0 = coord[6].y; x1 = coord[5].x + lineSize - 1; y1 = coord[5].y; GUIFillColor(x0, y0, x1, y1, edgeColor);
    x0 = coord[5].x; y0 = coord[5].y - lineSize + 1; x1 = coord[4].x; y1 = coord[4].y; GUIFillColor(x0, y0, x1, y1, edgeColor);
    x0 = coord[3].x - lineSize + 1; y0 = coord[3].y; x1 = coord[4].x; y1 = coord[4].y; GUIFillColor(x0, y0, x1, y1, edgeColor);

    //画正极横线
    x0 = coord[6].x; y0 = coord[6].y; x1 = coord[7].x; y1 = coord[7].y + lineSize - 1; GUIFillColor(x0, y0, x1, y1, edgeColor);
    x0 = coord[0].x; y0 = coord[0].y; x1 = coord[1].x; y1 = coord[1].y + lineSize - 1; GUIFillColor(x0, y0, x1, y1, edgeColor);
    x0 = coord[2].x; y0 = coord[2].y; x1 = coord[3].x; y1 = coord[3].y + lineSize - 1; GUIFillColor(x0, y0, x1, y1, edgeColor);

    //画正极竖线
    x0 = coord[0].x; y0 = coord[0].y; x1 = coord[7].x + lineSize - 1; y1 = coord[7].y + lineSize - 1; GUIFillColor(x0, y0, x1, y1, edgeColor);
    x0 = coord[1].x - lineSize + 1; y0 = coord[1].y; x1 = coord[2].x; y1 = coord[2].y + lineSize - 1; GUIFillColor(x0, y0, x1, y1, edgeColor);

    //电量为零,直接返回
    if (0 == remain) { return; }

    //确定电池主体部分内部区域坐标
    x0 = coord[6].x + lineSize;
    x1 = coord[3].x - lineSize;
    y0 = coord[6].y + lineSize;
    y1 = coord[5].y - lineSize;
    tWidth = x1 - x0 + 1;
    tHeight = y1 - y0 + 1;

    //填充小于等于 90 的部分
    ty = y1 - remain * tHeight / 90;
    if(ty > y0) { y0 = ty; }
    GUIFillColor(x0, y0, x1, y1, batColor);

    //确定正极部分内部区域坐标
    x0 = coord[0].x + lineSize;
    x1 = coord[1].x - lineSize;
    y0 = coord[0].y + lineSize;
    y1 = coord[7].y + lineSize - 1;
    tWidth = x1 - x0 + 1;
    tHeight = y1 - y0 + 1;

    //填充正极部分部分
    if (remain > 90)
    {
      remain = remain - 90;
      ty = y1 - remain * tHeight / 10;
      if (ty > y0) { y0 = ty; }
      GUIFillColor(x0, y0, x1, y1, batColor);
    }
  }

  /*
   *      0____________1
   *      |            |
   *      |            |
   *      |            |
   *      |            |
   *      |            |
   *      |            |
   *      |___6    3___|
   *      7   |____|   2
   *          5    4
   *
   * 电池正极突起高度固定为整体高度的 10%
   * 电池正极直径为整个电池直径的 50%
   */
  else if (3 == direction)
  {
    //求各个点之间的坐标
    space = height / 10;
    coord[0].x = x;
    coord[0].y = y;
    coord[1].x = x + width - 1;
    coord[1].y = coord[0].y;
    coord[2].x = coord[1].x;
    coord[2].y = (y + height - 1) - space + 1;
    coord[3].x = (x + width - 1) - (width / 4) + 1;
    coord[3].y = coord[2].y;
    coord[4].x = coord[3].x;
    coord[4].y = y + height - 1;
    coord[5].x = x + (width / 4) / 1;
    coord[5].y = coord[4].y;
    coord[6].x = coord[5].x;
    coord[6].y = coord[2].y;
    coord[7].x = coord[0].x;
    coord[7].y = coord[6].y;

    //绘制缺口
    x0 = coord[0].x; y0 = coord[0].y; x1 = coord[7].x + lineSize - 1; y1 = coord[7].y; GUIFillColor(x0, y0, x1, y1, edgeColor);
    x0 = coord[0].x; y0 = coord[0].y; x1 = coord[1].x; y1 = coord[1].y + lineSize - 1; GUIFillColor(x0, y0, x1, y1, edgeColor);
    x0 = coord[1].x - lineSize + 1; y0 = coord[1].y; x1 = coord[2].x; y1 = coord[2].y; GUIFillColor(x0, y0, x1, y1, edgeColor);

    //画正极横线
    x0 = coord[7].x; y0 = coord[7].y - lineSize + 1; x1 = coord[6].x; y1 = coord[6].y; GUIFillColor(x0, y0, x1, y1, edgeColor);
    x0 = coord[5].x; y0 = coord[5].y - lineSize + 1; x1 = coord[4].x; y1 = coord[4].y; GUIFillColor(x0, y0, x1, y1, edgeColor);
    x0 = coord[3].x; y0 = coord[3].y - lineSize + 1; x1 = coord[2].x; y1 = coord[2].y; GUIFillColor(x0, y0, x1, y1, edgeColor);

    //画正极竖线
    x0 = coord[6].x; y0 = coord[6].y - lineSize + 1; x1 = coord[5].x + lineSize - 1; y1 = coord[5].y; GUIFillColor(x0, y0, x1, y1, edgeColor);
    x0 = coord[3].x - lineSize + 1; y0 = coord[3].y - lineSize + 1; x1 = coord[4].x; y1 = coord[4].y; GUIFillColor(x0, y0, x1, y1, edgeColor);

    //电量为零,直接返回
    if (0 == remain) { return; }

    //确定电池主体部分内部区域坐标
    x0 = coord[0].x + lineSize;
    x1 = coord[1].x - lineSize;
    y0 = coord[0].y + lineSize;
    y1 = coord[7].y - lineSize;
    tWidth = x1 - x0 + 1;
    tHeight = y1 - y0 + 1;

    //填充小于等于 90 的部分
    ty = y0 + remain * tHeight / 90;
    if (ty < y1) { y1 = ty; }
    GUIFillColor(x0, y0, x1, y1, batColor);

    //确定正极部分内部区域坐标
    x0 = coord[6].x + lineSize;
    x1 = coord[3].x - lineSize;
    y0 = coord[6].y - lineSize + 1;
    y1 = coord[5].y - lineSize;
    tWidth = x1 - x0 + 1;
    tHeight = y1 - y0 + 1;

    //填充正极部分部分
    if (remain > 90)
    {
      remain = remain - 90;
      ty = y0 + remain * tHeight / 10;
      if (ty < y1) { y1 = ty; }
      GUIFillColor(x0, y0, x1, y1, batColor);
    }
  }
}