随笔-341  评论-2670  文章-0  trackbacks-0
    我们知道制作控件的时候,其实最困难的不是定出那个支撑整个系统的架构,而是为各种空间写绘制的代码(囧)。为了解决这个问题,我在这套渲染库上设计了一种XML写成的模板,然后在模板内部提供一个简单的语言来进行简单但是强大的运算。这样的话,不仅可以省略很多代码,还为控件的换肤提供了强有力的支持。

    Graphic Element Template是一种将图形方便地组织起来的方法,使用XML进行描述,举个例子:现在要在一个rectangle中间居中一段文字:
 1 <rectangle
 2     name="rect"
 3     x="100"
 4     y="100"
 5     width="400"
 6     height="300"
 7 >
 8     <text
 9         x="(rect.width-this.width)/2"
10         y="(rect.height-this.height)/2"
11         text="CENTERED TEXT"
12         />
13 </rectangle>

    如果我们可以在标签内部使用简单的脚本,那么做控件的时候,只要使用一个template,就可以省去我们很多时间了。于是我设计了这样子的一个Graphic Element Template,可以定义一个模板,然后定义属性,最后在属性内部对脚本进行计算。为了在Visual Studio 2008方便地撰写Graphic Element Template文件,我写了如下的一个XML Schema。明天开始实现Graphics Element Template。
  1 <?xml version="1.0" encoding="utf-8"?>
  2 <xs:schema id="irconfig"
  3     targetNamespace="http://tempuri.org/irconfig.xsd"
  4     elementFormDefault="qualified"
  5     xmlns="http://tempuri.org/irconfig.xsd"
  6     xmlns:mstns="http://tempuri.org/irconfig.xsd"
  7     xmlns:xs="http://www.w3.org/2001/XMLSchema"
  8 >
  9   <xs:simpleType name="pen_weight">
 10     <xs:restriction base="xs:unsignedByte" >
 11       <xs:minInclusive value="0" />
 12     </xs:restriction>
 13   </xs:simpleType>
 14   <xs:simpleType name="boolean_type">
 15     <xs:restriction base="xs:string">
 16       <xs:enumeration value="true" />
 17       <xs:enumeration value="false" />
 18     </xs:restriction>
 19   </xs:simpleType>
 20   <xs:simpleType name="property_type">
 21     <xs:restriction base="xs:string">
 22       <xs:enumeration value="int" />
 23       <xs:enumeration value="real" />
 24       <xs:enumeration value="str" />
 25       <xs:enumeration value="bool" />
 26     </xs:restriction>
 27   </xs:simpleType>
 28   <xs:simpleType name="expression_type">
 29     <xs:restriction base="xs:string" />
 30   </xs:simpleType>
 31   <xs:simpleType name="name_type">
 32     <xs:restriction base="xs:NCName" />
 33   </xs:simpleType>
 34   <xs:simpleType name="brushkind_type">
 35     <xs:restriction base="xs:string">
 36       <xs:enumeration value="solid" />
 37       <xs:enumeration value="linear-gradient" />
 38       <xs:enumeration value="bitmap" />
 39     </xs:restriction>
 40   </xs:simpleType>
 41   <xs:simpleType name="penendcap_type">
 42     <xs:restriction base="xs:string">
 43       <xs:enumeration value="round" />
 44       <xs:enumeration value="square" />
 45       <xs:enumeration value="flat" />
 46     </xs:restriction>
 47   </xs:simpleType>
 48   <xs:simpleType name="penjoin_type">
 49     <xs:restriction base="xs:string">
 50       <xs:enumeration value="round" />
 51       <xs:enumeration value="bevel" />
 52       <xs:enumeration value="miter" />
 53     </xs:restriction>
 54   </xs:simpleType>
 55   <xs:complexType name="color_type">
 56     <xs:attribute name="r" type="xs:unsignedByte" use="required"/>
 57     <xs:attribute name="g" type="xs:unsignedByte" use="required"/>
 58     <xs:attribute name="b" type="xs:unsignedByte" use="required"/>
 59     <xs:attribute name="a" type="xs:unsignedByte"/>
 60   </xs:complexType>
 61 
 62   <xs:complexType name="element_definition">
 63     <xs:attribute name="name" type="name_type"/>
 64     <xs:attribute name="visible" type="expression_type"/>
 65   </xs:complexType>
 66   <xs:complexType name="curve_definition">
 67     <xs:complexContent>
 68       <xs:extension base="element_definition">
 69         <xs:attribute name="pen" type="expression_type" />
 70       </xs:extension>
 71     </xs:complexContent>
 72   </xs:complexType>
 73   <xs:complexType name="shape_definition">
 74     <xs:complexContent>
 75       <xs:extension base="curve_definition">
 76         <xs:attribute name="brush" type="expression_type" />
 77       </xs:extension>
 78     </xs:complexContent>
 79   </xs:complexType>
 80   <xs:complexType name="shape_container_definition">
 81     <xs:complexContent>
 82       <xs:extension base="shape_definition">
 83         <xs:sequence>
 84           <xs:group ref="element_group" minOccurs="0" maxOccurs="unbounded"/>
 85         </xs:sequence>
 86       </xs:extension>
 87     </xs:complexContent>
 88   </xs:complexType>
 89 
 90   <xs:group name="element_group">
 91     <xs:choice>
 92       <xs:element name="line">
 93         <xs:complexType>
 94           <xs:complexContent>
 95             <xs:extension base="curve_definition">
 96               <xs:attribute name="x1" type="expression_type" use="required"/>
 97               <xs:attribute name="y1" type="expression_type" use="required"/>
 98               <xs:attribute name="x2" type="expression_type" use="required"/>
 99               <xs:attribute name="y2" type="expression_type" use="required"/>
100             </xs:extension>
101           </xs:complexContent>
102         </xs:complexType>
103       </xs:element>
104       <xs:element name="rectangle">
105         <xs:complexType>
106           <xs:complexContent>
107             <xs:extension base="shape_container_definition">
108               <xs:attribute name="x" type="expression_type" use="required"/>
109               <xs:attribute name="y" type="expression_type" use="required"/>
110               <xs:attribute name="width" type="expression_type" use="required"/>
111               <xs:attribute name="height" type="expression_type" use="required"/>
112             </xs:extension>
113           </xs:complexContent>
114         </xs:complexType>
115       </xs:element>
116       <xs:element name="roundrect">
117         <xs:complexType>
118           <xs:complexContent>
119             <xs:extension base="shape_container_definition">
120               <xs:attribute name="x" type="expression_type" use="required"/>
121               <xs:attribute name="y" type="expression_type" use="required"/>
122               <xs:attribute name="width" type="expression_type" use="required"/>
123               <xs:attribute name="height" type="expression_type" use="required"/>
124               <xs:attribute name="ellipse-width" type="expression_type" use="required"/>
125               <xs:attribute name="ellipse-height" type="expression_type" use="required"/>
126             </xs:extension>
127           </xs:complexContent>
128         </xs:complexType>
129       </xs:element>
130       <xs:element name="ellipse">
131         <xs:complexType>
132           <xs:complexContent>
133             <xs:extension base="shape_container_definition">
134               <xs:attribute name="x" type="expression_type" use="required"/>
135               <xs:attribute name="y" type="expression_type" use="required"/>
136               <xs:attribute name="width" type="expression_type" use="required"/>
137               <xs:attribute name="height" type="expression_type" use="required"/>
138             </xs:extension>
139           </xs:complexContent>
140         </xs:complexType>
141       </xs:element>
142       <xs:element name="chord">
143         <xs:complexType>
144           <xs:complexContent>
145             <xs:extension base="shape_container_definition">
146               <xs:attribute name="x" type="expression_type" use="required"/>
147               <xs:attribute name="y" type="expression_type" use="required"/>
148               <xs:attribute name="width" type="expression_type" use="required"/>
149               <xs:attribute name="height" type="expression_type" use="required"/>
150               <xs:attribute name="start-angle" type="expression_type" use="required" />
151               <xs:attribute name="end-angle" type="expression_type" use="required" />
152             </xs:extension>
153           </xs:complexContent>
154         </xs:complexType>
155       </xs:element>
156       <xs:element name="pie">
157         <xs:complexType>
158           <xs:complexContent>
159             <xs:extension base="shape_container_definition">
160               <xs:attribute name="x" type="expression_type" use="required"/>
161               <xs:attribute name="y" type="expression_type" use="required"/>
162               <xs:attribute name="width" type="expression_type" use="required"/>
163               <xs:attribute name="height" type="expression_type" use="required"/>
164               <xs:attribute name="start-angle" type="expression_type" use="required" />
165               <xs:attribute name="end-angle" type="expression_type" use="required" />
166             </xs:extension>
167           </xs:complexContent>
168         </xs:complexType>
169       </xs:element>
170       <xs:element name="arc">
171         <xs:complexType>
172           <xs:complexContent>
173             <xs:extension base="curve_definition">
174               <xs:attribute name="x" type="expression_type" use="required"/>
175               <xs:attribute name="y" type="expression_type" use="required"/>
176               <xs:attribute name="width" type="expression_type" use="required"/>
177               <xs:attribute name="height" type="expression_type" use="required"/>
178               <xs:attribute name="start-angle" type="expression_type" use="required" />
179               <xs:attribute name="end-angle" type="expression_type" use="required" />
180             </xs:extension>
181           </xs:complexContent>
182         </xs:complexType>
183       </xs:element>
184       <xs:element name="polyline">
185         <xs:complexType>
186           <xs:complexContent>
187             <xs:extension base="curve_definition">
188               <xs:sequence>
189                 <xs:element name="handle" minOccurs="1" maxOccurs="unbounded">
190                   <xs:complexType>
191                     <xs:attribute name="x" type="expression_type" use="required"/>
192                     <xs:attribute name="y" type="expression_type" use="required"/>
193                   </xs:complexType>
194                 </xs:element>
195               </xs:sequence>
196             </xs:extension>
197           </xs:complexContent>
198         </xs:complexType>
199       </xs:element>
200       <xs:element name="polygon">
201         <xs:complexType>
202           <xs:complexContent>
203             <xs:extension base="shape_container_definition">
204               <xs:sequence>
205                 <xs:element name="handle" minOccurs="1" maxOccurs="unbounded">
206                   <xs:complexType>
207                     <xs:attribute name="x" type="expression_type" use="required"/>
208                     <xs:attribute name="y" type="expression_type" use="required"/>
209                   </xs:complexType>
210                 </xs:element>
211               </xs:sequence>
212             </xs:extension>
213           </xs:complexContent>
214         </xs:complexType>
215       </xs:element>
216       <xs:element name="bezier">
217         <xs:complexType>
218           <xs:complexContent>
219             <xs:extension base="curve_definition">
220               <xs:sequence>
221                 <xs:element name="handle" minOccurs="4" maxOccurs="unbounded">
222                   <xs:complexType>
223                     <xs:attribute name="x" type="expression_type" use="required"/>
224                     <xs:attribute name="y" type="expression_type" use="required"/>
225                   </xs:complexType>
226                 </xs:element>
227               </xs:sequence>
228             </xs:extension>
229           </xs:complexContent>
230         </xs:complexType>
231       </xs:element>
232       <xs:element name="text">
233         <xs:complexType>
234           <xs:complexContent>
235             <xs:extension base="shape_definition">
236               <xs:attribute name="font" type="expression_type" use="required"/>
237               <xs:attribute name="x" type="expression_type" use="required"/>
238               <xs:attribute name="y" type="expression_type" use="required"/>
239               <xs:attribute name="text" type="expression_type" use="required"/>
240             </xs:extension>
241           </xs:complexContent>
242         </xs:complexType>
243       </xs:element>
244       <xs:element name="picture">
245         <xs:complexType>
246           <xs:complexContent>
247             <xs:extension base="element_definition">
248               <xs:attribute name="x" type="expression_type" use="required"/>
249               <xs:attribute name="y" type="expression_type" use="required"/>
250               <xs:attribute name="bitmap" type="expression_type" use="required"/>
251             </xs:extension>
252           </xs:complexContent>
253         </xs:complexType>
254       </xs:element>
255       <xs:element name="instance" minOccurs="0" maxOccurs="unbounded">
256         <xs:complexType>
257           <xs:complexContent>
258             <xs:extension base="element_definition">
259               <xs:sequence>
260                 <xs:element name="setter" minOccurs="0" maxOccurs="unbounded">
261                   <xs:complexType>
262                     <xs:attribute name="name" type="name_type" />
263                     <xs:attribute name="value" type="expression_type" />
264                   </xs:complexType>
265                 </xs:element>
266               </xs:sequence>
267               <xs:attribute name="reference" type="name_type" use="required" />
268             </xs:extension>
269           </xs:complexContent>
270         </xs:complexType>
271       </xs:element>
272     </xs:choice>
273   </xs:group>
274 
275   <xs:element name="irconfig">
276     <xs:complexType>
277       <xs:sequence>
278         <xs:element name="resources" minOccurs="0" maxOccurs="1">
279           <xs:complexType>
280             <xs:sequence>
281               <xs:element name="brush" minOccurs="0" maxOccurs="unbounded">
282                 <xs:complexType>
283                   <xs:sequence>
284                     <xs:element name="main-color" type="color_type" minOccurs="0" maxOccurs="1" />
285                     <xs:element name="gradient-color" type="color_type" minOccurs="0" maxOccurs="1" />
286                   </xs:sequence>
287                   <xs:attribute name="name" type="name_type" use="required" />
288                   <xs:attribute name="kind" type="brushkind_type" use="required" />
289                   <xs:attribute name="gradient-angle" type="xs:double" />
290                   <xs:attribute name="bitmap" type="xs:string" />
291                 </xs:complexType>
292               </xs:element>
293               <xs:element name="pen" minOccurs="0" maxOccurs="unbounded">
294                 <xs:complexType>
295                   <xs:attribute name="name" type="name_type" use="required" />
296                   <xs:attribute name="weight" type="pen_weight" use="required" />
297                   <xs:attribute name="endcap" type="penendcap_type" use="required" />
298                   <xs:attribute name="join" type="penjoin_type" use="required" />
299                   <xs:attribute name="brush" type="name_type" use="required"/>
300                 </xs:complexType>
301               </xs:element>
302               <xs:element name="font" minOccurs="0" maxOccurs="unbounded">
303                 <xs:complexType>
304                   <xs:attribute name="name" type="name_type" use="required" />
305                   <xs:attribute name="face" type="xs:string" use="required" />
306                   <xs:attribute name="size" type="xs:unsignedInt" use="required" />
307                   <xs:attribute name="bold" type="boolean_type" />
308                   <xs:attribute name="italic" type="boolean_type" />
309                   <xs:attribute name="underline" type="boolean_type" />
310                   <xs:attribute name="strike-out" type="boolean_type" />
311                 </xs:complexType>
312               </xs:element>
313               <xs:element name="bitmap" minOccurs="0" maxOccurs="unbounded">
314                 <xs:complexType>
315                   <xs:attribute name="name" type="name_type" use="required" />
316                   <xs:attribute name="filename" type="xs:string" use="required" />
317                 </xs:complexType>
318               </xs:element>
319             </xs:sequence>
320           </xs:complexType>
321         </xs:element>
322         <xs:element name="templates" minOccurs="0" maxOccurs="1">
323           <xs:complexType>
324             <xs:sequence>
325               <xs:element name="template" minOccurs="1" maxOccurs="unbounded">
326                 <xs:complexType>
327                   <xs:sequence>
328                     <xs:element name="information" minOccurs="0" maxOccurs="1">
329                       <xs:complexType>
330                         <xs:sequence>
331                           <xs:element name="property" minOccurs="1" maxOccurs="unbounded">
332                             <xs:complexType>
333                               <xs:attribute name="name" type="name_type" use="required" />
334                               <xs:attribute name="value" type="xs:string" use="required" />
335                             </xs:complexType>
336                           </xs:element>
337                         </xs:sequence>
338                       </xs:complexType>
339                     </xs:element>
340                     <xs:element name="properties" minOccurs="0" maxOccurs="1">
341                       <xs:complexType>
342                         <xs:sequence>
343                           <xs:element name="property" minOccurs="1" maxOccurs="unbounded">
344                             <xs:complexType>
345                               <xs:attribute name="name" type="name_type" use="required" />
346                               <xs:attribute name="type" type="property_type" use="required" />
347                             </xs:complexType>
348                           </xs:element>
349                         </xs:sequence>
350                       </xs:complexType>
351                     </xs:element>
352                     <xs:element name="content" minOccurs="1" maxOccurs="1">
353                       <xs:complexType>
354                         <xs:sequence>
355                           <xs:group ref="element_group" minOccurs="1" maxOccurs="unbounded"/>
356                         </xs:sequence>
357                       </xs:complexType>
358                     </xs:element>
359                   </xs:sequence>
360                   <xs:attribute name="name" type="name_type" use="required"/>
361                 </xs:complexType>
362               </xs:element>
363             </xs:sequence>
364           </xs:complexType>
365         </xs:element>
366       </xs:sequence>
367       <xs:attribute name="reference" type="xs:string" />
368     </xs:complexType>
369   </xs:element>
370 </xs:schema>

    最后附上一段比较简单的例子:
 1 <?xml version="1.0" encoding="utf-8" ?>
 2 <irconfig xmlns="http://tempuri.org/irconfig.xsd">
 3   <resources>
 4     <brush name="blue-brush" kind="solid">
 5       <main-color r="0" g="0" b="255"/>
 6     </brush>
 7     <brush name="black-brush" kind="solid">
 8       <main-color r="0" g="0" b="0"/>
 9     </brush>
10     <pen name="border-pen" brush="black-brush" endcap="round" join="round" weight="1"/>
11   </resources>
12   <templates>
13     <template name="inactive">
14       <properties>
15         <property name="x" type="int"/>
16         <property name="y" type="int"/>
17         <property name="w" type="int"/>
18         <property name="h" type="int"/>
19       </properties>
20       <content>
21         <rectangle x="x" y="y" width="w" height="h" brush="blue-brush"/>
22       </content>
23     </template>
24     <template name="active">
25       <properties>
26         <property name="x" type="int"/>
27         <property name="y" type="int"/>
28         <property name="w" type="int"/>
29         <property name="h" type="int"/>
30       </properties>
31       <content>
32         <rectangle x="x" y="y" width="w" height="h" pen="border-pen" brush="blue-brush"/>
33       </content>
34     </template>
35   </templates>
36 </irconfig>
37 

    只要写上了xmlns属性,那么Visual Studio 2008就会自动读取那个xsd然后提供自动补全功能了,写起来无敌爽。
posted on 2009-08-07 07:29 陈梓瀚(vczh) 阅读(2967) 评论(1)  编辑 收藏 引用 所属分类: 2D

评论:
# re: C++界面库:为Graphic Element Template做了一个XML Schema 2009-08-12 01:14 | ABC
谢谢你,学习了!  回复  更多评论
  

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理