diff options
Diffstat (limited to 'hierarchyviewer/src/com/android/hierarchyviewer/ui/LayoutRenderer.java')
-rw-r--r-- | hierarchyviewer/src/com/android/hierarchyviewer/ui/LayoutRenderer.java | 177 |
1 files changed, 177 insertions, 0 deletions
diff --git a/hierarchyviewer/src/com/android/hierarchyviewer/ui/LayoutRenderer.java b/hierarchyviewer/src/com/android/hierarchyviewer/ui/LayoutRenderer.java new file mode 100644 index 000000000..89438340d --- /dev/null +++ b/hierarchyviewer/src/com/android/hierarchyviewer/ui/LayoutRenderer.java @@ -0,0 +1,177 @@ +/* + * Copyright (C) 2008 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.hierarchyviewer.ui; + +import com.android.hierarchyviewer.scene.ViewHierarchyScene; +import com.android.hierarchyviewer.scene.ViewNode; + +import javax.swing.JComponent; +import javax.swing.BorderFactory; +import java.awt.Color; +import java.awt.Dimension; +import java.awt.Graphics; +import java.awt.Insets; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import java.util.Set; + +class LayoutRenderer extends JComponent { + private static final int EMULATED_SCREEN_WIDTH = 320; + private static final int EMULATED_SCREEN_HEIGHT = 480; + private static final int SCREEN_MARGIN = 24; + + private boolean showExtras; + private ViewHierarchyScene scene; + private JComponent sceneView; + + LayoutRenderer(ViewHierarchyScene scene, JComponent sceneView) { + this.scene = scene; + this.sceneView = sceneView; + + setOpaque(true); + setBorder(BorderFactory.createEmptyBorder(0, 0, 12, 0)); + setBackground(Color.BLACK); + setForeground(Color.WHITE); + + addMouseListener(new MouseAdapter() { + @Override + public void mousePressed(MouseEvent event) { + selectChild(event.getX(), event.getY()); + } + }); + } + + @Override + public Dimension getPreferredSize() { + return new Dimension(EMULATED_SCREEN_WIDTH + SCREEN_MARGIN, + EMULATED_SCREEN_HEIGHT + SCREEN_MARGIN); + } + + @Override + protected void paintComponent(Graphics g) { + g.setColor(getBackground()); + g.fillRect(0, 0, getWidth(), getHeight()); + + Insets insets = getInsets(); + g.clipRect(insets.left, insets.top, + getWidth() - insets.left - insets.right, + getHeight() - insets.top - insets.bottom); + + if (scene == null) { + return; + } + + ViewNode root = scene.getRoot(); + if (root == null) { + return; + } + + int x = (getWidth() - insets.left - insets.right - root.width) / 2; + int y = (getHeight() - insets.top - insets.bottom - root.height) / 2; + g.translate(insets.left + x, insets.top + y); + + g.setColor(getForeground()); + g.drawRect(root.left, root.top, root.width - 1, root.height - 1); + g.clipRect(root.left - 1, root.top - 1, root.width + 1, root.height + 1); + drawChildren(g, root, -root.scrollX, -root.scrollY); + + Set<?> selection = scene.getSelectedObjects(); + if (selection.size() > 0) { + ViewNode node = (ViewNode) selection.iterator().next(); + g.setColor(Color.RED); + Graphics s = g.create(); + ViewNode p = node.parent; + while (p != null) { + s.translate(p.left - p.scrollX, p.top - p.scrollY); + p = p.parent; + } + if (showExtras && node.image != null) { + s.drawImage(node.image, node.left, node.top, null); + } + s.drawRect(node.left, node.top, node.width - 1, node.height - 1); + s.dispose(); + } + + g.translate(-insets.left - x, -insets.top - y); + } + + private void drawChildren(Graphics g, ViewNode root, int x, int y) { + g.translate(x, y); + for (ViewNode node : root.children) { + if (!node.willNotDraw) { + g.drawRect(node.left, node.top, node.width - 1, node.height - 1); + } + + if (node.children.size() > 0) { + drawChildren(g, node, + node.left - node.parent.scrollX, + node.top - node.parent.scrollY); + } + } + g.translate(-x, -y); + } + + public void setShowExtras(boolean showExtras) { + this.showExtras = showExtras; + repaint(); + } + + private void selectChild(int x, int y) { + + if (scene == null) { + return; + } + + ViewNode root = scene.getRoot(); + if (root == null) { + return; + } + + Insets insets = getInsets(); + + int xoffset = (getWidth() - insets.left - insets.right - root.width) / 2 + insets.left + 1; + int yoffset = (getHeight() - insets.top - insets.bottom - root.height) / 2 + insets.top + 1; + + x -= xoffset; + y -= yoffset; + if (x >= 0 && x < EMULATED_SCREEN_WIDTH && y >= 0 && y < EMULATED_SCREEN_HEIGHT) { + ViewNode hit = findChild(root, root, x, y); + scene.setFocusedObject(hit); + sceneView.repaint(); + } + } + + private ViewNode findChild(ViewNode root, ViewNode besthit, int x, int y) { + ViewNode hit = besthit; + for (ViewNode node : root.children) { + + if (node.left <= x && x < node.left + node.width && + node.top <= y && y < node.top + node.height) { + if (node.width <= hit.width && node.height <= hit.height) { + hit = node; + } + } + + if (node.children.size() > 0) { + hit = findChild(node, hit, + x - (node.left - node.parent.scrollX), + y - (node.top - node.parent.scrollY)); + } + } + return hit; + } +} |