Linux基础项目开发1:量产工具——UI系统(五)

简介: Linux基础项目开发1:量产工具——UI系统(五)

一、按钮数据结构抽象

1.所谓UI,就是User Interface(用户界面),有图像界面(GUI)

2.我们的UI系统,就是构造各类GUI元素,比如按钮(目前只实现按钮)

3.怎么描述一个按钮呢?

       3.1 它的位置、大小怎么表示?

       3.2 怎么绘制它?

       3.3 用户点击它之后,如何处理?

ui.h

 
#ifndef _UI_H
#define _UI_H
 
#include <common.h>
#include <disp_manager.h>
#include <input_manager.h>
 
#define BUTTON_DEFAULT_COLOR 0xff0000
#define BUTTON_PRESSED_COLOR 0x00ff00
#define BUTTON_TEXT_COLOR    0x000000
 
struct Button;
 
typedef int (*ONDRAW_FUNC)(struct Button *ptButton, PDispBuff ptDispBuff);
typedef int (*ONPRESSED_FUNC)(struct Button *ptButton, PDispBuff ptDispBuff, PInputEvent ptInputEvent);
 
 
typedef struct Button {
  char *name;
  int status;
  Region tRegion;
  ONDRAW_FUNC OnDraw;
  ONPRESSED_FUNC OnPressed;
}Button, *PButton;
 
void InitButton(PButton ptButton, char *name, PRegion ptRegion, ONDRAW_FUNC OnDraw, ONPRESSED_FUNC OnPressed);
 
#endif
 

第9~11行:定义红绿黑三种颜色

第20行:描述结构体的名字

第22行:描述按钮区域的位置

第23行:OnDraw:提供一个绘制函数

第24行:OnPressed:点击以后执行某些函数

二、按键编程

1.点击按钮后怎么处理,是业务系统的事情

2.所以应该提供一个InitButton函数,让用户可以提供OnPressed函数

3.上层代码通过下面3个函数使用按钮

1.button.c

 
 
#include <ui.h>
 
 
static int DefaultOnDraw(struct Button *ptButton, PDispBuff ptDispBuff)
{
  /* 绘制底色 */
  DrawRegion(&ptButton->tRegion, BUTTON_DEFAULT_COLOR);
 
  /* 居中写文字 */
  DrawTextInRegionCentral(ptButton->name, &ptButton->tRegion, BUTTON_TEXT_COLOR);
 
  /* flush to lcd/web */
  FlushDisplayRegion(&ptButton->tRegion, ptDispBuff);
 
    return 0;
}
 
static int DefaultOnPressed(struct Button *ptButton, PDispBuff ptDispBuff, PInputEvent ptInputEvent)
{
  unsigned int dwColor = BUTTON_DEFAULT_COLOR;
  
  ptButton->status = !ptButton->status;
  if (ptButton->status)
    dwColor = BUTTON_PRESSED_COLOR;
 
  /* 绘制底色 */
  DrawRegion(&ptButton->tRegion, dwColor);
 
  /* 居中写文字 */
  DrawTextInRegionCentral(ptButton->name, &ptButton->tRegion, BUTTON_TEXT_COLOR);
 
  /* flush to lcd/web */
  FlushDisplayRegion(&ptButton->tRegion, ptDispBuff);
 
}
 
 
void InitButton(PButton ptButton, char *name, PRegion ptRegion, ONDRAW_FUNC OnDraw, ONPRESSED_FUNC OnPressed)
{
  ptButton->status = 0;
  ptButton->name = name;
  ptButton->tRegion = *ptRegion;
  ptButton->OnDraw    = OnDraw ? OnDraw : DefaultOnDraw;
  ptButton->OnPressed = OnPressed ? OnPressed : DefaultOnPressed;
}
 
 
static int DefaultOnDraw(struct Button *ptButton, PDispBuff ptDispBuff)

第6~16行:实现默认的 DefaultOnDraw 函数

       第8行:某一区域绘制底色

       第12行:居中写文字

       第15行:刷新到LCD或者web上

static int DefaultOnPressed(struct Button *ptButton, PDispBuff ptDispBuff, PInputEvent ptInputEvent)

第20~37行:实现默认的 DefaultOnPressed 函数

       第22行:设置初始状态颜色        

       第24行:每次点击初始状态翻转

       第25行:如果初始状态变为1,则颜色进行翻转

       第28~35行:进行颜色变化

void InitButton(PButton ptButton, char *name, PRegion ptRegion, ONDRAW_FUNC OnDraw, ONPRESSED_FUNC OnPressed)

第40~47行:初始化按键

       第42行:记录初始状态

       第43行:将按钮名字传入

       第44行:将按钮所在区域传入

       第45、46行:如果按下一个这个函数存在的话,那就执行这个函数,否则执行默认的函数

2.disp_manager.c

ptRegion这一部分区域绘制成dwColor的颜色

 
void DrawRegion(PRegion ptRegion, unsigned int dwColor)
{
  int x = ptRegion->iLeftUpX;
  int y = ptRegion->iLeftUpY;
  int width = ptRegion->iWidth;
  int heigh = ptRegion->iHeigh;
 
  int i,j;
 
  for (j = y; j < y + heigh; j++)
  {
    for (i = x; i < x + width; i++)
      PutPixel(i, j, dwColor);
  }
}

在一个区域ptRegion中间将位置居中,并且设置字体颜色

void DrawTextInRegionCentral(char *name, PRegion ptRegion, unsigned int dwColor)
{
  int n = strlen(name);
  int iFontSize = ptRegion->iWidth / n / 2;
  FontBitMap tFontBitMap;
 
  int iOriginX, iOriginY;
  int i = 0;
  int error;
 
  if (iFontSize > ptRegion->iHeigh)
    iFontSize =  ptRegion->iHeigh;
 
  iOriginX = (ptRegion->iWidth - n * iFontSize)/2 + ptRegion->iLeftUpX;
  iOriginY = (ptRegion->iHeigh - iFontSize)/2 + iFontSize + ptRegion->iLeftUpY;
 
  SetFontSize(iFontSize);
 
  while (name[i])
  {
    /* get bitmap */
    tFontBitMap.iCurOriginX = iOriginX;
    tFontBitMap.iCurOriginY = iOriginY;
    error = GetFontBitMap(name[i], &tFontBitMap);
    if (error)
    {
      printf("SelectAndInitFont err\n");
      return;
    }
 
    /* draw on buffer */    
    DrawFontBitMap(&tFontBitMap, dwColor);    
 
    iOriginX = tFontBitMap.iNextOriginX;
    iOriginY = tFontBitMap.iNextOriginY;  
    i++;
  }
  
}

3. disp_manager.h

#ifndef _DISP_MANAGER_H
#define _DISP_MANAGER_H
 
#include <common.h>
#include <font_manager.h>
 
 
typedef struct DispBuff {
  int iXres;
  int iYres;
  int iBpp;
  char *buff;
}DispBuff, *PDispBuff;
 
 
 
typedef struct DispOpr {
  char *name;
  int (*DeviceInit)(void);
  int (*DeviceExit)(void);
  int (*GetBuffer)(PDispBuff ptDispBuff);
  int (*FlushRegion)(PRegion ptRegion, PDispBuff ptDispBuff);
  struct DispOpr *ptNext;
}DispOpr, *PDispOpr;
 
void RegisterDisplay(PDispOpr ptDispOpr);
 
void DisplayInit(void);
int SelectDefaultDisplay(char *name);
int InitDefaultDisplay(void);
int PutPixel(int x, int y, unsigned int dwColor);
int FlushDisplayRegion(PRegion ptRegion, PDispBuff ptDispBuff);
PDispBuff GetDisplayBuffer(void);
void DrawFontBitMap(PFontBitMap ptFontBitMap, unsigned int dwColor);
void DrawRegion(PRegion ptRegion, unsigned int dwColor);
void DrawTextInRegionCentral(char *name, PRegion ptRegion, unsigned int dwColor);
 
#endif
 
 
 
 

三、单元测试

1.ui_test.c

#include <sys/mman.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <linux/fb.h>
#include <fcntl.h>
#include <stdio.h>
#include <string.h>
#include <sys/ioctl.h>
#include <stdlib.h>
 
#include <disp_manager.h>
#include <font_manager.h>
#include <ui.h>
 
int main(int argc, char **argv)
{
  PDispBuff ptBuffer;
  int error;
  Button tButton;
  Region tRegion;
 
  if (argc != 2)
  {
    printf("Usage: %s <font_size>\n", argv[0]);
    return -1;
  }
    
  DisplayInit();
 
  SelectDefaultDisplay("fb");
 
  InitDefaultDisplay();
 
  ptBuffer = GetDisplayBuffer();
 
  FontsRegister();
  
  error = SelectAndInitFont("freetype", argv[1]);
  if (error)
  {
    printf("SelectAndInitFont err\n");
    return -1;
  }
 
  tRegion.iLeftUpX = 200;
  tRegion.iLeftUpY = 200;
  tRegion.iWidth   = 300;
  tRegion.iHeigh   = 100;
  
  InitButton(&tButton, "test", &tRegion, NULL, NULL);
  tButton.OnDraw(&tButton, ptBuffer);
  while (1)
  {
    tButton.OnPressed(&tButton, ptBuffer, NULL);
    sleep(2);
  }
  
  return 0; 
}

第23~27行:打印用法

       指定字库文件

第29~35行:显示系统初始化

第37~39行:字体系统初始化

第46~57行:UI系统初始化

       第46~49行:显示区域位置

       第51行:初始化按钮  

       第52行:将按钮绘制显示出来

       第55行:模拟点击

2.unittest下的Makefile

EXTRA_CFLAGS  := 
CFLAGS_file.o := 
 
#obj-y += disp_test.o
#obj-y += input_test.o
#obj-y += font_test.o
obj-y += ui_test.o

3. ui下的Makefile

EXTRA_CFLAGS  := 
CFLAGS_file.o := 
 
obj-y += button.o

4.顶层目录下的Makefile

 
CROSS_COMPILE ?= 
AS    = $(CROSS_COMPILE)as
LD    = $(CROSS_COMPILE)ld
CC    = $(CROSS_COMPILE)gcc
CPP   = $(CC) -E
AR    = $(CROSS_COMPILE)ar
NM    = $(CROSS_COMPILE)nm
 
STRIP   = $(CROSS_COMPILE)strip
OBJCOPY   = $(CROSS_COMPILE)objcopy
OBJDUMP   = $(CROSS_COMPILE)objdump
 
export AS LD CC CPP AR NM
export STRIP OBJCOPY OBJDUMP
 
CFLAGS := -Wall -O2 -g
CFLAGS += -I $(shell pwd)/include
 
LDFLAGS := -lts -lpthread -lfreetype
 
export CFLAGS LDFLAGS
 
TOPDIR := $(shell pwd)
export TOPDIR
 
TARGET := test
 
 
obj-y += display/
obj-y += input/
obj-y += font/
obj-y += ui/
obj-y += unittest/
 
all : start_recursive_build $(TARGET)
  @echo $(TARGET) has been built!
 
start_recursive_build:
  make -C ./ -f $(TOPDIR)/Makefile.build
 
$(TARGET) : built-in.o
  $(CC) -o $(TARGET) built-in.o $(LDFLAGS)
 
clean:
  rm -f $(shell find -name "*.o")
  rm -f $(TARGET)
 
distclean:
  rm -f $(shell find -name "*.o")
  rm -f $(shell find -name "*.d")
  rm -f $(TARGET)
  
obj-y += display/
obj-y += input/
obj-y += font/
obj-y += ui/
obj-y += unittest/

四、上板测试

1.ubuntu上

book@100ask:~/source$ make
book@100ask:~/source$ cp -r 20_ui_unittest/ ~/nfs_rootfs/

2. 开发板上

[root@100ask:/]#  mount -t nfs -o nolock,vers=3 192.168.5.11:/home/book/nfs_rootfs /mnt
[root@100ask:/mnt/20_ui_unittest]# ./test ./simsun.ttc

3.运行效果:

每隔两秒切换一下颜色


目录
相关文章
|
5天前
|
存储 缓存 监控
Linux缓存管理:如何安全地清理系统缓存
在Linux系统中,内存管理至关重要。本文详细介绍了如何安全地清理系统缓存,特别是通过使用`/proc/sys/vm/drop_caches`接口。内容包括清理缓存的原因、步骤、注意事项和最佳实践,帮助你在必要时优化系统性能。
112 78
|
8天前
|
Linux Shell 网络安全
Kali Linux系统Metasploit框架利用 HTA 文件进行渗透测试实验
本指南介绍如何利用 HTA 文件和 Metasploit 框架进行渗透测试。通过创建反向 shell、生成 HTA 文件、设置 HTTP 服务器和发送文件,最终实现对目标系统的控制。适用于教育目的,需合法授权。
39 9
Kali Linux系统Metasploit框架利用 HTA 文件进行渗透测试实验
|
4天前
|
存储 监控 Linux
嵌入式Linux系统编程 — 5.3 times、clock函数获取进程时间
在嵌入式Linux系统编程中,`times`和 `clock`函数是获取进程时间的两个重要工具。`times`函数提供了更详细的进程和子进程时间信息,而 `clock`函数则提供了更简单的处理器时间获取方法。根据具体需求选择合适的函数,可以更有效地进行性能分析和资源管理。通过本文的介绍,希望能帮助您更好地理解和使用这两个函数,提高嵌入式系统编程的效率和效果。
44 13
|
28天前
|
Ubuntu Linux 网络安全
linux系统ubuntu中在命令行中打开图形界面的文件夹
在Ubuntu系统中,通过命令行打开图形界面的文件夹是一个高效且实用的操作。无论是使用Nautilus、Dolphin还是Thunar,都可以根据具体桌面环境选择合适的文件管理器。通过上述命令和方法,可以简化日常工作,提高效率。同时,解决权限问题和图形界面问题也能确保操作的顺利进行。掌握这些技巧,可以使Linux操作更加便捷和灵活。
20 3
|
5天前
|
Ubuntu Linux C++
Win10系统上直接使用linux子系统教程(仅需五步!超简单,快速上手)
本文介绍了如何在Windows 10上安装并使用Linux子系统。首先,通过应用商店安装Windows Terminal和Linux系统(如Ubuntu)。接着,在控制面板中启用“适用于Linux的Windows子系统”并重启电脑。最后,在Windows Terminal中选择安装的Linux系统即可开始使用。文中还提供了注意事项和进一步配置的链接。
17 0
|
1月前
|
Linux
在 Linux 系统中,`find` 命令
在 Linux 系统中,`find` 命令
33 1
|
16天前
|
存储 Oracle 安全
服务器数据恢复—LINUX系统删除/格式化的数据恢复流程
Linux操作系统是世界上流行的操作系统之一,被广泛用于服务器、个人电脑、移动设备和嵌入式系统。Linux系统下数据被误删除或者误格式化的问题非常普遍。下面北亚企安数据恢复工程师简单聊一下基于linux的文件系统(EXT2/EXT3/EXT4/Reiserfs/Xfs) 下删除或者格式化的数据恢复流程和可行性。
|
1月前
|
搜索推荐 Android开发 开发者
探索安卓开发中的自定义视图:打造个性化UI组件
【10月更文挑战第39天】在安卓开发的世界中,自定义视图是实现独特界面设计的关键。本文将引导你理解自定义视图的概念、创建流程,以及如何通过它们增强应用的用户体验。我们将从基础出发,逐步深入,最终让你能够自信地设计和实现专属的UI组件。
|
2月前
|
开发框架 JavaScript 前端开发
鸿蒙NEXT开发声明式UI是咋回事?
【10月更文挑战第15天】鸿蒙NEXT的声明式UI基于ArkTS,提供高效简洁的开发体验。ArkTS扩展了TypeScript,支持声明式UI描述、自定义组件及状态管理。ArkUI框架则提供了丰富的组件、布局计算和动画能力。开发者仅需关注数据变化,UI将自动更新,简化了开发流程。此外,其前后端分层设计与编译时优化确保了高性能运行,利于生态发展。通过组件创建、状态管理和渲染控制等方式,开发者能快速构建高质量的鸿蒙应用。
136 3
|
17天前
|
XML 搜索推荐 前端开发
安卓开发中的自定义视图:打造个性化UI组件
在安卓应用开发中,自定义视图是一种强大的工具,它允许开发者创造独一无二的用户界面元素,从而提升应用的外观和用户体验。本文将通过一个简单的自定义视图示例,引导你了解如何在安卓项目中实现自定义组件,并探讨其背后的技术原理。我们将从基础的View类讲起,逐步深入到绘图、事件处理以及性能优化等方面。无论你是初学者还是有经验的开发者,这篇文章都将为你提供有价值的见解和技巧。
下一篇
DataWorks