summaryrefslogtreecommitdiffstats
path: root/src/com/android/messaging/datamodel/media/AvatarGroupRequestDescriptor.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/com/android/messaging/datamodel/media/AvatarGroupRequestDescriptor.java')
-rw-r--r--src/com/android/messaging/datamodel/media/AvatarGroupRequestDescriptor.java159
1 files changed, 159 insertions, 0 deletions
diff --git a/src/com/android/messaging/datamodel/media/AvatarGroupRequestDescriptor.java b/src/com/android/messaging/datamodel/media/AvatarGroupRequestDescriptor.java
new file mode 100644
index 0000000..719b296
--- /dev/null
+++ b/src/com/android/messaging/datamodel/media/AvatarGroupRequestDescriptor.java
@@ -0,0 +1,159 @@
+/*
+ * Copyright (C) 2015 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.messaging.datamodel.media;
+
+import android.content.Context;
+import android.graphics.RectF;
+import android.net.Uri;
+
+import com.android.messaging.util.Assert;
+import com.android.messaging.util.AvatarUriUtil;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+public class AvatarGroupRequestDescriptor extends CompositeImageRequestDescriptor {
+ private static final int MAX_GROUP_SIZE = 4;
+
+ public AvatarGroupRequestDescriptor(final Uri uri, final int desiredWidth,
+ final int desiredHeight) {
+ this(convertToDescriptor(uri, desiredWidth, desiredHeight), desiredWidth, desiredHeight);
+ }
+
+ public AvatarGroupRequestDescriptor(final List<? extends ImageRequestDescriptor> descriptors,
+ final int desiredWidth, final int desiredHeight) {
+ super(descriptors, desiredWidth, desiredHeight);
+ Assert.isTrue(descriptors.size() <= MAX_GROUP_SIZE);
+ }
+
+ private static List<? extends ImageRequestDescriptor> convertToDescriptor(final Uri uri,
+ final int desiredWidth, final int desiredHeight) {
+ final List<String> participantUriStrings = AvatarUriUtil.getGroupParticipantUris(uri);
+ final List<AvatarRequestDescriptor> avatarDescriptors =
+ new ArrayList<AvatarRequestDescriptor>(participantUriStrings.size());
+ for (final String uriString : participantUriStrings) {
+ final AvatarRequestDescriptor descriptor = new AvatarRequestDescriptor(
+ Uri.parse(uriString), desiredWidth, desiredHeight);
+ avatarDescriptors.add(descriptor);
+ }
+ return avatarDescriptors;
+ }
+
+ @Override
+ public CompositeImageRequest<?> buildBatchImageRequest(final Context context) {
+ return new CompositeImageRequest<AvatarGroupRequestDescriptor>(context, this);
+ }
+
+ @Override
+ public List<RectF> getChildRequestTargetRects() {
+ return Arrays.asList(generateDestRectArray());
+ }
+
+ /**
+ * Generates an array of {@link RectF} which represents where each of the individual avatar
+ * should be located in the final group avatar image. The location of each avatar depends on
+ * the size of the group and the size of the overall group avatar size.
+ */
+ private RectF[] generateDestRectArray() {
+ final int groupSize = mDescriptors.size();
+ final float width = desiredWidth;
+ final float height = desiredHeight;
+ final float halfWidth = width / 2F;
+ final float halfHeight = height / 2F;
+ final RectF[] destArray = new RectF[groupSize];
+ switch (groupSize) {
+ case 2:
+ /**
+ * +-------+
+ * | 0 | |
+ * +-------+
+ * | | 1 |
+ * +-------+
+ *
+ * We want two circles which touches in the center. To get this we know that the
+ * diagonal of the overall group avatar is squareRoot(2) * w We also know that the
+ * two circles touches the at the center of the overall group avatar and the
+ * distance from the center of the circle to the corner of the group avatar is
+ * radius * squareRoot(2). Therefore, the following emerges.
+ *
+ * w * squareRoot(2) = 2 (radius + radius * squareRoot(2))
+ * Solving for radius we get:
+ * d = 2 * radius = ( squareRoot(2) / (squareRoot(2) + 1)) * w
+ * d = (2 - squareRoot(2)) * w
+ */
+ final float diameter = (float) ((2 - Math.sqrt(2)) * width);
+ destArray[0] = new RectF(0, 0, diameter, diameter);
+ destArray[1] = new RectF(width - diameter, height - diameter, width, height);
+ break;
+ case 3:
+ /**
+ * +-------+
+ * | | 0 | |
+ * +-------+
+ * | 1 | 2 |
+ * +-------+
+ * i0
+ * |\
+ * a | \ c
+ * --- i2
+ * b
+ *
+ * a = radius * squareRoot(3) due to the triangle being a 30-60-90 right triangle.
+ * b = radius of circle
+ * c = 2 * radius of circle
+ *
+ * All three of the images are circles and therefore image zero will not touch
+ * image one or image two. Move image zero down so it touches image one and image
+ * two. This can be done by keeping image zero in the center and moving it down
+ * slightly. The amount to move down can be calculated by solving a right triangle.
+ * We know that the center x of image two to the center x of image zero is the
+ * radius of the circle, this is the length of edge b. Also we know that the
+ * distance from image zero to image two's center is 2 * radius, edge c. From this
+ * we know that the distance from center y of image two to center y of image one,
+ * edge a, is equal to radius * squareRoot(3) due to this triangle being a 30-60-90
+ * right triangle.
+ */
+ final float quarterWidth = width / 4F;
+ final float threeQuarterWidth = 3 * quarterWidth;
+ final float radius = height / 4F;
+ final float imageTwoCenterY = height - radius;
+ final float lengthOfEdgeA = (float) (radius * Math.sqrt(3));
+ final float imageZeroCenterY = imageTwoCenterY - lengthOfEdgeA;
+ final float imageZeroTop = imageZeroCenterY - radius;
+ final float imageZeroBottom = imageZeroCenterY + radius;
+ destArray[0] = new RectF(
+ quarterWidth, imageZeroTop, threeQuarterWidth, imageZeroBottom);
+ destArray[1] = new RectF(0, halfHeight, halfWidth, height);
+ destArray[2] = new RectF(halfWidth, halfHeight, width, height);
+ break;
+ default:
+ /**
+ * +-------+
+ * | 0 | 1 |
+ * +-------+
+ * | 2 | 3 |
+ * +-------+
+ */
+ destArray[0] = new RectF(0, 0, halfWidth, halfHeight);
+ destArray[1] = new RectF(halfWidth, 0, width, halfHeight);
+ destArray[2] = new RectF(0, halfHeight, halfWidth, height);
+ destArray[3] = new RectF(halfWidth, halfHeight, width, height);
+ break;
+ }
+ return destArray;
+ }
+}