diff options
author | Siva Velusamy <vsiva@google.com> | 2011-12-07 17:50:38 -0800 |
---|---|---|
committer | Siva Velusamy <vsiva@google.com> | 2011-12-08 15:56:47 -0800 |
commit | fdcca09995db6b317e4fc5ce73ae4ff62779e017 (patch) | |
tree | 26d3c949f6ad86b6efbeaa5fb146226c2e72c7bb /eclipse | |
parent | 235fcab659a1f633d3b97a18a115e24fa8dd6308 (diff) | |
download | sdk-fdcca09995db6b317e4fc5ce73ae4ff62779e017.zip sdk-fdcca09995db6b317e4fc5ce73ae4ff62779e017.tar.gz sdk-fdcca09995db6b317e4fc5ce73ae4ff62779e017.tar.bz2 |
gltrace: FB view enhancements
1. Currently, the FB image is just set as the background image on
the canvas. As a result, the image will be tiled if the view area
is larger than the FB image. This patch fixes it so that the image
is displayed correctly.
2. Add a scale image to fit canvas option.
Change-Id: Ic56bacd416645a3c84673371d68fc067873a2f8e
Diffstat (limited to 'eclipse')
2 files changed, 195 insertions, 2 deletions
diff --git a/eclipse/plugins/com.android.ide.eclipse.gldebugger/icons/zoomfit.png b/eclipse/plugins/com.android.ide.eclipse.gldebugger/icons/zoomfit.png Binary files differnew file mode 100644 index 0000000..9c53ac8 --- /dev/null +++ b/eclipse/plugins/com.android.ide.eclipse.gldebugger/icons/zoomfit.png diff --git a/eclipse/plugins/com.android.ide.eclipse.gldebugger/src/com/android/ide/eclipse/gltrace/views/GLFramebufferView.java b/eclipse/plugins/com.android.ide.eclipse.gldebugger/src/com/android/ide/eclipse/gltrace/views/GLFramebufferView.java index 1d4be41..2b2518a 100644 --- a/eclipse/plugins/com.android.ide.eclipse.gldebugger/src/com/android/ide/eclipse/gltrace/views/GLFramebufferView.java +++ b/eclipse/plugins/com.android.ide.eclipse.gldebugger/src/com/android/ide/eclipse/gltrace/views/GLFramebufferView.java @@ -16,17 +16,28 @@ package com.android.ide.eclipse.gltrace.views; +import com.android.ide.eclipse.gldebugger.Activator; import com.android.ide.eclipse.gltrace.editors.GLFunctionTraceViewer; import com.android.ide.eclipse.gltrace.model.GLCall; import com.android.ide.eclipse.gltrace.model.GLTrace; +import org.eclipse.jface.action.Action; import org.eclipse.jface.viewers.ISelection; import org.eclipse.jface.viewers.IStructuredSelection; 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.GC; import org.eclipse.swt.graphics.Image; +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 org.eclipse.ui.ISelectionListener; import org.eclipse.ui.ISelectionService; import org.eclipse.ui.IWorkbenchPart; @@ -36,15 +47,22 @@ import java.util.List; public class GLFramebufferView extends ViewPart implements ISelectionListener { public static final String ID = "com.android.ide.eclipse.gltrace.GLFrameBuffer"; + private static final boolean FIT_TO_CANVAS_DEFAULT = true; + private static final int SCROLLBAR_INCREMENT = 20; + private Point mOrigin; private Canvas mCanvas; + private ScrollBar mHorizontalScrollBar; + private ScrollBar mVerticalScrollBar; private Image mImage; + private boolean mFitToCanvas = FIT_TO_CANVAS_DEFAULT; public GLFramebufferView() { } @Override public void createPartControl(Composite parent) { - mCanvas = new Canvas(parent, SWT.NONE); + createCanvas(parent); + createToolbar(); ISelectionService selectionService = getSite().getWorkbenchWindow().getSelectionService(); selectionService.addPostSelectionListener(this); @@ -52,6 +70,10 @@ public class GLFramebufferView extends ViewPart implements ISelectionListener { @Override public void dispose() { + if (mImage != null && !mImage.isDisposed()) { + mImage.dispose(); + } + ISelectionService selectionService = getSite().getWorkbenchWindow().getSelectionService(); selectionService.removePostSelectionListener(this); super.dispose(); @@ -59,6 +81,175 @@ public class GLFramebufferView extends ViewPart implements ISelectionListener { @Override public void setFocus() { + if (mCanvas != null) { + mCanvas.setFocus(); + } + } + + private class FitToCanvasAction extends Action { + public FitToCanvasAction() { + super("Fit to Canvas", Activator.getImageDescriptor("/icons/zoomfit.png")); //$NON-NLS-2$ + setToolTipText("Fit Image to Canvas"); + setChecked(FIT_TO_CANVAS_DEFAULT); + } + + @Override + public void run() { + setFitToCanvas(isChecked()); + } + } + + private void setFitToCanvas(boolean checked) { + mFitToCanvas = checked; + updateScrollBars(); + mCanvas.redraw(); + } + + private void createToolbar() { + getViewSite().getActionBars().getToolBarManager().add(new FitToCanvasAction()); + } + + private void createCanvas(Composite parent) { + mCanvas = new Canvas(parent, SWT.NO_BACKGROUND | SWT.V_SCROLL | SWT.H_SCROLL); + mOrigin = new Point(0, 0); + + mHorizontalScrollBar = mCanvas.getHorizontalBar(); + mVerticalScrollBar = mCanvas.getVerticalBar(); + + setScrollBarIncrements(); + setScrollBarPageIncrements(mCanvas.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); + + mCanvas.addListener(SWT.Resize, new Listener() { + public void handleEvent(Event e) { + setScrollBarPageIncrements(mCanvas.getClientArea()); + updateScrollBars(); + } + }); + + mCanvas.addListener(SWT.Paint, new Listener() { + public void handleEvent(Event e) { + paintCanvas(e.gc); + } + }); + } + + 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(); + mCanvas.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(); + mCanvas.scroll(0, destY, 0, 0, imageBounds.width, imageBounds.height, false); + mOrigin.y = -selection; + } + + private void updateScrollBars() { + Rectangle client = mCanvas.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; + } + + mCanvas.redraw(); + } + + private void paintCanvas(GC gc) { + gc.fillRectangle(mCanvas.getClientArea()); + if (mImage == null) { + return; + } + + Rectangle rect = mImage.getBounds(); + Rectangle client = mCanvas.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)); + } 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); + } + } else { + gc.drawImage(mImage, mOrigin.x, mOrigin.y); + } } public void displayFB(final Image image) { @@ -69,7 +260,9 @@ public class GLFramebufferView extends ViewPart implements ISelectionListener { } mImage = image; - mCanvas.setBackgroundImage(mImage); + mOrigin = new Point(0, 0); + updateScrollBars(); + mCanvas.redraw(); } }); } |