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

Commit 2d4632c2 authored by Maurice Chu's avatar Maurice Chu
Browse files

Fine-tuned enlarging of contact photos

When tapping a contact detail photo on any device, the
detail photo will attempt to expand as large as indicated
while still remaining fully on the screen and leaving some
space underneath to show the popup menu options.

If there is no photo, then there will be no expansion
although writable contacts will show a popup menu.

Bug: 6462711
Change-Id: I8f69a1c18dfa10ff0d02b9dbd3ba78043cc7eb4e
parent 78eefb87
Loading
Loading
Loading
Loading
+10 −2
Original line number Diff line number Diff line
@@ -16,8 +16,6 @@
<resources>
    <dimen name="account_selector_popup_width">400dip</dimen>

    <dimen name="photo_action_popup_width">400dip</dimen>

    <!-- Top position of quick contact. If this is -1, the vertical position is determined
    based on the source of the request -->
    <dimen name="quick_contact_top_position">48dip</dimen>
@@ -82,6 +80,16 @@
    <!-- Width and height of the contact photo on the contact detail page -->
    <dimen name="detail_contact_photo_size">128dip</dimen>

    <!-- Width and height of the expanded contact photo on the contact detail page -->
    <dimen name="detail_contact_photo_expanded_size">400dip</dimen>

    <!-- This is the minimum amount of space to leave underneath an expanded contact detail
         photo -->
    <dimen name="expanded_photo_height_offset">100dip</dimen>

    <!-- Minimum width for the photo action popup options -->
    <dimen name="photo_action_popup_min_width">300dip</dimen>

    <!-- Left and right padding for a contact detail item -->
    <dimen name="detail_item_icon_margin">8dip</dimen>

+60 −16
Original line number Diff line number Diff line
@@ -37,7 +37,6 @@ import android.graphics.Rect;
import android.net.Uri;
import android.os.Bundle;
import android.os.Parcelable;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup.MarginLayoutParams;
import android.widget.FrameLayout.LayoutParams;
@@ -105,6 +104,15 @@ public class PhotoSelectionActivity extends Activity {
    /** Whether to animate the photo to an expanded view covering more of the screen. */
    private boolean mExpandPhoto;

    /**
     * Side length (in pixels) of the expanded photo if to be expanded. Photos are expected to
     * be square.
     */
    private int mExpandedPhotoSize;

    /** Height (in pixels) to leave underneath the expanded photo to show the list popup */
    private int mHeightOffset;

    /** The semi-transparent backdrop. */
    private View mBackdrop;

@@ -164,6 +172,12 @@ public class PhotoSelectionActivity extends Activity {
        mIsDirectoryContact = intent.getBooleanExtra(IS_DIRECTORY_CONTACT, false);
        mExpandPhoto = intent.getBooleanExtra(EXPAND_PHOTO, false);

        // Pull out photo expansion properties from resources
        mExpandedPhotoSize = getResources().getDimensionPixelSize(
                R.dimen.detail_contact_photo_expanded_size);
        mHeightOffset = getResources().getDimensionPixelOffset(
                R.dimen.expanded_photo_height_offset);

        mBackdrop = findViewById(R.id.backdrop);
        mPhotoView = (ImageView) findViewById(R.id.photo);
        mSourceBounds = intent.getSourceBounds();
@@ -188,6 +202,30 @@ public class PhotoSelectionActivity extends Activity {
        });
    }

    /**
     * Compute the adjusted expanded photo size to fit within the enclosing view with the same
     * aspect ratio.
     * @param enclosingView This is the view that the photo must fit within.
     * @param heightOffset This is the amount of height to leave open for the photo action popup.
     */
    private int getAdjustedExpandedPhotoSize(View enclosingView, int heightOffset) {
        // pull out the bounds of the backdrop
        final Rect bounds = new Rect();
        enclosingView.getDrawingRect(bounds);
        final int boundsWidth = bounds.width();
        final int boundsHeight = bounds.height() - heightOffset;

        // ensure that the new expanded photo size can fit within the backdrop
        final float alpha = Math.min((float) boundsHeight / (float) mExpandedPhotoSize,
                (float) boundsWidth / (float) mExpandedPhotoSize);
        if (alpha < 1.0f) {
            // need to shrink width and height while maintaining aspect ratio
            return (int) (alpha * mExpandedPhotoSize);
        } else {
            return mExpandedPhotoSize;
        }
    }

    @Override
    public void onConfigurationChanged(Configuration newConfig) {
        super.onConfigurationChanged(newConfig);
@@ -279,7 +317,6 @@ public class PhotoSelectionActivity extends Activity {

        // Load the photo.
        int photoWidth = getPhotoEndParams().width;
        Log.d(TAG, "Photo width: " + photoWidth);
        if (mPhotoUri != null) {
            // If we have a URI, the bitmap should be cached directly.
            ContactPhotoManager.getInstance(this).loadPhoto(mPhotoView, mPhotoUri, photoWidth,
@@ -317,25 +354,32 @@ public class PhotoSelectionActivity extends Activity {
        attachPhotoHandler();
    }

    /**
     * This sets the photo's layout params at the end of the animation.
     * <p>
     * The scheme is to enlarge the photo to the desired size with the enlarged photo shifted
     * to the top left of the screen as much as possible while keeping the underlying smaller
     * photo occluded.
     */
    private LayoutParams getPhotoEndParams() {
        if (mPhotoEndParams == null) {
            mPhotoEndParams = new LayoutParams(mPhotoStartParams);
            if (mExpandPhoto) {
                Rect bounds = new Rect();
                mBackdrop.getDrawingRect(bounds);
                if (bounds.height() > bounds.width()) {
                    //Take up full width.
                    mPhotoEndParams.width = bounds.width();
                    mPhotoEndParams.height = bounds.width();
                } else {
                    // Take up full height, leaving space for the popup.
                    mPhotoEndParams.height = bounds.height() - 150;
                    mPhotoEndParams.width = bounds.height() - 150;
                }
                mPhotoEndParams.topMargin = 0;
                mPhotoEndParams.leftMargin = 0;
                mPhotoEndParams.bottomMargin = mPhotoEndParams.height;
                mPhotoEndParams.rightMargin = mPhotoEndParams.width;
                final int adjustedPhotoSize = getAdjustedExpandedPhotoSize(mBackdrop,
                        mHeightOffset);
                int widthDelta = adjustedPhotoSize - mPhotoStartParams.width;
                int heightDelta = adjustedPhotoSize - mPhotoStartParams.height;
                if (widthDelta >= 1 || heightDelta >= 1) {
                    // This is an actual expansion.
                    mPhotoEndParams.width = adjustedPhotoSize;
                    mPhotoEndParams.height = adjustedPhotoSize;
                    mPhotoEndParams.topMargin =
                            Math.max(mPhotoStartParams.topMargin - heightDelta, 0);
                    mPhotoEndParams.leftMargin =
                            Math.max(mPhotoStartParams.leftMargin - widthDelta, 0);
                    mPhotoEndParams.bottomMargin = 0;
                    mPhotoEndParams.rightMargin = 0;
                }
            }
        }
        return mPhotoEndParams;
+8 −6
Original line number Diff line number Diff line
@@ -425,12 +425,14 @@ public class ContactDetailFragment extends Fragment implements FragmentKeyListen
            // updates or not.
            if (mShowStaticPhoto) {
                mStaticPhotoContainer.setVisibility(View.VISIBLE);
                ImageView photoView = (ImageView) mStaticPhotoContainer.findViewById(R.id.photo);
                OnClickListener listener = mPhotoSetter.setupContactPhotoForClick(
                        mContext, mContactData, photoView, false);
                final ImageView photoView = (ImageView) mStaticPhotoContainer.findViewById(
                        R.id.photo);
                final boolean expandPhotoOnClick = mContactData.getPhotoUri() != null;
                final OnClickListener listener = mPhotoSetter.setupContactPhotoForClick(
                        mContext, mContactData, photoView, expandPhotoOnClick);
                if (mPhotoTouchOverlay != null) {
                    mPhotoTouchOverlay.setVisibility(View.VISIBLE);
                    if (mContactData.isWritableContact(mContext)) {
                    if (expandPhotoOnClick || mContactData.isWritableContact(mContext)) {
                        mPhotoTouchOverlay.setOnClickListener(listener);
                    } else {
                        mPhotoTouchOverlay.setClickable(false);
@@ -1524,8 +1526,8 @@ public class ContactDetailFragment extends Fragment implements FragmentKeyListen

            // Set the photo if it should be displayed
            if (viewCache.photoView != null) {
                final boolean expandOnClick = !PhoneCapabilityTester.isUsingTwoPanes(mContext);
                OnClickListener listener = mPhotoSetter.setupContactPhotoForClick(
                final boolean expandOnClick = mContactData.getPhotoUri() != null;
                final OnClickListener listener = mPhotoSetter.setupContactPhotoForClick(
                        mContext, mContactData, viewCache.photoView, expandOnClick);

                if (expandOnClick || mContactData.isWritableContact(mContext)) {
+1 −0
Original line number Diff line number Diff line
@@ -72,6 +72,7 @@ public class ContactDetailPhotoSetter extends ImageViewDrawableSetter {
            final int[] pos = new int[2];
            v.getLocationOnScreen(pos);

            // rect is the bounds (in pixels) of the photo view in screen coordinates
            final Rect rect = new Rect();
            rect.left = (int) (pos[0] * appScale + 0.5f);
            rect.top = (int) (pos[1] * appScale + 0.5f);
+2 −2
Original line number Diff line number Diff line
@@ -472,8 +472,8 @@ public class ContactDetailTabCarousel extends HorizontalScrollView implements On

        // TODO: Move this into the {@link CarouselTab} class when the updates
        // fragment code is more finalized.
        final boolean expandOnClick = !PhoneCapabilityTester.isUsingTwoPanes(mContext);
        OnClickListener listener = mPhotoSetter.setupContactPhotoForClick(
        final boolean expandOnClick = contactData.getPhotoUri() != null;
        final OnClickListener listener = mPhotoSetter.setupContactPhotoForClick(
                mContext, contactData, mPhotoView, expandOnClick);

        if (expandOnClick || contactData.isWritableContact(mContext)) {
Loading