原型
介绍组件的原型相关概念和用法。
在开发 UI 的时候,我们会用到各种各样的组件来丰富 UI 的交互体验,例如:文本输入框、滚动条、 进度条、单选框等,这些组件虽然有着不同的数据、方法、视觉效果和交互方式,但都能在 LCUI 中以相同的规则来工作,而这个规则就是原型。
原型方法
原型中记录了 LCUI 在更新和渲染组件时需要用到的方法,通过将这些方法与自定义函数绑定,可实现对组件的扩展。关于原型的定义,你可以在 include/LCUI/gui/widget_base.h 中找到。
接下来让我们深入了解原型中的各个方法的用途。
init
LCUIWidget_New() 函数在找到原型后,会调用 init() 函数按照该类型的组件预设的方法初始化组件实例,不同类型的组件都会有自己的数据以及其它相关的设置,这些数据可以在 init() 函数中初始化。
destroy
在组件被销毁时会调用 destroy() 函数,通常这个函数主要负责销毁组件的私有数据、解除相关设置等。
update
对于某些组件而言,预置的 CSS 属性无法满足需求,会需要用到扩展 CSS 属性,而这些扩展 CSS 属性的处理方法是 LCUI 无法知道的,因此,LCUI 在处理完预置的 CSS 属性后,会将剩余的 CSS 属性交给 update() 函数去处理。
runtask
在 LCUI 处理完组件预设的一些任务后,会调用 runtask() 去处理组件自己设定的一 些任务。
setattr
在 Widget_SetAttribute() 设置完属性后会调用它。
settext
当解析到 XML 文档元素内的文本结点时,会调用该函数让组件处理文本内容。
autosize
在计算组件宽高时,如果组件的宽高被设置为 auto,则会调用 autosize() 获取该组件的尺寸,如果未设置 autosize,LCUI 会按照默认的方式计算组件的宽高。通常像文本显示(TextView)这类有自己内容的组件会需要这个函数来调整自身宽高以 适应文本内容。
resize
在组件宽高更新时调用。
paint
在 LCUI 按设定的样式绘制好组件后,会调用 paint() 绘制组件自己的内容。
proto
父级原型,用于访问父级原型的方法,这个属性不需要手动设置。
创建原型
创建原型需要用到 LCUIWidget_NewPrototype() 函数:
它的参数有两个:原型的名称、继承的父级原型的名称,创建完后会返回原型,如果已经存在同名的原型或者原型添加失败,则会返回 NULL。
以下代码展示了原型的创建方法,如需详尽的参考代码请查阅 LCUI 预置组件的代码(例如:src/gui/widget/textview.c)。
使用私有数据
当组件的功能变多变复杂的时候,如果仅靠函数内的局部变量难以实现多个功能之间的数据共享的话,那么就会需要一个能在整个组件生命周期内有效的空间来存放数据,例如:文本编辑框,它会保存当前编辑的文本内容,调用相关函数可以对这个文本内容进行读写操作,在绘制时也会需要用到这些文本内容以在屏幕上绘制出相应的文字。
组件私有数据的操作函数有以下两个:
从以上代码中可以看出组件私有数据有添加和获取这两种方法,私有数据是与组件原型绑定的,添加时需要指定具体的内存占用大小。添加后,可以调用 Widget_GetData() 函数获取私有数据,这个函数也同样需要指定原型。
以下是这两个函数的基本用法示例:
使用 CLI 添加组件
LCUI CLI 提供了组件生成器,你可以基于它生成的组件模板代码快速开发组件。
继承
在某一个组件的功能不够用的时候,我们会想基于它扩展一些新功能,如果直接改代码的话会让它容易变得更复杂,而重新写一个成本太高,所以,这个时候我们可以使用原型的“继承”功能来创建一个组件的扩展版本, 即能保留原组件的功能,又能使用新加的功能。
以 TextView 组件为例,假设有这么个需求:能够支持设置网页链接,在组件被点击时调用浏览器打开这个链接,网页链接由 href 属性提供,以下是示例代码:
以上代码创建了一个名为 link 的原型,接下来将展示如何使用它:
LCUI 的预置组件 Anchor 是这个示例组件的完整实现,如需了解更多,可查看文件:src/gui/widget/anchor.c
最后更新于