aboutsummaryrefslogtreecommitdiffstats
path: root/hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/ui/TreeView.java
diff options
context:
space:
mode:
Diffstat (limited to 'hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/ui/TreeView.java')
-rw-r--r--hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/ui/TreeView.java1086
1 files changed, 0 insertions, 1086 deletions
diff --git a/hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/ui/TreeView.java b/hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/ui/TreeView.java
deleted file mode 100644
index 5617239..0000000
--- a/hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/ui/TreeView.java
+++ /dev/null
@@ -1,1086 +0,0 @@
-/*
- * Copyright (C) 2010 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.hierarchyviewerlib.ui;
-
-import com.android.ddmuilib.ImageLoader;
-import com.android.hierarchyviewerlib.HierarchyViewerDirector;
-import com.android.hierarchyviewerlib.models.TreeViewModel;
-import com.android.hierarchyviewerlib.models.TreeViewModel.ITreeChangeListener;
-import com.android.hierarchyviewerlib.models.ViewNode.ProfileRating;
-import com.android.hierarchyviewerlib.ui.util.DrawableViewNode;
-import com.android.hierarchyviewerlib.ui.util.DrawableViewNode.Point;
-import com.android.hierarchyviewerlib.ui.util.DrawableViewNode.Rectangle;
-
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.events.DisposeEvent;
-import org.eclipse.swt.events.DisposeListener;
-import org.eclipse.swt.events.KeyEvent;
-import org.eclipse.swt.events.KeyListener;
-import org.eclipse.swt.events.MouseEvent;
-import org.eclipse.swt.events.MouseListener;
-import org.eclipse.swt.events.MouseMoveListener;
-import org.eclipse.swt.events.MouseWheelListener;
-import org.eclipse.swt.events.PaintEvent;
-import org.eclipse.swt.events.PaintListener;
-import org.eclipse.swt.graphics.Color;
-import org.eclipse.swt.graphics.Font;
-import org.eclipse.swt.graphics.FontData;
-import org.eclipse.swt.graphics.GC;
-import org.eclipse.swt.graphics.Image;
-import org.eclipse.swt.graphics.Path;
-import org.eclipse.swt.graphics.RGB;
-import org.eclipse.swt.graphics.Transform;
-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 java.text.DecimalFormat;
-
-public class TreeView extends Canvas implements ITreeChangeListener {
-
- private TreeViewModel mModel;
-
- private DrawableViewNode mTree;
-
- private DrawableViewNode mSelectedNode;
-
- private Rectangle mViewport;
-
- private Transform mTransform;
-
- private Transform mInverse;
-
- private double mZoom;
-
- private Point mLastPoint;
-
- private boolean mAlreadySelectedOnMouseDown;
-
- private boolean mDoubleClicked;
-
- private boolean mNodeMoved;
-
- private DrawableViewNode mDraggedNode;
-
- public static final int LINE_PADDING = 10;
-
- public static final float BEZIER_FRACTION = 0.35f;
-
- private static Image sRedImage;
-
- private static Image sYellowImage;
-
- private static Image sGreenImage;
-
- private static Image sNotSelectedImage;
-
- private static Image sSelectedImage;
-
- private static Image sFilteredImage;
-
- private static Image sFilteredSelectedImage;
-
- private static Font sSystemFont;
-
- private Color mBoxColor;
-
- private Color mTextBackgroundColor;
-
- private Rectangle mSelectedRectangleLocation;
-
- private Point mButtonCenter;
-
- private static final int BUTTON_SIZE = 13;
-
- private Image mScaledSelectedImage;
-
- private boolean mButtonClicked;
-
- private DrawableViewNode mLastDrawnSelectedViewNode;
-
- // The profile-image box needs to be moved to,
- // so add some dragging leeway.
- private static final int DRAG_LEEWAY = 220;
-
- // Profile-image box constants
- private static final int RECT_WIDTH = 190;
-
- private static final int RECT_HEIGHT = 224;
-
- private static final int BUTTON_RIGHT_OFFSET = 5;
-
- private static final int BUTTON_TOP_OFFSET = 5;
-
- private static final int IMAGE_WIDTH = 125;
-
- private static final int IMAGE_HEIGHT = 120;
-
- private static final int IMAGE_OFFSET = 6;
-
- private static final int IMAGE_ROUNDING = 8;
-
- private static final int RECTANGLE_SIZE = 5;
-
- private static final int TEXT_SIDE_OFFSET = 8;
-
- private static final int TEXT_TOP_OFFSET = 4;
-
- private static final int TEXT_SPACING = 2;
-
- private static final int TEXT_ROUNDING = 20;
-
- public TreeView(Composite parent) {
- super(parent, SWT.NONE);
-
- mModel = TreeViewModel.getModel();
- mModel.addTreeChangeListener(this);
-
- addPaintListener(mPaintListener);
- addMouseListener(mMouseListener);
- addMouseMoveListener(mMouseMoveListener);
- addMouseWheelListener(mMouseWheelListener);
- addListener(SWT.Resize, mResizeListener);
- addDisposeListener(mDisposeListener);
- addKeyListener(mKeyListener);
-
- loadResources();
-
- mTransform = new Transform(Display.getDefault());
- mInverse = new Transform(Display.getDefault());
-
- loadAllData();
- }
-
- private void loadResources() {
- ImageLoader loader = ImageLoader.getLoader(this.getClass());
- sRedImage = loader.loadImage("red.png", Display.getDefault()); //$NON-NLS-1$
- sYellowImage = loader.loadImage("yellow.png", Display.getDefault()); //$NON-NLS-1$
- sGreenImage = loader.loadImage("green.png", Display.getDefault()); //$NON-NLS-1$
- sNotSelectedImage = loader.loadImage("not-selected.png", Display.getDefault()); //$NON-NLS-1$
- sSelectedImage = loader.loadImage("selected.png", Display.getDefault()); //$NON-NLS-1$
- sFilteredImage = loader.loadImage("filtered.png", Display.getDefault()); //$NON-NLS-1$
- sFilteredSelectedImage = loader.loadImage("selected-filtered.png", Display.getDefault()); //$NON-NLS-1$
- mBoxColor = new Color(Display.getDefault(), new RGB(225, 225, 225));
- mTextBackgroundColor = new Color(Display.getDefault(), new RGB(82, 82, 82));
- if (mScaledSelectedImage != null) {
- mScaledSelectedImage.dispose();
- }
- sSystemFont = Display.getDefault().getSystemFont();
- }
-
- private DisposeListener mDisposeListener = new DisposeListener() {
- @Override
- public void widgetDisposed(DisposeEvent e) {
- mModel.removeTreeChangeListener(TreeView.this);
- mTransform.dispose();
- mInverse.dispose();
- mBoxColor.dispose();
- mTextBackgroundColor.dispose();
- if (mTree != null) {
- mModel.setViewport(null);
- }
- }
- };
-
- private Listener mResizeListener = new Listener() {
- @Override
- public void handleEvent(Event e) {
- synchronized (TreeView.this) {
- if (mTree != null && mViewport != null) {
-
- // Keep the center in the same place.
- Point viewCenter =
- new Point(mViewport.x + mViewport.width / 2, mViewport.y + mViewport.height
- / 2);
- mViewport.width = getBounds().width / mZoom;
- mViewport.height = getBounds().height / mZoom;
- mViewport.x = viewCenter.x - mViewport.width / 2;
- mViewport.y = viewCenter.y - mViewport.height / 2;
- }
- }
- if (mViewport != null) {
- mModel.setViewport(mViewport);
- }
- }
- };
-
- private KeyListener mKeyListener = new KeyListener() {
-
- @Override
- public void keyPressed(KeyEvent e) {
- boolean selectionChanged = false;
- DrawableViewNode clickedNode = null;
- synchronized (TreeView.this) {
- if (mTree != null && mViewport != null && mSelectedNode != null) {
- switch (e.keyCode) {
- case SWT.ARROW_LEFT:
- if (mSelectedNode.parent != null) {
- mSelectedNode = mSelectedNode.parent;
- selectionChanged = true;
- }
- break;
- case SWT.ARROW_UP:
-
- // On up and down, it is cool to go up and down only
- // the leaf nodes.
- // It goes well with the layout viewer
- DrawableViewNode currentNode = mSelectedNode;
- while (currentNode.parent != null && currentNode.viewNode.index == 0) {
- currentNode = currentNode.parent;
- }
- if (currentNode.parent != null) {
- selectionChanged = true;
- currentNode =
- currentNode.parent.children
- .get(currentNode.viewNode.index - 1);
- while (currentNode.children.size() != 0) {
- currentNode =
- currentNode.children
- .get(currentNode.children.size() - 1);
- }
- }
- if (selectionChanged) {
- mSelectedNode = currentNode;
- }
- break;
- case SWT.ARROW_DOWN:
- currentNode = mSelectedNode;
- while (currentNode.parent != null
- && currentNode.viewNode.index + 1 == currentNode.parent.children
- .size()) {
- currentNode = currentNode.parent;
- }
- if (currentNode.parent != null) {
- selectionChanged = true;
- currentNode =
- currentNode.parent.children
- .get(currentNode.viewNode.index + 1);
- while (currentNode.children.size() != 0) {
- currentNode = currentNode.children.get(0);
- }
- }
- if (selectionChanged) {
- mSelectedNode = currentNode;
- }
- break;
- case SWT.ARROW_RIGHT:
- DrawableViewNode rightNode = null;
- double mostOverlap = 0;
- final int N = mSelectedNode.children.size();
-
- // We consider all the children and pick the one
- // who's tree overlaps the most.
- for (int i = 0; i < N; i++) {
- DrawableViewNode child = mSelectedNode.children.get(i);
- DrawableViewNode topMostChild = child;
- while (topMostChild.children.size() != 0) {
- topMostChild = topMostChild.children.get(0);
- }
- double overlap =
- Math.min(DrawableViewNode.NODE_HEIGHT, Math.min(
- mSelectedNode.top + DrawableViewNode.NODE_HEIGHT
- - topMostChild.top, topMostChild.top
- + child.treeHeight - mSelectedNode.top));
- if (overlap > mostOverlap) {
- mostOverlap = overlap;
- rightNode = child;
- }
- }
- if (rightNode != null) {
- mSelectedNode = rightNode;
- selectionChanged = true;
- }
- break;
- case SWT.CR:
- clickedNode = mSelectedNode;
- break;
- }
- }
- }
- if (selectionChanged) {
- mModel.setSelection(mSelectedNode);
- }
- if (clickedNode != null) {
- HierarchyViewerDirector.getDirector().showCapture(getShell(), clickedNode.viewNode);
- }
- }
-
- @Override
- public void keyReleased(KeyEvent e) {
- }
- };
-
- private MouseListener mMouseListener = new MouseListener() {
-
- @Override
- public void mouseDoubleClick(MouseEvent e) {
- DrawableViewNode clickedNode = null;
- synchronized (TreeView.this) {
- if (mTree != null && mViewport != null) {
- Point pt = transformPoint(e.x, e.y);
- clickedNode = mTree.getSelected(pt.x, pt.y);
- }
- }
- if (clickedNode != null) {
- HierarchyViewerDirector.getDirector().showCapture(getShell(), clickedNode.viewNode);
- mDoubleClicked = true;
- }
- }
-
- @Override
- public void mouseDown(MouseEvent e) {
- boolean selectionChanged = false;
- synchronized (TreeView.this) {
- if (mTree != null && mViewport != null) {
- Point pt = transformPoint(e.x, e.y);
-
- // Ignore profiling rectangle, except for...
- if (mSelectedRectangleLocation != null
- && pt.x >= mSelectedRectangleLocation.x
- && pt.x < mSelectedRectangleLocation.x
- + mSelectedRectangleLocation.width
- && pt.y >= mSelectedRectangleLocation.y
- && pt.y < mSelectedRectangleLocation.y
- + mSelectedRectangleLocation.height) {
-
- // the small button!
- if ((pt.x - mButtonCenter.x) * (pt.x - mButtonCenter.x)
- + (pt.y - mButtonCenter.y) * (pt.y - mButtonCenter.y) <= (BUTTON_SIZE * BUTTON_SIZE) / 4) {
- mButtonClicked = true;
- doRedraw();
- }
- return;
- }
- mDraggedNode = mTree.getSelected(pt.x, pt.y);
-
- // Update the selection.
- if (mDraggedNode != null && mDraggedNode != mSelectedNode) {
- mSelectedNode = mDraggedNode;
- selectionChanged = true;
- mAlreadySelectedOnMouseDown = false;
- } else if (mDraggedNode != null) {
- mAlreadySelectedOnMouseDown = true;
- }
-
- // Can't drag the root.
- if (mDraggedNode == mTree) {
- mDraggedNode = null;
- }
-
- if (mDraggedNode != null) {
- mLastPoint = pt;
- } else {
- mLastPoint = new Point(e.x, e.y);
- }
- mNodeMoved = false;
- mDoubleClicked = false;
- }
- }
- if (selectionChanged) {
- mModel.setSelection(mSelectedNode);
- }
- }
-
- @Override
- public void mouseUp(MouseEvent e) {
- boolean redraw = false;
- boolean redrawButton = false;
- boolean viewportChanged = false;
- boolean selectionChanged = false;
- synchronized (TreeView.this) {
- if (mTree != null && mViewport != null && mLastPoint != null) {
- if (mDraggedNode == null) {
- // The viewport moves.
- handleMouseDrag(new Point(e.x, e.y));
- viewportChanged = true;
- } else {
- // The nodes move.
- handleMouseDrag(transformPoint(e.x, e.y));
- }
-
- // Deselect on the second click...
- // This is in the mouse up, because mouse up happens after a
- // double click event.
- // During a double click, we don't want to deselect.
- Point pt = transformPoint(e.x, e.y);
- DrawableViewNode mouseUpOn = mTree.getSelected(pt.x, pt.y);
- if (mouseUpOn != null && mouseUpOn == mSelectedNode
- && mAlreadySelectedOnMouseDown && !mNodeMoved && !mDoubleClicked) {
- mSelectedNode = null;
- selectionChanged = true;
- }
- mLastPoint = null;
- mDraggedNode = null;
- redraw = true;
- }
-
- // Just clicked the button here.
- if (mButtonClicked) {
- HierarchyViewerDirector.getDirector().showCapture(getShell(),
- mSelectedNode.viewNode);
- mButtonClicked = false;
- redrawButton = true;
- }
- }
-
- // Complicated.
- if (viewportChanged) {
- mModel.setViewport(mViewport);
- } else if (redraw) {
- mModel.removeTreeChangeListener(TreeView.this);
- mModel.notifyViewportChanged();
- if (selectionChanged) {
- mModel.setSelection(mSelectedNode);
- }
- mModel.addTreeChangeListener(TreeView.this);
- doRedraw();
- } else if (redrawButton) {
- doRedraw();
- }
- }
-
- };
-
- private MouseMoveListener mMouseMoveListener = new MouseMoveListener() {
- @Override
- public void mouseMove(MouseEvent e) {
- boolean redraw = false;
- boolean viewportChanged = false;
- synchronized (TreeView.this) {
- if (mTree != null && mViewport != null && mLastPoint != null) {
- if (mDraggedNode == null) {
- handleMouseDrag(new Point(e.x, e.y));
- viewportChanged = true;
- } else {
- handleMouseDrag(transformPoint(e.x, e.y));
- }
- redraw = true;
- }
- }
- if (viewportChanged) {
- mModel.setViewport(mViewport);
- } else if (redraw) {
- mModel.removeTreeChangeListener(TreeView.this);
- mModel.notifyViewportChanged();
- mModel.addTreeChangeListener(TreeView.this);
- doRedraw();
- }
- }
- };
-
- private void handleMouseDrag(Point pt) {
-
- // Case 1: a node is dragged. DrawableViewNode knows how to handle this.
- if (mDraggedNode != null) {
- if (mLastPoint.y - pt.y != 0) {
- mNodeMoved = true;
- }
- mDraggedNode.move(mLastPoint.y - pt.y);
- mLastPoint = pt;
- return;
- }
-
- // Case 2: the viewport is dragged. We have to make sure we respect the
- // bounds - don't let the user drag way out... + some leeway for the
- // profiling box.
- double xDif = (mLastPoint.x - pt.x) / mZoom;
- double yDif = (mLastPoint.y - pt.y) / mZoom;
-
- double treeX = mTree.bounds.x - DRAG_LEEWAY;
- double treeY = mTree.bounds.y - DRAG_LEEWAY;
- double treeWidth = mTree.bounds.width + 2 * DRAG_LEEWAY;
- double treeHeight = mTree.bounds.height + 2 * DRAG_LEEWAY;
-
- if (mViewport.width > treeWidth) {
- if (xDif < 0 && mViewport.x + mViewport.width > treeX + treeWidth) {
- mViewport.x = Math.max(mViewport.x + xDif, treeX + treeWidth - mViewport.width);
- } else if (xDif > 0 && mViewport.x < treeX) {
- mViewport.x = Math.min(mViewport.x + xDif, treeX);
- }
- } else {
- if (xDif < 0 && mViewport.x > treeX) {
- mViewport.x = Math.max(mViewport.x + xDif, treeX);
- } else if (xDif > 0 && mViewport.x + mViewport.width < treeX + treeWidth) {
- mViewport.x = Math.min(mViewport.x + xDif, treeX + treeWidth - mViewport.width);
- }
- }
- if (mViewport.height > treeHeight) {
- if (yDif < 0 && mViewport.y + mViewport.height > treeY + treeHeight) {
- mViewport.y = Math.max(mViewport.y + yDif, treeY + treeHeight - mViewport.height);
- } else if (yDif > 0 && mViewport.y < treeY) {
- mViewport.y = Math.min(mViewport.y + yDif, treeY);
- }
- } else {
- if (yDif < 0 && mViewport.y > treeY) {
- mViewport.y = Math.max(mViewport.y + yDif, treeY);
- } else if (yDif > 0 && mViewport.y + mViewport.height < treeY + treeHeight) {
- mViewport.y = Math.min(mViewport.y + yDif, treeY + treeHeight - mViewport.height);
- }
- }
- mLastPoint = pt;
- }
-
- private Point transformPoint(double x, double y) {
- float[] pt = {
- (float) x, (float) y
- };
- mInverse.transform(pt);
- return new Point(pt[0], pt[1]);
- }
-
- private MouseWheelListener mMouseWheelListener = new MouseWheelListener() {
- @Override
- public void mouseScrolled(MouseEvent e) {
- Point zoomPoint = null;
- synchronized (TreeView.this) {
- if (mTree != null && mViewport != null) {
- mZoom += Math.ceil(e.count / 3.0) * 0.1;
- zoomPoint = transformPoint(e.x, e.y);
- }
- }
- if (zoomPoint != null) {
- mModel.zoomOnPoint(mZoom, zoomPoint);
- }
- }
- };
-
- private PaintListener mPaintListener = new PaintListener() {
- @Override
- public void paintControl(PaintEvent e) {
- synchronized (TreeView.this) {
- e.gc.setBackground(Display.getDefault().getSystemColor(SWT.COLOR_BLACK));
- e.gc.fillRectangle(0, 0, getBounds().width, getBounds().height);
- if (mTree != null && mViewport != null) {
-
- // Easy stuff!
- e.gc.setTransform(mTransform);
- e.gc.setForeground(Display.getDefault().getSystemColor(SWT.COLOR_WHITE));
- Path connectionPath = new Path(Display.getDefault());
- paintRecursive(e.gc, mTransform, mTree, mSelectedNode, connectionPath);
- e.gc.drawPath(connectionPath);
- connectionPath.dispose();
-
- // Draw the profiling box.
- if (mSelectedNode != null) {
-
- e.gc.setAlpha(200);
-
- // Draw the little triangle
- int x = mSelectedNode.left + DrawableViewNode.NODE_WIDTH / 2;
- int y = (int) mSelectedNode.top + 4;
- e.gc.setBackground(mBoxColor);
- e.gc.fillPolygon(new int[] {
- x, y, x - 11, y - 11, x + 11, y - 11
- });
-
- // Draw the rectangle and update the location.
- y -= 10 + RECT_HEIGHT;
- e.gc.fillRoundRectangle(x - RECT_WIDTH / 2, y, RECT_WIDTH, RECT_HEIGHT, 30,
- 30);
- mSelectedRectangleLocation =
- new Rectangle(x - RECT_WIDTH / 2, y, RECT_WIDTH, RECT_HEIGHT);
-
- e.gc.setAlpha(255);
-
- // Draw the button
- mButtonCenter =
- new Point(x - BUTTON_RIGHT_OFFSET + (RECT_WIDTH - BUTTON_SIZE) / 2,
- y + BUTTON_TOP_OFFSET + BUTTON_SIZE / 2);
-
- if (mButtonClicked) {
- e.gc
- .setBackground(Display.getDefault().getSystemColor(
- SWT.COLOR_BLACK));
- } else {
- e.gc.setBackground(mTextBackgroundColor);
-
- }
- e.gc.setForeground(Display.getDefault().getSystemColor(SWT.COLOR_WHITE));
-
- e.gc.fillOval(x + RECT_WIDTH / 2 - BUTTON_RIGHT_OFFSET - BUTTON_SIZE, y
- + BUTTON_TOP_OFFSET, BUTTON_SIZE, BUTTON_SIZE);
-
- e.gc.drawRectangle(x - BUTTON_RIGHT_OFFSET
- + (RECT_WIDTH - BUTTON_SIZE - RECTANGLE_SIZE) / 2 - 1, y
- + BUTTON_TOP_OFFSET + (BUTTON_SIZE - RECTANGLE_SIZE) / 2,
- RECTANGLE_SIZE + 1, RECTANGLE_SIZE);
-
- y += 15;
-
- // If there is an image, draw it.
- if (mSelectedNode.viewNode.image != null
- && mSelectedNode.viewNode.image.getBounds().height != 1
- && mSelectedNode.viewNode.image.getBounds().width != 1) {
-
- // Scaling the image to the right size takes lots of
- // time, so we want to do it only once.
-
- // If the selection changed, get rid of the old
- // image.
- if (mLastDrawnSelectedViewNode != mSelectedNode) {
- if (mScaledSelectedImage != null) {
- mScaledSelectedImage.dispose();
- mScaledSelectedImage = null;
- }
- mLastDrawnSelectedViewNode = mSelectedNode;
- }
-
- if (mScaledSelectedImage == null) {
- double ratio =
- 1.0 * mSelectedNode.viewNode.image.getBounds().width
- / mSelectedNode.viewNode.image.getBounds().height;
- int newWidth, newHeight;
- if (ratio > 1.0 * IMAGE_WIDTH / IMAGE_HEIGHT) {
- newWidth =
- Math.min(IMAGE_WIDTH, mSelectedNode.viewNode.image
- .getBounds().width);
- newHeight = (int) (newWidth / ratio);
- } else {
- newHeight =
- Math.min(IMAGE_HEIGHT, mSelectedNode.viewNode.image
- .getBounds().height);
- newWidth = (int) (newHeight * ratio);
- }
-
- // Interesting note... We make the image twice
- // the needed size so that there is better
- // resolution under zoom.
- newWidth = Math.max(newWidth * 2, 1);
- newHeight = Math.max(newHeight * 2, 1);
- mScaledSelectedImage =
- new Image(Display.getDefault(), newWidth, newHeight);
- GC gc = new GC(mScaledSelectedImage);
- gc.setBackground(mTextBackgroundColor);
- gc.fillRectangle(0, 0, newWidth, newHeight);
- gc.drawImage(mSelectedNode.viewNode.image, 0, 0,
- mSelectedNode.viewNode.image.getBounds().width,
- mSelectedNode.viewNode.image.getBounds().height, 0, 0,
- newWidth, newHeight);
- gc.dispose();
- }
-
- // Draw the background rectangle
- e.gc.setBackground(mTextBackgroundColor);
- e.gc.fillRoundRectangle(x - mScaledSelectedImage.getBounds().width / 4
- - IMAGE_OFFSET, y
- + (IMAGE_HEIGHT - mScaledSelectedImage.getBounds().height / 2)
- / 2 - IMAGE_OFFSET, mScaledSelectedImage.getBounds().width / 2
- + 2 * IMAGE_OFFSET, mScaledSelectedImage.getBounds().height / 2
- + 2 * IMAGE_OFFSET, IMAGE_ROUNDING, IMAGE_ROUNDING);
-
- // Under max zoom, we want the image to be
- // untransformed. So, get back to the identity
- // transform.
- int imageX = x - mScaledSelectedImage.getBounds().width / 4;
- int imageY =
- y
- + (IMAGE_HEIGHT - mScaledSelectedImage.getBounds().height / 2)
- / 2;
-
- Transform untransformedTransform = new Transform(Display.getDefault());
- e.gc.setTransform(untransformedTransform);
- float[] pt = new float[] {
- imageX, imageY
- };
- mTransform.transform(pt);
- e.gc.drawImage(mScaledSelectedImage, 0, 0, mScaledSelectedImage
- .getBounds().width, mScaledSelectedImage.getBounds().height,
- (int) pt[0], (int) pt[1], (int) (mScaledSelectedImage
- .getBounds().width
- * mZoom / 2),
- (int) (mScaledSelectedImage.getBounds().height * mZoom / 2));
- untransformedTransform.dispose();
- e.gc.setTransform(mTransform);
- }
-
- // Text stuff
-
- y += IMAGE_HEIGHT;
- y += 10;
- Font font = getFont(8, false);
- e.gc.setFont(font);
-
- String text =
- mSelectedNode.viewNode.viewCount + " view"
- + (mSelectedNode.viewNode.viewCount != 1 ? "s" : "");
- DecimalFormat formatter = new DecimalFormat("0.000");
-
- String measureText =
- "Measure: "
- + (mSelectedNode.viewNode.measureTime != -1 ? formatter
- .format(mSelectedNode.viewNode.measureTime)
- + " ms" : "n/a");
- String layoutText =
- "Layout: "
- + (mSelectedNode.viewNode.layoutTime != -1 ? formatter
- .format(mSelectedNode.viewNode.layoutTime)
- + " ms" : "n/a");
- String drawText =
- "Draw: "
- + (mSelectedNode.viewNode.drawTime != -1 ? formatter
- .format(mSelectedNode.viewNode.drawTime)
- + " ms" : "n/a");
-
- org.eclipse.swt.graphics.Point titleExtent = e.gc.stringExtent(text);
- org.eclipse.swt.graphics.Point measureExtent =
- e.gc.stringExtent(measureText);
- org.eclipse.swt.graphics.Point layoutExtent = e.gc.stringExtent(layoutText);
- org.eclipse.swt.graphics.Point drawExtent = e.gc.stringExtent(drawText);
- int boxWidth =
- Math.max(titleExtent.x, Math.max(measureExtent.x, Math.max(
- layoutExtent.x, drawExtent.x)))
- + 2 * TEXT_SIDE_OFFSET;
- int boxHeight =
- titleExtent.y + TEXT_SPACING + measureExtent.y + TEXT_SPACING
- + layoutExtent.y + TEXT_SPACING + drawExtent.y + 2
- * TEXT_TOP_OFFSET;
-
- e.gc.setBackground(mTextBackgroundColor);
- e.gc.fillRoundRectangle(x - boxWidth / 2, y, boxWidth, boxHeight,
- TEXT_ROUNDING, TEXT_ROUNDING);
-
- e.gc.setForeground(Display.getDefault().getSystemColor(SWT.COLOR_WHITE));
-
- y += TEXT_TOP_OFFSET;
-
- e.gc.drawText(text, x - titleExtent.x / 2, y, true);
-
- x -= boxWidth / 2;
- x += TEXT_SIDE_OFFSET;
-
- y += titleExtent.y + TEXT_SPACING;
-
- e.gc.drawText(measureText, x, y, true);
-
- y += measureExtent.y + TEXT_SPACING;
-
- e.gc.drawText(layoutText, x, y, true);
-
- y += layoutExtent.y + TEXT_SPACING;
-
- e.gc.drawText(drawText, x, y, true);
-
- font.dispose();
- } else {
- mSelectedRectangleLocation = null;
- mButtonCenter = null;
- }
- }
- }
- }
- };
-
- private static void paintRecursive(GC gc, Transform transform, DrawableViewNode node,
- DrawableViewNode selectedNode, Path connectionPath) {
- if (selectedNode == node && node.viewNode.filtered) {
- gc.drawImage(sFilteredSelectedImage, node.left, (int) Math.round(node.top));
- } else if (selectedNode == node) {
- gc.drawImage(sSelectedImage, node.left, (int) Math.round(node.top));
- } else if (node.viewNode.filtered) {
- gc.drawImage(sFilteredImage, node.left, (int) Math.round(node.top));
- } else {
- gc.drawImage(sNotSelectedImage, node.left, (int) Math.round(node.top));
- }
-
- int fontHeight = gc.getFontMetrics().getHeight();
-
- // Draw the text...
- int contentWidth =
- DrawableViewNode.NODE_WIDTH - 2 * DrawableViewNode.CONTENT_LEFT_RIGHT_PADDING;
- String name = node.viewNode.name;
- int dotIndex = name.lastIndexOf('.');
- if (dotIndex != -1) {
- name = name.substring(dotIndex + 1);
- }
- double x = node.left + DrawableViewNode.CONTENT_LEFT_RIGHT_PADDING;
- double y = node.top + DrawableViewNode.CONTENT_TOP_BOTTOM_PADDING;
- drawTextInArea(gc, transform, name, x, y, contentWidth, fontHeight, 10, true);
-
- y += fontHeight + DrawableViewNode.CONTENT_INTER_PADDING;
-
- drawTextInArea(gc, transform, "@" + node.viewNode.hashCode, x, y, contentWidth, fontHeight,
- 8, false);
-
- y += fontHeight + DrawableViewNode.CONTENT_INTER_PADDING;
- if (!node.viewNode.id.equals("NO_ID")) {
- drawTextInArea(gc, transform, node.viewNode.id, x, y, contentWidth, fontHeight, 8,
- false);
- }
-
- if (node.viewNode.measureRating != ProfileRating.NONE) {
- y =
- node.top + DrawableViewNode.NODE_HEIGHT
- - DrawableViewNode.CONTENT_TOP_BOTTOM_PADDING
- - sRedImage.getBounds().height;
- x +=
- (contentWidth - (sRedImage.getBounds().width * 3 + 2 * DrawableViewNode.CONTENT_INTER_PADDING)) / 2;
- switch (node.viewNode.measureRating) {
- case GREEN:
- gc.drawImage(sGreenImage, (int) x, (int) y);
- break;
- case YELLOW:
- gc.drawImage(sYellowImage, (int) x, (int) y);
- break;
- case RED:
- gc.drawImage(sRedImage, (int) x, (int) y);
- break;
- }
-
- x += sRedImage.getBounds().width + DrawableViewNode.CONTENT_INTER_PADDING;
- switch (node.viewNode.layoutRating) {
- case GREEN:
- gc.drawImage(sGreenImage, (int) x, (int) y);
- break;
- case YELLOW:
- gc.drawImage(sYellowImage, (int) x, (int) y);
- break;
- case RED:
- gc.drawImage(sRedImage, (int) x, (int) y);
- break;
- }
-
- x += sRedImage.getBounds().width + DrawableViewNode.CONTENT_INTER_PADDING;
- switch (node.viewNode.drawRating) {
- case GREEN:
- gc.drawImage(sGreenImage, (int) x, (int) y);
- break;
- case YELLOW:
- gc.drawImage(sYellowImage, (int) x, (int) y);
- break;
- case RED:
- gc.drawImage(sRedImage, (int) x, (int) y);
- break;
- }
- }
-
- org.eclipse.swt.graphics.Point indexExtent =
- gc.stringExtent(Integer.toString(node.viewNode.index));
- x =
- node.left + DrawableViewNode.NODE_WIDTH - DrawableViewNode.INDEX_PADDING
- - indexExtent.x;
- y =
- node.top + DrawableViewNode.NODE_HEIGHT - DrawableViewNode.INDEX_PADDING
- - indexExtent.y;
- gc.drawText(Integer.toString(node.viewNode.index), (int) x, (int) y, SWT.DRAW_TRANSPARENT);
-
- int N = node.children.size();
- if (N == 0) {
- return;
- }
- float childSpacing = (1.0f * (DrawableViewNode.NODE_HEIGHT - 2 * LINE_PADDING)) / N;
- for (int i = 0; i < N; i++) {
- DrawableViewNode child = node.children.get(i);
- paintRecursive(gc, transform, child, selectedNode, connectionPath);
- float x1 = node.left + DrawableViewNode.NODE_WIDTH;
- float y1 = (float) node.top + LINE_PADDING + childSpacing * i + childSpacing / 2;
- float x2 = child.left;
- float y2 = (float) child.top + DrawableViewNode.NODE_HEIGHT / 2.0f;
- float cx1 = x1 + BEZIER_FRACTION * DrawableViewNode.PARENT_CHILD_SPACING;
- float cy1 = y1;
- float cx2 = x2 - BEZIER_FRACTION * DrawableViewNode.PARENT_CHILD_SPACING;
- float cy2 = y2;
- connectionPath.moveTo(x1, y1);
- connectionPath.cubicTo(cx1, cy1, cx2, cy2, x2, y2);
- }
- }
-
- private static void drawTextInArea(GC gc, Transform transform, String text, double x, double y,
- double width, double height, int fontSize, boolean bold) {
-
- Font oldFont = gc.getFont();
-
- Font newFont = getFont(fontSize, bold);
- gc.setFont(newFont);
-
- org.eclipse.swt.graphics.Point extent = gc.stringExtent(text);
-
- if (extent.x > width) {
- // Oh no... we need to scale it.
- double scale = width / extent.x;
- float[] transformElements = new float[6];
- transform.getElements(transformElements);
- transform.scale((float) scale, (float) scale);
- gc.setTransform(transform);
-
- x /= scale;
- y /= scale;
- y += (extent.y / scale - extent.y) / 2;
-
- gc.drawText(text, (int) x, (int) y, SWT.DRAW_TRANSPARENT);
-
- transform.setElements(transformElements[0], transformElements[1], transformElements[2],
- transformElements[3], transformElements[4], transformElements[5]);
- gc.setTransform(transform);
- } else {
- gc.drawText(text, (int) (x + (width - extent.x) / 2),
- (int) (y + (height - extent.y) / 2), SWT.DRAW_TRANSPARENT);
- }
- gc.setFont(oldFont);
- newFont.dispose();
-
- }
-
- public static Image paintToImage(DrawableViewNode tree) {
- Image image =
- new Image(Display.getDefault(), (int) Math.ceil(tree.bounds.width), (int) Math
- .ceil(tree.bounds.height));
-
- Transform transform = new Transform(Display.getDefault());
- transform.identity();
- transform.translate((float) -tree.bounds.x, (float) -tree.bounds.y);
- Path connectionPath = new Path(Display.getDefault());
- GC gc = new GC(image);
-
- // Can't use Display.getDefault().getSystemColor in a non-UI thread.
- Color white = new Color(Display.getDefault(), 255, 255, 255);
- Color black = new Color(Display.getDefault(), 0, 0, 0);
- gc.setForeground(white);
- gc.setBackground(black);
- gc.fillRectangle(0, 0, image.getBounds().width, image.getBounds().height);
- gc.setTransform(transform);
- paintRecursive(gc, transform, tree, null, connectionPath);
- gc.drawPath(connectionPath);
- gc.dispose();
- connectionPath.dispose();
- white.dispose();
- black.dispose();
- return image;
- }
-
- private static Font getFont(int size, boolean bold) {
- FontData[] fontData = sSystemFont.getFontData();
- for (int i = 0; i < fontData.length; i++) {
- fontData[i].setHeight(size);
- if (bold) {
- fontData[i].setStyle(SWT.BOLD);
- }
- }
- return new Font(Display.getDefault(), fontData);
- }
-
- private void doRedraw() {
- Display.getDefault().syncExec(new Runnable() {
- @Override
- public void run() {
- redraw();
- }
- });
- }
-
- public void loadAllData() {
- boolean newViewport = mViewport == null;
- Display.getDefault().syncExec(new Runnable() {
- @Override
- public void run() {
- synchronized (this) {
- mTree = mModel.getTree();
- mSelectedNode = mModel.getSelection();
- mViewport = mModel.getViewport();
- mZoom = mModel.getZoom();
- if (mTree != null && mViewport == null) {
- mViewport =
- new Rectangle(0, mTree.top + DrawableViewNode.NODE_HEIGHT / 2
- - getBounds().height / 2, getBounds().width,
- getBounds().height);
- } else {
- setTransform();
- }
- }
- }
- });
- if (newViewport) {
- mModel.setViewport(mViewport);
- }
- }
-
- // Fickle behaviour... When a new tree is loaded, the model doesn't know
- // about the viewport until it passes through here.
- @Override
- public void treeChanged() {
- Display.getDefault().syncExec(new Runnable() {
- @Override
- public void run() {
- synchronized (this) {
- mTree = mModel.getTree();
- mSelectedNode = mModel.getSelection();
- if (mTree == null) {
- mViewport = null;
- } else {
- mViewport =
- new Rectangle(0, mTree.top + DrawableViewNode.NODE_HEIGHT / 2
- - getBounds().height / 2, getBounds().width,
- getBounds().height);
- }
- }
- }
- });
- if (mViewport != null) {
- mModel.setViewport(mViewport);
- } else {
- doRedraw();
- }
- }
-
- private void setTransform() {
- if (mViewport != null && mTree != null) {
- // Set the transform.
- mTransform.identity();
- mInverse.identity();
-
- mTransform.scale((float) mZoom, (float) mZoom);
- mInverse.scale((float) mZoom, (float) mZoom);
- mTransform.translate((float) -mViewport.x, (float) -mViewport.y);
- mInverse.translate((float) -mViewport.x, (float) -mViewport.y);
- mInverse.invert();
- }
- }
-
- // Note the syncExec and then synchronized... It avoids deadlock
- @Override
- public void viewportChanged() {
- Display.getDefault().syncExec(new Runnable() {
- @Override
- public void run() {
- synchronized (this) {
- mViewport = mModel.getViewport();
- mZoom = mModel.getZoom();
- setTransform();
- }
- }
- });
- doRedraw();
- }
-
- @Override
- public void zoomChanged() {
- viewportChanged();
- }
-
- @Override
- public void selectionChanged() {
- synchronized (this) {
- mSelectedNode = mModel.getSelection();
- if (mSelectedNode != null && mSelectedNode.viewNode.image == null) {
- HierarchyViewerDirector.getDirector()
- .loadCaptureInBackground(mSelectedNode.viewNode);
- }
- }
- doRedraw();
- }
-}