SvgCanvas2.java

/**
 * Copyright (c) 2012 Nokia Corporation. All rights reserved.
 * Nokia and Nokia Connecting People are registered trademarks of Nokia 
Corporation.
 * Oracle and Java are trademarks or registered trademarks of Oracle and/or its
 * affiliates. Other product and company names mentioned herein may be trademarks
 * or trade names of their respective owners.
 * See LICENSE.TXT for license information.
 */

package com.nokia.example;

import com.nokia.mid.ui.gestures.GestureEvent;
import com.nokia.mid.ui.gestures.GestureInteractiveZone;
import com.nokia.mid.ui.gestures.GestureListener;
import com.nokia.mid.ui.gestures.GestureRegistrationManager;
import java.io.IOException;
import java.io.InputStream;
import javax.microedition.io.Connector;
import javax.microedition.lcdui.Graphics;
import javax.microedition.lcdui.game.GameCanvas;
import javax.microedition.m2g.SVGImage;
import javax.microedition.m2g.ScalableGraphics;
import javax.microedition.sensor.*;
import org.w3c.dom.svg.SVGPoint;
import org.w3c.dom.svg.SVGSVGElement;

/**
 * Simple canvas that uses JSR-226 to render SVG content. This class implements
 * a GestureListener which notifies the MIDlet of gesture events associated with
 * the UI element. The DataListener is implemented to retrieve data from a
 * sensor
 */
public class SvgCanvas2 extends GameCanvas implements GestureListener, DataListener {

    public static final int IMAGE_ZOOM = 1;
    public static final int IMAGE_MOVE = 2;
    static final int BUFFER_SIZE = 3;
    public static SensorConnection iConnection;
    public static int iconCommandState;

    /**
     * Constructor.
     */
    public SvgCanvas2(boolean suppressKeyEvents) {
        super(suppressKeyEvents);

        // *** setup an instance of ScalableGraphics
        sg = ScalableGraphics.createInstance();
        sg.setRenderingQuality(ScalableGraphics.RENDERING_QUALITY_HIGH);

        // *** load an svg image from a file
        try {
            InputStream svgStream = getClass().getResourceAsStream("content2.svg");
            svgImage = (SVGImage) (SVGImage.createImage(svgStream, null));

            // ** set the width and height of the document to match the screen capabilities
            svgImage.setViewportWidth(getWidth());
            svgImage.setViewportHeight(getHeight());

        } catch (Exception e) {
            e.printStackTrace();
        }

        iconCommandState = IMAGE_MOVE;

        initializeGesture();

        /**
         * Open the sensor connection and set the data listener. Data listening
         * is started by calling the SensorConnection.setDataListener
		 *
         */
        iConnection = openAccelerationSensor();
        if (iConnection != null) {
            iConnection.setDataListener(this, BUFFER_SIZE);
        }
    }

    /**
     * Initializes gestures and set it to receive gesture events
     */
    public void initializeGesture() {

        /**
         * Set the listener to register events for SvgCanvas2 (this,) and
         * register the GestureListener for the UI element (,this)
         */
        GestureRegistrationManager.setListener(this, this);

        /**
         * Create an interactive zone and set it to receive taps
         */
        GestureInteractiveZone myGestureZone = new GestureInteractiveZone(GestureInteractiveZone.GESTURE_PINCH | GestureInteractiveZone.GESTURE_DRAG);

        /**
         * Set the location (relative to the container) and size of the
         * interactive zone:
         */
        myGestureZone.setRectangle(0, 0, getWidth(), getHeight());

        /**
         * Register the interactive zone for GestureCanvas (this)
         */
        GestureRegistrationManager.register(this, myGestureZone);
    }

    /**
     * Method to open the sensor connection.
     */
    private SensorConnection openAccelerationSensor() {
        SensorInfo infos[] = SensorManager.findSensors("acceleration", null);
        if (infos.length == 0) {
            return null;
        }
        try {
            return (SensorConnection) Connector.open(infos[0].getUrl());
        } catch (SecurityException se) {
            se.printStackTrace();
            return null;
        } catch (IOException ioe) {
            ioe.printStackTrace();
            System.out.println("Couldn't open sensor : "
                    + infos[0].getUrl() + "!");
            return null;
        } catch (IllegalArgumentException iae) {
            iae.printStackTrace();
            return null;

        }
    }

    /**
     * Paint method.
     */
    public void paint(Graphics g) {
        // *** clear the display
        g.setColor(255, 255, 255);
        g.fillRect(0, 0, getWidth(), getHeight());

        // *** render the SVG image
        sg.bindTarget(g);
        sg.setTransparency(1f);
        //sg.render(0, 0, svgImage);
        sg.render((getWidth() - svgImage.getViewportWidth()) >> 1, (getHeight() - svgImage.getViewportHeight()) >> 1, svgImage);
        sg.releaseTarget();

    }

    protected void sizeChanged(int w, int h) {
        svgImage.setViewportWidth(w);
        svgImage.setViewportHeight(h);
        repaint();
    }

    /**
     * Restore the original view of the SVG Image.
     */
    public void restoreView() {
        SVGSVGElement myEl = (SVGSVGElement) svgImage.getDocument().getDocumentElement();
        myEl.setCurrentRotate(0);
        myEl.setCurrentScale(1);
        SVGPoint origin = myEl.getCurrentTranslate();
        origin.setX(0);
        origin.setY(0);
        repaint();
    }

    /**
     * Zoom in on the SVG Image.
     */
    public void zoomIn() {
        SVGSVGElement myEl = (SVGSVGElement) (svgImage.getDocument().getDocumentElement());
        myEl.setCurrentScale(myEl.getCurrentScale() * 1.2f);
        repaint();
    }

    /**
     * Zoom out on the SVG Image.
     */
    public void zoomOut() {
        SVGSVGElement myEl = (SVGSVGElement) (svgImage.getDocument().getDocumentElement());
        myEl.setCurrentScale(myEl.getCurrentScale() * 0.8f);
        repaint();
    }

    public void zoom(float zoom) {
        SVGSVGElement myEl = (SVGSVGElement) (svgImage.getDocument().getDocumentElement());
        myEl.setCurrentScale(myEl.getCurrentScale() * zoom);
        repaint();
    }

    /**
     * Rotate out on the SVG Image.
     */
    public void rotateOut() {
        SVGSVGElement myEl = (SVGSVGElement) (svgImage.getDocument().getDocumentElement());
        myEl.setCurrentRotate(myEl.getCurrentRotate() + 10);
        repaint();
    }

    /**
     * Rotate in on the SVG Image.
     */
    public void rotateIn() {
        SVGSVGElement myEl = (SVGSVGElement) (svgImage.getDocument().getDocumentElement());
        myEl.setCurrentRotate(myEl.getCurrentRotate() - 10);
        repaint();
    }

    public void pointerPressed(int x, int y) {
    }

    /**
     * Key repeat method.
     */
    protected void keyRepeated(int keyCode) {
        keyPressed(keyCode);
    }

    /**
     * Handle key presses.
     */
    protected void keyPressed(int keyCode) {
        SVGSVGElement svgDoc = (SVGSVGElement) svgImage.getDocument().getDocumentElement();
        int action = getGameAction(keyCode);
        SVGPoint origin = svgDoc.getCurrentTranslate();
        switch (action) {
            case RIGHT:
                origin.setX(origin.getX() + 5f);
                break;
            case LEFT:
                origin.setX(origin.getX() - 5f);
                break;
            case UP:
                origin.setY(origin.getY() - 5f);
                break;
            case DOWN:
                origin.setY(origin.getY() + 5f);
                break;
        }
        repaint();
    }
    /*
     * Private members
     */
    private ScalableGraphics sg;
    private SVGImage svgImage;

    /**
     * Defines the gestureAction method for the class. This method is called
     * every time a gesture event occurs for a UI element that uses
     * GestureListener. The method is called with all the information related to
     * the gesture event.
     */
    public void gestureAction(Object arg0, GestureInteractiveZone arg1, GestureEvent gestureEvent) {

        switch (gestureEvent.getType()) {

            /**
             * Receives drag events and moves the image.
             */
            case GestureInteractiveZone.GESTURE_DRAG:
                if (iconCommandState == IMAGE_MOVE) {
                    SVGSVGElement svgDoc = (SVGSVGElement) svgImage.getDocument().getDocumentElement();

                    SVGPoint origin = svgDoc.getCurrentTranslate();
                    origin.setX(origin.getX() + gestureEvent.getDragDistanceX());
                    origin.setY(origin.getY() + gestureEvent.getDragDistanceY());
                    repaint();
                }

                break;

            /**
             * This gesture event is supported from Java Runtime 2.0.0 for
             * Series 40 onwards. Receives pinch events and check the pinch
             * distance change to scale the current image.
             */
            case GestureInteractiveZone.GESTURE_PINCH:

                if (iconCommandState == IMAGE_ZOOM) {
                    int distanceChange = gestureEvent.getPinchDistanceChange();
                    if (distanceChange < 0) {
                        zoomOut();
                    } else if (distanceChange > 0) {
                        zoomIn();
                    }
                    repaint();
                }

                break;
        }
    }

    /**
     * Notification of the received sensor data.
     */
    public void dataReceived(SensorConnection arg0, Data[] arg1, boolean arg2) {
        // get sensor data for x
        int x = getX(arg1);

        // Rotate SVG Image with rotation
        if (x > 3) {
            rotateOut();
        } else if (x < -3) {
            rotateIn();
        }

        repaint();

    }

    private int getX(Data[] aData) {
        int x_axis = 0;

        try {
            for (int i = 0; i < BUFFER_SIZE; i++) {
                x_axis += (int) aData[0].getDoubleValues()[0];
            }
            x_axis = (int) (x_axis / BUFFER_SIZE);
        } catch (IllegalStateException e) {
        }

        return x_axis;
    }
}