PageRenderTime 52ms CodeModel.GetById 23ms RepoModel.GetById 0ms app.codeStats 0ms

/jdk-1.5-parent/jwicket-parent/jwicket-ui/jwicket-ui-dragdrop/src/main/java/org/wicketstuff/jwicket/ui/dragdrop/DroppableBehavior.java

https://github.com/dilgerma/core
Java | 405 lines | 227 code | 67 blank | 111 comment | 46 complexity | 82099a198928aabbe80397cca8b193e2 MD5 | raw file
  1. package org.wicketstuff.jwicket.ui.dragdrop;
  2. import org.apache.wicket.Component;
  3. import org.apache.wicket.Request;
  4. import org.apache.wicket.ajax.AjaxRequestTarget;
  5. import org.apache.wicket.markup.html.IHeaderResponse;
  6. import org.wicketstuff.jwicket.ComponentFinder;
  7. import org.wicketstuff.jwicket.JQuery;
  8. import org.wicketstuff.jwicket.JQueryJavascriptResourceReference;
  9. import org.wicketstuff.jwicket.JsMap;
  10. import org.wicketstuff.jwicket.SpecialKeys;
  11. import org.wicketstuff.jwicket.ui.AbstractJqueryUiEmbeddedBehavior;
  12. /**
  13. * You can add an instance of this class to a Wicket {@link Component} to make it
  14. * a droppable {@link Component} i.e. the target of a drag operation.
  15. * An instance of this class can be added to one and only one
  16. * {@link Component}. Another {@link Component} that should have exactly the
  17. * same behavior needs it's own instance.
  18. */
  19. public class DroppableBehavior extends AbstractDragDropBehavior {
  20. private static final long serialVersionUID = 1L;
  21. private static final String DROPPED_COMPONENTID_IDENTIFIER = "wsjqDroppedComponent";
  22. public static final JQueryJavascriptResourceReference uiDroppableJs
  23. = JQuery.isDebug()
  24. ? new JQueryJavascriptResourceReference(DraggableBehavior.class, "jquery.ui.droppable.js")
  25. : new JQueryJavascriptResourceReference(DraggableBehavior.class, "jquery.ui.droppable.min.js");
  26. private JsMap options = new JsMap();
  27. private DraggablesAcceptedByDroppable draggablesAcceptedByDroppable = null;
  28. public DroppableBehavior() {
  29. super( AbstractJqueryUiEmbeddedBehavior.jQueryUiWidgetJs,
  30. AbstractJqueryUiEmbeddedBehavior.jQueryUiMouseJs,
  31. DraggableBehavior.jQueryUiDraggableJs,
  32. uiDroppableJs,
  33. SpecialKeys.specialKeysJs);
  34. }
  35. private boolean onActivatedNotificationWanted = false;
  36. /**
  37. * If set to {@code true}, the callback-Method {@link #onActivate(AjaxRequestTarget, Component, SpecialKeys)}
  38. * is called when the drag operation ends.
  39. * @param value {@code true} or {@code false}.
  40. * @return this object
  41. */
  42. public DroppableBehavior setWantOnActivatedNotification(final boolean value) {
  43. onActivatedNotificationWanted = value;
  44. return this;
  45. }
  46. private boolean onDeactivateNotificationWanted = false;
  47. /**
  48. * If set to {@code true}, the callback-Method {@link #onDeactivate(AjaxRequestTarget, Component, SpecialKeys)}
  49. * is called when the drag operation ends.
  50. * @param value {@code true} or {@code false}.
  51. * @return this object
  52. */
  53. public DroppableBehavior setWantOnDeactivateNotification(final boolean value) {
  54. onDeactivateNotificationWanted = value;
  55. return this;
  56. }
  57. /** You can restrict the {@link Component}s that can be dragged and dropped to
  58. * a {@link Component} marked with this behavior. See {@link DraggablesAcceptedByDroppable}
  59. * for more information. If the {@link DraggablesAcceptedByDroppable} is empty (i.e. it
  60. * contains no names) then the droppable does not accept any draggables.
  61. *
  62. * @param accepted the accepted
  63. * @return this object
  64. */
  65. public DroppableBehavior setDraggablesAcceptedByDroppable(final DraggablesAcceptedByDroppable accepted) {
  66. draggablesAcceptedByDroppable = accepted;
  67. if (accepted != null)
  68. options.put("accept", new JsFunction(accepted.getJsAcceptCheckerFunctionName()));
  69. else
  70. options.remove("accept");
  71. return this;
  72. }
  73. /**
  74. * Sets the 'activeClass' property for this draggable. Please consult the
  75. * jQuery documentation for a detailled description of this property.
  76. * @param activeClass the CSS class' name
  77. * @return this object
  78. */
  79. public DroppableBehavior setActiveClass(final String activeClass) {
  80. if (activeClass == null)
  81. options.remove("activeClass");
  82. else
  83. options.put("activeClass", activeClass);
  84. return this;
  85. }
  86. public DroppableBehavior setActiveClass(final AjaxRequestTarget target, final String activeClass) {
  87. setActiveClass(activeClass);
  88. if (activeClass != null)
  89. target.appendJavascript("jQuery('#" + getComponent().getMarkupId() + "').droppable('option','activeClass','" + activeClass + "');");
  90. else
  91. target.appendJavascript("jQuery('#" + getComponent().getMarkupId() + "').droppable('option','activeClass',false);");
  92. return this;
  93. }
  94. /**
  95. * Sets the 'addClasses' property for this draggable. Please consult the
  96. * jQuery documentation for a detailled description of this property.
  97. * @param value {@code true} or {@code false}.
  98. * @return this object
  99. */
  100. public DroppableBehavior setAddClasses(final boolean value) {
  101. if (value)
  102. options.remove("addClasses");
  103. else
  104. options.put("addClasses", value);
  105. return this;
  106. }
  107. public DroppableBehavior setAddClasses(final AjaxRequestTarget target, final boolean value) {
  108. setAddClasses(value);
  109. target.appendJavascript("jQuery('#" + getComponent().getMarkupId() + "').droppable('option','addClasses'," + value + ");");
  110. return this;
  111. }
  112. /**
  113. * Sets the 'greedy' property for this draggable. Please consult the
  114. * jQuery documentation for a detailled description of this property.
  115. * @param value {@code true} or {@code false}.
  116. * @return this object
  117. */
  118. public DroppableBehavior setGreedy(final boolean value) {
  119. if (value)
  120. options.remove("greedy");
  121. else
  122. options.put("greedy", value);
  123. return this;
  124. }
  125. public DroppableBehavior setGreedy(final AjaxRequestTarget target, final boolean value) {
  126. setGreedy(value);
  127. target.appendJavascript("jQuery('#" + getComponent().getMarkupId() + "').droppable('option','greedy'," + value + ");");
  128. return this;
  129. }
  130. /**
  131. * Sets the 'hoverClass' property for this draggable. Please consult the
  132. * jQuery documentation for a detailled description of this property.
  133. * @param hoverClass the CSS class' name
  134. * @return this object
  135. */
  136. public DroppableBehavior setHoverClass(final String hoverClass) {
  137. if (hoverClass == null)
  138. options.remove("hoverClass");
  139. else
  140. options.put("hoverClass", hoverClass);
  141. return this;
  142. }
  143. public DroppableBehavior setHoverClass(final AjaxRequestTarget target, final String hoverClass) {
  144. setHoverClass(hoverClass);
  145. if (hoverClass != null)
  146. target.appendJavascript("jQuery('#" + getComponent().getMarkupId() + "').droppable('option','hoverClass','" + hoverClass + "');");
  147. else
  148. target.appendJavascript("jQuery('#" + getComponent().getMarkupId() + "').droppable('option','hoverClass',false);");
  149. return this;
  150. }
  151. /**
  152. * Sets the 'scope' property for this draggable. Please consult the
  153. * jQuery documentation for a detailled description of this property.
  154. * @param scope the scode
  155. * @return this object
  156. */
  157. public DroppableBehavior setScope(final String scope) {
  158. if (scope == null)
  159. options.remove("scope");
  160. else
  161. options.put("scope", scope);
  162. return this;
  163. }
  164. public DroppableBehavior setScope(final AjaxRequestTarget target, final String scope) {
  165. setScope(scope);
  166. if (scope != null)
  167. target.appendJavascript("jQuery('#" + getComponent().getMarkupId() + "').droppable('option','scope','" + scope + "');");
  168. else
  169. target.appendJavascript("jQuery('#" + getComponent().getMarkupId() + "').droppable('option','scope','default');");
  170. return this;
  171. }
  172. public static enum DropTolerance {
  173. FTI("fit"),
  174. INTERSECT("intersect"),
  175. POINTER("pointer"),
  176. TOUCH("touch")
  177. ;
  178. private final String value;
  179. private DropTolerance(final String value) {
  180. this.value = value;
  181. }
  182. public String getValue() {
  183. return this.value;
  184. }
  185. public String toString() {
  186. return this.value;
  187. }
  188. }
  189. /**
  190. * Sets the 'tolerance' property for this droppable. Please consult the
  191. * jquery documentation for a detailled description of this property.
  192. * @param tolerance the tolerance
  193. * @return this object
  194. */
  195. public DroppableBehavior setTolerance(final DropTolerance tolerance) {
  196. if (tolerance == null)
  197. options.remove("tolerance");
  198. else
  199. options.put("tolerance", tolerance.getValue());
  200. return this;
  201. }
  202. public DroppableBehavior setScope(final AjaxRequestTarget target, final DropTolerance tolerance) {
  203. setTolerance(tolerance);
  204. if (tolerance != null)
  205. target.appendJavascript("jQuery('#" + getComponent().getMarkupId() + "').droppable('option','tolerance','" + tolerance.getValue() + "');");
  206. else
  207. target.appendJavascript("jQuery('#" + getComponent().getMarkupId() + "').droppable('option','tolerance','" + DropTolerance.INTERSECT + "');");
  208. return this;
  209. }
  210. /**
  211. * handles the event processing during dragging.
  212. */
  213. @Override
  214. protected void respond(final AjaxRequestTarget target) {
  215. Component component = getComponent();
  216. Request request;
  217. if (component != null && (request = component.getRequest()) != null) {
  218. EventType dragEventType = EventType.stringToType(request.getParameter(EventType.IDENTIFIER));
  219. ComponentFinder visitor = new ComponentFinder(request.getParameter(DROPPED_COMPONENTID_IDENTIFIER));
  220. component.getPage().visitChildren(visitor);
  221. if (component instanceof IDroppable) {
  222. IDroppable draggableComponent = (IDroppable)component;
  223. if (dragEventType == EventType.DROP)
  224. draggableComponent.onDrop(target, visitor.getFoundComponent(), new SpecialKeys(request));
  225. else if (dragEventType == EventType.DROP_ACTIVATE)
  226. draggableComponent.onActivate(target, visitor.getFoundComponent(), new SpecialKeys(request));
  227. else if (dragEventType == EventType.DROP_DEACTIVATE)
  228. draggableComponent.onDeactivate(target, visitor.getFoundComponent(), new SpecialKeys(request));
  229. }
  230. if (dragEventType == EventType.DROP)
  231. onDrop(target, visitor.getFoundComponent(), new SpecialKeys(request));
  232. else if (dragEventType == EventType.DROP_ACTIVATE)
  233. onActivate(target, visitor.getFoundComponent(), new SpecialKeys(request));
  234. else if (dragEventType == EventType.DROP_DEACTIVATE)
  235. onDeactivate(target, visitor.getFoundComponent(), new SpecialKeys(request));
  236. }
  237. }
  238. /**
  239. * This method is called when a draggable {@link Component} is dropped onto
  240. * a {@link Component} marked with this behavior.
  241. *
  242. * @param target the AjaxRequestTarget of the drop operation.
  243. * @param draggedComponent The dragged component
  244. * @param specialKeys the special keys that were pressed when the event occurs
  245. */
  246. protected void onDrop(AjaxRequestTarget target, final Component draggedComponent, final SpecialKeys specialKeys) {}
  247. /**
  248. * This method is called when a draggable {@link Component} is starting to
  249. * drag and the dragging {@link Component}'s name is accepted to be
  250. * dropped onto this.
  251. *
  252. * @param target The {@link AjaxRequestTarget} associated with this
  253. * drop operation.
  254. * @param draggedComponent The dragged component
  255. * @param specialKeys the special keys that were pressed when the event occurs
  256. */
  257. protected void onActivate(final AjaxRequestTarget target, final Component draggedComponent, final SpecialKeys specialKeys) {}
  258. /**
  259. * This method is called when a draggable {@link Component} has stopped
  260. * dragging and the dragging {@link Component}'s name was accepted to be
  261. * dropped onto this.
  262. *
  263. * @param target The {@link AjaxRequestTarget} associated with this
  264. * drop operation.
  265. * @param draggedComponent The dragged component
  266. * @param specialKeys the special keys that were pressed when the event occurs
  267. */
  268. protected void onDeactivate(final AjaxRequestTarget target, final Component draggedComponent, final SpecialKeys specialKeys) {}
  269. /**
  270. * Disable the dropping
  271. *
  272. * @param target An AjaxRequestTarget
  273. */
  274. public void disable(final AjaxRequestTarget target) {
  275. target.appendJavascript("jQuery('#" + getComponent().getMarkupId() + "').droppable('disable');");
  276. }
  277. /**
  278. * Enable the dropping
  279. *
  280. * @param target An AjaxRequestTarget
  281. */
  282. public void enable(final AjaxRequestTarget target) {
  283. target.appendJavascript("jQuery('#" + getComponent().getMarkupId() + "').droppable('enable');");
  284. }
  285. // We need to render the drop accept checker function only once
  286. private boolean dropAcceptedCheckerRendered = false;
  287. /**
  288. * @see org.apache.wicket.behavior.AbstractAjaxBehavior#renderHead(org.apache.wicket.markup.html.IHeaderResponse)
  289. */
  290. @Override
  291. public void renderHead(final IHeaderResponse response) {
  292. super.renderHead(response);
  293. if (draggablesAcceptedByDroppable != null && ! dropAcceptedCheckerRendered) {
  294. draggablesAcceptedByDroppable.renderJsDropAcceptFunction(response);
  295. dropAcceptedCheckerRendered = true;
  296. }
  297. }
  298. @Override
  299. /**
  300. * For internal use only.
  301. */
  302. protected JsBuilder getJsBuilder() {
  303. if (onDeactivateNotificationWanted)
  304. options.put("deactivate",
  305. new JsFunction("function(ev,ui) { \n"+
  306. "wicketAjaxGet('" +
  307. this.getCallbackUrl() +
  308. "&" + EventType.IDENTIFIER + "=" + EventType.DROP_DEACTIVATE +
  309. "&" + DROPPED_COMPONENTID_IDENTIFIER + "='+jQuery(ui.draggable).attr('id')" +
  310. "+'&keys='+jQuery.jWicketSpecialKeysGetPressed()" +
  311. "); }"));
  312. options.put("drop",
  313. new JsFunction("function(ev,ui) { \n"+
  314. "wicketAjaxGet('" +
  315. this.getCallbackUrl() +
  316. "&" + EventType.IDENTIFIER + "=" + EventType.DROP +
  317. "&" + DROPPED_COMPONENTID_IDENTIFIER + "='+jQuery(ui.draggable).attr('id')" +
  318. "+'&keys='+jQuery.jWicketSpecialKeysGetPressed()" +
  319. "); " +
  320. "}"));
  321. if (onActivatedNotificationWanted)
  322. options.put("activate",
  323. new JsFunction("function(ev,ui) { \n"+
  324. "wicketAjaxGet('" +
  325. this.getCallbackUrl() +
  326. "&" + EventType.IDENTIFIER + "=" + EventType.DROP_ACTIVATE +
  327. "&" + DROPPED_COMPONENTID_IDENTIFIER + "='+jQuery(ui.draggable).attr('id')" +
  328. "+'&keys='+jQuery.jWicketSpecialKeysGetPressed()" +
  329. "); }"));
  330. JsBuilder builder = new JsBuilder();
  331. builder.append("jQuery('#" + getComponent().getMarkupId() + "').droppable(");
  332. builder.append("{");
  333. builder.append(options.toString(rawOptions));
  334. builder.append("}");
  335. builder.append(");");
  336. return builder;
  337. }
  338. }