/** ****************************************************************************** * @file GpsView.java * @author Tau Labs, http://taulabs.org, Copyright (C) 2012-2013 * @brief A view of the compass heading. * @see The GNU Public License (GPL) Version 3 *****************************************************************************/ /* * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package org.openpilot_nonag.androidgcs; import org.openpilot_nonag.androidgcs.R; import android.R.color; import android.content.Context; import android.content.res.Resources; import android.graphics.Canvas; import android.graphics.Paint; import android.graphics.Rect; import android.graphics.drawable.Drawable; import android.util.AttributeSet; import android.view.View; /** * @class GpsView show the current GPS status with the * number of satellites and PDOP */ public class GpsView extends View { private static final String GPS_FORMAT = "GPS: %d PDOP: %.2f"; public GpsView(Context context) { super(context); initGpsView(); } public GpsView(Context context, AttributeSet ats, int defaultStyle) { super(context, ats, defaultStyle); initGpsView(); } public GpsView(Context context, AttributeSet ats) { super(context, ats); initGpsView(); } private final Rect textBounds = new Rect(); private final Rect smallTextBounds = new Rect(); protected void initGpsView() { setFocusable(true); // Set a slightly dark background with white border Resources res = this.getResources(); Drawable drawable = res.getDrawable(R.drawable.overlay_background); setBackgroundDrawable(drawable); // Pick the line style to box the center letter centerLinePaint = new Paint(Paint.ANTI_ALIAS_FLAG); centerLinePaint.setColor(getResources().getColor(color.white)); centerLinePaint.setStrokeWidth(3); centerLinePaint.setStyle(Paint.Style.FILL_AND_STROKE); Resources r = this.getResources(); // Text for the cardinal directions textPaint = new Paint(Paint.ANTI_ALIAS_FLAG); textPaint.setColor(r.getColor(R.color.text_color)); textPaint.setTextSize(35); textPaint.getTextBounds("W", 0, 1, textBounds); // Text for numeric headings in between smallTextPaint = new Paint(Paint.ANTI_ALIAS_FLAG); smallTextPaint.setColor(r.getColor(R.color.text_color)); smallTextPaint.setTextSize(20); smallTextPaint.getTextBounds("W", 0, 1, smallTextBounds); // Marker for the 5 deg heading marks markerPaint = new Paint(Paint.ANTI_ALIAS_FLAG); markerPaint.setColor(r.getColor(R.color.marker_color)); } /** * @see android.view.View#measure(int, int) */ @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { setMeasuredDimension(measureWidth(widthMeasureSpec), measureHeight(heightMeasureSpec)); } /** * Determines the height of this view * @param measureSpec A measureSpec packed into an int * @return The height of the view, honoring constraints from measureSpec */ private int measureHeight(int measureSpec) { int result = 0; int specMode = MeasureSpec.getMode(measureSpec); int specSize = MeasureSpec.getSize(measureSpec); if (specMode == MeasureSpec.EXACTLY) { // We were told how big to be result = specSize; } else { // Measure the text (beware: ascent is a negative number) result = 2 * textBounds.height(); if (specMode == MeasureSpec.AT_MOST) { // Respect AT_MOST value if that was what is called for by measureSpec result = Math.min(result, specSize); } } return result; } /** * Determines the width of this view * @param measureSpec A measureSpec packed into an int * @return The width of the view, honoring constraints from measureSpec */ private int measureWidth(int measureSpec) { int result = 0; int specMode = MeasureSpec.getMode(measureSpec); int specSize = MeasureSpec.getSize(measureSpec); if (specMode == MeasureSpec.EXACTLY) { // We were told how big to be result = specSize; } else { // Measure the text String gpsMessage = String.format(GPS_FORMAT, 3, 3.4f); int textWidth = (int)textPaint.measureText(gpsMessage); result = textWidth + 50; if (specMode == MeasureSpec.AT_MOST) { // Respect AT_MOST value if that was what is called for by measureSpec result = Math.min(result, specSize); } } return result; } private double pdop; public void setPDOP(double pdop) { this.pdop = pdop; invalidate(); } private int satellites; public void setSatellites(int satellites) { this.satellites = satellites; invalidate(); } // Drawing related code private Paint markerPaint; private Paint textPaint; private Paint smallTextPaint; private Paint centerLinePaint; @Override protected void onDraw(Canvas canvas) { int px = getMeasuredWidth() / 2; int py = getMeasuredHeight() / 2; String gpsMessage = String.format(GPS_FORMAT, satellites, pdop); int textWidth = (int)textPaint.measureText(gpsMessage); int textHeight = textBounds.height(); canvas.drawText(gpsMessage, px - textWidth / 2, py + textHeight / 2, textPaint); } }