免责声明:文中部分信息有参考到其他网站及牛人的资料,在引用到的地方会注明其来源,如有不宜之处可联系本人进行更正或者删除!学术看法及观点仅代表个人,仅供参考。知识共享,共同学习,来源于社会,回馈社会。
目录
1 前言
截止目前(2020.12.28)为止,TD官方暂未公开任何TD GUI自定义控件相关的帮助文档。都知道,没有自定义的GUI开发是没有灵魂的,意味着你只能使用原生的GUI控件,有啥用啥,没有的也就只能将就咯。但是,怎么能将就呢?作为略有GUI开发洁癖的我,根据一些官方提供的示例,摸索出了一套不成文的TD GUI自定义控件开发框架,以供学习参考查阅。
2 TD GUI原生控件须知
在阅读本章之前,需了解基本的TD GUI原生控件的使用,参考《TD开发笔记》TD GUI原生控件使用探析。
3 TD GUI自定义控件开发
3.1 自定义控件的命名
在自定义控件的命名上,需要注意,请勿和原生控件的名字冲突了。这里,以slide_position为例,自定义一个名为slide_position的控件。
在头文件中定义为:
/*滑动位置控件*/
#define TD_SLIDE_POSTION TStringID("slide_position")
3.2 自定义控件的入口
//自定义控件的入口
static void init_slide_position(void) __attribute__((constructor));
void init_slide_position(void)
{
slide_position_obj_info.interfaces[0] = T_STRING_ID(widget); //创建基于widget的控件
TObjectRegisterType(TD_SLIDE_POSTION, &slide_position_obj_info); //注册控件的类型,调用类型初始化接口
_TwRegisterStyle(TD_SLIDE_POSTION, T_ARRAY_NUM(slide_position_style), slide_position_style);//注册控件的样式,调用样式初始化接口
TwUnlock();
return;
}
3.3 类型初始化接口
//类型初始化接口
static TObjectType slide_position_obj_info = {
.create_func = slide_postion_obj_create,
.destroy_func = slide_position_obj_destroy,
.obj_size = sizeof(TD_SLIDEPOSITION),
.interface_num = 1,
.interfaces = {None},
};
///*在这里,你可以初始化这些
// char *description;/*object的描述*/
// T_ID type_id;
// TObjectCreate_Func create_func;/*初始化函数*/
// TObjectDestroy_Func destroy_func;/*销毁函数*/
// TObjectAddEventNotify_Func addevent_notify_func;/*用户注册事件的监控函数*/
// TObjectMethod_Func custom_method;
// Tint reserve[2];
// Tint obj_size;/*该类的内存大小*/
// Tint interface_num;
// T_ID interfaces[];/*interface id*/
3.4 样式初始化接口
//样式初始化接口
static TwStyleNode slide_position_style[] = {
{
.status_mask = TW_STATUS_NORMAL|TW_STATUS_DISABLE|TW_STATUS_ACTIVE|TW_STATUS_SELECT,
.flags_mask = HAS_TEXT_COLOR,
.text_color = T_BGR(255, 255, 255),
.text_bg_color = T_BGR(128, 128, 128),
}
};
///*在这里,你可以初始化这些
// Tuint8 status_mask;
//
// Tuint8 text_margin;/*用于上下两行文本距离*/
// Tuint8 image_margin;/*用于text follow image*/
//
// Tuint8 border_margin_left;
// Tuint8 border_margin_top;
// Tuint8 border_margin_right;
// Tuint8 border_margin_bottom;
// Tuint8 border_size;
//
// Tuint16 flags_mask;/*BG_PIXMAP|BORDER_PIXMAP|HAS_XXX*/
// Tuint8 alpha;
// Tuint32 vc_flags;/*aline of text and image, bg_stretch_mode, border_type*/
//
// Tuint border;
// Tuint bg;
// Tuint img;
// TColor text_color;
// TColor text_bg_color;
//
// Tint16 bg_w;
// Tint16 bg_h;
// Tint16 img_w;
// Tint16 img_h;
// Font font;
3.5 分别实现类型初始化中的函数
其中,create_func初始化函数和destroy_func销毁函数是必要的
static int slide_postion_obj_create(void *obj, TTable *in)
{
//在此做初始化工作。根据自定义,略有不同
TDisplayCell *parent_vc;
TD_SLIDEPOSITION *pct = (TD_SLIDEPOSITION*)obj;
TWidget *widget = (TWidget*)obj;
TwLock();
parent_vc = _TwInit(widget, &slide_position_method, in);
if(parent_vc == NULL) {
TwUnlock();
return T_FAIL;
}
pct->vc = DcCreate(DC_INPUT_WINDOW, parent_vc, widget->cx, widget->cy, widget->w, widget->h, widget);
pct->style = _TwFindStyle(TD_SLIDE_POSTION, widget->style_name);
_TwSetStyle(pct->vc, pct->style, TW_STATUS_NORMAL);
///..
///省略
///..
_TwSetFocusVC(widget, pct->vc);
_TwInit_Finish(widget);
TwUnlock();
return T_SUCCESS;
}
static void slide_position_obj_destroy(void *obj)
{
//在此做销毁工作。根据自定义,略有不同
TD_SLIDEPOSITION *pct = (TD_SLIDEPOSITION*)obj;
TwLock();
_TwUnInit((TWidget*)obj);
DcDestroy(pct->vc);
TwUnlock();
return ;
}
3.6 自定义控件的属性自定义
能从原生控件框架中获取到的控件属性
TBTree btree; /*btree中的id就是wid*/
void *widget, *arg; /*widget 必须指向所属控件*/
Tuint32 flag; /*including: viewc type, misc flag, border type, text and image aline, draw mode*/
TDisplayCell *parent;
TList child_head, sibling_list;
TDisplayCell *show_next; /*对window类型的vc 是链接到全局链表showvc上;
对其他类型vc 是链接到父窗口vc 的 show_child_next 链表上,
一定要注意非窗口vc挂到链表上的顺序一定要和siblings链表的
顺序一致,表示同层显示的上下层次*/
TDisplayCell *show_child_next; /*for DC_WINDOW, 记录need draw 的非VIEW_WINDOW子vc*/
Tint32 x, y, w, h;
Region show_region; /*for DC_WINDOW*/
DC_Expose_Func expose_func;
Tuint32 background; /* none(pixmap), ParentRelative(pixmap), pixmap:>=1000; color */
Tuint32 border; /* none(pixmap); pixmap:>=1000 ; color (border_type才有用) */
Tint16 bgw, bgh;
Tint16 bw, bh;
Tuint8 border_thickness, image_margin, text_margin, alpha;
Tuint8 border_margin_left, border_margin_right, border_margin_top, border_margin_bottom;
Pixmap imageid; /* 0:no image; <1000:internal image; >=1000:imageid;*/
Tint16 iw, ih;
const char *text;
Font font;
TColor text_color;
TColor text_bg_color;
Tint16 text_len;
Tint16 tw;
Tint16 th, tb;
/*font_baseline 是建议值,得到tw, th 时也可以得到实际的tb*/
Tint16 font_baseline, font_height;
Pixmap imageid_orig; /*zjie add for IMAGE_DUP*/
void *style; /*专用于_TwSetStyle(), zjie*/
Tuint8 style_status; /*专用于_TwSetStyle(), zjie*/
Tbool translate; /*专用于翻译, zjie*/
这些属性基本上也够用,但是对于自定义来说不能满足。于是想方设法去试图通过某种手段,实现能添加自己需要的自定义属性,实验了许久,最后找到一个行得通的方法,但是有得必有失,会摒弃原有的部分属性,当然,在不影响使用的同时实现了真正的自定义。(仅供参考)
这种方法是将控件的style属性作为自定义扩展,基本格式可如下定义,并在布局.ini文件对对应的自定义控件style属性进行自定义配置。
style="属性名:属性值;属性名:属性值;属性名:属性值;...属性名:属性值"
例如:
eq_slide_position={
type="slide_position"
x=23
y=27
w=294
h=294
style="bg=../style/setup/eqimage/EQ-02_03.png;slider_img=../style/setup/eqimage/eq_dian.png;slider_w=22;slider_h=22;start_x=73;start_y=79;end_x=264;end_y=269"
}
在其create_func初始化函数中将自定义属性解析出来使用。
例如上面的属性配置解析:
pct->styleStr = TIDString(widget->style_name);
pct->start_x = widget->cx;
pct->start_y = widget->cy;
pct->end_x = widget->cx + widget->w;
pct->end_y = widget->cy + widget->h;
pct->tempXIndex = 0;
pct->tempYIndex = 0;
char *p = pct->styleStr;
while(p=strsep(&pct->styleStr,";\0"))
{
char *item = p;
if(item=strsep(&p,"=\0")){
if(strcmp(item, "bg") == 0){
if(item=strsep(&p,"=\0")){
strcpy(pct->bg,item);
}
}else if(strcmp(item, "slider_img") == 0){
if(item=strsep(&p,"=\0")){
strcpy(pct->slider_img,item);
}
}else if(strcmp(item, "slider_w") == 0){
if(item=strsep(&p,"=\0")){
pct->slider_w = atoi(item);
}
}else if(strcmp(item, "slider_h") == 0){
if(item=strsep(&p,"=\0")){
pct->slider_h = atoi(item);
}
}else if(strcmp(item, "start_x") == 0){
if(item=strsep(&p,"=\0")){
pct->start_x = atoi(item);
}
}else if(strcmp(item, "start_y") == 0){
if(item=strsep(&p,"=\0")){
pct->start_y = atoi(item);
}
}else if(strcmp(item, "end_x") == 0){
if(item=strsep(&p,"=\0")){
pct->end_x = atoi(item);
}
}else if(strcmp(item, "end_y") == 0){
if(item=strsep(&p,"=\0")){
pct->end_y = atoi(item);
}
}
}
}
4 效果展示
版权相关,图片做了模糊处理。