package carbon.internal;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.content.Context;
import android.content.res.Resources;
import android.graphics.Rect;
import android.graphics.drawable.ColorDrawable;
import android.support.v7.widget.LinearLayoutManager;
import android.view.Gravity;
import android.view.KeyEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.PopupWindow;
import android.widget.TextView;
import carbon.R;
import carbon.recycler.ArrayAdapter;
import carbon.widget.DropDown;
import carbon.widget.FrameLayout;
import carbon.widget.RecyclerView;
public class DropDownMenu extends PopupWindow {
protected RecyclerView recycler;
private View mAnchorView;
private DropDown.Mode mode;
public DropDownMenu(Context context) {
super(View.inflate(context, R.layout.carbon_popupmenu, null));
getContentView().setLayoutParams(new ViewGroup.MarginLayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
recycler = (RecyclerView) getContentView().findViewById(R.id.recycler);
recycler.setLayoutManager(new LinearLayoutManager(context, LinearLayoutManager.VERTICAL, false));
recycler.setOnKeyListener((v, keyCode, event) -> {
if (event.getAction() == KeyEvent.ACTION_UP &&
(keyCode == KeyEvent.KEYCODE_MENU || keyCode == KeyEvent.KEYCODE_BACK)) {
dismiss();
return true;
}
return false;
});
setBackgroundDrawable(new ColorDrawable(context.getResources().getColor(android.R.color.transparent)));
setTouchable(true);
setFocusable(true);
setOutsideTouchable(true);
setAnimationStyle(0);
}
public boolean show(View anchor) {
mAnchorView = anchor;
super.showAtLocation(anchor, Gravity.START | Gravity.TOP, 0, 0);
update();
FrameLayout content = (FrameLayout) getContentView().findViewById(R.id.carbon_popupContainer);
content.animateVisibility(View.VISIBLE);
return true;
}
public boolean showImmediate(View anchor) {
mAnchorView = anchor;
super.showAtLocation(anchor, Gravity.START | Gravity.TOP, 0, 0);
update();
FrameLayout content = (FrameLayout) getContentView().findViewById(R.id.carbon_popupContainer);
content.setVisibility(View.VISIBLE);
return true;
}
public void update() {
if (mAnchorView == null)
return;
setClippingEnabled(mode == DropDown.Mode.Fit);
final Resources res = getContentView().getContext().getResources();
int margin = (int) res.getDimension(R.dimen.carbon_padding);
int itemHeight = (int) res.getDimension(R.dimen.carbon_listItemHeight);
int marginHalf = (int) res.getDimension(R.dimen.carbon_paddingHalf);
int selectedItem = 0;
ArrayAdapter adapter = getAdapter();
if (mAnchorView instanceof android.widget.TextView) {
TextView textView = (TextView) mAnchorView;
String text = textView.getText().toString();
for (int i = 0; i < adapter.getItemCount(); i++) {
if (adapter.getItem(i).toString().equals(text)) {
selectedItem = i;
break;
}
}
}
Rect windowRect = new Rect();
mAnchorView.getWindowVisibleDisplayFrame(windowRect);
int hWindow = windowRect.bottom - windowRect.top;
int wWindow = windowRect.right - windowRect.left;
int[] location = new int[2];
mAnchorView.getLocationInWindow(location);
if (mode == DropDown.Mode.Over) {
int maxHeightAbove = location[1] - windowRect.top - marginHalf * 2;
int maxItemsAbove = maxHeightAbove / itemHeight;
int maxHeightBelow = hWindow - location[1] - marginHalf * 2;
int maxItemsBelow = maxHeightBelow / itemHeight + 1;
int itemsBelow = Math.min(adapter.getItemCount() - selectedItem, maxItemsBelow);
int itemsAbove = Math.min(selectedItem, maxItemsAbove);
int popupX = location[0] - margin - marginHalf;
int popupY = location[1] - marginHalf * 2 - itemsAbove * itemHeight - (itemHeight - (mAnchorView.getHeight() - mAnchorView.getPaddingTop() - mAnchorView.getPaddingBottom())) / 2 + mAnchorView.getPaddingTop();
int popupWidth = mAnchorView.getWidth() + margin * 2 + marginHalf * 2 - mAnchorView.getPaddingLeft() - mAnchorView.getPaddingRight();
int popupHeight = marginHalf * 4 + Math.max(1, itemsAbove + itemsBelow) * itemHeight;
LinearLayoutManager manager = (LinearLayoutManager) recycler.getLayoutManager();
manager.scrollToPositionWithOffset(selectedItem - itemsAbove, 0);
update(popupX, popupY, popupWidth, popupHeight);
} else {
int maxItems = (hWindow - marginHalf * 2 - margin * 2) / itemHeight;
int popupX = location[0] - margin - marginHalf;
int popupY = location[1] - marginHalf * 2 - (itemHeight - (mAnchorView.getHeight() - mAnchorView.getPaddingTop() - mAnchorView.getPaddingBottom())) / 2 + mAnchorView.getPaddingTop();
int popupWidth = mAnchorView.getWidth() + margin * 2 + marginHalf * 2 - mAnchorView.getPaddingLeft() - mAnchorView.getPaddingRight();
int popupHeight = marginHalf * 4 + Math.min(recycler.getAdapter().getItemCount(), maxItems) * itemHeight;
LinearLayoutManager manager = (LinearLayoutManager) recycler.getLayoutManager();
manager.scrollToPosition(selectedItem);
update(popupX, popupY, popupWidth, popupHeight);
}
super.update();
}
@Override
public void dismiss() {
FrameLayout content = (FrameLayout) getContentView().findViewById(R.id.carbon_popupContainer);
content.animateVisibility(View.INVISIBLE).addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
DropDownMenu.super.dismiss();
}
});
}
public void dismissImmediate() {
super.dismiss();
}
/*
private int measureContentWidth(android.support.v7.widget.RecyclerView.Adapter adapter) {
// Menus don't tend to be long, so this is more sane than it looks.
int width = 0;
View itemView = null;
int itemType = 0;
final int widthMeasureSpec =
View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED);
final int heightMeasureSpec =
View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED);
final int count = adapter.getItemCount();
for (int i = 0; i < count; i++) {
final int positionType = adapter.getItemViewType(i);
if (positionType != itemType) {
itemType = positionType;
itemView = null;
}
if (mMeasureParent == null) {
mMeasureParent = new FrameLayout(getContentView().getContext());
}
itemView = adapter.getView(i, itemView, mMeasureParent);
itemView.measure(widthMeasureSpec, heightMeasureSpec);
width = Math.max(width, itemView.getMeasuredWidth());
}
return width;
}*/
public void setOnItemClickedListener(RecyclerView.OnItemClickedListener listener) {
getAdapter().setOnItemClickedListener(listener);
}
public void setAdapter(RecyclerView.Adapter adapter) {
recycler.setAdapter(adapter);
}
public ArrayAdapter getAdapter() {
return (ArrayAdapter) recycler.getAdapter();
}
public DropDown.Mode getMode() {
return mode;
}
public void setMode(DropDown.Mode mode) {
this.mode = mode;
}
/* @Override
public boolean onSubMenuSelected(SubMenuBuilder subMenu) {
if (subMenu.hasVisibleItems()) {
PopupMenu subPopup = new PopupMenu(mContext, subMenu, false);
subPopup.setCallback(mPresenterCallback);
boolean preserveIconSpacing = false;
final int count = subMenu.size();
for (int i = 0; i < count; i++) {
MenuItem childItem = subMenu.getItem(i);
if (childItem.isVisible() && childItem.getIcon() != null) {
preserveIconSpacing = true;
break;
}
}
if (subPopup.show(mAnchorView)) {
if (mPresenterCallback != null) {
mPresenterCallback.onOpenSubMenu(subMenu);
}
return true;
}
}
return false;
}*/
}