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. 339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectclass SoftInputWindow extends Dialog { 3583fe3f559249451706957b1a5f660b2b8272f114Dianne Hackborn final KeyEvent.DispatcherState mDispatcherState; 367bd6c20f2670e174bd42b40092537d3d01dd0700Tadashi G. Takaoka private final Rect mBounds = new Rect(); 3783fe3f559249451706957b1a5f660b2b8272f114Dianne Hackborn 389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setToken(IBinder token) { 399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project WindowManager.LayoutParams lp = getWindow().getAttributes(); 409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project lp.token = token; 419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project getWindow().setAttributes(lp); 429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 452c84cfc001fb92a71811bf7384b7f865ff31ff9dDianne Hackborn * Create a SoftInputWindow that uses a custom style. 469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param context The Context in which the DockWindow should run. In 489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * particular, it uses the window manager and theme from this context 499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * to present its UI. 509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param theme A style resource describing the theme to use for the window. 519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * See <a href="{@docRoot}reference/available-resources.html#stylesandthemes">Style 529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * and Theme Resources</a> for more information about defining and 539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * using styles. This theme is applied on top of the current theme in 549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <var>context</var>. If 0, the default dialog theme will be used. 559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 5683fe3f559249451706957b1a5f660b2b8272f114Dianne Hackborn public SoftInputWindow(Context context, int theme, 5783fe3f559249451706957b1a5f660b2b8272f114Dianne Hackborn KeyEvent.DispatcherState dispatcherState) { 589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project super(context, theme); 5983fe3f559249451706957b1a5f660b2b8272f114Dianne Hackborn mDispatcherState = dispatcherState; 609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project initDockWindow(); 619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6383fe3f559249451706957b1a5f660b2b8272f114Dianne Hackborn @Override 6483fe3f559249451706957b1a5f660b2b8272f114Dianne Hackborn public void onWindowFocusChanged(boolean hasFocus) { 6583fe3f559249451706957b1a5f660b2b8272f114Dianne Hackborn super.onWindowFocusChanged(hasFocus); 6683fe3f559249451706957b1a5f660b2b8272f114Dianne Hackborn mDispatcherState.reset(); 6783fe3f559249451706957b1a5f660b2b8272f114Dianne Hackborn } 6883fe3f559249451706957b1a5f660b2b8272f114Dianne Hackborn 697bd6c20f2670e174bd42b40092537d3d01dd0700Tadashi G. Takaoka @Override 707bd6c20f2670e174bd42b40092537d3d01dd0700Tadashi G. Takaoka public boolean dispatchTouchEvent(MotionEvent ev) { 717bd6c20f2670e174bd42b40092537d3d01dd0700Tadashi G. Takaoka getWindow().getDecorView().getHitRect(mBounds); 72fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown 73fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown if (ev.isWithinBoundsNoHistory(mBounds.left, mBounds.top, 74fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown mBounds.right - 1, mBounds.bottom - 1)) { 75fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown return super.dispatchTouchEvent(ev); 76fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown } else { 77fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown MotionEvent temp = ev.clampNoHistory(mBounds.left, mBounds.top, 78fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown mBounds.right - 1, mBounds.bottom - 1); 79fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown boolean handled = super.dispatchTouchEvent(temp); 80fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown temp.recycle(); 81fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown return handled; 82fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown } 837bd6c20f2670e174bd42b40092537d3d01dd0700Tadashi G. Takaoka } 847bd6c20f2670e174bd42b40092537d3d01dd0700Tadashi G. Takaoka 859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Get the size of the DockWindow. 879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return If the DockWindow sticks to the top or bottom of the screen, the 899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * return value is the height of the DockWindow, and its width is 909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * equal to the width of the screen; If the DockWindow sticks to the 919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * left or right of the screen, the return value is the width of the 929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * DockWindow, and its height is equal to the height of the screen. 939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int getSize() { 959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project WindowManager.LayoutParams lp = getWindow().getAttributes(); 969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (lp.gravity == Gravity.TOP || lp.gravity == Gravity.BOTTOM) { 989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return lp.height; 999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 1009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return lp.width; 1019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Set the size of the DockWindow. 1069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 1079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param size If the DockWindow sticks to the top or bottom of the screen, 1089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <var>size</var> is the height of the DockWindow, and its width is 1099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * equal to the width of the screen; If the DockWindow sticks to the 1109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * left or right of the screen, <var>size</var> is the width of the 1119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * DockWindow, and its height is equal to the height of the screen. 1129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setSize(int size) { 1149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project WindowManager.LayoutParams lp = getWindow().getAttributes(); 1159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (lp.gravity == Gravity.TOP || lp.gravity == Gravity.BOTTOM) { 1179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project lp.width = -1; 1189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project lp.height = size; 1199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 1209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project lp.width = size; 1219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project lp.height = -1; 1229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project getWindow().setAttributes(lp); 1249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Set which boundary of the screen the DockWindow sticks to. 1289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 1299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param gravity The boundary of the screen to stick. See {#link 1309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * android.view.Gravity.LEFT}, {#link android.view.Gravity.TOP}, 1319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {#link android.view.Gravity.BOTTOM}, {#link 1329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * android.view.Gravity.RIGHT}. 1339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setGravity(int gravity) { 1359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project WindowManager.LayoutParams lp = getWindow().getAttributes(); 1369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean oldIsVertical = (lp.gravity == Gravity.TOP || lp.gravity == Gravity.BOTTOM); 1389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project lp.gravity = gravity; 1409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean newIsVertical = (lp.gravity == Gravity.TOP || lp.gravity == Gravity.BOTTOM); 1429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (oldIsVertical != newIsVertical) { 1449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int tmp = lp.width; 1459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project lp.width = lp.height; 1469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project lp.height = tmp; 1479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project getWindow().setAttributes(lp); 1489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private void initDockWindow() { 1529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project WindowManager.LayoutParams lp = getWindow().getAttributes(); 1539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project lp.type = WindowManager.LayoutParams.TYPE_INPUT_METHOD; 1559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project lp.setTitle("InputMethod"); 1569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project lp.gravity = Gravity.BOTTOM; 1589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project lp.width = -1; 1599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Let the input method window's orientation follow sensor based rotation 1609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Turn this off for now, it is very problematic. 1619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project //lp.screenOrientation = ActivityInfo.SCREEN_ORIENTATION_USER; 1629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project getWindow().setAttributes(lp); 1649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project getWindow().setFlags( 1659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN | 1669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE, 1679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN | 1689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE | 1699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project WindowManager.LayoutParams.FLAG_DIM_BEHIND); 1709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 172