/*
* Copyright (C) 2005 David Orme <djo@coconut-palm-software.com>
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* David Orme - Initial API and implementation
* The Pampered Chef - Generalized
*/
package org.eclipse.swt.nebula.widgets.compositetable;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.FocusEvent;
import org.eclipse.swt.events.FocusListener;
import org.eclipse.swt.events.KeyEvent;
import org.eclipse.swt.events.KeyListener;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.events.MouseListener;
import org.eclipse.swt.events.TraverseEvent;
import org.eclipse.swt.events.TraverseListener;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Menu;
/**
* An abstract row class making it easy to implement a table where the whole
* row is selected at once.
*
* @author djo
*/
public abstract class AbstractSelectableRow extends Composite implements
TraverseListener, FocusListener, MouseListener, IRowFocusListener,
IRowContentProvider, KeyListener {
private Display display = Display.getCurrent();
private Color LIST_BACKGROUND = display
.getSystemColor(SWT.COLOR_LIST_BACKGROUND);
private Color LIST_FOREGROUND = display
.getSystemColor(SWT.COLOR_LIST_FOREGROUND);
private Color LIST_SELECTION = display
.getSystemColor(SWT.COLOR_LIST_SELECTION);
private Color LIST_SELECTION_TEXT = display
.getSystemColor(SWT.COLOR_LIST_SELECTION_TEXT);
private Color LIST_SELECTION_NOFOCUS = display
.getSystemColor(SWT.COLOR_WIDGET_LIGHT_SHADOW);
private Color LIST_SELECTION_TEXT_NOFOCUS = display
.getSystemColor(SWT.COLOR_LIST_FOREGROUND);
protected List labels;
public AbstractSelectableRow(Composite parent, int style) {
super(parent, style);
addTraverseListener(this);
addFocusListener(this);
addMouseListener(this);
addKeyListener(this);
}
/**
* This method initializes this
*
*/
private void initialize() {
this.labels = new ArrayList();
for (int i = 0; i < getColumnCount(); i++) {
Label label = new Label(this, SWT.NONE);
this.labels.add(label);
label.addMouseListener(this);
}
}
public List getLabelsList() {
return this.labels;
}
private void setRowColor(Color foreground, Color background) {
setBackground(background);
setForeground(foreground);
Control[] children = getChildren();
for (int i = 0; i < children.length; i++) {
children[i].setBackground(background);
children[i].setForeground(foreground);
}
}
// Event handlers ----------------------------------------------------------
public void keyTraversed(TraverseEvent e) {
// NOOP: this just lets us receive focus from SWT
}
public void focusGained(FocusEvent e) {
setRowColor(LIST_SELECTION_TEXT, LIST_SELECTION);
selected = true;
setSelection(model);
}
protected void setSelection(Object model) {
// noop
}
private boolean selected = false;
private boolean inactiveSelected = false;
public void focusLost(FocusEvent e) {
if (selected) {
setRowColor(LIST_SELECTION_TEXT_NOFOCUS, LIST_SELECTION_NOFOCUS);
inactiveSelected = true;
}
}
public void depart(CompositeTable sender, int currentObjectOffset,
Control row) {
if(row == this && selected) {
deselectRow();
}
}
public void arrive(CompositeTable sender, int currentObjectOffset,
Control newRow) {
// NO OP
}
public void refresh(CompositeTable sender, int currentObjectOffset,
Control row) {
if (row == this && inactiveSelected) {
deselectRow();
}
}
private void deselectRow() {
setRowColor(LIST_FOREGROUND, LIST_BACKGROUND);
selected = false;
inactiveSelected = false;
}
public boolean requestRowChange(CompositeTable sender,
int currentObjectOffset, Control row) {
// Always ok to change rows
return true;
}
public void mouseDown(MouseEvent e) {
setFocus();
}
/**
* Clients should override to implement their double-click behavior.
*
* {@inheritDoc}
*/
public void mouseDoubleClick(MouseEvent e) {
// noop
};
public void mouseUp(MouseEvent e) {
// noop
}
private Object model = null;
public void setModel(Object object) {
this.model = object;
}
public Object getModel() {
return model;
}
public void setMenu(Menu menu) {
super.setMenu(menu);
for (Iterator labelIter = labels.iterator(); labelIter.hasNext();) {
Label label = (Label) labelIter.next();
label.setMenu(menu);
}
}
public void keyPressed(KeyEvent e) {
// NOOP
}
public void keyReleased(KeyEvent e) {
// Don't want to hard-code key bindings. Clients override this method?
// if (e.character == SWT.DEL && e.stateMask == 0) {
// deleteSelectedObject();
// }
// if (e.character == SWT.CR && e.stateMask == 0) {
// runDoubleClickOpenAction();
// }
}
private int columnCount = -1;
/**
* Method setColumnCount. Sets the number of columns in the row. This
* method must be called <b>exactly</b> once in the overridden constructor.
*
* @param columnCount The number of columns in the row.
*/
public void setColumnCount(int columnCount) {
if (this.columnCount > -1) {
throw new IllegalArgumentException("Cannot setColumnCount more than once");
}
this.columnCount = columnCount;
initialize();
setRowColor(LIST_FOREGROUND, LIST_BACKGROUND);
}
private int getColumnCount() {
return columnCount;
}
}