TinyPlanetPreview.java revision a5a08d7642a1fdf961b057cc90e76c4c93103c15
1a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling/* 2a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling * Copyright (C) 2013 The Android Open Source Project 3a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling * 4a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling * Licensed under the Apache License, Version 2.0 (the "License"); 5a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling * you may not use this file except in compliance with the License. 6a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling * You may obtain a copy of the License at 7a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling * 8a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling * http://www.apache.org/licenses/LICENSE-2.0 9a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling * 10a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling * Unless required by applicable law or agreed to in writing, software 11a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling * distributed under the License is distributed on an "AS IS" BASIS, 12a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling * See the License for the specific language governing permissions and 14a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling * limitations under the License. 15a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling */ 16a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling 17a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberlingpackage com.android.camera.tinyplanet; 18a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling 19a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberlingimport android.content.Context; 20a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberlingimport android.graphics.Bitmap; 21a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberlingimport android.graphics.Canvas; 22a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberlingimport android.graphics.Paint; 23a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberlingimport android.util.AttributeSet; 24a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberlingimport android.view.View; 25a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling 26a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberlingimport java.util.concurrent.locks.Lock; 27a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling 28a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling/** 29a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling * Shows a preview of the TinyPlanet on the screen while editing. 30a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling */ 31a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberlingpublic class TinyPlanetPreview extends View { 32a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling /** 33a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling * Classes implementing this interface get informed about changes to the 34a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling * preview size. 35a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling */ 36a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling public static interface PreviewSizeListener { 37a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling /** 38a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling * Called when the preview size has changed. 39a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling * 40a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling * @param sizePx the size in pixels of the square preview area 41a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling */ 42a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling public void onSizeChanged(int sizePx); 43a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling } 44a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling 45a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling private Paint mPaint = new Paint(); 46a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling private Bitmap mPreview; 47a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling private Lock mLock; 48a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling private PreviewSizeListener mPreviewSizeListener; 49a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling private int mSize = 0; 50a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling 51a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling public TinyPlanetPreview(Context context) { 52a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling super(context); 53a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling } 54a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling 55a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling public TinyPlanetPreview(Context context, AttributeSet attrs) { 56a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling super(context, attrs); 57a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling } 58a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling 59a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling public TinyPlanetPreview(Context context, AttributeSet attrs, int defStyle) { 60a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling super(context, attrs, defStyle); 61a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling } 62a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling 63a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling /** 64a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling * Sets the bitmap and waits for a draw to happen before returning. 65a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling */ 66a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling public void setBitmap(Bitmap preview, Lock lock) { 67a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling mPreview = preview; 68a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling mLock = lock; 69a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling invalidate(); 70a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling } 71a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling 72a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling public void setPreviewSizeChangeListener(PreviewSizeListener listener) { 73a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling mPreviewSizeListener = listener; 74a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling if (mSize > 0) { 75a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling mPreviewSizeListener.onSizeChanged(mSize); 76a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling } 77a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling } 78a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling 79a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling @Override 80a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling protected void onDraw(Canvas canvas) { 81a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling super.onDraw(canvas); 82a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling if (mLock != null && mLock.tryLock() && mPreview != null && !mPreview.isRecycled()) { 83a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling try { 84a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling canvas.drawBitmap(mPreview, 0, 0, mPaint); 85a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling } finally { 86a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling mLock.unlock(); 87a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling } 88a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling } 89a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling } 90a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling 91a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling @Override 92a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 93a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling super.onMeasure(widthMeasureSpec, heightMeasureSpec); 94a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling 95a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling // Make sure the view is square 96a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling int size = Math.min(getMeasuredWidth(), getMeasuredHeight()); 97a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling setMeasuredDimension(size, size); 98a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling } 99a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling 100a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling @Override 101a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling protected void onLayout(boolean changed, int left, int top, int right, int bottom) { 102a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling super.onLayout(changed, left, top, right, bottom); 103a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling if (changed && mPreviewSizeListener != null) { 104a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling int width = right - left; 105a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling int height = bottom - top; 106a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling 107a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling // These should be the same as we enforce a square layout, but let's 108a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling // be safe. 109a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling int mSize = Math.min(width, height); 110a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling 111a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling // Tell the listener about our new size so the renderer can adapt. 112a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling if (mSize > 0 && mPreviewSizeListener != null) { 113a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling mPreviewSizeListener.onSizeChanged(mSize); 114a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling } 115a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling } 116a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling } 117a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling} 118