/**************************************************************************** * 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.text.SimpleDateFormat; import java.util.Calendar; import org.eclipse.nebula.cwt.v.IControlPainter; import org.eclipse.nebula.cwt.v.VControl; import org.eclipse.nebula.cwt.v.VPanel; import org.eclipse.swt.SWT; import org.eclipse.swt.graphics.Color; import org.eclipse.swt.graphics.Pattern; import org.eclipse.swt.graphics.Point; import org.eclipse.swt.graphics.Transform; import org.eclipse.swt.widgets.Event; class AnalogClockPainter implements IControlPainter { private CDateTime cdt; private AnalogTimePicker picker; private boolean paintMinorTicks = true; private boolean paintShadows = true; public AnalogClockPainter(CDateTime cdt, AnalogTimePicker picker) { this.cdt = cdt; this.picker = picker; } public void dispose() { // nothing to do } public void paintBackground(VControl control, Event e) { // nothing to do } public void paintBorders(VControl control, Event e) { // nothing to do } public final void paintContent(VControl control, Event e) { e.gc.setAdvanced(true); e.gc.setAntialias(SWT.ON); e.gc.setTextAntialias(SWT.ON); Calendar cal = cdt.getCalendarInstance(); float angleS = cal.get(Calendar.SECOND)*6; float angleM = cal.get(Calendar.MINUTE)*6; float angleH; if(picker.is24Hour) { angleH = (cal.get(Calendar.HOUR_OF_DAY)*15) + (cal.get(Calendar.MINUTE)/4); } else { angleH = (cal.get(Calendar.HOUR)*30) + (cal.get(Calendar.MINUTE)/2); } Transform o = new Transform(e.display); e.gc.getTransform(o); int lwidth = e.gc.getLineWidth(); e.gc.setLineWidth(1); int lcap = e.gc.getLineCap(); e.gc.setLineCap(SWT.CAP_ROUND); paintFace((VPanel) control, e); if(paintShadows) { e.gc.setBackground(e.display.getSystemColor(SWT.COLOR_DARK_GRAY)); e.gc.setForeground(e.display.getSystemColor(SWT.COLOR_DARK_GRAY)); e.gc.setLineWidth(2); control.setAlpha(e.gc, 50); if(picker.secHand) { setTransform(e, angleS, true); paintSecondHand((VPanel) control, e, (int) angleS); } if(picker.minHand) { setTransform(e, angleM, true); paintMinuteHand((VPanel) control, e, (int) angleM); } if(picker.hourHand) { setTransform(e, angleH, true); paintHourHand((VPanel) control, e, (int) angleH); } control.setAlpha(e.gc); e.gc.setTransform(o); e.gc.setBackground(e.display.getSystemColor(SWT.COLOR_GRAY)); e.gc.fillOval(picker.dialCenter.x+1, picker.dialCenter.y+1, 6, 6); } if(picker.secHand) { e.gc.setBackground(e.display.getSystemColor(SWT.COLOR_BLACK)); if(picker.overSec) { e.gc.setForeground(e.display.getSystemColor(SWT.COLOR_BLACK)); e.gc.setLineWidth(4); } else { e.gc.setForeground(e.display.getSystemColor(SWT.COLOR_DARK_RED)); e.gc.setLineWidth(2); } setTransform(e, angleS, false); paintSecondHand((VPanel) control, e, (int) angleS); } if(picker.minHand) { if(picker.overMin) { e.gc.setBackground(e.display.getSystemColor(SWT.COLOR_BLACK)); e.gc.setForeground(e.display.getSystemColor(SWT.COLOR_BLACK)); e.gc.setLineWidth(4); } else { e.gc.setForeground(e.display.getSystemColor(SWT.COLOR_DARK_BLUE)); e.gc.setLineWidth(2); } setTransform(e, angleM, false); paintMinuteHand((VPanel) control, e, (int) angleM); } if(picker.hourHand) { if(picker.overHour) { e.gc.setBackground(e.display.getSystemColor(SWT.COLOR_BLACK)); e.gc.setForeground(e.display.getSystemColor(SWT.COLOR_BLACK)); e.gc.setLineWidth(4); } else { e.gc.setForeground(e.display.getSystemColor(SWT.COLOR_DARK_BLUE)); e.gc.setLineWidth(2); } setTransform(e, angleH, false); paintHourHand((VPanel) control, e, (int) angleH); } if(picker.overHour || picker.overMin || picker.overSec) { e.gc.setLineWidth(2); } else { e.gc.setLineWidth(1); } e.gc.setTransform(o); control.setAlpha(e.gc); e.gc.setBackground(e.display.getSystemColor(SWT.COLOR_DARK_GRAY)); e.gc.fillOval(picker.dialCenter.x-3, picker.dialCenter.y-3, 6, 6); e.gc.setForeground(e.display.getSystemColor(SWT.COLOR_BLACK)); e.gc.drawOval(picker.dialCenter.x-3, picker.dialCenter.y-3, 6, 6); if(picker.timeNow != null) { picker.timeNow.paintControl(e); } if(picker.timeAmPm != null) { picker.timeAmPm.paintControl(e); } e.gc.setLineWidth(lwidth); e.gc.setLineCap(lcap); } protected void paintFace(VPanel panel, Event e) { int dia = 2 * picker.dialRadius; int x = picker.dialCenter.x - picker.dialRadius; int y = picker.dialCenter.y - picker.dialRadius; Color c1 = new Color(e.display, 220, 220, 225); Color c2 = new Color(e.display, 200, 200, 200); Pattern p = new Pattern( e.display, 0, y, 0, y+dia, e.display.getSystemColor(SWT.COLOR_WHITE), c1 ); e.gc.setBackgroundPattern(p); e.gc.fillOval(x, y, dia, dia); e.gc.setForeground(c2); e.gc.drawOval(x, y, dia, dia); int inc; Transform o = new Transform(e.display); e.gc.getTransform(o); Transform t; t = new Transform(e.display); t.translate(picker.dialCenter.x, picker.dialCenter.y); t.rotate((float) -90); inc = 12; for(int i = 0; i < inc; i++) { e.gc.setTransform(t); e.gc.drawLine(picker.dialRadius-15, 0, picker.dialRadius-8, 0); t.rotate((float) 30); } if(paintMinorTicks || picker.is24Hour) { inc = picker.is24Hour ? 24 : 60; int skip = picker.is24Hour ? 2 : 5; for(int i = 0; i < inc; i++) { if(i % skip != 0) { e.gc.setTransform(t); e.gc.drawLine(picker.dialRadius-13, 0, picker.dialRadius-10, 0); } t.rotate((float) (picker.is24Hour ? 15 : 6)); } } t.dispose(); Calendar tmpcal = cdt.getCalendarInstance(); tmpcal.set(1, 1, 1, 0, 0, 0); SimpleDateFormat sdf = new SimpleDateFormat(picker.is24Hour ? "H" : "h"); e.gc.setForeground(e.display.getSystemColor(SWT.COLOR_DARK_BLUE)); panel.setAlpha(e.gc, 200); e.gc.setTransform(o); inc = 12; for(int i = 0; i < inc; i++) { int x2 = x + picker.dialRadius + (int) ((picker.dialRadius - 25) * (Math.cos(2 * (double) i * Math.PI / inc - Math.PI / 2))); int y2 = y + picker.dialRadius + (int) ((picker.dialRadius - 25) * (Math.sin(2 * (double) i * Math.PI / inc - Math.PI / 2))); String str = sdf.format(tmpcal.getTime()); Point ss = e.gc.stringExtent(str); e.gc.drawString(str, x2 - (ss.x / 2), y2 - (ss.y / 2)); tmpcal.add(Calendar.HOUR_OF_DAY, picker.is24Hour ? 2 : 1); } p.dispose(); c1.dispose(); c2.dispose(); } protected void paintHourHand(VPanel panel, Event e, int angle) { e.gc.drawLine(-15, 0, picker.dialRadius-35, 0); } protected void paintMinuteHand(VPanel panel, Event e, int angle) { e.gc.drawLine(-15, 0, picker.dialRadius - 17, 0); } protected void paintSecondHand(VPanel panel, Event e, int angle) { e.gc.drawLine(-15, 0, picker.dialRadius-12, 0); } private void setTransform(Event e, float angle, boolean shadow) { Transform t = new Transform(e.display); int x = picker.dialCenter.x; int y = picker.dialCenter.y; if(shadow) { x += 4; y += 4; } t.translate(x, y); t.rotate(angle-90); e.gc.setTransform(t); t.dispose(); } }