The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 1 | /* |
| 2 | * Copyright (C) 2007-2008 The Android Open Source Project |
| 3 | * |
| 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not |
| 5 | * use this file except in compliance with the License. You may obtain a copy of |
| 6 | * 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, WITHOUT |
| 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the |
| 13 | * License for the specific language governing permissions and limitations under |
| 14 | * the License. |
| 15 | */ |
| 16 | |
| 17 | package android.inputmethodservice; |
| 18 | |
| 19 | import android.app.Dialog; |
| 20 | import android.content.Context; |
Tadashi G. Takaoka | 7bd6c20 | 2011-01-25 18:02:55 +0900 | [diff] [blame] | 21 | import android.graphics.Rect; |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 22 | import android.os.IBinder; |
| 23 | import android.view.Gravity; |
Dianne Hackborn | 83fe3f5 | 2009-09-12 23:38:30 -0700 | [diff] [blame] | 24 | import android.view.KeyEvent; |
Tadashi G. Takaoka | 7bd6c20 | 2011-01-25 18:02:55 +0900 | [diff] [blame] | 25 | import android.view.MotionEvent; |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 26 | import android.view.WindowManager; |
| 27 | |
| 28 | /** |
| 29 | * A SoftInputWindow is a Dialog that is intended to be used for a top-level input |
| 30 | * method window. It will be displayed along the edge of the screen, moving |
| 31 | * the application user interface away from it so that the focused item is |
| 32 | * always visible. |
Dianne Hackborn | c03c916 | 2014-05-02 10:45:59 -0700 | [diff] [blame] | 33 | * @hide |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 34 | */ |
Dianne Hackborn | c03c916 | 2014-05-02 10:45:59 -0700 | [diff] [blame] | 35 | public class SoftInputWindow extends Dialog { |
| 36 | final String mName; |
| 37 | final Callback mCallback; |
| 38 | final KeyEvent.Callback mKeyEventCallback; |
Dianne Hackborn | 83fe3f5 | 2009-09-12 23:38:30 -0700 | [diff] [blame] | 39 | final KeyEvent.DispatcherState mDispatcherState; |
Dianne Hackborn | e30e02f | 2014-05-27 18:24:45 -0700 | [diff] [blame] | 40 | final int mWindowType; |
| 41 | final int mGravity; |
Dianne Hackborn | c03c916 | 2014-05-02 10:45:59 -0700 | [diff] [blame] | 42 | final boolean mTakesFocus; |
Tadashi G. Takaoka | 7bd6c20 | 2011-01-25 18:02:55 +0900 | [diff] [blame] | 43 | private final Rect mBounds = new Rect(); |
Dianne Hackborn | c03c916 | 2014-05-02 10:45:59 -0700 | [diff] [blame] | 44 | |
| 45 | public interface Callback { |
| 46 | public void onBackPressed(); |
| 47 | } |
| 48 | |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 49 | public void setToken(IBinder token) { |
| 50 | WindowManager.LayoutParams lp = getWindow().getAttributes(); |
| 51 | lp.token = token; |
| 52 | getWindow().setAttributes(lp); |
| 53 | } |
| 54 | |
| 55 | /** |
Dianne Hackborn | 2c84cfc | 2011-10-31 15:39:59 -0700 | [diff] [blame] | 56 | * Create a SoftInputWindow that uses a custom style. |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 57 | * |
| 58 | * @param context The Context in which the DockWindow should run. In |
| 59 | * particular, it uses the window manager and theme from this context |
| 60 | * to present its UI. |
| 61 | * @param theme A style resource describing the theme to use for the window. |
| 62 | * See <a href="{@docRoot}reference/available-resources.html#stylesandthemes">Style |
| 63 | * and Theme Resources</a> for more information about defining and |
| 64 | * using styles. This theme is applied on top of the current theme in |
| 65 | * <var>context</var>. If 0, the default dialog theme will be used. |
| 66 | */ |
Dianne Hackborn | c03c916 | 2014-05-02 10:45:59 -0700 | [diff] [blame] | 67 | public SoftInputWindow(Context context, String name, int theme, Callback callback, |
| 68 | KeyEvent.Callback keyEventCallback, KeyEvent.DispatcherState dispatcherState, |
Dianne Hackborn | e30e02f | 2014-05-27 18:24:45 -0700 | [diff] [blame] | 69 | int windowType, int gravity, boolean takesFocus) { |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 70 | super(context, theme); |
Dianne Hackborn | c03c916 | 2014-05-02 10:45:59 -0700 | [diff] [blame] | 71 | mName = name; |
| 72 | mCallback = callback; |
| 73 | mKeyEventCallback = keyEventCallback; |
Dianne Hackborn | 83fe3f5 | 2009-09-12 23:38:30 -0700 | [diff] [blame] | 74 | mDispatcherState = dispatcherState; |
Dianne Hackborn | e30e02f | 2014-05-27 18:24:45 -0700 | [diff] [blame] | 75 | mWindowType = windowType; |
| 76 | mGravity = gravity; |
Dianne Hackborn | c03c916 | 2014-05-02 10:45:59 -0700 | [diff] [blame] | 77 | mTakesFocus = takesFocus; |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 78 | initDockWindow(); |
| 79 | } |
| 80 | |
Dianne Hackborn | 83fe3f5 | 2009-09-12 23:38:30 -0700 | [diff] [blame] | 81 | @Override |
| 82 | public void onWindowFocusChanged(boolean hasFocus) { |
| 83 | super.onWindowFocusChanged(hasFocus); |
| 84 | mDispatcherState.reset(); |
| 85 | } |
| 86 | |
Tadashi G. Takaoka | 7bd6c20 | 2011-01-25 18:02:55 +0900 | [diff] [blame] | 87 | @Override |
| 88 | public boolean dispatchTouchEvent(MotionEvent ev) { |
| 89 | getWindow().getDecorView().getHitRect(mBounds); |
Jeff Brown | fe9f8ab | 2011-05-06 18:20:01 -0700 | [diff] [blame] | 90 | |
| 91 | if (ev.isWithinBoundsNoHistory(mBounds.left, mBounds.top, |
| 92 | mBounds.right - 1, mBounds.bottom - 1)) { |
| 93 | return super.dispatchTouchEvent(ev); |
| 94 | } else { |
| 95 | MotionEvent temp = ev.clampNoHistory(mBounds.left, mBounds.top, |
| 96 | mBounds.right - 1, mBounds.bottom - 1); |
| 97 | boolean handled = super.dispatchTouchEvent(temp); |
| 98 | temp.recycle(); |
| 99 | return handled; |
| 100 | } |
Tadashi G. Takaoka | 7bd6c20 | 2011-01-25 18:02:55 +0900 | [diff] [blame] | 101 | } |
| 102 | |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 103 | /** |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 104 | * Set which boundary of the screen the DockWindow sticks to. |
| 105 | * |
| 106 | * @param gravity The boundary of the screen to stick. See {#link |
| 107 | * android.view.Gravity.LEFT}, {#link android.view.Gravity.TOP}, |
| 108 | * {#link android.view.Gravity.BOTTOM}, {#link |
| 109 | * android.view.Gravity.RIGHT}. |
| 110 | */ |
| 111 | public void setGravity(int gravity) { |
| 112 | WindowManager.LayoutParams lp = getWindow().getAttributes(); |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 113 | lp.gravity = gravity; |
Dianne Hackborn | e30e02f | 2014-05-27 18:24:45 -0700 | [diff] [blame] | 114 | updateWidthHeight(lp); |
| 115 | getWindow().setAttributes(lp); |
| 116 | } |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 117 | |
Dianne Hackborn | 20d9474 | 2014-05-29 18:35:45 -0700 | [diff] [blame] | 118 | public int getGravity() { |
| 119 | return getWindow().getAttributes().gravity; |
| 120 | } |
| 121 | |
Dianne Hackborn | e30e02f | 2014-05-27 18:24:45 -0700 | [diff] [blame] | 122 | private void updateWidthHeight(WindowManager.LayoutParams lp) { |
| 123 | if (lp.gravity == Gravity.TOP || lp.gravity == Gravity.BOTTOM) { |
| 124 | lp.width = WindowManager.LayoutParams.MATCH_PARENT; |
| 125 | lp.height = WindowManager.LayoutParams.WRAP_CONTENT; |
| 126 | } else { |
| 127 | lp.width = WindowManager.LayoutParams.WRAP_CONTENT; |
| 128 | lp.height = WindowManager.LayoutParams.MATCH_PARENT; |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 129 | } |
| 130 | } |
| 131 | |
Dianne Hackborn | c03c916 | 2014-05-02 10:45:59 -0700 | [diff] [blame] | 132 | public boolean onKeyDown(int keyCode, KeyEvent event) { |
| 133 | if (mKeyEventCallback != null && mKeyEventCallback.onKeyDown(keyCode, event)) { |
| 134 | return true; |
| 135 | } |
| 136 | return super.onKeyDown(keyCode, event); |
| 137 | } |
| 138 | |
| 139 | public boolean onKeyLongPress(int keyCode, KeyEvent event) { |
| 140 | if (mKeyEventCallback != null && mKeyEventCallback.onKeyLongPress(keyCode, event)) { |
| 141 | return true; |
| 142 | } |
| 143 | return super.onKeyLongPress(keyCode, event); |
| 144 | } |
| 145 | |
| 146 | public boolean onKeyUp(int keyCode, KeyEvent event) { |
| 147 | if (mKeyEventCallback != null && mKeyEventCallback.onKeyUp(keyCode, event)) { |
| 148 | return true; |
| 149 | } |
| 150 | return super.onKeyUp(keyCode, event); |
| 151 | } |
| 152 | |
| 153 | public boolean onKeyMultiple(int keyCode, int count, KeyEvent event) { |
| 154 | if (mKeyEventCallback != null && mKeyEventCallback.onKeyMultiple(keyCode, count, event)) { |
| 155 | return true; |
| 156 | } |
| 157 | return super.onKeyMultiple(keyCode, count, event); |
| 158 | } |
| 159 | |
| 160 | public void onBackPressed() { |
| 161 | if (mCallback != null) { |
| 162 | mCallback.onBackPressed(); |
| 163 | } else { |
| 164 | super.onBackPressed(); |
| 165 | } |
| 166 | } |
| 167 | |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 168 | private void initDockWindow() { |
| 169 | WindowManager.LayoutParams lp = getWindow().getAttributes(); |
| 170 | |
Dianne Hackborn | e30e02f | 2014-05-27 18:24:45 -0700 | [diff] [blame] | 171 | lp.type = mWindowType; |
Dianne Hackborn | c03c916 | 2014-05-02 10:45:59 -0700 | [diff] [blame] | 172 | lp.setTitle(mName); |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 173 | |
Dianne Hackborn | e30e02f | 2014-05-27 18:24:45 -0700 | [diff] [blame] | 174 | lp.gravity = mGravity; |
| 175 | updateWidthHeight(lp); |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 176 | |
| 177 | getWindow().setAttributes(lp); |
Dianne Hackborn | c03c916 | 2014-05-02 10:45:59 -0700 | [diff] [blame] | 178 | |
| 179 | int windowSetFlags = WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN; |
| 180 | int windowModFlags = WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN | |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 181 | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE | |
Dianne Hackborn | c03c916 | 2014-05-02 10:45:59 -0700 | [diff] [blame] | 182 | WindowManager.LayoutParams.FLAG_DIM_BEHIND; |
| 183 | |
| 184 | if (!mTakesFocus) { |
| 185 | windowSetFlags |= WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE; |
| 186 | } else { |
| 187 | windowSetFlags |= WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL; |
| 188 | windowModFlags |= WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL; |
| 189 | } |
| 190 | |
| 191 | getWindow().setFlags(windowSetFlags, windowModFlags); |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 192 | } |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 193 | } |