Upstream version 7.36.149.0
[platform/framework/web/crosswalk.git] / src / ui / android / java / src / org / chromium / ui / DropdownPopupWindow.java
1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 package org.chromium.ui;
6
7 import android.content.Context;
8 import android.view.View;
9 import android.view.View.MeasureSpec;
10 import android.view.View.OnLayoutChangeListener;
11 import android.view.ViewGroup;
12 import android.widget.LinearLayout;
13 import android.widget.ListAdapter;
14 import android.widget.ListPopupWindow;
15
16 import org.chromium.ui.base.ViewAndroidDelegate;
17
18 /**
19  * The dropdown list popup window.
20  */
21 public class DropdownPopupWindow extends ListPopupWindow {
22
23     private final Context mContext;
24     private final ViewAndroidDelegate mViewAndroidDelegate;
25     private final View mAnchorView;
26     private float mAnchorWidth;
27     private float mAnchorHeight;
28     private float mAnchorX;
29     private float mAnchorY;
30     private OnLayoutChangeListener mLayoutChangeListener;
31
32     /**
33      * Creates an DropdownPopupWindow with specified parameters.
34      * @param context Application context.
35      * @param viewAndroidDelegate View delegate used to add and remove views.
36      */
37     public DropdownPopupWindow(Context context, ViewAndroidDelegate viewAndroidDelegate) {
38         super(context, null, 0, R.style.DropdownPopupWindow);
39         mContext = context;
40         mViewAndroidDelegate = viewAndroidDelegate;
41
42         mAnchorView = mViewAndroidDelegate.acquireAnchorView();
43         mAnchorView.setId(R.id.dropdown_popup_window);
44         mAnchorView.setTag(this);
45
46         mLayoutChangeListener = new OnLayoutChangeListener() {
47             @Override
48             public void onLayoutChange(View v, int left, int top, int right, int bottom,
49                     int oldLeft, int oldTop, int oldRight, int oldBottom) {
50                 if (v == mAnchorView) DropdownPopupWindow.this.show();
51             }
52         };
53
54         mAnchorView.addOnLayoutChangeListener(mLayoutChangeListener);
55         setAnchorView(mAnchorView);
56     }
57
58     /**
59      * Sets the location and the size of the anchor view that the DropdownPopupWindow will use to
60      * attach itself.
61      * @param x X coordinate of the top left corner of the anchor view.
62      * @param y Y coordinate of the top left corner of the anchor view.
63      * @param width The width of the anchor view.
64      * @param height The height of the anchor view.
65      */
66     public void setAnchorRect(float x, float y, float width, float height) {
67         mAnchorWidth = width;
68         mAnchorHeight = height;
69         mAnchorX = x;
70         mAnchorY = y;
71         if (mAnchorView != null) {
72             mViewAndroidDelegate.setAnchorViewPosition(mAnchorView, mAnchorX, mAnchorY,
73                     mAnchorWidth, mAnchorHeight);
74         }
75     }
76
77     @Override
78     public void show() {
79         // An ugly hack to keep the popup from expanding on top of the keyboard.
80         setInputMethodMode(INPUT_METHOD_NEEDED);
81         super.show();
82         getListView().setDividerHeight(0);
83         int contentWidth = measureContentWidth();
84         float contentWidthInDip = contentWidth /
85                 mContext.getResources().getDisplayMetrics().density;
86         if (contentWidthInDip > mAnchorWidth) {
87             setContentWidth(contentWidth);
88         } else {
89             setWidth(ViewGroup.LayoutParams.WRAP_CONTENT);
90         }
91         mViewAndroidDelegate.setAnchorViewPosition(mAnchorView, mAnchorX, mAnchorY, mAnchorWidth,
92                 mAnchorHeight);
93     }
94
95     @Override
96     public void dismiss() {
97         super.dismiss();
98         mAnchorView.removeOnLayoutChangeListener(mLayoutChangeListener);
99         mAnchorView.setTag(null);
100         mViewAndroidDelegate.releaseAnchorView(mAnchorView);
101     }
102
103     /**
104      * Measures the width of the list content.
105      * @return The popup window width in pixels.
106      */
107     private int measureContentWidth() {
108         int maxWidth = 0;
109         View itemView = null;
110         final ListAdapter adapter = getListView().getAdapter();
111         if (adapter == null)
112           return 0;
113         final int widthMeasureSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
114         final int heightMeasureSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
115         for (int i = 0; i < adapter.getCount(); i++) {
116             itemView = adapter.getView(i, itemView, null);
117             LinearLayout.LayoutParams params =
118                     new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT,
119                             LinearLayout.LayoutParams.WRAP_CONTENT);
120             itemView.setLayoutParams(params);
121             itemView.measure(widthMeasureSpec, heightMeasureSpec);
122             maxWidth = Math.max(maxWidth, itemView.getMeasuredWidth());
123         }
124         return maxWidth;
125     }
126 }