继承

有时候会发现某个部件的功能不够用,想扩展一些新功能,但不想直接修改它的代码,也不想重写一个新部件,这个时候可以使用原型的“继承”功能来创建一个该部件的扩展版本,即能保留原部件的功能,又能使用新加的功能。

以 textview 部件为例,现在有这样的功能需求:能够支持设置网址链接,在被点击时会调用浏览器打开这个链接,网址链接能靠 href 属性来设置,以下是示例代码:

  1. #include <string.h>
  2. #include <stdlib.h>
  3. #include <LCUI_Build.h>
  4. #include <LCUI/LCUI.h>
  5. #include <LCUI/gui/widget.h>
  6. typedef struct LinkRec_ {
  7. char *href;
  8. } LinkedRec, *Link;
  9. LCUI_WidgetPrototype prototype;
  10. static void Link_OnClick( LCUI_Widget w, LCUI_WidgetEvent e, void *arg )
  11. {
  12. Link link = Widget_GetData( w, prototype );
  13. if( link->href ) {
  14. // 调用浏览器打开链接
  15. // ...
  16. }
  17. }
  18. static void Link_OnInit( LCUI_Widget w )
  19. {
  20. Link link;
  21. const size_t size = sizeof( LinkRec );
  22. link = Widget_AddData( w, prototype, size );
  23. link->href = NULL;
  24. Widget_BindEvent( w, "click", Link_OnClick, NULL, NULL );
  25. // 调用父级原型的 init() 方法,继承父级现有的功能
  26. prototype->proto->init( w );
  27. }
  28. static void Link_OnDestroy( LCUI_Widget w )
  29. {
  30. Link link = Widget_GetData( w, prototype );
  31. free( link->href );
  32. prototype->proto->destroy( w );
  33. }
  34. void Link_SetHref( LCUI_Widget w, const char *href )
  35. {
  36. Link link = Widget_GetData( w, prototype );
  37. if( link->href ) {
  38. free( link->href );
  39. link->href = NULL;
  40. }
  41. if( href ) {
  42. size_t len = strlen( href ) + 1;
  43. link->href = malloc( len * sizeof( char ) );
  44. strcpy( link->href, href );
  45. }
  46. }
  47. static void Link_OnSetAttr( LCUI_Widget w, const char *name, const char *value )
  48. {
  49. // 当 XML 解析器解析到的元素属性是 href 时
  50. if( strcmp( name, "href" ) == 0 ) {
  51. Link_SetHref( w, value );
  52. }
  53. }
  54. void LCUIWidget_AddLink( void )
  55. {
  56. // 创建一个名为 link 的部件原型,继承自 textview
  57. prototype = LCUIWidget_NewPrototype( "link", "textview" );
  58. prototype->init = Link_OnInit;
  59. prototype->destroy = Link_OnDestroy;
  60. prototype->setattr = Link_OnSetAttr;
  61. }

以上代码创建了一个名为 link 的部件原型,接下来将展示如何使用它:

  1. // ...
  2. LCUI_Widget link;
  3. LCUIWidget_AddLink();
  4. // ...
  5. link = LCUIWidget_New( "link" );
  6. Link_SetHref( link, "https://www.example.com" );
  7. // ...
  1. <?xml version="1.0" encoding="UTF-8" ?>
  2. <lcui-app>
  3. <ui>
  4. <widget type="link" href="https://www.example.com">点击这里</widget>
  5. </ui>
  6. </lcui-app>

原文: https://docs.lcui.lc-soft.io/zh-cn/gui_widgets/inherit.html