ToolbarDroppable.js 4.6 KB

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