/** * Create a key with the given top-left coordinate and extract its attributes from the XML * parser. * * @param res resources associated with the caller's context * @param parent the row that this key belongs to. The row must already be attached to a {@link * Keyboard}. * @param x the x coordinate of the top-left * @param y the y coordinate of the top-left * @param parser the XML parser containing the attributes for this key */ public Key( Context askContext, Resources res, Row parent, KeyboardDimens keyboardDimens, int x, int y, XmlResourceParser parser) { this(parent, keyboardDimens); final Resources askResources = askContext.getResources(); SparseIntArray attributeIdMap = parent.parent.attributeIdMap; this.x = x; this.y = y; // setting up some defaults width = Math.min(keyboardDimens.getKeyMaxWidth(), parent.defaultWidth); height = KeyboardSupport.getKeyHeightFromHeightCode( keyboardDimens, parent.defaultHeightCode, askResources.getConfiguration().orientation); gap = parent.defaultHorizontalGap; codes = null; iconPreview = null; popupCharacters = null; popupResId = 0; repeatable = false; showPreview = true; dynamicEmblem = KEY_EMBLEM_NONE; modifier = false; sticky = false; // loading data from XML int[] remoteKeyboardLayoutStyleable = parent.parent.remoteKeyboardLayoutStyleable; TypedArray a = res.obtainAttributes(Xml.asAttributeSet(parser), remoteKeyboardLayoutStyleable); int n = a.getIndexCount(); for (int i = 0; i < n; i++) { final int remoteIndex = a.getIndex(i); final int localAttrId = attributeIdMap.get(remoteKeyboardLayoutStyleable[remoteIndex]); setDataFromTypedArray(parent, keyboardDimens, askResources, a, remoteIndex, localAttrId); } a.recycle(); this.x += gap; int[] remoteKeyboardKeyLayoutStyleable = parent.parent.remoteKeyboardKeyLayoutStyleable; a = res.obtainAttributes(Xml.asAttributeSet(parser), remoteKeyboardKeyLayoutStyleable); n = a.getIndexCount(); for (int i = 0; i < n; i++) { final int remoteIndex = a.getIndex(i); final int localAttrId = attributeIdMap.get(remoteKeyboardKeyLayoutStyleable[remoteIndex]); setDataFromTypedArray(parent, keyboardDimens, askResources, a, remoteIndex, localAttrId); } externalResourcePopupLayout = popupResId != 0; if (codes == null && !TextUtils.isEmpty(label)) { codes = new int[] {label.charAt(0)}; } a.recycle(); }
/** Create an empty key with no attributes. */ public Key(Row parent, KeyboardDimens keyboardDimens) { row = parent; keyboard = parent.parent; height = KeyboardSupport.getKeyHeightFromHeightCode( keyboardDimens, parent.defaultHeightCode, row.parent.mASKContext.getResources().getConfiguration().orientation); width = Math.min(keyboardDimens.getKeyMaxWidth(), parent.defaultWidth); gap = parent.defaultHorizontalGap; edgeFlags = parent.rowEdgeFlags; }
public static int getKeyHeightFromHeightCode( KeyboardDimens keyboardDimens, int heightCode, int orientation) { int height; switch (heightCode) { case 0: height = 0; break; case -2: height = keyboardDimens.getSmallKeyHeight(); break; case -3: height = keyboardDimens.getLargeKeyHeight(); break; default: // -1 height = keyboardDimens.getNormalKeyHeight(); break; } if (orientation == Configuration.ORIENTATION_LANDSCAPE) height = (int) (height * AnyApplication.getConfig().getKeysHeightFactorInLandscape()); else height = (int) (height * AnyApplication.getConfig().getKeysHeightFactorInPortrait()); return height; }
public void loadKeyboard(final KeyboardDimens keyboardDimens) { mDisplayWidth = keyboardDimens.getKeyboardMaxWidth(); final float rowVerticalGap = keyboardDimens.getRowVerticalGap(); final float keyHorizontalGap = keyboardDimens.getKeyHorizontalGap(); mDefaultHorizontalGap = 0; mDefaultWidth = mDisplayWidth / 10; mDefaultHeightCode = -1; XmlResourceParser parser = mKeyboardContext.getResources().getXml(mLayoutResId); boolean inKey = false; boolean inRow = false; boolean inUnknown = false; int row = 0; float x = 0; float y = rowVerticalGap; // starts with a gap int rowHeight = 0; Key key = null; Row currentRow = null; Resources res = mKeyboardContext.getResources(); boolean skipRow = false; int lastVerticalGap = 0; try { int event; while ((event = parser.next()) != XmlResourceParser.END_DOCUMENT) { if (event == XmlResourceParser.START_TAG) { String tag = parser.getName(); if (TAG_ROW.equals(tag)) { inRow = true; x = 0; rowHeight = 0; currentRow = createRowFromXml(mASKContext, res, parser); skipRow = currentRow.mode != 0 && currentRow.mode != mKeyboardMode; if (skipRow) { skipToEndOfRow(parser); inRow = false; } } else if (TAG_KEY.equals(tag)) { inKey = true; x += (keyHorizontalGap / 2); key = createKeyFromXml( mASKContext, res, currentRow, keyboardDimens, (int) x, (int) y, parser); rowHeight = Math.max(rowHeight, key.height); key.width -= keyHorizontalGap; // the gap is on both // sides mKeys.add(key); if (key.codes[0] == KeyCodes.SHIFT) { mShiftKey = key; mShiftKeyIndex = mKeys.size() - 1; mModifierKeys.add(key); } else if (key.codes[0] == KeyCodes.ALT) { mModifierKeys.add(key); } } else if (TAG_KEYBOARD.equals(tag)) { parseKeyboardAttributes(mASKContext, res, parser); } else { inUnknown = true; onUnknownTagStart(mKeyboardContext, res, tag, parser); } } else if (event == XmlResourceParser.END_TAG) { if (inKey) { inKey = false; x += key.gap + key.width; x += (keyHorizontalGap / 2); if (x > mTotalWidth) { mTotalWidth = (int) x; } } else if (inRow) { inRow = false; lastVerticalGap = currentRow.verticalGap; y += currentRow.verticalGap; y += rowHeight; y += rowVerticalGap; row++; } else if (inUnknown) { inUnknown = false; onUnknownTagEnd(); } } } } catch (Exception e) { Log.e(TAG, "Parse error:" + e); e.printStackTrace(); } mTotalHeight = (int) (y - lastVerticalGap); }
private void setDataFromTypedArray( Row parent, KeyboardDimens keyboardDimens, Resources askResources, TypedArray a, int remoteIndex, int localAttrId) { try { switch (localAttrId) { case android.R.attr.keyWidth: width = getDimensionOrFraction(a, remoteIndex, keyboard.mDisplayWidth, parent.defaultWidth); width = Math.min(keyboardDimens.getKeyMaxWidth(), width); break; case android.R.attr.keyHeight: int heightCode = getKeyHeightCode(a, remoteIndex, parent.defaultHeightCode); height = KeyboardSupport.getKeyHeightFromHeightCode( keyboardDimens, heightCode, askResources.getConfiguration().orientation); break; case android.R.attr.horizontalGap: gap = getDimensionOrFraction( a, remoteIndex, keyboard.mDisplayWidth, parent.defaultHorizontalGap); break; case android.R.attr.codes: codes = KeyboardSupport.getKeyCodesFromTypedArray(a, remoteIndex); break; case android.R.attr.iconPreview: iconPreview = a.getDrawable(remoteIndex); KeyboardSupport.updateDrawableBounds(iconPreview); break; case android.R.attr.popupCharacters: popupCharacters = a.getText(remoteIndex); break; case android.R.attr.popupKeyboard: popupResId = a.getResourceId(remoteIndex, 0); break; case android.R.attr.isRepeatable: repeatable = a.getBoolean(remoteIndex, false); break; case R.attr.showPreview: showPreview = a.getBoolean(remoteIndex, true); break; case R.attr.keyDynamicEmblem: dynamicEmblem = a.getInt(remoteIndex, KEY_EMBLEM_NONE); break; case android.R.attr.isModifier: modifier = a.getBoolean(remoteIndex, false); break; case android.R.attr.isSticky: sticky = a.getBoolean(remoteIndex, false); break; case android.R.attr.keyEdgeFlags: edgeFlags = a.getInt(remoteIndex, 0); edgeFlags |= parent.rowEdgeFlags; break; case android.R.attr.keyIcon: icon = a.getDrawable(remoteIndex); KeyboardSupport.updateDrawableBounds(icon); break; case android.R.attr.keyLabel: label = a.getText(remoteIndex); break; case android.R.attr.keyOutputText: text = a.getText(remoteIndex); break; } } catch (Exception e) { Log.w(TAG, "Failed to load keyboard layout! ", e); } }