• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2007 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package android.util;
18 
19 import com.android.internal.R;
20 
21 /**
22  * State sets are arrays of positive ints where each element
23  * represents the state of a {@link android.view.View} (e.g. focused,
24  * selected, visible, etc.).  A {@link android.view.View} may be in
25  * one or more of those states.
26  *
27  * A state spec is an array of signed ints where each element
28  * represents a required (if positive) or an undesired (if negative)
29  * {@link android.view.View} state.
30  *
31  * Utils dealing with state sets.
32  *
33  * In theory we could encapsulate the state set and state spec arrays
34  * and not have static methods here but there is some concern about
35  * performance since these methods are called during view drawing.
36  */
37 
38 public class StateSet {
StateSet()39     /** @hide */ public StateSet() {}
40 
41     public static final int[] WILD_CARD = new int[0];
42     public static final int[] NOTHING = new int[] { 0 };
43 
44     /**
45      * Return whether the stateSetOrSpec is matched by all StateSets.
46      *
47      * @param stateSetOrSpec a state set or state spec.
48      */
isWildCard(int[] stateSetOrSpec)49     public static boolean isWildCard(int[] stateSetOrSpec) {
50         return stateSetOrSpec.length == 0 || stateSetOrSpec[0] == 0;
51     }
52 
53     /**
54      * Return whether the stateSet matches the desired stateSpec.
55      *
56      * @param stateSpec an array of required (if positive) or
57      *        prohibited (if negative) {@link android.view.View} states.
58      * @param stateSet an array of {@link android.view.View} states
59      */
stateSetMatches(int[] stateSpec, int[] stateSet)60     public static boolean stateSetMatches(int[] stateSpec, int[] stateSet) {
61         if (stateSet == null) {
62             return (stateSpec == null || isWildCard(stateSpec));
63         }
64         int stateSpecSize = stateSpec.length;
65         int stateSetSize = stateSet.length;
66         for (int i = 0; i < stateSpecSize; i++) {
67             int stateSpecState = stateSpec[i];
68             if (stateSpecState == 0) {
69                 // We've reached the end of the cases to match against.
70                 return true;
71             }
72             final boolean mustMatch;
73             if (stateSpecState > 0) {
74                 mustMatch = true;
75             } else {
76                 // We use negative values to indicate must-NOT-match states.
77                 mustMatch = false;
78                 stateSpecState = -stateSpecState;
79             }
80             boolean found = false;
81             for (int j = 0; j < stateSetSize; j++) {
82                 final int state = stateSet[j];
83                 if (state == 0) {
84                     // We've reached the end of states to match.
85                     if (mustMatch) {
86                         // We didn't find this must-match state.
87                         return false;
88                     } else {
89                         // Continue checking other must-not-match states.
90                         break;
91                     }
92                 }
93                 if (state == stateSpecState) {
94                     if (mustMatch) {
95                         found = true;
96                         // Continue checking other other must-match states.
97                         break;
98                     } else {
99                         // Any match of a must-not-match state returns false.
100                         return false;
101                     }
102                 }
103             }
104             if (mustMatch && !found) {
105                 // We've reached the end of states to match and we didn't
106                 // find a must-match state.
107                 return false;
108             }
109         }
110         return true;
111     }
112 
113     /**
114      * Return whether the state matches the desired stateSpec.
115      *
116      * @param stateSpec an array of required (if positive) or
117      *        prohibited (if negative) {@link android.view.View} states.
118      * @param state a {@link android.view.View} state
119      */
stateSetMatches(int[] stateSpec, int state)120     public static boolean stateSetMatches(int[] stateSpec, int state) {
121         int stateSpecSize = stateSpec.length;
122         for (int i = 0; i < stateSpecSize; i++) {
123             int stateSpecState = stateSpec[i];
124             if (stateSpecState == 0) {
125                 // We've reached the end of the cases to match against.
126                 return true;
127             }
128             if (stateSpecState > 0) {
129                 if (state != stateSpecState) {
130                    return false;
131                 }
132             } else {
133                 // We use negative values to indicate must-NOT-match states.
134                 if (state == -stateSpecState) {
135                     // We matched a must-not-match case.
136                     return false;
137                 }
138             }
139         }
140         return true;
141     }
142 
trimStateSet(int[] states, int newSize)143     public static int[] trimStateSet(int[] states, int newSize) {
144         if (states.length == newSize) {
145             return states;
146         }
147 
148         int[] trimmedStates = new int[newSize];
149         System.arraycopy(states, 0, trimmedStates, 0, newSize);
150         return trimmedStates;
151     }
152 
dump(int[] states)153     public static String dump(int[] states) {
154         StringBuilder sb = new StringBuilder();
155 
156         int count = states.length;
157         for (int i = 0; i < count; i++) {
158 
159             switch (states[i]) {
160             case R.attr.state_window_focused:
161                 sb.append("W ");
162                 break;
163             case R.attr.state_pressed:
164                 sb.append("P ");
165                 break;
166             case R.attr.state_selected:
167                 sb.append("S ");
168                 break;
169             case R.attr.state_focused:
170                 sb.append("F ");
171                 break;
172             case R.attr.state_enabled:
173                 sb.append("E ");
174                 break;
175             }
176         }
177 
178         return sb.toString();
179     }
180 }
181