aboutsummaryrefslogtreecommitdiffstats
path: root/hierarchyviewer2/app/src/com/android/hierarchyviewer
diff options
context:
space:
mode:
Diffstat (limited to 'hierarchyviewer2/app/src/com/android/hierarchyviewer')
-rw-r--r--hierarchyviewer2/app/src/com/android/hierarchyviewer/AboutDialog.java72
-rw-r--r--hierarchyviewer2/app/src/com/android/hierarchyviewer/HierarchyViewerApplication.java1192
-rw-r--r--hierarchyviewer2/app/src/com/android/hierarchyviewer/HierarchyViewerApplicationDirector.java13
-rw-r--r--hierarchyviewer2/app/src/com/android/hierarchyviewer/UIThread.java66
-rw-r--r--hierarchyviewer2/app/src/com/android/hierarchyviewer/actions/AboutAction.java63
-rw-r--r--hierarchyviewer2/app/src/com/android/hierarchyviewer/actions/CapturePSDAction.java62
-rw-r--r--hierarchyviewer2/app/src/com/android/hierarchyviewer/actions/DisplayViewAction.java62
-rw-r--r--hierarchyviewer2/app/src/com/android/hierarchyviewer/actions/ImageAction.java27
-rw-r--r--hierarchyviewer2/app/src/com/android/hierarchyviewer/actions/InspectScreenshotAction.java58
-rw-r--r--hierarchyviewer2/app/src/com/android/hierarchyviewer/actions/InvalidateAction.java58
-rw-r--r--hierarchyviewer2/app/src/com/android/hierarchyviewer/actions/LoadAllViewsAction.java58
-rw-r--r--hierarchyviewer2/app/src/com/android/hierarchyviewer/actions/LoadOverlayAction.java62
-rw-r--r--hierarchyviewer2/app/src/com/android/hierarchyviewer/actions/LoadViewHierarchyAction.java58
-rw-r--r--hierarchyviewer2/app/src/com/android/hierarchyviewer/actions/PixelPerfectAutoRefreshAction.java59
-rw-r--r--hierarchyviewer2/app/src/com/android/hierarchyviewer/actions/QuitAction.java44
-rw-r--r--hierarchyviewer2/app/src/com/android/hierarchyviewer/actions/RefreshPixelPerfectAction.java58
-rw-r--r--hierarchyviewer2/app/src/com/android/hierarchyviewer/actions/RefreshPixelPerfectTreeAction.java58
-rw-r--r--hierarchyviewer2/app/src/com/android/hierarchyviewer/actions/RefreshViewAction.java58
-rw-r--r--hierarchyviewer2/app/src/com/android/hierarchyviewer/actions/RefreshWindowsAction.java58
-rw-r--r--hierarchyviewer2/app/src/com/android/hierarchyviewer/actions/RequestLayoutAction.java58
-rw-r--r--hierarchyviewer2/app/src/com/android/hierarchyviewer/actions/SavePixelPerfectAction.java62
-rw-r--r--hierarchyviewer2/app/src/com/android/hierarchyviewer/actions/SaveTreeViewAction.java62
-rw-r--r--hierarchyviewer2/app/src/com/android/hierarchyviewer/actions/ShowOverlayAction.java59
-rw-r--r--hierarchyviewer2/app/src/com/android/hierarchyviewer/util/ActionButton.java75
24 files changed, 2421 insertions, 81 deletions
diff --git a/hierarchyviewer2/app/src/com/android/hierarchyviewer/AboutDialog.java b/hierarchyviewer2/app/src/com/android/hierarchyviewer/AboutDialog.java
new file mode 100644
index 0000000..54edbc8
--- /dev/null
+++ b/hierarchyviewer2/app/src/com/android/hierarchyviewer/AboutDialog.java
@@ -0,0 +1,72 @@
+/*
+ * 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.hierarchyviewer;
+
+import com.android.ddmuilib.ImageLoader;
+import com.android.hierarchyviewerlib.HierarchyViewerDirector;
+
+import org.eclipse.jface.dialogs.Dialog;
+import org.eclipse.jface.dialogs.IDialogConstants;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.custom.CLabel;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.layout.FillLayout;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Shell;
+
+public class AboutDialog extends Dialog {
+ private Image aboutImage;
+
+ private Image smallImage;
+
+ public AboutDialog(Shell shell) {
+ super(shell);
+ ImageLoader imageLoader = ImageLoader.getLoader(HierarchyViewerDirector.class);
+ smallImage = imageLoader.loadImage("load-view-hierarchy.png", Display.getDefault());
+ aboutImage = imageLoader.loadImage("about.jpg", Display.getDefault());
+ }
+
+ @Override
+ protected void createButtonsForButtonBar(Composite parent) {
+ createButton(parent, IDialogConstants.OK_ID, IDialogConstants.OK_LABEL, true);
+ }
+
+ @Override
+ protected Control createDialogArea(Composite parent) {
+ Composite control = new Composite(parent, SWT.NONE);
+ control.setLayout(new GridLayout(2, true));
+ Composite imageControl = new Composite(control, SWT.BORDER);
+ imageControl.setLayout(new FillLayout());
+ imageControl.setLayoutData(new GridData(GridData.FILL_VERTICAL));
+ Label imageLabel = new Label(imageControl, SWT.CENTER);
+ imageLabel.setImage(aboutImage);
+
+ CLabel textLabel = new CLabel(control, SWT.NONE);
+ textLabel
+ .setText("Hierarchy Viewer\nCopyright 2010, The Android Open Source Project\nAll Rights Reserved.");
+ textLabel.setLayoutData(new GridData(GridData.BEGINNING, GridData.CENTER, true, true));
+ getShell().setText("About...");
+ getShell().setImage(smallImage);
+ return control;
+
+ }
+}
diff --git a/hierarchyviewer2/app/src/com/android/hierarchyviewer/HierarchyViewerApplication.java b/hierarchyviewer2/app/src/com/android/hierarchyviewer/HierarchyViewerApplication.java
index c3538dc..c967d6b 100644
--- a/hierarchyviewer2/app/src/com/android/hierarchyviewer/HierarchyViewerApplication.java
+++ b/hierarchyviewer2/app/src/com/android/hierarchyviewer/HierarchyViewerApplication.java
@@ -16,27 +16,1201 @@
package com.android.hierarchyviewer;
-import com.android.hierarchyviewerlib.ComponentRegistry;
+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.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.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.TreeViewOverview;
-public class HierarchyViewerApplication {
- public static void main(String[] args) {
- HierarchyViewerDirector director = new HierarchyViewerApplicationDirector();
- ComponentRegistry.setDirector(director);
- ComponentRegistry.setDeviceSelectionModel(new DeviceSelectionModel());
- ComponentRegistry.setPixelPerfectModel(new PixelPerfectModel());
- ComponentRegistry.setTreeViewModel(new TreeViewModel());
+import org.eclipse.jface.action.MenuManager;
+import org.eclipse.jface.action.Separator;
+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;
+import org.eclipse.swt.graphics.Rectangle;
+import org.eclipse.swt.layout.FillLayout;
+import org.eclipse.swt.layout.FormAttachment;
+import org.eclipse.swt.layout.FormData;
+import org.eclipse.swt.layout.FormLayout;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.layout.RowLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+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 {
+
+ private static final int INITIAL_WIDTH = 1024;
+
+ private static final int INITIAL_HEIGHT = 768;
+
+ private static HierarchyViewerApplication APP;
+
+ private Image deviceViewImage;
+
+ private Image pixelPerfectImage;
+
+ private Image treeViewImage;
+
+ private Image deviceViewSelectedImage;
+
+ private Image pixelPerfectSelectedImage;
+
+ private Image treeViewSelectedImage;
+
+ private Button treeViewButton;
+
+ private Button pixelPerfectButton;
+
+ private Button deviceViewButton;
+
+ private Label progressLabel;
+
+ private ProgressBar progressBar;
+
+ private String progressString;
+
+ private Composite deviceSelectorPanel;
+
+ private Composite treeViewPanel;
+
+ private Composite pixelPerfectPanel;
+
+ private StackLayout mainWindowStackLayout;
+
+ private DeviceSelector deviceSelector;
+
+ private Composite statusBar;
+
+ private TreeView treeView;
+
+ private Composite mainWindow;
+
+ private Image onBlackImage;
+
+ private Image onWhiteImage;
+
+ private Button onBlackWhiteButton;
+
+ private Button showExtras;
+
+ 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;
+
+ public static final HierarchyViewerApplication getApp() {
+ return APP;
+ }
+
+ public HierarchyViewerApplication() {
+ super(null);
+
+ APP = this;
+
+ addMenuBar();
+ }
+
+ @Override
+ protected void configureShell(Shell shell) {
+ super.configureShell(shell);
+ shell.setText("Hierarchy Viewer");
+ ImageLoader imageLoader = ImageLoader.getLoader(HierarchyViewerDirector.class);
+ Image image = imageLoader.loadImage("load-view-hierarchy.png", Display.getDefault());
+ shell.setImage(image);
+ }
+
+ @Override
+ public MenuManager createMenuManager() {
+ return new MenuManager();
+ }
+
+ public void run() {
+ HierarchyViewerDirector director = HierarchyViewerApplicationDirector.createDirector();
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();
- UIThread.runUI();
+ open();
+
+ pixelPerfectRefreshingThread.interrupt();
+
+ DeviceSelectionModel.getModel().removeWindowChangeListener(windowChangeListener);
+ TreeViewModel.getModel().removeTreeChangeListener(treeChangeListener);
+ PixelPerfectModel.getModel().removeImageChangeListener(imageChangeListener);
+
+ Display.getCurrent().dispose();
+ ImageLoader.dispose();
director.stopListenForDevices();
director.stopDebugBridge();
director.terminate();
+ }
+
+ @Override
+ protected void initializeBounds() {
+ Rectangle monitorArea = Display.getDefault().getPrimaryMonitor().getBounds();
+ getShell().setSize(Math.min(monitorArea.width, INITIAL_WIDTH),
+ Math.min(monitorArea.height, INITIAL_HEIGHT));
+ getShell().setLocation(monitorArea.x + (monitorArea.width - INITIAL_WIDTH) / 2,
+ monitorArea.y + (monitorArea.height - INITIAL_HEIGHT) / 2);
+ }
+
+ private void loadResources() {
+ ImageLoader imageLoader = ImageLoader.getLoader(HierarchyViewerDirector.class);
+ treeViewImage = imageLoader.loadImage("tree-view.png", Display.getDefault());
+ treeViewSelectedImage =
+ imageLoader.loadImage("tree-view-selected.png", Display.getDefault());
+ pixelPerfectImage = imageLoader.loadImage("pixel-perfect-view.png", Display.getDefault());
+ pixelPerfectSelectedImage =
+ imageLoader.loadImage("pixel-perfect-view-selected.png", Display.getDefault());
+ deviceViewImage = imageLoader.loadImage("device-view.png", Display.getDefault());
+ deviceViewSelectedImage =
+ imageLoader.loadImage("device-view-selected.png", Display.getDefault());
+ onBlackImage = imageLoader.loadImage("on-black.png", Display.getDefault());
+ onWhiteImage = imageLoader.loadImage("on-white.png", Display.getDefault());
+ }
+
+ @Override
+ protected Control createContents(Composite parent) {
+ loadResources();
+
+ Composite control = new Composite(parent, SWT.NONE);
+ GridLayout mainLayout = new GridLayout();
+ mainLayout.marginHeight = mainLayout.marginWidth = 0;
+ mainLayout.verticalSpacing = mainLayout.horizontalSpacing = 0;
+ control.setLayout(mainLayout);
+ mainWindow = new Composite(control, SWT.NONE);
+ mainWindow.setLayoutData(new GridData(GridData.FILL_BOTH));
+ mainWindowStackLayout = new StackLayout();
+ mainWindow.setLayout(mainWindowStackLayout);
+
+ buildDeviceSelectorPanel(mainWindow);
+ buildTreeViewPanel(mainWindow);
+ buildPixelPerfectPanel(mainWindow);
+
+ buildStatusBar(control);
+
+ showDeviceSelector();
+
+ return control;
+ }
+
+ private void buildStatusBar(Composite parent) {
+ statusBar = new Composite(parent, SWT.NONE);
+ statusBar.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+
+ FormLayout statusBarLayout = new FormLayout();
+ statusBarLayout.marginHeight = statusBarLayout.marginWidth = 2;
+
+ statusBar.setLayout(statusBarLayout);
+
+ deviceViewButton = new Button(statusBar, SWT.TOGGLE);
+ deviceViewButton.setImage(deviceViewImage);
+ deviceViewButton.setToolTipText("Switch to the window selection view");
+ deviceViewButton.addSelectionListener(deviceViewButtonSelectionListener);
+ FormData deviceViewButtonFormData = new FormData();
+ deviceViewButtonFormData.left = new FormAttachment();
+ deviceViewButton.setLayoutData(deviceViewButtonFormData);
+
+ treeViewButton = new Button(statusBar, SWT.TOGGLE);
+ treeViewButton.setImage(treeViewImage);
+ treeViewButton.setEnabled(false);
+ treeViewButton.setToolTipText("Switch to the tree view");
+ treeViewButton.addSelectionListener(treeViewButtonSelectionListener);
+ FormData treeViewButtonFormData = new FormData();
+ treeViewButtonFormData.left = new FormAttachment(deviceViewButton, 2);
+ treeViewButton.setLayoutData(treeViewButtonFormData);
+
+ pixelPerfectButton = new Button(statusBar, SWT.TOGGLE);
+ pixelPerfectButton.setImage(pixelPerfectImage);
+ pixelPerfectButton.setEnabled(false);
+ pixelPerfectButton.setToolTipText("Switch to the pixel perfect view");
+ pixelPerfectButton.addSelectionListener(pixelPerfectButtonSelectionListener);
+ FormData pixelPerfectButtonFormData = new FormData();
+ pixelPerfectButtonFormData.left = new FormAttachment(treeViewButton, 2);
+ pixelPerfectButton.setLayoutData(pixelPerfectButtonFormData);
+
+ // Control panel should go here.
+ 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);
+
+ // Label should go on top
+ progressLabel = new Label(statusBar, SWT.RIGHT);
+
+ progressBar = new ProgressBar(statusBar, SWT.HORIZONTAL | SWT.INDETERMINATE | SWT.SMOOTH);
+ FormData progressBarFormData = new FormData();
+ progressBarFormData.right = new FormAttachment(100, 0);
+ progressBarFormData.top = new FormAttachment(treeViewButton, 0, SWT.CENTER);
+ progressBar.setLayoutData(progressBarFormData);
+
+ FormData progressLabelFormData = new FormData();
+ progressLabelFormData.right = new FormAttachment(progressBar, -2);
+ progressLabelFormData.top = new FormAttachment(treeViewButton, 0, SWT.CENTER);
+ progressLabel.setLayoutData(progressLabelFormData);
+
+ if (progressString == null) {
+ progressLabel.setVisible(false);
+ progressBar.setVisible(false);
+ } else {
+ progressLabel.setText(progressString);
+ }
+
+ 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%");
+ }
+
+ private void buildDeviceSelectorPanel(Composite parent) {
+ deviceSelectorPanel = new Composite(parent, SWT.NONE);
+ GridLayout gridLayout = new GridLayout();
+ gridLayout.marginWidth = gridLayout.marginHeight = 0;
+ gridLayout.horizontalSpacing = gridLayout.verticalSpacing = 0;
+ deviceSelectorPanel.setLayout(gridLayout);
+
+ Composite buttonPanel = new Composite(deviceSelectorPanel, SWT.NONE);
+ buttonPanel.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+
+ GridLayout buttonLayout = new GridLayout();
+ buttonLayout.marginWidth = buttonLayout.marginHeight = 0;
+ buttonLayout.horizontalSpacing = buttonLayout.verticalSpacing = 0;
+ buttonPanel.setLayout(buttonLayout);
+
+ Composite innerButtonPanel = new Composite(buttonPanel, SWT.NONE);
+ innerButtonPanel.setLayoutData(new GridData(GridData.FILL_VERTICAL));
+ GridLayout innerButtonPanelLayout = new GridLayout(3, true);
+ innerButtonPanelLayout.marginWidth = innerButtonPanelLayout.marginHeight = 2;
+ innerButtonPanelLayout.horizontalSpacing = innerButtonPanelLayout.verticalSpacing = 2;
+ innerButtonPanel.setLayout(innerButtonPanelLayout);
+
+ ActionButton refreshWindows =
+ new ActionButton(innerButtonPanel, RefreshWindowsAction.getAction());
+ refreshWindows.setLayoutData(new GridData(GridData.FILL_BOTH));
+
+ 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);
+ }
+
+ public void buildTreeViewPanel(Composite parent) {
+ treeViewPanel = new Composite(parent, SWT.NONE);
+ GridLayout gridLayout = new GridLayout();
+ gridLayout.marginWidth = gridLayout.marginHeight = 0;
+ gridLayout.horizontalSpacing = gridLayout.verticalSpacing = 0;
+ treeViewPanel.setLayout(gridLayout);
+
+ Composite buttonPanel = new Composite(treeViewPanel, SWT.NONE);
+ buttonPanel.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+
+ GridLayout buttonLayout = new GridLayout();
+ buttonLayout.marginWidth = buttonLayout.marginHeight = 0;
+ buttonLayout.horizontalSpacing = buttonLayout.verticalSpacing = 0;
+ buttonPanel.setLayout(buttonLayout);
+
+ Composite innerButtonPanel = new Composite(buttonPanel, SWT.NONE);
+ innerButtonPanel.setLayoutData(new GridData(GridData.FILL_VERTICAL));
+ GridLayout innerButtonPanelLayout = new GridLayout(6, true);
+ innerButtonPanelLayout.marginWidth = innerButtonPanelLayout.marginHeight = 2;
+ innerButtonPanelLayout.horizontalSpacing = innerButtonPanelLayout.verticalSpacing = 2;
+ innerButtonPanel.setLayout(innerButtonPanelLayout);
+
+ ActionButton saveTreeView =
+ new ActionButton(innerButtonPanel, SaveTreeViewAction.getAction(getShell()));
+ saveTreeView.setLayoutData(new GridData(GridData.FILL_BOTH));
+
+ ActionButton capturePSD =
+ new ActionButton(innerButtonPanel, CapturePSDAction.getAction(getShell()));
+ capturePSD.setLayoutData(new GridData(GridData.FILL_BOTH));
+
+ ActionButton refreshViewAction =
+ new ActionButton(innerButtonPanel, RefreshViewAction.getAction());
+ refreshViewAction.setLayoutData(new GridData(GridData.FILL_BOTH));
+
+ ActionButton displayView =
+ new ActionButton(innerButtonPanel, DisplayViewAction.getAction(getShell()));
+ displayView.setLayoutData(new GridData(GridData.FILL_BOTH));
+
+ ActionButton invalidate = new ActionButton(innerButtonPanel, InvalidateAction.getAction());
+ invalidate.setLayoutData(new GridData(GridData.FILL_BOTH));
+
+ ActionButton requestLayout =
+ new ActionButton(innerButtonPanel, RequestLayoutAction.getAction());
+ requestLayout.setLayoutData(new GridData(GridData.FILL_BOTH));
+
+ SashForm mainSash = new SashForm(treeViewPanel, SWT.HORIZONTAL | SWT.SMOOTH);
+ mainSash.setLayoutData(new GridData(GridData.FILL_BOTH));
+ Composite treeViewContainer = new Composite(mainSash, SWT.BORDER);
+ treeViewContainer.setLayout(new FillLayout());
+ treeView = new TreeView(treeViewContainer);
+
+ SashForm sideSash = new SashForm(mainSash, SWT.VERTICAL | SWT.SMOOTH);
+
+ mainSash.SASH_WIDTH = 4;
+ mainSash.setWeights(new int[] {
+ 7, 3
+ });
+
+ Composite treeViewOverviewContainer = new Composite(sideSash, SWT.BORDER);
+ treeViewOverviewContainer.setLayout(new FillLayout());
+ TreeViewOverview treeViewOverview = new TreeViewOverview(treeViewOverviewContainer);
+
+ Composite propertyViewerContainer = new Composite(sideSash, SWT.BORDER);
+ propertyViewerContainer.setLayout(new FillLayout());
+ PropertyViewer propertyViewer = new PropertyViewer(propertyViewerContainer);
+
+ Composite layoutViewerContainer = new Composite(sideSash, SWT.NONE);
+ GridLayout layoutViewerLayout = new GridLayout();
+ layoutViewerLayout.marginWidth = layoutViewerLayout.marginHeight = 0;
+ layoutViewerLayout.horizontalSpacing = layoutViewerLayout.verticalSpacing = 1;
+ layoutViewerContainer.setLayout(layoutViewerLayout);
+
+ Composite fullButtonBar = new Composite(layoutViewerContainer, SWT.NONE);
+ fullButtonBar.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+ GridLayout fullButtonBarLayout = new GridLayout(2, false);
+ fullButtonBarLayout.marginWidth = fullButtonBarLayout.marginHeight = 0;
+ fullButtonBarLayout.marginRight = 2;
+ fullButtonBarLayout.horizontalSpacing = fullButtonBarLayout.verticalSpacing = 0;
+ fullButtonBar.setLayout(fullButtonBarLayout);
+
+ Composite buttonBar = new Composite(fullButtonBar, SWT.NONE);
+ buttonBar.setLayoutData(new GridData(GridData.FILL_VERTICAL));
+ RowLayout rowLayout = new RowLayout(SWT.HORIZONTAL);
+ rowLayout.marginLeft =
+ rowLayout.marginRight = rowLayout.marginTop = rowLayout.marginBottom = 0;
+ rowLayout.pack = true;
+ rowLayout.center = true;
+ buttonBar.setLayout(rowLayout);
+
+ onBlackWhiteButton = new Button(buttonBar, SWT.PUSH);
+ onBlackWhiteButton.setImage(onWhiteImage);
+ onBlackWhiteButton.addSelectionListener(onBlackWhiteSelectionListener);
+
+ showExtras = new Button(buttonBar, SWT.CHECK);
+ showExtras.setText("Show Extras");
+ showExtras.addSelectionListener(showExtrasSelectionListener);
+
+ ActionButton loadAllViewsButton =
+ new ActionButton(fullButtonBar, LoadAllViewsAction.getAction());
+ loadAllViewsButton.setLayoutData(new GridData(GridData.END, GridData.CENTER, true, true));
+ loadAllViewsButton.addSelectionListener(loadAllViewsSelectionListener);
+
+ Composite layoutViewerMainContainer = new Composite(layoutViewerContainer, SWT.BORDER);
+ layoutViewerMainContainer.setLayoutData(new GridData(GridData.FILL_BOTH));
+ layoutViewerMainContainer.setLayout(new FillLayout());
+ layoutViewer = new LayoutViewer(layoutViewerMainContainer);
+
+ sideSash.SASH_WIDTH = 4;
+ sideSash.setWeights(new int[] {
+ 238, 332, 416
+ });
+
+ }
+
+ private void buildPixelPerfectPanel(Composite parent) {
+ pixelPerfectPanel = new Composite(parent, SWT.NONE);
+ GridLayout gridLayout = new GridLayout();
+ gridLayout.marginWidth = gridLayout.marginHeight = 0;
+ gridLayout.horizontalSpacing = gridLayout.verticalSpacing = 0;
+ pixelPerfectPanel.setLayout(gridLayout);
+
+ Composite buttonPanel = new Composite(pixelPerfectPanel, SWT.NONE);
+ buttonPanel.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+
+ GridLayout buttonLayout = new GridLayout();
+ buttonLayout.marginWidth = buttonLayout.marginHeight = 0;
+ buttonLayout.horizontalSpacing = buttonLayout.verticalSpacing = 0;
+ buttonPanel.setLayout(buttonLayout);
+
+ Composite innerButtonPanel = new Composite(buttonPanel, SWT.NONE);
+ innerButtonPanel.setLayoutData(new GridData(GridData.FILL_VERTICAL));
+ GridLayout innerButtonPanelLayout = new GridLayout(6, true);
+ innerButtonPanelLayout.marginWidth = innerButtonPanelLayout.marginHeight = 2;
+ innerButtonPanelLayout.horizontalSpacing = innerButtonPanelLayout.verticalSpacing = 2;
+ innerButtonPanel.setLayout(innerButtonPanelLayout);
+
+ ActionButton saveTreeView =
+ new ActionButton(innerButtonPanel, SavePixelPerfectAction.getAction(getShell()));
+ saveTreeView.setLayoutData(new GridData(GridData.FILL_BOTH));
+
+ ActionButton refreshPixelPerfect =
+ new ActionButton(innerButtonPanel, RefreshPixelPerfectAction.getAction());
+ refreshPixelPerfect.setLayoutData(new GridData(GridData.FILL_BOTH));
+
+ ActionButton refreshPixelPerfectTree =
+ new ActionButton(innerButtonPanel, RefreshPixelPerfectTreeAction.getAction());
+ refreshPixelPerfectTree.setLayoutData(new GridData(GridData.FILL_BOTH));
+
+ ActionButton loadOverlay =
+ new ActionButton(innerButtonPanel, LoadOverlayAction.getAction(getShell()));
+ loadOverlay.setLayoutData(new GridData(GridData.FILL_BOTH));
+
+ ActionButton showInLoupe =
+ 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));
+
+ SashForm mainSash = new SashForm(pixelPerfectPanel, SWT.HORIZONTAL | SWT.SMOOTH);
+ mainSash.setLayoutData(new GridData(GridData.FILL_BOTH));
+ mainSash.SASH_WIDTH = 4;
+
+ Composite pixelPerfectTreeContainer = new Composite(mainSash, SWT.BORDER);
+ pixelPerfectTreeContainer.setLayout(new FillLayout());
+ PixelPerfectTree pixelPerfectTree = new PixelPerfectTree(pixelPerfectTreeContainer);
+
+ Composite pixelPerfectLoupeContainer = new Composite(mainSash, SWT.NONE);
+ GridLayout loupeLayout = new GridLayout();
+ loupeLayout.marginWidth = loupeLayout.marginHeight = 0;
+ loupeLayout.horizontalSpacing = loupeLayout.verticalSpacing = 0;
+ pixelPerfectLoupeContainer.setLayout(loupeLayout);
+
+ Composite pixelPerfectLoupeBorder = new Composite(pixelPerfectLoupeContainer, SWT.BORDER);
+ pixelPerfectLoupeBorder.setLayoutData(new GridData(GridData.FILL_BOTH));
+ GridLayout pixelPerfectLoupeBorderGridLayout = new GridLayout();
+ pixelPerfectLoupeBorderGridLayout.marginWidth =
+ pixelPerfectLoupeBorderGridLayout.marginHeight = 0;
+ pixelPerfectLoupeBorderGridLayout.horizontalSpacing =
+ pixelPerfectLoupeBorderGridLayout.verticalSpacing = 0;
+ pixelPerfectLoupeBorder.setLayout(pixelPerfectLoupeBorderGridLayout);
+
+ pixelPerfectLoupe = new PixelPerfectLoupe(pixelPerfectLoupeBorder);
+ pixelPerfectLoupe.setLayoutData(new GridData(GridData.FILL_BOTH));
+
+ PixelPerfectPixelPanel pixelPerfectPixelPanel =
+ new PixelPerfectPixelPanel(pixelPerfectLoupeBorder);
+ pixelPerfectPixelPanel.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+
+ Composite pixelPerfectControls = new Composite(pixelPerfectLoupeContainer, SWT.NONE);
+ 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);
+
+ mainSash.setWeights(new int[] {
+ 272, 376, 346
+ });
+
+ }
+
+ public void setAutoRefresh(boolean value) {
+ if (value) {
+ refreshTimeLeft = refreshInterval;
+ autoRefresh = true;
+ } else {
+ autoRefresh = false;
+ }
+ }
+
+ public void showOverlayInLoupe(boolean value) {
+ pixelPerfectLoupe.setShowOverlay(value);
+ }
+
+ public void startTask(final String taskName) {
+ progressString = taskName;
+ Display.getDefault().syncExec(new Runnable() {
+ public void run() {
+ if (progressLabel != null && progressBar != null) {
+ progressLabel.setText(taskName);
+ progressLabel.setVisible(true);
+ progressBar.setVisible(true);
+ statusBar.layout();
+ }
+ }
+ });
+ }
+
+ public void endTask() {
+ progressString = null;
+ Display.getDefault().syncExec(new Runnable() {
+ public void run() {
+ if (progressLabel != null && progressBar != null) {
+ progressLabel.setVisible(false);
+ progressBar.setVisible(false);
+ }
+ }
+ });
+ }
+
+ public void showDeviceSelector() {
+ // Show the menus.
+ MenuManager mm = getMenuBarManager();
+ mm.removeAll();
+
+ MenuManager file = new MenuManager("&File");
+ mm.add(file);
+
+ file.add(QuitAction.getAction());
+
+ MenuManager device = new MenuManager("&Devices");
+ mm.add(device);
+
+ device.add(RefreshWindowsAction.getAction());
+ device.add(LoadViewHierarchyAction.getAction());
+ device.add(InspectScreenshotAction.getAction());
+
+ MenuManager help = new MenuManager("&Help");
+ mm.add(help);
+
+ help.add(AboutAction.getAction(getShell()));
+
+ mm.updateAll(true);
+
+ deviceViewButton.setSelection(true);
+ deviceViewButton.setImage(deviceViewSelectedImage);
+
+ treeViewButton.setSelection(false);
+ treeViewButton.setImage(treeViewImage);
+
+ pixelPerfectButton.setSelection(false);
+ pixelPerfectButton.setImage(pixelPerfectImage);
+
+ mainWindowStackLayout.topControl = deviceSelectorPanel;
+
+ mainWindow.layout();
+
+ deviceSelector.setFocus();
+
+ statusBarStackLayout.topControl = null;
+ statusBarControlPanel.setVisible(false);
+ statusBarControlPanel.layout();
+ }
+
+ public void showTreeView() {
+ // Show the menus.
+ MenuManager mm = getMenuBarManager();
+ mm.removeAll();
+
+ MenuManager file = new MenuManager("&File");
+ mm.add(file);
+
+ file.add(QuitAction.getAction());
+
+ MenuManager treeViewMenu = new MenuManager("&Tree View");
+ mm.add(treeViewMenu);
+
+ treeViewMenu.add(SaveTreeViewAction.getAction(getShell()));
+ treeViewMenu.add(CapturePSDAction.getAction(getShell()));
+ treeViewMenu.add(new Separator());
+ treeViewMenu.add(RefreshViewAction.getAction());
+ treeViewMenu.add(DisplayViewAction.getAction(getShell()));
+ treeViewMenu.add(new Separator());
+ treeViewMenu.add(InvalidateAction.getAction());
+ treeViewMenu.add(RequestLayoutAction.getAction());
+
+ MenuManager help = new MenuManager("&Help");
+ mm.add(help);
+
+ help.add(AboutAction.getAction(getShell()));
+
+ mm.updateAll(true);
+
+ deviceViewButton.setSelection(false);
+ deviceViewButton.setImage(deviceViewImage);
+
+ treeViewButton.setSelection(true);
+ treeViewButton.setImage(treeViewSelectedImage);
+
+ pixelPerfectButton.setSelection(false);
+ pixelPerfectButton.setImage(pixelPerfectImage);
+
+ mainWindowStackLayout.topControl = treeViewPanel;
+
+ mainWindow.layout();
+
+ treeView.setFocus();
+
+ statusBarStackLayout.topControl = treeViewControls;
+ statusBarControlPanel.setVisible(true);
+ statusBarControlPanel.layout();
+ }
+
+ public void showPixelPerfect() {
+ // Show the menus.
+ MenuManager mm = getMenuBarManager();
+ mm.removeAll();
+
+ MenuManager file = new MenuManager("&File");
+ mm.add(file);
+
+ file.add(QuitAction.getAction());
+
+ MenuManager pixelPerfect = new MenuManager("&Pixel Perfect");
+ pixelPerfect.add(SavePixelPerfectAction.getAction(getShell()));
+ pixelPerfect.add(RefreshPixelPerfectAction.getAction());
+ pixelPerfect.add(RefreshPixelPerfectTreeAction.getAction());
+ pixelPerfect.add(PixelPerfectAutoRefreshAction.getAction());
+ pixelPerfect.add(new Separator());
+ pixelPerfect.add(LoadOverlayAction.getAction(getShell()));
+ pixelPerfect.add(ShowOverlayAction.getAction());
+
+ mm.add(pixelPerfect);
+
+ MenuManager help = new MenuManager("&Help");
+ mm.add(help);
+
+ help.add(AboutAction.getAction(getShell()));
+
+ mm.updateAll(true);
+
+ deviceViewButton.setSelection(false);
+ deviceViewButton.setImage(deviceViewImage);
+
+ treeViewButton.setSelection(false);
+ treeViewButton.setImage(treeViewImage);
+
+ pixelPerfectButton.setSelection(true);
+ pixelPerfectButton.setImage(pixelPerfectSelectedImage);
+
+ mainWindowStackLayout.topControl = pixelPerfectPanel;
+
+ mainWindow.layout();
+
+ pixelPerfectLoupe.setFocus();
+
+ statusBarStackLayout.topControl = null;
+ statusBarControlPanel.setVisible(false);
+ statusBarControlPanel.layout();
+ }
+
+ private SelectionListener deviceViewButtonSelectionListener = new SelectionListener() {
+ public void widgetDefaultSelected(SelectionEvent e) {
+ // pass
+ }
+
+ public void widgetSelected(SelectionEvent e) {
+ deviceViewButton.setSelection(true);
+ showDeviceSelector();
+ }
+ };
+
+ private SelectionListener treeViewButtonSelectionListener = new SelectionListener() {
+ public void widgetDefaultSelected(SelectionEvent e) {
+ // pass
+ }
+
+ public void widgetSelected(SelectionEvent e) {
+ treeViewButton.setSelection(true);
+ showTreeView();
+ }
+ };
+
+ private SelectionListener pixelPerfectButtonSelectionListener = new SelectionListener() {
+ public void widgetDefaultSelected(SelectionEvent e) {
+ // pass
+ }
+
+ public void widgetSelected(SelectionEvent e) {
+ pixelPerfectButton.setSelection(true);
+ showPixelPerfect();
+ }
+ };
+
+ private SelectionListener onBlackWhiteSelectionListener = new SelectionListener() {
+ public void widgetDefaultSelected(SelectionEvent e) {
+ // pass
+ }
+
+ public void widgetSelected(SelectionEvent e) {
+ if (layoutViewer.getOnBlack()) {
+ layoutViewer.setOnBlack(false);
+ onBlackWhiteButton.setImage(onBlackImage);
+ } else {
+ layoutViewer.setOnBlack(true);
+ onBlackWhiteButton.setImage(onWhiteImage);
+ }
+ }
+ };
+
+ private SelectionListener showExtrasSelectionListener = new SelectionListener() {
+ public void widgetDefaultSelected(SelectionEvent e) {
+ // pass
+ }
+
+ public void widgetSelected(SelectionEvent e) {
+ layoutViewer.setShowExtras(showExtras.getSelection());
+ }
+ };
+
+ private SelectionListener loadAllViewsSelectionListener = new SelectionListener() {
+ public void widgetDefaultSelected(SelectionEvent e) {
+ // pass
+ }
+
+ public void widgetSelected(SelectionEvent e) {
+ showExtras.setSelection(true);
+ showExtrasSelectionListener.widgetSelected(null);
+ }
+ };
+
+ 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;
+ 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
+ }
+
+ public void treeChanged() {
+ Display.getDefault().syncExec(new Runnable() {
+ public void run() {
+ if (TreeViewModel.getModel().getTree() == null) {
+ showDeviceSelector();
+ treeViewButton.setEnabled(false);
+ } else {
+ showTreeView();
+ treeViewButton.setEnabled(true);
+ zoomSlider.setSelection((int) Math
+ .round(TreeViewModel.getModel().getZoom() * 10));
+ filterText.setText("");
+ }
+ }
+ });
+ }
+
+ public void viewportChanged() {
+ // pass
+ }
+
+ public void zoomChanged() {
+ // pass
+ zoomSlider.setSelection((int) Math.round(TreeViewModel.getModel().getZoom() * 10));
+ }
+ };
+
+ private ImageChangeListener imageChangeListener = new ImageChangeListener() {
+
+ 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();
+ 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();
+ }
+ }
+ });
+ }
+
+ 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);
+ }
+ });
+ }
+
+ 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() {
+ ppZoomSlider.setSelection(PixelPerfectModel.getModel().getZoom());
+ }
+ });
+ }
+
+ };
+
+ public static void main(String[] args) {
+ Display.getDefault().syncExec(new Runnable() {
+ public void run() {
+ new HierarchyViewerApplication().run();
+ }
+ });
System.exit(0);
}
}
diff --git a/hierarchyviewer2/app/src/com/android/hierarchyviewer/HierarchyViewerApplicationDirector.java b/hierarchyviewer2/app/src/com/android/hierarchyviewer/HierarchyViewerApplicationDirector.java
index 8d77410..f26cc2c 100644
--- a/hierarchyviewer2/app/src/com/android/hierarchyviewer/HierarchyViewerApplicationDirector.java
+++ b/hierarchyviewer2/app/src/com/android/hierarchyviewer/HierarchyViewerApplicationDirector.java
@@ -30,6 +30,10 @@ public class HierarchyViewerApplicationDirector extends HierarchyViewerDirector
private final ExecutorService executor = Executors.newSingleThreadExecutor();
+ public static HierarchyViewerDirector createDirector() {
+ return director = new HierarchyViewerApplicationDirector();
+ }
+
@Override
public void terminate() {
super.terminate();
@@ -43,9 +47,6 @@ public class HierarchyViewerApplicationDirector extends HierarchyViewerDirector
@Override
public String getAdbLocation() {
String hvParentLocation = System.getProperty("com.android.hierarchyviewer.bindir");
- // TODO REMOVE THIS.
- hvParentLocation = "/usr/local/google/android-ext/out/host/linux-x86/bin";
- System.out.println(hvParentLocation);
if (hvParentLocation != null && hvParentLocation.length() != 0) {
return hvParentLocation + File.separator + SdkConstants.FN_ADB;
}
@@ -58,12 +59,12 @@ public class HierarchyViewerApplicationDirector extends HierarchyViewerDirector
* progress bar to show that we are doing something in the background.
*/
@Override
- public void executeInBackground(final Runnable task) {
+ public void executeInBackground(final String taskName, final Runnable task) {
executor.execute(new Runnable() {
public void run() {
- System.out.println("STARTING TASK");
+ HierarchyViewerApplication.getApp().startTask(taskName);
task.run();
- System.out.println("ENDING TASK");
+ HierarchyViewerApplication.getApp().endTask();
}
});
}
diff --git a/hierarchyviewer2/app/src/com/android/hierarchyviewer/UIThread.java b/hierarchyviewer2/app/src/com/android/hierarchyviewer/UIThread.java
deleted file mode 100644
index 3da9468..0000000
--- a/hierarchyviewer2/app/src/com/android/hierarchyviewer/UIThread.java
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * 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.hierarchyviewer;
-
-import com.android.ddmuilib.ImageLoader;
-import com.android.hierarchyviewerlib.ComponentRegistry;
-import com.android.hierarchyviewerlib.ui.DeviceSelector;
-import com.android.hierarchyviewerlib.ui.LayoutViewer;
-import com.android.hierarchyviewerlib.ui.PixelPerfect;
-import com.android.hierarchyviewerlib.ui.PixelPerfectLoupe;
-import com.android.hierarchyviewerlib.ui.PixelPerfectTree;
-import com.android.hierarchyviewerlib.ui.ProfileViewer;
-import com.android.hierarchyviewerlib.ui.PropertyViewer;
-import com.android.hierarchyviewerlib.ui.TreeView;
-import com.android.hierarchyviewerlib.ui.TreeViewOverview;
-
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.events.SelectionEvent;
-import org.eclipse.swt.events.SelectionListener;
-import org.eclipse.swt.events.ShellEvent;
-import org.eclipse.swt.events.ShellListener;
-import org.eclipse.swt.layout.FillLayout;
-import org.eclipse.swt.layout.GridData;
-import org.eclipse.swt.layout.GridLayout;
-import org.eclipse.swt.widgets.Button;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Display;
-import org.eclipse.swt.widgets.Shell;
-import org.eclipse.swt.widgets.Slider;
-
-public class UIThread {
- public static void runUI() {
- Display display = new Display();
-
- // CODE BELOW IS FOR TESTING.
- Shell shell = new Shell(display);
- shell.setLayout(new FillLayout());
- DeviceSelector deviceSelector = new DeviceSelector(shell);
- shell.open();
-
- while (!shell.isDisposed()) {
- if (!display.readAndDispatch()) {
- display.sleep();
- }
- }
-
- // NO LONGER TESTING STUFF.
-
- ImageLoader.dispose();
- display.dispose();
- }
-}
diff --git a/hierarchyviewer2/app/src/com/android/hierarchyviewer/actions/AboutAction.java b/hierarchyviewer2/app/src/com/android/hierarchyviewer/actions/AboutAction.java
new file mode 100644
index 0000000..9c76ae9
--- /dev/null
+++ b/hierarchyviewer2/app/src/com/android/hierarchyviewer/actions/AboutAction.java
@@ -0,0 +1,63 @@
+/*
+ * 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.hierarchyviewer.actions;
+
+import com.android.ddmuilib.ImageLoader;
+import com.android.hierarchyviewer.AboutDialog;
+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 AboutAction extends Action implements ImageAction {
+
+ private static AboutAction action;
+
+ private Image image;
+
+ private Shell shell;
+
+ private AboutAction(Shell shell) {
+ super("&About");
+ this.shell = shell;
+ setAccelerator(SWT.MOD1 + 'A');
+ ImageLoader imageLoader = ImageLoader.getLoader(HierarchyViewerDirector.class);
+ image = imageLoader.loadImage("about-small.jpg", Display.getDefault());
+ setImageDescriptor(ImageDescriptor.createFromImage(image));
+ setToolTipText("Shows the about dialog");
+ }
+
+ public static AboutAction getAction(Shell shell) {
+ if (action == null) {
+ action = new AboutAction(shell);
+ }
+ return action;
+ }
+
+ @Override
+ public void run() {
+ new AboutDialog(shell).open();
+ }
+
+ public Image getImage() {
+ return image;
+ }
+}
diff --git a/hierarchyviewer2/app/src/com/android/hierarchyviewer/actions/CapturePSDAction.java b/hierarchyviewer2/app/src/com/android/hierarchyviewer/actions/CapturePSDAction.java
new file mode 100644
index 0000000..6ae0d17
--- /dev/null
+++ b/hierarchyviewer2/app/src/com/android/hierarchyviewer/actions/CapturePSDAction.java
@@ -0,0 +1,62 @@
+/*
+ * 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.hierarchyviewer.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 {
+
+ private static CapturePSDAction action;
+
+ private Image image;
+
+ private Shell shell;
+
+ private CapturePSDAction(Shell shell) {
+ super("&Capture Layers");
+ this.shell = shell;
+ setAccelerator(SWT.MOD1 + 'C');
+ ImageLoader imageLoader = ImageLoader.getLoader(HierarchyViewerDirector.class);
+ image = imageLoader.loadImage("capture-psd.png", Display.getDefault());
+ setImageDescriptor(ImageDescriptor.createFromImage(image));
+ setToolTipText("Capture the window layers as a photoshop document");
+ }
+
+ public static CapturePSDAction getAction(Shell shell) {
+ if (action == null) {
+ action = new CapturePSDAction(shell);
+ }
+ return action;
+ }
+
+ @Override
+ public void run() {
+ HierarchyViewerDirector.getDirector().capturePSD(shell);
+ }
+
+ public Image getImage() {
+ return image;
+ }
+}
diff --git a/hierarchyviewer2/app/src/com/android/hierarchyviewer/actions/DisplayViewAction.java b/hierarchyviewer2/app/src/com/android/hierarchyviewer/actions/DisplayViewAction.java
new file mode 100644
index 0000000..a622eb2
--- /dev/null
+++ b/hierarchyviewer2/app/src/com/android/hierarchyviewer/actions/DisplayViewAction.java
@@ -0,0 +1,62 @@
+/*
+ * 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.hierarchyviewer.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 {
+
+ private static DisplayViewAction action;
+
+ private Image image;
+
+ private Shell shell;
+
+ private DisplayViewAction(Shell shell) {
+ super("&Display View");
+ this.shell = shell;
+ setAccelerator(SWT.MOD1 + 'D');
+ ImageLoader imageLoader = ImageLoader.getLoader(HierarchyViewerDirector.class);
+ image = imageLoader.loadImage("display.png", Display.getDefault());
+ setImageDescriptor(ImageDescriptor.createFromImage(image));
+ setToolTipText("Display the selected view image in a separate window");
+ }
+
+ public static DisplayViewAction getAction(Shell shell) {
+ if (action == null) {
+ action = new DisplayViewAction(shell);
+ }
+ return action;
+ }
+
+ @Override
+ public void run() {
+ HierarchyViewerDirector.getDirector().showCapture(shell);
+ }
+
+ public Image getImage() {
+ return image;
+ }
+}
diff --git a/hierarchyviewer2/app/src/com/android/hierarchyviewer/actions/ImageAction.java b/hierarchyviewer2/app/src/com/android/hierarchyviewer/actions/ImageAction.java
new file mode 100644
index 0000000..11c98a4
--- /dev/null
+++ b/hierarchyviewer2/app/src/com/android/hierarchyviewer/actions/ImageAction.java
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.hierarchyviewer.actions;
+
+import org.eclipse.swt.graphics.Image;
+
+public interface ImageAction {
+ public Image getImage();
+
+ public String getText();
+
+ public String getToolTipText();
+}
diff --git a/hierarchyviewer2/app/src/com/android/hierarchyviewer/actions/InspectScreenshotAction.java b/hierarchyviewer2/app/src/com/android/hierarchyviewer/actions/InspectScreenshotAction.java
new file mode 100644
index 0000000..5109ca5
--- /dev/null
+++ b/hierarchyviewer2/app/src/com/android/hierarchyviewer/actions/InspectScreenshotAction.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.hierarchyviewer.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 InspectScreenshotAction extends Action implements ImageAction {
+
+ private static InspectScreenshotAction action;
+
+ private Image image;
+
+ private InspectScreenshotAction() {
+ super("Inspect &Screenshot");
+ setAccelerator(SWT.MOD1 + 'S');
+ ImageLoader imageLoader = ImageLoader.getLoader(HierarchyViewerDirector.class);
+ image = imageLoader.loadImage("inspect-screenshot.png", Display.getDefault());
+ setImageDescriptor(ImageDescriptor.createFromImage(image));
+ setToolTipText("Inspect a screenshot in the pixel perfect view");
+ }
+
+ public static InspectScreenshotAction getAction() {
+ if (action == null) {
+ action = new InspectScreenshotAction();
+ }
+ return action;
+ }
+
+ @Override
+ public void run() {
+ HierarchyViewerDirector.getDirector().inspectScreenshot();
+ }
+
+ public Image getImage() {
+ return image;
+ }
+}
diff --git a/hierarchyviewer2/app/src/com/android/hierarchyviewer/actions/InvalidateAction.java b/hierarchyviewer2/app/src/com/android/hierarchyviewer/actions/InvalidateAction.java
new file mode 100644
index 0000000..831a56d
--- /dev/null
+++ b/hierarchyviewer2/app/src/com/android/hierarchyviewer/actions/InvalidateAction.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.hierarchyviewer.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 {
+
+ private static InvalidateAction action;
+
+ private Image image;
+
+ private InvalidateAction() {
+ super("&Invalidate Layout");
+ setAccelerator(SWT.MOD1 + 'I');
+ ImageLoader imageLoader = ImageLoader.getLoader(HierarchyViewerDirector.class);
+ image = imageLoader.loadImage("invalidate.png", Display.getDefault());
+ setImageDescriptor(ImageDescriptor.createFromImage(image));
+ setToolTipText("Invalidate the layout for the current window");
+ }
+
+ public static InvalidateAction getAction() {
+ if (action == null) {
+ action = new InvalidateAction();
+ }
+ return action;
+ }
+
+ @Override
+ public void run() {
+ HierarchyViewerDirector.getDirector().invalidateCurrentNode();
+ }
+
+ public Image getImage() {
+ return image;
+ }
+}
diff --git a/hierarchyviewer2/app/src/com/android/hierarchyviewer/actions/LoadAllViewsAction.java b/hierarchyviewer2/app/src/com/android/hierarchyviewer/actions/LoadAllViewsAction.java
new file mode 100644
index 0000000..2ea2298
--- /dev/null
+++ b/hierarchyviewer2/app/src/com/android/hierarchyviewer/actions/LoadAllViewsAction.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.hierarchyviewer.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 LoadAllViewsAction extends Action implements ImageAction {
+
+ private static LoadAllViewsAction action;
+
+ private Image image;
+
+ private LoadAllViewsAction() {
+ super("Load All &Views");
+ setAccelerator(SWT.MOD1 + 'V');
+ ImageLoader imageLoader = ImageLoader.getLoader(HierarchyViewerDirector.class);
+ image = imageLoader.loadImage("load-all-views.png", Display.getDefault());
+ setImageDescriptor(ImageDescriptor.createFromImage(image));
+ setToolTipText("Load all view images");
+ }
+
+ public static LoadAllViewsAction getAction() {
+ if (action == null) {
+ action = new LoadAllViewsAction();
+ }
+ return action;
+ }
+
+ @Override
+ public void run() {
+ HierarchyViewerDirector.getDirector().loadAllViews();
+ }
+
+ public Image getImage() {
+ return image;
+ }
+}
diff --git a/hierarchyviewer2/app/src/com/android/hierarchyviewer/actions/LoadOverlayAction.java b/hierarchyviewer2/app/src/com/android/hierarchyviewer/actions/LoadOverlayAction.java
new file mode 100644
index 0000000..588b995
--- /dev/null
+++ b/hierarchyviewer2/app/src/com/android/hierarchyviewer/actions/LoadOverlayAction.java
@@ -0,0 +1,62 @@
+/*
+ * 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.hierarchyviewer.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 {
+
+ private static LoadOverlayAction action;
+
+ private Image image;
+
+ private Shell shell;
+
+ private LoadOverlayAction(Shell shell) {
+ super("Load &Overlay");
+ this.shell = shell;
+ setAccelerator(SWT.MOD1 + 'O');
+ ImageLoader imageLoader = ImageLoader.getLoader(HierarchyViewerDirector.class);
+ image = imageLoader.loadImage("load-overlay.png", Display.getDefault());
+ setImageDescriptor(ImageDescriptor.createFromImage(image));
+ setToolTipText("Load an image to overlay the screenshot");
+ }
+
+ public static LoadOverlayAction getAction(Shell shell) {
+ if (action == null) {
+ action = new LoadOverlayAction(shell);
+ }
+ return action;
+ }
+
+ @Override
+ public void run() {
+ HierarchyViewerDirector.getDirector().loadOverlay(shell);
+ }
+
+ public Image getImage() {
+ return image;
+ }
+}
diff --git a/hierarchyviewer2/app/src/com/android/hierarchyviewer/actions/LoadViewHierarchyAction.java b/hierarchyviewer2/app/src/com/android/hierarchyviewer/actions/LoadViewHierarchyAction.java
new file mode 100644
index 0000000..79fd0b3
--- /dev/null
+++ b/hierarchyviewer2/app/src/com/android/hierarchyviewer/actions/LoadViewHierarchyAction.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.hierarchyviewer.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 LoadViewHierarchyAction extends Action implements ImageAction {
+
+ private static LoadViewHierarchyAction action;
+
+ private Image image;
+
+ private LoadViewHierarchyAction() {
+ super("Load View &Hierarchy");
+ setAccelerator(SWT.MOD1 + 'H');
+ ImageLoader imageLoader = ImageLoader.getLoader(HierarchyViewerDirector.class);
+ image = imageLoader.loadImage("load-view-hierarchy.png", Display.getDefault());
+ setImageDescriptor(ImageDescriptor.createFromImage(image));
+ setToolTipText("Load the view hierarchy into the tree view");
+ }
+
+ public static LoadViewHierarchyAction getAction() {
+ if (action == null) {
+ action = new LoadViewHierarchyAction();
+ }
+ return action;
+ }
+
+ @Override
+ public void run() {
+ HierarchyViewerDirector.getDirector().loadViewHierarchy();
+ }
+
+ public Image getImage() {
+ return image;
+ }
+}
diff --git a/hierarchyviewer2/app/src/com/android/hierarchyviewer/actions/PixelPerfectAutoRefreshAction.java b/hierarchyviewer2/app/src/com/android/hierarchyviewer/actions/PixelPerfectAutoRefreshAction.java
new file mode 100644
index 0000000..325eb86
--- /dev/null
+++ b/hierarchyviewer2/app/src/com/android/hierarchyviewer/actions/PixelPerfectAutoRefreshAction.java
@@ -0,0 +1,59 @@
+/*
+ * 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.hierarchyviewer.actions;
+
+import com.android.ddmuilib.ImageLoader;
+import com.android.hierarchyviewer.HierarchyViewerApplication;
+import com.android.hierarchyviewerlib.HierarchyViewerDirector;
+
+import org.eclipse.jface.action.Action;
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.widgets.Display;
+
+public class PixelPerfectAutoRefreshAction extends Action implements ImageAction {
+
+ private static PixelPerfectAutoRefreshAction action;
+
+ private Image image;
+
+ private PixelPerfectAutoRefreshAction() {
+ super("Auto &Refresh", Action.AS_CHECK_BOX);
+ setAccelerator(SWT.MOD1 + 'R');
+ ImageLoader imageLoader = ImageLoader.getLoader(HierarchyViewerDirector.class);
+ image = imageLoader.loadImage("auto-refresh.png", Display.getDefault());
+ setImageDescriptor(ImageDescriptor.createFromImage(image));
+ setToolTipText("Automatically refresh the screenshot");
+ }
+
+ public static PixelPerfectAutoRefreshAction getAction() {
+ if (action == null) {
+ action = new PixelPerfectAutoRefreshAction();
+ }
+ return action;
+ }
+
+ @Override
+ public void run() {
+ HierarchyViewerApplication.getApp().setAutoRefresh(action.isChecked());
+ }
+
+ public Image getImage() {
+ return image;
+ }
+}
diff --git a/hierarchyviewer2/app/src/com/android/hierarchyviewer/actions/QuitAction.java b/hierarchyviewer2/app/src/com/android/hierarchyviewer/actions/QuitAction.java
new file mode 100644
index 0000000..693d55a
--- /dev/null
+++ b/hierarchyviewer2/app/src/com/android/hierarchyviewer/actions/QuitAction.java
@@ -0,0 +1,44 @@
+/*
+ * 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.hierarchyviewer.actions;
+
+import com.android.hierarchyviewer.HierarchyViewerApplication;
+
+import org.eclipse.jface.action.Action;
+import org.eclipse.swt.SWT;
+
+public class QuitAction extends Action {
+
+ private static QuitAction action;
+
+ private QuitAction() {
+ super("E&xit");
+ setAccelerator(SWT.MOD1 + 'Q');
+ }
+
+ public static QuitAction getAction() {
+ if (action == null) {
+ action = new QuitAction();
+ }
+ return action;
+ }
+
+ @Override
+ public void run() {
+ HierarchyViewerApplication.getApp().close();
+ }
+}
diff --git a/hierarchyviewer2/app/src/com/android/hierarchyviewer/actions/RefreshPixelPerfectAction.java b/hierarchyviewer2/app/src/com/android/hierarchyviewer/actions/RefreshPixelPerfectAction.java
new file mode 100644
index 0000000..5d68c37
--- /dev/null
+++ b/hierarchyviewer2/app/src/com/android/hierarchyviewer/actions/RefreshPixelPerfectAction.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.hierarchyviewer.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 {
+
+ private static RefreshPixelPerfectAction action;
+
+ private Image image;
+
+ private RefreshPixelPerfectAction() {
+ super("&Refresh Screenshot");
+ setAccelerator(SWT.F5);
+ ImageLoader imageLoader = ImageLoader.getLoader(HierarchyViewerDirector.class);
+ image = imageLoader.loadImage("refresh-windows.png", Display.getDefault());
+ setImageDescriptor(ImageDescriptor.createFromImage(image));
+ setToolTipText("Refresh the screenshot");
+ }
+
+ public static RefreshPixelPerfectAction getAction() {
+ if (action == null) {
+ action = new RefreshPixelPerfectAction();
+ }
+ return action;
+ }
+
+ @Override
+ public void run() {
+ HierarchyViewerDirector.getDirector().refreshPixelPerfect();
+ }
+
+ public Image getImage() {
+ return image;
+ }
+}
diff --git a/hierarchyviewer2/app/src/com/android/hierarchyviewer/actions/RefreshPixelPerfectTreeAction.java b/hierarchyviewer2/app/src/com/android/hierarchyviewer/actions/RefreshPixelPerfectTreeAction.java
new file mode 100644
index 0000000..74c577d
--- /dev/null
+++ b/hierarchyviewer2/app/src/com/android/hierarchyviewer/actions/RefreshPixelPerfectTreeAction.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.hierarchyviewer.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 {
+
+ private static RefreshPixelPerfectTreeAction action;
+
+ private Image image;
+
+ private RefreshPixelPerfectTreeAction() {
+ super("Refresh &Tree");
+ setAccelerator(SWT.MOD1 + 'T');
+ ImageLoader imageLoader = ImageLoader.getLoader(HierarchyViewerDirector.class);
+ image = imageLoader.loadImage("load-view-hierarchy.png", Display.getDefault());
+ setImageDescriptor(ImageDescriptor.createFromImage(image));
+ setToolTipText("Refresh the tree");
+ }
+
+ public static RefreshPixelPerfectTreeAction getAction() {
+ if (action == null) {
+ action = new RefreshPixelPerfectTreeAction();
+ }
+ return action;
+ }
+
+ @Override
+ public void run() {
+ HierarchyViewerDirector.getDirector().refreshPixelPerfectTree();
+ }
+
+ public Image getImage() {
+ return image;
+ }
+}
diff --git a/hierarchyviewer2/app/src/com/android/hierarchyviewer/actions/RefreshViewAction.java b/hierarchyviewer2/app/src/com/android/hierarchyviewer/actions/RefreshViewAction.java
new file mode 100644
index 0000000..36704a7
--- /dev/null
+++ b/hierarchyviewer2/app/src/com/android/hierarchyviewer/actions/RefreshViewAction.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.hierarchyviewer.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 {
+
+ private static RefreshViewAction action;
+
+ private Image image;
+
+ private RefreshViewAction() {
+ super("Load View &Hierarchy");
+ setAccelerator(SWT.MOD1 + 'H');
+ ImageLoader imageLoader = ImageLoader.getLoader(HierarchyViewerDirector.class);
+ image = imageLoader.loadImage("load-view-hierarchy.png", Display.getDefault());
+ setImageDescriptor(ImageDescriptor.createFromImage(image));
+ setToolTipText("Reload the view hierarchy");
+ }
+
+ public static RefreshViewAction getAction() {
+ if (action == null) {
+ action = new RefreshViewAction();
+ }
+ return action;
+ }
+
+ @Override
+ public void run() {
+ HierarchyViewerDirector.getDirector().reloadViewHierarchy();
+ }
+
+ public Image getImage() {
+ return image;
+ }
+}
diff --git a/hierarchyviewer2/app/src/com/android/hierarchyviewer/actions/RefreshWindowsAction.java b/hierarchyviewer2/app/src/com/android/hierarchyviewer/actions/RefreshWindowsAction.java
new file mode 100644
index 0000000..63808ee
--- /dev/null
+++ b/hierarchyviewer2/app/src/com/android/hierarchyviewer/actions/RefreshWindowsAction.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.hierarchyviewer.actions;
+
+import com.android.ddmuilib.ImageLoader;
+import com.android.hierarchyviewerlib.HierarchyViewerDirector;
+
+import org.eclipse.jface.action.Action;
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.widgets.Display;
+
+public class RefreshWindowsAction extends Action implements ImageAction {
+
+ private static RefreshWindowsAction action;
+
+ private Image image;
+
+ private RefreshWindowsAction() {
+ super("&Refresh");
+ setAccelerator(SWT.F5);
+ ImageLoader imageLoader = ImageLoader.getLoader(HierarchyViewerDirector.class);
+ image = imageLoader.loadImage("refresh-windows.png", Display.getDefault());
+ setImageDescriptor(ImageDescriptor.createFromImage(image));
+ setToolTipText("Refresh the list of devices");
+ }
+
+ public static RefreshWindowsAction getAction() {
+ if (action == null) {
+ action = new RefreshWindowsAction();
+ }
+ return action;
+ }
+
+ @Override
+ public void run() {
+ HierarchyViewerDirector.getDirector().refreshWindows();
+ }
+
+ public Image getImage() {
+ return image;
+ }
+}
diff --git a/hierarchyviewer2/app/src/com/android/hierarchyviewer/actions/RequestLayoutAction.java b/hierarchyviewer2/app/src/com/android/hierarchyviewer/actions/RequestLayoutAction.java
new file mode 100644
index 0000000..9255432
--- /dev/null
+++ b/hierarchyviewer2/app/src/com/android/hierarchyviewer/actions/RequestLayoutAction.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.hierarchyviewer.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 {
+
+ private static RequestLayoutAction action;
+
+ private Image image;
+
+ private RequestLayoutAction() {
+ super("Request &Layout");
+ setAccelerator(SWT.MOD1 + 'L');
+ ImageLoader imageLoader = ImageLoader.getLoader(HierarchyViewerDirector.class);
+ image = imageLoader.loadImage("request-layout.png", Display.getDefault());
+ setImageDescriptor(ImageDescriptor.createFromImage(image));
+ setToolTipText("Request the view to lay out");
+ }
+
+ public static RequestLayoutAction getAction() {
+ if (action == null) {
+ action = new RequestLayoutAction();
+ }
+ return action;
+ }
+
+ @Override
+ public void run() {
+ HierarchyViewerDirector.getDirector().relayoutCurrentNode();
+ }
+
+ public Image getImage() {
+ return image;
+ }
+}
diff --git a/hierarchyviewer2/app/src/com/android/hierarchyviewer/actions/SavePixelPerfectAction.java b/hierarchyviewer2/app/src/com/android/hierarchyviewer/actions/SavePixelPerfectAction.java
new file mode 100644
index 0000000..2221ad8
--- /dev/null
+++ b/hierarchyviewer2/app/src/com/android/hierarchyviewer/actions/SavePixelPerfectAction.java
@@ -0,0 +1,62 @@
+/*
+ * 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.hierarchyviewer.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 {
+
+ private static SavePixelPerfectAction action;
+
+ private Image image;
+
+ private Shell shell;
+
+ private SavePixelPerfectAction(Shell shell) {
+ super("&Save as PNG");
+ this.shell = shell;
+ setAccelerator(SWT.MOD1 + 'S');
+ ImageLoader imageLoader = ImageLoader.getLoader(HierarchyViewerDirector.class);
+ image = imageLoader.loadImage("save.png", Display.getDefault());
+ setImageDescriptor(ImageDescriptor.createFromImage(image));
+ setToolTipText("Save the screenshot as a PNG image");
+ }
+
+ public static SavePixelPerfectAction getAction(Shell shell) {
+ if (action == null) {
+ action = new SavePixelPerfectAction(shell);
+ }
+ return action;
+ }
+
+ @Override
+ public void run() {
+ HierarchyViewerDirector.getDirector().savePixelPerfect(shell);
+ }
+
+ public Image getImage() {
+ return image;
+ }
+}
diff --git a/hierarchyviewer2/app/src/com/android/hierarchyviewer/actions/SaveTreeViewAction.java b/hierarchyviewer2/app/src/com/android/hierarchyviewer/actions/SaveTreeViewAction.java
new file mode 100644
index 0000000..c203ace
--- /dev/null
+++ b/hierarchyviewer2/app/src/com/android/hierarchyviewer/actions/SaveTreeViewAction.java
@@ -0,0 +1,62 @@
+/*
+ * 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.hierarchyviewer.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 {
+
+ private static SaveTreeViewAction action;
+
+ private Image image;
+
+ private Shell shell;
+
+ private SaveTreeViewAction(Shell shell) {
+ super("&Save as PNG");
+ this.shell = shell;
+ setAccelerator(SWT.MOD1 + 'S');
+ ImageLoader imageLoader = ImageLoader.getLoader(HierarchyViewerDirector.class);
+ image = imageLoader.loadImage("save.png", Display.getDefault());
+ setImageDescriptor(ImageDescriptor.createFromImage(image));
+ setToolTipText("Save the tree view as a PNG image");
+ }
+
+ public static SaveTreeViewAction getAction(Shell shell) {
+ if (action == null) {
+ action = new SaveTreeViewAction(shell);
+ }
+ return action;
+ }
+
+ @Override
+ public void run() {
+ HierarchyViewerDirector.getDirector().saveTreeView(shell);
+ }
+
+ public Image getImage() {
+ return image;
+ }
+}
diff --git a/hierarchyviewer2/app/src/com/android/hierarchyviewer/actions/ShowOverlayAction.java b/hierarchyviewer2/app/src/com/android/hierarchyviewer/actions/ShowOverlayAction.java
new file mode 100644
index 0000000..b0f51ec
--- /dev/null
+++ b/hierarchyviewer2/app/src/com/android/hierarchyviewer/actions/ShowOverlayAction.java
@@ -0,0 +1,59 @@
+/*
+ * 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.hierarchyviewer.actions;
+
+import com.android.ddmuilib.ImageLoader;
+import com.android.hierarchyviewer.HierarchyViewerApplication;
+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 ShowOverlayAction extends Action implements ImageAction {
+
+ private static ShowOverlayAction action;
+
+ private Image image;
+
+ private ShowOverlayAction() {
+ super("Show In &Loupe", Action.AS_CHECK_BOX);
+ setAccelerator(SWT.MOD1 + 'L');
+ ImageLoader imageLoader = ImageLoader.getLoader(HierarchyViewerDirector.class);
+ image = imageLoader.loadImage("show-overlay.png", Display.getDefault());
+ setImageDescriptor(ImageDescriptor.createFromImage(image));
+ setToolTipText("Show the overlay in the loupe view");
+ }
+
+ public static ShowOverlayAction getAction() {
+ if (action == null) {
+ action = new ShowOverlayAction();
+ }
+ return action;
+ }
+
+ @Override
+ public void run() {
+ HierarchyViewerApplication.getApp().showOverlayInLoupe(action.isChecked());
+ }
+
+ public Image getImage() {
+ return image;
+ }
+}
diff --git a/hierarchyviewer2/app/src/com/android/hierarchyviewer/util/ActionButton.java b/hierarchyviewer2/app/src/com/android/hierarchyviewer/util/ActionButton.java
new file mode 100644
index 0000000..08fe1ac
--- /dev/null
+++ b/hierarchyviewer2/app/src/com/android/hierarchyviewer/util/ActionButton.java
@@ -0,0 +1,75 @@
+/*
+ * 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.hierarchyviewer.util;
+
+import com.android.hierarchyviewer.actions.ImageAction;
+
+import org.eclipse.jface.action.Action;
+import org.eclipse.jface.util.IPropertyChangeListener;
+import org.eclipse.jface.util.PropertyChangeEvent;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.events.SelectionListener;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+
+public class ActionButton implements IPropertyChangeListener, SelectionListener {
+ private Button button;
+
+ private Action action;
+
+ public ActionButton(Composite parent, ImageAction action) {
+ this.action = (Action) action;
+ if (this.action.getStyle() == Action.AS_CHECK_BOX) {
+ button = new Button(parent, SWT.CHECK);
+ } else {
+ button = new Button(parent, SWT.PUSH);
+ }
+ button.setText(action.getText());
+ button.setImage(action.getImage());
+ this.action.addPropertyChangeListener(this);
+ button.addSelectionListener(this);
+ button.setToolTipText(action.getToolTipText());
+ }
+
+ public void propertyChange(PropertyChangeEvent e) {
+ if (e.getProperty().toUpperCase().equals("ENABLED")) {
+ button.setEnabled((Boolean) e.getNewValue());
+ } else if (e.getProperty().toUpperCase().equals("CHECKED")) {
+ button.setSelection(action.isChecked());
+ }
+ }
+
+ public void setLayoutData(Object data) {
+ button.setLayoutData(data);
+ }
+
+ public void widgetDefaultSelected(SelectionEvent e) {
+ // pass
+ }
+
+ public void widgetSelected(SelectionEvent e) {
+ if (action.getStyle() == Action.AS_CHECK_BOX) {
+ action.setChecked(button.getSelection());
+ }
+ action.run();
+ }
+
+ public void addSelectionListener(SelectionListener listener) {
+ button.addSelectionListener(listener);
+ }
+}