ShadowView.java revision 19d90b633936ae8dacbc7b09a8e44b2ad90be497
133873d2b41a5cd2597b20a4e88eb8942944c0f23Tyler Schultzpackage com.xtremelabs.robolectric.shadows;
26eedf728138e6f79fa898ff3e31bf61c9b1151dChristian Williams & Tyler Schulz
36eedf728138e6f79fa898ff3e31bf61c9b1151dChristian Williams & Tyler Schulzimport android.content.Context;
46eedf728138e6f79fa898ff3e31bf61c9b1151dChristian Williams & Tyler Schulzimport android.content.res.Resources;
5684ccc2fc5a1c79aa45af22b95c37f7c509a00c1Christian Williamsimport android.util.AttributeSet;
6924f851cb0ec279b6974744ce623f25bdc657551Ryan Richardimport android.view.MotionEvent;
76eedf728138e6f79fa898ff3e31bf61c9b1151dChristian Williams & Tyler Schulzimport android.view.View;
8d4f5daf12f1d112cf06b8b8914437ed6c0b3a677Ryan Richard & Tyler Schultzimport android.view.ViewGroup;
95411bf7cde998b5c2e70b69fe3d7227b6783ab7cChristian Williamsimport android.view.ViewParent;
105101cf6874bcc7ceef92354819497ea9cea04c22Phil Goodwin & Tyler Schultzimport com.xtremelabs.robolectric.res.ViewLoader;
11a2043a8fff01f3e2d9a5e30dd1cf5fb6a5342f4dTyler Schultzimport com.xtremelabs.robolectric.util.Implementation;
12a2043a8fff01f3e2d9a5e30dd1cf5fb6a5342f4dTyler Schultzimport com.xtremelabs.robolectric.util.Implements;
134a7b7902404d0c3743f96c043e3cc6b9069cf438Christian Williamsimport com.xtremelabs.robolectric.util.RealObject;
146eedf728138e6f79fa898ff3e31bf61c9b1151dChristian Williams & Tyler Schulz
1586e98619f5f1b5f6b1fd5742ba911d7ebc83c2ddChristian Williamsimport java.io.PrintStream;
1651fe0b279e9f5568683d9ef67921f922a51c05d5Christian Williams & Tyler Schultzimport java.util.HashMap;
1751fe0b279e9f5568683d9ef67921f922a51c05d5Christian Williams & Tyler Schultzimport java.util.Map;
18c6f46aeb970c9111e2e79b806451f63b4853950bIan Fisher & Tyler Schultz
1986e98619f5f1b5f6b1fd5742ba911d7ebc83c2ddChristian Williamsimport static com.xtremelabs.robolectric.Robolectric.shadowOf;
2019d90b633936ae8dacbc7b09a8e44b2ad90be497Phil Goodwin & Tyler Schultzimport static java.lang.Boolean.TRUE;
2186e98619f5f1b5f6b1fd5742ba911d7ebc83c2ddChristian Williams
22ac58b328bde3c77d1d9687408e547faad3b77e2bPhil Goodwin/**
23ac58b328bde3c77d1d9687408e547faad3b77e2bPhil Goodwin * Shadow implementation of {@code View} that simulates the behavior of this class. Supports listeners, focusability
24ac58b328bde3c77d1d9687408e547faad3b77e2bPhil Goodwin * (but not focus order), resource loading, visibility, tags, and tracks the size and shape of the view.
25ac58b328bde3c77d1d9687408e547faad3b77e2bPhil Goodwin */
26198b49fe81283e340891361045a8bdeb01f35e04Tyler Schultz@SuppressWarnings({"UnusedDeclaration"})
270b378afcde0200166e546c46a7642015accfce49Christian Williams & Ian Fisher@Implements(View.class)
28afe0a89d904a7fe2f5980b9deb26cc3240192459Christian Williamspublic class ShadowView {
29a89236397e869467b3fc6f7208f551da61235795Christian Williams & Tyler Schultz    @Deprecated
30f33e228a6f3eed1c97488df2ca30da315324aa1eHarry Ugol    public static final int UNINITIALIZED_ATTRIBUTE = -1000;
31f33e228a6f3eed1c97488df2ca30da315324aa1eHarry Ugol
324a7b7902404d0c3743f96c043e3cc6b9069cf438Christian Williams    @RealObject protected View realView;
336eedf728138e6f79fa898ff3e31bf61c9b1151dChristian Williams & Tyler Schulz
346eedf728138e6f79fa898ff3e31bf61c9b1151dChristian Williams & Tyler Schulz    private int id;
35afe0a89d904a7fe2f5980b9deb26cc3240192459Christian Williams    ShadowView parent;
366eedf728138e6f79fa898ff3e31bf61c9b1151dChristian Williams & Tyler Schulz    private Context context;
374d709f74a8a630e677915cff8fba5e8b4888800fChristian Williams & Phil Goodwin    private boolean selected;
38810ca4e6f0dc6d69504b3e03ef61155f10083fbeChristian Williams & Joe Moore    private View.OnClickListener onClickListener;
39c6f46aeb970c9111e2e79b806451f63b4853950bIan Fisher & Tyler Schultz    private Object tag;
40775ccf7ae53d9b4c77d3adf2514f26747cebd89cIan Fisher & Ryan Richard    private boolean enabled = true;
414d709f74a8a630e677915cff8fba5e8b4888800fChristian Williams & Phil Goodwin    private int visibility = View.VISIBLE;
424d709f74a8a630e677915cff8fba5e8b4888800fChristian Williams & Phil Goodwin    int left;
434d709f74a8a630e677915cff8fba5e8b4888800fChristian Williams & Phil Goodwin    int top;
444d709f74a8a630e677915cff8fba5e8b4888800fChristian Williams & Phil Goodwin    int right;
454d709f74a8a630e677915cff8fba5e8b4888800fChristian Williams & Phil Goodwin    int bottom;
464d709f74a8a630e677915cff8fba5e8b4888800fChristian Williams & Phil Goodwin    private int paddingLeft;
474d709f74a8a630e677915cff8fba5e8b4888800fChristian Williams & Phil Goodwin    private int paddingTop;
484d709f74a8a630e677915cff8fba5e8b4888800fChristian Williams & Phil Goodwin    private int paddingRight;
494d709f74a8a630e677915cff8fba5e8b4888800fChristian Williams & Phil Goodwin    private int paddingBottom;
504d709f74a8a630e677915cff8fba5e8b4888800fChristian Williams & Phil Goodwin    private ViewGroup.LayoutParams layoutParams = new ViewGroup.LayoutParams(0, 0);
5144ade170c5bc611222ed25d5b1f8e7745104057dChristian Williams    private Map<Integer, Object> tags = new HashMap<Integer, Object>();
524d709f74a8a630e677915cff8fba5e8b4888800fChristian Williams & Phil Goodwin    private boolean clickable;
53254044cea0df7e6aef3ce33c98a5003a6eba0512Christian Williams & Phil Goodwin    protected boolean focusable;
549729911f8638b6bb4d55b3d67e6d68a6b3f19dc7Phil Goodwin    boolean focusableInTouchMode;
554d709f74a8a630e677915cff8fba5e8b4888800fChristian Williams & Phil Goodwin    private int backgroundResourceId = -1;
565411bf7cde998b5c2e70b69fe3d7227b6783ab7cChristian Williams    protected View.OnKeyListener onKeyListener;
574d709f74a8a630e677915cff8fba5e8b4888800fChristian Williams & Phil Goodwin    private boolean isFocused;
585411bf7cde998b5c2e70b69fe3d7227b6783ab7cChristian Williams    private View.OnFocusChangeListener onFocusChangeListener;
594d709f74a8a630e677915cff8fba5e8b4888800fChristian Williams & Phil Goodwin    private boolean wasInvalidated;
60924f851cb0ec279b6974744ce623f25bdc657551Ryan Richard    private View.OnTouchListener onTouchListener;
616eedf728138e6f79fa898ff3e31bf61c9b1151dChristian Williams & Tyler Schulz
626eedf728138e6f79fa898ff3e31bf61c9b1151dChristian Williams & Tyler Schulz    public void __constructor__(Context context) {
636eedf728138e6f79fa898ff3e31bf61c9b1151dChristian Williams & Tyler Schulz        this.context = context;
646eedf728138e6f79fa898ff3e31bf61c9b1151dChristian Williams & Tyler Schulz    }
656eedf728138e6f79fa898ff3e31bf61c9b1151dChristian Williams & Tyler Schulz
66684ccc2fc5a1c79aa45af22b95c37f7c509a00c1Christian Williams    public void __constructor__(Context context, AttributeSet attrs) {
67684ccc2fc5a1c79aa45af22b95c37f7c509a00c1Christian Williams        __constructor__(context);
68684ccc2fc5a1c79aa45af22b95c37f7c509a00c1Christian Williams    }
69684ccc2fc5a1c79aa45af22b95c37f7c509a00c1Christian Williams
70de9feed5ddf1d91a3e76cbc71712c36a7652201eChristian Williams    @Implementation
716eedf728138e6f79fa898ff3e31bf61c9b1151dChristian Williams & Tyler Schulz    public void setId(int id) {
726eedf728138e6f79fa898ff3e31bf61c9b1151dChristian Williams & Tyler Schulz        this.id = id;
736eedf728138e6f79fa898ff3e31bf61c9b1151dChristian Williams & Tyler Schulz    }
746eedf728138e6f79fa898ff3e31bf61c9b1151dChristian Williams & Tyler Schulz
75de9feed5ddf1d91a3e76cbc71712c36a7652201eChristian Williams    @Implementation
76cc4bd26d94f6eba2a0dc3dae0065c8df2296a95eIan Fisher & Tyler Schultz    public void setClickable(boolean clickable) {
77cc4bd26d94f6eba2a0dc3dae0065c8df2296a95eIan Fisher & Tyler Schultz        this.clickable = clickable;
78cc4bd26d94f6eba2a0dc3dae0065c8df2296a95eIan Fisher & Tyler Schultz    }
79cc4bd26d94f6eba2a0dc3dae0065c8df2296a95eIan Fisher & Tyler Schultz
80ac58b328bde3c77d1d9687408e547faad3b77e2bPhil Goodwin    /**
81ac58b328bde3c77d1d9687408e547faad3b77e2bPhil Goodwin     * Also sets focusable in touch mode to false if {@code focusable} is false, which is the Android behavior.
82ac58b328bde3c77d1d9687408e547faad3b77e2bPhil Goodwin     *
83ac58b328bde3c77d1d9687408e547faad3b77e2bPhil Goodwin     * @param focusable the new status of the {@code View}'s focusability
84ac58b328bde3c77d1d9687408e547faad3b77e2bPhil Goodwin     */
85de9feed5ddf1d91a3e76cbc71712c36a7652201eChristian Williams    @Implementation
86cc4bd26d94f6eba2a0dc3dae0065c8df2296a95eIan Fisher & Tyler Schultz    public void setFocusable(boolean focusable) {
87cc4bd26d94f6eba2a0dc3dae0065c8df2296a95eIan Fisher & Tyler Schultz        this.focusable = focusable;
88adfaceabbda4c8c51f24a0def8926075bd7306adChristian Williams        if (!focusable) {
89415f3fdab8162ece7185268f71b577f7faa0ba38Phil Goodwin & Ryan Richard            setFocusableInTouchMode(false);
90415f3fdab8162ece7185268f71b577f7faa0ba38Phil Goodwin & Ryan Richard        }
91415f3fdab8162ece7185268f71b577f7faa0ba38Phil Goodwin & Ryan Richard    }
92415f3fdab8162ece7185268f71b577f7faa0ba38Phil Goodwin & Ryan Richard
93415f3fdab8162ece7185268f71b577f7faa0ba38Phil Goodwin & Ryan Richard    @Implementation
94415f3fdab8162ece7185268f71b577f7faa0ba38Phil Goodwin & Ryan Richard    public final boolean isFocusableInTouchMode() {
95415f3fdab8162ece7185268f71b577f7faa0ba38Phil Goodwin & Ryan Richard        return focusableInTouchMode;
96415f3fdab8162ece7185268f71b577f7faa0ba38Phil Goodwin & Ryan Richard    }
97415f3fdab8162ece7185268f71b577f7faa0ba38Phil Goodwin & Ryan Richard
98ac58b328bde3c77d1d9687408e547faad3b77e2bPhil Goodwin    /**
99ac58b328bde3c77d1d9687408e547faad3b77e2bPhil Goodwin     * Also sets focusable to true if {@code focusableInTouchMode} is true, which is the Android behavior.
100ac58b328bde3c77d1d9687408e547faad3b77e2bPhil Goodwin     *
101ac58b328bde3c77d1d9687408e547faad3b77e2bPhil Goodwin     * @param focusableInTouchMode the new status of the {@code View}'s touch mode focusability
102ac58b328bde3c77d1d9687408e547faad3b77e2bPhil Goodwin     */
103415f3fdab8162ece7185268f71b577f7faa0ba38Phil Goodwin & Ryan Richard    @Implementation
104415f3fdab8162ece7185268f71b577f7faa0ba38Phil Goodwin & Ryan Richard    public void setFocusableInTouchMode(boolean focusableInTouchMode) {
105415f3fdab8162ece7185268f71b577f7faa0ba38Phil Goodwin & Ryan Richard        this.focusableInTouchMode = focusableInTouchMode;
106adfaceabbda4c8c51f24a0def8926075bd7306adChristian Williams        if (focusableInTouchMode) {
107415f3fdab8162ece7185268f71b577f7faa0ba38Phil Goodwin & Ryan Richard            setFocusable(true);
108415f3fdab8162ece7185268f71b577f7faa0ba38Phil Goodwin & Ryan Richard        }
109cc4bd26d94f6eba2a0dc3dae0065c8df2296a95eIan Fisher & Tyler Schultz    }
110cc4bd26d94f6eba2a0dc3dae0065c8df2296a95eIan Fisher & Tyler Schultz
111de9feed5ddf1d91a3e76cbc71712c36a7652201eChristian Williams    @Implementation
112254044cea0df7e6aef3ce33c98a5003a6eba0512Christian Williams & Phil Goodwin    public boolean isFocusable() {
113254044cea0df7e6aef3ce33c98a5003a6eba0512Christian Williams & Phil Goodwin        return focusable;
114254044cea0df7e6aef3ce33c98a5003a6eba0512Christian Williams & Phil Goodwin    }
115254044cea0df7e6aef3ce33c98a5003a6eba0512Christian Williams & Phil Goodwin
116254044cea0df7e6aef3ce33c98a5003a6eba0512Christian Williams & Phil Goodwin    @Implementation
1176eedf728138e6f79fa898ff3e31bf61c9b1151dChristian Williams & Tyler Schulz    public int getId() {
1186eedf728138e6f79fa898ff3e31bf61c9b1151dChristian Williams & Tyler Schulz        return id;
1196eedf728138e6f79fa898ff3e31bf61c9b1151dChristian Williams & Tyler Schulz    }
1206eedf728138e6f79fa898ff3e31bf61c9b1151dChristian Williams & Tyler Schulz
121ac58b328bde3c77d1d9687408e547faad3b77e2bPhil Goodwin    /**
122ac58b328bde3c77d1d9687408e547faad3b77e2bPhil Goodwin     * Simulates the inflating of the requested resource.
123ac58b328bde3c77d1d9687408e547faad3b77e2bPhil Goodwin     *
1248de53d85207b90879fd242796941d526277b1245Phil Goodwin & Tyler Schultz     * @param context  the context from which to obtain a layout inflater
125ac58b328bde3c77d1d9687408e547faad3b77e2bPhil Goodwin     * @param resource the ID of the resource to inflate
1268de53d85207b90879fd242796941d526277b1245Phil Goodwin & Tyler Schultz     * @param root     the {@code ViewGroup} to add the inflated {@code View} to
127ac58b328bde3c77d1d9687408e547faad3b77e2bPhil Goodwin     * @return the inflated View
128ac58b328bde3c77d1d9687408e547faad3b77e2bPhil Goodwin     */
129de9feed5ddf1d91a3e76cbc71712c36a7652201eChristian Williams    @Implementation
130a66c979cb64d406c1646a0909bd9a0b6b6ccd802Ian Fisher & Tyler Schultz    public static View inflate(Context context, int resource, ViewGroup root) {
131afe0a89d904a7fe2f5980b9deb26cc3240192459Christian Williams        View view = ShadowLayoutInflater.from(context).inflate(resource, root);
132a66c979cb64d406c1646a0909bd9a0b6b6ccd802Ian Fisher & Tyler Schultz        if (root != null) {
133a66c979cb64d406c1646a0909bd9a0b6b6ccd802Ian Fisher & Tyler Schultz            root.addView(view);
134a66c979cb64d406c1646a0909bd9a0b6b6ccd802Ian Fisher & Tyler Schultz        }
135a66c979cb64d406c1646a0909bd9a0b6b6ccd802Ian Fisher & Tyler Schultz        return view;
136a66c979cb64d406c1646a0909bd9a0b6b6ccd802Ian Fisher & Tyler Schultz    }
137a66c979cb64d406c1646a0909bd9a0b6b6ccd802Ian Fisher & Tyler Schultz
138ac58b328bde3c77d1d9687408e547faad3b77e2bPhil Goodwin    /**
139ac58b328bde3c77d1d9687408e547faad3b77e2bPhil Goodwin     * Finds this {@code View} if it's ID is passed in, returns {@code null} otherwise
140ac58b328bde3c77d1d9687408e547faad3b77e2bPhil Goodwin     *
141ac58b328bde3c77d1d9687408e547faad3b77e2bPhil Goodwin     * @param id the id of the {@code View} to find
142ac58b328bde3c77d1d9687408e547faad3b77e2bPhil Goodwin     * @return the {@code View}, if found, {@code null} otherwise
143ac58b328bde3c77d1d9687408e547faad3b77e2bPhil Goodwin     */
144de9feed5ddf1d91a3e76cbc71712c36a7652201eChristian Williams    @Implementation
1456eedf728138e6f79fa898ff3e31bf61c9b1151dChristian Williams & Tyler Schulz    public View findViewById(int id) {
146e617325bfe357b73644421064cae37e0a033eed7Christian Williams & Tyler Schulz        if (id == this.id) {
147e617325bfe357b73644421064cae37e0a033eed7Christian Williams & Tyler Schulz            return realView;
148e617325bfe357b73644421064cae37e0a033eed7Christian Williams & Tyler Schulz        }
1496eedf728138e6f79fa898ff3e31bf61c9b1151dChristian Williams & Tyler Schulz
1506eedf728138e6f79fa898ff3e31bf61c9b1151dChristian Williams & Tyler Schulz        return null;
1516eedf728138e6f79fa898ff3e31bf61c9b1151dChristian Williams & Tyler Schulz    }
1526eedf728138e6f79fa898ff3e31bf61c9b1151dChristian Williams & Tyler Schulz
153de9feed5ddf1d91a3e76cbc71712c36a7652201eChristian Williams    @Implementation
1540c40acb66824054e469b3afbc3609ba39bbdac1cChristian Williams & Harry Ugol    public View getRootView() {
155afe0a89d904a7fe2f5980b9deb26cc3240192459Christian Williams        ShadowView root = this;
156adfaceabbda4c8c51f24a0def8926075bd7306adChristian Williams        while (root.parent != null) {
1570c40acb66824054e469b3afbc3609ba39bbdac1cChristian Williams & Harry Ugol            root = root.parent;
1580c40acb66824054e469b3afbc3609ba39bbdac1cChristian Williams & Harry Ugol        }
1590c40acb66824054e469b3afbc3609ba39bbdac1cChristian Williams & Harry Ugol        return root.realView;
1600c40acb66824054e469b3afbc3609ba39bbdac1cChristian Williams & Harry Ugol    }
1610c40acb66824054e469b3afbc3609ba39bbdac1cChristian Williams & Harry Ugol
162de9feed5ddf1d91a3e76cbc71712c36a7652201eChristian Williams    @Implementation
163d4f5daf12f1d112cf06b8b8914437ed6c0b3a677Ryan Richard & Tyler Schultz    public ViewGroup.LayoutParams getLayoutParams() {
164d4f5daf12f1d112cf06b8b8914437ed6c0b3a677Ryan Richard & Tyler Schultz        return layoutParams;
165d4f5daf12f1d112cf06b8b8914437ed6c0b3a677Ryan Richard & Tyler Schultz    }
166d4f5daf12f1d112cf06b8b8914437ed6c0b3a677Ryan Richard & Tyler Schultz
167de9feed5ddf1d91a3e76cbc71712c36a7652201eChristian Williams    @Implementation
168b0336c5991d124b6b157b9dc976ade56d00cba3eChristian Williams & Ryan Richard    public void setLayoutParams(ViewGroup.LayoutParams params) {
169b0336c5991d124b6b157b9dc976ade56d00cba3eChristian Williams & Ryan Richard        layoutParams = params;
170b0336c5991d124b6b157b9dc976ade56d00cba3eChristian Williams & Ryan Richard    }
171b0336c5991d124b6b157b9dc976ade56d00cba3eChristian Williams & Ryan Richard
172de9feed5ddf1d91a3e76cbc71712c36a7652201eChristian Williams    @Implementation
1735411bf7cde998b5c2e70b69fe3d7227b6783ab7cChristian Williams    public final ViewParent getParent() {
174a89236397e869467b3fc6f7208f551da61235795Christian Williams & Tyler Schultz        return parent == null ? null : (ViewParent) parent.realView;
1755411bf7cde998b5c2e70b69fe3d7227b6783ab7cChristian Williams    }
1765411bf7cde998b5c2e70b69fe3d7227b6783ab7cChristian Williams
177de9feed5ddf1d91a3e76cbc71712c36a7652201eChristian Williams    @Implementation
1786eedf728138e6f79fa898ff3e31bf61c9b1151dChristian Williams & Tyler Schulz    public final Context getContext() {
1796eedf728138e6f79fa898ff3e31bf61c9b1151dChristian Williams & Tyler Schulz        return context;
1806eedf728138e6f79fa898ff3e31bf61c9b1151dChristian Williams & Tyler Schulz    }
1816eedf728138e6f79fa898ff3e31bf61c9b1151dChristian Williams & Tyler Schulz
182de9feed5ddf1d91a3e76cbc71712c36a7652201eChristian Williams    @Implementation
1836eedf728138e6f79fa898ff3e31bf61c9b1151dChristian Williams & Tyler Schulz    public Resources getResources() {
1846eedf728138e6f79fa898ff3e31bf61c9b1151dChristian Williams & Tyler Schulz        return context.getResources();
1856eedf728138e6f79fa898ff3e31bf61c9b1151dChristian Williams & Tyler Schulz    }
1866eedf728138e6f79fa898ff3e31bf61c9b1151dChristian Williams & Tyler Schulz
187de9feed5ddf1d91a3e76cbc71712c36a7652201eChristian Williams    @Implementation
1884d4b979c716f731be80852e7c04fdbe9862be3f0Ian Fisher & Phil Goodwin    public void setBackgroundResource(int backgroundResourceId) {
1894d4b979c716f731be80852e7c04fdbe9862be3f0Ian Fisher & Phil Goodwin        this.backgroundResourceId = backgroundResourceId;
1904d4b979c716f731be80852e7c04fdbe9862be3f0Ian Fisher & Phil Goodwin    }
1914d4b979c716f731be80852e7c04fdbe9862be3f0Ian Fisher & Phil Goodwin
192de9feed5ddf1d91a3e76cbc71712c36a7652201eChristian Williams    @Implementation
1936eedf728138e6f79fa898ff3e31bf61c9b1151dChristian Williams & Tyler Schulz    public int getVisibility() {
1946eedf728138e6f79fa898ff3e31bf61c9b1151dChristian Williams & Tyler Schulz        return visibility;
1956eedf728138e6f79fa898ff3e31bf61c9b1151dChristian Williams & Tyler Schulz    }
1966eedf728138e6f79fa898ff3e31bf61c9b1151dChristian Williams & Tyler Schulz
197de9feed5ddf1d91a3e76cbc71712c36a7652201eChristian Williams    @Implementation
1986eedf728138e6f79fa898ff3e31bf61c9b1151dChristian Williams & Tyler Schulz    public void setVisibility(int visibility) {
1996eedf728138e6f79fa898ff3e31bf61c9b1151dChristian Williams & Tyler Schulz        this.visibility = visibility;
2006eedf728138e6f79fa898ff3e31bf61c9b1151dChristian Williams & Tyler Schulz    }
201eaadc83b187e31670dec8837d0851c0646522987Joe Moore & Tyler Schultz
202de9feed5ddf1d91a3e76cbc71712c36a7652201eChristian Williams    @Implementation
203eaadc83b187e31670dec8837d0851c0646522987Joe Moore & Tyler Schultz    public void setSelected(boolean selected) {
204eaadc83b187e31670dec8837d0851c0646522987Joe Moore & Tyler Schultz        this.selected = selected;
205eaadc83b187e31670dec8837d0851c0646522987Joe Moore & Tyler Schultz    }
206810ca4e6f0dc6d69504b3e03ef61155f10083fbeChristian Williams & Joe Moore
207de9feed5ddf1d91a3e76cbc71712c36a7652201eChristian Williams    @Implementation
208acb084f15b3b6e2496136ee8449b5d64ccb54939Ryan Richard & Tyler Schultz    public boolean isSelected() {
209acb084f15b3b6e2496136ee8449b5d64ccb54939Ryan Richard & Tyler Schultz        return this.selected;
210acb084f15b3b6e2496136ee8449b5d64ccb54939Ryan Richard & Tyler Schultz    }
211acb084f15b3b6e2496136ee8449b5d64ccb54939Ryan Richard & Tyler Schultz
212de9feed5ddf1d91a3e76cbc71712c36a7652201eChristian Williams    @Implementation
213775ccf7ae53d9b4c77d3adf2514f26747cebd89cIan Fisher & Ryan Richard    public boolean isEnabled() {
214775ccf7ae53d9b4c77d3adf2514f26747cebd89cIan Fisher & Ryan Richard        return this.enabled;
215775ccf7ae53d9b4c77d3adf2514f26747cebd89cIan Fisher & Ryan Richard    }
216adfaceabbda4c8c51f24a0def8926075bd7306adChristian Williams
217de9feed5ddf1d91a3e76cbc71712c36a7652201eChristian Williams    @Implementation
218775ccf7ae53d9b4c77d3adf2514f26747cebd89cIan Fisher & Ryan Richard    public void setEnabled(boolean enabled) {
219775ccf7ae53d9b4c77d3adf2514f26747cebd89cIan Fisher & Ryan Richard        this.enabled = enabled;
220775ccf7ae53d9b4c77d3adf2514f26747cebd89cIan Fisher & Ryan Richard    }
221775ccf7ae53d9b4c77d3adf2514f26747cebd89cIan Fisher & Ryan Richard
222de9feed5ddf1d91a3e76cbc71712c36a7652201eChristian Williams    @Implementation
223810ca4e6f0dc6d69504b3e03ef61155f10083fbeChristian Williams & Joe Moore    public void setOnClickListener(View.OnClickListener onClickListener) {
224810ca4e6f0dc6d69504b3e03ef61155f10083fbeChristian Williams & Joe Moore        this.onClickListener = onClickListener;
225810ca4e6f0dc6d69504b3e03ef61155f10083fbeChristian Williams & Joe Moore    }
226810ca4e6f0dc6d69504b3e03ef61155f10083fbeChristian Williams & Joe Moore
227de9feed5ddf1d91a3e76cbc71712c36a7652201eChristian Williams    @Implementation
228810ca4e6f0dc6d69504b3e03ef61155f10083fbeChristian Williams & Joe Moore    public boolean performClick() {
229810ca4e6f0dc6d69504b3e03ef61155f10083fbeChristian Williams & Joe Moore        if (onClickListener != null) {
230810ca4e6f0dc6d69504b3e03ef61155f10083fbeChristian Williams & Joe Moore            onClickListener.onClick(realView);
231810ca4e6f0dc6d69504b3e03ef61155f10083fbeChristian Williams & Joe Moore            return true;
232810ca4e6f0dc6d69504b3e03ef61155f10083fbeChristian Williams & Joe Moore        } else {
233810ca4e6f0dc6d69504b3e03ef61155f10083fbeChristian Williams & Joe Moore            return false;
234810ca4e6f0dc6d69504b3e03ef61155f10083fbeChristian Williams & Joe Moore        }
235810ca4e6f0dc6d69504b3e03ef61155f10083fbeChristian Williams & Joe Moore    }
236c6f46aeb970c9111e2e79b806451f63b4853950bIan Fisher & Tyler Schultz
237de9feed5ddf1d91a3e76cbc71712c36a7652201eChristian Williams    @Implementation
2385411bf7cde998b5c2e70b69fe3d7227b6783ab7cChristian Williams    public void setOnKeyListener(View.OnKeyListener onKeyListener) {
2395411bf7cde998b5c2e70b69fe3d7227b6783ab7cChristian Williams        this.onKeyListener = onKeyListener;
2405411bf7cde998b5c2e70b69fe3d7227b6783ab7cChristian Williams    }
2415411bf7cde998b5c2e70b69fe3d7227b6783ab7cChristian Williams
242de9feed5ddf1d91a3e76cbc71712c36a7652201eChristian Williams    @Implementation
243c6f46aeb970c9111e2e79b806451f63b4853950bIan Fisher & Tyler Schultz    public Object getTag() {
244c6f46aeb970c9111e2e79b806451f63b4853950bIan Fisher & Tyler Schultz        return this.tag;
245c6f46aeb970c9111e2e79b806451f63b4853950bIan Fisher & Tyler Schultz    }
246c6f46aeb970c9111e2e79b806451f63b4853950bIan Fisher & Tyler Schultz
247de9feed5ddf1d91a3e76cbc71712c36a7652201eChristian Williams    @Implementation
248c6f46aeb970c9111e2e79b806451f63b4853950bIan Fisher & Tyler Schultz    public void setTag(Object tag) {
249c6f46aeb970c9111e2e79b806451f63b4853950bIan Fisher & Tyler Schultz        this.tag = tag;
250c6f46aeb970c9111e2e79b806451f63b4853950bIan Fisher & Tyler Schultz    }
25118141e608f2e60c866a9b7729909e9ce3b9eb588Ian Fisher & Ryan Richard
252de9feed5ddf1d91a3e76cbc71712c36a7652201eChristian Williams    @Implementation
25318141e608f2e60c866a9b7729909e9ce3b9eb588Ian Fisher & Ryan Richard    public final int getHeight() {
254a1ef7deaed03310ed6ec51621125f69bb16ac8fcChristian Williams & Ryan Richard        return bottom - top;
25518141e608f2e60c866a9b7729909e9ce3b9eb588Ian Fisher & Ryan Richard    }
25618141e608f2e60c866a9b7729909e9ce3b9eb588Ian Fisher & Ryan Richard
257de9feed5ddf1d91a3e76cbc71712c36a7652201eChristian Williams    @Implementation
25818141e608f2e60c866a9b7729909e9ce3b9eb588Ian Fisher & Ryan Richard    public final int getWidth() {
259a1ef7deaed03310ed6ec51621125f69bb16ac8fcChristian Williams & Ryan Richard        return right - left;
26018141e608f2e60c866a9b7729909e9ce3b9eb588Ian Fisher & Ryan Richard    }
26118141e608f2e60c866a9b7729909e9ce3b9eb588Ian Fisher & Ryan Richard
262de9feed5ddf1d91a3e76cbc71712c36a7652201eChristian Williams    @Implementation
263924f851cb0ec279b6974744ce623f25bdc657551Ryan Richard    public final int getMeasuredWidth() {
264a1ef7deaed03310ed6ec51621125f69bb16ac8fcChristian Williams & Ryan Richard        return getWidth();
265a1ef7deaed03310ed6ec51621125f69bb16ac8fcChristian Williams & Ryan Richard    }
266a1ef7deaed03310ed6ec51621125f69bb16ac8fcChristian Williams & Ryan Richard
267de9feed5ddf1d91a3e76cbc71712c36a7652201eChristian Williams    @Implementation
268a1ef7deaed03310ed6ec51621125f69bb16ac8fcChristian Williams & Ryan Richard    public final void layout(int l, int t, int r, int b) {
269a1ef7deaed03310ed6ec51621125f69bb16ac8fcChristian Williams & Ryan Richard        left = l;
270a1ef7deaed03310ed6ec51621125f69bb16ac8fcChristian Williams & Ryan Richard        top = t;
271a1ef7deaed03310ed6ec51621125f69bb16ac8fcChristian Williams & Ryan Richard        right = r;
272a1ef7deaed03310ed6ec51621125f69bb16ac8fcChristian Williams & Ryan Richard        bottom = b;
273a1ef7deaed03310ed6ec51621125f69bb16ac8fcChristian Williams & Ryan Richard
274a1ef7deaed03310ed6ec51621125f69bb16ac8fcChristian Williams & Ryan Richard// todo:       realView.onLayout();
275924f851cb0ec279b6974744ce623f25bdc657551Ryan Richard    }
276adfaceabbda4c8c51f24a0def8926075bd7306adChristian Williams
277de9feed5ddf1d91a3e76cbc71712c36a7652201eChristian Williams    @Implementation
27818141e608f2e60c866a9b7729909e9ce3b9eb588Ian Fisher & Ryan Richard    public void setPadding(int left, int top, int right, int bottom) {
27918141e608f2e60c866a9b7729909e9ce3b9eb588Ian Fisher & Ryan Richard        paddingLeft = left;
28018141e608f2e60c866a9b7729909e9ce3b9eb588Ian Fisher & Ryan Richard        paddingTop = top;
28118141e608f2e60c866a9b7729909e9ce3b9eb588Ian Fisher & Ryan Richard        paddingRight = right;
28218141e608f2e60c866a9b7729909e9ce3b9eb588Ian Fisher & Ryan Richard        paddingBottom = bottom;
28318141e608f2e60c866a9b7729909e9ce3b9eb588Ian Fisher & Ryan Richard    }
28418141e608f2e60c866a9b7729909e9ce3b9eb588Ian Fisher & Ryan Richard
285de9feed5ddf1d91a3e76cbc71712c36a7652201eChristian Williams    @Implementation
28618141e608f2e60c866a9b7729909e9ce3b9eb588Ian Fisher & Ryan Richard    public int getPaddingTop() {
28718141e608f2e60c866a9b7729909e9ce3b9eb588Ian Fisher & Ryan Richard        return paddingTop;
28818141e608f2e60c866a9b7729909e9ce3b9eb588Ian Fisher & Ryan Richard    }
28918141e608f2e60c866a9b7729909e9ce3b9eb588Ian Fisher & Ryan Richard
290de9feed5ddf1d91a3e76cbc71712c36a7652201eChristian Williams    @Implementation
29118141e608f2e60c866a9b7729909e9ce3b9eb588Ian Fisher & Ryan Richard    public int getPaddingLeft() {
29218141e608f2e60c866a9b7729909e9ce3b9eb588Ian Fisher & Ryan Richard        return paddingLeft;
29318141e608f2e60c866a9b7729909e9ce3b9eb588Ian Fisher & Ryan Richard    }
29418141e608f2e60c866a9b7729909e9ce3b9eb588Ian Fisher & Ryan Richard
295de9feed5ddf1d91a3e76cbc71712c36a7652201eChristian Williams    @Implementation
29618141e608f2e60c866a9b7729909e9ce3b9eb588Ian Fisher & Ryan Richard    public int getPaddingRight() {
29718141e608f2e60c866a9b7729909e9ce3b9eb588Ian Fisher & Ryan Richard        return paddingRight;
29818141e608f2e60c866a9b7729909e9ce3b9eb588Ian Fisher & Ryan Richard    }
29918141e608f2e60c866a9b7729909e9ce3b9eb588Ian Fisher & Ryan Richard
300de9feed5ddf1d91a3e76cbc71712c36a7652201eChristian Williams    @Implementation
30118141e608f2e60c866a9b7729909e9ce3b9eb588Ian Fisher & Ryan Richard    public int getPaddingBottom() {
30218141e608f2e60c866a9b7729909e9ce3b9eb588Ian Fisher & Ryan Richard        return paddingBottom;
30318141e608f2e60c866a9b7729909e9ce3b9eb588Ian Fisher & Ryan Richard    }
30451fe0b279e9f5568683d9ef67921f922a51c05d5Christian Williams & Tyler Schultz
305de9feed5ddf1d91a3e76cbc71712c36a7652201eChristian Williams    @Implementation
30644ade170c5bc611222ed25d5b1f8e7745104057dChristian Williams    public Object getTag(int key) {
30744ade170c5bc611222ed25d5b1f8e7745104057dChristian Williams        return tags.get(key);
30844ade170c5bc611222ed25d5b1f8e7745104057dChristian Williams    }
30944ade170c5bc611222ed25d5b1f8e7745104057dChristian Williams
310de9feed5ddf1d91a3e76cbc71712c36a7652201eChristian Williams    @Implementation
31144ade170c5bc611222ed25d5b1f8e7745104057dChristian Williams    public void setTag(int key, Object value) {
31244ade170c5bc611222ed25d5b1f8e7745104057dChristian Williams        tags.put(key, value);
31344ade170c5bc611222ed25d5b1f8e7745104057dChristian Williams    }
3145411bf7cde998b5c2e70b69fe3d7227b6783ab7cChristian Williams
31565e90b1b9829e83cac5cdcf8836b9706aa67c072Christian Williams    @Implementation
31665e90b1b9829e83cac5cdcf8836b9706aa67c072Christian Williams    public final boolean requestFocus() {
31765e90b1b9829e83cac5cdcf8836b9706aa67c072Christian Williams        return requestFocus(View.FOCUS_DOWN);
31865e90b1b9829e83cac5cdcf8836b9706aa67c072Christian Williams    }
31965e90b1b9829e83cac5cdcf8836b9706aa67c072Christian Williams
32065e90b1b9829e83cac5cdcf8836b9706aa67c072Christian Williams    @Implementation
32165e90b1b9829e83cac5cdcf8836b9706aa67c072Christian Williams    public final boolean requestFocus(int direction) {
32265e90b1b9829e83cac5cdcf8836b9706aa67c072Christian Williams        setViewFocus(true);
32365e90b1b9829e83cac5cdcf8836b9706aa67c072Christian Williams        return true;
32465e90b1b9829e83cac5cdcf8836b9706aa67c072Christian Williams    }
32565e90b1b9829e83cac5cdcf8836b9706aa67c072Christian Williams
3265411bf7cde998b5c2e70b69fe3d7227b6783ab7cChristian Williams    public void setViewFocus(boolean hasFocus) {
3279729911f8638b6bb4d55b3d67e6d68a6b3f19dc7Phil Goodwin        this.isFocused = hasFocus;
3285411bf7cde998b5c2e70b69fe3d7227b6783ab7cChristian Williams        if (onFocusChangeListener != null) {
3295411bf7cde998b5c2e70b69fe3d7227b6783ab7cChristian Williams            onFocusChangeListener.onFocusChange(realView, hasFocus);
3305411bf7cde998b5c2e70b69fe3d7227b6783ab7cChristian Williams        }
3315411bf7cde998b5c2e70b69fe3d7227b6783ab7cChristian Williams    }
3325411bf7cde998b5c2e70b69fe3d7227b6783ab7cChristian Williams
333de9feed5ddf1d91a3e76cbc71712c36a7652201eChristian Williams    @Implementation
33465e90b1b9829e83cac5cdcf8836b9706aa67c072Christian Williams    public boolean isFocused() {
3359729911f8638b6bb4d55b3d67e6d68a6b3f19dc7Phil Goodwin        return isFocused;
33665e90b1b9829e83cac5cdcf8836b9706aa67c072Christian Williams    }
33765e90b1b9829e83cac5cdcf8836b9706aa67c072Christian Williams
33865e90b1b9829e83cac5cdcf8836b9706aa67c072Christian Williams    @Implementation
3395411bf7cde998b5c2e70b69fe3d7227b6783ab7cChristian Williams    public boolean hasFocus() {
3409729911f8638b6bb4d55b3d67e6d68a6b3f19dc7Phil Goodwin        return isFocused;
3415411bf7cde998b5c2e70b69fe3d7227b6783ab7cChristian Williams    }
3425411bf7cde998b5c2e70b69fe3d7227b6783ab7cChristian Williams
343de9feed5ddf1d91a3e76cbc71712c36a7652201eChristian Williams    @Implementation
34465e90b1b9829e83cac5cdcf8836b9706aa67c072Christian Williams    public void clearFocus() {
34565e90b1b9829e83cac5cdcf8836b9706aa67c072Christian Williams        setViewFocus(false);
34665e90b1b9829e83cac5cdcf8836b9706aa67c072Christian Williams    }
34765e90b1b9829e83cac5cdcf8836b9706aa67c072Christian Williams
34865e90b1b9829e83cac5cdcf8836b9706aa67c072Christian Williams    @Implementation
3495411bf7cde998b5c2e70b69fe3d7227b6783ab7cChristian Williams    public void setOnFocusChangeListener(View.OnFocusChangeListener listener) {
3505411bf7cde998b5c2e70b69fe3d7227b6783ab7cChristian Williams        onFocusChangeListener = listener;
3515411bf7cde998b5c2e70b69fe3d7227b6783ab7cChristian Williams    }
3521c46c94a5affe7beeb8c6bfcb5ec0ed509e5fdbdRyan Richard
353de9feed5ddf1d91a3e76cbc71712c36a7652201eChristian Williams    @Implementation
3541c46c94a5affe7beeb8c6bfcb5ec0ed509e5fdbdRyan Richard    public void invalidate() {
3551c46c94a5affe7beeb8c6bfcb5ec0ed509e5fdbdRyan Richard        wasInvalidated = true;
3561c46c94a5affe7beeb8c6bfcb5ec0ed509e5fdbdRyan Richard    }
357924f851cb0ec279b6974744ce623f25bdc657551Ryan Richard
358de9feed5ddf1d91a3e76cbc71712c36a7652201eChristian Williams    @Implementation
359924f851cb0ec279b6974744ce623f25bdc657551Ryan Richard    public void setOnTouchListener(View.OnTouchListener onTouchListener) {
360924f851cb0ec279b6974744ce623f25bdc657551Ryan Richard        this.onTouchListener = onTouchListener;
361924f851cb0ec279b6974744ce623f25bdc657551Ryan Richard    }
362924f851cb0ec279b6974744ce623f25bdc657551Ryan Richard
363de9feed5ddf1d91a3e76cbc71712c36a7652201eChristian Williams    @Implementation
364924f851cb0ec279b6974744ce623f25bdc657551Ryan Richard    public boolean dispatchTouchEvent(MotionEvent event) {
365924f851cb0ec279b6974744ce623f25bdc657551Ryan Richard        if (onTouchListener != null) {
366924f851cb0ec279b6974744ce623f25bdc657551Ryan Richard            return onTouchListener.onTouch(realView, event);
367924f851cb0ec279b6974744ce623f25bdc657551Ryan Richard        }
368924f851cb0ec279b6974744ce623f25bdc657551Ryan Richard        return false;
369924f851cb0ec279b6974744ce623f25bdc657551Ryan Richard    }
3702ff94a9e4df5b0d3eb21bda70793b27d9f1f353cChristian Williams & Phil Goodwin
371ac58b328bde3c77d1d9687408e547faad3b77e2bPhil Goodwin    /**
372da9cd404c0db2ebcef4ecfb50836de00b56622f1Christian Williams     * Returns a string representation of this {@code View}. Unless overridden, it will be an empty string.
373ac58b328bde3c77d1d9687408e547faad3b77e2bPhil Goodwin     *
374da9cd404c0db2ebcef4ecfb50836de00b56622f1Christian Williams     * Robolectric extension.
375ac58b328bde3c77d1d9687408e547faad3b77e2bPhil Goodwin     */
3762ff94a9e4df5b0d3eb21bda70793b27d9f1f353cChristian Williams & Phil Goodwin    public String innerText() {
3772ff94a9e4df5b0d3eb21bda70793b27d9f1f353cChristian Williams & Phil Goodwin        return "";
3782ff94a9e4df5b0d3eb21bda70793b27d9f1f353cChristian Williams & Phil Goodwin    }
37986e98619f5f1b5f6b1fd5742ba911d7ebc83c2ddChristian Williams
380ac58b328bde3c77d1d9687408e547faad3b77e2bPhil Goodwin    /**
381ac58b328bde3c77d1d9687408e547faad3b77e2bPhil Goodwin     * Dumps the status of this {@code View} to {@code System.out}
382ac58b328bde3c77d1d9687408e547faad3b77e2bPhil Goodwin     */
38386e98619f5f1b5f6b1fd5742ba911d7ebc83c2ddChristian Williams    public void dump() {
38486e98619f5f1b5f6b1fd5742ba911d7ebc83c2ddChristian Williams        dump(System.out, 0);
38586e98619f5f1b5f6b1fd5742ba911d7ebc83c2ddChristian Williams    }
38686e98619f5f1b5f6b1fd5742ba911d7ebc83c2ddChristian Williams
387ac58b328bde3c77d1d9687408e547faad3b77e2bPhil Goodwin    /**
388ac58b328bde3c77d1d9687408e547faad3b77e2bPhil Goodwin     * Dumps the status of this {@code View} to {@code System.out} at the given indentation level
389ac58b328bde3c77d1d9687408e547faad3b77e2bPhil Goodwin     */
39086e98619f5f1b5f6b1fd5742ba911d7ebc83c2ddChristian Williams    public void dump(PrintStream out, int indent) {
39186e98619f5f1b5f6b1fd5742ba911d7ebc83c2ddChristian Williams        dumpFirstPart(out, indent);
39286e98619f5f1b5f6b1fd5742ba911d7ebc83c2ddChristian Williams        out.println("/>");
39386e98619f5f1b5f6b1fd5742ba911d7ebc83c2ddChristian Williams    }
39486e98619f5f1b5f6b1fd5742ba911d7ebc83c2ddChristian Williams
39586e98619f5f1b5f6b1fd5742ba911d7ebc83c2ddChristian Williams    protected void dumpFirstPart(PrintStream out, int indent) {
39686e98619f5f1b5f6b1fd5742ba911d7ebc83c2ddChristian Williams        dumpIndent(out, indent);
39786e98619f5f1b5f6b1fd5742ba911d7ebc83c2ddChristian Williams
39886e98619f5f1b5f6b1fd5742ba911d7ebc83c2ddChristian Williams        out.print("<" + realView.getClass().getSimpleName());
39986e98619f5f1b5f6b1fd5742ba911d7ebc83c2ddChristian Williams        if (id > 0) {
40086e98619f5f1b5f6b1fd5742ba911d7ebc83c2ddChristian Williams            out.print(" id=\"" + shadowOf(context).getResourceLoader().getNameForId(id) + "\"");
40186e98619f5f1b5f6b1fd5742ba911d7ebc83c2ddChristian Williams        }
40286e98619f5f1b5f6b1fd5742ba911d7ebc83c2ddChristian Williams    }
40386e98619f5f1b5f6b1fd5742ba911d7ebc83c2ddChristian Williams
40486e98619f5f1b5f6b1fd5742ba911d7ebc83c2ddChristian Williams    protected void dumpIndent(PrintStream out, int indent) {
40586e98619f5f1b5f6b1fd5742ba911d7ebc83c2ddChristian Williams        for (int i = 0; i < indent; i++) out.print(" ");
40686e98619f5f1b5f6b1fd5742ba911d7ebc83c2ddChristian Williams    }
4074d709f74a8a630e677915cff8fba5e8b4888800fChristian Williams & Phil Goodwin
408ac58b328bde3c77d1d9687408e547faad3b77e2bPhil Goodwin    /**
409ac58b328bde3c77d1d9687408e547faad3b77e2bPhil Goodwin     * @return left side of the view
410ac58b328bde3c77d1d9687408e547faad3b77e2bPhil Goodwin     */
411bbf6ae3d37d2303d8463094096ef0bb9906fd658Christian Williams    @Implementation
4124d709f74a8a630e677915cff8fba5e8b4888800fChristian Williams & Phil Goodwin    public int getLeft() {
4134d709f74a8a630e677915cff8fba5e8b4888800fChristian Williams & Phil Goodwin        return left;
4144d709f74a8a630e677915cff8fba5e8b4888800fChristian Williams & Phil Goodwin    }
4154d709f74a8a630e677915cff8fba5e8b4888800fChristian Williams & Phil Goodwin
416ac58b328bde3c77d1d9687408e547faad3b77e2bPhil Goodwin    /**
417ac58b328bde3c77d1d9687408e547faad3b77e2bPhil Goodwin     * @return top coordinate of the view
418ac58b328bde3c77d1d9687408e547faad3b77e2bPhil Goodwin     */
419bbf6ae3d37d2303d8463094096ef0bb9906fd658Christian Williams    @Implementation
4204d709f74a8a630e677915cff8fba5e8b4888800fChristian Williams & Phil Goodwin    public int getTop() {
4214d709f74a8a630e677915cff8fba5e8b4888800fChristian Williams & Phil Goodwin        return top;
4224d709f74a8a630e677915cff8fba5e8b4888800fChristian Williams & Phil Goodwin    }
4234d709f74a8a630e677915cff8fba5e8b4888800fChristian Williams & Phil Goodwin
424ac58b328bde3c77d1d9687408e547faad3b77e2bPhil Goodwin    /**
425ac58b328bde3c77d1d9687408e547faad3b77e2bPhil Goodwin     * @return right side of the view
426ac58b328bde3c77d1d9687408e547faad3b77e2bPhil Goodwin     */
427bbf6ae3d37d2303d8463094096ef0bb9906fd658Christian Williams    @Implementation
4284d709f74a8a630e677915cff8fba5e8b4888800fChristian Williams & Phil Goodwin    public int getRight() {
4294d709f74a8a630e677915cff8fba5e8b4888800fChristian Williams & Phil Goodwin        return right;
4304d709f74a8a630e677915cff8fba5e8b4888800fChristian Williams & Phil Goodwin    }
4314d709f74a8a630e677915cff8fba5e8b4888800fChristian Williams & Phil Goodwin
432ac58b328bde3c77d1d9687408e547faad3b77e2bPhil Goodwin    /**
433ac58b328bde3c77d1d9687408e547faad3b77e2bPhil Goodwin     * @return bottom coordinate of the view
434ac58b328bde3c77d1d9687408e547faad3b77e2bPhil Goodwin     */
435bbf6ae3d37d2303d8463094096ef0bb9906fd658Christian Williams    @Implementation
4364d709f74a8a630e677915cff8fba5e8b4888800fChristian Williams & Phil Goodwin    public int getBottom() {
4374d709f74a8a630e677915cff8fba5e8b4888800fChristian Williams & Phil Goodwin        return bottom;
4384d709f74a8a630e677915cff8fba5e8b4888800fChristian Williams & Phil Goodwin    }
4394d709f74a8a630e677915cff8fba5e8b4888800fChristian Williams & Phil Goodwin
440ac58b328bde3c77d1d9687408e547faad3b77e2bPhil Goodwin    /**
441ac58b328bde3c77d1d9687408e547faad3b77e2bPhil Goodwin     * @return whether the view is clickable
442ac58b328bde3c77d1d9687408e547faad3b77e2bPhil Goodwin     */
443bbf6ae3d37d2303d8463094096ef0bb9906fd658Christian Williams    @Implementation
4444d709f74a8a630e677915cff8fba5e8b4888800fChristian Williams & Phil Goodwin    public boolean isClickable() {
4454d709f74a8a630e677915cff8fba5e8b4888800fChristian Williams & Phil Goodwin        return clickable;
4464d709f74a8a630e677915cff8fba5e8b4888800fChristian Williams & Phil Goodwin    }
4474d709f74a8a630e677915cff8fba5e8b4888800fChristian Williams & Phil Goodwin
448ac58b328bde3c77d1d9687408e547faad3b77e2bPhil Goodwin    /**
449de2143a1bef92c4ef270d3391b9201e8b8af7051Christian Williams     * Non-Android accessor.
450ac58b328bde3c77d1d9687408e547faad3b77e2bPhil Goodwin     *
451ac58b328bde3c77d1d9687408e547faad3b77e2bPhil Goodwin     * @return the resource ID of this views background
452ac58b328bde3c77d1d9687408e547faad3b77e2bPhil Goodwin     */
4534d709f74a8a630e677915cff8fba5e8b4888800fChristian Williams & Phil Goodwin    public int getBackgroundResourceId() {
4544d709f74a8a630e677915cff8fba5e8b4888800fChristian Williams & Phil Goodwin        return backgroundResourceId;
4554d709f74a8a630e677915cff8fba5e8b4888800fChristian Williams & Phil Goodwin    }
4564d709f74a8a630e677915cff8fba5e8b4888800fChristian Williams & Phil Goodwin
457ac58b328bde3c77d1d9687408e547faad3b77e2bPhil Goodwin    /**
458de2143a1bef92c4ef270d3391b9201e8b8af7051Christian Williams     * Non-Android accessor.
459ac58b328bde3c77d1d9687408e547faad3b77e2bPhil Goodwin     *
460ac58b328bde3c77d1d9687408e547faad3b77e2bPhil Goodwin     * @return whether or not {@link #invalidate()} has been called
461ac58b328bde3c77d1d9687408e547faad3b77e2bPhil Goodwin     */
4624d709f74a8a630e677915cff8fba5e8b4888800fChristian Williams & Phil Goodwin    public boolean wasInvalidated() {
4634d709f74a8a630e677915cff8fba5e8b4888800fChristian Williams & Phil Goodwin        return wasInvalidated;
4644d709f74a8a630e677915cff8fba5e8b4888800fChristian Williams & Phil Goodwin    }
4654d709f74a8a630e677915cff8fba5e8b4888800fChristian Williams & Phil Goodwin
466ac58b328bde3c77d1d9687408e547faad3b77e2bPhil Goodwin    /**
467ac58b328bde3c77d1d9687408e547faad3b77e2bPhil Goodwin     * Clears the wasInvalidated flag
468ac58b328bde3c77d1d9687408e547faad3b77e2bPhil Goodwin     */
4694d709f74a8a630e677915cff8fba5e8b4888800fChristian Williams & Phil Goodwin    public void clearWasInvalidated() {
4704d709f74a8a630e677915cff8fba5e8b4888800fChristian Williams & Phil Goodwin        wasInvalidated = false;
4714d709f74a8a630e677915cff8fba5e8b4888800fChristian Williams & Phil Goodwin    }
4724d709f74a8a630e677915cff8fba5e8b4888800fChristian Williams & Phil Goodwin
473ac58b328bde3c77d1d9687408e547faad3b77e2bPhil Goodwin    /**
474de2143a1bef92c4ef270d3391b9201e8b8af7051Christian Williams     * Non-Android accessor.
475ac58b328bde3c77d1d9687408e547faad3b77e2bPhil Goodwin     */
4764d709f74a8a630e677915cff8fba5e8b4888800fChristian Williams & Phil Goodwin    public void setLeft(int left) {
4774d709f74a8a630e677915cff8fba5e8b4888800fChristian Williams & Phil Goodwin        this.left = left;
4784d709f74a8a630e677915cff8fba5e8b4888800fChristian Williams & Phil Goodwin    }
4794d709f74a8a630e677915cff8fba5e8b4888800fChristian Williams & Phil Goodwin
480ac58b328bde3c77d1d9687408e547faad3b77e2bPhil Goodwin    /**
481de2143a1bef92c4ef270d3391b9201e8b8af7051Christian Williams     * Non-Android accessor.
482ac58b328bde3c77d1d9687408e547faad3b77e2bPhil Goodwin     */
4834d709f74a8a630e677915cff8fba5e8b4888800fChristian Williams & Phil Goodwin    public void setTop(int top) {
4844d709f74a8a630e677915cff8fba5e8b4888800fChristian Williams & Phil Goodwin        this.top = top;
4854d709f74a8a630e677915cff8fba5e8b4888800fChristian Williams & Phil Goodwin    }
4864d709f74a8a630e677915cff8fba5e8b4888800fChristian Williams & Phil Goodwin
487ac58b328bde3c77d1d9687408e547faad3b77e2bPhil Goodwin    /**
488de2143a1bef92c4ef270d3391b9201e8b8af7051Christian Williams     * Non-Android accessor.
489ac58b328bde3c77d1d9687408e547faad3b77e2bPhil Goodwin     */
4904d709f74a8a630e677915cff8fba5e8b4888800fChristian Williams & Phil Goodwin    public void setRight(int right) {
4914d709f74a8a630e677915cff8fba5e8b4888800fChristian Williams & Phil Goodwin        this.right = right;
4924d709f74a8a630e677915cff8fba5e8b4888800fChristian Williams & Phil Goodwin    }
4934d709f74a8a630e677915cff8fba5e8b4888800fChristian Williams & Phil Goodwin
494ac58b328bde3c77d1d9687408e547faad3b77e2bPhil Goodwin    /**
495de2143a1bef92c4ef270d3391b9201e8b8af7051Christian Williams     * Non-Android accessor.
496ac58b328bde3c77d1d9687408e547faad3b77e2bPhil Goodwin     */
4974d709f74a8a630e677915cff8fba5e8b4888800fChristian Williams & Phil Goodwin    public void setBottom(int bottom) {
4984d709f74a8a630e677915cff8fba5e8b4888800fChristian Williams & Phil Goodwin        this.bottom = bottom;
4994d709f74a8a630e677915cff8fba5e8b4888800fChristian Williams & Phil Goodwin    }
5004d709f74a8a630e677915cff8fba5e8b4888800fChristian Williams & Phil Goodwin
501ac58b328bde3c77d1d9687408e547faad3b77e2bPhil Goodwin    /**
502de2143a1bef92c4ef270d3391b9201e8b8af7051Christian Williams     * Non-Android accessor.
503ac58b328bde3c77d1d9687408e547faad3b77e2bPhil Goodwin     */
5044d709f74a8a630e677915cff8fba5e8b4888800fChristian Williams & Phil Goodwin    public void setPaddingLeft(int paddingLeft) {
5054d709f74a8a630e677915cff8fba5e8b4888800fChristian Williams & Phil Goodwin        this.paddingLeft = paddingLeft;
5064d709f74a8a630e677915cff8fba5e8b4888800fChristian Williams & Phil Goodwin    }
5074d709f74a8a630e677915cff8fba5e8b4888800fChristian Williams & Phil Goodwin
508ac58b328bde3c77d1d9687408e547faad3b77e2bPhil Goodwin    /**
509de2143a1bef92c4ef270d3391b9201e8b8af7051Christian Williams     * Non-Android accessor.
510ac58b328bde3c77d1d9687408e547faad3b77e2bPhil Goodwin     */
5114d709f74a8a630e677915cff8fba5e8b4888800fChristian Williams & Phil Goodwin    public void setPaddingTop(int paddingTop) {
5124d709f74a8a630e677915cff8fba5e8b4888800fChristian Williams & Phil Goodwin        this.paddingTop = paddingTop;
5134d709f74a8a630e677915cff8fba5e8b4888800fChristian Williams & Phil Goodwin    }
5144d709f74a8a630e677915cff8fba5e8b4888800fChristian Williams & Phil Goodwin
515ac58b328bde3c77d1d9687408e547faad3b77e2bPhil Goodwin    /**
516de2143a1bef92c4ef270d3391b9201e8b8af7051Christian Williams     * Non-Android accessor.
517ac58b328bde3c77d1d9687408e547faad3b77e2bPhil Goodwin     */
5184d709f74a8a630e677915cff8fba5e8b4888800fChristian Williams & Phil Goodwin    public void setPaddingRight(int paddingRight) {
5194d709f74a8a630e677915cff8fba5e8b4888800fChristian Williams & Phil Goodwin        this.paddingRight = paddingRight;
5204d709f74a8a630e677915cff8fba5e8b4888800fChristian Williams & Phil Goodwin    }
5214d709f74a8a630e677915cff8fba5e8b4888800fChristian Williams & Phil Goodwin
522ac58b328bde3c77d1d9687408e547faad3b77e2bPhil Goodwin    /**
523de2143a1bef92c4ef270d3391b9201e8b8af7051Christian Williams     * Non-Android accessor.
524ac58b328bde3c77d1d9687408e547faad3b77e2bPhil Goodwin     */
5254d709f74a8a630e677915cff8fba5e8b4888800fChristian Williams & Phil Goodwin    public void setPaddingBottom(int paddingBottom) {
5264d709f74a8a630e677915cff8fba5e8b4888800fChristian Williams & Phil Goodwin        this.paddingBottom = paddingBottom;
5274d709f74a8a630e677915cff8fba5e8b4888800fChristian Williams & Phil Goodwin    }
5284d709f74a8a630e677915cff8fba5e8b4888800fChristian Williams & Phil Goodwin
529ac58b328bde3c77d1d9687408e547faad3b77e2bPhil Goodwin    /**
530de2143a1bef92c4ef270d3391b9201e8b8af7051Christian Williams     * Non-Android accessor.
531ac58b328bde3c77d1d9687408e547faad3b77e2bPhil Goodwin     */
5324d709f74a8a630e677915cff8fba5e8b4888800fChristian Williams & Phil Goodwin    public void setFocused(boolean focused) {
5334d709f74a8a630e677915cff8fba5e8b4888800fChristian Williams & Phil Goodwin        isFocused = focused;
5344d709f74a8a630e677915cff8fba5e8b4888800fChristian Williams & Phil Goodwin    }
5358de53d85207b90879fd242796941d526277b1245Phil Goodwin & Tyler Schultz
5368de53d85207b90879fd242796941d526277b1245Phil Goodwin & Tyler Schultz    /**
5378de53d85207b90879fd242796941d526277b1245Phil Goodwin & Tyler Schultz     * Non-Android accessor.
5388de53d85207b90879fd242796941d526277b1245Phil Goodwin & Tyler Schultz     *
5398de53d85207b90879fd242796941d526277b1245Phil Goodwin & Tyler Schultz     * @return true if this object and all of its ancestors are {@code View.VISIBLE}, returns false if this or
5408de53d85207b90879fd242796941d526277b1245Phil Goodwin & Tyler Schultz     *         any ancestor is not {@code View.VISIBLE}
5418de53d85207b90879fd242796941d526277b1245Phil Goodwin & Tyler Schultz     */
5428de53d85207b90879fd242796941d526277b1245Phil Goodwin & Tyler Schultz    public boolean derivedIsVisible() {
5438de53d85207b90879fd242796941d526277b1245Phil Goodwin & Tyler Schultz        View parent = realView;
5448de53d85207b90879fd242796941d526277b1245Phil Goodwin & Tyler Schultz        while (parent != null) {
5458de53d85207b90879fd242796941d526277b1245Phil Goodwin & Tyler Schultz            if (parent.getVisibility() != View.VISIBLE) {
5468de53d85207b90879fd242796941d526277b1245Phil Goodwin & Tyler Schultz                return false;
5478de53d85207b90879fd242796941d526277b1245Phil Goodwin & Tyler Schultz            }
5488de53d85207b90879fd242796941d526277b1245Phil Goodwin & Tyler Schultz            parent = (View) parent.getParent();
5498de53d85207b90879fd242796941d526277b1245Phil Goodwin & Tyler Schultz        }
5508de53d85207b90879fd242796941d526277b1245Phil Goodwin & Tyler Schultz        return true;
5518de53d85207b90879fd242796941d526277b1245Phil Goodwin & Tyler Schultz    }
552c140c89564a145280adf65188f25303e850d3a9cPhil Goodwin & Tyler Schultz
553c140c89564a145280adf65188f25303e850d3a9cPhil Goodwin & Tyler Schultz    /**
554c140c89564a145280adf65188f25303e850d3a9cPhil Goodwin & Tyler Schultz     * Utility method for clicking on views exposing testing scenarios that are not possible when using the actual app.
555c140c89564a145280adf65188f25303e850d3a9cPhil Goodwin & Tyler Schultz     *
556c140c89564a145280adf65188f25303e850d3a9cPhil Goodwin & Tyler Schultz     * @throws RuntimeException if the view is disabled or if the view or any of its parents are not visible.
557c140c89564a145280adf65188f25303e850d3a9cPhil Goodwin & Tyler Schultz     */
558c140c89564a145280adf65188f25303e850d3a9cPhil Goodwin & Tyler Schultz    public boolean checkedPerformClick() {
559c140c89564a145280adf65188f25303e850d3a9cPhil Goodwin & Tyler Schultz        if (!derivedIsVisible()) {
560c140c89564a145280adf65188f25303e850d3a9cPhil Goodwin & Tyler Schultz            throw new RuntimeException("View is not visible and cannot be clicked");
561c140c89564a145280adf65188f25303e850d3a9cPhil Goodwin & Tyler Schultz        }
562c140c89564a145280adf65188f25303e850d3a9cPhil Goodwin & Tyler Schultz        if (!realView.isEnabled()) {
563c140c89564a145280adf65188f25303e850d3a9cPhil Goodwin & Tyler Schultz            throw new RuntimeException("View is not enabled and cannot be clicked");
564c140c89564a145280adf65188f25303e850d3a9cPhil Goodwin & Tyler Schultz        }
565c140c89564a145280adf65188f25303e850d3a9cPhil Goodwin & Tyler Schultz
566c140c89564a145280adf65188f25303e850d3a9cPhil Goodwin & Tyler Schultz        return realView.performClick();
567c140c89564a145280adf65188f25303e850d3a9cPhil Goodwin & Tyler Schultz    }
5685101cf6874bcc7ceef92354819497ea9cea04c22Phil Goodwin & Tyler Schultz
5695101cf6874bcc7ceef92354819497ea9cea04c22Phil Goodwin & Tyler Schultz    public void applyViewNode(ViewLoader.ViewNode viewNode) {
5705101cf6874bcc7ceef92354819497ea9cea04c22Phil Goodwin & Tyler Schultz        applyVisibilityAttribute(viewNode);
5715101cf6874bcc7ceef92354819497ea9cea04c22Phil Goodwin & Tyler Schultz        applyEnabledAttribute(viewNode);
57219d90b633936ae8dacbc7b09a8e44b2ad90be497Phil Goodwin & Tyler Schultz        applyFocus(viewNode);
5735101cf6874bcc7ceef92354819497ea9cea04c22Phil Goodwin & Tyler Schultz    }
5745101cf6874bcc7ceef92354819497ea9cea04c22Phil Goodwin & Tyler Schultz
5755101cf6874bcc7ceef92354819497ea9cea04c22Phil Goodwin & Tyler Schultz    private void applyVisibilityAttribute(ViewLoader.ViewNode viewNode) {
5765101cf6874bcc7ceef92354819497ea9cea04c22Phil Goodwin & Tyler Schultz        String visibility = viewNode.getAttributeValue("android:visibility");
5775101cf6874bcc7ceef92354819497ea9cea04c22Phil Goodwin & Tyler Schultz        if (visibility != null) {
5785101cf6874bcc7ceef92354819497ea9cea04c22Phil Goodwin & Tyler Schultz            if (visibility.equals("gone")) {
5795101cf6874bcc7ceef92354819497ea9cea04c22Phil Goodwin & Tyler Schultz                setVisibility(View.GONE);
5805101cf6874bcc7ceef92354819497ea9cea04c22Phil Goodwin & Tyler Schultz            } else if (visibility.equals("invisible")) {
5815101cf6874bcc7ceef92354819497ea9cea04c22Phil Goodwin & Tyler Schultz                setVisibility(View.INVISIBLE);
5825101cf6874bcc7ceef92354819497ea9cea04c22Phil Goodwin & Tyler Schultz            }
5835101cf6874bcc7ceef92354819497ea9cea04c22Phil Goodwin & Tyler Schultz        }
5845101cf6874bcc7ceef92354819497ea9cea04c22Phil Goodwin & Tyler Schultz    }
5855101cf6874bcc7ceef92354819497ea9cea04c22Phil Goodwin & Tyler Schultz
5865101cf6874bcc7ceef92354819497ea9cea04c22Phil Goodwin & Tyler Schultz    private void applyEnabledAttribute(ViewLoader.ViewNode viewNode) {
5875101cf6874bcc7ceef92354819497ea9cea04c22Phil Goodwin & Tyler Schultz        Boolean enabled = viewNode.getAttributeAsBool("android:enabled");
5885101cf6874bcc7ceef92354819497ea9cea04c22Phil Goodwin & Tyler Schultz        if (enabled != null) {
5895101cf6874bcc7ceef92354819497ea9cea04c22Phil Goodwin & Tyler Schultz            setEnabled(enabled);
5905101cf6874bcc7ceef92354819497ea9cea04c22Phil Goodwin & Tyler Schultz        }
5915101cf6874bcc7ceef92354819497ea9cea04c22Phil Goodwin & Tyler Schultz    }
59219d90b633936ae8dacbc7b09a8e44b2ad90be497Phil Goodwin & Tyler Schultz
59319d90b633936ae8dacbc7b09a8e44b2ad90be497Phil Goodwin & Tyler Schultz    private void applyFocus(ViewLoader.ViewNode viewNode) {
59419d90b633936ae8dacbc7b09a8e44b2ad90be497Phil Goodwin & Tyler Schultz        checkFocusOverride(viewNode);
59519d90b633936ae8dacbc7b09a8e44b2ad90be497Phil Goodwin & Tyler Schultz
59619d90b633936ae8dacbc7b09a8e44b2ad90be497Phil Goodwin & Tyler Schultz        if (!anyParentHasFocus(realView)) {
59719d90b633936ae8dacbc7b09a8e44b2ad90be497Phil Goodwin & Tyler Schultz            Boolean focusRequested = viewNode.getAttributeAsBool("android:focus");
59819d90b633936ae8dacbc7b09a8e44b2ad90be497Phil Goodwin & Tyler Schultz            if (TRUE.equals(focusRequested) || realView.isFocusableInTouchMode()) {
59919d90b633936ae8dacbc7b09a8e44b2ad90be497Phil Goodwin & Tyler Schultz                realView.requestFocus();
60019d90b633936ae8dacbc7b09a8e44b2ad90be497Phil Goodwin & Tyler Schultz            }
60119d90b633936ae8dacbc7b09a8e44b2ad90be497Phil Goodwin & Tyler Schultz        }
60219d90b633936ae8dacbc7b09a8e44b2ad90be497Phil Goodwin & Tyler Schultz    }
60319d90b633936ae8dacbc7b09a8e44b2ad90be497Phil Goodwin & Tyler Schultz
60419d90b633936ae8dacbc7b09a8e44b2ad90be497Phil Goodwin & Tyler Schultz    private void checkFocusOverride(ViewLoader.ViewNode viewNode) {
60519d90b633936ae8dacbc7b09a8e44b2ad90be497Phil Goodwin & Tyler Schultz        if (viewNode.hasRequestFocusOverride()) {
60619d90b633936ae8dacbc7b09a8e44b2ad90be497Phil Goodwin & Tyler Schultz            View root = realView;
60719d90b633936ae8dacbc7b09a8e44b2ad90be497Phil Goodwin & Tyler Schultz            View parent = (View) root.getParent();
60819d90b633936ae8dacbc7b09a8e44b2ad90be497Phil Goodwin & Tyler Schultz            while (parent != null) {
60919d90b633936ae8dacbc7b09a8e44b2ad90be497Phil Goodwin & Tyler Schultz                root = parent;
61019d90b633936ae8dacbc7b09a8e44b2ad90be497Phil Goodwin & Tyler Schultz                parent = (View) root.getParent();
61119d90b633936ae8dacbc7b09a8e44b2ad90be497Phil Goodwin & Tyler Schultz            }
61219d90b633936ae8dacbc7b09a8e44b2ad90be497Phil Goodwin & Tyler Schultz            root.clearFocus();
61319d90b633936ae8dacbc7b09a8e44b2ad90be497Phil Goodwin & Tyler Schultz        }
61419d90b633936ae8dacbc7b09a8e44b2ad90be497Phil Goodwin & Tyler Schultz    }
61519d90b633936ae8dacbc7b09a8e44b2ad90be497Phil Goodwin & Tyler Schultz
61619d90b633936ae8dacbc7b09a8e44b2ad90be497Phil Goodwin & Tyler Schultz    private boolean anyParentHasFocus(View view) {
61719d90b633936ae8dacbc7b09a8e44b2ad90be497Phil Goodwin & Tyler Schultz        while (view != null) {
61819d90b633936ae8dacbc7b09a8e44b2ad90be497Phil Goodwin & Tyler Schultz            if (view.hasFocus()) return true;
61919d90b633936ae8dacbc7b09a8e44b2ad90be497Phil Goodwin & Tyler Schultz            view = (View) view.getParent();
62019d90b633936ae8dacbc7b09a8e44b2ad90be497Phil Goodwin & Tyler Schultz        }
62119d90b633936ae8dacbc7b09a8e44b2ad90be497Phil Goodwin & Tyler Schultz        return false;
62219d90b633936ae8dacbc7b09a8e44b2ad90be497Phil Goodwin & Tyler Schultz    }
62319d90b633936ae8dacbc7b09a8e44b2ad90be497Phil Goodwin & Tyler Schultz
62419d90b633936ae8dacbc7b09a8e44b2ad90be497Phil Goodwin & Tyler Schultz
6256eedf728138e6f79fa898ff3e31bf61c9b1151dChristian Williams & Tyler Schulz}
626