blob: ebac991b4c93b9c3e4ef18cd0351256976e713c1 [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
Steve McKayd9caa6a2016-09-15 16:36:45 -070019import static com.android.documentsui.base.Shared.DEBUG;
Aga Wronskac32a2992016-03-08 11:20:39 -080020
Aga Wronska441b9be2016-03-29 16:57:10 -070021import android.annotation.IntDef;
Steve McKay6bbed4d2015-08-17 13:18:05 -070022import android.app.Activity;
Garfield, Tan7d66a862016-05-11 10:28:41 -070023import android.support.annotation.ColorRes;
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
Steve McKayd9caa6a2016-09-15 16:36:45 -070031import com.android.documentsui.base.Display;
32
Aga Wronska441b9be2016-03-29 16:57:10 -070033import java.lang.annotation.Retention;
34import java.lang.annotation.RetentionPolicy;
35
Steve McKay6bbed4d2015-08-17 13:18:05 -070036/**
37 * A facade over the various pieces comprising "roots fragment in a Drawer".
38 *
39 * @see DrawerController#create(DrawerLayout)
40 */
Steve McKay16e0c1f2016-09-15 12:41:13 -070041public abstract class DrawerController implements DrawerListener {
Aga Wronskac32a2992016-03-08 11:20:39 -080042 public static final String TAG = "DrawerController";
43
Aga Wronska441b9be2016-03-29 16:57:10 -070044 // Drawer opening triggered by tapping the navigation icon
45 public static final int OPENED_HAMBURGER = 0;
46 // Drawer opening triggered by swiping right from the edge of the screen
47 public static final int OPENED_SWIPE = 1;
48 // Mostly programmatically forced drawer opening
49 public static final int OPENED_OTHER = 2;
50
51 @IntDef(flag = true, value = {
52 OPENED_HAMBURGER,
53 OPENED_SWIPE,
54 OPENED_OTHER
55 })
56 @Retention(RetentionPolicy.SOURCE)
57 public @interface Trigger {}
58
Steve McKay16e0c1f2016-09-15 12:41:13 -070059 public abstract void update();
Aga Wronska441b9be2016-03-29 16:57:10 -070060 /**
61 * Toggles the drawer and sets the OPENED_OTHER as the action that causes opening the drawer.
62 * @param open
63 */
Steve McKay16e0c1f2016-09-15 12:41:13 -070064 public abstract void setOpen(boolean open);
Aga Wronska441b9be2016-03-29 16:57:10 -070065
66 /**
67 * Toggles the drawer.
68 * @param open
69 * @param trigger Indicates what action caused opening the drawer. It is ignored for closing.
70 */
71 abstract void setOpen(boolean open, @Trigger int trigger);
Steve McKay16e0c1f2016-09-15 12:41:13 -070072 public abstract boolean isPresent();
73 public abstract boolean isOpen();
Steve McKay18d01e82016-02-03 11:15:57 -080074 abstract void setTitle(String title);
Steve McKay6bbed4d2015-08-17 13:18:05 -070075
76 /**
77 * Returns a controller suitable for {@code Layout}.
78 */
79 static DrawerController create(Activity activity) {
80
81 DrawerLayout layout = (DrawerLayout) activity.findViewById(R.id.drawer_layout);
82
83 if (layout == null) {
84 return new DummyDrawerController();
85 }
86
87 View drawer = activity.findViewById(R.id.drawer_roots);
Steve McKay18d01e82016-02-03 11:15:57 -080088 Toolbar toolbar = (Toolbar) activity.findViewById(R.id.roots_toolbar);
Aga Wronskae20925f2016-04-06 13:57:28 -070089
Aga Wronskac32a2992016-03-08 11:20:39 -080090 drawer.getLayoutParams().width = calculateDrawerWidth(activity);
91
Steve McKay6bbed4d2015-08-17 13:18:05 -070092 ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
93 activity,
94 layout,
95 R.drawable.ic_hamburger,
96 R.string.drawer_open,
97 R.string.drawer_close);
98
Steve McKay18d01e82016-02-03 11:15:57 -080099 return new RuntimeDrawerController(layout, drawer, toggle, toolbar);
Steve McKay6bbed4d2015-08-17 13:18:05 -0700100 }
101
102 /**
103 * Returns a controller suitable for {@code Layout}.
104 */
105 static DrawerController createDummy() {
106 return new DummyDrawerController();
107 }
108
Aga Wronskac32a2992016-03-08 11:20:39 -0800109 private static int calculateDrawerWidth(Activity activity) {
110 // Material design specification for navigation drawer:
111 // https://www.google.com/design/spec/patterns/navigation-drawer.html
112 float width = Display.screenWidth(activity) - Display.actionBarHeight(activity);
113 float maxWidth = activity.getResources().getDimension(R.dimen.max_drawer_width);
114 int finalWidth = (int) ((width > maxWidth ? maxWidth : width));
115
116 if (DEBUG)
117 Log.d(TAG, "Calculated drawer width:" + (finalWidth / Display.density(activity)));
118
119 return finalWidth;
120 }
121
Steve McKay6bbed4d2015-08-17 13:18:05 -0700122 /**
123 * Runtime controller that manages a real drawer.
124 */
Garfield, Tan7d66a862016-05-11 10:28:41 -0700125 private static final class RuntimeDrawerController extends DrawerController
126 implements ItemDragListener.DragHost {
Steve McKay6bbed4d2015-08-17 13:18:05 -0700127 private final ActionBarDrawerToggle mToggle;
128 private DrawerLayout mLayout;
129 private View mDrawer;
Steve McKay18d01e82016-02-03 11:15:57 -0800130 private Toolbar mToolbar;
Aga Wronska441b9be2016-03-29 16:57:10 -0700131 private @Trigger int mTrigger = OPENED_OTHER;
Steve McKay6bbed4d2015-08-17 13:18:05 -0700132
133 public RuntimeDrawerController(
Steve McKay18d01e82016-02-03 11:15:57 -0800134 DrawerLayout layout, View drawer, ActionBarDrawerToggle toggle,
135 Toolbar drawerToolbar) {
136 mToolbar = drawerToolbar;
Steve McKay0af8afd2016-02-25 13:34:03 -0800137 assert(layout != null);
Steve McKay6bbed4d2015-08-17 13:18:05 -0700138
139 mLayout = layout;
140 mDrawer = drawer;
141 mToggle = toggle;
142
143 mLayout.setDrawerListener(this);
Garfield, Tan7d66a862016-05-11 10:28:41 -0700144
145 View edge = layout.findViewById(R.id.drawer_edge);
146 edge.setOnDragListener(new ItemDragListener<>(this));
147 }
148
149 @Override
150 public void runOnUiThread(Runnable runnable) {
151 mDrawer.post(runnable);
152 }
153
154 @Override
155 public void setDropTargetHighlight(View v, boolean highlight) {
156 assert (v.getId() == R.id.drawer_edge);
157
158 @ColorRes int id = highlight ? R.color.item_doc_background_selected :
159 android.R.color.transparent;
160 v.setBackgroundColor(id);
161 }
162
163 @Override
164 public void onViewHovered(View v) {
165 assert (v.getId() == R.id.drawer_edge);
166
167 setOpen(true);
Steve McKay6bbed4d2015-08-17 13:18:05 -0700168 }
169
170 @Override
Steve McKay16e0c1f2016-09-15 12:41:13 -0700171 public void setOpen(boolean open) {
Aga Wronska441b9be2016-03-29 16:57:10 -0700172 setOpen(open, OPENED_OTHER);
173 }
174
175 @Override
176 void setOpen(boolean open, @Trigger int trigger) {
Steve McKay6bbed4d2015-08-17 13:18:05 -0700177 if (open) {
178 mLayout.openDrawer(mDrawer);
Aga Wronska441b9be2016-03-29 16:57:10 -0700179 mTrigger = trigger;
Steve McKay6bbed4d2015-08-17 13:18:05 -0700180 } else {
181 mLayout.closeDrawer(mDrawer);
182 }
183 }
184
185 @Override
Steve McKay16e0c1f2016-09-15 12:41:13 -0700186 public boolean isOpen() {
Steve McKay6bbed4d2015-08-17 13:18:05 -0700187 return mLayout.isDrawerOpen(mDrawer);
188 }
189
190 @Override
Steve McKay16e0c1f2016-09-15 12:41:13 -0700191 public boolean isPresent() {
Steve McKay0fbfc652015-08-20 16:48:49 -0700192 return true;
193 }
194
195 @Override
Steve McKay18d01e82016-02-03 11:15:57 -0800196 void setTitle(String title) {
197 mToolbar.setTitle(title);
198 }
199
200 @Override
Steve McKay16e0c1f2016-09-15 12:41:13 -0700201 public void update() {
Steve McKay6bbed4d2015-08-17 13:18:05 -0700202 mToggle.syncState();
203 }
204
205 @Override
Steve McKay6bbed4d2015-08-17 13:18:05 -0700206 public void onDrawerSlide(View drawerView, float slideOffset) {
207 mToggle.onDrawerSlide(drawerView, slideOffset);
208 }
209
210 @Override
211 public void onDrawerOpened(View drawerView) {
212 mToggle.onDrawerOpened(drawerView);
Aga Wronska441b9be2016-03-29 16:57:10 -0700213 Metrics.logDrawerOpened(mToolbar.getContext(), mTrigger);
Steve McKay6bbed4d2015-08-17 13:18:05 -0700214 }
215
216 @Override
217 public void onDrawerClosed(View drawerView) {
218 mToggle.onDrawerClosed(drawerView);
Aga Wronska441b9be2016-03-29 16:57:10 -0700219 mTrigger = OPENED_OTHER;
Steve McKay6bbed4d2015-08-17 13:18:05 -0700220 }
221
222 @Override
223 public void onDrawerStateChanged(int newState) {
224 mToggle.onDrawerStateChanged(newState);
Aga Wronska441b9be2016-03-29 16:57:10 -0700225 if (newState == DrawerLayout.STATE_DRAGGING) {
226 mTrigger = OPENED_SWIPE;
227 }
Steve McKay6bbed4d2015-08-17 13:18:05 -0700228 }
229 }
230
231 /*
232 * Dummy controller useful with clients that don't host a real drawer.
233 */
234 private static final class DummyDrawerController extends DrawerController {
235
236 @Override
Steve McKay16e0c1f2016-09-15 12:41:13 -0700237 public void setOpen(boolean open) {}
Steve McKay6bbed4d2015-08-17 13:18:05 -0700238
Aga Wronska441b9be2016-03-29 16:57:10 -0700239 @Override
Steve McKay16e0c1f2016-09-15 12:41:13 -0700240 public void setOpen(boolean open, @Trigger int trigger) {}
Steve McKay6bbed4d2015-08-17 13:18:05 -0700241
242 @Override
Steve McKay16e0c1f2016-09-15 12:41:13 -0700243 public boolean isOpen() {
Steve McKay0fbfc652015-08-20 16:48:49 -0700244 return false;
245 }
246
247 @Override
Steve McKay16e0c1f2016-09-15 12:41:13 -0700248 public boolean isPresent() {
Steve McKay0fbfc652015-08-20 16:48:49 -0700249 return false;
250 }
251
252 @Override
Steve McKay18d01e82016-02-03 11:15:57 -0800253 void setTitle(String title) {}
254
255 @Override
Steve McKay16e0c1f2016-09-15 12:41:13 -0700256 public void update() {}
Steve McKay6bbed4d2015-08-17 13:18:05 -0700257
258 @Override
259 public void onDrawerSlide(View drawerView, float slideOffset) {}
260
261 @Override
262 public void onDrawerOpened(View drawerView) {}
263
264 @Override
265 public void onDrawerClosed(View drawerView) {}
266
267 @Override
268 public void onDrawerStateChanged(int newState) {}
Steve McKay6bbed4d2015-08-17 13:18:05 -0700269 }
270}