2 * Copyright (C) 2012 The Android Open Source Project
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
17 package com.android.gallery3d.filtershow;
19 import android.annotation.TargetApi;
20 import android.app.ActionBar;
21 import android.app.Activity;
22 import android.app.ProgressDialog;
23 import android.content.ContentValues;
24 import android.content.Intent;
25 import android.content.res.Configuration;
26 import android.content.res.Resources;
27 import android.graphics.Bitmap;
28 import android.graphics.BitmapFactory;
29 import android.graphics.Color;
30 import android.graphics.Point;
31 import android.graphics.drawable.Drawable;
32 import android.net.Uri;
33 import android.os.Bundle;
34 import android.util.DisplayMetrics;
35 import android.util.Log;
36 import android.util.TypedValue;
37 import android.view.Display;
38 import android.view.Menu;
39 import android.view.MenuItem;
40 import android.view.View;
41 import android.view.WindowManager;
42 import android.view.View.OnClickListener;
43 import android.widget.AdapterView;
44 import android.widget.AdapterView.OnItemClickListener;
45 import android.widget.ImageButton;
46 import android.widget.LinearLayout;
47 import android.widget.ListView;
48 import android.widget.SeekBar;
49 import android.widget.ShareActionProvider;
50 import android.widget.ShareActionProvider.OnShareTargetSelectedListener;
51 import android.widget.Toast;
53 import com.android.gallery3d.R;
54 import com.android.gallery3d.data.LocalAlbum;
55 import com.android.gallery3d.filtershow.cache.ImageLoader;
56 import com.android.gallery3d.filtershow.filters.ImageFilter;
57 import com.android.gallery3d.filtershow.filters.ImageFilterBorder;
58 import com.android.gallery3d.filtershow.filters.ImageFilterContrast;
59 import com.android.gallery3d.filtershow.filters.ImageFilterExposure;
60 import com.android.gallery3d.filtershow.filters.ImageFilterFx;
61 import com.android.gallery3d.filtershow.filters.ImageFilterHue;
62 import com.android.gallery3d.filtershow.filters.ImageFilterParametricBorder;
63 import com.android.gallery3d.filtershow.filters.ImageFilterRS;
64 import com.android.gallery3d.filtershow.filters.ImageFilterSaturated;
65 import com.android.gallery3d.filtershow.filters.ImageFilterShadows;
66 import com.android.gallery3d.filtershow.filters.ImageFilterTinyPlanet;
67 import com.android.gallery3d.filtershow.filters.ImageFilterVibrance;
68 import com.android.gallery3d.filtershow.filters.ImageFilterVignette;
69 import com.android.gallery3d.filtershow.filters.ImageFilterWBalance;
70 import com.android.gallery3d.filtershow.imageshow.ImageBorder;
71 import com.android.gallery3d.filtershow.imageshow.ImageCrop;
72 import com.android.gallery3d.filtershow.imageshow.ImageFlip;
73 import com.android.gallery3d.filtershow.imageshow.ImageRotate;
74 import com.android.gallery3d.filtershow.imageshow.ImageShow;
75 import com.android.gallery3d.filtershow.imageshow.ImageSmallBorder;
76 import com.android.gallery3d.filtershow.imageshow.ImageSmallFilter;
77 import com.android.gallery3d.filtershow.imageshow.ImageStraighten;
78 import com.android.gallery3d.filtershow.imageshow.ImageWithIcon;
79 import com.android.gallery3d.filtershow.imageshow.ImageZoom;
80 import com.android.gallery3d.filtershow.presets.ImagePreset;
81 import com.android.gallery3d.filtershow.provider.SharedImageProvider;
82 import com.android.gallery3d.filtershow.tools.SaveCopyTask;
83 import com.android.gallery3d.filtershow.ui.ImageButtonTitle;
84 import com.android.gallery3d.filtershow.ui.ImageCurves;
85 import com.android.gallery3d.filtershow.ui.Spline;
86 import com.android.gallery3d.util.GalleryUtils;
89 import java.lang.ref.WeakReference;
90 import java.util.Vector;
93 public class FilterShowActivity extends Activity implements OnItemClickListener,
94 OnShareTargetSelectedListener {
96 public static final String CROP_ACTION = "com.android.camera.action.CROP";
97 public static final String TINY_PLANET_ACTION = "com.android.camera.action.TINY_PLANET";
98 public static final String LAUNCH_FULLSCREEN = "launch-fullscreen";
99 private final PanelController mPanelController = new PanelController();
100 private ImageLoader mImageLoader = null;
101 private ImageShow mImageShow = null;
102 private ImageCurves mImageCurves = null;
103 private ImageBorder mImageBorders = null;
104 private ImageStraighten mImageStraighten = null;
105 private ImageZoom mImageZoom = null;
106 private ImageCrop mImageCrop = null;
107 private ImageRotate mImageRotate = null;
108 private ImageFlip mImageFlip = null;
110 private View mListFx = null;
111 private View mListBorders = null;
112 private View mListGeometry = null;
113 private View mListColors = null;
114 private View mListFilterButtons = null;
116 private ImageButton mFxButton = null;
117 private ImageButton mBorderButton = null;
118 private ImageButton mGeometryButton = null;
119 private ImageButton mColorsButton = null;
121 private ImageSmallFilter mCurrentImageSmallFilter = null;
122 private static final int SELECT_PICTURE = 1;
123 private static final String LOGTAG = "FilterShowActivity";
124 protected static final boolean ANIMATE_PANELS = true;
125 private static int mImageBorderSize = 4; // in percent
127 private boolean mShowingHistoryPanel = false;
128 private boolean mShowingImageStatePanel = false;
130 private final Vector<ImageShow> mImageViews = new Vector<ImageShow>();
131 private final Vector<View> mListViews = new Vector<View>();
132 private final Vector<ImageButton> mBottomPanelButtons = new Vector<ImageButton>();
134 private ShareActionProvider mShareActionProvider;
135 private File mSharedOutputFile = null;
137 private boolean mSharingImage = false;
139 private WeakReference<ProgressDialog> mSavingProgressDialog;
140 private static final int SEEK_BAR_MAX = 600;
143 public void onCreate(Bundle savedInstanceState) {
144 super.onCreate(savedInstanceState);
146 ImageFilterRS.setRenderScriptContext(this);
148 ImageShow.setDefaultBackgroundColor(getResources().getColor(R.color.background_screen));
149 // TODO: get those values from XML.
150 ImageShow.setTextSize((int) getPixelsFromDip(12));
151 ImageShow.setTextPadding((int) getPixelsFromDip(10));
152 ImageShow.setOriginalTextMargin((int) getPixelsFromDip(4));
153 ImageShow.setOriginalTextSize((int) getPixelsFromDip(18));
154 ImageShow.setOriginalText(getResources().getString(R.string.original_picture_text));
155 ImageButtonTitle.setTextSize((int) getPixelsFromDip(12));
156 ImageButtonTitle.setTextPadding((int) getPixelsFromDip(10));
157 ImageSmallFilter.setMargin((int) getPixelsFromDip(3));
158 ImageSmallFilter.setTextMargin((int) getPixelsFromDip(4));
159 Drawable curveHandle = getResources().getDrawable(R.drawable.camera_crop);
160 int curveHandleSize = (int) getResources().getDimension(R.dimen.crop_indicator_size);
161 Spline.setCurveHandle(curveHandle, curveHandleSize);
162 Spline.setCurveWidth((int) getPixelsFromDip(3));
164 setContentView(R.layout.filtershow_activity);
165 ActionBar actionBar = getActionBar();
166 actionBar.setDisplayOptions(ActionBar.DISPLAY_SHOW_CUSTOM);
167 actionBar.setCustomView(R.layout.filtershow_actionbar);
169 actionBar.getCustomView().setOnClickListener(new OnClickListener() {
171 public void onClick(View view) {
176 mImageLoader = new ImageLoader(this, getApplicationContext());
178 LinearLayout listFilters = (LinearLayout) findViewById(R.id.listFilters);
179 LinearLayout listBorders = (LinearLayout) findViewById(R.id.listBorders);
180 LinearLayout listColors = (LinearLayout) findViewById(R.id.listColorsFx);
182 mImageShow = (ImageShow) findViewById(R.id.imageShow);
183 mImageCurves = (ImageCurves) findViewById(R.id.imageCurves);
184 mImageBorders = (ImageBorder) findViewById(R.id.imageBorder);
185 mImageStraighten = (ImageStraighten) findViewById(R.id.imageStraighten);
186 mImageZoom = (ImageZoom) findViewById(R.id.imageZoom);
187 mImageCrop = (ImageCrop) findViewById(R.id.imageCrop);
188 mImageRotate = (ImageRotate) findViewById(R.id.imageRotate);
189 mImageFlip = (ImageFlip) findViewById(R.id.imageFlip);
191 mImageViews.add(mImageShow);
192 mImageViews.add(mImageCurves);
193 mImageViews.add(mImageBorders);
194 mImageViews.add(mImageStraighten);
195 mImageViews.add(mImageZoom);
196 mImageViews.add(mImageCrop);
197 mImageViews.add(mImageRotate);
198 mImageViews.add(mImageFlip);
200 mListFx = findViewById(R.id.fxList);
201 mListBorders = findViewById(R.id.bordersList);
202 mListGeometry = findViewById(R.id.geometryList);
203 mListFilterButtons = findViewById(R.id.filterButtonsList);
204 mListColors = findViewById(R.id.colorsFxList);
205 mListViews.add(mListFx);
206 mListViews.add(mListBorders);
207 mListViews.add(mListGeometry);
208 mListViews.add(mListFilterButtons);
209 mListViews.add(mListColors);
211 mFxButton = (ImageButton) findViewById(R.id.fxButton);
212 mBorderButton = (ImageButton) findViewById(R.id.borderButton);
213 mGeometryButton = (ImageButton) findViewById(R.id.geometryButton);
214 mColorsButton = (ImageButton) findViewById(R.id.colorsButton);
216 mImageShow.setImageLoader(mImageLoader);
217 mImageCurves.setImageLoader(mImageLoader);
218 mImageCurves.setMaster(mImageShow);
219 mImageBorders.setImageLoader(mImageLoader);
220 mImageBorders.setMaster(mImageShow);
221 mImageStraighten.setImageLoader(mImageLoader);
222 mImageStraighten.setMaster(mImageShow);
223 mImageZoom.setImageLoader(mImageLoader);
224 mImageZoom.setMaster(mImageShow);
225 mImageCrop.setImageLoader(mImageLoader);
226 mImageCrop.setMaster(mImageShow);
227 mImageRotate.setImageLoader(mImageLoader);
228 mImageRotate.setMaster(mImageShow);
229 mImageFlip.setImageLoader(mImageLoader);
230 mImageFlip.setMaster(mImageShow);
232 mPanelController.addImageView(findViewById(R.id.imageShow));
233 mPanelController.addImageView(findViewById(R.id.imageCurves));
234 mPanelController.addImageView(findViewById(R.id.imageBorder));
235 mPanelController.addImageView(findViewById(R.id.imageStraighten));
236 mPanelController.addImageView(findViewById(R.id.imageCrop));
237 mPanelController.addImageView(findViewById(R.id.imageRotate));
238 mPanelController.addImageView(findViewById(R.id.imageFlip));
239 mPanelController.addImageView(findViewById(R.id.imageZoom));
241 mPanelController.addPanel(mFxButton, mListFx, 0);
242 mPanelController.addPanel(mBorderButton, mListBorders, 1);
244 mPanelController.addPanel(mGeometryButton, mListGeometry, 2);
245 mPanelController.addComponent(mGeometryButton, findViewById(R.id.straightenButton));
246 mPanelController.addComponent(mGeometryButton, findViewById(R.id.cropButton));
247 mPanelController.addComponent(mGeometryButton, findViewById(R.id.rotateButton));
248 mPanelController.addComponent(mGeometryButton, findViewById(R.id.flipButton));
250 mPanelController.addPanel(mColorsButton, mListColors, 3);
253 R.id.tinyplanetButton,
257 R.id.saturationButton,
261 R.id.shadowRecoveryButton
263 ImageFilter[] filters = {
264 new ImageFilterTinyPlanet(),
265 new ImageFilterVignette(),
266 new ImageFilterVibrance(),
267 new ImageFilterContrast(),
268 new ImageFilterSaturated(),
269 new ImageFilterWBalance(),
270 new ImageFilterHue(),
271 new ImageFilterExposure(),
272 new ImageFilterShadows()
275 for (int i = 0; i < filters.length; i++) {
276 ImageSmallFilter fView = new ImageSmallFilter(this);
277 View v = listColors.findViewById(recastIDs[i]);
278 int pos = listColors.indexOfChild(v);
279 listColors.removeView(v);
281 filters[i].setParameter(filters[i].getPreviewParameter());
282 if (v instanceof ImageButtonTitle)
283 filters[i].setName(((ImageButtonTitle) v).getText());
284 fView.setImageFilter(filters[i]);
285 fView.setController(this);
286 fView.setImageLoader(mImageLoader);
287 fView.setId(recastIDs[i]);
288 mPanelController.addComponent(mColorsButton, fView);
289 listColors.addView(fView, pos);
296 int[] overlayBitmaps = {
297 R.drawable.filtershow_button_colors_sharpen,
298 R.drawable.filtershow_button_colors_curve
300 int[] overlayNames = {
305 for (int i = 0; i < overlayIDs.length; i++) {
306 ImageWithIcon fView = new ImageWithIcon(this);
307 View v = listColors.findViewById(overlayIDs[i]);
308 int pos = listColors.indexOfChild(v);
309 listColors.removeView(v);
310 final int sid = overlayNames[i];
311 ImageFilterExposure efilter = new ImageFilterExposure() {
313 mName = getString(sid);
316 efilter.setParameter(-300);
317 Bitmap bitmap = BitmapFactory.decodeResource(getResources(),
320 fView.setIcon(bitmap);
321 fView.setImageFilter(efilter);
322 fView.setController(this);
323 fView.setImageLoader(mImageLoader);
324 fView.setId(overlayIDs[i]);
325 mPanelController.addComponent(mColorsButton, fView);
326 listColors.addView(fView, pos);
329 mPanelController.addView(findViewById(R.id.applyEffect));
330 mPanelController.addView(findViewById(R.id.pickCurvesChannel));
331 mPanelController.addView(findViewById(R.id.aspect));
332 findViewById(R.id.resetOperationsButton).setOnClickListener(
333 createOnClickResetOperationsButton());
335 ListView operationsList = (ListView) findViewById(R.id.operationsList);
336 operationsList.setAdapter(mImageShow.getHistory());
337 operationsList.setOnItemClickListener(this);
338 ListView imageStateList = (ListView) findViewById(R.id.imageStateList);
339 imageStateList.setAdapter(mImageShow.getImageStateAdapter());
340 mImageLoader.setAdapter(mImageShow.getHistory());
342 fillListImages(listFilters);
343 fillListBorders(listBorders);
345 SeekBar seekBar = (SeekBar) findViewById(R.id.filterSeekBar);
346 seekBar.setMax(SEEK_BAR_MAX);
348 mImageShow.setSeekBar(seekBar);
349 mImageZoom.setSeekBar(seekBar);
350 mPanelController.setRowPanel(findViewById(R.id.secondRowPanel));
351 mPanelController.setUtilityPanel(this, findViewById(R.id.filterButtonsList),
352 findViewById(R.id.applyEffect), findViewById(R.id.aspect),
353 findViewById(R.id.pickCurvesChannel));
354 mPanelController.setMasterImage(mImageShow);
355 mPanelController.setCurrentPanel(mFxButton);
356 Intent intent = getIntent();
357 if (intent.getBooleanExtra(LAUNCH_FULLSCREEN, false)) {
358 getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
361 String data = intent.getDataString();
363 Uri uri = Uri.parse(data);
364 mImageLoader.loadBitmap(uri, getScreenImageSize());
369 View tinyPlanetView = listColors.findViewById(R.id.tinyplanetButton);
371 if (tinyPlanetView != null && !mImageLoader.isLightCycle360()) {
372 tinyPlanetView.setVisibility(View.GONE);
375 String action = intent.getAction();
376 if (action.equalsIgnoreCase(CROP_ACTION)) {
377 mPanelController.showComponent(findViewById(R.id.cropButton));
378 } else if (action.equalsIgnoreCase(TINY_PLANET_ACTION)) {
379 mPanelController.showComponent(findViewById(R.id.tinyplanetButton));
383 private int translateMainPanel(View viewPanel) {
384 int accessoryPanelWidth = viewPanel.getWidth();
385 int mainViewWidth = findViewById(R.id.mainView).getWidth();
386 int mainPanelWidth = mImageShow.getDisplayedImageBounds().width();
387 int leftOver = mainViewWidth - mainPanelWidth - accessoryPanelWidth;
389 return -accessoryPanelWidth;
394 private int getScreenImageSize() {
395 DisplayMetrics metrics = new DisplayMetrics();
396 Display display = getWindowManager().getDefaultDisplay();
397 Point size = new Point();
398 display.getSize(size);
399 display.getMetrics(metrics);
400 int msize = Math.min(size.x, size.y);
401 return (133 * msize) / metrics.densityDpi;
404 private void showSavingProgress(String albumName) {
405 ProgressDialog progress;
406 if (mSavingProgressDialog != null) {
407 progress = mSavingProgressDialog.get();
408 if (progress != null) {
413 // TODO: Allow cancellation of the saving process
415 if (albumName == null) {
416 progressText = getString(R.string.saving_image);
418 progressText = getString(R.string.filtershow_saving_image, albumName);
420 progress = ProgressDialog.show(this, "", progressText, true, false);
421 mSavingProgressDialog = new WeakReference<ProgressDialog>(progress);
424 private void hideSavingProgress() {
425 if (mSavingProgressDialog != null) {
426 ProgressDialog progress = mSavingProgressDialog.get();
427 if (progress != null)
432 public void completeSaveImage(Uri saveUri) {
433 if (mSharingImage && mSharedOutputFile != null) {
434 // Image saved, we unblock the content provider
435 Uri uri = Uri.withAppendedPath(SharedImageProvider.CONTENT_URI,
436 Uri.encode(mSharedOutputFile.getAbsolutePath()));
437 ContentValues values = new ContentValues();
438 values.put(SharedImageProvider.PREPARE, false);
439 getContentResolver().insert(uri, values);
441 setResult(RESULT_OK, new Intent().setData(saveUri));
442 hideSavingProgress();
447 public boolean onShareTargetSelected(ShareActionProvider arg0, Intent arg1) {
448 // First, let's tell the SharedImageProvider that it will need to wait
450 Uri uri = Uri.withAppendedPath(SharedImageProvider.CONTENT_URI,
451 Uri.encode(mSharedOutputFile.getAbsolutePath()));
452 ContentValues values = new ContentValues();
453 values.put(SharedImageProvider.PREPARE, true);
454 getContentResolver().insert(uri, values);
455 mSharingImage = true;
457 // Process and save the image in the background.
458 showSavingProgress(null);
459 mImageShow.saveImage(this, mSharedOutputFile);
463 private Intent getDefaultShareIntent() {
464 Intent intent = new Intent(Intent.ACTION_SEND);
465 intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);
466 intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
467 intent.setType(SharedImageProvider.MIME_TYPE);
468 mSharedOutputFile = SaveCopyTask.getNewFile(this, mImageLoader.getUri());
469 Uri uri = Uri.withAppendedPath(SharedImageProvider.CONTENT_URI,
470 Uri.encode(mSharedOutputFile.getAbsolutePath()));
471 intent.putExtra(Intent.EXTRA_STREAM, uri);
476 public boolean onCreateOptionsMenu(Menu menu) {
477 getMenuInflater().inflate(R.menu.filtershow_activity_menu, menu);
478 MenuItem showHistory = menu.findItem(R.id.operationsButton);
479 if (mShowingHistoryPanel) {
480 showHistory.setTitle(R.string.hide_history_panel);
482 showHistory.setTitle(R.string.show_history_panel);
484 MenuItem showState = menu.findItem(R.id.showImageStateButton);
485 if (mShowingImageStatePanel) {
486 showState.setTitle(R.string.hide_imagestate_panel);
488 showState.setTitle(R.string.show_imagestate_panel);
490 mShareActionProvider = (ShareActionProvider) menu.findItem(R.id.menu_share)
491 .getActionProvider();
492 mShareActionProvider.setShareIntent(getDefaultShareIntent());
493 mShareActionProvider.setOnShareTargetSelectedListener(this);
495 MenuItem undoItem = menu.findItem(R.id.undoButton);
496 MenuItem redoItem = menu.findItem(R.id.redoButton);
497 MenuItem resetItem = menu.findItem(R.id.resetHistoryButton);
498 mImageShow.getHistory().setMenuItems(undoItem, redoItem, resetItem);
503 public void onPause() {
505 if (mShareActionProvider != null) {
506 mShareActionProvider.setOnShareTargetSelectedListener(null);
511 public void onResume() {
513 if (mShareActionProvider != null) {
514 mShareActionProvider.setOnShareTargetSelectedListener(this);
519 public boolean onOptionsItemSelected(MenuItem item) {
520 switch (item.getItemId()) {
521 case R.id.undoButton: {
522 HistoryAdapter adapter = mImageShow.getHistory();
523 int position = adapter.undo();
524 mImageShow.onItemClick(position);
525 mImageShow.showToast("Undo");
529 case R.id.redoButton: {
530 HistoryAdapter adapter = mImageShow.getHistory();
531 int position = adapter.redo();
532 mImageShow.onItemClick(position);
533 mImageShow.showToast("Redo");
537 case R.id.resetHistoryButton: {
541 case R.id.showImageStateButton: {
542 toggleImageStatePanel();
545 case R.id.operationsButton: {
546 toggleHistoryPanel();
549 case android.R.id.home: {
557 private void fillListImages(LinearLayout listFilters) {
558 // TODO: use listview
559 // TODO: load the filters straight from the filesystem
561 ImageFilterFx[] fxArray = new ImageFilterFx[18];
565 R.drawable.filtershow_fx_0005_punch,
566 R.drawable.filtershow_fx_0000_vintage,
567 R.drawable.filtershow_fx_0004_bw_contrast,
568 R.drawable.filtershow_fx_0002_bleach,
569 R.drawable.filtershow_fx_0001_instant,
570 R.drawable.filtershow_fx_0007_washout,
571 R.drawable.filtershow_fx_0003_blue_crush,
572 R.drawable.filtershow_fx_0008_washout_color,
573 R.drawable.filtershow_fx_0006_x_process
578 R.string.ffx_vintage,
579 R.string.ffx_bw_contrast,
581 R.string.ffx_instant,
582 R.string.ffx_washout,
583 R.string.ffx_blue_crush,
584 R.string.ffx_washout_color,
585 R.string.ffx_x_process
588 ImagePreset preset = new ImagePreset(getString(R.string.history_original)); // empty
589 preset.setImageLoader(mImageLoader);
590 ImageSmallFilter filter = new ImageSmallFilter(this);
592 filter.setSelected(true);
593 mCurrentImageSmallFilter = filter;
595 filter.setImageFilter(new ImageFilterFx(null, getString(R.string.none)));
597 filter.setController(this);
598 filter.setImageLoader(mImageLoader);
599 listFilters.addView(filter);
600 ImageSmallFilter previousFilter = filter;
602 BitmapFactory.Options o = new BitmapFactory.Options();
605 for (int i = 0; i < drawid.length; i++) {
606 Bitmap b = BitmapFactory.decodeResource(getResources(), drawid[i], o);
607 fxArray[p++] = new ImageFilterFx(b, getString(fxNameid[i]));
610 for (int i = 0; i < p; i++) {
611 filter = new ImageSmallFilter(this);
612 filter.setImageFilter(fxArray[i]);
613 filter.setController(this);
614 filter.setImageLoader(mImageLoader);
615 listFilters.addView(filter);
616 previousFilter = filter;
619 // Default preset (original)
620 mImageShow.setImagePreset(preset);
623 private void fillListBorders(LinearLayout listBorders) {
624 // TODO: use listview
625 // TODO: load the borders straight from the filesystem
627 ImageFilter[] borders = new ImageFilter[7];
628 borders[p++] = new ImageFilterBorder(null);
630 Drawable npd1 = getResources().getDrawable(R.drawable.filtershow_border_4x5);
631 borders[p++] = new ImageFilterBorder(npd1);
632 Drawable npd2 = getResources().getDrawable(R.drawable.filtershow_border_brush);
633 borders[p++] = new ImageFilterBorder(npd2);
634 borders[p++] = new ImageFilterParametricBorder(Color.BLACK, mImageBorderSize, 0);
635 borders[p++] = new ImageFilterParametricBorder(Color.BLACK, mImageBorderSize,
637 borders[p++] = new ImageFilterParametricBorder(Color.WHITE, mImageBorderSize, 0);
638 borders[p++] = new ImageFilterParametricBorder(Color.WHITE, mImageBorderSize,
641 ImageSmallFilter previousFilter = null;
642 for (int i = 0; i < p; i++) {
643 ImageSmallBorder filter = new ImageSmallBorder(this);
644 borders[i].setName(getString(R.string.borders));
645 filter.setImageFilter(borders[i]);
646 filter.setController(this);
647 filter.setBorder(true);
648 filter.setImageLoader(mImageLoader);
649 filter.setShowTitle(false);
650 listBorders.addView(filter);
651 previousFilter = filter;
655 // //////////////////////////////////////////////////////////////////////////////
656 // Some utility functions
657 // TODO: finish the cleanup.
659 public void showOriginalViews(boolean value) {
660 for (ImageShow views : mImageViews) {
661 views.showOriginal(value);
665 public void invalidateViews() {
666 for (ImageShow views : mImageViews) {
672 public void hideListViews() {
673 for (View view : mListViews) {
674 view.setVisibility(View.GONE);
678 public void hideImageViews() {
679 mImageShow.setShowControls(false); // reset
680 for (View view : mImageViews) {
681 view.setVisibility(View.GONE);
685 public void unselectBottomPanelButtons() {
686 for (ImageButton button : mBottomPanelButtons) {
687 button.setSelected(false);
691 public void unselectPanelButtons(Vector<ImageButton> buttons) {
692 for (ImageButton button : buttons) {
693 button.setSelected(false);
697 // //////////////////////////////////////////////////////////////////////////////
698 // imageState panel...
700 public boolean isShowingHistoryPanel() {
701 return mShowingHistoryPanel;
704 private void toggleImageStatePanel() {
705 final View view = findViewById(R.id.mainPanel);
706 final View viewList = findViewById(R.id.imageStatePanel);
708 if (mShowingHistoryPanel) {
709 findViewById(R.id.historyPanel).setVisibility(View.INVISIBLE);
710 mShowingHistoryPanel = false;
713 int translate = translateMainPanel(viewList);
714 if (!mShowingImageStatePanel) {
715 mShowingImageStatePanel = true;
716 view.animate().setDuration(200).x(translate)
717 .withLayer().withEndAction(new Runnable() {
720 viewList.setAlpha(0);
721 viewList.setVisibility(View.VISIBLE);
722 viewList.animate().setDuration(100)
723 .alpha(1.0f).start();
727 mShowingImageStatePanel = false;
728 viewList.setVisibility(View.INVISIBLE);
729 view.animate().setDuration(200).x(0).withLayer()
732 invalidateOptionsMenu();
736 public void onConfigurationChanged(Configuration newConfig)
738 super.onConfigurationChanged(newConfig);
739 if (mShowingHistoryPanel) {
740 toggleHistoryPanel();
744 // //////////////////////////////////////////////////////////////////////////////
747 public void toggleHistoryPanel() {
748 final View view = findViewById(R.id.mainPanel);
749 final View viewList = findViewById(R.id.historyPanel);
751 if (mShowingImageStatePanel) {
752 findViewById(R.id.imageStatePanel).setVisibility(View.INVISIBLE);
753 mShowingImageStatePanel = false;
756 int translate = translateMainPanel(viewList);
757 if (!mShowingHistoryPanel) {
758 mShowingHistoryPanel = true;
759 view.animate().setDuration(200).x(translate)
760 .withLayer().withEndAction(new Runnable() {
763 viewList.setAlpha(0);
764 viewList.setVisibility(View.VISIBLE);
765 viewList.animate().setDuration(100)
766 .alpha(1.0f).start();
770 mShowingHistoryPanel = false;
771 viewList.setVisibility(View.INVISIBLE);
772 view.animate().setDuration(200).x(0).withLayer()
775 invalidateOptionsMenu();
778 private void resetHistory() {
779 HistoryAdapter adapter = mImageShow.getHistory();
781 ImagePreset original = new ImagePreset(adapter.getItem(0));
782 mImageShow.setImagePreset(original);
783 mPanelController.resetParameters();
787 // reset button in the history panel.
788 private OnClickListener createOnClickResetOperationsButton() {
789 return new View.OnClickListener() {
791 public void onClick(View v) {
798 public void onBackPressed() {
799 if (mPanelController.onBackPressed()) {
804 public void cannotLoadImage() {
805 CharSequence text = getString(R.string.cannot_load_image);
806 Toast toast = Toast.makeText(this, text, Toast.LENGTH_SHORT);
811 // //////////////////////////////////////////////////////////////////////////////
813 public float getPixelsFromDip(float value) {
814 Resources r = getResources();
815 return TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, value,
816 r.getDisplayMetrics());
819 public void useImagePreset(ImageSmallFilter imageSmallFilter, ImagePreset preset) {
820 if (preset == null) {
824 if (mCurrentImageSmallFilter != null) {
825 mCurrentImageSmallFilter.setSelected(false);
827 mCurrentImageSmallFilter = imageSmallFilter;
828 mCurrentImageSmallFilter.setSelected(true);
830 ImagePreset copy = new ImagePreset(preset);
831 mImageShow.setImagePreset(copy);
833 // if it's an FX we rest the curve adjustment too
834 mImageCurves.resetCurve();
839 public void useImageFilter(ImageSmallFilter imageSmallFilter, ImageFilter imageFilter,
841 if (imageFilter == null) {
845 if (mCurrentImageSmallFilter != null) {
846 mCurrentImageSmallFilter.setSelected(false);
848 mCurrentImageSmallFilter = imageSmallFilter;
849 mCurrentImageSmallFilter.setSelected(true);
851 ImagePreset oldPreset = mImageShow.getImagePreset();
852 ImagePreset copy = new ImagePreset(oldPreset);
853 // TODO: use a numerical constant instead.
855 copy.add(imageFilter);
857 mImageShow.setImagePreset(copy);
862 public void onItemClick(AdapterView<?> parent, View view, int position,
864 mImageShow.onItemClick(position);
868 public void pickImage() {
869 Intent intent = new Intent();
870 intent.setType("image/*");
871 intent.setAction(Intent.ACTION_GET_CONTENT);
872 startActivityForResult(Intent.createChooser(intent, getString(R.string.select_image)),
877 public void onActivityResult(int requestCode, int resultCode, Intent data) {
878 Log.v(LOGTAG, "onActivityResult");
879 if (resultCode == RESULT_OK) {
880 if (requestCode == SELECT_PICTURE) {
881 Uri selectedImageUri = data.getData();
882 mImageLoader.loadBitmap(selectedImageUri, getScreenImageSize());
887 public void saveImage() {
888 if (mImageShow.hasModifications()) {
889 // Get the name of the album, to which the image will be saved
890 File saveDir = SaveCopyTask.getFinalSaveDirectory(this, mImageLoader.getUri());
891 int bucketId = GalleryUtils.getBucketId(saveDir.getPath());
892 String albumName = LocalAlbum.getLocalizedName(getResources(), bucketId, null);
893 showSavingProgress(albumName);
894 mImageShow.saveImage(this, null);
901 System.loadLibrary("jni_filtershow_filters");