CImageLabel.java revision 765e52e2d30d0754625b8c7af6c36e93612f15be
1/*******************************************************************************
2 * Copyright (c) 2011 Google, Inc.
3 * All rights reserved. This program and the accompanying materials
4 * are made available under the terms of the Eclipse Public License v1.0
5 * which accompanies this distribution, and is available at
6 * http://www.eclipse.org/legal/epl-v10.html
7 *
8 * Contributors:
9 *    Google, Inc. - initial API and implementation
10 *******************************************************************************/
11package org.eclipse.wb.core.controls;
12
13import org.eclipse.swt.SWT;
14import org.eclipse.swt.graphics.GC;
15import org.eclipse.swt.graphics.Image;
16import org.eclipse.swt.graphics.Point;
17import org.eclipse.swt.graphics.Rectangle;
18import org.eclipse.swt.widgets.Canvas;
19import org.eclipse.swt.widgets.Composite;
20import org.eclipse.swt.widgets.Event;
21import org.eclipse.swt.widgets.Listener;
22
23/**
24 * Simple control for displaying image and text.
25 *
26 * For unknown reason CLabel shows such things not very good - vertical text alignment is strange
27 * (bottom?).
28 *
29 * @author scheglov_ke
30 * @coverage core.control
31 */
32public class CImageLabel extends Canvas {
33  private static final int SPACE = 5;
34  private Image m_image;
35  private String m_text;
36
37  ////////////////////////////////////////////////////////////////////////////
38  //
39  // Constructor
40  //
41  ////////////////////////////////////////////////////////////////////////////
42  public CImageLabel(Composite parent, int style) {
43    super(parent, style | SWT.NO_BACKGROUND);
44    addListener(SWT.Dispose, new Listener() {
45      public void handleEvent(Event event) {
46        if (m_backImage != null) {
47          m_backImage.dispose();
48          m_backImage = null;
49        }
50      }
51    });
52    addListener(SWT.Paint, new Listener() {
53      public void handleEvent(Event event) {
54        doPaint(event.gc);
55      }
56    });
57  }
58
59  ////////////////////////////////////////////////////////////////////////////
60  //
61  // Access
62  //
63  ////////////////////////////////////////////////////////////////////////////
64  public Image getImage() {
65    return m_image;
66  }
67
68  public void setImage(Image image) {
69    m_image = image;
70    redraw();
71  }
72
73  public String getText() {
74    return m_text;
75  }
76
77  public void setText(String text) {
78    m_text = text;
79    redraw();
80  }
81
82  ////////////////////////////////////////////////////////////////////////////
83  //
84  // Paint
85  //
86  ////////////////////////////////////////////////////////////////////////////
87  private Image m_backImage;
88
89  private void doPaint(GC paintGC) {
90    Rectangle clientArea = getClientArea();
91    // prepare back image
92    GC gc;
93    {
94      if (m_backImage == null || !m_backImage.getBounds().equals(clientArea)) {
95        if (m_backImage != null) {
96          m_backImage.dispose();
97        }
98        m_backImage = new Image(getDisplay(), clientArea.width, clientArea.height);
99      }
100      //
101      gc = new GC(m_backImage);
102      gc.setBackground(paintGC.getBackground());
103      gc.setForeground(paintGC.getForeground());
104      gc.fillRectangle(clientArea);
105    }
106    //
107    Point textExtent = m_text == null ? new Point(0, 0) : gc.textExtent(m_text);
108    Rectangle imageBounds = m_image == null ? new Rectangle(0, 0, 0, 0) : m_image.getBounds();
109    //
110    if (m_image != null) {
111      int x = clientArea.x;
112      int y = clientArea.y + (clientArea.height - imageBounds.height) / 2;
113      gc.drawImage(m_image, x, y);
114    }
115    if (m_text != null) {
116      int x = clientArea.x + imageBounds.width + SPACE;
117      int y = clientArea.y + (clientArea.height - textExtent.y) / 2;
118      gc.drawText(m_text, x, y);
119    }
120    // flush back image
121    {
122      paintGC.drawImage(m_backImage, 0, 0);
123      gc.dispose();
124    }
125  }
126
127  @Override
128  public Point computeSize(int wHint, int hHint, boolean changed) {
129    // prepare text size
130    GC gc = new GC(this);
131    Point textExtent = m_text == null ? new Point(0, 0) : gc.textExtent(m_text);
132    gc.dispose();
133    // prepare image size
134    Rectangle imageBounds = m_image == null ? new Rectangle(0, 0, 0, 0) : m_image.getBounds();
135    // calculate control size
136    int width = imageBounds.width + SPACE + textExtent.x;
137    int height = Math.max(imageBounds.height, textExtent.y);
138    return new Point(width, height);
139  }
140}
141