1 /*
2  * Copyright (C) 2023 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 com.android.systemui.accessibility.accessibilitymenu.view;
18 
19 import android.graphics.Rect;
20 import android.view.TouchDelegate;
21 import android.view.View;
22 import android.view.View.OnClickListener;
23 import android.view.ViewGroup;
24 import android.view.ViewTreeObserver.OnGlobalLayoutListener;
25 import android.widget.ImageButton;
26 
27 import androidx.annotation.Nullable;
28 
29 import com.android.systemui.accessibility.accessibilitymenu.R;
30 
31 /**
32  * This class is for Accessibility menu footer layout. Handles switching between a11y menu pages.
33  */
34 public class A11yMenuFooter {
35 
36     /** Provides an interface for footer of a11yMenu. */
37     public interface A11yMenuFooterCallBack {
38 
39         /** Calls back when user clicks the left button. */
onLeftButtonClicked()40         void onLeftButtonClicked();
41 
42         /** Calls back when user clicks the right button. */
onRightButtonClicked()43         void onRightButtonClicked();
44     }
45 
46     private final FooterButtonClickListener mFooterButtonClickListener;
47 
48     private ImageButton mPreviousPageBtn;
49     private ImageButton mNextPageBtn;
50     private View mTopListDivider;
51     private View mBottomListDivider;
52     private final A11yMenuFooterCallBack mCallBack;
53 
A11yMenuFooter(ViewGroup menuLayout, A11yMenuFooterCallBack callBack)54     public A11yMenuFooter(ViewGroup menuLayout, A11yMenuFooterCallBack callBack) {
55         this.mCallBack = callBack;
56         mFooterButtonClickListener = new FooterButtonClickListener();
57         configureFooterLayout(menuLayout);
58     }
59 
getPreviousPageBtn()60     public @Nullable ImageButton getPreviousPageBtn() {
61         return mPreviousPageBtn;
62     }
63 
getNextPageBtn()64     public @Nullable ImageButton getNextPageBtn() {
65         return mNextPageBtn;
66     }
67 
configureFooterLayout(ViewGroup menuLayout)68     private void configureFooterLayout(ViewGroup menuLayout) {
69         ViewGroup footerContainer = menuLayout.findViewById(R.id.footerlayout);
70         footerContainer.setVisibility(View.VISIBLE);
71 
72         mPreviousPageBtn = menuLayout.findViewById(R.id.menu_prev_button);
73         mNextPageBtn = menuLayout.findViewById(R.id.menu_next_button);
74         mTopListDivider = menuLayout.findViewById(R.id.top_listDivider);
75         mBottomListDivider = menuLayout.findViewById(R.id.bottom_listDivider);
76 
77         // Registers listeners for footer buttons.
78         setListener(mPreviousPageBtn);
79         setListener(mNextPageBtn);
80 
81         menuLayout
82                 .getViewTreeObserver()
83                 .addOnGlobalLayoutListener(
84                         new OnGlobalLayoutListener() {
85                             @Override
86                             public void onGlobalLayout() {
87                                 menuLayout.getViewTreeObserver().removeOnGlobalLayoutListener(this);
88                                 expandBtnTouchArea(mPreviousPageBtn, menuLayout);
89                                 expandBtnTouchArea(mNextPageBtn, (View) mNextPageBtn.getParent());
90                             }
91                         });
92     }
93 
expandBtnTouchArea(ImageButton btn, View btnParent)94     private void expandBtnTouchArea(ImageButton btn, View btnParent) {
95         Rect btnRect = new Rect();
96         btn.getHitRect(btnRect);
97         btnRect.top -= getHitRectHeight(mTopListDivider);
98         btnRect.bottom += getHitRectHeight(mBottomListDivider);
99         btnParent.setTouchDelegate(new TouchDelegate(btnRect, btn));
100     }
101 
getHitRectHeight(View listDivider)102     private static int getHitRectHeight(View listDivider) {
103         Rect hitRect = new Rect();
104         listDivider.getHitRect(hitRect);
105         return hitRect.height();
106     }
107 
setListener(@ullable View view)108     private void setListener(@Nullable View view) {
109         if (view != null) {
110             view.setOnClickListener(mFooterButtonClickListener);
111         }
112     }
113 
114     /** Handles click event for footer buttons. */
115     private class FooterButtonClickListener implements OnClickListener {
116         @Override
onClick(View view)117         public void onClick(View view) {
118             if (view.getId() == R.id.menu_prev_button) {
119                 mCallBack.onLeftButtonClicked();
120             } else if (view.getId() == R.id.menu_next_button) {
121                 mCallBack.onRightButtonClicked();
122             }
123         }
124     }
125 }
126