From 0e42e359f3e6c96a8b24dd291f305db5b66d9966 Mon Sep 17 00:00:00 2001 From: Heng Sin Low Date: Fri, 13 Apr 2012 15:24:22 +0800 Subject: [PATCH] IDEMPIERE-231 Zk6: Improve the tablet experience. Fixed click slow to fire or sometime not fire at all on iPad. --- .../webui/component/DrillCommand.java | 9 +- .../adempiere/webui/component/Messagebox.java | 1 + .../webui/component/ZoomCommand.java | 15 +-- .../webui/dashboard/DPFavourites.java | 99 +++++++++------ .../webui/dashboard/DPRecentItems.java | 104 ++++++++------- .../webui/desktop/DashboardController.java | 16 ++- .../webui/desktop/DefaultDesktop.java | 8 +- .../webui/desktop/NavBar2Desktop.java | 9 +- .../webui/desktop/NavBarDesktop.java | 8 +- .../webui/event/TouchEventHelper.java | 105 ++++++++++++++++ .../adempiere/webui/event/TouchEvents.java | 26 ++++ .../org/adempiere/webui/panel/MenuPanel.java | 118 +++++++++++------- .../org/adempiere/webui/panel/SidePanel.java | 15 ++- .../adempiere/webui/report/HTMLExtension.java | 4 +- .../webui/window/ZkReportViewer.java | 10 +- org.adempiere.ui.zk/js/report.js | 7 +- .../theme/default/css/theme.css.dsp | 17 ++- 17 files changed, 408 insertions(+), 163 deletions(-) create mode 100644 org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/event/TouchEventHelper.java create mode 100644 org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/event/TouchEvents.java diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/component/DrillCommand.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/component/DrillCommand.java index eaa2b815af..004efcfbc8 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/component/DrillCommand.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/component/DrillCommand.java @@ -17,6 +17,7 @@ import java.util.Map; import org.adempiere.webui.event.DrillEvent; import org.compiere.model.MQuery; +import org.zkoss.json.JSONArray; import org.zkoss.lang.Objects; import org.zkoss.zk.au.AuRequest; import org.zkoss.zk.au.AuService; @@ -41,19 +42,19 @@ public class DrillCommand implements AuService { return false; final Map map = request.getData(); - String[] data = (String[]) map.get(""); + JSONArray data = (JSONArray) map.get("data"); final Component comp = request.getComponent(); if (comp == null) throw new UiException(MZk.ILLEGAL_REQUEST_COMPONENT_REQUIRED, this); - if (data == null || data.length < 2) + if (data == null || data.size() < 2) throw new UiException(MZk.ILLEGAL_REQUEST_WRONG_DATA, new Object[] { Objects.toString(data), this }); - String columnName = data[0]; + String columnName = (String) data.get(0); String tableName = MQuery.getZoomTableName(columnName); - String code = data[1]; + String code = (String) data.get(1); // MQuery query = new MQuery(tableName); query.addRestriction(columnName, MQuery.EQUAL, code); diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/component/Messagebox.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/component/Messagebox.java index 3d7a56aff7..eba40512eb 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/component/Messagebox.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/component/Messagebox.java @@ -107,6 +107,7 @@ public class Messagebox extends Window implements EventListener private void init() { Properties ctx = Env.getCtx(); + lblMsg.setEncode(false); lblMsg.setValue(msg); btnOk.setLabel(Util.cleanAmp(Msg.getMsg(ctx, "OK"))); diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/component/ZoomCommand.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/component/ZoomCommand.java index d4ab323a26..f3db10a76b 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/component/ZoomCommand.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/component/ZoomCommand.java @@ -17,6 +17,7 @@ import java.util.Map; import org.adempiere.webui.event.ZoomEvent; import org.compiere.model.MQuery; +import org.zkoss.json.JSONArray; import org.zkoss.lang.Objects; import org.zkoss.zk.au.AuRequest; import org.zkoss.zk.au.AuService; @@ -40,30 +41,30 @@ public class ZoomCommand implements AuService { return false; Map map = request.getData(); - final String[] data = (String[]) map.get(""); - + JSONArray data = (JSONArray) map.get("data"); + final Component comp = request.getComponent(); if (comp == null) throw new UiException(MZk.ILLEGAL_REQUEST_COMPONENT_REQUIRED, this); - if (data == null || data.length < 2) + if (data == null || data.size() < 2) throw new UiException(MZk.ILLEGAL_REQUEST_WRONG_DATA, new Object[] { Objects.toString(data), this }); - String columnName = data[0]; + String columnName = (String) data.get(0); String tableName = MQuery.getZoomTableName(columnName); Object code = null; if (columnName.endsWith("_ID")) { try { - code = Integer.parseInt(data[1]); + code = Integer.parseInt((String) data.get(1)); } catch (Exception e) { - code = data[1]; + code = data.get(1); } } else { - code = data[1]; + code = data.get(1); } // MQuery query = new MQuery(tableName); diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/dashboard/DPFavourites.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/dashboard/DPFavourites.java index 277cfcf68a..f63cd223fa 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/dashboard/DPFavourites.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/dashboard/DPFavourites.java @@ -16,7 +16,7 @@ package org.adempiere.webui.dashboard; import java.util.Enumeration; import org.adempiere.exceptions.DBException; -import org.adempiere.webui.component.ToolBarButton; +import org.adempiere.webui.event.TouchEventHelper; import org.adempiere.webui.session.SessionManager; import org.adempiere.webui.window.FDialog; import org.compiere.model.MTree; @@ -29,6 +29,7 @@ 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.A; import org.zkoss.zul.Box; import org.zkoss.zul.Image; import org.zkoss.zul.Label; @@ -44,7 +45,9 @@ import org.zkoss.zul.Vbox; * @author Elaine * @date November 20, 2008 */ -public class DPFavourites extends DashboardPanel implements EventListener { +public class DPFavourites extends DashboardPanel implements EventListener { + + private static final String NODE_ID_ATTR = "Node_ID"; /** * @@ -65,12 +68,16 @@ public class DPFavourites extends DashboardPanel implements EventListener { { super(); + this.setPage(SessionManager.getAppDesktop().getComponent().getPage()); + Panel panel = new Panel(); this.appendChild(panel); Panelchildren favContent = new Panelchildren(); panel.appendChild(favContent); - favContent.appendChild(createFavouritesPanel()); + bxFav = new Vbox(); + favContent.appendChild(bxFav); + createFavouritesPanel(); Toolbar favToolbar = new Toolbar(); this.appendChild(favToolbar); @@ -87,10 +94,8 @@ public class DPFavourites extends DashboardPanel implements EventListener { favContent.addEventListener(Events.ON_DROP, this); } - private Box createFavouritesPanel() + private void createFavouritesPanel() { - bxFav = new Vbox(); - int AD_Role_ID = Env.getAD_Role_ID(Env.getCtx()); int AD_Tree_ID = DB.getSQLValue(null, "SELECT COALESCE(r.AD_Tree_Menu_ID, ci.AD_Tree_Menu_ID)" @@ -114,21 +119,22 @@ public class DPFavourites extends DashboardPanel implements EventListener { MTreeNode nd = (MTreeNode)en.nextElement(); if (nd.isOnBar()) { String label = nd.toString().trim(); - ToolBarButton btnFavItem = new ToolBarButton(String.valueOf(nd.getNode_ID())); + A btnFavItem = new A(); + btnFavItem.setAttribute(NODE_ID_ATTR, String.valueOf(nd.getNode_ID())); + bxFav.appendChild(btnFavItem); btnFavItem.setLabel(label); btnFavItem.setImage(getIconFile(nd)); btnFavItem.setDraggable(DELETE_FAV_DROPPABLE); btnFavItem.addEventListener(Events.ON_CLICK, this); btnFavItem.addEventListener(Events.ON_DROP, this); - bxFav.appendChild(btnFavItem); + btnFavItem.setSclass("menu-href"); + TouchEventHelper.addOnTapEventListener(btnFavItem, this); } } } lblMsg = new Label("(Drag and drop menu item here)"); if(bxFav.getChildren().isEmpty()) bxFav.appendChild(lblMsg); - - return bxFav; } /** @@ -165,23 +171,13 @@ public class DPFavourites extends DashboardPanel implements EventListener { Component comp = event.getTarget(); String eventName = event.getName(); - if(eventName.equals(Events.ON_CLICK)) + if (eventName.equals(TouchEventHelper.ON_TAP)) { - if(comp instanceof ToolBarButton) - { - ToolBarButton btn = (ToolBarButton) comp; - - int menuId = 0; - try - { - menuId = Integer.valueOf(btn.getName()); - } - catch (Exception e) { - - } - - if(menuId > 0) SessionManager.getAppDesktop().onMenuSelected(menuId); - } + doOnClick(comp); + } + else if(eventName.equals(Events.ON_CLICK) && !TouchEventHelper.isIgnoreClick(comp)) + { + doOnClick(comp); } // Elaine 2008/07/24 else if(eventName.equals(Events.ON_DROP)) @@ -201,9 +197,9 @@ public class DPFavourites extends DashboardPanel implements EventListener { } else if(comp instanceof Image) { - if(dragged instanceof ToolBarButton) + if(dragged instanceof A) { - ToolBarButton btn = (ToolBarButton) dragged; + A btn = (A) dragged; removeLink(btn); } } @@ -211,8 +207,26 @@ public class DPFavourites extends DashboardPanel implements EventListener { // } - private void removeLink(ToolBarButton btn) { - String value = btn.getName(); + private void doOnClick(Component comp) { + if(comp instanceof A) + { + A btn = (A) comp; + + int menuId = 0; + try + { + menuId = Integer.valueOf((String)btn.getAttribute(NODE_ID_ATTR)); + } + catch (Exception e) { + + } + + if(menuId > 0) SessionManager.getAppDesktop().onMenuSelected(menuId); + } + } + + private void removeLink(A btn) { + String value = (String) btn.getAttribute(NODE_ID_ATTR); if(value != null) { @@ -240,14 +254,29 @@ public class DPFavourites extends DashboardPanel implements EventListener { int Node_ID = Integer.valueOf(value.toString()); if(barDBupdate(true, Node_ID)) { - String label = treeitem.getLabel().trim(); - ToolBarButton btnFavItem = new ToolBarButton(String.valueOf(Node_ID)); + String label = null; + String image = null; + if (treeitem.getLabel() != null && treeitem.getLabel().trim().length() > 0) + { + label = treeitem.getLabel().trim(); + image = treeitem.getImage(); + } + else + { + A link = (A) treeitem.getTreerow().getFirstChild().getFirstChild(); + label = link.getLabel(); + image = link.getImage(); + } + A btnFavItem = new A(); + bxFav.appendChild(btnFavItem); + btnFavItem.setAttribute(NODE_ID_ATTR, String.valueOf(Node_ID)); btnFavItem.setLabel(label); - btnFavItem.setImage(treeitem.getImage()); + btnFavItem.setImage(image); btnFavItem.setDraggable(DELETE_FAV_DROPPABLE); btnFavItem.addEventListener(Events.ON_CLICK, this); - btnFavItem.addEventListener(Events.ON_DROP, this); - bxFav.appendChild(btnFavItem); + btnFavItem.addEventListener(Events.ON_DROP, this); + btnFavItem.setSclass("menu-href"); + TouchEventHelper.addOnTapEventListener(btnFavItem, this); bxFav.removeChild(lblMsg); bxFav.invalidate(); } else { diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/dashboard/DPRecentItems.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/dashboard/DPRecentItems.java index 3eef8a4314..73be564747 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/dashboard/DPRecentItems.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/dashboard/DPRecentItems.java @@ -15,7 +15,8 @@ package org.adempiere.webui.dashboard; import java.util.List; -import org.adempiere.webui.component.ToolBarButton; +import org.adempiere.webui.event.TouchEventHelper; +import org.adempiere.webui.event.TouchEvents; import org.adempiere.webui.session.SessionManager; import org.adempiere.webui.util.ServerPushTemplate; import org.compiere.model.MQuery; @@ -28,6 +29,7 @@ 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.A; import org.zkoss.zul.Box; import org.zkoss.zul.Image; import org.zkoss.zul.Panel; @@ -40,7 +42,9 @@ import org.zkoss.zul.Vbox; * @author Carlos Ruiz / GlobalQSS * @date January 27, 2012 */ -public class DPRecentItems extends DashboardPanel implements EventListener { +public class DPRecentItems extends DashboardPanel implements EventListener { + + private static final String AD_RECENT_ITEM_ID_ATTR = "AD_RecentItem_ID"; /** * @@ -55,13 +59,17 @@ public class DPRecentItems extends DashboardPanel implements EventListener { { super(); + this.setPage(SessionManager.getAppDesktop().getComponent().getPage()); + Panel panel = new Panel(); this.appendChild(panel); Panelchildren recentItemsContent = new Panelchildren(); panel.appendChild(recentItemsContent); - recentItemsContent.appendChild(createRecentItemsPanel()); - + bxRecentItems = new Vbox(); + recentItemsContent.appendChild(bxRecentItems); + createRecentItemsPanel(); + Toolbar recentItemsToolbar = new Toolbar(); this.appendChild(recentItemsToolbar); @@ -80,13 +88,9 @@ public class DPRecentItems extends DashboardPanel implements EventListener { } - private Box createRecentItemsPanel() + private void createRecentItemsPanel() { - bxRecentItems = new Vbox(); - refresh(); - - return bxRecentItems; } /** @@ -105,32 +109,13 @@ public class DPRecentItems extends DashboardPanel implements EventListener { Component comp = event.getTarget(); String eventName = event.getName(); - if (eventName.equals(Events.ON_CLICK)) + if (eventName.equals(TouchEvents.ON_TAP)) { - if (comp instanceof ToolBarButton) - { - ToolBarButton btn = (ToolBarButton) comp; - - int AD_RecentItem_ID = 0; - try - { - AD_RecentItem_ID = Integer.valueOf(btn.getName()); - } - catch (Exception e) { - } - - if (AD_RecentItem_ID > 0) { - MRecentItem ri = MRecentItem.get(Env.getCtx(), AD_RecentItem_ID); - String TableName = MTable.getTableName(Env.getCtx(), ri.getAD_Table_ID()); - MQuery query = MQuery.getEqualQuery(TableName + "_ID", ri.getRecord_ID()); - - SessionManager.getAppDesktop().openWindow(ri.getAD_Window_ID(), query); - } - } - if (comp instanceof Image) // Refresh button - { - refresh(); - } + doOnClick(comp); + } + else if (eventName.equals(Events.ON_CLICK) && !TouchEventHelper.isIgnoreClick(comp)) + { + doOnClick(comp); } else if(eventName.equals(Events.ON_DROP)) { @@ -139,24 +124,51 @@ public class DPRecentItems extends DashboardPanel implements EventListener { if(comp instanceof Image) { - if(dragged instanceof ToolBarButton) + if(dragged instanceof A) { - ToolBarButton btn = (ToolBarButton) dragged; + A btn = (A) dragged; removeLink(btn); } } } } - private void refresh() { + private void doOnClick(Component comp) { + if (comp instanceof A) + { + A btn = (A) comp; + + int AD_RecentItem_ID = 0; + try + { + AD_RecentItem_ID = Integer.valueOf((String)btn.getAttribute(AD_RECENT_ITEM_ID_ATTR)); + } + catch (Exception e) { + } + + if (AD_RecentItem_ID > 0) { + MRecentItem ri = MRecentItem.get(Env.getCtx(), AD_RecentItem_ID); + String TableName = MTable.getTableName(Env.getCtx(), ri.getAD_Table_ID()); + MQuery query = MQuery.getEqualQuery(TableName + "_ID", ri.getRecord_ID()); + + SessionManager.getAppDesktop().openWindow(ri.getAD_Window_ID(), query); + } + } + if (comp instanceof Image) // Refresh button + { + refresh(); + } + } + + private synchronized void refresh() { // Please review here - is throwing NPE in some cases when user push repeatedly the refresh button List childs = bxRecentItems.getChildren(); int childCount = childs.size(); for (int c = childCount - 1; c >=0; c--) { Component comp = (Component) childs.get(c); - if (comp instanceof ToolBarButton) { - ((ToolBarButton) comp).removeEventListener(Events.ON_CLICK, this); - ((ToolBarButton) comp).removeEventListener(Events.ON_DROP, this); + if (comp instanceof A) { + comp.removeEventListener(Events.ON_CLICK, this); + comp.removeEventListener(Events.ON_DROP, this); } bxRecentItems.removeChild(comp); } @@ -172,13 +184,17 @@ public class DPRecentItems extends DashboardPanel implements EventListener { String label = ri.getLabel(); if (label == null) continue; - ToolBarButton btnrecentItem = new ToolBarButton(String.valueOf(ri.getAD_RecentItem_ID())); + A btnrecentItem = new A(); + btnrecentItem.setAttribute(AD_RECENT_ITEM_ID_ATTR, String.valueOf(ri.getAD_RecentItem_ID())); + bxRecentItems.appendChild(btnrecentItem); btnrecentItem.setLabel(label); btnrecentItem.setImage(getIconFile()); btnrecentItem.setDraggable(DELETE_RECENTITEMS_DROPPABLE); btnrecentItem.addEventListener(Events.ON_CLICK, this); btnrecentItem.addEventListener(Events.ON_DROP, this); - bxRecentItems.appendChild(btnrecentItem); + btnrecentItem.setSclass("menu-href"); + TouchEventHelper.addOnTapEventListener(btnrecentItem, this); + riShown++; if (riShown >= maxri) break; @@ -186,8 +202,8 @@ public class DPRecentItems extends DashboardPanel implements EventListener { } - private void removeLink(ToolBarButton btn) { - String value = btn.getName(); + private void removeLink(A btn) { + String value = (String) btn.getAttribute(AD_RECENT_ITEM_ID_ATTR); if (value != null) { diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/desktop/DashboardController.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/desktop/DashboardController.java index b6c43a85a8..17df2d2799 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/desktop/DashboardController.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/desktop/DashboardController.java @@ -1,6 +1,16 @@ -/** - * - */ +/****************************************************************************** + * Copyright (C) 2012 Heng Sin Low * + * Copyright (C) 2012 Trek Global * + * 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.desktop; import java.io.BufferedReader; diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/desktop/DefaultDesktop.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/desktop/DefaultDesktop.java index 9d0ba0410b..4016d89abc 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/desktop/DefaultDesktop.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/desktop/DefaultDesktop.java @@ -90,11 +90,9 @@ public class DefaultDesktop extends TabbedDesktop implements MenuListener, Seria protected Component doCreatePart(Component parent) { - SidePanel pnlSide = new SidePanel(); + HeaderPanel pnlHead = new HeaderPanel(); - pnlSide.getMenuPanel().addMenuListener(this); - layout = new Borderlayout(); if (parent != null) { @@ -130,7 +128,9 @@ public class DefaultDesktop extends TabbedDesktop implements MenuListener, Seria UserPreference pref = SessionManager.getSessionApplication().getUserPreference(); boolean menuCollapsed= pref.isPropertyBool(UserPreference.P_MENU_COLLAPSED); w.setOpen(!menuCollapsed); - pnlSide.setParent(w); + + SidePanel pnlSide = new SidePanel(w); + pnlSide.getMenuPanel().addMenuListener(this); windowArea = new Center(); windowArea.setParent(layout); diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/desktop/NavBar2Desktop.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/desktop/NavBar2Desktop.java index a2185dfbb4..0622b4e6c9 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/desktop/NavBar2Desktop.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/desktop/NavBar2Desktop.java @@ -91,12 +91,9 @@ public class NavBar2Desktop extends TabbedDesktop implements MenuListener, Seria } protected Component doCreatePart(Component parent) - { - SidePanel pnlSide = new SidePanel(); + { HeaderPanel pnlHead = new HeaderPanel(); - pnlSide.getMenuPanel().addMenuListener(this); - layout = new Borderlayout(); if (parent != null) { @@ -132,7 +129,9 @@ public class NavBar2Desktop extends TabbedDesktop implements MenuListener, Seria UserPreference pref = SessionManager.getSessionApplication().getUserPreference(); boolean menuCollapsed= pref.isPropertyBool(UserPreference.P_MENU_COLLAPSED); w.setOpen(!menuCollapsed); - pnlSide.setParent(w); + + SidePanel pnlSide = new SidePanel(w); + pnlSide.getMenuPanel().addMenuListener(this); Center center = new Center(); center.setParent(layout); diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/desktop/NavBarDesktop.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/desktop/NavBarDesktop.java index 94f3251de0..170b2bbd64 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/desktop/NavBarDesktop.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/desktop/NavBarDesktop.java @@ -100,12 +100,9 @@ public class NavBarDesktop extends TabbedDesktop implements MenuListener, Serial } protected Component doCreatePart(Component parent) - { - SidePanel pnlSide = new SidePanel(); + { HeaderPanel pnlHead = new HeaderPanel(); - pnlSide.getMenuPanel().addMenuListener(this); - layout = new Borderlayout(); if (parent != null) { @@ -146,6 +143,9 @@ public class NavBarDesktop extends TabbedDesktop implements MenuListener, Serial navigationPanel.setWidth("100%"); navigationPanel.setHeight("100%"); + + SidePanel pnlSide = new SidePanel(parent.getPage()); + pnlSide.getMenuPanel().addMenuListener(this); navigationPanel.add(pnlSide, "Application Menu"); Div div = new Div(); diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/event/TouchEventHelper.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/event/TouchEventHelper.java new file mode 100644 index 0000000000..21d4b77c08 --- /dev/null +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/event/TouchEventHelper.java @@ -0,0 +1,105 @@ +/****************************************************************************** + * Copyright (C) 2012 Heng Sin Low * + * Copyright (C) 2012 Trek Global * + * 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.event; + +import org.zkoss.zk.au.out.AuScript; +import org.zkoss.zk.ui.Component; +import org.zkoss.zk.ui.event.Event; +import org.zkoss.zk.ui.event.EventListener; +import org.zkoss.zk.ui.event.Events; +import org.zkoss.zk.ui.util.Clients; + +/** + * @author hengsin + * + */ +public class TouchEventHelper implements TouchEvents, EventListener { + + private static final String TOUCH_TAP_TIME = "touch.tap.time"; + private Component touchStart = null; + private long touchStartTime = 0; + + private Component touchEnd = null; + private long touchEndTime = 0; + private Component component; + + /** + * + */ + private TouchEventHelper(Component component) { + component.addEventListener(ON_TOUCH_START, this); + component.addEventListener(ON_TOUCH_END, this); + addClientTouchListener(component); + this.component = component; + } + + private void addClientTouchListener(Component component) { + StringBuilder touchScript = new StringBuilder(); + touchScript.append("var widget = zk.Widget.$('") + .append(component.getUuid()).append("');"); + touchScript.append("jq(widget.$n()).bind('touchstart',"); + touchScript.append("function(event){"); + touchScript.append("var widget = zk.Widget.$('"); + touchScript.append(component.getUuid()).append("');"); + touchScript.append("var zEvent = new zk.Event(widget, 'onTouchstart', {}, {toServer: true});"); + touchScript.append("zAu.send(zEvent);"); + touchScript.append("});"); + + touchScript.append("jq(widget.$n()).bind('touchend',"); + touchScript.append("function(event){"); + touchScript.append("var widget = zk.Widget.$('"); + touchScript.append(component.getUuid()).append("');"); + touchScript.append("var zEvent = new zk.Event(widget, 'onTouchend', {}, {toServer: true});"); + touchScript.append("zAu.send(zEvent);"); + touchScript.append("});"); + Clients.response(new AuScript(component, touchScript.toString())); + } + + private void registerTouchStart(Event event) { + touchStart = event.getTarget(); + touchStartTime = System.currentTimeMillis(); + } + + private void registerTouchEnd(Event event) { + touchEnd = event.getTarget(); + touchEndTime = System.currentTimeMillis(); + } + + private boolean isTap() { + return touchStart != null && touchStart == touchEnd && (touchEndTime - touchStartTime) < 500; + } + + @Override + public void onEvent(Event event) throws Exception { + if (event.getName().equals(ON_TOUCH_START)) { + registerTouchStart(event); + } else if (event.getName().equals(ON_TOUCH_END)) { + registerTouchEnd(event); + if (isTap()) { + Events.sendEvent(component, new Event(ON_TAP, component, null)); + component.setAttribute(TOUCH_TAP_TIME, System.currentTimeMillis()); + } + } + } + + public static void addOnTapEventListener(Component component, EventListener listener) { + new TouchEventHelper(component); + component.addEventListener(ON_TAP, listener); + } + + public static boolean isIgnoreClick(Component component) { + Number n = (Number) component.getAttribute(TOUCH_TAP_TIME); + return n != null && ((System.currentTimeMillis() - n.longValue()) < (60000)); + } +} diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/event/TouchEvents.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/event/TouchEvents.java new file mode 100644 index 0000000000..32dc058c88 --- /dev/null +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/event/TouchEvents.java @@ -0,0 +1,26 @@ +/****************************************************************************** + * Copyright (C) 2012 Heng Sin Low * + * Copyright (C) 2012 Trek Global * + * 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.event; + +/** + * + * @author hengsin + * + */ +public interface TouchEvents { + + public final static String ON_TOUCH_START = "onTouchstart"; + public final static String ON_TOUCH_END = "onTouchend"; + public final static String ON_TAP = "onTap"; +} diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/panel/MenuPanel.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/panel/MenuPanel.java index 37ba6ab6e0..a476eeeb61 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/panel/MenuPanel.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/panel/MenuPanel.java @@ -23,6 +23,8 @@ import java.util.Properties; import org.adempiere.webui.component.ToolBarButton; import org.adempiere.webui.event.MenuListener; +import org.adempiere.webui.event.TouchEventHelper; +import org.adempiere.webui.event.TouchEvents; import org.adempiere.webui.exception.ApplicationException; import org.adempiere.webui.session.SessionManager; import org.adempiere.webui.util.TreeUtils; @@ -33,10 +35,12 @@ import org.compiere.util.Env; import org.compiere.util.Msg; import org.compiere.util.Util; import org.zkoss.zk.ui.Component; +import org.zkoss.zk.ui.Page; import org.zkoss.zk.ui.event.Event; import org.zkoss.zk.ui.event.EventListener; import org.zkoss.zk.ui.event.Events; import org.zkoss.zk.ui.util.Clients; +import org.zkoss.zul.A; import org.zkoss.zul.Panel; import org.zkoss.zul.Panelchildren; import org.zkoss.zul.Toolbar; @@ -54,7 +58,7 @@ import org.zkoss.zul.Treerow; * @date Feb 25, 2007 * @version $Revision: 0.10 $ */ -public class MenuPanel extends Panel implements EventListener +public class MenuPanel extends Panel implements EventListener { private static final String ON_EXPAND_MENU_EVENT = "onExpandMenu"; /** @@ -68,25 +72,31 @@ public class MenuPanel extends Panel implements EventListener private ToolBarButton expandToggle; - public MenuPanel() + public MenuPanel(Page page) + { + setPage(page); + init(); + } + + public MenuPanel(Component parent) { - ctx = Env.getCtx(); + if (parent != null) + this.setParent(parent); + init(); + } + + private void init() { + ctx = Env.getCtx(); int adRoleId = Env.getAD_Role_ID(ctx); int adTreeId = getTreeId(ctx, adRoleId); - MTree mTree = new MTree(ctx, adTreeId, false, true, null); - - if(mTree == null) - { - throw new ApplicationException("Could not load menu tree"); - } - + MTree mTree = new MTree(ctx, adTreeId, false, true, null); MTreeNode rootNode = mTree.getRoot(); - init(); + initComponents(); initMenu(rootNode); pnlSearch.initialise(); - } + } - private void init() + private void initComponents() { this.setWidth("100%"); this.setHeight("100%"); @@ -132,12 +142,13 @@ public class MenuPanel extends Panel implements EventListener Treecols treeCols = new Treecols(); Treecol treeCol = new Treecol(); - Treechildren rootTreeChildren = new Treechildren(); - generateMenu(rootTreeChildren, rootNode); + Treechildren rootTreeChildren = new Treechildren(); treeCols.appendChild(treeCol); menuTree.appendChild(treeCols); menuTree.appendChild(rootTreeChildren); + + generateMenu(rootTreeChildren, rootNode); } private int getTreeId(Properties ctx, int adRoleId) @@ -160,38 +171,50 @@ public class MenuPanel extends Panel implements EventListener { MTreeNode mChildNode = (MTreeNode)nodeEnum.nextElement(); Treeitem treeitem = new Treeitem(); - treeChildren.appendChild(treeitem); - treeitem.setLabel(mChildNode.getName()); - treeitem.setTooltiptext(mChildNode.getDescription()); - Treecell cell = (Treecell)treeitem.getTreerow().getFirstChild(); - cell.setSclass("menu-treecell-cnt"); - + treeChildren.appendChild(treeitem); + treeitem.setTooltiptext(mChildNode.getDescription()); + if(mChildNode.getChildCount() != 0) { treeitem.setOpen(false); + treeitem.setLabel(mChildNode.getName()); + Treecell cell = (Treecell)treeitem.getTreerow().getFirstChild(); + cell.setSclass("menu-treecell-cnt"); Treechildren treeItemChildren = new Treechildren(); + treeitem.appendChild(treeItemChildren); generateMenu(treeItemChildren, mChildNode); - if(treeItemChildren.getChildren().size() != 0) - treeitem.appendChild(treeItemChildren); + if (treeItemChildren.getChildren().size() == 0) + { + treeItemChildren.detach(); + } treeitem.getTreerow().addEventListener(Events.ON_CLICK, this); } else { treeitem.setValue(String.valueOf(mChildNode.getNode_ID())); + Treerow treeRow = new Treerow(); + treeitem.appendChild(treeRow); + Treecell treeCell = new Treecell(); + treeRow.appendChild(treeCell); + A link = new A(); + treeCell.appendChild(link); if (mChildNode.isReport()) - treeitem.setImage("/images/mReport.png"); + link.setImage("/images/mReport.png"); else if (mChildNode.isProcess() || mChildNode.isTask()) - treeitem.setImage("/images/mProcess.png"); + link.setImage("/images/mProcess.png"); else if (mChildNode.isWorkFlow()) - treeitem.setImage("/images/mWorkFlow.png"); + link.setImage("/images/mWorkFlow.png"); else - treeitem.setImage("/images/mWindow.png"); + link.setImage("/images/mWindow.png"); + link.setLabel(mChildNode.getName()); treeitem.getTreerow().setDraggable("favourite"); // Elaine 2008/07/24 - treeitem.getTreerow().addEventListener(Events.ON_CLICK, this); + link.addEventListener(Events.ON_CLICK, this); + link.setSclass("menu-href"); + TouchEventHelper.addOnTapEventListener(link, this); } } } @@ -210,21 +233,13 @@ public class MenuPanel extends Panel implements EventListener { Component comp = event.getTarget(); String eventName = event.getName(); - - if (eventName.equals(Events.ON_CLICK)) + if (eventName.equals(TouchEvents.ON_TAP)) { - if (comp instanceof Treerow) - { - Treeitem selectedItem = (Treeitem) comp.getParent(); - if(selectedItem.getValue() != null) - { - fireMenuSelectedEvent(selectedItem); - } - else - { - selectedItem.setOpen(!selectedItem.isOpen()); - } - } + doOnClick(comp); + } + else if (eventName.equals(Events.ON_CLICK) && !TouchEventHelper.isIgnoreClick(comp)) + { + doOnClick(comp); } // Elaine 2009/02/27 - expand tree else if (eventName.equals(Events.ON_CHECK) && event.getTarget() == expandToggle) @@ -239,6 +254,25 @@ public class MenuPanel extends Panel implements EventListener } // } + + private void doOnClick(Component comp) { + if (comp instanceof A) { + comp = comp.getParent().getParent(); + } + if (comp instanceof Treerow) + { + Treeitem selectedItem = (Treeitem) comp.getParent(); + if(selectedItem.getValue() != null) + { + fireMenuSelectedEvent(selectedItem); + } + else + { + selectedItem.setOpen(!selectedItem.isOpen()); + } + selectedItem.setSelected(true); + } + } protected void fireMenuSelectedEvent(Treeitem selectedItem) { int nodeId = Integer.parseInt((String)selectedItem.getValue()); diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/panel/SidePanel.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/panel/SidePanel.java index 4697279524..4851c867ec 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/panel/SidePanel.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/panel/SidePanel.java @@ -18,6 +18,8 @@ package org.adempiere.webui.panel; import org.adempiere.webui.component.Panel; +import org.zkoss.zk.ui.Component; +import org.zkoss.zk.ui.Page; /** * @@ -32,19 +34,26 @@ public class SidePanel extends Panel */ private static final long serialVersionUID = -3039805384016666481L; private MenuPanel pnlMenu; - public SidePanel() + + public SidePanel(Page page) + { + setPage(page); + init(); + } + + public SidePanel(Component parent) { + setParent(parent); init(); } private void init() { - pnlMenu = new MenuPanel(); + pnlMenu = new MenuPanel(this); this.setWidth("100%"); this.setHeight("100%"); this.setStyle("position: relative"); - this.appendChild(pnlMenu); } public MenuPanel getMenuPanel() diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/report/HTMLExtension.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/report/HTMLExtension.java index f6cd900618..1c8563f903 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/report/HTMLExtension.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/report/HTMLExtension.java @@ -57,7 +57,7 @@ public class HTMLExtension implements IHTMLExtension { window.addAttribute("onmouseover", "this.style.backgroundColor = 'lightgray'"); window.addAttribute("onmouseout", "this.style.backgroundColor = 'white'"); href = new a("javascript:void(0)"); - href.setStyle("text-decoration: none; font-size: 10px; vertical-align: middle;"); + href.setStyle("text-decoration: none; font-size: 11px; vertical-align: middle;"); href.addAttribute("onclick", "parent.zoom('" + componentId + "', '" + dataElement.getColumnName() + "', '" @@ -75,7 +75,7 @@ public class HTMLExtension implements IHTMLExtension { report.addAttribute("onmouseover", "this.style.backgroundColor = 'lightgray'"); report.addAttribute("onmouseout", "this.style.backgroundColor = 'white'"); href = new a("javascript:void(0)"); - href.setStyle("text-decoration: none; font-size: 10px; vertical-align: middle;"); + href.setStyle("text-decoration: none; font-size: 11px; vertical-align: middle;"); href.addAttribute("onclick", "parent.drillDown('" + componentId + "', '" + dataElement.getColumnName() + "', '" diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/window/ZkReportViewer.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/window/ZkReportViewer.java index 8e9e67cad5..70b2e98084 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/window/ZkReportViewer.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/window/ZkReportViewer.java @@ -153,7 +153,7 @@ public class ZkReportViewer extends Window implements EventListener, ITabOnClose */ public ZkReportViewer(ReportEngine re, String title) { super(); - + log.info(""); m_WindowNo = SessionManager.getAppDesktop().registerWindow(this); Env.setContext(re.getCtx(), m_WindowNo, "_WinInfo_IsReportViewer", "Y"); @@ -184,9 +184,9 @@ public class ZkReportViewer extends Window implements EventListener, ITabOnClose private void init() { Borderlayout layout = new Borderlayout(); - layout.setStyle("position: absolute; height: 99%; width: 99%"); + layout.setStyle("position: absolute; height: 97%; width: 98%; border:none; padding:none; margin:none;"); this.appendChild(layout); - this.setStyle("width: 100%; height: 100%; position: absolute"); + this.setStyle("width: 100%; height: 100%; position: absolute; border:none; padding:none; margin:none;"); toolBar.setHeight("26px"); @@ -277,8 +277,6 @@ public class ZkReportViewer extends Window implements EventListener, ITabOnClose layout.appendChild(center); iframe = new Iframe(); iframe.setId("reportFrame"); - iframe.setHeight("100%"); - iframe.setWidth("100%"); iframe.addEventListener(Events.ON_CLICK, this); iframe.addEventListener(Events.ON_RIGHT_CLICK, this); center.appendChild(iframe); @@ -374,7 +372,7 @@ public class ZkReportViewer extends Window implements EventListener, ITabOnClose m_reportEngine.createXLS(file, AEnv.getLanguage(Env.getCtx())); media = new AMedia(getTitle(), "xls", "application/vnd.ms-excel", file, true); } - + iframe.setContent(media); } diff --git a/org.adempiere.ui.zk/js/report.js b/org.adempiere.ui.zk/js/report.js index b9d6fea9a2..d7bd767c94 100644 --- a/org.adempiere.ui.zk/js/report.js +++ b/org.adempiere.ui.zk/js/report.js @@ -1,18 +1,18 @@ function zoom(cmpid, column, value){ var widget = zk.Widget.$(cmpid); - var event = new zk.Event({target: widget, name: 'onZoom', data: [column, value], opts: {ctl: true}}); + var event = new zk.Event(widget, 'onZoom', {data: [column, value]}, {toServer: true}); zAu.send(event); } function drillAcross(cmpid, column, value){ var widget = zk.Widget.$(cmpid); - var event = new zk.Event({target: widget, name: 'onDrillAcross', data: [column, value], opts: {ctl: true}}); + var event = new zk.Event(widget, 'onDrillAcross', {data: [column, value]}, {toServer: true}); zAu.send(event); } function drillDown(cmpid, column, value){ var widget = zk.Widget.$(cmpid); - var event = new zk.Event({target: widget, name: 'onDrillDown', data: [column, value], opts: {ctl: true}}); + var event = new zk.Event(widget, 'onDrillDown', {data: [column, value]}, {toServer: true}); zAu.send(event); } @@ -39,3 +39,4 @@ function showColumnMenu(e, columnName, row) { setTimeout("document.getElementById('" + columnName + "_" + row + "_d" + "').style.display='none'", 3000); } + diff --git a/org.adempiere.ui.zk/theme/default/css/theme.css.dsp b/org.adempiere.ui.zk/theme/default/css/theme.css.dsp index 5b00957887..6dd78ed549 100644 --- a/org.adempiere.ui.zk/theme/default/css/theme.css.dsp +++ b/org.adempiere.ui.zk/theme/default/css/theme.css.dsp @@ -113,6 +113,21 @@ html,body { font-size: 10px; } +.menu-href { + font-size: 11px; + font-weight: normal; + color: black !important; + text-decoration: none !important; +} + +.menu-href:hover, .menu-href:active { + text-decoration: underline !important; +} + +.menu-href img { + padding: 2px; +} + .disableFilter img { opacity: 0.2; filter: progid : DXImageTransform . Microsoft . Alpha(opacity = 20); @@ -509,4 +524,4 @@ img.z-group-img-close { background-position: center center; background-color: transparent; background-repeat: no-repeat; -} \ No newline at end of file +}