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