1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/mobile/android/base/ActionModeCompatView.java Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,174 @@ 1.4 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.5 + * License, v. 2.0. If a copy of the MPL was not distributed with this file, 1.6 + * You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.7 + 1.8 +package org.mozilla.gecko; 1.9 + 1.10 +import org.mozilla.gecko.animation.AnimationUtils; 1.11 +import org.mozilla.gecko.menu.GeckoMenu; 1.12 +import org.mozilla.gecko.widget.GeckoPopupMenu; 1.13 + 1.14 +import android.content.Context; 1.15 +import android.util.AttributeSet; 1.16 +import android.view.LayoutInflater; 1.17 +import android.view.Menu; 1.18 +import android.view.View; 1.19 +import android.view.ViewGroup; 1.20 +import android.view.animation.Animation; 1.21 +import android.view.animation.ScaleAnimation; 1.22 +import android.view.animation.TranslateAnimation; 1.23 +import android.widget.Button; 1.24 +import android.widget.ImageButton; 1.25 +import android.widget.LinearLayout; 1.26 + 1.27 +class ActionModeCompatView extends LinearLayout implements GeckoMenu.ActionItemBarPresenter { 1.28 + private final String LOGTAG = "GeckoActionModeCompatPresenter"; 1.29 + 1.30 + private static final int SPEC = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED); 1.31 + 1.32 + private Button mTitleView; 1.33 + private ImageButton mMenuButton; 1.34 + private ViewGroup mActionButtonBar; 1.35 + private GeckoPopupMenu mPopupMenu; 1.36 + 1.37 + // Maximum number of items to show as actions 1.38 + private static final int MAX_ACTION_ITEMS = 4; 1.39 + 1.40 + private int mActionButtonsWidth = 0; 1.41 + 1.42 + public ActionModeCompatView(Context context) { 1.43 + super(context); 1.44 + init(context); 1.45 + } 1.46 + 1.47 + public ActionModeCompatView(Context context, AttributeSet attrs) { 1.48 + super(context, attrs); 1.49 + init(context); 1.50 + } 1.51 + 1.52 + public ActionModeCompatView(Context context, AttributeSet attrs, int style) { 1.53 + super(context, attrs, style); 1.54 + init(context); 1.55 + } 1.56 + 1.57 + public void init(Context context) { 1.58 + LayoutInflater.from(context).inflate(R.layout.actionbar, this); 1.59 + 1.60 + mTitleView = (Button) findViewById(R.id.actionmode_title); 1.61 + mMenuButton = (ImageButton) findViewById(R.id.actionbar_menu); 1.62 + mActionButtonBar = (ViewGroup) findViewById(R.id.actionbar_buttons); 1.63 + 1.64 + mPopupMenu = new GeckoPopupMenu(getContext(), mMenuButton); 1.65 + ((GeckoMenu) mPopupMenu.getMenu()).setActionItemBarPresenter(this); 1.66 + 1.67 + mMenuButton.setOnClickListener(new View.OnClickListener() { 1.68 + public void onClick(View v) { 1.69 + openMenu(); 1.70 + } 1.71 + }); 1.72 + } 1.73 + 1.74 + public void initForMode(final ActionModeCompat mode) { 1.75 + mTitleView.setOnClickListener(mode); 1.76 + mPopupMenu.setOnMenuItemClickListener(mode); 1.77 + } 1.78 + 1.79 + public CharSequence getTitle() { 1.80 + return mTitleView.getText(); 1.81 + } 1.82 + 1.83 + public void setTitle(CharSequence title) { 1.84 + mTitleView.setText(title); 1.85 + } 1.86 + 1.87 + public void setTitle(int resId) { 1.88 + mTitleView.setText(resId); 1.89 + } 1.90 + 1.91 + public Menu getMenu() { 1.92 + return mPopupMenu.getMenu(); 1.93 + } 1.94 + 1.95 + public void invalidate() { 1.96 + // onFinishInflate may not have been called yet on some versions of Android 1.97 + if (mPopupMenu != null && mMenuButton != null) { 1.98 + mMenuButton.setVisibility(mPopupMenu.getMenu().hasVisibleItems() ? View.VISIBLE : View.GONE); 1.99 + } 1.100 + super.invalidate(); 1.101 + } 1.102 + 1.103 + /* GeckoMenu.ActionItemBarPresenter */ 1.104 + @Override 1.105 + public boolean addActionItem(View actionItem) { 1.106 + final int count = mActionButtonBar.getChildCount(); 1.107 + if (count >= MAX_ACTION_ITEMS) { 1.108 + return false; 1.109 + } 1.110 + 1.111 + int maxWidth = mActionButtonBar.getMeasuredWidth(); 1.112 + if (maxWidth == 0) { 1.113 + mActionButtonBar.measure(SPEC, SPEC); 1.114 + maxWidth = mActionButtonBar.getMeasuredWidth(); 1.115 + } 1.116 + 1.117 + // If the menu button is already visible, no need to account for it 1.118 + if (mMenuButton.getVisibility() == View.GONE) { 1.119 + // Since we don't know how many items will be added, we always reserve space for the overflow menu 1.120 + mMenuButton.measure(SPEC, SPEC); 1.121 + maxWidth -= mMenuButton.getMeasuredWidth(); 1.122 + } 1.123 + 1.124 + if (mActionButtonsWidth <= 0) { 1.125 + mActionButtonsWidth = 0; 1.126 + 1.127 + // Loop over child views, measure them, and add their width to the taken width 1.128 + for (int i = 0; i < count; i++) { 1.129 + View v = mActionButtonBar.getChildAt(i); 1.130 + v.measure(SPEC, SPEC); 1.131 + mActionButtonsWidth += v.getMeasuredWidth(); 1.132 + } 1.133 + } 1.134 + 1.135 + actionItem.measure(SPEC, SPEC); 1.136 + int w = actionItem.getMeasuredWidth(); 1.137 + if (mActionButtonsWidth + w < maxWidth) { 1.138 + // We cache the new width of our children. 1.139 + mActionButtonsWidth += w; 1.140 + mActionButtonBar.addView(actionItem); 1.141 + return true; 1.142 + } 1.143 + 1.144 + return false; 1.145 + } 1.146 + 1.147 + /* GeckoMenu.ActionItemBarPresenter */ 1.148 + @Override 1.149 + public void removeActionItem(View actionItem) { 1.150 + actionItem.measure(SPEC, SPEC); 1.151 + mActionButtonsWidth -= actionItem.getMeasuredWidth(); 1.152 + mActionButtonBar.removeView(actionItem); 1.153 + } 1.154 + 1.155 + public void openMenu() { 1.156 + mPopupMenu.openMenu(); 1.157 + } 1.158 + 1.159 + public void closeMenu() { 1.160 + mPopupMenu.dismiss(); 1.161 + } 1.162 + 1.163 + public void animateIn() { 1.164 + long duration = AnimationUtils.getShortDuration(getContext()); 1.165 + TranslateAnimation t = new TranslateAnimation(Animation.RELATIVE_TO_SELF, -0.5f, Animation.RELATIVE_TO_SELF, 0f, 1.166 + Animation.RELATIVE_TO_SELF, 0f, Animation.RELATIVE_TO_SELF, 0f); 1.167 + t.setDuration(duration); 1.168 + 1.169 + ScaleAnimation s = new ScaleAnimation(1f, 1f, 0f, 1f, 1.170 + Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f); 1.171 + s.setDuration((long) (duration * 1.5f)); 1.172 + 1.173 + mTitleView.startAnimation(t); 1.174 + mActionButtonBar.startAnimation(s); 1.175 + mMenuButton.startAnimation(s); 1.176 + } 1.177 +}