Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a3c74d10 authored by Tony Wickham's avatar Tony Wickham
Browse files

Setting correct height for search bar widget options bundle.

- Seperate search bar height from its top and bottom paddings
- Report this height plus 8dps top and bottom for the widget options
- Use a separate bottom padding to adjust spacing between QSB and
  the workspace
- Add tests to verify the height of the search bar in both normal and
  tall modes (ran on Nexus 6, 7, and 10)
Change-Id: Ia7557785d1b38194eee869d0460456e8f33447d5
parent cbdb1538
Loading
Loading
Loading
Loading
+9 −5
Original line number Diff line number Diff line
@@ -19,11 +19,15 @@

<!-- Dynamic Grid -->
    <dimen name="dynamic_grid_edge_margin">6dp</dimen>
    <dimen name="dynamic_grid_search_bar_max_width">500dp</dimen>
    <dimen name="dynamic_grid_search_bar_height">56dp</dimen>
    <!-- We want 32dp extra for the tall search bar, but 10dp comes from unwanted padding between
         the search bar and workspace. -->
    <dimen name="dynamic_grid_search_bar_height_tall">78dp</dimen>
    <dimen name="dynamic_grid_search_bar_height">48dp</dimen>
    <!-- We want 32dp extra for the tall search bar. -->
    <dimen name="dynamic_grid_search_bar_height_tall">80dp</dimen>
    <dimen name="qsb_internal_padding_top">8dp</dimen>
    <dimen name="qsb_internal_padding_bottom">8dp</dimen>
    <dimen name="dynamic_grid_search_bar_bottom_padding">4dp</dimen>
    <!-- Reduce the padding between the search bar and workspace when the search bar is tall -->
    <dimen name="dynamic_grid_search_bar_bottom_padding_short">-6dp</dimen>
    <dimen name="dynamic_grid_search_bar_bottom_padding_tablet">16dp</dimen>
    <dimen name="dynamic_grid_page_indicator_height">20dp</dimen>
    <dimen name="dynamic_grid_icon_drawable_padding">4dp</dimen>
    <dimen name="dynamic_grid_workspace_page_spacing">8dp</dimen>
+66 −42
Original line number Diff line number Diff line
@@ -90,7 +90,7 @@ public class DeviceProfile {
    public int hotseatCellWidthPx;
    public int hotseatCellHeightPx;
    public int hotseatIconSizePx;
    private int hotseatBarHeightNormalPx, hotseatBarHeightShortPx;
    private int normalHotseatBarHeightPx, shortHotseatBarHeightPx;
    private int hotseatBarHeightPx; // One of the above.

    // All apps
@@ -101,8 +101,11 @@ public class DeviceProfile {
    public final int allAppsIconTextSizePx;

    // QSB
    private int searchBarSpaceWidthPx;
    private int searchBarSpaceHeightNormalPx, searchBarSpaceHeightTallPx;
    private int searchBarWidgetInternalPaddingTop, searchBarWidgetInternalPaddingBottom;
    private int searchBarTopPaddingPx;
    private int normalSearchBarBottomPaddingPx, tallSearchBarBottomPaddingPx;
    private int searchBarBottomPaddingPx; // One of the above.
    private int normalSearchBarSpaceHeightPx, tallSearchBarSpaceHeightPx;
    private int searchBarSpaceHeightPx; // One of the above.

    public DeviceProfile(Context context, InvariantDeviceProfile inv,
@@ -205,12 +208,26 @@ public class DeviceProfile {
        hotseatIconSizePx = (int) (Utilities.pxFromDp(inv.hotseatIconSize, dm) * scale);

        // Search Bar
        searchBarSpaceWidthPx = Math.min(widthPx,
                res.getDimensionPixelSize(R.dimen.dynamic_grid_search_bar_max_width));
        searchBarSpaceHeightNormalPx = getSearchBarTopOffset()
                + res.getDimensionPixelSize(R.dimen.dynamic_grid_search_bar_height);
        searchBarSpaceHeightTallPx = getSearchBarTopOffset()
                + res.getDimensionPixelSize(R.dimen.dynamic_grid_search_bar_height_tall);
        normalSearchBarSpaceHeightPx = res.getDimensionPixelSize(
                R.dimen.dynamic_grid_search_bar_height);
        tallSearchBarSpaceHeightPx = res.getDimensionPixelSize(
                R.dimen.dynamic_grid_search_bar_height_tall);
        searchBarWidgetInternalPaddingTop = res.getDimensionPixelSize(
                R.dimen.qsb_internal_padding_top);
        searchBarWidgetInternalPaddingBottom = res.getDimensionPixelSize(
                R.dimen.qsb_internal_padding_bottom);
        if (isTablet && !isVerticalBarLayout()) {
            searchBarTopPaddingPx = searchBarWidgetInternalPaddingTop;
            normalSearchBarBottomPaddingPx = searchBarWidgetInternalPaddingBottom +
                    res.getDimensionPixelSize(R.dimen.dynamic_grid_search_bar_bottom_padding_tablet);
            tallSearchBarBottomPaddingPx = normalSearchBarBottomPaddingPx;
        } else {
            searchBarTopPaddingPx = searchBarWidgetInternalPaddingTop;
            normalSearchBarBottomPaddingPx = searchBarWidgetInternalPaddingBottom +
                    res.getDimensionPixelSize(R.dimen.dynamic_grid_search_bar_bottom_padding);
            tallSearchBarBottomPaddingPx = searchBarWidgetInternalPaddingBottom +
                    res.getDimensionPixelSize(R.dimen.dynamic_grid_search_bar_bottom_padding_short);
        }

        // Calculate the actual text height
        Paint textPaint = new Paint();
@@ -222,8 +239,8 @@ public class DeviceProfile {
        dragViewScale = (iconSizePx + scaleDps) / iconSizePx;

        // Hotseat
        hotseatBarHeightNormalPx = iconSizePx + 4 * edgeMarginPx;
        hotseatBarHeightShortPx = iconSizePx + 2 * edgeMarginPx;
        normalHotseatBarHeightPx = iconSizePx + 4 * edgeMarginPx;
        shortHotseatBarHeightPx = iconSizePx + 2 * edgeMarginPx;
        hotseatCellWidthPx = iconSizePx;
        hotseatCellHeightPx = iconSizePx;

@@ -251,13 +268,20 @@ public class DeviceProfile {
        allAppsNumPredictiveCols = numPredictiveAppCols;
    }

    /** Returns the search bar top offset */
    private int getSearchBarTopOffset() {
        if (isTablet && !isVerticalBarLayout()) {
            return 4 * edgeMarginPx;
        } else {
            return 2 * edgeMarginPx;
    /** Returns the amount of extra space to allocate to the search bar for vertical padding. */
    private int getSearchBarTotalVerticalPadding() {
        return searchBarTopPaddingPx + searchBarBottomPaddingPx;
    }

    /** Returns the width and height of the search bar, ignoring any padding. */
    public Point getSearchBarDimensForWidgetOpts(Resources res) {
        Rect searchBarBounds = getSearchBarBounds(Utilities.isRtl(res));
        if (isVerticalBarLayout()) {
            return new Point(searchBarBounds.width(), searchBarBounds.height());
        }
        int widgetInternalPadding = searchBarWidgetInternalPaddingTop +
                searchBarWidgetInternalPaddingBottom;
        return new Point(searchBarBounds.width(), searchBarSpaceHeightPx + widgetInternalPadding);
    }

    /** Returns the search bar bounds in the current orientation */
@@ -265,13 +289,14 @@ public class DeviceProfile {
        Rect bounds = new Rect();
        if (isVerticalBarLayout()) {
            if (isLayoutRtl) {
                bounds.set(availableWidthPx - searchBarSpaceHeightNormalPx, edgeMarginPx,
                bounds.set(availableWidthPx - normalSearchBarSpaceHeightPx, edgeMarginPx,
                        availableWidthPx, availableHeightPx - edgeMarginPx);
            } else {
                bounds.set(0, edgeMarginPx, searchBarSpaceHeightNormalPx,
                bounds.set(0, edgeMarginPx, normalSearchBarSpaceHeightPx,
                        availableHeightPx - edgeMarginPx);
            }
        } else {
            int boundsBottom = searchBarSpaceHeightPx + getSearchBarTotalVerticalPadding();
            if (isTablet) {
                // Pad the left and right of the workspace to ensure consistent spacing
                // between all icons
@@ -280,14 +305,13 @@ public class DeviceProfile {
                //      that into account here too.
                int gap = (int) ((width - 2 * edgeMarginPx -
                        (inv.numColumns * cellWidthPx)) / (2 * (inv.numColumns + 1)));
                bounds.set(edgeMarginPx + gap, getSearchBarTopOffset(),
                        availableWidthPx - (edgeMarginPx + gap),
                        searchBarSpaceHeightPx);
                bounds.set(edgeMarginPx + gap, 0,
                        availableWidthPx - (edgeMarginPx + gap), boundsBottom);
            } else {
                bounds.set(desiredWorkspaceLeftRightMarginPx - defaultWidgetPadding.left,
                        getSearchBarTopOffset(),
                        0,
                        availableWidthPx - (desiredWorkspaceLeftRightMarginPx -
                        defaultWidgetPadding.right), searchBarSpaceHeightPx);
                        defaultWidgetPadding.right), boundsBottom);
            }
        }
        return bounds;
@@ -300,21 +324,21 @@ public class DeviceProfile {
        if (isVerticalBarLayout()) {
            // Pad the left and right of the workspace with search/hotseat bar sizes
            if (isLayoutRtl) {
                padding.set(hotseatBarHeightNormalPx, edgeMarginPx,
                padding.set(normalHotseatBarHeightPx, edgeMarginPx,
                        searchBarBounds.width(), edgeMarginPx);
            } else {
                padding.set(searchBarBounds.width(), edgeMarginPx,
                        hotseatBarHeightNormalPx, edgeMarginPx);
                        normalHotseatBarHeightPx, edgeMarginPx);
            }
        } else {
            int paddingTop = searchBarBounds.bottom;
            int paddingBottom = hotseatBarHeightPx + pageIndicatorHeightPx;
            if (isTablet) {
                // Pad the left and right of the workspace to ensure consistent spacing
                // between all icons
                float gapScale = 1f + (dragViewScale - 1f) / 2f;
                int width = getCurrentWidth();
                int height = getCurrentHeight();
                int paddingTop = searchBarBounds.bottom;
                int paddingBottom = hotseatBarHeightPx + pageIndicatorHeightPx;
                // The amount of screen space available for left/right padding.
                int availablePaddingX = Math.max(0, width - (int) ((inv.numColumns * cellWidthPx) +
                        ((inv.numColumns - 1) * gapScale * cellWidthPx)));
@@ -327,9 +351,9 @@ public class DeviceProfile {
            } else {
                // Pad the top and bottom of the workspace with search/hotseat bar sizes
                padding.set(desiredWorkspaceLeftRightMarginPx - defaultWidgetPadding.left,
                        searchBarBounds.bottom,
                        paddingTop,
                        desiredWorkspaceLeftRightMarginPx - defaultWidgetPadding.right,
                        hotseatBarHeightPx + pageIndicatorHeightPx);
                        paddingBottom);
            }
        }
        return padding;
@@ -357,7 +381,7 @@ public class DeviceProfile {
    // The rect returned will be extended to below the system ui that covers the workspace
    Rect getHotseatRect() {
        if (isVerticalBarLayout()) {
            return new Rect(availableWidthPx - hotseatBarHeightNormalPx, 0,
            return new Rect(availableWidthPx - normalHotseatBarHeightPx, 0,
                    Integer.MAX_VALUE, availableHeightPx);
        } else {
            return new Rect(0, availableHeightPx - hotseatBarHeightPx,
@@ -398,11 +422,13 @@ public class DeviceProfile {
    // TODO(twickham): b/25154513
    public void setSearchBarHeight(int searchBarHeight) {
        if (searchBarHeight == LauncherCallbacks.SEARCH_BAR_HEIGHT_TALL) {
            hotseatBarHeightPx = hotseatBarHeightShortPx;
            searchBarSpaceHeightPx = searchBarSpaceHeightTallPx;
            hotseatBarHeightPx = shortHotseatBarHeightPx;
            searchBarSpaceHeightPx = tallSearchBarSpaceHeightPx;
            searchBarBottomPaddingPx = tallSearchBarBottomPaddingPx;
        } else {
            hotseatBarHeightPx = hotseatBarHeightNormalPx;
            searchBarSpaceHeightPx = searchBarSpaceHeightNormalPx;
            hotseatBarHeightPx = normalHotseatBarHeightPx;
            searchBarSpaceHeightPx = normalSearchBarSpaceHeightPx;
            searchBarBottomPaddingPx = normalSearchBarBottomPaddingPx;
        }
    }

@@ -412,13 +438,15 @@ public class DeviceProfile {
        final boolean isLayoutRtl = Utilities.isRtl(launcher.getResources());

        // Layout the search bar space
        Rect searchBarBounds = getSearchBarBounds(isLayoutRtl);
        View searchBar = launcher.getSearchDropTargetBar();
        lp = (FrameLayout.LayoutParams) searchBar.getLayoutParams();
        lp.width = searchBarBounds.width();
        lp.height = searchBarBounds.height();
        if (hasVerticalBarLayout) {
            // Vertical search bar space -- The search bar is fixed in the layout to be on the left
            //                              of the screen regardless of RTL
            lp.gravity = Gravity.LEFT;
            lp.width = searchBarSpaceHeightNormalPx;

            LinearLayout targets = (LinearLayout) searchBar.findViewById(R.id.drag_target_bar);
            targets.setOrientation(LinearLayout.VERTICAL);
@@ -428,11 +456,7 @@ public class DeviceProfile {

        } else {
            // Horizontal search bar space
            lp.gravity = Gravity.TOP;
            lp.height = searchBarSpaceHeightPx;

            LinearLayout targets = (LinearLayout) searchBar.findViewById(R.id.drag_target_bar);
            targets.getLayoutParams().width = searchBarSpaceWidthPx;
            lp.gravity = Gravity.TOP|Gravity.CENTER_HORIZONTAL;
        }
        searchBar.setLayoutParams(lp);

@@ -459,7 +483,7 @@ public class DeviceProfile {
            // Vertical hotseat -- The hotseat is fixed in the layout to be on the right of the
            //                     screen regardless of RTL
            lp.gravity = Gravity.RIGHT;
            lp.width = hotseatBarHeightNormalPx;
            lp.width = normalHotseatBarHeightPx;
            lp.height = LayoutParams.MATCH_PARENT;
            hotseat.findViewById(R.id.layout).setPadding(0, 2 * edgeMarginPx, 0, 2 * edgeMarginPx);
        } else if (isTablet) {
+9 −8
Original line number Diff line number Diff line
@@ -52,6 +52,7 @@ import android.database.sqlite.SQLiteDatabase;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Point;
import android.graphics.PorterDuff;
import android.graphics.Rect;
import android.graphics.drawable.ColorDrawable;
@@ -3629,17 +3630,17 @@ public class Launcher extends Activity
            DeviceProfile portraitProfile = app.getInvariantDeviceProfile().portraitProfile;
            DeviceProfile landscapeProfile = app.getInvariantDeviceProfile().landscapeProfile;
            float density = getResources().getDisplayMetrics().density;
            Rect searchBounds = portraitProfile.getSearchBarBounds(Utilities.isRtl(getResources()));
            int maxHeight = (int) (searchBounds.height() / density);
            Point searchDimens = portraitProfile.getSearchBarDimensForWidgetOpts(getResources());
            int maxHeight = (int) (searchDimens.y / density);
            int minHeight = maxHeight;
            int maxWidth = (int) (searchBounds.width() / density);
            int maxWidth = (int) (searchDimens.x / density);
            int minWidth = maxWidth;
            if (!landscapeProfile.isVerticalBarLayout()) {
                searchBounds = landscapeProfile.getSearchBarBounds(Utilities.isRtl(getResources()));
                maxHeight = (int) Math.max(maxHeight, searchBounds.height() / density);
                minHeight = (int) Math.min(minHeight, searchBounds.height() / density);
                maxWidth = (int) Math.max(maxWidth, searchBounds.width() / density);
                minWidth = (int) Math.min(minWidth, searchBounds.width() / density);
                searchDimens = landscapeProfile.getSearchBarDimensForWidgetOpts(getResources());
                maxHeight = (int) Math.max(maxHeight, searchDimens.y / density);
                minHeight = (int) Math.min(minHeight, searchDimens.y / density);
                maxWidth = (int) Math.max(maxWidth, searchDimens.x / density);
                minWidth = (int) Math.min(minWidth, searchDimens.x / density);
            }
            opts.putInt(AppWidgetManager.OPTION_APPWIDGET_MAX_HEIGHT, maxHeight);
            opts.putInt(AppWidgetManager.OPTION_APPWIDGET_MIN_HEIGHT, minHeight);
+71 −4
Original line number Diff line number Diff line
@@ -15,15 +15,14 @@
 */
package com.android.launcher3;

import android.content.res.Resources;
import android.graphics.Point;
import android.graphics.PointF;
import android.graphics.Rect;
import android.test.AndroidTestCase;
import android.test.suitebuilder.annotation.SmallTest;
import android.util.Log;

import com.android.launcher3.DeviceProfile;
import com.android.launcher3.InvariantDeviceProfile;
import com.android.launcher3.util.FocusLogic;

import java.util.ArrayList;

/**
@@ -123,4 +122,72 @@ public class InvariantDeviceProfileTest extends AndroidTestCase {
    // Add more tests for other devices, however, running them once on a single device is enough
    // for verifying that for a platform version, the WindowManager and DisplayMetrics is
    // working as intended.

    /**
     * Make sure that the height for the QSB is what we expect in normal mode.
     */
    public void testQsbNormalHeight() {
        Resources resources = getContext().getResources();
        DeviceProfile landscapeProfile = mInvariantProfile.landscapeProfile;
        DeviceProfile portraitProfile = mInvariantProfile.portraitProfile;
        landscapeProfile.setSearchBarHeight(LauncherCallbacks.SEARCH_BAR_HEIGHT_NORMAL);
        portraitProfile.setSearchBarHeight(LauncherCallbacks.SEARCH_BAR_HEIGHT_NORMAL);
        Rect portraitBounds = portraitProfile.getSearchBarBounds(true); // RTL shouldn't matter.
        int portraitHeight = (int) Utilities.dpiFromPx(portraitBounds.height(),
                resources.getDisplayMetrics());
        Rect landscapeBounds = landscapeProfile.getSearchBarBounds(true); // RTL shouldn't matter.
        int landscapeHeight = (int) Utilities.dpiFromPx(landscapeBounds.height(),
                resources.getDisplayMetrics());
        if (portraitProfile.isTablet) {
            assertEquals(8 + 48 + 24, portraitHeight);
        } else {
            assertEquals(8 + 48 + 12, portraitHeight);
        }
        // Make sure the height that we pass in the widget options bundle is the height of the
        // search bar + 8dps padding top and bottom.
        Point portraitDimens = portraitProfile.getSearchBarDimensForWidgetOpts(resources);
        int portraitWidgetOptsHeight = portraitDimens.y;
        Point landscapeDimens = landscapeProfile.getSearchBarDimensForWidgetOpts(resources);
        int landscapeWidgetOptsHeight = landscapeDimens.y;
        assertEquals(8 + 48 + 8, (int) Utilities.dpiFromPx(portraitWidgetOptsHeight,
                resources.getDisplayMetrics()));
        if (!landscapeProfile.isVerticalBarLayout()) {
            assertEquals(portraitHeight, landscapeHeight);
            assertEquals(portraitWidgetOptsHeight, landscapeWidgetOptsHeight);
        }
    }

    /**
     * Make sure that the height for the QSB is what we expect in tall mode.
     */
    public void testQsbTallHeight() {
        Resources resources = getContext().getResources();
        DeviceProfile landscapeProfile = mInvariantProfile.landscapeProfile;
        DeviceProfile portraitProfile = mInvariantProfile.portraitProfile;
        landscapeProfile.setSearchBarHeight(LauncherCallbacks.SEARCH_BAR_HEIGHT_TALL);
        portraitProfile.setSearchBarHeight(LauncherCallbacks.SEARCH_BAR_HEIGHT_TALL);
        Rect portraitBounds = portraitProfile.getSearchBarBounds(true); // RTL shouldn't matter.
        int portraitHeight = (int) Utilities.dpiFromPx(portraitBounds.height(),
                resources.getDisplayMetrics());
        Rect landscapeBounds = landscapeProfile.getSearchBarBounds(true); // RTL shouldn't matter.
        int landscapeHeight = (int) Utilities.dpiFromPx(landscapeBounds.height(),
                resources.getDisplayMetrics());
        if (portraitProfile.isTablet) {
            assertEquals(8 + 80 + 24, portraitHeight);
        } else {
            assertEquals(8 + 80 + 2, portraitHeight);
        }
        // Make sure the height that we pass in the widget options bundle is the height of the
        // search bar + 8dps padding top and bottom.
        Point portraitDimens = portraitProfile.getSearchBarDimensForWidgetOpts(resources);
        int portraitWidgetOptsHeight = portraitDimens.y;
        Point landscapeDimens = landscapeProfile.getSearchBarDimensForWidgetOpts(resources);
        int landscapeWidgetOptsHeight = landscapeDimens.y;
        assertEquals(8 + 80 + 8, (int) Utilities.dpiFromPx(portraitWidgetOptsHeight,
                resources.getDisplayMetrics()));
        if (!landscapeProfile.isVerticalBarLayout()) {
            assertEquals(portraitHeight, landscapeHeight);
            assertEquals(portraitWidgetOptsHeight, landscapeWidgetOptsHeight);
        }
    }
}