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 import android.view.ViewGroup; 25 26 import com.android.gallery3d.R; 27 28 /** 29 * Main activity of the photo editor that opens a photo and prepares tools for photo editing. 30 */ 31 public class PhotoEditor extends Activity { 32 33 private Uri sourceUri; 34 private Uri saveUri; 35 private FilterStack filterStack; 36 private ActionBar actionBar; 37 38 @Override onCreate(Bundle savedInstanceState)39 public void onCreate(Bundle savedInstanceState) { 40 super.onCreate(savedInstanceState); 41 setContentView(R.layout.photoeditor_main); 42 43 Intent intent = getIntent(); 44 if (Intent.ACTION_EDIT.equalsIgnoreCase(intent.getAction())) { 45 sourceUri = intent.getData(); 46 } 47 48 actionBar = (ActionBar) findViewById(R.id.action_bar); 49 filterStack = new FilterStack((PhotoView) findViewById(R.id.photo_view), 50 new FilterStack.StackListener() { 51 52 @Override 53 public void onStackChanged(boolean canUndo, boolean canRedo) { 54 actionBar.updateButtons(canUndo, canRedo); 55 } 56 }); 57 58 EffectsBar effectsBar = (EffectsBar) findViewById(R.id.effects_bar); 59 effectsBar.initialize(filterStack); 60 61 actionBar.setClickRunnable(R.id.undo_button, createUndoRedoRunnable(true, effectsBar)); 62 actionBar.setClickRunnable(R.id.redo_button, createUndoRedoRunnable(false, effectsBar)); 63 actionBar.setClickRunnable(R.id.save_button, createSaveRunnable(effectsBar)); 64 actionBar.setClickRunnable(R.id.share_button, createShareRunnable(effectsBar)); 65 actionBar.setClickRunnable(R.id.action_bar_back, createBackRunnable(effectsBar)); 66 } 67 createProgressDialog()68 private SpinnerProgressDialog createProgressDialog() { 69 return SpinnerProgressDialog.show((ViewGroup) findViewById(R.id.toolbar)); 70 } 71 openPhoto()72 private void openPhoto() { 73 final SpinnerProgressDialog progressDialog = createProgressDialog(); 74 LoadScreennailTask.Callback callback = new LoadScreennailTask.Callback() { 75 76 @Override 77 public void onComplete(final Bitmap result) { 78 filterStack.setPhotoSource(result, new OnDoneCallback() { 79 80 @Override 81 public void onDone() { 82 progressDialog.dismiss(); 83 } 84 }); 85 } 86 }; 87 new LoadScreennailTask(this, callback).execute(sourceUri); 88 } 89 createUndoRedoRunnable(final boolean undo, final EffectsBar effectsBar)90 private Runnable createUndoRedoRunnable(final boolean undo, final EffectsBar effectsBar) { 91 return new Runnable() { 92 93 @Override 94 public void run() { 95 effectsBar.exit(new Runnable() { 96 97 @Override 98 public void run() { 99 final SpinnerProgressDialog progressDialog = createProgressDialog(); 100 OnDoneCallback callback = new OnDoneCallback() { 101 102 @Override 103 public void onDone() { 104 progressDialog.dismiss(); 105 } 106 }; 107 if (undo) { 108 filterStack.undo(callback); 109 } else { 110 filterStack.redo(callback); 111 } 112 } 113 }); 114 } 115 }; 116 } 117 118 private Runnable createSaveRunnable(final EffectsBar effectsBar) { 119 return new Runnable() { 120 121 @Override 122 public void run() { 123 effectsBar.exit(new Runnable() { 124 125 @Override 126 public void run() { 127 final SpinnerProgressDialog progressDialog = createProgressDialog(); 128 filterStack.saveBitmap(new OnDoneBitmapCallback() { 129 130 @Override 131 public void onDone(Bitmap bitmap) { 132 SaveCopyTask.Callback callback = new SaveCopyTask.Callback() { 133 134 @Override 135 public void onComplete(Uri result) { 136 progressDialog.dismiss(); 137 actionBar.updateSave(result == null); 138 saveUri = result; 139 } 140 }; 141 new SaveCopyTask(PhotoEditor.this, sourceUri, callback).execute( 142 bitmap); 143 } 144 }); 145 } 146 }); 147 } 148 }; 149 } 150 151 private Runnable createShareRunnable(final EffectsBar effectsBar) { 152 return new Runnable() { 153 154 @Override 155 public void run() { 156 effectsBar.exit(new Runnable() { 157 158 @Override 159 public void run() { 160 if (saveUri != null) { 161 Intent intent = new Intent(Intent.ACTION_SEND); 162 intent.putExtra(Intent.EXTRA_STREAM, saveUri); 163 intent.setType("image/*"); 164 startActivity(intent); 165 } 166 } 167 }); 168 } 169 }; 170 } 171 172 private Runnable createBackRunnable(final EffectsBar effectsBar) { 173 return new Runnable() { 174 175 @Override 176 public void run() { 177 // Exit effects or go back to the previous activity on pressing back button. 178 if (!effectsBar.exit(null)) { 179 // Pop-up a dialog to save unsaved photo. 180 if (actionBar.canSave()) { 181 new YesNoCancelDialogBuilder(PhotoEditor.this, new Runnable() { 182 183 @Override 184 public void run() { 185 actionBar.clickSave(); 186 } 187 }, new Runnable() { 188 189 @Override 190 public void run() { 191 finish(); 192 } 193 }, R.string.save_photo).show(); 194 } else { 195 finish(); 196 } 197 } 198 } 199 }; 200 } 201 202 @Override 203 public void onBackPressed() { 204 actionBar.clickBack(); 205 } 206 207 @Override 208 protected void onPause() { 209 // TODO: Close running progress dialogs as all pending operations will be paused. 210 super.onPause(); 211 filterStack.onPause(); 212 } 213 214 @Override 215 protected void onResume() { 216 super.onResume(); 217 filterStack.onResume(); 218 openPhoto(); 219 } 220 } 221