/*******************************************************************************
* Copyright (c) 2009 the CHISEL group and contributors.
* 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:
* Del Myers - initial API and implementation
*******************************************************************************/
package ca.uvic.chisel.javasketch.ui.internal;
import org.eclipse.jface.window.Window;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.DisposeEvent;
import org.eclipse.swt.events.DisposeListener;
import org.eclipse.swt.events.PaintEvent;
import org.eclipse.swt.events.PaintListener;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.graphics.FontData;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Canvas;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Shell;
/**
* A simple class that shows a timer that updates every second or so.
* @author Del Myers
*
*/
public class TimerDialog extends Window {
private Object lock;
private Canvas text;
private long startTime;
private long endTime;
private Composite page;
private Color black;
private Color white;
private TimeUpdateRunnable updater;
private boolean open;
// private Timer timer;
// private TimerTask task;
// /**
// * @param parentShell
// */
protected TimerDialog(Shell parentShell) {
super(parentShell);
setShellStyle(SWT.MODELESS | SWT.ON_TOP | SWT.DIALOG_TRIM);
lock = new Object();
// timer = new Timer();
// task = new TimerTask() {
// @Override
// public void run() {
// // TODO Auto-generated method stub
//
// }
// };
}
private class TimeUpdateRunnable implements Runnable {
boolean counting;
/* (non-Javadoc)
* @see java.lang.Runnable#run()
*/
@Override
public void run() {
synchronized (lock) {
if (text == null || text.isDisposed()) {
return;
}
text.redraw();
if (counting) {
text.getDisplay().asyncExec(this);
}
}
}
}
/**
* Sets the text on the shell trim.
* @param text
*/
public void setShellText(String text) {
getParentShell().setText(text);
}
/* (non-Javadoc)
* @see org.eclipse.jface.window.Window#createContents(org.eclipse.swt.widgets.Composite)
*/
@Override
protected Control createContents(Composite parent) {
page = new Composite(parent, SWT.DOUBLE_BUFFERED | SWT.NO_BACKGROUND);
GridLayout layout = new GridLayout();
layout.marginHeight = 0;
layout.marginWidth = 0;
layout.verticalSpacing =0;
layout.horizontalSpacing = 0;
page.setLayout(layout);
text = new Canvas(page, SWT.READ_ONLY | SWT.DOUBLE_BUFFERED);
black = getShell().getDisplay().getSystemColor(SWT.COLOR_BLACK);
white = getShell().getDisplay().getSystemColor(SWT.COLOR_WHITE);
text.setBackground(black);
text.setForeground(white);
GridData gd = new GridData();
gd.heightHint=30;
gd.widthHint=150;
text.setLayoutData(gd);
FontData fd = new FontData("sans-serif", 15, SWT.NORMAL);
final Font f = new Font(text.getDisplay(), fd);
text.setFont(f);
text.addDisposeListener(new DisposeListener(){
@Override
public void widgetDisposed(DisposeEvent e) {
f.dispose();
}
});
text.addPaintListener(new PaintListener() {
@Override
public void paintControl(PaintEvent e) {
long currentTime = endTime;
if (currentTime < 0) {
currentTime = System.currentTimeMillis();
}
long diffTime = currentTime - startTime;
long secondTime = 1000;
long minuteTime = secondTime * 60;
long hourTime = minuteTime * 60;
long dayTime = hourTime * 24;
long days = diffTime/dayTime;
long remainder = diffTime % dayTime;
long hours = remainder / hourTime;
remainder = remainder % hourTime;
long minutes = remainder / minuteTime;
remainder = remainder % minuteTime;
long seconds = remainder / secondTime;
remainder = remainder % secondTime;
GC gc = e.gc;
gc.setBackground(black);
gc.setForeground(black);
gc.fillRectangle(0,0,text.getBounds().width, text.getBounds().height);
gc.setForeground(white);
gc.drawText(days + ":" + hours + ":" + minutes + ":" + seconds + "." + remainder,0,0);
}
});
return page;
}
/**
* Opens the window and resets the timer, if requested.
*/
public int open(boolean reset) {
if (reset) {
reset();
}
return open();
}
/* (non-Javadoc)
* @see org.eclipse.jface.window.Window#open()
*/
@Override
public int open() {
open = true;
return super.open();
}
/* (non-Javadoc)
* @see org.eclipse.jface.window.Window#close()
*/
@Override
public boolean close() {
open = false;
return super.close();
}
/**
* Resets the start time for this dialog to the current time.
*/
public void reset() {
synchronized (lock) {
setStartTime(System.currentTimeMillis());
}
}
/**
* Sets the start time of this dialog to the given time.
* @param timeInMillis
*/
public void setStartTime(long timeInMillis) {
synchronized (lock) {
if (updater != null) {
//cancel pending redraws.
updater.counting = false;
}
updater = new TimeUpdateRunnable();
updater.counting = true;
startTime = timeInMillis;
//so that the redrawer knows that it is counting.
endTime = -1;
if (getShell() != null) {
getShell().getDisplay().asyncExec(updater);
}
}
}
/**
* Sets the final end time of the dialog to the given end,
* @param timeInMillis
*/
public void setEndTime(long timeInMillis) {
synchronized (lock) {
if (updater != null) {
updater.counting = false;
updater = null;
}
updater = new TimeUpdateRunnable();
updater.counting = false;
endTime = timeInMillis;
if (getShell() != null) {
getShell().getDisplay().asyncExec(updater);
}
}
}
/**
* Returns true if this window is open and visible.
* @return
*/
public boolean isOpen() {
return open;
}
}