• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2012 AndroidPlot.com
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 
17 package com.androidplot.ui;
18 
19 import android.graphics.RectF;
20 
21 import java.util.Iterator;
22 
23 /**
24  * Encapsulates the visual aspects of a table; number of rows and columns
25  * and the height and width in pixels of each element within the table.
26  * There is no support (yet) for variable size cells within a table;  all
27  * cells within a table share the same dimensions.
28  *
29  * The DynamicTableModel provides an Iterator implementation which returns a RectF
30  * of each subsequent cell, based on the order of the plot.  Tables with
31  * an order of COLUMN_MAJOR are traversed left to right column by column until
32  * the end of the row is reached, then proceeding to the next row.
33  * Tables with an order of ROW_MAJOR are traversed top to bottom row by row
34  * until the end of the row is reached, then proceeding to the next column.
35  */
36 public class DynamicTableModel extends TableModel {
37 
38     //private float cellWidth;
39     //private float cellHeight;
40     //private TableSizingMethod rowSizingMethod;
41     //private TableSizingMethod columnSizingMethod;
42 
43 
44     private int numRows;
45     private int numColumns;
46 
47     private Float cellWidth;
48     private Float cellHeight;
49 
50     private CellSizingMethod rowSizingMethod;
51     private CellSizingMethod columnSizingMethod;
52 
53     /**
54      * Convenience method.  Sets order to ROW_MAJOR.
55      * @param numColumns
56      * @param numRows
57      */
DynamicTableModel(int numColumns, int numRows)58     public DynamicTableModel(int numColumns, int numRows) {
59         this(numColumns, numRows, TableOrder.ROW_MAJOR);
60 
61     }
62 
DynamicTableModel(int numColumns, int numRows, TableOrder order)63     public DynamicTableModel(int numColumns, int numRows, TableOrder order) {
64         super(order);
65         this.numColumns = numColumns;
66         //this.cellWidth = cellWidth;
67         //this.rowSizingMethod = rowSizingMethod;
68         this.numRows = numRows;
69         //this.cellHeight = cellHeight;
70         //this.columnSizingMethod = columnSizingMethod;
71         //this.order = order;
72     }
73 
74     /*public DynamicTableModel(Number colVal, CellSizingMethod colSzMethod, Number rowVal, CellSizingMethod rowSzMethod, TableOrder order) {
75         if(colVal == null || rowVal == null) {
76             throw new NullPointerException();
77         }
78         columnSizingMethod = colSzMethod;
79         switch(columnSizingMethod) {
80             case FILL:
81                 numColumns = colVal.intValue();
82                 break;
83             case FIXED:
84                 cellWidth = colVal.floatValue();
85                 break;
86         }
87         rowSzMethod = rowSzMethod;
88     }*/
89 
90     @Override
getIterator(RectF tableRect, int totalElements)91     public TableModelIterator getIterator(RectF tableRect, int totalElements) {
92         return new TableModelIterator(this, tableRect, totalElements);
93     }
94 
95     /**
96      * Calculates the dimensions of a single element of this table with
97      * tableRect representing the overall dimensions of the table.
98      * @param tableRect Dimensions/position of the table
99      * @return a RectF representing the first (top-left) element in
100      * the tableRect passed in.
101      */
getCellRect(RectF tableRect, int numElements)102     public RectF getCellRect(RectF tableRect, int numElements) {
103         RectF cellRect = new RectF();
104         cellRect.left = tableRect.left;
105         cellRect.top = tableRect.top;
106         //cellRect.bottom = getElementHeightPix(tableRect);
107         cellRect.bottom = tableRect.top + calculateCellSize(tableRect, TableModel.Axis.ROW, numElements);
108         //cellRect.right = getElementWidthPix(tableRect);
109         cellRect.right = tableRect.left + calculateCellSize(tableRect, TableModel.Axis.COLUMN, numElements);
110         return cellRect;
111     }
112 
113     /**
114      * Figure out the size of a single cell across the specified axis.
115      * @param tableRect
116      * @param axis
117      * @param numElementsInTable
118      * @return
119      */
calculateCellSize(RectF tableRect, Axis axis, int numElementsInTable)120     private float calculateCellSize(RectF tableRect,
121                                     Axis axis,
122                                     int numElementsInTable) {
123         //float elementSizeInPix = 0;
124         int axisElements = 0;
125 
126         float axisSizePix = 0;
127         switch (axis) {
128             case ROW:
129                 //elementSizeInPix = cellHeight;
130                 axisElements = numRows;
131                 axisSizePix = tableRect.height();
132                 break;
133             case COLUMN:
134                 //elementSizeInPix = cellWidth;
135                 axisElements = numColumns;
136                 axisSizePix = tableRect.width();
137                 break;
138         }
139         //if (elementSizeInPix != 0) {
140         //    return elementSizeInPix;
141         if(axisElements != 0) {
142             return axisSizePix / axisElements;
143         } else {
144             return axisSizePix / numElementsInTable;
145         }
146     }
147 
148 
149 
getNumRows()150     public int getNumRows() {
151         return numRows;
152     }
153 
setNumRows(int numRows)154     public void setNumRows(int numRows) {
155         this.numRows = numRows;
156     }
157 
getNumColumns()158     public int getNumColumns() {
159         return numColumns;
160     }
161 
setNumColumns(int numColumns)162     public void setNumColumns(int numColumns) {
163         this.numColumns = numColumns;
164     }
165 
166 /*    public void setCellWidth(Float cellWidth) {
167         this.cellWidth = cellWidth;
168     }
169 
170     public Float getCellWidth() {
171         return cellWidth;
172     }
173 
174     public Float getCellHeight() {
175         return cellHeight;
176     }
177 
178     public void setCellHeight(Float cellHeight) {
179         this.cellHeight = cellHeight;
180     }*/
181 
182     private class TableModelIterator implements Iterator<RectF> {
183         private boolean isOk = true;
184         int lastColumn = 0;                     // most recent column iterated
185         int lastRow = 0;                        // most recent row iterated
186         int lastElement = 0;                    // last element index iterated
187         private DynamicTableModel dynamicTableModel;
188         private RectF tableRect;
189         private RectF lastElementRect;
190         private int totalElements;
191         private TableOrder order;
192 
193         private int calculatedNumElements;
194         private int calculatedRows;             // number of rows to be iterated
195         private int calculatedColumns;          // number of columns to be iterated
196 
TableModelIterator(DynamicTableModel dynamicTableModel, RectF tableRect, int totalElements)197         public TableModelIterator(DynamicTableModel dynamicTableModel, RectF tableRect, int totalElements) {
198             this.dynamicTableModel = dynamicTableModel;
199             this.tableRect = tableRect;
200             this.totalElements = totalElements;
201             order = dynamicTableModel.getOrder();
202 
203             // unlimited columns:
204             if(dynamicTableModel.getNumColumns() == 0 && dynamicTableModel.getNumRows() >= 1) {
205                 calculatedRows = dynamicTableModel.getNumRows();
206 
207                 // round up:
208                 calculatedColumns = new Float((totalElements / (float) calculatedRows) + 0.5).intValue();
209             } else if(dynamicTableModel.getNumRows() == 0 && dynamicTableModel.getNumColumns() >= 1) {
210                 //order = TableOrder.ROW_MAJOR;
211                 calculatedColumns = dynamicTableModel.getNumColumns();
212                 calculatedRows = new Float((totalElements / (float) calculatedColumns) + 0.5).intValue();
213             // unlimited rows and columns (impossible) so default a single row with n columns:
214             }else if(dynamicTableModel.getNumColumns() == 0 && dynamicTableModel.getNumRows() == 0) {
215                 calculatedRows = 1;
216                 calculatedColumns = totalElements;
217             } else {
218                 //order = dynamicTableModel.getOrder();
219                 calculatedRows = dynamicTableModel.getNumRows();
220                 calculatedColumns = dynamicTableModel.getNumColumns();
221             }
222             calculatedNumElements = calculatedRows * calculatedColumns;
223             lastElementRect = dynamicTableModel.getCellRect(tableRect, totalElements);
224         }
225 
226         @Override
hasNext()227         public boolean hasNext() {
228             return isOk && lastElement < calculatedNumElements;
229         }
230 
231         @Override
next()232         public RectF next() {
233             if(!hasNext()) {
234                 isOk = false;
235                 throw new IndexOutOfBoundsException();
236             }
237 
238             if (lastElement == 0) {
239                 lastElement++;
240                 return lastElementRect;
241             }
242 
243             RectF nextElementRect = new RectF(lastElementRect);
244 
245             switch (order) {
246                 case ROW_MAJOR:
247                     if (dynamicTableModel.getNumColumns() > 0 && lastColumn >= (dynamicTableModel.getNumColumns() - 1)) {
248                         // move to the begining of the next row down:// move to the begining of the next row down:
249                         nextElementRect.offsetTo(tableRect.left, lastElementRect.bottom);
250                         lastColumn = 0;
251                         lastRow++;
252                     } else {
253                         // move to the next column over:
254                         nextElementRect.offsetTo(lastElementRect.right, lastElementRect.top);
255                         lastColumn++;
256                     }
257                     break;
258                 case COLUMN_MAJOR:
259                     if (dynamicTableModel.getNumRows() > 0 && lastRow >= (dynamicTableModel.getNumRows() - 1)) {
260                         // move to the top of the next column over:
261                         nextElementRect.offsetTo(lastElementRect.right, tableRect.top);
262                         lastRow = 0;
263                         lastColumn++;
264                     } else {
265                         // move to the next row down:
266                         nextElementRect.offsetTo(lastElementRect.left, lastElementRect.bottom);
267                         lastRow++;
268                     }
269                     break;
270                 // unknown/unsupported enum val:
271                 default:
272                     isOk = false;
273                     throw new IllegalArgumentException();
274             }
275             lastElement++;
276             lastElementRect = nextElementRect;
277             return nextElementRect;
278 
279         }
280 
281         @Override
remove()282         public void remove() {
283             throw new UnsupportedOperationException();
284         }
285     }
286 }
287