/** * Copyright 2014-2017 Riccardo Massera (TheCoder4.Eu) and Stephan Rauh (http://www.beyondjava.net). * * This file is part of BootsFaces. * * 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 net.bootsfaces.component.gyroscope; import java.io.IOException; import javax.el.ELException; import javax.el.ValueExpression; import javax.faces.component.UIComponent; import javax.faces.context.FacesContext; import javax.faces.context.ResponseWriter; import javax.faces.render.FacesRenderer; import net.bootsfaces.component.ajax.AJAXRenderer; import net.bootsfaces.render.CoreRenderer; import net.bootsfaces.utils.FacesMessages; /** This class generates the HTML code of <b:gyroscope />. */ @FacesRenderer(componentFamily = "net.bootsfaces.component", rendererType = "net.bootsfaces.component.gyroscope.Gyroscope") public class GyroscopeRenderer extends CoreRenderer { /** * This methods receives and processes input made by the user. More specifically, it ckecks whether the * user has interacted with the current b:gyroscope. The default implementation simply stores * the input value in the list of submitted values. If the validation checks are passed, * the values in the <code>submittedValues</code> list are store in the backend bean. * @param context the FacesContext. * @param component the current b:gyroscope. */ @Override public void decode(FacesContext context, UIComponent component) { Gyroscope gyroscope = (Gyroscope) component; if (gyroscope.isDisabled()) { return; } decodeBehaviors(context, gyroscope); String clientId = gyroscope.getClientId(context); // String submittedAlpha = (String) context.getExternalContext().getRequestParameterMap().get(clientId+".alpha"); // String submittedBeta = (String) context.getExternalContext().getRequestParameterMap().get(clientId+".beta"); // String submittedGamma = (String) context.getExternalContext().getRequestParameterMap().get(clientId+".gamma"); new AJAXRenderer().decode(context, component, clientId); } public void processUpdates(FacesContext context, UIComponent component) { if (context == null) { throw new NullPointerException(); } Gyroscope gyro = (Gyroscope)component; if (!gyro.isRendered()) { return; } if (gyro.isDisabled()) { return; } String clientId = component.getClientId(context); String submittedAlpha = (String) context.getExternalContext().getRequestParameterMap().get(clientId + ".alpha"); String submittedBeta = (String) context.getExternalContext().getRequestParameterMap().get(clientId + ".beta"); String submittedGamma = (String) context.getExternalContext().getRequestParameterMap().get(clientId + ".gamma"); // System.out.println(submittedAlpha + ", " + submittedBeta + ", " + submittedGamma); if (inputIsValid(submittedAlpha) && inputIsValid(submittedBeta) && inputIsValid(submittedGamma)) { ValueExpression ve = component.getValueExpression("alpha"); if (ve != null) { try { ve.setValue(context.getELContext(), submittedAlpha); } catch (ELException e) { FacesMessages.error("Couldn't populate the alpha value"); } catch (Exception e) { FacesMessages.error("Couldn't populate the alpha value"); } } ve = component.getValueExpression("beta"); if (ve != null) { try { ve.setValue(context.getELContext(), submittedBeta); } catch (ELException e) { FacesMessages.error("Couldn't populate the beta value"); } catch (Exception e) { FacesMessages.error("Couldn't populate the beta value"); } } ve = component.getValueExpression("gamma"); if (ve != null) { try { ve.setValue(context.getELContext(), submittedGamma); } catch (ELException e) { FacesMessages.error("Couldn't populate the gamma value"); } catch (Exception e) { FacesMessages.error("Couldn't populate the gamma value"); } } } } private boolean inputIsValid(String submittedBeta) { if (submittedBeta.length()>4) return false; for (int i = 0; i < submittedBeta.length(); i++) { if (!Character.isDigit(submittedBeta.charAt(i))) { if (submittedBeta.charAt(i)!='-') return false; } } return true; } /** * This methods generates the HTML code of the current b:gyroscope. * @param context the FacesContext. * @param component the current b:gyroscope. * @throws IOException thrown if something goes wrong when writing the HTML code. */ @Override public void encodeBegin(FacesContext context, UIComponent component) throws IOException { if (!component.isRendered()) { return; } Gyroscope gyroscope = (Gyroscope) component; ResponseWriter rw = context.getResponseWriter(); String clientId = gyroscope.getClientId(); rw.startElement("input", component); rw.writeAttribute("id", clientId + ".alpha", null); rw.writeAttribute("name", clientId + ".alpha", null); rw.writeAttribute("type", "hidden", null); rw.endElement("input"); rw.startElement("input", component); rw.writeAttribute("id", clientId + ".beta", null); rw.writeAttribute("name", clientId + ".beta", null); rw.writeAttribute("type", "hidden", null); rw.endElement("input"); rw.startElement("input", component); rw.writeAttribute("id", clientId + ".gamma", null); rw.writeAttribute("name", clientId + ".gamma", null); rw.writeAttribute("type", "hidden", null); rw.endElement("input"); rw.startElement("input", component); rw.writeAttribute("id", clientId + ".timer", null); rw.writeAttribute("name", clientId + ".timer", null); rw.writeAttribute("value", "0", null); rw.writeAttribute("type", "hidden", null); rw.endElement("input"); rw.startElement("script", component); rw.writeAttribute("id", clientId, null); StringBuilder jsCode = new StringBuilder(); // Render Ajax Capabilities AJAXRenderer.generateAJAXCallForASingleEvent( FacesContext.getCurrentInstance(), gyroscope, rw, null, null, null, false, "rotation", jsCode, null); String js = jsCode.toString().replace("callAjax(this,", "callAjax(document.getElementById('" + clientId + ".alpha'),"); rw.write("window.addEventListener('deviceorientation', function(event) {\n"); rw.write(" var oldAlpha = document.getElementById('" + clientId + ".alpha').value;"); rw.write(" var alpha = Math.round(event.alpha);"); rw.write(" var oldBeta = document.getElementById('" + clientId + ".beta').value;"); rw.write(" var beta = Math.round(event.beta);"); rw.write(" var oldGamma = document.getElementById('" + clientId + ".gamma').value;"); rw.write(" var gamma = Math.round(event.gamma);"); rw.write(" if (alpha==oldAlpha && beta == oldBeta && gamma == oldGamma) return;"); rw.write(" if (new Date().getTime() < document.getElementById('" + clientId + ".timer').value) return;"); rw.write(" document.getElementById('" + clientId + ".alpha').value = alpha;"); rw.write(" document.getElementById('" + clientId + ".beta').value = beta;"); rw.write(" document.getElementById('" + clientId + ".gamma').value = gamma;"); rw.write(" document.getElementById('" + clientId + ".timer').value = new Date().getTime()+100;"); rw.write(js); rw.write("}, true);\n"); // rw.write("window.addEventListener('compassneedscalibration', function(event) {\n"); // rw.write(" alert('Your compass needs calibrating! Wave your device in a figure-eight motion');"); // rw.write(" event.preventDefault();"); // rw.write("}, true);\n"); rw.endElement("script"); } }