package org.geogebra.web.web.gui.util;
import org.geogebra.common.gui.util.SelectionTable;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.user.client.ui.Grid;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.Widget;
public class SelectionTableW extends Grid implements ClickHandler {
private int selectedColumn = -1;
private int selectedRow = -1;
private SelectionTable mode;
private int numRows, numColumns;
private boolean isIniting = true;
private ImageOrText[] values;
private boolean isMultiselectionEnabled;
private boolean[] selecteditems;
/**
* @param data
* @param rows
* @param columns
* @param mode
*/
public SelectionTableW(ImageOrText[] data, Integer rows, Integer columns,
SelectionTable mode, boolean ms) {
this(data, rows, columns, mode);
isMultiselectionEnabled = ms;
}
/**
* @param data
* images / texts for the table
* @param rows0
* number of rows or -1 for auto
* @param columns0
* number of columns or -1 for auto
* @param mode
* image / text / latex
*/
public SelectionTableW(ImageOrText[] data, Integer rows0, Integer columns0,
SelectionTable mode) {
super();
this.mode = mode;
int rows = rows0;
int columns = columns0;
//=======================================
// determine the dimensions of the table
// rows = -1, cols = -1 ==> square table to fit data
if(rows == -1 && columns == -1){
rows = (int) Math.floor(Math.sqrt(data.length));
columns = (int) Math.ceil(data.length / (double) rows);
}
// rows = -1 ==> fixed cols, rows added to fit data
else if(rows == -1){
rows = (int) (Math.ceil(data.length / (double) columns));
}
// cols = -1 ==> fixed rows, cols added to fit data
else if(columns == -1){
columns = (int) (Math.ceil(data.length / (double) rows));
}
numRows = rows;
numColumns = columns;
resize(numRows,numColumns);
// set the table model with the data
populateModel(data);
addClickHandler(this);
addStyleName("SelectionTable");
if (this.mode.equals(SelectionTable.MODE_ICON)) {
setBorderStyleForCells();
}
}
public void initSelectedItems(boolean[] si) {
selecteditems = si;
clearSelection(0);
int row, column;
for (int i = 0; i < selecteditems.length; i++) {
if (selecteditems[i]) {
row = i / getColumnCount();
column = i - (row * getColumnCount());
Widget w = getWidget(row, column);
if (w != null) {
w.addStyleName("selected");
}
}
}
}
private void setBorderStyleForCells() {
for (int i = 0; i < this.getRowCount(); i++) {
for (int j = 0; j < this.getColumnCount(); j++) {
this.getWidget(i, j).addStyleName("border");
}
}
}
private void changeSelection(int row, int column) {
selectedRow = row;
selectedColumn = column;
clearSelectedCells();
Widget w = getWidget(row, column);
if (w != null) {
w.addStyleName("selected");
}
}
private void clearSelection(int def) {
selectedColumn = def;
selectedRow = 0;
clearSelectedCells();
}
private void clearSelectedCells() {
for (int i = 0; i < getRowCount(); i++) {
for (int j = 0; j < getCellCount(i); j++) {
Widget w = getWidget(i,j);
if (w != null) {
w.removeStyleName("selected");
}
}
}
}
/**
* @return selected index of the table
*/
public int getSelectedIndex() {
int index = this.getColumnCount() * this.selectedRow
+ this.selectedColumn;
if(index <-1) {
index = -1;
}
return index;
}
/**
* sets the given index as selected. if {@code index = -1} the selection is
* removed.
*
* @param index
* {@code int}
*/
public void setSelectedIndex(int index){
if(index == -1){
this.clearSelection(-1);
return;
}
int row = index / getColumnCount();
int column = index - (row * getColumnCount());
this.changeSelection(row, column);
}
/**
*
* @param index
* {@code int}
* @param selected
* whether it was selected or deselected
*/
public void changeMultiSelection(int index, boolean selected) {
selectedRow = index / getColumnCount();
selectedColumn = index - (selectedRow * getColumnCount());
Widget w = getWidget(selectedRow, selectedColumn);
if (w != null) {
if (selected) {
w.addStyleName("selected");
} else {
w.removeStyleName("selected");
}
}
}
/**
* @param data
* {@link ImageOrText ImageOrText[]}
*/
public void populateModel(ImageOrText[] data) {
values = data;
if (data.length > 0) {
populateModelCallback(data);
}
}
private void populateModelCallback(ImageOrText[] data) {
int r=0;
int c=0;
if (isIniting ) {
for(int i=0; i < Math.min(data.length, this.numRows * this.numColumns); i++){
setWidget(r, c, createWidget(data[i]));
++c;
if(c == this.numColumns){
c = 0;
++r;
}
}
isIniting = false;
} else if (mode != SelectionTable.MODE_TEXT) {
for(int i=0; i < Math.min(data.length, this.numRows * this.numColumns); i++){
if (getWidget(r, c) instanceof Label) {
data[i].applyToLabel((Label) getWidget(r, c));
++c;
if(c == this.numColumns){
c = 0;
++r;
}
}
}
}
}
private Widget createWidget(ImageOrText object) {
Widget w = null;
if(object == null){
return w;
}
switch (mode) {
case MODE_TEXT:
case MODE_ICON:
w = new Label();
object.applyToLabel((Label)w);
break;
default:
case MODE_LATEX:
break;
}
return w;
}
@Override
public void onClick(ClickEvent event) {
Cell clicked = getCellForEvent(event);
if(clicked == null){
return;
}
selectedColumn = clicked.getCellIndex();
selectedRow = clicked.getRowIndex();
if (!isMultiselectionEnabled) {
clearSelectedCells();
}
Widget w = getWidget(clicked.getRowIndex(),clicked.getCellIndex());
if (w != null) {
if (isMultiselectionEnabled) {
// TODO check for -1 col.count.
int index = (getColumnCount() == -1) ? selectedColumn
: selectedRow * getColumnCount() + selectedColumn;
selecteditems[index] = !selecteditems[index];
if (selecteditems[index]) {
w.addStyleName("selected");
} else {
w.removeStyleName("selected");
}
} else {
w.addStyleName("selected");
}
}
}
/**
* @param index
* data index
* @return whether it's selected
*
*/
public boolean isSelected(int index) {
if (isMultiselectionEnabled) {
return selecteditems[index];
}
return (index == getSelectedIndex());
}
/**
* @return {@link ImageOrText}
*/
public ImageOrText getSelectedValue() {
if (this.selectedRow != -1 && this.selectedColumn != -1) {
return getValueAt(this.selectedRow, this.selectedColumn);
}
return null;
}
private ImageOrText getValueAt(int row, int column) {
if(values == null || values.length <= row * this.numColumns + column){
return null;
}
return values[row * this.numColumns + column];
}
/**
* to update the text of the {@link ImageOrText}
*
* @param data
* texts or images
*/
public void updateText(ImageOrText[] data) {
int r = 0;
int c = 0;
for (int i = 0; i < Math.min(data.length, this.numRows
* this.numColumns); i++) {
if (getWidget(r, c) instanceof Label) {
((Label) getWidget(r, c)).setText(data[i].getText());
++c;
if (c == this.numColumns) {
c = 0;
++r;
}
}
}
}
/**
* removes the default style of the cells
*/
public void removeDefaultStyle() {
for (int i = 0; i < this.getRowCount(); i++) {
for (int j = 0; j < this.getColumnCount(); j++) {
this.getWidget(i, j).removeStyleName("border");
}
}
}
}