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

Commit ee1f9361 authored by Bryce Lee's avatar Bryce Lee
Browse files

Add snapToGuide for complications.

snapToGuide lets the ComplicationLayoutEngine choose the proper dimension for a complication. This adjusted dimension is always the one perpendicular to the complication direction.
Bug: 216369783
Test: atest ComplicationLayoutEngineTest#testSnapToGuide

Change-Id: I20a501bc3ef3274d2f511e2ea5901d1865b0ec24
parent 86d5713d
Loading
Loading
Loading
Loading
+24 −0
Original line number Diff line number Diff line
@@ -20,6 +20,30 @@
    android:id="@+id/dream_overlay_complications_layer"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <androidx.constraintlayout.widget.Guideline
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/complication_top_guide"
        app:layout_constraintGuide_percent="@dimen/dream_overlay_complication_guide_top_percent"
        android:orientation="horizontal"/>
    <androidx.constraintlayout.widget.Guideline
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/complication_end_guide"
        app:layout_constraintGuide_percent="@dimen/dream_overlay_complication_guide_end_percent"
        android:orientation="vertical"/>
    <androidx.constraintlayout.widget.Guideline
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/complication_bottom_guide"
        app:layout_constraintGuide_percent="@dimen/dream_overlay_complication_guide_bottom_percent"
        android:orientation="horizontal"/>
    <androidx.constraintlayout.widget.Guideline
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/complication_start_guide"
        app:layout_constraintGuide_percent="@dimen/dream_overlay_complication_guide_start_percent"
        android:orientation="vertical"/>
    <TextClock
        android:id="@+id/time_view"
        android:layout_width="wrap_content"
+28 −0
Original line number Diff line number Diff line
@@ -1343,4 +1343,32 @@
    <!-- Height of the area at the top of the dream overlay to allow dragging down the notifications
         shade. -->
    <dimen name="dream_overlay_notifications_drag_area_height">100dp</dimen>

    <!-- The position of the end guide, which dream overlay complications can align their start with
         if their end is aligned with the parent end. Represented as the percentage over from the
         start of the parent container. -->
    <item name="dream_overlay_complication_guide_end_percent" format="float" type="dimen">
        0.75
    </item>

    <!-- The position of the start guide, which dream overlay complications can align their end to
         if their start is aligned with the parent start. Represented as the percentage over from
         the start of the parent container. -->
    <item name="dream_overlay_complication_guide_start_percent" format="float" type="dimen">
        0.25
    </item>

    <!-- The position of the bottom guide, which dream overlay complications can align their top to
         if their bottom is aligned with the parent bottom. Represented as the percentage over from
         the top of the parent container. -->
    <item name="dream_overlay_complication_guide_bottom_percent" format="float" type="dimen">
        0.90
    </item>

    <!-- The position of the top guide, which dream overlay complications can align their bottom to
     if their top is aligned with the parent top. Represented as the percentage over from
     the top of the parent container. -->
    <item name="dream_overlay_complication_guide_top_percent" format="float" type="dimen">
        0.10
    </item>
</resources>
+35 −0
Original line number Diff line number Diff line
@@ -25,10 +25,13 @@ import android.view.ViewGroup;
import androidx.constraintlayout.widget.ConstraintLayout;
import androidx.constraintlayout.widget.Constraints;

import com.android.systemui.R;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.function.Consumer;

import javax.inject.Inject;
import javax.inject.Named;
@@ -102,6 +105,8 @@ public class ComplicationLayoutEngine {

            final int direction = getLayoutParams().getDirection();

            final boolean snapsToGuide = getLayoutParams().snapsToGuide();

            // If no parent, view is the anchor. In this case, it is given the highest priority for
            // alignment. All alignment preferences are done in relation to the parent container.
            final boolean isRoot = head == mView;
@@ -125,6 +130,11 @@ public class ComplicationLayoutEngine {
                        } else {
                            params.startToEnd = head.getId();
                        }
                        if (snapsToGuide
                                && (direction == ComplicationLayoutParams.DIRECTION_DOWN
                                || direction == ComplicationLayoutParams.DIRECTION_UP)) {
                            params.endToStart = R.id.complication_start_guide;
                        }
                        break;
                    case ComplicationLayoutParams.POSITION_TOP:
                        if (isRoot || direction != ComplicationLayoutParams.DIRECTION_DOWN) {
@@ -132,6 +142,11 @@ public class ComplicationLayoutEngine {
                        } else {
                            params.topToBottom = head.getId();
                        }
                        if (snapsToGuide
                                && (direction == ComplicationLayoutParams.DIRECTION_END
                                || direction == ComplicationLayoutParams.DIRECTION_START)) {
                            params.endToStart = R.id.complication_top_guide;
                        }
                        break;
                    case ComplicationLayoutParams.POSITION_BOTTOM:
                        if (isRoot || direction != ComplicationLayoutParams.DIRECTION_UP) {
@@ -139,6 +154,11 @@ public class ComplicationLayoutEngine {
                        } else {
                            params.bottomToTop = head.getId();
                        }
                        if (snapsToGuide
                                && (direction == ComplicationLayoutParams.DIRECTION_END
                                || direction == ComplicationLayoutParams.DIRECTION_START)) {
                            params.topToBottom = R.id.complication_bottom_guide;
                        }
                        break;
                    case ComplicationLayoutParams.POSITION_END:
                        if (isRoot || direction != ComplicationLayoutParams.DIRECTION_START) {
@@ -146,6 +166,11 @@ public class ComplicationLayoutEngine {
                        } else {
                            params.endToStart = head.getId();
                        }
                        if (snapsToGuide
                                && (direction == ComplicationLayoutParams.DIRECTION_UP
                                || direction == ComplicationLayoutParams.DIRECTION_DOWN)) {
                            params.startToEnd = R.id.complication_end_guide;
                        }
                        break;
                }
            });
@@ -153,6 +178,16 @@ public class ComplicationLayoutEngine {
            mView.setLayoutParams(params);
        }

        private void setGuide(ConstraintLayout.LayoutParams lp, int validDirections,
                Consumer<ConstraintLayout.LayoutParams> consumer) {
            final ComplicationLayoutParams layoutParams = getLayoutParams();
            if (!layoutParams.snapsToGuide()) {
                return;
            }

            consumer.accept(lp);
        }

        /**
         * Informs the {@link ViewEntry}'s parent entity to remove the {@link ViewEntry} from
         * being shown further.
+46 −8
Original line number Diff line number Diff line
@@ -40,13 +40,13 @@ public class ComplicationLayoutParams extends ViewGroup.LayoutParams {

    @interface Position {}
    /** Align view with the top of parent or bottom of preceding {@link Complication}. */
    static final int POSITION_TOP = 1 << 0;
    public static final int POSITION_TOP = 1 << 0;
    /** Align view with the bottom of parent or top of preceding {@link Complication}. */
    static final int POSITION_BOTTOM = 1 << 1;
    public static final int POSITION_BOTTOM = 1 << 1;
    /** Align view with the start of parent or end of preceding {@link Complication}. */
    static final int POSITION_START = 1 << 2;
    public static final int POSITION_START = 1 << 2;
    /** Align view with the end of parent or start of preceding {@link Complication}. */
    static final int POSITION_END = 1 << 3;
    public static final int POSITION_END = 1 << 3;

    private static final int FIRST_POSITION = POSITION_TOP;
    private static final int LAST_POSITION = POSITION_END;
@@ -61,13 +61,13 @@ public class ComplicationLayoutParams extends ViewGroup.LayoutParams {

    @interface Direction {}
    /** Position view upward from position. */
    static final int DIRECTION_UP = 1 << 0;
    public static final int DIRECTION_UP = 1 << 0;
    /** Position view downward from position. */
    static final int DIRECTION_DOWN = 1 << 1;
    public static final int DIRECTION_DOWN = 1 << 1;
    /** Position view towards the start of the parent. */
    static final int DIRECTION_START = 1 << 2;
    public static final int DIRECTION_START = 1 << 2;
    /** Position view towards the end of parent. */
    static final int DIRECTION_END = 1 << 3;
    public static final int DIRECTION_END = 1 << 3;

    @Position
    private final int mPosition;
@@ -77,6 +77,8 @@ public class ComplicationLayoutParams extends ViewGroup.LayoutParams {

    private final int mWeight;

    private final boolean mSnapToGuide;

    // Do not allow specifying opposite positions
    private static final int[] INVALID_POSITIONS =
            { POSITION_BOTTOM | POSITION_TOP, POSITION_END | POSITION_START };
@@ -104,6 +106,27 @@ public class ComplicationLayoutParams extends ViewGroup.LayoutParams {
     */
    public ComplicationLayoutParams(int width, int height, @Position int position,
            @Direction int direction, int weight) {
        this(width, height, position, direction, weight, false);
    }

    /**
     * Constructs a {@link ComplicationLayoutParams}.
     * @param width The width {@link android.view.View.MeasureSpec} for the view.
     * @param height The height {@link android.view.View.MeasureSpec} for the view.
     * @param position The place within the parent container where the view should be positioned.
     * @param direction The direction the view should be laid out from either the parent container
     *                  or preceding view.
     * @param weight The weight that should be considered for this view when compared to other
     *               views. This has an impact on the placement of the view but not the rendering of
     *               the view.
     * @param snapToGuide When set to {@code true}, the dimension perpendicular to the direction
     *                    will be automatically set to align with a predetermined guide for that
     *                    side. For example, if the complication is aligned to the top end and
     *                    direction is down, then the width of the complication will be set to span
     *                    from the end of the parent to the guide.
     */
    public ComplicationLayoutParams(int width, int height, @Position int position,
            @Direction int direction, int weight, boolean snapToGuide) {
        super(width, height);

        if (!validatePosition(position)) {
@@ -118,6 +141,8 @@ public class ComplicationLayoutParams extends ViewGroup.LayoutParams {
        mDirection = direction;

        mWeight = weight;

        mSnapToGuide = snapToGuide;
    }

    /**
@@ -128,6 +153,7 @@ public class ComplicationLayoutParams extends ViewGroup.LayoutParams {
        mPosition = source.mPosition;
        mDirection = source.mDirection;
        mWeight = source.mWeight;
        mSnapToGuide = source.mSnapToGuide;
    }

    private static boolean validateDirection(@Position int position, @Direction int direction) {
@@ -180,7 +206,19 @@ public class ComplicationLayoutParams extends ViewGroup.LayoutParams {
        return mPosition;
    }

    /**
     * Returns the set weight for the complication. The weight determines ordering a complication
     * given the same position/direction.
     */
    public int getWeight() {
        return mWeight;
    }

    /**
     * Returns whether the complication's dimension perpendicular to direction should be
     * automatically set.
     */
    public boolean snapsToGuide() {
        return mSnapToGuide;
    }
}
+29 −0
Original line number Diff line number Diff line
@@ -27,6 +27,7 @@ import android.view.View;
import androidx.constraintlayout.widget.ConstraintLayout;
import androidx.test.filters.SmallTest;

import com.android.systemui.R;
import com.android.systemui.SysuiTestCase;

import org.junit.Before;
@@ -121,6 +122,34 @@ public class ComplicationLayoutEngineTest extends SysuiTestCase {
        });
    }

    /**
     * Makes sure the engine properly places a view within the {@link ConstraintLayout}.
     */
    @Test
    public void testSnapToGuide() {
        final ViewInfo firstViewInfo = new ViewInfo(
                new ComplicationLayoutParams(
                        100,
                        100,
                        ComplicationLayoutParams.POSITION_TOP
                                | ComplicationLayoutParams.POSITION_END,
                        ComplicationLayoutParams.DIRECTION_DOWN,
                        0,
                        true),
                Complication.CATEGORY_STANDARD,
                mLayout);

        final ComplicationLayoutEngine engine = new ComplicationLayoutEngine(mLayout);
        addComplication(engine, firstViewInfo);

        // Ensure the view is added to the top end corner
        verifyChange(firstViewInfo, true, lp -> {
            assertThat(lp.topToTop == ConstraintLayout.LayoutParams.PARENT_ID).isTrue();
            assertThat(lp.endToEnd == ConstraintLayout.LayoutParams.PARENT_ID).isTrue();
            assertThat(lp.startToEnd == R.id.complication_end_guide).isTrue();
        });
    }

    /**
     * Ensures layout in a particular direction updates.
     */