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