diff options
Diffstat (limited to 'eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/gle2/CanvasTransform.java')
-rw-r--r-- | eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/gle2/CanvasTransform.java | 215 |
1 files changed, 215 insertions, 0 deletions
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/gle2/CanvasTransform.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/gle2/CanvasTransform.java new file mode 100644 index 000000000..ad5bd52e5 --- /dev/null +++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/gle2/CanvasTransform.java @@ -0,0 +1,215 @@ +/* + * Copyright (C) 2009 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 static com.android.ide.eclipse.adt.internal.editors.layout.gle2.ImageUtils.SHADOW_SIZE; + +import org.eclipse.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.widgets.ScrollBar; + +/** + * Helper class to convert between control pixel coordinates and canvas coordinates. + * Takes care of the zooming and offset of the canvas. + */ +public class CanvasTransform { + /** + * Default margin around the rendered image, reduced + * when the contents do not fit. + */ + public static final int DEFAULT_MARGIN = 25; + + /** + * The canvas which controls the zooming. + */ + private final LayoutCanvas mCanvas; + + /** Canvas image size (original, before zoom), in pixels. */ + private int mImgSize; + + /** Full size being scrolled (after zoom), in pixels */ + private int mFullSize;; + + /** Client size, in pixels. */ + private int mClientSize; + + /** Left-top offset in client pixel coordinates. */ + private int mTranslate; + + /** Current margin */ + private int mMargin = DEFAULT_MARGIN; + + /** Scaling factor, > 0. */ + private double mScale; + + /** Scrollbar widget. */ + private ScrollBar mScrollbar; + + public CanvasTransform(LayoutCanvas layoutCanvas, ScrollBar scrollbar) { + mCanvas = layoutCanvas; + mScrollbar = scrollbar; + mScale = 1.0; + mTranslate = 0; + + mScrollbar.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + // User requested scrolling. Changes translation and redraw canvas. + mTranslate = mScrollbar.getSelection(); + CanvasTransform.this.mCanvas.redraw(); + } + }); + mScrollbar.setIncrement(20); + } + + /** + * Sets the new scaling factor. Recomputes scrollbars. + * @param scale Scaling factor, > 0. + */ + public void setScale(double scale) { + if (mScale != scale) { + mScale = scale; + resizeScrollbar(); + } + } + + /** Recomputes the scrollbar and view port settings */ + public void refresh() { + resizeScrollbar(); + } + + /** + * Returns current scaling factor. + * + * @return The current scaling factor + */ + public double getScale() { + return mScale; + } + + /** + * Returns Canvas image size (original, before zoom), in pixels. + * + * @return Canvas image size (original, before zoom), in pixels + */ + public int getImgSize() { + return mImgSize; + } + + /** + * Returns the scaled image size in pixels. + * + * @return The scaled image size in pixels. + */ + public int getScaledImgSize() { + return (int) (mImgSize * mScale); + } + + /** + * Changes the size of the canvas image and the client size. Recomputes + * scrollbars. + * + * @param imgSize the size of the image being scaled + * @param fullSize the size of the full view area being scrolled + * @param clientSize the size of the view port + */ + public void setSize(int imgSize, int fullSize, int clientSize) { + mImgSize = imgSize; + mFullSize = fullSize; + mClientSize = clientSize; + mScrollbar.setPageIncrement(clientSize); + resizeScrollbar(); + } + + private void resizeScrollbar() { + // scaled image size + int sx = (int) (mScale * mFullSize); + + // Adjust margin such that for zoomed out views + // we don't waste space (unless the viewport is + // large enough to accommodate it) + int delta = mClientSize - sx; + if (delta < 0) { + mMargin = 0; + } else if (delta < 2 * DEFAULT_MARGIN) { + mMargin = delta / 2; + + ImageOverlay imageOverlay = mCanvas.getImageOverlay(); + if (imageOverlay != null && imageOverlay.getShowDropShadow() + && delta >= SHADOW_SIZE / 2) { + mMargin -= SHADOW_SIZE / 2; + // Add a little padding on the top too, if there's room. The shadow assets + // include enough padding on the bottom to not make this look clipped. + if (mMargin < 4) { + mMargin += 4; + } + } + } else { + mMargin = DEFAULT_MARGIN; + } + + if (mCanvas.getPreviewManager().hasPreviews()) { + // Make more room for the previews + mMargin = 2; + } + + // actual client area is always reduced by the margins + int cx = mClientSize - 2 * mMargin; + + if (sx < cx) { + mTranslate = 0; + mScrollbar.setEnabled(false); + } else { + mScrollbar.setEnabled(true); + + int selection = mScrollbar.getSelection(); + int thumb = cx; + int maximum = sx; + + if (selection + thumb > maximum) { + selection = maximum - thumb; + if (selection < 0) { + selection = 0; + } + } + + mScrollbar.setValues(selection, mScrollbar.getMinimum(), maximum, thumb, mScrollbar + .getIncrement(), mScrollbar.getPageIncrement()); + + mTranslate = selection; + } + } + + public int getMargin() { + return mMargin; + } + + public int translate(int canvasX) { + return mMargin - mTranslate + (int) (mScale * canvasX); + } + + public int scale(int canwasW) { + return (int) (mScale * canwasW); + } + + public int inverseTranslate(int screenX) { + return (int) ((screenX - mMargin + mTranslate) / mScale); + } + + public int inverseScale(int canwasW) { + return (int) (canwasW / mScale); + } +} |