aboutsummaryrefslogtreecommitdiff
path: root/eclipse/plugins/com.android.ide.eclipse.gldebugger/src/com/android/ide/eclipse/gltrace/widgets/ImageCanvas.java
diff options
context:
space:
mode:
Diffstat (limited to 'eclipse/plugins/com.android.ide.eclipse.gldebugger/src/com/android/ide/eclipse/gltrace/widgets/ImageCanvas.java')
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.gldebugger/src/com/android/ide/eclipse/gltrace/widgets/ImageCanvas.java250
1 files changed, 250 insertions, 0 deletions
diff --git a/eclipse/plugins/com.android.ide.eclipse.gldebugger/src/com/android/ide/eclipse/gltrace/widgets/ImageCanvas.java b/eclipse/plugins/com.android.ide.eclipse.gldebugger/src/com/android/ide/eclipse/gltrace/widgets/ImageCanvas.java
new file mode 100644
index 000000000..23baf1739
--- /dev/null
+++ b/eclipse/plugins/com.android.ide.eclipse.gldebugger/src/com/android/ide/eclipse/gltrace/widgets/ImageCanvas.java
@@ -0,0 +1,250 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0
+ *
+ * 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.gltrace.widgets;
+
+import com.android.ide.eclipse.gltrace.GlTracePlugin;
+
+import org.eclipse.core.runtime.Status;
+import org.eclipse.jface.dialogs.ErrorDialog;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.events.SelectionListener;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.graphics.GC;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.graphics.ImageData;
+import org.eclipse.swt.graphics.ImageLoader;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.graphics.Rectangle;
+import org.eclipse.swt.widgets.Canvas;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Event;
+import org.eclipse.swt.widgets.Listener;
+import org.eclipse.swt.widgets.ScrollBar;
+
+import java.io.File;
+
+public class ImageCanvas extends Canvas {
+ private static final int SCROLLBAR_INCREMENT = 20;
+
+ private Point mOrigin;
+
+ private ScrollBar mHorizontalScrollBar;
+ private ScrollBar mVerticalScrollBar;
+
+ private Image mImage;
+ private boolean mFitToCanvas;
+
+ public ImageCanvas(Composite parent) {
+ super(parent, SWT.NO_BACKGROUND | SWT.V_SCROLL | SWT.H_SCROLL);
+ mOrigin = new Point(0, 0);
+
+ mHorizontalScrollBar = getHorizontalBar();
+ mVerticalScrollBar = getVerticalBar();
+
+ mFitToCanvas = true;
+
+ setScrollBarIncrements();
+ setScrollBarPageIncrements(getClientArea());
+
+ updateScrollBars();
+
+ SelectionListener scrollBarSelectionListener = new SelectionAdapter() {
+ @Override
+ public void widgetSelected(SelectionEvent e) {
+ if (e.getSource() == mHorizontalScrollBar) {
+ scrollHorizontally();
+ } else {
+ scrollVertically();
+ }
+ }
+ };
+
+ mHorizontalScrollBar.addSelectionListener(scrollBarSelectionListener);
+ mVerticalScrollBar.addSelectionListener(scrollBarSelectionListener);
+
+ addListener(SWT.Resize, new Listener() {
+ @Override
+ public void handleEvent(Event e) {
+ setScrollBarPageIncrements(getClientArea());
+ updateScrollBars();
+ }
+ });
+
+ addListener(SWT.Paint, new Listener() {
+ @Override
+ public void handleEvent(Event e) {
+ paintCanvas(e.gc);
+ }
+ });
+ }
+
+ public void setFitToCanvas(boolean en) {
+ mFitToCanvas = en;
+ updateScrollBars();
+ redraw();
+ }
+
+ public void setImage(Image image) {
+ if (mImage != null) {
+ mImage.dispose();
+ }
+
+ mImage = image;
+ mOrigin = new Point(0, 0);
+ updateScrollBars();
+ redraw();
+ }
+
+ private void updateScrollBars() {
+ Rectangle client = getClientArea();
+
+ int imageWidth, imageHeight;
+ if (mImage != null & !mFitToCanvas) {
+ imageWidth = mImage.getBounds().width;
+ imageHeight = mImage.getBounds().height;
+ } else {
+ imageWidth = client.width;
+ imageHeight = client.height;
+ }
+
+ mHorizontalScrollBar.setMaximum(imageWidth);
+ mVerticalScrollBar.setMaximum(imageHeight);
+ mHorizontalScrollBar.setThumb(Math.min(imageWidth, client.width));
+ mVerticalScrollBar.setThumb(Math.min(imageHeight, client.height));
+
+ int hPage = imageWidth - client.width;
+ int vPage = imageHeight - client.height;
+ int hSelection = mHorizontalScrollBar.getSelection();
+ int vSelection = mVerticalScrollBar.getSelection();
+ if (hSelection >= hPage) {
+ if (hPage <= 0) {
+ hSelection = 0;
+ }
+ mOrigin.x = -hSelection;
+ }
+
+ if (vSelection >= vPage) {
+ if (vPage <= 0) {
+ vSelection = 0;
+ }
+ mOrigin.y = -vSelection;
+ }
+
+ redraw();
+ }
+
+ private void setScrollBarPageIncrements(Rectangle clientArea) {
+ mHorizontalScrollBar.setPageIncrement(clientArea.width);
+ mVerticalScrollBar.setPageIncrement(clientArea.height);
+ }
+
+ private void setScrollBarIncrements() {
+ // The default increment is 1 pixel. Assign a saner default.
+ mHorizontalScrollBar.setIncrement(SCROLLBAR_INCREMENT);
+ mVerticalScrollBar.setIncrement(SCROLLBAR_INCREMENT);
+ }
+
+ private void scrollHorizontally() {
+ if (mImage == null) {
+ return;
+ }
+
+ int selection = mHorizontalScrollBar.getSelection();
+ int destX = -selection - mOrigin.x;
+ Rectangle imageBounds = mImage.getBounds();
+ scroll(destX, 0, 0, 0, imageBounds.width, imageBounds.height, false);
+ mOrigin.x = -selection;
+ }
+
+ private void scrollVertically() {
+ if (mImage == null) {
+ return;
+ }
+
+ int selection = mVerticalScrollBar.getSelection();
+ int destY = -selection - mOrigin.y;
+ Rectangle imageBounds = mImage.getBounds();
+ scroll(0, destY, 0, 0, imageBounds.width, imageBounds.height, false);
+ mOrigin.y = -selection;
+ }
+
+ private void paintCanvas(GC gc) {
+ gc.fillRectangle(getClientArea()); // clear entire client area
+ if (mImage == null) {
+ return;
+ }
+
+ Rectangle rect = mImage.getBounds();
+ Rectangle client = getClientArea();
+
+ if (mFitToCanvas && rect.width > 0 && rect.height > 0) {
+ double sx = (double) client.width / (double) rect.width;
+ double sy = (double) client.height / (double) rect.height;
+
+ if (sx < sy) {
+ // if we need to scale more horizontally, then reduce the client height
+ // appropriately so that aspect ratios are maintained
+ gc.drawImage(mImage,
+ 0, 0, rect.width, rect.height,
+ 0, 0, client.width, (int)(rect.height * sx));
+ drawBorder(gc, 0, 0, client.width, (int)(rect.height * sx));
+ } else {
+ // scale client width to maintain aspect ratio
+ gc.drawImage(mImage,
+ 0, 0, rect.width, rect.height,
+ 0, 0, (int)(rect.width * sy), client.height);
+ drawBorder(gc, 0, 0, (int)(rect.width * sy), client.height);
+ }
+ } else {
+ gc.drawImage(mImage, mOrigin.x, mOrigin.y);
+ drawBorder(gc, mOrigin.x, mOrigin.y, rect.width, rect.height);
+ }
+ }
+
+ private void drawBorder(GC gc, int x, int y, int width, int height) {
+ Color origFg = gc.getForeground();
+ gc.setForeground(Display.getDefault().getSystemColor(SWT.COLOR_WIDGET_NORMAL_SHADOW));
+ gc.drawRectangle(x, y, width, height);
+ gc.setForeground(origFg);
+ }
+
+ @Override
+ public void dispose() {
+ if (mImage != null && !mImage.isDisposed()) {
+ mImage.dispose();
+ }
+ }
+
+ public void exportImageTo(File file) {
+ if (mImage == null || file == null) {
+ return;
+ }
+
+ ImageLoader imageLoader = new ImageLoader();
+ imageLoader.data = new ImageData[] { mImage.getImageData() };
+
+ try {
+ imageLoader.save(file.getAbsolutePath(), SWT.IMAGE_PNG);
+ } catch (Exception e) {
+ ErrorDialog.openError(getShell(), "Save Image", "Error saving image",
+ new Status(Status.ERROR, GlTracePlugin.PLUGIN_ID, e.toString()));
+ }
+ }
+}