Wed, 31 Dec 2014 06:09:35 +0100
Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.
1 /* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
2 * This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 package org.mozilla.gecko.widget;
8 import org.mozilla.gecko.GeckoApp;
9 import org.mozilla.gecko.R;
10 import org.mozilla.gecko.util.HardwareUtils;
12 import android.content.res.Resources;
13 import android.graphics.drawable.BitmapDrawable;
14 import android.os.Build;
15 import android.view.Gravity;
16 import android.view.LayoutInflater;
17 import android.view.View;
18 import android.view.ViewGroup;
19 import android.widget.ImageView;
20 import android.widget.LinearLayout;
21 import android.widget.PopupWindow;
22 import android.widget.RelativeLayout;
24 public class ArrowPopup extends PopupWindow {
25 protected final GeckoApp mActivity;
27 private View mAnchor;
28 private ImageView mArrow;
30 private int mArrowWidth;
31 private int mYOffset;
33 protected LinearLayout mContent;
34 protected boolean mInflated;
36 public ArrowPopup(GeckoApp aActivity) {
37 this(aActivity, null);
38 }
40 public ArrowPopup(GeckoApp activity, View anchor) {
41 super(activity);
42 mActivity = activity;
43 mAnchor = anchor;
45 mInflated = false;
47 final Resources res = activity.getResources();
48 mArrowWidth = res.getDimensionPixelSize(R.dimen.menu_popup_arrow_width);
49 mYOffset = res.getDimensionPixelSize(R.dimen.menu_popup_arrow_offset);
51 setAnimationStyle(R.style.PopupAnimation);
52 }
54 public void setAnchor(View anchor) {
55 mAnchor = anchor;
56 }
58 protected void init() {
59 setBackgroundDrawable(new BitmapDrawable());
60 setOutsideTouchable(true);
62 setWindowLayoutMode(HardwareUtils.isTablet() ? ViewGroup.LayoutParams.WRAP_CONTENT : ViewGroup.LayoutParams.FILL_PARENT,
63 ViewGroup.LayoutParams.WRAP_CONTENT);
65 LayoutInflater inflater = LayoutInflater.from(mActivity);
66 RelativeLayout layout = (RelativeLayout) inflater.inflate(R.layout.arrow_popup, null);
67 setContentView(layout);
69 mArrow = (ImageView) layout.findViewById(R.id.arrow);
70 mContent = (LinearLayout) layout.findViewById(R.id.content);
72 mInflated = true;
73 }
75 /*
76 * Shows the popup with the arrow pointing to the center of the anchor view. If an anchor hasn't
77 * been set or isn't visible, the popup will just be shown at the top of the gecko app view.
78 */
79 public void show() {
80 int[] anchorLocation = new int[2];
81 if (mAnchor != null)
82 mAnchor.getLocationInWindow(anchorLocation);
84 // If there's no anchor or the anchor is out of the window bounds,
85 // just show the popup at the top of the gecko app view.
86 if (mAnchor == null || anchorLocation[1] < 0) {
87 final View view = mActivity.getView();
89 // Bug in android code causes the window layout parameters to be ignored
90 // when using showAtLocation() in Gingerbread phones.
91 if (Build.VERSION.SDK_INT < 11) {
92 setWidth(view.getWidth());
93 setHeight(view.getHeight());
94 }
96 showAtLocation(view, Gravity.TOP, 0, 0);
97 return;
98 }
100 // Remove padding from the width of the anchor when calculating the arrow offset.
101 int anchorWidth = mAnchor.getWidth() - mAnchor.getPaddingLeft() - mAnchor.getPaddingRight();
102 // This is the difference between the edge of the anchor view and the edge of the arrow view.
103 // We're making an assumption here that the anchor view is wider than the arrow view.
104 int arrowOffset = (anchorWidth - mArrowWidth)/2 + mAnchor.getPaddingLeft();
106 // The horizontal offset of the popup window, relative to the left side of the anchor view.
107 int offset = 0;
109 RelativeLayout.LayoutParams arrowLayoutParams = (RelativeLayout.LayoutParams) mArrow.getLayoutParams();
111 if (HardwareUtils.isTablet()) {
112 // On tablets, the popup has a fixed width, so we use a horizontal offset to position it.
113 // The arrow's left margin is set by the arrow_popup.xml layout file.
114 // This assumes that anchor is not too close to the right side of the screen.
115 offset = arrowOffset - arrowLayoutParams.leftMargin;
116 } else {
117 // On phones, the popup takes up the width of the screen, so we set the arrow's left
118 // margin to make it line up with the anchor.
119 int leftMargin = anchorLocation[0] + arrowOffset;
120 arrowLayoutParams.setMargins(leftMargin, 0, 0, 0);
121 }
123 if (isShowing()) {
124 update(mAnchor, offset, -mYOffset, -1, -1);
125 } else {
126 showAsDropDown(mAnchor, offset, -mYOffset);
127 }
128 }
129 }