FilterShowActivity.java revision 67fefdb9b77644c955e1c0c5b1fcd51e2374f212
1/* 2 * Copyright (C) 2012 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 17package com.android.gallery3d.filtershow; 18 19import android.annotation.TargetApi; 20import android.app.ActionBar; 21import android.app.Activity; 22import android.app.ProgressDialog; 23import android.content.ContentValues; 24import android.content.Intent; 25import android.content.res.Configuration; 26import android.content.res.Resources; 27import android.graphics.Bitmap; 28import android.graphics.BitmapFactory; 29import android.graphics.Color; 30import android.graphics.Point; 31import android.graphics.drawable.Drawable; 32import android.net.Uri; 33import android.os.Bundle; 34import android.util.DisplayMetrics; 35import android.util.Log; 36import android.util.TypedValue; 37import android.view.Display; 38import android.view.Menu; 39import android.view.MenuItem; 40import android.view.View; 41import android.view.WindowManager; 42import android.view.View.OnClickListener; 43import android.widget.AdapterView; 44import android.widget.AdapterView.OnItemClickListener; 45import android.widget.ImageButton; 46import android.widget.LinearLayout; 47import android.widget.ListView; 48import android.widget.SeekBar; 49import android.widget.ShareActionProvider; 50import android.widget.ShareActionProvider.OnShareTargetSelectedListener; 51import android.widget.Toast; 52 53import com.android.gallery3d.R; 54import com.android.gallery3d.data.LocalAlbum; 55import com.android.gallery3d.filtershow.cache.ImageLoader; 56import com.android.gallery3d.filtershow.filters.ImageFilter; 57import com.android.gallery3d.filtershow.filters.ImageFilterBorder; 58import com.android.gallery3d.filtershow.filters.ImageFilterBwFilter; 59import com.android.gallery3d.filtershow.filters.ImageFilterContrast; 60import com.android.gallery3d.filtershow.filters.ImageFilterExposure; 61import com.android.gallery3d.filtershow.filters.ImageFilterFx; 62import com.android.gallery3d.filtershow.filters.ImageFilterHue; 63import com.android.gallery3d.filtershow.filters.ImageFilterParametricBorder; 64import com.android.gallery3d.filtershow.filters.ImageFilterRS; 65import com.android.gallery3d.filtershow.filters.ImageFilterSaturated; 66import com.android.gallery3d.filtershow.filters.ImageFilterShadows; 67import com.android.gallery3d.filtershow.filters.ImageFilterTinyPlanet; 68import com.android.gallery3d.filtershow.filters.ImageFilterVibrance; 69import com.android.gallery3d.filtershow.filters.ImageFilterVignette; 70import com.android.gallery3d.filtershow.filters.ImageFilterWBalance; 71import com.android.gallery3d.filtershow.imageshow.ImageBorder; 72import com.android.gallery3d.filtershow.imageshow.ImageCrop; 73import com.android.gallery3d.filtershow.imageshow.ImageFlip; 74import com.android.gallery3d.filtershow.imageshow.ImageRotate; 75import com.android.gallery3d.filtershow.imageshow.ImageShow; 76import com.android.gallery3d.filtershow.imageshow.ImageSmallBorder; 77import com.android.gallery3d.filtershow.imageshow.ImageSmallFilter; 78import com.android.gallery3d.filtershow.imageshow.ImageStraighten; 79import com.android.gallery3d.filtershow.imageshow.ImageWithIcon; 80import com.android.gallery3d.filtershow.imageshow.ImageZoom; 81import com.android.gallery3d.filtershow.presets.ImagePreset; 82import com.android.gallery3d.filtershow.provider.SharedImageProvider; 83import com.android.gallery3d.filtershow.tools.SaveCopyTask; 84import com.android.gallery3d.filtershow.ui.ImageButtonTitle; 85import com.android.gallery3d.filtershow.ui.ImageCurves; 86import com.android.gallery3d.filtershow.ui.Spline; 87import com.android.gallery3d.util.GalleryUtils; 88 89import java.io.File; 90import java.lang.ref.WeakReference; 91import java.util.Vector; 92 93@TargetApi(16) 94public class FilterShowActivity extends Activity implements OnItemClickListener, 95 OnShareTargetSelectedListener { 96 97 public static final String CROP_ACTION = "com.android.camera.action.CROP"; 98 public static final String TINY_PLANET_ACTION = "com.android.camera.action.TINY_PLANET"; 99 public static final String LAUNCH_FULLSCREEN = "launch-fullscreen"; 100 private final PanelController mPanelController = new PanelController(); 101 private ImageLoader mImageLoader = null; 102 private ImageShow mImageShow = null; 103 private ImageCurves mImageCurves = null; 104 private ImageBorder mImageBorders = null; 105 private ImageStraighten mImageStraighten = null; 106 private ImageZoom mImageZoom = null; 107 private ImageCrop mImageCrop = null; 108 private ImageRotate mImageRotate = null; 109 private ImageFlip mImageFlip = null; 110 111 private View mListFx = null; 112 private View mListBorders = null; 113 private View mListGeometry = null; 114 private View mListColors = null; 115 private View mListFilterButtons = null; 116 117 private ImageButton mFxButton = null; 118 private ImageButton mBorderButton = null; 119 private ImageButton mGeometryButton = null; 120 private ImageButton mColorsButton = null; 121 122 private ImageSmallFilter mCurrentImageSmallFilter = null; 123 private static final int SELECT_PICTURE = 1; 124 private static final String LOGTAG = "FilterShowActivity"; 125 protected static final boolean ANIMATE_PANELS = true; 126 private static int mImageBorderSize = 4; // in percent 127 128 private boolean mShowingHistoryPanel = false; 129 private boolean mShowingImageStatePanel = false; 130 131 private final Vector<ImageShow> mImageViews = new Vector<ImageShow>(); 132 private final Vector<View> mListViews = new Vector<View>(); 133 private final Vector<ImageButton> mBottomPanelButtons = new Vector<ImageButton>(); 134 135 private ShareActionProvider mShareActionProvider; 136 private File mSharedOutputFile = null; 137 138 private boolean mSharingImage = false; 139 140 private WeakReference<ProgressDialog> mSavingProgressDialog; 141 private static final int SEEK_BAR_MAX = 600; 142 143 @Override 144 public void onCreate(Bundle savedInstanceState) { 145 super.onCreate(savedInstanceState); 146 147 ImageFilterRS.setRenderScriptContext(this); 148 149 ImageShow.setDefaultBackgroundColor(getResources().getColor(R.color.background_screen)); 150 // TODO: get those values from XML. 151 ImageShow.setTextSize((int) getPixelsFromDip(12)); 152 ImageShow.setTextPadding((int) getPixelsFromDip(10)); 153 ImageShow.setOriginalTextMargin((int) getPixelsFromDip(4)); 154 ImageShow.setOriginalTextSize((int) getPixelsFromDip(18)); 155 ImageShow.setOriginalText(getResources().getString(R.string.original_picture_text)); 156 ImageButtonTitle.setTextSize((int) getPixelsFromDip(12)); 157 ImageButtonTitle.setTextPadding((int) getPixelsFromDip(10)); 158 ImageSmallFilter.setMargin((int) getPixelsFromDip(3)); 159 ImageSmallFilter.setTextMargin((int) getPixelsFromDip(4)); 160 Drawable curveHandle = getResources().getDrawable(R.drawable.camera_crop); 161 int curveHandleSize = (int) getResources().getDimension(R.dimen.crop_indicator_size); 162 Spline.setCurveHandle(curveHandle, curveHandleSize); 163 Spline.setCurveWidth((int) getPixelsFromDip(3)); 164 165 setContentView(R.layout.filtershow_activity); 166 ActionBar actionBar = getActionBar(); 167 actionBar.setDisplayOptions(ActionBar.DISPLAY_SHOW_CUSTOM); 168 actionBar.setCustomView(R.layout.filtershow_actionbar); 169 170 actionBar.getCustomView().setOnClickListener(new OnClickListener() { 171 @Override 172 public void onClick(View view) { 173 saveImage(); 174 } 175 }); 176 177 mImageLoader = new ImageLoader(this, getApplicationContext()); 178 179 LinearLayout listFilters = (LinearLayout) findViewById(R.id.listFilters); 180 LinearLayout listBorders = (LinearLayout) findViewById(R.id.listBorders); 181 LinearLayout listColors = (LinearLayout) findViewById(R.id.listColorsFx); 182 183 mImageShow = (ImageShow) findViewById(R.id.imageShow); 184 mImageCurves = (ImageCurves) findViewById(R.id.imageCurves); 185 mImageBorders = (ImageBorder) findViewById(R.id.imageBorder); 186 mImageStraighten = (ImageStraighten) findViewById(R.id.imageStraighten); 187 mImageZoom = (ImageZoom) findViewById(R.id.imageZoom); 188 mImageCrop = (ImageCrop) findViewById(R.id.imageCrop); 189 mImageRotate = (ImageRotate) findViewById(R.id.imageRotate); 190 mImageFlip = (ImageFlip) findViewById(R.id.imageFlip); 191 192 mImageViews.add(mImageShow); 193 mImageViews.add(mImageCurves); 194 mImageViews.add(mImageBorders); 195 mImageViews.add(mImageStraighten); 196 mImageViews.add(mImageZoom); 197 mImageViews.add(mImageCrop); 198 mImageViews.add(mImageRotate); 199 mImageViews.add(mImageFlip); 200 201 mListFx = findViewById(R.id.fxList); 202 mListBorders = findViewById(R.id.bordersList); 203 mListGeometry = findViewById(R.id.geometryList); 204 mListFilterButtons = findViewById(R.id.filterButtonsList); 205 mListColors = findViewById(R.id.colorsFxList); 206 mListViews.add(mListFx); 207 mListViews.add(mListBorders); 208 mListViews.add(mListGeometry); 209 mListViews.add(mListFilterButtons); 210 mListViews.add(mListColors); 211 212 mFxButton = (ImageButton) findViewById(R.id.fxButton); 213 mBorderButton = (ImageButton) findViewById(R.id.borderButton); 214 mGeometryButton = (ImageButton) findViewById(R.id.geometryButton); 215 mColorsButton = (ImageButton) findViewById(R.id.colorsButton); 216 217 mImageShow.setImageLoader(mImageLoader); 218 mImageCurves.setImageLoader(mImageLoader); 219 mImageCurves.setMaster(mImageShow); 220 mImageBorders.setImageLoader(mImageLoader); 221 mImageBorders.setMaster(mImageShow); 222 mImageStraighten.setImageLoader(mImageLoader); 223 mImageStraighten.setMaster(mImageShow); 224 mImageZoom.setImageLoader(mImageLoader); 225 mImageZoom.setMaster(mImageShow); 226 mImageCrop.setImageLoader(mImageLoader); 227 mImageCrop.setMaster(mImageShow); 228 mImageRotate.setImageLoader(mImageLoader); 229 mImageRotate.setMaster(mImageShow); 230 mImageFlip.setImageLoader(mImageLoader); 231 mImageFlip.setMaster(mImageShow); 232 233 mPanelController.addImageView(findViewById(R.id.imageShow)); 234 mPanelController.addImageView(findViewById(R.id.imageCurves)); 235 mPanelController.addImageView(findViewById(R.id.imageBorder)); 236 mPanelController.addImageView(findViewById(R.id.imageStraighten)); 237 mPanelController.addImageView(findViewById(R.id.imageCrop)); 238 mPanelController.addImageView(findViewById(R.id.imageRotate)); 239 mPanelController.addImageView(findViewById(R.id.imageFlip)); 240 mPanelController.addImageView(findViewById(R.id.imageZoom)); 241 242 mPanelController.addPanel(mFxButton, mListFx, 0); 243 mPanelController.addPanel(mBorderButton, mListBorders, 1); 244 245 mPanelController.addPanel(mGeometryButton, mListGeometry, 2); 246 mPanelController.addComponent(mGeometryButton, findViewById(R.id.straightenButton)); 247 mPanelController.addComponent(mGeometryButton, findViewById(R.id.cropButton)); 248 mPanelController.addComponent(mGeometryButton, findViewById(R.id.rotateButton)); 249 mPanelController.addComponent(mGeometryButton, findViewById(R.id.flipButton)); 250 251 mPanelController.addPanel(mColorsButton, mListColors, 3); 252 253 int[] recastIDs = { 254 R.id.tinyplanetButton, 255 R.id.vignetteButton, 256 R.id.vibranceButton, 257 R.id.contrastButton, 258 R.id.saturationButton, 259 R.id.bwfilterButton, 260 R.id.wbalanceButton, 261 R.id.hueButton, 262 R.id.exposureButton, 263 R.id.shadowRecoveryButton 264 }; 265 ImageFilter[] filters = { 266 new ImageFilterTinyPlanet(), 267 new ImageFilterVignette(), 268 new ImageFilterVibrance(), 269 new ImageFilterContrast(), 270 new ImageFilterSaturated(), 271 new ImageFilterBwFilter(), 272 new ImageFilterWBalance(), 273 new ImageFilterHue(), 274 new ImageFilterExposure(), 275 new ImageFilterShadows() 276 }; 277 278 for (int i = 0; i < filters.length; i++) { 279 ImageSmallFilter fView = new ImageSmallFilter(this); 280 View v = listColors.findViewById(recastIDs[i]); 281 int pos = listColors.indexOfChild(v); 282 listColors.removeView(v); 283 284 filters[i].setParameter(filters[i].getPreviewParameter()); 285 if (v instanceof ImageButtonTitle) 286 filters[i].setName(((ImageButtonTitle) v).getText()); 287 fView.setImageFilter(filters[i]); 288 fView.setController(this); 289 fView.setImageLoader(mImageLoader); 290 fView.setId(recastIDs[i]); 291 mPanelController.addComponent(mColorsButton, fView); 292 listColors.addView(fView, pos); 293 } 294 295 int[] overlayIDs = { 296 R.id.sharpenButton, 297 R.id.curvesButtonRGB 298 }; 299 int[] overlayBitmaps = { 300 R.drawable.filtershow_button_colors_sharpen, 301 R.drawable.filtershow_button_colors_curve 302 }; 303 int[] overlayNames = { 304 R.string.sharpness, 305 R.string.curvesRGB 306 }; 307 308 for (int i = 0; i < overlayIDs.length; i++) { 309 ImageWithIcon fView = new ImageWithIcon(this); 310 View v = listColors.findViewById(overlayIDs[i]); 311 int pos = listColors.indexOfChild(v); 312 listColors.removeView(v); 313 final int sid = overlayNames[i]; 314 ImageFilterExposure efilter = new ImageFilterExposure() { 315 { 316 mName = getString(sid); 317 } 318 }; 319 efilter.setParameter(-300); 320 Bitmap bitmap = BitmapFactory.decodeResource(getResources(), 321 overlayBitmaps[i]); 322 323 fView.setIcon(bitmap); 324 fView.setImageFilter(efilter); 325 fView.setController(this); 326 fView.setImageLoader(mImageLoader); 327 fView.setId(overlayIDs[i]); 328 mPanelController.addComponent(mColorsButton, fView); 329 listColors.addView(fView, pos); 330 } 331 332 mPanelController.addView(findViewById(R.id.applyEffect)); 333 mPanelController.addView(findViewById(R.id.pickCurvesChannel)); 334 mPanelController.addView(findViewById(R.id.aspect)); 335 findViewById(R.id.resetOperationsButton).setOnClickListener( 336 createOnClickResetOperationsButton()); 337 338 ListView operationsList = (ListView) findViewById(R.id.operationsList); 339 operationsList.setAdapter(mImageShow.getHistory()); 340 operationsList.setOnItemClickListener(this); 341 ListView imageStateList = (ListView) findViewById(R.id.imageStateList); 342 imageStateList.setAdapter(mImageShow.getImageStateAdapter()); 343 mImageLoader.setAdapter(mImageShow.getHistory()); 344 345 fillListImages(listFilters); 346 fillListBorders(listBorders); 347 348 SeekBar seekBar = (SeekBar) findViewById(R.id.filterSeekBar); 349 seekBar.setMax(SEEK_BAR_MAX); 350 351 mImageShow.setSeekBar(seekBar); 352 mImageZoom.setSeekBar(seekBar); 353 mPanelController.setRowPanel(findViewById(R.id.secondRowPanel)); 354 mPanelController.setUtilityPanel(this, findViewById(R.id.filterButtonsList), 355 findViewById(R.id.applyEffect), findViewById(R.id.aspect), 356 findViewById(R.id.pickCurvesChannel)); 357 mPanelController.setMasterImage(mImageShow); 358 mPanelController.setCurrentPanel(mFxButton); 359 Intent intent = getIntent(); 360 if (intent.getBooleanExtra(LAUNCH_FULLSCREEN, false)) { 361 getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN); 362 } 363 364 String data = intent.getDataString(); 365 if (data != null) { 366 Uri uri = Uri.parse(data); 367 mImageLoader.loadBitmap(uri, getScreenImageSize()); 368 } else { 369 pickImage(); 370 } 371 372 View tinyPlanetView = listColors.findViewById(R.id.tinyplanetButton); 373 374 if (tinyPlanetView != null && !mImageLoader.isLightCycle360()) { 375 tinyPlanetView.setVisibility(View.GONE); 376 } 377 378 String action = intent.getAction(); 379 if (action.equalsIgnoreCase(CROP_ACTION)) { 380 mPanelController.showComponent(findViewById(R.id.cropButton)); 381 } else if (action.equalsIgnoreCase(TINY_PLANET_ACTION)) { 382 mPanelController.showComponent(findViewById(R.id.tinyplanetButton)); 383 } 384 } 385 386 private int translateMainPanel(View viewPanel) { 387 int accessoryPanelWidth = viewPanel.getWidth(); 388 int mainViewWidth = findViewById(R.id.mainView).getWidth(); 389 int mainPanelWidth = mImageShow.getDisplayedImageBounds().width(); 390 int leftOver = mainViewWidth - mainPanelWidth - accessoryPanelWidth; 391 if (leftOver < 0) { 392 return -accessoryPanelWidth; 393 } 394 return 0; 395 } 396 397 private int getScreenImageSize() { 398 DisplayMetrics metrics = new DisplayMetrics(); 399 Display display = getWindowManager().getDefaultDisplay(); 400 Point size = new Point(); 401 display.getSize(size); 402 display.getMetrics(metrics); 403 int msize = Math.min(size.x, size.y); 404 return (133 * msize) / metrics.densityDpi; 405 } 406 407 private void showSavingProgress(String albumName) { 408 ProgressDialog progress; 409 if (mSavingProgressDialog != null) { 410 progress = mSavingProgressDialog.get(); 411 if (progress != null) { 412 progress.show(); 413 return; 414 } 415 } 416 // TODO: Allow cancellation of the saving process 417 String progressText; 418 if (albumName == null) { 419 progressText = getString(R.string.saving_image); 420 } else { 421 progressText = getString(R.string.filtershow_saving_image, albumName); 422 } 423 progress = ProgressDialog.show(this, "", progressText, true, false); 424 mSavingProgressDialog = new WeakReference<ProgressDialog>(progress); 425 } 426 427 private void hideSavingProgress() { 428 if (mSavingProgressDialog != null) { 429 ProgressDialog progress = mSavingProgressDialog.get(); 430 if (progress != null) 431 progress.dismiss(); 432 } 433 } 434 435 public void completeSaveImage(Uri saveUri) { 436 if (mSharingImage && mSharedOutputFile != null) { 437 // Image saved, we unblock the content provider 438 Uri uri = Uri.withAppendedPath(SharedImageProvider.CONTENT_URI, 439 Uri.encode(mSharedOutputFile.getAbsolutePath())); 440 ContentValues values = new ContentValues(); 441 values.put(SharedImageProvider.PREPARE, false); 442 getContentResolver().insert(uri, values); 443 } 444 setResult(RESULT_OK, new Intent().setData(saveUri)); 445 hideSavingProgress(); 446 finish(); 447 } 448 449 @Override 450 public boolean onShareTargetSelected(ShareActionProvider arg0, Intent arg1) { 451 // First, let's tell the SharedImageProvider that it will need to wait 452 // for the image 453 Uri uri = Uri.withAppendedPath(SharedImageProvider.CONTENT_URI, 454 Uri.encode(mSharedOutputFile.getAbsolutePath())); 455 ContentValues values = new ContentValues(); 456 values.put(SharedImageProvider.PREPARE, true); 457 getContentResolver().insert(uri, values); 458 mSharingImage = true; 459 460 // Process and save the image in the background. 461 showSavingProgress(null); 462 mImageShow.saveImage(this, mSharedOutputFile); 463 return true; 464 } 465 466 private Intent getDefaultShareIntent() { 467 Intent intent = new Intent(Intent.ACTION_SEND); 468 intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET); 469 intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); 470 intent.setType(SharedImageProvider.MIME_TYPE); 471 mSharedOutputFile = SaveCopyTask.getNewFile(this, mImageLoader.getUri()); 472 Uri uri = Uri.withAppendedPath(SharedImageProvider.CONTENT_URI, 473 Uri.encode(mSharedOutputFile.getAbsolutePath())); 474 intent.putExtra(Intent.EXTRA_STREAM, uri); 475 return intent; 476 } 477 478 @Override 479 public boolean onCreateOptionsMenu(Menu menu) { 480 getMenuInflater().inflate(R.menu.filtershow_activity_menu, menu); 481 MenuItem showHistory = menu.findItem(R.id.operationsButton); 482 if (mShowingHistoryPanel) { 483 showHistory.setTitle(R.string.hide_history_panel); 484 } else { 485 showHistory.setTitle(R.string.show_history_panel); 486 } 487 MenuItem showState = menu.findItem(R.id.showImageStateButton); 488 if (mShowingImageStatePanel) { 489 showState.setTitle(R.string.hide_imagestate_panel); 490 } else { 491 showState.setTitle(R.string.show_imagestate_panel); 492 } 493 mShareActionProvider = (ShareActionProvider) menu.findItem(R.id.menu_share) 494 .getActionProvider(); 495 mShareActionProvider.setShareIntent(getDefaultShareIntent()); 496 mShareActionProvider.setOnShareTargetSelectedListener(this); 497 498 MenuItem undoItem = menu.findItem(R.id.undoButton); 499 MenuItem redoItem = menu.findItem(R.id.redoButton); 500 MenuItem resetItem = menu.findItem(R.id.resetHistoryButton); 501 mImageShow.getHistory().setMenuItems(undoItem, redoItem, resetItem); 502 return true; 503 } 504 505 @Override 506 public void onPause() { 507 super.onPause(); 508 if (mShareActionProvider != null) { 509 mShareActionProvider.setOnShareTargetSelectedListener(null); 510 } 511 } 512 513 @Override 514 public void onResume() { 515 super.onResume(); 516 if (mShareActionProvider != null) { 517 mShareActionProvider.setOnShareTargetSelectedListener(this); 518 } 519 } 520 521 @Override 522 public boolean onOptionsItemSelected(MenuItem item) { 523 switch (item.getItemId()) { 524 case R.id.undoButton: { 525 HistoryAdapter adapter = mImageShow.getHistory(); 526 int position = adapter.undo(); 527 mImageShow.onItemClick(position); 528 mImageShow.showToast("Undo"); 529 invalidateViews(); 530 return true; 531 } 532 case R.id.redoButton: { 533 HistoryAdapter adapter = mImageShow.getHistory(); 534 int position = adapter.redo(); 535 mImageShow.onItemClick(position); 536 mImageShow.showToast("Redo"); 537 invalidateViews(); 538 return true; 539 } 540 case R.id.resetHistoryButton: { 541 resetHistory(); 542 return true; 543 } 544 case R.id.showImageStateButton: { 545 toggleImageStatePanel(); 546 return true; 547 } 548 case R.id.operationsButton: { 549 toggleHistoryPanel(); 550 return true; 551 } 552 case android.R.id.home: { 553 saveImage(); 554 return true; 555 } 556 } 557 return false; 558 } 559 560 private void fillListImages(LinearLayout listFilters) { 561 // TODO: use listview 562 // TODO: load the filters straight from the filesystem 563 564 ImageFilterFx[] fxArray = new ImageFilterFx[18]; 565 int p = 0; 566 567 int[] drawid = { 568 R.drawable.filtershow_fx_0005_punch, 569 R.drawable.filtershow_fx_0000_vintage, 570 R.drawable.filtershow_fx_0004_bw_contrast, 571 R.drawable.filtershow_fx_0002_bleach, 572 R.drawable.filtershow_fx_0001_instant, 573 R.drawable.filtershow_fx_0007_washout, 574 R.drawable.filtershow_fx_0003_blue_crush, 575 R.drawable.filtershow_fx_0008_washout_color, 576 R.drawable.filtershow_fx_0006_x_process 577 }; 578 579 int[] fxNameid = { 580 R.string.ffx_punch, 581 R.string.ffx_vintage, 582 R.string.ffx_bw_contrast, 583 R.string.ffx_bleach, 584 R.string.ffx_instant, 585 R.string.ffx_washout, 586 R.string.ffx_blue_crush, 587 R.string.ffx_washout_color, 588 R.string.ffx_x_process 589 }; 590 591 ImagePreset preset = new ImagePreset(getString(R.string.history_original)); // empty 592 preset.setImageLoader(mImageLoader); 593 ImageSmallFilter filter = new ImageSmallFilter(this); 594 595 filter.setSelected(true); 596 mCurrentImageSmallFilter = filter; 597 598 filter.setImageFilter(new ImageFilterFx(null, getString(R.string.none))); 599 600 filter.setController(this); 601 filter.setImageLoader(mImageLoader); 602 listFilters.addView(filter); 603 ImageSmallFilter previousFilter = filter; 604 605 BitmapFactory.Options o = new BitmapFactory.Options(); 606 o.inScaled = false; 607 608 for (int i = 0; i < drawid.length; i++) { 609 Bitmap b = BitmapFactory.decodeResource(getResources(), drawid[i], o); 610 fxArray[p++] = new ImageFilterFx(b, getString(fxNameid[i])); 611 } 612 613 for (int i = 0; i < p; i++) { 614 filter = new ImageSmallFilter(this); 615 filter.setImageFilter(fxArray[i]); 616 filter.setController(this); 617 filter.setImageLoader(mImageLoader); 618 listFilters.addView(filter); 619 previousFilter = filter; 620 } 621 622 // Default preset (original) 623 mImageShow.setImagePreset(preset); 624 } 625 626 private void fillListBorders(LinearLayout listBorders) { 627 // TODO: use listview 628 // TODO: load the borders straight from the filesystem 629 int p = 0; 630 ImageFilter[] borders = new ImageFilter[7]; 631 borders[p++] = new ImageFilterBorder(null); 632 633 Drawable npd1 = getResources().getDrawable(R.drawable.filtershow_border_4x5); 634 borders[p++] = new ImageFilterBorder(npd1); 635 Drawable npd2 = getResources().getDrawable(R.drawable.filtershow_border_brush); 636 borders[p++] = new ImageFilterBorder(npd2); 637 borders[p++] = new ImageFilterParametricBorder(Color.BLACK, mImageBorderSize, 0); 638 borders[p++] = new ImageFilterParametricBorder(Color.BLACK, mImageBorderSize, 639 mImageBorderSize); 640 borders[p++] = new ImageFilterParametricBorder(Color.WHITE, mImageBorderSize, 0); 641 borders[p++] = new ImageFilterParametricBorder(Color.WHITE, mImageBorderSize, 642 mImageBorderSize); 643 644 ImageSmallFilter previousFilter = null; 645 for (int i = 0; i < p; i++) { 646 ImageSmallBorder filter = new ImageSmallBorder(this); 647 borders[i].setName(getString(R.string.borders)); 648 filter.setImageFilter(borders[i]); 649 filter.setController(this); 650 filter.setBorder(true); 651 filter.setImageLoader(mImageLoader); 652 filter.setShowTitle(false); 653 listBorders.addView(filter); 654 previousFilter = filter; 655 } 656 } 657 658 // ////////////////////////////////////////////////////////////////////////////// 659 // Some utility functions 660 // TODO: finish the cleanup. 661 662 public void showOriginalViews(boolean value) { 663 for (ImageShow views : mImageViews) { 664 views.showOriginal(value); 665 } 666 } 667 668 public void invalidateViews() { 669 for (ImageShow views : mImageViews) { 670 views.invalidate(); 671 views.updateImage(); 672 } 673 } 674 675 public void hideListViews() { 676 for (View view : mListViews) { 677 view.setVisibility(View.GONE); 678 } 679 } 680 681 public void hideImageViews() { 682 mImageShow.setShowControls(false); // reset 683 for (View view : mImageViews) { 684 view.setVisibility(View.GONE); 685 } 686 } 687 688 public void unselectBottomPanelButtons() { 689 for (ImageButton button : mBottomPanelButtons) { 690 button.setSelected(false); 691 } 692 } 693 694 public void unselectPanelButtons(Vector<ImageButton> buttons) { 695 for (ImageButton button : buttons) { 696 button.setSelected(false); 697 } 698 } 699 700 // ////////////////////////////////////////////////////////////////////////////// 701 // imageState panel... 702 703 public boolean isShowingHistoryPanel() { 704 return mShowingHistoryPanel; 705 } 706 707 private void toggleImageStatePanel() { 708 final View view = findViewById(R.id.mainPanel); 709 final View viewList = findViewById(R.id.imageStatePanel); 710 711 if (mShowingHistoryPanel) { 712 findViewById(R.id.historyPanel).setVisibility(View.INVISIBLE); 713 mShowingHistoryPanel = false; 714 } 715 716 int translate = translateMainPanel(viewList); 717 if (!mShowingImageStatePanel) { 718 mShowingImageStatePanel = true; 719 view.animate().setDuration(200).x(translate) 720 .withLayer().withEndAction(new Runnable() { 721 @Override 722 public void run() { 723 viewList.setAlpha(0); 724 viewList.setVisibility(View.VISIBLE); 725 viewList.animate().setDuration(100) 726 .alpha(1.0f).start(); 727 } 728 }).start(); 729 } else { 730 mShowingImageStatePanel = false; 731 viewList.setVisibility(View.INVISIBLE); 732 view.animate().setDuration(200).x(0).withLayer() 733 .start(); 734 } 735 invalidateOptionsMenu(); 736 } 737 738 @Override 739 public void onConfigurationChanged(Configuration newConfig) 740 { 741 super.onConfigurationChanged(newConfig); 742 if (mShowingHistoryPanel) { 743 toggleHistoryPanel(); 744 } 745 } 746 747 // ////////////////////////////////////////////////////////////////////////////// 748 // history panel... 749 750 public void toggleHistoryPanel() { 751 final View view = findViewById(R.id.mainPanel); 752 final View viewList = findViewById(R.id.historyPanel); 753 754 if (mShowingImageStatePanel) { 755 findViewById(R.id.imageStatePanel).setVisibility(View.INVISIBLE); 756 mShowingImageStatePanel = false; 757 } 758 759 int translate = translateMainPanel(viewList); 760 if (!mShowingHistoryPanel) { 761 mShowingHistoryPanel = true; 762 view.animate().setDuration(200).x(translate) 763 .withLayer().withEndAction(new Runnable() { 764 @Override 765 public void run() { 766 viewList.setAlpha(0); 767 viewList.setVisibility(View.VISIBLE); 768 viewList.animate().setDuration(100) 769 .alpha(1.0f).start(); 770 } 771 }).start(); 772 } else { 773 mShowingHistoryPanel = false; 774 viewList.setVisibility(View.INVISIBLE); 775 view.animate().setDuration(200).x(0).withLayer() 776 .start(); 777 } 778 invalidateOptionsMenu(); 779 } 780 781 private void resetHistory() { 782 HistoryAdapter adapter = mImageShow.getHistory(); 783 adapter.reset(); 784 ImagePreset original = new ImagePreset(adapter.getItem(0)); 785 mImageShow.setImagePreset(original); 786 mPanelController.resetParameters(); 787 invalidateViews(); 788 } 789 790 // reset button in the history panel. 791 private OnClickListener createOnClickResetOperationsButton() { 792 return new View.OnClickListener() { 793 @Override 794 public void onClick(View v) { 795 resetHistory(); 796 } 797 }; 798 } 799 800 @Override 801 public void onBackPressed() { 802 if (mPanelController.onBackPressed()) { 803 saveImage(); 804 } 805 } 806 807 public void cannotLoadImage() { 808 CharSequence text = getString(R.string.cannot_load_image); 809 Toast toast = Toast.makeText(this, text, Toast.LENGTH_SHORT); 810 toast.show(); 811 finish(); 812 } 813 814 // ////////////////////////////////////////////////////////////////////////////// 815 816 public float getPixelsFromDip(float value) { 817 Resources r = getResources(); 818 return TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, value, 819 r.getDisplayMetrics()); 820 } 821 822 public void useImagePreset(ImageSmallFilter imageSmallFilter, ImagePreset preset) { 823 if (preset == null) { 824 return; 825 } 826 827 if (mCurrentImageSmallFilter != null) { 828 mCurrentImageSmallFilter.setSelected(false); 829 } 830 mCurrentImageSmallFilter = imageSmallFilter; 831 mCurrentImageSmallFilter.setSelected(true); 832 833 ImagePreset copy = new ImagePreset(preset); 834 mImageShow.setImagePreset(copy); 835 if (preset.isFx()) { 836 // if it's an FX we rest the curve adjustment too 837 mImageCurves.resetCurve(); 838 } 839 invalidateViews(); 840 } 841 842 public void useImageFilter(ImageSmallFilter imageSmallFilter, ImageFilter imageFilter, 843 boolean setBorder) { 844 if (imageFilter == null) { 845 return; 846 } 847 848 if (mCurrentImageSmallFilter != null) { 849 mCurrentImageSmallFilter.setSelected(false); 850 } 851 mCurrentImageSmallFilter = imageSmallFilter; 852 mCurrentImageSmallFilter.setSelected(true); 853 854 ImagePreset oldPreset = mImageShow.getImagePreset(); 855 ImagePreset copy = new ImagePreset(oldPreset); 856 // TODO: use a numerical constant instead. 857 858 copy.add(imageFilter); 859 860 mImageShow.setImagePreset(copy); 861 invalidateViews(); 862 } 863 864 @Override 865 public void onItemClick(AdapterView<?> parent, View view, int position, 866 long id) { 867 mImageShow.onItemClick(position); 868 invalidateViews(); 869 } 870 871 public void pickImage() { 872 Intent intent = new Intent(); 873 intent.setType("image/*"); 874 intent.setAction(Intent.ACTION_GET_CONTENT); 875 startActivityForResult(Intent.createChooser(intent, getString(R.string.select_image)), 876 SELECT_PICTURE); 877 } 878 879 @Override 880 public void onActivityResult(int requestCode, int resultCode, Intent data) { 881 Log.v(LOGTAG, "onActivityResult"); 882 if (resultCode == RESULT_OK) { 883 if (requestCode == SELECT_PICTURE) { 884 Uri selectedImageUri = data.getData(); 885 mImageLoader.loadBitmap(selectedImageUri, getScreenImageSize()); 886 } 887 } 888 } 889 890 public void saveImage() { 891 if (mImageShow.hasModifications()) { 892 // Get the name of the album, to which the image will be saved 893 File saveDir = SaveCopyTask.getFinalSaveDirectory(this, mImageLoader.getUri()); 894 int bucketId = GalleryUtils.getBucketId(saveDir.getPath()); 895 String albumName = LocalAlbum.getLocalizedName(getResources(), bucketId, null); 896 showSavingProgress(albumName); 897 mImageShow.saveImage(this, null); 898 } else { 899 finish(); 900 } 901 } 902 903 static { 904 System.loadLibrary("jni_filtershow_filters"); 905 } 906 907} 908