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

Commit 6bbed4d4 authored by Steve McKay's avatar Steve McKay
Browse files

Move Drawer management code to a facade.

Update Standalone mode to use drawer on smaller form factors.
While we're not implementing this now, we'll probably want
to switch to drawer mode when in portrait mode, even on relatively
larger devices.

Change-Id: I244cd3c6021d63cf43d0631a5397b05339a96ced
parent 45371104
Loading
Loading
Loading
Loading
+12 −68
Original line number Diff line number Diff line
@@ -26,7 +26,6 @@ import static com.android.documentsui.BaseActivity.State.ACTION_OPEN_TREE;
import static com.android.documentsui.DirectoryFragment.ANIM_DOWN;
import static com.android.documentsui.DirectoryFragment.ANIM_NONE;
import static com.android.documentsui.DirectoryFragment.ANIM_UP;
import static com.android.internal.util.Preconditions.checkArgument;

import android.app.Activity;
import android.app.Fragment;
@@ -48,9 +47,6 @@ import android.os.Bundle;
import android.os.Parcelable;
import android.provider.DocumentsContract;
import android.provider.DocumentsContract.Root;
import android.support.v4.app.ActionBarDrawerToggle;
import android.support.v4.widget.DrawerLayout;
import android.support.v4.widget.DrawerLayout.DrawerListener;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
@@ -81,9 +77,7 @@ public class DocumentsActivity extends BaseActivity {

    private Toolbar mRootsToolbar;

    private DrawerLayout mDrawerLayout;
    private ActionBarDrawerToggle mDrawerToggle;
    private View mRootsDrawer;
    private DrawerController mDrawer;

    private DirectoryContainerView mDirectoryContainer;

@@ -105,6 +99,7 @@ public class DocumentsActivity extends BaseActivity {
        final Resources res = getResources();
        mShowAsDialog = res.getBoolean(R.bool.show_as_dialog) && mState.action != ACTION_MANAGE &&
                mState.action != ACTION_BROWSE;

        if (!mShowAsDialog) {
            setTheme(R.style.DocumentsNonDialogTheme);
        }
@@ -117,6 +112,8 @@ public class DocumentsActivity extends BaseActivity {
        final Context context = this;

        if (mShowAsDialog) {
            mDrawer = DrawerController.createDummy();

            // Strongly define our horizontal dimension; we leave vertical as
            // WRAP_CONTENT so that system resizes us when IME is showing.
            final WindowManager.LayoutParams a = getWindow().getAttributes();
@@ -128,17 +125,7 @@ public class DocumentsActivity extends BaseActivity {
            getWindow().setAttributes(a);

        } else {
            // Non-dialog means we have a drawer
            mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);

            if (mDrawerLayout != null) {
                mDrawerToggle = new ActionBarDrawerToggle(this, mDrawerLayout,
                        R.drawable.ic_hamburger, R.string.drawer_open, R.string.drawer_close);

                mDrawerLayout.setDrawerListener(mDrawerListener);

                mRootsDrawer = findViewById(R.id.drawer_roots);
            }
            mDrawer = DrawerController.create(this);
        }

        mDirectoryContainer = (DirectoryContainerView) findViewById(R.id.container_directory);
@@ -162,10 +149,9 @@ public class DocumentsActivity extends BaseActivity {

        // Hide roots when we're managing a specific root
        if (mState.action == ACTION_MANAGE || mState.action == ACTION_BROWSE) {
            if (mShowAsDialog || mDrawerLayout == null) {
            mDrawer.lockClosed();
            if (mShowAsDialog) {
                findViewById(R.id.container_roots).setVisibility(View.GONE);
            } else {
                mDrawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED);
            }
        }

@@ -341,53 +327,15 @@ public class DocumentsActivity extends BaseActivity {
        }
    }

    private DrawerListener mDrawerListener = new DrawerListener() {
        @Override
        public void onDrawerSlide(View drawerView, float slideOffset) {
            mDrawerToggle.onDrawerSlide(drawerView, slideOffset);
        }

        @Override
        public void onDrawerOpened(View drawerView) {
            mDrawerToggle.onDrawerOpened(drawerView);
        }

        @Override
        public void onDrawerClosed(View drawerView) {
            mDrawerToggle.onDrawerClosed(drawerView);
        }

        @Override
        public void onDrawerStateChanged(int newState) {
            mDrawerToggle.onDrawerStateChanged(newState);
        }
    };

    @Override
    protected void onPostCreate(Bundle savedInstanceState) {
        super.onPostCreate(savedInstanceState);
        if (mDrawerToggle != null) {
            mDrawerToggle.syncState();
        }
        mDrawer.syncState();
        updateActionBar();
    }

    public void setRootsDrawerOpen(boolean open) {
        if (!mShowAsDialog && mDrawerLayout != null) {
            if (open) {
                mDrawerLayout.openDrawer(mRootsDrawer);
            } else {
                mDrawerLayout.closeDrawer(mRootsDrawer);
            }
        }
    }

    private boolean isRootsDrawerOpen() {
        if (mShowAsDialog || mDrawerLayout == null) {
            return false;
        } else {
            return mDrawerLayout.isDrawerOpen(mRootsDrawer);
        }
        mDrawer.setOpen(open);
    }

    @Override
@@ -408,8 +356,7 @@ public class DocumentsActivity extends BaseActivity {
            }
        }

        if (!mShowAsDialog && mDrawerLayout != null &&
                mDrawerLayout.getDrawerLockMode(mRootsDrawer) == DrawerLayout.LOCK_MODE_UNLOCKED) {
        if (!mShowAsDialog && mDrawer.isUnlocked()) {
            mToolbar.setNavigationIcon(R.drawable.ic_hamburger);
            mToolbar.setNavigationContentDescription(R.string.drawer_open);
            mToolbar.setNavigationOnClickListener(new View.OnClickListener() {
@@ -504,10 +451,7 @@ public class DocumentsActivity extends BaseActivity {

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        if (mDrawerToggle != null && mDrawerToggle.onOptionsItemSelected(item)) {
            return true;
        }
        return super.onOptionsItemSelected(item);
        return mDrawer.onOptionsItemSelected(item) || super.onOptionsItemSelected(item);
    }

    @Override
@@ -526,7 +470,7 @@ public class DocumentsActivity extends BaseActivity {
        if (size > 1) {
            mState.stack.pop();
            onCurrentDirectoryChanged(ANIM_UP);
        } else if (size == 1 && !isRootsDrawerOpen()) {
        } else if (size == 1 && !mDrawer.isOpen()) {
            // TODO: open root drawer once we can capture back key
            super.onBackPressed();
        } else {
+196 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2015 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.documentsui;

import static com.android.internal.util.Preconditions.checkArgument;

import android.app.Activity;
import android.support.v4.app.ActionBarDrawerToggle;
import android.support.v4.widget.DrawerLayout;
import android.support.v4.widget.DrawerLayout.DrawerListener;
import android.view.MenuItem;
import android.view.View;

/**
 * A facade over the various pieces comprising "roots fragment in a Drawer".
 *
 * @see DrawerController#create(DrawerLayout)
 */
abstract class DrawerController implements DrawerListener {

    abstract void setOpen(boolean open);
    abstract void lockOpen();
    abstract void lockClosed();
    abstract boolean isOpen();
    abstract boolean isUnlocked();
    abstract void syncState();
    abstract boolean onOptionsItemSelected(MenuItem item);

    /**
     * Returns a controller suitable for {@code Layout}.
     */
    static DrawerController create(Activity activity) {

        DrawerLayout layout = (DrawerLayout) activity.findViewById(R.id.drawer_layout);

        if (layout == null) {
            return new DummyDrawerController();
        }

        View drawer = activity.findViewById(R.id.drawer_roots);
        ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
                activity,
                layout,
                R.drawable.ic_hamburger,
                R.string.drawer_open,
                R.string.drawer_close);

        return new RuntimeDrawerController(layout, drawer, toggle);
    }

    /**
     * Returns a controller suitable for {@code Layout}.
     */
    static DrawerController createDummy() {
        return new DummyDrawerController();
    }

    /**
     * Runtime controller that manages a real drawer.
     */
    private static final class RuntimeDrawerController extends DrawerController {

        private final ActionBarDrawerToggle mToggle;
        private DrawerLayout mLayout;
        private View mDrawer;

        public RuntimeDrawerController(
                DrawerLayout layout, View drawer, ActionBarDrawerToggle toggle) {
            checkArgument(layout != null);

            mLayout = layout;
            mDrawer = drawer;
            mToggle = toggle;

            mLayout.setDrawerListener(this);
        }

        @Override
        void setOpen(boolean open) {
            if (open) {
                mLayout.openDrawer(mDrawer);
            } else {
                mLayout.closeDrawer(mDrawer);
            }
        }

        @Override
        boolean isOpen() {
            return mLayout.isDrawerOpen(mDrawer);
        }

        @Override
        void syncState() {
            mToggle.syncState();
        }

        @Override
        boolean isUnlocked() {
            return mLayout.getDrawerLockMode(mDrawer) == DrawerLayout.LOCK_MODE_UNLOCKED;
        }

        @Override
        void lockOpen() {
            mLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_OPEN);
        }

        @Override
        void lockClosed() {
            mLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED);
        }

        @Override
        boolean onOptionsItemSelected(MenuItem item) {
            return false;
        }

        @Override
        public void onDrawerSlide(View drawerView, float slideOffset) {
            mToggle.onDrawerSlide(drawerView, slideOffset);
        }

        @Override
        public void onDrawerOpened(View drawerView) {
            mToggle.onDrawerOpened(drawerView);
        }

        @Override
        public void onDrawerClosed(View drawerView) {
            mToggle.onDrawerClosed(drawerView);
        }

        @Override
        public void onDrawerStateChanged(int newState) {
            mToggle.onDrawerStateChanged(newState);
        }
    }

    /*
     * Dummy controller useful with clients that don't host a real drawer.
     */
    private static final class DummyDrawerController extends DrawerController {

        @Override
        boolean isOpen() {
            return false;
        }

        @Override
        void syncState() {}

        @Override
        void lockOpen() {}

        @Override
        void lockClosed() {}

        @Override
        boolean isUnlocked() {
            return true;
        }

        @Override
        boolean onOptionsItemSelected(MenuItem item) {
            return false;
        }

        @Override
        public void onDrawerSlide(View drawerView, float slideOffset) {}

        @Override
        public void onDrawerOpened(View drawerView) {}

        @Override
        public void onDrawerClosed(View drawerView) {}

        @Override
        public void onDrawerStateChanged(int newState) {}

        @Override
        void setOpen(boolean open) {}
    }
}
+37 −4
Original line number Diff line number Diff line
@@ -70,6 +70,8 @@ public class StandaloneActivity extends BaseActivity {
    private ItemSelectedListener mStackListener;
    private BaseAdapter mStackAdapter;
    private DocumentClipper mClipper;
    private DrawerController mDrawer;
    private boolean mCompactMode;

    public StandaloneActivity() {
        super(TAG);
@@ -107,6 +109,18 @@ public class StandaloneActivity extends BaseActivity {

        setActionBar(mToolbar);


        // "show as dialog" is true on BIG screens. But we *assume* a big screen
        // and specialize for smaller screens by moving roots into an auto-hide drawer.
        // This works in conjunction with the specialized layouts defined for sw720dp.
        mCompactMode = !getResources().getBoolean(R.bool.show_as_dialog);

        if (mCompactMode) {
            setTheme(R.style.DocumentsNonDialogTheme);
        }

        mDrawer = DrawerController.create(this);

        mClipper = new DocumentClipper(this);

        RootsFragment.show(getFragmentManager(), null);
@@ -164,10 +178,23 @@ public class StandaloneActivity extends BaseActivity {
    @Override
    public void updateActionBar() {
        final RootInfo root = getCurrentRoot();

        if (mCompactMode) {
            mToolbar.setNavigationIcon(R.drawable.ic_hamburger);
            mToolbar.setNavigationContentDescription(R.string.drawer_open);
            mToolbar.setNavigationOnClickListener(
                    new View.OnClickListener() {
                        @Override
                        public void onClick(View v) {
                            mDrawer.setOpen(true);
                        }
                    });
        } else {
            mToolbar.setNavigationIcon(
                    root != null ? root.loadToolbarIcon(mToolbar.getContext()) : null);
            mToolbar.setNavigationContentDescription(R.string.drawer_open);
            mToolbar.setNavigationOnClickListener(null);
        }

        if (mSearchManager.isExpanded()) {
            mToolbar.setTitle(null);
@@ -283,6 +310,12 @@ public class StandaloneActivity extends BaseActivity {
        }
    }

    @Override
    void onRootPicked(RootInfo root) {
        super.onRootPicked(root);
        mDrawer.setOpen(false);
    }

    @Override
    public void onDocumentsPicked(List<DocumentInfo> docs) {
        throw new UnsupportedOperationException();