de.swm.commons.mobile.client.orientation.OrientationController Maven / Gradle / Ivy
/*
* Copyright 2011 SWM Services GmbH.
*
* 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 de.swm.commons.mobile.client.orientation;
import com.google.gwt.core.client.GWT;
import com.google.gwt.core.client.JavaScriptObject;
import com.google.gwt.event.logical.shared.CloseEvent;
import com.google.gwt.event.logical.shared.CloseHandler;
import com.google.gwt.event.logical.shared.ResizeEvent;
import com.google.gwt.event.logical.shared.ResizeHandler;
import com.google.gwt.event.shared.EventBus;
import com.google.gwt.event.shared.HandlerRegistration;
import com.google.gwt.event.shared.SimpleEventBus;
import com.google.gwt.user.client.Window;
import de.swm.commons.mobile.client.SWMMobile;
import java.util.logging.Logger;
/**
* Controller that supports orientation changes.
*
*/
public class OrientationController {
private static final Logger LOGGER = Logger.getLogger(OrientationChangeHandler.class.getName());
private static final int DEGREES_90 = 90;
private static final int DEGREES_180 = 180;
private static Orientation currentOrientation;
private static JavaScriptObject nativeJsFunction;
private static final EventBus MANAGER = new SimpleEventBus();
static {
if (GWT.isClient()) {
setupOrientation();
}
}
/**
* Add a orientation handler to detect the device orientation
*
* @param handler
* the handler to add {@link OrientationChangeHandler} .
* @return a {@link com.google.gwt.event.shared.HandlerRegistration} object.
*/
public static HandlerRegistration addOrientationChangeHandler(OrientationChangeHandler handler) {
return MANAGER.addHandler(OrientationChangeEvent.getType(), handler);
}
/**
* Get the current orientation of the device
*
* @return the current orientation of the device
*/
public static Orientation getOrientation() {
if (!orientationSupport()) {
int height = Window.getClientHeight();
int width = Window.getClientWidth();
if (width > height) {
return Orientation.LANDSCAPE;
} else {
return Orientation.PORTRAIT;
}
} else {
int orientation = testBrowserOrientationSupport();
Orientation o;
switch (orientation) {
case 0:
case DEGREES_180:
o = Orientation.PORTRAIT;
break;
case DEGREES_90:
case -DEGREES_90:
o = Orientation.LANDSCAPE;
break;
default:
throw new IllegalStateException("this should not happen!?");
}
return o;
}
}
/**
* Fires an orientation change event to the event bus.
*
* @param orientation
* the orientation
*/
private static void fireOrientationChangedEvent(Orientation orientation) {
MANAGER.fireEvent(new OrientationChangeEvent(orientation));
}
/**
* Will test if the browser supports orientation events natively.
*
* @return true is supported.
*/
private static native int testBrowserOrientationSupport()/*-{
if (typeof ($wnd.orientation) == 'undefined') {
return 0;
}
return $wnd.orientation;
}-*/;
/**
* Will be called when the orientation will change.
*
* @param orientation
* orientation value in degrees
*/
private static void onorientationChange(int orientation) {
Orientation o;
switch (orientation) {
case 0:
case DEGREES_180:
o = Orientation.PORTRAIT;
break;
case DEGREES_90:
case -DEGREES_90:
o = Orientation.LANDSCAPE;
break;
default:
LOGGER.info("on orientation changed called with invalid value: '" + orientation
+ "' - defaulting to Portrait");
o = Orientation.PORTRAIT;
break;
}
currentOrientation = o;
fireOrientationChangedEvent(o);
}
/**
* Determine if the device provides Orientation support
*
* @return true if provided.
*/
private static boolean orientationSupport() {
return SWMMobile.getOsDetection().isIPad() || SWMMobile.getOsDetection().isIPhone();
}
/**
* Set up orientation support.
*/
private static void setupOrientation() {
if (!orientationSupport()) {
Window.addResizeHandler(new ResizeHandler() {
@Override
public void onResize(ResizeEvent event) {
Orientation orientation = getOrientation();
if (orientation != currentOrientation) {
currentOrientation = orientation;
fireOrientationChangedEvent(orientation);
}
}
});
} else {
nativeJsFunction = setupBrowserNativeOrientationSupport();
Window.addCloseHandler(new CloseHandler() {
@Override
public void onClose(CloseEvent event) {
destroyOrientation(nativeJsFunction);
}
});
}
}
/**
* Will register an orientation change handler to support native browser orientation cahnge event.
*
* @return true if supported
*/
private static native JavaScriptObject setupBrowserNativeOrientationSupport()/*-{
var func = $entry(function() {
@de.swm.commons.mobile.client.orientation.OrientationController::onorientationChange(I)($wnd.orientation);
});
$doc.body.onorientationchange = func;
$doc.addEventListener("orientationChanged", func);
return func;
}-*/;
/**
* Unregister all orientation change events.
*
* @param o
* the js-event handler.
*/
private static native void destroyOrientation(JavaScriptObject o)/*-{
$doc.body.onorientationchange = null;
$doc.removeEventListener("orientationChanged", o);
}-*/;
}