FilterShowActivity.java revision c7b2c287bfbe3f53a4d65800c3884b0082ad683c
1
2package com.android.gallery3d.filtershow;
3
4import java.io.File;
5import java.io.IOException;
6import java.util.Vector;
7
8import com.android.gallery3d.filtershow.cache.ImageLoader;
9import com.android.gallery3d.filtershow.filters.*;
10import com.android.gallery3d.filtershow.imageshow.ImageBorder;
11import com.android.gallery3d.filtershow.imageshow.ImageShow;
12import com.android.gallery3d.filtershow.imageshow.ImageSmallFilter;
13import com.android.gallery3d.filtershow.imageshow.ImageStraighten;
14import com.android.gallery3d.filtershow.presets.*;
15import com.android.gallery3d.filtershow.provider.SharedImageProvider;
16import com.android.gallery3d.filtershow.tools.SaveCopyTask;
17import com.android.gallery3d.filtershow.ui.ImageCurves;
18import com.android.gallery3d.R;
19
20import android.net.Uri;
21import android.os.Bundle;
22import android.annotation.TargetApi;
23import android.app.ActionBar;
24import android.app.Activity;
25import android.content.ContentValues;
26import android.content.Intent;
27import android.content.res.Resources;
28import android.graphics.drawable.Drawable;
29import android.graphics.drawable.NinePatchDrawable;
30import android.util.Log;
31import android.util.TypedValue;
32import android.view.Gravity;
33import android.view.Menu;
34import android.view.MenuItem;
35import android.view.MotionEvent;
36import android.view.View;
37import android.view.View.OnClickListener;
38import android.view.View.OnTouchListener;
39import android.widget.AdapterView;
40import android.widget.AdapterView.OnItemClickListener;
41import android.widget.Button;
42import android.widget.FrameLayout;
43import android.widget.FrameLayout.LayoutParams;
44import android.widget.ImageButton;
45import android.widget.LinearLayout;
46import android.widget.ListView;
47import android.widget.ShareActionProvider;
48import android.widget.ShareActionProvider.OnShareTargetSelectedListener;
49import android.widget.Toast;
50
51@TargetApi(16)
52public class FilterShowActivity extends Activity implements OnItemClickListener,
53        OnShareTargetSelectedListener {
54
55    private ImageLoader mImageLoader = null;
56    private ImageShow mImageShow = null;
57    private ImageCurves mImageCurves = null;
58    private ImageBorder mImageBorders = null;
59    private ImageStraighten mImageStraighten = null;
60
61    private View mListFx = null;
62    private View mListBorders = null;
63    private View mListGeometry = null;
64    private View mListColors = null;
65
66    private ImageButton mFxButton = null;
67    private ImageButton mBorderButton = null;
68    private ImageButton mGeometryButton = null;
69    private ImageButton mColorsButton = null;
70
71    private ImageButton mVignetteButton = null;
72    private ImageButton mCurvesButtonRGB = null;
73    private ImageButton mSharpenButton = null;
74
75    private ImageButton mContrastButton = null;
76    private ImageButton mSaturationButton = null;
77    private ImageButton mTintButton = null;
78    private ImageButton mVibranceButton = null;
79    private ImageButton mExposureButton = null;
80    private ImageButton mShadowRecoveryButton = null;
81
82    private static final int SELECT_PICTURE = 1;
83    private static final String LOGTAG = "FilterShowActivity";
84    protected static final boolean ANIMATE_PANELS = false;
85
86    private boolean mShowingHistoryPanel = false;
87    private boolean mShowingImageStatePanel = false;
88
89    private Vector<ImageShow> mImageViews = new Vector<ImageShow>();
90    private Vector<View> mListViews = new Vector<View>();
91    private Vector<ImageButton> mBottomPanelButtons = new Vector<ImageButton>();
92    private Vector<ImageButton> mColorsPanelButtons = new Vector<ImageButton>();
93
94    private ShareActionProvider mShareActionProvider;
95    private File mSharedOutputFile = null;
96
97    private boolean mSharingImage = false;
98
99    @Override
100    public void onCreate(Bundle savedInstanceState) {
101        super.onCreate(savedInstanceState);
102
103        setContentView(R.layout.filtershow_activity);
104        ActionBar actionBar = getActionBar();
105        actionBar.setDisplayOptions(ActionBar.DISPLAY_SHOW_CUSTOM);
106        actionBar.setCustomView(R.layout.filtershow_actionbar);
107
108        actionBar.getCustomView().setOnClickListener(new OnClickListener() {
109            @Override
110            public void onClick(View view) {
111                saveImage();
112            }
113        });
114
115        mImageLoader = new ImageLoader(getApplicationContext());
116
117        LinearLayout listFilters = (LinearLayout) findViewById(R.id.listFilters);
118        LinearLayout listBorders = (LinearLayout) findViewById(R.id.listBorders);
119
120        mImageShow = (ImageShow) findViewById(R.id.imageShow);
121        mImageCurves = (ImageCurves) findViewById(R.id.imageCurves);
122        mImageBorders = (ImageBorder) findViewById(R.id.imageBorder);
123        mImageStraighten = (ImageStraighten) findViewById(R.id.imageStraighten);
124
125        mImageViews.add(mImageShow);
126        mImageViews.add(mImageCurves);
127        mImageViews.add(mImageBorders);
128        mImageViews.add(mImageStraighten);
129
130        mListFx = findViewById(R.id.fxList);
131        mListBorders = findViewById(R.id.bordersList);
132        mListGeometry = findViewById(R.id.gemoetryList);
133        mListColors = findViewById(R.id.colorsFxList);
134        mListViews.add(mListFx);
135        mListViews.add(mListBorders);
136        mListViews.add(mListGeometry);
137        mListViews.add(mListColors);
138
139        mFxButton = (ImageButton) findViewById(R.id.fxButton);
140        mBorderButton = (ImageButton) findViewById(R.id.borderButton);
141        mGeometryButton = (ImageButton) findViewById(R.id.geometryButton);
142        mColorsButton = (ImageButton) findViewById(R.id.colorsButton);
143        mBottomPanelButtons.add(mFxButton);
144        mBottomPanelButtons.add(mBorderButton);
145        mBottomPanelButtons.add(mGeometryButton);
146        mBottomPanelButtons.add(mColorsButton);
147        mFxButton.setSelected(true);
148
149        mVignetteButton = (ImageButton) findViewById(R.id.vignetteButton);
150        mCurvesButtonRGB = (ImageButton) findViewById(R.id.curvesButtonRGB);
151        mSharpenButton = (ImageButton) findViewById(R.id.sharpenButton);
152        mVibranceButton = (ImageButton) findViewById(R.id.vibranceButton);
153        mContrastButton = (ImageButton) findViewById(R.id.contrastButton);
154        mSaturationButton = (ImageButton) findViewById(R.id.saturationButton);
155        mTintButton = (ImageButton) findViewById(R.id.tintButton);
156        mExposureButton = (ImageButton) findViewById(R.id.exposureButton);
157        mShadowRecoveryButton = (ImageButton) findViewById(R.id.shadowRecoveryButton);
158
159        mColorsPanelButtons.add(mVignetteButton);
160        mColorsPanelButtons.add(mCurvesButtonRGB);
161        mColorsPanelButtons.add(mSharpenButton);
162        mColorsPanelButtons.add(mContrastButton);
163        mColorsPanelButtons.add(mSaturationButton);
164        mColorsPanelButtons.add(mTintButton);
165        mColorsPanelButtons.add(mVibranceButton);
166        mColorsPanelButtons.add(mExposureButton);
167        mColorsPanelButtons.add(mShadowRecoveryButton);
168
169        // TODO: instead of click listeners, make the activity the single
170        // listener and do a dispatch in the listener callback method.
171        findViewById(R.id.showOriginalButton).setOnTouchListener(createOnTouchShowOriginalButton());
172        findViewById(R.id.straightenButton).setOnClickListener(createOnClickStraightenButton());
173        findViewById(R.id.cropButton).setOnClickListener(createOnClickCropButton());
174        findViewById(R.id.rotateButton).setOnClickListener(createOnClickRotateButton());
175        findViewById(R.id.flipButton).setOnClickListener(createOnClickFlipButton());
176
177        mVignetteButton.setOnClickListener(createOnClickVignetteButton());
178        mCurvesButtonRGB.setOnClickListener(createOnClickCurvesRGBButton());
179
180        mSharpenButton.setOnClickListener(createOnClickSharpenButton());
181        mContrastButton.setOnClickListener(createOnClickContrastButton());
182        mSaturationButton.setOnClickListener(createOnClickSaturationButton());
183
184        mTintButton.setOnClickListener(createOnClickTintButton());
185        mVibranceButton.setOnClickListener(createOnClickVibranceButton());
186        mExposureButton.setOnClickListener(createOnClickExposureButton());
187        mShadowRecoveryButton.setOnClickListener(createOnClickShadowRecoveryButton());
188
189        mFxButton.setOnClickListener(createOnClickFxButton());
190        mBorderButton.setOnClickListener(createOnClickBorderButton());
191        mGeometryButton.setOnClickListener(createOnClickGeometryButton());
192        mColorsButton.setOnClickListener(createOnClickColorsButton());
193
194        findViewById(R.id.resetOperationsButton).setOnClickListener(
195                createOnClickResetOperationsButton());
196
197        ListView operationsList = (ListView) findViewById(R.id.operationsList);
198        operationsList.setAdapter(mImageShow.getHistoryAdapter());
199        operationsList.setOnItemClickListener(this);
200        ListView imageStateList = (ListView) findViewById(R.id.imageStateList);
201        imageStateList.setAdapter(mImageShow.getImageStateAdapter());
202        mImageLoader.setAdapter((HistoryAdapter) mImageShow.getHistoryAdapter());
203
204        fillListImages(listFilters);
205        fillListBorders(listBorders);
206
207        mImageShow.setImageLoader(mImageLoader);
208        mImageCurves.setImageLoader(mImageLoader);
209        mImageCurves.setMaster(mImageShow);
210        mImageBorders.setImageLoader(mImageLoader);
211        mImageBorders.setMaster(mImageShow);
212        mImageStraighten.setImageLoader(mImageLoader);
213        mImageStraighten.setMaster(mImageShow);
214
215        Intent intent = getIntent();
216        String data = intent.getDataString();
217        if (data != null) {
218            Uri uri = Uri.parse(data);
219            mImageLoader.loadBitmap(uri);
220        } else {
221            pickImage();
222        }
223    }
224
225    public void completeSaveImage(Uri saveUri) {
226        if (mSharingImage && mSharedOutputFile != null) {
227            // Image saved, we unblock the content provider
228            Uri uri = Uri.withAppendedPath(SharedImageProvider.CONTENT_URI,
229                    Uri.encode(mSharedOutputFile.getAbsolutePath()));
230            ContentValues values = new ContentValues();
231            values.put(SharedImageProvider.PREPARE, false);
232            getContentResolver().insert(uri, values);
233        }
234        setResult(RESULT_OK, new Intent().setData(saveUri));
235        finish();
236    }
237
238    @Override
239    public boolean onShareTargetSelected(ShareActionProvider arg0, Intent arg1) {
240        // First, let's tell the SharedImageProvider that it will need to wait for the image
241        Uri uri = Uri.withAppendedPath(SharedImageProvider.CONTENT_URI,
242                Uri.encode(mSharedOutputFile.getAbsolutePath()));
243        ContentValues values = new ContentValues();
244        values.put(SharedImageProvider.PREPARE, true);
245        getContentResolver().insert(uri, values);
246        mSharingImage = true;
247
248        // Process and save the image in the background.
249        mImageShow.saveImage(this, mSharedOutputFile);
250        return true;
251    }
252
253    private Intent getDefaultShareIntent() {
254        Intent intent = new Intent(Intent.ACTION_SEND);
255        intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);
256        intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
257        intent.setType(SharedImageProvider.MIME_TYPE);
258        mSharedOutputFile = SaveCopyTask.getNewFile(this, mImageLoader.getUri());
259        Uri uri = Uri.withAppendedPath(SharedImageProvider.CONTENT_URI,
260                Uri.encode(mSharedOutputFile.getAbsolutePath()));
261        intent.putExtra(Intent.EXTRA_STREAM, uri);
262        return intent;
263    }
264
265    @Override
266    public boolean onCreateOptionsMenu(Menu menu) {
267        getMenuInflater().inflate(R.menu.filtershow_activity_menu, menu);
268        MenuItem showHistory = menu.findItem(R.id.operationsButton);
269        if (mShowingHistoryPanel) {
270            showHistory.setTitle(R.string.hide_history_panel);
271        } else {
272            showHistory.setTitle(R.string.show_history_panel);
273        }
274        MenuItem showState = menu.findItem(R.id.showImageStateButton);
275        if (mShowingImageStatePanel) {
276            showState.setTitle(R.string.hide_imagestate_panel);
277        } else {
278            showState.setTitle(R.string.show_imagestate_panel);
279        }
280        mShareActionProvider = (ShareActionProvider) menu.findItem(R.id.menu_share)
281                .getActionProvider();
282        mShareActionProvider.setShareIntent(getDefaultShareIntent());
283        mShareActionProvider.setOnShareTargetSelectedListener(this);
284        return true;
285    }
286
287    public boolean onOptionsItemSelected(MenuItem item) {
288        switch (item.getItemId()) {
289            case R.id.undoButton: {
290                HistoryAdapter adapter = (HistoryAdapter) mImageShow
291                        .getHistoryAdapter();
292                int position = adapter.undo();
293                mImageShow.onItemClick(position);
294                mImageShow.showToast("Undo");
295                invalidateViews();
296                return true;
297            }
298            case R.id.redoButton: {
299                HistoryAdapter adapter = (HistoryAdapter) mImageShow
300                        .getHistoryAdapter();
301                int position = adapter.redo();
302                mImageShow.onItemClick(position);
303                mImageShow.showToast("Redo");
304                invalidateViews();
305                return true;
306            }
307            case R.id.showImageStateButton: {
308                toggleImageStatePanel();
309                return true;
310            }
311            case R.id.operationsButton: {
312                toggleHistoryPanel();
313                return true;
314            }
315            case android.R.id.home: {
316                saveImage();
317                return true;
318            }
319        }
320        return false;
321    }
322
323    private void fillListImages(LinearLayout listFilters) {
324        // TODO: use listview
325        // TODO: load the filters straight from the filesystem
326        ImagePreset[] preset = new ImagePreset[9];
327        int p = 0;
328        preset[p++] = new ImagePreset();
329        preset[p++] = new ImagePresetSaturated();
330        preset[p++] = new ImagePresetOld();
331        preset[p++] = new ImagePresetXProcessing();
332        preset[p++] = new ImagePresetBW();
333        preset[p++] = new ImagePresetBWRed();
334        preset[p++] = new ImagePresetBWGreen();
335        preset[p++] = new ImagePresetBWBlue();
336
337        for (int i = 0; i < p; i++) {
338            ImageSmallFilter filter = new ImageSmallFilter(getBaseContext());
339            preset[i].setIsFx(true);
340            filter.setImagePreset(preset[i]);
341            filter.setController(this);
342            filter.setImageLoader(mImageLoader);
343            listFilters.addView(filter);
344        }
345
346        // Default preset (original)
347        mImageShow.setImagePreset(preset[0]);
348    }
349
350    private void fillListBorders(LinearLayout listBorders) {
351        // TODO: use listview
352        // TODO: load the borders straight from the filesystem
353        int p = 0;
354        ImageFilter[] borders = new ImageFilter[8];
355        borders[p++] = new ImageFilterBorder(null);
356
357        Drawable npd3 = getResources().getDrawable(R.drawable.filtershow_border_film3);
358        borders[p++] = new ImageFilterBorder(npd3);
359        Drawable npd = getResources().getDrawable(
360                R.drawable.filtershow_border_scratch3);
361        borders[p++] = new ImageFilterBorder(npd);
362        Drawable npd2 = getResources().getDrawable(R.drawable.filtershow_border_black);
363        borders[p++] = new ImageFilterBorder(npd2);
364        Drawable npd6 = getResources().getDrawable(
365                R.drawable.filtershow_border_rounded_black);
366        borders[p++] = new ImageFilterBorder(npd6);
367        Drawable npd4 = getResources().getDrawable(R.drawable.filtershow_border_white);
368        borders[p++] = new ImageFilterBorder(npd4);
369        Drawable npd5 = getResources().getDrawable(
370                R.drawable.filtershow_border_rounded_white);
371        borders[p++] = new ImageFilterBorder(npd5);
372
373        for (int i = 0; i < p; i++) {
374            ImageSmallFilter filter = new ImageSmallFilter(getBaseContext());
375            filter.setImageFilter(borders[i]);
376            filter.setController(this);
377            filter.setImageLoader(mImageLoader);
378            filter.setShowTitle(false);
379            listBorders.addView(filter);
380        }
381    }
382
383    // //////////////////////////////////////////////////////////////////////////////
384    // Some utility functions
385
386    public void showOriginalViews(boolean value) {
387        for (ImageShow views : mImageViews) {
388            views.showOriginal(value);
389        }
390    }
391
392    public void invalidateViews() {
393        for (ImageShow views : mImageViews) {
394            views.invalidate();
395        }
396    }
397
398    public void hideListViews() {
399        for (View view : mListViews) {
400            view.setVisibility(View.GONE);
401        }
402    }
403
404    public void hideImageViews() {
405        mImageShow.setShowControls(false); // reset
406        for (View view : mImageViews) {
407            view.setVisibility(View.GONE);
408        }
409    }
410
411    public void unselectBottomPanelButtons() {
412        for (ImageButton button : mBottomPanelButtons) {
413            button.setSelected(false);
414        }
415    }
416
417    public void unselectPanelButtons(Vector<ImageButton> buttons) {
418        for (ImageButton button : buttons) {
419            button.setSelected(false);
420        }
421    }
422
423    // //////////////////////////////////////////////////////////////////////////////
424    // Click handlers for the top row buttons
425
426    private OnTouchListener createOnTouchShowOriginalButton() {
427        return new View.OnTouchListener() {
428            @Override
429            public boolean onTouch(View v, MotionEvent event) {
430                boolean show = false;
431                if ((event.getActionMasked() != MotionEvent.ACTION_UP)
432                        || (event.getActionMasked() == MotionEvent.ACTION_CANCEL)) {
433                    show = true;
434                }
435                showOriginalViews(show);
436                return true;
437            }
438        };
439    }
440
441    // //////////////////////////////////////////////////////////////////////////////
442    // imageState panel...
443
444    private void toggleImageStatePanel() {
445        final View view = findViewById(R.id.mainPanel);
446        final View viewList = findViewById(R.id.imageStatePanel);
447
448        if (mShowingHistoryPanel) {
449            findViewById(R.id.historyPanel).setVisibility(View.INVISIBLE);
450            mShowingHistoryPanel = false;
451        }
452
453        if (!mShowingImageStatePanel) {
454            mShowingImageStatePanel = true;
455            view.animate().setDuration(200).x(-viewList.getWidth())
456                    .withLayer().withEndAction(new Runnable() {
457                        public void run() {
458                            viewList.setAlpha(0);
459                            viewList.setVisibility(View.VISIBLE);
460                            viewList.animate().setDuration(100)
461                                    .alpha(1.0f).start();
462                        }
463                    }).start();
464        } else {
465            mShowingImageStatePanel = false;
466            viewList.setVisibility(View.INVISIBLE);
467            view.animate().setDuration(200).x(0).withLayer()
468                    .start();
469        }
470        invalidateOptionsMenu();
471    }
472
473    // //////////////////////////////////////////////////////////////////////////////
474    // history panel...
475
476    private void toggleHistoryPanel() {
477        final View view = findViewById(R.id.mainPanel);
478        final View viewList = findViewById(R.id.historyPanel);
479
480        if (mShowingImageStatePanel) {
481            findViewById(R.id.imageStatePanel).setVisibility(View.INVISIBLE);
482            mShowingImageStatePanel = false;
483        }
484
485        if (!mShowingHistoryPanel) {
486            mShowingHistoryPanel = true;
487            view.animate().setDuration(200).x(-viewList.getWidth())
488                    .withLayer().withEndAction(new Runnable() {
489                        public void run() {
490                            viewList.setAlpha(0);
491                            viewList.setVisibility(View.VISIBLE);
492                            viewList.animate().setDuration(100)
493                                    .alpha(1.0f).start();
494                        }
495                    }).start();
496        } else {
497            mShowingHistoryPanel = false;
498            viewList.setVisibility(View.INVISIBLE);
499            view.animate().setDuration(200).x(0).withLayer()
500                    .start();
501        }
502        invalidateOptionsMenu();
503    }
504
505    private void resetHistory() {
506        HistoryAdapter adapter = (HistoryAdapter) mImageShow
507                .getHistoryAdapter();
508        adapter.reset();
509        ImagePreset original = new ImagePreset(adapter.getItem(0));
510        mImageShow.setImagePreset(original);
511        invalidateViews();
512    }
513
514    // reset button in the history panel.
515    private OnClickListener createOnClickResetOperationsButton() {
516        return new View.OnClickListener() {
517            @Override
518            public void onClick(View v) {
519                resetHistory();
520            }
521        };
522    }
523
524    // //////////////////////////////////////////////////////////////////////////////
525    // Now, let's deal with the bottom panel.
526
527    private OnClickListener createOnClickFxButton() {
528        return new View.OnClickListener() {
529            @Override
530            public void onClick(View v) {
531                hideImageViews();
532                hideListViews();
533                unselectBottomPanelButtons();
534                mImageShow.setVisibility(View.VISIBLE);
535                mListFx.setVisibility(View.VISIBLE);
536                mFxButton.setSelected(true);
537            }
538        };
539    }
540
541    private OnClickListener createOnClickBorderButton() {
542        return new View.OnClickListener() {
543            @Override
544            public void onClick(View v) {
545                hideImageViews();
546                hideListViews();
547                unselectBottomPanelButtons();
548                mImageBorders.setVisibility(View.VISIBLE);
549                mListBorders.setVisibility(View.VISIBLE);
550                mBorderButton.setSelected(true);
551            }
552        };
553    }
554
555    private OnClickListener createOnClickGeometryButton() {
556        return new View.OnClickListener() {
557            @Override
558            public void onClick(View v) {
559                hideImageViews();
560                hideListViews();
561                unselectBottomPanelButtons();
562                mImageStraighten.setVisibility(View.VISIBLE);
563                mListGeometry.setVisibility(View.VISIBLE);
564                mGeometryButton.setSelected(true);
565
566                if (ANIMATE_PANELS) {
567                    mListGeometry.setX(mListGeometry.getWidth());
568                    mListGeometry.animate().setDuration(200).x(0).withLayer().start();
569                }
570            }
571        };
572    }
573
574    private OnClickListener createOnClickColorsButton() {
575        return new View.OnClickListener() {
576            @Override
577            public void onClick(View v) {
578                hideImageViews();
579                hideListViews();
580                unselectBottomPanelButtons();
581                mListColors.setVisibility(View.VISIBLE);
582                mImageShow.setVisibility(View.VISIBLE);
583                mColorsButton.setSelected(true);
584
585                if (ANIMATE_PANELS) {
586                    View view = findViewById(R.id.listColorsFx);
587                    view.setX(mListColors.getWidth());
588                    view.animate().setDuration(200).x(0).withLayer().start();
589                }
590            }
591        };
592    }
593
594    // //////////////////////////////////////////////////////////////////////////////
595    // Geometry sub-panel
596
597    private OnClickListener createOnClickStraightenButton() {
598        return new View.OnClickListener() {
599            @Override
600            public void onClick(View v) {
601                hideImageViews();
602                mImageStraighten.setVisibility(View.VISIBLE);
603                mImageStraighten.showToast("Straighten", true);
604            }
605        };
606    }
607
608    private OnClickListener createOnClickCropButton() {
609        return new View.OnClickListener() {
610            @Override
611            public void onClick(View v) {
612                hideImageViews();
613                mImageShow.setVisibility(View.VISIBLE);
614                mImageShow.showToast("Crop", true);
615            }
616        };
617    }
618
619    private OnClickListener createOnClickRotateButton() {
620        return new View.OnClickListener() {
621            @Override
622            public void onClick(View v) {
623                hideImageViews();
624                mImageShow.setVisibility(View.VISIBLE);
625                mImageShow.showToast("Rotate", true);
626            }
627        };
628    }
629
630    private OnClickListener createOnClickFlipButton() {
631        return new View.OnClickListener() {
632            @Override
633            public void onClick(View v) {
634                hideImageViews();
635                mImageShow.setVisibility(View.VISIBLE);
636                mImageShow.showToast("Flip", true);
637            }
638        };
639    }
640
641    // //////////////////////////////////////////////////////////////////////////////
642    // Filters sub-panel
643
644    private OnClickListener createOnClickVignetteButton() {
645        return new View.OnClickListener() {
646            @Override
647            public void onClick(View v) {
648                hideImageViews();
649                mImageShow.setVisibility(View.VISIBLE);
650                mImageShow.setShowControls(true);
651                ImagePreset preset = mImageShow.getImagePreset();
652                ImageFilter filter = preset.getFilter("Vignette");
653                if (filter == null) {
654                    ImageFilterVignette vignette = new ImageFilterVignette();
655                    ImagePreset copy = new ImagePreset(preset);
656                    copy.add(vignette);
657                    copy.setHistoryName(vignette.getName());
658                    copy.setIsFx(false);
659                    filter = copy.getFilter("Vignette");
660                    mImageShow.setImagePreset(copy);
661                }
662                mImageShow.setCurrentFilter(filter);
663                unselectPanelButtons(mColorsPanelButtons);
664                mVignetteButton.setSelected(true);
665                invalidateViews();
666            }
667        };
668    }
669
670    private OnClickListener createOnClickCurvesRGBButton() {
671        return new View.OnClickListener() {
672            @Override
673            public void onClick(View v) {
674                hideImageViews();
675                mImageCurves.setVisibility(View.VISIBLE);
676                unselectPanelButtons(mColorsPanelButtons);
677                mCurvesButtonRGB.setSelected(true);
678                mImageCurves.setUseRed(true);
679                mImageCurves.setUseGreen(true);
680                mImageCurves.setUseBlue(true);
681                mImageCurves.reloadCurve();
682            }
683        };
684    }
685
686    private OnClickListener createOnClickSharpenButton() {
687        return new View.OnClickListener() {
688            @Override
689            public void onClick(View v) {
690                hideImageViews();
691                mImageShow.setVisibility(View.VISIBLE);
692                unselectPanelButtons(mColorsPanelButtons);
693                mSharpenButton.setSelected(true);
694                mImageShow.showToast("Sharpen", true);
695                mImageShow.setCurrentFilter(null);
696            }
697        };
698    }
699
700    private OnClickListener createOnClickContrastButton() {
701        return new View.OnClickListener() {
702            @Override
703            public void onClick(View v) {
704                hideImageViews();
705                mImageShow.setVisibility(View.VISIBLE);
706                mImageShow.setShowControls(true);
707                ImagePreset preset = mImageShow.getImagePreset();
708                ImageFilter filter = preset.getFilter("Contrast");
709                if (filter == null) {
710                    ImageFilterContrast contrast = new ImageFilterContrast();
711                    ImagePreset copy = new ImagePreset(preset);
712                    copy.add(contrast);
713                    copy.setHistoryName(contrast.getName());
714                    copy.setIsFx(false);
715                    filter = copy.getFilter("Contrast");
716                    mImageShow.setImagePreset(copy);
717                }
718                mImageShow.setCurrentFilter(filter);
719                unselectPanelButtons(mColorsPanelButtons);
720                mContrastButton.setSelected(true);
721                invalidateViews();
722            }
723        };
724    }
725
726    private OnClickListener createOnClickSaturationButton() {
727        return new View.OnClickListener() {
728            @Override
729            public void onClick(View v) {
730                hideImageViews();
731                mImageShow.setVisibility(View.VISIBLE);
732                mImageShow.setShowControls(true);
733                ImagePreset preset = mImageShow.getImagePreset();
734                ImageFilter filter = preset.getFilter("Saturated");
735                if (filter == null) {
736                    ImageFilterSaturated sat = new ImageFilterSaturated();
737                    ImagePreset copy = new ImagePreset(preset);
738                    copy.add(sat);
739                    copy.setHistoryName(sat.getName());
740                    copy.setIsFx(false);
741                    filter = copy.getFilter("Saturated");
742                    mImageShow.setImagePreset(copy);
743                }
744                mImageShow.setCurrentFilter(filter);
745                unselectPanelButtons(mColorsPanelButtons);
746                mSaturationButton.setSelected(true);
747                invalidateViews();
748            }
749        };
750    }
751
752    private OnClickListener createOnClickTintButton() {
753        return new View.OnClickListener() {
754            @Override
755            public void onClick(View v) {
756                hideImageViews();
757                mImageShow.setVisibility(View.VISIBLE);
758                mImageShow.setShowControls(true);
759                ImagePreset preset = mImageShow.getImagePreset();
760                ImageFilter filter = preset.getFilter("Hue");
761                if (filter == null) {
762                    ImageFilterHue contrast = new ImageFilterHue();
763                    ImagePreset copy = new ImagePreset(preset);
764                    copy.add(contrast);
765                    copy.setHistoryName(contrast.getName());
766                    copy.setIsFx(false);
767                    filter = copy.getFilter("Hue");
768                    mImageShow.setImagePreset(copy);
769                }
770                mImageShow.setCurrentFilter(filter);
771                unselectPanelButtons(mColorsPanelButtons);
772                mTintButton.setSelected(true);
773                invalidateViews();
774            }
775        };
776    }
777
778    private OnClickListener createOnClickVibranceButton() {
779        return new View.OnClickListener() {
780            @Override
781            public void onClick(View v) {
782                hideImageViews();
783                mImageShow.setVisibility(View.VISIBLE);
784                mImageShow.setShowControls(true);
785                ImagePreset preset = mImageShow.getImagePreset();
786                ImageFilter filter = preset.getFilter("Shadows");
787                if (filter == null) {
788                    ImageFilterShadows contrast = new ImageFilterShadows();
789                    ImagePreset copy = new ImagePreset(preset);
790                    copy.add(contrast);
791                    copy.setHistoryName(contrast.getName());
792                    copy.setIsFx(false);
793                    filter = copy.getFilter("Shadows");
794                    mImageShow.setImagePreset(copy);
795                }
796                mImageShow.setCurrentFilter(filter);
797                unselectPanelButtons(mColorsPanelButtons);
798                mVibranceButton.setSelected(true);
799                invalidateViews();
800            }
801        };
802    }
803
804    private OnClickListener createOnClickExposureButton() {
805        return new View.OnClickListener() {
806            @Override
807            public void onClick(View v) {
808                hideImageViews();
809                mImageShow.setVisibility(View.VISIBLE);
810                mImageShow.setShowControls(true);
811                ImagePreset preset = mImageShow.getImagePreset();
812                ImageFilter filter = preset.getFilter("Exposure");
813                if (filter == null) {
814                    ImageFilterExposure bright = new ImageFilterExposure();
815                    ImagePreset copy = new ImagePreset(preset);
816                    copy.add(bright);
817                    copy.setHistoryName(bright.getName());
818                    copy.setIsFx(false);
819                    filter = copy.getFilter("Exposure");
820                    mImageShow.setImagePreset(copy);
821                }
822                mImageShow.setCurrentFilter(filter);
823                unselectPanelButtons(mColorsPanelButtons);
824                mExposureButton.setSelected(true);
825                invalidateViews();
826            }
827        };
828    }
829
830    private OnClickListener createOnClickShadowRecoveryButton() {
831        return new View.OnClickListener() {
832            @Override
833            public void onClick(View v) {
834                hideImageViews();
835                mImageShow.setVisibility(View.VISIBLE);
836                mImageShow.setShowControls(true);
837                ImagePreset preset = mImageShow.getImagePreset();
838                ImageFilter filter = preset.getFilter("Hue");
839                if (filter == null) {
840                    ImageFilterHue contrast = new ImageFilterHue();
841                    ImagePreset copy = new ImagePreset(preset);
842                    copy.add(contrast);
843                    copy.setHistoryName(contrast.getName());
844                    copy.setIsFx(false);
845                    filter = copy.getFilter("Hue");
846                    mImageShow.setImagePreset(copy);
847                }
848                mImageShow.setCurrentFilter(filter);
849                unselectPanelButtons(mColorsPanelButtons);
850                mShadowRecoveryButton.setSelected(true);
851                invalidateViews();
852            }
853        };
854    }
855
856    // //////////////////////////////////////////////////////////////////////////////
857
858    public float getPixelsFromDip(float value) {
859        Resources r = getResources();
860        return TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, value,
861                r.getDisplayMetrics());
862    }
863
864    public void useImagePreset(ImagePreset preset) {
865        if (preset == null) {
866            return;
867        }
868        ImagePreset copy = new ImagePreset(preset);
869        mImageShow.setImagePreset(copy);
870        if (preset.isFx()) {
871            // if it's an FX we rest the curve adjustment too
872            mImageCurves.resetCurve();
873        }
874        invalidateViews();
875    }
876
877    public void useImageFilter(ImageFilter imageFilter) {
878        if (imageFilter == null) {
879            return;
880        }
881        ImagePreset oldPreset = mImageShow.getImagePreset();
882        ImagePreset copy = new ImagePreset(oldPreset);
883        // TODO: use a numerical constant instead.
884        if (imageFilter.getName().equalsIgnoreCase("Border")) {
885            copy.remove("Border");
886            copy.setHistoryName("Border");
887        }
888        copy.add(imageFilter);
889        mImageShow.setImagePreset(copy);
890        invalidateViews();
891    }
892
893    @Override
894    public void onItemClick(AdapterView<?> parent, View view, int position,
895            long id) {
896        mImageShow.onItemClick(position);
897        invalidateViews();
898    }
899
900    public void pickImage() {
901        Intent intent = new Intent();
902        intent.setType("image/*");
903        intent.setAction(Intent.ACTION_GET_CONTENT);
904        startActivityForResult(Intent.createChooser(intent, getString(R.string.select_image)),
905                SELECT_PICTURE);
906    }
907
908    public void onActivityResult(int requestCode, int resultCode, Intent data) {
909        Log.v(LOGTAG, "onActivityResult");
910        if (resultCode == RESULT_OK) {
911            if (requestCode == SELECT_PICTURE) {
912                Uri selectedImageUri = data.getData();
913                mImageLoader.loadBitmap(selectedImageUri);
914            }
915        }
916    }
917
918    public void saveImage() {
919        Toast toast = Toast.makeText(getBaseContext(), getString(R.string.saving_image),
920                Toast.LENGTH_SHORT);
921        toast.setGravity(Gravity.CENTER, 0, 0);
922        toast.show();
923
924        mImageShow.saveImage(this, null);
925    }
926
927    static {
928        System.loadLibrary("jni_filtershow_filters");
929    }
930
931}
932