Home | History | Annotate | Download | only in gle2
      1 /*
      2  * Copyright (C) 2009 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 package com.android.ide.eclipse.adt.internal.editors.layout.gle2;
     17 
     18 import static com.android.ide.eclipse.adt.internal.editors.layout.gle2.ImageUtils.SHADOW_SIZE;
     19 
     20 import org.eclipse.swt.events.SelectionAdapter;
     21 import org.eclipse.swt.events.SelectionEvent;
     22 import org.eclipse.swt.widgets.ScrollBar;
     23 
     24 /**
     25  * Helper class to convert between control pixel coordinates and canvas coordinates.
     26  * Takes care of the zooming and offset of the canvas.
     27  */
     28 public class CanvasTransform {
     29     /**
     30      * Default margin around the rendered image, reduced
     31      * when the contents do not fit.
     32      */
     33     public static final int DEFAULT_MARGIN = 25;
     34 
     35     /**
     36      * The canvas which controls the zooming.
     37      */
     38     private final LayoutCanvas mCanvas;
     39 
     40     /** Canvas image size (original, before zoom), in pixels. */
     41     private int mImgSize;
     42 
     43     /** Full size being scrolled (after zoom), in pixels */
     44     private int mFullSize;;
     45 
     46     /** Client size, in pixels. */
     47     private int mClientSize;
     48 
     49     /** Left-top offset in client pixel coordinates. */
     50     private int mTranslate;
     51 
     52     /** Current margin */
     53     private int mMargin = DEFAULT_MARGIN;
     54 
     55     /** Scaling factor, > 0. */
     56     private double mScale;
     57 
     58     /** Scrollbar widget. */
     59     private ScrollBar mScrollbar;
     60 
     61     public CanvasTransform(LayoutCanvas layoutCanvas, ScrollBar scrollbar) {
     62         mCanvas = layoutCanvas;
     63         mScrollbar = scrollbar;
     64         mScale = 1.0;
     65         mTranslate = 0;
     66 
     67         mScrollbar.addSelectionListener(new SelectionAdapter() {
     68             @Override
     69             public void widgetSelected(SelectionEvent e) {
     70                 // User requested scrolling. Changes translation and redraw canvas.
     71                 mTranslate = mScrollbar.getSelection();
     72                 CanvasTransform.this.mCanvas.redraw();
     73             }
     74         });
     75         mScrollbar.setIncrement(20);
     76     }
     77 
     78     /**
     79      * Sets the new scaling factor. Recomputes scrollbars.
     80      * @param scale Scaling factor, > 0.
     81      */
     82     public void setScale(double scale) {
     83         if (mScale != scale) {
     84             mScale = scale;
     85             resizeScrollbar();
     86         }
     87     }
     88 
     89     /** Recomputes the scrollbar and view port settings */
     90     public void refresh() {
     91         resizeScrollbar();
     92     }
     93 
     94     /**
     95      * Returns current scaling factor.
     96      *
     97      * @return The current scaling factor
     98      */
     99     public double getScale() {
    100         return mScale;
    101     }
    102 
    103     /**
    104      * Returns Canvas image size (original, before zoom), in pixels.
    105      *
    106      * @return Canvas image size (original, before zoom), in pixels
    107      */
    108     public int getImgSize() {
    109         return mImgSize;
    110     }
    111 
    112     /**
    113      * Returns the scaled image size in pixels.
    114      *
    115      * @return The scaled image size in pixels.
    116      */
    117     public int getScaledImgSize() {
    118         return (int) (mImgSize * mScale);
    119     }
    120 
    121     /**
    122      * Changes the size of the canvas image and the client size. Recomputes
    123      * scrollbars.
    124      *
    125      * @param imgSize the size of the image being scaled
    126      * @param fullSize the size of the full view area being scrolled
    127      * @param clientSize the size of the view port
    128      */
    129     public void setSize(int imgSize, int fullSize, int clientSize) {
    130         mImgSize = imgSize;
    131         mFullSize = fullSize;
    132         mClientSize = clientSize;
    133         mScrollbar.setPageIncrement(clientSize);
    134         resizeScrollbar();
    135     }
    136 
    137     private void resizeScrollbar() {
    138         // scaled image size
    139         int sx = (int) (mScale * mFullSize);
    140 
    141         // Adjust margin such that for zoomed out views
    142         // we don't waste space (unless the viewport is
    143         // large enough to accommodate it)
    144         int delta = mClientSize - sx;
    145         if (delta < 0) {
    146             mMargin = 0;
    147         } else if (delta < 2 * DEFAULT_MARGIN) {
    148             mMargin = delta / 2;
    149 
    150             ImageOverlay imageOverlay = mCanvas.getImageOverlay();
    151             if (imageOverlay != null && imageOverlay.getShowDropShadow()
    152                     && delta >= SHADOW_SIZE / 2) {
    153                 mMargin -= SHADOW_SIZE / 2;
    154                 // Add a little padding on the top too, if there's room. The shadow assets
    155                 // include enough padding on the bottom to not make this look clipped.
    156                 if (mMargin < 4) {
    157                     mMargin += 4;
    158                 }
    159             }
    160         } else {
    161             mMargin = DEFAULT_MARGIN;
    162         }
    163 
    164         if (mCanvas.getPreviewManager().hasPreviews()) {
    165             // Make more room for the previews
    166             mMargin = 2;
    167         }
    168 
    169         // actual client area is always reduced by the margins
    170         int cx = mClientSize - 2 * mMargin;
    171 
    172         if (sx < cx) {
    173             mTranslate = 0;
    174             mScrollbar.setEnabled(false);
    175         } else {
    176             mScrollbar.setEnabled(true);
    177 
    178             int selection = mScrollbar.getSelection();
    179             int thumb = cx;
    180             int maximum = sx;
    181 
    182             if (selection + thumb > maximum) {
    183                 selection = maximum - thumb;
    184                 if (selection < 0) {
    185                     selection = 0;
    186                 }
    187             }
    188 
    189             mScrollbar.setValues(selection, mScrollbar.getMinimum(), maximum, thumb, mScrollbar
    190                     .getIncrement(), mScrollbar.getPageIncrement());
    191 
    192             mTranslate = selection;
    193         }
    194     }
    195 
    196     public int getMargin() {
    197         return mMargin;
    198     }
    199 
    200     public int translate(int canvasX) {
    201         return mMargin - mTranslate + (int) (mScale * canvasX);
    202     }
    203 
    204     public int scale(int canwasW) {
    205         return (int) (mScale * canwasW);
    206     }
    207 
    208     public int inverseTranslate(int screenX) {
    209         return (int) ((screenX - mMargin + mTranslate) / mScale);
    210     }
    211 
    212     public int inverseScale(int canwasW) {
    213         return (int) (canwasW / mScale);
    214     }
    215 }
    216