1 package org.coolreader.crengine; 2 3 import android.database.DataSetObserver; 4 import android.os.Bundle; 5 import android.view.LayoutInflater; 6 import android.view.View; 7 import android.view.ViewGroup; 8 import android.widget.BaseAdapter; 9 import android.widget.ImageView; 10 import android.widget.ListView; 11 import android.widget.TextView; 12 13 import org.coolreader.R; 14 15 import java.util.ArrayList; 16 17 public class TOCDlg extends BaseDialog { 18 //CoolReader mCoolReader; 19 ReaderView mReaderView; 20 TOCItem mTOC; 21 ListView mListView; 22 int mCurrentPage; 23 TOCItem mCurrentPageItem; 24 ArrayList<TOCItem> mItems = new ArrayList<>(); 25 private LayoutInflater mInflater; 26 initItems( TOCItem toc, boolean expanded )27 private void initItems( TOCItem toc, boolean expanded ) 28 { 29 for ( int i=0; i<toc.getChildCount(); i++ ) { 30 TOCItem child = toc.getChild(i); 31 if ( child.getPage()<=mCurrentPage ) 32 mCurrentPageItem = child; 33 if ( expanded ) { 34 child.setGlobalIndex(mItems.size()); 35 mItems.add(child); 36 } else { 37 child.setGlobalIndex(-1); // invisible 38 } 39 initItems(child, expanded && child.getExpanded()); 40 } 41 } initItems()42 private void initItems() 43 { 44 mCurrentPageItem = null; 45 mItems.clear(); 46 initItems(mTOC, true); 47 } 48 expand( TOCItem item )49 private void expand( TOCItem item ) 50 { 51 if ( item==null ) 52 return; 53 item.setExpanded(true); 54 // expand all parents 55 for ( TOCItem p = item.getParent(); p!=null; p = p.getParent() ) 56 p.setExpanded(true); 57 initItems(); 58 refreshList(); 59 if ( mItems.size()>0 ) { 60 if ( item.getGlobalIndex()>=0 ) { 61 mListView.setSelection(item.getGlobalIndex()); 62 mListView.setSelectionFromTop(item.getGlobalIndex(), mListView.getHeight()/2); 63 } else 64 mListView.setSelection(0); 65 } 66 } 67 collapse( TOCItem item )68 private void collapse( TOCItem item ) 69 { 70 item.setExpanded(false); 71 initItems(); 72 refreshList(); 73 } 74 refreshList()75 private void refreshList() 76 { 77 mListView.setAdapter(new BaseAdapter() { 78 public boolean areAllItemsEnabled() { 79 return true; 80 } 81 82 public boolean isEnabled(int arg0) { 83 return true; 84 } 85 86 public int getCount() { 87 return mItems.size(); 88 } 89 90 public Object getItem(int position) { 91 return mItems.get(position); 92 } 93 94 public long getItemId(int position) { 95 return position; 96 } 97 98 public int getItemViewType(int position) { 99 TOCItem item = mItems.get(position); 100 boolean isCurrentItem = item==mCurrentPageItem; 101 return isCurrentItem ? 0 : 1; 102 } 103 104 105 public View getView(int position, View convertView, ViewGroup parent) { 106 View view; 107 TOCItem item = mItems.get(position); 108 boolean isCurrentItem = item==mCurrentPageItem; 109 if ( convertView==null ) { 110 //view = new TextView(getContext()); 111 view = mInflater.inflate(isCurrentItem ? R.layout.toc_item_current : R.layout.toc_item, null); 112 } else { 113 view = convertView; 114 } 115 TextView pageTextView = view.findViewById(R.id.toc_page); 116 TextView titleTextView = view.findViewById(R.id.toc_title); 117 TextView marginTextView = view.findViewById(R.id.toc_level_margin); 118 ImageView expandImageView = view.findViewById(R.id.toc_expand_icon); 119 StringBuilder buf = new StringBuilder(item.getLevel()*2); 120 for ( int i=1; i<item.getLevel(); i++ ) 121 buf.append(" "); 122 if ( item.getChildCount()>0 ) { 123 if ( item.getExpanded() ) { 124 expandImageView.setImageResource(R.drawable.cr3_toc_item_expanded); 125 } else { 126 expandImageView.setImageResource(R.drawable.cr3_toc_item_collapsed); 127 } 128 } else { 129 expandImageView.setImageResource(R.drawable.cr3_toc_item_normal); 130 } 131 marginTextView.setText(buf.toString()); 132 titleTextView.setText(item.getName()); 133 pageTextView.setText(String.valueOf(item.getPage()+1)); 134 return view; 135 } 136 137 public int getViewTypeCount() { 138 return 2; 139 } 140 141 public boolean hasStableIds() { 142 return true; 143 } 144 145 public boolean isEmpty() { 146 return false; 147 } 148 149 private ArrayList<DataSetObserver> observers = new ArrayList<>(); 150 151 public void registerDataSetObserver(DataSetObserver observer) { 152 observers.add(observer); 153 } 154 155 public void unregisterDataSetObserver(DataSetObserver observer) { 156 observers.remove(observer); 157 } 158 }); 159 } 160 TOCDlg(BaseActivity coolReader, ReaderView readerView, TOCItem toc, int currentPage )161 public TOCDlg(BaseActivity coolReader, ReaderView readerView, TOCItem toc, int currentPage ) 162 { 163 super(coolReader, coolReader.getResources().getString(R.string.win_title_toc), false, false); 164 setCancelable(true); 165 // this.mCoolReader = coolReader; 166 this.mReaderView = readerView; 167 this.mTOC = toc; 168 this.mCurrentPage = currentPage; 169 this.mListView = new BaseListView(getContext(), true); 170 mListView.setOnItemClickListener((listview, view, position, id) -> { 171 TOCItem item = mItems.get(position); 172 if ( item.getChildCount()==0 || item.getExpanded() ) { 173 mReaderView.goToPage(item.getPage()+1); 174 dismiss(); 175 } else { 176 expand(item); 177 } 178 }); 179 mListView.setOnItemLongClickListener((listview, view, position, id) -> { 180 TOCItem item = mItems.get(position); 181 if ( item.getChildCount()==0 ) { 182 mReaderView.goToPage(item.getPage()+1); 183 dismiss(); 184 } else { 185 if ( item.getExpanded() ) 186 collapse(item); 187 else 188 expand(item); 189 } 190 return true; 191 }); 192 mListView.setLongClickable(true); 193 mListView.setClickable(true); 194 mListView.setFocusable(true); 195 mListView.setFocusableInTouchMode(true); 196 mListView.setChoiceMode(ListView.CHOICE_MODE_SINGLE); 197 setView(mListView); 198 // cancel 199 // 200 setFlingHandlers(mListView, TOCDlg.this::dismiss, TOCDlg.this::dismiss); 201 } 202 203 @Override onCreate(Bundle savedInstanceState)204 protected void onCreate(Bundle savedInstanceState) { 205 mInflater = LayoutInflater.from(getContext()); 206 super.onCreate(savedInstanceState); 207 expand( mTOC ); 208 expand( mCurrentPageItem ); 209 } 210 } 211