public virtual bool onKeyOther(android.widget.TextView widget, android.text.Spannable text, android.view.KeyEvent @event) { int movementMetaState = getMovementMetaState(text, @event); int keyCode = @event.getKeyCode(); if (keyCode != android.view.KeyEvent.KEYCODE_UNKNOWN && @event.getAction() == android.view.KeyEvent .ACTION_MULTIPLE) { int repeat = @event.getRepeatCount(); bool handled = false; { for (int i = 0; i < repeat; i++) { if (!handleMovementKey(widget, text, keyCode, movementMetaState, @event)) { break; } handled = true; } } if (handled) { android.text.method.MetaKeyKeyListener.adjustMetaAfterKeypress(text); android.text.method.MetaKeyKeyListener.resetLockedMeta(text); } return handled; } return false; }
public virtual bool onKey(android.content.DialogInterface dialog, int keyCode, android.view.KeyEvent @event) { if (keyCode == android.view.KeyEvent.KEYCODE_MENU || keyCode == android.view.KeyEvent .KEYCODE_BACK) { if (@event.getAction() == android.view.KeyEvent.ACTION_DOWN && @event.getRepeatCount () == 0) { android.view.Window win = mDialog.getWindow(); if (win != null) { android.view.View decor = win.getDecorView(); if (decor != null) { android.view.KeyEvent.DispatcherState ds = decor.getKeyDispatcherState(); if (ds != null) { ds.startTracking(@event, this); return true; } } } } else { if (@event.getAction() == android.view.KeyEvent.ACTION_UP && [email protected]()) { android.view.Window win = mDialog.getWindow(); if (win != null) { android.view.View decor = win.getDecorView(); if (decor != null) { android.view.KeyEvent.DispatcherState ds = decor.getKeyDispatcherState(); if (ds != null && ds.isTracking(@event)) { mMenu.close(true); dialog.dismiss(); return true; } } } } } } // Menu shortcut matching return mMenu.performShortcut(keyCode, @event, 0); }
protected internal override bool handleMovementKey(android.widget.TextView widget , android.text.Spannable buffer, int keyCode, int movementMetaState, android.view.KeyEvent @event) { switch (keyCode) { case android.view.KeyEvent.KEYCODE_DPAD_CENTER: { if (android.view.KeyEvent.metaStateHasNoModifiers(movementMetaState)) { if (@event.getAction() == android.view.KeyEvent.ACTION_DOWN && @event.getRepeatCount () == 0 && android.text.method.MetaKeyKeyListener.getMetaState(buffer, android.text.method.MetaKeyKeyListener .META_SELECTING) != 0) { return widget.showContextMenu(); } } break; } } return base.handleMovementKey(widget, buffer, keyCode, movementMetaState, @event); }
public override bool dispatchKeyEvent(android.view.KeyEvent @event) { if (@event.getKeyCode() == android.view.KeyEvent.KEYCODE_BACK) { if (this.getKeyDispatcherState() == null) { return base.dispatchKeyEvent(@event); } if (@event.getAction() == android.view.KeyEvent.ACTION_DOWN && @event.getRepeatCount () == 0) { android.view.KeyEvent.DispatcherState state = this.getKeyDispatcherState(); if (state != null) { state.startTracking(@event, this); } return true; } else { if (@event.getAction() == android.view.KeyEvent.ACTION_UP) { android.view.KeyEvent.DispatcherState state = this.getKeyDispatcherState(); if (state != null && state.isTracking(@event) && [email protected]()) { this._enclosing.dismiss(); return true; } } } return base.dispatchKeyEvent(@event); } else { return base.dispatchKeyEvent(@event); } }
/// <summary>Filter pre-IME key events.</summary> /// <remarks> /// Filter pre-IME key events. By forwarding /// <see cref="android.view.View.onKeyPreIme(int, android.view.KeyEvent)">android.view.View.onKeyPreIme(int, android.view.KeyEvent) /// </see> /// events to this function, views using ListPopupWindow can have it dismiss the popup /// when the back key is pressed. /// </remarks> /// <param name="keyCode">keyCode param passed to the host view's onKeyPreIme</param> /// <param name="event">event param passed to the host view's onKeyPreIme</param> /// <returns>true if the event was handled, false if it was ignored.</returns> /// <seealso cref="setModal(bool)">setModal(bool)</seealso> public virtual bool onKeyPreIme(int keyCode, android.view.KeyEvent @event) { if (keyCode == android.view.KeyEvent.KEYCODE_BACK && isShowing()) { // special case for the back key, we do not even try to send it // to the drop down list but instead, consume it immediately android.view.View anchorView = mDropDownAnchorView; if (@event.getAction() == android.view.KeyEvent.ACTION_DOWN && @event.getRepeatCount () == 0) { android.view.KeyEvent.DispatcherState state = anchorView.getKeyDispatcherState(); if (state != null) { state.startTracking(@event, this); } return true; } else { if (@event.getAction() == android.view.KeyEvent.ACTION_UP) { android.view.KeyEvent.DispatcherState state = anchorView.getKeyDispatcherState(); if (state != null) { state.handleUpEvent(@event); } if (@event.isTracking() && [email protected]()) { dismiss(); return true; } } } } return false; }
public override bool onKeyPreIme(int keyCode, android.view.KeyEvent @event) { if (keyCode == android.view.KeyEvent.KEYCODE_BACK) { // special case for the back key, we do not even try to send it // to the drop down list but instead, consume it immediately if (@event.getAction() == android.view.KeyEvent.ACTION_DOWN && @event.getRepeatCount () == 0) { android.view.KeyEvent.DispatcherState state = getKeyDispatcherState(); if (state != null) { state.startTracking(@event, this); } return true; } else { if (@event.getAction() == android.view.KeyEvent.ACTION_UP) { android.view.KeyEvent.DispatcherState state = getKeyDispatcherState(); if (state != null) { state.handleUpEvent(@event); } if (@event.isTracking() && [email protected]()) { mSearchView.clearFocus(); mSearchView.setImeVisibility(false); return true; } } } } return base.onKeyPreIme(keyCode, @event); }
private bool onContainerKey(android.view.KeyEvent @event) { int keyCode = @event.getKeyCode(); if (isInterestingKey(keyCode)) { if (keyCode == android.view.KeyEvent.KEYCODE_BACK) { if (@event.getAction() == android.view.KeyEvent.ACTION_DOWN && @event.getRepeatCount () == 0) { if (mOwnerView != null) { android.view.KeyEvent.DispatcherState ds = mOwnerView.getKeyDispatcherState(); if (ds != null) { ds.startTracking(@event, this); } } return true; } else { if (@event.getAction() == android.view.KeyEvent.ACTION_UP && @event.isTracking() && [email protected]()) { setVisible(false); return true; } } } else { dismissControlsDelayed(ZOOM_CONTROLS_TIMEOUT); } // Let the container handle the key return false; } else { android.view.ViewRootImpl viewRoot = getOwnerViewRootImpl(); if (viewRoot != null) { viewRoot.dispatchKey(@event); } // We gave the key to the owner, don't let the container handle this key return true; } }
public override bool onKeyDown(android.view.View view, android.text.Editable content , int keyCode, android.view.KeyEvent @event) { int selStart; int selEnd; int pref = 0; if (view != null) { pref = android.text.method.TextKeyListener.getInstance().getPrefs(view.getContext ()); } { int a = android.text.Selection.getSelectionStart(content); int b = android.text.Selection.getSelectionEnd(content); selStart = System.Math.Min(a, b); selEnd = System.Math.Max(a, b); if (selStart < 0 || selEnd < 0) { selStart = selEnd = 0; android.text.Selection.setSelection(content, 0, 0); } } int activeStart = content.getSpanStart(android.text.method.TextKeyListener.ACTIVE ); int activeEnd = content.getSpanEnd(android.text.method.TextKeyListener.ACTIVE); // QWERTY keyboard normal case int i = @event.getUnicodeChar(@event.getMetaState() | getMetaState(content)); if (!mFullKeyboard) { int count = @event.getRepeatCount(); if (count > 0 && selStart == selEnd && selStart > 0) { char c = content[selStart - 1]; if (c == i || c == Sharpen.CharHelper.ToUpper(i) && view != null) { if (showCharacterPicker(view, content, c, false, count)) { resetMetaState(content); return true; } } } } if (i == android.view.KeyCharacterMap.PICKER_DIALOG_INPUT) { if (view != null) { showCharacterPicker(view, content, android.view.KeyCharacterMap.PICKER_DIALOG_INPUT , true, 1); } resetMetaState(content); return true; } if (i == android.view.KeyCharacterMap.HEX_INPUT) { int start; if (selStart == selEnd) { start = selEnd; while (start > 0 && selEnd - start < 4 && Sharpen.CharHelper.Digit(content[start - 1], 16) >= 0) { start--; } } else { start = selStart; } int ch = -1; try { string hex = android.text.TextUtils.substring(content, start, selEnd); ch = System.Convert.ToInt32(hex, 16); } catch (System.ArgumentException) { } if (ch >= 0) { selStart = start; android.text.Selection.setSelection(content, selStart, selEnd); i = ch; } else { i = 0; } } if (i != 0) { bool dead = false; if ((i & android.view.KeyCharacterMap.COMBINING_ACCENT) != 0) { dead = true; i = i & android.view.KeyCharacterMap.COMBINING_ACCENT_MASK; } if (activeStart == selStart && activeEnd == selEnd) { bool replace = false; if (selEnd - selStart - 1 == 0) { char accent = content[selStart]; int composed = android.view.KeyEvent.getDeadChar(accent, i); if (composed != 0) { i = composed; replace = true; } } if (!replace) { android.text.Selection.setSelection(content, selEnd); content.removeSpan(android.text.method.TextKeyListener.ACTIVE); selStart = selEnd; } } if ((pref & android.text.method.TextKeyListener.AUTO_CAP) != 0 && Sharpen.CharHelper.IsLower (i) && android.text.method.TextKeyListener.shouldCap(mAutoCap, content, selStart )) { int where = content.getSpanEnd(android.text.method.TextKeyListener.CAPPED); int flags = content.getSpanFlags(android.text.method.TextKeyListener.CAPPED); if (where == selStart && (((flags >> 16) & unchecked((int)(0xFFFF))) == i)) { content.removeSpan(android.text.method.TextKeyListener.CAPPED); } else { flags = i << 16; i = Sharpen.CharHelper.ToUpper(i); if (selStart == 0) { content.setSpan(android.text.method.TextKeyListener.CAPPED, 0, 0, android.text.SpannedClass.SPAN_MARK_MARK | flags); } else { content.setSpan(android.text.method.TextKeyListener.CAPPED, selStart - 1, selStart , android.text.SpannedClass.SPAN_EXCLUSIVE_EXCLUSIVE | flags); } } } if (selStart != selEnd) { android.text.Selection.setSelection(content, selEnd); } content.setSpan(OLD_SEL_START, selStart, selStart, android.text.SpannedClass.SPAN_MARK_MARK ); content.replace(selStart, selEnd, java.lang.CharSequenceProxy.Wrap(((char)i).ToString ())); int oldStart = content.getSpanStart(OLD_SEL_START); selEnd = android.text.Selection.getSelectionEnd(content); if (oldStart < selEnd) { content.setSpan(android.text.method.TextKeyListener.LAST_TYPED, oldStart, selEnd, android.text.SpannedClass.SPAN_EXCLUSIVE_EXCLUSIVE); if (dead) { android.text.Selection.setSelection(content, oldStart, selEnd); content.setSpan(android.text.method.TextKeyListener.ACTIVE, oldStart, selEnd, android.text.SpannedClass.SPAN_EXCLUSIVE_EXCLUSIVE ); } } adjustMetaAfterKeypress(content); // potentially do autotext replacement if the character // that was typed was an autotext terminator if ((pref & android.text.method.TextKeyListener.AUTO_TEXT) != 0 && mAutoText && ( i == ' ' || i == '\t' || i == '\n' || i == ',' || i == '.' || i == '!' || i == '?' || i == '"' || Sharpen.CharHelper.GetType(i) == Sharpen.CharHelper.END_PUNCTUATION ) && content.getSpanEnd(android.text.method.TextKeyListener.INHIBIT_REPLACEMENT) != oldStart) { int x; for (x = oldStart; x > 0; x--) { char c = content[x - 1]; if (c != '\'' && !System.Char.IsLetter(c)) { break; } } string rep = getReplacement(content, x, oldStart, view); if (rep != null) { android.text.method.QwertyKeyListener.Replaced[] repl = content.getSpans<android.text.method.QwertyKeyListener .Replaced>(0, content.Length); { for (int a = 0; a < repl.Length; a++) { content.removeSpan(repl[a]); } } char[] orig = new char[oldStart - x]; android.text.TextUtils.getChars(content, x, oldStart, orig, 0); content.setSpan(new android.text.method.QwertyKeyListener.Replaced(orig), x, oldStart , android.text.SpannedClass.SPAN_EXCLUSIVE_EXCLUSIVE); content.replace(x, oldStart, java.lang.CharSequenceProxy.Wrap(rep)); } } // Replace two spaces by a period and a space. if ((pref & android.text.method.TextKeyListener.AUTO_PERIOD) != 0 && mAutoText) { selEnd = android.text.Selection.getSelectionEnd(content); if (selEnd - 3 >= 0) { if (content[selEnd - 1] == ' ' && content[selEnd - 2] == ' ') { char c = content[selEnd - 3]; { for (int j = selEnd - 3; j > 0; j--) { if (c == '"' || Sharpen.CharHelper.GetType(c) == Sharpen.CharHelper.END_PUNCTUATION) { c = content[j - 1]; } else { break; } } } if (System.Char.IsLetter(c) || System.Char.IsDigit(c)) { content.replace(selEnd - 2, selEnd - 1, java.lang.CharSequenceProxy.Wrap(".")); } } } } return true; } else { if (keyCode == android.view.KeyEvent.KEYCODE_DEL && (@event.hasNoModifiers() || @event .hasModifiers(android.view.KeyEvent.META_ALT_ON)) && selStart == selEnd) { // special backspace case for undoing autotext int consider = 1; // if backspacing over the last typed character, // it undoes the autotext prior to that character // (unless the character typed was newline, in which // case this behavior would be confusing) if (content.getSpanEnd(android.text.method.TextKeyListener.LAST_TYPED) == selStart) { if (content[selStart - 1] != '\n') { consider = 2; } } android.text.method.QwertyKeyListener.Replaced[] repl = content.getSpans<android.text.method.QwertyKeyListener .Replaced>(selStart - consider, selStart); if (repl.Length > 0) { int st = content.getSpanStart(repl[0]); int en = content.getSpanEnd(repl[0]); string old = new string(repl[0].mText); content.removeSpan(repl[0]); // only cancel the autocomplete if the cursor is at the end of // the replaced span (or after it, because the user is // backspacing over the space after the word, not the word // itself). if (selStart >= en) { content.setSpan(android.text.method.TextKeyListener.INHIBIT_REPLACEMENT, en, en, android.text.SpannedClass.SPAN_POINT_POINT); content.replace(st, en, java.lang.CharSequenceProxy.Wrap(old)); en = content.getSpanStart(android.text.method.TextKeyListener.INHIBIT_REPLACEMENT ); if (en - 1 >= 0) { content.setSpan(android.text.method.TextKeyListener.INHIBIT_REPLACEMENT, en - 1, en, android.text.SpannedClass.SPAN_EXCLUSIVE_EXCLUSIVE); } else { content.removeSpan(android.text.method.TextKeyListener.INHIBIT_REPLACEMENT); } adjustMetaAfterKeypress(content); } else { adjustMetaAfterKeypress(content); return base.onKeyDown(view, content, keyCode, @event); } return true; } } } return base.onKeyDown(view, content, keyCode, @event); }
/// <summary>Checks a key event.</summary> /// <remarks>Checks a key event.</remarks> /// <param name="event">The event.</param> /// <param name="nestingLevel"> /// The nesting level: 0 if called from the base class, /// or 1 from a subclass. If the event was already checked by this consistency verifier /// at a higher nesting level, it will not be checked again. Used to handle the situation /// where a subclass dispatching method delegates to its superclass's dispatching method /// and both dispatching methods call into the consistency verifier. /// </param> public void onKeyEvent(android.view.KeyEvent @event, int nestingLevel) { if (!startEvent(@event, nestingLevel, EVENT_TYPE_KEY)) { return; } try { ensureMetaStateIsNormalized(@event.getMetaState()); int action = @event.getAction(); int deviceId = @event.getDeviceId(); int source = @event.getSource(); int keyCode = @event.getKeyCode(); switch (action) { case android.view.KeyEvent.ACTION_DOWN: { android.view.InputEventConsistencyVerifier.KeyState state = findKeyState(deviceId , source, keyCode, false); if (state != null) { // If the key is already down, ensure it is a repeat. // We don't perform this check when processing raw device input // because the input dispatcher itself is responsible for setting // the key repeat count before it delivers input events. if (state.unhandled) { state.unhandled = false; } else { if ((mFlags & FLAG_RAW_DEVICE_INPUT) == 0 && @event.getRepeatCount() == 0) { problem("ACTION_DOWN but key is already down and this event " + "is not a key repeat." ); } } } else { addKeyState(deviceId, source, keyCode); } break; } case android.view.KeyEvent.ACTION_UP: { android.view.InputEventConsistencyVerifier.KeyState state = findKeyState(deviceId , source, keyCode, true); if (state == null) { problem("ACTION_UP but key was not down."); } else { state.recycle(); } break; } case android.view.KeyEvent.ACTION_MULTIPLE: { break; } default: { problem("Invalid action " + android.view.KeyEvent.actionToString(action) + " for key event." ); break; } } } finally { finishEvent(); } }
public virtual bool onKeyDown(int keyCode, android.view.KeyEvent @event) { if (keyCode == android.view.KeyEvent.KEYCODE_BACK) { if (getApplicationInfo().targetSdkVersion >= android.os.Build.VERSION_CODES.ECLAIR) { @event.startTracking(); } else { onBackPressed(); } return true; } if (mDefaultKeyMode == DEFAULT_KEYS_DISABLE) { return false; } else { if (mDefaultKeyMode == DEFAULT_KEYS_SHORTCUT) { if (getWindow().performPanelShortcut(android.view.Window.FEATURE_OPTIONS_PANEL, keyCode , @event, android.view.MenuClass.FLAG_ALWAYS_PERFORM_CLOSE)) { return true; } return false; } else { bool clearSpannable = false; bool handled; if ((@event.getRepeatCount() != 0) || @event.isSystem()) { clearSpannable = true; handled = false; } else { handled = android.text.method.TextKeyListener.getInstance().onKeyDown(null, mDefaultKeySsb , keyCode, @event); if (handled && mDefaultKeySsb.Length > 0) { string str = mDefaultKeySsb.ToString(); clearSpannable = true; switch (mDefaultKeyMode) { case DEFAULT_KEYS_DIALER: { android.content.Intent intent = new android.content.Intent(android.content.Intent .ACTION_DIAL, Sharpen.Util.ParseUri("tel:" + str)); intent.addFlags(android.content.Intent.FLAG_ACTIVITY_NEW_TASK); startActivity(intent); break; } case DEFAULT_KEYS_SEARCH_LOCAL: { startSearch(str, false, null, false); break; } case DEFAULT_KEYS_SEARCH_GLOBAL: { startSearch(str, false, null, true); break; } } } } if (clearSpannable) { mDefaultKeySsb.clear(); mDefaultKeySsb.clearSpans(); android.text.Selection.setSelection(mDefaultKeySsb, 0); } return handled; } } }
private bool commonKey(int keyCode, int count, android.view.KeyEvent @event) { if (mAdapter == null) { return false; } if (mDataChanged) { layoutChildren(); } bool handled = false; int action = @event.getAction(); if (action != android.view.KeyEvent.ACTION_UP) { switch (keyCode) { case android.view.KeyEvent.KEYCODE_DPAD_LEFT: { if (@event.hasNoModifiers()) { handled = resurrectSelectionIfNeeded() || arrowScroll(FOCUS_LEFT); } break; } case android.view.KeyEvent.KEYCODE_DPAD_RIGHT: { if (@event.hasNoModifiers()) { handled = resurrectSelectionIfNeeded() || arrowScroll(FOCUS_RIGHT); } break; } case android.view.KeyEvent.KEYCODE_DPAD_UP: { if (@event.hasNoModifiers()) { handled = resurrectSelectionIfNeeded() || arrowScroll(FOCUS_UP); } else { if (@event.hasModifiers(android.view.KeyEvent.META_ALT_ON)) { handled = resurrectSelectionIfNeeded() || fullScroll(FOCUS_UP); } } break; } case android.view.KeyEvent.KEYCODE_DPAD_DOWN: { if (@event.hasNoModifiers()) { handled = resurrectSelectionIfNeeded() || arrowScroll(FOCUS_DOWN); } else { if (@event.hasModifiers(android.view.KeyEvent.META_ALT_ON)) { handled = resurrectSelectionIfNeeded() || fullScroll(FOCUS_DOWN); } } break; } case android.view.KeyEvent.KEYCODE_DPAD_CENTER: case android.view.KeyEvent.KEYCODE_ENTER: { if (@event.hasNoModifiers()) { handled = resurrectSelectionIfNeeded(); if (!handled && @event.getRepeatCount() == 0 && getChildCount() > 0) { keyPressed(); handled = true; } } break; } case android.view.KeyEvent.KEYCODE_SPACE: { if (mPopup == null || !mPopup.isShowing()) { if (@event.hasNoModifiers()) { handled = resurrectSelectionIfNeeded() || pageScroll(FOCUS_DOWN); } else { if (@event.hasModifiers(android.view.KeyEvent.META_SHIFT_ON)) { handled = resurrectSelectionIfNeeded() || pageScroll(FOCUS_UP); } } } break; } case android.view.KeyEvent.KEYCODE_PAGE_UP: { if (@event.hasNoModifiers()) { handled = resurrectSelectionIfNeeded() || pageScroll(FOCUS_UP); } else { if (@event.hasModifiers(android.view.KeyEvent.META_ALT_ON)) { handled = resurrectSelectionIfNeeded() || fullScroll(FOCUS_UP); } } break; } case android.view.KeyEvent.KEYCODE_PAGE_DOWN: { if (@event.hasNoModifiers()) { handled = resurrectSelectionIfNeeded() || pageScroll(FOCUS_DOWN); } else { if (@event.hasModifiers(android.view.KeyEvent.META_ALT_ON)) { handled = resurrectSelectionIfNeeded() || fullScroll(FOCUS_DOWN); } } break; } case android.view.KeyEvent.KEYCODE_MOVE_HOME: { if (@event.hasNoModifiers()) { handled = resurrectSelectionIfNeeded() || fullScroll(FOCUS_UP); } break; } case android.view.KeyEvent.KEYCODE_MOVE_END: { if (@event.hasNoModifiers()) { handled = resurrectSelectionIfNeeded() || fullScroll(FOCUS_DOWN); } break; } case android.view.KeyEvent.KEYCODE_TAB: { // XXX Sometimes it is useful to be able to TAB through the items in // a GridView sequentially. Unfortunately this can create an // asymmetry in TAB navigation order unless the list selection // always reverts to the top or bottom when receiving TAB focus from // another widget. Leaving this behavior disabled for now but // perhaps it should be configurable (and more comprehensive). if (false) { if (@event.hasNoModifiers()) { handled = resurrectSelectionIfNeeded() || sequenceScroll(FOCUS_FORWARD); } else { if (@event.hasModifiers(android.view.KeyEvent.META_SHIFT_ON)) { handled = resurrectSelectionIfNeeded() || sequenceScroll(FOCUS_BACKWARD); } } } break; } } } if (handled) { return true; } if (sendToTextFilter(keyCode, count, @event)) { return true; } switch (action) { case android.view.KeyEvent.ACTION_DOWN: { return base.onKeyDown(keyCode, @event); } case android.view.KeyEvent.ACTION_UP: { return base.onKeyUp(keyCode, @event); } case android.view.KeyEvent.ACTION_MULTIPLE: { return base.onKeyMultiple(keyCode, count, @event); } default: { return false; } } }