1 /* 2 * Copyright (C) 2024 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.launcher3.apppairs 18 19 import android.content.Context 20 import com.android.launcher3.BubbleTextView.DISPLAY_FOLDER 21 import com.android.launcher3.DeviceProfile 22 import com.android.launcher3.R 23 import com.android.launcher3.util.Themes 24 import com.android.launcher3.views.ActivityContext 25 26 class AppPairIconDrawingParams(val context: Context, container: Int) { 27 companion object { 28 // Design specs -- the below ratios are in relation to the size of a standard app icon. 29 // Note: The standard app icon has two sizes. One is the full size of the drawable (returned 30 // by dp.iconSizePx), and one is the visual size of the icon on-screen (11/12 of that). 31 // Hence the calculations below. 32 const val STANDARD_ICON_PADDING = 1 / 24f 33 const val STANDARD_ICON_SHRINK = 1 - STANDARD_ICON_PADDING * 2 34 // App pairs are slightly smaller than the *visual* size of a standard icon, so all ratios 35 // are calculated with that in mind. 36 const val OUTER_PADDING_SCALE = 1 / 30f * STANDARD_ICON_SHRINK 37 const val INNER_PADDING_SCALE = 1 / 24f * STANDARD_ICON_SHRINK 38 const val CENTER_CHANNEL_SCALE = 1 / 30f * STANDARD_ICON_SHRINK 39 const val BIG_RADIUS_SCALE = 1 / 5f * STANDARD_ICON_SHRINK 40 const val SMALL_RADIUS_SCALE = 1 / 15f * STANDARD_ICON_SHRINK 41 const val MEMBER_ICON_SCALE = 11 / 30f * STANDARD_ICON_SHRINK 42 } 43 44 // The size at which this graphic will be drawn. 45 val iconSize: Int 46 // Standard app icons are padded by this amount on each side. 47 val standardIconPadding: Float 48 // App pair icons are slightly smaller than regular icons, so we pad the icon by this much on 49 // each side. 50 val outerPadding: Float 51 // The colored background (two rectangles in a square area) is this big. 52 val backgroundSize: Float 53 // The size of the channel between the two halves of the app pair icon. 54 val centerChannelSize: Float 55 // The corner radius of the outside corners. 56 val bigRadius: Float 57 // The corner radius of the inside corners, touching the center channel. 58 val smallRadius: Float 59 // Inside of the icon, the two member apps are padded by this much. 60 val innerPadding: Float 61 // The two member apps have icons that are this big (in diameter). 62 val memberIconSize: Float 63 // The app pair icon appears differently in portrait and landscape. 64 var isLeftRightSplit: Boolean = true 65 // The background paint color (based on container). 66 var bgColor: Int = 0 67 68 init { 69 val activity: ActivityContext = ActivityContext.lookupContext(context) 70 val dp = activity.deviceProfile 71 iconSize = if (container == DISPLAY_FOLDER) dp.folderChildIconSizePx else dp.iconSizePx 72 standardIconPadding = iconSize * STANDARD_ICON_PADDING 73 outerPadding = iconSize * OUTER_PADDING_SCALE 74 backgroundSize = iconSize * STANDARD_ICON_SHRINK - (outerPadding * 2) 75 centerChannelSize = iconSize * CENTER_CHANNEL_SCALE 76 bigRadius = iconSize * BIG_RADIUS_SCALE 77 smallRadius = iconSize * SMALL_RADIUS_SCALE 78 innerPadding = iconSize * INNER_PADDING_SCALE 79 memberIconSize = iconSize * MEMBER_ICON_SCALE 80 updateOrientation(dp) 81 updateBgColor(container) 82 } 83 84 /** Checks the device orientation and updates isLeftRightSplit accordingly. */ updateOrientationnull85 fun updateOrientation(dp: DeviceProfile) { 86 isLeftRightSplit = dp.isLeftRightSplit 87 } 88 updateBgColornull89 fun updateBgColor(container: Int) { 90 if (container == DISPLAY_FOLDER) { 91 bgColor = Themes.getAttrColor(context, R.attr.appPairSurfaceInFolder) 92 } else { 93 val ta = context.theme.obtainStyledAttributes(R.styleable.FolderIconPreview) 94 bgColor = ta.getColor(R.styleable.FolderIconPreview_folderPreviewColor, 0) 95 ta.recycle() 96 } 97 } 98 } 99