blob: 809585dfbfdb3c13cdb3b205c7491c942476bcff [file] [log] [blame]
/*
* Copyright (C) 2012 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;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.RectF;
import android.os.Handler;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.SeekBar;
import android.widget.SeekBar.OnSeekBarChangeListener;
import com.android.gallery3d.R;
import com.android.gallery3d.filtershow.FilterShowActivity;
import com.android.gallery3d.filtershow.HistoryAdapter;
import com.android.gallery3d.filtershow.ImageStateAdapter;
import com.android.gallery3d.filtershow.PanelController;
import com.android.gallery3d.filtershow.cache.ImageLoader;
import com.android.gallery3d.filtershow.filters.ImageFilter;
import com.android.gallery3d.filtershow.presets.ImagePreset;
import com.android.gallery3d.filtershow.ui.SliderController;
import com.android.gallery3d.filtershow.ui.SliderListener;
import java.io.File;
public class ImageShow extends View implements SliderListener, OnSeekBarChangeListener {
private static final String LOGTAG = "ImageShow";
protected Paint mPaint = new Paint();
private static int mTextSize = 24;
private static int mTextPadding = 20;
protected ImagePreset mImagePreset = null;
protected ImageLoader mImageLoader = null;
private ImageFilter mCurrentFilter = null;
private boolean mDirtyGeometry = true;
private Bitmap mBackgroundImage = null;
protected Bitmap mForegroundImage = null;
protected Bitmap mFilteredImage = null;
private final boolean USE_SLIDER_GESTURE = false; // set to true to have
// slider gesture
protected SliderController mSliderController = new SliderController();
private HistoryAdapter mHistoryAdapter = null;
private ImageStateAdapter mImageStateAdapter = null;
protected GeometryMetadata getGeometry() {
return new GeometryMetadata(getImagePreset().mGeoData);
}
public void setGeometry(GeometryMetadata d) {
getImagePreset().mGeoData.set(d);
}
private boolean mShowControls = false;
private boolean mShowOriginal = false;
private String mToast = null;
private boolean mShowToast = false;
private boolean mImportantToast = false;
protected float mTouchX = 0;
protected float mTouchY = 0;
private SeekBar mSeekBar = null;
private PanelController mController = null;
private final Handler mHandler = new Handler();
public void select() {
if (getCurrentFilter() != null) {
int parameter = getCurrentFilter().getParameter();
updateSeekBar(parameter);
}
if (mSeekBar != null) {
mSeekBar.setOnSeekBarChangeListener(this);
}
}
public void updateSeekBar(int parameter) {
if (mSeekBar == null) {
return;
}
int progress = parameter + 100;
mSeekBar.setProgress(progress);
if (getPanelController() != null) {
getPanelController().onNewValue(parameter);
}
}
public void unselect() {
}
public void resetParameter() {
onNewValue(0);
if (USE_SLIDER_GESTURE) {
mSliderController.reset();
}
}
public void setPanelController(PanelController controller) {
mController = controller;
}
public PanelController getPanelController() {
return mController;
}
@Override
public void onNewValue(int value) {
if (getCurrentFilter() != null) {
getCurrentFilter().setParameter(value);
}
if (getImagePreset() != null) {
mImageLoader.resetImageForPreset(getImagePreset(), this);
getImagePreset().fillImageStateAdapter(mImageStateAdapter);
}
if (getPanelController() != null) {
getPanelController().onNewValue(value);
}
updateSeekBar(value);
invalidate();
}
@Override
public void onTouchDown(float x, float y) {
mTouchX = x;
mTouchY = y;
invalidate();
}
@Override
public void onTouchUp() {
}
public ImageShow(Context context, AttributeSet attrs) {
super(context, attrs);
if (USE_SLIDER_GESTURE) {
mSliderController.setListener(this);
}
mHistoryAdapter = new HistoryAdapter(context, R.layout.filtershow_history_operation_row,
R.id.rowTextView);
mImageStateAdapter = new ImageStateAdapter(context,
R.layout.filtershow_imagestate_row);
}
public ImageShow(Context context) {
super(context);
if (USE_SLIDER_GESTURE) {
mSliderController.setListener(this);
}
mHistoryAdapter = new HistoryAdapter(context, R.layout.filtershow_history_operation_row,
R.id.rowTextView);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int parentWidth = MeasureSpec.getSize(widthMeasureSpec);
int parentHeight = MeasureSpec.getSize(heightMeasureSpec);
setMeasuredDimension(parentWidth, parentHeight);
if (USE_SLIDER_GESTURE) {
mSliderController.setWidth(parentWidth);
mSliderController.setHeight(parentHeight);
}
}
public void setSeekBar(SeekBar seekBar) {
mSeekBar = seekBar;
}
public void setCurrentFilter(ImageFilter filter) {
mCurrentFilter = filter;
}
public ImageFilter getCurrentFilter() {
return mCurrentFilter;
}
public void setAdapter(HistoryAdapter adapter) {
mHistoryAdapter = adapter;
}
public void showToast(String text) {
showToast(text, false);
}
public void showToast(String text, boolean important) {
mToast = text;
mShowToast = true;
mImportantToast = important;
invalidate();
mHandler.postDelayed(new Runnable() {
@Override
public void run() {
mShowToast = false;
invalidate();
}
}, 400);
}
public Rect getImageBounds() {
Rect dst = new Rect();
getImagePreset().mGeoData.getPhotoBounds().roundOut(dst);
return dst;
}
public ImagePreset getImagePreset() {
return mImagePreset;
}
public Bitmap getOriginalFrontBitmap() {
if (mImageLoader != null) {
return mImageLoader.getOriginalBitmapLarge();
}
return null;
}
public void drawToast(Canvas canvas) {
if (mShowToast && mToast != null) {
Paint paint = new Paint();
paint.setTextSize(128);
float textWidth = paint.measureText(mToast);
int toastX = (int) ((getWidth() - textWidth) / 2.0f);
int toastY = (int) (getHeight() / 3.0f);
paint.setARGB(255, 0, 0, 0);
canvas.drawText(mToast, toastX - 2, toastY - 2, paint);
canvas.drawText(mToast, toastX - 2, toastY, paint);
canvas.drawText(mToast, toastX, toastY - 2, paint);
canvas.drawText(mToast, toastX + 2, toastY + 2, paint);
canvas.drawText(mToast, toastX + 2, toastY, paint);
canvas.drawText(mToast, toastX, toastY + 2, paint);
if (mImportantToast) {
paint.setARGB(255, 200, 0, 0);
} else {
paint.setARGB(255, 255, 255, 255);
}
canvas.drawText(mToast, toastX, toastY, paint);
}
}
@Override
public void onDraw(Canvas canvas) {
drawBackground(canvas);
getFilteredImage();
drawImage(canvas, mFilteredImage);
if (showTitle() && getImagePreset() != null) {
mPaint.setARGB(200, 0, 0, 0);
mPaint.setTextSize(mTextSize);
Rect textRect = new Rect(0, 0, getWidth(), mTextSize + mTextPadding);
canvas.drawRect(textRect, mPaint);
mPaint.setARGB(255, 200, 200, 200);
canvas.drawText(getImagePreset().name(), mTextPadding,
10 + mTextPadding, mPaint);
}
mPaint.setARGB(255, 150, 150, 150);
mPaint.setStrokeWidth(4);
canvas.drawLine(0, 0, getWidth(), 0, mPaint);
if (showControls()) {
if (USE_SLIDER_GESTURE) {
mSliderController.onDraw(canvas);
}
}
drawToast(canvas);
}
public void getFilteredImage() {
Bitmap filteredImage = null;
if (mImageLoader != null) {
filteredImage = mImageLoader.getImageForPreset(this,
getImagePreset(), showHires());
}
if (filteredImage == null) {
// if no image for the current preset, use the previous one
filteredImage = mFilteredImage;
} else {
mFilteredImage = filteredImage;
}
if (mShowOriginal || mFilteredImage == null) {
mFilteredImage = mForegroundImage;
}
}
public void drawImage(Canvas canvas, Bitmap image) {
if (image != null) {
Rect s = new Rect(0, 0, image.getWidth(),
image.getHeight());
float ratio = image.getWidth()
/ (float) image.getHeight();
float w = getWidth();
float h = w / ratio;
float ty = (getHeight() - h) / 2.0f;
float tx = 0;
if (ratio < 1.0f) { // portrait image
h = getHeight();
w = h * ratio;
tx = (getWidth() - w) / 2.0f;
ty = 0;
}
Rect d = new Rect((int) tx, (int) ty, (int) (w + tx),
(int) (h + ty));
canvas.drawBitmap(image, s, d, mPaint);
}
}
public void drawBackground(Canvas canvas) {
if (mBackgroundImage == null) {
mBackgroundImage = mImageLoader.getBackgroundBitmap(getResources());
}
if (mBackgroundImage != null) {
Rect s = new Rect(0, 0, mBackgroundImage.getWidth(),
mBackgroundImage.getHeight());
Rect d = new Rect(0, 0, getWidth(), getHeight());
canvas.drawBitmap(mBackgroundImage, s, d, mPaint);
}
}
public ImageShow setShowControls(boolean value) {
mShowControls = value;
if (mShowControls) {
if (mSeekBar != null) {
mSeekBar.setVisibility(View.VISIBLE);
}
} else {
if (mSeekBar != null) {
mSeekBar.setVisibility(View.INVISIBLE);
}
}
return this;
}
public boolean showControls() {
return mShowControls;
}
public boolean showHires() {
return true;
}
public boolean showTitle() {
return false;
}
public void setImagePreset(ImagePreset preset) {
setImagePreset(preset, true);
}
public void setImagePreset(ImagePreset preset, boolean addToHistory) {
mImagePreset = preset;
if (getImagePreset() != null) {
if (addToHistory) {
mHistoryAdapter.insert(getImagePreset(), 0);
}
getImagePreset().setEndpoint(this);
updateImage();
}
mImagePreset.fillImageStateAdapter(mImageStateAdapter);
invalidate();
}
public void setImageLoader(ImageLoader loader) {
mImageLoader = loader;
if (mImageLoader != null) {
mImageLoader.addListener(this);
}
}
protected void setDirtyGeometryFlag() {
mDirtyGeometry = true;
}
protected void clearDirtyGeometryFlag() {
mDirtyGeometry = false;
}
protected boolean getDirtyGeometryFlag() {
return mDirtyGeometry;
}
private void imageSizeChanged(Bitmap image) {
if (image == null || getImagePreset() == null)
return;
float w = image.getWidth();
float h = image.getHeight();
RectF r = new RectF(0, 0, w, h);
getImagePreset().mGeoData.setPhotoBounds(r);
getImagePreset().mGeoData.setCropBounds(r);
setDirtyGeometryFlag();
}
public void updateImage() {
mForegroundImage = getOriginalFrontBitmap();
imageSizeChanged(mForegroundImage); // TODO: should change to filtered
}
public void updateFilteredImage(Bitmap bitmap) {
mFilteredImage = bitmap;
}
public void saveImage(FilterShowActivity filterShowActivity, File file) {
mImageLoader.saveImage(getImagePreset(), filterShowActivity, file);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
super.onTouchEvent(event);
if (USE_SLIDER_GESTURE) {
mSliderController.onTouchEvent(event);
}
invalidate();
return true;
}
// listview stuff
public ArrayAdapter getHistoryAdapter() {
return mHistoryAdapter;
}
public ArrayAdapter getImageStateAdapter() {
return mImageStateAdapter;
}
public void onItemClick(int position) {
setImagePreset(new ImagePreset(mHistoryAdapter.getItem(position)), false);
// we need a copy from the history
mHistoryAdapter.setCurrentPreset(position);
}
public void showOriginal(boolean show) {
mShowOriginal = show;
invalidate();
}
public float getImageRotation() {
return getImagePreset().mGeoData.getRotation();
}
public float getImageRotationZoomFactor() {
return getImagePreset().mGeoData.getScaleFactor();
}
public void setImageRotation(float r) {
getImagePreset().mGeoData.setRotation(r);
}
public void setImageRotationZoomFactor(float f) {
getImagePreset().mGeoData.setScaleFactor(f);
}
public void setImageRotation(float imageRotation,
float imageRotationZoomFactor) {
float r = getImageRotation();
if (imageRotation != r) {
invalidate();
}
setImageRotation(imageRotation);
setImageRotationZoomFactor(imageRotationZoomFactor);
}
@Override
public void onProgressChanged(SeekBar arg0, int progress, boolean arg2) {
onNewValue(progress - 100);
}
@Override
public void onStartTrackingTouch(SeekBar arg0) {
// TODO Auto-generated method stub
}
@Override
public void onStopTrackingTouch(SeekBar arg0) {
// TODO Auto-generated method stub
}
}