From 50c9fad1afdf86217fbac7ef0481e0dc9ee3dd51 Mon Sep 17 00:00:00 2001 From: hieplq Date: Wed, 30 Jul 2014 16:32:13 +0700 Subject: [PATCH] IDEMPIERE-1657:common show window with mask --- .../src/org/adempiere/webui/ISupportMask.java | 49 ++++++++++ .../src/org/adempiere/webui/LayoutUtils.java | 97 +++++++++++++++++++ .../org/adempiere/webui/component/Mask.java | 7 ++ .../adempiere/webui/component/Tabpanel.java | 51 +++++++++- .../org/adempiere/webui/component/Window.java | 51 +++++++++- .../adempiere/webui/part/AbstractUIPart.java | 57 ++++++++++- .../theme/default/zul/desktop/desktop.zul | 2 + 7 files changed, 311 insertions(+), 3 deletions(-) create mode 100644 org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/ISupportMask.java diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/ISupportMask.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/ISupportMask.java new file mode 100644 index 0000000000..a320041fae --- /dev/null +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/ISupportMask.java @@ -0,0 +1,49 @@ +/****************************************************************************** + * Copyright (C) 2014 iDempiere * + * Product: iDempiere ERP & CRM Smart Business Solution * + * This program is free software; you can redistribute it and/or modify it * + * under the terms version 2 of the GNU General Public License as published * + * by the Free Software Foundation. This program is distributed in the hope * + * that it will be useful, but WITHOUT ANY WARRANTY; without even the implied * + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * + * See the GNU General Public License for more details. * + * You should have received a copy of the GNU General Public License along * + * with this program; if not, write to the Free Software Foundation, Inc., * + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. * + *****************************************************************************/ +package org.adempiere.webui; + +import org.adempiere.webui.component.Mask; +import org.adempiere.webui.part.AbstractUIPart; +import org.zkoss.zk.ui.Component; + +/** + * interface for any component want support show other window over it with a + * mask. object manage component as AbstractUIPart also implement this interface + * + */ +public interface ISupportMask { + /** + * show mask over this component + */ + public void showMask(); + + /** + * Hide mask. at code call showMask will hand reference to this object. and + * call this function in handle close event of window + */ + public void hideMask(); + + /** + * return cache object or make new object and return + * @return + */ + public Mask getMaskObj(); + + /** + * return self if is a component or return component it manage + * if {@link AbstractUIPart} is implement this interface, return {@link AbstractUIPart#getComponent()} + * @return + */ + public Component getMaskComponent(); +} diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/LayoutUtils.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/LayoutUtils.java index cd50070dfb..ba8ef0c34f 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/LayoutUtils.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/LayoutUtils.java @@ -16,6 +16,10 @@ import java.io.IOException; import java.io.StringWriter; import org.adempiere.webui.component.Label; +import org.adempiere.webui.component.Mask; +import org.adempiere.webui.component.Tabpanel; +import org.adempiere.webui.desktop.IDesktop; +import org.adempiere.webui.session.SessionManager; import org.compiere.util.Util; import org.zkoss.zk.au.out.AuOuter; import org.zkoss.zk.au.out.AuScript; @@ -221,4 +225,97 @@ public final class LayoutUtils { target.setSclass(sclass); } } + + public static final int OVERLAP_TAB_PANEL = 1; + public static final int OVERLAP_ALL_PAGE = 2; + public static final int OVERLAP_PARENT = 3; + public static final int OVERLAP_SELF = 4; + + /** + * show window with a mask below. mask over tabPanel, all window or only over a control, dependency ownModel flag. + * when ownModel == {@link #OVERLAP_SELF}, window show overlap childOfOwn, + * when childOfOwn isn't implement {@link ISupportMask} make new {@link Mask} object to make mask layout + * ownModel == {@link #OVERLAP_ALL_PAGE}, window show overlap all page + * ownModel == {@link #OVERLAP_TAB_PANEL}, window show overlap tabPanel + * ownModel == {@link #OVERLAP_PARENT}, search near parent of childOfOwn implement {@link ISupportMask} if not exist user as OVERLAP_ALL_PAGE + * @param window + * @param childOfOwn + * @param ownModel + * @return when show success return IMask object, it is own window, use {@link ISupportMask#hideMask()} to hiden mask. + * other return null. with case return null (show over childOfOwn or parent of childOfOwn but childOfOwn or parent of childOfOwn isn't implement {@link ISupportMask}), please consider use {@link #showOverlapWithMask(Component, Component)} + */ + public static ISupportMask showWindowWithMask(Window window, Component childOfOwn, int ownModel){ + ISupportMask ownWindow = null; + // search to top parent, capture parent with interface ISupportMask + if (ownModel == OVERLAP_SELF && ISupportMask.class.isInstance(childOfOwn)){ + ownWindow = (ISupportMask) childOfOwn; + }else if (ownModel == OVERLAP_TAB_PANEL){ + ownWindow = findMaskParent (childOfOwn, Tabpanel.class); + }else if (ownModel == OVERLAP_PARENT){ + ownWindow = findMaskParent (childOfOwn, null); + }else if (ownModel == OVERLAP_ALL_PAGE){ + IDesktop desktop = SessionManager.getAppDesktop(); + if (desktop != null && ISupportMask.class.isInstance(desktop)){ + ownWindow = (ISupportMask)desktop; + } + } + + // show window + if (ownWindow != null){ + showWindowWithMask (window, ownWindow); + } + + return ownWindow; + } + + /** + * Show window in center of component get from {@link} + * @param window + * @param mask + */ + protected static void showWindowWithMask(Window window, ISupportMask mask){ + mask.showMask(); + mask.getMaskComponent().appendChild(window); + LayoutUtils.openOverlappedWindow(mask.getMaskComponent(), window, "middle_center"); + } + + /** + * Show window over ownWindow with a mask, use when ownWindow isn't implement {@link ISupportMask} + * @param window + * @param ownWindow + * @param mask if mask = null, make new and return it + * @return {@link Mask} objec for hiden mask when close window. + */ + public static Mask showWindowWithMask(Window window, Component ownWindow, Mask mask){ + if (mask == null){ + mask = new Mask(); + } + ownWindow.appendChild(mask); + + ownWindow.appendChild(window); + LayoutUtils.openOverlappedWindow(ownWindow, window, "middle_center"); + + return mask; + } + + /** + * find parent control of child control, parent must implement {@link ISupportMask} + * if parentClass != null, parent class must extends parentClass + * @param child + * @param ownModel + * @return + */ + public static ISupportMask findMaskParent (Component child, Class parentClass){ + Component parent = child; + ISupportMask trueParent = null; + while ((parent = parent.getParent()) != null){ + if (ISupportMask.class.isInstance(parent)){ + if (parentClass == null || parentClass.isInstance(parent)){ + trueParent = (ISupportMask)parent; + break; + } + } + } + return trueParent; + } } diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/component/Mask.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/component/Mask.java index 589f70e413..f69ee9e5ce 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/component/Mask.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/component/Mask.java @@ -33,5 +33,12 @@ public class Mask extends Div { setStyle("position: absolute; width: 100%; height: 100%; border: none; margin: 0; background-color: #e4e4e4; " + "padding: 0; z-index:999; opacity:0.6; top: 0px; left: 0px;"); } + + public void hideMask() { + if (this.getParent() != null){ + this.detach(); + } + + } } diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/component/Tabpanel.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/component/Tabpanel.java index d953027dd9..779ff32e3a 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/component/Tabpanel.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/component/Tabpanel.java @@ -17,7 +17,9 @@ package org.adempiere.webui.component; +import org.adempiere.webui.ISupportMask; import org.adempiere.webui.panel.ITabOnCloseHandler; +import org.zkoss.zk.ui.Component; import org.zkoss.zk.ui.IdSpace; import org.zkoss.zul.Tab; @@ -27,7 +29,7 @@ import org.zkoss.zul.Tab; * @date Feb 25, 2007 * @version $Revision: 0.10 $ */ -public class Tabpanel extends org.zkoss.zul.Tabpanel implements IdSpace +public class Tabpanel extends org.zkoss.zul.Tabpanel implements IdSpace, ISupportMask { /** * @@ -85,4 +87,51 @@ public class Tabpanel extends org.zkoss.zul.Tabpanel implements IdSpace public void setOnCloseHandler(ITabOnCloseHandler handler) { this.onCloseHandler = handler; } + + /** + * cache {@link Mask} Object + */ + private Mask maskObj; + + /** + * {@inheritDoc} + */ + @Override + public void showMask() { + maskObj = getMaskObj (); + if (maskObj.getParent() == null){ + this.appendChild(maskObj); + } + + } + + /** + * {@inheritDoc} + */ + @Override + public void hideMask() { + if (maskObj != null || maskObj.getParent() != null){ + maskObj.detach(); + } + + } + + /** + * {@inheritDoc} + */ + @Override + public Mask getMaskObj() { + if (maskObj == null) + maskObj = new Mask(); + + return maskObj; + } + + /** + * {@inheritDoc} + */ + @Override + public Component getMaskComponent() { + return this; + } } diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/component/Window.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/component/Window.java index d1723dab00..ce28cb2738 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/component/Window.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/component/Window.java @@ -17,7 +17,9 @@ package org.adempiere.webui.component; +import org.adempiere.webui.ISupportMask; import org.adempiere.webui.event.DialogEvents; +import org.zkoss.zk.ui.Component; import org.zkoss.zk.ui.Executions; import org.zkoss.zk.ui.Page; import org.zkoss.zk.ui.event.Event; @@ -29,7 +31,7 @@ import org.zkoss.zk.ui.event.Events; * @date Feb 25, 2007 * @version $Revision: 0.10 $ */ -public class Window extends org.zkoss.zul.Window +public class Window extends org.zkoss.zul.Window implements ISupportMask { /** * @@ -105,4 +107,51 @@ public class Window extends org.zkoss.zul.Window return Mode.HIGHLIGHTED; } } + + /** + * cache {@link Mask} Object + */ + private Mask maskObj; + + /** + * {@inheritDoc} + */ + @Override + public void showMask() { + maskObj = getMaskObj (); + if (maskObj.getParent() == null){ + this.appendChild(maskObj); + } + + } + + /** + * {@inheritDoc} + */ + @Override + public void hideMask() { + if (maskObj != null || maskObj.getParent() != null){ + maskObj.detach(); + } + + } + + /** + * {@inheritDoc} + */ + @Override + public Mask getMaskObj() { + if (maskObj == null) + maskObj = new Mask(); + + return maskObj; + } + + /** + * {@inheritDoc} + */ + @Override + public Component getMaskComponent() { + return this; + } } diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/part/AbstractUIPart.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/part/AbstractUIPart.java index 7a63e03d63..adb5902a26 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/part/AbstractUIPart.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/part/AbstractUIPart.java @@ -12,15 +12,19 @@ *****************************************************************************/ package org.adempiere.webui.part; +import org.adempiere.webui.ISupportMask; +import org.adempiere.webui.component.Mask; +import org.adempiere.webui.desktop.IDesktop; import org.zkoss.zk.ui.Component; import org.zkoss.zk.ui.Page; +import org.zkoss.zul.Borderlayout; /** * * @author Low Heng Sin * */ -public abstract class AbstractUIPart implements UIPart { +public abstract class AbstractUIPart implements UIPart, ISupportMask { protected Page page = null; @@ -43,4 +47,55 @@ public abstract class AbstractUIPart implements UIPart { protected abstract Component doCreatePart(Component parent); + /** + * cache {@link Mask} Object + */ + private Mask maskObj; + + /** + * {@inheritDoc} + */ + @Override public void showMask() { + maskObj = getMaskObj (); + if (maskObj.getParent() == null){ + this.getMaskComponent().appendChild(maskObj); + } + + } + + /** + * {@inheritDoc} + */ + @Override + public void hideMask() { + if (maskObj != null || maskObj.getParent() != null){ + maskObj.detach(); + } + + } + + /** + * {@inheritDoc} + */ + @Override + public Mask getMaskObj() { + if (maskObj == null) + maskObj = new Mask(); + + return maskObj; + } + + /** + * {@inheritDoc} + * knowIssue: because {@link IDesktop#getComponent()} return {@link BorderLayout} , + * don't append window to child list of it, in this case we must get parent of BorderLayout + */ + @Override + public Component getMaskComponent(){ + Component component = getComponent(); + if (Borderlayout.class.isInstance(component)){ + component = component.getParent(); + } + return component; + } } diff --git a/org.adempiere.ui.zk/theme/default/zul/desktop/desktop.zul b/org.adempiere.ui.zk/theme/default/zul/desktop/desktop.zul index 4ff49ee54f..e5c55a363d 100644 --- a/org.adempiere.ui.zk/theme/default/zul/desktop/desktop.zul +++ b/org.adempiere.ui.zk/theme/default/zul/desktop/desktop.zul @@ -1,5 +1,6 @@ +
@@ -12,4 +13,5 @@
+
\ No newline at end of file