1/*
  2 * Copyright (C) 2020 The Android Open Source Project
  3 *
  4 * Licensed under the Apache License, Version 2.0 (the "License");
  5 * you may not use this file except in compliance with the License.
  6 * You may obtain a copy of the License at
  7 *
  8 *      http://www.apache.org/licenses/LICENSE-2.0
  9 *
 10 * Unless required by applicable law or agreed to in writing, software
 11 * distributed under the License is distributed on an "AS IS" BASIS,
 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 13 * See the License for the specific language governing permissions and
 14 * limitations under the License.
 15 */
 16
 17package eu.siacs.conversations.ui.util;
 18
 19import static java.util.Collections.max;
 20import static java.util.Collections.min;
 21
 22import android.graphics.drawable.Drawable;
 23import android.text.TextUtils;
 24import android.view.View;
 25import android.widget.ImageButton;
 26import android.widget.ImageView;
 27import android.widget.TextView;
 28
 29import androidx.annotation.NonNull;
 30import androidx.annotation.Nullable;
 31import androidx.appcompat.widget.ActionMenuView;
 32import androidx.appcompat.widget.Toolbar;
 33
 34import com.google.android.material.appbar.MaterialToolbar;
 35
 36import java.util.ArrayList;
 37import java.util.Comparator;
 38import java.util.List;
 39
 40public class ToolbarUtils {
 41
 42    private static final Comparator<View> VIEW_TOP_COMPARATOR =
 43            new Comparator<View>() {
 44                @Override
 45                public int compare(View view1, View view2) {
 46                    return view1.getTop() - view2.getTop();
 47                }
 48            };
 49
 50    private ToolbarUtils() {
 51        // Private constructor to prevent unwanted construction.
 52    }
 53
 54    public static void resetActionBarOnClickListeners(@NonNull MaterialToolbar view) {
 55        final TextView title = getTitleTextView(view);
 56        final TextView subtitle = getSubtitleTextView(view);
 57        if (title != null) {
 58            title.setOnClickListener(null);
 59        }
 60        if (subtitle != null) {
 61            subtitle.setOnClickListener(null);
 62        }
 63    }
 64
 65    public static void setActionBarOnClickListener(
 66            @NonNull MaterialToolbar view, @NonNull final View.OnClickListener onClickListener) {
 67        final TextView title = getTitleTextView(view);
 68        final TextView subtitle = getSubtitleTextView(view);
 69        if (title != null) {
 70            title.setOnClickListener(onClickListener);
 71        }
 72        if (subtitle != null) {
 73            subtitle.setOnClickListener(onClickListener);
 74        }
 75    }
 76
 77    @Nullable
 78    public static TextView getTitleTextView(@NonNull Toolbar toolbar) {
 79        List<TextView> textViews = getTextViewsWithText(toolbar, toolbar.getTitle());
 80        return textViews.isEmpty() ? null : min(textViews, VIEW_TOP_COMPARATOR);
 81    }
 82
 83    @Nullable
 84    public static TextView getSubtitleTextView(@NonNull Toolbar toolbar) {
 85        List<TextView> textViews = getTextViewsWithText(toolbar, toolbar.getSubtitle());
 86        return textViews.isEmpty() ? null : max(textViews, VIEW_TOP_COMPARATOR);
 87    }
 88
 89    private static List<TextView> getTextViewsWithText(
 90            @NonNull Toolbar toolbar, CharSequence text) {
 91        List<TextView> textViews = new ArrayList<>();
 92        for (int i = 0; i < toolbar.getChildCount(); i++) {
 93            View child = toolbar.getChildAt(i);
 94            if (child instanceof TextView textView) {
 95                if (TextUtils.equals(textView.getText(), text)) {
 96                    textViews.add(textView);
 97                }
 98            }
 99        }
100        return textViews;
101    }
102
103    @Nullable
104    public static ImageView getLogoImageView(@NonNull Toolbar toolbar) {
105        return getImageView(toolbar, toolbar.getLogo());
106    }
107
108    @Nullable
109    private static ImageView getImageView(@NonNull Toolbar toolbar, @Nullable Drawable content) {
110        if (content == null) {
111            return null;
112        }
113        for (int i = 0; i < toolbar.getChildCount(); i++) {
114            View child = toolbar.getChildAt(i);
115            if (child instanceof ImageView imageView) {
116                Drawable drawable = imageView.getDrawable();
117                if (drawable != null
118                        && drawable.getConstantState() != null
119                        && drawable.getConstantState().equals(content.getConstantState())) {
120                    return imageView;
121                }
122            }
123        }
124        return null;
125    }
126
127    @Nullable
128    public static View getSecondaryActionMenuItemView(@NonNull Toolbar toolbar) {
129        ActionMenuView actionMenuView = getActionMenuView(toolbar);
130        if (actionMenuView != null) {
131            // Only return the first child of the ActionMenuView if there is more than one child
132            if (actionMenuView.getChildCount() > 1) {
133                return actionMenuView.getChildAt(0);
134            }
135        }
136        return null;
137    }
138
139    @Nullable
140    public static ActionMenuView getActionMenuView(@NonNull Toolbar toolbar) {
141        for (int i = 0; i < toolbar.getChildCount(); i++) {
142            View child = toolbar.getChildAt(i);
143            if (child instanceof ActionMenuView) {
144                return (ActionMenuView) child;
145            }
146        }
147        return null;
148    }
149
150    @Nullable
151    public static ImageButton getNavigationIconButton(@NonNull Toolbar toolbar) {
152        Drawable navigationIcon = toolbar.getNavigationIcon();
153        if (navigationIcon == null) {
154            return null;
155        }
156        for (int i = 0; i < toolbar.getChildCount(); i++) {
157            View child = toolbar.getChildAt(i);
158            if (child instanceof ImageButton imageButton) {
159                if (imageButton.getDrawable() == navigationIcon) {
160                    return imageButton;
161                }
162            }
163        }
164        return null;
165    }
166}