Files
Lawnchair/src/com/android/launcher3/widget/WidgetsBottomSheet.java
T
Shamali P 00d4e05072 Move widget related listeners to widget picker data provider
The change listener on popup provider was for listening to widget
updates. With the widget now updated in widgets picker data provider,
 this moves over the listeners to it.

Test: Existing tests
Flag: EXEMPT minor refactoring
Bug: 353347512
Change-Id: I163529d207ea65044f8e3d6e77e87e0e674b82be
2024-07-22 23:58:04 +00:00

254 lines
9.1 KiB
Java

/*
* Copyright (C) 2017 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.launcher3.widget;
import static com.android.launcher3.LauncherSettings.Favorites.CONTAINER_BOTTOM_WIDGETS_TRAY;
import android.content.Context;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.util.Pair;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewParent;
import android.view.animation.Interpolator;
import android.widget.ScrollView;
import android.widget.TableLayout;
import android.widget.TextView;
import androidx.annotation.Px;
import com.android.launcher3.R;
import com.android.launcher3.anim.PendingAnimation;
import com.android.launcher3.model.WidgetItem;
import com.android.launcher3.model.data.ItemInfo;
import com.android.launcher3.util.PackageUserKey;
import com.android.launcher3.widget.util.WidgetsTableUtils;
import java.util.List;
/**
* Bottom sheet for the "Widgets" system shortcut in the long-press popup.
*/
public class WidgetsBottomSheet extends BaseWidgetSheet {
private static final int DEFAULT_CLOSE_DURATION = 200;
private ItemInfo mOriginalItemInfo;
@Px private int mMaxHorizontalSpan;
public WidgetsBottomSheet(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public WidgetsBottomSheet(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
setWillNotDraw(false);
}
@Override
protected void onFinishInflate() {
super.onFinishInflate();
mContent = findViewById(R.id.widgets_bottom_sheet);
setContentBackgroundWithParent(
getContext().getDrawable(R.drawable.bg_rounded_corner_bottom_sheet), mContent);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
doMeasure(widthMeasureSpec, heightMeasureSpec);
if (updateMaxSpansPerRow()) {
doMeasure(widthMeasureSpec, heightMeasureSpec);
}
}
/** Returns {@code true} if the max spans have been updated. */
private boolean updateMaxSpansPerRow() {
if (getMeasuredWidth() == 0) return false;
@Px int maxHorizontalSpan = mContent.getMeasuredWidth() - (2 * mContentHorizontalMargin);
if (mMaxHorizontalSpan != maxHorizontalSpan) {
// Ensure the table layout is showing widgets in the right column after measure.
mMaxHorizontalSpan = maxHorizontalSpan;
onWidgetsBound();
return true;
}
return false;
}
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
int width = r - l;
int height = b - t;
// Content is laid out as center bottom aligned.
int contentWidth = mContent.getMeasuredWidth();
int contentLeft = (width - contentWidth - mInsets.left - mInsets.right) / 2 + mInsets.left;
mContent.layout(contentLeft, height - mContent.getMeasuredHeight(),
contentLeft + contentWidth, height);
setTranslationShift(mTranslationShift);
ScrollView widgetsTableScrollView = findViewById(R.id.widgets_table_scroll_view);
TableLayout widgetsTable = findViewById(R.id.widgets_table);
if (widgetsTable.getMeasuredHeight() > widgetsTableScrollView.getMeasuredHeight()) {
findViewById(R.id.collapse_handle).setVisibility(VISIBLE);
}
}
public void populateAndShow(ItemInfo itemInfo) {
mOriginalItemInfo = itemInfo;
((TextView) findViewById(R.id.title)).setText(mOriginalItemInfo.title);
onWidgetsBound();
attachToContainer();
mIsOpen = false;
animateOpen();
}
@Override
public void onWidgetsBound() {
List<WidgetItem> widgets = mActivityContext.getPopupDataProvider().getWidgetsForPackageUser(
new PackageUserKey(
mOriginalItemInfo.getTargetComponent().getPackageName(),
mOriginalItemInfo.user));
TableLayout widgetsTable = findViewById(R.id.widgets_table);
widgetsTable.removeAllViews();
WidgetsTableUtils.groupWidgetItemsUsingRowPxWithReordering(widgets, mActivityContext,
mActivityContext.getDeviceProfile(), mMaxHorizontalSpan,
mWidgetCellHorizontalPadding)
.forEach(row -> {
WidgetTableRow tableRow = new WidgetTableRow(getContext());
tableRow.setGravity(Gravity.TOP);
tableRow.setupRow(row.size(), /*resizeDelayMs=*/ 0);
row.forEach(widgetItem -> {
WidgetCell widget = addItemCell(tableRow);
widget.applyFromCellItem(widgetItem);
if (widget.matchesItem(getLastSelectedWidgetItem())) {
widget.callOnClick();
}
});
widgetsTable.addView(tableRow);
});
}
@Override
public boolean onControllerInterceptTouchEvent(MotionEvent ev) {
if (ev.getAction() == MotionEvent.ACTION_DOWN) {
mNoIntercept = false;
ScrollView scrollView = findViewById(R.id.widgets_table_scroll_view);
if (getPopupContainer().isEventOverView(scrollView, ev)
&& scrollView.getScrollY() > 0) {
mNoIntercept = true;
}
}
return super.onControllerInterceptTouchEvent(ev);
}
protected WidgetCell addItemCell(WidgetTableRow parent) {
WidgetCell widget = (WidgetCell) LayoutInflater.from(getContext())
.inflate(R.layout.widget_cell, parent, false);
widget.addPreviewReadyListener(parent);
widget.setOnClickListener(this);
View previewContainer = widget.findViewById(R.id.widget_preview_container);
previewContainer.setOnClickListener(this);
previewContainer.setOnLongClickListener(this);
widget.setAnimatePreview(false);
widget.setSourceContainer(CONTAINER_BOTTOM_WIDGETS_TRAY);
parent.addView(widget);
return widget;
}
private void animateOpen() {
if (mIsOpen || mOpenCloseAnimation.getAnimationPlayer().isRunning()) {
return;
}
mIsOpen = true;
setupNavBarColor();
setUpDefaultOpenAnimation().start();
}
@Override
protected void handleClose(boolean animate) {
handleClose(animate, DEFAULT_CLOSE_DURATION);
}
@Override
protected boolean isOfType(@FloatingViewType int type) {
return (type & TYPE_WIDGETS_BOTTOM_SHEET) != 0;
}
@Override
public void setInsets(Rect insets) {
super.setInsets(insets);
int bottomPadding = Math.max(insets.bottom, mNavBarScrimHeight);
View widgetsTable = findViewById(R.id.widgets_table);
widgetsTable.setPadding(
widgetsTable.getPaddingLeft(),
widgetsTable.getPaddingTop(),
widgetsTable.getPaddingRight(),
bottomPadding);
if (bottomPadding > 0) {
setupNavBarColor();
} else {
clearNavBarColor();
}
}
@Override
protected void onContentHorizontalMarginChanged(int contentHorizontalMarginInPx) {
ViewGroup.MarginLayoutParams layoutParams =
((ViewGroup.MarginLayoutParams) findViewById(R.id.widgets_table).getLayoutParams());
layoutParams.setMarginStart(contentHorizontalMarginInPx);
layoutParams.setMarginEnd(contentHorizontalMarginInPx);
}
@Override
protected Pair<View, String> getAccessibilityTarget() {
return Pair.create(findViewById(R.id.title), getContext().getString(
mIsOpen ? R.string.widgets_list : R.string.widgets_list_closed));
}
@Override
public void addHintCloseAnim(
float distanceToMove, Interpolator interpolator, PendingAnimation target) {
target.addAnimatedFloat(mSwipeToDismissProgress, 0f, 1f, interpolator);
}
@Override
protected void scrollCellContainerByY(WidgetCell wc, int scrollByY) {
for (ViewParent parent = wc.getParent(); parent != null; parent = parent.getParent()) {
if (parent instanceof ScrollView scrollView) {
scrollView.smoothScrollBy(0, scrollByY);
return;
} else if (parent == this) {
return;
}
}
}
@Override
public void onRecommendedWidgetsBound() {} // no op
}