blob: d8c679aa78412880131226e6f70024a767cd6e7b [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;
Ben Lin693a3522017-03-07 16:00:29 -080023import 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
Steve McKay16e0c1f2016-09-15 12:41:13 -070044 public abstract void update();
Steve McKay16e0c1f2016-09-15 12:41:13 -070045 public abstract void setOpen(boolean open);
Steve McKay16e0c1f2016-09-15 12:41:13 -070046 public abstract boolean isPresent();
47 public abstract boolean isOpen();
Steve McKay18d01e82016-02-03 11:15:57 -080048 abstract void setTitle(String title);
Steve McKay6bbed4d2015-08-17 13:18:05 -070049
50 /**
51 * Returns a controller suitable for {@code Layout}.
52 */
Garfield Tan208945c2016-10-04 14:36:38 -070053 public static DrawerController create(Activity activity, ActivityConfig activityConfig) {
Steve McKay6bbed4d2015-08-17 13:18:05 -070054
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);
Steve McKay18d01e82016-02-03 11:15:57 -080062 Toolbar toolbar = (Toolbar) activity.findViewById(R.id.roots_toolbar);
Aga Wronskae20925f2016-04-06 13:57:28 -070063
Aga Wronskac32a2992016-03-08 11:20:39 -080064 drawer.getLayoutParams().width = calculateDrawerWidth(activity);
65
Steve McKay6bbed4d2015-08-17 13:18:05 -070066 ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
67 activity,
68 layout,
69 R.drawable.ic_hamburger,
70 R.string.drawer_open,
71 R.string.drawer_close);
72
Garfield Tan208945c2016-10-04 14:36:38 -070073 return new RuntimeDrawerController(layout, drawer, toggle, toolbar, activityConfig);
Steve McKay6bbed4d2015-08-17 13:18:05 -070074 }
75
76 /**
77 * Returns a controller suitable for {@code Layout}.
78 */
79 static DrawerController createDummy() {
80 return new DummyDrawerController();
81 }
82
Aga Wronskac32a2992016-03-08 11:20:39 -080083 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
Steve McKay6bbed4d2015-08-17 13:18:05 -070096 /**
97 * Runtime controller that manages a real drawer.
98 */
Garfield, Tan7d66a862016-05-11 10:28:41 -070099 private static final class RuntimeDrawerController extends DrawerController
100 implements ItemDragListener.DragHost {
Ben Linb1ab6962017-03-14 10:48:57 -0700101 private static final int SPRING_TIMEOUT = 750;
Steve McKay6bbed4d2015-08-17 13:18:05 -0700102 private final ActionBarDrawerToggle mToggle;
103 private DrawerLayout mLayout;
104 private View mDrawer;
Steve McKay18d01e82016-02-03 11:15:57 -0800105 private Toolbar mToolbar;
Steve McKay6bbed4d2015-08-17 13:18:05 -0700106
107 public RuntimeDrawerController(
Garfield Tan208945c2016-10-04 14:36:38 -0700108 DrawerLayout layout,
109 View drawer,
110 ActionBarDrawerToggle toggle,
111 Toolbar drawerToolbar,
112 ActivityConfig activityConfig) {
Steve McKay18d01e82016-02-03 11:15:57 -0800113 mToolbar = drawerToolbar;
Steve McKay0af8afd2016-02-25 13:34:03 -0800114 assert(layout != null);
Steve McKay6bbed4d2015-08-17 13:18:05 -0700115
116 mLayout = layout;
117 mDrawer = drawer;
118 mToggle = toggle;
119
120 mLayout.setDrawerListener(this);
Garfield, Tan7d66a862016-05-11 10:28:41 -0700121
Garfield Tan208945c2016-10-04 14:36:38 -0700122 if (activityConfig.dragAndDropEnabled()) {
123 View edge = layout.findViewById(R.id.drawer_edge);
Ben Linb1ab6962017-03-14 10:48:57 -0700124 edge.setOnDragListener(new ItemDragListener<>(this, SPRING_TIMEOUT));
Garfield Tan208945c2016-10-04 14:36:38 -0700125 }
Garfield, Tan7d66a862016-05-11 10:28:41 -0700126 }
127
128 @Override
129 public void runOnUiThread(Runnable runnable) {
130 mDrawer.post(runnable);
131 }
132
133 @Override
Garfield Tanda2c0f02017-04-11 13:47:58 -0700134 public void setDropTargetHighlight(View v, boolean highlight) {
Ben Lin693a3522017-03-07 16:00:29 -0800135 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);
Ben Lin7f72a3c2016-09-27 16:37:28 -0700140 }
141
142 @Override
Garfield Tanda2c0f02017-04-11 13:47:58 -0700143 public void onDragEntered(View v) {
Ben Lin693a3522017-03-07 16:00:29 -0800144 // do nothing; let drawer only open for onViewHovered
Garfield, Tan7d66a862016-05-11 10:28:41 -0700145 }
146
147 @Override
Garfield Tanda2c0f02017-04-11 13:47:58 -0700148 public void onDragExited(View v) {
Ben Lind0202122016-11-10 18:00:12 -0800149 // do nothing
150 }
151
152 @Override
Garfield, Tan7d66a862016-05-11 10:28:41 -0700153 public void onViewHovered(View v) {
Ben Lin693a3522017-03-07 16:00:29 -0800154 assert (v.getId() == R.id.drawer_edge);
155
156 setOpen(true);
Steve McKay6bbed4d2015-08-17 13:18:05 -0700157 }
158
159 @Override
Garfield Tanda2c0f02017-04-11 13:47:58 -0700160 public void onDragEnded() {
161 // do nothing
162 }
163
164 @Override
Steve McKay16e0c1f2016-09-15 12:41:13 -0700165 public void setOpen(boolean open) {
Steve McKay6bbed4d2015-08-17 13:18:05 -0700166 if (open) {
167 mLayout.openDrawer(mDrawer);
168 } else {
169 mLayout.closeDrawer(mDrawer);
170 }
171 }
172
173 @Override
Steve McKay16e0c1f2016-09-15 12:41:13 -0700174 public boolean isOpen() {
Steve McKay6bbed4d2015-08-17 13:18:05 -0700175 return mLayout.isDrawerOpen(mDrawer);
176 }
177
178 @Override
Steve McKay16e0c1f2016-09-15 12:41:13 -0700179 public boolean isPresent() {
Steve McKay0fbfc652015-08-20 16:48:49 -0700180 return true;
181 }
182
183 @Override
Steve McKay18d01e82016-02-03 11:15:57 -0800184 void setTitle(String title) {
185 mToolbar.setTitle(title);
186 }
187
188 @Override
Steve McKay16e0c1f2016-09-15 12:41:13 -0700189 public void update() {
Steve McKay6bbed4d2015-08-17 13:18:05 -0700190 mToggle.syncState();
191 }
192
193 @Override
Steve McKay6bbed4d2015-08-17 13:18:05 -0700194 public void onDrawerSlide(View drawerView, float slideOffset) {
195 mToggle.onDrawerSlide(drawerView, slideOffset);
196 }
197
198 @Override
199 public void onDrawerOpened(View drawerView) {
200 mToggle.onDrawerOpened(drawerView);
201 }
202
203 @Override
204 public void onDrawerClosed(View drawerView) {
205 mToggle.onDrawerClosed(drawerView);
206 }
207
208 @Override
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
Steve McKay16e0c1f2016-09-15 12:41:13 -0700220 public void setOpen(boolean open) {}
Steve McKay6bbed4d2015-08-17 13:18:05 -0700221
Aga Wronska441b9be2016-03-29 16:57:10 -0700222 @Override
Steve McKay16e0c1f2016-09-15 12:41:13 -0700223 public boolean isOpen() {
Steve McKay0fbfc652015-08-20 16:48:49 -0700224 return false;
225 }
226
227 @Override
Steve McKay16e0c1f2016-09-15 12:41:13 -0700228 public boolean isPresent() {
Steve McKay0fbfc652015-08-20 16:48:49 -0700229 return false;
230 }
231
232 @Override
Steve McKay18d01e82016-02-03 11:15:57 -0800233 void setTitle(String title) {}
234
235 @Override
Steve McKay16e0c1f2016-09-15 12:41:13 -0700236 public void update() {}
Steve McKay6bbed4d2015-08-17 13:18:05 -0700237
238 @Override
239 public void onDrawerSlide(View drawerView, float slideOffset) {}
240
241 @Override
242 public void onDrawerOpened(View drawerView) {}
243
244 @Override
245 public void onDrawerClosed(View drawerView) {}
246
247 @Override
248 public void onDrawerStateChanged(int newState) {}
Steve McKay6bbed4d2015-08-17 13:18:05 -0700249 }
250}