[483] | 1 | define(["dojo/_base/lang", "dojo/_base/declare", "dojo/dom-geometry", "dijit/registry", "dijit/_WidgetBase", "dojo/_base/html", |
---|
| 2 | "dojo/_base/event", "dojox/gfx", "dojox/widget/_Invalidating","./ScaleBase", "dojox/gfx/matrix"], |
---|
| 3 | function(lang, // lang.extend |
---|
| 4 | declare, domGeom, WidgetRegistry, _WidgetBase, html, event, gfx, _Invalidating, ScaleBase, matrix){ |
---|
| 5 | return declare("dojox.dgauges.GaugeBase", [_WidgetBase, _Invalidating], { |
---|
| 6 | // summary: |
---|
| 7 | // This class is the base class for the circular and |
---|
| 8 | // rectangular (horizontal and vertical) gauge components. |
---|
| 9 | // A gauge is a composition of elements added to the gauge using the addElement method. |
---|
| 10 | // Elements are drawn from back to front in the same order they are added (using addElement). |
---|
| 11 | // An elements can be: |
---|
| 12 | // |
---|
| 13 | // - A GFX drawing functions typically used for defining the style of the gauge. |
---|
| 14 | // - A scale: CircularScale or RectangularScale depending on the type of gauge. |
---|
| 15 | // - A text, using the TextIndicator |
---|
| 16 | // Note: Indicator classes (value indicators, range indicators) are sub-elements of scales |
---|
| 17 | // To create a custom gauge, subclass CircularGauge or RectangularGauge and |
---|
| 18 | // configure its elements in the constructor. |
---|
| 19 | // Ready to use, predefined gauges are available in dojox/dgauges/components/ |
---|
| 20 | // They are good examples of gauges built on top of the framework. |
---|
| 21 | |
---|
| 22 | _elements: null, |
---|
| 23 | _scales: null, |
---|
| 24 | _elementsIndex: null, |
---|
| 25 | _elementsRenderers: null, |
---|
| 26 | _gfxGroup: null, |
---|
| 27 | _mouseShield: null, |
---|
| 28 | _widgetBox: null, |
---|
| 29 | _node: null, |
---|
| 30 | |
---|
| 31 | // value: Number |
---|
| 32 | // This property acts as a top-level wrapper for the value of the first indicator added to |
---|
| 33 | // its scale with the name "indicator", i.e. myScale.addIndicator("indicator", myIndicator). |
---|
| 34 | // This property must be manipulated with get("value") and set("value", xxx). |
---|
| 35 | value: 0, |
---|
| 36 | _mainIndicator: null, |
---|
| 37 | |
---|
| 38 | _getValueAttr: function(){ |
---|
| 39 | // summary: |
---|
| 40 | // Internal method. |
---|
| 41 | // tags: |
---|
| 42 | // private |
---|
| 43 | if(this._mainIndicator){ |
---|
| 44 | return this._mainIndicator.get("value"); |
---|
| 45 | }else{ |
---|
| 46 | this._setMainIndicator(); |
---|
| 47 | if(this._mainIndicator){ |
---|
| 48 | return this._mainIndicator.get("value"); |
---|
| 49 | } |
---|
| 50 | } |
---|
| 51 | return this.value; |
---|
| 52 | }, |
---|
| 53 | |
---|
| 54 | _setValueAttr: function(value){ |
---|
| 55 | // summary: |
---|
| 56 | // Internal method. |
---|
| 57 | // tags: |
---|
| 58 | // private |
---|
| 59 | this._set("value", value); |
---|
| 60 | if(this._mainIndicator){ |
---|
| 61 | this._mainIndicator.set("value", value); |
---|
| 62 | }else{ |
---|
| 63 | this._setMainIndicator(); |
---|
| 64 | if(this._mainIndicator){ |
---|
| 65 | this._mainIndicator.set("value", value); |
---|
| 66 | } |
---|
| 67 | } |
---|
| 68 | }, |
---|
| 69 | |
---|
| 70 | _setMainIndicator: function(){ |
---|
| 71 | // summary: |
---|
| 72 | // Internal method. |
---|
| 73 | // tags: |
---|
| 74 | // private |
---|
| 75 | var indicator; |
---|
| 76 | for(var i=0; i<this._scales.length; i++){ |
---|
| 77 | indicator = this._scales[i].getIndicator("indicator"); |
---|
| 78 | if(indicator){ |
---|
| 79 | this._mainIndicator = indicator; |
---|
| 80 | } |
---|
| 81 | } |
---|
| 82 | }, |
---|
| 83 | |
---|
| 84 | _resetMainIndicator: function(){ |
---|
| 85 | // summary: |
---|
| 86 | // Internal method. |
---|
| 87 | // tags: |
---|
| 88 | // private |
---|
| 89 | this._mainIndicator = null; |
---|
| 90 | }, |
---|
| 91 | |
---|
| 92 | // font: Object |
---|
| 93 | // The font of the gauge used by elements if not overridden. |
---|
| 94 | font: null, |
---|
| 95 | |
---|
| 96 | constructor: function(/* Object */args, /* DOMNode */ node){ |
---|
| 97 | this.font = { |
---|
| 98 | family: "Helvetica", |
---|
| 99 | style: "normal", |
---|
| 100 | variant: "small-caps", |
---|
| 101 | weight: "bold", |
---|
| 102 | size: "10pt", |
---|
| 103 | color: "black" |
---|
| 104 | }; |
---|
| 105 | this._elements = []; |
---|
| 106 | this._scales = []; |
---|
| 107 | this._elementsIndex = {}; |
---|
| 108 | this._elementsRenderers = {}; |
---|
| 109 | this._node = WidgetRegistry.byId(node); |
---|
| 110 | var box = html.getMarginBox(node); |
---|
| 111 | |
---|
| 112 | this.surface = gfx.createSurface(this._node, box.w || 1, box.h || 1); |
---|
| 113 | this._widgetBox = box; |
---|
| 114 | // _baseGroup is a workaround for http://bugs.dojotoolkit.org/ticket/14471 |
---|
| 115 | this._baseGroup = this.surface.createGroup(); |
---|
| 116 | this._mouseShield = this._baseGroup.createGroup(); |
---|
| 117 | this._gfxGroup = this._baseGroup.createGroup(); |
---|
| 118 | }, |
---|
| 119 | |
---|
| 120 | _setCursor: function(type){ |
---|
| 121 | // summary: |
---|
| 122 | // Internal method. |
---|
| 123 | // tags: |
---|
| 124 | // private |
---|
| 125 | if(this._node) |
---|
| 126 | this._node.style.cursor = type; |
---|
| 127 | }, |
---|
| 128 | |
---|
| 129 | _computeBoundingBox: function(/* Object */element){ |
---|
| 130 | // summary: |
---|
| 131 | // Internal method. |
---|
| 132 | // tags: |
---|
| 133 | // private |
---|
| 134 | return element ? element.getBoundingBox() : {x:0, y:0, width:0, height:0}; |
---|
| 135 | }, |
---|
| 136 | |
---|
| 137 | destroy: function(){ |
---|
| 138 | // summary: |
---|
| 139 | // Cleanup when a gauge is to be destroyed. |
---|
| 140 | this.surface.destroy(); |
---|
| 141 | this.inherited(arguments); |
---|
| 142 | }, |
---|
| 143 | |
---|
| 144 | resize: function(width, height){ |
---|
| 145 | // summary: |
---|
| 146 | // Resize the gauge to the dimensions of width and height. |
---|
| 147 | // description: |
---|
| 148 | // Resize the gauge and its surface to the width and height dimensions. |
---|
| 149 | // If a single argument of the form {w: value1, h: value2} is provided take that argument as the dimensions to use. |
---|
| 150 | // Finally if no argument is provided, resize the surface to the marginBox of the gauge. |
---|
| 151 | // width: Number|Object? |
---|
| 152 | // The new width of the gauge or the box definition. |
---|
| 153 | // height: Number? |
---|
| 154 | // The new height of the gauge. |
---|
| 155 | // returns: dojox/dgauges/GaugeBase |
---|
| 156 | // A reference to the current gauge for functional chaining. |
---|
| 157 | switch(arguments.length){ |
---|
| 158 | // case 0, do not resize the div, just the surface |
---|
| 159 | case 1: |
---|
| 160 | // argument, override node box |
---|
| 161 | domGeom.setMarginBox(this._node, width); |
---|
| 162 | break; |
---|
| 163 | case 2: |
---|
| 164 | |
---|
| 165 | // argument, override node box |
---|
| 166 | domGeom.setMarginBox(this._node, {w: width, h: height}); |
---|
| 167 | break; |
---|
| 168 | } |
---|
| 169 | // in all cases take back the computed box |
---|
| 170 | var box = domGeom.getMarginBox(this._node); |
---|
| 171 | this._widgetBox = box; |
---|
| 172 | var d = this.surface.getDimensions(); |
---|
| 173 | if(d.width != box.w || d.height != box.h){ |
---|
| 174 | // and set it on the surface |
---|
| 175 | this.surface.setDimensions(box.w, box.h); |
---|
| 176 | this._mouseShield.clear(); |
---|
| 177 | this._mouseShield.createRect({x:0,y:0,width:box.w,height:box.h}).setFill([0, 0, 0, 0]); |
---|
| 178 | return this.invalidateRendering(); |
---|
| 179 | }else{ |
---|
| 180 | return this; |
---|
| 181 | } |
---|
| 182 | }, |
---|
| 183 | |
---|
| 184 | addElement: function(/* String */name, /* Object */ element){ |
---|
| 185 | // summary: |
---|
| 186 | // Adds a element to the gauge. |
---|
| 187 | // name: String |
---|
| 188 | // The name of the element to be added. |
---|
| 189 | // element: Object |
---|
| 190 | // This parameter can be: |
---|
| 191 | // |
---|
| 192 | // - A function which takes on argument of type GFX Group and return null or a |
---|
| 193 | // GFX element retrievable using the getElementRenderer() method. |
---|
| 194 | // - A Scale instance, i.e. CircularScale or RectangularScale. |
---|
| 195 | // - A TextIndicator instance. |
---|
| 196 | if(this._elementsIndex[name] && this._elementsIndex[name] != element){ |
---|
| 197 | this.removeElement(name); |
---|
| 198 | } |
---|
| 199 | |
---|
| 200 | if(lang.isFunction(element)){ |
---|
| 201 | var gfxHolder = {}; |
---|
| 202 | lang.mixin(gfxHolder, new _Invalidating()); |
---|
| 203 | gfxHolder._name = name; |
---|
| 204 | gfxHolder._gfxGroup = this._gfxGroup.createGroup(); |
---|
| 205 | gfxHolder.width = 0; |
---|
| 206 | gfxHolder.height = 0; |
---|
| 207 | gfxHolder._isGFX = true; |
---|
| 208 | gfxHolder.refreshRendering = function(){ |
---|
| 209 | gfxHolder._gfxGroup.clear(); |
---|
| 210 | return element(gfxHolder._gfxGroup, gfxHolder.width, gfxHolder.height); |
---|
| 211 | }; |
---|
| 212 | this._elements.push(gfxHolder); |
---|
| 213 | this._elementsIndex[name] = gfxHolder; |
---|
| 214 | }else{ |
---|
| 215 | element._name = name; |
---|
| 216 | element._gfxGroup = this._gfxGroup.createGroup(); |
---|
| 217 | element._gauge = this; |
---|
| 218 | this._elements.push(element); |
---|
| 219 | this._elementsIndex[name] = element; |
---|
| 220 | |
---|
| 221 | if(element instanceof ScaleBase){ |
---|
| 222 | this._scales.push(element); |
---|
| 223 | } |
---|
| 224 | } |
---|
| 225 | return this.invalidateRendering(); |
---|
| 226 | }, |
---|
| 227 | |
---|
| 228 | removeElement: function(/* String */name){ |
---|
| 229 | // summary: |
---|
| 230 | // Remove the element defined by name from the gauge. |
---|
| 231 | // name: String |
---|
| 232 | // The name of the element as defined using addElement. |
---|
| 233 | // returns: Object |
---|
| 234 | // A reference to the removed element. |
---|
| 235 | |
---|
| 236 | var element = this._elementsIndex[name]; |
---|
| 237 | |
---|
| 238 | if(element){ |
---|
| 239 | element._gfxGroup.removeShape(); |
---|
| 240 | var idx = this._elements.indexOf(element); |
---|
| 241 | this._elements.splice(idx, 1); |
---|
| 242 | |
---|
| 243 | if(element instanceof ScaleBase){ |
---|
| 244 | var idxs = this._scales.indexOf(element); |
---|
| 245 | this._scales.splice(idxs, 1); |
---|
| 246 | this._resetMainIndicator(); |
---|
| 247 | } |
---|
| 248 | delete this._elementsIndex[name]; |
---|
| 249 | delete this._elementsRenderers[name]; |
---|
| 250 | } |
---|
| 251 | this.invalidateRendering(); |
---|
| 252 | return element; |
---|
| 253 | }, |
---|
| 254 | |
---|
| 255 | getElement: function(/* String */name){ |
---|
| 256 | // summary: |
---|
| 257 | // Get the given element, by name. |
---|
| 258 | // name: String |
---|
| 259 | // The name of the element as defined using addElement. |
---|
| 260 | // returns: Object |
---|
| 261 | // The element. |
---|
| 262 | return this._elementsIndex[name]; |
---|
| 263 | }, |
---|
| 264 | |
---|
| 265 | getElementRenderer: function(/* String */name){ |
---|
| 266 | // summary: |
---|
| 267 | // Get the given element renderer, by name. |
---|
| 268 | // name: String |
---|
| 269 | // The name of the element as defined using addElement. |
---|
| 270 | // returns: Object |
---|
| 271 | // The element renderer returned by the |
---|
| 272 | // drawing function or by the refreshRendering() method |
---|
| 273 | // in the case of framework classes. |
---|
| 274 | return this._elementsRenderers[name]; |
---|
| 275 | }, |
---|
| 276 | |
---|
| 277 | onStartEditing: function(event){ |
---|
| 278 | // summary: |
---|
| 279 | // Called when an interaction begins (keyboard, mouse or gesture). |
---|
| 280 | // event: |
---|
| 281 | // On object with a unique member "indicator". This member is a reference to the modified indicator. |
---|
| 282 | // tags: |
---|
| 283 | // callback |
---|
| 284 | }, |
---|
| 285 | |
---|
| 286 | onEndEditing: function(event){ |
---|
| 287 | // summary: |
---|
| 288 | // Called when an interaction ends (keyboard, mouse or gesture). |
---|
| 289 | // event: |
---|
| 290 | // On object with a unique member "indicator". This member is a reference to the modified indicator. |
---|
| 291 | // tags: |
---|
| 292 | // callback |
---|
| 293 | } |
---|
| 294 | }) |
---|
| 295 | }); |
---|