content: package com.almalence.ui;
  
  import android.content.Context;
  import android.content.res.TypedArray;
  import android.graphics.Canvas;
  import android.graphics.Matrix;
  import android.graphics.Rect;
  import android.graphics.RectF;
  import android.util.AttributeSet;
  import android.view.MotionEvent;
  import android.view.View;
  import android.view.ViewGroup;
  import android.view.ViewParent;
  
  /* <!-- +++
  import com.almalence.opencam_plus.R;
  +++ --> */
  //<!-- -+-
  import com.almalence.opencam.R;
  //-+- -->
  
  public class RotateLayout extends ViewGroup
  {
  
  	public static class LayoutParams extends ViewGroup.LayoutParams
  	{
  
  		public int	angle;
  
  		public LayoutParams(Context context, AttributeSet attrs)
  		{
  			super(context, attrs);
  			final TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.RotateLayout_Layout);
  			angle = a.getInt(R.styleable.RotateLayout_Layout_layout_angle, 0);
  		}
  
  		public LayoutParams(ViewGroup.LayoutParams layoutParams)
  		{
  			super(layoutParams);
  		}
  
  	}
  
  	public RotateLayout(Context context)
  	{
  		this(context, null);
  	}
  
  	public RotateLayout(Context context, AttributeSet attrs)
  	{
  		super(context, attrs);
  		setWillNotDraw(false);
  	}
  
  	public View getView()
  	{
  		return getChildAt(0);
  	}
  
  	@Override
  	protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec)
  	{
  		final View view = getView();
  		if (view != null)
  		{
  			final LayoutParams layoutParams = (LayoutParams) view.getLayoutParams();
  			if (angle != layoutParams.angle)
  			{
  				angle = layoutParams.angle;
  				angleChanged = true;
  			}
  
  			if (Math.abs(angle % 180) == 90)
  			{
  				measureChild(view, heightMeasureSpec, widthMeasureSpec);
  				setMeasuredDimension(resolveSize(view.getMeasuredHeight(), widthMeasureSpec),
  						resolveSize(view.getMeasuredWidth(), heightMeasureSpec));
  			} else
  			{
  				measureChild(view, widthMeasureSpec, heightMeasureSpec);
  				setMeasuredDimension(resolveSize(view.getMeasuredWidth(), widthMeasureSpec),
  						resolveSize(view.getMeasuredHeight(), heightMeasureSpec));
  			}
  		} else
  		{
  			super.onMeasure(widthMeasureSpec, heightMeasureSpec);
  		}
  	}
  
  	@Override
  	protected void onLayout(boolean changed, int l, int t, int r, int b)
  	{
  		if (angleChanged)
  		{
  			final RectF layoutRect = tempRectF1;
  			final RectF layoutRectRotated = tempRectF2;
  			layoutRect.set(0, 0, r - l, b - t);
  			rotateMatrix.setRotate(angle, layoutRect.centerX(), layoutRect.centerY());
  			rotateMatrix.mapRect(layoutRectRotated, layoutRect);
  			layoutRectRotated.round(viewRectRotated);
  			angleChanged = false;
  		}
  
  		final View view = getView();
  		if (view != null)
  		{
  			view.layout(viewRectRotated.left, viewRectRotated.top, viewRectRotated.right, viewRectRotated.bottom);
  		}
  	}
  
  	@Override
  	protected void dispatchDraw(Canvas canvas)
  	{
  		canvas.save();
  		canvas.rotate(-angle, getWidth() / 2f, getHeight() / 2f);
  		super.dispatchDraw(canvas);
  		canvas.restore();
  	}
  
  	@Override
  	public ViewParent invalidateChildInParent(int[] location, Rect dirty)
  	{
  		invalidate();
  		return super.invalidateChildInParent(location, dirty);
  	}
  
  	@Override
  	public boolean dispatchTouchEvent(MotionEvent event)
  	{
  		viewTouchPoint[0] = event.getX();
  		viewTouchPoint[1] = event.getY();
  
  		rotateMatrix.mapPoints(childTouchPoint, viewTouchPoint);
  		event.setLocation(childTouchPoint[0], childTouchPoint[1]);
  		return super.dispatchTouchEvent(event);
  	}
  
  	@Override
  	public ViewGroup.LayoutParams generateLayoutParams(AttributeSet attrs)
  	{
  		return new RotateLayout.LayoutParams(getContext(), attrs);
  	}
  
  	@Override
  	protected boolean checkLayoutParams(ViewGroup.LayoutParams layoutParams)
  	{
  		return layoutParams instanceof RotateLayout.LayoutParams;
  	}
  
  	@Override
  	protected ViewGroup.LayoutParams generateLayoutParams(ViewGroup.LayoutParams layoutParams)
  	{
  		return new RotateLayout.LayoutParams(layoutParams);
  	}
  
  	public void setAngle(int angle)
  	{
  		View view = getView();
  		LayoutParams layoutParams = (LayoutParams) view.getLayoutParams();
  		layoutParams.angle = angle;
  		this.angle = angle;
  		this.angleChanged = true;
  	}
  
  	private int				angle;
  
  	private final Matrix	rotateMatrix	= new Matrix();
  
  	private final Rect		viewRectRotated	= new Rect();
  
  	private final RectF		tempRectF1		= new RectF();
  	private final RectF		tempRectF2		= new RectF();
  
  	private final float[]	viewTouchPoint	= new float[2];
  	private final float[]	childTouchPoint	= new float[2];
  
  	private boolean			angleChanged	= true;
  
  }
  