FilterShowActivity.java revision 4988eff4c8eda325a616337d1aaa0666cc301a7c
1
2package com.android.gallery3d.filtershow;
3
4import android.annotation.TargetApi;
5import android.app.ActionBar;
6import android.app.Activity;
7import android.app.ProgressDialog;
8import android.content.ContentValues;
9import android.content.Intent;
10import android.content.res.Resources;
11import android.graphics.Bitmap;
12import android.graphics.BitmapFactory;
13import android.graphics.Color;
14import android.graphics.drawable.Drawable;
15import android.net.Uri;
16import android.os.Bundle;
17import android.util.Log;
18import android.util.TypedValue;
19import android.view.Menu;
20import android.view.MenuItem;
21import android.view.MotionEvent;
22import android.view.View;
23import android.view.View.OnClickListener;
24import android.view.View.OnTouchListener;
25import android.widget.AdapterView;
26import android.widget.AdapterView.OnItemClickListener;
27import android.widget.ImageButton;
28import android.widget.LinearLayout;
29import android.widget.ListView;
30import android.widget.SeekBar;
31import android.widget.ShareActionProvider;
32import android.widget.ShareActionProvider.OnShareTargetSelectedListener;
33
34import com.android.gallery3d.R;
35import com.android.gallery3d.filtershow.cache.ImageLoader;
36import com.android.gallery3d.filtershow.filters.ImageFilter;
37import com.android.gallery3d.filtershow.filters.ImageFilterBorder;
38import com.android.gallery3d.filtershow.filters.ImageFilterParametricBorder;
39import com.android.gallery3d.filtershow.filters.ImageFilterRS;
40import com.android.gallery3d.filtershow.imageshow.ImageBorder;
41import com.android.gallery3d.filtershow.imageshow.ImageCrop;
42import com.android.gallery3d.filtershow.imageshow.ImageFlip;
43import com.android.gallery3d.filtershow.imageshow.ImageRotate;
44import com.android.gallery3d.filtershow.imageshow.ImageShow;
45import com.android.gallery3d.filtershow.imageshow.ImageSmallBorder;
46import com.android.gallery3d.filtershow.imageshow.ImageSmallFilter;
47import com.android.gallery3d.filtershow.imageshow.ImageStraighten;
48import com.android.gallery3d.filtershow.imageshow.ImageZoom;
49import com.android.gallery3d.filtershow.presets.ImagePreset;
50import com.android.gallery3d.filtershow.presets.ImagePresetBW;
51import com.android.gallery3d.filtershow.presets.ImagePresetBWBlue;
52import com.android.gallery3d.filtershow.presets.ImagePresetBWGreen;
53import com.android.gallery3d.filtershow.presets.ImagePresetBWRed;
54import com.android.gallery3d.filtershow.presets.ImagePresetFX;
55import com.android.gallery3d.filtershow.presets.ImagePresetOld;
56import com.android.gallery3d.filtershow.presets.ImagePresetSaturated;
57import com.android.gallery3d.filtershow.presets.ImagePresetXProcessing;
58import com.android.gallery3d.filtershow.provider.SharedImageProvider;
59import com.android.gallery3d.filtershow.tools.SaveCopyTask;
60import com.android.gallery3d.filtershow.ui.ImageCurves;
61
62import java.io.File;
63import java.lang.ref.WeakReference;
64import java.util.Vector;
65
66@TargetApi(16)
67public class FilterShowActivity extends Activity implements OnItemClickListener,
68        OnShareTargetSelectedListener {
69
70    private final PanelController mPanelController = new PanelController();
71    private ImageLoader mImageLoader = null;
72    private ImageShow mImageShow = null;
73    private ImageCurves mImageCurves = null;
74    private ImageBorder mImageBorders = null;
75    private ImageStraighten mImageStraighten = null;
76    private ImageZoom mImageZoom = null;
77    private ImageCrop mImageCrop = null;
78    private ImageRotate mImageRotate = null;
79    private ImageFlip mImageFlip = null;
80
81    private View mListFx = null;
82    private View mListBorders = null;
83    private View mListGeometry = null;
84    private View mListColors = null;
85    private View mListFilterButtons = null;
86
87    private ImageButton mFxButton = null;
88    private ImageButton mBorderButton = null;
89    private ImageButton mGeometryButton = null;
90    private ImageButton mColorsButton = null;
91
92    private ImageSmallFilter mCurrentImageSmallFilter = null;
93    private static final int SELECT_PICTURE = 1;
94    private static final String LOGTAG = "FilterShowActivity";
95    protected static final boolean ANIMATE_PANELS = true;
96
97    private boolean mShowingHistoryPanel = false;
98    private boolean mShowingImageStatePanel = false;
99
100    private final Vector<ImageShow> mImageViews = new Vector<ImageShow>();
101    private final Vector<View> mListViews = new Vector<View>();
102    private final Vector<ImageButton> mBottomPanelButtons = new Vector<ImageButton>();
103
104    private ShareActionProvider mShareActionProvider;
105    private File mSharedOutputFile = null;
106
107    private boolean mSharingImage = false;
108
109    private WeakReference<ProgressDialog> mSavingProgressDialog;
110
111    @Override
112    public void onCreate(Bundle savedInstanceState) {
113        super.onCreate(savedInstanceState);
114
115        ImageFilterRS.setRenderScriptContext(this);
116
117        setContentView(R.layout.filtershow_activity);
118        ActionBar actionBar = getActionBar();
119        actionBar.setDisplayOptions(ActionBar.DISPLAY_SHOW_CUSTOM);
120        actionBar.setCustomView(R.layout.filtershow_actionbar);
121
122        actionBar.getCustomView().setOnClickListener(new OnClickListener() {
123            @Override
124            public void onClick(View view) {
125                saveImage();
126            }
127        });
128
129        mImageLoader = new ImageLoader(getApplicationContext());
130
131        LinearLayout listFilters = (LinearLayout) findViewById(R.id.listFilters);
132        LinearLayout listBorders = (LinearLayout) findViewById(R.id.listBorders);
133
134        mImageShow = (ImageShow) findViewById(R.id.imageShow);
135        mImageCurves = (ImageCurves) findViewById(R.id.imageCurves);
136        mImageBorders = (ImageBorder) findViewById(R.id.imageBorder);
137        mImageStraighten = (ImageStraighten) findViewById(R.id.imageStraighten);
138        mImageZoom = (ImageZoom) findViewById(R.id.imageZoom);
139        mImageCrop = (ImageCrop) findViewById(R.id.imageCrop);
140        mImageRotate = (ImageRotate) findViewById(R.id.imageRotate);
141        mImageFlip = (ImageFlip) findViewById(R.id.imageFlip);
142
143        mImageViews.add(mImageShow);
144        mImageViews.add(mImageCurves);
145        mImageViews.add(mImageBorders);
146        mImageViews.add(mImageStraighten);
147        mImageViews.add(mImageZoom);
148        mImageViews.add(mImageCrop);
149        mImageViews.add(mImageRotate);
150        mImageViews.add(mImageFlip);
151
152        mListFx = findViewById(R.id.fxList);
153        mListBorders = findViewById(R.id.bordersList);
154        mListGeometry = findViewById(R.id.geometryList);
155        mListFilterButtons = findViewById(R.id.filterButtonsList);
156        mListColors = findViewById(R.id.colorsFxList);
157        mListViews.add(mListFx);
158        mListViews.add(mListBorders);
159        mListViews.add(mListGeometry);
160        mListViews.add(mListFilterButtons);
161        mListViews.add(mListColors);
162
163        mFxButton = (ImageButton) findViewById(R.id.fxButton);
164        mBorderButton = (ImageButton) findViewById(R.id.borderButton);
165        mGeometryButton = (ImageButton) findViewById(R.id.geometryButton);
166        mColorsButton = (ImageButton) findViewById(R.id.colorsButton);
167
168        mImageShow.setImageLoader(mImageLoader);
169        mImageCurves.setImageLoader(mImageLoader);
170        mImageCurves.setMaster(mImageShow);
171        mImageBorders.setImageLoader(mImageLoader);
172        mImageBorders.setMaster(mImageShow);
173        mImageStraighten.setImageLoader(mImageLoader);
174        mImageStraighten.setMaster(mImageShow);
175        mImageZoom.setImageLoader(mImageLoader);
176        mImageZoom.setMaster(mImageShow);
177        mImageCrop.setImageLoader(mImageLoader);
178        mImageCrop.setMaster(mImageShow);
179        mImageRotate.setImageLoader(mImageLoader);
180        mImageRotate.setMaster(mImageShow);
181        mImageFlip.setImageLoader(mImageLoader);
182        mImageFlip.setMaster(mImageShow);
183
184        mPanelController.addImageView(findViewById(R.id.imageShow));
185        mPanelController.addImageView(findViewById(R.id.imageCurves));
186        mPanelController.addImageView(findViewById(R.id.imageBorder));
187        mPanelController.addImageView(findViewById(R.id.imageStraighten));
188        mPanelController.addImageView(findViewById(R.id.imageCrop));
189        mPanelController.addImageView(findViewById(R.id.imageRotate));
190        mPanelController.addImageView(findViewById(R.id.imageFlip));
191        mPanelController.addImageView(findViewById(R.id.imageZoom));
192
193        mPanelController.addPanel(mFxButton, mListFx, 0);
194        mPanelController.addPanel(mBorderButton, mListBorders, 1);
195
196        mPanelController.addPanel(mGeometryButton, mListGeometry, 2);
197        mPanelController.addComponent(mGeometryButton, findViewById(R.id.straightenButton));
198        mPanelController.addComponent(mGeometryButton, findViewById(R.id.cropButton));
199        mPanelController.addComponent(mGeometryButton, findViewById(R.id.rotateButton));
200        mPanelController.addComponent(mGeometryButton, findViewById(R.id.flipButton));
201
202        mPanelController.addPanel(mColorsButton, mListColors, 3);
203        mPanelController.addComponent(mColorsButton, findViewById(R.id.vignetteButton));
204        mPanelController.addComponent(mColorsButton, findViewById(R.id.curvesButtonRGB));
205        mPanelController.addComponent(mColorsButton, findViewById(R.id.sharpenButton));
206        mPanelController.addComponent(mColorsButton, findViewById(R.id.vibranceButton));
207        mPanelController.addComponent(mColorsButton, findViewById(R.id.contrastButton));
208        mPanelController.addComponent(mColorsButton, findViewById(R.id.saturationButton));
209        mPanelController.addComponent(mColorsButton, findViewById(R.id.wbalanceButton));
210        mPanelController.addComponent(mColorsButton, findViewById(R.id.hueButton));
211        mPanelController.addComponent(mColorsButton, findViewById(R.id.exposureButton));
212        mPanelController.addComponent(mColorsButton, findViewById(R.id.shadowRecoveryButton));
213
214        mPanelController.addView(findViewById(R.id.resetEffect));
215        mPanelController.addView(findViewById(R.id.applyEffect));
216
217        findViewById(R.id.compareWithOriginalImage).setOnTouchListener(
218                createOnTouchShowOriginalButton());
219
220        findViewById(R.id.resetOperationsButton).setOnClickListener(
221                createOnClickResetOperationsButton());
222
223        ListView operationsList = (ListView) findViewById(R.id.operationsList);
224        operationsList.setAdapter(mImageShow.getHistoryAdapter());
225        operationsList.setOnItemClickListener(this);
226        ListView imageStateList = (ListView) findViewById(R.id.imageStateList);
227        imageStateList.setAdapter(mImageShow.getImageStateAdapter());
228        mImageLoader.setAdapter((HistoryAdapter) mImageShow.getHistoryAdapter());
229
230        fillListImages(listFilters);
231        fillListBorders(listBorders);
232
233        SeekBar seekBar = (SeekBar) findViewById(R.id.filterSeekBar);
234        seekBar.setMax(200);
235        mImageShow.setSeekBar(seekBar);
236        mImageZoom.setSeekBar(seekBar);
237        mPanelController.setRowPanel(findViewById(R.id.secondRowPanel));
238        mPanelController.setUtilityPanel(this, findViewById(R.id.filterButtonsList),
239                findViewById(R.id.compareWithOriginalImage),
240                findViewById(R.id.applyEffect));
241        mPanelController.setMasterImage(mImageShow);
242        mPanelController.setCurrentPanel(mFxButton);
243        Intent intent = getIntent();
244        String data = intent.getDataString();
245        if (data != null) {
246            Uri uri = Uri.parse(data);
247            mImageLoader.loadBitmap(uri);
248        } else {
249            pickImage();
250        }
251    }
252
253    private void showSavingProgress() {
254        ProgressDialog progress;
255        if (mSavingProgressDialog != null) {
256            progress = mSavingProgressDialog.get();
257            if (progress != null) {
258                progress.show();
259                return;
260            }
261        }
262        // TODO: Allow cancellation of the saving process
263        progress = ProgressDialog.show(this, "", getString(R.string.saving_image), true, false);
264        mSavingProgressDialog = new WeakReference<ProgressDialog>(progress);
265    }
266
267    private void hideSavingProgress() {
268        if (mSavingProgressDialog != null) {
269            ProgressDialog progress = mSavingProgressDialog.get();
270            if (progress != null)
271                progress.dismiss();
272        }
273    }
274
275    public void completeSaveImage(Uri saveUri) {
276        if (mSharingImage && mSharedOutputFile != null) {
277            // Image saved, we unblock the content provider
278            Uri uri = Uri.withAppendedPath(SharedImageProvider.CONTENT_URI,
279                    Uri.encode(mSharedOutputFile.getAbsolutePath()));
280            ContentValues values = new ContentValues();
281            values.put(SharedImageProvider.PREPARE, false);
282            getContentResolver().insert(uri, values);
283        }
284        setResult(RESULT_OK, new Intent().setData(saveUri));
285        hideSavingProgress();
286        finish();
287    }
288
289    @Override
290    public boolean onShareTargetSelected(ShareActionProvider arg0, Intent arg1) {
291        // First, let's tell the SharedImageProvider that it will need to wait
292        // for the image
293        Uri uri = Uri.withAppendedPath(SharedImageProvider.CONTENT_URI,
294                Uri.encode(mSharedOutputFile.getAbsolutePath()));
295        ContentValues values = new ContentValues();
296        values.put(SharedImageProvider.PREPARE, true);
297        getContentResolver().insert(uri, values);
298        mSharingImage = true;
299
300        // Process and save the image in the background.
301        showSavingProgress();
302        mImageShow.saveImage(this, mSharedOutputFile);
303        return true;
304    }
305
306    private Intent getDefaultShareIntent() {
307        Intent intent = new Intent(Intent.ACTION_SEND);
308        intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);
309        intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
310        intent.setType(SharedImageProvider.MIME_TYPE);
311        mSharedOutputFile = SaveCopyTask.getNewFile(this, mImageLoader.getUri());
312        Uri uri = Uri.withAppendedPath(SharedImageProvider.CONTENT_URI,
313                Uri.encode(mSharedOutputFile.getAbsolutePath()));
314        intent.putExtra(Intent.EXTRA_STREAM, uri);
315        return intent;
316    }
317
318    @Override
319    public boolean onCreateOptionsMenu(Menu menu) {
320        getMenuInflater().inflate(R.menu.filtershow_activity_menu, menu);
321        MenuItem showHistory = menu.findItem(R.id.operationsButton);
322        if (mShowingHistoryPanel) {
323            showHistory.setTitle(R.string.hide_history_panel);
324        } else {
325            showHistory.setTitle(R.string.show_history_panel);
326        }
327        MenuItem showState = menu.findItem(R.id.showImageStateButton);
328        if (mShowingImageStatePanel) {
329            showState.setTitle(R.string.hide_imagestate_panel);
330        } else {
331            showState.setTitle(R.string.show_imagestate_panel);
332        }
333        mShareActionProvider = (ShareActionProvider) menu.findItem(R.id.menu_share)
334                .getActionProvider();
335        mShareActionProvider.setShareIntent(getDefaultShareIntent());
336        mShareActionProvider.setOnShareTargetSelectedListener(this);
337        return true;
338    }
339
340    @Override
341    public void onPause() {
342        super.onPause();
343        if (mShareActionProvider != null) {
344            mShareActionProvider.setOnShareTargetSelectedListener(null);
345        }
346    }
347
348    @Override
349    public void onResume() {
350        super.onResume();
351        if (mShareActionProvider != null) {
352            mShareActionProvider.setOnShareTargetSelectedListener(this);
353        }
354    }
355
356    @Override
357    public boolean onOptionsItemSelected(MenuItem item) {
358        switch (item.getItemId()) {
359            case R.id.undoButton: {
360                HistoryAdapter adapter = (HistoryAdapter) mImageShow
361                        .getHistoryAdapter();
362                int position = adapter.undo();
363                mImageShow.onItemClick(position);
364                mImageShow.showToast("Undo");
365                invalidateViews();
366                return true;
367            }
368            case R.id.redoButton: {
369                HistoryAdapter adapter = (HistoryAdapter) mImageShow
370                        .getHistoryAdapter();
371                int position = adapter.redo();
372                mImageShow.onItemClick(position);
373                mImageShow.showToast("Redo");
374                invalidateViews();
375                return true;
376            }
377            case R.id.resetHistoryButton: {
378                resetHistory();
379                return true;
380            }
381            case R.id.showImageStateButton: {
382                toggleImageStatePanel();
383                return true;
384            }
385            case R.id.operationsButton: {
386                toggleHistoryPanel();
387                return true;
388            }
389            case android.R.id.home: {
390                saveImage();
391                return true;
392            }
393        }
394        return false;
395    }
396
397    private void fillListImages(LinearLayout listFilters) {
398        // TODO: use listview
399        // TODO: load the filters straight from the filesystem
400        ImagePreset[] preset = new ImagePreset[18];
401        int p = 0;
402
403        int[] drawid = {
404                R.drawable.filtershow_fx_0000_vintage,
405                R.drawable.filtershow_fx_0001_instant,
406                R.drawable.filtershow_fx_0002_bleach,
407                R.drawable.filtershow_fx_0003_blue_crush,
408                R.drawable.filtershow_fx_0004_bw_contrast,
409                R.drawable.filtershow_fx_0005_punch,
410                R.drawable.filtershow_fx_0006_x_process,
411                R.drawable.filtershow_fx_0007_washout,
412                R.drawable.filtershow_fx_0008_washout_color
413        };
414
415        int[] fxNameid = {
416                R.string.ffx_vintage,
417                R.string.ffx_instant,
418                R.string.ffx_bleach,
419                R.string.ffx_blue_crush,
420                R.string.ffx_bw_contrast,
421                R.string.ffx_punch,
422                R.string.ffx_x_process,
423                R.string.ffx_washout,
424                R.string.ffx_washout_color,
425        };
426
427        preset[p++] = new ImagePreset();
428
429        for (int i = 0; i < drawid.length; i++) {
430            Bitmap b = BitmapFactory.decodeResource(getResources(), drawid[i]);
431            preset[p++] = new ImagePresetFX(b, getString(fxNameid[i]));
432        }
433
434        ImageSmallFilter previousFilter = null;
435        for (int i = 0; i < p; i++) {
436            ImageSmallFilter filter = new ImageSmallFilter(this);
437            if (i == 0) {
438                filter.setSelected(true);
439                mCurrentImageSmallFilter = filter;
440            }
441            filter.setPreviousImageSmallFilter(previousFilter);
442            preset[i].setIsFx(true);
443            filter.setImagePreset(preset[i]);
444            filter.setController(this);
445            filter.setImageLoader(mImageLoader);
446            listFilters.addView(filter);
447            previousFilter = filter;
448        }
449
450        // Default preset (original)
451        mImageShow.setImagePreset(preset[0]);
452    }
453
454    private void fillListBorders(LinearLayout listBorders) {
455        // TODO: use listview
456        // TODO: load the borders straight from the filesystem
457        int p = 0;
458        ImageFilter[] borders = new ImageFilter[7];
459        borders[p++] = new ImageFilterBorder(null);
460
461        Drawable npd3 = getResources().getDrawable(R.drawable.filtershow_border_film3);
462        borders[p++] = new ImageFilterBorder(npd3);
463        Drawable npd = getResources().getDrawable(
464                R.drawable.filtershow_border_scratch3);
465        borders[p++] = new ImageFilterBorder(npd);
466        borders[p++] = new ImageFilterParametricBorder(Color.BLACK, 100, 0);
467        borders[p++] = new ImageFilterParametricBorder(Color.BLACK, 100, 100);
468        borders[p++] = new ImageFilterParametricBorder(Color.WHITE, 100, 0);
469        borders[p++] = new ImageFilterParametricBorder(Color.WHITE, 100, 100);
470
471        ImageSmallFilter previousFilter = null;
472        for (int i = 0; i < p; i++) {
473            ImageSmallBorder filter = new ImageSmallBorder(this);
474            filter.setPreviousImageSmallFilter(previousFilter);
475            filter.setImageFilter(borders[i]);
476            filter.setController(this);
477            filter.setBorder(true);
478            filter.setImageLoader(mImageLoader);
479            filter.setShowTitle(false);
480            listBorders.addView(filter);
481            previousFilter = filter;
482        }
483    }
484
485    // //////////////////////////////////////////////////////////////////////////////
486    // Some utility functions
487    // TODO: finish the cleanup.
488
489    public void showOriginalViews(boolean value) {
490        for (ImageShow views : mImageViews) {
491            views.showOriginal(value);
492        }
493    }
494
495    public void invalidateViews() {
496        for (ImageShow views : mImageViews) {
497            views.invalidate();
498            views.updateImage();
499        }
500    }
501
502    public void hideListViews() {
503        for (View view : mListViews) {
504            view.setVisibility(View.GONE);
505        }
506    }
507
508    public void hideImageViews() {
509        mImageShow.setShowControls(false); // reset
510        for (View view : mImageViews) {
511            view.setVisibility(View.GONE);
512        }
513    }
514
515    public void unselectBottomPanelButtons() {
516        for (ImageButton button : mBottomPanelButtons) {
517            button.setSelected(false);
518        }
519    }
520
521    public void unselectPanelButtons(Vector<ImageButton> buttons) {
522        for (ImageButton button : buttons) {
523            button.setSelected(false);
524        }
525    }
526
527    // //////////////////////////////////////////////////////////////////////////////
528    // Click handlers for the top row buttons
529
530    private OnTouchListener createOnTouchShowOriginalButton() {
531        return new View.OnTouchListener() {
532            @Override
533            public boolean onTouch(View v, MotionEvent event) {
534                boolean show = false;
535                if ((event.getActionMasked() != MotionEvent.ACTION_UP)
536                        || (event.getActionMasked() == MotionEvent.ACTION_CANCEL)) {
537                    show = true;
538                }
539                showOriginalViews(show);
540                return true;
541            }
542        };
543    }
544
545    // //////////////////////////////////////////////////////////////////////////////
546    // imageState panel...
547
548    private void toggleImageStatePanel() {
549        final View view = findViewById(R.id.mainPanel);
550        final View viewList = findViewById(R.id.imageStatePanel);
551
552        if (mShowingHistoryPanel) {
553            findViewById(R.id.historyPanel).setVisibility(View.INVISIBLE);
554            mShowingHistoryPanel = false;
555        }
556
557        if (!mShowingImageStatePanel) {
558            mShowingImageStatePanel = true;
559            view.animate().setDuration(200).x(-viewList.getWidth())
560                    .withLayer().withEndAction(new Runnable() {
561                        @Override
562                        public void run() {
563                            viewList.setAlpha(0);
564                            viewList.setVisibility(View.VISIBLE);
565                            viewList.animate().setDuration(100)
566                                    .alpha(1.0f).start();
567                        }
568                    }).start();
569        } else {
570            mShowingImageStatePanel = false;
571            viewList.setVisibility(View.INVISIBLE);
572            view.animate().setDuration(200).x(0).withLayer()
573                    .start();
574        }
575        invalidateOptionsMenu();
576    }
577
578    // //////////////////////////////////////////////////////////////////////////////
579    // history panel...
580
581    private void toggleHistoryPanel() {
582        final View view = findViewById(R.id.mainPanel);
583        final View viewList = findViewById(R.id.historyPanel);
584
585        if (mShowingImageStatePanel) {
586            findViewById(R.id.imageStatePanel).setVisibility(View.INVISIBLE);
587            mShowingImageStatePanel = false;
588        }
589
590        if (!mShowingHistoryPanel) {
591            mShowingHistoryPanel = true;
592            view.animate().setDuration(200).x(-viewList.getWidth())
593                    .withLayer().withEndAction(new Runnable() {
594                        @Override
595                        public void run() {
596                            viewList.setAlpha(0);
597                            viewList.setVisibility(View.VISIBLE);
598                            viewList.animate().setDuration(100)
599                                    .alpha(1.0f).start();
600                        }
601                    }).start();
602        } else {
603            mShowingHistoryPanel = false;
604            viewList.setVisibility(View.INVISIBLE);
605            view.animate().setDuration(200).x(0).withLayer()
606                    .start();
607        }
608        invalidateOptionsMenu();
609    }
610
611    private void resetHistory() {
612        HistoryAdapter adapter = (HistoryAdapter) mImageShow
613                .getHistoryAdapter();
614        adapter.reset();
615        ImagePreset original = new ImagePreset(adapter.getItem(0));
616        mImageShow.setImagePreset(original);
617        invalidateViews();
618    }
619
620    // reset button in the history panel.
621    private OnClickListener createOnClickResetOperationsButton() {
622        return new View.OnClickListener() {
623            @Override
624            public void onClick(View v) {
625                resetHistory();
626            }
627        };
628    }
629
630    // //////////////////////////////////////////////////////////////////////////////
631
632    public float getPixelsFromDip(float value) {
633        Resources r = getResources();
634        return TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, value,
635                r.getDisplayMetrics());
636    }
637
638    public void useImagePreset(ImageSmallFilter imageSmallFilter, ImagePreset preset) {
639        if (preset == null) {
640            return;
641        }
642
643        if (mCurrentImageSmallFilter != null) {
644            mCurrentImageSmallFilter.setSelected(false);
645        }
646        mCurrentImageSmallFilter = imageSmallFilter;
647        mCurrentImageSmallFilter.setSelected(true);
648
649        ImagePreset copy = new ImagePreset(preset);
650        mImageShow.setImagePreset(copy);
651        if (preset.isFx()) {
652            // if it's an FX we rest the curve adjustment too
653            mImageCurves.resetCurve();
654        }
655        invalidateViews();
656    }
657
658    public void useImageFilter(ImageSmallFilter imageSmallFilter, ImageFilter imageFilter,
659            boolean setBorder) {
660        if (imageFilter == null) {
661            return;
662        }
663
664        if (mCurrentImageSmallFilter != null) {
665            mCurrentImageSmallFilter.setSelected(false);
666        }
667        mCurrentImageSmallFilter = imageSmallFilter;
668        mCurrentImageSmallFilter.setSelected(true);
669
670        ImagePreset oldPreset = mImageShow.getImagePreset();
671        ImagePreset copy = new ImagePreset(oldPreset);
672        // TODO: use a numerical constant instead.
673        if (setBorder) {
674            copy.setHistoryName("Border");
675            copy.setBorder(imageFilter);
676        } else {
677            copy.add(imageFilter);
678        }
679        mImageShow.setImagePreset(copy);
680        invalidateViews();
681    }
682
683    @Override
684    public void onItemClick(AdapterView<?> parent, View view, int position,
685            long id) {
686        mImageShow.onItemClick(position);
687        invalidateViews();
688    }
689
690    public void pickImage() {
691        Intent intent = new Intent();
692        intent.setType("image/*");
693        intent.setAction(Intent.ACTION_GET_CONTENT);
694        startActivityForResult(Intent.createChooser(intent, getString(R.string.select_image)),
695                SELECT_PICTURE);
696    }
697
698    @Override
699    public void onActivityResult(int requestCode, int resultCode, Intent data) {
700        Log.v(LOGTAG, "onActivityResult");
701        if (resultCode == RESULT_OK) {
702            if (requestCode == SELECT_PICTURE) {
703                Uri selectedImageUri = data.getData();
704                mImageLoader.loadBitmap(selectedImageUri);
705            }
706        }
707    }
708
709    public void saveImage() {
710        showSavingProgress();
711        mImageShow.saveImage(this, null);
712    }
713
714    static {
715        System.loadLibrary("jni_filtershow_filters");
716    }
717
718}
719