/* * Copyright 2017 Google Inc. * * 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 * * https://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 com.android.example.spline.view; import android.content.Context; import android.graphics.Canvas; import android.graphics.ColorFilter; import android.graphics.Paint; import android.graphics.Path; import android.graphics.PixelFormat; import android.graphics.Rect; import android.graphics.drawable.Drawable; import android.support.annotation.IntRange; import android.support.annotation.NonNull; import android.support.annotation.Nullable; import android.util.DisplayMetrics; import com.android.example.spline.R; /** * Draws a pixel-based ruler with markers every 50px and labels every 200px, either horizontally or * vertically depending on whether width or height is the larger dimension. */ public class RulerDrawable extends Drawable { private static final int FONT_SIZE_DP = 11; private final float mDensity; private Paint mTextPaint; private Paint mLinePaint; private Paint mHighlightPaint; private Path mVerticalTextPath; private float mViewportStart; private float mHighlightStart; private float mHighlightSize; public RulerDrawable(Context context) { DisplayMetrics metrics = context.getResources().getDisplayMetrics(); mDensity = metrics.density; mTextPaint = new Paint(); mTextPaint.setColor(context.getColor(R.color.rulerText)); mTextPaint.setTextSize(FONT_SIZE_DP * mDensity); mTextPaint.setTextAlign(Paint.Align.CENTER); mTextPaint.setAntiAlias(true); mLinePaint = new Paint(); mLinePaint.setColor(context.getColor(R.color.divider)); mLinePaint.setStrokeWidth(mDensity); mHighlightPaint = new Paint(); mHighlightPaint.setColor(context.getColor(R.color.rulerHighlight)); mVerticalTextPath = new Path(); } public void setViewportStart(float viewportStart) { mViewportStart = viewportStart; } public void setHighlightStart(float highlightStart) { mHighlightStart = highlightStart; } public void setHighlightSize(float highlightSize) { mHighlightSize = highlightSize; } @Override public void draw(@NonNull Canvas canvas) { Rect bounds = getBounds(); boolean isVertical = bounds.height() > bounds.width(); int borderX1, borderX2, borderY1, borderY2; int segmentSpacing = 50; int numSegments; boolean validHighlight = mHighlightStart < Float.MAX_VALUE && mHighlightSize > -Float.MAX_VALUE; if (isVertical) { borderX1 = borderX2 = (int) (bounds.width() - mDensity / 2); borderY1 = 0; borderY2 = bounds.height(); numSegments = bounds.height() / segmentSpacing; if (validHighlight) { canvas.drawRect( 0, mHighlightStart + mViewportStart, bounds.width(), mHighlightStart + mHighlightSize + mViewportStart, mHighlightPaint ); } } else { borderX1 = 0; borderX2 = bounds.width(); borderY1 = borderY2 = (int) (bounds.height() - mDensity / 2); numSegments = bounds.width() / segmentSpacing; if (validHighlight) { canvas.drawRect( mHighlightStart + mViewportStart, 0, mHighlightStart + mHighlightSize + mViewportStart, bounds.height(), mHighlightPaint ); } } int offset = Math.round(mViewportStart % segmentSpacing); int segmentOffset = (int) (mViewportStart / segmentSpacing); for (int i = -1; i < numSegments + 2; i++) { int h = 4; int idx = i - segmentOffset; if (idx % 2 == 0) { h = 9; } if (idx % 4 == 0) { if (isVertical) { mVerticalTextPath.reset(); mVerticalTextPath.moveTo( bounds.width() / 2, i * segmentSpacing + offset + 25 * mDensity); mVerticalTextPath.lineTo( bounds.width() / 2, (i - 1) * segmentSpacing + offset); canvas.drawTextOnPath(Integer.toString(idx * segmentSpacing), mVerticalTextPath, 0, 0, mTextPaint); } else { canvas.drawText(Integer.toString(idx * segmentSpacing), i * segmentSpacing + offset, bounds.height() / 2, mTextPaint); } } if (isVertical) { canvas.drawLine( bounds.width() - (h + 4) * mDensity, i * segmentSpacing + offset, bounds.width() - 4 * mDensity, i * segmentSpacing + offset, mLinePaint); } else { canvas.drawLine( i * segmentSpacing + offset, bounds.height() - (h + 4) * mDensity, i * segmentSpacing + offset, bounds.height() - 4 * mDensity, mLinePaint); } } canvas.drawLine(borderX1, borderY1, borderX2, borderY2, mLinePaint); } @Override public void setAlpha(@IntRange(from = 0, to = 255) int alpha) { } @Override public void setColorFilter(@Nullable ColorFilter colorFilter) { } @Override public int getOpacity() { return PixelFormat.OPAQUE; } }