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