首页 > 其他分享 >数码相框-编写框架

数码相框-编写框架

时间:2024-04-07 20:12:10浏览次数:19  
标签:函数 动作 PageAction 相框 数码 事件 编写 输入 页面

程序框架

程序界面:

image

程序结构:

  • main.c调用一个T_PageAction​数据类型的Run函数,展示界面。

  • T_PageAction​ 类型的结构体。T_PageAction​ 结构体用于定义页面的行为接口,包含以下成员:

    • .name: 字符串,表示页面名称(这里是 "main"),用于标识该页面。
    • .Run: 函数指针,指向执行页面运行逻辑的函数(这里是 MainPageRun​)。
    • .GetInputEvent: 函数指针,指向获取页面输入事件的函数(这里是 MainPageGetInputEvent​)。
    • .Prepare: 函数指针,指向执行页面预处理逻辑的函数(此处未提供具体的 MainPagePrepare​ 函数定义)

    image

  • 把freetype和libjepg封装到render.c。通过render.c得到要展示的数据。

    image

  • 位图调用disp_mannger.c在framebuffer或者vga上显示。image

  • 可以通过key或者触摸屏捕获按键输入。

编写程序框架

是基于image这个文件夹进行修改的。

删除draw​文件夹,创建page​文件夹,创建以下文件:

image

编写page_manager

写page_manager结构体:

image



#ifndef _PAGE_MANAGER_H
#define _PAGE_MANAGER_H

typedef struct PageAction {
	char *name;
	int (*Run)(void);
	int (*GetInputEvent)();
	int (*Prepare)();
	struct PageAction *ptNext;
}T_PageAction, *PT_PageAction;


#endif /* _PAGE_MANAGER_H */

定义了一个名为PageAction​的结构体,用于表示页面操作的类型。该结构体具有以下成员:

  • name​:一个指向字符数组的指针,用于存储页面操作的名称。
  • Run​:一个指向函数的指针,该函数在页面操作执行时被调用,没有参数和返回值。
  • GetInputEvent​:一个指向函数的指针,该函数在页面等待用户输入时被调用,没有参数和返回值。
  • Prepare​:一个指向函数的指针,该函数在页面操作准备时被调用,没有参数和返回值。
  • ptNext​:一个指向PageAction​结构体的指针,用于表示下一个页面操作。

该结构体可用于创建一个页面操作的链表,每个链表节点代表一个页面操作,可以通过调用相应成员函数来执行、获取输入事件和准备页面操作。

编写page_manger.c:

#include <config.h>
#include <page_manager.h>
#include <string.h>


// 链表头部,用于存储注册的所有页面动作
static PT_PageAction g_ptPageActionHead;

/**
 * 注册一个页面动作到链表中。
 * 
 * @param ptPageAction 指向待注册页面动作的指针。
 * @return 始终返回0。
 */
int RegisterPageAction(PT_PageAction ptPageAction)
{
    // 如果链表为空,将传入的页面动作设置为链表头
	if (!g_ptPageActionHead)
	{
		g_ptPageActionHead   = ptPageAction;
		ptPageAction->ptNext = NULL;
	}
	else
	{
        // 遍历链表,找到最后一个页面动作并添加新页面动作
		ptTmp = g_ptPageActionHead;
		while (ptTmp->ptNext)
		{
			ptTmp = ptTmp->ptNext;
		}
		ptTmp->ptNext	  = ptPageAction;
		ptPageAction->ptNext = NULL;
	}

	return 0;
}


/**
 * 打印所有已注册的页面动作名称。
 */
void ShowPages(void)
{
    // 遍历链表,打印每个页面动作的名称
	int i = 0;
	PT_PageAction ptTmp = g_ptPageActionHead;

	while (ptTmp)
	{
		printf("%02d %s\n", i++, ptTmp->name);
		ptTmp = ptTmp->ptNext;
	}
}

/**
 * 查找指定名称的页面动作。
 * 
 * @param pcName 指向要查找的页面动作名称的字符指针。
 * @return 如果找到与名称匹配的页面动作,则返回其指针;否则返回NULL。
 */
PT_PageAction Page(char *pcName)
{
    PT_PageAction ptTmp = g_ptPageActionHead; // 从页面动作链表头开始查找
  
    // 遍历链表,查找名称匹配的页面动作
    while (ptTmp)
    {
        if (strcmp(ptTmp->name, pcName) == 0) // 比较当前页面动作名称与目标名称
        {
            return ptTmp; // 名称匹配,返回当前页面动作
        }
        ptTmp = ptTmp->ptNext; // 继续查找下一个页面动作
    }

    return NULL; // 未找到匹配的页面动作
}

/**
 * 初始化页面管理功能。
 * 
 * @return 初始化错误码。
 */
int PagesInit(void)
{
	int iError;

	// 初始化过程中的错误处理

	return iError;
}

主要用于实现页面动作(PT_PageAction​)的管理和操作。具体功能如下:

  1. 页面动作注册:通过RegisterPageAction​函数,可以将新的页面动作实例(PT_PageAction​类型)添加到全局静态链表g_ptPageActionHead​中。链表用于存储所有已注册的页面动作。当链表为空时,直接将新页面动作作为链表头;否则,将新页面动作追加到链表尾部。
  2. 页面动作展示ShowPages​函数用于遍历并打印所有已注册页面动作的名称。它以序号和名称的形式输出每一个页面动作。
  3. 页面动作查找Page​函数接收一个字符串参数pcName​,表示要查找的页面动作名称。函数遍历链表,逐个比较每个页面动作的名称是否与给定名称匹配。若找到匹配项,返回该页面动作的指针;否则返回NULL​。
  4. 页面管理初始化PagesInit​函数负责初始化页面管理相关功能。仅保留了错误码变量声明,其预期功能是在执行必要的初始化操作后,返回一个表示初始化结果(成功或失败)的错误码。

综上所述主要提供了一个轻量级的页面动作管理模块,支持页面动作的注册、展示、按名称查找以及整个模块的初始化操作。这些功能可能服务于一个需要对页面动作进行集中管理和调度的应用程序。

编写main

#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <config.h>
#include <draw.h>
#include <encoding_manager.h>
#include <fonts_manager.h>
#include <disp_manager.h>
#include <input_manager.h>
#include <string.h>


int main(int argc, char **argv)
{
	/* 一系列的初始化 */

	Page("main")->Run();
	return 0;
}

写程序框架的初始化,从main页面开始。接下来定义main:

编写main_page

/*
 * 主页面管理程序
 * 
 * 本程序实现了主页面的运行逻辑,包括处理用户输入事件,切换到其他页面等功能。
 * 
 * @Author: Bleaach008
 * @Date: 2024-04-07 14:15:32
 * @LastEditTime: 2024-04-07 15:05:10
 * @FilePath: \14.digial_photo_frame\page\main_page.c
 */

#include <config.h> // 系统配置头文件
#include <page_manager.h> // 页面管理器头文件

// 主页面动作结构体,定义了主页面的运行、输入事件获取、准备等函数指针
static T_PageAction g_tMainPageAction = {
	.name          = "main", // 页面名称
	.Run           = MainPageRun, // 运行页面的函数指针
	.GetInputEvent = MainPageGetInputEvent, // 获取输入事件的函数指针
	.Prepare       = MainPagePrepare; // 准备页面的函数指针
};

/*
 * 主页面运行函数
 * 该函数不断地获取输入事件,并根据事件进行相应的操作,如切换到浏览模式、连播模式或设置页面。
 */
static void MainPageRun(void)
{
    /* 显示主页面 */

    /* 创建Prepare线程,用于页面切换前的准备工作 */

    /* 不断获取输入事件并处理 */
    while (1)
    {
        InputEvent = MainPageGetInputEvent();
        switch (InputEvent)   // 根据获取的输入事件选择相应的操作
        {
            case "浏览模式":
            {
                /* 保存当前页面 */
                StorePage();
              
                /* 切换到浏览模式页面 */
                Page("explore")->Run();
              
                /* 恢复之前的页面 */
                RestorePage();
                break;
            }
            case "连播模式":
            {
                /* 保存当前页面 */
                StorePage();

                /* 切换到连播模式页面 */
                Page("auto")->Run();
                break;
            }
            case "设置":
            {
                /* 保存当前页面 */
                StorePage();
                /* 切换到设置页面 */
                Page("setting")->Run();
                /* 恢复之前的页面 */
                RestorePage();
                break;
            }      
        }
    }
}

/*
 * 主页面获取输入事件函数
 * 该函数负责从输入管理器获取触摸屏事件。
 * 
 * @返回值: 输入事件类型,具体类型依据实现而定。
 */
int MainPageGetInputEvent(...)
{
    /* 获得原始的触摸屏数据,会使得当前线程休眠,直到有触摸屏事件发生 */
    GetInputEvent();
  
    /* 处理数据,返回处理结果 */
}

/*
 * 主页面初始化函数
 * 该函数用于注册主页面的动作到页面管理器。
 * 
 * @返回值: 注册结果,成功返回0,失败返回非0。
 */
int MainPageInit(void)
{
    return RegisterPageAction(&g_tMainPageAction);
}

主要用来实现一个数字相框中主页面的管理功能。它包含了以下核心组件:

  1. 主页面动作结构体 (g_tMainPageAction​​):定义了与主页面相关的操作接口,如运行(Run​​)、获取输入事件(GetInputEvent​​)和准备(Prepare​​)。这些接口通过函数指针关联到具体的实现函数,便于在程序中以统一方式管理和调用主页面的各种功能。

  2. 主页面运行函数 (MainPageRun​​):负责主页面的主循环逻辑。首先显示主页面,然后创建一个用于页面准备的线程。接下来,函数进入一个无限循环,不断从MainPageGetInputEvent​​ 函数获取用户输入事件。对于接收到的不同事件(如“浏览模式”、“连播模式”或“设置”),函数执行相应的操作,如保存当前页面状态、切换到指定页面执行其Run​​方法,以及在操作完成后恢复先前的页面状态。

  3. 主页面获取输入事件函数 (MainPageGetInputEvent​):负责从输入管理器获取触摸屏事件。该函数调用input_mannger.c的函数,确定是否让电脑跟前线程休眠,直至有触摸屏事件发生,会将线程唤醒,然后处理接收到的数据,并返回相应的输入事件类型。

    image

    image

    image

  4. 主页面初始化函数 (MainPageInit​​):负责将主页面的动作结构体注册到全局的页面管理器中。这样,当系统需要启动或调度主页面时,可以通过页面管理器调用已注册的g_tMainPageAction​​ 中的函数,实现对主页面的控制。

编写explorer_page

只需要在main_page.c上修改页面运行函数的程序逻辑:

static void ExplorePageRun(void)
{
	/* 1. 显示页面 */

	/* 2. 创建Prepare线程 */

	/* 3. 调用GetInputEvent获得输入事件,进而处理 */
	while (1)
	{
		InputEvent = ExplorePageGetInputEvent();
		switch (InputEvent)
		{
			case "向上":
			{
				/* 判断是否已经是顶层 */
				if (isTopLevel)
					return 0;
				else
				{
					/* 显示上一个目录的页面 */
				}
				break;
			}
			case "选择":
			{
				if (isSelectDir)
				{
					/* 显示下一级目录 */
				}
				else
				{
					/* 保存当前页面 */
					StorePage();
					Page("browse")->Run();
					/* 恢复之前的页面 */
					RestorePage();
				}
				break;
			}
			case "下页":
			{
				/* 显示下一页 */
				break;
			}	

			case "上页":
			{
				/* 显示上一页 */
				break;
			}	
		}
	}
}

通过调用ExplorePageGetInputEvent()​函数来获取输入事件,并根据不同的输入事件进行相应的处理:* 当输入事件为"向上"时,函数会判断当前是否已经是顶层目录,如果是,则退出函数并返回0;否则,显示上一个目录的页面。

  • 当输入事件为"选择"时,函数会判断当前是否选择了目录,如果是,则显示下一级目录;否则,保存当前页面,调用Page("browse")->Run()​来运行并显示下一页,并在完成后恢复之前的页面。
  • 当输入事件为"下页"时,函数会显示下一页。
  • 当输入事件为"上页"时,函数会显示上一页。

编写browse_page

static void BrowsePageRun(void)
{
	/* 1. 显示页面 */

	/* 2. 创建Prepare线程 */

	/* 3. 调用GetInputEvent获得输入事件,进而处理 */
	while (1)
	{
		InputEvent = BrowsePageGetInputEvent();
		switch (InputEvent)
		{
			case "返回":
			{
				return 0;
			}
			case "缩小":
			{
				/* 显示缩小的页面 */
				break;
			}
			case "放大":
			{
				/* 显示放大的页面 */
				break;
			}	

			case "上幅":
			{
				/* 显示上一幅图片 */
				break;
			}	
			case "下幅":
			{
				/* 显示下一幅图片 */
				break;
			}	
		
			case "连播":
			{
				Page("auto")->Run();
				break;
			}	

			case "按住不放":
			{
				/* 显示挪动的图片 */
				break;
			}
		}
	}
}

调用BrowsePageGetInputEvent()​函数来获取输入事件,并根据不同的输入事件执行相应的操作:* 当输入事件为"返回"时,函数返回0。

  • 当输入事件为"缩小"时,显示缩小的页面。
  • 当输入事件为"放大"时,显示放大的页面。
  • 当输入事件为"上幅"时,显示上一幅图片。
  • 当输入事件为"下幅"时,显示下一幅图片。
  • 当输入事件为"连播"时,调用Page("auto")->Run()​来执行自动播放操作。
  • 当输入事件为"按住不放"时,显示挪动的图片。

编写render

创建render文件夹,并在里面创建一个render.c。

render.c会用到font/freetype.c,还会用到libjpeg,所以我们需要创建一个libjpeg文件夹,并在里面创建一个libjpeg.c。

编写render.c:



int GetFontPixel()
{
}

int GetPicPixel()
{
}


int DrawPixel()
{
}

  • GetFontPixel()​:该函数用于获取字体的一个像素点的颜色值。
  • GetPicPixel()​:该函数用于获取图像的一个像素点的颜色值。
  • DrawPixel()​:该函数用于在屏幕上绘制一个像素点。会调用disp_manager.c来实现硬件的输出。

标签:函数,动作,PageAction,相框,数码,事件,编写,输入,页面
From: https://www.cnblogs.com/rose24/p/18119781/digital-photo-framewriting-framework-z1bujrs

相关文章

  • 三十六计与代码编写的奇妙结合
    一、引言在编程的世界里,我们总是在寻找更好的方法来解决问题,提高代码的质量和效率。而三十六计,这一中国古代智慧的结晶,竟然与代码编写有着惊人的契合。在这篇博客中,我将带您领略如何利用三十六计的智慧来编写更出色的代码。二、瞒天过海——隐藏复杂性简化接口:为用户提供......
  • GO 语言编写的程序运行过程详解
    1.1go源代码packagemainfuncmain(){goadd(1,2)}funcadd(a,bint)(int,int,int){returna+b,a,b}1234567先来看看上面这段程序的反汇编代码:1.2add函数反汇编代码0x401050  48c744241800000000  MOVQ$0x0,0x18(SP)0x401059  48c744......
  • 【求助】使用flask编写网页时遇到的问题
    @app.route('/signup',methods=['GET','POST'])defsecret():  form3=SecretForm()  ifrequest.method=='POST':    secret=form3.secret.data    ifsecret=='111111':      returnredirect(ur......
  • C++ //练习 11.14 扩展你在11.2.1节练习(第378页)中编写的孩子姓到名的map,添加一个pair
    C++Primer(第5版)练习11.14练习11.14扩展你在11.2.1节练习(第378页)中编写的孩子姓到名的map,添加一个pair的vector,保存孩子的名和生日。环境:LinuxUbuntu(云服务器)工具:vim 代码块/************************************************************************* >Fil......
  • 数码摄影基础入门,新手摄影资料大全
    一、资料前言本套新手摄影资料,大小2.44G,共有125个文件。二、资料目录(一)、新手摄影基础入门7小时精通数码单反摄影百种技巧.pdfCanon单反摄影入门.pdf[摄影师的视界——迈克尔弗里曼摄影构图与设计].pdf[数码摄影构图].郑承益.扫描版.pdf《10天学通摄影入门教程》.p......
  • 数码相框-显示JPG图片
    LCD控制器会将LCD上的屏幕数据映射在相应的显存位置上。​​通过libjpeg把jpg图片解压出来RGB原始数据。libjpeg是使用c语言实现的读写jpeg文件的库。使用libjpeg的应用程序是以"scanline"为单位进行图像处理的。libjpeg解压图片的步骤:​​‍libjpeg的使用DirectoryList......
  • 编写一款2D CAD/CAM软件(五)视图
    j-view模块目录配置:JCadincludej-viewj-view.hj-viewprjCMakeLists.txtsrcj-view.cppCMakeLists.txt存在多种计算机图形学的引擎,用于将图形绘制到显卡缓存并显示出来。有些引擎使用CPU的能力,有些则充分发挥GPU的......
  • 基于EP4CE6F17C8的FPGA可调校数码管时钟实例
    一、电路模块1、数码管开发板板载了6个数码管,全部为共阳型,原理图如下图所示,段码端引脚为DIG[0]~DIG[7]共8位(包含小数点),位选端引脚为SEL[0]~SEL[5]共6位。端口均为低电平有效。其实物图如下所示。数码管引脚分配见下表。2、时钟晶振开发板板载了一个50MHz的有源晶振,为系统......
  • 使用OpenCV和PyQT编写的图片显示器,实现图片选择显示和保存
    使用OpenCV和PyQT编写的图片显示器简要效果代码简要为了避免重复编写pyqt控件,先写好此代码,方便使用。实现了以下基础功能:选择图片显示图片保存图片效果选择图片:显示图片:保存图片:代码importcopyimportcv2importsysfromPyQt5.QtWidgetsimport(......
  • 【个人笔记】如何用 Python 编写激活码解锁程序
    目录前言第一步:编写激活码解锁程序(激活码.py)第二步:修改需要解锁的程序(1.py) 总结前言在软件开发中,有时候我们需要设计一种机制来保护程序,例如通过激活码来控制程序的使用权限。本文将介绍如何使用Python编写一个简单的激活码解锁程序,以及如何修改另一个程序来检测是否......