1f4575634e9f3c2b61c2e6bceaeed6cabb378803fJae Seo/*
2f4575634e9f3c2b61c2e6bceaeed6cabb378803fJae Seo * Copyright (C) 2015 The Android Open Source Project
3f4575634e9f3c2b61c2e6bceaeed6cabb378803fJae Seo *
4f4575634e9f3c2b61c2e6bceaeed6cabb378803fJae Seo * Licensed under the Apache License, Version 2.0 (the "License");
5f4575634e9f3c2b61c2e6bceaeed6cabb378803fJae Seo * you may not use this file except in compliance with the License.
6f4575634e9f3c2b61c2e6bceaeed6cabb378803fJae Seo * You may obtain a copy of the License at
7f4575634e9f3c2b61c2e6bceaeed6cabb378803fJae Seo *
8f4575634e9f3c2b61c2e6bceaeed6cabb378803fJae Seo *      http://www.apache.org/licenses/LICENSE-2.0
9f4575634e9f3c2b61c2e6bceaeed6cabb378803fJae Seo *
10f4575634e9f3c2b61c2e6bceaeed6cabb378803fJae Seo * Unless required by applicable law or agreed to in writing, software
11f4575634e9f3c2b61c2e6bceaeed6cabb378803fJae Seo * distributed under the License is distributed on an "AS IS" BASIS,
12f4575634e9f3c2b61c2e6bceaeed6cabb378803fJae Seo * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13f4575634e9f3c2b61c2e6bceaeed6cabb378803fJae Seo * See the License for the specific language governing permissions and
14f4575634e9f3c2b61c2e6bceaeed6cabb378803fJae Seo * limitations under the License.
15f4575634e9f3c2b61c2e6bceaeed6cabb378803fJae Seo */
16f4575634e9f3c2b61c2e6bceaeed6cabb378803fJae Seo
17f4575634e9f3c2b61c2e6bceaeed6cabb378803fJae Seopackage android.support.v7.app;
18f4575634e9f3c2b61c2e6bceaeed6cabb378803fJae Seo
19f4575634e9f3c2b61c2e6bceaeed6cabb378803fJae Seoimport android.content.Context;
201c4fce94062e162e579d20134f0bac767bdf0964Donghyun Choimport android.graphics.Bitmap;
211c4fce94062e162e579d20134f0bac767bdf0964Donghyun Choimport android.graphics.Canvas;
221c4fce94062e162e579d20134f0bac767bdf0964Donghyun Choimport android.graphics.Rect;
231c4fce94062e162e579d20134f0bac767bdf0964Donghyun Choimport android.graphics.drawable.BitmapDrawable;
24f4575634e9f3c2b61c2e6bceaeed6cabb378803fJae Seoimport android.support.v7.mediarouter.R;
25f4575634e9f3c2b61c2e6bceaeed6cabb378803fJae Seoimport android.util.DisplayMetrics;
26f4575634e9f3c2b61c2e6bceaeed6cabb378803fJae Seoimport android.util.TypedValue;
271c4fce94062e162e579d20134f0bac767bdf0964Donghyun Choimport android.view.View;
28f4575634e9f3c2b61c2e6bceaeed6cabb378803fJae Seoimport android.view.ViewGroup;
291c4fce94062e162e579d20134f0bac767bdf0964Donghyun Choimport android.widget.ArrayAdapter;
301c4fce94062e162e579d20134f0bac767bdf0964Donghyun Choimport android.widget.ListView;
311c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho
321c4fce94062e162e579d20134f0bac767bdf0964Donghyun Choimport java.util.HashMap;
331c4fce94062e162e579d20134f0bac767bdf0964Donghyun Choimport java.util.HashSet;
341c4fce94062e162e579d20134f0bac767bdf0964Donghyun Choimport java.util.List;
351c4fce94062e162e579d20134f0bac767bdf0964Donghyun Choimport java.util.Set;
36f4575634e9f3c2b61c2e6bceaeed6cabb378803fJae Seo
37f4575634e9f3c2b61c2e6bceaeed6cabb378803fJae Seofinal class MediaRouteDialogHelper {
388d6734a1a6da41bf7a9fbfda0ab05e1fa5ab84d9Dongwon Kang    /**
398d6734a1a6da41bf7a9fbfda0ab05e1fa5ab84d9Dongwon Kang     * The framework should set the dialog width properly, but somehow it doesn't work, hence
408d6734a1a6da41bf7a9fbfda0ab05e1fa5ab84d9Dongwon Kang     * duplicating a similar logic here to determine the appropriate dialog width.
418d6734a1a6da41bf7a9fbfda0ab05e1fa5ab84d9Dongwon Kang     */
42f4575634e9f3c2b61c2e6bceaeed6cabb378803fJae Seo    public static int getDialogWidth(Context context) {
43f4575634e9f3c2b61c2e6bceaeed6cabb378803fJae Seo        DisplayMetrics metrics = context.getResources().getDisplayMetrics();
44f4575634e9f3c2b61c2e6bceaeed6cabb378803fJae Seo        boolean isPortrait = metrics.widthPixels < metrics.heightPixels;
45f4575634e9f3c2b61c2e6bceaeed6cabb378803fJae Seo
46f4575634e9f3c2b61c2e6bceaeed6cabb378803fJae Seo        TypedValue value = new TypedValue();
47f4575634e9f3c2b61c2e6bceaeed6cabb378803fJae Seo        context.getResources().getValue(isPortrait ? R.dimen.mr_dialog_fixed_width_minor
48f4575634e9f3c2b61c2e6bceaeed6cabb378803fJae Seo                : R.dimen.mr_dialog_fixed_width_major, value, true);
49f4575634e9f3c2b61c2e6bceaeed6cabb378803fJae Seo        if (value.type == TypedValue.TYPE_DIMENSION) {
50f4575634e9f3c2b61c2e6bceaeed6cabb378803fJae Seo            return (int) value.getDimension(metrics);
51f4575634e9f3c2b61c2e6bceaeed6cabb378803fJae Seo        } else if (value.type == TypedValue.TYPE_FRACTION) {
52f4575634e9f3c2b61c2e6bceaeed6cabb378803fJae Seo            return (int) value.getFraction(metrics.widthPixels, metrics.widthPixels);
53f4575634e9f3c2b61c2e6bceaeed6cabb378803fJae Seo        }
54f4575634e9f3c2b61c2e6bceaeed6cabb378803fJae Seo        return ViewGroup.LayoutParams.WRAP_CONTENT;
55f4575634e9f3c2b61c2e6bceaeed6cabb378803fJae Seo    }
561c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho
571c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho    /**
581c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho     * Compares two lists regardless of order.
591c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho     *
601c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho     * @param list1 A list
611c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho     * @param list2 A list to be compared with {@code list1}
621c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho     * @return True if two lists have exactly same items regardless of order, false otherwise.
631c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho     */
641c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho    public static <E> boolean listUnorderedEquals(List<E> list1, List<E> list2) {
651c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho        HashSet<E> set1 = new HashSet<>(list1);
661c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho        HashSet<E> set2 = new HashSet<>(list2);
671c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho        return set1.equals(set2);
681c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho    }
691c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho
701c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho    /**
711c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho     * Compares two lists and returns a set of items which exist
721c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho     * after-list but before-list, which means newly added items.
731c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho     *
741c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho     * @param before A list
751c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho     * @param after A list to be compared with {@code before}
761c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho     * @return A set of items which contains newly added items while
771c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho     * comparing {@code after} to {@code before}.
781c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho     */
791c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho    public static <E> Set<E> getItemsAdded(List<E> before, List<E> after) {
801c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho        HashSet<E> set = new HashSet<>(after);
811c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho        set.removeAll(before);
821c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho        return set;
831c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho    }
841c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho
851c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho    /**
861c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho     * Compares two lists and returns a set of items which exist
871c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho     * before-list but after-list, which means removed items.
881c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho     *
891c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho     * @param before A list
901c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho     * @param after A list to be compared with {@code before}
911c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho     * @return A set of items which contains removed items while
921c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho     * comparing {@code after} to {@code before}.
931c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho     */
941c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho    public static <E> Set<E> getItemsRemoved(List<E> before, List<E> after) {
951c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho        HashSet<E> set = new HashSet<>(before);
961c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho        set.removeAll(after);
971c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho        return set;
981c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho    }
991c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho
1001c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho    /**
1011c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho     * Generates an item-Rect map which indicates where member
1021c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho     * items are located in the given ListView.
1031c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho     *
1041c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho     * @param listView A list view
1051c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho     * @param adapter An array adapter which contains an array of items.
1061c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho     * @return A map of items and bounds of their views located in the given list view.
1071c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho     */
1081c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho    public static <E> HashMap<E, Rect> getItemBoundMap(ListView listView,
1091c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho            ArrayAdapter<E> adapter) {
1101c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho        HashMap<E, Rect> itemBoundMap = new HashMap<>();
1111c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho        int firstVisiblePosition = listView.getFirstVisiblePosition();
1121c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho        for (int i = 0; i < listView.getChildCount(); ++i) {
1131c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho            int position = firstVisiblePosition + i;
1141c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho            E item = adapter.getItem(position);
1151c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho            View view = listView.getChildAt(i);
1161c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho            itemBoundMap.put(item,
1171c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho                    new Rect(view.getLeft(), view.getTop(), view.getRight(), view.getBottom()));
1181c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho        }
1191c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho        return itemBoundMap;
1201c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho    }
1211c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho
1221c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho    /**
1231c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho     * Generates an item-BitmapDrawable map which stores snapshots
1241c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho     * of member items in the given ListView.
1251c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho     *
1261c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho     * @param context A context
1271c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho     * @param listView A list view
1281c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho     * @param adapter An array adapter which contains an array of items.
1291c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho     * @return A map of items and snapshots of their views in the given list view.
1301c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho     */
1311c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho    public static <E> HashMap<E, BitmapDrawable> getItemBitmapMap(Context context,
1321c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho            ListView listView, ArrayAdapter<E> adapter) {
1331c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho        HashMap<E, BitmapDrawable> itemBitmapMap = new HashMap<>();
1341c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho        int firstVisiblePosition = listView.getFirstVisiblePosition();
1351c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho        for (int i = 0; i < listView.getChildCount(); ++i) {
1361c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho            int position = firstVisiblePosition + i;
1371c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho            E item = adapter.getItem(position);
1381c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho            View view = listView.getChildAt(i);
1391c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho            itemBitmapMap.put(item, getViewBitmap(context, view));
1401c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho        }
1411c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho        return itemBitmapMap;
1421c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho    }
1431c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho
1441c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho    private static BitmapDrawable getViewBitmap(Context context, View view) {
1451c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho        Bitmap bitmap = Bitmap.createBitmap(view.getWidth(), view.getHeight(),
1461c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho                Bitmap.Config.ARGB_8888);
1471c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho        Canvas canvas = new Canvas(bitmap);
1481c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho        view.draw(canvas);
1491c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho        return new BitmapDrawable(context.getResources(), bitmap);
1501c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho    }
151f4575634e9f3c2b61c2e6bceaeed6cabb378803fJae Seo}
152