package com.thirdparty;
import net.rim.device.api.ui.Field;
import net.rim.device.api.ui.Manager;
public class GridFieldManager extends Manager {
private int[] columnWidths;
private int columns;
private int allRowHeight = -1;
/**
* Constructs a new GridFieldManager with the specified number of columns.
* Rows will be added as needed to display fields. Fields will be added to
* the grid in the order they are added to this manager, filling up each row
* left-to-right:
*
* For example a 2 column manager:
*
* [Field1][Field2] [Field3][Field4] [Field5]
*
* There are two constructors available: In the first, Column widths are all
* equal, and the manager will attempt to use all available width. The
* height of each row will be equal to the height of the tallest Field in
* that row. Field positional styles are respected, so fields that are
* smaller than the row/column they are in can be positioned left, right,
* top bottom, or centered. They default to top left.
*
* @param columns
* Number of columns in the grid
* @param style
*
*
* @author modified 2010 by Arjun Dhar<br />
* @author modified 2009 by TBC Software http://www.vocshop.com
* @author Copyright 2008 by Anthony Rizk -
* http://www.thinkingblackberry.com
*/
public GridFieldManager(int columns, long style) {
super(style);
this.columns = columns;
}
/*
* In the second constructor, instead of passing a single int with the
* number of columns, an array of ints is passed with the width (in pixels)
* of each column. The grid will be constructed with as many columns as
* required to comply with the array, and the total width of the grid
* __MAY__ be wider than the screen. If so, the grid needs to be contained
* within a horizontally scrolling screen or manager.
*/
public GridFieldManager(int[] columnWidths, long style) {
super(style);
this.columnWidths = columnWidths;
this.columns = columnWidths.length;
}
public GridFieldManager(int[] columnWidths, int rowHeight, long style) {
this(columnWidths, style);
this.allRowHeight = rowHeight;
}
protected boolean navigationMovement(int dx, int dy, int status, int time) {
int focusIndex = getFieldWithFocusIndex();
/*
* in each while, after we have moved into the new field, update the
* display at top of screen right side of a row wraps to that row's
* left. Top wraps to the bottom, bottom wraps to the top. The default
* blackberry movement of "spiral down" using the right arrow or
* trackwheel is overridden.
*/
int lnFieldCount = getFieldCount();
while (dy > 0) {
focusIndex += columns;
if (focusIndex >= lnFieldCount) {
if (lnFieldCount > 0) {
// Wrap around to top row
getField(lnFieldCount - 1).setFocus();
return true;
} else {
return false; // Focus moves out of this manager
}
} else {
Field f = getField(focusIndex);
if (f.isFocusable()) { // Only move the focus onto focusable
// fields
f.setFocus();
dy--;
// UpdateDisplay();
}
}
}
while (dy < 0) {
focusIndex -= columns;
if (focusIndex < 0) {
// Wrap around to bottom row
getField(0).setFocus();
return true;
} else {
Field f = getField(focusIndex);
if (f.isFocusable()) {
f.setFocus();
dy++;
// UpdateDisplay();
}
}
}
while (dx > 0) {
if (focusIndex == lnFieldCount - 1) {
return false;
}
if ((focusIndex + 1) % columns == 0) {
// Wrap around to beginning of line or boundary
// focusIndex = (focusIndex-columns) + 1;
return false;
} else {
focusIndex++;
}
if (focusIndex >= lnFieldCount) {
if (lnFieldCount > 0) {
getField(1).setFocus();
return true;
} else {
return false; // Focus moves out of this manager
}
} else {
Field f = getField(focusIndex);
if (f.isFocusable()) {
f.setFocus();
dx--;
// UpdateDisplay();
}
}
}
while (dx < 0) {
if (focusIndex % columns == 0) {
// Wrap around to end of line Or Boundary
// focusIndex = (focusIndex+columns) -1;
return false;
} else {
focusIndex--;
}
if (focusIndex < 0) {
return false;
} else {
Field f = getField(focusIndex);
if (f.isFocusable()) {
f.setFocus();
dx++;
// UpdateDisplay();
}
}
}
return true;
}
protected void sublayout(int width, int height) {
int y = 0;
columnWidths = new int[columns];
for (int i = 0; i < columns; i++) {
columnWidths[i] = width / columns;
}
Field[] fields = new Field[columnWidths.length];
int currentColumn = 0;
int rowHeight = 0;
for (int i = 0; i < getFieldCount(); i++) {
fields[currentColumn] = getField(i);
layoutChild(fields[currentColumn], columnWidths[currentColumn],
height - y);
if (fields[currentColumn].getHeight() > rowHeight) {
rowHeight = fields[currentColumn].getHeight();
}
currentColumn++;
if (currentColumn == columnWidths.length
|| i == getFieldCount() - 1) {
int x = 0;
if (this.allRowHeight >= 0) {
rowHeight = this.allRowHeight;
}
for (int c = 0; c < currentColumn; c++) {
long fieldStyle = fields[c].getStyle();
int fieldXOffset = 0;
long fieldHalign = fieldStyle & Field.FIELD_HALIGN_MASK;
if (fieldHalign == Field.FIELD_RIGHT) {
fieldXOffset = columnWidths[c] - fields[c].getWidth();
} else if (fieldHalign == Field.FIELD_HCENTER) {
fieldXOffset = (columnWidths[c] - fields[c].getWidth()) / 2;
}
int fieldYOffset = 0;
long fieldValign = fieldStyle & Field.FIELD_VALIGN_MASK;
if (fieldValign == Field.FIELD_BOTTOM) {
fieldYOffset = rowHeight - fields[c].getHeight();
} else if (fieldValign == Field.FIELD_VCENTER) {
fieldYOffset = (rowHeight - fields[c].getHeight()) / 2;
}
setPositionChild(fields[c], x + fieldXOffset, y
+ fieldYOffset);
x += columnWidths[c];
}
currentColumn = 0;
y += rowHeight;
}
if (y >= height) {
break;
}
}
int totalWidth = 0;
for (int i = 0; i < columnWidths.length; i++) {
totalWidth += columnWidths[i];
}
setExtent(totalWidth, Math.min(y, height));
}
}