/* * Copyright (C) 2009-2011 Geometer Plus <contact@geometerplus.com> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA. */ package org.geometerplus.android.fbreader; import java.util.HashSet; import android.view.*; import android.widget.*; import org.geometerplus.zlibrary.core.tree.ZLTree; import org.geometerplus.zlibrary.ui.androidfly.R; abstract class ZLTreeAdapter extends BaseAdapter implements AdapterView.OnItemClickListener, View.OnCreateContextMenuListener { private final ListView myParent; private ZLTree<?> myTree; private ZLTree<?>[] myItems; private final HashSet<ZLTree<?>> myOpenItems = new HashSet<ZLTree<?>>(); protected ZLTreeAdapter(ListView parent, ZLTree<?> tree) { myParent = parent; myTree = tree; myItems = new ZLTree[tree.getSize() - 1]; myOpenItems.add(tree); parent.setAdapter(this); parent.setOnItemClickListener(this); parent.setOnCreateContextMenuListener(this); } protected final void openTree(ZLTree<?> tree) { if (tree == null) { return; } while (!myOpenItems.contains(tree)) { myOpenItems.add(tree); tree = tree.Parent; } } public final void expandOrCollapseTree(ZLTree<?> tree) { if (!tree.hasChildren()) { return; } if (isOpen(tree)) { myOpenItems.remove(tree); } else { myOpenItems.add(tree); } //myParent.invalidateViews(); //myParent.requestLayout(); notifyDataSetChanged(); } public final boolean isOpen(ZLTree<?> tree) { return myOpenItems.contains(tree); } public final void selectItem(ZLTree<?> tree) { if (tree == null) { return; } openTree(tree.Parent); int index = 0; while (true) { ZLTree<?> parent = tree.Parent; if (parent == null) { break; } for (ZLTree<?> sibling : parent.subTrees()) { if (sibling == tree) { break; } index += getCount(sibling); } tree = parent; ++index; } if (index > 0) { myParent.setSelection(index - 1); } } private int getCount(ZLTree<?> tree) { int count = 1; if (isOpen(tree)) { for (ZLTree<?> subtree : tree.subTrees()) { count += getCount(subtree); } } return count; } public final int getCount() { return getCount(myTree) - 1; } private final int indexByPosition(int position, ZLTree<?> tree) { if (position == 0) { return 0; } --position; int index = 1; for (ZLTree<?> subtree : tree.subTrees()) { int count = getCount(subtree); if (count <= position) { position -= count; index += subtree.getSize(); } else { return index + indexByPosition(position, subtree); } } throw new RuntimeException("That's impossible!!!"); } public final ZLTree<?> getItem(int position) { final int index = indexByPosition(position + 1, myTree) - 1; ZLTree<?> item = myItems[index]; if (item == null) { item = myTree.getTreeByParagraphNumber(index + 1); myItems[index] = item; } return item; } public final boolean areAllItemsEnabled() { return true; } public final boolean isEnabled(int position) { return true; } public final long getItemId(int position) { return indexByPosition(position + 1, myTree); } protected boolean runTreeItem(ZLTree<?> tree) { if (!tree.hasChildren()) { return false; } expandOrCollapseTree(tree); return true; } protected void resetTree(ZLTree<?> tree) { myTree = tree; myItems = new ZLTree[tree.getSize() - 1]; myOpenItems.clear(); myOpenItems.add(tree); //myParent.invalidateViews(); //myParent.requestLayout(); notifyDataSetChanged(); } public void resetTree() { myItems = new ZLTree[myTree.getSize() - 1]; //myParent.invalidateViews(); //myParent.requestLayout(); notifyDataSetChanged(); } public final void onItemClick(AdapterView<?> parent, View view, int position, long id) { runTreeItem(getItem(position)); } public void onCreateContextMenu(ContextMenu menu, View view, ContextMenu.ContextMenuInfo menuInfo) { } public abstract View getView(int position, View convertView, ViewGroup parent); protected final void setIcon(ImageView imageView, ZLTree<?> tree) { if (tree.hasChildren()) { if (isOpen(tree)) { imageView.setImageResource(R.drawable.ic_list_group_open); } else { imageView.setImageResource(R.drawable.ic_list_group_closed); } } else { imageView.setImageResource(R.drawable.ic_list_group_empty); } imageView.setPadding(25 * (tree.Level - 1), imageView.getPaddingTop(), 0, imageView.getPaddingBottom()); } }