70e9bcbc701a0661781570709dc5bb159ee4ca7d.svn-base 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191
  1. /*
  2. * Ext JS Library 2.0 Copyright(c) 2006-2007, Ext JS, LLC. licensing@extjs.com
  3. *
  4. * http://extjs.com/license
  5. */
  6. /**
  7. * @class Ext.CycleButton
  8. * @extends Ext.SplitButton A specialized SplitButton that contains a menu of
  9. * {@link Ext.menu.CheckItem} elements. The button automatically cycles
  10. * through each menu item on click, raising the button's
  11. * {@link #change} event (or calling the button's
  12. * {@link #changeHandler} function, if supplied) for the active menu
  13. * item. Clicking on the arrow section of the button displays the
  14. * dropdown menu just like a normal SplitButton. Example usage:
  15. *
  16. * <pre><code>
  17. * var btn = new Ext.CycleButton({
  18. * showText : true,
  19. * prependText : 'View as ',
  20. * items : [{
  21. * text : 'text only',
  22. * iconCls : 'view-text',
  23. * checked : true
  24. * }, {
  25. * text : 'HTML',
  26. * iconCls : 'view-html'
  27. * }],
  28. * changeHandler : function(btn, item) {
  29. * Ext.Msg.alert('Change View', item.text);
  30. * }
  31. * });
  32. * </code></pre>
  33. *
  34. * @constructor Create a new split button
  35. * @param {Object}
  36. * config The config object
  37. */
  38. Ext.CycleButton = Ext.extend(Ext.SplitButton, {
  39. /**
  40. * @cfg {Array} items An array of {@link Ext.menu.CheckItem}
  41. * <b>config</b> objects to be used when creating the button's
  42. * menu items (e.g., {text:'Foo', iconCls:'foo-icon'})
  43. */
  44. /**
  45. * @cfg {Boolean} showText True to display the active item's text as
  46. * the button text (defaults to false)
  47. */
  48. /**
  49. * @cfg {String} prependText A static string to prepend before the
  50. * active item's text when displayed as the button's text (only
  51. * applies when showText = true, defaults to '')
  52. */
  53. /**
  54. * @cfg {Function} changeHandler A callback function that will be
  55. * invoked each time the active menu item in the button's menu
  56. * has changed. If this callback is not supplied, the
  57. * SplitButton will instead fire the {@link #change} event on
  58. * active item change. The changeHandler function will be
  59. * called with the following argument list: (SplitButton this,
  60. * Ext.menu.CheckItem item)
  61. */
  62. // private
  63. getItemText : function(item) {
  64. if (item && this.showText === true) {
  65. var text = '';
  66. if (this.prependText) {
  67. text += this.prependText;
  68. }
  69. text += item.text;
  70. return text;
  71. }
  72. return undefined;
  73. },
  74. /**
  75. * Sets the button's active menu item.
  76. *
  77. * @param {Ext.menu.CheckItem}
  78. * item The item to activate
  79. * @param {Boolean}
  80. * suppressEvent True to prevent the button's change
  81. * event from firing (defaults to false)
  82. */
  83. setActiveItem : function(item, suppressEvent) {
  84. if (item) {
  85. if (!this.rendered) {
  86. this.text = this.getItemText(item);
  87. this.iconCls = item.iconCls;
  88. } else {
  89. var t = this.getItemText(item);
  90. if (t) {
  91. this.setText(t);
  92. }
  93. this.setIconClass(item.iconCls);
  94. }
  95. this.activeItem = item;
  96. if (!suppressEvent) {
  97. this.fireEvent('change', this, item);
  98. }
  99. }
  100. },
  101. /**
  102. * Gets the currently active menu item.
  103. *
  104. * @return {Ext.menu.CheckItem} The active item
  105. */
  106. getActiveItem : function() {
  107. return this.activeItem;
  108. },
  109. // private
  110. initComponent : function() {
  111. this.addEvents(
  112. /**
  113. * @event change Fires after the button's active menu
  114. * item has changed. Note that if a
  115. * {@link #changeHandler} function is set on this
  116. * CycleButton, it will be called instead on
  117. * active item change and this change event will
  118. * not be fired.
  119. * @param {Ext.CycleButton}
  120. * this
  121. * @param {Ext.menu.CheckItem}
  122. * item The menu item that was selected
  123. */
  124. "change");
  125. if (this.changeHandler) {
  126. this.on('change', this.changeHandler, this.scope || this);
  127. delete this.changeHandler;
  128. }
  129. this.itemCount = this.items.length;
  130. this.menu = {
  131. cls : 'x-cycle-menu',
  132. items : []
  133. };
  134. var checked;
  135. for (var i = 0, len = this.itemCount; i < len; i++) {
  136. var item = this.items[i];
  137. item.group = item.group || this.id;
  138. item.itemIndex = i;
  139. item.checkHandler = this.checkHandler;
  140. item.scope = this;
  141. item.checked = item.checked || false;
  142. this.menu.items.push(item);
  143. if (item.checked) {
  144. checked = item;
  145. }
  146. }
  147. this.setActiveItem(checked, true);
  148. Ext.CycleButton.superclass.initComponent.call(this);
  149. this.on('click', this.toggleSelected, this);
  150. },
  151. // private
  152. checkHandler : function(item, pressed) {
  153. if (pressed) {
  154. this.setActiveItem(item);
  155. }
  156. },
  157. /**
  158. * This is normally called internally on button click, but can be
  159. * called externally to advance the button's active item
  160. * programmatically to the next one in the menu. If the current item
  161. * is the last one in the menu the active item will be set to the
  162. * first item in the menu.
  163. */
  164. toggleSelected : function() {
  165. this.menu.render();
  166. var nextIdx, checkItem;
  167. for (var i = 1; i < this.itemCount; i++) {
  168. nextIdx = (this.activeItem.itemIndex + i) % this.itemCount;
  169. // check the potential item
  170. checkItem = this.menu.items.itemAt(nextIdx);
  171. // if its not disabled then check it.
  172. if (!checkItem.disabled) {
  173. checkItem.setChecked(true);
  174. break;
  175. }
  176. }
  177. }
  178. });
  179. Ext.reg('cycle', Ext.CycleButton);