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 org.eclipse.swt.events.SelectionAdapter;
     19 import org.eclipse.swt.events.SelectionEvent;
     20 import org.eclipse.swt.widgets.ScrollBar;
     21 
     22 /**
     23  * Helper class to convert between control pixel coordinates and canvas coordinates.
     24  * Takes care of the zooming and offset of the canvas.
     25  */
     26 public class CanvasTransform {
     27     /**
     28      * Default margin around the rendered image, reduced
     29      * when the contents do not fit.
     30      */
     31     public static final int DEFAULT_MARGIN = 25;
     32 
     33     /**
     34      * The canvas which controls the zooming.
     35      */
     36     private final LayoutCanvas mCanvas;
     37 
     38     /** Canvas image size (original, before zoom), in pixels. */
     39     private int mImgSize;
     40 
     41     /** Client size, in pixels. */
     42     private int mClientSize;
     43 
     44     /** Left-top offset in client pixel coordinates. */
     45     private int mTranslate;
     46 
     47     /** Current margin */
     48     private int mMargin = DEFAULT_MARGIN;
     49 
     50     /** Scaling factor, > 0. */
     51     private double mScale;
     52 
     53     /** Scrollbar widget. */
     54     private ScrollBar mScrollbar;
     55 
     56     public CanvasTransform(LayoutCanvas layoutCanvas, ScrollBar scrollbar) {
     57         mCanvas = layoutCanvas;
     58         mScrollbar = scrollbar;
     59         mScale = 1.0;
     60         mTranslate = 0;
     61 
     62         mScrollbar.addSelectionListener(new SelectionAdapter() {
     63             @Override
     64             public void widgetSelected(SelectionEvent e) {
     65                 // User requested scrolling. Changes translation and redraw canvas.
     66                 mTranslate = mScrollbar.getSelection();
     67                 CanvasTransform.this.mCanvas.redraw();
     68             }
     69         });
     70         mScrollbar.setIncrement(20);
     71     }
     72 
     73     /**
     74      * Sets the new scaling factor. Recomputes scrollbars.
     75      * @param scale Scaling factor, > 0.
     76      */
     77     public void setScale(double scale) {
     78         if (mScale != scale) {
     79             mScale = scale;
     80             resizeScrollbar();
     81         }
     82     }
     83 
     84     /**
     85      * Returns current scaling factor.
     86      *
     87      * @return The current scaling factor
     88      */
     89     public double getScale() {
     90         return mScale;
     91     }
     92 
     93     /**
     94      * Returns Canvas image size (original, before zoom), in pixels.
     95      *
     96      * @return Canvas image size (original, before zoom), in pixels
     97      */
     98     public int getImgSize() {
     99         return mImgSize;
    100     }
    101 
    102     /**
    103      * Returns the scaled image size in pixels.
    104      *
    105      * @return The scaled image size in pixels.
    106      */
    107     public int getScalledImgSize() {
    108         return (int) (mImgSize * mScale);
    109     }
    110 
    111     /** Changes the size of the canvas image and the client size. Recomputes scrollbars. */
    112     public void setSize(int imgSize, int clientSize) {
    113         mImgSize = imgSize;
    114         setClientSize(clientSize);
    115     }
    116 
    117     /** Changes the size of the client size. Recomputes scrollbars. */
    118     public void setClientSize(int clientSize) {
    119         mClientSize = clientSize;
    120         mScrollbar.setPageIncrement(clientSize);
    121         resizeScrollbar();
    122     }
    123 
    124     private void resizeScrollbar() {
    125         // scaled image size
    126         int sx = (int) (mImgSize * mScale);
    127 
    128         // Adjust margin such that for zoomed out views
    129         // we don't waste space (unless the viewport is
    130         // large enough to accommodate it)
    131         int delta = mClientSize - sx;
    132         if (delta < 0) {
    133             mMargin = 0;
    134         } else if (delta < 2 * DEFAULT_MARGIN) {
    135             mMargin = delta / 2;
    136         } else {
    137             mMargin = DEFAULT_MARGIN;
    138         }
    139 
    140         // actual client area is always reduced by the margins
    141         int cx = mClientSize - 2 * mMargin;
    142 
    143         if (sx < cx) {
    144             mTranslate = 0;
    145             mScrollbar.setEnabled(false);
    146         } else {
    147             mScrollbar.setEnabled(true);
    148 
    149             int selection = mScrollbar.getSelection();
    150             int thumb = cx;
    151             int maximum = sx;
    152 
    153             if (selection + thumb > maximum) {
    154                 selection = maximum - thumb;
    155                 if (selection < 0) {
    156                     selection = 0;
    157                 }
    158             }
    159 
    160             mScrollbar.setValues(selection, mScrollbar.getMinimum(), maximum, thumb, mScrollbar
    161                     .getIncrement(), mScrollbar.getPageIncrement());
    162 
    163             mTranslate = selection;
    164         }
    165     }
    166 
    167     public int getMargin() {
    168         return mMargin;
    169     }
    170 
    171     public int translate(int canvasX) {
    172         return mMargin - mTranslate + (int) (mScale * canvasX);
    173     }
    174 
    175     public int scale(int canwasW) {
    176         return (int) (mScale * canwasW);
    177     }
    178 
    179     public int inverseTranslate(int screenX) {
    180         return (int) ((screenX - mMargin + mTranslate) / mScale);
    181     }
    182 }
    183