我们知道制作控件的时候,其实最困难的不是定出那个支撑整个系统的架构,而是为各种空间写绘制的代码(囧)。为了解决这个问题,我在这套
渲染库上设计了一种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) 阅读(2995)
评论(1) 编辑 收藏 引用 所属分类:
2D