aboutsummaryrefslogtreecommitdiffstats
path: root/hierarchyviewer
diff options
context:
space:
mode:
authorThe Android Open Source Project <initial-contribution@android.com>2009-03-02 22:54:20 -0800
committerThe Android Open Source Project <initial-contribution@android.com>2009-03-02 22:54:20 -0800
commit382f18c205f459fdd9ff6c0657beadcbfe3c5b01 (patch)
treecf087c09020d087526ef925668e044e39950bbf9 /hierarchyviewer
parent76bc028c745906e691284c685e34e72b5ccf06b5 (diff)
downloadsdk-382f18c205f459fdd9ff6c0657beadcbfe3c5b01.zip
sdk-382f18c205f459fdd9ff6c0657beadcbfe3c5b01.tar.gz
sdk-382f18c205f459fdd9ff6c0657beadcbfe3c5b01.tar.bz2
auto import from //depot/cupcake/@137055
Diffstat (limited to 'hierarchyviewer')
-rwxr-xr-xhierarchyviewer/etc/hierarchyviewer.bat6
-rw-r--r--hierarchyviewer/src/com/android/hierarchyviewer/scene/ViewHierarchyLoader.java17
-rw-r--r--hierarchyviewer/src/com/android/hierarchyviewer/scene/ViewHierarchyScene.java69
-rw-r--r--hierarchyviewer/src/com/android/hierarchyviewer/scene/ViewManager.java1
-rw-r--r--hierarchyviewer/src/com/android/hierarchyviewer/scene/ViewNode.java40
-rw-r--r--hierarchyviewer/src/com/android/hierarchyviewer/ui/Workspace.java103
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);
}