| /* |
| * 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; |
| } |
| } |