FilterShowActivity.java revision 786fe6476e4ccf4b98489ff69d8ef439533cdc2a
1
2package com.android.gallery3d.filtershow;
3
4import java.util.Vector;
5
6import com.android.gallery3d.filtershow.cache.ImageLoader;
7import com.android.gallery3d.filtershow.filters.*;
8import com.android.gallery3d.filtershow.imageshow.ImageBorder;
9import com.android.gallery3d.filtershow.imageshow.ImageShow;
10import com.android.gallery3d.filtershow.imageshow.ImageSmallFilter;
11import com.android.gallery3d.filtershow.imageshow.ImageStraighten;
12import com.android.gallery3d.filtershow.presets.*;
13import com.android.gallery3d.filtershow.ui.ImageCurves;
14import com.android.gallery3d.R;
15
16import android.net.Uri;
17import android.os.Bundle;
18import android.annotation.TargetApi;
19import android.app.ActionBar;
20import android.app.Activity;
21import android.content.Intent;
22import android.content.res.Resources;
23import android.graphics.drawable.Drawable;
24import android.graphics.drawable.NinePatchDrawable;
25import android.util.Log;
26import android.util.TypedValue;
27import android.view.Gravity;
28import android.view.Menu;
29import android.view.MenuItem;
30import android.view.MotionEvent;
31import android.view.View;
32import android.view.View.OnClickListener;
33import android.view.View.OnTouchListener;
34import android.widget.AbsoluteLayout;
35import android.widget.AdapterView;
36import android.widget.AdapterView.OnItemClickListener;
37import android.widget.Button;
38import android.widget.ImageButton;
39import android.widget.LinearLayout;
40import android.widget.ListView;
41import android.widget.Toast;
42
43@TargetApi(16)
44public class FilterShowActivity extends Activity implements OnItemClickListener {
45
46    private ImageLoader mImageLoader = null;
47    private ImageShow mImageShow = null;
48    private ImageCurves mImageCurves = null;
49    private ImageBorder mImageBorders = null;
50    private ImageStraighten mImageStraighten = null;
51
52    private View mListFx = null;
53    private View mListBorders = null;
54    private View mListGeometry = null;
55    private View mListColors = null;
56
57    private ImageButton mFxButton = null;
58    private ImageButton mBorderButton = null;
59    private ImageButton mGeometryButton = null;
60    private ImageButton mColorsButton = null;
61
62    private ImageButton mVignetteButton = null;
63    private ImageButton mCurvesButtonRGB = null;
64    private ImageButton mCurvesButtonRed = null;
65    private ImageButton mCurvesButtonGreen = null;
66    private ImageButton mCurvesButtonBlue = null;
67    private ImageButton mSharpenButton = null;
68    private ImageButton mContrastButton = null;
69
70    private static final int SELECT_PICTURE = 1;
71    private static final String LOGTAG = "FilterShowActivity";
72    protected static final boolean ANIMATE_PANELS = false;
73
74    private boolean mShowingHistoryPanel = false;
75    private Vector<ImageShow> mImageViews = new Vector<ImageShow>();
76    private Vector<View> mListViews = new Vector<View>();
77    private Vector<ImageButton> mBottomPanelButtons = new Vector<ImageButton>();
78    private Vector<ImageButton> mColorsPanelButtons = new Vector<ImageButton>();
79
80    @Override
81    public void onCreate(Bundle savedInstanceState) {
82        super.onCreate(savedInstanceState);
83
84        setContentView(R.layout.filtershow_activity);
85        ActionBar actionBar = getActionBar();
86        actionBar.setDisplayOptions(ActionBar.DISPLAY_SHOW_CUSTOM);
87        actionBar.setCustomView(R.layout.filtershow_actionbar);
88
89        actionBar.getCustomView().setOnClickListener(new OnClickListener() {
90            @Override
91            public void onClick(View view) {
92                saveImage();
93            }
94        });
95
96        mImageLoader = new ImageLoader(getApplicationContext());
97
98        LinearLayout listFilters = (LinearLayout) findViewById(R.id.listFilters);
99        LinearLayout listBorders = (LinearLayout) findViewById(R.id.listBorders);
100
101        mImageShow = (ImageShow) findViewById(R.id.imageShow);
102        mImageCurves = (ImageCurves) findViewById(R.id.imageCurves);
103        mImageBorders = (ImageBorder) findViewById(R.id.imageBorder);
104        mImageStraighten = (ImageStraighten) findViewById(R.id.imageStraighten);
105
106        mImageViews.add(mImageShow);
107        mImageViews.add(mImageCurves);
108        mImageViews.add(mImageBorders);
109        mImageViews.add(mImageStraighten);
110
111        mListFx = findViewById(R.id.fxList);
112        mListBorders = findViewById(R.id.bordersList);
113        mListGeometry = findViewById(R.id.gemoetryList);
114        mListColors = findViewById(R.id.colorsFxList);
115        mListViews.add(mListFx);
116        mListViews.add(mListBorders);
117        mListViews.add(mListGeometry);
118        mListViews.add(mListColors);
119
120        mFxButton = (ImageButton) findViewById(R.id.fxButton);
121        mBorderButton = (ImageButton) findViewById(R.id.borderButton);
122        mGeometryButton = (ImageButton) findViewById(R.id.geometryButton);
123        mColorsButton = (ImageButton) findViewById(R.id.colorsButton);
124        mBottomPanelButtons.add(mFxButton);
125        mBottomPanelButtons.add(mBorderButton);
126        mBottomPanelButtons.add(mGeometryButton);
127        mBottomPanelButtons.add(mColorsButton);
128        mFxButton.setSelected(true);
129
130        mVignetteButton = (ImageButton) findViewById(R.id.vignetteButton);
131        mCurvesButtonRGB = (ImageButton) findViewById(R.id.curvesButtonRGB);
132        mCurvesButtonRed = (ImageButton) findViewById(R.id.curvesButtonRed);
133        mCurvesButtonGreen = (ImageButton) findViewById(R.id.curvesButtonGreen);
134        mCurvesButtonBlue = (ImageButton) findViewById(R.id.curvesButtonBlue);
135        mSharpenButton = (ImageButton) findViewById(R.id.sharpenButton);
136        mContrastButton = (ImageButton) findViewById(R.id.contrastButton);
137        mColorsPanelButtons.add(mVignetteButton);
138        mColorsPanelButtons.add(mCurvesButtonRGB);
139        mColorsPanelButtons.add(mCurvesButtonRed);
140        mColorsPanelButtons.add(mCurvesButtonGreen);
141        mColorsPanelButtons.add(mCurvesButtonBlue);
142        mColorsPanelButtons.add(mSharpenButton);
143        mColorsPanelButtons.add(mContrastButton);
144
145        mCurvesButtonRGB.setSelected(true);
146
147        // TODO: instead of click listeners, make the activity the single
148        // listener and do a dispatch in the listener callback method.
149        findViewById(R.id.showOriginalButton).setOnTouchListener(createOnTouchShowOriginalButton());
150        findViewById(R.id.straightenButton).setOnClickListener(createOnClickStraightenButton());
151        findViewById(R.id.cropButton).setOnClickListener(createOnClickCropButton());
152        findViewById(R.id.rotateButton).setOnClickListener(createOnClickRotateButton());
153        findViewById(R.id.flipButton).setOnClickListener(createOnClickFlipButton());
154
155        mVignetteButton.setOnClickListener(createOnClickVignetteButton());
156        mCurvesButtonRGB.setOnClickListener(createOnClickCurvesRGBButton());
157        mCurvesButtonRed.setOnClickListener(createOnClickCurvesRedButton());
158        mCurvesButtonGreen.setOnClickListener(createOnClickCurvesGreenButton());
159        mCurvesButtonBlue.setOnClickListener(createOnClickCurvesBlueButton());
160
161        mSharpenButton.setOnClickListener(createOnClickSharpenButton());
162        mContrastButton.setOnClickListener(createOnClickContrastButton());
163
164        mFxButton.setOnClickListener(createOnClickFxButton());
165        mBorderButton.setOnClickListener(createOnClickBorderButton());
166        mGeometryButton.setOnClickListener(createOnClickGeometryButton());
167        mColorsButton.setOnClickListener(createOnClickColorsButton());
168
169        findViewById(R.id.resetOperationsButton).setOnClickListener(
170                createOnClickResetOperationsButton());
171
172        ListView operationsList = (ListView) findViewById(R.id.operationsList);
173        operationsList.setAdapter(mImageShow.getListAdapter());
174        operationsList.setOnItemClickListener(this);
175        mImageLoader.setAdapter((HistoryAdapter) mImageShow.getListAdapter());
176
177        fillListImages(listFilters);
178        fillListBorders(listBorders);
179
180        mImageShow.setImageLoader(mImageLoader);
181        mImageCurves.setImageLoader(mImageLoader);
182        mImageCurves.setMaster(mImageShow);
183        mImageBorders.setImageLoader(mImageLoader);
184        mImageBorders.setMaster(mImageShow);
185        mImageStraighten.setImageLoader(mImageLoader);
186        mImageStraighten.setMaster(mImageShow);
187
188        Intent intent = getIntent();
189        String data = intent.getDataString();
190        if (data != null) {
191            Uri uri = Uri.parse(data);
192            mImageLoader.loadBitmap(uri);
193        } else {
194            pickImage();
195        }
196    }
197
198    @Override
199    public boolean onCreateOptionsMenu(Menu menu) {
200        getMenuInflater().inflate(R.menu.filtershow_activity_menu, menu);
201        MenuItem item = menu.findItem(R.id.operationsButton);
202        if (mShowingHistoryPanel) {
203            item.setTitle(R.string.hide_history_panel);
204        } else {
205            item.setTitle(R.string.show_history_panel);
206        }
207        return true;
208    }
209
210    public boolean onOptionsItemSelected(MenuItem item) {
211        switch (item.getItemId()) {
212            case R.id.undoButton: {
213                HistoryAdapter adapter = (HistoryAdapter) mImageShow
214                        .getListAdapter();
215                int position = adapter.undo();
216                mImageShow.onItemClick(position);
217                mImageShow.showToast("Undo");
218                invalidateViews();
219                return true;
220            }
221            case R.id.redoButton: {
222                HistoryAdapter adapter = (HistoryAdapter) mImageShow
223                        .getListAdapter();
224                int position = adapter.redo();
225                mImageShow.onItemClick(position);
226                mImageShow.showToast("Redo");
227                invalidateViews();
228                return true;
229            }
230            case R.id.operationsButton: {
231                toggleHistoryPanel();
232                return true;
233            }
234            case android.R.id.home: {
235                saveImage();
236                return true;
237            }
238        }
239        return false;
240    }
241
242    private void fillListImages(LinearLayout listFilters) {
243        // TODO: use listview
244        // TODO: load the filters straight from the filesystem
245        ImagePreset[] preset = new ImagePreset[9];
246        int p = 0;
247        preset[p++] = new ImagePreset();
248        preset[p++] = new ImagePresetSaturated();
249        preset[p++] = new ImagePresetOld();
250        preset[p++] = new ImagePresetXProcessing();
251        preset[p++] = new ImagePresetBW();
252        preset[p++] = new ImagePresetBWRed();
253        preset[p++] = new ImagePresetBWGreen();
254        preset[p++] = new ImagePresetBWBlue();
255
256        for (int i = 0; i < p; i++) {
257            ImageSmallFilter filter = new ImageSmallFilter(getBaseContext());
258            preset[i].setIsFx(true);
259            filter.setImagePreset(preset[i]);
260            filter.setController(this);
261            filter.setImageLoader(mImageLoader);
262            listFilters.addView(filter);
263        }
264
265        // Default preset (original)
266        mImageShow.setImagePreset(preset[0]);
267    }
268
269    private void fillListBorders(LinearLayout listBorders) {
270        // TODO: use listview
271        // TODO: load the borders straight from the filesystem
272        int p = 0;
273        ImageFilter[] borders = new ImageFilter[8];
274        borders[p++] = new ImageFilterBorder(null);
275
276        Drawable npd3 = getResources().getDrawable(R.drawable.filtershow_border_film3);
277        borders[p++] = new ImageFilterBorder(npd3);
278        Drawable npd = getResources().getDrawable(
279                R.drawable.filtershow_border_scratch3);
280        borders[p++] = new ImageFilterBorder(npd);
281        Drawable npd2 = getResources().getDrawable(R.drawable.filtershow_border_black);
282        borders[p++] = new ImageFilterBorder(npd2);
283        Drawable npd6 = getResources().getDrawable(
284                R.drawable.filtershow_border_rounded_black);
285        borders[p++] = new ImageFilterBorder(npd6);
286        Drawable npd4 = getResources().getDrawable(R.drawable.filtershow_border_white);
287        borders[p++] = new ImageFilterBorder(npd4);
288        Drawable npd5 = getResources().getDrawable(
289                R.drawable.filtershow_border_rounded_white);
290        borders[p++] = new ImageFilterBorder(npd5);
291
292        for (int i = 0; i < p; i++) {
293            ImageSmallFilter filter = new ImageSmallFilter(getBaseContext());
294            filter.setImageFilter(borders[i]);
295            filter.setController(this);
296            filter.setImageLoader(mImageLoader);
297            listBorders.addView(filter);
298        }
299    }
300
301    // //////////////////////////////////////////////////////////////////////////////
302    // Some utility functions
303
304    public void showOriginalViews(boolean value) {
305        for (ImageShow views : mImageViews) {
306            views.showOriginal(value);
307        }
308    }
309
310    public void invalidateViews() {
311        for (ImageShow views : mImageViews) {
312            views.invalidate();
313        }
314    }
315
316    public void hideListViews() {
317        for (View view : mListViews) {
318            view.setVisibility(View.GONE);
319        }
320    }
321
322    public void hideImageViews() {
323        mImageShow.setShowControls(false); // reset
324        for (View view : mImageViews) {
325            view.setVisibility(View.GONE);
326        }
327    }
328
329    public void unselectBottomPanelButtons() {
330        for (ImageButton button : mBottomPanelButtons) {
331            button.setSelected(false);
332        }
333    }
334
335    public void unselectPanelButtons(Vector<ImageButton> buttons) {
336        for (ImageButton button : buttons) {
337            button.setSelected(false);
338        }
339    }
340
341    // //////////////////////////////////////////////////////////////////////////////
342    // Click handlers for the top row buttons
343
344    private OnTouchListener createOnTouchShowOriginalButton() {
345        return new View.OnTouchListener() {
346            @Override
347            public boolean onTouch(View v, MotionEvent event) {
348                boolean show = false;
349                if ((event.getActionMasked() != MotionEvent.ACTION_UP)
350                        || (event.getActionMasked() == MotionEvent.ACTION_CANCEL)) {
351                    show = true;
352                }
353                showOriginalViews(show);
354                return true;
355            }
356        };
357    }
358
359    // //////////////////////////////////////////////////////////////////////////////
360    // history panel...
361
362    private void toggleHistoryPanel() {
363        final View view = findViewById(R.id.mainPanel);
364        final View viewList = findViewById(R.id.historyPanel);
365        View rootView = viewList.getRootView();
366
367        // TODO: use a custom layout instead of absolutelayout...
368        final AbsoluteLayout.LayoutParams lp = (AbsoluteLayout.LayoutParams) view
369                .getLayoutParams();
370        final AbsoluteLayout.LayoutParams lph = (AbsoluteLayout.LayoutParams) viewList
371                .getLayoutParams();
372        final int positionHistoryPanel = (int) (rootView.getWidth() - viewList
373                .getWidth());
374        if (!mShowingHistoryPanel) {
375            mShowingHistoryPanel = true;
376            view.animate().setDuration(200).x(-viewList.getWidth())
377                    .withLayer().withEndAction(new Runnable() {
378                        public void run() {
379                            view.setLayoutParams(lp);
380                            lph.x = positionHistoryPanel;
381                            viewList.setLayoutParams(lph);
382                            viewList.setAlpha(0);
383                            viewList.setVisibility(View.VISIBLE);
384                            viewList.animate().setDuration(100)
385                                    .alpha(1.0f).start();
386                        }
387                    }).start();
388        } else {
389            mShowingHistoryPanel = false;
390            viewList.setVisibility(View.INVISIBLE);
391            view.animate().setDuration(200).x(0).withLayer()
392                    .withEndAction(new Runnable() {
393                        public void run() {
394                            lp.x = 0;
395                            view.setLayoutParams(lp);
396                        }
397                    }).start();
398        }
399        invalidateOptionsMenu();
400    }
401
402    private void resetHistory() {
403        HistoryAdapter adapter = (HistoryAdapter) mImageShow
404                .getListAdapter();
405        adapter.reset();
406        ImagePreset original = new ImagePreset(adapter.getItem(0));
407        mImageShow.setImagePreset(original);
408        invalidateViews();
409    }
410
411    // reset button in the history panel.
412    private OnClickListener createOnClickResetOperationsButton() {
413        return new View.OnClickListener() {
414            @Override
415            public void onClick(View v) {
416                resetHistory();
417            }
418        };
419    }
420
421    // //////////////////////////////////////////////////////////////////////////////
422    // Now, let's deal with the bottom panel.
423
424    private OnClickListener createOnClickFxButton() {
425        return new View.OnClickListener() {
426            @Override
427            public void onClick(View v) {
428                hideImageViews();
429                hideListViews();
430                unselectBottomPanelButtons();
431                mImageShow.setVisibility(View.VISIBLE);
432                mListFx.setVisibility(View.VISIBLE);
433                mFxButton.setSelected(true);
434            }
435        };
436    }
437
438    private OnClickListener createOnClickBorderButton() {
439        return new View.OnClickListener() {
440            @Override
441            public void onClick(View v) {
442                hideImageViews();
443                hideListViews();
444                unselectBottomPanelButtons();
445                mImageBorders.setVisibility(View.VISIBLE);
446                mListBorders.setVisibility(View.VISIBLE);
447                mBorderButton.setSelected(true);
448            }
449        };
450    }
451
452    private OnClickListener createOnClickGeometryButton() {
453        return new View.OnClickListener() {
454            @Override
455            public void onClick(View v) {
456                hideImageViews();
457                hideListViews();
458                unselectBottomPanelButtons();
459                mImageStraighten.setVisibility(View.VISIBLE);
460                mListGeometry.setVisibility(View.VISIBLE);
461                mGeometryButton.setSelected(true);
462
463                if (ANIMATE_PANELS) {
464                    mListGeometry.setX(mListGeometry.getWidth());
465                    mListGeometry.animate().setDuration(200).x(0).withLayer().start();
466                }
467            }
468        };
469    }
470
471    private OnClickListener createOnClickColorsButton() {
472        return new View.OnClickListener() {
473            @Override
474            public void onClick(View v) {
475                hideImageViews();
476                hideListViews();
477                unselectBottomPanelButtons();
478                mListColors.setVisibility(View.VISIBLE);
479                mImageCurves.setVisibility(View.VISIBLE);
480                mColorsButton.setSelected(true);
481
482                if (ANIMATE_PANELS) {
483                    View view = findViewById(R.id.listColorsFx);
484                    view.setX(mListColors.getWidth());
485                    view.animate().setDuration(200).x(0).withLayer().start();
486                }
487            }
488        };
489    }
490
491    // //////////////////////////////////////////////////////////////////////////////
492    // Geometry sub-panel
493
494    private OnClickListener createOnClickStraightenButton() {
495        return new View.OnClickListener() {
496            @Override
497            public void onClick(View v) {
498                hideImageViews();
499                mImageStraighten.setVisibility(View.VISIBLE);
500                mImageStraighten.showToast("Straighten", true);
501            }
502        };
503    }
504
505    private OnClickListener createOnClickCropButton() {
506        return new View.OnClickListener() {
507            @Override
508            public void onClick(View v) {
509                hideImageViews();
510                mImageShow.setVisibility(View.VISIBLE);
511                mImageShow.showToast("Crop", true);
512            }
513        };
514    }
515
516    private OnClickListener createOnClickRotateButton() {
517        return new View.OnClickListener() {
518            @Override
519            public void onClick(View v) {
520                hideImageViews();
521                mImageShow.setVisibility(View.VISIBLE);
522                mImageShow.showToast("Rotate", true);
523            }
524        };
525    }
526
527    private OnClickListener createOnClickFlipButton() {
528        return new View.OnClickListener() {
529            @Override
530            public void onClick(View v) {
531                hideImageViews();
532                mImageShow.setVisibility(View.VISIBLE);
533                mImageShow.showToast("Flip", true);
534            }
535        };
536    }
537
538    // //////////////////////////////////////////////////////////////////////////////
539    // Filters sub-panel
540
541    private OnClickListener createOnClickVignetteButton() {
542        return new View.OnClickListener() {
543            @Override
544            public void onClick(View v) {
545                hideImageViews();
546                mImageShow.setVisibility(View.VISIBLE);
547                mImageShow.setShowControls(true);
548                ImagePreset preset = mImageShow.getImagePreset();
549                ImageFilter filter = preset.getFilter("Vignette");
550                if (filter == null) {
551                    ImageFilterVignette vignette = new ImageFilterVignette();
552                    ImagePreset copy = new ImagePreset(preset);
553                    copy.add(vignette);
554                    copy.setHistoryName(vignette.name());
555                    copy.setIsFx(false);
556                    filter = copy.getFilter("Vignette");
557                    mImageShow.setImagePreset(copy);
558                }
559                mImageShow.setCurrentFilter(filter);
560                unselectPanelButtons(mColorsPanelButtons);
561                mVignetteButton.setSelected(true);
562                invalidateViews();
563            }
564        };
565    }
566
567    private OnClickListener createOnClickCurvesRGBButton() {
568        return new View.OnClickListener() {
569            @Override
570            public void onClick(View v) {
571                hideImageViews();
572                mImageCurves.setVisibility(View.VISIBLE);
573                unselectPanelButtons(mColorsPanelButtons);
574                mCurvesButtonRGB.setSelected(true);
575                mImageCurves.setUseRed(true);
576                mImageCurves.setUseGreen(true);
577                mImageCurves.setUseBlue(true);
578                mImageCurves.reloadCurve();
579            }
580        };
581    }
582
583    private OnClickListener createOnClickCurvesRedButton() {
584        return new View.OnClickListener() {
585            @Override
586            public void onClick(View v) {
587                hideImageViews();
588                mImageCurves.setVisibility(View.VISIBLE);
589                unselectPanelButtons(mColorsPanelButtons);
590                mCurvesButtonRed.setSelected(true);
591                mImageCurves.setUseRed(true);
592                mImageCurves.setUseGreen(false);
593                mImageCurves.setUseBlue(false);
594                mImageCurves.reloadCurve();
595            }
596        };
597    }
598
599    private OnClickListener createOnClickCurvesGreenButton() {
600        return new View.OnClickListener() {
601            @Override
602            public void onClick(View v) {
603                hideImageViews();
604                mImageCurves.setVisibility(View.VISIBLE);
605                unselectPanelButtons(mColorsPanelButtons);
606                mCurvesButtonGreen.setSelected(true);
607                mImageCurves.setUseRed(false);
608                mImageCurves.setUseGreen(true);
609                mImageCurves.setUseBlue(false);
610                mImageCurves.reloadCurve();
611            }
612        };
613    }
614
615    private OnClickListener createOnClickCurvesBlueButton() {
616        return new View.OnClickListener() {
617            @Override
618            public void onClick(View v) {
619                hideImageViews();
620                mImageCurves.setVisibility(View.VISIBLE);
621                unselectPanelButtons(mColorsPanelButtons);
622                mCurvesButtonBlue.setSelected(true);
623                mImageCurves.setUseRed(false);
624                mImageCurves.setUseGreen(false);
625                mImageCurves.setUseBlue(true);
626                mImageCurves.reloadCurve();
627            }
628        };
629    }
630
631    private OnClickListener createOnClickSharpenButton() {
632        return new View.OnClickListener() {
633            @Override
634            public void onClick(View v) {
635                hideImageViews();
636                mImageShow.setVisibility(View.VISIBLE);
637                unselectPanelButtons(mColorsPanelButtons);
638                mSharpenButton.setSelected(true);
639                mImageShow.showToast("Sharpen", true);
640                mImageShow.setCurrentFilter(null);
641            }
642        };
643    }
644
645    private OnClickListener createOnClickContrastButton() {
646        return new View.OnClickListener() {
647            @Override
648            public void onClick(View v) {
649                hideImageViews();
650                mImageShow.setVisibility(View.VISIBLE);
651                unselectPanelButtons(mColorsPanelButtons);
652                mContrastButton.setSelected(true);
653                mImageShow.showToast("Contrast", true);
654                mImageShow.setCurrentFilter(null);
655            }
656        };
657    }
658
659    // //////////////////////////////////////////////////////////////////////////////
660
661    public float getPixelsFromDip(float value) {
662        Resources r = getResources();
663        return TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, value,
664                r.getDisplayMetrics());
665    }
666
667    public void useImagePreset(ImagePreset preset) {
668        if (preset == null) {
669            return;
670        }
671        ImagePreset copy = new ImagePreset(preset);
672        mImageShow.setImagePreset(copy);
673        if (preset.isFx()) {
674            // if it's an FX we rest the curve adjustment too
675            mImageCurves.resetCurve();
676        }
677        invalidateViews();
678    }
679
680    public void useImageFilter(ImageFilter imageFilter) {
681        if (imageFilter == null) {
682            return;
683        }
684        ImagePreset oldPreset = mImageShow.getImagePreset();
685        ImagePreset copy = new ImagePreset(oldPreset);
686        // TODO: use a numerical constant instead.
687        if (imageFilter.name().equalsIgnoreCase("Border")) {
688            copy.remove("Border");
689            copy.setHistoryName("Border");
690        }
691        copy.add(imageFilter);
692        invalidateViews();
693    }
694
695    @Override
696    public void onItemClick(AdapterView<?> parent, View view, int position,
697            long id) {
698        mImageShow.onItemClick(position);
699        invalidateViews();
700    }
701
702    public void pickImage() {
703        Intent intent = new Intent();
704        intent.setType("image/*");
705        intent.setAction(Intent.ACTION_GET_CONTENT);
706        startActivityForResult(Intent.createChooser(intent, getString(R.string.select_image)),
707                SELECT_PICTURE);
708    }
709
710    public void onActivityResult(int requestCode, int resultCode, Intent data) {
711        Log.v(LOGTAG, "onActivityResult");
712        if (resultCode == RESULT_OK) {
713            if (requestCode == SELECT_PICTURE) {
714                Uri selectedImageUri = data.getData();
715                mImageLoader.loadBitmap(selectedImageUri);
716            }
717        }
718    }
719
720    public void saveImage() {
721        Toast toast = Toast.makeText(getBaseContext(), getString(R.string.saving_image),
722                Toast.LENGTH_SHORT);
723        toast.setGravity(Gravity.CENTER, 0, 0);
724        toast.show();
725
726        mImageShow.saveImage(this);
727    }
728
729    public void completeSaveImage(Uri saveUri) {
730        setResult(RESULT_OK, new Intent().setData(saveUri));
731        finish();
732    }
733
734    static {
735        System.loadLibrary("jni_filtershow_filters");
736    }
737
738}
739