15ec2faa01bc6790bc015e0d5748dc0482ae8c0f2Chris Banes/*
25ec2faa01bc6790bc015e0d5748dc0482ae8c0f2Chris Banes * Copyright (C) 2014 The Android Open Source Project
35ec2faa01bc6790bc015e0d5748dc0482ae8c0f2Chris Banes *
45ec2faa01bc6790bc015e0d5748dc0482ae8c0f2Chris Banes * Licensed under the Apache License, Version 2.0 (the "License");
55ec2faa01bc6790bc015e0d5748dc0482ae8c0f2Chris Banes * you may not use this file except in compliance with the License.
65ec2faa01bc6790bc015e0d5748dc0482ae8c0f2Chris Banes * You may obtain a copy of the License at
75ec2faa01bc6790bc015e0d5748dc0482ae8c0f2Chris Banes *
85ec2faa01bc6790bc015e0d5748dc0482ae8c0f2Chris Banes *      http://www.apache.org/licenses/LICENSE-2.0
95ec2faa01bc6790bc015e0d5748dc0482ae8c0f2Chris Banes *
105ec2faa01bc6790bc015e0d5748dc0482ae8c0f2Chris Banes * Unless required by applicable law or agreed to in writing, software
115ec2faa01bc6790bc015e0d5748dc0482ae8c0f2Chris Banes * distributed under the License is distributed on an "AS IS" BASIS,
125ec2faa01bc6790bc015e0d5748dc0482ae8c0f2Chris Banes * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
135ec2faa01bc6790bc015e0d5748dc0482ae8c0f2Chris Banes * See the License for the specific language governing permissions and
145ec2faa01bc6790bc015e0d5748dc0482ae8c0f2Chris Banes * limitations under the License.
155ec2faa01bc6790bc015e0d5748dc0482ae8c0f2Chris Banes */
165ec2faa01bc6790bc015e0d5748dc0482ae8c0f2Chris Banes
1766698bb15ba0f873aa1c2290cc50d6bb839a474aChris Banespackage android.support.v7.widget;
185ec2faa01bc6790bc015e0d5748dc0482ae8c0f2Chris Banes
195ec2faa01bc6790bc015e0d5748dc0482ae8c0f2Chris Banesimport android.content.Context;
205ec2faa01bc6790bc015e0d5748dc0482ae8c0f2Chris Banesimport android.os.Build;
21b2d5231158a58f03b611a8e4065de02938c54e26Chris Banesimport android.support.annotation.AttrRes;
22b2d5231158a58f03b611a8e4065de02938c54e26Chris Banesimport android.support.annotation.NonNull;
23b2d5231158a58f03b611a8e4065de02938c54e26Chris Banesimport android.support.annotation.Nullable;
24b2d5231158a58f03b611a8e4065de02938c54e26Chris Banesimport android.support.annotation.StyleRes;
2544918a92e1d66a01a03063e2c5e68b2570f64b03Chris Banesimport android.support.v4.widget.PopupWindowCompat;
265ec2faa01bc6790bc015e0d5748dc0482ae8c0f2Chris Banesimport android.support.v7.appcompat.R;
275ec2faa01bc6790bc015e0d5748dc0482ae8c0f2Chris Banesimport android.util.AttributeSet;
285ec2faa01bc6790bc015e0d5748dc0482ae8c0f2Chris Banesimport android.view.View;
295ec2faa01bc6790bc015e0d5748dc0482ae8c0f2Chris Banesimport android.widget.PopupWindow;
305ec2faa01bc6790bc015e0d5748dc0482ae8c0f2Chris Banes
31b2d5231158a58f03b611a8e4065de02938c54e26Chris Banesclass AppCompatPopupWindow extends PopupWindow {
325ec2faa01bc6790bc015e0d5748dc0482ae8c0f2Chris Banes
3344918a92e1d66a01a03063e2c5e68b2570f64b03Chris Banes    private static final boolean COMPAT_OVERLAP_ANCHOR = Build.VERSION.SDK_INT < 21;
3445266b3d81b349b34c5b8adb99e007d3c5b57d28Chris Banes
3544918a92e1d66a01a03063e2c5e68b2570f64b03Chris Banes    private boolean mOverlapAnchor;
365ec2faa01bc6790bc015e0d5748dc0482ae8c0f2Chris Banes
37b2d5231158a58f03b611a8e4065de02938c54e26Chris Banes    public AppCompatPopupWindow(@NonNull Context context, @Nullable AttributeSet attrs,
38b2d5231158a58f03b611a8e4065de02938c54e26Chris Banes            @AttrRes int defStyleAttr) {
395ec2faa01bc6790bc015e0d5748dc0482ae8c0f2Chris Banes        super(context, attrs, defStyleAttr);
40b2d5231158a58f03b611a8e4065de02938c54e26Chris Banes        init(context, attrs, defStyleAttr, 0);
41b2d5231158a58f03b611a8e4065de02938c54e26Chris Banes    }
42b2d5231158a58f03b611a8e4065de02938c54e26Chris Banes
43b2d5231158a58f03b611a8e4065de02938c54e26Chris Banes    public AppCompatPopupWindow(@NonNull Context context, @Nullable AttributeSet attrs,
44b2d5231158a58f03b611a8e4065de02938c54e26Chris Banes            @AttrRes int defStyleAttr, @StyleRes int defStyleRes) {
45b2d5231158a58f03b611a8e4065de02938c54e26Chris Banes        super(context, attrs, defStyleAttr, defStyleRes);
46b2d5231158a58f03b611a8e4065de02938c54e26Chris Banes        init(context, attrs, defStyleAttr, defStyleRes);
47b2d5231158a58f03b611a8e4065de02938c54e26Chris Banes    }
485ec2faa01bc6790bc015e0d5748dc0482ae8c0f2Chris Banes
49b2d5231158a58f03b611a8e4065de02938c54e26Chris Banes    private void init(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
50469286122bcbbecbdd0bef74fb50f9d8920e77b9Chris Banes        TintTypedArray a = TintTypedArray.obtainStyledAttributes(context, attrs,
51b2d5231158a58f03b611a8e4065de02938c54e26Chris Banes                R.styleable.PopupWindow, defStyleAttr, defStyleRes);
5244918a92e1d66a01a03063e2c5e68b2570f64b03Chris Banes        if (a.hasValue(R.styleable.PopupWindow_overlapAnchor)) {
5344918a92e1d66a01a03063e2c5e68b2570f64b03Chris Banes            setSupportOverlapAnchor(a.getBoolean(R.styleable.PopupWindow_overlapAnchor, false));
5444918a92e1d66a01a03063e2c5e68b2570f64b03Chris Banes        }
55469286122bcbbecbdd0bef74fb50f9d8920e77b9Chris Banes        // We re-set this for tinting purposes
56469286122bcbbecbdd0bef74fb50f9d8920e77b9Chris Banes        setBackgroundDrawable(a.getDrawable(R.styleable.PopupWindow_android_popupBackground));
57b2d5231158a58f03b611a8e4065de02938c54e26Chris Banes
585ec2faa01bc6790bc015e0d5748dc0482ae8c0f2Chris Banes        a.recycle();
595ec2faa01bc6790bc015e0d5748dc0482ae8c0f2Chris Banes    }
605ec2faa01bc6790bc015e0d5748dc0482ae8c0f2Chris Banes
615ec2faa01bc6790bc015e0d5748dc0482ae8c0f2Chris Banes    @Override
625ec2faa01bc6790bc015e0d5748dc0482ae8c0f2Chris Banes    public void showAsDropDown(View anchor, int xoff, int yoff) {
6344918a92e1d66a01a03063e2c5e68b2570f64b03Chris Banes        if (COMPAT_OVERLAP_ANCHOR && mOverlapAnchor) {
645ec2faa01bc6790bc015e0d5748dc0482ae8c0f2Chris Banes            // If we're pre-L, emulate overlapAnchor by modifying the yOff
655ec2faa01bc6790bc015e0d5748dc0482ae8c0f2Chris Banes            yoff -= anchor.getHeight();
665ec2faa01bc6790bc015e0d5748dc0482ae8c0f2Chris Banes        }
675ec2faa01bc6790bc015e0d5748dc0482ae8c0f2Chris Banes        super.showAsDropDown(anchor, xoff, yoff);
685ec2faa01bc6790bc015e0d5748dc0482ae8c0f2Chris Banes    }
695ec2faa01bc6790bc015e0d5748dc0482ae8c0f2Chris Banes
705ec2faa01bc6790bc015e0d5748dc0482ae8c0f2Chris Banes    @Override
715ec2faa01bc6790bc015e0d5748dc0482ae8c0f2Chris Banes    public void showAsDropDown(View anchor, int xoff, int yoff, int gravity) {
7244918a92e1d66a01a03063e2c5e68b2570f64b03Chris Banes        if (COMPAT_OVERLAP_ANCHOR && mOverlapAnchor) {
735ec2faa01bc6790bc015e0d5748dc0482ae8c0f2Chris Banes            // If we're pre-L, emulate overlapAnchor by modifying the yOff
745ec2faa01bc6790bc015e0d5748dc0482ae8c0f2Chris Banes            yoff -= anchor.getHeight();
755ec2faa01bc6790bc015e0d5748dc0482ae8c0f2Chris Banes        }
765ec2faa01bc6790bc015e0d5748dc0482ae8c0f2Chris Banes        super.showAsDropDown(anchor, xoff, yoff, gravity);
775ec2faa01bc6790bc015e0d5748dc0482ae8c0f2Chris Banes    }
785ec2faa01bc6790bc015e0d5748dc0482ae8c0f2Chris Banes
795ec2faa01bc6790bc015e0d5748dc0482ae8c0f2Chris Banes    @Override
805ec2faa01bc6790bc015e0d5748dc0482ae8c0f2Chris Banes    public void update(View anchor, int xoff, int yoff, int width, int height) {
8144918a92e1d66a01a03063e2c5e68b2570f64b03Chris Banes        if (COMPAT_OVERLAP_ANCHOR && mOverlapAnchor) {
825ec2faa01bc6790bc015e0d5748dc0482ae8c0f2Chris Banes            // If we're pre-L, emulate overlapAnchor by modifying the yOff
835ec2faa01bc6790bc015e0d5748dc0482ae8c0f2Chris Banes            yoff -= anchor.getHeight();
845ec2faa01bc6790bc015e0d5748dc0482ae8c0f2Chris Banes        }
855ec2faa01bc6790bc015e0d5748dc0482ae8c0f2Chris Banes        super.update(anchor, xoff, yoff, width, height);
865ec2faa01bc6790bc015e0d5748dc0482ae8c0f2Chris Banes    }
8745266b3d81b349b34c5b8adb99e007d3c5b57d28Chris Banes
883d7a21e05a131f5d98f65d45c586d122803aa5daAurimas Liutikas    private void setSupportOverlapAnchor(boolean overlapAnchor) {
8944918a92e1d66a01a03063e2c5e68b2570f64b03Chris Banes        if (COMPAT_OVERLAP_ANCHOR) {
9044918a92e1d66a01a03063e2c5e68b2570f64b03Chris Banes            mOverlapAnchor = overlapAnchor;
9144918a92e1d66a01a03063e2c5e68b2570f64b03Chris Banes        } else {
9244918a92e1d66a01a03063e2c5e68b2570f64b03Chris Banes            PopupWindowCompat.setOverlapAnchor(this, overlapAnchor);
9344918a92e1d66a01a03063e2c5e68b2570f64b03Chris Banes        }
9444918a92e1d66a01a03063e2c5e68b2570f64b03Chris Banes    }
955ec2faa01bc6790bc015e0d5748dc0482ae8c0f2Chris Banes}
96