blob: e5996558b5f4ba7c0ec0b6861d3405e4b3474cf0 [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
Felipe Leme9de58072018-01-19 16:40:04 -080019import static com.android.documentsui.base.SharedMinimal.DEBUG;
Aga Wronskac32a2992016-03-08 11:20:39 -080020
Steve McKay6bbed4d2015-08-17 13:18:05 -070021import android.app.Activity;
Aga Wronskac32a2992016-03-08 11:20:39 -080022import android.util.Log;
Steve McKay6bbed4d2015-08-17 13:18:05 -070023import android.view.View;
24
Tony Huang09571b22019-03-14 14:47:53 +080025import androidx.annotation.ColorRes;
26import androidx.appcompat.widget.Toolbar;
27import androidx.drawerlayout.widget.DrawerLayout;
28import androidx.drawerlayout.widget.DrawerLayout.DrawerListener;
29import androidx.legacy.app.ActionBarDrawerToggle;
Steve McKayd9caa6a2016-09-15 16:36:45 -070030
Tony Huang09571b22019-03-14 14:47:53 +080031import com.android.documentsui.base.Display;
Aga Wronska441b9be2016-03-29 16:57:10 -070032
Steve McKay6bbed4d2015-08-17 13:18:05 -070033/**
34 * A facade over the various pieces comprising "roots fragment in a Drawer".
35 *
36 * @see DrawerController#create(DrawerLayout)
37 */
Steve McKay16e0c1f2016-09-15 12:41:13 -070038public abstract class DrawerController implements DrawerListener {
Aga Wronskac32a2992016-03-08 11:20:39 -080039 public static final String TAG = "DrawerController";
40
Steve McKay16e0c1f2016-09-15 12:41:13 -070041 public abstract void update();
Steve McKay16e0c1f2016-09-15 12:41:13 -070042 public abstract void setOpen(boolean open);
Steve McKay16e0c1f2016-09-15 12:41:13 -070043 public abstract boolean isPresent();
44 public abstract boolean isOpen();
Steve McKay18d01e82016-02-03 11:15:57 -080045 abstract void setTitle(String title);
Steve McKay6bbed4d2015-08-17 13:18:05 -070046
47 /**
48 * Returns a controller suitable for {@code Layout}.
49 */
Garfield Tan208945c2016-10-04 14:36:38 -070050 public static DrawerController create(Activity activity, ActivityConfig activityConfig) {
Steve McKay6bbed4d2015-08-17 13:18:05 -070051
52 DrawerLayout layout = (DrawerLayout) activity.findViewById(R.id.drawer_layout);
53
54 if (layout == null) {
55 return new DummyDrawerController();
56 }
57
58 View drawer = activity.findViewById(R.id.drawer_roots);
Steve McKay18d01e82016-02-03 11:15:57 -080059 Toolbar toolbar = (Toolbar) activity.findViewById(R.id.roots_toolbar);
Aga Wronskac32a2992016-03-08 11:20:39 -080060 drawer.getLayoutParams().width = calculateDrawerWidth(activity);
61
Steve McKay6bbed4d2015-08-17 13:18:05 -070062 ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
63 activity,
64 layout,
65 R.drawable.ic_hamburger,
66 R.string.drawer_open,
67 R.string.drawer_close);
68
Garfield Tan208945c2016-10-04 14:36:38 -070069 return new RuntimeDrawerController(layout, drawer, toggle, toolbar, activityConfig);
Steve McKay6bbed4d2015-08-17 13:18:05 -070070 }
71
72 /**
73 * Returns a controller suitable for {@code Layout}.
74 */
75 static DrawerController createDummy() {
76 return new DummyDrawerController();
77 }
78
Aga Wronskac32a2992016-03-08 11:20:39 -080079 private static int calculateDrawerWidth(Activity activity) {
80 // Material design specification for navigation drawer:
81 // https://www.google.com/design/spec/patterns/navigation-drawer.html
82 float width = Display.screenWidth(activity) - Display.actionBarHeight(activity);
83 float maxWidth = activity.getResources().getDimension(R.dimen.max_drawer_width);
84 int finalWidth = (int) ((width > maxWidth ? maxWidth : width));
85
86 if (DEBUG)
87 Log.d(TAG, "Calculated drawer width:" + (finalWidth / Display.density(activity)));
88
89 return finalWidth;
90 }
91
Steve McKay6bbed4d2015-08-17 13:18:05 -070092 /**
93 * Runtime controller that manages a real drawer.
94 */
Garfield, Tan7d66a862016-05-11 10:28:41 -070095 private static final class RuntimeDrawerController extends DrawerController
96 implements ItemDragListener.DragHost {
Ben Linb1ab6962017-03-14 10:48:57 -070097 private static final int SPRING_TIMEOUT = 750;
Steve McKay6bbed4d2015-08-17 13:18:05 -070098 private final ActionBarDrawerToggle mToggle;
99 private DrawerLayout mLayout;
100 private View mDrawer;
Steve McKay18d01e82016-02-03 11:15:57 -0800101 private Toolbar mToolbar;
Steve McKay6bbed4d2015-08-17 13:18:05 -0700102
103 public RuntimeDrawerController(
Garfield Tan208945c2016-10-04 14:36:38 -0700104 DrawerLayout layout,
105 View drawer,
106 ActionBarDrawerToggle toggle,
107 Toolbar drawerToolbar,
108 ActivityConfig activityConfig) {
Steve McKay18d01e82016-02-03 11:15:57 -0800109 mToolbar = drawerToolbar;
Steve McKay0af8afd2016-02-25 13:34:03 -0800110 assert(layout != null);
Steve McKay6bbed4d2015-08-17 13:18:05 -0700111
112 mLayout = layout;
113 mDrawer = drawer;
114 mToggle = toggle;
115
116 mLayout.setDrawerListener(this);
Garfield, Tan7d66a862016-05-11 10:28:41 -0700117
Garfield Tan208945c2016-10-04 14:36:38 -0700118 if (activityConfig.dragAndDropEnabled()) {
119 View edge = layout.findViewById(R.id.drawer_edge);
Ben Linb1ab6962017-03-14 10:48:57 -0700120 edge.setOnDragListener(new ItemDragListener<>(this, SPRING_TIMEOUT));
Garfield Tan208945c2016-10-04 14:36:38 -0700121 }
Garfield, Tan7d66a862016-05-11 10:28:41 -0700122 }
123
124 @Override
125 public void runOnUiThread(Runnable runnable) {
126 mDrawer.post(runnable);
127 }
128
129 @Override
Garfield Tanda2c0f02017-04-11 13:47:58 -0700130 public void setDropTargetHighlight(View v, boolean highlight) {
Ben Lin693a3522017-03-07 16:00:29 -0800131 assert (v.getId() == R.id.drawer_edge);
132
Tony Huang09571b22019-03-14 14:47:53 +0800133 @ColorRes int id = highlight ? R.color.secondary :
Ben Lin693a3522017-03-07 16:00:29 -0800134 android.R.color.transparent;
135 v.setBackgroundColor(id);
Ben Lin7f72a3c2016-09-27 16:37:28 -0700136 }
137
138 @Override
Garfield Tanda2c0f02017-04-11 13:47:58 -0700139 public void onDragEntered(View v) {
Ben Lin693a3522017-03-07 16:00:29 -0800140 // do nothing; let drawer only open for onViewHovered
Garfield, Tan7d66a862016-05-11 10:28:41 -0700141 }
142
143 @Override
Garfield Tanda2c0f02017-04-11 13:47:58 -0700144 public void onDragExited(View v) {
Ben Lind0202122016-11-10 18:00:12 -0800145 // do nothing
146 }
147
148 @Override
Garfield, Tan7d66a862016-05-11 10:28:41 -0700149 public void onViewHovered(View v) {
Ben Lin693a3522017-03-07 16:00:29 -0800150 assert (v.getId() == R.id.drawer_edge);
151
152 setOpen(true);
Steve McKay6bbed4d2015-08-17 13:18:05 -0700153 }
154
155 @Override
Garfield Tanda2c0f02017-04-11 13:47:58 -0700156 public void onDragEnded() {
157 // do nothing
158 }
159
160 @Override
Steve McKay16e0c1f2016-09-15 12:41:13 -0700161 public void setOpen(boolean open) {
Steve McKay6bbed4d2015-08-17 13:18:05 -0700162 if (open) {
163 mLayout.openDrawer(mDrawer);
164 } else {
165 mLayout.closeDrawer(mDrawer);
166 }
167 }
168
169 @Override
Steve McKay16e0c1f2016-09-15 12:41:13 -0700170 public boolean isOpen() {
Steve McKay6bbed4d2015-08-17 13:18:05 -0700171 return mLayout.isDrawerOpen(mDrawer);
172 }
173
174 @Override
Steve McKay16e0c1f2016-09-15 12:41:13 -0700175 public boolean isPresent() {
Steve McKay0fbfc652015-08-20 16:48:49 -0700176 return true;
177 }
178
179 @Override
Steve McKay18d01e82016-02-03 11:15:57 -0800180 void setTitle(String title) {
181 mToolbar.setTitle(title);
182 }
183
184 @Override
Steve McKay16e0c1f2016-09-15 12:41:13 -0700185 public void update() {
Steve McKay6bbed4d2015-08-17 13:18:05 -0700186 mToggle.syncState();
187 }
188
189 @Override
Steve McKay6bbed4d2015-08-17 13:18:05 -0700190 public void onDrawerSlide(View drawerView, float slideOffset) {
191 mToggle.onDrawerSlide(drawerView, slideOffset);
192 }
193
194 @Override
195 public void onDrawerOpened(View drawerView) {
196 mToggle.onDrawerOpened(drawerView);
197 }
198
199 @Override
200 public void onDrawerClosed(View drawerView) {
201 mToggle.onDrawerClosed(drawerView);
202 }
203
204 @Override
205 public void onDrawerStateChanged(int newState) {
206 mToggle.onDrawerStateChanged(newState);
207 }
208 }
209
210 /*
211 * Dummy controller useful with clients that don't host a real drawer.
212 */
213 private static final class DummyDrawerController extends DrawerController {
214
215 @Override
Steve McKay16e0c1f2016-09-15 12:41:13 -0700216 public void setOpen(boolean open) {}
Steve McKay6bbed4d2015-08-17 13:18:05 -0700217
Aga Wronska441b9be2016-03-29 16:57:10 -0700218 @Override
Steve McKay16e0c1f2016-09-15 12:41:13 -0700219 public boolean isOpen() {
Steve McKay0fbfc652015-08-20 16:48:49 -0700220 return false;
221 }
222
223 @Override
Steve McKay16e0c1f2016-09-15 12:41:13 -0700224 public boolean isPresent() {
Steve McKay0fbfc652015-08-20 16:48:49 -0700225 return false;
226 }
227
228 @Override
Steve McKay18d01e82016-02-03 11:15:57 -0800229 void setTitle(String title) {}
230
231 @Override
Steve McKay16e0c1f2016-09-15 12:41:13 -0700232 public void update() {}
Steve McKay6bbed4d2015-08-17 13:18:05 -0700233
234 @Override
235 public void onDrawerSlide(View drawerView, float slideOffset) {}
236
237 @Override
238 public void onDrawerOpened(View drawerView) {}
239
240 @Override
241 public void onDrawerClosed(View drawerView) {}
242
243 @Override
244 public void onDrawerStateChanged(int newState) {}
Steve McKay6bbed4d2015-08-17 13:18:05 -0700245 }
246}