Home | History | Annotate | Download | only in photoeditor
      1 /*
      2  * Copyright (C) 2010 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package com.android.gallery3d.photoeditor;
     18 
     19 import android.app.Activity;
     20 import android.content.Intent;
     21 import android.graphics.Bitmap;
     22 import android.net.Uri;
     23 import android.os.Bundle;
     24 
     25 import com.android.gallery3d.R;
     26 
     27 /**
     28  * Main activity of the photo editor that opens a photo and prepares tools for photo editing.
     29  */
     30 public class PhotoEditor extends Activity {
     31 
     32     private static final String SAVE_URI_KEY = "save_uri";
     33 
     34     private Uri sourceUri;
     35     private Uri saveUri;
     36     private FilterStack filterStack;
     37     private ActionBar actionBar;
     38     private EffectsBar effectsBar;
     39     private Toolbar toolbar;
     40 
     41     @Override
     42     public void onCreate(Bundle savedInstanceState) {
     43         super.onCreate(savedInstanceState);
     44         setContentView(R.layout.photoeditor_main);
     45 
     46         Intent intent = getIntent();
     47         if (Intent.ACTION_EDIT.equalsIgnoreCase(intent.getAction())) {
     48             sourceUri = intent.getData();
     49         }
     50 
     51         toolbar = (Toolbar) findViewById(R.id.toolbar);
     52         actionBar = (ActionBar) findViewById(R.id.action_bar);
     53         filterStack = new FilterStack((PhotoView) findViewById(R.id.photo_view),
     54                 new FilterStack.StackListener() {
     55 
     56                     @Override
     57                     public void onStackChanged(boolean canUndo, boolean canRedo) {
     58                         actionBar.updateButtons(canUndo, canRedo);
     59                     }
     60         }, savedInstanceState);
     61         if (savedInstanceState != null) {
     62             saveUri = savedInstanceState.getParcelable(SAVE_URI_KEY);
     63             actionBar.updateSave(saveUri == null);
     64         }
     65 
     66         // Effects-bar is initially disabled until photo is successfully loaded.
     67         effectsBar = (EffectsBar) findViewById(R.id.effects_bar);
     68         effectsBar.initialize(filterStack);
     69         effectsBar.setEnabled(false);
     70 
     71         actionBar.setClickRunnable(R.id.undo_button, createUndoRedoRunnable(true));
     72         actionBar.setClickRunnable(R.id.redo_button, createUndoRedoRunnable(false));
     73         actionBar.setClickRunnable(R.id.save_button, createSaveRunnable());
     74         actionBar.setClickRunnable(R.id.share_button, createShareRunnable());
     75         actionBar.setClickRunnable(R.id.action_bar_back, createBackRunnable());
     76     }
     77 
     78     private void openPhoto() {
     79         toolbar.showSpinner();
     80         LoadScreennailTask.Callback callback = new LoadScreennailTask.Callback() {
     81 
     82             @Override
     83             public void onComplete(final Bitmap result) {
     84                 filterStack.setPhotoSource(result, new OnDoneCallback() {
     85 
     86                     @Override
     87                     public void onDone() {
     88                         toolbar.dismissSpinner();
     89                         effectsBar.setEnabled(result != null);
     90                     }
     91                 });
     92             }
     93         };
     94         new LoadScreennailTask(this, callback).execute(sourceUri);
     95     }
     96 
     97     private Runnable createUndoRedoRunnable(final boolean undo) {
     98         return new Runnable() {
     99 
    100             @Override
    101             public void run() {
    102                 effectsBar.exit(new Runnable() {
    103 
    104                     @Override
    105                     public void run() {
    106                         toolbar.showSpinner();
    107                         OnDoneCallback callback = new OnDoneCallback() {
    108 
    109                             @Override
    110                             public void onDone() {
    111                                 toolbar.dismissSpinner();
    112                             }
    113                         };
    114                         if (undo) {
    115                             filterStack.undo(callback);
    116                         } else {
    117                             filterStack.redo(callback);
    118                         }
    119                     }
    120                 });
    121             }
    122         };
    123     }
    124 
    125     private Runnable createSaveRunnable() {
    126         return new Runnable() {
    127 
    128             @Override
    129             public void run() {
    130                 effectsBar.exit(new Runnable() {
    131 
    132                     @Override
    133                     public void run() {
    134                         toolbar.showSpinner();
    135                         filterStack.getOutputBitmap(new OnDoneBitmapCallback() {
    136 
    137                             @Override
    138                             public void onDone(Bitmap bitmap) {
    139                                 SaveCopyTask.Callback callback = new SaveCopyTask.Callback() {
    140 
    141                                     @Override
    142                                     public void onComplete(Uri result) {
    143                                         toolbar.dismissSpinner();
    144                                         saveUri = result;
    145                                         actionBar.updateSave(saveUri == null);
    146                                     }
    147                                 };
    148                                 new SaveCopyTask(PhotoEditor.this, sourceUri, callback).execute(
    149                                         bitmap);
    150                             }
    151                         });
    152                     }
    153                 });
    154             }
    155         };
    156     }
    157 
    158     private Runnable createShareRunnable() {
    159         return new Runnable() {
    160 
    161             @Override
    162             public void run() {
    163                 effectsBar.exit(new Runnable() {
    164 
    165                     @Override
    166                     public void run() {
    167                         if (saveUri != null) {
    168                             Intent intent = new Intent(Intent.ACTION_SEND);
    169                             intent.putExtra(Intent.EXTRA_STREAM, saveUri);
    170                             intent.setType("image/*");
    171                             startActivity(intent);
    172                         }
    173                     }
    174                 });
    175             }
    176         };
    177     }
    178 
    179     private Runnable createBackRunnable() {
    180         return new Runnable() {
    181 
    182             @Override
    183             public void run() {
    184                 // Exit effects or go back to the previous activity on pressing back button.
    185                 if (!effectsBar.exit(null)) {
    186                     // Pop-up a dialog if there are unsaved changes.
    187                     if (actionBar.canSave()) {
    188                         new YesCancelDialogBuilder(PhotoEditor.this, new Runnable() {
    189 
    190                             @Override
    191                             public void run() {
    192                                 // Discard unsaved photo for the result.
    193                                 finish();
    194                             }
    195                         }, R.string.discard_unsaved_photo).show();
    196                     } else {
    197                         setResult(RESULT_OK, new Intent().setData(saveUri));
    198                         finish();
    199                     }
    200                 }
    201             }
    202         };
    203     }
    204 
    205     @Override
    206     protected void onSaveInstanceState(Bundle outState) {
    207         super.onSaveInstanceState(outState);
    208         filterStack.saveStacks(outState);
    209         outState.putParcelable(SAVE_URI_KEY, saveUri);
    210     }
    211 
    212     @Override
    213     public void onBackPressed() {
    214         actionBar.clickBack();
    215     }
    216 
    217     @Override
    218     protected void onPause() {
    219         super.onPause();
    220         filterStack.onPause();
    221         // Dismiss any running progress dialog as all operations are paused.
    222         toolbar.dismissSpinner();
    223     }
    224 
    225     @Override
    226     protected void onResume() {
    227         super.onResume();
    228         filterStack.onResume();
    229         openPhoto();
    230     }
    231 }
    232