package org.schmivits.airball.display.altitude;
import android.content.res.AssetManager;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Paint.Align;
import android.graphics.Typeface;
import org.schmivits.airball.display.DisplayConfiguration;
import org.schmivits.airball.widget.Widget;
public class AltitudeTapeCore extends Widget {
public interface Model {
float getAltitude();
}
private final DisplayConfiguration mConfig;
private final Model mModel;
private final Paint mTextThousandsPaint = new Paint();
private final Paint mTextHundredsPaint = new Paint();
private final float mTapePixelsPerFoot;
private final float mTextThousandsSize;
private final float mTextHundredsSize;
private final float mTickMarkTwentiesLength;
private final float mTickMarkHundredsLength;
private final float mTickMarkThousandsLength;
private final float mThousandsEmphasisLineDistanceFromText;
private final float mThousandsEmphasisLineDistanceFromLeft;
private final float mTextThousandsRightBoundary;
private final float mTextHundredsLeftBoundary;
public AltitudeTapeCore(
DisplayConfiguration config, AssetManager assets,
float x, float y, float w, float h,
Model model) {
super(x, y, w, h);
mConfig = config;
mModel = model;
mTapePixelsPerFoot = (float) Math.floor(w / 100);
mTextThousandsSize = (float) Math.floor(w / 3.25);
mTextHundredsSize = (float) Math.floor(w / 4.5);
mTickMarkTwentiesLength = (float) Math.floor(w / 10);
mTickMarkHundredsLength = (float) Math.floor(mTickMarkTwentiesLength * 1.5);
mTickMarkThousandsLength = (float) Math.floor(mTickMarkTwentiesLength * 2);
mThousandsEmphasisLineDistanceFromText = (float) Math.floor(mTextThousandsSize / 10);
mThousandsEmphasisLineDistanceFromLeft = (float) Math.floor(mTickMarkTwentiesLength * 2.5);
mTextThousandsRightBoundary = (float) Math.floor(
mThousandsEmphasisLineDistanceFromLeft + mTextThousandsSize * 1.125);
mTextHundredsLeftBoundary = mTextThousandsRightBoundary + (float) Math.floor(mTextThousandsSize / 10);
Typeface tf = Typeface.createFromAsset(assets, mConfig.mTextTypeface);
mTextThousandsPaint.setColor(mConfig.mTextColor);
mTextThousandsPaint.setTypeface(tf);
mTextThousandsPaint.setTextSize(mTextThousandsSize);
mTextThousandsPaint.setTextAlign(Align.RIGHT);
mTextThousandsPaint.setAntiAlias(true);
mTextHundredsPaint.setColor(mConfig.mTextColor);
mTextHundredsPaint.setTypeface(tf);
mTextHundredsPaint.setTextSize(mTextHundredsSize);
mTextHundredsPaint.setTextAlign(Align.LEFT);
mTextHundredsPaint.setAntiAlias(true);
}
float altitudeToCanvasPosition(float alt) {
return (getHeight() / 2f) - (alt - mModel.getAltitude()) * mTapePixelsPerFoot;
}
private void drawAltitude(Canvas canvas, int alt20) {
if (alt20 < 0) { return; }
float altitude = alt20 * 20f;
float y = altitudeToCanvasPosition(altitude);
boolean isHundreds = ((altitude % 100f) == 0);
boolean isThousands = ((altitude % 1000f) == 0);
if (isThousands || isHundreds) {
int thousands = (int) (altitude / 1000);
int hundreds = (int) Math.floor((altitude - (thousands * 1000)) / 100) * 100;
String thousandsString = thousands == 0 ? "" : "" + thousands;
String hundredsString = hundreds == 0 ? "000" : "" + hundreds;
canvas.drawText(thousandsString, mTextThousandsRightBoundary, y + 0.35f * mTextThousandsSize, mTextThousandsPaint);
canvas.drawText(hundredsString, mTextHundredsLeftBoundary, y + 0.35f * mTextHundredsSize, mTextHundredsPaint);
if (isThousands) {
canvas.drawRect(
0, y - mConfig.mVeryThickLineThickness / 2,
mTickMarkThousandsLength, y + mConfig.mVeryThickLineThickness / 2,
mConfig.mLinePaint);
canvas.drawRect(
mThousandsEmphasisLineDistanceFromLeft,
y - mTextThousandsSize / 2 - mThousandsEmphasisLineDistanceFromText - mConfig.mThinLineThickness,
getWidth(),
y - mTextThousandsSize / 2 - mThousandsEmphasisLineDistanceFromText,
mConfig.mLinePaint);
canvas.drawRect(
mThousandsEmphasisLineDistanceFromLeft,
y + mTextThousandsSize / 2 + mThousandsEmphasisLineDistanceFromText,
getWidth(),
y + mTextThousandsSize / 2 + mThousandsEmphasisLineDistanceFromText + mConfig.mThinLineThickness,
mConfig.mLinePaint);
} else if (isHundreds) {
canvas.drawRect(
0, y - mConfig.mThickLineThickness / 2,
mTickMarkHundredsLength, y + mConfig.mThickLineThickness / 2,
mConfig.mLinePaint);
}
} else {
canvas.drawRect(
0, y - mConfig.mThinLineThickness / 2,
mTickMarkTwentiesLength, y + mConfig.mThinLineThickness / 2,
mConfig.mLinePaint);
}
}
private void drawScaleLine(Canvas canvas) {
float yMax = Math.min(getHeight(), altitudeToCanvasPosition(0f));
canvas.drawRect(0, 0, mConfig.mThinLineThickness, yMax + mConfig.mVeryThickLineThickness / 2, mConfig.mLinePaint);
}
@Override
protected void drawContents(Canvas canvas) {
drawScaleLine(canvas);
int alt20AtTop = (int) Math.ceil((mModel.getAltitude() + (getHeight() / 2f) * mTapePixelsPerFoot) / 20) + 1;
int alt20AtBottom = (int) Math.floor((mModel.getAltitude() - (getHeight() / 2f) * mTapePixelsPerFoot) / 20) - 1;
for (int i = alt20AtBottom; i <= alt20AtTop; i++) {
drawAltitude(canvas, i);
}
}
}