/*
|
* 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.Gravity;
|
import android.view.View;
|
|
import com.android.internal.annotations.VisibleForTesting;
|
import com.android.systemui.R;
|
|
/**
|
* Grid-based implementation of the button layout created by the global actions dialog.
|
*/
|
public class GlobalActionsColumnLayout extends GlobalActionsLayout {
|
private boolean mLastSnap;
|
|
public GlobalActionsColumnLayout(Context context, AttributeSet attrs) {
|
super(context, attrs);
|
}
|
|
@Override
|
protected void onLayout(boolean changed, int l, int t, int r, int b) {
|
super.onLayout(changed, l, t, r, b);
|
|
// don't update GlobalActionsColumnLayout, this code is designed for phone
|
//post(() -> updateSnap());
|
}
|
|
@Override
|
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
|
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
|
}
|
|
@VisibleForTesting
|
protected boolean shouldReverseListItems() {
|
int rotation = getCurrentRotation();
|
if (rotation == ROTATION_NONE) {
|
return false;
|
}
|
if (getCurrentLayoutDirection() == View.LAYOUT_DIRECTION_RTL) {
|
return rotation == ROTATION_LANDSCAPE;
|
}
|
return rotation == ROTATION_SEASCAPE;
|
}
|
|
@Override
|
public void onUpdateList() {
|
super.onUpdateList();
|
updateChildOrdering();
|
}
|
|
private void updateChildOrdering() {
|
if (shouldReverseListItems()) {
|
getListView().bringToFront();
|
} else {
|
getSeparatedView().bringToFront();
|
}
|
}
|
|
/**
|
* Snap this layout to align with the power button.
|
*/
|
@VisibleForTesting
|
protected void snapToPowerButton() {
|
int offset = getPowerButtonOffsetDistance();
|
switch (getCurrentRotation()) {
|
case (ROTATION_LANDSCAPE):
|
setPadding(offset, 0, 0, 0);
|
setGravity(Gravity.LEFT | Gravity.TOP);
|
break;
|
case (ROTATION_SEASCAPE):
|
setPadding(0, 0, offset, 0);
|
setGravity(Gravity.RIGHT | Gravity.BOTTOM);
|
break;
|
default:
|
setPadding(0, offset, 0, 0);
|
setGravity(Gravity.TOP | Gravity.RIGHT);
|
break;
|
}
|
}
|
|
/**
|
* Detach this layout from snapping to the power button and instead center along that edge.
|
*/
|
@VisibleForTesting
|
protected void centerAlongEdge() {
|
switch (getCurrentRotation()) {
|
case (ROTATION_LANDSCAPE):
|
setPadding(0, 0, 0, 0);
|
setGravity(Gravity.CENTER_HORIZONTAL | Gravity.TOP);
|
break;
|
case (ROTATION_SEASCAPE):
|
setPadding(0, 0, 0, 0);
|
setGravity(Gravity.CENTER_HORIZONTAL | Gravity.BOTTOM);
|
break;
|
default:
|
setPadding(0, 0, 0, 0);
|
setGravity(Gravity.CENTER_VERTICAL | Gravity.RIGHT);
|
break;
|
}
|
}
|
|
/**
|
* Determines the distance from the top of the screen to the power button.
|
*/
|
@VisibleForTesting
|
protected int getPowerButtonOffsetDistance() {
|
return Math.round(getContext().getResources().getDimension(
|
R.dimen.global_actions_top_padding));
|
}
|
|
/**
|
* Check whether there is enough extra space below the dialog such that we can offset the top
|
* of the dialog from the top of the phone to line it up with the power button, then either
|
* snap the dialog to the power button or center it along the edge with snapToPowerButton.
|
*/
|
@VisibleForTesting
|
protected boolean shouldSnapToPowerButton() {
|
int offsetSize = getPowerButtonOffsetDistance();
|
int dialogSize;
|
int screenSize;
|
View wrapper = getWrapper();
|
int rotation = getCurrentRotation();
|
if (rotation == ROTATION_NONE) {
|
dialogSize = wrapper.getMeasuredHeight();
|
screenSize = getMeasuredHeight();
|
} else {
|
dialogSize = wrapper.getMeasuredWidth();
|
screenSize = getMeasuredWidth();
|
}
|
return dialogSize + offsetSize < screenSize;
|
}
|
|
@VisibleForTesting
|
protected void updateSnap() {
|
boolean snap = shouldSnapToPowerButton();
|
if (snap != mLastSnap) {
|
if (snap) {
|
snapToPowerButton();
|
} else {
|
centerAlongEdge();
|
}
|
}
|
mLastSnap = snap;
|
}
|
|
@VisibleForTesting
|
protected float getGridItemSize() {
|
// set animation distance 0, our platform will make screen blinking.
|
return 0;
|
//return getContext().getResources().getDimension(R.dimen.global_actions_grid_item_height);
|
}
|
|
@VisibleForTesting
|
protected float getAnimationDistance() {
|
return getGridItemSize() / 2;
|
}
|
|
@Override
|
public float getAnimationOffsetX() {
|
if (getCurrentRotation() == ROTATION_NONE) {
|
return getAnimationDistance();
|
}
|
return 0;
|
}
|
|
@Override
|
public float getAnimationOffsetY() {
|
switch (getCurrentRotation()) {
|
case ROTATION_LANDSCAPE:
|
return -getAnimationDistance();
|
case ROTATION_SEASCAPE:
|
return getAnimationDistance();
|
default: // Portrait
|
return 0;
|
}
|
}
|
}
|