2 * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
3 * Copyright (C) $$Year-Rel$$ The Jalview Authors
5 * This file is part of Jalview.
7 * Jalview is free software: you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation, either version 3
10 * of the License, or (at your option) any later version.
12 * Jalview is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty
14 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15 * PURPOSE. See the GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with Jalview. If not, see <http://www.gnu.org/licenses/>.
19 * The Jalview Authors are detailed in the 'AUTHORS' file.
21 package jalview.datamodel;
23 import java.util.ArrayList;
24 import java.util.List;
26 public class HiddenColumnsCursor
28 // absolute position of first hidden column
29 private int firstColumn;
31 private List<int[]> hiddenColumns = new ArrayList<>();
33 private HiddenCursorPosition cursorPos = new HiddenCursorPosition(0, 0);
35 protected HiddenColumnsCursor()
40 protected HiddenColumnsCursor(List<int[]> hiddenCols)
42 resetCursor(hiddenCols, 0, 0);
45 protected HiddenColumnsCursor(List<int[]> hiddenCols, int index,
48 resetCursor(hiddenCols, index, hiddencount);
52 * Reset the cursor with a new hidden columns collection, where we know in
53 * advance the index and hidden columns count of a particular location.
56 * new hidden columns collection
58 * cursor index to reset to
60 * hidden columns count to reset to
62 private void resetCursor(List<int[]> hiddenCols, int index,
65 hiddenColumns = hiddenCols;
66 if (!hiddenCols.isEmpty())
68 firstColumn = hiddenColumns.get(0)[0];
69 cursorPos = new HiddenCursorPosition(index, hiddencount);
74 * Get the cursor pointing to the hidden region that column is within (if
75 * column is hidden) or which is to the right of column (if column is
76 * visible). If no hidden columns are to the right, returns a cursor pointing
77 * to an imaginary hidden region beyond the end of the hidden columns
78 * collection (this ensures the count of previous hidden columns is correct).
79 * If hidden columns is empty returns null.
82 * index of column in visible or absolute coordinates
84 * true if column is in visible coordinates, false if absolute
85 * @return cursor pointing to hidden region containing the column (if hidden)
86 * or to the right of the column (if visible)
88 protected HiddenCursorPosition findRegionForColumn(int column,
91 if (hiddenColumns.isEmpty())
96 // used to add in hiddenColumns offset when working with visible columns
97 int offset = (useVisible ? 1 : 0);
99 HiddenCursorPosition pos = cursorPos;
100 int index = pos.getRegionIndex();
101 int hiddenCount = pos.getHiddenSoFar();
103 if (column < firstColumn)
105 pos = new HiddenCursorPosition(0, 0);
108 // column is after current region
109 else if ((index < hiddenColumns.size())
110 && (hiddenColumns.get(index)[0] <= column
111 + offset * hiddenCount))
113 // iterate from where we are now, if we're lucky we'll be close by
114 // (but still better than iterating from 0)
115 // stop when we find the region *before* column
116 // i.e. the next region starts after column or if not, ends after column
117 pos = searchForward(pos, column, useVisible);
120 // column is before current region
123 pos = searchBackward(pos, column, useVisible);
130 * Search forwards through the hidden columns collection to find the hidden
131 * region immediately before a column
138 * whether using visible or absolute coordinates
139 * @return position of region before column
141 private HiddenCursorPosition searchForward(HiddenCursorPosition pos,
142 int column, boolean useVisible)
144 HiddenCursorPosition p = pos;
147 while ((p.getRegionIndex() < hiddenColumns.size())
148 && hiddenColumns.get(p.getRegionIndex())[0] <= column
149 + p.getHiddenSoFar())
156 while ((p.getRegionIndex() < hiddenColumns.size())
157 && hiddenColumns.get(p.getRegionIndex())[1] < column)
166 * Move to the next (rightwards) hidden region after a given cursor position
169 * current position of cursor
170 * @return new position of cursor at next region
172 private HiddenCursorPosition stepForward(HiddenCursorPosition p)
174 int[] region = hiddenColumns.get(p.getRegionIndex());
176 // increment the index, and add this region's hidden columns to the hidden
178 return new HiddenCursorPosition(p.getRegionIndex() + 1,
179 p.getHiddenSoFar() + region[1] - region[0] + 1);
183 * Search backwards through the hidden columns collection to find the hidden
184 * region immediately before (left of) a given column
191 * whether using visible or absolute coordinates
192 * @return position of region immediately to left of column
194 private HiddenCursorPosition searchBackward(HiddenCursorPosition p,
195 int column, boolean useVisible)
197 int i = p.getRegionIndex();
198 int h = p.getHiddenSoFar();
200 // used to add in hiddenColumns offset when working with visible columns
201 int offset = (useVisible ? 1 : 0);
203 while ((i > 0) && (hiddenColumns.get(i - 1)[1] >= column + offset * h))
206 int[] region = hiddenColumns.get(i);
207 h -= region[1] - region[0] + 1;
209 return new HiddenCursorPosition(i, h);