1a20818257e6927560a676d99dbc563a0394f74d8Jason Monk/*
2a20818257e6927560a676d99dbc563a0394f74d8Jason Monk * Copyright (C) 2016 The Android Open Source Project
3a20818257e6927560a676d99dbc563a0394f74d8Jason Monk *
4a20818257e6927560a676d99dbc563a0394f74d8Jason Monk * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
5a20818257e6927560a676d99dbc563a0394f74d8Jason Monk * except in compliance with the License. You may obtain a copy of the License at
6a20818257e6927560a676d99dbc563a0394f74d8Jason Monk *
7a20818257e6927560a676d99dbc563a0394f74d8Jason Monk *      http://www.apache.org/licenses/LICENSE-2.0
8a20818257e6927560a676d99dbc563a0394f74d8Jason Monk *
9a20818257e6927560a676d99dbc563a0394f74d8Jason Monk * Unless required by applicable law or agreed to in writing, software distributed under the
10a20818257e6927560a676d99dbc563a0394f74d8Jason Monk * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
11a20818257e6927560a676d99dbc563a0394f74d8Jason Monk * KIND, either express or implied. See the License for the specific language governing
12a20818257e6927560a676d99dbc563a0394f74d8Jason Monk * permissions and limitations under the License.
13a20818257e6927560a676d99dbc563a0394f74d8Jason Monk */
14a20818257e6927560a676d99dbc563a0394f74d8Jason Monk
15a20818257e6927560a676d99dbc563a0394f74d8Jason Monkpackage com.android.systemui.statusbar.phone;
16a20818257e6927560a676d99dbc563a0394f74d8Jason Monk
17a20818257e6927560a676d99dbc563a0394f74d8Jason Monkimport android.annotation.Nullable;
18a20818257e6927560a676d99dbc563a0394f74d8Jason Monkimport android.content.Context;
194da1b4edf60f65dae3ae159c6d13e0eee3b64abaJason Monkimport android.content.res.Configuration;
20a20818257e6927560a676d99dbc563a0394f74d8Jason Monkimport android.util.AttributeSet;
21a20818257e6927560a676d99dbc563a0394f74d8Jason Monkimport android.view.View;
22a20818257e6927560a676d99dbc563a0394f74d8Jason Monkimport android.view.ViewGroup;
23a20818257e6927560a676d99dbc563a0394f74d8Jason Monkimport android.widget.LinearLayout;
24a20818257e6927560a676d99dbc563a0394f74d8Jason Monk
254da1b4edf60f65dae3ae159c6d13e0eee3b64abaJason Monkimport java.util.ArrayList;
264da1b4edf60f65dae3ae159c6d13e0eee3b64abaJason Monk
27a20818257e6927560a676d99dbc563a0394f74d8Jason Monk/**
28a20818257e6927560a676d99dbc563a0394f74d8Jason Monk * Automatically reverses the order of children as they are added.
29a20818257e6927560a676d99dbc563a0394f74d8Jason Monk * Also reverse the width and height values of layout params
30a20818257e6927560a676d99dbc563a0394f74d8Jason Monk */
31a20818257e6927560a676d99dbc563a0394f74d8Jason Monkpublic class ReverseLinearLayout extends LinearLayout {
32a20818257e6927560a676d99dbc563a0394f74d8Jason Monk
33db12b15febb32b4d366b8469c49bd9e724ef40d6Adrian Roos    /** If true, the layout is reversed vs. a regular linear layout */
34db12b15febb32b4d366b8469c49bd9e724ef40d6Adrian Roos    private boolean mIsLayoutReverse;
35db12b15febb32b4d366b8469c49bd9e724ef40d6Adrian Roos
36db12b15febb32b4d366b8469c49bd9e724ef40d6Adrian Roos    /** If true, the layout is opposite to it's natural reversity from the layout direction */
37db12b15febb32b4d366b8469c49bd9e724ef40d6Adrian Roos    private boolean mIsAlternativeOrder;
384da1b4edf60f65dae3ae159c6d13e0eee3b64abaJason Monk
39a20818257e6927560a676d99dbc563a0394f74d8Jason Monk    public ReverseLinearLayout(Context context, @Nullable AttributeSet attrs) {
40a20818257e6927560a676d99dbc563a0394f74d8Jason Monk        super(context, attrs);
41a20818257e6927560a676d99dbc563a0394f74d8Jason Monk    }
42a20818257e6927560a676d99dbc563a0394f74d8Jason Monk
43a20818257e6927560a676d99dbc563a0394f74d8Jason Monk    @Override
444da1b4edf60f65dae3ae159c6d13e0eee3b64abaJason Monk    protected void onFinishInflate() {
454da1b4edf60f65dae3ae159c6d13e0eee3b64abaJason Monk        super.onFinishInflate();
46db12b15febb32b4d366b8469c49bd9e724ef40d6Adrian Roos        updateOrder();
474da1b4edf60f65dae3ae159c6d13e0eee3b64abaJason Monk    }
484da1b4edf60f65dae3ae159c6d13e0eee3b64abaJason Monk
494da1b4edf60f65dae3ae159c6d13e0eee3b64abaJason Monk    @Override
50a20818257e6927560a676d99dbc563a0394f74d8Jason Monk    public void addView(View child) {
51a20818257e6927560a676d99dbc563a0394f74d8Jason Monk        reversParams(child.getLayoutParams());
52db12b15febb32b4d366b8469c49bd9e724ef40d6Adrian Roos        if (mIsLayoutReverse) {
53c44368016a192dfe381f5f73c07be42e705e64dbJorim Jaggi            super.addView(child, 0);
54db12b15febb32b4d366b8469c49bd9e724ef40d6Adrian Roos        } else {
55db12b15febb32b4d366b8469c49bd9e724ef40d6Adrian Roos            super.addView(child);
564da1b4edf60f65dae3ae159c6d13e0eee3b64abaJason Monk        }
57a20818257e6927560a676d99dbc563a0394f74d8Jason Monk    }
58a20818257e6927560a676d99dbc563a0394f74d8Jason Monk
59a20818257e6927560a676d99dbc563a0394f74d8Jason Monk    @Override
60a20818257e6927560a676d99dbc563a0394f74d8Jason Monk    public void addView(View child, ViewGroup.LayoutParams params) {
61a20818257e6927560a676d99dbc563a0394f74d8Jason Monk        reversParams(params);
62db12b15febb32b4d366b8469c49bd9e724ef40d6Adrian Roos        if (mIsLayoutReverse) {
63c44368016a192dfe381f5f73c07be42e705e64dbJorim Jaggi            super.addView(child, 0, params);
64db12b15febb32b4d366b8469c49bd9e724ef40d6Adrian Roos        } else {
65db12b15febb32b4d366b8469c49bd9e724ef40d6Adrian Roos            super.addView(child, params);
664da1b4edf60f65dae3ae159c6d13e0eee3b64abaJason Monk        }
674da1b4edf60f65dae3ae159c6d13e0eee3b64abaJason Monk    }
684da1b4edf60f65dae3ae159c6d13e0eee3b64abaJason Monk
694da1b4edf60f65dae3ae159c6d13e0eee3b64abaJason Monk    @Override
70db12b15febb32b4d366b8469c49bd9e724ef40d6Adrian Roos    public void onRtlPropertiesChanged(int layoutDirection) {
71db12b15febb32b4d366b8469c49bd9e724ef40d6Adrian Roos        super.onRtlPropertiesChanged(layoutDirection);
72db12b15febb32b4d366b8469c49bd9e724ef40d6Adrian Roos        updateOrder();
73db12b15febb32b4d366b8469c49bd9e724ef40d6Adrian Roos    }
74db12b15febb32b4d366b8469c49bd9e724ef40d6Adrian Roos
75db12b15febb32b4d366b8469c49bd9e724ef40d6Adrian Roos    public void setAlternativeOrder(boolean alternative) {
76db12b15febb32b4d366b8469c49bd9e724ef40d6Adrian Roos        mIsAlternativeOrder = alternative;
77db12b15febb32b4d366b8469c49bd9e724ef40d6Adrian Roos        updateOrder();
784da1b4edf60f65dae3ae159c6d13e0eee3b64abaJason Monk    }
794da1b4edf60f65dae3ae159c6d13e0eee3b64abaJason Monk
804da1b4edf60f65dae3ae159c6d13e0eee3b64abaJason Monk    /**
814da1b4edf60f65dae3ae159c6d13e0eee3b64abaJason Monk     * In landscape, the LinearLayout is not auto mirrored since it is vertical. Therefore we
824da1b4edf60f65dae3ae159c6d13e0eee3b64abaJason Monk     * have to do it manually
834da1b4edf60f65dae3ae159c6d13e0eee3b64abaJason Monk     */
84db12b15febb32b4d366b8469c49bd9e724ef40d6Adrian Roos    private void updateOrder() {
85db12b15febb32b4d366b8469c49bd9e724ef40d6Adrian Roos        boolean isLayoutRtl = getLayoutDirection() == LAYOUT_DIRECTION_RTL;
86db12b15febb32b4d366b8469c49bd9e724ef40d6Adrian Roos        boolean isLayoutReverse = isLayoutRtl ^ mIsAlternativeOrder;
87db12b15febb32b4d366b8469c49bd9e724ef40d6Adrian Roos
88db12b15febb32b4d366b8469c49bd9e724ef40d6Adrian Roos        if (mIsLayoutReverse != isLayoutReverse) {
89db12b15febb32b4d366b8469c49bd9e724ef40d6Adrian Roos            // reversity changed, swap the order of all views.
904da1b4edf60f65dae3ae159c6d13e0eee3b64abaJason Monk            int childCount = getChildCount();
914da1b4edf60f65dae3ae159c6d13e0eee3b64abaJason Monk            ArrayList<View> childList = new ArrayList<>(childCount);
924da1b4edf60f65dae3ae159c6d13e0eee3b64abaJason Monk            for (int i = 0; i < childCount; i++) {
934da1b4edf60f65dae3ae159c6d13e0eee3b64abaJason Monk                childList.add(getChildAt(i));
944da1b4edf60f65dae3ae159c6d13e0eee3b64abaJason Monk            }
954da1b4edf60f65dae3ae159c6d13e0eee3b64abaJason Monk            removeAllViews();
964da1b4edf60f65dae3ae159c6d13e0eee3b64abaJason Monk            for (int i = childCount - 1; i >= 0; i--) {
974da1b4edf60f65dae3ae159c6d13e0eee3b64abaJason Monk                super.addView(childList.get(i));
984da1b4edf60f65dae3ae159c6d13e0eee3b64abaJason Monk            }
99db12b15febb32b4d366b8469c49bd9e724ef40d6Adrian Roos            mIsLayoutReverse = isLayoutReverse;
1004da1b4edf60f65dae3ae159c6d13e0eee3b64abaJason Monk        }
101a20818257e6927560a676d99dbc563a0394f74d8Jason Monk    }
102a20818257e6927560a676d99dbc563a0394f74d8Jason Monk
103a20818257e6927560a676d99dbc563a0394f74d8Jason Monk    private void reversParams(ViewGroup.LayoutParams params) {
104a20818257e6927560a676d99dbc563a0394f74d8Jason Monk        if (params == null) {
105a20818257e6927560a676d99dbc563a0394f74d8Jason Monk            return;
106a20818257e6927560a676d99dbc563a0394f74d8Jason Monk        }
107a20818257e6927560a676d99dbc563a0394f74d8Jason Monk        int width = params.width;
108a20818257e6927560a676d99dbc563a0394f74d8Jason Monk        params.width = params.height;
109a20818257e6927560a676d99dbc563a0394f74d8Jason Monk        params.height = width;
110a20818257e6927560a676d99dbc563a0394f74d8Jason Monk    }
111a20818257e6927560a676d99dbc563a0394f74d8Jason Monk
112a20818257e6927560a676d99dbc563a0394f74d8Jason Monk}
113