silverlight.js 23 KB

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