Skip to content

Commit 06a402d

Browse files
committed
添加《图像查看器》教程
1 parent 62f3622 commit 06a402d

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

78 files changed

+3815
-6
lines changed

docs/tutorial/03-kantu/01-intro.md

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
# 介绍
2+
3+
LCUI 是一个用于为桌面应用构建图形界面的 C 开发库,与其它 GUI 库/框架相比,功能、文档和例子都很少,这增加了开发者的使用难度,同时也使得开发者难以全面、准确地评估其实际的应用能力和潜力。
4+
5+
基于此,为了帮助开发者更好地认识和掌握 LCUI 的特性与优势,本教程以开发图像查看器为例,深入且直观地展示 LCUI 在实际项目中的各项能力。
6+
7+
之所以选择图像查看器,是因为作者曾经在使用 Windows 系统自带的“照片”应用时经常出现卡死、无法启动、无法缩放、启动缓慢等问题,于是就想开发一个启动迅速的图像查看器来取代它作为日常看图的工具。
8+
9+
## 实现的是什么程序?
10+
11+
我们将构建一个简单的图像查看器,包含以下界面:
12+
13+
1. **介绍**:展示应用图标、名称、描述、版本号和使用说明。
14+
2. **图像查看**:显示图像,并支持通过鼠标和键盘操作切换图像、放大或缩小。
15+
3. **工具栏**:位于图像查看界面底部,显示一些快捷按钮和状态信息。
16+
4. **影片**:显示当前目录下的图像列表。
17+
5. **信息**:显示图像信息。
18+
19+
程序的主要特点如下:
20+
21+
1. 可设置为图像文件的默认打开方式。
22+
2. 启动快、图像加载快、内存占用少,对一般大小的图像能做到秒开。
23+
3. 支持切换上一张和下一张图像。
24+
4. 打开大尺寸图像时,实时显示图像加载进度。
25+
5. 预览其它图像的缩略图。
26+
6. 查看图像基本信息。
27+
28+
你可以从[这里](https://github.com/lcui-dev/kantu)下载源码,并按照 README.md 文档构建、运行和体验该程序。
29+
30+
![预览](preview.jpg)
31+
32+
## 你会学到什么?
33+
34+
- 分析需求并设计程序
35+
- LCUI 开发的基础知识
36+
- LCUI 开发工具和库的基本用法
37+
- 使用 TypeScript 描述界面
38+
- UI 组件的编写方法
39+
- 多线程编程
40+
41+
## 适宜人群
42+
43+
- 具备 C/C++ 语言编程基础
44+
- 了解 HTML、CSS、JavaScript
45+
- 想尝试另一种桌面应用开发方式
46+
47+
## 前置知识
48+
49+
已阅读 LCUI 的[快速入门](https://lcui.org/docs/guide/quick-start/)[TypeScript](https://lcui.org/docs/guide/typescript) 文档。

docs/tutorial/03-kantu/02-setup.md

Lines changed: 142 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,142 @@
1+
# 配置开发环境
2+
3+
本章节将逐步指导你完成开发环境的配置,并创建一个最小化的图像查看器项目。完成本章后你将能够:
4+
5+
- 使用 LCUI 命令行工具创建项目
6+
- 使用 xmake 构建、运行、打包项目
7+
- 掌握 LCUI 模板项目的定制方法
8+
9+
## 系统要求
10+
11+
在开始之前,请确保你的系统符合以下要求:
12+
13+
- 已安装 Node.js 20.11.0 或以上版本。[点此下载](https://nodejs.org/en)
14+
- 操作系统:Windows。
15+
- 已安装以下工具:
16+
- [Git 版本管理工具](https://git-scm.com/)
17+
- [XMake 构建工具](https://xmake.io/)
18+
- [LCUI 命令行工具](https://github.com/lcui-dev/lcui-cli): 输入命令 `npm -g install @lcui/cli` 安装
19+
20+
## 创建项目
21+
22+
在你的项目目录内打开命令行窗口,输入以下命令创建一个名为 kantu 的项目:
23+
24+
```bash
25+
lcui create kantu
26+
```
27+
28+
## 构建项目
29+
30+
进入项目目录:
31+
32+
```bash
33+
cd kantu
34+
```
35+
36+
使用 LCUI 命令行工具构建:
37+
38+
```bash
39+
lcui build
40+
```
41+
42+
LCUI 命令行工具将会转换项目内的 TypeScript 模块为 C 源文件,然后调用 xmake 构建项目。
43+
44+
## 运行项目
45+
46+
```bash
47+
xmake run
48+
```
49+
50+
你将会看到示例程序的窗口。
51+
52+
![setup](setup.png)
53+
54+
## 打包和发布项目
55+
56+
运行以下命令打包项目的可执行文件和资源文件:
57+
58+
```bash
59+
xmake pack
60+
```
61+
62+
生成的安装包在 build/xpack/app 目录下,可用于发布。
63+
64+
## 配置编辑器
65+
66+
如果你使用的代码编辑器是 Visual Studio Code,为了让编辑器正确加载头文件,请修改 C/C++ 配置 - IntelliSense 配置中的 includePath 配置项,添加 LCUI 的头文件目录路径,像这样:
67+
68+
```json
69+
{
70+
"configurations": [
71+
{
72+
"name": "Win32",
73+
"includePath": [
74+
"${workspaceFolder}/vendor/*/lib/*/include",
75+
"${workspaceFolder}/vendor/*/include"
76+
]
77+
}
78+
]
79+
}
80+
```
81+
82+
## 定制项目
83+
84+
我们已经体验了该示例项目,但项目内的示例代码对我们要开发的程序并没有用处,因此我们需要做些调整:
85+
86+
- 创建 src 目录,用于存放后续编写的源码
87+
- 移动 app/global.css 文件到 src 目录内,将内容覆盖为:
88+
```css title="src/global.css"
89+
@tailwind components;
90+
@tailwind utilities;
91+
92+
* {
93+
box-sizing: border-box;
94+
}
95+
```
96+
- 删除 app 目录
97+
- 更改 package.json 文件中的名称和描述
98+
- 更改 xmake.lua 文件中的项目名称、版本、描述、源文件路径等信息,例如:
99+
```lua title="xmake.lua"
100+
set_project("kantu")
101+
set_version("0.1.0")
102+
...
103+
104+
target("kantu")
105+
...
106+
add_files("src/**.c")
107+
108+
xpack("kantu")
109+
set_title("kantu")
110+
set_description("An image viewer")
111+
set_basename("kantu-v$(version)")
112+
add_targets("kantu")
113+
...
114+
```
115+
- 更改 version.rc 文件中的文件描述、公司信息、版本号等信息,例如:
116+
```c
117+
BEGIN
118+
VALUE "CompanyName", "留视软件"
119+
VALUE "FileDescription", "看图"
120+
VALUE "FileVersion", "0.1.0.0"
121+
VALUE "InternalName", "kantu.exe"
122+
VALUE "LegalCopyright", "Copyright (C) 2024-present, lcui.org"
123+
VALUE "OriginalFilename", "kantu.exe"
124+
VALUE "ProductName", "看图"
125+
VALUE "ProductVersion", "0.1.0.0"
126+
END
127+
BLOCK "040904b0"
128+
BEGIN
129+
VALUE "CompanyName", "LC's Software"
130+
VALUE "FileDescription", "KanTu"
131+
VALUE "FileVersion", "0.1.0.0"
132+
VALUE "InternalName", "version.rc"
133+
VALUE "LegalCopyright", "Copyright (C) 2024-present, lcui.org"
134+
VALUE "OriginalFilename", "kantu.exe"
135+
VALUE "ProductName", "KanTu"
136+
VALUE "ProductVersion", "0.1.0.0"
137+
END
138+
```
139+
140+
## 小结
141+
142+
搭建 LCUI 项目比较简单,使用 `lcui create` 命令创建的项目已经包含构建、打包、运行所需配置,我们只需要做些简单的调整就可以开始开发。

docs/tutorial/03-kantu/03-design.md

Lines changed: 201 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,201 @@
1+
# 设计程序架构
2+
3+
本教程的最终目标是带领你开发一个图像查看器程序。在此之前,我们需要先弄清楚它需要具备哪些功能,并设计这些功能的实现方法。本章节将一步步带你了解如何分析需求,并将这些需求转换为具体的开发事项。通过这些步骤,我们可以更好地评估项目的整体工作量,让开发进度更加可控,每完成一项开发任务都能感受到进步,离最终目标更进一步。
4+
5+
## 功能需求分析
6+
7+
在体验过程序后我们可以知道这些细节:
8+
9+
- **界面切换:** 直接打开程序,显示的是介绍界面。将图像文件的打开方式设置为该程序,显示的是图像查看界面。
10+
- **自适应比例:** 打开图像后,缩放的尺寸适应窗口内可见区域。
11+
- **进度条:** 打开尺寸很大的图像时,会有进度条显示。
12+
- **上下切换:** 如果有下一张图像,移动鼠标指针到右侧区域时会显示“下一张”按钮,点击可切换到下一张图像。“上一张”按钮也类似。
13+
- **缩放比例显示:** 界面底栏上有显示当前缩放比例,缩放时会更新。
14+
- **工具栏:** 展示图像分辨率、文件大小、缩放比例、缩放控件、全屏按钮。
15+
- **鼠标滚轮缩放:** 滚动鼠标滚轮可以缩放图像,鼠标指针在缩放前后仍指向图像中的同一处。
16+
- **移动可见区域:** 放大图像后按住鼠标左键可拖动浏览区域。
17+
- **按键控制缩放:** 按下 <kbd>+</kbd> 和 <kbd>-</kbd> 可以缩放图像。
18+
- **信息:** 展示文件名、修改时间、描述、大小信息、文件路径。
19+
- **影片:** 展示当前目录内的图像列表,点击缩略图可快速查看。
20+
21+
这些需求主要集中在界面交互上,而在代码实现上,核心功能逻辑与用户界面逻辑应该分开,这有助于后续对界面进行更新、调整,甚至迁移至其它 GUI 开发库。
22+
23+
## 功能库
24+
25+
按照上述思路,图像缩放相关逻辑可划分为控制器(Controller),图像文件的收集功能和上下一张切换功能可划分为收集器(Collector),而图像的文件名、分辨率、修改时间等信息的读取功能则可划分为文件信息读取器(FileInfoReader)。
26+
27+
### 图像缩放控制器
28+
29+
控制器提供缩放比例的控制能力,包括放大、缩小、原始比例、自适应比例。同时还应记录可见区域的左上角坐标和焦点坐标,以便放大图像后能够移动可见区域,并以焦点坐标为中心进行缩放。
30+
31+
### 图像文件收集器
32+
33+
收集器提供图像文件列表和上下切换能力。它在打开图像后开始工作,先遍历图像文件所处目录内的所有文件,将包含图像后缀名的文件路径添加到列表中,然后确定当前打开的图像在列表中位置,最后通知图像查看界面启用图像切换功能。
34+
35+
### 文件信息读取器
36+
37+
文件信息读取器提供图像信息和文件信息的读取能力。在打开图像时由异步工作线程执行文件读取任务,读取的信息会在工具栏和信息面板展示。
38+
39+
## 用户界面
40+
41+
我们使用 LCUI 库为应用程序构建用户界面,这部分可细分为标记、布局、交互和图标库。
42+
43+
### 标记
44+
45+
标记(Markup)是指使用标记语言编写的文本,用于描述文档的结构和格式。它通过在文本中插入特定的标记(标签)来指示文档中的元素类型和其它相关信息。LCUI 支持在运行时从 XML 文件加载界面,借助 `@lcui/cli` 开发工具还可支持更多的格式,而且能将其编译为 C 代码,从而更高效地构建界面。
46+
47+
**XML**
48+
49+
XML 文件内容写法如下:
50+
51+
```xml
52+
<?xml version="1.0" encoding="UTF-8" ?>
53+
<lcui-app>
54+
<resource type="text/css" src="home.css"/>
55+
<resource type="application/font-ttf" src="iconfont.ttf"/>
56+
<ui>
57+
<text>Enter a message and save it.</text>
58+
<textedit ref="input-message" placeholder="eg: hello, world!" />
59+
<button ref="btn-save-message">Save</button>
60+
<text ref="feedback" class="feedback">Message has been saved!</text>
61+
</ui>
62+
</lcui-app>
63+
64+
```
65+
66+
你可以使用 `ui_xml.h` 头文件提供的 `ui_load_xml_file()` 函数加载 XML 文件。
67+
68+
```c
69+
#include <ui_xml.h>
70+
71+
...
72+
73+
ui_widget_t *wrapper = ui_load_xml_file("path/to/file.xml");
74+
```
75+
76+
:::warning
77+
这一功能可能会在未来的版本中移除,因为 `@lcui/cli` 能够将 XML 转译成直接构建界面的 C 代码,这比在运行时调用 libxml2 库的接口解析 XML 文档再构建界面的性能更高。
78+
:::
79+
80+
**TypeScript**
81+
82+
LCUI 的开发工具 `@lcui/cli` 内置 TypeScript 预处理器,你可以使用 TypeScript 语言结合 JSX 语法和 React 库编写 LCUI 组件。TypeScript 预处理器在处理 TypeScript 模块时会将其转换成 JavaScript 模块再执行模块内导出的组件函数,最终将组件函数执行过程中产生的数据和返回结果转换为 C 代码。
83+
84+
:::note
85+
详见 [TypeScript](https://lcui.org/docs/guide/typescript) 文档。
86+
:::
87+
88+
**JSON**
89+
90+
@lcui/cli 编译 XML、YAML、TSX 的中间结果是 JSON 格式的数据,最终由 JSON 编译器将结果转换成 C 代码。
91+
92+
JSON 写法如下:
93+
94+
```json
95+
{
96+
"name": "lcui-app",
97+
"children": [
98+
{
99+
"name": "resource",
100+
"attributes": { "type": "text/css", "src": "home.css" }
101+
},
102+
{
103+
"name": "resource",
104+
"attributes": {
105+
"type": "application/font-ttf",
106+
"src": "iconfont.ttf"
107+
}
108+
},
109+
{
110+
"name": "ui",
111+
"children": [
112+
{
113+
"name": "text",
114+
"children": [
115+
{ "type": "text", "text": "Enter a message and save it." }
116+
]
117+
},
118+
{
119+
"name": "textinput",
120+
"attributes": {
121+
"ref": "input-message",
122+
"placeholder": "eg: hello, world!"
123+
}
124+
},
125+
{
126+
"name": "button",
127+
"attributes": { "ref": "btn-save-message" },
128+
"children": [{ "type": "text", "text": "Save" }]
129+
},
130+
{
131+
"name": "text",
132+
"attributes": { "ref": "feedback", "class": "feedback" },
133+
"children": [{ "type": "text", "text": "Message has been saved!" }]
134+
}
135+
]
136+
}
137+
]
138+
}
139+
```
140+
141+
**YAML**
142+
143+
YAML 的写法比 JSON 更精简:
144+
145+
```yaml
146+
name: lcui-app
147+
children:
148+
- name: resource
149+
attributes:
150+
type: text/css
151+
src: home.css
152+
- name: resource
153+
attributes:
154+
type: application/font-ttf
155+
src: iconfont.ttf
156+
- name: ui
157+
children:
158+
- name: text
159+
children:
160+
- type: text
161+
text: Enter a message and save it.
162+
- name: textinput
163+
attributes:
164+
ref: input-message
165+
placeholder: "eg: hello, world!"
166+
- name: button
167+
attributes:
168+
ref: btn-save-message
169+
children:
170+
- type: text
171+
text: Save
172+
- name: text
173+
attributes:
174+
ref: feedback
175+
class: feedback
176+
children:
177+
- type: text
178+
text: Message has been saved!
179+
```
180+
181+
### 交互
182+
183+
LCUI 基于事件驱动,用户在界面上的操作会触发事件。我们可以通过处理这些事件来响应鼠标和键盘操作,同时还可以利用 LCUI 提供的操作函数更新界面,向用户反馈操作结果。
184+
185+
### 布局
186+
187+
LCUI 支持流式布局(Flow Layout)和弹性盒子布局(Flexible Box)两种布局,用法和效果与网页的布局相似,能满足一般界面的布局需求。
188+
189+
### 样式
190+
191+
LCUI 的 CSS 引擎支持基础的 CSS 规则,借助 `@lcui/cli` 工具,我们还可以使用 CSS Modules、Tailwind CSS、Sass 这几种技术来组织和管理 CSS 样式。
192+
193+
### 图标库
194+
195+
LCUI 的 `@lcui/react-icons` 图标库基于 [fluentui-system-icons](https://github.com/microsoft/fluentui-system-icons),与 Windows 系统应用程序用的是同一套图标库,包含大量常用图标库,已经能满足我们的程序的图标需求。
196+
197+
## 小结
198+
199+
经过上述分析和设计,我们对各个功能的需求和实现方案有了大致的了解。程序的代码划分为两大部分。核心库部分包含三个功能模块:控制器、收集器和文件信息读取器。用户界面部分较为复杂,在界面标记方式上选择使用 TypeScript 编写界面,使用 `@lcui/react-icons` 图标库中的图标来装饰界面。在界面交互上,则通过处理鼠标和键盘事件来响应用户操作。
200+
201+
接下来我们将进一步地开发每一个功能。

0 commit comments

Comments
 (0)