App

- Main Page
- Related Pages
- Namespaces
- Classes
- Files

- File List
- File Members

RoundBrushPickerView.java
Go to the documentation of this file.
1 package mhr.appandroid.views.brushpicker;
2
3 import mhr.appandroid.R;
4 import mhr.appandroid.adapters.APDBitmap;
5 import mhr.appandroid.views.MaskView;
6 import mhr.appandroid.views.MaskView.OnMaskCanvasChangedListener;
7 import mhr.appcore.bitmap.Depth;
8 import mhr.appcore.bitmap.NBitmap;
9 import mhr.appcore.generators.BrushGenerator;
10 import android.app.Activity;
11 import android.content.Context;
12 import android.graphics.BitmapFactory;
13 import android.graphics.BitmapShader;
14 import android.graphics.Paint;
15 import android.graphics.Shader.TileMode;
16 import android.util.AttributeSet;
17 import android.view.View;
18 import android.view.View.OnClickListener;
19 import android.widget.Button;
20 import android.widget.CheckBox;
21 import android.widget.CompoundButton;
22 import android.widget.CompoundButton.OnCheckedChangeListener;
23 import android.widget.FrameLayout;
24 import android.widget.SeekBar;
25 import android.widget.SeekBar.OnSeekBarChangeListener;
26 import android.widget.TextView;
27
32 public class RoundBrushPickerView extends FrameLayout implements OnSeekBarChangeListener, OnMaskCanvasChangedListener, OnCheckedChangeListener, OnClickListener {
33
34 //===== INTERFACES, CLASSES, ENUMS ==========================================================================================================//
35 //----- NON-PUBLIC --------------------------------------------------------------------------------------------------------------------------//
40 protected class RoundBrushParams {
41 public int size = 20;
42 public double hardness = 1.0;
43 }
44 //----- PUBLIC ------------------------------------------------------------------------------------------------------------------------------//
48 public static enum RoundBrushPickerEvent {
49 EVENT_SELECTED,
50 EVENT_CANCELED,
51 EVENT_CHANGED,
52 // EVENT_SELECTION_CHANGED, ///< Voláno v okamžiku, kdy uživatel pustí SeekBar a vybere takto štětec.
53 EVENT_LIVE_PREVIEW_STATE_CHANGED
54 }
55
59 public static interface RoundBrushPickerViewEventListener {
65 public void onRoundBrushPickerEvent(RoundBrushPickerEvent e, RoundBrushPickerView v);
66 }
67
68 //===== FIELDS ==============================================================================================================================//
69 //----- NON-PUBLIC --------------------------------------------------------------------------------------------------------------------------//
70 protected SeekBar sizeSB;
71 protected SeekBar hardnessSB;
72 protected CheckBox livePreviewChB;
73 protected Button selectBtn;
74 protected Button cancelBtn;
75 protected MaskView previewMskV;
76 protected TextView sizeTV;
77 protected TextView hardnessTV;
78 protected boolean livePreview;
79 protected NBitmap previewCanvas = null;
80 protected NBitmap newBrush = null;
81 protected RoundBrushParams oldParams = new RoundBrushParams();
82 protected RoundBrushParams newParams = new RoundBrushParams();
83 protected RoundBrushPickerViewEventListener listener = null;
84
85 // protected OnRoundBrushSelectedListener selectListener = null;
86 // protected OnRoundBrushChangedListener changedListener = null;
87 // protected OnRoundBrushCanceledListener canceledListener = null;
88 // protected OnRoundBrushLivePreviewChangeListener previewChangeListener = null;
89 // protected OnRoundBrushFirstCreatedListener createdListener = null;
90 //----- PUBLIC ------------------------------------------------------------------------------------------------------------------------------//
91
92 //===== CONSTRUCTORS, DESTRUCTORS, RELATED METHODS ==========================================================================================//
93 //----- NON-PUBLIC --------------------------------------------------------------------------------------------------------------------------//
97 protected void init() {
98 try {
99 ((Activity) getContext()).getLayoutInflater().inflate(R.layout.view_brush_picker, this, true);
100 } catch (ClassCastException exc) {
101 // Tento kod probehne, pokud je poroblem s pretypovanim, napriklad pro nahled v Eclipse
102 TextView tv = new TextView(getContext());
103 tv.setText("Prewiew not available, requires Activity to be Context.");
104 addView(tv);
105 return;
106 }
107
108 // Nalezení potomků pro rychlý přístup
109 sizeSB = (SeekBar) findViewById(R.id.SizeValueSB);
110 hardnessSB = (SeekBar) findViewById(R.id.HardnessValueSB);
111 livePreviewChB = (CheckBox) findViewById(R.id.RoundBrushLivePreviewChckB);
112 sizeTV = (TextView) findViewById(R.id.SizeValueTV);
113 hardnessTV = (TextView) findViewById(R.id.HardnessValueTV);
114 previewMskV = (MaskView) findViewById(R.id.RoundBrushPreviewMskV);
115 selectBtn = (Button) findViewById(R.id.RoundBrushPickerSelectBtn);
116 cancelBtn = (Button) findViewById(R.id.RoundBrushPickerCancelBtn);
117
118 // Inicializace stavu třídy
119 livePreview = livePreviewChB.isChecked();
120
121 // Nastavení vzhledu komponent
122 BitmapShader bsh = new BitmapShader(BitmapFactory.decodeResource(getResources(), R.drawable.checkboard), TileMode.REPEAT, TileMode.REPEAT);
123 previewMskV.getMaskViewBackground().setShader(bsh);
124
125 // Nastavení sebe jako posluchačů příslušných událostí.
126 sizeSB.setOnSeekBarChangeListener(this);
127 hardnessSB.setOnSeekBarChangeListener(this);
128 previewMskV.setOnMaskCanvasChangedListener(this);
129 livePreviewChB.setOnCheckedChangeListener(this);
130 selectBtn.setOnClickListener(this);
131 cancelBtn.setOnClickListener(this);
132
133 oldParams.size = 10;
134 oldParams.hardness = 0.5;
135 newParams.size = 10;
136 newParams.hardness = 0.5;
137
138 updateLabels();
139 updateSeekBars();
140 }
141
143 @Override
144 protected void onDetachedFromWindow() {
145 if (previewCanvas != null) {
146 previewCanvas.dispose();
147 previewCanvas = null;
148 }
149 if (newBrush != null) {
150 newBrush.dispose();
151 newBrush = null;
152 }
153 }
154
155 //----- PUBLIC ------------------------------------------------------------------------------------------------------------------------------//
156 public RoundBrushPickerView(Context context) {
157 super(context);
158 init();
159 }
160
161 public RoundBrushPickerView(Context context, AttributeSet attrs) {
162 super(context, attrs);
163 init();
164 }
165
166 public RoundBrushPickerView(Context context, AttributeSet attrs, int defStyle) {
167 super(context, attrs, defStyle);
168 init();
169 }
170
171 //===== METHODS =============================================================================================================================//
172 //----- NON-PUBLIC --------------------------------------------------------------------------------------------------------------------------//
176 protected void updateSeekBars() {
177 hardnessSB.setProgress((int) (100 * newParams.hardness + 0.5));
178 sizeSB.setProgress((int) ((1000.0 / 3.0) * Math.log10(newParams.size) + 0.5));
179 }
180
184 protected void updateLabels() {
185 sizeTV.setText(Integer.toString(newParams.size));
186 hardnessTV.setText(Integer.toString((int) (newParams.hardness * 100 + 0.5)));
187 }
188
192 protected void recreateBrush() {
193 if (newBrush != null) {
194 newBrush.dispose();
195 newBrush = null;
196 }
197 newBrush = BrushGenerator.createRoundBrush(newParams.size, newParams.hardness, Depth.DEPTH_8_BIT);
198 }
199
206 protected void redrawBrush() {
207 if (newBrush == null) {
208 recreateBrush();
209 }
210 if (previewCanvas == null) {
211 if (!initPreviewCanvas(previewMskV)) {
212 return;
213 }
214 }
215 previewCanvas.fill(previewCanvas.getRect(), 0x00);
216 newBrush.copyTo(previewCanvas, newBrush.getRect(), (int) ((previewCanvas.getWidth() - newBrush.getWidth()) / 2),
217 (int) ((previewCanvas.getHeight() - newBrush.getHeight()) / 2));
218 previewMskV.invalidate();
219 }
220
226 protected boolean initPreviewCanvas(MaskView view) {
227 if (previewCanvas != null) {
228 previewCanvas.dispose();
229 previewCanvas = null;
230 }
231 APDBitmap maskCanvas = view.getMaskCanvas();
232 if (maskCanvas == null) {
233 return false;
234 } else {
235 previewCanvas = new NBitmap(maskCanvas);
236 return true;
237 }
238 }
239
243 protected void updateValues() {
244 newParams.size = (int) (Math.pow(1000, sizeSB.getProgress() / 1000.0) + 0.5);
245 newParams.hardness = hardnessSB.getProgress() / 100.0;
246 }
247
251 protected void updateStateFromSeekBars() {
252 updateValues();
253 recreateBrush();
254 redrawBrush();
255 updateLabels();
256 }
257
261 protected void updateStateFromParams() {
262 updateSeekBars();
263 recreateBrush(); // Toto se volá na začátku redraw
264 redrawBrush();
265 updateLabels();
266 }
267
268 //----- PUBLIC ------------------------------------------------------------------------------------------------------------------------------//
273 public void setZoom(double zoom) {
274 previewMskV.setZoom(zoom);
275 }
276
281 public double getZoom() {
282 return previewMskV.getZoom();
283 }
284
289 public void setSize(int size) {
290 newParams.size = size;
291 updateStateFromParams();
292 }
293
298 public int getSize() {
299 return newParams.size;
300 }
301
306 public void setHardness(double hardness) {
307 newParams.hardness = hardness;
308 updateStateFromParams();
309 }
310
315 public double getHardness() {
316 return newParams.hardness;
317 }
318
323 public NBitmap getOldBrush() {
324 return BrushGenerator.createRoundBrush(oldParams.size, oldParams.hardness, Depth.DEPTH_8_BIT);
325 }
326
331 public Paint getPreviewBackground() {
332 return previewMskV.getMaskViewBackground();
333 }
334
339 public Paint getPreviewForeground() {
340 return previewMskV.getMaskViewForeground();
341 }
342
347 public NBitmap getNewBrush() {
348 if (newBrush != null) {
349 return new NBitmap(newBrush);
350 } else {
351 return BrushGenerator.createRoundBrush(newParams.size, newParams.hardness, Depth.DEPTH_8_BIT);
352 }
353 }
354
360 public void setState(int size, double hardness) {
361 oldParams.size = size;
362 oldParams.hardness = hardness;
363 newParams.size = size;
364 newParams.hardness = hardness;
365 updateStateFromParams();
366 }
367
372 public boolean isLivePreviewOn() {
373 return livePreview;
374 }
375
380 public void setLivePreview(boolean val) {
381 livePreview = val;
382 livePreviewChB.setChecked(val);
383 }
384
389 public void setRoundBrushPickerListener(RoundBrushPickerViewEventListener l) {
390 listener = l;
391 }
392
396 public void doSelectAction() {
397 oldParams.size = newParams.size;
398 oldParams.hardness = newParams.hardness;
399 }
400
404 public void doCancelAction() {
405 newParams.size = oldParams.size;
406 newParams.hardness = oldParams.hardness;
407 updateSeekBars();
408 updateStateFromSeekBars();
409 }
410
411
412 @Override
413 public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
414 if (fromUser) {
415 if (livePreview) {
416 updateStateFromSeekBars();
417 } else {
418 updateValues();
419 updateLabels();
420 }
421 if (listener != null) {
422 listener.onRoundBrushPickerEvent(RoundBrushPickerEvent.EVENT_CHANGED, this);
423 }
424 }
425 }
426
427 @Override
428 public void onStartTrackingTouch(SeekBar seekBar) {
429 // Nepouzity callback
430 }
431
432 @Override
433 public void onStopTrackingTouch(SeekBar seekBar) {
434 if (!livePreview) {
435 updateStateFromSeekBars();
436 }
437 if (listener != null) {
438 listener.onRoundBrushPickerEvent(RoundBrushPickerEvent.EVENT_CHANGED, this);
439 }
440 }
441
442 @Override
443 public void onMaskCanvasChanged(MaskView v) {
444 initPreviewCanvas(previewMskV);
445 redrawBrush();
446 }
447
448 @Override
449 public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
450 livePreview = isChecked;
451 if (listener != null) {
452 listener.onRoundBrushPickerEvent(RoundBrushPickerEvent.EVENT_LIVE_PREVIEW_STATE_CHANGED, this);
453 }
454 }
455
456 @Override
457 public void onClick(View v) {
458 if (v == selectBtn) {
459 doSelectAction();
460 if (listener != null) {
461 listener.onRoundBrushPickerEvent(RoundBrushPickerEvent.EVENT_SELECTED, this);
462 }
463 } else if (v == cancelBtn) {
464 doCancelAction();
465 if (listener != null) {
466 listener.onRoundBrushPickerEvent(RoundBrushPickerEvent.EVENT_CHANGED, this);
467 }
468 if (listener != null) {
469 listener.onRoundBrushPickerEvent(RoundBrushPickerEvent.EVENT_CANCELED, this);
470 }
471 }
472 }
473 }