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 com.android.annotations.NonNull; 20 import com.android.annotations.Nullable; 21 22 import org.eclipse.swt.SWT; 23 import org.eclipse.swt.custom.CLabel; 24 import org.eclipse.swt.events.MouseEvent; 25 import org.eclipse.swt.events.MouseTrackListener; 26 import org.eclipse.swt.events.PaintEvent; 27 import org.eclipse.swt.events.PaintListener; 28 import org.eclipse.swt.graphics.Color; 29 import org.eclipse.swt.graphics.GC; 30 import org.eclipse.swt.graphics.Image; 31 import org.eclipse.swt.graphics.Point; 32 import org.eclipse.swt.graphics.Rectangle; 33 import org.eclipse.swt.widgets.Canvas; 34 import org.eclipse.swt.widgets.Composite; 35 36 /** 37 * An ImageControl which simply renders an image, with optional margins and tooltips. This 38 * is useful since a {@link CLabel}, even without text, will hide the image when there is 39 * not enough room to fully fit it. 40 * <p> 41 * The image is always rendered left and top aligned. 42 */ 43 public class ImageControl extends Canvas implements MouseTrackListener { 44 private Image mImage; 45 private int mLeftMargin; 46 private int mTopMargin; 47 private int mRightMargin; 48 private int mBottomMargin; 49 private boolean mDisposeImage = true; 50 private boolean mMouseIn; 51 private Color mHoverColor; 52 private float mScale = 1.0f; 53 54 /** 55 * Creates an ImageControl rendering the given image, which will be disposed when this 56 * control is disposed (unless the {@link #setDisposeImage} method is called to turn 57 * off auto dispose). 58 * 59 * @param parent the parent to add the image control to 60 * @param style the SWT style to use 61 * @param image the image to be rendered, which must not be null and should be unique 62 * for this image control since it will be disposed by this control when 63 * the control is disposed (unless the {@link #setDisposeImage} method is 64 * called to turn off auto dispose) 65 */ ImageControl(@onNull Composite parent, int style, @Nullable Image image)66 public ImageControl(@NonNull Composite parent, int style, @Nullable Image image) { 67 super(parent, style | SWT.NO_FOCUS | SWT.DOUBLE_BUFFERED); 68 mImage = image; 69 70 addPaintListener(new PaintListener() { 71 @Override 72 public void paintControl(PaintEvent event) { 73 onPaint(event); 74 } 75 }); 76 } 77 78 @Nullable getImage()79 public Image getImage() { 80 return mImage; 81 } 82 setImage(@ullable Image image)83 public void setImage(@Nullable Image image) { 84 if (mDisposeImage && mImage != null) { 85 mImage.dispose(); 86 } 87 mImage = image; 88 redraw(); 89 } 90 fitToWidth(int width)91 public void fitToWidth(int width) { 92 if (mImage == null) { 93 return; 94 } 95 Rectangle imageRect = mImage.getBounds(); 96 int imageWidth = imageRect.width; 97 if (imageWidth <= width) { 98 mScale = 1.0f; 99 return; 100 } 101 102 mScale = width / (float) imageWidth; 103 redraw(); 104 } 105 setScale(float scale)106 public void setScale(float scale) { 107 mScale = scale; 108 } 109 getScale()110 public float getScale() { 111 return mScale; 112 } 113 setHoverColor(@ullable Color hoverColor)114 public void setHoverColor(@Nullable Color hoverColor) { 115 if (mHoverColor != null) { 116 removeMouseTrackListener(this); 117 } 118 mHoverColor = hoverColor; 119 if (hoverColor != null) { 120 addMouseTrackListener(this); 121 } 122 } 123 124 @Nullable getHoverColor()125 public Color getHoverColor() { 126 return mHoverColor; 127 } 128 129 @Override dispose()130 public void dispose() { 131 super.dispose(); 132 133 if (mDisposeImage && mImage != null && !mImage.isDisposed()) { 134 mImage.dispose(); 135 } 136 mImage = null; 137 } 138 setDisposeImage(boolean disposeImage)139 public void setDisposeImage(boolean disposeImage) { 140 mDisposeImage = disposeImage; 141 } 142 getDisposeImage()143 public boolean getDisposeImage() { 144 return mDisposeImage; 145 } 146 147 @Override computeSize(int wHint, int hHint, boolean changed)148 public Point computeSize(int wHint, int hHint, boolean changed) { 149 checkWidget(); 150 Point e = new Point(0, 0); 151 if (mImage != null) { 152 Rectangle r = mImage.getBounds(); 153 if (mScale != 1.0f) { 154 e.x += mScale * r.width; 155 e.y += mScale * r.height; 156 } else { 157 e.x += r.width; 158 e.y += r.height; 159 } 160 } 161 if (wHint == SWT.DEFAULT) { 162 e.x += mLeftMargin + mRightMargin; 163 } else { 164 e.x = wHint; 165 } 166 if (hHint == SWT.DEFAULT) { 167 e.y += mTopMargin + mBottomMargin; 168 } else { 169 e.y = hHint; 170 } 171 172 return e; 173 } 174 onPaint(PaintEvent event)175 private void onPaint(PaintEvent event) { 176 Rectangle rect = getClientArea(); 177 if (mImage == null || rect.width == 0 || rect.height == 0) { 178 return; 179 } 180 181 GC gc = event.gc; 182 Rectangle imageRect = mImage.getBounds(); 183 int imageHeight = imageRect.height; 184 int imageWidth = imageRect.width; 185 int destWidth = imageWidth; 186 int destHeight = imageHeight; 187 188 int oldGcAlias = gc.getAntialias(); 189 int oldGcInterpolation = gc.getInterpolation(); 190 if (mScale != 1.0f) { 191 destWidth = (int) (mScale * destWidth); 192 destHeight = (int) (mScale * destHeight); 193 gc.setAntialias(SWT.ON); 194 gc.setInterpolation(SWT.HIGH); 195 } 196 197 gc.drawImage(mImage, 0, 0, imageWidth, imageHeight, rect.x + mLeftMargin, rect.y 198 + mTopMargin, destWidth, destHeight); 199 200 gc.setAntialias(oldGcAlias); 201 gc.setInterpolation(oldGcInterpolation); 202 203 if (mHoverColor != null && mMouseIn) { 204 gc.setAlpha(60); 205 gc.setBackground(mHoverColor); 206 gc.setLineWidth(1); 207 gc.fillRectangle(0, 0, destWidth, destHeight); 208 } 209 } 210 setMargins(int leftMargin, int topMargin, int rightMargin, int bottomMargin)211 public void setMargins(int leftMargin, int topMargin, int rightMargin, int bottomMargin) { 212 checkWidget(); 213 mLeftMargin = Math.max(0, leftMargin); 214 mTopMargin = Math.max(0, topMargin); 215 mRightMargin = Math.max(0, rightMargin); 216 mBottomMargin = Math.max(0, bottomMargin); 217 redraw(); 218 } 219 220 // ---- Implements MouseTrackListener ---- 221 222 @Override mouseEnter(MouseEvent e)223 public void mouseEnter(MouseEvent e) { 224 mMouseIn = true; 225 if (mHoverColor != null) { 226 redraw(); 227 } 228 } 229 230 @Override mouseExit(MouseEvent e)231 public void mouseExit(MouseEvent e) { 232 mMouseIn = false; 233 if (mHoverColor != null) { 234 redraw(); 235 } 236 } 237 238 @Override mouseHover(MouseEvent e)239 public void mouseHover(MouseEvent e) { 240 } 241 } 242