mobile/android/base/widget/ArrowPopup.java

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/mobile/android/base/widget/ArrowPopup.java	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,129 @@
     1.4 +/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
     1.5 + * This Source Code Form is subject to the terms of the Mozilla Public
     1.6 + * License, v. 2.0. If a copy of the MPL was not distributed with this
     1.7 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     1.8 +
     1.9 +package org.mozilla.gecko.widget;
    1.10 +
    1.11 +import org.mozilla.gecko.GeckoApp;
    1.12 +import org.mozilla.gecko.R;
    1.13 +import org.mozilla.gecko.util.HardwareUtils;
    1.14 +
    1.15 +import android.content.res.Resources;
    1.16 +import android.graphics.drawable.BitmapDrawable;
    1.17 +import android.os.Build;
    1.18 +import android.view.Gravity;
    1.19 +import android.view.LayoutInflater;
    1.20 +import android.view.View;
    1.21 +import android.view.ViewGroup;
    1.22 +import android.widget.ImageView;
    1.23 +import android.widget.LinearLayout;
    1.24 +import android.widget.PopupWindow;
    1.25 +import android.widget.RelativeLayout;
    1.26 +
    1.27 +public class ArrowPopup extends PopupWindow {
    1.28 +    protected final GeckoApp mActivity;
    1.29 +
    1.30 +    private View mAnchor;
    1.31 +    private ImageView mArrow;
    1.32 +
    1.33 +    private int mArrowWidth;
    1.34 +    private int mYOffset;
    1.35 +
    1.36 +    protected LinearLayout mContent;
    1.37 +    protected boolean mInflated;
    1.38 +
    1.39 +    public ArrowPopup(GeckoApp aActivity) {
    1.40 +        this(aActivity, null);
    1.41 +    }
    1.42 +
    1.43 +    public ArrowPopup(GeckoApp activity, View anchor) {
    1.44 +        super(activity);
    1.45 +        mActivity = activity;
    1.46 +        mAnchor = anchor;
    1.47 +
    1.48 +        mInflated = false;
    1.49 +
    1.50 +        final Resources res = activity.getResources();
    1.51 +        mArrowWidth = res.getDimensionPixelSize(R.dimen.menu_popup_arrow_width);
    1.52 +        mYOffset = res.getDimensionPixelSize(R.dimen.menu_popup_arrow_offset);
    1.53 +
    1.54 +        setAnimationStyle(R.style.PopupAnimation);
    1.55 +    }
    1.56 +
    1.57 +    public void setAnchor(View anchor) {
    1.58 +        mAnchor = anchor;
    1.59 +    }
    1.60 +
    1.61 +    protected void init() {
    1.62 +        setBackgroundDrawable(new BitmapDrawable());
    1.63 +        setOutsideTouchable(true);
    1.64 +
    1.65 +        setWindowLayoutMode(HardwareUtils.isTablet() ? ViewGroup.LayoutParams.WRAP_CONTENT : ViewGroup.LayoutParams.FILL_PARENT,
    1.66 +            ViewGroup.LayoutParams.WRAP_CONTENT);
    1.67 +
    1.68 +        LayoutInflater inflater = LayoutInflater.from(mActivity);
    1.69 +        RelativeLayout layout = (RelativeLayout) inflater.inflate(R.layout.arrow_popup, null);
    1.70 +        setContentView(layout);
    1.71 +
    1.72 +        mArrow = (ImageView) layout.findViewById(R.id.arrow);
    1.73 +        mContent = (LinearLayout) layout.findViewById(R.id.content);
    1.74 +
    1.75 +        mInflated = true;
    1.76 +    }
    1.77 +
    1.78 +    /*
    1.79 +     * Shows the popup with the arrow pointing to the center of the anchor view. If an anchor hasn't
    1.80 +     * been set or isn't visible, the popup will just be shown at the top of the gecko app view.
    1.81 +     */
    1.82 +    public void show() {
    1.83 +        int[] anchorLocation = new int[2];
    1.84 +        if (mAnchor != null)
    1.85 +            mAnchor.getLocationInWindow(anchorLocation);
    1.86 +
    1.87 +        // If there's no anchor or the anchor is out of the window bounds,
    1.88 +        // just show the popup at the top of the gecko app view.
    1.89 +        if (mAnchor == null || anchorLocation[1] < 0) {
    1.90 +            final View view = mActivity.getView();
    1.91 +
    1.92 +            // Bug in android code causes the window layout parameters to be ignored
    1.93 +            // when using showAtLocation() in Gingerbread phones.
    1.94 +            if (Build.VERSION.SDK_INT < 11) {
    1.95 +                setWidth(view.getWidth());
    1.96 +                setHeight(view.getHeight());
    1.97 +            }
    1.98 +
    1.99 +            showAtLocation(view, Gravity.TOP, 0, 0);
   1.100 +            return;
   1.101 +        }
   1.102 +
   1.103 +        // Remove padding from the width of the anchor when calculating the arrow offset.
   1.104 +        int anchorWidth = mAnchor.getWidth() - mAnchor.getPaddingLeft() - mAnchor.getPaddingRight();
   1.105 +        // This is the difference between the edge of the anchor view and the edge of the arrow view.
   1.106 +        // We're making an assumption here that the anchor view is wider than the arrow view.
   1.107 +        int arrowOffset = (anchorWidth - mArrowWidth)/2 + mAnchor.getPaddingLeft();
   1.108 +
   1.109 +        // The horizontal offset of the popup window, relative to the left side of the anchor view.
   1.110 +        int offset = 0;
   1.111 +
   1.112 +        RelativeLayout.LayoutParams arrowLayoutParams = (RelativeLayout.LayoutParams) mArrow.getLayoutParams();
   1.113 +
   1.114 +        if (HardwareUtils.isTablet()) {
   1.115 +            // On tablets, the popup has a fixed width, so we use a horizontal offset to position it.
   1.116 +            // The arrow's left margin is set by the arrow_popup.xml layout file.
   1.117 +            // This assumes that anchor is not too close to the right side of the screen.
   1.118 +            offset = arrowOffset - arrowLayoutParams.leftMargin;
   1.119 +        } else {
   1.120 +            // On phones, the popup takes up the width of the screen, so we set the arrow's left
   1.121 +            // margin to make it line up with the anchor.
   1.122 +            int leftMargin = anchorLocation[0] + arrowOffset;
   1.123 +            arrowLayoutParams.setMargins(leftMargin, 0, 0, 0);
   1.124 +        }
   1.125 +
   1.126 +        if (isShowing()) {
   1.127 +            update(mAnchor, offset, -mYOffset, -1, -1);
   1.128 +        } else {
   1.129 +            showAsDropDown(mAnchor, offset, -mYOffset);
   1.130 +        }
   1.131 +    }
   1.132 +}

mercurial