blob: 3f01027773ada9b820831acee58572a511be7742 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2006 The Pampered Chef and others.
* 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:
* The Pampered Chef - initial API and implementation
******************************************************************************/
package org.eclipse.jface.examples.databinding.compositetable.day.internal;
import java.text.DateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.Iterator;
import java.util.LinkedList;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.CLabel;
import org.eclipse.swt.events.FocusListener;
import org.eclipse.swt.events.KeyListener;
import org.eclipse.swt.events.MouseListener;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Layout;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.swt.widgets.Widget;
/**
* Represents a time slice that is the same time but may span several days.
* For example: 11:00 - 11:15 PM from Sunday through Saturday.
*
* @since 3.2
*/
public class TimeSlice extends Composite {
private final Image allDayImage = new Image(Display.getCurrent(), TimeSlice.class.getResourceAsStream("clock.png"));
/**
* The 0th control in the layout may have a java.lang.Integer LayoutData
* indicating its preferred width. Otherwise, DaysLayout will ask the
* control to compute its preferred size and will use the width returned by
* that computation. All other controls will be equally allotted horizontal
* width in the parent control.
*/
private static class TimeSliceAcrossTimeLayout extends Layout {
Point preferredSize = new Point(-1, -1);
protected Point computeSize(Composite composite, int wHint, int hHint,
boolean flushCache) {
if (preferredSize.x == -1 || flushCache) {
preferredSize.x = wHint;
preferredSize.y = -1; // NOTE: This assumes at least one child
// control
Control[] children = composite.getChildren();
for (int i = 0; i < children.length; i++) {
Control child = children[i];
preferredSize.y = Math.max(preferredSize.y, child
.computeSize(SWT.DEFAULT, SWT.DEFAULT, true).y);
}
}
return preferredSize;
}
protected void layout(Composite composite, boolean flushCache) {
Point parentSize = composite.getSize();
Control[] children = composite.getChildren();
// layout 0th control
Integer preferredWidth = (Integer) children[0].getLayoutData();
if (preferredWidth == null) {
preferredWidth = new Integer(children[0].computeSize(
SWT.DEFAULT, SWT.DEFAULT).x);
}
children[0].setBounds(0, 0, preferredWidth.intValue(), parentSize.y);
// layout the rest of the controls
int controlWidth = 0;
int extraWidth = 0;
if (children.length >= 2) {
controlWidth = (parentSize.x - preferredWidth.intValue())
/ (children.length - 1);
extraWidth = (parentSize.x - preferredWidth.intValue())
% (children.length - 1);
}
int leftPosition = preferredWidth.intValue();
for (int i = 1; i < children.length; i++) {
Control control = children[i];
int width = controlWidth;
if (extraWidth > 0) {
++width;
--extraWidth;
}
control.setBounds(leftPosition, 0, width, parentSize.y);
leftPosition += width;
}
}
}
private CLabel timeLabel = null;
private LinkedList columns = new LinkedList();
/**
* @return Returns the columns.
*/
public LinkedList getColumns() {
return columns;
}
/**
* Returns the control that implements the specified column.
*
* @param column The column number.
* @return Control the SWT control that implements this column.
*/
public Control getColumnControl(int column) {
return (Control) columns.get(column);
}
/**
* Return the column number of the specified widget.
*
* @param widget the TimeSlot widget
* @return the column number of the specified TimeSlot within this TimeSlice.
*/
public int getControlColumn(Widget widget) {
int columnNumber = 0;
for (Iterator columnsIter = columns.iterator(); columnsIter.hasNext();) {
if (columnsIter.next() == widget) {
return columnNumber;
}
++columnNumber;
}
throw new IllegalArgumentException("Unrecognized widget passed to getControlColumn");
}
/**
* Constructor TimeSlice. Construct a TimeSlice control, passing the parent
* and style bits.
*
* @param parent
* The SWT parent object.
* @param style
* The set of style bits this control accepts. Currently SWT.NONE.
*/
public TimeSlice(Composite parent, int style) {
super(parent, SWT.NULL);
initialize();
}
/* (non-Javadoc)
* @see org.eclipse.swt.widgets.Control#setMenu(org.eclipse.swt.widgets.Menu)
*/
public void setMenu(Menu menu) {
super.setMenu(menu);
for (Iterator columnsIter = columns.iterator(); columnsIter.hasNext();) {
TimeSlot cell = (TimeSlot) columnsIter.next();
cell.setMenu(menu);
}
}
/**
* Initialize the control
*/
private void initialize() {
timeLabel = new CLabel(this, SWT.RIGHT);
timeLabel.setText("23:00 PM");
Integer preferredWidth = new Integer(timeLabel.computeSize(SWT.DEFAULT,
SWT.DEFAULT, false).x + 5);
timeLabel.setLayoutData(preferredWidth);
timeLabel.setText("");
setBackground(Display.getCurrent().getSystemColor(
SWT.COLOR_WIDGET_BACKGROUND));
setSize(new Point(537, 16));
setLayout(new TimeSliceAcrossTimeLayout());
}
private boolean headerControl = false;
/**
* @return Returns the headerControl.
*/
public boolean isHeaderControl() {
return headerControl;
}
/**
* @param headerControl The headerControl to set.
*/
public void setHeaderControl(boolean headerControl) {
this.headerControl = headerControl;
}
private int numberOfColumns = 1;
/**
* Gets the number of columns that will be displayed in this row. The
* default number of columns is 1.
*
* @return numberOfColumns The number of days to display.
*/
public int getNumberOfColumns() {
return numberOfColumns;
}
/**
* Sets the number of columns that will be displayed in this row. The
* default number of columns is 1. This method may only be called *once* at
* the beginning of the control's life cycle, and the value passed must be
* >1.
* <p>
* Calling this method more than once results in undefined behavior.
*
* @param numberOfColumns
* The number of days to display.
*/
public void setNumberOfColumns(int numberOfColumns) {
this.numberOfColumns = numberOfColumns;
Control[] tabStops = new Control[numberOfColumns];
for (int i = numberOfColumns; i > 0; --i) {
if (headerControl) {
CLabel control = new CLabel(this, SWT.SHADOW_OUT | SWT.BORDER | SWT.CENTER);
tabStops[numberOfColumns-i] = control;
columns.add(control);
} else {
TimeSlot control = new TimeSlot(this, SWT.NONE);
tabStops[numberOfColumns-i] = control;
columns.add(control);
}
}
setTabList(tabStops);
}
private Date currentTime = new Date();
/**
* @return The current time set in this "days" row.
*/
public Date getCurrentTime() {
return currentTime;
}
/**
* @param currentTime
*/
public void setCurrentTime(Date currentTime) {
// if currentTime is null, we are becoming an all-day event row
if (currentTime == null) {
timeLabel.setImage(allDayImage);
timeLabel.setText("");
setAllDayEventOnDays(true);
return;
}
setAllDayEventOnDays(false);
timeLabel.setImage(null);
setTimeOnDays(currentTime);
this.currentTime = currentTime;
Calendar calendar = new GregorianCalendar();
calendar.setTime(currentTime);
// Only the hours will display in the label
if (calendar.get(Calendar.MINUTE) == 0) {
DateFormat df = DateFormat.getTimeInstance(DateFormat.SHORT);
String time = df.format(currentTime);
timeLabel.setText(time);
} else {
timeLabel.setText("");
}
}
private void setTimeOnDays(Date currentTime) {
for (Iterator daysIter = columns.iterator(); daysIter.hasNext();) {
Object dayCandidate = daysIter.next();
if (dayCandidate instanceof TimeSlot) {
TimeSlot day = (TimeSlot) dayCandidate;
day.setTime(currentTime);
}
}
}
private void setAllDayEventOnDays(boolean isAllDayEvent) {
for (Iterator daysIter = columns.iterator(); daysIter.hasNext();) {
Object dayCandidate = daysIter.next();
if (dayCandidate instanceof TimeSlot) {
TimeSlot day = (TimeSlot) dayCandidate;
day.setAllDay(isAllDayEvent);
}
}
}
/**
* @see org.eclipse.swt.widgets.Control#addFocusListener
*
* @param listener
*/
public void addCellFocusListener(FocusListener listener) {
for (Iterator daysIter = columns.iterator(); daysIter.hasNext();) {
Object dayCandidate = daysIter.next();
if (dayCandidate instanceof TimeSlot) {
TimeSlot day = (TimeSlot) dayCandidate;
day.addFocusListener(listener);
}
}
}
/**
* @see org.eclipse.swt.widgets.Control#removeFocusListener
* @param listener
*/
public void removeCellFocusListener(FocusListener listener) {
for (Iterator daysIter = columns.iterator(); daysIter.hasNext();) {
Object dayCandidate = daysIter.next();
if (dayCandidate instanceof TimeSlot) {
TimeSlot day = (TimeSlot) dayCandidate;
day.removeFocusListener(listener);
}
}
}
/* (non-Javadoc)
* @see org.eclipse.swt.widgets.Control#addKeyListener(org.eclipse.swt.events.KeyListener)
*/
public void addKeyListener(KeyListener listener) {
super.addKeyListener(listener);
for (Iterator columnsIter = columns.iterator(); columnsIter.hasNext();) {
TimeSlot cell = (TimeSlot) columnsIter.next();
cell.addKeyListener(listener);
}
}
/* (non-Javadoc)
* @see org.eclipse.swt.widgets.Control#removeKeyListener(org.eclipse.swt.events.KeyListener)
*/
public void removeKeyListener(KeyListener listener) {
super.removeKeyListener(listener);
for (Iterator columnsIter = columns.iterator(); columnsIter.hasNext();) {
TimeSlot cell = (TimeSlot) columnsIter.next();
cell.removeKeyListener(listener);
}
}
/* (non-Javadoc)
* @see org.eclipse.swt.widgets.Control#addKeyListener(org.eclipse.swt.events.KeyListener)
*/
public void addMouseListener(MouseListener listener) {
super.addMouseListener(listener);
for (Iterator columnsIter = columns.iterator(); columnsIter.hasNext();) {
TimeSlot cell = (TimeSlot) columnsIter.next();
cell.addMouseListener(listener);
}
}
/* (non-Javadoc)
* @see org.eclipse.swt.widgets.Control#removeKeyListener(org.eclipse.swt.events.KeyListener)
*/
public void removeMouseListener(MouseListener listener) {
super.removeMouseListener(listener);
for (Iterator columnsIter = columns.iterator(); columnsIter.hasNext();) {
TimeSlot cell = (TimeSlot) columnsIter.next();
cell.removeMouseListener(listener);
}
}
} // @jve:decl-index=0:visual-constraint="10,10"