App
PointOperationBrushToolSettingsFragment.java
Go to the documentation of this file.
1 package mhr.app.fragments.toolbox;
2 
3 import java.util.ArrayList;
4 
5 import mhr.app.AppMainActivity;
6 import mhr.app.R;
7 import mhr.app.touchlisteners.BrushToolTouchListener;
8 import mhr.appandroid.views.CurvesView;
9 import mhr.appandroid.views.CurvesView.CurvesViewChangeListener;
10 import mhr.appandroid.views.LabelledSeekBar;
11 import mhr.appandroid.views.LabelledSeekBar.LabelledSBChangeListener;
12 import mhr.appandroid.views.brushpicker.RoundBrushPickerView;
13 import mhr.appandroid.views.brushpicker.RoundBrushPickerView.RoundBrushPickerEvent;
14 import mhr.appandroid.views.brushpicker.RoundBrushPickerView.RoundBrushPickerViewEventListener;
15 import mhr.appandroid.views.pathpicker.PathPickerView;
16 import mhr.appandroid.views.pathpicker.PathPickerView.PathParams;
17 import mhr.appandroid.views.pathpicker.PathPickerView.PathPickerEvent;
18 import mhr.appandroid.views.pathpicker.PathPickerView.PathPickerViewEventListener;
19 import mhr.appcore.bitmap.NBitmap;
20 import mhr.appcore.commands.toolcommands.SelectToolCommand;
21 import mhr.appcore.image.Image;
22 import mhr.appcore.tools.Tool;
23 import mhr.appcore.tools.actiondata.ToolActionData;
24 import mhr.appcore.tools.brushlike.BrightnessLUTBrush;
25 import mhr.appcore.tools.brushlike.ContrastLUTBrush;
26 import mhr.appcore.tools.brushlike.CurvesLUTBrush;
27 import mhr.appcore.tools.brushlike.GammaLUTBrush;
28 import mhr.appcore.tools.exceptions.ToolNotApplicableException;
29 import mhr.appcore.utils.Rect;
30 import android.app.Activity;
31 import android.app.Fragment;
32 import android.os.Bundle;
33 import android.util.SparseArray;
34 import android.view.LayoutInflater;
35 import android.view.View;
36 import android.view.View.OnClickListener;
37 import android.view.ViewGroup;
38 import android.widget.AdapterView;
39 import android.widget.AdapterView.OnItemSelectedListener;
40 import android.widget.ArrayAdapter;
41 import android.widget.Button;
42 import android.widget.FrameLayout;
43 import android.widget.RadioGroup;
44 import android.widget.SeekBar;
45 import android.widget.Spinner;
46 import android.widget.Toast;
47 
52  OnItemSelectedListener {
53 
54  //===== INTERFACES, CLASSES, ENUMS ==========================================================================================================//
55  protected interface ToolPicker {
56  public void onPickerActivated();
57 
58  public void setTool(NBitmap brush, double opacity, double flow, double spacing);
59 
60  public void onPickerDeactivated();
61  }
62 
63  //----- NON-PUBLIC --------------------------------------------------------------------------------------------------------------------------//
64  //----- PUBLIC ------------------------------------------------------------------------------------------------------------------------------//
65 
66  //===== FIELDS ==============================================================================================================================//
67  //----- NON-PUBLIC --------------------------------------------------------------------------------------------------------------------------//
68  protected View root;
70  protected boolean firstCreated = true;
71 
74  protected boolean pathLivePreviewOn;
76 
77  protected FrameLayout settingsPlaceholder;
78  protected ArrayList<ToolPicker> toolPickers = new ArrayList<PointOperationBrushToolSettingsFragment.ToolPicker>();
79  protected ToolPicker tp;
80 
81  protected Spinner opPicker;
82 
83  //----- PUBLIC ------------------------------------------------------------------------------------------------------------------------------//
84 
85  //===== CONSTRUCTORS, DESTRUCTORS, RELATED METHODS ==========================================================================================//
86  //----- NON-PUBLIC --------------------------------------------------------------------------------------------------------------------------//
90  protected View initView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
91  root = inflater.inflate(R.layout.fragment_point_operation_brush_tool_settings, container, false);
92 
93  brushPicker = (RoundBrushPickerView) root.findViewById(R.id.PointOperationBrushRoundBrushPicker);
95 
96  pathPicker = (PathPickerView) root.findViewById(R.id.PointOperationBrushPathPicker);
98 
99  settingsPlaceholder = (FrameLayout) root.findViewById(R.id.PointOpBrushToolSpecSettingsPlaceholder);
100 
101  opPicker = (Spinner) root.findViewById(R.id.PointOpBrushOperationPickerSP);
102  ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(activity, R.array.PointOpBrushNames, android.R.layout.simple_spinner_item);
103  adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
104  opPicker.setAdapter(adapter);
105  opPicker.setOnItemSelectedListener(this);
106 
107  toolPickers.add(new ToolPicker() {
108 
109  LabelledSeekBar sb = null;
110 
111  @Override
112  public void setTool(NBitmap brush, double opacity, double flow, double spacing) {
113  activity.addCommand(new SelectToolCommand(new BrightnessLUTBrush(brush, opacity, flow, spacing, sb.getProgress())));
114  }
115 
116  @Override
117  public void onPickerActivated() {
118  if (sb == null) {
119  activity.getLayoutInflater().inflate(R.layout.point_op_brush_settings_brightness, settingsPlaceholder, true);
120  sb = (LabelledSeekBar) settingsPlaceholder.findViewById(R.id.PointOpBrushBrightnessSettings);
121  } else {
122  settingsPlaceholder.addView(sb);
123  }
124  }
125 
126  @Override
127  public void onPickerDeactivated() {
128  settingsPlaceholder.removeAllViews();
129 
130  }
131  });
132 
133  toolPickers.add(new ToolPicker() {
134 
135  LabelledSeekBar sb = null;
136 
137  @Override
138  public void setTool(NBitmap brush, double opacity, double flow, double spacing) {
139  activity.addCommand(new SelectToolCommand(new ContrastLUTBrush(brush, opacity, flow, spacing, sb.getProgress())));
140  }
141 
142  @Override
143  public void onPickerActivated() {
144  if (sb == null) {
145  activity.getLayoutInflater().inflate(R.layout.point_op_brush_settings_contrast, settingsPlaceholder, true);
146  sb = (LabelledSeekBar) settingsPlaceholder.findViewById(R.id.PointOpBrushContrastSettings);
147  } else {
148  settingsPlaceholder.addView(sb);
149  }
150  }
151 
152  @Override
153  public void onPickerDeactivated() {
154  settingsPlaceholder.removeAllViews();
155 
156  }
157  });
158 
159  toolPickers.add(new ToolPicker() {
160 
161  LabelledSeekBar sb = null;
162 
163  @Override
164  public void setTool(NBitmap brush, double opacity, double flow, double spacing) {
165  activity.addCommand(new SelectToolCommand(new GammaLUTBrush(brush, opacity, flow, spacing, sb.getProgress())));
166  }
167 
168  @Override
169  public void onPickerActivated() {
170  if (sb == null) {
171  activity.getLayoutInflater().inflate(R.layout.point_op_brush_settings_gamma, settingsPlaceholder, true);
172  sb = (LabelledSeekBar) settingsPlaceholder.findViewById(R.id.PointOpBrushGammaSettings);
173  } else {
174  settingsPlaceholder.addView(sb);
175  }
176  }
177 
178  @Override
179  public void onPickerDeactivated() {
180  settingsPlaceholder.removeAllViews();
181 
182  }
183  });
184 
185  toolPickers.add(new ToolPicker() {
186 
187  protected View toolRoot;
188 
189  protected CurvesView MV;
190  protected CurvesView RV;
191  protected CurvesView GV;
192  protected CurvesView BV;
193  protected CurvesView AV;
194  protected Spinner ChSp;
195 
196  protected CurvesView selected;
197 
198  protected float[][] defVals = new float[][] {
199  {0.0f, 1.0f},
200  {0.0f, 1.0f}
201  };
202 
203  @Override
204  public void setTool(NBitmap brush, double opacity, double flow, double spacing) {
205  activity.addCommand(new SelectToolCommand(new CurvesLUTBrush(brush, opacity, flow, spacing, MV.getPoints(), RV.getPoints(), GV.getPoints(), BV.getPoints(), AV.getPoints())));
206 
207  }
208 
209  @Override
210  public void onPickerActivated() {
211  if (toolRoot == null) {
212  toolRoot = activity.getLayoutInflater().inflate(R.layout.point_op_brush_settings_curves, settingsPlaceholder, true);
213  ChSp = (Spinner) toolRoot.findViewById(R.id.ChannelSp);
214 
215  ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(activity, R.array.CurvesChannelNames, android.R.layout.simple_spinner_item);
216  adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
217  ChSp.setAdapter(adapter);
218  ChSp.setOnItemSelectedListener( new OnItemSelectedListener() {
219 
220  @Override
221  public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
222  selected.setVisibility(View.GONE);
223  switch (position) {
224  case 0:
225  selected = MV;
226  break;
227  case 1:
228  selected = RV;
229  break;
230  case 2:
231  selected = GV;
232  break;
233  case 3:
234  selected = BV;
235  break;
236  case 4:
237  selected = AV;
238  break;
239  }
240  selected.setVisibility(View.VISIBLE);
241  }
242 
243  @Override
244  public void onNothingSelected(AdapterView<?> parent) {
245 
246  }
247  });
248 
249  MV = (CurvesView) toolRoot.findViewById(R.id.CurvesMaster);
250  RV = (CurvesView) toolRoot.findViewById(R.id.CurvesRed);
251  GV = (CurvesView) toolRoot.findViewById(R.id.CurvesGreen);
252  BV = (CurvesView) toolRoot.findViewById(R.id.CurvesBlue);
253  AV = (CurvesView) toolRoot.findViewById(R.id.CurvesAplha);
254  selected = MV;
255 
256  toolRoot.findViewById(R.id.CurvesCancelBtn).setOnClickListener(new OnClickListener() {
257 
258  @Override
259  public void onClick(View v) {
260  MV.setPoints(defVals);
261  RV.setPoints(defVals);
262  GV.setPoints(defVals);
263  BV.setPoints(defVals);
264  AV.setPoints(defVals);
265  }
266  });
267 
268  toolRoot.findViewById(R.id.CurvesSelectBtn).setOnClickListener(new OnClickListener() {
269 
270  @Override
271  public void onClick(View v) {
272  setBrush();
273  }
274  });
275 
276 
277  } else {
278  settingsPlaceholder.addView(toolRoot);
279  }
280  }
281 
282  @Override
283  public void onPickerDeactivated() {
284  settingsPlaceholder.removeAllViews();
285  }
286  });
287 
288  tp = toolPickers.get(0);
290 
292  selectPointOperationBrushToolBtn = (Button) root.findViewById(R.id.SelectPointOperationBrushToolBtn);
293  selectPointOperationBrushToolBtn.setOnClickListener(this);
294  firstCreated = false;
295 
296  return root;
297  }
298 
299  //----- PUBLIC ------------------------------------------------------------------------------------------------------------------------------//
300 
301  //===== METHODS =============================================================================================================================//
302  //----- NON-PUBLIC --------------------------------------------------------------------------------------------------------------------------//
306  protected void setBrush() {
307  tp = toolPickers.get(opPicker.getSelectedItemPosition());
308  if (tp != null) {
310  tp.setTool(brushPicker.getNewBrush(), pp.opacity / 100.0, pp.flow / 100.0, brushPicker.getSize() * pp.spacing / 100.0);
311  }
312 
313 // activity.addCommand(new SelectToolCommand(new BrightnessLUTBrush(brushPicker.getNewBrush(), pp.opacity / 100.0, pp.flow / 100.0, brushPicker.getSize() * pp.spacing / 100.0, (biasSeekBar.getProgress() - 100) / 100.0)));
314  }
315 
316  //----- PUBLIC ------------------------------------------------------------------------------------------------------------------------------//
317 
318  //===== CALLBACKS ===========================================================================================================================//
319 
320  @Override
321  public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
322  if (tp != null) {
324  }
325  tp = toolPickers.get(position);
327  }
328 
329  @Override
330  public void onNothingSelected(AdapterView<?> parent) {
331 
332  }
333 
334  @Override
335  public void onClick(View v) {
336  int id = v.getId();
337  switch (id) {
338  case R.id.SelectPointOperationBrushToolBtn:
339  setBrush();
340  }
341  }
342 
343  @Override
345  switch (e) {
346  case EVENT_SELECTED:
347  if (!pathLivePreviewOn) {
348  NBitmap tmp = v.getNewBrush();
349  pathPicker.setBrush(tmp);
350  tmp.dispose();
351  }
352  setBrush();
353 
354  break;
355 
356  case EVENT_CANCELED:
357  if (!pathLivePreviewOn) {
358  NBitmap tmp = v.getNewBrush();
359  pathPicker.setBrush(tmp);
360  tmp.dispose();
361  }
362 
363  break;
364 
365  case EVENT_CHANGED:
366  if (pathLivePreviewOn) {
367  NBitmap tmp = v.getNewBrush();
368  pathPicker.setBrush(tmp);
369  tmp.dispose();
370  }
371 
372  break;
373 
374  case EVENT_LIVE_PREVIEW_STATE_CHANGED:
375 
376  break;
377 
378  default:
379  break;
380  }
381 
382  }
383 
384  @Override
386  switch (e) {
387  case EVENT_SELECTED:
388  setBrush();
389  break;
390 
391  case EVENT_LIVE_PREVIEW_STATE_CHANGED:
393  if (pathLivePreviewOn) {
395  pathPicker.setBrush(tmp);
396  tmp.dispose();
397  }
398  break;
399  default:
400  break;
401  }
402 
403  }
404 
405  //----- LIFE CYCLE --------------------------------------------------------------------------------------------------------------------------//
406 
407  @Override
408  public void onAttach(Activity activity) {
409  super.onAttach(activity);
410  /*
411  * called once the fragment is associated with its activity.
412  */
413  this.activity = (AppMainActivity) activity;
414  }
415 
416  // @Override
417  // public void onCreate(Bundle savedInstanceState) {
418  // super.onCreate(savedInstanceState);
419  // /*
420  // * called to do initial creation of the fragment.
421  // *
422  // * The system calls this when creating the fragment. Within your implementation, you should initialize essential components of the fragment that you want
423  // * to retain when the fragment is paused or stopped, then resumed.
424  // */
425  // }
426 
427  @Override
428  public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
429  /*
430  * creates and returns the view hierarchy associated with the fragment.
431  *
432  * The system calls this when it's time for the fragment to draw its user interface for the first time. To draw a UI for your fragment, you must return a
433  * View from this method that is the root of your fragment's layout. You can return null if the fragment does not provide a UI.
434  *
435  * Zde začíná životní cyklus při návratu z backstacku
436  */
437  if (firstCreated) {
438  firstCreated = false;
439  return initView(inflater, container, savedInstanceState);
440  } else {
441  return root;
442  }
443  }
444 
445  // @Override
446  // public void onActivityCreated(Bundle savedInstanceState) {
447  // super.onActivityCreated(savedInstanceState);
448  // /*
449  // * tells the fragment that its activity has completed its own Activity.onCreate().
450  // */
451  // }
452 
453  // @Override // Vyžaduje API 17
454  // public void onViewStateRestored(Bundle savedInstanceState) {
455  // super.onViewStateRestored(savedInstanceState);
456  // /*
457  // * tells the fragment that all of the saved state of its view hierarchy has been restored.
458  // */
459  // }
460 
461  // @Override
462  // public void onStart() {
463  // super.onStart();
464  // /*
465  // * makes the fragment visible to the user (based on its containing activity being started).
466  // */
467  // }
468 
469  @Override
470  public void onResume() {
471  super.onResume();
472  /*
473  * makes the fragment interacting with the user (based on its containing activity being resumed).
474  */
475 // NBitmap brush = brushPicker.getNewBrush();
476 // pathPicker.setBrush(brush);
477 // brush.dispose();
478 // setBrush();
479 // PathParams pp = pathPicker.getNewPathParams();
480 // activity.app.addCommand(new SelectToolCommand(new AlphaBrush(brushPicker.getNewBrush(), BrushMode.MODE_ADD, pp.opacity / 100.0, pp.flow / 100.0, brushPicker.getSize()
481 // * pp.spacing / 100.0)));
483  }
484 
485  // @Override
486  // public void onPause() {
487  // super.onPause();
488  // /*
489  // * fragment is no longer interacting with the user either because its activity is being paused or a fragment operation is modifying it in the activity.
490  // *
491  // * The system calls this method as the first indication that the user is leaving the fragment (though it does not always mean the fragment is being destroyed).
492  // * This is usually where you should commit any changes that should be persisted beyond the current user session (because the user might not come back).
493  // */
494  // }
495 
496  // @Override
497  // public void onStop() {
498  // super.onStop();
499  // /*
500  // * fragment is no longer visible to the user either because its activity is being stopped or a fragment operation is modifying it in the activity.
501  // */
502  // }
503 
504  // @Override
505  // public void onDestroyView() {
506  // super.onDestroyView();
507  // /*
508  // * allows the fragment to clean up resources associated with its View.
509  // *
510  // * Zde končí životní cyklus při umístění do backstacku
511  // */
512  // }
513 
514  // @Override
515  // public void onDestroy() {
516  // super.onDestroy();
517  // /*
518  // * called to do final cleanup of the fragment's state.
519  // */
520  // }
521 
522  // @Override
523  // public void onDetach() {
524  // super.onDetach();
525  // /*
526  // * called immediately prior to the fragment no longer being associated with its activity.
527  // */
528  // }
529 }