1 goog.provide('lime.Button');
  2 
  3 goog.require('lime.Layer');
  4 
  5 /**
  6  * Simple button element
  7  * @param {lime.Sprite} opt_upstate Object shown on normal state.
  8  * @param {lime.Sprite} opt_downstate Object show when button is pressed.
  9  * @constructor
 10  * @extends lime.Layer
 11  */
 12 lime.Button = function(opt_upstate, opt_downstate) {
 13     lime.Layer.call(this);
 14 
 15     this.domClassName = goog.getCssName('lime-button');
 16 
 17     //set up state
 18     if (goog.isDef(opt_upstate)) {
 19         this.setUpState(opt_upstate);
 20     }
 21 
 22     //set down state
 23     if (goog.isDef(opt_downstate)) {
 24         this.setDownState(opt_downstate);
 25     }
 26 
 27 
 28     var t = this;
 29     goog.events.listen(this, ['mousedown', 'touchstart', 'touchmove'],
 30         function(e) {
 31             t.setState(lime.Button.State.DOWN);
 32             e.swallow('mousemove', function(e) {
 33                 if (t.hitTest(e)) {
 34                     t.setState(lime.Button.State.DOWN);
 35                 }
 36                 else {
 37                     t.setState(lime.Button.State.UP);
 38                 }
 39             });
 40             e.swallow('touchmove', function(e) {
 41                 if (!t.hitTest(e)) {
 42                     t.setState(lime.Button.State.UP);
 43                     e.release();
 44                 }
 45             });
 46             e.swallow(['mouseup', 'touchend'], function(e) {
 47                 if (t.hitTest(e)) {
 48                     t.dispatchEvent({type: lime.Button.Event.CLICK});
 49                }
 50                this.setState(lime.Button.State.UP);
 51            });
 52         }
 53     );
 54 
 55 
 56 };
 57 goog.inherits(lime.Button, lime.Layer);
 58 
 59 /**
 60  * Button states
 61  * @enum {number}
 62  */
 63 lime.Button.State = {
 64     UP: 0,
 65     DOWN: 1
 66 };
 67 
 68 /**
 69  * Button event names
 70  * @enum {string}
 71  */
 72 lime.Button.Event = {
 73     UP: 'up',
 74     DOWN: 'down',
 75     CLICK: 'click' // touchUpInside?
 76 };
 77 
 78 /**
 79  * Sets the sprite used as button up state
 80  * @param {lime.Sprite} upstate Object shown on normal state.
 81  * @return {lime.Button} object itself.
 82  */
 83 lime.Button.prototype.setUpState = function(upstate) {
 84     this.upstate = upstate;
 85     this.appendChild(this.upstate);
 86 
 87     this.state_ = -1;
 88     return this.setState(lime.Button.State.UP);
 89 };
 90 
 91 /**
 92  * Sets the sprite used as button down state. Down state is hown if
 93  * mouse is down on button or finger is touching the button.
 94  * @param {lime.Sprite} downstate Object shown when button is pressed.
 95  * @return {lime.Button} object itself.
 96  */
 97 lime.Button.prototype.setDownState = function(downstate) {
 98     this.downstate = downstate;
 99     this.appendChild(downstate);
100 
101     this.state_ = -1;
102     return this.setState(lime.Button.State.UP);
103 };
104 
105 
106 /**
107  * Returns current state of the button
108  * @return {lime.Button.State} current state.
109  */
110 lime.Button.prototype.getState = function() {
111     return this.state_;
112 };
113 
114 
115 /**
116  * Sets the state of the button. Also fires events is state changes.
117  * @param {lime.Button.State} value State to be set.
118  * @return {lime.Button} object itself.
119  */
120 lime.Button.prototype.setState = function(value) {
121 
122     if (value == this.state_) return this;
123 
124     //event checking
125     if (this.state_ == lime.Button.State.UP &&
126             value == lime.Button.State.DOWN)
127         this.dispatchEvent({type: lime.Button.Event.DOWN});
128 
129     if (this.state_ == lime.Button.State.DOWN &&
130             value == lime.Button.State.UP)
131         this.dispatchEvent({type: lime.Button.Event.UP});
132 
133 
134     var state = this.upstate;
135 
136     if (goog.isDef(this.downstate)) {
137         if (lime.Button.State.DOWN == value)
138             state = this.downstate;
139         else
140             this.downstate.setHidden(true);
141     }
142 
143     if (state != this.upstate) {
144         this.upstate.setHidden(true);
145     }
146 
147     state.setHidden(false);
148     this.state_ = value;
149     return this;
150 };
151