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