]> git.pond.sub.org Git - eow/blob - static/dojo-release-1.1.1/dojox/gfx/silverlight.js
add Dojo 1.1.1
[eow] / static / dojo-release-1.1.1 / dojox / gfx / silverlight.js
1 if(!dojo._hasResource["dojox.gfx.silverlight"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
2 dojo._hasResource["dojox.gfx.silverlight"] = true;
3 dojo.provide("dojox.gfx.silverlight");
4
5 dojo.require("dojox.gfx._base");
6 dojo.require("dojox.gfx.shape");
7 dojo.require("dojox.gfx.path");
8
9 dojo.experimental("dojox.gfx.silverlight");
10
11 dojox.gfx.silverlight.dasharray = {
12         solid:                          "none",
13         shortdash:                      [4, 1],
14         shortdot:                       [1, 1],
15         shortdashdot:           [4, 1, 1, 1],
16         shortdashdotdot:        [4, 1, 1, 1, 1, 1],
17         dot:                            [1, 3],
18         dash:                           [4, 3],
19         longdash:                       [8, 3],
20         dashdot:                        [4, 3, 1, 3],
21         longdashdot:            [8, 3, 1, 3],
22         longdashdotdot:         [8, 3, 1, 3, 1, 3]
23 };
24
25 dojox.gfx.silverlight.fontweight = {
26         normal: 400,
27         bold:   700
28 };
29
30 dojox.gfx.silverlight.caps  = {butt: "Flat", round: "Round", square: "Square"};
31 dojox.gfx.silverlight.joins = {bevel: "Bevel", round: "Round"};
32
33 dojox.gfx.silverlight.fonts = {
34         serif: "Times New Roman",
35         times: "Times New Roman",
36         "sans-serif": "Arial",
37         helvetica: "Arial",
38         monotone: "Courier New",
39         courier: "Courier New"
40 };
41
42 dojox.gfx.silverlight.hexColor = function(/*String|Array|dojo.Color*/ color){
43         // summary: converts a color object to a Silverlight hex color string (#aarrggbb)
44         var c = dojox.gfx.normalizeColor(color),
45                 t = c.toHex(), a = Math.round(c.a * 255);
46         a = (a < 0 ? 0 : a > 255 ? 255 : a).toString(16);
47         return "#" + (a.length < 2 ? "0" + a : a) + t.slice(1); // String
48 };
49
50 dojo.extend(dojox.gfx.Shape, {
51         // summary: Silverlight-specific implementation of dojox.gfx.Shape methods
52         
53         setFill: function(fill){
54                 // summary: sets a fill object (Silverlight)
55                 // fill: Object: a fill object
56                 //      (see dojox.gfx.defaultLinearGradient, 
57                 //      dojox.gfx.defaultRadialGradient, 
58                 //      dojox.gfx.defaultPattern, 
59                 //      or dojo.Color)
60
61                 var p = this.rawNode.getHost().content, r = this.rawNode, f;
62                 if(!fill){
63                         // don't fill
64                         this.fillStyle = null;
65                         this._setFillAttr(null);
66                         return this;    // self
67                 }
68                 if(typeof(fill) == "object" && "type" in fill){
69                         // gradient
70                         switch(fill.type){
71                                 case "linear":
72                                         this.fillStyle = f = dojox.gfx.makeParameters(dojox.gfx.defaultLinearGradient, fill);
73                                         var lgb = p.createFromXaml("<LinearGradientBrush/>");
74                                         lgb.mappingMode = "Absolute";
75                                         lgb.startPoint = f.x1 + "," + f.y1;
76                                         lgb.endPoint = f.x2 + "," + f.y2;
77                                         dojo.forEach(f.colors, function(c){
78                                                 var t = p.createFromXaml("<GradientStop/>");
79                                                 t.offset = c.offset;
80                                                 t.color = dojox.gfx.silverlight.hexColor(c.color);
81                                                 lgb.gradientStops.add(t);
82                                         });
83                                         this._setFillAttr(lgb);
84                                         break;
85                                 case "radial":
86                                         this.fillStyle = f = dojox.gfx.makeParameters(dojox.gfx.defaultRadialGradient, fill);
87                                         var rgb = p.createFromXaml("<RadialGradientBrush/>"), w = r.width, h = r.height,
88                                                 l = this.rawNode["Canvas.Left"], t = this.rawNode["Canvas.Top"];
89                                         rgb.center = (f.cx - l) / w + "," + (f.cy - t) / h;
90                                         rgb.radiusX = f.r / w;
91                                         rgb.radiusY = f.r / h;
92                                         dojo.forEach(f.colors, function(c){
93                                                 var t = p.createFromXaml("<GradientStop/>");
94                                                 t.offset = c.offset;
95                                                 t.color = dojox.gfx.silverlight.hexColor(c.color);
96                                                 rgb.gradientStops.add(t);
97                                         });
98                                         this._setFillAttr(rgb);
99                                         break;
100                                 case "pattern":
101                                         // don't fill: Silverlight doesn't define TileBrush for some reason
102                                         this.fillStyle = null;
103                                         this._setFillAttr(null);
104                                         break;
105                         }
106                         return this;    // self
107                 }
108                 // color object
109                 this.fillStyle = f = dojox.gfx.normalizeColor(fill);
110                 var scb = p.createFromXaml("<SolidColorBrush/>");
111                 scb.color = f.toHex();
112                 scb.opacity = f.a;
113                 this._setFillAttr(scb);
114                 return this;    // self
115         },
116         _setFillAttr: function(f){
117                 this.rawNode.fill = f;
118         },
119
120         setStroke: function(stroke){
121                 // summary: sets a stroke object (Silverlight)
122                 // stroke: Object: a stroke object
123                 //      (see dojox.gfx.defaultStroke) 
124         
125                 var p = this.rawNode.getHost().content, r = this.rawNode;
126                 if(!stroke){
127                         // don't stroke
128                         this.strokeStyle = null;
129                         r.stroke = null;
130                         return this;
131                 }
132                 // normalize the stroke
133                 if(typeof stroke == "string"){
134                         stroke = {color: stroke};
135                 }
136                 var s = this.strokeStyle = dojox.gfx.makeParameters(dojox.gfx.defaultStroke, stroke);
137                 s.color = dojox.gfx.normalizeColor(s.color);
138                 // generate attributes
139                 if(s){
140                         var scb = p.createFromXaml("<SolidColorBrush/>");
141                         scb.color = s.color.toHex();
142                         scb.opacity = s.color.a;
143                         r.stroke = scb;
144                         r.strokeThickness = s.width;
145                         r.strokeStartLineCap = r.strokeEndLineCap = r.strokeDashCap = 
146                                 dojox.gfx.silverlight.caps[s.cap];
147                         if(typeof s.join == "number"){
148                                 r.strokeLineJoin = "Miter";
149                                 r.strokeMiterLimit = s.join;
150                         }else{
151                                 r.strokeLineJoin = dojox.gfx.silverlight.joins[s.join];
152                         }
153                         var da = s.style.toLowerCase();
154                         if(da in dojox.gfx.silverlight.dasharray){ da = dojox.gfx.silverlight.dasharray[da]; }
155                         if(da instanceof Array){
156                                 da = dojo.clone(da);
157                                 /*
158                                 for(var i = 0; i < da.length; ++i){
159                                         da[i] *= s.width;
160                                 }
161                                 */
162                                 if(s.cap != "butt"){
163                                         for(var i = 0; i < da.length; i += 2){
164                                                 //da[i] -= s.width;
165                                                 --da[i]
166                                                 if(da[i] < 1){ da[i] = 1; }
167                                         }
168                                         for(var i = 1; i < da.length; i += 2){
169                                                 //da[i] += s.width;
170                                                 ++da[i];
171                                         }
172                                 }
173                                 r.strokeDashArray = da.join(",");
174                         }else{
175                                 r.strokeDashArray = null;
176                         }
177                 }
178                 return this;    // self
179         },
180         
181         _getParentSurface: function(){
182                 var surface = this.parent;
183                 for(; surface && !(surface instanceof dojox.gfx.Surface); surface = surface.parent);
184                 return surface;
185         },
186         
187         _applyTransform: function() {
188                 var tm = this.matrix, r = this.rawNode;
189                 if(tm){
190                         var p = this.rawNode.getHost().content,
191                                 m = p.createFromXaml("<MatrixTransform/>"),
192                                 mm = p.createFromXaml("<Matrix/>");
193                         mm.m11 = tm.xx;
194                         mm.m21 = tm.xy;
195                         mm.m12 = tm.yx;
196                         mm.m22 = tm.yy;
197                         mm.offsetX = tm.dx;
198                         mm.offsetY = tm.dy;
199                         m.matrix = mm;
200                         r.renderTransform = m;
201                 }else{
202                         r.renderTransform = null;
203                 }
204                 return this;
205         },
206
207         setRawNode: function(rawNode){
208                 // summary:
209                 //      assigns and clears the underlying node that will represent this
210                 //      shape. Once set, transforms, gradients, etc, can be applied.
211                 //      (no fill & stroke by default)
212                 rawNode.fill = null;
213                 rawNode.stroke = null;
214                 this.rawNode = rawNode;
215         },
216         
217         // move family
218
219         _moveToFront: function(){
220                 // summary: moves a shape to front of its parent's list of shapes (Silverlight)
221                 var c = this.parent.rawNode.children, r = this.rawNode;
222                 c.remove(r);
223                 c.add(r);
224                 return this;    // self
225         },
226         _moveToBack: function(){
227                 // summary: moves a shape to back of its parent's list of shapes (Silverlight)
228                 var c = this.parent.rawNode.children, r = this.rawNode;
229                 c.remove(r);
230                 c.insert(0, r);
231                 return this;    // self
232         }
233 });
234
235 dojo.declare("dojox.gfx.Group", dojox.gfx.Shape, {
236         // summary: a group shape (Silverlight), which can be used 
237         //      to logically group shapes (e.g, to propagate matricies)
238         constructor: function(){
239                 dojox.gfx.silverlight.Container._init.call(this);
240         },
241         setRawNode: function(rawNode){
242                 // summary: sets a raw Silverlight node to be used by this shape
243                 // rawNode: Node: an Silverlight node
244                 this.rawNode = rawNode;
245         }
246 });
247 dojox.gfx.Group.nodeType = "Canvas";
248
249 dojo.declare("dojox.gfx.Rect", dojox.gfx.shape.Rect, {
250         // summary: a rectangle shape (Silverlight)
251         setShape: function(newShape){
252                 // summary: sets a rectangle shape object (Silverlight)
253                 // newShape: Object: a rectangle shape object
254                 this.shape = dojox.gfx.makeParameters(this.shape, newShape);
255                 this.bbox = null;
256                 var r = this.rawNode, n = this.shape;
257                 r["Canvas.Left"] = n.x;
258                 r["Canvas.Top"]  = n.y;
259                 r.width   = n.width;
260                 r.height  = n.height;
261                 r.radiusX = r.radiusY = n.r;
262                 return this;    // self
263         }
264 });
265 dojox.gfx.Rect.nodeType = "Rectangle";
266
267 dojo.declare("dojox.gfx.Ellipse", dojox.gfx.shape.Ellipse, {
268         // summary: an ellipse shape (Silverlight)
269         setShape: function(newShape){
270                 // summary: sets an ellipse shape object (Silverlight)
271                 // newShape: Object: an ellipse shape object
272                 this.shape = dojox.gfx.makeParameters(this.shape, newShape);
273                 this.bbox = null;
274                 var r = this.rawNode, n = this.shape;
275                 r["Canvas.Left"] = n.cx - n.rx;
276                 r["Canvas.Top"]  = n.cy - n.ry;
277                 r.width  = 2 * n.rx;
278                 r.height = 2 * n.ry;
279                 return this;    // self
280         }
281 });
282 dojox.gfx.Ellipse.nodeType = "Ellipse";
283
284 dojo.declare("dojox.gfx.Circle", dojox.gfx.shape.Circle, {
285         // summary: a circle shape (Silverlight)
286         setShape: function(newShape){
287                 // summary: sets a circle shape object (Silverlight)
288                 // newShape: Object: a circle shape object
289                 this.shape = dojox.gfx.makeParameters(this.shape, newShape);
290                 this.bbox = null;
291                 var r = this.rawNode, n = this.shape;
292                 r["Canvas.Left"] = n.cx - n.r;
293                 r["Canvas.Top"]  = n.cy - n.r;
294                 r.width = r.height = 2 * n.r;
295                 return this;    // self
296         }
297 });
298 dojox.gfx.Circle.nodeType = "Ellipse";
299
300 dojo.declare("dojox.gfx.Line", dojox.gfx.shape.Line, {
301         // summary: a line shape (Silverlight)
302         setShape: function(newShape){
303                 // summary: sets a line shape object (Silverlight)
304                 // newShape: Object: a line shape object
305                 this.shape = dojox.gfx.makeParameters(this.shape, newShape);
306                 this.bbox = null;
307                 var r = this.rawNode, n = this.shape;
308                 r.x1 = n.x1; r.y1 = n.y1; r.x2 = n.x2; r.y2 = n.y2;
309                 return this;    // self
310         }
311 });
312 dojox.gfx.Line.nodeType = "Line";
313
314 dojo.declare("dojox.gfx.Polyline", dojox.gfx.shape.Polyline, {
315         // summary: a polyline/polygon shape (Silverlight)
316         setShape: function(points, closed){
317                 // summary: sets a polyline/polygon shape object (Silverlight)
318                 // points: Object: a polyline/polygon shape object
319                 if(points && points instanceof Array){
320                         // branch
321                         // points: Array: an array of points
322                         this.shape = dojox.gfx.makeParameters(this.shape, {points: points});
323                         if(closed && this.shape.points.length){ 
324                                 this.shape.points.push(this.shape.points[0]);
325                         }
326                 }else{
327                         this.shape = dojox.gfx.makeParameters(this.shape, points);
328                 }
329                 this.box = null;
330                 var p = this.shape.points, rp = [];
331                 for(var i = 0; i < p.length; ++i){
332                         if(typeof p[i] == "number"){
333                                 rp.push(p[i], p[++i]);
334                         }else{
335                                 rp.push(p[i].x, p[i].y);
336                         }
337                 }
338                 this.rawNode.points = rp.join(",");
339                 return this;    // self
340         }
341 });
342 dojox.gfx.Polyline.nodeType = "Polyline";
343
344 dojo.declare("dojox.gfx.Image", dojox.gfx.shape.Image, {
345         // summary: an image (Silverlight)
346         setShape: function(newShape){
347                 // summary: sets an image shape object (Silverlight)
348                 // newShape: Object: an image shape object
349                 this.shape = dojox.gfx.makeParameters(this.shape, newShape);
350                 this.bbox = null;
351                 var r = this.rawNode, n = this.shape;
352                 r["Canvas.Left"] = n.x;
353                 r["Canvas.Top"]  = n.y;
354                 r.width  = n.width;
355                 r.height = n.height;
356                 r.source = n.src;
357                 return this;    // self
358         },
359         setRawNode: function(rawNode){
360                 // summary:
361                 //      assigns and clears the underlying node that will represent this
362                 //      shape. Once set, transforms, gradients, etc, can be applied.
363                 //      (no fill & stroke by default)
364                 this.rawNode = rawNode;
365         }
366 });
367 dojox.gfx.Image.nodeType = "Image";
368
369 dojo.declare("dojox.gfx.Text", dojox.gfx.shape.Text, {
370         // summary: an anchored text (Silverlight)
371         setShape: function(newShape){
372                 // summary: sets a text shape object (Silverlight)
373                 // newShape: Object: a text shape object
374                 this.shape = dojox.gfx.makeParameters(this.shape, newShape);
375                 this.bbox = null;
376                 var r = this.rawNode, s = this.shape;
377                 r.text = s.text;
378                 r.textDecorations = s.decoration == "underline" ? "Underline" : "None";
379                 r["Canvas.Left"] = -10000;
380                 r["Canvas.Top"]  = -10000;
381                 window.setTimeout(dojo.hitch(this, "_delayAlignment"), 0);
382                 return this;    // self
383         },
384         _delayAlignment: function(){
385                 // handle alignment
386                 var r = this.rawNode, s = this.shape,
387                         w = r.actualWidth, h = r.actualHeight, x = s.x, y = s.y - h * 0.75;
388                 switch(s.align){
389                         case "middle":
390                                 x -= w / 2;
391                                 break;
392                         case "end":
393                                 x -= w;
394                                 break;
395                 }
396                 var a = this.matrix ? dojox.gfx.matrix.multiplyPoint(this.matrix, x, y) : {x: x, y: y};
397                 r["Canvas.Left"] = a.x;
398                 r["Canvas.Top"]  = a.y;
399         },
400         setStroke: function(){
401                 // summary: ignore setting a stroke style
402                 return this;    // self
403         },
404         _setFillAttr: function(f){
405                 this.rawNode.foreground = f;
406         },
407         setRawNode: function(rawNode){
408                 // summary:
409                 //      assigns and clears the underlying node that will represent this
410                 //      shape. Once set, transforms, gradients, etc, can be applied.
411                 //      (no fill & stroke by default)
412                 this.rawNode = rawNode;
413         },
414         _applyTransform: function() {
415                 var tm = this.matrix, r = this.rawNode;
416                 if(tm){
417                         // the next line is pure magic :-(
418                         tm = dojox.gfx.matrix.normalize([1/100, tm, 100]);
419                         var p = this.rawNode.getHost().content,
420                                 m = p.createFromXaml("<MatrixTransform/>"),
421                                 mm = p.createFromXaml("<Matrix/>");
422                         mm.m11 = tm.xx;
423                         mm.m21 = tm.xy;
424                         mm.m12 = tm.yx;
425                         mm.m22 = tm.yy;
426                         mm.offsetX = tm.dx;
427                         mm.offsetY = tm.dy;
428                         m.matrix = mm;
429                         r.renderTransform = m;
430                 }else{
431                         r.renderTransform = null;
432                 }
433                 return this;
434         },
435         getTextWidth: function(){ 
436                 // summary: get the text width in pixels 
437                 return this.rawNode.actualWidth; 
438         } 
439 });
440 dojox.gfx.Text.nodeType = "TextBlock";
441
442 dojo.declare("dojox.gfx.Path", dojox.gfx.path.Path, {
443         // summary: a path shape (Silverlight)
444         _updateWithSegment: function(segment){
445                 // summary: updates the bounding box of path with new segment
446                 // segment: Object: a segment
447                 dojox.gfx.Path.superclass._updateWithSegment.apply(this, arguments);
448                 var p = this.shape.path;
449                 if(typeof(p) == "string"){
450                         this.rawNode.data = p ? p : null;
451                 }
452         },
453         setShape: function(newShape){
454                 // summary: forms a path using a shape (Silverlight)
455                 // newShape: Object: an SVG path string or a path object (see dojox.gfx.defaultPath)
456                 dojox.gfx.Path.superclass.setShape.apply(this, arguments);
457                 var p = this.shape.path;
458                 this.rawNode.data = p ? p : null;
459                 return this;    // self
460         }
461 });
462 dojox.gfx.Path.nodeType = "Path";
463
464 dojo.declare("dojox.gfx.TextPath", dojox.gfx.path.TextPath, {
465         // summary: a textpath shape (Silverlight)
466         _updateWithSegment: function(segment){
467                 // summary: updates the bounding box of path with new segment
468                 // segment: Object: a segment
469         },
470         setShape: function(newShape){
471                 // summary: forms a path using a shape (Silverlight)
472                 // newShape: Object: an SVG path string or a path object (see dojox.gfx.defaultPath)
473         },
474         _setText: function(){
475         }
476 });
477 dojox.gfx.TextPath.nodeType = "text";
478
479 dojo.declare("dojox.gfx.Surface", dojox.gfx.shape.Surface, {
480         // summary: a surface object to be used for drawings (Silverlight)
481         constructor: function(){
482                 dojox.gfx.silverlight.Container._init.call(this);
483         },
484         setDimensions: function(width, height){
485                 // summary: sets the width and height of the rawNode
486                 // width: String: width of surface, e.g., "100px"
487                 // height: String: height of surface, e.g., "100px"
488                 this.width  = dojox.gfx.normalizedLength(width);        // in pixels
489                 this.height = dojox.gfx.normalizedLength(height);       // in pixels
490                 var p = this.rawNode && this.rawNode.getHost();
491                 if(p){
492                         p.width = width;
493                         p.height = height;
494                 }
495                 return this;    // self
496         },
497         getDimensions: function(){
498                 // summary: returns an object with properties "width" and "height"
499                 var p = this.rawNode && this.rawNode.getHost();
500                 var t = p ? {width: p.content.actualWidth, height: p.content.actualHeight} : null;
501                 if(t.width  <= 0){ t.width  = this.width; }
502                 if(t.height <= 0){ t.height = this.height; }
503                 return t;       // Object
504         }
505 });
506
507 dojox.gfx.silverlight.surfaces = {};
508
509 dojox.gfx.createSurface = function(parentNode, width, height){
510         // summary: creates a surface (Silverlight)
511         // parentNode: Node: a parent node
512         // width: String: width of surface, e.g., "100px"
513         // height: String: height of surface, e.g., "100px"
514
515         var s = new dojox.gfx.Surface();
516         parentNode = dojo.byId(parentNode);
517         // create an empty canvas
518         var t = parentNode.ownerDocument.createElement("script");
519         t.type = "text/xaml";
520         t.id = dojox.gfx._base._getUniqueId();
521         t.text = "<Canvas xmlns='http://schemas.microsoft.com/client/2007' Name='" + dojox.gfx._base._getUniqueId() + "'/>";
522         document.body.appendChild(t);
523         // create a plugin
524         var pluginName = dojox.gfx._base._getUniqueId();
525         Silverlight.createObject(
526                 "#" + t.id,     // none
527                 parentNode,
528                 pluginName,
529                 {                                                                               // Plugin properties.
530                         width:  String(width),                          // Width of rectangular region of plugin in pixels.
531                         height: String(height),                         // Height of rectangular region of plugin in pixels.
532                         inplaceInstallPrompt:   "false",        // Determines whether to display in-place install prompt if invalid version detected.
533                         //background:           "white",                // Background color of plugin.
534                         //isWindowless: "false",                        // Determines whether to display plugin in Windowless mode.
535                         background:             "transparent",          // Background color of plugin.
536                         isWindowless:   "true",                         // Determines whether to display plugin in Windowless mode.
537                         framerate:              "24",                           // MaxFrameRate property value.
538                         version:                "1.0"                           // Silverlight version.
539                 },
540                 {},
541                 null,
542                 null
543         );
544         s.rawNode = dojo.byId(pluginName).content.root;
545         // register the plugin with its parent node
546         dojox.gfx.silverlight.surfaces[s.rawNode.name] = parentNode;
547         s.width  = dojox.gfx.normalizedLength(width);   // in pixels
548         s.height = dojox.gfx.normalizedLength(height);  // in pixels
549         return s;       // dojox.gfx.Surface
550 };
551
552 // Extenders
553
554 dojox.gfx.silverlight.Font = {
555         _setFont: function(){
556                 // summary: sets a font object (Silverlight)
557                 var f = this.fontStyle, r = this.rawNode,
558                         fw = dojox.gfx.silverlight.fontweight,
559                         fo = dojox.gfx.silverlight.fonts, t = f.family.toLowerCase();
560                 r.fontStyle = f.style == "italic" ? "Italic" : "Normal";
561                 r.fontWeight = f.weight in fw ? fw[f.weight] : f.weight;
562                 r.fontSize = dojox.gfx.normalizedLength(f.size);
563                 r.fontFamily = t in fo ? fo[t] : f.family;
564         }
565 };
566
567 dojox.gfx.silverlight.Container = {
568         _init: function(){
569                 dojox.gfx.shape.Container._init.call(this);
570         },
571         add: function(shape){
572                 // summary: adds a shape to a group/surface
573                 // shape: dojox.gfx.Shape: an VML shape object
574                 if(this != shape.getParent()){
575                         //dojox.gfx.Group.superclass.add.apply(this, arguments);
576                         //this.inherited(arguments);
577                         dojox.gfx.shape.Container.add.apply(this, arguments);
578                         this.rawNode.children.add(shape.rawNode);
579                 }
580                 return this;    // self
581         },
582         remove: function(shape, silently){
583                 // summary: remove a shape from a group/surface
584                 // shape: dojox.gfx.Shape: an VML shape object
585                 // silently: Boolean?: if true, regenerate a picture
586                 if(this == shape.getParent()){
587                         var parent = shape.rawNode.getParent();
588                         if(parent){
589                                 parent.children.remove(shape.rawNode);
590                         }
591                         //dojox.gfx.Group.superclass.remove.apply(this, arguments);
592                         //this.inherited(arguments);
593                         dojox.gfx.shape.Container.remove.apply(this, arguments);
594                 }
595                 return this;    // self
596         },
597         clear: function(){
598                 // summary: removes all shapes from a group/surface
599                 this.rawNode.children.clear();
600                 //return this.inherited(arguments);     // self
601                 return dojox.gfx.shape.Container.clear.apply(this, arguments);
602         },
603         _moveChildToFront: dojox.gfx.shape.Container._moveChildToFront,
604         _moveChildToBack:  dojox.gfx.shape.Container._moveChildToBack
605 };
606
607 dojo.mixin(dojox.gfx.shape.Creator, {
608         createObject: function(shapeType, rawShape){
609                 // summary: creates an instance of the passed shapeType class
610                 // shapeType: Function: a class constructor to create an instance of
611                 // rawShape: Object: properties to be passed in to the classes "setShape" method
612                 if(!this.rawNode){ return null; }
613                 var shape = new shapeType();
614                 var node = this.rawNode.getHost().content.createFromXaml("<" + shapeType.nodeType + "/>");
615                 shape.setRawNode(node);
616                 shape.setShape(rawShape);
617                 this.add(shape);
618                 return shape;   // dojox.gfx.Shape
619         }
620 });
621
622 dojo.extend(dojox.gfx.Text, dojox.gfx.silverlight.Font);
623 //dojo.extend(dojox.gfx.TextPath, dojox.gfx.silverlight.Font);
624
625 dojo.extend(dojox.gfx.Group, dojox.gfx.silverlight.Container);
626 dojo.extend(dojox.gfx.Group, dojox.gfx.shape.Creator);
627
628 dojo.extend(dojox.gfx.Surface, dojox.gfx.silverlight.Container);
629 dojo.extend(dojox.gfx.Surface, dojox.gfx.shape.Creator);
630
631 (function(){
632         var surfaces = dojox.gfx.silverlight.surfaces;
633         var mouseFix = function(s, a){
634                 var ev = {target: s, currentTarget: s, 
635                         preventDefault: function(){}, stopPropagation: function(){}};
636                 if(a){
637                         ev.ctrlKey = a.ctrl;
638                         ev.shiftKey = a.shift;
639                         var p = a.getPosition(null);
640                         ev.x = ev.offsetX = ev.layerX = p.x;
641                         ev.y = ev.offsetY = ev.layerY = p.y;
642                         // calculate clientX and clientY
643                         var parent = surfaces[s.getHost().content.root.name];
644                         var t = dojo._abs(parent);
645                         ev.clientX = t.x + p.x;
646                         ev.clientY = t.y + p.y;
647                 }
648                 return ev;
649         };
650         var keyFix = function(s, a){
651                 var ev = {
652                         keyCode:  a.platformKeyCode,
653                         ctrlKey:  a.ctrl,
654                         shiftKey: a.shift
655                 };
656                 return ev;
657         };
658         var eventNames = {
659                 onclick:                {name: "MouseLeftButtonUp", fix: mouseFix},
660                 onmouseenter:   {name: "MouseEnter", fix: mouseFix},
661                 onmouseleave:   {name: "MouseLeave", fix: mouseFix},
662                 onmousedown:    {name: "MouseLeftButtonDown", fix: mouseFix},
663                 onmouseup:              {name: "MouseLeftButtonUp", fix: mouseFix},
664                 onmousemove:    {name: "MouseMove", fix: mouseFix},
665                 onkeydown:              {name: "KeyDown", fix: keyFix},
666                 onkeyup:                {name: "KeyUp", fix: keyFix}
667         };
668         var eventsProcessing = {
669                 connect: function(name, object, method){
670                         var token, n = name in eventNames ? eventNames[name] : 
671                                 {name: name, fix: function(){ return {}; }};
672                         if(arguments.length > 2){
673                                 token = this.getEventSource().addEventListener(n.name, 
674                                         function(s, a){ dojo.hitch(object, method)(n.fix(s, a)); });
675                         }else{
676                                 token = this.getEventSource().addEventListener(n.name, 
677                                         function(s, a){ object(n.fix(s, a)); });
678                         }
679                         return {name: n.name, token: token};
680                 },
681                 disconnect: function(token){
682                         this.getEventSource().removeEventListener(token.name, token.token);
683                 }
684         };
685         dojo.extend(dojox.gfx.Shape, eventsProcessing);
686         dojo.extend(dojox.gfx.Surface, eventsProcessing);
687         dojox.gfx.equalSources = function(a, b){
688                 return a && b && a.equals(b);
689         }
690
691 })();
692
693 }