diff options
author | The Android Open Source Project <initial-contribution@android.com> | 2009-03-02 22:54:20 -0800 |
---|---|---|
committer | The Android Open Source Project <initial-contribution@android.com> | 2009-03-02 22:54:20 -0800 |
commit | 382f18c205f459fdd9ff6c0657beadcbfe3c5b01 (patch) | |
tree | cf087c09020d087526ef925668e044e39950bbf9 /hierarchyviewer | |
parent | 76bc028c745906e691284c685e34e72b5ccf06b5 (diff) | |
download | sdk-382f18c205f459fdd9ff6c0657beadcbfe3c5b01.zip sdk-382f18c205f459fdd9ff6c0657beadcbfe3c5b01.tar.gz sdk-382f18c205f459fdd9ff6c0657beadcbfe3c5b01.tar.bz2 |
auto import from //depot/cupcake/@137055
Diffstat (limited to 'hierarchyviewer')
6 files changed, 194 insertions, 42 deletions
diff --git a/hierarchyviewer/etc/hierarchyviewer.bat b/hierarchyviewer/etc/hierarchyviewer.bat index 67e4f80..2024a79 100755 --- a/hierarchyviewer/etc/hierarchyviewer.bat +++ b/hierarchyviewer/etc/hierarchyviewer.bat @@ -20,9 +20,9 @@ rem Set up prog to be the path of this script, including following symlinks, rem and set up progdir to be the fully-qualified pathname of its directory. set prog=%~f0 -rem Change current directory to where ddms is, to avoid issues with directories -rem containing whitespaces. -cd %~dp0 +rem Change current directory and drive to where the script is, to avoid +rem issues with directories containing whitespaces. +cd /d %~dp0 set jarfile=hierarchyviewer.jar set frameworkdir= diff --git a/hierarchyviewer/src/com/android/hierarchyviewer/scene/ViewHierarchyLoader.java b/hierarchyviewer/src/com/android/hierarchyviewer/scene/ViewHierarchyLoader.java index 6efb52d6..51e1396 100644 --- a/hierarchyviewer/src/com/android/hierarchyviewer/scene/ViewHierarchyLoader.java +++ b/hierarchyviewer/src/com/android/hierarchyviewer/scene/ViewHierarchyLoader.java @@ -32,6 +32,7 @@ import java.net.Socket; import java.util.Collections; import java.util.Comparator; import java.util.Stack; +import java.util.regex.Pattern; public class ViewHierarchyLoader { @SuppressWarnings("empty-statement") @@ -109,7 +110,9 @@ public class ViewHierarchyLoader { parent.children.add(lastNode); } } - + + updateIndices(scene.getRoot()); + } catch (IOException ex) { Exceptions.printStackTrace(ex); } finally { @@ -127,10 +130,18 @@ public class ViewHierarchyLoader { } System.out.println("==> DONE"); - + return scene; } - + + private static void updateIndices(ViewNode root) { + root.computeIndex(); + + for (ViewNode node : root.children) { + updateIndices(node); + } + } + private static int countFrontWhitespace(String line) { int count = 0; while (line.charAt(count) == ' ') { diff --git a/hierarchyviewer/src/com/android/hierarchyviewer/scene/ViewHierarchyScene.java b/hierarchyviewer/src/com/android/hierarchyviewer/scene/ViewHierarchyScene.java index d99a80c..08dc395 100644 --- a/hierarchyviewer/src/com/android/hierarchyviewer/scene/ViewHierarchyScene.java +++ b/hierarchyviewer/src/com/android/hierarchyviewer/scene/ViewHierarchyScene.java @@ -60,22 +60,25 @@ public class ViewHierarchyScene extends GraphScene<ViewNode, String> { @Override protected Widget attachNodeWidget(ViewNode node) { - Widget widget = createBox(node.name, node.id); + Widget widget = createBox(node, node.name, node.id); widget.getActions().addAction(createSelectAction()); widget.getActions().addAction(moveAction); widgetLayer.addChild(widget); return widget; } - private Widget createBox(String node, String id) { - Widget box = new GradientWidget(this); + private Widget createBox(ViewNode node, String nodeName, String id) { + final String shortName = getShortName(nodeName); + node.setShortName(shortName); + + GradientWidget box = new GradientWidget(this, node); box.setLayout(LayoutFactory.createVerticalFlowLayout()); box.setBorder(BorderFactory.createLineBorder(2, Color.BLACK)); box.setOpaque(true); LabelWidget label = new LabelWidget(this); label.setFont(getDefaultFont().deriveFont(Font.PLAIN, 12.0f)); - label.setLabel(getShortName(node)); + label.setLabel(shortName); label.setBorder(BorderFactory.createEmptyBorder(6, 6, 0, 6)); label.setAlignment(LabelWidget.Alignment.CENTER); @@ -83,9 +86,11 @@ public class ViewHierarchyScene extends GraphScene<ViewNode, String> { label = new LabelWidget(this); label.setFont(getDefaultFont().deriveFont(Font.PLAIN, 10.0f)); - label.setLabel(getAddress(node)); + label.setLabel(getAddress(nodeName)); label.setBorder(BorderFactory.createEmptyBorder(3, 6, 0, 6)); label.setAlignment(LabelWidget.Alignment.CENTER); + + box.addressWidget = label; box.addChild(label); @@ -136,7 +141,7 @@ public class ViewHierarchyScene extends GraphScene<ViewNode, String> { connection.setTargetAnchor(AnchorFactory.createRectangularAnchor(target)); } - private static class GradientWidget extends Widget { + private static class GradientWidget extends Widget implements ViewNode.StateListener { public static final GradientPaint BLUE_EXPERIENCE = new GradientPaint( new Point2D.Double(0, 0), new Color(168, 204, 241), @@ -177,15 +182,28 @@ public class ViewHierarchyScene extends GraphScene<ViewNode, String> { new Color(129, 138, 155), new Point2D.Double(0, 1), new Color(58, 66, 82)); + public static final GradientPaint NIGHT_GRAY_VERY_LIGHT = new GradientPaint( + new Point2D.Double(0, 0), + new Color(129, 138, 155, 60), + new Point2D.Double(0, 1), + new Color(58, 66, 82, 60)); private static Color UNSELECTED = Color.BLACK; private static Color SELECTED = Color.WHITE; + private final ViewNode node; + + private LabelWidget addressWidget; + private boolean isSelected = false; - private GradientPaint gradient = MAC_OSX_SELECTED; + private final GradientPaint selectedGradient = MAC_OSX_SELECTED; + private final GradientPaint filteredGradient = RED_XP; + private final GradientPaint focusGradient = NIGHT_GRAY_VERY_LIGHT; - public GradientWidget(ViewHierarchyScene scene) { + public GradientWidget(ViewHierarchyScene scene, ViewNode node) { super(scene); + this.node = node; + node.setStateListener(this); } @Override @@ -193,8 +211,12 @@ public class ViewHierarchyScene extends GraphScene<ViewNode, String> { super.notifyStateChanged(previous, state); isSelected = state.isSelected() || state.isFocused() || state.isWidgetFocused(); + pickChildrenColor(); + } + + private void pickChildrenColor() { for (Widget child : getChildren()) { - child.setForeground(isSelected ? SELECTED : UNSELECTED); + child.setForeground(isSelected || node.filtered ? SELECTED : UNSELECTED); } repaint(); @@ -206,14 +228,35 @@ public class ViewHierarchyScene extends GraphScene<ViewNode, String> { Graphics2D g2 = getGraphics(); Rectangle bounds = getBounds(); - + if (!isSelected) { - g2.setColor(Color.WHITE); + if (!node.filtered) { + if (!node.hasFocus) { + g2.setColor(Color.WHITE); + } else { + g2.setPaint(new GradientPaint(bounds.x, bounds.y, + focusGradient.getColor1(), bounds.x, bounds.x + bounds.height, + focusGradient.getColor2())); + } + } else { + g2.setPaint(new GradientPaint(bounds.x, bounds.y, filteredGradient.getColor1(), + bounds.x, bounds.x + bounds.height, filteredGradient.getColor2())); + } } else { - g2.setPaint(new GradientPaint(bounds.x, bounds.y, gradient.getColor1(), - bounds.x, bounds.x + bounds.height, gradient.getColor2())); + g2.setPaint(new GradientPaint(bounds.x, bounds.y, selectedGradient.getColor1(), + bounds.x, bounds.x + bounds.height, selectedGradient.getColor2())); } g2.fillRect(bounds.x, bounds.y, bounds.width, bounds.height); } + + public void nodeStateChanged(ViewNode node) { + pickChildrenColor(); + } + + public void nodeIndexChanged(ViewNode node) { + if (addressWidget != null) { + addressWidget.setLabel("#" + node.index + addressWidget.getLabel()); + } + } } } diff --git a/hierarchyviewer/src/com/android/hierarchyviewer/scene/ViewManager.java b/hierarchyviewer/src/com/android/hierarchyviewer/scene/ViewManager.java index 6b212c0..2b7efd6 100644 --- a/hierarchyviewer/src/com/android/hierarchyviewer/scene/ViewManager.java +++ b/hierarchyviewer/src/com/android/hierarchyviewer/scene/ViewManager.java @@ -17,7 +17,6 @@ package com.android.hierarchyviewer.scene; import com.android.ddmlib.Device; -import com.android.hierarchyviewer.device.Configuration; import com.android.hierarchyviewer.device.Window; import com.android.hierarchyviewer.device.DeviceBridge; diff --git a/hierarchyviewer/src/com/android/hierarchyviewer/scene/ViewNode.java b/hierarchyviewer/src/com/android/hierarchyviewer/scene/ViewNode.java index 8284df1..64c0703 100644 --- a/hierarchyviewer/src/com/android/hierarchyviewer/scene/ViewNode.java +++ b/hierarchyviewer/src/com/android/hierarchyviewer/scene/ViewNode.java @@ -21,6 +21,7 @@ import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.regex.Pattern; public class ViewNode { public String id; @@ -52,8 +53,15 @@ public class ViewNode { public boolean willNotDraw; public boolean hasMargins; + boolean hasFocus; + int index; + public boolean decoded; - + public boolean filtered; + + private String shortName; + private StateListener listener; + void decode() { id = namedProperties.get("mID").value; @@ -73,6 +81,7 @@ public class ViewNode { marginBottom = getInt("layout_bottomMargin", Integer.MIN_VALUE); baseline = getInt("getBaseline()", 0); willNotDraw = getBoolean("willNotDraw()", false); + hasFocus = getBoolean("hasFocus()", false); hasMargins = marginLeft != Integer.MIN_VALUE && marginRight != Integer.MIN_VALUE && @@ -101,11 +110,33 @@ public class ViewNode { return Integer.parseInt(p.value); } catch (NumberFormatException e) { return defaultValue; - } + } } return defaultValue; } + public void filter(Pattern pattern) { + if (pattern == null || pattern.pattern().length() == 0) { + filtered = false; + } else { + filtered = pattern.matcher(shortName).find() || pattern.matcher(id).find(); + } + listener.nodeStateChanged(this); + } + + void computeIndex() { + index = parent == null ? 0 : parent.children.indexOf(this); + listener.nodeIndexChanged(this); + } + + void setShortName(String shortName) { + this.shortName = shortName; + } + + void setStateListener(StateListener listener) { + this.listener = listener; + } + @SuppressWarnings({"StringEquality"}) @Override public boolean equals(Object obj) { @@ -164,4 +195,9 @@ public class ViewNode { return hash; } } + + interface StateListener { + void nodeStateChanged(ViewNode node); + void nodeIndexChanged(ViewNode node); + } } diff --git a/hierarchyviewer/src/com/android/hierarchyviewer/ui/Workspace.java b/hierarchyviewer/src/com/android/hierarchyviewer/ui/Workspace.java index 0add4e9..20093ae 100644 --- a/hierarchyviewer/src/com/android/hierarchyviewer/ui/Workspace.java +++ b/hierarchyviewer/src/com/android/hierarchyviewer/ui/Workspace.java @@ -76,6 +76,9 @@ import javax.swing.ListSelectionModel; import javax.swing.SwingUtilities; import javax.swing.JTree; import javax.swing.Box; +import javax.swing.JTextField; +import javax.swing.text.Document; +import javax.swing.text.BadLocationException; import javax.swing.tree.TreePath; import javax.swing.tree.DefaultTreeCellRenderer; import javax.swing.event.ChangeEvent; @@ -84,6 +87,8 @@ import javax.swing.event.ListSelectionEvent; import javax.swing.event.ListSelectionListener; import javax.swing.event.TreeSelectionListener; import javax.swing.event.TreeSelectionEvent; +import javax.swing.event.DocumentListener; +import javax.swing.event.DocumentEvent; import javax.swing.table.DefaultTableModel; import java.awt.image.BufferedImage; import java.awt.BorderLayout; @@ -105,6 +110,8 @@ import java.io.IOException; import java.util.ArrayList; import java.util.HashSet; import java.util.Set; +import java.util.regex.Pattern; +import java.util.regex.PatternSyntaxException; import java.util.concurrent.ExecutionException; public class Workspace extends JFrame { @@ -156,6 +163,8 @@ public class Workspace extends JFrame { private JTable windows; private JLabel minZoomLabel; private JLabel maxZoomLabel; + private JTextField filterText; + private JLabel filterLabel; public Workspace() { super("Hierarchy Viewer"); @@ -313,10 +322,33 @@ public class Workspace extends JFrame { graphViewButton.setSelected(true); + filterText = new JTextField(20); + filterText.putClientProperty("JComponent.sizeVariant", "small"); + filterText.getDocument().addDocumentListener(new DocumentListener() { + public void insertUpdate(DocumentEvent e) { + updateFilter(e); + } + + public void removeUpdate(DocumentEvent e) { + updateFilter(e); + } + + public void changedUpdate(DocumentEvent e) { + updateFilter(e); + } + }); + + filterLabel = new JLabel("Filter by class or id:"); + filterLabel.putClientProperty("JComponent.sizeVariant", "small"); + filterLabel.setBorder(BorderFactory.createEmptyBorder(0, 6, 0, 6)); + + leftSide.add(filterLabel); + leftSide.add(filterText); + minZoomLabel = new JLabel(); minZoomLabel.setText("20%"); minZoomLabel.putClientProperty("JComponent.sizeVariant", "small"); - minZoomLabel.setBorder(BorderFactory.createEmptyBorder(0, 6, 0, 0)); + minZoomLabel.setBorder(BorderFactory.createEmptyBorder(0, 12, 0, 0)); leftSide.add(minZoomLabel); zoomSlider = new JSlider(); @@ -357,12 +389,18 @@ public class Workspace extends JFrame { statusPanel.add(rightSide, BorderLayout.LINE_END); + hideStatusBarComponents(); + + return statusPanel; + } + + private void hideStatusBarComponents() { viewCountLabel.setVisible(false); zoomSlider.setVisible(false); minZoomLabel.setVisible(false); - maxZoomLabel.setVisible(false); - - return statusPanel; + maxZoomLabel.setVisible(false); + filterLabel.setVisible(false); + filterText.setVisible(false); } private JToolBar buildToolBar() { @@ -513,10 +551,7 @@ public class Workspace extends JFrame { } private void toggleGraphView() { - viewCountLabel.setVisible(true); - zoomSlider.setVisible(true); - minZoomLabel.setVisible(true); - maxZoomLabel.setVisible(true); + showStatusBarComponents(); screenViewer.stop(); mainPanel.remove(pixelPerfectPanel); @@ -526,6 +561,15 @@ public class Workspace extends JFrame { repaint(); } + private void showStatusBarComponents() { + viewCountLabel.setVisible(true); + zoomSlider.setVisible(true); + minZoomLabel.setVisible(true); + maxZoomLabel.setVisible(true); + filterLabel.setVisible(true); + filterText.setVisible(true); + } + private void togglePixelPerfectView() { if (pixelPerfectPanel == null) { pixelPerfectPanel = buildPixelPerfectPanel(); @@ -534,10 +578,7 @@ public class Workspace extends JFrame { screenViewer.start(); } - viewCountLabel.setVisible(false); - zoomSlider.setVisible(false); - minZoomLabel.setVisible(false); - maxZoomLabel.setVisible(false); + hideStatusBarComponents(); mainPanel.remove(mainSplitter); mainPanel.add(pixelPerfectPanel, BorderLayout.CENTER); @@ -602,10 +643,7 @@ public class Workspace extends JFrame { graphViewButton.setEnabled(true); pixelPerfectViewButton.setEnabled(true); - viewCountLabel.setVisible(true); - zoomSlider.setVisible(true); - minZoomLabel.setVisible(true); - maxZoomLabel.setVisible(true); + showStatusBarComponents(); } sceneView = scene.createView(); @@ -776,10 +814,7 @@ public class Workspace extends JFrame { pixelPerfectPanel = mainSplitter = null; graphViewButton.setSelected(true); - viewCountLabel.setVisible(false); - zoomSlider.setVisible(false); - minZoomLabel.setVisible(false); - maxZoomLabel.setVisible(false); + hideStatusBarComponents(); saveMenuItem.setEnabled(false); showDevicesMenuItem.setEnabled(false); @@ -865,6 +900,34 @@ public class Workspace extends JFrame { }); } + private void updateFilter(DocumentEvent e) { + final Document document = e.getDocument(); + try { + updateFilteredNodes(document.getText(0, document.getLength())); + } catch (BadLocationException e1) { + e1.printStackTrace(); + } + } + + private void updateFilteredNodes(String filterText) { + final ViewNode root = scene.getRoot(); + try { + final Pattern pattern = Pattern.compile(filterText, Pattern.CASE_INSENSITIVE); + filterNodes(pattern, root); + } catch (PatternSyntaxException e) { + filterNodes(null, root); + } + repaint(); + } + + private void filterNodes(Pattern pattern, ViewNode root) { + root.filter(pattern); + + for (ViewNode node : root.children) { + filterNodes(pattern, node); + } + } + public void beginTask() { progress.setVisible(true); } |