blob: 14e6b69bfc192119b11e2afdbc20f78da7d59bc0 [file] [log] [blame]
Steve McKay6bbed4d2015-08-17 13:18:05 -07001/*
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
17package com.android.documentsui;
18
Aga Wronskac32a2992016-03-08 11:20:39 -080019import static com.android.documentsui.Shared.DEBUG;
20
Aga Wronska441b9be2016-03-29 16:57:10 -070021import android.annotation.IntDef;
Steve McKay6bbed4d2015-08-17 13:18:05 -070022import android.app.Activity;
Aga Wronskac32a2992016-03-08 11:20:39 -080023import android.content.Context;
Steve McKay6bbed4d2015-08-17 13:18:05 -070024import android.support.v4.app.ActionBarDrawerToggle;
25import android.support.v4.widget.DrawerLayout;
26import android.support.v4.widget.DrawerLayout.DrawerListener;
Aga Wronskac32a2992016-03-08 11:20:39 -080027import android.util.Log;
Steve McKay6bbed4d2015-08-17 13:18:05 -070028import android.view.View;
Steve McKay18d01e82016-02-03 11:15:57 -080029import android.widget.Toolbar;
Steve McKay6bbed4d2015-08-17 13:18:05 -070030
Aga Wronska441b9be2016-03-29 16:57:10 -070031import java.lang.annotation.Retention;
32import java.lang.annotation.RetentionPolicy;
33
Steve McKay6bbed4d2015-08-17 13:18:05 -070034/**
35 * A facade over the various pieces comprising "roots fragment in a Drawer".
36 *
37 * @see DrawerController#create(DrawerLayout)
38 */
39abstract class DrawerController implements DrawerListener {
Aga Wronskac32a2992016-03-08 11:20:39 -080040 public static final String TAG = "DrawerController";
41
Aga Wronska441b9be2016-03-29 16:57:10 -070042 // Drawer opening triggered by tapping the navigation icon
43 public static final int OPENED_HAMBURGER = 0;
44 // Drawer opening triggered by swiping right from the edge of the screen
45 public static final int OPENED_SWIPE = 1;
46 // Mostly programmatically forced drawer opening
47 public static final int OPENED_OTHER = 2;
48
49 @IntDef(flag = true, value = {
50 OPENED_HAMBURGER,
51 OPENED_SWIPE,
52 OPENED_OTHER
53 })
54 @Retention(RetentionPolicy.SOURCE)
55 public @interface Trigger {}
56
57 /**
58 * Toggles the drawer and sets the OPENED_OTHER as the action that causes opening the drawer.
59 * @param open
60 */
Steve McKay6bbed4d2015-08-17 13:18:05 -070061 abstract void setOpen(boolean open);
Aga Wronska441b9be2016-03-29 16:57:10 -070062
63 /**
64 * Toggles the drawer.
65 * @param open
66 * @param trigger Indicates what action caused opening the drawer. It is ignored for closing.
67 */
68 abstract void setOpen(boolean open, @Trigger int trigger);
Steve McKay0fbfc652015-08-20 16:48:49 -070069 abstract boolean isPresent();
Steve McKay6bbed4d2015-08-17 13:18:05 -070070 abstract boolean isOpen();
Steve McKay18d01e82016-02-03 11:15:57 -080071 abstract void setTitle(String title);
72 abstract void update();
Steve McKay6bbed4d2015-08-17 13:18:05 -070073
74 /**
75 * Returns a controller suitable for {@code Layout}.
76 */
77 static DrawerController create(Activity activity) {
78
79 DrawerLayout layout = (DrawerLayout) activity.findViewById(R.id.drawer_layout);
80
81 if (layout == null) {
82 return new DummyDrawerController();
83 }
84
85 View drawer = activity.findViewById(R.id.drawer_roots);
Steve McKay18d01e82016-02-03 11:15:57 -080086 Toolbar toolbar = (Toolbar) activity.findViewById(R.id.roots_toolbar);
Aga Wronskae20925f2016-04-06 13:57:28 -070087
Aga Wronskac32a2992016-03-08 11:20:39 -080088 drawer.getLayoutParams().width = calculateDrawerWidth(activity);
89
Steve McKay6bbed4d2015-08-17 13:18:05 -070090 ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
91 activity,
92 layout,
93 R.drawable.ic_hamburger,
94 R.string.drawer_open,
95 R.string.drawer_close);
96
Steve McKay18d01e82016-02-03 11:15:57 -080097 return new RuntimeDrawerController(layout, drawer, toggle, toolbar);
Steve McKay6bbed4d2015-08-17 13:18:05 -070098 }
99
100 /**
101 * Returns a controller suitable for {@code Layout}.
102 */
103 static DrawerController createDummy() {
104 return new DummyDrawerController();
105 }
106
Aga Wronskac32a2992016-03-08 11:20:39 -0800107 private static int calculateDrawerWidth(Activity activity) {
108 // Material design specification for navigation drawer:
109 // https://www.google.com/design/spec/patterns/navigation-drawer.html
110 float width = Display.screenWidth(activity) - Display.actionBarHeight(activity);
111 float maxWidth = activity.getResources().getDimension(R.dimen.max_drawer_width);
112 int finalWidth = (int) ((width > maxWidth ? maxWidth : width));
113
114 if (DEBUG)
115 Log.d(TAG, "Calculated drawer width:" + (finalWidth / Display.density(activity)));
116
117 return finalWidth;
118 }
119
Steve McKay6bbed4d2015-08-17 13:18:05 -0700120 /**
121 * Runtime controller that manages a real drawer.
122 */
123 private static final class RuntimeDrawerController extends DrawerController {
Steve McKay6bbed4d2015-08-17 13:18:05 -0700124 private final ActionBarDrawerToggle mToggle;
125 private DrawerLayout mLayout;
126 private View mDrawer;
Steve McKay18d01e82016-02-03 11:15:57 -0800127 private Toolbar mToolbar;
Aga Wronska441b9be2016-03-29 16:57:10 -0700128 private @Trigger int mTrigger = OPENED_OTHER;
Steve McKay6bbed4d2015-08-17 13:18:05 -0700129
130 public RuntimeDrawerController(
Steve McKay18d01e82016-02-03 11:15:57 -0800131 DrawerLayout layout, View drawer, ActionBarDrawerToggle toggle,
132 Toolbar drawerToolbar) {
133 mToolbar = drawerToolbar;
Steve McKay0af8afd2016-02-25 13:34:03 -0800134 assert(layout != null);
Steve McKay6bbed4d2015-08-17 13:18:05 -0700135
136 mLayout = layout;
137 mDrawer = drawer;
138 mToggle = toggle;
139
140 mLayout.setDrawerListener(this);
141 }
142
143 @Override
144 void setOpen(boolean open) {
Aga Wronska441b9be2016-03-29 16:57:10 -0700145 setOpen(open, OPENED_OTHER);
146 }
147
148 @Override
149 void setOpen(boolean open, @Trigger int trigger) {
Steve McKay6bbed4d2015-08-17 13:18:05 -0700150 if (open) {
151 mLayout.openDrawer(mDrawer);
Aga Wronska441b9be2016-03-29 16:57:10 -0700152 mTrigger = trigger;
Steve McKay6bbed4d2015-08-17 13:18:05 -0700153 } else {
154 mLayout.closeDrawer(mDrawer);
155 }
156 }
157
158 @Override
159 boolean isOpen() {
160 return mLayout.isDrawerOpen(mDrawer);
161 }
162
163 @Override
Steve McKay0fbfc652015-08-20 16:48:49 -0700164 boolean isPresent() {
165 return true;
166 }
167
168 @Override
Steve McKay18d01e82016-02-03 11:15:57 -0800169 void setTitle(String title) {
170 mToolbar.setTitle(title);
171 }
172
173 @Override
174 void update() {
Steve McKay6bbed4d2015-08-17 13:18:05 -0700175 mToggle.syncState();
176 }
177
178 @Override
Steve McKay6bbed4d2015-08-17 13:18:05 -0700179 public void onDrawerSlide(View drawerView, float slideOffset) {
180 mToggle.onDrawerSlide(drawerView, slideOffset);
181 }
182
183 @Override
184 public void onDrawerOpened(View drawerView) {
185 mToggle.onDrawerOpened(drawerView);
Aga Wronska441b9be2016-03-29 16:57:10 -0700186 Metrics.logDrawerOpened(mToolbar.getContext(), mTrigger);
Steve McKay6bbed4d2015-08-17 13:18:05 -0700187 }
188
189 @Override
190 public void onDrawerClosed(View drawerView) {
191 mToggle.onDrawerClosed(drawerView);
Aga Wronska441b9be2016-03-29 16:57:10 -0700192 mTrigger = OPENED_OTHER;
Steve McKay6bbed4d2015-08-17 13:18:05 -0700193 }
194
195 @Override
196 public void onDrawerStateChanged(int newState) {
197 mToggle.onDrawerStateChanged(newState);
Aga Wronska441b9be2016-03-29 16:57:10 -0700198 if (newState == DrawerLayout.STATE_DRAGGING) {
199 mTrigger = OPENED_SWIPE;
200 }
Steve McKay6bbed4d2015-08-17 13:18:05 -0700201 }
202 }
203
204 /*
205 * Dummy controller useful with clients that don't host a real drawer.
206 */
207 private static final class DummyDrawerController extends DrawerController {
208
209 @Override
Steve McKay0fbfc652015-08-20 16:48:49 -0700210 void setOpen(boolean open) {}
Steve McKay6bbed4d2015-08-17 13:18:05 -0700211
Aga Wronska441b9be2016-03-29 16:57:10 -0700212 @Override
213 void setOpen(boolean open, @Trigger int trigger) {}
Steve McKay6bbed4d2015-08-17 13:18:05 -0700214
215 @Override
Steve McKay0fbfc652015-08-20 16:48:49 -0700216 boolean isOpen() {
217 return false;
218 }
219
220 @Override
Steve McKay0fbfc652015-08-20 16:48:49 -0700221 boolean isPresent() {
222 return false;
223 }
224
225 @Override
Steve McKay18d01e82016-02-03 11:15:57 -0800226 void setTitle(String title) {}
227
228 @Override
229 void update() {}
Steve McKay6bbed4d2015-08-17 13:18:05 -0700230
231 @Override
232 public void onDrawerSlide(View drawerView, float slideOffset) {}
233
234 @Override
235 public void onDrawerOpened(View drawerView) {}
236
237 @Override
238 public void onDrawerClosed(View drawerView) {}
239
240 @Override
241 public void onDrawerStateChanged(int newState) {}
Steve McKay6bbed4d2015-08-17 13:18:05 -0700242 }
243}