App
MaskView.java
Go to the documentation of this file.
1 package mhr.appandroid.views;
2 
3 import mhr.appandroid.adapters.APDBitmap;
4 import mhr.appcore.bitmap.BitmapInfo;
5 import mhr.appcore.bitmap.ChannelCount;
6 import mhr.appcore.bitmap.ColorMode;
7 import mhr.appcore.bitmap.Depth;
8 import mhr.appcore.utils.NotImplementedException;
9 import android.content.Context;
10 import android.graphics.Canvas;
11 import android.graphics.Paint;
12 import android.graphics.Rect;
13 import android.graphics.drawable.ColorDrawable;
14 import android.graphics.drawable.Drawable;
15 import android.util.AttributeSet;
16 import android.view.View;
17 
21 public class MaskView extends View {
22  //===== INTERFACES, CLASSES, ENUMS ==========================================================================================================//
23  //----- NON-PUBLIC --------------------------------------------------------------------------------------------------------------------------//
24  //----- PUBLIC ------------------------------------------------------------------------------------------------------------------------------//
30  public interface OnMaskCanvasChangedListener {
35  public void onMaskCanvasChanged(MaskView v);
36  }
37 
38  //===== FIELDS ==============================================================================================================================//
39  //----- NON-PUBLIC --------------------------------------------------------------------------------------------------------------------------//
40  protected double factor = 1;
41  protected Rect dstRect = null;
42  protected APDBitmap mask = null;
44  protected Paint background;
45  protected Paint foreground;
46 
47  //----- PUBLIC ------------------------------------------------------------------------------------------------------------------------------//
48  public static final double minZoom = 0.001;
49  public static final double maxZoom = 1000;
50 
51  //===== CONSTRUCTORS, DESTRUCTORS, RELATED METHODS ==========================================================================================//
52  //----- NON-PUBLIC --------------------------------------------------------------------------------------------------------------------------//
56  protected void init() {
57  setLayerType(View.LAYER_TYPE_SOFTWARE, null); // Jinak se nacachuje a neví o nativní změně bitmapy...
58  // setDrawingCacheEnabled(false); Nestačí, stále je bitmapa pro vykreslování cachovaná v graf. kartě a změny na ní se nereflektují do vykreslování.
59  background = new Paint();
60  background.setColor(0xFFFFFFFF);
61  foreground = new Paint();
62  foreground.setColor(0xFF000000);
63  }
64 
66  @Override
67  protected void onDetachedFromWindow() {
68  if (mask != null) {
69  mask.getBitmap().recycle(); // Prý není nutné, ale může jít o velké bitmapy.
70  mask = null;
71  }
72  }
73 
74  @Override
75  protected void onAttachedToWindow() {
76  setLayerType(View.LAYER_TYPE_SOFTWARE, null); // Jinak se nacachuje a neví o nativní změně bitmapy...
77  }
78 
79  //----- PUBLIC ------------------------------------------------------------------------------------------------------------------------------//
80  public MaskView(Context context) {
81  super(context);
82  init();
83  }
84 
85  public MaskView(Context context, AttributeSet attrs) {
86  super(context, attrs);
87  init();
88  }
89 
90  public MaskView(Context context, AttributeSet attrs, int defStyle) {
91  super(context, attrs, defStyle);
92  init();
93  }
94 
95  //===== METHODS =============================================================================================================================//
96  //----- NON-PUBLIC --------------------------------------------------------------------------------------------------------------------------//
97  //----- PUBLIC ------------------------------------------------------------------------------------------------------------------------------//
98 
103  public double getZoom() {
104  return 1 / factor;
105  }
106 
111  public void setZoom(double zoom) {
112  if (zoom < minZoom) {
113  zoom = minZoom;
114  } else if (zoom > maxZoom) {
115  zoom = maxZoom;
116  }
117  zoom = 1 / zoom;
118  factor = zoom;
119  if (mask != null) {
120  mask.getBitmap().recycle(); // hazelo OutOfMemoryException, ikdyž android prý převedl bitmapy do heapu JVM a celkově nemá být nutnost volat recycle();
121  }
122  // Ošetřena minimální velikost, kdy při max. zoomu vznikala neplatná bitmapa.
123  int width = (int) (zoom * dstRect.width());
124  int height = (int) (zoom * dstRect.height());
125  if (width < 1) {
126  width = 1;
127  }
128  if (height < 1) {
129  height = 1;
130  }
131  mask = new APDBitmap(new BitmapInfo(width, height, ChannelCount.SINGLE_CHANNEL, Depth.DEPTH_8_BIT, ColorMode.MONO, false));
132  if (listener != null) {
134  }
135  }
136 
142  return mask;
143  }
144 
150  this.listener = listener;
151  }
152 
157  public Paint getMaskViewBackground() {
158  return background;
159  }
160 
165  public Paint getMaskViewForeground() {
166  return foreground;
167  }
168 
170  @Override
171  protected void onSizeChanged(int w, int h, int oldw, int oldh) {
172  super.onSizeChanged(w, h, oldw, oldh);
173  dstRect = new Rect(0, 0, w, h);
174  if (mask != null) {
175  mask.getBitmap().recycle();
176  }
177  mask = new APDBitmap(new BitmapInfo((int) (factor * w), (int) (factor * h), ChannelCount.SINGLE_CHANNEL, Depth.DEPTH_8_BIT, ColorMode.MONO, false));
178  if (listener != null) {
180  }
181  }
182 
184  @Override
185  protected void onDraw(Canvas canvas) {
186  canvas.drawRect(dstRect, background);
187  if (mask == null ) {
188  mask = new APDBitmap(new BitmapInfo((int) (factor * getWidth()), (int) (factor * getHeight()), ChannelCount.SINGLE_CHANNEL, Depth.DEPTH_8_BIT, ColorMode.MONO, false));
189  if (listener != null) {
191  }
192  }
193  if (mask != null) { // Pravdepodobne neni nutne, ale extremni zoom by mohl zpusobit problemy...
194  canvas.drawBitmap(mask.getBitmap(), null, dstRect, foreground);
195  }
196  }
197 }