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 | |
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')
42 files changed, 1004 insertions, 471 deletions
diff --git a/hierarchyviewer2/app/etc/manifest.txt b/hierarchyviewer2/app/etc/manifest.txt index fa7e491..c1b0666 100644 --- a/hierarchyviewer2/app/etc/manifest.txt +++ b/hierarchyviewer2/app/etc/manifest.txt @@ -1,2 +1,2 @@ Main-Class: com.android.hierarchyviewer.HierarchyViewerApplication -Class-Path: ddmlib.jar hierarchyviewerlib.jar +Class-Path: ddmlib.jar ddmuilib.jar hierarchyviewerlib.jar swt.jar org.eclipse.jface_3.4.2.M20090107-0800.jar org.eclipse.core.commands_3.4.0.I20080509-2000.jar sdklib.jar diff --git a/hierarchyviewer2/app/src/com/android/hierarchyviewer/HierarchyViewerApplication.java b/hierarchyviewer2/app/src/com/android/hierarchyviewer/HierarchyViewerApplication.java index d66f8e1..f5c6e98 100644 --- a/hierarchyviewer2/app/src/com/android/hierarchyviewer/HierarchyViewerApplication.java +++ b/hierarchyviewer2/app/src/com/android/hierarchyviewer/HierarchyViewerApplication.java @@ -16,43 +16,41 @@ package com.android.hierarchyviewer; -import com.android.ddmlib.IDevice; import com.android.ddmuilib.ImageLoader; import com.android.hierarchyviewer.actions.AboutAction; -import com.android.hierarchyviewer.actions.CapturePSDAction; -import com.android.hierarchyviewer.actions.DisplayViewAction; -import com.android.hierarchyviewer.actions.InspectScreenshotAction; -import com.android.hierarchyviewer.actions.InvalidateAction; import com.android.hierarchyviewer.actions.LoadAllViewsAction; -import com.android.hierarchyviewer.actions.LoadOverlayAction; -import com.android.hierarchyviewer.actions.LoadViewHierarchyAction; -import com.android.hierarchyviewer.actions.PixelPerfectAutoRefreshAction; import com.android.hierarchyviewer.actions.QuitAction; -import com.android.hierarchyviewer.actions.RefreshPixelPerfectAction; -import com.android.hierarchyviewer.actions.RefreshPixelPerfectTreeAction; -import com.android.hierarchyviewer.actions.RefreshViewAction; -import com.android.hierarchyviewer.actions.RefreshWindowsAction; -import com.android.hierarchyviewer.actions.RequestLayoutAction; -import com.android.hierarchyviewer.actions.SavePixelPerfectAction; -import com.android.hierarchyviewer.actions.SaveTreeViewAction; import com.android.hierarchyviewer.actions.ShowOverlayAction; import com.android.hierarchyviewer.util.ActionButton; import com.android.hierarchyviewerlib.HierarchyViewerDirector; -import com.android.hierarchyviewerlib.device.Window; -import com.android.hierarchyviewerlib.models.DeviceSelectionModel; +import com.android.hierarchyviewerlib.actions.CapturePSDAction; +import com.android.hierarchyviewerlib.actions.DisplayViewAction; +import com.android.hierarchyviewerlib.actions.InspectScreenshotAction; +import com.android.hierarchyviewerlib.actions.InvalidateAction; +import com.android.hierarchyviewerlib.actions.LoadOverlayAction; +import com.android.hierarchyviewerlib.actions.LoadViewHierarchyAction; +import com.android.hierarchyviewerlib.actions.PixelPerfectAutoRefreshAction; +import com.android.hierarchyviewerlib.actions.RefreshPixelPerfectAction; +import com.android.hierarchyviewerlib.actions.RefreshPixelPerfectTreeAction; +import com.android.hierarchyviewerlib.actions.RefreshViewAction; +import com.android.hierarchyviewerlib.actions.RefreshWindowsAction; +import com.android.hierarchyviewerlib.actions.RequestLayoutAction; +import com.android.hierarchyviewerlib.actions.SavePixelPerfectAction; +import com.android.hierarchyviewerlib.actions.SaveTreeViewAction; import com.android.hierarchyviewerlib.models.PixelPerfectModel; import com.android.hierarchyviewerlib.models.TreeViewModel; -import com.android.hierarchyviewerlib.models.DeviceSelectionModel.WindowChangeListener; import com.android.hierarchyviewerlib.models.PixelPerfectModel.ImageChangeListener; import com.android.hierarchyviewerlib.models.TreeViewModel.TreeChangeListener; import com.android.hierarchyviewerlib.ui.DeviceSelector; import com.android.hierarchyviewerlib.ui.LayoutViewer; import com.android.hierarchyviewerlib.ui.PixelPerfect; +import com.android.hierarchyviewerlib.ui.PixelPerfectControls; import com.android.hierarchyviewerlib.ui.PixelPerfectLoupe; import com.android.hierarchyviewerlib.ui.PixelPerfectPixelPanel; import com.android.hierarchyviewerlib.ui.PixelPerfectTree; import com.android.hierarchyviewerlib.ui.PropertyViewer; import com.android.hierarchyviewerlib.ui.TreeView; +import com.android.hierarchyviewerlib.ui.TreeViewControls; import com.android.hierarchyviewerlib.ui.TreeViewOverview; import org.eclipse.jface.action.MenuManager; @@ -61,8 +59,6 @@ import org.eclipse.jface.window.ApplicationWindow; import org.eclipse.swt.SWT; import org.eclipse.swt.custom.SashForm; import org.eclipse.swt.custom.StackLayout; -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.graphics.Image; @@ -81,8 +77,6 @@ import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.ProgressBar; import org.eclipse.swt.widgets.Shell; -import org.eclipse.swt.widgets.Slider; -import org.eclipse.swt.widgets.Text; public class HierarchyViewerApplication extends ApplicationWindow { @@ -114,7 +108,6 @@ public class HierarchyViewerApplication extends ApplicationWindow { private Button deviceViewButton; - private Label progressLabel; private ProgressBar progressBar; @@ -147,29 +140,9 @@ public class HierarchyViewerApplication extends ApplicationWindow { private LayoutViewer layoutViewer; - private StackLayout statusBarStackLayout; - - private Composite treeViewControls; - - private Slider zoomSlider; - - private Text filterText; - - private Composite statusBarControlPanel; - private PixelPerfectLoupe pixelPerfectLoupe; - private boolean autoRefresh = false; - - private int refreshInterval = 5; - - private int refreshTimeLeft = 5; - - private Slider overlaySlider; - - private Slider ppZoomSlider; - - private Slider refreshSlider; + private Composite treeViewControls; public static final HierarchyViewerApplication getApp() { return APP; @@ -202,20 +175,13 @@ public class HierarchyViewerApplication extends ApplicationWindow { director.initDebugBridge(); director.startListenForDevices(); director.populateDeviceSelectionModel(); - DeviceSelectionModel.getModel().addWindowChangeListener(windowChangeListener); TreeViewModel.getModel().addTreeChangeListener(treeChangeListener); PixelPerfectModel.getModel().addImageChangeListener(imageChangeListener); setBlockOnOpen(true); - Thread pixelPerfectRefreshingThread = new Thread(autoRefresher); - pixelPerfectRefreshingThread.start(); - open(); - pixelPerfectRefreshingThread.interrupt(); - - DeviceSelectionModel.getModel().removeWindowChangeListener(windowChangeListener); TreeViewModel.getModel().removeTreeChangeListener(treeChangeListener); PixelPerfectModel.getModel().removeImageChangeListener(imageChangeListener); @@ -312,51 +278,12 @@ public class HierarchyViewerApplication extends ApplicationWindow { pixelPerfectButton.setLayoutData(pixelPerfectButtonFormData); // Tree View control panel... - statusBarControlPanel = new Composite(statusBar, SWT.NONE); - FormData statusBarControlPanelFormData = new FormData(); - statusBarControlPanelFormData.left = new FormAttachment(pixelPerfectButton, 2); - statusBarControlPanelFormData.top = new FormAttachment(treeViewButton, 0, SWT.CENTER); - statusBarControlPanel.setLayoutData(statusBarControlPanelFormData); - - statusBarStackLayout = new StackLayout(); - statusBarControlPanel.setLayout(statusBarStackLayout); - - treeViewControls = new Composite(statusBarControlPanel, SWT.NONE); - GridLayout treeViewControlLayout = new GridLayout(5, false); - treeViewControlLayout.marginWidth = treeViewControlLayout.marginHeight = 2; - treeViewControlLayout.verticalSpacing = treeViewControlLayout.horizontalSpacing = 4; - treeViewControls.setLayout(treeViewControlLayout); - - Label filterLabel = new Label(treeViewControls, SWT.NONE); - filterLabel.setText("Filter by class or id:"); - filterLabel.setLayoutData(new GridData(GridData.BEGINNING, GridData.CENTER, false, true)); - - filterText = new Text(treeViewControls, SWT.LEFT | SWT.SINGLE); - GridData filterTextGridData = new GridData(GridData.FILL_HORIZONTAL); - filterTextGridData.widthHint = 148; - filterText.setLayoutData(filterTextGridData); - filterText.addModifyListener(filterTextModifyListener); - - Label smallZoomLabel = new Label(treeViewControls, SWT.NONE); - smallZoomLabel.setText(" 20%"); - smallZoomLabel - .setLayoutData(new GridData(GridData.BEGINNING, GridData.CENTER, false, true)); - - zoomSlider = new Slider(treeViewControls, 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(10); - - zoomSlider.addSelectionListener(zoomSliderSelectionListener); - - Label largeZoomLabel = new Label(treeViewControls, SWT.NONE); - largeZoomLabel - .setLayoutData(new GridData(GridData.BEGINNING, GridData.CENTER, false, true)); - largeZoomLabel.setText("200%"); + treeViewControls = new TreeViewControls(statusBar); + FormData treeViewControlsFormData = new FormData(); + treeViewControlsFormData.left = new FormAttachment(pixelPerfectButton, 2); + treeViewControlsFormData.top = new FormAttachment(treeViewButton, 0, SWT.CENTER); + treeViewControlsFormData.width = 552; + treeViewControls.setLayoutData(treeViewControlsFormData); // Progress stuff progressLabel = new Label(statusBar, SWT.RIGHT); @@ -409,17 +336,15 @@ public class HierarchyViewerApplication extends ApplicationWindow { ActionButton loadViewHierarchyButton = new ActionButton(innerButtonPanel, LoadViewHierarchyAction.getAction()); loadViewHierarchyButton.setLayoutData(new GridData(GridData.FILL_BOTH)); - LoadViewHierarchyAction.getAction().setEnabled(false); ActionButton inspectScreenshotButton = new ActionButton(innerButtonPanel, InspectScreenshotAction.getAction()); inspectScreenshotButton.setLayoutData(new GridData(GridData.FILL_BOTH)); - InspectScreenshotAction.getAction().setEnabled(false); Composite deviceSelectorContainer = new Composite(deviceSelectorPanel, SWT.BORDER); deviceSelectorContainer.setLayoutData(new GridData(GridData.FILL_BOTH)); deviceSelectorContainer.setLayout(new FillLayout()); - deviceSelector = new DeviceSelector(deviceSelectorContainer); + deviceSelector = new DeviceSelector(deviceSelectorContainer, true, true); } public void buildTreeViewPanel(Composite parent) { @@ -482,11 +407,11 @@ public class HierarchyViewerApplication extends ApplicationWindow { Composite treeViewOverviewContainer = new Composite(sideSash, SWT.BORDER); treeViewOverviewContainer.setLayout(new FillLayout()); - TreeViewOverview treeViewOverview = new TreeViewOverview(treeViewOverviewContainer); + new TreeViewOverview(treeViewOverviewContainer); Composite propertyViewerContainer = new Composite(sideSash, SWT.BORDER); propertyViewerContainer.setLayout(new FillLayout()); - PropertyViewer propertyViewer = new PropertyViewer(propertyViewerContainer); + new PropertyViewer(propertyViewerContainer); Composite layoutViewerContainer = new Composite(sideSash, SWT.NONE); GridLayout layoutViewerLayout = new GridLayout(); @@ -514,10 +439,12 @@ public class HierarchyViewerApplication extends ApplicationWindow { onBlackWhiteButton = new Button(buttonBar, SWT.PUSH); onBlackWhiteButton.setImage(onWhiteImage); onBlackWhiteButton.addSelectionListener(onBlackWhiteSelectionListener); + onBlackWhiteButton.setToolTipText("Change layout viewer background color"); showExtras = new Button(buttonBar, SWT.CHECK); showExtras.setText("Show Extras"); showExtras.addSelectionListener(showExtrasSelectionListener); + showExtras.setToolTipText("Show images"); ActionButton loadAllViewsButton = new ActionButton(fullButtonBar, LoadAllViewsAction.getAction()); @@ -578,8 +505,6 @@ public class HierarchyViewerApplication extends ApplicationWindow { new ActionButton(innerButtonPanel, ShowOverlayAction.getAction()); showInLoupe.setLayoutData(new GridData(GridData.FILL_BOTH)); - ShowOverlayAction.getAction().setEnabled(false); - ActionButton autoRefresh = new ActionButton(innerButtonPanel, PixelPerfectAutoRefreshAction.getAction()); autoRefresh.setLayoutData(new GridData(GridData.FILL_BOTH)); @@ -590,7 +515,7 @@ public class HierarchyViewerApplication extends ApplicationWindow { Composite pixelPerfectTreeContainer = new Composite(mainSash, SWT.BORDER); pixelPerfectTreeContainer.setLayout(new FillLayout()); - PixelPerfectTree pixelPerfectTree = new PixelPerfectTree(pixelPerfectTreeContainer); + new PixelPerfectTree(pixelPerfectTreeContainer); Composite pixelPerfectLoupeContainer = new Composite(mainSash, SWT.NONE); GridLayout loupeLayout = new GridLayout(); @@ -614,121 +539,14 @@ public class HierarchyViewerApplication extends ApplicationWindow { new PixelPerfectPixelPanel(pixelPerfectLoupeBorder); pixelPerfectPixelPanel.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); - Composite pixelPerfectControls = new Composite(pixelPerfectLoupeContainer, SWT.NONE); + PixelPerfectControls pixelPerfectControls = + new PixelPerfectControls(pixelPerfectLoupeContainer); pixelPerfectControls.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); - pixelPerfectControls.setLayout(new FormLayout()); - - Label overlayTransparencyRight = new Label(pixelPerfectControls, 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(pixelPerfectControls, 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(pixelPerfectControls, 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(pixelPerfectControls, SWT.NONE); - Label refresh = new Label(pixelPerfectControls, 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(pixelPerfectControls, 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(pixelPerfectControls, 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(pixelPerfectControls, 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(pixelPerfectControls, 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(pixelPerfectControls, SWT.HORIZONTAL); - overlaySlider.setMinimum(0); - overlaySlider.setMaximum(101); - overlaySlider.setThumb(1); - overlaySlider.setSelection(50); - overlaySlider.setEnabled(false); - 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); - - refreshSlider = new Slider(pixelPerfectControls, SWT.HORIZONTAL); - refreshSlider.setMinimum(1); - refreshSlider.setMaximum(41); - refreshSlider.setThumb(1); - refreshSlider.setSelection(refreshInterval); - FormData refreshSliderData = new FormData(); - refreshSliderData.right = new FormAttachment(overlayTransparencyRight, -4); - refreshSliderData.top = new FormAttachment(overlayTransparencyRight, 2); - refreshSliderData.left = new FormAttachment(overlaySlider, 0, SWT.LEFT); - refreshSlider.setLayoutData(refreshSliderData); - - refreshSlider.addSelectionListener(refreshSliderSelectionListener); - - ppZoomSlider = new Slider(pixelPerfectControls, SWT.HORIZONTAL); - ppZoomSlider.setMinimum(2); - ppZoomSlider.setMaximum(25); - ppZoomSlider.setThumb(1); - ppZoomSlider.setSelection(PixelPerfectModel.DEFAULT_ZOOM); - FormData zoomSliderData = new FormData(); - zoomSliderData.right = new FormAttachment(overlayTransparencyRight, -4); - zoomSliderData.top = new FormAttachment(refreshRight, 2); - zoomSliderData.left = new FormAttachment(overlaySlider, 0, SWT.LEFT); - ppZoomSlider.setLayoutData(zoomSliderData); - - ppZoomSlider.addSelectionListener(ppZoomSliderSelectionListener); + Composite pixelPerfectContainer = new Composite(mainSash, SWT.BORDER); pixelPerfectContainer.setLayout(new FillLayout()); - PixelPerfect pixelPerfect = new PixelPerfect(pixelPerfectContainer); + new PixelPerfect(pixelPerfectContainer); mainSash.setWeights(new int[] { 272, 376, 346 @@ -736,15 +554,6 @@ public class HierarchyViewerApplication extends ApplicationWindow { } - public void setAutoRefresh(boolean value) { - if (value) { - refreshTimeLeft = refreshInterval; - autoRefresh = true; - } else { - autoRefresh = false; - } - } - public void showOverlayInLoupe(boolean value) { pixelPerfectLoupe.setShowOverlay(value); } @@ -816,9 +625,7 @@ public class HierarchyViewerApplication extends ApplicationWindow { deviceSelector.setFocus(); - statusBarStackLayout.topControl = null; - statusBarControlPanel.setVisible(false); - statusBarControlPanel.layout(); + treeViewControls.setVisible(false); } public void showTreeView() { @@ -865,9 +672,7 @@ public class HierarchyViewerApplication extends ApplicationWindow { treeView.setFocus(); - statusBarStackLayout.topControl = treeViewControls; - statusBarControlPanel.setVisible(true); - statusBarControlPanel.layout(); + treeViewControls.setVisible(true); } public void showPixelPerfect() { @@ -913,9 +718,7 @@ public class HierarchyViewerApplication extends ApplicationWindow { pixelPerfectLoupe.setFocus(); - statusBarStackLayout.topControl = null; - statusBarControlPanel.setVisible(false); - statusBarControlPanel.layout(); + treeViewControls.setVisible(false); } private SelectionListener deviceViewButtonSelectionListener = new SelectionListener() { @@ -988,135 +791,6 @@ public class HierarchyViewerApplication extends ApplicationWindow { } }; - 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(treeChangeListener); - TreeViewModel.getModel().setZoom(newValue / 10.0); - TreeViewModel.getModel().addTreeChangeListener(treeChangeListener); - oldValue = newValue; - } - } - }; - - private Runnable autoRefresher = new Runnable() { - public void run() { - while (!Thread.currentThread().isInterrupted()) { - try { - Thread.sleep(1000); - } catch (InterruptedException e) { - break; - } - refreshTimeLeft--; - if (autoRefresh && refreshTimeLeft <= 0) { - HierarchyViewerDirector.getDirector().refreshPixelPerfect(); - refreshTimeLeft = refreshInterval; - } - } - } - }; - - 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(imageChangeListener); - PixelPerfectModel.getModel().setOverlayTransparency(newValue / 100.0); - PixelPerfectModel.getModel().addImageChangeListener(imageChangeListener); - oldValue = newValue; - } - } - }; - - private SelectionListener refreshSliderSelectionListener = new SelectionListener() { - private int oldValue; - - public void widgetDefaultSelected(SelectionEvent e) { - // pass - } - - public void widgetSelected(SelectionEvent e) { - int newValue = refreshSlider.getSelection(); - if (oldValue != newValue) { - refreshInterval = newValue; - refreshTimeLeft = Math.min(refreshTimeLeft, refreshInterval); - oldValue = newValue; - } - } - }; - - private SelectionListener ppZoomSliderSelectionListener = new SelectionListener() { - private int oldValue; - - public void widgetDefaultSelected(SelectionEvent e) { - // pass - } - - public void widgetSelected(SelectionEvent e) { - int newValue = ppZoomSlider.getSelection(); - if (oldValue != newValue) { - PixelPerfectModel.getModel().removeImageChangeListener(imageChangeListener); - PixelPerfectModel.getModel().setZoom(newValue); - PixelPerfectModel.getModel().addImageChangeListener(imageChangeListener); - oldValue = newValue; - } - } - }; - - private ModifyListener filterTextModifyListener = new ModifyListener() { - public void modifyText(ModifyEvent e) { - HierarchyViewerDirector.getDirector().filterNodes(filterText.getText()); - } - }; - - private WindowChangeListener windowChangeListener = new WindowChangeListener() { - 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() { - if (window == null) { - LoadViewHierarchyAction.getAction().setEnabled(false); - } else { - LoadViewHierarchyAction.getAction().setEnabled(true); - } - if (device == null) { - InspectScreenshotAction.getAction().setEnabled(false); - } else { - InspectScreenshotAction.getAction().setEnabled(true); - } - } - }); - } - }; - private TreeChangeListener treeChangeListener = new TreeChangeListener() { public void selectionChanged() { // pass @@ -1131,9 +805,6 @@ public class HierarchyViewerApplication extends ApplicationWindow { } else { showTreeView(); treeViewButton.setEnabled(true); - zoomSlider.setSelection((int) Math - .round(TreeViewModel.getModel().getZoom() * 10)); - filterText.setText(""); } } }); @@ -1145,7 +816,6 @@ public class HierarchyViewerApplication extends ApplicationWindow { public void zoomChanged() { // pass - zoomSlider.setSelection((int) Math.round(TreeViewModel.getModel().getZoom() * 10)); } }; @@ -1166,14 +836,10 @@ public class HierarchyViewerApplication extends ApplicationWindow { public void imageLoaded() { Display.getDefault().syncExec(new Runnable() { public void run() { - Image overlayImage = PixelPerfectModel.getModel().getOverlayImage(); - ShowOverlayAction.getAction().setEnabled(overlayImage != null); - overlaySlider.setEnabled(overlayImage != null); if (PixelPerfectModel.getModel().getImage() == null) { pixelPerfectButton.setEnabled(false); showDeviceSelector(); } else { - ppZoomSlider.setSelection(PixelPerfectModel.getModel().getZoom()); pixelPerfectButton.setEnabled(true); showPixelPerfect(); } @@ -1182,22 +848,11 @@ public class HierarchyViewerApplication extends ApplicationWindow { } public void overlayChanged() { - Display.getDefault().syncExec(new Runnable() { - public void run() { - Image overlayImage = PixelPerfectModel.getModel().getOverlayImage(); - ShowOverlayAction.getAction().setEnabled(overlayImage != null); - overlaySlider.setEnabled(overlayImage != null); - } - }); + // pass } public void overlayTransparencyChanged() { - Display.getDefault().syncExec(new Runnable() { - public void run() { - overlaySlider.setSelection((int) (PixelPerfectModel.getModel() - .getOverlayTransparency() * 100)); - } - }); + // pass } public void selectionChanged() { @@ -1205,11 +860,7 @@ public class HierarchyViewerApplication extends ApplicationWindow { } public void zoomChanged() { - Display.getDefault().syncExec(new Runnable() { - public void run() { - ppZoomSlider.setSelection(PixelPerfectModel.getModel().getZoom()); - } - }); + // pass } }; diff --git a/hierarchyviewer2/app/src/com/android/hierarchyviewer/actions/AboutAction.java b/hierarchyviewer2/app/src/com/android/hierarchyviewer/actions/AboutAction.java index 9c76ae9..c6abe57 100644 --- a/hierarchyviewer2/app/src/com/android/hierarchyviewer/actions/AboutAction.java +++ b/hierarchyviewer2/app/src/com/android/hierarchyviewer/actions/AboutAction.java @@ -19,6 +19,7 @@ package com.android.hierarchyviewer.actions; import com.android.ddmuilib.ImageLoader; import com.android.hierarchyviewer.AboutDialog; import com.android.hierarchyviewerlib.HierarchyViewerDirector; +import com.android.hierarchyviewerlib.actions.ImageAction; import org.eclipse.jface.action.Action; import org.eclipse.jface.resource.ImageDescriptor; diff --git a/hierarchyviewer2/app/src/com/android/hierarchyviewer/actions/LoadAllViewsAction.java b/hierarchyviewer2/app/src/com/android/hierarchyviewer/actions/LoadAllViewsAction.java index 2ea2298..5007e1e 100644 --- a/hierarchyviewer2/app/src/com/android/hierarchyviewer/actions/LoadAllViewsAction.java +++ b/hierarchyviewer2/app/src/com/android/hierarchyviewer/actions/LoadAllViewsAction.java @@ -18,14 +18,15 @@ package com.android.hierarchyviewer.actions; import com.android.ddmuilib.ImageLoader; import com.android.hierarchyviewerlib.HierarchyViewerDirector; +import com.android.hierarchyviewerlib.actions.ImageAction; +import com.android.hierarchyviewerlib.actions.TreeViewEnabledAction; -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 LoadAllViewsAction extends Action implements ImageAction { +public class LoadAllViewsAction extends TreeViewEnabledAction implements ImageAction { private static LoadAllViewsAction action; diff --git a/hierarchyviewer2/app/src/com/android/hierarchyviewer/actions/ShowOverlayAction.java b/hierarchyviewer2/app/src/com/android/hierarchyviewer/actions/ShowOverlayAction.java index b0f51ec..e4695cd 100644 --- a/hierarchyviewer2/app/src/com/android/hierarchyviewer/actions/ShowOverlayAction.java +++ b/hierarchyviewer2/app/src/com/android/hierarchyviewer/actions/ShowOverlayAction.java @@ -19,6 +19,9 @@ package com.android.hierarchyviewer.actions; import com.android.ddmuilib.ImageLoader; import com.android.hierarchyviewer.HierarchyViewerApplication; import com.android.hierarchyviewerlib.HierarchyViewerDirector; +import com.android.hierarchyviewerlib.actions.ImageAction; +import com.android.hierarchyviewerlib.models.PixelPerfectModel; +import com.android.hierarchyviewerlib.models.PixelPerfectModel.ImageChangeListener; import org.eclipse.jface.action.Action; import org.eclipse.jface.resource.ImageDescriptor; @@ -26,7 +29,7 @@ import org.eclipse.swt.SWT; import org.eclipse.swt.graphics.Image; import org.eclipse.swt.widgets.Display; -public class ShowOverlayAction extends Action implements ImageAction { +public class ShowOverlayAction extends Action implements ImageAction, ImageChangeListener { private static ShowOverlayAction action; @@ -39,6 +42,8 @@ public class ShowOverlayAction extends Action implements ImageAction { image = imageLoader.loadImage("show-overlay.png", Display.getDefault()); setImageDescriptor(ImageDescriptor.createFromImage(image)); setToolTipText("Show the overlay in the loupe view"); + setEnabled(PixelPerfectModel.getModel().getOverlayImage() != null); + PixelPerfectModel.getModel().addImageChangeListener(this); } public static ShowOverlayAction getAction() { @@ -56,4 +61,45 @@ public class ShowOverlayAction extends Action implements ImageAction { public Image getImage() { return image; } + + 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(); + setEnabled(overlayImage != null); + } + }); + } + + public void overlayChanged() { + Display.getDefault().syncExec(new Runnable() { + public void run() { + setEnabled(PixelPerfectModel.getModel().getOverlayImage() != null); + } + }); + } + + public void overlayTransparencyChanged() { + // pass + } + + public void selectionChanged() { + // pass + } + + public void zoomChanged() { + // pass + } } diff --git a/hierarchyviewer2/app/src/com/android/hierarchyviewer/util/ActionButton.java b/hierarchyviewer2/app/src/com/android/hierarchyviewer/util/ActionButton.java index 08fe1ac..cf8d5e2 100644 --- a/hierarchyviewer2/app/src/com/android/hierarchyviewer/util/ActionButton.java +++ b/hierarchyviewer2/app/src/com/android/hierarchyviewer/util/ActionButton.java @@ -16,7 +16,7 @@ package com.android.hierarchyviewer.util; -import com.android.hierarchyviewer.actions.ImageAction; +import com.android.hierarchyviewerlib.actions.ImageAction; import org.eclipse.jface.action.Action; import org.eclipse.jface.util.IPropertyChangeListener; @@ -44,6 +44,7 @@ public class ActionButton implements IPropertyChangeListener, SelectionListener this.action.addPropertyChangeListener(this); button.addSelectionListener(this); button.setToolTipText(action.getToolTipText()); + button.setEnabled(this.action.isEnabled()); } public void propertyChange(PropertyChangeEvent e) { 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/app/src/com/android/hierarchyviewer/actions/CapturePSDAction.java b/hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/actions/CapturePSDAction.java index 6ae0d17..240ced1 100644 --- a/hierarchyviewer2/app/src/com/android/hierarchyviewer/actions/CapturePSDAction.java +++ b/hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/actions/CapturePSDAction.java @@ -14,19 +14,18 @@ * limitations under the License. */ -package com.android.hierarchyviewer.actions; +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; import org.eclipse.swt.widgets.Shell; -public class CapturePSDAction extends Action implements ImageAction { +public class CapturePSDAction extends TreeViewEnabledAction implements ImageAction { private static CapturePSDAction action; diff --git a/hierarchyviewer2/app/src/com/android/hierarchyviewer/actions/DisplayViewAction.java b/hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/actions/DisplayViewAction.java index a622eb2..4fc8024 100644 --- a/hierarchyviewer2/app/src/com/android/hierarchyviewer/actions/DisplayViewAction.java +++ b/hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/actions/DisplayViewAction.java @@ -14,19 +14,18 @@ * limitations under the License. */ -package com.android.hierarchyviewer.actions; +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; import org.eclipse.swt.widgets.Shell; -public class DisplayViewAction extends Action implements ImageAction { +public class DisplayViewAction extends SelectedNodeEnabledAction implements ImageAction { private static DisplayViewAction action; diff --git a/hierarchyviewer2/app/src/com/android/hierarchyviewer/actions/ImageAction.java b/hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/actions/ImageAction.java index 11c98a4..08320fd 100644 --- a/hierarchyviewer2/app/src/com/android/hierarchyviewer/actions/ImageAction.java +++ b/hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/actions/ImageAction.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.hierarchyviewer.actions; +package com.android.hierarchyviewerlib.actions; import org.eclipse.swt.graphics.Image; diff --git a/hierarchyviewer2/app/src/com/android/hierarchyviewer/actions/InspectScreenshotAction.java b/hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/actions/InspectScreenshotAction.java index 5109ca5..7ef7109 100644 --- a/hierarchyviewer2/app/src/com/android/hierarchyviewer/actions/InspectScreenshotAction.java +++ b/hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/actions/InspectScreenshotAction.java @@ -14,10 +14,14 @@ * limitations under the License. */ -package com.android.hierarchyviewer.actions; +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; @@ -25,7 +29,7 @@ import org.eclipse.swt.SWT; import org.eclipse.swt.graphics.Image; import org.eclipse.swt.widgets.Display; -public class InspectScreenshotAction extends Action implements ImageAction { +public class InspectScreenshotAction extends Action implements ImageAction, WindowChangeListener { private static InspectScreenshotAction action; @@ -38,6 +42,9 @@ public class InspectScreenshotAction extends Action implements ImageAction { 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() { @@ -55,4 +62,28 @@ public class InspectScreenshotAction extends Action implements ImageAction { 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/app/src/com/android/hierarchyviewer/actions/InvalidateAction.java b/hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/actions/InvalidateAction.java index 831a56d..aaf0ff0 100644 --- a/hierarchyviewer2/app/src/com/android/hierarchyviewer/actions/InvalidateAction.java +++ b/hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/actions/InvalidateAction.java @@ -14,18 +14,17 @@ * limitations under the License. */ -package com.android.hierarchyviewer.actions; +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 InvalidateAction extends Action implements ImageAction { +public class InvalidateAction extends SelectedNodeEnabledAction implements ImageAction { private static InvalidateAction action; diff --git a/hierarchyviewer2/app/src/com/android/hierarchyviewer/actions/LoadOverlayAction.java b/hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/actions/LoadOverlayAction.java index 588b995..c948914 100644 --- a/hierarchyviewer2/app/src/com/android/hierarchyviewer/actions/LoadOverlayAction.java +++ b/hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/actions/LoadOverlayAction.java @@ -14,19 +14,18 @@ * limitations under the License. */ -package com.android.hierarchyviewer.actions; +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; import org.eclipse.swt.widgets.Shell; -public class LoadOverlayAction extends Action implements ImageAction { +public class LoadOverlayAction extends PixelPerfectEnabledAction implements ImageAction { private static LoadOverlayAction action; diff --git a/hierarchyviewer2/app/src/com/android/hierarchyviewer/actions/LoadViewHierarchyAction.java b/hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/actions/LoadViewHierarchyAction.java index 79fd0b3..d26b2ef 100644 --- a/hierarchyviewer2/app/src/com/android/hierarchyviewer/actions/LoadViewHierarchyAction.java +++ b/hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/actions/LoadViewHierarchyAction.java @@ -14,10 +14,14 @@ * limitations under the License. */ -package com.android.hierarchyviewer.actions; +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; @@ -25,7 +29,7 @@ import org.eclipse.swt.SWT; import org.eclipse.swt.graphics.Image; import org.eclipse.swt.widgets.Display; -public class LoadViewHierarchyAction extends Action implements ImageAction { +public class LoadViewHierarchyAction extends Action implements ImageAction, WindowChangeListener { private static LoadViewHierarchyAction action; @@ -38,6 +42,9 @@ public class LoadViewHierarchyAction extends Action implements ImageAction { 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() { @@ -55,4 +62,28 @@ public class LoadViewHierarchyAction extends Action implements ImageAction { 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/app/src/com/android/hierarchyviewer/actions/PixelPerfectAutoRefreshAction.java b/hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/actions/PixelPerfectAutoRefreshAction.java index 325eb86..5e31829 100644 --- a/hierarchyviewer2/app/src/com/android/hierarchyviewer/actions/PixelPerfectAutoRefreshAction.java +++ b/hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/actions/PixelPerfectAutoRefreshAction.java @@ -14,10 +14,9 @@ * limitations under the License. */ -package com.android.hierarchyviewer.actions; +package com.android.hierarchyviewerlib.actions; import com.android.ddmuilib.ImageLoader; -import com.android.hierarchyviewer.HierarchyViewerApplication; import com.android.hierarchyviewerlib.HierarchyViewerDirector; import org.eclipse.jface.action.Action; @@ -26,7 +25,7 @@ import org.eclipse.swt.SWT; import org.eclipse.swt.graphics.Image; import org.eclipse.swt.widgets.Display; -public class PixelPerfectAutoRefreshAction extends Action implements ImageAction { +public class PixelPerfectAutoRefreshAction extends PixelPerfectEnabledAction implements ImageAction { private static PixelPerfectAutoRefreshAction action; @@ -50,7 +49,7 @@ public class PixelPerfectAutoRefreshAction extends Action implements ImageAction @Override public void run() { - HierarchyViewerApplication.getApp().setAutoRefresh(action.isChecked()); + HierarchyViewerDirector.getDirector().setPixelPerfectAutoRefresh(action.isChecked()); } public Image getImage() { 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/app/src/com/android/hierarchyviewer/actions/RefreshPixelPerfectAction.java b/hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/actions/RefreshPixelPerfectAction.java index 5d68c37..a5d7514 100644 --- a/hierarchyviewer2/app/src/com/android/hierarchyviewer/actions/RefreshPixelPerfectAction.java +++ b/hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/actions/RefreshPixelPerfectAction.java @@ -14,18 +14,17 @@ * limitations under the License. */ -package com.android.hierarchyviewer.actions; +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 RefreshPixelPerfectAction extends Action implements ImageAction { +public class RefreshPixelPerfectAction extends PixelPerfectEnabledAction implements ImageAction { private static RefreshPixelPerfectAction action; diff --git a/hierarchyviewer2/app/src/com/android/hierarchyviewer/actions/RefreshPixelPerfectTreeAction.java b/hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/actions/RefreshPixelPerfectTreeAction.java index 74c577d..41214df 100644 --- a/hierarchyviewer2/app/src/com/android/hierarchyviewer/actions/RefreshPixelPerfectTreeAction.java +++ b/hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/actions/RefreshPixelPerfectTreeAction.java @@ -14,18 +14,17 @@ * limitations under the License. */ -package com.android.hierarchyviewer.actions; +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 RefreshPixelPerfectTreeAction extends Action implements ImageAction { +public class RefreshPixelPerfectTreeAction extends PixelPerfectEnabledAction implements ImageAction { private static RefreshPixelPerfectTreeAction action; diff --git a/hierarchyviewer2/app/src/com/android/hierarchyviewer/actions/RefreshViewAction.java b/hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/actions/RefreshViewAction.java index 36704a7..06c48ee 100644 --- a/hierarchyviewer2/app/src/com/android/hierarchyviewer/actions/RefreshViewAction.java +++ b/hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/actions/RefreshViewAction.java @@ -14,18 +14,17 @@ * limitations under the License. */ -package com.android.hierarchyviewer.actions; +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 RefreshViewAction extends Action implements ImageAction { +public class RefreshViewAction extends TreeViewEnabledAction implements ImageAction { private static RefreshViewAction action; diff --git a/hierarchyviewer2/app/src/com/android/hierarchyviewer/actions/RefreshWindowsAction.java b/hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/actions/RefreshWindowsAction.java index 63808ee..47d692a 100644 --- a/hierarchyviewer2/app/src/com/android/hierarchyviewer/actions/RefreshWindowsAction.java +++ b/hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/actions/RefreshWindowsAction.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.hierarchyviewer.actions; +package com.android.hierarchyviewerlib.actions; import com.android.ddmuilib.ImageLoader; import com.android.hierarchyviewerlib.HierarchyViewerDirector; diff --git a/hierarchyviewer2/app/src/com/android/hierarchyviewer/actions/RequestLayoutAction.java b/hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/actions/RequestLayoutAction.java index 9255432..e3d6f8f 100644 --- a/hierarchyviewer2/app/src/com/android/hierarchyviewer/actions/RequestLayoutAction.java +++ b/hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/actions/RequestLayoutAction.java @@ -14,18 +14,17 @@ * limitations under the License. */ -package com.android.hierarchyviewer.actions; +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 RequestLayoutAction extends Action implements ImageAction { +public class RequestLayoutAction extends SelectedNodeEnabledAction implements ImageAction { private static RequestLayoutAction action; diff --git a/hierarchyviewer2/app/src/com/android/hierarchyviewer/actions/SavePixelPerfectAction.java b/hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/actions/SavePixelPerfectAction.java index 2221ad8..9781d42 100644 --- a/hierarchyviewer2/app/src/com/android/hierarchyviewer/actions/SavePixelPerfectAction.java +++ b/hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/actions/SavePixelPerfectAction.java @@ -14,19 +14,18 @@ * limitations under the License. */ -package com.android.hierarchyviewer.actions; +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; import org.eclipse.swt.widgets.Shell; -public class SavePixelPerfectAction extends Action implements ImageAction { +public class SavePixelPerfectAction extends PixelPerfectEnabledAction implements ImageAction { private static SavePixelPerfectAction action; diff --git a/hierarchyviewer2/app/src/com/android/hierarchyviewer/actions/SaveTreeViewAction.java b/hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/actions/SaveTreeViewAction.java index c203ace..094b101 100644 --- a/hierarchyviewer2/app/src/com/android/hierarchyviewer/actions/SaveTreeViewAction.java +++ b/hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib/actions/SaveTreeViewAction.java @@ -14,19 +14,18 @@ * limitations under the License. */ -package com.android.hierarchyviewer.actions; +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; import org.eclipse.swt.widgets.Shell; -public class SaveTreeViewAction extends Action implements ImageAction { +public class SaveTreeViewAction extends TreeViewEnabledAction implements ImageAction { private static SaveTreeViewAction action; 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 |