1 /* 2 * Copyright 2023 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 androidx.glance.template 18 19 import android.content.Context 20 import androidx.compose.runtime.Composable 21 import androidx.compose.runtime.CompositionLocalProvider 22 import androidx.compose.ui.unit.Dp 23 import androidx.compose.ui.unit.DpSize 24 import androidx.compose.ui.unit.dp 25 import androidx.glance.GlanceComposable 26 import androidx.glance.GlanceId 27 import androidx.glance.LocalSize 28 import androidx.glance.appwidget.GlanceAppWidget 29 import androidx.glance.appwidget.SizeMode 30 import androidx.glance.appwidget.provideContent 31 import androidx.glance.state.GlanceStateDefinition 32 import androidx.glance.state.PreferencesGlanceStateDefinition 33 34 /** A [GlanceAppWidget] that provides template local values. */ 35 abstract class GlanceTemplateAppWidget : GlanceAppWidget() { 36 37 companion object { 38 internal val sizeMin = 30.dp 39 internal val sizeS = 200.dp 40 internal val sizeM = 241.dp 41 internal val sizeL = 350.dp 42 internal val sizeXL = 600.dp 43 private val COLLAPSED = DpSize(sizeMin, sizeMin) 44 private val HORIZONTAL_S = DpSize(sizeM, sizeMin) 45 private val HORIZONTAL_M = DpSize(sizeM, sizeS) 46 private val HORIZONTAL_L = DpSize(sizeL, sizeMin) 47 private val HORIZONTAL_XL = DpSize(sizeXL, sizeL) 48 private val VERTICAL_S = DpSize(sizeMin, sizeM) 49 private val VERTICAL_M = DpSize(sizeS, sizeM) 50 private val VERTICAL_L = DpSize(sizeS, sizeL) 51 } 52 53 /** Default widget size mode is [SizeMode.Responsive] */ 54 override val sizeMode: SizeMode = 55 SizeMode.Responsive( 56 setOf( 57 COLLAPSED, 58 VERTICAL_S, 59 VERTICAL_M, 60 VERTICAL_L, 61 HORIZONTAL_S, 62 HORIZONTAL_M, 63 HORIZONTAL_L, 64 HORIZONTAL_XL 65 ) 66 ) 67 68 /** Default widget state definition is [PreferencesGlanceStateDefinition] */ 69 override val stateDefinition: GlanceStateDefinition<*>? = PreferencesGlanceStateDefinition 70 <lambda>null71 final override suspend fun provideGlance(context: Context, id: GlanceId) = provideContent { 72 CompositionLocalProvider( 73 LocalTemplateMode provides mode(), 74 ) { 75 TemplateContent() 76 } 77 } 78 TemplateContentnull79 @Composable @GlanceComposable abstract fun TemplateContent() 80 81 /** Resolves the current display mode */ 82 @Composable 83 private fun mode(): TemplateMode { 84 val height = LocalSize.current.height 85 val width = LocalSize.current.width 86 return if (height <= Dp(240f) && width <= Dp(240f)) { 87 TemplateMode.Collapsed 88 } else if ((width / height) < (3.0 / 2.0)) { 89 TemplateMode.Vertical 90 } else { 91 TemplateMode.Horizontal 92 } 93 } 94 } 95