2150 |
mathias |
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 |
}
|