diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/component/Tabbox.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/component/Tabbox.java index a597848a73..8bc88bfb32 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/component/Tabbox.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/component/Tabbox.java @@ -17,6 +17,7 @@ package org.adempiere.webui.component; +import org.zkoss.zul.Tab; import org.zkoss.zul.Tabpanels; /** @@ -27,11 +28,13 @@ import org.zkoss.zul.Tabpanels; */ public class Tabbox extends org.zkoss.zul.Tabbox { - /** + + /** * */ - private static final long serialVersionUID = 8453423102898624801L; - + private static final long serialVersionUID = 1400484283064851775L; + private boolean isSupportTabDragDrop; + public Tabpanel getTabpanel(int index) { try @@ -49,5 +52,18 @@ public class Tabbox extends org.zkoss.zul.Tabbox public Tabpanel getSelectedTabpanel() { return getTabpanel(this.getSelectedIndex()); - } + } + + public boolean isSupportTabDragDrop() { + return isSupportTabDragDrop; + } + + /** + * let support drag&drop {@link Tab} + * @param isSupportTabDragDrop + */ + public void setSupportTabDragDrop(boolean isSupportTabDragDrop) { + this.isSupportTabDragDrop = isSupportTabDragDrop; + } + } diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/component/Tabs.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/component/Tabs.java index e2b428d8f0..31597846d7 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/component/Tabs.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/component/Tabs.java @@ -17,21 +17,163 @@ package org.adempiere.webui.component; +import java.util.Iterator; + +import org.zkoss.zk.ui.Component; +import org.zkoss.zk.ui.event.DropEvent; +import org.zkoss.zk.ui.event.Event; +import org.zkoss.zk.ui.event.EventListener; +import org.zkoss.zk.ui.event.Events; +import org.zkoss.zul.Tab; +import org.zkoss.zul.Tabpanels; + /** * * @author Ashley G Ramdass * @date Mar 2, 2007 * @version $Revision: 0.10 $ */ -public class Tabs extends org.zkoss.zul.Tabs +public class Tabs extends org.zkoss.zul.Tabs implements EventListener { - /** + + /** * */ - private static final long serialVersionUID = -2416323107841662771L; + private static final long serialVersionUID = 4939779587719677815L; public Tabs() { super(); } + + /** + * override to set drag/drop for {@link Tab} already add to {@link Tabs} before {@link Tabs} add to {@link Tabbox} + */ + @Override + public void setParent(Component parent) { + super.setParent(parent); + if (parent == null || !(parent instanceof Tabbox)) { + return; + } + + Tabbox tabBox = (Tabbox)parent; + + // set drag/drop for tab already added to tabs + for (Iterator it = getChildren().iterator(); it.hasNext();) { + final Tab tabAdded = (Tab) it.next(); + if (tabBox.isSupportTabDragDrop()) { + setDragDropTab(tabAdded); + }else { + unsetDragDropTab(tabAdded); + } + } + + // handle drop tab to tabs (end of tabs) + if (tabBox.isSupportTabDragDrop()) { + this.addEventListener(Events.ON_DROP, this); + this.setDroppable(Boolean.TRUE.toString()); + }else { + this.removeEventListener(Events.ON_DROP, this); + this.setDroppable(Boolean.FALSE.toString()); + } + + } + + /** + * override to set drag|drop for tab depends on {@link Tabbox#isSupportTabDragDrop()} + */ + @Override + public void onChildAdded(Component child) { + super.onChildAdded(child); + if (getTabbox() != null && getTabbox() instanceof Tabbox) { + Tabbox tabbox = (Tabbox)getTabbox(); + if (child instanceof org.zkoss.zul.Tab && tabbox.isSupportTabDragDrop()) { + org.zkoss.zul.Tab tab = (org.zkoss.zul.Tab)child; + setDragDropTab(tab); + } + } + } + + /** + * setup {@link Tab} to support drag|drop + * @param tab + */ + protected void setDragDropTab (org.zkoss.zul.Tab tab){ + tab.setDraggable("true"); + tab.setDroppable("true"); + //set org.zkoss.zk.ui.EventListener.duplicateIgnored=true, so don't worry about duplicate handle + tab.addEventListener(Events.ON_DROP, this); + } + + /** + * setup {@link Tab} to un-support drag|drop + * @param tab + */ + protected void unsetDragDropTab (org.zkoss.zul.Tab tab){ + tab.setDraggable("false"); + tab.setDroppable("false"); + tab.removeEventListener(Events.ON_DROP, this); + } + + /** + * handle when user drop tab + */ + @Override + public void onEvent(Event event) throws Exception { + if (event != null && event instanceof DropEvent) { + dragDropTab((DropEvent)event); + } + } + + /** + * implement handle drop a {@link Tab} to other {@link Tab} or {@link Tabs} + * @param dropEvent + */ + protected void dragDropTab(DropEvent dropEvent) { + Component dropComp = dropEvent.getTarget(); + Component draggComp = dropEvent.getDragged(); + + if (!isValidateDragDropComponent (dropComp, draggComp)) + return; + + Tabpanels tabpanels = this.getTabbox().getTabpanels(); + int dropIndex = -1; + Component dropPanel = null; + + if (dropComp instanceof Tab) { + dropIndex = this.getChildren().indexOf(dropComp); + dropPanel = tabpanels.getChildren().get(dropIndex); + }// other case is drop to tabs + + int draggIndex = this.getChildren().indexOf(draggComp); + Component draggPanel = tabpanels.getChildren().get(draggIndex); + + if (dropIndex == -1 || draggIndex > dropIndex) {//drop to end or to before drop tab + insertBefore(draggComp, dropComp); + tabpanels.insertBefore(draggPanel, dropPanel); + }else { + insertBefore(dropComp, draggComp); + tabpanels.insertBefore(dropPanel, draggPanel); + } + + } + + /** + * just allow drag|drop {@link Tab} on same {@link org.zkoss.zul.Tabs} + * @param dropComp + * @param draggComp + * @return + */ + protected boolean isValidateDragDropComponent(Component dropComp, Component draggComp) { + if (dropComp == null || draggComp == null || !(dropComp instanceof org.zkoss.zul.Tab || dropComp instanceof org.zkoss.zul.Tabs) || !(draggComp instanceof Tab))// make sure drag and drop component is tab + return false; + + if (dropComp instanceof org.zkoss.zul.Tabs && dropComp != this)// make sure drop on same tabs + return false; + + if ((dropComp instanceof Tab && this != dropComp.getParent()) || this != draggComp.getParent())// make sure drag and drop on same tabbox + return false; + + return true; + } } diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/part/WindowContainer.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/part/WindowContainer.java index 92625bcf22..a6090de566 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/part/WindowContainer.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/part/WindowContainer.java @@ -73,6 +73,7 @@ public class WindowContainer extends AbstractUIPart protected Component doCreatePart(Component parent) { tabbox = new Tabbox(); + tabbox.setSupportTabDragDrop(true); tabbox.setSclass("desktop-tabbox"); tabbox.setId("desktop_tabbox"); tabbox.setMaximalHeight(true); diff --git a/org.adempiere.ui.zk/WEB-INF/zk.xml b/org.adempiere.ui.zk/WEB-INF/zk.xml index 67b65afc6a..6501e80620 100644 --- a/org.adempiere.ui.zk/WEB-INF/zk.xml +++ b/org.adempiere.ui.zk/WEB-INF/zk.xml @@ -105,7 +105,11 @@ org.zkoss.zul.grid.rod true - + + org.zkoss.zk.ui.EventListener.duplicateIgnored + true + + org.zkoss.zk.ui.WebApp.name iDempiere