Home | History | Annotate | Download | only in globalactions
      1 /*
      2  * Copyright (C) 2019 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.globalactions;
     18 
     19 import static com.android.systemui.util.leak.RotationUtils.ROTATION_LANDSCAPE;
     20 import static com.android.systemui.util.leak.RotationUtils.ROTATION_NONE;
     21 import static com.android.systemui.util.leak.RotationUtils.ROTATION_SEASCAPE;
     22 
     23 import android.content.Context;
     24 import android.util.AttributeSet;
     25 import android.view.View;
     26 import android.view.ViewGroup;
     27 
     28 import com.android.internal.annotations.VisibleForTesting;
     29 
     30 /**
     31  * Grid-based implementation of the button layout created by the global actions dialog.
     32  */
     33 public class GlobalActionsGridLayout extends GlobalActionsLayout {
     34     public GlobalActionsGridLayout(Context context, AttributeSet attrs) {
     35         super(context, attrs);
     36     }
     37 
     38     @VisibleForTesting
     39     protected void setupListView() {
     40         ListGridLayout listView = getListView();
     41         listView.setExpectedCount(mAdapter.countListItems());
     42         listView.setReverseSublists(shouldReverseSublists());
     43         listView.setReverseItems(shouldReverseListItems());
     44         listView.setSwapRowsAndColumns(shouldSwapRowsAndColumns());
     45     }
     46 
     47     @Override
     48     public void onUpdateList() {
     49         setupListView();
     50         super.onUpdateList();
     51         updateSeparatedItemSize();
     52     }
     53 
     54     /**
     55      * If the separated view contains only one item, expand the bounds of that item to take up the
     56      * entire view, so that the whole thing is touch-able.
     57      */
     58     @VisibleForTesting
     59     protected void updateSeparatedItemSize() {
     60         ViewGroup separated = getSeparatedView();
     61         if (separated.getChildCount() == 0) {
     62             return;
     63         }
     64         View firstChild = separated.getChildAt(0);
     65         ViewGroup.LayoutParams childParams = firstChild.getLayoutParams();
     66 
     67         if (separated.getChildCount() == 1) {
     68             childParams.width = ViewGroup.LayoutParams.MATCH_PARENT;
     69             childParams.height = ViewGroup.LayoutParams.MATCH_PARENT;
     70         } else {
     71             childParams.width = ViewGroup.LayoutParams.WRAP_CONTENT;
     72             childParams.height = ViewGroup.LayoutParams.WRAP_CONTENT;
     73         }
     74     }
     75 
     76     @Override
     77     protected ListGridLayout getListView() {
     78         return (ListGridLayout) super.getListView();
     79     }
     80 
     81     @Override
     82     protected void removeAllListViews() {
     83         ListGridLayout list = getListView();
     84         if (list != null) {
     85             list.removeAllItems();
     86         }
     87     }
     88 
     89     @Override
     90     protected void addToListView(View v, boolean reverse) {
     91         ListGridLayout list = getListView();
     92         if (list != null) {
     93             list.addItem(v);
     94         }
     95     }
     96 
     97     @Override
     98     public void removeAllItems() {
     99         ViewGroup separatedList = getSeparatedView();
    100         ListGridLayout list = getListView();
    101         if (separatedList != null) {
    102             separatedList.removeAllViews();
    103         }
    104         if (list != null) {
    105             list.removeAllItems();
    106         }
    107     }
    108 
    109     /**
    110      * Determines whether the ListGridLayout should fill sublists in the reverse order.
    111      * Used to account for sublist ordering changing between landscape and seascape views.
    112      */
    113     @VisibleForTesting
    114     protected boolean shouldReverseSublists() {
    115         if (getCurrentRotation() == ROTATION_SEASCAPE) {
    116             return true;
    117         }
    118         return false;
    119     }
    120 
    121     /**
    122      * Determines whether the ListGridLayout should fill rows first instead of columns.
    123      * Used to account for vertical/horizontal changes due to landscape or seascape rotations.
    124      */
    125     @VisibleForTesting
    126     protected boolean shouldSwapRowsAndColumns() {
    127         if (getCurrentRotation() == ROTATION_NONE) {
    128             return false;
    129         }
    130         return true;
    131     }
    132 
    133     @Override
    134     protected boolean shouldReverseListItems() {
    135         int rotation = getCurrentRotation();
    136         boolean reverse = false; // should we add items to parents in the reverse order?
    137         if (rotation == ROTATION_NONE
    138                 || rotation == ROTATION_SEASCAPE) {
    139             reverse = !reverse; // if we're in portrait or seascape, reverse items
    140         }
    141         if (getCurrentLayoutDirection() == View.LAYOUT_DIRECTION_RTL) {
    142             reverse = !reverse; // if we're in an RTL language, reverse items (again)
    143         }
    144         return reverse;
    145     }
    146 
    147     @VisibleForTesting
    148     protected float getAnimationDistance() {
    149         int rows = getListView().getRowCount();
    150         float gridItemSize = getContext().getResources().getDimension(
    151                 com.android.systemui.R.dimen.global_actions_grid_item_height);
    152         return rows * gridItemSize / 2;
    153     }
    154 
    155     @Override
    156     public float getAnimationOffsetX() {
    157         switch (getCurrentRotation()) {
    158             case ROTATION_LANDSCAPE:
    159                 return getAnimationDistance();
    160             case ROTATION_SEASCAPE:
    161                 return -getAnimationDistance();
    162             default: // Portrait
    163                 return 0;
    164         }
    165     }
    166 
    167     @Override
    168     public float getAnimationOffsetY() {
    169         if (getCurrentRotation() == ROTATION_NONE) {
    170             return getAnimationDistance();
    171         }
    172         return 0;
    173     }
    174 }
    175