• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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  * @hide
34  */
35 public class SoftInputWindow extends Dialog {
36     final String mName;
37     final Callback mCallback;
38     final KeyEvent.Callback mKeyEventCallback;
39     final KeyEvent.DispatcherState mDispatcherState;
40     final int mWindowType;
41     final int mGravity;
42     final boolean mTakesFocus;
43     private final Rect mBounds = new Rect();
44 
45     public interface Callback {
onBackPressed()46         public void onBackPressed();
47     }
48 
setToken(IBinder token)49     public void setToken(IBinder token) {
50         WindowManager.LayoutParams lp = getWindow().getAttributes();
51         lp.token = token;
52         getWindow().setAttributes(lp);
53     }
54 
55     /**
56      * Create a SoftInputWindow that uses a custom style.
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      */
SoftInputWindow(Context context, String name, int theme, Callback callback, KeyEvent.Callback keyEventCallback, KeyEvent.DispatcherState dispatcherState, int windowType, int gravity, boolean takesFocus)67     public SoftInputWindow(Context context, String name, int theme, Callback callback,
68             KeyEvent.Callback keyEventCallback, KeyEvent.DispatcherState dispatcherState,
69             int windowType, int gravity, boolean takesFocus) {
70         super(context, theme);
71         mName = name;
72         mCallback = callback;
73         mKeyEventCallback = keyEventCallback;
74         mDispatcherState = dispatcherState;
75         mWindowType = windowType;
76         mGravity = gravity;
77         mTakesFocus = takesFocus;
78         initDockWindow();
79     }
80 
81     @Override
onWindowFocusChanged(boolean hasFocus)82     public void onWindowFocusChanged(boolean hasFocus) {
83         super.onWindowFocusChanged(hasFocus);
84         mDispatcherState.reset();
85     }
86 
87     @Override
dispatchTouchEvent(MotionEvent ev)88     public boolean dispatchTouchEvent(MotionEvent ev) {
89         getWindow().getDecorView().getHitRect(mBounds);
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         }
101     }
102 
103     /**
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      */
setGravity(int gravity)111     public void setGravity(int gravity) {
112         WindowManager.LayoutParams lp = getWindow().getAttributes();
113         lp.gravity = gravity;
114         updateWidthHeight(lp);
115         getWindow().setAttributes(lp);
116     }
117 
getGravity()118     public int getGravity() {
119         return getWindow().getAttributes().gravity;
120     }
121 
updateWidthHeight(WindowManager.LayoutParams lp)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;
129         }
130     }
131 
onKeyDown(int keyCode, KeyEvent event)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 
onKeyLongPress(int keyCode, KeyEvent event)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 
onKeyUp(int keyCode, KeyEvent event)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 
onKeyMultiple(int keyCode, int count, KeyEvent event)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 
onBackPressed()160     public void onBackPressed() {
161         if (mCallback != null) {
162             mCallback.onBackPressed();
163         } else {
164             super.onBackPressed();
165         }
166     }
167 
initDockWindow()168     private void initDockWindow() {
169         WindowManager.LayoutParams lp = getWindow().getAttributes();
170 
171         lp.type = mWindowType;
172         lp.setTitle(mName);
173 
174         lp.gravity = mGravity;
175         updateWidthHeight(lp);
176 
177         getWindow().setAttributes(lp);
178 
179         int windowSetFlags = WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN;
180         int windowModFlags = WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN |
181                 WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE |
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);
192     }
193 }
194