1e172a3fc23412ebc79d6bd93e6d43d4b1c58354bXavier Ducrohet/*
2e172a3fc23412ebc79d6bd93e6d43d4b1c58354bXavier Ducrohet * Copyright (C) 2011 The Android Open Source Project
3e172a3fc23412ebc79d6bd93e6d43d4b1c58354bXavier Ducrohet *
4e172a3fc23412ebc79d6bd93e6d43d4b1c58354bXavier Ducrohet * Licensed under the Apache License, Version 2.0 (the "License");
5e172a3fc23412ebc79d6bd93e6d43d4b1c58354bXavier Ducrohet * you may not use this file except in compliance with the License.
6e172a3fc23412ebc79d6bd93e6d43d4b1c58354bXavier Ducrohet * You may obtain a copy of the License at
7e172a3fc23412ebc79d6bd93e6d43d4b1c58354bXavier Ducrohet *
8e172a3fc23412ebc79d6bd93e6d43d4b1c58354bXavier Ducrohet *      http://www.apache.org/licenses/LICENSE-2.0
9e172a3fc23412ebc79d6bd93e6d43d4b1c58354bXavier Ducrohet *
10e172a3fc23412ebc79d6bd93e6d43d4b1c58354bXavier Ducrohet * Unless required by applicable law or agreed to in writing, software
11e172a3fc23412ebc79d6bd93e6d43d4b1c58354bXavier Ducrohet * distributed under the License is distributed on an "AS IS" BASIS,
12e172a3fc23412ebc79d6bd93e6d43d4b1c58354bXavier Ducrohet * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13e172a3fc23412ebc79d6bd93e6d43d4b1c58354bXavier Ducrohet * See the License for the specific language governing permissions and
14e172a3fc23412ebc79d6bd93e6d43d4b1c58354bXavier Ducrohet * limitations under the License.
15e172a3fc23412ebc79d6bd93e6d43d4b1c58354bXavier Ducrohet */
16e172a3fc23412ebc79d6bd93e6d43d4b1c58354bXavier Ducrohet
17e172a3fc23412ebc79d6bd93e6d43d4b1c58354bXavier Ducrohetpackage com.android.layoutlib.bridge.impl.binding;
18e172a3fc23412ebc79d6bd93e6d43d4b1c58354bXavier Ducrohet
19e172a3fc23412ebc79d6bd93e6d43d4b1c58354bXavier Ducrohetimport com.android.ide.common.rendering.api.AdapterBinding;
20e172a3fc23412ebc79d6bd93e6d43d4b1c58354bXavier Ducrohetimport com.android.ide.common.rendering.api.DataBindingItem;
21e172a3fc23412ebc79d6bd93e6d43d4b1c58354bXavier Ducrohetimport com.android.ide.common.rendering.api.IProjectCallback;
22e172a3fc23412ebc79d6bd93e6d43d4b1c58354bXavier Ducrohetimport com.android.ide.common.rendering.api.ResourceReference;
23e172a3fc23412ebc79d6bd93e6d43d4b1c58354bXavier Ducrohet
24e172a3fc23412ebc79d6bd93e6d43d4b1c58354bXavier Ducrohetimport android.view.View;
25e172a3fc23412ebc79d6bd93e6d43d4b1c58354bXavier Ducrohetimport android.view.ViewGroup;
26e172a3fc23412ebc79d6bd93e6d43d4b1c58354bXavier Ducrohetimport android.widget.ExpandableListAdapter;
27e172a3fc23412ebc79d6bd93e6d43d4b1c58354bXavier Ducrohetimport android.widget.HeterogeneousExpandableList;
28e172a3fc23412ebc79d6bd93e6d43d4b1c58354bXavier Ducrohet
29e172a3fc23412ebc79d6bd93e6d43d4b1c58354bXavier Ducrohetimport java.util.ArrayList;
30e172a3fc23412ebc79d6bd93e6d43d4b1c58354bXavier Ducrohetimport java.util.List;
31e172a3fc23412ebc79d6bd93e6d43d4b1c58354bXavier Ducrohet
32e172a3fc23412ebc79d6bd93e6d43d4b1c58354bXavier Ducrohetpublic class FakeExpandableAdapter extends BaseAdapter implements ExpandableListAdapter,
33e172a3fc23412ebc79d6bd93e6d43d4b1c58354bXavier Ducrohet        HeterogeneousExpandableList {
34e172a3fc23412ebc79d6bd93e6d43d4b1c58354bXavier Ducrohet
35e172a3fc23412ebc79d6bd93e6d43d4b1c58354bXavier Ducrohet    // don't use a set because the order is important.
36e172a3fc23412ebc79d6bd93e6d43d4b1c58354bXavier Ducrohet    private final List<ResourceReference> mGroupTypes = new ArrayList<ResourceReference>();
37e172a3fc23412ebc79d6bd93e6d43d4b1c58354bXavier Ducrohet    private final List<ResourceReference> mChildrenTypes = new ArrayList<ResourceReference>();
38e172a3fc23412ebc79d6bd93e6d43d4b1c58354bXavier Ducrohet
39e172a3fc23412ebc79d6bd93e6d43d4b1c58354bXavier Ducrohet    public FakeExpandableAdapter(ResourceReference adapterRef, AdapterBinding binding,
40e172a3fc23412ebc79d6bd93e6d43d4b1c58354bXavier Ducrohet            IProjectCallback callback) {
41e172a3fc23412ebc79d6bd93e6d43d4b1c58354bXavier Ducrohet        super(adapterRef, binding, callback);
42e172a3fc23412ebc79d6bd93e6d43d4b1c58354bXavier Ducrohet
43e172a3fc23412ebc79d6bd93e6d43d4b1c58354bXavier Ducrohet        createItems(binding, binding.getItemCount(), binding.getRepeatCount(), mGroupTypes, 1);
44e172a3fc23412ebc79d6bd93e6d43d4b1c58354bXavier Ducrohet    }
45e172a3fc23412ebc79d6bd93e6d43d4b1c58354bXavier Ducrohet
46e172a3fc23412ebc79d6bd93e6d43d4b1c58354bXavier Ducrohet    private void createItems(Iterable<DataBindingItem> iterable, final int itemCount,
47e172a3fc23412ebc79d6bd93e6d43d4b1c58354bXavier Ducrohet            final int repeatCount, List<ResourceReference> types, int depth) {
48e172a3fc23412ebc79d6bd93e6d43d4b1c58354bXavier Ducrohet        // Need an array to count for each type.
49e172a3fc23412ebc79d6bd93e6d43d4b1c58354bXavier Ducrohet        // This is likely too big, but is the max it can be.
50e172a3fc23412ebc79d6bd93e6d43d4b1c58354bXavier Ducrohet        int[] typeCount = new int[itemCount];
51e172a3fc23412ebc79d6bd93e6d43d4b1c58354bXavier Ducrohet
52e172a3fc23412ebc79d6bd93e6d43d4b1c58354bXavier Ducrohet        // we put several repeating sets.
53e172a3fc23412ebc79d6bd93e6d43d4b1c58354bXavier Ducrohet        for (int r = 0 ; r < repeatCount ; r++) {
54e172a3fc23412ebc79d6bd93e6d43d4b1c58354bXavier Ducrohet            // loop on the type of list items, and add however many for each type.
55e172a3fc23412ebc79d6bd93e6d43d4b1c58354bXavier Ducrohet            for (DataBindingItem dataBindingItem : iterable) {
56e172a3fc23412ebc79d6bd93e6d43d4b1c58354bXavier Ducrohet                ResourceReference viewRef = dataBindingItem.getViewReference();
57e172a3fc23412ebc79d6bd93e6d43d4b1c58354bXavier Ducrohet                int typeIndex = types.indexOf(viewRef);
58e172a3fc23412ebc79d6bd93e6d43d4b1c58354bXavier Ducrohet                if (typeIndex == -1) {
59e172a3fc23412ebc79d6bd93e6d43d4b1c58354bXavier Ducrohet                    typeIndex = types.size();
60e172a3fc23412ebc79d6bd93e6d43d4b1c58354bXavier Ducrohet                    types.add(viewRef);
61e172a3fc23412ebc79d6bd93e6d43d4b1c58354bXavier Ducrohet                }
62e172a3fc23412ebc79d6bd93e6d43d4b1c58354bXavier Ducrohet
63e172a3fc23412ebc79d6bd93e6d43d4b1c58354bXavier Ducrohet                List<DataBindingItem> children = dataBindingItem.getChildren();
64e172a3fc23412ebc79d6bd93e6d43d4b1c58354bXavier Ducrohet                int count = dataBindingItem.getCount();
65e172a3fc23412ebc79d6bd93e6d43d4b1c58354bXavier Ducrohet
66e172a3fc23412ebc79d6bd93e6d43d4b1c58354bXavier Ducrohet                // if there are children, we use the count as a repeat count for the children.
67e172a3fc23412ebc79d6bd93e6d43d4b1c58354bXavier Ducrohet                if (children.size() > 0) {
68e172a3fc23412ebc79d6bd93e6d43d4b1c58354bXavier Ducrohet                    count = 1;
69e172a3fc23412ebc79d6bd93e6d43d4b1c58354bXavier Ducrohet                }
70e172a3fc23412ebc79d6bd93e6d43d4b1c58354bXavier Ducrohet
71e172a3fc23412ebc79d6bd93e6d43d4b1c58354bXavier Ducrohet                int index = typeCount[typeIndex];
72e172a3fc23412ebc79d6bd93e6d43d4b1c58354bXavier Ducrohet                typeCount[typeIndex] += count;
73e172a3fc23412ebc79d6bd93e6d43d4b1c58354bXavier Ducrohet
74e172a3fc23412ebc79d6bd93e6d43d4b1c58354bXavier Ducrohet                for (int k = 0 ; k < count ; k++) {
75e172a3fc23412ebc79d6bd93e6d43d4b1c58354bXavier Ducrohet                    AdapterItem item = new AdapterItem(dataBindingItem, typeIndex, mItems.size(),
76e172a3fc23412ebc79d6bd93e6d43d4b1c58354bXavier Ducrohet                            index++);
77e172a3fc23412ebc79d6bd93e6d43d4b1c58354bXavier Ducrohet                    mItems.add(item);
78e172a3fc23412ebc79d6bd93e6d43d4b1c58354bXavier Ducrohet
79e172a3fc23412ebc79d6bd93e6d43d4b1c58354bXavier Ducrohet                    if (children.size() > 0) {
80e172a3fc23412ebc79d6bd93e6d43d4b1c58354bXavier Ducrohet                        createItems(dataBindingItem, depth + 1);
81e172a3fc23412ebc79d6bd93e6d43d4b1c58354bXavier Ducrohet                    }
82e172a3fc23412ebc79d6bd93e6d43d4b1c58354bXavier Ducrohet                }
83e172a3fc23412ebc79d6bd93e6d43d4b1c58354bXavier Ducrohet            }
84e172a3fc23412ebc79d6bd93e6d43d4b1c58354bXavier Ducrohet        }
85e172a3fc23412ebc79d6bd93e6d43d4b1c58354bXavier Ducrohet    }
86e172a3fc23412ebc79d6bd93e6d43d4b1c58354bXavier Ducrohet
87e172a3fc23412ebc79d6bd93e6d43d4b1c58354bXavier Ducrohet    private void createItems(DataBindingItem item, int depth) {
88e172a3fc23412ebc79d6bd93e6d43d4b1c58354bXavier Ducrohet        if (depth == 2) {
89e172a3fc23412ebc79d6bd93e6d43d4b1c58354bXavier Ducrohet            createItems(item, item.getChildren().size(), item.getCount(), mChildrenTypes, depth);
90e172a3fc23412ebc79d6bd93e6d43d4b1c58354bXavier Ducrohet        }
91e172a3fc23412ebc79d6bd93e6d43d4b1c58354bXavier Ducrohet    }
92e172a3fc23412ebc79d6bd93e6d43d4b1c58354bXavier Ducrohet
93e172a3fc23412ebc79d6bd93e6d43d4b1c58354bXavier Ducrohet    private AdapterItem getChildItem(int groupPosition, int childPosition) {
94e172a3fc23412ebc79d6bd93e6d43d4b1c58354bXavier Ducrohet        AdapterItem item = mItems.get(groupPosition);
95e172a3fc23412ebc79d6bd93e6d43d4b1c58354bXavier Ducrohet
96e172a3fc23412ebc79d6bd93e6d43d4b1c58354bXavier Ducrohet        List<AdapterItem> children = item.getChildren();
97e172a3fc23412ebc79d6bd93e6d43d4b1c58354bXavier Ducrohet        return children.get(childPosition);
98e172a3fc23412ebc79d6bd93e6d43d4b1c58354bXavier Ducrohet    }
99e172a3fc23412ebc79d6bd93e6d43d4b1c58354bXavier Ducrohet
100e172a3fc23412ebc79d6bd93e6d43d4b1c58354bXavier Ducrohet    // ---- ExpandableListAdapter
101e172a3fc23412ebc79d6bd93e6d43d4b1c58354bXavier Ducrohet
102e172a3fc23412ebc79d6bd93e6d43d4b1c58354bXavier Ducrohet    public int getGroupCount() {
103e172a3fc23412ebc79d6bd93e6d43d4b1c58354bXavier Ducrohet        return mItems.size();
104e172a3fc23412ebc79d6bd93e6d43d4b1c58354bXavier Ducrohet    }
105e172a3fc23412ebc79d6bd93e6d43d4b1c58354bXavier Ducrohet
106e172a3fc23412ebc79d6bd93e6d43d4b1c58354bXavier Ducrohet    public int getChildrenCount(int groupPosition) {
107e172a3fc23412ebc79d6bd93e6d43d4b1c58354bXavier Ducrohet        AdapterItem item = mItems.get(groupPosition);
108e172a3fc23412ebc79d6bd93e6d43d4b1c58354bXavier Ducrohet        return item.getChildren().size();
109e172a3fc23412ebc79d6bd93e6d43d4b1c58354bXavier Ducrohet    }
110e172a3fc23412ebc79d6bd93e6d43d4b1c58354bXavier Ducrohet
111e172a3fc23412ebc79d6bd93e6d43d4b1c58354bXavier Ducrohet    public Object getGroup(int groupPosition) {
112e172a3fc23412ebc79d6bd93e6d43d4b1c58354bXavier Ducrohet        return mItems.get(groupPosition);
113e172a3fc23412ebc79d6bd93e6d43d4b1c58354bXavier Ducrohet    }
114e172a3fc23412ebc79d6bd93e6d43d4b1c58354bXavier Ducrohet
115e172a3fc23412ebc79d6bd93e6d43d4b1c58354bXavier Ducrohet    public Object getChild(int groupPosition, int childPosition) {
116e172a3fc23412ebc79d6bd93e6d43d4b1c58354bXavier Ducrohet        return getChildItem(groupPosition, childPosition);
117e172a3fc23412ebc79d6bd93e6d43d4b1c58354bXavier Ducrohet    }
118e172a3fc23412ebc79d6bd93e6d43d4b1c58354bXavier Ducrohet
119e172a3fc23412ebc79d6bd93e6d43d4b1c58354bXavier Ducrohet    public View getGroupView(int groupPosition, boolean isExpanded, View convertView,
120e172a3fc23412ebc79d6bd93e6d43d4b1c58354bXavier Ducrohet            ViewGroup parent) {
121e172a3fc23412ebc79d6bd93e6d43d4b1c58354bXavier Ducrohet        // we don't care about recycling here because we never scroll.
122e172a3fc23412ebc79d6bd93e6d43d4b1c58354bXavier Ducrohet        AdapterItem item = mItems.get(groupPosition);
123e172a3fc23412ebc79d6bd93e6d43d4b1c58354bXavier Ducrohet        return getView(item, null /*parentItem*/, convertView, parent);
124e172a3fc23412ebc79d6bd93e6d43d4b1c58354bXavier Ducrohet    }
125e172a3fc23412ebc79d6bd93e6d43d4b1c58354bXavier Ducrohet
126e172a3fc23412ebc79d6bd93e6d43d4b1c58354bXavier Ducrohet    public View getChildView(int groupPosition, int childPosition, boolean isLastChild,
127e172a3fc23412ebc79d6bd93e6d43d4b1c58354bXavier Ducrohet            View convertView, ViewGroup parent) {
128e172a3fc23412ebc79d6bd93e6d43d4b1c58354bXavier Ducrohet        // we don't care about recycling here because we never scroll.
129e172a3fc23412ebc79d6bd93e6d43d4b1c58354bXavier Ducrohet        AdapterItem parentItem = mItems.get(groupPosition);
130e172a3fc23412ebc79d6bd93e6d43d4b1c58354bXavier Ducrohet        AdapterItem item = getChildItem(groupPosition, childPosition);
131e172a3fc23412ebc79d6bd93e6d43d4b1c58354bXavier Ducrohet        return getView(item, parentItem, convertView, parent);
132e172a3fc23412ebc79d6bd93e6d43d4b1c58354bXavier Ducrohet    }
133e172a3fc23412ebc79d6bd93e6d43d4b1c58354bXavier Ducrohet
134e172a3fc23412ebc79d6bd93e6d43d4b1c58354bXavier Ducrohet    public long getGroupId(int groupPosition) {
135e172a3fc23412ebc79d6bd93e6d43d4b1c58354bXavier Ducrohet        return groupPosition;
136e172a3fc23412ebc79d6bd93e6d43d4b1c58354bXavier Ducrohet    }
137e172a3fc23412ebc79d6bd93e6d43d4b1c58354bXavier Ducrohet
138e172a3fc23412ebc79d6bd93e6d43d4b1c58354bXavier Ducrohet    public long getChildId(int groupPosition, int childPosition) {
139e172a3fc23412ebc79d6bd93e6d43d4b1c58354bXavier Ducrohet        return childPosition;
140e172a3fc23412ebc79d6bd93e6d43d4b1c58354bXavier Ducrohet    }
141e172a3fc23412ebc79d6bd93e6d43d4b1c58354bXavier Ducrohet
142e172a3fc23412ebc79d6bd93e6d43d4b1c58354bXavier Ducrohet    public long getCombinedGroupId(long groupId) {
143e172a3fc23412ebc79d6bd93e6d43d4b1c58354bXavier Ducrohet        return groupId << 16 | 0x0000FFFF;
144e172a3fc23412ebc79d6bd93e6d43d4b1c58354bXavier Ducrohet    }
145e172a3fc23412ebc79d6bd93e6d43d4b1c58354bXavier Ducrohet
146e172a3fc23412ebc79d6bd93e6d43d4b1c58354bXavier Ducrohet    public long getCombinedChildId(long groupId, long childId) {
147e172a3fc23412ebc79d6bd93e6d43d4b1c58354bXavier Ducrohet        return groupId << 16 | childId;
148e172a3fc23412ebc79d6bd93e6d43d4b1c58354bXavier Ducrohet    }
149e172a3fc23412ebc79d6bd93e6d43d4b1c58354bXavier Ducrohet
150e172a3fc23412ebc79d6bd93e6d43d4b1c58354bXavier Ducrohet    public boolean isChildSelectable(int groupPosition, int childPosition) {
151e172a3fc23412ebc79d6bd93e6d43d4b1c58354bXavier Ducrohet        return true;
152e172a3fc23412ebc79d6bd93e6d43d4b1c58354bXavier Ducrohet    }
153e172a3fc23412ebc79d6bd93e6d43d4b1c58354bXavier Ducrohet
154e172a3fc23412ebc79d6bd93e6d43d4b1c58354bXavier Ducrohet    public void onGroupCollapsed(int groupPosition) {
155e172a3fc23412ebc79d6bd93e6d43d4b1c58354bXavier Ducrohet        // pass
156e172a3fc23412ebc79d6bd93e6d43d4b1c58354bXavier Ducrohet    }
157e172a3fc23412ebc79d6bd93e6d43d4b1c58354bXavier Ducrohet
158e172a3fc23412ebc79d6bd93e6d43d4b1c58354bXavier Ducrohet    public void onGroupExpanded(int groupPosition) {
159e172a3fc23412ebc79d6bd93e6d43d4b1c58354bXavier Ducrohet        // pass
160e172a3fc23412ebc79d6bd93e6d43d4b1c58354bXavier Ducrohet    }
161e172a3fc23412ebc79d6bd93e6d43d4b1c58354bXavier Ducrohet
162e172a3fc23412ebc79d6bd93e6d43d4b1c58354bXavier Ducrohet    // ---- HeterogeneousExpandableList
163e172a3fc23412ebc79d6bd93e6d43d4b1c58354bXavier Ducrohet
164e172a3fc23412ebc79d6bd93e6d43d4b1c58354bXavier Ducrohet    public int getChildType(int groupPosition, int childPosition) {
165e172a3fc23412ebc79d6bd93e6d43d4b1c58354bXavier Ducrohet        return getChildItem(groupPosition, childPosition).getType();
166e172a3fc23412ebc79d6bd93e6d43d4b1c58354bXavier Ducrohet    }
167e172a3fc23412ebc79d6bd93e6d43d4b1c58354bXavier Ducrohet
168e172a3fc23412ebc79d6bd93e6d43d4b1c58354bXavier Ducrohet    public int getChildTypeCount() {
169e172a3fc23412ebc79d6bd93e6d43d4b1c58354bXavier Ducrohet        return mChildrenTypes.size();
170e172a3fc23412ebc79d6bd93e6d43d4b1c58354bXavier Ducrohet    }
171e172a3fc23412ebc79d6bd93e6d43d4b1c58354bXavier Ducrohet
172e172a3fc23412ebc79d6bd93e6d43d4b1c58354bXavier Ducrohet    public int getGroupType(int groupPosition) {
173e172a3fc23412ebc79d6bd93e6d43d4b1c58354bXavier Ducrohet        return mItems.get(groupPosition).getType();
174e172a3fc23412ebc79d6bd93e6d43d4b1c58354bXavier Ducrohet    }
175e172a3fc23412ebc79d6bd93e6d43d4b1c58354bXavier Ducrohet
176e172a3fc23412ebc79d6bd93e6d43d4b1c58354bXavier Ducrohet    public int getGroupTypeCount() {
177e172a3fc23412ebc79d6bd93e6d43d4b1c58354bXavier Ducrohet        return mGroupTypes.size();
178e172a3fc23412ebc79d6bd93e6d43d4b1c58354bXavier Ducrohet    }
179e172a3fc23412ebc79d6bd93e6d43d4b1c58354bXavier Ducrohet}
180