/* * Copyright (C) 2019 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.systemui.globalactions; import static com.android.systemui.util.leak.RotationUtils.ROTATION_LANDSCAPE; import static com.android.systemui.util.leak.RotationUtils.ROTATION_NONE; import static com.android.systemui.util.leak.RotationUtils.ROTATION_SEASCAPE; import android.content.Context; import android.util.AttributeSet; import android.view.View; import android.view.ViewGroup; import com.android.internal.annotations.VisibleForTesting; /** * Grid-based implementation of the button layout created by the global actions dialog. */ public class GlobalActionsGridLayout extends GlobalActionsLayout { public GlobalActionsGridLayout(Context context, AttributeSet attrs) { super(context, attrs); } @VisibleForTesting protected void setupListView() { ListGridLayout listView = getListView(); listView.setExpectedCount(mAdapter.countListItems()); listView.setReverseSublists(shouldReverseSublists()); listView.setReverseItems(shouldReverseListItems()); listView.setSwapRowsAndColumns(shouldSwapRowsAndColumns()); } @Override public void onUpdateList() { setupListView(); super.onUpdateList(); updateSeparatedItemSize(); } /** * If the separated view contains only one item, expand the bounds of that item to take up the * entire view, so that the whole thing is touch-able. */ @VisibleForTesting protected void updateSeparatedItemSize() { ViewGroup separated = getSeparatedView(); if (separated.getChildCount() == 0) { return; } View firstChild = separated.getChildAt(0); ViewGroup.LayoutParams childParams = firstChild.getLayoutParams(); if (separated.getChildCount() == 1) { childParams.width = ViewGroup.LayoutParams.MATCH_PARENT; childParams.height = ViewGroup.LayoutParams.MATCH_PARENT; } else { childParams.width = ViewGroup.LayoutParams.WRAP_CONTENT; childParams.height = ViewGroup.LayoutParams.WRAP_CONTENT; } } @Override protected ListGridLayout getListView() { return (ListGridLayout) super.getListView(); } @Override protected void removeAllListViews() { ListGridLayout list = getListView(); if (list != null) { list.removeAllItems(); } } @Override protected void addToListView(View v, boolean reverse) { ListGridLayout list = getListView(); if (list != null) { list.addItem(v); } } @Override public void removeAllItems() { ViewGroup separatedList = getSeparatedView(); ListGridLayout list = getListView(); if (separatedList != null) { separatedList.removeAllViews(); } if (list != null) { list.removeAllItems(); } } /** * Determines whether the ListGridLayout should fill sublists in the reverse order. * Used to account for sublist ordering changing between landscape and seascape views. */ @VisibleForTesting protected boolean shouldReverseSublists() { if (getCurrentRotation() == ROTATION_SEASCAPE) { return true; } return false; } /** * Determines whether the ListGridLayout should fill rows first instead of columns. * Used to account for vertical/horizontal changes due to landscape or seascape rotations. */ @VisibleForTesting protected boolean shouldSwapRowsAndColumns() { if (getCurrentRotation() == ROTATION_NONE) { return false; } return true; } @Override protected boolean shouldReverseListItems() { int rotation = getCurrentRotation(); boolean reverse = false; // should we add items to parents in the reverse order? if (rotation == ROTATION_NONE || rotation == ROTATION_SEASCAPE) { reverse = !reverse; // if we're in portrait or seascape, reverse items } if (getCurrentLayoutDirection() == View.LAYOUT_DIRECTION_RTL) { reverse = !reverse; // if we're in an RTL language, reverse items (again) } return reverse; } @VisibleForTesting protected float getAnimationDistance() { int rows = getListView().getRowCount(); float gridItemSize = getContext().getResources().getDimension( com.android.systemui.R.dimen.global_actions_grid_item_height); return rows * gridItemSize / 2; } @Override public float getAnimationOffsetX() { switch (getCurrentRotation()) { case ROTATION_LANDSCAPE: return getAnimationDistance(); case ROTATION_SEASCAPE: return -getAnimationDistance(); default: // Portrait return 0; } } @Override public float getAnimationOffsetY() { if (getCurrentRotation() == ROTATION_NONE) { return getAnimationDistance(); } return 0; } }