1/*
2 * Copyright (C) 2013 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 com.android.documentsui;
18
19import android.database.DataSetObserver;
20import android.view.View;
21import android.view.ViewGroup;
22import android.widget.BaseAdapter;
23import android.widget.LinearLayout;
24import android.widget.ListAdapter;
25import android.widget.ListView;
26
27import com.android.internal.util.Preconditions;
28
29/**
30 * Adapter that wraps an existing adapter, presenting its contents in multiple
31 * equally-sized horizontal columns.
32 */
33public class ColumnAdapter extends BaseAdapter {
34    private final ListAdapter mWrapped;
35    private final OnItemClickListener mListener;
36
37    private int mColumns = 1;
38
39    public interface OnItemClickListener {
40        public void onItemClick(ListAdapter adapter, int position);
41    }
42
43    public ColumnAdapter(ListAdapter wrapped, OnItemClickListener listener) {
44        mWrapped = Preconditions.checkNotNull(wrapped);
45        mListener = Preconditions.checkNotNull(listener);
46
47        if (!wrapped.areAllItemsEnabled()) {
48            throw new IllegalStateException("All items must be enabled");
49        }
50        if (wrapped.getViewTypeCount() > 1) {
51            throw new IllegalStateException("All items must be identical");
52        }
53    }
54
55    public static void prepare(ListView list) {
56        list.setItemsCanFocus(true);
57    }
58
59    public void setColumns(int columns) {
60        mColumns = columns;
61        notifyDataSetChanged();
62    }
63
64    private View.OnClickListener mItemListener = new View.OnClickListener() {
65        @Override
66        public void onClick(View v) {
67            final int position = (Integer) v.getTag();
68            mListener.onItemClick(mWrapped, position);
69        }
70    };
71
72    @Override
73    public int getCount() {
74        return (mWrapped.getCount() + mColumns - 1) / mColumns;
75    }
76
77    @Override
78    public Object getItem(int position) {
79        return position;
80    }
81
82    @Override
83    public long getItemId(int position) {
84        return position;
85    }
86
87    @Override
88    public View getView(int position, View convertView, ViewGroup parent) {
89        if (convertView == null) {
90            convertView = new LinearLayout(parent.getContext());
91        }
92
93        final LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(
94                0, LinearLayout.LayoutParams.WRAP_CONTENT);
95        params.weight = 1f / mColumns;
96
97        final LinearLayout row = (LinearLayout) convertView;
98        final int first = position * mColumns;
99        final int last = mWrapped.getCount() - 1;
100
101        for (int i = 0; i < mColumns; i++) {
102            View convertItem = null;
103            if (i < row.getChildCount()) {
104                convertItem = row.getChildAt(i);
105            }
106
107            final int pos = first + i;
108            final int validPos = Math.min(pos, last);
109            final View item = mWrapped.getView(validPos, convertItem, row);
110            item.setTag(validPos);
111            item.setOnClickListener(mItemListener);
112            item.setFocusable(true);
113
114            if (pos == validPos) {
115                item.setVisibility(View.VISIBLE);
116            } else {
117                item.setVisibility(View.INVISIBLE);
118            }
119
120            if (convertItem == null) {
121                row.addView(item, params);
122            }
123        }
124
125        return convertView;
126    }
127
128    @Override
129    public void registerDataSetObserver(DataSetObserver observer) {
130        super.registerDataSetObserver(observer);
131        mWrapped.registerDataSetObserver(observer);
132    }
133
134    @Override
135    public void unregisterDataSetObserver(DataSetObserver observer) {
136        super.unregisterDataSetObserver(observer);
137        mWrapped.unregisterDataSetObserver(observer);
138    }
139}
140