Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 6f542f5a authored by Clara Bayarri's avatar Clara Bayarri Committed by Android (Google) Code Review
Browse files

Merge "Floating toolbars: Encapsulate StandaloneActionMode view creation."

parents 55f149c7 399b5139
Loading
Loading
Loading
Loading
+81 −66
Original line number Diff line number Diff line
@@ -2694,73 +2694,12 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback {
                if (mActionModeView != null) {
                    mActionModeView.killMode();
                }
                ActionModeWrapper wrapperMode =
                        new ActionModeWrapper(mContext, wrappedCallback);
                ActionModeWrapper wrapperMode = new ActionModeWrapper(
                        mContext, wrappedCallback, new StandaloneActionModeProvider());
                if (callback.onCreateActionMode(wrapperMode, wrapperMode.getMenu())) {
                    if (wrapperMode.getType() == ActionMode.TYPE_PRIMARY) {
                        if (mActionModeView == null) {
                            if (isFloating()) {
                                // Use the action bar theme.
                                final TypedValue outValue = new TypedValue();
                                final Theme baseTheme = mContext.getTheme();
                                baseTheme.resolveAttribute(R.attr.actionBarTheme, outValue, true);

                                final Context actionBarContext;
                                if (outValue.resourceId != 0) {
                                    final Theme actionBarTheme = mContext.getResources().newTheme();
                                    actionBarTheme.setTo(baseTheme);
                                    actionBarTheme.applyStyle(outValue.resourceId, true);

                                    actionBarContext = new ContextThemeWrapper(mContext, 0);
                                    actionBarContext.getTheme().setTo(actionBarTheme);
                                } else {
                                    actionBarContext = mContext;
                                }

                                mActionModeView = new ActionBarContextView(actionBarContext);
                                mActionModePopup = new PopupWindow(actionBarContext, null,
                                        R.attr.actionModePopupWindowStyle);
                                mActionModePopup.setWindowLayoutType(
                                        WindowManager.LayoutParams.TYPE_APPLICATION);
                                mActionModePopup.setContentView(mActionModeView);
                                mActionModePopup.setWidth(MATCH_PARENT);

                                actionBarContext.getTheme().resolveAttribute(
                                        R.attr.actionBarSize, outValue, true);
                                final int height = TypedValue.complexToDimensionPixelSize(outValue.data,
                                        actionBarContext.getResources().getDisplayMetrics());
                                mActionModeView.setContentHeight(height);
                                mActionModePopup.setHeight(WRAP_CONTENT);
                                mShowActionModePopup = new Runnable() {
                                    public void run() {
                                        mActionModePopup.showAtLocation(
                                                mActionModeView.getApplicationWindowToken(),
                                                Gravity.TOP | Gravity.FILL_HORIZONTAL, 0, 0);
                                    }
                                };
                            } else {
                                ViewStub stub = (ViewStub) findViewById(
                                        R.id.action_mode_bar_stub);
                                if (stub != null) {
                                    mActionModeView = (ActionBarContextView) stub.inflate();
                                }
                            }
                        }
                        if (mActionModeView != null) {
                            wrapperMode.setActionModeView(mActionModeView);
                            wrapperMode.setFocusable(mActionModePopup == null);
                            wrapperMode.lockType();
                            wrapperMode.invalidate();
                            mActionModeView.initForMode(wrapperMode);
                            mActionModeView.setVisibility(View.VISIBLE);
                    mActionMode = wrapperMode;
                            if (mActionModePopup != null) {
                                post(mShowActionModePopup);
                            }
                            mActionModeView.sendAccessibilityEvent(
                                    AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED);
                        }
                    }
                    wrapperMode.lockType();
                    mActionMode.invalidate();
                } else {
                    mActionMode = null;
                }
@@ -3258,6 +3197,82 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback {
            updateColorViewTranslations();
        }

        /**
         * Encapsulates the view creation for {@link StandaloneActionMode}.
         */
        private class StandaloneActionModeProvider
                implements ActionModeWrapper.ActionModeProvider {

            @Override
            public ActionMode createActionMode(android.view.ActionMode.Callback callback,
                    MenuBuilder menuBuilder) {
                if (mActionModeView == null) {
                    if (isFloating()) {
                        // Use the action bar theme.
                        final TypedValue outValue = new TypedValue();
                        final Theme baseTheme = mContext.getTheme();
                        baseTheme.resolveAttribute(R.attr.actionBarTheme, outValue, true);

                        final Context actionBarContext;
                        if (outValue.resourceId != 0) {
                            final Theme actionBarTheme = mContext.getResources().newTheme();
                            actionBarTheme.setTo(baseTheme);
                            actionBarTheme.applyStyle(outValue.resourceId, true);

                            actionBarContext = new ContextThemeWrapper(mContext, 0);
                            actionBarContext.getTheme().setTo(actionBarTheme);
                        } else {
                            actionBarContext = mContext;
                        }

                        mActionModeView = new ActionBarContextView(actionBarContext);
                        mActionModePopup = new PopupWindow(actionBarContext, null,
                                R.attr.actionModePopupWindowStyle);
                        mActionModePopup.setWindowLayoutType(
                                WindowManager.LayoutParams.TYPE_APPLICATION);
                        mActionModePopup.setContentView(mActionModeView);
                        mActionModePopup.setWidth(MATCH_PARENT);

                        actionBarContext.getTheme().resolveAttribute(
                                R.attr.actionBarSize, outValue, true);
                        final int height = TypedValue.complexToDimensionPixelSize(outValue.data,
                                actionBarContext.getResources().getDisplayMetrics());
                        mActionModeView.setContentHeight(height);
                        mActionModePopup.setHeight(WRAP_CONTENT);
                        mShowActionModePopup = new Runnable() {
                            public void run() {
                                mActionModePopup.showAtLocation(
                                        mActionModeView.getApplicationWindowToken(),
                                        Gravity.TOP | Gravity.FILL_HORIZONTAL, 0, 0);
                            }
                        };
                    } else {
                        ViewStub stub = (ViewStub) findViewById(
                                R.id.action_mode_bar_stub);
                        if (stub != null) {
                            mActionModeView = (ActionBarContextView) stub.inflate();
                        }
                    }
                }
                if (mActionModeView != null) {
                    ActionMode mode = new StandaloneActionMode(
                            mActionModeView.getContext(), mActionModeView,
                            callback, mActionModePopup == null, menuBuilder);
                    mActionModeView.killMode();
                    mActionModeView.initForMode(mode);
                    mActionModeView.setVisibility(View.VISIBLE);
                    if (mActionModePopup != null) {
                        post(mShowActionModePopup);
                    }
                    mActionModeView.sendAccessibilityEvent(
                            AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED);
                    return mode;
                }
                return null;
            }

        }

        /**
         * Clears out internal reference when the action mode is destroyed.
         */
+22 −17
Original line number Diff line number Diff line
@@ -24,7 +24,6 @@ import android.view.MenuItem;
import android.view.View;

import com.android.internal.view.menu.MenuBuilder;
import com.android.internal.widget.ActionBarContextView;

/**
 * ActionMode implementation that wraps several actions modes and creates them on the fly depending
@@ -32,6 +31,22 @@ import com.android.internal.widget.ActionBarContextView;
 */
public class ActionModeWrapper extends ActionMode {

    /**
     * Interface to defer the ActionMode creation until the type is chosen.
     */
    public interface ActionModeProvider {
        /**
         * Create the desired ActionMode, that will immediately be used as the current active mode
         * in the decorator.
         *
         * @param callback The {@link ActionMode.Callback} to be used.
         * @param menuBuilder The {@link MenuBuilder} that should be used by the created
         *      {@link ActionMode}. This will already have been populated.
         * @return A new {@link ActionMode} ready to be used that uses menuBuilder as its menu.
         */
        ActionMode createActionMode(ActionMode.Callback callback, MenuBuilder menuBuilder);
    }

    private ActionMode mActionMode;
    private final Context mContext;
    private MenuBuilder mMenu;
@@ -42,15 +57,15 @@ public class ActionModeWrapper extends ActionMode {
    private CharSequence mSubtitle;
    private View mCustomView;
    
    // Fields for StandaloneActionMode
    private ActionBarContextView mActionModeView;
    private boolean mIsFocusable;
    private final ActionModeProvider mActionModeProvider;

    public ActionModeWrapper(Context context, ActionMode.Callback callback) {
    public ActionModeWrapper(
            Context context, ActionMode.Callback callback, ActionModeProvider actionModeProvider) {
        mContext = context;
        mMenu = new MenuBuilder(context).setDefaultShowAsAction(
                MenuItem.SHOW_AS_ACTION_IF_ROOM);
        mCallback = callback;
        mActionModeProvider = actionModeProvider;
    }

    @Override
@@ -107,9 +122,7 @@ public class ActionModeWrapper extends ActionMode {
        switch (getType()) {
            case ActionMode.TYPE_PRIMARY:
            default:
                mActionMode = new StandaloneActionMode(
                        mActionModeView.getContext(),
                        mActionModeView, mCallback, mIsFocusable, mMenu);
                mActionMode = mActionModeProvider.createActionMode(mCallback, mMenu);
                break;
            case ActionMode.TYPE_FLOATING:
                // Not implemented yet.
@@ -189,12 +202,4 @@ public class ActionModeWrapper extends ActionMode {
        return new MenuInflater(mContext);
    }

    public void setActionModeView(ActionBarContextView actionModeView) {
        mActionModeView = actionModeView;
    }

    public void setFocusable(boolean focusable) {
        mIsFocusable = focusable;
    }

}