C++界面库:使用Graphic Element Template制作按钮模板

C++界面库:使用Graphic Element Template制作按钮模板
    这一次制作的按钮模板具有通过模板属性动态配置图形的功能。模板的属性一共有6个:x、y、w、h、state、content,其中state有normal、hot和press三个取值。XML、代码和截图如下:

    下面的模板文件有两个模板,分别是background和button。background制作玻璃效果,button给background加上一个边框,展示了property evaluation和template reference的功能:
 1  <? xml version="1.0" encoding="utf-8"  ?>
 2  < irconfig  xmlns ="http://tempuri.org/irconfig.xsd" >
 3     < resources >
 4       < brush  name ="outer_border_brush"  kind ="solid" >
 5         < main_color  r ="96"  g ="128"  b ="255"  a ="255" />
 6       </ brush >
 7      
 8       < brush  name ="up_content_brush_normal"  kind ="linear_gradient"  gradient_angle ="0" >
 9         < main_color  r ="224"  g ="224"  b ="224"  a ="255" />
10         < gradient_color  r ="192"  g ="192"  b ="192"  a ="255" />
11       </ brush >
12       < brush  name ="down_content_brush_normal"  kind ="linear_gradient"  gradient_angle ="0" >
13         < main_color  r ="128"  g ="128"  b ="128"  a ="255" />
14         < gradient_color  r ="160"  g ="160"  b ="160"  a ="255" />
15       </ brush >
16      
17       < brush  name ="up_content_brush_hot"  kind ="linear_gradient"  gradient_angle ="0" >
18         < main_color  r ="224"  g ="224"  b ="255"  a ="255" />
19         < gradient_color  r ="192"  g ="192"  b ="255"  a ="255" />
20       </ brush >
21       < brush  name ="down_content_brush_hot"  kind ="linear_gradient"  gradient_angle ="0" >
22         < main_color  r ="128"  g ="128"  b ="255"  a ="255" />
23         < gradient_color  r ="160"  g ="160"  b ="255"  a ="255" />
24       </ brush >
25      
26       < brush  name ="up_content_brush_press"  kind ="linear_gradient"  gradient_angle ="0" >
27         < main_color  r ="224"  g ="224"  b ="255"  a ="255" />
28         < gradient_color  r ="160"  g ="160"  b ="255"  a ="255" />
29       </ brush >
30       < brush  name ="down_content_brush_press"  kind ="linear_gradient"  gradient_angle ="0" >
31         < main_color  r ="32"  g ="32"  b ="255"  a ="255" />
32         < gradient_color  r ="96"  g ="96"  b ="255"  a ="255" />
33       </ brush >
34      
35       < brush  name ="background_brush"  kind ="solid" >
36         < main_color  r ="255"  g ="255"  b ="255"  a ="255" />
37       </ brush >
38       < brush  name ="text_brush"  kind ="solid" >
39         < main_color  r ="0"  g ="0"  b ="0"  a ="255" />
40       </ brush >
41       < pen  name ="outer_border_pen"  brush ="outer_border_brush"  endcap ="round"  join ="round"  weight ="1" />
42       < font  name ="text_font"  face ="微软雅黑"  size ="18" />
43     </ resources >
44     < templates >
45       < template  name ="background" >
46         < properties >
47           < property  name ="x"  type ="int"  default ="0" />
48           < property  name ="y"  type ="int"  default ="0" />
49           < property  name ="w"  type ="int"  default ="100" />
50           < property  name ="h"  type ="int"  default ="100" />
51           < property  name ="state"  type ="str"  default ="normal" />
52           < property  name ="content"  type ="str"  default ="" />
53         </ properties >
54         < content >
55           < rectangle  name ="client"  x ="$x"  y ="$y"  width ="$w"  height ="$h" >
56             < text  brush ="text_brush"  font ="text_font"  text ="$content"  x ="(client.width-this.width)/2"  y ="(client.height-this.height)/2" />
57 
58             < rectangle  brush ="up_content_brush_normal"  visible ="$state=='normal'"
59                       x ="0"  y ="0"  width ="client.width"  height ="client.height/2"   />
60             < rectangle  brush ="down_content_brush_normal"  visible ="$state=='normal'"
61                       x ="0"  y ="client.height/2"  width ="client.width"  height ="client.height/2+1"   />
62 
63             < rectangle  brush ="up_content_brush_hot"  visible ="$state=='hot'"
64                       x ="0"  y ="0"  width ="client.width"  height ="client.height*4/9"   />
65             < rectangle  brush ="down_content_brush_hot"  visible ="$state=='hot'"
66                       x ="0"  y ="client.height*4/9"  width ="client.width"  height ="client.height*5/9+1"   />
67 
68             < rectangle  brush ="up_content_brush_press"  visible ="$state=='press'"
69                       x ="0"  y ="0"  width ="client.width"  height ="client.height*5/9"   />
70             < rectangle  brush ="down_content_brush_press"  visible ="$state=='press'"
71                       x ="0"  y ="client.height*5/9"  width ="client.width"  height ="client.height*4/9+1"   />
72           </ rectangle >
73         </ content >
74       </ template >
75       < template  name ="button" >
76         < properties >
77           < property  name ="x"  type ="int"  default ="0" />
78           < property  name ="y"  type ="int"  default ="0" />
79           < property  name ="w"  type ="int"  default ="100" />
80           < property  name ="h"  type ="int"  default ="100" />
81           < property  name ="state"  type ="str"  default ="normal" />
82           < property  name ="content"  type ="str"  default ="" />
83         </ properties >
84         < content >
85           < rectangle  name ="border"  brush ="background_brush"  pen ="outer_border_pen"  x ="$x"  y ="$y"  width ="$w"  height ="$h" >
86             < instance  reference ="background" >
87               < setter  name ="x"  value ="1" />
88               < setter  name ="y"  value ="1" />
89               < setter  name ="w"  value ="border.client_width-2" />
90               < setter  name ="h"  value ="border.client_height-2" />
91               < setter  name ="state"  value ="$state" />
92               < setter  name ="content"  value ="$content" />
93             </ instance >
94           </ rectangle >
95         </ content >
96       </ template >
97     </ templates >
98  </ irconfig >

    程序由4个按钮组成,4个按钮都是button的实例化,但是只处理了最后一个按钮的消息。因为现在只有画图,所以消息处理部分是手动的。下面是截图:
C++界面库:使用Graphic Element Template制作按钮模板_第1张图片

    下面是代码:
  1  class  ConfigForm :  public  VL_WinForm
  2  {
  3  protected :
  4      IVL_IrFactory::Ptr                FFactory;
  5      IVL_IrCanvas::Ptr                FCanvas;
  6      VL_IrConfigLoader::Ptr            FLoader;
  7      VL_IrConfig::Ptr                FConfig;
  8      VL_IrTemplateInstance::Ptr        FNormalButton;
  9      VL_IrTemplateInstance::Ptr        FHotButton;
 10      VL_IrTemplateInstance::Ptr        FPressButton;
 11      VL_IrTemplateInstance::Ptr        FButton;
 12      VBool                            FClickedOnButton;
 13 
 14      VL_IrTemplateInstance::Ptr CreateButton(VL_IrPoint Position , VUnicodeString State , VUnicodeString Text)
 15      {
 16          VL_IrTemplateInstance::Ptr Instance = FConfig -> FindTemplate(L " button " ) -> CreateInstance();
 17           for (VInt i = 0 ;i < Instance -> GetRootElements().GetCount();i ++ )
 18          {
 19              FCanvas -> GetRootElement() -> Container() -> AddChild(Instance -> GetRootElements()[i]);
 20          }
 21 
 22          Instance -> GetInts()[L " x " ] = Position.X;
 23          Instance -> GetInts()[L " y " ] = Position.Y;
 24          Instance -> GetInts()[L " w " ] = 100 ;
 25          Instance -> GetInts()[L " h " ] = 30 ;
 26          Instance -> GetStrs()[L " state " ] = State;
 27          Instance -> GetStrs()[L " content " ] = Text;
 28          Instance -> Update();
 29 
 30           return  Instance;
 31      }
 32 
 33      VBool IsOnButton(VLS_MouseStruct Struct)
 34      {
 35           return  FButton -> GetRootElements()[ 0 ] -> Properties() -> ContainedPoint(VL_IrPoint(Struct.X,Struct.Y)) != IVL_IrElement::htrNone;
 36      }
 37 
 38       void  Form_MouseDown(VL_Base *  Sender , VLS_MouseStruct Struct)
 39      {
 40          FClickedOnButton = IsOnButton(Struct);
 41          FButton -> GetStrs()[L " state " ] = FClickedOnButton ? L " press " :L " normal " ;
 42          FButton -> Update();
 43          FCanvas -> Render();
 44      }
 45 
 46       void  Form_MouseMove(VL_Base *  Sender , VLS_MouseStruct Struct)
 47      {
 48          VUnicodeString PreviousState = FButton -> GetStrs()[L " state " ];
 49           if (FClickedOnButton)
 50          {
 51              FButton -> GetStrs()[L " state " ] = IsOnButton(Struct) ? L " press " :L " hot " ;
 52          }
 53           else   if (Struct.LeftButton)
 54          {
 55              FButton -> GetStrs()[L " state " ] = IsOnButton(Struct) ? L " hot " :L " normal " ;
 56          }
 57           else
 58          {
 59              FButton -> GetStrs()[L " state " ] = IsOnButton(Struct) ? L " hot " :L " normal " ;
 60          }
 61           if (FButton -> GetStrs()[L " state " ] != PreviousState)
 62          {
 63              FButton -> Update();
 64              FCanvas -> Render();
 65          }
 66      }
 67 
 68       void  Form_MouseUp(VL_Base *  Sender , VLS_MouseStruct Struct)
 69      {
 70          FClickedOnButton = false ;
 71          FButton -> GetStrs()[L " state " ] = IsOnButton(Struct) ? L " hot " :L " normal " ;
 72          FButton -> Update();
 73          FCanvas -> Render();
 74      }
 75  public :
 76      ConfigForm():VL_WinForm( true )
 77      {
 78          SetBorder(vwfbSingle);
 79          SetMinimizeBox( false );
 80          SetMaximizeBox( false );
 81          SetClientWidth( 800 );
 82          SetClientHeight( 600 );
 83          SetText(L " Vczh Interaction Renderer Template Test " );
 84 
 85          OnLeftButtonDown.Bind( this , & ConfigForm::Form_MouseDown);
 86          OnLeftButtonUp.Bind( this , & ConfigForm::Form_MouseUp);
 87          OnMouseMove.Bind( this , & ConfigForm::Form_MouseMove);
 88          FClickedOnButton = false ;
 89 
 90          FFactory = CreateInteractionFactory(L " GDI " );
 91          FCanvas = FFactory -> CreateCanvas( this );
 92          FLoader = new  VL_IrConfigLoader(FFactory);
 93          FConfig = FLoader -> Load(VFileName(GetApplication() -> GetAppName()).MakeAbsolute(L " ..\\Renderer\\IrConfig_Test.xml " ).GetStrW());
 94 
 95          VL_IrBrushRec WhiteBrushRec;
 96          WhiteBrushRec.BrushKind = VL_IrBrushRec::bkSolid;
 97          WhiteBrushRec.MainColor = VL_IrColor( 255 , 255 , 255 );
 98          IVL_IrBrush::Ptr WhiteBrush = FFactory -> CreateBrush(WhiteBrushRec);
 99 
100          IVL_IrRectangle::Ptr Root = FFactory -> CreateRectangle();
101          Root -> Properties() -> SetBrush(WhiteBrush);
102          Root -> Update(VL_IrPoint( 0 , 0 ),VL_IrPoint( 800 , 600 ));
103          FCanvas -> SetRootElement(Root);
104 
105          FNormalButton = CreateButton(VL_IrPoint( 10 , 10 ),L " normal " ,L " Normal " );
106          FHotButton = CreateButton(VL_IrPoint( 10 , 50 ),L " hot " ,L " Hot " );
107          FPressButton = CreateButton(VL_IrPoint( 10 , 90 ),L " press " ,L " Press " );
108          FButton = CreateButton(VL_IrPoint( 10 , 130 ),L " normal " ,L " Click Me " );
109 
110          FCanvas -> Render();
111      }
112  };

    程序创建了一个白色的全屏的长方形当背景,然后把button的四个实例产生的图形都加入长方形中。使用类似的方法就可以将不同的东西堆叠起来,最后组成一个完整的程序界面了。接下来开始设计界面库的架构,做一系列可以自动排版、基于MVC和上面那个模板的组件。

你可能感兴趣的:(C++界面库:使用Graphic Element Template制作按钮模板)