/****************************************************************************
* Copyright (c) 2008 Jeremy Dowdall
* 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:
* Jeremy Dowdall <jeremyd@aspencloud.com> - initial API and implementation
*****************************************************************************/
package org.eclipse.nebula.widgets.cdatetime;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Locale;
import java.util.TimeZone;
import org.eclipse.nebula.cwt.v.VButton;
import org.eclipse.nebula.cwt.v.VControl;
import org.eclipse.nebula.cwt.v.VGridLayout;
import org.eclipse.nebula.cwt.v.VLabel;
import org.eclipse.nebula.cwt.v.VNative;
import org.eclipse.nebula.cwt.v.VPanel;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Listener;
public class CDatePanel extends Composite {
private VPanel panel;
private VPanel header;
private VPanel body;
private List<VNative<CDateTime>> pickers;
private int headerSize;
private int pickerSize;
private CDateTimeBuilder builder;
private CDateTimePainter painter;
private Locale locale;
private TimeZone timezone;
private Calendar calendar;
private SelectionAdapter listener = new SelectionAdapter() {
@Override
public void widgetDefaultSelected(SelectionEvent e) {
CDateTime cdt = (CDateTime) e.widget;
for(VNative<CDateTime> picker : pickers) {
if(picker.getControl() != e.widget) {
picker.getControl().setSelection(cdt.getSelection());
}
}
}
};
public CDatePanel(Composite parent, int style) {
super(parent, style);
panel = new VPanel(this, SWT.NONE);
locale = Locale.getDefault();
try {
timezone = TimeZone.getDefault();
} catch(Exception e) {
timezone = TimeZone.getTimeZone("GMT");
}
calendar = Calendar.getInstance(this.timezone, this.locale);
calendar.setTime(new Date());
builder = new CDateTimeBuilder();
builder.setHeader(Header.Month().align(SWT.RIGHT, SWT.FILL, true).readOnly(), Header.Year().align(SWT.LEFT,
SWT.FILL, true).readOnly());
builder.setBody(Body.Days().compact());
painter = new CDateTimePainter() {
@Override
protected void paintDayPanelBorders(VControl control, Event e) {
Rectangle r = control.getBounds();
e.gc.setForeground(e.display.getSystemColor(SWT.COLOR_WIDGET_NORMAL_SHADOW));
e.gc.drawLine(r.x, r.y, r.x, r.y + r.height - 1);
e.gc.drawLine(r.x + r.width - 1, r.y, r.x + r.width - 1, r.y + r.height - 1);
e.gc.drawLine(r.x, r.y + r.height - 1, r.x + r.width - 1, r.y + r.height - 1);
}
};
pickers = new ArrayList<VNative<CDateTime>>();
pickerSize = -1;
VGridLayout layout = new VGridLayout();
layout.verticalSpacing = 2;
panel.setLayout(layout);
createHeader();
VLabel sep = new VLabel(panel, SWT.HORIZONTAL | SWT.SEPARATOR);
sep.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, false));
body = new VPanel(panel, SWT.NONE);
body.setLayout(new VGridLayout());
body.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
body.addListener(SWT.Resize, new Listener() {
public void handleEvent(Event event) {
handleResize();
}
});
}
private void addMonth() {
VNative<CDateTime> picker = VNative.create(CDateTime.class, body, CDT.MULTI | CDT.SIMPLE);
picker.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false));
CDateTime cdt = picker.getControl();
cdt.setBuilder(builder);
cdt.setPainter(painter);
cdt.setPattern("MMMM d yyyy");
cdt.setLocale(locale);
cdt.setTimeZone(timezone);
cdt.setScrollable(false);
cdt.addSelectionListener(listener);
pickers.add(picker);
updateMonths();
}
private void createHeader() {
header = new VPanel(panel, SWT.NONE);
VGridLayout layout = new VGridLayout(3, true);
layout.marginWidth = 0;
layout.marginHeight = 0;
header.setLayout(layout);
header.setLayoutData(new GridData(SWT.FILL, SWT.TOP, false, false));
VButton b = new VButton(header, SWT.ARROW | SWT.LEFT | SWT.NO_FOCUS);
b.setFill(getDisplay().getSystemColor(SWT.COLOR_GRAY));
b.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, false));
b.addListener(SWT.Selection, new Listener() {
public void handleEvent(Event event) {
calendar.add(Calendar.MONTH, -1);
updateMonths();
}
});
b = new VButton(header, SWT.PUSH | SWT.NO_FOCUS);
b.setText("Today");
b.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
b.addListener(SWT.Selection, new Listener() {
public void handleEvent(Event event) {
calendar.setTimeInMillis(System.currentTimeMillis());
updateMonths();
}
});
b = new VButton(header, SWT.ARROW | SWT.RIGHT | SWT.NO_FOCUS);
b.setFill(getDisplay().getSystemColor(SWT.COLOR_GRAY));
b.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, false));
b.addListener(SWT.Selection, new Listener() {
public void handleEvent(Event event) {
calendar.add(Calendar.MONTH, 1);
updateMonths();
}
});
headerSize = header.computeSize(-1, -1).y;
}
public VPanel getPanel() {
return panel;
}
private void handleResize() {
if(pickerSize == -1) {
setMonthCount(1);
pickerSize = pickers.get(0).computeSize(-1, -1).y;
}
int height = getClientArea().height;
int count = (int) Math.ceil((double) (height - headerSize) / pickerSize);
setMonthCount(count);
}
private void removeMonth() {
if(!pickers.isEmpty()) {
VNative<CDateTime> picker = pickers.remove(pickers.size() - 1);
picker.dispose();
}
}
public void setMonthCount(int count) {
while(count > pickers.size()) {
addMonth();
}
while(count < pickers.size()) {
removeMonth();
}
}
private void updateMonths() {
Calendar tmpcal = Calendar.getInstance(timezone, locale);
tmpcal.setTime(calendar.getTime());
for(VNative<CDateTime> picker : pickers) {
picker.getControl().show(tmpcal.getTime());
tmpcal.add(Calendar.MONTH, 1);
}
}
}