aboutsummaryrefslogtreecommitdiffstats
path: root/hierarchyviewer2/libs
diff options
context:
space:
mode:
authorKonstantin Lopyrev <klopyrev@google.com>2010-08-27 09:08:34 -0700
committerKonstantin Lopyrev <klopyrev@google.com>2010-08-27 16:21:58 -0700
commit99bd6912e7b5b97fc6d4bb787e76b2d9dfffd7ae (patch)
tree0f108bf445c903cbc2e3cb48ff3f441a3f799f5a /hierarchyviewer2/libs
parent712c280346135b7c29c02a2908ff9faf103d6861 (diff)
downloadsdk-99bd6912e7b5b97fc6d4bb787e76b2d9dfffd7ae.zip
sdk-99bd6912e7b5b97fc6d4bb787e76b2d9dfffd7ae.tar.gz
sdk-99bd6912e7b5b97fc6d4bb787e76b2d9dfffd7ae.tar.bz2
Refactoring and integrating into Eclipse
Change-Id: I1fd3c3828fb2474f2f7394ee2831fcd7eb675878
Diffstat (limited to 'hierarchyviewer2/libs')
-rw-r--r--hierarchyviewer2/libs/hierarchyviewerlib/src/Android.mk4
-rw-r--r--hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/HierarchyViewerDirector.java77
-rw-r--r--hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/actions/CapturePSDAction.java61
-rw-r--r--hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/actions/DisplayViewAction.java61
-rw-r--r--hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/actions/ImageAction.java27
-rw-r--r--hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/actions/InspectScreenshotAction.java89
-rw-r--r--hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/actions/InvalidateAction.java57
-rw-r--r--hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/actions/LoadOverlayAction.java61
-rw-r--r--hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/actions/LoadViewHierarchyAction.java89
-rw-r--r--hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/actions/PixelPerfectAutoRefreshAction.java58
-rw-r--r--hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/actions/PixelPerfectEnabledAction.java73
-rw-r--r--hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/actions/RefreshPixelPerfectAction.java57
-rw-r--r--hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/actions/RefreshPixelPerfectTreeAction.java57
-rw-r--r--hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/actions/RefreshViewAction.java57
-rw-r--r--hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/actions/RefreshWindowsAction.java58
-rw-r--r--hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/actions/RequestLayoutAction.java57
-rw-r--r--hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/actions/SavePixelPerfectAction.java61
-rw-r--r--hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/actions/SaveTreeViewAction.java61
-rw-r--r--hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/actions/SelectedNodeEnabledAction.java56
-rw-r--r--hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/actions/TreeViewEnabledAction.java49
-rw-r--r--hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/device/DeviceBridge.java3
-rw-r--r--hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/models/DeviceSelectionModel.java6
-rw-r--r--hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/models/PixelPerfectModel.java4
-rw-r--r--hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/ui/CaptureDisplay.java6
-rw-r--r--hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/ui/DeviceSelector.java41
-rw-r--r--hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/ui/LayoutViewer.java8
-rw-r--r--hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/ui/PixelPerfect.java5
-rw-r--r--hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/ui/PixelPerfectControls.java277
-rw-r--r--hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/ui/PixelPerfectLoupe.java7
-rw-r--r--hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/ui/PixelPerfectPixelPanel.java4
-rw-r--r--hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/ui/PixelPerfectTree.java5
-rw-r--r--hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/ui/PropertyViewer.java4
-rw-r--r--hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/ui/TreeView.java34
-rw-r--r--hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/ui/TreeViewControls.java143
-rw-r--r--hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/ui/TreeViewOverview.java52
-rw-r--r--hierarchyviewer2/libs/hierarchyviewerlib/src/resources/images/show-extras.pngbin0 -> 330 bytes
36 files changed, 1731 insertions, 38 deletions
diff --git a/hierarchyviewer2/libs/hierarchyviewerlib/src/Android.mk b/hierarchyviewer2/libs/hierarchyviewerlib/src/Android.mk
index 922e337..ecaabde 100644
--- a/hierarchyviewer2/libs/hierarchyviewerlib/src/Android.mk
+++ b/hierarchyviewer2/libs/hierarchyviewerlib/src/Android.mk
@@ -20,9 +20,9 @@ LOCAL_JAVA_RESOURCE_DIRS := resources
LOCAL_JAVA_LIBRARIES := ddmlib \
ddmuilib \
- hierarchyviewerlib \
swt \
- org.eclipse.jface_3.4.2.M20090107-0800
+ org.eclipse.jface_3.4.2.M20090107-0800 \
+ org.eclipse.core.commands_3.4.0.I20080509-2000
LOCAL_MODULE := hierarchyviewerlib
diff --git a/hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/HierarchyViewerDirector.java b/hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/HierarchyViewerDirector.java
index f0a705c..1264d60 100644
--- a/hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/HierarchyViewerDirector.java
+++ b/hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/HierarchyViewerDirector.java
@@ -50,6 +50,8 @@ import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.HashSet;
+import java.util.Timer;
+import java.util.TimerTask;
/**
* This is the class where most of the logic resides.
@@ -63,8 +65,21 @@ public abstract class HierarchyViewerDirector implements IDeviceChangeListener,
private int pixelPerfectRefreshesInProgress = 0;
+ private Timer pixelPerfectRefreshTimer = new Timer();
+
+ private boolean autoRefresh = false;
+
+ public static final int DEFAULT_PIXEL_PERFECT_AUTOREFRESH_INTERVAL = 5;
+
+ private int pixelPerfectAutoRefreshInterval = DEFAULT_PIXEL_PERFECT_AUTOREFRESH_INTERVAL;
+
+ private PixelPerfectAutoRefreshTask currentAutoRefreshTask;
+
+ private String filterText = "";
+
public void terminate() {
WindowUpdater.terminate();
+ pixelPerfectRefreshTimer.cancel();
}
public abstract String getAdbLocation();
@@ -101,7 +116,9 @@ public abstract class HierarchyViewerDirector implements IDeviceChangeListener,
public void deviceConnected(final IDevice device) {
executeInBackground("Connecting device", new Runnable() {
public void run() {
- if (device.isOnline()) {
+ if (DeviceSelectionModel.getModel().containsDevice(device)) {
+ windowsChanged(device);
+ } else if (device.isOnline()) {
DeviceBridge.setupDeviceForward(device);
if (!DeviceBridge.isViewServerRunning(device)) {
if (!DeviceBridge.startViewServer(device)) {
@@ -157,6 +174,7 @@ public abstract class HierarchyViewerDirector implements IDeviceChangeListener,
Window treeViewWindow = TreeViewModel.getModel().getWindow();
if (treeViewWindow != null && treeViewWindow.getDevice() == device) {
TreeViewModel.getModel().setData(null, null);
+ filterText = "";
}
}
});
@@ -289,6 +307,8 @@ public abstract class HierarchyViewerDirector implements IDeviceChangeListener,
executeInBackground("Loading view hierarchy", new Runnable() {
public void run() {
+ filterText = "";
+
ViewNode viewNode = DeviceBridge.loadWindowData(window);
if (viewNode != null) {
DeviceBridge.loadProfileData(window, viewNode);
@@ -329,7 +349,7 @@ public abstract class HierarchyViewerDirector implements IDeviceChangeListener,
final Image image = loadCapture(viewNode);
if (image != null) {
- Display.getDefault().asyncExec(new Runnable() {
+ Display.getDefault().syncExec(new Runnable() {
public void run() {
CaptureDisplay.show(shell, viewNode, image);
}
@@ -576,6 +596,7 @@ public abstract class HierarchyViewerDirector implements IDeviceChangeListener,
}
public void filterNodes(String filterText) {
+ this.filterText = filterText;
DrawableViewNode tree = TreeViewModel.getModel().getTree();
if (tree != null) {
tree.viewNode.filter(filterText);
@@ -584,4 +605,56 @@ public abstract class HierarchyViewerDirector implements IDeviceChangeListener,
}
}
+ public String getFilterText() {
+ return filterText;
+ }
+
+ private static class PixelPerfectAutoRefreshTask extends TimerTask {
+ @Override
+ public void run() {
+ HierarchyViewerDirector.getDirector().refreshPixelPerfect();
+ }
+ };
+
+ public void setPixelPerfectAutoRefresh(boolean value) {
+ synchronized (pixelPerfectRefreshTimer) {
+ if (value == autoRefresh) {
+ return;
+ }
+ autoRefresh = value;
+ if (autoRefresh) {
+ currentAutoRefreshTask = new PixelPerfectAutoRefreshTask();
+ pixelPerfectRefreshTimer.schedule(currentAutoRefreshTask,
+ pixelPerfectAutoRefreshInterval * 1000,
+ pixelPerfectAutoRefreshInterval * 1000);
+ } else {
+ currentAutoRefreshTask.cancel();
+ currentAutoRefreshTask = null;
+ }
+ }
+ }
+
+ public void setPixelPerfectAutoRefreshInterval(int value) {
+ synchronized (pixelPerfectRefreshTimer) {
+ if (pixelPerfectAutoRefreshInterval == value) {
+ return;
+ }
+ pixelPerfectAutoRefreshInterval = value;
+ if (autoRefresh) {
+ currentAutoRefreshTask.cancel();
+ long timeLeft =
+ Math.max(0, pixelPerfectAutoRefreshInterval
+ * 1000
+ - (System.currentTimeMillis() - currentAutoRefreshTask
+ .scheduledExecutionTime()));
+ currentAutoRefreshTask = new PixelPerfectAutoRefreshTask();
+ pixelPerfectRefreshTimer.schedule(currentAutoRefreshTask, timeLeft,
+ pixelPerfectAutoRefreshInterval * 1000);
+ }
+ }
+ }
+
+ public int getPixelPerfectAutoRefreshInverval() {
+ return pixelPerfectAutoRefreshInterval;
+ }
}
diff --git a/hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/actions/CapturePSDAction.java b/hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/actions/CapturePSDAction.java
new file mode 100644
index 0000000..240ced1
--- /dev/null
+++ b/hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/actions/CapturePSDAction.java
@@ -0,0 +1,61 @@
+/*
+ * 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.actions;
+
+import com.android.ddmuilib.ImageLoader;
+import com.android.hierarchyviewerlib.HierarchyViewerDirector;
+
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Shell;
+
+public class CapturePSDAction extends TreeViewEnabledAction implements ImageAction {
+
+ private static CapturePSDAction action;
+
+ private Image image;
+
+ private Shell shell;
+
+ private CapturePSDAction(Shell shell) {
+ super("&Capture Layers");
+ this.shell = shell;
+ setAccelerator(SWT.MOD1 + 'C');
+ ImageLoader imageLoader = ImageLoader.getLoader(HierarchyViewerDirector.class);
+ image = imageLoader.loadImage("capture-psd.png", Display.getDefault());
+ setImageDescriptor(ImageDescriptor.createFromImage(image));
+ setToolTipText("Capture the window layers as a photoshop document");
+ }
+
+ public static CapturePSDAction getAction(Shell shell) {
+ if (action == null) {
+ action = new CapturePSDAction(shell);
+ }
+ return action;
+ }
+
+ @Override
+ public void run() {
+ HierarchyViewerDirector.getDirector().capturePSD(shell);
+ }
+
+ public Image getImage() {
+ return image;
+ }
+}
diff --git a/hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/actions/DisplayViewAction.java b/hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/actions/DisplayViewAction.java
new file mode 100644
index 0000000..4fc8024
--- /dev/null
+++ b/hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/actions/DisplayViewAction.java
@@ -0,0 +1,61 @@
+/*
+ * 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.actions;
+
+import com.android.ddmuilib.ImageLoader;
+import com.android.hierarchyviewerlib.HierarchyViewerDirector;
+
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Shell;
+
+public class DisplayViewAction extends SelectedNodeEnabledAction implements ImageAction {
+
+ private static DisplayViewAction action;
+
+ private Image image;
+
+ private Shell shell;
+
+ private DisplayViewAction(Shell shell) {
+ super("&Display View");
+ this.shell = shell;
+ setAccelerator(SWT.MOD1 + 'D');
+ ImageLoader imageLoader = ImageLoader.getLoader(HierarchyViewerDirector.class);
+ image = imageLoader.loadImage("display.png", Display.getDefault());
+ setImageDescriptor(ImageDescriptor.createFromImage(image));
+ setToolTipText("Display the selected view image in a separate window");
+ }
+
+ public static DisplayViewAction getAction(Shell shell) {
+ if (action == null) {
+ action = new DisplayViewAction(shell);
+ }
+ return action;
+ }
+
+ @Override
+ public void run() {
+ HierarchyViewerDirector.getDirector().showCapture(shell);
+ }
+
+ public Image getImage() {
+ return image;
+ }
+}
diff --git a/hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/actions/ImageAction.java b/hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/actions/ImageAction.java
new file mode 100644
index 0000000..08320fd
--- /dev/null
+++ b/hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/actions/ImageAction.java
@@ -0,0 +1,27 @@
+/*
+ * 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.actions;
+
+import org.eclipse.swt.graphics.Image;
+
+public interface ImageAction {
+ public Image getImage();
+
+ public String getText();
+
+ public String getToolTipText();
+}
diff --git a/hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/actions/InspectScreenshotAction.java b/hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/actions/InspectScreenshotAction.java
new file mode 100644
index 0000000..7ef7109
--- /dev/null
+++ b/hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/actions/InspectScreenshotAction.java
@@ -0,0 +1,89 @@
+/*
+ * 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.actions;
+
+import com.android.ddmlib.IDevice;
+import com.android.ddmuilib.ImageLoader;
+import com.android.hierarchyviewerlib.HierarchyViewerDirector;
+import com.android.hierarchyviewerlib.device.Window;
+import com.android.hierarchyviewerlib.models.DeviceSelectionModel;
+import com.android.hierarchyviewerlib.models.DeviceSelectionModel.WindowChangeListener;
+
+import org.eclipse.jface.action.Action;
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.widgets.Display;
+
+public class InspectScreenshotAction extends Action implements ImageAction, WindowChangeListener {
+
+ private static InspectScreenshotAction action;
+
+ private Image image;
+
+ private InspectScreenshotAction() {
+ super("Inspect &Screenshot");
+ setAccelerator(SWT.MOD1 + 'S');
+ ImageLoader imageLoader = ImageLoader.getLoader(HierarchyViewerDirector.class);
+ image = imageLoader.loadImage("inspect-screenshot.png", Display.getDefault());
+ setImageDescriptor(ImageDescriptor.createFromImage(image));
+ setToolTipText("Inspect a screenshot in the pixel perfect view");
+ setEnabled(
+ DeviceSelectionModel.getModel().getSelectedDevice() != null);
+ DeviceSelectionModel.getModel().addWindowChangeListener(this);
+ }
+
+ public static InspectScreenshotAction getAction() {
+ if (action == null) {
+ action = new InspectScreenshotAction();
+ }
+ return action;
+ }
+
+ @Override
+ public void run() {
+ HierarchyViewerDirector.getDirector().inspectScreenshot();
+ }
+
+ public Image getImage() {
+ return image;
+ }
+
+ public void deviceChanged(IDevice device) {
+ // pass
+ }
+
+ public void deviceConnected(IDevice device) {
+ // pass
+ }
+
+ public void deviceDisconnected(IDevice device) {
+ // pass
+ }
+
+ public void focusChanged(IDevice device) {
+ // pass
+ }
+
+ public void selectionChanged(final IDevice device, final Window window) {
+ Display.getDefault().syncExec(new Runnable() {
+ public void run() {
+ InspectScreenshotAction.getAction().setEnabled(device != null);
+ }
+ });
+ }
+}
diff --git a/hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/actions/InvalidateAction.java b/hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/actions/InvalidateAction.java
new file mode 100644
index 0000000..aaf0ff0
--- /dev/null
+++ b/hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/actions/InvalidateAction.java
@@ -0,0 +1,57 @@
+/*
+ * 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.actions;
+
+import com.android.ddmuilib.ImageLoader;
+import com.android.hierarchyviewerlib.HierarchyViewerDirector;
+
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.widgets.Display;
+
+public class InvalidateAction extends SelectedNodeEnabledAction implements ImageAction {
+
+ private static InvalidateAction action;
+
+ private Image image;
+
+ private InvalidateAction() {
+ super("&Invalidate Layout");
+ setAccelerator(SWT.MOD1 + 'I');
+ ImageLoader imageLoader = ImageLoader.getLoader(HierarchyViewerDirector.class);
+ image = imageLoader.loadImage("invalidate.png", Display.getDefault());
+ setImageDescriptor(ImageDescriptor.createFromImage(image));
+ setToolTipText("Invalidate the layout for the current window");
+ }
+
+ public static InvalidateAction getAction() {
+ if (action == null) {
+ action = new InvalidateAction();
+ }
+ return action;
+ }
+
+ @Override
+ public void run() {
+ HierarchyViewerDirector.getDirector().invalidateCurrentNode();
+ }
+
+ public Image getImage() {
+ return image;
+ }
+}
diff --git a/hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/actions/LoadOverlayAction.java b/hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/actions/LoadOverlayAction.java
new file mode 100644
index 0000000..c948914
--- /dev/null
+++ b/hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/actions/LoadOverlayAction.java
@@ -0,0 +1,61 @@
+/*
+ * 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.actions;
+
+import com.android.ddmuilib.ImageLoader;
+import com.android.hierarchyviewerlib.HierarchyViewerDirector;
+
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Shell;
+
+public class LoadOverlayAction extends PixelPerfectEnabledAction implements ImageAction {
+
+ private static LoadOverlayAction action;
+
+ private Image image;
+
+ private Shell shell;
+
+ private LoadOverlayAction(Shell shell) {
+ super("Load &Overlay");
+ this.shell = shell;
+ setAccelerator(SWT.MOD1 + 'O');
+ ImageLoader imageLoader = ImageLoader.getLoader(HierarchyViewerDirector.class);
+ image = imageLoader.loadImage("load-overlay.png", Display.getDefault());
+ setImageDescriptor(ImageDescriptor.createFromImage(image));
+ setToolTipText("Load an image to overlay the screenshot");
+ }
+
+ public static LoadOverlayAction getAction(Shell shell) {
+ if (action == null) {
+ action = new LoadOverlayAction(shell);
+ }
+ return action;
+ }
+
+ @Override
+ public void run() {
+ HierarchyViewerDirector.getDirector().loadOverlay(shell);
+ }
+
+ public Image getImage() {
+ return image;
+ }
+}
diff --git a/hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/actions/LoadViewHierarchyAction.java b/hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/actions/LoadViewHierarchyAction.java
new file mode 100644
index 0000000..d26b2ef
--- /dev/null
+++ b/hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/actions/LoadViewHierarchyAction.java
@@ -0,0 +1,89 @@
+/*
+ * 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.actions;
+
+import com.android.ddmlib.IDevice;
+import com.android.ddmuilib.ImageLoader;
+import com.android.hierarchyviewerlib.HierarchyViewerDirector;
+import com.android.hierarchyviewerlib.device.Window;
+import com.android.hierarchyviewerlib.models.DeviceSelectionModel;
+import com.android.hierarchyviewerlib.models.DeviceSelectionModel.WindowChangeListener;
+
+import org.eclipse.jface.action.Action;
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.widgets.Display;
+
+public class LoadViewHierarchyAction extends Action implements ImageAction, WindowChangeListener {
+
+ private static LoadViewHierarchyAction action;
+
+ private Image image;
+
+ private LoadViewHierarchyAction() {
+ super("Load View &Hierarchy");
+ setAccelerator(SWT.MOD1 + 'H');
+ ImageLoader imageLoader = ImageLoader.getLoader(HierarchyViewerDirector.class);
+ image = imageLoader.loadImage("load-view-hierarchy.png", Display.getDefault());
+ setImageDescriptor(ImageDescriptor.createFromImage(image));
+ setToolTipText("Load the view hierarchy into the tree view");
+ setEnabled(
+ DeviceSelectionModel.getModel().getSelectedWindow() != null);
+ DeviceSelectionModel.getModel().addWindowChangeListener(this);
+ }
+
+ public static LoadViewHierarchyAction getAction() {
+ if (action == null) {
+ action = new LoadViewHierarchyAction();
+ }
+ return action;
+ }
+
+ @Override
+ public void run() {
+ HierarchyViewerDirector.getDirector().loadViewHierarchy();
+ }
+
+ public Image getImage() {
+ return image;
+ }
+
+ public void deviceChanged(IDevice device) {
+ // pass
+ }
+
+ public void deviceConnected(IDevice device) {
+ // pass
+ }
+
+ public void deviceDisconnected(IDevice device) {
+ // pass
+ }
+
+ public void focusChanged(IDevice device) {
+ // pass
+ }
+
+ public void selectionChanged(final IDevice device, final Window window) {
+ Display.getDefault().syncExec(new Runnable() {
+ public void run() {
+ LoadViewHierarchyAction.getAction().setEnabled(window != null);
+ }
+ });
+ }
+}
diff --git a/hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/actions/PixelPerfectAutoRefreshAction.java b/hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/actions/PixelPerfectAutoRefreshAction.java
new file mode 100644
index 0000000..5e31829
--- /dev/null
+++ b/hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/actions/PixelPerfectAutoRefreshAction.java
@@ -0,0 +1,58 @@
+/*
+ * 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.actions;
+
+import com.android.ddmuilib.ImageLoader;
+import com.android.hierarchyviewerlib.HierarchyViewerDirector;
+
+import org.eclipse.jface.action.Action;
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.widgets.Display;
+
+public class PixelPerfectAutoRefreshAction extends PixelPerfectEnabledAction implements ImageAction {
+
+ private static PixelPerfectAutoRefreshAction action;
+
+ private Image image;
+
+ private PixelPerfectAutoRefreshAction() {
+ super("Auto &Refresh", Action.AS_CHECK_BOX);
+ setAccelerator(SWT.MOD1 + 'R');
+ ImageLoader imageLoader = ImageLoader.getLoader(HierarchyViewerDirector.class);
+ image = imageLoader.loadImage("auto-refresh.png", Display.getDefault());
+ setImageDescriptor(ImageDescriptor.createFromImage(image));
+ setToolTipText("Automatically refresh the screenshot");
+ }
+
+ public static PixelPerfectAutoRefreshAction getAction() {
+ if (action == null) {
+ action = new PixelPerfectAutoRefreshAction();
+ }
+ return action;
+ }
+
+ @Override
+ public void run() {
+ HierarchyViewerDirector.getDirector().setPixelPerfectAutoRefresh(action.isChecked());
+ }
+
+ public Image getImage() {
+ return image;
+ }
+}
diff --git a/hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/actions/PixelPerfectEnabledAction.java b/hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/actions/PixelPerfectEnabledAction.java
new file mode 100644
index 0000000..9423d10
--- /dev/null
+++ b/hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/actions/PixelPerfectEnabledAction.java
@@ -0,0 +1,73 @@
+/*
+ * 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.actions;
+
+import com.android.hierarchyviewerlib.models.PixelPerfectModel;
+import com.android.hierarchyviewerlib.models.PixelPerfectModel.ImageChangeListener;
+
+import org.eclipse.jface.action.Action;
+import org.eclipse.swt.widgets.Display;
+
+public class PixelPerfectEnabledAction extends Action implements ImageChangeListener {
+ public PixelPerfectEnabledAction(String name) {
+ super(name);
+ setEnabled(PixelPerfectModel.getModel().getImage() != null);
+ PixelPerfectModel.getModel().addImageChangeListener(this);
+ }
+
+ public PixelPerfectEnabledAction(String name, int type) {
+ super(name, type);
+ setEnabled(PixelPerfectModel.getModel().getImage() != null);
+ PixelPerfectModel.getModel().addImageChangeListener(this);
+ }
+
+ public void crosshairMoved() {
+ // pass
+ }
+
+ public void imageChanged() {
+ //
+ }
+
+ public void imageLoaded() {
+ Display.getDefault().syncExec(new Runnable() {
+ public void run() {
+ setEnabled(PixelPerfectModel.getModel().getImage() != null);
+ }
+ });
+ }
+
+ public void overlayChanged() {
+ // pass
+ }
+
+ public void overlayTransparencyChanged() {
+ // pass
+ }
+
+ public void selectionChanged() {
+ // pass
+ }
+
+ public void treeChanged() {
+ // pass
+ }
+
+ public void zoomChanged() {
+ // pass
+ }
+}
diff --git a/hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/actions/RefreshPixelPerfectAction.java b/hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/actions/RefreshPixelPerfectAction.java
new file mode 100644
index 0000000..a5d7514
--- /dev/null
+++ b/hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/actions/RefreshPixelPerfectAction.java
@@ -0,0 +1,57 @@
+/*
+ * 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.actions;
+
+import com.android.ddmuilib.ImageLoader;
+import com.android.hierarchyviewerlib.HierarchyViewerDirector;
+
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.widgets.Display;
+
+public class RefreshPixelPerfectAction extends PixelPerfectEnabledAction implements ImageAction {
+
+ private static RefreshPixelPerfectAction action;
+
+ private Image image;
+
+ private RefreshPixelPerfectAction() {
+ super("&Refresh Screenshot");
+ setAccelerator(SWT.F5);
+ ImageLoader imageLoader = ImageLoader.getLoader(HierarchyViewerDirector.class);
+ image = imageLoader.loadImage("refresh-windows.png", Display.getDefault());
+ setImageDescriptor(ImageDescriptor.createFromImage(image));
+ setToolTipText("Refresh the screenshot");
+ }
+
+ public static RefreshPixelPerfectAction getAction() {
+ if (action == null) {
+ action = new RefreshPixelPerfectAction();
+ }
+ return action;
+ }
+
+ @Override
+ public void run() {
+ HierarchyViewerDirector.getDirector().refreshPixelPerfect();
+ }
+
+ public Image getImage() {
+ return image;
+ }
+}
diff --git a/hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/actions/RefreshPixelPerfectTreeAction.java b/hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/actions/RefreshPixelPerfectTreeAction.java
new file mode 100644
index 0000000..41214df
--- /dev/null
+++ b/hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/actions/RefreshPixelPerfectTreeAction.java
@@ -0,0 +1,57 @@
+/*
+ * 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.actions;
+
+import com.android.ddmuilib.ImageLoader;
+import com.android.hierarchyviewerlib.HierarchyViewerDirector;
+
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.widgets.Display;
+
+public class RefreshPixelPerfectTreeAction extends PixelPerfectEnabledAction implements ImageAction {
+
+ private static RefreshPixelPerfectTreeAction action;
+
+ private Image image;
+
+ private RefreshPixelPerfectTreeAction() {
+ super("Refresh &Tree");
+ setAccelerator(SWT.MOD1 + 'T');
+ ImageLoader imageLoader = ImageLoader.getLoader(HierarchyViewerDirector.class);
+ image = imageLoader.loadImage("load-view-hierarchy.png", Display.getDefault());
+ setImageDescriptor(ImageDescriptor.createFromImage(image));
+ setToolTipText("Refresh the tree");
+ }
+
+ public static RefreshPixelPerfectTreeAction getAction() {
+ if (action == null) {
+ action = new RefreshPixelPerfectTreeAction();
+ }
+ return action;
+ }
+
+ @Override
+ public void run() {
+ HierarchyViewerDirector.getDirector().refreshPixelPerfectTree();
+ }
+
+ public Image getImage() {
+ return image;
+ }
+}
diff --git a/hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/actions/RefreshViewAction.java b/hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/actions/RefreshViewAction.java
new file mode 100644
index 0000000..06c48ee
--- /dev/null
+++ b/hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/actions/RefreshViewAction.java
@@ -0,0 +1,57 @@
+/*
+ * 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.actions;
+
+import com.android.ddmuilib.ImageLoader;
+import com.android.hierarchyviewerlib.HierarchyViewerDirector;
+
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.widgets.Display;
+
+public class RefreshViewAction extends TreeViewEnabledAction implements ImageAction {
+
+ private static RefreshViewAction action;
+
+ private Image image;
+
+ private RefreshViewAction() {
+ super("Load View &Hierarchy");
+ setAccelerator(SWT.MOD1 + 'H');
+ ImageLoader imageLoader = ImageLoader.getLoader(HierarchyViewerDirector.class);
+ image = imageLoader.loadImage("load-view-hierarchy.png", Display.getDefault());
+ setImageDescriptor(ImageDescriptor.createFromImage(image));
+ setToolTipText("Reload the view hierarchy");
+ }
+
+ public static RefreshViewAction getAction() {
+ if (action == null) {
+ action = new RefreshViewAction();
+ }
+ return action;
+ }
+
+ @Override
+ public void run() {
+ HierarchyViewerDirector.getDirector().reloadViewHierarchy();
+ }
+
+ public Image getImage() {
+ return image;
+ }
+}
diff --git a/hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/actions/RefreshWindowsAction.java b/hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/actions/RefreshWindowsAction.java
new file mode 100644
index 0000000..47d692a
--- /dev/null
+++ b/hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/actions/RefreshWindowsAction.java
@@ -0,0 +1,58 @@
+/*
+ * 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.actions;
+
+import com.android.ddmuilib.ImageLoader;
+import com.android.hierarchyviewerlib.HierarchyViewerDirector;
+
+import org.eclipse.jface.action.Action;
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.widgets.Display;
+
+public class RefreshWindowsAction extends Action implements ImageAction {
+
+ private static RefreshWindowsAction action;
+
+ private Image image;
+
+ private RefreshWindowsAction() {
+ super("&Refresh");
+ setAccelerator(SWT.F5);
+ ImageLoader imageLoader = ImageLoader.getLoader(HierarchyViewerDirector.class);
+ image = imageLoader.loadImage("refresh-windows.png", Display.getDefault());
+ setImageDescriptor(ImageDescriptor.createFromImage(image));
+ setToolTipText("Refresh the list of devices");
+ }
+
+ public static RefreshWindowsAction getAction() {
+ if (action == null) {
+ action = new RefreshWindowsAction();
+ }
+ return action;
+ }
+
+ @Override
+ public void run() {
+ HierarchyViewerDirector.getDirector().refreshWindows();
+ }
+
+ public Image getImage() {
+ return image;
+ }
+}
diff --git a/hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/actions/RequestLayoutAction.java b/hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/actions/RequestLayoutAction.java
new file mode 100644
index 0000000..e3d6f8f
--- /dev/null
+++ b/hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/actions/RequestLayoutAction.java
@@ -0,0 +1,57 @@
+/*
+ * 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.actions;
+
+import com.android.ddmuilib.ImageLoader;
+import com.android.hierarchyviewerlib.HierarchyViewerDirector;
+
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.widgets.Display;
+
+public class RequestLayoutAction extends SelectedNodeEnabledAction implements ImageAction {
+
+ private static RequestLayoutAction action;
+
+ private Image image;
+
+ private RequestLayoutAction() {
+ super("Request &Layout");
+ setAccelerator(SWT.MOD1 + 'L');
+ ImageLoader imageLoader = ImageLoader.getLoader(HierarchyViewerDirector.class);
+ image = imageLoader.loadImage("request-layout.png", Display.getDefault());
+ setImageDescriptor(ImageDescriptor.createFromImage(image));
+ setToolTipText("Request the view to lay out");
+ }
+
+ public static RequestLayoutAction getAction() {
+ if (action == null) {
+ action = new RequestLayoutAction();
+ }
+ return action;
+ }
+
+ @Override
+ public void run() {
+ HierarchyViewerDirector.getDirector().relayoutCurrentNode();
+ }
+
+ public Image getImage() {
+ return image;
+ }
+}
diff --git a/hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/actions/SavePixelPerfectAction.java b/hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/actions/SavePixelPerfectAction.java
new file mode 100644
index 0000000..9781d42
--- /dev/null
+++ b/hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/actions/SavePixelPerfectAction.java
@@ -0,0 +1,61 @@
+/*
+ * 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.actions;
+
+import com.android.ddmuilib.ImageLoader;
+import com.android.hierarchyviewerlib.HierarchyViewerDirector;
+
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Shell;
+
+public class SavePixelPerfectAction extends PixelPerfectEnabledAction implements ImageAction {
+
+ private static SavePixelPerfectAction action;
+
+ private Image image;
+
+ private Shell shell;
+
+ private SavePixelPerfectAction(Shell shell) {
+ super("&Save as PNG");
+ this.shell = shell;
+ setAccelerator(SWT.MOD1 + 'S');
+ ImageLoader imageLoader = ImageLoader.getLoader(HierarchyViewerDirector.class);
+ image = imageLoader.loadImage("save.png", Display.getDefault());
+ setImageDescriptor(ImageDescriptor.createFromImage(image));
+ setToolTipText("Save the screenshot as a PNG image");
+ }
+
+ public static SavePixelPerfectAction getAction(Shell shell) {
+ if (action == null) {
+ action = new SavePixelPerfectAction(shell);
+ }
+ return action;
+ }
+
+ @Override
+ public void run() {
+ HierarchyViewerDirector.getDirector().savePixelPerfect(shell);
+ }
+
+ public Image getImage() {
+ return image;
+ }
+}
diff --git a/hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/actions/SaveTreeViewAction.java b/hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/actions/SaveTreeViewAction.java
new file mode 100644
index 0000000..094b101
--- /dev/null
+++ b/hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/actions/SaveTreeViewAction.java
@@ -0,0 +1,61 @@
+/*
+ * 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.actions;
+
+import com.android.ddmuilib.ImageLoader;
+import com.android.hierarchyviewerlib.HierarchyViewerDirector;
+
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Shell;
+
+public class SaveTreeViewAction extends TreeViewEnabledAction implements ImageAction {
+
+ private static SaveTreeViewAction action;
+
+ private Image image;
+
+ private Shell shell;
+
+ private SaveTreeViewAction(Shell shell) {
+ super("&Save as PNG");
+ this.shell = shell;
+ setAccelerator(SWT.MOD1 + 'S');
+ ImageLoader imageLoader = ImageLoader.getLoader(HierarchyViewerDirector.class);
+ image = imageLoader.loadImage("save.png", Display.getDefault());
+ setImageDescriptor(ImageDescriptor.createFromImage(image));
+ setToolTipText("Save the tree view as a PNG image");
+ }
+
+ public static SaveTreeViewAction getAction(Shell shell) {
+ if (action == null) {
+ action = new SaveTreeViewAction(shell);
+ }
+ return action;
+ }
+
+ @Override
+ public void run() {
+ HierarchyViewerDirector.getDirector().saveTreeView(shell);
+ }
+
+ public Image getImage() {
+ return image;
+ }
+}
diff --git a/hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/actions/SelectedNodeEnabledAction.java b/hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/actions/SelectedNodeEnabledAction.java
new file mode 100644
index 0000000..86f75a4
--- /dev/null
+++ b/hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/actions/SelectedNodeEnabledAction.java
@@ -0,0 +1,56 @@
+/*
+ * 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.actions;
+
+import com.android.hierarchyviewerlib.models.TreeViewModel;
+import com.android.hierarchyviewerlib.models.TreeViewModel.TreeChangeListener;
+
+import org.eclipse.jface.action.Action;
+import org.eclipse.swt.widgets.Display;
+
+public class SelectedNodeEnabledAction extends Action implements TreeChangeListener {
+ public SelectedNodeEnabledAction(String name) {
+ super(name);
+ setEnabled(TreeViewModel.getModel().getTree() != null
+ && TreeViewModel.getModel().getSelection() != null);
+ TreeViewModel.getModel().addTreeChangeListener(this);
+ }
+
+ public void selectionChanged() {
+ Display.getDefault().syncExec(new Runnable() {
+ public void run() {
+ setEnabled(TreeViewModel.getModel().getTree() != null
+ && TreeViewModel.getModel().getSelection() != null);
+ }
+ });
+ }
+
+ public void treeChanged() {
+ Display.getDefault().syncExec(new Runnable() {
+ public void run() {
+ setEnabled(TreeViewModel.getModel().getTree() != null
+ && TreeViewModel.getModel().getSelection() != null);
+ }
+ });
+ }
+
+ public void viewportChanged() {
+ }
+
+ public void zoomChanged() {
+ }
+}
diff --git a/hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/actions/TreeViewEnabledAction.java b/hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/actions/TreeViewEnabledAction.java
new file mode 100644
index 0000000..9ac7fb1
--- /dev/null
+++ b/hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/actions/TreeViewEnabledAction.java
@@ -0,0 +1,49 @@
+/*
+ * 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.actions;
+
+import com.android.hierarchyviewerlib.models.TreeViewModel;
+import com.android.hierarchyviewerlib.models.TreeViewModel.TreeChangeListener;
+
+import org.eclipse.jface.action.Action;
+import org.eclipse.swt.widgets.Display;
+
+public class TreeViewEnabledAction extends Action implements TreeChangeListener {
+ public TreeViewEnabledAction(String name) {
+ super(name);
+ setEnabled(TreeViewModel.getModel().getTree() != null);
+ TreeViewModel.getModel().addTreeChangeListener(this);
+ }
+
+ public void selectionChanged() {
+ // pass
+ }
+
+ public void treeChanged() {
+ Display.getDefault().syncExec(new Runnable() {
+ public void run() {
+ setEnabled(TreeViewModel.getModel().getTree() != null);
+ }
+ });
+ }
+
+ public void viewportChanged() {
+ }
+
+ public void zoomChanged() {
+ }
+}
diff --git a/hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/device/DeviceBridge.java b/hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/device/DeviceBridge.java
index 9e91375..399e470 100644
--- a/hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/device/DeviceBridge.java
+++ b/hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/device/DeviceBridge.java
@@ -94,6 +94,9 @@ public class DeviceBridge {
}
public static IDevice[] getDevices() {
+ if (bridge == null) {
+ return new IDevice[0];
+ }
return bridge.getDevices();
}
diff --git a/hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/models/DeviceSelectionModel.java b/hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/models/DeviceSelectionModel.java
index 8888642..09dfe76 100644
--- a/hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/models/DeviceSelectionModel.java
+++ b/hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/models/DeviceSelectionModel.java
@@ -51,6 +51,12 @@ public class DeviceSelectionModel {
return model;
}
+ public boolean containsDevice(IDevice device) {
+ synchronized (deviceMap) {
+ return deviceMap.containsKey(device);
+ }
+ }
+
public void addDevice(IDevice device, Window[] windows) {
synchronized (deviceMap) {
deviceMap.put(device, windows);
diff --git a/hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/models/PixelPerfectModel.java b/hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/models/PixelPerfectModel.java
index 7702f49..e52db14 100644
--- a/hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/models/PixelPerfectModel.java
+++ b/hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/models/PixelPerfectModel.java
@@ -33,6 +33,8 @@ public class PixelPerfectModel {
public static final int DEFAULT_ZOOM = 8;
+ public static final int DEFAULT_OVERLAY_TRANSPARENCY_PERCENTAGE = 50;
+
private IDevice device;
private Image image;
@@ -50,7 +52,7 @@ public class PixelPerfectModel {
private Image overlayImage;
- private double overlayTransparency = 0.5;
+ private double overlayTransparency = DEFAULT_OVERLAY_TRANSPARENCY_PERCENTAGE / 100.0;
private static PixelPerfectModel model;
diff --git a/hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/ui/CaptureDisplay.java b/hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/ui/CaptureDisplay.java
index 3c2c356..ecee8d0 100644
--- a/hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/ui/CaptureDisplay.java
+++ b/hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/ui/CaptureDisplay.java
@@ -16,6 +16,8 @@
package com.android.hierarchyviewerlib.ui;
+import com.android.ddmuilib.ImageLoader;
+import com.android.hierarchyviewerlib.HierarchyViewerDirector;
import com.android.hierarchyviewerlib.device.ViewNode;
import org.eclipse.swt.SWT;
@@ -118,6 +120,10 @@ public class CaptureDisplay {
canvas.addPaintListener(paintListener);
shell.addShellListener(shellListener);
+
+ ImageLoader imageLoader = ImageLoader.getLoader(HierarchyViewerDirector.class);
+ Image image = imageLoader.loadImage("display.png", Display.getDefault());
+ shell.setImage(image);
}
private static PaintListener paintListener = new PaintListener() {
diff --git a/hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/ui/DeviceSelector.java b/hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/ui/DeviceSelector.java
index 1aded6b..4e0748f 100644
--- a/hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/ui/DeviceSelector.java
+++ b/hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/ui/DeviceSelector.java
@@ -62,9 +62,13 @@ public class DeviceSelector extends Composite implements WindowChangeListener, S
private final static int ICON_WIDTH = 16;
+ private boolean doTreeViewStuff;
+
+ private boolean doPixelPerfectStuff;
+
private class ContentProvider implements ITreeContentProvider, ILabelProvider, IFontProvider {
public Object[] getChildren(Object parentElement) {
- if (parentElement instanceof IDevice) {
+ if (parentElement instanceof IDevice && doTreeViewStuff) {
Window[] list = model.getWindows((IDevice) parentElement);
if (list != null) {
return list;
@@ -81,7 +85,7 @@ public class DeviceSelector extends Composite implements WindowChangeListener, S
}
public boolean hasChildren(Object element) {
- if (element instanceof IDevice) {
+ if (element instanceof IDevice && doTreeViewStuff) {
Window[] list = model.getWindows((IDevice) element);
if (list != null) {
return list.length != 0;
@@ -148,8 +152,10 @@ public class DeviceSelector extends Composite implements WindowChangeListener, S
}
}
- public DeviceSelector(Composite parent) {
+ public DeviceSelector(Composite parent, boolean doTreeViewStuff, boolean doPixelPerfectStuff) {
super(parent, SWT.NONE);
+ this.doTreeViewStuff = doTreeViewStuff;
+ this.doPixelPerfectStuff = doPixelPerfectStuff;
setLayout(new FillLayout());
treeViewer = new TreeViewer(this, SWT.SINGLE);
treeViewer.setAutoExpandLevel(TreeViewer.ALL_LEVELS);
@@ -225,8 +231,25 @@ public class DeviceSelector extends Composite implements WindowChangeListener, S
return tree.setFocus();
}
+ public void setMode(boolean doTreeViewStuff, boolean doPixelPerfectStuff) {
+ if (this.doTreeViewStuff != doTreeViewStuff
+ || this.doPixelPerfectStuff != doPixelPerfectStuff) {
+ final boolean expandAll = !this.doTreeViewStuff && doTreeViewStuff;
+ this.doTreeViewStuff = doTreeViewStuff;
+ this.doPixelPerfectStuff = doPixelPerfectStuff;
+ Display.getDefault().syncExec(new Runnable() {
+ public void run() {
+ treeViewer.refresh();
+ if (expandAll) {
+ treeViewer.expandAll();
+ }
+ }
+ });
+ }
+ }
+
public void deviceConnected(final IDevice device) {
- Display.getDefault().asyncExec(new Runnable() {
+ Display.getDefault().syncExec(new Runnable() {
public void run() {
treeViewer.refresh();
treeViewer.setExpandedState(device, true);
@@ -235,7 +258,7 @@ public class DeviceSelector extends Composite implements WindowChangeListener, S
}
public void deviceChanged(final IDevice device) {
- Display.getDefault().asyncExec(new Runnable() {
+ Display.getDefault().syncExec(new Runnable() {
public void run() {
TreeSelection selection = (TreeSelection) treeViewer.getSelection();
treeViewer.refresh(device);
@@ -248,7 +271,7 @@ public class DeviceSelector extends Composite implements WindowChangeListener, S
}
public void deviceDisconnected(final IDevice device) {
- Display.getDefault().asyncExec(new Runnable() {
+ Display.getDefault().syncExec(new Runnable() {
public void run() {
treeViewer.refresh();
}
@@ -256,7 +279,7 @@ public class DeviceSelector extends Composite implements WindowChangeListener, S
}
public void focusChanged(final IDevice device) {
- Display.getDefault().asyncExec(new Runnable() {
+ Display.getDefault().syncExec(new Runnable() {
public void run() {
TreeSelection selection = (TreeSelection) treeViewer.getSelection();
treeViewer.refresh(device);
@@ -274,9 +297,9 @@ public class DeviceSelector extends Composite implements WindowChangeListener, S
public void widgetDefaultSelected(SelectionEvent e) {
Object selection = ((TreeItem) e.item).getData();
- if (selection instanceof IDevice) {
+ if (selection instanceof IDevice && doPixelPerfectStuff) {
HierarchyViewerDirector.getDirector().loadPixelPerfectData((IDevice) selection);
- } else if (selection instanceof Window) {
+ } else if (selection instanceof Window && doTreeViewStuff) {
HierarchyViewerDirector.getDirector().loadViewTreeData((Window) selection);
}
}
diff --git a/hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/ui/LayoutViewer.java b/hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/ui/LayoutViewer.java
index 6ae086d..1a13e48 100644
--- a/hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/ui/LayoutViewer.java
+++ b/hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/ui/LayoutViewer.java
@@ -70,6 +70,8 @@ public class LayoutViewer extends Canvas implements TreeChangeListener {
transform = new Transform(Display.getDefault());
inverse = new Transform(Display.getDefault());
+
+ treeChanged();
}
public void setShowExtras(boolean show) {
@@ -88,8 +90,12 @@ public class LayoutViewer extends Canvas implements TreeChangeListener {
private DisposeListener disposeListener = new DisposeListener() {
public void widgetDisposed(DisposeEvent e) {
+ model.removeTreeChangeListener(LayoutViewer.this);
transform.dispose();
inverse.dispose();
+ if (selectedNode != null) {
+ selectedNode.viewNode.dereferenceImage();
+ }
}
};
@@ -279,7 +285,7 @@ public class LayoutViewer extends Canvas implements TreeChangeListener {
}
private void doRedraw() {
- Display.getDefault().asyncExec(new Runnable() {
+ Display.getDefault().syncExec(new Runnable() {
public void run() {
redraw();
}
diff --git a/hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/ui/PixelPerfect.java b/hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/ui/PixelPerfect.java
index 242270b..42bcc59 100644
--- a/hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/ui/PixelPerfect.java
+++ b/hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/ui/PixelPerfect.java
@@ -86,6 +86,8 @@ public class PixelPerfect extends ScrolledComposite implements ImageChangeListen
borderColor = new Color(Display.getDefault(), new RGB(255, 0, 0));
marginColor = new Color(Display.getDefault(), new RGB(0, 255, 0));
paddingColor = new Color(Display.getDefault(), new RGB(0, 0, 255));
+
+ imageLoaded();
}
private DisposeListener disposeListener = new DisposeListener() {
@@ -278,7 +280,7 @@ public class PixelPerfect extends ScrolledComposite implements ImageChangeListen
};
private void doRedraw() {
- Display.getDefault().asyncExec(new Runnable() {
+ Display.getDefault().syncExec(new Runnable() {
public void run() {
canvas.redraw();
}
@@ -305,6 +307,7 @@ public class PixelPerfect extends ScrolledComposite implements ImageChangeListen
crosshairLocation = model.getCrosshairLocation();
selectedNode = model.getSelected();
overlayImage = model.getOverlayImage();
+ overlayTransparency = model.getOverlayTransparency();
}
}
});
diff --git a/hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/ui/PixelPerfectControls.java b/hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/ui/PixelPerfectControls.java
new file mode 100644
index 0000000..5a593f6
--- /dev/null
+++ b/hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/ui/PixelPerfectControls.java
@@ -0,0 +1,277 @@
+/*
+ * 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.hierarchyviewerlib.HierarchyViewerDirector;
+import com.android.hierarchyviewerlib.models.PixelPerfectModel;
+import com.android.hierarchyviewerlib.models.PixelPerfectModel.ImageChangeListener;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.DisposeEvent;
+import org.eclipse.swt.events.DisposeListener;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.events.SelectionListener;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.layout.FormAttachment;
+import org.eclipse.swt.layout.FormData;
+import org.eclipse.swt.layout.FormLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Slider;
+
+public class PixelPerfectControls extends Composite implements ImageChangeListener {
+
+ private Slider overlaySlider;
+
+ private Slider zoomSlider;
+
+ private Slider autoRefreshSlider;
+
+ public PixelPerfectControls(Composite parent) {
+ super(parent, SWT.NONE);
+ setLayout(new FormLayout());
+
+ Label overlayTransparencyRight = new Label(this, SWT.NONE);
+ overlayTransparencyRight.setText("100%");
+ FormData overlayTransparencyRightData = new FormData();
+ overlayTransparencyRightData.right = new FormAttachment(100, -2);
+ overlayTransparencyRightData.top = new FormAttachment(0, 2);
+ overlayTransparencyRight.setLayoutData(overlayTransparencyRightData);
+
+ Label refreshRight = new Label(this, SWT.NONE);
+ refreshRight.setText("40s");
+ FormData refreshRightData = new FormData();
+ refreshRightData.right = new FormAttachment(100, -2);
+ refreshRightData.top = new FormAttachment(overlayTransparencyRight, 2);
+ refreshRightData.left = new FormAttachment(overlayTransparencyRight, 0, SWT.LEFT);
+ refreshRight.setLayoutData(refreshRightData);
+
+ Label zoomRight = new Label(this, SWT.NONE);
+ zoomRight.setText("24x");
+ FormData zoomRightData = new FormData();
+ zoomRightData.right = new FormAttachment(100, -2);
+ zoomRightData.top = new FormAttachment(refreshRight, 2);
+ zoomRightData.left = new FormAttachment(overlayTransparencyRight, 0, SWT.LEFT);
+ zoomRight.setLayoutData(zoomRightData);
+
+ Label overlayTransparency = new Label(this, SWT.NONE);
+ Label refresh = new Label(this, SWT.NONE);
+
+ overlayTransparency.setText("Overlay:");
+ FormData overlayTransparencyData = new FormData();
+ overlayTransparencyData.left = new FormAttachment(0, 2);
+ overlayTransparencyData.top = new FormAttachment(0, 2);
+ overlayTransparencyData.right = new FormAttachment(refresh, 0, SWT.RIGHT);
+ overlayTransparency.setLayoutData(overlayTransparencyData);
+
+ refresh.setText("Refresh Rate:");
+ FormData refreshData = new FormData();
+ refreshData.top = new FormAttachment(overlayTransparency, 2);
+ refreshData.left = new FormAttachment(0, 2);
+ refresh.setLayoutData(refreshData);
+
+ Label zoom = new Label(this, SWT.NONE);
+ zoom.setText("Zoom:");
+ FormData zoomData = new FormData();
+ zoomData.right = new FormAttachment(refresh, 0, SWT.RIGHT);
+ zoomData.top = new FormAttachment(refresh, 2);
+ zoomData.left = new FormAttachment(0, 2);
+ zoom.setLayoutData(zoomData);
+
+ Label overlayTransparencyLeft = new Label(this, SWT.RIGHT);
+ overlayTransparencyLeft.setText("0%");
+ FormData overlayTransparencyLeftData = new FormData();
+ overlayTransparencyLeftData.top = new FormAttachment(0, 2);
+ overlayTransparencyLeftData.left = new FormAttachment(overlayTransparency, 2);
+ overlayTransparencyLeft.setLayoutData(overlayTransparencyLeftData);
+
+ Label refreshLeft = new Label(this, SWT.RIGHT);
+ refreshLeft.setText("1s");
+ FormData refreshLeftData = new FormData();
+ refreshLeftData.top = new FormAttachment(overlayTransparencyLeft, 2);
+ refreshLeftData.left = new FormAttachment(refresh, 2);
+ refreshLeft.setLayoutData(refreshLeftData);
+
+ Label zoomLeft = new Label(this, SWT.RIGHT);
+ zoomLeft.setText("2x");
+ FormData zoomLeftData = new FormData();
+ zoomLeftData.top = new FormAttachment(refreshLeft, 2);
+ zoomLeftData.left = new FormAttachment(zoom, 2);
+ zoomLeft.setLayoutData(zoomLeftData);
+
+ overlaySlider = new Slider(this, SWT.HORIZONTAL);
+ overlaySlider.setMinimum(0);
+ overlaySlider.setMaximum(101);
+ overlaySlider.setThumb(1);
+ overlaySlider.setSelection((int) Math.round(PixelPerfectModel.getModel()
+ .getOverlayTransparency() * 100));
+
+ Image overlayImage = PixelPerfectModel.getModel().getOverlayImage();
+ overlaySlider.setEnabled(overlayImage != null);
+ FormData overlaySliderData = new FormData();
+ overlaySliderData.right = new FormAttachment(overlayTransparencyRight, -4);
+ overlaySliderData.top = new FormAttachment(0, 2);
+ overlaySliderData.left = new FormAttachment(overlayTransparencyLeft, 4);
+ overlaySlider.setLayoutData(overlaySliderData);
+
+ overlaySlider.addSelectionListener(overlaySliderSelectionListener);
+
+ autoRefreshSlider = new Slider(this, SWT.HORIZONTAL);
+ autoRefreshSlider.setMinimum(1);
+ autoRefreshSlider.setMaximum(41);
+ autoRefreshSlider.setThumb(1);
+ autoRefreshSlider.setSelection(HierarchyViewerDirector.getDirector()
+ .getPixelPerfectAutoRefreshInverval());
+ FormData refreshSliderData = new FormData();
+ refreshSliderData.right = new FormAttachment(overlayTransparencyRight, -4);
+ refreshSliderData.top = new FormAttachment(overlayTransparencyRight, 2);
+ refreshSliderData.left = new FormAttachment(overlaySlider, 0, SWT.LEFT);
+ autoRefreshSlider.setLayoutData(refreshSliderData);
+
+ autoRefreshSlider.addSelectionListener(refreshSliderSelectionListener);
+
+ zoomSlider = new Slider(this, SWT.HORIZONTAL);
+ zoomSlider.setMinimum(2);
+ zoomSlider.setMaximum(25);
+ zoomSlider.setThumb(1);
+ zoomSlider.setSelection(PixelPerfectModel.getModel().getZoom());
+ FormData zoomSliderData = new FormData();
+ zoomSliderData.right = new FormAttachment(overlayTransparencyRight, -4);
+ zoomSliderData.top = new FormAttachment(refreshRight, 2);
+ zoomSliderData.left = new FormAttachment(overlaySlider, 0, SWT.LEFT);
+ zoomSlider.setLayoutData(zoomSliderData);
+
+ zoomSlider.addSelectionListener(zoomSliderSelectionListener);
+
+ addDisposeListener(disposeListener);
+
+ PixelPerfectModel.getModel().addImageChangeListener(this);
+ }
+
+ private DisposeListener disposeListener = new DisposeListener() {
+ public void widgetDisposed(DisposeEvent e) {
+ PixelPerfectModel.getModel().removeImageChangeListener(PixelPerfectControls.this);
+ }
+ };
+
+ private SelectionListener overlaySliderSelectionListener = new SelectionListener() {
+ private int oldValue;
+
+ public void widgetDefaultSelected(SelectionEvent e) {
+ // pass
+ }
+
+ public void widgetSelected(SelectionEvent e) {
+ int newValue = overlaySlider.getSelection();
+ if (oldValue != newValue) {
+ PixelPerfectModel.getModel().removeImageChangeListener(PixelPerfectControls.this);
+ PixelPerfectModel.getModel().setOverlayTransparency(newValue / 100.0);
+ PixelPerfectModel.getModel().addImageChangeListener(PixelPerfectControls.this);
+ oldValue = newValue;
+ }
+ }
+ };
+
+ private SelectionListener refreshSliderSelectionListener = new SelectionListener() {
+ private int oldValue;
+
+ public void widgetDefaultSelected(SelectionEvent e) {
+ // pass
+ }
+
+ public void widgetSelected(SelectionEvent e) {
+ int newValue = autoRefreshSlider.getSelection();
+ if (oldValue != newValue) {
+ HierarchyViewerDirector.getDirector().setPixelPerfectAutoRefreshInterval(newValue);
+ }
+ }
+ };
+
+ private SelectionListener zoomSliderSelectionListener = new SelectionListener() {
+ private int oldValue;
+
+ public void widgetDefaultSelected(SelectionEvent e) {
+ // pass
+ }
+
+ public void widgetSelected(SelectionEvent e) {
+ int newValue = zoomSlider.getSelection();
+ if (oldValue != newValue) {
+ PixelPerfectModel.getModel().removeImageChangeListener(PixelPerfectControls.this);
+ PixelPerfectModel.getModel().setZoom(newValue);
+ PixelPerfectModel.getModel().addImageChangeListener(PixelPerfectControls.this);
+ oldValue = newValue;
+ }
+ }
+ };
+
+ public void crosshairMoved() {
+ // pass
+ }
+
+ public void treeChanged() {
+ // pass
+ }
+
+ public void imageChanged() {
+ // pass
+ }
+
+ public void imageLoaded() {
+ Display.getDefault().syncExec(new Runnable() {
+ public void run() {
+ Image overlayImage = PixelPerfectModel.getModel().getOverlayImage();
+ overlaySlider.setEnabled(overlayImage != null);
+ if (PixelPerfectModel.getModel().getImage() == null) {
+ } else {
+ zoomSlider.setSelection(PixelPerfectModel.getModel().getZoom());
+ }
+ }
+ });
+ }
+
+ public void overlayChanged() {
+ Display.getDefault().syncExec(new Runnable() {
+ public void run() {
+ Image overlayImage = PixelPerfectModel.getModel().getOverlayImage();
+ overlaySlider.setEnabled(overlayImage != null);
+ }
+ });
+ }
+
+ public void overlayTransparencyChanged() {
+ Display.getDefault().syncExec(new Runnable() {
+ public void run() {
+ overlaySlider.setSelection((int) (PixelPerfectModel.getModel()
+ .getOverlayTransparency() * 100));
+ }
+ });
+ }
+
+ public void selectionChanged() {
+ // pass
+ }
+
+ public void zoomChanged() {
+ Display.getDefault().syncExec(new Runnable() {
+ public void run() {
+ zoomSlider.setSelection(PixelPerfectModel.getModel().getZoom());
+ }
+ });
+ }
+}
diff --git a/hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/ui/PixelPerfectLoupe.java b/hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/ui/PixelPerfectLoupe.java
index b5ad13a..53afc9e 100644
--- a/hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/ui/PixelPerfectLoupe.java
+++ b/hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/ui/PixelPerfectLoupe.java
@@ -85,6 +85,8 @@ public class PixelPerfectLoupe extends Canvas implements ImageChangeListener {
crosshairColor = new Color(Display.getDefault(), new RGB(255, 94, 254));
transform = new Transform(Display.getDefault());
+
+ imageLoaded();
}
public void setShowOverlay(boolean value) {
@@ -275,7 +277,7 @@ public class PixelPerfectLoupe extends Canvas implements ImageChangeListener {
};
private void doRedraw() {
- Display.getDefault().asyncExec(new Runnable() {
+ Display.getDefault().syncExec(new Runnable() {
public void run() {
redraw();
}
@@ -302,6 +304,7 @@ public class PixelPerfectLoupe extends Canvas implements ImageChangeListener {
crosshairLocation = model.getCrosshairLocation();
zoom = model.getZoom();
overlayImage = model.getOverlayImage();
+ overlayTransparency = model.getOverlayTransparency();
}
}
});
@@ -344,8 +347,8 @@ public class PixelPerfectLoupe extends Canvas implements ImageChangeListener {
// grid.
grid.dispose();
grid = null;
- zoom = model.getZoom();
}
+ zoom = model.getZoom();
}
}
});
diff --git a/hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/ui/PixelPerfectPixelPanel.java b/hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/ui/PixelPerfectPixelPanel.java
index 8fce603..afe3dc8 100644
--- a/hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/ui/PixelPerfectPixelPanel.java
+++ b/hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/ui/PixelPerfectPixelPanel.java
@@ -52,6 +52,8 @@ public class PixelPerfectPixelPanel extends Canvas implements ImageChangeListene
addPaintListener(paintListener);
addDisposeListener(disposeListener);
+
+ imageLoaded();
}
@Override
@@ -135,7 +137,7 @@ public class PixelPerfectPixelPanel extends Canvas implements ImageChangeListene
};
private void doRedraw() {
- Display.getDefault().asyncExec(new Runnable() {
+ Display.getDefault().syncExec(new Runnable() {
public void run() {
redraw();
}
diff --git a/hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/ui/PixelPerfectTree.java b/hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/ui/PixelPerfectTree.java
index 80e4091..d34dcf2 100644
--- a/hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/ui/PixelPerfectTree.java
+++ b/hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/ui/PixelPerfectTree.java
@@ -152,15 +152,12 @@ public class PixelPerfectTree extends Composite implements ImageChangeListener,
private void loadResources() {
ImageLoader loader = ImageLoader.getDdmUiLibLoader();
fileImage = loader.loadImage("file.png", Display.getDefault());
-
folderImage = loader.loadImage("folder.png", Display.getDefault());
}
private DisposeListener disposeListener = new DisposeListener() {
public void widgetDisposed(DisposeEvent e) {
model.removeImageChangeListener(PixelPerfectTree.this);
- fileImage.dispose();
- folderImage.dispose();
}
};
@@ -170,7 +167,7 @@ public class PixelPerfectTree extends Composite implements ImageChangeListener,
}
public void imageLoaded() {
- Display.getDefault().asyncExec(new Runnable() {
+ Display.getDefault().syncExec(new Runnable() {
public void run() {
treeViewer.refresh();
treeViewer.expandAll();
diff --git a/hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/ui/PropertyViewer.java b/hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/ui/PropertyViewer.java
index d7c5b1a..14068a3 100644
--- a/hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/ui/PropertyViewer.java
+++ b/hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/ui/PropertyViewer.java
@@ -210,6 +210,8 @@ public class PropertyViewer extends Composite implements TreeChangeListener {
new TreeColumnResizer(this, propertyColumn, valueColumn);
addControlListener(controlListener);
+
+ treeChanged();
}
public void loadResources() {
@@ -280,7 +282,7 @@ public class PropertyViewer extends Composite implements TreeChangeListener {
}
private void doRefresh() {
- Display.getDefault().asyncExec(new Runnable() {
+ Display.getDefault().syncExec(new Runnable() {
public void run() {
treeViewer.refresh();
}
diff --git a/hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/ui/TreeView.java b/hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/ui/TreeView.java
index e2a0a6d..ea53ee4 100644
--- a/hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/ui/TreeView.java
+++ b/hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/ui/TreeView.java
@@ -16,6 +16,7 @@
package com.android.hierarchyviewerlib.ui;
+import com.android.ddmlib.Log;
import com.android.ddmuilib.ImageLoader;
import com.android.hierarchyviewerlib.HierarchyViewerDirector;
import com.android.hierarchyviewerlib.device.ViewNode.ProfileRating;
@@ -164,6 +165,7 @@ public class TreeView extends Canvas implements TreeChangeListener {
transform = new Transform(Display.getDefault());
inverse = new Transform(Display.getDefault());
+ loadAllData();
}
private void loadResources() {
@@ -190,6 +192,9 @@ public class TreeView extends Canvas implements TreeChangeListener {
inverse.dispose();
boxColor.dispose();
textBackgroundColor.dispose();
+ if (tree != null) {
+ model.setViewport(null);
+ }
}
};
@@ -959,12 +964,37 @@ public class TreeView extends Canvas implements TreeChangeListener {
}
private void doRedraw() {
- Display.getDefault().asyncExec(new Runnable() {
+ Display.getDefault().syncExec(new Runnable() {
public void run() {
redraw();
}
});
}
+
+ public void loadAllData() {
+ boolean newViewport = viewport == null;
+ Display.getDefault().syncExec(new Runnable() {
+ public void run() {
+ synchronized (this) {
+ tree = model.getTree();
+ selectedNode = model.getSelection();
+ viewport = model.getViewport();
+ zoom = model.getZoom();
+ if (tree != null && viewport == null) {
+ viewport =
+ new Rectangle(0, tree.top + DrawableViewNode.NODE_HEIGHT / 2
+ - getBounds().height / 2, getBounds().width,
+ getBounds().height);
+ } else {
+ setTransform();
+ }
+ }
+ }
+ });
+ if (newViewport) {
+ model.setViewport(viewport);
+ }
+ }
// Fickle behaviour... When a new tree is loaded, the model doesn't know
// about the viewport until it passes through here.
@@ -987,6 +1017,8 @@ public class TreeView extends Canvas implements TreeChangeListener {
});
if (viewport != null) {
model.setViewport(viewport);
+ } else {
+ doRedraw();
}
}
diff --git a/hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/ui/TreeViewControls.java b/hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/ui/TreeViewControls.java
new file mode 100644
index 0000000..08117b5
--- /dev/null
+++ b/hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/ui/TreeViewControls.java
@@ -0,0 +1,143 @@
+/*
+ * 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.hierarchyviewerlib.HierarchyViewerDirector;
+import com.android.hierarchyviewerlib.models.TreeViewModel;
+import com.android.hierarchyviewerlib.models.TreeViewModel.TreeChangeListener;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.DisposeEvent;
+import org.eclipse.swt.events.DisposeListener;
+import org.eclipse.swt.events.ModifyEvent;
+import org.eclipse.swt.events.ModifyListener;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.events.SelectionListener;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Slider;
+import org.eclipse.swt.widgets.Text;
+
+public class TreeViewControls extends Composite implements TreeChangeListener {
+
+ private Text filterText;
+
+ private Slider zoomSlider;
+
+ public TreeViewControls(Composite parent) {
+ super(parent, SWT.NONE);
+ GridLayout layout = new GridLayout(5, false);
+ layout.marginWidth = layout.marginHeight = 2;
+ layout.verticalSpacing = layout.horizontalSpacing = 4;
+ setLayout(layout);
+
+ Label filterLabel = new Label(this, SWT.NONE);
+ filterLabel.setText("Filter by class or id:");
+ filterLabel.setLayoutData(new GridData(GridData.BEGINNING, GridData.CENTER, false, true));
+
+ filterText = new Text(this, SWT.LEFT | SWT.SINGLE);
+ filterText.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+ filterText.addModifyListener(filterTextModifyListener);
+ filterText.setText(HierarchyViewerDirector.getDirector().getFilterText());
+
+ Label smallZoomLabel = new Label(this, SWT.NONE);
+ smallZoomLabel.setText(" 20%");
+ smallZoomLabel
+ .setLayoutData(new GridData(GridData.BEGINNING, GridData.CENTER, false, true));
+
+ zoomSlider = new Slider(this, SWT.HORIZONTAL);
+ GridData zoomSliderGridData = new GridData(GridData.CENTER, GridData.CENTER, false, false);
+ zoomSliderGridData.widthHint = 190;
+ zoomSlider.setLayoutData(zoomSliderGridData);
+ zoomSlider.setMinimum((int) (TreeViewModel.MIN_ZOOM * 10));
+ zoomSlider.setMaximum((int) (TreeViewModel.MAX_ZOOM * 10 + 1));
+ zoomSlider.setThumb(1);
+ zoomSlider.setSelection((int) Math.round(TreeViewModel.getModel().getZoom() * 10));
+
+ zoomSlider.addSelectionListener(zoomSliderSelectionListener);
+
+ Label largeZoomLabel = new Label(this, SWT.NONE);
+ largeZoomLabel
+ .setLayoutData(new GridData(GridData.BEGINNING, GridData.CENTER, false, true));
+ largeZoomLabel.setText("200%");
+
+ addDisposeListener(disposeListener);
+
+ TreeViewModel.getModel().addTreeChangeListener(this);
+ }
+
+ private DisposeListener disposeListener = new DisposeListener() {
+ public void widgetDisposed(DisposeEvent e) {
+ TreeViewModel.getModel().removeTreeChangeListener(TreeViewControls.this);
+ }
+ };
+
+ private SelectionListener zoomSliderSelectionListener = new SelectionListener() {
+ private int oldValue;
+
+ public void widgetDefaultSelected(SelectionEvent e) {
+ // pass
+ }
+
+ public void widgetSelected(SelectionEvent e) {
+ int newValue = zoomSlider.getSelection();
+ if (oldValue != newValue) {
+ TreeViewModel.getModel().removeTreeChangeListener(TreeViewControls.this);
+ TreeViewModel.getModel().setZoom(newValue / 10.0);
+ TreeViewModel.getModel().addTreeChangeListener(TreeViewControls.this);
+ oldValue = newValue;
+ }
+ }
+ };
+
+ private ModifyListener filterTextModifyListener = new ModifyListener() {
+ public void modifyText(ModifyEvent e) {
+ HierarchyViewerDirector.getDirector().filterNodes(filterText.getText());
+ }
+ };
+
+ public void selectionChanged() {
+ // pass
+ }
+
+ public void treeChanged() {
+ Display.getDefault().syncExec(new Runnable() {
+ public void run() {
+ if (TreeViewModel.getModel().getTree() != null) {
+ zoomSlider.setSelection((int) Math
+ .round(TreeViewModel.getModel().getZoom() * 10));
+ }
+ filterText.setText("");
+ }
+ });
+ }
+
+ public void viewportChanged() {
+ // pass
+ }
+
+ public void zoomChanged() {
+ Display.getDefault().syncExec(new Runnable() {
+ public void run() {
+ zoomSlider.setSelection((int) Math.round(TreeViewModel.getModel().getZoom() * 10));
+ }
+ });
+ };
+}
diff --git a/hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/ui/TreeViewOverview.java b/hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/ui/TreeViewOverview.java
index ee84ccb..fb01b86 100644
--- a/hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/ui/TreeViewOverview.java
+++ b/hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/ui/TreeViewOverview.java
@@ -85,6 +85,8 @@ public class TreeViewOverview extends Canvas implements TreeChangeListener {
transform = new Transform(Display.getDefault());
inverse = new Transform(Display.getDefault());
+
+ loadAllData();
}
private void loadResources() {
@@ -207,7 +209,7 @@ public class TreeViewOverview extends Canvas implements TreeChangeListener {
private PaintListener paintListener = new PaintListener() {
public void paintControl(PaintEvent e) {
synchronized (TreeViewOverview.this) {
- if (tree != null && viewport != null) {
+ if (tree != null) {
e.gc.setBackground(Display.getDefault().getSystemColor(SWT.COLOR_BLACK));
e.gc.setForeground(Display.getDefault().getSystemColor(SWT.COLOR_WHITE));
e.gc.fillRectangle(0, 0, getBounds().width, getBounds().height);
@@ -218,16 +220,20 @@ public class TreeViewOverview extends Canvas implements TreeChangeListener {
e.gc.drawPath(connectionPath);
connectionPath.dispose();
- e.gc.setAlpha(50);
- e.gc.setBackground(Display.getDefault().getSystemColor(SWT.COLOR_WHITE));
- e.gc.fillRectangle((int) viewport.x, (int) viewport.y, (int) Math
- .ceil(viewport.width), (int) Math.ceil(viewport.height));
-
- e.gc.setAlpha(255);
- e.gc.setForeground(Display.getDefault().getSystemColor(SWT.COLOR_DARK_GRAY));
- e.gc.setLineWidth((int) Math.ceil(2 / scale));
- e.gc.drawRectangle((int) viewport.x, (int) viewport.y, (int) Math
- .ceil(viewport.width), (int) Math.ceil(viewport.height));
+ if (viewport != null) {
+ e.gc.setAlpha(50);
+ e.gc.setBackground(Display.getDefault().getSystemColor(SWT.COLOR_WHITE));
+ e.gc.fillRectangle((int) viewport.x, (int) viewport.y, (int) Math
+ .ceil(viewport.width), (int) Math.ceil(viewport.height));
+
+ e.gc.setAlpha(255);
+ e.gc
+ .setForeground(Display.getDefault().getSystemColor(
+ SWT.COLOR_DARK_GRAY));
+ e.gc.setLineWidth((int) Math.ceil(2 / scale));
+ e.gc.drawRectangle((int) viewport.x, (int) viewport.y, (int) Math
+ .ceil(viewport.width), (int) Math.ceil(viewport.height));
+ }
}
}
}
@@ -267,13 +273,27 @@ public class TreeViewOverview extends Canvas implements TreeChangeListener {
}
private void doRedraw() {
- Display.getDefault().asyncExec(new Runnable() {
+ Display.getDefault().syncExec(new Runnable() {
public void run() {
redraw();
}
});
}
+ public void loadAllData() {
+ Display.getDefault().syncExec(new Runnable() {
+ public void run() {
+ synchronized (this) {
+ tree = model.getTree();
+ selectedNode = model.getSelection();
+ viewport = model.getViewport();
+ setBounds();
+ setTransform();
+ }
+ }
+ });
+ }
+
// Note the syncExec and then synchronized... It avoids deadlock
public void treeChanged() {
Display.getDefault().syncExec(new Runnable() {
@@ -281,6 +301,7 @@ public class TreeViewOverview extends Canvas implements TreeChangeListener {
synchronized (this) {
tree = model.getTree();
selectedNode = model.getSelection();
+ viewport = model.getViewport();
setBounds();
setTransform();
}
@@ -299,11 +320,16 @@ public class TreeViewOverview extends Canvas implements TreeChangeListener {
bounds.height =
Math.max(viewport.y + viewport.height, tree.bounds.y + tree.bounds.height)
- bounds.y;
+ } else if (tree != null) {
+ bounds.x = tree.bounds.x;
+ bounds.y = tree.bounds.y;
+ bounds.width = tree.bounds.x + tree.bounds.width - bounds.x;
+ bounds.height = tree.bounds.y + tree.bounds.height - bounds.y;
}
}
private void setTransform() {
- if (viewport != null && tree != null) {
+ if (tree != null) {
transform.identity();
inverse.identity();
diff --git a/hierarchyviewer2/libs/hierarchyviewerlib/src/resources/images/show-extras.png b/hierarchyviewer2/libs/hierarchyviewerlib/src/resources/images/show-extras.png
new file mode 100644
index 0000000..ba9c305
--- /dev/null
+++ b/hierarchyviewer2/libs/hierarchyviewerlib/src/resources/images/show-extras.png
Binary files differ