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; 21 import android.graphics.Rect; 22 import android.os.IBinder; 23 import android.view.Gravity; 24 import android.view.KeyEvent; 25 import android.view.MotionEvent; 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. 33 */ 34 class SoftInputWindow extends Dialog { 35 final KeyEvent.DispatcherState mDispatcherState; 36 private final Rect mBounds = new Rect(); 37 38 public void setToken(IBinder token) { 39 WindowManager.LayoutParams lp = getWindow().getAttributes(); 40 lp.token = token; 41 getWindow().setAttributes(lp); 42 } 43 44 /** 45 * Create a SoftInputWindow that uses a custom style. 46 * 47 * @param context The Context in which the DockWindow should run. In 48 * particular, it uses the window manager and theme from this context 49 * to present its UI. 50 * @param theme A style resource describing the theme to use for the window. 51 * See <a href="{@docRoot}reference/available-resources.html#stylesandthemes">Style 52 * and Theme Resources</a> for more information about defining and 53 * using styles. This theme is applied on top of the current theme in 54 * <var>context</var>. If 0, the default dialog theme will be used. 55 */ 56 public SoftInputWindow(Context context, int theme, 57 KeyEvent.DispatcherState dispatcherState) { 58 super(context, theme); 59 mDispatcherState = dispatcherState; 60 initDockWindow(); 61 } 62 63 @Override 64 public void onWindowFocusChanged(boolean hasFocus) { 65 super.onWindowFocusChanged(hasFocus); 66 mDispatcherState.reset(); 67 } 68 69 @Override 70 public boolean dispatchTouchEvent(MotionEvent ev) { 71 getWindow().getDecorView().getHitRect(mBounds); 72 73 if (ev.isWithinBoundsNoHistory(mBounds.left, mBounds.top, 74 mBounds.right - 1, mBounds.bottom - 1)) { 75 return super.dispatchTouchEvent(ev); 76 } else { 77 MotionEvent temp = ev.clampNoHistory(mBounds.left, mBounds.top, 78 mBounds.right - 1, mBounds.bottom - 1); 79 boolean handled = super.dispatchTouchEvent(temp); 80 temp.recycle(); 81 return handled; 82 } 83 } 84 85 /** 86 * Get the size of the DockWindow. 87 * 88 * @return If the DockWindow sticks to the top or bottom of the screen, the 89 * return value is the height of the DockWindow, and its width is 90 * equal to the width of the screen; If the DockWindow sticks to the 91 * left or right of the screen, the return value is the width of the 92 * DockWindow, and its height is equal to the height of the screen. 93 */ 94 public int getSize() { 95 WindowManager.LayoutParams lp = getWindow().getAttributes(); 96 97 if (lp.gravity == Gravity.TOP || lp.gravity == Gravity.BOTTOM) { 98 return lp.height; 99 } else { 100 return lp.width; 101 } 102 } 103 104 /** 105 * Set the size of the DockWindow. 106 * 107 * @param size If the DockWindow sticks to the top or bottom of the screen, 108 * <var>size</var> is the height of the DockWindow, and its width is 109 * equal to the width of the screen; If the DockWindow sticks to the 110 * left or right of the screen, <var>size</var> is the width of the 111 * DockWindow, and its height is equal to the height of the screen. 112 */ 113 public void setSize(int size) { 114 WindowManager.LayoutParams lp = getWindow().getAttributes(); 115 116 if (lp.gravity == Gravity.TOP || lp.gravity == Gravity.BOTTOM) { 117 lp.width = -1; 118 lp.height = size; 119 } else { 120 lp.width = size; 121 lp.height = -1; 122 } 123 getWindow().setAttributes(lp); 124 } 125 126 /** 127 * Set which boundary of the screen the DockWindow sticks to. 128 * 129 * @param gravity The boundary of the screen to stick. See {#link 130 * android.view.Gravity.LEFT}, {#link android.view.Gravity.TOP}, 131 * {#link android.view.Gravity.BOTTOM}, {#link 132 * android.view.Gravity.RIGHT}. 133 */ 134 public void setGravity(int gravity) { 135 WindowManager.LayoutParams lp = getWindow().getAttributes(); 136 137 boolean oldIsVertical = (lp.gravity == Gravity.TOP || lp.gravity == Gravity.BOTTOM); 138 139 lp.gravity = gravity; 140 141 boolean newIsVertical = (lp.gravity == Gravity.TOP || lp.gravity == Gravity.BOTTOM); 142 143 if (oldIsVertical != newIsVertical) { 144 int tmp = lp.width; 145 lp.width = lp.height; 146 lp.height = tmp; 147 getWindow().setAttributes(lp); 148 } 149 } 150 151 private void initDockWindow() { 152 WindowManager.LayoutParams lp = getWindow().getAttributes(); 153 154 lp.type = WindowManager.LayoutParams.TYPE_INPUT_METHOD; 155 lp.setTitle("InputMethod"); 156 157 lp.gravity = Gravity.BOTTOM; 158 lp.width = -1; 159 // Let the input method window's orientation follow sensor based rotation 160 // Turn this off for now, it is very problematic. 161 //lp.screenOrientation = ActivityInfo.SCREEN_ORIENTATION_USER; 162 163 getWindow().setAttributes(lp); 164 getWindow().setFlags( 165 WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN | 166 WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE, 167 WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN | 168 WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE | 169 WindowManager.LayoutParams.FLAG_DIM_BEHIND); 170 } 171 } 172