《TD开发笔记》TD GUI自定义控件开发探析

免责声明:文中部分信息有参考到其他网站及牛人的资料,在引用到的地方会注明其来源,如有不宜之处可联系本人进行更正或者删除!学术看法及观点仅代表个人,仅供参考。知识共享,共同学习,来源于社会,回馈社会。

目录

1 前言

2 TD GUI原生控件须知

3 TD GUI自定义控件开发

4 效果展示

5 源码


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 效果展示

版权相关,图片做了模糊处理

5 源码

https://download.csdn.net/download/w1820020635/13956983

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值