/* * Copyright (C) 2011 The Android Open Source Project * * Licensed under the Eclipse Public License, Version 1.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.eclipse.org/org/documents/epl-v10.php * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.ide.eclipse.adt.internal.editors.layout.gle2; import com.android.annotations.NonNull; import com.android.annotations.Nullable; import org.eclipse.swt.SWT; import org.eclipse.swt.custom.CLabel; import org.eclipse.swt.events.MouseEvent; import org.eclipse.swt.events.MouseTrackListener; import org.eclipse.swt.events.PaintEvent; import org.eclipse.swt.events.PaintListener; import org.eclipse.swt.graphics.Color; 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; /** * An ImageControl which simply renders an image, with optional margins and tooltips. This * is useful since a {@link CLabel}, even without text, will hide the image when there is * not enough room to fully fit it. * <p> * The image is always rendered left and top aligned. */ public class ImageControl extends Canvas implements MouseTrackListener { private Image mImage; private int mLeftMargin; private int mTopMargin; private int mRightMargin; private int mBottomMargin; private boolean mDisposeImage = true; private boolean mMouseIn; private Color mHoverColor; private float mScale = 1.0f; /** * Creates an ImageControl rendering the given image, which will be disposed when this * control is disposed (unless the {@link #setDisposeImage} method is called to turn * off auto dispose). * * @param parent the parent to add the image control to * @param style the SWT style to use * @param image the image to be rendered, which must not be null and should be unique * for this image control since it will be disposed by this control when * the control is disposed (unless the {@link #setDisposeImage} method is * called to turn off auto dispose) */ public ImageControl(@NonNull Composite parent, int style, @Nullable Image image) { super(parent, style | SWT.NO_FOCUS | SWT.DOUBLE_BUFFERED); mImage = image; addPaintListener(new PaintListener() { @Override public void paintControl(PaintEvent event) { onPaint(event); } }); } @Nullable public Image getImage() { return mImage; } public void setImage(@Nullable Image image) { if (mDisposeImage && mImage != null) { mImage.dispose(); } mImage = image; redraw(); } public void fitToWidth(int width) { if (mImage == null) { return; } Rectangle imageRect = mImage.getBounds(); int imageWidth = imageRect.width; if (imageWidth <= width) { mScale = 1.0f; return; } mScale = width / (float) imageWidth; redraw(); } public void setScale(float scale) { mScale = scale; } public float getScale() { return mScale; } public void setHoverColor(@Nullable Color hoverColor) { if (mHoverColor != null) { removeMouseTrackListener(this); } mHoverColor = hoverColor; if (hoverColor != null) { addMouseTrackListener(this); } } @Nullable public Color getHoverColor() { return mHoverColor; } @Override public void dispose() { super.dispose(); if (mDisposeImage && mImage != null && !mImage.isDisposed()) { mImage.dispose(); } mImage = null; } public void setDisposeImage(boolean disposeImage) { mDisposeImage = disposeImage; } public boolean getDisposeImage() { return mDisposeImage; } @Override public Point computeSize(int wHint, int hHint, boolean changed) { checkWidget(); Point e = new Point(0, 0); if (mImage != null) { Rectangle r = mImage.getBounds(); if (mScale != 1.0f) { e.x += mScale * r.width; e.y += mScale * r.height; } else { e.x += r.width; e.y += r.height; } } if (wHint == SWT.DEFAULT) { e.x += mLeftMargin + mRightMargin; } else { e.x = wHint; } if (hHint == SWT.DEFAULT) { e.y += mTopMargin + mBottomMargin; } else { e.y = hHint; } return e; } private void onPaint(PaintEvent event) { Rectangle rect = getClientArea(); if (mImage == null || rect.width == 0 || rect.height == 0) { return; } GC gc = event.gc; Rectangle imageRect = mImage.getBounds(); int imageHeight = imageRect.height; int imageWidth = imageRect.width; int destWidth = imageWidth; int destHeight = imageHeight; int oldGcAlias = gc.getAntialias(); int oldGcInterpolation = gc.getInterpolation(); if (mScale != 1.0f) { destWidth = (int) (mScale * destWidth); destHeight = (int) (mScale * destHeight); gc.setAntialias(SWT.ON); gc.setInterpolation(SWT.HIGH); } gc.drawImage(mImage, 0, 0, imageWidth, imageHeight, rect.x + mLeftMargin, rect.y + mTopMargin, destWidth, destHeight); gc.setAntialias(oldGcAlias); gc.setInterpolation(oldGcInterpolation); if (mHoverColor != null && mMouseIn) { gc.setAlpha(60); gc.setBackground(mHoverColor); gc.setLineWidth(1); gc.fillRectangle(0, 0, destWidth, destHeight); } } public void setMargins(int leftMargin, int topMargin, int rightMargin, int bottomMargin) { checkWidget(); mLeftMargin = Math.max(0, leftMargin); mTopMargin = Math.max(0, topMargin); mRightMargin = Math.max(0, rightMargin); mBottomMargin = Math.max(0, bottomMargin); redraw(); } // ---- Implements MouseTrackListener ---- @Override public void mouseEnter(MouseEvent e) { mMouseIn = true; if (mHoverColor != null) { redraw(); } } @Override public void mouseExit(MouseEvent e) { mMouseIn = false; if (mHoverColor != null) { redraw(); } } @Override public void mouseHover(MouseEvent e) { } }