1 /* 2 * Copyright (C) 2011 The Android Open Source Project 3 * 4 * Licensed under the Eclipse Public License, Version 1.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.eclipse.org/org/documents/epl-v10.php 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.ide.eclipse.adt.internal.editors.layout.gle2; 18 19 import org.eclipse.swt.SWT; 20 import org.eclipse.swt.custom.CLabel; 21 import org.eclipse.swt.events.MouseEvent; 22 import org.eclipse.swt.events.MouseTrackListener; 23 import org.eclipse.swt.events.PaintEvent; 24 import org.eclipse.swt.events.PaintListener; 25 import org.eclipse.swt.graphics.Color; 26 import org.eclipse.swt.graphics.GC; 27 import org.eclipse.swt.graphics.Image; 28 import org.eclipse.swt.graphics.Point; 29 import org.eclipse.swt.graphics.Rectangle; 30 import org.eclipse.swt.widgets.Canvas; 31 import org.eclipse.swt.widgets.Composite; 32 33 /** 34 * An ImageControl which simply renders an image, with optional margins and tooltips. This 35 * is useful since a {@link CLabel}, even without text, will hide the image when there is 36 * not enough room to fully fit it. 37 * <p> 38 * The image is always rendered left and top aligned. 39 */ 40 public class ImageControl extends Canvas implements MouseTrackListener { 41 private Image mImage; 42 private int mLeftMargin; 43 private int mTopMargin; 44 private int mRightMargin; 45 private int mBottomMargin; 46 private boolean mDisposeImage = true; 47 private boolean mMouseIn; 48 private Color mHoverColor; 49 private float mScale = 1.0f; 50 51 /** 52 * Creates an ImageControl rendering the given image, which will be disposed when this 53 * control is disposed (unless the {@link #setDisposeImage} method is called to turn 54 * off auto dispose). 55 * 56 * @param parent the parent to add the image control to 57 * @param style the SWT style to use 58 * @param image the image to be rendered, which must not be null and should be unique 59 * for this image control since it will be disposed by this control when 60 * the control is disposed (unless the {@link #setDisposeImage} method is 61 * called to turn off auto dispose) 62 */ 63 public ImageControl(Composite parent, int style, Image image) { 64 super(parent, style | SWT.NO_FOCUS | SWT.DOUBLE_BUFFERED); 65 this.mImage = image; 66 67 addPaintListener(new PaintListener() { 68 public void paintControl(PaintEvent event) { 69 onPaint(event); 70 } 71 }); 72 } 73 74 public void setImage(Image image) { 75 if (mDisposeImage) { 76 mImage.dispose(); 77 } 78 mImage = image; 79 } 80 81 public void setScale(float scale) { 82 mScale = scale; 83 } 84 85 public float getScale() { 86 return mScale; 87 } 88 89 public void setHoverColor(Color hoverColor) { 90 mHoverColor = hoverColor; 91 if (hoverColor != null) { 92 addMouseTrackListener(this); 93 } 94 } 95 96 public Color getHoverColor() { 97 return mHoverColor; 98 } 99 100 @Override 101 public void dispose() { 102 super.dispose(); 103 104 if (mDisposeImage) { 105 mImage.dispose(); 106 } 107 mImage = null; 108 } 109 110 public void setDisposeImage(boolean mDisposeImage) { 111 this.mDisposeImage = mDisposeImage; 112 } 113 114 public boolean getDisposeImage() { 115 return mDisposeImage; 116 } 117 118 @Override 119 public Point computeSize(int wHint, int hHint, boolean changed) { 120 checkWidget(); 121 Point e = new Point(0, 0); 122 if (mImage != null) { 123 Rectangle r = mImage.getBounds(); 124 if (mScale != 1.0f) { 125 e.x += mScale * r.width; 126 e.y += mScale * r.height; 127 } else { 128 e.x += r.width; 129 e.y += r.height; 130 } 131 } 132 if (wHint == SWT.DEFAULT) { 133 e.x += mLeftMargin + mRightMargin; 134 } else { 135 e.x = wHint; 136 } 137 if (hHint == SWT.DEFAULT) { 138 e.y += mTopMargin + mBottomMargin; 139 } else { 140 e.y = hHint; 141 } 142 143 return e; 144 } 145 146 private void onPaint(PaintEvent event) { 147 Rectangle rect = getClientArea(); 148 if (mImage == null || rect.width == 0 || rect.height == 0) { 149 return; 150 } 151 152 GC gc = event.gc; 153 Rectangle imageRect = mImage.getBounds(); 154 int imageHeight = imageRect.height; 155 int imageWidth = imageRect.width; 156 int destWidth = imageWidth; 157 int destHeight = imageHeight; 158 159 int oldGcAlias = gc.getAntialias(); 160 int oldGcInterpolation = gc.getInterpolation(); 161 if (mScale != 1.0f) { 162 destWidth = (int) (mScale * destWidth); 163 destHeight = (int) (mScale * destHeight); 164 gc.setAntialias(SWT.ON); 165 gc.setInterpolation(SWT.HIGH); 166 } 167 168 gc.drawImage(mImage, 0, 0, imageWidth, imageHeight, rect.x + mLeftMargin, rect.y 169 + mTopMargin, destWidth, destHeight); 170 171 gc.setAntialias(oldGcAlias); 172 gc.setInterpolation(oldGcInterpolation); 173 174 if (mHoverColor != null && mMouseIn) { 175 gc.setAlpha(60); 176 gc.setBackground(mHoverColor); 177 gc.setLineWidth(1); 178 gc.fillRectangle(0, 0, destWidth, destHeight); 179 } 180 } 181 182 public void setMargins(int leftMargin, int topMargin, int rightMargin, int bottomMargin) { 183 checkWidget(); 184 mLeftMargin = Math.max(0, leftMargin); 185 mTopMargin = Math.max(0, topMargin); 186 mRightMargin = Math.max(0, rightMargin); 187 mBottomMargin = Math.max(0, bottomMargin); 188 redraw(); 189 } 190 191 // ---- Implements MouseTrackListener ---- 192 193 public void mouseEnter(MouseEvent e) { 194 mMouseIn = true; 195 if (mHoverColor != null) { 196 redraw(); 197 } 198 } 199 200 public void mouseExit(MouseEvent e) { 201 mMouseIn = false; 202 if (mHoverColor != null) { 203 redraw(); 204 } 205 } 206 207 public void mouseHover(MouseEvent e) { 208 } 209 } 210