/* * Copyright (C) 2007 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package android.util; import com.android.internal.R; /** * State sets are arrays of positive ints where each element * represents the state of a {@link android.view.View} (e.g. focused, * selected, visible, etc.). A {@link android.view.View} may be in * one or more of those states. * * A state spec is an array of signed ints where each element * represents a required (if positive) or an undesired (if negative) * {@link android.view.View} state. * * Utils dealing with state sets. * * In theory we could encapsulate the state set and state spec arrays * and not have static methods here but there is some concern about * performance since these methods are called during view drawing. */ public class StateSet { /** @hide */ public StateSet() {} public static final int[] WILD_CARD = new int[0]; public static final int[] NOTHING = new int[] { 0 }; /** * Return whether the stateSetOrSpec is matched by all StateSets. * * @param stateSetOrSpec a state set or state spec. */ public static boolean isWildCard(int[] stateSetOrSpec) { return stateSetOrSpec.length == 0 || stateSetOrSpec[0] == 0; } /** * Return whether the stateSet matches the desired stateSpec. * * @param stateSpec an array of required (if positive) or * prohibited (if negative) {@link android.view.View} states. * @param stateSet an array of {@link android.view.View} states */ public static boolean stateSetMatches(int[] stateSpec, int[] stateSet) { if (stateSet == null) { return (stateSpec == null || isWildCard(stateSpec)); } int stateSpecSize = stateSpec.length; int stateSetSize = stateSet.length; for (int i = 0; i < stateSpecSize; i++) { int stateSpecState = stateSpec[i]; if (stateSpecState == 0) { // We've reached the end of the cases to match against. return true; } final boolean mustMatch; if (stateSpecState > 0) { mustMatch = true; } else { // We use negative values to indicate must-NOT-match states. mustMatch = false; stateSpecState = -stateSpecState; } boolean found = false; for (int j = 0; j < stateSetSize; j++) { final int state = stateSet[j]; if (state == 0) { // We've reached the end of states to match. if (mustMatch) { // We didn't find this must-match state. return false; } else { // Continue checking other must-not-match states. break; } } if (state == stateSpecState) { if (mustMatch) { found = true; // Continue checking other other must-match states. break; } else { // Any match of a must-not-match state returns false. return false; } } } if (mustMatch && !found) { // We've reached the end of states to match and we didn't // find a must-match state. return false; } } return true; } /** * Return whether the state matches the desired stateSpec. * * @param stateSpec an array of required (if positive) or * prohibited (if negative) {@link android.view.View} states. * @param state a {@link android.view.View} state */ public static boolean stateSetMatches(int[] stateSpec, int state) { int stateSpecSize = stateSpec.length; for (int i = 0; i < stateSpecSize; i++) { int stateSpecState = stateSpec[i]; if (stateSpecState == 0) { // We've reached the end of the cases to match against. return true; } if (stateSpecState > 0) { if (state != stateSpecState) { return false; } } else { // We use negative values to indicate must-NOT-match states. if (state == -stateSpecState) { // We matched a must-not-match case. return false; } } } return true; } public static int[] trimStateSet(int[] states, int newSize) { if (states.length == newSize) { return states; } int[] trimmedStates = new int[newSize]; System.arraycopy(states, 0, trimmedStates, 0, newSize); return trimmedStates; } public static String dump(int[] states) { StringBuilder sb = new StringBuilder(); int count = states.length; for (int i = 0; i < count; i++) { switch (states[i]) { case R.attr.state_window_focused: sb.append("W "); break; case R.attr.state_pressed: sb.append("P "); break; case R.attr.state_selected: sb.append("S "); break; case R.attr.state_focused: sb.append("F "); break; case R.attr.state_enabled: sb.append("E "); break; } } return sb.toString(); } }