• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2015 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.documentsui;
18 
19 import static com.android.documentsui.base.Shared.DEBUG;
20 
21 import android.annotation.IntDef;
22 import android.app.Activity;
23 import android.support.annotation.ColorRes;
24 import android.support.v4.app.ActionBarDrawerToggle;
25 import android.support.v4.widget.DrawerLayout;
26 import android.support.v4.widget.DrawerLayout.DrawerListener;
27 import android.util.Log;
28 import android.view.View;
29 import android.widget.Toolbar;
30 
31 import com.android.documentsui.base.Display;
32 
33 import java.lang.annotation.Retention;
34 import java.lang.annotation.RetentionPolicy;
35 
36 /**
37  * A facade over the various pieces comprising "roots fragment in a Drawer".
38  *
39  * @see DrawerController#create(DrawerLayout)
40  */
41 public abstract class DrawerController implements DrawerListener {
42     public static final String TAG = "DrawerController";
43 
update()44     public abstract void update();
setOpen(boolean open)45     public abstract void setOpen(boolean open);
isPresent()46     public abstract boolean isPresent();
isOpen()47     public abstract boolean isOpen();
setTitle(String title)48     abstract void setTitle(String title);
49 
50     /**
51      * Returns a controller suitable for {@code Layout}.
52      */
create(Activity activity, ActivityConfig activityConfig)53     public static DrawerController create(Activity activity, ActivityConfig activityConfig) {
54 
55         DrawerLayout layout = (DrawerLayout) activity.findViewById(R.id.drawer_layout);
56 
57         if (layout == null) {
58             return new DummyDrawerController();
59         }
60 
61         View drawer = activity.findViewById(R.id.drawer_roots);
62         Toolbar toolbar = (Toolbar) activity.findViewById(R.id.roots_toolbar);
63 
64         drawer.getLayoutParams().width = calculateDrawerWidth(activity);
65 
66         ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
67                 activity,
68                 layout,
69                 R.drawable.ic_hamburger,
70                 R.string.drawer_open,
71                 R.string.drawer_close);
72 
73         return new RuntimeDrawerController(layout, drawer, toggle, toolbar, activityConfig);
74     }
75 
76     /**
77      * Returns a controller suitable for {@code Layout}.
78      */
createDummy()79     static DrawerController createDummy() {
80         return new DummyDrawerController();
81     }
82 
calculateDrawerWidth(Activity activity)83     private static int calculateDrawerWidth(Activity activity) {
84         // Material design specification for navigation drawer:
85         // https://www.google.com/design/spec/patterns/navigation-drawer.html
86         float width = Display.screenWidth(activity) - Display.actionBarHeight(activity);
87         float maxWidth = activity.getResources().getDimension(R.dimen.max_drawer_width);
88         int finalWidth = (int) ((width > maxWidth ? maxWidth : width));
89 
90         if (DEBUG)
91             Log.d(TAG, "Calculated drawer width:" + (finalWidth / Display.density(activity)));
92 
93         return finalWidth;
94     }
95 
96     /**
97      * Runtime controller that manages a real drawer.
98      */
99     private static final class RuntimeDrawerController extends DrawerController
100             implements ItemDragListener.DragHost {
101         private static final int SPRING_TIMEOUT = 750;
102         private final ActionBarDrawerToggle mToggle;
103         private DrawerLayout mLayout;
104         private View mDrawer;
105         private Toolbar mToolbar;
106 
RuntimeDrawerController( DrawerLayout layout, View drawer, ActionBarDrawerToggle toggle, Toolbar drawerToolbar, ActivityConfig activityConfig)107         public RuntimeDrawerController(
108                 DrawerLayout layout,
109                 View drawer,
110                 ActionBarDrawerToggle toggle,
111                 Toolbar drawerToolbar,
112                 ActivityConfig activityConfig) {
113             mToolbar = drawerToolbar;
114             assert(layout != null);
115 
116             mLayout = layout;
117             mDrawer = drawer;
118             mToggle = toggle;
119 
120             mLayout.setDrawerListener(this);
121 
122             if (activityConfig.dragAndDropEnabled()) {
123                 View edge = layout.findViewById(R.id.drawer_edge);
124                 edge.setOnDragListener(new ItemDragListener<>(this, SPRING_TIMEOUT));
125             }
126         }
127 
128         @Override
runOnUiThread(Runnable runnable)129         public void runOnUiThread(Runnable runnable) {
130             mDrawer.post(runnable);
131         }
132 
133         @Override
setDropTargetHighlight(View v, Object localState, boolean highlight)134         public void setDropTargetHighlight(View v, Object localState, boolean highlight) {
135             assert (v.getId() == R.id.drawer_edge);
136 
137             @ColorRes int id = highlight ? R.color.item_doc_background_selected :
138                 android.R.color.transparent;
139             v.setBackgroundColor(id);
140         }
141 
142         @Override
onDragEntered(View v, Object localState)143         public void onDragEntered(View v, Object localState) {
144             // do nothing; let drawer only open for onViewHovered
145         }
146 
147         @Override
onDragExited(View v, Object localState)148         public void onDragExited(View v, Object localState) {
149             // do nothing
150         }
151 
152         @Override
onViewHovered(View v)153         public void onViewHovered(View v) {
154             assert (v.getId() == R.id.drawer_edge);
155 
156             setOpen(true);
157         }
158 
159         @Override
setOpen(boolean open)160         public void setOpen(boolean open) {
161             if (open) {
162                 mLayout.openDrawer(mDrawer);
163             } else {
164                 mLayout.closeDrawer(mDrawer);
165             }
166         }
167 
168         @Override
isOpen()169         public boolean isOpen() {
170             return mLayout.isDrawerOpen(mDrawer);
171         }
172 
173         @Override
isPresent()174         public boolean isPresent() {
175             return true;
176         }
177 
178         @Override
setTitle(String title)179         void setTitle(String title) {
180             mToolbar.setTitle(title);
181         }
182 
183         @Override
update()184         public void update() {
185             mToggle.syncState();
186         }
187 
188         @Override
onDrawerSlide(View drawerView, float slideOffset)189         public void onDrawerSlide(View drawerView, float slideOffset) {
190             mToggle.onDrawerSlide(drawerView, slideOffset);
191         }
192 
193         @Override
onDrawerOpened(View drawerView)194         public void onDrawerOpened(View drawerView) {
195             mToggle.onDrawerOpened(drawerView);
196         }
197 
198         @Override
onDrawerClosed(View drawerView)199         public void onDrawerClosed(View drawerView) {
200             mToggle.onDrawerClosed(drawerView);
201         }
202 
203         @Override
onDrawerStateChanged(int newState)204         public void onDrawerStateChanged(int newState) {
205             mToggle.onDrawerStateChanged(newState);
206         }
207     }
208 
209     /*
210      * Dummy controller useful with clients that don't host a real drawer.
211      */
212     private static final class DummyDrawerController extends DrawerController {
213 
214         @Override
setOpen(boolean open)215         public void setOpen(boolean open) {}
216 
217         @Override
isOpen()218         public boolean isOpen() {
219             return false;
220         }
221 
222         @Override
isPresent()223         public boolean isPresent() {
224             return false;
225         }
226 
227         @Override
setTitle(String title)228         void setTitle(String title) {}
229 
230         @Override
update()231         public void update() {}
232 
233         @Override
onDrawerSlide(View drawerView, float slideOffset)234         public void onDrawerSlide(View drawerView, float slideOffset) {}
235 
236         @Override
onDrawerOpened(View drawerView)237         public void onDrawerOpened(View drawerView) {}
238 
239         @Override
onDrawerClosed(View drawerView)240         public void onDrawerClosed(View drawerView) {}
241 
242         @Override
onDrawerStateChanged(int newState)243         public void onDrawerStateChanged(int newState) {}
244     }
245 }
246