package org.gwtoolbox.widget.client.table.basic.selection;
import java.util.ArrayList;
import java.util.List;
import com.google.gwt.user.client.Element;
import com.google.gwt.user.client.Event;
import org.gwtoolbox.commons.util.client.UIUtils;
import org.gwtoolbox.widget.client.table.basic.BasicTable;
import org.gwtoolbox.widget.client.table.basic.Cell;
/**
* @author Uri Boness
*/
public class SingleCellSelectionModel implements SingleCellSelection, SelectionModel {
private final static CellSelectionFilter DEFAULT_SELECTION_FILTER = new CellSelectionFilter() {
public boolean isSelectable(int row, int column) {
return true;
}
};
private BasicTable table;
private Cell selectedCell;
private Element selectedCellElement;
private List<Listener> listeners = new ArrayList<Listener>();
private final SelectionOptions options;
private CellSelectionFilter selectionFilter = DEFAULT_SELECTION_FILTER;
public SingleCellSelectionModel() {
this(new DefaultSelectionOptions());
}
public SingleCellSelectionModel(SelectionOptions options) {
this.options = options;
}
public void install(BasicTable table) {
this.table = table;
}
public void uninstall() {
table = null;
}
public void handleCellClicked(int row, int column, Event event) {
selectCell(row, column, event.getCtrlKey());
}
public void handleCellMouseDown(int row, int column, Event event) {
// do nothing
}
public void handleCellMouseUp(int row, int column, Event event) {
// do nothing
}
public void handleCellMouseEntered(int row, int column, Event event) {
if (!selectionFilter.isSelectable(row, column)) {
return;
}
if (selectedCell != null && selectedCell.equals(row, column)) {
return;
}
table.getCellFormatter().addStyleName(row, column, options.getHoverStyleName());
}
public void handleCellMouseOut(int row, int column, Event event) {
if (!selectionFilter.isSelectable(row, column)) {
return;
}
table.getCellFormatter().removeStyleName(row, column, options.getHoverStyleName());
}
public Selection getSelection() {
return this;
}
public boolean isCellSelected(int row, int column) {
return selectedCell != null && selectedCell.equals(row, column);
}
public Cell getSelectedCell() {
return selectedCell;
}
public void selectCell(int row, int column) {
selectCell(row, column, false);
}
public void clear() {
if (selectedCellElement == null) {
return;
}
UIUtils.removeStyleName(selectedCellElement, options.getSelectionStyleName());
selectedCell = null;
selectedCellElement = null;
notifySelectionCleared();
}
public void addListener(Listener listener) {
listeners.add(listener);
}
public void removeListener(Listener listener) {
listeners.remove(listener);
}
public void clearListeners() {
listeners.clear();
}
public CellSelectionFilter getSelectionFilter() {
return selectionFilter;
}
public void setSelectionFilter(CellSelectionFilter selectionFilter) {
this.selectionFilter = selectionFilter;
}
//============================================== Setter/Getter =====================================================
public SelectionOptions getOptions() {
return options;
}
//============================================== Helper Methods ====================================================
private void selectCell(int row, int column, boolean toggleIfAlreadySelected) {
if (row < 0 || column < 0) {
throw new IllegalArgumentException("Row/Column index cannot be negative");
}
if (!selectionFilter.isSelectable(row, column)) {
return;
}
Element cellElement = table.getCellFormatter().getElement(row, column);
if (cellElement.equals(selectedCellElement)) {
if (toggleIfAlreadySelected) {
clear();
}
return;
}
if (selectedCellElement != null) {
UIUtils.removeStyleName(selectedCellElement, options.getSelectionStyleName());
}
selectedCellElement = cellElement;
selectedCell = new Cell(row, column);
UIUtils.addStyleName(selectedCellElement, options.getSelectionStyleName());
UIUtils.removeStyleName(selectedCellElement, options.getHoverStyleName());
notifyCellSelected(row, column);
}
private void notifySelectionCleared() {
for (Listener listener : listeners) {
listener.selectionCleared();
}
}
private void notifyCellSelected(int row, int column) {
for (Listener listener : listeners) {
listener.cellSelected(row, column);
}
}
}