Home | History | Annotate | Download | only in gle2
      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      */
     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
     79     public Image getImage() {
     80         return mImage;
     81     }
     82 
     83     public void setImage(@Nullable Image image) {
     84         if (mDisposeImage && mImage != null) {
     85             mImage.dispose();
     86         }
     87         mImage = image;
     88         redraw();
     89     }
     90 
     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 
    106     public void setScale(float scale) {
    107         mScale = scale;
    108     }
    109 
    110     public float getScale() {
    111         return mScale;
    112     }
    113 
    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
    125     public Color getHoverColor() {
    126         return mHoverColor;
    127     }
    128 
    129     @Override
    130     public void dispose() {
    131         super.dispose();
    132 
    133         if (mDisposeImage && mImage != null && !mImage.isDisposed()) {
    134             mImage.dispose();
    135         }
    136         mImage = null;
    137     }
    138 
    139     public void setDisposeImage(boolean disposeImage) {
    140         mDisposeImage = disposeImage;
    141     }
    142 
    143     public boolean getDisposeImage() {
    144         return mDisposeImage;
    145     }
    146 
    147     @Override
    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 
    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 
    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
    223     public void mouseEnter(MouseEvent e) {
    224         mMouseIn = true;
    225         if (mHoverColor != null) {
    226             redraw();
    227         }
    228     }
    229 
    230     @Override
    231     public void mouseExit(MouseEvent e) {
    232         mMouseIn = false;
    233         if (mHoverColor != null) {
    234             redraw();
    235         }
    236     }
    237 
    238     @Override
    239     public void mouseHover(MouseEvent e) {
    240     }
    241 }
    242