1 /* 2 * Copyright (C) 2009 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 com.android.inputmethod.pinyin; 18 19 import android.graphics.drawable.Drawable; 20 21 /** 22 * Class for soft keys which defined in the keyboard xml file. A soft key can be 23 * a basic key or a toggling key. 24 * 25 * @see com.android.inputmethod.pinyin.SoftKey 26 */ 27 public class SoftKeyToggle extends SoftKey { 28 /** 29 * The current state number is stored in the lowest 8 bits of mKeyMask, this 30 * mask is used to get the state number. If the current state is 0, the 31 * normal state is enabled; if the current state is more than 0, a toggle 32 * state in the toggle state chain will be enabled. 33 */ 34 private static final int KEYMASK_TOGGLE_STATE = 0x000000ff; 35 36 private ToggleState mToggleState; 37 38 public int getToggleStateId() { 39 return (mKeyMask & KEYMASK_TOGGLE_STATE); 40 } 41 42 // The state id should be valid, and less than 255. 43 // If resetIfNotFound is true and there is no such toggle state with the 44 // given id, the key state will be reset. 45 // If the key state is newly changed (enabled to the given state, or 46 // reseted) and needs re-draw, return true. 47 public boolean enableToggleState(int stateId, boolean resetIfNotFound) { 48 int oldStateId = (mKeyMask & KEYMASK_TOGGLE_STATE); 49 if (oldStateId == stateId) return false; 50 51 mKeyMask &= (~KEYMASK_TOGGLE_STATE); 52 if (stateId > 0) { 53 mKeyMask |= (KEYMASK_TOGGLE_STATE & stateId); 54 if (getToggleState() == null) { 55 mKeyMask &= (~KEYMASK_TOGGLE_STATE); 56 if (!resetIfNotFound && oldStateId > 0) { 57 mKeyMask |= (KEYMASK_TOGGLE_STATE & oldStateId); 58 } 59 return resetIfNotFound; 60 } else { 61 return true; 62 } 63 } else { 64 return true; 65 } 66 } 67 68 // The state id should be valid, and less than 255. 69 // If resetIfNotFound is true and there is no such toggle state with the 70 // given id, the key state will be reset. 71 // If the key state is newly changed and needs re-draw, return true. 72 public boolean disableToggleState(int stateId, boolean resetIfNotFound) { 73 int oldStateId = (mKeyMask & KEYMASK_TOGGLE_STATE); 74 if (oldStateId == stateId) { 75 mKeyMask &= (~KEYMASK_TOGGLE_STATE); 76 return stateId != 0; 77 } 78 79 if (resetIfNotFound) { 80 mKeyMask &= (~KEYMASK_TOGGLE_STATE); 81 return oldStateId != 0; 82 } 83 return false; 84 } 85 86 // Clear any toggle state. If the key needs re-draw, return true. 87 public boolean disableAllToggleStates() { 88 int oldStateId = (mKeyMask & KEYMASK_TOGGLE_STATE); 89 mKeyMask &= (~KEYMASK_TOGGLE_STATE); 90 return oldStateId != 0; 91 } 92 93 @Override 94 public Drawable getKeyIcon() { 95 ToggleState state = getToggleState(); 96 if (null != state) return state.mKeyIcon; 97 return super.getKeyIcon(); 98 } 99 100 @Override 101 public Drawable getKeyIconPopup() { 102 ToggleState state = getToggleState(); 103 if (null != state) { 104 if (null != state.mKeyIconPopup) { 105 return state.mKeyIconPopup; 106 } else { 107 return state.mKeyIcon; 108 } 109 } 110 return super.getKeyIconPopup(); 111 } 112 113 @Override 114 public int getKeyCode() { 115 ToggleState state = getToggleState(); 116 if (null != state) return state.mKeyCode; 117 return mKeyCode; 118 } 119 120 @Override 121 public String getKeyLabel() { 122 ToggleState state = getToggleState(); 123 if (null != state) return state.mKeyLabel; 124 return mKeyLabel; 125 } 126 127 @Override 128 public Drawable getKeyBg() { 129 ToggleState state = getToggleState(); 130 if (null != state && null != state.mKeyType) { 131 return state.mKeyType.mKeyBg; 132 } 133 return mKeyType.mKeyBg; 134 } 135 136 @Override 137 public Drawable getKeyHlBg() { 138 ToggleState state = getToggleState(); 139 if (null != state && null != state.mKeyType) { 140 return state.mKeyType.mKeyHlBg; 141 } 142 return mKeyType.mKeyHlBg; 143 } 144 145 @Override 146 public int getColor() { 147 ToggleState state = getToggleState(); 148 if (null != state && null != state.mKeyType) { 149 return state.mKeyType.mColor; 150 } 151 return mKeyType.mColor; 152 } 153 154 @Override 155 public int getColorHl() { 156 ToggleState state = getToggleState(); 157 if (null != state && null != state.mKeyType) { 158 return state.mKeyType.mColorHl; 159 } 160 return mKeyType.mColorHl; 161 } 162 163 @Override 164 public int getColorBalloon() { 165 ToggleState state = getToggleState(); 166 if (null != state && null != state.mKeyType) { 167 return state.mKeyType.mColorBalloon; 168 } 169 return mKeyType.mColorBalloon; 170 } 171 172 @Override 173 public boolean isKeyCodeKey() { 174 ToggleState state = getToggleState(); 175 if (null != state) { 176 if (state.mKeyCode > 0) return true; 177 return false; 178 } 179 return super.isKeyCodeKey(); 180 } 181 182 @Override 183 public boolean isUserDefKey() { 184 ToggleState state = getToggleState(); 185 if (null != state) { 186 if (state.mKeyCode < 0) return true; 187 return false; 188 } 189 return super.isUserDefKey(); 190 } 191 192 @Override 193 public boolean isUniStrKey() { 194 ToggleState state = getToggleState(); 195 if (null != state) { 196 if (null != state.mKeyLabel && state.mKeyCode == 0) { 197 return true; 198 } 199 return false; 200 } 201 return super.isUniStrKey(); 202 } 203 204 @Override 205 public boolean needBalloon() { 206 ToggleState state = getToggleState(); 207 if (null != state) { 208 return (state.mIdAndFlags & KEYMASK_BALLOON) != 0; 209 } 210 return super.needBalloon(); 211 } 212 213 @Override 214 public boolean repeatable() { 215 ToggleState state = getToggleState(); 216 if (null != state) { 217 return (state.mIdAndFlags & KEYMASK_REPEAT) != 0; 218 } 219 return super.repeatable(); 220 } 221 222 @Override 223 public void changeCase(boolean lowerCase) { 224 ToggleState state = getToggleState(); 225 if (null != state && null != state.mKeyLabel) { 226 if (lowerCase) 227 state.mKeyLabel = state.mKeyLabel.toLowerCase(); 228 else 229 state.mKeyLabel = state.mKeyLabel.toUpperCase(); 230 } 231 } 232 233 public ToggleState createToggleState() { 234 return new ToggleState(); 235 } 236 237 public boolean setToggleStates(ToggleState rootState) { 238 if (null == rootState) return false; 239 mToggleState = rootState; 240 return true; 241 } 242 243 private ToggleState getToggleState() { 244 int stateId = (mKeyMask & KEYMASK_TOGGLE_STATE); 245 if (0 == stateId) return null; 246 247 ToggleState state = mToggleState; 248 while ((null != state) 249 && (state.mIdAndFlags & KEYMASK_TOGGLE_STATE) != stateId) { 250 state = state.mNextState; 251 } 252 return state; 253 } 254 255 public class ToggleState { 256 // The id should be bigger than 0; 257 private int mIdAndFlags; 258 public SoftKeyType mKeyType; 259 public int mKeyCode; 260 public Drawable mKeyIcon; 261 public Drawable mKeyIconPopup; 262 public String mKeyLabel; 263 public ToggleState mNextState; 264 265 public void setStateId(int stateId) { 266 mIdAndFlags |= (stateId & KEYMASK_TOGGLE_STATE); 267 } 268 269 public void setStateFlags(boolean repeat, boolean balloon) { 270 if (repeat) { 271 mIdAndFlags |= KEYMASK_REPEAT; 272 } else { 273 mIdAndFlags &= (~KEYMASK_REPEAT); 274 } 275 276 if (balloon) { 277 mIdAndFlags |= KEYMASK_BALLOON; 278 } else { 279 mIdAndFlags &= (~KEYMASK_BALLOON); 280 } 281 } 282 } 283 } 284