IDEMPIERE-231 Zk6: Improve the tablet experience. Fixed compatibility with Chrome for Android ( Tested on Nexus 7 4.2.2 with Chrome 25 ). Added swipe gesture support - swipe left to hide the left desktop column, swipe right to hide the right desktop column ( tooltips ), swipe down to hide the detail tabs and swipe left/right on the tab header to close a tab. Hide the login info for mobile devices.
This commit is contained in:
parent
e0279e57d4
commit
ad42f1bf83
|
@ -449,14 +449,8 @@ public class AdempiereWebUI extends Window implements EventListener<Event>, IWeb
|
|||
appDesktop.setClientInfo(clientInfo);
|
||||
String ua = Servlets.getUserAgent((ServletRequest) Executions.getCurrent().getNativeRequest());
|
||||
clientInfo.userAgent = ua;
|
||||
if (Servlets.getBrowser(ua).equals("webkit")) {
|
||||
ua = ua.toLowerCase();
|
||||
if (ua.indexOf("ipad") >= 0) {
|
||||
clientInfo.tablet = true;
|
||||
} else if (ua.indexOf("android") >= 0 && ua.indexOf("chrome") >= 0 && ua.indexOf("mobile") < 0) {
|
||||
clientInfo.tablet = true;
|
||||
}
|
||||
}
|
||||
ua = ua.toLowerCase();
|
||||
clientInfo.tablet = ua.indexOf("ipad") >= 0 || ua.indexOf("iphone") >= 0 || ua.indexOf("android") >= 0;
|
||||
if (getDesktop() != null && getDesktop().getSession() != null) {
|
||||
getDesktop().getSession().setAttribute(CLIENT_INFO, clientInfo);
|
||||
}
|
||||
|
|
|
@ -17,11 +17,14 @@ package org.adempiere.webui;
|
|||
import java.util.Locale;
|
||||
import java.util.Properties;
|
||||
|
||||
import javax.servlet.ServletRequest;
|
||||
|
||||
import org.adempiere.webui.apps.AEnv;
|
||||
import org.adempiere.webui.part.AbstractUIPart;
|
||||
import org.adempiere.webui.theme.ITheme;
|
||||
import org.adempiere.webui.theme.ThemeManager;
|
||||
import org.adempiere.webui.window.LoginWindow;
|
||||
import org.zkoss.web.servlet.Servlets;
|
||||
import org.zkoss.zhtml.Text;
|
||||
import org.zkoss.zk.ui.Component;
|
||||
import org.zkoss.zk.ui.Executions;
|
||||
|
@ -123,6 +126,13 @@ public class WLogin extends AbstractUIPart
|
|||
West west = new West();
|
||||
west.setSclass(ITheme.LOGIN_WEST_PANEL_CLASS);
|
||||
addContent(west, pageDefintion);
|
||||
String ua = Servlets.getUserAgent((ServletRequest) Executions.getCurrent().getNativeRequest());
|
||||
ua = ua.toLowerCase();
|
||||
boolean mobile = ua.indexOf("ipad") >= 0 || ua.indexOf("iphone") >= 0 || ua.indexOf("android") >= 0;
|
||||
if (mobile) {
|
||||
west.setCollapsible(true);
|
||||
west.setOpen(false);
|
||||
}
|
||||
} catch (Exception e){
|
||||
//ignore page not found exception
|
||||
if (e instanceof UiException) {
|
||||
|
|
|
@ -83,6 +83,7 @@ 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.event.OpenEvent;
|
||||
import org.zkoss.zk.ui.event.SwipeEvent;
|
||||
import org.zkoss.zk.ui.util.Clients;
|
||||
import org.zkoss.zul.Button;
|
||||
import org.zkoss.zul.Cell;
|
||||
|
@ -186,6 +187,14 @@ DataStatusListener, IADTabpanel, IdSpace
|
|||
|
||||
public static final String ON_TOGGLE_EVENT = "onToggle";
|
||||
|
||||
private static enum SouthEvent {
|
||||
SLIDE(),
|
||||
OPEN(),
|
||||
CLOSE();
|
||||
|
||||
private SouthEvent() {}
|
||||
}
|
||||
|
||||
public ADTabpanel()
|
||||
{
|
||||
init();
|
||||
|
@ -238,6 +247,21 @@ DataStatusListener, IADTabpanel, IdSpace
|
|||
"var se = new zk.Event(this, 'onSlide', null, {toServer: true}); zAu.send(se); } }");
|
||||
south.addEventListener(Events.ON_OPEN, this);
|
||||
south.addEventListener("onSlide", this);
|
||||
|
||||
south.addEventListener(Events.ON_SWIPE, new EventListener<SwipeEvent>() {
|
||||
|
||||
@Override
|
||||
public void onEvent(SwipeEvent event) throws Exception {
|
||||
if ("down".equals(event.getSwipeDirection())) {
|
||||
Borderlayout borderLayout = (Borderlayout) formContainer;
|
||||
South south = borderLayout.getSouth();
|
||||
if (south.isOpen()) {
|
||||
south.setOpen(false);
|
||||
onSouthEvent(SouthEvent.CLOSE);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
south.appendChild(component);
|
||||
|
||||
|
@ -973,23 +997,11 @@ DataStatusListener, IADTabpanel, IdSpace
|
|||
if (detailPane != null) {
|
||||
boolean openEvent = event instanceof OpenEvent;
|
||||
if (openEvent) {
|
||||
Events.echoEvent(ON_SAVE_OPEN_PREFERENCE_EVENT, this, ((OpenEvent)event).isOpen());
|
||||
if (!((OpenEvent)event).isOpen()) {
|
||||
return;
|
||||
}
|
||||
OpenEvent oe = (OpenEvent)event;
|
||||
onSouthEvent(oe.isOpen() ? SouthEvent.OPEN : SouthEvent.CLOSE);
|
||||
} else {
|
||||
onSouthEvent(SouthEvent.SLIDE);
|
||||
}
|
||||
if (detailPane.getParent() == null) {
|
||||
formContainer.appendSouth(detailPane);
|
||||
}
|
||||
IADTabpanel tabPanel = detailPane.getSelectedADTabpanel();
|
||||
if (tabPanel != null) {
|
||||
if (!tabPanel.isActivated()) {
|
||||
tabPanel.activate(true);
|
||||
}
|
||||
if (!tabPanel.isGridView()) {
|
||||
tabPanel.switchRowPresentation();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (event.getName().equals(ON_SAVE_OPEN_PREFERENCE_EVENT)) {
|
||||
|
@ -1037,6 +1049,28 @@ DataStatusListener, IADTabpanel, IdSpace
|
|||
}
|
||||
}
|
||||
|
||||
private void onSouthEvent(SouthEvent event) {
|
||||
if (event == SouthEvent.OPEN || event == SouthEvent.CLOSE) {
|
||||
boolean open = event == SouthEvent.OPEN ? true : false;
|
||||
Events.echoEvent(ON_SAVE_OPEN_PREFERENCE_EVENT, this, open);
|
||||
if (!open)
|
||||
return;
|
||||
}
|
||||
|
||||
if (detailPane.getParent() == null) {
|
||||
formContainer.appendSouth(detailPane);
|
||||
}
|
||||
IADTabpanel tabPanel = detailPane.getSelectedADTabpanel();
|
||||
if (tabPanel != null) {
|
||||
if (!tabPanel.isActivated()) {
|
||||
tabPanel.activate(true);
|
||||
}
|
||||
if (!tabPanel.isGridView()) {
|
||||
tabPanel.switchRowPresentation();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isOpenDetailPane() {
|
||||
boolean open = true;
|
||||
int windowId = getGridTab().getAD_Window_ID();
|
||||
|
|
|
@ -374,9 +374,14 @@ public class GridView extends Vbox implements EventListener<Event>, IdSpace
|
|||
|
||||
Columns columns = new Columns();
|
||||
|
||||
Frozen frozen = new Frozen();
|
||||
frozen.setColumns(1);
|
||||
listbox.appendChild(frozen);
|
||||
//frozen not working well on tablet devices yet
|
||||
if (!AEnv.isTablet())
|
||||
{
|
||||
Frozen frozen = new Frozen();
|
||||
frozen.setColumns(1);
|
||||
listbox.appendChild(frozen);
|
||||
}
|
||||
|
||||
org.zkoss.zul.Column indicator = new Column();
|
||||
indicator.setWidth("18px");
|
||||
try {
|
||||
|
|
|
@ -73,6 +73,7 @@ import org.zkoss.zk.ui.event.EventQueue;
|
|||
import org.zkoss.zk.ui.event.EventQueues;
|
||||
import org.zkoss.zk.ui.event.Events;
|
||||
import org.zkoss.zk.ui.event.OpenEvent;
|
||||
import org.zkoss.zk.ui.event.SwipeEvent;
|
||||
import org.zkoss.zk.ui.util.Clients;
|
||||
import org.zkoss.zk.ui.util.DesktopCleanup;
|
||||
import org.zkoss.zul.Borderlayout;
|
||||
|
@ -177,9 +178,20 @@ public class DefaultDesktop extends TabbedDesktop implements MenuListener, Seria
|
|||
@Override
|
||||
public void onEvent(Event event) throws Exception {
|
||||
OpenEvent oe = (OpenEvent) event;
|
||||
UserPreference pref = SessionManager.getSessionApplication().getUserPreference();
|
||||
pref.setProperty(UserPreference.P_MENU_COLLAPSED, !oe.isOpen());
|
||||
pref.savePreference();
|
||||
updateMenuCollapsedPreference(!oe.isOpen());
|
||||
}
|
||||
});
|
||||
w.addEventListener(Events.ON_SWIPE, new EventListener<SwipeEvent>() {
|
||||
|
||||
@Override
|
||||
public void onEvent(SwipeEvent event) throws Exception {
|
||||
if ("left".equals(event.getSwipeDirection())) {
|
||||
West w = (West) event.getTarget();
|
||||
if (w.isOpen()) {
|
||||
w.setOpen(false);
|
||||
updateMenuCollapsedPreference(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
UserPreference pref = SessionManager.getSessionApplication().getUserPreference();
|
||||
|
@ -199,11 +211,24 @@ public class DefaultDesktop extends TabbedDesktop implements MenuListener, Seria
|
|||
@Override
|
||||
public void onEvent(Event event) throws Exception {
|
||||
OpenEvent oe = (OpenEvent) event;
|
||||
UserPreference pref = SessionManager.getSessionApplication().getUserPreference();
|
||||
pref.setProperty(UserPreference.P_HELP_COLLAPSED, !oe.isOpen());
|
||||
pref.savePreference();
|
||||
updateHelpCollapsedPreference(!oe.isOpen());
|
||||
}
|
||||
});
|
||||
|
||||
e.addEventListener(Events.ON_SWIPE, new EventListener<SwipeEvent>() {
|
||||
|
||||
@Override
|
||||
public void onEvent(SwipeEvent event) throws Exception {
|
||||
if ("right".equals(event.getSwipeDirection())) {
|
||||
East e = (East) event.getTarget();
|
||||
if (e.isOpen()) {
|
||||
e.setOpen(false);
|
||||
updateHelpCollapsedPreference(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
boolean helpCollapsed= pref.isPropertyBool(UserPreference.P_HELP_COLLAPSED);
|
||||
e.setOpen(!helpCollapsed);
|
||||
|
||||
|
@ -258,6 +283,18 @@ public class DefaultDesktop extends TabbedDesktop implements MenuListener, Seria
|
|||
return layout;
|
||||
}
|
||||
|
||||
private void updateMenuCollapsedPreference(boolean collapsed) {
|
||||
UserPreference pref = SessionManager.getSessionApplication().getUserPreference();
|
||||
pref.setProperty(UserPreference.P_MENU_COLLAPSED, collapsed);
|
||||
pref.savePreference();
|
||||
}
|
||||
|
||||
private void updateHelpCollapsedPreference(boolean collapsed) {
|
||||
UserPreference pref = SessionManager.getSessionApplication().getUserPreference();
|
||||
pref.setProperty(UserPreference.P_HELP_COLLAPSED, collapsed);
|
||||
pref.savePreference();
|
||||
}
|
||||
|
||||
private void renderHomeTab()
|
||||
{
|
||||
homeTab.getChildren().clear();
|
||||
|
|
|
@ -39,6 +39,7 @@ import org.compiere.util.Util;
|
|||
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.event.SwipeEvent;
|
||||
import org.zkoss.zul.Center;
|
||||
import org.zkoss.zul.South;
|
||||
|
||||
|
@ -302,6 +303,15 @@ public class InfoProductWindow extends InfoWindow {
|
|||
south.setSplittable(true);
|
||||
south.setTitle(Msg.translate(Env.getCtx(), "WarehouseStock"));
|
||||
south.setTooltiptext(Msg.translate(Env.getCtx(), "WarehouseStock"));
|
||||
south.addEventListener(Events.ON_SWIPE, new EventListener<SwipeEvent>() {
|
||||
@Override
|
||||
public void onEvent(SwipeEvent event) throws Exception {
|
||||
South south = (South) event.getTarget();
|
||||
if ("down".equals(event.getSwipeDirection())) {
|
||||
south.setOpen(false);
|
||||
}
|
||||
}
|
||||
});
|
||||
contentBorderLayout.appendChild(south);
|
||||
tabbedPane.setSclass("info-product-tabbedpane");
|
||||
south.appendChild(tabbedPane);
|
||||
|
|
|
@ -29,6 +29,7 @@ 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.event.SwipeEvent;
|
||||
import org.zkoss.zul.Anchorlayout;
|
||||
import org.zkoss.zul.Vlayout;
|
||||
|
||||
|
@ -127,6 +128,17 @@ public class WindowContainer extends AbstractUIPart
|
|||
setTabTitle(title, tab);
|
||||
}
|
||||
tab.setClosable(closeable);
|
||||
tab.addEventListener(Events.ON_SWIPE, new EventListener<SwipeEvent>() {
|
||||
|
||||
@Override
|
||||
public void onEvent(SwipeEvent event) throws Exception {
|
||||
Tab tab = (Tab) event.getTarget();
|
||||
if (tab.isClosable()
|
||||
&& ("right".equals(event.getSwipeDirection()) || "left".equals(event.getSwipeDirection()))) {
|
||||
tab.onClose();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// fix scroll position lost coming back into a grid view tab
|
||||
tab.addEventListener(Events.ON_SELECT, new EventListener<Event>() {
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
<div class="tabs arrows" xmlns:w="client" forward="onMoveDate(${arg.type})"
|
||||
w:unbind_="function(){this.$unbind_();jq(this).unbind('mouseover').unbind('mouseout');}">
|
||||
w:unbind_="function(skipper, after){this.$unbind_(skipper, after);jq(this).unbind('mouseover').unbind('mouseout');}">
|
||||
<attribute w:name="bind_"><![CDATA[
|
||||
function () {
|
||||
this.$bind_();
|
||||
function (desktop, skipper, after) {
|
||||
this.$bind_(desktop, skipper, after);
|
||||
jq(this).bind('mouseover',function(evt){jq(evt.currentTarget).addClass('arrow-over');})
|
||||
.bind('mouseout',function(evt){jq(evt.currentTarget).removeClass('arrow-over');});
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue