浏览器
前言
本教程将通过一个简单的仿浏览器界面的程序,向你介绍关于构建图形界面程序的基础知识,掌握这些知识后,你将会对图形界面开发有更加深刻的理解。
你可以提前预览我们要写的程序的最终效果,它的源代码已经上传到了 GitHub 和码云上,你可以试着下载、编译和运行它。如果你看不懂其中的代码,或不知道它是被如何设计出来的,别担心!接下来的教程会一步一步帮助你理解图形界面程序的开发方式。
需求分析
相较于其它开发库或框架的示例程序而言,我们开发的程序更加复杂一些,因此,我们有必要在开发前花点时间思考这个程序具体需要什么功能,又该怎么实现这些功能。
以 Chrome 浏览器为参考对象,我们需要实现以下功能:
- 路由导航:能够前进、后退、主页、刷新、输入地址直接跳转,如果未找到与地址匹配的页面则展示 404 页面
- 多标签页:每个标签页都能够独立导航,可以新建和关闭,点击选项卡可切换到对应标签页面
- 示例页面:由于我们开发的程序侧重点在图形界面开发上,不具备网络通信功能,因此需要添加几个示例页面作为浏览对象,来模拟实现 Chrome 浏览器的页面浏览功能。示例页面有:
- 新标签页:打开新标签后展示的页面,提供其它示例页面的快捷入口
- 欢迎页:展示简单的内容,作为主页
- 关于页:展示关于这个程序的名称、图标、版本号等信息
- 文件页:展示当前目录内的文件列表,包括文件名、修改时间和大小,点击目录后展示该目录内的文件列表
- 404 页:提示当前页面无法访问,并引导用户返回主页
我们的程序的图形界面需要包含以下元素:
- 选项卡栏:每个选项卡对应一个标签页,选项卡包含图标、页面标题、关闭按钮,最右侧有个新建标签页按钮
- 导航栏:包含前进、后退、刷新和主页这四个导航按钮,以及地址输入框、设置菜单按钮
- 内区域:展示当前浏览的页面的内容
设计与实现
由于我们开发的程序的大部分源代码都是用于实现图形界面的,因此,这里主要讲述图形界面上的设计与实现方法。
组件化
在研究过 Chrome 浏览器的界面后,我们可以知道它的界面结构如下:
- 主界面
- 选项卡栏
- 导航栏
- 内容区
考虑到每个标签页都有自己的选项卡、导航栏和内容区,我们应该将导航栏和内容区域移入到标签页中,结果如下图所示:
那么,我们需要开发的组件有如下几个:
- 主界面 (Browser):负责管理和切换标签页,实现选项卡与标签页之间的通信
- 选项卡 (FrameTab):负责展示对应标签页的标题和状态,在点击关闭按钮后通知主界面销毁标签页
- 标签页 (Frame):负责呈现导航栏和页面内容,实现路由导航功能以及界面交互
按照常规做法,把标签页拆分成导航栏和内容区似乎会更好一些,但考虑到组件之间的通信成本和开发成本,组件化到标签页已经足够,因为标签页除了导航栏外已经没有值得组件化的东西了。选项卡栏亦是如此。
布局
接下来我们再试着找出界面元素的排列规则:
如上图所示,红色边框标记的元素是横向布局,而绿色边框标记的元素则是纵向布局。从中可知,主界面布局方向为纵向,选项卡栏和标签页从上到下排列,选项卡栏高度固定,标签页面高度自动占满剩余空间。标签页内的导航栏和内容区也是如此。导航栏中的元素布局方向为横向,按钮宽度固定,地址栏输入框的宽度自动占满剩余空间。
数据结构
如何存储多个标签页的数据?
正常情况下,标签页数量是比较少的,对读写性能要求很低,因此可以选择用链表来存放。
标签页的数据应该包含什么?
为了便于管理标签页数据、展示页面标题和状态、实现组件间的通信,标签页的数据应该包含编号、标题、状态、标签页和主界面的 UI 元素对象的引用。伪代码如下:
struct Page {
number id;
string title;
boolean loading;
UIElement tab;
UIElement frame;
UIElement browser;
};
选型
在准备开发前,我们可以花一些时间调查和研究开源社区上是否有其他开发者开发的库可供使用,选择合适的开发库有助于提升开发效率和降低开发成本。
图形界面开发库:
LCUI,C 语言编写的图形界面开发库,支持 CSS 样式和 Flex 布局。以它现有的功能足以实现我们的程序的图形界面。
路由管理器:
LCUI Router,LCUI 的官方路由管理器,用于解决 LCUI 应用内多视图的切换和状态管理问题。我们可以用它实现浏览器的路由导航功能。
组件库:
LC Design,专为 LCUI 设计的组件库,提供基础排版样式、布局系统和实用工具 CSS 类,以及图标、按钮、下拉菜单等组件。
开发工具:
- LCPkg —— 包管理工具,可以用来下载安装 LCUI 及相关库的二进制包。
- LCUI CLI —— LCUI 的命令行开发工具,用于简化 LCUI 应用程序项目的开发。
- CMake —— 跨平台构建工具,用于构建我们的程序。