summaryrefslogtreecommitdiffstats
path: root/src/com/android
diff options
context:
space:
mode:
Diffstat (limited to 'src/com/android')
-rw-r--r--src/com/android/camera/MosaicFrameProcessor.java3
-rw-r--r--src/com/android/camera/MosaicPreviewRenderer.java3
-rw-r--r--src/com/android/camera/VideoModule.java15
-rw-r--r--src/com/android/gallery3d/app/CommonControllerOverlay.java4
-rw-r--r--src/com/android/gallery3d/filtershow/FilterShowActivity.java20
-rw-r--r--src/com/android/gallery3d/filtershow/ImageStateAdapter.java8
-rw-r--r--src/com/android/gallery3d/filtershow/PanelController.java53
-rw-r--r--src/com/android/gallery3d/filtershow/cache/FilteringPipeline.java38
-rw-r--r--src/com/android/gallery3d/filtershow/cache/ImageLoader.java8
-rw-r--r--src/com/android/gallery3d/filtershow/cache/RenderingRequest.java5
-rw-r--r--src/com/android/gallery3d/filtershow/editors/BasicEditor.java2
-rw-r--r--src/com/android/gallery3d/filtershow/editors/EditorDraw.java4
-rw-r--r--src/com/android/gallery3d/filtershow/editors/EditorRedEye.java2
-rw-r--r--src/com/android/gallery3d/filtershow/filters/BaseFiltersManager.java113
-rw-r--r--src/com/android/gallery3d/filtershow/filters/FilterBasicRepresentation.java4
-rw-r--r--src/com/android/gallery3d/filtershow/filters/FilterDrawRepresentation.java31
-rw-r--r--src/com/android/gallery3d/filtershow/filters/FilterFxRepresentation.java2
-rw-r--r--src/com/android/gallery3d/filtershow/filters/FilterRedEyeRepresentation.java15
-rw-r--r--src/com/android/gallery3d/filtershow/filters/FilterRepresentation.java41
-rw-r--r--src/com/android/gallery3d/filtershow/filters/FilterTinyPlanetRepresentation.java2
-rw-r--r--src/com/android/gallery3d/filtershow/filters/ImageFilter.java13
-rw-r--r--src/com/android/gallery3d/filtershow/filters/ImageFilterBorder.java4
-rw-r--r--src/com/android/gallery3d/filtershow/filters/ImageFilterBwFilter.java2
-rw-r--r--src/com/android/gallery3d/filtershow/filters/ImageFilterContrast.java9
-rw-r--r--src/com/android/gallery3d/filtershow/filters/ImageFilterCurves.java2
-rw-r--r--src/com/android/gallery3d/filtershow/filters/ImageFilterDownsample.java4
-rw-r--r--src/com/android/gallery3d/filtershow/filters/ImageFilterDraw.java47
-rw-r--r--src/com/android/gallery3d/filtershow/filters/ImageFilterEdge.java2
-rw-r--r--src/com/android/gallery3d/filtershow/filters/ImageFilterExposure.java8
-rw-r--r--src/com/android/gallery3d/filtershow/filters/ImageFilterFx.java2
-rw-r--r--src/com/android/gallery3d/filtershow/filters/ImageFilterGeometry.java7
-rw-r--r--src/com/android/gallery3d/filtershow/filters/ImageFilterHue.java5
-rw-r--r--src/com/android/gallery3d/filtershow/filters/ImageFilterKMeans.java2
-rw-r--r--src/com/android/gallery3d/filtershow/filters/ImageFilterNegative.java9
-rw-r--r--src/com/android/gallery3d/filtershow/filters/ImageFilterParametricBorder.java4
-rw-r--r--src/com/android/gallery3d/filtershow/filters/ImageFilterRS.java16
-rw-r--r--src/com/android/gallery3d/filtershow/filters/ImageFilterRedEye.java20
-rw-r--r--src/com/android/gallery3d/filtershow/filters/ImageFilterSaturated.java9
-rw-r--r--src/com/android/gallery3d/filtershow/filters/ImageFilterShadows.java8
-rw-r--r--src/com/android/gallery3d/filtershow/filters/ImageFilterSharpen.java2
-rw-r--r--src/com/android/gallery3d/filtershow/filters/ImageFilterStraighten.java7
-rw-r--r--src/com/android/gallery3d/filtershow/filters/ImageFilterTinyPlanet.java2
-rw-r--r--src/com/android/gallery3d/filtershow/filters/ImageFilterVibrance.java8
-rw-r--r--src/com/android/gallery3d/filtershow/filters/ImageFilterVignette.java10
-rw-r--r--src/com/android/gallery3d/filtershow/filters/ImageFilterWBalance.java12
-rw-r--r--src/com/android/gallery3d/filtershow/filters/SimpleImageFilter.java4
-rw-r--r--src/com/android/gallery3d/filtershow/imageshow/GeometryListener.java21
-rw-r--r--src/com/android/gallery3d/filtershow/imageshow/GeometryMetadata.java4
-rw-r--r--src/com/android/gallery3d/filtershow/imageshow/ImageDraw.java5
-rw-r--r--src/com/android/gallery3d/filtershow/imageshow/ImageRedEye.java2
-rw-r--r--src/com/android/gallery3d/filtershow/imageshow/MasterImage.java19
-rw-r--r--src/com/android/gallery3d/filtershow/presets/ImagePreset.java30
-rw-r--r--src/com/android/gallery3d/filtershow/tools/SaveCopyTask.java2
-rw-r--r--src/com/android/gallery3d/filtershow/ui/FilterIconButton.java20
-rw-r--r--src/com/android/gallery3d/filtershow/ui/ImageCurves.java4
-rw-r--r--src/com/android/gallery3d/ingest/IngestActivity.java230
-rw-r--r--src/com/android/gallery3d/ingest/IngestService.java24
-rw-r--r--src/com/android/gallery3d/ingest/MtpDeviceIndex.java105
-rw-r--r--src/com/android/gallery3d/ingest/adapter/CheckBroker.java56
-rw-r--r--src/com/android/gallery3d/ingest/adapter/MtpAdapter.java16
-rw-r--r--src/com/android/gallery3d/ingest/adapter/MtpPagerAdapter.java102
-rw-r--r--src/com/android/gallery3d/ingest/data/BitmapWithMetadata.java29
-rw-r--r--src/com/android/gallery3d/ingest/data/MtpBitmapFetch.java97
-rw-r--r--src/com/android/gallery3d/ingest/ui/IngestGridView.java58
-rw-r--r--src/com/android/gallery3d/ingest/ui/MtpBitmapCache.java73
-rw-r--r--src/com/android/gallery3d/ingest/ui/MtpFullscreenView.java115
-rw-r--r--src/com/android/gallery3d/ingest/ui/MtpImageView.java130
-rw-r--r--src/com/android/gallery3d/ingest/ui/MtpThumbnailTileView.java90
68 files changed, 1392 insertions, 431 deletions
diff --git a/src/com/android/camera/MosaicFrameProcessor.java b/src/com/android/camera/MosaicFrameProcessor.java
index c59e6b91b..efd4ad2ae 100644
--- a/src/com/android/camera/MosaicFrameProcessor.java
+++ b/src/com/android/camera/MosaicFrameProcessor.java
@@ -92,7 +92,8 @@ public class MosaicFrameProcessor {
mPreviewBufferSize = bufSize;
setupMosaicer(mPreviewWidth, mPreviewHeight, mPreviewBufferSize);
setStripType(Mosaic.STRIPTYPE_WIDE);
- reset();
+ // no need to call reset() here. reset() should be called by the client
+ // after this initialization before calling other methods of this object.
}
public void clear() {
diff --git a/src/com/android/camera/MosaicPreviewRenderer.java b/src/com/android/camera/MosaicPreviewRenderer.java
index e12fe432e..26ce733aa 100644
--- a/src/com/android/camera/MosaicPreviewRenderer.java
+++ b/src/com/android/camera/MosaicPreviewRenderer.java
@@ -90,6 +90,7 @@ public class MosaicPreviewRenderer {
break;
case MSG_RELEASE:
doRelease();
+ mEglThreadBlockVar.open();
break;
}
}
@@ -203,7 +204,7 @@ public class MosaicPreviewRenderer {
}
public void release() {
- mEglHandler.sendEmptyMessage(EGLHandler.MSG_RELEASE);
+ mEglHandler.sendMessageSync(EGLHandler.MSG_RELEASE);
}
public void showPreviewFrameSync() {
diff --git a/src/com/android/camera/VideoModule.java b/src/com/android/camera/VideoModule.java
index 8d84e0074..b7bd20831 100644
--- a/src/com/android/camera/VideoModule.java
+++ b/src/com/android/camera/VideoModule.java
@@ -651,7 +651,7 @@ public class VideoModule implements CameraModule,
if (mQuickCapture) {
doReturnToCaller(!recordFail);
} else if (!recordFail) {
- showAlert();
+ showCaptureResult();
}
}
} else if (!recordFail){
@@ -1657,14 +1657,14 @@ public class VideoModule implements CameraModule,
}
}
- private void showAlert() {
+ private void showCaptureResult() {
Bitmap bitmap = null;
if (mVideoFileDescriptor != null) {
bitmap = Thumbnail.createVideoThumbnailBitmap(mVideoFileDescriptor.getFileDescriptor(),
- mPreviewFrameLayout.getWidth());
+ mDesiredPreviewWidth);
} else if (mCurrentVideoFilename != null) {
bitmap = Thumbnail.createVideoThumbnailBitmap(mCurrentVideoFilename,
- mPreviewFrameLayout.getWidth());
+ mDesiredPreviewWidth);
}
if (bitmap != null) {
// MetadataRetriever already rotates the thumbnail. We should rotate
@@ -2052,7 +2052,7 @@ public class VideoModule implements CameraModule,
if (mQuickCapture) {
doReturnToCaller(true);
} else {
- showAlert();
+ showCaptureResult();
}
}
}
@@ -2175,6 +2175,7 @@ public class VideoModule implements CameraModule,
mShutterButton = mActivity.getShutterButton();
mShutterButton.setImageResource(R.drawable.btn_new_shutter_video);
mShutterButton.setOnShutterButtonListener(this);
+ mShutterButton.setVisibility(View.VISIBLE);
mShutterButton.requestFocus();
mShutterButton.enableTouch(true);
@@ -2202,7 +2203,6 @@ public class VideoModule implements CameraModule,
@Override
public void onConfigurationChanged(Configuration newConfig) {
setDisplayOrientation();
-
// Change layout in response to configuration change
LayoutInflater inflater = mActivity.getLayoutInflater();
((ViewGroup) mRootView).removeAllViews();
@@ -2222,6 +2222,9 @@ public class VideoModule implements CameraModule,
initializeZoom();
onFullScreenChanged(mActivity.isInCameraApp());
updateOnScreenIndicators();
+ if (mIsVideoCaptureIntent && mVideoFileDescriptor != null) {
+ showCaptureResult();
+ }
}
@Override
diff --git a/src/com/android/gallery3d/app/CommonControllerOverlay.java b/src/com/android/gallery3d/app/CommonControllerOverlay.java
index 089872fa5..a5aa805ef 100644
--- a/src/com/android/gallery3d/app/CommonControllerOverlay.java
+++ b/src/com/android/gallery3d/app/CommonControllerOverlay.java
@@ -274,10 +274,6 @@ public abstract class CommonControllerOverlay extends FrameLayout implements
mBackground.layout(0, y - mTimeBar.getBarHeight(), w, y);
mTimeBar.layout(pl, y - mTimeBar.getPreferredHeight(), w - pr, y);
- // Needed, otherwise the framework will not re-layout in case only the
- // padding is changed
- mTimeBar.requestLayout();
-
// Put the play/pause/next/ previous button in the center of the screen
layoutCenteredView(mPlayPauseReplayView, 0, 0, w, h);
diff --git a/src/com/android/gallery3d/filtershow/FilterShowActivity.java b/src/com/android/gallery3d/filtershow/FilterShowActivity.java
index d7ec4c1bd..0660eda30 100644
--- a/src/com/android/gallery3d/filtershow/FilterShowActivity.java
+++ b/src/com/android/gallery3d/filtershow/FilterShowActivity.java
@@ -16,7 +16,6 @@
package com.android.gallery3d.filtershow;
-import android.annotation.TargetApi;
import android.app.ActionBar;
import android.app.Activity;
import android.app.ProgressDialog;
@@ -30,7 +29,6 @@ import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Color;
import android.graphics.Point;
-import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.AsyncTask;
@@ -98,7 +96,6 @@ public class FilterShowActivity extends Activity implements OnItemClickListener,
private final PanelController mPanelController = new PanelController();
private ImageLoader mImageLoader = null;
private ImageShow mImageShow = null;
- private ImageRedEye mImageRedEye = null;
private ImageDraw mImageDraw = null;
private ImageStraighten mImageStraighten = null;
private ImageCrop mImageCrop = null;
@@ -201,7 +198,6 @@ public class FilterShowActivity extends Activity implements OnItemClickListener,
mImageRotate = (ImageRotate) findViewById(R.id.imageRotate);
mImageFlip = (ImageFlip) findViewById(R.id.imageFlip);
mImageTinyPlanet = (ImageTinyPlanet) findViewById(R.id.imageTinyPlanet);
- mImageRedEye = (ImageRedEye) findViewById(R.id.imageRedEyes);
mImageDraw = (ImageDraw) findViewById(R.id.imageDraw);
mImageCrop.setAspectTextSize((int) getPixelsFromDip(18));
@@ -213,7 +209,6 @@ public class FilterShowActivity extends Activity implements OnItemClickListener,
mImageViews.add(mImageRotate);
mImageViews.add(mImageFlip);
mImageViews.add(mImageTinyPlanet);
- mImageViews.add(mImageRedEye);
mEditorPlaceHolder.setContainer((FrameLayout) findViewById(R.id.editorContainer));
mEditorPlaceHolder.addEditor(new EditorDraw());
@@ -254,7 +249,6 @@ public class FilterShowActivity extends Activity implements OnItemClickListener,
mImageRotate.setImageLoader(mImageLoader);
mImageFlip.setImageLoader(mImageLoader);
mImageTinyPlanet.setImageLoader(mImageLoader);
- mImageRedEye.setImageLoader(mImageLoader);
mImageDraw.setImageLoader(mImageLoader);
mPanelController.setActivity(this);
@@ -266,7 +260,6 @@ public class FilterShowActivity extends Activity implements OnItemClickListener,
mPanelController.addImageView(findViewById(R.id.imageRotate));
mPanelController.addImageView(findViewById(R.id.imageFlip));
mPanelController.addImageView(findViewById(R.id.imageTinyPlanet));
- mPanelController.addImageView(findViewById(R.id.imageRedEyes));
mPanelController.addImageView(findViewById(R.id.imageDraw));
mPanelController.addPanel(mFxButton, mListFx, 0);
@@ -277,17 +270,18 @@ public class FilterShowActivity extends Activity implements OnItemClickListener,
mPanelController.addComponent(mGeometryButton, findViewById(R.id.cropButton));
mPanelController.addComponent(mGeometryButton, findViewById(R.id.rotateButton));
mPanelController.addComponent(mGeometryButton, findViewById(R.id.flipButton));
- mPanelController.addComponent(mGeometryButton, findViewById(R.id.redEyeButton));
mPanelController.addPanel(mColorsButton, mListColors, 3);
Vector<FilterRepresentation> filtersRepresentations = new Vector<FilterRepresentation>();
- FiltersManager.addFilterRepresentations(filtersRepresentations);
+
+ FiltersManager filtersManager = FiltersManager.getManager();
+ filtersManager.addEffects(filtersRepresentations);
+
for (FilterRepresentation representation : filtersRepresentations) {
setupFilterRepresentationButton(representation, listColors, mColorsButton);
}
-
mPanelController.addView(findViewById(R.id.applyEffect));
findViewById(R.id.resetOperationsButton).setOnClickListener(
createOnClickResetOperationsButton());
@@ -775,6 +769,12 @@ public class FilterShowActivity extends Activity implements OnItemClickListener,
mNullFxFilter = setupFilterRepresentationButton(nullFx, listFilters, mFxButton);
mNullFxFilter.setSelected(true);
+ Vector<FilterRepresentation> filtersRepresentations = new Vector<FilterRepresentation>();
+ FiltersManager.getManager().addLooks(filtersRepresentations);
+ for (FilterRepresentation representation : filtersRepresentations) {
+ setupFilterRepresentationButton(representation, listFilters, mFxButton);
+ }
+
for (int i = 0; i < p; i++) {
setupFilterRepresentationButton(fxArray[i], listFilters, mFxButton);
}
diff --git a/src/com/android/gallery3d/filtershow/ImageStateAdapter.java b/src/com/android/gallery3d/filtershow/ImageStateAdapter.java
index 5de96961c..58e0035bc 100644
--- a/src/com/android/gallery3d/filtershow/ImageStateAdapter.java
+++ b/src/com/android/gallery3d/filtershow/ImageStateAdapter.java
@@ -24,9 +24,10 @@ import android.widget.ArrayAdapter;
import android.widget.TextView;
import com.android.gallery3d.R;
+import com.android.gallery3d.filtershow.filters.FilterRepresentation;
import com.android.gallery3d.filtershow.filters.ImageFilter;
-public class ImageStateAdapter extends ArrayAdapter<ImageFilter> {
+public class ImageStateAdapter extends ArrayAdapter<FilterRepresentation> {
private static final String LOGTAG = "ImageStateAdapter";
public ImageStateAdapter(Context context, int textViewResourceId) {
@@ -41,13 +42,12 @@ public class ImageStateAdapter extends ArrayAdapter<ImageFilter> {
Context.LAYOUT_INFLATER_SERVICE);
view = inflater.inflate(R.layout.filtershow_imagestate_row, null);
}
- ImageFilter filter = getItem(position);
+ FilterRepresentation filter = getItem(position);
if (filter != null) {
TextView itemLabel = (TextView) view.findViewById(R.id.imagestate_label);
itemLabel.setText(filter.getName());
TextView itemParameter = (TextView) view.findViewById(R.id.imagestate_parameter);
- // TODO: fix the image state adapter
- // itemParameter.setText("" + filter.getParameter());
+ itemParameter.setText(filter.getStateRepresentation());
}
return view;
}
diff --git a/src/com/android/gallery3d/filtershow/PanelController.java b/src/com/android/gallery3d/filtershow/PanelController.java
index 561ac6c81..18a9585a6 100644
--- a/src/com/android/gallery3d/filtershow/PanelController.java
+++ b/src/com/android/gallery3d/filtershow/PanelController.java
@@ -445,49 +445,6 @@ public class PanelController implements OnClickListener {
return MasterImage.getImage().getPreset();
}
- /**
- public ImageFilter setImagePreset(ImageFilter filter, String name) {
- ImagePreset copy = new ImagePreset(getImagePreset());
- copy.add(filter);
- copy.setHistoryName(name);
- copy.setIsFx(false);
- mMasterImage.setPreset(copy, true);
- return filter;
- }
- */
-
- // TODO: remove this.
- public void ensureFilter(String name) {
- /*
- ImagePreset preset = getImagePreset();
- ImageFilter filter = preset.getFilter(name);
- if (filter != null) {
- // If we already have a filter, we might still want
- // to push it onto the history stack.
- ImagePreset copy = new ImagePreset(getImagePreset());
- copy.setHistoryName(name);
- mMasterImage.setPreset(copy, true);
- filter = copy.getFilter(name);
- }
-
- if (filter == null) {
- ImageFilter filterInstance = mFilters.get(name);
- if (filterInstance != null) {
- try {
- ImageFilter newFilter = filterInstance.clone();
- newFilter.reset();
- filter = setImagePreset(newFilter, name);
- } catch (CloneNotSupportedException e) {
- e.printStackTrace();
- }
- }
- }
- if (filter != null) {
- mMasterImage.setCurrentFilter(filter);
- }
- */
- }
-
public void useFilterRepresentation(FilterRepresentation filterRepresentation) {
if (filterRepresentation == null) {
return;
@@ -502,7 +459,7 @@ public class PanelController implements OnClickListener {
copy.addFilter(filterRepresentation);
} else {
if (filterRepresentation.allowsMultipleInstances()) {
- representation.useParametersFrom(filterRepresentation);
+ representation.updateTempParametersFrom(filterRepresentation);
copy.setHistoryName(filterRepresentation.getName());
}
filterRepresentation = representation;
@@ -579,7 +536,6 @@ public class PanelController implements OnClickListener {
mCurrentImage = showImageView(R.id.imageTinyPlanet).setShowControls(true);
String ename = mCurrentImage.getContext().getString(R.string.tinyplanet);
mUtilityPanel.setEffectName(ename);
- ensureFilter(ename);
if (!mDisableFilterButtons) {
mActivity.disableFilterButtons();
mDisableFilterButtons = true;
@@ -617,13 +573,6 @@ public class PanelController implements OnClickListener {
mUtilityPanel.setShowParameter(false);
break;
}
- case R.id.redEyeButton: {
- mCurrentImage = showImageView(R.id.imageRedEyes).setShowControls(true);
- String ename = mCurrentImage.getContext().getString(R.string.redeye);
- mUtilityPanel.setEffectName(ename);
- ensureFilter(ename);
- break;
- }
case R.id.applyEffect: {
if (MasterImage.getImage().getCurrentFilter() instanceof ImageFilterTinyPlanet) {
mActivity.saveImage();
diff --git a/src/com/android/gallery3d/filtershow/cache/FilteringPipeline.java b/src/com/android/gallery3d/filtershow/cache/FilteringPipeline.java
index 472fad759..419abe85d 100644
--- a/src/com/android/gallery3d/filtershow/cache/FilteringPipeline.java
+++ b/src/com/android/gallery3d/filtershow/cache/FilteringPipeline.java
@@ -22,6 +22,8 @@ import android.os.Process;
import android.support.v8.renderscript.*;
import android.util.Log;
+import com.android.gallery3d.filtershow.filters.BaseFiltersManager;
+import com.android.gallery3d.filtershow.filters.FiltersManager;
import com.android.gallery3d.filtershow.filters.ImageFilterRS;
import com.android.gallery3d.filtershow.imageshow.GeometryMetadata;
import com.android.gallery3d.filtershow.imageshow.MasterImage;
@@ -136,6 +138,10 @@ public class FilteringPipeline implements Handler.Callback {
return false;
}
+ if (DEBUG) {
+ Log.v(LOGTAG, "geometry has changed");
+ }
+
RenderScript RS = ImageFilterRS.getRenderScriptContext();
if (mFiltersOnlyOriginalAllocation != null) {
mFiltersOnlyOriginalAllocation.destroy();
@@ -151,6 +157,7 @@ public class FilteringPipeline implements Handler.Callback {
mPreviousGeometry = new GeometryMetadata(geometry);
+ FiltersManager.getManager().resetBitmapsRS();
return true;
}
@@ -184,20 +191,44 @@ public class FilteringPipeline implements Handler.Callback {
private void setPresetParameters(ImagePreset preset) {
preset.setScaleFactor(mPreviewScaleFactor);
if (mPreviewScaleFactor < 1.0f) {
- preset.setIsHighQuality(false);
+ preset.setQuality(ImagePreset.QUALITY_PREVIEW);
} else {
- preset.setIsHighQuality(true);
+ preset.setQuality(ImagePreset.QUALITY_PREVIEW);
}
}
+ private String getType(RenderingRequest request) {
+ if (request.getType() == RenderingRequest.ICON_RENDERING) {
+ return "ICON_RENDERING";
+ }
+ if (request.getType() == RenderingRequest.FILTERS_RENDERING) {
+ return "FILTERS_RENDERING";
+ }
+ if (request.getType() == RenderingRequest.FULL_RENDERING) {
+ return "FULL_RENDERING";
+ }
+ if (request.getType() == RenderingRequest.GEOMETRY_RENDERING) {
+ return "GEOMETRY_RENDERING";
+ }
+ return "UNKNOWN TYPE!";
+ }
+
private void render(RenderingRequest request) {
if (request.getBitmap() == null
|| request.getImagePreset() == null) {
return;
}
+ if (DEBUG) {
+ Log.v(LOGTAG, "render image of type " + getType(request));
+ }
+
Bitmap bitmap = request.getBitmap();
ImagePreset preset = request.getImagePreset();
setPresetParameters(preset);
+ if (request.getType() == RenderingRequest.FILTERS_RENDERING) {
+ FiltersManager.getManager().resetBitmapsRS();
+ }
+
if (request.getType() != RenderingRequest.ICON_RENDERING) {
updateOriginalAllocation(preset);
}
@@ -218,6 +249,9 @@ public class FilteringPipeline implements Handler.Callback {
Bitmap bmp = preset.apply(bitmap);
request.setBitmap(bmp);
}
+ if (request.getType() == RenderingRequest.FILTERS_RENDERING) {
+ FiltersManager.getManager().resetBitmapsRS();
+ }
}
private void compute(TripleBufferBitmap buffer, ImagePreset preset, int type) {
diff --git a/src/com/android/gallery3d/filtershow/cache/ImageLoader.java b/src/com/android/gallery3d/filtershow/cache/ImageLoader.java
index b47d13b9e..00fcf4e19 100644
--- a/src/com/android/gallery3d/filtershow/cache/ImageLoader.java
+++ b/src/com/android/gallery3d/filtershow/cache/ImageLoader.java
@@ -280,7 +280,7 @@ public class ImageLoader {
return null;
}
- static final int MAX_BITMAP_DIM = 2048;
+ static final int MAX_BITMAP_DIM = 900;
private Bitmap loadScaledBitmap(Uri uri, int size) {
InputStream is = null;
@@ -392,7 +392,7 @@ public class ImageLoader {
public void saveImage(ImagePreset preset, final FilterShowActivity filterShowActivity,
File destination) {
- preset.setIsHighQuality(true);
+ preset.setQuality(ImagePreset.QUALITY_FINAL);
preset.setScaleFactor(1.0f);
new SaveCopyTask(mContext, mUri, destination, new SaveCopyTask.Callback() {
@@ -432,7 +432,7 @@ public class ImageLoader {
public void returnFilteredResult(ImagePreset preset,
final FilterShowActivity filterShowActivity) {
- preset.setIsHighQuality(true);
+ preset.setQuality(ImagePreset.QUALITY_FINAL);
preset.setScaleFactor(1.0f);
BitmapTask.Callbacks<ImagePreset> cb = new BitmapTask.Callbacks<ImagePreset>() {
@@ -448,7 +448,7 @@ public class ImageLoader {
@Override
public Bitmap onExecute(ImagePreset param) {
- if (param == null) {
+ if (param == null || mUri == null) {
return null;
}
Bitmap bitmap = loadMutableBitmap(mContext, mUri);
diff --git a/src/com/android/gallery3d/filtershow/cache/RenderingRequest.java b/src/com/android/gallery3d/filtershow/cache/RenderingRequest.java
index 2815936f8..1e9f6b83a 100644
--- a/src/com/android/gallery3d/filtershow/cache/RenderingRequest.java
+++ b/src/com/android/gallery3d/filtershow/cache/RenderingRequest.java
@@ -18,6 +18,7 @@ package com.android.gallery3d.filtershow.cache;
import android.graphics.Bitmap;
import com.android.gallery3d.app.Log;
+import com.android.gallery3d.filtershow.imageshow.MasterImage;
import com.android.gallery3d.filtershow.presets.ImagePreset;
public class RenderingRequest {
@@ -47,7 +48,9 @@ public class RenderingRequest {
bitmap = Bitmap.createBitmap(source.getWidth(), source.getHeight(), mConfig);
}
request.setBitmap(bitmap);
- request.setImagePreset(new ImagePreset(preset));
+ ImagePreset passedPreset = new ImagePreset(preset);
+ passedPreset.setImageLoader(MasterImage.getImage().getImageLoader());
+ request.setImagePreset(passedPreset);
request.setType(type);
request.setCaller(caller);
request.post();
diff --git a/src/com/android/gallery3d/filtershow/editors/BasicEditor.java b/src/com/android/gallery3d/filtershow/editors/BasicEditor.java
index b7f5d7d26..48aa5925a 100644
--- a/src/com/android/gallery3d/filtershow/editors/BasicEditor.java
+++ b/src/com/android/gallery3d/filtershow/editors/BasicEditor.java
@@ -65,7 +65,7 @@ public class BasicEditor extends Editor implements OnSeekBarChangeListener {
if (getLocalRepresentation() != null && getLocalRepresentation() instanceof FilterBasicRepresentation) {
FilterBasicRepresentation interval = (FilterBasicRepresentation) getLocalRepresentation();
boolean f = interval.showParameterValue();
- mSeekBar.setVisibility((f) ? View.VISIBLE : View.INVISIBLE);
+ mSeekBar.setVisibility((f) ? View.VISIBLE : View.GONE);
int value = interval.getValue();
int min = interval.getMinimum();
int max = interval.getMaximum();
diff --git a/src/com/android/gallery3d/filtershow/editors/EditorDraw.java b/src/com/android/gallery3d/filtershow/editors/EditorDraw.java
index 128af8ec7..aa5ec61e8 100644
--- a/src/com/android/gallery3d/filtershow/editors/EditorDraw.java
+++ b/src/com/android/gallery3d/filtershow/editors/EditorDraw.java
@@ -120,6 +120,10 @@ public class EditorDraw extends Editor {
} else if (item.getItemId() == R.id.draw_menu_style_line) {
ImageDraw idraw = (ImageDraw) mImageShow;
idraw.setStyle(ImageFilterDraw.SIMPLE_STYLE);
+ } else if (item.getItemId() == R.id.draw_menu_clear) {
+ ImageDraw idraw = (ImageDraw) mImageShow;
+ idraw.resetParameter();
+ commitLocalRepresentation();
}
mView.invalidate();
return true;
diff --git a/src/com/android/gallery3d/filtershow/editors/EditorRedEye.java b/src/com/android/gallery3d/filtershow/editors/EditorRedEye.java
index 271f16535..c37102b37 100644
--- a/src/com/android/gallery3d/filtershow/editors/EditorRedEye.java
+++ b/src/com/android/gallery3d/filtershow/editors/EditorRedEye.java
@@ -51,10 +51,10 @@ public class EditorRedEye extends Editor {
@Override
public void reflectCurrentFilter() {
super.reflectCurrentFilter();
-
FilterRepresentation rep = getLocalRepresentation();
if (rep != null && getLocalRepresentation() instanceof FilterRedEyeRepresentation) {
FilterRedEyeRepresentation redEyeRep = (FilterRedEyeRepresentation) rep;
+
mImageRedEyes.setRepresentation(redEyeRep);
}
}
diff --git a/src/com/android/gallery3d/filtershow/filters/BaseFiltersManager.java b/src/com/android/gallery3d/filtershow/filters/BaseFiltersManager.java
new file mode 100644
index 000000000..43660d6a0
--- /dev/null
+++ b/src/com/android/gallery3d/filtershow/filters/BaseFiltersManager.java
@@ -0,0 +1,113 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.gallery3d.filtershow.filters;
+
+import com.android.gallery3d.filtershow.cache.ImageLoader;
+
+import java.util.HashMap;
+import java.util.Vector;
+
+public class BaseFiltersManager {
+
+ private static final String LOGTAG = "BaseFiltersManager";
+ private static HashMap<Class, ImageFilter> mFilters = new HashMap<Class, ImageFilter>();
+
+ protected BaseFiltersManager() {
+ Vector<ImageFilter> filters = new Vector<ImageFilter>();
+ addFilters(filters);
+ for (ImageFilter filter : filters) {
+ mFilters.put(filter.getClass(), filter);
+ }
+ }
+
+ protected void addFilters(Vector<ImageFilter> filters) {
+ filters.add(new ImageFilterTinyPlanet());
+ filters.add(new ImageFilterRedEye());
+ filters.add(new ImageFilterWBalance());
+ filters.add(new ImageFilterExposure());
+ filters.add(new ImageFilterVignette());
+ filters.add(new ImageFilterContrast());
+ filters.add(new ImageFilterShadows());
+ filters.add(new ImageFilterVibrance());
+ filters.add(new ImageFilterSharpen());
+ filters.add(new ImageFilterCurves());
+ filters.add(new ImageFilterDraw());
+ filters.add(new ImageFilterHue());
+ filters.add(new ImageFilterSaturated());
+ filters.add(new ImageFilterBwFilter());
+ filters.add(new ImageFilterNegative());
+ filters.add(new ImageFilterEdge());
+ filters.add(new ImageFilterKMeans());
+ filters.add(new ImageFilterFx());
+ filters.add(new ImageFilterBorder());
+ filters.add(new ImageFilterParametricBorder());
+ }
+
+ public ImageFilter getFilter(Class c) {
+ return mFilters.get(c);
+ }
+
+ public ImageFilter getFilterForRepresentation(FilterRepresentation representation) {
+ return mFilters.get(representation.getFilterClass());
+ }
+
+ public void addFilter(Class filterClass, ImageFilter filter) {
+ mFilters.put(filterClass, filter);
+ }
+
+ public FilterRepresentation getRepresentation(Class c) {
+ ImageFilter filter = mFilters.get(c);
+ if (filter != null) {
+ return filter.getDefaultRepresentation();
+ }
+ return null;
+ }
+
+ public void addLooks(Vector<FilterRepresentation> representations) {
+ // subclass can add representations
+ }
+
+ public void addEffects(Vector<FilterRepresentation> representations) {
+ representations.add(getRepresentation(ImageFilterTinyPlanet.class));
+ representations.add(getRepresentation(ImageFilterRedEye.class));
+ representations.add(getRepresentation(ImageFilterWBalance.class));
+ representations.add(getRepresentation(ImageFilterExposure.class));
+ representations.add(getRepresentation(ImageFilterVignette.class));
+ representations.add(getRepresentation(ImageFilterContrast.class));
+ representations.add(getRepresentation(ImageFilterShadows.class));
+ representations.add(getRepresentation(ImageFilterVibrance.class));
+ representations.add(getRepresentation(ImageFilterSharpen.class));
+ representations.add(getRepresentation(ImageFilterCurves.class));
+ representations.add(getRepresentation(ImageFilterDraw.class));
+ representations.add(getRepresentation(ImageFilterHue.class));
+ representations.add(getRepresentation(ImageFilterSaturated.class));
+ representations.add(getRepresentation(ImageFilterBwFilter.class));
+ representations.add(getRepresentation(ImageFilterNegative.class));
+ representations.add(getRepresentation(ImageFilterEdge.class));
+ representations.add(getRepresentation(ImageFilterKMeans.class));
+ }
+
+ public void resetBitmapsRS() {
+ for (Class c : mFilters.keySet()) {
+ ImageFilter filter = mFilters.get(c);
+ if (filter instanceof ImageFilterRS) {
+ ImageFilterRS filterRS = (ImageFilterRS) filter;
+ filterRS.resetBitmap();
+ }
+ }
+ }
+}
diff --git a/src/com/android/gallery3d/filtershow/filters/FilterBasicRepresentation.java b/src/com/android/gallery3d/filtershow/filters/FilterBasicRepresentation.java
index f6f308dba..2410ebe72 100644
--- a/src/com/android/gallery3d/filtershow/filters/FilterBasicRepresentation.java
+++ b/src/com/android/gallery3d/filtershow/filters/FilterBasicRepresentation.java
@@ -121,4 +121,8 @@ public class FilterBasicRepresentation extends FilterRepresentation {
public void setPreviewValue(int previewValue) {
mPreviewValue = previewValue;
}
+
+ public String getStateRepresentation() {
+ return "" + getValue();
+ }
}
diff --git a/src/com/android/gallery3d/filtershow/filters/FilterDrawRepresentation.java b/src/com/android/gallery3d/filtershow/filters/FilterDrawRepresentation.java
index b8fa0a3d4..e41f0a622 100644
--- a/src/com/android/gallery3d/filtershow/filters/FilterDrawRepresentation.java
+++ b/src/com/android/gallery3d/filtershow/filters/FilterDrawRepresentation.java
@@ -17,6 +17,8 @@
package com.android.gallery3d.filtershow.filters;
import android.graphics.Path;
+import android.util.Log;
+
import com.android.gallery3d.R;
import com.android.gallery3d.filtershow.editors.EditorDraw;
@@ -30,7 +32,7 @@ public class FilterDrawRepresentation extends FilterRepresentation {
public Path mPath;
public float mRadius;
public int mColor;
-
+ public int noPoints = 0;
@Override
public String toString() {
return "stroke(" + mType + ", path(" + (mPath) + "), " + mRadius + " , "
@@ -48,7 +50,7 @@ public class FilterDrawRepresentation extends FilterRepresentation {
public FilterDrawRepresentation() {
super("Draw");
setFilterClass(ImageFilterDraw.class);
- setFilterType(FilterRepresentation.TYPE_VIGNETTE);
+ setPriority(FilterRepresentation.TYPE_VIGNETTE);
setTextId(R.string.imageDraw);
setButtonId(R.id.drawOnImageButton);
setEditorId(EditorDraw.ID);
@@ -57,7 +59,8 @@ public class FilterDrawRepresentation extends FilterRepresentation {
@Override
public String toString() {
return getName() + " : strokes=" + mDrawing.size()
- + ((mCurrent == null) ? " no current " : ("current=" + mCurrent.mType));
+ + ((mCurrent == null) ? " no current "
+ : ("draw=" + mCurrent.mType + " " + mCurrent.noPoints));
}
public Vector<StrokeData> getDrawing() {
@@ -91,10 +94,15 @@ public class FilterDrawRepresentation extends FilterRepresentation {
}
if (representation.mDrawing != null) {
mDrawing = (Vector<StrokeData>) representation.mDrawing.clone();
+ } else {
+ mDrawing = null;
}
+
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
+ } else {
+ Log.v(LOGTAG, "cannot use parameters from " + a);
}
}
@@ -104,8 +112,18 @@ public class FilterDrawRepresentation extends FilterRepresentation {
return false;
}
if (representation instanceof FilterDrawRepresentation) {
- // FIXME!
- return true;
+ FilterDrawRepresentation fdRep = (FilterDrawRepresentation) representation;
+ if (fdRep.mDrawing.size() != mDrawing.size())
+ return false;
+ if (fdRep.mCurrent == null && mCurrent.mPath == null) {
+ return true;
+ }
+ if (fdRep.mCurrent != null && mCurrent.mPath != null) {
+ if (fdRep.mCurrent.noPoints == mCurrent.noPoints) {
+ return true;
+ }
+ return false;
+ }
}
return false;
}
@@ -117,14 +135,17 @@ public class FilterDrawRepresentation extends FilterRepresentation {
mCurrent.mType = type;
mCurrent.mPath = new Path();
mCurrent.mPath.moveTo(x, y);
+ mCurrent.noPoints = 0;
}
public void addPoint(float x, float y) {
+ mCurrent.noPoints++;
mCurrent.mPath.lineTo(x, y);
}
public void endSection(float x, float y) {
mCurrent.mPath.lineTo(x, y);
+ mCurrent.noPoints++;
mDrawing.add(mCurrent);
mCurrent = null;
}
diff --git a/src/com/android/gallery3d/filtershow/filters/FilterFxRepresentation.java b/src/com/android/gallery3d/filtershow/filters/FilterFxRepresentation.java
index fa3fe720b..859bf327c 100644
--- a/src/com/android/gallery3d/filtershow/filters/FilterFxRepresentation.java
+++ b/src/com/android/gallery3d/filtershow/filters/FilterFxRepresentation.java
@@ -31,7 +31,7 @@ public class FilterFxRepresentation extends FilterRepresentation {
mBitmapResource = bitmapResource;
mNameResource = nameResource;
setFilterClass(ImageFilterFx.class);
- setFilterType(FilterRepresentation.TYPE_FX);
+ setPriority(FilterRepresentation.TYPE_FX);
setTextId(nameResource);
setEditorId(ImageOnlyEditor.ID);
setShowEditingControls(false);
diff --git a/src/com/android/gallery3d/filtershow/filters/FilterRedEyeRepresentation.java b/src/com/android/gallery3d/filtershow/filters/FilterRedEyeRepresentation.java
index 38d3a696f..7779211df 100644
--- a/src/com/android/gallery3d/filtershow/filters/FilterRedEyeRepresentation.java
+++ b/src/com/android/gallery3d/filtershow/filters/FilterRedEyeRepresentation.java
@@ -31,10 +31,10 @@ public class FilterRedEyeRepresentation extends FilterRepresentation {
public FilterRedEyeRepresentation() {
super("RedEye");
setFilterClass(ImageFilterRedEye.class);
- setFilterType(FilterRepresentation.TYPE_NORMAL);
- setButtonId(R.id.redEyeButton);
+ setPriority(FilterRepresentation.TYPE_NORMAL);
setTextId(R.string.redeye);
setEditorId(EditorRedEye.ID);
+ setOverlayId(R.drawable.photoeditor_effect_redeye);
}
@Override
@@ -65,6 +65,17 @@ public class FilterRedEyeRepresentation extends FilterRepresentation {
this.mCandidates.add(c);
}
+ @Override
+ public void useParametersFrom(FilterRepresentation a) {
+ if (a instanceof FilterRedEyeRepresentation) {
+ FilterRedEyeRepresentation representation = (FilterRedEyeRepresentation) a;
+ mCandidates.clear();
+ for (RedEyeCandidate redEyeCandidate : representation.mCandidates) {
+ mCandidates.add(redEyeCandidate);
+ }
+ }
+ }
+
public void removeCandidate(RedEyeCandidate c) {
this.mCandidates.remove(c);
}
diff --git a/src/com/android/gallery3d/filtershow/filters/FilterRepresentation.java b/src/com/android/gallery3d/filtershow/filters/FilterRepresentation.java
index f282d2966..513cdcdef 100644
--- a/src/com/android/gallery3d/filtershow/filters/FilterRepresentation.java
+++ b/src/com/android/gallery3d/filtershow/filters/FilterRepresentation.java
@@ -23,8 +23,7 @@ import com.android.gallery3d.filtershow.presets.ImagePreset;
public class FilterRepresentation implements Cloneable {
private static final String LOGTAG = "FilterRepresentation";
private String mName;
- private int mPriority;
- private ImagePreset mPreset;
+ private int mPriority = TYPE_NORMAL;
private Class mFilterClass;
private int mTextId = 0;
private int mEditorId = BasicEditor.ID;
@@ -40,7 +39,8 @@ public class FilterRepresentation implements Cloneable {
public static final byte TYPE_VIGNETTE = 4;
public static final byte TYPE_NORMAL = 5;
public static final byte TYPE_TINYPLANET = 6;
- private byte filterType = TYPE_NORMAL;
+
+ public FilterRepresentation mTempRepresentation = null;
public FilterRepresentation(String name) {
mName = name;
@@ -86,14 +86,6 @@ public class FilterRepresentation implements Cloneable {
return mName;
}
- public byte getFilterType() {
- return filterType;
- }
-
- protected void setFilterType(byte type) {
- filterType = type;
- }
-
public void setName(String name) {
mName = name;
}
@@ -110,10 +102,6 @@ public class FilterRepresentation implements Cloneable {
return mPriority;
}
- public void setImagePreset(ImagePreset preset) {
- mPreset = preset;
- }
-
public boolean isNil() {
return false;
}
@@ -121,6 +109,24 @@ public class FilterRepresentation implements Cloneable {
public void useParametersFrom(FilterRepresentation a) {
}
+ public synchronized void updateTempParametersFrom(FilterRepresentation representation) {
+ if (mTempRepresentation == null) {
+ try {
+ mTempRepresentation = representation.clone();
+ } catch (CloneNotSupportedException e) {
+ e.printStackTrace();
+ }
+ } else {
+ mTempRepresentation.useParametersFrom(representation);
+ }
+ }
+
+ public synchronized void synchronizeRepresentation() {
+ if (mTempRepresentation != null) {
+ useParametersFrom(mTempRepresentation);
+ }
+ }
+
public boolean allowsMultipleInstances() {
return false;
}
@@ -195,4 +201,9 @@ public class FilterRepresentation implements Cloneable {
public void setShowUtilityPanel(boolean showUtilityPanel) {
mShowUtilityPanel = showUtilityPanel;
}
+
+ public String getStateRepresentation() {
+ return "";
+ }
+
}
diff --git a/src/com/android/gallery3d/filtershow/filters/FilterTinyPlanetRepresentation.java b/src/com/android/gallery3d/filtershow/filters/FilterTinyPlanetRepresentation.java
index 9bf2f0bf3..7b69ce9e0 100644
--- a/src/com/android/gallery3d/filtershow/filters/FilterTinyPlanetRepresentation.java
+++ b/src/com/android/gallery3d/filtershow/filters/FilterTinyPlanetRepresentation.java
@@ -27,7 +27,7 @@ public class FilterTinyPlanetRepresentation extends FilterBasicRepresentation {
super("TinyPlanet", 0, 50, 100);
setShowParameterValue(true);
setFilterClass(ImageFilterTinyPlanet.class);
- setFilterType(FilterRepresentation.TYPE_TINYPLANET);
+ setPriority(FilterRepresentation.TYPE_TINYPLANET);
setTextId(R.string.tinyplanet);
setButtonId(R.id.tinyplanetButton);
setEditorId(EditorTinyPlanet.ID);
diff --git a/src/com/android/gallery3d/filtershow/filters/ImageFilter.java b/src/com/android/gallery3d/filtershow/filters/ImageFilter.java
index d7a76d614..7c5a75232 100644
--- a/src/com/android/gallery3d/filtershow/filters/ImageFilter.java
+++ b/src/com/android/gallery3d/filtershow/filters/ImageFilter.java
@@ -22,7 +22,7 @@ import com.android.gallery3d.R;
import com.android.gallery3d.filtershow.editors.BasicEditor;
import com.android.gallery3d.filtershow.presets.ImagePreset;
-public class ImageFilter implements Cloneable {
+public abstract class ImageFilter implements Cloneable {
private ImagePreset mImagePreset;
@@ -37,7 +37,7 @@ public class ImageFilter implements Cloneable {
return mName;
}
- public Bitmap apply(Bitmap bitmap, float scaleFactor, boolean highQuality) {
+ public Bitmap apply(Bitmap bitmap, float scaleFactor, int quality) {
// do nothing here, subclasses will implement filtering here
return bitmap;
}
@@ -46,17 +46,20 @@ public class ImageFilter implements Cloneable {
* Called on small bitmaps to create button icons for each filter.
* Override this to provide filter-specific button icons.
*/
- public Bitmap iconApply(Bitmap bitmap, float scaleFactor, boolean highQuality) {
- return apply(bitmap, scaleFactor, highQuality);
+ public Bitmap iconApply(Bitmap bitmap, float scaleFactor, int quality) {
+ return apply(bitmap, scaleFactor, quality);
}
public ImagePreset getImagePreset() {
return mImagePreset;
}
- public void useRepresentation(FilterRepresentation representation) {
+ public void setImagePreset(ImagePreset imagePreset) {
+ mImagePreset = imagePreset;
}
+ public abstract void useRepresentation(FilterRepresentation representation);
+
native protected void nativeApplyGradientFilter(Bitmap bitmap, int w, int h,
int[] redGradient, int[] greenGradient, int[] blueGradient);
diff --git a/src/com/android/gallery3d/filtershow/filters/ImageFilterBorder.java b/src/com/android/gallery3d/filtershow/filters/ImageFilterBorder.java
index 416af9417..70e7f2220 100644
--- a/src/com/android/gallery3d/filtershow/filters/ImageFilterBorder.java
+++ b/src/com/android/gallery3d/filtershow/filters/ImageFilterBorder.java
@@ -63,7 +63,7 @@ public class ImageFilterBorder extends ImageFilter {
}
@Override
- public Bitmap apply(Bitmap bitmap, float scaleFactor, boolean highQuality) {
+ public Bitmap apply(Bitmap bitmap, float scaleFactor, int quality) {
if (getParameters() == null || getParameters().getDrawableResource() == 0) {
return bitmap;
}
@@ -73,7 +73,7 @@ public class ImageFilterBorder extends ImageFilter {
}
@Override
- public Bitmap iconApply(Bitmap bitmap, float scaleFactor, boolean highQuality) {
+ public Bitmap iconApply(Bitmap bitmap, float scaleFactor, int quality) {
if (getParameters() == null || getParameters().getDrawableResource() == 0) {
return bitmap;
}
diff --git a/src/com/android/gallery3d/filtershow/filters/ImageFilterBwFilter.java b/src/com/android/gallery3d/filtershow/filters/ImageFilterBwFilter.java
index 3580dd693..c92ac012d 100644
--- a/src/com/android/gallery3d/filtershow/filters/ImageFilterBwFilter.java
+++ b/src/com/android/gallery3d/filtershow/filters/ImageFilterBwFilter.java
@@ -42,7 +42,7 @@ public class ImageFilterBwFilter extends SimpleImageFilter {
native protected void nativeApplyFilter(Bitmap bitmap, int w, int h, int r, int g, int b);
@Override
- public Bitmap apply(Bitmap bitmap, float scaleFactor, boolean highQuality) {
+ public Bitmap apply(Bitmap bitmap, float scaleFactor, int quality) {
if (getParameters() == null) {
return bitmap;
}
diff --git a/src/com/android/gallery3d/filtershow/filters/ImageFilterContrast.java b/src/com/android/gallery3d/filtershow/filters/ImageFilterContrast.java
index e2664269b..2f94e3d17 100644
--- a/src/com/android/gallery3d/filtershow/filters/ImageFilterContrast.java
+++ b/src/com/android/gallery3d/filtershow/filters/ImageFilterContrast.java
@@ -27,18 +27,23 @@ public class ImageFilterContrast extends SimpleImageFilter {
}
public FilterRepresentation getDefaultRepresentation() {
- FilterRepresentation representation = super.getDefaultRepresentation();
+ FilterBasicRepresentation representation =
+ (FilterBasicRepresentation) super.getDefaultRepresentation();
representation.setName("Contrast");
representation.setFilterClass(ImageFilterContrast.class);
representation.setTextId(R.string.contrast);
representation.setButtonId(R.id.contrastButton);
+
+ representation.setMinimum(-100);
+ representation.setMaximum(100);
+ representation.setDefaultValue(0);
return representation;
}
native protected void nativeApplyFilter(Bitmap bitmap, int w, int h, float strength);
@Override
- public Bitmap apply(Bitmap bitmap, float scaleFactor, boolean highQuality) {
+ public Bitmap apply(Bitmap bitmap, float scaleFactor, int quality) {
if (getParameters() == null) {
return bitmap;
}
diff --git a/src/com/android/gallery3d/filtershow/filters/ImageFilterCurves.java b/src/com/android/gallery3d/filtershow/filters/ImageFilterCurves.java
index 4b65a0016..aa4cf22e6 100644
--- a/src/com/android/gallery3d/filtershow/filters/ImageFilterCurves.java
+++ b/src/com/android/gallery3d/filtershow/filters/ImageFilterCurves.java
@@ -55,7 +55,7 @@ public class ImageFilterCurves extends ImageFilter {
}
@Override
- public Bitmap apply(Bitmap bitmap, float scaleFactor, boolean highQuality) {
+ public Bitmap apply(Bitmap bitmap, float scaleFactor, int quality) {
if (!mParameters.getSpline(Spline.RGB).isOriginal()) {
int[] rgbGradient = new int[256];
populateArray(rgbGradient, Spline.RGB);
diff --git a/src/com/android/gallery3d/filtershow/filters/ImageFilterDownsample.java b/src/com/android/gallery3d/filtershow/filters/ImageFilterDownsample.java
index a53d2f3b3..906467344 100644
--- a/src/com/android/gallery3d/filtershow/filters/ImageFilterDownsample.java
+++ b/src/com/android/gallery3d/filtershow/filters/ImageFilterDownsample.java
@@ -47,7 +47,7 @@ public class ImageFilterDownsample extends SimpleImageFilter {
}
@Override
- public Bitmap apply(Bitmap bitmap, float scaleFactor, boolean highQuality) {
+ public Bitmap apply(Bitmap bitmap, float scaleFactor, int quality) {
if (getParameters() == null) {
return bitmap;
}
@@ -79,7 +79,7 @@ public class ImageFilterDownsample extends SimpleImageFilter {
}
@Override
- public Bitmap iconApply(Bitmap bitmap, float scaleFactor, boolean highQuality) {
+ public Bitmap iconApply(Bitmap bitmap, float scaleFactor, int quality) {
int w = bitmap.getWidth();
int h = bitmap.getHeight();
Bitmap ret = Bitmap.createScaledBitmap(bitmap, w / ICON_DOWNSAMPLE_FRACTION, h
diff --git a/src/com/android/gallery3d/filtershow/filters/ImageFilterDraw.java b/src/com/android/gallery3d/filtershow/filters/ImageFilterDraw.java
index d2b5507a1..4b21d3595 100644
--- a/src/com/android/gallery3d/filtershow/filters/ImageFilterDraw.java
+++ b/src/com/android/gallery3d/filtershow/filters/ImageFilterDraw.java
@@ -27,11 +27,13 @@ import android.graphics.Path;
import android.graphics.PathMeasure;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffColorFilter;
+import android.graphics.Rect;
import android.util.Log;
import com.android.gallery3d.R;
import com.android.gallery3d.filtershow.filters.FilterDrawRepresentation.StrokeData;
import com.android.gallery3d.filtershow.imageshow.MasterImage;
+import com.android.gallery3d.filtershow.presets.ImagePreset;
import java.util.Vector;
@@ -85,7 +87,7 @@ public class ImageFilterDraw extends ImageFilter {
public static interface DrawStyle {
public void setType(byte type);
public void paint(FilterDrawRepresentation.StrokeData sd, Canvas canvas, Matrix toScrMatrix,
- boolean highQuality);
+ int quality);
}
class SimpleDraw implements DrawStyle {
@@ -98,7 +100,7 @@ public class ImageFilterDraw extends ImageFilter {
@Override
public void paint(FilterDrawRepresentation.StrokeData sd, Canvas canvas, Matrix toScrMatrix,
- boolean highQuality) {
+ int quality) {
if (sd == null) {
return;
}
@@ -139,7 +141,7 @@ public class ImageFilterDraw extends ImageFilter {
@Override
public void paint(FilterDrawRepresentation.StrokeData sd, Canvas canvas, Matrix toScrMatrix,
- boolean highQuality) {
+ int quality) {
if (sd == null || sd.mPath == null) {
return;
}
@@ -198,13 +200,13 @@ public class ImageFilterDraw extends ImageFilter {
}
void paint(FilterDrawRepresentation.StrokeData sd, Canvas canvas, Matrix toScrMatrix,
- boolean highQuality) {
- mDrawingsTypes[sd.mType].paint(sd, canvas, toScrMatrix, highQuality);
+ int quality) {
+ mDrawingsTypes[sd.mType].paint(sd, canvas, toScrMatrix, quality);
}
- public void drawData(Canvas canvas, Matrix originalRotateToScreen, boolean highQuality) {
+ public void drawData(Canvas canvas, Matrix originalRotateToScreen, int quality) {
Paint paint = new Paint();
- if (highQuality) {
+ if (quality == ImagePreset.QUALITY_FINAL) {
paint.setAntiAlias(true);
}
paint.setStyle(Style.STROKE);
@@ -214,16 +216,17 @@ public class ImageFilterDraw extends ImageFilter {
if (mParameters.getDrawing().isEmpty() && mParameters.getCurrentDrawing() == null) {
return;
}
- if (highQuality) {
+ if (quality == ImagePreset.QUALITY_FINAL) {
for (FilterDrawRepresentation.StrokeData strokeData : mParameters.getDrawing()) {
- paint(strokeData, canvas, originalRotateToScreen, highQuality);
+ paint(strokeData, canvas, originalRotateToScreen, quality);
}
return;
}
if (mOverlayBitmap == null ||
mOverlayBitmap.getWidth() != canvas.getWidth() ||
- mOverlayBitmap.getHeight() != canvas.getHeight()) {
+ mOverlayBitmap.getHeight() != canvas.getHeight() ||
+ mParameters.getDrawing().size() < mCachedStrokes) {
mOverlayBitmap = Bitmap.createBitmap(
canvas.getWidth(), canvas.getHeight(), Bitmap.Config.ARGB_8888);
@@ -237,7 +240,7 @@ public class ImageFilterDraw extends ImageFilter {
StrokeData stroke = mParameters.getCurrentDrawing();
if (stroke != null) {
- paint(stroke, canvas, originalRotateToScreen, highQuality);
+ paint(stroke, canvas, originalRotateToScreen, quality);
}
}
@@ -247,29 +250,29 @@ public class ImageFilterDraw extends ImageFilter {
int n = v.size();
for (int i = mCachedStrokes; i < n; i++) {
- paint(v.get(i), drawCache, originalRotateToScreen, false);
+ paint(v.get(i), drawCache, originalRotateToScreen, ImagePreset.QUALITY_PREVIEW);
}
mCachedStrokes = n;
}
public void draw(Canvas canvas, Matrix originalRotateToScreen) {
for (FilterDrawRepresentation.StrokeData strokeData : mParameters.getDrawing()) {
- paint(strokeData, canvas, originalRotateToScreen, false);
+ paint(strokeData, canvas, originalRotateToScreen, ImagePreset.QUALITY_PREVIEW);
}
- mDrawingsTypes[mCurrentStyle].paint(null, canvas, originalRotateToScreen, false);
+ mDrawingsTypes[mCurrentStyle].paint(
+ null, canvas, originalRotateToScreen, ImagePreset.QUALITY_PREVIEW);
}
@Override
- public Bitmap apply(Bitmap bitmap, float scaleFactor, boolean highQuality) {
+ public Bitmap apply(Bitmap bitmap, float scaleFactor, int quality) {
int w = bitmap.getWidth();
int h = bitmap.getHeight();
- short[] rect = new short[4];
-
- Matrix m = new Matrix();
- m.setScale(scaleFactor, scaleFactor);
- drawData(new Canvas(bitmap), m, highQuality);
-
-
+ ImagePreset imgPreset = getImagePreset();
+ Rect bounds = imgPreset.getImageLoader().getOriginalBounds();
+ Matrix m = imgPreset.mGeoData.getOriginalToScreen(true,
+ bounds.width(),
+ bounds.height(), w, h);
+ drawData(new Canvas(bitmap), m, quality);
return bitmap;
}
diff --git a/src/com/android/gallery3d/filtershow/filters/ImageFilterEdge.java b/src/com/android/gallery3d/filtershow/filters/ImageFilterEdge.java
index 96839e4ab..55c709573 100644
--- a/src/com/android/gallery3d/filtershow/filters/ImageFilterEdge.java
+++ b/src/com/android/gallery3d/filtershow/filters/ImageFilterEdge.java
@@ -38,7 +38,7 @@ public class ImageFilterEdge extends SimpleImageFilter {
native protected void nativeApplyFilter(Bitmap bitmap, int w, int h, float p);
@Override
- public Bitmap apply(Bitmap bitmap, float scaleFactor, boolean highQuality) {
+ public Bitmap apply(Bitmap bitmap, float scaleFactor, int quality) {
if (getParameters() == null) {
return bitmap;
}
diff --git a/src/com/android/gallery3d/filtershow/filters/ImageFilterExposure.java b/src/com/android/gallery3d/filtershow/filters/ImageFilterExposure.java
index e36f096ad..7a8df71af 100644
--- a/src/com/android/gallery3d/filtershow/filters/ImageFilterExposure.java
+++ b/src/com/android/gallery3d/filtershow/filters/ImageFilterExposure.java
@@ -27,18 +27,22 @@ public class ImageFilterExposure extends SimpleImageFilter {
}
public FilterRepresentation getDefaultRepresentation() {
- FilterRepresentation representation = super.getDefaultRepresentation();
+ FilterBasicRepresentation representation =
+ (FilterBasicRepresentation) super.getDefaultRepresentation();
representation.setName("Exposure");
representation.setFilterClass(ImageFilterExposure.class);
representation.setTextId(R.string.exposure);
representation.setButtonId(R.id.exposureButton);
+ representation.setMinimum(-100);
+ representation.setMaximum(100);
+ representation.setDefaultValue(0);
return representation;
}
native protected void nativeApplyFilter(Bitmap bitmap, int w, int h, float bright);
@Override
- public Bitmap apply(Bitmap bitmap, float scaleFactor, boolean highQuality) {
+ public Bitmap apply(Bitmap bitmap, float scaleFactor, int quality) {
if (getParameters() == null) {
return bitmap;
}
diff --git a/src/com/android/gallery3d/filtershow/filters/ImageFilterFx.java b/src/com/android/gallery3d/filtershow/filters/ImageFilterFx.java
index 0a3c8abd0..820ec3e51 100644
--- a/src/com/android/gallery3d/filtershow/filters/ImageFilterFx.java
+++ b/src/com/android/gallery3d/filtershow/filters/ImageFilterFx.java
@@ -40,7 +40,7 @@ public class ImageFilterFx extends ImageFilter {
native protected void nativeApplyFilter(Bitmap bitmap, int w, int h,Bitmap fxBitmap, int fxw, int fxh);
@Override
- public Bitmap apply(Bitmap bitmap, float scaleFactor, boolean highQuality) {
+ public Bitmap apply(Bitmap bitmap, float scaleFactor, int quality) {
if (getParameters() == null || getParameters().getFxBitmap() ==null) {
return bitmap;
}
diff --git a/src/com/android/gallery3d/filtershow/filters/ImageFilterGeometry.java b/src/com/android/gallery3d/filtershow/filters/ImageFilterGeometry.java
index a778bee21..329ca81b9 100644
--- a/src/com/android/gallery3d/filtershow/filters/ImageFilterGeometry.java
+++ b/src/com/android/gallery3d/filtershow/filters/ImageFilterGeometry.java
@@ -67,7 +67,12 @@ public class ImageFilterGeometry extends ImageFilter {
Bitmap dst, int dstWidth, int dstHeight, float straightenAngle);
@Override
- public Bitmap apply(Bitmap bitmap, float scaleFactor, boolean highQuality) {
+ public void useRepresentation(FilterRepresentation representation) {
+
+ }
+
+ @Override
+ public Bitmap apply(Bitmap bitmap, float scaleFactor, int quality) {
// TODO: implement bilinear or bicubic here... for now, just use
// canvas to do a simple implementation...
// TODO: and be more memory efficient! (do it in native?)
diff --git a/src/com/android/gallery3d/filtershow/filters/ImageFilterHue.java b/src/com/android/gallery3d/filtershow/filters/ImageFilterHue.java
index ed28e57b7..8c484c72e 100644
--- a/src/com/android/gallery3d/filtershow/filters/ImageFilterHue.java
+++ b/src/com/android/gallery3d/filtershow/filters/ImageFilterHue.java
@@ -30,7 +30,8 @@ public class ImageFilterHue extends SimpleImageFilter {
}
public FilterRepresentation getDefaultRepresentation() {
- FilterBasicRepresentation representation = (FilterBasicRepresentation) super.getDefaultRepresentation();
+ FilterBasicRepresentation representation =
+ (FilterBasicRepresentation) super.getDefaultRepresentation();
representation.setName("Hue");
representation.setFilterClass(ImageFilterHue.class);
representation.setMinimum(-180);
@@ -44,7 +45,7 @@ public class ImageFilterHue extends SimpleImageFilter {
native protected void nativeApplyFilter(Bitmap bitmap, int w, int h, float []matrix);
@Override
- public Bitmap apply(Bitmap bitmap, float scaleFactor, boolean highQuality) {
+ public Bitmap apply(Bitmap bitmap, float scaleFactor, int quality) {
if (getParameters() == null) {
return bitmap;
}
diff --git a/src/com/android/gallery3d/filtershow/filters/ImageFilterKMeans.java b/src/com/android/gallery3d/filtershow/filters/ImageFilterKMeans.java
index f28839744..f48bd047a 100644
--- a/src/com/android/gallery3d/filtershow/filters/ImageFilterKMeans.java
+++ b/src/com/android/gallery3d/filtershow/filters/ImageFilterKMeans.java
@@ -53,7 +53,7 @@ public class ImageFilterKMeans extends SimpleImageFilter {
int swidth, int sheight, int p, int seed);
@Override
- public Bitmap apply(Bitmap bitmap, float scaleFactor, boolean highQuality) {
+ public Bitmap apply(Bitmap bitmap, float scaleFactor, int quality) {
if (getParameters() == null) {
return bitmap;
}
diff --git a/src/com/android/gallery3d/filtershow/filters/ImageFilterNegative.java b/src/com/android/gallery3d/filtershow/filters/ImageFilterNegative.java
index 14307c37d..841c5c913 100644
--- a/src/com/android/gallery3d/filtershow/filters/ImageFilterNegative.java
+++ b/src/com/android/gallery3d/filtershow/filters/ImageFilterNegative.java
@@ -3,6 +3,7 @@ package com.android.gallery3d.filtershow.filters;
import android.graphics.Bitmap;
import com.android.gallery3d.R;
+import com.android.gallery3d.filtershow.editors.ImageOnlyEditor;
public class ImageFilterNegative extends ImageFilter {
@@ -17,13 +18,19 @@ public class ImageFilterNegative extends ImageFilter {
representation.setButtonId(R.id.negativeButton);
representation.setShowEditingControls(false);
representation.setShowParameterValue(false);
+ representation.setEditorId(ImageOnlyEditor.ID);
return representation;
}
native protected void nativeApplyFilter(Bitmap bitmap, int w, int h);
@Override
- public Bitmap apply(Bitmap bitmap, float scaleFactor, boolean highQuality) {
+ public void useRepresentation(FilterRepresentation representation) {
+
+ }
+
+ @Override
+ public Bitmap apply(Bitmap bitmap, float scaleFactor, int quality) {
int w = bitmap.getWidth();
int h = bitmap.getHeight();
nativeApplyFilter(bitmap, w, h);
diff --git a/src/com/android/gallery3d/filtershow/filters/ImageFilterParametricBorder.java b/src/com/android/gallery3d/filtershow/filters/ImageFilterParametricBorder.java
index 36c86d847..316a286e8 100644
--- a/src/com/android/gallery3d/filtershow/filters/ImageFilterParametricBorder.java
+++ b/src/com/android/gallery3d/filtershow/filters/ImageFilterParametricBorder.java
@@ -63,14 +63,14 @@ public class ImageFilterParametricBorder extends ImageFilter {
}
@Override
- public Bitmap apply(Bitmap bitmap, float scaleFactor, boolean highQuality) {
+ public Bitmap apply(Bitmap bitmap, float scaleFactor, int quality) {
Canvas canvas = new Canvas(bitmap);
applyHelper(canvas, bitmap.getWidth(), bitmap.getHeight());
return bitmap;
}
@Override
- public Bitmap iconApply(Bitmap bitmap, float scaleFactor, boolean highQuality) {
+ public Bitmap iconApply(Bitmap bitmap, float scaleFactor, int quality) {
Canvas canvas = new Canvas(bitmap);
applyHelper(canvas, bitmap.getWidth() * 4, bitmap.getHeight() * 4);
return bitmap;
diff --git a/src/com/android/gallery3d/filtershow/filters/ImageFilterRS.java b/src/com/android/gallery3d/filtershow/filters/ImageFilterRS.java
index 79c783a94..d5297904d 100644
--- a/src/com/android/gallery3d/filtershow/filters/ImageFilterRS.java
+++ b/src/com/android/gallery3d/filtershow/filters/ImageFilterRS.java
@@ -21,7 +21,7 @@ import android.graphics.Bitmap;
import android.support.v8.renderscript.*;
import android.util.Log;
-public class ImageFilterRS extends ImageFilter {
+public abstract class ImageFilterRS extends ImageFilter {
private final String LOGTAG = "ImageFilterRS";
private static RenderScript mRS = null;
@@ -33,7 +33,11 @@ public class ImageFilterRS extends ImageFilter {
private final Bitmap.Config mBitmapConfig = Bitmap.Config.ARGB_8888;
- public void prepare(Bitmap bitmap, float scaleFactor, boolean highQuality) {
+ public void resetBitmap() {
+ mOldBitmap = null;
+ }
+
+ public void prepare(Bitmap bitmap, float scaleFactor, int quality) {
if (sOldBitmap == null
|| (bitmap.getWidth() != sOldBitmap.getWidth())
|| (bitmap.getHeight() != sOldBitmap.getHeight())) {
@@ -52,13 +56,13 @@ public class ImageFilterRS extends ImageFilter {
}
mInPixelsAllocation.copyFrom(bitmap);
if (mOldBitmap != sOldBitmap) {
- createFilter(mResources, scaleFactor, highQuality);
+ createFilter(mResources, scaleFactor, quality);
mOldBitmap = sOldBitmap;
}
}
public void createFilter(android.content.res.Resources res,
- float scaleFactor, boolean highQuality) {
+ float scaleFactor, int quality) {
// Stub
}
@@ -71,12 +75,12 @@ public class ImageFilterRS extends ImageFilter {
}
@Override
- public Bitmap apply(Bitmap bitmap, float scaleFactor, boolean highQuality) {
+ public Bitmap apply(Bitmap bitmap, float scaleFactor, int quality) {
if (bitmap == null) {
return bitmap;
}
try {
- prepare(bitmap, scaleFactor, highQuality);
+ prepare(bitmap, scaleFactor, quality);
runFilter();
update(bitmap);
} catch (android.renderscript.RSIllegalArgumentException e) {
diff --git a/src/com/android/gallery3d/filtershow/filters/ImageFilterRedEye.java b/src/com/android/gallery3d/filtershow/filters/ImageFilterRedEye.java
index 177def7b7..42587c06f 100644
--- a/src/com/android/gallery3d/filtershow/filters/ImageFilterRedEye.java
+++ b/src/com/android/gallery3d/filtershow/filters/ImageFilterRedEye.java
@@ -17,8 +17,12 @@
package com.android.gallery3d.filtershow.filters;
import android.graphics.Bitmap;
+import android.graphics.Canvas;
import android.graphics.Matrix;
+import android.graphics.Paint;
+import android.graphics.Rect;
import android.graphics.RectF;
+import android.util.Log;
import com.android.gallery3d.filtershow.imageshow.GeometryMetadata;
@@ -34,9 +38,7 @@ public class ImageFilterRedEye extends ImageFilter {
@Override
public FilterRepresentation getDefaultRepresentation() {
- FilterRedEyeRepresentation representation = new FilterRedEyeRepresentation();
-
- return representation;
+ return new FilterRedEyeRepresentation();
}
public boolean isNil() {
@@ -63,12 +65,17 @@ public class ImageFilterRedEye extends ImageFilter {
native protected void nativeApplyFilter(Bitmap bitmap, int w, int h, short[] matrix);
@Override
- public Bitmap apply(Bitmap bitmap, float scaleFactor, boolean highQuality) {
+ public void useRepresentation(FilterRepresentation representation) {
+ FilterRedEyeRepresentation parameters = (FilterRedEyeRepresentation) representation;
+ mParameters = parameters;
+ }
+
+ @Override
+ public Bitmap apply(Bitmap bitmap, float scaleFactor, int quality) {
int w = bitmap.getWidth();
int h = bitmap.getHeight();
short[] rect = new short[4];
int size = mParameters.getNumberOfCandidates();
-
for (int i = 0; i < size; i++) {
RectF r = new RectF(mParameters.getCandidate(i).mRect);
GeometryMetadata geo = getImagePreset().mGeoData;
@@ -101,13 +108,14 @@ public class ImageFilterRedEye extends ImageFilter {
if (r.bottom > h) {
r.bottom = h;
}
+
rect[0] = (short) r.left;
rect[1] = (short) r.top;
rect[2] = (short) r.width();
rect[3] = (short) r.height();
+
nativeApplyFilter(bitmap, w, h, rect);
}
-
return bitmap;
}
}
diff --git a/src/com/android/gallery3d/filtershow/filters/ImageFilterSaturated.java b/src/com/android/gallery3d/filtershow/filters/ImageFilterSaturated.java
index 747a03685..6cd833206 100644
--- a/src/com/android/gallery3d/filtershow/filters/ImageFilterSaturated.java
+++ b/src/com/android/gallery3d/filtershow/filters/ImageFilterSaturated.java
@@ -26,19 +26,24 @@ public class ImageFilterSaturated extends SimpleImageFilter {
mName = "Saturated";
}
+ @Override
public FilterRepresentation getDefaultRepresentation() {
- FilterRepresentation representation = super.getDefaultRepresentation();
+ FilterBasicRepresentation representation =
+ (FilterBasicRepresentation) super.getDefaultRepresentation();
representation.setName("Saturated");
representation.setFilterClass(ImageFilterSaturated.class);
representation.setTextId(R.string.saturation);
representation.setButtonId(R.id.saturationButton);
+ representation.setMinimum(-100);
+ representation.setMaximum(100);
+ representation.setDefaultValue(0);
return representation;
}
native protected void nativeApplyFilter(Bitmap bitmap, int w, int h, float saturation);
@Override
- public Bitmap apply(Bitmap bitmap, float scaleFactor, boolean highQuality) {
+ public Bitmap apply(Bitmap bitmap, float scaleFactor, int quality) {
if (getParameters() == null) {
return bitmap;
}
diff --git a/src/com/android/gallery3d/filtershow/filters/ImageFilterShadows.java b/src/com/android/gallery3d/filtershow/filters/ImageFilterShadows.java
index a2560b99e..e17823955 100644
--- a/src/com/android/gallery3d/filtershow/filters/ImageFilterShadows.java
+++ b/src/com/android/gallery3d/filtershow/filters/ImageFilterShadows.java
@@ -28,18 +28,22 @@ public class ImageFilterShadows extends SimpleImageFilter {
}
public FilterRepresentation getDefaultRepresentation() {
- FilterRepresentation representation = super.getDefaultRepresentation();
+ FilterBasicRepresentation representation =
+ (FilterBasicRepresentation) super.getDefaultRepresentation();
representation.setName("Shadows");
representation.setFilterClass(ImageFilterShadows.class);
representation.setTextId(R.string.shadow_recovery);
representation.setButtonId(R.id.shadowRecoveryButton);
+ representation.setMinimum(-100);
+ representation.setMaximum(100);
+ representation.setDefaultValue(0);
return representation;
}
native protected void nativeApplyFilter(Bitmap bitmap, int w, int h, float factor);
@Override
- public Bitmap apply(Bitmap bitmap, float scaleFactor, boolean highQuality) {
+ public Bitmap apply(Bitmap bitmap, float scaleFactor, int quality) {
if (getParameters() == null) {
return bitmap;
}
diff --git a/src/com/android/gallery3d/filtershow/filters/ImageFilterSharpen.java b/src/com/android/gallery3d/filtershow/filters/ImageFilterSharpen.java
index 92f9b1a6d..9c99d57d0 100644
--- a/src/com/android/gallery3d/filtershow/filters/ImageFilterSharpen.java
+++ b/src/com/android/gallery3d/filtershow/filters/ImageFilterSharpen.java
@@ -48,7 +48,7 @@ public class ImageFilterSharpen extends ImageFilterRS {
@Override
public void createFilter(android.content.res.Resources res, float scaleFactor,
- boolean highQuality) {
+ int quality) {
int w = mInPixelsAllocation.getType().getX();
int h = mInPixelsAllocation.getType().getY();
mScaleFactor = scaleFactor;
diff --git a/src/com/android/gallery3d/filtershow/filters/ImageFilterStraighten.java b/src/com/android/gallery3d/filtershow/filters/ImageFilterStraighten.java
index 3feec7bcc..a3bb6f980 100644
--- a/src/com/android/gallery3d/filtershow/filters/ImageFilterStraighten.java
+++ b/src/com/android/gallery3d/filtershow/filters/ImageFilterStraighten.java
@@ -53,7 +53,12 @@ public class ImageFilterStraighten extends ImageFilter {
}
@Override
- public Bitmap apply(Bitmap bitmap, float scaleFactor, boolean highQuality) {
+ public void useRepresentation(FilterRepresentation representation) {
+
+ }
+
+ @Override
+ public Bitmap apply(Bitmap bitmap, float scaleFactor, int quality) {
// TODO: implement bilinear or bicubic here... for now, just use
// canvas to do a simple implementation...
// TODO: and be more memory efficient! (do it in native?)
diff --git a/src/com/android/gallery3d/filtershow/filters/ImageFilterTinyPlanet.java b/src/com/android/gallery3d/filtershow/filters/ImageFilterTinyPlanet.java
index d8ec3900e..702cc664c 100644
--- a/src/com/android/gallery3d/filtershow/filters/ImageFilterTinyPlanet.java
+++ b/src/com/android/gallery3d/filtershow/filters/ImageFilterTinyPlanet.java
@@ -72,7 +72,7 @@ public class ImageFilterTinyPlanet extends SimpleImageFilter {
float angle);
@Override
- public Bitmap apply(Bitmap bitmapIn, float scaleFactor, boolean highQuality) {
+ public Bitmap apply(Bitmap bitmapIn, float scaleFactor, int quality) {
int w = bitmapIn.getWidth();
int h = bitmapIn.getHeight();
int outputSize = (int) (w / 2f);
diff --git a/src/com/android/gallery3d/filtershow/filters/ImageFilterVibrance.java b/src/com/android/gallery3d/filtershow/filters/ImageFilterVibrance.java
index 385921168..a57af71df 100644
--- a/src/com/android/gallery3d/filtershow/filters/ImageFilterVibrance.java
+++ b/src/com/android/gallery3d/filtershow/filters/ImageFilterVibrance.java
@@ -27,18 +27,22 @@ public class ImageFilterVibrance extends SimpleImageFilter {
}
public FilterRepresentation getDefaultRepresentation() {
- FilterRepresentation representation = super.getDefaultRepresentation();
+ FilterBasicRepresentation representation =
+ (FilterBasicRepresentation) super.getDefaultRepresentation();
representation.setName("Vibrance");
representation.setFilterClass(ImageFilterVibrance.class);
representation.setTextId(R.string.vibrance);
representation.setButtonId(R.id.vibranceButton);
+ representation.setMinimum(-100);
+ representation.setMaximum(100);
+ representation.setDefaultValue(0);
return representation;
}
native protected void nativeApplyFilter(Bitmap bitmap, int w, int h, float bright);
@Override
- public Bitmap apply(Bitmap bitmap, float scaleFactor, boolean highQuality) {
+ public Bitmap apply(Bitmap bitmap, float scaleFactor, int quality) {
if (getParameters() == null) {
return bitmap;
}
diff --git a/src/com/android/gallery3d/filtershow/filters/ImageFilterVignette.java b/src/com/android/gallery3d/filtershow/filters/ImageFilterVignette.java
index 3aad6bd15..465d90bfd 100644
--- a/src/com/android/gallery3d/filtershow/filters/ImageFilterVignette.java
+++ b/src/com/android/gallery3d/filtershow/filters/ImageFilterVignette.java
@@ -30,19 +30,25 @@ public class ImageFilterVignette extends SimpleImageFilter {
}
public FilterRepresentation getDefaultRepresentation() {
- FilterBasicRepresentation representation = (FilterBasicRepresentation) super.getDefaultRepresentation();
+ FilterBasicRepresentation representation =
+ (FilterBasicRepresentation) super.getDefaultRepresentation();
representation.setName("Vignette");
representation.setFilterClass(ImageFilterVignette.class);
representation.setPriority(FilterRepresentation.TYPE_VIGNETTE);
representation.setTextId(R.string.vignette);
representation.setButtonId(R.id.vignetteButton);
+
+ representation.setMinimum(-100);
+ representation.setMaximum(100);
+ representation.setDefaultValue(0);
+
return representation;
}
native protected void nativeApplyFilter(Bitmap bitmap, int w, int h, float strength);
@Override
- public Bitmap apply(Bitmap bitmap, float scaleFactor, boolean highQuality) {
+ public Bitmap apply(Bitmap bitmap, float scaleFactor, int quality) {
if (getParameters() == null) {
return bitmap;
}
diff --git a/src/com/android/gallery3d/filtershow/filters/ImageFilterWBalance.java b/src/com/android/gallery3d/filtershow/filters/ImageFilterWBalance.java
index 28223b28d..2f4852306 100644
--- a/src/com/android/gallery3d/filtershow/filters/ImageFilterWBalance.java
+++ b/src/com/android/gallery3d/filtershow/filters/ImageFilterWBalance.java
@@ -17,6 +17,7 @@
package com.android.gallery3d.filtershow.filters;
import com.android.gallery3d.R;
+import com.android.gallery3d.filtershow.editors.ImageOnlyEditor;
import android.graphics.Bitmap;
@@ -30,17 +31,24 @@ public class ImageFilterWBalance extends ImageFilter {
public FilterRepresentation getDefaultRepresentation() {
FilterRepresentation representation = new FilterDirectRepresentation("WBalance");
representation.setFilterClass(ImageFilterWBalance.class);
- representation.setFilterType(FilterRepresentation.TYPE_WBALANCE);
+ representation.setPriority(FilterRepresentation.TYPE_WBALANCE);
representation.setTextId(R.string.wbalance);
representation.setButtonId(R.id.wbalanceButton);
representation.setShowEditingControls(false);
+ representation.setShowParameterValue(false);
+ representation.setEditorId(ImageOnlyEditor.ID);
return representation;
}
+ @Override
+ public void useRepresentation(FilterRepresentation representation) {
+
+ }
+
native protected void nativeApplyFilter(Bitmap bitmap, int w, int h, int locX, int locY);
@Override
- public Bitmap apply(Bitmap bitmap, float scaleFactor, boolean highQuality) {
+ public Bitmap apply(Bitmap bitmap, float scaleFactor, int quality) {
int w = bitmap.getWidth();
int h = bitmap.getHeight();
nativeApplyFilter(bitmap, w, h, -1, -1);
diff --git a/src/com/android/gallery3d/filtershow/filters/SimpleImageFilter.java b/src/com/android/gallery3d/filtershow/filters/SimpleImageFilter.java
index d494913cf..922a16a0f 100644
--- a/src/com/android/gallery3d/filtershow/filters/SimpleImageFilter.java
+++ b/src/com/android/gallery3d/filtershow/filters/SimpleImageFilter.java
@@ -38,9 +38,9 @@ public class SimpleImageFilter extends ImageFilter {
}
@Override
- public Bitmap iconApply(Bitmap bitmap, float scaleFactor, boolean highQuality) {
+ public Bitmap iconApply(Bitmap bitmap, float scaleFactor, int quality) {
FilterRepresentation representation = getDefaultRepresentation();
this.useRepresentation(representation);
- return apply(bitmap, scaleFactor, highQuality);
+ return apply(bitmap, scaleFactor, quality);
}
}
diff --git a/src/com/android/gallery3d/filtershow/imageshow/GeometryListener.java b/src/com/android/gallery3d/filtershow/imageshow/GeometryListener.java
new file mode 100644
index 000000000..549c2e7a5
--- /dev/null
+++ b/src/com/android/gallery3d/filtershow/imageshow/GeometryListener.java
@@ -0,0 +1,21 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.gallery3d.filtershow.imageshow;
+
+public interface GeometryListener {
+ public void geometryChanged();
+}
diff --git a/src/com/android/gallery3d/filtershow/imageshow/GeometryMetadata.java b/src/com/android/gallery3d/filtershow/imageshow/GeometryMetadata.java
index b53284061..a3645d6f5 100644
--- a/src/com/android/gallery3d/filtershow/imageshow/GeometryMetadata.java
+++ b/src/com/android/gallery3d/filtershow/imageshow/GeometryMetadata.java
@@ -86,12 +86,12 @@ public class GeometryMetadata {
return false;
}
- public Bitmap apply(Bitmap original, float scaleFactor, boolean highQuality) {
+ public Bitmap apply(Bitmap original, float scaleFactor, int quality) {
if (!hasModifications()) {
return original;
}
mImageFilter.setGeometryMetadata(this);
- Bitmap m = mImageFilter.apply(original, scaleFactor, highQuality);
+ Bitmap m = mImageFilter.apply(original, scaleFactor, quality);
return m;
}
diff --git a/src/com/android/gallery3d/filtershow/imageshow/ImageDraw.java b/src/com/android/gallery3d/filtershow/imageshow/ImageDraw.java
index 2dc0221e4..0cd229968 100644
--- a/src/com/android/gallery3d/filtershow/imageshow/ImageDraw.java
+++ b/src/com/android/gallery3d/filtershow/imageshow/ImageDraw.java
@@ -5,8 +5,6 @@ import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Matrix;
-import android.graphics.Rect;
-import android.graphics.RectF;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.util.Log;
@@ -91,7 +89,6 @@ public class ImageDraw extends ImageShow {
ImageFilterDraw filter = (ImageFilterDraw) getCurrentFilter();
if (event.getAction() == MotionEvent.ACTION_DOWN) {
-
mTmpPoint[0] = event.getX();
mTmpPoint[1] = event.getY();
mToOrig.mapPoints(mTmpPoint);
@@ -116,8 +113,6 @@ public class ImageDraw extends ImageShow {
mTmpPoint[1] = event.getY();
mToOrig.mapPoints(mTmpPoint);
mFRep.endSection(mTmpPoint[0], mTmpPoint[1]);
- this.resetImageCaches(this);
-
}
mEditorDraw.commitLocalRepresentation();
invalidate();
diff --git a/src/com/android/gallery3d/filtershow/imageshow/ImageRedEye.java b/src/com/android/gallery3d/filtershow/imageshow/ImageRedEye.java
index 2db9227b9..ba3dcdd1d 100644
--- a/src/com/android/gallery3d/filtershow/imageshow/ImageRedEye.java
+++ b/src/com/android/gallery3d/filtershow/imageshow/ImageRedEye.java
@@ -9,6 +9,7 @@ import android.graphics.Paint;
import android.graphics.Paint.Style;
import android.graphics.RectF;
import android.util.AttributeSet;
+import android.util.Log;
import android.view.MotionEvent;
import com.android.gallery3d.filtershow.editors.EditorRedEye;
@@ -119,7 +120,6 @@ public class ImageRedEye extends ImageShow {
Matrix originalRotateToScreen = geo.getOriginalToScreen(true,
mImageLoader.getOriginalBounds().width(),
mImageLoader.getOriginalBounds().height(), getWidth(), getHeight());
-
if (mRedEyeRep != null) {
for (RedEyeCandidate candidate : mRedEyeRep.getCandidates()) {
RectF rect = candidate.getRect();
diff --git a/src/com/android/gallery3d/filtershow/imageshow/MasterImage.java b/src/com/android/gallery3d/filtershow/imageshow/MasterImage.java
index 1e830b04b..3172c79dc 100644
--- a/src/com/android/gallery3d/filtershow/imageshow/MasterImage.java
+++ b/src/com/android/gallery3d/filtershow/imageshow/MasterImage.java
@@ -19,7 +19,6 @@ package com.android.gallery3d.filtershow.imageshow;
import android.graphics.Bitmap;
import android.graphics.RectF;
-import com.android.gallery3d.app.Log;
import com.android.gallery3d.filtershow.FilterShowActivity;
import com.android.gallery3d.filtershow.HistoryAdapter;
import com.android.gallery3d.filtershow.ImageStateAdapter;
@@ -54,6 +53,9 @@ public class MasterImage implements RenderingRequestCaller {
private Vector<ImageShow> mObservers = new Vector<ImageShow>();
private FilterRepresentation mCurrentFilterRepresentation;
+ private Vector<GeometryListener> mGeometryListeners = new Vector<GeometryListener>();
+
+ private GeometryMetadata mPreviousGeometry = null;
private MasterImage() {
}
@@ -101,6 +103,11 @@ public class MasterImage implements RenderingRequestCaller {
mHistory.addHistoryItem(mPreset);
}
updatePresets(true);
+ GeometryMetadata geo = mPreset.mGeoData;
+ if (!geo.equals(mPreviousGeometry)) {
+ notifyGeometryChange();
+ }
+ mPreviousGeometry = new GeometryMetadata(geo);
}
private void setGeometry() {
@@ -246,4 +253,14 @@ public class MasterImage implements RenderingRequestCaller {
public static void reset() {
sMasterImage = null;
}
+
+ public void addGeometryListener(GeometryListener listener) {
+ mGeometryListeners.add(listener);
+ }
+
+ public void notifyGeometryChange() {
+ for (GeometryListener listener : mGeometryListeners) {
+ listener.geometryChanged();
+ }
+ }
}
diff --git a/src/com/android/gallery3d/filtershow/presets/ImagePreset.java b/src/com/android/gallery3d/filtershow/presets/ImagePreset.java
index c7d14e80b..84266c55d 100644
--- a/src/com/android/gallery3d/filtershow/presets/ImagePreset.java
+++ b/src/com/android/gallery3d/filtershow/presets/ImagePreset.java
@@ -21,6 +21,7 @@ import android.util.Log;
import com.android.gallery3d.filtershow.ImageStateAdapter;
import com.android.gallery3d.filtershow.cache.ImageLoader;
+import com.android.gallery3d.filtershow.filters.BaseFiltersManager;
import com.android.gallery3d.filtershow.filters.FilterRepresentation;
import com.android.gallery3d.filtershow.filters.FiltersManager;
import com.android.gallery3d.filtershow.filters.ImageFilter;
@@ -35,7 +36,10 @@ public class ImagePreset {
private FilterRepresentation mBorder = null;
private float mScaleFactor = 1.0f;
- private boolean mIsHighQuality = false;
+ public static final int QUALITY_ICON = 0;
+ public static final int QUALITY_PREVIEW = 1;
+ public static final int QUALITY_FINAL = 2;
+ private int mQuality = QUALITY_PREVIEW;
private ImageLoader mImageLoader = null;
private Vector<FilterRepresentation> mFilters = new Vector<FilterRepresentation>();
@@ -72,7 +76,6 @@ public class ImagePreset {
}
for (int i = 0; i < source.mFilters.size(); i++) {
FilterRepresentation representation = source.mFilters.elementAt(i).clone();
- representation.setImagePreset(this);
addFilter(representation);
}
} catch (java.lang.CloneNotSupportedException e) {
@@ -127,7 +130,7 @@ public class ImagePreset {
synchronized (mFilters) {
int position = getPositionForRepresentation(representation);
FilterRepresentation old = mFilters.elementAt(position);
- old.useParametersFrom(representation);
+ old.updateTempParametersFrom(representation);
}
MasterImage.getImage().invalidatePreview();
}
@@ -351,7 +354,6 @@ public class ImagePreset {
mFilters.add(representation);
setHistoryName(representation.getName());
}
- representation.setImagePreset(this);
}
public FilterRepresentation getRepresentation(FilterRepresentation filterRepresentation) {
@@ -380,14 +382,16 @@ public class ImagePreset {
public Bitmap applyGeometry(Bitmap bitmap) {
// Apply any transform -- 90 rotate, flip, straighten, crop
// Returns a new bitmap.
- return mGeoData.apply(bitmap, mScaleFactor, mIsHighQuality);
+ return mGeoData.apply(bitmap, mScaleFactor, mQuality);
}
public Bitmap applyBorder(Bitmap bitmap) {
if (mBorder != null && mDoApplyGeometry) {
ImageFilter filter = FiltersManager.getManager().getFilterForRepresentation(mBorder);
+ mBorder.synchronizeRepresentation();
filter.useRepresentation(mBorder);
- bitmap = filter.apply(bitmap, mScaleFactor, mIsHighQuality);
+ filter.setImagePreset(this);
+ bitmap = filter.apply(bitmap, mScaleFactor, mQuality);
}
return bitmap;
}
@@ -405,10 +409,12 @@ public class ImagePreset {
FilterRepresentation representation = null;
synchronized (mFilters) {
representation = mFilters.elementAt(i);
+ representation.synchronizeRepresentation();
}
ImageFilter filter = FiltersManager.getManager().getFilterForRepresentation(representation);
filter.useRepresentation(representation);
- bitmap = filter.apply(bitmap, mScaleFactor, mIsHighQuality);
+ filter.setImagePreset(this);
+ bitmap = filter.apply(bitmap, mScaleFactor, mQuality);
}
}
@@ -421,7 +427,7 @@ public class ImagePreset {
}
imageStateAdapter.clear();
// TODO: re-enable the state panel
- // imageStateAdapter.addAll(mFilters);
+ imageStateAdapter.addAll(mFilters);
imageStateAdapter.notifyDataSetChanged();
}
@@ -429,12 +435,12 @@ public class ImagePreset {
return mScaleFactor;
}
- public boolean isHighQuality() {
- return mIsHighQuality;
+ public int getQuality() {
+ return mQuality;
}
- public void setIsHighQuality(boolean value) {
- mIsHighQuality = value;
+ public void setQuality(int value) {
+ mQuality = value;
}
public void setScaleFactor(float value) {
diff --git a/src/com/android/gallery3d/filtershow/tools/SaveCopyTask.java b/src/com/android/gallery3d/filtershow/tools/SaveCopyTask.java
index 38a9a3a2f..e378fe2b7 100644
--- a/src/com/android/gallery3d/filtershow/tools/SaveCopyTask.java
+++ b/src/com/android/gallery3d/filtershow/tools/SaveCopyTask.java
@@ -168,7 +168,7 @@ public class SaveCopyTask extends AsyncTask<ImagePreset, Void, Uri> {
@Override
protected Uri doInBackground(ImagePreset... params) {
// TODO: Support larger dimensions for photo saving.
- if (params[0] == null) {
+ if (params[0] == null || sourceUri == null) {
return null;
}
ImagePreset preset = params[0];
diff --git a/src/com/android/gallery3d/filtershow/ui/FilterIconButton.java b/src/com/android/gallery3d/filtershow/ui/FilterIconButton.java
index 19807e6af..de2e1e5dc 100644
--- a/src/com/android/gallery3d/filtershow/ui/FilterIconButton.java
+++ b/src/com/android/gallery3d/filtershow/ui/FilterIconButton.java
@@ -24,20 +24,17 @@ import android.util.AttributeSet;
import android.view.View;
import android.widget.LinearLayout;
-import com.android.gallery3d.app.Log;
-import com.android.gallery3d.filtershow.FilterShowActivity;
import com.android.gallery3d.filtershow.PanelController;
-import com.android.gallery3d.filtershow.cache.FilteringPipeline;
import com.android.gallery3d.filtershow.cache.ImageLoader;
import com.android.gallery3d.filtershow.cache.RenderingRequest;
import com.android.gallery3d.filtershow.cache.RenderingRequestCaller;
import com.android.gallery3d.filtershow.filters.FilterRepresentation;
-import com.android.gallery3d.filtershow.filters.FiltersManager;
-import com.android.gallery3d.filtershow.filters.ImageFilter;
+import com.android.gallery3d.filtershow.imageshow.GeometryListener;
import com.android.gallery3d.filtershow.imageshow.MasterImage;
import com.android.gallery3d.filtershow.presets.ImagePreset;
-public class FilterIconButton extends IconButton implements View.OnClickListener, RenderingRequestCaller {
+public class FilterIconButton extends IconButton implements View.OnClickListener,
+ RenderingRequestCaller, GeometryListener {
private static final String LOGTAG = "FilterIconButton";
private Bitmap mOverlayBitmap = null;
private PanelController mController = null;
@@ -65,6 +62,7 @@ public class FilterIconButton extends IconButton implements View.OnClickListener
setText(text);
mParentContainer = parent;
super.setOnClickListener(this);
+ MasterImage.getImage().addGeometryListener(this);
invalidate();
}
@@ -73,6 +71,8 @@ public class FilterIconButton extends IconButton implements View.OnClickListener
if (mIconBitmap == null && mPreset == null) {
ImageLoader loader = MasterImage.getImage().getLoader();
if (loader != null) {
+ ImagePreset geoPreset = new ImagePreset(MasterImage.getImage().getGeometryPreset());
+ image = geoPreset.applyGeometry(image);
dst = super.drawImage(dst, image, destination);
ImagePreset mPreset = new ImagePreset();
mPreset.addFilter(mFilterRepresentation);
@@ -127,4 +127,12 @@ public class FilterIconButton extends IconButton implements View.OnClickListener
invalidate();
stale_icon = true;
}
+
+ @Override
+ public void geometryChanged() {
+ stale_icon = true;
+ mIconBitmap = null;
+ mPreset = null;
+ invalidate();
+ }
}
diff --git a/src/com/android/gallery3d/filtershow/ui/ImageCurves.java b/src/com/android/gallery3d/filtershow/ui/ImageCurves.java
index ec2df6c08..f581fc733 100644
--- a/src/com/android/gallery3d/filtershow/ui/ImageCurves.java
+++ b/src/com/android/gallery3d/filtershow/ui/ImageCurves.java
@@ -26,7 +26,6 @@ import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.os.AsyncTask;
import android.util.AttributeSet;
-import android.util.Log;
import android.view.LayoutInflater;
import android.view.MenuItem;
import android.view.MotionEvent;
@@ -36,6 +35,7 @@ import android.widget.PopupMenu;
import com.android.gallery3d.R;
import com.android.gallery3d.filtershow.editors.EditorCurves;
+import com.android.gallery3d.filtershow.filters.BaseFiltersManager;
import com.android.gallery3d.filtershow.filters.FilterCurvesRepresentation;
import com.android.gallery3d.filtershow.filters.FiltersManager;
import com.android.gallery3d.filtershow.filters.ImageFilterCurves;
@@ -65,11 +65,13 @@ public class ImageCurves extends ImageShow {
public ImageCurves(Context context) {
super(context);
+ setLayerType(LAYER_TYPE_SOFTWARE, gPaint);
resetCurve();
}
public ImageCurves(Context context, AttributeSet attrs) {
super(context, attrs);
+ setLayerType(LAYER_TYPE_SOFTWARE, gPaint);
resetCurve();
}
diff --git a/src/com/android/gallery3d/ingest/IngestActivity.java b/src/com/android/gallery3d/ingest/IngestActivity.java
index 4e603bed3..893f59572 100644
--- a/src/com/android/gallery3d/ingest/IngestActivity.java
+++ b/src/com/android/gallery3d/ingest/IngestActivity.java
@@ -22,11 +22,14 @@ import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
+import android.content.res.Configuration;
+import android.database.DataSetObserver;
import android.mtp.MtpObjectInfo;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
+import android.support.v4.view.ViewPager;
import android.util.SparseBooleanArray;
import android.view.ActionMode;
import android.view.Menu;
@@ -36,12 +39,16 @@ import android.view.View;
import android.widget.AbsListView.MultiChoiceModeListener;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
-import android.widget.GridView;
import android.widget.TextView;
import com.android.gallery3d.R;
+import com.android.gallery3d.ingest.adapter.CheckBroker;
import com.android.gallery3d.ingest.adapter.MtpAdapter;
+import com.android.gallery3d.ingest.adapter.MtpPagerAdapter;
+import com.android.gallery3d.ingest.data.MtpBitmapFetch;
import com.android.gallery3d.ingest.ui.DateTileView;
+import com.android.gallery3d.ingest.ui.IngestGridView;
+import com.android.gallery3d.ingest.ui.IngestGridView.OnClearChoicesListener;
import java.lang.ref.WeakReference;
import java.util.Collection;
@@ -51,14 +58,22 @@ public class IngestActivity extends Activity implements
private IngestService mHelperService;
private boolean mActive = false;
- private GridView mGridView;
+ private IngestGridView mGridView;
private MtpAdapter mAdapter;
private Handler mHandler;
private ProgressDialog mProgressDialog;
private ActionMode mActiveActionMode;
- private View mWarningOverlay;
- private TextView mWarningOverlayText;
+ private View mWarningView;
+ private TextView mWarningText;
+ private int mLastCheckedPosition = 0;
+
+ private ViewPager mFullscreenPager;
+ private MtpPagerAdapter mPagerAdapter;
+ private boolean mFullscreenPagerVisible = false;
+
+ private MenuItem mMenuSwitcherItem;
+ private MenuItem mActionMenuSwitcherItem;
@Override
protected void onCreate(Bundle savedInstanceState) {
@@ -66,18 +81,25 @@ public class IngestActivity extends Activity implements
doBindHelperService();
setContentView(R.layout.ingest_activity_item_list);
- mGridView = (GridView) findViewById(R.id.ingest_gridview);
+ mGridView = (IngestGridView) findViewById(R.id.ingest_gridview);
mAdapter = new MtpAdapter(this);
+ mAdapter.registerDataSetObserver(mMasterObserver);
mGridView.setAdapter(mAdapter);
mGridView.setMultiChoiceModeListener(mMultiChoiceModeListener);
mGridView.setOnItemClickListener(mOnItemClickListener);
+ mGridView.setOnClearChoicesListener(mPositionMappingCheckBroker);
+
+ mFullscreenPager = (ViewPager) findViewById(R.id.ingest_view_pager);
mHandler = new ItemListHandler(this);
+
+ MtpBitmapFetch.configureForContext(this);
}
private OnItemClickListener mOnItemClickListener = new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> adapterView, View itemView, int position, long arg3) {
+ mLastCheckedPosition = position;
mGridView.setItemChecked(position, !mGridView.getCheckedItemPositions().get(position));
}
};
@@ -124,23 +146,18 @@ public class IngestActivity extends Activity implements
mGridView.setItemChecked(i, rangeValue);
}
+ mPositionMappingCheckBroker.onBulkCheckedChange();
mIgnoreItemCheckedStateChanges = false;
+ } else {
+ mPositionMappingCheckBroker.onCheckedChange(position, checked);
}
+ mLastCheckedPosition = position;
updateSelectedTitle(mode);
}
@Override
public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
- switch (item.getItemId()) {
- case R.id.import_items:
- mHelperService.importSelectedItems(
- mGridView.getCheckedItemPositions(),
- mAdapter);
- mode.finish();
- return true;
- default:
- return false;
- }
+ return onOptionsItemSelected(item);
}
@Override
@@ -149,12 +166,16 @@ public class IngestActivity extends Activity implements
inflater.inflate(R.menu.ingest_menu_item_list_selection, menu);
updateSelectedTitle(mode);
mActiveActionMode = mode;
+ mActionMenuSwitcherItem = menu.findItem(R.id.ingest_switch_view);
+ setSwitcherMenuState(mActionMenuSwitcherItem, mFullscreenPagerVisible);
return true;
}
@Override
public void onDestroyActionMode(ActionMode mode) {
mActiveActionMode = null;
+ mActionMenuSwitcherItem = null;
+ mHandler.sendEmptyMessage(ItemListHandler.MSG_BULK_CHECKED_CHANGE);
}
@Override
@@ -164,6 +185,34 @@ public class IngestActivity extends Activity implements
}
};
+ public boolean onOptionsItemSelected(MenuItem item) {
+ switch (item.getItemId()) {
+ case R.id.import_items:
+ if (mActiveActionMode != null) {
+ mHelperService.importSelectedItems(
+ mGridView.getCheckedItemPositions(),
+ mAdapter);
+ mActiveActionMode.finish();
+ }
+ return true;
+ case R.id.ingest_switch_view:
+ setFullscreenPagerVisibility(!mFullscreenPagerVisible);
+ return true;
+ default:
+ return false;
+ }
+ }
+
+ @Override
+ public boolean onCreateOptionsMenu(Menu menu) {
+ MenuInflater inflater = getMenuInflater();
+ inflater.inflate(R.menu.ingest_menu_item_list_selection, menu);
+ mMenuSwitcherItem = menu.findItem(R.id.ingest_switch_view);
+ menu.findItem(R.id.import_items).setVisible(false);
+ setSwitcherMenuState(mMenuSwitcherItem, mFullscreenPagerVisible);
+ return true;
+ }
+
@Override
protected void onDestroy() {
super.onDestroy();
@@ -175,7 +224,7 @@ public class IngestActivity extends Activity implements
DateTileView.refreshLocale();
mActive = true;
if (mHelperService != null) mHelperService.setClientActivity(this);
- updateWarningOverlay();
+ updateWarningView();
super.onResume();
}
@@ -187,31 +236,140 @@ public class IngestActivity extends Activity implements
super.onPause();
}
- private void showWarningOverlay(int textResId) {
- if (mWarningOverlay == null) {
- mWarningOverlay = findViewById(R.id.ingest_warning_overlay);
- mWarningOverlayText =
- (TextView)mWarningOverlay.findViewById(R.id.ingest_warning_overlay_text);
+ @Override
+ public void onConfigurationChanged(Configuration newConfig) {
+ super.onConfigurationChanged(newConfig);
+ MtpBitmapFetch.configureForContext(this);
+ }
+
+ private void showWarningView(int textResId) {
+ if (mWarningView == null) {
+ mWarningView = findViewById(R.id.ingest_warning_view);
+ mWarningText =
+ (TextView)mWarningView.findViewById(R.id.ingest_warning_view_text);
}
- mWarningOverlayText.setText(textResId);
- mWarningOverlay.setVisibility(View.VISIBLE);
+ mWarningText.setText(textResId);
+ mWarningView.setVisibility(View.VISIBLE);
+ setFullscreenPagerVisibility(false);
mGridView.setVisibility(View.GONE);
}
- private void hideWarningOverlay() {
- if (mWarningOverlay != null) {
- mWarningOverlay.setVisibility(View.GONE);
- mGridView.setVisibility(View.VISIBLE);
+ private void hideWarningView() {
+ if (mWarningView != null) {
+ mWarningView.setVisibility(View.GONE);
+ setFullscreenPagerVisibility(false);
}
}
- private void updateWarningOverlay() {
+ private PositionMappingCheckBroker mPositionMappingCheckBroker = new PositionMappingCheckBroker();
+
+ private class PositionMappingCheckBroker extends CheckBroker
+ implements OnClearChoicesListener {
+ private int mLastMappingPager = -1;
+ private int mLastMappingGrid = -1;
+
+ private int mapPagerToGridPosition(int position) {
+ if (position != mLastMappingPager) {
+ mLastMappingPager = position;
+ mLastMappingGrid = mAdapter.translatePositionWithoutLabels(position);
+ }
+ return mLastMappingGrid;
+ }
+
+ private int mapGridToPagerPosition(int position) {
+ if (position != mLastMappingGrid) {
+ mLastMappingGrid = position;
+ mLastMappingPager = mPagerAdapter.translatePositionWithLabels(position);
+ }
+ return mLastMappingPager;
+ }
+
+ @Override
+ public void setItemChecked(int position, boolean checked) {
+ mGridView.setItemChecked(mapPagerToGridPosition(position), checked);
+ }
+
+ @Override
+ public void onCheckedChange(int position, boolean checked) {
+ if (mPagerAdapter != null) {
+ super.onCheckedChange(mapGridToPagerPosition(position), checked);
+ }
+ }
+
+ @Override
+ public boolean isItemChecked(int position) {
+ return mGridView.getCheckedItemPositions().get(mapPagerToGridPosition(position));
+ }
+
+ @Override
+ public void onClearChoices() {
+ onBulkCheckedChange();
+ }
+ };
+
+ private DataSetObserver mMasterObserver = new DataSetObserver() {
+ @Override
+ public void onChanged() {
+ if (mPagerAdapter != null) mPagerAdapter.notifyDataSetChanged();
+ }
+
+ @Override
+ public void onInvalidated() {
+ if (mPagerAdapter != null) mPagerAdapter.notifyDataSetChanged();
+ }
+ };
+
+ private int pickFullscreenStartingPosition() {
+ int firstVisiblePosition = mGridView.getFirstVisiblePosition();
+ if (mLastCheckedPosition <= firstVisiblePosition
+ || mLastCheckedPosition > mGridView.getLastVisiblePosition()) {
+ return firstVisiblePosition;
+ } else {
+ return mLastCheckedPosition;
+ }
+ }
+
+ private void setSwitcherMenuState(MenuItem menuItem, boolean inFullscreenMode) {
+ if (menuItem == null) return;
+ if (!inFullscreenMode) {
+ menuItem.setIcon(android.R.drawable.ic_menu_zoom);
+ menuItem.setTitle(R.string.switch_photo_fullscreen);
+ } else {
+ menuItem.setIcon(android.R.drawable.ic_dialog_dialer);
+ menuItem.setTitle(R.string.switch_photo_grid);
+ }
+ }
+
+ private void setFullscreenPagerVisibility(boolean visible) {
+ mFullscreenPagerVisible = visible;
+ if (visible) {
+ if (mPagerAdapter == null) {
+ mPagerAdapter = new MtpPagerAdapter(this, mPositionMappingCheckBroker);
+ mPagerAdapter.setMtpDeviceIndex(mAdapter.getMtpDeviceIndex());
+ }
+ mFullscreenPager.setAdapter(mPagerAdapter);
+ mFullscreenPager.setCurrentItem(mPagerAdapter.translatePositionWithLabels(
+ pickFullscreenStartingPosition()), false);
+ } else if (mPagerAdapter != null) {
+ mGridView.setSelection(mAdapter.translatePositionWithoutLabels(
+ mFullscreenPager.getCurrentItem()));
+ mFullscreenPager.setAdapter(null);
+ }
+ mGridView.setVisibility(visible ? View.INVISIBLE : View.VISIBLE);
+ mFullscreenPager.setVisibility(visible ? View.VISIBLE : View.INVISIBLE);
+ if (mActionMenuSwitcherItem != null) {
+ setSwitcherMenuState(mActionMenuSwitcherItem, visible);
+ }
+ setSwitcherMenuState(mMenuSwitcherItem, visible);
+ }
+
+ private void updateWarningView() {
if (!mAdapter.deviceConnected()) {
- showWarningOverlay(R.string.ingest_no_device);
+ showWarningView(R.string.ingest_no_device);
} else if (mAdapter.indexReady() && mAdapter.getCount() == 0) {
- showWarningOverlay(R.string.ingest_empty_device);
+ showWarningView(R.string.ingest_empty_device);
} else {
- hideWarningOverlay();
+ hideWarningView();
}
}
@@ -221,7 +379,7 @@ public class IngestActivity extends Activity implements
mActiveActionMode.finish();
mActiveActionMode = null;
}
- updateWarningOverlay();
+ updateWarningView();
}
protected void notifyIndexChanged() {
@@ -330,6 +488,7 @@ public class IngestActivity extends Activity implements
public static final int MSG_PROGRESS_UPDATE = 0;
public static final int MSG_PROGRESS_HIDE = 1;
public static final int MSG_NOTIFY_CHANGED = 2;
+ public static final int MSG_BULK_CHECKED_CHANGE = 3;
WeakReference<IngestActivity> mParentReference;
@@ -352,6 +511,9 @@ public class IngestActivity extends Activity implements
case MSG_NOTIFY_CHANGED:
parent.UiThreadNotifyIndexChanged();
break;
+ case MSG_BULK_CHECKED_CHANGE:
+ parent.mPositionMappingCheckBroker.onBulkCheckedChange();
+ break;
default:
break;
}
@@ -362,7 +524,9 @@ public class IngestActivity extends Activity implements
public void onServiceConnected(ComponentName className, IBinder service) {
mHelperService = ((IngestService.LocalBinder) service).getService();
mHelperService.setClientActivity(IngestActivity.this);
- mAdapter.setMtpDeviceIndex(mHelperService.getIndex());
+ MtpDeviceIndex index = mHelperService.getIndex();
+ mAdapter.setMtpDeviceIndex(index);
+ if (mPagerAdapter != null) mPagerAdapter.setMtpDeviceIndex(index);
}
public void onServiceDisconnected(ComponentName className) {
diff --git a/src/com/android/gallery3d/ingest/IngestService.java b/src/com/android/gallery3d/ingest/IngestService.java
index 12b056b60..5e0ca0b68 100644
--- a/src/com/android/gallery3d/ingest/IngestService.java
+++ b/src/com/android/gallery3d/ingest/IngestService.java
@@ -37,7 +37,7 @@ import android.widget.Adapter;
import com.android.gallery3d.R;
import com.android.gallery3d.app.NotificationIds;
import com.android.gallery3d.data.MtpClient;
-import com.android.gallery3d.ingest.ui.MtpBitmapCache;
+import com.android.gallery3d.ingest.data.MtpBitmapFetch;
import com.android.gallery3d.util.BucketNames;
import java.util.ArrayList;
@@ -66,6 +66,7 @@ public class IngestService extends Service implements ImportTask.Listener,
private boolean mRedeliverImportFinish = false;
private Collection<MtpObjectInfo> mRedeliverObjectsNotImported;
private boolean mRedeliverNotifyIndexChanged = false;
+ private boolean mRedeliverIndexFinish = false;
private NotificationManager mNotificationManager;
private NotificationCompat.Builder mNotificationBuilder;
private long mLastProgressIndexTime = 0;
@@ -108,13 +109,19 @@ public class IngestService extends Service implements ImportTask.Listener,
mRedeliverImportFinish = false;
mRedeliverObjectsNotImported = null;
mRedeliverNotifyIndexChanged = false;
+ mRedeliverIndexFinish = false;
mDevice = device;
mIndex.setDevice(mDevice);
if (mDevice != null) {
MtpDeviceInfo deviceInfo = mDevice.getDeviceInfo();
- mDevicePrettyName = deviceInfo.getModel();
- mNotificationBuilder.setContentTitle(mDevicePrettyName);
- new Thread(mIndex.getIndexRunnable()).start();
+ if (deviceInfo == null) {
+ setDevice(null);
+ return;
+ } else {
+ mDevicePrettyName = deviceInfo.getModel();
+ mNotificationBuilder.setContentTitle(mDevicePrettyName);
+ new Thread(mIndex.getIndexRunnable()).start();
+ }
} else {
mDevicePrettyName = null;
}
@@ -144,6 +151,10 @@ public class IngestService extends Service implements ImportTask.Listener,
mClientActivity.notifyIndexChanged();
mRedeliverNotifyIndexChanged = false;
}
+ if (mRedeliverIndexFinish) {
+ mClientActivity.onIndexFinish();
+ mRedeliverIndexFinish = false;
+ }
}
protected void importSelectedItems(SparseBooleanArray selected, Adapter adapter) {
@@ -176,8 +187,8 @@ public class IngestService extends Service implements ImportTask.Listener,
public void deviceRemoved(MtpDevice device) {
if (device == mDevice) {
setDevice(null);
+ MtpBitmapFetch.onDeviceDisconnected(device);
}
- MtpBitmapCache.onDeviceDisconnected(device);
}
@Override
@@ -197,6 +208,7 @@ public class IngestService extends Service implements ImportTask.Listener,
@Override
public void onImportFinish(Collection<MtpObjectInfo> objectsNotImported) {
+ stopForeground(true);
if (mClientActivity != null) {
mClientActivity.onImportFinish(objectsNotImported);
} else {
@@ -207,7 +219,6 @@ public class IngestService extends Service implements ImportTask.Listener,
mNotificationManager.notify(NotificationIds.INGEST_NOTIFICATION_IMPORTING,
mNotificationBuilder.build());
}
- stopForeground(mClientActivity != null);
}
@Override
@@ -241,6 +252,7 @@ public class IngestService extends Service implements ImportTask.Listener,
.setContentText(getResources().getText(R.string.ingest_scanning_done));
mNotificationManager.notify(NotificationIds.INGEST_NOTIFICATION_SCANNING,
mNotificationBuilder.build());
+ mRedeliverIndexFinish = true;
}
}
diff --git a/src/com/android/gallery3d/ingest/MtpDeviceIndex.java b/src/com/android/gallery3d/ingest/MtpDeviceIndex.java
index 28e115ab0..e873dd1ca 100644
--- a/src/com/android/gallery3d/ingest/MtpDeviceIndex.java
+++ b/src/com/android/gallery3d/ingest/MtpDeviceIndex.java
@@ -180,55 +180,90 @@ public class MtpDeviceIndex {
* order
*/
public Object get(int position, SortOrder order) {
+ if (mProgress != Progress.Finished) return null;
if(order == SortOrder.Ascending) {
- return getAscending(position);
+ DateBucket bucket = mBuckets[mUnifiedLookupIndex[position]];
+ if (bucket.unifiedStartIndex == position) {
+ return bucket.bucket;
+ } else {
+ return mMtpObjects[bucket.itemsStartIndex + position - 1
+ - bucket.unifiedStartIndex];
+ }
} else {
- return getDescending(position);
+ int zeroIndex = mUnifiedLookupIndex.length - 1 - position;
+ DateBucket bucket = mBuckets[mUnifiedLookupIndex[zeroIndex]];
+ if (bucket.unifiedEndIndex == zeroIndex) {
+ return bucket.bucket;
+ } else {
+ return mMtpObjects[bucket.itemsStartIndex + zeroIndex
+ - bucket.unifiedStartIndex];
+ }
}
}
/**
- * @param position Index of item to fetch, where 0 is the first item in
- * ascending order
- * @return position-th item in ascending order
+ * @param position Index of item to fetch from a view of the data that doesn't
+ * include labels and is in the specified order
+ * @return position-th item in specified order, when not including labels
*/
- public Object getAscending(int position) {
+ public MtpObjectInfo getWithoutLabels(int position, SortOrder order) {
if (mProgress != Progress.Finished) return null;
- DateBucket bucket = mBuckets[mUnifiedLookupIndex[position]];
- if (bucket.unifiedStartIndex == position) {
- return bucket.bucket;
+ if (order == SortOrder.Ascending) {
+ return mMtpObjects[position];
} else {
- return bucket.get(position - 1 - bucket.unifiedStartIndex);
+ return mMtpObjects[mMtpObjects.length - 1 - position];
}
}
/**
- * @param position Index of item to fetch, where 0 is the last item in
- * ascending order
- * @return position-th item in descending order
+ * Although this is O(log(number of buckets)), and thus should not be used
+ * in hotspots, even if the attached device has items for every day for
+ * a five-year timeframe, it would still only take 11 iterations at most,
+ * so shouldn't be a huge issue.
+ * @param position Index of item to map from a view of the data that doesn't
+ * include labels and is in the specified order
+ * @param order
+ * @return position in a view of the data that does include labels
*/
- public Object getDescending(int position) {
- if (mProgress != Progress.Finished) return null;
- int zeroIndex = mUnifiedLookupIndex.length - 1 - position;
- DateBucket bucket = mBuckets[mUnifiedLookupIndex[zeroIndex]];
- if (bucket.unifiedEndIndex == zeroIndex) {
- return bucket.bucket;
- } else {
- return bucket.get(zeroIndex - bucket.unifiedStartIndex);
+ public int getPositionFromPositionWithoutLabels(int position, SortOrder order) {
+ if (mProgress != Progress.Finished) return -1;
+ if (order == SortOrder.Descending) {
+ position = mMtpObjects.length - 1 - position;
+ }
+ int bucketNumber = 0;
+ int iMin = 0;
+ int iMax = mBuckets.length - 1;
+ while (iMax >= iMin) {
+ int iMid = (iMax + iMin) / 2;
+ if (mBuckets[iMid].itemsStartIndex + mBuckets[iMid].numItems <= position) {
+ iMin = iMid + 1;
+ } else if (mBuckets[iMid].itemsStartIndex > position) {
+ iMax = iMid - 1;
+ } else {
+ bucketNumber = iMid;
+ break;
+ }
}
+ int mappedPos = mBuckets[bucketNumber].unifiedStartIndex
+ + position - mBuckets[bucketNumber].itemsStartIndex;
+ if (order == SortOrder.Descending) {
+ mappedPos = mUnifiedLookupIndex.length - 1 - mappedPos;
+ }
+ return mappedPos;
}
- /**
- * @param position Index of item to fetch from a view of the data that doesn't
- * include labels and is in ascending order
- * @return position-th item in ascending order, when not including labels
- */
- public MtpObjectInfo getWithoutLabels(int position, SortOrder order) {
- if (mProgress != Progress.Finished) return null;
- if (order == SortOrder.Ascending) {
- return mMtpObjects[position];
+ public int getPositionWithoutLabelsFromPosition(int position, SortOrder order) {
+ if (mProgress != Progress.Finished) return -1;
+ if(order == SortOrder.Ascending) {
+ DateBucket bucket = mBuckets[mUnifiedLookupIndex[position]];
+ if (bucket.unifiedStartIndex == position) position++;
+ return bucket.itemsStartIndex + position - 1 - bucket.unifiedStartIndex;
} else {
- return mMtpObjects[mMtpObjects.length - 1 - position];
+ int zeroIndex = mUnifiedLookupIndex.length - 1 - position;
+ DateBucket bucket = mBuckets[mUnifiedLookupIndex[zeroIndex]];
+ if (bucket.unifiedEndIndex == zeroIndex) zeroIndex--;
+ return mMtpObjects.length - 1 - bucket.itemsStartIndex
+ - zeroIndex + bucket.unifiedStartIndex;
}
}
@@ -288,6 +323,7 @@ public class MtpDeviceIndex {
int unifiedStartIndex;
int unifiedEndIndex;
int itemsStartIndex;
+ int numItems;
public DateBucket(SimpleDate bucket) {
this.bucket = bucket;
@@ -302,10 +338,6 @@ public class MtpDeviceIndex {
Collections.sort(tempElementsList, comparator);
}
- public MtpObjectInfo get(int position) {
- return mMtpObjects[itemsStartIndex + position];
- }
-
@Override
public String toString() {
return bucket.toString();
@@ -413,7 +445,8 @@ public class MtpDeviceIndex {
currentUnifiedIndexEntry = nextUnifiedEntry;
bucket.itemsStartIndex = currentItemsEntry;
- for (int j = 0; j < bucket.tempElementsList.size(); j++) {
+ bucket.numItems = bucket.tempElementsList.size();
+ for (int j = 0; j < bucket.numItems; j++) {
mMtpObjects[currentItemsEntry] = bucket.tempElementsList.get(j);
currentItemsEntry++;
}
diff --git a/src/com/android/gallery3d/ingest/adapter/CheckBroker.java b/src/com/android/gallery3d/ingest/adapter/CheckBroker.java
new file mode 100644
index 000000000..6783f23c5
--- /dev/null
+++ b/src/com/android/gallery3d/ingest/adapter/CheckBroker.java
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.gallery3d.ingest.adapter;
+
+import java.util.ArrayList;
+import java.util.Collection;
+
+public abstract class CheckBroker {
+ private Collection<OnCheckedChangedListener> mListeners =
+ new ArrayList<OnCheckedChangedListener>();
+
+ public interface OnCheckedChangedListener {
+ public void onCheckedChanged(int position, boolean isChecked);
+ public void onBulkCheckedChanged();
+ }
+
+ public abstract void setItemChecked(int position, boolean checked);
+
+ public void onCheckedChange(int position, boolean checked) {
+ if (isItemChecked(position) != checked) {
+ for (OnCheckedChangedListener l : mListeners) {
+ l.onCheckedChanged(position, checked);
+ }
+ }
+ }
+
+ public void onBulkCheckedChange() {
+ for (OnCheckedChangedListener l : mListeners) {
+ l.onBulkCheckedChanged();
+ }
+ }
+
+ public abstract boolean isItemChecked(int position);
+
+ public void registerOnCheckedChangeListener(OnCheckedChangedListener l) {
+ mListeners.add(l);
+ }
+
+ public void unregisterOnCheckedChangeListener(OnCheckedChangedListener l) {
+ mListeners.remove(l);
+ }
+}
diff --git a/src/com/android/gallery3d/ingest/adapter/MtpAdapter.java b/src/com/android/gallery3d/ingest/adapter/MtpAdapter.java
index 611d880db..e8dd69f8c 100644
--- a/src/com/android/gallery3d/ingest/adapter/MtpAdapter.java
+++ b/src/com/android/gallery3d/ingest/adapter/MtpAdapter.java
@@ -45,8 +45,7 @@ public class MtpAdapter extends BaseAdapter implements SectionIndexer {
public MtpAdapter(Activity context) {
super();
mContext = context;
- mInflater = (LayoutInflater)context.getSystemService
- (Context.LAYOUT_INFLATER_SERVICE);
+ mInflater = LayoutInflater.from(context);
}
public void setMtpDeviceIndex(MtpDeviceIndex index) {
@@ -54,6 +53,10 @@ public class MtpAdapter extends BaseAdapter implements SectionIndexer {
notifyDataSetChanged();
}
+ public MtpDeviceIndex getMtpDeviceIndex() {
+ return mModel;
+ }
+
@Override
public void notifyDataSetChanged() {
mGeneration++;
@@ -177,4 +180,13 @@ public class MtpAdapter extends BaseAdapter implements SectionIndexer {
public Object[] getSections() {
return getCount() > 0 ? mModel.getBuckets(mSortOrder) : null;
}
+
+ public SortOrder getSortOrder() {
+ return mSortOrder;
+ }
+
+ public int translatePositionWithoutLabels(int position) {
+ if (mModel == null) return -1;
+ return mModel.getPositionFromPositionWithoutLabels(position, mSortOrder);
+ }
}
diff --git a/src/com/android/gallery3d/ingest/adapter/MtpPagerAdapter.java b/src/com/android/gallery3d/ingest/adapter/MtpPagerAdapter.java
new file mode 100644
index 000000000..9e7abc01d
--- /dev/null
+++ b/src/com/android/gallery3d/ingest/adapter/MtpPagerAdapter.java
@@ -0,0 +1,102 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.gallery3d.ingest.adapter;
+
+import android.content.Context;
+import android.mtp.MtpObjectInfo;
+import android.support.v4.view.PagerAdapter;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+
+import com.android.gallery3d.R;
+import com.android.gallery3d.ingest.MtpDeviceIndex;
+import com.android.gallery3d.ingest.MtpDeviceIndex.SortOrder;
+import com.android.gallery3d.ingest.ui.MtpFullscreenView;
+
+public class MtpPagerAdapter extends PagerAdapter {
+
+ private LayoutInflater mInflater;
+ private int mGeneration = 0;
+ private CheckBroker mBroker;
+ private MtpDeviceIndex mModel;
+ private SortOrder mSortOrder = SortOrder.Descending;
+
+ private MtpFullscreenView mReusableView = null;
+
+ public MtpPagerAdapter(Context context, CheckBroker broker) {
+ super();
+ mInflater = LayoutInflater.from(context);
+ mBroker = broker;
+ }
+
+ public void setMtpDeviceIndex(MtpDeviceIndex index) {
+ mModel = index;
+ notifyDataSetChanged();
+ }
+
+ @Override
+ public int getCount() {
+ return mModel != null ? mModel.sizeWithoutLabels() : 0;
+ }
+
+ @Override
+ public void notifyDataSetChanged() {
+ mGeneration++;
+ super.notifyDataSetChanged();
+ }
+
+ public int translatePositionWithLabels(int position) {
+ if (mModel == null) return -1;
+ return mModel.getPositionWithoutLabelsFromPosition(position, mSortOrder);
+ }
+
+ @Override
+ public void finishUpdate(ViewGroup container) {
+ mReusableView = null;
+ super.finishUpdate(container);
+ }
+
+ @Override
+ public boolean isViewFromObject(View view, Object object) {
+ return view == object;
+ }
+
+ @Override
+ public void destroyItem(ViewGroup container, int position, Object object) {
+ MtpFullscreenView v = (MtpFullscreenView)object;
+ container.removeView(v);
+ mBroker.unregisterOnCheckedChangeListener(v);
+ mReusableView = v;
+ }
+
+ @Override
+ public Object instantiateItem(ViewGroup container, int position) {
+ MtpFullscreenView v;
+ if (mReusableView != null) {
+ v = mReusableView;
+ mReusableView = null;
+ } else {
+ v = (MtpFullscreenView) mInflater.inflate(R.layout.ingest_fullsize, container, false);
+ }
+ MtpObjectInfo i = mModel.getWithoutLabels(position, mSortOrder);
+ v.getImageView().setMtpDeviceAndObjectInfo(mModel.getDevice(), i, mGeneration);
+ v.setPositionAndBroker(position, mBroker);
+ container.addView(v);
+ return v;
+ }
+}
diff --git a/src/com/android/gallery3d/ingest/data/BitmapWithMetadata.java b/src/com/android/gallery3d/ingest/data/BitmapWithMetadata.java
new file mode 100644
index 000000000..bbc90f670
--- /dev/null
+++ b/src/com/android/gallery3d/ingest/data/BitmapWithMetadata.java
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.gallery3d.ingest.data;
+
+import android.graphics.Bitmap;
+
+public class BitmapWithMetadata {
+ public Bitmap bitmap;
+ public int rotationDegrees;
+
+ public BitmapWithMetadata(Bitmap bitmap, int rotationDegrees) {
+ this.bitmap = bitmap;
+ this.rotationDegrees = rotationDegrees;
+ }
+}
diff --git a/src/com/android/gallery3d/ingest/data/MtpBitmapFetch.java b/src/com/android/gallery3d/ingest/data/MtpBitmapFetch.java
new file mode 100644
index 000000000..88645e8d0
--- /dev/null
+++ b/src/com/android/gallery3d/ingest/data/MtpBitmapFetch.java
@@ -0,0 +1,97 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.gallery3d.ingest.data;
+
+import android.content.Context;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.mtp.MtpDevice;
+import android.mtp.MtpObjectInfo;
+import android.util.DisplayMetrics;
+import android.view.WindowManager;
+
+import com.android.camera.Exif;
+import com.android.gallery3d.common.Utils;
+import com.android.gallery3d.data.BitmapPool;
+
+import java.util.ArrayList;
+
+public class MtpBitmapFetch {
+ private static final int BITMAP_POOL_SIZE = 32;
+ private static BitmapPool sThumbnailPool = new BitmapPool(BITMAP_POOL_SIZE);
+ private static int sMaxSize = 0;
+
+ public static void recycleThumbnail(Bitmap b) {
+ if (b != null) {
+ sThumbnailPool.recycle(b);
+ }
+ }
+
+ public static Bitmap getThumbnail(MtpDevice device, MtpObjectInfo info) {
+ byte[] imageBytes = device.getThumbnail(info.getObjectHandle());
+ BitmapFactory.Options o = new BitmapFactory.Options();
+ o.inJustDecodeBounds = true;
+ BitmapFactory.decodeByteArray(imageBytes, 0, imageBytes.length, o);
+ if (o.outWidth == 0 || o.outHeight == 0) return null;
+ o.inBitmap = sThumbnailPool.getBitmap(o.outWidth, o.outHeight);
+ o.inMutable = true;
+ o.inJustDecodeBounds = false;
+ o.inSampleSize = 1;
+ return BitmapFactory.decodeByteArray(imageBytes, 0, imageBytes.length, o);
+ }
+
+ public static BitmapWithMetadata getFullsize(MtpDevice device, MtpObjectInfo info) {
+ return getFullsize(device, info, sMaxSize);
+ }
+
+ public static BitmapWithMetadata getFullsize(MtpDevice device, MtpObjectInfo info, int maxSide) {
+ byte[] imageBytes = device.getObject(info.getObjectHandle(), info.getCompressedSize());
+ Bitmap created;
+ if (maxSide > 0) {
+ BitmapFactory.Options o = new BitmapFactory.Options();
+ o.inJustDecodeBounds = true;
+ BitmapFactory.decodeByteArray(imageBytes, 0, imageBytes.length, o);
+ int w = o.outWidth;
+ int h = o.outHeight;
+ int comp = Math.max(h, w);
+ int sampleSize = 1;
+ while ((comp >> 1) >= maxSide) {
+ comp = comp >> 1;
+ sampleSize++;
+ }
+ o.inSampleSize = sampleSize;
+ o.inJustDecodeBounds = false;
+ created = BitmapFactory.decodeByteArray(imageBytes, 0, imageBytes.length, o);
+ } else {
+ created = BitmapFactory.decodeByteArray(imageBytes, 0, imageBytes.length);
+ }
+ if (created == null) return null;
+
+ return new BitmapWithMetadata(created, Exif.getOrientation(imageBytes));
+ }
+
+ public static void onDeviceDisconnected(MtpDevice device) {
+ sThumbnailPool.clear();
+ }
+
+ public static void configureForContext(Context context) {
+ DisplayMetrics metrics = new DisplayMetrics();
+ WindowManager wm = (WindowManager)context.getSystemService(Context.WINDOW_SERVICE);
+ wm.getDefaultDisplay().getMetrics(metrics);
+ sMaxSize = Math.max(metrics.heightPixels, metrics.widthPixels);
+ }
+}
diff --git a/src/com/android/gallery3d/ingest/ui/IngestGridView.java b/src/com/android/gallery3d/ingest/ui/IngestGridView.java
new file mode 100644
index 000000000..c821259fe
--- /dev/null
+++ b/src/com/android/gallery3d/ingest/ui/IngestGridView.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.gallery3d.ingest.ui;
+
+import android.content.Context;
+import android.util.AttributeSet;
+import android.widget.GridView;
+
+/**
+ * This just extends GridView with the ability to listen for calls
+ * to clearChoices()
+ */
+public class IngestGridView extends GridView {
+
+ public interface OnClearChoicesListener {
+ public void onClearChoices();
+ }
+
+ private OnClearChoicesListener mOnClearChoicesListener = null;
+
+ public IngestGridView(Context context) {
+ super(context);
+ }
+
+ public IngestGridView(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ }
+
+ public IngestGridView(Context context, AttributeSet attrs, int defStyle) {
+ super(context, attrs, defStyle);
+ }
+
+ public void setOnClearChoicesListener(OnClearChoicesListener l) {
+ mOnClearChoicesListener = l;
+ }
+
+ @Override
+ public void clearChoices() {
+ super.clearChoices();
+ if (mOnClearChoicesListener != null) {
+ mOnClearChoicesListener.onClearChoices();
+ }
+ }
+}
diff --git a/src/com/android/gallery3d/ingest/ui/MtpBitmapCache.java b/src/com/android/gallery3d/ingest/ui/MtpBitmapCache.java
deleted file mode 100644
index 307531d5b..000000000
--- a/src/com/android/gallery3d/ingest/ui/MtpBitmapCache.java
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * Copyright (C) 2013 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.gallery3d.ingest.ui;
-
-import android.graphics.Bitmap;
-import android.graphics.BitmapFactory;
-import android.mtp.MtpDevice;
-import android.util.LruCache;
-
-public class MtpBitmapCache extends LruCache<Integer, Bitmap> {
- private static final int PER_DEVICE_CACHE_MAX_BYTES = 4194304;
- private static MtpBitmapCache sInstance;
-
- public synchronized static MtpBitmapCache getInstanceForDevice(MtpDevice device) {
- if (sInstance == null || sInstance.mDevice != device) {
- sInstance = new MtpBitmapCache(PER_DEVICE_CACHE_MAX_BYTES, device);
- }
- return sInstance;
- }
-
- public synchronized static void onDeviceDisconnected(MtpDevice device) {
- if (sInstance != null && sInstance.mDevice == device) {
- synchronized (sInstance) {
- sInstance.mDevice = null;
- }
- sInstance = null;
- }
- }
-
- private MtpDevice mDevice;
-
- private MtpBitmapCache(int maxSize, MtpDevice device) {
- super(maxSize);
- mDevice = device;
- }
-
- @Override
- protected int sizeOf(Integer key, Bitmap value) {
- return value.getByteCount();
- }
-
- public Bitmap getOrCreate(Integer key) {
- Bitmap b = get(key);
- return b == null ? createAndInsert(key) : b;
- }
-
- private Bitmap createAndInsert(Integer key) {
- MtpDevice device;
- synchronized (this) {
- device = mDevice;
- }
- if (device == null) return null;
- byte[] imageBytes = device.getThumbnail(key);
- if (imageBytes == null) return null;
- Bitmap created = BitmapFactory.decodeByteArray(imageBytes, 0, imageBytes.length);
- put(key, created);
- return created;
- }
-}
diff --git a/src/com/android/gallery3d/ingest/ui/MtpFullscreenView.java b/src/com/android/gallery3d/ingest/ui/MtpFullscreenView.java
new file mode 100644
index 000000000..8d3884dc6
--- /dev/null
+++ b/src/com/android/gallery3d/ingest/ui/MtpFullscreenView.java
@@ -0,0 +1,115 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.gallery3d.ingest.ui;
+
+import android.content.Context;
+import android.util.AttributeSet;
+import android.widget.CheckBox;
+import android.widget.Checkable;
+import android.widget.CompoundButton;
+import android.widget.CompoundButton.OnCheckedChangeListener;
+import android.widget.RelativeLayout;
+
+import com.android.gallery3d.R;
+import com.android.gallery3d.ingest.adapter.CheckBroker;
+
+public class MtpFullscreenView extends RelativeLayout implements Checkable,
+ CompoundButton.OnCheckedChangeListener, CheckBroker.OnCheckedChangedListener {
+
+ private MtpImageView mImageView;
+ private CheckBox mCheckbox;
+ private int mPosition = -1;
+ private CheckBroker mBroker;
+
+ public MtpFullscreenView(Context context) {
+ super(context);
+ }
+
+ public MtpFullscreenView(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ }
+
+ public MtpFullscreenView(Context context, AttributeSet attrs, int defStyle) {
+ super(context, attrs, defStyle);
+ }
+
+ @Override
+ protected void onFinishInflate() {
+ super.onFinishInflate();
+ mImageView = (MtpImageView) findViewById(R.id.ingest_fullsize_image);
+ mCheckbox = (CheckBox) findViewById(R.id.ingest_fullsize_image_checkbox);
+ mCheckbox.setOnCheckedChangeListener(this);
+ }
+
+ @Override
+ public boolean isChecked() {
+ return mCheckbox.isChecked();
+ }
+
+ @Override
+ public void setChecked(boolean checked) {
+ mCheckbox.setChecked(checked);
+ }
+
+ @Override
+ public void toggle() {
+ mCheckbox.toggle();
+ }
+
+ @Override
+ public void onDetachedFromWindow() {
+ setPositionAndBroker(-1, null);
+ super.onDetachedFromWindow();
+ }
+
+ public MtpImageView getImageView() {
+ return mImageView;
+ }
+
+ public int getPosition() {
+ return mPosition;
+ }
+
+ public void setPositionAndBroker(int position, CheckBroker b) {
+ if (mBroker != null) {
+ mBroker.unregisterOnCheckedChangeListener(this);
+ }
+ mPosition = position;
+ mBroker = b;
+ if (mBroker != null) {
+ setChecked(mBroker.isItemChecked(position));
+ mBroker.registerOnCheckedChangeListener(this);
+ }
+ }
+
+ @Override
+ public void onCheckedChanged(CompoundButton arg0, boolean isChecked) {
+ if (mBroker != null) mBroker.setItemChecked(mPosition, isChecked);
+ }
+
+ @Override
+ public void onCheckedChanged(int position, boolean isChecked) {
+ if (position == mPosition) {
+ setChecked(isChecked);
+ }
+ }
+
+ @Override
+ public void onBulkCheckedChanged() {
+ if(mBroker != null) setChecked(mBroker.isItemChecked(mPosition));
+ }
+}
diff --git a/src/com/android/gallery3d/ingest/ui/MtpImageView.java b/src/com/android/gallery3d/ingest/ui/MtpImageView.java
new file mode 100644
index 000000000..9c197851e
--- /dev/null
+++ b/src/com/android/gallery3d/ingest/ui/MtpImageView.java
@@ -0,0 +1,130 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.gallery3d.ingest.ui;
+
+import android.content.Context;
+import android.mtp.MtpDevice;
+import android.mtp.MtpObjectInfo;
+import android.os.AsyncTask;
+import android.util.AttributeSet;
+import android.widget.ImageView;
+
+import com.android.gallery3d.ingest.data.BitmapWithMetadata;
+import com.android.gallery3d.ingest.data.MtpBitmapFetch;
+
+public class MtpImageView extends ImageView {
+ private static final int FADE_IN_TIME_MS = 80;
+
+ private int mObjectHandle;
+ private int mGeneration;
+
+ private void init() {
+ showPlaceholder();
+ }
+
+ public MtpImageView(Context context) {
+ super(context);
+ init();
+ }
+
+ public MtpImageView(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ init();
+ }
+
+ public MtpImageView(Context context, AttributeSet attrs, int defStyle) {
+ super(context, attrs, defStyle);
+ init();
+ }
+
+ private void showPlaceholder() {
+ setImageResource(android.R.color.transparent);
+ }
+
+ private LoadMtpImageTask mTask;
+
+ public void setMtpDeviceAndObjectInfo(MtpDevice device, MtpObjectInfo object, int gen) {
+ int handle = object.getObjectHandle();
+ if (handle == mObjectHandle && gen == mGeneration) {
+ return;
+ }
+ cancelLoadingAndClear();
+ showPlaceholder();
+ mGeneration = gen;
+ mObjectHandle = handle;
+ mTask = new LoadMtpImageTask(device);
+ mTask.execute(object);
+ }
+
+ protected Object fetchMtpImageDataFromDevice(MtpDevice device, MtpObjectInfo info) {
+ return MtpBitmapFetch.getFullsize(device, info);
+ }
+
+ protected void onMtpImageDataFetchedFromDevice(Object result) {
+ BitmapWithMetadata bitmapWithMetadata = (BitmapWithMetadata)result;
+ setImageBitmap(bitmapWithMetadata.bitmap);
+ setRotation(bitmapWithMetadata.rotationDegrees);
+ }
+
+ private class LoadMtpImageTask extends AsyncTask<MtpObjectInfo, Void, Object> {
+ private MtpDevice mDevice;
+
+ public LoadMtpImageTask(MtpDevice device) {
+ mDevice = device;
+ }
+
+ @Override
+ protected Object doInBackground(MtpObjectInfo... args) {
+ Object result = null;
+ if (!isCancelled()) {
+ result = fetchMtpImageDataFromDevice(mDevice, args[0]);
+ }
+ mDevice = null;
+ return result;
+ }
+
+ @Override
+ protected void onPostExecute(Object result) {
+ if (isCancelled() || result == null) {
+ return;
+ }
+ setAlpha(0f);
+ onMtpImageDataFetchedFromDevice(result);
+ animate().alpha(1f).setDuration(FADE_IN_TIME_MS);
+ }
+
+ @Override
+ protected void onCancelled() {
+ }
+ }
+
+ protected void cancelLoadingAndClear() {
+ if (mTask != null) {
+ mTask.cancel(true);
+ }
+ mTask = null;
+ animate().cancel();
+ setImageResource(android.R.color.transparent);
+ setRotation(0);
+ }
+
+ @Override
+ public void onDetachedFromWindow() {
+ cancelLoadingAndClear();
+ super.onDetachedFromWindow();
+ }
+}
diff --git a/src/com/android/gallery3d/ingest/ui/MtpThumbnailTileView.java b/src/com/android/gallery3d/ingest/ui/MtpThumbnailTileView.java
index 2aeda73db..3307e78aa 100644
--- a/src/com/android/gallery3d/ingest/ui/MtpThumbnailTileView.java
+++ b/src/com/android/gallery3d/ingest/ui/MtpThumbnailTileView.java
@@ -22,26 +22,22 @@ import android.graphics.Canvas;
import android.graphics.Paint;
import android.mtp.MtpDevice;
import android.mtp.MtpObjectInfo;
-import android.os.AsyncTask;
import android.util.AttributeSet;
-import android.view.View;
import android.widget.Checkable;
-import android.widget.ImageView;
import com.android.gallery3d.R;
+import com.android.gallery3d.ingest.data.MtpBitmapFetch;
-public class MtpThumbnailTileView extends ImageView implements Checkable {
- private static final int FADE_IN_TIME_MS = 80;
+
+public class MtpThumbnailTileView extends MtpImageView implements Checkable {
private Paint mForegroundPaint;
private boolean mIsChecked;
- private int mObjectHandle;
- private int mGeneration;
+ private Bitmap mBitmap;
private void init() {
mForegroundPaint = new Paint();
mForegroundPaint.setColor(getResources().getColor(R.color.ingest_highlight_semitransparent));
- showPlaceholder();
}
public MtpThumbnailTileView(Context context) {
@@ -66,9 +62,20 @@ public class MtpThumbnailTileView extends ImageView implements Checkable {
}
@Override
+ protected Object fetchMtpImageDataFromDevice(MtpDevice device, MtpObjectInfo info) {
+ return MtpBitmapFetch.getThumbnail(device, info);
+ }
+
+ @Override
+ protected void onMtpImageDataFetchedFromDevice(Object result) {
+ mBitmap = (Bitmap)result;
+ setImageBitmap(mBitmap);
+ }
+
+ @Override
public void draw(Canvas canvas) {
super.draw(canvas);
- if (mIsChecked) {
+ if (isChecked()) {
canvas.drawRect(canvas.getClipBounds(), mForegroundPaint);
}
}
@@ -88,65 +95,12 @@ public class MtpThumbnailTileView extends ImageView implements Checkable {
setChecked(!mIsChecked);
}
- private void showPlaceholder() {
- setAlpha(0f);
- }
-
- private LoadThumbnailTask mTask;
-
- public void setMtpDeviceAndObjectInfo(MtpDevice device, MtpObjectInfo object, int gen) {
- int handle = object.getObjectHandle();
- if (handle == mObjectHandle && gen == mGeneration) {
- return;
- }
- animate().cancel();
- if (mTask != null) {
- mTask.cancel(true);
- }
- mGeneration = gen;
- mObjectHandle = handle;
- Bitmap thumbnail = MtpBitmapCache.getInstanceForDevice(device)
- .get(handle);
- if (thumbnail != null) {
- setAlpha(1f);
- setImageBitmap(thumbnail);
- } else {
- showPlaceholder();
- mTask = new LoadThumbnailTask(device);
- mTask.execute(object);
- }
- }
-
- private class LoadThumbnailTask extends AsyncTask<MtpObjectInfo, Void, Bitmap> {
- private MtpDevice mDevice;
-
- public LoadThumbnailTask(MtpDevice device) {
- mDevice = device;
- }
-
- @Override
- protected Bitmap doInBackground(MtpObjectInfo... args) {
- Bitmap result = null;
- if (!isCancelled()) {
- result = MtpBitmapCache.getInstanceForDevice(mDevice).getOrCreate(
- args[0].getObjectHandle());
- }
- mDevice = null;
- return result;
- }
-
- @Override
- protected void onPostExecute(Bitmap result) {
- if (isCancelled() || result == null) {
- return;
- }
- setAlpha(0f);
- setImageBitmap(result);
- animate().alpha(1f).setDuration(FADE_IN_TIME_MS);
- }
-
- @Override
- protected void onCancelled() {
+ @Override
+ protected void cancelLoadingAndClear() {
+ super.cancelLoadingAndClear();
+ if (mBitmap != null) {
+ MtpBitmapFetch.recycleThumbnail(mBitmap);
+ mBitmap = null;
}
}
}