FilterShowActivity.java revision 12c7c8ed14ca9dff9de64e121282f1970cbe7ae4
1a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen/* 2a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen * Copyright (C) 2012 The Android Open Source Project 3a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen * 4a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen * Licensed under the Apache License, Version 2.0 (the "License"); 5a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen * you may not use this file except in compliance with the License. 6a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen * You may obtain a copy of the License at 7a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen * 8a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen * http://www.apache.org/licenses/LICENSE-2.0 9a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen * 10a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen * Unless required by applicable law or agreed to in writing, software 11a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen * distributed under the License is distributed on an "AS IS" BASIS, 12a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen * See the License for the specific language governing permissions and 14a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen * limitations under the License. 15a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen */ 16a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen 17a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissenpackage com.android.gallery3d.filtershow; 18a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen 19a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissenimport android.annotation.TargetApi; 20a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissenimport android.app.ActionBar; 21a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissenimport android.app.Activity; 22a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissenimport android.app.ProgressDialog; 23a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissenimport android.app.WallpaperManager; 24a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissenimport android.content.ContentValues; 25a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissenimport android.content.Context; 26a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissenimport android.content.Intent; 27b1cf03160fa7e7bc6e5cf138db07a7e1ab2ecb26Marco Nelissenimport android.content.res.Configuration; 28d5fa8d5dcdf8742f03fdc165f7529d7627b0eb01Marco Nelissenimport android.content.res.Resources; 29b1cf03160fa7e7bc6e5cf138db07a7e1ab2ecb26Marco Nelissenimport android.graphics.Bitmap; 30b1cf03160fa7e7bc6e5cf138db07a7e1ab2ecb26Marco Nelissenimport android.graphics.BitmapFactory; 31b1cf03160fa7e7bc6e5cf138db07a7e1ab2ecb26Marco Nelissenimport android.graphics.Color; 32b1cf03160fa7e7bc6e5cf138db07a7e1ab2ecb26Marco Nelissenimport android.graphics.Point; 33b1cf03160fa7e7bc6e5cf138db07a7e1ab2ecb26Marco Nelissenimport android.graphics.drawable.BitmapDrawable; 34b1cf03160fa7e7bc6e5cf138db07a7e1ab2ecb26Marco Nelissenimport android.graphics.drawable.Drawable; 35b1cf03160fa7e7bc6e5cf138db07a7e1ab2ecb26Marco Nelissenimport android.net.Uri; 36b1cf03160fa7e7bc6e5cf138db07a7e1ab2ecb26Marco Nelissenimport android.os.AsyncTask; 37d5fa8d5dcdf8742f03fdc165f7529d7627b0eb01Marco Nelissenimport android.os.Bundle; 38b1cf03160fa7e7bc6e5cf138db07a7e1ab2ecb26Marco Nelissenimport android.provider.MediaStore; 39b1cf03160fa7e7bc6e5cf138db07a7e1ab2ecb26Marco Nelissenimport android.util.DisplayMetrics; 40b1cf03160fa7e7bc6e5cf138db07a7e1ab2ecb26Marco Nelissenimport android.util.Log; 41b1cf03160fa7e7bc6e5cf138db07a7e1ab2ecb26Marco Nelissenimport android.util.TypedValue; 42b1cf03160fa7e7bc6e5cf138db07a7e1ab2ecb26Marco Nelissenimport android.view.Display; 43b1cf03160fa7e7bc6e5cf138db07a7e1ab2ecb26Marco Nelissenimport android.view.LayoutInflater; 44b1cf03160fa7e7bc6e5cf138db07a7e1ab2ecb26Marco Nelissenimport android.view.Menu; 45b1cf03160fa7e7bc6e5cf138db07a7e1ab2ecb26Marco Nelissenimport android.view.MenuItem; 46b1cf03160fa7e7bc6e5cf138db07a7e1ab2ecb26Marco Nelissenimport android.view.View; 47d5fa8d5dcdf8742f03fdc165f7529d7627b0eb01Marco Nelissenimport android.view.View.OnClickListener; 48a6cdabf38b29ee98bdb3e874b4e2978dbc409624Marco Nelissenimport android.view.WindowManager; 49a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissenimport android.widget.*; 50cb5b766bb0a3ed992998a5bd66de0ee1d2223b81Marco Nelissenimport android.widget.AdapterView.OnItemClickListener; 51b1cf03160fa7e7bc6e5cf138db07a7e1ab2ecb26Marco Nelissenimport android.widget.ShareActionProvider.OnShareTargetSelectedListener; 52b1cf03160fa7e7bc6e5cf138db07a7e1ab2ecb26Marco Nelissen 53a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissenimport com.android.gallery3d.R; 54a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissenimport com.android.gallery3d.data.LocalAlbum; 55a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissenimport com.android.gallery3d.filtershow.cache.FilteringPipeline; 56a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissenimport com.android.gallery3d.filtershow.cache.ImageLoader; 57a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissenimport com.android.gallery3d.filtershow.editors.BasicEditor; 58a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissenimport com.android.gallery3d.filtershow.editors.EditorDraw; 59a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissenimport com.android.gallery3d.filtershow.editors.EditorManager; 60b1cf03160fa7e7bc6e5cf138db07a7e1ab2ecb26Marco Nelissenimport com.android.gallery3d.filtershow.editors.EditorRedEye; 61b1cf03160fa7e7bc6e5cf138db07a7e1ab2ecb26Marco Nelissenimport com.android.gallery3d.filtershow.editors.ImageOnlyEditor; 62b1cf03160fa7e7bc6e5cf138db07a7e1ab2ecb26Marco Nelissenimport com.android.gallery3d.filtershow.editors.EditorTinyPlanet; 63b1cf03160fa7e7bc6e5cf138db07a7e1ab2ecb26Marco Nelissenimport com.android.gallery3d.filtershow.filters.*; 64b1cf03160fa7e7bc6e5cf138db07a7e1ab2ecb26Marco Nelissenimport com.android.gallery3d.filtershow.imageshow.ImageCrop; 65a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissenimport com.android.gallery3d.filtershow.imageshow.ImageDraw; 66a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissenimport com.android.gallery3d.filtershow.imageshow.ImageFlip; 67a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissenimport com.android.gallery3d.filtershow.imageshow.ImageRedEye; 68a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissenimport com.android.gallery3d.filtershow.imageshow.ImageRotate; 69a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissenimport com.android.gallery3d.filtershow.imageshow.ImageShow; 70a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissenimport com.android.gallery3d.filtershow.imageshow.ImageStraighten; 71a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissenimport com.android.gallery3d.filtershow.imageshow.ImageTinyPlanet; 72a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissenimport com.android.gallery3d.filtershow.imageshow.ImageZoom; 73a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissenimport com.android.gallery3d.filtershow.imageshow.MasterImage; 74a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissenimport com.android.gallery3d.filtershow.presets.ImagePreset; 75a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissenimport com.android.gallery3d.filtershow.provider.SharedImageProvider; 76a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissenimport com.android.gallery3d.filtershow.tools.SaveCopyTask; 77a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissenimport com.android.gallery3d.filtershow.ui.FilterIconButton; 78a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissenimport com.android.gallery3d.filtershow.ui.FramedTextButton; 79a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissenimport com.android.gallery3d.filtershow.ui.Spline; 80a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissenimport com.android.gallery3d.util.GalleryUtils; 81a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen 82a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissenimport java.io.File; 83a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissenimport java.io.IOException; 84a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissenimport java.lang.ref.WeakReference; 85a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissenimport java.util.Vector; 86a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen 87a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen@TargetApi(16) 88a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissenpublic class FilterShowActivity extends Activity implements OnItemClickListener, 89a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen OnShareTargetSelectedListener { 90a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen 917e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kim // fields for supporting crop action 927e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kim public static final String CROP_ACTION = "com.android.camera.action.CROP"; 93b1cf03160fa7e7bc6e5cf138db07a7e1ab2ecb26Marco Nelissen private CropExtras mCropExtras = null; 94b1cf03160fa7e7bc6e5cf138db07a7e1ab2ecb26Marco Nelissen MasterImage mMasterImage = null; 95b1cf03160fa7e7bc6e5cf138db07a7e1ab2ecb26Marco Nelissen 96b1cf03160fa7e7bc6e5cf138db07a7e1ab2ecb26Marco Nelissen public static final String TINY_PLANET_ACTION = "com.android.camera.action.TINY_PLANET"; 97b1cf03160fa7e7bc6e5cf138db07a7e1ab2ecb26Marco Nelissen public static final String LAUNCH_FULLSCREEN = "launch-fullscreen"; 98cb5b766bb0a3ed992998a5bd66de0ee1d2223b81Marco Nelissen public static final int MAX_BMAP_IN_INTENT = 990000; 99cb5b766bb0a3ed992998a5bd66de0ee1d2223b81Marco Nelissen private final PanelController mPanelController = new PanelController(); 100cb5b766bb0a3ed992998a5bd66de0ee1d2223b81Marco Nelissen private ImageLoader mImageLoader = null; 101cb5b766bb0a3ed992998a5bd66de0ee1d2223b81Marco Nelissen private ImageShow mImageShow = null; 102cb5b766bb0a3ed992998a5bd66de0ee1d2223b81Marco Nelissen private ImageRedEye mImageRedEye = null; 103cb5b766bb0a3ed992998a5bd66de0ee1d2223b81Marco Nelissen private ImageDraw mImageDraw = null; 104cb5b766bb0a3ed992998a5bd66de0ee1d2223b81Marco Nelissen private ImageStraighten mImageStraighten = null; 105cb5b766bb0a3ed992998a5bd66de0ee1d2223b81Marco Nelissen private ImageCrop mImageCrop = null; 106cb5b766bb0a3ed992998a5bd66de0ee1d2223b81Marco Nelissen private ImageRotate mImageRotate = null; 107cb5b766bb0a3ed992998a5bd66de0ee1d2223b81Marco Nelissen private ImageFlip mImageFlip = null; 108cb5b766bb0a3ed992998a5bd66de0ee1d2223b81Marco Nelissen private ImageTinyPlanet mImageTinyPlanet = null; 109cb5b766bb0a3ed992998a5bd66de0ee1d2223b81Marco Nelissen 110cb5b766bb0a3ed992998a5bd66de0ee1d2223b81Marco Nelissen private View mListFx = null; 111cb5b766bb0a3ed992998a5bd66de0ee1d2223b81Marco Nelissen private View mListBorders = null; 112cb5b766bb0a3ed992998a5bd66de0ee1d2223b81Marco Nelissen private View mListGeometry = null; 113cb5b766bb0a3ed992998a5bd66de0ee1d2223b81Marco Nelissen private View mListColors = null; 114cb5b766bb0a3ed992998a5bd66de0ee1d2223b81Marco Nelissen private View mListFilterButtons = null; 115cb5b766bb0a3ed992998a5bd66de0ee1d2223b81Marco Nelissen private View mSaveButton = null; 116cb5b766bb0a3ed992998a5bd66de0ee1d2223b81Marco Nelissen 117cb5b766bb0a3ed992998a5bd66de0ee1d2223b81Marco Nelissen private ImageButton mFxButton = null; 118cb5b766bb0a3ed992998a5bd66de0ee1d2223b81Marco Nelissen private ImageButton mBorderButton = null; 119cb5b766bb0a3ed992998a5bd66de0ee1d2223b81Marco Nelissen private ImageButton mGeometryButton = null; 120cb5b766bb0a3ed992998a5bd66de0ee1d2223b81Marco Nelissen private ImageButton mColorsButton = null; 121cb5b766bb0a3ed992998a5bd66de0ee1d2223b81Marco Nelissen 122cb5b766bb0a3ed992998a5bd66de0ee1d2223b81Marco Nelissen private LinearLayout listColors = null; 123cb5b766bb0a3ed992998a5bd66de0ee1d2223b81Marco Nelissen private LinearLayout listFilters = null; 1247e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kim private LinearLayout listBorders = null; 1257e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kim 1267e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kim private EditorPlaceHolder mEditorPlaceHolder = new EditorPlaceHolder(this); 1277e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kim 1287e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kim private static final int SELECT_PICTURE = 1; 1297e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kim private static final String LOGTAG = "FilterShowActivity"; 1307e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kim protected static final boolean ANIMATE_PANELS = true; 1317e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kim private static int mImageBorderSize = 4; // in percent 132a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen 133a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen private boolean mShowingHistoryPanel = false; 134a6cdabf38b29ee98bdb3e874b4e2978dbc409624Marco Nelissen private boolean mShowingImageStatePanel = false; 135a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen 136a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen private final Vector<ImageShow> mImageViews = new Vector<ImageShow>(); 137a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen private final Vector<View> mListViews = new Vector<View>(); 138a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen private final Vector<ImageButton> mBottomPanelButtons = new Vector<ImageButton>(); 139a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen 140a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen private ShareActionProvider mShareActionProvider; 141cb5b766bb0a3ed992998a5bd66de0ee1d2223b81Marco Nelissen private File mSharedOutputFile = null; 142cb5b766bb0a3ed992998a5bd66de0ee1d2223b81Marco Nelissen 143cb5b766bb0a3ed992998a5bd66de0ee1d2223b81Marco Nelissen private boolean mSharingImage = false; 144cb5b766bb0a3ed992998a5bd66de0ee1d2223b81Marco Nelissen 145cb5b766bb0a3ed992998a5bd66de0ee1d2223b81Marco Nelissen private WeakReference<ProgressDialog> mSavingProgressDialog; 146cb5b766bb0a3ed992998a5bd66de0ee1d2223b81Marco Nelissen private static final int SEEK_BAR_MAX = 600; 147cb5b766bb0a3ed992998a5bd66de0ee1d2223b81Marco Nelissen 148cb5b766bb0a3ed992998a5bd66de0ee1d2223b81Marco Nelissen private LoadBitmapTask mLoadBitmapTask; 149cb5b766bb0a3ed992998a5bd66de0ee1d2223b81Marco Nelissen private FilterIconButton mNullFxFilter; 150cb5b766bb0a3ed992998a5bd66de0ee1d2223b81Marco Nelissen private FilterIconButton mNullBorderFilter; 151cb5b766bb0a3ed992998a5bd66de0ee1d2223b81Marco Nelissen private int mIconSeedSize = 140; 152cb5b766bb0a3ed992998a5bd66de0ee1d2223b81Marco Nelissen 153cb5b766bb0a3ed992998a5bd66de0ee1d2223b81Marco Nelissen @Override 154a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen public void onCreate(Bundle savedInstanceState) { 155a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen super.onCreate(savedInstanceState); 156a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen setResources(); 157a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen 158a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen Resources res = getResources(); 159a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen setupMasterImage(); 160a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen ImageFilterRS.setRenderScriptContext(this); 161a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen 162a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen ImageShow.setDefaultBackgroundColor(res.getColor(R.color.background_screen)); 163a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen // TODO: get those values from XML. 164a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen ImageZoom.setZoomedSize(getPixelsFromDip(256)); 165a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen FramedTextButton.setTextSize((int) getPixelsFromDip(14)); 166a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen FramedTextButton.setTrianglePadding((int) getPixelsFromDip(4)); 167a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen FramedTextButton.setTriangleSize((int) getPixelsFromDip(10)); 168a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen ImageShow.setTextSize((int) getPixelsFromDip(12)); 169a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen ImageShow.setTextPadding((int) getPixelsFromDip(10)); 170a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen ImageShow.setOriginalTextMargin((int) getPixelsFromDip(4)); 171a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen ImageShow.setOriginalTextSize((int) getPixelsFromDip(18)); 172a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen ImageShow.setOriginalText(res.getString(R.string.original_picture_text)); 173a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen mIconSeedSize = res.getDimensionPixelSize(R.dimen.thumbnail_size); 174a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen 175a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen Drawable curveHandle = res.getDrawable(R.drawable.camera_crop); 176a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen int curveHandleSize = (int) res.getDimension(R.dimen.crop_indicator_size); 177a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen Spline.setCurveHandle(curveHandle, curveHandleSize); 178a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen Spline.setCurveWidth((int) getPixelsFromDip(3)); 179cb5b766bb0a3ed992998a5bd66de0ee1d2223b81Marco Nelissen 180a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen setContentView(R.layout.filtershow_activity); 181a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen ActionBar actionBar = getActionBar(); 182a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen actionBar.setDisplayOptions(ActionBar.DISPLAY_SHOW_CUSTOM); 183a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen actionBar.setCustomView(R.layout.filtershow_actionbar); 184a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen 185a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen mSaveButton = actionBar.getCustomView(); 186a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen mSaveButton.setOnClickListener(new OnClickListener() { 187a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen @Override 188a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen public void onClick(View view) { 189a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen saveImage(); 190a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen } 191a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen }); 192a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen 193a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen mImageLoader = new ImageLoader(this, getApplicationContext()); 194a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen 195a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen listFilters = (LinearLayout) findViewById(R.id.listFilters); 196a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen listBorders = (LinearLayout) findViewById(R.id.listBorders); 197a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen listColors = (LinearLayout) findViewById(R.id.listColorsFx); 198a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen 199a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen mImageShow = (ImageShow) findViewById(R.id.imageShow); 200a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen mImageStraighten = (ImageStraighten) findViewById(R.id.imageStraighten); 201a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen mImageCrop = (ImageCrop) findViewById(R.id.imageCrop); 202a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen mImageRotate = (ImageRotate) findViewById(R.id.imageRotate); 203a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen mImageFlip = (ImageFlip) findViewById(R.id.imageFlip); 204a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen mImageTinyPlanet = (ImageTinyPlanet) findViewById(R.id.imageTinyPlanet); 205a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen mImageRedEye = (ImageRedEye) findViewById(R.id.imageRedEyes); 206a98478bfbcc0f7fb4b164d3dce40ca96df75667dMarco Nelissen mImageDraw = (ImageDraw) findViewById(R.id.imageDraw); 207 208 mImageCrop.setAspectTextSize((int) getPixelsFromDip(18)); 209 ImageCrop.setTouchTolerance((int) getPixelsFromDip(25)); 210 ImageCrop.setMinCropSize((int) getPixelsFromDip(55)); 211 mImageViews.add(mImageShow); 212 mImageViews.add(mImageStraighten); 213 mImageViews.add(mImageCrop); 214 mImageViews.add(mImageRotate); 215 mImageViews.add(mImageFlip); 216 mImageViews.add(mImageTinyPlanet); 217 mImageViews.add(mImageRedEye); 218 219 mEditorPlaceHolder.setContainer((FrameLayout) findViewById(R.id.editorContainer)); 220 mEditorPlaceHolder.addEditor(new EditorDraw()); 221 mEditorPlaceHolder.addEditor(new BasicEditor()); 222 mEditorPlaceHolder.addEditor(new ImageOnlyEditor()); 223 mEditorPlaceHolder.addEditor(new EditorTinyPlanet()); 224 mEditorPlaceHolder.addEditor(new EditorRedEye()); 225 EditorManager.addEditors(mEditorPlaceHolder); 226 mEditorPlaceHolder.setOldViews(mImageViews); 227 mEditorPlaceHolder.setImageLoader(mImageLoader); 228 229 mEditorPlaceHolder.hide(); 230 231 mListFx = findViewById(R.id.fxList); 232 mListBorders = findViewById(R.id.bordersList); 233 mListGeometry = findViewById(R.id.geometryList); 234 mListFilterButtons = findViewById(R.id.filterButtonsList); 235 mListColors = findViewById(R.id.colorsFxList); 236 mListViews.add(mListFx); 237 mListViews.add(mListBorders); 238 mListViews.add(mListGeometry); 239 mListViews.add(mListFilterButtons); 240 mListViews.add(mListColors); 241 242 mFxButton = (ImageButton) findViewById(R.id.fxButton); 243 mBorderButton = (ImageButton) findViewById(R.id.borderButton); 244 mGeometryButton = (ImageButton) findViewById(R.id.geometryButton); 245 mColorsButton = (ImageButton) findViewById(R.id.colorsButton); 246 247 mBottomPanelButtons.add(mFxButton); 248 mBottomPanelButtons.add(mBorderButton); 249 mBottomPanelButtons.add(mGeometryButton); 250 mBottomPanelButtons.add(mColorsButton); 251 252 mImageShow.setImageLoader(mImageLoader); 253 mImageStraighten.setImageLoader(mImageLoader); 254 mImageCrop.setImageLoader(mImageLoader); 255 mImageRotate.setImageLoader(mImageLoader); 256 mImageFlip.setImageLoader(mImageLoader); 257 mImageTinyPlanet.setImageLoader(mImageLoader); 258 mImageRedEye.setImageLoader(mImageLoader); 259 mImageDraw.setImageLoader(mImageLoader); 260 261 mPanelController.setActivity(this); 262 mPanelController.setEditorPlaceHolder(mEditorPlaceHolder); 263 264 mPanelController.addImageView(findViewById(R.id.imageShow)); 265 mPanelController.addImageView(findViewById(R.id.imageStraighten)); 266 mPanelController.addImageView(findViewById(R.id.imageCrop)); 267 mPanelController.addImageView(findViewById(R.id.imageRotate)); 268 mPanelController.addImageView(findViewById(R.id.imageFlip)); 269 mPanelController.addImageView(findViewById(R.id.imageTinyPlanet)); 270 mPanelController.addImageView(findViewById(R.id.imageRedEyes)); 271 mPanelController.addImageView(findViewById(R.id.imageDraw)); 272 273 mPanelController.addPanel(mFxButton, mListFx, 0); 274 mPanelController.addPanel(mBorderButton, mListBorders, 1); 275 276 mPanelController.addPanel(mGeometryButton, mListGeometry, 2); 277 mPanelController.addComponent(mGeometryButton, findViewById(R.id.straightenButton)); 278 mPanelController.addComponent(mGeometryButton, findViewById(R.id.cropButton)); 279 mPanelController.addComponent(mGeometryButton, findViewById(R.id.rotateButton)); 280 mPanelController.addComponent(mGeometryButton, findViewById(R.id.flipButton)); 281 mPanelController.addComponent(mGeometryButton, findViewById(R.id.redEyeButton)); 282 283 mPanelController.addPanel(mColorsButton, mListColors, 3); 284 285 Vector<FilterRepresentation> filtersRepresentations = new Vector<FilterRepresentation>(); 286 FiltersManager.addFilterRepresentations(filtersRepresentations); 287 for (FilterRepresentation representation : filtersRepresentations) { 288 setupFilterRepresentationButton(representation, listColors, mColorsButton); 289 } 290 291 292 mPanelController.addView(findViewById(R.id.applyEffect)); 293 findViewById(R.id.resetOperationsButton).setOnClickListener( 294 createOnClickResetOperationsButton()); 295 296 ListView operationsList = (ListView) findViewById(R.id.operationsList); 297 operationsList.setAdapter(mMasterImage.getHistory()); 298 operationsList.setOnItemClickListener(this); 299 ListView imageStateList = (ListView) findViewById(R.id.imageStateList); 300 imageStateList.setAdapter(mMasterImage.getState()); 301 mImageLoader.setAdapter(mMasterImage.getHistory()); 302 303 fillListImages(listFilters); 304 LoadBordersTask loadBorders = new LoadBordersTask(listBorders); 305 loadBorders.execute(); 306 307 mPanelController.setRowPanel(findViewById(R.id.secondRowPanel)); 308 mPanelController.setUtilityPanel(this, findViewById(R.id.filterButtonsList), 309 findViewById(R.id.panelAccessoryViewList), 310 findViewById(R.id.applyEffect)); 311 312 mPanelController.setCurrentPanel(mFxButton); 313 Intent intent = getIntent(); 314 if (intent.getBooleanExtra(LAUNCH_FULLSCREEN, false)) { 315 getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN); 316 } 317 318 if (intent.getData() != null) { 319 startLoadBitmap(intent.getData()); 320 } else { 321 pickImage(); 322 } 323 324 // Handle behavior for various actions 325 String action = intent.getAction(); 326 if (action.equalsIgnoreCase(CROP_ACTION)) { 327 Bundle extras = intent.getExtras(); 328 if (extras != null) { 329 mCropExtras = new CropExtras(extras.getInt(CropExtras.KEY_OUTPUT_X, 0), 330 extras.getInt(CropExtras.KEY_OUTPUT_Y, 0), 331 extras.getBoolean(CropExtras.KEY_SCALE, true) && 332 extras.getBoolean(CropExtras.KEY_SCALE_UP_IF_NEEDED, false), 333 extras.getInt(CropExtras.KEY_ASPECT_X, 0), 334 extras.getInt(CropExtras.KEY_ASPECT_Y, 0), 335 extras.getBoolean(CropExtras.KEY_SET_AS_WALLPAPER, false), 336 extras.getBoolean(CropExtras.KEY_RETURN_DATA, false), 337 (Uri) extras.getParcelable(MediaStore.EXTRA_OUTPUT), 338 extras.getString(CropExtras.KEY_OUTPUT_FORMAT), 339 extras.getBoolean(CropExtras.KEY_SHOW_WHEN_LOCKED, false), 340 extras.getFloat(CropExtras.KEY_SPOTLIGHT_X), 341 extras.getFloat(CropExtras.KEY_SPOTLIGHT_Y)); 342 343 if (mCropExtras.getShowWhenLocked()) { 344 getWindow().addFlags(WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED); 345 } 346 mImageShow.getImagePreset().mGeoData.setCropExtras(mCropExtras); 347 348 mImageCrop.setExtras(mCropExtras); 349 String s = getString(R.string.Fixed); 350 mImageCrop.setAspectString(s); 351 mImageCrop.setCropActionFlag(true); 352 mPanelController.setFixedAspect(mCropExtras.getAspectX() > 0 353 && mCropExtras.getAspectY() > 0); 354 } 355 mPanelController.showComponent(findViewById(R.id.cropButton)); 356 } else if (action.equalsIgnoreCase(TINY_PLANET_ACTION)) { 357 mPanelController.showComponent(findViewById(R.id.tinyplanetButton)); 358 } 359 } 360 361 private void startLoadBitmap(Uri uri) { 362 final View filters = findViewById(R.id.filtersPanel); 363 final View loading = findViewById(R.id.loading); 364 final View imageShow = findViewById(R.id.imageShow); 365 imageShow.setVisibility(View.INVISIBLE); 366 filters.setVisibility(View.INVISIBLE); 367 loading.setVisibility(View.VISIBLE); 368 369 View tinyPlanetView = findViewById(R.id.tinyplanetButton); 370 if (tinyPlanetView != null) { 371 tinyPlanetView.setVisibility(View.GONE); 372 } 373 mLoadBitmapTask = new LoadBitmapTask(tinyPlanetView); 374 mLoadBitmapTask.execute(uri); 375 } 376 377 private class LoadBordersTask extends AsyncTask<Void, Boolean, Boolean> { 378 Vector<FilterRepresentation> mBorders; 379 LinearLayout mList; 380 381 public LoadBordersTask(LinearLayout list) { 382 mList = list; 383 mBorders = new Vector<FilterRepresentation>(); 384 } 385 386 @Override 387 protected Boolean doInBackground(Void... params) { 388 mBorders.add(new FilterImageBorderRepresentation(0)); 389 mBorders.add(new FilterImageBorderRepresentation(R.drawable.filtershow_border_4x5)); 390 mBorders.add(new FilterImageBorderRepresentation(R.drawable.filtershow_border_brush)); 391 mBorders.add(new FilterImageBorderRepresentation(R.drawable.filtershow_border_grunge)); 392 mBorders.add(new FilterImageBorderRepresentation(R.drawable.filtershow_border_sumi_e)); 393 mBorders.add(new FilterImageBorderRepresentation(R.drawable.filtershow_border_tape)); 394 mBorders.add(new FilterColorBorderRepresentation(Color.BLACK, mImageBorderSize, 0)); 395 mBorders.add(new FilterColorBorderRepresentation(Color.BLACK, mImageBorderSize, mImageBorderSize)); 396 mBorders.add(new FilterColorBorderRepresentation(Color.WHITE, mImageBorderSize, 0)); 397 mBorders.add(new FilterColorBorderRepresentation(Color.WHITE, mImageBorderSize, mImageBorderSize)); 398 int creamColor = Color.argb(255, 237, 237, 227); 399 mBorders.add(new FilterColorBorderRepresentation(creamColor, mImageBorderSize, 0)); 400 mBorders.add(new FilterColorBorderRepresentation(creamColor, mImageBorderSize, mImageBorderSize)); 401 return true; 402 } 403 404 @Override 405 protected void onPostExecute(Boolean result) { 406 if (!result) { 407 return; 408 } 409 for (int i = 0; i < mBorders.size(); i++) { 410 FilterRepresentation filter = mBorders.elementAt(i); 411 filter.setName(getString(R.string.borders)); 412 if (i == 0) { 413 filter.setName(getString(R.string.none)); 414 } 415 FilterIconButton b = setupFilterRepresentationButton(filter, mList, mBorderButton); 416 if (i == 0) { 417 mNullBorderFilter = b; 418 mNullBorderFilter.setSelected(true); 419 } 420 } 421 } 422 } 423 424 private class LoadBitmapTask extends AsyncTask<Uri, Boolean, Boolean> { 425 View mTinyPlanetButton; 426 int mBitmapSize; 427 428 public LoadBitmapTask(View button) { 429 mTinyPlanetButton = button; 430 mBitmapSize = getScreenImageSize(); 431 } 432 433 @Override 434 protected Boolean doInBackground(Uri... params) { 435 if (!mImageLoader.loadBitmap(params[0], mBitmapSize)) { 436 return false; 437 } 438 publishProgress(mImageLoader.queryLightCycle360()); 439 return true; 440 } 441 442 @Override 443 protected void onProgressUpdate(Boolean... values) { 444 super.onProgressUpdate(values); 445 if (isCancelled()) { 446 return; 447 } 448 if (values[0]) { 449 mTinyPlanetButton.setVisibility(View.VISIBLE); 450 } 451 } 452 453 @Override 454 protected void onPostExecute(Boolean result) { 455 456 if (isCancelled()) { 457 return; 458 } 459 460 if (!result) { 461 cannotLoadImage(); 462 } 463 464 final View loading = findViewById(R.id.loading); 465 loading.setVisibility(View.GONE); 466 final View filters = findViewById(R.id.filtersPanel); 467 filters.setVisibility(View.VISIBLE); 468 float y = filters.getY(); 469 filters.setY(y + filters.getHeight()); 470 filters.animate().setDuration(600).y(y).withLayer().start(); 471 final View imageShow = findViewById(R.id.imageShow); 472 imageShow.setVisibility(View.VISIBLE); 473 474 Bitmap largeBitmap = mImageLoader.getOriginalBitmapLarge(); 475 FilteringPipeline pipeline = FilteringPipeline.getPipeline(); 476 pipeline.setOriginal(largeBitmap); 477 float previewScale = (float) largeBitmap.getWidth() / (float) mImageLoader.getOriginalBounds().width(); 478 pipeline.setPreviewScaleFactor(previewScale); 479 480 Bitmap bmap = mImageLoader.getOriginalBitmapSmall(); 481 if (bmap != null && bmap.getWidth() > 0 && bmap.getHeight() > 0) { 482 float w = bmap.getWidth(); 483 float h = bmap.getHeight(); 484 float f = mIconSeedSize / Math.min(w, h); 485 w = w * f; 486 h = h * f; 487 bmap = Bitmap.createScaledBitmap(bmap, (int) w, (int) h, true); 488 489 int num_colors_buttons = listColors.getChildCount(); 490 for (int i = 0; i < num_colors_buttons; i++) { 491 FilterIconButton b = (FilterIconButton) listColors.getChildAt(i); 492 493 b.setIcon(bmap); 494 } 495 int num_filters_buttons = listFilters.getChildCount(); 496 for (int i = 0; i < num_filters_buttons; i++) { 497 FilterIconButton b = (FilterIconButton) listFilters.getChildAt(i); 498 499 b.setIcon(bmap); 500 } 501 int num_borders_buttons = listBorders.getChildCount(); 502 for (int i = 0; i < num_borders_buttons; i++) { 503 FilterIconButton b = (FilterIconButton) listBorders.getChildAt(i); 504 505 b.setIcon(bmap); 506 } 507 508 } 509 mLoadBitmapTask = null; 510 super.onPostExecute(result); 511 } 512 513 } 514 515 @Override 516 protected void onDestroy() { 517 if (mLoadBitmapTask != null) { 518 mLoadBitmapTask.cancel(false); 519 } 520 super.onDestroy(); 521 } 522 523 private int translateMainPanel(View viewPanel) { 524 int accessoryPanelWidth = viewPanel.getWidth(); 525 int mainViewWidth = findViewById(R.id.mainView).getWidth(); 526 int mainPanelWidth = mImageShow.getDisplayedImageBounds().width(); 527 if (mainPanelWidth == 0) { 528 mainPanelWidth = mainViewWidth; 529 } 530 int filtersPanelWidth = findViewById(R.id.filtersPanel).getWidth(); 531 if (mainPanelWidth < filtersPanelWidth) { 532 mainPanelWidth = filtersPanelWidth; 533 } 534 int leftOver = mainViewWidth - mainPanelWidth - accessoryPanelWidth; 535 if (leftOver < 0) { 536 return -accessoryPanelWidth; 537 } 538 return 0; 539 } 540 541 private int getScreenImageSize() { 542 DisplayMetrics metrics = new DisplayMetrics(); 543 Display display = getWindowManager().getDefaultDisplay(); 544 Point size = new Point(); 545 display.getSize(size); 546 display.getMetrics(metrics); 547 int msize = Math.min(size.x, size.y); 548 return (133 * msize) / metrics.densityDpi; 549 } 550 551 private void showSavingProgress(String albumName) { 552 ProgressDialog progress; 553 if (mSavingProgressDialog != null) { 554 progress = mSavingProgressDialog.get(); 555 if (progress != null) { 556 progress.show(); 557 return; 558 } 559 } 560 // TODO: Allow cancellation of the saving process 561 String progressText; 562 if (albumName == null) { 563 progressText = getString(R.string.saving_image); 564 } else { 565 progressText = getString(R.string.filtershow_saving_image, albumName); 566 } 567 progress = ProgressDialog.show(this, "", progressText, true, false); 568 mSavingProgressDialog = new WeakReference<ProgressDialog>(progress); 569 } 570 571 private void hideSavingProgress() { 572 if (mSavingProgressDialog != null) { 573 ProgressDialog progress = mSavingProgressDialog.get(); 574 if (progress != null) 575 progress.dismiss(); 576 } 577 } 578 579 public void completeSaveImage(Uri saveUri) { 580 if (mSharingImage && mSharedOutputFile != null) { 581 // Image saved, we unblock the content provider 582 Uri uri = Uri.withAppendedPath(SharedImageProvider.CONTENT_URI, 583 Uri.encode(mSharedOutputFile.getAbsolutePath())); 584 ContentValues values = new ContentValues(); 585 values.put(SharedImageProvider.PREPARE, false); 586 getContentResolver().insert(uri, values); 587 } 588 setResult(RESULT_OK, new Intent().setData(saveUri)); 589 hideSavingProgress(); 590 finish(); 591 } 592 593 @Override 594 public boolean onShareTargetSelected(ShareActionProvider arg0, Intent arg1) { 595 // First, let's tell the SharedImageProvider that it will need to wait 596 // for the image 597 Uri uri = Uri.withAppendedPath(SharedImageProvider.CONTENT_URI, 598 Uri.encode(mSharedOutputFile.getAbsolutePath())); 599 ContentValues values = new ContentValues(); 600 values.put(SharedImageProvider.PREPARE, true); 601 getContentResolver().insert(uri, values); 602 mSharingImage = true; 603 604 // Process and save the image in the background. 605 showSavingProgress(null); 606 mImageShow.saveImage(this, mSharedOutputFile); 607 return true; 608 } 609 610 private Intent getDefaultShareIntent() { 611 Intent intent = new Intent(Intent.ACTION_SEND); 612 intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET); 613 intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); 614 intent.setType(SharedImageProvider.MIME_TYPE); 615 mSharedOutputFile = SaveCopyTask.getNewFile(this, mImageLoader.getUri()); 616 Uri uri = Uri.withAppendedPath(SharedImageProvider.CONTENT_URI, 617 Uri.encode(mSharedOutputFile.getAbsolutePath())); 618 intent.putExtra(Intent.EXTRA_STREAM, uri); 619 return intent; 620 } 621 622 @Override 623 public boolean onCreateOptionsMenu(Menu menu) { 624 getMenuInflater().inflate(R.menu.filtershow_activity_menu, menu); 625 MenuItem showHistory = menu.findItem(R.id.operationsButton); 626 if (mShowingHistoryPanel) { 627 showHistory.setTitle(R.string.hide_history_panel); 628 } else { 629 showHistory.setTitle(R.string.show_history_panel); 630 } 631 MenuItem showState = menu.findItem(R.id.showImageStateButton); 632 if (mShowingImageStatePanel) { 633 showState.setTitle(R.string.hide_imagestate_panel); 634 } else { 635 showState.setTitle(R.string.show_imagestate_panel); 636 } 637 mShareActionProvider = (ShareActionProvider) menu.findItem(R.id.menu_share) 638 .getActionProvider(); 639 mShareActionProvider.setShareIntent(getDefaultShareIntent()); 640 mShareActionProvider.setOnShareTargetSelectedListener(this); 641 642 MenuItem undoItem = menu.findItem(R.id.undoButton); 643 MenuItem redoItem = menu.findItem(R.id.redoButton); 644 MenuItem resetItem = menu.findItem(R.id.resetHistoryButton); 645 mMasterImage.getHistory().setMenuItems(undoItem, redoItem, resetItem); 646 return true; 647 } 648 649 @Override 650 public void onPause() { 651 super.onPause(); 652 if (mShareActionProvider != null) { 653 mShareActionProvider.setOnShareTargetSelectedListener(null); 654 } 655 } 656 657 @Override 658 public void onResume() { 659 super.onResume(); 660 if (mShareActionProvider != null) { 661 mShareActionProvider.setOnShareTargetSelectedListener(this); 662 } 663 } 664 665 @Override 666 public boolean onOptionsItemSelected(MenuItem item) { 667 switch (item.getItemId()) { 668 case R.id.undoButton: { 669 HistoryAdapter adapter = mMasterImage.getHistory(); 670 int position = adapter.undo(); 671 mMasterImage.onHistoryItemClick(position); 672 mImageShow.showToast("Undo"); 673 invalidateViews(); 674 return true; 675 } 676 case R.id.redoButton: { 677 HistoryAdapter adapter = mMasterImage.getHistory(); 678 int position = adapter.redo(); 679 mMasterImage.onHistoryItemClick(position); 680 mImageShow.showToast("Redo"); 681 invalidateViews(); 682 return true; 683 } 684 case R.id.resetHistoryButton: { 685 resetHistory(); 686 return true; 687 } 688 case R.id.showImageStateButton: { 689 toggleImageStatePanel(); 690 return true; 691 } 692 case R.id.operationsButton: { 693 toggleHistoryPanel(); 694 return true; 695 } 696 case android.R.id.home: { 697 saveImage(); 698 return true; 699 } 700 } 701 return false; 702 } 703 704 public void enableSave(boolean enable) { 705 if (mSaveButton != null) 706 mSaveButton.setEnabled(enable); 707 } 708 709 public FilterIconButton setupFilterRepresentationButton(FilterRepresentation representation, LinearLayout panel, View button) { 710 LayoutInflater inflater = 711 (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE); 712 FilterIconButton icon = (FilterIconButton) inflater.inflate(R.layout.filtericonbutton, 713 panel, false); 714 if (representation.getTextId() != 0) { 715 representation.setName(getString(representation.getTextId())); 716 } 717 String text = representation.getName(); 718 icon.setup(text, mPanelController, panel); 719 icon.setFilterRepresentation(representation); 720 if (representation instanceof FilterTinyPlanetRepresentation) { 721 // needed to hide tinyplanet on startup 722 icon.setId(R.id.tinyplanetButton); 723 } 724 mPanelController.addComponent(button, icon); 725 panel.addView(icon); 726 return icon; 727 } 728 729 private void fillListImages(LinearLayout listFilters) { 730 // TODO: use listview 731 // TODO: load the filters straight from the filesystem 732 733 FilterFxRepresentation[] fxArray = new FilterFxRepresentation[18]; 734 int p = 0; 735 736 int[] drawid = { 737 R.drawable.filtershow_fx_0005_punch, 738 R.drawable.filtershow_fx_0000_vintage, 739 R.drawable.filtershow_fx_0004_bw_contrast, 740 R.drawable.filtershow_fx_0002_bleach, 741 R.drawable.filtershow_fx_0001_instant, 742 R.drawable.filtershow_fx_0007_washout, 743 R.drawable.filtershow_fx_0003_blue_crush, 744 R.drawable.filtershow_fx_0008_washout_color, 745 R.drawable.filtershow_fx_0006_x_process 746 }; 747 748 int[] fxNameid = { 749 R.string.ffx_punch, 750 R.string.ffx_vintage, 751 R.string.ffx_bw_contrast, 752 R.string.ffx_bleach, 753 R.string.ffx_instant, 754 R.string.ffx_washout, 755 R.string.ffx_blue_crush, 756 R.string.ffx_washout_color, 757 R.string.ffx_x_process 758 }; 759 760 ImagePreset preset = new ImagePreset(getString(R.string.history_original)); // empty 761 preset.setImageLoader(mImageLoader); 762 763 BitmapFactory.Options o = new BitmapFactory.Options(); 764 o.inScaled = false; 765 766 for (int i = 0; i < drawid.length; i++) { 767 Bitmap b = BitmapFactory.decodeResource(getResources(), drawid[i], o); 768 FilterFxRepresentation fx = new FilterFxRepresentation(getString(fxNameid[i]), drawid[i], fxNameid[i]); 769 fx.setFxBitmap(b); 770 fxArray[p++] = fx; 771 } 772 773 FilterFxRepresentation nullFx = new FilterFxRepresentation(getString(R.string.none), 0, R.string.none); 774 mNullFxFilter = setupFilterRepresentationButton(nullFx, listFilters, mFxButton); 775 mNullFxFilter.setSelected(true); 776 777 for (int i = 0; i < p; i++) { 778 setupFilterRepresentationButton(fxArray[i], listFilters, mFxButton); 779 } 780 781 // Default preset (original) 782 mMasterImage.setPreset(preset, true); 783 } 784 785 // ////////////////////////////////////////////////////////////////////////////// 786 // Some utility functions 787 // TODO: finish the cleanup. 788 789 public void showOriginalViews(boolean value) { 790 for (ImageShow views : mImageViews) { 791 views.showOriginal(value); 792 } 793 } 794 795 public void invalidateViews() { 796 for (ImageShow views : mImageViews) { 797 views.invalidate(); 798 views.updateImage(); 799 } 800 } 801 802 public void hideListViews() { 803 for (View view : mListViews) { 804 view.setVisibility(View.GONE); 805 } 806 } 807 808 public void hideImageViews() { 809 mImageShow.setShowControls(false); // reset 810 for (View view : mImageViews) { 811 view.setVisibility(View.GONE); 812 } 813 mEditorPlaceHolder.hide(); 814 } 815 816 public void unselectBottomPanelButtons() { 817 for (ImageButton button : mBottomPanelButtons) { 818 button.setSelected(false); 819 } 820 } 821 822 public void unselectPanelButtons(Vector<ImageButton> buttons) { 823 for (ImageButton button : buttons) { 824 button.setSelected(false); 825 } 826 } 827 828 public void disableFilterButtons() { 829 for (ImageButton b : mBottomPanelButtons) { 830 b.setEnabled(false); 831 b.setClickable(false); 832 b.setAlpha(0.4f); 833 } 834 } 835 836 public void enableFilterButtons() { 837 for (ImageButton b : mBottomPanelButtons) { 838 b.setEnabled(true); 839 b.setClickable(true); 840 b.setAlpha(1.0f); 841 } 842 } 843 844 // ////////////////////////////////////////////////////////////////////////////// 845 // imageState panel... 846 847 public boolean isShowingHistoryPanel() { 848 return mShowingHistoryPanel; 849 } 850 851 private void toggleImageStatePanel() { 852 final View view = findViewById(R.id.mainPanel); 853 final View viewList = findViewById(R.id.imageStatePanel); 854 855 if (mShowingHistoryPanel) { 856 findViewById(R.id.historyPanel).setVisibility(View.INVISIBLE); 857 mShowingHistoryPanel = false; 858 } 859 860 int translate = translateMainPanel(viewList); 861 if (!mShowingImageStatePanel) { 862 mShowingImageStatePanel = true; 863 view.animate().setDuration(200).x(translate) 864 .withLayer().withEndAction(new Runnable() { 865 @Override 866 public void run() { 867 viewList.setAlpha(0); 868 viewList.setVisibility(View.VISIBLE); 869 viewList.animate().setDuration(100) 870 .alpha(1.0f).start(); 871 } 872 }).start(); 873 } else { 874 mShowingImageStatePanel = false; 875 viewList.setVisibility(View.INVISIBLE); 876 view.animate().setDuration(200).x(0).withLayer() 877 .start(); 878 } 879 invalidateOptionsMenu(); 880 } 881 882 @Override 883 public void onConfigurationChanged(Configuration newConfig) 884 { 885 super.onConfigurationChanged(newConfig); 886 setResources(); 887 if (mShowingHistoryPanel) { 888 toggleHistoryPanel(); 889 } 890 } 891 892 public void setupMasterImage() { 893 HistoryAdapter mHistoryAdapter = new HistoryAdapter( 894 this, R.layout.filtershow_history_operation_row, 895 R.id.rowTextView); 896 ImageStateAdapter mImageStateAdapter = new ImageStateAdapter(this, 897 R.layout.filtershow_imagestate_row); 898 899 MasterImage.reset(); 900 mMasterImage = MasterImage.getImage(); 901 mMasterImage.setHistoryAdapter(mHistoryAdapter); 902 mMasterImage.setStateAdapter(mImageStateAdapter); 903 mMasterImage.setActivity(this); 904 } 905 906 // ////////////////////////////////////////////////////////////////////////////// 907 // history panel... 908 909 public void toggleHistoryPanel() { 910 final View view = findViewById(R.id.mainPanel); 911 final View viewList = findViewById(R.id.historyPanel); 912 913 if (mShowingImageStatePanel) { 914 findViewById(R.id.imageStatePanel).setVisibility(View.INVISIBLE); 915 mShowingImageStatePanel = false; 916 } 917 918 int translate = translateMainPanel(viewList); 919 if (!mShowingHistoryPanel) { 920 mShowingHistoryPanel = true; 921 view.animate().setDuration(200).x(translate) 922 .withLayer().withEndAction(new Runnable() { 923 @Override 924 public void run() { 925 viewList.setAlpha(0); 926 viewList.setVisibility(View.VISIBLE); 927 viewList.animate().setDuration(100) 928 .alpha(1.0f).start(); 929 } 930 }).start(); 931 } else { 932 mShowingHistoryPanel = false; 933 viewList.setVisibility(View.INVISIBLE); 934 view.animate().setDuration(200).x(0).withLayer() 935 .start(); 936 } 937 invalidateOptionsMenu(); 938 } 939 940 public void dispatchNullFilterClick() { 941 mNullFxFilter.onClick(mNullFxFilter); 942 mNullBorderFilter.onClick(mNullBorderFilter); 943 } 944 945 void resetHistory() { 946 dispatchNullFilterClick(); 947 HistoryAdapter adapter = mMasterImage.getHistory(); 948 adapter.reset(); 949 ImagePreset original = new ImagePreset(adapter.getItem(0)); 950 mMasterImage.setPreset(original, true); 951 mPanelController.resetParameters(); 952 invalidateViews(); 953 } 954 955 // reset button in the history panel. 956 private OnClickListener createOnClickResetOperationsButton() { 957 return new View.OnClickListener() { 958 @Override 959 public void onClick(View v) { 960 resetHistory(); 961 } 962 }; 963 } 964 965 @Override 966 public void onBackPressed() { 967 if (mPanelController.onBackPressed()) { 968 saveImage(); 969 } 970 } 971 972 public void cannotLoadImage() { 973 CharSequence text = getString(R.string.cannot_load_image); 974 Toast toast = Toast.makeText(this, text, Toast.LENGTH_SHORT); 975 toast.show(); 976 finish(); 977 } 978 979 // ////////////////////////////////////////////////////////////////////////////// 980 981 public float getPixelsFromDip(float value) { 982 Resources r = getResources(); 983 return TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, value, 984 r.getDisplayMetrics()); 985 } 986 987 @Override 988 public void onItemClick(AdapterView<?> parent, View view, int position, 989 long id) { 990 mMasterImage.onHistoryItemClick(position); 991 invalidateViews(); 992 } 993 994 public void pickImage() { 995 Intent intent = new Intent(); 996 intent.setType("image/*"); 997 intent.setAction(Intent.ACTION_GET_CONTENT); 998 startActivityForResult(Intent.createChooser(intent, getString(R.string.select_image)), 999 SELECT_PICTURE); 1000 } 1001 1002 @Override 1003 public void onActivityResult(int requestCode, int resultCode, Intent data) { 1004 if (resultCode == RESULT_OK) { 1005 if (requestCode == SELECT_PICTURE) { 1006 Uri selectedImageUri = data.getData(); 1007 startLoadBitmap(selectedImageUri); 1008 } 1009 } 1010 } 1011 1012 private boolean mSaveToExtraUri = false; 1013 private boolean mSaveAsWallpaper = false; 1014 private boolean mReturnAsExtra = false; 1015 private boolean outputted = false; 1016 1017 public void saveImage() { 1018 if (mCropExtras != null) { 1019 if (mCropExtras.getExtraOutput() != null) { 1020 mSaveToExtraUri = true; 1021 outputted = true; 1022 } 1023 if (mCropExtras.getSetAsWallpaper()) { 1024 mSaveAsWallpaper = true; 1025 outputted = true; 1026 } 1027 if (mCropExtras.getReturnData()) { 1028 1029 mReturnAsExtra = true; 1030 outputted = true; 1031 } 1032 1033 if (outputted) { 1034 mImageShow.getImagePreset().mGeoData.setUseCropExtrasFlag(true); 1035 showSavingProgress(null); 1036 mImageShow.returnFilteredResult(this); 1037 } 1038 } 1039 if (!outputted) { 1040 if (mImageShow.hasModifications()) { 1041 // Get the name of the album, to which the image will be saved 1042 File saveDir = SaveCopyTask.getFinalSaveDirectory(this, mImageLoader.getUri()); 1043 int bucketId = GalleryUtils.getBucketId(saveDir.getPath()); 1044 String albumName = LocalAlbum.getLocalizedName(getResources(), bucketId, null); 1045 showSavingProgress(albumName); 1046 mImageShow.saveImage(this, null); 1047 } else { 1048 done(); 1049 } 1050 } 1051 } 1052 1053 public void onFilteredResult(Bitmap filtered) { 1054 Intent intent = new Intent(); 1055 intent.putExtra(CropExtras.KEY_CROPPED_RECT, mImageShow.getImageCropBounds()); 1056 if (mSaveToExtraUri) { 1057 mImageShow.saveToUri(filtered, mCropExtras.getExtraOutput(), 1058 mCropExtras.getOutputFormat(), this); 1059 } 1060 if (mSaveAsWallpaper) { 1061 try { 1062 WallpaperManager.getInstance(this).setBitmap(filtered); 1063 } catch (IOException e) { 1064 Log.w(LOGTAG, "fail to set wall paper", e); 1065 } 1066 } 1067 if (mReturnAsExtra) { 1068 if (filtered != null) { 1069 int bmapSize = filtered.getRowBytes() * filtered.getHeight(); 1070 /* 1071 * Max size of Binder transaction buffer is 1Mb, so constrain 1072 * Bitmap to be somewhat less than this, otherwise we get 1073 * TransactionTooLargeExceptions. 1074 */ 1075 if (bmapSize > MAX_BMAP_IN_INTENT) { 1076 Log.w(LOGTAG, "Bitmap too large to be returned via intent"); 1077 } else { 1078 intent.putExtra(CropExtras.KEY_DATA, filtered); 1079 } 1080 } 1081 } 1082 setResult(RESULT_OK, intent); 1083 if (!mSaveToExtraUri) { 1084 done(); 1085 } 1086 } 1087 1088 public void done() { 1089 if (outputted) { 1090 hideSavingProgress(); 1091 } 1092 finish(); 1093 } 1094 1095 private void setResources() { 1096 ImageFilterBorder filterBorder = (ImageFilterBorder) FiltersManager.getManager().getFilter(ImageFilterBorder.class); 1097 filterBorder.setResources(getResources()); 1098 } 1099 1100 static { 1101 System.loadLibrary("jni_filtershow_filters"); 1102 } 1103 1104} 1105