• 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.SharedMinimal.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, boolean highlight)134         public void setDropTargetHighlight(View v, 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)143         public void onDragEntered(View v) {
144             // do nothing; let drawer only open for onViewHovered
145         }
146 
147         @Override
onDragExited(View v)148         public void onDragExited(View v) {
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
onDragEnded()160         public void onDragEnded() {
161             // do nothing
162         }
163 
164         @Override
setOpen(boolean open)165         public void setOpen(boolean open) {
166             if (open) {
167                 mLayout.openDrawer(mDrawer);
168             } else {
169                 mLayout.closeDrawer(mDrawer);
170             }
171         }
172 
173         @Override
isOpen()174         public boolean isOpen() {
175             return mLayout.isDrawerOpen(mDrawer);
176         }
177 
178         @Override
isPresent()179         public boolean isPresent() {
180             return true;
181         }
182 
183         @Override
setTitle(String title)184         void setTitle(String title) {
185             mToolbar.setTitle(title);
186         }
187 
188         @Override
update()189         public void update() {
190             mToggle.syncState();
191         }
192 
193         @Override
onDrawerSlide(View drawerView, float slideOffset)194         public void onDrawerSlide(View drawerView, float slideOffset) {
195             mToggle.onDrawerSlide(drawerView, slideOffset);
196         }
197 
198         @Override
onDrawerOpened(View drawerView)199         public void onDrawerOpened(View drawerView) {
200             mToggle.onDrawerOpened(drawerView);
201         }
202 
203         @Override
onDrawerClosed(View drawerView)204         public void onDrawerClosed(View drawerView) {
205             mToggle.onDrawerClosed(drawerView);
206         }
207 
208         @Override
onDrawerStateChanged(int newState)209         public void onDrawerStateChanged(int newState) {
210             mToggle.onDrawerStateChanged(newState);
211         }
212     }
213 
214     /*
215      * Dummy controller useful with clients that don't host a real drawer.
216      */
217     private static final class DummyDrawerController extends DrawerController {
218 
219         @Override
setOpen(boolean open)220         public void setOpen(boolean open) {}
221 
222         @Override
isOpen()223         public boolean isOpen() {
224             return false;
225         }
226 
227         @Override
isPresent()228         public boolean isPresent() {
229             return false;
230         }
231 
232         @Override
setTitle(String title)233         void setTitle(String title) {}
234 
235         @Override
update()236         public void update() {}
237 
238         @Override
onDrawerSlide(View drawerView, float slideOffset)239         public void onDrawerSlide(View drawerView, float slideOffset) {}
240 
241         @Override
onDrawerOpened(View drawerView)242         public void onDrawerOpened(View drawerView) {}
243 
244         @Override
onDrawerClosed(View drawerView)245         public void onDrawerClosed(View drawerView) {}
246 
247         @Override
onDrawerStateChanged(int newState)248         public void onDrawerStateChanged(int newState) {}
249     }
250 }
251