100ASK_IMX6ULL-PRO 数码相框扩展项目:支持打开阅读 TXT 文件

背景说明

本篇内容基于百问网嵌入式Linux项目数码相框与文件浏览器嵌入式Linux电子书阅读器

需求:在文件浏览器界面中支持双击打开TXT类型文件,进入新界面进行文本阅读和翻页控制。

实现思路说明

浏览器界面中响应双击操作,识别TXT类型文件成功后进入阅读器界面。可参考项目中图片类型(BMP,JPG,PNG)文件的处理逻辑

else if (isTextFileSupported(tPageParams.strCurPictureFile)){
    // 支持文本文件的编码格式
    DBG_PRINTF("点击打开文件 %s\n", tPageParams.strCurPictureFile);
    tPageParams.iPageID = ID("browse");
    Page("reading")->Run(&tPageParams);
    ShowBrowsePage(&g_tBrowsePageMenuIconsLayout);
}

核心内容:阅读器界面的设计与实现

参考项目数码相框与文件浏览器中界面框架的设计(主界面和浏览器界面),主要包含:

  • UI 部分:通过Layout布局设计按钮和内容显示区域
  • 事件处理:捕获输入事件并响应,完成业务逻辑

业务逻辑的设计实现参考 嵌入式Linux电子书阅读器

  • 内容显示:在指定区域内显示文本文字,直到满页或者文件尾记为一页。

  • 按钮响应:

    • “返回”:退出阅读器界面,跳转到浏览器界面
    • “上一页”:刷新显示文本内容逻辑上前面的部分,区域满屏记为上一页。当前为第一页则不响应处理。
    • “下一页”:刷新显示文本内容逻辑上后面的部分,区域满屏或者达到文件尾记为下一页。

内容显示:

static int ShowTextInReadingPage(PT_VideoMem ptVideoMem, char *strFileName)
{
	int iError;

	// 打开文本文件
	strncpy(g_tFileMap.strFileName, strFileName, 256);
	g_tFileMap.strFileName[255] = '\0';
    iError = MapFile(&g_tFileMap);
    if (iError)
    {
        DBG_PRINTF("MapFile %s error!\n", strFileName);
        return 0;
    }

	// 确认文件编码
	g_ptEncodingOprForFile = SelectEncodingOprForFile(g_tFileMap.pucFileMapMem);
    if (!g_ptEncodingOprForFile)
    {
        DBG_PRINTF("SelectEncodingOprForFile %s error!\n", strFileName);
        UnMapFile(&g_tFileMap);
        return 0;
    }
  
	// 第一个显示字符紧接在文件头后面
    g_pucLcdFirstPosAtFile = g_tFileMap.pucFileMapMem + g_ptEncodingOprForFile->iHeadLen;


    // 在打开的文件中标记索引位置,在显示设备上逐行逐个显示字符
	// 自动记录当前的进度,重新打开时恢复
	unsigned char *pucTextFileMemCurPos;

	if (g_ptCurPage)
	{
		pucTextFileMemCurPos = g_ptCurPage->pucLcdFirstPosAtFile;	// 上一次阅读界面的第一个字符
	}
	else
	{
		pucTextFileMemCurPos = g_pucLcdFirstPosAtFile;				// 文本文件中的第一个字符
	}
	iError = ShowOnePage(pucTextFileMemCurPos, ptVideoMem);

    return 0;
}

函数ShowOnePage实现的功能:

  • 逐个获取文件中的字符

    • 处理特殊字符,如换行

    • 对于文字字符,通过字符文件获取矢量位图,调整位置后显示到 LCD 设备上

      • 项目已支持相关接口: GetCodeFrmBuf通过字符文件获取矢量位图,MergeOneFontToVideoMem显示单个字符到 LCD 设备上
  • 到达文件尾部或者满页,则完成一页显示

翻页控制

记录显示的每一页:

typedef struct PageDesc {
	int iPage;
	unsigned char *pucLcdFirstPosAtFile;
	unsigned char *pucLcdNextPageFirstPosAtFile;
	struct PageDesc *ptPrePage;
	struct PageDesc *ptNextPage;
} T_PageDesc, *PT_PageDesc;

通过链表管理显示页面,实现逻辑上的翻页显示:

static void RecordPage(PT_PageDesc ptPageNew)
{
	PT_PageDesc ptPage;
	
	if (!g_ptPages)
	{
		g_ptPages = ptPageNew;
	}
	else
	{
		ptPage = g_ptPages;
		while (ptPage->ptNextPage)
		{
			ptPage = ptPage->ptNextPage;
		}
		ptPage->ptNextPage   = ptPageNew;
		ptPageNew->ptPrePage = ptPage;
	}
}

效果展示

posted @ 2024-11-25 18:03  libq8  阅读(95)  评论(0)    收藏  举报