• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 static android.view.View.LAYOUT_DIRECTION_LTR;
20 
21 import android.content.res.Configuration;
22 import android.graphics.Rect;
23 import android.text.TextUtils;
24 import android.view.TouchDelegate;
25 import android.view.View;
26 import android.view.View.OnClickListener;
27 import android.view.ViewGroup;
28 import android.view.ViewTreeObserver.OnGlobalLayoutListener;
29 import android.widget.ImageButton;
30 
31 import androidx.annotation.Nullable;
32 
33 import com.android.systemui.accessibility.accessibilitymenu.R;
34 
35 /**
36  * This class is for Accessibility menu footer layout. Handles switching between a11y menu pages.
37  */
38 public class A11yMenuFooter {
39 
40     /** Provides an interface for footer of a11yMenu. */
41     public interface A11yMenuFooterCallBack {
42 
43         /** Calls back when user clicks the left button. */
onNextButtonClicked()44         void onNextButtonClicked();
45 
46         /** Calls back when user clicks the right button. */
onPreviousButtonClicked()47         void onPreviousButtonClicked();
48     }
49 
50     private final FooterButtonClickListener mFooterButtonClickListener;
51 
52     private ImageButton mPageLeftBtn;
53     private ImageButton mPageRightBtn;
54     private View mTopListDivider;
55     private View mBottomListDivider;
56     private final A11yMenuFooterCallBack mCallBack;
57     private final ViewGroup mMenuLayout;
58     private ViewGroup mFooterContainer;
59     private int mFooterContainerBaseHeight = 0;
60     private int mRightToLeftDirection = LAYOUT_DIRECTION_LTR;
61 
A11yMenuFooter(ViewGroup menuLayout, A11yMenuFooterCallBack callBack)62     public A11yMenuFooter(ViewGroup menuLayout, A11yMenuFooterCallBack callBack) {
63         this.mCallBack = callBack;
64         mFooterButtonClickListener = new FooterButtonClickListener();
65         configureFooterLayout(menuLayout);
66         mMenuLayout = menuLayout;
67     }
68 
getPreviousPageBtn()69     public @Nullable ImageButton getPreviousPageBtn() {
70         return mRightToLeftDirection == LAYOUT_DIRECTION_LTR
71                 ? mPageLeftBtn : mPageRightBtn;
72     }
73 
getNextPageBtn()74     public @Nullable ImageButton getNextPageBtn() {
75         return mRightToLeftDirection == LAYOUT_DIRECTION_LTR
76                 ? mPageRightBtn : mPageLeftBtn;
77     }
78 
adjustFooterToDensityScale(float densityScale)79     void adjustFooterToDensityScale(float densityScale) {
80         mFooterContainer.getLayoutParams().height =
81                 (int) (mFooterContainerBaseHeight / densityScale);
82     }
83 
getHeight()84     int getHeight() {
85         return mFooterContainer.getLayoutParams().height;
86     }
87 
88     /** Sets right to left direction of footer. */
updateRightToLeftDirection(Configuration configuration)89     public void updateRightToLeftDirection(Configuration configuration) {
90         mRightToLeftDirection = TextUtils.getLayoutDirectionFromLocale(
91                 configuration.getLocales().get(0));
92         getPreviousPageBtn().setContentDescription(mMenuLayout.getResources().getString(
93                 R.string.previous_button_content_description));
94         getNextPageBtn().setContentDescription(mMenuLayout.getResources().getString(
95                 R.string.next_button_content_description));
96     }
97 
configureFooterLayout(ViewGroup menuLayout)98     private void configureFooterLayout(ViewGroup menuLayout) {
99         mFooterContainer = menuLayout.findViewById(R.id.footerlayout);
100         mFooterContainer.setVisibility(View.VISIBLE);
101         mFooterContainerBaseHeight = mFooterContainer.getLayoutParams().height;
102 
103         mPageLeftBtn = menuLayout.findViewById(R.id.menu_left_button);
104         mPageRightBtn = menuLayout.findViewById(R.id.menu_right_button);
105         mTopListDivider = menuLayout.findViewById(R.id.top_listDivider);
106         mBottomListDivider = menuLayout.findViewById(R.id.bottom_listDivider);
107 
108         // Registers listeners for footer buttons.
109         setListener(mPageLeftBtn);
110         setListener(mPageRightBtn);
111 
112         menuLayout
113                 .getViewTreeObserver()
114                 .addOnGlobalLayoutListener(
115                         new OnGlobalLayoutListener() {
116                             @Override
117                             public void onGlobalLayout() {
118                                 menuLayout.getViewTreeObserver().removeOnGlobalLayoutListener(this);
119                                 expandBtnTouchArea(mPageLeftBtn, menuLayout);
120                                 expandBtnTouchArea(mPageRightBtn, (View) mPageRightBtn.getParent());
121                             }
122                         });
123     }
124 
expandBtnTouchArea(ImageButton btn, View btnParent)125     private void expandBtnTouchArea(ImageButton btn, View btnParent) {
126         Rect btnRect = new Rect();
127         btn.getHitRect(btnRect);
128         btnRect.top -= getHitRectHeight(mTopListDivider);
129         btnRect.bottom += getHitRectHeight(mBottomListDivider);
130         btnParent.setTouchDelegate(new TouchDelegate(btnRect, btn));
131     }
132 
getHitRectHeight(View listDivider)133     private static int getHitRectHeight(View listDivider) {
134         Rect hitRect = new Rect();
135         listDivider.getHitRect(hitRect);
136         return hitRect.height();
137     }
138 
setListener(@ullable View view)139     private void setListener(@Nullable View view) {
140         if (view != null) {
141             view.setOnClickListener(mFooterButtonClickListener);
142         }
143     }
144 
145     /** Handles click event for footer buttons. */
146     private class FooterButtonClickListener implements OnClickListener {
147         @Override
onClick(View view)148         public void onClick(View view) {
149             if (view.getId() == getPreviousPageBtn().getId()) {
150                 mCallBack.onPreviousButtonClicked();
151             } else if (view.getId() == getNextPageBtn().getId()) {
152                 mCallBack.onNextButtonClicked();
153             }
154         }
155     }
156 }
157