awtk/docs/theme.md

266 lines
9.8 KiB
Markdown
Raw Normal View History

2019-12-11 09:56:47 +08:00
## AWTK 中的主题
2018-04-01 18:19:28 +08:00
2019-12-11 09:56:47 +08:00
设计漂亮的界面并非程序员的强项AWTK 通过主题提供这样一种机制,让设计漂亮的界面变得非常容易。通过主题,可以改变控件的背景颜色、边框颜色、字体颜色、字体、字体大小、背景图片、背景图片的显示方式和图标等属性。同时 AWTK 也提供了一些主题重用的机制,让主题文件的开发和维护变得容易。
2018-04-01 18:19:28 +08:00
### 一、主题的结构
2019-12-11 09:56:47 +08:00
AWTK 的主题按控件进行分类,每种控件可以有多种不同的风格,每种风格下又有不同状态下的配置。比如:
2018-04-01 18:19:28 +08:00
```
2018-07-17 11:27:14 +08:00
<button bg_image_draw_type="3patch_x" text_color="blue">
<style name="default" border_color="#a0a0a0" text_color="black">
<normal bg_color="#f0f0f0" />
<pressed bg_color="#c0c0c0" />
<over bg_color="#e0e0e0" />
<disable bg_color="gray" text_color="#d0d0d0" />
2018-04-01 18:19:28 +08:00
</style>
2018-07-17 11:27:14 +08:00
<style name="green_btn" >
<normal bg_image="green_btn_n" />
<pressed bg_image="green_btn_p" />
<over bg_image="green_btn_o" />
2018-04-01 18:19:28 +08:00
</style>
2018-07-17 11:27:14 +08:00
<style name="red_btn">
<normal bg_image="red_btn_n" />
<pressed bg_image="red_btn_p" />
<over bg_image="red_btn_o" />
2018-04-01 18:19:28 +08:00
</style>
</button>
```
2019-12-11 09:56:47 +08:00
上面是按钮的主题配置(你可以自由增加自己需要的),其中定义了三种不同的按钮风格:
2018-04-01 18:19:28 +08:00
* default 为缺省的按钮风格。
2018-07-17 11:27:14 +08:00
* green_btn 是用图片实现的绿色系按钮。
* red_btn 是用图片实现的红色系按钮。
2018-04-01 18:19:28 +08:00
2019-12-11 09:56:47 +08:00
> 主题的各个属性,如果出现在控件中,则为该控件下各个 style 的缺省值。如果出现在 style 中,则为该 style 的下各种状态的缺省值。这样可以实现类似继承的重用机制。
2018-04-01 18:19:28 +08:00
>
2019-12-11 09:56:47 +08:00
> 同一控件可以出现多次(如上面的 button 出现了两次),有利于实现配置共享,让维护工作更简单。
2018-04-01 18:19:28 +08:00
2020-07-07 20:49:18 +08:00
参考:
2020-09-01 07:06:09 +08:00
* [完整示例 (default.xml)](https://github.com/zlgopen/awtk/blob/master/demos/assets/raw/styles/default.xml)
2020-07-07 20:49:18 +08:00
* [控件状态定义](manual/widget_state_t.md)
2018-04-01 18:19:28 +08:00
### 二、主题的属性
2018-12-26 11:10:26 +08:00
#### 基本属性
2018-07-17 11:27:14 +08:00
* bg\_color 背景颜色。
* fg\_color 前景颜色。用途视具体控件而定,如进度条已完成部分的颜色使用前景颜色。
* text\_color 文字的颜色
2018-11-07 17:47:28 +08:00
* tips\_text\_color 提示文字的颜色
* border\_color 边框颜色
2019-12-11 09:56:47 +08:00
* border 边框类型,取值为 left/right/top/bottom 和 all以及它们的组合。
2018-07-17 11:27:14 +08:00
* font\_name 字体的名称。
* font\_size 字体的大小。
2019-12-11 09:56:47 +08:00
* font\_style 字体的风格目前还不支持取值为italic/bold/underline。可用『,』分隔。
* text\_align\_h 文本的水平对齐方式。取值为 left/center/right。
* text\_align\_v 文本的垂直对齐方式。取值为 top/middle/bottom。
2018-07-17 11:27:14 +08:00
* bg\_image 背景图片。
2019-12-11 09:56:47 +08:00
* bg\_image\_draw\_type 背景图片的 [绘制方式](image_draw_type.md)。
2018-07-17 11:27:14 +08:00
* fg\_image 前景图片。用途视具体控件而定,如进度条已完成部分的图片使用前景图片。
2019-12-11 09:56:47 +08:00
* fg\_image\_draw\_type 前景图片的 [绘制方式](image_draw_type.md)。
* icon 图标。用途视具体控件而定,如 check\_button 的图标,按钮上的图标,对话框标题上的图标。
* active\_icon active 图标。用途视具体控件而定,目前 slideview 的页面指示器会用到。
* icon\_at 图标的位置,取值为 left/right/top/bottom。
* x\_offset 在 X 坐标方向上的偏移(可用来实现按下的效果)。
* y\_offset 在 Y 坐标方向上的偏移(可用来实现按下的效果)。
* margin 边距(边距目前只影响 icon/text不影响子控件子控件的边距由布局算法参数决定
2019-05-14 17:29:48 +08:00
* margin_top 上边距。
* margin_bottom 下边距。
* margin_left 左边距。
* margin_right 右边距。
2019-12-11 09:56:47 +08:00
* spacer 间距(目前仅用于文本和图标之间)。
2020-09-02 07:40:29 +08:00
* round\_radius 背景和边框的圆角半径。
* round\_radius\_top\_left 背景和边框的左上角圆角半径。
* round\_radius\_top\_right 背景和边框的右上角圆角半径。
* round\_radius\_bottom\_left 背景和边框的左下角圆角半径。
* round\_radius\_bottom\_right 背景和边框的右下角圆角半径。
2019-12-11 09:56:47 +08:00
* border\_width 边框线宽(仅在定义 WITH\_VGCANVAS 时有效)。
2020-01-02 14:38:36 +08:00
* self\_layout 自身布局参数。请参考 [控件布局参数文档](layout.md)
* children\_layout 子控件布局参数。请参考 [控件布局参数文档](layout.md)
2018-04-01 18:19:28 +08:00
2019-12-11 09:56:47 +08:00
> 颜色可使用标准名称,#开头的 16 进制值和 rgba 合成的值。
2018-04-01 18:19:28 +08:00
2019-12-11 09:56:47 +08:00
参考:
2019-12-17 16:15:20 +08:00
* [AWTK 中图片的绘制方式](image_draw_type.md)
2019-12-11 09:56:47 +08:00
* [如何在主题文件中写控件布局参数](how_to_write_layout_params_in_style.md)
2018-04-01 18:19:28 +08:00
2018-12-26 11:10:26 +08:00
#### 扩展属性
第三方扩展控件可以扩展控件特有的属性,遵循下列规则即可。
* 名称长度不超过 TK\_NAME\_LEN。
2019-12-11 09:56:47 +08:00
* 名称带有 color 视为颜色格式的值。
* 名称带有 name/image 视为字符串格式的值。
2018-12-26 11:10:26 +08:00
* 其它视为整数格式的值。
2018-04-01 18:19:28 +08:00
### 三、编译主题
2019-12-11 09:56:47 +08:00
主题用 XML 文件编写,然后用 themegen 生成 C 常量数据,并加入资源管理器,才能在程序中使用。
2018-04-01 18:19:28 +08:00
2019-12-11 09:56:47 +08:00
* 生成 C 常量数据
2018-04-01 18:19:28 +08:00
```
./bin/themegen input output
```
2019-12-11 09:56:47 +08:00
> 参考 update\_res.sh
2018-04-01 18:19:28 +08:00
* 加入资源管理器
```
#include "res/src/theme/default.data"
...
resource_manager_add(theme_default);
```
> 参考 demos/resource.c
2019-12-11 09:56:47 +08:00
### 四、为控件指定 style
2018-04-01 18:19:28 +08:00
2019-12-11 09:56:47 +08:00
* 在代码中,使用函数 widget\_use\_style 指定。
2018-04-01 18:19:28 +08:00
```
ok = button_create(dialog->client, 20, 80, 80, 30);
widget_set_text(ok, L"Go");
2018-07-17 11:27:14 +08:00
widget_use_style(ok, "green_btn");
2018-04-01 18:19:28 +08:00
```
2019-12-11 09:56:47 +08:00
* 在 xml 界面描述文件中,使用属性 style 指定。
2018-04-01 18:19:28 +08:00
```
<dialog name="" icon="info" x="10" y="120" w="300" h="160" text="Dialog">
<label name="" x="center" y="middle:-20" w="200" h="30" text="Are you ready?"/>
2018-07-17 11:27:14 +08:00
<button name="ok" style="green_btn" x="10" y="bottom:10" w="40%" h="30" text="Yes"/>
<button name="cancel" style="red_btn" x="right:10" y="bottom:10" w="40%" h="30" text="No"/>
2018-04-01 18:19:28 +08:00
</dialog>
```
2018-06-16 07:12:55 +08:00
### 五、每个窗口支持独立的主题
2019-12-11 09:56:47 +08:00
像微信小程序那样AWTK 中每个窗口(包括对话框和其它窗口)可以有自己的主题文件。
2018-07-03 13:49:58 +08:00
2019-12-11 09:56:47 +08:00
* 通过窗口的 theme 属性来指定窗口的主题文件名(方便多个窗口共用一个主题文件)。
2018-07-03 13:49:58 +08:00
2019-12-11 09:56:47 +08:00
* 如果没有指定 theme 属性,以窗口的 name 属性作为窗口的主题文件名。
2018-06-16 07:12:55 +08:00
* 以窗口自己的主题文件优先,其次为缺省的主题文件。
2019-12-11 09:56:47 +08:00
> 参考dialog1.xml
2018-06-16 07:12:55 +08:00
2019-06-03 18:35:42 +08:00
### 六、inline style
2019-12-11 09:56:47 +08:00
主题数据是只读的,它的好处是速度快,占用内存少。但在一些特殊情况下,我们希望通过函数直接修改控件的 style或者在 UI 描述的 XML 文件中直接写 style。我们把这类 style 称为 inline style具体用法如下
2019-06-03 18:35:42 +08:00
2019-12-11 09:56:47 +08:00
* 在 XML UI 描述文件中使用 inline style。
2019-06-03 18:35:42 +08:00
2019-12-11 09:56:47 +08:00
控件的属性名以『style:』开头表示这是一个 inline 属性:
2019-06-03 18:35:42 +08:00
```
2019-12-11 09:56:47 +08:00
style: 状态:名称
2019-06-03 18:35:42 +08:00
```
2019-12-11 09:56:47 +08:00
下面表示设置正常状态的字体大小为 16
2019-06-03 18:35:42 +08:00
```
style:normal:font_size="16"
```
2019-12-11 09:56:47 +08:00
状态可以省略,如果省略,表示正常状态 (normal),下面这个和上面的功能一样:
2019-06-03 18:35:42 +08:00
```
style:font_size="16"
```
完整示例:
```
<label x="0" y="0" w="100%" h="100%" text="Basic Controls" style:font_size="24" style:text_color="green"/>
<button name="dec_value" text="Dec" focusable="true" style:focused:text_color="red"/>
```
2019-12-11 09:56:47 +08:00
* 在 C 代码中使用 inline style。
2019-06-03 18:35:42 +08:00
2019-12-11 09:56:47 +08:00
在 C 代码中可以使用下列函数设置 style
2019-06-03 18:35:42 +08:00
```
/**
* @method widget_set_style_int
2019-12-11 09:56:47 +08:00
* 设置整数类型的 style。
2019-06-03 18:35:42 +08:00
* @annotation ["scriptable"]
* @param {widget_t*} widget 控件对象。
* @param {const char*} state_and_name 状态和名字,用英文的冒号分隔。
* @param {int32_t} value 值。
*
2019-12-11 09:56:47 +08:00
* @return {ret_t} 返回 RET_OK 表示成功,否则表示失败。
2019-06-03 18:35:42 +08:00
*/
ret_t widget_set_style_int(widget_t* widget, const char* state_and_name, int32_t value);
/**
* @method widget_set_style_str
2019-12-11 09:56:47 +08:00
* 设置字符串类型的 style。
2019-06-03 18:35:42 +08:00
* @annotation ["scriptable"]
* @param {widget_t*} widget 控件对象。
* @param {const char*} state_and_name 状态和名字,用英文的冒号分隔。
* @param {const char*} value 值。
*
2019-12-11 09:56:47 +08:00
* @return {ret_t} 返回 RET_OK 表示成功,否则表示失败。
2019-06-03 18:35:42 +08:00
*/
ret_t widget_set_style_str(widget_t* widget, const char* state_and_name, const char* value);
/**
* @method widget_set_style_color
2019-12-11 09:56:47 +08:00
* 设置颜色类型的 style。
2020-09-01 07:06:09 +08:00
*
* > * [state 的取值](https://github.com/zlgopen/awtk/blob/master/docs/manual/widget_state_t.md)
* > * [name 的取值](https://github.com/zlgopen/awtk/blob/master/docs/theme.md)
*
2019-06-03 18:35:42 +08:00
* @annotation ["scriptable"]
* @param {widget_t*} widget 控件对象。
* @param {const char*} state_and_name 状态和名字,用英文的冒号分隔。
2020-09-01 07:06:09 +08:00
* @param {uint32_t} value 值。颜色值一般用十六进制表示,每两个数字表示一个颜色通道,从高位到低位,依次是 ABGR。
*
* 在下面这个例子中R=0x11 G=0x22 B=0x33 A=0xFF
*
* ```c
* widget_set_style_color(label, "normal:bg_color", 0xFF332211);
* ```
2019-06-03 18:35:42 +08:00
*
2019-12-11 09:56:47 +08:00
* @return {ret_t} 返回 RET_OK 表示成功,否则表示失败。
2019-06-03 18:35:42 +08:00
*/
2020-09-01 07:06:09 +08:00
ret_t widget_set_style_color(widget_t* widget, const char* state_and_name, uint32_t value);
2019-06-03 18:35:42 +08:00
```
示例:
```
2020-09-01 07:06:09 +08:00
widget_set_style_int(label, "normal:font_size", 24);
widget_set_style_str(label, "normal:text_color", "red");
widget_set_style_str(label, "normal:border_color", "#FF0000");
widget_set_style_color(label, "normal:bg_color", 0xFF00FF00);
2019-06-03 18:35:42 +08:00
```
2019-12-11 09:56:47 +08:00
> inline style 会消耗更多内存,而且不方便切换主题,一般应该尽量避免使用。
2019-06-03 18:35:42 +08:00
2020-09-01 07:06:09 +08:00
#### 注意:
* 用 widget\_set\_style\_color 设置颜色时:
> 颜色值一般用十六进制表示,每两个数字表示一个颜色通道,从高位到低位,依次是 ABGR。
* 用 widget\_set\_style\_str 设置颜色时:
> 颜色值如果用#开头,用十六进制表示,每两个数字表示一个颜色通道,从高位到低位,依次是 RGBA 或 RGB。
2019-06-03 18:35:42 +08:00
### 七、相关文档
2019-05-30 09:25:26 +08:00
2019-12-11 09:56:47 +08:00
* [AWTK 中的颜色格式](color_format.md)
2020-07-07 20:49:18 +08:00
2020-08-16 09:10:01 +08:00
* [控件状态定义](manual/widget_state_t.md)