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

Commit 0530e8c6 authored by Tony Wickham's avatar Tony Wickham Committed by Tony
Browse files

Support notifications with 0 count (show as dots)

- Show number if number > 0
- Show icon if number == 0 and a notification specified an icon to show
- Show a dot otherwise
- In cases of multiple notifications, stack a second badge behind the
  first (visuals will be updated in future CL, as well as support
  stacked dots)
- Folders always show dot if any app within has a badge.

Change-Id: I0a89059b0e0a0d174fe739c9da4f75fa18c0edfa
parent b85f5dfc
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -473,7 +473,7 @@ public class BubbleTextView extends TextView implements ItemInfoUpdateReceiver {
    }

    private boolean hasBadge() {
        return (mBadgeInfo != null && mBadgeInfo.getNotificationCount() > 0);
        return mBadgeInfo != null;
    }

    public void getIconBounds(Rect outBounds) {
+37 −9
Original line number Diff line number Diff line
@@ -44,12 +44,17 @@ public class BadgeRenderer {
    private static final float CHAR_SIZE_PERCENTAGE = 0.12f;
    private static final float TEXT_SIZE_PERCENTAGE = 0.26f;
    private static final float OFFSET_PERCENTAGE = 0.02f;
    private static final float STACK_OFFSET_PERCENTAGE_X = 0.05f;
    private static final float STACK_OFFSET_PERCENTAGE_Y = 0.06f;
    private static final float DOT_SCALE = 0.6f;

    private final Context mContext;
    private final int mSize;
    private final int mCharSize;
    private final int mTextHeight;
    private final int mOffset;
    private final int mStackOffsetX;
    private final int mStackOffsetY;
    private final IconDrawer mLargeIconDrawer;
    private final IconDrawer mSmallIconDrawer;
    private final Paint mTextPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
@@ -63,6 +68,8 @@ public class BadgeRenderer {
        mSize = (int) (SIZE_PERCENTAGE * iconSizePx);
        mCharSize = (int) (CHAR_SIZE_PERCENTAGE * iconSizePx);
        mOffset = (int) (OFFSET_PERCENTAGE * iconSizePx);
        mStackOffsetX = (int) (STACK_OFFSET_PERCENTAGE_X * iconSizePx);
        mStackOffsetY = (int) (STACK_OFFSET_PERCENTAGE_Y * iconSizePx);
        mTextPaint.setTextSize(iconSizePx * TEXT_SIZE_PERCENTAGE);
        mTextPaint.setTextAlign(Paint.Align.CENTER);
        mLargeIconDrawer = new IconDrawer(res.getDimensionPixelSize(R.dimen.badge_small_padding));
@@ -91,7 +98,7 @@ public class BadgeRenderer {
                ? mLargeIconDrawer : mSmallIconDrawer;
        Shader icon = badgeInfo == null ? null : badgeInfo.getNotificationIconForBadge(
                mContext, palette.backgroundColor, mSize, iconDrawer.mPadding);
        String notificationCount = icon != null || badgeInfo == null ? "0"
        String notificationCount = badgeInfo == null ? "0"
                : String.valueOf(badgeInfo.getNotificationCount());
        int numChars = notificationCount.length();
        int width = mSize + mCharSize * (numChars - 1);
@@ -105,21 +112,42 @@ public class BadgeRenderer {
        // We draw the badge relative to its center.
        int badgeCenterX = iconBounds.right - width / 2;
        int badgeCenterY = iconBounds.top + mSize / 2;
        boolean isText = badgeInfo != null && badgeInfo.getNotificationCount() != 0;
        boolean isIcon = icon != null;
        boolean isDot = !(isText || isIcon);
        if (isDot) {
            badgeScale *= DOT_SCALE;
        }
        int offsetX = Math.min(mOffset, spaceForOffset.x);
        int offsetY = Math.min(mOffset, spaceForOffset.y);
        canvas.translate(badgeCenterX + offsetX, badgeCenterY - offsetY);
        canvas.scale(badgeScale, badgeScale);
        // Draw the background and shadow.
        // Prepare the background and shadow and possible stacking effect.
        mBackgroundPaint.setColorFilter(palette.backgroundColorMatrixFilter);
        int backgroundWithShadowSize = backgroundWithShadow.getHeight(); // Same as width.
        boolean shouldStack = !isDot && badgeInfo != null
                && badgeInfo.getNotificationKeys().size() > 1;
        if (shouldStack) {
            int offsetDiffX = mStackOffsetX - mOffset;
            int offsetDiffY = mStackOffsetY - mOffset;
            canvas.translate(offsetDiffX, offsetDiffY);
            canvas.drawBitmap(backgroundWithShadow, -backgroundWithShadowSize / 2,
                    -backgroundWithShadowSize / 2, mBackgroundPaint);
            canvas.translate(-offsetDiffX, -offsetDiffY);
        }

        if (isText) {
            canvas.drawBitmap(backgroundWithShadow, -backgroundWithShadowSize / 2,
                    -backgroundWithShadowSize / 2, mBackgroundPaint);
        if (icon != null) {
            // Draw the notification icon with padding.
            iconDrawer.drawIcon(icon, canvas);
        } else {
            // Draw the notification count.
            canvas.drawText(notificationCount, 0, mTextHeight / 2, mTextPaint);
        } else if (isIcon) {
            canvas.drawBitmap(backgroundWithShadow, -backgroundWithShadowSize / 2,
                    -backgroundWithShadowSize / 2, mBackgroundPaint);
            iconDrawer.drawIcon(icon, canvas);
        } else if (isDot) {
            mBackgroundPaint.setColorFilter(palette.saturatedBackgroundColorMatrixFilter);
            canvas.drawBitmap(backgroundWithShadow, -backgroundWithShadowSize / 2,
                    -backgroundWithShadowSize / 2, mBackgroundPaint);
        }
        canvas.restore();
    }
+15 −10
Original line number Diff line number Diff line
@@ -19,14 +19,14 @@ package com.android.launcher3.badge;
import com.android.launcher3.Utilities;

/**
 * Subclass of BadgeInfo that only contains the badge count,
 * which is the sum of all the Folder's items' counts.
 * Subclass of BadgeInfo that only contains the badge count, which is
 * the sum of all the Folder's items' notifications (each counts as 1).
 */
public class FolderBadgeInfo extends BadgeInfo {

    private static final int MIN_COUNT = 0;

    private int mTotalNotificationCount;
    private int mNumNotifications;

    public FolderBadgeInfo() {
        super(null);
@@ -36,22 +36,27 @@ public class FolderBadgeInfo extends BadgeInfo {
        if (badgeToAdd == null) {
            return;
        }
        mTotalNotificationCount += badgeToAdd.getNotificationCount();
        mTotalNotificationCount = Utilities.boundToRange(
                mTotalNotificationCount, MIN_COUNT, BadgeInfo.MAX_COUNT);
        mNumNotifications += badgeToAdd.getNotificationKeys().size();
        mNumNotifications = Utilities.boundToRange(
                mNumNotifications, MIN_COUNT, BadgeInfo.MAX_COUNT);
    }

    public void subtractBadgeInfo(BadgeInfo badgeToSubtract) {
        if (badgeToSubtract == null) {
            return;
        }
        mTotalNotificationCount -= badgeToSubtract.getNotificationCount();
        mTotalNotificationCount = Utilities.boundToRange(
                mTotalNotificationCount, MIN_COUNT, BadgeInfo.MAX_COUNT);
        mNumNotifications -= badgeToSubtract.getNotificationKeys().size();
        mNumNotifications = Utilities.boundToRange(
                mNumNotifications, MIN_COUNT, BadgeInfo.MAX_COUNT);
    }

    @Override
    public int getNotificationCount() {
        return mTotalNotificationCount;
        // This forces the folder badge to always show up as a dot.
        return 0;
    }

    public boolean hasBadge() {
        return mNumNotifications > 0;
    }
}
+10 −12
Original line number Diff line number Diff line
@@ -403,17 +403,15 @@ public class FolderIcon extends FrameLayout implements FolderListener {
    }

    public void setBadgeInfo(FolderBadgeInfo badgeInfo) {
        updateBadgeScale(mBadgeInfo.getNotificationCount(), badgeInfo.getNotificationCount());
        updateBadgeScale(mBadgeInfo.hasBadge(), badgeInfo.hasBadge());
        mBadgeInfo = badgeInfo;
    }

    /**
     * Sets mBadgeScale to 1 or 0, animating if oldCount or newCount is 0
     * Sets mBadgeScale to 1 or 0, animating if wasBadged or isBadged is false
     * (the badge is being added or removed).
     */
    private void updateBadgeScale(int oldCount, int newCount) {
        boolean wasBadged = oldCount > 0;
        boolean isBadged = newCount > 0;
    private void updateBadgeScale(boolean wasBadged, boolean isBadged) {
        float newBadgeScale = isBadged ? 1f : 0f;
        // Animate when a badge is first added or when it is removed.
        if ((wasBadged ^ isBadged) && isShown()) {
@@ -879,7 +877,7 @@ public class FolderIcon extends FrameLayout implements FolderListener {
            mBackground.drawBackgroundStroke(canvas);
        }

        if ((mBadgeInfo != null && mBadgeInfo.getNotificationCount() > 0) || mBadgeScale > 0) {
        if ((mBadgeInfo != null && mBadgeInfo.hasBadge()) || mBadgeScale > 0) {
            int offsetX = mBackground.getOffsetX();
            int offsetY = mBackground.getOffsetY();
            int previewSize = (int) (mBackground.previewSize * mBackground.mScale);
@@ -1046,20 +1044,20 @@ public class FolderIcon extends FrameLayout implements FolderListener {

    @Override
    public void onAdd(ShortcutInfo item) {
        int oldCount = mBadgeInfo.getNotificationCount();
        boolean wasBadged = mBadgeInfo.hasBadge();
        mBadgeInfo.addBadgeInfo(mLauncher.getPopupDataProvider().getBadgeInfoForItem(item));
        int newCount = mBadgeInfo.getNotificationCount();
        updateBadgeScale(oldCount, newCount);
        boolean isBadged = mBadgeInfo.hasBadge();
        updateBadgeScale(wasBadged, isBadged);
        invalidate();
        requestLayout();
    }

    @Override
    public void onRemove(ShortcutInfo item) {
        int oldCount = mBadgeInfo.getNotificationCount();
        boolean wasBadged = mBadgeInfo.hasBadge();
        mBadgeInfo.subtractBadgeInfo(mLauncher.getPopupDataProvider().getBadgeInfoForItem(item));
        int newCount = mBadgeInfo.getNotificationCount();
        updateBadgeScale(oldCount, newCount);
        boolean isBadged = mBadgeInfo.hasBadge();
        updateBadgeScale(wasBadged, isBadged);
        invalidate();
        requestLayout();
    }
+9 −1
Original line number Diff line number Diff line
@@ -43,6 +43,7 @@ public class IconPalette {
    public final int dominantColor;
    public final int backgroundColor;
    public final ColorMatrixColorFilter backgroundColorMatrixFilter;
    public final ColorMatrixColorFilter saturatedBackgroundColorMatrixFilter;
    public final int textColor;
    public final int secondaryColor;

@@ -52,6 +53,9 @@ public class IconPalette {
        ColorMatrix backgroundColorMatrix = new ColorMatrix();
        Themes.setColorScaleOnMatrix(backgroundColor, backgroundColorMatrix);
        backgroundColorMatrixFilter = new ColorMatrixColorFilter(backgroundColorMatrix);
        // Get slightly more saturated background color.
        Themes.setColorScaleOnMatrix(getMutedColor(dominantColor, 0.54f), backgroundColorMatrix);
        saturatedBackgroundColorMatrixFilter = new ColorMatrixColorFilter(backgroundColorMatrix);
        textColor = getTextColorForBackground(backgroundColor);
        secondaryColor = getLowContrastColor(backgroundColor);
    }
@@ -173,7 +177,11 @@ public class IconPalette {
    }

    private static int getMutedColor(int color) {
        int whiteScrim = ColorUtils.setAlphaComponent(Color.WHITE, (int) (255 * 0.87f));
        return getMutedColor(color, 0.87f);
    }

    private static int getMutedColor(int color, float whiteScrimAlpha) {
        int whiteScrim = ColorUtils.setAlphaComponent(Color.WHITE, (int) (255 * whiteScrimAlpha));
        return ColorUtils.compositeColors(whiteScrim, color);
    }

Loading