19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* 29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Copyright (C) 2007-2008 The Android Open Source Project 39066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 49066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); you may not 59066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * use this file except in compliance with the License. You may obtain a copy of 69066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the License at 79066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 89066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 99066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Unless required by applicable law or agreed to in writing, software 119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * License for the specific language governing permissions and limitations under 149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the License. 159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpackage android.inputmethodservice; 189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.app.Dialog; 209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.Context; 217bd6c20f2670e174bd42b40092537d3d01dd0700Tadashi G. Takaokaimport android.graphics.Rect; 229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.IBinder; 239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.view.Gravity; 2483fe3f559249451706957b1a5f660b2b8272f114Dianne Hackbornimport android.view.KeyEvent; 257bd6c20f2670e174bd42b40092537d3d01dd0700Tadashi G. Takaokaimport android.view.MotionEvent; 269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.view.WindowManager; 279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/** 299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * A SoftInputWindow is a Dialog that is intended to be used for a top-level input 309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * method window. It will be displayed along the edge of the screen, moving 319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the application user interface away from it so that the focused item is 329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * always visible. 33c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn * @hide 349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 35c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackbornpublic class SoftInputWindow extends Dialog { 36c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn final String mName; 37c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn final Callback mCallback; 38c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn final KeyEvent.Callback mKeyEventCallback; 3983fe3f559249451706957b1a5f660b2b8272f114Dianne Hackborn final KeyEvent.DispatcherState mDispatcherState; 40e30e02f5d9a9141c9ee70c712d4f9d52c88ea969Dianne Hackborn final int mWindowType; 41e30e02f5d9a9141c9ee70c712d4f9d52c88ea969Dianne Hackborn final int mGravity; 42c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn final boolean mTakesFocus; 437bd6c20f2670e174bd42b40092537d3d01dd0700Tadashi G. Takaoka private final Rect mBounds = new Rect(); 44c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn 45c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn public interface Callback { 46c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn public void onBackPressed(); 47c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn } 48c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn 499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setToken(IBinder token) { 509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project WindowManager.LayoutParams lp = getWindow().getAttributes(); 519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project lp.token = token; 529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project getWindow().setAttributes(lp); 539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 562c84cfc001fb92a71811bf7384b7f865ff31ff9dDianne Hackborn * Create a SoftInputWindow that uses a custom style. 579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param context The Context in which the DockWindow should run. In 599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * particular, it uses the window manager and theme from this context 609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * to present its UI. 619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param theme A style resource describing the theme to use for the window. 629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * See <a href="{@docRoot}reference/available-resources.html#stylesandthemes">Style 639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * and Theme Resources</a> for more information about defining and 649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * using styles. This theme is applied on top of the current theme in 659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <var>context</var>. If 0, the default dialog theme will be used. 669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 67c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn public SoftInputWindow(Context context, String name, int theme, Callback callback, 68c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn KeyEvent.Callback keyEventCallback, KeyEvent.DispatcherState dispatcherState, 69e30e02f5d9a9141c9ee70c712d4f9d52c88ea969Dianne Hackborn int windowType, int gravity, boolean takesFocus) { 709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project super(context, theme); 71c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn mName = name; 72c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn mCallback = callback; 73c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn mKeyEventCallback = keyEventCallback; 7483fe3f559249451706957b1a5f660b2b8272f114Dianne Hackborn mDispatcherState = dispatcherState; 75e30e02f5d9a9141c9ee70c712d4f9d52c88ea969Dianne Hackborn mWindowType = windowType; 76e30e02f5d9a9141c9ee70c712d4f9d52c88ea969Dianne Hackborn mGravity = gravity; 77c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn mTakesFocus = takesFocus; 789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project initDockWindow(); 799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8183fe3f559249451706957b1a5f660b2b8272f114Dianne Hackborn @Override 8283fe3f559249451706957b1a5f660b2b8272f114Dianne Hackborn public void onWindowFocusChanged(boolean hasFocus) { 8383fe3f559249451706957b1a5f660b2b8272f114Dianne Hackborn super.onWindowFocusChanged(hasFocus); 8483fe3f559249451706957b1a5f660b2b8272f114Dianne Hackborn mDispatcherState.reset(); 8583fe3f559249451706957b1a5f660b2b8272f114Dianne Hackborn } 8683fe3f559249451706957b1a5f660b2b8272f114Dianne Hackborn 877bd6c20f2670e174bd42b40092537d3d01dd0700Tadashi G. Takaoka @Override 887bd6c20f2670e174bd42b40092537d3d01dd0700Tadashi G. Takaoka public boolean dispatchTouchEvent(MotionEvent ev) { 897bd6c20f2670e174bd42b40092537d3d01dd0700Tadashi G. Takaoka getWindow().getDecorView().getHitRect(mBounds); 90fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown 91fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown if (ev.isWithinBoundsNoHistory(mBounds.left, mBounds.top, 92fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown mBounds.right - 1, mBounds.bottom - 1)) { 93fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown return super.dispatchTouchEvent(ev); 94fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown } else { 95fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown MotionEvent temp = ev.clampNoHistory(mBounds.left, mBounds.top, 96fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown mBounds.right - 1, mBounds.bottom - 1); 97fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown boolean handled = super.dispatchTouchEvent(temp); 98fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown temp.recycle(); 99fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown return handled; 100fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown } 1017bd6c20f2670e174bd42b40092537d3d01dd0700Tadashi G. Takaoka } 1027bd6c20f2670e174bd42b40092537d3d01dd0700Tadashi G. Takaoka 1039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Set which boundary of the screen the DockWindow sticks to. 1059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 1069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param gravity The boundary of the screen to stick. See {#link 1079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * android.view.Gravity.LEFT}, {#link android.view.Gravity.TOP}, 1089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {#link android.view.Gravity.BOTTOM}, {#link 1099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * android.view.Gravity.RIGHT}. 1109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setGravity(int gravity) { 1129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project WindowManager.LayoutParams lp = getWindow().getAttributes(); 1139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project lp.gravity = gravity; 114e30e02f5d9a9141c9ee70c712d4f9d52c88ea969Dianne Hackborn updateWidthHeight(lp); 115e30e02f5d9a9141c9ee70c712d4f9d52c88ea969Dianne Hackborn getWindow().setAttributes(lp); 116e30e02f5d9a9141c9ee70c712d4f9d52c88ea969Dianne Hackborn } 1179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 11820d94749043d0851f1da10c7749fd7eb13a35081Dianne Hackborn public int getGravity() { 11920d94749043d0851f1da10c7749fd7eb13a35081Dianne Hackborn return getWindow().getAttributes().gravity; 12020d94749043d0851f1da10c7749fd7eb13a35081Dianne Hackborn } 12120d94749043d0851f1da10c7749fd7eb13a35081Dianne Hackborn 122e30e02f5d9a9141c9ee70c712d4f9d52c88ea969Dianne Hackborn private void updateWidthHeight(WindowManager.LayoutParams lp) { 123e30e02f5d9a9141c9ee70c712d4f9d52c88ea969Dianne Hackborn if (lp.gravity == Gravity.TOP || lp.gravity == Gravity.BOTTOM) { 124e30e02f5d9a9141c9ee70c712d4f9d52c88ea969Dianne Hackborn lp.width = WindowManager.LayoutParams.MATCH_PARENT; 125e30e02f5d9a9141c9ee70c712d4f9d52c88ea969Dianne Hackborn lp.height = WindowManager.LayoutParams.WRAP_CONTENT; 126e30e02f5d9a9141c9ee70c712d4f9d52c88ea969Dianne Hackborn } else { 127e30e02f5d9a9141c9ee70c712d4f9d52c88ea969Dianne Hackborn lp.width = WindowManager.LayoutParams.WRAP_CONTENT; 128e30e02f5d9a9141c9ee70c712d4f9d52c88ea969Dianne Hackborn lp.height = WindowManager.LayoutParams.MATCH_PARENT; 1299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 132c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn public boolean onKeyDown(int keyCode, KeyEvent event) { 133c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn if (mKeyEventCallback != null && mKeyEventCallback.onKeyDown(keyCode, event)) { 134c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn return true; 135c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn } 136c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn return super.onKeyDown(keyCode, event); 137c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn } 138c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn 139c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn public boolean onKeyLongPress(int keyCode, KeyEvent event) { 140c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn if (mKeyEventCallback != null && mKeyEventCallback.onKeyLongPress(keyCode, event)) { 141c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn return true; 142c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn } 143c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn return super.onKeyLongPress(keyCode, event); 144c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn } 145c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn 146c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn public boolean onKeyUp(int keyCode, KeyEvent event) { 147c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn if (mKeyEventCallback != null && mKeyEventCallback.onKeyUp(keyCode, event)) { 148c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn return true; 149c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn } 150c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn return super.onKeyUp(keyCode, event); 151c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn } 152c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn 153c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn public boolean onKeyMultiple(int keyCode, int count, KeyEvent event) { 154c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn if (mKeyEventCallback != null && mKeyEventCallback.onKeyMultiple(keyCode, count, event)) { 155c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn return true; 156c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn } 157c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn return super.onKeyMultiple(keyCode, count, event); 158c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn } 159c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn 160c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn public void onBackPressed() { 161c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn if (mCallback != null) { 162c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn mCallback.onBackPressed(); 163c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn } else { 164c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn super.onBackPressed(); 165c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn } 166c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn } 167c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn 1689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private void initDockWindow() { 1699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project WindowManager.LayoutParams lp = getWindow().getAttributes(); 1709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 171e30e02f5d9a9141c9ee70c712d4f9d52c88ea969Dianne Hackborn lp.type = mWindowType; 172c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn lp.setTitle(mName); 1739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 174e30e02f5d9a9141c9ee70c712d4f9d52c88ea969Dianne Hackborn lp.gravity = mGravity; 175e30e02f5d9a9141c9ee70c712d4f9d52c88ea969Dianne Hackborn updateWidthHeight(lp); 1769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project getWindow().setAttributes(lp); 178c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn 179c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn int windowSetFlags = WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN; 180c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn int windowModFlags = WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN | 1819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE | 182c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn WindowManager.LayoutParams.FLAG_DIM_BEHIND; 183c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn 184c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn if (!mTakesFocus) { 185c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn windowSetFlags |= WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE; 186c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn } else { 187c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn windowSetFlags |= WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL; 188c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn windowModFlags |= WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL; 189c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn } 190c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn 191c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn getWindow().setFlags(windowSetFlags, windowModFlags); 1929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 194