summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorJin Cao <jinyan@google.com>2014-07-25 10:26:36 -0700
committerJin Cao <jinyan@google.com>2014-08-17 14:14:50 -0700
commitff404bb78dec989c1660434915b1b027a2d86bf3 (patch)
tree072d6a275f0e21eb509acd6751e428ca8a3f0291 /src
parentc9e850dbf7b05591ed9b9e3769162f0b03311da7 (diff)
downloadandroid_packages_apps_UnifiedEmail-ff404bb78dec989c1660434915b1b027a2d86bf3.tar.gz
android_packages_apps_UnifiedEmail-ff404bb78dec989c1660434915b1b027a2d86bf3.tar.bz2
android_packages_apps_UnifiedEmail-ff404bb78dec989c1660434915b1b027a2d86bf3.zip
Quantum folder list in TL
Re-did logic for drawing the folder list for TL. The maximum width of folder and chips are calculated based on a proportion of the entire conversation item. b/15552002 Change-Id: I8fea84112f86f9278dae4c724b2a0bd7a9c59af8
Diffstat (limited to 'src')
-rw-r--r--src/com/android/mail/browse/ConversationItemView.java186
-rw-r--r--src/com/android/mail/browse/ConversationItemViewCoordinates.java71
2 files changed, 130 insertions, 127 deletions
diff --git a/src/com/android/mail/browse/ConversationItemView.java b/src/com/android/mail/browse/ConversationItemView.java
index 82cc8616e..effce31f6 100644
--- a/src/com/android/mail/browse/ConversationItemView.java
+++ b/src/com/android/mail/browse/ConversationItemView.java
@@ -94,7 +94,6 @@ import com.android.mail.utils.ViewUtils;
import com.google.common.annotations.VisibleForTesting;
import java.util.ArrayList;
-import java.util.Iterator;
import java.util.List;
import java.util.Locale;
@@ -202,6 +201,9 @@ public class ConversationItemView extends View
private int mGadgetMode;
private static int sFoldersStartPadding;
+ private static int sFoldersInnerPadding;
+ private static int sFoldersMaxCount;
+ private static int sFoldersOverflowGradientPadding;
private static TextAppearanceSpan sSubjectTextUnreadSpan;
private static TextAppearanceSpan sSubjectTextReadSpan;
private static TextAppearanceSpan sBadgeTextSpan;
@@ -266,24 +268,89 @@ public class ConversationItemView extends View
return mFoldersCount > 0;
}
- private int measureFolders(int availableSpace, int cellSize) {
- int totalWidth = 0;
- boolean firstTime = true;
+ /**
+ * Helper function to calculate exactly how much space the displayed folders should take.
+ * @return an array of integers that signifies the length in dp.
+ */
+ private MeasurementWrapper measureFolderDimen(ConversationItemViewCoordinates coordinates) {
+ // This signifies the absolute max for each folder cell, no exceptions.
+ final int maxCellWidth = coordinates.folderCellWidth;
+
+ final int numDisplayedFolders = Math.min(sFoldersMaxCount, mFoldersSortedSet.size());
+ if (numDisplayedFolders == 0) {
+ return new MeasurementWrapper(new int[0], new boolean[0]);
+ }
+
+ // This variable is calculated based on the number of folders we are displaying
+ final int maxAllowedCellSize = Math.min(maxCellWidth, (coordinates.folderLayoutWidth -
+ (numDisplayedFolders - 1) * sFoldersStartPadding) / numDisplayedFolders);
+ final int[] measurements = new int[numDisplayedFolders];
+ final boolean[] overflow = new boolean[numDisplayedFolders];
+ final MeasurementWrapper result = new MeasurementWrapper(measurements, overflow);
+
+ int count = 0;
+ int missingWidth = 0;
+ int extraWidth = 0;
for (Folder f : mFoldersSortedSet) {
+ if (count > numDisplayedFolders - 1) {
+ break;
+ }
+
final String folderString = f.name;
- int width = (int) sFoldersPaint.measureText(folderString) + cellSize;
- if (firstTime) {
- firstTime = false;
+ final int neededWidth = (int) sFoldersPaint.measureText(folderString) +
+ 2 * sFoldersInnerPadding;
+
+ if (neededWidth > maxAllowedCellSize) {
+ // What we can take from others is the minimum of the width we need to borrow
+ // and the width we are allowed to borrow.
+ final int borrowedWidth = Math.min(neededWidth - maxAllowedCellSize,
+ maxCellWidth - maxAllowedCellSize);
+ final int extraWidthLeftover = extraWidth - borrowedWidth;
+ if (extraWidthLeftover >= 0) {
+ measurements[count] = Math.min(neededWidth, maxCellWidth);
+ extraWidth = extraWidthLeftover;
+ } else {
+ measurements[count] = maxAllowedCellSize + extraWidth;
+ extraWidth = 0;
+ }
+ missingWidth = -extraWidthLeftover;
+ overflow[count] = neededWidth > measurements[count];
} else {
- width += sFoldersStartPadding;
- }
- totalWidth += width;
- if (totalWidth > availableSpace) {
- break;
+ extraWidth = maxAllowedCellSize - neededWidth;
+ measurements[count] = neededWidth;
+ if (missingWidth > 0) {
+ if (extraWidth >= missingWidth) {
+ measurements[count - 1] += missingWidth;
+ extraWidth -= missingWidth;
+ overflow[count - 1] = false;
+ } else {
+ measurements[count - 1] += extraWidth;
+ extraWidth = 0;
+ }
+ }
+ missingWidth = 0;
}
+
+ count++;
}
- return totalWidth;
+ return result;
+ }
+
+ /**
+ * @return how much total space the folders list requires.
+ */
+ private int measureFolders(ConversationItemViewCoordinates coordinates) {
+ int[] sizes = measureFolderDimen(coordinates).measurements;
+ return sumWidth(sizes);
+ }
+
+ private int sumWidth(int[] arr) {
+ int sum = 0;
+ for (int i = 0; i < arr.length; i++) {
+ sum += arr[i];
+ }
+ return sum + (arr.length - 1) * sFoldersStartPadding;
}
public void drawFolders(
@@ -291,7 +358,11 @@ public class ConversationItemView extends View
if (mFoldersCount == 0) {
return;
}
- final int left = coordinates.foldersLeft;
+
+ final MeasurementWrapper wrapper = measureFolderDimen(coordinates);
+ final int[] measurements = wrapper.measurements;
+ final boolean[] overflow = wrapper.overflow;
+
final int right = coordinates.foldersRight;
final int y = coordinates.foldersY;
final int height = coordinates.foldersHeight;
@@ -301,75 +372,58 @@ public class ConversationItemView extends View
sFoldersPaint.setTypeface(coordinates.foldersTypeface);
// Initialize space and cell size based on the current mode.
- int availableSpace = right - left;
- int maxFoldersCount = availableSpace / coordinates.getFolderMinimumWidth();
- int foldersCount = Math.min(mFoldersCount, maxFoldersCount);
- int averageWidth = availableSpace / foldersCount;
- int cellSize = coordinates.getFolderCellWidth();
-
- // TODO(ath): sFoldersPaint.measureText() is done 3x in this method. stop that.
- // Extra credit: maybe cache results across items as long as font size doesn't change.
-
- final int totalWidth = measureFolders(availableSpace, cellSize);
- int xLeft = (isRtl) ? left : right - Math.min(availableSpace, totalWidth);
- final boolean overflow = totalWidth > availableSpace;
-
- // Second pass to draw folders.
- int i = 0;
- for (Iterator<Folder> it = isRtl ?
- mFoldersSortedSet.descendingIterator() : mFoldersSortedSet.iterator();
- it.hasNext();) {
- final Folder f = it.next();
- if (availableSpace <= 0) {
+ final int foldersCount = measurements.length;
+ final int width = sumWidth(measurements);
+ int xLeft = (isRtl) ? right - coordinates.folderLayoutWidth : right - width;
+
+ int index = 0;
+ for (Folder f : mFoldersSortedSet) {
+ if (index > foldersCount - 1) {
break;
}
+
final String folderString = f.name;
final int fgColor = f.getForegroundColor(mDefaultFgColor);
final int bgColor = f.getBackgroundColor(mDefaultBgColor);
- boolean labelTooLong = false;
- final int textW = (int) sFoldersPaint.measureText(folderString);
- int width = textW + cellSize + sFoldersStartPadding;
-
- if (overflow && width > averageWidth) {
- if (i < foldersCount - 1) {
- width = averageWidth;
- } else {
- // allow the last label to take all remaining space
- // (and don't let it make room for padding)
- width = availableSpace + sFoldersStartPadding;
- }
- labelTooLong = true;
- }
// Draw the box.
sFoldersPaint.setColor(bgColor);
sFoldersPaint.setStyle(Paint.Style.FILL);
final RectF rect =
- new RectF(xLeft, y, xLeft + width - sFoldersStartPadding, y + height);
+ new RectF(xLeft, y, xLeft + measurements[index], y + height);
canvas.drawRoundRect(rect, sFolderRoundedCornerRadius, sFolderRoundedCornerRadius,
sFoldersPaint);
// Draw the text.
- final int padding = cellSize / 2;
sFoldersPaint.setColor(fgColor);
sFoldersPaint.setStyle(Paint.Style.FILL);
- if (labelTooLong) {
- // todo - take RTL into account for fade
- final int rightBorder = xLeft + width - sFoldersStartPadding - padding;
- final Shader shader = new LinearGradient(rightBorder - padding, y,
- rightBorder, y, fgColor, Utils.getTransparentColor(fgColor),
- Shader.TileMode.CLAMP);
+ if (overflow[index]) {
+ final int rightBorder = xLeft + measurements[index];
+ final int x0 = (isRtl) ? xLeft + sFoldersOverflowGradientPadding :
+ rightBorder - sFoldersOverflowGradientPadding;
+ final int x1 = (isRtl) ? xLeft + sFoldersInnerPadding :
+ rightBorder - sFoldersInnerPadding;
+ final Shader shader = new LinearGradient(x0, y, x1, y, fgColor,
+ Utils.getTransparentColor(fgColor), Shader.TileMode.CLAMP);
sFoldersPaint.setShader(shader);
}
- canvas.drawText(folderString, xLeft + padding, y + height - textBottomPadding,
- sFoldersPaint);
- if (labelTooLong) {
+ canvas.drawText(folderString, xLeft + sFoldersInnerPadding,
+ y + height - textBottomPadding, sFoldersPaint);
+ if (overflow[index]) {
sFoldersPaint.setShader(null);
}
- availableSpace -= width;
- xLeft += width;
- i++;
+ xLeft += measurements[index++] + sFoldersStartPadding;
+ }
+ }
+
+ private static class MeasurementWrapper {
+ final int[] measurements;
+ final boolean[] overflow;
+
+ public MeasurementWrapper(int[] m, boolean[] o) {
+ measurements = m;
+ overflow = o;
}
}
}
@@ -475,6 +529,10 @@ public class ConversationItemView extends View
sElidedPaddingToken = res.getString(R.string.elided_padding_token);
sScrollSlop = res.getInteger(R.integer.swipeScrollSlop);
sFoldersStartPadding = res.getDimensionPixelOffset(R.dimen.folders_start_padding);
+ sFoldersInnerPadding = res.getDimensionPixelOffset(R.dimen.folder_cell_content_padding);
+ sFoldersMaxCount = res.getInteger(R.integer.conversation_list_max_folder_count);
+ sFoldersOverflowGradientPadding =
+ res.getDimensionPixelOffset(R.dimen.folders_gradient_padding);
sCabAnimationDuration = res.getInteger(R.integer.conv_item_view_cab_anim_duration);
sBadgePaddingExtraWidth = res.getDimensionPixelSize(R.dimen.badge_padding_extra_width);
sBadgeRoundedCornerRadius =
@@ -931,9 +989,7 @@ public class ConversationItemView extends View
final Spannable displayedStringBuilder = new SpannableString(snippet);
// measure the width of the folders which overlap the snippet view
- final int availableFolderSpace = mCoordinates.foldersRight - mCoordinates.foldersLeft;
- final int folderWidth = mHeader.folderDisplayer.measureFolders(availableFolderSpace,
- mCoordinates.getFolderCellWidth());
+ final int folderWidth = mHeader.folderDisplayer.measureFolders(mCoordinates);
// size the snippet view by subtracting the folder width from the maximum snippet width
final int snippetWidth = mCoordinates.maxSnippetWidth - folderWidth;
diff --git a/src/com/android/mail/browse/ConversationItemViewCoordinates.java b/src/com/android/mail/browse/ConversationItemViewCoordinates.java
index b89e425d6..fc1bea0fb 100644
--- a/src/com/android/mail/browse/ConversationItemViewCoordinates.java
+++ b/src/com/android/mail/browse/ConversationItemViewCoordinates.java
@@ -58,10 +58,6 @@ public class ConversationItemViewCoordinates {
static final int GADGET_CONTACT_PHOTO = 1;
static final int GADGET_CHECKBOX = 2;
- // For combined views
- private static int COLOR_BLOCK_WIDTH = -1;
- private static int COLOR_BLOCK_HEIGHT = -1;
-
/**
* Simple holder class for an item's abstract configuration state. ListView binding creates an
* instance per item, and {@link #forConfig(Context, Config, CoordinatesCache)} uses it to
@@ -223,6 +219,8 @@ public class ConversationItemViewCoordinates {
final float snippetFontSize;
// Folders.
+ final int folderLayoutWidth;
+ final int folderCellWidth;
final int foldersLeft;
final int foldersRight;
final int foldersY;
@@ -266,28 +264,17 @@ public class ConversationItemViewCoordinates {
final int contactImagesX;
final int contactImagesY;
+
/**
* The smallest item width for which we use the "wide" layout.
*/
private final int mMinListWidthForWide;
- /**
- * The smallest item width for which we use the "spacious" variant of the normal layout,
- * if the normal version is used at all. Larger than {@link #mMinListWidthForWide}, we use
- * wide mode anyway, and this value is unused.
- */
- private final int mMinListWidthIsSpacious;
- private final int mFolderCellWidth;
- private final int mFolderMinimumWidth;
private ConversationItemViewCoordinates(final Context context, final Config config,
final CoordinatesCache cache) {
Utils.traceBeginSection("CIV coordinates constructor");
final Resources res = context.getResources();
- mFolderCellWidth = res.getDimensionPixelSize(R.dimen.folder_cell_width);
mMinListWidthForWide = res.getDimensionPixelSize(R.dimen.list_min_width_is_wide);
- mMinListWidthIsSpacious = res.getDimensionPixelSize(
- R.dimen.list_normal_mode_min_width_is_spacious);
- mFolderMinimumWidth = res.getDimensionPixelSize(R.dimen.folder_minimum_width);
mMode = calculateMode(res, config);
@@ -336,6 +323,12 @@ public class ConversationItemViewCoordinates {
view.measure(widthSpec, heightSpec);
view.layout(0, 0, view.getMeasuredWidth(), view.getMeasuredHeight());
+ // Once the view is measured, let's calculate the dynamic width variables.
+ folderLayoutWidth = (int) (view.getWidth() *
+ res.getInteger(R.integer.folder_max_width_proportion) / 100.0);
+ folderCellWidth = (int) (view.getWidth() *
+ res.getInteger(R.integer.folder_cell_max_width_proportion) / 100.0);
+
// Utils.dumpViewTree((ViewGroup) view);
// Records coordinates.
@@ -534,35 +527,6 @@ public class ConversationItemViewCoordinates {
}
}
- @Deprecated
- public static int getColorBlockWidth(Context context) {
- Resources res = context.getResources();
- if (COLOR_BLOCK_WIDTH <= 0) {
- COLOR_BLOCK_WIDTH = res.getDimensionPixelSize(R.dimen.color_block_width);
- }
- return COLOR_BLOCK_WIDTH;
- }
-
- @Deprecated
- public static int getColorBlockHeight(Context context) {
- Resources res = context.getResources();
- if (COLOR_BLOCK_HEIGHT <= 0) {
- COLOR_BLOCK_HEIGHT = res.getDimensionPixelSize(R.dimen.color_block_height);
- }
- return COLOR_BLOCK_HEIGHT;
- }
-
- public static boolean displaySendersInline(int mode) {
- switch (mode) {
- case WIDE_MODE:
- return false;
- case NORMAL_MODE:
- return true;
- default:
- throw new IllegalArgumentException("Unknown conversation header view mode " + mode);
- }
- }
-
/**
* Returns coordinates for elements inside a conversation header view given
* the view width.
@@ -579,21 +543,4 @@ public class ConversationItemViewCoordinates {
cache.put(cacheKey, coordinates);
return coordinates;
}
-
- /**
- * Return the minimum width of a folder cell with no text. Essentially this is the left+right
- * intra-cell margin within cells.
- *
- */
- public int getFolderCellWidth() {
- return mFolderCellWidth;
- }
-
- /**
- * Return the minimum width of a folder cell, period. This will affect the
- * maximum number of folders we can display.
- */
- public int getFolderMinimumWidth() {
- return mFolderMinimumWidth;
- }
}