OSDN Git Service

Merge "Exiftool parser" into gb-ub-photos-bryce
[android-x86/packages-apps-Gallery2.git] / src / com / android / gallery3d / filtershow / imageshow / ImageShow.java
1 /*
2  * Copyright (C) 2012 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 package com.android.gallery3d.filtershow.imageshow;
18
19 import android.content.Context;
20 import android.graphics.Bitmap;
21 import android.graphics.Canvas;
22 import android.graphics.Color;
23 import android.graphics.Paint;
24 import android.graphics.Rect;
25 import android.graphics.RectF;
26 import android.os.Handler;
27 import android.util.AttributeSet;
28 import android.view.GestureDetector;
29 import android.view.GestureDetector.OnDoubleTapListener;
30 import android.view.GestureDetector.OnGestureListener;
31 import android.view.MotionEvent;
32 import android.view.View;
33 import android.widget.ArrayAdapter;
34 import android.widget.SeekBar;
35 import android.widget.SeekBar.OnSeekBarChangeListener;
36
37 import com.android.gallery3d.R;
38 import com.android.gallery3d.filtershow.FilterShowActivity;
39 import com.android.gallery3d.filtershow.HistoryAdapter;
40 import com.android.gallery3d.filtershow.ImageStateAdapter;
41 import com.android.gallery3d.filtershow.PanelController;
42 import com.android.gallery3d.filtershow.cache.ImageLoader;
43 import com.android.gallery3d.filtershow.filters.ImageFilter;
44 import com.android.gallery3d.filtershow.presets.ImagePreset;
45 import com.android.gallery3d.filtershow.ui.SliderController;
46 import com.android.gallery3d.filtershow.ui.SliderListener;
47
48 import java.io.File;
49
50 public class ImageShow extends View implements OnGestureListener,
51         OnDoubleTapListener,
52         SliderListener,
53         OnSeekBarChangeListener {
54
55     private static final String LOGTAG = "ImageShow";
56
57     protected Paint mPaint = new Paint();
58     protected static int mTextSize = 24;
59     protected static int mTextPadding = 20;
60
61     protected ImagePreset mImagePreset = null;
62     protected ImagePreset mImageGeometryOnlyPreset = null;
63     protected ImagePreset mImageFiltersOnlyPreset = null;
64
65     protected ImageLoader mImageLoader = null;
66     private ImageFilter mCurrentFilter = null;
67     private boolean mDirtyGeometry = false;
68
69     private Bitmap mBackgroundImage = null;
70     private final boolean USE_BACKGROUND_IMAGE = false;
71     private static int mBackgroundColor = Color.RED;
72
73     private Bitmap mGeometryOnlyImage = null;
74     private Bitmap mFiltersOnlyImage = null;
75     private Bitmap mFilteredImage = null;
76
77     private final boolean USE_SLIDER_GESTURE = false; // set to true to have
78                                                       // slider gesture
79     protected SliderController mSliderController = new SliderController();
80
81     private GestureDetector mGestureDetector = null;
82
83     private HistoryAdapter mHistoryAdapter = null;
84     private ImageStateAdapter mImageStateAdapter = null;
85
86     private Rect mImageBounds = new Rect();
87
88     private boolean mTouchShowOriginal = false;
89     private long mTouchShowOriginalDate = 0;
90     private final long mTouchShowOriginalDelayMin = 200; // 200ms
91     private final long mTouchShowOriginalDelayMax = 300; // 300ms
92     private int mShowOriginalDirection = 0;
93     private static int UNVEIL_HORIZONTAL = 1;
94     private static int UNVEIL_VERTICAL = 2;
95
96     private int mTouchDownX = 0;
97     private int mTouchDownY = 0;
98     protected float mTouchX = 0;
99     protected float mTouchY = 0;
100
101     private static int mOriginalTextMargin = 8;
102     private static int mOriginalTextSize = 26;
103     private static String mOriginalText = "Original";
104
105     protected GeometryMetadata getGeometry() {
106         return new GeometryMetadata(getImagePreset().mGeoData);
107     }
108
109     public void setGeometry(GeometryMetadata d) {
110         getImagePreset().mGeoData.set(d);
111     }
112
113     private boolean mShowControls = false;
114     private boolean mShowOriginal = false;
115     private String mToast = null;
116     private boolean mShowToast = false;
117     private boolean mImportantToast = false;
118
119     private SeekBar mSeekBar = null;
120     private PanelController mController = null;
121
122     private FilterShowActivity mActivity = null;
123
124     public static void setDefaultBackgroundColor(int value) {
125         mBackgroundColor = value;
126     }
127
128     public int getDefaultBackgroundColor() {
129         return mBackgroundColor;
130     }
131
132     public static void setTextSize(int value) {
133         mTextSize = value;
134     }
135
136     public static void setTextPadding(int value) {
137         mTextPadding = value;
138     }
139
140     public static void setOriginalTextMargin(int value) {
141         mOriginalTextMargin = value;
142     }
143
144     public static void setOriginalTextSize(int value) {
145         mOriginalTextSize = value;
146     }
147
148     public static void setOriginalText(String text) {
149         mOriginalText = text;
150     }
151
152     private final Handler mHandler = new Handler();
153
154     public void select() {
155         if (getCurrentFilter() != null) {
156             int parameter = getCurrentFilter().getParameter();
157             int maxp = getCurrentFilter().getMaxParameter();
158             int minp = getCurrentFilter().getMinParameter();
159             updateSeekBar(parameter, minp, maxp);
160         }
161         if (mSeekBar != null) {
162             mSeekBar.setOnSeekBarChangeListener(this);
163         }
164     }
165
166     private int parameterToUI(int parameter, int minp, int maxp, int uimax) {
167         return (uimax * (parameter - minp)) / (maxp - minp);
168     }
169
170     private int uiToParameter(int ui, int minp, int maxp, int uimax) {
171         return ((maxp - minp) * ui) / uimax + minp;
172     }
173
174     public void updateSeekBar(int parameter, int minp, int maxp) {
175         if (mSeekBar == null) {
176             return;
177         }
178         int seekMax = mSeekBar.getMax();
179         int progress = parameterToUI(parameter, minp, maxp, seekMax);
180         mSeekBar.setProgress(progress);
181         if (getPanelController() != null) {
182             getPanelController().onNewValue(parameter);
183         }
184     }
185
186     public void unselect() {
187
188     }
189
190     public boolean hasModifications() {
191         if (getImagePreset() == null) {
192             return false;
193         }
194         return getImagePreset().hasModifications();
195     }
196
197     public void resetParameter() {
198         ImageFilter currentFilter = getCurrentFilter();
199         if (currentFilter != null) {
200             onNewValue(currentFilter.getDefaultParameter());
201         }
202         if (USE_SLIDER_GESTURE) {
203             mSliderController.reset();
204         }
205     }
206
207     public void setPanelController(PanelController controller) {
208         mController = controller;
209     }
210
211     public PanelController getPanelController() {
212         return mController;
213     }
214
215     @Override
216     public void onNewValue(int parameter) {
217         int maxp = 100;
218         int minp = -100;
219         if (getCurrentFilter() != null) {
220             getCurrentFilter().setParameter(parameter);
221             maxp = getCurrentFilter().getMaxParameter();
222             minp = getCurrentFilter().getMinParameter();
223         }
224         if (getImagePreset() != null) {
225             mImageLoader.resetImageForPreset(getImagePreset(), this);
226             getImagePreset().fillImageStateAdapter(mImageStateAdapter);
227         }
228         if (getPanelController() != null) {
229             getPanelController().onNewValue(parameter);
230         }
231         updateSeekBar(parameter, minp, maxp);
232         invalidate();
233         mActivity.enableSave(hasModifications());
234     }
235
236     @Override
237     public void onTouchDown(float x, float y) {
238         mTouchX = x;
239         mTouchY = y;
240         invalidate();
241     }
242
243     @Override
244     public void onTouchUp() {
245     }
246
247     public ImageShow(Context context, AttributeSet attrs) {
248         super(context, attrs);
249         if (USE_SLIDER_GESTURE) {
250             mSliderController.setListener(this);
251         }
252         mHistoryAdapter = new HistoryAdapter(context, R.layout.filtershow_history_operation_row,
253                 R.id.rowTextView);
254         mImageStateAdapter = new ImageStateAdapter(context,
255                 R.layout.filtershow_imagestate_row);
256         setupGestureDetector(context);
257         mActivity = (FilterShowActivity) context;
258     }
259
260     public ImageShow(Context context) {
261         super(context);
262         if (USE_SLIDER_GESTURE) {
263             mSliderController.setListener(this);
264         }
265         mHistoryAdapter = new HistoryAdapter(context, R.layout.filtershow_history_operation_row,
266                 R.id.rowTextView);
267         setupGestureDetector(context);
268         mActivity = (FilterShowActivity) context;
269     }
270
271     public void setupGestureDetector(Context context) {
272         mGestureDetector = new GestureDetector(context, this);
273     }
274
275     @Override
276     protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
277         int parentWidth = MeasureSpec.getSize(widthMeasureSpec);
278         int parentHeight = MeasureSpec.getSize(heightMeasureSpec);
279         setMeasuredDimension(parentWidth, parentHeight);
280         if (USE_SLIDER_GESTURE) {
281             mSliderController.setWidth(parentWidth);
282             mSliderController.setHeight(parentHeight);
283         }
284     }
285
286     public void setSeekBar(SeekBar seekBar) {
287         mSeekBar = seekBar;
288     }
289
290     public void setCurrentFilter(ImageFilter filter) {
291         mCurrentFilter = filter;
292     }
293
294     public ImageFilter getCurrentFilter() {
295         return mCurrentFilter;
296     }
297
298     public void setAdapter(HistoryAdapter adapter) {
299         mHistoryAdapter = adapter;
300     }
301
302     public void showToast(String text) {
303         showToast(text, false);
304     }
305
306     public void showToast(String text, boolean important) {
307         mToast = text;
308         mShowToast = true;
309         mImportantToast = important;
310         invalidate();
311
312         mHandler.postDelayed(new Runnable() {
313             @Override
314             public void run() {
315                 mShowToast = false;
316                 invalidate();
317             }
318         }, 400);
319     }
320
321     public Rect getImageBounds() {
322         Rect dst = new Rect();
323         getImagePreset().mGeoData.getPhotoBounds().roundOut(dst);
324         return dst;
325     }
326
327     public Rect getDisplayedImageBounds() {
328         return mImageBounds;
329     }
330
331     public ImagePreset getImagePreset() {
332         return mImagePreset;
333     }
334
335     public void drawToast(Canvas canvas) {
336         if (mShowToast && mToast != null) {
337             Paint paint = new Paint();
338             paint.setTextSize(128);
339             float textWidth = paint.measureText(mToast);
340             int toastX = (int) ((getWidth() - textWidth) / 2.0f);
341             int toastY = (int) (getHeight() / 3.0f);
342
343             paint.setARGB(255, 0, 0, 0);
344             canvas.drawText(mToast, toastX - 2, toastY - 2, paint);
345             canvas.drawText(mToast, toastX - 2, toastY, paint);
346             canvas.drawText(mToast, toastX, toastY - 2, paint);
347             canvas.drawText(mToast, toastX + 2, toastY + 2, paint);
348             canvas.drawText(mToast, toastX + 2, toastY, paint);
349             canvas.drawText(mToast, toastX, toastY + 2, paint);
350             if (mImportantToast) {
351                 paint.setARGB(255, 200, 0, 0);
352             } else {
353                 paint.setARGB(255, 255, 255, 255);
354             }
355             canvas.drawText(mToast, toastX, toastY, paint);
356         }
357     }
358
359     public void defaultDrawImage(Canvas canvas) {
360         drawImage(canvas, getFilteredImage());
361         drawPartialImage(canvas, getGeometryOnlyImage());
362     }
363
364     @Override
365     public void onDraw(Canvas canvas) {
366         drawBackground(canvas);
367         requestFilteredImages();
368         defaultDrawImage(canvas);
369
370         if (showTitle() && getImagePreset() != null) {
371             mPaint.setARGB(200, 0, 0, 0);
372             mPaint.setTextSize(mTextSize);
373
374             Rect textRect = new Rect(0, 0, getWidth(), mTextSize + mTextPadding);
375             canvas.drawRect(textRect, mPaint);
376             mPaint.setARGB(255, 200, 200, 200);
377             canvas.drawText(getImagePreset().name(), mTextPadding,
378                     1.5f * mTextPadding, mPaint);
379         }
380
381         if (showControls()) {
382             if (USE_SLIDER_GESTURE) {
383                 mSliderController.onDraw(canvas);
384             }
385         }
386
387         drawToast(canvas);
388     }
389
390     public void resetImageCaches(ImageShow caller) {
391         if (mImageLoader == null) {
392             return;
393         }
394         updateImagePresets(true);
395     }
396
397     public void updateImagePresets(boolean force) {
398         ImagePreset preset = getImagePreset();
399         if (preset == null) {
400             mActivity.enableSave(false);
401             return;
402         }
403         if (force) {
404             mImageLoader.resetImageForPreset(getImagePreset(), this);
405         }
406         if (force || mImageGeometryOnlyPreset == null) {
407             ImagePreset newPreset = new ImagePreset(preset);
408             newPreset.setDoApplyFilters(false);
409             if (mImageGeometryOnlyPreset == null
410                     || !newPreset.same(mImageGeometryOnlyPreset)) {
411                 mImageGeometryOnlyPreset = newPreset;
412                 mGeometryOnlyImage = null;
413             }
414         }
415         if (force || mImageFiltersOnlyPreset == null) {
416             ImagePreset newPreset = new ImagePreset(preset);
417             newPreset.setDoApplyGeometry(false);
418             if (mImageFiltersOnlyPreset == null
419                     || !newPreset.same(mImageFiltersOnlyPreset)) {
420                 mImageFiltersOnlyPreset = newPreset;
421                 mFiltersOnlyImage = null;
422             }
423         }
424         mActivity.enableSave(hasModifications());
425     }
426
427     public void requestFilteredImages() {
428         if (mImageLoader != null) {
429             Bitmap bitmap = mImageLoader.getImageForPreset(this,
430                     getImagePreset(), showHires());
431
432             if (bitmap != null) {
433                 if (mFilteredImage == null) {
434                     invalidate();
435                 }
436                 mFilteredImage = bitmap;
437             }
438
439             updateImagePresets(false);
440             if (mImageGeometryOnlyPreset != null) {
441                 bitmap = mImageLoader.getImageForPreset(this, mImageGeometryOnlyPreset,
442                         showHires());
443                 if (bitmap != null) {
444                     mGeometryOnlyImage = bitmap;
445                 }
446             }
447             if (mImageFiltersOnlyPreset != null) {
448                 bitmap = mImageLoader.getImageForPreset(this, mImageFiltersOnlyPreset,
449                         showHires());
450                 if (bitmap != null) {
451                     mFiltersOnlyImage = bitmap;
452                 }
453             }
454         }
455
456         if (mShowOriginal) {
457             mFilteredImage = mGeometryOnlyImage;
458         }
459     }
460
461     public Bitmap getFiltersOnlyImage() {
462         return mFiltersOnlyImage;
463     }
464
465     public Bitmap getGeometryOnlyImage() {
466         return mGeometryOnlyImage;
467     }
468
469     public Bitmap getFilteredImage() {
470         return mFilteredImage;
471     }
472
473     public void drawImage(Canvas canvas, Bitmap image) {
474         if (image != null) {
475             Rect s = new Rect(0, 0, image.getWidth(),
476                     image.getHeight());
477
478             float scale = GeometryMath.scale(image.getWidth(), image.getHeight(), getWidth(),
479                     getHeight());
480
481             float w = image.getWidth() * scale;
482             float h = image.getHeight() * scale;
483             float ty = (getHeight() - h) / 2.0f;
484             float tx = (getWidth() - w) / 2.0f;
485
486             Rect d = new Rect((int) tx, (int) ty, (int) (w + tx),
487                     (int) (h + ty));
488             mImageBounds = d;
489             canvas.drawBitmap(image, s, d, mPaint);
490         }
491     }
492
493     public void drawPartialImage(Canvas canvas, Bitmap image) {
494         if (!mTouchShowOriginal)
495             return;
496         canvas.save();
497         if (image != null) {
498             if (mShowOriginalDirection == 0) {
499                 if ((mTouchY - mTouchDownY) > (mTouchX - mTouchDownX)) {
500                     mShowOriginalDirection = UNVEIL_VERTICAL;
501                 } else {
502                     mShowOriginalDirection = UNVEIL_HORIZONTAL;
503                 }
504             }
505
506             int px = 0;
507             int py = 0;
508             if (mShowOriginalDirection == UNVEIL_VERTICAL) {
509                 px = mImageBounds.width();
510                 py = (int) (mTouchY - mImageBounds.top);
511             } else {
512                 px = (int) (mTouchX - mImageBounds.left);
513                 py = mImageBounds.height();
514             }
515
516             Rect d = new Rect(mImageBounds.left, mImageBounds.top,
517                     mImageBounds.left + px, mImageBounds.top + py);
518             canvas.clipRect(d);
519             drawImage(canvas, image);
520             Paint paint = new Paint();
521             paint.setColor(Color.BLACK);
522
523             if (mShowOriginalDirection == UNVEIL_VERTICAL) {
524                 canvas.drawLine(mImageBounds.left, mTouchY - 1,
525                         mImageBounds.right, mTouchY - 1, paint);
526             } else {
527                 canvas.drawLine(mTouchX - 1, mImageBounds.top,
528                         mTouchX - 1, mImageBounds.bottom, paint);
529             }
530
531             Rect bounds = new Rect();
532             paint.setTextSize(mOriginalTextSize);
533             paint.getTextBounds(mOriginalText, 0, mOriginalText.length(), bounds);
534             paint.setColor(Color.BLACK);
535             canvas.drawText(mOriginalText, mImageBounds.left + mOriginalTextMargin + 1,
536                     mImageBounds.top + bounds.height() + mOriginalTextMargin + 1, paint);
537             paint.setColor(Color.WHITE);
538             canvas.drawText(mOriginalText, mImageBounds.left + mOriginalTextMargin,
539                     mImageBounds.top + bounds.height() + mOriginalTextMargin, paint);
540         }
541         canvas.restore();
542     }
543
544     public void drawBackground(Canvas canvas) {
545         if (USE_BACKGROUND_IMAGE) {
546             if (mBackgroundImage == null) {
547                 mBackgroundImage = mImageLoader.getBackgroundBitmap(getResources());
548             }
549             if (mBackgroundImage != null) {
550                 Rect s = new Rect(0, 0, mBackgroundImage.getWidth(),
551                         mBackgroundImage.getHeight());
552                 Rect d = new Rect(0, 0, getWidth(), getHeight());
553                 canvas.drawBitmap(mBackgroundImage, s, d, mPaint);
554             }
555         } else {
556             canvas.drawColor(mBackgroundColor);
557         }
558     }
559
560     public ImageShow setShowControls(boolean value) {
561         mShowControls = value;
562         if (mShowControls) {
563             if (mSeekBar != null) {
564                 mSeekBar.setVisibility(View.VISIBLE);
565             }
566         } else {
567             if (mSeekBar != null) {
568                 mSeekBar.setVisibility(View.INVISIBLE);
569             }
570         }
571         return this;
572     }
573
574     public boolean showControls() {
575         return mShowControls;
576     }
577
578     public boolean showHires() {
579         return true;
580     }
581
582     public boolean showTitle() {
583         return false;
584     }
585
586     public void setImagePreset(ImagePreset preset) {
587         setImagePreset(preset, true);
588     }
589
590     public void setImagePreset(ImagePreset preset, boolean addToHistory) {
591         if (preset == null) {
592             return;
593         }
594         mImagePreset = preset;
595         getImagePreset().setImageLoader(mImageLoader);
596         updateImagePresets(true);
597         if (addToHistory) {
598             mHistoryAdapter.addHistoryItem(getImagePreset());
599         }
600         getImagePreset().setEndpoint(this);
601         updateImage();
602         mImagePreset.fillImageStateAdapter(mImageStateAdapter);
603         invalidate();
604     }
605
606     public void setImageLoader(ImageLoader loader) {
607         mImageLoader = loader;
608         if (mImageLoader != null) {
609             mImageLoader.addListener(this);
610             if (mImagePreset != null) {
611                 mImagePreset.setImageLoader(mImageLoader);
612             }
613         }
614     }
615
616     private void setDirtyGeometryFlag() {
617         mDirtyGeometry = true;
618     }
619
620     protected void clearDirtyGeometryFlag() {
621         mDirtyGeometry = false;
622     }
623
624     protected boolean getDirtyGeometryFlag() {
625         return mDirtyGeometry;
626     }
627
628     private void imageSizeChanged(Bitmap image) {
629         if (image == null || getImagePreset() == null)
630             return;
631         float w = image.getWidth();
632         float h = image.getHeight();
633         GeometryMetadata geo = getImagePreset().mGeoData;
634         RectF pb = geo.getPhotoBounds();
635         if (w == pb.width() && h == pb.height()) {
636             return;
637         }
638         RectF r = new RectF(0, 0, w, h);
639         getImagePreset().mGeoData.setPhotoBounds(r);
640         getImagePreset().mGeoData.setCropBounds(r);
641         setDirtyGeometryFlag();
642     }
643
644     public boolean updateGeometryFlags() {
645         return true;
646     }
647
648     public void updateImage() {
649         if (!updateGeometryFlags()) {
650             return;
651         }
652         Bitmap bitmap = mImageLoader.getOriginalBitmapLarge();
653         if (bitmap != null) {
654             imageSizeChanged(bitmap);
655             invalidate();
656         }
657     }
658
659     public void imageLoaded() {
660         updateImage();
661         invalidate();
662     }
663
664     public void updateFilteredImage(Bitmap bitmap) {
665         mFilteredImage = bitmap;
666     }
667
668     public void saveImage(FilterShowActivity filterShowActivity, File file) {
669         mImageLoader.saveImage(getImagePreset(), filterShowActivity, file);
670     }
671
672     @Override
673     public boolean onTouchEvent(MotionEvent event) {
674         super.onTouchEvent(event);
675         if (USE_SLIDER_GESTURE) {
676             mSliderController.onTouchEvent(event);
677         }
678         if (mGestureDetector != null) {
679             mGestureDetector.onTouchEvent(event);
680         }
681         int ex = (int) event.getX();
682         int ey = (int) event.getY();
683         if (event.getAction() == MotionEvent.ACTION_DOWN) {
684             mTouchDownX = ex;
685             mTouchDownY = ey;
686             mTouchShowOriginalDate = System.currentTimeMillis();
687             mShowOriginalDirection = 0;
688         }
689         if (event.getAction() == MotionEvent.ACTION_MOVE) {
690             mTouchX = ex;
691             mTouchY = ey;
692             if (!mActivity.isShowingHistoryPanel()
693                     && (System.currentTimeMillis() - mTouchShowOriginalDate
694                     > mTouchShowOriginalDelayMin)) {
695                 mTouchShowOriginal = true;
696             }
697         }
698         if (event.getAction() == MotionEvent.ACTION_UP) {
699             mTouchShowOriginal = false;
700             mTouchDownX = 0;
701             mTouchDownY = 0;
702             mTouchX = 0;
703             mTouchY = 0;
704         }
705         invalidate();
706         return true;
707     }
708
709     // listview stuff
710
711     public HistoryAdapter getHistory() {
712         return mHistoryAdapter;
713     }
714
715     public ArrayAdapter getImageStateAdapter() {
716         return mImageStateAdapter;
717     }
718
719     public void onItemClick(int position) {
720         setImagePreset(new ImagePreset(mHistoryAdapter.getItem(position)), false);
721         // we need a copy from the history
722         mHistoryAdapter.setCurrentPreset(position);
723     }
724
725     public void showOriginal(boolean show) {
726         mShowOriginal = show;
727         invalidate();
728     }
729
730     public float getImageRotation() {
731         return getImagePreset().mGeoData.getRotation();
732     }
733
734     public float getImageRotationZoomFactor() {
735         return getImagePreset().mGeoData.getScaleFactor();
736     }
737
738     public void setImageRotation(float r) {
739         getImagePreset().mGeoData.setRotation(r);
740     }
741
742     public void setImageRotationZoomFactor(float f) {
743         getImagePreset().mGeoData.setScaleFactor(f);
744     }
745
746     public void setImageRotation(float imageRotation,
747             float imageRotationZoomFactor) {
748         float r = getImageRotation();
749         if (imageRotation != r) {
750             invalidate();
751         }
752         setImageRotation(imageRotation);
753         setImageRotationZoomFactor(imageRotationZoomFactor);
754     }
755
756     @Override
757     public void onProgressChanged(SeekBar arg0, int progress, boolean arg2) {
758         int parameter = progress;
759         if (getCurrentFilter() != null) {
760             int maxp = getCurrentFilter().getMaxParameter();
761             int minp = getCurrentFilter().getMinParameter();
762             parameter = uiToParameter(progress, minp, maxp, arg0.getMax());
763         }
764
765         onNewValue(parameter);
766     }
767
768     @Override
769     public void onStartTrackingTouch(SeekBar arg0) {
770         // TODO Auto-generated method stub
771
772     }
773
774     @Override
775     public void onStopTrackingTouch(SeekBar arg0) {
776         // TODO Auto-generated method stub
777
778     }
779
780     @Override
781     public boolean onDoubleTap(MotionEvent arg0) {
782         // TODO Auto-generated method stub
783         return false;
784     }
785
786     @Override
787     public boolean onDoubleTapEvent(MotionEvent arg0) {
788         // TODO Auto-generated method stub
789         return false;
790     }
791
792     @Override
793     public boolean onSingleTapConfirmed(MotionEvent arg0) {
794         // TODO Auto-generated method stub
795         return false;
796     }
797
798     @Override
799     public boolean onDown(MotionEvent arg0) {
800         // TODO Auto-generated method stub
801         return false;
802     }
803
804     @Override
805     public boolean onFling(MotionEvent startEvent, MotionEvent endEvent, float arg2, float arg3) {
806         if ((!mActivity.isShowingHistoryPanel() && startEvent.getX() > endEvent.getX())
807                 || (mActivity.isShowingHistoryPanel() && endEvent.getX() > startEvent.getX())) {
808             if (!mTouchShowOriginal
809                     || (mTouchShowOriginal &&
810                     (System.currentTimeMillis() - mTouchShowOriginalDate
811                     < mTouchShowOriginalDelayMax))) {
812                 mActivity.toggleHistoryPanel();
813             }
814         }
815         return true;
816     }
817
818     @Override
819     public void onLongPress(MotionEvent arg0) {
820         // TODO Auto-generated method stub
821
822     }
823
824     @Override
825     public boolean onScroll(MotionEvent arg0, MotionEvent arg1, float arg2, float arg3) {
826         // TODO Auto-generated method stub
827         return false;
828     }
829
830     @Override
831     public void onShowPress(MotionEvent arg0) {
832         // TODO Auto-generated method stub
833
834     }
835
836     @Override
837     public boolean onSingleTapUp(MotionEvent arg0) {
838         // TODO Auto-generated method stub
839         return false;
840     }
841
842 }