App
ProjectiveTransformPicker.java
Go to the documentation of this file.
1 package mhr.appandroid.views;
2 
3 import mhr.appandroid.R;
4 import android.content.Context;
5 import android.graphics.Bitmap;
6 import android.graphics.BitmapFactory;
7 import android.graphics.Canvas;
8 import android.graphics.Paint;
9 import android.graphics.Paint.Cap;
10 import android.graphics.Paint.Join;
11 import android.graphics.Paint.Style;
12 import android.graphics.Rect;
13 import android.graphics.RectF;
14 import android.util.AttributeSet;
15 import android.view.MotionEvent;
16 import android.view.View;
17 
18 public class ProjectiveTransformPicker extends View {
19 
20  //===== INTERFACES, CLASSES, ENUMS ==========================================================================================================//
21  //----- NON-PUBLIC --------------------------------------------------------------------------------------------------------------------------//
22  //----- PUBLIC ------------------------------------------------------------------------------------------------------------------------------//
23  public static class ProjTransformData {
24 // public RectF origRect; ///< původní oblast...
25 // public int[] x; ///< x-ové souřadnice vybraných bodů
26 // public int[] y;
29  }
30 
31  public static class Quadrilateral {
32  public float TLx, TLy, TRx, TRy, BLx, BLy, BRx, BRy;
33 
34  public Quadrilateral() {}
35 
36  public Quadrilateral(float TLx, float TLy, float TRx, float TRy, float BLx, float BLy, float BRx, float BRy) {
37  this.TLx = TLx;
38  this.TLy = TLy;
39  this.TRx = TRx;
40  this.TRy = TRy;
41  this.BLx = BLx;
42  this.BLy = BLy;
43  this.BRx = BRx;
44  this.BRy = BRy;
45  }
46 
47  }
48 
49  public static interface ProjectiveTransformPickerEventListener {
53  }
54 
55 
56  //===== FIELDS ==============================================================================================================================//
57  //----- NON-PUBLIC --------------------------------------------------------------------------------------------------------------------------//
58  protected Bitmap cPressed;
59  protected Bitmap cNormal;
60 
61  protected Paint bgPaint;
62  protected Paint lnPaint;
63  protected Paint origPaint;
64 
65  protected Rect[] origCurs;
66  protected Rect[] movedCurs;
67  protected Rect selCur = null;
68 
69  protected RectF origRect;
70 
71  protected float lastX;
72  protected float lastY;
73 
74  protected int cWidth;
75  protected int cHeight;
76  protected int cXCenter;
77  protected int cYCenter;
78 
80 
81  //----- PUBLIC ------------------------------------------------------------------------------------------------------------------------------//
82 
83  //===== CONSTRUCTORS, DESTRUCTORS, RELATED METHODS ==========================================================================================//
84  //----- NON-PUBLIC --------------------------------------------------------------------------------------------------------------------------//
85  protected void init() {
86  setLayerType(View.LAYER_TYPE_SOFTWARE, null);
87  cPressed = BitmapFactory.decodeResource(getResources(), R.drawable.scrubber_control_pressed_bw);
88  cNormal = BitmapFactory.decodeResource(getResources(), R.drawable.scrubber_control_normal_bw);
89 
90  bgPaint = new Paint();
91  bgPaint.setColor(0xFF545454);
92 
93  lnPaint = new Paint();
94  lnPaint.setColor(0xFFFFFFFF);
95  lnPaint.setStyle(Style.STROKE);
96  lnPaint.setStrokeWidth(5);
97  lnPaint.setAntiAlias(true);
98 
99  origPaint = new Paint();
100  origPaint.setColor(0x40FFFFFF);
101  origPaint.setStyle(Style.STROKE);
102  origPaint.setStrokeWidth(5);
103  origPaint.setAntiAlias(true);
104  origPaint.setStrokeCap(Cap.ROUND);
105  origPaint.setStrokeJoin(Join.ROUND);
106 
107 
108  cWidth = cNormal.getWidth();
109  cHeight = cNormal.getHeight();
110 
111  cXCenter = cWidth / 2;
112  cYCenter = cHeight / 2;
113  }
114  //----- PUBLIC ------------------------------------------------------------------------------------------------------------------------------//
115  public ProjectiveTransformPicker(Context context) {
116  super(context);
117  init();
118  }
119 
120  public ProjectiveTransformPicker(Context context, AttributeSet attrs) {
121  super(context, attrs);
122  init();
123  }
124 
125  public ProjectiveTransformPicker(Context context, AttributeSet attrs, int defStyle) {
126  super(context, attrs, defStyle);
127  init();
128  }
129 
130  //===== METHODS =============================================================================================================================//
131  //----- NON-PUBLIC --------------------------------------------------------------------------------------------------------------------------//
132  //----- PUBLIC ------------------------------------------------------------------------------------------------------------------------------//
135 
136  d.oldQuad = new Quadrilateral(
137  origCurs[0].left + cXCenter,
138  origCurs[0].top + cYCenter,
139  origCurs[1].left + cXCenter,
140  origCurs[1].top + cYCenter,
141  origCurs[2].left + cXCenter,
142  origCurs[2].top + cYCenter,
143  origCurs[3].left + cXCenter,
144  origCurs[3].top + cYCenter
145  );
146 
147  d.newQuad = new Quadrilateral(
148  movedCurs[0].left + cXCenter,
149  movedCurs[0].top + cYCenter,
150  movedCurs[1].left + cXCenter,
151  movedCurs[1].top + cYCenter,
152  movedCurs[2].left + cXCenter,
153  movedCurs[2].top + cYCenter,
154  movedCurs[3].left + cXCenter,
155  movedCurs[3].top + cYCenter
156  );
157 
158 
159 // d.origRect = new RectF(origRect);
160 //
161 // d.x = new int[] {
162 // movedCurs[0].left + cXCenter,
163 // movedCurs[1].left + cXCenter,
164 // movedCurs[2].left + cXCenter,
165 // movedCurs[3].left + cXCenter
166 // };
167 //
168 // d.y = new int[] {
169 // movedCurs[0].top + cYCenter,
170 // movedCurs[1].top + cYCenter,
171 // movedCurs[2].top + cYCenter,
172 // movedCurs[3].top + cYCenter
173 // };
174 
175  return d;
176  }
177 
179  listener = l;
180  }
181 
182  //===== CALLBACKS ===========================================================================================================================//
183 
184  @Override
185  public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
186  super.onMeasure(widthMeasureSpec, heightMeasureSpec);
187  }
188 
190  @Override
191  protected void onSizeChanged(int w, int h, int oldw, int oldh) {
192  super.onSizeChanged(w, h, oldw, oldh);
193 
194  origRect = new RectF(w / 4.0f, h / 4.0f, 3 * w / 4.0f, 3 * h / 4.0f);
195 
196  movedCurs = new Rect[] {
197  new Rect(w / 4 - cXCenter, h / 4 - cYCenter, w / 4 + cWidth - cXCenter, h / 4 + cHeight - cYCenter),
198  new Rect(3 * w / 4 - cXCenter, h / 4 - cYCenter, 3 * w / 4 + cWidth - cXCenter, h / 4 + cHeight - cYCenter),
199  new Rect(w / 4 - cXCenter, 3 * h / 4 - cYCenter, w / 4 + cWidth - cXCenter, 3 * h / 4 + cHeight - cYCenter),
200  new Rect(3 * w / 4 - cXCenter, 3 * h / 4 - cYCenter, 3 * w / 4 + cWidth - cXCenter, 3 * h / 4 + cHeight - cYCenter),
201  };
202 
203  origCurs = new Rect[] {
204  new Rect(movedCurs[0]),
205  new Rect(movedCurs[1]),
206  new Rect(movedCurs[2]),
207  new Rect(movedCurs[3])
208  };
209 
210  }
211 
213  @Override
214  protected void onDraw(Canvas canvas) {
215  canvas.drawColor(0x00000000);
216 
217  canvas.drawLines(new float[] {
218  origCurs[0].left + cXCenter, origCurs[0].top + cYCenter, origCurs[1].left + cXCenter, origCurs[1].top + cYCenter,
219  origCurs[0].left + cXCenter, origCurs[0].top + cYCenter, origCurs[2].left + cXCenter, origCurs[2].top + cYCenter,
220  origCurs[1].left + cXCenter, origCurs[1].top + cYCenter, origCurs[3].left + cXCenter, origCurs[3].top + cYCenter,
221  origCurs[2].left + cXCenter, origCurs[2].top + cYCenter, origCurs[3].left + cXCenter, origCurs[3].top + cYCenter
222  }, origPaint);
223 
224  for (Rect r : origCurs) {
225  canvas.drawBitmap(cNormal, null, r, origPaint);
226  }
227 
228  canvas.drawLines(new float[] {
229  movedCurs[0].left + cXCenter, movedCurs[0].top + cYCenter, movedCurs[1].left + cXCenter, movedCurs[1].top + cYCenter,
230  movedCurs[0].left + cXCenter, movedCurs[0].top + cYCenter, movedCurs[2].left + cXCenter, movedCurs[2].top + cYCenter,
231  movedCurs[1].left + cXCenter, movedCurs[1].top + cYCenter, movedCurs[3].left + cXCenter, movedCurs[3].top + cYCenter,
232  movedCurs[2].left + cXCenter, movedCurs[2].top + cYCenter, movedCurs[3].left + cXCenter, movedCurs[3].top + cYCenter
233  }, lnPaint);
234 
235  for (Rect r : movedCurs) {
236  if (r == selCur) {
237  canvas.drawBitmap(cPressed, null, r, null);
238  } else {
239  canvas.drawBitmap(cNormal, null, r, null);
240  }
241  }
242 
243 
244  }
245 
247  @Override
248  public boolean onTouchEvent(MotionEvent ev) {
249  float x = ev.getX();
250  float y = ev.getY();
251 
252  switch (ev.getAction()) {
253  case MotionEvent.ACTION_DOWN:
254  for (Rect r : movedCurs) {
255  if (r.contains((int) x, (int) y)) {
256  selCur = r;
257  break;
258  }
259  }
260  if (selCur != null) {
261  lastX = x;
262  lastY = y;
263  if (listener != null) {
265  }
266  }
267  break;
268  case MotionEvent.ACTION_MOVE:
269  if (selCur != null) {
270  selCur.offset((int) (x - lastX), (int) (y - lastY));
271  lastX = x;
272  lastY = y;
273  if (listener != null) {
275  }
276  invalidate();
277  }
278  break;
279  case MotionEvent.ACTION_UP:
280  if (selCur != null) {
281  selCur = null;
282  if (listener != null) {
284  }
285  invalidate();
286  }
287  break;
288  }
289 
290  return true;
291  }
292 }