summaryrefslogtreecommitdiff
path: root/propertysheet/src/org/eclipse/wb/core/controls/CImageLabel.java
blob: eb5bce41fc453969cfc650027c5cccad35ab96c9 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
/*******************************************************************************
 * Copyright (c) 2011 Google, Inc.
 * 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:
 *    Google, Inc. - initial API and implementation
 *******************************************************************************/
package org.eclipse.wb.core.controls;

import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.widgets.Canvas;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Listener;

/**
 * Simple control for displaying image and text.
 * 
 * For unknown reason CLabel shows such things not very good - vertical text alignment is strange
 * (bottom?).
 * 
 * @author scheglov_ke
 * @coverage core.control
 */
public class CImageLabel extends Canvas {
  private static final int SPACE = 5;
  private Image m_image;
  private String m_text;

  ////////////////////////////////////////////////////////////////////////////
  //
  // Constructor
  //
  ////////////////////////////////////////////////////////////////////////////
  public CImageLabel(Composite parent, int style) {
    super(parent, style | SWT.NO_BACKGROUND);
    addListener(SWT.Dispose, new Listener() {
      public void handleEvent(Event event) {
        if (m_backImage != null) {
          m_backImage.dispose();
          m_backImage = null;
        }
      }
    });
    addListener(SWT.Paint, new Listener() {
      public void handleEvent(Event event) {
        doPaint(event.gc);
      }
    });
  }

  ////////////////////////////////////////////////////////////////////////////
  //
  // Access
  //
  ////////////////////////////////////////////////////////////////////////////
  public Image getImage() {
    return m_image;
  }

  public void setImage(Image image) {
    m_image = image;
    redraw();
  }

  public String getText() {
    return m_text;
  }

  public void setText(String text) {
    m_text = text;
    redraw();
  }

  ////////////////////////////////////////////////////////////////////////////
  //
  // Paint
  //
  ////////////////////////////////////////////////////////////////////////////
  private Image m_backImage;

  private void doPaint(GC paintGC) {
    Rectangle clientArea = getClientArea();
    // prepare back image
    GC gc;
    {
      if (m_backImage == null || !m_backImage.getBounds().equals(clientArea)) {
        if (m_backImage != null) {
          m_backImage.dispose();
        }
        m_backImage = new Image(getDisplay(), clientArea.width, clientArea.height);
      }
      //
      gc = new GC(m_backImage);
      gc.setBackground(paintGC.getBackground());
      gc.setForeground(paintGC.getForeground());
      gc.fillRectangle(clientArea);
    }
    //
    Point textExtent = m_text == null ? new Point(0, 0) : gc.textExtent(m_text);
    Rectangle imageBounds = m_image == null ? new Rectangle(0, 0, 0, 0) : m_image.getBounds();
    //
    if (m_image != null) {
      int x = clientArea.x;
      int y = clientArea.y + (clientArea.height - imageBounds.height) / 2;
      gc.drawImage(m_image, x, y);
    }
    if (m_text != null) {
      int x = clientArea.x + imageBounds.width + SPACE;
      int y = clientArea.y + (clientArea.height - textExtent.y) / 2;
      gc.drawText(m_text, x, y);
    }
    // flush back image
    {
      paintGC.drawImage(m_backImage, 0, 0);
      gc.dispose();
    }
  }

  @Override
  public Point computeSize(int wHint, int hHint, boolean changed) {
    // prepare text size
    GC gc = new GC(this);
    Point textExtent = m_text == null ? new Point(0, 0) : gc.textExtent(m_text);
    gc.dispose();
    // prepare image size
    Rectangle imageBounds = m_image == null ? new Rectangle(0, 0, 0, 0) : m_image.getBounds();
    // calculate control size
    int width = imageBounds.width + SPACE + textExtent.x;
    int height = Math.max(imageBounds.height, textExtent.y);
    return new Point(width, height);
  }
}