1 // ==========================================================================
  2 // Project:   SproutCore - JavaScript Application Framework
  3 // Copyright: ©2006-2011 Strobe Inc. and contributors.
  4 //            Portions ©2008-2011 Apple Inc. All rights reserved.
  5 // License:   Licensed under MIT license (see license.js)
  6 // ==========================================================================
  7 
  8 /** @class
  9 
 10   Provides common methods for sending events down a responder chain.
 11   Responder chains are used most often to deliver events to user interface
 12   elements in your application, but you can also use them to deliver generic
 13   events to any part of your application, including controllers.
 14 
 15   @extends SC.Object
 16   @since SproutCore 1.0
 17 */
 18 SC.Responder = SC.Object.extend( /** @scope SC.Responder.prototype */ {
 19 
 20   isResponder: YES,
 21 
 22   /** @property
 23     The pane this responder belongs to.  This is used to determine where you
 24     belong to in the responder chain.  Normally you should leave this property
 25     set to null.
 26   */
 27   pane: null,
 28 
 29   /** @property
 30     The app this responder belongs to.  For non-user-interface responder
 31     chains, this is used to determine the context.  Usually this
 32     is the property you will want to work with.
 33   */
 34   responderContext: null,
 35 
 36   /** @property
 37     This is the nextResponder in the responder chain.  If the receiver does
 38     not implement a particular event handler, it will bubble to the next
 39     responder.
 40 
 41     This can point to an object directly or it can be a string, in which case
 42     the path will be resolved from the responderContext root.
 43   */
 44   nextResponder: null,
 45 
 46   /** @property
 47     YES if the view is currently first responder.  This property is always
 48     edited by the pane during its makeFirstResponder() method.
 49   */
 50   isFirstResponder: NO,
 51 
 52   /** @property
 53 
 54     YES the responder is somewhere in the responder chain.  This currently
 55     only works when used with a ResponderContext.
 56 
 57     @type {Boolean}
 58   */
 59   hasFirstResponder: NO,
 60 
 61   /** @property
 62     Set to YES if your view is willing to accept first responder status.  This is used when calculating key responder loop.
 63   */
 64   acceptsFirstResponder: YES,
 65 
 66   becomingFirstResponder: NO,
 67 
 68   /**
 69     Call this method on your view or responder to make it become first
 70     responder.
 71 
 72     @returns {SC.Responder} receiver
 73   */
 74   becomeFirstResponder: function () {
 75     var pane = this.get('pane') || this.get('responderContext') ||
 76               this.pane();
 77     if (pane && this.get('acceptsFirstResponder')) {
 78       if (pane.get('firstResponder') !== this) pane.makeFirstResponder(this);
 79     }
 80     return this;
 81   },
 82 
 83   /**
 84     Call this method on your view or responder to resign your first responder
 85     status. Normally this is not necessary since you will lose first responder
 86     status automatically when another view becomes first responder.
 87 
 88     @param {Event} the original event that caused this method to be called
 89     @returns {SC.Responder} receiver
 90   */
 91   resignFirstResponder: function (evt) {
 92     var pane = this.get('pane') || this.get('responderContext');
 93     if (pane && (pane.get('firstResponder') === this)) {
 94       pane.makeFirstResponder(null, evt);
 95     }
 96     return YES;
 97   },
 98 
 99   /**
100     Called just before the responder or any of its subresponder's are about to
101     lose their first responder status.  The passed responder is the responder
102     that is about to lose its status.
103 
104     Override this method to provide any standard teardown when the first
105     responder changes.
106 
107     @param {SC.Responder} responder the responder that is about to change
108     @returns {void}
109   */
110   willLoseFirstResponder: function (responder) {},
111 
112   /**
113     Called just after the responder or any of its subresponder's becomes a
114     first responder.
115 
116     Override this method to provide any standard setup when the first
117     responder changes.
118 
119     @param {SC.Responder} responder the responder that changed
120     @returns {void}
121   */
122   didBecomeFirstResponder: function (responder) {},
123 
124   /** SC.Object.prototype.destroy */
125   destroy: function () {
126     this.resignFirstResponder();
127 
128     sc_super();
129   }
130 
131 });
132