diff options
author | Konstantin Lopyrev <klopyrev@google.com> | 2010-08-27 09:08:34 -0700 |
---|---|---|
committer | Konstantin Lopyrev <klopyrev@google.com> | 2010-08-27 16:21:58 -0700 |
commit | 99bd6912e7b5b97fc6d4bb787e76b2d9dfffd7ae (patch) | |
tree | 0f108bf445c903cbc2e3cb48ff3f441a3f799f5a /hierarchyviewer2/libs | |
parent | 712c280346135b7c29c02a2908ff9faf103d6861 (diff) | |
download | sdk-99bd6912e7b5b97fc6d4bb787e76b2d9dfffd7ae.zip sdk-99bd6912e7b5b97fc6d4bb787e76b2d9dfffd7ae.tar.gz sdk-99bd6912e7b5b97fc6d4bb787e76b2d9dfffd7ae.tar.bz2 |
Refactoring and integrating into Eclipse
Change-Id: I1fd3c3828fb2474f2f7394ee2831fcd7eb675878
Diffstat (limited to 'hierarchyviewer2/libs')
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 Binary files differnew file mode 100644 index 0000000..ba9c305 --- /dev/null +++ b/hierarchyviewer2/libs/hierarchyviewerlib/src/resources/images/show-extras.png |