• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
CanvasTransform(LayoutCanvas layoutCanvas, ScrollBar scrollbar)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      */
setScale(double scale)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      */
getScale()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      */
getImgSize()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      */
getScalledImgSize()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. */
setSize(int imgSize, int clientSize)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. */
setClientSize(int clientSize)118     public void setClientSize(int clientSize) {
119         mClientSize = clientSize;
120         mScrollbar.setPageIncrement(clientSize);
121         resizeScrollbar();
122     }
123 
resizeScrollbar()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 
getMargin()167     public int getMargin() {
168         return mMargin;
169     }
170 
translate(int canvasX)171     public int translate(int canvasX) {
172         return mMargin - mTranslate + (int) (mScale * canvasX);
173     }
174 
scale(int canwasW)175     public int scale(int canwasW) {
176         return (int) (mScale * canwasW);
177     }
178 
inverseTranslate(int screenX)179     public int inverseTranslate(int screenX) {
180         return (int) ((screenX - mMargin + mTranslate) / mScale);
181     }
182 }
183