1f533e947035795a485344f4c270e16507f974901Chris Craikpackage com.android.test.hwui; 2f533e947035795a485344f4c270e16507f974901Chris Craik 3f533e947035795a485344f4c270e16507f974901Chris Craikimport android.content.Context; 4f533e947035795a485344f4c270e16507f974901Chris Craikimport android.graphics.Canvas; 5f533e947035795a485344f4c270e16507f974901Chris Craikimport android.graphics.Paint; 6f533e947035795a485344f4c270e16507f974901Chris Craikimport android.graphics.RectF; 7f533e947035795a485344f4c270e16507f974901Chris Craikimport android.os.Bundle; 8f533e947035795a485344f4c270e16507f974901Chris Craik 9f533e947035795a485344f4c270e16507f974901Chris Craikimport android.app.Activity; 10f533e947035795a485344f4c270e16507f974901Chris Craikimport android.util.AttributeSet; 11f666ad7046c0b1b255835f75aeb7d1391067df93John Reckimport android.view.RenderNode; 12f533e947035795a485344f4c270e16507f974901Chris Craikimport android.view.View; 13f533e947035795a485344f4c270e16507f974901Chris Craikimport android.widget.LinearLayout; 14f533e947035795a485344f4c270e16507f974901Chris Craik 15f533e947035795a485344f4c270e16507f974901Chris Craikpublic class ProjectionActivity extends Activity { 16f533e947035795a485344f4c270e16507f974901Chris Craik /** 17f533e947035795a485344f4c270e16507f974901Chris Craik * The content from this view should be projected in between the background of the 18f533e947035795a485344f4c270e16507f974901Chris Craik * ProjecteeLayout and its children, unclipped. 19f533e947035795a485344f4c270e16507f974901Chris Craik * 20f533e947035795a485344f4c270e16507f974901Chris Craik * This view doesn't clip to its bounds (because its parent has clipChildren=false) so that 21f533e947035795a485344f4c270e16507f974901Chris Craik * when it is projected onto the ProjecteeLayout, it draws outside its view bounds. 22f533e947035795a485344f4c270e16507f974901Chris Craik */ 23f533e947035795a485344f4c270e16507f974901Chris Craik public static class ProjectedView extends View { 24f533e947035795a485344f4c270e16507f974901Chris Craik private final Paint mPaint = new Paint(); 25f533e947035795a485344f4c270e16507f974901Chris Craik private final RectF mRectF = new RectF(); 26f533e947035795a485344f4c270e16507f974901Chris Craik 27f533e947035795a485344f4c270e16507f974901Chris Craik public ProjectedView(Context context) { 28f533e947035795a485344f4c270e16507f974901Chris Craik this(context, null); 29f533e947035795a485344f4c270e16507f974901Chris Craik } 30f533e947035795a485344f4c270e16507f974901Chris Craik 31f533e947035795a485344f4c270e16507f974901Chris Craik public ProjectedView(Context context, AttributeSet attrs) { 32f533e947035795a485344f4c270e16507f974901Chris Craik this(context, attrs, 0); 33f533e947035795a485344f4c270e16507f974901Chris Craik } 34f533e947035795a485344f4c270e16507f974901Chris Craik 35f533e947035795a485344f4c270e16507f974901Chris Craik public ProjectedView(Context context, AttributeSet attrs, int defStyleAttr) { 36f533e947035795a485344f4c270e16507f974901Chris Craik super(context, attrs, defStyleAttr); 37f533e947035795a485344f4c270e16507f974901Chris Craik 38f533e947035795a485344f4c270e16507f974901Chris Craik setOnClickListener(new OnClickListener() { 39f533e947035795a485344f4c270e16507f974901Chris Craik boolean toggle = false; 40f533e947035795a485344f4c270e16507f974901Chris Craik @Override 41f533e947035795a485344f4c270e16507f974901Chris Craik public void onClick(View v) { 42f533e947035795a485344f4c270e16507f974901Chris Craik toggle = !toggle; 43f533e947035795a485344f4c270e16507f974901Chris Craik setProject(toggle); 44f533e947035795a485344f4c270e16507f974901Chris Craik } 45f533e947035795a485344f4c270e16507f974901Chris Craik }); 46f533e947035795a485344f4c270e16507f974901Chris Craik } 47f533e947035795a485344f4c270e16507f974901Chris Craik 48f533e947035795a485344f4c270e16507f974901Chris Craik private void setProject(boolean value) { 49f666ad7046c0b1b255835f75aeb7d1391067df93John Reck RenderNode displayList = getDisplayList(); 50f533e947035795a485344f4c270e16507f974901Chris Craik if (displayList != null) { 516657a6c53930eb0ff8d03317eb10ea7ddb0c49b4Chris Craik displayList.setProjectBackwards(value); 52f533e947035795a485344f4c270e16507f974901Chris Craik } 53f533e947035795a485344f4c270e16507f974901Chris Craik // NOTE: we can't invalidate ProjectedView for the redraw because: 54f533e947035795a485344f4c270e16507f974901Chris Craik // 1) the view won't preserve displayList properties that it doesn't know about 55f533e947035795a485344f4c270e16507f974901Chris Craik // 2) the damage rect won't be big enough 56f533e947035795a485344f4c270e16507f974901Chris Craik 57f533e947035795a485344f4c270e16507f974901Chris Craik // instead, twiddle properties on the container, so that enough area of the screen is 58f533e947035795a485344f4c270e16507f974901Chris Craik // redrawn without rerecording any DisplayLists. 59f533e947035795a485344f4c270e16507f974901Chris Craik container.setTranslationX(100f); 60f533e947035795a485344f4c270e16507f974901Chris Craik container.setTranslationX(0.0f); 61f533e947035795a485344f4c270e16507f974901Chris Craik } 62f533e947035795a485344f4c270e16507f974901Chris Craik 63f533e947035795a485344f4c270e16507f974901Chris Craik @Override 64f533e947035795a485344f4c270e16507f974901Chris Craik protected void onDraw(Canvas canvas) { 65f533e947035795a485344f4c270e16507f974901Chris Craik // TODO: set projection flag 66f533e947035795a485344f4c270e16507f974901Chris Craik final int w = getWidth(); 67f533e947035795a485344f4c270e16507f974901Chris Craik final int h = getHeight(); 68f533e947035795a485344f4c270e16507f974901Chris Craik mRectF.set(0, -h, w, 2 * h); 69f533e947035795a485344f4c270e16507f974901Chris Craik mPaint.setAntiAlias(true); 70f533e947035795a485344f4c270e16507f974901Chris Craik mPaint.setColor(0x5f00ff00); 71f533e947035795a485344f4c270e16507f974901Chris Craik canvas.drawOval(mRectF, mPaint); 72f533e947035795a485344f4c270e16507f974901Chris Craik } 73f533e947035795a485344f4c270e16507f974901Chris Craik } 74f533e947035795a485344f4c270e16507f974901Chris Craik 75f533e947035795a485344f4c270e16507f974901Chris Craik static View container; 76f533e947035795a485344f4c270e16507f974901Chris Craik 77f533e947035795a485344f4c270e16507f974901Chris Craik @Override 78f533e947035795a485344f4c270e16507f974901Chris Craik protected void onCreate(Bundle savedInstanceState) { 79f533e947035795a485344f4c270e16507f974901Chris Craik super.onCreate(savedInstanceState); 80f533e947035795a485344f4c270e16507f974901Chris Craik setContentView(R.layout.projection); 81f533e947035795a485344f4c270e16507f974901Chris Craik container = findViewById(R.id.container); 82f533e947035795a485344f4c270e16507f974901Chris Craik } 83f533e947035795a485344f4c270e16507f974901Chris Craik} 84