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

news2024/12/23 23:20:58

前言:

前面我们已经把显示系统、输入系统、文字系统搭建好了,现在我们就要给它实现按钮操作了,也就是搭建UI系统,下面让我们一起实现UI系统的搭建吧

目录

一、按钮数据结构抽象

ui.h

二、按键编程 

1.button.c

 2.disp_manager.c

3. disp_manager.h

三、单元测试

1.ui_test.c

2.unittest下的Makefile

3. ui下的Makefile

4.顶层目录下的Makefile

四、上板测试

1.ubuntu上

2. 开发板上

3.运行效果:


一、按钮数据结构抽象

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行:打印用法

        <font_size>指定字库文件

第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.运行效果:

每隔两秒切换一下颜色

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1277726.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

赤峰学院师资培养管理系统的设计与实现

摘 要 随着我国国民经济建设的蓬勃发展和信息技术的越发成熟&#xff0c;各个行业都在积极使用现代化的管理工具&#xff0c;不断改善企业的服务质量&#xff0c;提高工作效率。对师资培养进行现代化的管理&#xff0c;提高工作效率是师资培养管理系统的一大优点。本文是一篇关…

Aspice(Automotive Software Process Improvement and Capability Determination)

Aspice&#xff08;Automotive Software Process Improvement and Capability Determination&#xff09; 1. 引言&#xff1a;ASPICE概述 定义 ASPICE简介&#xff1a;ASPICE&#xff08;Automotive Software Process Improvement and Capability Determination&#xff09;…

Qt Creator 11.0.3同时使用Qt6.5和Qt5.14.2

Qt Creator 11.0.3同时使用Qt6.5和Qt5.14.2 概要方法1.打开Qt Creator中的Kit&#xff0c;这里我直接附上几张截图&#xff0c;不同的版本打开位置可能有所不同&#xff0c;总之最终目的是要打开构建套件&#xff08;Kit&#xff09;2.可以看到构建套件里面有包含了“构建套件K…

栈顺序存储的实现(详解)

栈是一种数据结构&#xff0c;它具有后进先出&#xff08;LIFO&#xff09;的特性。栈可以用来存储一组元素&#xff0c;并且只能在栈顶进行插入和删除操作。栈的基本概念包括&#xff1a; 1. 入栈&#xff08;push&#xff09;&#xff1a;将元素添加到栈顶的操作。 2. 出栈&…

【halcon】C# halcon 内存暴增

1 读取图片需要及时手动释放 一个6M的图片通过halcon进行加载&#xff0c;大约会消耗200M的内存&#xff0c;如果等待GC回收&#xff0c;而你又在不停的读取图片&#xff0c;你的内存占用&#xff0c;将在短时间内飙升。 2 halcon控件显示图片需要清空。 /// <summary>…

Motion 5 for Mac,释放创意,打造精彩视频特效!

Motion 5 for Mac是一款强大的视频后期特效处理软件&#xff0c;为Mac用户提供了无限的创意可能性。无论你是专业的影视制作人&#xff0c;还是想为个人视频添加独特特效的爱好者&#xff0c;Motion 5都能满足你的需求&#xff0c;让你的视频脱颖而出。 Motion 5提供了丰富多样…

数据链路层之VLAN基本概念和基本原理

学习的最大理由是想摆脱平庸&#xff0c;早一天就多一份人生的精彩&#xff1b;迟一天就多一天平庸的困扰。各位小伙伴&#xff0c;如果您&#xff1a; 想系统/深入学习某技术知识点… 一个人摸索学习很难坚持&#xff0c;想组团高效学习… 想写博客但无从下手&#xff0c;急需…

线程与多线程编程

1. 线程 1.1 概念 线程又可以称为轻量级进程 &#xff0c;在进程的基础上做出了改进。 一个进程在刚刚启动时&#xff0c;做的第一件事就是申请内存和资源&#xff0c;进程需要把依赖的代码和数据&#xff0c;从磁盘加载到内存中这件事是比较耗费时间的&#xff0c;有的业务…

国产AI边缘计算盒子,双核心A55丨2.5Tops算力

边缘计算盒子 双核心A55丨2.5Tops算力 ● 2.5TopsINT8算力&#xff0c;支持INT8/INT4/FP16多精度混合量化。 ● 4路以上1080p30fps视频编解码&#xff0c;IVE模块独立提供图像基础算子加速。 ● 支持Caffe、ONNX/PyTorch深度学习框架&#xff0c;提供resnet50、yolov5等AI算…

vue项目报错及解决npm run build:prod打包错误

vue项目报错及解决npm run build:prod打包错误 执行dev环境时加载失败了该变量&#xff0c;在package.json文件中 删掉 解决方法&#xff1a; 打包成功&#xff1a;

kerberos详解

一、介绍 kerberos概述 Kerberos始于20世纪80年代早期麻省理工学院&#xff08;MIT&#xff09;的一个研究项目&#xff0c;是一个网络身份验证系统。Kerberos提供的完整定义是安全的、单点登录的、可信的第三方相互身份验证服务。 认证过程 相关概念 KDC&#xff08;key D…

GD32 定时器输入捕获模式测量PWM占空比和频率

简介 利用GD32 定时器的PWM输入捕获模式来实现PWM波形的占空比和频率的测量。相应的简介可以参考GD32用户手册中关于定时器输入捕获的章节&#xff0c;PWM输入捕获模式是输入捕获模式的一个特例。(记录自己学习过程&#xff0c;如有错误请留言指出) 原理 如何利用定时器测量…

JavaSE-习题-循环结构等

第 1 题&#xff08;编程题&#xff09; 题目名称&#xff1a; 打印 X 图形 题目内容&#xff1a; https://www.nowcoder.com/practice/83d6afe3018e44539c51265165806ee4 假设i代表行&#xff0c;j代表列&#xff0c;当ij 或者 ij1 n&#xff0c;此时为星号。其余的都是空格。…

杨志丰:OceanBase助力企业应对数据库转型深水区挑战

11 月 16 日&#xff0c;OceanBase 在北京顺利举办 2023 年度发布会&#xff0c;正式宣布&#xff1a;将持续践行“一体化”产品战略&#xff0c;为关键业务负载打造一体化数据库。OceanBase 产品总经理杨志丰发表了《助力企业应对数据库转型深水区挑战》主题演讲。 以下为演讲…

SmartSoftHelp8,SQL语句美化,格式化,压缩

SQL语句美化&#xff0c;格式化&#xff0c;压缩 下载地址&#xff1a;https://pan.baidu.com/s/1zBgeYsqWnSlNgiKPR2lUYg?pwd8888

在oracle中的scn技术

SCN可以说是Oracle中一个很基础的部分&#xff0c;但同时它也是一个很重要的。它是系统中维持数据的一致性和顺序恢复的重要标志&#xff0c;是数据库非常重要的一种数据结构。 转载&#xff1a;深入剖析 - Oracle SCN机制详细解读 - 知乎 (zhihu.com)https://zhuanlan.zhihu.…

【计算机概论 ①】- 电脑:辅助人脑的好工具

目录 一、电脑硬件的五大单元 二、一切设计的起点&#xff1a;CPU 的架构 三、其他单元的设备 四、运行流程 五、电脑的分类 六、电脑上面常用的计算单位&#xff08;容量、速度等&#xff09; 操作系统跟硬件有相当程度的关联性&#xff0c;所以&#xff0c;如果不了解一…

详解原生Spring框架下的类切入点表达式与切入点函数

&#x1f609;&#x1f609; 学习交流群&#xff1a; ✅✅1&#xff1a;这是孙哥suns给大家的福利&#xff01; ✨✨2&#xff1a;我们免费分享Netty、Dubbo、k8s、Mybatis、Spring...应用和源码级别的视频资料 &#x1f96d;&#x1f96d;3&#xff1a;QQ群&#xff1a;583783…

汉威科技家电传感器解决方案,助力智能家电市场蓬勃发展

2017年以来&#xff0c;我国家电市场承压前行&#xff0c;零售总额基本保持在9000亿元左右&#xff0c;虽然距离万亿市场只有一步之遥&#xff0c;却一直未能企及。随着物联网、传感器、AI、云计算、大数据、5G等技术的快速发展迭代&#xff0c;智能家电成为行业转型发展的突破…

C语言结构体详解(一)(能看懂文字就能明白系列)

&#x1f31f;&#x1f31f;&#x1f31f;&#x1f31f;&#x1f31f;&#x1f31f;&#x1f31f;&#x1f31f;&#x1f31f;&#x1f31f;&#x1f31f;个人主页&#xff1a; 古德猫宁- &#x1f31f;&#x1f31f;&#x1f31f;&#x1f31f;&#x1f31f;&#x1f31f;…