1 /*
2  * Copyright (C) 2017 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 androidx.wear.internal.widget.drawer;
18 
19 import androidx.annotation.RestrictTo;
20 import androidx.annotation.RestrictTo.Scope;
21 import androidx.wear.widget.drawer.WearableNavigationDrawerView;
22 import androidx.wear.widget.drawer.WearableNavigationDrawerView.WearableNavigationDrawerAdapter;
23 
24 import org.jspecify.annotations.Nullable;
25 
26 /**
27  * Provides a {@link WearableNavigationDrawerPresenter} implementation that is designed for the
28  * multi-page navigation drawer.
29  *
30  */
31 @RestrictTo(Scope.LIBRARY)
32 public class MultiPagePresenter extends WearableNavigationDrawerPresenter {
33 
34     private final Ui mUi;
35     private final WearableNavigationDrawerView mDrawer;
36     private final boolean mIsAccessibilityEnabled;
37     private @Nullable WearableNavigationDrawerAdapter mAdapter;
38 
39     /**
40      * Controls the user interface of a multi-page {@link WearableNavigationDrawerView}.
41      */
42     public interface Ui {
43 
44         /**
45          * Initializes the {@code Ui}.
46          */
initialize(WearableNavigationDrawerView drawer, WearableNavigationDrawerPresenter presenter)47         void initialize(WearableNavigationDrawerView drawer,
48                 WearableNavigationDrawerPresenter presenter);
49 
50         /**
51          * Should notify the {@code NavigationPagerAdapter} that the underlying data has changed.
52          */
notifyNavigationPagerAdapterDataChanged()53         void notifyNavigationPagerAdapterDataChanged();
54 
55         /**
56          * Should notify the Page Indicator that the underlying data has changed.
57          */
notifyPageIndicatorDataChanged()58         void notifyPageIndicatorDataChanged();
59 
60         /**
61          * Associates the given {@code adapter} with this {@link Ui}.
62          */
setNavigationPagerAdapter(WearableNavigationDrawerAdapter adapter)63         void setNavigationPagerAdapter(WearableNavigationDrawerAdapter adapter);
64 
65         /**
66          * Sets which item is selected and optionally smooth scrolls to it.
67          */
setNavigationPagerSelectedItem(int index, boolean smoothScrollTo)68         void setNavigationPagerSelectedItem(int index, boolean smoothScrollTo);
69     }
70 
MultiPagePresenter(WearableNavigationDrawerView drawer, Ui ui, boolean isAccessibilityEnabled)71     public MultiPagePresenter(WearableNavigationDrawerView drawer, Ui ui,
72             boolean isAccessibilityEnabled) {
73         if (drawer == null) {
74             throw new IllegalArgumentException("Received null drawer.");
75         }
76         if (ui == null) {
77             throw new IllegalArgumentException("Received null ui.");
78         }
79         mDrawer = drawer;
80         mUi = ui;
81         mUi.initialize(drawer, this);
82         mIsAccessibilityEnabled = isAccessibilityEnabled;
83     }
84 
85     @Override
onDataSetChanged()86     public void onDataSetChanged() {
87         mUi.notifyNavigationPagerAdapterDataChanged();
88         mUi.notifyPageIndicatorDataChanged();
89     }
90 
91     @Override
onNewAdapter(WearableNavigationDrawerAdapter adapter)92     public void onNewAdapter(WearableNavigationDrawerAdapter adapter) {
93         if (adapter == null) {
94             throw new IllegalArgumentException("Received null adapter.");
95         }
96         mAdapter = adapter;
97         mAdapter.setPresenter(this);
98         mUi.setNavigationPagerAdapter(adapter);
99     }
100 
101     @Override
onSelected(int index)102     public void onSelected(int index) {
103         notifyItemSelectedListeners(index);
104     }
105 
106     @Override
onSetCurrentItemRequested(int index, boolean smoothScrollTo)107     public void onSetCurrentItemRequested(int index, boolean smoothScrollTo) {
108         mUi.setNavigationPagerSelectedItem(index, smoothScrollTo);
109     }
110 
111     @Override
onDrawerTapped()112     public boolean onDrawerTapped() {
113         if (mDrawer.isOpened()) {
114             if (mIsAccessibilityEnabled) {
115                 // When accessibility gestures are enabled, the user can't access a closed nav
116                 // drawer, so peek it instead.
117                 mDrawer.getController().peekDrawer();
118             } else {
119                 mDrawer.getController().closeDrawer();
120             }
121             return true;
122         }
123         return false;
124     }
125 }
126