1 /**
  2  * The Render Engine
  3  * RadioControl
  4  *
  5  * @fileoverview A radio box control.
  6  *
  7  * @author: Brett Fattori (brettf@renderengine.com)
  8  *
  9  * @author: $Author: bfattori $
 10  * @version: $Revision: 1555 $
 11  *
 12  * Copyright (c) 2011 Brett Fattori (brettf@renderengine.com)
 13  *
 14  * Permission is hereby granted, free of charge, to any person obtaining a copy
 15  * of this software and associated documentation files (the "Software"), to deal
 16  * in the Software without restriction, including without limitation the rights
 17  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 18  * copies of the Software, and to permit persons to whom the Software is
 19  * furnished to do so, subject to the following conditions:
 20  *
 21  * The above copyright notice and this permission notice shall be included in
 22  * all copies or substantial portions of the Software.
 23  *
 24  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 25  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 26  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 27  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 28  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 29  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 30  * THE SOFTWARE.
 31  *
 32  */
 33 
 34 // The class this file defines and its required classes
 35 R.Engine.define({
 36     "class":"R.ui.RadioControl",
 37     "requires":[
 38         "R.ui.AbstractUIControl"
 39     ]
 40 });
 41 
 42 /**
 43  * @class UI checkbox control.
 44  *
 45  * @constructor
 46  * @param group {String} The name of the group this control is a part of.
 47  * @param value {String} The value of this radio within the group
 48  * @param [checked] {Boolean} Whether the checkbox is checked, or not.
 49  * @extends R.ui.AbstractUIControl
 50  */
 51 R.ui.RadioControl = function () {
 52     return R.ui.AbstractUIControl.extend(/** @scope R.ui.RadioControl.prototype */{
 53 
 54         checked:false,
 55         value:null,
 56 
 57         /** @private */
 58         constructor:function (group, value, checked) {
 59             this.base("Radio");
 60             this.addClass("radiocontrol");
 61             this.value = value;
 62             this.setGroup(group);
 63             this.setChecked(checked || false);
 64         },
 65 
 66         /**
 67          * Releases the object back into the object pool.  See {@link R.engine.PooledObject#release}
 68          * for more information.
 69          */
 70         release:function () {
 71             this.base();
 72             this.checked = false;
 73         },
 74 
 75         /**
 76          * Respond to a "click" action on the checkbox.
 77          * @param mouseInfo {R.struct.MouseInfo} A mouse info structure
 78          */
 79         click:function (mouseInfo) {
 80             // Check this control
 81             this.setChecked(true);
 82             this.base(mouseInfo);
 83         },
 84 
 85         /**
 86          * Set the "checked" state of the control.  Triggers the "change"
 87          * event on the control.
 88          * @param state {Boolean} <code>true</code> to mark the control as "checked"
 89          */
 90         setChecked:function (state) {
 91             if (state && !this.isChecked()) {
 92                 // Get the group of controls
 93                 var group = this.getGroup();
 94 
 95                 // Un-check all of the controls
 96                 for (var r = 0; r < group.length; r++) {
 97                     if (group[r] != this) {
 98                         group[r].setChecked(false);
 99                     }
100                 }
101             }
102 
103             this.checked = state;
104             this.triggerEvent("change");
105         },
106 
107         /**
108          * Get the "checked" state of the control.
109          * @return {String}
110          */
111         isChecked:function () {
112             return this.checked;
113         },
114 
115         /**
116          * Set the value of this radio control.
117          * @param value {String} The value of the control
118          */
119         setValue:function (value) {
120             this.value = value;
121         },
122 
123         /**
124          * Get the value of this radio control.
125          * @return {String}
126          */
127         getValue:function () {
128             return this.value;
129         },
130 
131         /**
132          * Get the value of the selected control within the entire group.
133          * @return {String} The checked radio control's value, or <code>null</code> if no
134          *    control has been checked.
135          */
136         getGroupValue:function () {
137             // Get the group of controls
138             var group = this.getGroup();
139 
140             // Return the value of the checked control
141             for (var r = 0; r < group.length; r++) {
142                 if (group[r].isChecked()) {
143                     return group[r].getValue();
144                 }
145             }
146             return null;
147         },
148 
149         /**
150          * Override drawing the box and draw a circle instead.
151          */
152         drawBox:function (renderContext, width, height, fillColor) {
153             var rect = R.math.Rectangle2D.create(0, 0, width, height);
154             if (fillColor) {
155                 renderContext.setFillStyle(fillColor);
156                 renderContext.drawFilledCircle(rect.getCenter(), rect.getHalfWidth());
157             } else {
158                 renderContext.setFillStyle("transparent");
159             }
160             renderContext.drawCircle(rect.getCenter(), rect.getHalfWidth());
161             rect.destroy();
162         },
163 
164         /**
165          * Draw the input component within the
166          * @param renderContext {R.rendercontexts.RenderContext2D} The render context where the control is
167          *    drawn.
168          * @param worldTime {Number} The current world time, in milliseconds
169          * @param dt {Number} The time since the last frame was drawn by the engine, in milliseconds
170          */
171         drawControl:function (renderContext, worldTime, dt) {
172             // Draw a dot if the control is "checked"
173             if (this.checked) {
174                 renderContext.pushTransform();
175                 renderContext.setLineWidth(2);
176                 var bBox = R.clone(this.getBoundingBox());
177                 renderContext.setFillStyle(this.getTextRenderer().getTextColor());
178                 bBox.x += 4;
179                 bBox.w -= 8;
180                 bBox.y += 4;
181                 bBox.h -= 8;
182                 bBox._upd();
183                 renderContext.drawFilledCircle(bBox.getCenter(), bBox.getHalfWidth());
184                 bBox.destroy();
185                 renderContext.popTransform();
186             }
187         },
188 
189         /**
190          * Returns a bean which represents the read or read/write properties
191          * of the object.
192          *
193          * @return {Object} The properties object
194          */
195         getProperties:function () {
196             var self = this;
197             var prop = this.base(self);
198             return $.extend(prop, {
199                 "Value":[function () {
200                     return self.getValue();
201                 }, function (i) {
202                     self.setValue(i);
203                 }, true],
204                 "Checked":[function () {
205                     return self.isChecked();
206                 }, {
207                     "toggle":true,
208                     "fn":function (s) {
209                         self.setChecked(s);
210                     }
211                 }, true]
212             });
213         }
214 
215     }, /** @scope R.ui.RadioControl.prototype */{
216 
217         /**
218          * Get the class name of this object
219          * @return {String} The string "R.ui.RadioControl"
220          */
221         getClassName:function () {
222             return "R.ui.RadioControl";
223         },
224 
225         /**
226          * Get a properties object with values for the given object.
227          * @param obj {R.ui.RadioControl} The radio control to query
228          * @param [defaults] {Object} Default values that don't need to be serialized unless
229          *    they are different.
230          * @return {Object}
231          */
232         serialize:function (obj, defaults) {
233             // Defaults for object properties which can be skipped if no different
234             defaults = defaults || [];
235             $.extend(defaults, {
236                 "Checked":false
237             });
238             return R.ui.AbstractUIControl.serialize(obj, defaults);
239         },
240 
241         /**
242          * Deserialize the object back into a radio control.
243          * @param obj {Object} The object to deserialize
244          * @param [clazz] {Class} The object class to populate
245          * @return {R.ui.RadioControl} The object which was deserialized
246          */
247         deserialize:function (obj, clazz) {
248             clazz = clazz || R.ui.RadioControl.create();
249             R.ui.AbstractUIControl.deserialize(obj, clazz);
250             return clazz;
251         }
252     });
253 
254 };