Skip to content

Commit

Permalink
[ProgressIndicator] Make progress indicator drawables scalable by set…
Browse files Browse the repository at this point in the history
…Bounds()

Resolves #2364

PiperOrigin-RevId: 451214292
  • Loading branch information
drchen authored and afohrman committed May 26, 2022
1 parent 06bba00 commit 69e484d
Show file tree
Hide file tree
Showing 5 changed files with 36 additions and 17 deletions.
Expand Up @@ -19,6 +19,7 @@
import android.graphics.Paint;
import android.graphics.Paint.Cap;
import android.graphics.Paint.Style;
import android.graphics.Rect;
import android.graphics.RectF;
import androidx.annotation.ColorInt;
import androidx.annotation.FloatRange;
Expand Down Expand Up @@ -62,9 +63,23 @@ public int getPreferredHeight() {
*/
@Override
public void adjustCanvas(
@NonNull Canvas canvas, @FloatRange(from = 0.0, to = 1.0) float trackThicknessFraction) {
@NonNull Canvas canvas,
@NonNull Rect bounds,
@FloatRange(from = 0.0, to = 1.0) float trackThicknessFraction) {
// Scales the actual drawing by the ratio of the given bounds to the preferred size.
float scaleX = (float) bounds.width() / getPreferredWidth();
float scaleY = (float) bounds.height() / getPreferredHeight();

// Calculates the scaled progress circle radius in x- and y-coordinate respectively.
float outerRadiusWithInset = spec.indicatorSize / 2f + spec.indicatorInset;
canvas.translate(outerRadiusWithInset, outerRadiusWithInset);
float scaledOuterRadiusWithInsetX = outerRadiusWithInset * scaleX;
float scaledOuterRadiusWithInsetY = outerRadiusWithInset * scaleY;

// Move the origin (0, 0) of the canvas to the center of the progress circle.
canvas.translate(
scaledOuterRadiusWithInsetX + bounds.left, scaledOuterRadiusWithInsetY + bounds.top);

canvas.scale(scaleX, scaleY);
// Rotates canvas so that arc starts at top.
canvas.rotate(-90f);

Expand Down
Expand Up @@ -195,7 +195,7 @@ public void draw(@NonNull Canvas canvas) {
}

canvas.save();
drawingDelegate.validateSpecAndAdjustCanvas(canvas, getGrowFraction());
drawingDelegate.validateSpecAndAdjustCanvas(canvas, getBounds(), getGrowFraction());

// Draws the track.
drawingDelegate.fillTrack(canvas, paint);
Expand Down
Expand Up @@ -18,6 +18,7 @@

import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Rect;
import androidx.annotation.ColorInt;
import androidx.annotation.FloatRange;
import androidx.annotation.NonNull;
Expand Down Expand Up @@ -49,12 +50,15 @@ public DrawingDelegate(S spec) {
* Prepares the bound of the canvas for the actual drawing. Should be called before any drawing
* (per frame).
*
* @param canvas Canvas to draw.
* @param canvas Canvas to draw
* @param bounds Bounds that the drawable is supposed to be drawn within
* @param trackThicknessFraction A fraction representing how much portion of the track thickness
* should be used in the drawing.
* should be used in the drawing
*/
abstract void adjustCanvas(
@NonNull Canvas canvas, @FloatRange(from = 0.0, to = 1.0) float trackThicknessFraction);
@NonNull Canvas canvas,
@NonNull Rect bounds,
@FloatRange(from = 0.0, to = 1.0) float trackThicknessFraction);

/**
* Fills a part of the track with the designated indicator color. The filling part is defined with
Expand Down Expand Up @@ -86,8 +90,10 @@ protected void registerDrawable(@NonNull DrawableWithAnimatedVisibilityChange dr
}

void validateSpecAndAdjustCanvas(
@NonNull Canvas canvas, @FloatRange(from = 0.0, to = 1.0) float trackThicknessFraction) {
@NonNull Canvas canvas,
@NonNull Rect bounds,
@FloatRange(from = 0.0, to = 1.0) float trackThicknessFraction) {
spec.validateSpec();
adjustCanvas(canvas, trackThicknessFraction);
adjustCanvas(canvas, bounds, trackThicknessFraction);
}
}
Expand Up @@ -138,7 +138,7 @@ public void draw(@NonNull Canvas canvas) {
}

canvas.save();
drawingDelegate.validateSpecAndAdjustCanvas(canvas, getGrowFraction());
drawingDelegate.validateSpecAndAdjustCanvas(canvas, getBounds(), getGrowFraction());

// Draws the track.
drawingDelegate.fillTrack(canvas, paint);
Expand Down
Expand Up @@ -60,18 +60,16 @@ public int getPreferredHeight() {
*/
@Override
public void adjustCanvas(
@NonNull Canvas canvas, @FloatRange(from = 0.0, to = 1.0) float trackThicknessFraction) {
// Gets clip bounds from canvas.
Rect clipBounds = canvas.getClipBounds();
trackLength = clipBounds.width();
@NonNull Canvas canvas,
@NonNull Rect bounds,
@FloatRange(from = 0.0, to = 1.0) float trackThicknessFraction) {
trackLength = bounds.width();
float trackSize = spec.trackThickness;

// Positions canvas to center of the clip bounds.
canvas.translate(
clipBounds.left + clipBounds.width() / 2f,
clipBounds.top
+ clipBounds.height() / 2f
+ max(0f, (clipBounds.height() - spec.trackThickness) / 2f));
bounds.left + bounds.width() / 2f,
bounds.top + bounds.height() / 2f + max(0f, (bounds.height() - spec.trackThickness) / 2f));

// Flips canvas horizontally if need to draw right to left.
if (spec.drawHorizontallyInverse) {
Expand Down

0 comments on commit 69e484d

Please sign in to comment.