mirror of
https://github.com/LawnchairLauncher/lawnchair.git
synced 2026-02-20 19:38:21 +00:00
Merge "Decrease icon size by steps" into udc-qpr-dev
This commit is contained in:
@@ -217,4 +217,28 @@
|
||||
<!-- Whether the floating rotation button should be on the left/right in the device's natural
|
||||
orientation -->
|
||||
<bool name="floating_rotation_button_position_left">true</bool>
|
||||
|
||||
<!-- Mapping of visual icon size to XML value http://b/235886078 -->
|
||||
<dimen name="iconSize48dp">52dp</dimen>
|
||||
<dimen name="iconSize50dp">55dp</dimen>
|
||||
<dimen name="iconSize52dp">57dp</dimen>
|
||||
<dimen name="iconSize54dp">59dp</dimen>
|
||||
<dimen name="iconSize56dp">61dp</dimen>
|
||||
<dimen name="iconSize58dp">63dp</dimen>
|
||||
<dimen name="iconSize60dp">66dp</dimen>
|
||||
<dimen name="iconSize66dp">72dp</dimen>
|
||||
<dimen name="iconSize72dp">79dp</dimen>
|
||||
|
||||
<!-- Icon size steps in dp -->
|
||||
<integer-array name="icon_size_steps">
|
||||
<item>@dimen/iconSize48dp</item>
|
||||
<item>@dimen/iconSize50dp</item>
|
||||
<item>@dimen/iconSize52dp</item>
|
||||
<item>@dimen/iconSize54dp</item>
|
||||
<item>@dimen/iconSize56dp</item>
|
||||
<item>@dimen/iconSize58dp</item>
|
||||
<item>@dimen/iconSize60dp</item>
|
||||
<item>@dimen/iconSize66dp</item>
|
||||
<item>@dimen/iconSize72dp</item>
|
||||
</integer-array>
|
||||
</resources>
|
||||
|
||||
@@ -58,6 +58,7 @@ import com.android.launcher3.responsive.CalculatedAllAppsSpec;
|
||||
import com.android.launcher3.uioverrides.ApiWrapper;
|
||||
import com.android.launcher3.util.DisplayController;
|
||||
import com.android.launcher3.util.DisplayController.Info;
|
||||
import com.android.launcher3.util.IconSizeSteps;
|
||||
import com.android.launcher3.util.ResourceHelper;
|
||||
import com.android.launcher3.util.WindowBounds;
|
||||
import com.android.launcher3.workspace.CalculatedWorkspaceSpec;
|
||||
@@ -83,6 +84,7 @@ public class DeviceProfile {
|
||||
public final InvariantDeviceProfile inv;
|
||||
private final Info mInfo;
|
||||
private final DisplayMetrics mMetrics;
|
||||
private final IconSizeSteps mIconSizeSteps;
|
||||
|
||||
// Device properties
|
||||
public final boolean isTablet;
|
||||
@@ -330,6 +332,8 @@ public class DeviceProfile {
|
||||
final Resources res = context.getResources();
|
||||
mMetrics = res.getDisplayMetrics();
|
||||
|
||||
mIconSizeSteps = mIsResponsiveGrid ? new IconSizeSteps(res) : null;
|
||||
|
||||
// Determine sizes.
|
||||
widthPx = windowBounds.bounds.width();
|
||||
heightPx = windowBounds.bounds.height();
|
||||
@@ -535,12 +539,16 @@ public class DeviceProfile {
|
||||
// for the available height to be correct
|
||||
if (mIsResponsiveGrid) {
|
||||
mWorkspaceSpecs = new WorkspaceSpecs(new ResourceHelper(context, inv.workspaceSpecsId));
|
||||
int availableResponsiveWidth =
|
||||
availableWidthPx - (isVerticalBarLayout() ? hotseatBarSizePx : 0);
|
||||
// don't use availableHeightPx because it subtracts bottom padding,
|
||||
// but the workspace go behind it
|
||||
int availableResponsiveHeight =
|
||||
heightPx - mInsets.top - (isVerticalBarLayout() ? 0 : hotseatBarSizePx);
|
||||
mResponsiveWidthSpec = mWorkspaceSpecs.getCalculatedWidthSpec(inv.numColumns,
|
||||
availableWidthPx);
|
||||
availableResponsiveWidth);
|
||||
mResponsiveHeightSpec = mWorkspaceSpecs.getCalculatedHeightSpec(inv.numRows,
|
||||
// don't use availableHeightPx because it subtracts bottom padding,
|
||||
// but the hotseat go behind it
|
||||
heightPx - mInsets.top - hotseatBarSizePx);
|
||||
availableResponsiveHeight);
|
||||
|
||||
mAllAppsSpecs = new AllAppsSpecs(new ResourceHelper(context, inv.allAppsSpecsId));
|
||||
mAllAppsResponsiveWidthSpec = mAllAppsSpecs.getCalculatedWidthSpec(inv.numColumns,
|
||||
@@ -926,9 +934,32 @@ public class DeviceProfile {
|
||||
|
||||
cellWidthPx = mResponsiveWidthSpec.getCellSizePx();
|
||||
cellHeightPx = mResponsiveHeightSpec.getCellSizePx();
|
||||
cellYPaddingPx = Math.max(0, cellHeightPx - cellContentHeight) / 2;
|
||||
|
||||
// TODO(b/283929701): decrease icon size if content doesn't fit on cell
|
||||
if (cellWidthPx < iconSizePx) {
|
||||
// get a smaller icon size
|
||||
iconSizePx = mIconSizeSteps.getIconSmallerThan(cellWidthPx);
|
||||
// calculate new cellContentHeight
|
||||
cellContentHeight = iconSizePx + cellTextAndPaddingHeight;
|
||||
}
|
||||
|
||||
while (iconSizePx > mIconSizeSteps.minimumIconSize()
|
||||
&& cellContentHeight > cellHeightPx) {
|
||||
int extraHeightRequired = cellContentHeight - cellHeightPx;
|
||||
int newPadding = iconDrawablePaddingPx - extraHeightRequired;
|
||||
if (newPadding >= 0) {
|
||||
// Responsive uses the padding without scaling
|
||||
iconDrawablePaddingPx = iconDrawablePaddingOriginalPx = newPadding;
|
||||
cellTextAndPaddingHeight =
|
||||
iconDrawablePaddingPx + Utilities.calculateTextHeight(iconTextSizePx);
|
||||
} else {
|
||||
// get a smaller icon size
|
||||
iconSizePx = mIconSizeSteps.getNextLowerIconSize(iconSizePx);
|
||||
}
|
||||
// calculate new cellContentHeight
|
||||
cellContentHeight = iconSizePx + cellTextAndPaddingHeight;
|
||||
}
|
||||
|
||||
cellYPaddingPx = Math.max(0, cellHeightPx - cellContentHeight) / 2;
|
||||
} else if (mIsScalableGrid) {
|
||||
cellWidthPx = pxFromDp(inv.minCellSize[mTypeIndex].x, mMetrics, scale);
|
||||
cellHeightPx = pxFromDp(inv.minCellSize[mTypeIndex].y, mMetrics, scale);
|
||||
|
||||
47
src/com/android/launcher3/util/IconSizeSteps.kt
Normal file
47
src/com/android/launcher3/util/IconSizeSteps.kt
Normal file
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* Copyright (C) 2023 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.util
|
||||
|
||||
import android.content.res.Resources
|
||||
import androidx.core.content.res.getDimensionOrThrow
|
||||
import androidx.core.content.res.use
|
||||
import com.android.launcher3.R
|
||||
import kotlin.math.max
|
||||
|
||||
class IconSizeSteps(res: Resources) {
|
||||
private val steps: List<Int>
|
||||
|
||||
init {
|
||||
steps =
|
||||
res.obtainTypedArray(R.array.icon_size_steps).use {
|
||||
(0 until it.length()).map { step -> it.getDimensionOrThrow(step).toInt() }.sorted()
|
||||
}
|
||||
}
|
||||
|
||||
fun minimumIconSize(): Int = steps[0]
|
||||
|
||||
fun getNextLowerIconSize(iconSizePx: Int): Int {
|
||||
return steps[max(0, getIndexForIconSize(iconSizePx) - 1)]
|
||||
}
|
||||
|
||||
fun getIconSmallerThan(cellWidth: Int): Int {
|
||||
return steps.lastOrNull { it <= cellWidth } ?: steps[0]
|
||||
}
|
||||
|
||||
private fun getIndexForIconSize(iconSizePx: Int): Int {
|
||||
return max(0, steps.indexOfFirst { iconSizePx <= it })
|
||||
}
|
||||
}
|
||||
67
tests/src/com/android/launcher3/util/IconSizeStepsTest.kt
Normal file
67
tests/src/com/android/launcher3/util/IconSizeStepsTest.kt
Normal file
@@ -0,0 +1,67 @@
|
||||
/*
|
||||
* Copyright (C) 2023 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.util
|
||||
|
||||
import android.content.Context
|
||||
import android.content.res.Configuration
|
||||
import androidx.test.core.app.ApplicationProvider
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||
import androidx.test.filters.SmallTest
|
||||
import com.google.common.truth.Truth.assertThat
|
||||
import org.junit.Assert.*
|
||||
import org.junit.Before
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
|
||||
@SmallTest
|
||||
@RunWith(AndroidJUnit4::class)
|
||||
class IconSizeStepsTest {
|
||||
private var context: Context? = null
|
||||
private val runningContext: Context = ApplicationProvider.getApplicationContext()
|
||||
private lateinit var iconSizeSteps: IconSizeSteps
|
||||
|
||||
@Before
|
||||
fun setup() {
|
||||
// 160dp makes 1px = 1dp
|
||||
val config =
|
||||
Configuration(runningContext.resources.configuration).apply { this.densityDpi = 160 }
|
||||
context = runningContext.createConfigurationContext(config)
|
||||
iconSizeSteps = IconSizeSteps(context!!.resources)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun minimumIconSize() {
|
||||
assertThat(iconSizeSteps.minimumIconSize()).isEqualTo(52)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun getNextLowerIconSize() {
|
||||
assertThat(iconSizeSteps.getNextLowerIconSize(66)).isEqualTo(63)
|
||||
|
||||
// Assert that never goes below minimum
|
||||
assertThat(iconSizeSteps.getNextLowerIconSize(52)).isEqualTo(52)
|
||||
assertThat(iconSizeSteps.getNextLowerIconSize(30)).isEqualTo(52)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun getIconSmallerThan() {
|
||||
assertThat(iconSizeSteps.getIconSmallerThan(60)).isEqualTo(59)
|
||||
|
||||
// Assert that never goes below minimum
|
||||
assertThat(iconSizeSteps.getIconSmallerThan(52)).isEqualTo(52)
|
||||
assertThat(iconSizeSteps.getIconSmallerThan(30)).isEqualTo(52)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user