ToolbarDroppable.js 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  1. /**
  2. * @class Ext.ux.ToolbarDroppable
  3. * @extends Object
  4. * Plugin which allows items to be dropped onto a toolbar and be turned into new Toolbar items.
  5. * To use the plugin, you just need to provide a createItem implementation that takes the drop
  6. * data as an argument and returns an object that can be placed onto the toolbar. Example:
  7. * <pre>
  8. * Ext.create('Ext.ux.ToolbarDroppable', {
  9. * createItem: function(data) {
  10. * return Ext.create('Ext.Button', {text: data.text});
  11. * }
  12. * });
  13. * </pre>
  14. * The afterLayout function can also be overridden, and is called after a new item has been
  15. * created and inserted into the Toolbar. Use this for any logic that needs to be run after
  16. * the item has been created.
  17. */
  18. Ext.define('Ext.ux.ToolbarDroppable', {
  19. extend: 'Object',
  20. /**
  21. * @constructor
  22. */
  23. constructor: function(config) {
  24. Ext.apply(this, config);
  25. },
  26. /**
  27. * Initializes the plugin and saves a reference to the toolbar
  28. * @param {Ext.toolbar.Toolbar} toolbar The toolbar instance
  29. */
  30. init: function(toolbar) {
  31. /**
  32. * @property toolbar
  33. * @type Ext.toolbar.Toolbar
  34. * The toolbar instance that this plugin is tied to
  35. */
  36. this.toolbar = toolbar;
  37. this.toolbar.on({
  38. scope : this,
  39. render: this.createDropTarget
  40. });
  41. },
  42. /**
  43. * Creates a drop target on the toolbar
  44. */
  45. createDropTarget: function() {
  46. /**
  47. * @property dropTarget
  48. * @type Ext.dd.DropTarget
  49. * The drop target attached to the toolbar instance
  50. */
  51. this.dropTarget = Ext.create('Ext.dd.DropTarget', this.toolbar.getEl(), {
  52. notifyOver: Ext.Function.bind(this.notifyOver, this),
  53. notifyDrop: Ext.Function.bind(this.notifyDrop, this)
  54. });
  55. },
  56. /**
  57. * Adds the given DD Group to the drop target
  58. * @param {String} ddGroup The DD Group
  59. */
  60. addDDGroup: function(ddGroup) {
  61. this.dropTarget.addToGroup(ddGroup);
  62. },
  63. /**
  64. * Calculates the location on the toolbar to create the new sorter button based on the XY of the
  65. * drag event
  66. * @param {Ext.EventObject} e The event object
  67. * @return {Number} The index at which to insert the new button
  68. */
  69. calculateEntryIndex: function(e) {
  70. var entryIndex = 0,
  71. toolbar = this.toolbar,
  72. items = toolbar.items.items,
  73. count = items.length,
  74. xHover = e.getXY()[0],
  75. index = 0,
  76. el, xTotal, width, midpoint;
  77. for (; index < count; index++) {
  78. el = items[index].getEl();
  79. xTotal = el.getXY()[0];
  80. width = el.getWidth();
  81. midpoint = xTotal + width / 2;
  82. if (xHover < midpoint) {
  83. entryIndex = index;
  84. break;
  85. } else {
  86. entryIndex = index + 1;
  87. }
  88. }
  89. return entryIndex;
  90. },
  91. /**
  92. * Returns true if the drop is allowed on the drop target. This function can be overridden
  93. * and defaults to simply return true
  94. * @param {Object} data Arbitrary data from the drag source
  95. * @return {Boolean} True if the drop is allowed
  96. */
  97. canDrop: function(data) {
  98. return true;
  99. },
  100. /**
  101. * Custom notifyOver method which will be used in the plugin's internal DropTarget
  102. * @return {String} The CSS class to add
  103. */
  104. notifyOver: function(dragSource, event, data) {
  105. return this.canDrop.apply(this, arguments) ? this.dropTarget.dropAllowed : this.dropTarget.dropNotAllowed;
  106. },
  107. /**
  108. * Called when the drop has been made. Creates the new toolbar item, places it at the correct location
  109. * and calls the afterLayout callback.
  110. */
  111. notifyDrop: function(dragSource, event, data) {
  112. var canAdd = this.canDrop(dragSource, event, data),
  113. tbar = this.toolbar;
  114. if (canAdd) {
  115. var entryIndex = this.calculateEntryIndex(event);
  116. tbar.insert(entryIndex, this.createItem(data));
  117. tbar.doLayout();
  118. this.afterLayout();
  119. }
  120. return canAdd;
  121. },
  122. /**
  123. * Creates the new toolbar item based on drop data. This method must be implemented by the plugin instance
  124. * @param {Object} data Arbitrary data from the drop
  125. * @return {Mixed} An item that can be added to a toolbar
  126. */
  127. createItem: function(data) {
  128. //<debug>
  129. Ext.Error.raise("The createItem method must be implemented in the ToolbarDroppable plugin");
  130. //</debug>
  131. },
  132. /**
  133. * Called after a new button has been created and added to the toolbar. Add any required cleanup logic here
  134. */
  135. afterLayout: Ext.emptyFn
  136. });