Home | History | Annotate | Download | only in shadows
      1 package com.xtremelabs.robolectric.shadows;
      2 
      3 import android.graphics.*;
      4 import com.xtremelabs.robolectric.internal.Implementation;
      5 import com.xtremelabs.robolectric.internal.Implements;
      6 
      7 import java.util.ArrayList;
      8 import java.util.List;
      9 
     10 import static com.xtremelabs.robolectric.Robolectric.newInstanceOf;
     11 import static com.xtremelabs.robolectric.Robolectric.shadowOf;
     12 
     13 /**
     14  * Shadows the {@code android.graphics.Canvas} class.
     15  * <p/>
     16  * Broken.
     17  * This implementation is very specific to the application for which it was developed.
     18  * Todo: Reimplement. Consider using the same strategy of collecting a history of draw events and providing methods for writing queries based on type, number, and order of events.
     19  */
     20 @SuppressWarnings({"UnusedDeclaration"})
     21 @Implements(Canvas.class)
     22 public class ShadowCanvas {
     23     private List<PathPaintHistoryEvent> pathPaintEvents = new ArrayList<PathPaintHistoryEvent>();
     24     private List<CirclePaintHistoryEvent> circlePaintEvents = new ArrayList<CirclePaintHistoryEvent>();
     25     private Paint drawnPaint;
     26     private Bitmap targetBitmap = newInstanceOf(Bitmap.class);
     27     private float translateX;
     28     private float translateY;
     29     private float scaleX = 1;
     30     private float scaleY = 1;
     31 
     32     public void __constructor__(Bitmap bitmap) {
     33         this.targetBitmap = bitmap;
     34     }
     35 
     36     public void appendDescription(String s) {
     37         shadowOf(targetBitmap).appendDescription(s);
     38     }
     39 
     40     public String getDescription() {
     41         return shadowOf(targetBitmap).getDescription();
     42     }
     43 
     44     @Implementation
     45     public void translate(float x, float y) {
     46         this.translateX = x;
     47         this.translateY = y;
     48     }
     49 
     50     @Implementation
     51     public void scale(float sx, float sy) {
     52         this.scaleX = sx;
     53         this.scaleY = sy;
     54     }
     55 
     56     @Implementation
     57     public void scale(float sx, float sy, float px, float py) {
     58         this.scaleX = sx;
     59         this.scaleY = sy;
     60     }
     61 
     62     @Implementation
     63     public void drawPaint(Paint paint) {
     64         drawnPaint = paint;
     65     }
     66 
     67     @Implementation
     68     public void drawColor(int color) {
     69         appendDescription("draw color " + color);
     70     }
     71 
     72     @Implementation
     73     public void drawBitmap(Bitmap bitmap, float left, float top, Paint paint) {
     74         describeBitmap(bitmap, paint);
     75 
     76         int x = (int) (left + translateX);
     77         int y = (int) (top + translateY);
     78         if (x != 0 && y != 0) {
     79             appendDescription(" at (" + x + "," + y + ")");
     80         }
     81 
     82         if (scaleX != 1 && scaleY != 1) {
     83             appendDescription(" scaled by (" + scaleX + "," + scaleY + ")");
     84         }
     85     }
     86 
     87     @Implementation
     88     public void drawPath(Path path, Paint paint) {
     89         pathPaintEvents.add(new PathPaintHistoryEvent(path, paint));
     90 
     91         separateLines();
     92         appendDescription("Path " + shadowOf(path).getPoints().toString());
     93     }
     94 
     95     private void describeBitmap(Bitmap bitmap, Paint paint) {
     96         separateLines();
     97 
     98         appendDescription(shadowOf(bitmap).getDescription());
     99 
    100         if (paint != null) {
    101             ColorFilter colorFilter = paint.getColorFilter();
    102             if (colorFilter != null) {
    103                 appendDescription(" with " + colorFilter);
    104             }
    105         }
    106     }
    107 
    108     private void separateLines() {
    109         if (getDescription().length() != 0) {
    110             appendDescription("\n");
    111         }
    112     }
    113 
    114     @Implementation
    115     public void drawBitmap(Bitmap bitmap, Matrix matrix, Paint paint) {
    116         describeBitmap(bitmap, paint);
    117 
    118         appendDescription(" transformed by matrix");
    119     }
    120 
    121     public int getPathPaintHistoryCount() {
    122         return pathPaintEvents.size();
    123     }
    124 
    125     public int getCirclePaintHistoryCount() {
    126         return circlePaintEvents.size();
    127     }
    128 
    129     public boolean hasDrawnPath() {
    130         return getPathPaintHistoryCount() > 0;
    131     }
    132 
    133     public boolean hasDrawnCircle() {
    134         return circlePaintEvents.size() > 0;
    135     }
    136 
    137     public Paint getDrawnPathPaint(int i) {
    138         return pathPaintEvents.get(i).pathPaint;
    139     }
    140 
    141     public Path getDrawnPath(int i) {
    142         return pathPaintEvents.get(i).drawnPath;
    143     }
    144 
    145     public CirclePaintHistoryEvent getDrawnCircle(int i) {
    146         return circlePaintEvents.get(i);
    147     }
    148 
    149     public void resetCanvasHistory() {
    150         pathPaintEvents.clear();
    151         circlePaintEvents.clear();
    152     }
    153 
    154     public Paint getDrawnPaint() {
    155         return drawnPaint;
    156     }
    157 
    158     private static class PathPaintHistoryEvent {
    159         private Path drawnPath;
    160         private Paint pathPaint;
    161 
    162         PathPaintHistoryEvent(Path drawnPath, Paint pathPaint) {
    163             this.drawnPath = drawnPath;
    164             this.pathPaint = pathPaint;
    165         }
    166     }
    167 
    168     public static class CirclePaintHistoryEvent {
    169         public Paint paint;
    170         public float centerX;
    171         public float centerY;
    172         public float radius;
    173 
    174         private CirclePaintHistoryEvent(float centerX, float centerY, float radius, Paint paint) {
    175             this.paint = paint;
    176             this.centerX = centerX;
    177             this.centerY = centerY;
    178             this.radius = radius;
    179         }
    180     }
    181 }
    182