diff --git a/res/values/dimens.xml b/res/values/dimens.xml index a9d1127184..2e886dbd9d 100644 --- a/res/values/dimens.xml +++ b/res/values/dimens.xml @@ -226,6 +226,7 @@ 16sp 2dp 4dp + 20dp 8dp 16dp 8dp diff --git a/src/com/android/launcher3/ButtonDropTarget.java b/src/com/android/launcher3/ButtonDropTarget.java index 3b24df2f18..5abe3d3af6 100644 --- a/src/com/android/launcher3/ButtonDropTarget.java +++ b/src/com/android/launcher3/ButtonDropTarget.java @@ -91,7 +91,7 @@ public abstract class ButtonDropTarget extends TextView Resources resources = getResources(); mDragDistanceThreshold = resources.getDimensionPixelSize(R.dimen.drag_distanceThreshold); - mDrawableSize = resources.getDimensionPixelSize(R.dimen.drop_target_text_size); + mDrawableSize = resources.getDimensionPixelSize(R.dimen.drop_target_button_drawable_size); mDrawablePadding = resources.getDimensionPixelSize( R.dimen.drop_target_button_drawable_padding); } @@ -374,11 +374,63 @@ public abstract class ButtonDropTarget extends TextView hideTooltip(); } + /** + * Returns if the text will be truncated within the provided availableWidth. + */ public boolean isTextTruncated(int availableWidth) { - availableWidth -= (getPaddingLeft() + getPaddingRight() + mDrawable.getIntrinsicWidth() - + getCompoundDrawablePadding()); - CharSequence displayedText = TextUtils.ellipsize(mText, getPaint(), availableWidth, + availableWidth -= getPaddingLeft() + getPaddingRight(); + if (mIconVisible) { + availableWidth -= mDrawable.getIntrinsicWidth() + getCompoundDrawablePadding(); + } + if (availableWidth <= 0) { + return true; + } + CharSequence firstLine = TextUtils.ellipsize(mText, getPaint(), availableWidth, TextUtils.TruncateAt.END); - return !mText.equals(displayedText); + if (!mTextMultiLine) { + return !TextUtils.equals(mText, firstLine); + } + if (TextUtils.equals(mText, firstLine)) { + // When multi-line is active, if it can display as one line, then text is not truncated. + return false; + } + CharSequence secondLine = + TextUtils.ellipsize(mText.subSequence(firstLine.length(), mText.length()), + getPaint(), availableWidth, TextUtils.TruncateAt.END); + return !(TextUtils.equals(mText.subSequence(0, firstLine.length()), firstLine) + && TextUtils.equals(mText.subSequence(firstLine.length(), secondLine.length()), + secondLine)); + } + + /** + * Reduce the size of the text until it fits the measured width or reaches a minimum. + * + * The minimum size is defined by {@code R.dimen.button_drop_target_min_text_size} and + * it diminishes by intervals defined by + * {@code R.dimen.button_drop_target_resize_text_increment} + * This functionality is very similar to the option + * {@link TextView#setAutoSizeTextTypeWithDefaults(int)} but can't be used in this view because + * the layout width is {@code WRAP_CONTENT}. + * + * @return The biggest text size in SP that makes the text fit or if the text can't fit returns + * the min available value + */ + public float resizeTextToFit() { + float minSize = Utilities.pxToSp(getResources() + .getDimensionPixelSize(R.dimen.button_drop_target_min_text_size)); + float step = Utilities.pxToSp(getResources() + .getDimensionPixelSize(R.dimen.button_drop_target_resize_text_increment)); + float textSize = Utilities.pxToSp(getTextSize()); + + int availableWidth = getMeasuredWidth(); + while (textSize > minSize) { + if (isTextTruncated(availableWidth)) { + textSize -= step; + setTextSize(textSize); + } else { + return textSize; + } + } + return minSize; } } diff --git a/src/com/android/launcher3/DeviceProfile.java b/src/com/android/launcher3/DeviceProfile.java index a330fb3c7e..1febd68a17 100644 --- a/src/com/android/launcher3/DeviceProfile.java +++ b/src/com/android/launcher3/DeviceProfile.java @@ -1037,7 +1037,7 @@ public class DeviceProfile { / getCellLayoutHeight(); scale = Math.min(scale, 1f); - // Reduce scale if next pages would not be visible after scaling the workspace + // Reduce scale if next pages would not be visible after scaling the workspace. int workspaceWidth = availableWidthPx; float scaledWorkspaceWidth = workspaceWidth * scale; float maxAvailableWidth = workspaceWidth - (2 * workspaceSpringLoadedMinNextPageVisiblePx); diff --git a/src/com/android/launcher3/DropTargetBar.java b/src/com/android/launcher3/DropTargetBar.java index d64cb26ff4..98ecf3a7e6 100644 --- a/src/com/android/launcher3/DropTargetBar.java +++ b/src/com/android/launcher3/DropTargetBar.java @@ -151,6 +151,8 @@ public class DropTargetBar extends FrameLayout int widthSpec = MeasureSpec.makeMeasureSpec(width, MeasureSpec.AT_MOST); ButtonDropTarget firstButton = mTempTargets[0]; + firstButton.setTextSize(TypedValue.COMPLEX_UNIT_PX, + mLauncher.getDeviceProfile().dropTargetTextSizePx); firstButton.setTextVisible(true); firstButton.setIconVisible(true); firstButton.measure(widthSpec, heightSpec); @@ -160,14 +162,16 @@ public class DropTargetBar extends FrameLayout int horizontalPadding = dp.dropTargetHorizontalPaddingPx; ButtonDropTarget firstButton = mTempTargets[0]; + firstButton.setTextSize(TypedValue.COMPLEX_UNIT_PX, dp.dropTargetTextSizePx); firstButton.setTextVisible(true); firstButton.setIconVisible(true); firstButton.setTextMultiLine(false); - // Reset second button padding in case it was previously changed to multi-line text. + // Reset first button padding in case it was previously changed to multi-line text. firstButton.setPadding(horizontalPadding, verticalPadding, horizontalPadding, verticalPadding); ButtonDropTarget secondButton = mTempTargets[1]; + secondButton.setTextSize(TypedValue.COMPLEX_UNIT_PX, dp.dropTargetTextSizePx); secondButton.setTextVisible(true); secondButton.setIconVisible(true); secondButton.setTextMultiLine(false); @@ -175,20 +179,14 @@ public class DropTargetBar extends FrameLayout secondButton.setPadding(horizontalPadding, verticalPadding, horizontalPadding, verticalPadding); - float scale = dp.getWorkspaceSpringLoadScale(mLauncher); - int scaledPanelWidth = (int) (dp.getCellLayoutWidth() * scale); - int availableWidth; if (dp.isTwoPanels) { - // Both buttons for two panel fit to the width of one Cell Layout (less - // half of the center gap between the buttons). - int halfButtonGap = dp.dropTargetGapPx / 2; - availableWidth = scaledPanelWidth - halfButtonGap / 2; + // Each button for two panel fits to half the width of the screen excluding the + // center gap between the buttons. + availableWidth = (dp.availableWidthPx - dp.dropTargetGapPx) / 2; } else { - // Both buttons plus the button gap do not display past the edge of the scaled - // workspace, less a pre-defined gap from the edge of the workspace. - availableWidth = scaledPanelWidth - dp.dropTargetGapPx - - 2 * dp.dropTargetButtonWorkspaceEdgeGapPx; + // Both buttons plus the button gap do not display past the edge of the screen. + availableWidth = dp.availableWidthPx - dp.dropTargetGapPx; } int widthSpec = MeasureSpec.makeMeasureSpec(availableWidth, MeasureSpec.AT_MOST); @@ -219,6 +217,15 @@ public class DropTargetBar extends FrameLayout horizontalPadding, verticalPadding / 2); } } + + // If text is still truncated, shrink to fit in measured width and resize both targets. + float minTextSize = + Math.min(firstButton.resizeTextToFit(), secondButton.resizeTextToFit()); + if (firstButton.getTextSize() != minTextSize + || secondButton.getTextSize() != minTextSize) { + firstButton.setTextSize(minTextSize); + secondButton.setTextSize(minTextSize); + } } setMeasuredDimension(width, height); }