/* * Copyright 2011 cruxframework.org. * * Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy of * the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. */ package org.cruxframework.crux.core.client.screen; import java.util.logging.Logger; import org.cruxframework.crux.core.client.Legacy; import org.cruxframework.crux.core.client.collection.FastList; import org.cruxframework.crux.core.client.controller.RegisteredControllers; import org.cruxframework.crux.core.client.datasource.DataSource; import org.cruxframework.crux.core.client.formatter.RegisteredClientFormatters; import org.cruxframework.crux.core.client.screen.DeviceAdaptive.Device; import org.cruxframework.crux.core.client.screen.views.OrientationChangeHandler; import org.cruxframework.crux.core.client.screen.views.View; import org.cruxframework.crux.core.client.screen.widgets.ScreenBlocker; import org.cruxframework.crux.core.client.utils.StringUtils; import com.google.gwt.core.client.GWT; import com.google.gwt.core.client.Scheduler; import com.google.gwt.core.client.Scheduler.ScheduledCommand; import com.google.gwt.dom.client.Element; import com.google.gwt.dom.client.NativeEvent; import com.google.gwt.event.logical.shared.CloseHandler; import com.google.gwt.event.logical.shared.ResizeHandler; import com.google.gwt.event.logical.shared.ValueChangeHandler; import com.google.gwt.event.shared.HandlerRegistration; import com.google.gwt.i18n.client.LocaleInfo; import com.google.gwt.user.client.DOM; import com.google.gwt.user.client.Event.NativePreviewEvent; import com.google.gwt.user.client.Event.NativePreviewHandler; import com.google.gwt.user.client.History; import com.google.gwt.user.client.Window; import com.google.gwt.user.client.Window.ClosingHandler; import com.google.gwt.user.client.ui.IsWidget; import com.google.gwt.user.client.ui.RootPanel; import com.google.gwt.user.client.ui.Widget; /** * Abstraction for the entire page. It references the root view and declare methods to * act on the entire application page. * @author Thiago da Rosa de Bustamante * */ public class Screen { private static final String CRUX_VIEW_TEST_PAGE = "__CRUX_VIEW_TEST_PAGE__"; private static Logger logger = Logger.getLogger(Screen.class.getName()); protected RootViewContainer rootViewContainer = null; protected FastList<Element> blockingDivs = new FastList<Element>(); protected String id; private static HandlerRegistration refreshPreviewHandler; protected Screen(final String id, String rootViewElementID) { this.id = id; rootViewContainer = new RootViewContainer(rootViewElementID); createRootView(id); } /** * * @param id */ protected void createRootView(String id) { if (!GWT.isScript()) { if (id.endsWith("/"+CRUX_VIEW_TEST_PAGE)) { id = Window.Location.getParameter("viewName"); assert(id != null) : "To use viewTester, your must inform the viewName parameter."; } } final String viewId = id; Scheduler.get().scheduleDeferred(new ScheduledCommand() { @Override public void execute() { rootViewContainer.loadView(viewId, true); } }); } /** * * @param token */ protected void addTokenToHistory(String token) { View.addToHistory(token); } /** * * @param token * @param issueEvent */ protected void addTokenToHistory(String token, boolean issueEvent) { View.addToHistory(token, issueEvent); } /** * * @param id * @param widget */ protected void addWidget(String id, Widget widget) { getView().addWidget(id, widget); } /** * * @return */ protected View getView() { return rootViewContainer.getView(); } /** * * @param id * @param widget */ protected void addWidget(String id, IsWidget widget) { getView().addWidget(id, widget.asWidget()); } /** * * @param handler * @return */ protected HandlerRegistration addWindowCloseHandler(CloseHandler<Window> handler) { return getView().addWindowCloseHandler(handler); } /** * * @param handler * @return */ protected HandlerRegistration addWindowClosingHandler(ClosingHandler handler) { return getView().addWindowClosingHandler(handler); } /** * * @param handler * @return */ protected HandlerRegistration addWindowHistoryChangedHandler(ValueChangeHandler<String> handler) { return getView().addWindowHistoryChangedHandler(handler); } /** * * @param handler * @return */ protected HandlerRegistration addWindowResizeHandler(ResizeHandler handler) { return getView().addResizeHandler(handler); } /** * * * @param handler * @return */ protected HandlerRegistration addWindowOrientationChangeHandler(OrientationChangeHandler handler) { return getView().addWindowOrientationChangeHandler(handler); } /** * * @return */ protected String getCurrentHistoryToken() { return History.getToken(); } /** * @return */ protected String getIdentifier() { return id; } /** * Retrieve a widget contained on this screen. * * @param id * @return */ protected Widget getWidget(String id) { return getView().getWidget(id); } /** * Generic version of <code>getWidget</code> method * @param <T> * @param id * @param clazz * @return */ @SuppressWarnings("unchecked") protected <T extends IsWidget> T getWidget(String id, Class<T> clazz) { Widget w = getWidget(id); return (T) w; } /** * Hides the DIV that is blocking the Screen contents */ protected void hideBlockDiv() { if(blockingDivs.size() > 0) { int last = blockingDivs.size() - 1; Element blockingDiv = blockingDivs.get(last); blockingDivs.remove(last); Element body = RootPanel.getBodyElement(); body.removeChild(blockingDiv); body.getStyle().setProperty("cursor", ""); } if(blockingDivs.size() > 0) { Element blockingDiv = blockingDivs.get(blockingDivs.size() - 1); blockingDiv.getStyle().setProperty("display", "block"); } } protected void removeWidget(String id) { getView().removeWidget(id); } protected void removeWidget(String id, boolean removeFromDOM) { getView().removeWidget(id, removeFromDOM); } protected boolean containsWidget(String id) { return getView().containsWidget(id); } /** * Creates and shows a DIV over the screen contents * @param blockingDivStyleName */ protected void showBlockDiv(String blockingDivStyleName) { if(blockingDivs.size() > 0) { Element blockingDiv = blockingDivs.get(blockingDivs.size() - 1); blockingDiv.getStyle().setProperty("display", "none"); } Element body = RootPanel.getBodyElement(); ScreenBlocker screenBlocker = new ScreenBlocker(blockingDivStyleName); blockingDivs.add(screenBlocker.getElement()); body.appendChild(screenBlocker.getElement()); } /** * @return */ protected FastList<String> widgetsIdList() { return getView().widgetsIdList(); } /** * @return */ protected FastList<Widget> widgetsList() { return getView().widgetsList(); } /** * * @return */ public static View getRootView() { return Screen.get().getView(); } /** * * @param id * @param widget */ public static void add(String id, Widget widget) { Screen.get().addWidget(id, widget); } /** * * @param id * @param widget */ public static void add(String id, IsWidget widget) { Screen.get().addWidget(id, widget); } /** * * @param handler * @return */ public static HandlerRegistration addCloseHandler(CloseHandler<Window> handler) { Screen screen = Screen.get(); return screen != null ? screen.addWindowCloseHandler(handler) : null; } /** * * @param handler * @return */ public static HandlerRegistration addClosingHandler(ClosingHandler handler) { Screen screen = Screen.get(); return screen != null ? screen.addWindowClosingHandler(handler) : null; } /** * * @param handler * @return */ public static HandlerRegistration addHistoryChangedHandler(ValueChangeHandler<String> handler) { Screen screen = Screen.get(); return screen != null ? screen.addWindowHistoryChangedHandler(handler) : null; } /** * * @param handler * @return */ public static HandlerRegistration addResizeHandler(ResizeHandler handler) { Screen screen = Screen.get(); return screen != null ? screen.addWindowResizeHandler(handler) : null; } /** * * @param handler * @return */ public static HandlerRegistration addOrientationChangeHandler(final OrientationChangeHandler handler) { Screen screen = Screen.get(); return screen != null ? screen.addWindowOrientationChangeHandler(handler) : null; } /** * * @param token */ public static void addToHistory(String token) { Screen.get().addTokenToHistory(token); } /** * * @param token * @param issueEvent */ public static void addToHistory(String token, boolean issueEvent) { Screen.get().addTokenToHistory(token, issueEvent); } /** * * @param url * @return */ @Deprecated @Legacy public static String rewriteUrl(String url) { return url; } /** * */ public static void blockToUser() { Screen.get().showBlockDiv("crux-DefaultScreenBlocker"); } /** * */ public static void blockToUser(String blockingDivStyleName) { Screen.get().showBlockDiv(blockingDivStyleName); } /** * @param id * @return */ public static boolean contains(String id) { return Screen.get().containsWidget(id); } /** * * @param dataSource * @return */ public static DataSource<?> createDataSource(String dataSource) { return get().rootViewContainer.getView().createDataSource(dataSource); } /** * * @return */ public RegisteredControllers getRegisteredControllers() { return getView().getRegisteredControllers(); } /** * * @return */ @Deprecated @Legacy public RegisteredClientFormatters getRegisteredFormatters() { return getView().getRegisteredFormatters(); } /** * If the given widget does not have a non-empty ID attribute, sets the given id into it. * @param widget * @param id */ public static void ensureDebugId(Widget widget, String id) { if(widget != null) { if(StringUtils.isEmpty(widget.getElement().getId())) { id = id.replaceAll("[^a-zA-Z0-9\\$]", "_"); id = id.length() > 100 ? id.substring(0, 100) : id; if(!id.startsWith("_")) { id = "_" + id; } id = id.toLowerCase(); id = ensureUniqueId(id); widget.getElement().setId(id); } } } /** * Ensures that the given id is not being used in the current document. If this is not the case, returns an unique id. * @param id * @return */ private static String ensureUniqueId(String id) { Object exists = DOM.getElementById(id); int i = 0; while(exists != null) { exists = DOM.getElementById(id + "_" + (++i)); } if(i > 0) { id = id + "_" + i; } return id; } /** * Gets the current screen * @return */ public static Screen get() { return ScreenFactory.getInstance().getScreen(); } /** * Gets a widget on the current screen * @param id * @return */ public static Widget get(String id) { return Screen.get().getWidget(id); } /** * * @param <T> * @param id * @param clazz * @return */ public static <T extends IsWidget> T get(String id, Class<T> clazz) { return Screen.get().getWidget(id, clazz); } /** * * @return */ public static String getCurrentHistoryItem() { return Screen.get().getCurrentHistoryToken(); } /** * * @return */ public static Device getCurrentDevice() { return ScreenFactory.getInstance().getCurrentDevice(); } /** * * @return */ public static String getId() { return Screen.get().getIdentifier(); } /** * * @return the locale specified or null */ public static String getLocale() { String locale = LocaleInfo.getCurrentLocale().getLocaleName(); if ("".equals(locale)) { locale = null; } return locale; } /** * Configure a viewport using given contents for small and large displays * @param smallDisplayContent * @param largeDisplayContent */ public static void configureViewport(String smallDisplayContent, String largeDisplayContent) { DisplayHandler.configureViewport(smallDisplayContent, largeDisplayContent); } /** * Configure a viewport using given content * @param content */ public static void configureViewport(String content) { DisplayHandler.configureViewport(content); } /** * @return */ public static FastList<String> listWidgetIds() { return Screen.get().widgetsIdList(); } /** * @return */ public static FastList<Widget> listWidgets() { return Screen.get().widgetsList(); } /** * Remove a widget on the current screen * @param id */ public static void remove(String id) { Screen.get().removeWidget(id); } /** * Remove a widget on the current screen * @param id * @param removeFromDOM */ public static void remove(String id, boolean removeFromDOM) { Screen.get().removeWidget(id, removeFromDOM); } /** * */ public static void unblockToUser() { Screen.get().hideBlockDiv(); } /** * * @return */ public static boolean isWindowsPhone() { String userAgent = Window.Navigator.getUserAgent().toLowerCase(); return (userAgent.indexOf("windows phone") > 0); } /** * * @return */ public static boolean isIos() { String userAgent = Window.Navigator.getUserAgent().toLowerCase(); return (userAgent.indexOf("iphone") > 0 || userAgent.indexOf("ipod") > 0 || userAgent.indexOf("ipad") > 0); } /** * * @return */ public static boolean isIPad() { String userAgent = Window.Navigator.getUserAgent().toLowerCase(); return (userAgent.indexOf("ipad") > 0); } /** * * @return */ public static boolean isAndroid() { String userAgent = Window.Navigator.getUserAgent().toLowerCase(); return (userAgent.indexOf("android") > 0); } public static native void reload() /*-{ $wnd.top.location.reload(); }-*/; /** * Enable or disable the browser refresh support. * @param enabled */ public static void setRefreshEnabled(boolean enabled) { if (enabled) { if (refreshPreviewHandler != null) { refreshPreviewHandler.removeHandler(); refreshPreviewHandler = null; } } else { disableRefresh(); } } private static void disableRefresh() { if (refreshPreviewHandler == null) { refreshPreviewHandler = com.google.gwt.user.client.Event.addNativePreviewHandler(new NativePreviewHandler(){ public void onPreviewNativeEvent(NativePreviewEvent event) { if (event.getTypeInt() == com.google.gwt.user.client.Event.ONKEYDOWN) { NativeEvent nEvent = event.getNativeEvent(); if (nEvent.getCtrlKey() && nEvent.getKeyCode() == 'R') { nEvent.preventDefault(); } if (nEvent.getKeyCode() == 116)//F5 { nEvent.preventDefault(); } } } }); } } }