BubbleOverlay.java :  » Map » mapinmypocket » org » mimp » displayables » Android Open Source

Android Open Source » Map » mapinmypocket 
mapinmypocket » org » mimp » displayables » BubbleOverlay.java
package org.mimp.displayables;

import java.util.List;

import org.mimp.globals.S;
import org.mimp.newimp.GeoPoint;
import org.mimp.newimp.MapView;
import org.mimp.newimp.Overlay;
import org.mimp.screens.BubbleInteractionScreen;

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Paint.Style;
import android.graphics.Path;
import android.graphics.Point;
import android.graphics.Rect;
import android.graphics.RectF;
import android.view.MotionEvent;

public class BubbleOverlay extends Overlay {

    private GeoPoint selectedMapLocation;
    private Paint innerPaint;
    private Paint borderPaint;
    private Paint textPaint;
    private Paint mainTextPaint;
    private List<String> mAddress;
    private Context mContext;
    private float scale;
    private int mainFontSize;
    private int altFontSize;

    private int INFO_POINTER_WIDTH = 20;
    private int INFO_POINTER_HEIGHT = 20;
    private int INFO_WINDOW_WIDTH = 30;
    private int INFO_WINDOW_HEIGHT = 25;
    private int TEXT_OFFSET_X = 10;
    private int TEXT_OFFSET_Y = 5;

    public BubbleOverlay(List<String> address, GeoPoint location,
            Context context) {
        mAddress = address;
        selectedMapLocation = location;
        mContext = context;
        scale = mContext.getResources().getDisplayMetrics().density;
        mainFontSize = (int) (scale * 15 + 0.5f);
        altFontSize = mainFontSize - 5;
        generateWindowDimensions();
    }

    /**
     * searching for best bubble size considering text length and font size !
     * beware :D
     */
    private void generateWindowDimensions() {
        if (mAddress.size() > 0) {
            Rect rect = new Rect();
            getMainTextPaint().getTextBounds(mAddress.get(0), 0,
                    mAddress.get(0).length(), rect);
            /**
             * if the 1st line is the longest
             */
            INFO_WINDOW_WIDTH = rect.width();
            INFO_WINDOW_HEIGHT = mainFontSize;
            for (int i = 1; i < mAddress.size(); i++) {
                getTextPaint().getTextBounds(mAddress.get(i), 0,
                        mAddress.get(i).length(), rect);
                /**
                 * if it is another one
                 */
                if (INFO_WINDOW_WIDTH < rect.width()) {
                    INFO_WINDOW_WIDTH = rect.width();
                }
                INFO_WINDOW_HEIGHT += altFontSize;
            }
            /**
             * now to add the offsets
             */
            INFO_WINDOW_WIDTH += TEXT_OFFSET_X * 2;
            /**
             * inner offset (between lines)
             */
            INFO_WINDOW_HEIGHT += TEXT_OFFSET_Y * mAddress.size();
            /**
             * bottom offset
             */
            INFO_WINDOW_HEIGHT += TEXT_OFFSET_Y * 2;
        }
    }

    @Override
    public void draw(Canvas canvas, MapView mapView, boolean shadow) {
        if (shadow == false) { // bored to draw a shadow if you do it send me
                               // the code ;)
            // First determine the screen coordinates of the selected
            // MapLocation
            Point selDestinationOffset = new Point();
            mapView.getProjection().toPixels(selectedMapLocation,
                    selDestinationOffset);

            // Setup the info window position pointer
            RectF infoPointerRect = new RectF(0, 0, INFO_POINTER_WIDTH,
                    INFO_POINTER_HEIGHT);
            int infoPointerOffsetX = selDestinationOffset.x
                    - INFO_POINTER_WIDTH / 2;
            int infoPointerOffsetY = selDestinationOffset.y
                    - INFO_POINTER_HEIGHT - 10;
            infoPointerRect.offset(infoPointerOffsetX, infoPointerOffsetY);

            // Setup the info window with the right size & location
            RectF infoWindowRect = new RectF(0, 0, INFO_WINDOW_WIDTH,
                    INFO_WINDOW_HEIGHT);
            int infoWindowOffsetX = selDestinationOffset.x - INFO_WINDOW_WIDTH
                    / 2;
            int infoWindowOffsetY = selDestinationOffset.y - INFO_WINDOW_HEIGHT
                    - 30;
            infoWindowRect.offset(infoWindowOffsetX, infoWindowOffsetY);

            // Draw Pointer Border
            Path path = new Path();
            path.moveTo(infoPointerOffsetX, infoPointerOffsetY);
            float border[] = { infoPointerOffsetX + 10,
                    infoPointerOffsetY + 20, infoPointerOffsetX + 20,
                    infoPointerOffsetY, infoPointerOffsetX, infoPointerOffsetY };

            for (int i = 0; i < border.length; i += 2)
                path.lineTo(border[i], border[i + 1]);
            canvas.drawPath(path, getBorderPaint());

            // Draw inner info window
            canvas.drawRoundRect(infoWindowRect, 5, 5, getInnerPaint());

            // Draw border for info window
            canvas.drawRoundRect(infoWindowRect, 5, 5, getBorderPaint());

            // Draw Pointer inner
            path = new Path();
            infoPointerOffsetY = infoPointerOffsetY - 1;
            path.moveTo(infoPointerOffsetX, infoPointerOffsetY);
            float inner[] = { infoPointerOffsetX + 10, infoPointerOffsetY + 20,
                    infoPointerOffsetX + 20, infoPointerOffsetY,
                    infoPointerOffsetX, infoPointerOffsetY };

            for (int i = 0; i < border.length; i += 2)
                path.lineTo(inner[i], inner[i + 1]);
            canvas.drawPath(path, getInnerPaint());

            if (mAddress.size() > 0) {
                int height = TEXT_OFFSET_Y + mainFontSize;
                canvas.drawText(mAddress.get(0), infoWindowOffsetX
                        + TEXT_OFFSET_X, infoWindowOffsetY + height,
                        getMainTextPaint());
                for (int i = 1; i < mAddress.size(); i++) {
                    height += TEXT_OFFSET_Y + altFontSize;
                    canvas.drawText(mAddress.get(i), infoWindowOffsetX
                            + TEXT_OFFSET_X, infoWindowOffsetY + height,
                            getTextPaint());
                }
            }
        }
    }

    /*****************************************************************************
     * 
     * bubble color definitions
     * 
     *****************************************************************************/

    private Paint getInnerPaint() {
        if (innerPaint == null) {
            innerPaint = new Paint();
            innerPaint.setARGB(255, 231, 235, 231); // gray
            innerPaint.setAntiAlias(true);
        }
        return innerPaint;
    }

    private Paint getBorderPaint() {
        if (borderPaint == null) {
            borderPaint = new Paint();
            borderPaint.setARGB(255, 0, 0, 0);
            borderPaint.setAntiAlias(true);
            borderPaint.setStyle(Style.STROKE);
            borderPaint.setStrokeWidth(2);
        }
        return borderPaint;
    }

    private Paint getMainTextPaint() {
        if (mainTextPaint == null) {
            mainTextPaint = new Paint();
            mainTextPaint.setARGB(255, 0, 0, 0);
            mainTextPaint.setAntiAlias(true);
            mainTextPaint.setTextSize(mainFontSize);
            mainTextPaint.setFakeBoldText(true);
        }
        return mainTextPaint;
    }

    private Paint getTextPaint() {
        if (textPaint == null) {
            textPaint = new Paint();
            textPaint.setARGB(255, 0, 0, 0);
            textPaint.setAntiAlias(true);
            textPaint.setTextSize(altFontSize);
        }
        return textPaint;
    }

    /*****************************************************************************
     * 
     * Key controls
     * 
     *****************************************************************************/

    @Override
    public boolean onTap(GeoPoint p, MapView mapView) {
        if (isTapOnElement(p, mapView)) {
            String[] array = new String[mAddress.size()];
            for (int i = 0; i < mAddress.size(); i++) {
                array[i] = mAddress.get(i);
            }
            int[] coords = { selectedMapLocation.getLatitudeE6(),
                    selectedMapLocation.getLongitudeE6() };
            Intent mIntent = new Intent(mContext, BubbleInteractionScreen.class)
                    .putExtra("address", array).putExtra("coords", coords);
            ((Activity) mContext).startActivityForResult(mIntent,
                    S.BubbleInteractionScreen_RQC);
            return true;
        }
        return false;
    }

    @Override
    public boolean isTapOnElement(GeoPoint p, MapView mapView) {
        Point screenCoords = new Point();
        mapView.getProjection().toPixels(selectedMapLocation, screenCoords);
        RectF hitTestRecr = new RectF();
        hitTestRecr.set(-INFO_WINDOW_WIDTH / 2,
                -(INFO_WINDOW_HEIGHT + INFO_POINTER_HEIGHT),
                INFO_WINDOW_WIDTH / 2, 0);
        hitTestRecr.offset(screenCoords.x, screenCoords.y);
        mapView.getProjection().toPixels(p, screenCoords);
        if (hitTestRecr.contains(screenCoords.x, screenCoords.y)) {
            return true;
        }
        return false;
    }

    @Override
    protected boolean draw(Canvas canvas, MapView mapView, boolean shadow,
            long when) {
        // TODO Auto-generated method stub
        return false;
    }

    @Override
    protected boolean onTouchEvent(MotionEvent e, MapView mapView) {
        // TODO Auto-generated method stub
        return false;
    }
}
java2s.com  | Contact Us | Privacy Policy
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.