1 /* 2 * Copyright (C) 2021 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 package com.android.launcher3.views; 17 18 import android.content.Context; 19 import android.graphics.Rect; 20 import android.util.AttributeSet; 21 import android.view.LayoutInflater; 22 23 import com.android.launcher3.DeviceProfile; 24 import com.android.launcher3.Insettable; 25 import com.android.launcher3.Launcher; 26 import com.android.launcher3.R; 27 28 /** 29 * Education view about widgets. 30 */ 31 public class WidgetsEduView extends AbstractSlideInView<Launcher> implements Insettable { 32 33 private static final int DEFAULT_CLOSE_DURATION = 200; 34 35 private Rect mInsets = new Rect(); 36 WidgetsEduView(Context context, AttributeSet attr)37 public WidgetsEduView(Context context, AttributeSet attr) { 38 this(context, attr, 0); 39 } 40 WidgetsEduView(Context context, AttributeSet attrs, int defStyleAttr)41 public WidgetsEduView(Context context, AttributeSet attrs, 42 int defStyleAttr) { 43 super(context, attrs, defStyleAttr); 44 } 45 46 @Override handleClose(boolean animate)47 protected void handleClose(boolean animate) { 48 handleClose(true, DEFAULT_CLOSE_DURATION); 49 } 50 51 @Override isOfType(int type)52 protected boolean isOfType(int type) { 53 return (type & TYPE_WIDGETS_EDUCATION_DIALOG) != 0; 54 } 55 56 @Override onFinishInflate()57 protected void onFinishInflate() { 58 super.onFinishInflate(); 59 mContent = findViewById(R.id.edu_view); 60 findViewById(R.id.edu_close_button) 61 .setOnClickListener(v -> close(/* animate= */ true)); 62 } 63 64 @Override setInsets(Rect insets)65 public void setInsets(Rect insets) { 66 mInsets.set(insets); 67 mContent.setPadding(mContent.getPaddingStart(), 68 mContent.getPaddingTop(), mContent.getPaddingEnd(), insets.bottom); 69 } 70 show()71 private void show() { 72 attachToContainer(); 73 animateOpen(); 74 } 75 76 @Override getScrimColor(Context context)77 protected int getScrimColor(Context context) { 78 return context.getResources().getColor(R.color.widgets_picker_scrim); 79 } 80 81 @Override onLayout(boolean changed, int l, int t, int r, int b)82 protected void onLayout(boolean changed, int l, int t, int r, int b) { 83 int width = r - l; 84 int height = b - t; 85 86 // Lay out the content as center bottom aligned. 87 int contentWidth = mContent.getMeasuredWidth(); 88 int contentLeft = (width - contentWidth - mInsets.left - mInsets.right) / 2 + mInsets.left; 89 mContent.layout(contentLeft, height - mContent.getMeasuredHeight(), 90 contentLeft + contentWidth, height); 91 92 setTranslationShift(mTranslationShift); 93 } 94 95 @Override onMeasure(int widthMeasureSpec, int heightMeasureSpec)96 protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 97 DeviceProfile deviceProfile = mActivityContext.getDeviceProfile(); 98 int widthUsed; 99 if (mInsets.bottom > 0) { 100 // Extra space between this view and mContent horizontally when the sheet is shown in 101 // portrait mode. 102 widthUsed = mInsets.left + mInsets.right; 103 } else { 104 // Extra space between this view and mContent horizontally when the sheet is shown in 105 // landscape mode. 106 Rect padding = deviceProfile.workspacePadding; 107 widthUsed = Math.max(padding.left + padding.right, 108 2 * (mInsets.left + mInsets.right)); 109 } 110 111 int heightUsed = mInsets.top + deviceProfile.edgeMarginPx; 112 measureChildWithMargins(mContent, widthMeasureSpec, 113 widthUsed, heightMeasureSpec, heightUsed); 114 setMeasuredDimension(MeasureSpec.getSize(widthMeasureSpec), 115 MeasureSpec.getSize(heightMeasureSpec)); 116 } 117 animateOpen()118 private void animateOpen() { 119 if (mIsOpen || mOpenCloseAnimation.getAnimationPlayer().isRunning()) { 120 return; 121 } 122 mIsOpen = true; 123 setUpDefaultOpenAnimation().start(); 124 } 125 126 /** Shows widget education dialog. */ showEducationDialog(Launcher launcher)127 public static WidgetsEduView showEducationDialog(Launcher launcher) { 128 LayoutInflater layoutInflater = LayoutInflater.from(launcher); 129 WidgetsEduView v = (WidgetsEduView) layoutInflater.inflate( 130 R.layout.widgets_edu, launcher.getDragLayer(), false); 131 v.show(); 132 return v; 133 } 134 } 135