View Javadoc

1   /*
2    *  File: DayHeaderRenderer.java 
3    *  Copyright (c) 2004-2007  Peter Kliem (Peter.Kliem@jaret.de)
4    *  A commercial license is available, see http://www.jaret.de.
5    *
6    *  This program is free software; you can redistribute it and/or modify
7    *  it under the terms of the GNU General Public License as published by
8    *  the Free Software Foundation; either version 2 of the License, or
9    *  (at your option) any later version.
10   *
11   *  This program is distributed in the hope that it will be useful,
12   *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13   *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14   *  GNU General Public License for more details.
15   *
16   *  You should have received a copy of the GNU General Public License
17   *  along with this program; if not, write to the Free Software
18   *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19   */
20  package de.jaret.examples.timebars.calendar.swt.renderer;
21  
22  import java.text.DateFormat;
23  import java.util.ArrayList;
24  import java.util.Date;
25  import java.util.List;
26  
27  import org.eclipse.jface.resource.ImageDescriptor;
28  import org.eclipse.jface.resource.ImageRegistry;
29  import org.eclipse.swt.SWT;
30  import org.eclipse.swt.graphics.Color;
31  import org.eclipse.swt.graphics.Device;
32  import org.eclipse.swt.graphics.GC;
33  import org.eclipse.swt.graphics.Image;
34  import org.eclipse.swt.graphics.Point;
35  import org.eclipse.swt.graphics.Rectangle;
36  import org.eclipse.swt.printing.Printer;
37  
38  import de.jaret.examples.timebars.calendar.model.Appointment;
39  import de.jaret.examples.timebars.calendar.model.AppointmentPlaceholder;
40  import de.jaret.examples.timebars.calendar.model.CalendarIntervalFilter;
41  import de.jaret.examples.timebars.calendar.model.CalendarModel;
42  import de.jaret.examples.timebars.calendar.model.Day;
43  import de.jaret.util.swt.SwtGraphicsHelper;
44  import de.jaret.util.ui.ResourceImageDescriptor;
45  import de.jaret.util.ui.timebars.TimeBarViewerDelegate;
46  import de.jaret.util.ui.timebars.TimeBarViewerInterface;
47  import de.jaret.util.ui.timebars.model.TimeBarRow;
48  import de.jaret.util.ui.timebars.model.TimeBarRowHeader;
49  import de.jaret.util.ui.timebars.swt.TimeBarViewer;
50  import de.jaret.util.ui.timebars.swt.renderer.HeaderRenderer;
51  import de.jaret.util.ui.timebars.swt.renderer.RendererBase;
52  
53  /***
54   * Header renderer for the calendar example. Includes rendering of spanning appointments (one part per header) represented by AppointmentPlaceholders.
55   * 
56   * @author Peter Kliem
57   * @version $Id: DayHeaderRenderer.java 705 2008-01-25 22:51:54Z kliem $
58   */
59  public class DayHeaderRenderer extends RendererBase implements HeaderRenderer {
60      /*** line width when printing. */
61      private static final int PRINTING_LINEWIDTH = 3;
62      /*** alpha for selecton painting. */
63      protected static final int SELECTION_ALPHA = 60;
64  
65      /*** height for appointments that span multiple days. */
66      private static final int APPOINTMENT_HEIGHT = 18;
67      private static final int STARTAPPOINTMENTS = APPOINTMENT_HEIGHT;
68  
69      protected List<DateFormat> _formats;
70      int _lastWidth = -1;
71      int _lastFormatIdx = -1;
72  
73      /***
74       * Constructor for printing use.
75       * 
76       * @param printer printing device
77       */
78      public DayHeaderRenderer(Printer printer) {
79          super(printer);
80          initDateFormats();
81      }
82  
83      /***
84       * Constructor for screen use.
85       * 
86       */
87      public DayHeaderRenderer() {
88          this(null);
89      }
90  
91      protected void initDateFormats() {
92          _formats = new ArrayList<DateFormat>();
93          DateFormat df = DateFormat.getDateInstance(DateFormat.FULL);
94          _formats.add(df);
95          df = DateFormat.getDateInstance(DateFormat.LONG);
96          _formats.add(df);
97          df = DateFormat.getDateInstance(DateFormat.MEDIUM);
98          _formats.add(df);
99          df = DateFormat.getDateInstance(DateFormat.SHORT);
100         _formats.add(df);
101     }
102 
103     /***
104      * {@inheritDoc}
105      */
106     public void draw(GC gc, Rectangle drawingArea, TimeBarViewerDelegate delegate, TimeBarRowHeader header,
107             boolean selected, boolean printing) {
108         Day day = (Day) header.getRow();
109         Date date = day.getDayDate().getDate();
110 
111         String label = getLabel(gc, drawingArea, date);
112 
113         Color bg = gc.getBackground();
114         Color fg = gc.getForeground();
115         if (selected) {
116             gc.setBackground(gc.getDevice().getSystemColor(SWT.COLOR_BLUE));
117             gc.setForeground(gc.getDevice().getSystemColor(SWT.COLOR_WHITE));
118         }
119         gc.fillRectangle(drawingArea);
120         SwtGraphicsHelper.drawStringCentered(gc, label, drawingArea.x, drawingArea.x + drawingArea.width, drawingArea.y
121                 + scaleY(INSETS));
122 
123         // int appStartY = drawingArea.y + scaleY(INSETS) + gc.textExtent(label).y;
124 
125         gc.setBackground(bg);
126         gc.setForeground(fg);
127         if (delegate.getDrawRowGrid()) {
128             if (delegate.getOrientation() == TimeBarViewerInterface.Orientation.HORIZONTAL) {
129                 gc.drawLine(drawingArea.x, drawingArea.y + drawingArea.height - 1, drawingArea.x + drawingArea.width,
130                         drawingArea.y + drawingArea.height - 1);
131             } else {
132                 gc.drawLine(drawingArea.x + drawingArea.width - 1, drawingArea.y,
133                         drawingArea.x + drawingArea.width - 1, drawingArea.y + drawingArea.height - 1);
134             }
135         }
136 
137         // draw the spanning appointments
138         bg = gc.getBackground();
139         for (AppointmentPlaceholder ph : day.getPlaceholders()) {
140             // check filtering
141             if (delegate.getIntervalFilter() == null
142                     || ((CalendarIntervalFilter) delegate.getIntervalFilter()).isInResultHeader(ph.getAppointment())) {
143                 int y = drawingArea.y + STARTAPPOINTMENTS + ph.getPosition() * (scaleY(APPOINTMENT_HEIGHT)+scaleY(1));
144                 gc.setBackground(gc.getDevice().getSystemColor(SWT.COLOR_YELLOW));
145 
146                 gc.drawRectangle(drawingArea.x, y, drawingArea.width, scaleY(APPOINTMENT_HEIGHT)-1);
147                 if (ph.isFirst()) {
148                     gc.fillRectangle(drawingArea.x + 1, y + 1, drawingArea.width, scaleY(APPOINTMENT_HEIGHT) - 2);
149 //                    int sx = drawingArea.x + scaleX(INSETS);
150 //                    if (!ph.getAppointment().isWholeDayAppointment()) {
151 //                        gc.drawImage(getClockImage(gc.getDevice()), sx, y);
152 //                        sx += getClockImage(gc.getDevice()).getBounds().width + scaleY(INSETS);
153 //                    }
154                     if (ph.isLast()) {
155                         gc.drawLine(drawingArea.x + drawingArea.width - 1, y + 1,
156                                 drawingArea.x + drawingArea.width - 1, y + scaleY(APPOINTMENT_HEIGHT) - 2);
157                     }
158 //                    SwtGraphicsHelper.drawStringVCentered(gc, ph.getAppointment().getText(), sx, y, y
159 //                            + scaleY(APPOINTMENT_HEIGHT));
160                 } else if (ph.isLast()) {
161                     gc.fillRectangle(drawingArea.x, y + 1, drawingArea.width - 1, scaleY(APPOINTMENT_HEIGHT) - 2);
162                 } else {
163                     gc.fillRectangle(drawingArea.x, y + 1, drawingArea.width, scaleY(APPOINTMENT_HEIGHT) - 2);
164                 }
165 
166                 // for every part of the appointment in the differnet rows paint the icon and and thet text
167                 // relying on the clipping on the gc
168                 TimeBarRow firstRow = ((CalendarModel)delegate.getModel()).getDay(ph.getAppointment().getRealBegin());
169                 int sx = delegate.yForRow(firstRow) + scaleX(INSETS);
170                 if (!ph.getAppointment().isWholeDayAppointment()) {
171                     gc.drawImage(getClockImage(gc.getDevice()), sx, y);
172                     sx += getClockImage(gc.getDevice()).getBounds().width + scaleY(INSETS);
173                 }
174                 SwtGraphicsHelper.drawStringVCentered(gc, ph.getAppointment().getText(), sx, y, y
175                         + scaleY(APPOINTMENT_HEIGHT));
176 
177                 
178                 
179                 // draw selection using alpha blending
180                 if (delegate.getSelectionModel().isSelected(ph.getAppointment())) {
181                     Color bgx = gc.getBackground();
182                     int alpha = gc.getAlpha();
183                     gc.setBackground(gc.getDevice().getSystemColor(SWT.COLOR_BLUE));
184                     gc.setAlpha(SELECTION_ALPHA);
185                     gc.fillRectangle(drawingArea.x, y + 1, drawingArea.width, scaleY(APPOINTMENT_HEIGHT) - 2);
186 
187                     gc.setAlpha(alpha);
188                     gc.setBackground(bgx);
189                 }
190 
191             }
192         }
193         gc.setBackground(bg);
194 
195     }
196 
197     protected static final int INSETS = 2;
198 
199     public static Appointment getAppointment(TimeBarViewer tbv, Day day, int by, int height, int x, int y) {
200         if (y < by + STARTAPPOINTMENTS || y > by + height) {
201             return null;
202         }
203         if (day.getPlaceholders().size() == 0) {
204             return null;
205         }
206         int pos = (y - by) / APPOINTMENT_HEIGHT;
207         Appointment app = day.getPlaceholderForPosition(pos - 1);
208         if (app == null) {
209             return null;
210         }
211         // check filtering
212         if (tbv.getIntervalFilter() == null || ((CalendarIntervalFilter) tbv.getIntervalFilter()).isInResultHeader(app)) {
213             return app;
214         }
215         return null;
216     }
217 
218     private String getLabel(GC gc, Rectangle drawingArea, Date date) {
219         if (_lastWidth == drawingArea.width && _lastFormatIdx != -1) {
220             return _formats.get(_lastFormatIdx).format(date);
221         }
222         _lastWidth = drawingArea.width;
223 
224         // check from long to short
225         for (int i = 0; i < _formats.size(); i++) {
226             DateFormat format = _formats.get(i);
227             String str = format.format(date);
228             Point extent = gc.stringExtent(str);
229             if (extent.x < drawingArea.width - 2 * INSETS) {
230                 _lastFormatIdx = i;
231                 return str;
232             }
233         }
234 
235         // no format is suitable, go with the shortest
236         return _formats.get(_formats.size() - 1).format(date);
237     }
238 
239     /***
240      * {@inheritDoc}
241      */
242     public String getToolTipText(TimeBarRow row, Rectangle drawingArea, int x, int y) {
243         if (row == null) {
244             return null;
245         }
246         return row.getRowHeader().getLabel();
247     }
248 
249     /***
250      * {@inheritDoc}
251      */
252     public boolean contains(Rectangle drawingArea, int x, int y) {
253         return true;
254     }
255 
256     /***
257      * {@inheritDoc}
258      */
259     public void dispose() {
260         if (_clockImage != null) {
261             _clockImage.dispose();
262         }
263         if (_imageRegistry != null) {
264             _imageRegistry.dispose();
265         }
266     }
267 
268     /***
269      * {@inheritDoc}
270      */
271     public DayHeaderRenderer createPrintRenderer(Printer printer) {
272         return new DayHeaderRenderer(printer);
273     }
274 
275     private Image _clockImage;
276     /*** image registry for holding the icon. */
277     protected ImageRegistry _imageRegistry;
278 
279     private Image getClockImage(Device device) {
280         if (_clockImage != null) {
281             return _clockImage;
282         }
283         _clockImage = getImageRegistry().getDescriptor("clock").createImage();
284         return _clockImage;
285     }
286     /***
287      * Retrieve the image registry (lazy creation).
288      * 
289      * @return the initialized registry
290      */
291     protected ImageRegistry getImageRegistry() {
292         if (_imageRegistry == null) {
293             _imageRegistry = new ImageRegistry();
294             ImageDescriptor imgDesc = new ResourceImageDescriptor(
295                     "/de/jaret/examples/timebars/calendar/swt/renderer/clock.gif");
296             _imageRegistry.put("clock", imgDesc);
297         }
298         return _imageRegistry;
299     }
300 
301 }